aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout_thread/lib.rs10
-rw-r--r--components/script/dom/node.rs4
-rw-r--r--components/script/layout_wrapper.rs19
-rw-r--r--components/style/dom.rs13
-rw-r--r--components/style/properties/data.py3
-rw-r--r--components/style/properties/helpers.mako.rs12
-rw-r--r--components/style/properties/longhand/background.mako.rs25
-rw-r--r--components/style/properties/longhand/border.mako.rs9
-rw-r--r--components/style/properties/longhand/box.mako.rs35
-rw-r--r--components/style/properties/longhand/column.mako.rs23
-rw-r--r--components/style/properties/longhand/counters.mako.rs4
-rw-r--r--components/style/properties/longhand/effects.mako.rs82
-rw-r--r--components/style/properties/longhand/font.mako.rs14
-rw-r--r--components/style/properties/longhand/inherited_box.mako.rs6
-rw-r--r--components/style/properties/longhand/inherited_table.mako.rs7
-rw-r--r--components/style/properties/longhand/inherited_text.mako.rs52
-rw-r--r--components/style/properties/longhand/list.mako.rs5
-rw-r--r--components/style/properties/longhand/outline.mako.rs9
-rw-r--r--components/style/properties/longhand/pointing.mako.rs2
-rw-r--r--components/style/properties/longhand/position.mako.rs2
-rw-r--r--components/style/properties/longhand/text.mako.rs2
-rw-r--r--components/style/properties/properties.mako.rs14
-rw-r--r--components/style/traversal.rs21
-rw-r--r--components/style/values.rs101
-rw-r--r--ports/geckolib/wrapper.rs11
-rw-r--r--tests/unit/style/lib.rs1
-rw-r--r--tests/unit/style/properties.rs25
-rw-r--r--tests/unit/style/value.rs15
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());
+}