Fix style computation for first-letter pseudo-elements with inline ancestors.

We should inherit from the inline, not its parent block.

Gecko bug 1324618 part 10 servo bits: https://bugzilla.mozilla.org/show_bug.cgi?id=1324618
This commit is contained in:
Boris Zbarsky 2017-06-26 23:29:18 -07:00
parent d40e27d6e5
commit 746f245f32
3 changed files with 63 additions and 7 deletions

View file

@ -2654,6 +2654,8 @@ extern "C" {
pub fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed, pub fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed,
pseudo_type: CSSPseudoElementType, pseudo_type: CSSPseudoElementType,
is_probe: bool, is_probe: bool,
inherited_style:
ServoComputedValuesBorrowedOrNull,
set: RawServoStyleSetBorrowed) set: RawServoStyleSetBorrowed)
-> ServoComputedValuesStrong; -> ServoComputedValuesStrong;
} }

View file

@ -685,10 +685,28 @@ impl Stylist {
where E: TElement, where E: TElement,
{ {
let rule_node = let rule_node =
match self.lazy_pseudo_rules(guards, element, pseudo, rule_inclusion) { self.lazy_pseudo_rules(guards, element, pseudo, rule_inclusion);
Some(rule_node) => rule_node, self.compute_pseudo_element_style_with_rulenode(rule_node.as_ref(),
None => return None guards,
}; parent_style,
font_metrics)
}
/// Computes a pseudo-element style lazily using the given rulenode. This
/// can be used for truly lazy pseudo-elements or to avoid redoing selector
/// matching for eager pseudo-elements when we need to recompute their style
/// with a new parent style.
pub fn compute_pseudo_element_style_with_rulenode(&self,
rule_node: Option<&StrongRuleNode>,
guards: &StylesheetGuards,
parent_style: &ComputedValues,
font_metrics: &FontMetricsProvider)
-> Option<Arc<ComputedValues>>
{
let rule_node = match rule_node {
Some(rule_node) => rule_node,
None => return None
};
// Read the comment on `precomputed_values_for_pseudo` to see why it's // Read the comment on `precomputed_values_for_pseudo` to see why it's
// difficult to assert that display: contents nodes never arrive here // difficult to assert that display: contents nodes never arrive here
@ -697,7 +715,7 @@ impl Stylist {
// Bug 1364242: We need to add visited support for lazy pseudos // Bug 1364242: We need to add visited support for lazy pseudos
let computed = let computed =
properties::cascade(&self.device, properties::cascade(&self.device,
&rule_node, rule_node,
guards, guards,
Some(parent_style), Some(parent_style),
Some(parent_style), Some(parent_style),

View file

@ -1447,6 +1447,7 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
pub extern "C" fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed, pub extern "C" fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed,
pseudo_type: CSSPseudoElementType, pseudo_type: CSSPseudoElementType,
is_probe: bool, is_probe: bool,
inherited_style: ServoComputedValuesBorrowedOrNull,
raw_data: RawServoStyleSetBorrowed) raw_data: RawServoStyleSetBorrowed)
-> ServoComputedValuesStrong -> ServoComputedValuesStrong
{ {
@ -1478,6 +1479,7 @@ pub extern "C" fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed,
&pseudo, &pseudo,
RuleInclusion::All, RuleInclusion::All,
&data.styles, &data.styles,
ComputedValues::arc_from_borrowed(&inherited_style).map(|v| v.as_ref()),
&*doc_data, &*doc_data,
is_probe is_probe
); );
@ -1517,13 +1519,47 @@ fn get_pseudo_style(
pseudo: &PseudoElement, pseudo: &PseudoElement,
rule_inclusion: RuleInclusion, rule_inclusion: RuleInclusion,
styles: &ElementStyles, styles: &ElementStyles,
inherited_styles: Option<&ComputedValues>,
doc_data: &PerDocumentStyleDataImpl, doc_data: &PerDocumentStyleDataImpl,
is_probe: bool, is_probe: bool,
) -> Option<Arc<ComputedValues>> { ) -> Option<Arc<ComputedValues>> {
let style = match pseudo.cascade_type() { let style = match pseudo.cascade_type() {
PseudoElementCascadeType::Eager => styles.pseudos.get(&pseudo).map(|s| s.clone()), PseudoElementCascadeType::Eager => {
match *pseudo {
PseudoElement::FirstLetter => {
// inherited_styles can be None when doing lazy resolution
// (e.g. for computed style) or when probing. In that case
// we just inherit from our element, which is what Gecko
// does in that situation. What should actually happen in
// the computed style case is a bit unclear.
let inherited_styles =
inherited_styles.unwrap_or(styles.primary());
let guards = StylesheetGuards::same(guard);
let metrics = get_metrics_provider_for_product();
let rule_node = match styles.pseudos.get(&pseudo) {
Some(styles) => styles.rules.as_ref(),
None => None,
};
doc_data.stylist
.compute_pseudo_element_style_with_rulenode(
rule_node,
&guards,
inherited_styles,
&metrics)
},
_ => {
debug_assert!(inherited_styles.is_none() ||
ptr::eq(inherited_styles.unwrap(),
&**styles.primary()));
styles.pseudos.get(&pseudo).cloned()
},
}
}
PseudoElementCascadeType::Precomputed => unreachable!("No anonymous boxes"), PseudoElementCascadeType::Precomputed => unreachable!("No anonymous boxes"),
PseudoElementCascadeType::Lazy => { PseudoElementCascadeType::Lazy => {
debug_assert!(inherited_styles.is_none() ||
ptr::eq(inherited_styles.unwrap(),
&**styles.primary()));
let base = if pseudo.inherits_from_default_values() { let base = if pseudo.inherits_from_default_values() {
doc_data.default_computed_values() doc_data.default_computed_values()
} else { } else {
@ -1539,7 +1575,6 @@ fn get_pseudo_style(
rule_inclusion, rule_inclusion,
base, base,
&metrics) &metrics)
.map(|s| s.clone())
}, },
}; };
@ -2633,6 +2668,7 @@ pub extern "C" fn Servo_ResolveStyleLazily(element: RawGeckoElementBorrowed,
pseudo, pseudo,
rule_inclusion, rule_inclusion,
styles, styles,
/* inherited_styles = */ None,
&*data, &*data,
/* is_probe = */ false, /* is_probe = */ false,
).expect("We're not probing, so we should always get a style \ ).expect("We're not probing, so we should always get a style \