Auto merge of #12515 - servo:concrete-style, r=bholley

Make the style crate more concrete

Background:

The changes to Servo code to support Stylo began in the `selectors` crate with making pseudo-elements generic, defined be the user, so that different users (such as Servo and Gecko/Stylo) could have a different set of pseudo-elements supported and parsed. Adding a trait makes sense there since `selectors` is in its own repository and has others users (or at least [one](https://github.com/SimonSapin/kuchiki)).

Then we kind of kept going with the same pattern and added a bunch of traits in the `style` crate to make everything generic, allowing Servo and Gecko/Stylo to do things differently. But we’ve also added a `gecko` Cargo feature to do conditional compilation, at first to enable or disable some CSS properties and values in the Mako templates. Since we’re doing conditional compilation anyway, it’s often easier and simpler to do it more (with `#[cfg(feature = "gecko")]` and `#[cfg(feature = "servo")]`) that to keep adding traits and making everything generic. When a type is generic, any method that we want to call on it needs to be part of some trait.

----

The first several commits move some code around, mostly from `geckolib` to `style` (with `#[cfg(feature = "gecko")]`) but otherwise don’t change much.

The following commits remove some traits and many type parameters through the `style` crate, replacing them with pairs of conditionally-compiled API-compatible items (types, methods, …).

Simplifying code is nice to make it more maintainable, but this is motivated by another change described in https://github.com/servo/servo/pull/12391#issuecomment-232183942. (Porting Servo for that change proved difficult because some code in the `style` crate was becoming generic over `String` vs `Atom`, and this PR will help make that concrete. That change, in turn, is motivated by removing geckolib’s `[replace]` override for string-cache, in order to enable using a single Cargo "workspace" in this repository.)

r? @bholley

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [x] These changes do not require new tests because refactoring

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/12515)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-07-20 02:58:34 -05:00 committed by GitHub
commit 2d01d41a50
88 changed files with 1199 additions and 1344 deletions

View file

@ -25,7 +25,7 @@ use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use string_cache::Atom; use string_cache::Atom;
use style::computed_values::{font_style, font_variant}; use style::computed_values::{font_style, font_variant};
use style::properties::style_structs::ServoFont; use style::properties::style_structs;
use webrender_traits; use webrender_traits;
#[cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))] #[cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))]
@ -141,7 +141,7 @@ impl FontContext {
/// Create a group of fonts for use in layout calculations. May return /// Create a group of fonts for use in layout calculations. May return
/// a cached font if this font instance has already been used by /// a cached font if this font instance has already been used by
/// this context. /// this context.
pub fn layout_font_group_for_style(&mut self, style: Arc<ServoFont>) pub fn layout_font_group_for_style(&mut self, style: Arc<style_structs::Font>)
-> Rc<FontGroup> { -> Rc<FontGroup> {
self.expire_font_caches_if_necessary(); self.expire_font_caches_if_necessary();
@ -297,7 +297,7 @@ impl HeapSizeOf for FontContext {
#[derive(Debug)] #[derive(Debug)]
struct LayoutFontGroupCacheKey { struct LayoutFontGroupCacheKey {
pointer: Arc<ServoFont>, pointer: Arc<style_structs::Font>,
size: Au, size: Au,
} }

View file

@ -14,16 +14,15 @@ use script_traits::{AnimationState, LayoutMsg as ConstellationMsg};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::mpsc::Receiver; use std::sync::mpsc::Receiver;
use style::animation::{Animation, update_style_for_animation}; use style::animation::{Animation, update_style_for_animation};
use style::selector_impl::{SelectorImplExt, ServoSelectorImpl};
use time; use time;
/// Processes any new animations that were discovered after style recalculation. /// Processes any new animations that were discovered after style recalculation.
/// Also expire any old animations that have completed, inserting them into /// Also expire any old animations that have completed, inserting them into
/// `expired_animations`. /// `expired_animations`.
pub fn update_animation_state<Impl: SelectorImplExt>(constellation_chan: &IpcSender<ConstellationMsg>, pub fn update_animation_state(constellation_chan: &IpcSender<ConstellationMsg>,
running_animations: &mut HashMap<OpaqueNode, Vec<Animation<Impl>>>, running_animations: &mut HashMap<OpaqueNode, Vec<Animation>>,
expired_animations: &mut HashMap<OpaqueNode, Vec<Animation<Impl>>>, expired_animations: &mut HashMap<OpaqueNode, Vec<Animation>>,
new_animations_receiver: &Receiver<Animation<Impl>>, new_animations_receiver: &Receiver<Animation>,
pipeline_id: PipelineId) { pipeline_id: PipelineId) {
let mut new_running_animations = vec![]; let mut new_running_animations = vec![];
while let Ok(animation) = new_animations_receiver.try_recv() { while let Ok(animation) = new_animations_receiver.try_recv() {
@ -125,7 +124,7 @@ pub fn update_animation_state<Impl: SelectorImplExt>(constellation_chan: &IpcSen
pub fn recalc_style_for_animations(context: &SharedLayoutContext, pub fn recalc_style_for_animations(context: &SharedLayoutContext,
flow: &mut Flow, flow: &mut Flow,
animations: &HashMap<OpaqueNode, animations: &HashMap<OpaqueNode,
Vec<Animation<ServoSelectorImpl>>>) { Vec<Animation>>) {
let mut damage = RestyleDamage::empty(); let mut damage = RestyleDamage::empty();
flow.mutate_fragments(&mut |fragment| { flow.mutate_fragments(&mut |fragment| {
if let Some(ref animations) = animations.get(&fragment.node) { if let Some(ref animations) = animations.get(&fragment.node) {

View file

@ -56,10 +56,9 @@ use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::{border_collapse, box_sizing, display, float, overflow_x, overflow_y}; use style::computed_values::{border_collapse, box_sizing, display, float, overflow_x, overflow_y};
use style::computed_values::{position, text_align, transform, transform_style}; use style::computed_values::{position, text_align, transform, transform_style};
use style::context::StyleContext; use style::context::{SharedStyleContext, StyleContext};
use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
use style::properties::{ComputedValues, ServoComputedValues}; use style::properties::ServoComputedValues;
use style::servo::SharedStyleContext;
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

@ -46,8 +46,8 @@ use std::sync::atomic::Ordering;
use style::computed_values::content::ContentItem; use style::computed_values::content::ContentItem;
use style::computed_values::position; use style::computed_values::position;
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::properties::{self, ComputedValues, ServoComputedValues}; use style::context::SharedStyleContext;
use style::servo::SharedStyleContext; use style::properties::{self, ServoComputedValues};
use table::TableFlow; use table::TableFlow;
use table_caption::TableCaptionFlow; use table_caption::TableCaptionFlow;
use table_cell::TableCellFlow; use table_cell::TableCellFlow;

View file

@ -24,14 +24,12 @@ use std::collections::HashMap;
use std::hash::BuildHasherDefault; use std::hash::BuildHasherDefault;
use std::rc::Rc; 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, SharedStyleContext};
use style::selector_impl::ServoSelectorImpl;
use style::servo::SharedStyleContext;
use url::Url; use url::Url;
use util::opts; use util::opts;
struct LocalLayoutContext { struct LocalLayoutContext {
style_context: LocalStyleContext<ServoSelectorImpl>, style_context: LocalStyleContext,
font_context: RefCell<FontContext>, font_context: RefCell<FontContext>,
} }
@ -103,12 +101,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> 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<ServoSelectorImpl> { fn local_context(&self) -> &LocalStyleContext {
&self.cached_local_layout_context.style_context &self.cached_local_layout_context.style_context
} }
} }

View file

@ -4,7 +4,7 @@
use construct::ConstructionResult; use construct::ConstructionResult;
use script_layout_interface::restyle_damage::RestyleDamage; use script_layout_interface::restyle_damage::RestyleDamage;
use style::servo::PrivateStyleData; use style::data::PrivateStyleData;
/// Data that layout associates with a node. /// Data that layout associates with a node.
pub struct PrivateLayoutData { pub struct PrivateLayoutData {

View file

@ -50,8 +50,8 @@ use style::computed_values::{background_repeat, background_size, border_style};
use style::computed_values::{cursor, image_rendering, overflow_x, pointer_events, position}; use style::computed_values::{cursor, image_rendering, overflow_x, pointer_events, 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::ServoBorder; use style::properties::style_structs;
use style::properties::{self, ComputedValues, ServoComputedValues}; use style::properties::{self, ServoComputedValues};
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};
@ -315,7 +315,7 @@ fn handle_overlapping_radii(size: &Size2D<Au>, radii: &BorderRadii<Au>) -> Borde
} }
} }
fn build_border_radius(abs_bounds: &Rect<Au>, border_style: &ServoBorder) -> BorderRadii<Au> { fn build_border_radius(abs_bounds: &Rect<Au>, border_style: &style_structs::Border) -> BorderRadii<Au> {
// TODO(cgaebel): Support border radii even in the case of multiple border widths. // TODO(cgaebel): Support border radii even in the case of multiple border widths.
// This is an extension of supporting elliptical radii. For now, all percentage // This is an extension of supporting elliptical radii. For now, all percentage
// radii will be relative to the width. // radii will be relative to the width.

View file

@ -25,9 +25,9 @@ use script_layout_interface::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW};
use std::cmp::max; use std::cmp::max;
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::flex_direction; use style::computed_values::flex_direction;
use style::context::SharedStyleContext;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::{ComputedValues, ServoComputedValues}; use style::properties::ServoComputedValues;
use style::servo::SharedStyleContext;
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
/// The size of an axis. May be a specified size, a min/max /// The size of an axis. May be a specified size, a min/max

View file

@ -50,10 +50,10 @@ use std::sync::Arc;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::{fmt, mem, raw}; 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::context::SharedStyleContext;
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, ServoComputedValues}; use style::properties::{self, ServoComputedValues};
use style::servo::SharedStyleContext;
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

@ -44,7 +44,7 @@ use style::computed_values::{overflow_wrap, overflow_x, position, text_decoratio
use style::computed_values::{transform_style, vertical_align, white_space, word_break, z_index}; use style::computed_values::{transform_style, vertical_align, 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, ServoComputedValues}; use style::properties::ServoComputedValues;
use style::str::char_is_whitespace; use style::str::char_is_whitespace;
use style::values::computed::LengthOrPercentageOrNone; use style::values::computed::LengthOrPercentageOrNone;
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};

View file

@ -21,7 +21,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, ServoComputedValues}; use style::properties::ServoComputedValues;
use text::TextRunScanner; use text::TextRunScanner;
// Decimal styles per CSS-COUNTER-STYLES § 6.1: // Decimal styles per CSS-COUNTER-STYLES § 6.1:

View file

@ -35,10 +35,9 @@ use std::{fmt, i32, isize, mem};
use style::arc_ptr_eq; use style::arc_ptr_eq;
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::context::StyleContext; use style::context::{SharedStyleContext, StyleContext};
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::properties::{ComputedValues, ServoComputedValues}; use style::properties::ServoComputedValues;
use style::servo::SharedStyleContext;
use style::values::computed::LengthOrPercentage; use style::values::computed::LengthOrPercentage;
use text; use text;
use unicode_bidi; use unicode_bidi;

View file

@ -23,9 +23,9 @@ use inline::InlineMetrics;
use script_layout_interface::restyle_damage::RESOLVE_GENERATED_CONTENT; use script_layout_interface::restyle_damage::RESOLVE_GENERATED_CONTENT;
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::context::SharedStyleContext;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::{ComputedValues, ServoComputedValues}; use style::properties::ServoComputedValues;
use style::servo::SharedStyleContext;
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, ServoComputedValues}; use style::properties::ServoComputedValues;
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,10 +21,9 @@ use gfx_traits::print_tree::PrintTree;
use std::cmp::{min, max}; use std::cmp::{min, max};
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::context::StyleContext; use style::context::{StyleContext, SharedStyleContext};
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::{ComputedValues, ServoComputedValues}; use style::properties::ServoComputedValues;
use style::servo::SharedStyleContext;
use style::values::computed::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use style::values::computed::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
pub struct MulticolFlow { pub struct MulticolFlow {

View file

@ -31,11 +31,10 @@ 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::ComputedValues;
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;
use style::servo::Stylist; use style::selector_matching::Stylist;
use style::values::LocalToCss; use style::values::LocalToCss;
use style_traits::cursor::Cursor; use style_traits::cursor::Cursor;
use wrapper::ThreadSafeLayoutNodeHelpers; use wrapper::ThreadSafeLayoutNodeHelpers;
@ -450,7 +449,7 @@ impl ParentOffsetBorderBoxIterator {
impl FragmentBorderBoxIterator for FragmentLocatingFragmentIterator { impl FragmentBorderBoxIterator for FragmentLocatingFragmentIterator {
fn process(&mut self, fragment: &Fragment, _: i32, border_box: &Rect<Au>) { fn process(&mut self, fragment: &Fragment, _: i32, border_box: &Rect<Au>) {
let style_structs::ServoBorder { let style_structs::Border {
border_top_width: top_width, border_top_width: top_width,
border_right_width: right_width, border_right_width: right_width,
border_bottom_width: bottom_width, border_bottom_width: bottom_width,
@ -476,7 +475,7 @@ impl FragmentBorderBoxIterator for UnioningFragmentScrollAreaIterator {
// increase in size. To work around this, we store the original elements padding // increase in size. To work around this, we store the original elements padding
// rectangle as `origin_rect` and the union of all child elements padding and // rectangle as `origin_rect` and the union of all child elements padding and
// margin rectangles as `union_rect`. // margin rectangles as `union_rect`.
let style_structs::ServoBorder { let style_structs::Border {
border_top_width: top_border, border_top_width: top_border,
border_right_width: right_border, border_right_width: right_border,
border_bottom_width: bottom_border, border_bottom_width: bottom_border,

View file

@ -26,9 +26,9 @@ use std::cmp;
use std::fmt; 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::context::SharedStyleContext;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::{ComputedValues, ServoComputedValues}; use style::properties::ServoComputedValues;
use style::servo::SharedStyleContext;
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

@ -18,9 +18,9 @@ use gfx_traits::StackingContextId;
use gfx_traits::print_tree::PrintTree; use gfx_traits::print_tree::PrintTree;
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::context::SharedStyleContext;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ServoComputedValues; use style::properties::ServoComputedValues;
use style::servo::SharedStyleContext;
/// A table formatting context. /// A table formatting context.
pub struct TableCaptionFlow { pub struct TableCaptionFlow {

View file

@ -24,9 +24,9 @@ use script_layout_interface::wrapper_traits::ThreadSafeLayoutNode;
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::{border_collapse, border_top_style, vertical_align}; use style::computed_values::{border_collapse, border_top_style, vertical_align};
use style::context::SharedStyleContext;
use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode}; use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode};
use style::properties::{ComputedValues, ServoComputedValues}; use style::properties::ServoComputedValues;
use style::servo::SharedStyleContext;
use table::InternalTable; use table::InternalTable;
use table_row::{CollapsedBorder, CollapsedBorderProvenance}; use table_row::{CollapsedBorder, CollapsedBorderProvenance};

View file

@ -18,9 +18,9 @@ use layout_debug;
use std::cmp::max; use std::cmp::max;
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::context::SharedStyleContext;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ServoComputedValues; use style::properties::ServoComputedValues;
use style::servo::SharedStyleContext;
use style::values::computed::LengthOrPercentageOrAuto; use style::values::computed::LengthOrPercentageOrAuto;
/// A table formatting context. /// A table formatting context.

View file

@ -26,9 +26,9 @@ use std::fmt;
use std::iter::{Enumerate, IntoIterator, Peekable}; 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::context::SharedStyleContext;
use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode}; use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode};
use style::properties::{ComputedValues, ServoComputedValues}; use style::properties::ServoComputedValues;
use style::servo::SharedStyleContext;
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

@ -22,9 +22,9 @@ use std::fmt;
use std::iter::{IntoIterator, Iterator, Peekable}; 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::context::SharedStyleContext;
use style::logical_geometry::{LogicalSize, WritingMode}; use style::logical_geometry::{LogicalSize, WritingMode};
use style::properties::{ComputedValues, ServoComputedValues}; use style::properties::ServoComputedValues;
use style::servo::SharedStyleContext;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, TableLikeFlow}; use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, TableLikeFlow};
use table_row; use table_row;

View file

@ -31,9 +31,9 @@ use std::fmt;
use std::ops::Add; 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::context::SharedStyleContext;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::{ComputedValues, ServoComputedValues}; use style::properties::ServoComputedValues;
use style::servo::SharedStyleContext;
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

@ -25,8 +25,8 @@ use std::sync::Arc;
use style::computed_values::white_space; use style::computed_values::white_space;
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::logical_geometry::{LogicalSize, WritingMode}; use style::logical_geometry::{LogicalSize, WritingMode};
use style::properties::style_structs::ServoFont; use style::properties::ServoComputedValues;
use style::properties::{ComputedValues, ServoComputedValues}; use style::properties::style_structs;
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};
@ -431,11 +431,11 @@ fn bounding_box_for_run_metrics(metrics: &RunMetrics, writing_mode: WritingMode)
} }
/// Returns the metrics of the font represented by the given `ServoFont`, respectively. /// Returns the metrics of the font represented by the given `style_structs::Font`, respectively.
/// ///
/// `#[inline]` because often the caller only needs a few fields from the font metrics. /// `#[inline]` because often the caller only needs a few fields from the font metrics.
#[inline] #[inline]
pub fn font_metrics_for_style(font_context: &mut FontContext, font_style: Arc<ServoFont>) pub fn font_metrics_for_style(font_context: &mut FontContext, font_style: Arc<style_structs::Font>)
-> FontMetrics { -> FontMetrics {
let fontgroup = font_context.layout_font_group_for_style(font_style); let fontgroup = font_context.layout_font_group_for_style(font_style);
// FIXME(https://github.com/rust-lang/rust/issues/23338) // FIXME(https://github.com/rust-lang/rust/issues/23338)

View file

@ -13,10 +13,9 @@ use gfx::display_list::OpaqueNode;
use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage}; use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage};
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode}; use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
use std::mem; use std::mem;
use style::context::SharedStyleContext;
use style::dom::TNode; use style::dom::TNode;
use style::properties::ServoComputedValues;
use style::selector_impl::ServoSelectorImpl; use style::selector_impl::ServoSelectorImpl;
use style::servo::SharedStyleContext;
use style::traversal::{DomTraversalContext, remove_from_bloom_filter, recalc_style_at}; use style::traversal::{DomTraversalContext, remove_from_bloom_filter, recalc_style_at};
use util::opts; use util::opts;
use wrapper::{LayoutNodeLayoutData, ThreadSafeLayoutNodeHelpers}; use wrapper::{LayoutNodeLayoutData, ThreadSafeLayoutNodeHelpers};
@ -27,7 +26,7 @@ pub struct RecalcStyleAndConstructFlows<'lc> {
} }
impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc> impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc>
where N: LayoutNode + TNode<ConcreteComputedValues=ServoComputedValues>, where N: LayoutNode + TNode,
N::ConcreteElement: ::selectors::Element<Impl=ServoSelectorImpl, AttrString=String> N::ConcreteElement: ::selectors::Element<Impl=ServoSelectorImpl, AttrString=String>
{ {

View file

@ -35,7 +35,6 @@ use data::{LayoutDataFlags, PrivateLayoutData};
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode}; use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData}; use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData};
use style::computed_values::content::{self, ContentItem}; use style::computed_values::content::{self, ContentItem};
use style::properties::ComputedValues;
use style::refcell::{Ref, RefCell, RefMut}; use style::refcell::{Ref, RefCell, RefMut};
pub type NonOpaqueStyleAndLayoutData = *mut RefCell<PrivateLayoutData>; pub type NonOpaqueStyleAndLayoutData = *mut RefCell<PrivateLayoutData>;

View file

@ -98,18 +98,18 @@ use std::ops::{Deref, DerefMut};
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::{channel, Sender, Receiver}; use std::sync::mpsc::{channel, Sender, Receiver};
use std::sync::{Arc, Mutex, MutexGuard, RwLock}; use std::sync::{Arc, Mutex, MutexGuard, RwLock};
use style::animation::Animation;
use style::computed_values::{filter, mix_blend_mode}; use style::computed_values::{filter, mix_blend_mode};
use style::context::ReflowGoal; use style::context::{ReflowGoal, LocalStyleContextCreationInfo, SharedStyleContext};
use style::dom::{TDocument, TElement, TNode}; use style::dom::{TDocument, TElement, TNode};
use style::error_reporting::ParseErrorReporter; 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::ComputedValues;
use style::refcell::RefCell; use style::refcell::RefCell;
use style::selector_matching::USER_OR_USER_AGENT_STYLESHEETS; use style::selector_matching::Stylist;
use style::servo::{Animation, LocalStyleContextCreationInfo, SharedStyleContext, Stylesheet, Stylist}; use style::servo_selector_impl::USER_OR_USER_AGENT_STYLESHEETS;
use style::stylesheets::CSSRuleIteratorExt; use style::stylesheets::{Stylesheet, CSSRuleIteratorExt};
use style::workqueue::WorkQueue; use style::workqueue::WorkQueue;
use url::Url; use url::Url;
use util::geometry::MAX_RECT; use util::geometry::MAX_RECT;

View file

@ -123,8 +123,8 @@ use string_cache::{Atom, QualName};
use style::attr::AttrValue; use style::attr::AttrValue;
use style::context::ReflowGoal; use style::context::ReflowGoal;
use style::restyle_hints::ElementSnapshot; use style::restyle_hints::ElementSnapshot;
use style::servo::Stylesheet;
use style::str::{split_html_space_chars, str_join}; use style::str::{split_html_space_chars, str_join};
use style::stylesheets::Stylesheet;
use time; use time;
use url::Url; use url::Url;
use url::percent_encoding::percent_decode; use url::percent_encoding::percent_decode;

View file

@ -39,9 +39,8 @@ use string_cache::Atom;
use style::attr::AttrValue; use style::attr::AttrValue;
use style::media_queries::{MediaQueryList, parse_media_query_list}; use style::media_queries::{MediaQueryList, parse_media_query_list};
use style::parser::ParserContextExtraData; use style::parser::ParserContextExtraData;
use style::servo::Stylesheet;
use style::str::HTML_SPACE_CHARACTERS; use style::str::HTML_SPACE_CHARACTERS;
use style::stylesheets::Origin; use style::stylesheets::{Stylesheet, Origin};
use url::Url; use url::Url;
no_jsmanaged_fields!(Stylesheet); no_jsmanaged_fields!(Stylesheet);

View file

@ -20,9 +20,8 @@ use std::ascii::AsciiExt;
use std::sync::Arc; use std::sync::Arc;
use string_cache::Atom; use string_cache::Atom;
use style::attr::AttrValue; use style::attr::AttrValue;
use style::servo::Stylesheet;
use style::str::HTML_SPACE_CHARACTERS; use style::str::HTML_SPACE_CHARACTERS;
use style::stylesheets::{CSSRule, Origin}; use style::stylesheets::{Stylesheet, CSSRule, Origin};
use style::viewport::ViewportRule; use style::viewport::ViewportRule;
#[dom_struct] #[dom_struct]

View file

@ -19,8 +19,7 @@ use std::sync::Arc;
use string_cache::Atom; use string_cache::Atom;
use style::media_queries::parse_media_query_list; use style::media_queries::parse_media_query_list;
use style::parser::ParserContextExtraData; use style::parser::ParserContextExtraData;
use style::servo::Stylesheet; use style::stylesheets::{Stylesheet, Origin};
use style::stylesheets::Origin;
#[dom_struct] #[dom_struct]
pub struct HTMLStyleElement { pub struct HTMLStyleElement {

View file

@ -54,14 +54,14 @@ use std::mem::{transmute, transmute_copy};
use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace}; use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace};
use style::attr::AttrValue; use style::attr::AttrValue;
use style::computed_values::display; use style::computed_values::display;
use style::context::SharedStyleContext;
use style::data::PrivateStyleData;
use style::dom::{PresentationalHintsSynthetizer, OpaqueNode, TDocument, TElement, TNode, UnsafeNode}; use style::dom::{PresentationalHintsSynthetizer, OpaqueNode, TDocument, TElement, TNode, UnsafeNode};
use style::element_state::*; use style::element_state::*;
use style::properties::{ComputedValues, ServoComputedValues};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
use style::refcell::{Ref, RefCell, RefMut}; use style::refcell::{Ref, RefCell, RefMut};
use style::restyle_hints::ElementSnapshot; use style::restyle_hints::ElementSnapshot;
use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl};
use style::servo::{PrivateStyleData, SharedStyleContext};
use style::sink::Push; use style::sink::Push;
use style::str::is_whitespace; use style::str::is_whitespace;
use url::Url; use url::Url;
@ -110,7 +110,6 @@ impl<'ln> ServoLayoutNode<'ln> {
} }
impl<'ln> TNode for ServoLayoutNode<'ln> { impl<'ln> TNode for ServoLayoutNode<'ln> {
type ConcreteComputedValues = ServoComputedValues;
type ConcreteElement = ServoLayoutElement<'ln>; type ConcreteElement = ServoLayoutElement<'ln>;
type ConcreteDocument = ServoLayoutDocument<'ln>; type ConcreteDocument = ServoLayoutDocument<'ln>;
type ConcreteRestyleDamage = RestyleDamage; type ConcreteRestyleDamage = RestyleDamage;

View file

@ -52,8 +52,8 @@ use core::nonzero::NonZero;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use libc::c_void; use libc::c_void;
use restyle_damage::RestyleDamage; use restyle_damage::RestyleDamage;
use style::data::PrivateStyleData;
use style::refcell::RefCell; use style::refcell::RefCell;
use style::servo::PrivateStyleData;
pub struct PartialStyleAndLayoutData { pub struct PartialStyleAndLayoutData {
pub style_data: PrivateStyleData, pub style_data: PrivateStyleData,

View file

@ -18,7 +18,7 @@ use std::sync::mpsc::{Receiver, Sender};
use string_cache::Atom; use string_cache::Atom;
use style::context::ReflowGoal; use style::context::ReflowGoal;
use style::selector_impl::PseudoElement; use style::selector_impl::PseudoElement;
use style::servo::Stylesheet; use style::stylesheets::Stylesheet;
use url::Url; use url::Url;
use util::ipc::OptionalOpaqueIpcSender; use util::ipc::OptionalOpaqueIpcSender;
use {OpaqueStyleAndLayoutData, TrustedNodeAddress}; use {OpaqueStyleAndLayoutData, TrustedNodeAddress};

View file

@ -6,7 +6,7 @@ use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use style::computed_values::display; use style::computed_values::display;
use style::dom::TRestyleDamage; use style::dom::TRestyleDamage;
use style::properties::{ComputedValues, ServoComputedValues}; use style::properties::ServoComputedValues;
bitflags! { bitflags! {
#[doc = "Individual layout actions that may be necessary after restyling."] #[doc = "Individual layout actions that may be necessary after restyling."]
@ -44,7 +44,6 @@ bitflags! {
} }
impl TRestyleDamage for RestyleDamage { impl TRestyleDamage for RestyleDamage {
type ConcreteComputedValues = ServoComputedValues;
fn compute(old: Option<&Arc<ServoComputedValues>>, new: &ServoComputedValues) -> fn compute(old: Option<&Arc<ServoComputedValues>>, new: &ServoComputedValues) ->
RestyleDamage { compute_damage(old, new) } RestyleDamage { compute_damage(old, new) }

View file

@ -13,12 +13,12 @@ use restyle_damage::RestyleDamage;
use std::sync::Arc; use std::sync::Arc;
use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace}; use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace};
use style::computed_values::display; use style::computed_values::display;
use style::context::SharedStyleContext;
use style::dom::OpaqueNode; use style::dom::OpaqueNode;
use style::dom::{PresentationalHintsSynthetizer, TNode}; use style::dom::{PresentationalHintsSynthetizer, TNode};
use style::properties::ServoComputedValues; use style::properties::ServoComputedValues;
use style::refcell::{Ref, RefCell}; use style::refcell::{Ref, RefCell};
use style::selector_impl::{PseudoElement, PseudoElementCascadeType, ServoSelectorImpl}; use style::selector_impl::{PseudoElement, PseudoElementCascadeType, ServoSelectorImpl};
use style::servo::SharedStyleContext;
use url::Url; use url::Url;
#[derive(Copy, PartialEq, Clone)] #[derive(Copy, PartialEq, Clone)]

View file

@ -15,9 +15,7 @@ use properties::longhands::animation_iteration_count::computed_value::AnimationI
use properties::longhands::animation_play_state::computed_value::AnimationPlayState; use properties::longhands::animation_play_state::computed_value::AnimationPlayState;
use properties::longhands::transition_timing_function::computed_value::StartEnd; use properties::longhands::transition_timing_function::computed_value::StartEnd;
use properties::longhands::transition_timing_function::computed_value::TransitionTimingFunction; use properties::longhands::transition_timing_function::computed_value::TransitionTimingFunction;
use properties::style_struct_traits::Box;
use properties::{self, ComputedValues}; use properties::{self, ComputedValues};
use selector_impl::SelectorImplExt;
use selectors::matching::DeclarationBlock; use selectors::matching::DeclarationBlock;
use std::sync::Arc; use std::sync::Arc;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
@ -53,7 +51,7 @@ pub enum KeyframesRunningState {
/// playing or paused). /// playing or paused).
// TODO: unify the use of f32/f64 in this file. // TODO: unify the use of f32/f64 in this file.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct KeyframesAnimationState<Impl: SelectorImplExt> { pub struct KeyframesAnimationState {
/// The time this animation started at. /// The time this animation started at.
pub started_at: f64, pub started_at: f64,
/// The duration of this animation. /// The duration of this animation.
@ -72,10 +70,10 @@ pub struct KeyframesAnimationState<Impl: SelectorImplExt> {
pub expired: bool, pub expired: bool,
/// The original cascade style, needed to compute the generated keyframes of /// The original cascade style, needed to compute the generated keyframes of
/// the animation. /// the animation.
pub cascade_style: Arc<Impl::ComputedValues>, pub cascade_style: Arc<ComputedValues>,
} }
impl<Impl: SelectorImplExt> KeyframesAnimationState<Impl> { impl KeyframesAnimationState {
/// Performs a tick in the animation state, i.e., increments the counter of /// Performs a tick in the animation state, i.e., increments the counter of
/// the current iteration count, updates times and then toggles the /// the current iteration count, updates times and then toggles the
/// direction if appropriate. /// direction if appropriate.
@ -180,7 +178,7 @@ impl<Impl: SelectorImplExt> KeyframesAnimationState<Impl> {
/// State relating to an animation. /// State relating to an animation.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Animation<Impl: SelectorImplExt> { pub enum Animation {
/// A transition is just a single frame triggered at a time, with a reflow. /// A transition is just a single frame triggered at a time, with a reflow.
/// ///
/// the f64 field is the start time as returned by `time::precise_time_s()`. /// the f64 field is the start time as returned by `time::precise_time_s()`.
@ -189,10 +187,10 @@ pub enum Animation<Impl: SelectorImplExt> {
Transition(OpaqueNode, f64, AnimationFrame, bool), Transition(OpaqueNode, f64, AnimationFrame, bool),
/// A keyframes animation is identified by a name, and can have a /// A keyframes animation is identified by a name, and can have a
/// node-dependent state (i.e. iteration count, etc.). /// node-dependent state (i.e. iteration count, etc.).
Keyframes(OpaqueNode, Atom, KeyframesAnimationState<Impl>), Keyframes(OpaqueNode, Atom, KeyframesAnimationState),
} }
impl<Impl: SelectorImplExt> Animation<Impl> { impl Animation {
#[inline] #[inline]
pub fn mark_as_expired(&mut self) { pub fn mark_as_expired(&mut self) {
debug_assert!(!self.is_expired()); debug_assert!(!self.is_expired());
@ -249,9 +247,9 @@ impl PropertyAnimation {
/// Creates a new property animation for the given transition index and old and new styles. /// Creates a new property animation for the given transition index and old and new styles.
/// Any number of animations may be returned, from zero (if the property did not animate) to /// Any number of animations may be returned, from zero (if the property did not animate) to
/// one (for a single transition property) to arbitrarily many (for `all`). /// one (for a single transition property) to arbitrarily many (for `all`).
pub fn from_transition<C: ComputedValues>(transition_index: usize, pub fn from_transition(transition_index: usize,
old_style: &C, old_style: &ComputedValues,
new_style: &mut C) new_style: &mut ComputedValues)
-> Vec<PropertyAnimation> { -> Vec<PropertyAnimation> {
let mut result = vec![]; let mut result = vec![];
let box_style = new_style.get_box(); let box_style = new_style.get_box();
@ -286,11 +284,11 @@ impl PropertyAnimation {
result result
} }
fn from_transition_property<C: ComputedValues>(transition_property: TransitionProperty, fn from_transition_property(transition_property: TransitionProperty,
timing_function: TransitionTimingFunction, timing_function: TransitionTimingFunction,
duration: Time, duration: Time,
old_style: &C, old_style: &ComputedValues,
new_style: &C) new_style: &ComputedValues)
-> Option<PropertyAnimation> { -> Option<PropertyAnimation> {
let animated_property = AnimatedProperty::from_transition_property(&transition_property, let animated_property = AnimatedProperty::from_transition_property(&transition_property,
old_style, old_style,
@ -309,7 +307,7 @@ impl PropertyAnimation {
} }
} }
pub fn update<C: ComputedValues>(&self, style: &mut C, time: f64) { pub fn update(&self, style: &mut ComputedValues, time: f64) {
let progress = match self.timing_function { let progress = match self.timing_function {
TransitionTimingFunction::CubicBezier(p1, p2) => { TransitionTimingFunction::CubicBezier(p1, p2) => {
// See `WebCore::AnimationBase::solveEpsilon(double)` in WebKit. // See `WebCore::AnimationBase::solveEpsilon(double)` in WebKit.
@ -340,10 +338,10 @@ impl PropertyAnimation {
// //
// TODO(emilio): Take rid of this mutex splitting SharedLayoutContex into a // TODO(emilio): Take rid of this mutex splitting SharedLayoutContex into a
// cloneable part and a non-cloneable part.. // cloneable part and a non-cloneable part..
pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sender: &Sender<Animation<Impl>>, pub fn start_transitions_if_applicable(new_animations_sender: &Sender<Animation>,
node: OpaqueNode, node: OpaqueNode,
old_style: &Impl::ComputedValues, old_style: &ComputedValues,
new_style: &mut Arc<Impl::ComputedValues>) new_style: &mut Arc<ComputedValues>)
-> bool { -> bool {
let mut had_animations = false; let mut had_animations = false;
for i in 0..new_style.get_box().transition_property_count() { for i in 0..new_style.get_box().transition_property_count() {
@ -373,11 +371,11 @@ pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sen
had_animations had_animations
} }
fn compute_style_for_animation_step<Impl: SelectorImplExt>(context: &SharedStyleContext<Impl>, fn compute_style_for_animation_step(context: &SharedStyleContext,
step: &KeyframesStep, step: &KeyframesStep,
previous_style: &Impl::ComputedValues, previous_style: &ComputedValues,
style_from_cascade: &Impl::ComputedValues) style_from_cascade: &ComputedValues)
-> Impl::ComputedValues { -> ComputedValues {
match step.value { match step.value {
// TODO: avoiding this spurious clone might involve having to create // TODO: avoiding this spurious clone might involve having to create
// an Arc in the below (more common case). // an Arc in the below (more common case).
@ -399,11 +397,11 @@ fn compute_style_for_animation_step<Impl: SelectorImplExt>(context: &SharedStyle
} }
} }
pub fn maybe_start_animations<Impl: SelectorImplExt>(context: &SharedStyleContext<Impl>, pub fn maybe_start_animations(context: &SharedStyleContext,
new_animations_sender: &Sender<Animation<Impl>>, new_animations_sender: &Sender<Animation>,
node: OpaqueNode, node: OpaqueNode,
new_style: &Arc<Impl::ComputedValues>) -> bool new_style: &Arc<ComputedValues>)
{ -> bool {
let mut had_animations = false; let mut had_animations = false;
let box_style = new_style.get_box(); let box_style = new_style.get_box();
@ -470,7 +468,7 @@ pub fn maybe_start_animations<Impl: SelectorImplExt>(context: &SharedStyleContex
/// Updates a given computed style for a given animation frame. Returns a bool /// Updates a given computed style for a given animation frame. Returns a bool
/// representing if the style was indeed updated. /// representing if the style was indeed updated.
pub fn update_style_for_animation_frame<C: ComputedValues>(mut new_style: &mut Arc<C>, pub fn update_style_for_animation_frame(mut new_style: &mut Arc<ComputedValues>,
now: f64, now: f64,
start_time: f64, start_time: f64,
frame: &AnimationFrame) -> bool { frame: &AnimationFrame) -> bool {
@ -489,12 +487,11 @@ pub fn update_style_for_animation_frame<C: ComputedValues>(mut new_style: &mut A
} }
/// Updates a single animation and associated style based on the current time. /// Updates a single animation and associated style based on the current time.
/// If `damage` is provided, inserts the appropriate restyle damage. /// If `damage` is provided, inserts the appropriate restyle damage.
pub fn update_style_for_animation<Damage, Impl>(context: &SharedStyleContext<Impl>, pub fn update_style_for_animation<Damage>(context: &SharedStyleContext,
animation: &Animation<Impl>, animation: &Animation,
style: &mut Arc<Damage::ConcreteComputedValues>, style: &mut Arc<ComputedValues>,
damage: Option<&mut Damage>) damage: Option<&mut Damage>)
where Impl: SelectorImplExt, where Damage: TRestyleDamage {
Damage: TRestyleDamage<ConcreteComputedValues = Impl::ComputedValues> {
debug!("update_style_for_animation: entering"); debug!("update_style_for_animation: entering");
debug_assert!(!animation.is_expired()); debug_assert!(!animation.is_expired());
match *animation { match *animation {

View file

@ -10,7 +10,6 @@ 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 selector_impl::SelectorImplExt;
use selector_matching::Stylist; use selector_matching::Stylist;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
@ -18,19 +17,19 @@ use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
/// This structure is used to create a local style context from a shared one. /// This structure is used to create a local style context from a shared one.
pub struct LocalStyleContextCreationInfo<Impl: SelectorImplExt> { pub struct LocalStyleContextCreationInfo {
new_animations_sender: Sender<Animation<Impl>>, new_animations_sender: Sender<Animation>,
} }
impl<Impl: SelectorImplExt> LocalStyleContextCreationInfo<Impl> { impl LocalStyleContextCreationInfo {
pub fn new(animations_sender: Sender<Animation<Impl>>) -> Self { pub fn new(animations_sender: Sender<Animation>) -> Self {
LocalStyleContextCreationInfo { LocalStyleContextCreationInfo {
new_animations_sender: animations_sender, new_animations_sender: animations_sender,
} }
} }
} }
pub struct SharedStyleContext<Impl: SelectorImplExt> { pub struct SharedStyleContext {
/// The current viewport size. /// The current viewport size.
pub viewport_size: Size2D<Au>, pub viewport_size: Size2D<Au>,
@ -38,7 +37,7 @@ pub struct SharedStyleContext<Impl: SelectorImplExt> {
pub screen_size_changed: bool, pub screen_size_changed: bool,
/// The CSS selector stylist. /// The CSS selector stylist.
pub stylist: Arc<Stylist<Impl>>, pub stylist: Arc<Stylist>,
/// Starts at zero, and increased by one every time a layout completes. /// Starts at zero, and increased by one every time a layout completes.
/// This can be used to easily check for invalid stale data. /// This can be used to easily check for invalid stale data.
@ -48,28 +47,28 @@ pub struct SharedStyleContext<Impl: SelectorImplExt> {
pub goal: ReflowGoal, pub goal: ReflowGoal,
/// The animations that are currently running. /// The animations that are currently running.
pub running_animations: Arc<RwLock<HashMap<OpaqueNode, Vec<Animation<Impl>>>>>, pub running_animations: Arc<RwLock<HashMap<OpaqueNode, Vec<Animation>>>>,
/// The list of animations that have expired since the last style recalculation. /// The list of animations that have expired since the last style recalculation.
pub expired_animations: Arc<RwLock<HashMap<OpaqueNode, Vec<Animation<Impl>>>>>, pub expired_animations: Arc<RwLock<HashMap<OpaqueNode, Vec<Animation>>>>,
///The CSS error reporter for all CSS loaded in this layout thread ///The CSS error reporter for all CSS loaded in this layout thread
pub error_reporter: Box<ParseErrorReporter + Sync>, pub error_reporter: Box<ParseErrorReporter + Sync>,
/// Data needed to create the local style context from the shared one. /// Data needed to create the local style context from the shared one.
pub local_context_creation_data: Mutex<LocalStyleContextCreationInfo<Impl>>, pub local_context_creation_data: Mutex<LocalStyleContextCreationInfo>,
} }
pub struct LocalStyleContext<Impl: SelectorImplExt> { pub struct LocalStyleContext {
pub applicable_declarations_cache: RefCell<ApplicableDeclarationsCache<Impl::ComputedValues>>, pub applicable_declarations_cache: RefCell<ApplicableDeclarationsCache>,
pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache<Impl::ComputedValues>>, pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache>,
/// A channel on which new animations that have been triggered by style /// A channel on which new animations that have been triggered by style
/// recalculation can be sent. /// recalculation can be sent.
pub new_animations_sender: Sender<Animation<Impl>>, pub new_animations_sender: Sender<Animation>,
} }
impl<Impl: SelectorImplExt> LocalStyleContext<Impl> { impl LocalStyleContext {
pub fn new(local_context_creation_data: &LocalStyleContextCreationInfo<Impl>) -> Self { pub fn new(local_context_creation_data: &LocalStyleContextCreationInfo) -> Self {
LocalStyleContext { LocalStyleContext {
applicable_declarations_cache: RefCell::new(ApplicableDeclarationsCache::new()), applicable_declarations_cache: RefCell::new(ApplicableDeclarationsCache::new()),
style_sharing_candidate_cache: RefCell::new(StyleSharingCandidateCache::new()), style_sharing_candidate_cache: RefCell::new(StyleSharingCandidateCache::new()),
@ -78,9 +77,9 @@ impl<Impl: SelectorImplExt> LocalStyleContext<Impl> {
} }
} }
pub trait StyleContext<'a, Impl: SelectorImplExt> { pub trait StyleContext<'a> {
fn shared_context(&self) -> &'a SharedStyleContext<Impl>; fn shared_context(&self) -> &'a SharedStyleContext;
fn local_context(&self) -> &LocalStyleContext<Impl>; fn local_context(&self) -> &LocalStyleContext;
} }
/// Why we're doing reflow. /// Why we're doing reflow.

View file

@ -5,27 +5,26 @@
//! Per-node data used in style calculation. //! Per-node data used in style calculation.
use properties::ComputedValues; use properties::ComputedValues;
use selectors::parser::SelectorImpl; use selector_impl::PseudoElement;
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, ConcreteComputedValues: ComputedValues> { pub struct PrivateStyleData {
/// The results of CSS styling for this node. /// The results of CSS styling for this node.
pub style: Option<Arc<ConcreteComputedValues>>, pub style: Option<Arc<ComputedValues>>,
/// 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<ConcreteComputedValues>, pub per_pseudo: HashMap<PseudoElement, Arc<ComputedValues>,
BuildHasherDefault<::fnv::FnvHasher>>, BuildHasherDefault<::fnv::FnvHasher>>,
/// Information needed during parallel traversals. /// Information needed during parallel traversals.
pub parallel: DomParallelInfo, pub parallel: DomParallelInfo,
} }
impl<Impl, ConcreteComputedValues> PrivateStyleData<Impl, ConcreteComputedValues> impl PrivateStyleData {
where Impl: SelectorImpl, ConcreteComputedValues: ComputedValues { pub fn new() -> Self {
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

@ -46,16 +46,14 @@ impl OpaqueNode {
} }
pub trait TRestyleDamage : BitOr<Output=Self> + Copy { pub trait TRestyleDamage : BitOr<Output=Self> + Copy {
type ConcreteComputedValues: ComputedValues; fn compute(old: Option<&Arc<ComputedValues>>, new: &ComputedValues) -> Self;
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<ConcreteComputedValues = Self::ConcreteComputedValues>; type ConcreteRestyleDamage: TRestyleDamage;
type ConcreteComputedValues: ComputedValues;
fn to_unsafe(&self) -> UnsafeNode; fn to_unsafe(&self) -> UnsafeNode;
unsafe fn from_unsafe(n: &UnsafeNode) -> Self; unsafe fn from_unsafe(n: &UnsafeNode) -> Self;
@ -146,21 +144,15 @@ 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>;
-> 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>>;
-> 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>>;
-> 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;
@ -181,10 +173,8 @@ 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, fn style(&self, _context: &SharedStyleContext) -> Ref<Arc<ComputedValues>>
_context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>) where <Self::ConcreteElement as Element>::Impl: SelectorImplExt {
-> Ref<Arc<Self::ConcreteComputedValues>>
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt<ComputedValues=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

@ -0,0 +1,57 @@
/* 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/. */
#![allow(unsafe_code)]
use std::marker::PhantomData;
use std::mem::{forget, transmute};
use std::sync::Arc;
pub struct ArcHelpers<GeckoType, ServoType> {
phantom1: PhantomData<GeckoType>,
phantom2: PhantomData<ServoType>,
}
impl<GeckoType, ServoType> ArcHelpers<GeckoType, ServoType> {
pub fn with<F, Output>(raw: *mut GeckoType, cb: F) -> Output
where F: FnOnce(&Arc<ServoType>) -> Output {
debug_assert!(!raw.is_null());
let owned = unsafe { Self::into(raw) };
let result = cb(&owned);
forget(owned);
result
}
pub fn maybe_with<F, Output>(maybe_raw: *mut GeckoType, cb: F) -> Output
where F: FnOnce(Option<&Arc<ServoType>>) -> Output {
let owned = if maybe_raw.is_null() {
None
} else {
Some(unsafe { Self::into(maybe_raw) })
};
let result = cb(owned.as_ref());
forget(owned);
result
}
pub unsafe fn into(ptr: *mut GeckoType) -> Arc<ServoType> {
transmute(ptr)
}
pub fn from(owned: Arc<ServoType>) -> *mut GeckoType {
unsafe { transmute(owned) }
}
pub unsafe fn addref(ptr: *mut GeckoType) {
Self::with(ptr, |arc| forget(arc.clone()));
}
pub unsafe fn release(ptr: *mut GeckoType) {
let _ = Self::into(ptr);
}
}

View file

@ -2,20 +2,13 @@
* 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 element_state::ElementState;
use selector_impl::{PseudoElementCascadeType, SelectorImplExt};
use selectors::parser::{ParserContext, SelectorImpl}; use selectors::parser::{ParserContext, SelectorImpl};
use string_cache::Atom; use string_cache::Atom;
use style; use stylesheets::Stylesheet;
use style::element_state::ElementState;
use style::selector_impl::{PseudoElementCascadeType, SelectorImplExt};
pub type Stylist = style::selector_matching::Stylist<GeckoSelectorImpl>; #[derive(Debug, Clone, PartialEq, Eq)]
pub type Stylesheet = style::stylesheets::Stylesheet<GeckoSelectorImpl>;
pub type SharedStyleContext = style::context::SharedStyleContext<GeckoSelectorImpl>;
pub type PrivateStyleData = style::data::PrivateStyleData<GeckoSelectorImpl, GeckoComputedValues>;
pub type Animation = style::animation::Animation<GeckoSelectorImpl>;
#[derive(Debug, Clone)]
pub struct GeckoSelectorImpl; pub struct GeckoSelectorImpl;
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@ -135,8 +128,8 @@ pub enum NonTSPseudoClass {
impl NonTSPseudoClass { impl NonTSPseudoClass {
pub fn state_flag(&self) -> ElementState { pub fn state_flag(&self) -> ElementState {
use element_state::*;
use self::NonTSPseudoClass::*; use self::NonTSPseudoClass::*;
use style::element_state::*;
match *self { match *self {
Active => IN_ACTIVE_STATE, Active => IN_ACTIVE_STATE,
Focus => IN_FOCUS_STATE, Focus => IN_FOCUS_STATE,
@ -292,8 +285,6 @@ impl SelectorImpl for GeckoSelectorImpl {
} }
impl SelectorImplExt for GeckoSelectorImpl { impl SelectorImplExt for GeckoSelectorImpl {
type ComputedValues = GeckoComputedValues;
#[inline] #[inline]
fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType { fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType {
match *pseudo { match *pseudo {

View file

@ -2,12 +2,14 @@
* 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/. */
#![allow(unsafe_code)]
use app_units::Au; use app_units::Au;
use cssparser::RGBA; use cssparser::RGBA;
use gecko_bindings::structs::{nsStyleCoord, nsStyleUnion, nsStyleUnit}; use gecko_bindings::structs::{nsStyleCoord, nsStyleUnion, nsStyleUnit};
use std::cmp::max; use std::cmp::max;
use style::values::computed::Angle; use values::computed::Angle;
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
pub trait StyleCoordHelpers { pub trait StyleCoordHelpers {
fn copy_from(&mut self, other: &Self); fn copy_from(&mut self, other: &Self);

View file

@ -81,8 +81,10 @@ pub mod dom;
pub mod element_state; pub mod element_state;
pub mod error_reporting; pub mod error_reporting;
pub mod font_face; pub mod font_face;
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")] pub mod gecko_conversions;
pub mod gecko_conversions; #[cfg(feature = "gecko")] pub mod gecko_glue;
#[cfg(feature = "gecko")] pub mod gecko_selector_impl;
#[cfg(feature = "gecko")] pub mod gecko_values;
pub mod keyframes; pub mod keyframes;
pub mod logical_geometry; pub mod logical_geometry;
pub mod matching; pub mod matching;
@ -94,7 +96,7 @@ pub mod restyle_hints;
pub mod selector_impl; pub mod selector_impl;
pub mod selector_matching; pub mod selector_matching;
pub mod sequential; pub mod sequential;
pub mod servo; #[cfg(feature = "servo")] pub mod servo_selector_impl;
pub mod sink; pub mod sink;
pub mod str; pub mod str;
pub mod stylesheets; pub mod stylesheets;
@ -116,6 +118,12 @@ pub mod properties {
include!(concat!(env!("OUT_DIR"), "/properties.rs")); include!(concat!(env!("OUT_DIR"), "/properties.rs"));
} }
#[cfg(feature = "gecko")]
#[allow(unsafe_code)]
pub mod gecko_properties {
include!(concat!(env!("OUT_DIR"), "/gecko_properties.rs"));
}
macro_rules! reexport_computed_values { macro_rules! reexport_computed_values {
( $( $name: ident )+ ) => { ( $( $name: ident )+ ) => {
/// Types for [computed values][computed]. /// Types for [computed values][computed].

View file

@ -13,7 +13,7 @@ use context::{StyleContext, SharedStyleContext};
use data::PrivateStyleData; use data::PrivateStyleData;
use dom::{TElement, TNode, TRestyleDamage}; use dom::{TElement, TNode, TRestyleDamage};
use properties::{ComputedValues, PropertyDeclaration, cascade}; use properties::{ComputedValues, PropertyDeclaration, cascade};
use selector_impl::{ElementExt, SelectorImplExt}; use selector_impl::{ElementExt, SelectorImplExt, TheSelectorImpl, PseudoElement};
use selector_matching::{DeclarationBlock, Stylist}; use selector_matching::{DeclarationBlock, Stylist};
use selectors::Element; use selectors::Element;
use selectors::bloom::BloomFilter; use selectors::bloom::BloomFilter;
@ -48,9 +48,9 @@ fn create_common_style_affecting_attributes_from_element<E: TElement>(element: &
flags flags
} }
pub struct ApplicableDeclarations<Impl: SelectorImplExt> { pub struct ApplicableDeclarations {
pub normal: SmallVec<[DeclarationBlock; 16]>, pub normal: SmallVec<[DeclarationBlock; 16]>,
pub per_pseudo: HashMap<Impl::PseudoElement, pub per_pseudo: HashMap<PseudoElement,
Vec<DeclarationBlock>, Vec<DeclarationBlock>,
BuildHasherDefault<::fnv::FnvHasher>>, BuildHasherDefault<::fnv::FnvHasher>>,
@ -58,15 +58,15 @@ pub struct ApplicableDeclarations<Impl: SelectorImplExt> {
pub normal_shareable: bool, pub normal_shareable: bool,
} }
impl<Impl: SelectorImplExt> ApplicableDeclarations<Impl> { impl ApplicableDeclarations {
pub fn new() -> ApplicableDeclarations<Impl> { pub fn new() -> Self {
let mut applicable_declarations = ApplicableDeclarations { let mut applicable_declarations = ApplicableDeclarations {
normal: SmallVec::new(), normal: SmallVec::new(),
per_pseudo: HashMap::with_hasher(Default::default()), per_pseudo: HashMap::with_hasher(Default::default()),
normal_shareable: false, normal_shareable: false,
}; };
Impl::each_eagerly_cascaded_pseudo_element(|pseudo| { TheSelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
applicable_declarations.per_pseudo.insert(pseudo, vec![]); applicable_declarations.per_pseudo.insert(pseudo, vec![]);
}); });
@ -149,25 +149,25 @@ impl<'a> Hash for ApplicableDeclarationsCacheQuery<'a> {
static APPLICABLE_DECLARATIONS_CACHE_SIZE: usize = 32; static APPLICABLE_DECLARATIONS_CACHE_SIZE: usize = 32;
pub struct ApplicableDeclarationsCache<C: ComputedValues> { pub struct ApplicableDeclarationsCache {
cache: SimpleHashCache<ApplicableDeclarationsCacheEntry, Arc<C>>, cache: SimpleHashCache<ApplicableDeclarationsCacheEntry, Arc<ComputedValues>>,
} }
impl<C: ComputedValues> ApplicableDeclarationsCache<C> { impl ApplicableDeclarationsCache {
pub fn new() -> Self { 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<C>> { pub fn find(&self, declarations: &[DeclarationBlock]) -> Option<Arc<ComputedValues>> {
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<C>) { pub fn insert(&mut self, declarations: Vec<DeclarationBlock>, style: Arc<ComputedValues>) {
self.cache.insert(ApplicableDeclarationsCacheEntry::new(declarations), style) self.cache.insert(ApplicableDeclarationsCacheEntry::new(declarations), style)
} }
@ -177,14 +177,14 @@ impl<C: ComputedValues> ApplicableDeclarationsCache<C> {
} }
/// 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<C: ComputedValues> { pub struct StyleSharingCandidateCache {
cache: LRUCache<StyleSharingCandidate<C>, ()>, cache: LRUCache<StyleSharingCandidate, ()>,
} }
#[derive(Clone)] #[derive(Clone)]
pub struct StyleSharingCandidate<C: ComputedValues> { pub struct StyleSharingCandidate {
pub style: Arc<C>, pub style: Arc<ComputedValues>,
pub parent_style: Arc<C>, pub parent_style: Arc<ComputedValues>,
pub local_name: Atom, pub local_name: Atom,
pub classes: Vec<Atom>, pub classes: Vec<Atom>,
pub namespace: Namespace, pub namespace: Namespace,
@ -192,7 +192,7 @@ pub struct StyleSharingCandidate<C: ComputedValues> {
pub link: bool, pub link: bool,
} }
impl<C: ComputedValues> PartialEq for StyleSharingCandidate<C> { impl PartialEq for StyleSharingCandidate {
fn eq(&self, other: &Self) -> 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) &&
@ -204,12 +204,12 @@ impl<C: ComputedValues> PartialEq for StyleSharingCandidate<C> {
} }
} }
impl<C: ComputedValues> StyleSharingCandidate<C> { impl StyleSharingCandidate {
/// 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<N: TNode<ConcreteComputedValues=C>>(element: &N::ConcreteElement) -> Option<Self> { fn new<N: TNode>(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,
@ -329,18 +329,18 @@ impl<C: ComputedValues> StyleSharingCandidate<C> {
static STYLE_SHARING_CANDIDATE_CACHE_SIZE: usize = 40; static STYLE_SHARING_CANDIDATE_CACHE_SIZE: usize = 40;
impl<C: ComputedValues> StyleSharingCandidateCache<C> { impl StyleSharingCandidateCache {
pub fn new() -> Self { 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<C>, ())> { pub fn iter(&self) -> Iter<(StyleSharingCandidate, ())> {
self.cache.iter() self.cache.iter()
} }
pub fn insert_if_possible<N: TNode<ConcreteComputedValues=C>>(&mut self, element: &N::ConcreteElement) { pub fn insert_if_possible<N: TNode>(&mut self, element: &N::ConcreteElement) {
match StyleSharingCandidate::new::<N>(element) { match StyleSharingCandidate::new::<N>(element) {
None => {} None => {}
Some(candidate) => self.cache.insert(candidate, ()) Some(candidate) => self.cache.insert(candidate, ())
@ -362,22 +362,22 @@ pub enum StyleSharingResult<ConcreteRestyleDamage: TRestyleDamage> {
} }
trait PrivateMatchMethods: TNode trait PrivateMatchMethods: TNode
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt<ComputedValues = Self::ConcreteComputedValues> { where <Self::ConcreteElement as Element>::Impl: SelectorImplExt {
/// Actually cascades style for a node or a pseudo-element of a node. /// Actually cascades style for a node or a pseudo-element of a node.
/// ///
/// Note that animations only apply to nodes or ::before or ::after /// Note that animations only apply to nodes or ::before or ::after
/// pseudo-elements. /// pseudo-elements.
fn cascade_node_pseudo_element<'a, Ctx>(&self, fn cascade_node_pseudo_element<'a, Ctx>(&self,
context: &Ctx, context: &Ctx,
parent_style: Option<&Arc<Self::ConcreteComputedValues>>, parent_style: Option<&Arc<ComputedValues>>,
applicable_declarations: &[DeclarationBlock], applicable_declarations: &[DeclarationBlock],
mut style: Option<&mut Arc<Self::ConcreteComputedValues>>, mut style: Option<&mut Arc<ComputedValues>>,
applicable_declarations_cache: applicable_declarations_cache:
&mut ApplicableDeclarationsCache<Self::ConcreteComputedValues>, &mut ApplicableDeclarationsCache,
shareable: bool, shareable: bool,
animate_properties: bool) animate_properties: bool)
-> (Self::ConcreteRestyleDamage, Arc<Self::ConcreteComputedValues>) -> (Self::ConcreteRestyleDamage, Arc<ComputedValues>)
where Ctx: StyleContext<'a, <Self::ConcreteElement as Element>::Impl> { where Ctx: StyleContext<'a> {
let mut cacheable = true; let mut cacheable = true;
let shared_context = context.shared_context(); let shared_context = context.shared_context();
if animate_properties { if animate_properties {
@ -421,7 +421,7 @@ trait PrivateMatchMethods: TNode
let new_animations_sender = &context.local_context().new_animations_sender; let new_animations_sender = &context.local_context().new_animations_sender;
let this_opaque = self.opaque(); let this_opaque = self.opaque();
// Trigger any present animations if necessary. // Trigger any present animations if necessary.
let mut animations_started = animation::maybe_start_animations::<<Self::ConcreteElement as Element>::Impl>( let mut animations_started = animation::maybe_start_animations(
&shared_context, &shared_context,
new_animations_sender, new_animations_sender,
this_opaque, this_opaque,
@ -431,7 +431,7 @@ trait PrivateMatchMethods: TNode
// to its old value if it did trigger a transition. // to its old value if it did trigger a transition.
if let Some(ref style) = style { if let Some(ref style) = style {
animations_started |= animations_started |=
animation::start_transitions_if_applicable::<<Self::ConcreteElement as Element>::Impl>( animation::start_transitions_if_applicable(
new_animations_sender, new_animations_sender,
this_opaque, this_opaque,
&**style, &**style,
@ -455,8 +455,8 @@ trait PrivateMatchMethods: TNode
} }
fn update_animations_for_cascade(&self, fn update_animations_for_cascade(&self,
context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>, context: &SharedStyleContext,
style: &mut Option<&mut Arc<Self::ConcreteComputedValues>>) style: &mut Option<&mut Arc<ComputedValues>>)
-> bool { -> bool {
let style = match *style { let style = match *style {
None => return false, None => return false,
@ -506,8 +506,8 @@ trait PrivateMatchMethods: TNode
// See #12171 and the associated PR for an example where this // See #12171 and the associated PR for an example where this
// happened while debugging other release panic. // happened while debugging other release panic.
if !running_animation.is_expired() { if !running_animation.is_expired() {
animation::update_style_for_animation::<Self::ConcreteRestyleDamage, animation::update_style_for_animation::<Self::ConcreteRestyleDamage>(
<Self::ConcreteElement as Element>::Impl>(context, running_animation, style, None); context, running_animation, style, None);
running_animation.mark_as_expired(); running_animation.mark_as_expired();
} }
} }
@ -518,21 +518,19 @@ trait PrivateMatchMethods: TNode
} }
impl<N: TNode> PrivateMatchMethods for N impl<N: TNode> PrivateMatchMethods for N
where <N::ConcreteElement as Element>::Impl: where <N::ConcreteElement as Element>::Impl: SelectorImplExt {}
SelectorImplExt<ComputedValues = N::ConcreteComputedValues> {}
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<<Self::ConcreteNode as candidate: &StyleSharingCandidate)
TNode>::ConcreteComputedValues>) -> Option<Arc<ComputedValues>> {
-> 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)
}; };
@ -554,12 +552,11 @@ trait PrivateElementMatchMethods: TElement {
impl<E: TElement> PrivateElementMatchMethods for E {} impl<E: TElement> PrivateElementMatchMethods for E {}
pub trait ElementMatchMethods : TElement pub trait ElementMatchMethods : TElement {
where Self::Impl: SelectorImplExt {
fn match_element(&self, fn match_element(&self,
stylist: &Stylist<Self::Impl>, stylist: &Stylist,
parent_bf: Option<&BloomFilter>, parent_bf: Option<&BloomFilter>,
applicable_declarations: &mut ApplicableDeclarations<Self::Impl>) applicable_declarations: &mut ApplicableDeclarations)
-> bool { -> bool {
let style_attribute = self.style_attribute().as_ref(); let style_attribute = self.style_attribute().as_ref();
@ -569,7 +566,7 @@ pub trait ElementMatchMethods : TElement
style_attribute, style_attribute,
None, None,
&mut applicable_declarations.normal); &mut applicable_declarations.normal);
Self::Impl::each_eagerly_cascaded_pseudo_element(|pseudo| { TheSelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
stylist.push_applicable_declarations(self, stylist.push_applicable_declarations(self,
parent_bf, parent_bf,
None, None,
@ -586,8 +583,7 @@ 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<<Self::ConcreteNode as &mut StyleSharingCandidateCache,
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 {
@ -672,11 +668,8 @@ pub trait MatchMethods : TNode {
unsafe fn cascade_node<'a, Ctx>(&self, unsafe fn cascade_node<'a, Ctx>(&self,
context: &Ctx, context: &Ctx,
parent: Option<Self>, parent: Option<Self>,
applicable_declarations: applicable_declarations: &ApplicableDeclarations)
&ApplicableDeclarations<<Self::ConcreteElement as Element>::Impl>) where Ctx: StyleContext<'a> {
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt<ComputedValues = Self::ConcreteComputedValues>,
Ctx: StyleContext<'a, <Self::ConcreteElement as Element>::Impl>
{
// 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
// borrow flags. // borrow flags.
// //
@ -697,7 +690,7 @@ pub trait MatchMethods : TNode {
if self.is_text_node() { if self.is_text_node() {
let mut data_ref = self.mutate_data().unwrap(); let mut data_ref = self.mutate_data().unwrap();
let mut data = &mut *data_ref; let mut data = &mut *data_ref;
let cloned_parent_style = Self::ConcreteComputedValues::style_for_child_text_node(parent_style.unwrap()); let cloned_parent_style = ComputedValues::style_for_child_text_node(parent_style.unwrap());
damage = Self::ConcreteRestyleDamage::compute(data.style.as_ref(), damage = Self::ConcreteRestyleDamage::compute(data.style.as_ref(),
&*cloned_parent_style); &*cloned_parent_style);
data.style = Some(cloned_parent_style); data.style = Some(cloned_parent_style);

View file

@ -18,7 +18,7 @@ import data
def main(): def main():
usage = "Usage: %s [ servo | gecko ] [ style-crate | geckolib | html ]" % sys.argv[0] usage = "Usage: %s [ servo | gecko ] [ style-crate | html ]" % sys.argv[0]
if len(sys.argv) < 3: if len(sys.argv) < 3:
abort(usage) abort(usage)
product = sys.argv[1] product = sys.argv[1]
@ -30,10 +30,10 @@ def main():
rust = render(os.path.join(BASE, "properties.mako.rs"), product=product, data=properties) rust = render(os.path.join(BASE, "properties.mako.rs"), product=product, data=properties)
if output == "style-crate": if output == "style-crate":
write(os.environ["OUT_DIR"], "properties.rs", rust) write(os.environ["OUT_DIR"], "properties.rs", rust)
if output == "geckolib": if product == "gecko":
template = os.path.join(BASE, "..", "..", "..", "ports", "geckolib", "properties.mako.rs") template = os.path.join(BASE, "gecko.mako.rs")
rust = render(template, data=properties) rust = render(template, data=properties)
write(os.environ["OUT_DIR"], "properties.rs", rust) write(os.environ["OUT_DIR"], "gecko_properties.rs", rust)
elif output == "html": elif output == "html":
write_html(properties) write_html(properties)

View file

@ -117,11 +117,10 @@ class Method(object):
class StyleStruct(object): class StyleStruct(object):
def __init__(self, name, inherited, gecko_name=None, additional_methods=None): def __init__(self, name, inherited, gecko_name=None, additional_methods=None):
self.servo_struct_name = "Servo" + name
self.gecko_struct_name = "Gecko" + name self.gecko_struct_name = "Gecko" + name
self.trait_name = name self.name = name
self.trait_name_lower = name.lower() self.name_lower = name.lower()
self.ident = to_rust_ident(self.trait_name_lower) self.ident = to_rust_ident(self.name_lower)
self.longhands = [] self.longhands = []
self.inherited = inherited self.inherited = inherited
self.gecko_name = gecko_name or name self.gecko_name = gecko_name or name

View file

@ -10,6 +10,7 @@
%> %>
use app_units::Au; use app_units::Au;
use custom_properties::ComputedValuesMap;
% for style_struct in data.style_structs: % for style_struct in data.style_structs:
use gecko_bindings::structs::${style_struct.gecko_ffi_name}; use gecko_bindings::structs::${style_struct.gecko_ffi_name};
use gecko_bindings::bindings::Gecko_Construct_${style_struct.gecko_ffi_name}; use gecko_bindings::bindings::Gecko_Construct_${style_struct.gecko_ffi_name};
@ -23,25 +24,30 @@ use gecko_bindings::bindings::{Gecko_EnsureImageLayersLength, Gecko_CreateGradie
use gecko_bindings::bindings::{Gecko_CopyImageValueFrom, Gecko_CopyFontFamilyFrom}; use gecko_bindings::bindings::{Gecko_CopyImageValueFrom, Gecko_CopyFontFamilyFrom};
use gecko_bindings::bindings::{Gecko_FontFamilyList_AppendGeneric, Gecko_FontFamilyList_AppendNamed}; use gecko_bindings::bindings::{Gecko_FontFamilyList_AppendGeneric, Gecko_FontFamilyList_AppendNamed};
use gecko_bindings::bindings::{Gecko_FontFamilyList_Clear, Gecko_InitializeImageLayer}; use gecko_bindings::bindings::{Gecko_FontFamilyList_Clear, Gecko_InitializeImageLayer};
use gecko_bindings::bindings;
use gecko_bindings::structs; use gecko_bindings::structs;
use glue::ArcHelpers; use gecko_glue::ArcHelpers;
use gecko_values::{StyleCoordHelpers, GeckoStyleCoordConvertible, convert_nscolor_to_rgba};
use gecko_values::convert_rgba_to_nscolor;
use gecko_values::round_border_to_device_pixels;
use logical_geometry::WritingMode;
use properties::CascadePropertyFn;
use properties::longhands;
use std::fmt::{self, Debug}; use std::fmt::{self, Debug};
use std::mem::{transmute, uninitialized, zeroed}; use std::mem::{transmute, uninitialized, zeroed};
use std::sync::Arc; use std::sync::Arc;
use std::cmp; use std::cmp;
use style::custom_properties::ComputedValuesMap;
use style::logical_geometry::WritingMode; pub mod style_structs {
use style::properties::{CascadePropertyFn, ServoComputedValues, ComputedValues}; % for style_struct in data.style_structs:
use style::properties::longhands; pub use super::${style_struct.gecko_struct_name} as ${style_struct.name};
use style::properties::style_struct_traits::*; % endfor
use values::{StyleCoordHelpers, GeckoStyleCoordConvertible, convert_nscolor_to_rgba}; }
use values::convert_rgba_to_nscolor;
use values::round_border_to_device_pixels;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct GeckoComputedValues { pub struct ComputedValues {
% for style_struct in data.style_structs: % for style_struct in data.style_structs:
${style_struct.ident}: Arc<${style_struct.gecko_struct_name}>, ${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor % endfor
custom_properties: Option<Arc<ComputedValuesMap>>, custom_properties: Option<Arc<ComputedValuesMap>>,
@ -50,9 +56,9 @@ pub struct GeckoComputedValues {
pub root_font_size: Au, pub root_font_size: Au,
} }
impl GeckoComputedValues { impl ComputedValues {
pub fn inherit_from(parent: &Arc<Self>) -> Arc<Self> { pub fn inherit_from(parent: &Arc<Self>) -> Arc<Self> {
Arc::new(GeckoComputedValues { Arc::new(ComputedValues {
custom_properties: parent.custom_properties.clone(), custom_properties: parent.custom_properties.clone(),
shareable: parent.shareable, shareable: parent.shareable,
writing_mode: parent.writing_mode, writing_mode: parent.writing_mode,
@ -66,22 +72,16 @@ impl GeckoComputedValues {
% endfor % endfor
}) })
} }
}
impl ComputedValues for GeckoComputedValues { pub fn new(custom_properties: Option<Arc<ComputedValuesMap>>,
% for style_struct in data.style_structs:
type Concrete${style_struct.trait_name} = ${style_struct.gecko_struct_name};
% endfor
fn new(custom_properties: Option<Arc<ComputedValuesMap>>,
shareable: bool, shareable: bool,
writing_mode: WritingMode, writing_mode: WritingMode,
root_font_size: Au, root_font_size: Au,
% for style_struct in data.style_structs: % for style_struct in data.style_structs:
${style_struct.ident}: Arc<${style_struct.gecko_struct_name}>, ${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor % endfor
) -> Self { ) -> Self {
GeckoComputedValues { ComputedValues {
custom_properties: custom_properties, custom_properties: custom_properties,
shareable: shareable, shareable: shareable,
writing_mode: writing_mode, writing_mode: writing_mode,
@ -92,43 +92,46 @@ impl ComputedValues for GeckoComputedValues {
} }
} }
fn style_for_child_text_node(parent: &Arc<Self>) -> Arc<Self> { pub fn style_for_child_text_node(parent: &Arc<Self>) -> Arc<Self> {
// Gecko expects text nodes to be styled as if they were elements that // Gecko expects text nodes to be styled as if they were elements that
// matched no rules (that is, inherited style structs are inherited and // matched no rules (that is, inherited style structs are inherited and
// non-inherited style structs are set to their initial values). // non-inherited style structs are set to their initial values).
GeckoComputedValues::inherit_from(parent) ComputedValues::inherit_from(parent)
} }
fn initial_values() -> &'static Self { &*INITIAL_GECKO_VALUES } pub fn initial_values() -> &'static Self { &*INITIAL_GECKO_VALUES }
#[inline] #[inline]
fn do_cascade_property<F: FnOnce(&[CascadePropertyFn<Self>])>(f: F) { pub fn do_cascade_property<F: FnOnce(&[CascadePropertyFn])>(f: F) {
f(&CASCADE_PROPERTY) f(&CASCADE_PROPERTY)
} }
% for style_struct in data.style_structs: % for style_struct in data.style_structs:
#[inline] #[inline]
fn clone_${style_struct.trait_name_lower}(&self) -> Arc<Self::Concrete${style_struct.trait_name}> { pub fn clone_${style_struct.name_lower}(&self) -> Arc<style_structs::${style_struct.name}> {
self.${style_struct.ident}.clone() self.${style_struct.ident}.clone()
} }
#[inline] #[inline]
fn get_${style_struct.trait_name_lower}<'a>(&'a self) -> &'a Self::Concrete${style_struct.trait_name} { pub fn get_${style_struct.name_lower}(&self) -> &style_structs::${style_struct.name} {
&self.${style_struct.ident} &self.${style_struct.ident}
} }
#[inline] #[inline]
fn mutate_${style_struct.trait_name_lower}<'a>(&'a mut self) -> &'a mut Self::Concrete${style_struct.trait_name} { pub fn mutate_${style_struct.name_lower}(&mut self) -> &mut style_structs::${style_struct.name} {
Arc::make_mut(&mut self.${style_struct.ident}) Arc::make_mut(&mut self.${style_struct.ident})
} }
% endfor % endfor
fn custom_properties(&self) -> Option<Arc<ComputedValuesMap>> { self.custom_properties.as_ref().map(|x| x.clone())} pub fn custom_properties(&self) -> Option<Arc<ComputedValuesMap>> {
fn root_font_size(&self) -> Au { self.root_font_size } self.custom_properties.as_ref().map(|x| x.clone())
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; }
pub fn root_font_size(&self) -> Au { self.root_font_size }
pub fn set_root_font_size(&mut self, s: Au) { self.root_font_size = s; }
pub fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; }
// FIXME(bholley): Implement this properly. // FIXME(bholley): Implement this properly.
#[inline] #[inline]
fn is_multicol(&self) -> bool { false } pub fn is_multicol(&self) -> bool { false }
} }
<%def name="declare_style_struct(style_struct)"> <%def name="declare_style_struct(style_struct)">
@ -138,25 +141,29 @@ pub struct ${style_struct.gecko_struct_name} {
</%def> </%def>
<%def name="impl_simple_setter(ident, gecko_ffi_name)"> <%def name="impl_simple_setter(ident, gecko_ffi_name)">
fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { #[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
${set_gecko_property(gecko_ffi_name, "v")} ${set_gecko_property(gecko_ffi_name, "v")}
} }
</%def> </%def>
<%def name="impl_simple_clone(ident, gecko_ffi_name)"> <%def name="impl_simple_clone(ident, gecko_ffi_name)">
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { #[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
self.gecko.${gecko_ffi_name} self.gecko.${gecko_ffi_name}
} }
</%def> </%def>
<%def name="impl_simple_copy(ident, gecko_ffi_name, *kwargs)"> <%def name="impl_simple_copy(ident, gecko_ffi_name, *kwargs)">
fn copy_${ident}_from(&mut self, other: &Self) { #[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name}; self.gecko.${gecko_ffi_name} = other.gecko.${gecko_ffi_name};
} }
</%def> </%def>
<%def name="impl_coord_copy(ident, gecko_ffi_name)"> <%def name="impl_coord_copy(ident, gecko_ffi_name)">
fn copy_${ident}_from(&mut self, other: &Self) { #[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
self.gecko.${gecko_ffi_name}.copy_from(&other.gecko.${gecko_ffi_name}); self.gecko.${gecko_ffi_name}.copy_from(&other.gecko.${gecko_ffi_name});
} }
</%def> </%def>
@ -180,8 +187,9 @@ def set_gecko_property(ffi_name, expr):
%> %>
<%def name="impl_keyword_setter(ident, gecko_ffi_name, keyword)"> <%def name="impl_keyword_setter(ident, gecko_ffi_name, keyword)">
fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { #[allow(non_snake_case)]
use style::properties::longhands::${ident}::computed_value::T as Keyword; pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
use properties::longhands::${ident}::computed_value::T as Keyword;
// FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts // FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts
let result = match v { let result = match v {
% for value in keyword.values_for('gecko'): % for value in keyword.values_for('gecko'):
@ -193,8 +201,9 @@ def set_gecko_property(ffi_name, expr):
</%def> </%def>
<%def name="impl_keyword_clone(ident, gecko_ffi_name, keyword)"> <%def name="impl_keyword_clone(ident, gecko_ffi_name, keyword)">
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { #[allow(non_snake_case)]
use style::properties::longhands::${ident}::computed_value::T as Keyword; pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use properties::longhands::${ident}::computed_value::T as Keyword;
// FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts // FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts
match ${get_gecko_property(gecko_ffi_name)} as u32 { match ${get_gecko_property(gecko_ffi_name)} as u32 {
% for value in keyword.values_for('gecko'): % for value in keyword.values_for('gecko'):
@ -232,7 +241,8 @@ def set_gecko_property(ffi_name, expr):
<%def name="impl_color_setter(ident, gecko_ffi_name, color_flags_ffi_name=None)"> <%def name="impl_color_setter(ident, gecko_ffi_name, color_flags_ffi_name=None)">
#[allow(unreachable_code)] #[allow(unreachable_code)]
fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { #[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
use cssparser::Color; use cssparser::Color;
${clear_color_flags(color_flags_ffi_name)} ${clear_color_flags(color_flags_ffi_name)}
let result = match v { let result = match v {
@ -247,7 +257,8 @@ def set_gecko_property(ffi_name, expr):
</%def> </%def>
<%def name="impl_color_copy(ident, gecko_ffi_name, color_flags_ffi_name=None)"> <%def name="impl_color_copy(ident, gecko_ffi_name, color_flags_ffi_name=None)">
fn copy_${ident}_from(&mut self, other: &Self) { #[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
% if color_flags_ffi_name: % if color_flags_ffi_name:
${clear_color_flags(color_flags_ffi_name)} ${clear_color_flags(color_flags_ffi_name)}
if ${get_current_color_flag_from("other.gecko." + color_flags_ffi_name)} { if ${get_current_color_flag_from("other.gecko." + color_flags_ffi_name)} {
@ -259,7 +270,8 @@ def set_gecko_property(ffi_name, expr):
</%def> </%def>
<%def name="impl_color_clone(ident, gecko_ffi_name, color_flags_ffi_name=None)"> <%def name="impl_color_clone(ident, gecko_ffi_name, color_flags_ffi_name=None)">
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { #[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use cssparser::Color; use cssparser::Color;
% if color_flags_ffi_name: % if color_flags_ffi_name:
if ${get_current_color_flag_from("self.gecko." + color_flags_ffi_name)} { if ${get_current_color_flag_from("self.gecko." + color_flags_ffi_name)} {
@ -295,7 +307,8 @@ def set_gecko_property(ffi_name, expr):
</%def> </%def>
<%def name="impl_app_units(ident, gecko_ffi_name, need_clone, round_to_pixels=False)"> <%def name="impl_app_units(ident, gecko_ffi_name, need_clone, round_to_pixels=False)">
fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { #[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
% if round_to_pixels: % if round_to_pixels:
let au_per_device_px = Au(self.gecko.mTwipsPerPixel); let au_per_device_px = Au(self.gecko.mTwipsPerPixel);
self.gecko.${gecko_ffi_name} = round_border_to_device_pixels(v, au_per_device_px).0; self.gecko.${gecko_ffi_name} = round_border_to_device_pixels(v, au_per_device_px).0;
@ -305,26 +318,30 @@ def set_gecko_property(ffi_name, expr):
} }
<%call expr="impl_simple_copy(ident, gecko_ffi_name)"></%call> <%call expr="impl_simple_copy(ident, gecko_ffi_name)"></%call>
%if need_clone: %if need_clone:
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { #[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
Au(self.gecko.${gecko_ffi_name}) Au(self.gecko.${gecko_ffi_name})
} }
% endif % endif
</%def> </%def>
<%def name="impl_split_style_coord(ident, unit_ffi_name, union_ffi_name, need_clone=False)"> <%def name="impl_split_style_coord(ident, unit_ffi_name, union_ffi_name, need_clone=False)">
fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { #[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
v.to_gecko_style_coord(&mut self.gecko.${unit_ffi_name}, v.to_gecko_style_coord(&mut self.gecko.${unit_ffi_name},
&mut self.gecko.${union_ffi_name}); &mut self.gecko.${union_ffi_name});
} }
fn copy_${ident}_from(&mut self, other: &Self) { #[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
unsafe { self.gecko.${union_ffi_name}.reset(&mut self.gecko.${unit_ffi_name}) }; unsafe { self.gecko.${union_ffi_name}.reset(&mut self.gecko.${unit_ffi_name}) };
self.gecko.${unit_ffi_name} = other.gecko.${unit_ffi_name}; self.gecko.${unit_ffi_name} = other.gecko.${unit_ffi_name};
self.gecko.${union_ffi_name} = other.gecko.${union_ffi_name}; self.gecko.${union_ffi_name} = other.gecko.${union_ffi_name};
unsafe { self.gecko.${union_ffi_name}.addref_if_calc(&self.gecko.${unit_ffi_name}) }; unsafe { self.gecko.${union_ffi_name}.addref_if_calc(&self.gecko.${unit_ffi_name}) };
} }
% if need_clone: % if need_clone:
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { #[allow(non_snake_case)]
use style::properties::longhands::${ident}::computed_value::T; pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use properties::longhands::${ident}::computed_value::T;
T::from_gecko_style_coord(&self.gecko.${unit_ffi_name}, T::from_gecko_style_coord(&self.gecko.${unit_ffi_name},
&self.gecko.${union_ffi_name}) &self.gecko.${union_ffi_name})
.expect("clone for ${ident} failed") .expect("clone for ${ident} failed")
@ -341,13 +358,15 @@ ${impl_split_style_coord(ident,
<%def name="impl_corner_style_coord(ident, x_unit_ffi_name, x_union_ffi_name, \ <%def name="impl_corner_style_coord(ident, x_unit_ffi_name, x_union_ffi_name, \
y_unit_ffi_name, y_union_ffi_name, need_clone=False)"> y_unit_ffi_name, y_union_ffi_name, need_clone=False)">
fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) { #[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
v.0.width.to_gecko_style_coord(&mut self.gecko.${x_unit_ffi_name}, v.0.width.to_gecko_style_coord(&mut self.gecko.${x_unit_ffi_name},
&mut self.gecko.${x_union_ffi_name}); &mut self.gecko.${x_union_ffi_name});
v.0.height.to_gecko_style_coord(&mut self.gecko.${y_unit_ffi_name}, v.0.height.to_gecko_style_coord(&mut self.gecko.${y_unit_ffi_name},
&mut self.gecko.${y_union_ffi_name}); &mut self.gecko.${y_union_ffi_name});
} }
fn copy_${ident}_from(&mut self, other: &Self) { #[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
unsafe { self.gecko.${x_union_ffi_name}.reset(&mut self.gecko.${x_unit_ffi_name}) }; unsafe { self.gecko.${x_union_ffi_name}.reset(&mut self.gecko.${x_unit_ffi_name}) };
unsafe { self.gecko.${y_union_ffi_name}.reset(&mut self.gecko.${y_unit_ffi_name}) }; unsafe { self.gecko.${y_union_ffi_name}.reset(&mut self.gecko.${y_unit_ffi_name}) };
self.gecko.${x_unit_ffi_name} = other.gecko.${x_unit_ffi_name}; self.gecko.${x_unit_ffi_name} = other.gecko.${x_unit_ffi_name};
@ -358,8 +377,9 @@ ${impl_split_style_coord(ident,
unsafe { self.gecko.${y_union_ffi_name}.addref_if_calc(&self.gecko.${y_unit_ffi_name}) }; unsafe { self.gecko.${y_union_ffi_name}.addref_if_calc(&self.gecko.${y_unit_ffi_name}) };
} }
% if need_clone: % if need_clone:
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { #[allow(non_snake_case)]
use style::properties::longhands::${ident}::computed_value::T; pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use properties::longhands::${ident}::computed_value::T;
use euclid::Size2D; use euclid::Size2D;
let width = GeckoStyleCoordConvertible::from_gecko_style_coord(&self.gecko.${x_unit_ffi_name}, let width = GeckoStyleCoordConvertible::from_gecko_style_coord(&self.gecko.${x_unit_ffi_name},
&self.gecko.${x_union_ffi_name}) &self.gecko.${x_union_ffi_name})
@ -375,7 +395,7 @@ ${impl_split_style_coord(ident,
<%def name="impl_style_struct(style_struct)"> <%def name="impl_style_struct(style_struct)">
impl ${style_struct.gecko_struct_name} { impl ${style_struct.gecko_struct_name} {
#[allow(dead_code, unused_variables)] #[allow(dead_code, unused_variables)]
fn initial() -> Arc<Self> { pub fn initial() -> Arc<Self> {
let mut result = Arc::new(${style_struct.gecko_struct_name} { gecko: unsafe { zeroed() } }); let mut result = Arc::new(${style_struct.gecko_struct_name} { gecko: unsafe { zeroed() } });
unsafe { unsafe {
Gecko_Construct_${style_struct.gecko_ffi_name}(&mut Arc::make_mut(&mut result).gecko); Gecko_Construct_${style_struct.gecko_ffi_name}(&mut Arc::make_mut(&mut result).gecko);
@ -455,7 +475,7 @@ impl Debug for ${style_struct.gecko_struct_name} {
if x.predefined_type in predefined_types and not x.name in force_stub] if x.predefined_type in predefined_types and not x.name in force_stub]
stub_longhands = [x for x in longhands if x not in keyword_longhands + predefined_longhands] stub_longhands = [x for x in longhands if x not in keyword_longhands + predefined_longhands]
%> %>
impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} { impl ${style_struct.gecko_struct_name} {
/* /*
* Manually-Implemented Methods. * Manually-Implemented Methods.
*/ */
@ -476,24 +496,28 @@ impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} {
* Stubs. * Stubs.
*/ */
% for longhand in stub_longhands: % for longhand in stub_longhands:
fn set_${longhand.ident}(&mut self, _: longhands::${longhand.ident}::computed_value::T) { #[allow(non_snake_case)]
pub fn set_${longhand.ident}(&mut self, _: longhands::${longhand.ident}::computed_value::T) {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
println!("stylo: Unimplemented property setter: ${longhand.name}"); println!("stylo: Unimplemented property setter: ${longhand.name}");
} }
} }
fn copy_${longhand.ident}_from(&mut self, _: &Self) { #[allow(non_snake_case)]
pub fn copy_${longhand.ident}_from(&mut self, _: &Self) {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
println!("stylo: Unimplemented property setter: ${longhand.name}"); println!("stylo: Unimplemented property setter: ${longhand.name}");
} }
} }
% if longhand.need_clone: % if longhand.need_clone:
fn clone_${longhand.ident}(&self) -> longhands::${longhand.ident}::computed_value::T { #[allow(non_snake_case)]
pub fn clone_${longhand.ident}(&self) -> longhands::${longhand.ident}::computed_value::T {
unimplemented!() unimplemented!()
} }
% endif % endif
% if longhand.need_index: % if longhand.need_index:
fn ${longhand.ident}_count(&self) -> usize { 0 } pub fn ${longhand.ident}_count(&self) -> usize { 0 }
fn ${longhand.ident}_at(&self, _index: usize) -> longhands::${longhand.ident}::computed_value::SingleComputedValue { pub fn ${longhand.ident}_at(&self, _index: usize)
-> longhands::${longhand.ident}::computed_value::SingleComputedValue {
unimplemented!() unimplemented!()
} }
% endif % endif
@ -508,7 +532,7 @@ impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} {
<% data.manual_style_structs = [] %> <% data.manual_style_structs = [] %>
<%def name="impl_trait(style_struct_name, skip_longhands='', skip_additionals='')"> <%def name="impl_trait(style_struct_name, skip_longhands='', skip_additionals='')">
<%self:raw_impl_trait style_struct="${next(x for x in data.style_structs if x.trait_name == style_struct_name)}" <%self:raw_impl_trait style_struct="${next(x for x in data.style_structs if x.name == style_struct_name)}"
skip_longhands="${skip_longhands}" skip_additionals="${skip_additionals}"> skip_longhands="${skip_longhands}" skip_additionals="${skip_additionals}">
${caller.body()} ${caller.body()}
</%self:raw_impl_trait> </%self:raw_impl_trait>
@ -571,7 +595,7 @@ fn static_assert() {
<% impl_app_units("border_%s_width" % side.ident, "mComputedBorder.%s" % side.ident, need_clone=True, <% impl_app_units("border_%s_width" % side.ident, "mComputedBorder.%s" % side.ident, need_clone=True,
round_to_pixels=True) %> round_to_pixels=True) %>
fn border_${side.ident}_has_nonzero_width(&self) -> bool { pub fn border_${side.ident}_has_nonzero_width(&self) -> bool {
self.gecko.mComputedBorder.${side.ident} != 0 self.gecko.mComputedBorder.${side.ident} != 0
} }
% endfor % endfor
@ -621,15 +645,15 @@ fn static_assert() {
need_clone=True) %> need_clone=True) %>
% endfor % endfor
fn set_z_index(&mut self, v: longhands::z_index::computed_value::T) { pub fn set_z_index(&mut self, v: longhands::z_index::computed_value::T) {
use style::properties::longhands::z_index::computed_value::T; use properties::longhands::z_index::computed_value::T;
match v { match v {
T::Auto => self.gecko.mZIndex.set_auto(), T::Auto => self.gecko.mZIndex.set_auto(),
T::Number(n) => self.gecko.mZIndex.set_int(n), T::Number(n) => self.gecko.mZIndex.set_int(n),
} }
} }
fn copy_z_index_from(&mut self, other: &Self) { pub fn copy_z_index_from(&mut self, other: &Self) {
use gecko_bindings::structs::nsStyleUnit; use gecko_bindings::structs::nsStyleUnit;
// z-index is never a calc(). If it were, we'd be leaking here, so // z-index is never a calc(). If it were, we'd be leaking here, so
// assert that it isn't. // assert that it isn't.
@ -638,8 +662,8 @@ fn static_assert() {
self.gecko.mZIndex.mValue = other.gecko.mZIndex.mValue; self.gecko.mZIndex.mValue = other.gecko.mZIndex.mValue;
} }
fn clone_z_index(&self) -> longhands::z_index::computed_value::T { pub fn clone_z_index(&self) -> longhands::z_index::computed_value::T {
use style::properties::longhands::z_index::computed_value::T; use properties::longhands::z_index::computed_value::T;
if self.gecko.mZIndex.is_auto() { if self.gecko.mZIndex.is_auto() {
return T::Auto; return T::Auto;
@ -649,8 +673,8 @@ fn static_assert() {
T::Number(self.gecko.mZIndex.get_int()) T::Number(self.gecko.mZIndex.get_int())
} }
fn set_box_sizing(&mut self, v: longhands::box_sizing::computed_value::T) { pub fn set_box_sizing(&mut self, v: longhands::box_sizing::computed_value::T) {
use style::computed_values::box_sizing::T; use computed_values::box_sizing::T;
use gecko_bindings::structs::StyleBoxSizing; use gecko_bindings::structs::StyleBoxSizing;
// TODO: guess what to do with box-sizing: padding-box // TODO: guess what to do with box-sizing: padding-box
self.gecko.mBoxSizing = match v { self.gecko.mBoxSizing = match v {
@ -684,7 +708,7 @@ fn static_assert() {
"mOutlineRadius.mValues[%s]" % corner.y_index) %> "mOutlineRadius.mValues[%s]" % corner.y_index) %>
% endfor % endfor
fn outline_has_nonzero_width(&self) -> bool { pub fn outline_has_nonzero_width(&self) -> bool {
self.gecko.mActualOutlineWidth != 0 self.gecko.mActualOutlineWidth != 0
} }
</%self:impl_trait> </%self:impl_trait>
@ -693,8 +717,8 @@ fn static_assert() {
skip_longhands="font-family font-style font-size font-weight" skip_longhands="font-family font-style font-size font-weight"
skip_additionals="*"> skip_additionals="*">
fn set_font_family(&mut self, v: longhands::font_family::computed_value::T) { pub fn set_font_family(&mut self, v: longhands::font_family::computed_value::T) {
use style::properties::longhands::font_family::computed_value::FontFamily; use properties::longhands::font_family::computed_value::FontFamily;
use gecko_bindings::structs::FontFamilyType; use gecko_bindings::structs::FontFamilyType;
let list = &mut self.gecko.mFont.fontlist; let list = &mut self.gecko.mFont.fontlist;
@ -719,7 +743,7 @@ fn static_assert() {
} }
} }
fn copy_font_family_from(&mut self, other: &Self) { pub fn copy_font_family_from(&mut self, other: &Self) {
unsafe { Gecko_CopyFontFamilyFrom(&mut self.gecko.mFont, &other.gecko.mFont); } unsafe { Gecko_CopyFontFamilyFrom(&mut self.gecko.mFont, &other.gecko.mFont); }
} }
@ -729,24 +753,24 @@ fn static_assert() {
// FIXME(bholley): Gecko has two different sizes, one of which (mSize) is the // FIXME(bholley): Gecko has two different sizes, one of which (mSize) is the
// actual computed size, and the other of which (mFont.size) is the 'display // actual computed size, and the other of which (mFont.size) is the 'display
// size' which takes font zooming into account. We don't handle font zooming yet. // size' which takes font zooming into account. We don't handle font zooming yet.
fn set_font_size(&mut self, v: longhands::font_size::computed_value::T) { pub fn set_font_size(&mut self, v: longhands::font_size::computed_value::T) {
self.gecko.mFont.size = v.0; self.gecko.mFont.size = v.0;
self.gecko.mSize = v.0; self.gecko.mSize = v.0;
} }
fn copy_font_size_from(&mut self, other: &Self) { pub fn copy_font_size_from(&mut self, other: &Self) {
self.gecko.mFont.size = other.gecko.mFont.size; self.gecko.mFont.size = other.gecko.mFont.size;
self.gecko.mSize = other.gecko.mSize; self.gecko.mSize = other.gecko.mSize;
} }
fn clone_font_size(&self) -> longhands::font_size::computed_value::T { pub fn clone_font_size(&self) -> longhands::font_size::computed_value::T {
Au(self.gecko.mSize) Au(self.gecko.mSize)
} }
fn set_font_weight(&mut self, v: longhands::font_weight::computed_value::T) { pub fn set_font_weight(&mut self, v: longhands::font_weight::computed_value::T) {
self.gecko.mFont.weight = v as u16; self.gecko.mFont.weight = v as u16;
} }
${impl_simple_copy('font_weight', 'mFont.weight')} ${impl_simple_copy('font_weight', 'mFont.weight')}
fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T { pub fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T {
debug_assert!(self.gecko.mFont.weight >= 100); debug_assert!(self.gecko.mFont.weight >= 100);
debug_assert!(self.gecko.mFont.weight <= 900); debug_assert!(self.gecko.mFont.weight <= 900);
debug_assert!(self.gecko.mFont.weight % 10 == 0); debug_assert!(self.gecko.mFont.weight % 10 == 0);
@ -754,7 +778,7 @@ fn static_assert() {
} }
// This is used for PartialEq, which we don't implement for gecko style structs. // This is used for PartialEq, which we don't implement for gecko style structs.
fn compute_font_hash(&mut self) {} pub fn compute_font_hash(&mut self) {}
</%self:impl_trait> </%self:impl_trait>
@ -773,8 +797,8 @@ fn static_assert() {
// overflow-y is implemented as a newtype of overflow-x, so we need special handling. // overflow-y is implemented as a newtype of overflow-x, so we need special handling.
// We could generalize this if we run into other newtype keywords. // We could generalize this if we run into other newtype keywords.
<% overflow_x = data.longhands_by_name["overflow-x"] %> <% overflow_x = data.longhands_by_name["overflow-x"] %>
fn set_overflow_y(&mut self, v: longhands::overflow_y::computed_value::T) { pub fn set_overflow_y(&mut self, v: longhands::overflow_y::computed_value::T) {
use style::properties::longhands::overflow_x::computed_value::T as BaseType; use properties::longhands::overflow_x::computed_value::T as BaseType;
// FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts // FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts
self.gecko.mOverflowY = match v.0 { self.gecko.mOverflowY = match v.0 {
% for value in overflow_x.keyword.values_for('gecko'): % for value in overflow_x.keyword.values_for('gecko'):
@ -783,9 +807,9 @@ fn static_assert() {
}; };
} }
${impl_simple_copy('overflow_y', 'mOverflowY')} ${impl_simple_copy('overflow_y', 'mOverflowY')}
fn clone_overflow_y(&self) -> longhands::overflow_y::computed_value::T { pub fn clone_overflow_y(&self) -> longhands::overflow_y::computed_value::T {
use style::properties::longhands::overflow_x::computed_value::T as BaseType; use properties::longhands::overflow_x::computed_value::T as BaseType;
use style::properties::longhands::overflow_y::computed_value::T as NewType; use properties::longhands::overflow_y::computed_value::T as NewType;
// FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts // FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts
match self.gecko.mOverflowY as u32 { match self.gecko.mOverflowY as u32 {
% for value in overflow_x.keyword.values_for('gecko'): % for value in overflow_x.keyword.values_for('gecko'):
@ -795,9 +819,9 @@ fn static_assert() {
} }
} }
fn set_vertical_align(&mut self, v: longhands::vertical_align::computed_value::T) { pub fn set_vertical_align(&mut self, v: longhands::vertical_align::computed_value::T) {
<% keyword = data.longhands_by_name["vertical-align"].keyword %> <% keyword = data.longhands_by_name["vertical-align"].keyword %>
use style::properties::longhands::vertical_align::computed_value::T; use properties::longhands::vertical_align::computed_value::T;
// FIXME: Align binary representations and ditch |match| for cast + static_asserts // FIXME: Align binary representations and ditch |match| for cast + static_asserts
match v { match v {
% for value in keyword.values_for('gecko'): % for value in keyword.values_for('gecko'):
@ -808,9 +832,9 @@ fn static_assert() {
} }
} }
fn clone_vertical_align(&self) -> longhands::vertical_align::computed_value::T { pub fn clone_vertical_align(&self) -> longhands::vertical_align::computed_value::T {
use style::properties::longhands::vertical_align::computed_value::T; use properties::longhands::vertical_align::computed_value::T;
use style::values::computed::LengthOrPercentage; use values::computed::LengthOrPercentage;
if self.gecko.mVerticalAlign.is_enum() { if self.gecko.mVerticalAlign.is_enum() {
match self.gecko.mVerticalAlign.get_enum() as u32 { match self.gecko.mVerticalAlign.get_enum() as u32 {
@ -830,8 +854,9 @@ fn static_assert() {
<%call expr="impl_coord_copy('vertical_align', 'mVerticalAlign')"></%call> <%call expr="impl_coord_copy('vertical_align', 'mVerticalAlign')"></%call>
fn set__moz_binding(&mut self, v: longhands::_moz_binding::computed_value::T) { #[allow(non_snake_case)]
use style::properties::longhands::_moz_binding::SpecifiedValue as BindingValue; pub fn set__moz_binding(&mut self, v: longhands::_moz_binding::computed_value::T) {
use properties::longhands::_moz_binding::SpecifiedValue as BindingValue;
match v { match v {
BindingValue::None => debug_assert!(self.gecko.mBinding.mRawPtr.is_null()), BindingValue::None => debug_assert!(self.gecko.mBinding.mRawPtr.is_null()),
BindingValue::Url(ref url, ref extra_data) => { BindingValue::Url(ref url, ref extra_data) => {
@ -846,7 +871,8 @@ fn static_assert() {
} }
} }
} }
fn copy__moz_binding_from(&mut self, other: &Self) { #[allow(non_snake_case)]
pub fn copy__moz_binding_from(&mut self, other: &Self) {
unsafe { Gecko_CopyMozBindingFrom(&mut self.gecko, &other.gecko); } unsafe { Gecko_CopyMozBindingFrom(&mut self.gecko, &other.gecko); }
} }
@ -854,8 +880,8 @@ fn static_assert() {
// Map 'auto' and 'avoid' to false, and 'always', 'left', and 'right' to true. // Map 'auto' and 'avoid' to false, and 'always', 'left', and 'right' to true.
// "A conforming user agent may interpret the values 'left' and 'right' // "A conforming user agent may interpret the values 'left' and 'right'
// as 'always'." - CSS2.1, section 13.3.1 // as 'always'." - CSS2.1, section 13.3.1
fn set_page_break_before(&mut self, v: longhands::page_break_before::computed_value::T) { pub fn set_page_break_before(&mut self, v: longhands::page_break_before::computed_value::T) {
use style::computed_values::page_break_before::T; use computed_values::page_break_before::T;
let result = match v { let result = match v {
T::auto => false, T::auto => false,
T::always => true, T::always => true,
@ -871,8 +897,8 @@ fn static_assert() {
// Temp fix for Bugzilla bug 24000. // Temp fix for Bugzilla bug 24000.
// See set_page_break_before for detail. // See set_page_break_before for detail.
fn set_page_break_after(&mut self, v: longhands::page_break_after::computed_value::T) { pub fn set_page_break_after(&mut self, v: longhands::page_break_after::computed_value::T) {
use style::computed_values::page_break_after::T; use computed_values::page_break_after::T;
let result = match v { let result = match v {
T::auto => false, T::auto => false,
T::always => true, T::always => true,
@ -900,14 +926,14 @@ fn static_assert() {
<% impl_color("background_color", "mBackgroundColor", need_clone=True) %> <% impl_color("background_color", "mBackgroundColor", need_clone=True) %>
fn copy_background_repeat_from(&mut self, other: &Self) { pub fn copy_background_repeat_from(&mut self, other: &Self) {
self.gecko.mImage.mRepeatCount = cmp::min(1, other.gecko.mImage.mRepeatCount); self.gecko.mImage.mRepeatCount = cmp::min(1, other.gecko.mImage.mRepeatCount);
self.gecko.mImage.mLayers.mFirstElement.mRepeat = self.gecko.mImage.mLayers.mFirstElement.mRepeat =
other.gecko.mImage.mLayers.mFirstElement.mRepeat; other.gecko.mImage.mLayers.mFirstElement.mRepeat;
} }
fn set_background_repeat(&mut self, v: longhands::background_repeat::computed_value::T) { pub fn set_background_repeat(&mut self, v: longhands::background_repeat::computed_value::T) {
use style::properties::longhands::background_repeat::computed_value::T; use properties::longhands::background_repeat::computed_value::T;
use gecko_bindings::structs::{NS_STYLE_IMAGELAYER_REPEAT_REPEAT, NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT}; use gecko_bindings::structs::{NS_STYLE_IMAGELAYER_REPEAT_REPEAT, NS_STYLE_IMAGELAYER_REPEAT_NO_REPEAT};
use gecko_bindings::structs::nsStyleImageLayers_Repeat; use gecko_bindings::structs::nsStyleImageLayers_Repeat;
let (repeat_x, repeat_y) = match v { let (repeat_x, repeat_y) = match v {
@ -928,14 +954,14 @@ fn static_assert() {
}; };
} }
fn copy_background_clip_from(&mut self, other: &Self) { pub fn copy_background_clip_from(&mut self, other: &Self) {
self.gecko.mImage.mClipCount = cmp::min(1, other.gecko.mImage.mClipCount); self.gecko.mImage.mClipCount = cmp::min(1, other.gecko.mImage.mClipCount);
self.gecko.mImage.mLayers.mFirstElement.mClip = self.gecko.mImage.mLayers.mFirstElement.mClip =
other.gecko.mImage.mLayers.mFirstElement.mClip; other.gecko.mImage.mLayers.mFirstElement.mClip;
} }
fn set_background_clip(&mut self, v: longhands::background_clip::computed_value::T) { pub fn set_background_clip(&mut self, v: longhands::background_clip::computed_value::T) {
use style::properties::longhands::background_clip::computed_value::T; use properties::longhands::background_clip::computed_value::T;
self.gecko.mImage.mClipCount = 1; self.gecko.mImage.mClipCount = 1;
// TODO: Gecko supports background-clip: text, but just on -webkit- // TODO: Gecko supports background-clip: text, but just on -webkit-
@ -947,14 +973,14 @@ fn static_assert() {
}; };
} }
fn copy_background_origin_from(&mut self, other: &Self) { pub fn copy_background_origin_from(&mut self, other: &Self) {
self.gecko.mImage.mOriginCount = cmp::min(1, other.gecko.mImage.mOriginCount); self.gecko.mImage.mOriginCount = cmp::min(1, other.gecko.mImage.mOriginCount);
self.gecko.mImage.mLayers.mFirstElement.mOrigin = self.gecko.mImage.mLayers.mFirstElement.mOrigin =
other.gecko.mImage.mLayers.mFirstElement.mOrigin; other.gecko.mImage.mLayers.mFirstElement.mOrigin;
} }
fn set_background_origin(&mut self, v: longhands::background_origin::computed_value::T) { pub fn set_background_origin(&mut self, v: longhands::background_origin::computed_value::T) {
use style::properties::longhands::background_origin::computed_value::T; use properties::longhands::background_origin::computed_value::T;
self.gecko.mImage.mOriginCount = 1; self.gecko.mImage.mOriginCount = 1;
self.gecko.mImage.mLayers.mFirstElement.mOrigin = match v { self.gecko.mImage.mLayers.mFirstElement.mOrigin = match v {
@ -964,14 +990,14 @@ fn static_assert() {
}; };
} }
fn copy_background_attachment_from(&mut self, other: &Self) { pub fn copy_background_attachment_from(&mut self, other: &Self) {
self.gecko.mImage.mAttachmentCount = cmp::min(1, other.gecko.mImage.mAttachmentCount); self.gecko.mImage.mAttachmentCount = cmp::min(1, other.gecko.mImage.mAttachmentCount);
self.gecko.mImage.mLayers.mFirstElement.mAttachment = self.gecko.mImage.mLayers.mFirstElement.mAttachment =
other.gecko.mImage.mLayers.mFirstElement.mAttachment; other.gecko.mImage.mLayers.mFirstElement.mAttachment;
} }
fn set_background_attachment(&mut self, v: longhands::background_attachment::computed_value::T) { pub fn set_background_attachment(&mut self, v: longhands::background_attachment::computed_value::T) {
use style::properties::longhands::background_attachment::computed_value::T; use properties::longhands::background_attachment::computed_value::T;
self.gecko.mImage.mAttachmentCount = 1; self.gecko.mImage.mAttachmentCount = 1;
self.gecko.mImage.mLayers.mFirstElement.mAttachment = match v { self.gecko.mImage.mLayers.mFirstElement.mAttachment = match v {
@ -981,19 +1007,19 @@ fn static_assert() {
}; };
} }
fn copy_background_image_from(&mut self, other: &Self) { pub fn copy_background_image_from(&mut self, other: &Self) {
unsafe { unsafe {
Gecko_CopyImageValueFrom(&mut self.gecko.mImage.mLayers.mFirstElement.mImage, Gecko_CopyImageValueFrom(&mut self.gecko.mImage.mLayers.mFirstElement.mImage,
&other.gecko.mImage.mLayers.mFirstElement.mImage); &other.gecko.mImage.mLayers.mFirstElement.mImage);
} }
} }
fn set_background_image(&mut self, images: longhands::background_image::computed_value::T) { pub fn set_background_image(&mut self, images: longhands::background_image::computed_value::T) {
use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType; use gecko_bindings::structs::nsStyleImageLayers_LayerType as LayerType;
use gecko_bindings::structs::{NS_STYLE_GRADIENT_SHAPE_LINEAR, NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER}; use gecko_bindings::structs::{NS_STYLE_GRADIENT_SHAPE_LINEAR, NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER};
use gecko_bindings::structs::nsStyleCoord; use gecko_bindings::structs::nsStyleCoord;
use style::values::computed::Image; use values::computed::Image;
use style::values::specified::AngleOrCorner; use values::specified::AngleOrCorner;
use cssparser::Color as CSSColor; use cssparser::Color as CSSColor;
unsafe { unsafe {
@ -1088,7 +1114,7 @@ fn static_assert() {
${impl_keyword_setter("list_style_type", "__LIST_STYLE_TYPE__", ${impl_keyword_setter("list_style_type", "__LIST_STYLE_TYPE__",
data.longhands_by_name["list-style-type"].keyword)} data.longhands_by_name["list-style-type"].keyword)}
fn copy_list_style_type_from(&mut self, other: &Self) { pub fn copy_list_style_type_from(&mut self, other: &Self) {
unsafe { unsafe {
Gecko_CopyListStyleTypeFrom(&mut self.gecko, &other.gecko); Gecko_CopyListStyleTypeFrom(&mut self.gecko, &other.gecko);
} }
@ -1103,8 +1129,8 @@ fn static_assert() {
"-moz-right match-parent") %> "-moz-right match-parent") %>
${impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)} ${impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)}
fn set_line_height(&mut self, v: longhands::line_height::computed_value::T) { pub fn set_line_height(&mut self, v: longhands::line_height::computed_value::T) {
use style::properties::longhands::line_height::computed_value::T; use properties::longhands::line_height::computed_value::T;
// FIXME: Align binary representations and ditch |match| for cast + static_asserts // FIXME: Align binary representations and ditch |match| for cast + static_asserts
match v { match v {
T::Normal => self.gecko.mLineHeight.set_normal(), T::Normal => self.gecko.mLineHeight.set_normal(),
@ -1115,8 +1141,8 @@ fn static_assert() {
} }
} }
fn clone_line_height(&self) -> longhands::line_height::computed_value::T { pub fn clone_line_height(&self) -> longhands::line_height::computed_value::T {
use style::properties::longhands::line_height::computed_value::T; use properties::longhands::line_height::computed_value::T;
if self.gecko.mLineHeight.is_normal() { if self.gecko.mLineHeight.is_normal() {
return T::Normal; return T::Normal;
} }
@ -1142,7 +1168,7 @@ fn static_assert() {
${impl_color("text_decoration_color", "mTextDecorationColor", ${impl_color("text_decoration_color", "mTextDecorationColor",
color_flags_ffi_name="mTextDecorationStyle", need_clone=True)} color_flags_ffi_name="mTextDecorationStyle", need_clone=True)}
fn set_text_decoration_line(&mut self, v: longhands::text_decoration_line::computed_value::T) { pub fn set_text_decoration_line(&mut self, v: longhands::text_decoration_line::computed_value::T) {
let mut bits: u8 = 0; let mut bits: u8 = 0;
if v.underline { if v.underline {
bits |= structs::NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE as u8; bits |= structs::NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE as u8;
@ -1159,17 +1185,17 @@ fn static_assert() {
${impl_simple_copy('text_decoration_line', 'mTextDecorationLine')} ${impl_simple_copy('text_decoration_line', 'mTextDecorationLine')}
#[inline] #[inline]
fn has_underline(&self) -> bool { pub fn has_underline(&self) -> bool {
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE as u8)) != 0 (self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE as u8)) != 0
} }
#[inline] #[inline]
fn has_overline(&self) -> bool { pub fn has_overline(&self) -> bool {
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_OVERLINE as u8)) != 0 (self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_OVERLINE as u8)) != 0
} }
#[inline] #[inline]
fn has_line_through(&self) -> bool { pub fn has_line_through(&self) -> bool {
(self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH as u8)) != 0 (self.gecko.mTextDecorationLine & (structs::NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH as u8)) != 0
} }
</%self:impl_trait> </%self:impl_trait>
@ -1188,14 +1214,14 @@ fn static_assert() {
<%self:impl_trait style_struct_name="Color" <%self:impl_trait style_struct_name="Color"
skip_longhands="*"> skip_longhands="*">
fn set_color(&mut self, v: longhands::color::computed_value::T) { pub fn set_color(&mut self, v: longhands::color::computed_value::T) {
let result = convert_rgba_to_nscolor(&v); let result = convert_rgba_to_nscolor(&v);
${set_gecko_property("mColor", "result")} ${set_gecko_property("mColor", "result")}
} }
<%call expr="impl_simple_copy('color', 'mColor')"></%call> <%call expr="impl_simple_copy('color', 'mColor')"></%call>
fn clone_color(&self) -> longhands::color::computed_value::T { pub fn clone_color(&self) -> longhands::color::computed_value::T {
let color = ${get_gecko_property("mColor")} as u32; let color = ${get_gecko_property("mColor")} as u32;
convert_nscolor_to_rgba(color) convert_nscolor_to_rgba(color)
} }
@ -1203,8 +1229,8 @@ fn static_assert() {
<%self:impl_trait style_struct_name="Pointing" <%self:impl_trait style_struct_name="Pointing"
skip_longhands="cursor"> skip_longhands="cursor">
fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) { pub fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) {
use style::properties::longhands::cursor::computed_value::T; use properties::longhands::cursor::computed_value::T;
use style_traits::cursor::Cursor; use style_traits::cursor::Cursor;
self.gecko.mCursor = match v { self.gecko.mCursor = match v {
@ -1255,7 +1281,7 @@ fn static_assert() {
<%self:impl_trait style_struct_name="Column" <%self:impl_trait style_struct_name="Column"
skip_longhands="column-width"> skip_longhands="column-width">
fn set_column_width(&mut self, v: longhands::column_width::computed_value::T) { pub fn set_column_width(&mut self, v: longhands::column_width::computed_value::T) {
match v.0 { match v.0 {
Some(au) => self.gecko.mColumnWidth.set_coord(au), Some(au) => self.gecko.mColumnWidth.set_coord(au),
None => self.gecko.mColumnWidth.set_auto(), None => self.gecko.mColumnWidth.set_auto(),
@ -1268,10 +1294,10 @@ fn static_assert() {
<%def name="define_ffi_struct_accessor(style_struct)"> <%def name="define_ffi_struct_accessor(style_struct)">
#[no_mangle] #[no_mangle]
#[allow(non_snake_case, unused_variables)] #[allow(non_snake_case, unused_variables)]
pub extern "C" fn Servo_GetStyle${style_struct.gecko_name}(computed_values: *mut ServoComputedValues) pub extern "C" fn Servo_GetStyle${style_struct.gecko_name}(computed_values: *mut bindings::ServoComputedValues)
-> *const ${style_struct.gecko_ffi_name} { -> *const ${style_struct.gecko_ffi_name} {
type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>; type Helpers = ArcHelpers<bindings::ServoComputedValues, ComputedValues>;
Helpers::with(computed_values, |values| values.get_${style_struct.trait_name_lower}().get_gecko() Helpers::with(computed_values, |values| values.get_${style_struct.name_lower}().get_gecko()
as *const ${style_struct.gecko_ffi_name}) as *const ${style_struct.gecko_ffi_name})
} }
</%def> </%def>
@ -1279,16 +1305,16 @@ pub extern "C" fn Servo_GetStyle${style_struct.gecko_name}(computed_values: *mut
% for style_struct in data.style_structs: % for style_struct in data.style_structs:
${declare_style_struct(style_struct)} ${declare_style_struct(style_struct)}
${impl_style_struct(style_struct)} ${impl_style_struct(style_struct)}
% if not style_struct.trait_name in data.manual_style_structs: % if not style_struct.name in data.manual_style_structs:
<%self:raw_impl_trait style_struct="${style_struct}"></%self:raw_impl_trait> <%self:raw_impl_trait style_struct="${style_struct}"></%self:raw_impl_trait>
% endif % endif
${define_ffi_struct_accessor(style_struct)} ${define_ffi_struct_accessor(style_struct)}
% endfor % endfor
lazy_static! { lazy_static! {
pub static ref INITIAL_GECKO_VALUES: GeckoComputedValues = GeckoComputedValues { pub static ref INITIAL_GECKO_VALUES: ComputedValues = ComputedValues {
% for style_struct in data.style_structs: % for style_struct in data.style_structs:
${style_struct.ident}: ${style_struct.gecko_struct_name}::initial(), ${style_struct.ident}: style_structs::${style_struct.name}::initial(),
% endfor % endfor
custom_properties: None, custom_properties: None,
shareable: true, shareable: true,
@ -1297,7 +1323,7 @@ lazy_static! {
}; };
} }
static CASCADE_PROPERTY: [CascadePropertyFn<GeckoComputedValues>; ${len(data.longhands)}] = [ static CASCADE_PROPERTY: [CascadePropertyFn; ${len(data.longhands)}] = [
% for property in data.longhands: % for property in data.longhands:
longhands::${property.ident}::cascade_property, longhands::${property.ident}::cascade_property,
% endfor % endfor

View file

@ -64,7 +64,7 @@
use cssparser::Parser; use cssparser::Parser;
use parser::{ParserContext, ParserContextExtraData}; use parser::{ParserContext, ParserContextExtraData};
use properties::{CSSWideKeyword, DeclaredValue, Shorthand}; use properties::{CSSWideKeyword, DeclaredValue, Shorthand};
use values::computed::{TContext, ToComputedValue}; use values::computed::{Context, ToComputedValue};
use values::{computed, specified}; use values::{computed, specified};
${caller.body()} ${caller.body()}
} }
@ -144,7 +144,7 @@
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T(self.0.iter().map(|x| x.to_computed_value(context)).collect()) computed_value::T(self.0.iter().map(|x| x.to_computed_value(context)).collect())
} }
} }
@ -170,21 +170,19 @@
use error_reporting::ParseErrorReporter; use error_reporting::ParseErrorReporter;
use properties::longhands; use properties::longhands;
use properties::property_bit_field::PropertyBitField; use properties::property_bit_field::PropertyBitField;
use properties::{ComputedValues, ServoComputedValues, PropertyDeclaration}; use properties::{ComputedValues, PropertyDeclaration};
use properties::style_struct_traits::${data.current_style_struct.trait_name};
use properties::style_structs; use properties::style_structs;
use std::boxed::Box as StdBox; use std::boxed::Box as StdBox;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use values::computed::{TContext, ToComputedValue}; use values::computed::{Context, ToComputedValue};
use values::{computed, specified}; use values::{computed, specified};
use string_cache::Atom; use string_cache::Atom;
${caller.body()} ${caller.body()}
#[allow(unused_variables)] #[allow(unused_variables)]
pub fn cascade_property<C: ComputedValues>( pub fn cascade_property(declaration: &PropertyDeclaration,
declaration: &PropertyDeclaration, inherited_style: &ComputedValues,
inherited_style: &C, context: &mut computed::Context,
context: &mut computed::Context<C>,
seen: &mut PropertyBitField, seen: &mut PropertyBitField,
cacheable: &mut bool, cacheable: &mut bool,
error_reporter: &mut StdBox<ParseErrorReporter + Send>) { error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
@ -205,16 +203,16 @@
declared_value, &custom_props, |value| match *value { declared_value, &custom_props, |value| match *value {
DeclaredValue::Value(ref specified_value) => { DeclaredValue::Value(ref specified_value) => {
let computed = specified_value.to_computed_value(context); let computed = specified_value.to_computed_value(context);
context.mutate_style().mutate_${data.current_style_struct.trait_name_lower}() context.mutate_style().mutate_${data.current_style_struct.name_lower}()
.set_${property.ident}(computed); .set_${property.ident}(computed);
} }
DeclaredValue::WithVariables { .. } => unreachable!(), DeclaredValue::WithVariables { .. } => unreachable!(),
DeclaredValue::Initial => { DeclaredValue::Initial => {
// We assume that it's faster to use copy_*_from rather than // We assume that it's faster to use copy_*_from rather than
// set_*(get_initial_value()); // set_*(get_initial_value());
let initial_struct = C::initial_values() let initial_struct = ComputedValues::initial_values()
.get_${data.current_style_struct.trait_name_lower}(); .get_${data.current_style_struct.name_lower}();
context.mutate_style().mutate_${data.current_style_struct.trait_name_lower}() context.mutate_style().mutate_${data.current_style_struct.name_lower}()
.copy_${property.ident}_from(initial_struct); .copy_${property.ident}_from(initial_struct);
}, },
DeclaredValue::Inherit => { DeclaredValue::Inherit => {
@ -224,8 +222,8 @@
// FIXME: is it still? // FIXME: is it still?
*cacheable = false; *cacheable = false;
let inherited_struct = let inherited_struct =
inherited_style.get_${data.current_style_struct.trait_name_lower}(); inherited_style.get_${data.current_style_struct.name_lower}();
context.mutate_style().mutate_${data.current_style_struct.trait_name_lower}() context.mutate_style().mutate_${data.current_style_struct.name_lower}()
.copy_${property.ident}_from(inherited_struct); .copy_${property.ident}_from(inherited_struct);
} }
}, error_reporter }, error_reporter

View file

@ -24,7 +24,6 @@ use properties::longhands::transform_origin::computed_value::T as TransformOrigi
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::*;
use std::cmp; use std::cmp;
use std::fmt; use std::fmt;
use super::ComputedValues; use super::ComputedValues;
@ -115,7 +114,7 @@ impl AnimatedProperty {
} }
} }
pub fn update<C: ComputedValues>(&self, style: &mut C, progress: f64) { pub fn update(&self, style: &mut ComputedValues, progress: f64) {
match *self { match *self {
% for prop in data.longhands: % for prop in data.longhands:
% if prop.animatable: % if prop.animatable:
@ -129,9 +128,10 @@ impl AnimatedProperty {
} }
} }
pub fn from_transition_property<C: ComputedValues>(transition_property: &TransitionProperty, pub fn from_transition_property(transition_property: &TransitionProperty,
old_style: &C, old_style: &ComputedValues,
new_style: &C) -> AnimatedProperty { new_style: &ComputedValues)
-> AnimatedProperty {
match *transition_property { match *transition_property {
TransitionProperty::All => panic!("Can't use TransitionProperty::All here."), TransitionProperty::All => panic!("Can't use TransitionProperty::All here."),
% for prop in data.longhands: % for prop in data.longhands:

View file

@ -65,7 +65,7 @@ ${helpers.predefined_type("background-color", "CSSColor",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match *self { match *self {
SpecifiedValue(None) => computed_value::T(None), SpecifiedValue(None) => computed_value::T(None),
SpecifiedValue(Some(ref image)) => SpecifiedValue(Some(ref image)) =>
@ -172,7 +172,7 @@ ${helpers.predefined_type("background-color", "CSSColor",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T { computed_value::T {
horizontal: self.horizontal.to_computed_value(context), horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context), vertical: self.vertical.to_computed_value(context),
@ -308,7 +308,7 @@ ${helpers.single_keyword("background-origin",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match *self { match *self {
SpecifiedValue::Explicit(ref size) => { SpecifiedValue::Explicit(ref size) => {
computed_value::T::Explicit(computed_value::ExplicitSize { computed_value::T::Explicit(computed_value::ExplicitSize {

View file

@ -62,7 +62,7 @@
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
self.0.to_computed_value(context) self.0.to_computed_value(context)
} }
} }

View file

@ -26,7 +26,7 @@
experimental_values = set("flex".split()) experimental_values = set("flex".split())
%> %>
pub use self::computed_value::T as SpecifiedValue; pub use self::computed_value::T as SpecifiedValue;
use values::computed::{Context, ComputedValueAsSpecified}; use values::computed::ComputedValueAsSpecified;
use values::NoViewportPercentage; use values::NoViewportPercentage;
impl NoViewportPercentage for SpecifiedValue {} impl NoViewportPercentage for SpecifiedValue {}
@ -76,10 +76,9 @@
impl ComputedValueAsSpecified for SpecifiedValue {} impl ComputedValueAsSpecified for SpecifiedValue {}
% if product == "servo": % if product == "servo":
fn cascade_property_custom<C: ComputedValues>( fn cascade_property_custom(_declaration: &PropertyDeclaration,
_declaration: &PropertyDeclaration, _inherited_style: &ComputedValues,
_inherited_style: &C, context: &mut computed::Context,
context: &mut computed::Context<C>,
_seen: &mut PropertyBitField, _seen: &mut PropertyBitField,
_cacheable: &mut bool, _cacheable: &mut bool,
_error_reporter: &mut StdBox<ParseErrorReporter + Send>) { _error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
@ -105,7 +104,7 @@ ${helpers.single_keyword("position", "static absolute relative fixed",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
let positioned = matches!(context.style().get_box().clone_position(), let positioned = matches!(context.style().get_box().clone_position(),
longhands::position::SpecifiedValue::absolute | longhands::position::SpecifiedValue::absolute |
longhands::position::SpecifiedValue::fixed); longhands::position::SpecifiedValue::fixed);
@ -134,7 +133,7 @@ ${helpers.single_keyword("clear", "none left right both",
} }
#[inline] #[inline]
pub fn derive_from_display<Cx: TContext>(context: &mut Cx) { pub fn derive_from_display(context: &mut Context) {
let d = context.style().get_box().clone_display(); let d = context.style().get_box().clone_display();
context.mutate_style().mutate_box().set__servo_display_for_hypothetical_box(d); context.mutate_style().mutate_box().set__servo_display_for_hypothetical_box(d);
} }
@ -228,7 +227,7 @@ ${helpers.single_keyword("clear", "none left right both",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match *self { match *self {
% for keyword in vertical_align_keywords: % for keyword in vertical_align_keywords:
SpecifiedValue::${to_rust_ident(keyword)} => { SpecifiedValue::${to_rust_ident(keyword)} => {
@ -287,7 +286,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T(self.0.to_computed_value(context)) computed_value::T(self.0.to_computed_value(context))
} }
} }
@ -316,7 +315,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
pub mod computed_value { pub mod computed_value {
use cssparser::ToCss; use cssparser::ToCss;
use std::fmt; use std::fmt;
use values::computed::{TContext, ToComputedValue}; use values::computed::{Context, ToComputedValue};
pub use values::computed::Time as SingleComputedValue; pub use values::computed::Time as SingleComputedValue;
@ -497,7 +496,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> computed_value::T { fn to_computed_value(&self, _: &Context) -> computed_value::T {
(*self).clone() (*self).clone()
} }
} }
@ -623,7 +622,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> computed_value::T { fn to_computed_value(&self, _: &Context) -> computed_value::T {
(*self).clone() (*self).clone()
} }
} }

View file

@ -15,7 +15,7 @@
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> computed_value::T { fn to_computed_value(&self, _context: &Context) -> computed_value::T {
self.parsed self.parsed
} }
} }

View file

@ -63,7 +63,7 @@
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match *self { match *self {
SpecifiedValue::Auto => computed_value::T(None), SpecifiedValue::Auto => computed_value::T(None),
SpecifiedValue::Specified(l) => SpecifiedValue::Specified(l) =>
@ -129,7 +129,7 @@
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> computed_value::T { fn to_computed_value(&self, _context: &Context) -> computed_value::T {
match *self { match *self {
SpecifiedValue::Auto => computed_value::T(None), SpecifiedValue::Auto => computed_value::T(None),
SpecifiedValue::Specified(count) => SpecifiedValue::Specified(count) =>
@ -209,7 +209,7 @@
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match *self { match *self {
SpecifiedValue::Normal => computed_value::T(None), SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) => SpecifiedValue::Specified(l) =>

View file

@ -98,7 +98,7 @@ ${helpers.predefined_type("opacity",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T { computed_value::T {
offset_x: self.offset_x.to_computed_value(context), offset_x: self.offset_x.to_computed_value(context),
offset_y: self.offset_y.to_computed_value(context), offset_y: self.offset_y.to_computed_value(context),
@ -306,7 +306,7 @@ ${helpers.predefined_type("opacity",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T(self.0.map(|value| computed_value::ClipRect { computed_value::T(self.0.map(|value| computed_value::ClipRect {
top: value.top.to_computed_value(context), top: value.top.to_computed_value(context),
right: value.right.map(|right| right.to_computed_value(context)), right: value.right.map(|right| right.to_computed_value(context)),
@ -598,7 +598,7 @@ ${helpers.predefined_type("opacity",
impl ToComputedValue for SpecifiedValue { impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T{ filters: self.0.iter().map(|value| { computed_value::T{ filters: self.0.iter().map(|value| {
match *value { match *value {
SpecifiedFilter::Blur(factor) => SpecifiedFilter::Blur(factor) =>
@ -1064,7 +1064,7 @@ ${helpers.predefined_type("opacity",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
if self.0.is_empty() { if self.0.is_empty() {
return computed_value::T(None) return computed_value::T(None)
} }
@ -1275,7 +1275,7 @@ ${helpers.single_keyword("transform-style",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T { computed_value::T {
horizontal: self.horizontal.to_computed_value(context), horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context), vertical: self.vertical.to_computed_value(context),
@ -1361,7 +1361,7 @@ ${helpers.predefined_type("perspective",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T { computed_value::T {
horizontal: self.horizontal.to_computed_value(context), horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context), vertical: self.vertical.to_computed_value(context),

View file

@ -220,7 +220,7 @@ ${helpers.single_keyword("font-variant",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match *self { match *self {
% for weight in range(100, 901, 100): % for weight in range(100, 901, 100):
SpecifiedValue::Weight${weight} => computed_value::T::Weight${weight}, SpecifiedValue::Weight${weight} => computed_value::T::Weight${weight},
@ -288,7 +288,7 @@ ${helpers.single_keyword("font-variant",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match self.0 { match self.0 {
LengthOrPercentage::Length(Length::FontRelative(value)) => { LengthOrPercentage::Length(Length::FontRelative(value)) => {
value.to_computed_value(context.inherited_style().get_font().clone_font_size(), value.to_computed_value(context.inherited_style().get_font().clone_font_size(),

View file

@ -92,7 +92,7 @@ ${helpers.single_keyword("color-adjust",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> computed_value::T { fn to_computed_value(&self, _: &Context) -> computed_value::T {
*self *self
} }
} }
@ -131,8 +131,7 @@ ${helpers.single_keyword("color-adjust",
} }
#[inline] #[inline]
pub fn derive_from_display<Cx: TContext>(context: &mut Cx) { pub fn derive_from_display(context: &mut Context) {
use properties::style_struct_traits::Box;
use super::display::computed_value::T as Display; use super::display::computed_value::T as Display;
if context.style().get_box().clone_display() == Display::none { if context.style().get_box().clone_display() == Display::none {

View file

@ -76,7 +76,7 @@ ${helpers.single_keyword("caption-side", "top bottom",
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T { computed_value::T {
horizontal: self.horizontal.to_computed_value(context), horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context), vertical: self.vertical.to_computed_value(context),

View file

@ -102,7 +102,7 @@
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match *self { match *self {
SpecifiedValue::Normal => computed_value::T::Normal, SpecifiedValue::Normal => computed_value::T::Normal,
% if product == "gecko": % if product == "gecko":
@ -248,7 +248,7 @@
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match *self { match *self {
SpecifiedValue::Normal => computed_value::T(None), SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) => SpecifiedValue::Specified(l) =>
@ -322,7 +322,7 @@
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
match *self { match *self {
SpecifiedValue::Normal => computed_value::T(None), SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) => SpecifiedValue::Specified(l) =>
@ -374,7 +374,6 @@ ${helpers.single_keyword("text-justify",
use values:: NoViewportPercentage; use values:: NoViewportPercentage;
use values::computed::ComputedValueAsSpecified; use values::computed::ComputedValueAsSpecified;
use properties::style_struct_traits::{Box, Color, Text};
impl ComputedValueAsSpecified for SpecifiedValue {} impl ComputedValueAsSpecified for SpecifiedValue {}
impl NoViewportPercentage for SpecifiedValue {} impl NoViewportPercentage for SpecifiedValue {}
@ -407,7 +406,7 @@ ${helpers.single_keyword("text-justify",
} }
} }
fn maybe<Cx: TContext>(flag: bool, context: &Cx) -> Option<RGBA> { fn maybe(flag: bool, context: &Context) -> Option<RGBA> {
if flag { if flag {
Some(context.style().get_color().clone_color()) Some(context.style().get_color().clone_color())
} else { } else {
@ -415,7 +414,7 @@ ${helpers.single_keyword("text-justify",
} }
} }
fn derive<Cx: TContext>(context: &Cx) -> computed_value::T { fn derive(context: &Context) -> computed_value::T {
// Start with no declarations if this is an atomic inline-level box; otherwise, start with the // Start with no declarations if this is an atomic inline-level box; otherwise, start with the
// declarations in effect and add in the text decorations that this block specifies. // declarations in effect and add in the text decorations that this block specifies.
let mut result = match context.style().get_box().clone_display() { let mut result = match context.style().get_box().clone_display() {
@ -439,13 +438,13 @@ ${helpers.single_keyword("text-justify",
} }
#[inline] #[inline]
pub fn derive_from_text_decoration<Cx: TContext>(context: &mut Cx) { pub fn derive_from_text_decoration(context: &mut Context) {
let derived = derive(context); let derived = derive(context);
context.mutate_style().mutate_inheritedtext().set__servo_text_decorations_in_effect(derived); context.mutate_style().mutate_inheritedtext().set__servo_text_decorations_in_effect(derived);
} }
#[inline] #[inline]
pub fn derive_from_display<Cx: TContext>(context: &mut Cx) { pub fn derive_from_display(context: &mut Context) {
let derived = derive(context); let derived = derive(context);
context.mutate_style().mutate_inheritedtext().set__servo_text_decorations_in_effect(derived); context.mutate_style().mutate_inheritedtext().set__servo_text_decorations_in_effect(derived);
} }
@ -675,7 +674,7 @@ ${helpers.single_keyword("text-justify",
impl ToComputedValue for SpecifiedValue { impl ToComputedValue for SpecifiedValue {
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
computed_value::T(self.0.iter().map(|value| { computed_value::T(self.0.iter().map(|value| {
computed_value::TextShadow { computed_value::TextShadow {
offset_x: value.offset_x.to_computed_value(context), offset_x: value.offset_x.to_computed_value(context),

View file

@ -75,7 +75,7 @@ ${helpers.single_keyword("list-style-type", """
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> computed_value::T { fn to_computed_value(&self, _context: &Context) -> computed_value::T {
match *self { match *self {
SpecifiedValue::None => computed_value::T(None), SpecifiedValue::None => computed_value::T(None),
SpecifiedValue::Url(ref url) => computed_value::T(Some(url.clone())), SpecifiedValue::Url(ref url) => computed_value::T(Some(url.clone())),

View file

@ -63,7 +63,7 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr
type ComputedValue = computed_value::T; type ComputedValue = computed_value::T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T { fn to_computed_value(&self, context: &Context) -> computed_value::T {
self.0.to_computed_value(context) self.0.to_computed_value(context)
} }
} }

View file

@ -108,10 +108,9 @@ ${helpers.single_keyword("unicode-bidi",
} }
% if product == "servo": % if product == "servo":
fn cascade_property_custom<C: ComputedValues>( fn cascade_property_custom(_declaration: &PropertyDeclaration,
_declaration: &PropertyDeclaration, _inherited_style: &ComputedValues,
_inherited_style: &C, context: &mut computed::Context,
context: &mut computed::Context<C>,
_seen: &mut PropertyBitField, _seen: &mut PropertyBitField,
_cacheable: &mut bool, _cacheable: &mut bool,
_error_reporter: &mut StdBox<ParseErrorReporter + Send>) { _error_reporter: &mut StdBox<ParseErrorReporter + Send>) {

View file

@ -13,28 +13,28 @@
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::boxed::Box as StdBox; use std::boxed::Box as StdBox;
use std::collections::HashSet; use std::collections::HashSet;
use std::fmt; use std::fmt::{self, Write};
use std::fmt::{Debug, Write};
use std::sync::Arc; use std::sync::Arc;
use app_units::Au; use app_units::Au;
use cssparser::Color as CSSParserColor; #[cfg(feature = "servo")] use cssparser::{Color as CSSParserColor, RGBA};
use cssparser::{Parser, RGBA, AtRuleParser, DeclarationParser, Delimiter, use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter,
DeclarationListParser, parse_important, ToCss, TokenSerializationType}; DeclarationListParser, parse_important, ToCss, TokenSerializationType};
use error_reporting::ParseErrorReporter; use error_reporting::ParseErrorReporter;
use url::Url; use url::Url;
use euclid::side_offsets::SideOffsets2D; #[cfg(feature = "servo")] use euclid::side_offsets::SideOffsets2D;
use euclid::size::Size2D; use euclid::size::Size2D;
use string_cache::Atom; use string_cache::Atom;
use computed_values; use computed_values;
use logical_geometry::{LogicalMargin, PhysicalSide, WritingMode}; #[cfg(feature = "servo")] use logical_geometry::{LogicalMargin, PhysicalSide};
use logical_geometry::WritingMode;
use parser::{ParserContext, ParserContextExtraData, log_css_error}; use parser::{ParserContext, ParserContextExtraData, log_css_error};
use selectors::matching::DeclarationBlock; use selectors::matching::DeclarationBlock;
use stylesheets::Origin; use stylesheets::Origin;
use values::LocalToCss; use values::LocalToCss;
use values::HasViewportPercentage; use values::HasViewportPercentage;
use values::computed::{self, TContext, ToComputedValue}; use values::computed::{self, ToComputedValue};
use values::specified::BorderStyle; #[cfg(feature = "servo")] use values::specified::BorderStyle;
use self::property_bit_field::PropertyBitField; use self::property_bit_field::PropertyBitField;
@ -1082,33 +1082,123 @@ impl PropertyDeclaration {
} }
} }
pub mod style_struct_traits { #[cfg(feature = "gecko")]
pub use gecko_properties::style_structs;
#[cfg(feature = "servo")]
pub mod style_structs {
use fnv::FnvHasher;
use super::longhands; use super::longhands;
use std::fmt::Debug; use std::hash::{Hash, Hasher};
% for style_struct in data.active_style_structs(): % for style_struct in data.active_style_structs():
pub trait ${style_struct.trait_name}: Debug + Clone { % if style_struct.name == "Font":
#[derive(Clone, Debug)]
% else:
#[derive(PartialEq, Clone, Debug)]
% endif
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct ${style_struct.name} {
% for longhand in style_struct.longhands:
pub ${longhand.ident}: longhands::${longhand.ident}::computed_value::T,
% endfor
% if style_struct.name == "Font":
pub hash: u64,
% endif
}
% if style_struct.name == "Font":
impl PartialEq for ${style_struct.name} {
fn eq(&self, other: &${style_struct.name}) -> bool {
self.hash == other.hash
% for longhand in style_struct.longhands:
&& self.${longhand.ident} == other.${longhand.ident}
% endfor
}
}
% endif
impl ${style_struct.name} {
% for longhand in style_struct.longhands: % for longhand in style_struct.longhands:
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T); #[inline]
#[allow(non_snake_case)] pub fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T) {
fn copy_${longhand.ident}_from(&mut self, other: &Self); self.${longhand.ident} = v;
% if longhand.need_clone: }
#[allow(non_snake_case)]
fn clone_${longhand.ident}(&self) -> longhands::${longhand.ident}::computed_value::T;
% endif
% if longhand.need_index:
#[allow(non_snake_case)]
fn ${longhand.ident}_count(&self) -> usize;
#[allow(non_snake_case)]
fn ${longhand.ident}_at(&self, index: usize)
-> longhands::${longhand.ident}::computed_value::SingleComputedValue;
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[inline] #[inline]
fn ${longhand.ident}_iter<'a>(&'a self) pub fn copy_${longhand.ident}_from(&mut self, other: &Self) {
-> ${longhand.camel_case}Iter<'a, Self> { self.${longhand.ident} = other.${longhand.ident}.clone();
}
% if longhand.need_clone:
#[allow(non_snake_case)]
#[inline]
pub fn clone_${longhand.ident}(&self) -> longhands::${longhand.ident}::computed_value::T {
self.${longhand.ident}.clone()
}
% endif
% if longhand.need_index:
#[allow(non_snake_case)]
pub fn ${longhand.ident}_count(&self) -> usize {
self.${longhand.ident}.0.len()
}
#[allow(non_snake_case)]
pub fn ${longhand.ident}_at(&self, index: usize)
-> longhands::${longhand.ident}::computed_value::SingleComputedValue {
self.${longhand.ident}.0[index].clone()
}
% endif
% endfor
% if style_struct.name == "Border":
% for side in ["top", "right", "bottom", "left"]:
#[allow(non_snake_case)]
pub fn border_${side}_has_nonzero_width(&self) -> bool {
self.border_${side}_width != ::app_units::Au(0)
}
% endfor
% elif style_struct.name == "Font":
pub 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 == "Outline":
#[inline]
pub fn outline_has_nonzero_width(&self) -> bool {
self.outline_width != ::app_units::Au(0)
}
% elif style_struct.name == "Text":
<% text_decoration_field = 'text_decoration' if product == 'servo' else 'text_decoration_line' %>
#[inline]
pub fn has_underline(&self) -> bool {
self.${text_decoration_field}.underline
}
#[inline]
pub fn has_overline(&self) -> bool {
self.${text_decoration_field}.overline
}
#[inline]
pub fn has_line_through(&self) -> bool {
self.${text_decoration_field}.line_through
}
% endif
}
% endfor
}
% for style_struct in data.active_style_structs():
impl style_structs::${style_struct.name} {
% for longhand in style_struct.longhands:
% if longhand.need_index:
#[allow(non_snake_case)]
#[inline]
pub fn ${longhand.ident}_iter(&self) -> ${longhand.camel_case}Iter {
${longhand.camel_case}Iter { ${longhand.camel_case}Iter {
style_struct: self, style_struct: self,
current: 0, current: 0,
@ -1118,27 +1208,23 @@ pub mod style_struct_traits {
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[inline] #[inline]
fn ${longhand.ident}_mod(&self, index: usize) pub fn ${longhand.ident}_mod(&self, index: usize)
-> longhands::${longhand.ident}::computed_value::SingleComputedValue { -> longhands::${longhand.ident}::computed_value::SingleComputedValue {
self.${longhand.ident}_at(index % self.${longhand.ident}_count()) self.${longhand.ident}_at(index % self.${longhand.ident}_count())
} }
% endif % endif
% endfor % endfor
% for additional in style_struct.additional_methods:
#[allow(non_snake_case)]
${additional.declare()}
% endfor
} }
% for longhand in style_struct.longhands: % for longhand in style_struct.longhands:
% if longhand.need_index: % if longhand.need_index:
pub struct ${longhand.camel_case}Iter<'a, S: ${style_struct.trait_name} + 'static> { pub struct ${longhand.camel_case}Iter<'a> {
style_struct: &'a S, style_struct: &'a style_structs::${style_struct.name},
current: usize, current: usize,
max: usize, max: usize,
} }
impl<'a, S: ${style_struct.trait_name} + 'static> Iterator for ${longhand.camel_case}Iter<'a, S> { impl<'a> Iterator for ${longhand.camel_case}Iter<'a> {
type Item = longhands::${longhand.ident}::computed_value::SingleComputedValue; type Item = longhands::${longhand.ident}::computed_value::SingleComputedValue;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@ -1152,151 +1238,20 @@ pub mod style_struct_traits {
} }
% endif % endif
% endfor % endfor
% endfor % endfor
}
pub mod style_structs {
use fnv::FnvHasher;
use super::longhands;
use std::hash::{Hash, Hasher};
#[cfg(feature = "gecko")]
pub use gecko_properties::ComputedValues;
#[cfg(feature = "servo")]
pub type ServoComputedValues = ComputedValues;
#[cfg(feature = "servo")]
#[cfg_attr(feature = "servo", derive(Clone, Debug, HeapSizeOf))]
pub struct ComputedValues {
% for style_struct in data.active_style_structs(): % for style_struct in data.active_style_structs():
% if style_struct.trait_name == "Font": ${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
#[derive(Clone, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
% else:
#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
% endif
pub struct ${style_struct.servo_struct_name} {
% for longhand in style_struct.longhands:
pub ${longhand.ident}: longhands::${longhand.ident}::computed_value::T,
% endfor
% if style_struct.trait_name == "Font":
pub hash: u64,
% endif
}
% if style_struct.trait_name == "Font":
impl PartialEq for ${style_struct.servo_struct_name} {
fn eq(&self, other: &${style_struct.servo_struct_name}) -> bool {
self.hash == other.hash
% for longhand in style_struct.longhands:
&& self.${longhand.ident} == other.${longhand.ident}
% endfor
}
}
% endif
impl super::style_struct_traits::${style_struct.trait_name} for ${style_struct.servo_struct_name} {
% for longhand in style_struct.longhands:
#[inline]
fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T) {
self.${longhand.ident} = v;
}
#[inline]
fn copy_${longhand.ident}_from(&mut self, other: &Self) {
self.${longhand.ident} = other.${longhand.ident}.clone();
}
% if longhand.need_clone:
#[inline]
fn clone_${longhand.ident}(&self) -> longhands::${longhand.ident}::computed_value::T {
self.${longhand.ident}.clone()
}
% endif
% if longhand.need_index:
fn ${longhand.ident}_count(&self) -> usize {
self.${longhand.ident}.0.len()
}
fn ${longhand.ident}_at(&self, index: usize)
-> longhands::${longhand.ident}::computed_value::SingleComputedValue {
self.${longhand.ident}.0[index].clone()
}
% endif
% endfor
% if style_struct.trait_name == "Border":
% for side in ["top", "right", "bottom", "left"]:
fn border_${side}_has_nonzero_width(&self) -> bool {
self.border_${side}_width != ::app_units::Au(0)
}
% endfor
% elif style_struct.trait_name == "Font":
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.trait_name == "Outline":
#[inline]
fn outline_has_nonzero_width(&self) -> bool {
self.outline_width != ::app_units::Au(0)
}
% elif style_struct.trait_name == "Text":
<% text_decoration_field = 'text_decoration' if product == 'servo' else 'text_decoration_line' %>
#[inline]
fn has_underline(&self) -> bool {
self.${text_decoration_field}.underline
}
#[inline]
fn has_overline(&self) -> bool {
self.${text_decoration_field}.overline
}
#[inline]
fn has_line_through(&self) -> bool {
self.${text_decoration_field}.line_through
}
% endif
}
% endfor
}
pub trait ComputedValues : Debug + Clone + Send + Sync + 'static {
% for style_struct in data.active_style_structs():
type Concrete${style_struct.trait_name}: style_struct_traits::${style_struct.trait_name};
% endfor
fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
shareable: bool,
writing_mode: WritingMode,
root_font_size: Au,
% for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<Self::Concrete${style_struct.trait_name}>,
% endfor
) -> Self;
fn style_for_child_text_node(parent: &Arc<Self>) -> Arc<Self>;
fn initial_values() -> &'static Self;
fn do_cascade_property<F: FnOnce(&[CascadePropertyFn<Self>])>(f: F);
% for style_struct in data.active_style_structs():
fn clone_${style_struct.trait_name_lower}(&self) ->
Arc<Self::Concrete${style_struct.trait_name}>;
fn get_${style_struct.trait_name_lower}<'a>(&'a self) ->
&'a Self::Concrete${style_struct.trait_name};
fn mutate_${style_struct.trait_name_lower}<'a>(&'a mut self) ->
&'a mut Self::Concrete${style_struct.trait_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, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct ServoComputedValues {
% for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.servo_struct_name}>,
% endfor % endfor
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>, custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
shareable: bool, shareable: bool,
@ -1304,20 +1259,17 @@ pub struct ServoComputedValues {
pub root_font_size: Au, pub root_font_size: Au,
} }
impl ComputedValues for ServoComputedValues { #[cfg(feature = "servo")]
% for style_struct in data.active_style_structs(): impl ComputedValues {
type Concrete${style_struct.trait_name} = style_structs::${style_struct.servo_struct_name}; pub fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
% endfor
fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
shareable: bool, shareable: bool,
writing_mode: WritingMode, writing_mode: WritingMode,
root_font_size: Au, root_font_size: Au,
% for style_struct in data.active_style_structs(): % for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.servo_struct_name}>, ${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor % endfor
) -> Self { ) -> Self {
ServoComputedValues { ComputedValues {
custom_properties: custom_properties, custom_properties: custom_properties,
shareable: shareable, shareable: shareable,
writing_mode: writing_mode, writing_mode: writing_mode,
@ -1328,7 +1280,7 @@ impl ComputedValues for ServoComputedValues {
} }
} }
fn style_for_child_text_node(parent: &Arc<Self>) -> Arc<Self> { pub fn style_for_child_text_node(parent: &Arc<Self>) -> Arc<Self> {
// Text nodes get a copy of the parent style. Inheriting all non- // Text nodes get a copy of the parent style. Inheriting all non-
// inherited properties into the text node is odd from a CSS // inherited properties into the text node is odd from a CSS
// perspective, but makes fragment construction easier (by making // perspective, but makes fragment construction easier (by making
@ -1340,49 +1292,44 @@ impl ComputedValues for ServoComputedValues {
parent.clone() parent.clone()
} }
fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES } pub fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
#[inline] #[inline]
fn do_cascade_property<F: FnOnce(&[CascadePropertyFn<Self>])>(f: F) { pub fn do_cascade_property<F: FnOnce(&[CascadePropertyFn])>(f: F) {
f(&CASCADE_PROPERTY) f(&CASCADE_PROPERTY)
} }
% for style_struct in data.active_style_structs(): % for style_struct in data.active_style_structs():
#[inline] #[inline]
fn clone_${style_struct.trait_name_lower}(&self) -> pub fn clone_${style_struct.name_lower}(&self) -> Arc<style_structs::${style_struct.name}> {
Arc<Self::Concrete${style_struct.trait_name}> {
self.${style_struct.ident}.clone() self.${style_struct.ident}.clone()
} }
#[inline] #[inline]
fn get_${style_struct.trait_name_lower}<'a>(&'a self) -> pub fn get_${style_struct.name_lower}(&self) -> &style_structs::${style_struct.name} {
&'a Self::Concrete${style_struct.trait_name} {
&self.${style_struct.ident} &self.${style_struct.ident}
} }
#[inline] #[inline]
fn mutate_${style_struct.trait_name_lower}<'a>(&'a mut self) -> pub fn mutate_${style_struct.name_lower}(&mut self) -> &mut style_structs::${style_struct.name} {
&'a mut Self::Concrete${style_struct.trait_name} {
Arc::make_mut(&mut self.${style_struct.ident}) Arc::make_mut(&mut self.${style_struct.ident})
} }
% endfor % endfor
// Cloning the Arc here is fine because it only happens in the case where we have custom // 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. // properties, and those are both rare and expensive.
fn custom_properties(&self) -> Option<Arc<::custom_properties::ComputedValuesMap>> { pub fn custom_properties(&self) -> Option<Arc<::custom_properties::ComputedValuesMap>> {
self.custom_properties.as_ref().map(|x| x.clone()) self.custom_properties.as_ref().map(|x| x.clone())
} }
fn root_font_size(&self) -> Au { self.root_font_size } pub fn root_font_size(&self) -> Au { self.root_font_size }
fn set_root_font_size(&mut self, size: Au) { self.root_font_size = size } pub 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; } pub fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; }
#[inline] #[inline]
fn is_multicol(&self) -> bool { pub fn is_multicol(&self) -> bool {
let style = self.get_column(); let style = self.get_column();
style.column_count.0.is_some() || style.column_width.0.is_some() style.column_count.0.is_some() || style.column_width.0.is_some()
} }
}
impl ServoComputedValues {
/// Resolves the currentColor keyword. /// Resolves the currentColor keyword.
/// Any color value form computed values (except for the 'color' property itself) /// Any color value form computed values (except for the 'color' property itself)
/// should go through this method. /// should go through this method.
@ -1483,7 +1430,7 @@ impl ServoComputedValues {
} }
#[inline] #[inline]
pub fn get_font_arc(&self) -> Arc<style_structs::ServoFont> { pub fn get_font_arc(&self) -> Arc<style_structs::Font> {
self.font.clone() self.font.clone()
} }
@ -1566,7 +1513,7 @@ impl ServoComputedValues {
/// Return a WritingMode bitflags from the relevant CSS properties. /// Return a WritingMode bitflags from the relevant CSS properties.
pub fn get_writing_mode<S: style_struct_traits::InheritedBox>(inheritedbox_style: &S) -> WritingMode { pub fn get_writing_mode(inheritedbox_style: &style_structs::InheritedBox) -> WritingMode {
use logical_geometry; use logical_geometry;
let mut flags = WritingMode::empty(); let mut flags = WritingMode::empty();
match inheritedbox_style.clone_direction() { match inheritedbox_style.clone_direction() {
@ -1607,15 +1554,25 @@ pub fn get_writing_mode<S: style_struct_traits::InheritedBox>(inheritedbox_style
} }
/// The initial values for all style structs as defined by the specification. #[cfg(feature = "servo")]
lazy_static! { pub use self::lazy_static_module::INITIAL_SERVO_VALUES;
pub static ref INITIAL_SERVO_VALUES: ServoComputedValues = ServoComputedValues {
// Use a module to work around #[cfg] on lazy_static! not being applied to every generated item.
#[cfg(feature = "servo")]
mod lazy_static_module {
use logical_geometry::WritingMode;
use std::sync::Arc;
use super::{ComputedValues, longhands, style_structs};
/// The initial values for all style structs as defined by the specification.
lazy_static! {
pub static ref INITIAL_SERVO_VALUES: ComputedValues = ComputedValues {
% for style_struct in data.active_style_structs(): % for style_struct in data.active_style_structs():
${style_struct.ident}: Arc::new(style_structs::${style_struct.servo_struct_name} { ${style_struct.ident}: Arc::new(style_structs::${style_struct.name} {
% for longhand in style_struct.longhands: % for longhand in style_struct.longhands:
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(), ${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
% endfor % endfor
% if style_struct.trait_name == "Font": % if style_struct.name == "Font":
hash: 0, hash: 0,
% endif % endif
}), }),
@ -1625,25 +1582,25 @@ lazy_static! {
writing_mode: WritingMode::empty(), writing_mode: WritingMode::empty(),
root_font_size: longhands::font_size::get_initial_value(), root_font_size: longhands::font_size::get_initial_value(),
}; };
}
} }
/// Fast path for the function below. Only computes new inherited styles. /// Fast path for the function below. Only computes new inherited styles.
#[allow(unused_mut, unused_imports)] #[allow(unused_mut, unused_imports)]
fn cascade_with_cached_declarations<C: ComputedValues>( fn cascade_with_cached_declarations(
viewport_size: Size2D<Au>, viewport_size: Size2D<Au>,
applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>], applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>],
shareable: bool, shareable: bool,
parent_style: &C, parent_style: &ComputedValues,
cached_style: &C, cached_style: &ComputedValues,
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>, custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
mut error_reporter: StdBox<ParseErrorReporter + Send>) mut error_reporter: StdBox<ParseErrorReporter + Send>)
-> C { -> ComputedValues {
let mut context = computed::Context { let mut context = computed::Context {
is_root_element: false, is_root_element: false,
viewport_size: viewport_size, viewport_size: viewport_size,
inherited_style: parent_style, inherited_style: parent_style,
style: C::new( style: ComputedValues::new(
custom_properties, custom_properties,
shareable, shareable,
WritingMode::empty(), WritingMode::empty(),
@ -1654,7 +1611,7 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
% else: % else:
cached_style cached_style
% endif % endif
.clone_${style_struct.trait_name_lower}(), .clone_${style_struct.name_lower}(),
% endfor % endfor
), ),
}; };
@ -1671,7 +1628,6 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
PropertyDeclaration::${property.camel_case}(ref PropertyDeclaration::${property.camel_case}(ref
${'_' if not style_struct.inherited else ''}declared_value) ${'_' if not style_struct.inherited else ''}declared_value)
=> { => {
use properties::style_struct_traits::${style_struct.trait_name};
% if style_struct.inherited: % if style_struct.inherited:
if seen.get_${property.ident}() { if seen.get_${property.ident}() {
continue continue
@ -1684,14 +1640,14 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
DeclaredValue::Value(ref specified_value) DeclaredValue::Value(ref specified_value)
=> { => {
let computed = specified_value.to_computed_value(&context); let computed = specified_value.to_computed_value(&context);
context.mutate_style().mutate_${style_struct.trait_name_lower}() context.mutate_style().mutate_${style_struct.name_lower}()
.set_${property.ident}(computed); .set_${property.ident}(computed);
}, },
DeclaredValue::Initial DeclaredValue::Initial
=> { => {
// FIXME(bholley): We may want set_X_to_initial_value() here. // FIXME(bholley): We may want set_X_to_initial_value() here.
let initial = longhands::${property.ident}::get_initial_value(); let initial = longhands::${property.ident}::get_initial_value();
context.mutate_style().mutate_${style_struct.trait_name_lower}() context.mutate_style().mutate_${style_struct.name_lower}()
.set_${property.ident}(initial); .set_${property.ident}(initial);
}, },
DeclaredValue::Inherit => { DeclaredValue::Inherit => {
@ -1700,7 +1656,7 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
// //
// FIXME: is it still? // FIXME: is it still?
let inherited_struct = parent_style.get_${style_struct.ident}(); let inherited_struct = parent_style.get_${style_struct.ident}();
context.mutate_style().mutate_${style_struct.trait_name_lower}() context.mutate_style().mutate_${style_struct.name_lower}()
.copy_${property.ident}_from(inherited_struct); .copy_${property.ident}_from(inherited_struct);
} }
DeclaredValue::WithVariables { .. } => unreachable!() DeclaredValue::WithVariables { .. } => unreachable!()
@ -1729,22 +1685,22 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() || if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() ||
seen.get_font_family() { seen.get_font_family() {
use properties::style_struct_traits::Font;
context.mutate_style().mutate_font().compute_font_hash(); context.mutate_style().mutate_font().compute_font_hash();
} }
context.style context.style
} }
pub type CascadePropertyFn<C /*: ComputedValues */> = pub type CascadePropertyFn =
extern "Rust" fn(declaration: &PropertyDeclaration, extern "Rust" fn(declaration: &PropertyDeclaration,
inherited_style: &C, inherited_style: &ComputedValues,
context: &mut computed::Context<C>, context: &mut computed::Context,
seen: &mut PropertyBitField, seen: &mut PropertyBitField,
cacheable: &mut bool, cacheable: &mut bool,
error_reporter: &mut StdBox<ParseErrorReporter + Send>); error_reporter: &mut StdBox<ParseErrorReporter + Send>);
static CASCADE_PROPERTY: [CascadePropertyFn<ServoComputedValues>; ${len(data.longhands)}] = [ #[cfg(feature = "servo")]
static CASCADE_PROPERTY: [CascadePropertyFn; ${len(data.longhands)}] = [
% for property in data.longhands: % for property in data.longhands:
longhands::${property.ident}::cascade_property, longhands::${property.ident}::cascade_property,
% endfor % endfor
@ -1768,16 +1724,14 @@ static CASCADE_PROPERTY: [CascadePropertyFn<ServoComputedValues>; ${len(data.lon
/// this is ignored. /// this is ignored.
/// ///
/// Returns the computed values and a boolean indicating whether the result is cacheable. /// Returns the computed values and a boolean indicating whether the result is cacheable.
pub fn cascade<C: ComputedValues>( pub fn cascade(viewport_size: Size2D<Au>,
viewport_size: Size2D<Au>,
applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>], applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>],
shareable: bool, shareable: bool,
parent_style: Option<<&C>, parent_style: Option<<&ComputedValues>,
cached_style: Option<<&C>, cached_style: Option<<&ComputedValues>,
mut error_reporter: StdBox<ParseErrorReporter + Send>) mut error_reporter: StdBox<ParseErrorReporter + Send>)
-> (C, bool) { -> (ComputedValues, bool) {
use properties::style_struct_traits::{Border, Box, Font, Outline}; let initial_values = ComputedValues::initial_values();
let initial_values = C::initial_values();
let (is_root_element, inherited_style) = match parent_style { let (is_root_element, inherited_style) = match parent_style {
Some(parent_style) => (false, parent_style), Some(parent_style) => (false, parent_style),
None => (true, initial_values), None => (true, initial_values),
@ -1817,7 +1771,7 @@ pub fn cascade<C: ComputedValues>(
is_root_element: is_root_element, is_root_element: is_root_element,
viewport_size: viewport_size, viewport_size: viewport_size,
inherited_style: inherited_style, inherited_style: inherited_style,
style: C::new( style: ComputedValues::new(
custom_properties, custom_properties,
shareable, shareable,
WritingMode::empty(), WritingMode::empty(),
@ -1828,7 +1782,7 @@ pub fn cascade<C: ComputedValues>(
% else: % else:
initial_values initial_values
% endif % endif
.clone_${style_struct.trait_name_lower}(), .clone_${style_struct.name_lower}(),
% endfor % endfor
), ),
}; };
@ -1842,7 +1796,7 @@ pub fn cascade<C: ComputedValues>(
// We could (and used to) use a pattern match here, but that bloats this function to over 100K // 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 // of compiled code! To improve i-cache behavior, we outline the individual functions and use
// virtual dispatch instead. // virtual dispatch instead.
C::do_cascade_property(|cascade_property| { ComputedValues::do_cascade_property(|cascade_property| {
% for category_to_cascade_now in ["early", "other"]: % for category_to_cascade_now in ["early", "other"]:
for sub_list in applicable_declarations.iter().rev() { for sub_list in applicable_declarations.iter().rev() {
// Declarations are already stored in reverse order. // Declarations are already stored in reverse order.
@ -1940,7 +1894,6 @@ pub fn cascade<C: ComputedValues>(
% if "align-items" in data.longhands_by_name: % if "align-items" in data.longhands_by_name:
{ {
use self::style_struct_traits::Position;
use computed_values::align_self::T as align_self; use computed_values::align_self::T as align_self;
use computed_values::align_items::T as align_items; use computed_values::align_items::T as align_items;
if style.get_position().clone_align_self() == computed_values::align_self::T::auto && !positioned { if style.get_position().clone_align_self() == computed_values::align_self::T::auto && !positioned {
@ -1979,7 +1932,6 @@ pub fn cascade<C: ComputedValues>(
if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() || if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() ||
seen.get_font_family() { seen.get_font_family() {
use properties::style_struct_traits::Font;
style.mutate_font().compute_font_hash(); style.mutate_font().compute_font_hash();
} }
@ -1988,7 +1940,8 @@ pub fn cascade<C: ComputedValues>(
(style, cacheable) (style, cacheable)
} }
pub fn modify_style_for_anonymous_flow(style: &mut Arc<ServoComputedValues>, #[cfg(feature = "servo")]
pub fn modify_style_for_anonymous_flow(style: &mut Arc<ComputedValues>,
new_display_value: longhands::display::computed_value::T) { new_display_value: longhands::display::computed_value::T) {
// The 'align-self' property needs some special treatment since // The 'align-self' property needs some special treatment since
// its value depends on the 'align-items' value of its parent. // its value depends on the 'align-items' value of its parent.
@ -2008,7 +1961,7 @@ pub fn modify_style_for_anonymous_flow(style: &mut Arc<ServoComputedValues>,
let mut style = Arc::make_mut(style); let mut style = Arc::make_mut(style);
% for style_struct in data.active_style_structs(): % for style_struct in data.active_style_structs():
% if not style_struct.inherited: % if not style_struct.inherited:
style.${style_struct.ident} = inital_values.clone_${style_struct.trait_name_lower}(); style.${style_struct.ident} = inital_values.clone_${style_struct.name_lower}();
% endif % endif
% endfor % endfor
% if "align-items" in data.longhands_by_name: % if "align-items" in data.longhands_by_name:
@ -2035,8 +1988,9 @@ pub fn modify_style_for_anonymous_flow(style: &mut Arc<ServoComputedValues>,
/// `vertical-align: top` style of `sup` must not propagate down into `Foo`). /// `vertical-align: top` style of `sup` must not propagate down into `Foo`).
/// ///
/// FIXME(#5625, pcwalton): It would probably be cleaner and faster to do this in the cascade. /// FIXME(#5625, pcwalton): It would probably be cleaner and faster to do this in the cascade.
#[cfg(feature = "servo")]
#[inline] #[inline]
pub fn modify_style_for_replaced_content(style: &mut Arc<ServoComputedValues>) { pub fn modify_style_for_replaced_content(style: &mut Arc<ComputedValues>) {
// Reset `position` to handle cases like `<div style="position: absolute">foo bar baz</div>`. // Reset `position` to handle cases like `<div style="position: absolute">foo bar baz</div>`.
if style.box_.display != longhands::display::computed_value::T::inline { if style.box_.display != longhands::display::computed_value::T::inline {
let mut style = Arc::make_mut(style); let mut style = Arc::make_mut(style);
@ -2071,11 +2025,12 @@ pub fn modify_style_for_replaced_content(style: &mut Arc<ServoComputedValues>) {
/// ///
/// Specifically, this function sets border widths to zero on the sides for which the fragment is /// Specifically, this function sets border widths to zero on the sides for which the fragment is
/// not outermost. /// not outermost.
#[cfg(feature = "servo")]
#[inline] #[inline]
pub fn modify_border_style_for_inline_sides(style: &mut Arc<ServoComputedValues>, pub fn modify_border_style_for_inline_sides(style: &mut Arc<ComputedValues>,
is_first_fragment_of_element: bool, is_first_fragment_of_element: bool,
is_last_fragment_of_element: bool) { is_last_fragment_of_element: bool) {
fn modify_side(style: &mut Arc<ServoComputedValues>, side: PhysicalSide) { fn modify_side(style: &mut Arc<ComputedValues>, side: PhysicalSide) {
{ {
let border = &style.border; let border = &style.border;
let current_style = match side { let current_style = match side {
@ -2122,9 +2077,10 @@ pub fn modify_border_style_for_inline_sides(style: &mut Arc<ServoComputedValues>
} }
/// Adjusts the display and position properties as appropriate for an anonymous table object. /// Adjusts the display and position properties as appropriate for an anonymous table object.
#[cfg(feature = "servo")]
#[inline] #[inline]
pub fn modify_style_for_anonymous_table_object( pub fn modify_style_for_anonymous_table_object(
style: &mut Arc<ServoComputedValues>, style: &mut Arc<ComputedValues>,
new_display_value: longhands::display::computed_value::T) { new_display_value: longhands::display::computed_value::T) {
let mut style = Arc::make_mut(style); let mut style = Arc::make_mut(style);
let box_style = Arc::make_mut(&mut style.box_); let box_style = Arc::make_mut(&mut style.box_);
@ -2133,8 +2089,9 @@ pub fn modify_style_for_anonymous_table_object(
} }
/// Adjusts the `position` property as necessary for the outer fragment wrapper of an inline-block. /// Adjusts the `position` property as necessary for the outer fragment wrapper of an inline-block.
#[cfg(feature = "servo")]
#[inline] #[inline]
pub fn modify_style_for_outer_inline_block_fragment(style: &mut Arc<ServoComputedValues>) { pub fn modify_style_for_outer_inline_block_fragment(style: &mut Arc<ComputedValues>) {
let mut style = Arc::make_mut(style); let mut style = Arc::make_mut(style);
let box_style = Arc::make_mut(&mut style.box_); let box_style = Arc::make_mut(&mut style.box_);
box_style.position = longhands::position::computed_value::T::static_ box_style.position = longhands::position::computed_value::T::static_
@ -2144,8 +2101,9 @@ pub fn modify_style_for_outer_inline_block_fragment(style: &mut Arc<ServoCompute
/// ///
/// Text is never directly relatively positioned; it's always contained within an element that is /// Text is never directly relatively positioned; it's always contained within an element that is
/// itself relatively positioned. /// itself relatively positioned.
#[cfg(feature = "servo")]
#[inline] #[inline]
pub fn modify_style_for_text(style: &mut Arc<ServoComputedValues>) { pub fn modify_style_for_text(style: &mut Arc<ComputedValues>) {
if style.box_.position == longhands::position::computed_value::T::relative { if style.box_.position == longhands::position::computed_value::T::relative {
// We leave the `position` property set to `relative` so that we'll still establish a // We leave the `position` property set to `relative` so that we'll still establish a
// containing block if needed. But we reset all position offsets to `auto`. // containing block if needed. But we reset all position offsets to `auto`.
@ -2180,7 +2138,8 @@ pub fn modify_style_for_text(style: &mut Arc<ServoComputedValues>) {
/// ///
/// Margins apply to the `input` element itself, so including them in the text will cause them to /// Margins apply to the `input` element itself, so including them in the text will cause them to
/// be double-counted. /// be double-counted.
pub fn modify_style_for_input_text(style: &mut Arc<ServoComputedValues>) { #[cfg(feature = "servo")]
pub fn modify_style_for_input_text(style: &mut Arc<ComputedValues>) {
let mut style = Arc::make_mut(style); let mut style = Arc::make_mut(style);
let margin_style = Arc::make_mut(&mut style.margin); let margin_style = Arc::make_mut(&mut style.margin);
margin_style.margin_top = computed::LengthOrPercentageOrAuto::Length(Au(0)); margin_style.margin_top = computed::LengthOrPercentageOrAuto::Length(Au(0));
@ -2195,7 +2154,8 @@ pub fn modify_style_for_input_text(style: &mut Arc<ServoComputedValues>) {
/// Adjusts the `clip` property so that an inline absolute hypothetical fragment doesn't clip its /// Adjusts the `clip` property so that an inline absolute hypothetical fragment doesn't clip its
/// children. /// children.
pub fn modify_style_for_inline_absolute_hypothetical_fragment(style: &mut Arc<ServoComputedValues>) { #[cfg(feature = "servo")]
pub fn modify_style_for_inline_absolute_hypothetical_fragment(style: &mut Arc<ComputedValues>) {
if style.get_effects().clip.0.is_some() { if style.get_effects().clip.0.is_some() {
let mut style = Arc::make_mut(style); let mut style = Arc::make_mut(style);
let effects_style = Arc::make_mut(&mut style.effects); let effects_style = Arc::make_mut(&mut style.effects);

View file

@ -6,10 +6,11 @@
use attr::{AttrIdentifier, AttrValue}; use attr::{AttrIdentifier, AttrValue};
use element_state::*; use element_state::*;
use selector_impl::SelectorImplExt; use selector_impl::{SelectorImplExt, TheSelectorImpl, AttrString};
use selectors::matching::matches_compound_selector; use selectors::matching::matches_compound_selector;
use selectors::parser::{AttrSelector, Combinator, CompoundSelector, SelectorImpl, SimpleSelector}; use selectors::parser::{AttrSelector, Combinator, CompoundSelector, SelectorImpl, SimpleSelector};
use selectors::{Element, MatchAttrGeneric}; use selectors::{Element, MatchAttrGeneric};
#[cfg(feature = "gecko")] use selectors::MatchAttr;
use std::clone::Clone; use std::clone::Clone;
use std::sync::Arc; use std::sync::Arc;
use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace}; use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace};
@ -88,14 +89,14 @@ static EMPTY_SNAPSHOT: ElementSnapshot = ElementSnapshot { state: None, attrs: N
// geckolib, but in the mean time we can just use the trait parameters to // geckolib, but in the mean time we can just use the trait parameters to
// specialize it to the Servo configuration. // specialize it to the Servo configuration.
struct ElementWrapper<'a, E> struct ElementWrapper<'a, E>
where E: Element<AttrString=String>, where E: Element<AttrString=AttrString>,
E::Impl: SelectorImplExt { E::Impl: SelectorImplExt {
element: E, element: E,
snapshot: &'a ElementSnapshot, snapshot: &'a ElementSnapshot,
} }
impl<'a, E> ElementWrapper<'a, E> impl<'a, E> ElementWrapper<'a, E>
where E: Element<AttrString=String>, where E: Element<AttrString=AttrString>,
E::Impl: SelectorImplExt { E::Impl: SelectorImplExt {
pub fn new(el: E) -> ElementWrapper<'a, E> { pub fn new(el: E) -> ElementWrapper<'a, E> {
ElementWrapper { element: el, snapshot: &EMPTY_SNAPSHOT } ElementWrapper { element: el, snapshot: &EMPTY_SNAPSHOT }
@ -108,7 +109,7 @@ impl<'a, E> ElementWrapper<'a, E>
#[cfg(not(feature = "gecko"))] #[cfg(not(feature = "gecko"))]
impl<'a, E> MatchAttrGeneric for ElementWrapper<'a, E> impl<'a, E> MatchAttrGeneric for ElementWrapper<'a, E>
where E: Element<AttrString=String>, where E: Element<AttrString=AttrString>,
E: MatchAttrGeneric, E: MatchAttrGeneric,
E::Impl: SelectorImplExt { E::Impl: SelectorImplExt {
fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool
@ -129,18 +130,46 @@ impl<'a, E> MatchAttrGeneric for ElementWrapper<'a, E>
} }
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
impl<'a, E> MatchAttrGeneric for ElementWrapper<'a, E> impl<'a, E> MatchAttr for ElementWrapper<'a, E>
where E: Element<AttrString=String>, where E: Element<AttrString=AttrString>,
E: MatchAttrGeneric,
E::Impl: SelectorImplExt { E::Impl: SelectorImplExt {
fn match_attr<F>(&self, _: &AttrSelector, _: F) -> bool type AttrString = AttrString;
where F: Fn(&str) -> bool {
fn match_attr_has(&self, _attr: &AttrSelector) -> bool {
panic!("Not implemented for Gecko - this system will need to be redesigned");
}
fn match_attr_equals(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
panic!("Not implemented for Gecko - this system will need to be redesigned");
}
fn match_attr_equals_ignore_ascii_case(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
panic!("Not implemented for Gecko - this system will need to be redesigned");
}
fn match_attr_includes(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
panic!("Not implemented for Gecko - this system will need to be redesigned");
}
fn match_attr_dash(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
panic!("Not implemented for Gecko - this system will need to be redesigned");
}
fn match_attr_prefix(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
panic!("Not implemented for Gecko - this system will need to be redesigned");
}
fn match_attr_substring(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
panic!("Not implemented for Gecko - this system will need to be redesigned");
}
fn match_attr_suffix(&self, _attr: &AttrSelector, _value: &Self::AttrString) -> bool {
panic!("Not implemented for Gecko - this system will need to be redesigned"); panic!("Not implemented for Gecko - this system will need to be redesigned");
} }
} }
impl<'a, E> Element for ElementWrapper<'a, E> impl<'a, E> Element for ElementWrapper<'a, E>
where E: Element<AttrString=String>, where E: Element<AttrString=AttrString>,
E: MatchAttrGeneric, E: MatchAttrGeneric,
E::Impl: SelectorImplExt { E::Impl: SelectorImplExt {
type Impl = E::Impl; type Impl = E::Impl;
@ -213,14 +242,14 @@ impl<'a, E> Element for ElementWrapper<'a, E>
} }
} }
fn selector_to_state<Impl: SelectorImplExt>(sel: &SimpleSelector<Impl>) -> ElementState { fn selector_to_state(sel: &SimpleSelector<TheSelectorImpl>) -> ElementState {
match *sel { match *sel {
SimpleSelector::NonTSPseudoClass(ref pc) => Impl::pseudo_class_state_flag(pc), SimpleSelector::NonTSPseudoClass(ref pc) => TheSelectorImpl::pseudo_class_state_flag(pc),
_ => ElementState::empty(), _ => ElementState::empty(),
} }
} }
fn is_attr_selector<Impl: SelectorImpl>(sel: &SimpleSelector<Impl>) -> bool { fn is_attr_selector(sel: &SimpleSelector<TheSelectorImpl>) -> bool {
match *sel { match *sel {
SimpleSelector::ID(_) | SimpleSelector::ID(_) |
SimpleSelector::Class(_) | SimpleSelector::Class(_) |
@ -287,24 +316,24 @@ impl Sensitivities {
// elements in the document. // elements in the document.
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
struct Dependency<Impl: SelectorImplExt> { struct Dependency {
selector: Arc<CompoundSelector<Impl>>, selector: Arc<CompoundSelector<TheSelectorImpl>>,
combinator: Option<Combinator>, combinator: Option<Combinator>,
sensitivities: Sensitivities, sensitivities: Sensitivities,
} }
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct DependencySet<Impl: SelectorImplExt> { pub struct DependencySet {
deps: Vec<Dependency<Impl>>, deps: Vec<Dependency>,
} }
impl<Impl: SelectorImplExt> DependencySet<Impl> { impl DependencySet {
pub fn new() -> DependencySet<Impl> { pub fn new() -> Self {
DependencySet { deps: Vec::new() } DependencySet { deps: Vec::new() }
} }
pub fn note_selector(&mut self, selector: Arc<CompoundSelector<Impl>>) { pub fn note_selector(&mut self, selector: Arc<CompoundSelector<TheSelectorImpl>>) {
let mut cur = selector; let mut cur = selector;
let mut combinator: Option<Combinator> = None; let mut combinator: Option<Combinator> = None;
loop { loop {
@ -338,10 +367,10 @@ impl<Impl: SelectorImplExt> DependencySet<Impl> {
} }
} }
impl<Impl: SelectorImplExt<AttrString=String>> DependencySet<Impl> { impl DependencySet {
pub fn compute_hint<E>(&self, el: &E, snapshot: &ElementSnapshot, current_state: ElementState) pub fn compute_hint<E>(&self, el: &E, snapshot: &ElementSnapshot, current_state: ElementState)
-> RestyleHint -> RestyleHint
where E: Element<Impl=Impl, AttrString=Impl::AttrString> + Clone + MatchAttrGeneric { where E: Element<Impl=TheSelectorImpl, AttrString=AttrString> + Clone + MatchAttrGeneric {
let state_changes = snapshot.state.map_or(ElementState::empty(), |old_state| current_state ^ old_state); let state_changes = snapshot.state.map_or(ElementState::empty(), |old_state| current_state ^ old_state);
let attrs_changed = snapshot.attrs.is_some(); let attrs_changed = snapshot.attrs.is_some();
let mut hint = RestyleHint::empty(); let mut hint = RestyleHint::empty();

View file

@ -5,13 +5,22 @@
//! The pseudo-classes and pseudo-elements supported by the style system. //! The pseudo-classes and pseudo-elements supported by the style system.
use element_state::ElementState; use element_state::ElementState;
use properties::{self, ServoComputedValues};
use selector_matching::{USER_OR_USER_AGENT_STYLESHEETS, QUIRKS_MODE_STYLESHEET};
use selectors::Element; use selectors::Element;
use selectors::parser::{ParserContext, SelectorImpl}; use selectors::parser::SelectorImpl;
use std::fmt::Debug; use std::fmt::Debug;
use stylesheets::Stylesheet; use stylesheets::Stylesheet;
pub type AttrString = <TheSelectorImpl as SelectorImpl>::AttrString;
#[cfg(feature = "servo")]
pub use servo_selector_impl::ServoSelectorImpl;
#[cfg(feature = "servo")]
pub use servo_selector_impl::{ServoSelectorImpl as TheSelectorImpl, PseudoElement, NonTSPseudoClass};
#[cfg(feature = "gecko")]
pub use gecko_selector_impl::{GeckoSelectorImpl as TheSelectorImpl, PseudoElement, NonTSPseudoClass};
/// This function determines if a pseudo-element is eagerly cascaded or not. /// This function determines if a pseudo-element is eagerly cascaded or not.
/// ///
/// Eagerly cascaded pseudo-elements are "normal" pseudo-elements (i.e. /// Eagerly cascaded pseudo-elements are "normal" pseudo-elements (i.e.
@ -59,15 +68,13 @@ impl PseudoElementCascadeType {
} }
} }
pub trait ElementExt: Element { pub trait ElementExt: Element<Impl=TheSelectorImpl, AttrString=<TheSelectorImpl as SelectorImpl>::AttrString> {
fn is_link(&self) -> bool; fn is_link(&self) -> bool;
} }
// NB: The `Clone` trait is here for convenience due to: // NB: The `Clone` trait is here for convenience due to:
// https://github.com/rust-lang/rust/issues/26925 // https://github.com/rust-lang/rust/issues/26925
pub trait SelectorImplExt : SelectorImpl + Clone + Debug + Sized + 'static { pub trait SelectorImplExt : SelectorImpl + Clone + Debug + Sized + 'static {
type ComputedValues: properties::ComputedValues;
fn pseudo_element_cascade_type(pseudo: &Self::PseudoElement) -> PseudoElementCascadeType; fn pseudo_element_cascade_type(pseudo: &Self::PseudoElement) -> PseudoElementCascadeType;
fn each_pseudo_element<F>(mut fun: F) fn each_pseudo_element<F>(mut fun: F)
@ -97,190 +104,7 @@ pub trait SelectorImplExt : SelectorImpl + Clone + Debug + Sized + 'static {
fn pseudo_class_state_flag(pc: &Self::NonTSPseudoClass) -> ElementState; fn pseudo_class_state_flag(pc: &Self::NonTSPseudoClass) -> ElementState;
fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet<Self>]; fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet];
fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet<Self>>; fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet>;
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum PseudoElement {
Before,
After,
Selection,
DetailsSummary,
DetailsContent,
}
impl PseudoElement {
#[inline]
pub fn is_before_or_after(&self) -> bool {
match *self {
PseudoElement::Before |
PseudoElement::After => true,
_ => false,
}
}
#[inline]
pub fn cascade_type(&self) -> PseudoElementCascadeType {
match *self {
PseudoElement::Before |
PseudoElement::After |
PseudoElement::Selection => PseudoElementCascadeType::Eager,
PseudoElement::DetailsSummary => PseudoElementCascadeType::Lazy,
PseudoElement::DetailsContent => PseudoElementCascadeType::Precomputed,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum NonTSPseudoClass {
AnyLink,
Link,
Visited,
Active,
Focus,
Hover,
Enabled,
Disabled,
Checked,
Indeterminate,
ServoNonZeroBorder,
ReadWrite,
ReadOnly,
PlaceholderShown,
}
impl NonTSPseudoClass {
pub fn state_flag(&self) -> ElementState {
use element_state::*;
use self::NonTSPseudoClass::*;
match *self {
Active => IN_ACTIVE_STATE,
Focus => IN_FOCUS_STATE,
Hover => IN_HOVER_STATE,
Enabled => IN_ENABLED_STATE,
Disabled => IN_DISABLED_STATE,
Checked => IN_CHECKED_STATE,
Indeterminate => IN_INDETERMINATE_STATE,
ReadOnly | ReadWrite => IN_READ_WRITE_STATE,
PlaceholderShown => IN_PLACEHOLDER_SHOWN_STATE,
AnyLink |
Link |
Visited |
ServoNonZeroBorder => ElementState::empty(),
}
}
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct ServoSelectorImpl;
impl SelectorImpl for ServoSelectorImpl {
type AttrString = String;
type PseudoElement = PseudoElement;
type NonTSPseudoClass = NonTSPseudoClass;
fn parse_non_ts_pseudo_class(context: &ParserContext,
name: &str) -> Result<NonTSPseudoClass, ()> {
use self::NonTSPseudoClass::*;
let pseudo_class = match_ignore_ascii_case! { name,
"any-link" => AnyLink,
"link" => Link,
"visited" => Visited,
"active" => Active,
"focus" => Focus,
"hover" => Hover,
"enabled" => Enabled,
"disabled" => Disabled,
"checked" => Checked,
"indeterminate" => Indeterminate,
"read-write" => ReadWrite,
"read-only" => ReadOnly,
"placeholder-shown" => PlaceholderShown,
"-servo-nonzero-border" => {
if !context.in_user_agent_stylesheet {
return Err(());
}
ServoNonZeroBorder
},
_ => return Err(())
};
Ok(pseudo_class)
}
fn parse_pseudo_element(context: &ParserContext,
name: &str) -> Result<PseudoElement, ()> {
use self::PseudoElement::*;
let pseudo_element = match_ignore_ascii_case! { name,
"before" => Before,
"after" => After,
"selection" => Selection,
"-servo-details-summary" => {
if !context.in_user_agent_stylesheet {
return Err(())
}
DetailsSummary
},
"-servo-details-content" => {
if !context.in_user_agent_stylesheet {
return Err(())
}
DetailsContent
},
_ => return Err(())
};
Ok(pseudo_element)
}
}
impl SelectorImplExt for ServoSelectorImpl {
type ComputedValues = ServoComputedValues;
#[inline]
fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType {
pseudo.cascade_type()
}
#[inline]
fn each_pseudo_element<F>(mut fun: F)
where F: FnMut(PseudoElement) {
fun(PseudoElement::Before);
fun(PseudoElement::After);
fun(PseudoElement::DetailsContent);
fun(PseudoElement::DetailsSummary);
fun(PseudoElement::Selection);
}
#[inline]
fn pseudo_class_state_flag(pc: &NonTSPseudoClass) -> ElementState {
pc.state_flag()
}
#[inline]
fn pseudo_is_before_or_after(pseudo: &PseudoElement) -> bool {
pseudo.is_before_or_after()
}
#[inline]
fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet<Self>] {
&*USER_OR_USER_AGENT_STYLESHEETS
}
#[inline]
fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet<Self>> {
Some(&*QUIRKS_MODE_STYLESHEET)
}
}
impl<E: Element<Impl=ServoSelectorImpl, AttrString=String>> ElementExt for E {
fn is_link(&self) -> bool {
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
}
} }

View file

@ -9,86 +9,26 @@ use element_state::*;
use error_reporting::StdoutErrorReporter; use error_reporting::StdoutErrorReporter;
use keyframes::KeyframesAnimation; use keyframes::KeyframesAnimation;
use media_queries::{Device, MediaType}; use media_queries::{Device, MediaType};
use parser::ParserContextExtraData; use properties::{self, PropertyDeclaration, PropertyDeclarationBlock, ComputedValues};
use properties::{self, PropertyDeclaration, PropertyDeclarationBlock};
use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet}; use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet};
use selector_impl::{SelectorImplExt, ServoSelectorImpl}; use selector_impl::{SelectorImplExt, TheSelectorImpl, PseudoElement, AttrString};
use selectors::bloom::BloomFilter; use selectors::bloom::BloomFilter;
use selectors::matching::DeclarationBlock as GenericDeclarationBlock; use selectors::matching::DeclarationBlock as GenericDeclarationBlock;
use selectors::matching::{Rule, SelectorMap}; use selectors::matching::{Rule, SelectorMap};
use selectors::parser::SelectorImpl;
use selectors::{Element, MatchAttrGeneric}; use selectors::{Element, MatchAttrGeneric};
use sink::Push; use sink::Push;
use smallvec::VecLike; use smallvec::VecLike;
use std::collections::HashMap; use std::collections::HashMap;
use std::hash::BuildHasherDefault; use std::hash::BuildHasherDefault;
use std::process;
use std::sync::Arc; use std::sync::Arc;
use string_cache::Atom; use string_cache::Atom;
use style_traits::viewport::ViewportConstraints; use style_traits::viewport::ViewportConstraints;
use stylesheets::{CSSRule, CSSRuleIteratorExt, Origin, Stylesheet}; use stylesheets::{CSSRule, CSSRuleIteratorExt, Origin, Stylesheet};
use url::Url;
use util::opts;
use util::resource_files::read_resource_file;
use viewport::{MaybeNew, ViewportRuleCascade}; use viewport::{MaybeNew, ViewportRuleCascade};
pub type DeclarationBlock = GenericDeclarationBlock<Vec<PropertyDeclaration>>; pub type DeclarationBlock = GenericDeclarationBlock<Vec<PropertyDeclaration>>;
lazy_static! {
pub static ref USER_OR_USER_AGENT_STYLESHEETS: Vec<Stylesheet<ServoSelectorImpl>> = {
let mut stylesheets = vec!();
// FIXME: presentational-hints.css should be at author origin with zero specificity.
// (Does it make a difference?)
for &filename in &["user-agent.css", "servo.css", "presentational-hints.css"] {
match read_resource_file(filename) {
Ok(res) => {
let ua_stylesheet = Stylesheet::from_bytes(
&res,
Url::parse(&format!("chrome://resources/{:?}", filename)).unwrap(),
None,
None,
Origin::UserAgent,
Box::new(StdoutErrorReporter),
ParserContextExtraData::default());
stylesheets.push(ua_stylesheet);
}
Err(..) => {
error!("Failed to load UA stylesheet {}!", filename);
process::exit(1);
}
}
}
for &(ref contents, ref url) in &opts::get().user_stylesheets {
stylesheets.push(Stylesheet::from_bytes(
&contents, url.clone(), None, None, Origin::User, Box::new(StdoutErrorReporter),
ParserContextExtraData::default()));
}
stylesheets
};
}
lazy_static! {
pub static ref QUIRKS_MODE_STYLESHEET: Stylesheet<ServoSelectorImpl> = {
match read_resource_file("quirks-mode.css") {
Ok(res) => {
Stylesheet::from_bytes(
&res,
Url::parse("chrome://resources/quirks-mode.css").unwrap(),
None,
None,
Origin::UserAgent,
Box::new(StdoutErrorReporter),
ParserContextExtraData::default())
},
Err(..) => {
error!("Stylist failed to load 'quirks-mode.css'!");
process::exit(1);
}
}
};
}
/// This structure holds all the selectors and device characteristics /// This structure holds all the selectors and device characteristics
/// for a given document. The selectors are converted into `Rule`s /// for a given document. The selectors are converted into `Rule`s
/// (defined in rust-selectors), and introduced in a `SelectorMap` /// (defined in rust-selectors), and introduced in a `SelectorMap`
@ -106,7 +46,7 @@ lazy_static! {
/// regular builds, or `GeckoSelectorImpl`, the implementation used in the /// regular builds, or `GeckoSelectorImpl`, the implementation used in the
/// geckolib port. /// geckolib port.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Stylist<Impl: SelectorImplExt> { pub struct Stylist {
/// Device that the stylist is currently evaluating against. /// Device that the stylist is currently evaluating against.
pub device: Device, pub device: Device,
@ -121,12 +61,12 @@ pub struct Stylist<Impl: SelectorImplExt> {
/// The current selector maps, after evaluating media /// The current selector maps, after evaluating media
/// rules against the current device. /// rules against the current device.
element_map: PerPseudoElementSelectorMap<Impl>, element_map: PerPseudoElementSelectorMap,
/// The selector maps corresponding to a given pseudo-element /// The selector maps corresponding to a given pseudo-element
/// (depending on the implementation) /// (depending on the implementation)
pseudos_map: HashMap<Impl::PseudoElement, pseudos_map: HashMap<PseudoElement,
PerPseudoElementSelectorMap<Impl>, PerPseudoElementSelectorMap,
BuildHasherDefault<::fnv::FnvHasher>>, BuildHasherDefault<::fnv::FnvHasher>>,
/// A map with all the animations indexed by name. /// A map with all the animations indexed by name.
@ -135,19 +75,19 @@ pub struct Stylist<Impl: SelectorImplExt> {
/// Applicable declarations for a given non-eagerly cascaded pseudo-element. /// Applicable declarations for a given non-eagerly cascaded pseudo-element.
/// These are eagerly computed once, and then used to resolve the new /// These are eagerly computed once, and then used to resolve the new
/// computed values on the fly on layout. /// computed values on the fly on layout.
precomputed_pseudo_element_decls: HashMap<Impl::PseudoElement, precomputed_pseudo_element_decls: HashMap<PseudoElement,
Vec<DeclarationBlock>, Vec<DeclarationBlock>,
BuildHasherDefault<::fnv::FnvHasher>>, BuildHasherDefault<::fnv::FnvHasher>>,
rules_source_order: usize, rules_source_order: usize,
/// Selector dependencies used to compute restyle hints. /// Selector dependencies used to compute restyle hints.
state_deps: DependencySet<Impl>, state_deps: DependencySet,
} }
impl<Impl: SelectorImplExt> Stylist<Impl> { impl Stylist {
#[inline] #[inline]
pub fn new(device: Device) -> Stylist<Impl> { pub fn new(device: Device) -> Self {
let mut stylist = Stylist { let mut stylist = Stylist {
viewport_constraints: None, viewport_constraints: None,
device: device, device: device,
@ -162,7 +102,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
state_deps: DependencySet::new(), state_deps: DependencySet::new(),
}; };
Impl::each_eagerly_cascaded_pseudo_element(|pseudo| { TheSelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
stylist.pseudos_map.insert(pseudo, PerPseudoElementSelectorMap::new()); stylist.pseudos_map.insert(pseudo, PerPseudoElementSelectorMap::new());
}); });
@ -171,9 +111,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
stylist stylist
} }
pub fn update(&mut self, doc_stylesheets: &[Arc<Stylesheet<Impl>>], pub fn update(&mut self, doc_stylesheets: &[Arc<Stylesheet>], stylesheets_changed: bool) -> bool {
stylesheets_changed: bool) -> bool
where Impl: 'static {
if !(self.is_device_dirty || stylesheets_changed) { if !(self.is_device_dirty || stylesheets_changed) {
return false; return false;
} }
@ -181,7 +119,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
self.element_map = PerPseudoElementSelectorMap::new(); self.element_map = PerPseudoElementSelectorMap::new();
self.pseudos_map = HashMap::with_hasher(Default::default()); self.pseudos_map = HashMap::with_hasher(Default::default());
self.animations = HashMap::with_hasher(Default::default()); self.animations = HashMap::with_hasher(Default::default());
Impl::each_eagerly_cascaded_pseudo_element(|pseudo| { TheSelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
self.pseudos_map.insert(pseudo, PerPseudoElementSelectorMap::new()); self.pseudos_map.insert(pseudo, PerPseudoElementSelectorMap::new());
}); });
@ -189,12 +127,12 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
self.rules_source_order = 0; self.rules_source_order = 0;
self.state_deps.clear(); self.state_deps.clear();
for ref stylesheet in Impl::get_user_or_user_agent_stylesheets().iter() { for ref stylesheet in TheSelectorImpl::get_user_or_user_agent_stylesheets().iter() {
self.add_stylesheet(&stylesheet); self.add_stylesheet(&stylesheet);
} }
if self.quirks_mode { if self.quirks_mode {
if let Some(s) = Impl::get_quirks_mode_stylesheet() { if let Some(s) = TheSelectorImpl::get_quirks_mode_stylesheet() {
self.add_stylesheet(s); self.add_stylesheet(s);
} }
} }
@ -207,7 +145,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
true true
} }
fn add_stylesheet(&mut self, stylesheet: &Stylesheet<Impl>) { fn add_stylesheet(&mut self, stylesheet: &Stylesheet) {
if !stylesheet.is_effective_for_device(&self.device) { if !stylesheet.is_effective_for_device(&self.device) {
return; return;
} }
@ -271,7 +209,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
} }
} }
Impl::each_precomputed_pseudo_element(|pseudo| { TheSelectorImpl::each_precomputed_pseudo_element(|pseudo| {
// TODO: Consider not doing this and just getting the rules on the // TODO: Consider not doing this and just getting the rules on the
// fly. It should be a bit slower, but we'd take rid of the // fly. It should be a bit slower, but we'd take rid of the
// extra field, and avoid this precomputation entirely. // extra field, and avoid this precomputation entirely.
@ -289,10 +227,10 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
/// Computes the style for a given "precomputed" pseudo-element, taking the /// Computes the style for a given "precomputed" pseudo-element, taking the
/// universal rules and applying them. /// universal rules and applying them.
pub fn precomputed_values_for_pseudo(&self, pub fn precomputed_values_for_pseudo(&self,
pseudo: &Impl::PseudoElement, pseudo: &PseudoElement,
parent: Option<&Arc<Impl::ComputedValues>>) parent: Option<&Arc<ComputedValues>>)
-> Option<Arc<Impl::ComputedValues>> { -> Option<Arc<ComputedValues>> {
debug_assert!(Impl::pseudo_element_cascade_type(pseudo).is_precomputed()); debug_assert!(TheSelectorImpl::pseudo_element_cascade_type(pseudo).is_precomputed());
if let Some(declarations) = self.precomputed_pseudo_element_decls.get(pseudo) { if let Some(declarations) = self.precomputed_pseudo_element_decls.get(pseudo) {
let (computed, _) = let (computed, _) =
properties::cascade(self.device.au_viewport_size(), properties::cascade(self.device.au_viewport_size(),
@ -308,12 +246,12 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
pub fn lazily_compute_pseudo_element_style<E>(&self, pub fn lazily_compute_pseudo_element_style<E>(&self,
element: &E, element: &E,
pseudo: &Impl::PseudoElement, pseudo: &PseudoElement,
parent: &Arc<Impl::ComputedValues>) parent: &Arc<ComputedValues>)
-> Option<Arc<Impl::ComputedValues>> -> Option<Arc<ComputedValues>>
where E: Element<Impl=Impl, AttrString=Impl::AttrString> + where E: Element<Impl=TheSelectorImpl, AttrString=AttrString> +
PresentationalHintsSynthetizer { PresentationalHintsSynthetizer {
debug_assert!(Impl::pseudo_element_cascade_type(pseudo).is_lazy()); debug_assert!(TheSelectorImpl::pseudo_element_cascade_type(pseudo).is_lazy());
if self.pseudos_map.get(pseudo).is_none() { if self.pseudos_map.get(pseudo).is_none() {
return None; return None;
} }
@ -336,7 +274,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
Some(Arc::new(computed)) Some(Arc::new(computed))
} }
pub fn set_device(&mut self, mut device: Device, stylesheets: &[Arc<Stylesheet<Impl>>]) { pub fn set_device(&mut self, mut device: Device, stylesheets: &[Arc<Stylesheet>]) {
let cascaded_rule = stylesheets.iter() let cascaded_rule = stylesheets.iter()
.flat_map(|s| s.effective_rules(&self.device).viewport()) .flat_map(|s| s.effective_rules(&self.device).viewport())
.cascade(); .cascade();
@ -374,17 +312,18 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
element: &E, element: &E,
parent_bf: Option<&BloomFilter>, parent_bf: Option<&BloomFilter>,
style_attribute: Option<&PropertyDeclarationBlock>, style_attribute: Option<&PropertyDeclarationBlock>,
pseudo_element: Option<&Impl::PseudoElement>, pseudo_element: Option<&PseudoElement>,
applicable_declarations: &mut V) applicable_declarations: &mut V)
-> bool -> bool
where E: Element<Impl=Impl, AttrString=Impl::AttrString> + where E: Element<Impl=TheSelectorImpl, AttrString=AttrString> +
PresentationalHintsSynthetizer, PresentationalHintsSynthetizer,
V: Push<DeclarationBlock> + VecLike<DeclarationBlock> { V: Push<DeclarationBlock> + VecLike<DeclarationBlock> {
assert!(!self.is_device_dirty); assert!(!self.is_device_dirty);
assert!(style_attribute.is_none() || pseudo_element.is_none(), assert!(style_attribute.is_none() || pseudo_element.is_none(),
"Style attributes do not apply to pseudo-elements"); "Style attributes do not apply to pseudo-elements");
debug_assert!(pseudo_element.is_none() || debug_assert!(pseudo_element.is_none() ||
!Impl::pseudo_element_cascade_type(pseudo_element.as_ref().unwrap()).is_precomputed()); !TheSelectorImpl::pseudo_element_cascade_type(pseudo_element.as_ref().unwrap())
.is_precomputed());
let map = match pseudo_element { let map = match pseudo_element {
Some(ref pseudo) => self.pseudos_map.get(pseudo).unwrap(), Some(ref pseudo) => self.pseudos_map.get(pseudo).unwrap(),
@ -461,9 +400,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
pub fn animations(&self) -> &HashMap<Atom, KeyframesAnimation> { pub fn animations(&self) -> &HashMap<Atom, KeyframesAnimation> {
&self.animations &self.animations
} }
}
impl<Impl: SelectorImplExt<AttrString=String>> Stylist<Impl> {
pub fn compute_restyle_hint<E>(&self, element: &E, pub fn compute_restyle_hint<E>(&self, element: &E,
snapshot: &ElementSnapshot, snapshot: &ElementSnapshot,
// NB: We need to pass current_state as an argument because // NB: We need to pass current_state as an argument because
@ -472,7 +409,8 @@ impl<Impl: SelectorImplExt<AttrString=String>> Stylist<Impl> {
// more expensive than getting it directly from the caller. // more expensive than getting it directly from the caller.
current_state: ElementState) current_state: ElementState)
-> RestyleHint -> RestyleHint
where E: Element<Impl=Impl, AttrString=String> + Clone + MatchAttrGeneric { where E: Element<Impl=TheSelectorImpl, AttrString=AttrString>
+ Clone + MatchAttrGeneric {
self.state_deps.compute_hint(element, snapshot, current_state) self.state_deps.compute_hint(element, snapshot, current_state)
} }
} }
@ -480,18 +418,18 @@ impl<Impl: SelectorImplExt<AttrString=String>> Stylist<Impl> {
/// Map that contains the CSS rules for a given origin. /// Map that contains the CSS rules for a given origin.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
struct PerOriginSelectorMap<Impl: SelectorImpl> { struct PerOriginSelectorMap {
/// Rules that contains at least one property declararion with /// Rules that contains at least one property declararion with
/// normal importance. /// normal importance.
normal: SelectorMap<Vec<PropertyDeclaration>, Impl>, normal: SelectorMap<Vec<PropertyDeclaration>, TheSelectorImpl>,
/// Rules that contains at least one property declararion with /// Rules that contains at least one property declararion with
/// !important. /// !important.
important: SelectorMap<Vec<PropertyDeclaration>, Impl>, important: SelectorMap<Vec<PropertyDeclaration>, TheSelectorImpl>,
} }
impl<Impl: SelectorImpl> PerOriginSelectorMap<Impl> { impl PerOriginSelectorMap {
#[inline] #[inline]
fn new() -> PerOriginSelectorMap<Impl> { fn new() -> Self {
PerOriginSelectorMap { PerOriginSelectorMap {
normal: SelectorMap::new(), normal: SelectorMap::new(),
important: SelectorMap::new(), important: SelectorMap::new(),
@ -502,18 +440,18 @@ impl<Impl: SelectorImpl> PerOriginSelectorMap<Impl> {
/// Map that contains the CSS rules for a specific PseudoElement /// Map that contains the CSS rules for a specific PseudoElement
/// (or lack of PseudoElement). /// (or lack of PseudoElement).
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
struct PerPseudoElementSelectorMap<Impl: SelectorImpl> { struct PerPseudoElementSelectorMap {
/// Rules from user agent stylesheets /// Rules from user agent stylesheets
user_agent: PerOriginSelectorMap<Impl>, user_agent: PerOriginSelectorMap,
/// Rules from author stylesheets /// Rules from author stylesheets
author: PerOriginSelectorMap<Impl>, author: PerOriginSelectorMap,
/// Rules from user stylesheets /// Rules from user stylesheets
user: PerOriginSelectorMap<Impl>, user: PerOriginSelectorMap,
} }
impl<Impl: SelectorImpl> PerPseudoElementSelectorMap<Impl> { impl PerPseudoElementSelectorMap {
#[inline] #[inline]
fn new() -> PerPseudoElementSelectorMap<Impl> { fn new() -> Self {
PerPseudoElementSelectorMap { PerPseudoElementSelectorMap {
user_agent: PerOriginSelectorMap::new(), user_agent: PerOriginSelectorMap::new(),
author: PerOriginSelectorMap::new(), author: PerOriginSelectorMap::new(),
@ -522,7 +460,7 @@ impl<Impl: SelectorImpl> PerPseudoElementSelectorMap<Impl> {
} }
#[inline] #[inline]
fn borrow_for_origin(&mut self, origin: &Origin) -> &mut PerOriginSelectorMap<Impl> { fn borrow_for_origin(&mut self, origin: &Origin) -> &mut PerOriginSelectorMap {
match *origin { match *origin {
Origin::UserAgent => &mut self.user_agent, Origin::UserAgent => &mut self.user_agent,
Origin::Author => &mut self.author, Origin::Author => &mut self.author,

View file

@ -1,19 +0,0 @@
/* 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/. */
//! Concrete types for servo Style implementation
use animation;
use context;
use data;
use properties::ServoComputedValues;
use selector_impl::ServoSelectorImpl;
use selector_matching;
use stylesheets;
pub type Stylesheet = stylesheets::Stylesheet<ServoSelectorImpl>;
pub type PrivateStyleData = data::PrivateStyleData<ServoSelectorImpl, ServoComputedValues>;
pub type Stylist = selector_matching::Stylist<ServoSelectorImpl>;
pub type SharedStyleContext = context::SharedStyleContext<ServoSelectorImpl>;
pub type LocalStyleContextCreationInfo = context::LocalStyleContextCreationInfo<ServoSelectorImpl>;
pub type Animation = animation::Animation<ServoSelectorImpl>;

View file

@ -0,0 +1,250 @@
/* 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 element_state::ElementState;
use error_reporting::StdoutErrorReporter;
use parser::ParserContextExtraData;
use selector_impl::{SelectorImplExt, ElementExt, PseudoElementCascadeType, TheSelectorImpl};
use selectors::Element;
use selectors::parser::{ParserContext, SelectorImpl};
use std::process;
use stylesheets::{Stylesheet, Origin};
use url::Url;
use util::opts;
use util::resource_files::read_resource_file;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum PseudoElement {
Before,
After,
Selection,
DetailsSummary,
DetailsContent,
}
impl PseudoElement {
#[inline]
pub fn is_before_or_after(&self) -> bool {
match *self {
PseudoElement::Before |
PseudoElement::After => true,
_ => false,
}
}
#[inline]
pub fn cascade_type(&self) -> PseudoElementCascadeType {
match *self {
PseudoElement::Before |
PseudoElement::After |
PseudoElement::Selection => PseudoElementCascadeType::Eager,
PseudoElement::DetailsSummary => PseudoElementCascadeType::Lazy,
PseudoElement::DetailsContent => PseudoElementCascadeType::Precomputed,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum NonTSPseudoClass {
AnyLink,
Link,
Visited,
Active,
Focus,
Hover,
Enabled,
Disabled,
Checked,
Indeterminate,
ServoNonZeroBorder,
ReadWrite,
ReadOnly,
PlaceholderShown,
}
impl NonTSPseudoClass {
pub fn state_flag(&self) -> ElementState {
use element_state::*;
use self::NonTSPseudoClass::*;
match *self {
Active => IN_ACTIVE_STATE,
Focus => IN_FOCUS_STATE,
Hover => IN_HOVER_STATE,
Enabled => IN_ENABLED_STATE,
Disabled => IN_DISABLED_STATE,
Checked => IN_CHECKED_STATE,
Indeterminate => IN_INDETERMINATE_STATE,
ReadOnly | ReadWrite => IN_READ_WRITE_STATE,
PlaceholderShown => IN_PLACEHOLDER_SHOWN_STATE,
AnyLink |
Link |
Visited |
ServoNonZeroBorder => ElementState::empty(),
}
}
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct ServoSelectorImpl;
impl SelectorImpl for ServoSelectorImpl {
type AttrString = String;
type PseudoElement = PseudoElement;
type NonTSPseudoClass = NonTSPseudoClass;
fn parse_non_ts_pseudo_class(context: &ParserContext,
name: &str) -> Result<NonTSPseudoClass, ()> {
use self::NonTSPseudoClass::*;
let pseudo_class = match_ignore_ascii_case! { name,
"any-link" => AnyLink,
"link" => Link,
"visited" => Visited,
"active" => Active,
"focus" => Focus,
"hover" => Hover,
"enabled" => Enabled,
"disabled" => Disabled,
"checked" => Checked,
"indeterminate" => Indeterminate,
"read-write" => ReadWrite,
"read-only" => ReadOnly,
"placeholder-shown" => PlaceholderShown,
"-servo-nonzero-border" => {
if !context.in_user_agent_stylesheet {
return Err(());
}
ServoNonZeroBorder
},
_ => return Err(())
};
Ok(pseudo_class)
}
fn parse_pseudo_element(context: &ParserContext,
name: &str) -> Result<PseudoElement, ()> {
use self::PseudoElement::*;
let pseudo_element = match_ignore_ascii_case! { name,
"before" => Before,
"after" => After,
"selection" => Selection,
"-servo-details-summary" => {
if !context.in_user_agent_stylesheet {
return Err(())
}
DetailsSummary
},
"-servo-details-content" => {
if !context.in_user_agent_stylesheet {
return Err(())
}
DetailsContent
},
_ => return Err(())
};
Ok(pseudo_element)
}
}
impl SelectorImplExt for ServoSelectorImpl {
#[inline]
fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType {
pseudo.cascade_type()
}
#[inline]
fn each_pseudo_element<F>(mut fun: F)
where F: FnMut(PseudoElement) {
fun(PseudoElement::Before);
fun(PseudoElement::After);
fun(PseudoElement::DetailsContent);
fun(PseudoElement::DetailsSummary);
fun(PseudoElement::Selection);
}
#[inline]
fn pseudo_class_state_flag(pc: &NonTSPseudoClass) -> ElementState {
pc.state_flag()
}
#[inline]
fn pseudo_is_before_or_after(pseudo: &PseudoElement) -> bool {
pseudo.is_before_or_after()
}
#[inline]
fn get_user_or_user_agent_stylesheets() -> &'static [Stylesheet] {
&*USER_OR_USER_AGENT_STYLESHEETS
}
#[inline]
fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet> {
Some(&*QUIRKS_MODE_STYLESHEET)
}
}
impl<E: Element<Impl=TheSelectorImpl, AttrString=String>> ElementExt for E {
fn is_link(&self) -> bool {
self.match_non_ts_pseudo_class(NonTSPseudoClass::AnyLink)
}
}
lazy_static! {
pub static ref USER_OR_USER_AGENT_STYLESHEETS: Vec<Stylesheet> = {
let mut stylesheets = vec!();
// FIXME: presentational-hints.css should be at author origin with zero specificity.
// (Does it make a difference?)
for &filename in &["user-agent.css", "servo.css", "presentational-hints.css"] {
match read_resource_file(filename) {
Ok(res) => {
let ua_stylesheet = Stylesheet::from_bytes(
&res,
Url::parse(&format!("chrome://resources/{:?}", filename)).unwrap(),
None,
None,
Origin::UserAgent,
Box::new(StdoutErrorReporter),
ParserContextExtraData::default());
stylesheets.push(ua_stylesheet);
}
Err(..) => {
error!("Failed to load UA stylesheet {}!", filename);
process::exit(1);
}
}
}
for &(ref contents, ref url) in &opts::get().user_stylesheets {
stylesheets.push(Stylesheet::from_bytes(
&contents, url.clone(), None, None, Origin::User, Box::new(StdoutErrorReporter),
ParserContextExtraData::default()));
}
stylesheets
};
}
lazy_static! {
pub static ref QUIRKS_MODE_STYLESHEET: Stylesheet = {
match read_resource_file("quirks-mode.css") {
Ok(res) => {
Stylesheet::from_bytes(
&res,
Url::parse("chrome://resources/quirks-mode.css").unwrap(),
None,
None,
Origin::UserAgent,
Box::new(StdoutErrorReporter),
ParserContextExtraData::default())
},
Err(..) => {
error!("Stylist failed to load 'quirks-mode.css'!");
process::exit(1);
}
}
};
}

View file

@ -13,11 +13,11 @@ use keyframes::{Keyframe, parse_keyframe_list};
use media_queries::{Device, MediaQueryList, parse_media_query_list}; use media_queries::{Device, MediaQueryList, parse_media_query_list};
use parser::{ParserContext, ParserContextExtraData, log_css_error}; use parser::{ParserContext, ParserContextExtraData, log_css_error};
use properties::{PropertyDeclarationBlock, parse_property_declaration_list}; use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
use selectors::parser::{Selector, SelectorImpl, parse_selector_list}; use selector_impl::TheSelectorImpl;
use selectors::parser::{Selector, parse_selector_list};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::cell::Cell; use std::cell::Cell;
use std::iter::Iterator; use std::iter::Iterator;
use std::marker::PhantomData;
use std::slice; use std::slice;
use string_cache::{Atom, Namespace}; use string_cache::{Atom, Namespace};
use url::Url; use url::Url;
@ -43,10 +43,10 @@ pub enum Origin {
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Stylesheet<Impl: SelectorImpl> { pub struct Stylesheet {
/// List of rules in the order they were found (important for /// List of rules in the order they were found (important for
/// cascading order) /// cascading order)
pub rules: Vec<CSSRule<Impl>>, pub rules: Vec<CSSRule>,
/// List of media associated with the Stylesheet, if any. /// List of media associated with the Stylesheet, if any.
pub media: Option<MediaQueryList>, pub media: Option<MediaQueryList>,
pub origin: Origin, pub origin: Origin,
@ -56,11 +56,11 @@ pub struct Stylesheet<Impl: SelectorImpl> {
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum CSSRule<Impl: SelectorImpl> { pub enum CSSRule {
Charset(String), Charset(String),
Namespace(Option<String>, Namespace), Namespace(Option<String>, Namespace),
Style(StyleRule<Impl>), Style(StyleRule),
Media(MediaRule<Impl>), Media(MediaRule),
FontFace(FontFaceRule), FontFace(FontFaceRule),
Viewport(ViewportRule), Viewport(ViewportRule),
Keyframes(KeyframesRule), Keyframes(KeyframesRule),
@ -76,13 +76,13 @@ pub struct KeyframesRule {
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct MediaRule<Impl: SelectorImpl> { pub struct MediaRule {
pub media_queries: MediaQueryList, pub media_queries: MediaQueryList,
pub rules: Vec<CSSRule<Impl>>, pub rules: Vec<CSSRule>,
} }
impl<Impl: SelectorImpl> MediaRule<Impl> { impl MediaRule {
#[inline] #[inline]
pub fn evaluate(&self, device: &Device) -> bool { pub fn evaluate(&self, device: &Device) -> bool {
self.media_queries.evaluate(device) self.media_queries.evaluate(device)
@ -91,18 +91,18 @@ impl<Impl: SelectorImpl> MediaRule<Impl> {
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct StyleRule<Impl: SelectorImpl> { pub struct StyleRule {
pub selectors: Vec<Selector<Impl>>, pub selectors: Vec<Selector<TheSelectorImpl>>,
pub declarations: PropertyDeclarationBlock, pub declarations: PropertyDeclarationBlock,
} }
impl<Impl: SelectorImpl> Stylesheet<Impl> { impl Stylesheet {
pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>( pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>(
input: I, base_url: Url, protocol_encoding_label: Option<&str>, input: I, base_url: Url, protocol_encoding_label: Option<&str>,
environment_encoding: Option<EncodingRef>, origin: Origin, environment_encoding: Option<EncodingRef>, origin: Origin,
error_reporter: Box<ParseErrorReporter + Send>, error_reporter: Box<ParseErrorReporter + Send>,
extra_data: ParserContextExtraData) -> Stylesheet<Impl> { extra_data: ParserContextExtraData) -> Stylesheet {
let mut bytes = vec![]; let mut bytes = vec![];
// TODO: incremental decoding and tokenization/parsing // TODO: incremental decoding and tokenization/parsing
for chunk in input { for chunk in input {
@ -119,7 +119,7 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
environment_encoding: Option<EncodingRef>, environment_encoding: Option<EncodingRef>,
origin: Origin, error_reporter: Box<ParseErrorReporter + Send>, origin: Origin, error_reporter: Box<ParseErrorReporter + Send>,
extra_data: ParserContextExtraData) extra_data: ParserContextExtraData)
-> Stylesheet<Impl> { -> Stylesheet {
// TODO: bytes.as_slice could be bytes.container_as_bytes() // TODO: bytes.as_slice could be bytes.container_as_bytes()
let (string, _) = decode_stylesheet_bytes( let (string, _) = decode_stylesheet_bytes(
bytes, protocol_encoding_label, environment_encoding); bytes, protocol_encoding_label, environment_encoding);
@ -128,12 +128,11 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
pub fn from_str(css: &str, base_url: Url, origin: Origin, pub fn from_str(css: &str, base_url: Url, origin: Origin,
error_reporter: Box<ParseErrorReporter + Send>, error_reporter: Box<ParseErrorReporter + Send>,
extra_data: ParserContextExtraData) -> Stylesheet<Impl> { extra_data: ParserContextExtraData) -> Stylesheet {
let rule_parser = TopLevelRuleParser { let rule_parser = TopLevelRuleParser {
context: ParserContext::new_with_extra_data(origin, &base_url, error_reporter.clone(), context: ParserContext::new_with_extra_data(origin, &base_url, error_reporter.clone(),
extra_data), extra_data),
state: Cell::new(State::Start), state: Cell::new(State::Start),
_impl: PhantomData,
}; };
let mut input = Parser::new(css); let mut input = Parser::new(css);
input.look_for_viewport_percentages(); input.look_for_viewport_percentages();
@ -189,7 +188,7 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
/// Return an iterator over all the rules within the style-sheet. /// Return an iterator over all the rules within the style-sheet.
#[inline] #[inline]
pub fn rules(&self) -> Rules<Impl> { pub fn rules(&self) -> Rules {
Rules::new(self.rules.iter(), None) Rules::new(self.rules.iter(), None)
} }
@ -200,7 +199,7 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
/// nested rules will be skipped. Use `rules` if all rules need to be /// nested rules will be skipped. Use `rules` if all rules need to be
/// examined. /// examined.
#[inline] #[inline]
pub fn effective_rules<'a>(&'a self, device: &'a Device) -> Rules<'a, Impl> { pub fn effective_rules<'a>(&'a self, device: &'a Device) -> Rules<'a> {
Rules::new(self.rules.iter(), Some(device)) Rules::new(self.rules.iter(), Some(device))
} }
} }
@ -209,25 +208,25 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
/// ///
/// The iteration order is pre-order. Specifically, this implies that a /// The iteration order is pre-order. Specifically, this implies that a
/// conditional group rule will come before its nested rules. /// conditional group rule will come before its nested rules.
pub struct Rules<'a, Impl: SelectorImpl + 'a> { pub struct Rules<'a> {
// 2 because normal case is likely to be just one level of nesting (@media) // 2 because normal case is likely to be just one level of nesting (@media)
stack: SmallVec<[slice::Iter<'a, CSSRule<Impl>>; 2]>, stack: SmallVec<[slice::Iter<'a, CSSRule>; 2]>,
device: Option<&'a Device> device: Option<&'a Device>
} }
impl<'a, Impl: SelectorImpl + 'a> Rules<'a, Impl> { impl<'a> Rules<'a> {
fn new(iter: slice::Iter<'a, CSSRule<Impl>>, device: Option<&'a Device>) -> Rules<'a, Impl> { fn new(iter: slice::Iter<'a, CSSRule>, device: Option<&'a Device>) -> Rules<'a> {
let mut stack: SmallVec<[slice::Iter<'a, CSSRule<Impl>>; 2]> = SmallVec::new(); let mut stack: SmallVec<[slice::Iter<'a, CSSRule>; 2]> = SmallVec::new();
stack.push(iter); stack.push(iter);
Rules { stack: stack, device: device } Rules { stack: stack, device: device }
} }
} }
impl<'a, Impl: SelectorImpl + 'a> Iterator for Rules<'a, Impl> { impl<'a> Iterator for Rules<'a> {
type Item = &'a CSSRule<Impl>; type Item = &'a CSSRule;
fn next(&mut self) -> Option<&'a CSSRule<Impl>> { fn next(&mut self) -> Option<&'a CSSRule> {
while !self.stack.is_empty() { while !self.stack.is_empty() {
let top = self.stack.len() - 1; let top = self.stack.len() - 1;
while let Some(rule) = self.stack[top].next() { while let Some(rule) = self.stack[top].next() {
@ -262,7 +261,6 @@ impl<'a, Impl: SelectorImpl + 'a> Iterator for Rules<'a, Impl> {
pub mod rule_filter { pub mod rule_filter {
//! Specific `CSSRule` variant iterators. //! Specific `CSSRule` variant iterators.
use selectors::parser::SelectorImpl;
use std::marker::PhantomData; use std::marker::PhantomData;
use super::super::font_face::FontFaceRule; use super::super::font_face::FontFaceRule;
use super::super::viewport::ViewportRule; use super::super::viewport::ViewportRule;
@ -277,8 +275,8 @@ pub mod rule_filter {
_lifetime: PhantomData<&'a ()> _lifetime: PhantomData<&'a ()>
} }
impl<'a, I, Impl: SelectorImpl + 'a> $variant<'a, I> impl<'a, I> $variant<'a, I>
where I: Iterator<Item=&'a CSSRule<Impl>> { where I: Iterator<Item=&'a CSSRule> {
#[inline] #[inline]
pub fn new(iter: I) -> $variant<'a, I> { pub fn new(iter: I) -> $variant<'a, I> {
$variant { $variant {
@ -288,8 +286,8 @@ pub mod rule_filter {
} }
} }
impl<'a, I, Impl: SelectorImpl + 'a> Iterator for $variant<'a, I> impl<'a, I> Iterator for $variant<'a, I>
where I: Iterator<Item=&'a CSSRule<Impl>> { where I: Iterator<Item=&'a CSSRule> {
type Item = &'a $value; type Item = &'a $value;
fn next(&mut self) -> Option<&'a $value> { fn next(&mut self) -> Option<&'a $value> {
@ -310,15 +308,15 @@ pub mod rule_filter {
} }
} }
rule_filter!(Media -> MediaRule<Impl>); rule_filter!(Media -> MediaRule);
rule_filter!(Style -> StyleRule<Impl>); rule_filter!(Style -> StyleRule);
rule_filter!(FontFace -> FontFaceRule); rule_filter!(FontFace -> FontFaceRule);
rule_filter!(Viewport -> ViewportRule); rule_filter!(Viewport -> ViewportRule);
rule_filter!(Keyframes -> KeyframesRule); rule_filter!(Keyframes -> KeyframesRule);
} }
/// Extension methods for `CSSRule` iterators. /// Extension methods for `CSSRule` iterators.
pub trait CSSRuleIteratorExt<'a, Impl: SelectorImpl + 'a>: Iterator<Item=&'a CSSRule<Impl>> + Sized { pub trait CSSRuleIteratorExt<'a>: Iterator<Item=&'a CSSRule> + Sized {
/// Yield only @font-face rules. /// Yield only @font-face rules.
fn font_face(self) -> rule_filter::FontFace<'a, Self>; fn font_face(self) -> rule_filter::FontFace<'a, Self>;
@ -335,7 +333,7 @@ pub trait CSSRuleIteratorExt<'a, Impl: SelectorImpl + 'a>: Iterator<Item=&'a CSS
fn keyframes(self) -> rule_filter::Keyframes<'a, Self>; fn keyframes(self) -> rule_filter::Keyframes<'a, Self>;
} }
impl<'a, I, Impl: SelectorImpl + 'a> CSSRuleIteratorExt<'a, Impl> for I where I: Iterator<Item=&'a CSSRule<Impl>> { impl<'a, I> CSSRuleIteratorExt<'a> for I where I: Iterator<Item=&'a CSSRule> {
#[inline] #[inline]
fn font_face(self) -> rule_filter::FontFace<'a, I> { fn font_face(self) -> rule_filter::FontFace<'a, I> {
rule_filter::FontFace::new(self) rule_filter::FontFace::new(self)
@ -362,12 +360,9 @@ impl<'a, I, Impl: SelectorImpl + 'a> CSSRuleIteratorExt<'a, Impl> for I where I:
} }
} }
fn parse_nested_rules<Impl: SelectorImpl>(context: &ParserContext, input: &mut Parser) -> Vec<CSSRule<Impl>> { fn parse_nested_rules(context: &ParserContext, input: &mut Parser) -> Vec<CSSRule> {
let mut iter = RuleListParser::new_for_nested_rule(input, let mut iter = RuleListParser::new_for_nested_rule(input,
NestedRuleParser { NestedRuleParser { context: context });
context: context,
_impl: PhantomData
});
let mut rules = Vec::new(); let mut rules = Vec::new();
while let Some(result) = iter.next() { while let Some(result) = iter.next() {
match result { match result {
@ -383,10 +378,9 @@ fn parse_nested_rules<Impl: SelectorImpl>(context: &ParserContext, input: &mut P
} }
struct TopLevelRuleParser<'a, Impl: SelectorImpl> { struct TopLevelRuleParser<'a> {
context: ParserContext<'a>, context: ParserContext<'a>,
state: Cell<State>, state: Cell<State>,
_impl: PhantomData<Impl>
} }
#[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone)] #[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
@ -410,12 +404,12 @@ enum AtRulePrelude {
} }
impl<'a, Impl: SelectorImpl> AtRuleParser for TopLevelRuleParser<'a, Impl> { impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
type Prelude = AtRulePrelude; type Prelude = AtRulePrelude;
type AtRule = CSSRule<Impl>; type AtRule = CSSRule;
fn parse_prelude(&self, name: &str, input: &mut Parser) fn parse_prelude(&self, name: &str, input: &mut Parser)
-> Result<AtRuleType<AtRulePrelude, CSSRule<Impl>>, ()> { -> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> {
match_ignore_ascii_case! { name, match_ignore_ascii_case! { name,
"charset" => { "charset" => {
if self.state.get() <= State::Start { if self.state.get() <= State::Start {
@ -451,46 +445,45 @@ impl<'a, Impl: SelectorImpl> AtRuleParser for TopLevelRuleParser<'a, Impl> {
} }
self.state.set(State::Body); self.state.set(State::Body);
AtRuleParser::parse_prelude(&NestedRuleParser { context: &self.context, _impl: PhantomData }, name, input) AtRuleParser::parse_prelude(&NestedRuleParser { context: &self.context }, name, input)
} }
#[inline] #[inline]
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule<Impl>, ()> { fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> {
AtRuleParser::parse_block(&NestedRuleParser { context: &self.context, _impl: PhantomData }, prelude, input) AtRuleParser::parse_block(&NestedRuleParser { context: &self.context }, prelude, input)
} }
} }
impl<'a, Impl: SelectorImpl> QualifiedRuleParser for TopLevelRuleParser<'a, Impl> { impl<'a> QualifiedRuleParser for TopLevelRuleParser<'a> {
type Prelude = Vec<Selector<Impl>>; type Prelude = Vec<Selector<TheSelectorImpl>>;
type QualifiedRule = CSSRule<Impl>; type QualifiedRule = CSSRule;
#[inline] #[inline]
fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<Impl>>, ()> { fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<TheSelectorImpl>>, ()> {
self.state.set(State::Body); self.state.set(State::Body);
QualifiedRuleParser::parse_prelude(&NestedRuleParser { context: &self.context, _impl: PhantomData }, input) QualifiedRuleParser::parse_prelude(&NestedRuleParser { context: &self.context }, input)
} }
#[inline] #[inline]
fn parse_block(&self, prelude: Vec<Selector<Impl>>, input: &mut Parser) -> Result<CSSRule<Impl>, ()> { fn parse_block(&self, prelude: Vec<Selector<TheSelectorImpl>>, input: &mut Parser) -> Result<CSSRule, ()> {
QualifiedRuleParser::parse_block(&NestedRuleParser { context: &self.context, _impl: PhantomData }, QualifiedRuleParser::parse_block(&NestedRuleParser { context: &self.context },
prelude, input) prelude, input)
} }
} }
struct NestedRuleParser<'a, 'b: 'a, Impl: SelectorImpl> { struct NestedRuleParser<'a, 'b: 'a> {
context: &'a ParserContext<'b>, context: &'a ParserContext<'b>,
_impl: PhantomData<Impl>,
} }
impl<'a, 'b, Impl: SelectorImpl> AtRuleParser for NestedRuleParser<'a, 'b, Impl> { impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
type Prelude = AtRulePrelude; type Prelude = AtRulePrelude;
type AtRule = CSSRule<Impl>; type AtRule = CSSRule;
fn parse_prelude(&self, name: &str, input: &mut Parser) fn parse_prelude(&self, name: &str, input: &mut Parser)
-> Result<AtRuleType<AtRulePrelude, CSSRule<Impl>>, ()> { -> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> {
match_ignore_ascii_case! { name, match_ignore_ascii_case! { name,
"media" => { "media" => {
let media_queries = parse_media_query_list(input); let media_queries = parse_media_query_list(input);
@ -519,7 +512,7 @@ impl<'a, 'b, Impl: SelectorImpl> AtRuleParser for NestedRuleParser<'a, 'b, Impl>
} }
} }
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule<Impl>, ()> { fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> {
match prelude { match prelude {
AtRulePrelude::FontFace => { AtRulePrelude::FontFace => {
parse_font_face_block(self.context, input).map(CSSRule::FontFace) parse_font_face_block(self.context, input).map(CSSRule::FontFace)
@ -543,15 +536,15 @@ impl<'a, 'b, Impl: SelectorImpl> AtRuleParser for NestedRuleParser<'a, 'b, Impl>
} }
} }
impl<'a, 'b, Impl: SelectorImpl> QualifiedRuleParser for NestedRuleParser<'a, 'b, Impl> { impl<'a, 'b> QualifiedRuleParser for NestedRuleParser<'a, 'b> {
type Prelude = Vec<Selector<Impl>>; type Prelude = Vec<Selector<TheSelectorImpl>>;
type QualifiedRule = CSSRule<Impl>; type QualifiedRule = CSSRule;
fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<Impl>>, ()> { fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector<TheSelectorImpl>>, ()> {
parse_selector_list(&self.context.selector_context, input) parse_selector_list(&self.context.selector_context, input)
} }
fn parse_block(&self, prelude: Vec<Selector<Impl>>, input: &mut Parser) -> Result<CSSRule<Impl>, ()> { fn parse_block(&self, prelude: Vec<Selector<TheSelectorImpl>>, input: &mut Parser) -> Result<CSSRule, ()> {
Ok(CSSRule::Style(StyleRule { Ok(CSSRule::Style(StyleRule {
selectors: prelude, selectors: prelude,
declarations: parse_property_declaration_list(self.context, input) declarations: parse_property_declaration_list(self.context, input)

View file

@ -46,9 +46,9 @@ thread_local!(
/// ///
/// If one does not exist, a new one will be made for you. If it is out of date, /// If one does not exist, a new one will be made for you. If it is out of date,
/// it will be cleared and reused. /// it will be cleared and reused.
fn take_thread_local_bloom_filter<N, Impl: SelectorImplExt>(parent_node: Option<N>, fn take_thread_local_bloom_filter<N>(parent_node: Option<N>,
root: OpaqueNode, root: OpaqueNode,
context: &SharedStyleContext<Impl>) context: &SharedStyleContext)
-> Box<BloomFilter> -> Box<BloomFilter>
where N: TNode { where N: TNode {
STYLE_BLOOM.with(|style_bloom| { STYLE_BLOOM.with(|style_bloom| {
@ -82,9 +82,8 @@ fn take_thread_local_bloom_filter<N, Impl: SelectorImplExt>(parent_node: Option<
}) })
} }
fn put_thread_local_bloom_filter<Impl: SelectorImplExt>(bf: Box<BloomFilter>, fn put_thread_local_bloom_filter(bf: Box<BloomFilter>, unsafe_node: &UnsafeNode,
unsafe_node: &UnsafeNode, context: &SharedStyleContext) {
context: &SharedStyleContext<Impl>) {
STYLE_BLOOM.with(move |style_bloom| { STYLE_BLOOM.with(move |style_bloom| {
assert!(style_bloom.borrow().is_none(), assert!(style_bloom.borrow().is_none(),
"Putting into a never-taken thread-local bloom filter"); "Putting into a never-taken thread-local bloom filter");
@ -111,10 +110,9 @@ fn insert_ancestors_into_bloom_filter<N>(bf: &mut Box<BloomFilter>,
debug!("[{}] Inserted {} ancestors.", tid(), ancestors); debug!("[{}] Inserted {} ancestors.", tid(), ancestors);
} }
pub fn remove_from_bloom_filter<'a, N, C, Impl>(context: &C, root: OpaqueNode, node: N) pub fn remove_from_bloom_filter<'a, N, C>(context: &C, root: OpaqueNode, node: N)
where N: TNode, where N: TNode,
Impl: SelectorImplExt + 'a, C: StyleContext<'a>
C: StyleContext<'a, Impl>
{ {
let unsafe_layout_node = node.to_unsafe(); let unsafe_layout_node = node.to_unsafe();
@ -158,8 +156,8 @@ 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: SelectorImplExt<ComputedValues=N::ConcreteComputedValues> + 'a { <N::ConcreteElement as Element>::Impl: SelectorImplExt + 'a {
// Get the parent node. // Get the parent node.
let parent_opt = match node.parent_node() { let parent_opt = match node.parent_node() {
Some(parent) if parent.is_element() => Some(parent), Some(parent) if parent.is_element() => Some(parent),

View file

@ -105,7 +105,7 @@ pub mod specified {
use std::fmt; use std::fmt;
use std::ops::Mul; use std::ops::Mul;
use style_traits::values::specified::AllowedNumericType; use style_traits::values::specified::AllowedNumericType;
use super::computed::{TContext, ToComputedValue}; use super::computed::{Context, ToComputedValue};
use super::{CSSFloat, FONT_MEDIUM_PX, HasViewportPercentage, LocalToCss, NoViewportPercentage}; use super::{CSSFloat, FONT_MEDIUM_PX, HasViewportPercentage, LocalToCss, NoViewportPercentage};
use url::Url; use url::Url;
@ -1569,7 +1569,7 @@ pub mod specified {
type ComputedValue = Time; type ComputedValue = Time;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> Time { fn to_computed_value(&self, _: &Context) -> Time {
*self *self
} }
} }
@ -1611,7 +1611,7 @@ pub mod specified {
type ComputedValue = CSSFloat; type ComputedValue = CSSFloat;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> CSSFloat { self.0 } fn to_computed_value(&self, _: &Context) -> CSSFloat { self.0 }
} }
impl ToCss for Number { impl ToCss for Number {
@ -1636,7 +1636,7 @@ pub mod specified {
type ComputedValue = CSSFloat; type ComputedValue = CSSFloat;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> CSSFloat { fn to_computed_value(&self, _: &Context) -> CSSFloat {
if self.0 < 0.0 { if self.0 < 0.0 {
0.0 0.0
} else if self.0 > 1.0 { } else if self.0 > 1.0 {
@ -1658,7 +1658,6 @@ pub mod computed {
use app_units::Au; use app_units::Au;
use euclid::size::Size2D; use euclid::size::Size2D;
use properties::ComputedValues; use properties::ComputedValues;
use properties::style_struct_traits::Font;
use std::fmt; use std::fmt;
use super::LocalToCss; use super::LocalToCss;
use super::specified::AngleOrCorner; use super::specified::AngleOrCorner;
@ -1667,39 +1666,29 @@ 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 trait TContext { pub struct Context<'a> {
type ConcreteComputedValues: ComputedValues;
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: ComputedValues> {
pub is_root_element: bool, pub is_root_element: bool,
pub viewport_size: Size2D<Au>, pub viewport_size: Size2D<Au>,
pub inherited_style: &'a C, pub inherited_style: &'a ComputedValues,
/// 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: C, pub style: ComputedValues,
} }
impl<'a, C: ComputedValues> TContext for Context<'a, C> { impl<'a> Context<'a> {
type ConcreteComputedValues = C; pub fn is_root_element(&self) -> bool { self.is_root_element }
fn is_root_element(&self) -> bool { self.is_root_element } pub fn viewport_size(&self) -> Size2D<Au> { self.viewport_size }
fn viewport_size(&self) -> Size2D<Au> { self.viewport_size } pub fn inherited_style(&self) -> &ComputedValues { &self.inherited_style }
fn inherited_style(&self) -> &C { &self.inherited_style } pub fn style(&self) -> &ComputedValues { &self.style }
fn style(&self) -> &C { &self.style } pub fn mutate_style(&mut self) -> &mut ComputedValues { &mut 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<Cx: TContext>(&self, _context: &Cx) -> Self::ComputedValue; fn to_computed_value(&self, _context: &Context) -> Self::ComputedValue;
} }
pub trait ComputedValueAsSpecified {} pub trait ComputedValueAsSpecified {}
@ -1708,7 +1697,7 @@ pub mod computed {
type ComputedValue = T; type ComputedValue = T;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> T { fn to_computed_value(&self, _context: &Context) -> T {
self.clone() self.clone()
} }
} }
@ -1717,7 +1706,7 @@ pub mod computed {
type ComputedValue = CSSColor; type ComputedValue = CSSColor;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, _context: &Cx) -> CSSColor { fn to_computed_value(&self, _context: &Context) -> CSSColor {
self.parsed self.parsed
} }
} }
@ -1728,7 +1717,7 @@ pub mod computed {
type ComputedValue = Au; type ComputedValue = Au;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> Au { fn to_computed_value(&self, context: &Context) -> 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(),
@ -1823,7 +1812,7 @@ pub mod computed {
impl ToComputedValue for specified::CalcLengthOrPercentage { impl ToComputedValue for specified::CalcLengthOrPercentage {
type ComputedValue = CalcLengthOrPercentage; type ComputedValue = CalcLengthOrPercentage;
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> CalcLengthOrPercentage { fn to_computed_value(&self, context: &Context) -> CalcLengthOrPercentage {
let mut length = None; let mut length = None;
if let Some(absolute) = self.absolute { if let Some(absolute) = self.absolute {
@ -1862,7 +1851,7 @@ pub mod computed {
type ComputedValue = BorderRadiusSize; type ComputedValue = BorderRadiusSize;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> BorderRadiusSize { fn to_computed_value(&self, context: &Context) -> BorderRadiusSize {
let w = self.0.width.to_computed_value(context); let w = self.0.width.to_computed_value(context);
let h = self.0.height.to_computed_value(context); let h = self.0.height.to_computed_value(context);
BorderRadiusSize(Size2D::new(w, h)) BorderRadiusSize(Size2D::new(w, h))
@ -1917,7 +1906,7 @@ pub mod computed {
impl ToComputedValue for specified::LengthOrPercentage { impl ToComputedValue for specified::LengthOrPercentage {
type ComputedValue = LengthOrPercentage; type ComputedValue = LengthOrPercentage;
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentage { fn to_computed_value(&self, context: &Context) -> 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))
@ -1981,7 +1970,7 @@ pub mod computed {
type ComputedValue = LengthOrPercentageOrAuto; type ComputedValue = LengthOrPercentageOrAuto;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentageOrAuto { fn to_computed_value(&self, context: &Context) -> 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))
@ -2037,7 +2026,7 @@ pub mod computed {
type ComputedValue = LengthOrPercentageOrAutoOrContent; type ComputedValue = LengthOrPercentageOrAutoOrContent;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentageOrAutoOrContent { fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAutoOrContent {
match *self { match *self {
specified::LengthOrPercentageOrAutoOrContent::Length(value) => { specified::LengthOrPercentageOrAutoOrContent::Length(value) => {
LengthOrPercentageOrAutoOrContent::Length(value.to_computed_value(context)) LengthOrPercentageOrAutoOrContent::Length(value.to_computed_value(context))
@ -2095,7 +2084,7 @@ pub mod computed {
type ComputedValue = LengthOrPercentageOrNone; type ComputedValue = LengthOrPercentageOrNone;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrPercentageOrNone { fn to_computed_value(&self, context: &Context) -> 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))
@ -2145,7 +2134,7 @@ pub mod computed {
type ComputedValue = LengthOrNone; type ComputedValue = LengthOrNone;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LengthOrNone { fn to_computed_value(&self, context: &Context) -> 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())
@ -2173,7 +2162,7 @@ pub mod computed {
type ComputedValue = Image; type ComputedValue = Image;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> Image { fn to_computed_value(&self, context: &Context) -> 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) => {
@ -2272,7 +2261,7 @@ pub mod computed {
type ComputedValue = LinearGradient; type ComputedValue = LinearGradient;
#[inline] #[inline]
fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> LinearGradient { fn to_computed_value(&self, context: &Context) -> LinearGradient {
let specified::LinearGradient { let specified::LinearGradient {
angle_or_corner, angle_or_corner,
ref stops ref stops

View file

@ -13,7 +13,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::{ComputedValues, ServoComputedValues}; use properties::ComputedValues;
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::fmt; use std::fmt;
use std::iter::Enumerate; use std::iter::Enumerate;
@ -646,8 +646,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: ServoComputedValues::initial_values(), inherited_style: ComputedValues::initial_values(),
style: ServoComputedValues::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

@ -139,7 +139,7 @@ that you didn't find it here so it can be added :)
[stylo]: https://public.etherpad-mozilla.org/p/stylo [stylo]: https://public.etherpad-mozilla.org/p/stylo
[selector-impl]: http://doc.servo.org/selectors/parser/trait.SelectorImpl.html [selector-impl]: http://doc.servo.org/selectors/parser/trait.SelectorImpl.html
[selector-impl-ext]: http://doc.servo.org/style/selector_impl/trait.SelectorImplExt.html [selector-impl-ext]: http://doc.servo.org/style/selector_impl/trait.SelectorImplExt.html
[servo-selector-impl]: http://doc.servo.org/style/selector_impl/struct.ServoSelectorImpl.html [servo-selector-impl]: http://doc.servo.org/style/servo_selector_impl/struct.ServoSelectorImpl.html
[tree-structural-pseudo-classes]: https://www.w3.org/TR/selectors4/#structural-pseudos [tree-structural-pseudo-classes]: https://www.w3.org/TR/selectors4/#structural-pseudos
[style-dom-traits]: http://doc.servo.org/style/dom/index.html [style-dom-traits]: http://doc.servo.org/style/dom/index.html
[layout-wrapper]: http://doc.servo.org/layout/wrapper/index.html [layout-wrapper]: http://doc.servo.org/layout/wrapper/index.html

View file

@ -3,7 +3,6 @@ name = "geckoservo"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"app_units 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "app_units 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gecko_bindings 0.0.1", "gecko_bindings 0.0.1",

View file

@ -4,8 +4,6 @@ version = "0.0.1"
authors = ["The Servo Project Developers"] authors = ["The Servo Project Developers"]
license = "MPL-2.0" license = "MPL-2.0"
build = "build.rs"
[lib] [lib]
name = "geckoservo" name = "geckoservo"
path = "lib.rs" path = "lib.rs"
@ -13,7 +11,6 @@ crate-type = ["staticlib"]
[dependencies] [dependencies]
app_units = "0.2.5" app_units = "0.2.5"
cssparser = "0.5.4"
env_logger = "0.3" env_logger = "0.3"
euclid = "0.7.1" euclid = "0.7.1"
gecko_bindings = {version = "0.0.1", path = "gecko_bindings"} gecko_bindings = {version = "0.0.1", path = "gecko_bindings"}

View file

@ -1,58 +0,0 @@
/* 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::path::Path;
use std::process::{Command, exit};
#[cfg(windows)]
fn find_python() -> String {
if Command::new("python2.7.exe").arg("--version").output().is_ok() {
return "python2.7.exe".to_owned();
}
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!(concat!("Can't find python (tried python2.7.exe, 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 = env::var("PYTHON").ok().unwrap_or_else(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 properties_dir = Path::new("components").join("style").join("properties");
println!("cargo:rerun-if-changed={}", top_dir.join(&properties_dir).to_str().unwrap());
println!("cargo:rerun-if-changed={}", geckolib_dir.join("properties.mako.rs").to_str().unwrap());
let status = Command::new(python)
.current_dir(&top_dir)
.arg(&properties_dir.join("build.py"))
.arg("gecko")
.arg("geckolib")
.status()
.unwrap();
if !status.success() {
exit(1)
}
}

View file

@ -1,17 +1,15 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* 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 * 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 selector_impl::{GeckoSelectorImpl, SharedStyleContext};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use style::context::{LocalStyleContext, StyleContext}; use style::context::{LocalStyleContext, StyleContext, SharedStyleContext};
thread_local!(static LOCAL_CONTEXT_KEY: thread_local!(static LOCAL_CONTEXT_KEY: RefCell<Option<Rc<LocalStyleContext>>> = RefCell::new(None));
RefCell<Option<Rc<LocalStyleContext<GeckoSelectorImpl>>>> = 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<GeckoSelectorImpl>> {
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() {
@ -29,7 +27,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<GeckoSelectorImpl>>, cached_local_context: Rc<LocalStyleContext>,
} }
impl<'a> StandaloneStyleContext<'a> { impl<'a> StandaloneStyleContext<'a> {
@ -42,12 +40,12 @@ impl<'a> StandaloneStyleContext<'a> {
} }
} }
impl<'a> StyleContext<'a, GeckoSelectorImpl> for StandaloneStyleContext<'a> { impl<'a> StyleContext<'a> for StandaloneStyleContext<'a> {
fn shared_context(&self) -> &'a SharedStyleContext { fn shared_context(&self) -> &'a SharedStyleContext {
&self.shared &self.shared
} }
fn local_context(&self) -> &LocalStyleContext<GeckoSelectorImpl> { fn local_context(&self) -> &LocalStyleContext {
&self.cached_local_context &self.cached_local_context
} }
} }

View file

@ -6,15 +6,18 @@ use euclid::Size2D;
use euclid::size::TypedSize2D; use euclid::size::TypedSize2D;
use gecko_bindings::bindings::RawServoStyleSet; use gecko_bindings::bindings::RawServoStyleSet;
use num_cpus; use num_cpus;
use selector_impl::{Animation, SharedStyleContext, Stylist, Stylesheet};
use std::cmp; use std::cmp;
use std::collections::HashMap; use std::collections::HashMap;
use std::env; use std::env;
use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use style::animation::Animation;
use style::context::SharedStyleContext;
use style::dom::OpaqueNode; use style::dom::OpaqueNode;
use style::media_queries::{Device, MediaType}; use style::media_queries::{Device, MediaType};
use style::parallel::WorkQueueData; use style::parallel::WorkQueueData;
use style::selector_matching::Stylist;
use style::stylesheets::Stylesheet;
use style::workqueue::WorkQueue; use style::workqueue::WorkQueue;
use style_traits::ViewportPx; use style_traits::ViewportPx;
use util::thread_state; use util::thread_state;

View file

@ -1,22 +0,0 @@
# 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/.
import os
import sys
from mako import exceptions
from mako.template import Template
try:
style_template = Template(filename=os.environ['STYLE_TEMPLATE'],
input_encoding='utf8')
style_template.render(PRODUCT='gecko')
geckolib_template = Template(filename=os.environ['GECKOLIB_TEMPLATE'], input_encoding='utf8')
output = geckolib_template.render(STYLE_STRUCTS=style_template.module.STYLE_STRUCTS,
to_rust_ident=style_template.module.to_rust_ident)
print(output.encode('utf8'))
except:
sys.stderr.write(exceptions.text_error_template().render().encode('utf8'))
sys.exit(1)

View file

@ -14,24 +14,23 @@ use gecko_bindings::bindings::{ServoDeclarationBlock, ServoNodeData, ThreadSafeP
use gecko_bindings::bindings::{ThreadSafeURIHolder, nsHTMLCSSStyleSheet}; use gecko_bindings::bindings::{ThreadSafeURIHolder, nsHTMLCSSStyleSheet};
use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI}; use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI};
use gecko_bindings::structs::{SheetParsingMode, nsIAtom}; use gecko_bindings::structs::{SheetParsingMode, nsIAtom};
use properties::GeckoComputedValues; use std::mem::transmute;
use selector_impl::{GeckoSelectorImpl, PseudoElement, SharedStyleContext, Stylesheet};
use std::marker::PhantomData;
use std::mem::{forget, transmute};
use std::ptr; 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::arc_ptr_eq; use style::arc_ptr_eq;
use style::context::{LocalStyleContextCreationInfo, ReflowGoal}; use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext};
use style::dom::{TDocument, TElement, TNode}; use style::dom::{TDocument, TElement, TNode};
use style::error_reporting::StdoutErrorReporter; use style::error_reporting::StdoutErrorReporter;
use style::gecko_glue::ArcHelpers;
use style::gecko_selector_impl::{GeckoSelectorImpl, PseudoElement};
use style::parallel; use style::parallel;
use style::parser::ParserContextExtraData; use style::parser::ParserContextExtraData;
use style::properties::{ComputedValues, PropertyDeclarationBlock, parse_one_declaration}; use style::properties::{ComputedValues, PropertyDeclarationBlock, parse_one_declaration};
use style::selector_impl::{SelectorImplExt, PseudoElementCascadeType}; use style::selector_impl::{SelectorImplExt, PseudoElementCascadeType};
use style::sequential; use style::sequential;
use style::stylesheets::Origin; use style::stylesheets::{Stylesheet, Origin};
use traversal::RecalcStyleOnly; use traversal::RecalcStyleOnly;
use url::Url; use url::Url;
use wrapper::{DUMMY_BASE_URL, GeckoDocument, GeckoElement, GeckoNode, NonOpaqueStyleData}; use wrapper::{DUMMY_BASE_URL, GeckoDocument, GeckoElement, GeckoNode, NonOpaqueStyleData};
@ -87,7 +86,7 @@ fn restyle_subtree(node: GeckoNode, raw_data: *mut RawServoStyleSet) {
// rid of the HackilyFindSomeDeviceContext stuff that happens during // rid of the HackilyFindSomeDeviceContext stuff that happens during
// initial_values computation, since that stuff needs to be called further // initial_values computation, since that stuff needs to be called further
// along in startup than the sensible place to call Servo_Initialize. // along in startup than the sensible place to call Servo_Initialize.
GeckoComputedValues::initial_values(); ComputedValues::initial_values();
let _needs_dirtying = Arc::get_mut(&mut per_doc_data.stylist).unwrap() let _needs_dirtying = Arc::get_mut(&mut per_doc_data.stylist).unwrap()
.update(&per_doc_data.stylesheets, .update(&per_doc_data.stylesheets,
@ -178,54 +177,6 @@ pub extern "C" fn Servo_StylesheetFromUTF8Bytes(bytes: *const u8,
} }
} }
pub struct ArcHelpers<GeckoType, ServoType> {
phantom1: PhantomData<GeckoType>,
phantom2: PhantomData<ServoType>,
}
impl<GeckoType, ServoType> ArcHelpers<GeckoType, ServoType> {
pub fn with<F, Output>(raw: *mut GeckoType, cb: F) -> Output
where F: FnOnce(&Arc<ServoType>) -> Output {
debug_assert!(!raw.is_null());
let owned = unsafe { Self::into(raw) };
let result = cb(&owned);
forget(owned);
result
}
pub fn maybe_with<F, Output>(maybe_raw: *mut GeckoType, cb: F) -> Output
where F: FnOnce(Option<&Arc<ServoType>>) -> Output {
let owned = if maybe_raw.is_null() {
None
} else {
Some(unsafe { Self::into(maybe_raw) })
};
let result = cb(owned.as_ref());
forget(owned);
result
}
pub unsafe fn into(ptr: *mut GeckoType) -> Arc<ServoType> {
transmute(ptr)
}
pub fn from(owned: Arc<ServoType>) -> *mut GeckoType {
unsafe { transmute(owned) }
}
pub unsafe fn addref(ptr: *mut GeckoType) {
Self::with(ptr, |arc| forget(arc.clone()));
}
pub 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) {
@ -307,7 +258,7 @@ pub extern "C" fn Servo_GetComputedValues(node: *mut RawGeckoNode)
// cases where Gecko wants the style for a node that Servo never // cases where Gecko wants the style for a node that Servo never
// traversed. We should remove this as soon as possible. // traversed. We should remove this as soon as possible.
error!("stylo: encountered unstyled node, substituting default values."); error!("stylo: encountered unstyled node, substituting default values.");
Arc::new(GeckoComputedValues::initial_values().clone()) Arc::new(ComputedValues::initial_values().clone())
}, },
}; };
unsafe { transmute(arc_cv) } unsafe { transmute(arc_cv) }
@ -328,7 +279,7 @@ pub extern "C" fn Servo_GetComputedValuesForAnonymousBox(parent_style_or_null: *
} }
}; };
type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>; type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>;
Helpers::maybe_with(parent_style_or_null, |maybe_parent| { Helpers::maybe_with(parent_style_or_null, |maybe_parent| {
let new_computed = data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent); let new_computed = data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent);
@ -367,7 +318,7 @@ pub extern "C" fn Servo_GetComputedValuesForPseudoElement(parent_style: *mut Ser
let element = unsafe { GeckoElement::from_raw(match_element) }; let element = unsafe { GeckoElement::from_raw(match_element) };
type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>; type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>;
match GeckoSelectorImpl::pseudo_element_cascade_type(&pseudo) { match GeckoSelectorImpl::pseudo_element_cascade_type(&pseudo) {
PseudoElementCascadeType::Eager => { PseudoElementCascadeType::Eager => {
@ -395,22 +346,22 @@ pub extern "C" fn Servo_GetComputedValuesForPseudoElement(parent_style: *mut Ser
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_InheritComputedValues(parent_style: *mut ServoComputedValues) pub extern "C" fn Servo_InheritComputedValues(parent_style: *mut ServoComputedValues)
-> *mut ServoComputedValues { -> *mut ServoComputedValues {
type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>; type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>;
Helpers::with(parent_style, |parent| { Helpers::with(parent_style, |parent| {
let style = GeckoComputedValues::inherit_from(parent); let style = ComputedValues::inherit_from(parent);
Helpers::from(style) Helpers::from(style)
}) })
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_AddRefComputedValues(ptr: *mut ServoComputedValues) -> () { pub extern "C" fn Servo_AddRefComputedValues(ptr: *mut ServoComputedValues) -> () {
type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>; type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>;
unsafe { Helpers::addref(ptr) }; unsafe { Helpers::addref(ptr) };
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_ReleaseComputedValues(ptr: *mut ServoComputedValues) -> () { pub extern "C" fn Servo_ReleaseComputedValues(ptr: *mut ServoComputedValues) -> () {
type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>; type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>;
unsafe { Helpers::release(ptr) }; unsafe { Helpers::release(ptr) };
} }

View file

@ -3,8 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern crate app_units; extern crate app_units;
#[macro_use]
extern crate cssparser;
extern crate env_logger; extern crate env_logger;
extern crate euclid; extern crate euclid;
extern crate gecko_bindings; extern crate gecko_bindings;
@ -26,18 +24,9 @@ mod context;
mod data; mod data;
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub mod glue; pub mod glue;
mod selector_impl;
mod traversal; mod traversal;
mod values;
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"));
}
// FIXME(bholley): This should probably go away once we harmonize the allocators. // FIXME(bholley): This should probably go away once we harmonize the allocators.
#[no_mangle] #[no_mangle]
pub extern "C" fn je_malloc_usable_size(_: *const ::libc::c_void) -> ::libc::size_t { 0 } pub extern "C" fn je_malloc_usable_size(_: *const ::libc::c_void) -> ::libc::size_t { 0 }

View file

@ -3,8 +3,8 @@
* 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::StandaloneStyleContext; use context::StandaloneStyleContext;
use selector_impl::SharedStyleContext;
use std::mem; use std::mem;
use style::context::SharedStyleContext;
use style::dom::OpaqueNode; use style::dom::OpaqueNode;
use style::traversal::{DomTraversalContext, recalc_style_at}; use style::traversal::{DomTraversalContext, recalc_style_at};
use wrapper::GeckoNode; use wrapper::GeckoNode;

View file

@ -27,8 +27,6 @@ use gecko_bindings::structs::nsIAtom;
use gecko_bindings::structs::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRTY_FOR_SERVO}; use gecko_bindings::structs::{NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO, NODE_IS_DIRTY_FOR_SERVO};
use glue::GeckoDeclarationBlock; use glue::GeckoDeclarationBlock;
use libc::uintptr_t; use libc::uintptr_t;
use properties::GeckoComputedValues;
use selector_impl::{GeckoSelectorImpl, NonTSPseudoClass, PrivateStyleData};
use selectors::Element; use selectors::Element;
use selectors::matching::DeclarationBlock; use selectors::matching::DeclarationBlock;
use selectors::parser::{AttrSelector, NamespaceConstraint}; use selectors::parser::{AttrSelector, NamespaceConstraint};
@ -38,15 +36,17 @@ use std::ptr;
use std::slice; use std::slice;
use std::sync::Arc; use std::sync::Arc;
use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace}; use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace};
use style::data::PrivateStyleData;
use style::dom::{OpaqueNode, PresentationalHintsSynthetizer}; use style::dom::{OpaqueNode, PresentationalHintsSynthetizer};
use style::dom::{TDocument, TElement, TNode, TRestyleDamage, UnsafeNode}; use style::dom::{TDocument, TElement, TNode, TRestyleDamage, UnsafeNode};
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::gecko_selector_impl::{GeckoSelectorImpl, NonTSPseudoClass};
#[allow(unused_imports)] // Used in commented-out code. #[allow(unused_imports)] // Used in commented-out code.
use style::parser::ParserContextExtraData; use style::parser::ParserContextExtraData;
#[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::{ComputedValues, parse_style_attribute};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock};
use style::refcell::{Ref, RefCell, RefMut}; use style::refcell::{Ref, RefCell, RefMut};
use style::restyle_hints::ElementSnapshot; use style::restyle_hints::ElementSnapshot;
@ -99,8 +99,7 @@ impl<'ln> GeckoNode<'ln> {
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct DummyRestyleDamage; pub struct DummyRestyleDamage;
impl TRestyleDamage for DummyRestyleDamage { impl TRestyleDamage for DummyRestyleDamage {
type ConcreteComputedValues = GeckoComputedValues; fn compute(_: Option<&Arc<ComputedValues>>, _: &ComputedValues) -> Self { DummyRestyleDamage }
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 {
@ -114,7 +113,6 @@ 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)

View file

@ -29,7 +29,7 @@ mod viewport;
mod writing_modes { mod writing_modes {
use style::logical_geometry::WritingMode; use style::logical_geometry::WritingMode;
use style::properties::{INITIAL_SERVO_VALUES, ComputedValues, get_writing_mode}; use style::properties::{INITIAL_SERVO_VALUES, get_writing_mode};
#[test] #[test]
fn initial_writing_mode_is_empty() { fn initial_writing_mode_is_empty() {

View file

@ -9,8 +9,7 @@ use std::borrow::ToOwned;
use style::error_reporting::ParseErrorReporter; use style::error_reporting::ParseErrorReporter;
use style::media_queries::*; use style::media_queries::*;
use style::parser::ParserContextExtraData; use style::parser::ParserContextExtraData;
use style::servo::Stylesheet; use style::stylesheets::{Stylesheet, Origin, CSSRuleIteratorExt};
use style::stylesheets::{Origin, CSSRuleIteratorExt};
use style::values::specified; use style::values::specified;
use url::Url; use url::Url;

View file

@ -13,8 +13,7 @@ use style::error_reporting::ParseErrorReporter;
use style::keyframes::{Keyframe, KeyframeSelector, KeyframePercentage}; use style::keyframes::{Keyframe, KeyframeSelector, KeyframePercentage};
use style::parser::ParserContextExtraData; use style::parser::ParserContextExtraData;
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredValue, longhands}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredValue, longhands};
use style::servo::Stylesheet; use style::stylesheets::{Stylesheet, CSSRule, StyleRule, KeyframesRule, Origin};
use style::stylesheets::{CSSRule, StyleRule, KeyframesRule, Origin};
use style::values::specified::{LengthOrPercentageOrAuto, Percentage}; use style::values::specified::{LengthOrPercentageOrAuto, Percentage};
use url::Url; use url::Url;

View file

@ -9,8 +9,7 @@ use media_queries::CSSErrorReporterTest;
use style::error_reporting::ParseErrorReporter; use style::error_reporting::ParseErrorReporter;
use style::media_queries::{Device, MediaType}; use style::media_queries::{Device, MediaType};
use style::parser::{ParserContext, ParserContextExtraData}; use style::parser::{ParserContext, ParserContextExtraData};
use style::servo::Stylesheet; use style::stylesheets::{Stylesheet, Origin, CSSRuleIteratorExt};
use style::stylesheets::{Origin, CSSRuleIteratorExt};
use style::values::specified::Length::{self, ViewportPercentage}; use style::values::specified::Length::{self, ViewportPercentage};
use style::values::specified::LengthOrPercentageOrAuto::{self, Auto}; use style::values::specified::LengthOrPercentageOrAuto::{self, Auto};
use style::values::specified::ViewportPercentageLength::Vw; use style::values::specified::ViewportPercentageLength::Vw;