diff options
author | Cameron McCormack <cam@mcc.id.au> | 2017-06-27 17:14:14 -0700 |
---|---|---|
committer | Cameron McCormack <cam@mcc.id.au> | 2017-06-28 11:58:50 -0700 |
commit | 84c61fa15e69f1b898483c6a7c80e6c96daaf6ed (patch) | |
tree | c1f200d993de590b8b4a8b2e0af8d3b5be5c96bc | |
parent | 71f1f4b508e949e9acdd17a9fe50a8717dfea465 (diff) | |
download | servo-84c61fa15e69f1b898483c6a7c80e6c96daaf6ed.tar.gz servo-84c61fa15e69f1b898483c6a7c80e6c96daaf6ed.zip |
style: Look to base XBL bindings for content too. r=bholley
MozReview-Commit-ID: DFep2S6jnWf
-rw-r--r-- | components/style/gecko/wrapper.rs | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index cc980fd86d1..bfcbee65608 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -373,10 +373,11 @@ impl<'a> Iterator for GeckoChildrenIterator<'a> { } /// A Simple wrapper over a non-null Gecko `nsXBLBinding` pointer. +#[derive(Clone, Copy)] pub struct GeckoXBLBinding<'lb>(pub &'lb RawGeckoXBLBinding); impl<'lb> GeckoXBLBinding<'lb> { - fn base_binding(&self) -> Option<GeckoXBLBinding> { + fn base_binding(&self) -> Option<Self> { unsafe { self.0.mNextBinding.mRawPtr.as_ref().map(GeckoXBLBinding) } } @@ -388,6 +389,21 @@ impl<'lb> GeckoXBLBinding<'lb> { unsafe { bindings::Gecko_XBLBinding_InheritsStyle(self.0) } } + // This duplicates the logic in Gecko's + // nsBindingManager::GetBindingWithContent. + fn get_binding_with_content(&self) -> Option<Self> { + let mut binding = *self; + loop { + if !binding.anon_content().is_null() { + return Some(binding); + } + binding = match binding.base_binding() { + Some(b) => b, + None => return None, + }; + } + } + // Implements Gecko's nsXBLBinding::WalkRules(). fn get_declarations_for<E, V>(&self, element: &E, @@ -480,10 +496,25 @@ impl<'le> GeckoElement<'le> { unsafe { slots.as_ref() } } + #[inline] fn get_xbl_binding(&self) -> Option<GeckoXBLBinding> { + if self.flags() & (structs::NODE_MAY_BE_IN_BINDING_MNGR as u32) == 0 { + return None; + } + unsafe { bindings::Gecko_GetXBLBinding(self.0).map(GeckoXBLBinding) } } + #[inline] + fn get_xbl_binding_with_content(&self) -> Option<GeckoXBLBinding> { + self.get_xbl_binding().and_then(|b| b.get_binding_with_content()) + } + + #[inline] + fn has_xbl_binding_with_content(&self) -> bool { + !self.get_xbl_binding_with_content().is_none() + } + fn get_xbl_binding_parent(&self) -> Option<Self> { unsafe { bindings::Gecko_GetBindingParent(self.0).map(GeckoElement) } } @@ -1061,16 +1092,9 @@ impl<'le> TElement for GeckoElement<'le> { } fn xbl_binding_anonymous_content(&self) -> Option<GeckoNode<'le>> { - if self.flags() & (structs::NODE_MAY_BE_IN_BINDING_MNGR as u32) == 0 { - return None; - } - - let anon_content = match self.get_xbl_binding() { - Some(binding) => binding.anon_content(), - None => return None, - }; - - unsafe { anon_content.as_ref().map(GeckoNode::from_content) } + self.get_xbl_binding_with_content() + .map(|b| unsafe { b.anon_content().as_ref() }.unwrap()) + .map(GeckoNode::from_content) } fn get_css_transitions_info(&self) |