aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/gfx/display_list/mod.rs2
-rw-r--r--components/layout/block.rs2
-rw-r--r--components/layout/construct.rs2
-rw-r--r--components/layout/context.rs7
-rw-r--r--components/layout/display_list_builder.rs2
-rw-r--r--components/layout/flex.rs2
-rw-r--r--components/layout/flow.rs2
-rw-r--r--components/layout/fragment.rs2
-rw-r--r--components/layout/generated_content.rs2
-rw-r--r--components/layout/incremental.rs3
-rw-r--r--components/layout/inline.rs2
-rw-r--r--components/layout/layout_thread.rs1
-rw-r--r--components/layout/list_item.rs2
-rw-r--r--components/layout/model.rs2
-rw-r--r--components/layout/multicol.rs2
-rw-r--r--components/layout/query.rs1
-rw-r--r--components/layout/table.rs2
-rw-r--r--components/layout/table_caption.rs2
-rw-r--r--components/layout/table_cell.rs2
-rw-r--r--components/layout/table_colgroup.rs2
-rw-r--r--components/layout/table_row.rs2
-rw-r--r--components/layout/table_rowgroup.rs2
-rw-r--r--components/layout/table_wrapper.rs2
-rw-r--r--components/layout/text.rs2
-rw-r--r--components/layout/wrapper.rs3
-rw-r--r--components/style/animation.rs34
-rw-r--r--components/style/context.rs11
-rw-r--r--components/style/data.rs14
-rw-r--r--components/style/dom.rs19
-rw-r--r--components/style/lib.rs2
-rw-r--r--components/style/matching.rs83
-rw-r--r--components/style/properties.mako.rs719
-rw-r--r--components/style/servo.rs3
-rw-r--r--components/style/traversal.rs4
-rw-r--r--components/style/values.rs68
-rw-r--r--components/style/viewport.rs6
-rw-r--r--ports/geckolib/Cargo.toml2
-rw-r--r--ports/geckolib/bindings.rs11
-rw-r--r--ports/geckolib/build.rs80
-rw-r--r--ports/geckolib/glue.rs94
-rw-r--r--ports/geckolib/lib.rs7
-rw-r--r--ports/geckolib/properties.mako.rs168
-rw-r--r--ports/geckolib/selector_impl.rs7
-rw-r--r--ports/geckolib/traversal.rs22
-rw-r--r--ports/geckolib/wrapper.rs9
-rw-r--r--python/tidy.py4
-rw-r--r--tests/unit/style/lib.rs4
47 files changed, 994 insertions, 432 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/layout/block.rs b/components/layout/block.rs
index 19bb6e71ce2..06f41861425 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -60,7 +60,7 @@ use style::computed_values::{border_collapse, box_sizing, display, float, overfl
use style::computed_values::{position, text_align, transform_style};
use style::context::StyleContext;
use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::{LengthOrNone, LengthOrPercentageOrNone};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
use util::geometry::MAX_RECT;
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index 25988b7eb11..aedbeaf04f6 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -45,7 +45,7 @@ use std::sync::atomic::Ordering;
use style::computed_values::content::ContentItem;
use style::computed_values::{caption_side, display, empty_cells, float, list_style_position};
use style::computed_values::{position};
-use style::properties::{self, ComputedValues};
+use style::properties::{self, ComputedValues, TComputedValues};
use table::TableFlow;
use table_caption::TableCaptionFlow;
use table_cell::TableCellFlow;
diff --git a/components/layout/context.rs b/components/layout/context.rs
index 2775e6e791c..7b6fa3e4691 100644
--- a/components/layout/context.rs
+++ b/components/layout/context.rs
@@ -26,13 +26,14 @@ use std::rc::Rc;
use std::sync::{Arc, Mutex, RwLock};
use style::context::{LocalStyleContext, StyleContext};
use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
+use style::properties::ComputedValues;
use style::selector_impl::ServoSelectorImpl;
use style::servo::SharedStyleContext;
use url::Url;
use util::opts;
struct LocalLayoutContext {
- style_context: LocalStyleContext,
+ style_context: LocalStyleContext<ComputedValues>,
font_context: RefCell<FontContext>,
}
@@ -107,12 +108,12 @@ pub struct LayoutContext<'a> {
cached_local_layout_context: Rc<LocalLayoutContext>,
}
-impl<'a> StyleContext<'a, ServoSelectorImpl> for LayoutContext<'a> {
+impl<'a> StyleContext<'a, ServoSelectorImpl, ComputedValues> for LayoutContext<'a> {
fn shared_context(&self) -> &'a SharedStyleContext {
&self.shared.style_context
}
- fn local_context(&self) -> &LocalStyleContext {
+ fn local_context(&self) -> &LocalStyleContext<ComputedValues> {
&self.cached_local_layout_context.style_context
}
}
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 4d62d221a5e..d20186cf0f9 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -51,7 +51,7 @@ use style::computed_values::{border_style, image_rendering, overflow_x, position
use style::computed_values::{transform, transform_style, visibility};
use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
use style::properties::style_structs::Border;
-use style::properties::{self, ComputedValues};
+use style::properties::{self, ComputedValues, TComputedValues};
use style::values::RGBA;
use style::values::computed;
use style::values::computed::{LengthOrNone, LengthOrPercentage, LengthOrPercentageOrAuto, LinearGradient};
diff --git a/components/layout/flex.rs b/components/layout/flex.rs
index b53bb697c49..dbc01b58178 100644
--- a/components/layout/flex.rs
+++ b/components/layout/flex.rs
@@ -28,8 +28,8 @@ use std::cmp::max;
use std::sync::Arc;
use style::computed_values::{flex_direction, float};
use style::logical_geometry::LogicalSize;
-use style::properties::ComputedValues;
use style::properties::style_structs;
+use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::LengthOrPercentageOrAuto;
// A mode describes which logical axis a flex axis is parallel with.
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index b61540dfb3b..dc434ce03f2 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -50,7 +50,7 @@ use std::{fmt, mem, raw};
use style::computed_values::{clear, display, empty_cells, float, position, overflow_x, text_align};
use style::dom::TRestyleDamage;
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
-use style::properties::{self, ComputedValues};
+use style::properties::{self, ComputedValues, TComputedValues};
use style::values::computed::LengthOrPercentageOrAuto;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, TableFlow};
use table_caption::TableCaptionFlow;
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 8c1c54fd282..227b492b038 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -41,7 +41,7 @@ use style::computed_values::{overflow_x, position, text_decoration, transform_st
use style::computed_values::{white_space, word_break, z_index};
use style::dom::TRestyleDamage;
use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode};
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
use style::values::computed::{LengthOrPercentageOrNone};
use text;
diff --git a/components/layout/generated_content.rs b/components/layout/generated_content.rs
index b0284c62d7e..7af9c4349d2 100644
--- a/components/layout/generated_content.rs
+++ b/components/layout/generated_content.rs
@@ -20,7 +20,7 @@ use std::sync::Arc;
use style::computed_values::content::ContentItem;
use style::computed_values::{display, list_style_type};
use style::dom::TRestyleDamage;
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use text::TextRunScanner;
use wrapper::PseudoElementType;
diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs
index d909192c0d3..8daf3cdd14f 100644
--- a/components/layout/incremental.rs
+++ b/components/layout/incremental.rs
@@ -7,7 +7,7 @@ use std::fmt;
use std::sync::Arc;
use style::computed_values::float;
use style::dom::TRestyleDamage;
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
bitflags! {
#[doc = "Individual layout actions that may be necessary after restyling."]
@@ -53,6 +53,7 @@ bitflags! {
}
impl TRestyleDamage for RestyleDamage {
+ type ConcreteComputedValues = ComputedValues;
fn compute(old: Option<&Arc<ComputedValues>>, new: &ComputedValues) -> RestyleDamage { compute_damage(old, new) }
/// Returns a bitmask that represents a flow that needs to be rebuilt and reflowed.
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index 8784728d808..175295c6f09 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -30,7 +30,7 @@ use std::{fmt, isize, mem};
use style::computed_values::{display, overflow_x, position, text_align, text_justify};
use style::computed_values::{text_overflow, vertical_align, white_space};
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::LengthOrPercentage;
use text;
use unicode_bidi;
diff --git a/components/layout/layout_thread.rs b/components/layout/layout_thread.rs
index cbad465b4f8..646defb49e4 100644
--- a/components/layout/layout_thread.rs
+++ b/components/layout/layout_thread.rs
@@ -72,6 +72,7 @@ use style::error_reporting::ParseErrorReporter;
use style::logical_geometry::LogicalPoint;
use style::media_queries::{Device, MediaType};
use style::parallel::WorkQueueData;
+use style::properties::TComputedValues;
use style::selector_impl::ServoSelectorImpl;
use style::selector_matching::USER_OR_USER_AGENT_STYLESHEETS;
use style::servo::{SharedStyleContext, Stylesheet, Stylist};
diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs
index 6c8817ec1da..e64faa96758 100644
--- a/components/layout/list_item.rs
+++ b/components/layout/list_item.rs
@@ -23,7 +23,7 @@ use inline::InlineMetrics;
use std::sync::Arc;
use style::computed_values::{list_style_type, position};
use style::logical_geometry::LogicalSize;
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use text;
/// A block with the CSS `display` property equal to `list-item`.
diff --git a/components/layout/model.rs b/components/layout/model.rs
index 057bb46fa52..6312bf3d30b 100644
--- a/components/layout/model.rs
+++ b/components/layout/model.rs
@@ -13,7 +13,7 @@ use std::cmp::{max, min};
use std::fmt;
use style::computed_values::transform::ComputedMatrix;
use style::logical_geometry::LogicalMargin;
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::{BorderRadiusSize, LengthOrPercentageOrAuto};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrNone};
diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs
index 4b7ac7d8814..b7e89fecf6c 100644
--- a/components/layout/multicol.rs
+++ b/components/layout/multicol.rs
@@ -21,7 +21,7 @@ use std::fmt;
use std::sync::Arc;
use style::context::StyleContext;
use style::logical_geometry::LogicalSize;
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use util::print_tree::PrintTree;
diff --git a/components/layout/query.rs b/components/layout/query.rs
index 9d1b9ed1db3..e05564f1aca 100644
--- a/components/layout/query.rs
+++ b/components/layout/query.rs
@@ -27,6 +27,7 @@ use std::sync::{Arc, Mutex};
use string_cache::Atom;
use style::computed_values;
use style::logical_geometry::{WritingMode, BlockFlowDirection, InlineBaseDirection};
+use style::properties::TComputedValues;
use style::properties::longhands::{display, position};
use style::properties::style_structs;
use style::selector_impl::PseudoElement;
diff --git a/components/layout/table.rs b/components/layout/table.rs
index 0c8d8865a8d..bd6b6bee6ed 100644
--- a/components/layout/table.rs
+++ b/components/layout/table.rs
@@ -25,7 +25,7 @@ use std::fmt;
use std::sync::Arc;
use style::computed_values::{border_collapse, border_spacing, table_layout};
use style::logical_geometry::LogicalSize;
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use style::values::CSSFloat;
use style::values::computed::LengthOrPercentageOrAuto;
use table_row::{TableRowFlow};
diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs
index e1706fc53cd..20ca8d8a8dc 100644
--- a/components/layout/table_caption.rs
+++ b/components/layout/table_caption.rs
@@ -17,7 +17,7 @@ use gfx::display_list::{StackingContext, StackingContextId};
use std::fmt;
use std::sync::Arc;
use style::logical_geometry::LogicalSize;
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use util::print_tree::PrintTree;
/// A table formatting context.
diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs
index ea16a5b5a59..508d201f6fd 100644
--- a/components/layout/table_cell.rs
+++ b/components/layout/table_cell.rs
@@ -21,7 +21,7 @@ use std::fmt;
use std::sync::Arc;
use style::computed_values::{border_collapse, border_top_style};
use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode};
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use table::InternalTable;
use table_row::{CollapsedBorder, CollapsedBorderProvenance};
use util::print_tree::PrintTree;
diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs
index 32d2c693131..762e3526cf6 100644
--- a/components/layout/table_colgroup.rs
+++ b/components/layout/table_colgroup.rs
@@ -18,7 +18,7 @@ use std::cmp::max;
use std::fmt;
use std::sync::Arc;
use style::logical_geometry::LogicalSize;
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::LengthOrPercentageOrAuto;
/// A table formatting context.
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index 45e8bca12ec..64a2e71beed 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -25,7 +25,7 @@ use std::iter::{Enumerate, IntoIterator, Peekable};
use std::sync::Arc;
use style::computed_values::{border_collapse, border_spacing, border_top_style};
use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode};
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::LengthOrPercentageOrAuto;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt};
use table_cell::{CollapsedBordersForCell, TableCellFlow};
diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs
index 44da4878119..a43d6f6ebbc 100644
--- a/components/layout/table_rowgroup.rs
+++ b/components/layout/table_rowgroup.rs
@@ -21,7 +21,7 @@ use std::iter::{IntoIterator, Iterator, Peekable};
use std::sync::Arc;
use style::computed_values::{border_collapse, border_spacing};
use style::logical_geometry::{LogicalSize, WritingMode};
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, TableLikeFlow};
use table_row;
use util::print_tree::PrintTree;
diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs
index a8e16812efd..e543f981127 100644
--- a/components/layout/table_wrapper.rs
+++ b/components/layout/table_wrapper.rs
@@ -31,7 +31,7 @@ use std::ops::Add;
use std::sync::Arc;
use style::computed_values::{border_collapse, table_layout};
use style::logical_geometry::LogicalSize;
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use style::values::CSSFloat;
use style::values::computed::LengthOrPercentageOrAuto;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize};
diff --git a/components/layout/text.rs b/components/layout/text.rs
index 2a9e99d18d3..0969bc4e43e 100644
--- a/components/layout/text.rs
+++ b/components/layout/text.rs
@@ -23,8 +23,8 @@ use std::sync::Arc;
use style::computed_values::{line_height, text_orientation, text_rendering, text_transform};
use style::computed_values::{white_space};
use style::logical_geometry::{LogicalSize, WritingMode};
-use style::properties::ComputedValues;
use style::properties::style_structs::Font as FontStyle;
+use style::properties::{ComputedValues, TComputedValues};
use unicode_bidi::{is_rtl, process_text};
use unicode_script::{get_script, Script};
use util::linked_list::split_off_head;
diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs
index 30ca65f6e39..094bc40a4a0 100644
--- a/components/layout/wrapper.rs
+++ b/components/layout/wrapper.rs
@@ -66,7 +66,7 @@ use style::computed_values::content::ContentItem;
use style::computed_values::{content, display};
use style::dom::{TDocument, TElement, TNode, UnsafeNode};
use style::element_state::*;
-use style::properties::ComputedValues;
+use style::properties::{ComputedValues, TComputedValues};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
use style::restyle_hints::ElementSnapshot;
use style::selector_impl::{NonTSPseudoClass, PseudoElement, ServoSelectorImpl};
@@ -131,6 +131,7 @@ impl<'ln> ServoLayoutNode<'ln> {
}
impl<'ln> TNode for ServoLayoutNode<'ln> {
+ type ConcreteComputedValues = ComputedValues;
type ConcreteElement = ServoLayoutElement<'ln>;
type ConcreteDocument = ServoLayoutDocument<'ln>;
type ConcreteRestyleDamage = RestyleDamage;
diff --git a/components/style/animation.rs b/components/style/animation.rs
index b152be5fcc3..e7663093cd5 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,8 @@ 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::style_struct_traits::TAnimation;
+use properties::{ComputedValues, TComputedValues};
use std::cmp::Ordering;
use std::iter::repeat;
use std::sync::mpsc::Sender;
@@ -73,7 +74,7 @@ impl PropertyAnimation {
-> Vec<PropertyAnimation> {
let mut result = Vec::new();
let transition_property =
- new_style.get_animation().transition_property.0[transition_index];
+ new_style.as_servo().get_animation().transition_property.0[transition_index];
if transition_property != TransitionProperty::All {
if let Some(property_animation) =
PropertyAnimation::from_transition_property(transition_property,
@@ -929,22 +930,22 @@ impl<T> GetMod for Vec<T> {
/// Inserts transitions into the queue of running animations as applicable for the given style
/// difference. This is called from the layout worker threads. Returns true if any animations were
/// kicked off and false otherwise.
-pub fn start_transitions_if_applicable(new_animations_sender: &Mutex<Sender<Animation>>,
- node: OpaqueNode,
- old_style: &ComputedValues,
- new_style: &mut ComputedValues)
- -> bool {
+pub fn start_transitions_if_applicable<C: TComputedValues>(new_animations_sender: &Mutex<Sender<Animation>>,
+ node: OpaqueNode,
+ old_style: &C,
+ new_style: &mut C)
+ -> bool {
let mut had_animations = false;
- for i in 0..new_style.get_animation().transition_property.0.len() {
+ for i in 0..new_style.get_animation().transition_count() {
// Create any property animations, if applicable.
- let property_animations = PropertyAnimation::from_transition(i, old_style, new_style);
+ let property_animations = PropertyAnimation::from_transition(i, old_style.as_servo(), new_style.as_servo_mut());
for property_animation in property_animations {
// Set the property to the initial value.
- property_animation.update(new_style, 0.0);
+ property_animation.update(new_style.as_servo_mut(), 0.0);
// Kick off the animation.
let now = time::precise_time_s();
- let animation_style = new_style.get_animation();
+ let animation_style = new_style.as_servo().get_animation();
let start_time =
now + (animation_style.transition_delay.0.get_mod(i).seconds() as f64);
new_animations_sender.lock().unwrap().send(Animation {
@@ -964,9 +965,10 @@ pub fn start_transitions_if_applicable(new_animations_sender: &Mutex<Sender<Anim
/// Updates a single animation and associated style based on the current time. If `damage` is
/// provided, inserts the appropriate restyle damage.
-pub fn update_style_for_animation<ConcreteRestyleDamage: TRestyleDamage>(animation: &Animation,
- style: &mut Arc<ComputedValues>,
- damage: Option<&mut ConcreteRestyleDamage>) {
+pub fn update_style_for_animation<C: TComputedValues,
+ Damage: TRestyleDamage<ConcreteComputedValues=C>>(animation: &Animation,
+ style: &mut Arc<C>,
+ damage: Option<&mut Damage>) {
let now = time::precise_time_s();
let mut progress = (now - animation.start_time) / animation.duration();
if progress > 1.0 {
@@ -977,9 +979,9 @@ pub fn update_style_for_animation<ConcreteRestyleDamage: TRestyleDamage>(animati
}
let mut new_style = (*style).clone();
- animation.property_animation.update(&mut *Arc::make_mut(&mut new_style), progress);
+ animation.property_animation.update(Arc::make_mut(&mut new_style).as_servo_mut(), progress);
if let Some(damage) = damage {
- *damage = *damage | ConcreteRestyleDamage::compute(Some(style), &new_style);
+ *damage = *damage | Damage::compute(Some(style), &new_style);
}
*style = new_style
diff --git a/components/style/context.rs b/components/style/context.rs
index 6e4edfd1b52..ef19bc2561e 100644
--- a/components/style/context.rs
+++ b/components/style/context.rs
@@ -8,6 +8,7 @@ use dom::OpaqueNode;
use error_reporting::ParseErrorReporter;
use euclid::Size2D;
use matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
+use properties::TComputedValues;
use selector_impl::SelectorImplExt;
use selector_matching::Stylist;
use std::cell::RefCell;
@@ -54,15 +55,15 @@ pub struct SharedStyleContext<Impl: SelectorImplExt> {
pub error_reporter: Box<ParseErrorReporter + Sync>,
}
-pub struct LocalStyleContext {
- pub applicable_declarations_cache: RefCell<ApplicableDeclarationsCache>,
- pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache>,
+pub struct LocalStyleContext<C: TComputedValues> {
+ pub applicable_declarations_cache: RefCell<ApplicableDeclarationsCache<C>>,
+ pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache<C>>,
}
-pub trait StyleContext<'a, Impl: SelectorImplExt> {
+pub trait StyleContext<'a, Impl: SelectorImplExt, C: TComputedValues> {
fn shared_context(&self) -> &'a SharedStyleContext<Impl>;
- fn local_context(&self) -> &LocalStyleContext;
+ fn local_context(&self) -> &LocalStyleContext<C>;
}
/// Why we're doing reflow.
diff --git a/components/style/data.rs b/components/style/data.rs
index ffe12908cba..6bc6916a564 100644
--- a/components/style/data.rs
+++ b/components/style/data.rs
@@ -2,26 +2,28 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use properties::ComputedValues;
+use properties::TComputedValues;
use selectors::parser::SelectorImpl;
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use std::sync::Arc;
use std::sync::atomic::AtomicIsize;
-pub struct PrivateStyleData<Impl: SelectorImpl> {
+pub struct PrivateStyleData<Impl: SelectorImpl, ConcreteComputedValues: TComputedValues> {
/// The results of CSS styling for this node.
- pub style: Option<Arc<ComputedValues>>,
+ pub style: Option<Arc<ConcreteComputedValues>>,
/// The results of CSS styling for each pseudo-element (if any).
- pub per_pseudo: HashMap<Impl::PseudoElement, Arc<ComputedValues>, BuildHasherDefault<::fnv::FnvHasher>>,
+ pub per_pseudo: HashMap<Impl::PseudoElement, Arc<ConcreteComputedValues>,
+ BuildHasherDefault<::fnv::FnvHasher>>,
/// Information needed during parallel traversals.
pub parallel: DomParallelInfo,
}
-impl<Impl: SelectorImpl> PrivateStyleData<Impl> {
- pub fn new() -> PrivateStyleData<Impl> {
+impl<Impl, ConcreteComputedValues> PrivateStyleData<Impl, ConcreteComputedValues>
+ where Impl: SelectorImpl, ConcreteComputedValues: TComputedValues {
+ pub fn new() -> PrivateStyleData<Impl, ConcreteComputedValues> {
PrivateStyleData {
style: None,
per_pseudo: HashMap::with_hasher(Default::default()),
diff --git a/components/style/dom.rs b/components/style/dom.rs
index 37859736dbe..861cec599a2 100644
--- a/components/style/dom.rs
+++ b/components/style/dom.rs
@@ -6,7 +6,7 @@
use data::PrivateStyleData;
use element_state::ElementState;
-use properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock};
+use properties::{PropertyDeclaration, PropertyDeclarationBlock, TComputedValues};
use restyle_hints::{ElementSnapshot, RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint};
use selector_impl::ElementExt;
use selectors::Element;
@@ -43,14 +43,16 @@ impl OpaqueNode {
}
pub trait TRestyleDamage : BitOr<Output=Self> + Copy {
- fn compute(old: Option<&Arc<ComputedValues>>, new: &ComputedValues) -> Self;
+ type ConcreteComputedValues: TComputedValues;
+ fn compute(old: Option<&Arc<Self::ConcreteComputedValues>>, new: &Self::ConcreteComputedValues) -> Self;
fn rebuild_and_reflow() -> Self;
}
pub trait TNode : Sized + Copy + Clone {
type ConcreteElement: TElement<ConcreteNode = Self, ConcreteDocument = Self::ConcreteDocument>;
type ConcreteDocument: TDocument<ConcreteNode = Self, ConcreteElement = Self::ConcreteElement>;
- type ConcreteRestyleDamage: TRestyleDamage;
+ type ConcreteRestyleDamage: TRestyleDamage<ConcreteComputedValues = Self::ConcreteComputedValues>;
+ type ConcreteComputedValues: TComputedValues;
fn to_unsafe(&self) -> UnsafeNode;
unsafe fn from_unsafe(n: &UnsafeNode) -> Self;
@@ -135,17 +137,20 @@ pub trait TNode : Sized + Copy + Clone {
/// Borrows the PrivateStyleData without checks.
#[inline(always)]
unsafe fn borrow_data_unchecked(&self)
- -> Option<*const PrivateStyleData<<Self::ConcreteElement as Element>::Impl>>;
+ -> Option<*const PrivateStyleData<<Self::ConcreteElement as Element>::Impl,
+ Self::ConcreteComputedValues>>;
/// Borrows the PrivateStyleData immutably. Fails on a conflicting borrow.
#[inline(always)]
fn borrow_data(&self)
- -> Option<Ref<PrivateStyleData<<Self::ConcreteElement as Element>::Impl>>>;
+ -> Option<Ref<PrivateStyleData<<Self::ConcreteElement as Element>::Impl,
+ Self::ConcreteComputedValues>>>;
/// Borrows the PrivateStyleData mutably. Fails on a conflicting borrow.
#[inline(always)]
fn mutate_data(&self)
- -> Option<RefMut<PrivateStyleData<<Self::ConcreteElement as Element>::Impl>>>;
+ -> Option<RefMut<PrivateStyleData<<Self::ConcreteElement as Element>::Impl,
+ Self::ConcreteComputedValues>>>;
/// Get the description of how to account for recent style changes.
fn restyle_damage(self) -> Self::ConcreteRestyleDamage;
@@ -166,7 +171,7 @@ pub trait TNode : Sized + Copy + Clone {
/// Returns the style results for the given node. If CSS selector matching
/// has not yet been performed, fails.
- fn style(&self) -> Ref<Arc<ComputedValues>> {
+ fn style(&self) -> Ref<Arc<Self::ConcreteComputedValues>> {
Ref::map(self.borrow_data().unwrap(), |data| data.style.as_ref().unwrap())
}
diff --git a/components/style/lib.rs b/components/style/lib.rs
index a696b882d43..951a32cd3ce 100644
--- a/components/style/lib.rs
+++ b/components/style/lib.rs
@@ -50,7 +50,7 @@ pub mod animation;
pub mod attr;
pub mod bezier;
pub mod context;
-mod custom_properties;
+pub mod custom_properties;
pub mod data;
pub mod dom;
pub mod element_state;
diff --git a/components/style/matching.rs b/components/style/matching.rs
index 1c158505e97..025e229e57c 100644
--- a/components/style/matching.rs
+++ b/components/style/matching.rs
@@ -8,8 +8,8 @@ use animation::{self, Animation};
use context::SharedStyleContext;
use data::PrivateStyleData;
use dom::{TElement, TNode, TRestyleDamage};
-use properties::{ComputedValues, PropertyDeclaration, cascade};
-use selector_impl::SelectorImplExt;
+use properties::{PropertyDeclaration, TComputedValues, cascade};
+use selector_impl::{ElementExt, SelectorImplExt};
use selector_matching::{DeclarationBlock, Stylist};
use selectors::Element;
use selectors::bloom::BloomFilter;
@@ -151,25 +151,25 @@ impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> {
static APPLICABLE_DECLARATIONS_CACHE_SIZE: usize = 32;
-pub struct ApplicableDeclarationsCache {
- cache: SimpleHashCache<ApplicableDeclarationsCacheEntry, Arc<ComputedValues>>,
+pub struct ApplicableDeclarationsCache<C: TComputedValues> {
+ cache: SimpleHashCache<ApplicableDeclarationsCacheEntry, Arc<C>>,
}
-impl ApplicableDeclarationsCache {
- pub fn new() -> ApplicableDeclarationsCache {
+impl<C: TComputedValues> ApplicableDeclarationsCache<C> {
+ pub fn new() -> Self {
ApplicableDeclarationsCache {
cache: SimpleHashCache::new(APPLICABLE_DECLARATIONS_CACHE_SIZE),
}
}
- pub fn find(&self, declarations: &[DeclarationBlock]) -> Option<Arc<ComputedValues>> {
+ pub fn find(&self, declarations: &[DeclarationBlock]) -> Option<Arc<C>> {
match self.cache.find(&ApplicableDeclarationsCacheQuery::new(declarations)) {
None => None,
Some(ref values) => Some((*values).clone()),
}
}
- pub fn insert(&mut self, declarations: Vec<DeclarationBlock>, style: Arc<ComputedValues>) {
+ pub fn insert(&mut self, declarations: Vec<DeclarationBlock>, style: Arc<C>) {
self.cache.insert(ApplicableDeclarationsCacheEntry::new(declarations), style)
}
@@ -179,14 +179,14 @@ impl ApplicableDeclarationsCache {
}
/// An LRU cache of the last few nodes seen, so that we can aggressively try to reuse their styles.
-pub struct StyleSharingCandidateCache {
- cache: LRUCache<StyleSharingCandidate, ()>,
+pub struct StyleSharingCandidateCache<C: TComputedValues> {
+ cache: LRUCache<StyleSharingCandidate<C>, ()>,
}
#[derive(Clone)]
-pub struct StyleSharingCandidate {
- pub style: Arc<ComputedValues>,
- pub parent_style: Arc<ComputedValues>,
+pub struct StyleSharingCandidate<C: TComputedValues> {
+ pub style: Arc<C>,
+ pub parent_style: Arc<C>,
pub local_name: Atom,
// FIXME(pcwalton): Should be a list of atoms instead.
pub class: Option<String>,
@@ -195,8 +195,8 @@ pub struct StyleSharingCandidate {
pub link: bool,
}
-impl PartialEq for StyleSharingCandidate {
- fn eq(&self, other: &StyleSharingCandidate) -> bool {
+impl<C: TComputedValues> PartialEq for StyleSharingCandidate<C> {
+ fn eq(&self, other: &Self) -> bool {
arc_ptr_eq(&self.style, &other.style) &&
arc_ptr_eq(&self.parent_style, &other.parent_style) &&
self.local_name == other.local_name &&
@@ -207,12 +207,12 @@ impl PartialEq for StyleSharingCandidate {
}
}
-impl StyleSharingCandidate {
+impl<C: TComputedValues> StyleSharingCandidate<C> {
/// Attempts to create a style sharing candidate from this node. Returns
/// the style sharing candidate or `None` if this node is ineligible for
/// style sharing.
#[allow(unsafe_code)]
- fn new<E: TElement>(element: &E) -> Option<StyleSharingCandidate> {
+ fn new<N: TNode<ConcreteComputedValues=C>>(element: &N::ConcreteElement) -> Option<Self> {
let parent_element = match element.parent_element() {
None => return None,
Some(parent_element) => parent_element,
@@ -254,7 +254,7 @@ impl StyleSharingCandidate {
link: element.is_link(),
namespace: (*element.get_namespace()).clone(),
common_style_affecting_attributes:
- create_common_style_affecting_attributes_from_element::<E>(&element)
+ create_common_style_affecting_attributes_from_element::<N::ConcreteElement>(&element)
})
}
@@ -332,19 +332,19 @@ impl StyleSharingCandidate {
static STYLE_SHARING_CANDIDATE_CACHE_SIZE: usize = 40;
-impl StyleSharingCandidateCache {
- pub fn new() -> StyleSharingCandidateCache {
+impl<C: TComputedValues> StyleSharingCandidateCache<C> {
+ pub fn new() -> Self {
StyleSharingCandidateCache {
cache: LRUCache::new(STYLE_SHARING_CANDIDATE_CACHE_SIZE),
}
}
- pub fn iter(&self) -> Iter<(StyleSharingCandidate, ())> {
+ pub fn iter(&self) -> Iter<(StyleSharingCandidate<C>, ())> {
self.cache.iter()
}
- pub fn insert_if_possible<E: TElement>(&mut self, element: &E) {
- match StyleSharingCandidate::new(element) {
+ pub fn insert_if_possible<N: TNode<ConcreteComputedValues=C>>(&mut self, element: &N::ConcreteElement) {
+ match StyleSharingCandidate::new::<N>(element) {
None => {}
Some(candidate) => self.cache.insert(candidate, ())
}
@@ -368,15 +368,15 @@ trait PrivateMatchMethods: TNode
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt {
fn cascade_node_pseudo_element(&self,
context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
- parent_style: Option<&Arc<ComputedValues>>,
+ parent_style: Option<&Arc<Self::ConcreteComputedValues>>,
applicable_declarations: &[DeclarationBlock],
- mut style: Option<&mut Arc<ComputedValues>>,
+ mut style: Option<&mut Arc<Self::ConcreteComputedValues>>,
applicable_declarations_cache:
- &mut ApplicableDeclarationsCache,
+ &mut ApplicableDeclarationsCache<Self::ConcreteComputedValues>,
new_animations_sender: &Mutex<Sender<Animation>>,
shareable: bool,
animate_properties: bool)
- -> (Self::ConcreteRestyleDamage, Arc<ComputedValues>) {
+ -> (Self::ConcreteRestyleDamage, Arc<Self::ConcreteComputedValues>) {
let mut cacheable = true;
if animate_properties {
cacheable = !self.update_animations_for_cascade(context, &mut style) && cacheable;
@@ -416,10 +416,11 @@ trait PrivateMatchMethods: TNode
if animate_properties {
if let Some(ref style) = style {
let animations_started =
- animation::start_transitions_if_applicable(new_animations_sender,
- self.opaque(),
- &**style,
- &mut this_style);
+ animation::start_transitions_if_applicable::<Self::ConcreteComputedValues>(
+ new_animations_sender,
+ self.opaque(),
+ &**style,
+ &mut this_style);
cacheable = cacheable && !animations_started
}
}
@@ -440,7 +441,7 @@ trait PrivateMatchMethods: TNode
fn update_animations_for_cascade(&self,
context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
- style: &mut Option<&mut Arc<ComputedValues>>)
+ style: &mut Option<&mut Arc<Self::ConcreteComputedValues>>)
-> bool {
let style = match *style {
None => return false,
@@ -456,7 +457,7 @@ trait PrivateMatchMethods: TNode
had_animations_to_expire = animations_to_expire.is_some();
if let Some(ref animations) = animations_to_expire {
for animation in *animations {
- animation.property_animation.update(&mut *Arc::make_mut(style), 1.0);
+ animation.property_animation.update(Arc::make_mut(style).as_servo_mut(), 1.0);
}
}
}
@@ -474,7 +475,8 @@ trait PrivateMatchMethods: TNode
if had_running_animations {
let mut all_running_animations = context.running_animations.write().unwrap();
for running_animation in all_running_animations.get(&this_opaque).unwrap() {
- animation::update_style_for_animation::<Self::ConcreteRestyleDamage>(running_animation, style, None);
+ animation::update_style_for_animation::<Self::ConcreteComputedValues,
+ Self::ConcreteRestyleDamage>(running_animation, style, None);
}
all_running_animations.remove(&this_opaque);
}
@@ -489,14 +491,15 @@ impl<N: TNode> PrivateMatchMethods for N
trait PrivateElementMatchMethods: TElement {
fn share_style_with_candidate_if_possible(&self,
parent_node: Option<Self::ConcreteNode>,
- candidate: &StyleSharingCandidate)
- -> Option<Arc<ComputedValues>> {
+ candidate: &StyleSharingCandidate<<Self::ConcreteNode as
+ TNode>::ConcreteComputedValues>)
+ -> Option<Arc<<Self::ConcreteNode as TNode>::ConcreteComputedValues>> {
let parent_node = match parent_node {
Some(ref parent_node) if parent_node.as_element().is_some() => parent_node,
Some(_) | None => return None,
};
- let parent_data: Option<&PrivateStyleData<_>> = unsafe {
+ let parent_data: Option<&PrivateStyleData<_, _>> = unsafe {
parent_node.borrow_data_unchecked().map(|d| &*d)
};
@@ -550,7 +553,8 @@ pub trait ElementMatchMethods : TElement
/// guarantee that at the type system level yet.
unsafe fn share_style_if_possible(&self,
style_sharing_candidate_cache:
- &mut StyleSharingCandidateCache,
+ &mut StyleSharingCandidateCache<<Self::ConcreteNode as
+ TNode>::ConcreteComputedValues>,
parent: Option<Self::ConcreteNode>)
-> StyleSharingResult<<Self::ConcreteNode as TNode>::ConcreteRestyleDamage> {
if opts::get().disable_share_style_cache {
@@ -639,7 +643,8 @@ pub trait MatchMethods : TNode {
context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
parent: Option<Self>,
applicable_declarations: &ApplicableDeclarations<<Self::ConcreteElement as Element>::Impl>,
- applicable_declarations_cache: &mut ApplicableDeclarationsCache,
+ applicable_declarations_cache:
+ &mut ApplicableDeclarationsCache<Self::ConcreteComputedValues>,
new_animations_sender: &Mutex<Sender<Animation>>)
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt {
// Get our parent's style. This must be unsafe so that we don't touch the parent's
diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs
index a7cd97743cc..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,17 +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>) {
@@ -167,31 +167,39 @@ pub mod longhands {
return
}
seen.set_${property.ident}();
- let computed_value = ::properties::substitute_variables_${property.ident}(
- declared_value, &context.style.custom_properties, |value| match *value {
- DeclaredValue::Value(ref specified_value) => {
- specified_value.to_computed_value(&context)
- }
- DeclaredValue::WithVariables { .. } => unreachable!(),
- DeclaredValue::Initial => 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;
- inherited_style.${THIS_STYLE_STRUCT.ident}
- .${property.ident}
- .clone()
- }
- }, error_reporter
- );
- Arc::make_mut(&mut context.style.${THIS_STYLE_STRUCT.ident}).${property.ident} =
- computed_value;
+ {
+ 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:
- cascade_property_custom(&computed_value,
- declaration,
+ cascade_property_custom(declaration,
inherited_style,
context,
seen,
@@ -334,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 {
@@ -361,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)
}
}
@@ -399,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 {
@@ -421,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)
}
}
@@ -453,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)]
@@ -498,31 +505,27 @@ pub mod longhands {
impl ComputedValueAsSpecified for SpecifiedValue {}
- fn cascade_property_custom(_computed_value: &computed_value::T,
+ fn cascade_property_custom<C: TComputedValues>(
_declaration: &PropertyDeclaration,
- _inherited_style: &ComputedValues,
- context: &mut computed::Context,
+ _inherited_style: &C,
+ context: &mut computed::Context<C>,
_seen: &mut PropertyBitField,
_cacheable: &mut bool,
_error_reporter: &mut Box<ParseErrorReporter + Send>) {
- Arc::make_mut(&mut context.style.box_)._servo_display_for_hypothetical_box =
- longhands::_servo_display_for_hypothetical_box::derive_from_display(&context);
- Arc::make_mut(&mut context.style.inheritedtext)._servo_text_decorations_in_effect =
- longhands::_servo_text_decorations_in_effect::derive_from_display(&context);
+ longhands::_servo_display_for_hypothetical_box::derive_from_display(context);
+ longhands::_servo_text_decorations_in_effect::derive_from_display(context);
}
</%self:longhand>
${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 {
@@ -546,9 +549,9 @@ pub mod longhands {
}
#[inline]
- pub fn derive_from_display(context: &computed::Context)
- -> computed_value::T {
- 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>
@@ -636,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 {
@@ -699,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),
@@ -729,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()) %>
@@ -797,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)} => {
@@ -823,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;
@@ -845,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))
}
}
@@ -1052,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)]
@@ -1093,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())),
@@ -1272,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;
@@ -1320,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)) =>
@@ -1334,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;
@@ -1419,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),
@@ -1456,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;
@@ -1529,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 {
@@ -1593,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
}
}
@@ -1747,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 {
@@ -1831,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,
@@ -1847,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,
@@ -1868,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 {
@@ -1891,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())
}
}
}
@@ -1992,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 {
@@ -2033,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) =>
@@ -2055,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 {
@@ -2096,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) =>
@@ -2136,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 {}
@@ -2207,16 +2200,14 @@ pub mod longhands {
if !empty { Ok(result) } else { Err(()) }
}
- fn cascade_property_custom(_computed_value: &computed_value::T,
+ fn cascade_property_custom<C: TComputedValues>(
_declaration: &PropertyDeclaration,
- _inherited_style: &ComputedValues,
- context: &mut computed::Context,
+ _inherited_style: &C,
+ context: &mut computed::Context<C>,
_seen: &mut PropertyBitField,
_cacheable: &mut bool,
_error_reporter: &mut Box<ParseErrorReporter + Send>) {
- Arc::make_mut(&mut context.style.inheritedtext)._servo_text_decorations_in_effect =
- longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(
- &context);
+ longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(context);
}
</%self:longhand>
@@ -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,27 +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: &computed::Context)
- -> computed_value::T {
- 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: &computed::Context)
- -> computed_value::T {
- 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>
@@ -2365,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;
@@ -2414,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),
@@ -2529,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 {
@@ -2570,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) =>
@@ -2591,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 {
@@ -2631,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) =>
@@ -2658,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 {
@@ -2699,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) =>
@@ -2724,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 {
@@ -2747,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 {
@@ -2766,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>);
@@ -2890,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),
@@ -2978,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;
@@ -3083,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)),
@@ -3130,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>);
@@ -3289,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),
@@ -3518,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) =>
@@ -3540,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;
@@ -3957,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)
}
@@ -4083,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;
@@ -4149,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),
@@ -4164,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;
@@ -4225,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),
@@ -4240,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;
@@ -4289,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
}
}
@@ -4307,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;
@@ -4318,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()
}
}
@@ -4363,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;
@@ -4487,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()
}
}
@@ -4560,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;
@@ -4807,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()
}
}
@@ -5587,13 +5565,12 @@ mod property_bit_field {
% for property in LONGHANDS:
% if property.derived_from is None:
#[allow(non_snake_case)]
- fn substitute_variables_${property.ident}<F, R>(
+ fn substitute_variables_${property.ident}<F>(
value: &DeclaredValue<longhands::${property.ident}::SpecifiedValue>,
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F,
error_reporter: &mut Box<ParseErrorReporter + Send>)
- -> R
- where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>) -> R
+ where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>)
{
if let DeclaredValue::WithVariables {
ref css, first_token_type, ref base_url, from_shorthand
@@ -5604,15 +5581,15 @@ mod property_bit_field {
from_shorthand,
custom_properties,
f,
- error_reporter)
+ error_reporter);
} else {
- f(value)
+ f(value);
}
}
#[allow(non_snake_case)]
#[inline(never)]
- fn substitute_variables_${property.ident}_slow<F, R>(
+ fn substitute_variables_${property.ident}_slow<F>(
css: &String,
first_token_type: TokenSerializationType,
base_url: &Url,
@@ -5620,9 +5597,7 @@ mod property_bit_field {
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F,
error_reporter: &mut Box<ParseErrorReporter + Send>)
- -> R
- where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>)
- -> R {
+ where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>) {
f(&
::custom_properties::substitute(css, first_token_type, custom_properties)
.and_then(|css| {
@@ -5656,7 +5631,7 @@ mod property_bit_field {
// Invalid at computed-value time.
DeclaredValue::${"Inherit" if property.style_struct.inherited else "Initial"}
)
- )
+ );
}
% endif
% endfor
@@ -6087,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":
@@ -6116,7 +6141,132 @@ 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)]
@@ -6130,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)
@@ -6231,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()
}
@@ -6301,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:
@@ -6333,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);
@@ -6352,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);
@@ -6369,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:
@@ -6389,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,
@@ -6432,42 +6627,47 @@ 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 computed_value =
+ let custom_props = context.style().custom_properties();
substitute_variables_${property.ident}(
- declared_value, &context.style.custom_properties,
+ declared_value, &custom_props,
|value| match *value {
DeclaredValue::Value(ref specified_value)
- => 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
- => 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?
- 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
);
- Arc::make_mut(&mut context.style.${style_struct.ident})
- .${property.ident} = computed_value;
% endif
% if property.name in DERIVED_LONGHANDS:
% for derived in DERIVED_LONGHANDS[property.name]:
- Arc::make_mut(&mut context.style.${derived.style_struct.ident})
- .${derived.ident} =
longhands::${derived.ident}
- ::derive_from_${property.ident}(
- &context);
+ ::derive_from_${property.ident}(&mut context);
% endfor
% endif
}
@@ -6485,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;
@@ -6537,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() {
@@ -6558,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)
}
_ => {}
@@ -6566,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,
@@ -6583,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.
@@ -6609,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.
@@ -6655,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)
@@ -6677,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));
}
_ => {}
}
@@ -6705,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)
}
@@ -6930,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/servo.rs b/components/style/servo.rs
index 56aef8f6210..10867d4eaf8 100644
--- a/components/style/servo.rs
+++ b/components/style/servo.rs
@@ -3,13 +3,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use context;
use data;
+use properties::ComputedValues;
use selector_impl::ServoSelectorImpl;
use selector_matching;
use stylesheets;
/// Concrete types for servo Style implementation
pub type Stylesheet = stylesheets::Stylesheet<ServoSelectorImpl>;
-pub type PrivateStyleData = data::PrivateStyleData<ServoSelectorImpl>;
+pub type PrivateStyleData = data::PrivateStyleData<ServoSelectorImpl, ComputedValues>;
pub type Stylist = selector_matching::Stylist<ServoSelectorImpl>;
pub type StylistWrapper = context::StylistWrapper<ServoSelectorImpl>;
pub type SharedStyleContext = context::SharedStyleContext<ServoSelectorImpl>;
diff --git a/components/style/traversal.rs b/components/style/traversal.rs
index 79759cf26b9..f39347e83ab 100644
--- a/components/style/traversal.rs
+++ b/components/style/traversal.rs
@@ -123,7 +123,7 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C,
root: OpaqueNode,
node: N)
where N: TNode,
- C: StyleContext<'a, <N::ConcreteElement as Element>::Impl>,
+ C: StyleContext<'a, <N::ConcreteElement as Element>::Impl, N::ConcreteComputedValues>,
<N::ConcreteElement as Element>::Impl: SelectorImplExt + 'a {
// Initialize layout data.
//
@@ -195,7 +195,7 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C,
// Add ourselves to the LRU cache.
if let Some(element) = shareable_element {
- style_sharing_candidate_cache.insert_if_possible(&element);
+ style_sharing_candidate_cache.insert_if_possible::<'ln, N>(&element);
}
}
StyleSharingResult::StyleWasShared(index, damage) => {
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'
diff --git a/ports/geckolib/Cargo.toml b/ports/geckolib/Cargo.toml
index c8d5dcabcea..cd9031ee98e 100644
--- a/ports/geckolib/Cargo.toml
+++ b/ports/geckolib/Cargo.toml
@@ -3,6 +3,8 @@ name = "geckoservo"
version = "0.0.1"
authors = ["The Servo Project Developers"]
+build = "build.rs"
+
[lib]
name = "geckoservo"
path = "lib.rs"
diff --git a/ports/geckolib/bindings.rs b/ports/geckolib/bindings.rs
index ba761f17d78..545e30d00f7 100644
--- a/ports/geckolib/bindings.rs
+++ b/ports/geckolib/bindings.rs
@@ -28,6 +28,7 @@ pub type intptr_t = int64_t;
pub type uintptr_t = uint64_t;
pub type intmax_t = ::libc::c_long;
pub type uintmax_t = ::libc::c_ulong;
+pub enum nsIAtom { }
pub enum nsINode { }
pub type RawGeckoNode = nsINode;
pub enum Element { }
@@ -35,6 +36,7 @@ pub type RawGeckoElement = Element;
pub enum nsIDocument { }
pub type RawGeckoDocument = nsIDocument;
pub enum ServoNodeData { }
+pub enum ServoComputedValues { }
pub enum RawServoStyleSheet { }
pub enum RawServoStyleSet { }
extern "C" {
@@ -72,7 +74,8 @@ extern "C" {
pub fn Servo_StylesheetFromUTF8Bytes(bytes: *const uint8_t,
length: uint32_t)
-> *mut RawServoStyleSheet;
- pub fn Servo_ReleaseStylesheet(sheet: *mut RawServoStyleSheet);
+ pub fn Servo_AddRefStyleSheet(sheet: *mut RawServoStyleSheet);
+ pub fn Servo_ReleaseStyleSheet(sheet: *mut RawServoStyleSheet);
pub fn Servo_AppendStyleSheet(sheet: *mut RawServoStyleSheet,
set: *mut RawServoStyleSet);
pub fn Servo_PrependStyleSheet(sheet: *mut RawServoStyleSheet,
@@ -82,6 +85,12 @@ extern "C" {
pub fn Servo_StyleSheetHasRules(sheet: *mut RawServoStyleSheet) -> bool;
pub fn Servo_InitStyleSet() -> *mut RawServoStyleSet;
pub fn Servo_DropStyleSet(set: *mut RawServoStyleSet);
+ pub fn Servo_GetComputedValues(element: *mut RawGeckoElement)
+ -> *mut ServoComputedValues;
+ pub fn Servo_GetComputedValuesForAnonymousBox(pseudoTag: *mut nsIAtom)
+ -> *mut ServoComputedValues;
+ pub fn Servo_AddRefComputedValues(arg1: *mut ServoComputedValues);
+ pub fn Servo_ReleaseComputedValues(arg1: *mut ServoComputedValues);
pub fn Gecko_GetAttrAsUTF8(element: *mut RawGeckoElement,
ns: *const uint8_t, name: *const uint8_t,
length: *mut uint32_t)
diff --git a/ports/geckolib/build.rs b/ports/geckolib/build.rs
new file mode 100644
index 00000000000..0cb930b072b
--- /dev/null
+++ b/ports/geckolib/build.rs
@@ -0,0 +1,80 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use std::env;
+use std::fs::File;
+use std::io::Write;
+use std::path::Path;
+use std::process::{Command, Stdio, exit};
+
+#[cfg(windows)]
+fn find_python() -> String {
+ if Command::new("python27.exe").arg("--version").output().is_ok() {
+ return "python27.exe".to_owned();
+ }
+
+ if Command::new("python.exe").arg("--version").output().is_ok() {
+ return "python.exe".to_owned();
+ }
+
+ panic!("Can't find python (tried python27.exe and python.exe)! Try fixing PATH or setting the PYTHON env var");
+}
+
+#[cfg(not(windows))]
+fn find_python() -> String {
+ if Command::new("python2.7").arg("--version").output().unwrap().status.success() {
+ "python2.7"
+ } else {
+ "python"
+ }.to_owned()
+}
+
+fn main() {
+ let python = match env::var("PYTHON") {
+ Ok(python_path) => python_path,
+ Err(_) => find_python(),
+ };
+
+ // Mako refuses to load templates outside the scope of the current working directory,
+ // so we need to run it from the top source directory.
+ let geckolib_dir = Path::new(file!()).parent().unwrap();
+ let top_dir = geckolib_dir.join("..").join("..");
+
+ let style_template = Path::new("components/style/properties.mako.rs");
+ let geckolib_template = Path::new("ports/geckolib/properties.mako.rs");
+ let mako = Path::new("components/style/Mako-0.9.1.zip");
+
+ let result = Command::new(python)
+ .current_dir(top_dir)
+ .env("PYTHONPATH", &mako)
+ .env("STYLE_TEMPLATE", &style_template)
+ .env("GECKOLIB_TEMPLATE", &geckolib_template)
+ .arg("-c")
+ .arg(r#"
+import json
+import os
+import sys
+from mako.template import Template
+from mako import exceptions
+try:
+ style_template = Template(filename=os.environ['STYLE_TEMPLATE'], input_encoding='utf8')
+ style_template.render()
+
+ geckolib_template = Template(filename=os.environ['GECKOLIB_TEMPLATE'], input_encoding='utf8')
+ output = geckolib_template.render(STYLE_STRUCTS = style_template.module.STYLE_STRUCTS,
+ LONGHANDS = style_template.module.LONGHANDS)
+ print(output.encode('utf8'))
+except:
+ sys.stderr.write(exceptions.text_error_template().render().encode('utf8'))
+ sys.exit(1)
+"#)
+ .stderr(Stdio::inherit())
+ .output()
+ .unwrap();
+ if !result.status.success() {
+ exit(1)
+ }
+ let out = env::var("OUT_DIR").unwrap();
+ File::create(&Path::new(&out).join("properties.rs")).unwrap().write_all(&result.stdout).unwrap();
+}
diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs
index 510e39cc041..56c8d9e146c 100644
--- a/ports/geckolib/glue.rs
+++ b/ports/geckolib/glue.rs
@@ -5,24 +5,28 @@
#![allow(unsafe_code)]
use app_units::Au;
-use bindings::RawGeckoDocument;
-use bindings::{ServoNodeData, RawServoStyleSet, RawServoStyleSheet, uint8_t, uint32_t};
+use bindings::{RawGeckoDocument, RawGeckoElement};
+use bindings::{RawServoStyleSet, RawServoStyleSheet, ServoComputedValues, ServoNodeData};
+use bindings::{nsIAtom, uint8_t, uint32_t};
use data::PerDocumentStyleData;
use euclid::Size2D;
+use properties::GeckoComputedValues;
use selector_impl::{SharedStyleContext, Stylesheet};
+use std::marker::PhantomData;
use std::mem::{forget, transmute};
+use std::ptr;
use std::slice;
use std::str::from_utf8_unchecked;
use std::sync::{Arc, Mutex};
use style::context::{ReflowGoal, StylistWrapper};
-use style::dom::{TDocument, TNode};
+use style::dom::{TDocument, TElement, TNode};
use style::error_reporting::StdoutErrorReporter;
use style::parallel;
use style::stylesheets::Origin;
use traversal::RecalcStyleOnly;
use url::Url;
use util::arc_ptr_eq;
-use wrapper::{GeckoDocument, GeckoNode, NonOpaqueStyleData};
+use wrapper::{GeckoDocument, GeckoElement, GeckoNode, NonOpaqueStyleData};
/*
* For Gecko->Servo function calls, we need to redeclare the same signature that was declared in
@@ -82,23 +86,39 @@ pub extern "C" fn Servo_StylesheetFromUTF8Bytes(bytes: *const uint8_t,
}
}
-fn with_arc_stylesheet<F, Output>(raw: *mut RawServoStyleSheet, cb: F) -> Output
- where F: FnOnce(&Arc<Stylesheet>) -> Output {
- let owned = unsafe { consume_arc_stylesheet(raw) };
- let result = cb(&owned);
- forget(owned);
- result
+struct ArcHelpers<GeckoType, ServoType> {
+ phantom1: PhantomData<GeckoType>,
+ phantom2: PhantomData<ServoType>,
}
-unsafe fn consume_arc_stylesheet(raw: *mut RawServoStyleSheet) -> Arc<Stylesheet> {
- transmute(raw)
+impl<GeckoType, ServoType> ArcHelpers<GeckoType, ServoType> {
+ fn with<F, Output>(raw: *mut GeckoType, cb: F) -> Output
+ where F: FnOnce(&Arc<ServoType>) -> Output {
+ let owned = unsafe { Self::into(raw) };
+ let result = cb(&owned);
+ forget(owned);
+ result
+ }
+
+ unsafe fn into(ptr: *mut GeckoType) -> Arc<ServoType> {
+ transmute(ptr)
+ }
+
+ unsafe fn addref(ptr: *mut GeckoType) {
+ Self::with(ptr, |arc| forget(arc.clone()));
+ }
+
+ unsafe fn release(ptr: *mut GeckoType) {
+ let _ = Self::into(ptr);
+ }
}
#[no_mangle]
pub extern "C" fn Servo_AppendStyleSheet(raw_sheet: *mut RawServoStyleSheet,
raw_data: *mut RawServoStyleSet) {
+ type Helpers = ArcHelpers<RawServoStyleSheet, Stylesheet>;
let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data);
- with_arc_stylesheet(raw_sheet, |sheet| {
+ Helpers::with(raw_sheet, |sheet| {
data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets.push(sheet.clone());
data.stylesheets_changed = true;
@@ -108,8 +128,9 @@ pub extern "C" fn Servo_AppendStyleSheet(raw_sheet: *mut RawServoStyleSheet,
#[no_mangle]
pub extern "C" fn Servo_PrependStyleSheet(raw_sheet: *mut RawServoStyleSheet,
raw_data: *mut RawServoStyleSet) {
+ type Helpers = ArcHelpers<RawServoStyleSheet, Stylesheet>;
let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data);
- with_arc_stylesheet(raw_sheet, |sheet| {
+ Helpers::with(raw_sheet, |sheet| {
data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets.insert(0, sheet.clone());
data.stylesheets_changed = true;
@@ -119,8 +140,9 @@ pub extern "C" fn Servo_PrependStyleSheet(raw_sheet: *mut RawServoStyleSheet,
#[no_mangle]
pub extern "C" fn Servo_RemoveStyleSheet(raw_sheet: *mut RawServoStyleSheet,
raw_data: *mut RawServoStyleSet) {
+ type Helpers = ArcHelpers<RawServoStyleSheet, Stylesheet>;
let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data);
- with_arc_stylesheet(raw_sheet, |sheet| {
+ Helpers::with(raw_sheet, |sheet| {
data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets_changed = true;
});
@@ -128,15 +150,46 @@ pub extern "C" fn Servo_RemoveStyleSheet(raw_sheet: *mut RawServoStyleSheet,
#[no_mangle]
pub extern "C" fn Servo_StyleSheetHasRules(raw_sheet: *mut RawServoStyleSheet) -> bool {
- with_arc_stylesheet(raw_sheet, |sheet| !sheet.rules.is_empty())
+ type Helpers = ArcHelpers<RawServoStyleSheet, Stylesheet>;
+ Helpers::with(raw_sheet, |sheet| !sheet.rules.is_empty())
}
+#[no_mangle]
+pub extern "C" fn Servo_AddRefStyleSheet(sheet: *mut RawServoStyleSheet) -> () {
+ type Helpers = ArcHelpers<RawServoStyleSheet, Stylesheet>;
+ unsafe { Helpers::addref(sheet) };
+}
#[no_mangle]
-pub extern "C" fn Servo_ReleaseStylesheet(sheet: *mut RawServoStyleSheet) -> () {
- unsafe {
- let _ = consume_arc_stylesheet(sheet);
- }
+pub extern "C" fn Servo_ReleaseStyleSheet(sheet: *mut RawServoStyleSheet) -> () {
+ type Helpers = ArcHelpers<RawServoStyleSheet, Stylesheet>;
+ unsafe { Helpers::release(sheet) };
+}
+
+#[no_mangle]
+pub extern "C" fn Servo_GetComputedValues(element: *mut RawGeckoElement)
+ -> *mut ServoComputedValues {
+ let node = unsafe { GeckoElement::from_raw(element).as_node() };
+ let arc_cv = node.borrow_data().map(|data| data.style.clone());
+ arc_cv.map_or(ptr::null_mut(), |arc| unsafe { transmute(arc) })
+}
+
+#[no_mangle]
+pub extern "C" fn Servo_GetComputedValuesForAnonymousBox(_: *mut nsIAtom)
+ -> *mut ServoComputedValues {
+ unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn Servo_AddRefComputedValues(ptr: *mut ServoComputedValues) -> () {
+ type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>;
+ unsafe { Helpers::addref(ptr) };
+}
+
+#[no_mangle]
+pub extern "C" fn Servo_ReleaseComputedValues(ptr: *mut ServoComputedValues) -> () {
+ type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>;
+ unsafe { Helpers::release(ptr) };
}
#[no_mangle]
@@ -145,7 +198,6 @@ pub extern "C" fn Servo_InitStyleSet() -> *mut RawServoStyleSet {
Box::into_raw(data) as *mut RawServoStyleSet
}
-
#[no_mangle]
pub extern "C" fn Servo_DropStyleSet(data: *mut RawServoStyleSet) -> () {
unsafe {
diff --git a/ports/geckolib/lib.rs b/ports/geckolib/lib.rs
index dfb9bb06ea3..e28bf611a5c 100644
--- a/ports/geckolib/lib.rs
+++ b/ports/geckolib/lib.rs
@@ -40,3 +40,10 @@ pub mod glue;
mod selector_impl;
mod traversal;
mod wrapper;
+
+// Generated from the properties.mako.rs template by build.rs
+#[macro_use]
+#[allow(unsafe_code)]
+pub mod properties {
+ include!(concat!(env!("OUT_DIR"), "/properties.rs"));
+}
diff --git a/ports/geckolib/properties.mako.rs b/ports/geckolib/properties.mako.rs
new file mode 100644
index 00000000000..4d2010dcecd
--- /dev/null
+++ b/ports/geckolib/properties.mako.rs
@@ -0,0 +1,168 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use app_units::Au;
+use std::sync::Arc;
+use style::custom_properties::ComputedValuesMap;
+use style::logical_geometry::WritingMode;
+use style::properties::{CascadePropertyFn, ComputedValues, TComputedValues};
+use style::properties::longhands;
+use style::properties::style_struct_traits::*;
+
+#[derive(Clone)]
+pub struct GeckoComputedValues {
+ % for style_struct in STYLE_STRUCTS:
+ ${style_struct.ident}: Arc<Gecko${style_struct.name}>,
+ % endfor
+
+ custom_properties: Option<Arc<ComputedValuesMap>>,
+ shareable: bool,
+ pub writing_mode: WritingMode,
+ pub root_font_size: Au,
+}
+
+impl TComputedValues for GeckoComputedValues {
+% for style_struct in STYLE_STRUCTS:
+ type Concrete${style_struct.name} = Gecko${style_struct.name};
+% endfor
+
+ // These will go away, and we will never implement them.
+ fn as_servo<'a>(&'a self) -> &'a ComputedValues { unimplemented!() }
+ fn as_servo_mut<'a>(&'a mut self) -> &'a mut ComputedValues { unimplemented!() }
+
+ fn new(custom_properties: Option<Arc<ComputedValuesMap>>,
+ shareable: bool,
+ writing_mode: WritingMode,
+ root_font_size: Au,
+ % for style_struct in STYLE_STRUCTS:
+ ${style_struct.ident}: Arc<Gecko${style_struct.name}>,
+ % endfor
+ ) -> Self {
+ GeckoComputedValues {
+ 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 { unimplemented!() }
+
+ fn do_cascade_property<F: FnOnce(&Vec<Option<CascadePropertyFn<Self>>>)>(_: F) {
+ unimplemented!()
+ }
+
+ % 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
+
+ fn custom_properties(&self) -> Option<Arc<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, s: Au) { self.root_font_size = s; }
+ fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; }
+
+ #[inline]
+ fn is_multicol(&self) -> bool { unimplemented!() }
+}
+
+% for style_struct in STYLE_STRUCTS:
+#[derive(PartialEq, Clone, HeapSizeOf, Debug)]
+pub struct Gecko${style_struct.name};
+impl T${style_struct.name} for Gecko${style_struct.name} {
+ % for longhand in style_struct.longhands:
+ fn set_${longhand.ident}(&mut self, _: longhands::${longhand.ident}::computed_value::T) {
+ unimplemented!()
+ }
+ fn copy_${longhand.ident}_from(&mut self, _: &Self) {
+ unimplemented!()
+ }
+ % endfor
+ % if style_struct.name == "Animation":
+ fn transition_count(&self) -> usize {
+ unimplemented!()
+ }
+ % 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 {
+ unimplemented!()
+ }
+ % endfor
+ % elif style_struct.name == "Box":
+ fn clone_display(&self) -> longhands::display::computed_value::T {
+ unimplemented!()
+ }
+ fn clone_position(&self) -> longhands::position::computed_value::T {
+ unimplemented!()
+ }
+ fn is_floated(&self) -> bool {
+ unimplemented!()
+ }
+ fn overflow_x_is_visible(&self) -> bool {
+ unimplemented!()
+ }
+ fn overflow_y_is_visible(&self) -> bool {
+ unimplemented!()
+ }
+ % elif style_struct.name == "Color":
+ fn clone_color(&self) -> longhands::color::computed_value::T {
+ unimplemented!()
+ }
+ % elif style_struct.name == "Font":
+ fn clone_font_size(&self) -> longhands::font_size::computed_value::T {
+ unimplemented!()
+ }
+ fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T {
+ unimplemented!()
+ }
+ fn compute_font_hash(&mut self) {
+ unimplemented!()
+ }
+ % elif style_struct.name == "InheritedBox":
+ fn clone_direction(&self) -> longhands::direction::computed_value::T {
+ unimplemented!()
+ }
+ fn clone_writing_mode(&self) -> longhands::writing_mode::computed_value::T {
+ unimplemented!()
+ }
+ fn clone_text_orientation(&self) -> longhands::text_orientation::computed_value::T {
+ unimplemented!()
+ }
+ % elif style_struct.name == "InheritedText":
+ fn clone__servo_text_decorations_in_effect(&self) ->
+ longhands::_servo_text_decorations_in_effect::computed_value::T {
+ unimplemented!()
+ }
+ % elif style_struct.name == "Outline":
+ fn outline_is_none_or_hidden_and_has_nonzero_width(&self) -> bool {
+ unimplemented!()
+ }
+ % elif style_struct.name == "Text":
+ fn has_underline(&self) -> bool {
+ unimplemented!()
+ }
+ fn has_overline(&self) -> bool {
+ unimplemented!()
+ }
+ fn has_line_through(&self) -> bool {
+ unimplemented!()
+ }
+ % endif
+
+}
+
+% endfor
diff --git a/ports/geckolib/selector_impl.rs b/ports/geckolib/selector_impl.rs
index 45ded949052..0bd84ab9782 100644
--- a/ports/geckolib/selector_impl.rs
+++ b/ports/geckolib/selector_impl.rs
@@ -2,19 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use properties::GeckoComputedValues;
use selectors::parser::{ParserContext, SelectorImpl};
-use std::process;
use style;
use style::element_state::ElementState;
-use style::error_reporting::StdoutErrorReporter;
use style::selector_impl::SelectorImplExt;
-use style::stylesheets::Origin;
-use url::Url;
pub type Stylist = style::selector_matching::Stylist<GeckoSelectorImpl>;
pub type Stylesheet = style::stylesheets::Stylesheet<GeckoSelectorImpl>;
pub type SharedStyleContext = style::context::SharedStyleContext<GeckoSelectorImpl>;
-pub type PrivateStyleData = style::data::PrivateStyleData<GeckoSelectorImpl>;
+pub type PrivateStyleData = style::data::PrivateStyleData<GeckoSelectorImpl, GeckoComputedValues>;
pub struct GeckoSelectorImpl;
diff --git a/ports/geckolib/traversal.rs b/ports/geckolib/traversal.rs
index b1cfbd1fbbd..33fc1fd322e 100644
--- a/ports/geckolib/traversal.rs
+++ b/ports/geckolib/traversal.rs
@@ -2,20 +2,23 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use properties::GeckoComputedValues;
use selector_impl::{GeckoSelectorImpl, SharedStyleContext};
use std::cell::RefCell;
use std::mem;
use std::rc::Rc;
use style::context::{LocalStyleContext, StyleContext};
-use style::dom::{OpaqueNode, TNode};
+use style::dom::OpaqueNode;
use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use style::traversal::{DomTraversalContext, recalc_style_at};
+use wrapper::GeckoNode;
-thread_local!(static LOCAL_CONTEXT_KEY: RefCell<Option<Rc<LocalStyleContext>>> = RefCell::new(None));
+thread_local!(static LOCAL_CONTEXT_KEY:
+ RefCell<Option<Rc<LocalStyleContext<GeckoComputedValues>>>> = RefCell::new(None));
// Keep this implementation in sync with the one in components/layout/context.rs.
fn create_or_get_local_context(shared: &SharedStyleContext)
- -> Rc<LocalStyleContext> {
+ -> Rc<LocalStyleContext<GeckoComputedValues>> {
LOCAL_CONTEXT_KEY.with(|r| {
let mut r = r.borrow_mut();
if let Some(context) = r.clone() {
@@ -36,7 +39,7 @@ fn create_or_get_local_context(shared: &SharedStyleContext)
pub struct StandaloneStyleContext<'a> {
pub shared: &'a SharedStyleContext,
- cached_local_context: Rc<LocalStyleContext>,
+ cached_local_context: Rc<LocalStyleContext<GeckoComputedValues>>,
}
impl<'a> StandaloneStyleContext<'a> {
@@ -49,12 +52,12 @@ impl<'a> StandaloneStyleContext<'a> {
}
}
-impl<'a> StyleContext<'a, GeckoSelectorImpl> for StandaloneStyleContext<'a> {
+impl<'a> StyleContext<'a, GeckoSelectorImpl, GeckoComputedValues> for StandaloneStyleContext<'a> {
fn shared_context(&self) -> &'a SharedStyleContext {
&self.shared
}
- fn local_context(&self) -> &LocalStyleContext {
+ fn local_context(&self) -> &LocalStyleContext<GeckoComputedValues> {
&self.cached_local_context
}
}
@@ -64,8 +67,7 @@ pub struct RecalcStyleOnly<'lc> {
root: OpaqueNode,
}
-impl<'lc, N: TNode> DomTraversalContext<N> for RecalcStyleOnly<'lc>
- where N::ConcreteElement: ::selectors::Element<Impl=GeckoSelectorImpl> {
+impl<'lc, 'ln> DomTraversalContext<GeckoNode<'ln>> for RecalcStyleOnly<'lc> {
type SharedContext = SharedStyleContext;
#[allow(unsafe_code)]
fn new<'a>(shared: &'a Self::SharedContext, root: OpaqueNode) -> Self {
@@ -78,7 +80,7 @@ impl<'lc, N: TNode> DomTraversalContext<N> for RecalcStyleOnly<'lc>
}
}
- fn process_preorder(&self, node: N) { recalc_style_at(&self.context, self.root, node); }
- fn process_postorder(&self, _: N) {}
+ fn process_preorder(&self, node: GeckoNode<'ln>) { recalc_style_at(&self.context, self.root, node); }
+ fn process_postorder(&self, _: GeckoNode<'ln>) {}
}
diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs
index bb2e58c4ee2..7262f91e47e 100644
--- a/ports/geckolib/wrapper.rs
+++ b/ports/geckolib/wrapper.rs
@@ -19,6 +19,7 @@ use bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsElement, Gecko_SetN
use bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode};
use bindings::{ServoNodeData};
use libc::uintptr_t;
+use properties::GeckoComputedValues;
use selector_impl::{GeckoSelectorImpl, NonTSPseudoClass, PrivateStyleData};
use selectors::Element;
use selectors::matching::DeclarationBlock;
@@ -35,7 +36,7 @@ use style::dom::{OpaqueNode, TDocument, TElement, TNode, TRestyleDamage, UnsafeN
use style::element_state::ElementState;
#[allow(unused_imports)] // Used in commented-out code.
use style::error_reporting::StdoutErrorReporter;
-use style::properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock};
+use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
#[allow(unused_imports)] // Used in commented-out code.
use style::properties::{parse_style_attribute};
use style::restyle_hints::ElementSnapshot;
@@ -78,7 +79,8 @@ impl<'ln> GeckoNode<'ln> {
#[derive(Clone, Copy)]
pub struct DummyRestyleDamage;
impl TRestyleDamage for DummyRestyleDamage {
- fn compute(_: Option<&Arc<ComputedValues>>, _: &ComputedValues) -> Self { DummyRestyleDamage }
+ type ConcreteComputedValues = GeckoComputedValues;
+ fn compute(_: Option<&Arc<GeckoComputedValues>>, _: &GeckoComputedValues) -> Self { DummyRestyleDamage }
fn rebuild_and_reflow() -> Self { DummyRestyleDamage }
}
impl BitOr for DummyRestyleDamage {
@@ -92,6 +94,7 @@ impl<'ln> TNode for GeckoNode<'ln> {
type ConcreteDocument = GeckoDocument<'ln>;
type ConcreteElement = GeckoElement<'ln>;
type ConcreteRestyleDamage = DummyRestyleDamage;
+ type ConcreteComputedValues = GeckoComputedValues;
fn to_unsafe(&self) -> UnsafeNode {
(self.node as usize, 0)
@@ -297,7 +300,7 @@ pub struct GeckoElement<'le> {
}
impl<'le> GeckoElement<'le> {
- unsafe fn from_raw(el: *mut RawGeckoElement) -> GeckoElement<'le> {
+ pub unsafe fn from_raw(el: *mut RawGeckoElement) -> GeckoElement<'le> {
GeckoElement {
element: el,
chain: PhantomData,
diff --git a/python/tidy.py b/python/tidy.py
index 989e617648b..999d5745577 100644
--- a/python/tidy.py
+++ b/python/tidy.py
@@ -35,6 +35,7 @@ ignored_files = [
# Generated and upstream code combined with our own. Could use cleanup
os.path.join(".", "ports", "gonk", "src", "native_window_glue.cpp"),
os.path.join(".", "ports", "geckolib", "bindings.rs"),
+ os.path.join(".", "ports", "geckolib", "gecko_style_structs.rs"),
os.path.join(".", "resources", "hsts_preload.json"),
os.path.join(".", "tests", "wpt", "metadata", "MANIFEST.json"),
os.path.join(".", "tests", "wpt", "metadata-css", "MANIFEST.json"),
@@ -60,6 +61,8 @@ ignored_dirs = [
# Generated and upstream code combined with our own. Could use cleanup
os.path.join(".", "target"),
os.path.join(".", "ports", "cef"),
+ # Tooling, generated locally from external repos.
+ os.path.join(".", "ports", "geckolib", "tools"),
# Hidden directories
os.path.join(".", "."),
]
@@ -260,6 +263,7 @@ def check_rust(file_name, lines):
if not file_name.endswith(".rs") or \
file_name.endswith("properties.mako.rs") or \
file_name.endswith(os.path.join("style", "build.rs")) or \
+ file_name.endswith(os.path.join("geckolib", "build.rs")) or \
file_name.endswith(os.path.join("unit", "style", "stylesheets.rs")):
raise StopIteration
comment_depth = 0
diff --git a/tests/unit/style/lib.rs b/tests/unit/style/lib.rs
index c8432c12b30..bd443004076 100644
--- a/tests/unit/style/lib.rs
+++ b/tests/unit/style/lib.rs
@@ -25,10 +25,10 @@ extern crate util;
#[cfg(test)] mod writing_modes {
use style::logical_geometry::WritingMode;
- use style::properties::{INITIAL_VALUES, get_writing_mode};
+ use style::properties::{INITIAL_SERVO_VALUES, TComputedValues, get_writing_mode};
#[test]
fn initial_writing_mode_is_empty() {
- assert_eq!(get_writing_mode(INITIAL_VALUES.get_inheritedbox()), WritingMode::empty())
+ assert_eq!(get_writing_mode(INITIAL_SERVO_VALUES.get_inheritedbox()), WritingMode::empty())
}
}