diff --git a/properties/common_types.rs b/properties/common_types.rs index 8031df10479..358cbc1edd8 100644 --- a/properties/common_types.rs +++ b/properties/common_types.rs @@ -12,6 +12,7 @@ pub mod specified { use super::{Integer, Float}; pub use CSSColor = cssparser::Color; + #[deriving(Clone)] pub enum Length { Au(Integer), // application units Em(Float), @@ -65,6 +66,7 @@ pub mod specified { } } + #[deriving(Clone)] pub enum LengthOrPercentage { LP_Length(Length), LP_Percentage(Float), @@ -91,6 +93,7 @@ pub mod specified { } } + #[deriving(Clone)] pub enum LengthOrPercentageOrAuto { LPA_Length(Length), LPA_Percentage(Float), @@ -123,19 +126,23 @@ pub mod specified { pub mod computed { use cssparser; pub use CSSColor = cssparser::Color; - pub use compute_CSSColor = std::util::id; + pub use compute_CSSColor = super::super::longhands::computed_as_specified; use super::*; - use super::super::longhands::font_weight; + use super::super::longhands; pub struct Context { current_color: cssparser::RGBA, + font_size: Length, + font_weight: longhands::font_weight::ComputedValue, + position: longhands::position::SpecifiedValue, + float: longhands::float::SpecifiedValue, + is_root_element: bool, has_border_top: bool, has_border_right: bool, has_border_bottom: bool, has_border_left: bool, - font_size: Length, - font_weight: font_weight::ComputedValue, // TODO, as needed: root font size, viewport size, etc. } + #[deriving(Clone)] pub struct Length(Integer); // in application units impl Length { pub fn times(self, factor: Float) -> Length { @@ -154,6 +161,7 @@ pub mod computed { } } + #[deriving(Clone)] pub enum LengthOrPercentage { LP_Length(Length), LP_Percentage(Float), @@ -166,6 +174,7 @@ pub mod computed { } } + #[deriving(Clone)] pub enum LengthOrPercentageOrAuto { LPA_Length(Length), LPA_Percentage(Float), diff --git a/properties/mod.rs.mako b/properties/mod.rs.mako index 755bca0389b..250f548670a 100644 --- a/properties/mod.rs.mako +++ b/properties/mod.rs.mako @@ -54,6 +54,8 @@ pub mod longhands { pub use super::*; pub use std; + pub fn computed_as_specified(value: T, _context: &computed::Context) -> T { value } + <%def name="raw_longhand(name, inherited=False, no_super=False)"> <% property = Longhand(name, inherited) @@ -100,7 +102,8 @@ pub mod longhands { <%def name="single_keyword(name, values, inherited=False)"> <%self:single_component_value name="${name}" inherited="${inherited}"> // The computed value is the same as the specified value. - pub use to_computed_value = std::util::id; + pub use to_computed_value = super::computed_as_specified; + #[deriving(Clone)] pub enum SpecifiedValue { % for value in values.split(): ${to_rust_ident(value)}, @@ -153,14 +156,14 @@ pub mod longhands { "parse_non_negative")} % endfor + ${new_style_struct("Border")} + % for side in ["top", "right", "bottom", "left"]: ${predefined_type("border-%s-color" % side, "CSSColor", "CurrentColor")} % endfor - ${new_style_struct("Border")} - - // dotted dashed double groove ridge insed outset hidden - ${single_keyword("border-top-style", "none solid")} + // dotted dashed double groove ridge insed outset + ${single_keyword("border-top-style", "none solid hidden")} % for side in ["right", "bottom", "left"]: <%self:longhand name="border-${side}-style", no_super="True"> pub use super::border_top_style::*; @@ -223,6 +226,7 @@ pub mod longhands { "parse_non_negative")} <%self:single_component_value name="line-height"> + #[deriving(Clone)] pub enum SpecifiedValue { SpecifiedNormal, SpecifiedLength(specified::Length), @@ -244,6 +248,7 @@ pub mod longhands { _ => None, } } + #[deriving(Clone)] pub enum ComputedValue { Normal, Length(computed::Length), @@ -277,7 +282,7 @@ pub mod longhands { ${new_style_struct("Color")} <%self:raw_longhand name="color" inherited="True"> - pub use to_computed_value = std::util::id; + pub use to_computed_value = super::computed_as_specified; pub type SpecifiedValue = RGBA; pub type ComputedValue = SpecifiedValue; #[inline] pub fn get_initial_value() -> ComputedValue { @@ -297,7 +302,8 @@ pub mod longhands { ${new_style_struct("Font")} <%self:longhand name="font-family" inherited="True"> - pub use to_computed_value = std::util::id; + pub use to_computed_value = super::computed_as_specified; + #[deriving(Clone)] enum FontFamily { FamilyName(~str), // Generic @@ -373,6 +379,7 @@ pub mod longhands { ${single_keyword("font-variant", "normal", inherited=True)} // Add small-caps when supported <%self:single_component_value name="font-weight" inherited="True"> + #[deriving(Clone)] pub enum SpecifiedValue { Bolder, Lighther, @@ -405,6 +412,7 @@ pub mod longhands { _ => None } } + #[deriving(Clone)] pub enum ComputedValue { % for weight in range(100, 901, 100): Weight${weight}, @@ -470,7 +478,8 @@ pub mod longhands { ${single_keyword("text-align", "left right center justify", inherited=True)} <%self:longhand name="text-decoration"> - pub use to_computed_value = std::util::id; + pub use to_computed_value = super::computed_as_specified; + #[deriving(Clone)] pub struct SpecifiedValue { underline: bool, overline: bool, @@ -670,6 +679,7 @@ pub fn parse_property_declaration_list(input: ~[Node]) -> PropertyDeclarationBlo } +#[deriving(Clone)] pub enum CSSWideKeyword { Initial, Inherit, @@ -690,6 +700,8 @@ impl CSSWideKeyword { } } + +#[deriving(Clone)] pub enum DeclaredValue { SpecifiedValue(T), CSSWideKeyword(CSSWideKeyword), @@ -751,6 +763,7 @@ impl PropertyDeclaration { } } + pub mod style_structs { use super::longhands; % for name, longhands in LONGHANDS_PER_STYLE_STRUCT: @@ -769,10 +782,10 @@ pub struct ComputedValues { } #[inline] -pub fn get_initial_values() -> ComputedValues { +fn get_initial_values() -> ComputedValues { ComputedValues { - % for name, longhands in LONGHANDS_PER_STYLE_STRUCT: - ${name}: style_structs::${name} { + % for style_struct, longhands in LONGHANDS_PER_STYLE_STRUCT: + ${style_struct}: style_structs::${style_struct} { % for longhand in longhands: ${longhand.ident}: longhands::${longhand.ident}::get_initial_value(), % endfor @@ -781,10 +794,89 @@ pub fn get_initial_values() -> ComputedValues { } } -pub fn cascade(applicable_declarations: &[PropertyDeclaration], parent_style: &ComputedValues) + +pub fn cascade(applicable_declarations: &[PropertyDeclaration], + parent_style: Option< &ComputedValues>) -> ComputedValues { - // TODO - let _ = applicable_declarations; - let _ = parent_style; - get_initial_values() + let initial_keep_alive; + let (parent_style, is_root_element) = match parent_style { + Some(s) => (s, false), + None => { + initial_keep_alive = ~get_initial_values(); + (&*initial_keep_alive, true) + } + }; + struct AllDeclaredValues { + % for property in LONGHANDS: + ${property.ident}: DeclaredValue, + % endfor + } + let mut specified = AllDeclaredValues { + % for property in LONGHANDS: + ${property.ident}: CSSWideKeyword(${ + "Inherit" if property.is_inherited else "Initial"}), + % endfor + }; + for declaration in applicable_declarations.iter() { + match declaration { + % for property in LONGHANDS: + &${property.ident}_declaration(ref value) => { + // Overwrite earlier declarations. + specified.${property.ident} = (*value).clone() // TODO: can we avoid a copy? + } + % endfor + } + } + // This assumes that the computed and specified values have the same Rust type. + macro_rules! get_specified( + ($style_struct: ident, $property: ident) => { + match specified.$property { + SpecifiedValue(value) => value, + CSSWideKeyword(Initial) => longhands::$property::get_initial_value(), + CSSWideKeyword(Inherit) => parent_style.$style_struct.$property.clone(), + } + }; + ) + macro_rules! has_border( + ($property: ident) => { + match get_specified!(Border, $property) { + longhands::border_top_style::none + | longhands::border_top_style::hidden => false, + _ => true, + } + }; + ) + let context = &mut computed::Context { + current_color: get_specified!(Color, color), + font_size: parent_style.Font.font_size, + font_weight: parent_style.Font.font_weight, + position: get_specified!(Box, position), + float: get_specified!(Box, float), + is_root_element: is_root_element, + has_border_top: has_border!(border_top_style), + has_border_right: has_border!(border_right_style), + has_border_bottom: has_border!(border_bottom_style), + has_border_left: has_border!(border_left_style), + }; + macro_rules! get_computed( + ($style_struct: ident, $property: ident) => { + match specified.$property { + SpecifiedValue(ref value) + // TODO: avoid a copy? + => longhands::$property::to_computed_value(value.clone(), context), + CSSWideKeyword(Initial) => longhands::$property::get_initial_value(), + CSSWideKeyword(Inherit) => parent_style.$style_struct.$property.clone(), + } + }; + ) + context.font_size = get_computed!(Font, font_size); + ComputedValues { + % for style_struct, longhands in LONGHANDS_PER_STYLE_STRUCT: + ${style_struct}: style_structs::${style_struct} { + % for longhand in longhands: + ${longhand.ident}: get_computed!(${style_struct}, ${longhand.ident}), + % endfor + }, + % endfor + } }