Add a Stylo API for reparenting a given style.

Servo side of part 4 of the fix for Gecko bug 1324619.  r=emilio
This commit is contained in:
Boris Zbarsky 2017-07-28 21:16:41 -04:00
parent 8db39f8fde
commit 7161fff1b8
6 changed files with 189 additions and 36 deletions

View file

@ -20,6 +20,7 @@ use properties::{self, CascadeFlags, ComputedValues};
use properties::{AnimationRules, PropertyDeclarationBlock};
#[cfg(feature = "servo")]
use properties::INHERIT_ALL;
use properties::IS_LINK;
use rule_tree::{CascadeLevel, RuleTree, StyleSource};
use selector_map::{SelectorMap, SelectorMapEntry};
use selector_parser::{SelectorImpl, PseudoElement};
@ -727,6 +728,47 @@ impl Stylist {
return None
}
// FIXME(emilio): The lack of layout_parent_style here could be
// worrying, but we're probably dropping the display fixup for
// pseudos other than before and after, so it's probably ok.
//
// (Though the flags don't indicate so!)
Some(self.compute_style_with_inputs(inputs,
Some(pseudo),
guards,
parent_style,
parent_style,
parent_style,
font_metrics,
CascadeFlags::empty()))
}
/// Computes a style using the given CascadeInputs. This can be used to
/// compute a style any time we know what rules apply and just need to use
/// the given parent styles.
///
/// parent_style is the style to inherit from for properties affected by
/// first-line ancestors.
///
/// parent_style_ignoring_first_line is the style to inherit from for
/// properties not affected by first-line ancestors.
///
/// layout_parent_style is the style used for some property fixups. It's
/// the style of the nearest ancestor with a layout box.
///
/// is_link should be true if we're computing style for a link; that affects
/// how :visited handling is done.
pub fn compute_style_with_inputs(&self,
inputs: &CascadeInputs,
pseudo: Option<&PseudoElement>,
guards: &StylesheetGuards,
parent_style: &ComputedValues,
parent_style_ignoring_first_line: &ComputedValues,
layout_parent_style: &ComputedValues,
font_metrics: &FontMetricsProvider,
cascade_flags: CascadeFlags)
-> Arc<ComputedValues>
{
// We need to compute visited values if we have visited rules or if our
// parent has visited values.
let visited_values = if inputs.visited_rules.is_some() || parent_style.get_visited_style().is_some() {
@ -737,28 +779,37 @@ impl Stylist {
Some(rules) => rules,
None => inputs.rules.as_ref().unwrap(),
};
// We want to use the visited bits (if any) from our parent style as
// our parent.
let inherited_style =
parent_style.get_visited_style().unwrap_or(parent_style);
let inherited_style;
let inherited_style_ignoring_first_line;
let layout_parent_style_for_visited;
if cascade_flags.contains(IS_LINK) {
// We just want to use our parent style as our parent.
inherited_style = parent_style;
inherited_style_ignoring_first_line = parent_style_ignoring_first_line;
layout_parent_style_for_visited = layout_parent_style;
} else {
// We want to use the visited bits (if any) from our parent
// style as our parent.
inherited_style =
parent_style.get_visited_style().unwrap_or(parent_style);
inherited_style_ignoring_first_line =
parent_style_ignoring_first_line.get_visited_style().unwrap_or(parent_style_ignoring_first_line);
layout_parent_style_for_visited =
layout_parent_style.get_visited_style().unwrap_or(layout_parent_style);
}
// FIXME(emilio): The lack of layout_parent_style here could be
// worrying, but we're probably dropping the display fixup for
// pseudos other than before and after, so it's probably ok.
//
// (Though the flags don't indicate so!)
let computed =
properties::cascade(&self.device,
Some(pseudo),
pseudo,
rule_node,
guards,
Some(inherited_style),
Some(inherited_style),
Some(inherited_style),
Some(inherited_style_ignoring_first_line),
Some(layout_parent_style_for_visited),
None,
None,
font_metrics,
CascadeFlags::empty(),
cascade_flags,
self.quirks_mode);
Some(computed)
@ -774,18 +825,18 @@ impl Stylist {
// difficult to assert that display: contents nodes never arrive here
// (tl;dr: It doesn't apply for replaced elements and such, but the
// computed value is still "contents").
Some(properties::cascade(&self.device,
Some(pseudo),
rules,
guards,
Some(parent_style),
Some(parent_style),
Some(parent_style),
visited_values,
None,
font_metrics,
CascadeFlags::empty(),
self.quirks_mode))
properties::cascade(&self.device,
pseudo,
rules,
guards,
Some(parent_style),
Some(parent_style_ignoring_first_line),
Some(layout_parent_style),
visited_values,
None,
font_metrics,
cascade_flags,
self.quirks_mode)
}
/// Computes the cascade inputs for a lazily-cascaded pseudo-element.