Index: Source/WebCore/dom/Element.cpp |
=================================================================== |
--- Source/WebCore/dom/Element.cpp (revision 98492) |
+++ Source/WebCore/dom/Element.cpp (working copy) |
@@ -1092,6 +1092,7 @@ |
// Ref currentStyle in case it would otherwise be deleted when setRenderStyle() is called. |
RefPtr<RenderStyle> currentStyle(renderStyle()); |
bool hasParentStyle = parentNodeForRenderingAndStyle() ? static_cast<bool>(parentNodeForRenderingAndStyle()->renderStyle()) : false; |
+ bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules(); |
bool hasIndirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByForwardPositionalRules(); |
if ((change > NoChange || needsStyleRecalc())) { |
@@ -1133,8 +1134,8 @@ |
newStyle->setChildrenAffectedByFirstChildRules(); |
if (currentStyle->childrenAffectedByLastChildRules()) |
newStyle->setChildrenAffectedByLastChildRules(); |
- if (currentStyle->affectedByDirectAdjacentRules()) |
- newStyle->setAffectedByDirectAdjacentRules(); |
+ if (currentStyle->childrenAffectedByDirectAdjacentRules()) |
+ newStyle->setChildrenAffectedByDirectAdjacentRules(); |
} |
if (ch != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer() && renderer()->requiresForcedStyleRecalcPropagation())) { |
@@ -1164,7 +1165,7 @@ |
// FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar. |
// For now we will just worry about the common case, since it's a lot trickier to get the second case right |
// without doing way too much re-resolution. |
- bool previousSiblingHadDirectAdjacentRules = false; |
+ bool forceCheckOfNextElementSibling = false; |
bool forceCheckOfAnyElementSibling = false; |
for (Node *n = firstChild(); n; n = n->nextSibling()) { |
if (n->isTextNode()) { |
@@ -1176,14 +1177,13 @@ |
continue; |
Element* element = static_cast<Element*>(n); |
bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() == FullStyleChange; |
- bool childAffectedByDirectAdjacentRules = element->renderStyle() ? element->renderStyle()->affectedByDirectAdjacentRules() : previousSiblingHadDirectAdjacentRules; |
- if (childAffectedByDirectAdjacentRules || forceCheckOfAnyElementSibling) |
+ if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling)) |
element->setNeedsStyleRecalc(); |
if (change >= Inherit || element->childNeedsStyleRecalc() || element->needsStyleRecalc()) { |
parentPusher.push(); |
element->recalcStyle(change); |
} |
- previousSiblingHadDirectAdjacentRules = childAffectedByDirectAdjacentRules; |
+ forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules; |
forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules); |
} |
// FIXME: This does not care about sibling combinators. Will be necessary in XBL2 world. |
@@ -1370,6 +1370,17 @@ |
newLastChild->setNeedsStyleRecalc(); |
} |
+ // The + selector. We need to invalidate the first element following the insertion point. It is the only possible element |
+ // that could be affected by this DOM change. |
+ if (style->childrenAffectedByDirectAdjacentRules() && afterChange) { |
+ Node* firstElementAfterInsertion = 0; |
+ for (firstElementAfterInsertion = afterChange; |
+ firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode(); |
+ firstElementAfterInsertion = firstElementAfterInsertion->nextSibling()) {}; |
+ if (firstElementAfterInsertion && firstElementAfterInsertion->attached()) |
+ firstElementAfterInsertion->setNeedsStyleRecalc(); |
+ } |
+ |
// Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type. |
// Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type. |
// We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the |