diff options
-rw-r--r-- | components/script/dom/bindings/trace.rs | 2 | ||||
-rw-r--r-- | components/script/dom/document.rs | 161 | ||||
-rw-r--r-- | components/script/dom/documentorshadowroot.rs | 183 | ||||
-rw-r--r-- | components/script/dom/element.rs | 2 | ||||
-rw-r--r-- | components/script/dom/shadowroot.rs | 36 | ||||
-rw-r--r-- | components/script/dom/stylesheetlist.rs | 15 |
6 files changed, 207 insertions, 192 deletions
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index f1734d74b55..2c86040308e 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -39,6 +39,7 @@ use crate::dom::bindings::utils::WindowProxyHandler; use crate::dom::document::PendingRestyle; use crate::dom::htmlimageelement::SourceSet; use crate::dom::htmlmediaelement::{HTMLMediaElementFetchContext, MediaFrameRenderer}; +use crate::dom::stylesheetlist::StyleSheetListOwner; use crate::task::TaskBox; use app_units::Au; use canvas_traits::canvas::{ @@ -497,6 +498,7 @@ unsafe_no_jsmanaged_fields!(HTMLMediaElementFetchContext); unsafe_no_jsmanaged_fields!(Rotation3D<f64>, Transform2D<f32>, Transform3D<f64>); unsafe_no_jsmanaged_fields!(Point2D<f32>, Vector2D<f32>, Rect<Au>); unsafe_no_jsmanaged_fields!(Rect<f32>, RigidTransform3D<f64>); +unsafe_no_jsmanaged_fields!(StyleSheetListOwner); unsafe impl<'a> JSTraceable for &'a str { #[inline] diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 31778542466..f4f0e809fce 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -43,7 +43,7 @@ use crate::dom::cssstylesheet::CSSStyleSheet; use crate::dom::customelementregistry::CustomElementDefinition; use crate::dom::customevent::CustomEvent; use crate::dom::documentfragment::DocumentFragment; -use crate::dom::documentorshadowroot::{DocumentOrShadowRoot, DocumentOrShadowRootImpl}; +use crate::dom::documentorshadowroot::{DocumentOrShadowRoot, StyleSheetInDocument}; use crate::dom::documenttype::DocumentType; use crate::dom::domimplementation::DOMImplementation; use crate::dom::element::CustomElementCreationMode; @@ -68,7 +68,6 @@ use crate::dom::htmlheadelement::HTMLHeadElement; use crate::dom::htmlhtmlelement::HTMLHtmlElement; use crate::dom::htmliframeelement::HTMLIFrameElement; use crate::dom::htmlimageelement::HTMLImageElement; -use crate::dom::htmlmetaelement::HTMLMetaElement; use crate::dom::htmlscriptelement::{HTMLScriptElement, ScriptResult}; use crate::dom::htmltitleelement::HTMLTitleElement; use crate::dom::keyboardevent::KeyboardEvent; @@ -89,7 +88,7 @@ use crate::dom::range::Range; use crate::dom::servoparser::ServoParser; use crate::dom::shadowroot::ShadowRoot; use crate::dom::storageevent::StorageEvent; -use crate::dom::stylesheetlist::StyleSheetList; +use crate::dom::stylesheetlist::{StyleSheetList, StyleSheetListOwner}; use crate::dom::text::Text; use crate::dom::touch::Touch; use crate::dom::touchevent::TouchEvent; @@ -145,7 +144,6 @@ use std::cell::{Cell, Ref, RefMut}; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::{HashMap, HashSet, VecDeque}; use std::default::Default; -use std::fmt; use std::mem; use std::ptr::NonNull; use std::rc::Rc; @@ -153,12 +151,12 @@ use std::time::{Duration, Instant}; use style::attr::AttrValue; use style::context::QuirksMode; use style::invalidation::element::restyle_hints::RestyleHint; -use style::media_queries::{Device, MediaList, MediaType}; +use style::media_queries::{Device, MediaType}; use style::selector_parser::{RestyleDamage, Snapshot}; -use style::shared_lock::{SharedRwLock as StyleSharedRwLock, SharedRwLockReadGuard}; +use style::shared_lock::SharedRwLock as StyleSharedRwLock; use style::str::{split_html_space_chars, str_join}; use style::stylesheet_set::DocumentStylesheetSet; -use style::stylesheets::{CssRule, Origin, OriginSet, Stylesheet}; +use style::stylesheets::Stylesheet; use url::percent_encoding::percent_decode; use url::Host; @@ -221,53 +219,11 @@ impl PendingRestyle { } } -#[derive(Clone, JSTraceable, MallocSizeOf)] -#[must_root] -struct StyleSheetInDocument { - #[ignore_malloc_size_of = "Arc"] - sheet: Arc<Stylesheet>, - owner: Dom<Element>, -} - -impl fmt::Debug for StyleSheetInDocument { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - self.sheet.fmt(formatter) - } -} - -impl PartialEq for StyleSheetInDocument { - fn eq(&self, other: &Self) -> bool { - Arc::ptr_eq(&self.sheet, &other.sheet) - } -} - -impl ::style::stylesheets::StylesheetInDocument for StyleSheetInDocument { - fn origin(&self, guard: &SharedRwLockReadGuard) -> Origin { - self.sheet.origin(guard) - } - - fn quirks_mode(&self, guard: &SharedRwLockReadGuard) -> QuirksMode { - self.sheet.quirks_mode(guard) - } - - fn enabled(&self) -> bool { - self.sheet.enabled() - } - - fn media<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> Option<&'a MediaList> { - self.sheet.media(guard) - } - - fn rules<'a, 'b: 'a>(&'a self, guard: &'b SharedRwLockReadGuard) -> &'a [CssRule] { - self.sheet.rules(guard) - } -} - /// <https://dom.spec.whatwg.org/#document> #[dom_struct] pub struct Document { node: Node, - document_or_shadow_root: DocumentOrShadowRootImpl, + document_or_shadow_root: DocumentOrShadowRoot, window: Dom<Window>, implementation: MutNullableDom<DOMImplementation>, #[ignore_malloc_size_of = "type from external crate"] @@ -618,7 +574,7 @@ impl Document { // FIXME: This should check the dirty bit on the document, // not the document element. Needs some layout changes to make // that workable. - self.stylesheets.borrow().has_changed() || + self.document_or_shadow_root.stylesheets_have_changed() || self.GetDocumentElement().map_or(false, |root| { root.upcast::<Node>().has_dirty_descendants() || !self.pending_restyles.borrow().is_empty() || @@ -1580,7 +1536,7 @@ impl Document { } pub fn invalidate_stylesheets(&self) { - self.stylesheets.borrow_mut().force_dirty(OriginSet::all()); + self.document_or_shadow_root.invalidate_stylesheets(); // Mark the document element dirty so a reflow will be performed. // @@ -2627,7 +2583,7 @@ impl Document { let has_browsing_context = has_browsing_context == HasBrowsingContext::Yes; Document { node: Node::new_document_node(), - document_or_shadow_root: DocumentOrShadowRootImpl::new(window), + document_or_shadow_root: DocumentOrShadowRoot::new(window), window: Dom::from_ref(window), has_browsing_context, implementation: Default::default(), @@ -2865,9 +2821,9 @@ impl Document { // and normal stylesheets additions / removals, because in the last case // the layout thread already has that information and we could avoid // dirtying the whole thing. - let mut stylesheets = self.stylesheets.borrow_mut(); - let have_changed = stylesheets.has_changed(); - stylesheets.flush_without_invalidation(); + let have_changed = self.document_or_shadow_root.stylesheets_have_changed(); + self.document_or_shadow_root + .flush_stylesheets_without_invalidation(); have_changed } @@ -2885,90 +2841,21 @@ impl Document { /// 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(); - - let guard = s.shared_lock.read(); - - // FIXME(emilio): Would be nice to remove the clone, etc. - self.stylesheets.borrow_mut().remove_stylesheet( - None, - StyleSheetInDocument { - sheet: s.clone(), - owner: Dom::from_ref(owner), - }, - &guard, - ); + self.document_or_shadow_root.remove_stylesheet(owner, s) } /// 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>) { - // FIXME(emilio): It'd be nice to unify more code between the elements - // that own stylesheets, but StylesheetOwner is more about loading - // them... - debug_assert!( - owner.as_stylesheet_owner().is_some() || owner.is::<HTMLMetaElement>(), - "Wat" - ); - - let mut stylesheets = 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(); - - let sheet = StyleSheetInDocument { - sheet, - owner: Dom::from_ref(owner), - }; - - let lock = self.style_shared_lock(); - let guard = lock.read(); - - match insertion_point { - Some(ip) => { - stylesheets.insert_stylesheet_before(None, sheet, ip, &guard); - }, - None => { - stylesheets.append_stylesheet(None, sheet, &guard); - }, - } - } - - /// Returns the number of document stylesheets. - pub fn stylesheet_count(&self) -> usize { - self.stylesheets.borrow().len() + self.document_or_shadow_root + .add_stylesheet(owner, sheet, self.style_shared_lock()); } pub fn salvageable(&self) -> bool { self.salvageable.get() } - 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()) - } - /// <https://html.spec.whatwg.org/multipage/#appropriate-template-contents-owner-document> pub fn appropriate_template_contents_owner_document(&self) -> DomRoot<Document> { self.appropriate_template_contents_owner_document @@ -3290,12 +3177,8 @@ 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, - DocumentOrShadowRoot::Document(Dom::from_ref(self)), - ) - }) + self.stylesheet_list + .or_init(|| StyleSheetList::new(&self.window, Box::new(Dom::from_ref(self)))) } // https://dom.spec.whatwg.org/#dom-document-implementation @@ -4678,3 +4561,13 @@ impl PendingScript { .map(|result| (DomRoot::from_ref(&*self.element), result)) } } + +impl StyleSheetListOwner for Dom<Document> { + fn stylesheet_count(&self) -> usize { + self.document_or_shadow_root.stylesheet_count() + } + + fn stylesheet_at(&self, index: usize) -> Option<DomRoot<CSSStyleSheet>> { + self.document_or_shadow_root.stylesheet_at(index) + } +} diff --git a/components/script/dom/documentorshadowroot.rs b/components/script/dom/documentorshadowroot.rs index 5e413c5cc89..b1ea9ee1549 100644 --- a/components/script/dom/documentorshadowroot.rs +++ b/components/script/dom/documentorshadowroot.rs @@ -2,65 +2,86 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeBinding::NodeMethods; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::num::Finite; 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::htmlelement::HTMLElement; -use crate::dom::node; -use crate::dom::shadowroot::ShadowRoot; +use crate::dom::htmlmetaelement::HTMLMetaElement; +use crate::dom::node::{self, Node}; use crate::dom::window::Window; use euclid::Point2D; use js::jsapi::JS_GetRuntime; -use script_layout_interface::message::{NodesFromPointQueryType, QueryMsg}; +use script_layout_interface::message::{Msg, NodesFromPointQueryType, QueryMsg}; use script_traits::UntrustedNodeAddress; +use servo_arc::Arc; +use std::fmt; +use style::context::QuirksMode; +use style::media_queries::MediaList; +use style::shared_lock::{SharedRwLock as StyleSharedRwLock, SharedRwLockReadGuard}; +use style::stylesheet_set::DocumentStylesheetSet; +use style::stylesheets::{CssRule, Origin, OriginSet, Stylesheet}; -macro_rules! proxy_call( - ($fn_name:ident, $return_type:ty) => ( - pub fn $fn_name(&self) -> $return_type { - match self { - DocumentOrShadowRoot::Document(doc) => doc.$fn_name(), - DocumentOrShadowRoot::ShadowRoot(root) => root.$fn_name(), - } - } - ); +#[derive(Clone, JSTraceable, MallocSizeOf)] +#[must_root] +pub struct StyleSheetInDocument { + #[ignore_malloc_size_of = "Arc"] + sheet: Arc<Stylesheet>, + owner: Dom<Element>, +} - ($fn_name:ident, $arg1:ident, $arg1_type:ty, $return_type:ty) => ( - pub fn $fn_name(&self, $arg1: $arg1_type) -> $return_type { - match self { - DocumentOrShadowRoot::Document(doc) => doc.$fn_name($arg1), - DocumentOrShadowRoot::ShadowRoot(root) => root.$fn_name($arg1), - } - } - ); -); +impl fmt::Debug for StyleSheetInDocument { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.sheet.fmt(formatter) + } +} -#[must_root] -#[derive(JSTraceable, MallocSizeOf)] -pub enum DocumentOrShadowRoot { - Document(Dom<Document>), - ShadowRoot(Dom<ShadowRoot>), +impl PartialEq for StyleSheetInDocument { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.sheet, &other.sheet) + } } -impl DocumentOrShadowRoot { - proxy_call!(stylesheet_count, usize); - proxy_call!(stylesheet_at, index, usize, Option<DomRoot<CSSStyleSheet>>); +impl ::style::stylesheets::StylesheetInDocument for StyleSheetInDocument { + fn origin(&self, guard: &SharedRwLockReadGuard) -> Origin { + self.sheet.origin(guard) + } + + fn quirks_mode(&self, guard: &SharedRwLockReadGuard) -> QuirksMode { + self.sheet.quirks_mode(guard) + } + + fn enabled(&self) -> bool { + self.sheet.enabled() + } + + fn media<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> Option<&'a MediaList> { + self.sheet.media(guard) + } + + fn rules<'a, 'b: 'a>(&'a self, guard: &'b SharedRwLockReadGuard) -> &'a [CssRule] { + self.sheet.rules(guard) + } } // https://w3c.github.io/webcomponents/spec/shadow/#extensions-to-the-documentorshadowroot-mixin #[must_root] #[derive(JSTraceable, MallocSizeOf)] -pub struct DocumentOrShadowRootImpl { +pub struct DocumentOrShadowRoot { window: Dom<Window>, + /// List of stylesheets associated with nodes in this document or shadow root. + /// |None| if the list needs to be refreshed. + stylesheets: DomRefCell<DocumentStylesheetSet<StyleSheetInDocument>>, } -impl DocumentOrShadowRootImpl { +impl DocumentOrShadowRoot { pub fn new(window: &Window) -> Self { Self { window: Dom::from_ref(window), + stylesheets: DomRefCell::new(DocumentStylesheetSet::new()), } } @@ -185,4 +206,102 @@ impl DocumentOrShadowRootImpl { }, } } + + 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()) + } + + pub fn stylesheets_have_changed(&self) -> bool { + self.stylesheets.borrow().has_changed() + } + + pub fn invalidate_stylesheets(&self) { + self.stylesheets.borrow_mut().force_dirty(OriginSet::all()); + } + + pub fn flush_stylesheets_without_invalidation(&self) { + self.stylesheets.borrow_mut().flush_without_invalidation(); + } + + /// 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(); + + let guard = s.shared_lock.read(); + + // FIXME(emilio): Would be nice to remove the clone, etc. + self.stylesheets.borrow_mut().remove_stylesheet( + None, + StyleSheetInDocument { + sheet: s.clone(), + owner: Dom::from_ref(owner), + }, + &guard, + ); + } + + /// 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>, + style_shared_lock: &StyleSharedRwLock, + ) { + // FIXME(emilio): It'd be nice to unify more code between the elements + // that own stylesheets, but StylesheetOwner is more about loading + // them... + debug_assert!( + owner.as_stylesheet_owner().is_some() || owner.is::<HTMLMetaElement>(), + "Wat" + ); + + let mut stylesheets = 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(); + + let sheet = StyleSheetInDocument { + sheet, + owner: Dom::from_ref(owner), + }; + + let guard = style_shared_lock.read(); + + match insertion_point { + Some(ip) => { + stylesheets.insert_stylesheet_before(None, sheet, ip, &guard); + }, + None => { + stylesheets.append_stylesheet(None, sheet, &guard); + }, + } + } } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index f9923da3fea..4b24ab84a90 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -77,7 +77,7 @@ use crate::dom::node::{NodeDamage, NodeFlags, UnbindContext}; use crate::dom::nodelist::NodeList; use crate::dom::promise::Promise; use crate::dom::servoparser::ServoParser; -use crate::dom::shadowroot::{LayoutShadowRootHelpers, ShadowRoot}; +use crate::dom::shadowroot::ShadowRoot; use crate::dom::text::Text; use crate::dom::validation::Validatable; use crate::dom::virtualmethods::{vtable_for, VirtualMethods}; diff --git a/components/script/dom/shadowroot.rs b/components/script/dom/shadowroot.rs index 55470a9935d..4a77452a2a5 100644 --- a/components/script/dom/shadowroot.rs +++ b/components/script/dom/shadowroot.rs @@ -11,10 +11,10 @@ use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom}; use crate::dom::cssstylesheet::CSSStyleSheet; use crate::dom::document::Document; use crate::dom::documentfragment::DocumentFragment; -use crate::dom::documentorshadowroot::{DocumentOrShadowRoot, DocumentOrShadowRootImpl}; +use crate::dom::documentorshadowroot::DocumentOrShadowRoot; use crate::dom::element::Element; use crate::dom::node::{Node, NodeFlags}; -use crate::dom::stylesheetlist::StyleSheetList; +use crate::dom::stylesheetlist::{StyleSheetList, StyleSheetListOwner}; use crate::dom::window::Window; use dom_struct::dom_struct; @@ -22,7 +22,7 @@ use dom_struct::dom_struct; #[dom_struct] pub struct ShadowRoot { document_fragment: DocumentFragment, - document_or_shadow_root: DocumentOrShadowRootImpl, + document_or_shadow_root: DocumentOrShadowRoot, document: Dom<Document>, host: Dom<Element>, stylesheet_list: MutNullableDom<StyleSheetList>, @@ -38,7 +38,7 @@ impl ShadowRoot { .set_flag(NodeFlags::IS_IN_SHADOW_TREE, true); ShadowRoot { document_fragment, - document_or_shadow_root: DocumentOrShadowRootImpl::new(document.window()), + document_or_shadow_root: DocumentOrShadowRoot::new(document.window()), document: Dom::from_ref(document), host: Dom::from_ref(host), stylesheet_list: MutNullableDom::new(None), @@ -58,16 +58,6 @@ impl ShadowRoot { //XXX get retargeted focused element None } - - pub fn stylesheet_count(&self) -> usize { - //XXX handle shadowroot stylesheets - 0 - } - - pub fn stylesheet_at(&self, _index: usize) -> Option<DomRoot<CSSStyleSheet>> { - //XXX handle shadowroot stylesheets - None - } } impl ShadowRootMethods for ShadowRoot { @@ -113,12 +103,8 @@ 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, - DocumentOrShadowRoot::ShadowRoot(Dom::from_ref(self)), - ) - }) + self.stylesheet_list + .or_init(|| StyleSheetList::new(&self.window, Box::new(Dom::from_ref(self)))) } } @@ -134,3 +120,13 @@ impl LayoutShadowRootHelpers for LayoutDom<ShadowRoot> { (*self.unsafe_get()).host.to_layout() } } + +impl StyleSheetListOwner for Dom<ShadowRoot> { + fn stylesheet_count(&self) -> usize { + self.document_or_shadow_root.stylesheet_count() + } + + fn stylesheet_at(&self, index: usize) -> Option<DomRoot<CSSStyleSheet>> { + self.document_or_shadow_root.stylesheet_at(index) + } +} diff --git a/components/script/dom/stylesheetlist.rs b/components/script/dom/stylesheetlist.rs index 79afcfed21f..101a252086e 100644 --- a/components/script/dom/stylesheetlist.rs +++ b/components/script/dom/stylesheetlist.rs @@ -6,20 +6,25 @@ 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::documentorshadowroot::DocumentOrShadowRoot; +use crate::dom::cssstylesheet::CSSStyleSheet; use crate::dom::stylesheet::StyleSheet; use crate::dom::window::Window; use dom_struct::dom_struct; +pub trait StyleSheetListOwner { + fn stylesheet_count(&self) -> usize; + fn stylesheet_at(&self, index: usize) -> Option<DomRoot<CSSStyleSheet>>; +} + #[dom_struct] pub struct StyleSheetList { reflector_: Reflector, - document_or_shadow_root: DocumentOrShadowRoot, + #[ignore_malloc_size_of = "trait object"] + document_or_shadow_root: Box<StyleSheetListOwner>, } impl StyleSheetList { - #[allow(unrooted_must_root)] - fn new_inherited(doc_or_sr: DocumentOrShadowRoot) -> StyleSheetList { + fn new_inherited(doc_or_sr: Box<StyleSheetListOwner>) -> StyleSheetList { StyleSheetList { reflector_: Reflector::new(), document_or_shadow_root: doc_or_sr, @@ -27,7 +32,7 @@ impl StyleSheetList { } #[allow(unrooted_must_root)] - pub fn new(window: &Window, doc_or_sr: DocumentOrShadowRoot) -> DomRoot<StyleSheetList> { + pub fn new(window: &Window, doc_or_sr: Box<StyleSheetListOwner>) -> DomRoot<StyleSheetList> { reflect_dom_object( Box::new(StyleSheetList::new_inherited(doc_or_sr)), window, |