Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/dom/shadow/SlotScopedTraversal.h" | 5 #include "core/dom/shadow/SlotScopedTraversal.h" |
| 6 | 6 |
| 7 #include "core/dom/Element.h" | 7 #include "core/dom/Element.h" |
| 8 #include "core/dom/ElementTraversal.h" | 8 #include "core/dom/ElementTraversal.h" |
| 9 #include "core/html/HTMLSlotElement.h" | 9 #include "core/html/HTMLSlotElement.h" |
| 10 | 10 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 // is directly assigned to a slot. | 24 // is directly assigned to a slot. |
| 25 Element* element = const_cast<Element*>(¤t); | 25 Element* element = const_cast<Element*>(¤t); |
| 26 for (; element; element = element->parentElement()) { | 26 for (; element; element = element->parentElement()) { |
| 27 if (element->assignedSlot()) | 27 if (element->assignedSlot()) |
| 28 break; | 28 break; |
| 29 } | 29 } |
| 30 return element; | 30 return element; |
| 31 } | 31 } |
| 32 | 32 |
| 33 Element* SlotScopedTraversal::next(const Element& current) { | 33 Element* SlotScopedTraversal::next(const Element& current) { |
| 34 // current.assignedSlot returns a slot only when current is assigned | 34 Element* next = nullptr; |
| 35 // explicitly | |
| 36 // If current is assigned to a slot, return a descendant of current, which is | |
| 37 // in the assigned scope of the same slot as current. | |
| 38 HTMLSlotElement* slot = current.assignedSlot(); | |
| 39 Element* nearestAncestorAssignedToSlot = | 35 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
| |
| 40 SlotScopedTraversal::nearestAncestorAssignedToSlot(current); | 36 SlotScopedTraversal::nearestAncestorAssignedToSlot(current); |
| 41 if (slot) { | 37 // 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.
| |
| 42 if (Element* next = ElementTraversal::next(current, ¤t)) | 38 if (current.assignedSlot()) { |
| 43 return next; | 39 next = ElementTraversal::next(current, ¤t); |
| 44 } else { | 40 } else { |
| 45 // If current is in assigned scope, find an assigned ancestor. | 41 // If current is in assigned scope, find an assigned ancestor. |
| 46 DCHECK(nearestAncestorAssignedToSlot); | 42 DCHECK(nearestAncestorAssignedToSlot); |
| 47 if (Element* next = | 43 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
| |
| 48 ElementTraversal::next(current, nearestAncestorAssignedToSlot)) | 44 return nullptr; |
| 49 return next; | 45 next = ElementTraversal::next(current, nearestAncestorAssignedToSlot); |
| 50 slot = nearestAncestorAssignedToSlot->assignedSlot(); | |
| 51 DCHECK(slot); | |
| 52 } | 46 } |
| 47 | |
| 48 // Exclude elements that is assigned to another slot scope. | |
| 49 while (next && next->assignedSlot()) | |
| 50 next = ElementTraversal::nextSkippingChildren(*next, ¤t); | |
| 51 | |
| 52 if (next) { | |
| 53 DCHECK(!next->assignedSlot()); | |
| 54 return next; | |
| 55 } | |
| 56 | |
| 57 // Seek to the next element assigned to the same slot. | |
| 58 HTMLSlotElement* slot = nearestAncestorAssignedToSlot->assignedSlot(); | |
| 59 DCHECK(slot); | |
| 53 HeapVector<Member<Node>> assignedNodes = slot->assignedNodes(); | 60 HeapVector<Member<Node>> assignedNodes = slot->assignedNodes(); |
| 54 size_t currentIndex = assignedNodes.find(*nearestAncestorAssignedToSlot); | 61 size_t currentIndex = assignedNodes.find(*nearestAncestorAssignedToSlot); |
| 55 DCHECK_NE(currentIndex, kNotFound); | 62 DCHECK_NE(currentIndex, kNotFound); |
| 56 for (++currentIndex; currentIndex < assignedNodes.size(); ++currentIndex) { | 63 for (++currentIndex; currentIndex < assignedNodes.size(); ++currentIndex) { |
| 57 if (assignedNodes[currentIndex]->isElementNode()) | 64 if (assignedNodes[currentIndex]->isElementNode()) |
| 58 return toElement(assignedNodes[currentIndex]); | 65 return toElement(assignedNodes[currentIndex]); |
| 59 } | 66 } |
| 60 return nullptr; | 67 return nullptr; |
| 61 } | 68 } |
| 62 | 69 |
| 63 Element* SlotScopedTraversal::previous(const Element& current) { | 70 Element* SlotScopedTraversal::previous(const Element& current) { |
| 64 Element* nearestAncestorAssignedToSlot = | 71 Element* nearestAncestorAssignedToSlot = |
| 65 SlotScopedTraversal::nearestAncestorAssignedToSlot(current); | 72 SlotScopedTraversal::nearestAncestorAssignedToSlot(current); |
| 66 DCHECK(nearestAncestorAssignedToSlot); | 73 DCHECK(nearestAncestorAssignedToSlot); |
| 67 // NodeTraversal within nearestAncestorAssignedToSlot | 74 |
| 68 if (Element* previous = | 75 // Search within children of an element which is directly assigned to a slot. |
| 69 ElementTraversal::previous(current, nearestAncestorAssignedToSlot)) | 76 Element* previous = |
| 70 return previous; | 77 ElementTraversal::previous(current, nearestAncestorAssignedToSlot); |
| 71 // If null, jump to previous assigned node's descendant | 78 |
| 79 // TODO(kochi): repeatedly calling nearestAncestorAssignedToSlot() which | |
| 80 // is O(depth from directly slotted ancestor) and can be very slow. | |
| 81 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
| |
| 82 Element* ancestor = | |
| 83 SlotScopedTraversal::nearestAncestorAssignedToSlot(*previous); | |
| 84 DCHECK(ancestor); | |
| 85 if (ancestor == nearestAncestorAssignedToSlot) | |
| 86 return previous; | |
| 87 previous = ancestor->parentElement(); | |
| 88 } | |
| 89 | |
| 90 // Seek to the previous element assigned to the same slot. | |
| 72 const HeapVector<Member<Node>> assignedNodes = | 91 const HeapVector<Member<Node>> assignedNodes = |
| 73 nearestAncestorAssignedToSlot->assignedSlot()->assignedNodes(); | 92 nearestAncestorAssignedToSlot->assignedSlot()->assignedNodes(); |
| 74 size_t currentIndex = | 93 size_t currentIndex = |
| 75 assignedNodes.reverseFind(*nearestAncestorAssignedToSlot); | 94 assignedNodes.reverseFind(*nearestAncestorAssignedToSlot); |
| 76 DCHECK_NE(currentIndex, kNotFound); | 95 DCHECK_NE(currentIndex, kNotFound); |
| 77 for (; currentIndex > 0; --currentIndex) { | 96 for (; currentIndex > 0; --currentIndex) { |
| 78 const Member<Node> assignedPrevious = assignedNodes[currentIndex - 1]; | 97 const Member<Node> assignedPrevious = assignedNodes[currentIndex - 1]; |
| 79 if (assignedPrevious->isElementNode()) { | 98 if (!assignedPrevious->isElementNode()) |
| 80 if (Element* last = | 99 continue; |
| 81 ElementTraversal::lastWithin(*toElement(assignedPrevious))) | 100 |
| 101 Element* last = ElementTraversal::lastWithin(*toElement(assignedPrevious)); | |
| 102 if (!last) | |
| 103 return toElement(assignedPrevious); | |
| 104 | |
| 105 while (last) { | |
| 106 Element* ancestor = | |
| 107 SlotScopedTraversal::nearestAncestorAssignedToSlot(*last); | |
| 108 DCHECK(ancestor); | |
| 109 if (ancestor == assignedPrevious) | |
| 82 return last; | 110 return last; |
| 83 return toElement(assignedPrevious); | 111 last = ancestor->parentElement(); |
| 84 } | 112 } |
| 113 NOTREACHED(); | |
| 85 } | 114 } |
| 86 return nullptr; | 115 return nullptr; |
| 87 } | 116 } |
| 88 | 117 |
| 89 bool SlotScopedTraversal::isSlotScoped(const Element& current) { | 118 bool SlotScopedTraversal::isSlotScoped(const Element& current) { |
| 90 return SlotScopedTraversal::nearestAncestorAssignedToSlot(current); | 119 return SlotScopedTraversal::nearestAncestorAssignedToSlot(current); |
| 91 } | 120 } |
| 92 | 121 |
| 93 } // namespace blink | 122 } // namespace blink |
| OLD | NEW |