mirror of
https://github.com/servo/servo.git
synced 2025-07-31 11:10:22 +01:00
auto merge of #4757 : servo/servo/newnewnewcss, r=mbrubeck
(Still off by default. Enable with `RUST_LOG=style`.) r? @mbrubeck
This commit is contained in:
commit
172aed535b
49 changed files with 424 additions and 351 deletions
|
@ -40,7 +40,7 @@ use util::smallvec::{SmallVec, SmallVec8};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::computed_values::{border_style, cursor, filter, mix_blend_mode, pointer_events};
|
use style::computed_values::{border_style, cursor, filter, mix_blend_mode, pointer_events};
|
||||||
|
|
||||||
// It seems cleaner to have layout code not mention Azure directly, so let's just reexport this for
|
// It seems cleaner to have layout code not mention Azure directly, so let's just reexport this for
|
||||||
|
|
|
@ -11,7 +11,7 @@ use std::cell::RefCell;
|
||||||
use util::cache::HashCache;
|
use util::cache::HashCache;
|
||||||
use util::smallvec::{SmallVec, SmallVec8};
|
use util::smallvec::{SmallVec, SmallVec8};
|
||||||
use style::computed_values::{font_stretch, font_variant, font_weight};
|
use style::computed_values::{font_stretch, font_variant, font_weight};
|
||||||
use style::style_structs::Font as FontStyle;
|
use style::properties::style_structs::Font as FontStyle;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
|
@ -18,7 +18,7 @@ use platform::font_template::FontTemplateData;
|
||||||
use servo_net::resource_task::{ResourceTask, load_whole_resource};
|
use servo_net::resource_task::{ResourceTask, load_whole_resource};
|
||||||
use util::task::spawn_named;
|
use util::task::spawn_named;
|
||||||
use util::str::LowercaseString;
|
use util::str::LowercaseString;
|
||||||
use style::Source;
|
use style::font_face::Source;
|
||||||
|
|
||||||
/// A list of font templates that make up a given font family.
|
/// A list of font templates that make up a given font family.
|
||||||
struct FontFamily {
|
struct FontFamily {
|
||||||
|
|
|
@ -57,10 +57,9 @@ use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
|
||||||
use servo_util::opts;
|
use servo_util::opts;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::computed_values::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
|
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
|
||||||
use style::computed_values::{LengthOrPercentage, box_sizing, display, float};
|
use style::computed_values::{overflow, position, box_sizing, display, float};
|
||||||
use style::computed_values::{overflow, position};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Information specific to floated blocks.
|
/// Information specific to floated blocks.
|
||||||
|
|
|
@ -56,7 +56,7 @@ use std::mem;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use style::computed_values::{caption_side, display, empty_cells, float, list_style_position};
|
use style::computed_values::{caption_side, display, empty_cells, float, list_style_position};
|
||||||
use style::computed_values::{position};
|
use style::computed_values::{position};
|
||||||
use style::{self, ComputedValues};
|
use style::properties::{ComputedValues, make_inline};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -707,7 +707,7 @@ impl<'a> FlowConstructor<'a> {
|
||||||
// `baz` had better not be absolutely positioned!
|
// `baz` had better not be absolutely positioned!
|
||||||
let mut style = (*node.style()).clone();
|
let mut style = (*node.style()).clone();
|
||||||
if style.get_box().display != display::T::inline {
|
if style.get_box().display != display::T::inline {
|
||||||
style = Arc::new(style::make_inline(&*style))
|
style = Arc::new(make_inline(&*style))
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is generated content, then we need to initialize the accumulator with the
|
// If this is generated content, then we need to initialize the accumulator with the
|
||||||
|
|
|
@ -19,7 +19,7 @@ use std::cell::Cell;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use style::Stylist;
|
use style::selector_matching::Stylist;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
struct LocalLayoutContext {
|
struct LocalLayoutContext {
|
||||||
|
|
|
@ -19,8 +19,12 @@ use std::mem;
|
||||||
use std::hash::{Hash, Hasher, Writer};
|
use std::hash::{Hash, Hasher, Writer};
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
use string_cache::{Atom, Namespace};
|
use string_cache::{Atom, Namespace};
|
||||||
use style::{self, PseudoElement, ComputedValues, DeclarationBlock, Stylist, TElement, TNode};
|
use style::selectors::PseudoElement;
|
||||||
use style::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes, cascade};
|
use style::selector_matching::{Stylist, DeclarationBlock};
|
||||||
|
use style::node::{TElement, TNode};
|
||||||
|
use style::properties::{ComputedValues, cascade};
|
||||||
|
use style::selector_matching::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes};
|
||||||
|
use style::selector_matching::{common_style_affecting_attributes, rare_style_affecting_attributes};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct ApplicableDeclarations {
|
pub struct ApplicableDeclarations {
|
||||||
|
@ -156,7 +160,7 @@ pub struct StyleSharingCandidateCache {
|
||||||
fn create_common_style_affecting_attributes_from_element(element: &LayoutElement)
|
fn create_common_style_affecting_attributes_from_element(element: &LayoutElement)
|
||||||
-> CommonStyleAffectingAttributes {
|
-> CommonStyleAffectingAttributes {
|
||||||
let mut flags = CommonStyleAffectingAttributes::empty();
|
let mut flags = CommonStyleAffectingAttributes::empty();
|
||||||
for attribute_info in style::common_style_affecting_attributes().iter() {
|
for attribute_info in common_style_affecting_attributes().iter() {
|
||||||
match attribute_info.mode {
|
match attribute_info.mode {
|
||||||
CommonStyleAffectingAttributeMode::IsPresent(flag) => {
|
CommonStyleAffectingAttributeMode::IsPresent(flag) => {
|
||||||
if element.get_attr(&ns!(""), &attribute_info.atom).is_some() {
|
if element.get_attr(&ns!(""), &attribute_info.atom).is_some() {
|
||||||
|
@ -276,7 +280,7 @@ impl StyleSharingCandidate {
|
||||||
// FIXME(pcwalton): It's probably faster to iterate over all the element's attributes and
|
// FIXME(pcwalton): It's probably faster to iterate over all the element's attributes and
|
||||||
// use the {common, rare}-style-affecting-attributes tables as lookup tables.
|
// use the {common, rare}-style-affecting-attributes tables as lookup tables.
|
||||||
|
|
||||||
for attribute_info in style::common_style_affecting_attributes().iter() {
|
for attribute_info in common_style_affecting_attributes().iter() {
|
||||||
match attribute_info.mode {
|
match attribute_info.mode {
|
||||||
CommonStyleAffectingAttributeMode::IsPresent(flag) => {
|
CommonStyleAffectingAttributeMode::IsPresent(flag) => {
|
||||||
if self.common_style_affecting_attributes.contains(flag) !=
|
if self.common_style_affecting_attributes.contains(flag) !=
|
||||||
|
@ -303,7 +307,7 @@ impl StyleSharingCandidate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for attribute_name in style::rare_style_affecting_attributes().iter() {
|
for attribute_name in rare_style_affecting_attributes().iter() {
|
||||||
if element.get_attr(&ns!(""), attribute_name).is_some() {
|
if element.get_attr(&ns!(""), attribute_name).is_some() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use wrapper::{PseudoElementType, ThreadSafeLayoutNode};
|
use wrapper::{PseudoElementType, ThreadSafeLayoutNode};
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Node mixin providing `style` method that returns a `NodeStyle`
|
/// Node mixin providing `style` method that returns a `NodeStyle`
|
||||||
|
|
|
@ -47,12 +47,13 @@ use std::default::Default;
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use std::num::Float;
|
use std::num::Float;
|
||||||
use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection};
|
use style::values::specified::{AngleOrCorner, HorizontalDirection, VerticalDirection};
|
||||||
use style::computed::{Image, LinearGradient, LengthOrPercentage};
|
use style::values::computed::{Image, LinearGradient, LengthOrPercentage};
|
||||||
|
use style::values::RGBA;
|
||||||
use style::computed_values::filter::Filter;
|
use style::computed_values::filter::Filter;
|
||||||
use style::computed_values::{background_attachment, background_repeat, border_style, overflow};
|
use style::computed_values::{background_attachment, background_repeat, border_style, overflow};
|
||||||
use style::computed_values::{position, visibility};
|
use style::computed_values::{position, visibility};
|
||||||
use style::style_structs::Border;
|
use style::properties::style_structs::Border;
|
||||||
use style::{ComputedValues, RGBA};
|
use style::properties::ComputedValues;
|
||||||
use std::num::ToPrimitive;
|
use std::num::ToPrimitive;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
|
|
|
@ -60,7 +60,7 @@ use std::raw;
|
||||||
use std::sync::atomic::{AtomicUint, Ordering};
|
use std::sync::atomic::{AtomicUint, Ordering};
|
||||||
use std::slice::IterMut;
|
use std::slice::IterMut;
|
||||||
use style::computed_values::{clear, empty_cells, float, position, text_align};
|
use style::computed_values::{clear, empty_cells, float, position, text_align};
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Virtual methods that make up a float context.
|
/// Virtual methods that make up a float context.
|
||||||
|
|
|
@ -46,9 +46,10 @@ use std::str::FromStr;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use style::{ComputedValues, TElement, TNode, cascade_anonymous};
|
use style::properties::{ComputedValues, cascade_anonymous};
|
||||||
use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto};
|
use style::node::{TElement, TNode};
|
||||||
use style::computed_values::{LengthOrPercentageOrNone, clear, mix_blend_mode, overflow_wrap};
|
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
|
||||||
|
use style::computed_values::{clear, mix_blend_mode, overflow_wrap};
|
||||||
use style::computed_values::{position, text_align, text_decoration, vertical_align, white_space};
|
use style::computed_values::{position, text_align, text_decoration, vertical_align, white_space};
|
||||||
use style::computed_values::{word_break};
|
use style::computed_values::{word_break};
|
||||||
use text::TextRunScanner;
|
use text::TextRunScanner;
|
||||||
|
|
|
@ -8,7 +8,7 @@ use flow::{IS_ABSOLUTELY_POSITIONED};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style::computed_values::float;
|
use style::computed_values::float;
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
#[doc = "Individual layout actions that may be necessary after restyling."]
|
#[doc = "Individual layout actions that may be necessary after restyling."]
|
||||||
|
|
|
@ -36,7 +36,7 @@ use std::ops::{Add, Sub, Mul, Div, Rem, Neg, Shl, Shr, Not, BitOr, BitAnd, BitXo
|
||||||
use std::u16;
|
use std::u16;
|
||||||
use style::computed_values::{overflow, text_align, text_justify, text_overflow, vertical_align};
|
use style::computed_values::{overflow, text_align, text_justify, text_overflow, vertical_align};
|
||||||
use style::computed_values::{white_space};
|
use style::computed_values::{white_space};
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
// From gfxFontConstants.h in Firefox
|
// From gfxFontConstants.h in Firefox
|
||||||
|
|
|
@ -65,9 +65,11 @@ use std::ops::{Deref, DerefMut};
|
||||||
use std::sync::mpsc::{channel, Sender, Receiver, Select};
|
use std::sync::mpsc::{channel, Sender, Receiver, Select};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use style::selector_matching::Stylist;
|
||||||
use style::computed_values::{filter, mix_blend_mode};
|
use style::computed_values::{filter, mix_blend_mode};
|
||||||
use style::{StylesheetOrigin, Stylesheet, Stylist, TNode, iter_font_face_rules};
|
use style::stylesheets::{Origin, Stylesheet, iter_font_face_rules};
|
||||||
use style::{MediaType, Device};
|
use style::node::TNode;
|
||||||
|
use style::media_queries::{MediaType, Device};
|
||||||
use std::sync::{Arc, Mutex, MutexGuard};
|
use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -488,7 +490,7 @@ impl LayoutTask {
|
||||||
final_url,
|
final_url,
|
||||||
protocol_encoding_label,
|
protocol_encoding_label,
|
||||||
Some(environment_encoding),
|
Some(environment_encoding),
|
||||||
StylesheetOrigin::Author);
|
Origin::Author);
|
||||||
self.handle_add_stylesheet(sheet, possibly_locked_rw_data);
|
self.handle_add_stylesheet(sheet, possibly_locked_rw_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ use gfx::display_list::DisplayList;
|
||||||
use servo_util::geometry::Au;
|
use servo_util::geometry::Au;
|
||||||
use servo_util::logical_geometry::LogicalRect;
|
use servo_util::logical_geometry::LogicalRect;
|
||||||
use servo_util::opts;
|
use servo_util::opts;
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::computed_values::list_style_type;
|
use style::computed_values::list_style_type;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,9 @@
|
||||||
|
|
||||||
use fragment::Fragment;
|
use fragment::Fragment;
|
||||||
|
|
||||||
use style::computed_values as computed;
|
|
||||||
use geom::SideOffsets2D;
|
use geom::SideOffsets2D;
|
||||||
use style::computed_values::{LengthOrPercentageOrAuto, LengthOrPercentage};
|
use style::values::computed::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, LengthOrPercentage};
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use servo_util::geometry::Au;
|
use servo_util::geometry::Au;
|
||||||
use servo_util::logical_geometry::LogicalMargin;
|
use servo_util::logical_geometry::LogicalMargin;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
|
@ -333,14 +332,14 @@ pub enum MaybeAuto {
|
||||||
|
|
||||||
impl MaybeAuto {
|
impl MaybeAuto {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_style(length: computed::LengthOrPercentageOrAuto, containing_length: Au)
|
pub fn from_style(length: LengthOrPercentageOrAuto, containing_length: Au)
|
||||||
-> MaybeAuto {
|
-> MaybeAuto {
|
||||||
match length {
|
match length {
|
||||||
computed::LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
|
LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
|
||||||
computed::LengthOrPercentageOrAuto::Percentage(percent) => {
|
LengthOrPercentageOrAuto::Percentage(percent) => {
|
||||||
MaybeAuto::Specified(containing_length.scale_by(percent))
|
MaybeAuto::Specified(containing_length.scale_by(percent))
|
||||||
}
|
}
|
||||||
computed::LengthOrPercentageOrAuto::Length(length) => MaybeAuto::Specified(length)
|
LengthOrPercentageOrAuto::Length(length) => MaybeAuto::Specified(length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,18 +365,18 @@ impl MaybeAuto {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn specified_or_none(length: computed::LengthOrPercentageOrNone, containing_length: Au) -> Option<Au> {
|
pub fn specified_or_none(length: LengthOrPercentageOrNone, containing_length: Au) -> Option<Au> {
|
||||||
match length {
|
match length {
|
||||||
computed::LengthOrPercentageOrNone::None => None,
|
LengthOrPercentageOrNone::None => None,
|
||||||
computed::LengthOrPercentageOrNone::Percentage(percent) => Some(containing_length.scale_by(percent)),
|
LengthOrPercentageOrNone::Percentage(percent) => Some(containing_length.scale_by(percent)),
|
||||||
computed::LengthOrPercentageOrNone::Length(length) => Some(length),
|
LengthOrPercentageOrNone::Length(length) => Some(length),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn specified(length: computed::LengthOrPercentage, containing_length: Au) -> Au {
|
pub fn specified(length: LengthOrPercentage, containing_length: Au) -> Au {
|
||||||
match length {
|
match length {
|
||||||
computed::LengthOrPercentage::Length(length) => length,
|
LengthOrPercentage::Length(length) => length,
|
||||||
computed::LengthOrPercentage::Percentage(p) => containing_length.scale_by(p)
|
LengthOrPercentage::Percentage(p) => containing_length.scale_by(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,10 @@ use servo_util::geometry::Au;
|
||||||
use servo_util::logical_geometry::LogicalRect;
|
use servo_util::logical_geometry::LogicalRect;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style::{ComputedValues, CSSFloat};
|
use style::properties::ComputedValues;
|
||||||
use style::computed_values::{LengthOrPercentageOrAuto, table_layout};
|
use style::values::CSSFloat;
|
||||||
|
use style::values::computed::{LengthOrPercentageOrAuto};
|
||||||
|
use style::computed_values::table_layout;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A table flow corresponded to the table's internal table fragment under a table wrapper flow.
|
/// A table flow corresponded to the table's internal table fragment under a table wrapper flow.
|
||||||
|
|
|
@ -17,7 +17,7 @@ use geom::{Point2D, Rect};
|
||||||
use servo_util::geometry::Au;
|
use servo_util::geometry::Au;
|
||||||
use servo_util::logical_geometry::LogicalRect;
|
use servo_util::logical_geometry::LogicalRect;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A table formatting context.
|
/// A table formatting context.
|
||||||
|
|
|
@ -19,7 +19,8 @@ use geom::{Point2D, Rect};
|
||||||
use servo_util::geometry::Au;
|
use servo_util::geometry::Au;
|
||||||
use servo_util::logical_geometry::LogicalRect;
|
use servo_util::logical_geometry::LogicalRect;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style::{UnsignedIntegerAttribute, ComputedValues};
|
use style::properties::ComputedValues;
|
||||||
|
use style::legacy::UnsignedIntegerAttribute;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A table formatting context.
|
/// A table formatting context.
|
||||||
|
|
|
@ -17,8 +17,8 @@ use geom::{Point2D, Rect};
|
||||||
use servo_util::geometry::{Au, ZERO_RECT};
|
use servo_util::geometry::{Au, ZERO_RECT};
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style::computed_values::LengthOrPercentageOrAuto;
|
use style::values::computed::LengthOrPercentageOrAuto;
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A table formatting context.
|
/// A table formatting context.
|
||||||
|
|
|
@ -23,8 +23,8 @@ use servo_util::geometry::Au;
|
||||||
use servo_util::logical_geometry::LogicalRect;
|
use servo_util::logical_geometry::LogicalRect;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::computed_values::LengthOrPercentageOrAuto;
|
use style::values::computed::LengthOrPercentageOrAuto;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A single row of a table.
|
/// A single row of a table.
|
||||||
|
|
|
@ -19,7 +19,7 @@ use geom::{Point2D, Rect};
|
||||||
use servo_util::geometry::Au;
|
use servo_util::geometry::Au;
|
||||||
use servo_util::logical_geometry::LogicalRect;
|
use servo_util::logical_geometry::LogicalRect;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A table formatting context.
|
/// A table formatting context.
|
||||||
|
|
|
@ -28,8 +28,10 @@ use servo_util::geometry::Au;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
use style::{ComputedValues, CSSFloat};
|
use style::properties::ComputedValues;
|
||||||
use style::computed_values::{table_layout, LengthOrPercentageOrAuto};
|
use style::computed_values::table_layout;
|
||||||
|
use style::values::CSSFloat;
|
||||||
|
use style::values::computed::LengthOrPercentageOrAuto;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Copy, RustcEncodable, Show)]
|
#[derive(Copy, RustcEncodable, Show)]
|
||||||
|
|
|
@ -22,10 +22,10 @@ use servo_util::range::Range;
|
||||||
use servo_util::smallvec::{SmallVec, SmallVec1};
|
use servo_util::smallvec::{SmallVec, SmallVec1};
|
||||||
use std::collections::DList;
|
use std::collections::DList;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use style::ComputedValues;
|
|
||||||
use style::computed_values::{line_height, text_orientation, text_rendering, text_transform};
|
use style::computed_values::{line_height, text_orientation, text_rendering, text_transform};
|
||||||
use style::computed_values::{white_space};
|
use style::computed_values::{white_space};
|
||||||
use style::style_structs::Font as FontStyle;
|
use style::properties::ComputedValues;
|
||||||
|
use style::properties::style_structs::Font as FontStyle;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextFragment`s.
|
/// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextFragment`s.
|
||||||
|
|
|
@ -19,7 +19,7 @@ use wrapper::{PreorderDomTraversal, PostorderDomTraversal};
|
||||||
use servo_util::bloom::BloomFilter;
|
use servo_util::bloom::BloomFilter;
|
||||||
use servo_util::opts;
|
use servo_util::opts;
|
||||||
use servo_util::tid::tid;
|
use servo_util::tid::tid;
|
||||||
use style::TNode;
|
use style::node::TNode;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
|
@ -17,7 +17,7 @@ use script::layout_interface::{LayoutChan, TrustedNodeAddress};
|
||||||
use script_traits::UntrustedNodeAddress;
|
use script_traits::UntrustedNodeAddress;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::cell::{Ref, RefMut};
|
use std::cell::{Ref, RefMut};
|
||||||
use style::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style;
|
use style;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ pub trait ToGfxColor {
|
||||||
fn to_gfx_color(&self) -> gfx::color::Color;
|
fn to_gfx_color(&self) -> gfx::color::Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToGfxColor for style::computed_values::RGBA {
|
impl ToGfxColor for style::values::RGBA {
|
||||||
fn to_gfx_color(&self) -> gfx::color::Color {
|
fn to_gfx_color(&self) -> gfx::color::Color {
|
||||||
gfx::color::rgba(self.red, self.green, self.blue, self.alpha)
|
gfx::color::rgba(self.red, self.green, self.blue, self.alpha)
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,9 +66,10 @@ use std::mem;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use string_cache::{Atom, Namespace};
|
use string_cache::{Atom, Namespace};
|
||||||
use style::computed_values::{content, display, white_space};
|
use style::computed_values::{content, display, white_space};
|
||||||
use style::{NamespaceConstraint, AttrSelector, IntegerAttribute};
|
use style::selectors::{NamespaceConstraint, AttrSelector};
|
||||||
use style::{LengthAttribute, PropertyDeclarationBlock, SimpleColorAttribute};
|
use style::legacy::{LengthAttribute, SimpleColorAttribute, UnsignedIntegerAttribute, IntegerAttribute};
|
||||||
use style::{TElement, TElementAttributes, TNode, UnsignedIntegerAttribute};
|
use style::node::{TElement, TElementAttributes, TNode};
|
||||||
|
use style::properties::PropertyDeclarationBlock;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
/// Allows some convenience methods on generic layout nodes.
|
/// Allows some convenience methods on generic layout nodes.
|
||||||
|
|
|
@ -58,7 +58,7 @@ use std::io::timer::Timer;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::mpsc::{Receiver, Sender};
|
use std::sync::mpsc::{Receiver, Sender};
|
||||||
use string_cache::{Atom, Namespace};
|
use string_cache::{Atom, Namespace};
|
||||||
use style::PropertyDeclarationBlock;
|
use style::properties::PropertyDeclarationBlock;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,8 @@ use dom::node::{window_from_node, document_from_node, NodeDamage, Node};
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use style::{is_supported_property, longhands_from_shorthand, parse_style_attribute};
|
use style::properties::{is_supported_property, longhands_from_shorthand, parse_style_attribute};
|
||||||
use style::PropertyDeclaration;
|
use style::properties::PropertyDeclaration;
|
||||||
|
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
|
|
@ -50,8 +50,11 @@ use dom::node::{window_from_node};
|
||||||
use dom::nodelist::NodeList;
|
use dom::nodelist::NodeList;
|
||||||
use dom::virtualmethods::{VirtualMethods, vtable_for};
|
use dom::virtualmethods::{VirtualMethods, vtable_for};
|
||||||
use devtools_traits::AttrInfo;
|
use devtools_traits::AttrInfo;
|
||||||
use style::{self, SimpleColorAttribute, UnsignedIntegerAttribute};
|
use style::legacy::{SimpleColorAttribute, UnsignedIntegerAttribute, IntegerAttribute, LengthAttribute};
|
||||||
use style::{IntegerAttribute, LengthAttribute, matches};
|
use style::selector_matching::matches;
|
||||||
|
use style::properties::{PropertyDeclarationBlock, PropertyDeclaration, parse_style_attribute};
|
||||||
|
use style::selectors::parse_author_origin_selector_list_from_str;
|
||||||
|
use style;
|
||||||
use util::namespace;
|
use util::namespace;
|
||||||
use util::str::{DOMString, LengthOrPercentageOrAuto};
|
use util::str::{DOMString, LengthOrPercentageOrAuto};
|
||||||
|
|
||||||
|
@ -74,7 +77,7 @@ pub struct Element {
|
||||||
namespace: Namespace,
|
namespace: Namespace,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
attrs: DOMRefCell<Vec<JS<Attr>>>,
|
attrs: DOMRefCell<Vec<JS<Attr>>>,
|
||||||
style_attribute: DOMRefCell<Option<style::PropertyDeclarationBlock>>,
|
style_attribute: DOMRefCell<Option<PropertyDeclarationBlock>>,
|
||||||
attr_list: MutNullableJS<NamedNodeMap>,
|
attr_list: MutNullableJS<NamedNodeMap>,
|
||||||
class_list: MutNullableJS<DOMTokenList>,
|
class_list: MutNullableJS<DOMTokenList>,
|
||||||
}
|
}
|
||||||
|
@ -152,7 +155,7 @@ pub trait RawLayoutElementHelpers {
|
||||||
-> Option<RGBA>;
|
-> Option<RGBA>;
|
||||||
fn local_name<'a>(&'a self) -> &'a Atom;
|
fn local_name<'a>(&'a self) -> &'a Atom;
|
||||||
fn namespace<'a>(&'a self) -> &'a Namespace;
|
fn namespace<'a>(&'a self) -> &'a Namespace;
|
||||||
fn style_attribute<'a>(&'a self) -> &'a DOMRefCell<Option<style::PropertyDeclarationBlock>>;
|
fn style_attribute<'a>(&'a self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -363,7 +366,7 @@ impl RawLayoutElementHelpers for Element {
|
||||||
&self.namespace
|
&self.namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
fn style_attribute<'a>(&'a self) -> &'a DOMRefCell<Option<style::PropertyDeclarationBlock>> {
|
fn style_attribute<'a>(&'a self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>> {
|
||||||
&self.style_attribute
|
&self.style_attribute
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,13 +405,13 @@ pub trait ElementHelpers<'a> {
|
||||||
fn prefix(self) -> &'a Option<DOMString>;
|
fn prefix(self) -> &'a Option<DOMString>;
|
||||||
fn attrs(&self) -> Ref<Vec<JS<Attr>>>;
|
fn attrs(&self) -> Ref<Vec<JS<Attr>>>;
|
||||||
fn attrs_mut(&self) -> RefMut<Vec<JS<Attr>>>;
|
fn attrs_mut(&self) -> RefMut<Vec<JS<Attr>>>;
|
||||||
fn style_attribute(self) -> &'a DOMRefCell<Option<style::PropertyDeclarationBlock>>;
|
fn style_attribute(self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>>;
|
||||||
fn summarize(self) -> Vec<AttrInfo>;
|
fn summarize(self) -> Vec<AttrInfo>;
|
||||||
fn is_void(self) -> bool;
|
fn is_void(self) -> bool;
|
||||||
fn remove_inline_style_property(self, property: DOMString);
|
fn remove_inline_style_property(self, property: DOMString);
|
||||||
fn update_inline_style(self, property_decl: style::PropertyDeclaration, style_priority: StylePriority);
|
fn update_inline_style(self, property_decl: PropertyDeclaration, style_priority: StylePriority);
|
||||||
fn get_inline_style_declaration(self, property: &Atom) -> Option<style::PropertyDeclaration>;
|
fn get_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
||||||
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<style::PropertyDeclaration>;
|
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
|
@ -446,7 +449,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
self.extended_deref().attrs.borrow_mut()
|
self.extended_deref().attrs.borrow_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn style_attribute(self) -> &'a DOMRefCell<Option<style::PropertyDeclarationBlock>> {
|
fn style_attribute(self) -> &'a DOMRefCell<Option<PropertyDeclarationBlock>> {
|
||||||
&self.extended_deref().style_attribute
|
&self.extended_deref().style_attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,7 +506,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_inline_style(self, property_decl: style::PropertyDeclaration, style_priority: StylePriority) {
|
fn update_inline_style(self, property_decl: PropertyDeclaration, style_priority: StylePriority) {
|
||||||
let mut inline_declarations = self.style_attribute().borrow_mut();
|
let mut inline_declarations = self.style_attribute().borrow_mut();
|
||||||
if let &mut Some(ref mut declarations) = &mut *inline_declarations {
|
if let &mut Some(ref mut declarations) = &mut *inline_declarations {
|
||||||
let existing_declarations = if style_priority == StylePriority::Important {
|
let existing_declarations = if style_priority == StylePriority::Important {
|
||||||
|
@ -528,13 +531,13 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
(vec!(), vec!(property_decl))
|
(vec!(), vec!(property_decl))
|
||||||
};
|
};
|
||||||
|
|
||||||
*inline_declarations = Some(style::PropertyDeclarationBlock {
|
*inline_declarations = Some(PropertyDeclarationBlock {
|
||||||
important: Arc::new(important),
|
important: Arc::new(important),
|
||||||
normal: Arc::new(normal),
|
normal: Arc::new(normal),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_inline_style_declaration(self, property: &Atom) -> Option<style::PropertyDeclaration> {
|
fn get_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
||||||
let inline_declarations = self.style_attribute.borrow();
|
let inline_declarations = self.style_attribute.borrow();
|
||||||
inline_declarations.as_ref().and_then(|declarations| {
|
inline_declarations.as_ref().and_then(|declarations| {
|
||||||
declarations.normal
|
declarations.normal
|
||||||
|
@ -545,7 +548,7 @@ impl<'a> ElementHelpers<'a> for JSRef<'a, Element> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<style::PropertyDeclaration> {
|
fn get_important_inline_style_declaration(self, property: &Atom) -> Option<PropertyDeclaration> {
|
||||||
let inline_declarations = self.style_attribute.borrow();
|
let inline_declarations = self.style_attribute.borrow();
|
||||||
inline_declarations.as_ref().and_then(|declarations| {
|
inline_declarations.as_ref().and_then(|declarations| {
|
||||||
declarations.important
|
declarations.important
|
||||||
|
@ -1117,7 +1120,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
|
|
||||||
// http://dom.spec.whatwg.org/#dom-element-matches
|
// http://dom.spec.whatwg.org/#dom-element-matches
|
||||||
fn Matches(self, selectors: DOMString) -> Fallible<bool> {
|
fn Matches(self, selectors: DOMString) -> Fallible<bool> {
|
||||||
match style::parse_author_origin_selector_list_from_str(selectors.as_slice()) {
|
match parse_author_origin_selector_list_from_str(selectors.as_slice()) {
|
||||||
Err(()) => Err(Syntax),
|
Err(()) => Err(Syntax),
|
||||||
Ok(ref selectors) => {
|
Ok(ref selectors) => {
|
||||||
let root: JSRef<Node> = NodeCast::from_ref(self);
|
let root: JSRef<Node> = NodeCast::from_ref(self);
|
||||||
|
@ -1128,7 +1131,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-element-closest
|
// https://dom.spec.whatwg.org/#dom-element-closest
|
||||||
fn Closest(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> {
|
fn Closest(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> {
|
||||||
match style::parse_author_origin_selector_list_from_str(selectors.as_slice()) {
|
match parse_author_origin_selector_list_from_str(selectors.as_slice()) {
|
||||||
Err(()) => Err(Syntax),
|
Err(()) => Err(Syntax),
|
||||||
Ok(ref selectors) => {
|
Ok(ref selectors) => {
|
||||||
let root: JSRef<Node> = NodeCast::from_ref(self);
|
let root: JSRef<Node> = NodeCast::from_ref(self);
|
||||||
|
@ -1173,7 +1176,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
|
||||||
let doc = document_from_node(*self).root();
|
let doc = document_from_node(*self).root();
|
||||||
let base_url = doc.r().url().clone();
|
let base_url = doc.r().url().clone();
|
||||||
let value = attr.value();
|
let value = attr.value();
|
||||||
let style = Some(style::parse_style_attribute(value.as_slice(), &base_url));
|
let style = Some(parse_style_attribute(value.as_slice(), &base_url));
|
||||||
*self.style_attribute.borrow_mut() = style;
|
*self.style_attribute.borrow_mut() = style;
|
||||||
|
|
||||||
if node.is_in_doc() {
|
if node.is_in_doc() {
|
||||||
|
@ -1312,7 +1315,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> style::TElement<'a> for JSRef<'a, Element> {
|
impl<'a> style::node::TElement<'a> for JSRef<'a, Element> {
|
||||||
#[allow(unsafe_blocks)]
|
#[allow(unsafe_blocks)]
|
||||||
fn get_attr(self, namespace: &Namespace, attr: &Atom) -> Option<&'a str> {
|
fn get_attr(self, namespace: &Namespace, attr: &Atom) -> Option<&'a str> {
|
||||||
self.get_attribute(namespace.clone(), attr).root().map(|attr| {
|
self.get_attribute(namespace.clone(), attr).root().map(|attr| {
|
||||||
|
|
|
@ -14,7 +14,7 @@ use dom::node::{Node, NodeHelpers, NodeTypeId, window_from_node};
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use layout_interface::{LayoutChan, Msg};
|
use layout_interface::{LayoutChan, Msg};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
use style::{StylesheetOrigin, Stylesheet};
|
use style::stylesheets::{Origin, Stylesheet};
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct HTMLStyleElement {
|
pub struct HTMLStyleElement {
|
||||||
|
@ -55,8 +55,7 @@ impl<'a> StyleElementHelpers for JSRef<'a, HTMLStyleElement> {
|
||||||
let url = win.page().get_url();
|
let url = win.page().get_url();
|
||||||
|
|
||||||
let data = node.GetTextContent().expect("Element.textContent must be a string");
|
let data = node.GetTextContent().expect("Element.textContent must be a string");
|
||||||
let sheet = Stylesheet::from_str(data.as_slice(), url,
|
let sheet = Stylesheet::from_str(data.as_slice(), url, Origin::Author);
|
||||||
StylesheetOrigin::Author);
|
|
||||||
let LayoutChan(ref layout_chan) = win.page().layout_chan;
|
let LayoutChan(ref layout_chan) = win.page().layout_chan;
|
||||||
layout_chan.send(Msg::AddStylesheet(sheet));
|
layout_chan.send(Msg::AddStylesheet(sheet));
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,11 @@ use devtools_traits::NodeInfo;
|
||||||
use script_traits::UntrustedNodeAddress;
|
use script_traits::UntrustedNodeAddress;
|
||||||
use util::geometry::Au;
|
use util::geometry::Au;
|
||||||
use util::str::{DOMString, null_str_as_empty};
|
use util::str::{DOMString, null_str_as_empty};
|
||||||
use style::{matches, SelectorList};
|
use style::selectors::{Selector, AttrSelector, NamespaceConstraint};
|
||||||
|
use style::selectors::parse_author_origin_selector_list_from_str;
|
||||||
|
use style::selector_matching::matches;
|
||||||
|
use style::properties::ComputedValues;
|
||||||
|
use style;
|
||||||
|
|
||||||
use js::jsapi::{JSContext, JSObject, JSTracer, JSRuntime};
|
use js::jsapi::{JSContext, JSObject, JSTracer, JSRuntime};
|
||||||
use js::jsfriendapi;
|
use js::jsfriendapi;
|
||||||
|
@ -60,7 +64,6 @@ use std::cell::{Cell, RefCell, Ref, RefMut};
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::iter::{FilterMap, Peekable};
|
use std::iter::{FilterMap, Peekable};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use style::{self, ComputedValues};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use uuid;
|
use uuid;
|
||||||
use string_cache::QualName;
|
use string_cache::QualName;
|
||||||
|
@ -376,12 +379,12 @@ impl<'a> PrivateNodeHelpers for JSRef<'a, Node> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct QuerySelectorIterator<'a> {
|
pub struct QuerySelectorIterator<'a> {
|
||||||
selectors: SelectorList,
|
selectors: Vec<Selector>,
|
||||||
iterator: TreeIterator<'a>,
|
iterator: TreeIterator<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> QuerySelectorIterator<'a> {
|
impl<'a> QuerySelectorIterator<'a> {
|
||||||
unsafe fn new(iter: TreeIterator<'a>, selectors: SelectorList) -> QuerySelectorIterator<'a> {
|
unsafe fn new(iter: TreeIterator<'a>, selectors: Vec<Selector>) -> QuerySelectorIterator<'a> {
|
||||||
QuerySelectorIterator {
|
QuerySelectorIterator {
|
||||||
selectors: selectors,
|
selectors: selectors,
|
||||||
iterator: iter,
|
iterator: iter,
|
||||||
|
@ -746,7 +749,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> {
|
||||||
// http://dom.spec.whatwg.org/#dom-parentnode-queryselector
|
// http://dom.spec.whatwg.org/#dom-parentnode-queryselector
|
||||||
fn query_selector(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> {
|
fn query_selector(self, selectors: DOMString) -> Fallible<Option<Temporary<Element>>> {
|
||||||
// Step 1.
|
// Step 1.
|
||||||
match style::parse_author_origin_selector_list_from_str(selectors.as_slice()) {
|
match parse_author_origin_selector_list_from_str(selectors.as_slice()) {
|
||||||
// Step 2.
|
// Step 2.
|
||||||
Err(()) => return Err(Syntax),
|
Err(()) => return Err(Syntax),
|
||||||
// Step 3.
|
// Step 3.
|
||||||
|
@ -768,7 +771,7 @@ impl<'a> NodeHelpers<'a> for JSRef<'a, Node> {
|
||||||
// Step 1.
|
// Step 1.
|
||||||
let nodes;
|
let nodes;
|
||||||
let root = self.ancestors().last().unwrap_or(self.clone());
|
let root = self.ancestors().last().unwrap_or(self.clone());
|
||||||
match style::parse_author_origin_selector_list_from_str(selectors.as_slice()) {
|
match parse_author_origin_selector_list_from_str(selectors.as_slice()) {
|
||||||
// Step 2.
|
// Step 2.
|
||||||
Err(()) => return Err(Syntax),
|
Err(()) => return Err(Syntax),
|
||||||
// Step 3.
|
// Step 3.
|
||||||
|
@ -2229,7 +2232,7 @@ impl<'a> VirtualMethods for JSRef<'a, Node> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> style::TNode<'a, JSRef<'a, Element>> for JSRef<'a, Node> {
|
impl<'a> style::node::TNode<'a, JSRef<'a, Element>> for JSRef<'a, Node> {
|
||||||
fn parent_node(self) -> Option<JSRef<'a, Node>> {
|
fn parent_node(self) -> Option<JSRef<'a, Node>> {
|
||||||
// FIXME(zwarich): Remove this when UFCS lands and there is a better way
|
// FIXME(zwarich): Remove this when UFCS lands and there is a better way
|
||||||
// of disambiguating methods.
|
// of disambiguating methods.
|
||||||
|
@ -2304,7 +2307,7 @@ impl<'a> style::TNode<'a, JSRef<'a, Element>> for JSRef<'a, Node> {
|
||||||
ElementCast::to_ref(self).unwrap()
|
ElementCast::to_ref(self).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_attr<F>(self, attr: &style::AttrSelector, test: F) -> bool
|
fn match_attr<F>(self, attr: &AttrSelector, test: F) -> bool
|
||||||
where F: Fn(&str) -> bool
|
where F: Fn(&str) -> bool
|
||||||
{
|
{
|
||||||
let name = {
|
let name = {
|
||||||
|
@ -2315,11 +2318,11 @@ impl<'a> style::TNode<'a, JSRef<'a, Element>> for JSRef<'a, Node> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match attr.namespace {
|
match attr.namespace {
|
||||||
style::NamespaceConstraint::Specific(ref ns) => {
|
NamespaceConstraint::Specific(ref ns) => {
|
||||||
self.as_element().get_attribute(ns.clone(), name).root()
|
self.as_element().get_attribute(ns.clone(), name).root()
|
||||||
.map_or(false, |attr| test(attr.r().value().as_slice()))
|
.map_or(false, |attr| test(attr.r().value().as_slice()))
|
||||||
},
|
},
|
||||||
style::NamespaceConstraint::Any => {
|
NamespaceConstraint::Any => {
|
||||||
self.as_element().get_attributes(name).into_iter()
|
self.as_element().get_attributes(name).into_iter()
|
||||||
.map(|attr| attr.root())
|
.map(|attr| attr.root())
|
||||||
.any(|attr| test(attr.r().value().as_slice()))
|
.any(|attr| test(attr.r().value().as_slice()))
|
||||||
|
|
|
@ -16,7 +16,7 @@ use util::geometry::Au;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||||
use std::boxed::BoxAny;
|
use std::boxed::BoxAny;
|
||||||
use style::Stylesheet;
|
use style::stylesheets::Stylesheet;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub use dom::node::TrustedNodeAddress;
|
pub use dom::node::TrustedNodeAddress;
|
||||||
|
|
8
components/servo/Cargo.lock
generated
8
components/servo/Cargo.lock
generated
|
@ -134,7 +134,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cssparser"
|
name = "cssparser"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/servo/rust-cssparser#2a8c9f2c5f568495bae16f44b799be39b8efad39"
|
source = "git+https://github.com/servo/rust-cssparser#42714934cbe83dab349190695503a09ae23f9528"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -553,6 +553,11 @@ dependencies = [
|
||||||
"log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mod_path"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mozjs-sys"
|
name = "mozjs-sys"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
@ -753,6 +758,7 @@ dependencies = [
|
||||||
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
|
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
|
||||||
"lazy_static 0.1.6 (git+https://github.com/Kimundi/lazy-static.rs)",
|
"lazy_static 0.1.6 (git+https://github.com/Kimundi/lazy-static.rs)",
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"mod_path 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"plugins 0.0.1",
|
"plugins 0.0.1",
|
||||||
"string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
|
"string_cache 0.0.0 (git+https://github.com/servo/string-cache)",
|
||||||
"string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
|
"string_cache_macros 0.0.0 (git+https://github.com/servo/string-cache)",
|
||||||
|
|
2
components/style/.gitignore
vendored
2
components/style/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
properties/mod.rs
|
|
||||||
properties/mod.rs.tmp
|
|
|
@ -3,7 +3,7 @@ name = "style"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
authors = ["The Servo Project Developers"]
|
authors = ["The Servo Project Developers"]
|
||||||
|
|
||||||
build = "make -f makefile.cargo"
|
build = "build.rs"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "style"
|
name = "style"
|
||||||
|
@ -34,4 +34,5 @@ git = "https://github.com/servo/string-cache"
|
||||||
text_writer = "0.1.1"
|
text_writer = "0.1.1"
|
||||||
encoding = "0.2"
|
encoding = "0.2"
|
||||||
matches = "0.1"
|
matches = "0.1"
|
||||||
url = "*"
|
url = "*"
|
||||||
|
mod_path = "0.1"
|
||||||
|
|
31
components/style/build.rs
Normal file
31
components/style/build.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/* 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::os;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::io::process::{Command, ProcessExit, StdioContainer};
|
||||||
|
use std::io::File;
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let python = if Command::new("python2.7").arg("--version").status() == Ok(ProcessExit::ExitStatus(0)) {
|
||||||
|
"python2.7"
|
||||||
|
} else {
|
||||||
|
"python"
|
||||||
|
};
|
||||||
|
let style = Path::new(file!()).dir_path();
|
||||||
|
let mako = style.join("Mako-0.9.1.zip");
|
||||||
|
let template = style.join("properties.mako.rs");
|
||||||
|
let result = Command::new(python)
|
||||||
|
.env("PYTHONPATH", mako.as_str().unwrap())
|
||||||
|
.env("TEMPLATE", template.as_str().unwrap())
|
||||||
|
.arg("-c")
|
||||||
|
.arg("from os import environ; from mako.template import Template; print(Template(filename=environ['TEMPLATE']).render())")
|
||||||
|
.stderr(StdioContainer::InheritFd(2))
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(result.status, ProcessExit::ExitStatus(0));
|
||||||
|
let out = Path::new(os::getenv("OUT_DIR").unwrap());
|
||||||
|
File::create(&out.join("properties.rs")).unwrap().write(&*result.output).unwrap();
|
||||||
|
}
|
|
@ -6,10 +6,10 @@ use cssparser::{Token, Parser, DeclarationListParser, AtRuleParser, DeclarationP
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use stylesheets::CSSRule;
|
use stylesheets::CSSRule;
|
||||||
use properties::longhands::font_family::parse_one_family;
|
use properties::longhands::font_family::parse_one_family;
|
||||||
use properties::computed_values::font_family::FontFamily;
|
use computed_values::font_family::FontFamily;
|
||||||
use media_queries::Device;
|
use media_queries::Device;
|
||||||
use url::{Url, UrlParser};
|
use url::{Url, UrlParser};
|
||||||
use parser::ParserContext;
|
use parser::{ParserContext, log_css_error};
|
||||||
|
|
||||||
|
|
||||||
pub fn iter_font_face_rules_inner<F>(rules: &[CSSRule], device: &Device,
|
pub fn iter_font_face_rules_inner<F>(rules: &[CSSRule], device: &Device,
|
||||||
|
@ -52,13 +52,26 @@ pub struct FontFaceRule {
|
||||||
|
|
||||||
pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser)
|
pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser)
|
||||||
-> Result<FontFaceRule, ()> {
|
-> Result<FontFaceRule, ()> {
|
||||||
let parser = FontFaceRuleParser {
|
let mut family = None;
|
||||||
context: context,
|
let mut src = None;
|
||||||
family: None,
|
let mut iter = DeclarationListParser::new(input, FontFaceRuleParser { context: context });
|
||||||
src: None,
|
while let Some(declaration) = iter.next() {
|
||||||
};
|
match declaration {
|
||||||
match DeclarationListParser::new(input, parser).run() {
|
Err(range) => {
|
||||||
FontFaceRuleParser { family: Some(family), src: Some(src), .. } => {
|
let message = format!("Unsupported @font-face descriptor declaration: '{}'",
|
||||||
|
iter.input.slice(range));
|
||||||
|
log_css_error(iter.input, range.start, &*message);
|
||||||
|
}
|
||||||
|
Ok(FontFaceDescriptorDeclaration::Family(value)) => {
|
||||||
|
family = Some(value);
|
||||||
|
}
|
||||||
|
Ok(FontFaceDescriptorDeclaration::Src(value)) => {
|
||||||
|
src = Some(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match (family, src) {
|
||||||
|
(Some(family), Some(src)) => {
|
||||||
Ok(FontFaceRule {
|
Ok(FontFaceRule {
|
||||||
family: family,
|
family: family,
|
||||||
sources: src,
|
sources: src,
|
||||||
|
@ -68,30 +81,36 @@ pub fn parse_font_face_block(context: &ParserContext, input: &mut Parser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum FontFaceDescriptorDeclaration {
|
||||||
|
Family(String),
|
||||||
|
Src(Vec<Source>),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct FontFaceRuleParser<'a, 'b: 'a> {
|
struct FontFaceRuleParser<'a, 'b: 'a> {
|
||||||
context: &'a ParserContext<'b>,
|
context: &'a ParserContext<'b>,
|
||||||
family: Option<String>,
|
|
||||||
src: Option<Vec<Source>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Default methods reject all at rules.
|
/// Default methods reject all at rules.
|
||||||
impl<'a, 'b> AtRuleParser<(), ()> for FontFaceRuleParser<'a, 'b> {}
|
impl<'a, 'b> AtRuleParser for FontFaceRuleParser<'a, 'b> {
|
||||||
|
type Prelude = ();
|
||||||
|
type AtRule = FontFaceDescriptorDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a, 'b> DeclarationParser<()> for FontFaceRuleParser<'a, 'b> {
|
impl<'a, 'b> DeclarationParser for FontFaceRuleParser<'a, 'b> {
|
||||||
fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result<(), ()> {
|
type Declaration = FontFaceDescriptorDeclaration;
|
||||||
|
|
||||||
|
fn parse_value(&self, name: &str, input: &mut Parser) -> Result<FontFaceDescriptorDeclaration, ()> {
|
||||||
match_ignore_ascii_case! { name,
|
match_ignore_ascii_case! { name,
|
||||||
"font-family" => {
|
"font-family" => {
|
||||||
self.family = Some(try!(parse_one_non_generic_family_name(input)));
|
Ok(FontFaceDescriptorDeclaration::Family(try!(parse_one_non_generic_family_name(input))))
|
||||||
Ok(())
|
|
||||||
},
|
},
|
||||||
"src" => {
|
"src" => {
|
||||||
self.src = Some(try!(input.parse_comma_separated(|input| {
|
Ok(FontFaceDescriptorDeclaration::Src(try!(input.parse_comma_separated(|input| {
|
||||||
parse_one_src(self.context, input)
|
parse_one_src(self.context, input)
|
||||||
})));
|
}))))
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
_ => Err(())
|
_ => Err(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,42 +34,33 @@ extern crate lazy_static;
|
||||||
|
|
||||||
extern crate util;
|
extern crate util;
|
||||||
|
|
||||||
|
#[plugin] #[no_link] extern crate mod_path;
|
||||||
|
|
||||||
pub use media_queries::{Device, MediaType};
|
|
||||||
pub use stylesheets::{Stylesheet, iter_font_face_rules};
|
|
||||||
pub use selector_matching::{Stylist};
|
|
||||||
pub use selector_matching::{DeclarationBlock, CommonStyleAffectingAttributes};
|
|
||||||
pub use selector_matching::{CommonStyleAffectingAttributeInfo, CommonStyleAffectingAttributeMode};
|
|
||||||
pub use selector_matching::{matches, matches_simple_selector, common_style_affecting_attributes};
|
|
||||||
pub use selector_matching::{rare_style_affecting_attributes};
|
|
||||||
pub use selector_matching::{RECOMMENDED_SELECTOR_BLOOM_FILTER_SIZE, SELECTOR_WHITESPACE};
|
|
||||||
pub use properties::{cascade, cascade_anonymous, longhands_from_shorthand};
|
|
||||||
pub use properties::{is_supported_property, make_inline};
|
|
||||||
pub use properties::{PropertyDeclaration};
|
|
||||||
pub use properties::{computed_values, ComputedValues, style_structs};
|
|
||||||
pub use properties::{PropertyDeclarationBlock, parse_style_attribute}; // Style attributes
|
|
||||||
pub use properties::{DeclaredValue, PropertyDeclarationParseResult};
|
|
||||||
pub use values::CSSFloat;
|
|
||||||
pub use values::specified::{Angle, AngleOrCorner, HorizontalDirection, VerticalDirection};
|
|
||||||
pub use values::computed;
|
|
||||||
pub use node::{TElement, TElementAttributes, TNode};
|
|
||||||
pub use selectors::{PseudoElement, SelectorList};
|
|
||||||
pub use selectors::{AttrSelector, NamespaceConstraint};
|
|
||||||
pub use selectors::{SimpleSelector, parse_author_origin_selector_list_from_str};
|
|
||||||
pub use cssparser::{Color, RGBA};
|
|
||||||
pub use legacy::{IntegerAttribute, LengthAttribute};
|
|
||||||
pub use legacy::{SimpleColorAttribute, UnsignedIntegerAttribute};
|
|
||||||
pub use font_face::Source;
|
|
||||||
pub use stylesheets::Origin as StylesheetOrigin;
|
|
||||||
|
|
||||||
pub mod stylesheets;
|
pub mod stylesheets;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod selectors;
|
pub mod selectors;
|
||||||
pub mod selector_matching;
|
pub mod selector_matching;
|
||||||
#[macro_use] pub mod values;
|
#[macro_use] pub mod values;
|
||||||
pub mod properties;
|
|
||||||
pub mod namespaces;
|
// Generated from the properties.mako.rs template by build.rs
|
||||||
|
mod_path! properties (concat!(env!("OUT_DIR"), "/properties.rs"));
|
||||||
|
|
||||||
pub mod node;
|
pub mod node;
|
||||||
pub mod media_queries;
|
pub mod media_queries;
|
||||||
pub mod font_face;
|
pub mod font_face;
|
||||||
pub mod legacy;
|
pub mod legacy;
|
||||||
|
|
||||||
|
macro_rules! reexport_computed_values {
|
||||||
|
( $( $name: ident )+ ) => {
|
||||||
|
pub mod computed_values {
|
||||||
|
$(
|
||||||
|
pub use properties::longhands::$name::computed_value as $name;
|
||||||
|
)+
|
||||||
|
// Don't use a side-specific name needlessly:
|
||||||
|
pub use properties::longhands::border_top_style::computed_value as border_style;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
longhand_properties_idents!(reexport_computed_values);
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
MAKO_ZIP = Mako-0.9.1.zip
|
|
||||||
PYTHON = $(shell which python2.7 2>/dev/null || echo python)
|
|
||||||
|
|
||||||
all: properties/mod.rs
|
|
||||||
|
|
||||||
properties/mod.rs: properties/mod.rs.mako
|
|
||||||
PYTHONPATH=$(MAKO_ZIP) $(PYTHON) -c "from mako.template import Template; print(Template(filename='$<').render())" > $@.tmp
|
|
||||||
mv $@.tmp $@
|
|
|
@ -1,49 +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 cssparser::Parser;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use string_cache::{Atom, Namespace};
|
|
||||||
use parser::ParserContext;
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct NamespaceMap {
|
|
||||||
pub default: Option<Namespace>,
|
|
||||||
pub prefix_map: HashMap<String, Namespace>,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl NamespaceMap {
|
|
||||||
pub fn new() -> NamespaceMap {
|
|
||||||
NamespaceMap { default: None, prefix_map: HashMap::new() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn parse_namespace_rule(context: &mut ParserContext, input: &mut Parser)
|
|
||||||
-> Result<(Option<String>, Namespace), ()> {
|
|
||||||
let prefix = input.try(|input| input.expect_ident()).ok().map(|p| p.into_owned());
|
|
||||||
let url = try!(input.expect_url_or_string());
|
|
||||||
try!(input.expect_exhausted());
|
|
||||||
|
|
||||||
let namespace = Namespace(Atom::from_slice(url.as_slice()));
|
|
||||||
let is_duplicate = match prefix {
|
|
||||||
Some(ref prefix) => {
|
|
||||||
context.namespaces.prefix_map.insert(prefix.clone(), namespace.clone()).is_some()
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let has_default = context.namespaces.default.is_some();
|
|
||||||
if !has_default {
|
|
||||||
context.namespaces.default = Some(namespace.clone());
|
|
||||||
}
|
|
||||||
has_default
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if is_duplicate {
|
|
||||||
Err(()) // "Duplicate @namespace rule"
|
|
||||||
} else {
|
|
||||||
Ok((prefix, namespace))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,12 +3,19 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use string_cache::Namespace;
|
||||||
use cssparser::{Parser, SourcePosition};
|
use cssparser::{Parser, SourcePosition};
|
||||||
use url::{Url, UrlParser};
|
use url::{Url, UrlParser};
|
||||||
use log;
|
use log;
|
||||||
|
|
||||||
use stylesheets::Origin;
|
use stylesheets::Origin;
|
||||||
use namespaces::NamespaceMap;
|
|
||||||
|
|
||||||
|
pub struct NamespaceMap {
|
||||||
|
pub default: Option<Namespace>,
|
||||||
|
pub prefix_map: HashMap<String, Namespace>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct ParserContext<'a> {
|
pub struct ParserContext<'a> {
|
||||||
|
@ -17,6 +24,19 @@ pub struct ParserContext<'a> {
|
||||||
pub namespaces: NamespaceMap,
|
pub namespaces: NamespaceMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ParserContext<'a> {
|
||||||
|
pub fn new(stylesheet_origin: Origin, base_url: &'a Url) -> ParserContext<'a> {
|
||||||
|
ParserContext {
|
||||||
|
stylesheet_origin: stylesheet_origin,
|
||||||
|
base_url: base_url,
|
||||||
|
namespaces: NamespaceMap {
|
||||||
|
default: None,
|
||||||
|
prefix_map: HashMap::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a> ParserContext<'a> {
|
impl<'a> ParserContext<'a> {
|
||||||
pub fn in_user_agent_stylesheet(&self) -> bool {
|
pub fn in_user_agent_stylesheet(&self) -> bool {
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
// This file is a Mako template: http://www.makotemplates.org/
|
// This file is a Mako template: http://www.makotemplates.org/
|
||||||
|
|
||||||
|
#![macro_use]
|
||||||
|
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -20,9 +22,9 @@ use geom::SideOffsets2D;
|
||||||
use values::specified::BorderStyle;
|
use values::specified::BorderStyle;
|
||||||
use values::computed;
|
use values::computed;
|
||||||
use selector_matching::DeclarationBlock;
|
use selector_matching::DeclarationBlock;
|
||||||
use parser::ParserContext;
|
use parser::{ParserContext, log_css_error};
|
||||||
use namespaces::NamespaceMap;
|
|
||||||
use stylesheets::Origin;
|
use stylesheets::Origin;
|
||||||
|
use computed_values;
|
||||||
|
|
||||||
use self::property_bit_field::PropertyBitField;
|
use self::property_bit_field::PropertyBitField;
|
||||||
|
|
||||||
|
@ -1805,7 +1807,9 @@ pub mod longhands {
|
||||||
</%self:longhand>
|
</%self:longhand>
|
||||||
|
|
||||||
${single_keyword("mix-blend-mode",
|
${single_keyword("mix-blend-mode",
|
||||||
"normal multiply screen overlay darken lighten color-dodge color-burn hard-light soft-light difference exclusion hue saturation color luminosity")}
|
"""normal multiply screen overlay darken lighten color-dodge
|
||||||
|
color-burn hard-light soft-light difference exclusion hue
|
||||||
|
saturation color luminosity""")}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2325,57 +2329,65 @@ pub struct PropertyDeclarationBlock {
|
||||||
|
|
||||||
|
|
||||||
pub fn parse_style_attribute(input: &str, base_url: &Url) -> PropertyDeclarationBlock {
|
pub fn parse_style_attribute(input: &str, base_url: &Url) -> PropertyDeclarationBlock {
|
||||||
let context = ParserContext {
|
let context = ParserContext::new(Origin::Author, base_url);
|
||||||
stylesheet_origin: Origin::Author,
|
|
||||||
base_url: base_url,
|
|
||||||
namespaces: NamespaceMap::new(),
|
|
||||||
};
|
|
||||||
parse_property_declaration_list(&context, &mut Parser::new(input))
|
parse_property_declaration_list(&context, &mut Parser::new(input))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct PropertyDeclarationParser<'a, 'b: 'a> {
|
struct PropertyDeclarationParser<'a, 'b: 'a> {
|
||||||
context: &'a ParserContext<'b>,
|
context: &'a ParserContext<'b>,
|
||||||
important_declarations: Vec<PropertyDeclaration>,
|
|
||||||
normal_declarations: Vec<PropertyDeclaration>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Default methods reject all at rules.
|
/// Default methods reject all at rules.
|
||||||
impl<'a, 'b> AtRuleParser<(), ()> for PropertyDeclarationParser<'a, 'b> {}
|
impl<'a, 'b> AtRuleParser for PropertyDeclarationParser<'a, 'b> {
|
||||||
|
type Prelude = ();
|
||||||
|
type AtRule = (Vec<PropertyDeclaration>, bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a, 'b> DeclarationParser<()> for PropertyDeclarationParser<'a, 'b> {
|
impl<'a, 'b> DeclarationParser for PropertyDeclarationParser<'a, 'b> {
|
||||||
fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result<(), ()> {
|
type Declaration = (Vec<PropertyDeclaration>, bool);
|
||||||
|
|
||||||
|
fn parse_value(&self, name: &str, input: &mut Parser) -> Result<(Vec<PropertyDeclaration>, bool), ()> {
|
||||||
let mut results = vec![];
|
let mut results = vec![];
|
||||||
let important = try!(input.parse_entirely(|input| {
|
match PropertyDeclaration::parse(name, self.context, input, &mut results) {
|
||||||
match PropertyDeclaration::parse(name, self.context, input, &mut results) {
|
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => {}
|
||||||
PropertyDeclarationParseResult::ValidOrIgnoredDeclaration => {}
|
_ => return Err(())
|
||||||
_ => return Err(())
|
|
||||||
}
|
|
||||||
Ok(input.try(parse_important).is_ok())
|
|
||||||
}));
|
|
||||||
if important {
|
|
||||||
self.important_declarations.push_all(results.as_slice());
|
|
||||||
} else {
|
|
||||||
self.normal_declarations.push_all(results.as_slice());
|
|
||||||
}
|
}
|
||||||
Ok(())
|
let important = input.try(parse_important).is_ok();
|
||||||
|
Ok((results, important))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn parse_property_declaration_list(context: &ParserContext, input: &mut Parser)
|
pub fn parse_property_declaration_list(context: &ParserContext, input: &mut Parser)
|
||||||
-> PropertyDeclarationBlock {
|
-> PropertyDeclarationBlock {
|
||||||
|
let mut important_declarations = Vec::new();
|
||||||
|
let mut normal_declarations = Vec::new();
|
||||||
let parser = PropertyDeclarationParser {
|
let parser = PropertyDeclarationParser {
|
||||||
context: context,
|
context: context,
|
||||||
important_declarations: vec![],
|
|
||||||
normal_declarations: vec![],
|
|
||||||
};
|
};
|
||||||
let parser = DeclarationListParser::new(input, parser).run();
|
let mut iter = DeclarationListParser::new(input, parser);
|
||||||
|
while let Some(declaration) = iter.next() {
|
||||||
|
match declaration {
|
||||||
|
Ok((results, important)) => {
|
||||||
|
if important {
|
||||||
|
important_declarations.push_all(results.as_slice());
|
||||||
|
} else {
|
||||||
|
normal_declarations.push_all(results.as_slice());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(range) => {
|
||||||
|
let message = format!("Unsupported property declaration: '{}'",
|
||||||
|
iter.input.slice(range));
|
||||||
|
log_css_error(iter.input, range.start, &*message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
PropertyDeclarationBlock {
|
PropertyDeclarationBlock {
|
||||||
important: Arc::new(deduplicate_property_declarations(parser.important_declarations)),
|
important: Arc::new(deduplicate_property_declarations(important_declarations)),
|
||||||
normal: Arc::new(deduplicate_property_declarations(parser.normal_declarations)),
|
normal: Arc::new(deduplicate_property_declarations(normal_declarations)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2622,43 +2634,43 @@ impl ComputedValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn content_inline_size(&self) -> computed_values::LengthOrPercentageOrAuto {
|
pub fn content_inline_size(&self) -> computed::LengthOrPercentageOrAuto {
|
||||||
let box_style = self.get_box();
|
let box_style = self.get_box();
|
||||||
if self.writing_mode.is_vertical() { box_style.height } else { box_style.width }
|
if self.writing_mode.is_vertical() { box_style.height } else { box_style.width }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn content_block_size(&self) -> computed_values::LengthOrPercentageOrAuto {
|
pub fn content_block_size(&self) -> computed::LengthOrPercentageOrAuto {
|
||||||
let box_style = self.get_box();
|
let box_style = self.get_box();
|
||||||
if self.writing_mode.is_vertical() { box_style.width } else { box_style.height }
|
if self.writing_mode.is_vertical() { box_style.width } else { box_style.height }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn min_inline_size(&self) -> computed_values::LengthOrPercentage {
|
pub fn min_inline_size(&self) -> computed::LengthOrPercentage {
|
||||||
let box_style = self.get_box();
|
let box_style = self.get_box();
|
||||||
if self.writing_mode.is_vertical() { box_style.min_height } else { box_style.min_width }
|
if self.writing_mode.is_vertical() { box_style.min_height } else { box_style.min_width }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn min_block_size(&self) -> computed_values::LengthOrPercentage {
|
pub fn min_block_size(&self) -> computed::LengthOrPercentage {
|
||||||
let box_style = self.get_box();
|
let box_style = self.get_box();
|
||||||
if self.writing_mode.is_vertical() { box_style.min_width } else { box_style.min_height }
|
if self.writing_mode.is_vertical() { box_style.min_width } else { box_style.min_height }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn max_inline_size(&self) -> computed_values::LengthOrPercentageOrNone {
|
pub fn max_inline_size(&self) -> computed::LengthOrPercentageOrNone {
|
||||||
let box_style = self.get_box();
|
let box_style = self.get_box();
|
||||||
if self.writing_mode.is_vertical() { box_style.max_height } else { box_style.max_width }
|
if self.writing_mode.is_vertical() { box_style.max_height } else { box_style.max_width }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn max_block_size(&self) -> computed_values::LengthOrPercentageOrNone {
|
pub fn max_block_size(&self) -> computed::LengthOrPercentageOrNone {
|
||||||
let box_style = self.get_box();
|
let box_style = self.get_box();
|
||||||
if self.writing_mode.is_vertical() { box_style.max_width } else { box_style.max_height }
|
if self.writing_mode.is_vertical() { box_style.max_width } else { box_style.max_height }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn logical_padding(&self) -> LogicalMargin<computed_values::LengthOrPercentage> {
|
pub fn logical_padding(&self) -> LogicalMargin<computed::LengthOrPercentage> {
|
||||||
let padding_style = self.get_padding();
|
let padding_style = self.get_padding();
|
||||||
LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new(
|
LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new(
|
||||||
padding_style.padding_top,
|
padding_style.padding_top,
|
||||||
|
@ -2680,7 +2692,7 @@ impl ComputedValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn logical_margin(&self) -> LogicalMargin<computed_values::LengthOrPercentageOrAuto> {
|
pub fn logical_margin(&self) -> LogicalMargin<computed::LengthOrPercentageOrAuto> {
|
||||||
let margin_style = self.get_margin();
|
let margin_style = self.get_margin();
|
||||||
LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new(
|
LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new(
|
||||||
margin_style.margin_top,
|
margin_style.margin_top,
|
||||||
|
@ -2691,7 +2703,7 @@ impl ComputedValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn logical_position(&self) -> LogicalMargin<computed_values::LengthOrPercentageOrAuto> {
|
pub fn logical_position(&self) -> LogicalMargin<computed::LengthOrPercentageOrAuto> {
|
||||||
// FIXME(SimonSapin): should be the writing mode of the containing block, maybe?
|
// FIXME(SimonSapin): should be the writing mode of the containing block, maybe?
|
||||||
let position_style = self.get_positionoffsets();
|
let position_style = self.get_positionoffsets();
|
||||||
LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new(
|
LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new(
|
||||||
|
@ -3162,6 +3174,17 @@ macro_rules! css_properties_accessors {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! longhand_properties_idents {
|
||||||
|
($macro_name: ident) => {
|
||||||
|
$macro_name! {
|
||||||
|
% for property in LONGHANDS:
|
||||||
|
${property.ident}
|
||||||
|
% endfor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn longhands_from_shorthand(shorthand: &str) -> Option<Vec<String>> {
|
pub fn longhands_from_shorthand(shorthand: &str) -> Option<Vec<String>> {
|
||||||
match shorthand {
|
match shorthand {
|
||||||
% for property in SHORTHANDS:
|
% for property in SHORTHANDS:
|
||||||
|
@ -3174,18 +3197,3 @@ pub fn longhands_from_shorthand(shorthand: &str) -> Option<Vec<String>> {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only re-export the types for computed values.
|
|
||||||
pub mod computed_values {
|
|
||||||
% for property in LONGHANDS:
|
|
||||||
pub use super::longhands::${property.ident}::computed_value as ${property.ident};
|
|
||||||
% endfor
|
|
||||||
// Don't use a side-specific name needlessly:
|
|
||||||
pub use super::longhands::border_top_style::computed_value as border_style;
|
|
||||||
|
|
||||||
pub use cssparser::RGBA;
|
|
||||||
pub use values::computed::{
|
|
||||||
LengthOrPercentage,
|
|
||||||
LengthOrPercentageOrAuto,
|
|
||||||
LengthOrPercentageOrNone};
|
|
||||||
}
|
|
|
@ -21,8 +21,7 @@ use media_queries::Device;
|
||||||
use node::{TElement, TElementAttributes, TNode};
|
use node::{TElement, TElementAttributes, TNode};
|
||||||
use properties::{PropertyDeclaration, PropertyDeclarationBlock};
|
use properties::{PropertyDeclaration, PropertyDeclarationBlock};
|
||||||
use selectors::{CaseSensitivity, Combinator, CompoundSelector, LocalName};
|
use selectors::{CaseSensitivity, Combinator, CompoundSelector, LocalName};
|
||||||
use selectors::{PseudoElement, SelectorList, SimpleSelector};
|
use selectors::{PseudoElement, SimpleSelector, Selector};
|
||||||
use selectors::{get_selector_list_selectors};
|
|
||||||
use stylesheets::{Stylesheet, iter_stylesheet_media_rules, iter_stylesheet_style_rules, Origin};
|
use stylesheets::{Stylesheet, iter_stylesheet_media_rules, iter_stylesheet_style_rules, Origin};
|
||||||
|
|
||||||
|
|
||||||
|
@ -549,14 +548,15 @@ impl DeclarationBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn matches<'a,E,N>(selector_list: &SelectorList,
|
pub fn matches<'a,E,N>(selector_list: &Vec<Selector>,
|
||||||
element: &N,
|
element: &N,
|
||||||
parent_bf: &Option<Box<BloomFilter>>)
|
parent_bf: &Option<Box<BloomFilter>>)
|
||||||
-> bool
|
-> bool
|
||||||
where E: TElement<'a>, N: TNode<'a,E> {
|
where E: TElement<'a>, N: TNode<'a,E> {
|
||||||
get_selector_list_selectors(selector_list).iter().any(|selector|
|
selector_list.iter().any(|selector| {
|
||||||
selector.pseudo_element.is_none() &&
|
selector.pseudo_element.is_none() &&
|
||||||
matches_compound_selector(&*selector.compound_selectors, element, parent_bf, &mut false))
|
matches_compound_selector(&*selector.compound_selectors, element, parent_bf, &mut false)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines whether the given element matches the given single or compound selector.
|
/// Determines whether the given element matches the given single or compound selector.
|
||||||
|
@ -1166,16 +1166,12 @@ mod tests {
|
||||||
/// Helper method to get some Rules from selector strings.
|
/// Helper method to get some Rules from selector strings.
|
||||||
/// Each sublist of the result contains the Rules for one StyleRule.
|
/// Each sublist of the result contains the Rules for one StyleRule.
|
||||||
fn get_mock_rules(css_selectors: &[&str]) -> Vec<Vec<Rule>> {
|
fn get_mock_rules(css_selectors: &[&str]) -> Vec<Vec<Rule>> {
|
||||||
use namespaces::NamespaceMap;
|
|
||||||
use selectors::parse_selector_list;
|
use selectors::parse_selector_list;
|
||||||
use stylesheets::Origin;
|
use stylesheets::Origin;
|
||||||
|
|
||||||
css_selectors.iter().enumerate().map(|(i, selectors)| {
|
css_selectors.iter().enumerate().map(|(i, selectors)| {
|
||||||
let context = ParserContext {
|
let url = Url::parse("about:blank").unwrap();
|
||||||
stylesheet_origin: Origin::Author,
|
let context = ParserContext::new(Origin::Author, &url);
|
||||||
namespaces: NamespaceMap::new(),
|
|
||||||
base_url: &Url::parse("about:blank").unwrap(),
|
|
||||||
};
|
|
||||||
parse_selector_list(&context, &mut Parser::new(*selectors))
|
parse_selector_list(&context, &mut Parser::new(*selectors))
|
||||||
.unwrap().into_iter().map(|s| {
|
.unwrap().into_iter().map(|s| {
|
||||||
Rule {
|
Rule {
|
||||||
|
|
|
@ -12,7 +12,6 @@ use string_cache::{Atom, Namespace};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
use namespaces::NamespaceMap;
|
|
||||||
use stylesheets::Origin;
|
use stylesheets::Origin;
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,17 +111,6 @@ pub enum NamespaceConstraint {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Re-exported to script, but opaque.
|
|
||||||
pub struct SelectorList {
|
|
||||||
selectors: Vec<Selector>
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Public to the style crate, but not re-exported to script
|
|
||||||
pub fn get_selector_list_selectors<'a>(selector_list: &'a SelectorList) -> &'a [Selector] {
|
|
||||||
selector_list.selectors.as_slice()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn compute_specificity(mut selector: &CompoundSelector,
|
fn compute_specificity(mut selector: &CompoundSelector,
|
||||||
pseudo_element: &Option<PseudoElement>) -> u32 {
|
pseudo_element: &Option<PseudoElement>) -> u32 {
|
||||||
struct Specificity {
|
struct Specificity {
|
||||||
|
@ -194,15 +182,10 @@ fn compute_specificity(mut selector: &CompoundSelector,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn parse_author_origin_selector_list_from_str(input: &str)
|
pub fn parse_author_origin_selector_list_from_str(input: &str) -> Result<Vec<Selector>, ()> {
|
||||||
-> Result<SelectorList,()> {
|
let url = Url::parse("about:blank").unwrap();
|
||||||
let context = ParserContext {
|
let context = ParserContext::new(Origin::Author, &url);
|
||||||
stylesheet_origin: Origin::Author,
|
|
||||||
namespaces: NamespaceMap::new(),
|
|
||||||
base_url: &Url::parse("about:blank").unwrap(),
|
|
||||||
};
|
|
||||||
parse_selector_list(&context, &mut Parser::new(input))
|
parse_selector_list(&context, &mut Parser::new(input))
|
||||||
.map(|s| SelectorList { selectors: s })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a comma-separated list of Selectors.
|
/// Parse a comma-separated list of Selectors.
|
||||||
|
@ -647,7 +630,6 @@ fn parse_pseudo_element(name: &str) -> Result<PseudoElement, ()> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use cssparser::Parser;
|
use cssparser::Parser;
|
||||||
use namespaces::NamespaceMap;
|
|
||||||
use stylesheets::Origin;
|
use stylesheets::Origin;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use parser::ParserContext;
|
use parser::ParserContext;
|
||||||
|
@ -655,16 +637,11 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn parse(input: &str) -> Result<Vec<Selector>, ()> {
|
fn parse(input: &str) -> Result<Vec<Selector>, ()> {
|
||||||
parse_ns(input, NamespaceMap::new())
|
parse_ns(input, &ParserContext::new(Origin::Author, &Url::parse("about:blank").unwrap()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_ns(input: &str, namespaces: NamespaceMap) -> Result<Vec<Selector>, ()> {
|
fn parse_ns(input: &str, context: &ParserContext) -> Result<Vec<Selector>, ()> {
|
||||||
let context = ParserContext {
|
parse_selector_list(context, &mut Parser::new(input))
|
||||||
stylesheet_origin: Origin::Author,
|
|
||||||
namespaces: namespaces,
|
|
||||||
base_url: &Url::parse("about:blank").unwrap(),
|
|
||||||
};
|
|
||||||
parse_selector_list(&context, &mut Parser::new(input))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn specificity(a: u32, b: u32, c: u32) -> u32 {
|
fn specificity(a: u32, b: u32, c: u32) -> u32 {
|
||||||
|
@ -728,8 +705,9 @@ mod tests {
|
||||||
})));
|
})));
|
||||||
// Default namespace does not apply to attribute selectors
|
// Default namespace does not apply to attribute selectors
|
||||||
// https://github.com/mozilla/servo/pull/1652
|
// https://github.com/mozilla/servo/pull/1652
|
||||||
let mut namespaces = NamespaceMap::new();
|
let url = Url::parse("about:blank").unwrap();
|
||||||
assert_eq!(parse_ns("[Foo]", namespaces.clone()), Ok(vec!(Selector {
|
let mut context = ParserContext::new(Origin::Author, &url);
|
||||||
|
assert_eq!(parse_ns("[Foo]", &context), Ok(vec!(Selector {
|
||||||
compound_selectors: Arc::new(CompoundSelector {
|
compound_selectors: Arc::new(CompoundSelector {
|
||||||
simple_selectors: vec!(SimpleSelector::AttrExists(AttrSelector {
|
simple_selectors: vec!(SimpleSelector::AttrExists(AttrSelector {
|
||||||
name: Atom::from_slice("Foo"),
|
name: Atom::from_slice("Foo"),
|
||||||
|
@ -743,8 +721,8 @@ mod tests {
|
||||||
})));
|
})));
|
||||||
// Default namespace does not apply to attribute selectors
|
// Default namespace does not apply to attribute selectors
|
||||||
// https://github.com/mozilla/servo/pull/1652
|
// https://github.com/mozilla/servo/pull/1652
|
||||||
namespaces.default = Some(ns!(MathML));
|
context.namespaces.default = Some(ns!(MathML));
|
||||||
assert_eq!(parse_ns("[Foo]", namespaces.clone()), Ok(vec!(Selector {
|
assert_eq!(parse_ns("[Foo]", &context), Ok(vec!(Selector {
|
||||||
compound_selectors: Arc::new(CompoundSelector {
|
compound_selectors: Arc::new(CompoundSelector {
|
||||||
simple_selectors: vec!(SimpleSelector::AttrExists(AttrSelector {
|
simple_selectors: vec!(SimpleSelector::AttrExists(AttrSelector {
|
||||||
name: Atom::from_slice("Foo"),
|
name: Atom::from_slice("Foo"),
|
||||||
|
@ -757,7 +735,7 @@ mod tests {
|
||||||
specificity: specificity(0, 1, 0),
|
specificity: specificity(0, 1, 0),
|
||||||
})));
|
})));
|
||||||
// Default namespace does apply to type selectors
|
// Default namespace does apply to type selectors
|
||||||
assert_eq!(parse_ns("e", namespaces), Ok(vec!(Selector {
|
assert_eq!(parse_ns("e", &context), Ok(vec!(Selector {
|
||||||
compound_selectors: Arc::new(CompoundSelector {
|
compound_selectors: Arc::new(CompoundSelector {
|
||||||
simple_selectors: vec!(
|
simple_selectors: vec!(
|
||||||
SimpleSelector::Namespace(ns!(MathML)),
|
SimpleSelector::Namespace(ns!(MathML)),
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use std::cell::Cell;
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -10,11 +11,10 @@ use encoding::EncodingRef;
|
||||||
|
|
||||||
use cssparser::{Parser, decode_stylesheet_bytes,
|
use cssparser::{Parser, decode_stylesheet_bytes,
|
||||||
QualifiedRuleParser, AtRuleParser, RuleListParser, AtRuleType};
|
QualifiedRuleParser, AtRuleParser, RuleListParser, AtRuleType};
|
||||||
use string_cache::Namespace;
|
use string_cache::{Atom, Namespace};
|
||||||
use selectors::{Selector, parse_selector_list};
|
use selectors::{Selector, parse_selector_list};
|
||||||
use parser::ParserContext;
|
use parser::{ParserContext, log_css_error};
|
||||||
use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
|
use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
|
||||||
use namespaces::{NamespaceMap, parse_namespace_rule};
|
|
||||||
use media_queries::{self, Device, MediaQueryList, parse_media_query_list};
|
use media_queries::{self, Device, MediaQueryList, parse_media_query_list};
|
||||||
use font_face::{FontFaceRule, Source, parse_font_face_block, iter_font_face_rules_inner};
|
use font_face::{FontFaceRule, Source, parse_font_face_block, iter_font_face_rules_inner};
|
||||||
|
|
||||||
|
@ -85,18 +85,32 @@ impl Stylesheet {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_str<'i>(css: &'i str, base_url: Url, origin: Origin) -> Stylesheet {
|
pub fn from_str<'i>(css: &'i str, base_url: Url, origin: Origin) -> Stylesheet {
|
||||||
let mut context = ParserContext {
|
let rule_parser = TopLevelRuleParser {
|
||||||
stylesheet_origin: origin,
|
context: ParserContext::new(origin, &base_url),
|
||||||
base_url: &base_url,
|
state: Cell::new(State::Start),
|
||||||
namespaces: NamespaceMap::new()
|
|
||||||
};
|
};
|
||||||
let rule_parser = MainRuleParser {
|
let mut input = Parser::new(css);
|
||||||
context: &mut context,
|
let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser);
|
||||||
state: State::Start,
|
let mut rules = Vec::new();
|
||||||
};
|
while let Some(result) = iter.next() {
|
||||||
let rules = RuleListParser::new_for_stylesheet(&mut Parser::new(css), rule_parser)
|
match result {
|
||||||
.filter_map(|result| result.ok())
|
Ok(rule) => {
|
||||||
.collect();
|
if let CSSRule::Namespace(ref prefix, ref namespace) = rule {
|
||||||
|
if let Some(prefix) = prefix.as_ref() {
|
||||||
|
iter.parser.context.namespaces.prefix_map.insert(
|
||||||
|
prefix.clone(), namespace.clone());
|
||||||
|
} else {
|
||||||
|
iter.parser.context.namespaces.default = Some(namespace.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rules.push(rule);
|
||||||
|
}
|
||||||
|
Err(range) => {
|
||||||
|
let message = format!("Invalid rule: '{}'", iter.input.slice(range));
|
||||||
|
log_css_error(iter.input, range.start, &*message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Stylesheet {
|
Stylesheet {
|
||||||
origin: origin,
|
origin: origin,
|
||||||
rules: rules,
|
rules: rules,
|
||||||
|
@ -105,24 +119,28 @@ impl Stylesheet {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn parse_nested_rules(context: &mut ParserContext, input: &mut Parser) -> Vec<CSSRule> {
|
fn parse_nested_rules(context: &ParserContext, input: &mut Parser) -> Vec<CSSRule> {
|
||||||
let parser = MainRuleParser {
|
let mut iter = RuleListParser::new_for_nested_rule(input, NestedRuleParser { context: context });
|
||||||
context: context,
|
let mut rules = Vec::new();
|
||||||
state: State::Body,
|
while let Some(result) = iter.next() {
|
||||||
};
|
match result {
|
||||||
RuleListParser::new_for_nested_rule(input, parser)
|
Ok(rule) => rules.push(rule),
|
||||||
.filter_map(|result| result.ok())
|
Err(range) => {
|
||||||
.collect()
|
let message = format!("Unsupported rule: '{}'", iter.input.slice(range));
|
||||||
|
log_css_error(iter.input, range.start, &*message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct MainRuleParser<'a, 'b: 'a> {
|
struct TopLevelRuleParser<'a> {
|
||||||
context: &'a mut ParserContext<'b>,
|
context: ParserContext<'a>,
|
||||||
state: State,
|
state: Cell<State>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Copy)]
|
||||||
#[derive(Eq, PartialEq, Ord, PartialOrd)]
|
|
||||||
enum State {
|
enum State {
|
||||||
Start = 1,
|
Start = 1,
|
||||||
Imports = 2,
|
Imports = 2,
|
||||||
|
@ -137,14 +155,17 @@ enum AtRulePrelude {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a, 'b> AtRuleParser<AtRulePrelude, CSSRule> for MainRuleParser<'a, 'b> {
|
impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
|
||||||
fn parse_prelude(&mut self, name: &str, input: &mut Parser)
|
type Prelude = AtRulePrelude;
|
||||||
|
type AtRule = CSSRule;
|
||||||
|
|
||||||
|
fn parse_prelude(&self, name: &str, input: &mut Parser)
|
||||||
-> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> {
|
-> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> {
|
||||||
match_ignore_ascii_case! { name,
|
match_ignore_ascii_case! { name,
|
||||||
"charset" => {
|
"charset" => {
|
||||||
if self.state <= State::Start {
|
if self.state.get() <= State::Start {
|
||||||
// Valid @charset rules are just ignored
|
// Valid @charset rules are just ignored
|
||||||
self.state = State::Imports;
|
self.state.set(State::Imports);
|
||||||
let charset = try!(input.expect_string()).into_owned();
|
let charset = try!(input.expect_string()).into_owned();
|
||||||
return Ok(AtRuleType::WithoutBlock(CSSRule::Charset(charset)))
|
return Ok(AtRuleType::WithoutBlock(CSSRule::Charset(charset)))
|
||||||
} else {
|
} else {
|
||||||
|
@ -152,8 +173,8 @@ impl<'a, 'b> AtRuleParser<AtRulePrelude, CSSRule> for MainRuleParser<'a, 'b> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"import" => {
|
"import" => {
|
||||||
if self.state <= State::Imports {
|
if self.state.get() <= State::Imports {
|
||||||
self.state = State::Imports;
|
self.state.set(State::Imports);
|
||||||
// TODO: support @import
|
// TODO: support @import
|
||||||
return Err(()) // "@import is not supported yet"
|
return Err(()) // "@import is not supported yet"
|
||||||
} else {
|
} else {
|
||||||
|
@ -161,10 +182,12 @@ impl<'a, 'b> AtRuleParser<AtRulePrelude, CSSRule> for MainRuleParser<'a, 'b> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"namespace" => {
|
"namespace" => {
|
||||||
if self.state <= State::Namespaces {
|
if self.state.get() <= State::Namespaces {
|
||||||
self.state = State::Namespaces;
|
self.state.set(State::Namespaces);
|
||||||
let (prefix, namespace) = try!(parse_namespace_rule(self.context, input));
|
|
||||||
return Ok(AtRuleType::WithoutBlock(CSSRule::Namespace(prefix, namespace)))
|
let prefix = input.try(|input| input.expect_ident()).ok().map(|p| p.into_owned());
|
||||||
|
let url = Namespace(Atom::from_slice(try!(input.expect_url_or_string()).as_slice()));
|
||||||
|
return Ok(AtRuleType::WithoutBlock(CSSRule::Namespace(prefix, url)))
|
||||||
} else {
|
} else {
|
||||||
return Err(()) // "@namespace must be before any rule but @charset and @import"
|
return Err(()) // "@namespace must be before any rule but @charset and @import"
|
||||||
}
|
}
|
||||||
|
@ -172,8 +195,46 @@ impl<'a, 'b> AtRuleParser<AtRulePrelude, CSSRule> for MainRuleParser<'a, 'b> {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state = State::Body;
|
self.state.set(State::Body);
|
||||||
|
AtRuleParser::parse_prelude(&NestedRuleParser { context: &self.context }, name, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> {
|
||||||
|
AtRuleParser::parse_block(&NestedRuleParser { context: &self.context }, prelude, input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<'a> QualifiedRuleParser for TopLevelRuleParser<'a> {
|
||||||
|
type Prelude = Vec<Selector>;
|
||||||
|
type QualifiedRule = CSSRule;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector>, ()> {
|
||||||
|
self.state.set(State::Body);
|
||||||
|
QualifiedRuleParser::parse_prelude(&NestedRuleParser { context: &self.context }, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn parse_block(&self, prelude: Vec<Selector>, input: &mut Parser) -> Result<CSSRule, ()> {
|
||||||
|
QualifiedRuleParser::parse_block(&NestedRuleParser { context: &self.context },
|
||||||
|
prelude, input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct NestedRuleParser<'a, 'b: 'a> {
|
||||||
|
context: &'a ParserContext<'b>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
|
||||||
|
type Prelude = AtRulePrelude;
|
||||||
|
type AtRule = CSSRule;
|
||||||
|
|
||||||
|
fn parse_prelude(&self, name: &str, input: &mut Parser)
|
||||||
|
-> Result<AtRuleType<AtRulePrelude, CSSRule>, ()> {
|
||||||
match_ignore_ascii_case! { name,
|
match_ignore_ascii_case! { name,
|
||||||
"media" => {
|
"media" => {
|
||||||
let media_queries = parse_media_query_list(input);
|
let media_queries = parse_media_query_list(input);
|
||||||
|
@ -186,7 +247,7 @@ impl<'a, 'b> AtRuleParser<AtRulePrelude, CSSRule> for MainRuleParser<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_block(&mut self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> {
|
fn parse_block(&self, prelude: AtRulePrelude, input: &mut Parser) -> Result<CSSRule, ()> {
|
||||||
match prelude {
|
match prelude {
|
||||||
AtRulePrelude::FontFace => {
|
AtRulePrelude::FontFace => {
|
||||||
parse_font_face_block(self.context, input).map(CSSRule::FontFace)
|
parse_font_face_block(self.context, input).map(CSSRule::FontFace)
|
||||||
|
@ -202,13 +263,15 @@ impl<'a, 'b> AtRuleParser<AtRulePrelude, CSSRule> for MainRuleParser<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a, 'b> QualifiedRuleParser<Vec<Selector>, CSSRule> for MainRuleParser<'a, 'b> {
|
impl<'a, 'b> QualifiedRuleParser for NestedRuleParser<'a, 'b> {
|
||||||
fn parse_prelude(&mut self, input: &mut Parser) -> Result<Vec<Selector>, ()> {
|
type Prelude = Vec<Selector>;
|
||||||
self.state = State::Body;
|
type QualifiedRule = CSSRule;
|
||||||
|
|
||||||
|
fn parse_prelude(&self, input: &mut Parser) -> Result<Vec<Selector>, ()> {
|
||||||
parse_selector_list(self.context, input)
|
parse_selector_list(self.context, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_block(&mut self, prelude: Vec<Selector>, input: &mut Parser) -> Result<CSSRule, ()> {
|
fn parse_block(&self, prelude: Vec<Selector>, input: &mut Parser) -> Result<CSSRule, ()> {
|
||||||
Ok(CSSRule::Style(StyleRule {
|
Ok(CSSRule::Style(StyleRule {
|
||||||
selectors: prelude,
|
selectors: prelude,
|
||||||
declarations: parse_property_declaration_list(self.context, input)
|
declarations: parse_property_declaration_list(self.context, input)
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
|
pub use cssparser::RGBA;
|
||||||
|
|
||||||
|
|
||||||
macro_rules! define_css_keyword_enum {
|
macro_rules! define_css_keyword_enum {
|
||||||
($name: ident: $( $css: expr => $variant: ident ),+,) => {
|
($name: ident: $( $css: expr => $variant: ident ),+,) => {
|
||||||
|
|
2
ports/cef/Cargo.lock
generated
2
ports/cef/Cargo.lock
generated
|
@ -132,7 +132,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cssparser"
|
name = "cssparser"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/servo/rust-cssparser#2a8c9f2c5f568495bae16f44b799be39b8efad39"
|
source = "git+https://github.com/servo/rust-cssparser#42714934cbe83dab349190695503a09ae23f9528"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
2
ports/gonk/Cargo.lock
generated
2
ports/gonk/Cargo.lock
generated
|
@ -103,7 +103,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cssparser"
|
name = "cssparser"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/servo/rust-cssparser#2a8c9f2c5f568495bae16f44b799be39b8efad39"
|
source = "git+https://github.com/servo/rust-cssparser#42714934cbe83dab349190695503a09ae23f9528"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encoding 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue