Make it possible to construct StyleBuilder with two different inherited styles.

Part 3 of Gecko bug 1382806.  r=emilio
This commit is contained in:
Boris Zbarsky 2017-07-26 13:41:48 -04:00
parent f991b76535
commit 048044f98b
4 changed files with 41 additions and 1 deletions

View file

@ -499,6 +499,7 @@ fn compute_style_for_animation_step(context: &SharedStyleContext,
iter, iter,
Some(previous_style), Some(previous_style),
Some(previous_style), Some(previous_style),
Some(previous_style),
/* cascade_info = */ None, /* cascade_info = */ None,
/* visited_style = */ None, /* visited_style = */ None,
font_metrics_provider, font_metrics_provider,

View file

@ -14,6 +14,7 @@ use servo_arc::{Arc, UniqueArc};
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::HashSet; use std::collections::HashSet;
use std::{fmt, mem, ops}; use std::{fmt, mem, ops};
#[cfg(feature = "gecko")] use std::ptr;
use app_units::Au; use app_units::Au;
#[cfg(feature = "servo")] use cssparser::RGBA; #[cfg(feature = "servo")] use cssparser::RGBA;
@ -2512,6 +2513,7 @@ impl<'a> StyleBuilder<'a> {
fn new( fn new(
device: &'a Device, device: &'a Device,
parent_style: Option<<&'a ComputedValues>, parent_style: Option<<&'a ComputedValues>,
parent_style_ignoring_first_line: Option<<&'a ComputedValues>,
pseudo: Option<<&'a PseudoElement>, pseudo: Option<<&'a PseudoElement>,
cascade_flags: CascadeFlags, cascade_flags: CascadeFlags,
rules: Option<StrongRuleNode>, rules: Option<StrongRuleNode>,
@ -2521,8 +2523,19 @@ impl<'a> StyleBuilder<'a> {
flags: ComputedValueFlags, flags: ComputedValueFlags,
visited_style: Option<Arc<ComputedValues>>, visited_style: Option<Arc<ComputedValues>>,
) -> Self { ) -> Self {
debug_assert_eq!(parent_style.is_some(), parent_style_ignoring_first_line.is_some());
#[cfg(feature = "gecko")]
debug_assert!(parent_style.is_none() ||
ptr::eq(parent_style.unwrap(),
parent_style_ignoring_first_line.unwrap()) ||
parent_style.unwrap().pseudo() == Some(PseudoElement::FirstLine));
let reset_style = device.default_computed_values(); let reset_style = device.default_computed_values();
let inherited_style = parent_style.unwrap_or(reset_style); let inherited_style = parent_style.unwrap_or(reset_style);
let inherited_style_ignoring_first_line = parent_style_ignoring_first_line.unwrap_or(reset_style);
// FIXME(bz): INHERIT_ALL seems like a fundamentally broken idea. I'm
// 99% sure it should give incorrect behavior for table anonymous box
// backgrounds, for example. This code doesn't attempt to make it play
// nice with inherited_style_ignoring_first_line.
let reset_style = if cascade_flags.contains(INHERIT_ALL) { let reset_style = if cascade_flags.contains(INHERIT_ALL) {
inherited_style inherited_style
} else { } else {
@ -2533,7 +2546,7 @@ impl<'a> StyleBuilder<'a> {
device, device,
parent_style, parent_style,
inherited_style, inherited_style,
inherited_style_ignoring_first_line: inherited_style, inherited_style_ignoring_first_line,
reset_style, reset_style,
pseudo, pseudo,
rules, rules,
@ -2562,10 +2575,14 @@ impl<'a> StyleBuilder<'a> {
) -> Self { ) -> Self {
let reset_style = device.default_computed_values(); let reset_style = device.default_computed_values();
let inherited_style = parent_style.unwrap_or(reset_style); let inherited_style = parent_style.unwrap_or(reset_style);
#[cfg(feature = "gecko")]
debug_assert!(parent_style.is_none() ||
parent_style.unwrap().pseudo() != Some(PseudoElement::FirstLine));
StyleBuilder { StyleBuilder {
device, device,
parent_style, parent_style,
inherited_style, inherited_style,
// None of our callers pass in ::first-line parent styles.
inherited_style_ignoring_first_line: inherited_style, inherited_style_ignoring_first_line: inherited_style,
reset_style, reset_style,
pseudo, pseudo,
@ -2651,6 +2668,7 @@ impl<'a> StyleBuilder<'a> {
Self::new( Self::new(
device, device,
Some(parent), Some(parent),
Some(parent),
pseudo, pseudo,
CascadeFlags::empty(), CascadeFlags::empty(),
/* rules = */ None, /* rules = */ None,
@ -2910,6 +2928,7 @@ pub fn cascade(
rule_node: &StrongRuleNode, rule_node: &StrongRuleNode,
guards: &StylesheetGuards, guards: &StylesheetGuards,
parent_style: Option<<&ComputedValues>, parent_style: Option<<&ComputedValues>,
parent_style_ignoring_first_line: Option<<&ComputedValues>,
layout_parent_style: Option<<&ComputedValues>, layout_parent_style: Option<<&ComputedValues>,
visited_style: Option<Arc<ComputedValues>>, visited_style: Option<Arc<ComputedValues>>,
cascade_info: Option<<&mut CascadeInfo>, cascade_info: Option<<&mut CascadeInfo>,
@ -2917,6 +2936,12 @@ pub fn cascade(
flags: CascadeFlags, flags: CascadeFlags,
quirks_mode: QuirksMode quirks_mode: QuirksMode
) -> Arc<ComputedValues> { ) -> Arc<ComputedValues> {
debug_assert_eq!(parent_style.is_some(), parent_style_ignoring_first_line.is_some());
#[cfg(feature = "gecko")]
debug_assert!(parent_style.is_none() ||
ptr::eq(parent_style.unwrap(),
parent_style_ignoring_first_line.unwrap()) ||
parent_style.unwrap().pseudo() == Some(PseudoElement::FirstLine));
let iter_declarations = || { let iter_declarations = || {
rule_node.self_and_ancestors().flat_map(|node| { rule_node.self_and_ancestors().flat_map(|node| {
let cascade_level = node.cascade_level(); let cascade_level = node.cascade_level();
@ -2962,6 +2987,7 @@ pub fn cascade(
rule_node, rule_node,
iter_declarations, iter_declarations,
parent_style, parent_style,
parent_style_ignoring_first_line,
layout_parent_style, layout_parent_style,
visited_style, visited_style,
cascade_info, cascade_info,
@ -2980,6 +3006,7 @@ pub fn apply_declarations<'a, F, I>(
rules: &StrongRuleNode, rules: &StrongRuleNode,
iter_declarations: F, iter_declarations: F,
parent_style: Option<<&ComputedValues>, parent_style: Option<<&ComputedValues>,
parent_style_ignoring_first_line: Option<<&ComputedValues>,
layout_parent_style: Option<<&ComputedValues>, layout_parent_style: Option<<&ComputedValues>,
visited_style: Option<Arc<ComputedValues>>, visited_style: Option<Arc<ComputedValues>>,
mut cascade_info: Option<<&mut CascadeInfo>, mut cascade_info: Option<<&mut CascadeInfo>,
@ -2992,6 +3019,12 @@ where
I: Iterator<Item = (&'a PropertyDeclaration, CascadeLevel)>, I: Iterator<Item = (&'a PropertyDeclaration, CascadeLevel)>,
{ {
debug_assert!(layout_parent_style.is_none() || parent_style.is_some()); debug_assert!(layout_parent_style.is_none() || parent_style.is_some());
debug_assert_eq!(parent_style.is_some(), parent_style_ignoring_first_line.is_some());
#[cfg(feature = "gecko")]
debug_assert!(parent_style.is_none() ||
ptr::eq(parent_style.unwrap(),
parent_style_ignoring_first_line.unwrap()) ||
parent_style.unwrap().pseudo() == Some(PseudoElement::FirstLine));
let (inherited_style, layout_parent_style) = match parent_style { let (inherited_style, layout_parent_style) = match parent_style {
Some(parent_style) => { Some(parent_style) => {
(parent_style, (parent_style,
@ -3026,6 +3059,7 @@ where
builder: StyleBuilder::new( builder: StyleBuilder::new(
device, device,
parent_style, parent_style,
parent_style_ignoring_first_line,
pseudo, pseudo,
flags, flags,
Some(rules.clone()), Some(rules.clone()),

View file

@ -479,6 +479,7 @@ where
rules.unwrap_or(self.context.shared.stylist.rule_tree().root()), rules.unwrap_or(self.context.shared.stylist.rule_tree().root()),
&self.context.shared.guards, &self.context.shared.guards,
parent_style, parent_style,
parent_style,
layout_parent_style, layout_parent_style,
style_if_visited, style_if_visited,
Some(&mut cascade_info), Some(&mut cascade_info),

View file

@ -637,6 +637,7 @@ impl Stylist {
guards, guards,
parent, parent,
parent, parent,
parent,
None, None,
None, None,
font_metrics, font_metrics,
@ -753,6 +754,7 @@ impl Stylist {
guards, guards,
Some(inherited_style), Some(inherited_style),
Some(inherited_style), Some(inherited_style),
Some(inherited_style),
None, None,
None, None,
font_metrics, font_metrics,
@ -778,6 +780,7 @@ impl Stylist {
guards, guards,
Some(parent_style), Some(parent_style),
Some(parent_style), Some(parent_style),
Some(parent_style),
visited_values, visited_values,
None, None,
font_metrics, font_metrics,
@ -1342,6 +1345,7 @@ impl Stylist {
guards, guards,
Some(parent_style), Some(parent_style),
Some(parent_style), Some(parent_style),
Some(parent_style),
None, None,
None, None,
&metrics, &metrics,