mirror of
https://github.com/servo/servo.git
synced 2025-06-20 07:08:59 +01:00
style: Separate out style structs into inherited and initial structs.
This doesn't make much of a difference in performance, but will be necessary for style struct sharing.
This commit is contained in:
parent
6b89cbf3c5
commit
758f5ba755
6 changed files with 251 additions and 175 deletions
|
@ -719,7 +719,7 @@ impl Flow for BlockFlow {
|
||||||
let style = box_.style();
|
let style = box_.style();
|
||||||
|
|
||||||
// The text alignment of a block flow is the text alignment of its box's style.
|
// The text alignment of a block flow is the text alignment of its box's style.
|
||||||
self.base.flags_info.flags.set_text_align(style.Text.text_align);
|
self.base.flags_info.flags.set_text_align(style.InheritedText.text_align);
|
||||||
|
|
||||||
box_.assign_width(remaining_width);
|
box_.assign_width(remaining_width);
|
||||||
// Can compute padding here since we know containing block width.
|
// Can compute padding here since we know containing block width.
|
||||||
|
|
|
@ -781,11 +781,11 @@ impl Box {
|
||||||
/// Returns the text alignment of the computed style of the nearest ancestor-or-self `Element`
|
/// Returns the text alignment of the computed style of the nearest ancestor-or-self `Element`
|
||||||
/// node.
|
/// node.
|
||||||
pub fn text_align(&self) -> text_align::T {
|
pub fn text_align(&self) -> text_align::T {
|
||||||
self.style().Text.text_align
|
self.style().InheritedText.text_align
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn line_height(&self) -> line_height::T {
|
pub fn line_height(&self) -> line_height::T {
|
||||||
self.style().Box.line_height
|
self.style().InheritedBox.line_height
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vertical_align(&self) -> vertical_align::T {
|
pub fn vertical_align(&self) -> vertical_align::T {
|
||||||
|
@ -793,7 +793,7 @@ impl Box {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn white_space(&self) -> white_space::T {
|
pub fn white_space(&self) -> white_space::T {
|
||||||
self.style().Text.white_space
|
self.style().InheritedText.white_space
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the text decoration of this box, according to the style of the nearest ancestor
|
/// Returns the text decoration of this box, according to the style of the nearest ancestor
|
||||||
|
@ -1029,7 +1029,7 @@ impl Box {
|
||||||
box_bounds, absolute_box_bounds, self.debug_str());
|
box_bounds, absolute_box_bounds, self.debug_str());
|
||||||
debug!("Box::build_display_list: dirty={}, offset={}", *dirty, offset);
|
debug!("Box::build_display_list: dirty={}, offset={}", *dirty, offset);
|
||||||
|
|
||||||
if self.style().Box.visibility != visibility::visible {
|
if self.style().InheritedBox.visibility != visibility::visible {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -730,7 +730,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
|
||||||
//
|
//
|
||||||
// If you implement other values for this property, you will almost certainly
|
// If you implement other values for this property, you will almost certainly
|
||||||
// want to update this check.
|
// want to update this check.
|
||||||
match self.style().get().Text.white_space {
|
match self.style().get().InheritedText.white_space {
|
||||||
white_space::normal => true,
|
white_space::normal => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,7 @@ pub fn compute_damage(old: &ComputedValues, new: &ComputedValues) -> RestyleDama
|
||||||
Padding.padding_top, Padding.padding_right, Padding.padding_bottom, Padding.padding_left,
|
Padding.padding_top, Padding.padding_right, Padding.padding_bottom, Padding.padding_left,
|
||||||
Box.position, Box.width, Box.height, Box.float, Box.display,
|
Box.position, Box.width, Box.height, Box.float, Box.display,
|
||||||
Font.font_family, Font.font_size, Font.font_style, Font.font_weight,
|
Font.font_family, Font.font_size, Font.font_style, Font.font_weight,
|
||||||
Text.text_align, Text.text_decoration, Box.line_height ]);
|
InheritedText.text_align, Text.text_decoration, InheritedBox.line_height ]);
|
||||||
|
|
||||||
// FIXME: test somehow that we checked every CSS property
|
// FIXME: test somehow that we checked every CSS property
|
||||||
|
|
||||||
|
|
|
@ -169,21 +169,24 @@ pub mod computed {
|
||||||
|
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
current_color: cssparser::RGBA,
|
current_color: cssparser::RGBA,
|
||||||
|
parent_font_size: Au,
|
||||||
font_size: Au,
|
font_size: Au,
|
||||||
font_weight: longhands::font_weight::computed_value::T,
|
font_weight: longhands::font_weight::computed_value::T,
|
||||||
position: longhands::position::SpecifiedValue,
|
position: longhands::position::SpecifiedValue,
|
||||||
float: longhands::float::SpecifiedValue,
|
float: longhands::float::SpecifiedValue,
|
||||||
is_root_element: bool,
|
is_root_element: bool,
|
||||||
has_border_top: bool,
|
border_top_style: longhands::border_top_style::computed_value::T,
|
||||||
has_border_right: bool,
|
border_right_style: longhands::border_top_style::computed_value::T,
|
||||||
has_border_bottom: bool,
|
border_bottom_style: longhands::border_top_style::computed_value::T,
|
||||||
has_border_left: bool,
|
border_left_style: longhands::border_top_style::computed_value::T,
|
||||||
// TODO, as needed: root font size, viewport size, etc.
|
// TODO, as needed: root font size, viewport size, etc.
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_Au(value: specified::Length, context: &Context) -> Au {
|
#[inline]
|
||||||
|
pub fn compute_Au(value: specified::Length, context: &Context, em_is_parent: bool) -> Au {
|
||||||
match value {
|
match value {
|
||||||
specified::Au_(value) => value,
|
specified::Au_(value) => value,
|
||||||
|
specified::Em(value) if em_is_parent => context.parent_font_size.scale_by(value),
|
||||||
specified::Em(value) => context.font_size.scale_by(value),
|
specified::Em(value) => context.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
|
||||||
|
@ -200,7 +203,7 @@ pub mod computed {
|
||||||
pub fn compute_LengthOrPercentage(value: specified::LengthOrPercentage, context: &Context)
|
pub fn compute_LengthOrPercentage(value: specified::LengthOrPercentage, context: &Context)
|
||||||
-> LengthOrPercentage {
|
-> LengthOrPercentage {
|
||||||
match value {
|
match value {
|
||||||
specified::LP_Length(value) => LP_Length(compute_Au(value, context)),
|
specified::LP_Length(value) => LP_Length(compute_Au(value, context, false)),
|
||||||
specified::LP_Percentage(value) => LP_Percentage(value),
|
specified::LP_Percentage(value) => LP_Percentage(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +217,7 @@ pub mod computed {
|
||||||
pub fn compute_LengthOrPercentageOrAuto(value: specified::LengthOrPercentageOrAuto,
|
pub fn compute_LengthOrPercentageOrAuto(value: specified::LengthOrPercentageOrAuto,
|
||||||
context: &Context) -> LengthOrPercentageOrAuto {
|
context: &Context) -> LengthOrPercentageOrAuto {
|
||||||
match value {
|
match value {
|
||||||
specified::LPA_Length(value) => LPA_Length(compute_Au(value, context)),
|
specified::LPA_Length(value) => LPA_Length(compute_Au(value, context, false)),
|
||||||
specified::LPA_Percentage(value) => LPA_Percentage(value),
|
specified::LPA_Percentage(value) => LPA_Percentage(value),
|
||||||
specified::LPA_Auto => LPA_Auto,
|
specified::LPA_Auto => LPA_Auto,
|
||||||
}
|
}
|
||||||
|
@ -229,7 +232,7 @@ pub mod computed {
|
||||||
pub fn compute_LengthOrPercentageOrNone(value: specified::LengthOrPercentageOrNone,
|
pub fn compute_LengthOrPercentageOrNone(value: specified::LengthOrPercentageOrNone,
|
||||||
context: &Context) -> LengthOrPercentageOrNone {
|
context: &Context) -> LengthOrPercentageOrNone {
|
||||||
match value {
|
match value {
|
||||||
specified::LPN_Length(value) => LPN_Length(compute_Au(value, context)),
|
specified::LPN_Length(value) => LPN_Length(compute_Au(value, context, false)),
|
||||||
specified::LPN_Percentage(value) => LPN_Percentage(value),
|
specified::LPN_Percentage(value) => LPN_Percentage(value),
|
||||||
specified::LPN_None => LPN_None,
|
specified::LPN_None => LPN_None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,43 +25,61 @@ def to_rust_ident(name):
|
||||||
return name
|
return name
|
||||||
|
|
||||||
class Longhand(object):
|
class Longhand(object):
|
||||||
def __init__(self, name, is_inherited):
|
def __init__(self, name, priority):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.ident = to_rust_ident(name)
|
self.ident = to_rust_ident(name)
|
||||||
self.is_inherited = is_inherited
|
self.style_struct = THIS_STYLE_STRUCT
|
||||||
|
self.priority = priority
|
||||||
|
|
||||||
class Shorthand(object):
|
class Shorthand(object):
|
||||||
def __init__(self, name, sub_properties):
|
def __init__(self, name, priority, sub_properties):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.ident = to_rust_ident(name)
|
self.ident = to_rust_ident(name)
|
||||||
self.sub_properties = [LONGHANDS_BY_NAME[s] for s in sub_properties]
|
self.sub_properties = [LONGHANDS_BY_NAME[s] for s in sub_properties]
|
||||||
|
self.priority = priority
|
||||||
|
|
||||||
LONGHANDS_PER_STYLE_STRUCT = []
|
class StyleStruct(object):
|
||||||
THIS_STYLE_STRUCT_LONGHANDS = None
|
def __init__(self, name, inherited):
|
||||||
|
self.name = name
|
||||||
|
self.longhands = []
|
||||||
|
self.inherited = inherited
|
||||||
|
|
||||||
|
STYLE_STRUCTS = []
|
||||||
|
THIS_STYLE_STRUCT = None
|
||||||
LONGHANDS = []
|
LONGHANDS = []
|
||||||
LONGHANDS_BY_NAME = {}
|
LONGHANDS_BY_NAME = {}
|
||||||
SHORTHANDS = []
|
SHORTHANDS = []
|
||||||
|
|
||||||
def new_style_struct(name):
|
def new_style_struct(name, is_inherited):
|
||||||
longhands = []
|
global THIS_STYLE_STRUCT
|
||||||
LONGHANDS_PER_STYLE_STRUCT.append((name, longhands))
|
|
||||||
global THIS_STYLE_STRUCT_LONGHANDS
|
style_struct = StyleStruct(name, is_inherited)
|
||||||
THIS_STYLE_STRUCT_LONGHANDS = longhands
|
STYLE_STRUCTS.append(style_struct)
|
||||||
|
THIS_STYLE_STRUCT = style_struct
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
def switch_to_style_struct(name):
|
||||||
|
global THIS_STYLE_STRUCT
|
||||||
|
|
||||||
|
for style_struct in STYLE_STRUCTS:
|
||||||
|
if style_struct.name == name:
|
||||||
|
THIS_STYLE_STRUCT = style_struct
|
||||||
|
return ""
|
||||||
|
fail()
|
||||||
%>
|
%>
|
||||||
|
|
||||||
pub mod longhands {
|
pub mod longhands {
|
||||||
pub use super::*;
|
pub use super::*;
|
||||||
pub use std;
|
pub use std;
|
||||||
|
|
||||||
pub fn computed_as_specified<T>(value: T, _context: &computed::Context) -> T { value }
|
pub fn computed_as_specified<T>(value: T, _context: &mut computed::Context) -> T {
|
||||||
|
value
|
||||||
|
}
|
||||||
|
|
||||||
<%def name="raw_longhand(name, inherited=False, no_super=False)">
|
<%def name="raw_longhand(name, priority='Normal', no_super=False)">
|
||||||
<%
|
<%
|
||||||
property = Longhand(name, inherited)
|
property = Longhand(name, priority)
|
||||||
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
|
||||||
%>
|
%>
|
||||||
|
@ -76,15 +94,15 @@ pub mod longhands {
|
||||||
match CSSWideKeyword::parse(input) {
|
match CSSWideKeyword::parse(input) {
|
||||||
Some(Some(keyword)) => Some(CSSWideKeyword(keyword)),
|
Some(Some(keyword)) => Some(CSSWideKeyword(keyword)),
|
||||||
Some(None) => Some(CSSWideKeyword(${
|
Some(None) => Some(CSSWideKeyword(${
|
||||||
"Inherit" if inherited else "Initial"})),
|
"Inherit" if THIS_STYLE_STRUCT.inherited else "Initial"})),
|
||||||
None => parse_specified(input),
|
None => parse_specified(input),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="longhand(name, inherited=False, no_super=False)">
|
<%def name="longhand(name, priority='Normal', no_super=False)">
|
||||||
<%self:raw_longhand name="${name}" inherited="${inherited}">
|
<%self:raw_longhand name="${name}" priority="${priority}">
|
||||||
${caller.body()}
|
${caller.body()}
|
||||||
pub fn parse_specified(input: &[ComponentValue])
|
pub fn parse_specified(input: &[ComponentValue])
|
||||||
-> Option<DeclaredValue<SpecifiedValue>> {
|
-> Option<DeclaredValue<SpecifiedValue>> {
|
||||||
|
@ -93,8 +111,8 @@ pub mod longhands {
|
||||||
</%self:raw_longhand>
|
</%self:raw_longhand>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="single_component_value(name, inherited=False)">
|
<%def name="single_component_value(name, priority='Normal')">
|
||||||
<%self:longhand name="${name}" inherited="${inherited}">
|
<%self:longhand name="${name}" priority="${priority}">
|
||||||
${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)
|
||||||
|
@ -102,8 +120,8 @@ pub mod longhands {
|
||||||
</%self:longhand>
|
</%self:longhand>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="single_keyword_computed(name, values, inherited=False)">
|
<%def name="single_keyword_computed(name, values, priority='Normal')">
|
||||||
<%self:single_component_value name="${name}" inherited="${inherited}">
|
<%self:single_component_value name="${name}" priority="${priority}">
|
||||||
${caller.body()}
|
${caller.body()}
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
#[deriving(Eq, Clone, FromPrimitive)]
|
#[deriving(Eq, Clone, FromPrimitive)]
|
||||||
|
@ -130,15 +148,15 @@ pub mod longhands {
|
||||||
</%self:single_component_value>
|
</%self:single_component_value>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="single_keyword(name, values, inherited=False)">
|
<%def name="single_keyword(name, values, priority='Normal')">
|
||||||
<%self:single_keyword_computed name="${name}" values="${values}" inherited="${inherited}">
|
<%self:single_keyword_computed name="${name}" values="${values}" priority="${priority}">
|
||||||
// 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>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="predefined_type(name, type, initial_value, parse_method='parse', inherited=False)">
|
<%def name="predefined_type(name, type, initial_value, parse_method='parse')">
|
||||||
<%self:single_component_value name="${name}" inherited="${inherited}">
|
<%self:single_component_value name="${name}">
|
||||||
pub use to_computed_value = super::super::common_types::computed::compute_${type};
|
pub use to_computed_value = super::super::common_types::computed::compute_${type};
|
||||||
pub type SpecifiedValue = specified::${type};
|
pub type SpecifiedValue = specified::${type};
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
|
@ -154,14 +172,14 @@ pub mod longhands {
|
||||||
|
|
||||||
// CSS 2.1, Section 8 - Box model
|
// CSS 2.1, Section 8 - Box model
|
||||||
|
|
||||||
${new_style_struct("Margin")}
|
${new_style_struct("Margin", False)}
|
||||||
|
|
||||||
% for side in ["top", "right", "bottom", "left"]:
|
% for side in ["top", "right", "bottom", "left"]:
|
||||||
${predefined_type("margin-" + side, "LengthOrPercentageOrAuto",
|
${predefined_type("margin-" + side, "LengthOrPercentageOrAuto",
|
||||||
"computed::LPA_Length(Au(0))")}
|
"computed::LPA_Length(Au(0))")}
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
${new_style_struct("Padding")}
|
${new_style_struct("Padding", False)}
|
||||||
|
|
||||||
% for side in ["top", "right", "bottom", "left"]:
|
% for side in ["top", "right", "bottom", "left"]:
|
||||||
${predefined_type("padding-" + side, "LengthOrPercentage",
|
${predefined_type("padding-" + side, "LengthOrPercentage",
|
||||||
|
@ -169,17 +187,33 @@ pub mod longhands {
|
||||||
"parse_non_negative")}
|
"parse_non_negative")}
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
${new_style_struct("Border")}
|
${new_style_struct("Border", False)}
|
||||||
|
|
||||||
% for side in ["top", "right", "bottom", "left"]:
|
% for side in ["top", "right", "bottom", "left"]:
|
||||||
${predefined_type("border-%s-color" % side, "CSSColor", "CurrentColor")}
|
${predefined_type("border-%s-color" % side, "CSSColor", "CurrentColor")}
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
// double groove ridge insed outset
|
// double groove ridge insed outset
|
||||||
${single_keyword("border-top-style", "none solid dotted dashed hidden")}
|
<%self:single_keyword_computed name="border-top-style"
|
||||||
|
values="none solid dotted dashed hidden"
|
||||||
|
priority="High">
|
||||||
|
pub fn to_computed_value(value: SpecifiedValue, context: &mut computed::Context)
|
||||||
|
-> computed_value::T {
|
||||||
|
context.border_top_style = value;
|
||||||
|
value
|
||||||
|
}
|
||||||
|
</%self:single_keyword_computed>
|
||||||
% for side in ["right", "bottom", "left"]:
|
% for side in ["right", "bottom", "left"]:
|
||||||
<%self:longhand name="border-${side}-style", no_super="True">
|
<%self:longhand name="border-${side}-style", no_super="True", priority="High">
|
||||||
pub use super::border_top_style::*;
|
pub use super::border_top_style::get_initial_value;
|
||||||
|
pub use super::border_top_style::parse;
|
||||||
|
|
||||||
|
pub fn to_computed_value(value: SpecifiedValue, context: &mut computed::Context)
|
||||||
|
-> computed_value::T {
|
||||||
|
context.border_${side}_style = value;
|
||||||
|
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 {
|
||||||
pub type T = super::super::border_top_style::computed_value::T;
|
pub type T = super::super::border_top_style::computed_value::T;
|
||||||
|
@ -204,6 +238,7 @@ pub mod longhands {
|
||||||
}
|
}
|
||||||
% for side in ["top", "right", "bottom", "left"]:
|
% for side in ["top", "right", "bottom", "left"]:
|
||||||
<%self:longhand name="border-${side}-width">
|
<%self:longhand name="border-${side}-width">
|
||||||
|
use super::super::border_is_present;
|
||||||
pub type SpecifiedValue = specified::Length;
|
pub type SpecifiedValue = specified::Length;
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
use super::super::Au;
|
use super::super::Au;
|
||||||
|
@ -215,15 +250,18 @@ pub mod longhands {
|
||||||
pub fn parse(input: &[ComponentValue]) -> Option<SpecifiedValue> {
|
pub fn parse(input: &[ComponentValue]) -> Option<SpecifiedValue> {
|
||||||
one_component_value(input).and_then(parse_border_width)
|
one_component_value(input).and_then(parse_border_width)
|
||||||
}
|
}
|
||||||
pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context)
|
pub fn to_computed_value(value: SpecifiedValue, context: &mut computed::Context)
|
||||||
-> computed_value::T {
|
-> computed_value::T {
|
||||||
if context.has_border_${side} { computed::compute_Au(value, context) }
|
if !border_is_present(context.border_${side}_style) {
|
||||||
else { Au(0) }
|
Au(0)
|
||||||
|
} else {
|
||||||
|
computed::compute_Au(value, context, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</%self:longhand>
|
</%self:longhand>
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
${new_style_struct("PositionOffsets")}
|
${new_style_struct("PositionOffsets", False)}
|
||||||
|
|
||||||
% for side in ["top", "right", "bottom", "left"]:
|
% for side in ["top", "right", "bottom", "left"]:
|
||||||
${predefined_type(side, "LengthOrPercentageOrAuto",
|
${predefined_type(side, "LengthOrPercentageOrAuto",
|
||||||
|
@ -232,7 +270,7 @@ pub mod longhands {
|
||||||
|
|
||||||
// CSS 2.1, Section 9 - Visual formatting model
|
// CSS 2.1, Section 9 - Visual formatting model
|
||||||
|
|
||||||
${new_style_struct("Box")}
|
${new_style_struct("Box", False)}
|
||||||
|
|
||||||
// TODO: don't parse values we don't support
|
// TODO: don't parse values we don't support
|
||||||
<%self:single_keyword_computed name="display"
|
<%self:single_keyword_computed name="display"
|
||||||
|
@ -286,8 +324,9 @@ pub mod longhands {
|
||||||
"computed::LPN_None",
|
"computed::LPN_None",
|
||||||
"parse_non_negative")}
|
"parse_non_negative")}
|
||||||
|
|
||||||
|
${new_style_struct("InheritedBox", True)}
|
||||||
|
|
||||||
<%self:single_component_value name="line-height" inherited="True">
|
<%self:single_component_value name="line-height">
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub enum SpecifiedValue {
|
pub enum SpecifiedValue {
|
||||||
SpecifiedNormal,
|
SpecifiedNormal,
|
||||||
|
@ -324,12 +363,14 @@ pub mod longhands {
|
||||||
-> computed_value::T {
|
-> computed_value::T {
|
||||||
match value {
|
match value {
|
||||||
SpecifiedNormal => Normal,
|
SpecifiedNormal => Normal,
|
||||||
SpecifiedLength(value) => Length(computed::compute_Au(value, context)),
|
SpecifiedLength(value) => Length(computed::compute_Au(value, context, false)),
|
||||||
SpecifiedNumber(value) => Number(value),
|
SpecifiedNumber(value) => Number(value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%self:single_component_value>
|
</%self:single_component_value>
|
||||||
|
|
||||||
|
${switch_to_style_struct("Box")}
|
||||||
|
|
||||||
<%self:single_component_value name="vertical-align">
|
<%self:single_component_value name="vertical-align">
|
||||||
<% vertical_align_keywords = (
|
<% vertical_align_keywords = (
|
||||||
"baseline sub super top text-top middle bottom text-bottom".split()) %>
|
"baseline sub super top text-top middle bottom text-bottom".split()) %>
|
||||||
|
@ -387,14 +428,18 @@ pub mod longhands {
|
||||||
|
|
||||||
|
|
||||||
// CSS 2.1, Section 11 - Visual effects
|
// CSS 2.1, Section 11 - Visual effects
|
||||||
${single_keyword("overflow", "visible hidden", inherited=False)} // TODO: scroll auto
|
${single_keyword("overflow", "visible hidden")} // TODO: scroll auto
|
||||||
|
|
||||||
|
${switch_to_style_struct("InheritedBox")}
|
||||||
|
|
||||||
// TODO: collapse. Well, do tables first.
|
// TODO: collapse. Well, do tables first.
|
||||||
${single_keyword("visibility", "visible hidden", inherited=True)}
|
${single_keyword("visibility", "visible hidden")}
|
||||||
|
|
||||||
// CSS 2.1, Section 12 - Generated content, automatic numbering, and lists
|
// CSS 2.1, Section 12 - Generated content, automatic numbering, and lists
|
||||||
|
|
||||||
<%self:longhand name="content" inherited="False">
|
${switch_to_style_struct("Box")}
|
||||||
|
|
||||||
|
<%self:longhand name="content">
|
||||||
pub use to_computed_value = super::computed_as_specified;
|
pub use to_computed_value = super::computed_as_specified;
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
#[deriving(Eq, Clone)]
|
#[deriving(Eq, Clone)]
|
||||||
|
@ -437,15 +482,15 @@ pub mod longhands {
|
||||||
|
|
||||||
// CSS 2.1, Section 14 - Colors and Backgrounds
|
// CSS 2.1, Section 14 - Colors and Backgrounds
|
||||||
|
|
||||||
${new_style_struct("Background")}
|
${new_style_struct("Background", False)}
|
||||||
|
|
||||||
${predefined_type("background-color", "CSSColor",
|
${predefined_type("background-color", "CSSColor",
|
||||||
"RGBA(RGBA { red: 0., green: 0., blue: 0., alpha: 0. }) /* transparent */")}
|
"RGBA(RGBA { red: 0., green: 0., blue: 0., alpha: 0. }) /* transparent */")}
|
||||||
|
|
||||||
|
|
||||||
${new_style_struct("Color")}
|
${new_style_struct("Color", True)}
|
||||||
|
|
||||||
<%self:raw_longhand name="color" inherited="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 {
|
||||||
|
@ -465,9 +510,9 @@ pub mod longhands {
|
||||||
|
|
||||||
// CSS 2.1, Section 15 - Fonts
|
// CSS 2.1, Section 15 - Fonts
|
||||||
|
|
||||||
${new_style_struct("Font")}
|
${new_style_struct("Font", True)}
|
||||||
|
|
||||||
<%self:longhand name="font-family" inherited="True">
|
<%self:longhand name="font-family">
|
||||||
pub use to_computed_value = super::computed_as_specified;
|
pub use to_computed_value = super::computed_as_specified;
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
#[deriving(Eq, Clone)]
|
#[deriving(Eq, Clone)]
|
||||||
|
@ -545,10 +590,10 @@ pub mod longhands {
|
||||||
</%self:longhand>
|
</%self:longhand>
|
||||||
|
|
||||||
|
|
||||||
${single_keyword("font-style", "normal italic oblique", inherited=True)}
|
${single_keyword("font-style", "normal italic oblique")}
|
||||||
${single_keyword("font-variant", "normal", inherited=True)} // Add small-caps when supported
|
${single_keyword("font-variant", "normal")} // Add small-caps when supported
|
||||||
|
|
||||||
<%self:single_component_value name="font-weight" inherited="True">
|
<%self:single_component_value name="font-weight" priority="High">
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub enum SpecifiedValue {
|
pub enum SpecifiedValue {
|
||||||
Bolder,
|
Bolder,
|
||||||
|
@ -603,9 +648,9 @@ pub mod longhands {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline] pub fn get_initial_value() -> computed_value::T { Weight400 } // normal
|
#[inline] pub fn get_initial_value() -> computed_value::T { Weight400 } // normal
|
||||||
pub fn to_computed_value(value: SpecifiedValue, context: &computed::Context)
|
pub fn to_computed_value(value: SpecifiedValue, context: &mut computed::Context)
|
||||||
-> computed_value::T {
|
-> computed_value::T {
|
||||||
match value {
|
let result = match value {
|
||||||
% for weight in range(100, 901, 100):
|
% for weight in range(100, 901, 100):
|
||||||
SpecifiedWeight${weight} => Weight${weight},
|
SpecifiedWeight${weight} => Weight${weight},
|
||||||
% endfor
|
% endfor
|
||||||
|
@ -631,17 +676,25 @@ pub mod longhands {
|
||||||
Weight800 => Weight700,
|
Weight800 => Weight700,
|
||||||
Weight900 => Weight700,
|
Weight900 => Weight700,
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
context.font_weight = result;
|
||||||
|
result
|
||||||
}
|
}
|
||||||
</%self:single_component_value>
|
</%self:single_component_value>
|
||||||
|
|
||||||
<%self:single_component_value name="font-size" inherited="True">
|
<%self:single_component_value name="font-size" priority="High">
|
||||||
pub use to_computed_value = super::super::common_types::computed::compute_Au;
|
pub use to_computed_value = super::super::common_types::computed::compute_Au;
|
||||||
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;
|
||||||
pub type T = Au;
|
pub type T = Au;
|
||||||
}
|
}
|
||||||
|
pub fn to_computed_value(value: SpecifiedValue, context: &mut computed::Context)
|
||||||
|
-> computed_value::T {
|
||||||
|
let result = computed::compute_Au(value, context, true);
|
||||||
|
context.font_size = result;
|
||||||
|
result
|
||||||
|
}
|
||||||
#[inline] pub fn get_initial_value() -> computed_value::T {
|
#[inline] pub fn get_initial_value() -> computed_value::T {
|
||||||
Au::from_px(16) // medium
|
Au::from_px(16) // medium
|
||||||
}
|
}
|
||||||
|
@ -659,10 +712,12 @@ pub mod longhands {
|
||||||
|
|
||||||
// CSS 2.1, Section 16 - Text
|
// CSS 2.1, Section 16 - Text
|
||||||
|
|
||||||
${new_style_struct("Text")}
|
${new_style_struct("InheritedText", True)}
|
||||||
|
|
||||||
// TODO: initial value should be 'start' (CSS Text Level 3, direction-dependent.)
|
// TODO: initial value should be 'start' (CSS Text Level 3, direction-dependent.)
|
||||||
${single_keyword("text-align", "left right center justify", inherited=True)}
|
${single_keyword("text-align", "left right center justify")}
|
||||||
|
|
||||||
|
${new_style_struct("Text", False)}
|
||||||
|
|
||||||
<%self:longhand name="text-decoration">
|
<%self:longhand name="text-decoration">
|
||||||
pub use to_computed_value = super::computed_as_specified;
|
pub use to_computed_value = super::computed_as_specified;
|
||||||
|
@ -709,7 +764,9 @@ pub mod longhands {
|
||||||
}
|
}
|
||||||
</%self:longhand>
|
</%self:longhand>
|
||||||
|
|
||||||
${single_keyword("white-space", "normal pre", inherited=True)}
|
${switch_to_style_struct("InheritedText")}
|
||||||
|
|
||||||
|
${single_keyword("white-space", "normal pre")}
|
||||||
|
|
||||||
// CSS 2.1, Section 17 - Tables
|
// CSS 2.1, Section 17 - Tables
|
||||||
|
|
||||||
|
@ -721,9 +778,9 @@ pub mod shorthands {
|
||||||
pub use super::*;
|
pub use super::*;
|
||||||
pub use super::longhands::*;
|
pub use super::longhands::*;
|
||||||
|
|
||||||
<%def name="shorthand(name, sub_properties)">
|
<%def name="shorthand(name, sub_properties, priority='Normal')">
|
||||||
<%
|
<%
|
||||||
shorthand = Shorthand(name, sub_properties.split())
|
shorthand = Shorthand(name, priority, sub_properties.split())
|
||||||
SHORTHANDS.append(shorthand)
|
SHORTHANDS.append(shorthand)
|
||||||
%>
|
%>
|
||||||
pub mod ${shorthand.ident} {
|
pub mod ${shorthand.ident} {
|
||||||
|
@ -1029,7 +1086,7 @@ impl PropertyDeclaration {
|
||||||
% for sub_property in shorthand.sub_properties:
|
% for sub_property in shorthand.sub_properties:
|
||||||
result_list.push(${sub_property.ident}_declaration(
|
result_list.push(${sub_property.ident}_declaration(
|
||||||
CSSWideKeyword(${
|
CSSWideKeyword(${
|
||||||
"Inherit" if sub_property.is_inherited else "Initial"})
|
"Inherit" if sub_property.style_struct.inherited else "Initial"})
|
||||||
));
|
));
|
||||||
% endfor
|
% endfor
|
||||||
},
|
},
|
||||||
|
@ -1057,10 +1114,10 @@ impl PropertyDeclaration {
|
||||||
|
|
||||||
pub mod style_structs {
|
pub mod style_structs {
|
||||||
use super::longhands;
|
use super::longhands;
|
||||||
% for name, longhands in LONGHANDS_PER_STYLE_STRUCT:
|
% for style_struct in STYLE_STRUCTS:
|
||||||
#[deriving(Eq, Clone)]
|
#[deriving(Eq, Clone)]
|
||||||
pub struct ${name} {
|
pub struct ${style_struct.name} {
|
||||||
% for longhand in longhands:
|
% for longhand in style_struct.longhands:
|
||||||
${longhand.ident}: longhands::${longhand.ident}::computed_value::T,
|
${longhand.ident}: longhands::${longhand.ident}::computed_value::T,
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
|
@ -1069,8 +1126,8 @@ pub mod style_structs {
|
||||||
|
|
||||||
#[deriving(Eq, Clone)]
|
#[deriving(Eq, Clone)]
|
||||||
pub struct ComputedValues {
|
pub struct ComputedValues {
|
||||||
% for name, longhands in LONGHANDS_PER_STYLE_STRUCT:
|
% for style_struct in STYLE_STRUCTS:
|
||||||
${name}: style_structs::${name},
|
${style_struct.name}: style_structs::${style_struct.name},
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,111 +1147,127 @@ impl ComputedValues {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
/// Creates a new cascade context.
|
||||||
fn get_initial_values() -> ComputedValues {
|
fn new_cascade_context(style_Color: &style_structs::Color,
|
||||||
ComputedValues {
|
style_Font: &style_structs::Font,
|
||||||
% for style_struct, longhands in LONGHANDS_PER_STYLE_STRUCT:
|
style_Box: &style_structs::Box,
|
||||||
${style_struct}: style_structs::${style_struct} {
|
is_root_element: bool)
|
||||||
% for longhand in longhands:
|
-> computed::Context {
|
||||||
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
|
computed::Context {
|
||||||
% endfor
|
current_color: style_Color.color,
|
||||||
},
|
parent_font_size: style_Font.font_size,
|
||||||
% endfor
|
font_size: style_Font.font_size,
|
||||||
|
font_weight: style_Font.font_weight,
|
||||||
|
position: style_Box.position,
|
||||||
|
float: style_Box.float,
|
||||||
|
is_root_element: is_root_element,
|
||||||
|
border_top_style: longhands::border_top_style::get_initial_value(),
|
||||||
|
border_right_style: longhands::border_top_style::get_initial_value(),
|
||||||
|
border_bottom_style: longhands::border_top_style::get_initial_value(),
|
||||||
|
border_left_style: longhands::border_top_style::get_initial_value(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn border_is_present(border_style: longhands::border_top_style::computed_value::T) -> bool {
|
||||||
|
match border_style {
|
||||||
|
longhands::border_top_style::hidden | longhands::border_top_style::none => false,
|
||||||
|
_ => true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Most specific/important declarations last
|
/// Performs the CSS cascade, computing new styles for an element from its parent style and
|
||||||
|
/// optionally a cached related style. The arguments are:
|
||||||
|
///
|
||||||
|
/// * `applicable_declarations`: The list of CSS rules that matched.
|
||||||
|
///
|
||||||
|
/// * `parent_style`: The parent style, if applicable; if `None`, this is the root node.
|
||||||
|
///
|
||||||
|
/// Returns the computed values.
|
||||||
pub fn cascade(applicable_declarations: &[Arc<~[PropertyDeclaration]>],
|
pub fn cascade(applicable_declarations: &[Arc<~[PropertyDeclaration]>],
|
||||||
parent_style: Option< &ComputedValues>)
|
parent_style: Option< &ComputedValues >)
|
||||||
-> ComputedValues {
|
-> ComputedValues {
|
||||||
let initial_keep_alive;
|
let is_root_element;
|
||||||
let (parent_style, is_root_element) = match parent_style {
|
% for style_struct in STYLE_STRUCTS:
|
||||||
Some(s) => (s, false),
|
let mut style_${style_struct.name};
|
||||||
|
% 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} = style_structs::${style_struct.name} {
|
||||||
|
% for longhand in style_struct.longhands:
|
||||||
|
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
|
||||||
|
% endfor
|
||||||
|
};
|
||||||
|
%endif
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
initial_keep_alive = ~get_initial_values();
|
is_root_element = true;
|
||||||
(&*initial_keep_alive, true)
|
% for style_struct in STYLE_STRUCTS:
|
||||||
}
|
style_${style_struct.name} = style_structs::${style_struct.name} {
|
||||||
};
|
% for longhand in style_struct.longhands:
|
||||||
struct AllDeclaredValues {
|
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
|
||||||
% for property in LONGHANDS:
|
% endfor
|
||||||
${property.ident}: DeclaredValue<longhands::${property.ident}::SpecifiedValue>,
|
};
|
||||||
% endfor
|
% endfor
|
||||||
}
|
|
||||||
let mut specified = AllDeclaredValues {
|
|
||||||
% for property in LONGHANDS:
|
|
||||||
${property.ident}: CSSWideKeyword(${
|
|
||||||
"Inherit" if property.is_inherited else "Initial"}),
|
|
||||||
% endfor
|
|
||||||
};
|
|
||||||
for sub_list in applicable_declarations.iter() {
|
|
||||||
for declaration in sub_list.get().iter() {
|
|
||||||
match declaration {
|
|
||||||
% for property in LONGHANDS:
|
|
||||||
&${property.ident}_declaration(ref value) => {
|
|
||||||
// Overwrite earlier declarations.
|
|
||||||
// TODO: can we avoid a copy?
|
|
||||||
specified.${property.ident} = (*value).clone()
|
|
||||||
}
|
|
||||||
% endfor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// This assumes that the computed and specified values have the same Rust type.
|
|
||||||
macro_rules! get_specified(
|
let mut context = new_cascade_context(&style_Color, &style_Font, &style_Box, is_root_element);
|
||||||
($style_struct: ident, $property: ident) => {
|
|
||||||
match specified.$property {
|
<%def name="apply(priority)">
|
||||||
SpecifiedValue(value) => value,
|
for sub_list in applicable_declarations.iter() {
|
||||||
CSSWideKeyword(Initial) => longhands::$property::get_initial_value(),
|
for declaration in sub_list.get().iter() {
|
||||||
CSSWideKeyword(Inherit) => parent_style.$style_struct.$property.clone(),
|
match declaration {
|
||||||
|
% for style_struct in STYLE_STRUCTS:
|
||||||
|
% for property in style_struct.longhands:
|
||||||
|
% if property.priority == priority:
|
||||||
|
&${property.ident}_declaration(SpecifiedValue(ref value)) => {
|
||||||
|
// Overwrite earlier declarations.
|
||||||
|
// TODO: can we avoid a copy?
|
||||||
|
style_${style_struct.name}.${property.ident} =
|
||||||
|
longhands::${property.ident}::to_computed_value(
|
||||||
|
(*value).clone(),
|
||||||
|
&mut context)
|
||||||
|
}
|
||||||
|
&${property.ident}_declaration(CSSWideKeyword(Inherit)) => {
|
||||||
|
// This is a bit slow, but this is rare so it shouldn't matter.
|
||||||
|
match parent_style {
|
||||||
|
None => {
|
||||||
|
style_${style_struct.name}.${property.ident} =
|
||||||
|
longhands::${property.ident}::get_initial_value()
|
||||||
|
}
|
||||||
|
Some(ref parent_style) => {
|
||||||
|
style_${style_struct.name}.${property.ident} =
|
||||||
|
parent_style.${style_struct.name}
|
||||||
|
.${property.ident}
|
||||||
|
.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&${property.ident}_declaration(CSSWideKeyword(Initial)) => {
|
||||||
|
style_${style_struct.name}.${property.ident} =
|
||||||
|
longhands::${property.ident}::get_initial_value()
|
||||||
|
}
|
||||||
|
% endif
|
||||||
|
% endfor
|
||||||
|
% endfor
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
)
|
</%def>
|
||||||
macro_rules! has_border(
|
|
||||||
($property: ident) => {
|
${apply("High")}
|
||||||
match get_specified!(Border, $property) {
|
${apply("Normal")}
|
||||||
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 {
|
ComputedValues {
|
||||||
% for style_struct, longhands in LONGHANDS_PER_STYLE_STRUCT:
|
% for style_struct in STYLE_STRUCTS:
|
||||||
${style_struct}: style_structs::${style_struct} {
|
${style_struct.name}: style_${style_struct.name},
|
||||||
% for longhand in longhands:
|
|
||||||
${longhand.ident}:
|
|
||||||
% if longhand.ident == 'font_size':
|
|
||||||
context.font_size,
|
|
||||||
% else:
|
|
||||||
get_computed!(${style_struct}, ${longhand.ident}),
|
|
||||||
% endif
|
|
||||||
% endfor
|
|
||||||
},
|
|
||||||
% endfor
|
% endfor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue