| 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, 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 bool ContainerNode::checkAcceptChildGuaranteedNodeTypes(const Node& newChild, Ex
ceptionState& exceptionState) const | 170 bool ContainerNode::checkAcceptChildGuaranteedNodeTypes(const Node& newChild, Ex
ceptionState& exceptionState) const |
| 171 { | 171 { |
| 172 ASSERT(isChildTypeAllowed(newChild)); | 172 ASSERT(isChildTypeAllowed(newChild)); |
| 173 if (newChild.contains(this)) { | 173 if (newChild.contains(this)) { |
| 174 exceptionState.throwDOMException(HierarchyRequestError, "The new child e
lement contains the parent."); | 174 exceptionState.throwDOMException(HierarchyRequestError, "The new child e
lement contains the parent."); |
| 175 return false; | 175 return false; |
| 176 } | 176 } |
| 177 return true; | 177 return true; |
| 178 } | 178 } |
| 179 | 179 |
| 180 void ContainerNode::insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* re
fChild, ExceptionState& exceptionState) | 180 PassRefPtrWillBeRawPtr<Node> ContainerNode::insertBefore(PassRefPtrWillBeRawPtr<
Node> newChild, Node* refChild, ExceptionState& exceptionState) |
| 181 { | 181 { |
| 182 #if !ENABLE(OILPAN) | 182 #if !ENABLE(OILPAN) |
| 183 // Check that this node is not "floating". | 183 // Check that this node is not "floating". |
| 184 // If it is, it can be deleted as a side effect of sending mutation events. | 184 // If it is, it can be deleted as a side effect of sending mutation events. |
| 185 ASSERT(refCount() || parentOrShadowHostNode()); | 185 ASSERT(refCount() || parentOrShadowHostNode()); |
| 186 #endif | 186 #endif |
| 187 | 187 |
| 188 RefPtrWillBeRawPtr<Node> protect(this); | 188 RefPtrWillBeRawPtr<Node> protect(this); |
| 189 | 189 |
| 190 // insertBefore(node, 0) is equivalent to appendChild(node) | 190 // insertBefore(node, 0) is equivalent to appendChild(node) |
| 191 if (!refChild) { | 191 if (!refChild) { |
| 192 appendChild(newChild, exceptionState); | 192 return appendChild(newChild, exceptionState); |
| 193 return; | |
| 194 } | 193 } |
| 195 | 194 |
| 196 // Make sure adding the new child is OK. | 195 // Make sure adding the new child is OK. |
| 197 if (!checkAcceptChild(newChild.get(), 0, exceptionState)) | 196 if (!checkAcceptChild(newChild.get(), 0, exceptionState)) { |
| 198 return; | 197 if (exceptionState.hadException()) |
| 198 return nullptr; |
| 199 return newChild; |
| 200 } |
| 199 ASSERT(newChild); | 201 ASSERT(newChild); |
| 200 | 202 |
| 201 // NotFoundError: Raised if refChild is not a child of this node | 203 // NotFoundError: Raised if refChild is not a child of this node |
| 202 if (refChild->parentNode() != this) { | 204 if (refChild->parentNode() != this) { |
| 203 exceptionState.throwDOMException(NotFoundError, "The node before which t
he new node is to be inserted is not a child of this node."); | 205 exceptionState.throwDOMException(NotFoundError, "The node before which t
he new node is to be inserted is not a child of this node."); |
| 204 return; | 206 return nullptr; |
| 205 } | 207 } |
| 206 | 208 |
| 207 if (refChild->previousSibling() == newChild || refChild == newChild) // noth
ing to do | 209 // nothing to do |
| 208 return; | 210 if (refChild->previousSibling() == newChild || refChild == newChild) |
| 211 return newChild; |
| 209 | 212 |
| 210 RefPtrWillBeRawPtr<Node> next = refChild; | 213 RefPtrWillBeRawPtr<Node> next = refChild; |
| 211 | 214 |
| 212 NodeVector targets; | 215 NodeVector targets; |
| 213 collectChildrenAndRemoveFromOldParent(*newChild, targets, exceptionState); | 216 collectChildrenAndRemoveFromOldParent(*newChild, targets, exceptionState); |
| 214 if (exceptionState.hadException()) | 217 if (exceptionState.hadException()) |
| 215 return; | 218 return nullptr; |
| 216 if (targets.isEmpty()) | 219 if (targets.isEmpty()) |
| 217 return; | 220 return newChild; |
| 218 | 221 |
| 219 // We need this extra check because collectChildrenAndRemoveFromOldParent()
can fire mutation events. | 222 // We need this extra check because collectChildrenAndRemoveFromOldParent()
can fire mutation events. |
| 220 if (!checkAcceptChildGuaranteedNodeTypes(*newChild, exceptionState)) | 223 if (!checkAcceptChildGuaranteedNodeTypes(*newChild, exceptionState)) { |
| 221 return; | 224 if (exceptionState.hadException()) |
| 225 return nullptr; |
| 226 return newChild; |
| 227 } |
| 222 | 228 |
| 223 InspectorInstrumentation::willInsertDOMNode(this); | 229 InspectorInstrumentation::willInsertDOMNode(this); |
| 224 | 230 |
| 225 ChildListMutationScope mutation(*this); | 231 ChildListMutationScope mutation(*this); |
| 226 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); +
+it) { | 232 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); +
+it) { |
| 227 ASSERT(*it); | 233 ASSERT(*it); |
| 228 Node& child = **it; | 234 Node& child = **it; |
| 229 | 235 |
| 230 // Due to arbitrary code running in response to a DOM mutation event it'
s | 236 // Due to arbitrary code running in response to a DOM mutation event it'
s |
| 231 // possible that "next" is no longer a child of "this". | 237 // possible that "next" is no longer a child of "this". |
| 232 // It's also possible that "child" has been inserted elsewhere. | 238 // It's also possible that "child" has been inserted elsewhere. |
| 233 // In either of those cases, we'll just stop. | 239 // In either of those cases, we'll just stop. |
| 234 if (next->parentNode() != this) | 240 if (next->parentNode() != this) |
| 235 break; | 241 break; |
| 236 if (child.parentNode()) | 242 if (child.parentNode()) |
| 237 break; | 243 break; |
| 238 | 244 |
| 239 treeScope().adoptIfNeeded(child); | 245 treeScope().adoptIfNeeded(child); |
| 240 | 246 |
| 241 insertBeforeCommon(*next, child); | 247 insertBeforeCommon(*next, child); |
| 242 | 248 |
| 243 updateTreeAfterInsertion(child); | 249 updateTreeAfterInsertion(child); |
| 244 } | 250 } |
| 245 | 251 |
| 246 dispatchSubtreeModifiedEvent(); | 252 dispatchSubtreeModifiedEvent(); |
| 253 |
| 254 return newChild; |
| 247 } | 255 } |
| 248 | 256 |
| 249 void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild) | 257 void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild) |
| 250 { | 258 { |
| 251 NoEventDispatchAssertion assertNoEventDispatch; | 259 NoEventDispatchAssertion assertNoEventDispatch; |
| 252 ScriptForbiddenScope forbidScript; | 260 ScriptForbiddenScope forbidScript; |
| 253 | 261 |
| 254 ASSERT(!newChild.parentNode()); // Use insertBefore if you need to handle re
parenting (and want DOM mutation events). | 262 ASSERT(!newChild.parentNode()); // Use insertBefore if you need to handle re
parenting (and want DOM mutation events). |
| 255 ASSERT(!newChild.nextSibling()); | 263 ASSERT(!newChild.nextSibling()); |
| 256 ASSERT(!newChild.previousSibling()); | 264 ASSERT(!newChild.previousSibling()); |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 ChildrenChange change = {AllChildrenRemoved, nullptr, nullptr, ChildrenC
hangeSourceAPI}; | 593 ChildrenChange change = {AllChildrenRemoved, nullptr, nullptr, ChildrenC
hangeSourceAPI}; |
| 586 childrenChanged(change); | 594 childrenChanged(change); |
| 587 | 595 |
| 588 for (size_t i = 0; i < removedChildren.size(); ++i) | 596 for (size_t i = 0; i < removedChildren.size(); ++i) |
| 589 notifyNodeRemoved(*removedChildren[i]); | 597 notifyNodeRemoved(*removedChildren[i]); |
| 590 } | 598 } |
| 591 | 599 |
| 592 dispatchSubtreeModifiedEvent(); | 600 dispatchSubtreeModifiedEvent(); |
| 593 } | 601 } |
| 594 | 602 |
| 595 void ContainerNode::appendChild(PassRefPtrWillBeRawPtr<Node> newChild, Exception
State& exceptionState) | 603 PassRefPtrWillBeRawPtr<Node> ContainerNode::appendChild(PassRefPtrWillBeRawPtr<N
ode> newChild, ExceptionState& exceptionState) |
| 596 { | 604 { |
| 597 RefPtrWillBeRawPtr<ContainerNode> protect(this); | 605 RefPtrWillBeRawPtr<ContainerNode> protect(this); |
| 598 | 606 |
| 599 #if !ENABLE(OILPAN) | 607 #if !ENABLE(OILPAN) |
| 600 // Check that this node is not "floating". | 608 // Check that this node is not "floating". |
| 601 // If it is, it can be deleted as a side effect of sending mutation events. | 609 // If it is, it can be deleted as a side effect of sending mutation events. |
| 602 ASSERT(refCount() || parentOrShadowHostNode()); | 610 ASSERT(refCount() || parentOrShadowHostNode()); |
| 603 #endif | 611 #endif |
| 604 | 612 |
| 605 // Make sure adding the new child is ok | 613 // Make sure adding the new child is ok |
| 606 if (!checkAcceptChild(newChild.get(), 0, exceptionState)) | 614 if (!checkAcceptChild(newChild.get(), 0, exceptionState)) { |
| 607 return; | 615 if (exceptionState.hadException()) |
| 616 return nullptr; |
| 617 return newChild; |
| 618 } |
| 608 ASSERT(newChild); | 619 ASSERT(newChild); |
| 609 | 620 |
| 610 if (newChild == m_lastChild) // nothing to do | 621 if (newChild == m_lastChild) // nothing to do |
| 611 return; | 622 return newChild; |
| 612 | 623 |
| 613 NodeVector targets; | 624 NodeVector targets; |
| 614 collectChildrenAndRemoveFromOldParent(*newChild, targets, exceptionState); | 625 collectChildrenAndRemoveFromOldParent(*newChild, targets, exceptionState); |
| 615 if (exceptionState.hadException()) | 626 if (exceptionState.hadException()) |
| 616 return; | 627 return nullptr; |
| 617 | 628 |
| 618 if (targets.isEmpty()) | 629 if (targets.isEmpty()) |
| 619 return; | 630 return newChild; |
| 620 | 631 |
| 621 // We need this extra check because collectChildrenAndRemoveFromOldParent()
can fire mutation events. | 632 // We need this extra check because collectChildrenAndRemoveFromOldParent()
can fire mutation events. |
| 622 if (!checkAcceptChildGuaranteedNodeTypes(*newChild, exceptionState)) | 633 if (!checkAcceptChildGuaranteedNodeTypes(*newChild, exceptionState)) { |
| 623 return; | 634 if (exceptionState.hadException()) |
| 635 return nullptr; |
| 636 return newChild; |
| 637 } |
| 624 | 638 |
| 625 InspectorInstrumentation::willInsertDOMNode(this); | 639 InspectorInstrumentation::willInsertDOMNode(this); |
| 626 | 640 |
| 627 // Now actually add the child(ren) | 641 // Now actually add the child(ren) |
| 628 ChildListMutationScope mutation(*this); | 642 ChildListMutationScope mutation(*this); |
| 629 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); +
+it) { | 643 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); +
+it) { |
| 630 ASSERT(*it); | 644 ASSERT(*it); |
| 631 Node& child = **it; | 645 Node& child = **it; |
| 632 | 646 |
| 633 // If the child has a parent again, just stop what we're doing, because | 647 // If the child has a parent again, just stop what we're doing, because |
| 634 // that means someone is doing something with DOM mutation -- can't re-p
arent | 648 // that means someone is doing something with DOM mutation -- can't re-p
arent |
| 635 // a child that already has a parent. | 649 // a child that already has a parent. |
| 636 if (child.parentNode()) | 650 if (child.parentNode()) |
| 637 break; | 651 break; |
| 638 | 652 |
| 639 { | 653 { |
| 640 NoEventDispatchAssertion assertNoEventDispatch; | 654 NoEventDispatchAssertion assertNoEventDispatch; |
| 641 ScriptForbiddenScope forbidScript; | 655 ScriptForbiddenScope forbidScript; |
| 642 | 656 |
| 643 treeScope().adoptIfNeeded(child); | 657 treeScope().adoptIfNeeded(child); |
| 644 appendChildCommon(child); | 658 appendChildCommon(child); |
| 645 } | 659 } |
| 646 | 660 |
| 647 updateTreeAfterInsertion(child); | 661 updateTreeAfterInsertion(child); |
| 648 } | 662 } |
| 649 | 663 |
| 650 dispatchSubtreeModifiedEvent(); | 664 dispatchSubtreeModifiedEvent(); |
| 665 return newChild; |
| 651 } | 666 } |
| 652 | 667 |
| 653 void ContainerNode::parserAppendChild(PassRefPtrWillBeRawPtr<Node> newChild) | 668 void ContainerNode::parserAppendChild(PassRefPtrWillBeRawPtr<Node> newChild) |
| 654 { | 669 { |
| 655 ASSERT(newChild); | 670 ASSERT(newChild); |
| 656 ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle re
parenting (and want DOM mutation events). | 671 ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle re
parenting (and want DOM mutation events). |
| 657 ASSERT(!newChild->isDocumentFragment()); | 672 ASSERT(!newChild->isDocumentFragment()); |
| 658 ASSERT(!isHTMLTemplateElement(this)); | 673 ASSERT(!isHTMLTemplateElement(this)); |
| 659 | 674 |
| 660 if (document() != newChild->document()) | 675 if (document() != newChild->document()) |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1294 return true; | 1309 return true; |
| 1295 | 1310 |
| 1296 if (node->isElementNode() && toElement(node)->shadow()) | 1311 if (node->isElementNode() && toElement(node)->shadow()) |
| 1297 return true; | 1312 return true; |
| 1298 | 1313 |
| 1299 return false; | 1314 return false; |
| 1300 } | 1315 } |
| 1301 #endif | 1316 #endif |
| 1302 | 1317 |
| 1303 } // namespace WebCore | 1318 } // namespace WebCore |
| OLD | NEW |