Chromium Code Reviews| 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 Node* ContainerNode::sameNode(Node* node) |
|
Jens Widell
2014/07/10 09:14:54
I don't see why this is necessary, and performance
kangil_
2014/07/11 02:09:26
Done.
| |
| 181 { | |
| 182 for (Node* child = firstChild(); child; child = child->nextSibling()) { | |
| 183 if (child->isSameNode(node)) { | |
| 184 return child; | |
| 185 } | |
| 186 } | |
| 187 return nullptr; | |
| 188 } | |
| 189 | |
| 190 PassRefPtrWillBeRawPtr<Node> ContainerNode::insertBefore(PassRefPtrWillBeRawPtr< Node> newChild, Node* refChild, ExceptionState& exceptionState) | |
|
haraken
2014/07/10 09:16:02
insertBefore is in hot call paths. Calling sameNod
kangil_
2014/07/11 02:09:26
Done.
| |
| 181 { | 191 { |
| 182 #if !ENABLE(OILPAN) | 192 #if !ENABLE(OILPAN) |
| 183 // Check that this node is not "floating". | 193 // Check that this node is not "floating". |
| 184 // If it is, it can be deleted as a side effect of sending mutation events. | 194 // If it is, it can be deleted as a side effect of sending mutation events. |
| 185 ASSERT(refCount() || parentOrShadowHostNode()); | 195 ASSERT(refCount() || parentOrShadowHostNode()); |
| 186 #endif | 196 #endif |
| 187 | 197 |
| 188 RefPtrWillBeRawPtr<Node> protect(this); | 198 RefPtrWillBeRawPtr<Node> protect(this); |
| 189 | 199 |
| 190 // insertBefore(node, 0) is equivalent to appendChild(node) | 200 // insertBefore(node, 0) is equivalent to appendChild(node) |
| 191 if (!refChild) { | 201 if (!refChild) { |
| 192 appendChild(newChild, exceptionState); | 202 appendChild(newChild, exceptionState); |
|
Jens Widell
2014/07/10 09:18:27
We could deal with appendChild(), replaceChild() a
kangil_
2014/07/11 02:09:26
insertBefore() and appendChild() implementations a
| |
| 193 return; | 203 return lastChild(); |
|
Jens Widell
2014/07/10 09:14:54
You should just return 'newChild' everywhere (or n
kangil_
2014/07/11 02:09:26
Done.
| |
| 194 } | 204 } |
| 195 | 205 |
| 196 // Make sure adding the new child is OK. | 206 // Make sure adding the new child is OK. |
| 197 if (!checkAcceptChild(newChild.get(), 0, exceptionState)) | 207 if (!checkAcceptChild(newChild.get(), 0, exceptionState)) |
| 198 return; | 208 return nullptr; |
| 199 ASSERT(newChild); | 209 ASSERT(newChild); |
| 200 | 210 |
| 201 // NotFoundError: Raised if refChild is not a child of this node | 211 // NotFoundError: Raised if refChild is not a child of this node |
| 202 if (refChild->parentNode() != this) { | 212 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."); | 213 exceptionState.throwDOMException(NotFoundError, "The node before which t he new node is to be inserted is not a child of this node."); |
| 204 return; | 214 return nullptr; |
| 205 } | 215 } |
| 206 | 216 |
| 207 if (refChild->previousSibling() == newChild || refChild == newChild) // noth ing to do | 217 // nothing to do |
| 208 return; | 218 if (refChild->previousSibling() == newChild || refChild == newChild) |
| 219 return sameNode(newChild.get()); | |
| 209 | 220 |
| 210 RefPtrWillBeRawPtr<Node> next = refChild; | 221 RefPtrWillBeRawPtr<Node> next = refChild; |
| 211 | 222 |
| 212 NodeVector targets; | 223 NodeVector targets; |
| 213 collectChildrenAndRemoveFromOldParent(*newChild, targets, exceptionState); | 224 collectChildrenAndRemoveFromOldParent(*newChild, targets, exceptionState); |
| 214 if (exceptionState.hadException()) | 225 if (exceptionState.hadException()) |
| 215 return; | 226 return nullptr; |
| 216 if (targets.isEmpty()) | 227 if (targets.isEmpty()) |
| 217 return; | 228 return sameNode(newChild.get()); |
| 218 | 229 |
| 219 // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events. | 230 // We need this extra check because collectChildrenAndRemoveFromOldParent() can fire mutation events. |
| 220 if (!checkAcceptChildGuaranteedNodeTypes(*newChild, exceptionState)) | 231 if (!checkAcceptChildGuaranteedNodeTypes(*newChild, exceptionState)) |
| 221 return; | 232 return nullptr; |
| 222 | 233 |
| 223 InspectorInstrumentation::willInsertDOMNode(this); | 234 InspectorInstrumentation::willInsertDOMNode(this); |
| 224 | 235 |
| 225 ChildListMutationScope mutation(*this); | 236 ChildListMutationScope mutation(*this); |
| 226 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); + +it) { | 237 for (NodeVector::const_iterator it = targets.begin(); it != targets.end(); + +it) { |
| 227 ASSERT(*it); | 238 ASSERT(*it); |
| 228 Node& child = **it; | 239 Node& child = **it; |
| 229 | 240 |
| 230 // Due to arbitrary code running in response to a DOM mutation event it' s | 241 // 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". | 242 // possible that "next" is no longer a child of "this". |
| 232 // It's also possible that "child" has been inserted elsewhere. | 243 // It's also possible that "child" has been inserted elsewhere. |
| 233 // In either of those cases, we'll just stop. | 244 // In either of those cases, we'll just stop. |
| 234 if (next->parentNode() != this) | 245 if (next->parentNode() != this) |
| 235 break; | 246 break; |
| 236 if (child.parentNode()) | 247 if (child.parentNode()) |
| 237 break; | 248 break; |
| 238 | 249 |
| 239 treeScope().adoptIfNeeded(child); | 250 treeScope().adoptIfNeeded(child); |
| 240 | 251 |
| 241 insertBeforeCommon(*next, child); | 252 insertBeforeCommon(*next, child); |
| 242 | 253 |
| 243 updateTreeAfterInsertion(child); | 254 updateTreeAfterInsertion(child); |
| 244 } | 255 } |
| 245 | 256 |
| 246 dispatchSubtreeModifiedEvent(); | 257 dispatchSubtreeModifiedEvent(); |
| 258 | |
| 259 return sameNode(newChild.get()); | |
| 247 } | 260 } |
| 248 | 261 |
| 249 void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild) | 262 void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild) |
| 250 { | 263 { |
| 251 NoEventDispatchAssertion assertNoEventDispatch; | 264 NoEventDispatchAssertion assertNoEventDispatch; |
| 252 ScriptForbiddenScope forbidScript; | 265 ScriptForbiddenScope forbidScript; |
| 253 | 266 |
| 254 ASSERT(!newChild.parentNode()); // Use insertBefore if you need to handle re parenting (and want DOM mutation events). | 267 ASSERT(!newChild.parentNode()); // Use insertBefore if you need to handle re parenting (and want DOM mutation events). |
| 255 ASSERT(!newChild.nextSibling()); | 268 ASSERT(!newChild.nextSibling()); |
| 256 ASSERT(!newChild.previousSibling()); | 269 ASSERT(!newChild.previousSibling()); |
| (...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1294 return true; | 1307 return true; |
| 1295 | 1308 |
| 1296 if (node->isElementNode() && toElement(node)->shadow()) | 1309 if (node->isElementNode() && toElement(node)->shadow()) |
| 1297 return true; | 1310 return true; |
| 1298 | 1311 |
| 1299 return false; | 1312 return false; |
| 1300 } | 1313 } |
| 1301 #endif | 1314 #endif |
| 1302 | 1315 |
| 1303 } // namespace WebCore | 1316 } // namespace WebCore |
| OLD | NEW |