tree: 4a1c1de40f078decfd9755e8436e9506c972b856 [path history] [tgz]
  1. events/
  2. AccessibleNode.cpp
  3. AccessibleNode.h
  4. AccessibleNode.idl
  5. AccessibleNodeList.cpp
  6. AccessibleNodeList.h
  7. AccessibleNodeList.idl
  8. AncestorList.h
  9. AnimationWorkletProxyClient.cpp
  10. AnimationWorkletProxyClient.h
  11. Attr.cpp
  12. Attr.h
  13. Attr.idl
  14. Attribute.h
  15. AttributeCollection.h
  16. AttrTest.cpp
  17. AXObjectCache.cpp
  18. AXObjectCache.h
  19. AXObjectCacheBase.cpp
  20. AXObjectCacheBase.h
  21. BUILD.gn
  22. CDATASection.cpp
  23. CDATASection.h
  24. CDATASection.idl
  25. CharacterData.cpp
  26. CharacterData.h
  27. CharacterData.idl
  28. ChildFrameDisconnector.cpp
  29. ChildFrameDisconnector.h
  30. ChildListMutationScope.cpp
  31. ChildListMutationScope.h
  32. ChildNode.h
  33. ChildNode.idl
  34. ChildNodeList.cpp
  35. ChildNodeList.h
  36. ClassCollection.cpp
  37. ClassCollection.h
  38. ClassicPendingScript.cpp
  39. ClassicPendingScript.h
  40. ClassicScript.cpp
  41. ClassicScript.h
  42. CollectionIndexCache.h
  43. Comment.cpp
  44. Comment.h
  45. Comment.idl
  46. CommonDefinitions.idl
  47. CompositorWorkerProxyClient.cpp
  48. CompositorWorkerProxyClient.h
  49. ContainerNode.cpp
  50. ContainerNode.h
  51. ContextFeatures.cpp
  52. ContextFeatures.h
  53. ContextFeaturesClientImpl.cpp
  54. ContextFeaturesClientImpl.h
  55. ContextLifecycleNotifier.cpp
  56. ContextLifecycleNotifier.h
  57. ContextLifecycleObserver.cpp
  58. ContextLifecycleObserver.h
  59. CSSSelectorWatch.cpp
  60. CSSSelectorWatch.h
  61. CSSSelectorWatchTest.cpp
  62. DatasetDOMStringMap.cpp
  63. DatasetDOMStringMap.h
  64. DecodedDataDocumentParser.cpp
  65. DecodedDataDocumentParser.h
  66. DistributedNodes.cpp
  67. DistributedNodes.h
  68. Document.cpp
  69. Document.h
  70. Document.idl
  71. DocumentEncodingData.cpp
  72. DocumentEncodingData.h
  73. DocumentFragment.cpp
  74. DocumentFragment.h
  75. DocumentFragment.idl
  76. DocumentInit.cpp
  77. DocumentInit.h
  78. DocumentLifecycle.cpp
  79. DocumentLifecycle.h
  80. DocumentOrShadowRoot.h
  81. DocumentOrShadowRoot.idl
  82. DocumentParser.cpp
  83. DocumentParser.h
  84. DocumentParserClient.h
  85. DocumentParserTiming.cpp
  86. DocumentParserTiming.h
  87. DocumentShutdownNotifier.cpp
  88. DocumentShutdownNotifier.h
  89. DocumentShutdownObserver.cpp
  90. DocumentShutdownObserver.h
  91. DocumentStatisticsCollector.cpp
  92. DocumentStatisticsCollector.h
  93. DocumentStatisticsCollectorTest.cpp
  94. DocumentStyleSheetCollection.cpp
  95. DocumentStyleSheetCollection.h
  96. DocumentStyleSheetCollector.cpp
  97. DocumentStyleSheetCollector.h
  98. DocumentTest.cpp
  99. DocumentTiming.cpp
  100. DocumentTiming.h
  101. DocumentType.cpp
  102. DocumentType.h
  103. DocumentType.idl
  104. DocumentWriteIntervention.cpp
  105. DocumentWriteIntervention.h
  106. DOMException.cpp
  107. DOMException.h
  108. DOMException.idl
  109. DOMHighResTimeStamp.h
  110. DOMImplementation.cpp
  111. DOMImplementation.h
  112. DOMImplementation.idl
  113. DOMImplementationTest.cpp
  114. DOMNodeIds.cpp
  115. DOMNodeIds.h
  116. DOMStringList.cpp
  117. DOMStringList.h
  118. DOMStringList.idl
  119. DOMStringMap.cpp
  120. DOMStringMap.h
  121. DOMStringMap.idl
  122. DOMTimeStamp.h
  123. DOMTokenList.cpp
  124. DOMTokenList.h
  125. DOMTokenList.idl
  126. Element.cpp
  127. Element.h
  128. Element.idl
  129. ElementCreationOptions.idl
  130. ElementData.cpp
  131. ElementData.h
  132. ElementDataCache.cpp
  133. ElementDataCache.h
  134. ElementDefinitionOptions.idl
  135. ElementRareData.cpp
  136. ElementRareData.h
  137. ElementRegistrationOptions.idl
  138. ElementShadow.cpp
  139. ElementShadow.h
  140. ElementShadowV0.cpp
  141. ElementShadowV0.h
  142. ElementTest.cpp
  143. ElementTraversal.h
  144. ElementVisibilityObserver.cpp
  145. ElementVisibilityObserver.h
  146. ElementVisibilityObserverTest.cpp
  147. EmptyNodeList.cpp
  148. EmptyNodeList.h
  149. ExceptionCode.h
  150. ExecutionContext.cpp
  151. ExecutionContext.h
  152. FirstLetterPseudoElement.cpp
  153. FirstLetterPseudoElement.h
  154. FirstLetterPseudoElementTest.cpp
  155. FlatTreeTraversal.cpp
  156. FlatTreeTraversal.h
  157. FlatTreeTraversalTest.cpp
  158. FrameRequestCallback.h
  159. FrameRequestCallback.idl
  160. FrameRequestCallbackCollection.cpp
  161. FrameRequestCallbackCollection.h
  162. FunctionStringCallback.idl
  163. GetRootNodeOptions.idl
  164. GlobalEventHandlers.h
  165. GlobalEventHandlers.idl
  166. IconURL.cpp
  167. IconURL.h
  168. IdleDeadline.cpp
  169. IdleDeadline.h
  170. IdleDeadline.idl
  171. IdleDeadlineTest.cpp
  172. IdleRequestCallback.h
  173. IdleRequestCallback.idl
  174. IdleRequestOptions.idl
  175. IdTargetObserver.cpp
  176. IdTargetObserver.h
  177. IdTargetObserverRegistry.cpp
  178. IdTargetObserverRegistry.h
  179. IgnoreDestructiveWriteCountIncrementer.h
  180. IncrementLoadEventDelayCount.cpp
  181. IncrementLoadEventDelayCount.h
  182. Iterator.h
  183. Iterator.idl
  184. LayoutTreeBuilder.cpp
  185. LayoutTreeBuilder.h
  186. LayoutTreeBuilderTraversal.cpp
  187. LayoutTreeBuilderTraversal.h
  188. LayoutTreeBuilderTraversalTest.cpp
  189. LiveNodeList.cpp
  190. LiveNodeList.h
  191. LiveNodeListBase.cpp
  192. LiveNodeListBase.h
  193. MessageChannel.cpp
  194. MessageChannel.h
  195. MessageChannel.idl
  196. MessagePort.cpp
  197. MessagePort.h
  198. MessagePort.idl
  199. MockScriptElementBase.h
  200. Modulator.cpp
  201. Modulator.h
  202. ModulatorImpl.cpp
  203. ModulatorImpl.h
  204. ModulatorTest.cpp
  205. ModuleMap.cpp
  206. ModuleMap.h
  207. ModuleMapTest.cpp
  208. ModulePendingScript.cpp
  209. ModulePendingScript.h
  210. ModuleScript.cpp
  211. ModuleScript.h
  212. MutationObserver.cpp
  213. MutationObserver.h
  214. MutationObserver.idl
  215. MutationObserverInit.idl
  216. MutationObserverInterestGroup.cpp
  217. MutationObserverInterestGroup.h
  218. MutationObserverRegistration.cpp
  219. MutationObserverRegistration.h
  220. MutationObserverTest.cpp
  221. MutationRecord.cpp
  222. MutationRecord.h
  223. MutationRecord.idl
  224. NamedNodeMap.cpp
  225. NamedNodeMap.h
  226. NamedNodeMap.idl
  227. NameNodeList.cpp
  228. NameNodeList.h
  229. Node.cpp
  230. Node.h
  231. Node.idl
  232. NodeChildRemovalTracker.cpp
  233. NodeChildRemovalTracker.h
  234. NodeComputedStyle.h
  235. NodeFilter.h
  236. NodeFilter.idl
  237. NodeIterator.cpp
  238. NodeIterator.h
  239. NodeIterator.idl
  240. NodeIteratorBase.cpp
  241. NodeIteratorBase.h
  242. NodeList.h
  243. NodeList.idl
  244. NodeListsNodeData.cpp
  245. NodeListsNodeData.h
  246. NodeRareData.cpp
  247. NodeRareData.h
  248. NodeTest.cpp
  249. NodeTraversal.cpp
  250. NodeTraversal.h
  251. NodeTraversalStrategy.h
  252. NodeWithIndex.h
  253. NoncedElement.idl
  254. NonDocumentTypeChildNode.h
  255. NonDocumentTypeChildNode.idl
  256. NonElementParentNode.h
  257. NonElementParentNode.idl
  258. NthIndexCache.cpp
  259. NthIndexCache.h
  260. NthIndexCacheTest.cpp
  261. OWNERS
  262. ParentNode.h
  263. ParentNode.idl
  264. ParserContentPolicy.h
  265. PendingScript.cpp
  266. PendingScript.h
  267. PresentationAttributeStyle.cpp
  268. PresentationAttributeStyle.h
  269. ProcessingInstruction.cpp
  270. ProcessingInstruction.h
  271. ProcessingInstruction.idl
  272. PseudoElement.cpp
  273. PseudoElement.h
  274. PseudoElementData.h
  275. QualifiedName.cpp
  276. QualifiedName.h
  277. Range.cpp
  278. Range.h
  279. Range.idl
  280. RangeBoundaryPoint.h
  281. RangeTest.cpp
  282. RawDataDocumentParser.h
  283. README.md
  284. RemoteSecurityContext.cpp
  285. RemoteSecurityContext.h
  286. SandboxFlags.cpp
  287. SandboxFlags.h
  288. ScopedWindowFocusAllowedIndicator.h
  289. Script.h
  290. ScriptableDocumentParser.cpp
  291. ScriptableDocumentParser.h
  292. ScriptedAnimationController.cpp
  293. ScriptedAnimationController.h
  294. ScriptedAnimationControllerTest.cpp
  295. ScriptedIdleTaskController.cpp
  296. ScriptedIdleTaskController.h
  297. ScriptedIdleTaskControllerTest.cpp
  298. ScriptElementBase.cpp
  299. ScriptElementBase.h
  300. ScriptLoader.cpp
  301. ScriptLoader.h
  302. ScriptModuleResolver.h
  303. ScriptModuleResolverImpl.cpp
  304. ScriptModuleResolverImpl.h
  305. ScriptModuleResolverImplTest.cpp
  306. ScriptRunner.cpp
  307. ScriptRunner.h
  308. ScriptRunnerTest.cpp
  309. SecurityContext.cpp
  310. SecurityContext.h
  311. SelectorQuery.cpp
  312. SelectorQuery.h
  313. SelectorQueryTest.cpp
  314. SelectRuleFeatureSet.cpp
  315. SelectRuleFeatureSet.h
  316. ShadowDOMV0Test.cpp
  317. ShadowRoot.cpp
  318. ShadowRoot.h
  319. ShadowRoot.idl
  320. ShadowRootInit.idl
  321. ShadowRootRareDataV0.h
  322. ShadowTreeStyleSheetCollection.cpp
  323. ShadowTreeStyleSheetCollection.h
  324. SimulatedClickOptions.h
  325. SinkDocument.cpp
  326. SinkDocument.h
  327. SlotAssignment.cpp
  328. SlotAssignment.h
  329. SpaceSplitString.cpp
  330. SpaceSplitString.h
  331. SpaceSplitStringTest.cpp
  332. StaticNodeList.h
  333. StaticRange.cpp
  334. StaticRange.h
  335. StaticRange.idl
  336. StaticRangeTest.cpp
  337. StyleChangeReason.cpp
  338. StyleChangeReason.h
  339. StyleElement.cpp
  340. StyleElement.h
  341. StyleElementTest.cpp
  342. StyleEngine.cpp
  343. StyleEngine.h
  344. StyleEngineContext.cpp
  345. StyleEngineContext.h
  346. StyleEngineTest.cpp
  347. stylerecalc.md
  348. StyleSheetCandidate.cpp
  349. StyleSheetCandidate.h
  350. StyleSheetCollection.cpp
  351. StyleSheetCollection.h
  352. SuspendableObject.cpp
  353. SuspendableObject.h
  354. SuspendableObjectTest.cpp
  355. SynchronousMutationNotifier.cpp
  356. SynchronousMutationNotifier.h
  357. SynchronousMutationObserver.cpp
  358. SynchronousMutationObserver.h
  359. SyncReattachContext.cpp
  360. SyncReattachContext.h
  361. TagCollection.cpp
  362. TagCollection.h
  363. TaskRunnerHelper.cpp
  364. TaskRunnerHelper.h
  365. TemplateContentDocumentFragment.h
  366. Text.cpp
  367. Text.h
  368. Text.idl
  369. TextLinkColors.cpp
  370. TextLinkColors.h
  371. TextTest.cpp
  372. ThrowOnDynamicMarkupInsertionCountIncrementer.h
  373. Touch.cpp
  374. Touch.h
  375. Touch.idl
  376. TouchInit.idl
  377. TouchList.cpp
  378. TouchList.h
  379. TouchList.idl
  380. TransformSource.h
  381. TransformSourceLibxslt.cpp
  382. TreeOrderedList.cpp
  383. TreeOrderedList.h
  384. TreeOrderedMap.cpp
  385. TreeOrderedMap.h
  386. TreeScope.cpp
  387. TreeScope.h
  388. TreeScopeAdopter.cpp
  389. TreeScopeAdopter.h
  390. TreeScopeStyleSheetCollection.cpp
  391. TreeScopeStyleSheetCollection.h
  392. TreeScopeTest.cpp
  393. TreeWalker.cpp
  394. TreeWalker.h
  395. TreeWalker.idl
  396. UserActionElementSet.cpp
  397. UserActionElementSet.h
  398. UserGestureIndicator.cpp
  399. UserGestureIndicator.h
  400. UserGestureIndicatorTest.cpp
  401. V0InsertionPoint.cpp
  402. V0InsertionPoint.h
  403. ViewportDescription.cpp
  404. ViewportDescription.h
  405. VisitedLinkState.cpp
  406. VisitedLinkState.h
  407. WeakIdentifierMap.h
  408. WhitespaceAttacher.cpp
  409. WhitespaceAttacher.h
  410. WhitespaceAttacherTest.cpp
  411. WhitespaceLayoutObjects.md
  412. XMLDocument.cpp
  413. XMLDocument.h
  414. XMLDocument.idl
third_party/WebKit/Source/core/dom/README.md

DOM

Rendered

Author: hayato@chromium.org

The Source/core/dom directory contains the implementation of DOM.

Basically, this directory should contain only a file which is related to DOM Standard. However, for historical reasons, Source/core/dom directory has been used as if it were misc directory. As a result, unfortunately, this directory contains a lot of files which are not directly related to DOM.

Please don‘t add unrelated files to this directory any more. We are trying to organize the files so that developers wouldn’t get confused at seeing this directory.

  • See the spreadsheet, as a rough plan to organize Source/core/dom files.

    The classification in the spreadsheet might be wrong. Please update the spreadsheet, and move files if you can, if you know more appropriate places for each file.

  • See crbug.com/738794 for tracking our efforts.

Node and Node Tree

In this README, we draw a tree in left-to-right direction. A is the root of the tree.

A
├───B
├───C
   ├───D
   └───E
└───F

Node is a base class of all kinds of nodes in a node tree. Each Node has following 3 pointers (but not limited to):

  • parent_or_shadow_host_node_: Points to the parent (or the shadow host if it is a shadow root; explained later)
  • previous_: Points to the previous sibling
  • next_: Points to the next sibling

ContainerNode, from which Element extends, has additional pointers for its child:

  • first_child_: The meaning is obvious.
  • last_child_: Nit.

That means:

  • Siblings are stored as a linked list. It takes O(N) to access a parent's n-th child.
  • Parent can't tell how many children it has in O(1).

Further info:

  • Node, ContainerNode

C++11 range-based for loops for traversing a tree

You can traverse a tree manually:

// In C++

// Traverse a children.
for (Node* child = parent.firstChild(); child; child = child->nextSibling()) {
  ...
}

// ...

// Traverse nodes in tree order, depth-first traversal.
void foo(const Node& node) {
  ...
  for (Node* child = node.firstChild(); child; child = child->nextSibling()) {
    foo(*child);  // Recursively
  }
}

However, traversing a tree in this way might be error-prone. Instead, you can use NodeTraversal and ElementTraversal. They provides a C++11's range-based for loops, such as:

// In C++
for (Node& child : NodeTraversal::childrenOf(parent) {
  ...
}

e.g. Given a parent A, this traverses B, C, and F in this order.

// In C++
for (Node& node : NodeTraversal::startsAt(root)) {
  ...
}

e.g. Given the root A, this traverses A, B, C, D, E, and F in this order.

There are several other useful range-based for loops for each purpose. The cost of using range-based for loops is zero because everything can be inlined.

Further info:

  • NodeTraversal and ElementTraversal (more type-safe version)
  • The CL, which introduced these range-based for loops.

Shadow Tree

A shadow tree is a node tree whose root is a ShadowRoot. From web developer's perspective, a shadow root can be created by calling element.attachShadow{ ... } API. The element here is called a shadow host, or just a host if the context is clear.

  • A shadow root is always attached to another node tree through its host. A shadow tree is therefore never alone.
  • The node tree of a shadow root’s host is sometimes referred to as the light tree.

For example, given the example node tree:

A
├───B
├───C
   ├───D
   └───E
└───F

Web developers can create a shadow root, and manipulate the shadow tree in the following way:

// In JavaScript
const b = document.querySelector('#B');
const shadowRoot = b.attachShadow({ mode: 'open'} )
const sb = document.createElement('div');
shadowRoot.appendChild(sb);

The resulting shadow tree would be:

shadowRoot
└── sb

The shadowRoot has one child, sb. This shadow tree is being attached to B:

A
└── B
    ├──/shadowRoot
       └── sb
    ├── C
       ├── D
       └── E
    └── F

In this README, a notation (──/) is used to represent a shadowhost-shadowroot relationship, in a composed tree. A composed tree will be explained later. A shadowhost-shadowroot is 1:1 relationship.

Though a shadow root has always a corresponding shadow host element, a light tree and a shadow tree should be considered separately, from a node tree's perspective. (──/) is NOT a parent-child relationship in a node tree.

For example, even though B hosts the shadow tree, shadowRoot is not considered as a child of B. The means the following traversal:

// In C++
for (Node& node : NodeTraversal::startsAt(A)) {
  ...
}

traverses only A, B, C, D, E and F nodes. It never visits shadowRoot nor sb. NodeTraversal never cross a shadow boundary, ──/.

Further info:

  • ShadowRoot
  • Element#attachShadow

TreeScope

Document and ShadowRoot are always the root of a node tree. BothDocument and ShadowRoot implements TreeScope.

TreeScope maintains a lot of information about the underlying tree for efficiency. For example, TreeScope has a id-to-element mapping, as TreeOrderedMap, so that querySelector('#foo') can find an element whose id attribute is “foo” in O(1). In other words, root.querySelector('#foo') can be slow if that is used in a node tree whose root is not TreeScope.

Each Node has tree_scope_ pointer, which points to:

  • The root node: if the node's root is either Document or ShadowRoot.
  • owner document, otherwise.

The means tree_scope_ pointer is always non-null (except for while in a DOM mutation), but it doesn‘t always point to the node’s root.

Since each node doesn't have a pointer which always points to the root, Node::getRootNode(...) may take O(N) if the node is neither in a document tree nor in a shadow tree. If the node is in TreeScope (Node#IsInTreeScope() can tell it), we can get the root in O(1).

Each node has flags, which is updated in DOM mutation, so that we can tell whether the node is in a document tree, in a shadow tree, or in none of them, by using Node::IsInDocumentTree() and/or Node::IsInShadowTree().

If you want to add new features to Document, Document might be a wrong place to add. Instead, please consider to add functionality to TreeScope. We want to treat a document tree and a shadow tree equally as much as possible.

Example

document
└── a1
    ├──/shadowRoot1
       └── s1
    └── a2
        └── a3

document-fragment
└── b1
    ├──/shadowRoot2
       └── t2
    └── b2
        └── b3
  • Here, there are 4 node trees; The root node of each tree is document, shadowRoot1, document-fragment, and shadowRoot2.
  • Suppose that each node is created by document.createElement(...) (except for Document and ShadowRoot). That means each node's owner document is document.
nodenode's rootnode's _tree_scope points to:
documentdocument (self)document (self)
a1documentdocument
a2documentdocument
a3documentdocument
shadowRoot1shadowRoot1 (self)shadowRoot1 (self)
s1shadowRoot1shadowRoot1
document-fragmentdocument-fragment (self)document
b1document-fragmentdocument
b2document-fragmentdocument
b3document-fragmentdocument
shadowRoot2shadowRoot2 (self)shadowRoot2 (self)
t1shadowRoot2shadowRoot2

Further Info:

Composed Tree (a tree of node trees)

In the previous picture, you might think that more than one node trees, a document tree and a shadow tree, were connected to each other. That is true in some sense. The following is a more complex example:

document
├── a1 (host)
   ├──/shadowRoot1
      └── b1
   └── a2 (host)
       ├──/shadowRoot2
          ├── c1
             ├── c2
             └── c3
          └── c4
       ├── a3
       └── a4
└── a5
    └── a6 (host)
        └──/shadowRoot3
            └── d1
                ├── d2
                ├── d3 (host)
                   └──/shadowRoot4
                       ├── e1
                       └── e2
                └── d4 (host)
                    └──/shadowRoot5
                        ├── f1
                        └── f2

If you see this carefully, you can notice that this composed tree is composed of 6 node trees; 1 document tree and 5 shadow trees:

  • document tree

    document
    ├── a1 (host)
       └── a2 (host)
           ├── a3
           └── a4
    └── a5
        └── a6 (host)
    
  • shadow tree 1

    shadowRoot1
    └── b1
    
  • shadow tree 2

    shadowRoot2
    ├── c1
       ├── c2
       └── c3
    └── c4
    
  • shadow tree 3

    shadowRoot3
    └── d1
        ├── d2
        ├── d3 (host)
        └── d4 (host)
    
  • shadow tree 4

    shadowRoot4
    ├── e1
    └── e2
    
  • shadow tree 5

    shadowRoot5
    ├── f1
    └── f2
    

If we consider each node tree as node of a super-tree, we can draw a super-tree as such:

document
├── shadowRoot1
├── shadowRoot2
└── shadowRoot3
    ├── shadowRoot4
    └── shadowRoot5

Here, a root node is used as a representative of each node tree; A root node and a node tree itself can be sometimes exchangeable in explanations.

We call this kind of a super-tree (a tree of node trees) a composed tree. The concept of a composed tree is very useful to understand how Shadow DOM's encapsulation works.

DOM Standard defines the following terminologies:

For example,

  • d1's shadow-including ancestor nodes are shadowRoot3, a6, a5, and document
  • d1's shadow-including descendant nodes are d2, d3, shadowRoot4, e1, e2, d4, shadowRoot5, f1, and f2.

To honor Shadow DOM's encapsulation, we have a concept of visibility relationship between two nodes.

In the following table, “-” means that “node A is visible from node B”.

A \ Bdocumenta1a2b1c1d1d2e1f1
document---------
a1---------
a2---------
b1hiddenhiddenhidden-hiddenhiddenhiddenhiddenhidden
c1hiddenhiddenhiddenhidden-hiddenhiddenhiddenhidden
d1hiddenhiddenhiddenhiddenhidden----
d2hiddenhiddenhiddenhiddenhidden----
e1hiddenhiddenhiddenhiddenhiddenhiddenhidden-hidden
f1hiddenhiddenhiddenhiddenhiddenhiddenhiddenhidden-

For example, document is visible from any nodes.

To understand visibility relationship easily, here is a rule of thumb:

  • If node B can reach node A by traversing an edge (in the first picture of this section), recursively, A is visible from B.
  • However, an edge of (──/) ( shadowhost-shadowroot relationship) is one-directional:
    • From a shadow root to the shadow host -> Okay
    • From a shadow host to the shadow root -> Forbidden

In other words, a node in an inner tree can see a node in an outer tree in a composed tree, but the opposite is not true.

We have designed (or re-designed) a bunch of Web-facing APIs to honor this basic principle. If you add a new API to the web platform and Blink, please consider this rule and don't leak a node which should be hidden to web developers.

Warning: Unfortunately, a composed tree had a different meaning in the past; it was used to specify a flat tree (which will be explained later). If you find a wrong usage of a composed tree in Blink, please fix it.

Further Info:

  • TreeScope::ParentTreeScope()
  • Node::IsConnected()
  • DOM Standard: connected
  • DOM Standard: retarget

Flat tree

A composed tree itself can‘t be rendered as is. From the rendering’s perspective, Blink has to construct a layout tree, which would be used as an input to the paint phase. A layout tree is a tree whose node is LayoutObject, which points to Node in a node tree, plus additional calculated layout information.

Before the Web Platform got Shadow DOM, the structure of a layout tree is almost similar to the structure of a document tree; where only one node tree, document tree, is being involved there.

Since the Web Platform got Shadow DOM, we now have a composed tree which is composed of multiple node trees, instead of a single node tree. That means We have to flatten the composed tree to the one node tree, called a flat tree, from which a layout tree is constructed.

For example, given the following composed tree,

document
├── a1 (host)
   ├──/shadowRoot1
      └── b1
   └── a2 (host)
       ├──/shadowRoot2
          ├── c1
             ├── c2
             └── c3
          └── c4
       ├── a3
       └── a4
└── a5
    └── a6 (host)
        └──/shadowRoot3
            └── d1
                ├── d2
                ├── d3 (host)
                   └──/shadowRoot4
                       ├── e1
                       └── e2
                └── d4 (host)
                    └──/shadowRoot5
                        ├── f1
                        └── f2

This composed tree would be flattened into the following flat tree (assuming there are not <slot> elements there):

document
├── a1 (host)
   └── b1
└── a5
    └── a6 (host)
        └── d1
            ├── d2
            ├── d3 (host)
               ├── e1
               └── e2
            └── d4 (host)
                ├── f1
                └── f2

We can't explain the exact algorithm how to flatten a composed tree into a flat tree until I explain the concept of slots and node distribution If we are ignoring the effect of <slot>, we can have the following simple definition. A flat tree can be defined as:

  • A root of a flat tree: document
  • Given node A which is in a flat tree, its children are defined, recursively, as follows:
    • If A is a shadow host, its shadow root's children
    • Otherwise, A's children

Distribution and slots

TODO(hayato): Explain.

FlatTreeTraversal

TODO(hayato): Explain.

DOM mutations

TODO(hayato): Explain.

Related flags

TODO(hayato): Explain.

Event path and Event Retargeting

TODO(hayato): Explain.