| 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 | 56 |
| 57 namespace blink { | 57 namespace blink { |
| 58 | 58 |
| 59 using namespace HTMLNames; | 59 using namespace HTMLNames; |
| 60 | 60 |
| 61 static void dispatchChildInsertionEvents(Node&); | 61 static void dispatchChildInsertionEvents(Node&); |
| 62 static void dispatchChildRemovalEvents(Node&); | 62 static void dispatchChildRemovalEvents(Node&); |
| 63 | 63 |
| 64 // This dispatches various events; DOM mutation events, blur events, IFRAME | 64 // This dispatches various events; DOM mutation events, blur events, IFRAME |
| 65 // unload events, etc. | 65 // unload events, etc. |
| 66 static void collectChildrenAndRemoveFromOldParent(Node& node, NodeVector& nodes,
ExceptionState& exceptionState) | 66 static inline void collectChildrenAndRemoveFromOldParent(Node& node, NodeVector&
nodes, ExceptionState& exceptionState) |
| 67 { | 67 { |
| 68 if (node.isDocumentFragment()) { | 68 if (node.isDocumentFragment()) { |
| 69 DocumentFragment& fragment = toDocumentFragment(node); | 69 DocumentFragment& fragment = toDocumentFragment(node); |
| 70 getChildNodes(fragment, nodes); | 70 getChildNodes(fragment, nodes); |
| 71 fragment.removeChildren(); | 71 fragment.removeChildren(); |
| 72 return; | 72 return; |
| 73 } | 73 } |
| 74 nodes.append(&node); | 74 nodes.append(&node); |
| 75 if (ContainerNode* oldParent = node.parentNode()) | 75 if (ContainerNode* oldParent = node.parentNode()) |
| 76 oldParent->removeChild(&node, exceptionState); | 76 oldParent->removeChild(&node, exceptionState); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 exceptionState.throwDOMException(HierarchyRequestError, "The new child e
lement contains the parent."); | 151 exceptionState.throwDOMException(HierarchyRequestError, "The new child e
lement contains the parent."); |
| 152 return false; | 152 return false; |
| 153 } | 153 } |
| 154 if (!isChildTypeAllowed(newChild)) { | 154 if (!isChildTypeAllowed(newChild)) { |
| 155 exceptionState.throwDOMException(HierarchyRequestError, "Nodes of type '
" + newChild.nodeName() + "' may not be inserted inside nodes of type '" + nodeN
ame() + "'."); | 155 exceptionState.throwDOMException(HierarchyRequestError, "Nodes of type '
" + newChild.nodeName() + "' may not be inserted inside nodes of type '" + nodeN
ame() + "'."); |
| 156 return false; | 156 return false; |
| 157 } | 157 } |
| 158 return true; | 158 return true; |
| 159 } | 159 } |
| 160 | 160 |
| 161 void ContainerNode::collectChildrenAndRemoveFromOldParentWithCheck(const Node* n
ext, const Node* oldChild, Node& newChild, NodeVector& newChildren, ExceptionSta
te& exceptionState) const | 161 bool ContainerNode::collectChildrenAndRemoveFromOldParentWithCheck(const Node* n
ext, const Node* oldChild, Node& newChild, NodeVector& newChildren, ExceptionSta
te& exceptionState) const |
| 162 { | 162 { |
| 163 collectChildrenAndRemoveFromOldParent(newChild, newChildren, exceptionState)
; | 163 collectChildrenAndRemoveFromOldParent(newChild, newChildren, exceptionState)
; |
| 164 if (exceptionState.hadException()) | 164 if (exceptionState.hadException() || newChildren.isEmpty()) |
| 165 return; | 165 return false; |
| 166 if (newChildren.isEmpty()) | |
| 167 return; | |
| 168 | 166 |
| 169 // We need this extra check because collectChildrenAndRemoveFromOldParent() | 167 // We need this extra check because collectChildrenAndRemoveFromOldParent() |
| 170 // can fire various events. | 168 // can fire various events. |
| 171 for (const auto& child : newChildren) { | 169 for (const auto& child : newChildren) { |
| 172 if (child->parentNode()) { | 170 if (child->parentNode()) { |
| 173 // A new child was added to another parent before adding to this | 171 // A new child was added to another parent before adding to this |
| 174 // node. Firefox and Edge don't throw in this case. | 172 // node. Firefox and Edge don't throw in this case. |
| 175 newChildren.clear(); | 173 return false; |
| 176 return; | |
| 177 } | 174 } |
| 178 if (!checkAcceptChildGuaranteedNodeTypes(*child, oldChild, exceptionStat
e)) | 175 if (!checkAcceptChildGuaranteedNodeTypes(*child, oldChild, exceptionStat
e)) |
| 179 return; | 176 return false; |
| 180 } | 177 } |
| 181 if (next && next->parentNode() != this) { | 178 if (next && next->parentNode() != this) { |
| 182 exceptionState.throwDOMException(NotFoundError, "The node before which t
he new node is to be inserted is not a child of this node."); | 179 exceptionState.throwDOMException(NotFoundError, "The node before which t
he new node is to be inserted is not a child of this node."); |
| 183 return; | 180 return false; |
| 184 } | 181 } |
| 182 return true; |
| 185 } | 183 } |
| 186 | 184 |
| 187 template <typename Functor> | 185 template <typename Functor> |
| 188 void ContainerNode::insertNodeVector(const NodeVector& targets, Node* next, cons
t Functor& mutator) | 186 void ContainerNode::insertNodeVector(const NodeVector& targets, Node* next, cons
t Functor& mutator) |
| 189 { | 187 { |
| 190 InspectorInstrumentation::willInsertDOMNode(this); | 188 InspectorInstrumentation::willInsertDOMNode(this); |
| 191 NodeVector postInsertionNotificationTargets; | 189 NodeVector postInsertionNotificationTargets; |
| 192 { | 190 { |
| 193 EventDispatchForbiddenScope assertNoEventDispatch; | 191 EventDispatchForbiddenScope assertNoEventDispatch; |
| 194 ScriptForbiddenScope forbidScript; | 192 ScriptForbiddenScope forbidScript; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 inline void operator()(ContainerNode& container, Node& child, Node*) const | 231 inline void operator()(ContainerNode& container, Node& child, Node*) const |
| 234 { | 232 { |
| 235 container.treeScope().adoptIfNeeded(child); | 233 container.treeScope().adoptIfNeeded(child); |
| 236 container.appendChildCommon(child); | 234 container.appendChildCommon(child); |
| 237 } | 235 } |
| 238 }; | 236 }; |
| 239 | 237 |
| 240 Node* ContainerNode::insertBefore(Node* newChild, Node* refChild, ExceptionState
& exceptionState) | 238 Node* ContainerNode::insertBefore(Node* newChild, Node* refChild, ExceptionState
& exceptionState) |
| 241 { | 239 { |
| 242 // insertBefore(node, 0) is equivalent to appendChild(node) | 240 // insertBefore(node, 0) is equivalent to appendChild(node) |
| 243 if (!refChild) { | 241 if (!refChild) |
| 244 return appendChild(newChild, exceptionState); | 242 return appendChild(newChild, exceptionState); |
| 245 } | |
| 246 | 243 |
| 247 // Make sure adding the new child is OK. | 244 // Make sure adding the new child is OK. |
| 248 if (!checkAcceptChild(newChild, 0, exceptionState)) { | 245 if (!checkAcceptChild(newChild, 0, exceptionState)) |
| 249 if (exceptionState.hadException()) | |
| 250 return nullptr; | |
| 251 return newChild; | 246 return newChild; |
| 252 } | |
| 253 DCHECK(newChild); | 247 DCHECK(newChild); |
| 254 | 248 |
| 255 // NotFoundError: Raised if refChild is not a child of this node | 249 // NotFoundError: Raised if refChild is not a child of this node |
| 256 if (refChild->parentNode() != this) { | 250 if (refChild->parentNode() != this) { |
| 257 exceptionState.throwDOMException(NotFoundError, "The node before which t
he new node is to be inserted is not a child of this node."); | 251 exceptionState.throwDOMException(NotFoundError, "The node before which t
he new node is to be inserted is not a child of this node."); |
| 258 return nullptr; | 252 return nullptr; |
| 259 } | 253 } |
| 260 | 254 |
| 261 // Nothing to do. | 255 // Nothing to do. |
| 262 if (refChild->previousSibling() == newChild || refChild == newChild) | 256 if (refChild->previousSibling() == newChild || refChild == newChild) |
| 263 return newChild; | 257 return newChild; |
| 264 | 258 |
| 265 Node* next = refChild; | |
| 266 | |
| 267 NodeVector targets; | 259 NodeVector targets; |
| 268 collectChildrenAndRemoveFromOldParentWithCheck(next, nullptr, *newChild, tar
gets, exceptionState); | 260 if (!collectChildrenAndRemoveFromOldParentWithCheck(refChild, nullptr, *newC
hild, targets, exceptionState)) |
| 269 if (exceptionState.hadException()) | |
| 270 return nullptr; | |
| 271 if (targets.isEmpty()) | |
| 272 return newChild; | 261 return newChild; |
| 273 | 262 |
| 274 ChildListMutationScope mutation(*this); | 263 ChildListMutationScope mutation(*this); |
| 275 insertNodeVector(targets, next, AdoptAndInsertBefore()); | 264 insertNodeVector(targets, refChild, AdoptAndInsertBefore()); |
| 276 return newChild; | 265 return newChild; |
| 277 } | 266 } |
| 278 | 267 |
| 279 void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild) | 268 void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild) |
| 280 { | 269 { |
| 281 EventDispatchForbiddenScope assertNoEventDispatch; | 270 #if DCHECK_IS_ON() |
| 282 ScriptForbiddenScope forbidScript; | 271 DCHECK(EventDispatchForbiddenScope::isEventDispatchForbidden()); |
| 283 | 272 #endif |
| 273 DCHECK(ScriptForbiddenScope::isScriptForbidden()); |
| 284 DCHECK(!newChild.parentNode()); // Use insertBefore if you need to handle re
parenting (and want DOM mutation events). | 274 DCHECK(!newChild.parentNode()); // Use insertBefore if you need to handle re
parenting (and want DOM mutation events). |
| 285 DCHECK(!newChild.nextSibling()); | 275 DCHECK(!newChild.nextSibling()); |
| 286 DCHECK(!newChild.previousSibling()); | 276 DCHECK(!newChild.previousSibling()); |
| 287 DCHECK(!newChild.isShadowRoot()); | 277 DCHECK(!newChild.isShadowRoot()); |
| 288 | 278 |
| 289 Node* prev = nextChild.previousSibling(); | 279 Node* prev = nextChild.previousSibling(); |
| 290 DCHECK_NE(m_lastChild, prev); | 280 DCHECK_NE(m_lastChild, prev); |
| 291 nextChild.setPreviousSibling(&newChild); | 281 nextChild.setPreviousSibling(&newChild); |
| 292 if (prev) { | 282 if (prev) { |
| 293 DCHECK_NE(firstChild(), nextChild); | 283 DCHECK_NE(firstChild(), nextChild); |
| 294 DCHECK_EQ(prev->nextSibling(), nextChild); | 284 DCHECK_EQ(prev->nextSibling(), nextChild); |
| 295 prev->setNextSibling(&newChild); | 285 prev->setNextSibling(&newChild); |
| 296 } else { | 286 } else { |
| 297 DCHECK(firstChild() == nextChild); | 287 DCHECK(firstChild() == nextChild); |
| 298 m_firstChild = &newChild; | 288 m_firstChild = &newChild; |
| 299 } | 289 } |
| 300 newChild.setParentOrShadowHostNode(this); | 290 newChild.setParentOrShadowHostNode(this); |
| 301 newChild.setPreviousSibling(prev); | 291 newChild.setPreviousSibling(prev); |
| 302 newChild.setNextSibling(&nextChild); | 292 newChild.setNextSibling(&nextChild); |
| 303 } | 293 } |
| 304 | 294 |
| 305 void ContainerNode::appendChildCommon(Node& child) | 295 void ContainerNode::appendChildCommon(Node& child) |
| 306 { | 296 { |
| 297 #if DCHECK_IS_ON() |
| 298 DCHECK(EventDispatchForbiddenScope::isEventDispatchForbidden()); |
| 299 #endif |
| 300 DCHECK(ScriptForbiddenScope::isScriptForbidden()); |
| 301 |
| 307 child.setParentOrShadowHostNode(this); | 302 child.setParentOrShadowHostNode(this); |
| 308 | |
| 309 if (m_lastChild) { | 303 if (m_lastChild) { |
| 310 child.setPreviousSibling(m_lastChild); | 304 child.setPreviousSibling(m_lastChild); |
| 311 m_lastChild->setNextSibling(&child); | 305 m_lastChild->setNextSibling(&child); |
| 312 } else { | 306 } else { |
| 313 setFirstChild(&child); | 307 setFirstChild(&child); |
| 314 } | 308 } |
| 315 | |
| 316 setLastChild(&child); | 309 setLastChild(&child); |
| 317 } | 310 } |
| 318 | 311 |
| 319 bool ContainerNode::checkParserAcceptChild(const Node& newChild) const | 312 bool ContainerNode::checkParserAcceptChild(const Node& newChild) const |
| 320 { | 313 { |
| 321 if (!isDocumentNode()) | 314 if (!isDocumentNode()) |
| 322 return true; | 315 return true; |
| 323 // TODO(esprehn): Are there other conditions where the parser can create | 316 // TODO(esprehn): Are there other conditions where the parser can create |
| 324 // invalid trees? | 317 // invalid trees? |
| 325 return toDocument(*this).canAcceptChild(newChild, nullptr, IGNORE_EXCEPTION)
; | 318 return toDocument(*this).canAcceptChild(newChild, nullptr, IGNORE_EXCEPTION)
; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 347 if (nextChild.parentNode() != this) | 340 if (nextChild.parentNode() != this) |
| 348 return; | 341 return; |
| 349 | 342 |
| 350 if (document() != newChild->document()) | 343 if (document() != newChild->document()) |
| 351 document().adoptNode(newChild, ASSERT_NO_EXCEPTION); | 344 document().adoptNode(newChild, ASSERT_NO_EXCEPTION); |
| 352 | 345 |
| 353 { | 346 { |
| 354 EventDispatchForbiddenScope assertNoEventDispatch; | 347 EventDispatchForbiddenScope assertNoEventDispatch; |
| 355 ScriptForbiddenScope forbidScript; | 348 ScriptForbiddenScope forbidScript; |
| 356 | 349 |
| 357 treeScope().adoptIfNeeded(*newChild); | 350 AdoptAndInsertBefore()(*this, *newChild, &nextChild); |
| 358 insertBeforeCommon(nextChild, *newChild); | |
| 359 DCHECK_EQ(newChild->connectedSubframeCount(), 0u); | 351 DCHECK_EQ(newChild->connectedSubframeCount(), 0u); |
| 360 ChildListMutationScope(*this).childAdded(*newChild); | 352 ChildListMutationScope(*this).childAdded(*newChild); |
| 361 } | 353 } |
| 362 | 354 |
| 363 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); | 355 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); |
| 364 } | 356 } |
| 365 | 357 |
| 366 Node* ContainerNode::replaceChild(Node* newChild, Node* oldChild, ExceptionState
& exceptionState) | 358 Node* ContainerNode::replaceChild(Node* newChild, Node* oldChild, ExceptionState
& exceptionState) |
| 367 { | 359 { |
| 368 if (oldChild == newChild) // Nothing to do. | 360 if (oldChild == newChild) // Nothing to do. |
| 369 return oldChild; | 361 return oldChild; |
| 370 | 362 |
| 371 if (!oldChild) { | 363 if (!oldChild) { |
| 372 exceptionState.throwDOMException(NotFoundError, "The node to be replaced
is null."); | 364 exceptionState.throwDOMException(NotFoundError, "The node to be replaced
is null."); |
| 373 return nullptr; | 365 return nullptr; |
| 374 } | 366 } |
| 375 | 367 |
| 376 Node* child = oldChild; | |
| 377 | |
| 378 // Make sure replacing the old child with the new is OK. | 368 // Make sure replacing the old child with the new is OK. |
| 379 if (!checkAcceptChild(newChild, child, exceptionState)) { | 369 if (!checkAcceptChild(newChild, oldChild, exceptionState)) |
| 380 if (exceptionState.hadException()) | 370 return oldChild; |
| 381 return nullptr; | |
| 382 return child; | |
| 383 } | |
| 384 | 371 |
| 385 // NotFoundError: Raised if oldChild is not a child of this node. | 372 // NotFoundError: Raised if oldChild is not a child of this node. |
| 386 if (child->parentNode() != this) { | 373 if (oldChild->parentNode() != this) { |
| 387 exceptionState.throwDOMException(NotFoundError, "The node to be replaced
is not a child of this node."); | 374 exceptionState.throwDOMException(NotFoundError, "The node to be replaced
is not a child of this node."); |
| 388 return nullptr; | 375 return nullptr; |
| 389 } | 376 } |
| 390 | 377 |
| 391 ChildListMutationScope mutation(*this); | 378 ChildListMutationScope mutation(*this); |
| 392 | 379 Node* next = oldChild->nextSibling(); |
| 393 Node* next = child->nextSibling(); | |
| 394 | 380 |
| 395 // Remove the node we're replacing. | 381 // Remove the node we're replacing. |
| 396 removeChild(child, exceptionState); | 382 removeChild(oldChild, exceptionState); |
| 397 if (exceptionState.hadException()) | 383 if (exceptionState.hadException()) |
| 398 return nullptr; | 384 return nullptr; |
| 399 | 385 |
| 400 if (next && (next->previousSibling() == newChild || next == newChild)) // no
thing to do | 386 if (next && (next->previousSibling() == newChild || next == newChild)) // no
thing to do |
| 401 return child; | 387 return oldChild; |
| 402 | 388 |
| 403 // Does this one more time because removeChild() fires a MutationEvent. | 389 // Does this one more time because removeChild() fires a MutationEvent. |
| 404 if (!checkAcceptChild(newChild, child, exceptionState)) { | 390 if (!checkAcceptChild(newChild, oldChild, exceptionState)) |
| 405 if (exceptionState.hadException()) | 391 return oldChild; |
| 406 return nullptr; | |
| 407 return child; | |
| 408 } | |
| 409 | 392 |
| 410 NodeVector targets; | 393 NodeVector targets; |
| 411 collectChildrenAndRemoveFromOldParentWithCheck(next, child, *newChild, targe
ts, exceptionState); | 394 if (!collectChildrenAndRemoveFromOldParentWithCheck(next, oldChild, *newChil
d, targets, exceptionState)) |
| 412 if (exceptionState.hadException()) | 395 return oldChild; |
| 413 return nullptr; | |
| 414 if (targets.isEmpty()) | |
| 415 return child; | |
| 416 | 396 |
| 417 if (next) | 397 if (next) |
| 418 insertNodeVector(targets, next, AdoptAndInsertBefore()); | 398 insertNodeVector(targets, next, AdoptAndInsertBefore()); |
| 419 else | 399 else |
| 420 insertNodeVector(targets, nullptr, AdoptAndAppendChild()); | 400 insertNodeVector(targets, nullptr, AdoptAndAppendChild()); |
| 421 return child; | 401 return oldChild; |
| 422 } | 402 } |
| 423 | 403 |
| 424 void ContainerNode::willRemoveChild(Node& child) | 404 void ContainerNode::willRemoveChild(Node& child) |
| 425 { | 405 { |
| 426 DCHECK_EQ(child.parentNode(), this); | 406 DCHECK_EQ(child.parentNode(), this); |
| 427 ChildListMutationScope(*this).willRemoveChild(child); | 407 ChildListMutationScope(*this).willRemoveChild(child); |
| 428 child.notifyMutationObserversNodeWillDetach(); | 408 child.notifyMutationObserversNodeWillDetach(); |
| 429 dispatchChildRemovalEvents(child); | 409 dispatchChildRemovalEvents(child); |
| 430 ChildFrameDisconnector(child).disconnect(); | 410 ChildFrameDisconnector(child).disconnect(); |
| 431 if (document() != child.document()) { | 411 if (document() != child.document()) { |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 612 ChildrenChange change = {AllChildrenRemoved, nullptr, nullptr, nullptr,
ChildrenChangeSourceAPI}; | 592 ChildrenChange change = {AllChildrenRemoved, nullptr, nullptr, nullptr,
ChildrenChangeSourceAPI}; |
| 613 childrenChanged(change); | 593 childrenChanged(change); |
| 614 } | 594 } |
| 615 | 595 |
| 616 if (action == DispatchSubtreeModifiedEvent) | 596 if (action == DispatchSubtreeModifiedEvent) |
| 617 dispatchSubtreeModifiedEvent(); | 597 dispatchSubtreeModifiedEvent(); |
| 618 } | 598 } |
| 619 | 599 |
| 620 Node* ContainerNode::appendChild(Node* newChild, ExceptionState& exceptionState) | 600 Node* ContainerNode::appendChild(Node* newChild, ExceptionState& exceptionState) |
| 621 { | 601 { |
| 622 | |
| 623 // Make sure adding the new child is ok | 602 // Make sure adding the new child is ok |
| 624 if (!checkAcceptChild(newChild, 0, exceptionState)) { | 603 if (!checkAcceptChild(newChild, 0, exceptionState)) |
| 625 if (exceptionState.hadException()) | |
| 626 return nullptr; | |
| 627 return newChild; | 604 return newChild; |
| 628 } | |
| 629 DCHECK(newChild); | 605 DCHECK(newChild); |
| 630 | 606 |
| 631 if (newChild == m_lastChild) // nothing to do | 607 if (newChild == m_lastChild) // nothing to do |
| 632 return newChild; | 608 return newChild; |
| 633 | 609 |
| 634 NodeVector targets; | 610 NodeVector targets; |
| 635 collectChildrenAndRemoveFromOldParentWithCheck(nullptr, nullptr, *newChild,
targets, exceptionState); | 611 if (!collectChildrenAndRemoveFromOldParentWithCheck(nullptr, nullptr, *newCh
ild, targets, exceptionState)) |
| 636 if (exceptionState.hadException()) | |
| 637 return nullptr; | |
| 638 if (targets.isEmpty()) | |
| 639 return newChild; | 612 return newChild; |
| 640 | 613 |
| 641 ChildListMutationScope mutation(*this); | 614 ChildListMutationScope mutation(*this); |
| 642 insertNodeVector(targets, nullptr, AdoptAndAppendChild()); | 615 insertNodeVector(targets, nullptr, AdoptAndAppendChild()); |
| 643 return newChild; | 616 return newChild; |
| 644 } | 617 } |
| 645 | 618 |
| 646 void ContainerNode::parserAppendChild(Node* newChild) | 619 void ContainerNode::parserAppendChild(Node* newChild) |
| 647 { | 620 { |
| 648 DCHECK(newChild); | 621 DCHECK(newChild); |
| 649 DCHECK(!newChild->isDocumentFragment()); | 622 DCHECK(!newChild->isDocumentFragment()); |
| 650 DCHECK(!isHTMLTemplateElement(this)); | 623 DCHECK(!isHTMLTemplateElement(this)); |
| 651 | 624 |
| 652 if (!checkParserAcceptChild(*newChild)) | 625 if (!checkParserAcceptChild(*newChild)) |
| 653 return; | 626 return; |
| 654 | 627 |
| 655 // FIXME: parserRemoveChild can run script which could then insert the | 628 // FIXME: parserRemoveChild can run script which could then insert the |
| 656 // newChild back into the page. Loop until the child is actually removed. | 629 // newChild back into the page. Loop until the child is actually removed. |
| 657 // See: fast/parser/execute-script-during-adoption-agency-removal.html | 630 // See: fast/parser/execute-script-during-adoption-agency-removal.html |
| 658 while (ContainerNode* parent = newChild->parentNode()) | 631 while (ContainerNode* parent = newChild->parentNode()) |
| 659 parent->parserRemoveChild(*newChild); | 632 parent->parserRemoveChild(*newChild); |
| 660 | 633 |
| 661 if (document() != newChild->document()) | 634 if (document() != newChild->document()) |
| 662 document().adoptNode(newChild, ASSERT_NO_EXCEPTION); | 635 document().adoptNode(newChild, ASSERT_NO_EXCEPTION); |
| 663 | 636 |
| 664 { | 637 { |
| 665 EventDispatchForbiddenScope assertNoEventDispatch; | 638 EventDispatchForbiddenScope assertNoEventDispatch; |
| 666 ScriptForbiddenScope forbidScript; | 639 ScriptForbiddenScope forbidScript; |
| 667 | 640 |
| 668 treeScope().adoptIfNeeded(*newChild); | 641 AdoptAndAppendChild()(*this, *newChild, nullptr); |
| 669 appendChildCommon(*newChild); | |
| 670 DCHECK_EQ(newChild->connectedSubframeCount(), 0u); | 642 DCHECK_EQ(newChild->connectedSubframeCount(), 0u); |
| 671 ChildListMutationScope(*this).childAdded(*newChild); | 643 ChildListMutationScope(*this).childAdded(*newChild); |
| 672 } | 644 } |
| 673 | 645 |
| 674 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); | 646 notifyNodeInserted(*newChild, ChildrenChangeSourceParser); |
| 675 } | 647 } |
| 676 | 648 |
| 677 DISABLE_CFI_PERF | 649 DISABLE_CFI_PERF |
| 678 void ContainerNode::notifyNodeInserted(Node& root, ChildrenChangeSource source) | 650 void ContainerNode::notifyNodeInserted(Node& root, ChildrenChangeSource source) |
| 679 { | 651 { |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1092 } | 1064 } |
| 1093 | 1065 |
| 1094 HTMLCollection* ContainerNode::children() | 1066 HTMLCollection* ContainerNode::children() |
| 1095 { | 1067 { |
| 1096 return ensureCachedCollection<HTMLCollection>(NodeChildren); | 1068 return ensureCachedCollection<HTMLCollection>(NodeChildren); |
| 1097 } | 1069 } |
| 1098 | 1070 |
| 1099 unsigned ContainerNode::countChildren() const | 1071 unsigned ContainerNode::countChildren() const |
| 1100 { | 1072 { |
| 1101 unsigned count = 0; | 1073 unsigned count = 0; |
| 1102 Node* n; | 1074 for (Node* node = firstChild(); node; node = node->nextSibling()) |
| 1103 for (n = firstChild(); n; n = n->nextSibling()) | |
| 1104 count++; | 1075 count++; |
| 1105 return count; | 1076 return count; |
| 1106 } | 1077 } |
| 1107 | 1078 |
| 1108 Element* ContainerNode::querySelector(const AtomicString& selectors, ExceptionSt
ate& exceptionState) | 1079 Element* ContainerNode::querySelector(const AtomicString& selectors, ExceptionSt
ate& exceptionState) |
| 1109 { | 1080 { |
| 1110 if (selectors.isEmpty()) { | 1081 if (selectors.isEmpty()) { |
| 1111 exceptionState.throwDOMException(SyntaxError, "The provided selector is
empty."); | 1082 exceptionState.throwDOMException(SyntaxError, "The provided selector is
empty."); |
| 1112 return nullptr; | 1083 return nullptr; |
| 1113 } | 1084 } |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 return true; | 1352 return true; |
| 1382 | 1353 |
| 1383 if (node->isElementNode() && toElement(node)->shadow()) | 1354 if (node->isElementNode() && toElement(node)->shadow()) |
| 1384 return true; | 1355 return true; |
| 1385 | 1356 |
| 1386 return false; | 1357 return false; |
| 1387 } | 1358 } |
| 1388 #endif | 1359 #endif |
| 1389 | 1360 |
| 1390 } // namespace blink | 1361 } // namespace blink |
| OLD | NEW |