From cada5d7c0354d82c0ba6053f772eb5b8b3f6d954 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 16 Nov 2016 17:48:54 -0800 Subject: [PATCH] Transitively deparent on removal Chrome and Firefox do this already, probably a spec oversight --- components/script/dom/csskeyframesrule.rs | 7 ++++++- components/script/dom/cssrule.rs | 20 ++++++++++++++++---- components/script/dom/cssrulelist.rs | 11 +++++++++-- components/script/dom/mod.rs | 2 +- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/components/script/dom/csskeyframesrule.rs b/components/script/dom/csskeyframesrule.rs index 79cd7ce3e6f5..444ae8a5424d 100644 --- a/components/script/dom/csskeyframesrule.rs +++ b/components/script/dom/csskeyframesrule.rs @@ -55,7 +55,8 @@ impl CSSKeyframesRule { } impl CSSKeyframesRuleMethods for CSSKeyframesRule { - fn CssRules(&self) -> Root { + // https://drafts.csswg.org/css-animations/#dom-csskeyframesrule-cssrules + fn CssRules(&self) -> Root { self.rulelist() } } @@ -69,4 +70,8 @@ impl SpecificCSSRule for CSSKeyframesRule { fn get_css(&self) -> DOMString { self.keyframesrule.read().to_css_string().into() } + + fn deparent_children(&self) { + self.rulelist.get().map(|list| list.deparent_all()); + } } diff --git a/components/script/dom/cssrule.rs b/components/script/dom/cssrule.rs index 7b1edcab045a..ca1e52b77f0f 100644 --- a/components/script/dom/cssrule.rs +++ b/components/script/dom/cssrule.rs @@ -9,8 +9,8 @@ use dom::bindings::js::{JS, MutNullableHeap, Root}; 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::csskeyframesrule::CSSKeyframesRule; use dom::cssmediarule::CSSMediaRule; use dom::cssnamespacerule::CSSNamespaceRule; use dom::cssstylerule::CSSStyleRule; @@ -78,10 +78,18 @@ impl CSSRule { } /// Sets owner sheet/rule to null - pub fn disown(&self) { - self.parent.set(None); + pub fn detach(&self) { + self.deparent(); // should set parent rule to None when we add parent rule support - // Should we disown children as well? (https://github.com/w3c/csswg-drafts/issues/722) + } + + /// Sets owner sheet to null (and does the same for all children) + pub fn deparent(&self) { + self.parent.set(None); + // https://github.com/w3c/csswg-drafts/issues/722 + // Spec doesn't ask us to do this, but it makes sense + // and browsers implement this behavior + self.as_specific().deparent_children(); } } @@ -110,4 +118,8 @@ impl CSSRuleMethods for CSSRule { pub trait SpecificCSSRule { fn ty(&self) -> u16; fn get_css(&self) -> DOMString; + /// Remove CSSStyleSheet parent from all transitive children + fn deparent_children(&self) { + // most CSSRules do nothing here + } } diff --git a/components/script/dom/cssrulelist.rs b/components/script/dom/cssrulelist.rs index ebdea9f2ca02..f7969aeb9845 100644 --- a/components/script/dom/cssrulelist.rs +++ b/components/script/dom/cssrulelist.rs @@ -9,8 +9,8 @@ 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::csskeyframerule::CSSKeyframeRule; +use dom::cssrule::CSSRule; use dom::cssstylesheet::CSSStyleSheet; use dom::window::Window; use parking_lot::RwLock; @@ -166,10 +166,17 @@ impl CSSRuleList { let mut dom_rules = self.dom_rules.borrow_mut(); css_rules.0.write().remove(index); - dom_rules[index].get().map(|r| r.disown()); + dom_rules[index].get().map(|r| r.detach()); dom_rules.remove(index); Ok(()) } + + // Remove parent stylesheets from all children + pub fn deparent_all(&self) { + for rule in self.dom_rules.borrow().iter() { + rule.get().map(|r| Root::upcast(r).deparent()); + } + } } impl CSSRuleListMethods for CSSRuleList { diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 5895e0c08cbd..23209d89e079 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -244,8 +244,8 @@ pub mod crypto; pub mod css; pub mod cssfontfacerule; pub mod cssgroupingrule; -pub mod csskeyframesrule; pub mod csskeyframerule; +pub mod csskeyframesrule; pub mod cssmediarule; pub mod cssnamespacerule; pub mod cssrule;