Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: Source/core/dom/Element.cpp

Issue 102273004: Defer pushing the parent stack in recalcStyle until StyleResolver::styleForElement() (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: no-find-copies Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Peter Kelly (pmk@post.com) 4 * (C) 2001 Peter Kelly (pmk@post.com)
5 * (C) 2001 Dirk Mueller (mueller@kde.org) 5 * (C) 2001 Dirk Mueller (mueller@kde.org)
6 * (C) 2007 David Smith (catfish.man@gmail.com) 6 * (C) 2007 David Smith (catfish.man@gmail.com)
7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved. 7 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
8 * (C) 2007 Eric Seidel (eric@webkit.org) 8 * (C) 2007 Eric Seidel (eric@webkit.org)
9 * 9 *
10 * This library is free software; you can redistribute it and/or 10 * This library is free software; you can redistribute it and/or
(...skipping 22 matching lines...) Expand all
33 #include "bindings/v8/ExceptionState.h" 33 #include "bindings/v8/ExceptionState.h"
34 #include "core/accessibility/AXObjectCache.h" 34 #include "core/accessibility/AXObjectCache.h"
35 #include "core/animation/DocumentTimeline.h" 35 #include "core/animation/DocumentTimeline.h"
36 #include "core/animation/css/CSSAnimations.h" 36 #include "core/animation/css/CSSAnimations.h"
37 #include "core/css/CSSParser.h" 37 #include "core/css/CSSParser.h"
38 #include "core/css/CSSStyleSheet.h" 38 #include "core/css/CSSStyleSheet.h"
39 #include "core/css/CSSValuePool.h" 39 #include "core/css/CSSValuePool.h"
40 #include "core/css/PropertySetCSSStyleDeclaration.h" 40 #include "core/css/PropertySetCSSStyleDeclaration.h"
41 #include "core/css/StylePropertySet.h" 41 #include "core/css/StylePropertySet.h"
42 #include "core/css/resolver/StyleResolver.h" 42 #include "core/css/resolver/StyleResolver.h"
43 #include "core/css/resolver/StyleResolverParentScope.h"
43 #include "core/dom/Attr.h" 44 #include "core/dom/Attr.h"
44 #include "core/dom/CSSSelectorWatch.h" 45 #include "core/dom/CSSSelectorWatch.h"
45 #include "core/dom/ClientRect.h" 46 #include "core/dom/ClientRect.h"
46 #include "core/dom/ClientRectList.h" 47 #include "core/dom/ClientRectList.h"
47 #include "core/dom/DatasetDOMStringMap.h" 48 #include "core/dom/DatasetDOMStringMap.h"
48 #include "core/dom/DocumentSharedObjectPool.h" 49 #include "core/dom/DocumentSharedObjectPool.h"
49 #include "core/dom/ElementRareData.h" 50 #include "core/dom/ElementRareData.h"
50 #include "core/dom/ExceptionCode.h" 51 #include "core/dom/ExceptionCode.h"
51 #include "core/dom/FullscreenElementStack.h" 52 #include "core/dom/FullscreenElementStack.h"
52 #include "core/dom/MutationObserverInterestGroup.h" 53 #include "core/dom/MutationObserverInterestGroup.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 #include "wtf/BitVector.h" 98 #include "wtf/BitVector.h"
98 #include "wtf/HashFunctions.h" 99 #include "wtf/HashFunctions.h"
99 #include "wtf/text/CString.h" 100 #include "wtf/text/CString.h"
100 #include "wtf/text/TextPosition.h" 101 #include "wtf/text/TextPosition.h"
101 102
102 namespace WebCore { 103 namespace WebCore {
103 104
104 using namespace HTMLNames; 105 using namespace HTMLNames;
105 using namespace XMLNames; 106 using namespace XMLNames;
106 107
107 class StyleResolverParentPusher {
108 public:
109 explicit StyleResolverParentPusher(Element& parent)
110 : m_parent(parent)
111 , m_pushedStyleResolver(0)
112 {
113 }
114 void push()
115 {
116 if (m_pushedStyleResolver)
117 return;
118 m_pushedStyleResolver = &m_parent.document().ensureStyleResolver();
119 m_pushedStyleResolver->pushParentElement(m_parent);
120 }
121 ~StyleResolverParentPusher()
122 {
123
124 if (!m_pushedStyleResolver)
125 return;
126
127 // This tells us that our pushed style selector is in a bad state,
128 // so we should just bail out in that scenario.
129 ASSERT(m_pushedStyleResolver == m_parent.document().styleResolver());
130 if (m_pushedStyleResolver != m_parent.document().styleResolver())
131 return;
132
133 m_pushedStyleResolver->popParentElement(m_parent);
134 }
135
136 private:
137 Element& m_parent;
138 StyleResolver* m_pushedStyleResolver;
139 };
140
141 typedef Vector<RefPtr<Attr> > AttrNodeList; 108 typedef Vector<RefPtr<Attr> > AttrNodeList;
142 typedef HashMap<Element*, OwnPtr<AttrNodeList> > AttrNodeListMap; 109 typedef HashMap<Element*, OwnPtr<AttrNodeList> > AttrNodeListMap;
143 110
144 static AttrNodeListMap& attrNodeListMap() 111 static AttrNodeListMap& attrNodeListMap()
145 { 112 {
146 DEFINE_STATIC_LOCAL(AttrNodeListMap, map, ()); 113 DEFINE_STATIC_LOCAL(AttrNodeListMap, map, ());
147 return map; 114 return map;
148 } 115 }
149 116
150 static AttrNodeList* attrNodeListForElement(Element* element) 117 static AttrNodeList* attrNodeListForElement(Element* element)
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1358 document().removeFromTopLayer(this); 1325 document().removeFromTopLayer(this);
1359 1326
1360 if (hasRareData()) 1327 if (hasRareData())
1361 elementRareData()->setIsInCanvasSubtree(false); 1328 elementRareData()->setIsInCanvasSubtree(false);
1362 } 1329 }
1363 1330
1364 void Element::attach(const AttachContext& context) 1331 void Element::attach(const AttachContext& context)
1365 { 1332 {
1366 ASSERT(document().inStyleRecalc()); 1333 ASSERT(document().inStyleRecalc());
1367 1334
1368 StyleResolverParentPusher parentPusher(*this);
1369
1370 // We've already been through detach when doing an attach, but we might 1335 // We've already been through detach when doing an attach, but we might
1371 // need to clear any state that's been added since then. 1336 // need to clear any state that's been added since then.
1372 if (hasRareData() && styleChangeType() == NeedsReattachStyleChange) { 1337 if (hasRareData() && styleChangeType() == NeedsReattachStyleChange) {
1373 ElementRareData* data = elementRareData(); 1338 ElementRareData* data = elementRareData();
1374 data->clearComputedStyle(); 1339 data->clearComputedStyle();
1375 data->resetDynamicRestyleObservations(); 1340 data->resetDynamicRestyleObservations();
1376 // Only clear the style state if we're not going to reuse the style from recalcStyle. 1341 // Only clear the style state if we're not going to reuse the style from recalcStyle.
1377 if (!context.resolvedStyle) 1342 if (!context.resolvedStyle)
1378 data->resetStyleState(); 1343 data->resetStyleState();
1379 } 1344 }
1380 1345
1381 NodeRenderingContext(this, context.resolvedStyle).createRendererForElementIf Needed(); 1346 NodeRenderingContext(this, context.resolvedStyle).createRendererForElementIf Needed();
1382 1347
1383 addCallbackSelectors(); 1348 addCallbackSelectors();
1384 1349
1385 createPseudoElementIfNeeded(BEFORE); 1350 StyleResolverParentScope parentScope(*this);
1386 1351
1387 // When a shadow root exists, it does the work of attaching the children. 1352 // When a shadow root exists, it does the work of attaching the children.
1388 if (ElementShadow* shadow = this->shadow()) { 1353 if (ElementShadow* shadow = this->shadow())
1389 parentPusher.push();
1390 shadow->attach(context); 1354 shadow->attach(context);
1391 } else if (firstChild()) { 1355
1392 parentPusher.push(); 1356 createPseudoElementIfNeeded(BEFORE);
1393 }
1394 1357
1395 ContainerNode::attach(context); 1358 ContainerNode::attach(context);
1396 1359
1397 createPseudoElementIfNeeded(AFTER); 1360 createPseudoElementIfNeeded(AFTER);
1398 createPseudoElementIfNeeded(BACKDROP); 1361 createPseudoElementIfNeeded(BACKDROP);
1399 1362
1400 if (hasRareData()) { 1363 if (hasRareData()) {
1401 ElementRareData* data = elementRareData(); 1364 ElementRareData* data = elementRareData();
1402 if (data->needsFocusAppearanceUpdateSoonAfterAttach()) { 1365 if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
1403 if (isFocusable() && document().focusedElement() == this) 1366 if (isFocusable() && document().focusedElement() == this)
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1594 1557
1595 return max(localChange, change); 1558 return max(localChange, change);
1596 } 1559 }
1597 1560
1598 void Element::recalcChildStyle(StyleRecalcChange change) 1561 void Element::recalcChildStyle(StyleRecalcChange change)
1599 { 1562 {
1600 ASSERT(document().inStyleRecalc()); 1563 ASSERT(document().inStyleRecalc());
1601 ASSERT(change >= Inherit || childNeedsStyleRecalc()); 1564 ASSERT(change >= Inherit || childNeedsStyleRecalc());
1602 ASSERT(!needsStyleRecalc()); 1565 ASSERT(!needsStyleRecalc());
1603 1566
1604 StyleResolverParentPusher parentPusher(*this); 1567 StyleResolverParentScope parentScope(*this);
1605 1568
1606 for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadow Root()) { 1569 for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadow Root()) {
1607 if (shouldRecalcStyle(change, root)) { 1570 if (shouldRecalcStyle(change, root))
1608 parentPusher.push();
1609 root->recalcStyle(change); 1571 root->recalcStyle(change);
1610 }
1611 } 1572 }
1612 1573
1574 if (change < Force && hasRareData() && childNeedsStyleRecalc())
1575 checkForChildrenAdjacentRuleChanges();
1576
1613 if (shouldRecalcStyle(change, this)) 1577 if (shouldRecalcStyle(change, this))
1614 updatePseudoElement(BEFORE, change); 1578 updatePseudoElement(BEFORE, change);
1615 1579
1616 if (change < Force && hasRareData() && childNeedsStyleRecalc())
1617 checkForChildrenAdjacentRuleChanges();
1618
1619 // This loop is deliberately backwards because we use insertBefore in the re ndering tree, and want to avoid 1580 // This loop is deliberately backwards because we use insertBefore in the re ndering tree, and want to avoid
1620 // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last 1581 // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last
1621 // child and work our way back means in the common case, we'll find the inse rtion point in O(1) time. 1582 // child and work our way back means in the common case, we'll find the inse rtion point in O(1) time.
1622 // See crbug.com/288225 1583 // See crbug.com/288225
1623 StyleResolver& styleResolver = document().ensureStyleResolver(); 1584 StyleResolver& styleResolver = document().ensureStyleResolver();
1624 Text* lastTextNode = 0; 1585 Text* lastTextNode = 0;
1625 for (Node* child = lastChild(); child; child = child->previousSibling()) { 1586 for (Node* child = lastChild(); child; child = child->previousSibling()) {
1626 if (child->isTextNode()) { 1587 if (child->isTextNode()) {
1627 toText(child)->recalcTextStyle(change, lastTextNode); 1588 toText(child)->recalcTextStyle(change, lastTextNode);
1628 lastTextNode = toText(child); 1589 lastTextNode = toText(child);
1629 } else if (child->isElementNode()) { 1590 } else if (child->isElementNode()) {
1630 Element* element = toElement(child); 1591 Element* element = toElement(child);
1631 if (shouldRecalcStyle(change, element)) { 1592 if (shouldRecalcStyle(change, element))
1632 parentPusher.push();
1633 element->recalcStyle(change, lastTextNode); 1593 element->recalcStyle(change, lastTextNode);
1634 } else if (element->supportsStyleSharing()) { 1594 else if (element->supportsStyleSharing())
1635 styleResolver.addToStyleSharingList(*element); 1595 styleResolver.addToStyleSharingList(*element);
1636 }
1637 if (element->renderer()) 1596 if (element->renderer())
1638 lastTextNode = 0; 1597 lastTextNode = 0;
1639 } 1598 }
1640 } 1599 }
1641 1600
1642 if (shouldRecalcStyle(change, this)) { 1601 if (shouldRecalcStyle(change, this)) {
1643 updatePseudoElement(AFTER, change); 1602 updatePseudoElement(AFTER, change);
1644 updatePseudoElement(BACKDROP, change); 1603 updatePseudoElement(BACKDROP, change);
1645 } 1604 }
1646 } 1605 }
(...skipping 1889 matching lines...) Expand 10 before | Expand all | Expand 10 after
3536 // Before doing so, we need to resolve issues in HTMLSelectElement::recalcLi stItems 3495 // Before doing so, we need to resolve issues in HTMLSelectElement::recalcLi stItems
3537 // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cg i?id=88405 3496 // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cg i?id=88405
3538 if (hasTagName(optionTag) || hasTagName(optgroupTag)) 3497 if (hasTagName(optionTag) || hasTagName(optgroupTag))
3539 return false; 3498 return false;
3540 if (FullscreenElementStack::isActiveFullScreenElement(this)) 3499 if (FullscreenElementStack::isActiveFullScreenElement(this))
3541 return false; 3500 return false;
3542 return true; 3501 return true;
3543 } 3502 }
3544 3503
3545 } // namespace WebCore 3504 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698