From c432f8a1d790ab4ab1f5eb2816480d587d3874bb Mon Sep 17 00:00:00 2001 From: nojaf Date: Sat, 1 Mar 2025 14:22:50 +0100 Subject: [PATCH] Prototype type safe query selector --- src/DOMAPI/Document.js | 11 +++++++++++ src/DOMAPI/Document.res | 11 +++++++++++ src/DOMAPI/HTMLHeadingElement.js | 15 +++++++++++++++ src/DOMAPI/HTMLHeadingElement.res | 9 +++++++++ tests/DOMAPI/QuerySelector__test.js | 15 +++++++++++++++ tests/DOMAPI/QuerySelector__test.res | 14 ++++++++++++++ 6 files changed, 75 insertions(+) create mode 100644 tests/DOMAPI/QuerySelector__test.js create mode 100644 tests/DOMAPI/QuerySelector__test.res diff --git a/src/DOMAPI/Document.js b/src/DOMAPI/Document.js index eee8545..0c57006 100644 --- a/src/DOMAPI/Document.js +++ b/src/DOMAPI/Document.js @@ -1,14 +1,25 @@ // Generated by ReScript, PLEASE EDIT WITH CARE import * as Node$WebAPI from "./Node.js"; +import * as HTMLHeadingElement$WebAPI from "./HTMLHeadingElement.js"; Node$WebAPI.Impl({}); +function querySelectorAsHeading(document, selector) { + let element = document.querySelector(selector); + if (element === null || !HTMLHeadingElement$WebAPI.isInstanceOf(element)) { + return; + } else { + return element; + } +} + function isInstanceOf(param) { return (param instanceof Document); } export { + querySelectorAsHeading, isInstanceOf, } /* Not a pure module */ diff --git a/src/DOMAPI/Document.res b/src/DOMAPI/Document.res index 60cef5b..c772d17 100644 --- a/src/DOMAPI/Document.res +++ b/src/DOMAPI/Document.res @@ -86,6 +86,17 @@ Returns the first element that is a descendant of node that matches selectors. @send external querySelector: (document, string) => Null.t = "querySelector" +/** +Invoke querySelector and checks if the element is an HTMLHeadingElement. +[Read more on MDN](https://developer.mozilla.org/docs/Web/API/Document/querySelector) +*/ +let querySelectorAsHeading = (document, selector): option => { + switch querySelector(document, selector) { + | Value(element) if HTMLHeadingElement.isInstanceOf(element) => Some(element->Obj.magic) + | _ => None + } +} + /** Returns all element descendants of node that match selectors. [Read more on MDN](https://developer.mozilla.org/docs/Web/API/Document/querySelectorAll) diff --git a/src/DOMAPI/HTMLHeadingElement.js b/src/DOMAPI/HTMLHeadingElement.js index 1541b40..56eb206 100644 --- a/src/DOMAPI/HTMLHeadingElement.js +++ b/src/DOMAPI/HTMLHeadingElement.js @@ -4,4 +4,19 @@ import * as HTMLElement$WebAPI from "./HTMLElement.js"; HTMLElement$WebAPI.Impl({}); +function isInstanceOf(param) { + return (param instanceof HTMLHeadingElement); +} + +function tryParse(element) { + if (isInstanceOf(element)) { + return element; + } + +} + +export { + isInstanceOf, + tryParse, +} /* Not a pure module */ diff --git a/src/DOMAPI/HTMLHeadingElement.res b/src/DOMAPI/HTMLHeadingElement.res index 6fc967a..7b50586 100644 --- a/src/DOMAPI/HTMLHeadingElement.res +++ b/src/DOMAPI/HTMLHeadingElement.res @@ -3,3 +3,12 @@ open DOMAPI include HTMLElement.Impl({ type t = htmlHeadingElement }) + +let isInstanceOf = (_: 't): bool => %raw(`param instanceof HTMLHeadingElement`) + +let tryParse = (element: 't): option => + if isInstanceOf(element) { + Some(element->Obj.magic) + } else { + None + } diff --git a/tests/DOMAPI/QuerySelector__test.js b/tests/DOMAPI/QuerySelector__test.js new file mode 100644 index 0000000..bc00006 --- /dev/null +++ b/tests/DOMAPI/QuerySelector__test.js @@ -0,0 +1,15 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Stdlib_Option from "rescript/lib/es6/Stdlib_Option.js"; +import * as Document$WebAPI from "../../src/DOMAPI/Document.js"; +import * as HTMLHeadingElement$WebAPI from "../../src/DOMAPI/HTMLHeadingElement.js"; + +Stdlib_Option.forEach(Document$WebAPI.querySelectorAsHeading(document, "h2"), heading => { + heading.style.color = "red"; +}); + +Stdlib_Option.forEach(Stdlib_Option.flatMap(Document$WebAPI.querySelectorAsHeading(document, "h2"), HTMLHeadingElement$WebAPI.tryParse), heading => { + heading.style.color = "red"; +}); + +/* Not a pure module */ diff --git a/tests/DOMAPI/QuerySelector__test.res b/tests/DOMAPI/QuerySelector__test.res new file mode 100644 index 0000000..2f5fada --- /dev/null +++ b/tests/DOMAPI/QuerySelector__test.res @@ -0,0 +1,14 @@ +// Option 1 +Global.document +->Document.querySelectorAsHeading("h2") +->Option.forEach(heading => { + heading.style.color = "red" +}) + +// Option 2 +Global.document +->Document.querySelectorAsHeading("h2") +->Option.flatMap(HTMLHeadingElement.tryParse) +->Option.forEach(heading => { + heading.style.color = "red" +})