Index: Source/core/css/SiblingTraversalStrategies.h |
diff --git a/Source/core/css/SiblingTraversalStrategies.h b/Source/core/css/SiblingTraversalStrategies.h |
index 55b78d0f8cde87e715b8ec9d71aa67d4f8db0acc..93b6fbecbfb4a12c69d98db601b1320ac644c00a 100644 |
--- a/Source/core/css/SiblingTraversalStrategies.h |
+++ b/Source/core/css/SiblingTraversalStrategies.h |
@@ -78,14 +78,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; |
} |
@@ -104,8 +101,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; |
} |