Refactor the cascade

Converting the specified value of some properties into a computed value
depends on the value of other properties. For example, the `em` unit
of any length depends on the `font-size` property.

Previously, we would do a first pass over applicable declarations
to build up a `values::computed::Context` struct with a number of fields
for each such piece of data from other properties.

This simplies the struct by instead having it contain the
set of computed values (for a given element) that is being populated
and classify properties into "early" and "other",
such that the only dependencies can be from "other" to "early".
We iterate applicable_declarations twice, first cascading "early" properties
then "other".
Unfortunately, it’s not easy to check that this classification is correct.
This commit is contained in:
Simon Sapin 2016-03-09 00:33:01 +01:00
parent bab28e5070
commit 529164e4a5
3 changed files with 213 additions and 339 deletions

View file

@ -1377,6 +1377,12 @@ pub mod specified {
"outset" => outset = 2,
}
impl BorderStyle {
pub fn none_or_hidden(&self) -> bool {
matches!(*self, BorderStyle::none | BorderStyle::hidden)
}
}
/// A time in seconds according to CSS-VALUES § 6.2.
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, HeapSizeOf)]
pub struct Time(pub CSSFloat);
@ -1431,7 +1437,7 @@ pub mod specified {
pub mod computed {
use app_units::Au;
use euclid::size::Size2D;
use properties::longhands;
use properties::ComputedValues;
use std::fmt;
use super::AuExtensionMethods;
use super::specified::AngleOrCorner;
@ -1440,26 +1446,14 @@ pub mod computed {
pub use cssparser::Color as CSSColor;
pub use super::specified::{Angle, BorderStyle, Time};
pub struct Context {
pub inherited_font_weight: longhands::font_weight::computed_value::T,
pub inherited_font_size: longhands::font_size::computed_value::T,
pub inherited_text_decorations_in_effect:
longhands::_servo_text_decorations_in_effect::computed_value::T,
pub color: longhands::color::computed_value::T,
pub text_decoration: longhands::text_decoration::computed_value::T,
pub font_size: longhands::font_size::computed_value::T,
pub root_font_size: longhands::font_size::computed_value::T,
pub display: longhands::display::computed_value::T,
pub positioned: bool,
pub floated: bool,
pub border_top_present: bool,
pub border_right_present: bool,
pub border_bottom_present: bool,
pub border_left_present: bool,
pub struct Context<'a> {
pub is_root_element: bool,
pub viewport_size: Size2D<Au>,
pub outline_style_present: bool,
// TODO, as needed: viewport size, etc.
pub inherited_style: &'a ComputedValues,
/// Values access through this need to be in the properties "computed early":
/// color, text-decoration, font-size, display, position, float, border-*-style, outline-style
pub style: ComputedValues,
}
pub trait ToComputedValue {
@ -1500,11 +1494,12 @@ pub mod computed {
specified::Length::Absolute(length) => length,
specified::Length::Calc(calc) => calc.to_computed_value(context).length(),
specified::Length::FontRelative(length) =>
length.to_computed_value(context.font_size, context.root_font_size),
length.to_computed_value(context.style.get_font().font_size,
context.style.root_font_size),
specified::Length::ViewportPercentage(length) =>
length.to_computed_value(context.viewport_size),
specified::Length::ServoCharacterWidth(length) =>
length.to_computed_value(context.font_size)
length.to_computed_value(context.style.get_font().font_size)
}
}
}
@ -1603,8 +1598,8 @@ pub mod computed {
}
for val in &[self.ch, self.em, self.ex, self.rem] {
if let Some(val) = *val {
length = Some(length.unwrap_or(Au(0)) +
val.to_computed_value(context.font_size, context.root_font_size));
length = Some(length.unwrap_or(Au(0)) + val.to_computed_value(
context.style.get_font().font_size, context.style.root_font_size));
}
}