| 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 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1562 static void checkForEmptyStyleChange(Element* element, RenderStyle* style) | 1562 static void checkForEmptyStyleChange(Element* element, RenderStyle* style) |
| 1563 { | 1563 { |
| 1564 if (!style && !element->styleAffectedByEmpty()) | 1564 if (!style && !element->styleAffectedByEmpty()) |
| 1565 return; | 1565 return; |
| 1566 | 1566 |
| 1567 if (!style || (element->styleAffectedByEmpty() && (!style->emptyState() || e
lement->hasChildNodes()))) | 1567 if (!style || (element->styleAffectedByEmpty() && (!style->emptyState() || e
lement->hasChildNodes()))) |
| 1568 element->setNeedsStyleRecalc(); | 1568 element->setNeedsStyleRecalc(); |
| 1569 } | 1569 } |
| 1570 | 1570 |
| 1571 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin
ishedParsingCallback, | 1571 static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin
ishedParsingCallback, |
| 1572 Node* beforeChange, Node* afterChange, i
nt childCountDelta) | 1572 const Handle<Node>& beforeChange, const Handle<Node>& afterChange, int child
CountDelta) |
| 1573 { | 1573 { |
| 1574 // :empty selector. | 1574 // :empty selector. |
| 1575 checkForEmptyStyleChange(e, style); | 1575 checkForEmptyStyleChange(e, style); |
| 1576 | 1576 |
| 1577 if (!style || (e->needsStyleRecalc() && e->childrenAffectedByPositionalRules
())) | 1577 if (!style || (e->needsStyleRecalc() && e->childrenAffectedByPositionalRules
())) |
| 1578 return; | 1578 return; |
| 1579 | 1579 |
| 1580 // :first-child. In the parser callback case, we don't have to check anythi
ng, since we were right the first time. | 1580 // :first-child. In the parser callback case, we don't have to check anythi
ng, since we were right the first time. |
| 1581 // In the DOM case, we only need to do something if |afterChange| is not 0. | 1581 // In the DOM case, we only need to do something if |afterChange| is not 0. |
| 1582 // |afterChange| is 0 in the parser case, so it works out that we'll skip th
is block. | 1582 // |afterChange| is 0 in the parser case, so it works out that we'll skip th
is block. |
| 1583 if (e->childrenAffectedByFirstChildRules() && afterChange) { | 1583 if (e->childrenAffectedByFirstChildRules() && afterChange) { |
| 1584 // Find our new first child. | 1584 // Find our new first child. |
| 1585 Node* newFirstChild = 0; | 1585 Node* newFirstChild = 0; |
| 1586 for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->i
sElementNode(); newFirstChild = newFirstChild->nextSibling()) {}; | 1586 for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->i
sElementNode(); newFirstChild = newFirstChild->nextSibling()) {}; |
| 1587 | 1587 |
| 1588 // Find the first element node following |afterChange| | 1588 // Find the first element node following |afterChange| |
| 1589 Node* firstElementAfterInsertion = 0; | 1589 Node* firstElementAfterInsertion = 0; |
| 1590 for (firstElementAfterInsertion = afterChange; | 1590 for (firstElementAfterInsertion = afterChange.raw(); |
| 1591 firstElementAfterInsertion && !firstElementAfterInsertion->isElemen
tNode(); | 1591 firstElementAfterInsertion && !firstElementAfterInsertion->isElemen
tNode(); |
| 1592 firstElementAfterInsertion = firstElementAfterInsertion->nextSiblin
g()) {}; | 1592 firstElementAfterInsertion = firstElementAfterInsertion->nextSiblin
g()) {}; |
| 1593 | 1593 |
| 1594 // This is the insert/append case. | 1594 // This is the insert/append case. |
| 1595 if (newFirstChild != firstElementAfterInsertion && firstElementAfterInse
rtion && firstElementAfterInsertion->attached() && | 1595 if (newFirstChild != firstElementAfterInsertion && firstElementAfterInse
rtion && firstElementAfterInsertion->attached() && |
| 1596 firstElementAfterInsertion->renderStyle() && firstElementAfterInsert
ion->renderStyle()->firstChildState()) | 1596 firstElementAfterInsertion->renderStyle() && firstElementAfterInsert
ion->renderStyle()->firstChildState()) |
| 1597 firstElementAfterInsertion->setNeedsStyleRecalc(); | 1597 firstElementAfterInsertion->setNeedsStyleRecalc(); |
| 1598 | 1598 |
| 1599 // We also have to handle node removal. | 1599 // We also have to handle node removal. |
| 1600 if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion &
& newFirstChild && (!newFirstChild->renderStyle() || !newFirstChild->renderStyle
()->firstChildState())) | 1600 if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion &
& newFirstChild && (!newFirstChild->renderStyle() || !newFirstChild->renderStyle
()->firstChildState())) |
| 1601 newFirstChild->setNeedsStyleRecalc(); | 1601 newFirstChild->setNeedsStyleRecalc(); |
| 1602 } | 1602 } |
| 1603 | 1603 |
| 1604 // :last-child. In the parser callback case, we don't have to check anythin
g, since we were right the first time. | 1604 // :last-child. In the parser callback case, we don't have to check anythin
g, since we were right the first time. |
| 1605 // In the DOM case, we only need to do something if |afterChange| is not 0. | 1605 // In the DOM case, we only need to do something if |afterChange| is not 0. |
| 1606 if (e->childrenAffectedByLastChildRules() && beforeChange) { | 1606 if (e->childrenAffectedByLastChildRules() && beforeChange) { |
| 1607 // Find our new last child. | 1607 // Find our new last child. |
| 1608 Node* newLastChild = 0; | 1608 Node* newLastChild = 0; |
| 1609 for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isEle
mentNode(); newLastChild = newLastChild->previousSibling()) {}; | 1609 for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isEle
mentNode(); newLastChild = newLastChild->previousSibling()) {}; |
| 1610 | 1610 |
| 1611 // Find the last element node going backwards from |beforeChange| | 1611 // Find the last element node going backwards from |beforeChange| |
| 1612 Node* lastElementBeforeInsertion = 0; | 1612 Node* lastElementBeforeInsertion = 0; |
| 1613 for (lastElementBeforeInsertion = beforeChange; | 1613 for (lastElementBeforeInsertion = beforeChange.raw(); |
| 1614 lastElementBeforeInsertion && !lastElementBeforeInsertion->isElemen
tNode(); | 1614 lastElementBeforeInsertion && !lastElementBeforeInsertion->isElemen
tNode(); |
| 1615 lastElementBeforeInsertion = lastElementBeforeInsertion->previousSi
bling()) {}; | 1615 lastElementBeforeInsertion = lastElementBeforeInsertion->previousSi
bling()) {}; |
| 1616 | 1616 |
| 1617 if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInser
tion && lastElementBeforeInsertion->attached() && | 1617 if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInser
tion && lastElementBeforeInsertion->attached() && |
| 1618 lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsert
ion->renderStyle()->lastChildState()) | 1618 lastElementBeforeInsertion->renderStyle() && lastElementBeforeInsert
ion->renderStyle()->lastChildState()) |
| 1619 lastElementBeforeInsertion->setNeedsStyleRecalc(); | 1619 lastElementBeforeInsertion->setNeedsStyleRecalc(); |
| 1620 | 1620 |
| 1621 // 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 | 1621 // 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 |
| 1622 // to match now. | 1622 // to match now. |
| 1623 if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild ==
lastElementBeforeInsertion && newLastChild && (!newLastChild->renderStyle() || !
newLastChild->renderStyle()->lastChildState())) | 1623 if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild ==
lastElementBeforeInsertion && newLastChild && (!newLastChild->renderStyle() || !
newLastChild->renderStyle()->lastChildState())) |
| 1624 newLastChild->setNeedsStyleRecalc(); | 1624 newLastChild->setNeedsStyleRecalc(); |
| 1625 } | 1625 } |
| 1626 | 1626 |
| 1627 // The + selector. We need to invalidate the first element following the in
sertion point. It is the only possible element | 1627 // The + selector. We need to invalidate the first element following the in
sertion point. It is the only possible element |
| 1628 // that could be affected by this DOM change. | 1628 // that could be affected by this DOM change. |
| 1629 if (e->childrenAffectedByDirectAdjacentRules() && afterChange) { | 1629 if (e->childrenAffectedByDirectAdjacentRules() && afterChange) { |
| 1630 Node* firstElementAfterInsertion = 0; | 1630 Node* firstElementAfterInsertion = 0; |
| 1631 for (firstElementAfterInsertion = afterChange; | 1631 for (firstElementAfterInsertion = afterChange.raw(); |
| 1632 firstElementAfterInsertion && !firstElementAfterInsertion->isElemen
tNode(); | 1632 firstElementAfterInsertion && !firstElementAfterInsertion->isElemen
tNode(); |
| 1633 firstElementAfterInsertion = firstElementAfterInsertion->nextSiblin
g()) {}; | 1633 firstElementAfterInsertion = firstElementAfterInsertion->nextSiblin
g()) {}; |
| 1634 if (firstElementAfterInsertion && firstElementAfterInsertion->attached()
) | 1634 if (firstElementAfterInsertion && firstElementAfterInsertion->attached()
) |
| 1635 firstElementAfterInsertion->setNeedsStyleRecalc(); | 1635 firstElementAfterInsertion->setNeedsStyleRecalc(); |
| 1636 } | 1636 } |
| 1637 | 1637 |
| 1638 // Forward positional selectors include the ~ selector, nth-child, nth-of-ty
pe, first-of-type and only-of-type. | 1638 // Forward positional selectors include the ~ selector, nth-child, nth-of-ty
pe, first-of-type and only-of-type. |
| 1639 // Backward positional selectors include nth-last-child, nth-last-of-type, l
ast-of-type and only-of-type. | 1639 // Backward positional selectors include nth-last-child, nth-last-of-type, l
ast-of-type and only-of-type. |
| 1640 // We have to invalidate everything following the insertion point in the for
ward case, and everything before the insertion point in the | 1640 // We have to invalidate everything following the insertion point in the for
ward case, and everything before the insertion point in the |
| 1641 // backward case. | 1641 // backward case. |
| 1642 // |afterChange| is 0 in the parser callback case, so we won't do any work f
or the forward case if we don't have to. | 1642 // |afterChange| is 0 in the parser callback case, so we won't do any work f
or the forward case if we don't have to. |
| 1643 // For performance reasons we just mark the parent node as changed, since we
don't want to make childrenChanged O(n^2) by crawling all our kids | 1643 // For performance reasons we just mark the parent node as changed, since we
don't want to make childrenChanged O(n^2) by crawling all our kids |
| 1644 // here. recalcStyle will then force a walk of the children when it sees th
at this has happened. | 1644 // here. recalcStyle will then force a walk of the children when it sees th
at this has happened. |
| 1645 if ((e->childrenAffectedByForwardPositionalRules() && afterChange) | 1645 if ((e->childrenAffectedByForwardPositionalRules() && afterChange) |
| 1646 || (e->childrenAffectedByBackwardPositionalRules() && beforeChange)) | 1646 || (e->childrenAffectedByBackwardPositionalRules() && beforeChange)) |
| 1647 e->setNeedsStyleRecalc(); | 1647 e->setNeedsStyleRecalc(); |
| 1648 } | 1648 } |
| 1649 | 1649 |
| 1650 void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* af
terChange, int childCountDelta) | 1650 void Element::childrenChanged(bool changedByParser, const Handle<Node>& beforeCh
ange, const Handle<Node>& afterChange, int childCountDelta) |
| 1651 { | 1651 { |
| 1652 ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, c
hildCountDelta); | 1652 ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, c
hildCountDelta); |
| 1653 if (changedByParser) | 1653 if (changedByParser) |
| 1654 checkForEmptyStyleChange(this, renderStyle()); | 1654 checkForEmptyStyleChange(this, renderStyle()); |
| 1655 else | 1655 else |
| 1656 checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, af
terChange, childCountDelta); | 1656 checkForSiblingStyleChanges(this, renderStyle(), false, beforeChange, af
terChange, childCountDelta); |
| 1657 | 1657 |
| 1658 if (ElementShadow * shadow = this->shadow()) | 1658 if (ElementShadow * shadow = this->shadow()) |
| 1659 shadow->invalidateDistribution(); | 1659 shadow->invalidateDistribution(); |
| 1660 } | 1660 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1671 clearIsParsingChildrenFinished(); | 1671 clearIsParsingChildrenFinished(); |
| 1672 StyleResolver* styleResolver = document()->styleResolverIfExists(); | 1672 StyleResolver* styleResolver = document()->styleResolverIfExists(); |
| 1673 if (styleResolver && attached()) | 1673 if (styleResolver && attached()) |
| 1674 styleResolver->pushParentElement(this); | 1674 styleResolver->pushParentElement(this); |
| 1675 } | 1675 } |
| 1676 | 1676 |
| 1677 void Element::finishParsingChildren() | 1677 void Element::finishParsingChildren() |
| 1678 { | 1678 { |
| 1679 ContainerNode::finishParsingChildren(); | 1679 ContainerNode::finishParsingChildren(); |
| 1680 setIsParsingChildrenFinished(); | 1680 setIsParsingChildrenFinished(); |
| 1681 checkForSiblingStyleChanges(this, renderStyle(), true, lastChild(), 0, 0); | 1681 checkForSiblingStyleChanges(this, renderStyle(), true, adoptRawResult(lastCh
ild()), nullptr, 0); |
| 1682 if (StyleResolver* styleResolver = document()->styleResolverIfExists()) | 1682 if (StyleResolver* styleResolver = document()->styleResolverIfExists()) |
| 1683 styleResolver->popParentElement(this); | 1683 styleResolver->popParentElement(this); |
| 1684 } | 1684 } |
| 1685 | 1685 |
| 1686 #ifndef NDEBUG | 1686 #ifndef NDEBUG |
| 1687 void Element::formatForDebugger(char* buffer, unsigned length) const | 1687 void Element::formatForDebugger(char* buffer, unsigned length) const |
| 1688 { | 1688 { |
| 1689 StringBuilder result; | 1689 StringBuilder result; |
| 1690 String s; | 1690 String s; |
| 1691 | 1691 |
| (...skipping 1448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3140 return &m_attributeVector.at(index); | 3140 return &m_attributeVector.at(index); |
| 3141 } | 3141 } |
| 3142 | 3142 |
| 3143 void UniqueElementData::acceptHeapVisitor(Visitor* visitor) const | 3143 void UniqueElementData::acceptHeapVisitor(Visitor* visitor) const |
| 3144 { | 3144 { |
| 3145 visitor->visit(m_presentationAttributeStyle); | 3145 visitor->visit(m_presentationAttributeStyle); |
| 3146 ElementData::acceptHeapVisitor(visitor); | 3146 ElementData::acceptHeapVisitor(visitor); |
| 3147 } | 3147 } |
| 3148 | 3148 |
| 3149 } // namespace WebCore | 3149 } // namespace WebCore |
| OLD | NEW |