From 4799e83e3c2cad0f21ff2caeae4989bd8e4c636c Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Sat, 15 Dec 2018 08:17:46 +0000 Subject: [PATCH 01/27] style: Enable CSS containment for frontend code. Differential Revision: https://phabricator.services.mozilla.com/D9963 --- components/style/properties/longhands/box.mako.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/components/style/properties/longhands/box.mako.rs b/components/style/properties/longhands/box.mako.rs index 1e0629861e4..e8946c3206e 100644 --- a/components/style/properties/longhands/box.mako.rs +++ b/components/style/properties/longhands/box.mako.rs @@ -559,6 +559,7 @@ ${helpers.predefined_type( flags="CREATES_STACKING_CONTEXT FIXPOS_CB", gecko_pref="layout.css.contain.enabled", spec="https://drafts.csswg.org/css-contain/#contain-property", + enabled_in="chrome", )} // Non-standard From 31838b1e6f759113cf432d24ff9268919cf368ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 15 Dec 2018 22:48:37 +0000 Subject: [PATCH 02/27] style: The 'all' property is not animatable. Since it allows to animate display, which is not good. This is a regression from: https://hg.mozilla.org/mozilla-central/rev/6884ba750aa3 Actually I wonder if the logic shouldn't be the other way around, i.e., a shorthand is animatable if all the longhands are, not if just one. In any case this rolls back to the previous behavior, should we do that, it should be another bug. Differential Revision: https://phabricator.services.mozilla.com/D14632 --- components/style/properties/data.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 8faaa163823..4d980039d1e 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -388,12 +388,12 @@ class Shorthand(object): and allowed_in_keyframe_block != "False" def get_animatable(self): - animatable = False + if self.ident == "all": + return False for sub in self.sub_properties: if sub.animatable: - animatable = True - break - return animatable + return True + return False def get_transitionable(self): transitionable = False From b59ec2e6994f247fcf543b874cb5be1208daf4e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 17 Dec 2018 13:14:19 +0000 Subject: [PATCH 03/27] style: Make shadow trees lookup keyframe rules in the containing tree. The same thing we do for rule matching. Differential Revision: https://phabricator.services.mozilla.com/D14548 --- components/style/rule_collector.rs | 85 +++++++++++++++++------------- components/style/stylist.rs | 6 ++- 2 files changed, 53 insertions(+), 38 deletions(-) diff --git a/components/style/rule_collector.rs b/components/style/rule_collector.rs index 6424cc237db..6304a1af2d7 100644 --- a/components/style/rule_collector.rs +++ b/components/style/rule_collector.rs @@ -5,7 +5,7 @@ //! Collects a series of applicable rules for a given element. use crate::applicable_declarations::{ApplicableDeclarationBlock, ApplicableDeclarationList}; -use crate::dom::{TElement, TShadowRoot}; +use crate::dom::{TElement, TNode, TShadowRoot}; use crate::properties::{AnimationRules, PropertyDeclarationBlock}; use crate::rule_tree::{CascadeLevel, ShadowCascadeOrder}; use crate::selector_map::SelectorMap; @@ -17,6 +17,43 @@ use selectors::matching::{ElementSelectorFlags, MatchingContext}; use servo_arc::ArcBorrow; use smallvec::SmallVec; +/// This is a bit of a hack so matches the rules of the enclosing +/// tree. +/// +/// This function returns the containing shadow host ignoring shadow +/// trees, since those match the enclosing tree's rules. +/// +/// Only a handful of places need to really care about this. This is not a +/// problem for invalidation and that kind of stuff because they still don't +/// match rules based on elements outside of the shadow tree, and because the +/// subtrees are immutable and recreated each time the source tree +/// changes. +/// +/// We historically allow cross-document to have these rules applied, +/// but I think that's not great. Gecko is the only engine supporting that. +/// +/// See https://github.com/w3c/svgwg/issues/504 for the relevant spec +/// discussion. +#[inline] +pub fn containing_shadow_ignoring_svg_use( + element: E, +) -> Option<::ConcreteShadowRoot> { + let mut shadow = element.containing_shadow()?; + loop { + let host = shadow.host(); + let host_is_svg_use_element = + host.is_svg_element() && host.local_name() == &*local_name!("use"); + if !host_is_svg_use_element { + return Some(shadow); + } + debug_assert!( + shadow.style_data().is_none(), + "We allow no stylesheets in subtrees" + ); + shadow = host.containing_shadow()?; + } +} + /// An object that we use with all the intermediate state needed for the /// cascade. /// @@ -213,43 +250,19 @@ where return; } - let mut current_containing_shadow = self.rule_hash_target.containing_shadow(); - while let Some(containing_shadow) = current_containing_shadow { - let cascade_data = containing_shadow.style_data(); - let host = containing_shadow.host(); - if let Some(map) = cascade_data.and_then(|data| data.normal_rules(self.pseudo_element)) - { - self.collect_rules_in_shadow_tree(host, map, CascadeLevel::SameTreeAuthorNormal); - } - let host_is_svg_use_element = - host.is_svg_element() && host.local_name() == &*local_name!("use"); - if !host_is_svg_use_element { - self.matches_document_author_rules = false; - break; - } + let containing_shadow = containing_shadow_ignoring_svg_use(self.rule_hash_target); + let containing_shadow = match containing_shadow { + Some(s) => s, + None => return, + }; - debug_assert!( - cascade_data.is_none(), - "We allow no stylesheets in subtrees" - ); + self.matches_document_author_rules = false; - // NOTE(emilio): Hack so matches the rules of the - // enclosing tree. - // - // This is not a problem for invalidation and that kind of stuff - // because they still don't match rules based on elements - // outside of the shadow tree, and because the - // subtrees are immutable and recreated each time the source - // tree changes. - // - // We historically allow cross-document to have these - // rules applied, but I think that's not great. Gecko is the - // only engine supporting that. - // - // See https://github.com/w3c/svgwg/issues/504 for the relevant - // spec discussion. - current_containing_shadow = host.containing_shadow(); - self.matches_document_author_rules = current_containing_shadow.is_none(); + let cascade_data = containing_shadow.style_data(); + let host = containing_shadow.host(); + if let Some(map) = cascade_data.and_then(|data| data.normal_rules(self.pseudo_element)) + { + self.collect_rules_in_shadow_tree(host, map, CascadeLevel::SameTreeAuthorNormal); } } diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 592e4e81081..3815a8a3da6 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -17,7 +17,7 @@ use crate::media_queries::Device; use crate::properties::{self, CascadeMode, ComputedValues}; use crate::properties::{AnimationRules, PropertyDeclarationBlock}; use crate::rule_cache::{RuleCache, RuleCacheConditions}; -use crate::rule_collector::RuleCollector; +use crate::rule_collector::{RuleCollector, containing_shadow_ignoring_svg_use}; use crate::rule_tree::{CascadeLevel, RuleTree, ShadowCascadeOrder, StrongRuleNode, StyleSource}; use crate::selector_map::{PrecomputedHashMap, PrecomputedHashSet, SelectorMap, SelectorMapEntry}; use crate::selector_parser::{PerPseudoElementMap, PseudoElement, SelectorImpl, SnapshotMap}; @@ -1187,7 +1187,9 @@ impl Stylist { } } - if let Some(shadow) = element.containing_shadow() { + // Use the same rules to look for the containing host as we do for rule + // collection. + if let Some(shadow) = containing_shadow_ignoring_svg_use(element) { if let Some(data) = shadow.style_data() { try_find_in!(data); } From 19035590ceb565ac068529360e70b8eb4724acc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 16 Dec 2018 09:13:49 +0000 Subject: [PATCH 04/27] style: Cleanup some conversion code dealing with NonNegative. I'm about to introduce another use of it and I don't want to repeat the same copy-pasta again. Differential Revision: https://phabricator.services.mozilla.com/D14672 --- components/style/gecko/values.rs | 48 +++++++++++--------------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index 98dafcd070f..59ccd0afeca 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -13,12 +13,10 @@ use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, Coor use crate::media_queries::Device; use crate::values::computed::basic_shape::ShapeRadius as ComputedShapeRadius; use crate::values::computed::FlexBasis as ComputedFlexBasis; -use crate::values::computed::NonNegativeNumber; use crate::values::computed::{Angle, ExtremumLength, Length, LengthOrPercentage}; use crate::values::computed::{LengthOrPercentageOrAuto, Percentage}; use crate::values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage}; use crate::values::computed::{MaxLength as ComputedMaxLength, MozLength as ComputedMozLength}; -use crate::values::computed::{NonNegativeLength, NonNegativeLengthOrPercentage}; use crate::values::generics::basic_shape::ShapeRadius; use crate::values::generics::box_::Perspective; use crate::values::generics::flex::FlexBasis; @@ -34,6 +32,9 @@ use nsstring::{nsACString, nsCStr}; use std::cmp::max; /// A trait that defines an interface to convert from and to `nsStyleCoord`s. +/// +/// TODO(emilio): Almost everything that is in this file should be somehow +/// switched to cbindgen. pub trait GeckoStyleCoordConvertible: Sized { /// Convert this to a `nsStyleCoord`. fn to_gecko_style_coord(&self, coord: &mut T); @@ -66,6 +67,19 @@ impl GeckoStyleCoo } } +impl GeckoStyleCoordConvertible for NonNegative +where + Inner: GeckoStyleCoordConvertible, +{ + fn to_gecko_style_coord(&self, coord: &mut T) { + self.0.to_gecko_style_coord(coord) + } + + fn from_gecko_style_coord(coord: &T) -> Option { + Some(NonNegative(Inner::from_gecko_style_coord(coord)?)) + } +} + impl GeckoStyleCoordConvertible for ComputedFlexBasis { fn to_gecko_style_coord(&self, coord: &mut T) { match *self { @@ -152,16 +166,6 @@ impl GeckoStyleCoordConvertible for LengthOrPercentage { } } -impl GeckoStyleCoordConvertible for NonNegativeLengthOrPercentage { - fn to_gecko_style_coord(&self, coord: &mut T) { - self.0.to_gecko_style_coord(coord); - } - - fn from_gecko_style_coord(coord: &T) -> Option { - LengthOrPercentage::from_gecko_style_coord(coord).map(NonNegative::) - } -} - impl GeckoStyleCoordConvertible for Length { fn to_gecko_style_coord(&self, coord: &mut T) { coord.set_value(CoordDataValue::Coord(self.to_i32_au())); @@ -175,26 +179,6 @@ impl GeckoStyleCoordConvertible for Length { } } -impl GeckoStyleCoordConvertible for NonNegativeLength { - fn to_gecko_style_coord(&self, coord: &mut T) { - self.0.to_gecko_style_coord(coord); - } - - fn from_gecko_style_coord(coord: &T) -> Option { - Length::from_gecko_style_coord(coord).map(NonNegative::) - } -} - -impl GeckoStyleCoordConvertible for NonNegativeNumber { - fn to_gecko_style_coord(&self, coord: &mut T) { - self.0.to_gecko_style_coord(coord); - } - - fn from_gecko_style_coord(coord: &T) -> Option { - Number::from_gecko_style_coord(coord).map(NonNegative::) - } -} - impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto { fn to_gecko_style_coord(&self, coord: &mut T) { let value = match *self { From ca1ad003bdb7dc8d2ae97d9bd0d15a7971847947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 17 Dec 2018 21:35:14 +0000 Subject: [PATCH 05/27] style: Use NonNegative more in the border code. This ended up not being so small of a patch as I'd have thought, since it propagated a bit. But most of it is mechanical. Interesting part is NonNegativeNumberOrPercentage and the actual uses of the NonNegative stuff and during parsing. This looks like it'd fix a few correctness issues during interpolation for all the types except for BorderRadius and co (which handled it manually). I should write tests for those in a different patch. Differential Revision: https://phabricator.services.mozilla.com/D14673 --- components/style/gecko/conversions.rs | 13 ++-- components/style/properties/gecko.mako.rs | 4 +- .../style/properties/longhands/border.mako.rs | 16 ++--- .../longhands/inherited_text.mako.rs | 2 +- components/style/values/animated/mod.rs | 18 ------ .../style/values/computed/basic_shape.rs | 6 +- components/style/values/computed/border.rs | 43 +++++++------ components/style/values/computed/mod.rs | 34 ++++++++++ .../style/values/generics/basic_shape.rs | 13 ++-- components/style/values/generics/border.rs | 15 +---- .../style/values/specified/basic_shape.rs | 11 ++-- components/style/values/specified/border.rs | 62 ++++++++++++------- components/style/values/specified/length.rs | 10 +++ components/style/values/specified/mod.rs | 20 ++++++ 14 files changed, 161 insertions(+), 106 deletions(-) diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index c48d56f56e1..e077a9f9666 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -5,6 +5,8 @@ //! This module contains conversion helpers between Servo and Gecko types //! Ideally, it would be in geckolib itself, but coherence //! forces us to keep the traits and implementations here +//! +//! FIXME(emilio): This file should generally just die. #![allow(unsafe_code)] @@ -22,6 +24,7 @@ use crate::values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image}; use crate::values::computed::{Integer, LengthOrPercentage}; use crate::values::computed::{LengthOrPercentageOrAuto, NonNegativeLengthOrPercentageOrAuto}; use crate::values::computed::{Percentage, TextAlign}; +use crate::values::generics::NonNegative; use crate::values::generics::box_::VerticalAlign; use crate::values::generics::grid::{TrackListValue, TrackSize}; use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage}; @@ -113,7 +116,6 @@ impl From for LengthOrPercentageOrAuto { // disappear as we move more stuff to cbindgen. impl From for NonNegativeLengthOrPercentageOrAuto { fn from(other: nsStyleCoord_CalcValue) -> Self { - use crate::values::generics::NonNegative; use style_traits::values::specified::AllowedNumericType; NonNegative(if other.mLength < 0 || other.mPercent < 0. { LengthOrPercentageOrAuto::Calc(CalcLengthOrPercentage::with_clamping_mode( @@ -675,6 +677,7 @@ pub mod basic_shape { use crate::values::generics::basic_shape::{ BasicShape as GenericBasicShape, InsetRect, Polygon, }; + use crate::values::generics::NonNegative; use crate::values::generics::basic_shape::{Circle, Ellipse, Path, PolygonCoord}; use crate::values::generics::basic_shape::{GeometryBox, ShapeBox, ShapeSource}; use crate::values::generics::border::BorderRadius as GenericBorderRadius; @@ -838,10 +841,10 @@ pub mod basic_shape { fn from(other: &'a nsStyleCorners) -> Self { let get_corner = |index| { BorderCornerRadius::new( - LengthOrPercentage::from_gecko_style_coord(&other.data_at(index)) - .expect(" should be a length, percentage, or calc value"), - LengthOrPercentage::from_gecko_style_coord(&other.data_at(index + 1)) - .expect(" should be a length, percentage, or calc value"), + NonNegative(LengthOrPercentage::from_gecko_style_coord(&other.data_at(index)) + .expect(" should be a length, percentage, or calc value")), + NonNegative(LengthOrPercentage::from_gecko_style_coord(&other.data_at(index + 1)) + .expect(" should be a length, percentage, or calc value")), ) }; diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 5f96b42c10a..218f150e670 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1687,8 +1687,8 @@ fn static_assert() { pub fn clone_border_image_slice(&self) -> longhands::border_image_slice::computed_value::T { use crate::gecko_bindings::structs::NS_STYLE_BORDER_IMAGE_SLICE_FILL; - use crate::values::computed::{BorderImageSlice, NumberOrPercentage}; - type NumberOrPercentageRect = crate::values::generics::rect::Rect; + use crate::values::computed::{BorderImageSlice, NonNegativeNumberOrPercentage}; + type NumberOrPercentageRect = crate::values::generics::rect::Rect; BorderImageSlice { offsets: diff --git a/components/style/properties/longhands/border.mako.rs b/components/style/properties/longhands/border.mako.rs index 5a5cdbeb552..2c304780e6d 100644 --- a/components/style/properties/longhands/border.mako.rs +++ b/components/style/properties/longhands/border.mako.rs @@ -153,14 +153,15 @@ ${helpers.predefined_type( ${helpers.predefined_type( "border-image-slice", "BorderImageSlice", - initial_value="computed::NumberOrPercentage::Percentage(computed::Percentage(1.)).into()", - initial_specified_value="specified::NumberOrPercentage::Percentage(specified::Percentage::new(1.)).into()", + initial_value="computed::BorderImageSlice::hundred_percent()", + initial_specified_value="specified::BorderImageSlice::hundred_percent()", spec="https://drafts.csswg.org/css-backgrounds/#border-image-slice", animation_value_type="discrete", flags="APPLIES_TO_FIRST_LETTER", boxed=True, )} +// FIXME(emilio): Why does this live here? ;_; #[cfg(feature = "gecko")] impl crate::values::computed::BorderImageWidth { pub fn to_gecko_rect(&self, sides: &mut crate::gecko_bindings::structs::nsStyleSides) { @@ -177,7 +178,7 @@ impl crate::values::computed::BorderImageWidth { l.to_gecko_style_coord(&mut sides.data_at_mut(${i})) }, BorderImageSideWidth::Number(n) => { - sides.data_at_mut(${i}).set_value(CoordDataValue::Factor(n)) + sides.data_at_mut(${i}).set_value(CoordDataValue::Factor(n.0)) }, } % endfor @@ -191,6 +192,7 @@ impl crate::values::computed::BorderImageWidth { use crate::gecko::values::GeckoStyleCoordConvertible; use crate::values::computed::{LengthOrPercentage, Number}; use crate::values::generics::border::BorderImageSideWidth; + use crate::values::generics::NonNegative; Some( crate::values::computed::BorderImageWidth::new( @@ -201,13 +203,13 @@ impl crate::values::computed::BorderImageWidth { }, eStyleUnit_Factor => { BorderImageSideWidth::Number( - Number::from_gecko_style_coord(&sides.data_at(${i})) - .expect("sides[${i}] could not convert to Number")) + NonNegative(Number::from_gecko_style_coord(&sides.data_at(${i})) + .expect("sides[${i}] could not convert to Number"))) }, _ => { BorderImageSideWidth::Length( - LengthOrPercentage::from_gecko_style_coord(&sides.data_at(${i})) - .expect("sides[${i}] could not convert to LengthOrPercentager")) + NonNegative(LengthOrPercentage::from_gecko_style_coord(&sides.data_at(${i})) + .expect("sides[${i}] could not convert to LengthOrPercentage"))) }, }, % endfor diff --git a/components/style/properties/longhands/inherited_text.mako.rs b/components/style/properties/longhands/inherited_text.mako.rs index f751b29ae68..5a7b88e3823 100644 --- a/components/style/properties/longhands/inherited_text.mako.rs +++ b/components/style/properties/longhands/inherited_text.mako.rs @@ -295,7 +295,7 @@ ${helpers.predefined_type( "-webkit-text-stroke-width", "BorderSideWidth", "crate::values::computed::NonNegativeLength::new(0.)", - initial_specified_value="specified::BorderSideWidth::Length(specified::Length::zero())", + initial_specified_value="specified::BorderSideWidth::zero()", computed_type="crate::values::computed::NonNegativeLength", products="gecko", gecko_pref="layout.css.prefixes.webkit", diff --git a/components/style/values/animated/mod.rs b/components/style/values/animated/mod.rs index 38de8a359a1..cf5ca94bae6 100644 --- a/components/style/values/animated/mod.rs +++ b/components/style/values/animated/mod.rs @@ -12,7 +12,6 @@ use crate::properties::PropertyId; use crate::values::computed::length::CalcLengthOrPercentage; use crate::values::computed::url::ComputedUrl; use crate::values::computed::Angle as ComputedAngle; -use crate::values::computed::BorderCornerRadius as ComputedBorderCornerRadius; use crate::values::CSSFloat; use app_units::Au; use euclid::{Point2D, Size2D}; @@ -340,23 +339,6 @@ trivial_to_animated_value!(ComputedUrl); trivial_to_animated_value!(bool); trivial_to_animated_value!(f32); -impl ToAnimatedValue for ComputedBorderCornerRadius { - type AnimatedValue = Self; - - #[inline] - fn to_animated_value(self) -> Self { - self - } - - #[inline] - fn from_animated_value(animated: Self::AnimatedValue) -> Self { - ComputedBorderCornerRadius::new( - (animated.0).0.width.clamp_to_non_negative(), - (animated.0).0.height.clamp_to_non_negative(), - ) - } -} - impl ToAnimatedZero for Au { #[inline] fn to_animated_zero(&self) -> Result { diff --git a/components/style/values/computed/basic_shape.rs b/components/style/values/computed/basic_shape.rs index 6a7b02cadcd..383c7b39bfc 100644 --- a/components/style/values/computed/basic_shape.rs +++ b/components/style/values/computed/basic_shape.rs @@ -8,7 +8,7 @@ //! [basic-shape]: https://drafts.csswg.org/css-shapes/#typedef-basic-shape use crate::values::computed::url::ComputedUrl; -use crate::values::computed::{Image, LengthOrPercentage}; +use crate::values::computed::{Image, LengthOrPercentage, NonNegativeLengthOrPercentage}; use crate::values::generics::basic_shape as generic; use std::fmt::{self, Write}; use style_traits::{CssWriter, ToCss}; @@ -24,10 +24,10 @@ pub type FloatAreaShape = generic::FloatAreaShape; /// A computed basic shape. pub type BasicShape = - generic::BasicShape; + generic::BasicShape; /// The computed value of `inset()` -pub type InsetRect = generic::InsetRect; +pub type InsetRect = generic::InsetRect; /// A computed circle. pub type Circle = generic::Circle; diff --git a/components/style/values/computed/border.rs b/components/style/values/computed/border.rs index 676e8c1b6be..09dcfbe117a 100644 --- a/components/style/values/computed/border.rs +++ b/components/style/values/computed/border.rs @@ -4,9 +4,9 @@ //! Computed types for CSS values related to borders. -use crate::values::animated::ToAnimatedZero; -use crate::values::computed::length::{LengthOrPercentage, NonNegativeLength}; -use crate::values::computed::{Number, NumberOrPercentage}; +use crate::values::generics::NonNegative; +use crate::values::computed::length::{NonNegativeLengthOrPercentage, NonNegativeLength}; +use crate::values::computed::{NonNegativeNumber, NonNegativeNumberOrPercentage}; use crate::values::generics::border::BorderCornerRadius as GenericBorderCornerRadius; use crate::values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth; use crate::values::generics::border::BorderImageSlice as GenericBorderImageSlice; @@ -22,16 +22,16 @@ pub use crate::values::specified::border::BorderImageRepeat; pub type BorderImageWidth = Rect; /// A computed value for a single side of a `border-image-width` property. -pub type BorderImageSideWidth = GenericBorderImageSideWidth; +pub type BorderImageSideWidth = GenericBorderImageSideWidth; /// A computed value for the `border-image-slice` property. -pub type BorderImageSlice = GenericBorderImageSlice; +pub type BorderImageSlice = GenericBorderImageSlice; /// A computed value for the `border-radius` property. -pub type BorderRadius = GenericBorderRadius; +pub type BorderRadius = GenericBorderRadius; /// A computed value for the `border-*-radius` longhand properties. -pub type BorderCornerRadius = GenericBorderCornerRadius; +pub type BorderCornerRadius = GenericBorderCornerRadius; /// A computed value for the `border-spacing` longhand property. pub type BorderSpacing = GenericBorderSpacing; @@ -40,7 +40,18 @@ impl BorderImageSideWidth { /// Returns `1`. #[inline] pub fn one() -> Self { - GenericBorderImageSideWidth::Number(1.) + GenericBorderImageSideWidth::Number(NonNegative(1.)) + } +} + +impl BorderImageSlice { + /// Returns the `100%` value. + #[inline] + pub fn hundred_percent() -> Self { + GenericBorderImageSlice { + offsets: Rect::all(NonNegativeNumberOrPercentage::hundred_percent()), + fill: false, + } } } @@ -68,26 +79,18 @@ impl BorderCornerRadius { /// Returns `0 0`. pub fn zero() -> Self { GenericBorderCornerRadius(Size::new( - LengthOrPercentage::zero(), - LengthOrPercentage::zero(), + NonNegativeLengthOrPercentage::zero(), + NonNegativeLengthOrPercentage::zero(), )) } } -impl ToAnimatedZero for BorderCornerRadius { - #[inline] - fn to_animated_zero(&self) -> Result { - // FIXME(nox): Why? - Err(()) - } -} - impl BorderRadius { /// Returns whether all the values are `0px`. pub fn all_zero(&self) -> bool { fn all(corner: &BorderCornerRadius) -> bool { - fn is_zero(l: &LengthOrPercentage) -> bool { - *l == LengthOrPercentage::zero() + fn is_zero(l: &NonNegativeLengthOrPercentage) -> bool { + *l == NonNegativeLengthOrPercentage::zero() } is_zero(corner.0.width()) && is_zero(corner.0.height()) } diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 93ee3e73cc1..7ee151a4078 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -543,6 +543,15 @@ pub enum NumberOrPercentage { Number(Number), } +impl NumberOrPercentage { + fn clamp_to_non_negative(self) -> Self { + match self { + NumberOrPercentage::Percentage(p) => NumberOrPercentage::Percentage(p.clamp_to_non_negative()), + NumberOrPercentage::Number(n) => NumberOrPercentage::Number(n.max(0.)), + } + } +} + impl ToComputedValue for specified::NumberOrPercentage { type ComputedValue = NumberOrPercentage; @@ -572,6 +581,31 @@ impl ToComputedValue for specified::NumberOrPercentage { } } +/// A non-negative . +pub type NonNegativeNumberOrPercentage = NonNegative; + +impl NonNegativeNumberOrPercentage { + /// Returns the `100%` value. + #[inline] + pub fn hundred_percent() -> Self { + NonNegative(NumberOrPercentage::Percentage(Percentage::hundred())) + } +} + +impl ToAnimatedValue for NonNegativeNumberOrPercentage { + type AnimatedValue = NumberOrPercentage; + + #[inline] + fn to_animated_value(self) -> Self::AnimatedValue { + self.0 + } + + #[inline] + fn from_animated_value(animated: Self::AnimatedValue) -> Self { + NonNegative(animated.clamp_to_non_negative()) + } +} + /// A type used for opacity. pub type Opacity = CSSFloat; diff --git a/components/style/values/generics/basic_shape.rs b/components/style/values/generics/basic_shape.rs index cbcdadd055f..9390de653d9 100644 --- a/components/style/values/generics/basic_shape.rs +++ b/components/style/values/generics/basic_shape.rs @@ -85,8 +85,8 @@ pub enum ShapeSource { ToComputedValue, ToCss, )] -pub enum BasicShape { - Inset(#[css(field_bound)] InsetRect), +pub enum BasicShape { + Inset(#[css(field_bound)] InsetRect), Circle(#[css(field_bound)] Circle), Ellipse(#[css(field_bound)] Ellipse), Polygon(Polygon), @@ -105,9 +105,9 @@ pub enum BasicShape { SpecifiedValueInfo, ToComputedValue, )] -pub struct InsetRect { +pub struct InsetRect { pub rect: Rect, - pub round: Option>, + pub round: Option>, } /// @@ -258,9 +258,10 @@ impl ToAnimatedZero for ShapeSource { } } -impl ToCss for InsetRect +impl ToCss for InsetRect where - L: ToCss + PartialEq, + Length: ToCss + PartialEq, + NonNegativeLength: ToCss + PartialEq, { fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where diff --git a/components/style/values/generics/border.rs b/components/style/values/generics/border.rs index 0a50721bcda..eb651377e0d 100644 --- a/components/style/values/generics/border.rs +++ b/components/style/values/generics/border.rs @@ -45,6 +45,8 @@ pub struct BorderImageSlice { MallocSizeOf, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, + ToAnimatedZero, ToComputedValue, ToCss, )] @@ -106,19 +108,6 @@ pub struct BorderRadius { pub bottom_left: BorderCornerRadius, } -impl From for BorderImageSlice -where - N: Clone, -{ - #[inline] - fn from(value: N) -> Self { - Self { - offsets: Rect::all(value), - fill: false, - } - } -} - impl BorderRadius { /// Returns a new `BorderRadius`. #[inline] diff --git a/components/style/values/specified/basic_shape.rs b/components/style/values/specified/basic_shape.rs index 981cad00aaa..2f1f510372c 100644 --- a/components/style/values/specified/basic_shape.rs +++ b/components/style/values/specified/basic_shape.rs @@ -16,7 +16,7 @@ use crate::values::specified::border::BorderRadius; use crate::values::specified::image::Image; use crate::values::specified::position::{HorizontalPosition, Position, VerticalPosition}; use crate::values::specified::url::SpecifiedUrl; -use crate::values::specified::LengthOrPercentage; +use crate::values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage}; use crate::values::specified::SVGPathData; use cssparser::Parser; use std::fmt::{self, Write}; @@ -32,10 +32,10 @@ pub type ClippingShape = generic::ClippingShape; pub type FloatAreaShape = generic::FloatAreaShape; /// A specified basic shape. -pub type BasicShape = generic::BasicShape; +pub type BasicShape = generic::BasicShape; /// The specified value of `inset()` -pub type InsetRect = generic::InsetRect; +pub type InsetRect = generic::InsetRect; /// A specified circle. pub type Circle = generic::Circle; @@ -199,10 +199,7 @@ impl InsetRect { } else { None }; - Ok(generic::InsetRect { - rect: rect, - round: round, - }) + Ok(generic::InsetRect { rect, round }) } } diff --git a/components/style/values/specified/border.rs b/components/style/values/specified/border.rs index cf60c91b329..ee0b491f027 100644 --- a/components/style/values/specified/border.rs +++ b/components/style/values/specified/border.rs @@ -13,8 +13,8 @@ use crate::values::generics::border::BorderRadius as GenericBorderRadius; use crate::values::generics::border::BorderSpacing as GenericBorderSpacing; use crate::values::generics::rect::Rect; use crate::values::generics::size::Size; -use crate::values::specified::length::{Length, LengthOrPercentage, NonNegativeLength}; -use crate::values::specified::{AllowQuirks, Number, NumberOrPercentage}; +use crate::values::specified::length::{NonNegativeLengthOrPercentage, NonNegativeLength}; +use crate::values::specified::{AllowQuirks, NonNegativeNumber, NonNegativeNumberOrPercentage}; use cssparser::Parser; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, ToCss}; @@ -71,28 +71,45 @@ pub enum BorderSideWidth { /// `thick` Thick, /// `` - Length(Length), + Length(NonNegativeLength), } /// A specified value for the `border-image-width` property. pub type BorderImageWidth = Rect; /// A specified value for a single side of a `border-image-width` property. -pub type BorderImageSideWidth = GenericBorderImageSideWidth; +pub type BorderImageSideWidth = GenericBorderImageSideWidth; /// A specified value for the `border-image-slice` property. -pub type BorderImageSlice = GenericBorderImageSlice; +pub type BorderImageSlice = GenericBorderImageSlice; /// A specified value for the `border-radius` property. -pub type BorderRadius = GenericBorderRadius; +pub type BorderRadius = GenericBorderRadius; /// A specified value for the `border-*-radius` longhand properties. -pub type BorderCornerRadius = GenericBorderCornerRadius; +pub type BorderCornerRadius = GenericBorderCornerRadius; /// A specified value for the `border-spacing` longhand properties. pub type BorderSpacing = GenericBorderSpacing; +impl BorderImageSlice { + /// Returns the `100%` value. + #[inline] + pub fn hundred_percent() -> Self { + GenericBorderImageSlice { + offsets: Rect::all(NonNegativeNumberOrPercentage::hundred_percent()), + fill: false, + } + } +} + impl BorderSideWidth { + /// Returns the `0px` value. + #[inline] + pub fn zero() -> Self { + BorderSideWidth::Length(NonNegativeLength::zero()) + } + /// Parses, with quirks. pub fn parse_quirky<'i, 't>( context: &ParserContext, @@ -100,7 +117,7 @@ impl BorderSideWidth { allow_quirks: AllowQuirks, ) -> Result> { if let Ok(length) = - input.try(|i| Length::parse_non_negative_quirky(context, i, allow_quirks)) + input.try(|i| NonNegativeLength::parse_quirky(context, i, allow_quirks)) { return Ok(BorderSideWidth::Length(length)); } @@ -130,9 +147,9 @@ impl ToComputedValue for BorderSideWidth { // Spec: https://drafts.csswg.org/css-backgrounds-3/#line-width // Gecko: https://bugzilla.mozilla.org/show_bug.cgi?id=1312155#c0 match *self { - BorderSideWidth::Thin => Length::from_px(1.).to_computed_value(context), - BorderSideWidth::Medium => Length::from_px(3.).to_computed_value(context), - BorderSideWidth::Thick => Length::from_px(5.).to_computed_value(context), + BorderSideWidth::Thin => NonNegativeLength::from_px(1.).to_computed_value(context), + BorderSideWidth::Medium => NonNegativeLength::from_px(3.).to_computed_value(context), + BorderSideWidth::Thick => NonNegativeLength::from_px(5.).to_computed_value(context), BorderSideWidth::Length(ref length) => length.to_computed_value(context), } .into() @@ -140,7 +157,7 @@ impl ToComputedValue for BorderSideWidth { #[inline] fn from_computed_value(computed: &Self::ComputedValue) -> Self { - BorderSideWidth::Length(ToComputedValue::from_computed_value(&computed.0)) + BorderSideWidth::Length(ToComputedValue::from_computed_value(computed)) } } @@ -148,7 +165,7 @@ impl BorderImageSideWidth { /// Returns `1`. #[inline] pub fn one() -> Self { - GenericBorderImageSideWidth::Number(Number::new(1.)) + GenericBorderImageSideWidth::Number(NonNegativeNumber::new(1.)) } } @@ -161,11 +178,11 @@ impl Parse for BorderImageSideWidth { return Ok(GenericBorderImageSideWidth::Auto); } - if let Ok(len) = input.try(|i| LengthOrPercentage::parse_non_negative(context, i)) { + if let Ok(len) = input.try(|i| NonNegativeLengthOrPercentage::parse(context, i)) { return Ok(GenericBorderImageSideWidth::Length(len)); } - let num = Number::parse_non_negative(context, input)?; + let num = NonNegativeNumber::parse(context, input)?; Ok(GenericBorderImageSideWidth::Number(num)) } } @@ -176,14 +193,11 @@ impl Parse for BorderImageSlice { input: &mut Parser<'i, 't>, ) -> Result> { let mut fill = input.try(|i| i.expect_ident_matching("fill")).is_ok(); - let offsets = Rect::parse_with(context, input, NumberOrPercentage::parse_non_negative)?; + let offsets = Rect::parse_with(context, input, NonNegativeNumberOrPercentage::parse)?; if !fill { fill = input.try(|i| i.expect_ident_matching("fill")).is_ok(); } - Ok(GenericBorderImageSlice { - offsets: offsets, - fill: fill, - }) + Ok(GenericBorderImageSlice { offsets, fill }) } } @@ -192,9 +206,9 @@ impl Parse for BorderRadius { context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - let widths = Rect::parse_with(context, input, LengthOrPercentage::parse_non_negative)?; + let widths = Rect::parse_with(context, input, NonNegativeLengthOrPercentage::parse)?; let heights = if input.try(|i| i.expect_delim('/')).is_ok() { - Rect::parse_with(context, input, LengthOrPercentage::parse_non_negative)? + Rect::parse_with(context, input, NonNegativeLengthOrPercentage::parse)? } else { widths.clone() }; @@ -213,7 +227,7 @@ impl Parse for BorderCornerRadius { context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - Size::parse_with(context, input, LengthOrPercentage::parse_non_negative) + Size::parse_with(context, input, NonNegativeLengthOrPercentage::parse) .map(GenericBorderCornerRadius) } } @@ -224,7 +238,7 @@ impl Parse for BorderSpacing { input: &mut Parser<'i, 't>, ) -> Result> { Size::parse_with(context, input, |context, input| { - Length::parse_non_negative_quirky(context, input, AllowQuirks::Yes).map(From::from) + NonNegativeLength::parse_quirky(context, input, AllowQuirks::Yes).map(From::from) }) .map(GenericBorderSpacing) } diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 13877dbe594..db5a359cacd 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -717,6 +717,16 @@ impl NonNegativeLength { pub fn from_px(px_value: CSSFloat) -> Self { Length::from_px(px_value.max(0.)).into() } + + /// Parses a non-negative length, optionally with quirks. + #[inline] + pub fn parse_quirky<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + allow_quirks: AllowQuirks, + ) -> Result> { + Ok(NonNegative(Length::parse_non_negative_quirky(context, input, allow_quirks)?)) + } } /// Either a NonNegativeLength or the `auto` keyword. diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index d3df66a0eea..a73252bbeb6 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -359,6 +359,26 @@ impl Parse for NumberOrPercentage { } } +/// A non-negative | . +pub type NonNegativeNumberOrPercentage = NonNegative; + +impl NonNegativeNumberOrPercentage { + /// Returns the `100%` value. + #[inline] + pub fn hundred_percent() -> Self { + NonNegative(NumberOrPercentage::Percentage(Percentage::hundred())) + } +} + +impl Parse for NonNegativeNumberOrPercentage { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + Ok(NonNegative(NumberOrPercentage::parse_non_negative(context, input)?)) + } +} + #[allow(missing_docs)] #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, SpecifiedValueInfo, ToCss)] pub struct Opacity(Number); From 3ed525f6c998977853fb266747a99d9c38aa907e Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Tue, 18 Dec 2018 18:47:35 +0000 Subject: [PATCH 06/27] style: Use cbindgen for ExtremumLength. ExtremumLength is the keyword type for css sizing properties, so we could use cbindgen. In Gecko, we use nsStyleCoord to store the sizing properties, and use integer values to check the enum values, so I keep the macros in nsStyleConsts. Even though we need to convert the enum type into integer, we still have benefits to reduce the complexity of converting Rust into C++, and leave the simplified mappings in C++ for better readability. Differential Revision: https://phabricator.services.mozilla.com/D7535 --- components/style/cbindgen.toml | 1 + components/style/gecko/values.rs | 33 ++-------------------- components/style/values/computed/length.rs | 2 ++ 3 files changed, 6 insertions(+), 30 deletions(-) diff --git a/components/style/cbindgen.toml b/components/style/cbindgen.toml index 6005126fb27..27ad7bc80a1 100644 --- a/components/style/cbindgen.toml +++ b/components/style/cbindgen.toml @@ -50,6 +50,7 @@ include = [ "ComputedTimingFunction", "Display", "DisplayMode", + "ExtremumLength", "FillRule", "FontDisplay", "FontFaceSourceListComponent", diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index 59ccd0afeca..8006d50925f 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -362,40 +362,13 @@ impl GeckoStyleCoordConvertible for Normal { impl GeckoStyleCoordConvertible for ExtremumLength { fn to_gecko_style_coord(&self, coord: &mut T) { - use crate::gecko_bindings::structs::{ - NS_STYLE_WIDTH_AVAILABLE, NS_STYLE_WIDTH_FIT_CONTENT, - }; - use crate::gecko_bindings::structs::{ - NS_STYLE_WIDTH_MAX_CONTENT, NS_STYLE_WIDTH_MIN_CONTENT, - }; - coord.set_value(CoordDataValue::Enumerated(match *self { - ExtremumLength::MozMaxContent => NS_STYLE_WIDTH_MAX_CONTENT, - ExtremumLength::MozMinContent => NS_STYLE_WIDTH_MIN_CONTENT, - ExtremumLength::MozFitContent => NS_STYLE_WIDTH_FIT_CONTENT, - ExtremumLength::MozAvailable => NS_STYLE_WIDTH_AVAILABLE, - })) + coord.set_value(CoordDataValue::Enumerated(*self as u32)); } fn from_gecko_style_coord(coord: &T) -> Option { - use crate::gecko_bindings::structs::{ - NS_STYLE_WIDTH_AVAILABLE, NS_STYLE_WIDTH_FIT_CONTENT, - }; - use crate::gecko_bindings::structs::{ - NS_STYLE_WIDTH_MAX_CONTENT, NS_STYLE_WIDTH_MIN_CONTENT, - }; + use num_traits::FromPrimitive; match coord.as_value() { - CoordDataValue::Enumerated(NS_STYLE_WIDTH_MAX_CONTENT) => { - Some(ExtremumLength::MozMaxContent) - }, - CoordDataValue::Enumerated(NS_STYLE_WIDTH_MIN_CONTENT) => { - Some(ExtremumLength::MozMinContent) - }, - CoordDataValue::Enumerated(NS_STYLE_WIDTH_FIT_CONTENT) => { - Some(ExtremumLength::MozFitContent) - }, - CoordDataValue::Enumerated(NS_STYLE_WIDTH_AVAILABLE) => { - Some(ExtremumLength::MozAvailable) - }, + CoordDataValue::Enumerated(v) => ExtremumLength::from_u32(v), _ => None, } } diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 96886e9096a..7592c3a2cae 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -975,6 +975,7 @@ pub type NonNegativeLengthOrPercentageOrNormal = Either Date: Tue, 18 Dec 2018 18:47:37 +0000 Subject: [PATCH 07/27] style: Support unprefixed min-content and max-content. Support unprefixed min-content and max-content and treat the prefixed version as aliases for 1. width, min-width, max-width if inline-axis is horizontal, and 2. height, min-height, max-height if inline-axis is vertical, and 3. inline-size, min-inline-size, max-inline-size, and 4. flex-basis. Besides, update the test cases to use unprefixed max-content and min-content. Differential Revision: https://phabricator.services.mozilla.com/D7536 --- components/style/values/computed/length.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 7592c3a2cae..240b5ceb1ee 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -985,8 +985,10 @@ pub type NonNegativeLengthOrPercentageOrNormal = Either Date: Tue, 18 Dec 2018 18:47:39 +0000 Subject: [PATCH 08/27] style: Let logical height, block-size, accept keywords. We should let block-size/min-block-size/max-block-size accept keywords as the initial value, just like width in vertical writing mode or height in horizontal writing mode. Differential Revision: https://phabricator.services.mozilla.com/D14320 --- .../properties/longhands/position.mako.rs | 11 ---------- components/style/values/specified/length.rs | 22 ------------------- 2 files changed, 33 deletions(-) diff --git a/components/style/properties/longhands/position.mako.rs b/components/style/properties/longhands/position.mako.rs index c5e507da10e..53a3acf81ec 100644 --- a/components/style/properties/longhands/position.mako.rs +++ b/components/style/properties/longhands/position.mako.rs @@ -244,21 +244,12 @@ ${helpers.predefined_type( if logical: spec = "https://drafts.csswg.org/css-logical-props/#propdef-%s" %> - // NOTE: Block-size doesn't support -moz-*-content keywords, since they make - // no sense on the block axis, but it simplifies things the have that it has - // the same type as the other properties, since otherwise we'd need to - // handle logical props where the types are different, which looks like a - // pain. % if product == "gecko": - <% - parse_function = "parse" if size != "block-size" else "parse_disallow_keyword" - %> // width, height, block-size, inline-size ${helpers.predefined_type( size, "MozLength", "computed::MozLength::auto()", - parse_function, logical=logical, logical_group="size", allow_quirks=not logical, @@ -272,7 +263,6 @@ ${helpers.predefined_type( "min-%s" % size, "MozLength", "computed::MozLength::auto()", - parse_function, logical=logical, logical_group="min-size", allow_quirks=not logical, @@ -284,7 +274,6 @@ ${helpers.predefined_type( "max-%s" % size, "MaxLength", "computed::MaxLength::none()", - parse_function, logical=logical, logical_group="max-size", allow_quirks=not logical, diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index db5a359cacd..dce643a754f 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -1256,17 +1256,6 @@ impl Parse for MozLength { } impl MozLength { - /// Parses, without quirks, and disallowing ExtremumLength values. - /// - /// Used for logical props in the block direction. - pub fn parse_disallow_keyword<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - let length = LengthOrPercentageOrAuto::parse_non_negative(context, input)?; - Ok(GenericMozLength::LengthOrPercentageOrAuto(length)) - } - /// Parses, with quirks. pub fn parse_quirky<'i, 't>( context: &ParserContext, @@ -1308,17 +1297,6 @@ impl Parse for MaxLength { } impl MaxLength { - /// Parses, without quirks, and disallowing ExtremumLength values. - /// - /// Used for logical props in the block direction. - pub fn parse_disallow_keyword<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - let length = LengthOrPercentageOrNone::parse_non_negative(context, input)?; - Ok(GenericMaxLength::LengthOrPercentageOrNone(length)) - } - /// Parses, with quirks. pub fn parse_quirky<'i, 't>( context: &ParserContext, From f0f3eb31949a98d3ceabac545b531d8c278dc31f Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Wed, 19 Dec 2018 19:08:08 +0000 Subject: [PATCH 09/27] style: Clamp to non-negative value after doing interpolation for circle(), ellipse(), and inset(). Replace LengthOrPercentage with NonNegativeLengthOrPercentage on ShapeRadius, Circle, Ellipse. And derive ToAnimatedValue for ShapeSource and its related types, so we clamp its interpolated results into non-negative values. (i.e. The radius of circle()/ellipse() and the border-radius of inset().) Note: We may get negative values when using a negative easing function, so the clamp is necessary to avoid the incorrect result or any undefined behavior. Differential Revision: https://phabricator.services.mozilla.com/D14654 --- components/style/gecko/values.rs | 4 +- .../style/properties/longhands/box.mako.rs | 2 +- .../style/properties/longhands/svg.mako.rs | 2 +- components/style/values/animated/mod.rs | 15 ++++ .../style/values/computed/basic_shape.rs | 16 ++-- .../style/values/generics/basic_shape.rs | 78 +++++++++++++++---- components/style/values/generics/border.rs | 1 + components/style/values/generics/position.rs | 1 + components/style/values/generics/rect.rs | 1 + .../style/values/specified/basic_shape.rs | 17 ++-- 10 files changed, 110 insertions(+), 27 deletions(-) diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index 8006d50925f..b22f68cd05d 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -286,7 +286,9 @@ impl GeckoStyleCoordConvertible for ComputedShapeRadius { None } }, - _ => LengthOrPercentage::from_gecko_style_coord(coord).map(ShapeRadius::Length), + _ => { + GeckoStyleCoordConvertible::from_gecko_style_coord(coord).map(ShapeRadius::Length) + }, } } } diff --git a/components/style/properties/longhands/box.mako.rs b/components/style/properties/longhands/box.mako.rs index e8946c3206e..7eb6ff0028d 100644 --- a/components/style/properties/longhands/box.mako.rs +++ b/components/style/properties/longhands/box.mako.rs @@ -627,7 +627,7 @@ ${helpers.predefined_type( "generics::basic_shape::ShapeSource::None", products="gecko", boxed=True, - animation_value_type="ComputedValue", + animation_value_type="basic_shape::FloatAreaShape", flags="APPLIES_TO_FIRST_LETTER", spec="https://drafts.csswg.org/css-shapes/#shape-outside-property", )} diff --git a/components/style/properties/longhands/svg.mako.rs b/components/style/properties/longhands/svg.mako.rs index d6e76f6f1f6..43a8952d86e 100644 --- a/components/style/properties/longhands/svg.mako.rs +++ b/components/style/properties/longhands/svg.mako.rs @@ -88,7 +88,7 @@ ${helpers.predefined_type( "generics::basic_shape::ShapeSource::None", products="gecko", boxed=True, - animation_value_type="ComputedValue", + animation_value_type="basic_shape::ClippingShape", flags="CREATES_STACKING_CONTEXT", spec="https://drafts.fxtf.org/css-masking/#propdef-clip-path", )} diff --git a/components/style/values/animated/mod.rs b/components/style/values/animated/mod.rs index cf5ca94bae6..bd0a7af1f95 100644 --- a/components/style/values/animated/mod.rs +++ b/components/style/values/animated/mod.rs @@ -12,7 +12,9 @@ use crate::properties::PropertyId; use crate::values::computed::length::CalcLengthOrPercentage; use crate::values::computed::url::ComputedUrl; use crate::values::computed::Angle as ComputedAngle; +use crate::values::computed::Image; use crate::values::CSSFloat; +use crate::values::specified::SVGPathData; use app_units::Au; use euclid::{Point2D, Size2D}; use smallvec::SmallVec; @@ -338,6 +340,19 @@ trivial_to_animated_value!(ComputedAngle); trivial_to_animated_value!(ComputedUrl); trivial_to_animated_value!(bool); trivial_to_animated_value!(f32); +// Note: This implementation is for ToAnimatedValue of ShapeSource. +// +// SVGPathData uses Box<[T]>. If we want to derive ToAnimatedValue for all the +// types, we have to do "impl ToAnimatedValue for Box<[T]>" first. +// However, the general version of "impl ToAnimatedValue for Box<[T]>" needs to +// clone |T| and convert it into |T::AnimatedValue|. However, for SVGPathData +// that is unnecessary--moving |T| is sufficient. So here, we implement this +// trait manually. +trivial_to_animated_value!(SVGPathData); +// FIXME: Bug 1514342, Image is not animatable, but we still need to implement +// this to avoid adding this derive to generic::Image and all its arms. We can +// drop this after landing Bug 1514342. +trivial_to_animated_value!(Image); impl ToAnimatedZero for Au { #[inline] diff --git a/components/style/values/computed/basic_shape.rs b/components/style/values/computed/basic_shape.rs index 383c7b39bfc..f808e0bf9f5 100644 --- a/components/style/values/computed/basic_shape.rs +++ b/components/style/values/computed/basic_shape.rs @@ -23,20 +23,26 @@ pub type ClippingShape = generic::ClippingShape; pub type FloatAreaShape = generic::FloatAreaShape; /// A computed basic shape. -pub type BasicShape = - generic::BasicShape; +pub type BasicShape = generic::BasicShape< + LengthOrPercentage, + LengthOrPercentage, + LengthOrPercentage, + NonNegativeLengthOrPercentage, +>; /// The computed value of `inset()` pub type InsetRect = generic::InsetRect; /// A computed circle. -pub type Circle = generic::Circle; +pub type Circle = + generic::Circle; /// A computed ellipse. -pub type Ellipse = generic::Ellipse; +pub type Ellipse = + generic::Ellipse; /// The computed value of `ShapeRadius` -pub type ShapeRadius = generic::ShapeRadius; +pub type ShapeRadius = generic::ShapeRadius; impl ToCss for Circle { fn to_css(&self, dest: &mut CssWriter) -> fmt::Result diff --git a/components/style/values/generics/basic_shape.rs b/components/style/values/generics/basic_shape.rs index 9390de653d9..bfe709ceb4b 100644 --- a/components/style/values/generics/basic_shape.rs +++ b/components/style/values/generics/basic_shape.rs @@ -20,7 +20,16 @@ pub type ClippingShape = ShapeSource #[allow(missing_docs)] #[derive( - Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, + Animate, + Clone, + Copy, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, )] pub enum GeometryBox { FillBox, @@ -45,6 +54,7 @@ pub type FloatAreaShape = ShapeSource { #[animation(error)] @@ -82,13 +100,14 @@ pub enum ShapeSource { MallocSizeOf, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToComputedValue, ToCss, )] pub enum BasicShape { Inset(#[css(field_bound)] InsetRect), - Circle(#[css(field_bound)] Circle), - Ellipse(#[css(field_bound)] Ellipse), + Circle(#[css(field_bound)] Circle), + Ellipse(#[css(field_bound)] Ellipse), Polygon(Polygon), } @@ -103,6 +122,7 @@ pub enum BasicShape { MallocSizeOf, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToComputedValue, )] pub struct InsetRect { @@ -122,11 +142,12 @@ pub struct InsetRect { MallocSizeOf, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToComputedValue, )] -pub struct Circle { +pub struct Circle { pub position: Position, - pub radius: ShapeRadius, + pub radius: ShapeRadius, } /// @@ -141,12 +162,13 @@ pub struct Circle { MallocSizeOf, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToComputedValue, )] -pub struct Ellipse { +pub struct Ellipse { pub position: Position, - pub semiaxis_x: ShapeRadius, - pub semiaxis_y: ShapeRadius, + pub semiaxis_x: ShapeRadius, + pub semiaxis_y: ShapeRadius, } /// @@ -160,11 +182,12 @@ pub struct Ellipse { MallocSizeOf, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToComputedValue, ToCss, )] -pub enum ShapeRadius { - Length(LengthOrPercentage), +pub enum ShapeRadius { + Length(NonNegativeLengthOrPercentage), #[animation(error)] ClosestSide, #[animation(error)] @@ -175,7 +198,16 @@ pub enum ShapeRadius { /// /// #[css(comma, function)] -#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] +#[derive( + Clone, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, +)] pub struct Polygon { /// The filling rule for a polygon. #[css(skip_if = "fill_is_default")] @@ -186,7 +218,16 @@ pub struct Polygon { } /// Coordinates for Polygon. -#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] +#[derive( + Clone, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, +)] pub struct PolygonCoord(pub LengthOrPercentage, pub LengthOrPercentage); // https://drafts.csswg.org/css-shapes/#typedef-fill-rule @@ -204,6 +245,7 @@ pub struct PolygonCoord(pub LengthOrPercentage, pub LengthOr Parse, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToComputedValue, ToCss, )] @@ -218,7 +260,15 @@ pub enum FillRule { /// https://drafts.csswg.org/css-shapes-2/#funcdef-path #[css(comma)] #[derive( - Animate, Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, + Animate, + Clone, + Debug, + MallocSizeOf, + PartialEq, + SpecifiedValueInfo, + ToAnimatedValue, + ToComputedValue, + ToCss, )] pub struct Path { /// The filling rule for the svg path. diff --git a/components/style/values/generics/border.rs b/components/style/values/generics/border.rs index eb651377e0d..20274816615 100644 --- a/components/style/values/generics/border.rs +++ b/components/style/values/generics/border.rs @@ -95,6 +95,7 @@ impl BorderSpacing { MallocSizeOf, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToComputedValue, )] pub struct BorderRadius { diff --git a/components/style/values/generics/position.rs b/components/style/values/generics/position.rs index 0bde0067def..07612913c0a 100644 --- a/components/style/values/generics/position.rs +++ b/components/style/values/generics/position.rs @@ -15,6 +15,7 @@ MallocSizeOf, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToAnimatedZero, ToComputedValue, )] diff --git a/components/style/values/generics/rect.rs b/components/style/values/generics/rect.rs index dfffb3a4834..985a9c4a320 100644 --- a/components/style/values/generics/rect.rs +++ b/components/style/values/generics/rect.rs @@ -20,6 +20,7 @@ use style_traits::{CssWriter, ParseError, ToCss}; MallocSizeOf, PartialEq, SpecifiedValueInfo, + ToAnimatedValue, ToComputedValue, )] pub struct Rect(pub T, pub T, pub T, pub T); diff --git a/components/style/values/specified/basic_shape.rs b/components/style/values/specified/basic_shape.rs index 2f1f510372c..20c7ad6eeb4 100644 --- a/components/style/values/specified/basic_shape.rs +++ b/components/style/values/specified/basic_shape.rs @@ -32,19 +32,26 @@ pub type ClippingShape = generic::ClippingShape; pub type FloatAreaShape = generic::FloatAreaShape; /// A specified basic shape. -pub type BasicShape = generic::BasicShape; +pub type BasicShape = generic::BasicShape< + HorizontalPosition, + VerticalPosition, + LengthOrPercentage, + NonNegativeLengthOrPercentage, +>; /// The specified value of `inset()` pub type InsetRect = generic::InsetRect; /// A specified circle. -pub type Circle = generic::Circle; +pub type Circle = + generic::Circle; /// A specified ellipse. -pub type Ellipse = generic::Ellipse; +pub type Ellipse = + generic::Ellipse; /// The specified value of `ShapeRadius` -pub type ShapeRadius = generic::ShapeRadius; +pub type ShapeRadius = generic::ShapeRadius; /// The specified value of `Polygon` pub type Polygon = generic::Polygon; @@ -309,7 +316,7 @@ impl Parse for ShapeRadius { context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - if let Ok(lop) = input.try(|i| LengthOrPercentage::parse_non_negative(context, i)) { + if let Ok(lop) = input.try(|i| NonNegativeLengthOrPercentage::parse(context, i)) { return Ok(generic::ShapeRadius::Length(lop)); } From 7b444182febacb13424e318a56eb761b103087d8 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Thu, 20 Dec 2018 01:49:42 +0000 Subject: [PATCH 10/27] style: Bump smallvec and smallbitvec. Differential Revision: https://phabricator.services.mozilla.com/D15052 --- components/malloc_size_of/Cargo.toml | 2 +- components/style/Cargo.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/malloc_size_of/Cargo.toml b/components/malloc_size_of/Cargo.toml index 22840c89d8a..92b3db44c15 100644 --- a/components/malloc_size_of/Cargo.toml +++ b/components/malloc_size_of/Cargo.toml @@ -37,7 +37,7 @@ selectors = { path = "../selectors" } serde = { version = "1.0.27", optional = true } serde_bytes = { version = "0.10", optional = true } servo_arc = { path = "../servo_arc" } -smallbitvec = "2.1.0" +smallbitvec = "2.3.0" smallvec = "0.6" string_cache = { version = "0.7", optional = true } thin-slice = "0.1.0" diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index 9ae935c0e4d..17612eff900 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -60,8 +60,8 @@ serde = {version = "1.0", optional = true, features = ["derive"]} servo_arc = { path = "../servo_arc" } servo_atoms = {path = "../atoms", optional = true} servo_config = {path = "../config", optional = true} -smallbitvec = "2.1.1" -smallvec = "0.6" +smallbitvec = "2.3.0" +smallvec = "0.6.6" string_cache = { version = "0.7", optional = true } style_derive = {path = "../style_derive"} style_traits = {path = "../style_traits"} From 8a6230e5a23ae9185e8d4b2575feceeb85ee4c67 Mon Sep 17 00:00:00 2001 From: sharath Date: Mon, 24 Dec 2018 15:28:11 +0000 Subject: [PATCH 11/27] style: changes to implement enum class for #define NS_STYLE_COLOR_ADJUST. Differential Revision: https://phabricator.services.mozilla.com/D15284 --- components/style/properties/longhands/inherited_box.mako.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/components/style/properties/longhands/inherited_box.mako.rs b/components/style/properties/longhands/inherited_box.mako.rs index 65d5727f11a..aaa6815179c 100644 --- a/components/style/properties/longhands/inherited_box.mako.rs +++ b/components/style/properties/longhands/inherited_box.mako.rs @@ -54,6 +54,7 @@ ${helpers.single_keyword( ${helpers.single_keyword( "color-adjust", "economy exact", products="gecko", + gecko_enum_prefix="StyleColorAdjust", gecko_pref="layout.css.color-adjust.enabled", animation_value_type="discrete", spec="https://drafts.csswg.org/css-color/#propdef-color-adjust", From 8929087d8365d2e57dc446f25ee18ac4139c4e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 25 Dec 2018 23:09:29 +0000 Subject: [PATCH 12/27] style: Update the Rust target version for bindgen. This brings us alignas support and also associated constants for bitfield enums. Differential Revision: https://phabricator.services.mozilla.com/D15334 --- components/style/build_gecko.rs | 4 +- .../gecko/pseudo_element_definition.mako.rs | 4 +- components/style/gecko/restyle_damage.rs | 2 +- components/style/gecko/wrapper.rs | 7 +--- .../gecko_bindings/sugar/origin_flags.rs | 9 ++--- .../invalidation/element/restyle_hints.rs | 37 ++++++++----------- components/style/properties/gecko.mako.rs | 3 +- 7 files changed, 26 insertions(+), 40 deletions(-) diff --git a/components/style/build_gecko.rs b/components/style/build_gecko.rs index 9b627a4a82e..734d09569f5 100644 --- a/components/style/build_gecko.rs +++ b/components/style/build_gecko.rs @@ -139,7 +139,9 @@ mod bindings { // Disable rust unions, because we replace some types inside of // them. - let mut builder = Builder::default().rust_target(RustTarget::Stable_1_0); + let mut builder = Builder::default() + .rust_target(RustTarget::Stable_1_25) + .disable_untagged_union(); let rustfmt_path = env::var_os("RUSTFMT") // This can be replaced with diff --git a/components/style/gecko/pseudo_element_definition.mako.rs b/components/style/gecko/pseudo_element_definition.mako.rs index aaa3d7c8c99..613bbd281ee 100644 --- a/components/style/gecko/pseudo_element_definition.mako.rs +++ b/components/style/gecko/pseudo_element_definition.mako.rs @@ -156,8 +156,6 @@ impl PseudoElement { /// Construct a `CSSPseudoElementType` from a pseudo-element #[inline] fn pseudo_type(&self) -> CSSPseudoElementType { - use crate::gecko_bindings::structs::CSSPseudoElementType_InheritingAnonBox; - match *self { % for pseudo in PSEUDOS: % if not pseudo.is_anon_box(): @@ -165,7 +163,7 @@ impl PseudoElement { % elif pseudo.is_tree_pseudo_element(): PseudoElement::${pseudo.capitalized_pseudo()}(..) => CSSPseudoElementType::XULTree, % elif pseudo.is_inheriting_anon_box(): - PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType_InheritingAnonBox, + PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::InheritingAnonBox, % else: PseudoElement::${pseudo.capitalized_pseudo()} => CSSPseudoElementType::NonInheritingAnonBox, % endif diff --git a/components/style/gecko/restyle_damage.rs b/components/style/gecko/restyle_damage.rs index b2b14b413e3..9c9d07b7112 100644 --- a/components/style/gecko/restyle_damage.rs +++ b/components/style/gecko/restyle_damage.rs @@ -83,7 +83,7 @@ impl GeckoRestyleDamage { /// Gets restyle damage to reconstruct the entire frame, subsuming all /// other damage. pub fn reconstruct() -> Self { - GeckoRestyleDamage(structs::nsChangeHint_nsChangeHint_ReconstructFrame) + GeckoRestyleDamage(structs::nsChangeHint::nsChangeHint_ReconstructFrame) } } diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 0768e9e26af..1340a005d74 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -1501,9 +1501,6 @@ impl<'le> TElement for GeckoElement<'le> { /// Process various tasks that are a result of animation-only restyle. fn process_post_animation(&self, tasks: PostAnimationTasks) { - use crate::gecko_bindings::structs::nsChangeHint_nsChangeHint_Empty; - use crate::gecko_bindings::structs::nsRestyleHint_eRestyle_Subtree; - debug_assert!(!tasks.is_empty(), "Should be involved a task"); // If display style was changed from none to other, we need to resolve @@ -1519,8 +1516,8 @@ impl<'le> TElement for GeckoElement<'le> { ); unsafe { self.note_explicit_hints( - nsRestyleHint_eRestyle_Subtree, - nsChangeHint_nsChangeHint_Empty, + nsRestyleHint::eRestyle_Subtree, + nsChangeHint::nsChangeHint_Empty, ); } } diff --git a/components/style/gecko_bindings/sugar/origin_flags.rs b/components/style/gecko_bindings/sugar/origin_flags.rs index b7250b53930..409b145f1e9 100644 --- a/components/style/gecko_bindings/sugar/origin_flags.rs +++ b/components/style/gecko_bindings/sugar/origin_flags.rs @@ -5,17 +5,14 @@ //! Helper to iterate over `OriginFlags` bits. use crate::gecko_bindings::structs::OriginFlags; -use crate::gecko_bindings::structs::OriginFlags_Author; -use crate::gecko_bindings::structs::OriginFlags_User; -use crate::gecko_bindings::structs::OriginFlags_UserAgent; use crate::stylesheets::OriginSet; /// Checks that the values for OriginFlags are the ones we expect. pub fn assert_flags_match() { use crate::stylesheets::origin::*; - debug_assert_eq!(OriginFlags_UserAgent.0, OriginSet::ORIGIN_USER_AGENT.bits()); - debug_assert_eq!(OriginFlags_Author.0, OriginSet::ORIGIN_AUTHOR.bits()); - debug_assert_eq!(OriginFlags_User.0, OriginSet::ORIGIN_USER.bits()); + debug_assert_eq!(OriginFlags::UserAgent.0, OriginSet::ORIGIN_USER_AGENT.bits()); + debug_assert_eq!(OriginFlags::Author.0, OriginSet::ORIGIN_AUTHOR.bits()); + debug_assert_eq!(OriginFlags::User.0, OriginSet::ORIGIN_USER.bits()); } impl From for OriginSet { diff --git a/components/style/invalidation/element/restyle_hints.rs b/components/style/invalidation/element/restyle_hints.rs index 1d8a7f5bd14..2cb8e222e46 100644 --- a/components/style/invalidation/element/restyle_hints.rs +++ b/components/style/invalidation/element/restyle_hints.rs @@ -193,38 +193,31 @@ impl Default for RestyleHint { #[cfg(feature = "gecko")] impl From for RestyleHint { fn from(mut raw: nsRestyleHint) -> Self { - use crate::gecko_bindings::structs::nsRestyleHint_eRestyle_Force as eRestyle_Force; - use crate::gecko_bindings::structs::nsRestyleHint_eRestyle_ForceDescendants as eRestyle_ForceDescendants; - use crate::gecko_bindings::structs::nsRestyleHint_eRestyle_LaterSiblings as eRestyle_LaterSiblings; - use crate::gecko_bindings::structs::nsRestyleHint_eRestyle_Self as eRestyle_Self; - use crate::gecko_bindings::structs::nsRestyleHint_eRestyle_SomeDescendants as eRestyle_SomeDescendants; - use crate::gecko_bindings::structs::nsRestyleHint_eRestyle_Subtree as eRestyle_Subtree; - let mut hint = RestyleHint::empty(); debug_assert!( - raw.0 & eRestyle_LaterSiblings.0 == 0, + raw.0 & nsRestyleHint::eRestyle_LaterSiblings.0 == 0, "Handle later siblings manually if necessary plz." ); - if (raw.0 & (eRestyle_Self.0 | eRestyle_Subtree.0)) != 0 { - raw.0 &= !eRestyle_Self.0; + if (raw.0 & (nsRestyleHint::eRestyle_Self.0 | nsRestyleHint::eRestyle_Subtree.0)) != 0 { + raw.0 &= !nsRestyleHint::eRestyle_Self.0; hint.insert(RestyleHint::RESTYLE_SELF); } - if (raw.0 & (eRestyle_Subtree.0 | eRestyle_SomeDescendants.0)) != 0 { - raw.0 &= !eRestyle_Subtree.0; - raw.0 &= !eRestyle_SomeDescendants.0; + if (raw.0 & (nsRestyleHint::eRestyle_Subtree.0 | nsRestyleHint::eRestyle_SomeDescendants.0)) != 0 { + raw.0 &= !nsRestyleHint::eRestyle_Subtree.0; + raw.0 &= !nsRestyleHint::eRestyle_SomeDescendants.0; hint.insert(RestyleHint::RESTYLE_DESCENDANTS); } - if (raw.0 & (eRestyle_ForceDescendants.0 | eRestyle_Force.0)) != 0 { - raw.0 &= !eRestyle_Force.0; + if (raw.0 & (nsRestyleHint::eRestyle_ForceDescendants.0 | nsRestyleHint::eRestyle_Force.0)) != 0 { + raw.0 &= !nsRestyleHint::eRestyle_Force.0; hint.insert(RestyleHint::RECASCADE_SELF); } - if (raw.0 & eRestyle_ForceDescendants.0) != 0 { - raw.0 &= !eRestyle_ForceDescendants.0; + if (raw.0 & nsRestyleHint::eRestyle_ForceDescendants.0) != 0 { + raw.0 &= !nsRestyleHint::eRestyle_ForceDescendants.0; hint.insert(RestyleHint::RECASCADE_DESCENDANTS); } @@ -248,7 +241,7 @@ pub fn assert_restyle_hints_match() { if cfg!(debug_assertions) { let mut replacements = RestyleHint::replacements(); $( - assert_eq!(structs::$a.0 as usize, $b.bits() as usize, stringify!($b)); + assert_eq!(structs::nsRestyleHint::$a.0 as usize, $b.bits() as usize, stringify!($b)); replacements.remove($b); )* assert_eq!(replacements, RestyleHint::empty(), @@ -259,9 +252,9 @@ pub fn assert_restyle_hints_match() { } check_restyle_hints! { - nsRestyleHint_eRestyle_CSSTransitions => RestyleHint::RESTYLE_CSS_TRANSITIONS, - nsRestyleHint_eRestyle_CSSAnimations => RestyleHint::RESTYLE_CSS_ANIMATIONS, - nsRestyleHint_eRestyle_StyleAttribute => RestyleHint::RESTYLE_STYLE_ATTRIBUTE, - nsRestyleHint_eRestyle_StyleAttribute_Animations => RestyleHint::RESTYLE_SMIL, + eRestyle_CSSTransitions => RestyleHint::RESTYLE_CSS_TRANSITIONS, + eRestyle_CSSAnimations => RestyleHint::RESTYLE_CSS_ANIMATIONS, + eRestyle_StyleAttribute => RestyleHint::RESTYLE_STYLE_ATTRIBUTE, + eRestyle_StyleAttribute_Animations => RestyleHint::RESTYLE_SMIL, } } diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 218f150e670..d969f14f54a 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -39,7 +39,6 @@ use crate::gecko_bindings::bindings::RawGeckoPresContextBorrowed; use crate::gecko_bindings::structs; use crate::gecko_bindings::structs::nsCSSPropertyID; use crate::gecko_bindings::structs::mozilla::CSSPseudoElementType; -use crate::gecko_bindings::structs::mozilla::CSSPseudoElementType_InheritingAnonBox; use crate::gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut}; use crate::gecko_bindings::sugar::refptr::RefPtr; use crate::gecko::values::convert_nscolor_to_rgba; @@ -138,7 +137,7 @@ impl ComputedValues { #[inline] pub fn is_anon_box(&self) -> bool { let our_type = self.get_pseudo_type(); - return our_type == CSSPseudoElementType_InheritingAnonBox || + return our_type == CSSPseudoElementType::InheritingAnonBox || our_type == CSSPseudoElementType::NonInheritingAnonBox; } From 81a07b4351fad96843824e6ef86d5b4d27d25190 Mon Sep 17 00:00:00 2001 From: quasicomputational Date: Thu, 27 Dec 2018 14:43:34 +0000 Subject: [PATCH 13/27] style: Implement the 'overflow-block' media query. Bug: 1422235 Reviewed-by: emilio --- components/style/gecko/media_features.rs | 42 ++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/components/style/gecko/media_features.rs b/components/style/gecko/media_features.rs index 25355c45d70..ede01f3b1b9 100644 --- a/components/style/gecko/media_features.rs +++ b/components/style/gecko/media_features.rs @@ -9,7 +9,7 @@ use crate::gecko_bindings::structs; use crate::media_queries::media_feature::{AllowsRanges, ParsingRequirements}; use crate::media_queries::media_feature::{Evaluator, MediaFeatureDescription}; use crate::media_queries::media_feature_expression::{AspectRatio, RangeOrOperator}; -use crate::media_queries::Device; +use crate::media_queries::{Device, MediaType}; use crate::values::computed::CSSPixelLength; use crate::values::computed::Resolution; use crate::Atom; @@ -295,6 +295,38 @@ fn eval_prefers_reduced_motion(device: &Device, query_value: Option) -> bool { + // For the time being, assume that printing (including previews) + // is the only time when we paginate, and we are otherwise always + // scrolling. This is true at the moment in Firefox, but may need + // updating in the future (e.g., ebook readers built with Stylo, a + // billboard mode that doesn't support overflow at all). + // + // If this ever changes, don't forget to change eval_overflow_inline too. + let scrolling = device.media_type() != MediaType::print(); + let query_value = match query_value { + Some(v) => v, + None => return true, + }; + + match query_value { + OverflowBlock::None | + OverflowBlock::OptionalPaged => false, + OverflowBlock::Scroll => scrolling, + OverflowBlock::Paged => !scrolling, + } +} + /// https://drafts.csswg.org/mediaqueries-4/#mf-interaction bitflags! { struct PointerCapabilities: u8 { @@ -473,7 +505,7 @@ lazy_static! { /// to support new types in these entries and (2) ensuring that either /// nsPresContext::MediaFeatureValuesChanged is called when the value that /// would be returned by the evaluator function could change. - pub static ref MEDIA_FEATURES: [MediaFeatureDescription; 48] = [ + pub static ref MEDIA_FEATURES: [MediaFeatureDescription; 49] = [ feature!( atom!("width"), AllowsRanges::Yes, @@ -592,6 +624,12 @@ lazy_static! { keyword_evaluator!(eval_prefers_reduced_motion, PrefersReducedMotion), ParsingRequirements::empty(), ), + feature!( + atom!("overflow-block"), + AllowsRanges::No, + keyword_evaluator!(eval_overflow_block, OverflowBlock), + ParsingRequirements::empty(), + ), feature!( atom!("pointer"), AllowsRanges::No, From 274845fc14e4cd40616a71ec8ae3da4d159934da Mon Sep 17 00:00:00 2001 From: quasicomputational Date: Sat, 22 Dec 2018 19:41:33 +0000 Subject: [PATCH 14/27] style: Implement the 'overflow-inline' media query. Bug: 1422235 Reviewed-by: emilio --- components/style/gecko/media_features.rs | 30 +++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/components/style/gecko/media_features.rs b/components/style/gecko/media_features.rs index ede01f3b1b9..29f5b61816f 100644 --- a/components/style/gecko/media_features.rs +++ b/components/style/gecko/media_features.rs @@ -327,6 +327,28 @@ fn eval_overflow_block(device: &Device, query_value: Option) -> b } } +#[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)] +#[repr(u8)] +enum OverflowInline { + None, + Scroll, +} + +/// https://drafts.csswg.org/mediaqueries-4/#mf-overflow-inline +fn eval_overflow_inline(device: &Device, query_value: Option) -> bool { + // See the note in eval_overflow_block. + let scrolling = device.media_type() != MediaType::print(); + let query_value = match query_value { + Some(v) => v, + None => return scrolling, + }; + + match query_value { + OverflowInline::None => !scrolling, + OverflowInline::Scroll => scrolling, + } +} + /// https://drafts.csswg.org/mediaqueries-4/#mf-interaction bitflags! { struct PointerCapabilities: u8 { @@ -505,7 +527,7 @@ lazy_static! { /// to support new types in these entries and (2) ensuring that either /// nsPresContext::MediaFeatureValuesChanged is called when the value that /// would be returned by the evaluator function could change. - pub static ref MEDIA_FEATURES: [MediaFeatureDescription; 49] = [ + pub static ref MEDIA_FEATURES: [MediaFeatureDescription; 50] = [ feature!( atom!("width"), AllowsRanges::Yes, @@ -630,6 +652,12 @@ lazy_static! { keyword_evaluator!(eval_overflow_block, OverflowBlock), ParsingRequirements::empty(), ), + feature!( + atom!("overflow-inline"), + AllowsRanges::No, + keyword_evaluator!(eval_overflow_inline, OverflowInline), + ParsingRequirements::empty(), + ), feature!( atom!("pointer"), AllowsRanges::No, From a454f6233d117135145a7dfcaef0c5df6a25eab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 2 Jan 2019 14:05:23 +0100 Subject: [PATCH 15/27] Rename nsIDocument to mozilla::dom::Document. Summary: Really sorry for the size of the patch. It's mostly automatic s/nsIDocument/Document/ but I had to fix up in a bunch of places manually to add the right namespacing and such. Overall it's not a very interesting patch I think. nsDocument.cpp turns into Document.cpp, nsIDocument.h into Document.h and nsIDocumentInlines.h into DocumentInlines.h. I also changed a bunch of nsCOMPtr usage to RefPtr, but not all of it. While fixing up some of the bits I also removed some unneeded OwnerDoc() null checks and such, but I didn't do anything riskier than that. Bug: 1517241 Reviewed-by: smaug --- components/style/element_state.rs | 2 +- components/style/gecko/data.rs | 7 +++---- components/style/gecko/media_queries.rs | 4 ++-- components/style/gecko/wrapper.rs | 12 ++++++------ 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/components/style/element_state.rs b/components/style/element_state.rs index a646a2a37bf..8165c73ef14 100644 --- a/components/style/element_state.rs +++ b/components/style/element_state.rs @@ -144,7 +144,7 @@ bitflags! { /// Event-based document states. /// /// NB: Is important for this to remain in sync with Gecko's - /// dom/base/nsIDocument.h. + /// dom/base/Document.h. #[derive(MallocSizeOf)] pub struct DocumentState: u64 { /// RTL locale: specific to the XUL localedir attribute diff --git a/components/style/gecko/data.rs b/components/style/gecko/data.rs index d4c976cc2a6..af98f116afb 100644 --- a/components/style/gecko/data.rs +++ b/components/style/gecko/data.rs @@ -7,8 +7,7 @@ use crate::context::QuirksMode; use crate::dom::TElement; use crate::gecko_bindings::bindings::{self, RawServoStyleSet}; -use crate::gecko_bindings::structs::StyleSheet as DomStyleSheet; -use crate::gecko_bindings::structs::{nsIDocument, StyleSheetInfo}; +use crate::gecko_bindings::structs::{StyleSheet as DomStyleSheet, StyleSheetInfo}; use crate::gecko_bindings::structs::{RawGeckoPresContextBorrowed, ServoStyleSetSizes}; use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFFI}; use crate::invalidation::media_queries::{MediaListKey, ToMediaListKey}; @@ -152,7 +151,7 @@ impl PerDocumentStyleData { // // Should we just force XBL Stylists to be NoQuirks? let quirks_mode = - unsafe { (*device.pres_context().mDocument.raw::()).mCompatMode }; + unsafe { (*device.pres_context().mDocument.mRawPtr).mCompatMode }; PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl { stylist: Stylist::new(device, quirks_mode.into()), @@ -198,7 +197,7 @@ impl PerDocumentStyleDataImpl { .device() .pres_context() .mDocument - .raw::(); + .mRawPtr; unsafe { bindings::Gecko_VisitedStylesEnabled(doc) } } diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs index ab3f3a0de80..851422467ce 100644 --- a/components/style/gecko/media_queries.rs +++ b/components/style/gecko/media_queries.rs @@ -162,8 +162,8 @@ impl Device { /// Gets the document pointer. #[inline] - pub fn document(&self) -> *mut structs::nsIDocument { - self.pres_context().mDocument.raw::() + pub fn document(&self) -> *mut structs::Document { + self.pres_context().mDocument.mRawPtr } /// Recreates the default computed values. diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 1340a005d74..b169ee947fa 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -45,7 +45,7 @@ use crate::gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWThe use crate::gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags}; use crate::gecko_bindings::structs; use crate::gecko_bindings::structs::nsChangeHint; -use crate::gecko_bindings::structs::nsIDocument_DocumentTheme as DocumentTheme; +use crate::gecko_bindings::structs::Document_DocumentTheme as DocumentTheme; use crate::gecko_bindings::structs::nsRestyleHint; use crate::gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel; use crate::gecko_bindings::structs::ELEMENT_HANDLED_SNAPSHOT; @@ -107,9 +107,9 @@ fn elements_with_id<'a, 'le>( } } -/// A simple wrapper over `nsIDocument`. +/// A simple wrapper over `Document`. #[derive(Clone, Copy)] -pub struct GeckoDocument<'ld>(pub &'ld structs::nsIDocument); +pub struct GeckoDocument<'ld>(pub &'ld structs::Document); impl<'ld> TDocument for GeckoDocument<'ld> { type ConcreteNode = GeckoNode<'ld>; @@ -121,7 +121,7 @@ impl<'ld> TDocument for GeckoDocument<'ld> { #[inline] fn is_html_document(&self) -> bool { - self.0.mType == structs::root::nsIDocument_Type::eHTML + self.0.mType == structs::Document_Type::eHTML } #[inline] @@ -1242,11 +1242,11 @@ impl<'le> TElement for GeckoElement<'le> { } fn owner_doc_matches_for_testing(&self, device: &Device) -> bool { - self.as_node().owner_doc().0 as *const structs::nsIDocument == + self.as_node().owner_doc().0 as *const structs::Document == device .pres_context() .mDocument - .raw::() + .mRawPtr } fn style_attribute(&self) -> Option>> { From d5bee572d7c8e0c6047a7cd896d77aa6ceec60bd Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Fri, 4 Jan 2019 07:23:07 +0000 Subject: [PATCH 16/27] style: Drop layout.css.box-decoration-break.enabled pref. It was enabled by default in bug 1006326. Differential Revision: https://phabricator.services.mozilla.com/D15702 --- components/style/properties/longhands/border.mako.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/style/properties/longhands/border.mako.rs b/components/style/properties/longhands/border.mako.rs index 2c304780e6d..3fcf73bf2f4 100644 --- a/components/style/properties/longhands/border.mako.rs +++ b/components/style/properties/longhands/border.mako.rs @@ -88,7 +88,6 @@ ${helpers.single_keyword( "box-decoration-break", "slice clone", gecko_enum_prefix="StyleBoxDecorationBreak", - gecko_pref="layout.css.box-decoration-break.enabled", spec="https://drafts.csswg.org/css-break/#propdef-box-decoration-break", products="gecko", animation_value_type="discrete", From 529ff36bb61bc1a11adf7f89413e051a6f02f1c4 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Fri, 4 Jan 2019 07:23:38 +0000 Subject: [PATCH 17/27] style: Drop layout.css.color-adjust.enabled pref. It was enabled by default in bug 1209273. Depends on D15702 Differential Revision: https://phabricator.services.mozilla.com/D15703 --- components/style/properties/longhands/inherited_box.mako.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/style/properties/longhands/inherited_box.mako.rs b/components/style/properties/longhands/inherited_box.mako.rs index aaa6815179c..4da61628677 100644 --- a/components/style/properties/longhands/inherited_box.mako.rs +++ b/components/style/properties/longhands/inherited_box.mako.rs @@ -55,7 +55,6 @@ ${helpers.single_keyword( "color-adjust", "economy exact", products="gecko", gecko_enum_prefix="StyleColorAdjust", - gecko_pref="layout.css.color-adjust.enabled", animation_value_type="discrete", spec="https://drafts.csswg.org/css-color/#propdef-color-adjust", )} From d862daeee623bdb9f8a03affc3ab3b0260fc9f1b Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Fri, 4 Jan 2019 07:22:52 +0000 Subject: [PATCH 18/27] style: Drop layout.css.image-orientation.enabled pref. It was enabled by default in bug 825771. Differential Revision: https://phabricator.services.mozilla.com/D15704 --- components/style/properties/longhands/inherited_box.mako.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/style/properties/longhands/inherited_box.mako.rs b/components/style/properties/longhands/inherited_box.mako.rs index 4da61628677..0e3799f6c46 100644 --- a/components/style/properties/longhands/inherited_box.mako.rs +++ b/components/style/properties/longhands/inherited_box.mako.rs @@ -77,6 +77,5 @@ ${helpers.single_keyword( products="gecko", gecko_enum_prefix="StyleImageOrientation", animation_value_type="discrete", - gecko_pref="layout.css.image-orientation.enabled", spec="https://drafts.csswg.org/css-images/#propdef-image-orientation", )} From 0488f81dac5255680fe2b37e4f117f568993c38f Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Fri, 4 Jan 2019 07:22:27 +0000 Subject: [PATCH 19/27] style: Drop layout.css.isolation.enabled pref. It was enabled by default in bug 1091885. Differential Revision: https://phabricator.services.mozilla.com/D15705 --- components/style/properties/longhands/box.mako.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/style/properties/longhands/box.mako.rs b/components/style/properties/longhands/box.mako.rs index 7eb6ff0028d..cb580cc93ba 100644 --- a/components/style/properties/longhands/box.mako.rs +++ b/components/style/properties/longhands/box.mako.rs @@ -427,7 +427,6 @@ ${helpers.single_keyword( "isolation", "auto isolate", products="gecko", - gecko_pref="layout.css.isolation.enabled", spec="https://drafts.fxtf.org/compositing/#isolation", flags="CREATES_STACKING_CONTEXT", animation_value_type="discrete", From a0d1a038a282c69403b3533218c2106d66ae90be Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Fri, 4 Jan 2019 07:22:13 +0000 Subject: [PATCH 20/27] style: Drop layout.css.mix-blend-mode.enabled pref. It was enabled by default in bug 952643. Differential Revision: https://phabricator.services.mozilla.com/D15706 --- components/style/properties/longhands/effects.mako.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/style/properties/longhands/effects.mako.rs b/components/style/properties/longhands/effects.mako.rs index 066ac4ca02a..0b3f96f0dde 100644 --- a/components/style/properties/longhands/effects.mako.rs +++ b/components/style/properties/longhands/effects.mako.rs @@ -62,6 +62,5 @@ ${helpers.single_keyword( gecko_constant_prefix="NS_STYLE_BLEND", animation_value_type="discrete", flags="CREATES_STACKING_CONTEXT", - gecko_pref="layout.css.mix-blend-mode.enabled", spec="https://drafts.fxtf.org/compositing/#propdef-mix-blend-mode", )} From 48e4433ab8f16a940db325716b75b875fac933f8 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Fri, 4 Jan 2019 07:21:53 +0000 Subject: [PATCH 21/27] style: Drop layout.css.scroll-behavior.property-enabled pref. It was enabled by default in bug 1041833 (for desktops) and bug 1087562 (for Fennec). Differential Revision: https://phabricator.services.mozilla.com/D15707 --- components/style/properties/longhands/box.mako.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/style/properties/longhands/box.mako.rs b/components/style/properties/longhands/box.mako.rs index cb580cc93ba..48b83271d9b 100644 --- a/components/style/properties/longhands/box.mako.rs +++ b/components/style/properties/longhands/box.mako.rs @@ -389,7 +389,6 @@ ${helpers.predefined_type( ${helpers.single_keyword( "scroll-behavior", "auto smooth", - gecko_pref="layout.css.scroll-behavior.property-enabled", products="gecko", spec="https://drafts.csswg.org/cssom-view/#propdef-scroll-behavior", animation_value_type="discrete", From 152ef2e042d7a49d6d85540f8b60587bf1dd15d2 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Fri, 4 Jan 2019 07:21:32 +0000 Subject: [PATCH 22/27] style: Drop layout.css.background-blend-mode.enabled pref. It was enabled by default in bug 970600. Differential Revision: https://phabricator.services.mozilla.com/D15708 --- components/style/properties/longhands/background.mako.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/style/properties/longhands/background.mako.rs b/components/style/properties/longhands/background.mako.rs index 934814567ba..b97545898c2 100644 --- a/components/style/properties/longhands/background.mako.rs +++ b/components/style/properties/longhands/background.mako.rs @@ -108,7 +108,6 @@ ${helpers.single_keyword( color-burn hard-light soft-light difference exclusion hue saturation color luminosity""", gecko_constant_prefix="NS_STYLE_BLEND", - gecko_pref="layout.css.background-blend-mode.enabled", vector=True, products="gecko", animation_value_type="discrete", spec="https://drafts.fxtf.org/compositing/#background-blend-mode", flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", From 5f173c463e386e6e870d2fa96fe8d687cbc2f78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 7 Jan 2019 00:00:55 +0100 Subject: [PATCH 23/27] style: Rustfmt recent changes. --- components/style/gecko/conversions.rs | 19 +++++++++++++------ components/style/gecko/data.rs | 12 +++--------- components/style/gecko/media_features.rs | 3 +-- components/style/gecko/values.rs | 4 +--- components/style/gecko/wrapper.rs | 7 ++----- .../gecko_bindings/sugar/origin_flags.rs | 5 ++++- .../invalidation/element/restyle_hints.rs | 8 ++++++-- components/style/rule_collector.rs | 3 +-- components/style/stylist.rs | 2 +- components/style/values/animated/mod.rs | 2 +- components/style/values/computed/border.rs | 7 ++++--- components/style/values/computed/mod.rs | 4 +++- .../style/values/specified/basic_shape.rs | 2 +- components/style/values/specified/border.rs | 8 ++++---- components/style/values/specified/length.rs | 6 +++++- components/style/values/specified/mod.rs | 4 +++- 16 files changed, 53 insertions(+), 43 deletions(-) diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index e077a9f9666..266ebbd750a 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -24,11 +24,11 @@ use crate::values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image}; use crate::values::computed::{Integer, LengthOrPercentage}; use crate::values::computed::{LengthOrPercentageOrAuto, NonNegativeLengthOrPercentageOrAuto}; use crate::values::computed::{Percentage, TextAlign}; -use crate::values::generics::NonNegative; use crate::values::generics::box_::VerticalAlign; use crate::values::generics::grid::{TrackListValue, TrackSize}; use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage}; use crate::values::generics::rect::Rect; +use crate::values::generics::NonNegative; use app_units::Au; use std::f32::consts::PI; @@ -677,11 +677,11 @@ pub mod basic_shape { use crate::values::generics::basic_shape::{ BasicShape as GenericBasicShape, InsetRect, Polygon, }; - use crate::values::generics::NonNegative; use crate::values::generics::basic_shape::{Circle, Ellipse, Path, PolygonCoord}; use crate::values::generics::basic_shape::{GeometryBox, ShapeBox, ShapeSource}; use crate::values::generics::border::BorderRadius as GenericBorderRadius; use crate::values::generics::rect::Rect; + use crate::values::generics::NonNegative; use crate::values::specified::SVGPathData; use std::borrow::Borrow; @@ -841,10 +841,17 @@ pub mod basic_shape { fn from(other: &'a nsStyleCorners) -> Self { let get_corner = |index| { BorderCornerRadius::new( - NonNegative(LengthOrPercentage::from_gecko_style_coord(&other.data_at(index)) - .expect(" should be a length, percentage, or calc value")), - NonNegative(LengthOrPercentage::from_gecko_style_coord(&other.data_at(index + 1)) - .expect(" should be a length, percentage, or calc value")), + NonNegative( + LengthOrPercentage::from_gecko_style_coord(&other.data_at(index)).expect( + " should be a length, percentage, or calc value", + ), + ), + NonNegative( + LengthOrPercentage::from_gecko_style_coord(&other.data_at(index + 1)) + .expect( + " should be a length, percentage, or calc value", + ), + ), ) }; diff --git a/components/style/gecko/data.rs b/components/style/gecko/data.rs index af98f116afb..80e34fe2e7e 100644 --- a/components/style/gecko/data.rs +++ b/components/style/gecko/data.rs @@ -7,8 +7,8 @@ use crate::context::QuirksMode; use crate::dom::TElement; use crate::gecko_bindings::bindings::{self, RawServoStyleSet}; -use crate::gecko_bindings::structs::{StyleSheet as DomStyleSheet, StyleSheetInfo}; use crate::gecko_bindings::structs::{RawGeckoPresContextBorrowed, ServoStyleSetSizes}; +use crate::gecko_bindings::structs::{StyleSheet as DomStyleSheet, StyleSheetInfo}; use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFFI}; use crate::invalidation::media_queries::{MediaListKey, ToMediaListKey}; use crate::media_queries::{Device, MediaList}; @@ -150,8 +150,7 @@ impl PerDocumentStyleData { // right now not always honored, see bug 1405543... // // Should we just force XBL Stylists to be NoQuirks? - let quirks_mode = - unsafe { (*device.pres_context().mDocument.mRawPtr).mCompatMode }; + let quirks_mode = unsafe { (*device.pres_context().mDocument.mRawPtr).mCompatMode }; PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl { stylist: Stylist::new(device, quirks_mode.into()), @@ -192,12 +191,7 @@ impl PerDocumentStyleDataImpl { /// Returns whether visited styles are enabled. #[inline] pub fn visited_styles_enabled(&self) -> bool { - let doc = self - .stylist - .device() - .pres_context() - .mDocument - .mRawPtr; + let doc = self.stylist.device().pres_context().mDocument.mRawPtr; unsafe { bindings::Gecko_VisitedStylesEnabled(doc) } } diff --git a/components/style/gecko/media_features.rs b/components/style/gecko/media_features.rs index 29f5b61816f..82613c9e245 100644 --- a/components/style/gecko/media_features.rs +++ b/components/style/gecko/media_features.rs @@ -320,8 +320,7 @@ fn eval_overflow_block(device: &Device, query_value: Option) -> b }; match query_value { - OverflowBlock::None | - OverflowBlock::OptionalPaged => false, + OverflowBlock::None | OverflowBlock::OptionalPaged => false, OverflowBlock::Scroll => scrolling, OverflowBlock::Paged => !scrolling, } diff --git a/components/style/gecko/values.rs b/components/style/gecko/values.rs index b22f68cd05d..39a5ac2de89 100644 --- a/components/style/gecko/values.rs +++ b/components/style/gecko/values.rs @@ -286,9 +286,7 @@ impl GeckoStyleCoordConvertible for ComputedShapeRadius { None } }, - _ => { - GeckoStyleCoordConvertible::from_gecko_style_coord(coord).map(ShapeRadius::Length) - }, + _ => GeckoStyleCoordConvertible::from_gecko_style_coord(coord).map(ShapeRadius::Length), } } } diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index b169ee947fa..0c8bbb9f9a7 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -45,8 +45,8 @@ use crate::gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWThe use crate::gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags}; use crate::gecko_bindings::structs; use crate::gecko_bindings::structs::nsChangeHint; -use crate::gecko_bindings::structs::Document_DocumentTheme as DocumentTheme; use crate::gecko_bindings::structs::nsRestyleHint; +use crate::gecko_bindings::structs::Document_DocumentTheme as DocumentTheme; use crate::gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel; use crate::gecko_bindings::structs::ELEMENT_HANDLED_SNAPSHOT; use crate::gecko_bindings::structs::ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO; @@ -1243,10 +1243,7 @@ impl<'le> TElement for GeckoElement<'le> { fn owner_doc_matches_for_testing(&self, device: &Device) -> bool { self.as_node().owner_doc().0 as *const structs::Document == - device - .pres_context() - .mDocument - .mRawPtr + device.pres_context().mDocument.mRawPtr } fn style_attribute(&self) -> Option>> { diff --git a/components/style/gecko_bindings/sugar/origin_flags.rs b/components/style/gecko_bindings/sugar/origin_flags.rs index 409b145f1e9..e0f0981c5d8 100644 --- a/components/style/gecko_bindings/sugar/origin_flags.rs +++ b/components/style/gecko_bindings/sugar/origin_flags.rs @@ -10,7 +10,10 @@ use crate::stylesheets::OriginSet; /// Checks that the values for OriginFlags are the ones we expect. pub fn assert_flags_match() { use crate::stylesheets::origin::*; - debug_assert_eq!(OriginFlags::UserAgent.0, OriginSet::ORIGIN_USER_AGENT.bits()); + debug_assert_eq!( + OriginFlags::UserAgent.0, + OriginSet::ORIGIN_USER_AGENT.bits() + ); debug_assert_eq!(OriginFlags::Author.0, OriginSet::ORIGIN_AUTHOR.bits()); debug_assert_eq!(OriginFlags::User.0, OriginSet::ORIGIN_USER.bits()); } diff --git a/components/style/invalidation/element/restyle_hints.rs b/components/style/invalidation/element/restyle_hints.rs index 2cb8e222e46..de84fe56c85 100644 --- a/components/style/invalidation/element/restyle_hints.rs +++ b/components/style/invalidation/element/restyle_hints.rs @@ -205,13 +205,17 @@ impl From for RestyleHint { hint.insert(RestyleHint::RESTYLE_SELF); } - if (raw.0 & (nsRestyleHint::eRestyle_Subtree.0 | nsRestyleHint::eRestyle_SomeDescendants.0)) != 0 { + if (raw.0 & (nsRestyleHint::eRestyle_Subtree.0 | nsRestyleHint::eRestyle_SomeDescendants.0)) != + 0 + { raw.0 &= !nsRestyleHint::eRestyle_Subtree.0; raw.0 &= !nsRestyleHint::eRestyle_SomeDescendants.0; hint.insert(RestyleHint::RESTYLE_DESCENDANTS); } - if (raw.0 & (nsRestyleHint::eRestyle_ForceDescendants.0 | nsRestyleHint::eRestyle_Force.0)) != 0 { + if (raw.0 & (nsRestyleHint::eRestyle_ForceDescendants.0 | nsRestyleHint::eRestyle_Force.0)) != + 0 + { raw.0 &= !nsRestyleHint::eRestyle_Force.0; hint.insert(RestyleHint::RECASCADE_SELF); } diff --git a/components/style/rule_collector.rs b/components/style/rule_collector.rs index 6304a1af2d7..ba602ddca83 100644 --- a/components/style/rule_collector.rs +++ b/components/style/rule_collector.rs @@ -260,8 +260,7 @@ where let cascade_data = containing_shadow.style_data(); let host = containing_shadow.host(); - if let Some(map) = cascade_data.and_then(|data| data.normal_rules(self.pseudo_element)) - { + if let Some(map) = cascade_data.and_then(|data| data.normal_rules(self.pseudo_element)) { self.collect_rules_in_shadow_tree(host, map, CascadeLevel::SameTreeAuthorNormal); } } diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 3815a8a3da6..74b055e099b 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -17,7 +17,7 @@ use crate::media_queries::Device; use crate::properties::{self, CascadeMode, ComputedValues}; use crate::properties::{AnimationRules, PropertyDeclarationBlock}; use crate::rule_cache::{RuleCache, RuleCacheConditions}; -use crate::rule_collector::{RuleCollector, containing_shadow_ignoring_svg_use}; +use crate::rule_collector::{containing_shadow_ignoring_svg_use, RuleCollector}; use crate::rule_tree::{CascadeLevel, RuleTree, ShadowCascadeOrder, StrongRuleNode, StyleSource}; use crate::selector_map::{PrecomputedHashMap, PrecomputedHashSet, SelectorMap, SelectorMapEntry}; use crate::selector_parser::{PerPseudoElementMap, PseudoElement, SelectorImpl, SnapshotMap}; diff --git a/components/style/values/animated/mod.rs b/components/style/values/animated/mod.rs index bd0a7af1f95..a7c947f810a 100644 --- a/components/style/values/animated/mod.rs +++ b/components/style/values/animated/mod.rs @@ -13,8 +13,8 @@ use crate::values::computed::length::CalcLengthOrPercentage; use crate::values::computed::url::ComputedUrl; use crate::values::computed::Angle as ComputedAngle; use crate::values::computed::Image; -use crate::values::CSSFloat; use crate::values::specified::SVGPathData; +use crate::values::CSSFloat; use app_units::Au; use euclid::{Point2D, Size2D}; use smallvec::SmallVec; diff --git a/components/style/values/computed/border.rs b/components/style/values/computed/border.rs index 09dcfbe117a..c6ab4abc5a5 100644 --- a/components/style/values/computed/border.rs +++ b/components/style/values/computed/border.rs @@ -4,8 +4,7 @@ //! Computed types for CSS values related to borders. -use crate::values::generics::NonNegative; -use crate::values::computed::length::{NonNegativeLengthOrPercentage, NonNegativeLength}; +use crate::values::computed::length::{NonNegativeLength, NonNegativeLengthOrPercentage}; use crate::values::computed::{NonNegativeNumber, NonNegativeNumberOrPercentage}; use crate::values::generics::border::BorderCornerRadius as GenericBorderCornerRadius; use crate::values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth; @@ -14,6 +13,7 @@ use crate::values::generics::border::BorderRadius as GenericBorderRadius; use crate::values::generics::border::BorderSpacing as GenericBorderSpacing; use crate::values::generics::rect::Rect; use crate::values::generics::size::Size; +use crate::values::generics::NonNegative; use app_units::Au; pub use crate::values::specified::border::BorderImageRepeat; @@ -22,7 +22,8 @@ pub use crate::values::specified::border::BorderImageRepeat; pub type BorderImageWidth = Rect; /// A computed value for a single side of a `border-image-width` property. -pub type BorderImageSideWidth = GenericBorderImageSideWidth; +pub type BorderImageSideWidth = + GenericBorderImageSideWidth; /// A computed value for the `border-image-slice` property. pub type BorderImageSlice = GenericBorderImageSlice; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 7ee151a4078..4051511e28e 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -546,7 +546,9 @@ pub enum NumberOrPercentage { impl NumberOrPercentage { fn clamp_to_non_negative(self) -> Self { match self { - NumberOrPercentage::Percentage(p) => NumberOrPercentage::Percentage(p.clamp_to_non_negative()), + NumberOrPercentage::Percentage(p) => { + NumberOrPercentage::Percentage(p.clamp_to_non_negative()) + }, NumberOrPercentage::Number(n) => NumberOrPercentage::Number(n.max(0.)), } } diff --git a/components/style/values/specified/basic_shape.rs b/components/style/values/specified/basic_shape.rs index 20c7ad6eeb4..84624671ffe 100644 --- a/components/style/values/specified/basic_shape.rs +++ b/components/style/values/specified/basic_shape.rs @@ -16,8 +16,8 @@ use crate::values::specified::border::BorderRadius; use crate::values::specified::image::Image; use crate::values::specified::position::{HorizontalPosition, Position, VerticalPosition}; use crate::values::specified::url::SpecifiedUrl; -use crate::values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage}; use crate::values::specified::SVGPathData; +use crate::values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage}; use cssparser::Parser; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; diff --git a/components/style/values/specified/border.rs b/components/style/values/specified/border.rs index ee0b491f027..acd38ea5ba4 100644 --- a/components/style/values/specified/border.rs +++ b/components/style/values/specified/border.rs @@ -13,7 +13,7 @@ use crate::values::generics::border::BorderRadius as GenericBorderRadius; use crate::values::generics::border::BorderSpacing as GenericBorderSpacing; use crate::values::generics::rect::Rect; use crate::values::generics::size::Size; -use crate::values::specified::length::{NonNegativeLengthOrPercentage, NonNegativeLength}; +use crate::values::specified::length::{NonNegativeLength, NonNegativeLengthOrPercentage}; use crate::values::specified::{AllowQuirks, NonNegativeNumber, NonNegativeNumberOrPercentage}; use cssparser::Parser; use std::fmt::{self, Write}; @@ -78,7 +78,8 @@ pub enum BorderSideWidth { pub type BorderImageWidth = Rect; /// A specified value for a single side of a `border-image-width` property. -pub type BorderImageSideWidth = GenericBorderImageSideWidth; +pub type BorderImageSideWidth = + GenericBorderImageSideWidth; /// A specified value for the `border-image-slice` property. pub type BorderImageSlice = GenericBorderImageSlice; @@ -116,8 +117,7 @@ impl BorderSideWidth { input: &mut Parser<'i, 't>, allow_quirks: AllowQuirks, ) -> Result> { - if let Ok(length) = - input.try(|i| NonNegativeLength::parse_quirky(context, i, allow_quirks)) + if let Ok(length) = input.try(|i| NonNegativeLength::parse_quirky(context, i, allow_quirks)) { return Ok(BorderSideWidth::Length(length)); } diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index dce643a754f..e64385472a0 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -725,7 +725,11 @@ impl NonNegativeLength { input: &mut Parser<'i, 't>, allow_quirks: AllowQuirks, ) -> Result> { - Ok(NonNegative(Length::parse_non_negative_quirky(context, input, allow_quirks)?)) + Ok(NonNegative(Length::parse_non_negative_quirky( + context, + input, + allow_quirks, + )?)) } } diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index a73252bbeb6..17d1ea04186 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -375,7 +375,9 @@ impl Parse for NonNegativeNumberOrPercentage { context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - Ok(NonNegative(NumberOrPercentage::parse_non_negative(context, input)?)) + Ok(NonNegative(NumberOrPercentage::parse_non_negative( + context, input, + )?)) } } From d0eb20c7d332752b01583810f53e6175921fb7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 7 Jan 2019 00:11:40 +0100 Subject: [PATCH 24/27] Update lockfile. --- Cargo.lock | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 25d1dd886b9..9d5b7d5f676 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -684,7 +684,7 @@ dependencies = [ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -772,7 +772,7 @@ dependencies = [ "procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1123,7 +1123,7 @@ name = "fallible" version = "0.0.1" dependencies = [ "hashglobe 0.1.0", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1287,7 +1287,7 @@ dependencies = [ "servo_arc 0.1.1", "servo_atoms 0.0.1", "servo_url 0.0.1", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "truetype 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2012,7 +2012,7 @@ dependencies = [ "servo_geometry 0.0.1", "servo_url 0.0.1", "size_of_test 0.0.1", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", "style_traits 0.0.1", "unicode-bidi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2136,7 +2136,7 @@ dependencies = [ "libservo 0.0.1", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2275,8 +2275,8 @@ dependencies = [ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)", "servo_arc 0.1.1", - "smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallbitvec 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2850,7 +2850,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3284,7 +3284,7 @@ dependencies = [ "servo_geometry 0.0.1", "servo_rand 0.0.1", "servo_url 0.0.1", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", "style_traits 0.0.1", "swapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3400,7 +3400,7 @@ dependencies = [ "phf_codegen 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "servo_arc 0.1.1", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3528,7 +3528,7 @@ dependencies = [ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "servo_media_derive 0.1.0 (git+https://github.com/servo/media)", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3762,12 +3762,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "smallbitvec" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "smallvec" -version = "0.6.3" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3894,8 +3894,8 @@ dependencies = [ "servo_atoms 0.0.1", "servo_config 0.0.1", "servo_url 0.0.1", - "smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallbitvec 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "style_derive 0.0.1", "style_traits 0.0.1", @@ -4575,7 +4575,7 @@ dependencies = [ "ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", "thread_profiler 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "webrender_api 0.57.2 (git+https://github.com/servo/webrender)", @@ -5115,8 +5115,8 @@ dependencies = [ "checksum signpost 0.1.0 (git+https://github.com/pcwalton/signpost.git)" = "" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" "checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" -"checksum smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c63726029f0069f88467873e47f392575f28f9f16b72ac65465263db4b3a13c" -"checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8" +"checksum smallbitvec 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1764fe2b30ee783bfe3b9b37b2649d8d590b3148bb12e0079715d4d5c673562e" +"checksum smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db" "checksum smithay-client-toolkit 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ef227bd9251cf8f8e54f8dd9a4b164307e515f5312cd632ebc87b56f723893a2" "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" "checksum stb_truetype 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "48fa7d3136d8645909de1f7c7eb5416cc43057a75ace08fc39ae736bc9da8af1" From 4c1076a9ac4a344d587bb23d5cf9bfda633ae609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 7 Jan 2019 00:30:29 +0100 Subject: [PATCH 25/27] style: Fix gecko build. --- components/style/gecko/wrapper.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 0c8bbb9f9a7..97f0f887a00 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -22,7 +22,6 @@ use crate::dom::{LayoutIterator, NodeInfo, OpaqueNode, TDocument, TElement, TNod use crate::element_state::{DocumentState, ElementState}; use crate::font_metrics::{FontMetrics, FontMetricsProvider, FontMetricsQueryResult}; use crate::gecko::data::GeckoStyleSheet; -use crate::gecko::global_style_data::GLOBAL_STYLE_DATA; use crate::gecko::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl}; use crate::gecko::snapshot_helpers; use crate::gecko_bindings::bindings; @@ -57,6 +56,7 @@ use crate::gecko_bindings::structs::NODE_NEEDS_FRAME; use crate::gecko_bindings::structs::{nsAtom, nsIContent, nsINode_BooleanFlag}; use crate::gecko_bindings::structs::{RawGeckoElement, RawGeckoNode, RawGeckoXBLBinding}; use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI}; +use crate::global_style_data::GLOBAL_STYLE_DATA; use crate::hash::FxHashMap; use crate::logical_geometry::WritingMode; use crate::media_queries::Device; From 97bd8fc2804460a4aa11aab6cb63acbe986dc94c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 7 Jan 2019 00:56:59 +0100 Subject: [PATCH 26/27] Fix Servo build. --- components/layout/display_list/border.rs | 9 +++++---- components/script/dom/element.rs | 6 ++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/components/layout/display_list/border.rs b/components/layout/display_list/border.rs index 265b25a2805..d5909abee84 100644 --- a/components/layout/display_list/border.rs +++ b/components/layout/display_list/border.rs @@ -14,6 +14,7 @@ use style::values::computed::{BorderCornerRadius, BorderImageWidth}; use style::values::computed::{BorderImageSideWidth, LengthOrNumber}; use style::values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth; use style::values::generics::rect::Rect as StyleRect; +use style::values::generics::NonNegative; use style::values::Either; use webrender_api::{BorderRadius, BorderSide, BorderStyle, ColorF}; use webrender_api::{LayoutSideOffsets, LayoutSize, NormalBorder}; @@ -163,7 +164,7 @@ fn side_image_width( ) -> f32 { match border_image_width { GenericBorderImageSideWidth::Length(v) => v.to_used_value(total_length).to_f32_px(), - GenericBorderImageSideWidth::Number(x) => border_width * x, + GenericBorderImageSideWidth::Number(x) => border_width * x.0, GenericBorderImageSideWidth::Auto => border_width, } } @@ -181,15 +182,15 @@ pub fn image_width( ) } -fn resolve_percentage(value: NumberOrPercentage, length: i32) -> i32 { - match value { +fn resolve_percentage(value: NonNegative, length: i32) -> i32 { + match value.0 { NumberOrPercentage::Percentage(p) => (p.0 * length as f32).round() as i32, NumberOrPercentage::Number(n) => n.round() as i32, } } pub fn image_slice( - border_image_slice: &StyleRect, + border_image_slice: &StyleRect>, width: i32, height: i32, ) -> SideOffsets2D { diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 91cc8939590..233d4a01bb3 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -128,6 +128,7 @@ use style::selector_parser::{ }; use style::shared_lock::{Locked, SharedRwLock}; use style::thread_state; +use style::values::generics::NonNegative; use style::values::{computed, specified}; use style::values::{CSSFloat, Either}; use style::CaseSensitivityExt; @@ -847,8 +848,9 @@ impl LayoutElementHelpers for LayoutDom { }; if let Some(border) = border { - let width_value = - specified::BorderSideWidth::Length(specified::Length::from_px(border as f32)); + let width_value = specified::BorderSideWidth::Length(NonNegative( + specified::Length::from_px(border as f32), + )); hints.push(from_declaration( shared_lock, PropertyDeclaration::BorderTopWidth(width_value.clone()), From ecd9794a81d0ead13e47348994ea323556f969b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 7 Jan 2019 01:26:23 +0100 Subject: [PATCH 27/27] style: Remove a bunch of unit tests that are not very useful. And no longer compile. This is fairly well tested in WPT and Gecko tests. --- tests/unit/style/properties/serialization.rs | 404 ------------------- 1 file changed, 404 deletions(-) diff --git a/tests/unit/style/properties/serialization.rs b/tests/unit/style/properties/serialization.rs index 38326dcd1fd..035f9a9385c 100644 --- a/tests/unit/style/properties/serialization.rs +++ b/tests/unit/style/properties/serialization.rs @@ -10,9 +10,7 @@ use style::properties::parse_property_declaration_list; use style::properties::{Importance, PropertyDeclaration}; use style::values::specified::url::SpecifiedUrl; use style::values::specified::NoCalcLength; -use style::values::specified::{BorderSideWidth, BorderStyle, Color}; use style::values::specified::{Length, LengthOrPercentage, LengthOrPercentageOrAuto}; -use style::values::RGBA; use style_traits::ToCss; trait ToCssString { @@ -83,408 +81,6 @@ mod shorthand_serialization { block.to_css_string() } - mod four_sides_shorthands { - pub use super::*; - - // we can use margin as a base to test out the different combinations - // but afterwards, we only need to to one test per "four sides shorthand" - #[test] - fn all_equal_properties_should_serialize_to_one_value() { - let mut properties = Vec::new(); - - let px_70 = LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(70f32)); - properties.push(PropertyDeclaration::MarginTop(px_70.clone())); - properties.push(PropertyDeclaration::MarginRight(px_70.clone())); - properties.push(PropertyDeclaration::MarginBottom(px_70.clone())); - properties.push(PropertyDeclaration::MarginLeft(px_70)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "margin: 70px;"); - } - - #[test] - fn equal_vertical_and_equal_horizontal_properties_should_serialize_to_two_value() { - let mut properties = Vec::new(); - - let vertical_px = LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(10f32)); - let horizontal_px = LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(5f32)); - - properties.push(PropertyDeclaration::MarginTop(vertical_px.clone())); - properties.push(PropertyDeclaration::MarginRight(horizontal_px.clone())); - properties.push(PropertyDeclaration::MarginBottom(vertical_px)); - properties.push(PropertyDeclaration::MarginLeft(horizontal_px)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "margin: 10px 5px;"); - } - - #[test] - fn different_vertical_and_equal_horizontal_properties_should_serialize_to_three_values() { - let mut properties = Vec::new(); - - let top_px = LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(8f32)); - let bottom_px = LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(10f32)); - let horizontal_px = LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(5f32)); - - properties.push(PropertyDeclaration::MarginTop(top_px)); - properties.push(PropertyDeclaration::MarginRight(horizontal_px.clone())); - properties.push(PropertyDeclaration::MarginBottom(bottom_px)); - properties.push(PropertyDeclaration::MarginLeft(horizontal_px)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "margin: 8px 5px 10px;"); - } - - #[test] - fn different_properties_should_serialize_to_four_values() { - let mut properties = Vec::new(); - - let top_px = LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(8f32)); - let right_px = LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(12f32)); - let bottom_px = LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(10f32)); - let left_px = LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(14f32)); - - properties.push(PropertyDeclaration::MarginTop(top_px)); - properties.push(PropertyDeclaration::MarginRight(right_px)); - properties.push(PropertyDeclaration::MarginBottom(bottom_px)); - properties.push(PropertyDeclaration::MarginLeft(left_px)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "margin: 8px 12px 10px 14px;"); - } - - #[test] - fn different_longhands_should_serialize_to_long_form() { - let mut properties = Vec::new(); - - let solid = BorderStyle::Solid; - - properties.push(PropertyDeclaration::BorderTopStyle(solid.clone())); - properties.push(PropertyDeclaration::BorderRightStyle(solid.clone())); - properties.push(PropertyDeclaration::BorderBottomStyle(solid.clone())); - properties.push(PropertyDeclaration::BorderLeftStyle(solid.clone())); - - let px_30 = BorderSideWidth::Length(Length::from_px(30f32)); - let px_10 = BorderSideWidth::Length(Length::from_px(10f32)); - - properties.push(PropertyDeclaration::BorderTopWidth(px_30.clone())); - properties.push(PropertyDeclaration::BorderRightWidth(px_30.clone())); - properties.push(PropertyDeclaration::BorderBottomWidth(px_30.clone())); - properties.push(PropertyDeclaration::BorderLeftWidth(px_10.clone())); - - let blue = Color::rgba(RGBA::new(0, 0, 255, 255)); - - properties.push(PropertyDeclaration::BorderTopColor(blue.clone())); - properties.push(PropertyDeclaration::BorderRightColor(blue.clone())); - properties.push(PropertyDeclaration::BorderBottomColor(blue.clone())); - properties.push(PropertyDeclaration::BorderLeftColor(blue.clone())); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, - "border-style: solid; border-width: 30px 30px 30px 10px; border-color: rgb(0, 0, 255);"); - } - - #[test] - fn same_longhands_should_serialize_correctly() { - let mut properties = Vec::new(); - - let solid = BorderStyle::Solid; - - properties.push(PropertyDeclaration::BorderTopStyle(solid.clone())); - properties.push(PropertyDeclaration::BorderRightStyle(solid.clone())); - properties.push(PropertyDeclaration::BorderBottomStyle(solid.clone())); - properties.push(PropertyDeclaration::BorderLeftStyle(solid.clone())); - - let px_30 = BorderSideWidth::Length(Length::from_px(30f32)); - - properties.push(PropertyDeclaration::BorderTopWidth(px_30.clone())); - properties.push(PropertyDeclaration::BorderRightWidth(px_30.clone())); - properties.push(PropertyDeclaration::BorderBottomWidth(px_30.clone())); - properties.push(PropertyDeclaration::BorderLeftWidth(px_30.clone())); - - let blue = Color::rgba(RGBA::new(0, 0, 255, 255)); - - properties.push(PropertyDeclaration::BorderTopColor(blue.clone())); - properties.push(PropertyDeclaration::BorderRightColor(blue.clone())); - properties.push(PropertyDeclaration::BorderBottomColor(blue.clone())); - properties.push(PropertyDeclaration::BorderLeftColor(blue.clone())); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!( - serialization, - "border-style: solid; border-width: 30px; border-color: rgb(0, 0, 255);" - ); - } - - #[test] - fn padding_should_serialize_correctly() { - use style::values::specified::NonNegativeLengthOrPercentage; - - let mut properties = Vec::new(); - - let px_10: NonNegativeLengthOrPercentage = NoCalcLength::from_px(10f32).into(); - let px_15: NonNegativeLengthOrPercentage = NoCalcLength::from_px(15f32).into(); - properties.push(PropertyDeclaration::PaddingTop(px_10.clone())); - properties.push(PropertyDeclaration::PaddingRight(px_15.clone())); - properties.push(PropertyDeclaration::PaddingBottom(px_10)); - properties.push(PropertyDeclaration::PaddingLeft(px_15)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "padding: 10px 15px;"); - } - - #[test] - fn border_width_should_serialize_correctly() { - let mut properties = Vec::new(); - - let top_px = BorderSideWidth::Length(Length::from_px(10f32)); - let bottom_px = BorderSideWidth::Length(Length::from_px(10f32)); - - let right_px = BorderSideWidth::Length(Length::from_px(15f32)); - let left_px = BorderSideWidth::Length(Length::from_px(15f32)); - - properties.push(PropertyDeclaration::BorderTopWidth(top_px)); - properties.push(PropertyDeclaration::BorderRightWidth(right_px)); - properties.push(PropertyDeclaration::BorderBottomWidth(bottom_px)); - properties.push(PropertyDeclaration::BorderLeftWidth(left_px)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "border-width: 10px 15px;"); - } - - #[test] - fn border_width_with_keywords_should_serialize_correctly() { - let mut properties = Vec::new(); - - let top_px = BorderSideWidth::Thin; - let right_px = BorderSideWidth::Medium; - let bottom_px = BorderSideWidth::Thick; - let left_px = BorderSideWidth::Length(Length::from_px(15f32)); - - properties.push(PropertyDeclaration::BorderTopWidth(top_px)); - properties.push(PropertyDeclaration::BorderRightWidth(right_px)); - properties.push(PropertyDeclaration::BorderBottomWidth(bottom_px)); - properties.push(PropertyDeclaration::BorderLeftWidth(left_px)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "border-width: thin medium thick 15px;"); - } - - #[test] - fn border_color_should_serialize_correctly() { - let mut properties = Vec::new(); - - let red = Color::rgba(RGBA::new(255, 0, 0, 255)); - let blue = Color::rgba(RGBA::new(0, 0, 255, 255)); - - properties.push(PropertyDeclaration::BorderTopColor(blue.clone())); - properties.push(PropertyDeclaration::BorderRightColor(red.clone())); - properties.push(PropertyDeclaration::BorderBottomColor(blue)); - properties.push(PropertyDeclaration::BorderLeftColor(red)); - - let serialization = shorthand_properties_to_string(properties); - - // TODO: Make the rgb test show border-color as blue red instead of below tuples - assert_eq!( - serialization, - "border-color: rgb(0, 0, 255) rgb(255, 0, 0);" - ); - } - - #[test] - fn border_style_should_serialize_correctly() { - let mut properties = Vec::new(); - - let solid = BorderStyle::Solid; - let dotted = BorderStyle::Dotted; - properties.push(PropertyDeclaration::BorderTopStyle(solid.clone())); - properties.push(PropertyDeclaration::BorderRightStyle(dotted.clone())); - properties.push(PropertyDeclaration::BorderBottomStyle(solid)); - properties.push(PropertyDeclaration::BorderLeftStyle(dotted)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "border-style: solid dotted;"); - } - - use style::values::specified::{BorderCornerRadius, Percentage}; - - #[test] - fn border_radius_should_serialize_correctly() { - let mut properties = Vec::new(); - properties.push(PropertyDeclaration::BorderTopLeftRadius(Box::new( - BorderCornerRadius::new(Percentage::new(0.01).into(), Percentage::new(0.05).into()), - ))); - properties.push(PropertyDeclaration::BorderTopRightRadius(Box::new( - BorderCornerRadius::new(Percentage::new(0.02).into(), Percentage::new(0.06).into()), - ))); - properties.push(PropertyDeclaration::BorderBottomRightRadius(Box::new( - BorderCornerRadius::new(Percentage::new(0.03).into(), Percentage::new(0.07).into()), - ))); - properties.push(PropertyDeclaration::BorderBottomLeftRadius(Box::new( - BorderCornerRadius::new(Percentage::new(0.04).into(), Percentage::new(0.08).into()), - ))); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "border-radius: 1% 2% 3% 4% / 5% 6% 7% 8%;"); - } - } - - mod border_shorthands { - use super::*; - - #[test] - fn border_top_and_color() { - let mut properties = Vec::new(); - properties.push(PropertyDeclaration::BorderTopWidth( - BorderSideWidth::Length(Length::from_px(1.)), - )); - properties.push(PropertyDeclaration::BorderTopStyle(BorderStyle::Solid)); - let c = Color::Numeric { - parsed: RGBA::new(255, 0, 0, 255), - authored: Some("green".to_string().into_boxed_str()), - }; - properties.push(PropertyDeclaration::BorderTopColor(c)); - let c = Color::Numeric { - parsed: RGBA::new(0, 255, 0, 255), - authored: Some("red".to_string().into_boxed_str()), - }; - properties.push(PropertyDeclaration::BorderTopColor(c.clone())); - properties.push(PropertyDeclaration::BorderBottomColor(c.clone())); - properties.push(PropertyDeclaration::BorderLeftColor(c.clone())); - properties.push(PropertyDeclaration::BorderRightColor(c.clone())); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!( - serialization, - "border-top: 1px solid red; border-color: red;" - ); - } - - #[test] - fn border_color_and_top() { - let mut properties = Vec::new(); - let c = Color::Numeric { - parsed: RGBA::new(0, 255, 0, 255), - authored: Some("red".to_string().into_boxed_str()), - }; - properties.push(PropertyDeclaration::BorderTopColor(c.clone())); - properties.push(PropertyDeclaration::BorderBottomColor(c.clone())); - properties.push(PropertyDeclaration::BorderLeftColor(c.clone())); - properties.push(PropertyDeclaration::BorderRightColor(c.clone())); - - properties.push(PropertyDeclaration::BorderTopWidth( - BorderSideWidth::Length(Length::from_px(1.)), - )); - properties.push(PropertyDeclaration::BorderTopStyle(BorderStyle::Solid)); - let c = Color::Numeric { - parsed: RGBA::new(255, 0, 0, 255), - authored: Some("green".to_string().into_boxed_str()), - }; - properties.push(PropertyDeclaration::BorderTopColor(c)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!( - serialization, - "border-color: green red red; border-top: 1px solid green;" - ); - } - - // we can use border-top as a base to test out the different combinations - // but afterwards, we only need to to one test per "directional border shorthand" - - #[test] - fn directional_border_should_show_all_properties_when_values_are_set() { - let mut properties = Vec::new(); - - let width = BorderSideWidth::Length(Length::from_px(4f32)); - let style = BorderStyle::Solid; - let color = RGBA::new(255, 0, 0, 255).into(); - - properties.push(PropertyDeclaration::BorderTopWidth(width)); - properties.push(PropertyDeclaration::BorderTopStyle(style)); - properties.push(PropertyDeclaration::BorderTopColor(color)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "border-top: 4px solid rgb(255, 0, 0);"); - } - - fn get_border_property_values() -> (BorderSideWidth, BorderStyle, Color) { - ( - BorderSideWidth::Length(Length::from_px(4f32)), - BorderStyle::Solid, - Color::currentcolor(), - ) - } - - #[test] - fn border_top_should_serialize_correctly() { - let mut properties = Vec::new(); - let (width, style, color) = get_border_property_values(); - properties.push(PropertyDeclaration::BorderTopWidth(width)); - properties.push(PropertyDeclaration::BorderTopStyle(style)); - properties.push(PropertyDeclaration::BorderTopColor(color)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "border-top: 4px solid;"); - } - - #[test] - fn border_right_should_serialize_correctly() { - let mut properties = Vec::new(); - let (width, style, color) = get_border_property_values(); - properties.push(PropertyDeclaration::BorderRightWidth(width)); - properties.push(PropertyDeclaration::BorderRightStyle(style)); - properties.push(PropertyDeclaration::BorderRightColor(color)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "border-right: 4px solid;"); - } - - #[test] - fn border_bottom_should_serialize_correctly() { - let mut properties = Vec::new(); - let (width, style, color) = get_border_property_values(); - properties.push(PropertyDeclaration::BorderBottomWidth(width)); - properties.push(PropertyDeclaration::BorderBottomStyle(style)); - properties.push(PropertyDeclaration::BorderBottomColor(color)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "border-bottom: 4px solid;"); - } - - #[test] - fn border_left_should_serialize_correctly() { - let mut properties = Vec::new(); - let (width, style, color) = get_border_property_values(); - properties.push(PropertyDeclaration::BorderLeftWidth(width)); - properties.push(PropertyDeclaration::BorderLeftStyle(style)); - properties.push(PropertyDeclaration::BorderLeftColor(color)); - - let serialization = shorthand_properties_to_string(properties); - assert_eq!(serialization, "border-left: 4px solid;"); - } - - #[test] - fn border_should_serialize_correctly() { - // According to https://drafts.csswg.org/css-backgrounds-3/#the-border-shorthands, - // the ‘border’ shorthand resets ‘border-image’ to its initial value. To verify the - // serialization of 'border' shorthand, we need to set 'border-image' as well. - let block_text = "\ - border-top: 4px solid; \ - border-right: 4px solid; \ - border-bottom: 4px solid; \ - border-left: 4px solid; \ - border-image: none;"; - - let block = - parse(|c, i| Ok(parse_property_declaration_list(c, i)), block_text).unwrap(); - - let serialization = block.to_css_string(); - - assert_eq!(serialization, "border: 4px solid;"); - } - } - mod list_style { use super::*; use style::properties::longhands::list_style_position::SpecifiedValue as ListStylePosition;