aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-02-09 15:51:29 -0800
committerGitHub <noreply@github.com>2017-02-09 15:51:29 -0800
commite985ad54229083e5e76b2862cec57ce4fef4433c (patch)
tree151eeb17007f252c278aaa13e38deba3af5bee9d
parentce7827eadfcceb37e779846926c2b2f72c08dd72 (diff)
parent779d93669855c787bde3a66e0bdf06aec27a9004 (diff)
downloadservo-e985ad54229083e5e76b2862cec57ce4fef4433c.tar.gz
servo-e985ad54229083e5e76b2862cec57ce4fef4433c.zip
Auto merge of #15463 - Manishearth:buncha-props, r=mbrubeck
stylo: Implement a bunch of properties r? @mbrubeck or @heycam <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15463) <!-- Reviewable:end -->
-rw-r--r--components/layout/display_list_builder.rs5
-rw-r--r--components/style/gecko_bindings/sugar/ns_t_array.rs9
-rw-r--r--components/style/properties/gecko.mako.rs141
-rw-r--r--components/style/properties/helpers.mako.rs27
-rw-r--r--components/style/properties/helpers/animated_properties.mako.rs23
-rw-r--r--components/style/properties/longhand/background.mako.rs6
-rw-r--r--components/style/properties/longhand/border.mako.rs4
-rw-r--r--components/style/properties/longhand/box.mako.rs19
-rw-r--r--components/style/properties/longhand/effects.mako.rs218
-rw-r--r--components/style/properties/longhand/inherited_text.mako.rs12
-rw-r--r--components/style/properties/longhand/list.mako.rs8
-rw-r--r--components/style/properties/longhand/outline.mako.rs2
-rw-r--r--components/style/properties/longhand/position.mako.rs8
-rw-r--r--components/style/properties/longhand/ui.mako.rs6
-rw-r--r--components/style/properties/longhand/xul.mako.rs7
-rw-r--r--components/style/properties/properties.mako.rs6
-rw-r--r--components/style/values/computed/mod.rs57
-rw-r--r--components/style/values/computed/position.rs10
-rw-r--r--components/style/values/specified/length.rs2
-rw-r--r--components/style/values/specified/mod.rs127
20 files changed, 451 insertions, 246 deletions
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 1285d5cef7a..4dc72f20301 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -1176,10 +1176,11 @@ impl FragmentDisplayListBuilding for Fragment {
fn adjust_clip_for_style(&self,
parent_clip: &mut ClippingRegion,
stacking_relative_border_box: &Rect<Au>) {
+ use style::values::Either;
// Account for `clip` per CSS 2.1 § 11.1.2.
let style_clip_rect = match (self.style().get_box().position,
- self.style().get_effects().clip.0) {
- (position::T::absolute, Some(style_clip_rect)) => style_clip_rect,
+ self.style().get_effects().clip) {
+ (position::T::absolute, Either::First(style_clip_rect)) => style_clip_rect,
_ => return,
};
diff --git a/components/style/gecko_bindings/sugar/ns_t_array.rs b/components/style/gecko_bindings/sugar/ns_t_array.rs
index 5d9c005f0e3..6bc389702f5 100644
--- a/components/style/gecko_bindings/sugar/ns_t_array.rs
+++ b/components/style/gecko_bindings/sugar/ns_t_array.rs
@@ -93,4 +93,13 @@ impl<T> nsTArray<T> {
let mut header = self.header_mut();
header.mLength = len;
}
+
+ /// Resizes an array containing only POD elements
+ ///
+ /// This will not leak since it only works on POD types (and thus doesn't assert)
+ pub unsafe fn set_len_pod(&mut self, len: u32) where T: Copy {
+ self.ensure_capacity(len as usize);
+ let mut header = unsafe { self.header_mut() };
+ header.mLength = len;
+ }
}
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs
index 70363eba25c..5d79857be93 100644
--- a/components/style/properties/gecko.mako.rs
+++ b/components/style/properties/gecko.mako.rs
@@ -328,6 +328,39 @@ def set_gecko_property(ffi_name, expr):
% endif
</%def>
+<%def name="impl_absolute_length(ident, gecko_ffi_name, need_clone=False)">
+ #[allow(non_snake_case)]
+ pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
+ ${set_gecko_property(gecko_ffi_name, "v.0")}
+ }
+ <%call expr="impl_simple_copy(ident, gecko_ffi_name)"></%call>
+ % if need_clone:
+ #[allow(non_snake_case)]
+ pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
+ Au(self.gecko.${gecko_ffi_name})
+ }
+ % endif
+</%def>
+
+<%def name="impl_position(ident, gecko_ffi_name, need_clone=False)">
+ #[allow(non_snake_case)]
+ pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
+ ${set_gecko_property("%s.mXPosition" % gecko_ffi_name, "v.horizontal.into()")}
+ ${set_gecko_property("%s.mYPosition" % gecko_ffi_name, "v.vertical.into()")}
+ }
+ <%call expr="impl_simple_copy(ident, gecko_ffi_name)"></%call>
+ % if need_clone:
+ #[allow(non_snake_case)]
+ pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
+ use values::computed::Position;
+ Position {
+ horizontal: self.gecko.${gecko_ffi_name}.mXPosition.into(),
+ vertical: self.gecko.${gecko_ffi_name}.mYPosition.into(),
+ }
+ }
+ % endif
+</%def>
+
<%def name="impl_color(ident, gecko_ffi_name, need_clone=False, complex_color=True)">
<%call expr="impl_color_setter(ident, gecko_ffi_name, complex_color)"></%call>
<%call expr="impl_color_copy(ident, gecko_ffi_name, complex_color)"></%call>
@@ -501,7 +534,8 @@ impl Debug for ${style_struct.gecko_struct_name} {
# Types used with predefined_type()-defined properties that we can auto-generate.
predefined_types = {
"length::LengthOrAuto": impl_style_coord,
- "Length": impl_style_coord,
+ "Length": impl_absolute_length,
+ "Position": impl_position,
"LengthOrPercentage": impl_style_coord,
"LengthOrPercentageOrAuto": impl_style_coord,
"LengthOrPercentageOrNone": impl_style_coord,
@@ -1169,7 +1203,8 @@ fn static_assert() {
animation-iteration-count animation-timing-function
-moz-binding page-break-before page-break-after
scroll-snap-points-x scroll-snap-points-y transform
- scroll-snap-type-y perspective-origin transform-origin""" %>
+ scroll-snap-type-y scroll-snap-coordinate
+ perspective-origin transform-origin""" %>
<%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
// We manually-implement the |display| property until we get general
@@ -1340,6 +1375,34 @@ fn static_assert() {
${impl_coord_copy('scroll_snap_points_y', 'mScrollSnapPointsY')}
+ pub fn set_scroll_snap_coordinate(&mut self, v: longhands::scroll_snap_coordinate::computed_value::T) {
+ unsafe { self.gecko.mScrollSnapCoordinate.set_len_pod(v.0.len() as u32); }
+ for (gecko, servo) in self.gecko.mScrollSnapCoordinate
+ .iter_mut()
+ .zip(v.0.iter()) {
+ gecko.mXPosition = servo.horizontal.into();
+ gecko.mYPosition = servo.vertical.into();
+ }
+ }
+
+ pub fn copy_scroll_snap_coordinate_from(&mut self, other: &Self) {
+ unsafe {
+ self.gecko.mScrollSnapCoordinate
+ .set_len_pod(other.gecko.mScrollSnapCoordinate.len() as u32);
+ }
+
+ for (this, that) in self.gecko.mScrollSnapCoordinate
+ .iter_mut()
+ .zip(other.gecko.mScrollSnapCoordinate.iter()) {
+ *this = *that;
+ }
+ }
+
+ pub fn clone_scroll_snap_coordinate(&self) -> longhands::scroll_snap_coordinate::computed_value::T {
+ let vec = self.gecko.mScrollSnapCoordinate.iter().map(|f| f.into()).collect();
+ longhands::scroll_snap_coordinate::computed_value::T(vec)
+ }
+
<%def name="transform_function_arm(name, keyword, items)">
<%
pattern = None
@@ -1971,7 +2034,7 @@ fn static_assert() {
</%self:impl_trait>
<%self:impl_trait style_struct_name="List"
- skip_longhands="list-style-image list-style-type quotes"
+ skip_longhands="list-style-image list-style-type quotes -moz-image-region"
skip_additionals="*">
pub fn set_list_style_image(&mut self, image: longhands::list_style_image::computed_value::T) {
@@ -2037,6 +2100,28 @@ fn static_assert() {
unsafe { self.gecko.mQuotes.set(&other.gecko.mQuotes); }
}
+ #[allow(non_snake_case)]
+ pub fn set__moz_image_region(&mut self, v: longhands::_moz_image_region::computed_value::T) {
+ use values::Either;
+
+ match v {
+ Either::Second(_auto) => {
+ self.gecko.mImageRegion.x = 0;
+ self.gecko.mImageRegion.y = 0;
+ self.gecko.mImageRegion.width = 0;
+ self.gecko.mImageRegion.height = 0;
+ }
+ Either::First(rect) => {
+ self.gecko.mImageRegion.x = rect.left.0;
+ self.gecko.mImageRegion.y = rect.top.0;
+ self.gecko.mImageRegion.height = rect.bottom.unwrap_or(Au(0)).0 - self.gecko.mImageRegion.y;
+ self.gecko.mImageRegion.width = rect.right.unwrap_or(Au(0)).0 - self.gecko.mImageRegion.x;
+ }
+ }
+ }
+
+ ${impl_simple_copy('_moz_image_region', 'mImageRegion')}
+
</%self:impl_trait>
<%self:impl_trait style_struct_name="Effects"
@@ -2204,7 +2289,7 @@ fn static_assert() {
<%self:impl_trait style_struct_name="InheritedText"
skip_longhands="text-align text-emphasis-style text-shadow line-height letter-spacing word-spacing
- -webkit-text-stroke-width">
+ -webkit-text-stroke-width text-emphasis-position -moz-tab-size">
<% text_align_keyword = Keyword("text-align", "start end left right center justify -moz-center -moz-left " +
"-moz-right match-parent") %>
@@ -2310,6 +2395,26 @@ fn static_assert() {
}
}
+ pub fn set_text_emphasis_position(&mut self, v: longhands::text_emphasis_position::computed_value::T) {
+ use properties::longhands::text_emphasis_position::*;
+
+ let mut result = match v.0 {
+ HorizontalWritingModeValue::Over => structs::NS_STYLE_TEXT_EMPHASIS_POSITION_OVER as u8,
+ HorizontalWritingModeValue::Under => structs::NS_STYLE_TEXT_EMPHASIS_POSITION_UNDER as u8,
+ };
+ match v.1 {
+ VerticalWritingModeValue::Right => {
+ result |= structs::NS_STYLE_TEXT_EMPHASIS_POSITION_RIGHT as u8;
+ }
+ VerticalWritingModeValue::Left => {
+ result |= structs::NS_STYLE_TEXT_EMPHASIS_POSITION_LEFT as u8;
+ }
+ }
+ self.gecko.mTextEmphasisPosition = result;
+ }
+
+ <%call expr="impl_simple_copy('text_emphasis_position', 'mTextEmphasisPosition')"></%call>
+
pub fn set_text_emphasis_style(&mut self, v: longhands::text_emphasis_style::computed_value::T) {
use nsstring::nsCString;
use properties::longhands::text_emphasis_style::computed_value::T;
@@ -2353,6 +2458,22 @@ fn static_assert() {
<%call expr="impl_app_units('_webkit_text_stroke_width', 'mWebkitTextStrokeWidth', need_clone=False)"></%call>
+ #[allow(non_snake_case)]
+ pub fn set__moz_tab_size(&mut self, v: longhands::_moz_tab_size::computed_value::T) {
+ use values::Either;
+
+ match v {
+ Either::Second(number) => {
+ self.gecko.mTabSize.set_value(CoordDataValue::Factor(number));
+ }
+ Either::First(au) => {
+ self.gecko.mTabSize.set(au);
+ }
+ }
+ }
+
+ <%call expr="impl_coord_copy('_moz_tab_size', 'mTabSize')"></%call>
+
</%self:impl_trait>
<%self:impl_trait style_struct_name="Text"
@@ -2815,6 +2936,18 @@ clip-path
}
</%self:impl_trait>
+<%self:impl_trait style_struct_name="XUL"
+ skip_longhands="-moz-stack-sizing">
+
+ #[allow(non_snake_case)]
+ pub fn set__moz_stack_sizing(&mut self, v: longhands::_moz_stack_sizing::computed_value::T) {
+ use properties::longhands::_moz_stack_sizing::computed_value::T;
+ self.gecko.mStretchStack = v == T::stretch_to_fit;
+ }
+
+ ${impl_simple_copy('_moz_stack_sizing', 'mStretchStack')}
+</%self:impl_trait>
+
<%def name="define_ffi_struct_accessor(style_struct)">
#[no_mangle]
#[allow(non_snake_case, unused_variables)]
diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs
index 30c6873a8a2..3d84c4a8190 100644
--- a/components/style/properties/helpers.mako.rs
+++ b/components/style/properties/helpers.mako.rs
@@ -21,8 +21,9 @@
</%call>
</%def>
-<%def name="predefined_type(name, type, initial_value, parse_method='parse', needs_context=True, **kwargs)">
- <%call expr="longhand(name, predefined_type=type, **kwargs)">
+<%def name="predefined_type(name, type, initial_value, parse_method='parse',
+ needs_context=True, vector=False, **kwargs)">
+ <%def name="predefined_type_inner(name, type, initial_value, parse_method)">
#[allow(unused_imports)]
use app_units::Au;
use cssparser::{Color as CSSParserColor, RGBA};
@@ -40,7 +41,16 @@
specified::${type}::${parse_method}(input)
% endif
}
- </%call>
+ </%def>
+ % if vector:
+ <%call expr="vector_longhand(name, predefined_type=type, **kwargs)">
+ ${predefined_type_inner(name, type, initial_value, parse_method)}
+ </%call>
+ % else:
+ <%call expr="longhand(name, predefined_type=type, **kwargs)">
+ ${predefined_type_inner(name, type, initial_value, parse_method)}
+ </%call>
+ % endif
</%def>
// FIXME (Manishearth): Add computed_value_as_specified argument
@@ -56,7 +66,7 @@
We assume that the default/initial value is an empty vector for these.
`initial_value` need not be defined for these.
</%doc>
-<%def name="vector_longhand(name, gecko_only=False, allow_empty=False, **kwargs)">
+<%def name="vector_longhand(name, gecko_only=False, allow_empty=False, delegate_animate=False, **kwargs)">
<%call expr="longhand(name, **kwargs)">
% if not gecko_only:
use std::fmt;
@@ -87,6 +97,15 @@
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct T(pub Vec<single_value::T>);
+
+ % if delegate_animate:
+ use properties::animated_properties::Interpolate;
+ impl Interpolate for T {
+ fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
+ self.0.interpolate(&other.0, progress).map(T)
+ }
+ }
+ % endif
}
impl ToCss for computed_value::T {
diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs
index 35fb529c851..fae2c82e54d 100644
--- a/components/style/properties/helpers/animated_properties.mako.rs
+++ b/components/style/properties/helpers/animated_properties.mako.rs
@@ -10,8 +10,6 @@ use euclid::{Point2D, Size2D};
#[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSPropertyID;
use properties::{DeclaredValue, PropertyDeclaration};
use properties::longhands;
-use properties::longhands::background_position_x::computed_value::T as BackgroundPositionX;
-use properties::longhands::background_position_y::computed_value::T as BackgroundPositionY;
use properties::longhands::background_size::computed_value::T as BackgroundSize;
use properties::longhands::font_weight::computed_value::T as FontWeight;
use properties::longhands::line_height::computed_value::T as LineHeight;
@@ -33,7 +31,7 @@ use super::ComputedValues;
use values::CSSFloat;
use values::Either;
use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
-use values::computed::{BorderRadiusSize, LengthOrNone};
+use values::computed::{BorderRadiusSize, ClipRect, LengthOrNone};
use values::computed::{CalcLengthOrPercentage, Context, LengthOrPercentage};
use values::computed::position::{HorizontalPosition, Position, VerticalPosition};
use values::computed::ToComputedValue;
@@ -724,17 +722,16 @@ impl Interpolate for VerticalPosition {
impl RepeatableListInterpolate for VerticalPosition {}
-impl Interpolate for BackgroundPositionX {
+/// https://drafts.csswg.org/css-transitions/#animtype-rect
+impl Interpolate for ClipRect {
#[inline]
- fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
- Ok(BackgroundPositionX(try!(self.0.interpolate(&other.0, progress))))
- }
-}
-
-impl Interpolate for BackgroundPositionY {
- #[inline]
- fn interpolate(&self, other: &Self, progress: f64) -> Result<Self, ()> {
- Ok(BackgroundPositionY(try!(self.0.interpolate(&other.0, progress))))
+ fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
+ Ok(ClipRect {
+ top: try!(self.top.interpolate(&other.top, time)),
+ right: try!(self.right.interpolate(&other.right, time)),
+ bottom: try!(self.bottom.interpolate(&other.bottom, time)),
+ left: try!(self.left.interpolate(&other.left, time)),
+ })
}
}
diff --git a/components/style/properties/longhand/background.mako.rs b/components/style/properties/longhand/background.mako.rs
index b4b0686e542..f8622e75d29 100644
--- a/components/style/properties/longhand/background.mako.rs
+++ b/components/style/properties/longhand/background.mako.rs
@@ -89,7 +89,8 @@ ${helpers.predefined_type("background-color", "CSSColor",
</%helpers:vector_longhand>
<%helpers:vector_longhand name="background-position-x" animatable="True"
- spec="https://drafts.csswg.org/css-backgrounds-4/#propdef-background-position-x">
+ spec="https://drafts.csswg.org/css-backgrounds-4/#propdef-background-position-x"
+ delegate_animate="True">
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
@@ -139,7 +140,8 @@ ${helpers.predefined_type("background-color", "CSSColor",
</%helpers:vector_longhand>
<%helpers:vector_longhand name="background-position-y" animatable="True"
- spec="https://drafts.csswg.org/css-backgrounds-4/#propdef-background-position-y">
+ spec="https://drafts.csswg.org/css-backgrounds-4/#propdef-background-position-y"
+ delegate_animate="True">
use std::fmt;
use style_traits::ToCss;
use values::HasViewportPercentage;
diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs
index 624e8ac7926..8a85377febb 100644
--- a/components/style/properties/longhand/border.mako.rs
+++ b/components/style/properties/longhand/border.mako.rs
@@ -257,10 +257,10 @@ ${helpers.single_keyword("-moz-float-edge", "content-box margin-box",
}
}
- pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
+ pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
let mut values = vec![];
for _ in 0..4 {
- let value = input.try(|input| LengthOrNumber::parse_non_negative(input));
+ let value = input.try(|input| LengthOrNumber::parse_non_negative(context, input));
match value {
Ok(val) => values.push(val),
Err(_) => break,
diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs
index 95d23dbf0e4..9fbe615fea0 100644
--- a/components/style/properties/longhand/box.mako.rs
+++ b/components/style/properties/longhand/box.mako.rs
@@ -1049,6 +1049,25 @@ ${helpers.single_keyword("animation-fill-mode",
</%helpers:longhand>
+${helpers.predefined_type("scroll-snap-destination",
+ "Position",
+ "computed::Position::zero()",
+ products="gecko",
+ boxed="True",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-destination)",
+ animatable=True)}
+
+${helpers.predefined_type("scroll-snap-coordinate",
+ "Position",
+ "computed::Position::zero()",
+ vector=True,
+ products="gecko",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-destination)",
+ animatable=True,
+ allow_empty=True,
+ delegate_animate=True)}
+
+
<%helpers:longhand name="transform" products="gecko servo" extra_prefixes="webkit"
animatable="True"
diff --git a/components/style/properties/longhand/effects.mako.rs b/components/style/properties/longhand/effects.mako.rs
index b01874e8095..eb4879f7afb 100644
--- a/components/style/properties/longhand/effects.mako.rs
+++ b/components/style/properties/longhand/effects.mako.rs
@@ -77,217 +77,13 @@ ${helpers.predefined_type("opacity",
</%helpers:vector_longhand>
// FIXME: This prop should be animatable
-<%helpers:longhand name="clip" products="servo" animatable="False" boxed="True"
- spec="https://drafts.fxtf.org/css-masking/#clip-property">
- use std::fmt;
- use style_traits::ToCss;
- use values::HasViewportPercentage;
-
- // NB: `top` and `left` are 0 if `auto` per CSS 2.1 11.1.2.
-
- pub mod computed_value {
- use app_units::Au;
- use properties::animated_properties::Interpolate;
-
- #[derive(Clone, PartialEq, Eq, Copy, Debug)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct ClipRect {
- pub top: Au,
- pub right: Option<Au>,
- pub bottom: Option<Au>,
- pub left: Au,
- }
-
- #[derive(Debug, Clone, PartialEq)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct T(pub Option<ClipRect>);
-
-
- /// https://drafts.csswg.org/css-transitions/#animtype-rect
- impl Interpolate for ClipRect {
- #[inline]
- fn interpolate(&self, other: &Self, time: f64) -> Result<Self, ()> {
- Ok(ClipRect {
- top: try!(self.top.interpolate(&other.top, time)),
- right: try!(self.right.interpolate(&other.right, time)),
- bottom: try!(self.bottom.interpolate(&other.bottom, time)),
- left: try!(self.left.interpolate(&other.left, time)),
- })
- }
- }
- }
-
- impl ToCss for computed_value::T {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- match self.0 {
- None => dest.write_str("auto"),
- Some(rect) => {
- try!(dest.write_str("rect("));
- try!(rect.top.to_css(dest));
- try!(dest.write_str(", "));
- if let Some(right) = rect.right {
- try!(right.to_css(dest));
- try!(dest.write_str(", "));
- } else {
- try!(dest.write_str("auto, "));
- }
-
- if let Some(bottom) = rect.bottom {
- try!(bottom.to_css(dest));
- try!(dest.write_str(", "));
- } else {
- try!(dest.write_str("auto, "));
- }
-
- try!(rect.left.to_css(dest));
- try!(dest.write_str(")"));
- Ok(())
- }
- }
- }
- }
-
- impl HasViewportPercentage for SpecifiedClipRect {
- fn has_viewport_percentage(&self) -> bool {
- self.top.has_viewport_percentage() ||
- self.right.as_ref().map_or(false, |x| x.has_viewport_percentage()) ||
- self.bottom.as_ref().map_or(false, |x| x.has_viewport_percentage()) ||
- self.left.has_viewport_percentage()
- }
- }
-
- #[derive(Clone, Debug, PartialEq)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct SpecifiedClipRect {
- pub top: specified::Length,
- pub right: Option<specified::Length>,
- pub bottom: Option<specified::Length>,
- pub left: specified::Length,
- }
-
- impl HasViewportPercentage for SpecifiedValue {
- fn has_viewport_percentage(&self) -> bool {
- self.0.as_ref().map_or(false, |x| x.has_viewport_percentage())
- }
- }
-
- #[derive(Clone, Debug, PartialEq)]
- #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
- pub struct SpecifiedValue(Option<SpecifiedClipRect>);
-
- impl ToCss for SpecifiedClipRect {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- try!(dest.write_str("rect("));
-
- try!(self.top.to_css(dest));
- try!(dest.write_str(", "));
-
- if let Some(ref right) = self.right {
- try!(right.to_css(dest));
- try!(dest.write_str(", "));
- } else {
- try!(dest.write_str("auto, "));
- }
-
- if let Some(ref bottom) = self.bottom {
- try!(bottom.to_css(dest));
- try!(dest.write_str(", "));
- } else {
- try!(dest.write_str("auto, "));
- }
-
- try!(self.left.to_css(dest));
-
- try!(dest.write_str(")"));
- Ok(())
- }
- }
-
- impl ToCss for SpecifiedValue {
- fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
- if let Some(ref rect) = self.0 {
- rect.to_css(dest)
- } else {
- dest.write_str("auto")
- }
- }
- }
-
- #[inline]
- pub fn get_initial_value() -> computed_value::T {
- computed_value::T(None)
- }
-
- impl ToComputedValue for SpecifiedValue {
- type ComputedValue = computed_value::T;
-
- #[inline]
- fn to_computed_value(&self, context: &Context) -> computed_value::T {
- computed_value::T(self.0.as_ref().map(|value| computed_value::ClipRect {
- top: value.top.to_computed_value(context),
- right: value.right.as_ref().map(|right| right.to_computed_value(context)),
- bottom: value.bottom.as_ref().map(|bottom| bottom.to_computed_value(context)),
- left: value.left.to_computed_value(context),
- }))
- }
-
- #[inline]
- fn from_computed_value(computed: &computed_value::T) -> Self {
- SpecifiedValue(computed.0.map(|value| SpecifiedClipRect {
- top: ToComputedValue::from_computed_value(&value.top),
- right: value.right.map(|right| ToComputedValue::from_computed_value(&right)),
- bottom: value.bottom.map(|bottom| ToComputedValue::from_computed_value(&bottom)),
- left: ToComputedValue::from_computed_value(&value.left),
- }))
- }
- }
-
- pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
- use app_units::Au;
- use std::ascii::AsciiExt;
- use values::specified::Length;
-
- fn parse_argument(context: &ParserContext, input: &mut Parser) -> Result<Option<Length>, ()> {
- if input.try(|input| input.expect_ident_matching("auto")).is_ok() {
- Ok(None)
- } else {
- Length::parse(context, input).map(Some)
- }
- }
-
- if input.try(|input| input.expect_ident_matching("auto")).is_ok() {
- return Ok(SpecifiedValue(None))
- }
- if !try!(input.expect_function()).eq_ignore_ascii_case("rect") {
- return Err(())
- }
-
- input.parse_nested_block(|input| {
- let top = try!(parse_argument(context, input));
- let right;
- let bottom;
- let left;
-
- if input.try(|input| input.expect_comma()).is_ok() {
- right = try!(parse_argument(context, input));
- try!(input.expect_comma());
- bottom = try!(parse_argument(context, input));
- try!(input.expect_comma());
- left = try!(parse_argument(context, input));
- } else {
- right = try!(parse_argument(context, input));
- bottom = try!(parse_argument(context, input));
- left = try!(parse_argument(context, input));
- }
- Ok(SpecifiedValue(Some(SpecifiedClipRect {
- top: top.unwrap_or(Length::zero()),
- right: right,
- bottom: bottom,
- left: left.unwrap_or(Length::zero()),
- })))
- })
- }
-</%helpers:longhand>
+${helpers.predefined_type("clip",
+ "ClipRectOrAuto",
+ "computed::ClipRectOrAuto::auto()",
+ animatable=False,
+ products="servo",
+ boxed="True",
+ spec="https://drafts.fxtf.org/css-masking/#clip-property")}
// FIXME: This prop should be animatable
<%helpers:longhand name="filter" animatable="False" extra_prefixes="webkit"
diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs
index 335ad1f1ca1..dc3e32f99b3 100644
--- a/components/style/properties/longhand/inherited_text.mako.rs
+++ b/components/style/properties/longhand/inherited_text.mako.rs
@@ -973,7 +973,7 @@ ${helpers.single_keyword("text-align-last",
}
</%helpers:longhand>
-<%helpers:longhand name="text-emphasis-position" animatable="False" products="none"
+<%helpers:longhand name="text-emphasis-position" animatable="False" products="gecko"
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-position">
use std::fmt;
use values::computed::ComputedValueAsSpecified;
@@ -1030,6 +1030,15 @@ ${helpers.predefined_type("text-emphasis-color", "CSSColor",
boxed=True,
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-color")}
+
+${helpers.predefined_type(
+ "-moz-tab-size", "LengthOrNumber",
+ "::values::Either::Second(8.0)",
+ "parse_non_negative",
+ products="gecko", animatable=False,
+ spec="https://drafts.csswg.org/css-text-3/#tab-size-property")}
+
+
// CSS Compatibility
// https://compat.spec.whatwg.org
${helpers.predefined_type(
@@ -1070,6 +1079,7 @@ ${helpers.predefined_type(
}
</%helpers:longhand>
+
// CSS Ruby Layout Module Level 1
// https://drafts.csswg.org/css-ruby/
${helpers.single_keyword("ruby-align", "start center space-between space-around",
diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs
index f4f84f9e884..91e003d2575 100644
--- a/components/style/properties/longhand/list.mako.rs
+++ b/components/style/properties/longhand/list.mako.rs
@@ -101,3 +101,11 @@ ${helpers.predefined_type("list-style-image", "UrlOrNone", "Either::Second(None_
}
}
</%helpers:longhand>
+
+${helpers.predefined_type("-moz-image-region",
+ "ClipRectOrAuto",
+ "computed::ClipRectOrAuto::auto()",
+ animatable=False,
+ products="gecko",
+ boxed="True",
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-image-region)")}
diff --git a/components/style/properties/longhand/outline.mako.rs b/components/style/properties/longhand/outline.mako.rs
index b47f45d7a68..cd242797f0d 100644
--- a/components/style/properties/longhand/outline.mako.rs
+++ b/components/style/properties/longhand/outline.mako.rs
@@ -114,5 +114,5 @@ ${helpers.predefined_type("outline-color", "CSSColor", "::cssparser::Color::Curr
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-outline-radius)")}
% endfor
-${helpers.predefined_type("outline-offset", "Length", "Au(0)", products="servo", animatable=True,
+${helpers.predefined_type("outline-offset", "Length", "Au(0)", products="servo gecko", animatable=True,
spec="https://drafts.csswg.org/css-ui/#propdef-outline-offset")}
diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs
index 3e55cb2bd3b..9c801358988 100644
--- a/components/style/properties/longhand/position.mako.rs
+++ b/components/style/properties/longhand/position.mako.rs
@@ -210,6 +210,14 @@ ${helpers.single_keyword("object-fit", "fill contain cover none scale-down",
products="gecko", animatable=False,
spec="https://drafts.csswg.org/css-images/#propdef-object-fit")}
+${helpers.predefined_type("object-position",
+ "Position",
+ "computed::Position::zero()",
+ products="gecko",
+ boxed="True",
+ spec="https://drafts.csswg.org/css-images-3/#the-object-position",
+ animatable=True)}
+
<% grid_longhands = ["grid-row-start", "grid-row-end", "grid-column-start", "grid-column-end"] %>
% for longhand in grid_longhands:
diff --git a/components/style/properties/longhand/ui.mako.rs b/components/style/properties/longhand/ui.mako.rs
index 62948316e70..79d25467df6 100644
--- a/components/style/properties/longhand/ui.mako.rs
+++ b/components/style/properties/longhand/ui.mako.rs
@@ -23,3 +23,9 @@ ${helpers.single_keyword("-moz-user-select", "auto text none all", products="gec
gecko_inexhaustive=True,
animatable=False,
spec="https://drafts.csswg.org/css-ui-4/#propdef-user-select")}
+
+${helpers.single_keyword("-moz-window-dragging", "default drag no-drag", products="gecko",
+ gecko_ffi_name="mWindowDragging",
+ gecko_enum_prefix="StyleWindowDragging",
+ animatable=False,
+ spec="None (Nonstandard Firefox-only property)")}
diff --git a/components/style/properties/longhand/xul.mako.rs b/components/style/properties/longhand/xul.mako.rs
index 7862b1d9177..6cf61f3948a 100644
--- a/components/style/properties/longhand/xul.mako.rs
+++ b/components/style/properties/longhand/xul.mako.rs
@@ -22,3 +22,10 @@ ${helpers.predefined_type("-moz-box-flex", "Number", "0.0", "parse_non_negative"
animatable=False,
alias="-webkit-box-flex",
spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/box-flex)")}
+
+
+${helpers.single_keyword("-moz-stack-sizing", "stretch-to-fit ignore",
+ products="gecko", gecko_ffi_name="mStretchStack",
+ gecko_constant_prefix="NS_STYLE_STACK_SIZING",
+ animatable=False,
+ spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-stack-sizing)")}
diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs
index 3f014d3368f..02cbcbf1150 100644
--- a/components/style/properties/properties.mako.rs
+++ b/components/style/properties/properties.mako.rs
@@ -1589,7 +1589,7 @@ impl ComputedValues {
// TODO(gw): Add clip-path, isolation, mask-image, mask-border-source when supported.
if effects.opacity < 1.0 ||
!effects.filter.is_empty() ||
- effects.clip.0.is_some() {
+ !effects.clip.is_auto() {
effects.mix_blend_mode != mix_blend_mode::T::normal ||
return transform_style::T::flat;
}
@@ -2290,10 +2290,10 @@ pub fn modify_style_for_text(style: &mut Arc<ComputedValues>) {
/// doesn't clip its children.
#[cfg(feature = "servo")]
pub fn modify_style_for_inline_absolute_hypothetical_fragment(style: &mut Arc<ComputedValues>) {
- if style.get_effects().clip.0.is_some() {
+ if !style.get_effects().clip.is_auto() {
let mut style = Arc::make_mut(style);
let effects_style = Arc::make_mut(&mut style.effects);
- effects_style.clip.0 = None
+ effects_style.clip = Either::auto()
}
}
diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs
index a653d18918c..36b3b2dc6ac 100644
--- a/components/style/values/computed/mod.rs
+++ b/components/style/values/computed/mod.rs
@@ -15,11 +15,12 @@ use super::{CSSFloat, specified};
pub use cssparser::Color as CSSColor;
pub use self::image::{AngleOrCorner, EndingShape as GradientShape, Gradient, GradientKind, Image};
pub use self::image::{LengthOrKeyword, LengthOrPercentageOrKeyword};
-pub use super::{Either, None_};
+pub use super::{Auto, Either, None_};
pub use super::specified::{Angle, BorderStyle, GridLine, Time, UrlOrNone};
pub use super::specified::url::UrlExtraData;
pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto};
pub use self::length::{LengthOrPercentageOrAutoOrContent, LengthOrPercentageOrNone, LengthOrNone};
+pub use self::position::Position;
pub mod basic_shape;
pub mod image;
@@ -176,3 +177,57 @@ pub type Number = CSSFloat;
/// A type used for opacity.
pub type Opacity = CSSFloat;
+
+
+#[derive(Clone, PartialEq, Eq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+#[allow(missing_docs)]
+/// A computed cliprect for clip and image-region
+pub struct ClipRect {
+ pub top: Au,
+ pub right: Option<Au>,
+ pub bottom: Option<Au>,
+ pub left: Au,
+}
+
+impl ToCss for ClipRect {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ try!(dest.write_str("rect("));
+ try!(self.top.to_css(dest));
+ try!(dest.write_str(", "));
+ if let Some(right) = self.right {
+ try!(right.to_css(dest));
+ try!(dest.write_str(", "));
+ } else {
+ try!(dest.write_str("auto, "));
+ }
+
+ if let Some(bottom) = self.bottom {
+ try!(bottom.to_css(dest));
+ try!(dest.write_str(", "));
+ } else {
+ try!(dest.write_str("auto, "));
+ }
+
+ try!(self.left.to_css(dest));
+ dest.write_str(")")
+ }
+}
+
+/// rect(...) | auto
+pub type ClipRectOrAuto = Either<ClipRect, Auto>;
+
+impl ClipRectOrAuto {
+ /// Return an auto (default for clip-rect and image-region) value
+ pub fn auto() -> Self {
+ Either::Second(Auto)
+ }
+
+ /// Check if it is auto
+ pub fn is_auto(&self) -> bool {
+ match *self {
+ Either::Second(_) => true,
+ _ => false
+ }
+ }
+}
diff --git a/components/style/values/computed/position.rs b/components/style/values/computed/position.rs
index a9b51953810..d2cc4b1e48f 100644
--- a/components/style/values/computed/position.rs
+++ b/components/style/values/computed/position.rs
@@ -19,6 +19,16 @@ pub struct Position {
pub vertical: LengthOrPercentage,
}
+impl Position {
+ /// Construct a position at (0, 0)
+ pub fn zero() -> Self {
+ Position {
+ horizontal: LengthOrPercentage::zero(),
+ vertical: LengthOrPercentage::zero(),
+ }
+ }
+}
+
impl ToCss for Position {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
try!(self.horizontal.to_css(dest));
diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs
index 99c4a09abf1..fb4ac9c0b60 100644
--- a/components/style/values/specified/length.rs
+++ b/components/style/values/specified/length.rs
@@ -1215,7 +1215,7 @@ pub type LengthOrNumber = Either<Length, Number>;
impl LengthOrNumber {
/// Parse a non-negative LengthOrNumber.
- pub fn parse_non_negative(input: &mut Parser) -> Result<Self, ()> {
+ pub fn parse_non_negative(_context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
// We try to parse as a Number first because, for cases like LengthOrNumber,
// we want "0" to be parsed as a plain Number rather than a Length (0px); this
// matches the behaviour of all major browsers
diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs
index dac10f661f7..8e3315f0ea6 100644
--- a/components/style/values/specified/mod.rs
+++ b/components/style/values/specified/mod.rs
@@ -16,7 +16,7 @@ use std::f32::consts::PI;
use std::fmt;
use std::ops::Mul;
use style_traits::ToCss;
-use super::{CSSFloat, HasViewportPercentage, Either, None_};
+use super::{Auto, CSSFloat, HasViewportPercentage, Either, None_};
use super::computed::{ComputedValueAsSpecified, Context, ToComputedValue};
use super::computed::Shadow as ComputedShadow;
@@ -27,6 +27,7 @@ pub use self::image::{SizeKeyword, VerticalDirection};
pub use self::length::{FontRelativeLength, ViewportPercentageLength, CharacterWidth, Length, CalcLengthOrPercentage};
pub use self::length::{Percentage, LengthOrNone, LengthOrNumber, LengthOrPercentage, LengthOrPercentageOrAuto};
pub use self::length::{LengthOrPercentageOrNone, LengthOrPercentageOrAutoOrContent, NoCalcLength, CalcUnit};
+pub use self::position::{HorizontalPosition, Position, VerticalPosition};
pub mod basic_shape;
pub mod grid;
@@ -664,3 +665,127 @@ impl Shadow {
})
}
}
+
+
+impl HasViewportPercentage for ClipRect {
+ fn has_viewport_percentage(&self) -> bool {
+ self.top.has_viewport_percentage() ||
+ self.right.as_ref().map_or(false, |x| x.has_viewport_percentage()) ||
+ self.bottom.as_ref().map_or(false, |x| x.has_viewport_percentage()) ||
+ self.left.has_viewport_percentage()
+ }
+}
+
+#[derive(Clone, Debug, PartialEq)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+/// rect(<top>, <left>, <bottom>, <right>) used by clip and image-region
+pub struct ClipRect {
+ /// <top> (<length> | <auto>). Auto maps to 0
+ pub top: Length,
+ /// <right> (<length> | <auto>)
+ pub right: Option<Length>,
+ /// <bottom> (<length> | <auto>)
+ pub bottom: Option<Length>,
+ /// <left> (<length> | <auto>). Auto maps to 0
+ pub left: Length,
+}
+
+
+impl ToCss for ClipRect {
+ fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+ try!(dest.write_str("rect("));
+
+ try!(self.top.to_css(dest));
+ try!(dest.write_str(", "));
+
+ if let Some(ref right) = self.right {
+ try!(right.to_css(dest));
+ try!(dest.write_str(", "));
+ } else {
+ try!(dest.write_str("auto, "));
+ }
+
+ if let Some(ref bottom) = self.bottom {
+ try!(bottom.to_css(dest));
+ try!(dest.write_str(", "));
+ } else {
+ try!(dest.write_str("auto, "));
+ }
+
+ try!(self.left.to_css(dest));
+
+ try!(dest.write_str(")"));
+ Ok(())
+ }
+}
+
+impl ToComputedValue for ClipRect {
+ type ComputedValue = super::computed::ClipRect;
+
+ #[inline]
+ fn to_computed_value(&self, context: &Context) -> super::computed::ClipRect {
+ super::computed::ClipRect {
+ top: self.top.to_computed_value(context),
+ right: self.right.as_ref().map(|right| right.to_computed_value(context)),
+ bottom: self.bottom.as_ref().map(|bottom| bottom.to_computed_value(context)),
+ left: self.left.to_computed_value(context),
+ }
+ }
+
+ #[inline]
+ fn from_computed_value(computed: &super::computed::ClipRect) -> Self {
+ ClipRect {
+ top: ToComputedValue::from_computed_value(&computed.top),
+ right: computed.right.map(|right| ToComputedValue::from_computed_value(&right)),
+ bottom: computed.bottom.map(|bottom| ToComputedValue::from_computed_value(&bottom)),
+ left: ToComputedValue::from_computed_value(&computed.left),
+ }
+ }
+}
+
+impl Parse for ClipRect {
+ fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
+ use values::specified::Length;
+
+ fn parse_argument(context: &ParserContext, input: &mut Parser) -> Result<Option<Length>, ()> {
+ if input.try(|input| input.expect_ident_matching("auto")).is_ok() {
+ Ok(None)
+ } else {
+ Length::parse(context, input).map(Some)
+ }
+ }
+
+ if !try!(input.expect_function()).eq_ignore_ascii_case("rect") {
+ return Err(())
+ }
+
+ // NB: `top` and `left` are 0 if `auto` per CSS 2.1 11.1.2.
+ input.parse_nested_block(|input| {
+ let top = try!(parse_argument(context, input));
+ let right;
+ let bottom;
+ let left;
+
+ if input.try(|input| input.expect_comma()).is_ok() {
+ right = try!(parse_argument(context, input));
+ try!(input.expect_comma());
+ bottom = try!(parse_argument(context, input));
+ try!(input.expect_comma());
+ left = try!(parse_argument(context, input));
+ } else {
+ right = try!(parse_argument(context, input));
+ bottom = try!(parse_argument(context, input));
+ left = try!(parse_argument(context, input));
+ }
+ Ok(ClipRect {
+ top: top.unwrap_or(Length::zero()),
+ right: right,
+ bottom: bottom,
+ left: left.unwrap_or(Length::zero()),
+ })
+ })
+ }
+}
+
+/// rect(...) | auto
+pub type ClipRectOrAuto = Either<ClipRect, Auto>;