diff options
author | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2019-02-05 20:50:44 +0100 |
---|---|---|
committer | Fernando Jiménez Moreno <ferjmoreno@gmail.com> | 2019-04-26 10:17:47 +0200 |
commit | 3bb50cc4795c3ac98d25e2b54d871ded2c3f3fed (patch) | |
tree | 736690ba430ac32c66157ca93a2d304c5a969820 /components | |
parent | 0d6bd24245df02e8e745a273e37cd53d70c19ce6 (diff) | |
download | servo-3bb50cc4795c3ac98d25e2b54d871ded2c3f3fed.tar.gz servo-3bb50cc4795c3ac98d25e2b54d871ded2c3f3fed.zip |
ShadowRoot stylesheet list
Diffstat (limited to 'components')
-rw-r--r-- | components/script/dom/bindings/trace.rs | 13 | ||||
-rw-r--r-- | components/script/dom/document.rs | 28 | ||||
-rw-r--r-- | components/script/dom/htmllinkelement.rs | 12 | ||||
-rw-r--r-- | components/script/dom/htmlmetaelement.rs | 9 | ||||
-rw-r--r-- | components/script/dom/htmlstyleelement.rs | 11 | ||||
-rw-r--r-- | components/script/dom/node.rs | 17 | ||||
-rw-r--r-- | components/script/dom/shadowroot.rs | 27 | ||||
-rw-r--r-- | components/script/dom/stylesheetlist.rs | 5 |
8 files changed, 93 insertions, 29 deletions
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 2c86040308e..06ee56e173a 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -126,7 +126,7 @@ use style::media_queries::MediaList; use style::properties::PropertyDeclarationBlock; use style::selector_parser::{PseudoElement, Snapshot}; use style::shared_lock::{Locked as StyleLocked, SharedRwLock as StyleSharedRwLock}; -use style::stylesheet_set::DocumentStylesheetSet; +use style::stylesheet_set::{AuthorStylesheetSet, DocumentStylesheetSet}; use style::stylesheets::keyframes_rule::Keyframe; use style::stylesheets::{CssRules, FontFaceRule, KeyframesRule, MediaRule, Stylesheet}; use style::stylesheets::{ImportRule, NamespaceRule, StyleRule, SupportsRule, ViewportRule}; @@ -717,6 +717,17 @@ where } } +unsafe impl<S> JSTraceable for AuthorStylesheetSet<S> +where + S: JSTraceable + ::style::stylesheets::StylesheetInDocument + PartialEq + 'static, +{ + unsafe fn trace(&self, tracer: *mut JSTracer) { + for s in self.iter() { + s.trace(tracer) + } + } +} + unsafe impl<Sink> JSTraceable for LossyDecoder<Sink> where Sink: JSTraceable + TendrilSink<UTF8>, diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index f4f0e809fce..ad4099bdbf9 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -2838,20 +2838,6 @@ impl Document { Device::new(MediaType::screen(), viewport_size, device_pixel_ratio) } - /// 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.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>) { - self.document_or_shadow_root - .add_stylesheet(owner, sheet, self.style_shared_lock()); - } - pub fn salvageable(&self) -> bool { self.salvageable.get() } @@ -4570,4 +4556,18 @@ impl StyleSheetListOwner for Dom<Document> { fn stylesheet_at(&self, index: usize) -> Option<DomRoot<CSSStyleSheet>> { self.document_or_shadow_root.stylesheet_at(index) } + + /// 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>) { + self.document_or_shadow_root + .add_stylesheet(owner, sheet, 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.document_or_shadow_root.remove_stylesheet(owner, s) + } } diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 6623593bc43..9e102795b2c 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -18,7 +18,9 @@ use crate::dom::element::{ }; use crate::dom::element::{AttributeMutation, Element, ElementCreator}; use crate::dom::htmlelement::HTMLElement; -use crate::dom::node::{document_from_node, window_from_node, Node, UnbindContext}; +use crate::dom::node::{ + document_from_node, stylesheets_owner_from_node, window_from_node, Node, UnbindContext, +}; use crate::dom::stylesheet::StyleSheet as DOMStyleSheet; use crate::dom::virtualmethods::VirtualMethods; use crate::stylesheet_loader::{StylesheetContextSource, StylesheetLoader, StylesheetOwner}; @@ -108,13 +110,13 @@ impl HTMLLinkElement { // FIXME(emilio): These methods are duplicated with // HTMLStyleElement::set_stylesheet. pub fn set_stylesheet(&self, s: Arc<Stylesheet>) { - let doc = document_from_node(self); + let stylesheets_owner = stylesheets_owner_from_node(self); if let Some(ref s) = *self.stylesheet.borrow() { - doc.remove_stylesheet(self.upcast(), s) + stylesheets_owner.remove_stylesheet(self.upcast(), s) } *self.stylesheet.borrow_mut() = Some(s.clone()); self.cssom_stylesheet.set(None); - doc.add_stylesheet(self.upcast(), s); + stylesheets_owner.add_stylesheet(self.upcast(), s); } pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> { @@ -252,7 +254,7 @@ impl VirtualMethods for HTMLLinkElement { } if let Some(s) = self.stylesheet.borrow_mut().take() { - document_from_node(self).remove_stylesheet(self.upcast(), &s); + stylesheets_owner_from_node(self).remove_stylesheet(self.upcast(), &s); } } } diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index de605c31092..0c8794711f1 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -15,7 +15,9 @@ use crate::dom::document::Document; use crate::dom::element::{AttributeMutation, Element}; use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlheadelement::HTMLHeadElement; -use crate::dom::node::{document_from_node, window_from_node, Node, UnbindContext}; +use crate::dom::node::{ + document_from_node, stylesheets_owner_from_node, window_from_node, Node, UnbindContext, +}; use crate::dom::virtualmethods::VirtualMethods; use dom_struct::dom_struct; use html5ever::{LocalName, Prefix}; @@ -106,6 +108,7 @@ impl HTMLMetaElement { let content = content.value(); if !content.is_empty() { if let Some(translated_rule) = ViewportRule::from_meta(&**content) { + let stylesheets_owner = stylesheets_owner_from_node(self); let document = document_from_node(self); let shared_lock = document.style_shared_lock(); let rule = CssRule::Viewport(Arc::new(shared_lock.wrap(translated_rule))); @@ -124,7 +127,7 @@ impl HTMLMetaElement { disabled: AtomicBool::new(false), }); *self.stylesheet.borrow_mut() = Some(sheet.clone()); - document.add_stylesheet(self.upcast(), sheet); + stylesheets_owner.add_stylesheet(self.upcast(), sheet); } } } @@ -208,7 +211,7 @@ impl VirtualMethods for HTMLMetaElement { self.process_referrer_attribute(); if let Some(s) = self.stylesheet.borrow_mut().take() { - document_from_node(self).remove_stylesheet(self.upcast(), &s); + stylesheets_owner_from_node(self).remove_stylesheet(self.upcast(), &s); } } } diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs index 20617a37079..f8465874a38 100644 --- a/components/script/dom/htmlstyleelement.rs +++ b/components/script/dom/htmlstyleelement.rs @@ -13,7 +13,8 @@ use crate::dom::document::Document; use crate::dom::element::{Element, ElementCreator}; use crate::dom::htmlelement::HTMLElement; use crate::dom::node::{ - document_from_node, window_from_node, ChildrenMutation, Node, UnbindContext, + document_from_node, stylesheets_owner_from_node, window_from_node, ChildrenMutation, Node, + UnbindContext, }; use crate::dom::stylesheet::StyleSheet as DOMStyleSheet; use crate::dom::virtualmethods::VirtualMethods; @@ -138,13 +139,13 @@ impl HTMLStyleElement { // FIXME(emilio): This is duplicated with HTMLLinkElement::set_stylesheet. pub fn set_stylesheet(&self, s: Arc<Stylesheet>) { - let doc = document_from_node(self); + let stylesheets_owner = stylesheets_owner_from_node(self); if let Some(ref s) = *self.stylesheet.borrow() { - doc.remove_stylesheet(self.upcast(), s) + stylesheets_owner.remove_stylesheet(self.upcast(), s) } *self.stylesheet.borrow_mut() = Some(s.clone()); self.cssom_stylesheet.set(None); - doc.add_stylesheet(self.upcast(), s); + stylesheets_owner.add_stylesheet(self.upcast(), s); } pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> { @@ -216,7 +217,7 @@ impl VirtualMethods for HTMLStyleElement { if context.tree_connected { if let Some(s) = self.stylesheet.borrow_mut().take() { - document_from_node(self).remove_stylesheet(self.upcast(), &s) + stylesheets_owner_from_node(self).remove_stylesheet(self.upcast(), &s) } } } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index b20f8cf037e..e1a40c13982 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -54,6 +54,7 @@ use crate::dom::nodelist::NodeList; use crate::dom::processinginstruction::ProcessingInstruction; use crate::dom::range::WeakRangeVec; use crate::dom::shadowroot::ShadowRoot; +use crate::dom::stylesheetlist::StyleSheetListOwner; use crate::dom::svgsvgelement::{LayoutSVGSVGElementHelpers, SVGSVGElement}; use crate::dom::text::Text; use crate::dom::virtualmethods::{vtable_for, VirtualMethods}; @@ -2786,6 +2787,22 @@ pub fn document_from_node<T: DerivedFrom<Node> + DomObject>(derived: &T) -> DomR derived.upcast().owner_doc() } +pub fn shadow_root_from_node<T: DerivedFrom<Node> + DomObject>( + derived: &T, +) -> Option<DomRoot<ShadowRoot>> { + derived.upcast().owner_shadow_root() +} + +pub fn stylesheets_owner_from_node<T: DerivedFrom<Node> + DomObject>( + derived: &T, +) -> Box<StyleSheetListOwner> { + if let Some(shadow_root) = shadow_root_from_node(derived) { + Box::new(Dom::from_ref(&*shadow_root)) + } else { + Box::new(Dom::from_ref(&*document_from_node(derived))) + } +} + pub fn window_from_node<T: DerivedFrom<Node> + DomObject>(derived: &T) -> DomRoot<Window> { let document = document_from_node(derived); DomRoot::from_ref(document.window()) diff --git a/components/script/dom/shadowroot.rs b/components/script/dom/shadowroot.rs index 4a77452a2a5..3b1e9d34b87 100644 --- a/components/script/dom/shadowroot.rs +++ b/components/script/dom/shadowroot.rs @@ -2,6 +2,7 @@ * 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::ShadowRootBinding::ShadowRootBinding::ShadowRootMethods; use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::{self, ShadowRootMode}; use crate::dom::bindings::inheritance::Castable; @@ -11,12 +12,15 @@ 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; +use crate::dom::documentorshadowroot::{DocumentOrShadowRoot, StyleSheetInDocument}; use crate::dom::element::Element; use crate::dom::node::{Node, NodeFlags}; use crate::dom::stylesheetlist::{StyleSheetList, StyleSheetListOwner}; use crate::dom::window::Window; use dom_struct::dom_struct; +use servo_arc::Arc; +use style::stylesheet_set::AuthorStylesheetSet; +use style::stylesheets::Stylesheet; // https://dom.spec.whatwg.org/#interface-shadowroot #[dom_struct] @@ -25,6 +29,9 @@ pub struct ShadowRoot { document_or_shadow_root: DocumentOrShadowRoot, document: Dom<Document>, host: Dom<Element>, + /// List of stylesheets associated with nodes in this shadow tree. + /// |None| if the list needs to be refreshed. + stylesheets: DomRefCell<AuthorStylesheetSet<StyleSheetInDocument>>, stylesheet_list: MutNullableDom<StyleSheetList>, window: Dom<Window>, } @@ -41,6 +48,7 @@ impl ShadowRoot { document_or_shadow_root: DocumentOrShadowRoot::new(document.window()), document: Dom::from_ref(document), host: Dom::from_ref(host), + stylesheets: DomRefCell::new(AuthorStylesheetSet::new()), stylesheet_list: MutNullableDom::new(None), window: Dom::from_ref(document.window()), } @@ -129,4 +137,21 @@ impl StyleSheetListOwner for Dom<ShadowRoot> { fn stylesheet_at(&self, index: usize) -> Option<DomRoot<CSSStyleSheet>> { self.document_or_shadow_root.stylesheet_at(index) } + + /// 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>) { + self.document_or_shadow_root.add_stylesheet( + owner, + sheet, + 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>) { + self.document_or_shadow_root.remove_stylesheet(owner, s) + } } diff --git a/components/script/dom/stylesheetlist.rs b/components/script/dom/stylesheetlist.rs index 101a252086e..b87d7957dfb 100644 --- a/components/script/dom/stylesheetlist.rs +++ b/components/script/dom/stylesheetlist.rs @@ -7,13 +7,18 @@ use crate::dom::bindings::codegen::Bindings::StyleSheetListBinding::StyleSheetLi use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::DomRoot; use crate::dom::cssstylesheet::CSSStyleSheet; +use crate::dom::element::Element; 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 { 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>); } #[dom_struct] |