From ea5417b29c466247fd56c581696e534e105abaa8 Mon Sep 17 00:00:00 2001 From: Yusuf Sermet Date: Wed, 30 May 2018 14:28:53 -0700 Subject: [PATCH 01/40] style: Make contain:paint trigger clipping independent of the overflow property. Bug: 1465250 Reviewed-by: mattwoodrow MozReview-Commit-ID: 2QbfZD1jnWX --- components/style/style_adjuster.rs | 34 ------------------------------ 1 file changed, 34 deletions(-) diff --git a/components/style/style_adjuster.rs b/components/style/style_adjuster.rs index 2bb400f63ec..8bbc40ca8c6 100644 --- a/components/style/style_adjuster.rs +++ b/components/style/style_adjuster.rs @@ -315,39 +315,6 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { } } - #[cfg(feature = "gecko")] - fn adjust_for_contain(&mut self) { - use properties::longhands::contain::SpecifiedValue; - - // An element with contain: paint needs to be a formatting context, and - // also implies overflow: clip. - // - // TODO(emilio): This mimics Gecko, but spec links are missing! - let contain = self.style.get_box().clone_contain(); - if !contain.contains(SpecifiedValue::PAINT) { - return; - } - - if self.style.get_box().clone_display() == Display::Inline { - self.style - .mutate_box() - .set_adjusted_display(Display::InlineBlock, false); - } - - // When 'contain: paint', update overflow from 'visible' to 'clip'. - if self.style - .get_box() - .clone_contain() - .contains(SpecifiedValue::PAINT) - { - if self.style.get_box().clone_overflow_x() == Overflow::Visible { - let box_style = self.style.mutate_box(); - box_style.set_overflow_x(Overflow::MozHiddenUnscrollable); - box_style.set_overflow_y(Overflow::MozHiddenUnscrollable); - } - } - } - /// When mathvariant is not "none", font-weight and font-style are /// both forced to "normal". #[cfg(feature = "gecko")] @@ -752,7 +719,6 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { #[cfg(feature = "gecko")] { self.adjust_for_table_text_align(); - self.adjust_for_contain(); self.adjust_for_mathvariant(); self.adjust_for_justify_items(); } From 35a1a30f6b2ce901bcfb192da1e10fc6bb01eec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 13:25:41 +0200 Subject: [PATCH 02/40] style: Remove invalid assertion. We can look at stale styles while trying to figure out if we need any invalidation, and that's ok. Bug: 1449243 MozReview-Commit-ID: 4mBIFNm9qJv --- components/style/gecko/wrapper.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 9ff92a19e16..a666d571ed9 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -181,7 +181,6 @@ impl<'lr> TShadowRoot for GeckoShadowRoot<'lr> { let author_styles = AuthorStyles::::from_ffi(author_styles); - debug_assert!(!author_styles.stylesheets.dirty()); debug_assert!( author_styles.quirks_mode == self.as_node().owner_doc().quirks_mode() || author_styles.stylesheets.is_empty() From 69407879162cf79816176f05af913bfcda6660b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 1 Jun 2018 16:34:08 +0200 Subject: [PATCH 03/40] style: Make the transition-property code make more sense. We were working around the lack of alias support during parsing in TransitionProperty by doing a Gecko lookup. That's a hack and is now gone. Bug: 1419695 Reviewed-by: xidorn MozReview-Commit-ID: EptUvJNTrZr --- components/style/animation.rs | 3 +- components/style/gecko/wrapper.rs | 1 + components/style/properties/gecko.mako.rs | 38 +++++++-- .../helpers/animated_properties.mako.rs | 80 +++++++++++-------- .../style/properties/longhand/box.mako.rs | 1 - .../style/properties/shorthand/box.mako.rs | 6 +- 6 files changed, 86 insertions(+), 43 deletions(-) diff --git a/components/style/animation.rs b/components/style/animation.rs index bbf847d7f14..15c58c6098e 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -303,7 +303,8 @@ impl PropertyAnimation { let duration = box_style.transition_duration_mod(transition_index); match transition_property { - TransitionProperty::Unsupported(_) => result, + TransitionProperty::Custom(..) | + TransitionProperty::Unsupported(..) => result, TransitionProperty::Shorthand(ref shorthand_id) => shorthand_id .longhands() .filter_map(|longhand| { diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index a666d571ed9..3ba686911ee 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -1629,6 +1629,7 @@ impl<'le> TElement for GeckoElement<'le> { }; match transition_property { + TransitionProperty::Custom(..) | TransitionProperty::Unsupported(..) => {}, TransitionProperty::Shorthand(ref shorthand) => { if shorthand.longhands().any(property_check_helper) { diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 4b902358866..4fa98fc1b9d 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -28,7 +28,6 @@ use gecko_bindings::bindings::Gecko_CopyListStyleImageFrom; use gecko_bindings::bindings::Gecko_EnsureImageLayersLength; use gecko_bindings::bindings::Gecko_SetCursorArrayLength; use gecko_bindings::bindings::Gecko_SetCursorImageValue; -use gecko_bindings::bindings::Gecko_StyleTransition_SetUnsupportedProperty; use gecko_bindings::bindings::Gecko_NewCSSShadowArray; use gecko_bindings::bindings::Gecko_nsStyleFont_SetLang; use gecko_bindings::bindings::Gecko_nsStyleFont_CopyLangFrom; @@ -3267,6 +3266,8 @@ fn static_assert() { I::IntoIter: ExactSizeIterator { use gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_no_properties; + use gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_variable; + use gecko_bindings::structs::nsCSSPropertyID::eCSSProperty_UNKNOWN; let v = v.into_iter(); @@ -3274,10 +3275,20 @@ fn static_assert() { self.gecko.mTransitions.ensure_len(v.len()); self.gecko.mTransitionPropertyCount = v.len() as u32; for (servo, gecko) in v.zip(self.gecko.mTransitions.iter_mut()) { + if !gecko.mUnknownProperty.mRawPtr.is_null() { + unsafe { Atom::from_addrefed(gecko.mUnknownProperty.mRawPtr) }; + gecko.mUnknownProperty.mRawPtr = ptr::null_mut(); + } + match servo { - TransitionProperty::Unsupported(ref ident) => unsafe { - Gecko_StyleTransition_SetUnsupportedProperty(gecko, ident.0.as_ptr()) + TransitionProperty::Unsupported(ident) => { + gecko.mProperty = eCSSProperty_UNKNOWN; + gecko.mUnknownProperty.mRawPtr = ident.0.into_addrefed(); }, + TransitionProperty::Custom(name) => { + gecko.mProperty = eCSSPropertyExtra_variable; + gecko.mUnknownProperty.mRawPtr = name.into_addrefed(); + } _ => gecko.mProperty = servo.to_nscsspropertyid().unwrap(), } } @@ -3307,15 +3318,24 @@ fn static_assert() { use gecko_bindings::structs::nsCSSPropertyID::eCSSProperty_UNKNOWN; let property = self.gecko.mTransitions[index].mProperty; - if property == eCSSProperty_UNKNOWN || property == eCSSPropertyExtra_variable { + if property == eCSSProperty_UNKNOWN { let atom = self.gecko.mTransitions[index].mUnknownProperty.mRawPtr; debug_assert!(!atom.is_null()); TransitionProperty::Unsupported(CustomIdent(unsafe{ Atom::from_raw(atom) })) + } else if property == eCSSPropertyExtra_variable { + let atom = self.gecko.mTransitions[index].mUnknownProperty.mRawPtr; + debug_assert!(!atom.is_null()); + TransitionProperty::Custom(unsafe{ + Atom::from_raw(atom) + }) } else if property == eCSSPropertyExtra_no_properties { - // Actually, we don't expect TransitionProperty::Unsupported also represents "none", - // but if the caller wants to convert it, it is fine. Please use it carefully. + // Actually, we don't expect TransitionProperty::Unsupported also + // represents "none", but if the caller wants to convert it, it is + // fine. Please use it carefully. + // + // FIXME(emilio): This is a hack, is this reachable? TransitionProperty::Unsupported(CustomIdent(atom!("none"))) } else { property.into() @@ -3336,11 +3356,15 @@ fn static_assert() { for (index, transition) in self.gecko.mTransitions.iter_mut().enumerate().take(count as usize) { transition.mProperty = other.gecko.mTransitions[index].mProperty; + if !transition.mUnknownProperty.mRawPtr.is_null() { + unsafe { Atom::from_addrefed(transition.mUnknownProperty.mRawPtr) }; + transition.mUnknownProperty.mRawPtr = ptr::null_mut(); + } if transition.mProperty == eCSSProperty_UNKNOWN || transition.mProperty == eCSSPropertyExtra_variable { let atom = other.gecko.mTransitions[index].mUnknownProperty.mRawPtr; debug_assert!(!atom.is_null()); - unsafe { Gecko_StyleTransition_SetUnsupportedProperty(transition, atom) }; + transition.mUnknownProperty.mRawPtr = unsafe { Atom::from_raw(atom) }.into_addrefed(); } } } diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index f45b7ffe91e..bccbc4d9683 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -9,6 +9,7 @@ from itertools import groupby %> +use Atom; use cssparser::Parser; #[cfg(feature = "gecko")] use gecko_bindings::bindings::RawServoAnimationValueMap; #[cfg(feature = "gecko")] use gecko_bindings::structs::RawGeckoGfxMatrix4x4; @@ -16,7 +17,8 @@ use cssparser::Parser; #[cfg(feature = "gecko")] use gecko_bindings::sugar::ownership::{HasFFI, HasSimpleFFI}; use itertools::{EitherOrBoth, Itertools}; use num_traits::Zero; -use properties::{CSSWideKeyword, PropertyDeclaration}; +use parser::ParserContext; +use properties::{CSSWideKeyword, PropertyDeclaration, PropertyDeclarationId}; use properties::longhands; use properties::longhands::font_weight::computed_value::T as FontWeight; use properties::longhands::visibility::computed_value::T as Visibility; @@ -25,9 +27,10 @@ use properties::{LonghandId, ShorthandId}; use servo_arc::Arc; use smallvec::SmallVec; use std::{cmp, ptr}; +use std::fmt::{self, Write}; use std::mem::{self, ManuallyDrop}; #[cfg(feature = "gecko")] use hash::FnvHashMap; -use style_traits::{KeywordsCollectFn, ParseError, SpecifiedValueInfo}; +use style_traits::{KeywordsCollectFn, ParseError, SpecifiedValueInfo, ToCss, CssWriter}; use super::ComputedValues; use values::{CSSFloat, CustomIdent}; use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero}; @@ -74,17 +77,37 @@ pub fn nscsspropertyid_is_animatable(property: nsCSSPropertyID) -> bool { /// a shorthand with at least one transitionable longhand component, or an unsupported property. // NB: This needs to be here because it needs all the longhands generated // beforehand. -#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToCss)] +#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue)] pub enum TransitionProperty { /// A shorthand. Shorthand(ShorthandId), /// A longhand transitionable property. Longhand(LonghandId), + /// A custom property. + Custom(Atom), /// Unrecognized property which could be any non-transitionable, custom property, or /// unknown property. Unsupported(CustomIdent), } +impl ToCss for TransitionProperty { + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + use values::serialize_atom_identifier; + match *self { + TransitionProperty::Shorthand(ref s) => s.to_css(dest), + TransitionProperty::Longhand(ref l) => l.to_css(dest), + TransitionProperty::Custom(ref name) => { + dest.write_str("--")?; + serialize_atom_identifier(name, dest) + } + TransitionProperty::Unsupported(ref i) => i.to_css(dest), + } + } +} + impl TransitionProperty { /// Returns `all`. #[inline] @@ -93,38 +116,30 @@ impl TransitionProperty { } /// Parse a transition-property value. - pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - // FIXME(https://github.com/rust-lang/rust/issues/33156): remove this - // enum and use PropertyId when stable Rust allows destructors in - // statics. - // - // FIXME: This should handle aliases too. - pub enum StaticId { - Longhand(LonghandId), - Shorthand(ShorthandId), - } - ascii_case_insensitive_phf_map! { - static_id -> StaticId = { - % for prop in data.shorthands: - "${prop.name}" => StaticId::Shorthand(ShorthandId::${prop.camel_case}), - % endfor - % for prop in data.longhands: - "${prop.name}" => StaticId::Longhand(LonghandId::${prop.camel_case}), - % endfor - } - } - + pub fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { let location = input.current_source_location(); let ident = input.expect_ident()?; - Ok(match static_id(&ident) { - Some(&StaticId::Longhand(id)) => TransitionProperty::Longhand(id), - Some(&StaticId::Shorthand(id)) => TransitionProperty::Shorthand(id), - None => { - TransitionProperty::Unsupported( - CustomIdent::from_ident(location, ident, &["none"])?, - ) - }, + let id = match PropertyId::parse(&ident, context) { + Ok(id) => id, + Err(..) => return Ok(TransitionProperty::Unsupported( + CustomIdent::from_ident(location, ident, &["none"])?, + )), + }; + + Ok(match id.as_shorthand() { + Ok(s) => TransitionProperty::Shorthand(s), + Err(longhand_or_custom) => { + match longhand_or_custom { + PropertyDeclarationId::Longhand(id) => TransitionProperty::Longhand(id), + PropertyDeclarationId::Custom(custom) => { + TransitionProperty::Custom(custom.clone()) + } + } + } }) } @@ -137,6 +152,7 @@ impl TransitionProperty { } TransitionProperty::Shorthand(ref id) => id.to_nscsspropertyid(), TransitionProperty::Longhand(ref id) => id.to_nscsspropertyid(), + TransitionProperty::Custom(..) | TransitionProperty::Unsupported(..) => return Err(()), }) } diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index f8389a19a79..82e609c44e9 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -257,7 +257,6 @@ ${helpers.predefined_type( vector=True, allow_empty="NotInitial", need_index=True, - needs_context=False, animation_value_type="none", extra_prefixes=transition_extra_prefixes, spec="https://drafts.csswg.org/css-transitions/#propdef-transition-property", diff --git a/components/style/properties/shorthand/box.mako.rs b/components/style/properties/shorthand/box.mako.rs index 1d3bab6eaa4..d4f1eb66293 100644 --- a/components/style/properties/shorthand/box.mako.rs +++ b/components/style/properties/shorthand/box.mako.rs @@ -158,10 +158,12 @@ macro_rules! try_parse_one { // Must check 'transition-property' after 'transition-timing-function' since // 'transition-property' accepts any keyword. if property.is_none() { - if let Ok(value) = input.try(|i| transition_property::SingleSpecifiedValue::parse(i)) { + if let Ok(value) = input.try(|i| transition_property::SingleSpecifiedValue::parse(context, i)) { property = Some(Some(value)); continue; - } else if input.try(|i| i.expect_ident_matching("none")).is_ok() { + } + + if input.try(|i| i.expect_ident_matching("none")).is_ok() { // 'none' is not a valid value for , // so it's not acceptable in the function above. property = Some(None); From f6f421f5aab8eb7462cc19f5ebfe00615b69d504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 1 Jun 2018 16:36:54 +0200 Subject: [PATCH 04/40] style: Hide multiple -moz-window-* properties from content. Bug: 1419695 Reviewed-by: xidorn MozReview-Commit-ID: Jsqt3kqjPiq --- .../style/properties/longhand/ui.mako.rs | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/components/style/properties/longhand/ui.mako.rs b/components/style/properties/longhand/ui.mako.rs index 683a8967ea3..13a940b2b96 100644 --- a/components/style/properties/longhand/ui.mako.rs +++ b/components/style/properties/longhand/ui.mako.rs @@ -41,13 +41,17 @@ ${helpers.single_keyword("-moz-window-shadow", "none default menu tooltip sheet" enabled_in="chrome", spec="None (Nonstandard internal property)")} -// TODO(bug 1419695) This should be hidden from content. -${helpers.predefined_type("-moz-window-opacity", "Opacity", "1.0", products="gecko", - gecko_ffi_name="mWindowOpacity", - animation_value_type="ComputedValue", - spec="None (Nonstandard internal property)")} +${helpers.predefined_type( + "-moz-window-opacity", + "Opacity", + "1.0", + products="gecko", + gecko_ffi_name="mWindowOpacity", + animation_value_type="ComputedValue", + spec="None (Nonstandard internal property)", + enabled_in="chrome", +)} -// TODO(bug 1419695) This should be hidden from content. ${helpers.predefined_type( "-moz-window-transform", "Transform", @@ -56,10 +60,10 @@ ${helpers.predefined_type( gecko_ffi_name="mSpecifiedWindowTransform", flags="GETCS_NEEDS_LAYOUT_FLUSH", animation_value_type="ComputedValue", - spec="None (Nonstandard internal property)" + spec="None (Nonstandard internal property)", + enabled_in="chrome", )} -// TODO(bug 1419695) This should be hidden from content. ${helpers.predefined_type( "-moz-window-transform-origin", "TransformOrigin", @@ -69,7 +73,8 @@ ${helpers.predefined_type( products="gecko", boxed=True, flags="GETCS_NEEDS_LAYOUT_FLUSH", - spec="None (Nonstandard internal property)" + spec="None (Nonstandard internal property)", + enabled_in="chrome", )} // TODO(emilio): Probably also should be hidden from content. From 90ef5607e41cea1be31575c6d9444c8dc36d619f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 1 Jun 2018 17:09:34 +0200 Subject: [PATCH 05/40] style: Move TransitionProperty where it belongs. Bug: 1419695 Reviewed-by: xidorn MozReview-Commit-ID: 9PN6VfbDbLA --- components/style/animation.rs | 3 +- components/style/gecko/wrapper.rs | 2 +- components/style/properties/gecko.mako.rs | 3 +- .../helpers/animated_properties.mako.rs | 105 +----------------- .../style/properties/shorthand/box.mako.rs | 6 +- components/style/values/computed/box.rs | 2 +- components/style/values/computed/mod.rs | 3 +- components/style/values/specified/box.rs | 97 +++++++++++++++- components/style/values/specified/mod.rs | 3 +- 9 files changed, 109 insertions(+), 115 deletions(-) diff --git a/components/style/animation.rs b/components/style/animation.rs index 15c58c6098e..d090ecb1ecb 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -10,7 +10,7 @@ use context::SharedStyleContext; use dom::{OpaqueNode, TElement}; use font_metrics::FontMetricsProvider; use properties::{self, CascadeFlags, ComputedValues, LonghandId}; -use properties::animated_properties::{AnimatedProperty, TransitionProperty}; +use properties::animated_properties::AnimatedProperty; use properties::longhands::animation_direction::computed_value::single_value::T as AnimationDirection; use properties::longhands::animation_play_state::computed_value::single_value::T as AnimationPlayState; use rule_tree::CascadeLevel; @@ -20,6 +20,7 @@ use std::sync::mpsc::Sender; use stylesheets::keyframes_rule::{KeyframesAnimation, KeyframesStep, KeyframesStepValue}; use timer::Timer; use values::computed::Time; +use values::computed::box_::TransitionProperty; use values::computed::transform::TimingFunction; use values::generics::box_::AnimationIterationCount; use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction}; diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 3ba686911ee..4eae24a2bfa 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -67,7 +67,6 @@ use media_queries::Device; use properties::{ComputedValues, LonghandId}; use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock}; use properties::animated_properties::{AnimationValue, AnimationValueMap}; -use properties::animated_properties::TransitionProperty; use properties::style_structs::Font; use rule_tree::CascadeLevel as ServoCascadeLevel; use selector_parser::{AttrValue, Direction, PseudoClassStringArg}; @@ -1586,6 +1585,7 @@ impl<'le> TElement for GeckoElement<'le> { ) -> bool { use gecko_bindings::structs::nsCSSPropertyID; use properties::LonghandIdSet; + use values::computed::TransitionProperty; debug_assert!( self.might_need_transitions_update(Some(before_change_style), after_change_style), diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 4fa98fc1b9d..b4411e1ea8b 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -48,7 +48,6 @@ use gecko::values::GeckoStyleCoordConvertible; use gecko::values::round_border_to_device_pixels; use logical_geometry::WritingMode; use media_queries::Device; -use properties::animated_properties::TransitionProperty; use properties::computed_value_flags::*; use properties::{longhands, Importance, LonghandId}; use properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyDeclarationId}; @@ -59,7 +58,7 @@ use std::marker::PhantomData; use std::mem::{forget, uninitialized, transmute, zeroed}; use std::{cmp, ops, ptr}; use values::{self, CustomIdent, Either, KeyframesName, None_}; -use values::computed::{NonNegativeLength, ToComputedValue, Percentage}; +use values::computed::{NonNegativeLength, ToComputedValue, Percentage, TransitionProperty}; use values::computed::font::FontSize; use values::computed::effects::{BoxShadow, Filter, SimpleShadow}; use values::computed::outline::OutlineStyle; diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index bccbc4d9683..acdaebef205 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -9,16 +9,13 @@ from itertools import groupby %> -use Atom; -use cssparser::Parser; #[cfg(feature = "gecko")] use gecko_bindings::bindings::RawServoAnimationValueMap; #[cfg(feature = "gecko")] use gecko_bindings::structs::RawGeckoGfxMatrix4x4; #[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSPropertyID; #[cfg(feature = "gecko")] use gecko_bindings::sugar::ownership::{HasFFI, HasSimpleFFI}; use itertools::{EitherOrBoth, Itertools}; use num_traits::Zero; -use parser::ParserContext; -use properties::{CSSWideKeyword, PropertyDeclaration, PropertyDeclarationId}; +use properties::{CSSWideKeyword, PropertyDeclaration}; use properties::longhands; use properties::longhands::font_weight::computed_value::T as FontWeight; use properties::longhands::visibility::computed_value::T as Visibility; @@ -27,19 +24,17 @@ use properties::{LonghandId, ShorthandId}; use servo_arc::Arc; use smallvec::SmallVec; use std::{cmp, ptr}; -use std::fmt::{self, Write}; use std::mem::{self, ManuallyDrop}; #[cfg(feature = "gecko")] use hash::FnvHashMap; -use style_traits::{KeywordsCollectFn, ParseError, SpecifiedValueInfo, ToCss, CssWriter}; use super::ComputedValues; -use values::{CSSFloat, CustomIdent}; +use values::CSSFloat; use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero}; use values::animated::color::RGBA as AnimatedRGBA; use values::animated::effects::Filter as AnimatedFilter; use values::computed::{Angle, CalcLengthOrPercentage}; use values::computed::{ClipRect, Context}; use values::computed::{Length, LengthOrPercentage, LengthOrPercentageOrAuto}; -use values::computed::{LengthOrPercentageOrNone, MaxLength}; +use values::computed::{LengthOrPercentageOrNone, MaxLength, TransitionProperty}; use values::computed::{NonNegativeNumber, Number, NumberOrPercentage, Percentage}; use values::computed::length::NonNegativeLengthOrPercentage; use values::computed::ToComputedValue; @@ -73,91 +68,6 @@ pub fn nscsspropertyid_is_animatable(property: nsCSSPropertyID) -> bool { } } -/// A given transition property, that is either `All`, a transitionable longhand property, -/// a shorthand with at least one transitionable longhand component, or an unsupported property. -// NB: This needs to be here because it needs all the longhands generated -// beforehand. -#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue)] -pub enum TransitionProperty { - /// A shorthand. - Shorthand(ShorthandId), - /// A longhand transitionable property. - Longhand(LonghandId), - /// A custom property. - Custom(Atom), - /// Unrecognized property which could be any non-transitionable, custom property, or - /// unknown property. - Unsupported(CustomIdent), -} - -impl ToCss for TransitionProperty { - fn to_css(&self, dest: &mut CssWriter) -> fmt::Result - where - W: Write, - { - use values::serialize_atom_identifier; - match *self { - TransitionProperty::Shorthand(ref s) => s.to_css(dest), - TransitionProperty::Longhand(ref l) => l.to_css(dest), - TransitionProperty::Custom(ref name) => { - dest.write_str("--")?; - serialize_atom_identifier(name, dest) - } - TransitionProperty::Unsupported(ref i) => i.to_css(dest), - } - } -} - -impl TransitionProperty { - /// Returns `all`. - #[inline] - pub fn all() -> Self { - TransitionProperty::Shorthand(ShorthandId::All) - } - - /// Parse a transition-property value. - pub fn parse<'i, 't>( - context: &ParserContext, - input: &mut Parser<'i, 't>, - ) -> Result> { - let location = input.current_source_location(); - let ident = input.expect_ident()?; - - let id = match PropertyId::parse(&ident, context) { - Ok(id) => id, - Err(..) => return Ok(TransitionProperty::Unsupported( - CustomIdent::from_ident(location, ident, &["none"])?, - )), - }; - - Ok(match id.as_shorthand() { - Ok(s) => TransitionProperty::Shorthand(s), - Err(longhand_or_custom) => { - match longhand_or_custom { - PropertyDeclarationId::Longhand(id) => TransitionProperty::Longhand(id), - PropertyDeclarationId::Custom(custom) => { - TransitionProperty::Custom(custom.clone()) - } - } - } - }) - } - - /// Convert TransitionProperty to nsCSSPropertyID. - #[cfg(feature = "gecko")] - pub fn to_nscsspropertyid(&self) -> Result { - Ok(match *self { - TransitionProperty::Shorthand(ShorthandId::All) => { - nsCSSPropertyID::eCSSPropertyExtra_all_properties - } - TransitionProperty::Shorthand(ref id) => id.to_nscsspropertyid(), - TransitionProperty::Longhand(ref id) => id.to_nscsspropertyid(), - TransitionProperty::Custom(..) | - TransitionProperty::Unsupported(..) => return Err(()), - }) - } -} - /// Convert nsCSSPropertyID to TransitionProperty #[cfg(feature = "gecko")] #[allow(non_upper_case_globals)] @@ -184,15 +94,6 @@ impl From for TransitionProperty { } } -impl SpecifiedValueInfo for TransitionProperty { - fn collect_completion_keywords(f: KeywordsCollectFn) { - // `transition-property` can actually accept all properties and - // arbitrary identifiers, but `all` is a special one we'd like - // to list. - f(&["all"]); - } -} - /// Returns true if this nsCSSPropertyID is one of the transitionable properties. #[cfg(feature = "gecko")] pub fn nscsspropertyid_is_transitionable(property: nsCSSPropertyID) -> bool { diff --git a/components/style/properties/shorthand/box.mako.rs b/components/style/properties/shorthand/box.mako.rs index d4f1eb66293..842dfbd7229 100644 --- a/components/style/properties/shorthand/box.mako.rs +++ b/components/style/properties/shorthand/box.mako.rs @@ -123,9 +123,11 @@ macro_rules! try_parse_one { transition-timing-function transition-delay" spec="https://drafts.csswg.org/css-transitions/#propdef-transition"> + use parser::Parse; % for prop in "delay duration property timing_function".split(): use properties::longhands::transition_${prop}; % endfor + use values::specified::TransitionProperty; pub fn parse_value<'i, 't>( context: &ParserContext, @@ -137,7 +139,7 @@ macro_rules! try_parse_one { % endfor // Unlike other properties, transition-property uses an Option<> to // represent 'none' as `None`. - transition_property: Option, + transition_property: Option, } fn parse_one_transition<'i, 't>( @@ -158,7 +160,7 @@ macro_rules! try_parse_one { // Must check 'transition-property' after 'transition-timing-function' since // 'transition-property' accepts any keyword. if property.is_none() { - if let Ok(value) = input.try(|i| transition_property::SingleSpecifiedValue::parse(context, i)) { + if let Ok(value) = input.try(|i| TransitionProperty::parse(context, i)) { property = Some(Some(value)); continue; } diff --git a/components/style/values/computed/box.rs b/components/style/values/computed/box.rs index 96696702a2a..224fe4669a1 100644 --- a/components/style/values/computed/box.rs +++ b/components/style/values/computed/box.rs @@ -11,7 +11,7 @@ use values::generics::box_::Perspective as GenericPerspective; use values::generics::box_::VerticalAlign as GenericVerticalAlign; pub use values::specified::box_::{AnimationName, Contain, Display, OverflowClipBox}; -pub use values::specified::box_::{OverscrollBehavior, ScrollSnapType, TouchAction, WillChange}; +pub use values::specified::box_::{OverscrollBehavior, ScrollSnapType, TouchAction, TransitionProperty, WillChange}; /// A computed value for the `vertical-align` property. pub type VerticalAlign = GenericVerticalAlign; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index d6660f6a6eb..e742c4e49f1 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -30,7 +30,6 @@ use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent use super::specified; pub use app_units::Au; -pub use properties::animated_properties::TransitionProperty; #[cfg(feature = "gecko")] pub use self::align::{AlignContent, AlignItems, JustifyContent, JustifyItems, SelfAlignment}; #[cfg(feature = "gecko")] @@ -43,7 +42,7 @@ pub use self::font::{FontSize, FontSizeAdjust, FontStretch, FontSynthesis, FontV pub use self::font::{FontFamily, FontLanguageOverride, FontStyle, FontVariantEastAsian, FontVariationSettings}; pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric}; pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom}; -pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display}; +pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display, TransitionProperty}; pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective}; pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange}; pub use self::color::{Color, ColorPropertyValue, RGBAColor}; diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index dcce3d592ab..059188f824d 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -7,10 +7,10 @@ use Atom; use cssparser::Parser; use parser::{Parse, ParserContext}; -use properties::{LonghandId, PropertyId, PropertyFlags, PropertyDeclarationId}; +use properties::{LonghandId, ShorthandId, PropertyId, PropertyFlags, PropertyDeclarationId}; use selectors::parser::SelectorParseErrorKind; use std::fmt::{self, Write}; -use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; +use style_traits::{CssWriter, KeywordsCollectFn, ParseError, StyleParseErrorKind, SpecifiedValueInfo, ToCss}; use values::{CustomIdent, KeyframesName}; use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount; use values::generics::box_::Perspective as GenericPerspective; @@ -714,3 +714,96 @@ impl Parse for Perspective { )?)) } } + +/// A given transition property, that is either `All`, a longhand or shorthand +/// property, or an unsupported or custom property. +#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue)] +pub enum TransitionProperty { + /// A shorthand. + Shorthand(ShorthandId), + /// A longhand transitionable property. + Longhand(LonghandId), + /// A custom property. + Custom(Atom), + /// Unrecognized property which could be any non-transitionable, custom property, or + /// unknown property. + Unsupported(CustomIdent), +} + +impl ToCss for TransitionProperty { + fn to_css(&self, dest: &mut CssWriter) -> fmt::Result + where + W: Write, + { + use values::serialize_atom_identifier; + match *self { + TransitionProperty::Shorthand(ref s) => s.to_css(dest), + TransitionProperty::Longhand(ref l) => l.to_css(dest), + TransitionProperty::Custom(ref name) => { + dest.write_str("--")?; + serialize_atom_identifier(name, dest) + } + TransitionProperty::Unsupported(ref i) => i.to_css(dest), + } + } +} + +impl Parse for TransitionProperty { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + let location = input.current_source_location(); + let ident = input.expect_ident()?; + + let id = match PropertyId::parse(&ident, context) { + Ok(id) => id, + Err(..) => return Ok(TransitionProperty::Unsupported( + CustomIdent::from_ident(location, ident, &["none"])?, + )), + }; + + Ok(match id.as_shorthand() { + Ok(s) => TransitionProperty::Shorthand(s), + Err(longhand_or_custom) => { + match longhand_or_custom { + PropertyDeclarationId::Longhand(id) => TransitionProperty::Longhand(id), + PropertyDeclarationId::Custom(custom) => { + TransitionProperty::Custom(custom.clone()) + } + } + } + }) + } +} + +impl SpecifiedValueInfo for TransitionProperty { + fn collect_completion_keywords(f: KeywordsCollectFn) { + // `transition-property` can actually accept all properties and + // arbitrary identifiers, but `all` is a special one we'd like + // to list. + f(&["all"]); + } +} + +impl TransitionProperty { + /// Returns `all`. + #[inline] + pub fn all() -> Self { + TransitionProperty::Shorthand(ShorthandId::All) + } + + /// Convert TransitionProperty to nsCSSPropertyID. + #[cfg(feature = "gecko")] + pub fn to_nscsspropertyid(&self) -> Result<::gecko_bindings::structs::nsCSSPropertyID, ()> { + Ok(match *self { + TransitionProperty::Shorthand(ShorthandId::All) => { + ::gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_all_properties + } + TransitionProperty::Shorthand(ref id) => id.to_nscsspropertyid(), + TransitionProperty::Longhand(ref id) => id.to_nscsspropertyid(), + TransitionProperty::Custom(..) | + TransitionProperty::Unsupported(..) => return Err(()), + }) + } +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index c25d58332f5..c5794bbad1e 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -23,7 +23,6 @@ use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericT use values::serialize_atom_identifier; use values::specified::calc::CalcNode; -pub use properties::animated_properties::TransitionProperty; pub use self::angle::Angle; #[cfg(feature = "gecko")] pub use self::align::{AlignContent, AlignItems, AlignSelf, ContentDistribution}; @@ -40,7 +39,7 @@ pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumer pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom}; pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display}; pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective}; -pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange}; +pub use self::box_::{ScrollSnapType, TouchAction, TransitionProperty, VerticalAlign, WillChange}; pub use self::color::{Color, ColorPropertyValue, RGBAColor}; pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset}; pub use self::effects::{BoxShadow, Filter, SimpleShadow}; From ce5a85d6a19dbfc8be0fcfbacb241462019139ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 15:36:24 +0200 Subject: [PATCH 06/40] style: Use custom_properties::Name in TransitionProperty. Bug: 1419695 Reviewed-by: xidorn MozReview-Commit-ID: BUSWrcA5hkw --- components/style/values/specified/box.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index 059188f824d..3caee1e7f08 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -6,6 +6,7 @@ use Atom; use cssparser::Parser; +use custom_properties::Name as CustomPropertyName; use parser::{Parse, ParserContext}; use properties::{LonghandId, ShorthandId, PropertyId, PropertyFlags, PropertyDeclarationId}; use selectors::parser::SelectorParseErrorKind; @@ -724,7 +725,7 @@ pub enum TransitionProperty { /// A longhand transitionable property. Longhand(LonghandId), /// A custom property. - Custom(Atom), + Custom(CustomPropertyName), /// Unrecognized property which could be any non-transitionable, custom property, or /// unknown property. Unsupported(CustomIdent), From 1da798e65bb3451e056afdd2b584ac42e957a93f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 2 Jun 2018 18:38:42 +0200 Subject: [PATCH 07/40] style: Introduce css(parse_condition). This will allow us to add a pref for this, and to parse it only on chrome easily. Bug: 1288572 Reviewed-by: xidorn MozReview-Commit-ID: L1rsyc2A2hu --- components/style/parser.rs | 13 +++++++-- components/style_derive/parse.rs | 44 ++++++++++++++++++++++++++----- components/style_derive/to_css.rs | 1 + 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/components/style/parser.rs b/components/style/parser.rs index 26f4aeea071..1b7c65e2559 100644 --- a/components/style/parser.rs +++ b/components/style/parser.rs @@ -150,10 +150,19 @@ impl<'a> ParserContext<'a> { } } -// XXXManishearth Replace all specified value parse impls with impls of this -// trait. This will make it easy to write more generic values in the future. /// A trait to abstract parsing of a specified value given a `ParserContext` and /// CSS input. +/// +/// This can be derived on keywords with `#[derive(Parse)]`. +/// +/// The derive code understands the following attributes on each of the variants: +/// +/// * `#[css(aliases = "foo,bar")]` can be used to alias a value with another +/// at parse-time. +/// +/// * `#[css(parse_condition = "function")]` can be used to make the parsing of +/// the value conditional on `function`, which will be invoked with a +/// `&ParserContext` reference. pub trait Parse: Sized { /// Parse a value of this type. /// diff --git a/components/style_derive/parse.rs b/components/style_derive/parse.rs index 7727d6b89bb..8b9044fb495 100644 --- a/components/style_derive/parse.rs +++ b/components/style_derive/parse.rs @@ -12,6 +12,7 @@ pub fn derive(input: DeriveInput) -> Tokens { let name = &input.ident; let s = synstructure::Structure::new(&input); + let mut saw_condition = false; let match_body = s.variants().iter().fold(quote!(), |match_body, variant| { let bindings = variant.bindings(); assert!( @@ -29,11 +30,16 @@ pub fn derive(input: DeriveInput) -> Tokens { ); let ident = &variant.ast().ident; - let mut body = quote! { - #match_body - #identifier => Ok(#name::#ident), + saw_condition |= variant_attrs.parse_condition.is_some(); + let condition = match variant_attrs.parse_condition { + Some(ref p) => quote! { if #p(context) }, + None => quote! { }, }; + let mut body = quote! { + #match_body + #identifier #condition => Ok(#name::#ident), + }; let aliases = match variant_attrs.aliases { Some(aliases) => aliases, @@ -43,25 +49,51 @@ pub fn derive(input: DeriveInput) -> Tokens { for alias in aliases.split(",") { body = quote! { #body - #alias => Ok(#name::#ident), + #alias #condition => Ok(#name::#ident), }; } body }); + let context_ident = if saw_condition { + quote! { context } + } else { + quote! { _ } + }; + + let parse_body = if saw_condition { + quote! { + let location = input.current_source_location(); + let ident = input.expect_ident()?; + match_ignore_ascii_case! { &ident, + #match_body + _ => Err(location.new_unexpected_token_error( + ::cssparser::Token::Ident(ident.clone()) + )) + } + } + } else { + quote! { Self::parse(input) } + }; + + let parse_trait_impl = quote! { impl ::parser::Parse for #name { #[inline] fn parse<'i, 't>( - _: &::parser::ParserContext, + #context_ident: &::parser::ParserContext, input: &mut ::cssparser::Parser<'i, 't>, ) -> Result> { - Self::parse(input) + #parse_body } } }; + if saw_condition { + return parse_trait_impl; + } + // TODO(emilio): It'd be nice to get rid of these, but that makes the // conversion harder... let methods_impl = quote! { diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs index 0caef8b01a7..4853f41ee53 100644 --- a/components/style_derive/to_css.rs +++ b/components/style_derive/to_css.rs @@ -235,6 +235,7 @@ pub struct CssVariantAttrs { pub dimension: bool, pub keyword: Option, pub aliases: Option, + pub parse_condition: Option, pub skip: bool, } From cf7b10a32d4bbd04c2ba4375ddfb69255f011b3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 2 Jun 2018 19:35:12 +0200 Subject: [PATCH 08/40] style: Hide -moz- display values from content behind a pref. Bug: 1288572 Reviewed-by: xidorn MozReview-Commit-ID: HDQPub043H1 --- .../style/properties/longhand/box.mako.rs | 3 --- components/style/values/specified/box.rs | 22 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 82e609c44e9..6c388d1efbd 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -9,8 +9,6 @@ inherited=False, gecko_name="Display") %> -// TODO(SimonSapin): don't parse `inline-table`, since we don't support it -// // We allow "display" to apply to placeholders because we need to make the // placeholder pseudo-element an inline-block in the UA stylesheet in Gecko. ${helpers.predefined_type( @@ -19,7 +17,6 @@ ${helpers.predefined_type( "computed::Display::inline()", initial_specified_value="specified::Display::inline()", animation_value_type="discrete", - needs_context=False, flags="APPLIES_TO_PLACEHOLDER", spec="https://drafts.csswg.org/css-display/#propdef-display", servo_restyle_damage="rebuild_and_reflow" diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index 3caee1e7f08..bece7115c17 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -19,6 +19,17 @@ use values::generics::box_::VerticalAlign as GenericVerticalAlign; use values::specified::{AllowQuirks, Number}; use values::specified::length::{LengthOrPercentage, NonNegativeLength}; +#[cfg(feature = "gecko")] +fn moz_display_values_enabled(context: &ParserContext) -> bool { + use gecko_bindings::structs; + use stylesheets::Origin; + context.stylesheet_origin == Origin::UserAgent || + context.chrome_rules_enabled() || + unsafe { + structs::StaticPrefs_sVarCache_layout_css_xul_display_values_content_enabled + } +} + #[allow(missing_docs)] #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] @@ -69,26 +80,37 @@ pub enum Display { #[cfg(feature = "gecko")] WebkitInlineBox, #[cfg(feature = "gecko")] + #[css(parse_condition = "moz_display_values_enabled")] MozBox, #[cfg(feature = "gecko")] + #[css(parse_condition = "moz_display_values_enabled")] MozInlineBox, #[cfg(feature = "gecko")] + #[css(parse_condition = "moz_display_values_enabled")] MozGrid, #[cfg(feature = "gecko")] + #[css(parse_condition = "moz_display_values_enabled")] MozInlineGrid, #[cfg(feature = "gecko")] + #[css(parse_condition = "moz_display_values_enabled")] MozGridGroup, #[cfg(feature = "gecko")] + #[css(parse_condition = "moz_display_values_enabled")] MozGridLine, #[cfg(feature = "gecko")] + #[css(parse_condition = "moz_display_values_enabled")] MozStack, #[cfg(feature = "gecko")] + #[css(parse_condition = "moz_display_values_enabled")] MozInlineStack, #[cfg(feature = "gecko")] + #[css(parse_condition = "moz_display_values_enabled")] MozDeck, #[cfg(feature = "gecko")] + #[css(parse_condition = "moz_display_values_enabled")] MozPopup, #[cfg(feature = "gecko")] + #[css(parse_condition = "moz_display_values_enabled")] MozGroupbox, } From 618eef77eb8ab61a88fed1b84c206bde96c8c310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 2 Jun 2018 20:53:33 +0200 Subject: [PATCH 09/40] style: Don't hide -moz-box / -moz-inline-box yet. I'd really prefer to not land this patch, but... Bug: 1288572 Reviewed-by: mats MozReview-Commit-ID: HzmvhTd32gz --- components/style/values/specified/box.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index bece7115c17..4890f225e6d 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -80,10 +80,8 @@ pub enum Display { #[cfg(feature = "gecko")] WebkitInlineBox, #[cfg(feature = "gecko")] - #[css(parse_condition = "moz_display_values_enabled")] MozBox, #[cfg(feature = "gecko")] - #[css(parse_condition = "moz_display_values_enabled")] MozInlineBox, #[cfg(feature = "gecko")] #[css(parse_condition = "moz_display_values_enabled")] From 0f1b79327fd86c17f6f8f9ff755e272a28fe44ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 21:16:33 +0200 Subject: [PATCH 10/40] style: Minor indentation cleanup. MozReview-Commit-ID: JmilaCX3rNy --- components/style/properties/helpers.mako.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 209c06df095..d266d3e27ac 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -809,8 +809,10 @@ use values::generics::rect::Rect; use values::specified; - pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result> { + pub fn parse_value<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { let rect = Rect::parse_with(context, input, |_c, i| { % if allow_quirks: ${parser_function}_quirky(_c, i, specified::AllowQuirks::Yes) From 4b10b2a7f261428984656bcad80d93a6aec33c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 21:40:07 +0200 Subject: [PATCH 11/40] style: Update smallbitvec to v2.1.1. Actual code changes reviewed upstream in: https://github.com/servo/smallbitvec/pull/12 Bug: 1466647 MozReview-Commit-ID: 3vKVPMovBj --- components/style/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index 56e427c983a..4fb50d8ad85 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -59,7 +59,7 @@ 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.0" +smallbitvec = "2.1.1" smallvec = "0.6" string_cache = { version = "0.7", optional = true } style_derive = {path = "../style_derive"} From 2baa794de6afe81adeeeee6442df1a68f557617b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 21:46:22 +0200 Subject: [PATCH 12/40] style: Sprinkle some inline in methods that are just pointer-chasing or function calls. MozReview-Commit-ID: 8G2NQPBVuXn --- components/style/gecko/wrapper.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 4eae24a2bfa..f85bffaaac6 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -615,31 +615,37 @@ impl<'le> GeckoElement<'le> { // GeckoNode is a raw reference. // // We can use a Cell, but that's a bit of a pain. + #[inline] fn set_flags(&self, flags: u32) { unsafe { Gecko_SetNodeFlags(self.as_node().0, flags) } } + #[inline] unsafe fn unset_flags(&self, flags: u32) { Gecko_UnsetNodeFlags(self.as_node().0, flags) } /// Returns true if this element has descendants for lazy frame construction. + #[inline] pub fn descendants_need_frames(&self) -> bool { self.flags() & (NODE_DESCENDANTS_NEED_FRAMES as u32) != 0 } /// Returns true if this element needs lazy frame construction. + #[inline] pub fn needs_frame(&self) -> bool { self.flags() & (NODE_NEEDS_FRAME as u32) != 0 } /// Returns a reference to the DOM slots for this Element, if they exist. + #[inline] fn dom_slots(&self) -> Option<&structs::FragmentOrElement_nsDOMSlots> { let slots = self.as_node().0.mSlots as *const structs::FragmentOrElement_nsDOMSlots; unsafe { slots.as_ref() } } /// Returns a reference to the extended DOM slots for this Element. + #[inline] fn extended_slots(&self) -> Option<&structs::FragmentOrElement_nsExtendedDOMSlots> { self.dom_slots().and_then(|s| unsafe { (s._base.mExtendedSlots.mPtr as *const structs::FragmentOrElement_nsExtendedDOMSlots) @@ -697,6 +703,7 @@ impl<'le> GeckoElement<'le> { } } + #[inline] fn non_xul_xbl_binding_parent_raw_content(&self) -> *mut nsIContent { debug_assert!(!self.is_xul_element()); self.extended_slots() From 710184b6705dbee66359bfc5732d02c50cacf0fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 21:48:43 +0200 Subject: [PATCH 13/40] style: Sprinkle some #[inline] on methods that have inline fast-paths. MozReview-Commit-ID: 5kOmctLTAX0 --- components/style/gecko/wrapper.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index f85bffaaac6..96f20fd90ab 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -1356,6 +1356,7 @@ impl<'le> TElement for GeckoElement<'le> { !self.is_in_native_anonymous_subtree() } + #[inline] fn implemented_pseudo_element(&self) -> Option { if !self.is_in_native_anonymous_subtree() { return None; @@ -1369,6 +1370,7 @@ impl<'le> TElement for GeckoElement<'le> { PseudoElement::from_pseudo_type(pseudo_type) } + #[inline] fn store_children_to_process(&self, _: isize) { // This is only used for bottom-up traversal, and is thus a no-op for Gecko. } From f82930075127419481380997b69bcb895a872938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 1 Jun 2018 17:11:00 +0200 Subject: [PATCH 14/40] style: Don't look at the rule type from value parsing. This would cause properties to change the value semantics between, e.g., @keyframes and non-@keyframes, which would be observable. It happens not to be observable since the animation-* and transition-* properties are not allowed in @keyframes, nor have bits in `contain`, and none of the two properties are allowed in @page. But I think it's the right thing to do. This still causes a quirk like a property value in chrome / user origins being potentially different if the value is specified via CSS var functions. But I think that is fine. Bug: 1466136 Reviewed-by: hiro MozReview-Commit-ID: GhoPt0I34oO --- .../style/properties/properties.mako.rs | 43 ++++++++++++++++++- components/style/values/specified/box.rs | 4 +- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index b7bc96973b3..38245b707f6 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -499,6 +499,11 @@ impl NonCustomPropertyId { _ => {} } + self.allowed_in_ignoring_rule_type(context) + } + + + fn allowed_in_ignoring_rule_type(self, context: &ParserContext) -> bool { // The semantics of these are kinda hard to reason about, what follows // is a description of the different combinations that can happen with // these three sets. @@ -1423,11 +1428,17 @@ impl UnparsedValue { // As of this writing, only the base URL is used for property // values. // - // FIXME(emilio): These bits are slightly fishy. + // NOTE(emilio): we intentionally pase `None` as the rule type here. + // If something starts depending on it, it's probably a bug, since + // it'd change how values are parsed depending on whether we're in a + // @keyframes rule or not, for example... So think twice about + // whether you want to do this! + // + // FIXME(emilio): ParsingMode is slightly fishy... let context = ParserContext::new( Origin::Author, &self.url_data, - Some(CssRuleType::Style), + None, ParsingMode::DEFAULT, quirks_mode, ); @@ -1674,6 +1685,24 @@ impl PropertyId { Ok(id) } + /// Parses a property name, and returns an error if it's unknown or isn't + /// allowed in this context, ignoring the rule_type checks. + /// + /// This is useful for parsing stuff from CSS values, for example. + #[inline] + pub fn parse_ignoring_rule_type( + name: &str, + context: &ParserContext, + ) -> Result { + let id = Self::parse_unchecked(name)?; + + if !id.allowed_in_ignoring_rule_type(context) { + return Err(()); + } + + Ok(id) + } + /// Returns a property id from Gecko's nsCSSPropertyID. #[cfg(feature = "gecko")] #[allow(non_upper_case_globals)] @@ -1787,6 +1816,16 @@ impl PropertyId { id.allowed_in(context) } + #[inline] + fn allowed_in_ignoring_rule_type(&self, context: &ParserContext) -> bool { + let id = match self.non_custom_id() { + // Custom properties are allowed everywhere + None => return true, + Some(id) => id, + }; + id.allowed_in_ignoring_rule_type(context) + } + /// Whether the property supports the given CSS type. /// `ty` should a bitflags of constants in style_traits::CssType. pub fn supports_type(&self, ty: u8) -> bool { diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index 4890f225e6d..020c8112ad1 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -465,7 +465,7 @@ fn change_bits_for_longhand(longhand: LonghandId) -> WillChangeBits { } fn change_bits_for_maybe_property(ident: &str, context: &ParserContext) -> WillChangeBits { - let id = match PropertyId::parse(ident, context) { + let id = match PropertyId::parse_ignoring_rule_type(ident, context) { Ok(id) => id, Err(..) => return WillChangeBits::empty(), }; @@ -777,7 +777,7 @@ impl Parse for TransitionProperty { let location = input.current_source_location(); let ident = input.expect_ident()?; - let id = match PropertyId::parse(&ident, context) { + let id = match PropertyId::parse_ignoring_rule_type(&ident, context) { Ok(id) => id, Err(..) => return Ok(TransitionProperty::Unsupported( CustomIdent::from_ident(location, ident, &["none"])?, From 8d069d127a49ef43962362c91d81ad046a7d757c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 19:14:20 +0200 Subject: [PATCH 15/40] style: Work around a bindgen bug on Android. Bug: 1466406 Reviewed-by: xidorn MozReview-Commit-ID: 2lltjH7IoZu --- components/style/gecko/wrapper.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 96f20fd90ab..5475be1e3fc 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -1118,7 +1118,23 @@ impl<'le> TElement for GeckoElement<'le> { assert_eq!(base as *const _, self.0 as *const _, "Bad cast"); } - let assigned_nodes: &[structs::RefPtr] = &*slot.mAssignedNodes; + // FIXME(emilio): Workaround a bindgen bug on Android that causes + // mAssignedNodes to be at the wrong offset. See bug 1466406. + // + // Bug 1466580 tracks running the Android layout tests on automation. + // + // The actual bindgen bug still needs reduction. + let assigned_nodes: &[structs::RefPtr] = + if !cfg!(target_os = "android") { + debug_assert_eq!( + unsafe { bindings::Gecko_GetAssignedNodes(self.0) }, + &slot.mAssignedNodes as *const _, + ); + + &*slot.mAssignedNodes + } else { + unsafe { &**bindings::Gecko_GetAssignedNodes(self.0) } + }; debug_assert_eq!( mem::size_of::>(), From 8821ad72f4a95ea04fe8d73fa6e868410c2349f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 16:27:00 +0200 Subject: [PATCH 16/40] style: Make pseudo-elements work with :host. Imported WebKit's test as a WPT. Bug: 1465291 Reviewed-by: xidorn MozReview-Commit-ID: 19ZThuoqKLW --- components/selectors/parser.rs | 22 +++++++++++++++--- components/style/stylist.rs | 41 +++++++++++++--------------------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index fc840bfe926..2c9d6505776 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -544,10 +544,26 @@ impl Selector { } /// Whether this selector is a featureless :host selector, with no - /// combinators to the left. + /// combinators to the left, and optionally has a pseudo-element to the + /// right. #[inline] - pub fn is_featureless_host_selector(&self) -> bool { - self.iter().is_featureless_host_selector() + pub fn is_featureless_host_selector_or_pseudo_element(&self) -> bool { + let mut iter = self.iter(); + if !self.has_pseudo_element() { + return iter.is_featureless_host_selector(); + } + + // Skip the pseudo-element. + for _ in &mut iter { } + + match iter.next_sequence() { + None => return false, + Some(combinator) => { + debug_assert_eq!(combinator, Combinator::PseudoElement); + } + } + + iter.is_featureless_host_selector() } /// Returns an iterator over this selector in matching order (right-to-left), diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 34f187e483a..e777921e668 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -1951,14 +1951,9 @@ pub struct CascadeData { /// cascade level. normal_rules: ElementAndPseudoRules, - /// The `:host` pseudo rules that are the rightmost selector. - /// - /// Note that as of right now these can't affect invalidation in any way, - /// until we support the :host() notation. - /// - /// Also, note that other engines don't accept stuff like :host::before / - /// :host::after, so we don't need to store pseudo rules at all. - host_rules: Option>>, + /// The `:host` pseudo rules that are the rightmost selector (without + /// accounting for pseudo-elements). + host_rules: Option>, /// The data coming from ::slotted() pseudo-element rules. /// @@ -2122,11 +2117,7 @@ impl CascadeData { #[inline] fn host_rules(&self, pseudo: Option<&PseudoElement>) -> Option<&SelectorMap> { - if pseudo.is_some() { - return None; - } - - self.host_rules.as_ref().map(|rules| &**rules) + self.host_rules.as_ref().and_then(|d| d.rules(pseudo)) } #[inline] @@ -2258,20 +2249,20 @@ impl CascadeData { } } - if selector.is_featureless_host_selector() { - let host_rules = self.host_rules - .get_or_insert_with(|| Box::new(Default::default())); - host_rules.insert(rule, quirks_mode)?; + // NOTE(emilio): It's fine to look at :host and then at + // ::slotted(..), since :host::slotted(..) could never + // possibly match, as is not a valid shadow host. + let rules = if selector.is_featureless_host_selector_or_pseudo_element() { + self.host_rules + .get_or_insert_with(|| Box::new(Default::default())) + } else if selector.is_slotted() { + self.slotted_rules + .get_or_insert_with(|| Box::new(Default::default())) } else { - let rules = if selector.is_slotted() { - self.slotted_rules - .get_or_insert_with(|| Box::new(Default::default())) - } else { - &mut self.normal_rules - }; + &mut self.normal_rules + }; - rules.insert(rule, pseudo_element, quirks_mode)?; - } + rules.insert(rule, pseudo_element, quirks_mode)?; } self.rules_source_order += 1; }, From 2c0a19e5171669d6c1162d00871f0d76ce7f6f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 19:24:43 +0200 Subject: [PATCH 17/40] style: Move some parsing-only attributes to use #[parse(..)] instead of #[css(..)]. I need to admit I'm ambivalent about this one :). Bug: 1466609 Reviewed-by: xidorn MozReview-Commit-ID: F1jlfnQKXwo --- components/style/parser.rs | 8 +++---- components/style/properties/helpers.mako.rs | 2 +- components/style/values/specified/box.rs | 22 ++++++++--------- components/style_derive/lib.rs | 4 ++-- components/style_derive/parse.rs | 24 +++++++++++++------ .../style_derive/specified_value_info.rs | 4 +++- components/style_derive/to_css.rs | 2 -- .../style_traits/specified_value_info.rs | 2 +- 8 files changed, 39 insertions(+), 29 deletions(-) diff --git a/components/style/parser.rs b/components/style/parser.rs index 1b7c65e2559..6dbfe1cfa01 100644 --- a/components/style/parser.rs +++ b/components/style/parser.rs @@ -157,12 +157,12 @@ impl<'a> ParserContext<'a> { /// /// The derive code understands the following attributes on each of the variants: /// -/// * `#[css(aliases = "foo,bar")]` can be used to alias a value with another +/// * `#[parse(aliases = "foo,bar")]` can be used to alias a value with another /// at parse-time. /// -/// * `#[css(parse_condition = "function")]` can be used to make the parsing of -/// the value conditional on `function`, which will be invoked with a -/// `&ParserContext` reference. +/// * `#[parse(condition = "function")]` can be used to make the parsing of the +/// value conditional on `function`, which needs to fulfill +/// `fn(&ParserContext) -> bool`. pub trait Parse: Sized { /// Parse a value of this type. /// diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index d266d3e27ac..11a1283f1cc 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -594,7 +594,7 @@ aliases.append(alias) %> % if aliases: - #[css(aliases = "${','.join(aliases)}")] + #[parse(aliases = "${','.join(aliases)}")] % endif % endif ${to_camel_case(variant)}, diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index 020c8112ad1..1f56583575c 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -53,9 +53,9 @@ pub enum Display { TableCaption, ListItem, None, - #[css(aliases = "-webkit-flex")] + #[parse(aliases = "-webkit-flex")] Flex, - #[css(aliases = "-webkit-inline-flex")] + #[parse(aliases = "-webkit-inline-flex")] InlineFlex, #[cfg(feature = "gecko")] Grid, @@ -84,31 +84,31 @@ pub enum Display { #[cfg(feature = "gecko")] MozInlineBox, #[cfg(feature = "gecko")] - #[css(parse_condition = "moz_display_values_enabled")] + #[parse(condition = "moz_display_values_enabled")] MozGrid, #[cfg(feature = "gecko")] - #[css(parse_condition = "moz_display_values_enabled")] + #[parse(condition = "moz_display_values_enabled")] MozInlineGrid, #[cfg(feature = "gecko")] - #[css(parse_condition = "moz_display_values_enabled")] + #[parse(condition = "moz_display_values_enabled")] MozGridGroup, #[cfg(feature = "gecko")] - #[css(parse_condition = "moz_display_values_enabled")] + #[parse(condition = "moz_display_values_enabled")] MozGridLine, #[cfg(feature = "gecko")] - #[css(parse_condition = "moz_display_values_enabled")] + #[parse(condition = "moz_display_values_enabled")] MozStack, #[cfg(feature = "gecko")] - #[css(parse_condition = "moz_display_values_enabled")] + #[parse(condition = "moz_display_values_enabled")] MozInlineStack, #[cfg(feature = "gecko")] - #[css(parse_condition = "moz_display_values_enabled")] + #[parse(condition = "moz_display_values_enabled")] MozDeck, #[cfg(feature = "gecko")] - #[css(parse_condition = "moz_display_values_enabled")] + #[parse(condition = "moz_display_values_enabled")] MozPopup, #[cfg(feature = "gecko")] - #[css(parse_condition = "moz_display_values_enabled")] + #[parse(condition = "moz_display_values_enabled")] MozGroupbox, } diff --git a/components/style_derive/lib.rs b/components/style_derive/lib.rs index 88f0bbadfb1..8c8c0705e8f 100644 --- a/components/style_derive/lib.rs +++ b/components/style_derive/lib.rs @@ -40,7 +40,7 @@ pub fn derive_to_animated_value(stream: TokenStream) -> TokenStream { to_animated_value::derive(input).into() } -#[proc_macro_derive(Parse, attributes(css))] +#[proc_macro_derive(Parse, attributes(css, parse))] pub fn derive_parse(stream: TokenStream) -> TokenStream { let input = syn::parse(stream).unwrap(); parse::derive(input).into() @@ -64,7 +64,7 @@ pub fn derive_to_css(stream: TokenStream) -> TokenStream { to_css::derive(input).into() } -#[proc_macro_derive(SpecifiedValueInfo, attributes(css, value_info))] +#[proc_macro_derive(SpecifiedValueInfo, attributes(css, parse, value_info))] pub fn derive_specified_value_info(stream: TokenStream) -> TokenStream { let input = syn::parse(stream).unwrap(); specified_value_info::derive(input).into() diff --git a/components/style_derive/parse.rs b/components/style_derive/parse.rs index 8b9044fb495..13d8aa6f48b 100644 --- a/components/style_derive/parse.rs +++ b/components/style_derive/parse.rs @@ -4,10 +4,17 @@ use cg; use quote::Tokens; -use syn::DeriveInput; +use syn::{DeriveInput, Path}; use synstructure; use to_css::CssVariantAttrs; +#[darling(attributes(parse), default)] +#[derive(Default, FromVariant)] +pub struct ParseVariantAttrs { + pub aliases: Option, + pub condition: Option, +} + pub fn derive(input: DeriveInput) -> Tokens { let name = &input.ident; let s = synstructure::Structure::new(&input); @@ -20,18 +27,21 @@ pub fn derive(input: DeriveInput) -> Tokens { "Parse is only supported for single-variant enums for now" ); - let variant_attrs = cg::parse_variant_attrs_from_ast::(&variant.ast()); - if variant_attrs.skip { + let css_variant_attrs = + cg::parse_variant_attrs_from_ast::(&variant.ast()); + let parse_attrs = + cg::parse_variant_attrs_from_ast::(&variant.ast()); + if css_variant_attrs.skip { return match_body; } let identifier = cg::to_css_identifier( - &variant_attrs.keyword.unwrap_or(variant.ast().ident.as_ref().into()), + &css_variant_attrs.keyword.unwrap_or(variant.ast().ident.as_ref().into()), ); let ident = &variant.ast().ident; - saw_condition |= variant_attrs.parse_condition.is_some(); - let condition = match variant_attrs.parse_condition { + saw_condition |= parse_attrs.condition.is_some(); + let condition = match parse_attrs.condition { Some(ref p) => quote! { if #p(context) }, None => quote! { }, }; @@ -41,7 +51,7 @@ pub fn derive(input: DeriveInput) -> Tokens { #identifier #condition => Ok(#name::#ident), }; - let aliases = match variant_attrs.aliases { + let aliases = match parse_attrs.aliases { Some(aliases) => aliases, None => return body, }; diff --git a/components/style_derive/specified_value_info.rs b/components/style_derive/specified_value_info.rs index 7aae081641d..37471b041a8 100644 --- a/components/style_derive/specified_value_info.rs +++ b/components/style_derive/specified_value_info.rs @@ -6,6 +6,7 @@ use cg; use quote::Tokens; use syn::{Data, DeriveInput, Fields, Ident, Type}; use to_css::{CssFieldAttrs, CssInputAttrs, CssVariantAttrs}; +use parse::ParseVariantAttrs; pub fn derive(mut input: DeriveInput) -> Tokens { let css_attrs = cg::parse_input_attrs::(&input); @@ -33,10 +34,11 @@ pub fn derive(mut input: DeriveInput) -> Tokens { for v in e.variants.iter() { let css_attrs = cg::parse_variant_attrs::(&v); let info_attrs = cg::parse_variant_attrs::(&v); + let parse_attrs = cg::parse_variant_attrs::(&v); if css_attrs.skip { continue; } - if let Some(aliases) = css_attrs.aliases { + if let Some(aliases) = parse_attrs.aliases { for alias in aliases.split(",") { values.push(alias.to_string()); } diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs index 4853f41ee53..471cf37b6de 100644 --- a/components/style_derive/to_css.rs +++ b/components/style_derive/to_css.rs @@ -234,8 +234,6 @@ pub struct CssVariantAttrs { pub comma: bool, pub dimension: bool, pub keyword: Option, - pub aliases: Option, - pub parse_condition: Option, pub skip: bool, } diff --git a/components/style_traits/specified_value_info.rs b/components/style_traits/specified_value_info.rs index d9f4578b1a8..e0dd5544d0a 100644 --- a/components/style_traits/specified_value_info.rs +++ b/components/style_traits/specified_value_info.rs @@ -43,7 +43,7 @@ pub type KeywordsCollectFn<'a> = &'a mut FnMut(&[&'static str]); /// name is listed in `collect_completion_keywords`. /// * If `#[css(skip)]` is found, the content inside the variant or /// field is ignored. -/// * Values listed in `#[css(if_empty)]`, `#[css(aliases)]`, and +/// * Values listed in `#[css(if_empty)]`, `#[parse(aliases)]`, and /// `#[css(keyword)]` are added into `collect_completion_keywords`. /// /// In addition to `css` attributes, it also has `value_info` helper From d461a7ddbe36403fc354885f0ba6ab33e9cb0927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 19:53:45 +0200 Subject: [PATCH 18/40] style: Make the threadsafe refcounting macros more reusable. Bug: 1466609 Reviewed-by: xidorn MozReview-Commit-ID: IanxqRksGqE --- .../style/gecko_bindings/sugar/refptr.rs | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/components/style/gecko_bindings/sugar/refptr.rs b/components/style/gecko_bindings/sugar/refptr.rs index 76a7021ef5b..5019663a580 100644 --- a/components/style/gecko_bindings/sugar/refptr.rs +++ b/components/style/gecko_bindings/sugar/refptr.rs @@ -4,7 +4,7 @@ //! A rust helper to ease the use of Gecko's refcounted types. -use gecko_bindings::structs; +use gecko_bindings::{structs, bindings}; use gecko_bindings::sugar::ownership::HasArcFFI; use servo_arc::Arc; use std::{fmt, mem, ptr}; @@ -255,13 +255,16 @@ unsafe impl Send for RefPtr {} unsafe impl Sync for RefPtr {} macro_rules! impl_refcount { - ($t:ty, $addref:ident, $release:ident) => { + ($t:ty, $addref:path, $release:path) => { unsafe impl RefCounted for $t { + #[inline] fn addref(&self) { - unsafe { ::gecko_bindings::bindings::$addref(self as *const _ as *mut _) } + unsafe { $addref(self as *const _ as *mut _) } } + + #[inline] unsafe fn release(&self) { - ::gecko_bindings::bindings::$release(self as *const _ as *mut _) + $release(self as *const _ as *mut _) } } }; @@ -271,50 +274,49 @@ macro_rules! impl_refcount { // // Gets you a free RefCounted impl implemented via FFI. macro_rules! impl_threadsafe_refcount { - ($t:ty, $addref:ident, $release:ident) => { + ($t:ty, $addref:path, $release:path) => { impl_refcount!($t, $addref, $release); unsafe impl ThreadSafeRefCounted for $t {} }; } impl_threadsafe_refcount!( - ::gecko_bindings::structs::RawGeckoURLExtraData, - Gecko_AddRefURLExtraDataArbitraryThread, - Gecko_ReleaseURLExtraDataArbitraryThread + structs::RawGeckoURLExtraData, + bindings::Gecko_AddRefURLExtraDataArbitraryThread, + bindings::Gecko_ReleaseURLExtraDataArbitraryThread ); impl_threadsafe_refcount!( - ::gecko_bindings::structs::nsStyleQuoteValues, - Gecko_AddRefQuoteValuesArbitraryThread, - Gecko_ReleaseQuoteValuesArbitraryThread + structs::nsStyleQuoteValues, + bindings::Gecko_AddRefQuoteValuesArbitraryThread, + bindings::Gecko_ReleaseQuoteValuesArbitraryThread ); impl_threadsafe_refcount!( - ::gecko_bindings::structs::nsCSSValueSharedList, - Gecko_AddRefCSSValueSharedListArbitraryThread, - Gecko_ReleaseCSSValueSharedListArbitraryThread + structs::nsCSSValueSharedList, + bindings::Gecko_AddRefCSSValueSharedListArbitraryThread, + bindings::Gecko_ReleaseCSSValueSharedListArbitraryThread ); impl_threadsafe_refcount!( - ::gecko_bindings::structs::mozilla::css::URLValue, - Gecko_AddRefCSSURLValueArbitraryThread, - Gecko_ReleaseCSSURLValueArbitraryThread + structs::mozilla::css::URLValue, + bindings::Gecko_AddRefCSSURLValueArbitraryThread, + bindings::Gecko_ReleaseCSSURLValueArbitraryThread ); impl_threadsafe_refcount!( - ::gecko_bindings::structs::mozilla::css::GridTemplateAreasValue, - Gecko_AddRefGridTemplateAreasValueArbitraryThread, - Gecko_ReleaseGridTemplateAreasValueArbitraryThread + structs::mozilla::css::GridTemplateAreasValue, + bindings::Gecko_AddRefGridTemplateAreasValueArbitraryThread, + bindings::Gecko_ReleaseGridTemplateAreasValueArbitraryThread ); impl_threadsafe_refcount!( - ::gecko_bindings::structs::ImageValue, - Gecko_AddRefImageValueArbitraryThread, - Gecko_ReleaseImageValueArbitraryThread + structs::ImageValue, + bindings::Gecko_AddRefImageValueArbitraryThread, + bindings::Gecko_ReleaseImageValueArbitraryThread ); impl_threadsafe_refcount!( - ::gecko_bindings::structs::SharedFontList, - Gecko_AddRefSharedFontListArbitraryThread, - Gecko_ReleaseSharedFontListArbitraryThread + structs::SharedFontList, + bindings::Gecko_AddRefSharedFontListArbitraryThread, + bindings::Gecko_ReleaseSharedFontListArbitraryThread ); - impl_threadsafe_refcount!( - ::gecko_bindings::structs::SheetLoadDataHolder, - Gecko_AddRefSheetLoadDataHolderArbitraryThread, - Gecko_ReleaseSheetLoadDataHolderArbitraryThread + structs::SheetLoadDataHolder, + bindings::Gecko_AddRefSheetLoadDataHolderArbitraryThread, + bindings::Gecko_ReleaseSheetLoadDataHolderArbitraryThread ); From 63ca2a803dbf05e8659f974053c4c601429257ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 20:09:51 +0200 Subject: [PATCH 19/40] style: Make clearing atoms slightly more ergonomic. I prefer to do it this way because Atom has inline paths for static atoms and such. Bug: 1466609 Reviewed-by: xidorn MozReview-Commit-ID: CFsBHl80KDY --- components/style/gecko_bindings/sugar/refptr.rs | 15 +++++++++++++++ components/style/properties/gecko.mako.rs | 10 ++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/components/style/gecko_bindings/sugar/refptr.rs b/components/style/gecko_bindings/sugar/refptr.rs index 5019663a580..10c9e627699 100644 --- a/components/style/gecko_bindings/sugar/refptr.rs +++ b/components/style/gecko_bindings/sugar/refptr.rs @@ -4,6 +4,7 @@ //! A rust helper to ease the use of Gecko's refcounted types. +use Atom; use gecko_bindings::{structs, bindings}; use gecko_bindings::sugar::ownership::HasArcFFI; use servo_arc::Arc; @@ -320,3 +321,17 @@ impl_threadsafe_refcount!( bindings::Gecko_AddRefSheetLoadDataHolderArbitraryThread, bindings::Gecko_ReleaseSheetLoadDataHolderArbitraryThread ); + +#[inline] +unsafe fn addref_atom(atom: *mut structs::nsAtom) { + mem::forget(Atom::from_raw(atom)); +} +#[inline] +unsafe fn release_atom(atom: *mut structs::nsAtom) { + let _ = Atom::from_addrefed(atom); +} +impl_threadsafe_refcount!( + structs::nsAtom, + addref_atom, + release_atom +); diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index b4411e1ea8b..13d93b0a144 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -3274,10 +3274,7 @@ fn static_assert() { self.gecko.mTransitions.ensure_len(v.len()); self.gecko.mTransitionPropertyCount = v.len() as u32; for (servo, gecko) in v.zip(self.gecko.mTransitions.iter_mut()) { - if !gecko.mUnknownProperty.mRawPtr.is_null() { - unsafe { Atom::from_addrefed(gecko.mUnknownProperty.mRawPtr) }; - gecko.mUnknownProperty.mRawPtr = ptr::null_mut(); - } + unsafe { gecko.mUnknownProperty.clear() }; match servo { TransitionProperty::Unsupported(ident) => { @@ -3355,10 +3352,7 @@ fn static_assert() { for (index, transition) in self.gecko.mTransitions.iter_mut().enumerate().take(count as usize) { transition.mProperty = other.gecko.mTransitions[index].mProperty; - if !transition.mUnknownProperty.mRawPtr.is_null() { - unsafe { Atom::from_addrefed(transition.mUnknownProperty.mRawPtr) }; - transition.mUnknownProperty.mRawPtr = ptr::null_mut(); - } + unsafe { transition.mUnknownProperty.clear() }; if transition.mProperty == eCSSProperty_UNKNOWN || transition.mProperty == eCSSPropertyExtra_variable { let atom = other.gecko.mTransitions[index].mUnknownProperty.mRawPtr; From c6e43c03294da0823e48b95f0d744684245d9978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 5 Jun 2018 15:53:43 +0200 Subject: [PATCH 20/40] style: Avoid useless allocations in custom property name serialization. And make transition-property more correct by serializing --0 unescaped instead of escaped. Bug: 1466645 Reviewed-by: xidorn MozReview-Commit-ID: CCBSe5Frd0d --- .../style/properties/properties.mako.rs | 11 +++++---- components/style/values/mod.rs | 24 ++++++++++++++++++- components/style/values/specified/box.rs | 4 ++-- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 38245b707f6..2c80c2573c8 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -49,6 +49,7 @@ use stylesheets::{CssRuleType, Origin, UrlExtraData}; use values::generics::text::LineHeight; use values::computed; use values::computed::NonNegativeLength; +use values::serialize_atom_name; use rule_tree::{CascadeLevel, StrongRuleNode}; use self::computed_value_flags::*; use str::{CssString, CssStringBorrow, CssStringWriter}; @@ -1506,8 +1507,9 @@ impl<'a> ToCss for PropertyDeclarationId<'a> { { match *self { PropertyDeclarationId::Longhand(id) => dest.write_str(id.name()), - PropertyDeclarationId::Custom(_) => { - serialize_identifier(&self.name(), dest) + PropertyDeclarationId::Custom(ref name) => { + dest.write_str("--")?; + serialize_atom_name(name, dest) } } } @@ -1587,8 +1589,9 @@ impl ToCss for PropertyId { PropertyId::Shorthand(id) => dest.write_str(id.name()), PropertyId::LonghandAlias(id, _) => dest.write_str(id.name()), PropertyId::ShorthandAlias(id, _) => dest.write_str(id.name()), - PropertyId::Custom(_) => { - serialize_identifier(&self.name(), dest) + PropertyId::Custom(ref name) => { + dest.write_str("--")?; + serialize_atom_name(name, dest) } } } diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index f02242e78d1..a5f8d0abd32 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -9,7 +9,7 @@ #![deny(missing_docs)] use Atom; -pub use cssparser::{serialize_identifier, CowRcStr, Parser, SourceLocation, Token, RGBA}; +pub use cssparser::{serialize_identifier, serialize_name, CowRcStr, Parser, SourceLocation, Token, RGBA}; use parser::{Parse, ParserContext}; use selectors::parser::SelectorParseErrorKind; use std::fmt::{self, Debug, Write}; @@ -60,6 +60,28 @@ where serialize_identifier(&ident, dest) } +/// Serialize a name which is represented as an Atom. +#[cfg(feature = "gecko")] +pub fn serialize_atom_name(ident: &Atom, dest: &mut W) -> fmt::Result +where + W: Write, +{ + ident.with_str(|s| serialize_name(s, dest)) +} + +/// Serialize a name which is represented as an Atom. +#[cfg(feature = "servo")] +pub fn serialize_atom_name( + ident: &::string_cache::Atom, + dest: &mut W, +) -> fmt::Result +where + Static: ::string_cache::StaticAtomSet, + W: Write, +{ + serialize_name(&ident, dest) +} + /// Serialize a normalized value into percentage. pub fn serialize_percentage(value: CSSFloat, dest: &mut CssWriter) -> fmt::Result where diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index 1f56583575c..7980fb2b2e7 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -756,13 +756,13 @@ impl ToCss for TransitionProperty { where W: Write, { - use values::serialize_atom_identifier; + use values::serialize_atom_name; match *self { TransitionProperty::Shorthand(ref s) => s.to_css(dest), TransitionProperty::Longhand(ref l) => l.to_css(dest), TransitionProperty::Custom(ref name) => { dest.write_str("--")?; - serialize_atom_identifier(name, dest) + serialize_atom_name(name, dest) } TransitionProperty::Unsupported(ref i) => i.to_css(dest), } From 752978837566d58ed2b14922d3b78618191c4795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 21:08:35 +0200 Subject: [PATCH 21/40] style: Make getting a property name explicitly an indexing operation. The six milliseconds spent in Olli's profile make me thing this is not getting optimized and we expected. Also move it to NonCustomPropertyId, so it works for aliases properly too. Bug: 1466645 Reviewed-by: xidorn MozReview-Commit-ID: 4d76Z55ZBEH --- .../style/properties/properties.mako.rs | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 2c80c2573c8..e2078853844 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -428,6 +428,17 @@ impl NonCustomPropertyId { MAP[self.0] } + /// Get the property name. + #[inline] + fn name(self) -> &'static str { + static MAP: [&'static str; ${len(data.longhands) + len(data.shorthands) + len(data.all_aliases())}] = [ + % for property in data.longhands + data.shorthands + data.all_aliases(): + "${property.name}", + % endfor + ]; + MAP[self.0] + } + #[inline] fn enabled_for_all_content(self) -> bool { ${static_non_custom_property_id_set( @@ -860,12 +871,9 @@ impl fmt::Debug for LonghandId { impl LonghandId { /// Get the name of this longhand property. + #[inline] pub fn name(&self) -> &'static str { - match *self { - % for property in data.longhands: - LonghandId::${property.camel_case} => "${property.name}", - % endfor - } + NonCustomPropertyId::from(*self).name() } /// Returns whether the longhand property is inherited by default. @@ -1203,12 +1211,9 @@ impl ToCss for ShorthandId { impl ShorthandId { /// Get the name for this shorthand property. + #[inline] pub fn name(&self) -> &'static str { - match *self { - % for property in data.shorthands: - ShorthandId::${property.camel_case} => "${property.name}", - % endfor - } + NonCustomPropertyId::from(*self).name() } /// Converts from a ShorthandId to an adequate nsCSSPropertyID. From 915c8725aee035d0a602ae946795c0b1f5c7315e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 20:57:49 +0200 Subject: [PATCH 22/40] style: Remove PropertyId::name. It's only used for the error path in property parsing, so most of the time is not useful. Use the just-introduced NonCustomPropertyId::name to preserve the alias name, which we were doing by passing the name around. Bug: 1466645 Reviewed-by: xidorn MozReview-Commit-ID: 46xxZKCoeBB --- .../style/properties/declaration_block.rs | 6 +-- .../style/properties/properties.mako.rs | 44 +++++++++---------- .../style/stylesheets/keyframes_rule.rs | 4 +- components/style/stylesheets/supports_rule.rs | 29 ++++++------ components/style_traits/lib.rs | 6 ++- 5 files changed, 47 insertions(+), 42 deletions(-) diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index a66058caf1e..3cdbf61de66 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -1116,9 +1116,7 @@ where let mut parser = Parser::new(&mut input); let start_position = parser.position(); parser.parse_entirely(|parser| { - let name = id.name().into(); - PropertyDeclaration::parse_into(declarations, id, name, &context, parser) - .map_err(|e| e.into()) + PropertyDeclaration::parse_into(declarations, id, &context, parser) }).map_err(|err| { let location = err.location; let error = ContextualParseError::UnsupportedPropertyDeclaration( @@ -1169,7 +1167,7 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> { } }; input.parse_until_before(Delimiter::Bang, |input| { - PropertyDeclaration::parse_into(self.declarations, id, name, self.context, input) + PropertyDeclaration::parse_into(self.declarations, id, self.context, input) })?; let importance = match input.try(parse_important) { Ok(()) => Importance::Important, diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index e2078853844..5133cd6ae2d 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -23,7 +23,7 @@ use std::fmt::{self, Write}; use std::mem::{self, ManuallyDrop}; #[cfg(feature = "servo")] use cssparser::RGBA; -use cssparser::{CowRcStr, Parser, TokenSerializationType, serialize_identifier}; +use cssparser::{Parser, TokenSerializationType}; use cssparser::ParserInput; #[cfg(feature = "servo")] use euclid::SideOffsets2D; use context::QuirksMode; @@ -1765,21 +1765,6 @@ impl PropertyId { } } - /// Returns the name of the property without CSS escaping. - pub fn name(&self) -> Cow<'static, str> { - match *self { - PropertyId::ShorthandAlias(id, _) | - PropertyId::Shorthand(id) => id.name().into(), - PropertyId::LonghandAlias(id, _) | - PropertyId::Longhand(id) => id.name().into(), - PropertyId::Custom(ref name) => { - let mut s = String::new(); - write!(&mut s, "--{}", name).unwrap(); - s.into() - } - } - } - fn non_custom_id(&self) -> Option { Some(match *self { PropertyId::Custom(_) => return None, @@ -2042,13 +2027,13 @@ impl PropertyDeclaration { pub fn parse_into<'i, 't>( declarations: &mut SourcePropertyDeclaration, id: PropertyId, - name: CowRcStr<'i>, context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<(), ParseError<'i>> { assert!(declarations.is_empty()); debug_assert!(id.allowed_in(context), "{:?}", id); + let non_custom_id = id.non_custom_id(); let start = input.state(); match id { PropertyId::Custom(property_name) => { @@ -2059,7 +2044,10 @@ impl PropertyDeclaration { Ok(keyword) => DeclaredValueOwned::CSSWideKeyword(keyword), Err(()) => match ::custom_properties::SpecifiedValue::parse(input) { Ok(value) => DeclaredValueOwned::Value(value), - Err(e) => return Err(StyleParseErrorKind::new_invalid(name, e)), + Err(e) => return Err(StyleParseErrorKind::new_invalid( + format!("--{}", property_name), + e, + )), } }; declarations.push(PropertyDeclaration::Custom(CustomDeclaration { @@ -2084,7 +2072,10 @@ impl PropertyDeclaration { input.reset(&start); let (first_token_type, css) = ::custom_properties::parse_non_custom_with_var(input).map_err(|e| { - StyleParseErrorKind::new_invalid(name, e) + StyleParseErrorKind::new_invalid( + non_custom_id.unwrap().name(), + e, + ) })?; Ok(PropertyDeclaration::WithVariables(VariableDeclaration { id, @@ -2096,7 +2087,10 @@ impl PropertyDeclaration { }), })) } else { - Err(StyleParseErrorKind::new_invalid(name, err)) + Err(StyleParseErrorKind::new_invalid( + non_custom_id.unwrap().name(), + err, + )) } }) }).map(|declaration| { @@ -2130,7 +2124,10 @@ impl PropertyDeclaration { input.reset(&start); let (first_token_type, css) = ::custom_properties::parse_non_custom_with_var(input).map_err(|e| { - StyleParseErrorKind::new_invalid(name, e) + StyleParseErrorKind::new_invalid( + non_custom_id.unwrap().name(), + e, + ) })?; let unparsed = Arc::new(UnparsedValue { css: css.into_owned(), @@ -2152,7 +2149,10 @@ impl PropertyDeclaration { } Ok(()) } else { - Err(StyleParseErrorKind::new_invalid(name, err)) + Err(StyleParseErrorKind::new_invalid( + non_custom_id.unwrap().name(), + err, + )) } }) } diff --git a/components/style/stylesheets/keyframes_rule.rs b/components/style/stylesheets/keyframes_rule.rs index afe797c12ff..5f39267ac7b 100644 --- a/components/style/stylesheets/keyframes_rule.rs +++ b/components/style/stylesheets/keyframes_rule.rs @@ -623,12 +623,12 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeDeclarationParser<'a, 'b> { let id = match PropertyId::parse(&name, self.context) { Ok(id) => id, Err(()) => return Err(input.new_custom_error( - StyleParseErrorKind::UnknownProperty(name.clone()) + StyleParseErrorKind::UnknownProperty(name) )), }; // TODO(emilio): Shouldn't this use parse_entirely? - PropertyDeclaration::parse_into(self.declarations, id, name, self.context, input)?; + PropertyDeclaration::parse_into(self.declarations, id, self.context, input)?; // In case there is still unparsed text in the declaration, we should // roll back. diff --git a/components/style/stylesheets/supports_rule.rs b/components/style/stylesheets/supports_rule.rs index 5e2739d153d..f8c3235f295 100644 --- a/components/style/stylesheets/supports_rule.rs +++ b/components/style/stylesheets/supports_rule.rs @@ -316,20 +316,23 @@ impl Declaration { let mut input = ParserInput::new(&self.0); let mut input = Parser::new(&mut input); input.parse_entirely(|input| -> Result<(), CssParseError<()>> { - let prop = input.expect_ident_cloned().unwrap(); - input.expect_colon().unwrap(); + let prop = input.expect_ident_cloned().unwrap(); + input.expect_colon().unwrap(); - let id = PropertyId::parse(&prop, context) - .map_err(|_| input.new_custom_error(()))?; + let id = PropertyId::parse(&prop, context) + .map_err(|_| input.new_custom_error(()))?; - let mut declarations = SourcePropertyDeclaration::new(); - input.parse_until_before(Delimiter::Bang, |input| { - PropertyDeclaration::parse_into(&mut declarations, id, prop, &context, input) - .map_err(|_| input.new_custom_error(())) - })?; - let _ = input.try(parse_important); - Ok(()) - }) - .is_ok() + let mut declarations = SourcePropertyDeclaration::new(); + input.parse_until_before(Delimiter::Bang, |input| { + PropertyDeclaration::parse_into( + &mut declarations, + id, + &context, + input, + ).map_err(|_| input.new_custom_error(())) + })?; + let _ = input.try(parse_important); + Ok(()) + }).is_ok() } } diff --git a/components/style_traits/lib.rs b/components/style_traits/lib.rs index f232b157cf9..b1eaf4e086f 100644 --- a/components/style_traits/lib.rs +++ b/components/style_traits/lib.rs @@ -177,7 +177,11 @@ pub enum ValueParseErrorKind<'i> { impl<'i> StyleParseErrorKind<'i> { /// Create an InvalidValue parse error - pub fn new_invalid(name: CowRcStr<'i>, value_error: ParseError<'i>) -> ParseError<'i> { + pub fn new_invalid(name: S, value_error: ParseError<'i>) -> ParseError<'i> + where + S: Into>, + { + let name = name.into(); let variant = match value_error.kind { cssparser::ParseErrorKind::Custom(StyleParseErrorKind::ValueError(e)) => { match e { From 3816143a1d419ab89c7c7ab4cceb09e573e4aaf0 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 6 Jun 2018 11:34:30 -0400 Subject: [PATCH 23/40] style: Use Atomic for the staticpref version of layout.css.font-variations.enabled. Atomic is implemented in terms of AtomicBase, because that way you don't need to depend on atomic 1-byte operations. That means that the rust bindgen sees it as a u32, not a bool. It's a bit concerning that the rust code seems to be doing an unsynchronized read here, but given this is a RelaxedAtomic, that's probably ok. Bug: 1467134 Reviewed-by: emilio --- components/style/font_face.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/style/font_face.rs b/components/style/font_face.rs index 5a111925ae7..57c0f3b0b77 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -323,7 +323,7 @@ macro_rules! is_descriptor_enabled { ("font-variation-settings") => { unsafe { use gecko_bindings::structs::mozilla; - mozilla::StaticPrefs_sVarCache_layout_css_font_variations_enabled + mozilla::StaticPrefs_sVarCache_layout_css_font_variations_enabled != 0 } }; ($name:tt) => { From 255fe05d404a216fe6f2e9d0142d321c9eaf49c1 Mon Sep 17 00:00:00 2001 From: Dan Glastonbury Date: Wed, 23 May 2018 15:23:26 +1000 Subject: [PATCH 24/40] style: Extend StyleComplexColor to support additive blending. Refactored StyleComplexColor to support "complex" blending between background (numeric) color and foreground color (currentColor). Made explicit the distinction between numeric, currentColor and a complex blend in Gecko and Stylo. This is to support SMIL animation, for example, of the form: Bug: 1465307 Reviewed-by: hiro,xidorn MozReview-Commit-ID: IUAK8P07gtm --- .../sugar/style_complex_color.rs | 81 +++++--- components/style/values/animated/color.rs | 191 ++++++++++-------- components/style/values/computed/color.rs | 146 +++++++------ components/style/values/computed/mod.rs | 2 +- components/style/values/specified/color.rs | 32 ++- 5 files changed, 248 insertions(+), 204 deletions(-) diff --git a/components/style/gecko_bindings/sugar/style_complex_color.rs b/components/style/gecko_bindings/sugar/style_complex_color.rs index 696eb6968b6..3a37f9cb0fd 100644 --- a/components/style/gecko_bindings/sugar/style_complex_color.rs +++ b/components/style/gecko_bindings/sugar/style_complex_color.rs @@ -5,28 +5,21 @@ //! Rust helpers to interact with Gecko's StyleComplexColor. use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor}; -use gecko_bindings::structs::{nscolor, StyleComplexColor}; +use gecko_bindings::structs::StyleComplexColor; +use gecko_bindings::structs::StyleComplexColor_Tag as Tag; use values::{Auto, Either}; -use values::computed::Color as ComputedColor; +use values::computed::{Color as ComputedColor, RGBAColor as ComputedRGBA}; +use values::computed::ComplexColorRatios; use values::computed::ui::ColorOrAuto; -impl From for StyleComplexColor { - fn from(other: nscolor) -> Self { - StyleComplexColor { - mColor: other, - mForegroundRatio: 0, - mIsAuto: false, - } - } -} - impl StyleComplexColor { /// Create a `StyleComplexColor` value that represents `currentColor`. pub fn current_color() -> Self { StyleComplexColor { mColor: 0, - mForegroundRatio: 255, - mIsAuto: false, + mBgRatio: 0., + mFgRatio: 1., + mTag: Tag::eForeground, } } @@ -34,28 +27,66 @@ impl StyleComplexColor { pub fn auto() -> Self { StyleComplexColor { mColor: 0, - mForegroundRatio: 255, - mIsAuto: true, + mBgRatio: 0., + mFgRatio: 1., + mTag: Tag::eAuto, + } + } +} + +impl From for StyleComplexColor { + fn from(other: ComputedRGBA) -> Self { + StyleComplexColor { + mColor: convert_rgba_to_nscolor(&other), + mBgRatio: 1., + mFgRatio: 0., + mTag: Tag::eNumeric, } } } impl From for StyleComplexColor { fn from(other: ComputedColor) -> Self { - StyleComplexColor { - mColor: convert_rgba_to_nscolor(&other.color).into(), - mForegroundRatio: other.foreground_ratio, - mIsAuto: false, + match other { + ComputedColor::Numeric(color) => color.into(), + ComputedColor::Foreground => Self::current_color(), + ComputedColor::Complex(color, ratios) => { + debug_assert!(ratios != ComplexColorRatios::NUMERIC); + debug_assert!(ratios != ComplexColorRatios::FOREGROUND); + StyleComplexColor { + mColor: convert_rgba_to_nscolor(&color).into(), + mBgRatio: ratios.bg, + mFgRatio: ratios.fg, + mTag: Tag::eComplex, + } + } } } } impl From for ComputedColor { fn from(other: StyleComplexColor) -> Self { - debug_assert!(!other.mIsAuto); - ComputedColor { - color: convert_nscolor_to_rgba(other.mColor), - foreground_ratio: other.mForegroundRatio, + match other.mTag { + Tag::eNumeric => { + debug_assert!(other.mBgRatio == 1. && other.mFgRatio == 0.); + ComputedColor::Numeric(convert_nscolor_to_rgba(other.mColor)) + } + Tag::eForeground => { + debug_assert!(other.mBgRatio == 0. && other.mFgRatio == 1.); + ComputedColor::Foreground + } + Tag::eComplex => { + debug_assert!(other.mBgRatio != 1. || other.mFgRatio != 0.); + debug_assert!(other.mBgRatio != 0. || other.mFgRatio != 1.); + ComputedColor::Complex( + convert_nscolor_to_rgba(other.mColor), + ComplexColorRatios { + bg: other.mBgRatio, + fg: other.mFgRatio, + }, + ) + } + Tag::eAuto => unreachable!("Unsupport StyleComplexColor with tag eAuto"), } } } @@ -71,7 +102,7 @@ impl From for StyleComplexColor { impl From for ColorOrAuto { fn from(other: StyleComplexColor) -> Self { - if !other.mIsAuto { + if other.mTag != Tag::eAuto { Either::First(other.into()) } else { Either::Second(Auto) diff --git a/components/style/values/animated/color.rs b/components/style/values/animated/color.rs index 614c17df00c..98f3f425d22 100644 --- a/components/style/values/animated/color.rs +++ b/components/style/values/animated/color.rs @@ -6,6 +6,7 @@ use values::animated::{Animate, Procedure, ToAnimatedZero}; use values::distance::{ComputeSquaredDistance, SquaredDistance}; +use values::computed::ComplexColorRatios; /// An animated RGBA color. /// @@ -91,42 +92,51 @@ impl ComputeSquaredDistance for RGBA { } } +impl Animate for ComplexColorRatios { + #[inline] + fn animate(&self, other: &Self, procedure: Procedure) -> Result { + let bg = self.bg.animate(&other.bg, procedure)?; + let fg = self.fg.animate(&other.fg, procedure)?; + + Ok(ComplexColorRatios { bg, fg }) + } +} + #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(MallocSizeOf))] #[derive(Clone, Copy, Debug, PartialEq)] -pub struct Color { - pub color: RGBA, - pub foreground_ratio: f32, +pub enum Color { + Numeric(RGBA), + Foreground, + Complex(RGBA, ComplexColorRatios), } impl Color { fn currentcolor() -> Self { - Color { - color: RGBA::transparent(), - foreground_ratio: 1., - } + Color::Foreground } /// Returns a transparent intermediate color. pub fn transparent() -> Self { - Color { - color: RGBA::transparent(), - foreground_ratio: 0., - } - } - - fn is_currentcolor(&self) -> bool { - self.foreground_ratio >= 1. - } - - fn is_numeric(&self) -> bool { - self.foreground_ratio <= 0. + Color::Numeric(RGBA::transparent()) } fn effective_intermediate_rgba(&self) -> RGBA { - RGBA { - alpha: self.color.alpha * (1. - self.foreground_ratio), - ..self.color + match *self { + Color::Numeric(color) => color, + Color::Foreground => RGBA::transparent(), + Color::Complex(color, ratios) => RGBA { + alpha: color.alpha * ratios.bg, + ..color.clone() + }, + } + } + + fn effective_ratios(&self) -> ComplexColorRatios { + match *self { + Color::Numeric(..) => ComplexColorRatios::NUMERIC, + Color::Foreground => ComplexColorRatios::FOREGROUND, + Color::Complex(.., ratios) => ratios, } } } @@ -136,50 +146,66 @@ impl Animate for Color { fn animate(&self, other: &Self, procedure: Procedure) -> Result { // Common cases are interpolating between two numeric colors, // two currentcolors, and a numeric color and a currentcolor. - // - // Note: this algorithm assumes self_portion + other_portion - // equals to one, so it may be broken for additive operation. - // To properly support additive color interpolation, we would - // need two ratio fields in computed color types. let (this_weight, other_weight) = procedure.weights(); - if self.foreground_ratio == other.foreground_ratio { - if self.is_currentcolor() { - Ok(Color::currentcolor()) - } else { - Ok(Color { - color: self.color.animate(&other.color, procedure)?, - foreground_ratio: self.foreground_ratio, - }) + + Ok(match (*self, *other, procedure) { + // Any interpolation of currentColor with currentColor returns currentColor. + (Color::Foreground, Color::Foreground, Procedure::Interpolate { .. }) => { + Color::currentcolor() } - } else if self.is_currentcolor() && other.is_numeric() { - Ok(Color { - color: other.color, - foreground_ratio: this_weight as f32, - }) - } else if self.is_numeric() && other.is_currentcolor() { - Ok(Color { - color: self.color, - foreground_ratio: other_weight as f32, - }) - } else { - // 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 foreground ratio, and derive - // the final alpha value from the effective alpha value. - let foreground_ratio = self.foreground_ratio - .animate(&other.foreground_ratio, procedure)?; - let alpha = color.alpha / (1. - foreground_ratio); - Ok(Color { - color: RGBA { - alpha: alpha, - ..color + // Animating two numeric colors. + (Color::Numeric(c1), Color::Numeric(c2), _) => { + Color::Numeric(c1.animate(&c2, procedure)?) + } + // Combinations of numeric color and currentColor + (Color::Foreground, Color::Numeric(color), _) => Color::Complex( + color, + ComplexColorRatios { + bg: other_weight as f32, + fg: this_weight as f32, }, - foreground_ratio: foreground_ratio, - }) - } + ), + (Color::Numeric(color), Color::Foreground, _) => Color::Complex( + color, + ComplexColorRatios { + bg: this_weight as f32, + fg: other_weight as f32, + }, + ), + + // Any other animation of currentColor with currentColor is complex. + (Color::Foreground, Color::Foreground, _) => Color::Complex( + RGBA::transparent(), + ComplexColorRatios { + bg: 0., + fg: (this_weight + other_weight) as f32, + }, + ), + + // 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 }; + + if ratios == ComplexColorRatios::NUMERIC { + Color::Numeric(color) + } else if ratios == ComplexColorRatios::FOREGROUND { + Color::Foreground + } else { + Color::Complex(color, ratios) + } + } + }) } } @@ -187,27 +213,26 @@ impl ComputeSquaredDistance for Color { #[inline] fn compute_squared_distance(&self, other: &Self) -> Result { // All comments from the Animate impl also applies here. - if self.foreground_ratio == other.foreground_ratio { - if self.is_currentcolor() { - Ok(SquaredDistance::from_sqrt(0.)) - } else { - self.color.compute_squared_distance(&other.color) + Ok(match (*self, *other) { + (Color::Foreground, Color::Foreground) => SquaredDistance::from_sqrt(0.), + (Color::Numeric(c1), Color::Numeric(c2)) => c1.compute_squared_distance(&c2)?, + (Color::Foreground, Color::Numeric(color)) + | (Color::Numeric(color), Color::Foreground) => { + // `computed_squared_distance` is symmetic. + color.compute_squared_distance(&RGBA::transparent())? + + SquaredDistance::from_sqrt(1.) } - } else if self.is_currentcolor() && other.is_numeric() { - Ok( - RGBA::transparent().compute_squared_distance(&other.color)? + - SquaredDistance::from_sqrt(1.), - ) - } else if self.is_numeric() && other.is_currentcolor() { - Ok(self.color.compute_squared_distance(&RGBA::transparent())? + - SquaredDistance::from_sqrt(1.)) - } else { - let self_color = self.effective_intermediate_rgba(); - let other_color = other.effective_intermediate_rgba(); - Ok(self_color.compute_squared_distance(&other_color)? + - self.foreground_ratio - .compute_squared_distance(&other.foreground_ratio)?) - } + (_, _) => { + let self_color = self.effective_intermediate_rgba(); + let other_color = other.effective_intermediate_rgba(); + let self_ratios = self.effective_ratios(); + let other_ratios = other.effective_ratios(); + + self_color.compute_squared_distance(&other_color)? + + self_ratios.bg.compute_squared_distance(&other_ratios.bg)? + + self_ratios.fg.compute_squared_distance(&other_ratios.fg)? + } + }) } } diff --git a/components/style/values/computed/color.rs b/components/style/values/computed/color.rs index d37aef00b9d..d5fff086759 100644 --- a/components/style/values/computed/color.rs +++ b/components/style/values/computed/color.rs @@ -10,17 +10,36 @@ use style_traits::{CssWriter, ToCss}; use values::animated::ToAnimatedValue; use values::animated::color::{Color as AnimatedColor, RGBA as AnimatedRGBA}; -/// This struct represents a combined color from a numeric color and -/// the current foreground color (currentcolor keyword). -/// Conceptually, the formula is "color * (1 - p) + currentcolor * p" -/// where p is foreground_ratio. -#[derive(Clone, Copy, Debug, MallocSizeOf)] -pub struct Color { - /// RGBA color. - pub color: RGBA, +/// Ratios representing the contribution of color and currentcolor to +/// the final color value. +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] +pub struct ComplexColorRatios { + /// Numeric color contribution. + pub bg: f32, + /// Foreground color, aka currentcolor, contribution. + pub fg: f32, +} - /// The ratio of currentcolor in complex color. - pub foreground_ratio: u8, +impl ComplexColorRatios { + /// Ratios representing pure numeric color. + pub const NUMERIC: ComplexColorRatios = ComplexColorRatios { bg: 1., fg: 0. }; + /// Ratios representing pure foreground color. + pub const FOREGROUND: ComplexColorRatios = ComplexColorRatios { bg: 0., fg: 1. }; +} + +/// This enum represents a combined color from a numeric color and +/// the current foreground color (currentColor keyword). +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] +pub enum Color { + /// Numeric RGBA color. + Numeric(RGBA), + + /// The current foreground color. + Foreground, + + /// A linear combination of numeric color and currentColor. + /// The formula is: `color * bg_ratio + currentColor * fg_ratio`. + Complex(RGBA, ComplexColorRatios), } /// Computed value type for the specified RGBAColor. @@ -31,11 +50,8 @@ pub type ColorPropertyValue = RGBA; impl Color { /// Returns a numeric color representing the given RGBA value. - pub fn rgba(rgba: RGBA) -> Color { - Color { - color: rgba, - foreground_ratio: 0, - } + pub fn rgba(color: RGBA) -> Color { + Color::Numeric(color) } /// Returns a complex color value representing transparent. @@ -45,73 +61,53 @@ impl Color { /// Returns a complex color value representing currentcolor. pub fn currentcolor() -> Color { - Color { - color: RGBA::transparent(), - foreground_ratio: u8::max_value(), - } + Color::Foreground } /// Whether it is a numeric color (no currentcolor component). pub fn is_numeric(&self) -> bool { - self.foreground_ratio == 0 + matches!(*self, Color::Numeric { .. }) } /// Whether it is a currentcolor value (no numeric color component). pub fn is_currentcolor(&self) -> bool { - self.foreground_ratio == u8::max_value() + matches!(*self, Color::Foreground) } /// Combine this complex color with the given foreground color into /// a numeric RGBA color. It currently uses linear blending. pub fn to_rgba(&self, fg_color: RGBA) -> RGBA { - // Common cases that the complex color is either pure numeric - // color or pure currentcolor. - if self.is_numeric() { - return self.color; - } - if self.is_currentcolor() { - return fg_color.clone(); - } - - fn blend_color_component(bg: u8, fg: u8, fg_alpha: u8) -> u8 { - let bg_ratio = (u8::max_value() - fg_alpha) as u32; - let fg_ratio = fg_alpha as u32; - let color = bg as u32 * bg_ratio + fg as u32 * fg_ratio; - // Rounding divide the number by 255 - ((color + 127) / 255) as u8 - } - - // Common case that alpha channel is equal (usually both are opaque). - let fg_ratio = self.foreground_ratio; - if self.color.alpha == fg_color.alpha { - let r = blend_color_component(self.color.red, fg_color.red, fg_ratio); - let g = blend_color_component(self.color.green, fg_color.green, fg_ratio); - let b = blend_color_component(self.color.blue, fg_color.blue, fg_ratio); - return RGBA::new(r, g, b, fg_color.alpha); - } + let (color, ratios) = match *self { + // Common cases that the complex color is either pure numeric + // color or pure currentcolor. + Color::Numeric(color) => return color, + Color::Foreground => return fg_color, + Color::Complex(color, ratios) => (color, ratios), + }; // For the more complicated case that the alpha value differs, // we use the following formula to compute the components: - // alpha = self_alpha * (1 - fg_ratio) + fg_alpha * fg_ratio - // color = (self_color * self_alpha * (1 - fg_ratio) + + // alpha = self_alpha * bg_ratio + fg_alpha * fg_ratio + // color = (self_color * self_alpha * bg_ratio + // fg_color * fg_alpha * fg_ratio) / alpha - let p1 = (1. / 255.) * (255 - fg_ratio) as f32; - let a1 = self.color.alpha_f32(); - let r1 = a1 * self.color.red_f32(); - let g1 = a1 * self.color.green_f32(); - let b1 = a1 * self.color.blue_f32(); + let p1 = ratios.bg; + let a1 = color.alpha_f32(); + let r1 = a1 * color.red_f32(); + let g1 = a1 * color.green_f32(); + let b1 = a1 * color.blue_f32(); - let p2 = 1. - p1; + let p2 = ratios.fg; let a2 = fg_color.alpha_f32(); let r2 = a2 * fg_color.red_f32(); let g2 = a2 * fg_color.green_f32(); let b2 = a2 * fg_color.blue_f32(); let a = p1 * a1 + p2 * a2; - if a == 0.0 { + if a <= 0. { return RGBA::transparent(); } + let a = f32::min(a, 1.); let inverse_a = 1. / a; let r = (p1 * r1 + p2 * r2) * inverse_a; @@ -121,19 +117,9 @@ impl Color { } } -impl PartialEq for Color { - fn eq(&self, other: &Color) -> bool { - self.foreground_ratio == other.foreground_ratio && - (self.is_currentcolor() || self.color == other.color) - } -} - impl From for Color { fn from(color: RGBA) -> Color { - Color { - color: color, - foreground_ratio: 0, - } + Color::Numeric(color) } } @@ -142,12 +128,10 @@ impl ToCss for Color { where W: fmt::Write, { - if self.is_numeric() { - self.color.to_css(dest) - } else if self.is_currentcolor() { - CSSParserColor::CurrentColor.to_css(dest) - } else { - Ok(()) + match *self { + Color::Numeric(color) => color.to_css(dest), + Color::Foreground => CSSParserColor::CurrentColor.to_css(dest), + _ => Ok(()), } } } @@ -157,17 +141,23 @@ impl ToAnimatedValue for Color { #[inline] fn to_animated_value(self) -> Self::AnimatedValue { - AnimatedColor { - color: self.color.to_animated_value(), - foreground_ratio: self.foreground_ratio as f32 * (1. / 255.), + match self { + Color::Numeric(color) => AnimatedColor::Numeric(color.to_animated_value()), + Color::Foreground => AnimatedColor::Foreground, + Color::Complex(color, ratios) => { + AnimatedColor::Complex(color.to_animated_value(), ratios) + } } } #[inline] fn from_animated_value(animated: Self::AnimatedValue) -> Self { - Color { - color: RGBA::from_animated_value(animated.color), - foreground_ratio: (animated.foreground_ratio * 255.).round() as u8, + match animated { + AnimatedColor::Numeric(color) => Color::Numeric(RGBA::from_animated_value(color)), + AnimatedColor::Foreground => Color::Foreground, + AnimatedColor::Complex(color, ratios) => { + Color::Complex(RGBA::from_animated_value(color), ratios) + } } } } diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index e742c4e49f1..fc1d617a02e 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -45,7 +45,7 @@ pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display, TransitionProperty}; pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective}; pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange}; -pub use self::color::{Color, ColorPropertyValue, RGBAColor}; +pub use self::color::{Color, ColorPropertyValue, ComplexColorRatios, RGBAColor}; pub use self::column::ColumnCount; pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset}; pub use self::effects::{BoxShadow, Filter, SimpleShadow}; diff --git a/components/style/values/specified/color.rs b/components/style/values/specified/color.rs index 3066c5b8c2a..0670e8126ec 100644 --- a/components/style/values/specified/color.rs +++ b/components/style/values/specified/color.rs @@ -88,11 +88,11 @@ impl<'a, 'b: 'a, 'i: 'a> ::cssparser::ColorComponentParser<'i> for ColorComponen }; Ok(AngleOrNumber::Angle { degrees }) - }, + } Token::Number { value, .. } => Ok(AngleOrNumber::Number { value }), Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { input.parse_nested_block(|i| CalcNode::parse_angle_or_number(self.0, i)) - }, + } t => return Err(location.new_unexpected_token_error(t)), } } @@ -119,10 +119,10 @@ impl<'a, 'b: 'a, 'i: 'a> ::cssparser::ColorComponentParser<'i> for ColorComponen Token::Number { value, .. } => Ok(NumberOrPercentage::Number { value }), Token::Percentage { unit_value, .. } => { Ok(NumberOrPercentage::Percentage { unit_value }) - }, + } Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { input.parse_nested_block(|i| CalcNode::parse_number_or_percentage(self.0, i)) - }, + } t => return Err(location.new_unexpected_token_error(t)), } } @@ -168,10 +168,10 @@ impl Parse for Color { Err(e.location.new_custom_error(StyleParseErrorKind::ValueError( ValueParseErrorKind::InvalidColor(t), ))) - }, + } _ => Err(e), } - }, + } } } } @@ -275,10 +275,10 @@ impl Color { } return parse_hash_color(ident.as_bytes()) .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); - }, + } ref t => { return Err(location.new_unexpected_token_error(t.clone())); - }, + } }; if value < 0 { return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); @@ -358,11 +358,11 @@ impl Color { Keyword::MozVisitedhyperlinktext => pres_context.mVisitedLinkColor, }) }) - }, + } #[cfg(feature = "gecko")] Color::InheritFromBodyQuirk => { _context.map(|context| ComputedColor::rgba(context.device().body_text_color())) - }, + } } } } @@ -372,7 +372,7 @@ impl ToComputedValue for Color { fn to_computed_value(&self, context: &Context) -> ComputedColor { let result = self.to_computed_color(Some(context)).unwrap(); - if result.foreground_ratio != 0 { + if !result.is_numeric() { if let Some(longhand) = context.for_non_inherited_property { if longhand.stores_complex_colors_lossily() { context.rule_cache_conditions.borrow_mut().set_uncacheable(); @@ -383,12 +383,10 @@ impl ToComputedValue for Color { } fn from_computed_value(computed: &ComputedColor) -> Self { - if computed.is_numeric() { - Color::rgba(computed.color) - } else if computed.is_currentcolor() { - Color::currentcolor() - } else { - Color::Complex(*computed) + match *computed { + ComputedColor::Numeric(color) => Color::rgba(color), + ComputedColor::Foreground => Color::currentcolor(), + ComputedColor::Complex(..) => Color::Complex(*computed), } } } From 9c51d31b055b79e22a13303bcb2dc18b5db351d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Jun 2018 21:58:14 +0200 Subject: [PATCH 25/40] style: Inline some trivial bits. Bug: 1466963 Reviewed-by: xidorn MozReview-Commit-ID: A219QehiMqZ --- components/style/gecko_bindings/sugar/ns_compatibility.rs | 1 + components/style/properties/properties.mako.rs | 3 +++ 2 files changed, 4 insertions(+) diff --git a/components/style/gecko_bindings/sugar/ns_compatibility.rs b/components/style/gecko_bindings/sugar/ns_compatibility.rs index 3fe63391d36..eaf97ca6f31 100644 --- a/components/style/gecko_bindings/sugar/ns_compatibility.rs +++ b/components/style/gecko_bindings/sugar/ns_compatibility.rs @@ -8,6 +8,7 @@ use context::QuirksMode; use gecko_bindings::structs::nsCompatibility; impl From for QuirksMode { + #[inline] fn from(mode: nsCompatibility) -> QuirksMode { match mode { nsCompatibility::eCompatibility_FullStandards => QuirksMode::NoQuirks, diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 5133cd6ae2d..4e52412c18d 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -593,18 +593,21 @@ impl NonCustomPropertyId { } impl From for NonCustomPropertyId { + #[inline] fn from(id: LonghandId) -> Self { NonCustomPropertyId(id as usize) } } impl From for NonCustomPropertyId { + #[inline] fn from(id: ShorthandId) -> Self { NonCustomPropertyId((id as usize) + ${len(data.longhands)}) } } impl From for NonCustomPropertyId { + #[inline] fn from(id: AliasId) -> Self { NonCustomPropertyId(id as usize + ${len(data.longhands) + len(data.shorthands)}) } From e0526661538f89e50ecbdd5c04f991e1c055f3e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 5 Jun 2018 20:11:04 +0200 Subject: [PATCH 26/40] style: Fix a typo. Nobody looks at the result from parsing, but this is the right thing to return. Bug: 1466963 Reviewed-by: xidorn MozReview-Commit-ID: 9P5VARiPIAk --- components/style/properties/declaration_block.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index 3cdbf61de66..e192d08b22d 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -492,9 +492,9 @@ impl PropertyDeclarationBlock { /// 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 and - /// will preserve the original position on the block. + /// * For `DeclarationSource::CssOm`, this will override importance. /// + /// Returns whether the declaration has changed. pub fn push( &mut self, declaration: PropertyDeclaration, @@ -522,7 +522,7 @@ impl PropertyDeclarationBlock { // shouldn't override existing important one. if important && !importance.important() && matches!(source, DeclarationSource::Parsing) { - return true; + return false; } if matches!(source, DeclarationSource::Parsing) { From 6ca324f8b591f9f811acb600faabb3567ddb6125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 5 Jun 2018 21:13:04 +0200 Subject: [PATCH 27/40] style: Remove unused PropertyDeclarationBlock::set_importance. Bug: 1466963 Reviewed-by: xidorn MozReview-Commit-ID: 1YrlOvktag9 --- .../style/properties/declaration_block.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index e192d08b22d..c88458d0fd9 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -564,23 +564,6 @@ impl PropertyDeclarationBlock { true } - /// Set the declaration importance for a given property, if found. - /// - /// Returns whether any declaration was updated. - pub fn set_importance(&mut self, property: &PropertyId, new_importance: Importance) -> bool { - let mut updated_at_least_one = false; - for (i, declaration) in self.declarations.iter().enumerate() { - if declaration.id().is_or_is_longhand_of(property) { - let is_important = new_importance.important(); - if self.declarations_importance[i] != is_important { - self.declarations_importance.set(i, is_important); - updated_at_least_one = true; - } - } - } - updated_at_least_one - } - /// /// /// Returns whether any declaration was actually removed. From 3c7fb2a217ed9af0fff8e204f36b1a0be563049c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 5 Jun 2018 21:13:48 +0200 Subject: [PATCH 28/40] style: Add a before-change callback to remove_property. Bug: 1466963 Reviewed-by: xidorn MozReview-Commit-ID: 4vyN9iLT7e3 --- .../style/properties/declaration_block.rs | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index c88458d0fd9..e9d7f8cfd62 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -567,7 +567,14 @@ impl PropertyDeclarationBlock { /// /// /// Returns whether any declaration was actually removed. - pub fn remove_property(&mut self, property: &PropertyId) -> bool { + pub fn remove_property( + &mut self, + property: &PropertyId, + mut before_change_callback: C, + ) -> bool + where + C: FnMut(&Self), + { let longhand_id = property.longhand_id(); if let Some(id) = longhand_id { if !self.longhands.contains(id) { @@ -575,23 +582,28 @@ impl PropertyDeclarationBlock { } } let mut removed_at_least_one = false; - let longhands = &mut self.longhands; - let declarations_importance = &mut self.declarations_importance; let mut i = 0; - self.declarations.retain(|declaration| { - let id = declaration.id(); - let remove = id.is_or_is_longhand_of(property); - if remove { + let mut len = self.len(); + while i < len { + { + let id = self.declarations[i].id(); + if !id.is_or_is_longhand_of(property) { + i += 1; + continue; + } + + if !removed_at_least_one { + before_change_callback(&*self); + } removed_at_least_one = true; if let PropertyDeclarationId::Longhand(id) = id { - longhands.remove(id); + self.longhands.remove(id); } - declarations_importance.remove(i); - } else { - i += 1; + self.declarations_importance.remove(i); } - !remove - }); + self.declarations.remove(i); + len -= 1; + } if longhand_id.is_some() { debug_assert!(removed_at_least_one); From cdbc4097598d3f918caa97c36339380217ec750b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 5 Jun 2018 21:17:08 +0200 Subject: [PATCH 29/40] style: Trivially simplify a condition. Bug: 1466963 Reviewed-by: xidorn MozReview-Commit-ID: L9LzpPt4js4 --- components/style/properties/declaration_block.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index e9d7f8cfd62..4e368c0c2b7 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -517,15 +517,15 @@ impl PropertyDeclarationBlock { continue; } - let important = self.declarations_importance[i]; - // For declarations from parsing, non-important declarations - // shouldn't override existing important one. - if important && !importance.important() && - matches!(source, DeclarationSource::Parsing) { - return false; - } - if matches!(source, DeclarationSource::Parsing) { + let important = self.declarations_importance[i]; + + // For declarations from parsing, non-important declarations + // shouldn't override existing important one. + if important && !importance.important() { + return false; + } + // As a compatibility hack, specially on Android, // don't allow to override a prefixed webkit display // value with an unprefixed version from parsing From 314b14d46ec58ce72d7f28357a847d496510d135 Mon Sep 17 00:00:00 2001 From: Dan Glastonbury Date: Tue, 5 Jun 2018 11:24:12 +1000 Subject: [PATCH 30/40] style: Fix nsStyleBorder::mBorderColor for GCC. GCC doesn't like StyleComplexColor with constructor in an anonymous struct in an anonymous union. Replace the use of a union to access `mBorder[..]Color` fields as an array with an accessor methods. Bug: 1465307 Reviewed-by: xidorn MozReview-Commit-ID: 1Wulh1qKYCZ --- components/style/properties/gecko.mako.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 13d93b0a144..f83e0836c91 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -388,17 +388,9 @@ impl ${style_struct.gecko_struct_name} { <%! def get_gecko_property(ffi_name, self_param = "self"): - if "mBorderColor" in ffi_name: - return ffi_name.replace("mBorderColor", - "unsafe { *%s.gecko.__bindgen_anon_1.mBorderColor.as_ref() }" - % self_param) return "%s.gecko.%s" % (self_param, ffi_name) def set_gecko_property(ffi_name, expr): - if "mBorderColor" in ffi_name: - ffi_name = ffi_name.replace("mBorderColor", - "*self.gecko.__bindgen_anon_1.mBorderColor.as_mut()") - return "unsafe { %s = %s };" % (ffi_name, expr) return "self.gecko.%s = %s;" % (ffi_name, expr) %> @@ -1594,7 +1586,7 @@ fn static_assert() { self.gecko.mComputedBorder.${side.ident} = self.gecko.mBorder.${side.ident}; } - <% impl_color("border_%s_color" % side.ident, "(mBorderColor)[%s]" % side.index) %> + <% impl_color("border_%s_color" % side.ident, "mBorder%sColor" % side.name) %> <% impl_non_negative_length("border_%s_width" % side.ident, "mComputedBorder.%s" % side.ident, From 5f74a15f385b4777549513a4d59bf01803ef2470 Mon Sep 17 00:00:00 2001 From: Dan Glastonbury Date: Tue, 5 Jun 2018 11:49:51 +1000 Subject: [PATCH 31/40] style: Extract {animated,computed}::Color common parts. Extract the common parts of `animated::Color` and `computed::Color` out into `generics::color::Color` that is generic over the type of RGBA color. Bug: 1465307 Reviewed-by: xidorn MozReview-Commit-ID: EymSr7aqnAP --- .../sugar/style_complex_color.rs | 14 +-- components/style/values/animated/color.rs | 68 ++++-------- components/style/values/computed/color.rs | 100 ++---------------- components/style/values/computed/mod.rs | 2 +- components/style/values/generics/color.rs | 76 +++++++++++++ components/style/values/generics/mod.rs | 1 + components/style/values/specified/color.rs | 7 +- 7 files changed, 122 insertions(+), 146 deletions(-) create mode 100644 components/style/values/generics/color.rs diff --git a/components/style/gecko_bindings/sugar/style_complex_color.rs b/components/style/gecko_bindings/sugar/style_complex_color.rs index 3a37f9cb0fd..90e93b72fd0 100644 --- a/components/style/gecko_bindings/sugar/style_complex_color.rs +++ b/components/style/gecko_bindings/sugar/style_complex_color.rs @@ -9,8 +9,8 @@ use gecko_bindings::structs::StyleComplexColor; use gecko_bindings::structs::StyleComplexColor_Tag as Tag; use values::{Auto, Either}; use values::computed::{Color as ComputedColor, RGBAColor as ComputedRGBA}; -use values::computed::ComplexColorRatios; use values::computed::ui::ColorOrAuto; +use values::generics::color::{Color as GenericColor, ComplexColorRatios}; impl StyleComplexColor { /// Create a `StyleComplexColor` value that represents `currentColor`. @@ -48,9 +48,9 @@ impl From for StyleComplexColor { impl From for StyleComplexColor { fn from(other: ComputedColor) -> Self { match other { - ComputedColor::Numeric(color) => color.into(), - ComputedColor::Foreground => Self::current_color(), - ComputedColor::Complex(color, ratios) => { + GenericColor::Numeric(color) => color.into(), + GenericColor::Foreground => Self::current_color(), + GenericColor::Complex(color, ratios) => { debug_assert!(ratios != ComplexColorRatios::NUMERIC); debug_assert!(ratios != ComplexColorRatios::FOREGROUND); StyleComplexColor { @@ -69,16 +69,16 @@ impl From for ComputedColor { match other.mTag { Tag::eNumeric => { debug_assert!(other.mBgRatio == 1. && other.mFgRatio == 0.); - ComputedColor::Numeric(convert_nscolor_to_rgba(other.mColor)) + GenericColor::Numeric(convert_nscolor_to_rgba(other.mColor)) } Tag::eForeground => { debug_assert!(other.mBgRatio == 0. && other.mFgRatio == 1.); - ComputedColor::Foreground + GenericColor::Foreground } Tag::eComplex => { debug_assert!(other.mBgRatio != 1. || other.mFgRatio != 0.); debug_assert!(other.mBgRatio != 0. || other.mFgRatio != 1.); - ComputedColor::Complex( + GenericColor::Complex( convert_nscolor_to_rgba(other.mColor), ComplexColorRatios { bg: other.mBgRatio, diff --git a/components/style/values/animated/color.rs b/components/style/values/animated/color.rs index 98f3f425d22..6a82896d62b 100644 --- a/components/style/values/animated/color.rs +++ b/components/style/values/animated/color.rs @@ -6,7 +6,7 @@ use values::animated::{Animate, Procedure, ToAnimatedZero}; use values::distance::{ComputeSquaredDistance, SquaredDistance}; -use values::computed::ComplexColorRatios; +use values::generics::color::{Color as GenericColor, ComplexColorRatios}; /// An animated RGBA color. /// @@ -102,30 +102,15 @@ impl Animate for ComplexColorRatios { } } -#[allow(missing_docs)] -#[cfg_attr(feature = "servo", derive(MallocSizeOf))] -#[derive(Clone, Copy, Debug, PartialEq)] -pub enum Color { - Numeric(RGBA), - Foreground, - Complex(RGBA, ComplexColorRatios), -} +/// An animated value for ``. +pub type Color = GenericColor; impl Color { - fn currentcolor() -> Self { - Color::Foreground - } - - /// Returns a transparent intermediate color. - pub fn transparent() -> Self { - Color::Numeric(RGBA::transparent()) - } - fn effective_intermediate_rgba(&self) -> RGBA { match *self { - Color::Numeric(color) => color, - Color::Foreground => RGBA::transparent(), - Color::Complex(color, ratios) => RGBA { + GenericColor::Numeric(color) => color, + GenericColor::Foreground => RGBA::transparent(), + GenericColor::Complex(color, ratios) => RGBA { alpha: color.alpha * ratios.bg, ..color.clone() }, @@ -134,9 +119,9 @@ impl Color { fn effective_ratios(&self) -> ComplexColorRatios { match *self { - Color::Numeric(..) => ComplexColorRatios::NUMERIC, - Color::Foreground => ComplexColorRatios::FOREGROUND, - Color::Complex(.., ratios) => ratios, + GenericColor::Numeric(..) => ComplexColorRatios::NUMERIC, + GenericColor::Foreground => ComplexColorRatios::FOREGROUND, + GenericColor::Complex(.., ratios) => ratios, } } } @@ -144,28 +129,26 @@ impl Color { impl Animate for Color { #[inline] fn animate(&self, other: &Self, procedure: Procedure) -> Result { + use self::GenericColor::*; + // Common cases are interpolating between two numeric colors, // two currentcolors, and a numeric color and a currentcolor. let (this_weight, other_weight) = procedure.weights(); Ok(match (*self, *other, procedure) { // Any interpolation of currentColor with currentColor returns currentColor. - (Color::Foreground, Color::Foreground, Procedure::Interpolate { .. }) => { - Color::currentcolor() - } + (Foreground, Foreground, Procedure::Interpolate { .. }) => Color::currentcolor(), // Animating two numeric colors. - (Color::Numeric(c1), Color::Numeric(c2), _) => { - Color::Numeric(c1.animate(&c2, procedure)?) - } + (Numeric(c1), Numeric(c2), _) => Numeric(c1.animate(&c2, procedure)?), // Combinations of numeric color and currentColor - (Color::Foreground, Color::Numeric(color), _) => Color::Complex( + (Foreground, Numeric(color), _) => Self::with_ratios( color, ComplexColorRatios { bg: other_weight as f32, fg: this_weight as f32, }, ), - (Color::Numeric(color), Color::Foreground, _) => Color::Complex( + (Numeric(color), Foreground, _) => Self::with_ratios( color, ComplexColorRatios { bg: this_weight as f32, @@ -173,8 +156,8 @@ impl Animate for Color { }, ), - // Any other animation of currentColor with currentColor is complex. - (Color::Foreground, Color::Foreground, _) => Color::Complex( + // Any other animation of currentColor with currentColor. + (Foreground, Foreground, _) => Self::with_ratios( RGBA::transparent(), ComplexColorRatios { bg: 0., @@ -197,13 +180,7 @@ impl Animate for Color { let alpha = color.alpha / ratios.bg; let color = RGBA { alpha, ..color }; - if ratios == ComplexColorRatios::NUMERIC { - Color::Numeric(color) - } else if ratios == ComplexColorRatios::FOREGROUND { - Color::Foreground - } else { - Color::Complex(color, ratios) - } + Self::with_ratios(color, ratios) } }) } @@ -212,12 +189,13 @@ impl Animate for Color { impl ComputeSquaredDistance for Color { #[inline] fn compute_squared_distance(&self, other: &Self) -> Result { + use self::GenericColor::*; + // All comments from the Animate impl also applies here. Ok(match (*self, *other) { - (Color::Foreground, Color::Foreground) => SquaredDistance::from_sqrt(0.), - (Color::Numeric(c1), Color::Numeric(c2)) => c1.compute_squared_distance(&c2)?, - (Color::Foreground, Color::Numeric(color)) - | (Color::Numeric(color), Color::Foreground) => { + (Foreground, Foreground) => SquaredDistance::from_sqrt(0.), + (Numeric(c1), Numeric(c2)) => c1.compute_squared_distance(&c2)?, + (Foreground, Numeric(color)) | (Numeric(color), Foreground) => { // `computed_squared_distance` is symmetic. color.compute_squared_distance(&RGBA::transparent())? + SquaredDistance::from_sqrt(1.) diff --git a/components/style/values/computed/color.rs b/components/style/values/computed/color.rs index d5fff086759..5effffe5966 100644 --- a/components/style/values/computed/color.rs +++ b/components/style/values/computed/color.rs @@ -8,39 +8,8 @@ use cssparser::{Color as CSSParserColor, RGBA}; use std::fmt; use style_traits::{CssWriter, ToCss}; use values::animated::ToAnimatedValue; -use values::animated::color::{Color as AnimatedColor, RGBA as AnimatedRGBA}; - -/// Ratios representing the contribution of color and currentcolor to -/// the final color value. -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] -pub struct ComplexColorRatios { - /// Numeric color contribution. - pub bg: f32, - /// Foreground color, aka currentcolor, contribution. - pub fg: f32, -} - -impl ComplexColorRatios { - /// Ratios representing pure numeric color. - pub const NUMERIC: ComplexColorRatios = ComplexColorRatios { bg: 1., fg: 0. }; - /// Ratios representing pure foreground color. - pub const FOREGROUND: ComplexColorRatios = ComplexColorRatios { bg: 0., fg: 1. }; -} - -/// This enum represents a combined color from a numeric color and -/// the current foreground color (currentColor keyword). -#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] -pub enum Color { - /// Numeric RGBA color. - Numeric(RGBA), - - /// The current foreground color. - Foreground, - - /// A linear combination of numeric color and currentColor. - /// The formula is: `color * bg_ratio + currentColor * fg_ratio`. - Complex(RGBA, ComplexColorRatios), -} +use values::animated::color::RGBA as AnimatedRGBA; +use values::generics::color::Color as GenericColor; /// Computed value type for the specified RGBAColor. pub type RGBAColor = RGBA; @@ -48,41 +17,24 @@ pub type RGBAColor = RGBA; /// The computed value of the `color` property. pub type ColorPropertyValue = RGBA; -impl Color { - /// Returns a numeric color representing the given RGBA value. - pub fn rgba(color: RGBA) -> Color { - Color::Numeric(color) - } +/// A computed value for ``. +pub type Color = GenericColor; +impl Color { /// Returns a complex color value representing transparent. pub fn transparent() -> Color { Color::rgba(RGBA::transparent()) } - /// Returns a complex color value representing currentcolor. - pub fn currentcolor() -> Color { - Color::Foreground - } - - /// Whether it is a numeric color (no currentcolor component). - pub fn is_numeric(&self) -> bool { - matches!(*self, Color::Numeric { .. }) - } - - /// Whether it is a currentcolor value (no numeric color component). - pub fn is_currentcolor(&self) -> bool { - matches!(*self, Color::Foreground) - } - /// Combine this complex color with the given foreground color into /// a numeric RGBA color. It currently uses linear blending. pub fn to_rgba(&self, fg_color: RGBA) -> RGBA { let (color, ratios) = match *self { // Common cases that the complex color is either pure numeric // color or pure currentcolor. - Color::Numeric(color) => return color, - Color::Foreground => return fg_color, - Color::Complex(color, ratios) => (color, ratios), + GenericColor::Numeric(color) => return color, + GenericColor::Foreground => return fg_color, + GenericColor::Complex(color, ratios) => (color, ratios), }; // For the more complicated case that the alpha value differs, @@ -117,51 +69,19 @@ impl Color { } } -impl From for Color { - fn from(color: RGBA) -> Color { - Color::Numeric(color) - } -} - impl ToCss for Color { fn to_css(&self, dest: &mut CssWriter) -> fmt::Result where W: fmt::Write, { match *self { - Color::Numeric(color) => color.to_css(dest), - Color::Foreground => CSSParserColor::CurrentColor.to_css(dest), + GenericColor::Numeric(color) => color.to_css(dest), + GenericColor::Foreground => CSSParserColor::CurrentColor.to_css(dest), _ => Ok(()), } } } -impl ToAnimatedValue for Color { - type AnimatedValue = AnimatedColor; - - #[inline] - fn to_animated_value(self) -> Self::AnimatedValue { - match self { - Color::Numeric(color) => AnimatedColor::Numeric(color.to_animated_value()), - Color::Foreground => AnimatedColor::Foreground, - Color::Complex(color, ratios) => { - AnimatedColor::Complex(color.to_animated_value(), ratios) - } - } - } - - #[inline] - fn from_animated_value(animated: Self::AnimatedValue) -> Self { - match animated { - AnimatedColor::Numeric(color) => Color::Numeric(RGBA::from_animated_value(color)), - AnimatedColor::Foreground => Color::Foreground, - AnimatedColor::Complex(color, ratios) => { - Color::Complex(RGBA::from_animated_value(color), ratios) - } - } - } -} - impl ToAnimatedValue for RGBA { type AnimatedValue = AnimatedRGBA; diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index fc1d617a02e..e742c4e49f1 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -45,7 +45,7 @@ pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display, TransitionProperty}; pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective}; pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange}; -pub use self::color::{Color, ColorPropertyValue, ComplexColorRatios, RGBAColor}; +pub use self::color::{Color, ColorPropertyValue, RGBAColor}; pub use self::column::ColumnCount; pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset}; pub use self::effects::{BoxShadow, Filter, SimpleShadow}; diff --git a/components/style/values/generics/color.rs b/components/style/values/generics/color.rs new file mode 100644 index 00000000000..693803ad5fd --- /dev/null +++ b/components/style/values/generics/color.rs @@ -0,0 +1,76 @@ +/* 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/. */ + +//! Generic types for color properties. + +/// Ratios representing the contribution of color and currentcolor to +/// the final color value. +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue)] +pub struct ComplexColorRatios { + /// Numeric color contribution. + pub bg: f32, + /// Foreground color, aka currentcolor, contribution. + pub fg: f32, +} + +impl ComplexColorRatios { + /// Ratios representing a `Numeric` color. + pub const NUMERIC: ComplexColorRatios = ComplexColorRatios { bg: 1., fg: 0. }; + /// Ratios representing the `Foreground` color. + pub const FOREGROUND: ComplexColorRatios = ComplexColorRatios { bg: 0., fg: 1. }; +} + +/// This enum represents a combined color from a numeric color and +/// the current foreground color (currentcolor keyword). +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue)] +pub enum Color { + /// Numeric RGBA color. + Numeric(RGBA), + + /// The current foreground color. + Foreground, + + /// A linear combination of numeric color and currentcolor. + /// The formula is: `color * ratios.bg + currentcolor * ratios.fg`. + Complex(RGBA, ComplexColorRatios), +} + +impl Color { + /// Create a color based upon the specified ratios. + pub fn with_ratios(color: RGBA, ratios: ComplexColorRatios) -> Self { + if ratios == ComplexColorRatios::NUMERIC { + Color::Numeric(color) + } else if ratios == ComplexColorRatios::FOREGROUND { + Color::Foreground + } else { + Color::Complex(color, ratios) + } + } + + /// Returns a numeric color representing the given RGBA value. + pub fn rgba(color: RGBA) -> Self { + Color::Numeric(color) + } + + /// Returns a complex color value representing currentcolor. + pub fn currentcolor() -> Self { + Color::Foreground + } + + /// Whether it is a numeric color (no currentcolor component). + pub fn is_numeric(&self) -> bool { + matches!(*self, Color::Numeric(..)) + } + + /// Whether it is a currentcolor value (no numeric color component). + pub fn is_currentcolor(&self) -> bool { + matches!(*self, Color::Foreground) + } +} + +impl From for Color { + fn from(color: RGBA) -> Self { + Self::rgba(color) + } +} diff --git a/components/style/values/generics/mod.rs b/components/style/values/generics/mod.rs index c3b29c93769..e6c1befea9f 100644 --- a/components/style/values/generics/mod.rs +++ b/components/style/values/generics/mod.rs @@ -17,6 +17,7 @@ pub mod basic_shape; pub mod border; #[path = "box.rs"] pub mod box_; +pub mod color; pub mod column; pub mod counters; pub mod effects; diff --git a/components/style/values/specified/color.rs b/components/style/values/specified/color.rs index 0670e8126ec..c05f0ddce0e 100644 --- a/components/style/values/specified/color.rs +++ b/components/style/values/specified/color.rs @@ -18,6 +18,7 @@ use style_traits::{CssType, CssWriter, KeywordsCollectFn, ParseError, StyleParse use style_traits::{SpecifiedValueInfo, ToCss, ValueParseErrorKind}; use super::AllowQuirks; use values::computed::{Color as ComputedColor, Context, ToComputedValue}; +use values::generics::color::Color as GenericColor; use values::specified::calc::CalcNode; /// Specified color value @@ -384,9 +385,9 @@ impl ToComputedValue for Color { fn from_computed_value(computed: &ComputedColor) -> Self { match *computed { - ComputedColor::Numeric(color) => Color::rgba(color), - ComputedColor::Foreground => Color::currentcolor(), - ComputedColor::Complex(..) => Color::Complex(*computed), + GenericColor::Numeric(color) => Color::rgba(color), + GenericColor::Foreground => Color::currentcolor(), + GenericColor::Complex(..) => Color::Complex(*computed), } } } From 011cad2534da0023364bdb2d3f88bd025aa4a5c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 7 Jun 2018 20:27:57 +0200 Subject: [PATCH 32/40] style: Add a Servo API to get the serialized style of a property. This is intended to be used by GetComputedStyle when there's no layout dependency. Bug: 1467536 Reviewed-by: xidorn MozReview-Commit-ID: 3GAbjo1uQ34 --- .../style/properties/properties.mako.rs | 93 +++++++++++++------ 1 file changed, 66 insertions(+), 27 deletions(-) diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index 4e52412c18d..cdebe662279 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -22,8 +22,7 @@ use std::cell::RefCell; use std::fmt::{self, Write}; use std::mem::{self, ManuallyDrop}; -#[cfg(feature = "servo")] use cssparser::RGBA; -use cssparser::{Parser, TokenSerializationType}; +use cssparser::{Parser, RGBA, TokenSerializationType}; use cssparser::ParserInput; #[cfg(feature = "servo")] use euclid::SideOffsets2D; use context::QuirksMode; @@ -45,7 +44,6 @@ use shared_lock::StylesheetGuards; use style_traits::{CssWriter, KeywordsCollectFn, ParseError, ParsingMode}; use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss}; use stylesheets::{CssRuleType, Origin, UrlExtraData}; -#[cfg(feature = "servo")] use values::Either; use values::generics::text::LineHeight; use values::computed; use values::computed::NonNegativeLength; @@ -834,13 +832,13 @@ bitflags! { const APPLIES_TO_FIRST_LINE = 1 << 4; /// This longhand property applies to ::placeholder. const APPLIES_TO_PLACEHOLDER = 1 << 5; + /// This property's getComputedStyle implementation requires layout + /// to be flushed. + const GETCS_NEEDS_LAYOUT_FLUSH = 1 << 6; /* The following flags are currently not used in Rust code, they * only need to be listed in corresponding properties so that * they can be checked in the C++ side via ServoCSSPropList.h. */ - /// This property's getComputedStyle implementation requires layout - /// to be flushed. - const GETCS_NEEDS_LAYOUT_FLUSH = 0; /// This property can be animated on the compositor. const CAN_ANIMATE_ON_COMPOSITOR = 0; } @@ -2614,6 +2612,59 @@ impl ComputedValues { pub fn custom_properties(&self) -> Option<<&Arc<::custom_properties::CustomPropertiesMap>> { self.custom_properties.as_ref() } + + /// Writes the value of the given longhand as a string in `dest`. + /// + /// Note that the value will usually be the computed value, except for + /// colors, where it's resolved. + pub fn get_longhand_property_value( + &self, + property_id: LonghandId, + dest: &mut CssWriter + ) -> fmt::Result + where + W: Write, + { + // TODO(emilio): Is it worth to merge branches here just like + // PropertyDeclaration::to_css does? + // + // We'd need to get a concept of ~resolved value, which may not be worth + // it. + match property_id { + % for prop in data.longhands: + LonghandId::${prop.camel_case} => { + let style_struct = + self.get_${prop.style_struct.ident.strip("_")}(); + let value = + style_struct + % if prop.logical: + .clone_${prop.ident}(self.writing_mode); + % else: + .clone_${prop.ident}(); + % endif + + % if prop.predefined_type == "Color": + let value = self.resolve_color(value); + % endif + + value.to_css(dest) + } + % endfor + } + } + + /// Resolves the currentColor keyword. + /// + /// Any color value from computed values (except for the 'color' property + /// itself) should go through this method. + /// + /// Usage example: + /// let top_color = + /// style.resolve_color(style.get_border().clone_border_top_color()); + #[inline] + pub fn resolve_color(&self, color: computed::Color) -> RGBA { + color.to_rgba(self.get_color().clone_color()) + } } #[cfg(feature = "servo")] @@ -2726,18 +2777,6 @@ impl ComputedValuesInner { self.get_column().is_multicol() } - /// Resolves the currentColor keyword. - /// - /// Any color value from computed values (except for the 'color' property - /// itself) should go through this method. - /// - /// Usage example: - /// let top_color = style.resolve_color(style.Border.border_top_color); - #[inline] - pub fn resolve_color(&self, color: computed::Color) -> RGBA { - color.to_rgba(self.get_color().color) - } - /// Get the logical computed inline size. #[inline] pub fn content_inline_size(&self) -> computed::LengthOrPercentageOrAuto { @@ -2902,19 +2941,19 @@ impl ComputedValuesInner { /// Serializes the computed value of this property as a string. pub fn computed_value_to_string(&self, property: PropertyDeclarationId) -> String { match property { - % for style_struct in data.active_style_structs(): - % for longhand in style_struct.longhands: - PropertyDeclarationId::Longhand(LonghandId::${longhand.camel_case}) => { - self.${style_struct.ident}.${longhand.ident}.to_css_string() - } - % endfor - % endfor + PropertyDeclarationId::Longhand(id) => { + let mut s = String::new(); + self.get_longhand_property_value( + property, + &mut CssWriter::new(&mut s) + ).unwrap(); + s + } PropertyDeclarationId::Custom(name) => { self.custom_properties .as_ref() .and_then(|map| map.get(name)) - .map(|value| value.to_css_string()) - .unwrap_or(String::new()) + .map_or(String::new(), |value| value.to_css_string()) } } } From d65b29da2710f49b98eb1df93346ec68f5e1b66f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 7 Jun 2018 21:07:28 +0200 Subject: [PATCH 33/40] style: Add CssPropFlags::SerializedByServo and use it on some simple properties. The idea is to turn the simple properties into a blacklist instead really soon, and fix the offending ones soon after, so that only shorthands and properties with layout dependence (and maybe the scrollbar properties, because the poke at LookAndFeel) are not serialized by Servo. Bug: 1467536 Reviewed-by: xidorn MozReview-Commit-ID: JTLNnmXzny8 --- components/style/properties/data.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 0ac42b365ee..fca4b536e01 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -226,6 +226,10 @@ class Longhand(object): # See compute_damage for the various values this can take self.servo_restyle_damage = servo_restyle_damage + @staticmethod + def type(): + return "longhand" + def experimental(self, product): if product == "gecko": return bool(self.gecko_pref) @@ -361,6 +365,10 @@ class Shorthand(object): animatable = property(get_animatable) transitionable = property(get_transitionable) + @staticmethod + def type(): + return "shorthand" + def experimental(self, product): if product == "gecko": return bool(self.gecko_pref) @@ -392,6 +400,10 @@ class Alias(object): self.allowed_in_page_rule = original.allowed_in_page_rule self.allowed_in_keyframe_block = original.allowed_in_keyframe_block + @staticmethod + def type(): + return "alias" + def experimental(self, product): if product == "gecko": return bool(self.gecko_pref) From 572a93142fddf64af952106073a9921cb2fbc961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 10 Jun 2018 01:08:43 +0200 Subject: [PATCH 34/40] style: Add diagnostics. Bug: 1416282 Reviewed-by: xidorn MozReview-Commit-ID: GTnFyZnXR84 --- components/selectors/builder.rs | 25 ++++++++++++++++++------- components/selectors/parser.rs | 2 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/components/selectors/builder.rs b/components/selectors/builder.rs index f100166f48d..0be3eb90e0c 100644 --- a/components/selectors/builder.rs +++ b/components/selectors/builder.rs @@ -36,6 +36,7 @@ use std::slice; /// (from left to right). Once the process is complete, callers should invoke /// build(), which transforms the contents of the SelectorBuilder into a heap- /// allocated Selector and leaves the builder in a drained state. +#[derive(Debug)] pub struct SelectorBuilder { /// The entire sequence of simple selectors, from left to right, without combinators. /// @@ -104,7 +105,7 @@ impl SelectorBuilder { parsed_slotted: bool, ) -> ThinArc> { // Compute the specificity and flags. - let mut spec = SpecificityAndFlags(specificity(self.simple_selectors.iter())); + let mut spec = SpecificityAndFlags(specificity(&*self, self.simple_selectors.iter())); if parsed_pseudo { spec.0 |= HAS_PSEUDO_BIT; } @@ -268,25 +269,35 @@ impl From for u32 { } } -fn specificity(iter: slice::Iter>) -> u32 +fn specificity(builder: &SelectorBuilder, iter: slice::Iter>) -> u32 where Impl: SelectorImpl, { - complex_selector_specificity(iter).into() + complex_selector_specificity(builder, iter).into() } -fn complex_selector_specificity(mut iter: slice::Iter>) -> Specificity +fn complex_selector_specificity( + builder: &SelectorBuilder, + mut iter: slice::Iter>, +) -> Specificity where Impl: SelectorImpl, { fn simple_selector_specificity( + builder: &SelectorBuilder, simple_selector: &Component, specificity: &mut Specificity, ) where Impl: SelectorImpl, { match *simple_selector { - Component::Combinator(..) => unreachable!(), + Component::Combinator(ref combinator) => { + unreachable!( + "Found combinator {:?} in simple selectors vector? {:?}", + combinator, + builder, + ); + } // FIXME(emilio): Spec doesn't define any particular specificity for // ::slotted(), so apply the general rule for pseudos per: // @@ -326,7 +337,7 @@ where }, Component::Negation(ref negated) => { for ss in negated.iter() { - simple_selector_specificity(&ss, specificity); + simple_selector_specificity(builder, &ss, specificity); } }, } @@ -334,7 +345,7 @@ where let mut specificity = Default::default(); for simple_selector in &mut iter { - simple_selector_specificity(&simple_selector, &mut specificity); + simple_selector_specificity(builder, &simple_selector, &mut specificity); } specificity } diff --git a/components/selectors/parser.rs b/components/selectors/parser.rs index 2c9d6505776..3210f1085b0 100644 --- a/components/selectors/parser.rs +++ b/components/selectors/parser.rs @@ -92,7 +92,7 @@ macro_rules! with_all_bounds { /// NB: We need Clone so that we can derive(Clone) on struct with that /// are parameterized on SelectorImpl. See /// - pub trait SelectorImpl: Clone + Sized + 'static { + pub trait SelectorImpl: Clone + Debug + Sized + 'static { type ExtraMatchingData: Sized + Default + 'static; type AttrValue: $($InSelector)*; type Identifier: $($InSelector)*; From 078df23e965cc8cb1898f5e824262862494698bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 11 Jun 2018 16:12:23 -0700 Subject: [PATCH 35/40] style: Update cssparser. --- Cargo.lock | 86 ++++++++++++++----------------------------------- servo-tidy.toml | 4 --- 2 files changed, 25 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c439fee0ea..9675e950eb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -271,7 +271,7 @@ dependencies = [ "azure 0.29.0 (git+https://github.com/servo/rust-azure)", "canvas_traits 0.0.1", "compositing 0.0.1", - "cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -289,7 +289,7 @@ dependencies = [ name = "canvas_traits" version = "0.0.1" dependencies = [ - "cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -563,30 +563,32 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.23.2" +version = "0.23.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser-macros 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "dtoa-short 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "procedural-masquerade 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cssparser-macros" -version = "0.3.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "procedural-masquerade 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1319,11 +1321,6 @@ dependencies = [ "either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "itoa" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "itoa" version = "0.4.1" @@ -1615,7 +1612,7 @@ name = "malloc_size_of" version = "0.0.1" dependencies = [ "app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashglobe 0.1.0", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1625,7 +1622,7 @@ dependencies = [ "serde 1.0.37 (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.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2280,11 +2277,6 @@ name = "quick-error" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "quote" version = "0.5.1" @@ -2472,7 +2464,7 @@ dependencies = [ "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", "deny_public_fields 0.0.1", "devtools_traits 0.0.1", "dom_struct 0.0.1", @@ -2549,7 +2541,7 @@ dependencies = [ "app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "canvas_traits 0.0.1", - "cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", "html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2631,7 +2623,7 @@ name = "selectors" version = "0.19.0" dependencies = [ "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2921,7 +2913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "smallbitvec" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2981,7 +2973,7 @@ dependencies = [ "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", "encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "fallible 0.0.1", @@ -3012,7 +3004,7 @@ dependencies = [ "servo_atoms 0.0.1", "servo_config 0.0.1", "servo_url 0.0.1", - "smallbitvec 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.0 (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", @@ -3042,7 +3034,7 @@ version = "0.0.1" dependencies = [ "app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3064,7 +3056,7 @@ version = "0.0.1" dependencies = [ "app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of 0.0.1", "malloc_size_of_derive 0.0.1", @@ -3081,16 +3073,6 @@ name = "swapper" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "syn" version = "0.13.1" @@ -3101,14 +3083,6 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "synstructure" version = "0.8.1" @@ -3296,11 +3270,6 @@ name = "unicode-width" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-xid" version = "0.1.0" @@ -3787,8 +3756,8 @@ dependencies = [ "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" -"checksum cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8a807ac3ab7a217829c2a3b65732b926b2befe6a35f33b4bf8b503692430f223" -"checksum cssparser-macros 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "079adec4af52bb5275eadd004292028c79eb3c5f5b4ee8086a36d4197032f6df" +"checksum cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)" = "205647ffe2b63a9726a4c3bb6f31c7325e8ceff10e2f1b75a6fb7609e20419ea" +"checksum cssparser-macros 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a5383ae18dbfdeb569ed62019f5bddb2a95cd2d3833313c475a0d014777805" "checksum darling 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a78af487e4eb8f4421a1770687b328af6bb4494ca93435210678c6eea875c11" "checksum darling_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b315f49c7b6db3708bca6e6913c194581a44ec619b7a39e131d4dd63733a3698" "checksum darling_macro 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb69a38fdeaeaf3db712e1df170de67ee9dfc24fb88ca3e9d21e703ec25a4d8e" @@ -3853,7 +3822,6 @@ dependencies = [ "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9daf099728ac5390c73f54e6e3708f0c514d2b51f24373830f568702eadfca" "checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394" -"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682" "checksum jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "479294d130502fada93c7a957e8d059b632b03d6204aca37af557dee947f30a9" "checksum jpeg-decoder 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0dfe27a6c0dabd772d0f9b9f8701c4ca12c4d1eebcadf2be1f6f70396f6a1434" @@ -3927,7 +3895,6 @@ dependencies = [ "checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4" "checksum procedural-masquerade 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c93cdc1fb30af9ddf3debc4afbdb0f35126cbd99daa229dd76cdd5349b41d989" "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" -"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" @@ -3967,7 +3934,7 @@ 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.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" -"checksum smallbitvec 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "665fbc8384f961eb55c548daa2a4b1efff1f9d03b7a10f162ac6ad6a781ca966" +"checksum smallbitvec 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c63726029f0069f88467873e47f392575f28f9f16b72ac65465263db4b3a13c" "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9" "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" "checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423" @@ -3975,9 +3942,7 @@ dependencies = [ "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" "checksum swapper 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e454d048db5527d000bfddb77bd072bbf3a1e2ae785f16d9bd116e07c2ab45eb" -"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59" -"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "98cad891cd238c98e1f0aec9f7c0f620aa696e4e5f7daba56ac67b5e86a6b049" "checksum tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11ce2fe9db64b842314052e2421ac61a73ce41b898dc8e3750398b219c5fc1e0" "checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508" @@ -4002,7 +3967,6 @@ dependencies = [ "checksum unicode-script 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e8bd7bbf020b2885113e6304f68bcc33881c5552657c58d4e9699cd1b6606e81" "checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" -"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2" diff --git a/servo-tidy.toml b/servo-tidy.toml index 90d316726a4..c3539b5b141 100644 --- a/servo-tidy.toml +++ b/servo-tidy.toml @@ -39,13 +39,9 @@ num = [ # Ignored packages with duplicated versions packages = [ "bitflags", - "itoa", "log", "num-traits", - "quote", "rand", - "syn", - "unicode-xid", "winapi", ] # Files that are ignored for all tidy and lint checks. From e94395b52368ad237749793766767bb5ff95cc93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 11 Jun 2018 16:19:56 -0700 Subject: [PATCH 36/40] style_derive: Fix tidy lint. --- components/style_derive/specified_value_info.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/style_derive/specified_value_info.rs b/components/style_derive/specified_value_info.rs index 37471b041a8..b707ec2c69f 100644 --- a/components/style_derive/specified_value_info.rs +++ b/components/style_derive/specified_value_info.rs @@ -3,10 +3,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use cg; +use parse::ParseVariantAttrs; use quote::Tokens; use syn::{Data, DeriveInput, Fields, Ident, Type}; use to_css::{CssFieldAttrs, CssInputAttrs, CssVariantAttrs}; -use parse::ParseVariantAttrs; pub fn derive(mut input: DeriveInput) -> Tokens { let css_attrs = cg::parse_input_attrs::(&input); From ab760033fdd480f644b372e45c679804c880ce67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 11 Jun 2018 16:24:26 -0700 Subject: [PATCH 37/40] style: Fix servo build. --- components/script/dom/cssstyledeclaration.rs | 4 +- .../helpers/animated_properties.mako.rs | 3 +- .../style/properties/longhand/box.mako.rs | 3 +- .../style/properties/properties.mako.rs | 41 ++++++++++--------- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index 43eac985c5e..e3a4a20d380 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -253,7 +253,7 @@ impl CSSStyleDeclaration { self.owner.mutate_associated_block(|pdb, changed| { if value.is_empty() { // Step 3 - *changed = pdb.remove_property(&id); + *changed = pdb.remove_property(&id, |_| {}); return Ok(()); } @@ -365,7 +365,7 @@ impl CSSStyleDeclarationMethods for CSSStyleDeclaration { let mut string = String::new(); self.owner.mutate_associated_block(|pdb, changed| { pdb.property_value_to_css(&id, &mut string).unwrap(); - *changed = pdb.remove_property(&id); + *changed = pdb.remove_property(&id, |_| {}); }); // Step 6 diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index acdaebef205..d935726eb48 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -31,10 +31,11 @@ use values::CSSFloat; use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero}; use values::animated::color::RGBA as AnimatedRGBA; use values::animated::effects::Filter as AnimatedFilter; +#[cfg(feature = "gecko")] use values::computed::TransitionProperty; use values::computed::{Angle, CalcLengthOrPercentage}; use values::computed::{ClipRect, Context}; use values::computed::{Length, LengthOrPercentage, LengthOrPercentageOrAuto}; -use values::computed::{LengthOrPercentageOrNone, MaxLength, TransitionProperty}; +use values::computed::{LengthOrPercentageOrNone, MaxLength}; use values::computed::{NonNegativeNumber, Number, NumberOrPercentage, Percentage}; use values::computed::length::NonNegativeLengthOrPercentage; use values::computed::ToComputedValue; diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 6c388d1efbd..898f7391de0 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -19,7 +19,8 @@ ${helpers.predefined_type( animation_value_type="discrete", flags="APPLIES_TO_PLACEHOLDER", spec="https://drafts.csswg.org/css-display/#propdef-display", - servo_restyle_damage="rebuild_and_reflow" + servo_restyle_damage="rebuild_and_reflow", + needs_context=product == "gecko" )} // FIXME(emilio): Listing all the display values here is very unfortunate, we should teach C++ to use the diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index cdebe662279..4d18e0ca634 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -2501,6 +2501,7 @@ pub mod style_structs { /// Whether this is a multicol style. #[cfg(feature = "servo")] pub fn is_multicol(&self) -> bool { + use values::Either; match self.column_width { Either::First(_width) => true, Either::Second(_auto) => !self.column_count.is_auto(), @@ -2699,6 +2700,26 @@ impl ComputedValues { /// Get the initial computed values. pub fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES } + + /// Serializes the computed value of this property as a string. + pub fn computed_value_to_string(&self, property: PropertyDeclarationId) -> String { + match property { + PropertyDeclarationId::Longhand(id) => { + let mut s = String::new(); + self.get_longhand_property_value( + id, + &mut CssWriter::new(&mut s) + ).unwrap(); + s + } + PropertyDeclarationId::Custom(name) => { + self.custom_properties + .as_ref() + .and_then(|map| map.get(name)) + .map_or(String::new(), |value| value.to_css_string()) + } + } + } } #[cfg(feature = "servo")] @@ -2937,26 +2958,6 @@ impl ComputedValuesInner { // Neither perspective nor transform present false } - - /// Serializes the computed value of this property as a string. - pub fn computed_value_to_string(&self, property: PropertyDeclarationId) -> String { - match property { - PropertyDeclarationId::Longhand(id) => { - let mut s = String::new(); - self.get_longhand_property_value( - property, - &mut CssWriter::new(&mut s) - ).unwrap(); - s - } - PropertyDeclarationId::Custom(name) => { - self.custom_properties - .as_ref() - .and_then(|map| map.get(name)) - .map_or(String::new(), |value| value.to_css_string()) - } - } - } } % if product == "gecko": From 4cd16ee63c69d0a80998055a83bd8582edd9639b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 11 Jun 2018 16:54:27 -0700 Subject: [PATCH 38/40] style: Derive Animate for ComplexColorRatios. --- components/style/values/animated/color.rs | 10 ---------- components/style/values/generics/color.rs | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/components/style/values/animated/color.rs b/components/style/values/animated/color.rs index 6a82896d62b..1b01a86457a 100644 --- a/components/style/values/animated/color.rs +++ b/components/style/values/animated/color.rs @@ -92,16 +92,6 @@ impl ComputeSquaredDistance for RGBA { } } -impl Animate for ComplexColorRatios { - #[inline] - fn animate(&self, other: &Self, procedure: Procedure) -> Result { - let bg = self.bg.animate(&other.bg, procedure)?; - let fg = self.fg.animate(&other.fg, procedure)?; - - Ok(ComplexColorRatios { bg, fg }) - } -} - /// An animated value for ``. pub type Color = GenericColor; diff --git a/components/style/values/generics/color.rs b/components/style/values/generics/color.rs index 693803ad5fd..e84bd690c7c 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(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue)] +#[derive(Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedValue)] pub struct ComplexColorRatios { /// Numeric color contribution. pub bg: f32, From 0d0b0e08bb90a25a49187ccf22375f76d349e237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 11 Jun 2018 17:25:57 -0700 Subject: [PATCH 39/40] Update WPT expectations. --- .../css/css-transitions/currentcolor-animation-001.html.ini | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 tests/wpt/metadata/css/css-transitions/currentcolor-animation-001.html.ini diff --git a/tests/wpt/metadata/css/css-transitions/currentcolor-animation-001.html.ini b/tests/wpt/metadata/css/css-transitions/currentcolor-animation-001.html.ini deleted file mode 100644 index c8a94fa2ed1..00000000000 --- a/tests/wpt/metadata/css/css-transitions/currentcolor-animation-001.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[currentcolor-animation-001.html] - type: testharness - [currentcolortransition] - expected: FAIL - From 2106cc46e5eedd909b981d69d8f0f9b9dc9eb44c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 12 Jun 2018 12:14:11 -0700 Subject: [PATCH 40/40] style: Update cssparser again to avoid intermittent stack overflows on CI. Fixes #21038 --- Cargo.lock | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9675e950eb3..29b9ef4a501 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -271,7 +271,7 @@ dependencies = [ "azure 0.29.0 (git+https://github.com/servo/rust-azure)", "canvas_traits 0.0.1", "compositing 0.0.1", - "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -289,7 +289,7 @@ dependencies = [ name = "canvas_traits" version = "0.0.1" dependencies = [ - "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -563,7 +563,7 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.23.9" +version = "0.23.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cssparser-macros 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1612,7 +1612,7 @@ name = "malloc_size_of" version = "0.0.1" dependencies = [ "app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "hashglobe 0.1.0", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2464,7 +2464,7 @@ dependencies = [ "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)", "deny_public_fields 0.0.1", "devtools_traits 0.0.1", "dom_struct 0.0.1", @@ -2541,7 +2541,7 @@ dependencies = [ "app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "canvas_traits 0.0.1", - "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_traits 0.0.1", "html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2623,7 +2623,7 @@ name = "selectors" version = "0.19.0" dependencies = [ "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2973,7 +2973,7 @@ dependencies = [ "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)", "encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "fallible 0.0.1", @@ -3034,7 +3034,7 @@ version = "0.0.1" dependencies = [ "app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3056,7 +3056,7 @@ version = "0.0.1" dependencies = [ "app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of 0.0.1", "malloc_size_of_derive 0.0.1", @@ -3756,7 +3756,7 @@ dependencies = [ "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" -"checksum cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)" = "205647ffe2b63a9726a4c3bb6f31c7325e8ceff10e2f1b75a6fb7609e20419ea" +"checksum cssparser 0.23.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1c74d99b0f489cc546336b911452562ebfd4aec034b0c526cb77a3a02d3790" "checksum cssparser-macros 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a5383ae18dbfdeb569ed62019f5bddb2a95cd2d3833313c475a0d014777805" "checksum darling 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a78af487e4eb8f4421a1770687b328af6bb4494ca93435210678c6eea875c11" "checksum darling_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b315f49c7b6db3708bca6e6913c194581a44ec619b7a39e131d4dd63733a3698"