diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2019-10-04 20:28:51 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-04 20:28:51 -0400 |
commit | b81e5db17aa8b3088d6034ddf86b79c69410f012 (patch) | |
tree | 579e4c23d60d1b0d038156bc28a04f74ea87b2f0 /cli/js/dom_util.ts | |
parent | 9049213867d30f7df090a83b6baf3e0717a4d2d2 (diff) |
Merge deno_cli_snapshots into deno_cli (#3064)
Diffstat (limited to 'cli/js/dom_util.ts')
-rw-r--r-- | cli/js/dom_util.ts | 85 |
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]; + } + } +} |