mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Bug 1364377: Fix inheritance of NAC, and selector-matching of pseudo-implementing NAC. r=bholley
MozReview-Commit-ID: DjSyaWHq1Xj Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>
This commit is contained in:
parent
58253f545b
commit
2ffffcfdce
3 changed files with 59 additions and 8 deletions
|
@ -325,6 +325,21 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the parent element we should inherit from.
|
||||||
|
///
|
||||||
|
/// This is pretty much always the parent element itself, except in the case
|
||||||
|
/// of Gecko's Native Anonymous Content, which may need to find the closest
|
||||||
|
/// non-NAC ancestor.
|
||||||
|
fn inheritance_parent(&self) -> Option<Self> {
|
||||||
|
self.parent_element()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For a given NAC element, return the closest non-NAC ancestor, which is
|
||||||
|
/// guaranteed to exist.
|
||||||
|
fn closest_non_native_anonymous_ancestor(&self) -> Option<Self> {
|
||||||
|
unreachable!("Servo doesn't know about NAC");
|
||||||
|
}
|
||||||
|
|
||||||
/// Get this element's style attribute.
|
/// Get this element's style attribute.
|
||||||
fn style_attribute(&self) -> Option<&Arc<Locked<PropertyDeclarationBlock>>>;
|
fn style_attribute(&self) -> Option<&Arc<Locked<PropertyDeclarationBlock>>>;
|
||||||
|
|
||||||
|
|
|
@ -526,6 +526,32 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
type ConcreteNode = GeckoNode<'le>;
|
type ConcreteNode = GeckoNode<'le>;
|
||||||
type FontMetricsProvider = GeckoFontMetricsProvider;
|
type FontMetricsProvider = GeckoFontMetricsProvider;
|
||||||
|
|
||||||
|
fn inheritance_parent(&self) -> Option<Self> {
|
||||||
|
if self.is_native_anonymous() {
|
||||||
|
return self.closest_non_native_anonymous_ancestor();
|
||||||
|
}
|
||||||
|
return self.parent_element();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn closest_non_native_anonymous_ancestor(&self) -> Option<Self> {
|
||||||
|
debug_assert!(self.is_native_anonymous());
|
||||||
|
let mut parent = match self.parent_element() {
|
||||||
|
Some(e) => e,
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if !parent.is_native_anonymous() {
|
||||||
|
return Some(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent = match parent.parent_element() {
|
||||||
|
Some(p) => p,
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn as_node(&self) -> Self::ConcreteNode {
|
fn as_node(&self) -> Self::ConcreteNode {
|
||||||
unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) }
|
unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,10 @@ use stylist::ApplicableDeclarationBlock;
|
||||||
|
|
||||||
/// The way a style should be inherited.
|
/// The way a style should be inherited.
|
||||||
enum InheritMode {
|
enum InheritMode {
|
||||||
/// Inherit from the parent element, as normal CSS dictates.
|
/// Inherit from the parent element, as normal CSS dictates, _or_ from the
|
||||||
FromParentElement,
|
/// closest non-Native Anonymous element in case this is Native Anonymous
|
||||||
|
/// Content.
|
||||||
|
Normal,
|
||||||
/// Inherit from the primary style, this is used while computing eager
|
/// Inherit from the primary style, this is used while computing eager
|
||||||
/// pseudos, like ::before and ::after when we're traversing the parent.
|
/// pseudos, like ::before and ::after when we're traversing the parent.
|
||||||
FromPrimaryStyle,
|
FromPrimaryStyle,
|
||||||
|
@ -423,8 +425,8 @@ trait PrivateMatchMethods: TElement {
|
||||||
let parent_el;
|
let parent_el;
|
||||||
let parent_data;
|
let parent_data;
|
||||||
let style_to_inherit_from = match inherit_mode {
|
let style_to_inherit_from = match inherit_mode {
|
||||||
InheritMode::FromParentElement => {
|
InheritMode::Normal => {
|
||||||
parent_el = self.parent_element();
|
parent_el = self.inheritance_parent();
|
||||||
parent_data = parent_el.as_ref().and_then(|e| e.borrow_data());
|
parent_data = parent_el.as_ref().and_then(|e| e.borrow_data());
|
||||||
let parent_values = parent_data.as_ref().map(|d| {
|
let parent_values = parent_data.as_ref().map(|d| {
|
||||||
// Sometimes Gecko eagerly styles things without processing
|
// Sometimes Gecko eagerly styles things without processing
|
||||||
|
@ -500,7 +502,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
let inherit_mode = if eager_pseudo_style.is_some() {
|
let inherit_mode = if eager_pseudo_style.is_some() {
|
||||||
InheritMode::FromPrimaryStyle
|
InheritMode::FromPrimaryStyle
|
||||||
} else {
|
} else {
|
||||||
InheritMode::FromParentElement
|
InheritMode::Normal
|
||||||
};
|
};
|
||||||
|
|
||||||
self.cascade_with_rules(context.shared,
|
self.cascade_with_rules(context.shared,
|
||||||
|
@ -623,7 +625,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
&context.thread_local.font_metrics_provider,
|
&context.thread_local.font_metrics_provider,
|
||||||
&without_transition_rules,
|
&without_transition_rules,
|
||||||
primary_style,
|
primary_style,
|
||||||
InheritMode::FromParentElement))
|
InheritMode::Normal))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
|
@ -1002,8 +1004,16 @@ pub trait MatchMethods : TElement {
|
||||||
self.apply_selector_flags(map, element, flags);
|
self.apply_selector_flags(map, element, flags);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let selector_matching_target = match implemented_pseudo {
|
||||||
|
Some(..) => {
|
||||||
|
self.closest_non_native_anonymous_ancestor()
|
||||||
|
.expect("Pseudo-element without non-NAC parent?")
|
||||||
|
},
|
||||||
|
None => *self,
|
||||||
|
};
|
||||||
|
|
||||||
// Compute the primary rule node.
|
// Compute the primary rule node.
|
||||||
*relations = stylist.push_applicable_declarations(self,
|
*relations = stylist.push_applicable_declarations(&selector_matching_target,
|
||||||
Some(bloom),
|
Some(bloom),
|
||||||
style_attribute,
|
style_attribute,
|
||||||
smil_override,
|
smil_override,
|
||||||
|
@ -1448,7 +1458,7 @@ pub trait MatchMethods : TElement {
|
||||||
font_metrics_provider,
|
font_metrics_provider,
|
||||||
&without_animation_rules,
|
&without_animation_rules,
|
||||||
primary_style,
|
primary_style,
|
||||||
InheritMode::FromParentElement)
|
InheritMode::Normal)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue