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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 #include "core/dom/MutationObserverInterestGroup.h" | 56 #include "core/dom/MutationObserverInterestGroup.h" |
57 #include "core/dom/MutationRecord.h" | 57 #include "core/dom/MutationRecord.h" |
58 #include "core/dom/NamedNodeMap.h" | 58 #include "core/dom/NamedNodeMap.h" |
59 #include "core/dom/NodeRenderStyle.h" | 59 #include "core/dom/NodeRenderStyle.h" |
60 #include "core/dom/NodeRenderingContext.h" | 60 #include "core/dom/NodeRenderingContext.h" |
61 #include "core/dom/PostAttachCallbacks.h" | 61 #include "core/dom/PostAttachCallbacks.h" |
62 #include "core/dom/PseudoElement.h" | 62 #include "core/dom/PseudoElement.h" |
63 #include "core/dom/ScriptableDocumentParser.h" | 63 #include "core/dom/ScriptableDocumentParser.h" |
64 #include "core/dom/SelectorQuery.h" | 64 #include "core/dom/SelectorQuery.h" |
65 #include "core/dom/Text.h" | 65 #include "core/dom/Text.h" |
| 66 #include "core/dom/WhitespaceChildList.h" |
66 #include "core/dom/custom/CustomElement.h" | 67 #include "core/dom/custom/CustomElement.h" |
67 #include "core/dom/custom/CustomElementRegistrationContext.h" | 68 #include "core/dom/custom/CustomElementRegistrationContext.h" |
68 #include "core/dom/shadow/InsertionPoint.h" | 69 #include "core/dom/shadow/InsertionPoint.h" |
69 #include "core/dom/shadow/ShadowRoot.h" | 70 #include "core/dom/shadow/ShadowRoot.h" |
70 #include "core/editing/FrameSelection.h" | 71 #include "core/editing/FrameSelection.h" |
71 #include "core/editing/TextIterator.h" | 72 #include "core/editing/TextIterator.h" |
72 #include "core/editing/htmlediting.h" | 73 #include "core/editing/htmlediting.h" |
73 #include "core/events/EventDispatcher.h" | 74 #include "core/events/EventDispatcher.h" |
74 #include "core/events/FocusEvent.h" | 75 #include "core/events/FocusEvent.h" |
75 #include "core/html/ClassList.h" | 76 #include "core/html/ClassList.h" |
(...skipping 1477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1553 if (shouldRecalcStyle(change, this)) | 1554 if (shouldRecalcStyle(change, this)) |
1554 updatePseudoElement(BEFORE, change); | 1555 updatePseudoElement(BEFORE, change); |
1555 | 1556 |
1556 // FIXME: This check is good enough for :hover + foo, but it is not good eno
ugh for :hover + foo + bar. | 1557 // FIXME: This check is good enough for :hover + foo, but it is not good eno
ugh for :hover + foo + bar. |
1557 // For now we will just worry about the common case, since it's a lot tricki
er to get the second case right | 1558 // For now we will just worry about the common case, since it's a lot tricki
er to get the second case right |
1558 // without doing way too much re-resolution. | 1559 // without doing way too much re-resolution. |
1559 bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules(); | 1560 bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules(); |
1560 bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules(); | 1561 bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules(); |
1561 bool forceCheckOfNextElementSibling = false; | 1562 bool forceCheckOfNextElementSibling = false; |
1562 bool forceCheckOfAnyElementSibling = false; | 1563 bool forceCheckOfAnyElementSibling = false; |
1563 bool forceReattachOfAnyWhitespaceSibling = false; | 1564 if (hasDirectAdjacentRules || hasIndirectAdjacentRules) { |
1564 for (Node* child = firstChild(); child; child = child->nextSibling()) { | 1565 for (Node* child = firstChild(); child; child = child->nextSibling()) { |
1565 bool didReattach = false; | 1566 if (!child->isElementNode()) |
1566 | 1567 continue; |
1567 if (child->renderer()) | 1568 Element* element = toElement(child); |
1568 forceReattachOfAnyWhitespaceSibling = false; | 1569 bool childRulesChanged = element->needsStyleRecalc() && element->sty
leChangeType() >= SubtreeStyleChange; |
1569 | 1570 if (forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling) |
| 1571 element->setNeedsStyleRecalc(); |
| 1572 forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjac
entRules; |
| 1573 forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (ch
ildRulesChanged && hasIndirectAdjacentRules); |
| 1574 } |
| 1575 } |
| 1576 // This loop is deliberately backwards because we use insertBefore in the re
ndering tree, and want to avoid |
| 1577 // a potentially n^2 loop to find the insertion point while resolving style.
Having us start from the last |
| 1578 // child and work our way back means in the common case, we'll find the inse
rtion point in O(1) time. |
| 1579 // Reversing this loop can lead to non-deterministic results in our code to
optimize out empty whitespace |
| 1580 // RenderTexts. We try to put off recalcing their style until the end to avo
id this issue. |
| 1581 // See crbug.com/288225 |
| 1582 WhitespaceChildList whitespaceChildList(change); |
| 1583 for (Node* child = lastChild(); child; child = child->previousSibling()) { |
1570 if (child->isTextNode()) { | 1584 if (child->isTextNode()) { |
1571 if (forceReattachOfAnyWhitespaceSibling && toText(child)->containsOn
lyWhitespace()) | 1585 Text* textChild = toText(child); |
1572 child->reattach(); | 1586 // FIXME: This check is expensive and may negate the performance gai
ned by the optimization of |
| 1587 // avoiding whitespace renderers. |
| 1588 if (textChild->containsOnlyWhitespace()) |
| 1589 whitespaceChildList.append(textChild); |
1573 else | 1590 else |
1574 didReattach = toText(child)->recalcTextStyle(change); | 1591 textChild->recalcTextStyle(change); |
1575 } else if (child->isElementNode()) { | 1592 } else if (child->isElementNode()) { |
1576 Element* element = toElement(child); | 1593 Element* element = toElement(child); |
1577 | |
1578 bool childRulesChanged = element->needsStyleRecalc() && element->sty
leChangeType() >= SubtreeStyleChange; | |
1579 | |
1580 if (forceCheckOfNextElementSibling || forceCheckOfAnyElementSibling) | |
1581 element->setNeedsStyleRecalc(); | |
1582 | |
1583 forceCheckOfNextElementSibling = childRulesChanged && hasDirectAdjac
entRules; | |
1584 forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (ch
ildRulesChanged && hasIndirectAdjacentRules); | |
1585 | |
1586 if (shouldRecalcStyle(change, element)) { | 1594 if (shouldRecalcStyle(change, element)) { |
1587 parentPusher.push(); | 1595 parentPusher.push(); |
1588 didReattach = element->recalcStyle(change); | 1596 element->recalcStyle(change); |
1589 } else if (document().styleResolver()->supportsStyleSharing(element)
) { | 1597 } else if (document().styleResolver()->supportsStyleSharing(element)
) { |
1590 document().styleResolver()->addToStyleSharingList(element); | 1598 document().styleResolver()->addToStyleSharingList(element); |
1591 } | 1599 } |
1592 } | 1600 } |
| 1601 } |
1593 | 1602 |
1594 forceReattachOfAnyWhitespaceSibling = didReattach || forceReattachOfAnyW
hitespaceSibling; | 1603 whitespaceChildList.recalcStyle(); |
1595 } | |
1596 | 1604 |
1597 if (shouldRecalcStyle(change, this)) { | 1605 if (shouldRecalcStyle(change, this)) { |
1598 updatePseudoElement(AFTER, change); | 1606 updatePseudoElement(AFTER, change); |
1599 updatePseudoElement(BACKDROP, change); | 1607 updatePseudoElement(BACKDROP, change); |
1600 } | 1608 } |
1601 } | 1609 } |
1602 | 1610 |
1603 ElementShadow* Element::shadow() const | 1611 ElementShadow* Element::shadow() const |
1604 { | 1612 { |
1605 return hasRareData() ? elementRareData()->shadow() : 0; | 1613 return hasRareData() ? elementRareData()->shadow() : 0; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1756 | 1764 |
1757 // We also have to handle node removal. The parser callback case is sim
ilar to node removal as well in that we need to change the last child | 1765 // We also have to handle node removal. The parser callback case is sim
ilar to node removal as well in that we need to change the last child |
1758 // to match now. | 1766 // to match now. |
1759 if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild ==
lastElementBeforeInsertion && newLastChild && (!newLastChildStyle || !newLastChi
ldStyle->lastChildState())) | 1767 if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild ==
lastElementBeforeInsertion && newLastChild && (!newLastChildStyle || !newLastChi
ldStyle->lastChildState())) |
1760 newLastChild->setNeedsStyleRecalc(); | 1768 newLastChild->setNeedsStyleRecalc(); |
1761 } | 1769 } |
1762 | 1770 |
1763 // The + selector. We need to invalidate the first element following the in
sertion point. It is the only possible element | 1771 // The + selector. We need to invalidate the first element following the in
sertion point. It is the only possible element |
1764 // that could be affected by this DOM change. | 1772 // that could be affected by this DOM change. |
1765 if (e->childrenAffectedByDirectAdjacentRules() && afterChange) { | 1773 if (e->childrenAffectedByDirectAdjacentRules() && afterChange) { |
1766 if (Node* firstElementAfterInsertion = afterChange->nextElementSibling()
) | 1774 if (Node* firstElementAfterInsertion = afterChange->isElementNode() ? af
terChange : afterChange->nextElementSibling()) |
1767 firstElementAfterInsertion->setNeedsStyleRecalc(); | 1775 firstElementAfterInsertion->setNeedsStyleRecalc(); |
1768 } | 1776 } |
1769 } | 1777 } |
1770 | 1778 |
1771 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* af
terChange, int childCountDelta) | 1779 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* af
terChange, int childCountDelta) |
1772 { | 1780 { |
1773 ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, c
hildCountDelta); | 1781 ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, c
hildCountDelta); |
1774 if (changedByParser) | 1782 if (changedByParser) |
1775 checkForEmptyStyleChange(this, renderStyle()); | 1783 checkForEmptyStyleChange(this, renderStyle()); |
1776 else | 1784 else |
(...skipping 1897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3674 return 0; | 3682 return 0; |
3675 } | 3683 } |
3676 | 3684 |
3677 Attribute* UniqueElementData::attributeItem(unsigned index) | 3685 Attribute* UniqueElementData::attributeItem(unsigned index) |
3678 { | 3686 { |
3679 ASSERT_WITH_SECURITY_IMPLICATION(index < length()); | 3687 ASSERT_WITH_SECURITY_IMPLICATION(index < length()); |
3680 return &m_attributeVector.at(index); | 3688 return &m_attributeVector.at(index); |
3681 } | 3689 } |
3682 | 3690 |
3683 } // namespace WebCore | 3691 } // namespace WebCore |
OLD | NEW |