Skip to content

Add IntersectionObserverAPI #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/DOMAPI/Document.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/DOMAPI/Document.res
Original file line number Diff line number Diff line change
Expand Up @@ -458,3 +458,5 @@ external hasStorageAccess: document => promise<bool> = "hasStorageAccess"
*/
@send
external requestStorageAccess: document => promise<unit> = "requestStorageAccess"

let isInstanceOf = (_: 't): bool => %raw(`param instanceof Document`)
5 changes: 5 additions & 0 deletions src/DOMAPI/Element.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions src/DOMAPI/Element.res
Original file line number Diff line number Diff line change
Expand Up @@ -498,3 +498,5 @@ Returns true if qualifiedName is now present, and false otherwise.
include Impl({
type t = element
})

let isInstanceOf = (_: 't): bool => %raw(`param instanceof Element`)
2 changes: 2 additions & 0 deletions src/IntersectionObserverAPI.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

69 changes: 69 additions & 0 deletions src/IntersectionObserverAPI.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
@@warning("-30")

open DOMAPI

@editor.completeFrom(IntersectionObserverRoot)
type root

/**
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.
[See IntersectionObserver on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserver)
*/
@editor.completeFrom(IntersectionObserver)
type intersectionObserver = {
/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/root)
*/
root: root,
/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/rootMargin)
*/
rootMargin: string,
/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/thresholds)
*/
thresholds: array<float>,
}

/**
This Intersection Observer API interface describes the intersection between the target element and its root container at a specific moment of transition.
[See IntersectionObserverEntry on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry)
*/
type intersectionObserverEntry = {
/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/time)
*/
time: float,
/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/rootBounds)
*/
rootBounds: Null.t<domRectReadOnly>,
/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/boundingClientRect)
*/
boundingClientRect: domRectReadOnly,
/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/intersectionRect)
*/
intersectionRect: domRectReadOnly,
/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/isIntersecting)
*/
isIntersecting: bool,
/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/intersectionRatio)
*/
intersectionRatio: float,
/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/target)
*/
target: element,
}

type intersectionObserverInit = {
mutable root?: root,
mutable rootMargin?: string,
mutable threshold?: array<float>,
}

type intersectionObserverCallback = (array<intersectionObserverEntry>, intersectionObserver) => unit
2 changes: 2 additions & 0 deletions src/IntersectionObserverAPI/IntersectionObserver.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 35 additions & 0 deletions src/IntersectionObserverAPI/IntersectionObserver.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
open DOMAPI
open IntersectionObserverAPI

/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserver)
*/
@new
external make: (
~callback: intersectionObserverCallback,
~options: intersectionObserverInit=?,
) => intersectionObserver = "IntersectionObserver"

/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/observe)
*/
@send
external observe: (intersectionObserver, element) => unit = "observe"

/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/unobserve)
*/
@send
external unobserve: (intersectionObserver, element) => unit = "unobserve"

/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/disconnect)
*/
@send
external disconnect: intersectionObserver => unit = "disconnect"

/**
[Read more on MDN](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/takeRecords)
*/
@send
external takeRecords: intersectionObserver => array<intersectionObserverEntry> = "takeRecords"
25 changes: 25 additions & 0 deletions src/IntersectionObserverAPI/IntersectionObserverRoot.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions src/IntersectionObserverAPI/IntersectionObserverRoot.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
open DOMAPI
open IntersectionObserverAPI

external fromDocument: document => root = "%identity"
external fromElement: element => root = "%identity"
external fromNull: root = "null"

type decoded =
| Element(element)
| Document(document)
| Null

let decode = (t: root): decoded => {
open Prelude
if Element.isInstanceOf(t) {
Element(t->unsafeConversation)
} else if Document.isInstanceOf(t) {
Document(t->unsafeConversation)
} else {
Null
}
}
57 changes: 57 additions & 0 deletions tests/IntersectionObserverAPI/IntersectionObserver__test.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions tests/IntersectionObserverAPI/IntersectionObserver__test.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
let observer = IntersectionObserver.make(~callback=(entry, observer) => {
Console.log2(entry, observer)
})

let root = Global.document->Document.querySelector("#root")->Null.getUnsafe

let observer2 = IntersectionObserver.make(~callback=(entry, observer) => {
Console.log2(entry, observer)
}, ~options={
root: root->IntersectionObserverRoot.fromElement,
rootMargin: "10px",
threshold: [0.1],
})

switch observer2.root->IntersectionObserverRoot.decode {
| Element(_) => Console.log("Element")
| Document(_) => Console.log("Document")
| Null => Console.log("Null")
}
let rootMargin2 = observer2.rootMargin

let targetElement = Global.document->Document.querySelector("#targetElement")->Null.toOption
switch targetElement {
| Some(e) => {
observer2->IntersectionObserver.observe(e)
observer2->IntersectionObserver.unobserve(e)
}
| _ => Console.log("Target element not found.")
}

let entries2 = observer2->IntersectionObserver.takeRecords
Console.log(entries2->Array.length)

observer2->IntersectionObserver.disconnect
Loading