mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
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:
parent
d40e27d6e5
commit
746f245f32
3 changed files with 63 additions and 7 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue