diff options
-rw-r--r-- | components/script/dom/csskeyframerule.rs | 50 | ||||
-rw-r--r-- | components/script/dom/csskeyframesrule.rs | 23 | ||||
-rw-r--r-- | components/script/dom/cssrule.rs | 3 | ||||
-rw-r--r-- | components/script/dom/cssrulelist.rs | 67 | ||||
-rw-r--r-- | components/script/dom/cssstylesheet.rs | 5 | ||||
-rw-r--r-- | components/script/dom/mod.rs | 1 | ||||
-rw-r--r-- | components/script/dom/webidls/CSSKeyframeRule.webidl | 10 | ||||
-rw-r--r-- | components/script/dom/webidls/CSSKeyframesRule.webidl | 2 |
8 files changed, 143 insertions, 18 deletions
diff --git a/components/script/dom/csskeyframerule.rs b/components/script/dom/csskeyframerule.rs new file mode 100644 index 00000000000..1cebaf706a7 --- /dev/null +++ b/components/script/dom/csskeyframerule.rs @@ -0,0 +1,50 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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::codegen::Bindings::CSSKeyframeRuleBinding; +use dom::bindings::js::Root; +use dom::bindings::reflector::reflect_dom_object; +use dom::bindings::str::DOMString; +use dom::cssrule::{CSSRule, SpecificCSSRule}; +use dom::cssstylesheet::CSSStyleSheet; +use dom::window::Window; +use parking_lot::RwLock; +use std::sync::Arc; +use style::keyframes::Keyframe; + +#[dom_struct] +pub struct CSSKeyframeRule { + cssrule: CSSRule, + #[ignore_heap_size_of = "Arc"] + keyframerule: Arc<RwLock<Keyframe>>, +} + +impl CSSKeyframeRule { + fn new_inherited(parent: &CSSStyleSheet, keyframerule: Arc<RwLock<Keyframe>>) -> CSSKeyframeRule { + CSSKeyframeRule { + cssrule: CSSRule::new_inherited(parent), + keyframerule: keyframerule, + } + } + + #[allow(unrooted_must_root)] + pub fn new(window: &Window, parent: &CSSStyleSheet, + keyframerule: Arc<RwLock<Keyframe>>) -> Root<CSSKeyframeRule> { + reflect_dom_object(box CSSKeyframeRule::new_inherited(parent, keyframerule), + window, + CSSKeyframeRuleBinding::Wrap) + } +} + +impl SpecificCSSRule for CSSKeyframeRule { + fn ty(&self) -> u16 { + use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleConstants; + CSSRuleConstants::KEYFRAME_RULE + } + + fn get_css(&self) -> DOMString { + // self.keyframerule.read().to_css_string().into() + "".into() + } +} diff --git a/components/script/dom/csskeyframesrule.rs b/components/script/dom/csskeyframesrule.rs index 138c8b20558..5a14f2c3acd 100644 --- a/components/script/dom/csskeyframesrule.rs +++ b/components/script/dom/csskeyframesrule.rs @@ -3,10 +3,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::Bindings::CSSKeyframesRuleBinding; -use dom::bindings::js::Root; -use dom::bindings::reflector::reflect_dom_object; +use dom::bindings::codegen::Bindings::CSSKeyframesRuleBinding::CSSKeyframesRuleMethods; +use dom::bindings::codegen::Bindings::CSSRuleBinding::CSSRuleMethods; +use dom::bindings::inheritance::Castable; +use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::reflector::{Reflectable, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::cssrule::{CSSRule, SpecificCSSRule}; +use dom::cssrulelist::{CSSRuleList, RulesSource}; use dom::cssstylesheet::CSSStyleSheet; use dom::window::Window; use parking_lot::RwLock; @@ -19,6 +23,7 @@ pub struct CSSKeyframesRule { cssrule: CSSRule, #[ignore_heap_size_of = "Arc"] keyframesrule: Arc<RwLock<KeyframesRule>>, + rulelist: MutNullableHeap<JS<CSSRuleList>>, } impl CSSKeyframesRule { @@ -26,6 +31,7 @@ impl CSSKeyframesRule { CSSKeyframesRule { cssrule: CSSRule::new_inherited(parent), keyframesrule: keyframesrule, + rulelist: MutNullableHeap::new(None), } } @@ -36,6 +42,19 @@ impl CSSKeyframesRule { window, CSSKeyframesRuleBinding::Wrap) } + + fn rulelist(&self) -> Root<CSSRuleList> { + self.rulelist.or_init(|| CSSRuleList::new(self.global().as_window(), + // temporary unwrap + &self.upcast::<CSSRule>().GetParentStyleSheet().unwrap(), + RulesSource::Keyframes(self.keyframesrule.clone()))) + } +} + +impl CSSKeyframesRuleMethods for CSSKeyframesRule { + fn CssRules(&self) -> Root<CSSRuleList> { + self.rulelist() + } } impl SpecificCSSRule for CSSKeyframesRule { diff --git a/components/script/dom/cssrule.rs b/components/script/dom/cssrule.rs index 7ed26bce2c7..2a2e3cf3165 100644 --- a/components/script/dom/cssrule.rs +++ b/components/script/dom/cssrule.rs @@ -10,6 +10,7 @@ use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::cssfontfacerule::CSSFontFaceRule; use dom::csskeyframesrule::CSSKeyframesRule; +use dom::csskeyframerule::CSSKeyframeRule; use dom::cssmediarule::CSSMediaRule; use dom::cssnamespacerule::CSSNamespaceRule; use dom::cssstylerule::CSSStyleRule; @@ -54,6 +55,8 @@ impl CSSRule { rule as &SpecificCSSRule } else if let Some(rule) = self.downcast::<CSSViewportRule>() { rule as &SpecificCSSRule + } else if let Some(rule) = self.downcast::<CSSKeyframeRule>() { + rule as &SpecificCSSRule } else { unreachable!() } diff --git a/components/script/dom/cssrulelist.rs b/components/script/dom/cssrulelist.rs index 14f85bc0ab6..902f3c8a189 100644 --- a/components/script/dom/cssrulelist.rs +++ b/components/script/dom/cssrulelist.rs @@ -10,27 +10,43 @@ 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::csskeyframerule::CSSKeyframeRule; use dom::cssstylesheet::CSSStyleSheet; use dom::window::Window; +use parking_lot::RwLock; +use std::sync::Arc; use style::parser::ParserContextExtraData; -use style::stylesheets::{CssRules, Origin}; +use style::stylesheets::{CssRules, KeyframesRule, Origin}; use style::stylesheets::CssRule as StyleCssRule; -no_jsmanaged_fields!(CssRules); +no_jsmanaged_fields!(RulesSource); #[dom_struct] pub struct CSSRuleList { reflector_: Reflector, sheet: JS<CSSStyleSheet>, #[ignore_heap_size_of = "Arc"] - rules: CssRules, + rules: RulesSource, dom_rules: DOMRefCell<Vec<MutNullableHeap<JS<CSSRule>>>> } +pub enum RulesSource { + Rules(CssRules), + Keyframes(Arc<RwLock<KeyframesRule>>), +} + impl CSSRuleList { #[allow(unrooted_must_root)] - pub fn new_inherited(sheet: &CSSStyleSheet, rules: CssRules) -> CSSRuleList { - let dom_rules = rules.0.read().iter().map(|_| MutNullableHeap::new(None)).collect(); + pub fn new_inherited(sheet: &CSSStyleSheet, rules: RulesSource) -> CSSRuleList { + let dom_rules = match rules { + RulesSource::Rules(ref rules) => { + rules.0.read().iter().map(|_| MutNullableHeap::new(None)).collect() + } + RulesSource::Keyframes(ref rules) => { + rules.read().keyframes.iter().map(|_| MutNullableHeap::new(None)).collect() + } + }; + CSSRuleList { reflector_: Reflector::new(), sheet: JS::from_ref(sheet), @@ -40,7 +56,7 @@ impl CSSRuleList { } #[allow(unrooted_must_root)] - pub fn new(window: &Window, sheet: &CSSStyleSheet, rules: CssRules) -> Root<CSSRuleList> { + pub fn new(window: &Window, sheet: &CSSStyleSheet, rules: RulesSource) -> Root<CSSRuleList> { reflect_dom_object(box CSSRuleList::new_inherited(sheet, rules), window, CSSRuleListBinding::Wrap) @@ -57,6 +73,13 @@ impl CSSRuleList { vec.insert(index, item); } } + + let css_rules = if let RulesSource::Rules(ref rules) = self.rules { + rules + } else { + panic!("Called insert_rule on non-CssRule-backed CSSRuleList"); + }; + let global = self.global(); let window = global.as_window(); let doc = window.Document(); @@ -64,7 +87,7 @@ impl CSSRuleList { let new_rule = { - let rules = self.rules.0.read(); + let rules = css_rules.0.read(); let state = if nested { None } else { @@ -108,7 +131,7 @@ impl CSSRuleList { new_rule }; - insert(&mut self.rules.0.write(), index, new_rule.clone()); + insert(&mut css_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))); @@ -119,8 +142,14 @@ impl CSSRuleList { pub fn remove_rule(&self, index: u32) -> ErrorResult { let index = index as usize; + let css_rules = if let RulesSource::Rules(ref rules) = self.rules { + rules + } else { + panic!("Called remove_rule on non-CssRule-backed CSSRuleList"); + }; + { - let rules = self.rules.0.read(); + let rules = css_rules.0.read(); if index >= rules.len() { return Err(Error::IndexSize); } @@ -133,7 +162,7 @@ impl CSSRuleList { } let mut dom_rules = self.dom_rules.borrow_mut(); - self.rules.0.write().remove(index); + css_rules.0.write().remove(index); dom_rules[index].get().map(|r| r.disown()); dom_rules.remove(index); Ok(()) @@ -145,9 +174,21 @@ impl CSSRuleListMethods for CSSRuleList { fn Item(&self, idx: u32) -> Option<Root<CSSRule>> { self.dom_rules.borrow().get(idx as usize).map(|rule| { rule.or_init(|| { - CSSRule::new_specific(self.global().as_window(), - &self.sheet, - self.rules.0.read()[idx as usize].clone()) + match self.rules { + RulesSource::Rules(ref rules) => { + CSSRule::new_specific(self.global().as_window(), + &self.sheet, + rules.0.read()[idx as usize].clone()) + } + RulesSource::Keyframes(ref rules) => { + Root::upcast(CSSKeyframeRule::new(self.global().as_window(), + &self.sheet, + rules.read() + .keyframes[idx as usize] + .clone())) + } + } + }) }) } diff --git a/components/script/dom/cssstylesheet.rs b/components/script/dom/cssstylesheet.rs index 1a99767d1a0..c8f801a0417 100644 --- a/components/script/dom/cssstylesheet.rs +++ b/components/script/dom/cssstylesheet.rs @@ -8,7 +8,7 @@ use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::js::{JS, Root, MutNullableHeap}; use dom::bindings::reflector::{reflect_dom_object, Reflectable}; use dom::bindings::str::DOMString; -use dom::cssrulelist::CSSRuleList; +use dom::cssrulelist::{CSSRuleList, RulesSource}; use dom::stylesheet::StyleSheet; use dom::window::Window; use std::sync::Arc; @@ -45,7 +45,8 @@ impl CSSStyleSheet { fn rulelist(&self) -> Root<CSSRuleList> { self.rulelist.or_init(|| CSSRuleList::new(self.global().as_window(), self, - self.style_stylesheet.rules.clone())) + RulesSource::Rules(self.style_stylesheet + .rules.clone()))) } } diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 05ec1963a20..5895e0c08cb 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -245,6 +245,7 @@ pub mod css; pub mod cssfontfacerule; pub mod cssgroupingrule; pub mod csskeyframesrule; +pub mod csskeyframerule; pub mod cssmediarule; pub mod cssnamespacerule; pub mod cssrule; diff --git a/components/script/dom/webidls/CSSKeyframeRule.webidl b/components/script/dom/webidls/CSSKeyframeRule.webidl new file mode 100644 index 00000000000..5458440be6d --- /dev/null +++ b/components/script/dom/webidls/CSSKeyframeRule.webidl @@ -0,0 +1,10 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +// https://drafts.csswg.org/css-animations/#interface-csskeyframerule +[Exposed=Window] +interface CSSKeyframeRule : CSSRule { + // attribute DOMString keyText; + // readonly attribute CSSStyleDeclaration style; +}; diff --git a/components/script/dom/webidls/CSSKeyframesRule.webidl b/components/script/dom/webidls/CSSKeyframesRule.webidl index db152d72850..3e7c69f6d08 100644 --- a/components/script/dom/webidls/CSSKeyframesRule.webidl +++ b/components/script/dom/webidls/CSSKeyframesRule.webidl @@ -6,7 +6,7 @@ [Exposed=Window] interface CSSKeyframesRule : CSSRule { // attribute DOMString name; - // readonly attribute CSSRuleList cssRules; + readonly attribute CSSRuleList cssRules; // void appendRule(DOMString rule); // void deleteRule(DOMString select); |