summaryrefslogtreecommitdiff
path: root/cli/js/dom_util.ts
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2019-10-04 20:28:51 -0400
committerGitHub <noreply@github.com>2019-10-04 20:28:51 -0400
commitb81e5db17aa8b3088d6034ddf86b79c69410f012 (patch)
tree579e4c23d60d1b0d038156bc28a04f74ea87b2f0 /cli/js/dom_util.ts
parent9049213867d30f7df090a83b6baf3e0717a4d2d2 (diff)
Merge deno_cli_snapshots into deno_cli (#3064)
Diffstat (limited to 'cli/js/dom_util.ts')
-rw-r--r--cli/js/dom_util.ts85
1 files changed, 85 insertions, 0 deletions
diff --git a/cli/js/dom_util.ts b/cli/js/dom_util.ts
new file mode 100644
index 000000000..725a35aaf
--- /dev/null
+++ b/cli/js/dom_util.ts
@@ -0,0 +1,85 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+// Utility functions for DOM nodes
+import * as domTypes from "./dom_types.ts";
+
+export function isNode(nodeImpl: domTypes.EventTarget | null): boolean {
+ return Boolean(nodeImpl && "nodeType" in nodeImpl);
+}
+
+export function isShadowRoot(nodeImpl: domTypes.EventTarget | null): boolean {
+ return Boolean(
+ nodeImpl &&
+ nodeImpl[domTypes.eventTargetNodeType] ===
+ domTypes.NodeType.DOCUMENT_FRAGMENT_NODE &&
+ nodeImpl[domTypes.eventTargetHost] != null
+ );
+}
+
+export function isSlotable(nodeImpl: domTypes.EventTarget | null): boolean {
+ return Boolean(
+ nodeImpl &&
+ (nodeImpl[domTypes.eventTargetNodeType] ===
+ domTypes.NodeType.ELEMENT_NODE ||
+ nodeImpl[domTypes.eventTargetNodeType] === domTypes.NodeType.TEXT_NODE)
+ );
+}
+
+// https://dom.spec.whatwg.org/#node-trees
+// const domSymbolTree = Symbol("DOM Symbol Tree");
+
+// https://dom.spec.whatwg.org/#concept-shadow-including-inclusive-ancestor
+export function isShadowInclusiveAncestor(
+ ancestor: domTypes.EventTarget | null,
+ node: domTypes.EventTarget | null
+): boolean {
+ while (isNode(node)) {
+ if (node === ancestor) {
+ return true;
+ }
+
+ if (isShadowRoot(node)) {
+ node = node && node[domTypes.eventTargetHost];
+ } else {
+ node = null; // domSymbolTree.parent(node);
+ }
+ }
+
+ return false;
+}
+
+export function getRoot(
+ node: domTypes.EventTarget | null
+): domTypes.EventTarget | null {
+ const root = node;
+
+ // for (const ancestor of domSymbolTree.ancestorsIterator(node)) {
+ // root = ancestor;
+ // }
+
+ return root;
+}
+
+// https://dom.spec.whatwg.org/#retarget
+export function retarget(
+ a: domTypes.EventTarget | null,
+ b: domTypes.EventTarget
+): domTypes.EventTarget | null {
+ while (true) {
+ if (!isNode(a)) {
+ return a;
+ }
+
+ const aRoot = getRoot(a);
+
+ if (aRoot) {
+ if (
+ !isShadowRoot(aRoot) ||
+ (isNode(b) && isShadowInclusiveAncestor(aRoot, b))
+ ) {
+ return a;
+ }
+
+ a = aRoot[domTypes.eventTargetHost];
+ }
+ }
+}