| Index: Source/core/css/SiblingTraversalStrategies.h
|
| diff --git a/Source/core/css/SiblingTraversalStrategies.h b/Source/core/css/SiblingTraversalStrategies.h
|
| index 660a6c5edd3201bb12fbc303dbca15da6c5113de..f4e185b2ef32dfb577c58338a8eac59959ec16a4 100644
|
| --- a/Source/core/css/SiblingTraversalStrategies.h
|
| +++ b/Source/core/css/SiblingTraversalStrategies.h
|
| @@ -79,14 +79,11 @@ inline bool DOMSiblingTraversalStrategy::isLastOfType(Element* element, const Qu
|
| inline int DOMSiblingTraversalStrategy::countElementsBefore(Element* element) const
|
| {
|
| int count = 0;
|
| - for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) {
|
| - unsigned index = sibling->childIndex();
|
| - if (index) {
|
| - count += index;
|
| - break;
|
| - }
|
| - count++;
|
| - }
|
| + // We can't use the same early return as is present in countElementsAfter due
|
| + // to the order we resolve style; if a new element is inserted into the middle,
|
| + // we'd end up using a stale cached childIndex.
|
| + for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling())
|
| + ++count;
|
|
|
| return count;
|
| }
|
| @@ -105,8 +102,16 @@ inline int DOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element* eleme
|
| inline int DOMSiblingTraversalStrategy::countElementsAfter(Element* element) const
|
| {
|
| int count = 0;
|
| - for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling())
|
| + // We can use an early return here because we resolve style from lastChild to
|
| + // firstChild, so we're guaranteed to not have stale cached childIndices.
|
| + for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) {
|
| + unsigned index = sibling->childIndex();
|
| + if (index) {
|
| + count += index;
|
| + break;
|
| + }
|
| ++count;
|
| + }
|
|
|
| return count;
|
| }
|
|
|