aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCameron McCormack <cam@mcc.id.au>2017-06-27 17:14:14 -0700
committerCameron McCormack <cam@mcc.id.au>2017-06-28 11:58:50 -0700
commit84c61fa15e69f1b898483c6a7c80e6c96daaf6ed (patch)
treec1f200d993de590b8b4a8b2e0af8d3b5be5c96bc
parent71f1f4b508e949e9acdd17a9fe50a8717dfea465 (diff)
downloadservo-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.rs46
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)