| 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 |