| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 OwnPtr<Digest> oldInfo = createDigest(m_document.documentElement(), 0); | 106 OwnPtr<Digest> oldInfo = createDigest(m_document.documentElement(), 0); |
| 107 OwnPtr<Digest> newInfo = createDigest(newDocument->documentElement(), &m_unu
sedNodesMap); | 107 OwnPtr<Digest> newInfo = createDigest(newDocument->documentElement(), &m_unu
sedNodesMap); |
| 108 | 108 |
| 109 if (!innerPatchNode(oldInfo.get(), newInfo.get(), IGNORE_EXCEPTION)) { | 109 if (!innerPatchNode(oldInfo.get(), newInfo.get(), IGNORE_EXCEPTION)) { |
| 110 // Fall back to rewrite. | 110 // Fall back to rewrite. |
| 111 m_document.write(markup); | 111 m_document.write(markup); |
| 112 m_document.close(); | 112 m_document.close(); |
| 113 } | 113 } |
| 114 } | 114 } |
| 115 | 115 |
| 116 Node* DOMPatchSupport::patchNode(Node* node, const String& markup, ExceptionStat
e& es) | 116 Node* DOMPatchSupport::patchNode(Node* node, const String& markup, ExceptionStat
e& exceptionState) |
| 117 { | 117 { |
| 118 // Don't parse <html> as a fragment. | 118 // Don't parse <html> as a fragment. |
| 119 if (node->isDocumentNode() || (node->parentNode() && node->parentNode()->isD
ocumentNode())) { | 119 if (node->isDocumentNode() || (node->parentNode() && node->parentNode()->isD
ocumentNode())) { |
| 120 patchDocument(markup); | 120 patchDocument(markup); |
| 121 return 0; | 121 return 0; |
| 122 } | 122 } |
| 123 | 123 |
| 124 Node* previousSibling = node->previousSibling(); | 124 Node* previousSibling = node->previousSibling(); |
| 125 // FIXME: This code should use one of createFragment* in markup.h | 125 // FIXME: This code should use one of createFragment* in markup.h |
| 126 RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document); | 126 RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 143 for (Node* child = fragment->firstChild(); child; child = child->nextSibling
()) { | 143 for (Node* child = fragment->firstChild(); child; child = child->nextSibling
()) { |
| 144 if (child->hasTagName(headTag) && !child->firstChild() && markupCopy.fin
d("</head>") == kNotFound) | 144 if (child->hasTagName(headTag) && !child->firstChild() && markupCopy.fin
d("</head>") == kNotFound) |
| 145 continue; // HTML5 parser inserts empty <head> tag whenever it parse
s <body> | 145 continue; // HTML5 parser inserts empty <head> tag whenever it parse
s <body> |
| 146 if (child->hasTagName(bodyTag) && !child->firstChild() && markupCopy.fin
d("</body>") == kNotFound) | 146 if (child->hasTagName(bodyTag) && !child->firstChild() && markupCopy.fin
d("</body>") == kNotFound) |
| 147 continue; // HTML5 parser inserts empty <body> tag whenever it parse
s </head> | 147 continue; // HTML5 parser inserts empty <body> tag whenever it parse
s </head> |
| 148 newList.append(createDigest(child, &m_unusedNodesMap)); | 148 newList.append(createDigest(child, &m_unusedNodesMap)); |
| 149 } | 149 } |
| 150 for (Node* child = node->nextSibling(); child; child = child->nextSibling()) | 150 for (Node* child = node->nextSibling(); child; child = child->nextSibling()) |
| 151 newList.append(createDigest(child, 0)); | 151 newList.append(createDigest(child, 0)); |
| 152 | 152 |
| 153 if (!innerPatchChildren(parentNode, oldList, newList, es)) { | 153 if (!innerPatchChildren(parentNode, oldList, newList, exceptionState)) { |
| 154 // Fall back to total replace. | 154 // Fall back to total replace. |
| 155 if (!m_domEditor->replaceChild(parentNode, fragment.release(), node, es)
) | 155 if (!m_domEditor->replaceChild(parentNode, fragment.release(), node, exc
eptionState)) |
| 156 return 0; | 156 return 0; |
| 157 } | 157 } |
| 158 return previousSibling ? previousSibling->nextSibling() : parentNode->firstC
hild(); | 158 return previousSibling ? previousSibling->nextSibling() : parentNode->firstC
hild(); |
| 159 } | 159 } |
| 160 | 160 |
| 161 bool DOMPatchSupport::innerPatchNode(Digest* oldDigest, Digest* newDigest, Excep
tionState& es) | 161 bool DOMPatchSupport::innerPatchNode(Digest* oldDigest, Digest* newDigest, Excep
tionState& exceptionState) |
| 162 { | 162 { |
| 163 if (oldDigest->m_sha1 == newDigest->m_sha1) | 163 if (oldDigest->m_sha1 == newDigest->m_sha1) |
| 164 return true; | 164 return true; |
| 165 | 165 |
| 166 Node* oldNode = oldDigest->m_node; | 166 Node* oldNode = oldDigest->m_node; |
| 167 Node* newNode = newDigest->m_node; | 167 Node* newNode = newDigest->m_node; |
| 168 | 168 |
| 169 if (newNode->nodeType() != oldNode->nodeType() || newNode->nodeName() != old
Node->nodeName()) | 169 if (newNode->nodeType() != oldNode->nodeType() || newNode->nodeName() != old
Node->nodeName()) |
| 170 return m_domEditor->replaceChild(oldNode->parentNode(), newNode, oldNode
, es); | 170 return m_domEditor->replaceChild(oldNode->parentNode(), newNode, oldNode
, exceptionState); |
| 171 | 171 |
| 172 if (oldNode->nodeValue() != newNode->nodeValue()) { | 172 if (oldNode->nodeValue() != newNode->nodeValue()) { |
| 173 if (!m_domEditor->setNodeValue(oldNode, newNode->nodeValue(), es)) | 173 if (!m_domEditor->setNodeValue(oldNode, newNode->nodeValue(), exceptionS
tate)) |
| 174 return false; | 174 return false; |
| 175 } | 175 } |
| 176 | 176 |
| 177 if (oldNode->nodeType() != Node::ELEMENT_NODE) | 177 if (oldNode->nodeType() != Node::ELEMENT_NODE) |
| 178 return true; | 178 return true; |
| 179 | 179 |
| 180 // Patch attributes | 180 // Patch attributes |
| 181 Element* oldElement = toElement(oldNode); | 181 Element* oldElement = toElement(oldNode); |
| 182 Element* newElement = toElement(newNode); | 182 Element* newElement = toElement(newNode); |
| 183 if (oldDigest->m_attrsSHA1 != newDigest->m_attrsSHA1) { | 183 if (oldDigest->m_attrsSHA1 != newDigest->m_attrsSHA1) { |
| 184 // FIXME: Create a function in Element for removing all properties. Take
in account whether did/willModifyAttribute are important. | 184 // FIXME: Create a function in Element for removing all properties. Take
in account whether did/willModifyAttribute are important. |
| 185 if (oldElement->hasAttributesWithoutUpdate()) { | 185 if (oldElement->hasAttributesWithoutUpdate()) { |
| 186 while (oldElement->attributeCount()) { | 186 while (oldElement->attributeCount()) { |
| 187 const Attribute* attribute = oldElement->attributeItem(0); | 187 const Attribute* attribute = oldElement->attributeItem(0); |
| 188 if (!m_domEditor->removeAttribute(oldElement, attribute->localNa
me(), es)) | 188 if (!m_domEditor->removeAttribute(oldElement, attribute->localNa
me(), exceptionState)) |
| 189 return false; | 189 return false; |
| 190 } | 190 } |
| 191 } | 191 } |
| 192 | 192 |
| 193 // FIXME: Create a function in Element for copying properties. cloneData
FromElement() is close but not enough for this case. | 193 // FIXME: Create a function in Element for copying properties. cloneData
FromElement() is close but not enough for this case. |
| 194 if (newElement->hasAttributesWithoutUpdate()) { | 194 if (newElement->hasAttributesWithoutUpdate()) { |
| 195 size_t numAttrs = newElement->attributeCount(); | 195 size_t numAttrs = newElement->attributeCount(); |
| 196 for (size_t i = 0; i < numAttrs; ++i) { | 196 for (size_t i = 0; i < numAttrs; ++i) { |
| 197 const Attribute* attribute = newElement->attributeItem(i); | 197 const Attribute* attribute = newElement->attributeItem(i); |
| 198 if (!m_domEditor->setAttribute(oldElement, attribute->name().loc
alName(), attribute->value(), es)) | 198 if (!m_domEditor->setAttribute(oldElement, attribute->name().loc
alName(), attribute->value(), exceptionState)) |
| 199 return false; | 199 return false; |
| 200 } | 200 } |
| 201 } | 201 } |
| 202 } | 202 } |
| 203 | 203 |
| 204 bool result = innerPatchChildren(oldElement, oldDigest->m_children, newDiges
t->m_children, es); | 204 bool result = innerPatchChildren(oldElement, oldDigest->m_children, newDiges
t->m_children, exceptionState); |
| 205 m_unusedNodesMap.remove(newDigest->m_sha1); | 205 m_unusedNodesMap.remove(newDigest->m_sha1); |
| 206 return result; | 206 return result; |
| 207 } | 207 } |
| 208 | 208 |
| 209 pair<DOMPatchSupport::ResultMap, DOMPatchSupport::ResultMap> | 209 pair<DOMPatchSupport::ResultMap, DOMPatchSupport::ResultMap> |
| 210 DOMPatchSupport::diff(const Vector<OwnPtr<Digest> >& oldList, const Vector<OwnPt
r<Digest> >& newList) | 210 DOMPatchSupport::diff(const Vector<OwnPtr<Digest> >& oldList, const Vector<OwnPt
r<Digest> >& newList) |
| 211 { | 211 { |
| 212 ResultMap newMap(newList.size()); | 212 ResultMap newMap(newList.size()); |
| 213 ResultMap oldMap(oldList.size()); | 213 ResultMap oldMap(oldList.size()); |
| 214 | 214 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 } | 287 } |
| 288 | 288 |
| 289 #ifdef DEBUG_DOM_PATCH_SUPPORT | 289 #ifdef DEBUG_DOM_PATCH_SUPPORT |
| 290 dumpMap(oldMap, "OLD"); | 290 dumpMap(oldMap, "OLD"); |
| 291 dumpMap(newMap, "NEW"); | 291 dumpMap(newMap, "NEW"); |
| 292 #endif | 292 #endif |
| 293 | 293 |
| 294 return make_pair(oldMap, newMap); | 294 return make_pair(oldMap, newMap); |
| 295 } | 295 } |
| 296 | 296 |
| 297 bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector
<OwnPtr<Digest> >& oldList, const Vector<OwnPtr<Digest> >& newList, ExceptionSta
te& es) | 297 bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector
<OwnPtr<Digest> >& oldList, const Vector<OwnPtr<Digest> >& newList, ExceptionSta
te& exceptionState) |
| 298 { | 298 { |
| 299 pair<ResultMap, ResultMap> resultMaps = diff(oldList, newList); | 299 pair<ResultMap, ResultMap> resultMaps = diff(oldList, newList); |
| 300 ResultMap& oldMap = resultMaps.first; | 300 ResultMap& oldMap = resultMaps.first; |
| 301 ResultMap& newMap = resultMaps.second; | 301 ResultMap& newMap = resultMaps.second; |
| 302 | 302 |
| 303 Digest* oldHead = 0; | 303 Digest* oldHead = 0; |
| 304 Digest* oldBody = 0; | 304 Digest* oldBody = 0; |
| 305 | 305 |
| 306 // 1. First strip everything except for the nodes that retain. Collect pendi
ng merges. | 306 // 1. First strip everything except for the nodes that retain. Collect pendi
ng merges. |
| 307 HashMap<Digest*, Digest*> merges; | 307 HashMap<Digest*, Digest*> merges; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 325 continue; | 325 continue; |
| 326 } | 326 } |
| 327 | 327 |
| 328 // Check if this change is between stable nodes. If it is, consider it a
s "modified". | 328 // Check if this change is between stable nodes. If it is, consider it a
s "modified". |
| 329 if (!m_unusedNodesMap.contains(oldList[i]->m_sha1) && (!i || oldMap[i -
1].first) && (i == oldMap.size() - 1 || oldMap[i + 1].first)) { | 329 if (!m_unusedNodesMap.contains(oldList[i]->m_sha1) && (!i || oldMap[i -
1].first) && (i == oldMap.size() - 1 || oldMap[i + 1].first)) { |
| 330 size_t anchorCandidate = i ? oldMap[i - 1].second + 1 : 0; | 330 size_t anchorCandidate = i ? oldMap[i - 1].second + 1 : 0; |
| 331 size_t anchorAfter = (i == oldMap.size() - 1) ? anchorCandidate + 1
: oldMap[i + 1].second; | 331 size_t anchorAfter = (i == oldMap.size() - 1) ? anchorCandidate + 1
: oldMap[i + 1].second; |
| 332 if (anchorAfter - anchorCandidate == 1 && anchorCandidate < newList.
size()) | 332 if (anchorAfter - anchorCandidate == 1 && anchorCandidate < newList.
size()) |
| 333 merges.set(newList[anchorCandidate].get(), oldList[i].get()); | 333 merges.set(newList[anchorCandidate].get(), oldList[i].get()); |
| 334 else { | 334 else { |
| 335 if (!removeChildAndMoveToNew(oldList[i].get(), es)) | 335 if (!removeChildAndMoveToNew(oldList[i].get(), exceptionState)) |
| 336 return false; | 336 return false; |
| 337 } | 337 } |
| 338 } else { | 338 } else { |
| 339 if (!removeChildAndMoveToNew(oldList[i].get(), es)) | 339 if (!removeChildAndMoveToNew(oldList[i].get(), exceptionState)) |
| 340 return false; | 340 return false; |
| 341 } | 341 } |
| 342 } | 342 } |
| 343 | 343 |
| 344 // Mark retained nodes as used, do not reuse node more than once. | 344 // Mark retained nodes as used, do not reuse node more than once. |
| 345 HashSet<size_t, WTF::IntHash<size_t>, WTF::UnsignedWithZeroKeyHashTraits<siz
e_t> > usedOldOrdinals; | 345 HashSet<size_t, WTF::IntHash<size_t>, WTF::UnsignedWithZeroKeyHashTraits<siz
e_t> > usedOldOrdinals; |
| 346 for (size_t i = 0; i < newList.size(); ++i) { | 346 for (size_t i = 0; i < newList.size(); ++i) { |
| 347 if (!newMap[i].first) | 347 if (!newMap[i].first) |
| 348 continue; | 348 continue; |
| 349 size_t oldOrdinal = newMap[i].second; | 349 size_t oldOrdinal = newMap[i].second; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 362 for (size_t i = 0; i < newList.size(); ++i) { | 362 for (size_t i = 0; i < newList.size(); ++i) { |
| 363 if (oldHead && newList[i]->m_node->hasTagName(headTag)) | 363 if (oldHead && newList[i]->m_node->hasTagName(headTag)) |
| 364 merges.set(newList[i].get(), oldHead); | 364 merges.set(newList[i].get(), oldHead); |
| 365 if (oldBody && newList[i]->m_node->hasTagName(bodyTag)) | 365 if (oldBody && newList[i]->m_node->hasTagName(bodyTag)) |
| 366 merges.set(newList[i].get(), oldBody); | 366 merges.set(newList[i].get(), oldBody); |
| 367 } | 367 } |
| 368 } | 368 } |
| 369 | 369 |
| 370 // 2. Patch nodes marked for merge. | 370 // 2. Patch nodes marked for merge. |
| 371 for (HashMap<Digest*, Digest*>::iterator it = merges.begin(); it != merges.e
nd(); ++it) { | 371 for (HashMap<Digest*, Digest*>::iterator it = merges.begin(); it != merges.e
nd(); ++it) { |
| 372 if (!innerPatchNode(it->value, it->key, es)) | 372 if (!innerPatchNode(it->value, it->key, exceptionState)) |
| 373 return false; | 373 return false; |
| 374 } | 374 } |
| 375 | 375 |
| 376 // 3. Insert missing nodes. | 376 // 3. Insert missing nodes. |
| 377 for (size_t i = 0; i < newMap.size(); ++i) { | 377 for (size_t i = 0; i < newMap.size(); ++i) { |
| 378 if (newMap[i].first || merges.contains(newList[i].get())) | 378 if (newMap[i].first || merges.contains(newList[i].get())) |
| 379 continue; | 379 continue; |
| 380 if (!insertBeforeAndMarkAsUsed(parentNode, newList[i].get(), parentNode-
>childNode(i), es)) | 380 if (!insertBeforeAndMarkAsUsed(parentNode, newList[i].get(), parentNode-
>childNode(i), exceptionState)) |
| 381 return false; | 381 return false; |
| 382 } | 382 } |
| 383 | 383 |
| 384 // 4. Then put all nodes that retained into their slots (sort by new index). | 384 // 4. Then put all nodes that retained into their slots (sort by new index). |
| 385 for (size_t i = 0; i < oldMap.size(); ++i) { | 385 for (size_t i = 0; i < oldMap.size(); ++i) { |
| 386 if (!oldMap[i].first) | 386 if (!oldMap[i].first) |
| 387 continue; | 387 continue; |
| 388 RefPtr<Node> node = oldMap[i].first->m_node; | 388 RefPtr<Node> node = oldMap[i].first->m_node; |
| 389 Node* anchorNode = parentNode->childNode(oldMap[i].second); | 389 Node* anchorNode = parentNode->childNode(oldMap[i].second); |
| 390 if (node.get() == anchorNode) | 390 if (node.get() == anchorNode) |
| 391 continue; | 391 continue; |
| 392 if (node->hasTagName(bodyTag) || node->hasTagName(headTag)) | 392 if (node->hasTagName(bodyTag) || node->hasTagName(headTag)) |
| 393 continue; // Never move head or body, move the rest of the nodes aro
und them. | 393 continue; // Never move head or body, move the rest of the nodes aro
und them. |
| 394 | 394 |
| 395 if (!m_domEditor->insertBefore(parentNode, node.release(), anchorNode, e
s)) | 395 if (!m_domEditor->insertBefore(parentNode, node.release(), anchorNode, e
xceptionState)) |
| 396 return false; | 396 return false; |
| 397 } | 397 } |
| 398 return true; | 398 return true; |
| 399 } | 399 } |
| 400 | 400 |
| 401 static void addStringToSHA1(SHA1& sha1, const String& string) | 401 static void addStringToSHA1(SHA1& sha1, const String& string) |
| 402 { | 402 { |
| 403 CString cString = string.utf8(); | 403 CString cString = string.utf8(); |
| 404 sha1.addBytes(reinterpret_cast<const uint8_t*>(cString.data()), cString.leng
th()); | 404 sha1.addBytes(reinterpret_cast<const uint8_t*>(cString.data()), cString.leng
th()); |
| 405 } | 405 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 } | 441 } |
| 442 | 442 |
| 443 Vector<uint8_t, 20> hash; | 443 Vector<uint8_t, 20> hash; |
| 444 sha1.computeHash(hash); | 444 sha1.computeHash(hash); |
| 445 digest->m_sha1 = base64Encode(reinterpret_cast<const char*>(hash.data()), 10
); | 445 digest->m_sha1 = base64Encode(reinterpret_cast<const char*>(hash.data()), 10
); |
| 446 if (unusedNodesMap) | 446 if (unusedNodesMap) |
| 447 unusedNodesMap->add(digest->m_sha1, digest); | 447 unusedNodesMap->add(digest->m_sha1, digest); |
| 448 return adoptPtr(digest); | 448 return adoptPtr(digest); |
| 449 } | 449 } |
| 450 | 450 |
| 451 bool DOMPatchSupport::insertBeforeAndMarkAsUsed(ContainerNode* parentNode, Diges
t* digest, Node* anchor, ExceptionState& es) | 451 bool DOMPatchSupport::insertBeforeAndMarkAsUsed(ContainerNode* parentNode, Diges
t* digest, Node* anchor, ExceptionState& exceptionState) |
| 452 { | 452 { |
| 453 bool result = m_domEditor->insertBefore(parentNode, digest->m_node, anchor,
es); | 453 bool result = m_domEditor->insertBefore(parentNode, digest->m_node, anchor,
exceptionState); |
| 454 markNodeAsUsed(digest); | 454 markNodeAsUsed(digest); |
| 455 return result; | 455 return result; |
| 456 } | 456 } |
| 457 | 457 |
| 458 bool DOMPatchSupport::removeChildAndMoveToNew(Digest* oldDigest, ExceptionState&
es) | 458 bool DOMPatchSupport::removeChildAndMoveToNew(Digest* oldDigest, ExceptionState&
exceptionState) |
| 459 { | 459 { |
| 460 RefPtr<Node> oldNode = oldDigest->m_node; | 460 RefPtr<Node> oldNode = oldDigest->m_node; |
| 461 if (!m_domEditor->removeChild(oldNode->parentNode(), oldNode.get(), es)) | 461 if (!m_domEditor->removeChild(oldNode->parentNode(), oldNode.get(), exceptio
nState)) |
| 462 return false; | 462 return false; |
| 463 | 463 |
| 464 // Diff works within levels. In order not to lose the node identity when use
r | 464 // Diff works within levels. In order not to lose the node identity when use
r |
| 465 // prepends his HTML with "<div>" (i.e. all nodes are shifted to the next ne
sted level), | 465 // prepends his HTML with "<div>" (i.e. all nodes are shifted to the next ne
sted level), |
| 466 // prior to dropping the original node on the floor, check whether new DOM h
as a digest | 466 // prior to dropping the original node on the floor, check whether new DOM h
as a digest |
| 467 // with matching sha1. If it does, replace it with the original DOM chunk. C
hances are | 467 // with matching sha1. If it does, replace it with the original DOM chunk. C
hances are |
| 468 // high that it will get merged back into the original DOM during the furthe
r patching. | 468 // high that it will get merged back into the original DOM during the furthe
r patching. |
| 469 UnusedNodesMap::iterator it = m_unusedNodesMap.find(oldDigest->m_sha1); | 469 UnusedNodesMap::iterator it = m_unusedNodesMap.find(oldDigest->m_sha1); |
| 470 if (it != m_unusedNodesMap.end()) { | 470 if (it != m_unusedNodesMap.end()) { |
| 471 Digest* newDigest = it->value; | 471 Digest* newDigest = it->value; |
| 472 Node* newNode = newDigest->m_node; | 472 Node* newNode = newDigest->m_node; |
| 473 if (!m_domEditor->replaceChild(newNode->parentNode(), oldNode, newNode,
es)) | 473 if (!m_domEditor->replaceChild(newNode->parentNode(), oldNode, newNode,
exceptionState)) |
| 474 return false; | 474 return false; |
| 475 newDigest->m_node = oldNode.get(); | 475 newDigest->m_node = oldNode.get(); |
| 476 markNodeAsUsed(newDigest); | 476 markNodeAsUsed(newDigest); |
| 477 return true; | 477 return true; |
| 478 } | 478 } |
| 479 | 479 |
| 480 for (size_t i = 0; i < oldDigest->m_children.size(); ++i) { | 480 for (size_t i = 0; i < oldDigest->m_children.size(); ++i) { |
| 481 if (!removeChildAndMoveToNew(oldDigest->m_children[i].get(), es)) | 481 if (!removeChildAndMoveToNew(oldDigest->m_children[i].get(), exceptionSt
ate)) |
| 482 return false; | 482 return false; |
| 483 } | 483 } |
| 484 return true; | 484 return true; |
| 485 } | 485 } |
| 486 | 486 |
| 487 void DOMPatchSupport::markNodeAsUsed(Digest* digest) | 487 void DOMPatchSupport::markNodeAsUsed(Digest* digest) |
| 488 { | 488 { |
| 489 Deque<Digest*> queue; | 489 Deque<Digest*> queue; |
| 490 queue.append(digest); | 490 queue.append(digest); |
| 491 while (!queue.isEmpty()) { | 491 while (!queue.isEmpty()) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 507 void DOMPatchSupport::dumpMap(const ResultMap& map, const String& name) | 507 void DOMPatchSupport::dumpMap(const ResultMap& map, const String& name) |
| 508 { | 508 { |
| 509 fprintf(stderr, "\n\n"); | 509 fprintf(stderr, "\n\n"); |
| 510 for (size_t i = 0; i < map.size(); ++i) | 510 for (size_t i = 0; i < map.size(); ++i) |
| 511 fprintf(stderr, "%s[%lu]: %s (%p) - [%lu]\n", name.utf8().data(), i, map
[i].first ? nodeName(map[i].first->m_node).utf8().data() : "", map[i].first, map
[i].second); | 511 fprintf(stderr, "%s[%lu]: %s (%p) - [%lu]\n", name.utf8().data(), i, map
[i].first ? nodeName(map[i].first->m_node).utf8().data() : "", map[i].first, map
[i].second); |
| 512 } | 512 } |
| 513 #endif | 513 #endif |
| 514 | 514 |
| 515 } // namespace WebCore | 515 } // namespace WebCore |
| 516 | 516 |
| OLD | NEW |