diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/cssrulelist.rs | 44 | ||||
-rw-r--r-- | components/script/dom/cssstylesheet.rs | 2 |
2 files changed, 34 insertions, 12 deletions
diff --git a/components/script/dom/cssrulelist.rs b/components/script/dom/cssrulelist.rs index f8cf59ad670..14f85bc0ab6 100644 --- a/components/script/dom/cssrulelist.rs +++ b/components/script/dom/cssrulelist.rs @@ -47,7 +47,8 @@ impl CSSRuleList { } // https://drafts.csswg.org/cssom/#insert-a-css-rule - pub fn insert_rule(&self, rule: &str, idx: u32) -> Fallible<u32> { + 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() { @@ -61,22 +62,41 @@ impl CSSRuleList { let doc = window.Document(); let index = idx as usize; - // Step 1, 2 - // XXXManishearth get url from correct location - // XXXManishearth should we also store the namespace map? - let new_rule = try!(StyleCssRule::from_str(&rule, Origin::Author, - doc.url().clone(), - ParserContextExtraData::default()) - .map_err(|_| Error::Syntax)); - { + let new_rule = { let rules = self.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); } - // XXXManishearth Step 5 (throw HierarchyRequestError in invalid situations) + 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 { @@ -84,7 +104,9 @@ impl CSSRuleList { return Err(Error::InvalidState); } } - } + + new_rule + }; insert(&mut self.rules.0.write(), index, new_rule.clone()); let dom_rule = CSSRule::new_specific(&window, &self.sheet, new_rule); diff --git a/components/script/dom/cssstylesheet.rs b/components/script/dom/cssstylesheet.rs index 079199c2e6e..1a99767d1a0 100644 --- a/components/script/dom/cssstylesheet.rs +++ b/components/script/dom/cssstylesheet.rs @@ -59,7 +59,7 @@ impl CSSStyleSheetMethods for CSSStyleSheet { // https://drafts.csswg.org/cssom/#dom-cssstylesheet-insertrule fn InsertRule(&self, rule: DOMString, index: u32) -> Fallible<u32> { // XXXManishearth check origin clean flag - self.rulelist().insert_rule(&rule, index) + self.rulelist().insert_rule(&rule, index, /* nested */ false) } // https://drafts.csswg.org/cssom/#dom-cssstylesheet-deleterule |