OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "config.h" |
| 6 #include "core/dom/shadow/SlotAssignment.h" |
| 7 |
| 8 #include "core/HTMLNames.h" |
| 9 #include "core/dom/ElementTraversal.h" |
| 10 #include "core/dom/NodeTraversal.h" |
| 11 #include "core/dom/shadow/InsertionPoint.h" |
| 12 #include "core/dom/shadow/ShadowRoot.h" |
| 13 #include "core/html/HTMLSlotElement.h" |
| 14 |
| 15 namespace blink { |
| 16 |
| 17 HTMLSlotElement* SlotAssignment::assignedSlotFor(const Node& node) const |
| 18 { |
| 19 return m_assignment.get(const_cast<Node*>(&node)); |
| 20 } |
| 21 |
| 22 static void detachNotAssignedNode(Node& node) |
| 23 { |
| 24 if (node.layoutObject()) |
| 25 node.lazyReattachIfAttached(); |
| 26 } |
| 27 |
| 28 void SlotAssignment::resolveAssignment(const ShadowRoot& shadowRoot) |
| 29 { |
| 30 m_assignment.clear(); |
| 31 |
| 32 using Name2Slot = HashMap<AtomicString, HTMLSlotElement*>; |
| 33 Name2Slot name2slot; |
| 34 HTMLSlotElement* defaultSlot = nullptr; |
| 35 |
| 36 // TODO(hayato): Cache slots elements so that we do not have to travese the
shadow tree. See ShadowRoot::descendantInsertionPoints() |
| 37 for (HTMLSlotElement& slot : Traversal<HTMLSlotElement>::descendantsOf(shado
wRoot)) { |
| 38 slot.clearDistribution(); |
| 39 |
| 40 AtomicString name = slot.fastGetAttribute(HTMLNames::nameAttr); |
| 41 if (name.isNull() || name.isEmpty()) { |
| 42 if (!defaultSlot) |
| 43 defaultSlot = &slot; |
| 44 } else { |
| 45 name2slot.add(name, &slot); |
| 46 } |
| 47 } |
| 48 |
| 49 for (Node& child : NodeTraversal::childrenOf(*shadowRoot.host())) { |
| 50 if (child.isElementNode()) { |
| 51 if (isActiveInsertionPoint(child)) { |
| 52 // TODO(hayato): Support re-distribution across v0 and v1 shadow
trees |
| 53 detachNotAssignedNode(child); |
| 54 continue; |
| 55 } |
| 56 AtomicString slotName = toElement(child).fastGetAttribute(HTMLNames:
:slotAttr); |
| 57 if (slotName.isNull() || slotName.isEmpty()) { |
| 58 if (defaultSlot) |
| 59 assign(child, *defaultSlot); |
| 60 else |
| 61 detachNotAssignedNode(child); |
| 62 } else { |
| 63 HTMLSlotElement* slot = name2slot.get(slotName); |
| 64 if (slot) |
| 65 assign(child, *slot); |
| 66 else |
| 67 detachNotAssignedNode(child); |
| 68 } |
| 69 } else if (defaultSlot) { |
| 70 assign(child, *defaultSlot); |
| 71 } else { |
| 72 detachNotAssignedNode(child); |
| 73 } |
| 74 } |
| 75 } |
| 76 |
| 77 void SlotAssignment::assign(Node& hostChild, HTMLSlotElement& slot) |
| 78 { |
| 79 m_assignment.add(&hostChild, &slot); |
| 80 slot.appendAssignedNode(hostChild); |
| 81 if (isHTMLSlotElement(hostChild)) |
| 82 slot.appendDistributedNodes(toHTMLSlotElement(hostChild).getDistributedN
odes()); |
| 83 else |
| 84 slot.appendDistributedNode(hostChild); |
| 85 } |
| 86 |
| 87 DEFINE_TRACE(SlotAssignment) |
| 88 { |
| 89 #if ENABLE(OILPAN) |
| 90 visitor->trace(m_assignment); |
| 91 #endif |
| 92 } |
| 93 |
| 94 } // namespace blink |
OLD | NEW |