diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-11-27 15:40:19 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-27 15:40:19 -0800 |
commit | b18ec28fa7dab1728bb9e01d675534a28c43bb6a (patch) | |
tree | 3fe7dc36cbc0cd060b3392d3d35d1df47e3b7b8d /components/script | |
parent | 7d69f53794c9f823d524d0d4382c04c4a57bea65 (diff) | |
parent | 3e7818f1775db03e8adedf32f80aee43f5765166 (diff) | |
download | servo-b18ec28fa7dab1728bb9e01d675534a28c43bb6a.tar.gz servo-b18ec28fa7dab1728bb9e01d675534a28c43bb6a.zip |
Auto merge of #14355 - upsuper:rulelist-mutate, r=Manishearth
Move algorithm for insertRule and deleteRule to style component
<!-- Please describe your changes on the following line: -->
r? @Manishearth
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14355)
<!-- Reviewable:end -->
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/cssrulelist.rs | 102 |
1 files changed, 15 insertions, 87 deletions
diff --git a/components/script/dom/cssrulelist.rs b/components/script/dom/cssrulelist.rs index deb6b93e8b1..0f2212319dc 100644 --- a/components/script/dom/cssrulelist.rs +++ b/components/script/dom/cssrulelist.rs @@ -15,13 +15,22 @@ use dom::cssstylesheet::CSSStyleSheet; use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; -use style::parser::ParserContextExtraData; -use style::stylesheets::{CssRules, KeyframesRule, Origin}; -use style::stylesheets::CssRule as StyleCssRule; +use style::stylesheets::{CssRules, KeyframesRule, RulesMutateError}; no_jsmanaged_fields!(RulesSource); no_jsmanaged_fields!(CssRules); +impl From<RulesMutateError> for Error { + fn from(other: RulesMutateError) -> Self { + match other { + RulesMutateError::Syntax => Error::Syntax, + RulesMutateError::IndexSize => Error::IndexSize, + RulesMutateError::HierarchyRequest => Error::HierarchyRequest, + RulesMutateError::InvalidState => Error::InvalidState, + } + } +} + #[dom_struct] pub struct CSSRuleList { reflector_: Reflector, @@ -64,21 +73,9 @@ impl CSSRuleList { CSSRuleListBinding::Wrap) } - /// https://drafts.csswg.org/cssom/#insert-a-css-rule - /// /// Should only be called for CssRules-backed rules. Use append_lazy_rule /// for keyframes-backed rules. pub fn insert_rule(&self, rule: &str, idx: u32, nested: bool) -> Fallible<u32> { - use style::stylesheets::SingleRuleParseError; - /// Insert an item into a vector, appending if it is out of bounds - fn insert<T>(vec: &mut Vec<T>, index: usize, item: T) { - if index >= vec.len() { - vec.push(item); - } else { - vec.insert(index, item); - } - } - let css_rules = if let RulesSource::Rules(ref rules) = self.rules { rules } else { @@ -90,92 +87,23 @@ impl CSSRuleList { let doc = window.Document(); let index = idx as usize; + let new_rule = css_rules.insert_rule(rule, doc.url().clone(), index, nested)?; - let new_rule = { - let rules = css_rules.0.read(); - let state = if nested { - None - } else { - Some(CssRules::state_at_index(&rules, index)) - }; - - let rev_state = CssRules::state_at_index_rev(&rules, index); - - // Step 1, 2 - // XXXManishearth get url from correct location - // XXXManishearth should we also store the namespace map? - let parse_result = StyleCssRule::parse(&rule, Origin::Author, - doc.url().clone(), - ParserContextExtraData::default(), - state); - - if let Err(SingleRuleParseError::Syntax) = parse_result { - return Err(Error::Syntax) - } - - // Step 3, 4 - if index > rules.len() { - return Err(Error::IndexSize); - } - - let (new_rule, new_state) = try!(parse_result.map_err(|_| Error::HierarchyRequest)); - - if new_state > rev_state { - // We inserted a rule too early, e.g. inserting - // a regular style rule before @namespace rules - return Err((Error::HierarchyRequest)); - } - - // Step 6 - if let StyleCssRule::Namespace(..) = new_rule { - if !CssRules::only_ns_or_import(&rules) { - return Err(Error::InvalidState); - } - } - - new_rule - }; - - insert(&mut css_rules.0.write(), index, new_rule.clone()); let sheet = self.sheet.get(); let sheet = sheet.as_ref().map(|sheet| &**sheet); let dom_rule = CSSRule::new_specific(&window, sheet, new_rule); - insert(&mut self.dom_rules.borrow_mut(), - index, MutNullableHeap::new(Some(&*dom_rule))); + self.dom_rules.borrow_mut().insert(index, MutNullableHeap::new(Some(&*dom_rule))); Ok((idx)) } - // https://drafts.csswg.org/cssom/#remove-a-css-rule - // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-deleterule // In case of a keyframe rule, index must be valid. pub fn remove_rule(&self, index: u32) -> ErrorResult { let index = index as usize; match self.rules { RulesSource::Rules(ref css_rules) => { - // https://drafts.csswg.org/cssom/#remove-a-css-rule - { - let rules = css_rules.0.read(); - - // Step 1, 2 - if index >= rules.len() { - return Err(Error::IndexSize); - } - - // Step 3 - let ref rule = rules[index]; - - // Step 4 - if let StyleCssRule::Namespace(..) = *rule { - if !CssRules::only_ns_or_import(&rules) { - return Err(Error::InvalidState); - } - } - } - - // Step 5, 6 + css_rules.remove_rule(index)?; let mut dom_rules = self.dom_rules.borrow_mut(); - css_rules.0.write().remove(index); dom_rules[index].get().map(|r| r.detach()); dom_rules.remove(index); Ok(()) |