New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CSSOM: Whole ton of things #14241
Merged
+656
−192
Merged
CSSOM: Whole ton of things #14241
Changes from 1 commit
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
1d20d75
Add insertRule() and deleteRule() on CSSStyleSheet
Manishearth 972e9ac
Add support for LinkStyle's sheet getter on <style> and <link>
Manishearth 262408d
Update test expectations
Manishearth 2793d5f
Handle parser state in CSSOM insert_rule
Manishearth 52a3a71
Add support for keyframe-backed CSSRules, CSSKeyframesRule.cssRules a…
Manishearth 53c9966
Make parent stylesheet optional for CSSRules
Manishearth cada5d7
Transitively deparent on removal
Manishearth a9cd17a
Add CSSGroupingRule.{cssRules, insertRule(), deleteRule()}
Manishearth 6444209
Add CSSKeyframesRule.{findRule, deleteRule, appendRule}
Manishearth 8108fc4
Add CSSNamespaceRule.{namespaceURI, prefix}
Manishearth 0e19f45
Fixup error from #14238
Manishearth 18742e7
Update test expectations
Manishearth 95cbf1a
Address review comments
Manishearth File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.
Add insertRule() and deleteRule() on CSSStyleSheet
- Loading branch information
commit 1d20d75cb2e8153768d177e0e9f1f6f054816014
| @@ -2,14 +2,19 @@ | ||
| * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
|
|
||
| use dom::bindings::cell::DOMRefCell; | ||
| use dom::bindings::codegen::Bindings::CSSRuleListBinding; | ||
| use dom::bindings::codegen::Bindings::CSSRuleListBinding::CSSRuleListMethods; | ||
| use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; | ||
| use dom::bindings::error::{Error, ErrorResult, Fallible}; | ||
| use dom::bindings::js::{JS, MutNullableHeap, Root}; | ||
| use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object}; | ||
| use dom::cssrule::CSSRule; | ||
| use dom::cssstylesheet::CSSStyleSheet; | ||
| use dom::window::Window; | ||
| use style::stylesheets::CssRules; | ||
| use style::parser::ParserContextExtraData; | ||
| use style::stylesheets::{CssRules, Origin}; | ||
| use style::stylesheets::CssRule as StyleCssRule; | ||
|
|
||
| no_jsmanaged_fields!(CssRules); | ||
|
|
||
| @@ -19,7 +24,7 @@ pub struct CSSRuleList { | ||
| sheet: JS<CSSStyleSheet>, | ||
| #[ignore_heap_size_of = "Arc"] | ||
| rules: CssRules, | ||
| dom_rules: Vec<MutNullableHeap<JS<CSSRule>>> | ||
| dom_rules: DOMRefCell<Vec<MutNullableHeap<JS<CSSRule>>>> | ||
| } | ||
|
|
||
| impl CSSRuleList { | ||
| @@ -30,7 +35,7 @@ impl CSSRuleList { | ||
| reflector_: Reflector::new(), | ||
| sheet: JS::from_ref(sheet), | ||
| rules: rules, | ||
| dom_rules: dom_rules, | ||
| dom_rules: DOMRefCell::new(dom_rules), | ||
| } | ||
| } | ||
|
|
||
| @@ -40,12 +45,83 @@ impl CSSRuleList { | ||
| window, | ||
| CSSRuleListBinding::Wrap) | ||
| } | ||
|
|
||
| // https://drafts.csswg.org/cssom/#insert-a-css-rule | ||
| pub fn insert_rule(&self, rule: &str, idx: u32) -> Fallible<u32> { | ||
| /// 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 global = self.global(); | ||
| let window = global.as_window(); | ||
| 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 rules = self.rules.0.read(); | ||
| // Step 3, 4 | ||
| if index > rules.len() { | ||
| return Err(Error::IndexSize); | ||
| } | ||
|
|
||
| // XXXManishearth Step 5 (throw HierarchyRequestError in invalid situations) | ||
Manishearth
Author
Member
|
||
|
|
||
| // Step 6 | ||
| if let StyleCssRule::Namespace(..) = new_rule { | ||
| if !CssRules::only_ns_or_import(&rules) { | ||
| return Err(Error::InvalidState); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| insert(&mut self.rules.0.write(), index, new_rule.clone()); | ||
| let dom_rule = CSSRule::new_specific(&window, &self.sheet, new_rule); | ||
| insert(&mut self.dom_rules.borrow_mut(), | ||
| index, MutNullableHeap::new(Some(&*dom_rule))); | ||
| Ok((idx)) | ||
| } | ||
|
|
||
| // https://drafts.csswg.org/cssom/#remove-a-css-rule | ||
| pub fn remove_rule(&self, index: u32) -> ErrorResult { | ||
| let index = index as usize; | ||
|
|
||
| { | ||
| let rules = self.rules.0.read(); | ||
| if index >= rules.len() { | ||
| return Err(Error::IndexSize); | ||
| } | ||
| let ref rule = rules[index]; | ||
| if let StyleCssRule::Namespace(..) = *rule { | ||
| if !CssRules::only_ns_or_import(&rules) { | ||
| return Err(Error::InvalidState); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| let mut dom_rules = self.dom_rules.borrow_mut(); | ||
| self.rules.0.write().remove(index); | ||
| dom_rules[index].get().map(|r| r.disown()); | ||
| dom_rules.remove(index); | ||
| Ok(()) | ||
| } | ||
| } | ||
|
|
||
| impl CSSRuleListMethods for CSSRuleList { | ||
| // https://drafts.csswg.org/cssom/#ref-for-dom-cssrulelist-item-1 | ||
| fn Item(&self, idx: u32) -> Option<Root<CSSRule>> { | ||
| self.dom_rules.get(idx as usize).map(|rule| { | ||
| self.dom_rules.borrow().get(idx as usize).map(|rule| { | ||
| rule.or_init(|| { | ||
| CSSRule::new_specific(self.global().as_window(), | ||
| &self.sheet, | ||
| @@ -56,7 +132,7 @@ impl CSSRuleListMethods for CSSRuleList { | ||
|
|
||
| // https://drafts.csswg.org/cssom/#dom-cssrulelist-length | ||
| fn Length(&self) -> u32 { | ||
| self.dom_rules.len() as u32 | ||
| self.dom_rules.borrow().len() as u32 | ||
| } | ||
|
|
||
| // check-tidy: no specs after this line | ||
ProTip!
Use n and p to navigate between commits in a pull request.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
I'm considering just filing issues for these