Chromium Code Reviews| Index: third_party/WebKit/Source/core/dom/shadow/AssignedElementTraversal.cpp |
| diff --git a/third_party/WebKit/Source/core/dom/shadow/AssignedElementTraversal.cpp b/third_party/WebKit/Source/core/dom/shadow/AssignedElementTraversal.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..7ab0e12e15b879e33b0772b0489cb40197e41f77 |
| --- /dev/null |
| +++ b/third_party/WebKit/Source/core/dom/shadow/AssignedElementTraversal.cpp |
| @@ -0,0 +1,80 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "core/dom/shadow/AssignedElementTraversal.h" |
| + |
| +#include "core/dom/Element.h" |
| +#include "core/dom/ElementTraversal.h" |
| +#include "core/html/HTMLSlotElement.h" |
| + |
| +namespace blink { |
| + |
| +HTMLSlotElement* AssignedElementTraversal::slot(const Element& current) |
| +{ |
| + if (Element* assignedAncestor = AssignedElementTraversal::assignedAncestor(current)) { |
| + return assignedAncestor->assignedSlot(); |
| + } |
|
kochi
2016/03/02 13:26:56
nit: you can remove {}.
yuzuchan
2016/03/03 04:12:42
Done.
|
| + return nullptr; |
| +} |
| + |
| +Element* AssignedElementTraversal::assignedAncestor(const Element& current) |
| +{ |
| + // assignedAncestor returns an ancestor element of current which is directly assigned to a slot. |
| + Element* element = const_cast<Element*>(¤t); |
| + for (; element; element = element->parentElement()) { |
| + if (element->assignedSlot()) |
| + break; |
| + } |
| + return element; |
| +} |
| + |
| +Element* AssignedElementTraversal::next(const Element& current) |
| +{ |
| + // current.assignedSlot returns a slot only when current is assigned explicitly |
| + // if current is directly assigned to a slot, return a descendant of current, which is indirectly assigned to the same slot as current. |
| + HTMLSlotElement* slot = current.assignedSlot(); |
| + WillBeHeapVector<RefPtrWillBeMember<Node>> assignedNodes; |
| + if (slot) { |
| + if (Element* next = ElementTraversal::next(current, ¤t)) |
| + return next; |
| + // if not, jump to another tree of assigned elements. |
| + assignedNodes = slot->getAssignedNodes(); |
| + } else { |
| + // if current is indirectly assigned to a slot, find a directly-assigned ancestor. |
| + Element* assignedAncestor = AssignedElementTraversal::assignedAncestor(current); |
| + if (Element* next = ElementTraversal::next(current, assignedAncestor)) |
| + return next; |
| + assignedNodes = AssignedElementTraversal::slot(*assignedAncestor)->getAssignedNodes(); |
|
kochi
2016/03/02 13:26:56
nit: I feel like on this line it should be
slo
yuzuchan
2016/03/03 04:12:42
Done.
|
| + } |
| + size_t currentIndex = assignedNodes.find(current); |
| + if (currentIndex != kNotFound && currentIndex < assignedNodes.size() - 1) |
| + return toElement(assignedNodes[currentIndex + 1]); |
| + return nullptr; |
| +} |
| + |
| +Element* AssignedElementTraversal::previous(const Element& current) |
| +{ |
| + Element* assignedAncestor = AssignedElementTraversal::assignedAncestor(current); |
| + // NodeTraversal within assignedAncestor |
| + if (Element* previous = ElementTraversal::previous(current, assignedAncestor)) |
| + return previous; |
| + // if null, jump to previous assigned node's descendant |
| + const WillBeHeapVector<RefPtrWillBeMember<Node>> assignedNodes = AssignedElementTraversal::slot(*assignedAncestor)->getAssignedNodes(); |
| + size_t currentIndex = assignedNodes.reverseFind(current); |
| + if (currentIndex != kNotFound && currentIndex > 0) { |
| + Node* assignedPrevious = assignedNodes[currentIndex - 1]; |
| + if (Node* lastChild = assignedPrevious->lastChild()) |
| + return toElement(lastChild); |
| + // if the previous assigned node has no children, return the assigned node itself |
| + return toElement(assignedPrevious); |
| + } |
| + return nullptr; |
| +} |
| + |
| +bool AssignedElementTraversal::isInAssignedScope(const Element& current) |
| +{ |
| + return AssignedElementTraversal::assignedAncestor(current); |
|
kochi
2016/03/02 13:26:56
aha, you don't need !! in front of AssingedElement
yuzuchan
2016/03/03 04:12:42
Acknowledged.
|
| +} |
| + |
| +} // namespace blink |