aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-05-12 07:25:00 -0500
committerGitHub <noreply@github.com>2017-05-12 07:25:00 -0500
commitdb080cea97bd88ef4081ff244b5cf0707cbb5d48 (patch)
tree2a1a604a8d781ffb2873a2ea366d0f512e556d49
parent1faac6a6e640e9af1890debfbecce60c8cdf37a9 (diff)
parent2ffffcfdcefbf5815f72c3d90ec7311282791f86 (diff)
downloadservo-db080cea97bd88ef4081ff244b5cf0707cbb5d48.tar.gz
servo-db080cea97bd88ef4081ff244b5cf0707cbb5d48.zip
Auto merge of #16834 - emilio:nac-is-a-pain, r=bholley
Bug 1364377: Fix inheritance of NAC, and selector-matching of pseudo-implementing NAC. <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16834) <!-- Reviewable:end -->
-rw-r--r--components/style/dom.rs15
-rw-r--r--components/style/gecko/wrapper.rs26
-rw-r--r--components/style/matching.rs26
3 files changed, 59 insertions, 8 deletions
diff --git a/components/style/dom.rs b/components/style/dom.rs
index c4647928efb..4dab32eba22 100644
--- a/components/style/dom.rs
+++ b/components/style/dom.rs
@@ -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.
fn style_attribute(&self) -> Option<&Arc<Locked<PropertyDeclarationBlock>>>;
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs
index 4ac047e41d8..5461bd7768e 100644
--- a/components/style/gecko/wrapper.rs
+++ b/components/style/gecko/wrapper.rs
@@ -526,6 +526,32 @@ impl<'le> TElement for GeckoElement<'le> {
type ConcreteNode = GeckoNode<'le>;
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 {
unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) }
}
diff --git a/components/style/matching.rs b/components/style/matching.rs
index f8fbfd493c9..40c2661d245 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -33,8 +33,10 @@ use stylist::ApplicableDeclarationBlock;
/// The way a style should be inherited.
enum InheritMode {
- /// Inherit from the parent element, as normal CSS dictates.
- FromParentElement,
+ /// Inherit from the parent element, as normal CSS dictates, _or_ from the
+ /// closest non-Native Anonymous element in case this is Native Anonymous
+ /// Content.
+ Normal,
/// Inherit from the primary style, this is used while computing eager
/// pseudos, like ::before and ::after when we're traversing the parent.
FromPrimaryStyle,
@@ -423,8 +425,8 @@ trait PrivateMatchMethods: TElement {
let parent_el;
let parent_data;
let style_to_inherit_from = match inherit_mode {
- InheritMode::FromParentElement => {
- parent_el = self.parent_element();
+ InheritMode::Normal => {
+ parent_el = self.inheritance_parent();
parent_data = parent_el.as_ref().and_then(|e| e.borrow_data());
let parent_values = parent_data.as_ref().map(|d| {
// Sometimes Gecko eagerly styles things without processing
@@ -500,7 +502,7 @@ trait PrivateMatchMethods: TElement {
let inherit_mode = if eager_pseudo_style.is_some() {
InheritMode::FromPrimaryStyle
} else {
- InheritMode::FromParentElement
+ InheritMode::Normal
};
self.cascade_with_rules(context.shared,
@@ -623,7 +625,7 @@ trait PrivateMatchMethods: TElement {
&context.thread_local.font_metrics_provider,
&without_transition_rules,
primary_style,
- InheritMode::FromParentElement))
+ InheritMode::Normal))
}
#[cfg(feature = "gecko")]
@@ -1002,8 +1004,16 @@ pub trait MatchMethods : TElement {
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.
- *relations = stylist.push_applicable_declarations(self,
+ *relations = stylist.push_applicable_declarations(&selector_matching_target,
Some(bloom),
style_attribute,
smil_override,
@@ -1448,7 +1458,7 @@ pub trait MatchMethods : TElement {
font_metrics_provider,
&without_animation_rules,
primary_style,
- InheritMode::FromParentElement)
+ InheritMode::Normal)
}
}