Chromium Code Reviews| Index: Source/core/dom/Element.cpp |
| diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp |
| index 766e76d777765c6035e6b9660b88ba345db30037..ce9397ecb88e4566c0cc9db1d05c1a3afa008d80 100644 |
| --- a/Source/core/dom/Element.cpp |
| +++ b/Source/core/dom/Element.cpp |
| @@ -1347,22 +1347,22 @@ bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderS |
| return false; |
| } |
| -PassRefPtr<RenderStyle> Element::styleForRenderer() |
| +PassRefPtr<RenderStyle> Element::styleForRenderer(int childIndex) |
| { |
| if (hasCustomStyleCallbacks()) { |
| if (RefPtr<RenderStyle> style = customStyleForRenderer()) |
| return style.release(); |
| } |
| - return originalStyleForRenderer(); |
| + return originalStyleForRenderer(childIndex); |
| } |
| -PassRefPtr<RenderStyle> Element::originalStyleForRenderer() |
| +PassRefPtr<RenderStyle> Element::originalStyleForRenderer(int childIndex) |
| { |
| - return document()->styleResolver()->styleForElement(this); |
| + return document()->styleResolver()->styleForElement(this, childIndex); |
| } |
| -void Element::recalcStyle(StyleChange change) |
| +void Element::recalcStyle(StyleChange change, int childIndex) |
| { |
| ASSERT(document()->inStyleRecalc()); |
| @@ -1386,7 +1386,7 @@ void Element::recalcStyle(StyleChange change) |
| // FIXME: This still recalcs style twice when changing display types, but saves |
| // us from recalcing twice when going from none -> anything else which is more |
| // common, especially during lazy attach. |
| - newStyle = styleForRenderer(); |
| + newStyle = styleForRenderer(childIndex); |
| localChange = Node::diff(currentStyle.get(), newStyle.get(), document()); |
| } |
| if (localChange == Detach) { |
| @@ -1442,7 +1442,9 @@ void Element::recalcStyle(StyleChange change) |
| // without doing way too much re-resolution. |
| bool forceCheckOfNextElementSibling = false; |
| bool forceCheckOfAnyElementSibling = false; |
| + int indexForChild = 0; |
| for (Node *n = firstChild(); n; n = n->nextSibling()) { |
| + ++indexForChild; |
| if (n->isTextNode()) { |
| toText(n)->recalcTextStyle(change); |
| continue; |
| @@ -1453,12 +1455,20 @@ void Element::recalcStyle(StyleChange change) |
| bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() == FullStyleChange; |
| if ((forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling)) |
| element->setNeedsStyleRecalc(); |
| + forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules; |
| + forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules); |
| + } |
| + // FIXME: Reversing the loop we call recalcStyle avoids an N^2 walk through the DOM to find the next renderer |
| + // to insert before. The logic in NodeRenderingContext should be improved to make this unnecessary. |
| + for (Node *n = lastChild(); n; n = n->previousSibling()) { |
| + if (n->isTextNode() || !n->isElementNode()) |
|
esprehn
2013/06/05 00:12:26
You don't need to check for isTextNode, it's alrea
|
| + continue; |
| + Element* element = toElement(n); |
| if (shouldRecalcStyle(change, element)) { |
| parentPusher.push(); |
| - element->recalcStyle(change); |
| + element->recalcStyle(change, indexForChild); |
| } |
| - forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjacentRules; |
| - forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules); |
| + --indexForChild; |
| } |
| if (shouldRecalcStyle(change, this)) |