diff options
author | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2019-02-21 12:34:59 +0100 |
---|---|---|
committer | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2019-04-26 11:31:17 +0200 |
commit | 2674a3e71748eb0ef6db371fc2f1401a951b94c4 (patch) | |
tree | 3106346788c2fce743ab8a9f0a8674d0b44aea7e | |
parent | a841c713d653f57256e5b795197920c7ee6834e9 (diff) | |
download | servo-2674a3e71748eb0ef6db371fc2f1401a951b94c4.tar.gz servo-2674a3e71748eb0ef6db371fc2f1401a951b94c4.zip |
Flush shadow roots stylesheets only if they changed
-rw-r--r-- | components/layout_thread/dom_wrapper.rs | 17 | ||||
-rw-r--r-- | components/layout_thread/lib.rs | 12 | ||||
-rw-r--r-- | components/script/dom/document.rs | 31 | ||||
-rw-r--r-- | components/script/dom/shadowroot.rs | 1 |
4 files changed, 54 insertions, 7 deletions
diff --git a/components/layout_thread/dom_wrapper.rs b/components/layout_thread/dom_wrapper.rs index 7ea68e6e3a2..72cbdf04701 100644 --- a/components/layout_thread/dom_wrapper.rs +++ b/components/layout_thread/dom_wrapper.rs @@ -437,6 +437,23 @@ impl<'ld> ServoLayoutDocument<'ld> { } } + pub fn flush_shadow_roots_stylesheets( + &self, + device: &Device, + quirks_mode: QuirksMode, + guard: &SharedRwLockReadGuard, + ) { + unsafe { + if !self.document.shadow_roots_styles_changed() { + return; + } + self.document.flush_shadow_roots_stylesheets(); + for shadow_root in self.shadow_roots() { + shadow_root.flush_stylesheets(device, quirks_mode, guard); + } + } + } + pub fn from_layout_js(doc: LayoutDom<Document>) -> ServoLayoutDocument<'ld> { ServoLayoutDocument { document: doc, diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 3ed2624d2d3..b44bbb54b96 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -1352,13 +1352,11 @@ impl LayoutThread { ); // Flush shadow roots stylesheets if dirty. - for shadow_root in document.shadow_roots() { - shadow_root.flush_stylesheets( - &self.stylist.device(), - document.quirks_mode(), - guards.author.clone(), - ); - } + document.flush_shadow_roots_stylesheets( + &self.stylist.device(), + document.quirks_mode(), + guards.author.clone(), + ); let restyles = document.drain_pending_restyles(); debug!("Draining restyles: {}", restyles.len()); diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 0d25b535593..3c02d76e7d0 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -379,6 +379,8 @@ pub struct Document { completely_loaded: Cell<bool>, /// List of shadow roots bound to the document tree. shadow_roots: DomRefCell<Vec<Dom<ShadowRoot>>>, + /// Whether any of the shadow roots need the stylesheets flushed. + shadow_roots_styles_changed: Cell<bool>, } #[derive(JSTraceable, MallocSizeOf)] @@ -2431,6 +2433,8 @@ pub trait LayoutDocumentHelpers { unsafe fn quirks_mode(&self) -> QuirksMode; unsafe fn style_shared_lock(&self) -> &StyleSharedRwLock; unsafe fn shadow_roots(&self) -> Vec<LayoutDom<ShadowRoot>>; + unsafe fn shadow_roots_styles_changed(&self) -> bool; + unsafe fn flush_shadow_roots_stylesheets(&self); } #[allow(unsafe_code)] @@ -2485,6 +2489,16 @@ impl LayoutDocumentHelpers for LayoutDom<Document> { .map(|sr| sr.to_layout()) .collect() } + + #[inline] + unsafe fn shadow_roots_styles_changed(&self) -> bool { + (*self.unsafe_get()).shadow_roots_styles_changed() + } + + #[inline] + unsafe fn flush_shadow_roots_stylesheets(&self) { + (*self.unsafe_get()).flush_shadow_roots_stylesheets() + } } // https://html.spec.whatwg.org/multipage/#is-a-registrable-domain-suffix-of-or-is-equal-to @@ -2694,6 +2708,7 @@ impl Document { script_and_layout_blockers: Cell::new(0), delayed_tasks: Default::default(), shadow_roots: DomRefCell::new(Vec::new()), + shadow_roots_styles_changed: Cell::new(false), } } @@ -3151,6 +3166,7 @@ impl Document { self.shadow_roots .borrow_mut() .push(Dom::from_ref(shadow_root)); + self.invalidate_shadow_roots_stylesheets(); } pub fn unregister_shadow_root(&self, shadow_root: &ShadowRoot) { @@ -3160,6 +3176,21 @@ impl Document { shadow_roots.remove(index); } } + + pub fn invalidate_shadow_roots_stylesheets(&self) { + self.shadow_roots_styles_changed.set(true); + } + + pub fn shadow_roots_styles_changed(&self) -> bool { + self.shadow_roots_styles_changed.get() + } + + pub fn flush_shadow_roots_stylesheets(&self) { + if !self.shadow_roots_styles_changed.get() { + return; + } + self.shadow_roots_styles_changed.set(false); + } } impl Element { diff --git a/components/script/dom/shadowroot.rs b/components/script/dom/shadowroot.rs index b562172dd05..dd47187836e 100644 --- a/components/script/dom/shadowroot.rs +++ b/components/script/dom/shadowroot.rs @@ -75,6 +75,7 @@ impl ShadowRoot { } pub fn invalidate_stylesheets(&self) { + self.document.invalidate_shadow_roots_stylesheets(); self.author_styles.borrow_mut().stylesheets.force_dirty(); // Mark the host element dirty so a reflow will be performed. self.host |