aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-01-04 12:19:00 -0800
committerGitHub <noreply@github.com>2017-01-04 12:19:00 -0800
commit2fe914e2fa68f44db903bc3de55d9823a44cdf0d (patch)
tree267cf07fb71ba6c82bf7c6d62431a8f113a55b38
parent6f9ff7b8bf66cbeb7d539c6728db05f05aa8f85c (diff)
parent9a264c8173501b2cbcc77895a1b66702fb69e5c6 (diff)
downloadservo-2fe914e2fa68f44db903bc3de55d9823a44cdf0d.tar.gz
servo-2fe914e2fa68f44db903bc3de55d9823a44cdf0d.zip
Auto merge of #14845 - jdm:restyle-ood, r=emilio
Avoid restyling elements that aren't in a document - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #14480 - [X] There are tests for these changes <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14845) <!-- Reviewable:end -->
-rw-r--r--components/script/dom/document.rs9
-rw-r--r--components/script/layout_wrapper.rs3
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json24
-rw-r--r--tests/wpt/mozilla/tests/mozilla/restyle-out-of-document-ref.html3
-rw-r--r--tests/wpt/mozilla/tests/mozilla/restyle-out-of-document.html13
5 files changed, 49 insertions, 3 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 83dc980716c..d6d967db6c4 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -66,7 +66,7 @@ use dom::keyboardevent::KeyboardEvent;
use dom::location::Location;
use dom::messageevent::MessageEvent;
use dom::mouseevent::MouseEvent;
-use dom::node::{self, CloneChildrenFlag, Node, NodeDamage, window_from_node};
+use dom::node::{self, CloneChildrenFlag, Node, NodeDamage, window_from_node, IS_IN_DOC, LayoutNodeHelpers};
use dom::nodeiterator::NodeIterator;
use dom::nodelist::NodeList;
use dom::pagetransitionevent::PageTransitionEvent;
@@ -1788,7 +1788,12 @@ impl LayoutDocumentHelpers for LayoutJS<Document> {
#[allow(unrooted_must_root)]
unsafe fn drain_pending_restyles(&self) -> Vec<(LayoutJS<Element>, PendingRestyle)> {
let mut elements = (*self.unsafe_get()).pending_restyles.borrow_mut_for_layout();
- let result = elements.drain().map(|(k, v)| (k.to_layout(), v)).collect();
+ // Elements were in a document when they were adding to this list, but that
+ // may no longer be true when the next layout occurs.
+ let result = elements.drain()
+ .map(|(k, v)| (k.to_layout(), v))
+ .filter(|&(ref k, _)| k.upcast::<Node>().get_flag(IS_IN_DOC))
+ .collect();
result
}
diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs
index 25150d60dfe..5576648b84d 100644
--- a/components/script/layout_wrapper.rs
+++ b/components/script/layout_wrapper.rs
@@ -37,7 +37,7 @@ use dom::bindings::js::LayoutJS;
use dom::characterdata::LayoutCharacterDataHelpers;
use dom::document::{Document, LayoutDocumentHelpers, PendingRestyle};
use dom::element::{Element, LayoutElementHelpers, RawLayoutElementHelpers};
-use dom::node::{CAN_BE_FRAGMENTED, DIRTY_ON_VIEWPORT_SIZE_CHANGE, HAS_DIRTY_DESCENDANTS};
+use dom::node::{CAN_BE_FRAGMENTED, DIRTY_ON_VIEWPORT_SIZE_CHANGE, HAS_DIRTY_DESCENDANTS, IS_IN_DOC};
use dom::node::{LayoutNodeHelpers, Node};
use dom::text::Text;
use gfx_traits::ByteIndex;
@@ -404,6 +404,7 @@ impl<'le> TElement for ServoLayoutElement<'le> {
}
unsafe fn set_dirty_descendants(&self) {
+ debug_assert!(self.as_node().node.get_flag(IS_IN_DOC));
self.as_node().node.set_flag(HAS_DIRTY_DESCENDANTS, true)
}
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index c77dd130e6b..4f7b9c4ec43 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -6438,6 +6438,18 @@
"url": "/_mozilla/mozilla/iframe/resize_after_load.html"
}
],
+ "mozilla/restyle-out-of-document.html": [
+ {
+ "path": "mozilla/restyle-out-of-document.html",
+ "references": [
+ [
+ "/_mozilla/mozilla/restyle-out-of-document-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/mozilla/restyle-out-of-document.html"
+ }
+ ],
"mozilla/scrolling_div_background_borders.html": [
{
"path": "mozilla/scrolling_div_background_borders.html",
@@ -21732,6 +21744,18 @@
"url": "/_mozilla/mozilla/iframe/resize_after_load.html"
}
],
+ "mozilla/restyle-out-of-document.html": [
+ {
+ "path": "mozilla/restyle-out-of-document.html",
+ "references": [
+ [
+ "/_mozilla/mozilla/restyle-out-of-document-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/mozilla/restyle-out-of-document.html"
+ }
+ ],
"mozilla/scrolling_div_background_borders.html": [
{
"path": "mozilla/scrolling_div_background_borders.html",
diff --git a/tests/wpt/mozilla/tests/mozilla/restyle-out-of-document-ref.html b/tests/wpt/mozilla/tests/mozilla/restyle-out-of-document-ref.html
new file mode 100644
index 00000000000..12d09f82161
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/restyle-out-of-document-ref.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<meta charset="utf-8">
+<span>Visible content.</span>
diff --git a/tests/wpt/mozilla/tests/mozilla/restyle-out-of-document.html b/tests/wpt/mozilla/tests/mozilla/restyle-out-of-document.html
new file mode 100644
index 00000000000..cff2590e4eb
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/restyle-out-of-document.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Verify that dirtying an element and removing it from the document before it's restyled doesn't mess up layout</title>
+<link rel='match' href='restyle-out-of-document-ref.html'>
+<div><strong>Removed content.</strong></div>
+<span>Visible content.</span>
+<script>
+ addEventListener('load', function() {
+ var d = document.querySelector('div');
+ d.firstChild.style.display = "none";
+ d.remove();
+ }, true);
+</script>