From 4d005cb90ed2919e230d48600a862943f55ed55b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 6 Jul 2018 03:41:56 +0200 Subject: [PATCH 01/16] style: Reformat most of inherited_box.mako.rs. image-orientation is being changed as we speak, so I left it there to avoid bitrot. Bug: 1473779 Reviewed-by: heycam MozReview-Commit-ID: IwpA5HEuVU --- 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 efb3ec19ccb..03ab9ef0fc2 100644 --- a/components/style/properties/longhands/inherited_box.mako.rs +++ b/components/style/properties/longhands/inherited_box.mako.rs @@ -27,6 +27,7 @@ ${helpers.single_keyword( tb=vertical-rl tb-rl=vertical-rl", servo_pref="layout.writing-mode.enabled", animation_value_type="none", + animation_value_type="discrete", spec="https://drafts.csswg.org/css-writing-modes/#propdef-writing-mode", servo_restyle_damage="rebuild_and_reflow", )} From 1c799dd296f854eb669c4e43768788f4ebb88c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 6 Jul 2018 03:44:28 +0200 Subject: [PATCH 02/16] style: Make writing-mode and direction non-animatable. Per https://github.com/w3c/csswg-drafts/issues/2751 Bug: 1473779 Reviewed-by: heycam MozReview-Commit-ID: GCG3vJWNPfC --- 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 03ab9ef0fc2..efb3ec19ccb 100644 --- a/components/style/properties/longhands/inherited_box.mako.rs +++ b/components/style/properties/longhands/inherited_box.mako.rs @@ -27,7 +27,6 @@ ${helpers.single_keyword( tb=vertical-rl tb-rl=vertical-rl", servo_pref="layout.writing-mode.enabled", animation_value_type="none", - animation_value_type="discrete", spec="https://drafts.csswg.org/css-writing-modes/#propdef-writing-mode", servo_restyle_damage="rebuild_and_reflow", )} From 4e8d3fce38dbeb7ab290dd7264b81b7ea137882c Mon Sep 17 00:00:00 2001 From: Oriol Brufau Date: Thu, 5 Jul 2018 12:56:34 +0200 Subject: [PATCH 03/16] style: Honor logical border colors in visited links. Bug: 1472567 Reviewed-by: emilio MozReview-Commit-ID: IF8yvkFmPc4 --- components/style/properties/properties.mako.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 3e6676842c5..7eb36f8d418 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -3768,14 +3768,6 @@ where PropertyDeclarationId::Custom(..) => continue, }; - // Only a few properties are allowed to depend on the visited state - // of links. When cascading visited styles, we can save time by - // only processing these properties. - if flags.contains(CascadeFlags::VISITED_DEPENDENT_ONLY) && - !longhand_id.is_visited_dependent() { - continue - } - if !apply_reset && !longhand_id.inherited() { continue; } @@ -3795,6 +3787,14 @@ where continue } + // Only a few properties are allowed to depend on the visited state + // of links. When cascading visited styles, we can save time by + // only processing these properties. + if flags.contains(CascadeFlags::VISITED_DEPENDENT_ONLY) && + !physical_longhand_id.is_visited_dependent() { + continue + } + let mut declaration = match *declaration { PropertyDeclaration::WithVariables(ref declaration) => { if !declaration.id.inherited() { From f526af7f0196399fadc21811c7bc4fcbe58692da Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Thu, 5 Jul 2018 12:04:58 +1000 Subject: [PATCH 04/16] style: Remove angle values from image-orientation. Bug: 1473450 Reviewed-by: emilio MozReview-Commit-ID: FB74ILJM6Fm --- components/style/properties/data.py | 1 - components/style/properties/gecko.mako.rs | 59 +------ .../longhands/inherited_box.mako.rs | 17 +- .../style/values/computed/inherited_box.rs | 81 --------- components/style/values/computed/mod.rs | 2 - .../style/values/specified/inherited_box.rs | 158 ------------------ components/style/values/specified/mod.rs | 2 - 7 files changed, 10 insertions(+), 310 deletions(-) delete mode 100644 components/style/values/computed/inherited_box.rs delete mode 100644 components/style/values/specified/inherited_box.rs diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 08001628e60..57838655d8e 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -285,7 +285,6 @@ class Longhand(object): "FontSynthesis", "FontWeight", "GridAutoFlow", - "ImageOrientation", "InitialLetter", "Integer", "JustifyContent", diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index c82288e14ae..3980700407f 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -4533,64 +4533,7 @@ fn static_assert() { -<%self:impl_trait style_struct_name="InheritedBox" - skip_longhands="image-orientation"> - // FIXME: Gecko uses a tricky way to store computed value of image-orientation - // within an u8. We could inline following glue codes by implementing all - // those tricky parts for Servo as well. But, it's not done yet just for - // convenience. - pub fn set_image_orientation(&mut self, v: longhands::image_orientation::computed_value::T) { - use properties::longhands::image_orientation::computed_value::T; - match v { - T::FromImage => { - unsafe { - bindings::Gecko_SetImageOrientationAsFromImage(&mut self.gecko); - } - }, - T::AngleWithFlipped(ref orientation, flipped) => { - unsafe { - bindings::Gecko_SetImageOrientation(&mut self.gecko, *orientation as u8, flipped); - } - } - } - } - - pub fn copy_image_orientation_from(&mut self, other: &Self) { - unsafe { - bindings::Gecko_CopyImageOrientationFrom(&mut self.gecko, &other.gecko); - } - } - - pub fn reset_image_orientation(&mut self, other: &Self) { - self.copy_image_orientation_from(other) - } - - pub fn clone_image_orientation(&self) -> longhands::image_orientation::computed_value::T { - use gecko_bindings::structs::nsStyleImageOrientation_Angles; - use properties::longhands::image_orientation::computed_value::T; - use values::computed::Orientation; - - let gecko_orientation = self.gecko.mImageOrientation.mOrientation; - if gecko_orientation & structs::nsStyleImageOrientation_Bits_FROM_IMAGE_MASK as u8 != 0 { - T::FromImage - } else { - const ANGLE0: u8 = nsStyleImageOrientation_Angles::ANGLE_0 as u8; - const ANGLE90: u8 = nsStyleImageOrientation_Angles::ANGLE_90 as u8; - const ANGLE180: u8 = nsStyleImageOrientation_Angles::ANGLE_180 as u8; - const ANGLE270: u8 = nsStyleImageOrientation_Angles::ANGLE_270 as u8; - - let flip = gecko_orientation & structs::nsStyleImageOrientation_Bits_FLIP_MASK as u8 != 0; - let orientation = - match gecko_orientation & structs::nsStyleImageOrientation_Bits_ORIENTATION_MASK as u8 { - ANGLE0 => Orientation::Angle0, - ANGLE90 => Orientation::Angle90, - ANGLE180 => Orientation::Angle180, - ANGLE270 => Orientation::Angle270, - _ => unreachable!() - }; - T::AngleWithFlipped(orientation, flip) - } - } +<%self:impl_trait style_struct_name="InheritedBox"> <%self:impl_trait style_struct_name="InheritedTable" diff --git a/components/style/properties/longhands/inherited_box.mako.rs b/components/style/properties/longhands/inherited_box.mako.rs index efb3ec19ccb..4482931fd7a 100644 --- a/components/style/properties/longhands/inherited_box.mako.rs +++ b/components/style/properties/longhands/inherited_box.mako.rs @@ -76,11 +76,12 @@ ${helpers.single_keyword( spec="https://drafts.csswg.org/css-images/#propdef-image-rendering", )} -${helpers.predefined_type("image-orientation", - "ImageOrientation", - "computed::ImageOrientation::zero()", - products="gecko", - animation_value_type="discrete", - gecko_pref="layout.css.image-orientation.enabled", - spec="https://drafts.csswg.org/css-images/#propdef-image-orientation, \ - /// additional values in https://developer.mozilla.org/en-US/docs/Web/CSS/image-orientation")} +${helpers.single_keyword( + "image-orientation", + "none from-image", + 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", +)} diff --git a/components/style/values/computed/inherited_box.rs b/components/style/values/computed/inherited_box.rs deleted file mode 100644 index f6fe6ad7bf9..00000000000 --- a/components/style/values/computed/inherited_box.rs +++ /dev/null @@ -1,81 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -//! Computed values for inherited box - -use std::fmt::{self, Write}; -use style_traits::{CssWriter, ToCss}; -use values::specified::Angle; - -/// An angle rounded and normalized per https://drafts.csswg.org/css-images/#propdef-image-orientation -#[allow(missing_docs)] -#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)] -pub enum Orientation { - Angle0 = 0, - Angle90, - Angle180, - Angle270, -} - -impl Orientation { - /// Get the actual angle that this orientation value represents. - pub fn angle(&self) -> Angle { - match *self { - Orientation::Angle0 => Angle::from_degrees(0.0, false), - Orientation::Angle90 => Angle::from_degrees(90.0, false), - Orientation::Angle180 => Angle::from_degrees(180.0, false), - Orientation::Angle270 => Angle::from_degrees(270.0, false), - } - } -} - -impl ToCss for Orientation { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: Write, - { - // Should agree with Angle::to_css. - match *self { - Orientation::Angle0 => dest.write_str("0deg"), - Orientation::Angle90 => dest.write_str("90deg"), - Orientation::Angle180 => dest.write_str("180deg"), - Orientation::Angle270 => dest.write_str("270deg"), - } - } -} - -/// https://drafts.csswg.org/css-images/#propdef-image-orientation -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] -pub enum ImageOrientation { - /// 'from-image' - FromImage, - - /// '' | '? flip' - AngleWithFlipped(Orientation, bool), -} - -impl ImageOrientation { - #[allow(missing_docs)] - pub fn zero() -> Self { - ImageOrientation::AngleWithFlipped(Orientation::Angle0, false) - } -} - -impl ToCss for ImageOrientation { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: Write, - { - match *self { - ImageOrientation::FromImage => dest.write_str("from-image"), - ImageOrientation::AngleWithFlipped(angle, flipped) => { - angle.to_css(dest)?; - if flipped { - dest.write_str(" flip")?; - } - Ok(()) - }, - } - } -} diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index fa5a2425d1f..14a74a4ed53 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -52,7 +52,6 @@ pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset}; pub use self::effects::{BoxShadow, Filter, SimpleShadow}; pub use self::flex::FlexBasis; pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect}; -pub use self::inherited_box::{ImageOrientation, Orientation}; #[cfg(feature = "gecko")] pub use self::gecko::ScrollSnapPoint; pub use self::rect::LengthOrNumberRect; @@ -99,7 +98,6 @@ pub mod font; #[cfg(feature = "gecko")] pub mod gecko; pub mod image; -pub mod inherited_box; pub mod length; pub mod list; pub mod outline; diff --git a/components/style/values/specified/inherited_box.rs b/components/style/values/specified/inherited_box.rs deleted file mode 100644 index c7756f974f2..00000000000 --- a/components/style/values/specified/inherited_box.rs +++ /dev/null @@ -1,158 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -//! Specified values for inherited box - -use cssparser::Parser; -use parser::{Parse, ParserContext}; -use std::f64::consts::PI; -use std::fmt::{self, Write}; -use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; -use values::computed; -use values::computed::{Context, Orientation, ToComputedValue}; -use values::specified::Angle; - -/// The specified value of the `image-orientation` property. -/// https://drafts.csswg.org/css-images/#propdef-image-orientation -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo)] -pub struct ImageOrientation { - /// The angle specified, if any - pub angle: Option, - - /// Whether or not "flip" was specified - #[value_info(other_values = "flip,from-image")] - pub flipped: bool, -} - -impl ToCss for ImageOrientation { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: Write, - { - if let Some(angle) = self.angle { - angle.to_css(dest)?; - if self.flipped { - dest.write_str(" flip") - } else { - Ok(()) - } - } else { - if self.flipped { - dest.write_str("flip") - } else { - dest.write_str("from-image") - } - } - } -} - -const TWO_PI: f64 = 2.0 * PI; - -// According to CSS Content Module Level 3: -// The computed value of the property is calculated by rounding the specified angle -// to the nearest quarter-turn, rounding away from 0, then moduloing the value by 1 turn. -// This mirrors the Gecko implementation in -// nsStyleImageOrientation::CreateAsAngleAndFlip. -#[inline] -fn orientation_of_angle(angle: &computed::Angle) -> Orientation { - // Note that `angle` can be negative. - let mut rounded_angle = angle.radians64() % TWO_PI; - if rounded_angle < 0.0 { - // This computation introduces rounding error. Gecko previously - // didn't handle the negative case correctly; by branching we can - // match Gecko's behavior when it was correct. - rounded_angle += TWO_PI; - } - if rounded_angle < 0.25 * PI { - return Orientation::Angle0; - } - if rounded_angle < 0.75 * PI { - return Orientation::Angle90; - } - if rounded_angle < 1.25 * PI { - return Orientation::Angle180; - } - if rounded_angle < 1.75 * PI { - return Orientation::Angle270; - } - Orientation::Angle0 -} - -impl ToComputedValue for ImageOrientation { - type ComputedValue = computed::ImageOrientation; - - #[inline] - fn to_computed_value(&self, context: &Context) -> computed::ImageOrientation { - if let Some(ref angle) = self.angle { - let angle = angle.to_computed_value(context); - let orientation = orientation_of_angle(&angle); - computed::ImageOrientation::AngleWithFlipped(orientation, self.flipped) - } else { - if self.flipped { - computed::ImageOrientation::zero() - } else { - computed::ImageOrientation::FromImage - } - } - } - - #[inline] - fn from_computed_value(computed: &computed::ImageOrientation) -> Self { - match *computed { - computed::ImageOrientation::FromImage => ImageOrientation { - angle: None, - flipped: false, - }, - - computed::ImageOrientation::AngleWithFlipped(ref orientation, flipped) => { - ImageOrientation { - angle: Some(orientation.angle()), - flipped: flipped, - } - }, - } - } -} - -impl Parse for ImageOrientation { - // from-image | | [? flip] - fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - if input - .try(|input| input.expect_ident_matching("from-image")) - .is_ok() - { - // Handle from-image - Ok(ImageOrientation { - angle: None, - flipped: false, - }) - } else if input - .try(|input| input.expect_ident_matching("flip")) - .is_ok() - { - // Handle flip - Ok(ImageOrientation { - angle: Some(Angle::zero()), - flipped: true, - }) - } else { - // Handle | flip - let angle = input.try(|input| Angle::parse(context, input)).ok(); - if angle.is_none() { - return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); - } - - let flipped = input - .try(|input| input.expect_ident_matching("flip")) - .is_ok(); - Ok(ImageOrientation { - angle: angle, - flipped: flipped, - }) - } - } -} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index ad1b0f07416..d33872f1bab 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -49,7 +49,6 @@ pub use self::flex::FlexBasis; pub use self::gecko::ScrollSnapPoint; pub use self::image::{ColorStop, EndingShape as GradientEndingShape, Gradient}; pub use self::image::{GradientItem, GradientKind, Image, ImageLayer, MozImageRect}; -pub use self::inherited_box::ImageOrientation; pub use self::length::{AbsoluteLength, CalcLengthOrPercentage, CharacterWidth}; pub use self::length::{FontRelativeLength, Length, LengthOrNumber}; pub use self::length::{LengthOrPercentage, LengthOrPercentageOrAuto}; @@ -99,7 +98,6 @@ pub mod font; pub mod gecko; pub mod grid; pub mod image; -pub mod inherited_box; pub mod length; pub mod list; pub mod outline; From 36038869aa10485042d791792fdb7de17d5fce01 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Mon, 9 Jul 2018 16:03:32 +1000 Subject: [PATCH 05/16] style: Rename DeclarationSource to DeclarationPushMode. Bug: 1461285 Reviewed-by: emilio MozReview-Commit-ID: Iyv9JrXrpzl --- .../style/properties/declaration_block.rs | 42 +++++++++---------- .../style/stylesheets/keyframes_rule.rs | 4 +- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index 8727ba4cc41..92fa0bc4134 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -39,13 +39,17 @@ impl AnimationRules { } } -/// Whether a given declaration comes from CSS parsing, or from CSSOM. +/// Enum for how a given declaration should be pushed into a declaration block. #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq)] -pub enum DeclarationSource { - /// The declaration was obtained from CSS parsing of sheets and such. +pub enum DeclarationPushMode { + /// Mode used when declarations were obtained from CSS parsing. + /// If there is an existing declaration of the same property with a higher + /// importance, the new declaration will be discarded. Otherwise, it will + /// be appended to the end of the declaration block. Parsing, - /// The declaration was obtained from CSSOM. - CssOm, + /// In this mode, the new declaration is always pushed to the end of the + /// declaration block. This is for CSSOM. + Append, } /// A declaration [importance][importance]. @@ -418,10 +422,10 @@ impl PropertyDeclarationBlock { &mut self, mut drain: SourcePropertyDeclarationDrain, importance: Importance, - source: DeclarationSource, + mode: DeclarationPushMode, ) -> bool { - match source { - DeclarationSource::Parsing => { + match mode { + DeclarationPushMode::Parsing => { let all_shorthand_len = match drain.all_shorthand { AllShorthand::NotSet => 0, AllShorthand::CSSWideKeyword(_) | @@ -433,7 +437,7 @@ impl PropertyDeclarationBlock { // With deduplication the actual length increase may be less than this. self.declarations.reserve(push_calls_count); } - DeclarationSource::CssOm => { + _ => { // Don't bother reserving space, since it's usually the case // that CSSOM just overrides properties and we don't need to use // more memory. See bug 1424346 for an example where this @@ -448,7 +452,7 @@ impl PropertyDeclarationBlock { changed |= self.push( decl, importance, - source, + mode, ); } match drain.all_shorthand { @@ -461,7 +465,7 @@ impl PropertyDeclarationBlock { changed |= self.push( decl, importance, - source, + mode, ); } } @@ -473,7 +477,7 @@ impl PropertyDeclarationBlock { changed |= self.push( decl, importance, - source, + mode, ); } } @@ -483,22 +487,16 @@ impl PropertyDeclarationBlock { /// Adds or overrides the declaration for a given property in this block. /// - /// Depending on the value of `source`, this has a different behavior in the + /// Depending on the value of `mode`, this has a different behavior in the /// presence of another declaration with the same ID in the declaration /// block. /// - /// * For `DeclarationSource::Parsing`, this will not override a - /// declaration with more importance, and will ensure that, if inserted, - /// it's inserted at the end of the declaration block. - /// - /// * For `DeclarationSource::CssOm`, this will override importance. - /// /// Returns whether the declaration has changed. pub fn push( &mut self, declaration: PropertyDeclaration, importance: Importance, - source: DeclarationSource, + mode: DeclarationPushMode, ) -> bool { let longhand_id = match declaration.id() { PropertyDeclarationId::Longhand(id) => Some(id), @@ -516,7 +514,7 @@ impl PropertyDeclarationBlock { continue; } - if matches!(source, DeclarationSource::Parsing) { + if matches!(mode, DeclarationPushMode::Parsing) { let important = self.declarations_importance[i]; // For declarations from parsing, non-important declarations @@ -1209,7 +1207,7 @@ pub fn parse_property_declaration_list( block.extend( iter.parser.declarations.drain(), importance, - DeclarationSource::Parsing, + DeclarationPushMode::Parsing, ); } Err((error, slice)) => { diff --git a/components/style/stylesheets/keyframes_rule.rs b/components/style/stylesheets/keyframes_rule.rs index 85dc00bb9af..82476652b9c 100644 --- a/components/style/stylesheets/keyframes_rule.rs +++ b/components/style/stylesheets/keyframes_rule.rs @@ -8,7 +8,7 @@ use cssparser::{AtRuleParser, CowRcStr, Parser, ParserInput, QualifiedRuleParser use cssparser::{parse_one_rule, DeclarationListParser, DeclarationParser, SourceLocation, Token}; use error_reporting::ContextualParseError; use parser::ParserContext; -use properties::{DeclarationSource, Importance, PropertyDeclaration}; +use properties::{DeclarationPushMode, Importance, PropertyDeclaration}; use properties::{LonghandId, PropertyDeclarationBlock, PropertyId}; use properties::{PropertyDeclarationId, SourcePropertyDeclaration}; use properties::LonghandIdSet; @@ -554,7 +554,7 @@ impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> { block.extend( iter.parser.declarations.drain(), Importance::Normal, - DeclarationSource::Parsing, + DeclarationPushMode::Parsing, ); }, Err((error, slice)) => { From 2be13757458120f44173921c0f4f90dd8c38c2d5 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 11 Jul 2018 10:52:52 +1000 Subject: [PATCH 06/16] style: Add a declaration iterator to AllShorthand for simplify code. Bug: 1461285 Reviewed-by: emilio MozReview-Commit-ID: 9w2B3SpdkQo --- .../style/properties/declaration_block.rs | 31 ++----------- .../style/properties/properties.mako.rs | 44 +++++++++++++++++++ 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index 92fa0bc4134..0d5ba518935 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -455,34 +455,9 @@ impl PropertyDeclarationBlock { mode, ); } - match drain.all_shorthand { - AllShorthand::NotSet => {} - AllShorthand::CSSWideKeyword(keyword) => { - for id in ShorthandId::All.longhands() { - let decl = PropertyDeclaration::CSSWideKeyword( - WideKeywordDeclaration { id, keyword }, - ); - changed |= self.push( - decl, - importance, - mode, - ); - } - } - AllShorthand::WithVariables(unparsed) => { - for id in ShorthandId::All.longhands() { - let decl = PropertyDeclaration::WithVariables( - VariableDeclaration { id, value: unparsed.clone() }, - ); - changed |= self.push( - decl, - importance, - mode, - ); - } - } - } - changed + drain.all_shorthand.declarations().fold(changed, |changed, decl| { + changed | self.push(decl, importance, mode) + }) } /// Adds or overrides the declaration for a given property in this block. diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 7eb36f8d418..dcc85d57509 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -2222,6 +2222,50 @@ enum AllShorthand { WithVariables(Arc) } +impl AllShorthand { + /// Iterates property declarations from the given all shorthand value. + #[inline] + fn declarations(&self) -> AllShorthandDeclarationIterator { + AllShorthandDeclarationIterator { + all_shorthand: self, + longhands: ShorthandId::All.longhands(), + } + } +} + +struct AllShorthandDeclarationIterator<'a> { + all_shorthand: &'a AllShorthand, + longhands: NonCustomPropertyIterator, +} + +impl<'a> Iterator for AllShorthandDeclarationIterator<'a> { + type Item = PropertyDeclaration; + + #[inline] + fn next(&mut self) -> Option { + match *self.all_shorthand { + AllShorthand::NotSet => None, + AllShorthand::CSSWideKeyword(ref keyword) => { + Some(PropertyDeclaration::CSSWideKeyword( + WideKeywordDeclaration { + id: self.longhands.next()?, + keyword: *keyword + } + )) + } + AllShorthand::WithVariables(ref unparsed) => { + let id = self.longhands.next()?; + Some(PropertyDeclaration::WithVariables( + VariableDeclaration { + id: self.longhands.next()?, + value: unparsed.clone() + } + )) + } + } + } +} + #[cfg(feature = "gecko")] pub use gecko_properties::style_structs; From d4ea70fd348fdbc66b9fa4a21955bf8a36c783ef Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 11 Jul 2018 10:54:47 +1000 Subject: [PATCH 07/16] style: Have the CSSOM appending behavior behind a pref and only enable it on Nightly. Bug: 1461285 Reviewed-by: emilio MozReview-Commit-ID: 6BzPTNjXjyA --- .../style/properties/declaration_block.rs | 67 +++++++++++++++---- 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index 0d5ba518935..29277eef1d8 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -47,8 +47,12 @@ pub enum DeclarationPushMode { /// importance, the new declaration will be discarded. Otherwise, it will /// be appended to the end of the declaration block. Parsing, + /// In this mode, if there is an existing declaration of the same property, + /// the value is updated in-place. Otherwise it's appended. This is one + /// possible behavior of CSSOM. + Update, /// In this mode, the new declaration is always pushed to the end of the - /// declaration block. This is for CSSOM. + /// declaration block. This is another possible behavior of CSSOM. Append, } @@ -414,10 +418,49 @@ impl PropertyDeclarationBlock { } } + /// Returns whether the property is definitely new for this declaration + /// block. It returns true when the declaration is a non-custom longhand + /// and it doesn't exist in the block, and returns false otherwise. + #[inline] + fn is_definitely_new(&self, decl: &PropertyDeclaration) -> bool { + match decl.id() { + PropertyDeclarationId::Longhand(id) => !self.longhands.contains(id), + PropertyDeclarationId::Custom(..) => false, + } + } + + /// Returns whether calling extend with `DeclarationPushMode::Update` + /// will cause this declaration block to change. + pub fn will_change_in_update_mode( + &self, + source_declarations: &SourcePropertyDeclaration, + importance: Importance, + ) -> bool { + // XXX The type of parameter seems to be necessary because otherwise + // the compiler complains about `decl` not living long enough in the + // all_shorthand expression. Why? + let needs_update = |decl: &_| { + if self.is_definitely_new(decl) { + return true; + } + self.declarations.iter().enumerate() + .find(|&(_, ref slot)| slot.id() == decl.id()) + .map_or(true, |(i, slot)| { + let important = self.declarations_importance[i]; + *slot != *decl || important != importance.important() + }) + }; + source_declarations.declarations.iter().any(&needs_update) || + source_declarations.all_shorthand.declarations().any(|decl| needs_update(&decl)) + } + /// Adds or overrides the declaration for a given property in this block. /// /// See the documentation of `push` to see what impact `source` has when the /// property is already there. + /// + /// When calling with `DeclarationPushMode::Update`, this should not change + /// anything if `will_change_in_update_mode` returns false. pub fn extend( &mut self, mut drain: SourcePropertyDeclarationDrain, @@ -473,16 +516,7 @@ impl PropertyDeclarationBlock { importance: Importance, mode: DeclarationPushMode, ) -> bool { - let longhand_id = match declaration.id() { - PropertyDeclarationId::Longhand(id) => Some(id), - PropertyDeclarationId::Custom(..) => None, - }; - - let definitely_new = longhand_id.map_or(false, |id| { - !self.longhands.contains(id) - }); - - if !definitely_new { + if !self.is_definitely_new(&declaration) { let mut index_to_remove = None; for (i, slot) in self.declarations.iter_mut().enumerate() { if slot.id() != declaration.id() { @@ -514,6 +548,15 @@ impl PropertyDeclarationBlock { } } } + if matches!(mode, DeclarationPushMode::Update) { + let important = self.declarations_importance[i]; + if *slot == declaration && important == importance.important() { + return false; + } + *slot = declaration; + self.declarations_importance.set(i, importance.important()); + return true; + } index_to_remove = Some(i); break; @@ -528,7 +571,7 @@ impl PropertyDeclarationBlock { } } - if let Some(id) = longhand_id { + if let PropertyDeclarationId::Longhand(id) = declaration.id() { self.longhands.insert(id); } self.declarations.push(declaration); From dd277be4871472b461727ea99367773d5e3ac3a5 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Thu, 12 Jul 2018 14:19:16 +1000 Subject: [PATCH 08/16] style: Remove a unused line to fix a warning. Bug: 1461285 --- components/style/properties/properties.mako.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index dcc85d57509..9372068b052 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -2254,7 +2254,6 @@ impl<'a> Iterator for AllShorthandDeclarationIterator<'a> { )) } AllShorthand::WithVariables(ref unparsed) => { - let id = self.longhands.next()?; Some(PropertyDeclaration::WithVariables( VariableDeclaration { id: self.longhands.next()?, From a41127152b333d7f59554d630e5bfee64d7cfd73 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Thu, 12 Jul 2018 19:44:00 +1000 Subject: [PATCH 09/16] style: Measure heap allocations hanging off selector components. Bug: 1475191 Reviewed-by: emilio MozReview-Commit-ID: D7vZQ7v8owS --- components/malloc_size_of/lib.rs | 84 +++++++++++++++++++ .../gecko/pseudo_element_definition.mako.rs | 2 +- components/style/gecko/selector_parser.rs | 2 +- components/style/selector_parser.rs | 2 +- components/style/stylesheets/style_rule.rs | 15 +--- 5 files changed, 89 insertions(+), 16 deletions(-) diff --git a/components/malloc_size_of/lib.rs b/components/malloc_size_of/lib.rs index eaec2cb20dc..641d276483e 100644 --- a/components/malloc_size_of/lib.rs +++ b/components/malloc_size_of/lib.rs @@ -693,6 +693,90 @@ impl MallocSizeOf for selectors::parser::AncestorHashes { } } +impl MallocSizeOf + for selectors::parser::Selector +where + Impl::NonTSPseudoClass: MallocSizeOf, + Impl::PseudoElement: MallocSizeOf, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + let mut n = 0; + + // It's OK to measure this ThinArc directly because it's the + // "primary" reference. (The secondary references are on the + // Stylist.) + n += unsafe { ops.malloc_size_of(self.thin_arc_heap_ptr()) }; + for component in self.iter_raw_match_order() { + n += component.size_of(ops); + } + + n + } +} + +impl MallocSizeOf + for selectors::parser::Component +where + Impl::NonTSPseudoClass: MallocSizeOf, + Impl::PseudoElement: MallocSizeOf, +{ + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + use selectors::parser::Component; + + match self { + Component::AttributeOther(ref attr_selector) => { + attr_selector.size_of(ops) + } + Component::Negation(ref components) => { + components.size_of(ops) + } + Component::NonTSPseudoClass(ref pseudo) => { + (*pseudo).size_of(ops) + } + Component::Slotted(ref selector) | + Component::Host(Some(ref selector)) => { + selector.size_of(ops) + } + Component::PseudoElement(ref pseudo) => { + (*pseudo).size_of(ops) + } + Component::Combinator(..) | + Component::ExplicitAnyNamespace | + Component::ExplicitNoNamespace | + Component::DefaultNamespace(..) | + Component::Namespace(..) | + Component::ExplicitUniversalType | + Component::LocalName(..) | + Component::ID(..) | + Component::Class(..) | + Component::AttributeInNoNamespaceExists { .. } | + Component::AttributeInNoNamespace { .. } | + Component::FirstChild | + Component::LastChild | + Component::OnlyChild | + Component::Root | + Component::Empty | + Component::Scope | + Component::NthChild(..) | + Component::NthLastChild(..) | + Component::NthOfType(..) | + Component::NthLastOfType(..) | + Component::FirstOfType | + Component::LastOfType | + Component::OnlyOfType | + Component::Host(None) => 0, + } + } +} + +impl MallocSizeOf + for selectors::attr::AttrSelectorWithNamespace +{ + fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { + 0 + } +} + impl MallocSizeOf for Void { #[inline] fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { diff --git a/components/style/gecko/pseudo_element_definition.mako.rs b/components/style/gecko/pseudo_element_definition.mako.rs index caaeeac629d..216650c9295 100644 --- a/components/style/gecko/pseudo_element_definition.mako.rs +++ b/components/style/gecko/pseudo_element_definition.mako.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /// Gecko's pseudo-element definition. -#[derive(Clone, Debug, Eq, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq)] pub enum PseudoElement { % for pseudo in PSEUDOS: /// ${pseudo.value} diff --git a/components/style/gecko/selector_parser.rs b/components/style/gecko/selector_parser.rs index 7dfc9aa1bbc..45f42acc09d 100644 --- a/components/style/gecko/selector_parser.rs +++ b/components/style/gecko/selector_parser.rs @@ -40,7 +40,7 @@ macro_rules! pseudo_class_name { (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => { /// Our representation of a non tree-structural pseudo-class. - #[derive(Clone, Debug, Eq, PartialEq)] + #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)] pub enum NonTSPseudoClass { $( #[doc = $css] diff --git a/components/style/selector_parser.rs b/components/style/selector_parser.rs index e93085af141..7250502b1ad 100644 --- a/components/style/selector_parser.rs +++ b/components/style/selector_parser.rs @@ -172,7 +172,7 @@ impl PerPseudoElementMap { } /// Values for the :dir() pseudo class -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)] pub enum Direction { /// left-to-right semantic directionality Ltr, diff --git a/components/style/stylesheets/style_rule.rs b/components/style/stylesheets/style_rule.rs index 9a34c203818..c161cc43ee2 100644 --- a/components/style/stylesheets/style_rule.rs +++ b/components/style/stylesheets/style_rule.rs @@ -6,7 +6,7 @@ use cssparser::SourceLocation; #[cfg(feature = "gecko")] -use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps}; +use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; #[cfg(feature = "gecko")] use malloc_size_of::MallocUnconditionalShallowSizeOf; use properties::PropertyDeclarationBlock; @@ -50,20 +50,9 @@ impl StyleRule { #[cfg(feature = "gecko")] pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { let mut n = 0; - - // We may add measurement of things hanging off the embedded Components - // later. - n += self.selectors.0.shallow_size_of(ops); - for selector in self.selectors.0.iter() { - // It's safe to measure this ThinArc directly because it's the - // "primary" reference. (The secondary references are on the - // Stylist.) - n += unsafe { ops.malloc_size_of(selector.thin_arc_heap_ptr()) }; - } - + n += self.selectors.0.size_of(ops); n += self.block.unconditional_shallow_size_of(ops) + self.block.read_with(guard).size_of(ops); - n } } From db74d0c579a322c9d946ace0b3e10097aeebd91f Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Fri, 13 Jul 2018 22:06:05 +1000 Subject: [PATCH 10/16] style: Remove unused parent parameter in ComputedValues::new. Bug: 1475229 MozReview-Commit-ID: EBG0TS7tI4P --- components/style/properties/gecko.mako.rs | 19 +++++++++---------- .../style/properties/properties.mako.rs | 8 -------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 3980700407f..c262af439ca 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -83,7 +83,6 @@ pub struct ComputedValues(::gecko_bindings::structs::mozilla::ComputedStyle); impl ComputedValues { pub fn new( device: &Device, - parent: Option<<&ComputedValues>, pseudo: Option<<&PseudoElement>, custom_properties: Option>, writing_mode: WritingMode, @@ -105,7 +104,6 @@ impl ComputedValues { % endfor ).to_outer( device.pres_context(), - parent, pseudo.map(|p| p.pseudo_info()) ) } @@ -120,7 +118,7 @@ impl ComputedValues { % for style_struct in data.style_structs: style_structs::${style_struct.name}::default(pres_context), % endfor - ).to_outer(pres_context, None, None) + ).to_outer(pres_context, None) } pub fn pseudo(&self) -> Option { @@ -195,7 +193,6 @@ impl Clone for ComputedValuesInner { } type PseudoInfo = (*mut structs::nsAtom, structs::CSSPseudoElementType); -type ParentComputedStyleInfo<'a> = Option< &'a ComputedValues>; impl ComputedValuesInner { pub fn new(custom_properties: Option>, @@ -222,7 +219,6 @@ impl ComputedValuesInner { fn to_outer( self, pres_context: RawGeckoPresContextBorrowed, - parent: ParentComputedStyleInfo, info: Option ) -> Arc { let (tag, ty) = if let Some(info) = info { @@ -231,21 +227,24 @@ impl ComputedValuesInner { (ptr::null_mut(), structs::CSSPseudoElementType::NotPseudo) }; - unsafe { self.to_outer_helper(pres_context, parent, ty, tag) } + unsafe { self.to_outer_helper(pres_context, ty, tag) } } unsafe fn to_outer_helper( self, pres_context: bindings::RawGeckoPresContextBorrowed, - parent: ParentComputedStyleInfo, pseudo_ty: structs::CSSPseudoElementType, pseudo_tag: *mut structs::nsAtom ) -> Arc { let arc = { let arc: Arc = Arc::new(uninitialized()); - bindings::Gecko_ComputedStyle_Init(&arc.0 as *const _ as *mut _, - parent, pres_context, - &self, pseudo_ty, pseudo_tag); + bindings::Gecko_ComputedStyle_Init( + &arc.0 as *const _ as *mut _, + pres_context, + &self, + pseudo_ty, + pseudo_tag + ); // We're simulating a move by having C++ do a memcpy and then forgetting // it on this end. forget(self); diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 9372068b052..a4396d0b4fd 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -2720,7 +2720,6 @@ impl ComputedValues { /// Create a new refcounted `ComputedValues` pub fn new( _: &Device, - _: Option<<&ComputedValues>, _: Option<<&PseudoElement>, custom_properties: Option>, writing_mode: WritingMode, @@ -3128,10 +3127,6 @@ pub struct StyleBuilder<'a> { /// The style we're getting reset structs from. reset_style: &'a ComputedValues, - /// The style we're inheriting from explicitly, or none if we're the root of - /// a subtree. - parent_style: Option<<&'a ComputedValues>, - /// The rule node representing the ordered list of rules matched for this /// node. pub rules: Option, @@ -3199,7 +3194,6 @@ impl<'a> StyleBuilder<'a> { StyleBuilder { device, - parent_style, inherited_style, inherited_style_ignoring_first_line, reset_style, @@ -3243,7 +3237,6 @@ impl<'a> StyleBuilder<'a> { parent_style.unwrap().pseudo() != Some(PseudoElement::FirstLine)); StyleBuilder { device, - parent_style, inherited_style, // None of our callers pass in ::first-line parent styles. inherited_style_ignoring_first_line: inherited_style, @@ -3485,7 +3478,6 @@ impl<'a> StyleBuilder<'a> { pub fn build(self) -> Arc { ComputedValues::new( self.device, - self.parent_style, self.pseudo, self.custom_properties, self.writing_mode, From 6f9b47be2516533c5e5e50df1383788109dfec3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 12 Jul 2018 08:58:09 +0200 Subject: [PATCH 11/16] style: Cleanup push_applicable_declarations. r=xidorn This patch changes the behavior to skipping XBL rules for getDefaultComputedStyle. Bug: 1475220 Reviewed-by: xidorn MozReview-Commit-ID: 52cwDyBAXO --- components/style/stylist.rs | 83 ++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/components/style/stylist.rs b/components/style/stylist.rs index aa5f77d0db4..5acdcf33bb0 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -1175,7 +1175,6 @@ impl Stylist { pseudo_element.is_some() ); - let only_default_rules = rule_inclusion == RuleInclusion::DefaultOnly; let matches_user_rules = rule_hash_target.matches_user_and_author_rules(); let matches_author_rules = matches_user_rules && self.author_styles_enabled == AuthorStylesEnabled::Yes; @@ -1220,7 +1219,11 @@ impl Stylist { } } - if pseudo_element.is_none() && !only_default_rules { + if rule_inclusion == RuleInclusion::DefaultOnly { + return; + } + + if pseudo_element.is_none() { // Presentational hints. // // These go before author rules, but after user rules, see: @@ -1230,8 +1233,8 @@ impl Stylist { context.visited_handling(), applicable_declarations, ); - if applicable_declarations.len() != length_before_preshints { - if cfg!(debug_assertions) { + if cfg!(debug_assertions) { + if applicable_declarations.len() != length_before_preshints { for declaration in &applicable_declarations[length_before_preshints..] { assert_eq!(declaration.level(), CascadeLevel::PresHints); } @@ -1248,7 +1251,7 @@ impl Stylist { // particular, normally document rules override ::slotted() rules, but // for !important it should be the other way around. So probably we need // to add some sort of AuthorScoped cascade level or something. - if matches_author_rules && !only_default_rules { + if matches_author_rules { if let Some(shadow) = rule_hash_target.shadow_root() { if let Some(map) = shadow.style_data().host_rules(pseudo_element) { context.with_shadow_host(Some(rule_hash_target), |context| { @@ -1315,10 +1318,8 @@ impl Stylist { } } - // FIXME(emilio): It looks very wrong to match XBL rules even for - // getDefaultComputedStyle! - // - // Also, this doesn't account for the author_styles_enabled stuff. + // FIXME(emilio): This doesn't account for the author_styles_enabled + // stuff... let cut_xbl_binding_inheritance = element.each_xbl_cascade_data(|cascade_data, quirks_mode| { if let Some(map) = cascade_data.normal_rules(pseudo_element) { @@ -1349,7 +1350,7 @@ impl Stylist { match_document_author_rules &= !cut_xbl_binding_inheritance; - if match_document_author_rules && !only_default_rules { + if match_document_author_rules { // Author normal rules. if let Some(map) = self.cascade_data.author.normal_rules(pseudo_element) { map.get_all_matching_rules( @@ -1364,47 +1365,43 @@ impl Stylist { } } - if !only_default_rules { - // Style attribute ("Normal override declarations"). - if let Some(sa) = style_attribute { - applicable_declarations.push(ApplicableDeclarationBlock::from_declarations( - sa.clone_arc(), - CascadeLevel::StyleAttributeNormal, - )); - } + // Style attribute ("Normal override declarations"). + if let Some(sa) = style_attribute { + applicable_declarations.push(ApplicableDeclarationBlock::from_declarations( + sa.clone_arc(), + CascadeLevel::StyleAttributeNormal, + )); + } - // Declarations from SVG SMIL animation elements. - if let Some(so) = smil_override { - applicable_declarations.push(ApplicableDeclarationBlock::from_declarations( - so.clone_arc(), - CascadeLevel::SMILOverride, - )); - } + // Declarations from SVG SMIL animation elements. + if let Some(so) = smil_override { + applicable_declarations.push(ApplicableDeclarationBlock::from_declarations( + so.clone_arc(), + CascadeLevel::SMILOverride, + )); + } - // The animations sheet (CSS animations, script-generated - // animations, and CSS transitions that are no longer tied to CSS - // markup). - if let Some(anim) = animation_rules.0 { - applicable_declarations.push(ApplicableDeclarationBlock::from_declarations( - anim.clone(), - CascadeLevel::Animations, - )); - } + // The animations sheet (CSS animations, script-generated + // animations, and CSS transitions that are no longer tied to CSS + // markup). + if let Some(anim) = animation_rules.0 { + applicable_declarations.push(ApplicableDeclarationBlock::from_declarations( + anim.clone(), + CascadeLevel::Animations, + )); } // // !important rules are handled during rule tree insertion. // - if !only_default_rules { - // The transitions sheet (CSS transitions that are tied to CSS - // markup). - if let Some(anim) = animation_rules.1 { - applicable_declarations.push(ApplicableDeclarationBlock::from_declarations( - anim.clone(), - CascadeLevel::Transitions, - )); - } + // The transitions sheet (CSS transitions that are tied to CSS + // markup). + if let Some(anim) = animation_rules.1 { + applicable_declarations.push(ApplicableDeclarationBlock::from_declarations( + anim.clone(), + CascadeLevel::Transitions, + )); } } From a76f5393d4eeaf6b8fc8885e1930dde8b2e2e5e7 Mon Sep 17 00:00:00 2001 From: Dan Glastonbury Date: Wed, 27 Jun 2018 17:07:37 +1000 Subject: [PATCH 12/16] style: Change nscolor to StyleComplexColor. Bug: 1467622 Reviewed-by: xidorn MozReview-Commit-ID: 1bbQzOoOuBe --- components/style/properties/gecko.mako.rs | 9 +++++---- .../style/properties/helpers/animated_properties.mako.rs | 6 +++--- components/style/values/computed/svg.rs | 7 ++++--- components/style/values/specified/svg.rs | 6 +++--- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index c262af439ca..03265c7214a 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -667,14 +667,14 @@ def set_gecko_property(ffi_name, expr): SVGPaintKind::Color(color) => { paint.mType = nsStyleSVGPaintType::eStyleSVGPaintType_Color; unsafe { - *paint.mPaint.mColor.as_mut() = convert_rgba_to_nscolor(&color); + *paint.mPaint.mColor.as_mut() = color.into(); } } } paint.mFallbackType = match fallback { Some(Either::First(color)) => { - paint.mFallbackColor = convert_rgba_to_nscolor(&color); + paint.mFallbackColor = color.into(); nsStyleSVGFallbackType::eStyleSVGFallbackType_Color }, Some(Either::Second(_)) => { @@ -709,7 +709,7 @@ def set_gecko_property(ffi_name, expr): let fallback = match paint.mFallbackType { nsStyleSVGFallbackType::eStyleSVGFallbackType_Color => { - Some(Either::First(convert_nscolor_to_rgba(paint.mFallbackColor))) + Some(Either::First(paint.mFallbackColor.into())) }, nsStyleSVGFallbackType::eStyleSVGFallbackType_None => { Some(Either::Second(None_)) @@ -728,7 +728,8 @@ def set_gecko_property(ffi_name, expr): }) } nsStyleSVGPaintType::eStyleSVGPaintType_Color => { - unsafe { SVGPaintKind::Color(convert_nscolor_to_rgba(*paint.mPaint.mColor.as_ref())) } + let col = unsafe { *paint.mPaint.mColor.as_ref() }; + SVGPaintKind::Color(col.into()) } }; SVGPaint { diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index d4a96e1f177..a51860f9a19 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -29,7 +29,7 @@ use hash::FnvHashMap; use super::ComputedValues; use values::CSSFloat; use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero}; -use values::animated::color::RGBA as AnimatedRGBA; +use values::animated::color::Color as AnimatedColor; use values::animated::effects::Filter as AnimatedFilter; #[cfg(feature = "gecko")] use values::computed::TransitionProperty; use values::computed::{Angle, CalcLengthOrPercentage}; @@ -2674,10 +2674,10 @@ impl ComputeSquaredDistance for ComputedTransform { } /// Animated SVGPaint -pub type IntermediateSVGPaint = SVGPaint; +pub type IntermediateSVGPaint = SVGPaint; /// Animated SVGPaintKind -pub type IntermediateSVGPaintKind = SVGPaintKind; +pub type IntermediateSVGPaintKind = SVGPaintKind; impl ToAnimatedZero for IntermediateSVGPaint { #[inline] diff --git a/components/style/values/computed/svg.rs b/components/style/values/computed/svg.rs index fd908580b13..ab9bbd18b4e 100644 --- a/components/style/values/computed/svg.rs +++ b/components/style/values/computed/svg.rs @@ -9,6 +9,7 @@ use values::RGBA; use values::computed::{LengthOrPercentage, NonNegativeLength}; use values::computed::{NonNegativeLengthOrPercentage, NonNegativeNumber, Number}; use values::computed::Opacity; +use values::computed::color::Color; use values::computed::url::ComputedUrl; use values::generics::svg as generic; @@ -17,9 +18,9 @@ pub use values::specified::SVGPaintOrder; pub use values::specified::MozContextProperties; /// Computed SVG Paint value -pub type SVGPaint = generic::SVGPaint; +pub type SVGPaint = generic::SVGPaint; /// Computed SVG Paint Kind value -pub type SVGPaintKind = generic::SVGPaintKind; +pub type SVGPaintKind = generic::SVGPaintKind; impl Default for SVGPaint { fn default() -> Self { @@ -33,7 +34,7 @@ impl Default for SVGPaint { impl SVGPaint { /// Opaque black color pub fn black() -> Self { - let rgba = RGBA::from_floats(0., 0., 0., 1.); + let rgba = RGBA::from_floats(0., 0., 0., 1.).into(); SVGPaint { kind: generic::SVGPaintKind::Color(rgba), fallback: None, diff --git a/components/style/values/specified/svg.rs b/components/style/values/specified/svg.rs index 766f36cfc1e..e55442d7da8 100644 --- a/components/style/values/specified/svg.rs +++ b/components/style/values/specified/svg.rs @@ -13,14 +13,14 @@ use values::CustomIdent; use values::generics::svg as generic; use values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage, NonNegativeNumber}; use values::specified::{Number, Opacity}; -use values::specified::color::RGBAColor; +use values::specified::color::Color; use values::specified::url::SpecifiedUrl; /// Specified SVG Paint value -pub type SVGPaint = generic::SVGPaint; +pub type SVGPaint = generic::SVGPaint; /// Specified SVG Paint Kind value -pub type SVGPaintKind = generic::SVGPaintKind; +pub type SVGPaintKind = generic::SVGPaintKind; #[cfg(feature = "gecko")] fn is_context_value_enabled() -> bool { From 96e812e732d2d874eeaddeab3d50cbd6bf7c2751 Mon Sep 17 00:00:00 2001 From: Dan Glastonbury Date: Tue, 3 Jul 2018 14:15:06 +1000 Subject: [PATCH 13/16] style: Correct background/foreground ratio mixing. Bug: 1467622 Reviewed-by: xidorn MozReview-Commit-ID: InAZVcH2Vkt --- components/style/values/animated/color.rs | 86 ++++++++++++++++++----- components/style/values/generics/color.rs | 2 +- 2 files changed, 70 insertions(+), 18 deletions(-) diff --git a/components/style/values/animated/color.rs b/components/style/values/animated/color.rs index 7f6b4cd9d43..4356c5a3d9b 100644 --- a/components/style/values/animated/color.rs +++ b/components/style/values/animated/color.rs @@ -126,11 +126,11 @@ impl Animate for Color { let (this_weight, other_weight) = procedure.weights(); Ok(match (*self, *other, procedure) { - // Any interpolation of currentColor with currentColor returns currentColor. - (Foreground, Foreground, Procedure::Interpolate { .. }) => Color::currentcolor(), + // Any interpolation of currentcolor with currentcolor returns currentcolor. + (Foreground, Foreground, Procedure::Interpolate { .. }) => Foreground, // Animating two numeric colors. (Numeric(c1), Numeric(c2), _) => Numeric(c1.animate(&c2, procedure)?), - // Combinations of numeric color and currentColor + // Combinations of numeric color and currentcolor (Foreground, Numeric(color), _) => Self::with_ratios( color, ComplexColorRatios { @@ -146,7 +146,7 @@ impl Animate for Color { }, ), - // Any other animation of currentColor with currentColor. + // Any other animation of currentcolor with currentcolor. (Foreground, Foreground, _) => Self::with_ratios( RGBA::transparent(), ComplexColorRatios { @@ -157,20 +157,72 @@ impl Animate for Color { // Defer to complex calculations _ => { - // For interpolating between two complex colors, we need to - // generate colors with effective alpha value. - let self_color = self.effective_intermediate_rgba(); - let other_color = other.effective_intermediate_rgba(); - let color = self_color.animate(&other_color, procedure)?; - // Then we compute the final background ratio, and derive - // the final alpha value from the effective alpha value. - let self_ratios = self.effective_ratios(); - let other_ratios = other.effective_ratios(); - let ratios = self_ratios.animate(&other_ratios, procedure)?; - let alpha = color.alpha / ratios.bg; - let color = RGBA { alpha, ..color }; + // Compute the "scaled" contribution for `color`. + fn scaled_rgba(color: &Color) -> RGBA { + match *color { + GenericColor::Numeric(color) => color, + GenericColor::Foreground => RGBA::transparent(), + GenericColor::Complex(color, ratios) => RGBA { + red: color.red * ratios.bg, + green: color.green * ratios.bg, + blue: color.blue * ratios.bg, + alpha: color.alpha * ratios.bg, + }, + } + } - Self::with_ratios(color, ratios) + // Each `Color`, represents a complex combination of foreground color and + // background color where fg and bg represent the overall + // contributions. ie: + // + // color = { bg * mColor, fg * foreground } + // = { bg_color , fg_color } + // = bg_color + fg_color + // + // where `foreground` is `currentcolor`, and `bg_color`, + // `fg_color` are the scaled background and foreground + // contributions. + // + // Each operation, lerp, addition, or accumulate, can be + // represented as a scaled-addition each complex color. ie: + // + // p * col1 + q * col2 + // + // where p = (1 - a), q = a for lerp(a), p = 1, q = 1 for + // addition, etc. + // + // Therefore: + // + // col1 op col2 + // = p * col1 + q * col2 + // = p * { bg_color1, fg_color1 } + q * { bg_color2, fg_color2 } + // = p * (bg_color1 + fg_color1) + q * (bg_color2 + fg_color2) + // = p * bg_color1 + p * fg_color1 + q * bg_color2 + p * fg_color2 + // = (p * bg_color1 + q * bg_color2) + (p * fg_color1 + q * fg_color2) + // = (bg_color1 op bg_color2) + (fg_color1 op fg_color2) + // + // fg_color1 op fg_color2 is equivalent to (fg1 op fg2) * foreground, + // so the final color is: + // + // = { bg_color, fg_color } + // = { 1 * (bg_color1 op bg_color2), (fg1 op fg2) * foreground } + + // To perform the operation on two complex colors, we need to + // generate the scaled contributions of each background color + // component. + let bg_color1 = scaled_rgba(self); + let bg_color2 = scaled_rgba(other); + // Perform bg_color1 op bg_color2 + let bg_color = bg_color1.animate(&bg_color2, procedure)?; + + // Calculate the final foreground color ratios; perform + // animation on effective fg ratios. + let ComplexColorRatios { fg: fg1, .. } = self.effective_ratios(); + let ComplexColorRatios { fg: fg2, .. } = other.effective_ratios(); + // Perform fg1 op fg2 + let fg = fg1.animate(&fg2, procedure)?; + + Self::with_ratios(bg_color, ComplexColorRatios { bg: 1., fg }) } }) } diff --git a/components/style/values/generics/color.rs b/components/style/values/generics/color.rs index e84bd690c7c..693803ad5fd 100644 --- a/components/style/values/generics/color.rs +++ b/components/style/values/generics/color.rs @@ -6,7 +6,7 @@ /// Ratios representing the contribution of color and currentcolor to /// the final color value. -#[derive(Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue)] +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue)] pub struct ComplexColorRatios { /// Numeric color contribution. pub bg: f32, From fde93a60fe020f12908dc37b624b87f13d12244f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 16 Jul 2018 19:34:22 +0200 Subject: [PATCH 14/16] style: Fix build and unit tests. --- components/script/dom/cssstyledeclaration.rs | 4 +- tests/unit/style/keyframes.rs | 259 ------------------- tests/unit/style/lib.rs | 1 - tests/unit/style/stylesheets.rs | 4 +- 4 files changed, 4 insertions(+), 264 deletions(-) delete mode 100644 tests/unit/style/keyframes.rs diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index 9f6c97dbc7d..3c6e489a797 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -17,7 +17,7 @@ use dom_struct::dom_struct; use servo_arc::Arc; use servo_url::ServoUrl; use style::attr::AttrValue; -use style::properties::{DeclarationSource, Importance, PropertyDeclarationBlock, PropertyId, LonghandId, ShorthandId}; +use style::properties::{DeclarationPushMode, Importance, PropertyDeclarationBlock, PropertyId, LonghandId, ShorthandId}; use style::properties::{parse_one_declaration_into, parse_style_attribute, SourcePropertyDeclaration}; use style::selector_parser::PseudoElement; use style::shared_lock::Locked; @@ -302,7 +302,7 @@ impl CSSStyleDeclaration { *changed = pdb.extend( declarations.drain(), importance, - DeclarationSource::CssOm, + DeclarationPushMode::Update, ); Ok(()) diff --git a/tests/unit/style/keyframes.rs b/tests/unit/style/keyframes.rs deleted file mode 100644 index 0f8f02d5d27..00000000000 --- a/tests/unit/style/keyframes.rs +++ /dev/null @@ -1,259 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use cssparser::SourceLocation; -use servo_arc::Arc; -use style::properties::{LonghandId, LonghandIdSet, PropertyDeclaration, PropertyDeclarationBlock, Importance}; -use style::properties::DeclarationSource; -use style::shared_lock::SharedRwLock; -use style::stylesheets::keyframes_rule::{Keyframe, KeyframesAnimation, KeyframePercentage, KeyframeSelector}; -use style::stylesheets::keyframes_rule::{KeyframesStep, KeyframesStepValue}; -use style::values::specified::{LengthOrPercentageOrAuto, NoCalcLength}; - -macro_rules! longhand_set { - ($($word:ident),+) => {{ - let mut set = LonghandIdSet::new(); - $( - set.insert(LonghandId::$word); - )+ - set - }} -} - - -#[test] -fn test_empty_keyframe() { - let shared_lock = SharedRwLock::new(); - let keyframes = vec![]; - let animation = KeyframesAnimation::from_keyframes(&keyframes, - /* vendor_prefix = */ None, - &shared_lock.read()); - let expected = KeyframesAnimation { - steps: vec![], - properties_changed: LonghandIdSet::new(), - vendor_prefix: None, - }; - - assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected)); -} - -#[test] -fn test_no_property_in_keyframe() { - let shared_lock = SharedRwLock::new(); - let dummy_location = SourceLocation { line: 0, column: 0 }; - let keyframes = vec![ - Arc::new(shared_lock.wrap(Keyframe { - selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(1.)]), - block: Arc::new(shared_lock.wrap(PropertyDeclarationBlock::new())), - source_location: dummy_location, - })), - ]; - let animation = KeyframesAnimation::from_keyframes(&keyframes, - /* vendor_prefix = */ None, - &shared_lock.read()); - let expected = KeyframesAnimation { - steps: vec![], - properties_changed: LonghandIdSet::new(), - vendor_prefix: None, - }; - - assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected)); -} - -#[test] -fn test_missing_property_in_initial_keyframe() { - let shared_lock = SharedRwLock::new(); - let declarations_on_initial_keyframe = - Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one( - PropertyDeclaration::Width( - LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))), - Importance::Normal - ))); - - let declarations_on_final_keyframe = - Arc::new(shared_lock.wrap({ - let mut block = PropertyDeclarationBlock::new(); - block.push( - PropertyDeclaration::Width( - LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))), - Importance::Normal, - DeclarationSource::Parsing, - ); - block.push( - PropertyDeclaration::Height( - LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))), - Importance::Normal, - DeclarationSource::Parsing, - ); - block - })); - - let dummy_location = SourceLocation { line: 0, column: 0 }; - let keyframes = vec![ - Arc::new(shared_lock.wrap(Keyframe { - selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.)]), - block: declarations_on_initial_keyframe.clone(), - source_location: dummy_location, - })), - - Arc::new(shared_lock.wrap(Keyframe { - selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(1.)]), - block: declarations_on_final_keyframe.clone(), - source_location: dummy_location, - })), - ]; - let animation = KeyframesAnimation::from_keyframes(&keyframes, - /* vendor_prefix = */ None, - &shared_lock.read()); - let expected = KeyframesAnimation { - steps: vec![ - KeyframesStep { - start_percentage: KeyframePercentage(0.), - value: KeyframesStepValue::Declarations { block: declarations_on_initial_keyframe }, - declared_timing_function: false, - }, - KeyframesStep { - start_percentage: KeyframePercentage(1.), - value: KeyframesStepValue::Declarations { block: declarations_on_final_keyframe }, - declared_timing_function: false, - }, - ], - properties_changed: longhand_set!(Width, Height), - vendor_prefix: None, - }; - - assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected)); -} - -#[test] -fn test_missing_property_in_final_keyframe() { - let shared_lock = SharedRwLock::new(); - let declarations_on_initial_keyframe = - Arc::new(shared_lock.wrap({ - let mut block = PropertyDeclarationBlock::new(); - block.push( - PropertyDeclaration::Width( - LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))), - Importance::Normal, - DeclarationSource::Parsing, - ); - block.push( - PropertyDeclaration::Height( - LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))), - Importance::Normal, - DeclarationSource::Parsing, - ); - block - })); - - let declarations_on_final_keyframe = - Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one( - PropertyDeclaration::Height( - LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))), - Importance::Normal, - ))); - - let dummy_location = SourceLocation { line: 0, column: 0 }; - let keyframes = vec![ - Arc::new(shared_lock.wrap(Keyframe { - selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.)]), - block: declarations_on_initial_keyframe.clone(), - source_location: dummy_location, - })), - - Arc::new(shared_lock.wrap(Keyframe { - selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(1.)]), - block: declarations_on_final_keyframe.clone(), - source_location: dummy_location, - })), - ]; - let animation = KeyframesAnimation::from_keyframes(&keyframes, - /* vendor_prefix = */ None, - &shared_lock.read()); - let expected = KeyframesAnimation { - steps: vec![ - KeyframesStep { - start_percentage: KeyframePercentage(0.), - value: KeyframesStepValue::Declarations { block: declarations_on_initial_keyframe }, - declared_timing_function: false, - }, - KeyframesStep { - start_percentage: KeyframePercentage(1.), - value: KeyframesStepValue::Declarations { block: declarations_on_final_keyframe }, - declared_timing_function: false, - }, - ], - properties_changed: longhand_set!(Width, Height), - vendor_prefix: None, - }; - - assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected)); -} - -#[test] -fn test_missing_keyframe_in_both_of_initial_and_final_keyframe() { - let shared_lock = SharedRwLock::new(); - let declarations = - Arc::new(shared_lock.wrap({ - let mut block = PropertyDeclarationBlock::new(); - block.push( - PropertyDeclaration::Width( - LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))), - Importance::Normal, - DeclarationSource::Parsing, - ); - block.push( - PropertyDeclaration::Height( - LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))), - Importance::Normal, - DeclarationSource::Parsing, - ); - block - })); - - let dummy_location = SourceLocation { line: 0, column: 0 }; - let keyframes = vec![ - Arc::new(shared_lock.wrap(Keyframe { - selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.)]), - block: Arc::new(shared_lock.wrap(PropertyDeclarationBlock::new())), - source_location: dummy_location, - })), - Arc::new(shared_lock.wrap(Keyframe { - selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.5)]), - block: declarations.clone(), - source_location: dummy_location, - })), - ]; - let animation = KeyframesAnimation::from_keyframes(&keyframes, - /* vendor_prefix = */ None, - &shared_lock.read()); - let expected = KeyframesAnimation { - steps: vec![ - KeyframesStep { - start_percentage: KeyframePercentage(0.), - value: KeyframesStepValue::Declarations { - block: Arc::new(shared_lock.wrap( - // XXX: Should we use ComputedValues in this case? - PropertyDeclarationBlock::new() - )) - }, - declared_timing_function: false, - }, - KeyframesStep { - start_percentage: KeyframePercentage(0.5), - value: KeyframesStepValue::Declarations { block: declarations }, - declared_timing_function: false, - }, - KeyframesStep { - start_percentage: KeyframePercentage(1.), - value: KeyframesStepValue::ComputedValues, - declared_timing_function: false, - } - ], - properties_changed: longhand_set!(Width, Height), - vendor_prefix: None, - }; - - assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected)); -} diff --git a/tests/unit/style/lib.rs b/tests/unit/style/lib.rs index faa15845195..f9fe10dbaae 100644 --- a/tests/unit/style/lib.rs +++ b/tests/unit/style/lib.rs @@ -25,7 +25,6 @@ extern crate test; mod animated_properties; mod attr; mod custom_properties; -mod keyframes; mod logical_geometry; mod parsing; mod properties; diff --git a/tests/unit/style/stylesheets.rs b/tests/unit/style/stylesheets.rs index 632d51074fe..0e75b5a8458 100644 --- a/tests/unit/style/stylesheets.rs +++ b/tests/unit/style/stylesheets.rs @@ -17,7 +17,7 @@ use std::sync::atomic::AtomicBool; use style::context::QuirksMode; use style::error_reporting::{ParseErrorReporter, ContextualParseError}; use style::media_queries::MediaList; -use style::properties::{CSSWideKeyword, CustomDeclaration, DeclarationSource}; +use style::properties::{CSSWideKeyword, CustomDeclaration, DeclarationPushMode}; use style::properties::{DeclaredValueOwned, Importance}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock}; use style::properties::longhands::{self, animation_timing_function}; @@ -34,7 +34,7 @@ pub fn block_from(iterable: I) -> PropertyDeclarationBlock where I: IntoIterator { let mut block = PropertyDeclarationBlock::new(); for (d, i) in iterable { - block.push(d, i, DeclarationSource::CssOm); + block.push(d, i, DeclarationPushMode::Append); } block } From bad4f7d7297b9a7e8c9c5c0b39733beb684ef9df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 16 Jul 2018 18:50:18 +0200 Subject: [PATCH 15/16] style: Gecko build fix for Servo PR #21139. MozReview-Commit-ID: 3ocJrRB3jeO --- components/style/properties/gecko.mako.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 03265c7214a..9c5d9052428 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -3083,6 +3083,9 @@ fn static_assert() { <%call expr="impl_keyword_clone('display', 'mDisplay', display_keyword)"> + <% float_keyword = Keyword("float", "Left Right None", gecko_enum_prefix="StyleFloat") %> + ${impl_keyword('float', 'mFloat', float_keyword)} + <% overflow_x = data.longhands_by_name["overflow-x"] %> pub fn set_overflow_y(&mut self, v: longhands::overflow_y::computed_value::T) { use properties::longhands::overflow_x::computed_value::T as BaseType; From 5227c7572e32dd74a8b9bd37a2070c88307835be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 16 Jul 2018 19:01:24 +0200 Subject: [PATCH 16/16] style: Gecko build fix for Servo PR #21156. MozReview-Commit-ID: FbN0hiUGzYa --- components/style/properties/gecko.mako.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 9c5d9052428..ac5acfd05dc 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -3086,6 +3086,14 @@ fn static_assert() { <% float_keyword = Keyword("float", "Left Right None", gecko_enum_prefix="StyleFloat") %> ${impl_keyword('float', 'mFloat', float_keyword)} + <% clear_keyword = Keyword( + "clear", + "Left Right None Both", + gecko_enum_prefix="StyleClear", + gecko_inexhaustive=True, + ) %> + ${impl_keyword('clear', 'mBreakType', clear_keyword)} + <% overflow_x = data.longhands_by_name["overflow-x"] %> pub fn set_overflow_y(&mut self, v: longhands::overflow_y::computed_value::T) { use properties::longhands::overflow_x::computed_value::T as BaseType;