From 0714e2291cbb0ff888f817dd75414882e9309e8f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 28 Nov 2016 16:16:59 +0100 Subject: [PATCH 1/3] Add base_url and namespaces to style::Stylesheet --- components/script/dom/htmlmetaelement.rs | 2 + components/style/stylesheets.rs | 47 +++++++++++++----------- tests/unit/style/stylesheets.rs | 9 ++++- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index fa2fe7846c1..4a59d2f5812 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -100,6 +100,8 @@ impl HTMLMetaElement { *self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet { rules: vec![CssRule::Viewport(Arc::new(RwLock::new(translated_rule)))].into(), origin: Origin::Author, + base_url: window_from_node(self).get_url(), + namespaces: Default::default(), media: Default::default(), // Viewport constraints are always recomputed on resize; they don't need to // force all styles to be recomputed. diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index 5756504e63b..1529a2e77ef 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -44,7 +44,7 @@ pub enum Origin { User, } -#[derive(Default)] +#[derive(Default, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Namespaces { pub default: Option, @@ -166,6 +166,8 @@ pub struct Stylesheet { /// List of media associated with the Stylesheet. pub media: Arc>, pub origin: Origin, + pub base_url: ServoUrl, + pub namespaces: RwLock, pub dirty_on_viewport_size_change: AtomicBool, pub disabled: AtomicBool, } @@ -435,37 +437,40 @@ impl Stylesheet { error_reporter: Box, extra_data: ParserContextExtraData) -> Stylesheet { let mut namespaces = Namespaces::default(); - let rule_parser = TopLevelRuleParser { - stylesheet_origin: origin, - namespaces: &mut namespaces, - context: ParserContext::new_with_extra_data(origin, &base_url, error_reporter.clone(), - extra_data), - state: Cell::new(State::Start), - }; - let mut input = Parser::new(css); - input.look_for_viewport_percentages(); - let mut rules = vec![]; + let dirty_on_viewport_size_change; { - let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser); - while let Some(result) = iter.next() { - match result { - Ok(rule) => rules.push(rule), - Err(range) => { - let pos = range.start; - let message = format!("Invalid rule: '{}'", iter.input.slice(range)); - let context = ParserContext::new(origin, &base_url, error_reporter.clone()); - log_css_error(iter.input, pos, &*message, &context); + let rule_parser = TopLevelRuleParser { + stylesheet_origin: origin, + namespaces: &mut namespaces, + context: ParserContext::new_with_extra_data(origin, &base_url, error_reporter, extra_data), + state: Cell::new(State::Start), + }; + let mut input = Parser::new(css); + input.look_for_viewport_percentages(); + { + let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser); + while let Some(result) = iter.next() { + match result { + Ok(rule) => rules.push(rule), + Err(range) => { + let pos = range.start; + let message = format!("Invalid rule: '{}'", iter.input.slice(range)); + log_css_error(iter.input, pos, &*message, &iter.parser.context); + } } } } + dirty_on_viewport_size_change = input.seen_viewport_percentages(); } Stylesheet { origin: origin, + base_url: base_url, + namespaces: RwLock::new(namespaces), rules: rules.into(), media: Arc::new(RwLock::new(media)), - dirty_on_viewport_size_change: AtomicBool::new(input.seen_viewport_percentages()), + dirty_on_viewport_size_change: AtomicBool::new(dirty_on_viewport_size_change), disabled: AtomicBool::new(false), } } diff --git a/tests/unit/style/stylesheets.rs b/tests/unit/style/stylesheets.rs index 629bef96d28..1d7fb34fc98 100644 --- a/tests/unit/style/stylesheets.rs +++ b/tests/unit/style/stylesheets.rs @@ -19,7 +19,8 @@ use style::parser::ParserContextExtraData; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredValue, longhands}; use style::properties::Importance; use style::properties::longhands::animation_play_state; -use style::stylesheets::{Stylesheet, NamespaceRule, CssRule, StyleRule, KeyframesRule, Origin}; +use style::stylesheets::{Origin, Namespaces}; +use style::stylesheets::{Stylesheet, NamespaceRule, CssRule, StyleRule, KeyframesRule}; use style::values::specified::{LengthOrPercentageOrAuto, Percentage}; #[test] @@ -50,12 +51,16 @@ fn test_parse_stylesheet() { } }"; let url = ServoUrl::parse("about::test").unwrap(); - let stylesheet = Stylesheet::from_str(css, url, Origin::UserAgent, Default::default(), + let stylesheet = Stylesheet::from_str(css, url.clone(), Origin::UserAgent, Default::default(), Box::new(CSSErrorReporterTest), ParserContextExtraData::default()); + let mut namespaces = Namespaces::default(); + namespaces.default = Some(ns!(html)); let expected = Stylesheet { origin: Origin::UserAgent, media: Default::default(), + namespaces: RwLock::new(namespaces), + base_url: url, dirty_on_viewport_size_change: AtomicBool::new(false), disabled: AtomicBool::new(false), rules: vec![ From f1d49d3773846a65cb403af4e041660fad3117be Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 28 Nov 2016 16:33:47 +0100 Subject: [PATCH 2/3] Make CSSRule always keep a pointer to its parent stylesheet even when the parentStylesheet IDL attribute returns null. --- components/script/dom/cssfontfacerule.rs | 9 +++-- components/script/dom/cssgroupingrule.rs | 14 +++---- components/script/dom/csskeyframerule.rs | 9 +++-- components/script/dom/csskeyframesrule.rs | 15 ++++---- components/script/dom/cssmediarule.rs | 9 +++-- components/script/dom/cssnamespacerule.rs | 9 +++-- components/script/dom/cssrule.rs | 47 +++++++++++++++-------- components/script/dom/cssrulelist.rs | 22 +++++------ components/script/dom/cssstylerule.rs | 9 +++-- components/script/dom/cssstylesheet.rs | 2 +- components/script/dom/cssviewportrule.rs | 8 ++-- 11 files changed, 84 insertions(+), 69 deletions(-) diff --git a/components/script/dom/cssfontfacerule.rs b/components/script/dom/cssfontfacerule.rs index 60022b7ba8f..61234f8846a 100644 --- a/components/script/dom/cssfontfacerule.rs +++ b/components/script/dom/cssfontfacerule.rs @@ -22,17 +22,18 @@ pub struct CSSFontFaceRule { } impl CSSFontFaceRule { - fn new_inherited(parent: Option<&CSSStyleSheet>, fontfacerule: Arc>) -> CSSFontFaceRule { + fn new_inherited(parent_stylesheet: &CSSStyleSheet, fontfacerule: Arc>) + -> CSSFontFaceRule { CSSFontFaceRule { - cssrule: CSSRule::new_inherited(parent), + cssrule: CSSRule::new_inherited(parent_stylesheet), fontfacerule: fontfacerule, } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, + pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, fontfacerule: Arc>) -> Root { - reflect_dom_object(box CSSFontFaceRule::new_inherited(parent, fontfacerule), + reflect_dom_object(box CSSFontFaceRule::new_inherited(parent_stylesheet, fontfacerule), window, CSSFontFaceRuleBinding::Wrap) } diff --git a/components/script/dom/cssgroupingrule.rs b/components/script/dom/cssgroupingrule.rs index cd55cd358b6..aa381dcbaec 100644 --- a/components/script/dom/cssgroupingrule.rs +++ b/components/script/dom/cssgroupingrule.rs @@ -4,7 +4,6 @@ use dom::bindings::codegen::Bindings::CSSGroupingRuleBinding; use dom::bindings::codegen::Bindings::CSSGroupingRuleBinding::CSSGroupingRuleMethods; -use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleBinding::CSSRuleMethods; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutNullableHeap, Root}; @@ -25,27 +24,26 @@ pub struct CSSGroupingRule { } impl CSSGroupingRule { - pub fn new_inherited(parent: Option<&CSSStyleSheet>, + pub fn new_inherited(parent_stylesheet: &CSSStyleSheet, rules: StyleCssRules) -> CSSGroupingRule { CSSGroupingRule { - cssrule: CSSRule::new_inherited(parent), + cssrule: CSSRule::new_inherited(parent_stylesheet), rules: rules, rulelist: MutNullableHeap::new(None), } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, rules: StyleCssRules) -> Root { - reflect_dom_object(box CSSGroupingRule::new_inherited(parent, rules), + pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, rules: StyleCssRules) -> Root { + reflect_dom_object(box CSSGroupingRule::new_inherited(parent_stylesheet, rules), window, CSSGroupingRuleBinding::Wrap) } fn rulelist(&self) -> Root { - let sheet = self.upcast::().GetParentStyleSheet(); - let sheet = sheet.as_ref().map(|s| &**s); + let parent_stylesheet = self.upcast::().parent_stylesheet(); self.rulelist.or_init(|| CSSRuleList::new(self.global().as_window(), - sheet, + parent_stylesheet, RulesSource::Rules(self.rules.clone()))) } } diff --git a/components/script/dom/csskeyframerule.rs b/components/script/dom/csskeyframerule.rs index e09099e1135..78916d339ab 100644 --- a/components/script/dom/csskeyframerule.rs +++ b/components/script/dom/csskeyframerule.rs @@ -22,17 +22,18 @@ pub struct CSSKeyframeRule { } impl CSSKeyframeRule { - fn new_inherited(parent: Option<&CSSStyleSheet>, keyframerule: Arc>) -> CSSKeyframeRule { + fn new_inherited(parent_stylesheet: &CSSStyleSheet, keyframerule: Arc>) + -> CSSKeyframeRule { CSSKeyframeRule { - cssrule: CSSRule::new_inherited(parent), + cssrule: CSSRule::new_inherited(parent_stylesheet), keyframerule: keyframerule, } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, + pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, keyframerule: Arc>) -> Root { - reflect_dom_object(box CSSKeyframeRule::new_inherited(parent, keyframerule), + reflect_dom_object(box CSSKeyframeRule::new_inherited(parent_stylesheet, keyframerule), window, CSSKeyframeRuleBinding::Wrap) } diff --git a/components/script/dom/csskeyframesrule.rs b/components/script/dom/csskeyframesrule.rs index b7baf6b85a9..bda3ee2ea20 100644 --- a/components/script/dom/csskeyframesrule.rs +++ b/components/script/dom/csskeyframesrule.rs @@ -5,7 +5,6 @@ use cssparser::Parser; use dom::bindings::codegen::Bindings::CSSKeyframesRuleBinding; use dom::bindings::codegen::Bindings::CSSKeyframesRuleBinding::CSSKeyframesRuleMethods; -use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleMethods; use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutNullableHeap, Root}; @@ -32,28 +31,28 @@ pub struct CSSKeyframesRule { } impl CSSKeyframesRule { - fn new_inherited(parent: Option<&CSSStyleSheet>, keyframesrule: Arc>) -> CSSKeyframesRule { + fn new_inherited(parent_stylesheet: &CSSStyleSheet, keyframesrule: Arc>) + -> CSSKeyframesRule { CSSKeyframesRule { - cssrule: CSSRule::new_inherited(parent), + cssrule: CSSRule::new_inherited(parent_stylesheet), keyframesrule: keyframesrule, rulelist: MutNullableHeap::new(None), } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, + pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, keyframesrule: Arc>) -> Root { - reflect_dom_object(box CSSKeyframesRule::new_inherited(parent, keyframesrule), + reflect_dom_object(box CSSKeyframesRule::new_inherited(parent_stylesheet, keyframesrule), window, CSSKeyframesRuleBinding::Wrap) } fn rulelist(&self) -> Root { self.rulelist.or_init(|| { - let sheet = self.upcast::().GetParentStyleSheet(); - let sheet = sheet.as_ref().map(|s| &**s); + let parent_stylesheet = &self.upcast::().parent_stylesheet(); CSSRuleList::new(self.global().as_window(), - sheet, + parent_stylesheet, RulesSource::Keyframes(self.keyframesrule.clone())) }) } diff --git a/components/script/dom/cssmediarule.rs b/components/script/dom/cssmediarule.rs index 67933fccd3b..e42c1bc0021 100644 --- a/components/script/dom/cssmediarule.rs +++ b/components/script/dom/cssmediarule.rs @@ -23,18 +23,19 @@ pub struct CSSMediaRule { } impl CSSMediaRule { - fn new_inherited(parent: Option<&CSSStyleSheet>, mediarule: Arc>) -> CSSMediaRule { + fn new_inherited(parent_stylesheet: &CSSStyleSheet, mediarule: Arc>) + -> CSSMediaRule { let list = mediarule.read().rules.clone(); CSSMediaRule { - cssrule: CSSGroupingRule::new_inherited(parent, list), + cssrule: CSSGroupingRule::new_inherited(parent_stylesheet, list), mediarule: mediarule, } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, + pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, mediarule: Arc>) -> Root { - reflect_dom_object(box CSSMediaRule::new_inherited(parent, mediarule), + reflect_dom_object(box CSSMediaRule::new_inherited(parent_stylesheet, mediarule), window, CSSMediaRuleBinding::Wrap) } diff --git a/components/script/dom/cssnamespacerule.rs b/components/script/dom/cssnamespacerule.rs index 4e93eea2e1f..5f451d3b798 100644 --- a/components/script/dom/cssnamespacerule.rs +++ b/components/script/dom/cssnamespacerule.rs @@ -23,17 +23,18 @@ pub struct CSSNamespaceRule { } impl CSSNamespaceRule { - fn new_inherited(parent: Option<&CSSStyleSheet>, namespacerule: Arc>) -> CSSNamespaceRule { + fn new_inherited(parent_stylesheet: &CSSStyleSheet, namespacerule: Arc>) + -> CSSNamespaceRule { CSSNamespaceRule { - cssrule: CSSRule::new_inherited(parent), + cssrule: CSSRule::new_inherited(parent_stylesheet), namespacerule: namespacerule, } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, + pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, namespacerule: Arc>) -> Root { - reflect_dom_object(box CSSNamespaceRule::new_inherited(parent, namespacerule), + reflect_dom_object(box CSSNamespaceRule::new_inherited(parent_stylesheet, namespacerule), window, CSSNamespaceRuleBinding::Wrap) } diff --git a/components/script/dom/cssrule.rs b/components/script/dom/cssrule.rs index ca1e52b77f0..603354c8621 100644 --- a/components/script/dom/cssrule.rs +++ b/components/script/dom/cssrule.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::Bindings::CSSRuleBinding; use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::js::{JS, Root}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::cssfontfacerule::CSSFontFaceRule; @@ -17,27 +17,34 @@ use dom::cssstylerule::CSSStyleRule; use dom::cssstylesheet::CSSStyleSheet; use dom::cssviewportrule::CSSViewportRule; use dom::window::Window; +use std::cell::Cell; use style::stylesheets::CssRule as StyleCssRule; #[dom_struct] pub struct CSSRule { reflector_: Reflector, - parent: MutNullableHeap>, + parent_stylesheet: JS, + + /// Whether the parentStyleSheet attribute should return null. + /// We keep parent_stylesheet in that case because insertRule needs it + /// for the stylesheet’s base URL and namespace prefixes. + parent_stylesheet_removed: Cell, } impl CSSRule { #[allow(unrooted_must_root)] - pub fn new_inherited(parent: Option<&CSSStyleSheet>) -> CSSRule { + pub fn new_inherited(parent_stylesheet: &CSSStyleSheet) -> CSSRule { CSSRule { reflector_: Reflector::new(), - parent: MutNullableHeap::new(parent), + parent_stylesheet: JS::from_ref(parent_stylesheet), + parent_stylesheet_removed: Cell::new(false), } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: Option<&CSSStyleSheet>) -> Root { - reflect_dom_object(box CSSRule::new_inherited(parent), + pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet) -> Root { + reflect_dom_object(box CSSRule::new_inherited(parent_stylesheet), window, CSSRuleBinding::Wrap) } @@ -64,16 +71,16 @@ impl CSSRule { // Given a StyleCssRule, create a new instance of a derived class of // CSSRule based on which rule it is - pub fn new_specific(window: &Window, parent: Option<&CSSStyleSheet>, + pub fn new_specific(window: &Window, parent_stylesheet: &CSSStyleSheet, rule: StyleCssRule) -> Root { // be sure to update the match in as_specific when this is updated match rule { - StyleCssRule::Style(s) => Root::upcast(CSSStyleRule::new(window, parent, s)), - StyleCssRule::FontFace(s) => Root::upcast(CSSFontFaceRule::new(window, parent, s)), - StyleCssRule::Keyframes(s) => Root::upcast(CSSKeyframesRule::new(window, parent, s)), - StyleCssRule::Media(s) => Root::upcast(CSSMediaRule::new(window, parent, s)), - StyleCssRule::Namespace(s) => Root::upcast(CSSNamespaceRule::new(window, parent, s)), - StyleCssRule::Viewport(s) => Root::upcast(CSSViewportRule::new(window, parent, s)), + StyleCssRule::Style(s) => Root::upcast(CSSStyleRule::new(window, parent_stylesheet, s)), + StyleCssRule::FontFace(s) => Root::upcast(CSSFontFaceRule::new(window, parent_stylesheet, s)), + StyleCssRule::Keyframes(s) => Root::upcast(CSSKeyframesRule::new(window, parent_stylesheet, s)), + StyleCssRule::Media(s) => Root::upcast(CSSMediaRule::new(window, parent_stylesheet, s)), + StyleCssRule::Namespace(s) => Root::upcast(CSSNamespaceRule::new(window, parent_stylesheet, s)), + StyleCssRule::Viewport(s) => Root::upcast(CSSViewportRule::new(window, parent_stylesheet, s)), } } @@ -85,12 +92,16 @@ impl CSSRule { /// Sets owner sheet to null (and does the same for all children) pub fn deparent(&self) { - self.parent.set(None); + self.parent_stylesheet_removed.set(true); // https://github.com/w3c/csswg-drafts/issues/722 // Spec doesn't ask us to do this, but it makes sense // and browsers implement this behavior self.as_specific().deparent_children(); } + + pub fn parent_stylesheet(&self) -> &CSSStyleSheet { + &self.parent_stylesheet + } } impl CSSRuleMethods for CSSRule { @@ -101,7 +112,11 @@ impl CSSRuleMethods for CSSRule { // https://drafts.csswg.org/cssom/#dom-cssrule-parentstylesheet fn GetParentStyleSheet(&self) -> Option> { - self.parent.get() + if self.parent_stylesheet_removed.get() { + None + } else { + Some(Root::from_ref(&*self.parent_stylesheet)) + } } // https://drafts.csswg.org/cssom/#dom-cssrule-csstext @@ -118,7 +133,7 @@ impl CSSRuleMethods for CSSRule { pub trait SpecificCSSRule { fn ty(&self) -> u16; fn get_css(&self) -> DOMString; - /// Remove CSSStyleSheet parent from all transitive children + /// Remove parentStylesheet from all transitive children fn deparent_children(&self) { // most CSSRules do nothing here } diff --git a/components/script/dom/cssrulelist.rs b/components/script/dom/cssrulelist.rs index 0f2212319dc..643cce9a944 100644 --- a/components/script/dom/cssrulelist.rs +++ b/components/script/dom/cssrulelist.rs @@ -34,7 +34,7 @@ impl From for Error { #[dom_struct] pub struct CSSRuleList { reflector_: Reflector, - sheet: MutNullableHeap>, + parent_stylesheet: JS, #[ignore_heap_size_of = "Arc"] rules: RulesSource, dom_rules: DOMRefCell>>> @@ -47,7 +47,7 @@ pub enum RulesSource { impl CSSRuleList { #[allow(unrooted_must_root)] - pub fn new_inherited(sheet: Option<&CSSStyleSheet>, rules: RulesSource) -> CSSRuleList { + pub fn new_inherited(parent_stylesheet: &CSSStyleSheet, rules: RulesSource) -> CSSRuleList { let dom_rules = match rules { RulesSource::Rules(ref rules) => { rules.0.read().iter().map(|_| MutNullableHeap::new(None)).collect() @@ -59,16 +59,16 @@ impl CSSRuleList { CSSRuleList { reflector_: Reflector::new(), - sheet: MutNullableHeap::new(sheet), + parent_stylesheet: JS::from_ref(parent_stylesheet), rules: rules, dom_rules: DOMRefCell::new(dom_rules), } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, sheet: Option<&CSSStyleSheet>, + pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, rules: RulesSource) -> Root { - reflect_dom_object(box CSSRuleList::new_inherited(sheet, rules), + reflect_dom_object(box CSSRuleList::new_inherited(parent_stylesheet, rules), window, CSSRuleListBinding::Wrap) } @@ -89,9 +89,8 @@ impl CSSRuleList { let new_rule = css_rules.insert_rule(rule, doc.url().clone(), index, nested)?; - let sheet = self.sheet.get(); - let sheet = sheet.as_ref().map(|sheet| &**sheet); - let dom_rule = CSSRule::new_specific(&window, sheet, new_rule); + let parent_stylesheet = &*self.parent_stylesheet; + let dom_rule = CSSRule::new_specific(&window, parent_stylesheet, new_rule); self.dom_rules.borrow_mut().insert(index, MutNullableHeap::new(Some(&*dom_rule))); Ok((idx)) } @@ -129,17 +128,16 @@ impl CSSRuleList { pub fn item(&self, idx: u32) -> Option> { self.dom_rules.borrow().get(idx as usize).map(|rule| { rule.or_init(|| { - let sheet = self.sheet.get(); - let sheet = sheet.as_ref().map(|sheet| &**sheet); + let parent_stylesheet = &self.parent_stylesheet; match self.rules { RulesSource::Rules(ref rules) => { CSSRule::new_specific(self.global().as_window(), - sheet, + parent_stylesheet, rules.0.read()[idx as usize].clone()) } RulesSource::Keyframes(ref rules) => { Root::upcast(CSSKeyframeRule::new(self.global().as_window(), - sheet, + parent_stylesheet, rules.read() .keyframes[idx as usize] .clone())) diff --git a/components/script/dom/cssstylerule.rs b/components/script/dom/cssstylerule.rs index 7d776655147..091704f42d5 100644 --- a/components/script/dom/cssstylerule.rs +++ b/components/script/dom/cssstylerule.rs @@ -22,17 +22,18 @@ pub struct CSSStyleRule { } impl CSSStyleRule { - fn new_inherited(parent: Option<&CSSStyleSheet>, stylerule: Arc>) -> CSSStyleRule { + fn new_inherited(parent_stylesheet: &CSSStyleSheet, stylerule: Arc>) + -> CSSStyleRule { CSSStyleRule { - cssrule: CSSRule::new_inherited(parent), + cssrule: CSSRule::new_inherited(parent_stylesheet), stylerule: stylerule, } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, + pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, stylerule: Arc>) -> Root { - reflect_dom_object(box CSSStyleRule::new_inherited(parent, stylerule), + reflect_dom_object(box CSSStyleRule::new_inherited(parent_stylesheet, stylerule), window, CSSStyleRuleBinding::Wrap) } diff --git a/components/script/dom/cssstylesheet.rs b/components/script/dom/cssstylesheet.rs index 32413ea0298..2e643f3e8a2 100644 --- a/components/script/dom/cssstylesheet.rs +++ b/components/script/dom/cssstylesheet.rs @@ -53,7 +53,7 @@ impl CSSStyleSheet { fn rulelist(&self) -> Root { self.rulelist.or_init(|| CSSRuleList::new(self.global().as_window(), - Some(self), + self, RulesSource::Rules(self.style_stylesheet .rules.clone()))) } diff --git a/components/script/dom/cssviewportrule.rs b/components/script/dom/cssviewportrule.rs index b324b0c64f5..25ca1b292c8 100644 --- a/components/script/dom/cssviewportrule.rs +++ b/components/script/dom/cssviewportrule.rs @@ -22,17 +22,17 @@ pub struct CSSViewportRule { } impl CSSViewportRule { - fn new_inherited(parent: Option<&CSSStyleSheet>, viewportrule: Arc>) -> CSSViewportRule { + fn new_inherited(parent_stylesheet: &CSSStyleSheet, viewportrule: Arc>) -> CSSViewportRule { CSSViewportRule { - cssrule: CSSRule::new_inherited(parent), + cssrule: CSSRule::new_inherited(parent_stylesheet), viewportrule: viewportrule, } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent: Option<&CSSStyleSheet>, + pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, viewportrule: Arc>) -> Root { - reflect_dom_object(box CSSViewportRule::new_inherited(parent, viewportrule), + reflect_dom_object(box CSSViewportRule::new_inherited(parent_stylesheet, viewportrule), window, CSSViewportRuleBinding::Wrap) } From 70b250fe2ac43658a823cf5de4eb636f7b603d3d Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 28 Nov 2016 17:48:32 +0100 Subject: [PATCH 3/3] =?UTF-8?q?Use=20stylesheet=E2=80=99s=20base=20URL=20a?= =?UTF-8?q?nd=20ns=20prefixes=20in=20CSSOM=20insert/appendRule.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/script/dom/csskeyframesrule.rs | 5 ++--- components/script/dom/cssrulelist.rs | 4 ++-- components/script/dom/cssstylesheet.rs | 4 ++++ components/style/keyframes.rs | 11 +++++------ components/style/stylesheets.rs | 20 +++++++++++--------- 5 files changed, 24 insertions(+), 20 deletions(-) diff --git a/components/script/dom/csskeyframesrule.rs b/components/script/dom/csskeyframesrule.rs index bda3ee2ea20..41d7beeaf80 100644 --- a/components/script/dom/csskeyframesrule.rs +++ b/components/script/dom/csskeyframesrule.rs @@ -19,7 +19,7 @@ use parking_lot::RwLock; use std::sync::Arc; use style::keyframes::{Keyframe, KeyframeSelector}; use style::parser::ParserContextExtraData; -use style::stylesheets::{KeyframesRule, Origin}; +use style::stylesheets::KeyframesRule; use style_traits::ToCss; #[dom_struct] @@ -83,8 +83,7 @@ impl CSSKeyframesRuleMethods for CSSKeyframesRule { fn AppendRule(&self, rule: DOMString) { let global = self.global(); let window = global.as_window(); - let doc = window.Document(); - let rule = Keyframe::parse(&rule, Origin::Author, doc.url().clone(), + let rule = Keyframe::parse(&rule, self.cssrule.parent_stylesheet().style_stylesheet(), ParserContextExtraData::default()); if let Ok(rule) = rule { self.keyframesrule.write().keyframes.push(rule); diff --git a/components/script/dom/cssrulelist.rs b/components/script/dom/cssrulelist.rs index 643cce9a944..e51ae3c78be 100644 --- a/components/script/dom/cssrulelist.rs +++ b/components/script/dom/cssrulelist.rs @@ -84,10 +84,10 @@ impl CSSRuleList { let global = self.global(); let window = global.as_window(); - let doc = window.Document(); let index = idx as usize; - let new_rule = css_rules.insert_rule(rule, doc.url().clone(), index, nested)?; + let parent_stylesheet = self.parent_stylesheet.style_stylesheet(); + let new_rule = css_rules.insert_rule(rule, parent_stylesheet, index, nested)?; let parent_stylesheet = &*self.parent_stylesheet; let dom_rule = CSSRule::new_specific(&window, parent_stylesheet, new_rule); diff --git a/components/script/dom/cssstylesheet.rs b/components/script/dom/cssstylesheet.rs index 2e643f3e8a2..93aefa8f852 100644 --- a/components/script/dom/cssstylesheet.rs +++ b/components/script/dom/cssstylesheet.rs @@ -67,6 +67,10 @@ impl CSSStyleSheet { self.global().as_window().Document().invalidate_stylesheets(); } } + + pub fn style_stylesheet(&self) -> &StyleStyleSheet { + &self.style_stylesheet + } } impl CSSStyleSheetMethods for CSSStyleSheet { diff --git a/components/style/keyframes.rs b/components/style/keyframes.rs index 7c9b969a210..831627d42c3 100644 --- a/components/style/keyframes.rs +++ b/components/style/keyframes.rs @@ -9,11 +9,10 @@ use parser::{ParserContext, ParserContextExtraData, log_css_error}; use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock}; use properties::PropertyDeclarationParseResult; use properties::animated_properties::TransitionProperty; -use servo_url::ServoUrl; use std::fmt; use std::sync::Arc; use style_traits::ToCss; -use stylesheets::{MemoryHoleReporter, Origin}; +use stylesheets::{MemoryHoleReporter, Stylesheet}; /// A number from 1 to 100, indicating the percentage of the animation where /// this keyframe should run. @@ -108,11 +107,11 @@ impl ToCss for Keyframe { impl Keyframe { - pub fn parse(css: &str, origin: Origin, - base_url: ServoUrl, - extra_data: ParserContextExtraData) -> Result>, ()> { + pub fn parse(css: &str, parent_stylesheet: &Stylesheet, extra_data: ParserContextExtraData) + -> Result>, ()> { let error_reporter = Box::new(MemoryHoleReporter); - let context = ParserContext::new_with_extra_data(origin, &base_url, + let context = ParserContext::new_with_extra_data(parent_stylesheet.origin, + &parent_stylesheet.base_url, error_reporter, extra_data); let mut input = Parser::new(css); diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index 1529a2e77ef..f05cd4a7df6 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -88,7 +88,7 @@ impl CssRules { } // https://drafts.csswg.org/cssom/#insert-a-css-rule - pub fn insert_rule(&self, rule: &str, base_url: ServoUrl, index: usize, nested: bool) + pub fn insert_rule(&self, rule: &str, parent_stylesheet: &Stylesheet, index: usize, nested: bool) -> Result { let mut rules = self.0.write(); @@ -108,7 +108,7 @@ impl CssRules { // Step 3, 4 // XXXManishearth should we also store the namespace map? - let (new_rule, new_state) = try!(CssRule::parse(&rule, Origin::Author, base_url, + let (new_rule, new_state) = try!(CssRule::parse(&rule, parent_stylesheet, ParserContextExtraData::default(), state)); // Step 5 @@ -282,13 +282,15 @@ impl CssRule { // input state is None for a nested rule // Returns a parsed CSS rule and the final state of the parser - pub fn parse(css: &str, origin: Origin, - base_url: ServoUrl, - extra_data: ParserContextExtraData, - state: Option) -> Result<(Self, State), SingleRuleParseError> { + pub fn parse(css: &str, + parent_stylesheet: &Stylesheet, + extra_data: ParserContextExtraData, + state: Option) + -> Result<(Self, State), SingleRuleParseError> { let error_reporter = Box::new(MemoryHoleReporter); - let mut namespaces = Namespaces::default(); - let context = ParserContext::new_with_extra_data(origin, &base_url, + let mut namespaces = parent_stylesheet.namespaces.write(); + let context = ParserContext::new_with_extra_data(parent_stylesheet.origin, + &parent_stylesheet.base_url, error_reporter.clone(), extra_data); let mut input = Parser::new(css); @@ -296,7 +298,7 @@ impl CssRule { // nested rules are in the body state let state = state.unwrap_or(State::Body); let mut rule_parser = TopLevelRuleParser { - stylesheet_origin: origin, + stylesheet_origin: parent_stylesheet.origin, context: context, state: Cell::new(state), namespaces: &mut namespaces,