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

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

Issue 395633007: Call ContainerNode::checkForSiblingStyleChanges() for Element insertion / removal only (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix typo Created 6 years, 5 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 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved. 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 305
306 if (document() != newChild->document()) 306 if (document() != newChild->document())
307 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); 307 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
308 308
309 insertBeforeCommon(nextChild, *newChild); 309 insertBeforeCommon(nextChild, *newChild);
310 310
311 newChild->updateAncestorConnectedSubframeCountForInsertion(); 311 newChild->updateAncestorConnectedSubframeCountForInsertion();
312 312
313 ChildListMutationScope(*this).childAdded(*newChild); 313 ChildListMutationScope(*this).childAdded(*newChild);
314 314
315 ChildrenChange change = {ChildInserted, newChild->previousSibling(), &nextCh ild, ChildrenChangeSourceParser}; 315 childrenChanged(ChildrenChange::forInsertion(*newChild, ChildrenChangeSource Parser));
316 childrenChanged(change);
317 316
318 notifyNodeInserted(*newChild); 317 notifyNodeInserted(*newChild);
319 } 318 }
320 319
321 PassRefPtrWillBeRawPtr<Node> ContainerNode::replaceChild(PassRefPtrWillBeRawPtr< Node> newChild, PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& exception State) 320 PassRefPtrWillBeRawPtr<Node> ContainerNode::replaceChild(PassRefPtrWillBeRawPtr< Node> newChild, PassRefPtrWillBeRawPtr<Node> oldChild, ExceptionState& exception State)
322 { 321 {
323 #if !ENABLE(OILPAN) 322 #if !ENABLE(OILPAN)
324 // Check that this node is not "floating". 323 // Check that this node is not "floating".
325 // If it is, it can be deleted as a side effect of sending mutation events. 324 // If it is, it can be deleted as a side effect of sending mutation events.
326 ASSERT(refCount() || parentOrShadowHostNode()); 325 ASSERT(refCount() || parentOrShadowHostNode());
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 exceptionState.throwDOMException(NotFoundError, "The node to be removed is no longer a child of this node. Perhaps it was moved in response to a mutatio n?"); 560 exceptionState.throwDOMException(NotFoundError, "The node to be removed is no longer a child of this node. Perhaps it was moved in response to a mutatio n?");
562 return nullptr; 561 return nullptr;
563 } 562 }
564 563
565 { 564 {
566 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; 565 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
567 566
568 Node* prev = child->previousSibling(); 567 Node* prev = child->previousSibling();
569 Node* next = child->nextSibling(); 568 Node* next = child->nextSibling();
570 removeBetween(prev, next, *child); 569 removeBetween(prev, next, *child);
571 ChildrenChange change = {ChildRemoved, prev, next, ChildrenChangeSourceA PI}; 570 childrenChanged(ChildrenChange::forRemoval(*child, prev, next, ChildrenC hangeSourceAPI));
572 childrenChanged(change);
573 notifyNodeRemoved(*child); 571 notifyNodeRemoved(*child);
574 } 572 }
575 dispatchSubtreeModifiedEvent(); 573 dispatchSubtreeModifiedEvent();
576 return child; 574 return child;
577 } 575 }
578 576
579 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol dChild) 577 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol dChild)
580 { 578 {
581 NoEventDispatchAssertion assertNoEventDispatch; 579 NoEventDispatchAssertion assertNoEventDispatch;
582 580
(...skipping 26 matching lines...) Expand all
609 Node* prev = oldChild.previousSibling(); 607 Node* prev = oldChild.previousSibling();
610 Node* next = oldChild.nextSibling(); 608 Node* next = oldChild.nextSibling();
611 609
612 oldChild.updateAncestorConnectedSubframeCountForRemoval(); 610 oldChild.updateAncestorConnectedSubframeCountForRemoval();
613 611
614 ChildListMutationScope(*this).willRemoveChild(oldChild); 612 ChildListMutationScope(*this).willRemoveChild(oldChild);
615 oldChild.notifyMutationObserversNodeWillDetach(); 613 oldChild.notifyMutationObserversNodeWillDetach();
616 614
617 removeBetween(prev, next, oldChild); 615 removeBetween(prev, next, oldChild);
618 616
619 ChildrenChange change = {ChildRemoved, prev, next, ChildrenChangeSourceParse r}; 617 childrenChanged(ChildrenChange::forRemoval(oldChild, prev, next, ChildrenCha ngeSourceParser));
620 childrenChanged(change);
621 notifyNodeRemoved(oldChild); 618 notifyNodeRemoved(oldChild);
622 } 619 }
623 620
624 // this differs from other remove functions because it forcibly removes all the children, 621 // this differs from other remove functions because it forcibly removes all the children,
625 // regardless of read-only status or event exceptions, e.g. 622 // regardless of read-only status or event exceptions, e.g.
626 void ContainerNode::removeChildren() 623 void ContainerNode::removeChildren()
627 { 624 {
628 if (!m_firstChild) 625 if (!m_firstChild)
629 return; 626 return;
630 627
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 void ContainerNode::parserAppendChild(PassRefPtrWillBeRawPtr<Node> newChild) 741 void ContainerNode::parserAppendChild(PassRefPtrWillBeRawPtr<Node> newChild)
745 { 742 {
746 ASSERT(newChild); 743 ASSERT(newChild);
747 ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle re parenting (and want DOM mutation events). 744 ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle re parenting (and want DOM mutation events).
748 ASSERT(!newChild->isDocumentFragment()); 745 ASSERT(!newChild->isDocumentFragment());
749 ASSERT(!isHTMLTemplateElement(this)); 746 ASSERT(!isHTMLTemplateElement(this));
750 747
751 if (document() != newChild->document()) 748 if (document() != newChild->document())
752 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); 749 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
753 750
754 Node* last = m_lastChild;
755
756 { 751 {
757 NoEventDispatchAssertion assertNoEventDispatch; 752 NoEventDispatchAssertion assertNoEventDispatch;
758 ScriptForbiddenScope forbidScript; 753 ScriptForbiddenScope forbidScript;
759 754
760 treeScope().adoptIfNeeded(*newChild); 755 treeScope().adoptIfNeeded(*newChild);
761 appendChildCommon(*newChild); 756 appendChildCommon(*newChild);
762 newChild->updateAncestorConnectedSubframeCountForInsertion(); 757 newChild->updateAncestorConnectedSubframeCountForInsertion();
763 ChildListMutationScope(*this).childAdded(*newChild); 758 ChildListMutationScope(*this).childAdded(*newChild);
764 } 759 }
765 760
766 ChildrenChange change = {ChildInserted, last, nullptr, ChildrenChangeSourceP arser}; 761 childrenChanged(ChildrenChange::forInsertion(*newChild, ChildrenChangeSource Parser));
767 childrenChanged(change);
768 notifyNodeInserted(*newChild); 762 notifyNodeInserted(*newChild);
769 } 763 }
770 764
771 void ContainerNode::notifyNodeInserted(Node& root) 765 void ContainerNode::notifyNodeInserted(Node& root)
772 { 766 {
773 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); 767 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
774 768
775 InspectorInstrumentation::didInsertDOMNode(&root); 769 InspectorInstrumentation::didInsertDOMNode(&root);
776 770
777 RefPtrWillBeRawPtr<Node> protect(this); 771 RefPtrWillBeRawPtr<Node> protect(this);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 clearChildNeedsStyleRecalc(); 831 clearChildNeedsStyleRecalc();
838 Node::detach(context); 832 Node::detach(context);
839 } 833 }
840 834
841 void ContainerNode::childrenChanged(const ChildrenChange& change) 835 void ContainerNode::childrenChanged(const ChildrenChange& change)
842 { 836 {
843 document().incDOMTreeVersion(); 837 document().incDOMTreeVersion();
844 if (!change.byParser && change.type != TextChanged) 838 if (!change.byParser && change.type != TextChanged)
845 document().updateRangesAfterChildrenChanged(this); 839 document().updateRangesAfterChildrenChanged(this);
846 invalidateNodeListCachesInAncestors(); 840 invalidateNodeListCachesInAncestors();
847 if (change.type == ChildInserted && !childNeedsStyleRecalc()) { 841 if (change.isChildInsertion() && !childNeedsStyleRecalc()) {
848 setChildNeedsStyleRecalc(); 842 setChildNeedsStyleRecalc();
849 markAncestorsWithChildNeedsStyleRecalc(); 843 markAncestorsWithChildNeedsStyleRecalc();
850 } 844 }
851 } 845 }
852 846
853 void ContainerNode::cloneChildNodes(ContainerNode *clone) 847 void ContainerNode::cloneChildNodes(ContainerNode *clone)
854 { 848 {
855 TrackExceptionState exceptionState; 849 TrackExceptionState exceptionState;
856 for (Node* n = firstChild(); n && !exceptionState.hadException(); n = n->nex tSibling()) 850 for (Node* n = firstChild(); n && !exceptionState.hadException(); n = n->nex tSibling())
857 clone->appendChild(n->cloneNode(true), exceptionState); 851 clone->appendChild(n->cloneNode(true), exceptionState);
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 1178
1185 void ContainerNode::updateTreeAfterInsertion(Node& child) 1179 void ContainerNode::updateTreeAfterInsertion(Node& child)
1186 { 1180 {
1187 #if !ENABLE(OILPAN) 1181 #if !ENABLE(OILPAN)
1188 ASSERT(refCount()); 1182 ASSERT(refCount());
1189 ASSERT(child.refCount()); 1183 ASSERT(child.refCount());
1190 #endif 1184 #endif
1191 1185
1192 ChildListMutationScope(*this).childAdded(child); 1186 ChildListMutationScope(*this).childAdded(child);
1193 1187
1194 ChildrenChange change = {ChildInserted, child.previousSibling(), child.nextS ibling(), ChildrenChangeSourceAPI}; 1188 childrenChanged(ChildrenChange::forInsertion(child, ChildrenChangeSourceAPI) );
1195 childrenChanged(change);
1196 1189
1197 notifyNodeInserted(child); 1190 notifyNodeInserted(child);
1198 1191
1199 dispatchChildInsertionEvents(child); 1192 dispatchChildInsertionEvents(child);
1200 } 1193 }
1201 1194
1202 bool ContainerNode::hasRestyleFlagInternal(DynamicRestyleFlags mask) const 1195 bool ContainerNode::hasRestyleFlagInternal(DynamicRestyleFlags mask) const
1203 { 1196 {
1204 return rareData()->hasRestyleFlag(mask); 1197 return rareData()->hasRestyleFlag(mask);
1205 } 1198 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 ASSERT(changeType != FinishedParsingChildren); 1264 ASSERT(changeType != FinishedParsingChildren);
1272 // Find our new first child element. 1265 // Find our new first child element.
1273 Element* firstChildElement = ElementTraversal::firstChild(*this); 1266 Element* firstChildElement = ElementTraversal::firstChild(*this);
1274 RenderStyle* firstChildElementStyle = firstChildElement ? firstChildElem ent->renderStyle() : 0; 1267 RenderStyle* firstChildElementStyle = firstChildElement ? firstChildElem ent->renderStyle() : 0;
1275 1268
1276 // Find the first element after the change. 1269 // Find the first element after the change.
1277 Element* elementAfterChange = nodeAfterChange->isElementNode() ? toEleme nt(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange); 1270 Element* elementAfterChange = nodeAfterChange->isElementNode() ? toEleme nt(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange);
1278 RenderStyle* elementAfterChangeStyle = elementAfterChange ? elementAfter Change->renderStyle() : 0; 1271 RenderStyle* elementAfterChangeStyle = elementAfterChange ? elementAfter Change->renderStyle() : 0;
1279 1272
1280 // This is the element insertion as first child element case. 1273 // This is the element insertion as first child element case.
1281 if (firstChildElement != elementAfterChange && elementAfterChangeStyle & & elementAfterChangeStyle->firstChildState()) 1274 if (firstChildElement != elementAfterChange && elementAfterChangeStyle & & elementAfterChangeStyle->firstChildState()) {
1275 ASSERT(changeType == SiblingElementInserted);
1282 elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange); 1276 elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange);
1277 }
1283 1278
1284 // This is the first child element removal case. 1279 // This is the first child element removal case.
1285 if (changeType == SiblingRemoved && firstChildElement == elementAfterCha nge && firstChildElement && (!firstChildElementStyle || !firstChildElementStyle- >firstChildState())) 1280 if (changeType == SiblingElementRemoved && firstChildElement == elementA fterChange && firstChildElement && (!firstChildElementStyle || !firstChildElemen tStyle->firstChildState()))
1286 firstChildElement->setNeedsStyleRecalc(SubtreeStyleChange); 1281 firstChildElement->setNeedsStyleRecalc(SubtreeStyleChange);
1287 } 1282 }
1288 1283
1289 // :last-child. In the parser callback case, we don't have to check anything , since we were right the first time. 1284 // :last-child. In the parser callback case, we don't have to check anything , since we were right the first time.
1290 // In the DOM case, we only need to do something if |afterChange| is not 0. 1285 // In the DOM case, we only need to do something if |afterChange| is not 0.
1291 if (childrenAffectedByLastChildRules() && nodeBeforeChange) { 1286 if (childrenAffectedByLastChildRules() && nodeBeforeChange) {
1292 // Find our new last child element. 1287 // Find our new last child element.
1293 Element* lastChildElement = ElementTraversal::lastChild(*this); 1288 Element* lastChildElement = ElementTraversal::lastChild(*this);
1294 RenderStyle* lastChildElementStyle = lastChildElement ? lastChildElement ->renderStyle() : 0; 1289 RenderStyle* lastChildElementStyle = lastChildElement ? lastChildElement ->renderStyle() : 0;
1295 1290
1296 // Find the last element before the change. 1291 // Find the last element before the change.
1297 Element* elementBeforeChange = nodeBeforeChange->isElementNode() ? toEle ment(nodeBeforeChange) : ElementTraversal::previousSibling(*nodeBeforeChange); 1292 Element* elementBeforeChange = nodeBeforeChange->isElementNode() ? toEle ment(nodeBeforeChange) : ElementTraversal::previousSibling(*nodeBeforeChange);
1298 RenderStyle* elementBeforeChangeStyle = elementBeforeChange ? elementBef oreChange->renderStyle() : 0; 1293 RenderStyle* elementBeforeChangeStyle = elementBeforeChange ? elementBef oreChange->renderStyle() : 0;
1299 1294
1300 // This is the element insertion as last child element case. 1295 // This is the element insertion as last child element case.
1301 if (lastChildElement != elementBeforeChange && elementBeforeChangeStyle && elementBeforeChangeStyle->lastChildState()) 1296 if (lastChildElement != elementBeforeChange && elementBeforeChangeStyle && elementBeforeChangeStyle->lastChildState()) {
1297 ASSERT(SiblingElementInserted);
1302 elementBeforeChange->setNeedsStyleRecalc(SubtreeStyleChange); 1298 elementBeforeChange->setNeedsStyleRecalc(SubtreeStyleChange);
1299 }
1303 1300
1304 // This is the last child element removal case. The parser callback case is similar to node removal as well in that we need to change the last child 1301 // This is the last child element removal case. The parser callback case is similar to node removal as well in that we need to change the last child
1305 // to match now. 1302 // to match now.
1306 if ((changeType == SiblingRemoved || changeType == FinishedParsingChildr en) && lastChildElement == elementBeforeChange && lastChildElement && (!lastChil dElementStyle || !lastChildElementStyle->lastChildState())) 1303 if ((changeType == SiblingElementRemoved || changeType == FinishedParsin gChildren) && lastChildElement == elementBeforeChange && lastChildElement && (!l astChildElementStyle || !lastChildElementStyle->lastChildState()))
1307 lastChildElement->setNeedsStyleRecalc(SubtreeStyleChange); 1304 lastChildElement->setNeedsStyleRecalc(SubtreeStyleChange);
1308 } 1305 }
1309 1306
1310 // The + selector. We need to invalidate the first element following the cha nge. It is the only possible element 1307 // The + selector. We need to invalidate the first element following the cha nge. It is the only possible element
1311 // that could be affected by this DOM change. 1308 // that could be affected by this DOM change.
1312 if (childrenAffectedByDirectAdjacentRules() && nodeAfterChange) { 1309 if (childrenAffectedByDirectAdjacentRules() && nodeAfterChange) {
1313 if (Element* elementAfterChange = nodeAfterChange->isElementNode() ? toE lement(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange)) 1310 if (Element* elementAfterChange = nodeAfterChange->isElementNode() ? toE lement(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange))
1314 elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange); 1311 elementAfterChange->setNeedsStyleRecalc(SubtreeStyleChange);
1315 } 1312 }
1316 } 1313 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 return true; 1384 return true;
1388 1385
1389 if (node->isElementNode() && toElement(node)->shadow()) 1386 if (node->isElementNode() && toElement(node)->shadow())
1390 return true; 1387 return true;
1391 1388
1392 return false; 1389 return false;
1393 } 1390 }
1394 #endif 1391 #endif
1395 1392
1396 } // namespace WebCore 1393 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698