diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d6c1c83..b045753b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,9 @@ * `WorkerGlobalScope`, `WindowOrWorkerGlobalScope`, `WorkerNavigator`, and `WorkerLocation` bindings (#57) * `Response` constructors to `Fetch` bindings (#64) +### Fixed +* `ofElement` was incorrectly returning `Dom.htmlElement` type instead of the enclosing element type (#60) + ### Miscellaneous * Converted project to rescript syntax (#18) * Added explicit values to all externals instead of using `= ""` (#40) diff --git a/lib/js/tests/Webapi/Dom/Webapi__Dom__HtmlInputElement__test.js b/lib/js/tests/Webapi/Dom/Webapi__Dom__HtmlInputElement__test.js new file mode 100644 index 00000000..0928641f --- /dev/null +++ b/lib/js/tests/Webapi/Dom/Webapi__Dom__HtmlInputElement__test.js @@ -0,0 +1,15 @@ +'use strict'; + +var Curry = require("rescript/lib/js/curry.js"); +var Caml_option = require("rescript/lib/js/caml_option.js"); +var Webapi__Dom__HtmlInputElement = require("../../../src/Webapi/Dom/Webapi__Dom__HtmlInputElement.js"); + +var input = Curry._1(Webapi__Dom__HtmlInputElement.ofElement, document.body); + +if (input !== undefined) { + var input$1 = Caml_option.valFromOption(input); + input$1.focus(); + input$1.select(); +} + +/* input Not a pure module */ diff --git a/src/Webapi/Dom/Webapi__Dom__Element.res b/src/Webapi/Dom/Webapi__Dom__Element.res index df5cb191..d909a219 100644 --- a/src/Webapi/Dom/Webapi__Dom__Element.res +++ b/src/Webapi/Dom/Webapi__Dom__Element.res @@ -1,29 +1,27 @@ /* internal, moved out of Impl to reduce unnecessary code duplication */ -let ofNode = (node: Dom.node): option<'a> => - Webapi__Dom__Node.nodeType(node) == Webapi__Dom__Types.Element ? Some(Obj.magic(node)) : None +%%private( + let ofNode = (node: Dom.node): option<'a> => + Webapi__Dom__Node.nodeType(node) == Webapi__Dom__Types.Element ? Some(Obj.magic(node)) : None + + /* + At some point we can drop IE11 support and require constructor names to be available + */ + let asHtmlElement = %raw(` + function(element) { + if ((window.constructor.name !== undefined && /^HTML\w*Element$/.test(element.constructor.name)) + || (/^\[object HTML\w*Element\]$/.test(element.constructor.toString()))) { + return element; + } + } + `) +) module Impl = ( T: { type t }, ) => { - let asHtmlElement: T.t => option = %raw(` - function(element) { - var ownerDocument = element.ownerDocument; - - if (ownerDocument != null) { - var defaultView = ownerDocument.defaultView; - - if (defaultView != null) { - var HTMLElement = defaultView.HTMLElement; - - if (HTMLElement != null && element instanceof HTMLElement) { - return element; - } - } - } - } - `) + let asHtmlElement: T.t => option = asHtmlElement /** Unsafe cast, use [asHtmlElement] instead */ external unsafeAsHtmlElement: T.t => Dom.htmlElement = "%identity" diff --git a/src/Webapi/Dom/Webapi__Dom__HtmlElement.res b/src/Webapi/Dom/Webapi__Dom__HtmlElement.res index 7903e0d6..bf3aa0ec 100644 --- a/src/Webapi/Dom/Webapi__Dom__HtmlElement.res +++ b/src/Webapi/Dom/Webapi__Dom__HtmlElement.res @@ -5,7 +5,7 @@ module Impl = ( ) => { type t_htmlElement = T.t - let ofElement = Webapi__Dom__Element.asHtmlElement + let ofElement: Dom.element => option = Obj.magic(Webapi__Dom__Element.asHtmlElement) @get external accessKey: t_htmlElement => string = "accessKey" @set external setAccessKey: (t_htmlElement, string) => unit = "accessKey" diff --git a/tests/Webapi/Dom/Webapi__Dom__HtmlInputElement__test.res b/tests/Webapi/Dom/Webapi__Dom__HtmlInputElement__test.res new file mode 100644 index 00000000..4eab5cab --- /dev/null +++ b/tests/Webapi/Dom/Webapi__Dom__HtmlInputElement__test.res @@ -0,0 +1,11 @@ +open Webapi.Dom + +// verify `ofElement` returns the correct type +@val external element: Element.t = "document.body" + +switch (element->HtmlInputElement.ofElement) { +| Some(input) => + HtmlInputElement.focus(input); + HtmlInputElement.select(input); +| None => () +}; \ No newline at end of file