From c497fef9a1cbaa3f1f7215e50e39268ecaf6a8e6 Mon Sep 17 00:00:00 2001 From: Chris Lindholm Date: Tue, 8 Aug 2023 18:38:01 -0600 Subject: [PATCH 1/6] Add facade for Intersection Observer API --- api-reports/2_12.txt | 24 ++++++++++ api-reports/2_13.txt | 24 ++++++++++ .../scalajs/dom/IntersectionObserver.scala | 46 +++++++++++++++++++ .../dom/IntersectionObserverEntry.scala | 38 +++++++++++++++ .../dom/IntersectionObserverEntryInit.scala | 20 ++++++++ .../dom/IntersectionObserverInit.scala | 27 +++++++++++ 6 files changed, 179 insertions(+) create mode 100644 dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala create mode 100644 dom/src/main/scala/org/scalajs/dom/IntersectionObserverEntry.scala create mode 100644 dom/src/main/scala/org/scalajs/dom/IntersectionObserverEntryInit.scala create mode 100644 dom/src/main/scala/org/scalajs/dom/IntersectionObserverInit.scala diff --git a/api-reports/2_12.txt b/api-reports/2_12.txt index b80e958d2..06f0603cd 100644 --- a/api-reports/2_12.txt +++ b/api-reports/2_12.txt @@ -15531,6 +15531,30 @@ InputType[SO] val insertReplacementText: InputType InputType[SO] val insertText: InputType InputType[SO] val insertTranspose: InputType InputType[SO] val insertUnorderedList: InputType +IntersectionObserver[JC] def disconnect(): Unit +IntersectionObserver[JC] def observe(target: Element): Unit +IntersectionObserver[JC] def root: Document | Element +IntersectionObserver[JC] def rootMargin: String +IntersectionObserver[JC] def takeRecords(): js.Array[IntersectionObserverEntry] +IntersectionObserver[JC] def thresholds: js.Array[Double] +IntersectionObserver[JC] def unobserve(target: Element): Unit +IntersectionObserverEntry[JC] def boundingClientRect: DOMRectReadOnly +IntersectionObserverEntry[JC] def intersectionRatio: Double +IntersectionObserverEntry[JC] def intersectionRect: DOMRectReadOnly +IntersectionObserverEntry[JC] def isIntersecting: Boolean +IntersectionObserverEntry[JC] def rootBounds: DOMRectReadOnly +IntersectionObserverEntry[JC] def target: Element +IntersectionObserverEntry[JC] def time: Double +IntersectionObserverEntryInit[JT] var boundingClientRect: DOMRect +IntersectionObserverEntryInit[JT] var intersectionRatio: Double +IntersectionObserverEntryInit[JT] var intersectionRect: DOMRect +IntersectionObserverEntryInit[JT] var isIntersecting: Boolean +IntersectionObserverEntryInit[JT] var rootBounds: DOMRect +IntersectionObserverEntryInit[JT] var target: Element +IntersectionObserverEntryInit[JT] var time: Double +IntersectionObserverInit[JT] var root: js.UndefOr[Document | Element] +IntersectionObserverInit[JT] var rootMargin: js.UndefOr[String] +IntersectionObserverInit[JT] var threshold: js.UndefOr[Double | js.Array[Double]] JsonWebKey[JT] var alg: js.Array[String] JsonWebKey[JT] var crv: String JsonWebKey[JT] var d: String diff --git a/api-reports/2_13.txt b/api-reports/2_13.txt index b80e958d2..06f0603cd 100644 --- a/api-reports/2_13.txt +++ b/api-reports/2_13.txt @@ -15531,6 +15531,30 @@ InputType[SO] val insertReplacementText: InputType InputType[SO] val insertText: InputType InputType[SO] val insertTranspose: InputType InputType[SO] val insertUnorderedList: InputType +IntersectionObserver[JC] def disconnect(): Unit +IntersectionObserver[JC] def observe(target: Element): Unit +IntersectionObserver[JC] def root: Document | Element +IntersectionObserver[JC] def rootMargin: String +IntersectionObserver[JC] def takeRecords(): js.Array[IntersectionObserverEntry] +IntersectionObserver[JC] def thresholds: js.Array[Double] +IntersectionObserver[JC] def unobserve(target: Element): Unit +IntersectionObserverEntry[JC] def boundingClientRect: DOMRectReadOnly +IntersectionObserverEntry[JC] def intersectionRatio: Double +IntersectionObserverEntry[JC] def intersectionRect: DOMRectReadOnly +IntersectionObserverEntry[JC] def isIntersecting: Boolean +IntersectionObserverEntry[JC] def rootBounds: DOMRectReadOnly +IntersectionObserverEntry[JC] def target: Element +IntersectionObserverEntry[JC] def time: Double +IntersectionObserverEntryInit[JT] var boundingClientRect: DOMRect +IntersectionObserverEntryInit[JT] var intersectionRatio: Double +IntersectionObserverEntryInit[JT] var intersectionRect: DOMRect +IntersectionObserverEntryInit[JT] var isIntersecting: Boolean +IntersectionObserverEntryInit[JT] var rootBounds: DOMRect +IntersectionObserverEntryInit[JT] var target: Element +IntersectionObserverEntryInit[JT] var time: Double +IntersectionObserverInit[JT] var root: js.UndefOr[Document | Element] +IntersectionObserverInit[JT] var rootMargin: js.UndefOr[String] +IntersectionObserverInit[JT] var threshold: js.UndefOr[Double | js.Array[Double]] JsonWebKey[JT] var alg: js.Array[String] JsonWebKey[JT] var crv: String JsonWebKey[JT] var d: String diff --git a/dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala b/dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala new file mode 100644 index 000000000..c9b58af11 --- /dev/null +++ b/dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala @@ -0,0 +1,46 @@ +package org.scalajs.dom + +import scala.scalajs.js +import scala.scalajs.js.annotation.JSGlobal +import scala.scalajs.js.| + +/** The IntersectionObserver interface of the Intersection Observer API provides a way to asynchronously observe changes + * in the intersection of a target element with an ancestor element or with a top-level document's viewport. + */ +@js.native +@JSGlobal +class IntersectionObserver( + callback: js.Function2[js.Array[IntersectionObserverEntry], IntersectionObserver, Unit], + init: IntersectionObserverInit +) extends js.Object { + + /** The Element or Document whose bounds are used as the bounding box when testing for intersection. If no root value + * was passed to the constructor or its value is null, the top-level document's viewport is used. + */ + def root: Document | Element = js.native + + /** An offset rectangle applied to the root's bounding box when calculating intersections, effectively shrinking or + * growing the root for calculation purposes. The value returned by this property may not be the same as the one + * specified when calling the constructor as it may be changed to match internal requirements. Each offset can be + * expressed in pixels (px) or as a percentage (%). The default is "0px 0px 0px 0px". + */ + def rootMargin: String = js.native + + /** A list of thresholds, sorted in increasing numeric order, where each threshold is a ratio of intersection area to + * bounding box area of an observed target. Notifications for a target are generated when any of the thresholds are + * crossed for that target. If no value was passed to the constructor, 0 is used. + */ + def thresholds: js.Array[Double] = js.native + + /** Stops the IntersectionObserver object from observing any target. */ + def disconnect(): Unit = js.native + + /** Tells the IntersectionObserver a target element to observe. */ + def observe(target: Element): Unit = js.native + + /** Returns an array of IntersectionObserverEntry objects for all observed targets. */ + def takeRecords(): js.Array[IntersectionObserverEntry] = js.native + + /** Tells the IntersectionObserver to stop observing a particular target element. */ + def unobserve(target: Element): Unit = js.native +} diff --git a/dom/src/main/scala/org/scalajs/dom/IntersectionObserverEntry.scala b/dom/src/main/scala/org/scalajs/dom/IntersectionObserverEntry.scala new file mode 100644 index 000000000..0a9c46d0c --- /dev/null +++ b/dom/src/main/scala/org/scalajs/dom/IntersectionObserverEntry.scala @@ -0,0 +1,38 @@ +package org.scalajs.dom + +import scala.scalajs.js +import scala.scalajs.js.annotation.JSGlobal + +/** The IntersectionObserverEntry interface of the Intersection Observer API describes the intersection between the + * target element and its root container at a specific moment of transition. + */ +@js.native +@JSGlobal +class IntersectionObserverEntry(init: IntersectionObserverEntryInit) extends js.Object { + + /** The bounds rectangle of the target element as a DOMRectReadOnly. */ + def boundingClientRect: DOMRectReadOnly = js.native + + /** The ratio of the intersectionRect to the boundingClientRect. */ + def intersectionRatio: Double = js.native + + /** A DOMRectReadOnly representing the target's visible area. */ + def intersectionRect: DOMRectReadOnly = js.native + + /** A Boolean value which is true if the target element intersects with the intersection observer's root. If this is + * true, then, the IntersectionObserverEntry describes a transition into a state of intersection; if it's false, then + * you know the transition is from intersecting to not-intersecting. + */ + def isIntersecting: Boolean = js.native + + /** A DOMRectReadOnly for the intersection observer's root. */ + def rootBounds: DOMRectReadOnly = js.native + + /** The Element whose intersection with the root changed. */ + def target: Element = js.native + + /** A DOMHighResTimeStamp indicating the time at which the intersection was recorded, relative to the + * IntersectionObserver's time origin. + */ + def time: Double = js.native +} diff --git a/dom/src/main/scala/org/scalajs/dom/IntersectionObserverEntryInit.scala b/dom/src/main/scala/org/scalajs/dom/IntersectionObserverEntryInit.scala new file mode 100644 index 000000000..195617949 --- /dev/null +++ b/dom/src/main/scala/org/scalajs/dom/IntersectionObserverEntryInit.scala @@ -0,0 +1,20 @@ +package org.scalajs.dom + +import scala.scalajs.js + +trait IntersectionObserverEntryInit extends js.Object { + + var boundingClientRect: DOMRect + + var intersectionRatio: Double + + var intersectionRect: DOMRect + + var isIntersecting: Boolean + + var rootBounds: DOMRect + + var target: Element + + var time: Double +} diff --git a/dom/src/main/scala/org/scalajs/dom/IntersectionObserverInit.scala b/dom/src/main/scala/org/scalajs/dom/IntersectionObserverInit.scala new file mode 100644 index 000000000..2f965f43c --- /dev/null +++ b/dom/src/main/scala/org/scalajs/dom/IntersectionObserverInit.scala @@ -0,0 +1,27 @@ +package org.scalajs.dom + +import scala.scalajs.js +import scala.scalajs.js.| + +/** An object which customizes the observer. */ +trait IntersectionObserverInit extends js.Object { + + /** An Element or Document object which is an ancestor of the intended target, whose bounding rectangle will be + * considered the viewport. Any part of the target not visible in the visible area of the root is not considered + * visible. + */ + var root: js.UndefOr[Document | Element] = js.undefined + + /** A string which specifies a set of offsets to add to the root's bounding_box when calculating intersections, + * effectively shrinking or growing the root for calculation purposes. The syntax is approximately the same as that + * for the CSS margin property; see The intersection root and root margin for more information on how the margin + * works and the syntax. The default is "0px 0px 0px 0px". + */ + var rootMargin: js.UndefOr[String] = js.undefined + + /** Either a single number or an array of numbers between 0.0 and 1.0, specifying a ratio of intersection area to + * total bounding box area for the observed target. A value of 0.0 means that even a single visible pixel counts as + * the target being visible. 1.0 means that the entire target element is visible. The default is a threshold of 0.0. + */ + var threshold: js.UndefOr[Double | js.Array[Double]] = js.undefined +} From c7f1c146e3f40d76905c6932b69c46f232a03d0a Mon Sep 17 00:00:00 2001 From: Chris Lindholm Date: Mon, 14 Aug 2023 11:12:27 -0600 Subject: [PATCH 2/6] Use FrozenArray Co-authored-by: Arman Bilge --- dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala b/dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala index c9b58af11..9d0bbdd9b 100644 --- a/dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala +++ b/dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala @@ -30,7 +30,7 @@ class IntersectionObserver( * bounding box area of an observed target. Notifications for a target are generated when any of the thresholds are * crossed for that target. If no value was passed to the constructor, 0 is used. */ - def thresholds: js.Array[Double] = js.native + def thresholds: FrozenArray[Double] = js.native /** Stops the IntersectionObserver object from observing any target. */ def disconnect(): Unit = js.native From cecd5af813d33fec15f2c5023d447cd39d8d55d4 Mon Sep 17 00:00:00 2001 From: Chris Lindholm Date: Mon, 14 Aug 2023 11:14:49 -0600 Subject: [PATCH 3/6] Make options an optional argument Co-authored-by: Arman Bilge --- dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala b/dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala index 9d0bbdd9b..bc7f40158 100644 --- a/dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala +++ b/dom/src/main/scala/org/scalajs/dom/IntersectionObserver.scala @@ -11,7 +11,7 @@ import scala.scalajs.js.| @JSGlobal class IntersectionObserver( callback: js.Function2[js.Array[IntersectionObserverEntry], IntersectionObserver, Unit], - init: IntersectionObserverInit + options: IntersectionObserverInit = js.native ) extends js.Object { /** The Element or Document whose bounds are used as the bounding box when testing for intersection. If no root value From 8483feeddb85e42239af9538d8317e6d533c7fd3 Mon Sep 17 00:00:00 2001 From: Chris Lindholm Date: Mon, 14 Aug 2023 13:05:24 -0600 Subject: [PATCH 4/6] Add DOMRectInit --- .../main/scala/org/scalajs/dom/DOMRectInit.scala | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 dom/src/main/scala/org/scalajs/dom/DOMRectInit.scala diff --git a/dom/src/main/scala/org/scalajs/dom/DOMRectInit.scala b/dom/src/main/scala/org/scalajs/dom/DOMRectInit.scala new file mode 100644 index 000000000..5677ebba2 --- /dev/null +++ b/dom/src/main/scala/org/scalajs/dom/DOMRectInit.scala @@ -0,0 +1,13 @@ +package org.scalajs.dom + +import scala.scalajs.js + +trait DOMRectInit extends js.Object { + var x: js.UndefOr[Double] = js.undefined + + var y: js.UndefOr[Double] = js.undefined + + var width: js.UndefOr[Double] = js.undefined + + var height: js.UndefOr[Double] = js.undefined +} From 2dc2bcb0ed191c0b386799ec5c632d89744f9c60 Mon Sep 17 00:00:00 2001 From: Chris Lindholm Date: Mon, 14 Aug 2023 13:05:52 -0600 Subject: [PATCH 5/6] Use DOMRectInit --- .../org/scalajs/dom/IntersectionObserverEntryInit.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dom/src/main/scala/org/scalajs/dom/IntersectionObserverEntryInit.scala b/dom/src/main/scala/org/scalajs/dom/IntersectionObserverEntryInit.scala index 195617949..08b1e26bd 100644 --- a/dom/src/main/scala/org/scalajs/dom/IntersectionObserverEntryInit.scala +++ b/dom/src/main/scala/org/scalajs/dom/IntersectionObserverEntryInit.scala @@ -4,15 +4,15 @@ import scala.scalajs.js trait IntersectionObserverEntryInit extends js.Object { - var boundingClientRect: DOMRect + var boundingClientRect: DOMRectInit var intersectionRatio: Double - var intersectionRect: DOMRect + var intersectionRect: DOMRectInit var isIntersecting: Boolean - var rootBounds: DOMRect + var rootBounds: DOMRectInit var target: Element From 70f1ee5110c92136b8df1eeaa1fc6aabeda4bf5d Mon Sep 17 00:00:00 2001 From: Chris Lindholm Date: Mon, 14 Aug 2023 13:10:23 -0600 Subject: [PATCH 6/6] Update api-reports --- api-reports/2_12.txt | 12 ++++++++---- api-reports/2_13.txt | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/api-reports/2_12.txt b/api-reports/2_12.txt index 06f0603cd..a75d17f13 100644 --- a/api-reports/2_12.txt +++ b/api-reports/2_12.txt @@ -1502,6 +1502,10 @@ DOMRect[JC] def x: Double DOMRect[JC] def x_ = (x: Double): Unit DOMRect[JC] def y: Double DOMRect[JC] def y_ = (y: Double): Unit +DOMRectInit[JT] var height: js.UndefOr[Double] +DOMRectInit[JT] var width: js.UndefOr[Double] +DOMRectInit[JT] var x: js.UndefOr[Double] +DOMRectInit[JT] var y: js.UndefOr[Double] DOMRectList[JC] @JSBracketAccess def apply(index: Int): T DOMRectList[JC] def length: Int DOMRectReadOnly[JT] def bottom: Double @@ -15536,7 +15540,7 @@ IntersectionObserver[JC] def observe(target: Element): Unit IntersectionObserver[JC] def root: Document | Element IntersectionObserver[JC] def rootMargin: String IntersectionObserver[JC] def takeRecords(): js.Array[IntersectionObserverEntry] -IntersectionObserver[JC] def thresholds: js.Array[Double] +IntersectionObserver[JC] def thresholds: FrozenArray[Double] IntersectionObserver[JC] def unobserve(target: Element): Unit IntersectionObserverEntry[JC] def boundingClientRect: DOMRectReadOnly IntersectionObserverEntry[JC] def intersectionRatio: Double @@ -15545,11 +15549,11 @@ IntersectionObserverEntry[JC] def isIntersecting: Boolean IntersectionObserverEntry[JC] def rootBounds: DOMRectReadOnly IntersectionObserverEntry[JC] def target: Element IntersectionObserverEntry[JC] def time: Double -IntersectionObserverEntryInit[JT] var boundingClientRect: DOMRect +IntersectionObserverEntryInit[JT] var boundingClientRect: DOMRectInit IntersectionObserverEntryInit[JT] var intersectionRatio: Double -IntersectionObserverEntryInit[JT] var intersectionRect: DOMRect +IntersectionObserverEntryInit[JT] var intersectionRect: DOMRectInit IntersectionObserverEntryInit[JT] var isIntersecting: Boolean -IntersectionObserverEntryInit[JT] var rootBounds: DOMRect +IntersectionObserverEntryInit[JT] var rootBounds: DOMRectInit IntersectionObserverEntryInit[JT] var target: Element IntersectionObserverEntryInit[JT] var time: Double IntersectionObserverInit[JT] var root: js.UndefOr[Document | Element] diff --git a/api-reports/2_13.txt b/api-reports/2_13.txt index 06f0603cd..a75d17f13 100644 --- a/api-reports/2_13.txt +++ b/api-reports/2_13.txt @@ -1502,6 +1502,10 @@ DOMRect[JC] def x: Double DOMRect[JC] def x_ = (x: Double): Unit DOMRect[JC] def y: Double DOMRect[JC] def y_ = (y: Double): Unit +DOMRectInit[JT] var height: js.UndefOr[Double] +DOMRectInit[JT] var width: js.UndefOr[Double] +DOMRectInit[JT] var x: js.UndefOr[Double] +DOMRectInit[JT] var y: js.UndefOr[Double] DOMRectList[JC] @JSBracketAccess def apply(index: Int): T DOMRectList[JC] def length: Int DOMRectReadOnly[JT] def bottom: Double @@ -15536,7 +15540,7 @@ IntersectionObserver[JC] def observe(target: Element): Unit IntersectionObserver[JC] def root: Document | Element IntersectionObserver[JC] def rootMargin: String IntersectionObserver[JC] def takeRecords(): js.Array[IntersectionObserverEntry] -IntersectionObserver[JC] def thresholds: js.Array[Double] +IntersectionObserver[JC] def thresholds: FrozenArray[Double] IntersectionObserver[JC] def unobserve(target: Element): Unit IntersectionObserverEntry[JC] def boundingClientRect: DOMRectReadOnly IntersectionObserverEntry[JC] def intersectionRatio: Double @@ -15545,11 +15549,11 @@ IntersectionObserverEntry[JC] def isIntersecting: Boolean IntersectionObserverEntry[JC] def rootBounds: DOMRectReadOnly IntersectionObserverEntry[JC] def target: Element IntersectionObserverEntry[JC] def time: Double -IntersectionObserverEntryInit[JT] var boundingClientRect: DOMRect +IntersectionObserverEntryInit[JT] var boundingClientRect: DOMRectInit IntersectionObserverEntryInit[JT] var intersectionRatio: Double -IntersectionObserverEntryInit[JT] var intersectionRect: DOMRect +IntersectionObserverEntryInit[JT] var intersectionRect: DOMRectInit IntersectionObserverEntryInit[JT] var isIntersecting: Boolean -IntersectionObserverEntryInit[JT] var rootBounds: DOMRect +IntersectionObserverEntryInit[JT] var rootBounds: DOMRectInit IntersectionObserverEntryInit[JT] var target: Element IntersectionObserverEntryInit[JT] var time: Double IntersectionObserverInit[JT] var root: js.UndefOr[Document | Element]