Auto merge of #10155 - bholley:generalize_style_structs, r=SimonSapin

Generalize the style structs

This allows geckolib to pass gecko style structs and have the style system write to them directly, provided we implement all the traits.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10155)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-03-25 03:27:33 +05:30
commit 605842f193
47 changed files with 995 additions and 433 deletions

View file

@ -41,7 +41,7 @@ use std::ops::{Deref, DerefMut};
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::{border_style, cursor, filter, image_rendering, mix_blend_mode}; use style::computed_values::{border_style, cursor, filter, image_rendering, mix_blend_mode};
use style::computed_values::{pointer_events}; use style::computed_values::{pointer_events};
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use style_traits::cursor::Cursor; use style_traits::cursor::Cursor;
use text::TextRun; use text::TextRun;
use text::glyph::CharIndex; use text::glyph::CharIndex;

View file

@ -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::computed_values::{position, text_align, transform_style};
use style::context::StyleContext; use style::context::StyleContext;
use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode}; 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::{LengthOrNone, LengthOrPercentageOrNone};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
use util::geometry::MAX_RECT; use util::geometry::MAX_RECT;

View file

@ -45,7 +45,7 @@ use std::sync::atomic::Ordering;
use style::computed_values::content::ContentItem; use style::computed_values::content::ContentItem;
use style::computed_values::{caption_side, display, empty_cells, float, list_style_position}; use style::computed_values::{caption_side, display, empty_cells, float, list_style_position};
use style::computed_values::{position}; use style::computed_values::{position};
use style::properties::{self, ComputedValues}; use style::properties::{self, ComputedValues, TComputedValues};
use table::TableFlow; use table::TableFlow;
use table_caption::TableCaptionFlow; use table_caption::TableCaptionFlow;
use table_cell::TableCellFlow; use table_cell::TableCellFlow;

View file

@ -26,13 +26,14 @@ use std::rc::Rc;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
use style::context::{LocalStyleContext, StyleContext}; use style::context::{LocalStyleContext, StyleContext};
use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache}; use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use style::properties::ComputedValues;
use style::selector_impl::ServoSelectorImpl; use style::selector_impl::ServoSelectorImpl;
use style::servo::SharedStyleContext; use style::servo::SharedStyleContext;
use url::Url; use url::Url;
use util::opts; use util::opts;
struct LocalLayoutContext { struct LocalLayoutContext {
style_context: LocalStyleContext, style_context: LocalStyleContext<ComputedValues>,
font_context: RefCell<FontContext>, font_context: RefCell<FontContext>,
} }
@ -107,12 +108,12 @@ pub struct LayoutContext<'a> {
cached_local_layout_context: Rc<LocalLayoutContext>, 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 { fn shared_context(&self) -> &'a SharedStyleContext {
&self.shared.style_context &self.shared.style_context
} }
fn local_context(&self) -> &LocalStyleContext { fn local_context(&self) -> &LocalStyleContext<ComputedValues> {
&self.cached_local_layout_context.style_context &self.cached_local_layout_context.style_context
} }
} }

View file

@ -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::computed_values::{transform, transform_style, visibility};
use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
use style::properties::style_structs::Border; use style::properties::style_structs::Border;
use style::properties::{self, ComputedValues}; use style::properties::{self, ComputedValues, TComputedValues};
use style::values::RGBA; use style::values::RGBA;
use style::values::computed; use style::values::computed;
use style::values::computed::{LengthOrNone, LengthOrPercentage, LengthOrPercentageOrAuto, LinearGradient}; use style::values::computed::{LengthOrNone, LengthOrPercentage, LengthOrPercentageOrAuto, LinearGradient};

View file

@ -28,8 +28,8 @@ use std::cmp::max;
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::{flex_direction, float}; use style::computed_values::{flex_direction, float};
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues;
use style::properties::style_structs; use style::properties::style_structs;
use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::LengthOrPercentageOrAuto; use style::values::computed::LengthOrPercentageOrAuto;
// A mode describes which logical axis a flex axis is parallel with. // A mode describes which logical axis a flex axis is parallel with.

View file

@ -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::computed_values::{clear, display, empty_cells, float, position, overflow_x, text_align};
use style::dom::TRestyleDamage; use style::dom::TRestyleDamage;
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::properties::{self, ComputedValues}; use style::properties::{self, ComputedValues, TComputedValues};
use style::values::computed::LengthOrPercentageOrAuto; use style::values::computed::LengthOrPercentageOrAuto;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, TableFlow}; use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, TableFlow};
use table_caption::TableCaptionFlow; use table_caption::TableCaptionFlow;

View file

@ -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::computed_values::{white_space, word_break, z_index};
use style::dom::TRestyleDamage; use style::dom::TRestyleDamage;
use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode}; 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::{LengthOrPercentage, LengthOrPercentageOrAuto};
use style::values::computed::{LengthOrPercentageOrNone}; use style::values::computed::{LengthOrPercentageOrNone};
use text; use text;

View file

@ -20,7 +20,7 @@ use std::sync::Arc;
use style::computed_values::content::ContentItem; use style::computed_values::content::ContentItem;
use style::computed_values::{display, list_style_type}; use style::computed_values::{display, list_style_type};
use style::dom::TRestyleDamage; use style::dom::TRestyleDamage;
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use text::TextRunScanner; use text::TextRunScanner;
use wrapper::PseudoElementType; use wrapper::PseudoElementType;

View file

@ -7,7 +7,7 @@ use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::float; use style::computed_values::float;
use style::dom::TRestyleDamage; use style::dom::TRestyleDamage;
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
bitflags! { bitflags! {
#[doc = "Individual layout actions that may be necessary after restyling."] #[doc = "Individual layout actions that may be necessary after restyling."]
@ -53,6 +53,7 @@ bitflags! {
} }
impl TRestyleDamage for RestyleDamage { impl TRestyleDamage for RestyleDamage {
type ConcreteComputedValues = ComputedValues;
fn compute(old: Option<&Arc<ComputedValues>>, new: &ComputedValues) -> RestyleDamage { compute_damage(old, new) } 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. /// Returns a bitmask that represents a flow that needs to be rebuilt and reflowed.

View file

@ -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::{display, overflow_x, position, text_align, text_justify};
use style::computed_values::{text_overflow, vertical_align, white_space}; use style::computed_values::{text_overflow, vertical_align, white_space};
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::LengthOrPercentage; use style::values::computed::LengthOrPercentage;
use text; use text;
use unicode_bidi; use unicode_bidi;

View file

@ -72,6 +72,7 @@ use style::error_reporting::ParseErrorReporter;
use style::logical_geometry::LogicalPoint; use style::logical_geometry::LogicalPoint;
use style::media_queries::{Device, MediaType}; use style::media_queries::{Device, MediaType};
use style::parallel::WorkQueueData; use style::parallel::WorkQueueData;
use style::properties::TComputedValues;
use style::selector_impl::ServoSelectorImpl; use style::selector_impl::ServoSelectorImpl;
use style::selector_matching::USER_OR_USER_AGENT_STYLESHEETS; use style::selector_matching::USER_OR_USER_AGENT_STYLESHEETS;
use style::servo::{SharedStyleContext, Stylesheet, Stylist}; use style::servo::{SharedStyleContext, Stylesheet, Stylist};

View file

@ -23,7 +23,7 @@ use inline::InlineMetrics;
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::{list_style_type, position}; use style::computed_values::{list_style_type, position};
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use text; use text;
/// A block with the CSS `display` property equal to `list-item`. /// A block with the CSS `display` property equal to `list-item`.

View file

@ -13,7 +13,7 @@ use std::cmp::{max, min};
use std::fmt; use std::fmt;
use style::computed_values::transform::ComputedMatrix; use style::computed_values::transform::ComputedMatrix;
use style::logical_geometry::LogicalMargin; use style::logical_geometry::LogicalMargin;
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::{BorderRadiusSize, LengthOrPercentageOrAuto}; use style::values::computed::{BorderRadiusSize, LengthOrPercentageOrAuto};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrNone}; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrNone};

View file

@ -21,7 +21,7 @@ use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::context::StyleContext; use style::context::StyleContext;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use style::values::computed::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use util::print_tree::PrintTree; use util::print_tree::PrintTree;

View file

@ -27,6 +27,7 @@ use std::sync::{Arc, Mutex};
use string_cache::Atom; use string_cache::Atom;
use style::computed_values; use style::computed_values;
use style::logical_geometry::{WritingMode, BlockFlowDirection, InlineBaseDirection}; use style::logical_geometry::{WritingMode, BlockFlowDirection, InlineBaseDirection};
use style::properties::TComputedValues;
use style::properties::longhands::{display, position}; use style::properties::longhands::{display, position};
use style::properties::style_structs; use style::properties::style_structs;
use style::selector_impl::PseudoElement; use style::selector_impl::PseudoElement;

View file

@ -25,7 +25,7 @@ use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::{border_collapse, border_spacing, table_layout}; use style::computed_values::{border_collapse, border_spacing, table_layout};
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use style::values::CSSFloat; use style::values::CSSFloat;
use style::values::computed::LengthOrPercentageOrAuto; use style::values::computed::LengthOrPercentageOrAuto;
use table_row::{TableRowFlow}; use table_row::{TableRowFlow};

View file

@ -17,7 +17,7 @@ use gfx::display_list::{StackingContext, StackingContextId};
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use util::print_tree::PrintTree; use util::print_tree::PrintTree;
/// A table formatting context. /// A table formatting context.

View file

@ -21,7 +21,7 @@ use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::{border_collapse, border_top_style}; use style::computed_values::{border_collapse, border_top_style};
use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use table::InternalTable; use table::InternalTable;
use table_row::{CollapsedBorder, CollapsedBorderProvenance}; use table_row::{CollapsedBorder, CollapsedBorderProvenance};
use util::print_tree::PrintTree; use util::print_tree::PrintTree;

View file

@ -18,7 +18,7 @@ use std::cmp::max;
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::LengthOrPercentageOrAuto; use style::values::computed::LengthOrPercentageOrAuto;
/// A table formatting context. /// A table formatting context.

View file

@ -25,7 +25,7 @@ use std::iter::{Enumerate, IntoIterator, Peekable};
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::{border_collapse, border_spacing, border_top_style}; use style::computed_values::{border_collapse, border_spacing, border_top_style};
use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode}; use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode};
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use style::values::computed::LengthOrPercentageOrAuto; use style::values::computed::LengthOrPercentageOrAuto;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt}; use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt};
use table_cell::{CollapsedBordersForCell, TableCellFlow}; use table_cell::{CollapsedBordersForCell, TableCellFlow};

View file

@ -21,7 +21,7 @@ use std::iter::{IntoIterator, Iterator, Peekable};
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::{border_collapse, border_spacing}; use style::computed_values::{border_collapse, border_spacing};
use style::logical_geometry::{LogicalSize, WritingMode}; use style::logical_geometry::{LogicalSize, WritingMode};
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, TableLikeFlow}; use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, TableLikeFlow};
use table_row; use table_row;
use util::print_tree::PrintTree; use util::print_tree::PrintTree;

View file

@ -31,7 +31,7 @@ use std::ops::Add;
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::{border_collapse, table_layout}; use style::computed_values::{border_collapse, table_layout};
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use style::values::CSSFloat; use style::values::CSSFloat;
use style::values::computed::LengthOrPercentageOrAuto; use style::values::computed::LengthOrPercentageOrAuto;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize}; use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize};

View file

@ -23,8 +23,8 @@ use std::sync::Arc;
use style::computed_values::{line_height, text_orientation, text_rendering, text_transform}; use style::computed_values::{line_height, text_orientation, text_rendering, text_transform};
use style::computed_values::{white_space}; use style::computed_values::{white_space};
use style::logical_geometry::{LogicalSize, WritingMode}; use style::logical_geometry::{LogicalSize, WritingMode};
use style::properties::ComputedValues;
use style::properties::style_structs::Font as FontStyle; use style::properties::style_structs::Font as FontStyle;
use style::properties::{ComputedValues, TComputedValues};
use unicode_bidi::{is_rtl, process_text}; use unicode_bidi::{is_rtl, process_text};
use unicode_script::{get_script, Script}; use unicode_script::{get_script, Script};
use util::linked_list::split_off_head; use util::linked_list::split_off_head;

View file

@ -66,7 +66,7 @@ use style::computed_values::content::ContentItem;
use style::computed_values::{content, display}; use style::computed_values::{content, display};
use style::dom::{TDocument, TElement, TNode, UnsafeNode}; use style::dom::{TDocument, TElement, TNode, UnsafeNode};
use style::element_state::*; use style::element_state::*;
use style::properties::ComputedValues; use style::properties::{ComputedValues, TComputedValues};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
use style::restyle_hints::ElementSnapshot; use style::restyle_hints::ElementSnapshot;
use style::selector_impl::{NonTSPseudoClass, PseudoElement, ServoSelectorImpl}; use style::selector_impl::{NonTSPseudoClass, PseudoElement, ServoSelectorImpl};
@ -131,6 +131,7 @@ impl<'ln> ServoLayoutNode<'ln> {
} }
impl<'ln> TNode for ServoLayoutNode<'ln> { impl<'ln> TNode for ServoLayoutNode<'ln> {
type ConcreteComputedValues = ComputedValues;
type ConcreteElement = ServoLayoutElement<'ln>; type ConcreteElement = ServoLayoutElement<'ln>;
type ConcreteDocument = ServoLayoutDocument<'ln>; type ConcreteDocument = ServoLayoutDocument<'ln>;
type ConcreteRestyleDamage = RestyleDamage; type ConcreteRestyleDamage = RestyleDamage;

View file

@ -7,7 +7,6 @@ use bezier::Bezier;
use cssparser::{Color, RGBA}; use cssparser::{Color, RGBA};
use dom::{OpaqueNode, TRestyleDamage}; use dom::{OpaqueNode, TRestyleDamage};
use euclid::point::Point2D; use euclid::point::Point2D;
use properties::ComputedValues;
use properties::longhands::background_position::computed_value::T as BackgroundPosition; use properties::longhands::background_position::computed_value::T as BackgroundPosition;
use properties::longhands::border_spacing::computed_value::T as BorderSpacing; use properties::longhands::border_spacing::computed_value::T as BorderSpacing;
use properties::longhands::clip::computed_value::ClipRect; 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::vertical_align::computed_value::T as VerticalAlign;
use properties::longhands::visibility::computed_value::T as Visibility; use properties::longhands::visibility::computed_value::T as Visibility;
use properties::longhands::z_index::computed_value::T as ZIndex; 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::cmp::Ordering;
use std::iter::repeat; use std::iter::repeat;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
@ -73,7 +74,7 @@ impl PropertyAnimation {
-> Vec<PropertyAnimation> { -> Vec<PropertyAnimation> {
let mut result = Vec::new(); let mut result = Vec::new();
let transition_property = 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 transition_property != TransitionProperty::All {
if let Some(property_animation) = if let Some(property_animation) =
PropertyAnimation::from_transition_property(transition_property, 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 /// 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 /// difference. This is called from the layout worker threads. Returns true if any animations were
/// kicked off and false otherwise. /// kicked off and false otherwise.
pub fn start_transitions_if_applicable(new_animations_sender: &Mutex<Sender<Animation>>, pub fn start_transitions_if_applicable<C: TComputedValues>(new_animations_sender: &Mutex<Sender<Animation>>,
node: OpaqueNode, node: OpaqueNode,
old_style: &ComputedValues, old_style: &C,
new_style: &mut ComputedValues) new_style: &mut C)
-> bool { -> bool {
let mut had_animations = false; 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. // 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 { for property_animation in property_animations {
// Set the property to the initial value. // 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. // Kick off the animation.
let now = time::precise_time_s(); 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 = let start_time =
now + (animation_style.transition_delay.0.get_mod(i).seconds() as f64); now + (animation_style.transition_delay.0.get_mod(i).seconds() as f64);
new_animations_sender.lock().unwrap().send(Animation { 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 /// Updates a single animation and associated style based on the current time. If `damage` is
/// provided, inserts the appropriate restyle damage. /// provided, inserts the appropriate restyle damage.
pub fn update_style_for_animation<ConcreteRestyleDamage: TRestyleDamage>(animation: &Animation, pub fn update_style_for_animation<C: TComputedValues,
style: &mut Arc<ComputedValues>, Damage: TRestyleDamage<ConcreteComputedValues=C>>(animation: &Animation,
damage: Option<&mut ConcreteRestyleDamage>) { style: &mut Arc<C>,
damage: Option<&mut Damage>) {
let now = time::precise_time_s(); let now = time::precise_time_s();
let mut progress = (now - animation.start_time) / animation.duration(); let mut progress = (now - animation.start_time) / animation.duration();
if progress > 1.0 { if progress > 1.0 {
@ -977,9 +979,9 @@ pub fn update_style_for_animation<ConcreteRestyleDamage: TRestyleDamage>(animati
} }
let mut new_style = (*style).clone(); 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 { if let Some(damage) = damage {
*damage = *damage | ConcreteRestyleDamage::compute(Some(style), &new_style); *damage = *damage | Damage::compute(Some(style), &new_style);
} }
*style = new_style *style = new_style

View file

@ -8,6 +8,7 @@ use dom::OpaqueNode;
use error_reporting::ParseErrorReporter; use error_reporting::ParseErrorReporter;
use euclid::Size2D; use euclid::Size2D;
use matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache}; use matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use properties::TComputedValues;
use selector_impl::SelectorImplExt; use selector_impl::SelectorImplExt;
use selector_matching::Stylist; use selector_matching::Stylist;
use std::cell::RefCell; use std::cell::RefCell;
@ -54,15 +55,15 @@ pub struct SharedStyleContext<Impl: SelectorImplExt> {
pub error_reporter: Box<ParseErrorReporter + Sync>, pub error_reporter: Box<ParseErrorReporter + Sync>,
} }
pub struct LocalStyleContext { pub struct LocalStyleContext<C: TComputedValues> {
pub applicable_declarations_cache: RefCell<ApplicableDeclarationsCache>, pub applicable_declarations_cache: RefCell<ApplicableDeclarationsCache<C>>,
pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache>, 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 shared_context(&self) -> &'a SharedStyleContext<Impl>;
fn local_context(&self) -> &LocalStyleContext; fn local_context(&self) -> &LocalStyleContext<C>;
} }
/// Why we're doing reflow. /// Why we're doing reflow.

View file

@ -2,26 +2,28 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use properties::ComputedValues; use properties::TComputedValues;
use selectors::parser::SelectorImpl; use selectors::parser::SelectorImpl;
use std::collections::HashMap; use std::collections::HashMap;
use std::hash::BuildHasherDefault; use std::hash::BuildHasherDefault;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::AtomicIsize; 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. /// 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). /// 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. /// Information needed during parallel traversals.
pub parallel: DomParallelInfo, pub parallel: DomParallelInfo,
} }
impl<Impl: SelectorImpl> PrivateStyleData<Impl> { impl<Impl, ConcreteComputedValues> PrivateStyleData<Impl, ConcreteComputedValues>
pub fn new() -> PrivateStyleData<Impl> { where Impl: SelectorImpl, ConcreteComputedValues: TComputedValues {
pub fn new() -> PrivateStyleData<Impl, ConcreteComputedValues> {
PrivateStyleData { PrivateStyleData {
style: None, style: None,
per_pseudo: HashMap::with_hasher(Default::default()), per_pseudo: HashMap::with_hasher(Default::default()),

View file

@ -6,7 +6,7 @@
use data::PrivateStyleData; use data::PrivateStyleData;
use element_state::ElementState; 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 restyle_hints::{ElementSnapshot, RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint};
use selector_impl::ElementExt; use selector_impl::ElementExt;
use selectors::Element; use selectors::Element;
@ -43,14 +43,16 @@ impl OpaqueNode {
} }
pub trait TRestyleDamage : BitOr<Output=Self> + Copy { 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; fn rebuild_and_reflow() -> Self;
} }
pub trait TNode : Sized + Copy + Clone { pub trait TNode : Sized + Copy + Clone {
type ConcreteElement: TElement<ConcreteNode = Self, ConcreteDocument = Self::ConcreteDocument>; type ConcreteElement: TElement<ConcreteNode = Self, ConcreteDocument = Self::ConcreteDocument>;
type ConcreteDocument: TDocument<ConcreteNode = Self, ConcreteElement = Self::ConcreteElement>; 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; fn to_unsafe(&self) -> UnsafeNode;
unsafe fn from_unsafe(n: &UnsafeNode) -> Self; unsafe fn from_unsafe(n: &UnsafeNode) -> Self;
@ -135,17 +137,20 @@ pub trait TNode : Sized + Copy + Clone {
/// Borrows the PrivateStyleData without checks. /// Borrows the PrivateStyleData without checks.
#[inline(always)] #[inline(always)]
unsafe fn borrow_data_unchecked(&self) 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. /// Borrows the PrivateStyleData immutably. Fails on a conflicting borrow.
#[inline(always)] #[inline(always)]
fn borrow_data(&self) 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. /// Borrows the PrivateStyleData mutably. Fails on a conflicting borrow.
#[inline(always)] #[inline(always)]
fn mutate_data(&self) 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. /// Get the description of how to account for recent style changes.
fn restyle_damage(self) -> Self::ConcreteRestyleDamage; 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 /// Returns the style results for the given node. If CSS selector matching
/// has not yet been performed, fails. /// 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()) Ref::map(self.borrow_data().unwrap(), |data| data.style.as_ref().unwrap())
} }

View file

@ -50,7 +50,7 @@ pub mod animation;
pub mod attr; pub mod attr;
pub mod bezier; pub mod bezier;
pub mod context; pub mod context;
mod custom_properties; pub mod custom_properties;
pub mod data; pub mod data;
pub mod dom; pub mod dom;
pub mod element_state; pub mod element_state;

View file

@ -8,8 +8,8 @@ use animation::{self, Animation};
use context::SharedStyleContext; use context::SharedStyleContext;
use data::PrivateStyleData; use data::PrivateStyleData;
use dom::{TElement, TNode, TRestyleDamage}; use dom::{TElement, TNode, TRestyleDamage};
use properties::{ComputedValues, PropertyDeclaration, cascade}; use properties::{PropertyDeclaration, TComputedValues, cascade};
use selector_impl::SelectorImplExt; use selector_impl::{ElementExt, SelectorImplExt};
use selector_matching::{DeclarationBlock, Stylist}; use selector_matching::{DeclarationBlock, Stylist};
use selectors::Element; use selectors::Element;
use selectors::bloom::BloomFilter; use selectors::bloom::BloomFilter;
@ -151,25 +151,25 @@ impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> {
static APPLICABLE_DECLARATIONS_CACHE_SIZE: usize = 32; static APPLICABLE_DECLARATIONS_CACHE_SIZE: usize = 32;
pub struct ApplicableDeclarationsCache { pub struct ApplicableDeclarationsCache<C: TComputedValues> {
cache: SimpleHashCache<ApplicableDeclarationsCacheEntry, Arc<ComputedValues>>, cache: SimpleHashCache<ApplicableDeclarationsCacheEntry, Arc<C>>,
} }
impl ApplicableDeclarationsCache { impl<C: TComputedValues> ApplicableDeclarationsCache<C> {
pub fn new() -> ApplicableDeclarationsCache { pub fn new() -> Self {
ApplicableDeclarationsCache { ApplicableDeclarationsCache {
cache: SimpleHashCache::new(APPLICABLE_DECLARATIONS_CACHE_SIZE), 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)) { match self.cache.find(&ApplicableDeclarationsCacheQuery::new(declarations)) {
None => None, None => None,
Some(ref values) => Some((*values).clone()), 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) 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. /// An LRU cache of the last few nodes seen, so that we can aggressively try to reuse their styles.
pub struct StyleSharingCandidateCache { pub struct StyleSharingCandidateCache<C: TComputedValues> {
cache: LRUCache<StyleSharingCandidate, ()>, cache: LRUCache<StyleSharingCandidate<C>, ()>,
} }
#[derive(Clone)] #[derive(Clone)]
pub struct StyleSharingCandidate { pub struct StyleSharingCandidate<C: TComputedValues> {
pub style: Arc<ComputedValues>, pub style: Arc<C>,
pub parent_style: Arc<ComputedValues>, pub parent_style: Arc<C>,
pub local_name: Atom, pub local_name: Atom,
// FIXME(pcwalton): Should be a list of atoms instead. // FIXME(pcwalton): Should be a list of atoms instead.
pub class: Option<String>, pub class: Option<String>,
@ -195,8 +195,8 @@ pub struct StyleSharingCandidate {
pub link: bool, pub link: bool,
} }
impl PartialEq for StyleSharingCandidate { impl<C: TComputedValues> PartialEq for StyleSharingCandidate<C> {
fn eq(&self, other: &StyleSharingCandidate) -> bool { fn eq(&self, other: &Self) -> bool {
arc_ptr_eq(&self.style, &other.style) && arc_ptr_eq(&self.style, &other.style) &&
arc_ptr_eq(&self.parent_style, &other.parent_style) && arc_ptr_eq(&self.parent_style, &other.parent_style) &&
self.local_name == other.local_name && 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 /// Attempts to create a style sharing candidate from this node. Returns
/// the style sharing candidate or `None` if this node is ineligible for /// the style sharing candidate or `None` if this node is ineligible for
/// style sharing. /// style sharing.
#[allow(unsafe_code)] #[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() { let parent_element = match element.parent_element() {
None => return None, None => return None,
Some(parent_element) => parent_element, Some(parent_element) => parent_element,
@ -254,7 +254,7 @@ impl StyleSharingCandidate {
link: element.is_link(), link: element.is_link(),
namespace: (*element.get_namespace()).clone(), namespace: (*element.get_namespace()).clone(),
common_style_affecting_attributes: 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; static STYLE_SHARING_CANDIDATE_CACHE_SIZE: usize = 40;
impl StyleSharingCandidateCache { impl<C: TComputedValues> StyleSharingCandidateCache<C> {
pub fn new() -> StyleSharingCandidateCache { pub fn new() -> Self {
StyleSharingCandidateCache { StyleSharingCandidateCache {
cache: LRUCache::new(STYLE_SHARING_CANDIDATE_CACHE_SIZE), cache: LRUCache::new(STYLE_SHARING_CANDIDATE_CACHE_SIZE),
} }
} }
pub fn iter(&self) -> Iter<(StyleSharingCandidate, ())> { pub fn iter(&self) -> Iter<(StyleSharingCandidate<C>, ())> {
self.cache.iter() self.cache.iter()
} }
pub fn insert_if_possible<E: TElement>(&mut self, element: &E) { pub fn insert_if_possible<N: TNode<ConcreteComputedValues=C>>(&mut self, element: &N::ConcreteElement) {
match StyleSharingCandidate::new(element) { match StyleSharingCandidate::new::<N>(element) {
None => {} None => {}
Some(candidate) => self.cache.insert(candidate, ()) Some(candidate) => self.cache.insert(candidate, ())
} }
@ -368,15 +368,15 @@ trait PrivateMatchMethods: TNode
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt { where <Self::ConcreteElement as Element>::Impl: SelectorImplExt {
fn cascade_node_pseudo_element(&self, fn cascade_node_pseudo_element(&self,
context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>, context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
parent_style: Option<&Arc<ComputedValues>>, parent_style: Option<&Arc<Self::ConcreteComputedValues>>,
applicable_declarations: &[DeclarationBlock], applicable_declarations: &[DeclarationBlock],
mut style: Option<&mut Arc<ComputedValues>>, mut style: Option<&mut Arc<Self::ConcreteComputedValues>>,
applicable_declarations_cache: applicable_declarations_cache:
&mut ApplicableDeclarationsCache, &mut ApplicableDeclarationsCache<Self::ConcreteComputedValues>,
new_animations_sender: &Mutex<Sender<Animation>>, new_animations_sender: &Mutex<Sender<Animation>>,
shareable: bool, shareable: bool,
animate_properties: bool) animate_properties: bool)
-> (Self::ConcreteRestyleDamage, Arc<ComputedValues>) { -> (Self::ConcreteRestyleDamage, Arc<Self::ConcreteComputedValues>) {
let mut cacheable = true; let mut cacheable = true;
if animate_properties { if animate_properties {
cacheable = !self.update_animations_for_cascade(context, &mut style) && cacheable; cacheable = !self.update_animations_for_cascade(context, &mut style) && cacheable;
@ -416,7 +416,8 @@ trait PrivateMatchMethods: TNode
if animate_properties { if animate_properties {
if let Some(ref style) = style { if let Some(ref style) = style {
let animations_started = let animations_started =
animation::start_transitions_if_applicable(new_animations_sender, animation::start_transitions_if_applicable::<Self::ConcreteComputedValues>(
new_animations_sender,
self.opaque(), self.opaque(),
&**style, &**style,
&mut this_style); &mut this_style);
@ -440,7 +441,7 @@ trait PrivateMatchMethods: TNode
fn update_animations_for_cascade(&self, fn update_animations_for_cascade(&self,
context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>, context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
style: &mut Option<&mut Arc<ComputedValues>>) style: &mut Option<&mut Arc<Self::ConcreteComputedValues>>)
-> bool { -> bool {
let style = match *style { let style = match *style {
None => return false, None => return false,
@ -456,7 +457,7 @@ trait PrivateMatchMethods: TNode
had_animations_to_expire = animations_to_expire.is_some(); had_animations_to_expire = animations_to_expire.is_some();
if let Some(ref animations) = animations_to_expire { if let Some(ref animations) = animations_to_expire {
for animation in *animations { 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 { if had_running_animations {
let mut all_running_animations = context.running_animations.write().unwrap(); let mut all_running_animations = context.running_animations.write().unwrap();
for running_animation in all_running_animations.get(&this_opaque).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); all_running_animations.remove(&this_opaque);
} }
@ -489,14 +491,15 @@ impl<N: TNode> PrivateMatchMethods for N
trait PrivateElementMatchMethods: TElement { trait PrivateElementMatchMethods: TElement {
fn share_style_with_candidate_if_possible(&self, fn share_style_with_candidate_if_possible(&self,
parent_node: Option<Self::ConcreteNode>, parent_node: Option<Self::ConcreteNode>,
candidate: &StyleSharingCandidate) candidate: &StyleSharingCandidate<<Self::ConcreteNode as
-> Option<Arc<ComputedValues>> { TNode>::ConcreteComputedValues>)
-> Option<Arc<<Self::ConcreteNode as TNode>::ConcreteComputedValues>> {
let parent_node = match parent_node { let parent_node = match parent_node {
Some(ref parent_node) if parent_node.as_element().is_some() => parent_node, Some(ref parent_node) if parent_node.as_element().is_some() => parent_node,
Some(_) | None => return None, Some(_) | None => return None,
}; };
let parent_data: Option<&PrivateStyleData<_>> = unsafe { let parent_data: Option<&PrivateStyleData<_, _>> = unsafe {
parent_node.borrow_data_unchecked().map(|d| &*d) parent_node.borrow_data_unchecked().map(|d| &*d)
}; };
@ -550,7 +553,8 @@ pub trait ElementMatchMethods : TElement
/// guarantee that at the type system level yet. /// guarantee that at the type system level yet.
unsafe fn share_style_if_possible(&self, unsafe fn share_style_if_possible(&self,
style_sharing_candidate_cache: style_sharing_candidate_cache:
&mut StyleSharingCandidateCache, &mut StyleSharingCandidateCache<<Self::ConcreteNode as
TNode>::ConcreteComputedValues>,
parent: Option<Self::ConcreteNode>) parent: Option<Self::ConcreteNode>)
-> StyleSharingResult<<Self::ConcreteNode as TNode>::ConcreteRestyleDamage> { -> StyleSharingResult<<Self::ConcreteNode as TNode>::ConcreteRestyleDamage> {
if opts::get().disable_share_style_cache { if opts::get().disable_share_style_cache {
@ -639,7 +643,8 @@ pub trait MatchMethods : TNode {
context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>, context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>,
parent: Option<Self>, parent: Option<Self>,
applicable_declarations: &ApplicableDeclarations<<Self::ConcreteElement as Element>::Impl>, 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>>) new_animations_sender: &Mutex<Sender<Animation>>)
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt { 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 // Get our parent's style. This must be unsafe so that we don't touch the parent's

File diff suppressed because it is too large Load diff

View file

@ -3,13 +3,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use context; use context;
use data; use data;
use properties::ComputedValues;
use selector_impl::ServoSelectorImpl; use selector_impl::ServoSelectorImpl;
use selector_matching; use selector_matching;
use stylesheets; use stylesheets;
/// Concrete types for servo Style implementation /// Concrete types for servo Style implementation
pub type Stylesheet = stylesheets::Stylesheet<ServoSelectorImpl>; 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 Stylist = selector_matching::Stylist<ServoSelectorImpl>;
pub type StylistWrapper = context::StylistWrapper<ServoSelectorImpl>; pub type StylistWrapper = context::StylistWrapper<ServoSelectorImpl>;
pub type SharedStyleContext = context::SharedStyleContext<ServoSelectorImpl>; pub type SharedStyleContext = context::SharedStyleContext<ServoSelectorImpl>;

View file

@ -123,7 +123,7 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C,
root: OpaqueNode, root: OpaqueNode,
node: N) node: N)
where N: TNode, 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 { <N::ConcreteElement as Element>::Impl: SelectorImplExt + 'a {
// Initialize layout data. // Initialize layout data.
// //
@ -195,7 +195,7 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C,
// Add ourselves to the LRU cache. // Add ourselves to the LRU cache.
if let Some(element) = shareable_element { 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) => { StyleSharingResult::StyleWasShared(index, damage) => {

View file

@ -100,6 +100,7 @@ pub mod specified {
use std::ops::Mul; use std::ops::Mul;
use style_traits::values::specified::AllowedNumericType; use style_traits::values::specified::AllowedNumericType;
use super::AuExtensionMethods; use super::AuExtensionMethods;
use super::computed::{TContext, ToComputedValue};
use super::{CSSFloat, FONT_MEDIUM_PX}; use super::{CSSFloat, FONT_MEDIUM_PX};
use url::Url; use url::Url;
@ -1418,11 +1419,11 @@ pub mod specified {
} }
} }
impl super::computed::ToComputedValue for Time { impl ToComputedValue for Time {
type ComputedValue = Time; type ComputedValue = Time;
#[inline] #[inline]
fn to_computed_value(&self, _: &super::computed::Context) -> Time { fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> Time {
*self *self
} }
} }
@ -1437,7 +1438,8 @@ pub mod specified {
pub mod computed { pub mod computed {
use app_units::Au; use app_units::Au;
use euclid::size::Size2D; use euclid::size::Size2D;
use properties::ComputedValues; use properties::TComputedValues;
use properties::style_struct_traits::TFont;
use std::fmt; use std::fmt;
use super::AuExtensionMethods; use super::AuExtensionMethods;
use super::specified::AngleOrCorner; use super::specified::AngleOrCorner;
@ -1446,21 +1448,39 @@ pub mod computed {
pub use cssparser::Color as CSSColor; pub use cssparser::Color as CSSColor;
pub use super::specified::{Angle, BorderStyle, Time}; 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 is_root_element: bool,
pub viewport_size: Size2D<Au>, 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": /// Values access through this need to be in the properties "computed early":
/// color, text-decoration, font-size, display, position, float, border-*-style, outline-style /// 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 { pub trait ToComputedValue {
type ComputedValue; type ComputedValue;
#[inline] #[inline]
fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue; fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> Self::ComputedValue;
} }
pub trait ComputedValueAsSpecified {} pub trait ComputedValueAsSpecified {}
@ -1469,7 +1489,7 @@ pub mod computed {
type ComputedValue = T; type ComputedValue = T;
#[inline] #[inline]
fn to_computed_value(&self, _context: &Context) -> T { fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> T {
self.clone() self.clone()
} }
} }
@ -1478,7 +1498,7 @@ pub mod computed {
type ComputedValue = CSSColor; type ComputedValue = CSSColor;
#[inline] #[inline]
fn to_computed_value(&self, _context: &Context) -> CSSColor { fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> CSSColor {
self.parsed self.parsed
} }
} }
@ -1489,17 +1509,17 @@ pub mod computed {
type ComputedValue = Au; type ComputedValue = Au;
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> Au { fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> Au {
match *self { match *self {
specified::Length::Absolute(length) => length, specified::Length::Absolute(length) => length,
specified::Length::Calc(calc) => calc.to_computed_value(context).length(), specified::Length::Calc(calc) => calc.to_computed_value(context).length(),
specified::Length::FontRelative(length) => specified::Length::FontRelative(length) =>
length.to_computed_value(context.style.get_font().font_size, length.to_computed_value(context.style().get_font().clone_font_size(),
context.style.root_font_size), context.style().root_font_size()),
specified::Length::ViewportPercentage(length) => specified::Length::ViewportPercentage(length) =>
length.to_computed_value(context.viewport_size), length.to_computed_value(context.viewport_size()),
specified::Length::ServoCharacterWidth(length) => 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 { impl ToComputedValue for specified::CalcLengthOrPercentage {
type ComputedValue = 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; let mut length = None;
if let Some(absolute) = self.absolute { if let Some(absolute) = self.absolute {
@ -1593,13 +1613,13 @@ pub mod computed {
for val in &[self.vw, self.vh, self.vmin, self.vmax] { for val in &[self.vw, self.vh, self.vmin, self.vmax] {
if let Some(val) = *val { if let Some(val) = *val {
length = Some(length.unwrap_or(Au(0)) + 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] { for val in &[self.ch, self.em, self.ex, self.rem] {
if let Some(val) = *val { if let Some(val) = *val {
length = Some(length.unwrap_or(Au(0)) + val.to_computed_value( 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; type ComputedValue = BorderRadiusSize;
#[inline] #[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 specified::BorderRadiusSize(s) = *self;
let w = s.width.to_computed_value(context); let w = s.width.to_computed_value(context);
let h = s.height.to_computed_value(context); let h = s.height.to_computed_value(context);
@ -1664,7 +1684,7 @@ pub mod computed {
impl ToComputedValue for specified::LengthOrPercentage { impl ToComputedValue for specified::LengthOrPercentage {
type ComputedValue = LengthOrPercentage; type ComputedValue = LengthOrPercentage;
fn to_computed_value(&self, context: &Context) -> LengthOrPercentage { fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentage {
match *self { match *self {
specified::LengthOrPercentage::Length(value) => { specified::LengthOrPercentage::Length(value) => {
LengthOrPercentage::Length(value.to_computed_value(context)) LengthOrPercentage::Length(value.to_computed_value(context))
@ -1712,7 +1732,7 @@ pub mod computed {
type ComputedValue = LengthOrPercentageOrAuto; type ComputedValue = LengthOrPercentageOrAuto;
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAuto { fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentageOrAuto {
match *self { match *self {
specified::LengthOrPercentageOrAuto::Length(value) => { specified::LengthOrPercentageOrAuto::Length(value) => {
LengthOrPercentageOrAuto::Length(value.to_computed_value(context)) LengthOrPercentageOrAuto::Length(value.to_computed_value(context))
@ -1764,7 +1784,7 @@ pub mod computed {
type ComputedValue = LengthOrPercentageOrNone; type ComputedValue = LengthOrPercentageOrNone;
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrNone { fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentageOrNone {
match *self { match *self {
specified::LengthOrPercentageOrNone::Length(value) => { specified::LengthOrPercentageOrNone::Length(value) => {
LengthOrPercentageOrNone::Length(value.to_computed_value(context)) LengthOrPercentageOrNone::Length(value.to_computed_value(context))
@ -1812,7 +1832,7 @@ pub mod computed {
type ComputedValue = LengthOrNone; type ComputedValue = LengthOrNone;
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> LengthOrNone { fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrNone {
match *self { match *self {
specified::LengthOrNone::Length(specified::Length::Calc(calc)) => { specified::LengthOrNone::Length(specified::Length::Calc(calc)) => {
LengthOrNone::Length(calc.to_computed_value(context).length()) LengthOrNone::Length(calc.to_computed_value(context).length())
@ -1840,7 +1860,7 @@ pub mod computed {
type ComputedValue = Image; type ComputedValue = Image;
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> Image { fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> Image {
match *self { match *self {
specified::Image::Url(ref url) => Image::Url(url.clone()), specified::Image::Url(ref url) => Image::Url(url.clone()),
specified::Image::LinearGradient(ref linear_gradient) => { specified::Image::LinearGradient(ref linear_gradient) => {
@ -1936,7 +1956,7 @@ pub mod computed {
type ComputedValue = LinearGradient; type ComputedValue = LinearGradient;
#[inline] #[inline]
fn to_computed_value(&self, context: &Context) -> LinearGradient { fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LinearGradient {
let specified::LinearGradient { let specified::LinearGradient {
angle_or_corner, angle_or_corner,
ref stops ref stops

View file

@ -8,7 +8,7 @@ use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser,
use euclid::scale_factor::ScaleFactor; use euclid::scale_factor::ScaleFactor;
use euclid::size::{Size2D, TypedSize2D}; use euclid::size::{Size2D, TypedSize2D};
use parser::{ParserContext, log_css_error}; use parser::{ParserContext, log_css_error};
use properties::INITIAL_VALUES; use properties::{ComputedValues, TComputedValues};
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::collections::hash_map::{Entry, HashMap}; use std::collections::hash_map::{Entry, HashMap};
use std::fmt; use std::fmt;
@ -594,8 +594,8 @@ impl MaybeNew for ViewportConstraints {
let context = Context { let context = Context {
is_root_element: false, is_root_element: false,
viewport_size: initial_viewport, viewport_size: initial_viewport,
inherited_style: &*INITIAL_VALUES, inherited_style: ComputedValues::initial_values(),
style: INITIAL_VALUES.clone(), style: ComputedValues::initial_values().clone(),
}; };
// DEVICE-ADAPT § 9.3 Resolving 'extend-to-zoom' // DEVICE-ADAPT § 9.3 Resolving 'extend-to-zoom'

View file

@ -3,6 +3,8 @@ name = "geckoservo"
version = "0.0.1" version = "0.0.1"
authors = ["The Servo Project Developers"] authors = ["The Servo Project Developers"]
build = "build.rs"
[lib] [lib]
name = "geckoservo" name = "geckoservo"
path = "lib.rs" path = "lib.rs"

View file

@ -28,6 +28,7 @@ pub type intptr_t = int64_t;
pub type uintptr_t = uint64_t; pub type uintptr_t = uint64_t;
pub type intmax_t = ::libc::c_long; pub type intmax_t = ::libc::c_long;
pub type uintmax_t = ::libc::c_ulong; pub type uintmax_t = ::libc::c_ulong;
pub enum nsIAtom { }
pub enum nsINode { } pub enum nsINode { }
pub type RawGeckoNode = nsINode; pub type RawGeckoNode = nsINode;
pub enum Element { } pub enum Element { }
@ -35,6 +36,7 @@ pub type RawGeckoElement = Element;
pub enum nsIDocument { } pub enum nsIDocument { }
pub type RawGeckoDocument = nsIDocument; pub type RawGeckoDocument = nsIDocument;
pub enum ServoNodeData { } pub enum ServoNodeData { }
pub enum ServoComputedValues { }
pub enum RawServoStyleSheet { } pub enum RawServoStyleSheet { }
pub enum RawServoStyleSet { } pub enum RawServoStyleSet { }
extern "C" { extern "C" {
@ -72,7 +74,8 @@ extern "C" {
pub fn Servo_StylesheetFromUTF8Bytes(bytes: *const uint8_t, pub fn Servo_StylesheetFromUTF8Bytes(bytes: *const uint8_t,
length: uint32_t) length: uint32_t)
-> *mut RawServoStyleSheet; -> *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, pub fn Servo_AppendStyleSheet(sheet: *mut RawServoStyleSheet,
set: *mut RawServoStyleSet); set: *mut RawServoStyleSet);
pub fn Servo_PrependStyleSheet(sheet: *mut RawServoStyleSheet, pub fn Servo_PrependStyleSheet(sheet: *mut RawServoStyleSheet,
@ -82,6 +85,12 @@ extern "C" {
pub fn Servo_StyleSheetHasRules(sheet: *mut RawServoStyleSheet) -> bool; pub fn Servo_StyleSheetHasRules(sheet: *mut RawServoStyleSheet) -> bool;
pub fn Servo_InitStyleSet() -> *mut RawServoStyleSet; pub fn Servo_InitStyleSet() -> *mut RawServoStyleSet;
pub fn Servo_DropStyleSet(set: *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, pub fn Gecko_GetAttrAsUTF8(element: *mut RawGeckoElement,
ns: *const uint8_t, name: *const uint8_t, ns: *const uint8_t, name: *const uint8_t,
length: *mut uint32_t) length: *mut uint32_t)

80
ports/geckolib/build.rs Normal file
View file

@ -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();
}

View file

@ -5,24 +5,28 @@
#![allow(unsafe_code)] #![allow(unsafe_code)]
use app_units::Au; use app_units::Au;
use bindings::RawGeckoDocument; use bindings::{RawGeckoDocument, RawGeckoElement};
use bindings::{ServoNodeData, RawServoStyleSet, RawServoStyleSheet, uint8_t, uint32_t}; use bindings::{RawServoStyleSet, RawServoStyleSheet, ServoComputedValues, ServoNodeData};
use bindings::{nsIAtom, uint8_t, uint32_t};
use data::PerDocumentStyleData; use data::PerDocumentStyleData;
use euclid::Size2D; use euclid::Size2D;
use properties::GeckoComputedValues;
use selector_impl::{SharedStyleContext, Stylesheet}; use selector_impl::{SharedStyleContext, Stylesheet};
use std::marker::PhantomData;
use std::mem::{forget, transmute}; use std::mem::{forget, transmute};
use std::ptr;
use std::slice; use std::slice;
use std::str::from_utf8_unchecked; use std::str::from_utf8_unchecked;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use style::context::{ReflowGoal, StylistWrapper}; use style::context::{ReflowGoal, StylistWrapper};
use style::dom::{TDocument, TNode}; use style::dom::{TDocument, TElement, TNode};
use style::error_reporting::StdoutErrorReporter; use style::error_reporting::StdoutErrorReporter;
use style::parallel; use style::parallel;
use style::stylesheets::Origin; use style::stylesheets::Origin;
use traversal::RecalcStyleOnly; use traversal::RecalcStyleOnly;
use url::Url; use url::Url;
use util::arc_ptr_eq; 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 * 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 struct ArcHelpers<GeckoType, ServoType> {
where F: FnOnce(&Arc<Stylesheet>) -> Output { phantom1: PhantomData<GeckoType>,
let owned = unsafe { consume_arc_stylesheet(raw) }; phantom2: PhantomData<ServoType>,
}
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); let result = cb(&owned);
forget(owned); forget(owned);
result result
} }
unsafe fn consume_arc_stylesheet(raw: *mut RawServoStyleSheet) -> Arc<Stylesheet> { unsafe fn into(ptr: *mut GeckoType) -> Arc<ServoType> {
transmute(raw) 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] #[no_mangle]
pub extern "C" fn Servo_AppendStyleSheet(raw_sheet: *mut RawServoStyleSheet, pub extern "C" fn Servo_AppendStyleSheet(raw_sheet: *mut RawServoStyleSheet,
raw_data: *mut RawServoStyleSet) { raw_data: *mut RawServoStyleSet) {
type Helpers = ArcHelpers<RawServoStyleSheet, Stylesheet>;
let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); 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.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets.push(sheet.clone()); data.stylesheets.push(sheet.clone());
data.stylesheets_changed = true; data.stylesheets_changed = true;
@ -108,8 +128,9 @@ pub extern "C" fn Servo_AppendStyleSheet(raw_sheet: *mut RawServoStyleSheet,
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_PrependStyleSheet(raw_sheet: *mut RawServoStyleSheet, pub extern "C" fn Servo_PrependStyleSheet(raw_sheet: *mut RawServoStyleSheet,
raw_data: *mut RawServoStyleSet) { raw_data: *mut RawServoStyleSet) {
type Helpers = ArcHelpers<RawServoStyleSheet, Stylesheet>;
let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); 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.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets.insert(0, sheet.clone()); data.stylesheets.insert(0, sheet.clone());
data.stylesheets_changed = true; data.stylesheets_changed = true;
@ -119,8 +140,9 @@ pub extern "C" fn Servo_PrependStyleSheet(raw_sheet: *mut RawServoStyleSheet,
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_RemoveStyleSheet(raw_sheet: *mut RawServoStyleSheet, pub extern "C" fn Servo_RemoveStyleSheet(raw_sheet: *mut RawServoStyleSheet,
raw_data: *mut RawServoStyleSet) { raw_data: *mut RawServoStyleSet) {
type Helpers = ArcHelpers<RawServoStyleSheet, Stylesheet>;
let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); 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.retain(|x| !arc_ptr_eq(x, sheet));
data.stylesheets_changed = true; data.stylesheets_changed = true;
}); });
@ -128,15 +150,46 @@ pub extern "C" fn Servo_RemoveStyleSheet(raw_sheet: *mut RawServoStyleSheet,
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSheetHasRules(raw_sheet: *mut RawServoStyleSheet) -> bool { 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] #[no_mangle]
pub extern "C" fn Servo_ReleaseStylesheet(sheet: *mut RawServoStyleSheet) -> () { pub extern "C" fn Servo_AddRefStyleSheet(sheet: *mut RawServoStyleSheet) -> () {
unsafe { type Helpers = ArcHelpers<RawServoStyleSheet, Stylesheet>;
let _ = consume_arc_stylesheet(sheet); unsafe { Helpers::addref(sheet) };
} }
#[no_mangle]
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] #[no_mangle]
@ -145,7 +198,6 @@ pub extern "C" fn Servo_InitStyleSet() -> *mut RawServoStyleSet {
Box::into_raw(data) as *mut RawServoStyleSet Box::into_raw(data) as *mut RawServoStyleSet
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_DropStyleSet(data: *mut RawServoStyleSet) -> () { pub extern "C" fn Servo_DropStyleSet(data: *mut RawServoStyleSet) -> () {
unsafe { unsafe {

View file

@ -40,3 +40,10 @@ pub mod glue;
mod selector_impl; mod selector_impl;
mod traversal; mod traversal;
mod wrapper; 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"));
}

View file

@ -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

View file

@ -2,19 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use properties::GeckoComputedValues;
use selectors::parser::{ParserContext, SelectorImpl}; use selectors::parser::{ParserContext, SelectorImpl};
use std::process;
use style; use style;
use style::element_state::ElementState; use style::element_state::ElementState;
use style::error_reporting::StdoutErrorReporter;
use style::selector_impl::SelectorImplExt; use style::selector_impl::SelectorImplExt;
use style::stylesheets::Origin;
use url::Url;
pub type Stylist = style::selector_matching::Stylist<GeckoSelectorImpl>; pub type Stylist = style::selector_matching::Stylist<GeckoSelectorImpl>;
pub type Stylesheet = style::stylesheets::Stylesheet<GeckoSelectorImpl>; pub type Stylesheet = style::stylesheets::Stylesheet<GeckoSelectorImpl>;
pub type SharedStyleContext = style::context::SharedStyleContext<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; pub struct GeckoSelectorImpl;

View file

@ -2,20 +2,23 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use properties::GeckoComputedValues;
use selector_impl::{GeckoSelectorImpl, SharedStyleContext}; use selector_impl::{GeckoSelectorImpl, SharedStyleContext};
use std::cell::RefCell; use std::cell::RefCell;
use std::mem; use std::mem;
use std::rc::Rc; use std::rc::Rc;
use style::context::{LocalStyleContext, StyleContext}; use style::context::{LocalStyleContext, StyleContext};
use style::dom::{OpaqueNode, TNode}; use style::dom::OpaqueNode;
use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache}; use style::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use style::traversal::{DomTraversalContext, recalc_style_at}; 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. // Keep this implementation in sync with the one in components/layout/context.rs.
fn create_or_get_local_context(shared: &SharedStyleContext) fn create_or_get_local_context(shared: &SharedStyleContext)
-> Rc<LocalStyleContext> { -> Rc<LocalStyleContext<GeckoComputedValues>> {
LOCAL_CONTEXT_KEY.with(|r| { LOCAL_CONTEXT_KEY.with(|r| {
let mut r = r.borrow_mut(); let mut r = r.borrow_mut();
if let Some(context) = r.clone() { if let Some(context) = r.clone() {
@ -36,7 +39,7 @@ fn create_or_get_local_context(shared: &SharedStyleContext)
pub struct StandaloneStyleContext<'a> { pub struct StandaloneStyleContext<'a> {
pub shared: &'a SharedStyleContext, pub shared: &'a SharedStyleContext,
cached_local_context: Rc<LocalStyleContext>, cached_local_context: Rc<LocalStyleContext<GeckoComputedValues>>,
} }
impl<'a> StandaloneStyleContext<'a> { 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 { fn shared_context(&self) -> &'a SharedStyleContext {
&self.shared &self.shared
} }
fn local_context(&self) -> &LocalStyleContext { fn local_context(&self) -> &LocalStyleContext<GeckoComputedValues> {
&self.cached_local_context &self.cached_local_context
} }
} }
@ -64,8 +67,7 @@ pub struct RecalcStyleOnly<'lc> {
root: OpaqueNode, root: OpaqueNode,
} }
impl<'lc, N: TNode> DomTraversalContext<N> for RecalcStyleOnly<'lc> impl<'lc, 'ln> DomTraversalContext<GeckoNode<'ln>> for RecalcStyleOnly<'lc> {
where N::ConcreteElement: ::selectors::Element<Impl=GeckoSelectorImpl> {
type SharedContext = SharedStyleContext; type SharedContext = SharedStyleContext;
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn new<'a>(shared: &'a Self::SharedContext, root: OpaqueNode) -> Self { 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_preorder(&self, node: GeckoNode<'ln>) { recalc_style_at(&self.context, self.root, node); }
fn process_postorder(&self, _: N) {} fn process_postorder(&self, _: GeckoNode<'ln>) {}
} }

View file

@ -19,6 +19,7 @@ use bindings::{Gecko_LocalName, Gecko_Namespace, Gecko_NodeIsElement, Gecko_SetN
use bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; use bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode};
use bindings::{ServoNodeData}; use bindings::{ServoNodeData};
use libc::uintptr_t; use libc::uintptr_t;
use properties::GeckoComputedValues;
use selector_impl::{GeckoSelectorImpl, NonTSPseudoClass, PrivateStyleData}; use selector_impl::{GeckoSelectorImpl, NonTSPseudoClass, PrivateStyleData};
use selectors::Element; use selectors::Element;
use selectors::matching::DeclarationBlock; use selectors::matching::DeclarationBlock;
@ -35,7 +36,7 @@ use style::dom::{OpaqueNode, TDocument, TElement, TNode, TRestyleDamage, UnsafeN
use style::element_state::ElementState; use style::element_state::ElementState;
#[allow(unused_imports)] // Used in commented-out code. #[allow(unused_imports)] // Used in commented-out code.
use style::error_reporting::StdoutErrorReporter; use style::error_reporting::StdoutErrorReporter;
use style::properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
#[allow(unused_imports)] // Used in commented-out code. #[allow(unused_imports)] // Used in commented-out code.
use style::properties::{parse_style_attribute}; use style::properties::{parse_style_attribute};
use style::restyle_hints::ElementSnapshot; use style::restyle_hints::ElementSnapshot;
@ -78,7 +79,8 @@ impl<'ln> GeckoNode<'ln> {
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct DummyRestyleDamage; pub struct DummyRestyleDamage;
impl TRestyleDamage for 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 } fn rebuild_and_reflow() -> Self { DummyRestyleDamage }
} }
impl BitOr for DummyRestyleDamage { impl BitOr for DummyRestyleDamage {
@ -92,6 +94,7 @@ impl<'ln> TNode for GeckoNode<'ln> {
type ConcreteDocument = GeckoDocument<'ln>; type ConcreteDocument = GeckoDocument<'ln>;
type ConcreteElement = GeckoElement<'ln>; type ConcreteElement = GeckoElement<'ln>;
type ConcreteRestyleDamage = DummyRestyleDamage; type ConcreteRestyleDamage = DummyRestyleDamage;
type ConcreteComputedValues = GeckoComputedValues;
fn to_unsafe(&self) -> UnsafeNode { fn to_unsafe(&self) -> UnsafeNode {
(self.node as usize, 0) (self.node as usize, 0)
@ -297,7 +300,7 @@ pub struct GeckoElement<'le> {
} }
impl<'le> 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 { GeckoElement {
element: el, element: el,
chain: PhantomData, chain: PhantomData,

View file

@ -35,6 +35,7 @@ ignored_files = [
# Generated and upstream code combined with our own. Could use cleanup # 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", "gonk", "src", "native_window_glue.cpp"),
os.path.join(".", "ports", "geckolib", "bindings.rs"), 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(".", "resources", "hsts_preload.json"),
os.path.join(".", "tests", "wpt", "metadata", "MANIFEST.json"), os.path.join(".", "tests", "wpt", "metadata", "MANIFEST.json"),
os.path.join(".", "tests", "wpt", "metadata-css", "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 # Generated and upstream code combined with our own. Could use cleanup
os.path.join(".", "target"), os.path.join(".", "target"),
os.path.join(".", "ports", "cef"), os.path.join(".", "ports", "cef"),
# Tooling, generated locally from external repos.
os.path.join(".", "ports", "geckolib", "tools"),
# Hidden directories # Hidden directories
os.path.join(".", "."), os.path.join(".", "."),
] ]
@ -260,6 +263,7 @@ def check_rust(file_name, lines):
if not file_name.endswith(".rs") or \ if not file_name.endswith(".rs") or \
file_name.endswith("properties.mako.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("style", "build.rs")) or \
file_name.endswith(os.path.join("geckolib", "build.rs")) or \
file_name.endswith(os.path.join("unit", "style", "stylesheets.rs")): file_name.endswith(os.path.join("unit", "style", "stylesheets.rs")):
raise StopIteration raise StopIteration
comment_depth = 0 comment_depth = 0

View file

@ -25,10 +25,10 @@ extern crate util;
#[cfg(test)] mod writing_modes { #[cfg(test)] mod writing_modes {
use style::logical_geometry::WritingMode; use style::logical_geometry::WritingMode;
use style::properties::{INITIAL_VALUES, get_writing_mode}; use style::properties::{INITIAL_SERVO_VALUES, TComputedValues, get_writing_mode};
#[test] #[test]
fn initial_writing_mode_is_empty() { 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())
} }
} }