Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Unified Diff: third_party/WebKit/Source/core/dom/shadow/ComposedTreeTraversal.cpp

Issue 1530643003: Support slot element's fallback content feature (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: addressed Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/dom/shadow/ComposedTreeTraversal.cpp
diff --git a/third_party/WebKit/Source/core/dom/shadow/ComposedTreeTraversal.cpp b/third_party/WebKit/Source/core/dom/shadow/ComposedTreeTraversal.cpp
index 4050ea183c938d13aa89f4064d03f58a994ba969..a1c84831ebb6d643c091260743940a6577630f56 100644
--- a/third_party/WebKit/Source/core/dom/shadow/ComposedTreeTraversal.cpp
+++ b/third_party/WebKit/Source/core/dom/shadow/ComposedTreeTraversal.cpp
@@ -38,6 +38,11 @@ static inline ElementShadow* shadowFor(const Node& node)
return node.isElementNode() ? toElement(node).shadow() : nullptr;
}
+static inline bool canBeDistributedToInsertionPoint(const Node& node)
+{
+ return node.isInV0ShadowTree() || node.isChildOfV0ShadowHost();
+}
+
Node* ComposedTreeTraversal::traverseChild(const Node& node, TraversalDirection direction)
{
ElementShadow* shadow = shadowFor(node);
@@ -52,13 +57,23 @@ Node* ComposedTreeTraversal::resolveDistributionStartingAt(const Node* node, Tra
{
if (!node)
return nullptr;
- if (node->isInShadowTree() && node->containingShadowRoot()->isV1())
- return v1ResolveDistributionStartingAt(*node, direction);
- return v0ResolveDistributionStartingAt(*node, direction);
+ for (const Node* sibling = node; sibling; sibling = (direction == TraversalDirectionForward ? sibling->nextSibling() : sibling->previousSibling())) {
+ if (isHTMLSlotElement(*sibling)) {
+ const HTMLSlotElement& slot = toHTMLSlotElement(*sibling);
+ if (Node* found = (direction == TraversalDirectionForward ? slot.firstDistributedNode() : slot.lastDistributedNode()))
+ return found;
+ continue;
+ }
+ if (node->isInV0ShadowTree())
+ return v0ResolveDistributionStartingAt(*sibling, direction);
+ return const_cast<Node*>(sibling);
+ }
+ return nullptr;
}
Node* ComposedTreeTraversal::v0ResolveDistributionStartingAt(const Node& node, TraversalDirection direction)
{
+ ASSERT(!isHTMLSlotElement(node));
for (const Node* sibling = &node; sibling; sibling = (direction == TraversalDirectionForward ? sibling->nextSibling() : sibling->previousSibling())) {
if (!isActiveInsertionPoint(*sibling))
return const_cast<Node*>(sibling);
@@ -70,18 +85,6 @@ Node* ComposedTreeTraversal::v0ResolveDistributionStartingAt(const Node& node, T
return nullptr;
}
-Node* ComposedTreeTraversal::v1ResolveDistributionStartingAt(const Node& node, TraversalDirection direction)
-{
- for (const Node* sibling = &node; sibling; sibling = (direction == TraversalDirectionForward ? sibling->nextSibling() : sibling->previousSibling())) {
- if (!isHTMLSlotElement(*sibling))
- return const_cast<Node*>(sibling);
- const HTMLSlotElement& slot = toHTMLSlotElement(*sibling);
- if (Node* found = (direction == TraversalDirectionForward ? slot.firstDistributedNode() : slot.lastDistributedNode()))
- return found;
- }
- return nullptr;
-}
-
static HTMLSlotElement* finalDestinationSlotFor(const Node& node)
{
HTMLSlotElement* slot = node.assignedSlot();
@@ -93,70 +96,53 @@ static HTMLSlotElement* finalDestinationSlotFor(const Node& node)
return slot;
}
-Node* ComposedTreeTraversal::traverseSiblings(const Node& node, TraversalDirection direction)
-{
- Node* parent = node.parentNode();
- if (!parent)
- return nullptr;
- if (parent->isElementNode()) {
- if (ElementShadow* shadow = toElement(parent)->shadow()) {
- if (shadow->isV1()) {
- return v1TraverseSiblings(node, direction);
- }
- }
- }
- return v0TraverseSiblings(node, direction);
-}
-
// TODO(hayato): This may return a wrong result for a node which is not in a
// document composed tree. See ComposedTreeTraversalTest's redistribution test for details.
-Node* ComposedTreeTraversal::v0TraverseSiblings(const Node& node, TraversalDirection direction)
+Node* ComposedTreeTraversal::traverseSiblings(const Node& node, TraversalDirection direction)
{
- if (!shadowWhereNodeCanBeDistributed(node))
- return traverseSiblingsOrShadowInsertionPointSiblings(node, direction);
+ if (node.isChildOfV1ShadowHost())
+ return traverseSiblingsForV1HostChild(node, direction);
- const InsertionPoint* finalDestination = resolveReprojection(&node);
- if (!finalDestination)
- return nullptr;
- if (Node* found = (direction == TraversalDirectionForward ? finalDestination->distributedNodeNextTo(&node) : finalDestination->distributedNodePreviousTo(&node)))
- return found;
- return traverseSiblings(*finalDestination, direction);
-}
-
-Node* ComposedTreeTraversal::v1TraverseSiblings(const Node& node, TraversalDirection direction)
-{
- HTMLSlotElement* slot = finalDestinationSlotFor(node);
- if (!slot)
- return resolveDistributionStartingAt(direction == TraversalDirectionForward ? node.nextSibling() : node.previousSibling(), direction);
- if (Node* siblingInDistributedNodes = (direction == TraversalDirectionForward ? slot->distributedNodeNextTo(node) : slot->distributedNodePreviousTo(node)))
- return siblingInDistributedNodes;
- return v1TraverseSiblings(*slot, direction);
-}
+ if (shadowWhereNodeCanBeDistributed(node))
+ return traverseSiblingsForV0Distribution(node, direction);
-Node* ComposedTreeTraversal::traverseSiblingsOrShadowInsertionPointSiblings(const Node& node, TraversalDirection direction)
-{
if (Node* found = resolveDistributionStartingAt(direction == TraversalDirectionForward ? node.nextSibling() : node.previousSibling(), direction))
return found;
+ if (!node.isInV0ShadowTree())
+ return nullptr;
+
+ // For v0 older shadow tree
if (node.parentNode() && node.parentNode()->isShadowRoot()) {
ShadowRoot* parentShadowRoot = toShadowRoot(node.parentNode());
if (!parentShadowRoot->isYoungest()) {
HTMLShadowElement* assignedInsertionPoint = parentShadowRoot->shadowInsertionPointOfYoungerShadowRoot();
ASSERT(assignedInsertionPoint);
- return traverseSiblingsOrShadowInsertionPointSiblings(*assignedInsertionPoint, direction);
+ return traverseSiblings(*assignedInsertionPoint, direction);
}
}
return nullptr;
}
-static ElementShadow* parentElementShadow(const Node& node)
+Node* ComposedTreeTraversal::traverseSiblingsForV1HostChild(const Node& node, TraversalDirection direction)
{
- Node* parent = node.parentNode();
- if (!parent)
+ HTMLSlotElement* slot = finalDestinationSlotFor(node);
+ if (!slot)
return nullptr;
- if (parent->isElementNode())
- return toElement(parent)->shadow();
- return nullptr;
+ if (Node* siblingInDistributedNodes = (direction == TraversalDirectionForward ? slot->distributedNodeNextTo(node) : slot->distributedNodePreviousTo(node)))
+ return siblingInDistributedNodes;
+ return traverseSiblings(*slot, direction);
+}
+
+Node* ComposedTreeTraversal::traverseSiblingsForV0Distribution(const Node& node, TraversalDirection direction)
+{
+ const InsertionPoint* finalDestination = resolveReprojection(&node);
+ if (!finalDestination)
+ return nullptr;
+ if (Node* found = (direction == TraversalDirectionForward ? finalDestination->distributedNodeNextTo(&node) : finalDestination->distributedNodePreviousTo(&node)))
+ return found;
+ return traverseSiblings(*finalDestination, direction);
+
}
ContainerNode* ComposedTreeTraversal::traverseParent(const Node& node, ParentTraversalDetails* details)
@@ -165,43 +151,49 @@ ContainerNode* ComposedTreeTraversal::traverseParent(const Node& node, ParentTra
if (node.isPseudoElement())
return node.parentOrShadowHostNode();
- ElementShadow* shadow = parentElementShadow(node);
- if (shadow && shadow->isV1())
- return v1TraverseParent(node);
- if (shadowWhereNodeCanBeDistributed(node))
- return v0TraverseParent(node, details);
- return traverseParentOrHost(node);
-}
+ if (node.isChildOfV1ShadowHost()) {
+ HTMLSlotElement* slot = finalDestinationSlotFor(node);
+ if (!slot)
+ return nullptr;
+ return traverseParent(*slot);
+ }
-ContainerNode* ComposedTreeTraversal::v1TraverseParent(const Node& node)
-{
- HTMLSlotElement* slot = finalDestinationSlotFor(node);
- if (!slot)
- return nullptr;
- if (parentElementShadow(*slot)) {
- // The node is distributed to the |slot|, however, |slot|, which is a
- // child of a shadow host, is not assigned to any slots.
- return nullptr;
+ Element* parent = node.parentElement();
+ if (parent && isHTMLSlotElement(parent)) {
+ HTMLSlotElement& slot = toHTMLSlotElement(*parent);
+ if (!slot.getAssignedNodes().isEmpty())
+ return nullptr;
+ return traverseParent(slot, details);
}
- return traverseParentOrHost(*slot);
+
+ if (canBeDistributedToInsertionPoint(node))
+ return traverseParentForV0(node, details);
+
+ ASSERT(!shadowWhereNodeCanBeDistributed(node));
+ return traverseParentOrHost(node);
}
-ContainerNode* ComposedTreeTraversal::v0TraverseParent(const Node& node, ParentTraversalDetails* details)
+ContainerNode* ComposedTreeTraversal::traverseParentForV0(const Node& node, ParentTraversalDetails* details)
{
- if (const InsertionPoint* insertionPoint = resolveReprojection(&node)) {
- if (details)
- details->didTraverseInsertionPoint(insertionPoint);
- // The node is distributed. But the distribution was stopped at this insertion point.
- if (shadowWhereNodeCanBeDistributed(*insertionPoint))
- return nullptr;
- return traverseParentOrHost(*insertionPoint);
+ if (shadowWhereNodeCanBeDistributed(node)) {
+ if (const InsertionPoint* insertionPoint = resolveReprojection(&node)) {
+ if (details)
+ details->didTraverseInsertionPoint(insertionPoint);
+ // The node is distributed. But the distribution was stopped at this insertion point.
+ if (shadowWhereNodeCanBeDistributed(*insertionPoint))
+ return nullptr;
+ return traverseParent(*insertionPoint);
+ }
+ return nullptr;
}
- return nullptr;
+ ContainerNode* parent = traverseParentOrHost(node);
+ if (isActiveInsertionPoint(*parent))
+ return nullptr;
+ return parent;
}
-inline ContainerNode* ComposedTreeTraversal::traverseParentOrHost(const Node& node)
+ContainerNode* ComposedTreeTraversal::traverseParentOrHost(const Node& node)
{
- // TODO(hayato): Support fallback contents of slots. The parent can be a slot.
ContainerNode* parent = node.parentNode();
if (!parent)
return nullptr;
@@ -211,10 +203,7 @@ inline ContainerNode* ComposedTreeTraversal::traverseParentOrHost(const Node& no
ASSERT(!shadowRoot->shadowInsertionPointOfYoungerShadowRoot());
if (!shadowRoot->isYoungest())
return nullptr;
- Element* host = shadowRoot->host();
- if (isActiveInsertionPoint(*host))
- return nullptr;
- return host;
+ return shadowRoot->host();
}
Node* ComposedTreeTraversal::childAt(const Node& node, unsigned index)

Powered by Google App Engine
This is Rietveld 408576698