aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorBobby Holley <bobbyholley@gmail.com>2016-03-04 16:53:57 -0800
committerBobby Holley <bobbyholley@gmail.com>2016-03-24 11:49:46 -0700
commit5c749127cc4e56a89ceb19f2cbe44693cedd4eba (patch)
tree7f591ecda7b8ffbe4da483d49ef8e8f5bf3157e1 /components
parent16d2e9af65d6bc62fb73f7ab5152ad6723eb9d28 (diff)
downloadservo-5c749127cc4e56a89ceb19f2cbe44693cedd4eba.tar.gz
servo-5c749127cc4e56a89ceb19f2cbe44693cedd4eba.zip
Introduce traits for style structs and computed values.
Diffstat (limited to 'components')
-rw-r--r--components/gfx/display_list/mod.rs2
-rw-r--r--components/style/animation.rs2
-rw-r--r--components/style/matching.rs2
-rw-r--r--components/style/properties.mako.rs680
-rw-r--r--components/style/values.rs68
-rw-r--r--components/style/viewport.rs6
6 files changed, 489 insertions, 271 deletions
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs
index 7bba2ce0e53..747543dd7fc 100644
--- a/components/gfx/display_list/mod.rs
+++ b/components/gfx/display_list/mod.rs
@@ -41,7 +41,7 @@ use std::ops::{Deref, DerefMut};
use std::sync::Arc;
use style::computed_values::{border_style, cursor, filter, image_rendering, mix_blend_mode};
use style::computed_values::{pointer_events};
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use style_traits::cursor::Cursor;
use text::TextRun;
use text::glyph::CharIndex;
diff --git a/components/style/animation.rs b/components/style/animation.rs
index b152be5fcc3..ea901beca92 100644
--- a/components/style/animation.rs
+++ b/components/style/animation.rs
@@ -7,7 +7,6 @@ use bezier::Bezier;
use cssparser::{Color, RGBA};
use dom::{OpaqueNode, TRestyleDamage};
use euclid::point::Point2D;
-use properties::ComputedValues;
use properties::longhands::background_position::computed_value::T as BackgroundPosition;
use properties::longhands::border_spacing::computed_value::T as BorderSpacing;
use properties::longhands::clip::computed_value::ClipRect;
@@ -25,6 +24,7 @@ use properties::longhands::transition_timing_function::computed_value::{Transiti
use properties::longhands::vertical_align::computed_value::T as VerticalAlign;
use properties::longhands::visibility::computed_value::T as Visibility;
use properties::longhands::z_index::computed_value::T as ZIndex;
+use properties::{ComputedValues, TComputedValues};
use std::cmp::Ordering;
use std::iter::repeat;
use std::sync::mpsc::Sender;
diff --git a/components/style/matching.rs b/components/style/matching.rs
index 1c158505e97..2459500f308 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -8,7 +8,7 @@ use animation::{self, Animation};
use context::SharedStyleContext;
use data::PrivateStyleData;
use dom::{TElement, TNode, TRestyleDamage};
-use properties::{ComputedValues, PropertyDeclaration, cascade};
+use properties::{ComputedValues, PropertyDeclaration, TComputedValues, cascade};
use selector_impl::SelectorImplExt;
use selector_matching::{DeclarationBlock, Stylist};
use selectors::Element;
diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs
index b3fa89483fa..7c0189f599e 100644
--- a/components/style/properties.mako.rs
+++ b/components/style/properties.mako.rs
@@ -10,9 +10,7 @@
use std::ascii::AsciiExt;
use std::collections::HashSet;
-use std::default::Default;
use std::fmt;
-use std::hash::{Hash, Hasher};
use std::intrinsics;
use std::mem;
use std::sync::Arc;
@@ -24,7 +22,6 @@ use error_reporting::ParseErrorReporter;
use url::Url;
use euclid::SideOffsets2D;
use euclid::size::Size2D;
-use fnv::FnvHasher;
use string_cache::Atom;
use computed_values;
use logical_geometry::{LogicalMargin, PhysicalSide, WritingMode};
@@ -32,7 +29,7 @@ use parser::{ParserContext, log_css_error};
use selectors::matching::DeclarationBlock;
use stylesheets::Origin;
use values::AuExtensionMethods;
-use values::computed::{self, ToComputedValue};
+use values::computed::{self, TContext, ToComputedValue};
use values::specified::BorderStyle;
use self::property_bit_field::PropertyBitField;
@@ -142,18 +139,20 @@ pub mod longhands {
use error_reporting::ParseErrorReporter;
use properties::longhands;
use properties::property_bit_field::PropertyBitField;
- use properties::{ComputedValues, PropertyDeclaration};
+ use properties::{ComputedValues, PropertyDeclaration, TComputedValues};
+ use properties::style_struct_traits::T${THIS_STYLE_STRUCT.name};
use properties::style_structs;
use std::collections::HashMap;
use std::sync::Arc;
- use values::computed::ToComputedValue;
+ use values::computed::{TContext, ToComputedValue};
use values::{computed, specified};
use string_cache::Atom;
${caller.body()}
#[allow(unused_variables)]
- pub fn cascade_property(declaration: &PropertyDeclaration,
- inherited_style: &ComputedValues,
- context: &mut computed::Context,
+ pub fn cascade_property<C: TComputedValues>(
+ declaration: &PropertyDeclaration,
+ inherited_style: &C,
+ context: &mut computed::Context<C>,
seen: &mut PropertyBitField,
cacheable: &mut bool,
error_reporter: &mut Box<ParseErrorReporter + Send>) {
@@ -168,33 +167,35 @@ pub mod longhands {
return
}
seen.set_${property.ident}();
-
{
- let custom_props = context.style.custom_properties.clone();
- ::properties::substitute_variables_${property.ident}(
- declared_value, &custom_props, |value| match *value {
- DeclaredValue::Value(ref specified_value) => {
- Arc::make_mut(&mut context.style.${THIS_STYLE_STRUCT.ident}).${property.ident} =
- specified_value.to_computed_value(&context);
- }
- DeclaredValue::WithVariables { .. } => unreachable!(),
- DeclaredValue::Initial => {
- Arc::make_mut(&mut context.style.${THIS_STYLE_STRUCT.ident}).${property.ident} =
- get_initial_value();
- },
- DeclaredValue::Inherit => {
- // This is a bit slow, but this is rare so it shouldn't
- // matter.
- //
- // FIXME: is it still?
- *cacheable = false;
- Arc::make_mut(&mut context.style.${THIS_STYLE_STRUCT.ident}).${property.ident} =
- inherited_style.${THIS_STYLE_STRUCT.ident}
- .${property.ident}
- .clone();
- }
- }, error_reporter
- );
+ let custom_props = context.style().custom_properties();
+ ::properties::substitute_variables_${property.ident}(
+ declared_value, &custom_props, |value| match *value {
+ DeclaredValue::Value(ref specified_value) => {
+ let computed = specified_value.to_computed_value(context);
+ context.mutate_style().mutate_${THIS_STYLE_STRUCT.name.lower()}()
+ .set_${property.ident}(computed);
+ }
+ DeclaredValue::WithVariables { .. } => unreachable!(),
+ DeclaredValue::Initial => {
+ // We assume that it's faster to use copy_*_from rather than
+ // set_*(get_initial_value());
+ let initial_struct = C::initial_values().get_${THIS_STYLE_STRUCT.name.lower()}();
+ context.mutate_style().mutate_${THIS_STYLE_STRUCT.name.lower()}()
+ .copy_${property.ident}_from(initial_struct);
+ },
+ DeclaredValue::Inherit => {
+ // This is a bit slow, but this is rare so it shouldn't
+ // matter.
+ //
+ // FIXME: is it still?
+ *cacheable = false;
+ let inherited_struct = inherited_style.get_${THIS_STYLE_STRUCT.name.lower()}();
+ context.mutate_style().mutate_${THIS_STYLE_STRUCT.name.lower()}()
+ .copy_${property.ident}_from(inherited_struct);
+ }
+ }, error_reporter
+ );
}
% if custom_cascade:
@@ -341,7 +342,6 @@ pub mod longhands {
use app_units::Au;
use cssparser::ToCss;
use std::fmt;
- use values::computed::Context;
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -368,7 +368,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
self.0.to_computed_value(context)
}
}
@@ -406,7 +406,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -428,7 +427,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
self.0.to_computed_value(context)
}
}
@@ -460,6 +459,7 @@ pub mod longhands {
%>
pub use self::computed_value::T as SpecifiedValue;
use values::computed::{Context, ComputedValueAsSpecified};
+ use properties::style_struct_traits::TInheritedText;
pub mod computed_value {
#[allow(non_camel_case_types)]
@@ -505,9 +505,10 @@ pub mod longhands {
impl ComputedValueAsSpecified for SpecifiedValue {}
- fn cascade_property_custom(_declaration: &PropertyDeclaration,
- _inherited_style: &ComputedValues,
- context: &mut computed::Context,
+ fn cascade_property_custom<C: TComputedValues>(
+ _declaration: &PropertyDeclaration,
+ _inherited_style: &C,
+ context: &mut computed::Context<C>,
_seen: &mut PropertyBitField,
_cacheable: &mut bool,
_error_reporter: &mut Box<ParseErrorReporter + Send>) {
@@ -519,14 +520,12 @@ pub mod longhands {
${single_keyword("position", "static absolute relative fixed")}
<%self:single_keyword_computed name="float" values="none left right">
- use values::computed::Context;
-
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
- let positioned = matches!(context.style.box_.position,
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
+ let positioned = matches!(context.style().get_box().clone_position(),
longhands::position::SpecifiedValue::absolute |
longhands::position::SpecifiedValue::fixed);
if positioned {
@@ -550,8 +549,9 @@ pub mod longhands {
}
#[inline]
- pub fn derive_from_display(context: &mut computed::Context) {
- Arc::make_mut(&mut context.style.box_)._servo_display_for_hypothetical_box = context.style.box_.display;
+ pub fn derive_from_display<Cx: TContext>(context: &mut Cx) {
+ let d = context.style().get_box().clone_display();
+ context.mutate_style().mutate_box().set__servo_display_for_hypothetical_box(d);
}
</%self:longhand>
@@ -639,7 +639,6 @@ pub mod longhands {
use std::fmt;
use values::AuExtensionMethods;
use values::CSSFloat;
- use values::computed::Context;
#[derive(Debug, Clone, PartialEq, Copy, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -702,7 +701,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Normal => computed_value::T::Normal,
SpecifiedValue::Number(value) => computed_value::T::Number(value),
@@ -732,7 +731,6 @@ pub mod longhands {
<%self:longhand name="vertical-align">
use cssparser::ToCss;
use std::fmt;
- use values::computed::Context;
<% vertical_align_keywords = (
"baseline sub super top text-top middle bottom text-bottom".split()) %>
@@ -800,7 +798,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
% for keyword in vertical_align_keywords:
SpecifiedValue::${to_rust_ident(keyword)} => {
@@ -826,7 +824,6 @@ pub mod longhands {
// FIXME(pcwalton, #2742): Implement scrolling for `scroll` and `auto`.
<%self:longhand name="overflow-y">
use super::overflow_x;
- use values::computed::Context;
use cssparser::ToCss;
use std::fmt;
@@ -848,7 +845,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T(self.0.to_computed_value(context))
}
}
@@ -1055,7 +1052,6 @@ pub mod longhands {
use cssparser::{ToCss, Token};
use std::fmt;
use url::Url;
- use values::computed::Context;
use values::LocalToCss;
#[derive(Debug, Clone, PartialEq, Eq, HeapSizeOf)]
@@ -1096,7 +1092,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::None => computed_value::T(None),
SpecifiedValue::Url(ref url) => computed_value::T(Some(url.clone())),
@@ -1275,7 +1271,6 @@ pub mod longhands {
<%self:longhand name="background-image">
use cssparser::ToCss;
use std::fmt;
- use values::computed::Context;
use values::specified::Image;
use values::LocalToCss;
@@ -1323,7 +1318,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue(None) => computed_value::T(None),
SpecifiedValue(Some(ref image)) =>
@@ -1337,7 +1332,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
pub mod computed_value {
use values::computed::LengthOrPercentage;
@@ -1422,7 +1416,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T {
horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context),
@@ -1459,7 +1453,6 @@ pub mod longhands {
use cssparser::{ToCss, Token};
use std::ascii::AsciiExt;
use std::fmt;
- use values::computed::Context;
pub mod computed_value {
use values::computed::LengthOrPercentageOrAuto;
@@ -1532,7 +1525,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &computed::Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Explicit(ref size) => {
computed_value::T::Explicit(computed_value::ExplicitSize {
@@ -1596,14 +1589,13 @@ pub mod longhands {
<%self:raw_longhand name="color">
use cssparser::{Color, RGBA};
- use values::computed::Context;
use values::specified::{CSSColor, CSSRGBA};
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> computed_value::T {
self.parsed
}
}
@@ -1750,7 +1742,6 @@ pub mod longhands {
<%self:longhand name="font-weight">
use cssparser::ToCss;
use std::fmt;
- use values::computed::Context;
#[derive(Debug, Clone, PartialEq, Eq, Copy, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -1834,12 +1825,12 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
% for weight in range(100, 901, 100):
SpecifiedValue::Weight${weight} => computed_value::T::Weight${weight},
% endfor
- SpecifiedValue::Bolder => match context.inherited_style.font.font_weight {
+ SpecifiedValue::Bolder => match context.inherited_style().get_font().clone_font_weight() {
computed_value::T::Weight100 => computed_value::T::Weight400,
computed_value::T::Weight200 => computed_value::T::Weight400,
computed_value::T::Weight300 => computed_value::T::Weight400,
@@ -1850,7 +1841,7 @@ pub mod longhands {
computed_value::T::Weight800 => computed_value::T::Weight900,
computed_value::T::Weight900 => computed_value::T::Weight900,
},
- SpecifiedValue::Lighter => match context.inherited_style.font.font_weight {
+ SpecifiedValue::Lighter => match context.inherited_style().get_font().clone_font_weight() {
computed_value::T::Weight100 => computed_value::T::Weight100,
computed_value::T::Weight200 => computed_value::T::Weight100,
computed_value::T::Weight300 => computed_value::T::Weight100,
@@ -1871,7 +1862,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::FONT_MEDIUM_PX;
- use values::computed::Context;
use values::specified::{LengthOrPercentage, Length, Percentage};
impl ToCss for SpecifiedValue {
@@ -1894,24 +1884,25 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match self.0 {
LengthOrPercentage::Length(Length::FontRelative(value)) => {
- value.to_computed_value(context.inherited_style.font.font_size,
- context.style.root_font_size)
+ value.to_computed_value(context.inherited_style().get_font().clone_font_size(),
+ context.style().root_font_size())
}
LengthOrPercentage::Length(Length::ServoCharacterWidth(value)) => {
- value.to_computed_value(context.inherited_style.font.font_size)
+ value.to_computed_value(context.inherited_style().get_font().clone_font_size())
}
LengthOrPercentage::Length(l) => {
- l.to_computed_value(&context)
+ l.to_computed_value(context)
}
LengthOrPercentage::Percentage(Percentage(value)) => {
- context.inherited_style.font.font_size.scale_by(value)
+ context.inherited_style().get_font().clone_font_size().scale_by(value)
}
LengthOrPercentage::Calc(calc) => {
- let calc = calc.to_computed_value(&context);
- calc.length() + context.inherited_style.font.font_size.scale_by(calc.percentage())
+ let calc = calc.to_computed_value(context);
+ calc.length() + context.inherited_style().get_font().clone_font_size()
+ .scale_by(calc.percentage())
}
}
}
@@ -1995,7 +1986,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
#[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -2036,7 +2026,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) =>
@@ -2058,7 +2048,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
#[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -2099,7 +2088,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) =>
@@ -2139,6 +2128,7 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::computed::ComputedValueAsSpecified;
+ use properties::style_struct_traits::TInheritedText;
impl ComputedValueAsSpecified for SpecifiedValue {}
@@ -2210,9 +2200,10 @@ pub mod longhands {
if !empty { Ok(result) } else { Err(()) }
}
- fn cascade_property_custom(_declaration: &PropertyDeclaration,
- _inherited_style: &ComputedValues,
- context: &mut computed::Context,
+ fn cascade_property_custom<C: TComputedValues>(
+ _declaration: &PropertyDeclaration,
+ _inherited_style: &C,
+ context: &mut computed::Context<C>,
_seen: &mut PropertyBitField,
_cacheable: &mut bool,
_error_reporter: &mut Box<ParseErrorReporter + Send>) {
@@ -2228,6 +2219,7 @@ pub mod longhands {
use std::fmt;
use values::computed::ComputedValueAsSpecified;
+ use properties::style_struct_traits::{TBox, TColor, TText};
impl ComputedValueAsSpecified for SpecifiedValue {}
@@ -2258,20 +2250,20 @@ pub mod longhands {
}
}
- fn maybe(flag: bool, context: &computed::Context) -> Option<RGBA> {
+ fn maybe<Cx: TContext>(flag: bool, context: &Cx) -> Option<RGBA> {
if flag {
- Some(context.style.color.color)
+ Some(context.style().get_color().clone_color())
} else {
None
}
}
- fn derive(context: &computed::Context) -> computed_value::T {
+ fn derive<Cx: TContext>(context: &Cx) -> computed_value::T {
// Start with no declarations if this is a block; otherwise, start with the
// declarations in effect and add in the text decorations that this inline specifies.
- let mut result = match context.style.box_.display {
+ let mut result = match context.style().get_box().clone_display() {
super::display::computed_value::T::inline => {
- context.inherited_style.inheritedtext._servo_text_decorations_in_effect
+ context.inherited_style().get_inheritedtext().clone__servo_text_decorations_in_effect()
}
_ => {
SpecifiedValue {
@@ -2283,26 +2275,28 @@ pub mod longhands {
};
if result.underline.is_none() {
- result.underline = maybe(context.style.text.text_decoration.underline, context)
+ result.underline = maybe(context.style().get_text().has_underline(), context)
}
if result.overline.is_none() {
- result.overline = maybe(context.style.text.text_decoration.overline, context)
+ result.overline = maybe(context.style().get_text().has_overline(), context)
}
if result.line_through.is_none() {
- result.line_through = maybe(context.style.text.text_decoration.line_through, context)
+ result.line_through = maybe(context.style().get_text().has_line_through(), context)
}
result
}
#[inline]
- pub fn derive_from_text_decoration(context: &mut computed::Context) {
- Arc::make_mut(&mut context.style.inheritedtext)._servo_text_decorations_in_effect = derive(context);
+ pub fn derive_from_text_decoration<Cx: TContext>(context: &mut Cx) {
+ let derived = derive(context);
+ context.mutate_style().mutate_inheritedtext().set__servo_text_decorations_in_effect(derived);
}
#[inline]
- pub fn derive_from_display(context: &mut computed::Context) {
- Arc::make_mut(&mut context.style.inheritedtext)._servo_text_decorations_in_effect = derive(context);
+ pub fn derive_from_display<Cx: TContext>(context: &mut Cx) {
+ let derived = derive(context);
+ context.mutate_style().mutate_inheritedtext().set__servo_text_decorations_in_effect(derived);
}
</%self:longhand>
@@ -2364,7 +2358,6 @@ pub mod longhands {
<%self:longhand name="border-spacing">
use app_units::Au;
use values::AuExtensionMethods;
- use values::computed::Context;
use cssparser::ToCss;
use std::fmt;
@@ -2413,7 +2406,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T {
horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context),
@@ -2528,7 +2521,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
#[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -2569,7 +2561,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Auto => computed_value::T(None),
SpecifiedValue::Specified(l) =>
@@ -2590,7 +2582,6 @@ pub mod longhands {
<%self:longhand name="column-count" experimental="True">
use cssparser::ToCss;
use std::fmt;
- use values::computed::Context;
#[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -2630,7 +2621,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Auto => computed_value::T(None),
SpecifiedValue::Specified(count) =>
@@ -2657,7 +2648,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
#[derive(Debug, Clone, Copy, PartialEq, HeapSizeOf)]
pub enum SpecifiedValue {
@@ -2698,7 +2688,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
match *self {
SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) =>
@@ -2723,7 +2713,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::CSSFloat;
- use values::computed::Context;
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
@@ -2746,7 +2735,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> computed_value::T {
if self.0 < 0.0 {
0.0
} else if self.0 > 1.0 {
@@ -2765,7 +2754,6 @@ pub mod longhands {
use cssparser::{self, ToCss};
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
#[derive(Debug, Clone, PartialEq, HeapSizeOf)]
pub struct SpecifiedValue(Vec<SpecifiedBoxShadow>);
@@ -2889,12 +2877,12 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T(self.0.iter().map(|value| compute_one_box_shadow(value, context)).collect())
}
}
- pub fn compute_one_box_shadow(value: &SpecifiedBoxShadow, context: &computed::Context)
+ pub fn compute_one_box_shadow<Cx: TContext>(value: &SpecifiedBoxShadow, context: &Cx)
-> computed_value::BoxShadow {
computed_value::BoxShadow {
offset_x: value.offset_x.to_computed_value(context),
@@ -2977,8 +2965,6 @@ pub mod longhands {
// NB: `top` and `left` are 0 if `auto` per CSS 2.1 11.1.2.
- use values::computed::Context;
-
pub mod computed_value {
use app_units::Au;
@@ -3082,7 +3068,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T(self.0.map(|value| computed_value::ClipRect {
top: value.top.to_computed_value(context),
right: value.right.map(|right| right.to_computed_value(context)),
@@ -3129,7 +3115,6 @@ pub mod longhands {
use cssparser::{self, ToCss};
use std::fmt;
use values::AuExtensionMethods;
- use values::computed::Context;
#[derive(Clone, PartialEq, Debug, HeapSizeOf)]
pub struct SpecifiedValue(Vec<SpecifiedTextShadow>);
@@ -3288,7 +3273,7 @@ pub mod longhands {
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
- fn to_computed_value(&self, context: &computed::Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T(self.0.iter().map(|value| {
computed_value::TextShadow {
offset_x: value.offset_x.to_computed_value(context),
@@ -3517,7 +3502,7 @@ pub mod longhands {
impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T;
- fn to_computed_value(&self, context: &computed::Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T{ filters: self.0.iter().map(|value| {
match *value {
SpecifiedFilter::Blur(factor) =>
@@ -3539,7 +3524,6 @@ pub mod longhands {
<%self:longhand name="transform">
use app_units::Au;
use values::CSSFloat;
- use values::computed::Context;
use cssparser::ToCss;
use std::fmt;
@@ -3956,7 +3940,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
if self.0.is_empty() {
return computed_value::T(None)
}
@@ -4082,7 +4066,6 @@ pub mod longhands {
<%self:longhand name="transform-origin">
use app_units::Au;
use values::AuExtensionMethods;
- use values::computed::Context;
use values::specified::{Length, LengthOrPercentage, Percentage};
use cssparser::ToCss;
@@ -4148,7 +4131,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T {
horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context),
@@ -4163,7 +4146,6 @@ pub mod longhands {
"computed::LengthOrNone::None")}
<%self:longhand name="perspective-origin">
- use values::computed::Context;
use values::specified::{LengthOrPercentage, Percentage};
use cssparser::ToCss;
@@ -4224,7 +4206,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
computed_value::T {
horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context),
@@ -4239,7 +4221,6 @@ pub mod longhands {
saturation color luminosity""")}
<%self:longhand name="image-rendering">
- use values::computed::Context;
pub mod computed_value {
use cssparser::ToCss;
@@ -4288,7 +4269,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> computed_value::T {
*self
}
}
@@ -4306,7 +4287,7 @@ pub mod longhands {
pub mod computed_value {
use cssparser::ToCss;
use std::fmt;
- use values::computed::{Context, ToComputedValue};
+ use values::computed::{TContext, ToComputedValue};
pub use values::computed::Time as SingleComputedValue;
@@ -4317,7 +4298,7 @@ pub mod longhands {
type ComputedValue = T;
#[inline]
- fn to_computed_value(&self, _: &Context) -> T {
+ fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> T {
(*self).clone()
}
}
@@ -4362,7 +4343,6 @@ pub mod longhands {
// TODO(pcwalton): Multiple transitions.
<%self:longhand name="transition-timing-function">
use self::computed_value::{StartEnd, TransitionTimingFunction};
- use values::computed::Context;
use euclid::point::Point2D;
@@ -4486,7 +4466,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> computed_value::T {
(*self).clone()
}
}
@@ -4559,7 +4539,6 @@ pub mod longhands {
// TODO(pcwalton): Lots more properties.
<%self:longhand name="transition-property">
use self::computed_value::TransitionProperty;
- use values::computed::Context;
pub use self::computed_value::SingleComputedValue as SingleSpecifiedValue;
pub use self::computed_value::T as SpecifiedValue;
@@ -4806,7 +4785,7 @@ pub mod longhands {
type ComputedValue = computed_value::T;
#[inline]
- fn to_computed_value(&self, _: &Context) -> computed_value::T {
+ fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> computed_value::T {
(*self).clone()
}
}
@@ -6083,8 +6062,58 @@ impl PropertyDeclaration {
}
}
+pub mod style_struct_traits {
+ use super::longhands;
+
+ % for style_struct in STYLE_STRUCTS:
+ pub trait T${style_struct.name}: Clone + PartialEq {
+ % for longhand in style_struct.longhands:
+ #[allow(non_snake_case)]
+ fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T);
+ #[allow(non_snake_case)]
+ fn copy_${longhand.ident}_from(&mut self, other: &Self);
+ % endfor
+ % if style_struct.name == "Animation":
+ fn transition_count(&self) -> usize;
+ % elif style_struct.name == "Border":
+ % for side in ["top", "right", "bottom", "left"]:
+ fn border_${side}_is_none_or_hidden_and_has_nonzero_width(&self) -> bool;
+ % endfor
+ % elif style_struct.name == "Box":
+ fn clone_display(&self) -> longhands::display::computed_value::T;
+ fn clone_position(&self) -> longhands::position::computed_value::T;
+ fn is_floated(&self) -> bool;
+ fn overflow_x_is_visible(&self) -> bool;
+ fn overflow_y_is_visible(&self) -> bool;
+ % elif style_struct.name == "Color":
+ fn clone_color(&self) -> longhands::color::computed_value::T;
+ % elif style_struct.name == "Font":
+ fn clone_font_size(&self) -> longhands::font_size::computed_value::T;
+ fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T;
+ fn compute_font_hash(&mut self);
+ % elif style_struct.name == "InheritedBox":
+ fn clone_direction(&self) -> longhands::direction::computed_value::T;
+ fn clone_writing_mode(&self) -> longhands::writing_mode::computed_value::T;
+ fn clone_text_orientation(&self) -> longhands::text_orientation::computed_value::T;
+ % elif style_struct.name == "InheritedText":
+ #[allow(non_snake_case)]
+ fn clone__servo_text_decorations_in_effect(&self) ->
+ longhands::_servo_text_decorations_in_effect::computed_value::T;
+ % elif style_struct.name == "Outline":
+ fn outline_is_none_or_hidden_and_has_nonzero_width(&self) -> bool;
+ % elif style_struct.name == "Text":
+ fn has_underline(&self) -> bool;
+ fn has_overline(&self) -> bool;
+ fn has_line_through(&self) -> bool;
+ % endif
+ }
+ % endfor
+}
+
pub mod style_structs {
+ use fnv::FnvHasher;
use super::longhands;
+ use std::hash::{Hash, Hasher};
% for style_struct in STYLE_STRUCTS:
% if style_struct.name == "Font":
@@ -6112,9 +6141,134 @@ pub mod style_structs {
}
% endif
+ impl super::style_struct_traits::T${style_struct.name} for ${style_struct.name} {
+ % for longhand in style_struct.longhands:
+ fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T) {
+ self.${longhand.ident} = v;
+ }
+ fn copy_${longhand.ident}_from(&mut self, other: &Self) {
+ self.${longhand.ident} = other.${longhand.ident}.clone();
+ }
+ % endfor
+ % if style_struct.name == "Animation":
+ fn transition_count(&self) -> usize {
+ self.transition_property.0.len()
+ }
+ % elif style_struct.name == "Border":
+ % for side in ["top", "right", "bottom", "left"]:
+ fn border_${side}_is_none_or_hidden_and_has_nonzero_width(&self) -> bool {
+ self.border_${side}_style.none_or_hidden() &&
+ self.border_${side}_width != ::app_units::Au(0)
+ }
+ % endfor
+ % elif style_struct.name == "Box":
+ fn clone_display(&self) -> longhands::display::computed_value::T {
+ self.display.clone()
+ }
+ fn clone_position(&self) -> longhands::position::computed_value::T {
+ self.position.clone()
+ }
+ fn is_floated(&self) -> bool {
+ self.float != longhands::float::SpecifiedValue::none
+ }
+ fn overflow_x_is_visible(&self) -> bool {
+ self.overflow_x == longhands::overflow_x::computed_value::T::visible
+ }
+ fn overflow_y_is_visible(&self) -> bool {
+ self.overflow_y.0 == longhands::overflow_x::computed_value::T::visible
+ }
+ % elif style_struct.name == "Color":
+ fn clone_color(&self) -> longhands::color::computed_value::T {
+ self.color.clone()
+ }
+ % elif style_struct.name == "Font":
+ fn clone_font_size(&self) -> longhands::font_size::computed_value::T {
+ self.font_size.clone()
+ }
+ fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T {
+ self.font_weight.clone()
+ }
+ fn compute_font_hash(&mut self) {
+ // Corresponds to the fields in `gfx::font_template::FontTemplateDescriptor`.
+ let mut hasher: FnvHasher = Default::default();
+ hasher.write_u16(self.font_weight as u16);
+ self.font_stretch.hash(&mut hasher);
+ self.font_family.hash(&mut hasher);
+ self.hash = hasher.finish()
+ }
+ % elif style_struct.name == "InheritedBox":
+ fn clone_direction(&self) -> longhands::direction::computed_value::T {
+ self.direction.clone()
+ }
+ fn clone_writing_mode(&self) -> longhands::writing_mode::computed_value::T {
+ self.writing_mode.clone()
+ }
+ fn clone_text_orientation(&self) -> longhands::text_orientation::computed_value::T {
+ self.text_orientation.clone()
+ }
+ % elif style_struct.name == "InheritedText":
+ fn clone__servo_text_decorations_in_effect(&self) ->
+ longhands::_servo_text_decorations_in_effect::computed_value::T {
+ self._servo_text_decorations_in_effect.clone()
+ }
+ % elif style_struct.name == "Outline":
+ fn outline_is_none_or_hidden_and_has_nonzero_width(&self) -> bool {
+ self.outline_style.none_or_hidden() && self.outline_width != ::app_units::Au(0)
+ }
+ % elif style_struct.name == "Text":
+ fn has_underline(&self) -> bool {
+ self.text_decoration.underline
+ }
+ fn has_overline(&self) -> bool {
+ self.text_decoration.overline
+ }
+ fn has_line_through(&self) -> bool {
+ self.text_decoration.line_through
+ }
+ % endif
+ }
+
% endfor
}
+pub trait TComputedValues : Clone + Send + Sync + 'static {
+ % for style_struct in STYLE_STRUCTS:
+ type Concrete${style_struct.name}: style_struct_traits::T${style_struct.name};
+ % endfor
+
+ // Temporary bailout case for stuff we haven't made work with the trait
+ // yet - panics for non-Servo implementations.
+ //
+ // Used only for animations. Don't use it in other places.
+ fn as_servo<'a>(&'a self) -> &'a ComputedValues;
+ fn as_servo_mut<'a>(&'a mut self) -> &'a mut ComputedValues;
+
+ fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
+ shareable: bool,
+ writing_mode: WritingMode,
+ root_font_size: Au,
+ % for style_struct in STYLE_STRUCTS:
+ ${style_struct.ident}: Arc<Self::Concrete${style_struct.name}>,
+ % endfor
+ ) -> Self;
+
+ fn initial_values() -> &'static Self;
+
+ fn do_cascade_property<F: FnOnce(&Vec<Option<CascadePropertyFn<Self>>>)>(f: F);
+
+ % for style_struct in STYLE_STRUCTS:
+ fn clone_${style_struct.name.lower()}(&self) -> Arc<Self::Concrete${style_struct.name}>;
+ fn get_${style_struct.name.lower()}<'a>(&'a self) -> &'a Self::Concrete${style_struct.name};
+ fn mutate_${style_struct.name.lower()}<'a>(&'a mut self) -> &'a mut Self::Concrete${style_struct.name};
+ % endfor
+
+ fn custom_properties(&self) -> Option<Arc<::custom_properties::ComputedValuesMap>>;
+ fn root_font_size(&self) -> Au;
+ fn set_root_font_size(&mut self, size: Au);
+ fn set_writing_mode(&mut self, mode: WritingMode);
+ fn is_multicol(&self) -> bool;
+}
+
#[derive(Clone, HeapSizeOf)]
pub struct ComputedValues {
% for style_struct in STYLE_STRUCTS:
@@ -6126,6 +6280,71 @@ pub struct ComputedValues {
pub root_font_size: Au,
}
+impl TComputedValues for ComputedValues {
+ % for style_struct in STYLE_STRUCTS:
+ type Concrete${style_struct.name} = style_structs::${style_struct.name};
+ % endfor
+
+ fn as_servo<'a>(&'a self) -> &'a ComputedValues { self }
+ fn as_servo_mut<'a>(&'a mut self) -> &'a mut ComputedValues { self }
+
+ fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
+ shareable: bool,
+ writing_mode: WritingMode,
+ root_font_size: Au,
+ % for style_struct in STYLE_STRUCTS:
+ ${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
+ % endfor
+ ) -> Self {
+ ComputedValues {
+ custom_properties: custom_properties,
+ shareable: shareable,
+ writing_mode: writing_mode,
+ root_font_size: root_font_size,
+ % for style_struct in STYLE_STRUCTS:
+ ${style_struct.ident}: ${style_struct.ident},
+ % endfor
+ }
+ }
+
+ fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
+
+ fn do_cascade_property<F: FnOnce(&Vec<Option<CascadePropertyFn<Self>>>)>(f: F) {
+ CASCADE_PROPERTY.with(|x| f(x));
+ }
+
+ % for style_struct in STYLE_STRUCTS:
+ #[inline]
+ fn clone_${style_struct.name.lower()}(&self) -> Arc<Self::Concrete${style_struct.name}> {
+ self.${style_struct.ident}.clone()
+ }
+ #[inline]
+ fn get_${style_struct.name.lower()}<'a>(&'a self) -> &'a Self::Concrete${style_struct.name} {
+ &self.${style_struct.ident}
+ }
+ #[inline]
+ fn mutate_${style_struct.name.lower()}<'a>(&'a mut self) -> &'a mut Self::Concrete${style_struct.name} {
+ Arc::make_mut(&mut self.${style_struct.ident})
+ }
+ % endfor
+
+ // Cloning the Arc here is fine because it only happens in the case where we have custom
+ // properties, and those are both rare and expensive.
+ fn custom_properties(&self) -> Option<Arc<::custom_properties::ComputedValuesMap>> {
+ self.custom_properties.as_ref().map(|x| x.clone())
+ }
+
+ fn root_font_size(&self) -> Au { self.root_font_size }
+ fn set_root_font_size(&mut self, size: Au) { self.root_font_size = size }
+ fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; }
+
+ #[inline]
+ fn is_multicol(&self) -> bool {
+ let style = self.get_column();
+ style.column_count.0.is_some() || style.column_width.0.is_some()
+ }
+}
+
impl ComputedValues {
/// Resolves the currentColor keyword.
/// Any color value form computed values (except for the 'color' property itself)
@@ -6227,12 +6446,6 @@ impl ComputedValues {
}
#[inline]
- pub fn is_multicol(&self) -> bool {
- let style = self.get_column();
- style.column_count.0.is_some() || style.column_width.0.is_some()
- }
-
- #[inline]
pub fn get_font_arc(&self) -> Arc<style_structs::Font> {
self.font.clone()
}
@@ -6297,19 +6510,6 @@ impl ComputedValues {
false
}
- % for style_struct in STYLE_STRUCTS:
- #[inline]
- pub fn get_${style_struct.name.lower()}
- <'a>(&'a self) -> &'a style_structs::${style_struct.name} {
- &*self.${style_struct.ident}
- }
- #[inline]
- pub fn mutate_${style_struct.name.lower()}
- <'a>(&'a mut self) -> &'a mut style_structs::${style_struct.name} {
- &mut *Arc::make_mut(&mut self.${style_struct.ident})
- }
- % endfor
-
pub fn computed_value_to_string(&self, name: &str) -> Result<String, ()> {
match name {
% for style_struct in STYLE_STRUCTS:
@@ -6329,16 +6529,16 @@ impl ComputedValues {
/// Return a WritingMode bitflags from the relevant CSS properties.
-pub fn get_writing_mode(inheritedbox_style: &style_structs::InheritedBox) -> WritingMode {
+pub fn get_writing_mode<S: style_struct_traits::TInheritedBox>(inheritedbox_style: &S) -> WritingMode {
use logical_geometry;
let mut flags = WritingMode::empty();
- match inheritedbox_style.direction {
+ match inheritedbox_style.clone_direction() {
computed_values::direction::T::ltr => {},
computed_values::direction::T::rtl => {
flags.insert(logical_geometry::FLAG_RTL);
},
}
- match inheritedbox_style.writing_mode {
+ match inheritedbox_style.clone_writing_mode() {
computed_values::writing_mode::T::horizontal_tb => {},
computed_values::writing_mode::T::vertical_rl => {
flags.insert(logical_geometry::FLAG_VERTICAL);
@@ -6348,7 +6548,7 @@ pub fn get_writing_mode(inheritedbox_style: &style_structs::InheritedBox) -> Wri
flags.insert(logical_geometry::FLAG_VERTICAL_LR);
},
}
- match inheritedbox_style.text_orientation {
+ match inheritedbox_style.clone_text_orientation() {
computed_values::text_orientation::T::sideways_right => {},
computed_values::text_orientation::T::sideways_left => {
flags.insert(logical_geometry::FLAG_VERTICAL_LR);
@@ -6365,7 +6565,7 @@ pub fn get_writing_mode(inheritedbox_style: &style_structs::InheritedBox) -> Wri
/// The initial values for all style structs as defined by the specification.
lazy_static! {
- pub static ref INITIAL_VALUES: ComputedValues = ComputedValues {
+ pub static ref INITIAL_SERVO_VALUES: ComputedValues = ComputedValues {
% for style_struct in STYLE_STRUCTS:
${style_struct.ident}: Arc::new(style_structs::${style_struct.name} {
% for longhand in style_struct.longhands:
@@ -6385,35 +6585,34 @@ lazy_static! {
/// Fast path for the function below. Only computes new inherited styles.
-#[allow(unused_mut)]
-fn cascade_with_cached_declarations(
+#[allow(unused_mut, unused_imports)]
+fn cascade_with_cached_declarations<C: TComputedValues>(
viewport_size: Size2D<Au>,
applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>],
shareable: bool,
- parent_style: &ComputedValues,
- cached_style: &ComputedValues,
+ parent_style: &C,
+ cached_style: &C,
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
mut error_reporter: Box<ParseErrorReporter + Send>)
- -> ComputedValues {
+ -> C {
let mut context = computed::Context {
is_root_element: false,
viewport_size: viewport_size,
inherited_style: parent_style,
- style: ComputedValues {
+ style: C::new(
+ custom_properties,
+ shareable,
+ WritingMode::empty(),
+ parent_style.root_font_size(),
% for style_struct in STYLE_STRUCTS:
- ${style_struct.ident}:
- % if style_struct.inherited:
- parent_style
- % else:
- cached_style
- % endif
- .${style_struct.ident}.clone(),
+ % if style_struct.inherited:
+ parent_style
+ % else:
+ cached_style
+ % endif
+ .clone_${style_struct.name.lower()}(),
% endfor
- custom_properties: custom_properties,
- shareable: shareable,
- writing_mode: WritingMode::empty(),
- root_font_size: parent_style.root_font_size,
- },
+ ),
};
let mut seen = PropertyBitField::new();
// Declaration blocks are stored in increasing precedence order,
@@ -6428,35 +6627,37 @@ fn cascade_with_cached_declarations(
PropertyDeclaration::${property.camel_case}(ref
${'_' if not style_struct.inherited else ''}declared_value)
=> {
+ use properties::style_struct_traits::T${style_struct.name};
% if style_struct.inherited:
if seen.get_${property.ident}() {
continue
}
seen.set_${property.ident}();
- let custom_props = context.style.custom_properties.clone();
+ let custom_props = context.style().custom_properties();
substitute_variables_${property.ident}(
declared_value, &custom_props,
|value| match *value {
DeclaredValue::Value(ref specified_value)
=> {
- Arc::make_mut(&mut context.style.${style_struct.ident})
- .${property.ident} = specified_value.to_computed_value(&context);
+ let computed = specified_value.to_computed_value(&context);
+ context.mutate_style().mutate_${style_struct.name.lower()}()
+ .set_${property.ident}(computed);
},
DeclaredValue::Initial
=> {
- Arc::make_mut(&mut context.style.${style_struct.ident})
- .${property.ident} =
- longhands::${property.ident}::get_initial_value();
+ // FIXME(bholley): We may want set_X_to_initial_value() here.
+ let initial = longhands::${property.ident}::get_initial_value();
+ context.mutate_style().mutate_${style_struct.name.lower()}()
+ .set_${property.ident}(initial);
},
DeclaredValue::Inherit => {
// This is a bit slow, but this is rare so it shouldn't
// matter.
//
// FIXME: is it still?
- Arc::make_mut(&mut context.style.${style_struct.ident})
- .${property.ident} = parent_style.${style_struct.ident}
- .${property.ident}
- .clone();
+ let inherited_struct = parent_style.get_${style_struct.ident}();
+ context.mutate_style().mutate_${style_struct.name.lower()}()
+ .copy_${property.ident}_from(inherited_struct);
}
DeclaredValue::WithVariables { .. } => unreachable!()
}, &mut error_reporter
@@ -6484,23 +6685,25 @@ fn cascade_with_cached_declarations(
if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() ||
seen.get_font_family() {
- compute_font_hash(&mut *Arc::make_mut(&mut context.style.font))
+ use properties::style_struct_traits::TFont;
+ context.mutate_style().mutate_font().compute_font_hash();
}
context.style
}
-type CascadePropertyFn = extern "Rust" fn(declaration: &PropertyDeclaration,
- inherited_style: &ComputedValues,
- context: &mut computed::Context,
- seen: &mut PropertyBitField,
- cacheable: &mut bool,
- error_reporter: &mut Box<ParseErrorReporter + Send>);
+pub type CascadePropertyFn<C: TComputedValues> =
+ extern "Rust" fn(declaration: &PropertyDeclaration,
+ inherited_style: &C,
+ context: &mut computed::Context<C>,
+ seen: &mut PropertyBitField,
+ cacheable: &mut bool,
+ error_reporter: &mut Box<ParseErrorReporter + Send>);
// This is a thread-local rather than a lazy static to avoid atomic operations when cascading
// properties.
-thread_local!(static CASCADE_PROPERTY: Vec<Option<CascadePropertyFn>> = {
- let mut result: Vec<Option<CascadePropertyFn>> = Vec::new();
+thread_local!(static CASCADE_PROPERTY: Vec<Option<CascadePropertyFn<ComputedValues>>> = {
+ let mut result: Vec<Option<CascadePropertyFn<ComputedValues>>> = Vec::new();
% for style_struct in STYLE_STRUCTS:
% for property in style_struct.longhands:
let discriminant;
@@ -6536,19 +6739,22 @@ thread_local!(static CASCADE_PROPERTY: Vec<Option<CascadePropertyFn>> = {
/// this is ignored.
///
/// Returns the computed values and a boolean indicating whether the result is cacheable.
-pub fn cascade(viewport_size: Size2D<Au>,
+pub fn cascade<C: TComputedValues>(
+ viewport_size: Size2D<Au>,
applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>],
shareable: bool,
- parent_style: Option< &ComputedValues >,
- cached_style: Option< &ComputedValues >,
+ parent_style: Option< &C >,
+ cached_style: Option< &C >,
mut error_reporter: Box<ParseErrorReporter + Send>)
- -> (ComputedValues, bool) {
- let initial_values = &*INITIAL_VALUES;
+ -> (C, bool) {
+ use properties::style_struct_traits::{TBorder, TBox, TColor, TFont, TOutline};
+ let initial_values = C::initial_values();
let (is_root_element, inherited_style) = match parent_style {
Some(parent_style) => (false, parent_style),
None => (true, initial_values),
};
+ let inherited_custom_properties = inherited_style.custom_properties();
let mut custom_properties = None;
let mut seen_custom = HashSet::new();
for sub_list in applicable_declarations.iter().rev() {
@@ -6557,7 +6763,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
match *declaration {
PropertyDeclaration::Custom(ref name, ref value) => {
::custom_properties::cascade(
- &mut custom_properties, &inherited_style.custom_properties,
+ &mut custom_properties, &inherited_custom_properties,
&mut seen_custom, name, value)
}
_ => {}
@@ -6565,7 +6771,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
}
}
let custom_properties = ::custom_properties::finish_cascade(
- custom_properties, &inherited_style.custom_properties);
+ custom_properties, &inherited_custom_properties);
if let (Some(cached_style), Some(parent_style)) = (cached_style, parent_style) {
let style = cascade_with_cached_declarations(viewport_size,
@@ -6582,21 +6788,20 @@ pub fn cascade(viewport_size: Size2D<Au>,
is_root_element: is_root_element,
viewport_size: viewport_size,
inherited_style: inherited_style,
- style: ComputedValues {
+ style: C::new(
+ custom_properties,
+ shareable,
+ WritingMode::empty(),
+ inherited_style.root_font_size(),
% for style_struct in STYLE_STRUCTS:
- ${style_struct.ident}:
- % if style_struct.inherited:
- inherited_style
- % else:
- initial_values
- % endif
- .${style_struct.ident}.clone(),
+ % if style_struct.inherited:
+ inherited_style
+ % else:
+ initial_values
+ % endif
+ .clone_${style_struct.name.lower()}(),
% endfor
- custom_properties: custom_properties,
- shareable: shareable,
- writing_mode: WritingMode::empty(),
- root_font_size: inherited_style.root_font_size,
- },
+ ),
};
// Set computed values, overwriting earlier declarations for the same property.
@@ -6608,7 +6813,7 @@ pub fn cascade(viewport_size: Size2D<Au>,
// We could (and used to) use a pattern match here, but that bloats this function to over 100K
// of compiled code! To improve i-cache behavior, we outline the individual functions and use
// virtual dispatch instead.
- CASCADE_PROPERTY.with(|cascade_property| {
+ C::do_cascade_property(|cascade_property| {
% for category_to_cascade_now in ["early", "other"]:
for sub_list in applicable_declarations.iter().rev() {
// Declarations are already stored in reverse order.
@@ -6654,14 +6859,14 @@ pub fn cascade(viewport_size: Size2D<Au>,
let mut style = context.style;
- let positioned = matches!(style.box_.position,
+ let positioned = matches!(style.get_box().clone_position(),
longhands::position::SpecifiedValue::absolute |
longhands::position::SpecifiedValue::fixed);
- let floated = style.box_.float != longhands::float::SpecifiedValue::none;
+ let floated = style.get_box().is_floated();
if positioned || floated || is_root_element {
use computed_values::display::T;
- let specified_display = style.box_.display;
+ let specified_display = style.get_box().clone_display();
let computed_display = match specified_display {
T::inline_table => {
Some(T::table)
@@ -6676,26 +6881,26 @@ pub fn cascade(viewport_size: Size2D<Au>,
_ => None
};
if let Some(computed_display) = computed_display {
- let box_ = Arc::make_mut(&mut style.box_);
- box_.display = computed_display;
- box_._servo_display_for_hypothetical_box = if is_root_element {
+ let box_ = style.mutate_box();
+ box_.set_display(computed_display);
+ box_.set__servo_display_for_hypothetical_box(if is_root_element {
computed_display
} else {
specified_display
- };
+ });
}
}
{
use computed_values::overflow_x::T as overflow;
use computed_values::overflow_y;
- match (style.box_.overflow_x, style.box_.overflow_y.0) {
- (overflow::visible, overflow::visible) => {}
- (overflow::visible, _) => {
- Arc::make_mut(&mut style.box_).overflow_x = overflow::auto
+ match (style.get_box().overflow_x_is_visible(), style.get_box().overflow_y_is_visible()) {
+ (true, true) => {}
+ (true, _) => {
+ style.mutate_box().set_overflow_x(overflow::auto);
}
- (_, overflow::visible) => {
- Arc::make_mut(&mut style.box_).overflow_y = overflow_y::T(overflow::auto)
+ (_, true) => {
+ style.mutate_box().set_overflow_y(overflow_y::T(overflow::auto));
}
_ => {}
}
@@ -6704,27 +6909,29 @@ pub fn cascade(viewport_size: Size2D<Au>,
// The initial value of border-*-width may be changed at computed value time.
% for side in ["top", "right", "bottom", "left"]:
// Like calling to_computed_value, which wouldn't type check.
- if style.border.border_${side}_style.none_or_hidden() &&
- style.border.border_${side}_width != Au(0) {
- Arc::make_mut(&mut style.border).border_${side}_width = Au(0);
+ if style.get_border().border_${side}_is_none_or_hidden_and_has_nonzero_width() {
+ style.mutate_border().set_border_${side}_width(Au(0));
}
% endfor
// The initial value of outline width may be changed at computed value time.
- if style.outline.outline_style.none_or_hidden() && style.outline.outline_width != Au(0) {
- Arc::make_mut(&mut style.outline).outline_width = Au(0);
+ if style.get_outline().outline_is_none_or_hidden_and_has_nonzero_width() {
+ style.mutate_outline().set_outline_width(Au(0));
}
if is_root_element {
- style.root_font_size = style.font.font_size;
+ let s = style.get_font().clone_font_size();
+ style.set_root_font_size(s);
}
if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() ||
seen.get_font_family() {
- compute_font_hash(&mut *Arc::make_mut(&mut style.font))
+ use properties::style_struct_traits::TFont;
+ style.mutate_font().compute_font_hash();
}
- style.writing_mode = get_writing_mode(&*style.inheritedbox);
+ let mode = get_writing_mode(style.get_inheritedbox());
+ style.set_writing_mode(mode);
(style, cacheable)
}
@@ -6929,12 +7136,3 @@ macro_rules! longhand_properties_idents {
}
}
}
-
-/// Corresponds to the fields in `gfx::font_template::FontTemplateDescriptor`.
-fn compute_font_hash(font: &mut style_structs::Font) {
- let mut hasher: FnvHasher = Default::default();
- hasher.write_u16(font.font_weight as u16);
- font.font_stretch.hash(&mut hasher);
- font.font_family.hash(&mut hasher);
- font.hash = hasher.finish()
-}
diff --git a/components/style/values.rs b/components/style/values.rs
index b35a2ca0766..69cd83309fc 100644
--- a/components/style/values.rs
+++ b/components/style/values.rs
@@ -100,6 +100,7 @@ pub mod specified {
use std::ops::Mul;
use style_traits::values::specified::AllowedNumericType;
use super::AuExtensionMethods;
+ use super::computed::{TContext, ToComputedValue};
use super::{CSSFloat, FONT_MEDIUM_PX};
use url::Url;
@@ -1418,11 +1419,11 @@ pub mod specified {
}
}
- impl super::computed::ToComputedValue for Time {
+ impl ToComputedValue for Time {
type ComputedValue = Time;
#[inline]
- fn to_computed_value(&self, _: &super::computed::Context) -> Time {
+ fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> Time {
*self
}
}
@@ -1437,7 +1438,8 @@ pub mod specified {
pub mod computed {
use app_units::Au;
use euclid::size::Size2D;
- use properties::ComputedValues;
+ use properties::TComputedValues;
+ use properties::style_struct_traits::TFont;
use std::fmt;
use super::AuExtensionMethods;
use super::specified::AngleOrCorner;
@@ -1446,21 +1448,39 @@ pub mod computed {
pub use cssparser::Color as CSSColor;
pub use super::specified::{Angle, BorderStyle, Time};
- pub struct Context<'a> {
+ pub trait TContext {
+ type ConcreteComputedValues: TComputedValues;
+ fn is_root_element(&self) -> bool;
+ fn viewport_size(&self) -> Size2D<Au>;
+ fn inherited_style(&self) -> &Self::ConcreteComputedValues;
+ fn style(&self) -> &Self::ConcreteComputedValues;
+ fn mutate_style(&mut self) -> &mut Self::ConcreteComputedValues;
+ }
+
+ pub struct Context<'a, C: TComputedValues> {
pub is_root_element: bool,
pub viewport_size: Size2D<Au>,
- pub inherited_style: &'a ComputedValues,
+ pub inherited_style: &'a C,
/// 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 style: C,
+ }
+
+ impl<'a, C: TComputedValues> TContext for Context<'a, C> {
+ type ConcreteComputedValues = C;
+ fn is_root_element(&self) -> bool { self.is_root_element }
+ fn viewport_size(&self) -> Size2D<Au> { self.viewport_size }
+ fn inherited_style(&self) -> &C { &self.inherited_style }
+ fn style(&self) -> &C { &self.style }
+ fn mutate_style(&mut self) -> &mut C { &mut self.style }
}
pub trait ToComputedValue {
type ComputedValue;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue;
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> Self::ComputedValue;
}
pub trait ComputedValueAsSpecified {}
@@ -1469,7 +1489,7 @@ pub mod computed {
type ComputedValue = T;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> T {
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> T {
self.clone()
}
}
@@ -1478,7 +1498,7 @@ pub mod computed {
type ComputedValue = CSSColor;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> CSSColor {
+ fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> CSSColor {
self.parsed
}
}
@@ -1489,17 +1509,17 @@ pub mod computed {
type ComputedValue = Au;
#[inline]
- fn to_computed_value(&self, context: &Context) -> Au {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> Au {
match *self {
specified::Length::Absolute(length) => length,
specified::Length::Calc(calc) => calc.to_computed_value(context).length(),
specified::Length::FontRelative(length) =>
- length.to_computed_value(context.style.get_font().font_size,
- context.style.root_font_size),
+ length.to_computed_value(context.style().get_font().clone_font_size(),
+ context.style().root_font_size()),
specified::Length::ViewportPercentage(length) =>
- length.to_computed_value(context.viewport_size),
+ length.to_computed_value(context.viewport_size()),
specified::Length::ServoCharacterWidth(length) =>
- length.to_computed_value(context.style.get_font().font_size)
+ length.to_computed_value(context.style().get_font().clone_font_size())
}
}
}
@@ -1583,7 +1603,7 @@ pub mod computed {
impl ToComputedValue for specified::CalcLengthOrPercentage {
type ComputedValue = CalcLengthOrPercentage;
- fn to_computed_value(&self, context: &Context) -> CalcLengthOrPercentage {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> CalcLengthOrPercentage {
let mut length = None;
if let Some(absolute) = self.absolute {
@@ -1593,13 +1613,13 @@ pub mod computed {
for val in &[self.vw, self.vh, self.vmin, self.vmax] {
if let Some(val) = *val {
length = Some(length.unwrap_or(Au(0)) +
- val.to_computed_value(context.viewport_size));
+ val.to_computed_value(context.viewport_size()));
}
}
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.style.get_font().font_size, context.style.root_font_size));
+ context.style().get_font().clone_font_size(), context.style().root_font_size()));
}
}
@@ -1621,7 +1641,7 @@ pub mod computed {
type ComputedValue = BorderRadiusSize;
#[inline]
- fn to_computed_value(&self, context: &Context) -> BorderRadiusSize {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> BorderRadiusSize {
let specified::BorderRadiusSize(s) = *self;
let w = s.width.to_computed_value(context);
let h = s.height.to_computed_value(context);
@@ -1664,7 +1684,7 @@ pub mod computed {
impl ToComputedValue for specified::LengthOrPercentage {
type ComputedValue = LengthOrPercentage;
- fn to_computed_value(&self, context: &Context) -> LengthOrPercentage {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentage {
match *self {
specified::LengthOrPercentage::Length(value) => {
LengthOrPercentage::Length(value.to_computed_value(context))
@@ -1712,7 +1732,7 @@ pub mod computed {
type ComputedValue = LengthOrPercentageOrAuto;
#[inline]
- fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAuto {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentageOrAuto {
match *self {
specified::LengthOrPercentageOrAuto::Length(value) => {
LengthOrPercentageOrAuto::Length(value.to_computed_value(context))
@@ -1764,7 +1784,7 @@ pub mod computed {
type ComputedValue = LengthOrPercentageOrNone;
#[inline]
- fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrNone {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentageOrNone {
match *self {
specified::LengthOrPercentageOrNone::Length(value) => {
LengthOrPercentageOrNone::Length(value.to_computed_value(context))
@@ -1812,7 +1832,7 @@ pub mod computed {
type ComputedValue = LengthOrNone;
#[inline]
- fn to_computed_value(&self, context: &Context) -> LengthOrNone {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrNone {
match *self {
specified::LengthOrNone::Length(specified::Length::Calc(calc)) => {
LengthOrNone::Length(calc.to_computed_value(context).length())
@@ -1840,7 +1860,7 @@ pub mod computed {
type ComputedValue = Image;
#[inline]
- fn to_computed_value(&self, context: &Context) -> Image {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> Image {
match *self {
specified::Image::Url(ref url) => Image::Url(url.clone()),
specified::Image::LinearGradient(ref linear_gradient) => {
@@ -1936,7 +1956,7 @@ pub mod computed {
type ComputedValue = LinearGradient;
#[inline]
- fn to_computed_value(&self, context: &Context) -> LinearGradient {
+ fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LinearGradient {
let specified::LinearGradient {
angle_or_corner,
ref stops
diff --git a/components/style/viewport.rs b/components/style/viewport.rs
index 53c6d5bcbc2..f2da78088e4 100644
--- a/components/style/viewport.rs
+++ b/components/style/viewport.rs
@@ -8,7 +8,7 @@ use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser,
use euclid::scale_factor::ScaleFactor;
use euclid::size::{Size2D, TypedSize2D};
use parser::{ParserContext, log_css_error};
-use properties::INITIAL_VALUES;
+use properties::{ComputedValues, TComputedValues};
use std::ascii::AsciiExt;
use std::collections::hash_map::{Entry, HashMap};
use std::fmt;
@@ -594,8 +594,8 @@ impl MaybeNew for ViewportConstraints {
let context = Context {
is_root_element: false,
viewport_size: initial_viewport,
- inherited_style: &*INITIAL_VALUES,
- style: INITIAL_VALUES.clone(),
+ inherited_style: ComputedValues::initial_values(),
+ style: ComputedValues::initial_values().clone(),
};
// DEVICE-ADAPT § 9.3 Resolving 'extend-to-zoom'