Changeset 148026 in webkit
- Timestamp:
- Apr 9, 2013 8:27:05 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r148022 r148026 1 2013-04-09 Andrei Bucur <abucur@adobe.com> 2 3 Use DOM ordering for list counts 4 https://bugs.webkit.org/show_bug.cgi?id=110352 5 6 Reviewed by Elliott Sprehn. 7 8 The fast/dom/shadow/shadow-and-list-elements-expected.html has changed because the list items 9 inside the shadow tree no longer see the root <ol> element. 10 The test fast/lists/positioned-count-crash.html has the correct rendering after changing 11 the list counting to be in DOM order. 12 13 * fast/dom/shadow/shadow-and-list-elements-expected.html: 14 * fast/lists/positioned-count-crash-expected.txt: 15 1 16 2013-04-09 Rafael Brandao <rafael.lobo@openbossa.org> 2 17 -
trunk/LayoutTests/fast/dom/shadow/shadow-and-list-elements-expected.html
r146883 r148026 23 23 // </ol> 24 24 var hostEquivalent = document.getElementById("hostEquivalent"); 25 var shadowListRoot = document.createElement("ol"); 26 shadowListRoot.style.paddingLeft = "0px"; 27 hostEquivalent.appendChild(shadowListRoot); 25 28 26 29 var childX = document.createElement("li"); 27 30 childX.innerHTML = "X"; 28 hostEquivalent.appendChild(childX); 31 childX.style.listStylePosition = "inside"; 32 shadowListRoot.appendChild(childX); 29 33 30 34 var childUl = document.createElement("ul"); 31 35 childUl.innerHTML = "B"; 32 hostEquivalent.appendChild(childUl);36 shadowListRoot.appendChild(childUl); 33 37 34 38 var childY = document.createElement("li"); 35 39 childY.innerHTML = "Y"; 36 hostEquivalent.appendChild(childY); 40 childY.style.listStylePosition = "inside"; 41 shadowListRoot.appendChild(childY); 37 42 </script> 38 43 </body> -
trunk/LayoutTests/fast/lists/positioned-count-crash-expected.txt
r146883 r148026 3 3 4 4 For manual test: If you see no crash and "II II", it means this test PASS. 5 FAIL list marker should be II. WasI.5 PASS list marker is II. 6 6 -
trunk/Source/WebCore/ChangeLog
r148020 r148026 1 2013-04-09 Andrei Bucur <abucur@adobe.com> 2 3 Use DOM ordering for list counts 4 https://bugs.webkit.org/show_bug.cgi?id=110352 5 6 Reviewed by Elliott Sprehn. 7 8 Currently the list items ordering is made by traversing the render tree. This gives bad results for: 9 - list items flown inside regions because they are not rendered as descendants of their DOM list ancestors. 10 - list items matched to insertion points inside a shadow tree. The insertion point may be a child of a 11 list so the numbering gets broken. 12 13 To implement correct DOM ordering I've taken into account the fact that pseudo-elements can have display: list-item 14 so they should be included when traversing the DOM tree. I've added helper methods on the NodeTraversal 15 namespace that should allow easily traversing the tree including the pseudo-elements (e.g. firstChildWithPseudo 16 for an element with pseudo-before will return the before PseudoElement). Using these helper methods I've implemented 17 pre-order traversal methods aware of the pseudo-elements. 18 An effect of this change is how the list items inside shadow tree update their counting. With the patch, if there's 19 no <ol> or <ul> element on the ancestor chain of a <li> element to the shadow root, the list node will be considered the 20 first parent of the <li> or the shadow root if there is no ancestor. 21 The RenderListItem class now makes use of this new method of traversal, replacing the one based on the render tree. 22 To simplify the CSS counters implementation, I've changed the traversal functions inside RenderCounter to also make use 23 of this method. The CSS counters and the list items now have the same traversal algorithm. 24 25 In later patches I'll add tests that should cover the regions and shadow DOM use cases. 26 Tests bug for shadow DOM: https://bugs.webkit.org/show_bug.cgi?id=113193 27 Tests bug for regions: https://bugs.webkit.org/show_bug.cgi?id=103975 28 29 Tests: no new tests is this patch; added the correct expectations for fast/lists/positioned-count-crash.html 30 and fast/dom/shadow/shadow-and-list-elements.html 31 32 * dom/Node.cpp: 33 (WebCore::Node::pseudoAwarePreviousSibling): 34 (WebCore): 35 (WebCore::Node::pseudoAwareNextSibling): 36 (WebCore::Node::pseudoAwareFirstChild): 37 (WebCore::Node::pseudoAwareLastChild): 38 * dom/Node.h: 39 (Node): 40 * dom/NodeTraversal.cpp: 41 (WebCore): 42 (WebCore::NodeTraversal::previousIncludingPseudo): 43 (NodeTraversal): 44 (WebCore::NodeTraversal::nextIncludingPseudo): 45 (WebCore::NodeTraversal::nextIncludingPseudoSkippingChildren): 46 * dom/NodeTraversal.h: 47 (ElementTraversal): 48 (NodeTraversal): 49 (WebCore::ElementTraversal::previousIncludingPseudo): 50 (WebCore::ElementTraversal::nextIncludingPseudo): 51 (WebCore::ElementTraversal::nextIncludingPseudoSkippingChildren): 52 (WebCore::ElementTraversal::pseudoAwarePreviousSibling): 53 * html/HTMLLIElement.cpp: 54 (WebCore::HTMLLIElement::attach): 55 * html/HTMLOListElement.cpp: 56 (WebCore::HTMLOListElement::updateItemValues): 57 (WebCore::HTMLOListElement::recalculateItemCount): 58 * rendering/RenderCounter.cpp: 59 (WebCore::previousInPreOrder): 60 (WebCore::previousSiblingOrParent): 61 (WebCore::parentElement): 62 (WebCore::nextInPreOrder): 63 * rendering/RenderListItem.cpp: 64 (WebCore): 65 (WebCore::enclosingList): 66 (WebCore::RenderListItem::nextListItem): 67 (WebCore::previousListItem): 68 (WebCore::RenderListItem::calcValue): 69 (WebCore::RenderListItem::explicitValueChanged): 70 (WebCore::previousOrNextItem): 71 (WebCore::RenderListItem::updateListMarkerNumbers): 72 * rendering/RenderListItem.h: 73 (RenderListItem): 74 1 75 2013-04-09 Bruno de Oliveira Abinader <bruno.abinader@basyskom.com> 2 76 -
trunk/Source/WebCore/dom/Node.cpp
r147962 r148026 1133 1133 } 1134 1134 1135 Node* Node::pseudoAwarePreviousSibling() const 1136 { 1137 if (parentElement() && !previousSibling()) { 1138 Element* parent = parentElement(); 1139 if (isAfterPseudoElement() && parent->lastChild()) 1140 return parent->lastChild(); 1141 if (!isBeforePseudoElement()) 1142 return parent->pseudoElement(BEFORE); 1143 } 1144 return previousSibling(); 1145 } 1146 1147 Node* Node::pseudoAwareNextSibling() const 1148 { 1149 if (parentElement() && !nextSibling()) { 1150 Element* parent = parentElement(); 1151 if (isBeforePseudoElement() && parent->firstChild()) 1152 return parent->firstChild(); 1153 if (!isAfterPseudoElement()) 1154 return parent->pseudoElement(AFTER); 1155 } 1156 return nextSibling(); 1157 } 1158 1159 Node* Node::pseudoAwareFirstChild() const 1160 { 1161 if (isElementNode()) { 1162 const Element* currentElement = toElement(this); 1163 Node* first = currentElement->pseudoElement(BEFORE); 1164 if (first) 1165 return first; 1166 first = currentElement->firstChild(); 1167 if (!first) 1168 first = currentElement->pseudoElement(AFTER); 1169 return first; 1170 } 1171 1172 return firstChild(); 1173 } 1174 1175 Node* Node::pseudoAwareLastChild() const 1176 { 1177 if (isElementNode()) { 1178 const Element* currentElement = toElement(this); 1179 Node* last = currentElement->pseudoElement(AFTER); 1180 if (last) 1181 return last; 1182 last = currentElement->lastChild(); 1183 if (!last) 1184 last = currentElement->pseudoElement(BEFORE); 1185 return last; 1186 } 1187 1188 return lastChild(); 1189 } 1190 1135 1191 // FIXME: This code is used by editing. Seems like it could move over there and not pollute Node. 1136 1192 Node *Node::previousNodeConsideringAtomicNodes() const -
trunk/Source/WebCore/dom/Node.h
r147795 r148026 194 194 bool hasAttributes() const; 195 195 NamedNodeMap* attributes() const; 196 Node* pseudoAwareNextSibling() const; 197 Node* pseudoAwarePreviousSibling() const; 198 Node* pseudoAwareFirstChild() const; 199 Node* pseudoAwareLastChild() const; 196 200 197 201 virtual KURL baseURI() const; -
trunk/Source/WebCore/dom/NodeTraversal.cpp
r146883 r148026 27 27 28 28 #include "ContainerNode.h" 29 #include "PseudoElement.h" 29 30 30 31 namespace WebCore { 32 31 33 namespace NodeTraversal { 34 35 Node* previousIncludingPseudo(const Node* current, const Node* stayWithin) 36 { 37 Node* previous; 38 if (current == stayWithin) 39 return 0; 40 if ((previous = current->pseudoAwarePreviousSibling())) { 41 while (previous->pseudoAwareLastChild()) 42 previous = previous->pseudoAwareLastChild(); 43 return previous; 44 } 45 return current->parentNode(); 46 } 47 48 Node* nextIncludingPseudo(const Node* current, const Node* stayWithin) 49 { 50 Node* next; 51 if ((next = current->pseudoAwareFirstChild())) 52 return next; 53 if (current == stayWithin) 54 return 0; 55 if ((next = current->pseudoAwareNextSibling())) 56 return next; 57 for (current = current->parentNode(); current; current = current->parentNode()) { 58 if (current == stayWithin) 59 return 0; 60 if ((next = current->pseudoAwareNextSibling())) 61 return next; 62 } 63 return 0; 64 } 65 66 Node* nextIncludingPseudoSkippingChildren(const Node* current, const Node* stayWithin) 67 { 68 Node* next; 69 if (current == stayWithin) 70 return 0; 71 if ((next = current->pseudoAwareNextSibling())) 72 return next; 73 for (current = current->parentNode(); current; current = current->parentNode()) { 74 if (current == stayWithin) 75 return 0; 76 if ((next = current->pseudoAwareNextSibling())) 77 return next; 78 } 79 return 0; 80 } 32 81 33 82 Node* nextAncestorSibling(const Node* current) -
trunk/Source/WebCore/dom/NodeTraversal.h
r146883 r148026 35 35 Element* firstWithin(const Node*); 36 36 Element* firstWithin(const ContainerNode*); 37 37 38 // Pre-order traversal skipping non-element nodes. 38 39 Element* next(const Node*); … … 40 41 Element* next(const ContainerNode*); 41 42 Element* next(const ContainerNode*, const Node* stayWithin); 43 42 44 // Like next, but skips children. 43 45 Element* nextSkippingChildren(const Node*); … … 45 47 Element* nextSkippingChildren(const ContainerNode*); 46 48 Element* nextSkippingChildren(const ContainerNode*, const Node* stayWithin); 49 50 // Pre-order traversal including the pseudo-elements. 51 Element* previousIncludingPseudo(const Node*, const Node* = 0); 52 Element* nextIncludingPseudo(const Node*, const Node* = 0); 53 Element* nextIncludingPseudoSkippingChildren(const Node*, const Node* = 0); 54 55 // Utility function to traverse only the element and pseudo-element siblings of a node. 56 Element* pseudoAwarePreviousSibling(const Node*); 47 57 48 58 } … … 78 88 Node* previousSkippingChildrenPostOrder(const Node*, const Node* stayWithin = 0); 79 89 90 // Pre-order traversal including the pseudo-elements. 91 Node* previousIncludingPseudo(const Node*, const Node* = 0); 92 Node* nextIncludingPseudo(const Node*, const Node* = 0); 93 Node* nextIncludingPseudoSkippingChildren(const Node*, const Node* = 0); 94 80 95 } 81 96 … … 136 151 inline Element* nextSkippingChildren(const ContainerNode* current, const Node* stayWithin) { return traverseNextElementSkippingChildrenTemplate(current, stayWithin); } 137 152 inline Element* nextSkippingChildren(const Node* current, const Node* stayWithin) { return traverseNextElementSkippingChildrenTemplate(current, stayWithin); } 153 154 inline Element* previousIncludingPseudo(const Node* current, const Node* stayWithin) 155 { 156 Node* node = NodeTraversal::previousIncludingPseudo(current, stayWithin); 157 while (node && !node->isElementNode()) 158 node = NodeTraversal::previousIncludingPseudo(node, stayWithin); 159 return toElement(node); 160 } 161 162 inline Element* nextIncludingPseudo(const Node* current, const Node* stayWithin) 163 { 164 Node* node = NodeTraversal::nextIncludingPseudo(current, stayWithin); 165 while (node && !node->isElementNode()) 166 node = NodeTraversal::nextIncludingPseudo(node, stayWithin); 167 return toElement(node); 168 } 169 170 inline Element* nextIncludingPseudoSkippingChildren(const Node* current, const Node* stayWithin) 171 { 172 Node* node = NodeTraversal::nextIncludingPseudoSkippingChildren(current, stayWithin); 173 while (node && !node->isElementNode()) 174 node = NodeTraversal::nextIncludingPseudoSkippingChildren(node, stayWithin); 175 return toElement(node); 176 } 177 178 inline Element* pseudoAwarePreviousSibling(const Node* current) 179 { 180 Node* node = current->pseudoAwarePreviousSibling(); 181 while (node && !node->isElementNode()) 182 node = node->pseudoAwarePreviousSibling(); 183 return toElement(node); 184 } 185 138 186 } 139 187 -
trunk/Source/WebCore/html/HTMLLIElement.cpp
r146883 r148026 93 93 94 94 if (renderer() && renderer()->isListItem()) { 95 RenderListItem* render = toRenderListItem(renderer());95 RenderListItem* listItemRenderer = toRenderListItem(renderer()); 96 96 97 97 // Find the enclosing list node. 98 Node* listNode = 0;99 E ventPathWalker walker(this);98 Element* listNode = 0; 99 Element* current = this; 100 100 while (!listNode) { 101 walker.moveToParent();102 if (! walker.node())101 current = current->parentElement(); 102 if (!current) 103 103 break; 104 if ( walker.node()->hasTagName(ulTag) || walker.node()->hasTagName(olTag))105 listNode = walker.node();104 if (current->hasTagName(ulTag) || current->hasTagName(olTag)) 105 listNode = current; 106 106 } 107 107 … … 109 109 // We don't want to change our style to say "inside" since that would affect nested nodes. 110 110 if (!listNode) 111 render->setNotInList(true);111 listItemRenderer->setNotInList(true); 112 112 113 113 parseValue(fastGetAttribute(valueAttr)); -
trunk/Source/WebCore/html/HTMLOListElement.cpp
r146883 r148026 107 107 void HTMLOListElement::updateItemValues() 108 108 { 109 for (RenderListItem* listItem = RenderListItem::nextListItem( renderer()); listItem; listItem = RenderListItem::nextListItem(renderer(), listItem))109 for (RenderListItem* listItem = RenderListItem::nextListItem(this); listItem; listItem = RenderListItem::nextListItem(this, listItem)) 110 110 listItem->updateValue(); 111 111 } … … 115 115 m_itemCount = 0; 116 116 117 for (RenderListItem* listItem = RenderListItem::nextListItem( renderer()); listItem; listItem = RenderListItem::nextListItem(renderer(), listItem))117 for (RenderListItem* listItem = RenderListItem::nextListItem(this); listItem; listItem = RenderListItem::nextListItem(this, listItem)) 118 118 m_itemCount++; 119 119 -
trunk/Source/WebCore/rendering/RenderCounter.cpp
r146883 r148026 58 58 static RenderObject* previousInPreOrder(const RenderObject* object) 59 59 { 60 Element* parent; 61 Element* sibling; 62 switch (object->style()->styleType()) { 63 case NOPSEUDO: 64 ASSERT(!object->isAnonymous()); 65 parent = toElement(object->node()); 66 sibling = parent->previousElementSibling(); 67 parent = parent->parentElement(); 68 break; 69 case BEFORE: 70 return object->generatingNode()->renderer(); // It is always the generating node's renderer 71 case AFTER: 72 parent = toElement(object->generatingNode()); 73 sibling = parent->lastElementChild(); 74 break; 75 default: 76 ASSERT_NOT_REACHED(); 77 return 0; 78 } 79 while (sibling) { 80 if (RenderObject* renderer = sibling->renderer()) { 81 if (RenderObject* after = sibling->pseudoElementRenderer(AFTER)) 82 return after; 83 parent = sibling; 84 sibling = sibling->lastElementChild(); 85 if (!sibling) { 86 if (RenderObject* before = toElement(renderer->node())->pseudoElementRenderer(BEFORE)) 87 return before; 88 return renderer; 89 } 90 } else 91 sibling = sibling->previousElementSibling(); 92 } 93 if (!parent) 94 return 0; 95 if (RenderObject* before = parent->pseudoElementRenderer(BEFORE)) 96 return before; 97 return parent->renderer(); 60 Element* self = toElement(object->node()); 61 Element* previous = ElementTraversal::previousIncludingPseudo(self); 62 while (previous && !previous->renderer()) 63 previous = ElementTraversal::previousIncludingPseudo(previous); 64 return previous ? previous->renderer() : 0; 98 65 } 99 66 … … 102 69 static RenderObject* previousSiblingOrParent(const RenderObject* object) 103 70 { 104 Element* parent; 105 Element* sibling; 106 switch (object->style()->styleType()) { 107 case NOPSEUDO: 108 ASSERT(!object->isAnonymous()); 109 parent = toElement(object->node()); 110 sibling = parent->previousElementSibling(); 111 parent = parent->parentElement(); 112 break; 113 case BEFORE: 114 return object->generatingNode()->renderer(); // It is always the generating node's renderer 115 case AFTER: 116 parent = toElement(object->generatingNode()); 117 sibling = parent->lastElementChild(); 118 break; 119 default: 120 ASSERT_NOT_REACHED(); 121 return 0; 122 } 123 while (sibling) { 124 if (RenderObject* renderer = sibling->renderer()) // This skips invisible nodes 125 return renderer; 126 sibling = sibling->previousElementSibling(); 127 } 128 if (!parent) 129 return 0; 130 if (RenderObject* before = parent->pseudoElementRenderer(BEFORE)) 131 return before; 132 return parent->renderer(); 133 } 134 135 static Element* parentElement(RenderObject* object) 136 { 137 switch (object->style()->styleType()) { 138 case NOPSEUDO: 139 ASSERT(!object->isAnonymous()); 140 return toElement(object->node())->parentElement(); 141 case BEFORE: 142 case AFTER: 143 return toElement(object->generatingNode()); 144 default: 145 ASSERT_NOT_REACHED(); 146 return 0; 147 } 71 Element* self = toElement(object->node()); 72 Element* previous = ElementTraversal::pseudoAwarePreviousSibling(self); 73 while (previous && !previous->renderer()) 74 previous = ElementTraversal::pseudoAwarePreviousSibling(previous); 75 if (previous) 76 return previous->renderer(); 77 previous = self->parentElement(); 78 return previous ? previous->renderer() : 0; 79 } 80 81 static inline Element* parentElement(RenderObject* object) 82 { 83 return toElement(object->node())->parentElement(); 148 84 } 149 85 … … 157 93 static RenderObject* nextInPreOrder(const RenderObject* object, const Element* stayWithin, bool skipDescendants = false) 158 94 { 159 Element* self; 160 Element* child; 161 self = toElement(object->generatingNode()); 162 if (skipDescendants) 163 goto nextsibling; 164 switch (object->style()->styleType()) { 165 case NOPSEUDO: 166 ASSERT(!object->isAnonymous()); 167 if (RenderObject* before = self->pseudoElementRenderer(BEFORE)) 168 return before; 169 break; 170 case BEFORE: 171 break; 172 case AFTER: 173 goto nextsibling; 174 default: 175 ASSERT_NOT_REACHED(); 176 return 0; 177 } 178 child = ElementTraversal::firstWithin(self); 179 while (true) { 180 while (child) { 181 if (RenderObject* renderer = child->renderer()) 182 return renderer; 183 child = ElementTraversal::nextSkippingChildren(child, self); 184 } 185 if (RenderObject* after = self->pseudoElementRenderer(AFTER)) 186 return after; 187 nextsibling: 188 if (self == stayWithin) 189 return 0; 190 child = ElementTraversal::nextSkippingChildren(self); 191 self = self->parentElement(); 192 if (!self) { 193 ASSERT(!child); // We can only reach this if we are searching beyond the root element 194 return 0; // which cannot have siblings 195 } 196 } 95 Element* self = toElement(object->node()); 96 Element* next = skipDescendants ? ElementTraversal::nextIncludingPseudoSkippingChildren(self, stayWithin) : ElementTraversal::nextIncludingPseudo(self, stayWithin); 97 while (next && !next->renderer()) 98 next = skipDescendants ? ElementTraversal::nextIncludingPseudoSkippingChildren(next, stayWithin) : ElementTraversal::nextIncludingPseudo(next, stayWithin); 99 return next ? next->renderer() : 0; 197 100 } 198 101 -
trunk/Source/WebCore/rendering/RenderListItem.cpp
r146883 r148026 28 28 #include "HTMLNames.h" 29 29 #include "HTMLOListElement.h" 30 #include "NodeTraversal.h" 30 31 #include "RenderListMarker.h" 31 32 #include "RenderView.h" … … 97 98 } 98 99 100 // Returns the enclosing list with respect to the DOM order. 99 101 static Node* enclosingList(const RenderListItem* listItem) 100 102 { 103 Node* listItemNode = listItem->node(); 101 104 Node* firstNode = 0; 102 103 for (const RenderObject* renderer = listItem->parent(); renderer; renderer = renderer->parent()) { 104 Node* node = renderer->node(); 105 if (node) { 106 if (isList(node)) 107 return node; 108 if (!firstNode) 109 firstNode = node; 110 } 105 // We use parentNode because the enclosing list could be a ShadowRoot that's not Element. 106 for (Node* parent = listItemNode->parentNode(); parent; parent = parent->parentNode()) { 107 if (isList(parent)) 108 return parent; 109 if (!firstNode) 110 firstNode = parent; 111 111 } 112 112 … … 117 117 } 118 118 119 RenderListItem* RenderListItem::nextListItem(RenderObject* list, const RenderListItem* item) 120 { 121 if (!list) 119 // Returns the next list item with respect to the DOM order. 120 RenderListItem* RenderListItem::nextListItem(Node* listNode, const RenderListItem* item) 121 { 122 if (!listNode) 122 123 return 0; 123 124 124 RenderObject* renderer = item ? item->nextInPreOrder(list) : list->nextInPreOrder(list); 125 while (renderer) { 126 if (renderer->node() && isList(renderer->node())) { 125 Node* current = item ? item->node() : listNode; 126 current = ElementTraversal::nextIncludingPseudo(current, listNode); 127 128 while (current) { 129 if (isList(current)) { 127 130 // We've found a nested, independent list: nothing to do here. 128 renderer = renderer->nextInPreOrderAfterChildren(list);131 current = ElementTraversal::nextIncludingPseudoSkippingChildren(current, listNode); 129 132 continue; 130 133 } 131 134 132 if (renderer->isListItem()) 135 RenderObject* renderer = current->renderer(); 136 if (renderer && renderer->isListItem()) 133 137 return toRenderListItem(renderer); 134 138 135 renderer = renderer->nextInPreOrder(list); 136 } 139 // FIXME: Can this be optimized to skip the children of the elements without a renderer? 140 current = ElementTraversal::nextIncludingPseudo(current, listNode); 141 } 142 137 143 return 0; 138 144 } 139 145 140 static RenderListItem* previousListItem(RenderObject* list, const RenderListItem* item) 141 { 142 for (RenderObject* renderer = item->previousInPreOrder(); renderer && renderer != list; renderer = renderer->previousInPreOrder()) { 143 if (!renderer->isListItem()) 146 // Returns the previous list item with respect to the DOM order. 147 static RenderListItem* previousListItem(Node* listNode, const RenderListItem* item) 148 { 149 Node* current = item->node(); 150 for (current = ElementTraversal::previousIncludingPseudo(current, listNode); current; current = ElementTraversal::previousIncludingPseudo(current, listNode)) { 151 RenderObject* renderer = current->renderer(); 152 if (!renderer || (renderer && !renderer->isListItem())) 144 153 continue; 145 154 Node* otherList = enclosingList(toRenderListItem(renderer)); 146 155 // This item is part of our current list, so it's what we're looking for. 147 if (list ->node()== otherList)156 if (listNode == otherList) 148 157 return toRenderListItem(renderer); 149 158 // We found ourself inside another list; lets skip the rest of it. 150 // Use nextIn PreOrder() here because the other list itself may actually159 // Use nextIncludingPseudo() here because the other list itself may actually 151 160 // be a list item itself. We need to examine it, so we do this to counteract 152 // the previousIn PreOrder() that will be done by the loop.161 // the previousIncludingPseudo() that will be done by the loop. 153 162 if (otherList) 154 renderer = otherList->renderer()->nextInPreOrder();163 current = ElementTraversal::nextIncludingPseudo(otherList); 155 164 } 156 165 return 0; … … 163 172 164 173 Node* list = enclosingList(this); 165 RenderObject* listRenderer = list ? list->renderer() : 0;166 174 HTMLOListElement* oListElement = (list && list->hasTagName(olTag)) ? static_cast<HTMLOListElement*>(list) : 0; 167 175 int valueStep = 1; … … 171 179 // FIXME: This recurses to a possible depth of the length of the list. 172 180 // That's not good -- we need to change this to an iterative algorithm. 173 if (RenderListItem* previousItem = previousListItem(list Renderer, this))181 if (RenderListItem* previousItem = previousListItem(list, this)) 174 182 return previousItem->value() + valueStep; 175 183 … … 428 436 m_marker->setNeedsLayoutAndPrefWidthsRecalc(); 429 437 Node* listNode = enclosingList(this); 430 RenderObject* listRenderer = 0; 431 if (listNode) 432 listRenderer = listNode->renderer(); 433 for (RenderListItem* item = this; item; item = nextListItem(listRenderer, item)) 438 for (RenderListItem* item = this; item; item = nextListItem(listNode, item)) 434 439 item->updateValue(); 435 440 } … … 458 463 } 459 464 460 static RenderListItem* previousOrNextItem(bool isListReversed, RenderObject* list, RenderListItem* item)465 static RenderListItem* previousOrNextItem(bool isListReversed, Node* list, RenderListItem* item) 461 466 { 462 467 return isListReversed ? previousListItem(list, item) : RenderListItem::nextListItem(list, item); … … 466 471 { 467 472 Node* listNode = enclosingList(this); 468 ASSERT(listNode && listNode->renderer()); 469 if (!listNode || !listNode->renderer()) 473 // The list node can be the shadow root which has no renderer. 474 ASSERT(listNode); 475 if (!listNode) 470 476 return; 471 477 472 478 bool isListReversed = false; 473 RenderObject* list = listNode->renderer();474 479 HTMLOListElement* oListElement = (listNode && listNode->hasTagName(olTag)) ? static_cast<HTMLOListElement*>(listNode) : 0; 475 480 if (oListElement) { … … 477 482 isListReversed = oListElement->isReversed(); 478 483 } 479 for (RenderListItem* item = previousOrNextItem(isListReversed, list , this); item; item = previousOrNextItem(isListReversed, list, item)) {484 for (RenderListItem* item = previousOrNextItem(isListReversed, listNode, this); item; item = previousOrNextItem(isListReversed, listNode, item)) { 480 485 if (!item->m_isValueUpToDate) { 481 486 // If an item has been marked for update before, we can safely -
trunk/Source/WebCore/rendering/RenderListItem.h
r146883 r148026 50 50 void updateListMarkerNumbers(); 51 51 52 static RenderListItem* nextListItem( RenderObject* listRenderer, const RenderListItem* = 0);52 static RenderListItem* nextListItem(Node*, const RenderListItem* = 0); 53 53 54 54 private:
Note: See TracChangeset
for help on using the changeset viewer.