Changeset 196281 in webkit
- Timestamp:
- Feb 8, 2016, 5:15:52 PM (10 years ago)
- Location:
- trunk/Source/WebCore
- Files:
- 
      - 1 added
- 5 edited
 
 - 
          
  ChangeLog (modified) (1 diff)
- 
          
  WebCore.xcodeproj/project.pbxproj (modified) (4 diffs)
- 
          
  dom/ComposedTreeIterator.cpp (modified) (4 diffs)
- 
          
  dom/ComposedTreeIterator.h (modified) (8 diffs)
- 
          
  dom/ElementAndTextDescendantIterator.h (added)
- 
          
  dom/ElementIteratorAssertions.h (modified) (2 diffs)
 
Legend:
- Unmodified
- Added
- Removed
- 
      trunk/Source/WebCore/ChangeLogr196270 r196281 1 2016-02-08 Antti Koivisto <antti@apple.com> 2 3 Implement ComposedTreeIterator in terms of ElementAndTextDescendantIterator 4 https://bugs.webkit.org/show_bug.cgi?id=154003 5 6 Reviewed by Darin Adler. 7 8 Currently ComposedTreeIterator implements tree traversal using NodeTraversal. This makes it overly complicated. 9 It can also return nodes other than Element and Text which should not be part of the composed tree. 10 11 This patch adds a new iterator type, ElementAndTextDescendantIterator, similar to the existing ElementDescendantIterator. 12 ComposedTreeIterator is then implemented using this new iterator. 13 14 When entering a shadow tree or a slot the local iterator is pushed along with the context stack and a new local 15 iterator is initialized for the new context. When leaving a shadow tree the context stack is popped and the previous 16 local iterator becomes active. 17 18 * WebCore.xcodeproj/project.pbxproj: 19 * dom/ComposedTreeIterator.cpp: 20 (WebCore::ComposedTreeIterator::ComposedTreeIterator): 21 (WebCore::ComposedTreeIterator::initializeContextStack): 22 (WebCore::ComposedTreeIterator::pushContext): 23 (WebCore::ComposedTreeIterator::traverseNextInShadowTree): 24 (WebCore::ComposedTreeIterator::traverseNextLeavingContext): 25 (WebCore::ComposedTreeIterator::advanceInSlot): 26 (WebCore::ComposedTreeIterator::traverseSiblingInSlot): 27 (WebCore::ComposedTreeIterator::initializeShadowStack): Deleted. 28 (WebCore::ComposedTreeIterator::traverseParentInShadowTree): Deleted. 29 (WebCore::ComposedTreeIterator::traverseNextSiblingSlot): Deleted. 30 (WebCore::ComposedTreeIterator::traversePreviousSiblingSlot): Deleted. 31 * dom/ComposedTreeIterator.h: 32 (WebCore::ComposedTreeIterator::operator*): 33 (WebCore::ComposedTreeIterator::operator->): 34 (WebCore::ComposedTreeIterator::operator==): 35 (WebCore::ComposedTreeIterator::operator!=): 36 (WebCore::ComposedTreeIterator::operator++): 37 (WebCore::ComposedTreeIterator::Context::Context): 38 (WebCore::ComposedTreeIterator::context): 39 (WebCore::ComposedTreeIterator::current): 40 (WebCore::ComposedTreeIterator::ComposedTreeIterator): 41 (WebCore::ComposedTreeIterator::traverseNext): 42 (WebCore::ComposedTreeIterator::traverseNextSkippingChildren): 43 (WebCore::ComposedTreeIterator::traverseNextSibling): 44 (WebCore::ComposedTreeIterator::traversePreviousSibling): 45 (WebCore::ComposedTreeDescendantAdapter::ComposedTreeDescendantAdapter): 46 (WebCore::ComposedTreeDescendantAdapter::begin): 47 (WebCore::ComposedTreeDescendantAdapter::end): 48 (WebCore::ComposedTreeDescendantAdapter::at): 49 (WebCore::ComposedTreeChildAdapter::Iterator::Iterator): 50 (WebCore::ComposedTreeChildAdapter::ComposedTreeChildAdapter): 51 (WebCore::ComposedTreeChildAdapter::begin): 52 (WebCore::ComposedTreeChildAdapter::end): 53 (WebCore::ComposedTreeChildAdapter::at): 54 (WebCore::ComposedTreeIterator::ShadowContext::ShadowContext): Deleted. 55 (WebCore::ComposedTreeIterator::traverseParent): Deleted. 56 * dom/ElementAndTextDescendantIterator.h: Added. 57 58 New iterator type that traverses Element and Text nodes (that is renderable nodes only). 59 It also tracks depth for future use. 60 1 61 2016-02-08 Joseph Pecoraro <pecoraro@apple.com> 2 62 
- 
      trunk/Source/WebCore/WebCore.xcodeproj/project.pbxprojr196246 r196281 6531 6531 E43AF8E61AC5B7E800CA717E /* CacheValidation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43AF8E41AC5B7DD00CA717E /* CacheValidation.cpp */; }; 6532 6532 E43AF8E71AC5B7EC00CA717E /* CacheValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = E43AF8E51AC5B7DD00CA717E /* CacheValidation.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6533 E440AA961C68420800A265CC /* ElementAndTextDescendantIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = E440AA951C68420800A265CC /* ElementAndTextDescendantIterator.h */; }; 6533 6534 E44613A10CD6331000FADA75 /* HTMLAudioElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E446138F0CD6331000FADA75 /* HTMLAudioElement.cpp */; }; 6534 6535 E44613A20CD6331000FADA75 /* HTMLAudioElement.h in Headers */ = {isa = PBXBuildFile; fileRef = E44613900CD6331000FADA75 /* HTMLAudioElement.h */; }; … … 14509 14510 E43AF8E41AC5B7DD00CA717E /* CacheValidation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CacheValidation.cpp; sourceTree = "<group>"; }; 14510 14511 E43AF8E51AC5B7DD00CA717E /* CacheValidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CacheValidation.h; sourceTree = "<group>"; }; 14512 E440AA951C68420800A265CC /* ElementAndTextDescendantIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementAndTextDescendantIterator.h; sourceTree = "<group>"; }; 14511 14513 E446138F0CD6331000FADA75 /* HTMLAudioElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLAudioElement.cpp; sourceTree = "<group>"; }; 14512 14514 E44613900CD6331000FADA75 /* HTMLAudioElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLAudioElement.h; sourceTree = "<group>"; }; … … 24092 24094 93EEC1EA09C2877700C515D1 /* Element.idl */, 24093 24095 E4AE7C1917D232350009FB31 /* ElementAncestorIterator.h */, 24096 E440AA951C68420800A265CC /* ElementAndTextDescendantIterator.h */, 24094 24097 E46A2B1D17CA76B1000DBCD8 /* ElementChildIterator.h */, 24095 24098 B5B7A16F17C1080600E4AA0A /* ElementData.cpp */, … … 25851 25854 C4CD629B18383766007EBAF1 /* FrameSnapshotting.h in Headers */, 25852 25855 65A21485097A3F5300B9050A /* FrameTree.h in Headers */, 25856 E440AA961C68420800A265CC /* ElementAndTextDescendantIterator.h in Headers */, 25853 25857 65CBFEFA0974F607001DAC25 /* FrameView.h in Headers */, 25854 25858 97205AB0123928CA00B17380 /* FTPDirectoryDocument.h in Headers */, 
- 
      trunk/Source/WebCore/dom/ComposedTreeIterator.cppr191127 r196281 1 1 /* 2 * Copyright (C) 2015 Apple Inc. All rights reserved.2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 31 31 namespace WebCore { 32 32 33 void ComposedTreeIterator::initializeShadowStack() 33 ComposedTreeIterator::ComposedTreeIterator(ContainerNode& root) 34 { 35 ASSERT(!is<ShadowRoot>(root)); 36 37 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 38 if (is<HTMLSlotElement>(root)) { 39 auto& slot = downcast<HTMLSlotElement>(root); 40 if (auto* assignedNodes = slot.assignedNodes()) { 41 initializeContextStack(root, *assignedNodes->at(0)); 42 return; 43 } 44 } 45 #endif 46 auto& effectiveRoot = root.shadowRoot() ? *root.shadowRoot() : root; 47 m_contextStack.uncheckedAppend(Context(effectiveRoot)); 48 } 49 50 ComposedTreeIterator::ComposedTreeIterator(ContainerNode& root, Node& current) 51 { 52 ASSERT(!is<ShadowRoot>(root)); 53 ASSERT(!is<ShadowRoot>(current)); 54 55 bool mayNeedShadowStack = root.shadowRoot() || (¤t != &root && current.parentNode() != &root); 56 if (mayNeedShadowStack) 57 initializeContextStack(root, current); 58 else 59 m_contextStack.uncheckedAppend(Context(root, current)); 60 } 61 62 void ComposedTreeIterator::initializeContextStack(ContainerNode& root, Node& current) 34 63 { 35 64 // This code sets up the iterator for arbitrary node/root pair. It is not needed in common cases 36 65 // or completes fast because node and root are close (like in composedTreeChildren(*parent).at(node) case). 37 auto* node = m_current; 38 while (node != &m_root) { 66 auto* node = ¤t; 67 auto* contextCurrent = node; 68 size_t currentSlotNodeIndex = notFound; 69 while (node != &root) { 39 70 auto* parent = node->parentNode(); 40 71 if (!parent) { 41 m_current = nullptr;72 *this = { }; 42 73 return; 43 74 } 44 75 if (is<ShadowRoot>(*parent)) { 45 76 auto& shadowRoot = downcast<ShadowRoot>(*parent); 46 if (m_shadowStack.isEmpty() || m_shadowStack.last().host != shadowRoot.host()) 47 m_shadowStack.append(shadowRoot.host()); 77 m_contextStack.append(Context(shadowRoot, *contextCurrent, currentSlotNodeIndex)); 48 78 node = shadowRoot.host(); 79 contextCurrent = node; 80 currentSlotNodeIndex = notFound; 49 81 continue; 50 82 } 51 83 if (auto* shadowRoot = parent->shadowRoot()) { 52 84 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 53 m_ shadowStack.append(shadowRoot->host());85 m_contextStack.append(Context(*parent, *contextCurrent, currentSlotNodeIndex)); 54 86 auto* assignedSlot = shadowRoot->findAssignedSlot(*node); 55 87 if (assignedSlot) { 56 size_t index = assignedSlot->assignedNodes()->find(node); 57 ASSERT(index != notFound); 58 59 m_shadowStack.last().currentSlot = assignedSlot; 60 m_shadowStack.last().currentSlotNodeIndex = index; 88 currentSlotNodeIndex = assignedSlot->assignedNodes()->find(node); 89 ASSERT(currentSlotNodeIndex != notFound); 61 90 node = assignedSlot; 91 contextCurrent = assignedSlot; 62 92 continue; 63 93 } … … 65 95 #else 66 96 UNUSED_PARAM(shadowRoot); 67 m_current = nullptr; 97 #endif 98 *this = { }; 68 99 return; 69 #endif70 100 } 71 101 node = parent; 72 102 } 73 m_shadowStack.reverse(); 103 m_contextStack.append(Context(root, *contextCurrent, currentSlotNodeIndex)); 104 105 m_contextStack.reverse(); 106 } 107 108 bool ComposedTreeIterator::pushContext(ShadowRoot& shadowRoot) 109 { 110 Context shadowContext(shadowRoot); 111 if (!shadowContext.iterator) 112 return false; 113 m_contextStack.append(WTFMove(shadowContext)); 114 return true; 74 115 } 75 116 76 117 void ComposedTreeIterator::traverseNextInShadowTree() 77 118 { 78 ASSERT(!m_shadowStack.isEmpty()); 79 80 auto* shadowContext = &m_shadowStack.last(); 119 ASSERT(m_contextStack.size() > 1); 81 120 82 121 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 83 if (is<HTMLSlotElement>( *m_current) && !shadowContext->currentSlot) {84 auto& slot = downcast<HTMLSlotElement>( *m_current);122 if (is<HTMLSlotElement>(current())) { 123 auto& slot = downcast<HTMLSlotElement>(current()); 85 124 if (auto* assignedNodes = slot.assignedNodes()) { 86 shadowContext->currentSlot = &slot;87 shadowContext->currentSlotNodeIndex = 0;88 m_c urrent = assignedNodes->at(0);125 context().slotNodeIndex = 0; 126 auto* assignedNode = assignedNodes->at(0); 127 m_contextStack.append(Context(*assignedNode->parentElement(), *assignedNode)); 89 128 return; 90 129 } … … 92 131 #endif 93 132 94 m_current = NodeTraversal::next(*m_current, shadowContext->host);133 context().iterator.traverseNext(); 95 134 96 while (!m_current) { 135 if (!context().iterator) 136 traverseNextLeavingContext(); 137 } 138 139 void ComposedTreeIterator::traverseNextLeavingContext() 140 { 141 ASSERT(m_contextStack.size() > 1); 142 143 while (!context().iterator && m_contextStack.size() > 1) { 144 m_contextStack.removeLast(); 145 if (!context().iterator) 146 return; 97 147 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 98 if (auto* slot = shadowContext->currentSlot) { 99 bool nextNodeInSameSlot = ++shadowContext->currentSlotNodeIndex < slot->assignedNodes()->size(); 100 if (nextNodeInSameSlot) { 101 m_current = slot->assignedNodes()->at(shadowContext->currentSlotNodeIndex); 102 return; 103 } 104 m_current = NodeTraversal::nextSkippingChildren(*slot, shadowContext->host); 105 shadowContext->currentSlot = nullptr; 106 continue; 107 } 148 if (is<HTMLSlotElement>(current()) && advanceInSlot(1)) 149 return; 108 150 #endif 109 auto& previousHost = *shadowContext->host; 110 m_shadowStack.removeLast(); 111 112 if (m_shadowStack.isEmpty()) { 113 m_current = NodeTraversal::nextSkippingChildren(previousHost, &m_root); 114 return; 115 } 116 shadowContext = &m_shadowStack.last(); 117 m_current = NodeTraversal::nextSkippingChildren(previousHost, shadowContext->host); 151 context().iterator.traverseNextSkippingChildren(); 118 152 } 119 153 } 120 154 121 void ComposedTreeIterator::traverseParentInShadowTree() 155 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 156 bool ComposedTreeIterator::advanceInSlot(int direction) 122 157 { 123 ASSERT( !m_shadowStack.isEmpty());158 ASSERT(context().slotNodeIndex != notFound); 124 159 125 auto& shadowContext = m_shadowStack.last(); 160 auto& assignedNodes = *downcast<HTMLSlotElement>(current()).assignedNodes(); 161 // It is fine to underflow this. 162 context().slotNodeIndex += direction; 163 if (context().slotNodeIndex >= assignedNodes.size()) 164 return false; 126 165 127 auto* parent = m_current->parentNode(); 128 if (is<ShadowRoot>(parent)) { 129 ASSERT(shadowContext.host == downcast<ShadowRoot>(*parent).host()); 130 131 m_current = shadowContext.host; 132 m_shadowStack.removeLast(); 133 return; 134 } 135 if (parent->shadowRoot()) { 136 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 137 ASSERT(shadowContext.host == parent); 138 139 auto* slot = shadowContext.currentSlot; 140 ASSERT(slot->assignedNodes()->at(shadowContext.currentSlotNodeIndex) == m_current); 141 142 m_current = slot; 143 shadowContext.currentSlot = nullptr; 144 return; 145 #else 146 m_current = nullptr; 147 return; 148 #endif 149 } 150 m_current = parent; 166 auto* slotNode = assignedNodes.at(context().slotNodeIndex); 167 m_contextStack.append(Context(*slotNode->parentElement(), *slotNode)); 168 return true; 151 169 } 152 170 153 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 154 void ComposedTreeIterator::traverseNextSiblingSlot() 171 void ComposedTreeIterator::traverseSiblingInSlot(int direction) 155 172 { 156 ASSERT(m_current->parentNode()->shadowRoot()); 157 ASSERT(!m_shadowStack.isEmpty()); 158 ASSERT(m_shadowStack.last().host == m_current->parentNode()); 173 ASSERT(m_contextStack.size() > 1); 174 ASSERT(current().parentNode()->shadowRoot()); 159 175 160 auto& shadowContext = m_shadowStack.last();176 m_contextStack.removeLast(); 161 177 162 if (!shadowContext.currentSlot) { 163 m_current = nullptr; 164 return; 165 } 166 auto* slotNodes = shadowContext.currentSlot->assignedNodes(); 167 ASSERT(slotNodes->at(shadowContext.currentSlotNodeIndex) == m_current); 168 169 bool nextNodeInSameSlot = ++shadowContext.currentSlotNodeIndex < slotNodes->size(); 170 m_current = nextNodeInSameSlot ? slotNodes->at(shadowContext.currentSlotNodeIndex) : nullptr; 171 } 172 173 void ComposedTreeIterator::traversePreviousSiblingSlot() 174 { 175 ASSERT(m_current->parentNode()->shadowRoot()); 176 ASSERT(!m_shadowStack.isEmpty()); 177 ASSERT(m_shadowStack.last().host == m_current->parentNode()); 178 179 auto& shadowContext = m_shadowStack.last(); 180 181 if (!shadowContext.currentSlot) { 182 m_current = nullptr; 183 return; 184 } 185 auto* slotNodes = shadowContext.currentSlot->assignedNodes(); 186 ASSERT(slotNodes->at(shadowContext.currentSlotNodeIndex) == m_current); 187 188 bool previousNodeInSameSlot = shadowContext.currentSlotNodeIndex > 0; 189 m_current = previousNodeInSameSlot ? slotNodes->at(--shadowContext.currentSlotNodeIndex) : nullptr; 178 if (!advanceInSlot(direction)) 179 *this = { }; 190 180 } 191 181 #endif 
- 
      trunk/Source/WebCore/dom/ComposedTreeIterator.hr191112 r196281 1 1 /* 2 * Copyright (C) 2015 Apple Inc. All rights reserved.2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #include " NodeTraversal.h"26 #include "ElementAndTextDescendantIterator.h" 27 27 #include "ShadowRoot.h" 28 28 … … 36 36 class ComposedTreeIterator { 37 37 public: 38 ComposedTreeIterator(); 38 39 ComposedTreeIterator(ContainerNode& root); 39 40 ComposedTreeIterator(ContainerNode& root, Node& current); 40 41 41 Node& operator*() { return *m_current; }42 Node* operator->() { return m_current; }43 44 bool operator==(const ComposedTreeIterator& other) const { return m_current == other.m_current; }45 bool operator!=(const ComposedTreeIterator& other) const { return m_current != other.m_current; }46 47 ComposedTreeIterator& operator++() { return traverseNext Sibling(); }42 Node& operator*() { return current(); } 43 Node* operator->() { return ¤t(); } 44 45 bool operator==(const ComposedTreeIterator& other) const { return context().iterator == other.context().iterator; } 46 bool operator!=(const ComposedTreeIterator& other) const { return context().iterator != other.context().iterator; } 47 48 ComposedTreeIterator& operator++() { return traverseNext(); } 48 49 49 50 ComposedTreeIterator& traverseNext(); 51 ComposedTreeIterator& traverseNextSkippingChildren(); 50 52 ComposedTreeIterator& traverseNextSibling(); 51 53 ComposedTreeIterator& traversePreviousSibling(); 52 ComposedTreeIterator& traverseParent(); 54 55 unsigned depth() const; 53 56 54 57 private: 55 void initialize ShadowStack();58 void initializeContextStack(ContainerNode& root, Node& current); 56 59 void traverseNextInShadowTree(); 57 void traverseParentInShadowTree(); 58 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 59 void traverseNextSiblingSlot(); 60 void traversePreviousSiblingSlot(); 61 #endif 62 63 ContainerNode& m_root; 64 Node* m_current { 0 }; 65 66 struct ShadowContext { 67 ShadowContext(Element* host) 68 : host(host) 69 { } 70 71 Element* host; 72 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 73 HTMLSlotElement* currentSlot { nullptr }; 74 unsigned currentSlotNodeIndex { 0 }; 60 void traverseNextLeavingContext(); 61 bool pushContext(ShadowRoot&); 62 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 63 bool advanceInSlot(int direction); 64 void traverseSiblingInSlot(int direction); 65 #endif 66 67 struct Context { 68 Context() { } 69 explicit Context(ContainerNode& root) 70 : iterator(root) 71 { } 72 Context(ContainerNode& root, Node& node, size_t slotNodeIndex = notFound) 73 : iterator(root, &node) 74 , slotNodeIndex(slotNodeIndex) 75 { } 76 77 ElementAndTextDescendantIterator iterator; 78 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 79 size_t slotNodeIndex { notFound }; 75 80 #endif 76 81 }; 77 Vector<ShadowContext, 4> m_shadowStack; 82 Context& context() { return m_contextStack.last(); } 83 const Context& context() const { return m_contextStack.last(); } 84 Node& current() { return *context().iterator; } 85 86 Vector<Context, 4> m_contextStack; 78 87 }; 79 88 80 inline ComposedTreeIterator::ComposedTreeIterator(ContainerNode& root) 81 : m_root(root) 82 { 83 ASSERT(!is<ShadowRoot>(m_root)); 84 } 85 86 inline ComposedTreeIterator::ComposedTreeIterator(ContainerNode& root, Node& current) 87 : m_root(root) 88 , m_current(¤t) 89 { 90 ASSERT(!is<ShadowRoot>(m_root)); 91 ASSERT(!is<ShadowRoot>(m_current)); 92 93 bool mayNeedShadowStack = m_root.shadowRoot() || (m_current != &m_root && current.parentNode() != &m_root); 94 if (mayNeedShadowStack) 95 initializeShadowStack(); 89 inline ComposedTreeIterator::ComposedTreeIterator() 90 : m_contextStack({ { } }) 91 { 96 92 } 97 93 98 94 inline ComposedTreeIterator& ComposedTreeIterator::traverseNext() 99 95 { 100 if (auto* shadowRoot = m_current->shadowRoot()) { 101 m_shadowStack.append(shadowRoot->host()); 102 m_current = shadowRoot; 103 } 104 105 if (m_shadowStack.isEmpty()) 106 m_current = NodeTraversal::next(*m_current, &m_root); 107 else 96 if (auto* shadowRoot = context().iterator->shadowRoot()) { 97 if (pushContext(*shadowRoot)) 98 return *this; 99 } 100 101 if (m_contextStack.size() > 1) { 108 102 traverseNextInShadowTree(); 109 103 return *this; 104 } 105 106 context().iterator.traverseNext(); 107 return *this; 108 } 109 110 inline ComposedTreeIterator& ComposedTreeIterator::traverseNextSkippingChildren() 111 { 112 context().iterator.traverseNextSkippingChildren(); 113 114 if (!context().iterator && m_contextStack.size() > 1) 115 traverseNextLeavingContext(); 116 110 117 return *this; 111 118 } … … 114 121 { 115 122 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 116 bool isAssignedToSlot = !m_shadowStack.isEmpty() && m_current->parentNode()->shadowRoot(); 117 if (isAssignedToSlot) { 118 traverseNextSiblingSlot(); 123 if (current().parentNode()->shadowRoot()) { 124 traverseSiblingInSlot(1); 119 125 return *this; 120 126 } 121 127 #endif 122 m_current = m_current->nextSibling();128 context().iterator.traverseNextSibling(); 123 129 return *this; 124 130 } … … 127 133 { 128 134 #if ENABLE(SHADOW_DOM) || ENABLE(DETAILS_ELEMENT) 129 bool isAssignedToSlot = !m_shadowStack.isEmpty() && m_current->parentNode()->shadowRoot(); 130 if (isAssignedToSlot) { 131 traversePreviousSiblingSlot(); 135 if (current().parentNode()->shadowRoot()) { 136 traverseSiblingInSlot(-1); 132 137 return *this; 133 138 } 134 139 #endif 135 m_current = m_current->previousSibling(); 136 return *this; 137 } 138 139 inline ComposedTreeIterator& ComposedTreeIterator::traverseParent() 140 { 141 if (m_shadowStack.isEmpty()) 142 m_current = m_current->parentNode(); 143 else 144 traverseParentInShadowTree(); 145 146 return *this; 140 context().iterator.traversePreviousSibling(); 141 return *this; 142 } 143 144 inline unsigned ComposedTreeIterator::depth() const 145 { 146 unsigned depth = 0; 147 for (auto& context : m_contextStack) 148 depth += context.iterator.depth(); 149 return depth; 147 150 } 148 151 … … 153 156 { } 154 157 155 ComposedTreeIterator begin() { return ComposedTreeIterator(m_parent , m_parent).traverseNext(); }156 ComposedTreeIterator end() { return ComposedTreeIterator(m_parent); }158 ComposedTreeIterator begin() { return ComposedTreeIterator(m_parent); } 159 ComposedTreeIterator end() { return { }; } 157 160 ComposedTreeIterator at(const Node& child) { return ComposedTreeIterator(m_parent, const_cast<Node&>(child)); } 158 161 … … 165 168 class Iterator : public ComposedTreeIterator { 166 169 public: 167 Iterator(ContainerNode& root) 170 Iterator() = default; 171 explicit Iterator(ContainerNode& root) 168 172 : ComposedTreeIterator(root) 169 173 { } … … 180 184 { } 181 185 182 Iterator begin() { return static_cast<Iterator&>(Iterator(m_parent, m_parent).traverseNext()); }183 Iterator end() { return Iterator(m_parent); }186 Iterator begin() { return Iterator(m_parent); } 187 Iterator end() { return { }; } 184 188 Iterator at(const Node& child) { return Iterator(m_parent, const_cast<Node&>(child)); } 185 189 
- 
      trunk/Source/WebCore/dom/ElementIteratorAssertions.hr188520 r196281 33 33 class ElementIteratorAssertions { 34 34 public: 35 ElementIteratorAssertions(const Element* first = nullptr);35 ElementIteratorAssertions(const Node* first = nullptr); 36 36 bool domTreeHasMutated() const; 37 37 void dropEventDispatchAssertion(); … … 46 46 // FIXME: No real point in doing these as inlines; they are for debugging and we usually turn off inlining in debug builds. 47 47 48 inline ElementIteratorAssertions::ElementIteratorAssertions(const Element* first)48 inline ElementIteratorAssertions::ElementIteratorAssertions(const Node* first) 49 49 : m_document(first ? &first->document() : nullptr) 50 50 , m_initialDOMTreeVersion(first ? m_document->domTreeVersion() : 0) 
  Note:
 See   TracChangeset
 for help on using the changeset viewer.
  
