mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Refactor cascade() and fix cascade_with_cached_declarations()
* Expand the apply() and apply_cached() templates. Their two invocations each were different enough that this improves readability IMO. * Create computed::Context from inherited and cascaded values rather than computed value, as much as possible. * Centralize this creation rather than making it per-property, making 'needed_for_context' not needed anymore. * Pass a context to cascade_with_cached_declarations() rather than duplicate the creation code.
This commit is contained in:
parent
85ef67ef14
commit
83510ebbff
2 changed files with 171 additions and 267 deletions
|
@ -163,14 +163,13 @@ pub mod computed {
|
||||||
pub use CSSColor = cssparser::Color;
|
pub use CSSColor = cssparser::Color;
|
||||||
pub use compute_CSSColor = super::super::longhands::computed_as_specified;
|
pub use compute_CSSColor = super::super::longhands::computed_as_specified;
|
||||||
use super::*;
|
use super::*;
|
||||||
use super::super::{longhands, style_structs};
|
use super::super::longhands;
|
||||||
use servo_util::cowarc::CowArc;
|
|
||||||
pub use servo_util::geometry::Au;
|
pub use servo_util::geometry::Au;
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
color: longhands::color::computed_value::T,
|
color: longhands::color::computed_value::T,
|
||||||
parent_font_weight: longhands::font_weight::computed_value::T,
|
inherited_font_weight: longhands::font_weight::computed_value::T,
|
||||||
parent_font_size: longhands::font_size::computed_value::T,
|
inherited_font_size: longhands::font_size::computed_value::T,
|
||||||
font_size: longhands::font_size::computed_value::T,
|
font_size: longhands::font_size::computed_value::T,
|
||||||
positioned: bool,
|
positioned: bool,
|
||||||
floated: bool,
|
floated: bool,
|
||||||
|
@ -179,109 +178,23 @@ pub mod computed {
|
||||||
border_bottom_present: bool,
|
border_bottom_present: bool,
|
||||||
border_left_present: bool,
|
border_left_present: bool,
|
||||||
is_root_element: bool,
|
is_root_element: bool,
|
||||||
use_parent_font_size: bool,
|
|
||||||
// TODO, as needed: root font size, viewport size, etc.
|
// TODO, as needed: root font size, viewport size, etc.
|
||||||
}
|
}
|
||||||
|
|
||||||
fn border_is_present(border_style: longhands::border_top_style::computed_value::T) -> bool {
|
|
||||||
match border_style {
|
|
||||||
longhands::border_top_style::none | longhands::border_top_style::hidden => false,
|
|
||||||
_ => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Context {
|
|
||||||
#[inline]
|
|
||||||
pub fn new(color: &CowArc<style_structs::Color>,
|
|
||||||
font: &CowArc<style_structs::Font>,
|
|
||||||
css_box: &CowArc<style_structs::Box>,
|
|
||||||
border: &CowArc<style_structs::Border>,
|
|
||||||
is_root_element: bool)
|
|
||||||
-> Context {
|
|
||||||
let mut context = Context {
|
|
||||||
color: color.get().color,
|
|
||||||
parent_font_weight: font.get().font_weight,
|
|
||||||
parent_font_size: font.get().font_size,
|
|
||||||
font_size: font.get().font_size,
|
|
||||||
positioned: false,
|
|
||||||
floated: false,
|
|
||||||
border_top_present: false,
|
|
||||||
border_right_present: false,
|
|
||||||
border_bottom_present: false,
|
|
||||||
border_left_present: false,
|
|
||||||
is_root_element: is_root_element,
|
|
||||||
use_parent_font_size: true,
|
|
||||||
};
|
|
||||||
context.set_position(css_box.get().position);
|
|
||||||
context.set_float(css_box.get().float);
|
|
||||||
context.set_border_top_style(border.get().border_top_style);
|
|
||||||
context.set_border_right_style(border.get().border_right_style);
|
|
||||||
context.set_border_bottom_style(border.get().border_bottom_style);
|
|
||||||
context.set_border_left_style(border.get().border_left_style);
|
|
||||||
context
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_color(&mut self, color: longhands::color::computed_value::T) {
|
|
||||||
self.color = color
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_position(&mut self, position: longhands::position::computed_value::T) {
|
|
||||||
self.positioned = match position {
|
|
||||||
longhands::position::absolute | longhands::position::fixed => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_font_size(&mut self, font_size: longhands::font_size::computed_value::T) {
|
|
||||||
self.font_size = font_size
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_float(&mut self, float: longhands::float::computed_value::T) {
|
|
||||||
self.floated = float != longhands::float::none
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_border_top_style(&mut self,
|
|
||||||
style: longhands::border_top_style::computed_value::T) {
|
|
||||||
self.border_top_present = border_is_present(style)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_border_right_style(&mut self,
|
|
||||||
style: longhands::border_top_style::computed_value::T) {
|
|
||||||
self.border_right_present = border_is_present(style)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_border_bottom_style(&mut self,
|
|
||||||
style: longhands::border_top_style::computed_value::T) {
|
|
||||||
self.border_bottom_present = border_is_present(style)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_border_left_style(&mut self,
|
|
||||||
style: longhands::border_top_style::computed_value::T) {
|
|
||||||
self.border_left_present = border_is_present(style)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn compute_Au(value: specified::Length, context: &Context) -> Au {
|
pub fn compute_Au(value: specified::Length, context: &Context) -> Au {
|
||||||
match value {
|
compute_Au_with_font_size(value, context.font_size)
|
||||||
specified::Au_(value) => value,
|
|
||||||
specified::Em(value) => context.font_size.scale_by(value),
|
|
||||||
specified::Ex(value) => {
|
|
||||||
let x_height = 0.5; // TODO: find that from the font
|
|
||||||
context.font_size.scale_by(value * x_height)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A special version of `compute_Au` used for `font-size`.
|
/// A special version of `compute_Au` used for `font-size`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn compute_Au_from_parent(value: specified::Length, context: &Context) -> Au {
|
pub fn compute_Au_with_font_size(value: specified::Length, reference_font_size: Au) -> Au {
|
||||||
match value {
|
match value {
|
||||||
specified::Au_(value) => value,
|
specified::Au_(value) => value,
|
||||||
specified::Em(value) => context.parent_font_size.scale_by(value),
|
specified::Em(value) => reference_font_size.scale_by(value),
|
||||||
specified::Ex(value) => {
|
specified::Ex(value) => {
|
||||||
let x_height = 0.5; // TODO: find that from the font
|
let x_height = 0.5; // TODO: find that from the font
|
||||||
context.font_size.scale_by(value * x_height)
|
reference_font_size.scale_by(value * x_height)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,11 +27,10 @@ def to_rust_ident(name):
|
||||||
return name
|
return name
|
||||||
|
|
||||||
class Longhand(object):
|
class Longhand(object):
|
||||||
def __init__(self, name, needed_for_context):
|
def __init__(self, name):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.ident = to_rust_ident(name)
|
self.ident = to_rust_ident(name)
|
||||||
self.style_struct = THIS_STYLE_STRUCT
|
self.style_struct = THIS_STYLE_STRUCT
|
||||||
self.needed_for_context = needed_for_context
|
|
||||||
|
|
||||||
class Shorthand(object):
|
class Shorthand(object):
|
||||||
def __init__(self, name, sub_properties):
|
def __init__(self, name, sub_properties):
|
||||||
|
@ -77,9 +76,9 @@ pub mod longhands {
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
<%def name="raw_longhand(name, needed_for_context=False, no_super=False)">
|
<%def name="raw_longhand(name, no_super=False)">
|
||||||
<%
|
<%
|
||||||
property = Longhand(name, needed_for_context)
|
property = Longhand(name)
|
||||||
THIS_STYLE_STRUCT.longhands.append(property)
|
THIS_STYLE_STRUCT.longhands.append(property)
|
||||||
LONGHANDS.append(property)
|
LONGHANDS.append(property)
|
||||||
LONGHANDS_BY_NAME[name] = property
|
LONGHANDS_BY_NAME[name] = property
|
||||||
|
@ -102,8 +101,8 @@ pub mod longhands {
|
||||||
}
|
}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="longhand(name, needed_for_context=False, no_super=False)">
|
<%def name="longhand(name, no_super=False)">
|
||||||
<%self:raw_longhand name="${name}" needed_for_context="${needed_for_context}">
|
<%self:raw_longhand name="${name}">
|
||||||
${caller.body()}
|
${caller.body()}
|
||||||
pub fn parse_specified(input: &[ComponentValue])
|
pub fn parse_specified(input: &[ComponentValue])
|
||||||
-> Option<DeclaredValue<SpecifiedValue>> {
|
-> Option<DeclaredValue<SpecifiedValue>> {
|
||||||
|
@ -112,8 +111,8 @@ pub mod longhands {
|
||||||
</%self:raw_longhand>
|
</%self:raw_longhand>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="single_component_value(name, needed_for_context=False)">
|
<%def name="single_component_value(name)">
|
||||||
<%self:longhand name="${name}" needed_for_context="${needed_for_context}">
|
<%self:longhand name="${name}">
|
||||||
${caller.body()}
|
${caller.body()}
|
||||||
pub fn parse(input: &[ComponentValue]) -> Option<SpecifiedValue> {
|
pub fn parse(input: &[ComponentValue]) -> Option<SpecifiedValue> {
|
||||||
one_component_value(input).and_then(from_component_value)
|
one_component_value(input).and_then(from_component_value)
|
||||||
|
@ -121,8 +120,8 @@ pub mod longhands {
|
||||||
</%self:longhand>
|
</%self:longhand>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="single_keyword_computed(name, values, needed_for_context=False)">
|
<%def name="single_keyword_computed(name, values)">
|
||||||
<%self:single_component_value name="${name}" needed_for_context="${needed_for_context}">
|
<%self:single_component_value name="${name}">
|
||||||
${caller.body()}
|
${caller.body()}
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
#[deriving(Eq, Clone, FromPrimitive)]
|
#[deriving(Eq, Clone, FromPrimitive)]
|
||||||
|
@ -149,10 +148,9 @@ pub mod longhands {
|
||||||
</%self:single_component_value>
|
</%self:single_component_value>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="single_keyword(name, values, needed_for_context=False)">
|
<%def name="single_keyword(name, values)">
|
||||||
<%self:single_keyword_computed name="${name}"
|
<%self:single_keyword_computed name="${name}"
|
||||||
values="${values}"
|
values="${values}">
|
||||||
needed_for_context="${needed_for_context}">
|
|
||||||
// The computed value is the same as the specified value.
|
// The computed value is the same as the specified value.
|
||||||
pub use to_computed_value = super::computed_as_specified;
|
pub use to_computed_value = super::computed_as_specified;
|
||||||
</%self:single_keyword_computed>
|
</%self:single_keyword_computed>
|
||||||
|
@ -197,11 +195,10 @@ pub mod longhands {
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
// double groove ridge insed outset
|
// double groove ridge insed outset
|
||||||
${single_keyword("border-top-style", values="none solid dotted dashed hidden", \
|
${single_keyword("border-top-style", values="none solid dotted dashed hidden")}
|
||||||
needed_for_context=True)}
|
|
||||||
|
|
||||||
% for side in ["right", "bottom", "left"]:
|
% for side in ["right", "bottom", "left"]:
|
||||||
<%self:longhand name="border-${side}-style", no_super="True", needed_for_context="True">
|
<%self:longhand name="border-${side}-style", no_super="True">
|
||||||
pub use super::border_top_style::{get_initial_value, parse, to_computed_value};
|
pub use super::border_top_style::{get_initial_value, parse, to_computed_value};
|
||||||
pub type SpecifiedValue = super::border_top_style::SpecifiedValue;
|
pub type SpecifiedValue = super::border_top_style::SpecifiedValue;
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
|
@ -290,8 +287,8 @@ pub mod longhands {
|
||||||
}
|
}
|
||||||
</%self:single_keyword_computed>
|
</%self:single_keyword_computed>
|
||||||
|
|
||||||
${single_keyword("position", "static absolute relative fixed", needed_for_context="True")}
|
${single_keyword("position", "static absolute relative fixed")}
|
||||||
${single_keyword("float", "none left right", needed_for_context="True")}
|
${single_keyword("float", "none left right")}
|
||||||
${single_keyword("clear", "none left right both")}
|
${single_keyword("clear", "none left right both")}
|
||||||
|
|
||||||
// CSS 2.1, Section 10 - Visual formatting model details
|
// CSS 2.1, Section 10 - Visual formatting model details
|
||||||
|
@ -480,7 +477,7 @@ pub mod longhands {
|
||||||
|
|
||||||
${new_style_struct("Color", is_inherited=True)}
|
${new_style_struct("Color", is_inherited=True)}
|
||||||
|
|
||||||
<%self:raw_longhand name="color" needed_for_context="True">
|
<%self:raw_longhand name="color">
|
||||||
pub use to_computed_value = super::computed_as_specified;
|
pub use to_computed_value = super::computed_as_specified;
|
||||||
pub type SpecifiedValue = RGBA;
|
pub type SpecifiedValue = RGBA;
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
|
@ -646,7 +643,7 @@ pub mod longhands {
|
||||||
% for weight in range(100, 901, 100):
|
% for weight in range(100, 901, 100):
|
||||||
SpecifiedWeight${weight} => Weight${weight},
|
SpecifiedWeight${weight} => Weight${weight},
|
||||||
% endfor
|
% endfor
|
||||||
Bolder => match context.parent_font_weight {
|
Bolder => match context.inherited_font_weight {
|
||||||
Weight100 => Weight400,
|
Weight100 => Weight400,
|
||||||
Weight200 => Weight400,
|
Weight200 => Weight400,
|
||||||
Weight300 => Weight400,
|
Weight300 => Weight400,
|
||||||
|
@ -657,7 +654,7 @@ pub mod longhands {
|
||||||
Weight800 => Weight900,
|
Weight800 => Weight900,
|
||||||
Weight900 => Weight900,
|
Weight900 => Weight900,
|
||||||
},
|
},
|
||||||
Lighter => match context.parent_font_weight {
|
Lighter => match context.inherited_font_weight {
|
||||||
Weight100 => Weight100,
|
Weight100 => Weight100,
|
||||||
Weight200 => Weight100,
|
Weight200 => Weight100,
|
||||||
Weight300 => Weight100,
|
Weight300 => Weight100,
|
||||||
|
@ -672,8 +669,7 @@ pub mod longhands {
|
||||||
}
|
}
|
||||||
</%self:single_component_value>
|
</%self:single_component_value>
|
||||||
|
|
||||||
<%self:single_component_value name="font-size" needed_for_context="True">
|
<%self:single_component_value name="font-size">
|
||||||
use super::super::common_types::computed::compute_Au_from_parent;
|
|
||||||
pub type SpecifiedValue = specified::Length; // Percentages are the same as em.
|
pub type SpecifiedValue = specified::Length; // Percentages are the same as em.
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use super::super::Au;
|
use super::super::Au;
|
||||||
|
@ -683,13 +679,10 @@ pub mod longhands {
|
||||||
Au::from_px(16) // medium
|
Au::from_px(16) // medium
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context)
|
pub fn to_computed_value(_value: SpecifiedValue, context: &computed::Context)
|
||||||
-> computed_value::T {
|
-> computed_value::T {
|
||||||
if !context.use_parent_font_size {
|
// We already computed this element's font size; no need to compute it again.
|
||||||
// We already computed this element's font size; no need to compute it again.
|
return context.font_size
|
||||||
return context.font_size
|
|
||||||
}
|
|
||||||
compute_Au_from_parent(value, context)
|
|
||||||
}
|
}
|
||||||
/// <length> | <percentage>
|
/// <length> | <percentage>
|
||||||
/// TODO: support <absolute-size> and <relative-size>
|
/// TODO: support <absolute-size> and <relative-size>
|
||||||
|
@ -771,7 +764,7 @@ pub mod shorthands {
|
||||||
pub use super::*;
|
pub use super::*;
|
||||||
pub use super::longhands::*;
|
pub use super::longhands::*;
|
||||||
|
|
||||||
<%def name="shorthand(name, sub_properties, needed_for_context=False)">
|
<%def name="shorthand(name, sub_properties)">
|
||||||
<%
|
<%
|
||||||
shorthand = Shorthand(name, sub_properties.split())
|
shorthand = Shorthand(name, sub_properties.split())
|
||||||
SHORTHANDS.append(shorthand)
|
SHORTHANDS.append(shorthand)
|
||||||
|
@ -1156,74 +1149,53 @@ pub fn initial_values() -> ComputedValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fast path for the function below. Only computes new inherited styles.
|
/// Fast path for the function below. Only computes new inherited styles.
|
||||||
#[allow(unused_mut)]
|
|
||||||
fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty],
|
fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty],
|
||||||
shareable: bool,
|
shareable: bool,
|
||||||
parent_style: &ComputedValues,
|
parent_style: &ComputedValues,
|
||||||
cached_style: &ComputedValues)
|
cached_style: &ComputedValues,
|
||||||
|
context: &computed::Context)
|
||||||
-> ComputedValues {
|
-> ComputedValues {
|
||||||
% for style_struct in STYLE_STRUCTS:
|
% for style_struct in STYLE_STRUCTS:
|
||||||
% if style_struct.inherited:
|
% if style_struct.inherited:
|
||||||
let mut style_${style_struct.name} = parent_style.${style_struct.name}.clone();
|
let mut style_${style_struct.name} = parent_style.${style_struct.name}.clone();
|
||||||
% else:
|
% else:
|
||||||
let mut style_${style_struct.name} = cached_style.${style_struct.name}.clone();
|
let style_${style_struct.name} = cached_style.${style_struct.name}.clone();
|
||||||
% endif
|
% endif
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
let mut context = computed::Context::new(&style_Color,
|
for sub_list in applicable_declarations.iter() {
|
||||||
&style_Font,
|
for declaration in sub_list.declarations.get().iter() {
|
||||||
&style_Box,
|
match *declaration {
|
||||||
&style_Border,
|
% for style_struct in STYLE_STRUCTS:
|
||||||
false);
|
% if style_struct.inherited:
|
||||||
|
% for property in style_struct.longhands:
|
||||||
<%def name="apply_cached(priority)">
|
${property.ident}_declaration(ref declared_value) => {
|
||||||
for sub_list in applicable_declarations.iter() {
|
style_${style_struct.name}.get_mut().${property.ident} =
|
||||||
for declaration in sub_list.declarations.get().iter() {
|
match *declared_value {
|
||||||
match declaration {
|
SpecifiedValue(ref specified_value)
|
||||||
% for style_struct in STYLE_STRUCTS:
|
=> longhands::${property.ident}::to_computed_value(
|
||||||
% if style_struct.inherited:
|
(*specified_value).clone(),
|
||||||
% for property in style_struct.longhands:
|
context
|
||||||
% if (property.needed_for_context and needed_for_context) or not \
|
),
|
||||||
needed_for_context:
|
CSSWideKeyword(Initial)
|
||||||
&${property.ident}_declaration(SpecifiedValue(ref value)) => {
|
=> longhands::${property.ident}::get_initial_value(),
|
||||||
% if property.needed_for_context and needed_for_context:
|
CSSWideKeyword(Inherit) => {
|
||||||
context.set_${property.ident}(computed_value)
|
// This is a bit slow, but this is rare so it shouldn't matter.
|
||||||
% elif not needed_for_context:
|
// FIXME: is it still?
|
||||||
// Overwrite earlier declarations.
|
parent_style.${style_struct.name}
|
||||||
let computed_value =
|
.get()
|
||||||
longhands::${property.ident}::to_computed_value(
|
.${property.ident}
|
||||||
(*value).clone(),
|
.clone()
|
||||||
&context);
|
|
||||||
style_${style_struct.name}.get_mut()
|
|
||||||
.${property.ident} =
|
|
||||||
computed_value
|
|
||||||
% endif
|
|
||||||
}
|
}
|
||||||
&${property.ident}_declaration(CSSWideKeyword(Initial)) => {
|
}
|
||||||
let computed_value =
|
}
|
||||||
longhands::${property.ident}::get_initial_value();
|
% endfor
|
||||||
% if property.needed_for_context and needed_for_context:
|
% endif
|
||||||
context.set_${property.ident}(computed_value)
|
% endfor
|
||||||
% elif not needed_for_context:
|
_ => {}
|
||||||
// Overwrite earlier declarations.
|
|
||||||
style_${style_struct.name}.get_mut()
|
|
||||||
.${property.ident} =
|
|
||||||
computed_value
|
|
||||||
% endif
|
|
||||||
}
|
|
||||||
% endif
|
|
||||||
% endfor
|
|
||||||
% endif
|
|
||||||
% endfor
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%def>
|
}
|
||||||
|
|
||||||
${apply_cached(True)}
|
|
||||||
context.use_parent_font_size = false;
|
|
||||||
${apply_cached(False)}
|
|
||||||
|
|
||||||
ComputedValues {
|
ComputedValues {
|
||||||
% for style_struct in STYLE_STRUCTS:
|
% for style_struct in STYLE_STRUCTS:
|
||||||
|
@ -1257,113 +1229,132 @@ pub fn cascade(applicable_declarations: &[MatchedProperty],
|
||||||
initial_values: &ComputedValues,
|
initial_values: &ComputedValues,
|
||||||
cached_style: Option< &ComputedValues >)
|
cached_style: Option< &ComputedValues >)
|
||||||
-> (ComputedValues, bool) {
|
-> (ComputedValues, bool) {
|
||||||
|
let (is_root_element, inherited_style) = match parent_style {
|
||||||
|
Some(parent_style) => (false, parent_style),
|
||||||
|
None => (true, initial_values),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut context = {
|
||||||
|
let inherited_font_style = inherited_style.Font.get();
|
||||||
|
computed::Context {
|
||||||
|
is_root_element: is_root_element,
|
||||||
|
inherited_font_weight: inherited_font_style.font_weight,
|
||||||
|
inherited_font_size: inherited_font_style.font_size,
|
||||||
|
// To be overridden by applicable declarations:
|
||||||
|
font_size: inherited_font_style.font_size,
|
||||||
|
color: inherited_style.Color.get().color,
|
||||||
|
positioned: false,
|
||||||
|
floated: false,
|
||||||
|
border_top_present: false,
|
||||||
|
border_right_present: false,
|
||||||
|
border_bottom_present: false,
|
||||||
|
border_left_present: false,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This assumes that the computed and specified values have the same Rust type.
|
||||||
|
macro_rules! get_specified(
|
||||||
|
($style_struct: ident, $property: ident, $declared_value: expr) => {
|
||||||
|
match *$declared_value {
|
||||||
|
SpecifiedValue(specified_value) => specified_value,
|
||||||
|
CSSWideKeyword(Initial) => longhands::$property::get_initial_value(),
|
||||||
|
CSSWideKeyword(Inherit) => inherited_style.$style_struct.get().$property.clone(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
)
|
||||||
|
|
||||||
|
// Initialize `context`
|
||||||
|
for sub_list in applicable_declarations.iter() {
|
||||||
|
for declaration in sub_list.declarations.get().iter() {
|
||||||
|
match *declaration {
|
||||||
|
font_size_declaration(ref value) => {
|
||||||
|
context.font_size = match *value {
|
||||||
|
SpecifiedValue(specified_value) => computed::compute_Au_with_font_size(
|
||||||
|
specified_value, context.inherited_font_size),
|
||||||
|
CSSWideKeyword(Initial) => longhands::font_size::get_initial_value(),
|
||||||
|
CSSWideKeyword(Inherit) => context.inherited_font_size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
color_declaration(ref value) => {
|
||||||
|
context.color = get_specified!(Color, color, value);
|
||||||
|
}
|
||||||
|
position_declaration(ref value) => {
|
||||||
|
context.positioned = match get_specified!(Box, position, value) {
|
||||||
|
longhands::position::absolute | longhands::position::fixed => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float_declaration(ref value) => {
|
||||||
|
context.floated = get_specified!(Box, float, value) != longhands::float::none;
|
||||||
|
}
|
||||||
|
% for side in ["top", "right", "bottom", "left"]:
|
||||||
|
border_${side}_style_declaration(ref value) => {
|
||||||
|
context.border_${side}_present =
|
||||||
|
match get_specified!(Border, border_${side}_style, value) {
|
||||||
|
longhands::border_top_style::none |
|
||||||
|
longhands::border_top_style::hidden => false,
|
||||||
|
_ => true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
% endfor
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match (cached_style, parent_style) {
|
match (cached_style, parent_style) {
|
||||||
(Some(cached_style), Some(parent_style)) => {
|
(Some(cached_style), Some(parent_style)) => {
|
||||||
return (cascade_with_cached_declarations(applicable_declarations,
|
return (cascade_with_cached_declarations(applicable_declarations,
|
||||||
shareable,
|
shareable,
|
||||||
parent_style,
|
parent_style,
|
||||||
cached_style), false)
|
cached_style,
|
||||||
|
&context), false)
|
||||||
}
|
}
|
||||||
(_, _) => {}
|
(_, _) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_root_element;
|
// Set computed values, overwriting earlier declarations for the same property.
|
||||||
% for style_struct in STYLE_STRUCTS:
|
% for style_struct in STYLE_STRUCTS:
|
||||||
let mut style_${style_struct.name};
|
let mut style_${style_struct.name} =
|
||||||
|
% if style_struct.inherited:
|
||||||
|
inherited_style
|
||||||
|
% else:
|
||||||
|
initial_values
|
||||||
|
% endif
|
||||||
|
.${style_struct.name}.clone();
|
||||||
% endfor
|
% endfor
|
||||||
match parent_style {
|
|
||||||
Some(parent_style) => {
|
|
||||||
is_root_element = false;
|
|
||||||
% for style_struct in STYLE_STRUCTS:
|
|
||||||
% if style_struct.inherited:
|
|
||||||
style_${style_struct.name} = parent_style.${style_struct.name}.clone();
|
|
||||||
% else:
|
|
||||||
style_${style_struct.name} = initial_values.${style_struct.name}.clone();
|
|
||||||
% endif
|
|
||||||
% endfor
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
is_root_element = true;
|
|
||||||
% for style_struct in STYLE_STRUCTS:
|
|
||||||
style_${style_struct.name} = initial_values.${style_struct.name}.clone();
|
|
||||||
% endfor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut context = computed::Context::new(&style_Color,
|
|
||||||
&style_Font,
|
|
||||||
&style_Box,
|
|
||||||
&style_Border,
|
|
||||||
is_root_element);
|
|
||||||
|
|
||||||
let mut cacheable = true;
|
let mut cacheable = true;
|
||||||
<%def name="apply(needed_for_context)">
|
for sub_list in applicable_declarations.iter() {
|
||||||
for sub_list in applicable_declarations.iter() {
|
for declaration in sub_list.declarations.get().iter() {
|
||||||
for declaration in sub_list.declarations.get().iter() {
|
match *declaration {
|
||||||
match declaration {
|
% for style_struct in STYLE_STRUCTS:
|
||||||
% for style_struct in STYLE_STRUCTS:
|
% for property in style_struct.longhands:
|
||||||
% for property in style_struct.longhands:
|
${property.ident}_declaration(ref declared_value) => {
|
||||||
% if (property.needed_for_context and needed_for_context) or not \
|
style_${style_struct.name}.get_mut().${property.ident} =
|
||||||
needed_for_context:
|
match *declared_value {
|
||||||
&${property.ident}_declaration(SpecifiedValue(ref value)) => {
|
SpecifiedValue(ref specified_value)
|
||||||
let computed_value =
|
=> longhands::${property.ident}::to_computed_value(
|
||||||
longhands::${property.ident}::to_computed_value(
|
(*specified_value).clone(),
|
||||||
(*value).clone(),
|
&context
|
||||||
&context);
|
),
|
||||||
% if property.needed_for_context and needed_for_context:
|
CSSWideKeyword(Initial)
|
||||||
context.set_${property.ident}(computed_value)
|
=> longhands::${property.ident}::get_initial_value(),
|
||||||
% elif not needed_for_context:
|
CSSWideKeyword(Inherit) => {
|
||||||
// Overwrite earlier declarations.
|
|
||||||
style_${style_struct.name}.get_mut().${property.ident} =
|
|
||||||
computed_value
|
|
||||||
% endif
|
|
||||||
}
|
|
||||||
&${property.ident}_declaration(CSSWideKeyword(Initial)) => {
|
|
||||||
let computed_value =
|
|
||||||
longhands::${property.ident}::get_initial_value();
|
|
||||||
% if property.needed_for_context and needed_for_context:
|
|
||||||
context.set_${property.ident}(computed_value)
|
|
||||||
% elif not needed_for_context:
|
|
||||||
// Overwrite earlier declarations.
|
|
||||||
style_${style_struct.name}.get_mut().${property.ident} =
|
|
||||||
computed_value
|
|
||||||
% endif
|
|
||||||
}
|
|
||||||
% endif
|
|
||||||
% if not needed_for_context:
|
|
||||||
&${property.ident}_declaration(CSSWideKeyword(Inherit)) => {
|
|
||||||
// This is a bit slow, but this is rare so it shouldn't matter.
|
// This is a bit slow, but this is rare so it shouldn't matter.
|
||||||
|
// FIXME: is it still?
|
||||||
cacheable = false;
|
cacheable = false;
|
||||||
match parent_style {
|
inherited_style.${style_struct.name}
|
||||||
None => {
|
.get()
|
||||||
style_${style_struct.name}.get_mut()
|
.${property.ident}
|
||||||
.${property.ident} =
|
.clone()
|
||||||
longhands::${property.ident}::get_initial_value()
|
|
||||||
}
|
|
||||||
Some(ref parent_style) => {
|
|
||||||
style_${style_struct.name}.get_mut()
|
|
||||||
.${property.ident} =
|
|
||||||
parent_style.${style_struct.name}
|
|
||||||
.get()
|
|
||||||
.${property.ident}
|
|
||||||
.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
% endif
|
}
|
||||||
% endfor
|
}
|
||||||
% endfor
|
% endfor
|
||||||
% if needed_for_context:
|
% endfor
|
||||||
_ => {}
|
|
||||||
% endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%def>
|
}
|
||||||
|
|
||||||
${apply(True)}
|
|
||||||
context.use_parent_font_size = false;
|
|
||||||
${apply(False)}
|
|
||||||
|
|
||||||
(ComputedValues {
|
(ComputedValues {
|
||||||
% for style_struct in STYLE_STRUCTS:
|
% for style_struct in STYLE_STRUCTS:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue