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 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 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. |
11 * | 11 * |
12 * This library is distributed in the hope that it will be useful, | 12 * This library is distributed in the hope that it will be useful, |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 * Library General Public License for more details. | 15 * Library General Public License for more details. |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 | 297 |
298 if (document() != newChild->document()) | 298 if (document() != newChild->document()) |
299 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); | 299 document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION); |
300 | 300 |
301 insertBeforeCommon(nextChild, *newChild); | 301 insertBeforeCommon(nextChild, *newChild); |
302 | 302 |
303 newChild->updateAncestorConnectedSubframeCountForInsertion(); | 303 newChild->updateAncestorConnectedSubframeCountForInsertion(); |
304 | 304 |
305 ChildListMutationScope(*this).childAdded(*newChild); | 305 ChildListMutationScope(*this).childAdded(*newChild); |
306 | 306 |
307 childrenChanged(true, newChild->previousSibling(), &nextChild, 1); | 307 ChildrenChange change = {ChildInserted, newChild->previousSibling(), &nextCh
ild, ChildrenChangeSourceParser}; |
| 308 childrenChanged(change); |
308 | 309 |
309 notifyNodeInserted(*newChild); | 310 notifyNodeInserted(*newChild); |
310 } | 311 } |
311 | 312 |
312 void ContainerNode::replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* ol
dChild, ExceptionState& exceptionState) | 313 void ContainerNode::replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* ol
dChild, ExceptionState& exceptionState) |
313 { | 314 { |
314 #if !ENABLE(OILPAN) | 315 #if !ENABLE(OILPAN) |
315 // Check that this node is not "floating". | 316 // Check that this node is not "floating". |
316 // If it is, it can be deleted as a side effect of sending mutation events. | 317 // If it is, it can be deleted as a side effect of sending mutation events. |
317 ASSERT(refCount() || parentOrShadowHostNode()); | 318 ASSERT(refCount() || parentOrShadowHostNode()); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 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?"); | 477 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?"); |
477 return; | 478 return; |
478 } | 479 } |
479 | 480 |
480 { | 481 { |
481 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; | 482 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; |
482 | 483 |
483 Node* prev = child->previousSibling(); | 484 Node* prev = child->previousSibling(); |
484 Node* next = child->nextSibling(); | 485 Node* next = child->nextSibling(); |
485 removeBetween(prev, next, *child); | 486 removeBetween(prev, next, *child); |
486 childrenChanged(false, prev, next, -1); | 487 ChildrenChange change = {ChildRemoved, prev, next, ChildrenChangeSourceA
PI}; |
| 488 childrenChanged(change); |
487 notifyNodeRemoved(*child); | 489 notifyNodeRemoved(*child); |
488 } | 490 } |
489 dispatchSubtreeModifiedEvent(); | 491 dispatchSubtreeModifiedEvent(); |
490 } | 492 } |
491 | 493 |
492 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol
dChild) | 494 void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol
dChild) |
493 { | 495 { |
494 NoEventDispatchAssertion assertNoEventDispatch; | 496 NoEventDispatchAssertion assertNoEventDispatch; |
495 | 497 |
496 ASSERT(oldChild.parentNode() == this); | 498 ASSERT(oldChild.parentNode() == this); |
(...skipping 25 matching lines...) Expand all Loading... |
522 Node* prev = oldChild.previousSibling(); | 524 Node* prev = oldChild.previousSibling(); |
523 Node* next = oldChild.nextSibling(); | 525 Node* next = oldChild.nextSibling(); |
524 | 526 |
525 oldChild.updateAncestorConnectedSubframeCountForRemoval(); | 527 oldChild.updateAncestorConnectedSubframeCountForRemoval(); |
526 | 528 |
527 ChildListMutationScope(*this).willRemoveChild(oldChild); | 529 ChildListMutationScope(*this).willRemoveChild(oldChild); |
528 oldChild.notifyMutationObserversNodeWillDetach(); | 530 oldChild.notifyMutationObserversNodeWillDetach(); |
529 | 531 |
530 removeBetween(prev, next, oldChild); | 532 removeBetween(prev, next, oldChild); |
531 | 533 |
532 childrenChanged(true, prev, next, -1); | 534 ChildrenChange change = {ChildRemoved, prev, next, ChildrenChangeSourceParse
r}; |
| 535 childrenChanged(change); |
533 notifyNodeRemoved(oldChild); | 536 notifyNodeRemoved(oldChild); |
534 } | 537 } |
535 | 538 |
536 // this differs from other remove functions because it forcibly removes all the
children, | 539 // this differs from other remove functions because it forcibly removes all the
children, |
537 // regardless of read-only status or event exceptions, e.g. | 540 // regardless of read-only status or event exceptions, e.g. |
538 void ContainerNode::removeChildren() | 541 void ContainerNode::removeChildren() |
539 { | 542 { |
540 if (!m_firstChild) | 543 if (!m_firstChild) |
541 return; | 544 return; |
542 | 545 |
(...skipping 28 matching lines...) Expand all Loading... |
571 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; | 574 HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates; |
572 { | 575 { |
573 NoEventDispatchAssertion assertNoEventDispatch; | 576 NoEventDispatchAssertion assertNoEventDispatch; |
574 removedChildren.reserveInitialCapacity(countChildren()); | 577 removedChildren.reserveInitialCapacity(countChildren()); |
575 while (m_firstChild) { | 578 while (m_firstChild) { |
576 removedChildren.append(m_firstChild); | 579 removedChildren.append(m_firstChild); |
577 removeBetween(0, m_firstChild->nextSibling(), *m_firstChild); | 580 removeBetween(0, m_firstChild->nextSibling(), *m_firstChild); |
578 } | 581 } |
579 } | 582 } |
580 | 583 |
581 childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size())); | 584 ChildrenChange change = {AllChildrenRemoved, nullptr, nullptr, ChildrenC
hangeSourceAPI}; |
| 585 childrenChanged(change); |
582 | 586 |
583 for (size_t i = 0; i < removedChildren.size(); ++i) | 587 for (size_t i = 0; i < removedChildren.size(); ++i) |
584 notifyNodeRemoved(*removedChildren[i]); | 588 notifyNodeRemoved(*removedChildren[i]); |
585 } | 589 } |
586 | 590 |
587 dispatchSubtreeModifiedEvent(); | 591 dispatchSubtreeModifiedEvent(); |
588 } | 592 } |
589 | 593 |
590 void ContainerNode::appendChild(PassRefPtrWillBeRawPtr<Node> newChild, Exception
State& exceptionState) | 594 void ContainerNode::appendChild(PassRefPtrWillBeRawPtr<Node> newChild, Exception
State& exceptionState) |
591 { | 595 { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 { | 664 { |
661 NoEventDispatchAssertion assertNoEventDispatch; | 665 NoEventDispatchAssertion assertNoEventDispatch; |
662 ScriptForbiddenScope forbidScript; | 666 ScriptForbiddenScope forbidScript; |
663 | 667 |
664 treeScope().adoptIfNeeded(*newChild); | 668 treeScope().adoptIfNeeded(*newChild); |
665 appendChildCommon(*newChild); | 669 appendChildCommon(*newChild); |
666 newChild->updateAncestorConnectedSubframeCountForInsertion(); | 670 newChild->updateAncestorConnectedSubframeCountForInsertion(); |
667 ChildListMutationScope(*this).childAdded(*newChild); | 671 ChildListMutationScope(*this).childAdded(*newChild); |
668 } | 672 } |
669 | 673 |
670 childrenChanged(true, last, 0, 1); | 674 ChildrenChange change = {ChildInserted, last, nullptr, ChildrenChangeSourceP
arser}; |
| 675 childrenChanged(change); |
671 notifyNodeInserted(*newChild); | 676 notifyNodeInserted(*newChild); |
672 } | 677 } |
673 | 678 |
674 void ContainerNode::notifyNodeInserted(Node& root) | 679 void ContainerNode::notifyNodeInserted(Node& root) |
675 { | 680 { |
676 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); | 681 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); |
677 | 682 |
678 InspectorInstrumentation::didInsertDOMNode(&root); | 683 InspectorInstrumentation::didInsertDOMNode(&root); |
679 | 684 |
680 RefPtrWillBeRawPtr<Node> protect(this); | 685 RefPtrWillBeRawPtr<Node> protect(this); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 Node::attach(context); | 739 Node::attach(context); |
735 } | 740 } |
736 | 741 |
737 void ContainerNode::detach(const AttachContext& context) | 742 void ContainerNode::detach(const AttachContext& context) |
738 { | 743 { |
739 detachChildren(context); | 744 detachChildren(context); |
740 clearChildNeedsStyleRecalc(); | 745 clearChildNeedsStyleRecalc(); |
741 Node::detach(context); | 746 Node::detach(context); |
742 } | 747 } |
743 | 748 |
744 void ContainerNode::childrenChanged(bool changedByParser, Node*, Node*, int chil
dCountDelta) | 749 void ContainerNode::childrenChanged(const ChildrenChange& change) |
745 { | 750 { |
746 document().incDOMTreeVersion(); | 751 document().incDOMTreeVersion(); |
747 if (!changedByParser && childCountDelta) | 752 if (!change.byParser && change.type != TextChanged) |
748 document().updateRangesAfterChildrenChanged(this); | 753 document().updateRangesAfterChildrenChanged(this); |
749 invalidateNodeListCachesInAncestors(); | 754 invalidateNodeListCachesInAncestors(); |
750 if (childCountDelta > 0 && !childNeedsStyleRecalc()) { | 755 if (change.type == ChildInserted && !childNeedsStyleRecalc()) { |
751 setChildNeedsStyleRecalc(); | 756 setChildNeedsStyleRecalc(); |
752 markAncestorsWithChildNeedsStyleRecalc(); | 757 markAncestorsWithChildNeedsStyleRecalc(); |
753 } | 758 } |
754 } | 759 } |
755 | 760 |
756 void ContainerNode::cloneChildNodes(ContainerNode *clone) | 761 void ContainerNode::cloneChildNodes(ContainerNode *clone) |
757 { | 762 { |
758 TrackExceptionState exceptionState; | 763 TrackExceptionState exceptionState; |
759 for (Node* n = firstChild(); n && !exceptionState.hadException(); n = n->nex
tSibling()) | 764 for (Node* n = firstChild(); n && !exceptionState.hadException(); n = n->nex
tSibling()) |
760 clone->appendChild(n->cloneNode(true), exceptionState); | 765 clone->appendChild(n->cloneNode(true), exceptionState); |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1087 | 1092 |
1088 void ContainerNode::updateTreeAfterInsertion(Node& child) | 1093 void ContainerNode::updateTreeAfterInsertion(Node& child) |
1089 { | 1094 { |
1090 #if !ENABLE(OILPAN) | 1095 #if !ENABLE(OILPAN) |
1091 ASSERT(refCount()); | 1096 ASSERT(refCount()); |
1092 ASSERT(child.refCount()); | 1097 ASSERT(child.refCount()); |
1093 #endif | 1098 #endif |
1094 | 1099 |
1095 ChildListMutationScope(*this).childAdded(child); | 1100 ChildListMutationScope(*this).childAdded(child); |
1096 | 1101 |
1097 childrenChanged(false, child.previousSibling(), child.nextSibling(), 1); | 1102 ChildrenChange change = {ChildInserted, child.previousSibling(), child.nextS
ibling(), ChildrenChangeSourceAPI}; |
| 1103 childrenChanged(change); |
1098 | 1104 |
1099 notifyNodeInserted(child); | 1105 notifyNodeInserted(child); |
1100 | 1106 |
1101 dispatchChildInsertionEvents(child); | 1107 dispatchChildInsertionEvents(child); |
1102 } | 1108 } |
1103 | 1109 |
1104 bool ContainerNode::hasRestyleFlagInternal(DynamicRestyleFlags mask) const | 1110 bool ContainerNode::hasRestyleFlagInternal(DynamicRestyleFlags mask) const |
1105 { | 1111 { |
1106 return rareData()->hasRestyleFlag(mask); | 1112 return rareData()->hasRestyleFlag(mask); |
1107 } | 1113 } |
(...skipping 29 matching lines...) Expand all Loading... |
1137 | 1143 |
1138 if (childRulesChanged && hasDirectAdjacentRules) | 1144 if (childRulesChanged && hasDirectAdjacentRules) |
1139 forceCheckOfNextElementCount = document.styleEngine()->maxDirectAdja
centSelectors(); | 1145 forceCheckOfNextElementCount = document.styleEngine()->maxDirectAdja
centSelectors(); |
1140 else if (forceCheckOfNextElementCount) | 1146 else if (forceCheckOfNextElementCount) |
1141 --forceCheckOfNextElementCount; | 1147 --forceCheckOfNextElementCount; |
1142 | 1148 |
1143 forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childR
ulesChanged && hasIndirectAdjacentRules); | 1149 forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childR
ulesChanged && hasIndirectAdjacentRules); |
1144 } | 1150 } |
1145 } | 1151 } |
1146 | 1152 |
1147 void ContainerNode::checkForSiblingStyleChanges(bool finishedParsingCallback, No
de* beforeChange, Node* afterChange, int childCountDelta) | 1153 void ContainerNode::checkForSiblingStyleChanges(SiblingCheckType changeType, Nod
e* beforeChange, Node* afterChange) |
1148 { | 1154 { |
1149 if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || style
ChangeType() >= SubtreeStyleChange) | 1155 if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || style
ChangeType() >= SubtreeStyleChange) |
1150 return; | 1156 return; |
1151 | 1157 |
1152 if (needsStyleRecalc() && childrenAffectedByPositionalRules()) | 1158 if (needsStyleRecalc() && childrenAffectedByPositionalRules()) |
1153 return; | 1159 return; |
1154 | 1160 |
1155 // Forward positional selectors include nth-child, nth-of-type, first-of-typ
e and only-of-type. | 1161 // Forward positional selectors include nth-child, nth-of-type, first-of-typ
e and only-of-type. |
1156 // The indirect adjacent selector is the ~ selector. | 1162 // The indirect adjacent selector is the ~ selector. |
1157 // Backward positional selectors include nth-last-child, nth-last-of-type, l
ast-of-type and only-of-type. | 1163 // Backward positional selectors include nth-last-child, nth-last-of-type, l
ast-of-type and only-of-type. |
(...skipping 18 matching lines...) Expand all Loading... |
1176 | 1182 |
1177 // Find the first element node following |afterChange| | 1183 // Find the first element node following |afterChange| |
1178 Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterC
hange : ElementTraversal::nextSibling(*afterChange); | 1184 Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterC
hange : ElementTraversal::nextSibling(*afterChange); |
1179 RenderStyle* firstElementAfterInsertionStyle = firstElementAfterInsertio
n ? firstElementAfterInsertion->renderStyle() : 0; | 1185 RenderStyle* firstElementAfterInsertionStyle = firstElementAfterInsertio
n ? firstElementAfterInsertion->renderStyle() : 0; |
1180 | 1186 |
1181 // This is the insert/append case. | 1187 // This is the insert/append case. |
1182 if (newFirstChild != firstElementAfterInsertion && firstElementAfterInse
rtionStyle && firstElementAfterInsertionStyle->firstChildState()) | 1188 if (newFirstChild != firstElementAfterInsertion && firstElementAfterInse
rtionStyle && firstElementAfterInsertionStyle->firstChildState()) |
1183 firstElementAfterInsertion->setNeedsStyleRecalc(SubtreeStyleChange); | 1189 firstElementAfterInsertion->setNeedsStyleRecalc(SubtreeStyleChange); |
1184 | 1190 |
1185 // We also have to handle node removal. | 1191 // We also have to handle node removal. |
1186 if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion &
& newFirstChild && (!newFirstChildStyle || !newFirstChildStyle->firstChildState(
))) | 1192 if (changeType == SiblingRemoved && newFirstChild == firstElementAfterIn
sertion && newFirstChild && (!newFirstChildStyle || !newFirstChildStyle->firstCh
ildState())) |
1187 newFirstChild->setNeedsStyleRecalc(SubtreeStyleChange); | 1193 newFirstChild->setNeedsStyleRecalc(SubtreeStyleChange); |
1188 } | 1194 } |
1189 | 1195 |
1190 // :last-child. In the parser callback case, we don't have to check anything
, since we were right the first time. | 1196 // :last-child. In the parser callback case, we don't have to check anything
, since we were right the first time. |
1191 // In the DOM case, we only need to do something if |afterChange| is not 0. | 1197 // In the DOM case, we only need to do something if |afterChange| is not 0. |
1192 if (childrenAffectedByLastChildRules() && beforeChange) { | 1198 if (childrenAffectedByLastChildRules() && beforeChange) { |
1193 // Find our new last child. | 1199 // Find our new last child. |
1194 Node* newLastChild = ElementTraversal::lastChild(*this); | 1200 Node* newLastChild = ElementTraversal::lastChild(*this); |
1195 RenderStyle* newLastChildStyle = newLastChild ? newLastChild->renderStyl
e() : 0; | 1201 RenderStyle* newLastChildStyle = newLastChild ? newLastChild->renderStyl
e() : 0; |
1196 | 1202 |
1197 // Find the last element node going backwards from |beforeChange| | 1203 // Find the last element node going backwards from |beforeChange| |
1198 Node* lastElementBeforeInsertion = beforeChange->isElementNode() ? befor
eChange : ElementTraversal::previousSibling(*beforeChange); | 1204 Node* lastElementBeforeInsertion = beforeChange->isElementNode() ? befor
eChange : ElementTraversal::previousSibling(*beforeChange); |
1199 RenderStyle* lastElementBeforeInsertionStyle = lastElementBeforeInsertio
n ? lastElementBeforeInsertion->renderStyle() : 0; | 1205 RenderStyle* lastElementBeforeInsertionStyle = lastElementBeforeInsertio
n ? lastElementBeforeInsertion->renderStyle() : 0; |
1200 | 1206 |
1201 if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInser
tionStyle && lastElementBeforeInsertionStyle->lastChildState()) | 1207 if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInser
tionStyle && lastElementBeforeInsertionStyle->lastChildState()) |
1202 lastElementBeforeInsertion->setNeedsStyleRecalc(SubtreeStyleChange); | 1208 lastElementBeforeInsertion->setNeedsStyleRecalc(SubtreeStyleChange); |
1203 | 1209 |
1204 // We also have to handle node removal. The parser callback case is simi
lar to node removal as well in that we need to change the last child | 1210 // We also have to handle node removal. The parser callback case is simi
lar to node removal as well in that we need to change the last child |
1205 // to match now. | 1211 // to match now. |
1206 if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild ==
lastElementBeforeInsertion && newLastChild && (!newLastChildStyle || !newLastChi
ldStyle->lastChildState())) | 1212 if ((changeType == SiblingRemoved || changeType == FinishedParsingChildr
en) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastCh
ildStyle || !newLastChildStyle->lastChildState())) |
1207 newLastChild->setNeedsStyleRecalc(SubtreeStyleChange); | 1213 newLastChild->setNeedsStyleRecalc(SubtreeStyleChange); |
1208 } | 1214 } |
1209 | 1215 |
1210 // The + selector. We need to invalidate the first element following the ins
ertion point. It is the only possible element | 1216 // The + selector. We need to invalidate the first element following the ins
ertion point. It is the only possible element |
1211 // that could be affected by this DOM change. | 1217 // that could be affected by this DOM change. |
1212 if (childrenAffectedByDirectAdjacentRules() && afterChange) { | 1218 if (childrenAffectedByDirectAdjacentRules() && afterChange) { |
1213 if (Node* firstElementAfterInsertion = afterChange->isElementNode() ? af
terChange : ElementTraversal::nextSibling(*afterChange)) | 1219 if (Node* firstElementAfterInsertion = afterChange->isElementNode() ? af
terChange : ElementTraversal::nextSibling(*afterChange)) |
1214 firstElementAfterInsertion->setNeedsStyleRecalc(SubtreeStyleChange); | 1220 firstElementAfterInsertion->setNeedsStyleRecalc(SubtreeStyleChange); |
1215 } | 1221 } |
1216 } | 1222 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1287 return true; | 1293 return true; |
1288 | 1294 |
1289 if (node->isElementNode() && toElement(node)->shadow()) | 1295 if (node->isElementNode() && toElement(node)->shadow()) |
1290 return true; | 1296 return true; |
1291 | 1297 |
1292 return false; | 1298 return false; |
1293 } | 1299 } |
1294 #endif | 1300 #endif |
1295 | 1301 |
1296 } // namespace WebCore | 1302 } // namespace WebCore |
OLD | NEW |