diff options
28 files changed, 515 insertions, 11 deletions
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index fe1f82f533b..e670d214e03 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -1072,9 +1072,15 @@ impl LayoutThread { .send(ConstellationMsg::ViewportConstrained(self.id, constraints)) .unwrap(); } - // FIXME (#10104): Only dirty nodes affected by vh/vw/vmin/vmax styles. if data.document_stylesheets.iter().any(|sheet| sheet.dirty_on_viewport_size_change) { - needs_dirtying = true; + for node in node.traverse_preorder() { + if node.needs_dirty_on_viewport_size_changed() { + node.dirty_self(); + node.dirty_descendants(); + // TODO(shinglyu): We can skip the traversal if the descendants were already + // dirtied + } + } } } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 5cb2ac540c4..37495be3ba3 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -159,7 +159,9 @@ bitflags! { const SEQUENTIALLY_FOCUSABLE = 0x20, /// Whether any ancestor is a fragmentation container - const CAN_BE_FRAGMENTED = 0x40 + const CAN_BE_FRAGMENTED = 0x40, + #[doc = "Specifies whether this node needs to be dirted when viewport size changed."] + const DIRTY_ON_VIEWPORT_SIZE_CHANGE = 0x80 } } diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index ebc2da9c529..78a6b1a2f71 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -36,7 +36,7 @@ use dom::bindings::js::LayoutJS; use dom::characterdata::LayoutCharacterDataHelpers; use dom::document::{Document, LayoutDocumentHelpers}; use dom::element::{Element, LayoutElementHelpers, RawLayoutElementHelpers}; -use dom::node::{CAN_BE_FRAGMENTED, HAS_CHANGED, HAS_DIRTY_DESCENDANTS, IS_DIRTY}; +use dom::node::{CAN_BE_FRAGMENTED, HAS_CHANGED, HAS_DIRTY_DESCENDANTS, IS_DIRTY, DIRTY_ON_VIEWPORT_SIZE_CHANGE}; use dom::node::{Node, LayoutNodeHelpers}; use dom::text::Text; use gfx_traits::ByteIndex; @@ -193,6 +193,23 @@ impl<'ln> TNode for ServoLayoutNode<'ln> { self.node.set_flag(HAS_DIRTY_DESCENDANTS, value) } + fn needs_dirty_on_viewport_size_changed(&self) -> bool { + unsafe { self.node.get_flag(DIRTY_ON_VIEWPORT_SIZE_CHANGE) } + } + + unsafe fn set_dirty_on_viewport_size_changed(&self) { + self.node.set_flag(DIRTY_ON_VIEWPORT_SIZE_CHANGE, true); + } + + fn set_descendants_dirty_on_viewport_size_changed(&self) { + for ref child in self.children() { + unsafe { + child.set_dirty_on_viewport_size_changed(); + } + child.set_descendants_dirty_on_viewport_size_changed(); + } + } + fn can_be_fragmented(&self) -> bool { unsafe { self.node.get_flag(CAN_BE_FRAGMENTED) } } diff --git a/components/style/dom.rs b/components/style/dom.rs index 0e94c2c5c1d..e696a29372a 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -127,6 +127,19 @@ pub trait TNode : Sized + Copy + Clone { } } + fn needs_dirty_on_viewport_size_changed(&self) -> bool; + + unsafe fn set_dirty_on_viewport_size_changed(&self); + + fn set_descendants_dirty_on_viewport_size_changed(&self) { + for ref child in self.children() { + unsafe { + child.set_dirty_on_viewport_size_changed(); + } + child.set_descendants_dirty_on_viewport_size_changed(); + } + } + fn can_be_fragmented(&self) -> bool; unsafe fn set_can_be_fragmented(&self, value: bool); diff --git a/components/style/properties/data.py b/components/style/properties/data.py index f7fd3eec1b7..ed0466028f9 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -47,7 +47,7 @@ class Keyword(object): class Longhand(object): def __init__(self, style_struct, name, animatable=None, derived_from=None, keyword=None, predefined_type=None, custom_cascade=False, experimental=False, internal=False, - need_clone=False, need_index=False, gecko_ffi_name=None): + need_clone=False, need_index=False, gecko_ffi_name=None, depend_on_viewport_size=False): self.name = name self.keyword = keyword self.predefined_type = predefined_type @@ -59,6 +59,7 @@ class Longhand(object): self.internal = internal self.need_index = need_index self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case + self.depend_on_viewport_size = depend_on_viewport_size self.derived_from = (derived_from or "").split() # This is done like this since just a plain bool argument seemed like diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 374cd6a011e..71ce926fb23 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -51,6 +51,14 @@ % if product == "gecko" or not gecko_only: use cssparser::ToCss; use std::fmt; + use values::HasViewportPercentage; + + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + let &SpecifiedValue(ref vec) = self; + vec.iter().any(|ref x| x.has_viewport_percentage()) + } + } pub mod single_value { use cssparser::Parser; @@ -274,7 +282,9 @@ <%def name="single_keyword(name, values, **kwargs)"> <%call expr="single_keyword_computed(name, values, **kwargs)"> use values::computed::ComputedValueAsSpecified; + use values::NoViewportPercentage; impl ComputedValueAsSpecified for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} </%call> </%def> @@ -315,6 +325,8 @@ <%call expr="longhand(name, keyword=Keyword(name, values, **keyword_kwargs), **kwargs)"> use values::computed::ComputedValueAsSpecified; pub use self::computed_value::T as SpecifiedValue; + use values::NoViewportPercentage; + impl NoViewportPercentage for SpecifiedValue {} pub mod computed_value { use cssparser::ToCss; use std::fmt; diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs index 26dbf123df8..d98a60cb8c5 100644 --- a/components/style/properties/longhand/background.mako.rs +++ b/components/style/properties/longhand/background.mako.rs @@ -15,6 +15,7 @@ ${helpers.predefined_type("background-color", "CSSColor", use std::fmt; use values::specified::Image; use values::LocalToCss; + use values::NoViewportPercentage; pub mod computed_value { use values::computed; @@ -34,6 +35,8 @@ ${helpers.predefined_type("background-color", "CSSColor", } } + impl NoViewportPercentage for SpecifiedValue {} + #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(pub Option<Image>); @@ -76,6 +79,7 @@ ${helpers.predefined_type("background-color", "CSSColor", use cssparser::ToCss; use std::fmt; use values::LocalToCss; + use values::HasViewportPercentage; pub mod computed_value { use values::computed::LengthOrPercentage; @@ -88,6 +92,12 @@ ${helpers.predefined_type("background-color", "CSSColor", } } + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + return self.horizontal.has_viewport_percentage() || self.vertical.has_viewport_percentage(); + } + } + #[derive(Debug, Clone, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue { @@ -207,6 +217,7 @@ ${helpers.single_keyword("background-origin", use cssparser::{ToCss, Token}; use std::ascii::AsciiExt; use std::fmt; + use values::HasViewportPercentage; pub mod computed_value { use values::computed::LengthOrPercentageOrAuto; @@ -237,6 +248,12 @@ ${helpers.single_keyword("background-origin", } } + impl HasViewportPercentage for SpecifiedExplicitSize { + fn has_viewport_percentage(&self) -> bool { + return self.width.has_viewport_percentage() || self.height.has_viewport_percentage(); + } + } + #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedExplicitSize { @@ -260,6 +277,14 @@ ${helpers.single_keyword("background-origin", } } + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + match *self { + SpecifiedValue::Explicit(ref explicit_size) => explicit_size.has_viewport_percentage(), + _ => false + } + } + } #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index 57bd1880233..ed8e09377d9 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -26,6 +26,7 @@ use app_units::Au; use cssparser::ToCss; use std::fmt; + use values::HasViewportPercentage; impl ToCss for SpecifiedValue { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { @@ -41,6 +42,14 @@ #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(pub specified::Length); + + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + let &SpecifiedValue(length) = self; + length.has_viewport_percentage() + } + } + pub mod computed_value { use app_units::Au; pub type T = Au; diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 3a02b6c656d..533a3a95530 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -28,6 +28,9 @@ pub use self::computed_value::T as SpecifiedValue; use values::computed::{Context, ComputedValueAsSpecified}; + use values::NoViewportPercentage; + impl NoViewportPercentage for SpecifiedValue {} + pub mod computed_value { #[allow(non_camel_case_types)] #[derive(Clone, Eq, PartialEq, Copy, Hash, RustcEncodable, Debug)] @@ -94,7 +97,10 @@ ${helpers.single_keyword("position", "static absolute relative fixed", <%helpers:single_keyword_computed name="float" values="none left right" animatable="False" - need_clone="True"> + need_clone="True" + gecko_ffi_name="mFloat"> + use values::NoViewportPercentage; + impl NoViewportPercentage for SpecifiedValue {} impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -146,6 +152,16 @@ ${helpers.single_keyword("clear", "none left right both", extra_gecko_values="middle-with-baseline") %> <% vertical_align_keywords = vertical_align.keyword.values_for(product) %> + use values::HasViewportPercentage; + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + match *self { + SpecifiedValue::LengthOrPercentage(length) => length.has_viewport_percentage(), + _ => false + } + } + } + #[allow(non_camel_case_types)] #[derive(Debug, Clone, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -252,6 +268,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", pub use self::computed_value::T as SpecifiedValue; + use values::NoViewportPercentage; + impl NoViewportPercentage for SpecifiedValue {} + impl ToCss for SpecifiedValue { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { self.0.to_css(dest) @@ -291,6 +310,8 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", pub use self::computed_value::T as SpecifiedValue; pub use values::specified::Time as SingleSpecifiedValue; + use values::NoViewportPercentage; + impl NoViewportPercentage for SpecifiedValue {} pub mod computed_value { use cssparser::ToCss; @@ -469,6 +490,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", } } + use values::NoViewportPercentage; + impl NoViewportPercentage for SpecifiedValue {} + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -592,6 +616,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", Ok(SpecifiedValue(try!(input.parse_comma_separated(SingleSpecifiedValue::parse)))) } + use values::NoViewportPercentage; + impl NoViewportPercentage for SpecifiedValue {} + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -615,6 +642,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", need_index="True" animatable="False"> use values::computed::ComputedValueAsSpecified; + use values::NoViewportPercentage; pub mod computed_value { use cssparser::ToCss; @@ -646,6 +674,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", } pub use self::computed_value::T as SpecifiedValue; + impl NoViewportPercentage for SpecifiedValue {} pub use string_cache::Atom as SingleSpecifiedValue; #[inline] @@ -696,6 +725,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", need_index="True" animatable="False"> use values::computed::ComputedValueAsSpecified; + use values::NoViewportPercentage; pub mod computed_value { use cssparser::ToCss; @@ -742,6 +772,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto", pub use self::computed_value::AnimationIterationCount; pub use self::computed_value::AnimationIterationCount as SingleSpecifiedValue; pub use self::computed_value::T as SpecifiedValue; + impl NoViewportPercentage for SpecifiedValue {} #[inline] pub fn get_initial_single_value() -> AnimationIterationCount { @@ -885,6 +916,7 @@ ${helpers.single_keyword("-moz-appearance", use std::fmt::{self, Write}; use url::Url; use values::computed::ComputedValueAsSpecified; + use values::NoViewportPercentage; #[derive(PartialEq, Clone, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -902,6 +934,7 @@ ${helpers.single_keyword("-moz-appearance", } impl ComputedValueAsSpecified for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} impl ToCss for SpecifiedValue { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { diff --git a/components/style/properties/longhand/column.mako.rs b/components/style/properties/longhand/column.mako.rs index 91e1fc8fc3a..f69901571d6 100644 --- a/components/style/properties/longhand/column.mako.rs +++ b/components/style/properties/longhand/column.mako.rs @@ -11,6 +11,16 @@ use cssparser::ToCss; use std::fmt; use values::LocalToCss; + use values::HasViewportPercentage; + + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + match *self { + SpecifiedValue::Specified(length) => length.has_viewport_percentage(), + _ => false + } + } + } #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -75,6 +85,9 @@ <%helpers:longhand name="column-count" experimental="True" animatable="False"> use cssparser::ToCss; use std::fmt; + use values::NoViewportPercentage; + + impl NoViewportPercentage for SpecifiedValue {} #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -144,6 +157,16 @@ use cssparser::ToCss; use std::fmt; use values::LocalToCss; + use values::HasViewportPercentage; + + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + match *self { + SpecifiedValue::Specified(length) => length.has_viewport_percentage(), + _ => false + } + } + } #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] diff --git a/components/style/properties/longhand/counters.mako.rs b/components/style/properties/longhand/counters.mako.rs index 93fdb4bdc2c..c661c7838be 100644 --- a/components/style/properties/longhand/counters.mako.rs +++ b/components/style/properties/longhand/counters.mako.rs @@ -10,6 +10,7 @@ use cssparser::Token; use std::ascii::AsciiExt; use values::computed::ComputedValueAsSpecified; + use values::NoViewportPercentage; use super::list_style_type; @@ -17,6 +18,7 @@ pub use self::computed_value::ContentItem; impl ComputedValueAsSpecified for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} pub mod computed_value { use super::super::list_style_type; @@ -174,6 +176,7 @@ <%helpers:longhand name="counter-increment" animatable="False"> use std::fmt; use super::content; + use values::NoViewportPercentage; use values::computed::ComputedValueAsSpecified; use cssparser::{ToCss, Token, serialize_identifier}; @@ -193,6 +196,7 @@ } impl ComputedValueAsSpecified for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} impl ToCss for SpecifiedValue { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { diff --git a/components/style/properties/longhand/effects.mako.rs b/components/style/properties/longhand/effects.mako.rs index fa747076da1..77737e9ee83 100644 --- a/components/style/properties/longhand/effects.mako.rs +++ b/components/style/properties/longhand/effects.mako.rs @@ -16,6 +16,7 @@ ${helpers.predefined_type("opacity", use cssparser::{self, ToCss}; use std::fmt; use values::LocalToCss; + use values::HasViewportPercentage; #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -28,6 +29,15 @@ ${helpers.predefined_type("opacity", pub inset: bool, } + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + self.offset_x.has_viewport_percentage() || + self.offset_y.has_viewport_percentage() || + self.blur_radius.has_viewport_percentage() || + self.spread_radius.has_viewport_percentage() + } + } + impl ToCss for SpecifiedValue { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { if self.inset { @@ -169,6 +179,7 @@ ${helpers.predefined_type("opacity", use cssparser::ToCss; use std::fmt; use values::LocalToCss; + use values::HasViewportPercentage; // NB: `top` and `left` are 0 if `auto` per CSS 2.1 11.1.2. @@ -219,6 +230,15 @@ ${helpers.predefined_type("opacity", } } + impl HasViewportPercentage for SpecifiedClipRect { + fn has_viewport_percentage(&self) -> bool { + self.top.has_viewport_percentage() || + self.right.map_or(false, |x| x.has_viewport_percentage()) || + self.bottom.map_or(false, |x| x.has_viewport_percentage()) || + self.left.has_viewport_percentage() + } + } + #[derive(Clone, Debug, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedClipRect { @@ -228,6 +248,13 @@ ${helpers.predefined_type("opacity", pub left: specified::Length, } + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + let &SpecifiedValue(clip) = self; + clip.map_or(false, |x| x.has_viewport_percentage()) + } + } + #[derive(Clone, Debug, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(Option<SpecifiedClipRect>); @@ -343,12 +370,29 @@ ${helpers.predefined_type("opacity", use std::fmt; use values::LocalToCss; use values::CSSFloat; + use values::HasViewportPercentage; use values::specified::{Angle, Length}; + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + let &SpecifiedValue(ref vec) = self; + vec.iter().any(|ref x| x.has_viewport_percentage()) + } + } + #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(Vec<SpecifiedFilter>); + impl HasViewportPercentage for SpecifiedFilter { + fn has_viewport_percentage(&self) -> bool { + match *self { + SpecifiedFilter::Blur(length) => length.has_viewport_percentage(), + _ => false + } + } + } + // TODO(pcwalton): `drop-shadow` #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -576,6 +620,7 @@ ${helpers.predefined_type("opacity", <%helpers:longhand name="transform" animatable="True"> use app_units::Au; use values::CSSFloat; + use values::HasViewportPercentage; use cssparser::ToCss; use std::fmt; @@ -684,6 +729,20 @@ ${helpers.predefined_type("opacity", } } + impl HasViewportPercentage for SpecifiedOperation { + fn has_viewport_percentage(&self) -> bool { + match *self { + SpecifiedOperation::Translate(_, l1, l2, l3) => { + l1.has_viewport_percentage() || + l2.has_viewport_percentage() || + l3.has_viewport_percentage() + }, + SpecifiedOperation::Perspective(length) => length.has_viewport_percentage(), + _ => false + } + } + } + impl ToCss for SpecifiedOperation { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -743,6 +802,13 @@ ${helpers.predefined_type("opacity", } } + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + let &SpecifiedValue(ref specified_ops) = self; + specified_ops.iter().any(|ref x| x.has_viewport_percentage()) + } + } + #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(Vec<SpecifiedOperation>); @@ -1133,6 +1199,7 @@ ${helpers.single_keyword("transform-style", <%helpers:longhand name="transform-origin" animatable="True"> use app_units::Au; use values::LocalToCss; + use values::HasViewportPercentage; use values::specified::{Length, LengthOrPercentage, Percentage}; use cssparser::ToCss; @@ -1150,6 +1217,14 @@ ${helpers.single_keyword("transform-style", } } + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + self.horizontal.has_viewport_percentage() || + self.vertical.has_viewport_percentage() || + self.depth.has_viewport_percentage() + } + } + #[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue { @@ -1217,6 +1292,7 @@ ${helpers.predefined_type("perspective", // FIXME: This prop should be animatable <%helpers:longhand name="perspective-origin" animatable="False"> + use values::HasViewportPercentage; use values::specified::{LengthOrPercentage, Percentage}; use cssparser::ToCss; @@ -1241,6 +1317,12 @@ ${helpers.predefined_type("perspective", } } + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + self.horizontal.has_viewport_percentage() || self.vertical.has_viewport_percentage() + } + } + #[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue { diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 601097a604c..34ea5c0c546 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -10,10 +10,13 @@ additional_methods=[Method("compute_font_hash", is_mut=True)]) %> <%helpers:longhand name="font-family" animatable="False"> use self::computed_value::FontFamily; + use values::NoViewportPercentage; use values::computed::ComputedValueAsSpecified; pub use self::computed_value::T as SpecifiedValue; impl ComputedValueAsSpecified for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} + pub mod computed_value { use cssparser::ToCss; use std::fmt; @@ -128,6 +131,9 @@ ${helpers.single_keyword("font-variant", <%helpers:longhand name="font-weight" need_clone="True" animatable="True"> use cssparser::ToCss; use std::fmt; + use values::NoViewportPercentage; + + impl NoViewportPercentage for SpecifiedValue {} #[derive(Debug, Clone, PartialEq, Eq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -251,6 +257,7 @@ ${helpers.single_keyword("font-variant", use cssparser::ToCss; use std::fmt; use values::FONT_MEDIUM_PX; + use values::HasViewportPercentage; use values::specified::{LengthOrPercentage, Length, Percentage}; impl ToCss for SpecifiedValue { @@ -259,6 +266,13 @@ ${helpers.single_keyword("font-variant", } } + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + let &SpecifiedValue(length) = self; + return length.has_viewport_percentage() + } + } + #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(pub specified::LengthOrPercentage); diff --git a/components/style/properties/longhand/inherited_box.mako.rs b/components/style/properties/longhand/inherited_box.mako.rs index 65fac030ec2..0083f350621 100644 --- a/components/style/properties/longhand/inherited_box.mako.rs +++ b/components/style/properties/longhand/inherited_box.mako.rs @@ -64,6 +64,9 @@ ${helpers.single_keyword("color-adjust", } } + use values::NoViewportPercentage; + impl NoViewportPercentage for SpecifiedValue {} + pub type SpecifiedValue = computed_value::T; #[inline] @@ -104,6 +107,9 @@ ${helpers.single_keyword("color-adjust", use cssparser::ToCss; use std::fmt; use values::computed::ComputedValueAsSpecified; + use values::NoViewportPercentage; + + impl NoViewportPercentage for SpecifiedValue {} #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] diff --git a/components/style/properties/longhand/inherited_table.mako.rs b/components/style/properties/longhand/inherited_table.mako.rs index dd9b468ee1f..55e5c337ab9 100644 --- a/components/style/properties/longhand/inherited_table.mako.rs +++ b/components/style/properties/longhand/inherited_table.mako.rs @@ -19,6 +19,7 @@ ${helpers.single_keyword("caption-side", "top bottom", <%helpers:longhand name="border-spacing" animatable="False"> use app_units::Au; use values::LocalToCss; + use values::HasViewportPercentage; use cssparser::ToCss; use std::fmt; @@ -34,6 +35,12 @@ ${helpers.single_keyword("caption-side", "top bottom", } } + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + return self.horizontal.has_viewport_percentage() || self.vertical.has_viewport_percentage() + } + } + #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue { diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index d902b62739a..dc3eb51ab6e 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -11,6 +11,16 @@ use std::fmt; use values::LocalToCss; use values::CSSFloat; + use values::HasViewportPercentage; + + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + match *self { + SpecifiedValue::LengthOrPercentage(length) => length.has_viewport_percentage(), + _ => false + } + } + } #[derive(Debug, Clone, PartialEq, Copy)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -123,7 +133,9 @@ <%helpers:longhand name="text-align" animatable="False"> pub use self::computed_value::T as SpecifiedValue; use values::computed::ComputedValueAsSpecified; + use values::NoViewportPercentage; impl ComputedValueAsSpecified for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} pub mod computed_value { macro_rules! define_text_align { ( $( $name: ident ( $string: expr ) => $discriminant: expr, )+ ) => { @@ -184,6 +196,16 @@ use cssparser::ToCss; use std::fmt; use values::LocalToCss; + use values::HasViewportPercentage; + + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + match *self { + SpecifiedValue::Specified(length) => length.has_viewport_percentage(), + _ => false + } + } + } #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -248,6 +270,16 @@ use cssparser::ToCss; use std::fmt; use values::LocalToCss; + use values::HasViewportPercentage; + + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + match *self { + SpecifiedValue::Specified(length) => length.has_viewport_percentage(), + _ => false + } + } + } #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -340,10 +372,12 @@ ${helpers.single_keyword("text-justify", use cssparser::{RGBA, ToCss}; use std::fmt; + use values:: NoViewportPercentage; use values::computed::ComputedValueAsSpecified; use properties::style_struct_traits::{Box, Color, Text}; impl ComputedValueAsSpecified for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} #[derive(Clone, PartialEq, Copy, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -422,7 +456,9 @@ ${helpers.single_keyword("text-justify", gecko_constant_prefix="NS_STYLE_WHITESPACE" animatable="False"> use values::computed::ComputedValueAsSpecified; + use values::NoViewportPercentage; impl ComputedValueAsSpecified for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} impl SpecifiedValue { pub fn allow_wrap(&self) -> bool { @@ -461,11 +497,27 @@ ${helpers.single_keyword("text-justify", use cssparser::{self, ToCss}; use std::fmt; use values::LocalToCss; + use values::HasViewportPercentage; + + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + let &SpecifiedValue(ref vec) = self; + vec.iter().any(|ref x| x .has_viewport_percentage()) + } + } #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(Vec<SpecifiedTextShadow>); + impl HasViewportPercentage for SpecifiedTextShadow { + fn has_viewport_percentage(&self) -> bool { + self.offset_x.has_viewport_percentage() || + self.offset_y.has_viewport_percentage() || + self.blur_radius.has_viewport_percentage() + } + } + #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedTextShadow { diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs index c5d5c6be5b0..cc72d6d7782 100644 --- a/components/style/properties/longhand/list.mako.rs +++ b/components/style/properties/longhand/list.mako.rs @@ -31,6 +31,9 @@ ${helpers.single_keyword("list-style-type", """ use std::fmt; use url::Url; use values::LocalToCss; + use values::NoViewportPercentage; + + impl NoViewportPercentage for SpecifiedValue {} #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -96,6 +99,7 @@ ${helpers.single_keyword("list-style-type", """ <%helpers:longhand name="quotes" animatable="False"> use std::borrow::Cow; use std::fmt; + use values::NoViewportPercentage; use values::computed::ComputedValueAsSpecified; use cssparser::{ToCss, Token}; @@ -109,6 +113,7 @@ ${helpers.single_keyword("list-style-type", """ } impl ComputedValueAsSpecified for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} impl ToCss for SpecifiedValue { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { diff --git a/components/style/properties/longhand/outline.mako.rs b/components/style/properties/longhand/outline.mako.rs index 0869df7a657..93ba184064d 100644 --- a/components/style/properties/longhand/outline.mako.rs +++ b/components/style/properties/longhand/outline.mako.rs @@ -32,6 +32,7 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr use cssparser::ToCss; use std::fmt; use values::LocalToCss; + use values::HasViewportPercentage; impl ToCss for SpecifiedValue { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { @@ -42,6 +43,14 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> { specified::parse_border_width(input).map(SpecifiedValue) } + + impl HasViewportPercentage for SpecifiedValue { + fn has_viewport_percentage(&self) -> bool { + let &SpecifiedValue(length) = self; + length.has_viewport_percentage() + } + } + #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct SpecifiedValue(pub specified::Length); diff --git a/components/style/properties/longhand/pointing.mako.rs b/components/style/properties/longhand/pointing.mako.rs index 2394e2f3bee..3bdb71d2392 100644 --- a/components/style/properties/longhand/pointing.mako.rs +++ b/components/style/properties/longhand/pointing.mako.rs @@ -8,9 +8,11 @@ <%helpers:longhand name="cursor" animatable="False"> pub use self::computed_value::T as SpecifiedValue; + use values::NoViewportPercentage; use values::computed::ComputedValueAsSpecified; impl ComputedValueAsSpecified for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} pub mod computed_value { use cssparser::ToCss; diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index 3ad07a9c2c3..b75f4cd2d08 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -13,9 +13,11 @@ % endfor <%helpers:longhand name="z-index" animatable="True"> + use values::NoViewportPercentage; use values::computed::ComputedValueAsSpecified; impl ComputedValueAsSpecified for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} pub type SpecifiedValue = computed_value::T; pub mod computed_value { use cssparser::ToCss; diff --git a/components/style/properties/longhand/text.mako.rs b/components/style/properties/longhand/text.mako.rs index 50a4ef3476c..259288c4c62 100644 --- a/components/style/properties/longhand/text.mako.rs +++ b/components/style/properties/longhand/text.mako.rs @@ -25,8 +25,10 @@ ${helpers.single_keyword("unicode-bidi", use cssparser::ToCss; use std::fmt; use values::computed::ComputedValueAsSpecified; + use values::NoViewportPercentage; impl ComputedValueAsSpecified for SpecifiedValue {} + impl NoViewportPercentage for SpecifiedValue {} #[derive(PartialEq, Eq, Copy, Clone, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index e4da7a18c6d..7b8141eccde 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -32,6 +32,7 @@ use parser::{ParserContext, ParserContextExtraData, log_css_error}; use selectors::matching::DeclarationBlock; use stylesheets::Origin; use values::LocalToCss; +use values::HasViewportPercentage; use values::computed::{self, TContext, ToComputedValue}; use values::specified::BorderStyle; @@ -825,6 +826,19 @@ impl ToCss for PropertyDeclaration { } } +impl HasViewportPercentage for PropertyDeclaration { + fn has_viewport_percentage(&self) -> bool { + match *self { + % for property in data.longhands: + PropertyDeclaration::${property.camel_case}(DeclaredValue::Value(ref val)) => { + val.has_viewport_percentage() + }, + % endfor + _ => false + } + } +} + impl PropertyDeclaration { pub fn name(&self) -> PropertyDeclarationName { match *self { diff --git a/components/style/traversal.rs b/components/style/traversal.rs index 91ba161b3f8..7b10292e624 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -5,7 +5,7 @@ //! Traversing the DOM tree; the bloom filter. use context::{SharedStyleContext, StyleContext}; -use dom::{OpaqueNode, TNode, TRestyleDamage, UnsafeNode}; +use dom::{OpaqueNode, TElement, TNode, TRestyleDamage, UnsafeNode}; use matching::{ApplicableDeclarations, ElementMatchMethods, MatchMethods, StyleSharingResult}; use selector_impl::SelectorImplExt; use selectors::Element; @@ -13,6 +13,7 @@ use selectors::bloom::BloomFilter; use std::cell::RefCell; use tid::tid; use util::opts; +use values::HasViewportPercentage; /// Every time we do another layout, the old bloom filters are invalid. This is /// detected by ticking a generation number every layout. @@ -244,5 +245,23 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C, // NB: flow construction updates the bloom filter on the way up. put_thread_local_bloom_filter(bf, &unsafe_layout_node, context.shared_context()); + + // Mark the node as DIRTY_ON_VIEWPORT_SIZE_CHANGE is it uses viewport percentage units. + match node.as_element() { + Some(element) => { + match *element.style_attribute() { + Some(ref property_declaration_block) => { + if property_declaration_block.declarations().any(|d| d.0.has_viewport_percentage()) { + unsafe { + node.set_dirty_on_viewport_size_changed(); + } + node.set_descendants_dirty_on_viewport_size_changed(); + } + }, + None => {} + } + }, + None => {} + } } diff --git a/components/style/values.rs b/components/style/values.rs index 007426be88f..07ab39cbfc6 100644 --- a/components/style/values.rs +++ b/components/style/values.rs @@ -82,6 +82,17 @@ pub type CSSFloat = f32; pub const FONT_MEDIUM_PX: i32 = 16; +pub trait HasViewportPercentage { + fn has_viewport_percentage(&self) -> bool; +} + +pub trait NoViewportPercentage {} + +impl<T> HasViewportPercentage for T where T: NoViewportPercentage { + fn has_viewport_percentage(&self) -> bool { + false + } +} pub mod specified { use app_units::Au; @@ -94,11 +105,12 @@ pub mod specified { use std::fmt; use std::ops::Mul; use style_traits::values::specified::AllowedNumericType; - use super::LocalToCss; use super::computed::{TContext, ToComputedValue}; - use super::{CSSFloat, FONT_MEDIUM_PX}; + use super::{CSSFloat, FONT_MEDIUM_PX, HasViewportPercentage, LocalToCss, NoViewportPercentage}; use url::Url; + impl NoViewportPercentage for i32 {} // For PropertyDeclaration::Order + #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct CSSColor { @@ -120,6 +132,8 @@ pub mod specified { } } + impl NoViewportPercentage for CSSColor {} + impl ToCss for CSSColor { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match self.authored { @@ -136,6 +150,8 @@ pub mod specified { pub authored: Option<String>, } + impl NoViewportPercentage for CSSRGBA {} + impl ToCss for CSSRGBA { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match self.authored { @@ -192,6 +208,12 @@ pub mod specified { Vmax(CSSFloat) } + impl HasViewportPercentage for ViewportPercentageLength { + fn has_viewport_percentage(&self) -> bool { + true + } + } + impl ToCss for ViewportPercentageLength { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -257,6 +279,15 @@ pub mod specified { Calc(CalcLengthOrPercentage), } + impl HasViewportPercentage for Length { + fn has_viewport_percentage(&self) -> bool { + match *self { + Length::ViewportPercentage(_) => true, + _ => false + } + } + } + impl ToCss for Length { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -875,6 +906,15 @@ pub mod specified { Calc(CalcLengthOrPercentage), } + impl HasViewportPercentage for LengthOrPercentage { + fn has_viewport_percentage(&self) -> bool { + match *self { + LengthOrPercentage::Length(length) => length.has_viewport_percentage(), + _ => false + } + } + } + impl ToCss for LengthOrPercentage { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -925,6 +965,15 @@ pub mod specified { Calc(CalcLengthOrPercentage), } + impl HasViewportPercentage for LengthOrPercentageOrAuto { + fn has_viewport_percentage(&self) -> bool { + match *self { + LengthOrPercentageOrAuto::Length(length) => length.has_viewport_percentage(), + _ => false + } + } + } + impl ToCss for LengthOrPercentageOrAuto { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -975,6 +1024,15 @@ pub mod specified { None, } + impl HasViewportPercentage for LengthOrPercentageOrNone { + fn has_viewport_percentage(&self) -> bool { + match *self { + LengthOrPercentageOrNone::Length(length) => length.has_viewport_percentage(), + _ => false + } + } + } + impl ToCss for LengthOrPercentageOrNone { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -1022,6 +1080,15 @@ pub mod specified { None, } + impl HasViewportPercentage for LengthOrNone { + fn has_viewport_percentage(&self) -> bool { + match *self { + LengthOrNone::Length(length) => length.has_viewport_percentage(), + _ => false + } + } + } + impl ToCss for LengthOrNone { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -1066,6 +1133,15 @@ pub mod specified { Content } + impl HasViewportPercentage for LengthOrPercentageOrAutoOrContent { + fn has_viewport_percentage(&self) -> bool { + match *self { + LengthOrPercentageOrAutoOrContent::Length(length) => length.has_viewport_percentage(), + _ => false + } + } + } + impl ToCss for LengthOrPercentageOrAutoOrContent { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { match *self { @@ -1105,6 +1181,8 @@ pub mod specified { #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct BorderRadiusSize(pub Size2D<LengthOrPercentage>); + impl NoViewportPercentage for BorderRadiusSize {} + impl BorderRadiusSize { pub fn zero() -> BorderRadiusSize { let zero = LengthOrPercentage::Length(Length::Absolute(Au(0))); @@ -1145,6 +1223,16 @@ pub mod specified { Top, Bottom, } + + impl HasViewportPercentage for PositionComponent { + fn has_viewport_percentage(&self) -> bool { + match *self { + PositionComponent::LengthOrPercentage(length) => length.has_viewport_percentage(), + _ => false + } + } + } + impl PositionComponent { pub fn parse(input: &mut Parser) -> Result<PositionComponent, ()> { input.try(LengthOrPercentage::parse) @@ -1433,6 +1521,8 @@ pub mod specified { "outset" => outset = 2, } + impl NoViewportPercentage for BorderStyle {} + impl BorderStyle { pub fn none_or_hidden(&self) -> bool { matches!(*self, BorderStyle::none | BorderStyle::hidden) @@ -1494,6 +1584,8 @@ pub mod specified { #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Number(pub CSSFloat); + impl NoViewportPercentage for Number {} + impl Number { pub fn parse(input: &mut Parser) -> Result<Number, ()> { parse_number(input).map(Number) @@ -1532,6 +1624,8 @@ pub mod specified { #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct Opacity(pub CSSFloat); + impl NoViewportPercentage for Opacity {} + impl Opacity { pub fn parse(input: &mut Parser) -> Result<Opacity, ()> { parse_number(input).map(Opacity) @@ -1926,6 +2020,7 @@ pub mod computed { Auto, Content } + impl fmt::Debug for LengthOrPercentageOrAutoOrContent { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -1984,6 +2079,7 @@ pub mod computed { Calc(CalcLengthOrPercentage), None, } + impl fmt::Debug for LengthOrPercentageOrNone { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -2035,6 +2131,7 @@ pub mod computed { Length(Au), None, } + impl fmt::Debug for LengthOrNone { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs index 0dbba6ceca1..a61b8715779 100644 --- a/ports/geckolib/wrapper.rs +++ b/ports/geckolib/wrapper.rs @@ -284,6 +284,17 @@ impl<'ln> TNode for GeckoNode<'ln> { Gecko_GetNextSibling(self.node).as_ref().map(|n| GeckoNode::from_ref(n)) } } + + fn needs_dirty_on_viewport_size_changed(&self) -> bool { + // Gecko's node doesn't have the DIRTY_ON_VIEWPORT_SIZE_CHANGE flag, + // so we force them to be dirtied on viewport size change, regardless if + // they use viewport percentage size or not. + // TODO(shinglyu): implement this in Gecko: https://github.com/servo/servo/pull/11890 + true + } + + // TODO(shinglyu): implement this in Gecko: https://github.com/servo/servo/pull/11890 + unsafe fn set_dirty_on_viewport_size_changed(&self) {} } #[derive(Clone, Copy)] diff --git a/tests/unit/style/lib.rs b/tests/unit/style/lib.rs index 803dd7ce05e..1437daa999f 100644 --- a/tests/unit/style/lib.rs +++ b/tests/unit/style/lib.rs @@ -24,6 +24,7 @@ mod media_queries; mod properties; mod str; mod stylesheets; +mod value; mod viewport; mod writing_modes { diff --git a/tests/unit/style/properties.rs b/tests/unit/style/properties.rs index 3e8ef23a108..2ecae8cc940 100644 --- a/tests/unit/style/properties.rs +++ b/tests/unit/style/properties.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use app_units::Au; use cssparser::ToCss; use rustc_serialize::json::Json; use std::env; @@ -10,8 +11,10 @@ use std::path::Path; use std::process::Command; use std::sync::Arc; use style::computed_values::display::T::inline_block; -use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, DeclaredValue}; -use style::values::specified::{Length, LengthOrPercentageOrAuto, LengthOrPercentage}; +use style::properties::longhands::border_top_width; +use style::properties::{DeclaredValue, PropertyDeclaration, PropertyDeclarationBlock}; +use style::values::HasViewportPercentage; +use style::values::specified::{Length, LengthOrPercentageOrAuto, LengthOrPercentage, ViewportPercentageLength}; #[test] fn properties_list_json() { @@ -91,3 +94,21 @@ fn property_declaration_block_should_serialize_correctly() { "width: 70px; min-height: 20px; display: inline-block; height: 20px !important;" ); } + +#[test] +fn has_viewport_percentage_for_specified_value() { + //TODO: test all specified value with a HasViewportPercentage impl + let pvw = PropertyDeclaration::BorderTopWidth( + DeclaredValue::Value(border_top_width::SpecifiedValue( + Length::ViewportPercentage(ViewportPercentageLength::Vw(100.)) + )) + ); + assert!(pvw.has_viewport_percentage()); + + let pabs = PropertyDeclaration::BorderTopWidth( + DeclaredValue::Value(border_top_width::SpecifiedValue( + Length::Absolute(Au(100)) + )) + ); + assert!(!pabs.has_viewport_percentage()); +} diff --git a/tests/unit/style/value.rs b/tests/unit/style/value.rs new file mode 100644 index 00000000000..aff4b83c783 --- /dev/null +++ b/tests/unit/style/value.rs @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use app_units::Au; +use style::values::HasViewportPercentage; +use style::values::specified::{ViewportPercentageLength, Length}; + +#[test] +fn length_has_viewport_percentage() { + let l = Length::ViewportPercentage(ViewportPercentageLength::Vw(100.)); + assert!(l.has_viewport_percentage()); + let l = Length::Absolute(Au(100)); + assert!(!l.has_viewport_percentage()); +} |