Commit 93ca9118 authored by Fergal Daly's avatar Fergal Daly Committed by Commit Bot

DOM: Handle cross-document node moves correctly.

The current NeedsRecheck checks whether the node's document version has increased
by more than 1 but it does not notice when the node has moved to a new document.

Since we cannot capture the original version of the final document for
comparison, we have to assume that when the document changes, a recheck is
needed.

Bug: 837377
Change-Id: If83c4eaeb6b737768cc45c2f3a2241b03d3d2e75
Reviewed-on: https://chromium-review.googlesource.com/1109667Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Commit-Queue: Fergal Daly <fergal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569988}
parent e1f51a2b
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<span id="e1"></span>
<span id="e2">
<span id="e3"></span>
</span>
<script>
test(() => {
// This triggers a DCHECK when appendChild runs during another
// appendChild.
var e1 = document.getElementById("e1");
var e2 = document.getElementById("e2");
var e3 = document.getElementById("e3");
var doc1 = document.implementation.createDocument("", "", null);
doc1.appendChild(e2);
e2.addEventListener(
"DOMSubtreeModified", () => {e1.appendChild(e3)}, {once: true});
e2.appendChild(e3);
}, "appendChild between docs should not crash");
</script>
...@@ -82,13 +82,17 @@ class DOMTreeMutationDetector { ...@@ -82,13 +82,17 @@ class DOMTreeMutationDetector {
public: public:
DOMTreeMutationDetector(const Node& node, const Node& parent) DOMTreeMutationDetector(const Node& node, const Node& parent)
: node_document_(node.GetDocument()), : node_(&node),
node_document_(node.GetDocument()),
parent_document_(parent.GetDocument()), parent_document_(parent.GetDocument()),
parent_(parent), parent_(parent),
original_node_document_version_(node_document_->DomTreeVersion()), original_node_document_version_(node_document_->DomTreeVersion()),
original_parent_document_version_(parent_document_->DomTreeVersion()) {} original_parent_document_version_(parent_document_->DomTreeVersion()) {}
bool NeedsRecheck() { bool NeedsRecheck() {
if (node_document_ != node_->GetDocument()) {
return false;
}
if (node_document_->DomTreeVersion() > original_node_document_version_ + 1) if (node_document_->DomTreeVersion() > original_node_document_version_ + 1)
return false; return false;
if (parent_document_ != parent_->GetDocument()) if (parent_document_ != parent_->GetDocument())
...@@ -100,6 +104,7 @@ class DOMTreeMutationDetector { ...@@ -100,6 +104,7 @@ class DOMTreeMutationDetector {
} }
private: private:
const Member<const Node> node_;
const Member<Document> node_document_; const Member<Document> node_document_;
const Member<Document> parent_document_; const Member<Document> parent_document_;
const Member<const Node> parent_; const Member<const Node> parent_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment