From 5752142c48ca541a8fefbc1cc6e7d829255970c5 Mon Sep 17 00:00:00 2001 From: rob Date: Sat, 4 Sep 2021 14:15:59 -0400 Subject: [PATCH 1/4] feat: adds bindings for IntersectionObserver --- .../Webapi__IntersectionObserver__test.js | 49 +++++++++++++++++++ src/Webapi.res | 1 + ...ionObserver__IntersectionObserverEntry.res | 15 ++++++ src/Webapi/Webapi__IntersectionObserver.res | 44 +++++++++++++++++ .../Webapi__IntersectionObserver__test.res | 31 ++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 lib/js/tests/Webapi/Webapi__IntersectionObserver__test.js create mode 100644 src/Webapi/IntersectionObserver/Webapi__IntersectionObserver__IntersectionObserverEntry.res create mode 100644 src/Webapi/Webapi__IntersectionObserver.res create mode 100644 tests/Webapi/Webapi__IntersectionObserver__test.res diff --git a/lib/js/tests/Webapi/Webapi__IntersectionObserver__test.js b/lib/js/tests/Webapi/Webapi__IntersectionObserver__test.js new file mode 100644 index 00000000..70b2c573 --- /dev/null +++ b/lib/js/tests/Webapi/Webapi__IntersectionObserver__test.js @@ -0,0 +1,49 @@ +'use strict'; + +var Belt_Option = require("rescript/lib/js/belt_Option.js"); +var Caml_option = require("rescript/lib/js/caml_option.js"); +var TestHelpers = require("../testHelpers.js"); +var Webapi__Dom__Document = require("../../src/Webapi/Dom/Webapi__Dom__Document.js"); + +var el = document.createElement("div"); + +var body = TestHelpers.unsafelyUnwrapOption(Belt_Option.flatMap(Webapi__Dom__Document.asHtmlDocument(document), (function (prim) { + return Caml_option.nullable_to_opt(prim.body); + }))); + +el.innerText = "Hello There"; + +el.setAttribute("style", "margin-top: 800px; margin-bottom: 800px"); + +el.appendChild(body); + +function handler(entries, observer) { + entries.forEach(function (entry) { + console.log(entry.time); + console.log(entry.rootBounds); + console.log(entry.boundingClientRect); + console.log(entry.intersectionRect); + console.log(entry.isIntersecting); + console.log(entry.intersectionRatio); + console.log(entry.target); + + }); + observer.unobserve(el); + +} + +var observer = new IntersectionObserver(handler); + +observer.observe(el); + +observer.unobserve(el); + +observer.observe(el); + +observer.disconnect(); + +exports.el = el; +exports.body = body; +exports.handler = handler; +exports.observer = observer; +/* el Not a pure module */ diff --git a/src/Webapi.res b/src/Webapi.res index 2a51419d..5e3a0039 100644 --- a/src/Webapi.res +++ b/src/Webapi.res @@ -26,6 +26,7 @@ module Performance = Webapi__Performance /** @since 0.19.0 */ module ReadableStream = Webapi__ReadableStream +module IntersectionObserver = Webapi__IntersectionObserver module ResizeObserver = Webapi__ResizeObserver module Url = Webapi__Url diff --git a/src/Webapi/IntersectionObserver/Webapi__IntersectionObserver__IntersectionObserverEntry.res b/src/Webapi/IntersectionObserver/Webapi__IntersectionObserver__IntersectionObserverEntry.res new file mode 100644 index 00000000..bec32163 --- /dev/null +++ b/src/Webapi/IntersectionObserver/Webapi__IntersectionObserver__IntersectionObserverEntry.res @@ -0,0 +1,15 @@ +/** + * Spec: https://www.w3.org/TR/intersection-observer/#intersection-observer-entry + */ + +type t = Dom.intersectionObserverEntry + +/* Properties */ + +@get external time: t => float = "time"; +@get external rootBounds: t => Dom.domRect = "rootBounds"; +@get external boundingClientRect: t => Dom.domRect = "boundingClientRect"; +@get external intersectionRect: t => Dom.domRect = "intersectionRect"; +@get external isIntersecting: t => bool = "isIntersecting"; +@get external intersectionRatio: t => float = "intersectionRatio"; +@get external target: t => Dom.element = "target"; diff --git a/src/Webapi/Webapi__IntersectionObserver.res b/src/Webapi/Webapi__IntersectionObserver.res new file mode 100644 index 00000000..70161a58 --- /dev/null +++ b/src/Webapi/Webapi__IntersectionObserver.res @@ -0,0 +1,44 @@ +/** + * Spec: https://www.w3.org/TR/intersection-observer/ + */ +module IntersectionObserverEntry = Webapi__IntersectionObserver__IntersectionObserverEntry + +type t = Dom.intersectionObserver + +type intersectionObserverInit = { + root: option, + rootMargin: option, + threshold: option>, // between 0 and 1. +} + +@obj +external makeInit: ( + ~root: Dom.element=?, + ~rootMargin: string=?, + ~threshold: array=?, + unit, +) => intersectionObserverInit = "" + +@new +external make: (@uncurry (array, t) => unit) => t = + "IntersectionObserver" + +@new +external makeWithInit: ( + @uncurry (array, t) => unit, + intersectionObserverInit, +) => t = "IntersectionObserver" + +/* Properties */ + +@get @return(nullable) +external root: t => option = "root" +@get external rootMargin: t => string = "rootMargin" +@get external thresholds: t => array = "thresholds" + +/* Methods */ + +@send external disconnect: t => unit = "disconnect" +@send external observe: (t, Dom.element) => unit = "observe" +@send external unobserve: (t, Dom.element) => unit = "unobserve" +@send external takeRecords: t => array = "takeRecords" diff --git a/tests/Webapi/Webapi__IntersectionObserver__test.res b/tests/Webapi/Webapi__IntersectionObserver__test.res new file mode 100644 index 00000000..5ed064f0 --- /dev/null +++ b/tests/Webapi/Webapi__IntersectionObserver__test.res @@ -0,0 +1,31 @@ +let el = Webapi.Dom.document -> Webapi.Dom.Document.createElement("div") + +let body = + Webapi.Dom.Document.asHtmlDocument(Webapi.Dom.document) + ->Belt.Option.flatMap(Webapi.Dom.HtmlDocument.body) + ->TestHelpers.unsafelyUnwrapOption + +Webapi.Dom.Element.setInnerText(el, "Hello There") +Webapi.Dom.Element.setAttribute(el, "style", "margin-top: 800px; margin-bottom: 800px") +Webapi.Dom.Element.appendChild(el, body) + +let handler = (entries, observer) => { + Js.Array.forEach(entry => { + Js.log(Webapi.IntersectionObserver.IntersectionObserverEntry.time(entry)) + Js.log(Webapi.IntersectionObserver.IntersectionObserverEntry.rootBounds(entry)) + Js.log(Webapi.IntersectionObserver.IntersectionObserverEntry.boundingClientRect(entry)) + Js.log(Webapi.IntersectionObserver.IntersectionObserverEntry.intersectionRect(entry)) + Js.log(Webapi.IntersectionObserver.IntersectionObserverEntry.isIntersecting(entry)) + Js.log(Webapi.IntersectionObserver.IntersectionObserverEntry.intersectionRatio(entry)) + Js.log(Webapi.IntersectionObserver.IntersectionObserverEntry.target(entry)) + }, entries) + + Webapi.IntersectionObserver.unobserve(observer, el) +} + +let observer = Webapi.IntersectionObserver.make(handler) + +Webapi.IntersectionObserver.observe(observer, el) +Webapi.IntersectionObserver.unobserve(observer, el) +Webapi.IntersectionObserver.observe(observer, el) +Webapi.IntersectionObserver.disconnect(observer) From 40da4d17a6b9b0424dcd0506803bec9befd4fa97 Mon Sep 17 00:00:00 2001 From: rob Date: Fri, 17 Sep 2021 13:32:56 -0400 Subject: [PATCH 2/4] chore: add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72aafb3a..e5e3f1cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Done: * Remove deprecated APIs * `Window.getSelection` now returns an option, to better match the definition * Add scrollToWithOptions to window +* Added IntersectionObserver and IntersectionObserverEntry bindings Todo: * Convert to rescript syntax From 83f91cebaae35641b805e947bfae319c0967ad90 Mon Sep 17 00:00:00 2001 From: rob Date: Tue, 21 Sep 2021 21:26:34 -0400 Subject: [PATCH 3/4] refactor: move to local module --- ...ionObserver__IntersectionObserverEntry.res | 15 --------------- src/Webapi/Webapi__IntersectionObserver.res | 19 ++++++++++++++++++- 2 files changed, 18 insertions(+), 16 deletions(-) delete mode 100644 src/Webapi/IntersectionObserver/Webapi__IntersectionObserver__IntersectionObserverEntry.res diff --git a/src/Webapi/IntersectionObserver/Webapi__IntersectionObserver__IntersectionObserverEntry.res b/src/Webapi/IntersectionObserver/Webapi__IntersectionObserver__IntersectionObserverEntry.res deleted file mode 100644 index bec32163..00000000 --- a/src/Webapi/IntersectionObserver/Webapi__IntersectionObserver__IntersectionObserverEntry.res +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Spec: https://www.w3.org/TR/intersection-observer/#intersection-observer-entry - */ - -type t = Dom.intersectionObserverEntry - -/* Properties */ - -@get external time: t => float = "time"; -@get external rootBounds: t => Dom.domRect = "rootBounds"; -@get external boundingClientRect: t => Dom.domRect = "boundingClientRect"; -@get external intersectionRect: t => Dom.domRect = "intersectionRect"; -@get external isIntersecting: t => bool = "isIntersecting"; -@get external intersectionRatio: t => float = "intersectionRatio"; -@get external target: t => Dom.element = "target"; diff --git a/src/Webapi/Webapi__IntersectionObserver.res b/src/Webapi/Webapi__IntersectionObserver.res index 70161a58..1da206b3 100644 --- a/src/Webapi/Webapi__IntersectionObserver.res +++ b/src/Webapi/Webapi__IntersectionObserver.res @@ -1,7 +1,24 @@ /** * Spec: https://www.w3.org/TR/intersection-observer/ */ -module IntersectionObserverEntry = Webapi__IntersectionObserver__IntersectionObserverEntry + +module IntersectionObserverEntry = { + /** + * Spec: https://www.w3.org/TR/intersection-observer/#intersection-observer-entry + */ + + type t = Dom.intersectionObserverEntry + + /* Properties */ + + @get external time: t => float = "time" + @get external rootBounds: t => Dom.domRect = "rootBounds" + @get external boundingClientRect: t => Dom.domRect = "boundingClientRect" + @get external intersectionRect: t => Dom.domRect = "intersectionRect" + @get external isIntersecting: t => bool = "isIntersecting" + @get external intersectionRatio: t => float = "intersectionRatio" + @get external target: t => Dom.element = "target" +} type t = Dom.intersectionObserver From 259cc862eec831774bb74f22b3bd8a63014b7438 Mon Sep 17 00:00:00 2001 From: rob Date: Tue, 21 Sep 2021 21:30:17 -0400 Subject: [PATCH 4/4] fix: wrong argument order --- lib/js/tests/Webapi/Webapi__IntersectionObserver__test.js | 2 +- tests/Webapi/Webapi__IntersectionObserver__test.res | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/js/tests/Webapi/Webapi__IntersectionObserver__test.js b/lib/js/tests/Webapi/Webapi__IntersectionObserver__test.js index 70b2c573..357f0ff7 100644 --- a/lib/js/tests/Webapi/Webapi__IntersectionObserver__test.js +++ b/lib/js/tests/Webapi/Webapi__IntersectionObserver__test.js @@ -15,7 +15,7 @@ el.innerText = "Hello There"; el.setAttribute("style", "margin-top: 800px; margin-bottom: 800px"); -el.appendChild(body); +body.appendChild(el); function handler(entries, observer) { entries.forEach(function (entry) { diff --git a/tests/Webapi/Webapi__IntersectionObserver__test.res b/tests/Webapi/Webapi__IntersectionObserver__test.res index 5ed064f0..6b324383 100644 --- a/tests/Webapi/Webapi__IntersectionObserver__test.res +++ b/tests/Webapi/Webapi__IntersectionObserver__test.res @@ -7,7 +7,7 @@ let body = Webapi.Dom.Element.setInnerText(el, "Hello There") Webapi.Dom.Element.setAttribute(el, "style", "margin-top: 800px; margin-bottom: 800px") -Webapi.Dom.Element.appendChild(el, body) +Webapi.Dom.Element.appendChild(body, el) let handler = (entries, observer) => { Js.Array.forEach(entry => {