servo: Merge #12515 - Make the style crate more concrete (from servo:concrete-style); r=bholley

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

Source-Repo: https://github.com/servo/servo
Source-Revision: 2d01d41a506bcbc7f26a2284b9f42390d6ef96ab

--HG--
rename : servo/ports/geckolib/selector_impl.rs => servo/components/style/gecko_selector_impl.rs
rename : servo/ports/geckolib/values.rs => servo/components/style/gecko_values.rs
rename : servo/ports/geckolib/properties.mako.rs => servo/components/style/properties/gecko.mako.rs
This commit is contained in:
Simon Sapin 2016-07-20 02:58:34 -05:00
parent 30054a91c4
commit c710b104be
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 string_cache::Atom;
use style::computed_values::{font_style, font_variant};
use style::properties::style_structs::ServoFont;
use style::properties::style_structs;
use webrender_traits;
#[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
/// a cached font if this font instance has already been used by
/// 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> {
self.expire_font_caches_if_necessary();
@ -297,7 +297,7 @@ impl HeapSizeOf for FontContext {
#[derive(Debug)]
struct LayoutFontGroupCacheKey {
pointer: Arc<ServoFont>,
pointer: Arc<style_structs::Font>,
size: Au,
}

View File

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

View File

@ -56,10 +56,9 @@ use std::fmt;
use std::sync::Arc;
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::context::StyleContext;
use style::context::{SharedStyleContext, StyleContext};
use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
use style::properties::{ComputedValues, ServoComputedValues};
use style::servo::SharedStyleContext;
use style::properties::ServoComputedValues;
use style::values::computed::{LengthOrNone, LengthOrPercentageOrNone};
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
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::position;
use style::computed_values::{caption_side, display, empty_cells, float, list_style_position};
use style::properties::{self, ComputedValues, ServoComputedValues};
use style::servo::SharedStyleContext;
use style::context::SharedStyleContext;
use style::properties::{self, ServoComputedValues};
use table::TableFlow;
use table_caption::TableCaptionFlow;
use table_cell::TableCellFlow;

View File

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

View File

@ -4,7 +4,7 @@
use construct::ConstructionResult;
use script_layout_interface::restyle_damage::RestyleDamage;
use style::servo::PrivateStyleData;
use style::data::PrivateStyleData;
/// Data that layout associates with a node.
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::{transform, transform_style, visibility};
use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
use style::properties::style_structs::ServoBorder;
use style::properties::{self, ComputedValues, ServoComputedValues};
use style::properties::style_structs;
use style::properties::{self, ServoComputedValues};
use style::values::RGBA;
use style::values::computed;
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.
// This is an extension of supporting elliptical radii. For now, all percentage
// 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::sync::Arc;
use style::computed_values::flex_direction;
use style::context::SharedStyleContext;
use style::logical_geometry::LogicalSize;
use style::properties::{ComputedValues, ServoComputedValues};
use style::servo::SharedStyleContext;
use style::properties::ServoComputedValues;
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
/// 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::{fmt, mem, raw};
use style::computed_values::{clear, display, empty_cells, float, position, overflow_x, text_align};
use style::context::SharedStyleContext;
use style::dom::TRestyleDamage;
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::properties::{self, ComputedValues, ServoComputedValues};
use style::servo::SharedStyleContext;
use style::properties::{self, ServoComputedValues};
use style::values::computed::LengthOrPercentageOrAuto;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, TableFlow};
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::dom::TRestyleDamage;
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::values::computed::LengthOrPercentageOrNone;
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::{display, list_style_type};
use style::dom::TRestyleDamage;
use style::properties::{ComputedValues, ServoComputedValues};
use style::properties::ServoComputedValues;
use text::TextRunScanner;
// 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::computed_values::{display, overflow_x, position, text_align, text_justify};
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::properties::{ComputedValues, ServoComputedValues};
use style::servo::SharedStyleContext;
use style::properties::ServoComputedValues;
use style::values::computed::LengthOrPercentage;
use text;
use unicode_bidi;

View File

@ -23,9 +23,9 @@ use inline::InlineMetrics;
use script_layout_interface::restyle_damage::RESOLVE_GENERATED_CONTENT;
use std::sync::Arc;
use style::computed_values::{list_style_type, position};
use style::context::SharedStyleContext;
use style::logical_geometry::LogicalSize;
use style::properties::{ComputedValues, ServoComputedValues};
use style::servo::SharedStyleContext;
use style::properties::ServoComputedValues;
use text;
/// 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 style::computed_values::transform::ComputedMatrix;
use style::logical_geometry::LogicalMargin;
use style::properties::{ComputedValues, ServoComputedValues};
use style::properties::ServoComputedValues;
use style::values::computed::{BorderRadiusSize, LengthOrPercentageOrAuto};
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::fmt;
use std::sync::Arc;
use style::context::StyleContext;
use style::context::{StyleContext, SharedStyleContext};
use style::logical_geometry::LogicalSize;
use style::properties::{ComputedValues, ServoComputedValues};
use style::servo::SharedStyleContext;
use style::properties::ServoComputedValues;
use style::values::computed::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
pub struct MulticolFlow {

View File

@ -31,11 +31,10 @@ use std::sync::{Arc, Mutex};
use string_cache::Atom;
use style::computed_values;
use style::logical_geometry::{WritingMode, BlockFlowDirection, InlineBaseDirection};
use style::properties::ComputedValues;
use style::properties::longhands::{display, position};
use style::properties::style_structs;
use style::selector_impl::PseudoElement;
use style::servo::Stylist;
use style::selector_matching::Stylist;
use style::values::LocalToCss;
use style_traits::cursor::Cursor;
use wrapper::ThreadSafeLayoutNodeHelpers;
@ -450,7 +449,7 @@ impl ParentOffsetBorderBoxIterator {
impl FragmentBorderBoxIterator for FragmentLocatingFragmentIterator {
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_right_width: right_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
// rectangle as `origin_rect` and the union of all child elements padding and
// margin rectangles as `union_rect`.
let style_structs::ServoBorder {
let style_structs::Border {
border_top_width: top_border,
border_right_width: right_border,
border_bottom_width: bottom_border,

View File

@ -26,9 +26,9 @@ use std::cmp;
use std::fmt;
use std::sync::Arc;
use style::computed_values::{border_collapse, border_spacing, table_layout};
use style::context::SharedStyleContext;
use style::logical_geometry::LogicalSize;
use style::properties::{ComputedValues, ServoComputedValues};
use style::servo::SharedStyleContext;
use style::properties::ServoComputedValues;
use style::values::CSSFloat;
use style::values::computed::LengthOrPercentageOrAuto;
use table_row::TableRowFlow;

View File

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

View File

@ -24,9 +24,9 @@ use script_layout_interface::wrapper_traits::ThreadSafeLayoutNode;
use std::fmt;
use std::sync::Arc;
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::properties::{ComputedValues, ServoComputedValues};
use style::servo::SharedStyleContext;
use style::properties::ServoComputedValues;
use table::InternalTable;
use table_row::{CollapsedBorder, CollapsedBorderProvenance};

View File

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

View File

@ -26,9 +26,9 @@ use std::fmt;
use std::iter::{Enumerate, IntoIterator, Peekable};
use std::sync::Arc;
use style::computed_values::{border_collapse, border_spacing, border_top_style};
use style::context::SharedStyleContext;
use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode};
use style::properties::{ComputedValues, ServoComputedValues};
use style::servo::SharedStyleContext;
use style::properties::ServoComputedValues;
use style::values::computed::LengthOrPercentageOrAuto;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt};
use table_cell::{CollapsedBordersForCell, TableCellFlow};

View File

@ -22,9 +22,9 @@ use std::fmt;
use std::iter::{IntoIterator, Iterator, Peekable};
use std::sync::Arc;
use style::computed_values::{border_collapse, border_spacing};
use style::context::SharedStyleContext;
use style::logical_geometry::{LogicalSize, WritingMode};
use style::properties::{ComputedValues, ServoComputedValues};
use style::servo::SharedStyleContext;
use style::properties::ServoComputedValues;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, TableLikeFlow};
use table_row;

View File

@ -31,9 +31,9 @@ use std::fmt;
use std::ops::Add;
use std::sync::Arc;
use style::computed_values::{border_collapse, table_layout};
use style::context::SharedStyleContext;
use style::logical_geometry::LogicalSize;
use style::properties::{ComputedValues, ServoComputedValues};
use style::servo::SharedStyleContext;
use style::properties::ServoComputedValues;
use style::values::CSSFloat;
use style::values::computed::LengthOrPercentageOrAuto;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize};

View File

@ -25,8 +25,8 @@ use std::sync::Arc;
use style::computed_values::white_space;
use style::computed_values::{line_height, text_orientation, text_rendering, text_transform};
use style::logical_geometry::{LogicalSize, WritingMode};
use style::properties::style_structs::ServoFont;
use style::properties::{ComputedValues, ServoComputedValues};
use style::properties::ServoComputedValues;
use style::properties::style_structs;
use unicode_bidi::{is_rtl, process_text};
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]
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 {
let fontgroup = font_context.layout_font_group_for_style(font_style);
// 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::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
use std::mem;
use style::context::SharedStyleContext;
use style::dom::TNode;
use style::properties::ServoComputedValues;
use style::selector_impl::ServoSelectorImpl;
use style::servo::SharedStyleContext;
use style::traversal::{DomTraversalContext, remove_from_bloom_filter, recalc_style_at};
use util::opts;
use wrapper::{LayoutNodeLayoutData, ThreadSafeLayoutNodeHelpers};
@ -27,7 +26,7 @@ pub struct 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>
{

View File

@ -35,7 +35,6 @@ use data::{LayoutDataFlags, PrivateLayoutData};
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData};
use style::computed_values::content::{self, ContentItem};
use style::properties::ComputedValues;
use style::refcell::{Ref, RefCell, RefMut};
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::mpsc::{channel, Sender, Receiver};
use std::sync::{Arc, Mutex, MutexGuard, RwLock};
use style::animation::Animation;
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::error_reporting::ParseErrorReporter;
use style::logical_geometry::LogicalPoint;
use style::media_queries::{Device, MediaType};
use style::parallel::WorkQueueData;
use style::properties::ComputedValues;
use style::refcell::RefCell;
use style::selector_matching::USER_OR_USER_AGENT_STYLESHEETS;
use style::servo::{Animation, LocalStyleContextCreationInfo, SharedStyleContext, Stylesheet, Stylist};
use style::stylesheets::CSSRuleIteratorExt;
use style::selector_matching::Stylist;
use style::servo_selector_impl::USER_OR_USER_AGENT_STYLESHEETS;
use style::stylesheets::{Stylesheet, CSSRuleIteratorExt};
use style::workqueue::WorkQueue;
use url::Url;
use util::geometry::MAX_RECT;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -13,12 +13,12 @@ use restyle_damage::RestyleDamage;
use std::sync::Arc;
use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace};
use style::computed_values::display;
use style::context::SharedStyleContext;
use style::dom::OpaqueNode;
use style::dom::{PresentationalHintsSynthetizer, TNode};
use style::properties::ServoComputedValues;
use style::refcell::{Ref, RefCell};
use style::selector_impl::{PseudoElement, PseudoElementCascadeType, ServoSelectorImpl};
use style::servo::SharedStyleContext;
use url::Url;
#[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::transition_timing_function::computed_value::StartEnd;
use properties::longhands::transition_timing_function::computed_value::TransitionTimingFunction;
use properties::style_struct_traits::Box;
use properties::{self, ComputedValues};
use selector_impl::SelectorImplExt;
use selectors::matching::DeclarationBlock;
use std::sync::Arc;
use std::sync::mpsc::Sender;
@ -53,7 +51,7 @@ pub enum KeyframesRunningState {
/// playing or paused).
// TODO: unify the use of f32/f64 in this file.
#[derive(Debug, Clone)]
pub struct KeyframesAnimationState<Impl: SelectorImplExt> {
pub struct KeyframesAnimationState {
/// The time this animation started at.
pub started_at: f64,
/// The duration of this animation.
@ -72,10 +70,10 @@ pub struct KeyframesAnimationState<Impl: SelectorImplExt> {
pub expired: bool,
/// The original cascade style, needed to compute the generated keyframes of
/// 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
/// the current iteration count, updates times and then toggles the
/// direction if appropriate.
@ -180,7 +178,7 @@ impl<Impl: SelectorImplExt> KeyframesAnimationState<Impl> {
/// State relating to an animation.
#[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.
///
/// 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),
/// A keyframes animation is identified by a name, and can have a
/// 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]
pub fn mark_as_expired(&mut self) {
debug_assert!(!self.is_expired());
@ -249,10 +247,10 @@ impl PropertyAnimation {
/// 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
/// one (for a single transition property) to arbitrarily many (for `all`).
pub fn from_transition<C: ComputedValues>(transition_index: usize,
old_style: &C,
new_style: &mut C)
-> Vec<PropertyAnimation> {
pub fn from_transition(transition_index: usize,
old_style: &ComputedValues,
new_style: &mut ComputedValues)
-> Vec<PropertyAnimation> {
let mut result = vec![];
let box_style = new_style.get_box();
let transition_property = box_style.transition_property_at(transition_index);
@ -286,12 +284,12 @@ impl PropertyAnimation {
result
}
fn from_transition_property<C: ComputedValues>(transition_property: TransitionProperty,
timing_function: TransitionTimingFunction,
duration: Time,
old_style: &C,
new_style: &C)
-> Option<PropertyAnimation> {
fn from_transition_property(transition_property: TransitionProperty,
timing_function: TransitionTimingFunction,
duration: Time,
old_style: &ComputedValues,
new_style: &ComputedValues)
-> Option<PropertyAnimation> {
let animated_property = AnimatedProperty::from_transition_property(&transition_property,
old_style,
new_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 {
TransitionTimingFunction::CubicBezier(p1, p2) => {
// See `WebCore::AnimationBase::solveEpsilon(double)` in WebKit.
@ -340,11 +338,11 @@ impl PropertyAnimation {
//
// TODO(emilio): Take rid of this mutex splitting SharedLayoutContex into a
// cloneable part and a non-cloneable part..
pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sender: &Sender<Animation<Impl>>,
node: OpaqueNode,
old_style: &Impl::ComputedValues,
new_style: &mut Arc<Impl::ComputedValues>)
-> bool {
pub fn start_transitions_if_applicable(new_animations_sender: &Sender<Animation>,
node: OpaqueNode,
old_style: &ComputedValues,
new_style: &mut Arc<ComputedValues>)
-> bool {
let mut had_animations = false;
for i in 0..new_style.get_box().transition_property_count() {
// Create any property animations, if applicable.
@ -373,11 +371,11 @@ pub fn start_transitions_if_applicable<Impl: SelectorImplExt>(new_animations_sen
had_animations
}
fn compute_style_for_animation_step<Impl: SelectorImplExt>(context: &SharedStyleContext<Impl>,
step: &KeyframesStep,
previous_style: &Impl::ComputedValues,
style_from_cascade: &Impl::ComputedValues)
-> Impl::ComputedValues {
fn compute_style_for_animation_step(context: &SharedStyleContext,
step: &KeyframesStep,
previous_style: &ComputedValues,
style_from_cascade: &ComputedValues)
-> ComputedValues {
match step.value {
// TODO: avoiding this spurious clone might involve having to create
// 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>,
new_animations_sender: &Sender<Animation<Impl>>,
node: OpaqueNode,
new_style: &Arc<Impl::ComputedValues>) -> bool
{
pub fn maybe_start_animations(context: &SharedStyleContext,
new_animations_sender: &Sender<Animation>,
node: OpaqueNode,
new_style: &Arc<ComputedValues>)
-> bool {
let mut had_animations = false;
let box_style = new_style.get_box();
@ -470,10 +468,10 @@ pub fn maybe_start_animations<Impl: SelectorImplExt>(context: &SharedStyleContex
/// Updates a given computed style for a given animation frame. Returns a bool
/// representing if the style was indeed updated.
pub fn update_style_for_animation_frame<C: ComputedValues>(mut new_style: &mut Arc<C>,
now: f64,
start_time: f64,
frame: &AnimationFrame) -> bool {
pub fn update_style_for_animation_frame(mut new_style: &mut Arc<ComputedValues>,
now: f64,
start_time: f64,
frame: &AnimationFrame) -> bool {
let mut progress = (now - start_time) / frame.duration;
if progress > 1.0 {
progress = 1.0
@ -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.
/// If `damage` is provided, inserts the appropriate restyle damage.
pub fn update_style_for_animation<Damage, Impl>(context: &SharedStyleContext<Impl>,
animation: &Animation<Impl>,
style: &mut Arc<Damage::ConcreteComputedValues>,
damage: Option<&mut Damage>)
where Impl: SelectorImplExt,
Damage: TRestyleDamage<ConcreteComputedValues = Impl::ComputedValues> {
pub fn update_style_for_animation<Damage>(context: &SharedStyleContext,
animation: &Animation,
style: &mut Arc<ComputedValues>,
damage: Option<&mut Damage>)
where Damage: TRestyleDamage {
debug!("update_style_for_animation: entering");
debug_assert!(!animation.is_expired());
match *animation {

View File

@ -10,7 +10,6 @@ use dom::OpaqueNode;
use error_reporting::ParseErrorReporter;
use euclid::Size2D;
use matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
use selector_impl::SelectorImplExt;
use selector_matching::Stylist;
use std::cell::RefCell;
use std::collections::HashMap;
@ -18,19 +17,19 @@ use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex, RwLock};
/// This structure is used to create a local style context from a shared one.
pub struct LocalStyleContextCreationInfo<Impl: SelectorImplExt> {
new_animations_sender: Sender<Animation<Impl>>,
pub struct LocalStyleContextCreationInfo {
new_animations_sender: Sender<Animation>,
}
impl<Impl: SelectorImplExt> LocalStyleContextCreationInfo<Impl> {
pub fn new(animations_sender: Sender<Animation<Impl>>) -> Self {
impl LocalStyleContextCreationInfo {
pub fn new(animations_sender: Sender<Animation>) -> Self {
LocalStyleContextCreationInfo {
new_animations_sender: animations_sender,
}
}
}
pub struct SharedStyleContext<Impl: SelectorImplExt> {
pub struct SharedStyleContext {
/// The current viewport size.
pub viewport_size: Size2D<Au>,
@ -38,7 +37,7 @@ pub struct SharedStyleContext<Impl: SelectorImplExt> {
pub screen_size_changed: bool,
/// 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.
/// This can be used to easily check for invalid stale data.
@ -48,28 +47,28 @@ pub struct SharedStyleContext<Impl: SelectorImplExt> {
pub goal: ReflowGoal,
/// 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.
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
pub error_reporter: Box<ParseErrorReporter + Sync>,
/// 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 applicable_declarations_cache: RefCell<ApplicableDeclarationsCache<Impl::ComputedValues>>,
pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache<Impl::ComputedValues>>,
pub struct LocalStyleContext {
pub applicable_declarations_cache: RefCell<ApplicableDeclarationsCache>,
pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache>,
/// A channel on which new animations that have been triggered by style
/// recalculation can be sent.
pub new_animations_sender: Sender<Animation<Impl>>,
pub new_animations_sender: Sender<Animation>,
}
impl<Impl: SelectorImplExt> LocalStyleContext<Impl> {
pub fn new(local_context_creation_data: &LocalStyleContextCreationInfo<Impl>) -> Self {
impl LocalStyleContext {
pub fn new(local_context_creation_data: &LocalStyleContextCreationInfo) -> Self {
LocalStyleContext {
applicable_declarations_cache: RefCell::new(ApplicableDeclarationsCache::new()),
style_sharing_candidate_cache: RefCell::new(StyleSharingCandidateCache::new()),
@ -78,9 +77,9 @@ impl<Impl: SelectorImplExt> LocalStyleContext<Impl> {
}
}
pub trait StyleContext<'a, Impl: SelectorImplExt> {
fn shared_context(&self) -> &'a SharedStyleContext<Impl>;
fn local_context(&self) -> &LocalStyleContext<Impl>;
pub trait StyleContext<'a> {
fn shared_context(&self) -> &'a SharedStyleContext;
fn local_context(&self) -> &LocalStyleContext;
}
/// Why we're doing reflow.

View File

@ -5,27 +5,26 @@
//! Per-node data used in style calculation.
use properties::ComputedValues;
use selectors::parser::SelectorImpl;
use selector_impl::PseudoElement;
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use std::sync::Arc;
use std::sync::atomic::AtomicIsize;
pub struct PrivateStyleData<Impl: SelectorImpl, ConcreteComputedValues: ComputedValues> {
pub struct PrivateStyleData {
/// 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).
pub per_pseudo: HashMap<Impl::PseudoElement, Arc<ConcreteComputedValues>,
pub per_pseudo: HashMap<PseudoElement, Arc<ComputedValues>,
BuildHasherDefault<::fnv::FnvHasher>>,
/// Information needed during parallel traversals.
pub parallel: DomParallelInfo,
}
impl<Impl, ConcreteComputedValues> PrivateStyleData<Impl, ConcreteComputedValues>
where Impl: SelectorImpl, ConcreteComputedValues: ComputedValues {
pub fn new() -> PrivateStyleData<Impl, ConcreteComputedValues> {
impl PrivateStyleData {
pub fn new() -> Self {
PrivateStyleData {
style: None,
per_pseudo: HashMap::with_hasher(Default::default()),

View File

@ -46,16 +46,14 @@ impl OpaqueNode {
}
pub trait TRestyleDamage : BitOr<Output=Self> + Copy {
type ConcreteComputedValues: ComputedValues;
fn compute(old: Option<&Arc<Self::ConcreteComputedValues>>, new: &Self::ConcreteComputedValues) -> Self;
fn compute(old: Option<&Arc<ComputedValues>>, new: &ComputedValues) -> Self;
fn rebuild_and_reflow() -> Self;
}
pub trait TNode : Sized + Copy + Clone {
type ConcreteElement: TElement<ConcreteNode = Self, ConcreteDocument = Self::ConcreteDocument>;
type ConcreteDocument: TDocument<ConcreteNode = Self, ConcreteElement = Self::ConcreteElement>;
type ConcreteRestyleDamage: TRestyleDamage<ConcreteComputedValues = Self::ConcreteComputedValues>;
type ConcreteComputedValues: ComputedValues;
type ConcreteRestyleDamage: TRestyleDamage;
fn to_unsafe(&self) -> UnsafeNode;
unsafe fn from_unsafe(n: &UnsafeNode) -> Self;
@ -146,21 +144,15 @@ pub trait TNode : Sized + Copy + Clone {
/// Borrows the PrivateStyleData without checks.
#[inline(always)]
unsafe fn borrow_data_unchecked(&self)
-> Option<*const PrivateStyleData<<Self::ConcreteElement as Element>::Impl,
Self::ConcreteComputedValues>>;
unsafe fn borrow_data_unchecked(&self) -> Option<*const PrivateStyleData>;
/// Borrows the PrivateStyleData immutably. Fails on a conflicting borrow.
#[inline(always)]
fn borrow_data(&self)
-> Option<Ref<PrivateStyleData<<Self::ConcreteElement as Element>::Impl,
Self::ConcreteComputedValues>>>;
fn borrow_data(&self) -> Option<Ref<PrivateStyleData>>;
/// Borrows the PrivateStyleData mutably. Fails on a conflicting borrow.
#[inline(always)]
fn mutate_data(&self)
-> Option<RefMut<PrivateStyleData<<Self::ConcreteElement as Element>::Impl,
Self::ConcreteComputedValues>>>;
fn mutate_data(&self) -> Option<RefMut<PrivateStyleData>>;
/// Get the description of how to account for recent style changes.
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
/// has not yet been performed, fails.
fn style(&self,
_context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>)
-> Ref<Arc<Self::ConcreteComputedValues>>
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt<ComputedValues=Self::ConcreteComputedValues> {
fn style(&self, _context: &SharedStyleContext) -> Ref<Arc<ComputedValues>>
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt {
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
* 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 string_cache::Atom;
use style;
use style::element_state::ElementState;
use style::selector_impl::{PseudoElementCascadeType, SelectorImplExt};
use stylesheets::Stylesheet;
pub type Stylist = style::selector_matching::Stylist<GeckoSelectorImpl>;
pub type Stylesheet = style::stylesheets::Stylesheet<GeckoSelectorImpl>;
pub type SharedStyleContext = style::context::SharedStyleContext<GeckoSelectorImpl>;
pub type PrivateStyleData = style::data::PrivateStyleData<GeckoSelectorImpl, GeckoComputedValues>;
pub type Animation = style::animation::Animation<GeckoSelectorImpl>;
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GeckoSelectorImpl;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
@ -135,8 +128,8 @@ pub enum NonTSPseudoClass {
impl NonTSPseudoClass {
pub fn state_flag(&self) -> ElementState {
use element_state::*;
use self::NonTSPseudoClass::*;
use style::element_state::*;
match *self {
Active => IN_ACTIVE_STATE,
Focus => IN_FOCUS_STATE,
@ -292,8 +285,6 @@ impl SelectorImpl for GeckoSelectorImpl {
}
impl SelectorImplExt for GeckoSelectorImpl {
type ComputedValues = GeckoComputedValues;
#[inline]
fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType {
match *pseudo {

View File

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

View File

@ -81,8 +81,10 @@ pub mod dom;
pub mod element_state;
pub mod error_reporting;
pub mod font_face;
#[cfg(feature = "gecko")]
pub mod gecko_conversions;
#[cfg(feature = "gecko")] 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 logical_geometry;
pub mod matching;
@ -94,7 +96,7 @@ pub mod restyle_hints;
pub mod selector_impl;
pub mod selector_matching;
pub mod sequential;
pub mod servo;
#[cfg(feature = "servo")] pub mod servo_selector_impl;
pub mod sink;
pub mod str;
pub mod stylesheets;
@ -116,6 +118,12 @@ pub mod properties {
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 {
( $( $name: ident )+ ) => {
/// Types for [computed values][computed].

View File

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

View File

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

View File

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

View File

@ -10,6 +10,7 @@
%>
use app_units::Au;
use custom_properties::ComputedValuesMap;
% for style_struct in data.style_structs:
use gecko_bindings::structs::${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_FontFamilyList_AppendGeneric, Gecko_FontFamilyList_AppendNamed};
use gecko_bindings::bindings::{Gecko_FontFamilyList_Clear, Gecko_InitializeImageLayer};
use gecko_bindings::bindings;
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::mem::{transmute, uninitialized, zeroed};
use std::sync::Arc;
use std::cmp;
use style::custom_properties::ComputedValuesMap;
use style::logical_geometry::WritingMode;
use style::properties::{CascadePropertyFn, ServoComputedValues, ComputedValues};
use style::properties::longhands;
use style::properties::style_struct_traits::*;
use values::{StyleCoordHelpers, GeckoStyleCoordConvertible, convert_nscolor_to_rgba};
use values::convert_rgba_to_nscolor;
use values::round_border_to_device_pixels;
pub mod style_structs {
% for style_struct in data.style_structs:
pub use super::${style_struct.gecko_struct_name} as ${style_struct.name};
% endfor
}
#[derive(Clone, Debug)]
pub struct GeckoComputedValues {
pub struct ComputedValues {
% 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
custom_properties: Option<Arc<ComputedValuesMap>>,
@ -50,9 +56,9 @@ pub struct GeckoComputedValues {
pub root_font_size: Au,
}
impl GeckoComputedValues {
impl ComputedValues {
pub fn inherit_from(parent: &Arc<Self>) -> Arc<Self> {
Arc::new(GeckoComputedValues {
Arc::new(ComputedValues {
custom_properties: parent.custom_properties.clone(),
shareable: parent.shareable,
writing_mode: parent.writing_mode,
@ -66,22 +72,16 @@ impl GeckoComputedValues {
% endfor
})
}
}
impl ComputedValues for GeckoComputedValues {
% 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>>,
pub fn new(custom_properties: Option<Arc<ComputedValuesMap>>,
shareable: bool,
writing_mode: WritingMode,
root_font_size: Au,
% 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
) -> Self {
GeckoComputedValues {
ComputedValues {
custom_properties: custom_properties,
shareable: shareable,
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
// matched no rules (that is, inherited style structs are inherited and
// 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]
fn do_cascade_property<F: FnOnce(&[CascadePropertyFn<Self>])>(f: F) {
pub fn do_cascade_property<F: FnOnce(&[CascadePropertyFn])>(f: F) {
f(&CASCADE_PROPERTY)
}
% for style_struct in data.style_structs:
#[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()
}
#[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}
}
#[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})
}
% endfor
fn custom_properties(&self) -> Option<Arc<ComputedValuesMap>> { self.custom_properties.as_ref().map(|x| x.clone())}
fn root_font_size(&self) -> Au { self.root_font_size }
fn set_root_font_size(&mut self, s: Au) { self.root_font_size = s; }
fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; }
pub fn custom_properties(&self) -> Option<Arc<ComputedValuesMap>> {
self.custom_properties.as_ref().map(|x| x.clone())
}
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.
#[inline]
fn is_multicol(&self) -> bool { false }
pub fn is_multicol(&self) -> bool { false }
}
<%def name="declare_style_struct(style_struct)">
@ -138,25 +141,29 @@ pub struct ${style_struct.gecko_struct_name} {
</%def>
<%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")}
}
</%def>
<%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}
}
</%def>
<%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};
}
</%def>
<%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});
}
</%def>
@ -180,8 +187,9 @@ def set_gecko_property(ffi_name, expr):
%>
<%def name="impl_keyword_setter(ident, gecko_ffi_name, keyword)">
fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
use style::properties::longhands::${ident}::computed_value::T as Keyword;
#[allow(non_snake_case)]
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
let result = match v {
% for value in keyword.values_for('gecko'):
@ -193,8 +201,9 @@ def set_gecko_property(ffi_name, expr):
</%def>
<%def name="impl_keyword_clone(ident, gecko_ffi_name, keyword)">
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use style::properties::longhands::${ident}::computed_value::T as Keyword;
#[allow(non_snake_case)]
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
match ${get_gecko_property(gecko_ffi_name)} as u32 {
% 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)">
#[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;
${clear_color_flags(color_flags_ffi_name)}
let result = match v {
@ -247,7 +257,8 @@ def set_gecko_property(ffi_name, expr):
</%def>
<%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:
${clear_color_flags(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 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;
% if 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 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:
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;
@ -305,26 +318,30 @@ def set_gecko_property(ffi_name, expr):
}
<%call expr="impl_simple_copy(ident, gecko_ffi_name)"></%call>
%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})
}
% endif
</%def>
<%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},
&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}) };
self.gecko.${unit_ffi_name} = other.gecko.${unit_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}) };
}
% if need_clone:
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use style::properties::longhands::${ident}::computed_value::T;
#[allow(non_snake_case)]
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},
&self.gecko.${union_ffi_name})
.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, \
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},
&mut self.gecko.${x_union_ffi_name});
v.0.height.to_gecko_style_coord(&mut self.gecko.${y_unit_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.${y_union_ffi_name}.reset(&mut self.gecko.${y_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}) };
}
% if need_clone:
fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use style::properties::longhands::${ident}::computed_value::T;
#[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use properties::longhands::${ident}::computed_value::T;
use euclid::Size2D;
let width = GeckoStyleCoordConvertible::from_gecko_style_coord(&self.gecko.${x_unit_ffi_name},
&self.gecko.${x_union_ffi_name})
@ -375,7 +395,7 @@ ${impl_split_style_coord(ident,
<%def name="impl_style_struct(style_struct)">
impl ${style_struct.gecko_struct_name} {
#[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() } });
unsafe {
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]
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.
*/
@ -476,24 +496,28 @@ impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} {
* Stubs.
*/
% 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) {
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) {
println!("stylo: Unimplemented property setter: ${longhand.name}");
}
}
% 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!()
}
% endif
% if longhand.need_index:
fn ${longhand.ident}_count(&self) -> usize { 0 }
fn ${longhand.ident}_at(&self, _index: usize) -> longhands::${longhand.ident}::computed_value::SingleComputedValue {
pub fn ${longhand.ident}_count(&self) -> usize { 0 }
pub fn ${longhand.ident}_at(&self, _index: usize)
-> longhands::${longhand.ident}::computed_value::SingleComputedValue {
unimplemented!()
}
% endif
@ -508,7 +532,7 @@ impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} {
<% data.manual_style_structs = [] %>
<%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}">
${caller.body()}
</%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,
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
}
% endfor
@ -621,15 +645,15 @@ fn static_assert() {
need_clone=True) %>
% endfor
fn set_z_index(&mut self, v: longhands::z_index::computed_value::T) {
use style::properties::longhands::z_index::computed_value::T;
pub fn set_z_index(&mut self, v: longhands::z_index::computed_value::T) {
use properties::longhands::z_index::computed_value::T;
match v {
T::Auto => self.gecko.mZIndex.set_auto(),
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;
// z-index is never a calc(). If it were, we'd be leaking here, so
// assert that it isn't.
@ -638,8 +662,8 @@ fn static_assert() {
self.gecko.mZIndex.mValue = other.gecko.mZIndex.mValue;
}
fn clone_z_index(&self) -> longhands::z_index::computed_value::T {
use style::properties::longhands::z_index::computed_value::T;
pub fn clone_z_index(&self) -> longhands::z_index::computed_value::T {
use properties::longhands::z_index::computed_value::T;
if self.gecko.mZIndex.is_auto() {
return T::Auto;
@ -649,8 +673,8 @@ fn static_assert() {
T::Number(self.gecko.mZIndex.get_int())
}
fn set_box_sizing(&mut self, v: longhands::box_sizing::computed_value::T) {
use style::computed_values::box_sizing::T;
pub fn set_box_sizing(&mut self, v: longhands::box_sizing::computed_value::T) {
use computed_values::box_sizing::T;
use gecko_bindings::structs::StyleBoxSizing;
// TODO: guess what to do with box-sizing: padding-box
self.gecko.mBoxSizing = match v {
@ -684,7 +708,7 @@ fn static_assert() {
"mOutlineRadius.mValues[%s]" % corner.y_index) %>
% endfor
fn outline_has_nonzero_width(&self) -> bool {
pub fn outline_has_nonzero_width(&self) -> bool {
self.gecko.mActualOutlineWidth != 0
}
</%self:impl_trait>
@ -693,8 +717,8 @@ fn static_assert() {
skip_longhands="font-family font-style font-size font-weight"
skip_additionals="*">
fn set_font_family(&mut self, v: longhands::font_family::computed_value::T) {
use style::properties::longhands::font_family::computed_value::FontFamily;
pub fn set_font_family(&mut self, v: longhands::font_family::computed_value::T) {
use properties::longhands::font_family::computed_value::FontFamily;
use gecko_bindings::structs::FontFamilyType;
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); }
}
@ -729,24 +753,24 @@ fn static_assert() {
// 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
// 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.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.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)
}
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;
}
${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 <= 900);
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.
fn compute_font_hash(&mut self) {}
pub fn compute_font_hash(&mut self) {}
</%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.
// We could generalize this if we run into other newtype keywords.
<% overflow_x = data.longhands_by_name["overflow-x"] %>
fn set_overflow_y(&mut self, v: longhands::overflow_y::computed_value::T) {
use style::properties::longhands::overflow_x::computed_value::T as BaseType;
pub fn set_overflow_y(&mut self, v: longhands::overflow_y::computed_value::T) {
use properties::longhands::overflow_x::computed_value::T as BaseType;
// FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts
self.gecko.mOverflowY = match v.0 {
% for value in overflow_x.keyword.values_for('gecko'):
@ -783,9 +807,9 @@ fn static_assert() {
};
}
${impl_simple_copy('overflow_y', 'mOverflowY')}
fn clone_overflow_y(&self) -> longhands::overflow_y::computed_value::T {
use style::properties::longhands::overflow_x::computed_value::T as BaseType;
use style::properties::longhands::overflow_y::computed_value::T as NewType;
pub fn clone_overflow_y(&self) -> longhands::overflow_y::computed_value::T {
use properties::longhands::overflow_x::computed_value::T as BaseType;
use properties::longhands::overflow_y::computed_value::T as NewType;
// FIXME(bholley): Align binary representations and ditch |match| for cast + static_asserts
match self.gecko.mOverflowY as u32 {
% 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 %>
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
match v {
% 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 {
use style::properties::longhands::vertical_align::computed_value::T;
use style::values::computed::LengthOrPercentage;
pub fn clone_vertical_align(&self) -> longhands::vertical_align::computed_value::T {
use properties::longhands::vertical_align::computed_value::T;
use values::computed::LengthOrPercentage;
if self.gecko.mVerticalAlign.is_enum() {
match self.gecko.mVerticalAlign.get_enum() as u32 {
@ -830,8 +854,9 @@ fn static_assert() {
<%call expr="impl_coord_copy('vertical_align', 'mVerticalAlign')"></%call>
fn set__moz_binding(&mut self, v: longhands::_moz_binding::computed_value::T) {
use style::properties::longhands::_moz_binding::SpecifiedValue as BindingValue;
#[allow(non_snake_case)]
pub fn set__moz_binding(&mut self, v: longhands::_moz_binding::computed_value::T) {
use properties::longhands::_moz_binding::SpecifiedValue as BindingValue;
match v {
BindingValue::None => debug_assert!(self.gecko.mBinding.mRawPtr.is_null()),
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); }
}
@ -854,8 +880,8 @@ fn static_assert() {
// Map 'auto' and 'avoid' to false, and 'always', 'left', and 'right' to true.
// "A conforming user agent may interpret the values 'left' and 'right'
// as 'always'." - CSS2.1, section 13.3.1
fn set_page_break_before(&mut self, v: longhands::page_break_before::computed_value::T) {
use style::computed_values::page_break_before::T;
pub fn set_page_break_before(&mut self, v: longhands::page_break_before::computed_value::T) {
use computed_values::page_break_before::T;
let result = match v {
T::auto => false,
T::always => true,
@ -871,8 +897,8 @@ fn static_assert() {
// Temp fix for Bugzilla bug 24000.
// See set_page_break_before for detail.
fn set_page_break_after(&mut self, v: longhands::page_break_after::computed_value::T) {
use style::computed_values::page_break_after::T;
pub fn set_page_break_after(&mut self, v: longhands::page_break_after::computed_value::T) {
use computed_values::page_break_after::T;
let result = match v {
T::auto => false,
T::always => true,
@ -900,14 +926,14 @@ fn static_assert() {
<% 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.mLayers.mFirstElement.mRepeat =
other.gecko.mImage.mLayers.mFirstElement.mRepeat;
}
fn set_background_repeat(&mut self, v: longhands::background_repeat::computed_value::T) {
use style::properties::longhands::background_repeat::computed_value::T;
pub fn set_background_repeat(&mut self, v: 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::nsStyleImageLayers_Repeat;
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.mLayers.mFirstElement.mClip =
other.gecko.mImage.mLayers.mFirstElement.mClip;
}
fn set_background_clip(&mut self, v: longhands::background_clip::computed_value::T) {
use style::properties::longhands::background_clip::computed_value::T;
pub fn set_background_clip(&mut self, v: longhands::background_clip::computed_value::T) {
use properties::longhands::background_clip::computed_value::T;
self.gecko.mImage.mClipCount = 1;
// 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.mLayers.mFirstElement.mOrigin =
other.gecko.mImage.mLayers.mFirstElement.mOrigin;
}
fn set_background_origin(&mut self, v: longhands::background_origin::computed_value::T) {
use style::properties::longhands::background_origin::computed_value::T;
pub fn set_background_origin(&mut self, v: longhands::background_origin::computed_value::T) {
use properties::longhands::background_origin::computed_value::T;
self.gecko.mImage.mOriginCount = 1;
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.mLayers.mFirstElement.mAttachment =
other.gecko.mImage.mLayers.mFirstElement.mAttachment;
}
fn set_background_attachment(&mut self, v: longhands::background_attachment::computed_value::T) {
use style::properties::longhands::background_attachment::computed_value::T;
pub fn set_background_attachment(&mut self, v: longhands::background_attachment::computed_value::T) {
use properties::longhands::background_attachment::computed_value::T;
self.gecko.mImage.mAttachmentCount = 1;
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 {
Gecko_CopyImageValueFrom(&mut self.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::{NS_STYLE_GRADIENT_SHAPE_LINEAR, NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER};
use gecko_bindings::structs::nsStyleCoord;
use style::values::computed::Image;
use style::values::specified::AngleOrCorner;
use values::computed::Image;
use values::specified::AngleOrCorner;
use cssparser::Color as CSSColor;
unsafe {
@ -1088,7 +1114,7 @@ fn static_assert() {
${impl_keyword_setter("list_style_type", "__LIST_STYLE_TYPE__",
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 {
Gecko_CopyListStyleTypeFrom(&mut self.gecko, &other.gecko);
}
@ -1103,8 +1129,8 @@ fn static_assert() {
"-moz-right match-parent") %>
${impl_keyword('text_align', 'mTextAlign', text_align_keyword, need_clone=False)}
fn set_line_height(&mut self, v: longhands::line_height::computed_value::T) {
use style::properties::longhands::line_height::computed_value::T;
pub fn set_line_height(&mut self, v: 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
match v {
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 {
use style::properties::longhands::line_height::computed_value::T;
pub fn clone_line_height(&self) -> longhands::line_height::computed_value::T {
use properties::longhands::line_height::computed_value::T;
if self.gecko.mLineHeight.is_normal() {
return T::Normal;
}
@ -1142,7 +1168,7 @@ fn static_assert() {
${impl_color("text_decoration_color", "mTextDecorationColor",
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;
if v.underline {
bits |= structs::NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE as u8;
@ -1159,17 +1185,17 @@ fn static_assert() {
${impl_simple_copy('text_decoration_line', 'mTextDecorationLine')}
#[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
}
#[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
}
#[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:impl_trait>
@ -1188,14 +1214,14 @@ fn static_assert() {
<%self:impl_trait style_struct_name="Color"
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);
${set_gecko_property("mColor", "result")}
}
<%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;
convert_nscolor_to_rgba(color)
}
@ -1203,8 +1229,8 @@ fn static_assert() {
<%self:impl_trait style_struct_name="Pointing"
skip_longhands="cursor">
fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) {
use style::properties::longhands::cursor::computed_value::T;
pub fn set_cursor(&mut self, v: longhands::cursor::computed_value::T) {
use properties::longhands::cursor::computed_value::T;
use style_traits::cursor::Cursor;
self.gecko.mCursor = match v {
@ -1255,7 +1281,7 @@ fn static_assert() {
<%self:impl_trait style_struct_name="Column"
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 {
Some(au) => self.gecko.mColumnWidth.set_coord(au),
None => self.gecko.mColumnWidth.set_auto(),
@ -1268,10 +1294,10 @@ fn static_assert() {
<%def name="define_ffi_struct_accessor(style_struct)">
#[no_mangle]
#[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} {
type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>;
Helpers::with(computed_values, |values| values.get_${style_struct.trait_name_lower}().get_gecko()
type Helpers = ArcHelpers<bindings::ServoComputedValues, ComputedValues>;
Helpers::with(computed_values, |values| values.get_${style_struct.name_lower}().get_gecko()
as *const ${style_struct.gecko_ffi_name})
}
</%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:
${declare_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>
% endif
${define_ffi_struct_accessor(style_struct)}
% endfor
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:
${style_struct.ident}: ${style_struct.gecko_struct_name}::initial(),
${style_struct.ident}: style_structs::${style_struct.name}::initial(),
% endfor
custom_properties: None,
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:
longhands::${property.ident}::cascade_property,
% endfor

View File

@ -64,7 +64,7 @@
use cssparser::Parser;
use parser::{ParserContext, ParserContextExtraData};
use properties::{CSSWideKeyword, DeclaredValue, Shorthand};
use values::computed::{TContext, ToComputedValue};
use values::computed::{Context, ToComputedValue};
use values::{computed, specified};
${caller.body()}
}
@ -144,7 +144,7 @@
type ComputedValue = computed_value::T;
#[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())
}
}
@ -170,21 +170,19 @@
use error_reporting::ParseErrorReporter;
use properties::longhands;
use properties::property_bit_field::PropertyBitField;
use properties::{ComputedValues, ServoComputedValues, PropertyDeclaration};
use properties::style_struct_traits::${data.current_style_struct.trait_name};
use properties::{ComputedValues, PropertyDeclaration};
use properties::style_structs;
use std::boxed::Box as StdBox;
use std::collections::HashMap;
use std::sync::Arc;
use values::computed::{TContext, ToComputedValue};
use values::computed::{Context, ToComputedValue};
use values::{computed, specified};
use string_cache::Atom;
${caller.body()}
#[allow(unused_variables)]
pub fn cascade_property<C: ComputedValues>(
declaration: &PropertyDeclaration,
inherited_style: &C,
context: &mut computed::Context<C>,
pub fn cascade_property(declaration: &PropertyDeclaration,
inherited_style: &ComputedValues,
context: &mut computed::Context,
seen: &mut PropertyBitField,
cacheable: &mut bool,
error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
@ -205,16 +203,16 @@
declared_value, &custom_props, |value| match *value {
DeclaredValue::Value(ref specified_value) => {
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);
}
DeclaredValue::WithVariables { .. } => unreachable!(),
DeclaredValue::Initial => {
// We assume that it's faster to use copy_*_from rather than
// set_*(get_initial_value());
let initial_struct = C::initial_values()
.get_${data.current_style_struct.trait_name_lower}();
context.mutate_style().mutate_${data.current_style_struct.trait_name_lower}()
let initial_struct = ComputedValues::initial_values()
.get_${data.current_style_struct.name_lower}();
context.mutate_style().mutate_${data.current_style_struct.name_lower}()
.copy_${property.ident}_from(initial_struct);
},
DeclaredValue::Inherit => {
@ -224,8 +222,8 @@
// FIXME: is it still?
*cacheable = false;
let inherited_struct =
inherited_style.get_${data.current_style_struct.trait_name_lower}();
context.mutate_style().mutate_${data.current_style_struct.trait_name_lower}()
inherited_style.get_${data.current_style_struct.name_lower}();
context.mutate_style().mutate_${data.current_style_struct.name_lower}()
.copy_${property.ident}_from(inherited_struct);
}
}, 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::visibility::computed_value::T as Visibility;
use properties::longhands::z_index::computed_value::T as ZIndex;
use properties::style_struct_traits::*;
use std::cmp;
use std::fmt;
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 {
% for prop in data.longhands:
% if prop.animatable:
@ -129,9 +128,10 @@ impl AnimatedProperty {
}
}
pub fn from_transition_property<C: ComputedValues>(transition_property: &TransitionProperty,
old_style: &C,
new_style: &C) -> AnimatedProperty {
pub fn from_transition_property(transition_property: &TransitionProperty,
old_style: &ComputedValues,
new_style: &ComputedValues)
-> AnimatedProperty {
match *transition_property {
TransitionProperty::All => panic!("Can't use TransitionProperty::All here."),
% for prop in data.longhands:

View File

@ -65,7 +65,7 @@ ${helpers.predefined_type("background-color", "CSSColor",
type ComputedValue = computed_value::T;
#[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 {
SpecifiedValue(None) => computed_value::T(None),
SpecifiedValue(Some(ref image)) =>
@ -172,7 +172,7 @@ ${helpers.predefined_type("background-color", "CSSColor",
type ComputedValue = computed_value::T;
#[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 {
horizontal: self.horizontal.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;
#[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 {
SpecifiedValue::Explicit(ref size) => {
computed_value::T::Explicit(computed_value::ExplicitSize {

View File

@ -62,7 +62,7 @@
type ComputedValue = computed_value::T;
#[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)
}
}

View File

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

View File

@ -15,7 +15,7 @@
type ComputedValue = computed_value::T;
#[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
}
}

View File

@ -63,7 +63,7 @@
type ComputedValue = computed_value::T;
#[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 {
SpecifiedValue::Auto => computed_value::T(None),
SpecifiedValue::Specified(l) =>
@ -129,7 +129,7 @@
type ComputedValue = computed_value::T;
#[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 {
SpecifiedValue::Auto => computed_value::T(None),
SpecifiedValue::Specified(count) =>
@ -209,7 +209,7 @@
type ComputedValue = computed_value::T;
#[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 {
SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) =>

View File

@ -98,7 +98,7 @@ ${helpers.predefined_type("opacity",
type ComputedValue = computed_value::T;
#[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 {
offset_x: self.offset_x.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;
#[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 {
top: value.top.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 {
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| {
match *value {
SpecifiedFilter::Blur(factor) =>
@ -1064,7 +1064,7 @@ ${helpers.predefined_type("opacity",
type ComputedValue = computed_value::T;
#[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() {
return computed_value::T(None)
}
@ -1275,7 +1275,7 @@ ${helpers.single_keyword("transform-style",
type ComputedValue = computed_value::T;
#[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 {
horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context),
@ -1361,7 +1361,7 @@ ${helpers.predefined_type("perspective",
type ComputedValue = computed_value::T;
#[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 {
horizontal: self.horizontal.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;
#[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 {
% for weight in range(100, 901, 100):
SpecifiedValue::Weight${weight} => computed_value::T::Weight${weight},
@ -288,7 +288,7 @@ ${helpers.single_keyword("font-variant",
type ComputedValue = computed_value::T;
#[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 {
LengthOrPercentage::Length(Length::FontRelative(value)) => {
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;
#[inline]
fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> computed_value::T {
fn to_computed_value(&self, _: &Context) -> computed_value::T {
*self
}
}
@ -131,8 +131,7 @@ ${helpers.single_keyword("color-adjust",
}
#[inline]
pub fn derive_from_display<Cx: TContext>(context: &mut Cx) {
use properties::style_struct_traits::Box;
pub fn derive_from_display(context: &mut Context) {
use super::display::computed_value::T as Display;
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;
#[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 {
horizontal: self.horizontal.to_computed_value(context),
vertical: self.vertical.to_computed_value(context),

View File

@ -102,7 +102,7 @@
type ComputedValue = computed_value::T;
#[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 {
SpecifiedValue::Normal => computed_value::T::Normal,
% if product == "gecko":
@ -248,7 +248,7 @@
type ComputedValue = computed_value::T;
#[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 {
SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) =>
@ -322,7 +322,7 @@
type ComputedValue = computed_value::T;
#[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 {
SpecifiedValue::Normal => computed_value::T(None),
SpecifiedValue::Specified(l) =>
@ -374,7 +374,6 @@ ${helpers.single_keyword("text-justify",
use values:: NoViewportPercentage;
use values::computed::ComputedValueAsSpecified;
use properties::style_struct_traits::{Box, Color, Text};
impl ComputedValueAsSpecified 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 {
Some(context.style().get_color().clone_color())
} 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
// declarations in effect and add in the text decorations that this block specifies.
let mut result = match context.style().get_box().clone_display() {
@ -439,13 +438,13 @@ ${helpers.single_keyword("text-justify",
}
#[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);
context.mutate_style().mutate_inheritedtext().set__servo_text_decorations_in_effect(derived);
}
#[inline]
pub fn derive_from_display<Cx: TContext>(context: &mut Cx) {
pub fn derive_from_display(context: &mut Context) {
let derived = derive(context);
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 {
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::TextShadow {
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;
#[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 {
SpecifiedValue::None => computed_value::T(None),
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;
#[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)
}
}

View File

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

View File

@ -13,28 +13,28 @@
use std::ascii::AsciiExt;
use std::boxed::Box as StdBox;
use std::collections::HashSet;
use std::fmt;
use std::fmt::{Debug, Write};
use std::fmt::{self, Write};
use std::sync::Arc;
use app_units::Au;
use cssparser::Color as CSSParserColor;
use cssparser::{Parser, RGBA, AtRuleParser, DeclarationParser, Delimiter,
#[cfg(feature = "servo")] use cssparser::{Color as CSSParserColor, RGBA};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter,
DeclarationListParser, parse_important, ToCss, TokenSerializationType};
use error_reporting::ParseErrorReporter;
use url::Url;
use euclid::side_offsets::SideOffsets2D;
#[cfg(feature = "servo")] use euclid::side_offsets::SideOffsets2D;
use euclid::size::Size2D;
use string_cache::Atom;
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 selectors::matching::DeclarationBlock;
use stylesheets::Origin;
use values::LocalToCss;
use values::HasViewportPercentage;
use values::computed::{self, TContext, ToComputedValue};
use values::specified::BorderStyle;
use values::computed::{self, ToComputedValue};
#[cfg(feature = "servo")] use values::specified::BorderStyle;
use self::property_bit_field::PropertyBitField;
@ -1082,104 +1082,34 @@ impl PropertyDeclaration {
}
}
pub mod style_struct_traits {
use super::longhands;
use std::fmt::Debug;
% for style_struct in data.active_style_structs():
pub trait ${style_struct.trait_name}: Debug + Clone {
% for longhand in style_struct.longhands:
#[allow(non_snake_case)]
fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T);
#[allow(non_snake_case)]
fn copy_${longhand.ident}_from(&mut self, other: &Self);
% 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)]
#[inline]
fn ${longhand.ident}_iter<'a>(&'a self)
-> ${longhand.camel_case}Iter<'a, Self> {
${longhand.camel_case}Iter {
style_struct: self,
current: 0,
max: self.${longhand.ident}_count(),
}
}
#[allow(non_snake_case)]
#[inline]
fn ${longhand.ident}_mod(&self, index: usize)
-> longhands::${longhand.ident}::computed_value::SingleComputedValue {
self.${longhand.ident}_at(index % self.${longhand.ident}_count())
}
% endif
% endfor
% for additional in style_struct.additional_methods:
#[allow(non_snake_case)]
${additional.declare()}
% endfor
}
% for longhand in style_struct.longhands:
% if longhand.need_index:
pub struct ${longhand.camel_case}Iter<'a, S: ${style_struct.trait_name} + 'static> {
style_struct: &'a S,
current: usize,
max: usize,
}
impl<'a, S: ${style_struct.trait_name} + 'static> Iterator for ${longhand.camel_case}Iter<'a, S> {
type Item = longhands::${longhand.ident}::computed_value::SingleComputedValue;
fn next(&mut self) -> Option<Self::Item> {
self.current += 1;
if self.current <= self.max {
Some(self.style_struct.${longhand.ident}_at(self.current - 1))
} else {
None
}
}
}
% endif
% endfor
% endfor
}
#[cfg(feature = "gecko")]
pub use gecko_properties::style_structs;
#[cfg(feature = "servo")]
pub mod style_structs {
use fnv::FnvHasher;
use super::longhands;
use std::hash::{Hash, Hasher};
% for style_struct in data.active_style_structs():
% if style_struct.trait_name == "Font":
% if style_struct.name == "Font":
#[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} {
#[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.trait_name == "Font":
% if style_struct.name == "Font":
pub hash: u64,
% endif
}
% if style_struct.trait_name == "Font":
% if style_struct.name == "Font":
impl PartialEq for ${style_struct.servo_struct_name} {
fn eq(&self, other: &${style_struct.servo_struct_name}) -> bool {
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}
@ -1188,42 +1118,48 @@ pub mod style_structs {
}
% endif
impl super::style_struct_traits::${style_struct.trait_name} for ${style_struct.servo_struct_name} {
impl ${style_struct.name} {
% for longhand in style_struct.longhands:
#[allow(non_snake_case)]
#[inline]
fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T) {
pub fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T) {
self.${longhand.ident} = v;
}
#[allow(non_snake_case)]
#[inline]
fn copy_${longhand.ident}_from(&mut self, other: &Self) {
pub fn copy_${longhand.ident}_from(&mut self, other: &Self) {
self.${longhand.ident} = other.${longhand.ident}.clone();
}
% if longhand.need_clone:
#[allow(non_snake_case)]
#[inline]
fn clone_${longhand.ident}(&self) -> longhands::${longhand.ident}::computed_value::T {
pub 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 {
#[allow(non_snake_case)]
pub fn ${longhand.ident}_count(&self) -> usize {
self.${longhand.ident}.0.len()
}
fn ${longhand.ident}_at(&self, index: usize)
#[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.trait_name == "Border":
% if style_struct.name == "Border":
% for side in ["top", "right", "bottom", "left"]:
fn border_${side}_has_nonzero_width(&self) -> bool {
#[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.trait_name == "Font":
fn compute_font_hash(&mut self) {
% 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);
@ -1231,23 +1167,23 @@ pub mod style_structs {
self.font_family.hash(&mut hasher);
self.hash = hasher.finish()
}
% elif style_struct.trait_name == "Outline":
% elif style_struct.name == "Outline":
#[inline]
fn outline_has_nonzero_width(&self) -> bool {
pub fn outline_has_nonzero_width(&self) -> bool {
self.outline_width != ::app_units::Au(0)
}
% elif style_struct.trait_name == "Text":
% elif style_struct.name == "Text":
<% text_decoration_field = 'text_decoration' if product == 'servo' else 'text_decoration_line' %>
#[inline]
fn has_underline(&self) -> bool {
pub fn has_underline(&self) -> bool {
self.${text_decoration_field}.underline
}
#[inline]
fn has_overline(&self) -> bool {
pub fn has_overline(&self) -> bool {
self.${text_decoration_field}.overline
}
#[inline]
fn has_line_through(&self) -> bool {
pub fn has_line_through(&self) -> bool {
self.${text_decoration_field}.line_through
}
% endif
@ -1256,47 +1192,66 @@ pub mod style_structs {
% 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
% 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 {
style_struct: self,
current: 0,
max: self.${longhand.ident}_count(),
}
}
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}>,
#[allow(non_snake_case)]
#[inline]
pub fn ${longhand.ident}_mod(&self, index: usize)
-> longhands::${longhand.ident}::computed_value::SingleComputedValue {
self.${longhand.ident}_at(index % self.${longhand.ident}_count())
}
% endif
% endfor
) -> Self;
}
fn style_for_child_text_node(parent: &Arc<Self>) -> Arc<Self>;
% for longhand in style_struct.longhands:
% if longhand.need_index:
pub struct ${longhand.camel_case}Iter<'a> {
style_struct: &'a style_structs::${style_struct.name},
current: usize,
max: usize,
}
fn initial_values() -> &'static Self;
impl<'a> Iterator for ${longhand.camel_case}Iter<'a> {
type Item = longhands::${longhand.ident}::computed_value::SingleComputedValue;
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};
fn next(&mut self) -> Option<Self::Item> {
self.current += 1;
if self.current <= self.max {
Some(self.style_struct.${longhand.ident}_at(self.current - 1))
} else {
None
}
}
}
% endif
% endfor
% 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 {
#[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():
${style_struct.ident}: Arc<style_structs::${style_struct.servo_struct_name}>,
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
shareable: bool,
@ -1304,85 +1259,77 @@ pub struct ServoComputedValues {
pub root_font_size: Au,
}
impl ComputedValues for ServoComputedValues {
% for style_struct in data.active_style_structs():
type Concrete${style_struct.trait_name} = style_structs::${style_struct.servo_struct_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<style_structs::${style_struct.servo_struct_name}>,
% endfor
) -> Self {
ServoComputedValues {
custom_properties: custom_properties,
shareable: shareable,
writing_mode: writing_mode,
root_font_size: root_font_size,
% for style_struct in data.active_style_structs():
${style_struct.ident}: ${style_struct.ident},
% endfor
}
#[cfg(feature = "servo")]
impl ComputedValues {
pub 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<style_structs::${style_struct.name}>,
% endfor
) -> Self {
ComputedValues {
custom_properties: custom_properties,
shareable: shareable,
writing_mode: writing_mode,
root_font_size: root_font_size,
% for style_struct in data.active_style_structs():
${style_struct.ident}: ${style_struct.ident},
% endfor
}
}
fn style_for_child_text_node(parent: &Arc<Self>) -> Arc<Self> {
// Text nodes get a copy of the parent style. Inheriting all non-
// inherited properties into the text node is odd from a CSS
// perspective, but makes fragment construction easier (by making
// properties like vertical-align on fragments have values that
// match the parent element). This is an implementation detail of
// Servo layout that is not central to how fragment construction
// works, but would be difficult to change. (Text node style is
// also not visible to script.)
parent.clone()
}
pub fn style_for_child_text_node(parent: &Arc<Self>) -> Arc<Self> {
// Text nodes get a copy of the parent style. Inheriting all non-
// inherited properties into the text node is odd from a CSS
// perspective, but makes fragment construction easier (by making
// properties like vertical-align on fragments have values that
// match the parent element). This is an implementation detail of
// Servo layout that is not central to how fragment construction
// works, but would be difficult to change. (Text node style is
// also not visible to script.)
parent.clone()
}
fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
pub fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
#[inline]
fn do_cascade_property<F: FnOnce(&[CascadePropertyFn<Self>])>(f: F) {
f(&CASCADE_PROPERTY)
}
#[inline]
pub fn do_cascade_property<F: FnOnce(&[CascadePropertyFn])>(f: F) {
f(&CASCADE_PROPERTY)
}
% for style_struct in data.active_style_structs():
#[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()
}
#[inline]
fn get_${style_struct.trait_name_lower}<'a>(&'a self) ->
&'a Self::Concrete${style_struct.trait_name} {
&self.${style_struct.ident}
}
pub fn get_${style_struct.name_lower}(&self) -> &style_structs::${style_struct.name} {
&self.${style_struct.ident}
}
#[inline]
fn mutate_${style_struct.trait_name_lower}<'a>(&'a mut self) ->
&'a mut Self::Concrete${style_struct.trait_name} {
Arc::make_mut(&mut self.${style_struct.ident})
}
pub fn mutate_${style_struct.name_lower}(&mut self) -> &mut style_structs::${style_struct.name} {
Arc::make_mut(&mut self.${style_struct.ident})
}
% endfor
// Cloning the Arc here is fine because it only happens in the case where we have custom
// properties, and those are both rare and expensive.
fn custom_properties(&self) -> Option<Arc<::custom_properties::ComputedValuesMap>> {
pub fn custom_properties(&self) -> Option<Arc<::custom_properties::ComputedValuesMap>> {
self.custom_properties.as_ref().map(|x| x.clone())
}
fn root_font_size(&self) -> Au { self.root_font_size }
fn set_root_font_size(&mut self, size: Au) { self.root_font_size = size }
fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; }
pub fn root_font_size(&self) -> Au { self.root_font_size }
pub fn set_root_font_size(&mut self, size: Au) { self.root_font_size = size }
pub fn set_writing_mode(&mut self, mode: WritingMode) { self.writing_mode = mode; }
#[inline]
fn is_multicol(&self) -> bool {
pub fn is_multicol(&self) -> bool {
let style = self.get_column();
style.column_count.0.is_some() || style.column_width.0.is_some()
}
}
impl ServoComputedValues {
/// Resolves the currentColor keyword.
/// Any color value form computed values (except for the 'color' property itself)
/// should go through this method.
@ -1483,7 +1430,7 @@ impl ServoComputedValues {
}
#[inline]
pub fn get_font_arc(&self) -> Arc<style_structs::ServoFont> {
pub fn get_font_arc(&self) -> Arc<style_structs::Font> {
self.font.clone()
}
@ -1566,7 +1513,7 @@ impl ServoComputedValues {
/// 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;
let mut flags = WritingMode::empty();
match inheritedbox_style.clone_direction() {
@ -1607,43 +1554,53 @@ pub fn get_writing_mode<S: style_struct_traits::InheritedBox>(inheritedbox_style
}
/// The initial values for all style structs as defined by the specification.
lazy_static! {
pub static ref INITIAL_SERVO_VALUES: ServoComputedValues = ServoComputedValues {
% for style_struct in data.active_style_structs():
${style_struct.ident}: Arc::new(style_structs::${style_struct.servo_struct_name} {
% for longhand in style_struct.longhands:
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
% endfor
% if style_struct.trait_name == "Font":
hash: 0,
% endif
}),
% endfor
custom_properties: None,
shareable: true,
writing_mode: WritingMode::empty(),
root_font_size: longhands::font_size::get_initial_value(),
};
}
#[cfg(feature = "servo")]
pub use self::lazy_static_module::INITIAL_SERVO_VALUES;
// 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():
${style_struct.ident}: Arc::new(style_structs::${style_struct.name} {
% for longhand in style_struct.longhands:
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
% endfor
% if style_struct.name == "Font":
hash: 0,
% endif
}),
% endfor
custom_properties: None,
shareable: true,
writing_mode: WritingMode::empty(),
root_font_size: longhands::font_size::get_initial_value(),
};
}
}
/// Fast path for the function below. Only computes new inherited styles.
#[allow(unused_mut, unused_imports)]
fn cascade_with_cached_declarations<C: ComputedValues>(
fn cascade_with_cached_declarations(
viewport_size: Size2D<Au>,
applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>],
shareable: bool,
parent_style: &C,
cached_style: &C,
parent_style: &ComputedValues,
cached_style: &ComputedValues,
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
mut error_reporter: StdBox<ParseErrorReporter + Send>)
-> C {
-> ComputedValues {
let mut context = computed::Context {
is_root_element: false,
viewport_size: viewport_size,
inherited_style: parent_style,
style: C::new(
style: ComputedValues::new(
custom_properties,
shareable,
WritingMode::empty(),
@ -1654,7 +1611,7 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
% else:
cached_style
% endif
.clone_${style_struct.trait_name_lower}(),
.clone_${style_struct.name_lower}(),
% endfor
),
};
@ -1671,7 +1628,6 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
PropertyDeclaration::${property.camel_case}(ref
${'_' if not style_struct.inherited else ''}declared_value)
=> {
use properties::style_struct_traits::${style_struct.trait_name};
% if style_struct.inherited:
if seen.get_${property.ident}() {
continue
@ -1684,14 +1640,14 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
DeclaredValue::Value(ref specified_value)
=> {
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);
},
DeclaredValue::Initial
=> {
// FIXME(bholley): We may want set_X_to_initial_value() here.
let initial = longhands::${property.ident}::get_initial_value();
context.mutate_style().mutate_${style_struct.trait_name_lower}()
context.mutate_style().mutate_${style_struct.name_lower}()
.set_${property.ident}(initial);
},
DeclaredValue::Inherit => {
@ -1700,7 +1656,7 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
//
// FIXME: is it still?
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);
}
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() ||
seen.get_font_family() {
use properties::style_struct_traits::Font;
context.mutate_style().mutate_font().compute_font_hash();
}
context.style
}
pub type CascadePropertyFn<C /*: ComputedValues */> =
pub type CascadePropertyFn =
extern "Rust" fn(declaration: &PropertyDeclaration,
inherited_style: &C,
context: &mut computed::Context<C>,
inherited_style: &ComputedValues,
context: &mut computed::Context,
seen: &mut PropertyBitField,
cacheable: &mut bool,
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:
longhands::${property.ident}::cascade_property,
% endfor
@ -1768,16 +1724,14 @@ static CASCADE_PROPERTY: [CascadePropertyFn<ServoComputedValues>; ${len(data.lon
/// this is ignored.
///
/// Returns the computed values and a boolean indicating whether the result is cacheable.
pub fn cascade<C: ComputedValues>(
viewport_size: Size2D<Au>,
pub fn cascade(viewport_size: Size2D<Au>,
applicable_declarations: &[DeclarationBlock<Vec<PropertyDeclaration>>],
shareable: bool,
parent_style: Option<<&C>,
cached_style: Option<<&C>,
parent_style: Option<<&ComputedValues>,
cached_style: Option<<&ComputedValues>,
mut error_reporter: StdBox<ParseErrorReporter + Send>)
-> (C, bool) {
use properties::style_struct_traits::{Border, Box, Font, Outline};
let initial_values = C::initial_values();
-> (ComputedValues, bool) {
let initial_values = ComputedValues::initial_values();
let (is_root_element, inherited_style) = match parent_style {
Some(parent_style) => (false, parent_style),
None => (true, initial_values),
@ -1817,7 +1771,7 @@ pub fn cascade<C: ComputedValues>(
is_root_element: is_root_element,
viewport_size: viewport_size,
inherited_style: inherited_style,
style: C::new(
style: ComputedValues::new(
custom_properties,
shareable,
WritingMode::empty(),
@ -1828,7 +1782,7 @@ pub fn cascade<C: ComputedValues>(
% else:
initial_values
% endif
.clone_${style_struct.trait_name_lower}(),
.clone_${style_struct.name_lower}(),
% 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
// of compiled code! To improve i-cache behavior, we outline the individual functions and use
// virtual dispatch instead.
C::do_cascade_property(|cascade_property| {
ComputedValues::do_cascade_property(|cascade_property| {
% for category_to_cascade_now in ["early", "other"]:
for sub_list in applicable_declarations.iter().rev() {
// Declarations are already stored in reverse order.
@ -1940,7 +1894,6 @@ pub fn cascade<C: ComputedValues>(
% 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_items::T as align_items;
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() ||
seen.get_font_family() {
use properties::style_struct_traits::Font;
style.mutate_font().compute_font_hash();
}
@ -1988,7 +1940,8 @@ pub fn cascade<C: ComputedValues>(
(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) {
// The 'align-self' property needs some special treatment since
// 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);
% for style_struct in data.active_style_structs():
% 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
% endfor
% 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`).
///
/// FIXME(#5625, pcwalton): It would probably be cleaner and faster to do this in the cascade.
#[cfg(feature = "servo")]
#[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>`.
if style.box_.display != longhands::display::computed_value::T::inline {
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
/// not outermost.
#[cfg(feature = "servo")]
#[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_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 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.
#[cfg(feature = "servo")]
#[inline]
pub fn modify_style_for_anonymous_table_object(
style: &mut Arc<ServoComputedValues>,
style: &mut Arc<ComputedValues>,
new_display_value: longhands::display::computed_value::T) {
let mut style = Arc::make_mut(style);
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.
#[cfg(feature = "servo")]
#[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 box_style = Arc::make_mut(&mut style.box_);
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
/// itself relatively positioned.
#[cfg(feature = "servo")]
#[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 {
// 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`.
@ -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
/// 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 margin_style = Arc::make_mut(&mut style.margin);
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
/// 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() {
let mut style = Arc::make_mut(style);
let effects_style = Arc::make_mut(&mut style.effects);

View File

@ -6,10 +6,11 @@
use attr::{AttrIdentifier, AttrValue};
use element_state::*;
use selector_impl::SelectorImplExt;
use selector_impl::{SelectorImplExt, TheSelectorImpl, AttrString};
use selectors::matching::matches_compound_selector;
use selectors::parser::{AttrSelector, Combinator, CompoundSelector, SelectorImpl, SimpleSelector};
use selectors::{Element, MatchAttrGeneric};
#[cfg(feature = "gecko")] use selectors::MatchAttr;
use std::clone::Clone;
use std::sync::Arc;
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
// specialize it to the Servo configuration.
struct ElementWrapper<'a, E>
where E: Element<AttrString=String>,
where E: Element<AttrString=AttrString>,
E::Impl: SelectorImplExt {
element: E,
snapshot: &'a ElementSnapshot,
}
impl<'a, E> ElementWrapper<'a, E>
where E: Element<AttrString=String>,
where E: Element<AttrString=AttrString>,
E::Impl: SelectorImplExt {
pub fn new(el: E) -> ElementWrapper<'a, E> {
ElementWrapper { element: el, snapshot: &EMPTY_SNAPSHOT }
@ -108,7 +109,7 @@ impl<'a, E> ElementWrapper<'a, E>
#[cfg(not(feature = "gecko"))]
impl<'a, E> MatchAttrGeneric for ElementWrapper<'a, E>
where E: Element<AttrString=String>,
where E: Element<AttrString=AttrString>,
E: MatchAttrGeneric,
E::Impl: SelectorImplExt {
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")]
impl<'a, E> MatchAttrGeneric for ElementWrapper<'a, E>
where E: Element<AttrString=String>,
E: MatchAttrGeneric,
impl<'a, E> MatchAttr for ElementWrapper<'a, E>
where E: Element<AttrString=AttrString>,
E::Impl: SelectorImplExt {
fn match_attr<F>(&self, _: &AttrSelector, _: F) -> bool
where F: Fn(&str) -> bool {
type AttrString = AttrString;
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");
}
}
impl<'a, E> Element for ElementWrapper<'a, E>
where E: Element<AttrString=String>,
where E: Element<AttrString=AttrString>,
E: MatchAttrGeneric,
E::Impl: SelectorImplExt {
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 {
SimpleSelector::NonTSPseudoClass(ref pc) => Impl::pseudo_class_state_flag(pc),
SimpleSelector::NonTSPseudoClass(ref pc) => TheSelectorImpl::pseudo_class_state_flag(pc),
_ => ElementState::empty(),
}
}
fn is_attr_selector<Impl: SelectorImpl>(sel: &SimpleSelector<Impl>) -> bool {
fn is_attr_selector(sel: &SimpleSelector<TheSelectorImpl>) -> bool {
match *sel {
SimpleSelector::ID(_) |
SimpleSelector::Class(_) |
@ -287,24 +316,24 @@ impl Sensitivities {
// elements in the document.
#[derive(Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
struct Dependency<Impl: SelectorImplExt> {
selector: Arc<CompoundSelector<Impl>>,
struct Dependency {
selector: Arc<CompoundSelector<TheSelectorImpl>>,
combinator: Option<Combinator>,
sensitivities: Sensitivities,
}
#[derive(Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct DependencySet<Impl: SelectorImplExt> {
deps: Vec<Dependency<Impl>>,
pub struct DependencySet {
deps: Vec<Dependency>,
}
impl<Impl: SelectorImplExt> DependencySet<Impl> {
pub fn new() -> DependencySet<Impl> {
impl DependencySet {
pub fn new() -> Self {
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 combinator: Option<Combinator> = None;
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)
-> 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 attrs_changed = snapshot.attrs.is_some();
let mut hint = RestyleHint::empty();

View File

@ -5,13 +5,22 @@
//! The pseudo-classes and pseudo-elements supported by the style system.
use element_state::ElementState;
use properties::{self, ServoComputedValues};
use selector_matching::{USER_OR_USER_AGENT_STYLESHEETS, QUIRKS_MODE_STYLESHEET};
use selectors::Element;
use selectors::parser::{ParserContext, SelectorImpl};
use selectors::parser::SelectorImpl;
use std::fmt::Debug;
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.
///
/// 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;
}
// NB: The `Clone` trait is here for convenience due to:
// https://github.com/rust-lang/rust/issues/26925
pub trait SelectorImplExt : SelectorImpl + Clone + Debug + Sized + 'static {
type ComputedValues: properties::ComputedValues;
fn pseudo_element_cascade_type(pseudo: &Self::PseudoElement) -> PseudoElementCascadeType;
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 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>>;
}
#[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)
}
fn get_quirks_mode_stylesheet() -> Option<&'static Stylesheet>;
}

View File

@ -9,86 +9,26 @@ use element_state::*;
use error_reporting::StdoutErrorReporter;
use keyframes::KeyframesAnimation;
use media_queries::{Device, MediaType};
use parser::ParserContextExtraData;
use properties::{self, PropertyDeclaration, PropertyDeclarationBlock};
use properties::{self, PropertyDeclaration, PropertyDeclarationBlock, ComputedValues};
use restyle_hints::{ElementSnapshot, RestyleHint, DependencySet};
use selector_impl::{SelectorImplExt, ServoSelectorImpl};
use selector_impl::{SelectorImplExt, TheSelectorImpl, PseudoElement, AttrString};
use selectors::bloom::BloomFilter;
use selectors::matching::DeclarationBlock as GenericDeclarationBlock;
use selectors::matching::{Rule, SelectorMap};
use selectors::parser::SelectorImpl;
use selectors::{Element, MatchAttrGeneric};
use sink::Push;
use smallvec::VecLike;
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use std::process;
use std::sync::Arc;
use string_cache::Atom;
use style_traits::viewport::ViewportConstraints;
use stylesheets::{CSSRule, CSSRuleIteratorExt, Origin, Stylesheet};
use url::Url;
use util::opts;
use util::resource_files::read_resource_file;
use viewport::{MaybeNew, ViewportRuleCascade};
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
/// for a given document. The selectors are converted into `Rule`s
/// (defined in rust-selectors), and introduced in a `SelectorMap`
@ -106,7 +46,7 @@ lazy_static! {
/// regular builds, or `GeckoSelectorImpl`, the implementation used in the
/// geckolib port.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Stylist<Impl: SelectorImplExt> {
pub struct Stylist {
/// Device that the stylist is currently evaluating against.
pub device: Device,
@ -121,12 +61,12 @@ pub struct Stylist<Impl: SelectorImplExt> {
/// The current selector maps, after evaluating media
/// rules against the current device.
element_map: PerPseudoElementSelectorMap<Impl>,
element_map: PerPseudoElementSelectorMap,
/// The selector maps corresponding to a given pseudo-element
/// (depending on the implementation)
pseudos_map: HashMap<Impl::PseudoElement,
PerPseudoElementSelectorMap<Impl>,
pseudos_map: HashMap<PseudoElement,
PerPseudoElementSelectorMap,
BuildHasherDefault<::fnv::FnvHasher>>,
/// 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.
/// These are eagerly computed once, and then used to resolve the new
/// computed values on the fly on layout.
precomputed_pseudo_element_decls: HashMap<Impl::PseudoElement,
precomputed_pseudo_element_decls: HashMap<PseudoElement,
Vec<DeclarationBlock>,
BuildHasherDefault<::fnv::FnvHasher>>,
rules_source_order: usize,
/// Selector dependencies used to compute restyle hints.
state_deps: DependencySet<Impl>,
state_deps: DependencySet,
}
impl<Impl: SelectorImplExt> Stylist<Impl> {
impl Stylist {
#[inline]
pub fn new(device: Device) -> Stylist<Impl> {
pub fn new(device: Device) -> Self {
let mut stylist = Stylist {
viewport_constraints: None,
device: device,
@ -162,7 +102,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
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());
});
@ -171,9 +111,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
stylist
}
pub fn update(&mut self, doc_stylesheets: &[Arc<Stylesheet<Impl>>],
stylesheets_changed: bool) -> bool
where Impl: 'static {
pub fn update(&mut self, doc_stylesheets: &[Arc<Stylesheet>], stylesheets_changed: bool) -> bool {
if !(self.is_device_dirty || stylesheets_changed) {
return false;
}
@ -181,7 +119,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
self.element_map = PerPseudoElementSelectorMap::new();
self.pseudos_map = 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());
});
@ -189,12 +127,12 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
self.rules_source_order = 0;
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);
}
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);
}
}
@ -207,7 +145,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
true
}
fn add_stylesheet(&mut self, stylesheet: &Stylesheet<Impl>) {
fn add_stylesheet(&mut self, stylesheet: &Stylesheet) {
if !stylesheet.is_effective_for_device(&self.device) {
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
// fly. It should be a bit slower, but we'd take rid of the
// 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
/// universal rules and applying them.
pub fn precomputed_values_for_pseudo(&self,
pseudo: &Impl::PseudoElement,
parent: Option<&Arc<Impl::ComputedValues>>)
-> Option<Arc<Impl::ComputedValues>> {
debug_assert!(Impl::pseudo_element_cascade_type(pseudo).is_precomputed());
pseudo: &PseudoElement,
parent: Option<&Arc<ComputedValues>>)
-> Option<Arc<ComputedValues>> {
debug_assert!(TheSelectorImpl::pseudo_element_cascade_type(pseudo).is_precomputed());
if let Some(declarations) = self.precomputed_pseudo_element_decls.get(pseudo) {
let (computed, _) =
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,
element: &E,
pseudo: &Impl::PseudoElement,
parent: &Arc<Impl::ComputedValues>)
-> Option<Arc<Impl::ComputedValues>>
where E: Element<Impl=Impl, AttrString=Impl::AttrString> +
pseudo: &PseudoElement,
parent: &Arc<ComputedValues>)
-> Option<Arc<ComputedValues>>
where E: Element<Impl=TheSelectorImpl, AttrString=AttrString> +
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() {
return None;
}
@ -336,7 +274,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
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()
.flat_map(|s| s.effective_rules(&self.device).viewport())
.cascade();
@ -374,17 +312,18 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
element: &E,
parent_bf: Option<&BloomFilter>,
style_attribute: Option<&PropertyDeclarationBlock>,
pseudo_element: Option<&Impl::PseudoElement>,
pseudo_element: Option<&PseudoElement>,
applicable_declarations: &mut V)
-> bool
where E: Element<Impl=Impl, AttrString=Impl::AttrString> +
where E: Element<Impl=TheSelectorImpl, AttrString=AttrString> +
PresentationalHintsSynthetizer,
V: Push<DeclarationBlock> + VecLike<DeclarationBlock> {
assert!(!self.is_device_dirty);
assert!(style_attribute.is_none() || pseudo_element.is_none(),
"Style attributes do not apply to pseudo-elements");
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 {
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> {
&self.animations
}
}
impl<Impl: SelectorImplExt<AttrString=String>> Stylist<Impl> {
pub fn compute_restyle_hint<E>(&self, element: &E,
snapshot: &ElementSnapshot,
// 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.
current_state: ElementState)
-> 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)
}
}
@ -480,18 +418,18 @@ impl<Impl: SelectorImplExt<AttrString=String>> Stylist<Impl> {
/// Map that contains the CSS rules for a given origin.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
struct PerOriginSelectorMap<Impl: SelectorImpl> {
struct PerOriginSelectorMap {
/// Rules that contains at least one property declararion with
/// normal importance.
normal: SelectorMap<Vec<PropertyDeclaration>, Impl>,
normal: SelectorMap<Vec<PropertyDeclaration>, TheSelectorImpl>,
/// Rules that contains at least one property declararion with
/// !important.
important: SelectorMap<Vec<PropertyDeclaration>, Impl>,
important: SelectorMap<Vec<PropertyDeclaration>, TheSelectorImpl>,
}
impl<Impl: SelectorImpl> PerOriginSelectorMap<Impl> {
impl PerOriginSelectorMap {
#[inline]
fn new() -> PerOriginSelectorMap<Impl> {
fn new() -> Self {
PerOriginSelectorMap {
normal: SelectorMap::new(),
important: SelectorMap::new(),
@ -502,18 +440,18 @@ impl<Impl: SelectorImpl> PerOriginSelectorMap<Impl> {
/// Map that contains the CSS rules for a specific PseudoElement
/// (or lack of PseudoElement).
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
struct PerPseudoElementSelectorMap<Impl: SelectorImpl> {
struct PerPseudoElementSelectorMap {
/// Rules from user agent stylesheets
user_agent: PerOriginSelectorMap<Impl>,
user_agent: PerOriginSelectorMap,
/// Rules from author stylesheets
author: PerOriginSelectorMap<Impl>,
author: PerOriginSelectorMap,
/// Rules from user stylesheets
user: PerOriginSelectorMap<Impl>,
user: PerOriginSelectorMap,
}
impl<Impl: SelectorImpl> PerPseudoElementSelectorMap<Impl> {
impl PerPseudoElementSelectorMap {
#[inline]
fn new() -> PerPseudoElementSelectorMap<Impl> {
fn new() -> Self {
PerPseudoElementSelectorMap {
user_agent: PerOriginSelectorMap::new(),
author: PerOriginSelectorMap::new(),
@ -522,7 +460,7 @@ impl<Impl: SelectorImpl> PerPseudoElementSelectorMap<Impl> {
}
#[inline]
fn borrow_for_origin(&mut self, origin: &Origin) -> &mut PerOriginSelectorMap<Impl> {
fn borrow_for_origin(&mut self, origin: &Origin) -> &mut PerOriginSelectorMap {
match *origin {
Origin::UserAgent => &mut self.user_agent,
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 parser::{ParserContext, ParserContextExtraData, log_css_error};
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 std::cell::Cell;
use std::iter::Iterator;
use std::marker::PhantomData;
use std::slice;
use string_cache::{Atom, Namespace};
use url::Url;
@ -43,10 +43,10 @@ pub enum Origin {
#[derive(Debug, PartialEq)]
#[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
/// cascading order)
pub rules: Vec<CSSRule<Impl>>,
pub rules: Vec<CSSRule>,
/// List of media associated with the Stylesheet, if any.
pub media: Option<MediaQueryList>,
pub origin: Origin,
@ -56,11 +56,11 @@ pub struct Stylesheet<Impl: SelectorImpl> {
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum CSSRule<Impl: SelectorImpl> {
pub enum CSSRule {
Charset(String),
Namespace(Option<String>, Namespace),
Style(StyleRule<Impl>),
Media(MediaRule<Impl>),
Style(StyleRule),
Media(MediaRule),
FontFace(FontFaceRule),
Viewport(ViewportRule),
Keyframes(KeyframesRule),
@ -76,13 +76,13 @@ pub struct KeyframesRule {
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct MediaRule<Impl: SelectorImpl> {
pub struct MediaRule {
pub media_queries: MediaQueryList,
pub rules: Vec<CSSRule<Impl>>,
pub rules: Vec<CSSRule>,
}
impl<Impl: SelectorImpl> MediaRule<Impl> {
impl MediaRule {
#[inline]
pub fn evaluate(&self, device: &Device) -> bool {
self.media_queries.evaluate(device)
@ -91,18 +91,18 @@ impl<Impl: SelectorImpl> MediaRule<Impl> {
#[derive(Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct StyleRule<Impl: SelectorImpl> {
pub selectors: Vec<Selector<Impl>>,
pub struct StyleRule {
pub selectors: Vec<Selector<TheSelectorImpl>>,
pub declarations: PropertyDeclarationBlock,
}
impl<Impl: SelectorImpl> Stylesheet<Impl> {
impl Stylesheet {
pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>(
input: I, base_url: Url, protocol_encoding_label: Option<&str>,
environment_encoding: Option<EncodingRef>, origin: Origin,
error_reporter: Box<ParseErrorReporter + Send>,
extra_data: ParserContextExtraData) -> Stylesheet<Impl> {
extra_data: ParserContextExtraData) -> Stylesheet {
let mut bytes = vec![];
// TODO: incremental decoding and tokenization/parsing
for chunk in input {
@ -119,7 +119,7 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
environment_encoding: Option<EncodingRef>,
origin: Origin, error_reporter: Box<ParseErrorReporter + Send>,
extra_data: ParserContextExtraData)
-> Stylesheet<Impl> {
-> Stylesheet {
// TODO: bytes.as_slice could be bytes.container_as_bytes()
let (string, _) = decode_stylesheet_bytes(
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,
error_reporter: Box<ParseErrorReporter + Send>,
extra_data: ParserContextExtraData) -> Stylesheet<Impl> {
extra_data: ParserContextExtraData) -> Stylesheet {
let rule_parser = TopLevelRuleParser {
context: ParserContext::new_with_extra_data(origin, &base_url, error_reporter.clone(),
extra_data),
state: Cell::new(State::Start),
_impl: PhantomData,
};
let mut input = Parser::new(css);
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.
#[inline]
pub fn rules(&self) -> Rules<Impl> {
pub fn rules(&self) -> Rules {
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
/// examined.
#[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))
}
}
@ -209,25 +208,25 @@ impl<Impl: SelectorImpl> Stylesheet<Impl> {
///
/// The iteration order is pre-order. Specifically, this implies that a
/// 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)
stack: SmallVec<[slice::Iter<'a, CSSRule<Impl>>; 2]>,
stack: SmallVec<[slice::Iter<'a, CSSRule>; 2]>,
device: Option<&'a Device>
}
impl<'a, Impl: SelectorImpl + 'a> Rules<'a, Impl> {
fn new(iter: slice::Iter<'a, CSSRule<Impl>>, device: Option<&'a Device>) -> Rules<'a, Impl> {
let mut stack: SmallVec<[slice::Iter<'a, CSSRule<Impl>>; 2]> = SmallVec::new();
impl<'a> Rules<'a> {
fn new(iter: slice::Iter<'a, CSSRule>, device: Option<&'a Device>) -> Rules<'a> {
let mut stack: SmallVec<[slice::Iter<'a, CSSRule>; 2]> = SmallVec::new();
stack.push(iter);
Rules { stack: stack, device: device }
}
}
impl<'a, Impl: SelectorImpl + 'a> Iterator for Rules<'a, Impl> {
type Item = &'a CSSRule<Impl>;
impl<'a> Iterator for Rules<'a> {
type Item = &'a CSSRule;
fn next(&mut self) -> Option<&'a CSSRule<Impl>> {
fn next(&mut self) -> Option<&'a CSSRule> {
while !self.stack.is_empty() {
let top = self.stack.len() - 1;
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 {
//! Specific `CSSRule` variant iterators.
use selectors::parser::SelectorImpl;
use std::marker::PhantomData;
use super::super::font_face::FontFaceRule;
use super::super::viewport::ViewportRule;
@ -277,8 +275,8 @@ pub mod rule_filter {
_lifetime: PhantomData<&'a ()>
}
impl<'a, I, Impl: SelectorImpl + 'a> $variant<'a, I>
where I: Iterator<Item=&'a CSSRule<Impl>> {
impl<'a, I> $variant<'a, I>
where I: Iterator<Item=&'a CSSRule> {
#[inline]
pub fn new(iter: I) -> $variant<'a, I> {
$variant {
@ -288,8 +286,8 @@ pub mod rule_filter {
}
}
impl<'a, I, Impl: SelectorImpl + 'a> Iterator for $variant<'a, I>
where I: Iterator<Item=&'a CSSRule<Impl>> {
impl<'a, I> Iterator for $variant<'a, I>
where I: Iterator<Item=&'a CSSRule> {
type Item = &'a $value;
fn next(&mut self) -> Option<&'a $value> {
@ -310,15 +308,15 @@ pub mod rule_filter {
}
}
rule_filter!(Media -> MediaRule<Impl>);
rule_filter!(Style -> StyleRule<Impl>);
rule_filter!(Media -> MediaRule);
rule_filter!(Style -> StyleRule);
rule_filter!(FontFace -> FontFaceRule);
rule_filter!(Viewport -> ViewportRule);
rule_filter!(Keyframes -> KeyframesRule);
}
/// 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.
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>;
}
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]
fn font_face(self) -> rule_filter::FontFace<'a, I> {
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,
NestedRuleParser {
context: context,
_impl: PhantomData
});
NestedRuleParser { context: context });
let mut rules = Vec::new();
while let Some(result) = iter.next() {
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>,
state: Cell<State>,
_impl: PhantomData<Impl>
}
#[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 AtRule = CSSRule<Impl>;
type AtRule = CSSRule;
fn parse_prelude(&self, name: &str, input: &mut Parser)
-> Result<AtRuleType<AtRulePrelude, CSSRule<Impl>>, ()> {
-> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> {
match_ignore_ascii_case! { name,
"charset" => {
if self.state.get() <= State::Start {
@ -451,46 +445,45 @@ impl<'a, Impl: SelectorImpl> AtRuleParser for TopLevelRuleParser<'a, Impl> {
}
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]
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule<Impl>, ()> {
AtRuleParser::parse_block(&NestedRuleParser { context: &self.context, _impl: PhantomData }, prelude, input)
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> {
AtRuleParser::parse_block(&NestedRuleParser { context: &self.context }, prelude, input)
}
}
impl<'a, Impl: SelectorImpl> QualifiedRuleParser for TopLevelRuleParser<'a, Impl> {
type Prelude = Vec<Selector<Impl>>;
type QualifiedRule = CSSRule<Impl>;
impl<'a> QualifiedRuleParser for TopLevelRuleParser<'a> {
type Prelude = Vec<Selector<TheSelectorImpl>>;
type QualifiedRule = CSSRule;
#[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);
QualifiedRuleParser::parse_prelude(&NestedRuleParser { context: &self.context, _impl: PhantomData }, input)
QualifiedRuleParser::parse_prelude(&NestedRuleParser { context: &self.context }, input)
}
#[inline]
fn parse_block(&self, prelude: Vec<Selector<Impl>>, input: &mut Parser) -> Result<CSSRule<Impl>, ()> {
QualifiedRuleParser::parse_block(&NestedRuleParser { context: &self.context, _impl: PhantomData },
fn parse_block(&self, prelude: Vec<Selector<TheSelectorImpl>>, input: &mut Parser) -> Result<CSSRule, ()> {
QualifiedRuleParser::parse_block(&NestedRuleParser { context: &self.context },
prelude, input)
}
}
struct NestedRuleParser<'a, 'b: 'a, Impl: SelectorImpl> {
struct NestedRuleParser<'a, 'b: 'a> {
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 AtRule = CSSRule<Impl>;
type AtRule = CSSRule;
fn parse_prelude(&self, name: &str, input: &mut Parser)
-> Result<AtRuleType<AtRulePrelude, CSSRule<Impl>>, ()> {
-> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> {
match_ignore_ascii_case! { name,
"media" => {
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 {
AtRulePrelude::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> {
type Prelude = Vec<Selector<Impl>>;
type QualifiedRule = CSSRule<Impl>;
impl<'a, 'b> QualifiedRuleParser for NestedRuleParser<'a, 'b> {
type Prelude = Vec<Selector<TheSelectorImpl>>;
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)
}
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 {
selectors: prelude,
declarations: parse_property_declaration_list(self.context, input)

View File

@ -46,11 +46,11 @@ thread_local!(
///
/// 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.
fn take_thread_local_bloom_filter<N, Impl: SelectorImplExt>(parent_node: Option<N>,
root: OpaqueNode,
context: &SharedStyleContext<Impl>)
-> Box<BloomFilter>
where N: TNode {
fn take_thread_local_bloom_filter<N>(parent_node: Option<N>,
root: OpaqueNode,
context: &SharedStyleContext)
-> Box<BloomFilter>
where N: TNode {
STYLE_BLOOM.with(|style_bloom| {
match (parent_node, style_bloom.borrow_mut().take()) {
// Root node. Needs new bloom filter.
@ -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>,
unsafe_node: &UnsafeNode,
context: &SharedStyleContext<Impl>) {
fn put_thread_local_bloom_filter(bf: Box<BloomFilter>, unsafe_node: &UnsafeNode,
context: &SharedStyleContext) {
STYLE_BLOOM.with(move |style_bloom| {
assert!(style_bloom.borrow().is_none(),
"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);
}
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,
Impl: SelectorImplExt + 'a,
C: StyleContext<'a, Impl>
C: StyleContext<'a>
{
let unsafe_layout_node = node.to_unsafe();
@ -158,8 +156,8 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C,
root: OpaqueNode,
node: N)
where N: TNode,
C: StyleContext<'a, <N::ConcreteElement as Element>::Impl>,
<N::ConcreteElement as Element>::Impl: SelectorImplExt<ComputedValues=N::ConcreteComputedValues> + 'a {
C: StyleContext<'a>,
<N::ConcreteElement as Element>::Impl: SelectorImplExt + 'a {
// Get the parent node.
let parent_opt = match node.parent_node() {
Some(parent) if parent.is_element() => Some(parent),

View File

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

View File

@ -13,7 +13,7 @@ use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser,
use euclid::scale_factor::ScaleFactor;
use euclid::size::{Size2D, TypedSize2D};
use parser::{ParserContext, log_css_error};
use properties::{ComputedValues, ServoComputedValues};
use properties::ComputedValues;
use std::ascii::AsciiExt;
use std::fmt;
use std::iter::Enumerate;
@ -646,8 +646,8 @@ impl MaybeNew for ViewportConstraints {
let context = Context {
is_root_element: false,
viewport_size: initial_viewport,
inherited_style: ServoComputedValues::initial_values(),
style: ServoComputedValues::initial_values().clone(),
inherited_style: ComputedValues::initial_values(),
style: ComputedValues::initial_values().clone(),
};
// 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
[selector-impl]: http://doc.servo.org/selectors/parser/trait.SelectorImpl.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
[style-dom-traits]: http://doc.servo.org/style/dom/index.html
[layout-wrapper]: http://doc.servo.org/layout/wrapper/index.html

View File

@ -3,7 +3,6 @@ name = "geckoservo"
version = "0.0.1"
dependencies = [
"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)",
"euclid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gecko_bindings 0.0.1",

View File

@ -4,8 +4,6 @@ version = "0.0.1"
authors = ["The Servo Project Developers"]
license = "MPL-2.0"
build = "build.rs"
[lib]
name = "geckoservo"
path = "lib.rs"
@ -13,7 +11,6 @@ crate-type = ["staticlib"]
[dependencies]
app_units = "0.2.5"
cssparser = "0.5.4"
env_logger = "0.3"
euclid = "0.7.1"
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
* 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 selector_impl::{GeckoSelectorImpl, SharedStyleContext};
use std::cell::RefCell;
use std::rc::Rc;
use style::context::{LocalStyleContext, StyleContext};
use style::context::{LocalStyleContext, StyleContext, SharedStyleContext};
thread_local!(static LOCAL_CONTEXT_KEY:
RefCell<Option<Rc<LocalStyleContext<GeckoSelectorImpl>>>> = RefCell::new(None));
thread_local!(static LOCAL_CONTEXT_KEY: RefCell<Option<Rc<LocalStyleContext>>> = RefCell::new(None));
// Keep this implementation in sync with the one in components/layout/context.rs.
fn create_or_get_local_context(shared: &SharedStyleContext)
-> Rc<LocalStyleContext<GeckoSelectorImpl>> {
fn create_or_get_local_context(shared: &SharedStyleContext) -> Rc<LocalStyleContext> {
LOCAL_CONTEXT_KEY.with(|r| {
let mut r = r.borrow_mut();
if let Some(context) = r.clone() {
@ -29,7 +27,7 @@ fn create_or_get_local_context(shared: &SharedStyleContext)
pub struct StandaloneStyleContext<'a> {
pub shared: &'a SharedStyleContext,
cached_local_context: Rc<LocalStyleContext<GeckoSelectorImpl>>,
cached_local_context: Rc<LocalStyleContext>,
}
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 {
&self.shared
}
fn local_context(&self) -> &LocalStyleContext<GeckoSelectorImpl> {
fn local_context(&self) -> &LocalStyleContext {
&self.cached_local_context
}
}

View File

@ -6,15 +6,18 @@ use euclid::Size2D;
use euclid::size::TypedSize2D;
use gecko_bindings::bindings::RawServoStyleSet;
use num_cpus;
use selector_impl::{Animation, SharedStyleContext, Stylist, Stylesheet};
use std::cmp;
use std::collections::HashMap;
use std::env;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::{Arc, RwLock};
use style::animation::Animation;
use style::context::SharedStyleContext;
use style::dom::OpaqueNode;
use style::media_queries::{Device, MediaType};
use style::parallel::WorkQueueData;
use style::selector_matching::Stylist;
use style::stylesheets::Stylesheet;
use style::workqueue::WorkQueue;
use style_traits::ViewportPx;
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::ptr::{GeckoArcPrincipal, GeckoArcURI};
use gecko_bindings::structs::{SheetParsingMode, nsIAtom};
use properties::GeckoComputedValues;
use selector_impl::{GeckoSelectorImpl, PseudoElement, SharedStyleContext, Stylesheet};
use std::marker::PhantomData;
use std::mem::{forget, transmute};
use std::mem::transmute;
use std::ptr;
use std::slice;
use std::str::from_utf8_unchecked;
use std::sync::{Arc, Mutex};
use style::arc_ptr_eq;
use style::context::{LocalStyleContextCreationInfo, ReflowGoal};
use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext};
use style::dom::{TDocument, TElement, TNode};
use style::error_reporting::StdoutErrorReporter;
use style::gecko_glue::ArcHelpers;
use style::gecko_selector_impl::{GeckoSelectorImpl, PseudoElement};
use style::parallel;
use style::parser::ParserContextExtraData;
use style::properties::{ComputedValues, PropertyDeclarationBlock, parse_one_declaration};
use style::selector_impl::{SelectorImplExt, PseudoElementCascadeType};
use style::sequential;
use style::stylesheets::Origin;
use style::stylesheets::{Stylesheet, Origin};
use traversal::RecalcStyleOnly;
use url::Url;
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
// initial_values computation, since that stuff needs to be called further
// 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()
.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]
pub extern "C" fn Servo_AppendStyleSheet(raw_sheet: *mut RawServoStyleSheet,
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
// traversed. We should remove this as soon as possible.
error!("stylo: encountered unstyled node, substituting default values.");
Arc::new(GeckoComputedValues::initial_values().clone())
Arc::new(ComputedValues::initial_values().clone())
},
};
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| {
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) };
type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>;
type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>;
match GeckoSelectorImpl::pseudo_element_cascade_type(&pseudo) {
PseudoElementCascadeType::Eager => {
@ -395,22 +346,22 @@ pub extern "C" fn Servo_GetComputedValuesForPseudoElement(parent_style: *mut Ser
#[no_mangle]
pub extern "C" fn Servo_InheritComputedValues(parent_style: *mut ServoComputedValues)
-> *mut ServoComputedValues {
type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>;
type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>;
Helpers::with(parent_style, |parent| {
let style = GeckoComputedValues::inherit_from(parent);
let style = ComputedValues::inherit_from(parent);
Helpers::from(style)
})
}
#[no_mangle]
pub extern "C" fn Servo_AddRefComputedValues(ptr: *mut ServoComputedValues) -> () {
type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>;
type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>;
unsafe { Helpers::addref(ptr) };
}
#[no_mangle]
pub extern "C" fn Servo_ReleaseComputedValues(ptr: *mut ServoComputedValues) -> () {
type Helpers = ArcHelpers<ServoComputedValues, GeckoComputedValues>;
type Helpers = ArcHelpers<ServoComputedValues, ComputedValues>;
unsafe { Helpers::release(ptr) };
}

View File

@ -3,8 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
extern crate app_units;
#[macro_use]
extern crate cssparser;
extern crate env_logger;
extern crate euclid;
extern crate gecko_bindings;
@ -26,18 +24,9 @@ mod context;
mod data;
#[allow(non_snake_case)]
pub mod glue;
mod selector_impl;
mod traversal;
mod values;
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.
#[no_mangle]
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/. */
use context::StandaloneStyleContext;
use selector_impl::SharedStyleContext;
use std::mem;
use style::context::SharedStyleContext;
use style::dom::OpaqueNode;
use style::traversal::{DomTraversalContext, recalc_style_at};
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 glue::GeckoDeclarationBlock;
use libc::uintptr_t;
use properties::GeckoComputedValues;
use selector_impl::{GeckoSelectorImpl, NonTSPseudoClass, PrivateStyleData};
use selectors::Element;
use selectors::matching::DeclarationBlock;
use selectors::parser::{AttrSelector, NamespaceConstraint};
@ -38,15 +36,17 @@ use std::ptr;
use std::slice;
use std::sync::Arc;
use string_cache::{Atom, BorrowedAtom, BorrowedNamespace, Namespace};
use style::data::PrivateStyleData;
use style::dom::{OpaqueNode, PresentationalHintsSynthetizer};
use style::dom::{TDocument, TElement, TNode, TRestyleDamage, UnsafeNode};
use style::element_state::ElementState;
#[allow(unused_imports)] // Used in commented-out code.
use style::error_reporting::StdoutErrorReporter;
use style::gecko_selector_impl::{GeckoSelectorImpl, NonTSPseudoClass};
#[allow(unused_imports)] // Used in commented-out code.
use style::parser::ParserContextExtraData;
#[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::refcell::{Ref, RefCell, RefMut};
use style::restyle_hints::ElementSnapshot;
@ -99,8 +99,7 @@ impl<'ln> GeckoNode<'ln> {
#[derive(Clone, Copy)]
pub struct DummyRestyleDamage;
impl TRestyleDamage for DummyRestyleDamage {
type ConcreteComputedValues = GeckoComputedValues;
fn compute(_: Option<&Arc<GeckoComputedValues>>, _: &GeckoComputedValues) -> Self { DummyRestyleDamage }
fn compute(_: Option<&Arc<ComputedValues>>, _: &ComputedValues) -> Self { DummyRestyleDamage }
fn rebuild_and_reflow() -> Self { DummyRestyleDamage }
}
impl BitOr for DummyRestyleDamage {
@ -114,7 +113,6 @@ impl<'ln> TNode for GeckoNode<'ln> {
type ConcreteDocument = GeckoDocument<'ln>;
type ConcreteElement = GeckoElement<'ln>;
type ConcreteRestyleDamage = DummyRestyleDamage;
type ConcreteComputedValues = GeckoComputedValues;
fn to_unsafe(&self) -> UnsafeNode {
(self.node as usize, 0)

View File

@ -29,7 +29,7 @@ mod viewport;
mod writing_modes {
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]
fn initial_writing_mode_is_empty() {

View File

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

View File

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

View File

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