Skip to content
Open
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
3 changes: 3 additions & 0 deletions src/elements/NativeElement.bs.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
'use strict';

var DOMAPI$ReactNative = require("../types/DOMAPI.bs.js");
var NativeMethods$ReactNative = require("./NativeMethods.bs.js");

NativeMethods$ReactNative.Make({});

DOMAPI$ReactNative.$$Element.Impl({});

/* Not a pure module */
6 changes: 5 additions & 1 deletion src/elements/NativeElement.res
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
type element
type element = DOMAPI.element
type ref = Ref.t<element>

include NativeMethods.Make({
type t = element
})

include DOMAPI.Element.Impl({
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not expose DOM ref APIs to supported 0.81 apps

NativeElement now includes the new DOM-style methods on every ref, but this package still advertises react-native >=0.81.0 support. React Native only started returning DOM-like nodes from refs in 0.82, so an app that is still on 0.81 can compile against these bindings and then hit undefined is not a function at runtime as soon as it calls one of the newly exposed methods.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be done before release

type t = element
})
61 changes: 61 additions & 0 deletions src/types/DOMAPI.bs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'use strict';


var $$NodeList = {};

var $$HTMLCollection = {};

function Impl(T) {
return {};
}

var $$Node = {
Impl: Impl
};

function Impl$1(T) {
return {};
}

var $$Element = {
Impl: Impl$1
};

var $$Document = {};

var $$Text = {};

function classify(node) {
switch (node.nodeType) {
case 1 :
return {
TAG: "Element",
_0: node
};
case 3 :
return {
TAG: "Text",
_0: node
};
case 9 :
return {
TAG: "Document",
_0: node
};
default:
return "Unknown";
}
}

var NodeType = {
classify: classify
};

exports.$$NodeList = $$NodeList;
exports.$$HTMLCollection = $$HTMLCollection;
exports.$$Node = $$Node;
exports.$$Element = $$Element;
exports.$$Document = $$Document;
exports.$$Text = $$Text;
exports.NodeType = NodeType;
/* No side effect */
180 changes: 180 additions & 0 deletions src/types/DOMAPI.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
@@warning("-30")

type nodeList<'node> = {length: int}
type htmlCollection<'element> = {length: int}

type readOnlyNode<'node, 'document, 'element> = {
// Node
childNodes: nodeList<'node>,
firstChild: Js.Null.t<'node>,
isConnected: bool,
lastChild: Js.Null.t<'node>,
nextSibling: Js.Null.t<'node>,
nodeType: int,
nodeName: string,
nodeValue: Js.Null.t<string>,
ownerDocument: Js.Null.t<'document>,
parentElement: Js.Null.t<'element>,
parentNode: Js.Null.t<'node>,
previousSibling: Js.Null.t<'node>,
textContent: string,
}

type rec node = {
...readOnlyNode<node, document, element>,
}

and element = {
// Node
...readOnlyNode<node, document, element>,
// Element
childElementCount: int,
children: htmlCollection<element>,
clientHeight: int,
clientLeft: int,
clientTop: int,
clientWidth: int,
firstElementChild: Js.Null.t<element>,
id: string,
lastElementChild: Js.Null.t<element>,
nextElementSibling: Js.Null.t<element>,
previousElementSibling: Js.Null.t<element>,
scrollHeight: int,
scrollLeft: int,
scrollTop: int,
scrollWidth: int,
tagName: string,
// HTMLElement
offsetHeight: int,
offsetLeft: int,
offsetTop: int,
offsetWidth: int,
offsetParent: Js.Null.t<element>,
}

and text = {
// Node
...readOnlyNode<node, document, element>,
// CharacterData
data: string,
length: int,
nextElementSibling: Js.Null.t<element>,
previousElementSibling: Js.Null.t<element>,
}

and document = {
...readOnlyNode<node, document, element>,
childElementCount: int,
children: htmlCollection<element>,
documentElement: element,
firstElementChild: Js.Null.t<element>,
lastElementChild: Js.Null.t<element>,
}

module NodeList = {
@send
external item: (nodeList<'node>, int) => Js.Null.t<'node> = "item"
}

module HTMLCollection = {
@send
external item: (htmlCollection<'element>, int) => Js.Null.t<'element> = "item"

@send
external namedItem: (htmlCollection<'element>, string) => Js.Null.t<'element> = "namedItem"
}

module Node = {
module Impl = (
T: {
type t
},
) => {
external asNode: T.t => node = "%identity"

@send
external compareDocumentPosition: (T.t, node) => int = "compareDocumentPosition"
@send external contains: (T.t, node) => bool = "contains"
@send external getRootNode: T.t => node = "getRootNode"
@send external hasChildNodes: T.t => bool = "hasChildNodes"
}

include Impl({
type t = node
})
}

module Element = {
module Impl = (
T: {
type t
},
) => {
include Node.Impl({
type t = T.t
})

@send
external getBoundingClientRect: T.t => Rect.t = "getBoundingClientRect"
@send
external hasPointerCapture: (T.t, int) => bool = "hasPointerCapture"
@send
external releasePointerCapture: (T.t, int) => unit = "releasePointerCapture"
@send
external setPointerCapture: (T.t, int) => unit = "setPointerCapture"
@send external focus: T.t => unit = "focus"
@send external blur: T.t => unit = "blur"

@send external setNativeProps: (T.t, {..}) => unit = "setNativeProps"
}

include Impl({
type t = element
})
}

module Document = {
include Node.Impl({
type t = document
})

@send external getElementById: (document, string) => Js.Null.t<element> = "getElementById"
}

module Text = {
include Node.Impl({
type t = text
})

@send external substringData: (text, ~offset: int, ~count: int) => string = "substringData"
}

module NodeType = {
/*
Helper for handle NodeType
Waiting for this issue :
https://github.com/rescript-lang/rescript/issues/8280
to use this type for node instead

@tag("nodeType")
type rec node =
| @as(1) Element(element)
| @as(3) Text(text)
| @as(9) Document(document)

and remove this helper
*/
type t =
| Element(element)
| Text(text)
| Document(document)
| Unknown

let classify = (node: node) =>
switch node {
| {nodeType: 1} => Element(node->Obj.magic)
| {nodeType: 3} => Text(node->Obj.magic)
| {nodeType: 9} => Document(node->Obj.magic)
| _ => Unknown
}
}
Loading