diff --git a/components/script/dom/cssgroupingrule.rs b/components/script/dom/cssgroupingrule.rs index aa381dcbaec..7176dda8d12 100644 --- a/components/script/dom/cssgroupingrule.rs +++ b/components/script/dom/cssgroupingrule.rs @@ -13,19 +13,21 @@ use dom::cssrule::CSSRule; use dom::cssrulelist::{CSSRuleList, RulesSource}; use dom::cssstylesheet::CSSStyleSheet; use dom::window::Window; +use parking_lot::RwLock; +use std::sync::Arc; use style::stylesheets::CssRules as StyleCssRules; #[dom_struct] pub struct CSSGroupingRule { cssrule: CSSRule, #[ignore_heap_size_of = "Arc"] - rules: StyleCssRules, + rules: Arc>, rulelist: MutNullableHeap>, } impl CSSGroupingRule { pub fn new_inherited(parent_stylesheet: &CSSStyleSheet, - rules: StyleCssRules) -> CSSGroupingRule { + rules: Arc>) -> CSSGroupingRule { CSSGroupingRule { cssrule: CSSRule::new_inherited(parent_stylesheet), rules: rules, @@ -34,7 +36,8 @@ impl CSSGroupingRule { } #[allow(unrooted_must_root)] - pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, rules: StyleCssRules) -> Root { + pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, + rules: Arc>) -> Root { reflect_dom_object(box CSSGroupingRule::new_inherited(parent_stylesheet, rules), window, CSSGroupingRuleBinding::Wrap) diff --git a/components/script/dom/cssrulelist.rs b/components/script/dom/cssrulelist.rs index e51ae3c78be..b59087c4d3e 100644 --- a/components/script/dom/cssrulelist.rs +++ b/components/script/dom/cssrulelist.rs @@ -41,7 +41,7 @@ pub struct CSSRuleList { } pub enum RulesSource { - Rules(CssRules), + Rules(Arc>), Keyframes(Arc>), } @@ -50,7 +50,7 @@ impl 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() + rules.read().0.iter().map(|_| MutNullableHeap::new(None)).collect() } RulesSource::Keyframes(ref rules) => { rules.read().keyframes.iter().map(|_| MutNullableHeap::new(None)).collect() @@ -87,7 +87,7 @@ impl CSSRuleList { let index = idx as usize; let parent_stylesheet = self.parent_stylesheet.style_stylesheet(); - let new_rule = css_rules.insert_rule(rule, parent_stylesheet, index, nested)?; + let new_rule = css_rules.write().insert_rule(rule, parent_stylesheet, index, nested)?; let parent_stylesheet = &*self.parent_stylesheet; let dom_rule = CSSRule::new_specific(&window, parent_stylesheet, new_rule); @@ -101,7 +101,7 @@ impl CSSRuleList { match self.rules { RulesSource::Rules(ref css_rules) => { - css_rules.remove_rule(index)?; + css_rules.write().remove_rule(index)?; let mut dom_rules = self.dom_rules.borrow_mut(); dom_rules[index].get().map(|r| r.detach()); dom_rules.remove(index); @@ -133,7 +133,7 @@ impl CSSRuleList { RulesSource::Rules(ref rules) => { CSSRule::new_specific(self.global().as_window(), parent_stylesheet, - rules.0.read()[idx as usize].clone()) + rules.read().0[idx as usize].clone()) } RulesSource::Keyframes(ref rules) => { Root::upcast(CSSKeyframeRule::new(self.global().as_window(), diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index 4a59d2f5812..bcf112cce94 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -24,7 +24,7 @@ use std::sync::Arc; use std::sync::atomic::AtomicBool; use style::attr::AttrValue; use style::str::HTML_SPACE_CHARACTERS; -use style::stylesheets::{Stylesheet, CssRule, Origin}; +use style::stylesheets::{Stylesheet, CssRule, CssRules, Origin}; use style::viewport::ViewportRule; #[dom_struct] @@ -98,7 +98,7 @@ impl HTMLMetaElement { if !content.is_empty() { if let Some(translated_rule) = ViewportRule::from_meta(&**content) { *self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet { - rules: vec![CssRule::Viewport(Arc::new(RwLock::new(translated_rule)))].into(), + rules: CssRules::new(vec![CssRule::Viewport(Arc::new(RwLock::new(translated_rule)))]), origin: Origin::Author, base_url: window_from_node(self).get_url(), namespaces: Default::default(), diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index afca398c8b5..89a53fdd697 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -18,7 +18,7 @@ use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordDataMut}; use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI}; use parking_lot::RwLock; use properties::{ComputedValues, PropertyDeclarationBlock}; -use stylesheets::{CssRule, Stylesheet, StyleRule}; +use stylesheets::{CssRules, Stylesheet, StyleRule}; use values::computed::{CalcLengthOrPercentage, Gradient, Image, LengthOrPercentage, LengthOrPercentageOrAuto}; unsafe impl HasFFI for Stylesheet { @@ -35,10 +35,10 @@ unsafe impl HasFFI for RwLock { } unsafe impl HasArcFFI for RwLock {} -unsafe impl HasFFI for RwLock> { +unsafe impl HasFFI for RwLock { type FFIType = ServoCssRules; } -unsafe impl HasArcFFI for RwLock> {} +unsafe impl HasArcFFI for RwLock {} unsafe impl HasFFI for RwLock { type FFIType = RawServoStyleRule; diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index f05cd4a7df6..1156b85731c 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -51,14 +51,8 @@ pub struct Namespaces { pub prefixes: FnvHashMap, } -#[derive(Debug, Clone)] -pub struct CssRules(pub Arc>>); - -impl From> for CssRules { - fn from(other: Vec) -> Self { - CssRules(Arc::new(RwLock::new(other))) - } -} +#[derive(Debug)] +pub struct CssRules(pub Vec); pub enum RulesMutateError { Syntax, @@ -77,9 +71,12 @@ impl From for RulesMutateError { } impl CssRules { - // used in CSSOM - pub fn only_ns_or_import(rules: &[CssRule]) -> bool { - rules.iter().all(|r| { + pub fn new(rules: Vec) -> Arc> { + Arc::new(RwLock::new(CssRules(rules))) + } + + fn only_ns_or_import(&self) -> bool { + self.0.iter().all(|r| { match *r { CssRule::Namespace(..) /* | CssRule::Import(..) */ => true, _ => false @@ -88,12 +85,10 @@ impl CssRules { } // https://drafts.csswg.org/cssom/#insert-a-css-rule - pub fn insert_rule(&self, rule: &str, parent_stylesheet: &Stylesheet, index: usize, nested: bool) + pub fn insert_rule(&mut self, rule: &str, parent_stylesheet: &Stylesheet, index: usize, nested: bool) -> Result { - let mut rules = self.0.write(); - // Step 1, 2 - if index > rules.len() { + if index > self.0.len() { return Err(RulesMutateError::IndexSize); } @@ -103,7 +98,7 @@ impl CssRules { } else if index == 0 { Some(State::Start) } else { - rules.get(index - 1).map(CssRule::rule_state) + self.0.get(index - 1).map(CssRule::rule_state) }; // Step 3, 4 @@ -113,7 +108,7 @@ impl CssRules { // Step 5 // Computes the maximum allowed parser state at a given index. - let rev_state = rules.get(index).map_or(State::Body, CssRule::rule_state); + let rev_state = self.0.get(index).map_or(State::Body, CssRule::rule_state); if new_state > rev_state { // We inserted a rule too early, e.g. inserting // a regular style rule before @namespace rules @@ -122,38 +117,36 @@ impl CssRules { // Step 6 if let CssRule::Namespace(..) = new_rule { - if !CssRules::only_ns_or_import(&rules) { + if !self.only_ns_or_import() { return Err(RulesMutateError::InvalidState); } } - rules.insert(index, new_rule.clone()); + self.0.insert(index, new_rule.clone()); Ok(new_rule) } // https://drafts.csswg.org/cssom/#remove-a-css-rule - pub fn remove_rule(&self, index: usize) -> Result<(), RulesMutateError> { - let mut rules = self.0.write(); - + pub fn remove_rule(&mut self, index: usize) -> Result<(), RulesMutateError> { // Step 1, 2 - if index >= rules.len() { + if index >= self.0.len() { return Err(RulesMutateError::IndexSize); } { // Step 3 - let ref rule = rules[index]; + let ref rule = self.0[index]; // Step 4 if let CssRule::Namespace(..) = *rule { - if !CssRules::only_ns_or_import(&rules) { + if !self.only_ns_or_import() { return Err(RulesMutateError::InvalidState); } } } // Step 5, 6 - rules.remove(index); + self.0.remove(index); Ok(()) } } @@ -162,7 +155,7 @@ impl CssRules { pub struct Stylesheet { /// List of rules in the order they were found (important for /// cascading order) - pub rules: CssRules, + pub rules: Arc>, /// List of media associated with the Stylesheet. pub media: Arc>, pub origin: Origin, @@ -274,8 +267,8 @@ impl CssRule { CssRule::Media(ref lock) => { let media_rule = lock.read(); let mq = media_rule.media_queries.read(); - let rules = media_rule.rules.0.read(); - f(&rules, Some(&mq)) + let rules = &media_rule.rules.read().0; + f(rules, Some(&mq)) } } } @@ -376,7 +369,7 @@ impl ToCss for KeyframesRule { #[derive(Debug)] pub struct MediaRule { pub media_queries: Arc>, - pub rules: CssRules, + pub rules: Arc>, } impl ToCss for MediaRule { @@ -386,7 +379,7 @@ impl ToCss for MediaRule { try!(dest.write_str("@media (")); try!(self.media_queries.read().to_css(dest)); try!(dest.write_str(") {")); - for rule in self.rules.0.read().iter() { + for rule in self.rules.read().0.iter() { try!(dest.write_str(" ")); try!(rule.to_css(dest)); } @@ -470,7 +463,7 @@ impl Stylesheet { origin: origin, base_url: base_url, namespaces: RwLock::new(namespaces), - rules: rules.into(), + rules: CssRules::new(rules), media: Arc::new(RwLock::new(media)), dirty_on_viewport_size_change: AtomicBool::new(dirty_on_viewport_size_change), disabled: AtomicBool::new(false), @@ -512,7 +505,7 @@ impl Stylesheet { /// examined. #[inline] pub fn effective_rules(&self, device: &Device, mut f: F) where F: FnMut(&CssRule) { - effective_rules(&self.rules.0.read(), device, &mut f); + effective_rules(&self.rules.read().0, device, &mut f); } /// Returns whether the stylesheet has been explicitly disabled through the CSSOM. @@ -698,7 +691,7 @@ struct NestedRuleParser<'a, 'b: 'a> { } impl<'a, 'b> NestedRuleParser<'a, 'b> { - fn parse_nested_rules(&self, input: &mut Parser) -> CssRules { + fn parse_nested_rules(&self, input: &mut Parser) -> Arc> { let mut iter = RuleListParser::new_for_nested_rule(input, self.clone()); let mut rules = Vec::new(); while let Some(result) = iter.next() { @@ -711,7 +704,7 @@ impl<'a, 'b> NestedRuleParser<'a, 'b> { } } } - rules.into() + CssRules::new(rules) } } diff --git a/components/style/stylist.rs b/components/style/stylist.rs index c0910a72c81..11cbdeaa081 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -389,7 +389,7 @@ impl Stylist { false } self.is_device_dirty |= stylesheets.iter().any(|stylesheet| { - mq_eval_changed(&stylesheet.rules.0.read(), &self.device, &device) + mq_eval_changed(&stylesheet.rules.read().0, &self.device, &device) }); self.device = device; diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 1f813303b21..3e6220c2b0e 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -57,7 +57,7 @@ use style::restyle_hints::RestyleHint; use style::selector_parser::PseudoElementCascadeType; use style::sequential; use style::string_cache::Atom; -use style::stylesheets::{CssRule, Origin, Stylesheet, StyleRule}; +use style::stylesheets::{CssRule, CssRules, Origin, Stylesheet, StyleRule}; use style::thread_state; use style::timer::Timer; use style::traversal::{recalc_style_at, PerLevelTraversalData}; @@ -293,12 +293,12 @@ pub extern "C" fn Servo_StyleSet_RemoveStyleSheet(raw_data: RawServoStyleSetBorr #[no_mangle] pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool { - !Stylesheet::as_arc(&raw_sheet).rules.0.read().is_empty() + !Stylesheet::as_arc(&raw_sheet).rules.read().0.is_empty() } #[no_mangle] pub extern "C" fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed) -> ServoCssRulesStrong { - Stylesheet::as_arc(&sheet).rules.0.clone().into_strong() + Stylesheet::as_arc(&sheet).rules.clone().into_strong() } #[no_mangle] @@ -314,8 +314,8 @@ pub extern "C" fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetBorrowed) -> #[no_mangle] pub extern "C" fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed, result: nsTArrayBorrowed_uintptr_t) -> () { - let rules = RwLock::>::as_arc(&rules).read(); - let iter = rules.iter().map(|rule| rule.rule_type() as usize); + let rules = RwLock::::as_arc(&rules).read(); + let iter = rules.0.iter().map(|rule| rule.rule_type() as usize); let (size, upper) = iter.size_hint(); debug_assert_eq!(size, upper.unwrap()); unsafe { result.set_len(size as u32) }; @@ -325,8 +325,8 @@ pub extern "C" fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed, #[no_mangle] pub extern "C" fn Servo_CssRules_GetStyleRuleAt(rules: ServoCssRulesBorrowed, index: u32) -> RawServoStyleRuleStrong { - let rules = RwLock::>::as_arc(&rules).read(); - match rules[index as usize] { + let rules = RwLock::::as_arc(&rules).read(); + match rules.0[index as usize] { CssRule::Style(ref rule) => rule.clone().into_strong(), _ => { unreachable!("GetStyleRuleAt should only be called on a style rule"); @@ -336,12 +336,12 @@ pub extern "C" fn Servo_CssRules_GetStyleRuleAt(rules: ServoCssRulesBorrowed, in #[no_mangle] pub extern "C" fn Servo_CssRules_AddRef(rules: ServoCssRulesBorrowed) -> () { - unsafe { RwLock::>::addref(rules) }; + unsafe { RwLock::::addref(rules) }; } #[no_mangle] pub extern "C" fn Servo_CssRules_Release(rules: ServoCssRulesBorrowed) -> () { - unsafe { RwLock::>::release(rules) }; + unsafe { RwLock::::release(rules) }; } #[no_mangle] diff --git a/tests/unit/style/media_queries.rs b/tests/unit/style/media_queries.rs index b85904d14dc..8c91a5b52bb 100644 --- a/tests/unit/style/media_queries.rs +++ b/tests/unit/style/media_queries.rs @@ -31,7 +31,7 @@ fn test_media_rule(css: &str, callback: F) where F: Fn(&MediaList, &str) { css, url, Origin::Author, Default::default(), Box::new(CSSErrorReporterTest), ParserContextExtraData::default()); let mut rule_count = 0; - media_queries(&stylesheet.rules.0.read(), &mut |mq| { + media_queries(&stylesheet.rules.read().0, &mut |mq| { rule_count += 1; callback(mq, css); }); diff --git a/tests/unit/style/stylesheets.rs b/tests/unit/style/stylesheets.rs index 1d7fb34fc98..476d2d4ecd4 100644 --- a/tests/unit/style/stylesheets.rs +++ b/tests/unit/style/stylesheets.rs @@ -20,7 +20,7 @@ use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredV use style::properties::Importance; use style::properties::longhands::animation_play_state; use style::stylesheets::{Origin, Namespaces}; -use style::stylesheets::{Stylesheet, NamespaceRule, CssRule, StyleRule, KeyframesRule}; +use style::stylesheets::{Stylesheet, NamespaceRule, CssRule, CssRules, StyleRule, KeyframesRule}; use style::values::specified::{LengthOrPercentageOrAuto, Percentage}; #[test] @@ -63,7 +63,7 @@ fn test_parse_stylesheet() { base_url: url, dirty_on_viewport_size_change: AtomicBool::new(false), disabled: AtomicBool::new(false), - rules: vec![ + rules: CssRules::new(vec![ CssRule::Namespace(Arc::new(RwLock::new(NamespaceRule { prefix: None, url: NsAtom::from("http://www.w3.org/1999/xhtml") @@ -263,7 +263,7 @@ fn test_parse_stylesheet() { ] }))) - ].into(), + ]), }; assert_eq!(format!("{:#?}", stylesheet), format!("{:#?}", expected));