OLD | NEW |
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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 #include "wtf/text/CString.h" | 102 #include "wtf/text/CString.h" |
103 #include "wtf/text/TextPosition.h" | 103 #include "wtf/text/TextPosition.h" |
104 | 104 |
105 namespace WebCore { | 105 namespace WebCore { |
106 | 106 |
107 using namespace HTMLNames; | 107 using namespace HTMLNames; |
108 using namespace XMLNames; | 108 using namespace XMLNames; |
109 | 109 |
110 class StyleResolverParentPusher { | 110 class StyleResolverParentPusher { |
111 public: | 111 public: |
112 explicit StyleResolverParentPusher(Element& parent, StyleRecalcChange change
= NoChange) | 112 explicit StyleResolverParentPusher(Element& parent) |
113 : m_parent(parent) | 113 : m_parent(parent) |
114 , m_pushedStyleResolver(0) | 114 , m_pushedStyleResolver(0) |
115 { | 115 { |
116 if ((change >= Inherit || parent.childNeedsStyleRecalc()) && (parent.has
ChildNodes() || parent.youngestShadowRoot())) { | |
117 m_pushedStyleResolver = m_parent.document().styleResolver(); | |
118 m_pushedStyleResolver->pushParentElement(m_parent); | |
119 } | |
120 } | 116 } |
121 | 117 void push() |
| 118 { |
| 119 if (m_pushedStyleResolver) |
| 120 return; |
| 121 m_pushedStyleResolver = m_parent.document().styleResolver(); |
| 122 m_pushedStyleResolver->pushParentElement(m_parent); |
| 123 } |
122 ~StyleResolverParentPusher() | 124 ~StyleResolverParentPusher() |
123 { | 125 { |
| 126 |
124 if (!m_pushedStyleResolver) | 127 if (!m_pushedStyleResolver) |
125 return; | 128 return; |
| 129 |
| 130 // This tells us that our pushed style selector is in a bad state, |
| 131 // so we should just bail out in that scenario. |
| 132 ASSERT(m_pushedStyleResolver == m_parent.document().styleResolver()); |
| 133 if (m_pushedStyleResolver != m_parent.document().styleResolver()) |
| 134 return; |
| 135 |
126 m_pushedStyleResolver->popParentElement(m_parent); | 136 m_pushedStyleResolver->popParentElement(m_parent); |
127 } | 137 } |
128 | 138 |
129 private: | 139 private: |
130 Element& m_parent; | 140 Element& m_parent; |
131 StyleResolver* m_pushedStyleResolver; | 141 StyleResolver* m_pushedStyleResolver; |
132 }; | 142 }; |
133 | 143 |
134 typedef Vector<RefPtr<Attr> > AttrNodeList; | 144 typedef Vector<RefPtr<Attr> > AttrNodeList; |
135 typedef HashMap<Element*, OwnPtr<AttrNodeList> > AttrNodeListMap; | 145 typedef HashMap<Element*, OwnPtr<AttrNodeList> > AttrNodeListMap; |
(...skipping 1213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 document().removeFromTopLayer(this); | 1359 document().removeFromTopLayer(this); |
1350 | 1360 |
1351 if (hasRareData()) | 1361 if (hasRareData()) |
1352 elementRareData()->setIsInCanvasSubtree(false); | 1362 elementRareData()->setIsInCanvasSubtree(false); |
1353 } | 1363 } |
1354 | 1364 |
1355 void Element::attach(const AttachContext& context) | 1365 void Element::attach(const AttachContext& context) |
1356 { | 1366 { |
1357 ASSERT(document().inStyleRecalc()); | 1367 ASSERT(document().inStyleRecalc()); |
1358 | 1368 |
| 1369 StyleResolverParentPusher parentPusher(*this); |
| 1370 |
1359 // We've already been through detach when doing a lazyAttach, but we might | 1371 // We've already been through detach when doing a lazyAttach, but we might |
1360 // need to clear any state that's been added since then. | 1372 // need to clear any state that's been added since then. |
1361 if (hasRareData() && styleChangeType() == NeedsReattachStyleChange) { | 1373 if (hasRareData() && styleChangeType() == NeedsReattachStyleChange) { |
1362 ElementRareData* data = elementRareData(); | 1374 ElementRareData* data = elementRareData(); |
1363 data->clearComputedStyle(); | 1375 data->clearComputedStyle(); |
1364 data->resetDynamicRestyleObservations(); | 1376 data->resetDynamicRestyleObservations(); |
1365 if (!context.resolvedStyle) | 1377 if (!context.resolvedStyle) |
1366 data->resetStyleState(); | 1378 data->resetStyleState(); |
1367 } | 1379 } |
1368 | 1380 |
1369 NodeRenderingContext(this, context.resolvedStyle).createRendererForElementIf
Needed(); | 1381 NodeRenderingContext(this, context.resolvedStyle).createRendererForElementIf
Needed(); |
1370 | 1382 |
1371 addCallbackSelectors(); | 1383 addCallbackSelectors(); |
1372 | 1384 |
1373 StyleResolverParentPusher pushParent(*this); | |
1374 | |
1375 createPseudoElementIfNeeded(BEFORE); | 1385 createPseudoElementIfNeeded(BEFORE); |
1376 | 1386 |
1377 // When a shadow root exists, it does the work of attaching the children. | 1387 // When a shadow root exists, it does the work of attaching the children. |
1378 if (ElementShadow* shadow = this->shadow()) | 1388 if (ElementShadow* shadow = this->shadow()) { |
| 1389 parentPusher.push(); |
1379 shadow->attach(context); | 1390 shadow->attach(context); |
| 1391 } else if (firstChild()) { |
| 1392 parentPusher.push(); |
| 1393 } |
1380 | 1394 |
1381 ContainerNode::attach(context); | 1395 ContainerNode::attach(context); |
1382 | 1396 |
1383 createPseudoElementIfNeeded(AFTER); | 1397 createPseudoElementIfNeeded(AFTER); |
1384 createPseudoElementIfNeeded(BACKDROP); | 1398 createPseudoElementIfNeeded(BACKDROP); |
1385 | 1399 |
1386 if (hasRareData()) { | 1400 if (hasRareData()) { |
1387 ElementRareData* data = elementRareData(); | 1401 ElementRareData* data = elementRareData(); |
1388 if (data->needsFocusAppearanceUpdateSoonAfterAttach()) { | 1402 if (data->needsFocusAppearanceUpdateSoonAfterAttach()) { |
1389 if (isFocusable() && document().focusedElement() == this) | 1403 if (isFocusable() && document().focusedElement() == this) |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1560 | 1574 |
1561 return max(localChange, change); | 1575 return max(localChange, change); |
1562 } | 1576 } |
1563 | 1577 |
1564 void Element::recalcChildStyle(StyleRecalcChange change) | 1578 void Element::recalcChildStyle(StyleRecalcChange change) |
1565 { | 1579 { |
1566 ASSERT(document().inStyleRecalc()); | 1580 ASSERT(document().inStyleRecalc()); |
1567 ASSERT(change >= Inherit || childNeedsStyleRecalc()); | 1581 ASSERT(change >= Inherit || childNeedsStyleRecalc()); |
1568 ASSERT(!needsStyleRecalc()); | 1582 ASSERT(!needsStyleRecalc()); |
1569 | 1583 |
1570 StyleResolverParentPusher pushParent(*this, change); | 1584 StyleResolverParentPusher parentPusher(*this); |
1571 | 1585 |
1572 for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadow
Root()) { | 1586 for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadow
Root()) { |
1573 if (shouldRecalcStyle(change, root)) | 1587 if (shouldRecalcStyle(change, root)) { |
| 1588 parentPusher.push(); |
1574 root->recalcStyle(change); | 1589 root->recalcStyle(change); |
| 1590 } |
1575 } | 1591 } |
1576 | 1592 |
1577 if (shouldRecalcStyle(change, this)) | 1593 if (shouldRecalcStyle(change, this)) |
1578 updatePseudoElement(BEFORE, change); | 1594 updatePseudoElement(BEFORE, change); |
1579 | 1595 |
1580 if (change < Force && hasRareData() && childNeedsStyleRecalc()) | 1596 if (change < Force && hasRareData() && childNeedsStyleRecalc()) |
1581 checkForChildrenAdjacentRuleChanges(); | 1597 checkForChildrenAdjacentRuleChanges(); |
1582 | 1598 |
1583 // This loop is deliberately backwards because we use insertBefore in the re
ndering tree, and want to avoid | 1599 // This loop is deliberately backwards because we use insertBefore in the re
ndering tree, and want to avoid |
1584 // a potentially n^2 loop to find the insertion point while resolving style.
Having us start from the last | 1600 // a potentially n^2 loop to find the insertion point while resolving style.
Having us start from the last |
1585 // child and work our way back means in the common case, we'll find the inse
rtion point in O(1) time. | 1601 // child and work our way back means in the common case, we'll find the inse
rtion point in O(1) time. |
1586 // See crbug.com/288225 | 1602 // See crbug.com/288225 |
1587 StyleResolver& styleResolver = *document().styleResolver(); | 1603 StyleResolver& styleResolver = *document().styleResolver(); |
1588 for (Node* child = lastChild(); child; child = child->previousSibling()) { | 1604 for (Node* child = lastChild(); child; child = child->previousSibling()) { |
1589 if (child->isTextNode()) { | 1605 if (child->isTextNode()) { |
1590 toText(child)->recalcTextStyle(change); | 1606 toText(child)->recalcTextStyle(change); |
1591 } else if (child->isElementNode()) { | 1607 } else if (child->isElementNode()) { |
1592 Element* element = toElement(child); | 1608 Element* element = toElement(child); |
1593 if (shouldRecalcStyle(change, element)) | 1609 if (shouldRecalcStyle(change, element)) { |
| 1610 parentPusher.push(); |
1594 element->recalcStyle(change); | 1611 element->recalcStyle(change); |
1595 else if (element->supportsStyleSharing()) | 1612 } else if (element->supportsStyleSharing()) { |
1596 styleResolver.addToStyleSharingList(*element); | 1613 styleResolver.addToStyleSharingList(*element); |
| 1614 } |
1597 } | 1615 } |
1598 } | 1616 } |
1599 | 1617 |
1600 if (shouldRecalcStyle(change, this)) { | 1618 if (shouldRecalcStyle(change, this)) { |
1601 updatePseudoElement(AFTER, change); | 1619 updatePseudoElement(AFTER, change); |
1602 updatePseudoElement(BACKDROP, change); | 1620 updatePseudoElement(BACKDROP, change); |
1603 } | 1621 } |
1604 } | 1622 } |
1605 | 1623 |
1606 // FIXME: This method and checkForSiblingStyleChanges and checkForEmptyStyleChan
ge | 1624 // FIXME: This method and checkForSiblingStyleChanges and checkForEmptyStyleChan
ge |
(...skipping 1882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3489 // Before doing so, we need to resolve issues in HTMLSelectElement::recalcLi
stItems | 3507 // Before doing so, we need to resolve issues in HTMLSelectElement::recalcLi
stItems |
3490 // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cg
i?id=88405 | 3508 // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cg
i?id=88405 |
3491 if (hasTagName(optionTag) || hasTagName(optgroupTag)) | 3509 if (hasTagName(optionTag) || hasTagName(optgroupTag)) |
3492 return false; | 3510 return false; |
3493 if (FullscreenElementStack::isActiveFullScreenElement(this)) | 3511 if (FullscreenElementStack::isActiveFullScreenElement(this)) |
3494 return false; | 3512 return false; |
3495 return true; | 3513 return true; |
3496 } | 3514 } |
3497 | 3515 |
3498 } // namespace WebCore | 3516 } // namespace WebCore |
OLD | NEW |