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

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

Issue 22043003: [oilpan] Handlify childrenChanged. (Closed) Base URL: svn://svn.chromium.org/blink/branches/oilpan
Patch Set: Created 7 years, 4 months 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 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698