diff options
author | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2019-03-01 18:10:18 +0100 |
---|---|---|
committer | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2019-04-26 11:31:18 +0200 |
commit | 2350f0e3d1202d4c0cbb5189b9ab668b402eb179 (patch) | |
tree | 0ed7cb7f33c4d59577f561d5ca11e1db07b949d0 | |
parent | 8b353ee3ced609d2de688a93dcfd825c3cef3eae (diff) | |
download | servo-2350f0e3d1202d4c0cbb5189b9ab668b402eb179.tar.gz servo-2350f0e3d1202d4c0cbb5189b9ab668b402eb179.zip |
Make StyleSheetListOwner an enum instead of a trait object
-rw-r--r-- | components/script/dom/document.rs | 132 | ||||
-rw-r--r-- | components/script/dom/htmllinkelement.rs | 1 | ||||
-rw-r--r-- | components/script/dom/htmlmetaelement.rs | 1 | ||||
-rw-r--r-- | components/script/dom/htmlstyleelement.rs | 1 | ||||
-rw-r--r-- | components/script/dom/node.rs | 7 | ||||
-rw-r--r-- | components/script/dom/shadowroot.rs | 102 | ||||
-rw-r--r-- | components/script/dom/stylesheetlist.rs | 67 |
7 files changed, 177 insertions, 134 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index bef1edc68fd..4ec2e67521c 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -3191,6 +3191,65 @@ impl Document { } self.shadow_roots_styles_changed.set(false); } + + pub fn stylesheet_count(&self) -> usize { + self.stylesheets.borrow().len() + } + + pub fn stylesheet_at(&self, index: usize) -> Option<DomRoot<CSSStyleSheet>> { + let stylesheets = self.stylesheets.borrow(); + + stylesheets + .get(Origin::Author, index) + .and_then(|s| s.owner.upcast::<Node>().get_cssom_stylesheet()) + } + + /// Add a stylesheet owned by `owner` to the list of document sheets, in the + /// correct tree position. + #[allow(unrooted_must_root)] // Owner needs to be rooted already necessarily. + pub fn add_stylesheet(&self, owner: &Element, sheet: Arc<Stylesheet>) { + let stylesheets = &mut *self.stylesheets.borrow_mut(); + let insertion_point = stylesheets + .iter() + .map(|(sheet, _origin)| sheet) + .find(|sheet_in_doc| { + owner + .upcast::<Node>() + .is_before(sheet_in_doc.owner.upcast()) + }) + .cloned(); + + self.window + .layout_chan() + .send(Msg::AddStylesheet( + sheet.clone(), + insertion_point.as_ref().map(|s| s.sheet.clone()), + )) + .unwrap(); + + DocumentOrShadowRoot::add_stylesheet( + owner, + StylesheetSet::Document(stylesheets), + sheet, + insertion_point, + self.style_shared_lock(), + ); + } + + /// Remove a stylesheet owned by `owner` from the list of document sheets. + #[allow(unrooted_must_root)] // Owner needs to be rooted already necessarily. + pub fn remove_stylesheet(&self, owner: &Element, s: &Arc<Stylesheet>) { + self.window + .layout_chan() + .send(Msg::RemoveStylesheet(s.clone())) + .unwrap(); + + DocumentOrShadowRoot::remove_stylesheet( + owner, + s, + StylesheetSet::Document(&mut *self.stylesheets.borrow_mut()), + ) + } } impl Element { @@ -3222,8 +3281,12 @@ impl ProfilerMetadataFactory for Document { impl DocumentMethods for Document { // https://drafts.csswg.org/cssom/#dom-document-stylesheets fn StyleSheets(&self) -> DomRoot<StyleSheetList> { - self.stylesheet_list - .or_init(|| StyleSheetList::new(&self.window, Box::new(Dom::from_ref(self)))) + self.stylesheet_list.or_init(|| { + StyleSheetList::new( + &self.window, + StyleSheetListOwner::Document(Dom::from_ref(self)), + ) + }) } // https://dom.spec.whatwg.org/#dom-document-implementation @@ -4606,68 +4669,3 @@ impl PendingScript { .map(|result| (DomRoot::from_ref(&*self.element), result)) } } - -impl StyleSheetListOwner for Dom<Document> { - fn stylesheet_count(&self) -> usize { - self.stylesheets.borrow().len() - } - - fn stylesheet_at(&self, index: usize) -> Option<DomRoot<CSSStyleSheet>> { - let stylesheets = self.stylesheets.borrow(); - - stylesheets - .get(Origin::Author, index) - .and_then(|s| s.owner.upcast::<Node>().get_cssom_stylesheet()) - } - - /// Add a stylesheet owned by `owner` to the list of document sheets, in the - /// correct tree position. - #[allow(unrooted_must_root)] // Owner needs to be rooted already necessarily. - fn add_stylesheet(&self, owner: &Element, sheet: Arc<Stylesheet>) { - let stylesheets = &mut *self.stylesheets.borrow_mut(); - let insertion_point = stylesheets - .iter() - .map(|(sheet, _origin)| sheet) - .find(|sheet_in_doc| { - owner - .upcast::<Node>() - .is_before(sheet_in_doc.owner.upcast()) - }) - .cloned(); - - self.window - .layout_chan() - .send(Msg::AddStylesheet( - sheet.clone(), - insertion_point.as_ref().map(|s| s.sheet.clone()), - )) - .unwrap(); - - DocumentOrShadowRoot::add_stylesheet( - owner, - StylesheetSet::Document(stylesheets), - sheet, - insertion_point, - self.style_shared_lock(), - ); - } - - /// Remove a stylesheet owned by `owner` from the list of document sheets. - #[allow(unrooted_must_root)] // Owner needs to be rooted already necessarily. - fn remove_stylesheet(&self, owner: &Element, s: &Arc<Stylesheet>) { - self.window - .layout_chan() - .send(Msg::RemoveStylesheet(s.clone())) - .unwrap(); - - DocumentOrShadowRoot::remove_stylesheet( - owner, - s, - StylesheetSet::Document(&mut *self.stylesheets.borrow_mut()), - ) - } - - fn invalidate_stylesheets(&self) { - Document::invalidate_stylesheets(self); - } -} diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 9e102795b2c..d47d9343e53 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -109,6 +109,7 @@ impl HTMLLinkElement { // FIXME(emilio): These methods are duplicated with // HTMLStyleElement::set_stylesheet. + #[allow(unrooted_must_root)] pub fn set_stylesheet(&self, s: Arc<Stylesheet>) { let stylesheets_owner = stylesheets_owner_from_node(self); if let Some(ref s) = *self.stylesheet.borrow() { diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index 0c8794711f1..ffaf30e89f7 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -99,6 +99,7 @@ impl HTMLMetaElement { } } + #[allow(unrooted_must_root)] fn apply_viewport(&self) { if !pref!(layout.viewport.enabled) { return; diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index 763afcf1bdb..4c2d934a892 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -138,6 +138,7 @@ impl HTMLStyleElement { } // FIXME(emilio): This is duplicated with HTMLLinkElement::set_stylesheet. + #[allow(unrooted_must_root)] pub fn set_stylesheet(&self, s: Arc<Stylesheet>) { let stylesheets_owner = stylesheets_owner_from_node(self); if let Some(ref s) = *self.stylesheet.borrow() { diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 9a683f00698..04843e502c4 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -2802,13 +2802,14 @@ pub fn shadow_root_from_node<T: DerivedFrom<Node> + DomObject>( derived.upcast().owner_shadow_root() } +#[allow(unrooted_must_root)] pub fn stylesheets_owner_from_node<T: DerivedFrom<Node> + DomObject>( derived: &T, -) -> Box<StyleSheetListOwner> { +) -> StyleSheetListOwner { if let Some(shadow_root) = shadow_root_from_node(derived) { - Box::new(Dom::from_ref(&*shadow_root)) + StyleSheetListOwner::ShadowRoot(Dom::from_ref(&*shadow_root)) } else { - Box::new(Dom::from_ref(&*document_from_node(derived))) + StyleSheetListOwner::Document(Dom::from_ref(&*document_from_node(derived))) } } diff --git a/components/script/dom/shadowroot.rs b/components/script/dom/shadowroot.rs index 5233e7b4143..fb38c5531c6 100644 --- a/components/script/dom/shadowroot.rs +++ b/components/script/dom/shadowroot.rs @@ -75,6 +75,50 @@ impl ShadowRoot { None } + pub fn stylesheet_count(&self) -> usize { + self.author_styles.borrow().stylesheets.len() + } + + pub fn stylesheet_at(&self, index: usize) -> Option<DomRoot<CSSStyleSheet>> { + let stylesheets = &self.author_styles.borrow().stylesheets; + + stylesheets + .get(index) + .and_then(|s| s.owner.upcast::<Node>().get_cssom_stylesheet()) + } + + /// Add a stylesheet owned by `owner` to the list of shadow root sheets, in the + /// correct tree position. + #[allow(unrooted_must_root)] // Owner needs to be rooted already necessarily. + pub fn add_stylesheet(&self, owner: &Element, sheet: Arc<Stylesheet>) { + let stylesheets = &mut self.author_styles.borrow_mut().stylesheets; + let insertion_point = stylesheets + .iter() + .find(|sheet_in_shadow| { + owner + .upcast::<Node>() + .is_before(sheet_in_shadow.owner.upcast()) + }) + .cloned(); + DocumentOrShadowRoot::add_stylesheet( + owner, + StylesheetSet::Author(stylesheets), + sheet, + insertion_point, + self.document.style_shared_lock(), + ); + } + + /// Remove a stylesheet owned by `owner` from the list of shadow root sheets. + #[allow(unrooted_must_root)] // Owner needs to be rooted already necessarily. + pub fn remove_stylesheet(&self, owner: &Element, s: &Arc<Stylesheet>) { + DocumentOrShadowRoot::remove_stylesheet( + owner, + s, + StylesheetSet::Author(&mut self.author_styles.borrow_mut().stylesheets), + ) + } + pub fn invalidate_stylesheets(&self) { self.document.invalidate_shadow_roots_stylesheets(); self.author_styles.borrow_mut().stylesheets.force_dirty(); @@ -145,8 +189,12 @@ impl ShadowRootMethods for ShadowRoot { // https://drafts.csswg.org/cssom/#dom-document-stylesheets fn StyleSheets(&self) -> DomRoot<StyleSheetList> { - self.stylesheet_list - .or_init(|| StyleSheetList::new(&self.window, Box::new(Dom::from_ref(self)))) + self.stylesheet_list.or_init(|| { + StyleSheetList::new( + &self.window, + StyleSheetListOwner::ShadowRoot(Dom::from_ref(self)), + ) + }) } } @@ -193,53 +241,3 @@ impl LayoutShadowRootHelpers for LayoutDom<ShadowRoot> { } } } - -impl StyleSheetListOwner for Dom<ShadowRoot> { - fn stylesheet_count(&self) -> usize { - self.author_styles.borrow().stylesheets.len() - } - - fn stylesheet_at(&self, index: usize) -> Option<DomRoot<CSSStyleSheet>> { - let stylesheets = &self.author_styles.borrow().stylesheets; - - stylesheets - .get(index) - .and_then(|s| s.owner.upcast::<Node>().get_cssom_stylesheet()) - } - - /// Add a stylesheet owned by `owner` to the list of shadow root sheets, in the - /// correct tree position. - #[allow(unrooted_must_root)] // Owner needs to be rooted already necessarily. - fn add_stylesheet(&self, owner: &Element, sheet: Arc<Stylesheet>) { - let stylesheets = &mut self.author_styles.borrow_mut().stylesheets; - let insertion_point = stylesheets - .iter() - .find(|sheet_in_shadow| { - owner - .upcast::<Node>() - .is_before(sheet_in_shadow.owner.upcast()) - }) - .cloned(); - DocumentOrShadowRoot::add_stylesheet( - owner, - StylesheetSet::Author(stylesheets), - sheet, - insertion_point, - self.document.style_shared_lock(), - ); - } - - /// Remove a stylesheet owned by `owner` from the list of shadow root sheets. - #[allow(unrooted_must_root)] // Owner needs to be rooted already necessarily. - fn remove_stylesheet(&self, owner: &Element, s: &Arc<Stylesheet>) { - DocumentOrShadowRoot::remove_stylesheet( - owner, - s, - StylesheetSet::Author(&mut self.author_styles.borrow_mut().stylesheets), - ) - } - - fn invalidate_stylesheets(&self) { - ShadowRoot::invalidate_stylesheets(self); - } -} diff --git a/components/script/dom/stylesheetlist.rs b/components/script/dom/stylesheetlist.rs index 0b10680f52a..236f1c9cd9a 100644 --- a/components/script/dom/stylesheetlist.rs +++ b/components/script/dom/stylesheetlist.rs @@ -5,33 +5,76 @@ use crate::dom::bindings::codegen::Bindings::StyleSheetListBinding; use crate::dom::bindings::codegen::Bindings::StyleSheetListBinding::StyleSheetListMethods; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::trace::JSTraceable; +use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::cssstylesheet::CSSStyleSheet; +use crate::dom::document::Document; use crate::dom::element::Element; +use crate::dom::shadowroot::ShadowRoot; use crate::dom::stylesheet::StyleSheet; use crate::dom::window::Window; use dom_struct::dom_struct; use servo_arc::Arc; use style::stylesheets::Stylesheet; -pub trait StyleSheetListOwner: JSTraceable { - fn stylesheet_count(&self) -> usize; - fn stylesheet_at(&self, index: usize) -> Option<DomRoot<CSSStyleSheet>>; - fn add_stylesheet(&self, owner: &Element, sheet: Arc<Stylesheet>); - fn remove_stylesheet(&self, owner: &Element, s: &Arc<Stylesheet>); - fn invalidate_stylesheets(&self); +#[must_root] +#[derive(JSTraceable, MallocSizeOf)] +pub enum StyleSheetListOwner { + Document(Dom<Document>), + ShadowRoot(Dom<ShadowRoot>), +} + +impl StyleSheetListOwner { + pub fn stylesheet_count(&self) -> usize { + match *self { + StyleSheetListOwner::Document(ref doc) => doc.stylesheet_count(), + StyleSheetListOwner::ShadowRoot(ref shadow_root) => shadow_root.stylesheet_count(), + } + } + + pub fn stylesheet_at(&self, index: usize) -> Option<DomRoot<CSSStyleSheet>> { + match *self { + StyleSheetListOwner::Document(ref doc) => doc.stylesheet_at(index), + StyleSheetListOwner::ShadowRoot(ref shadow_root) => shadow_root.stylesheet_at(index), + } + } + + pub fn add_stylesheet(&self, owner: &Element, sheet: Arc<Stylesheet>) { + match *self { + StyleSheetListOwner::Document(ref doc) => doc.add_stylesheet(owner, sheet), + StyleSheetListOwner::ShadowRoot(ref shadow_root) => { + shadow_root.add_stylesheet(owner, sheet) + }, + } + } + + pub fn remove_stylesheet(&self, owner: &Element, s: &Arc<Stylesheet>) { + match *self { + StyleSheetListOwner::Document(ref doc) => doc.remove_stylesheet(owner, s), + StyleSheetListOwner::ShadowRoot(ref shadow_root) => { + shadow_root.remove_stylesheet(owner, s) + }, + } + } + + pub fn invalidate_stylesheets(&self) { + match *self { + StyleSheetListOwner::Document(ref doc) => doc.invalidate_stylesheets(), + StyleSheetListOwner::ShadowRoot(ref shadow_root) => { + shadow_root.invalidate_stylesheets() + }, + } + } } #[dom_struct] pub struct StyleSheetList { reflector_: Reflector, - #[ignore_malloc_size_of = "trait object"] - document_or_shadow_root: Box<StyleSheetListOwner>, + document_or_shadow_root: StyleSheetListOwner, } impl StyleSheetList { - fn new_inherited(doc_or_sr: Box<StyleSheetListOwner>) -> StyleSheetList { + #[allow(unrooted_must_root)] + fn new_inherited(doc_or_sr: StyleSheetListOwner) -> StyleSheetList { StyleSheetList { reflector_: Reflector::new(), document_or_shadow_root: doc_or_sr, @@ -39,7 +82,7 @@ impl StyleSheetList { } #[allow(unrooted_must_root)] - pub fn new(window: &Window, doc_or_sr: Box<StyleSheetListOwner>) -> DomRoot<StyleSheetList> { + pub fn new(window: &Window, doc_or_sr: StyleSheetListOwner) -> DomRoot<StyleSheetList> { reflect_dom_object( Box::new(StyleSheetList::new_inherited(doc_or_sr)), window, |