Chromium Code Reviews| Index: third_party/WebKit/Source/core/dom/shadow/SlotScopedTraversal.cpp |
| diff --git a/third_party/WebKit/Source/core/dom/shadow/SlotScopedTraversal.cpp b/third_party/WebKit/Source/core/dom/shadow/SlotScopedTraversal.cpp |
| index bbffc1cef8b7212c90bc0a9a4f10efaf0e6417bf..466d93ba8c1e6783921b192b35427f34b5605b7f 100644 |
| --- a/third_party/WebKit/Source/core/dom/shadow/SlotScopedTraversal.cpp |
| +++ b/third_party/WebKit/Source/core/dom/shadow/SlotScopedTraversal.cpp |
| @@ -31,25 +31,32 @@ Element* SlotScopedTraversal::nearestAncestorAssignedToSlot( |
| } |
| Element* SlotScopedTraversal::next(const Element& current) { |
| - // current.assignedSlot returns a slot only when current is assigned |
| - // explicitly |
| - // If current is assigned to a slot, return a descendant of current, which is |
| - // in the assigned scope of the same slot as current. |
| - HTMLSlotElement* slot = current.assignedSlot(); |
| + Element* next = nullptr; |
| Element* nearestAncestorAssignedToSlot = |
|
hayato
2016/10/24 06:43:26
Could we rename |nearestAncestorAssignedToSlot| to
kochi
2016/10/24 08:55:20
I agree the renaming, and adding "Inclusive" clari
|
| SlotScopedTraversal::nearestAncestorAssignedToSlot(current); |
| - if (slot) { |
| - if (Element* next = ElementTraversal::next(current, ¤t)) |
| - return next; |
| + // Search within children of an element which is directly assigned to a slot. |
|
hayato
2016/10/24 06:43:26
Could you remove |directly| from the comments in t
kochi
2016/10/24 08:55:20
Done.
|
| + if (current.assignedSlot()) { |
| + next = ElementTraversal::next(current, ¤t); |
| } else { |
| // If current is in assigned scope, find an assigned ancestor. |
| DCHECK(nearestAncestorAssignedToSlot); |
| - if (Element* next = |
| - ElementTraversal::next(current, nearestAncestorAssignedToSlot)) |
| - return next; |
| - slot = nearestAncestorAssignedToSlot->assignedSlot(); |
| - DCHECK(slot); |
| + if (current == nearestAncestorAssignedToSlot) |
|
hayato
2016/10/24 06:43:26
When does it happen?
It looks that current.assigne
kochi
2016/10/24 08:55:20
Good catch. Looks like an artifact while I was de
|
| + return nullptr; |
| + next = ElementTraversal::next(current, nearestAncestorAssignedToSlot); |
| } |
| + |
| + // Exclude elements that is assigned to another slot scope. |
| + while (next && next->assignedSlot()) |
| + next = ElementTraversal::nextSkippingChildren(*next, ¤t); |
| + |
| + if (next) { |
| + DCHECK(!next->assignedSlot()); |
| + return next; |
| + } |
| + |
| + // Seek to the next element assigned to the same slot. |
| + HTMLSlotElement* slot = nearestAncestorAssignedToSlot->assignedSlot(); |
| + DCHECK(slot); |
| HeapVector<Member<Node>> assignedNodes = slot->assignedNodes(); |
| size_t currentIndex = assignedNodes.find(*nearestAncestorAssignedToSlot); |
| DCHECK_NE(currentIndex, kNotFound); |
| @@ -64,11 +71,23 @@ Element* SlotScopedTraversal::previous(const Element& current) { |
| Element* nearestAncestorAssignedToSlot = |
| SlotScopedTraversal::nearestAncestorAssignedToSlot(current); |
| DCHECK(nearestAncestorAssignedToSlot); |
| - // NodeTraversal within nearestAncestorAssignedToSlot |
| - if (Element* previous = |
| - ElementTraversal::previous(current, nearestAncestorAssignedToSlot)) |
| - return previous; |
| - // If null, jump to previous assigned node's descendant |
| + |
| + // Search within children of an element which is directly assigned to a slot. |
| + Element* previous = |
| + ElementTraversal::previous(current, nearestAncestorAssignedToSlot); |
| + |
| + // TODO(kochi): repeatedly calling nearestAncestorAssignedToSlot() which |
| + // is O(depth from directly slotted ancestor) and can be very slow. |
| + while (previous) { |
|
hayato
2016/10/24 06:43:26
Could you extract L81-L88 as a separate function?
kochi
2016/10/24 08:55:20
Separated as a function previousWithinSameSlotScop
|
| + Element* ancestor = |
| + SlotScopedTraversal::nearestAncestorAssignedToSlot(*previous); |
| + DCHECK(ancestor); |
| + if (ancestor == nearestAncestorAssignedToSlot) |
| + return previous; |
| + previous = ancestor->parentElement(); |
| + } |
| + |
| + // Seek to the previous element assigned to the same slot. |
| const HeapVector<Member<Node>> assignedNodes = |
| nearestAncestorAssignedToSlot->assignedSlot()->assignedNodes(); |
| size_t currentIndex = |
| @@ -76,12 +95,22 @@ Element* SlotScopedTraversal::previous(const Element& current) { |
| DCHECK_NE(currentIndex, kNotFound); |
| for (; currentIndex > 0; --currentIndex) { |
| const Member<Node> assignedPrevious = assignedNodes[currentIndex - 1]; |
| - if (assignedPrevious->isElementNode()) { |
| - if (Element* last = |
| - ElementTraversal::lastWithin(*toElement(assignedPrevious))) |
| - return last; |
| + if (!assignedPrevious->isElementNode()) |
| + continue; |
| + |
| + Element* last = ElementTraversal::lastWithin(*toElement(assignedPrevious)); |
| + if (!last) |
| return toElement(assignedPrevious); |
| + |
| + while (last) { |
| + Element* ancestor = |
| + SlotScopedTraversal::nearestAncestorAssignedToSlot(*last); |
| + DCHECK(ancestor); |
| + if (ancestor == assignedPrevious) |
| + return last; |
| + last = ancestor->parentElement(); |
| } |
| + NOTREACHED(); |
| } |
| return nullptr; |
| } |