diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-01-04 12:19:00 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-04 12:19:00 -0800 |
commit | 2fe914e2fa68f44db903bc3de55d9823a44cdf0d (patch) | |
tree | 267cf07fb71ba6c82bf7c6d62431a8f113a55b38 | |
parent | 6f9ff7b8bf66cbeb7d539c6728db05f05aa8f85c (diff) | |
parent | 9a264c8173501b2cbcc77895a1b66702fb69e5c6 (diff) | |
download | servo-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.rs | 9 | ||||
-rw-r--r-- | components/script/layout_wrapper.rs | 3 | ||||
-rw-r--r-- | tests/wpt/mozilla/meta/MANIFEST.json | 24 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/mozilla/restyle-out-of-document-ref.html | 3 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/mozilla/restyle-out-of-document.html | 13 |
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> |