From 593e4e4c9eaf430e4c535d5370e143802c65fbfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 19 Apr 2018 17:50:32 +0200 Subject: [PATCH 01/31] style: Rename justify-items: auto to legacy. Bug: 1363875 Reviewed-by: mats,xidorn MozReview-Commit-ID: Jfwib2XDmSw --- components/style/properties/gecko.mako.rs | 2 +- .../properties/longhand/position.mako.rs | 12 ++- components/style/style_adjuster.rs | 8 +- components/style/values/computed/align.rs | 25 ++--- components/style/values/specified/align.rs | 98 +++++++++---------- 5 files changed, 74 insertions(+), 71 deletions(-) diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 067d014442d..82e52853fea 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -1806,7 +1806,7 @@ fn static_assert() { } pub fn set_computed_justify_items(&mut self, v: values::specified::JustifyItems) { - debug_assert_ne!(v.0, ::values::specified::align::AlignFlags::AUTO); + debug_assert_ne!(v.0, ::values::specified::align::AlignFlags::LEGACY); self.gecko.mJustifyItems = v.into(); } diff --git a/components/style/properties/longhand/position.mako.rs b/components/style/properties/longhand/position.mako.rs index 5d64159654c..bfda37e8a19 100644 --- a/components/style/properties/longhand/position.mako.rs +++ b/components/style/properties/longhand/position.mako.rs @@ -118,11 +118,13 @@ ${helpers.single_keyword("flex-wrap", "nowrap wrap wrap-reverse", #[cfg(feature = "gecko")] impl_align_conversions!(::values::specified::align::AlignItems); - ${helpers.predefined_type(name="justify-items", - type="JustifyItems", - initial_value="computed::JustifyItems::auto()", - spec="https://drafts.csswg.org/css-align/#propdef-justify-items", - animation_value_type="discrete")} + ${helpers.predefined_type( + name="justify-items", + type="JustifyItems", + initial_value="computed::JustifyItems::legacy()", + spec="https://drafts.csswg.org/css-align/#propdef-justify-items", + animation_value_type="discrete", + )} #[cfg(feature = "gecko")] impl_align_conversions!(::values::specified::align::JustifyItems); diff --git a/components/style/style_adjuster.rs b/components/style/style_adjuster.rs index b7270976ead..32bd68db52d 100644 --- a/components/style/style_adjuster.rs +++ b/components/style/style_adjuster.rs @@ -673,17 +673,15 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { } } - /// Resolves "justify-items: auto" based on the inherited style if needed to - /// comply with: + /// Resolves "justify-items: legacy" based on the inherited style if needed + /// to comply with: /// /// - /// - /// (Note that "auto" is being renamed to "legacy") #[cfg(feature = "gecko")] fn adjust_for_justify_items(&mut self) { use values::specified::align; let justify_items = self.style.get_position().clone_justify_items(); - if justify_items.specified.0 != align::AlignFlags::AUTO { + if justify_items.specified.0 != align::AlignFlags::LEGACY { return; } diff --git a/components/style/values/computed/align.rs b/components/style/values/computed/align.rs index 940e3f747b8..1a26e41fd24 100644 --- a/components/style/values/computed/align.rs +++ b/components/style/values/computed/align.rs @@ -20,10 +20,10 @@ pub use super::specified::{AlignSelf, JustifySelf}; /// In particular, `justify-items` is a reset property, so we ought to be able /// to share its computed representation across elements as long as they match /// the same rules. Except that it's not true if the specified value for -/// `justify-items` is `auto` and the computed value of the parent has the +/// `justify-items` is `legacy` and the computed value of the parent has the /// `legacy` modifier. /// -/// So instead of computing `auto` "normally" looking at get_parent_position(), +/// So instead of computing `legacy` "normally" looking at get_parent_position(), /// marking it as uncacheable, we carry the specified value around and handle /// the special case in `StyleAdjuster` instead, only when the result of the /// computation would vary. @@ -35,18 +35,21 @@ pub use super::specified::{AlignSelf, JustifySelf}; /// See the discussion in https://bugzil.la/1384542. #[derive(Clone, Copy, Debug, Eq, PartialEq, ToCss)] pub struct JustifyItems { - /// The specified value for the property. Can contain `auto`. + /// The specified value for the property. Can contain the bare `legacy` + /// keyword. #[css(skip)] pub specified: specified::JustifyItems, - /// The computed value for the property. Cannot contain `auto`. + /// The computed value for the property. Cannot contain the bare `legacy` + /// keyword, but note that it could contain it in combination with other + /// keywords like `left`, `right` or `center`. pub computed: specified::JustifyItems, } impl JustifyItems { - /// Returns the `auto` value. - pub fn auto() -> Self { + /// Returns the `legacy` value. + pub fn legacy() -> Self { Self { - specified: specified::JustifyItems::auto(), + specified: specified::JustifyItems::legacy(), computed: specified::JustifyItems::normal(), } } @@ -59,13 +62,13 @@ impl ToComputedValue for specified::JustifyItems { fn to_computed_value(&self, _context: &Context) -> JustifyItems { use values::specified::align; let specified = *self; - let computed = if self.0 != align::AlignFlags::AUTO { + let computed = if self.0 != align::AlignFlags::LEGACY { *self } else { // If the inherited value of `justify-items` includes the - // `legacy` keyword, `auto` computes to the inherited value, - // but we assume it computes to `normal`, and handle that - // special-case in StyleAdjuster. + // `legacy` keyword, `legacy` computes to the inherited value, but + // we assume it computes to `normal`, and handle that special-case + // in StyleAdjuster. Self::normal() }; diff --git a/components/style/values/specified/align.rs b/components/style/values/specified/align.rs index 918c4ddf8ed..7b9b003a50c 100644 --- a/components/style/values/specified/align.rs +++ b/components/style/values/specified/align.rs @@ -9,9 +9,8 @@ use cssparser::Parser; use gecko_bindings::structs; use parser::{Parse, ParserContext}; -use selectors::parser::SelectorParseErrorKind; use std::fmt::{self, Write}; -use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; +use style_traits::{CssWriter, ParseError, ToCss}; bitflags! { /// Constants shared by multiple CSS Box Alignment properties @@ -81,14 +80,26 @@ impl ToCss for AlignFlags { where W: Write, { - match *self & AlignFlags::FLAG_BITS { - AlignFlags::LEGACY => dest.write_str("legacy ")?, + let extra_flags = *self & AlignFlags::FLAG_BITS; + let value = self.value(); + + match extra_flags { + AlignFlags::LEGACY => { + dest.write_str("legacy")?; + if value.is_empty() { + return Ok(()); + } + dest.write_char(' ')?; + }, AlignFlags::SAFE => dest.write_str("safe ")?, // Don't serialize "unsafe", since it's the default. - _ => {}, + AlignFlags::UNSAFE => {}, + _ => { + debug_assert_eq!(extra_flags, AlignFlags::empty()); + }, } - dest.write_str(match self.value() { + dest.write_str(match value { AlignFlags::AUTO => "auto", AlignFlags::NORMAL => "normal", AlignFlags::START => "start", @@ -436,10 +447,10 @@ impl Parse for AlignItems { pub struct JustifyItems(pub AlignFlags); impl JustifyItems { - /// The initial value 'auto' + /// The initial value 'legacy' #[inline] - pub fn auto() -> Self { - JustifyItems(AlignFlags::AUTO) + pub fn legacy() -> Self { + JustifyItems(AlignFlags::LEGACY) } /// The value 'normal' @@ -462,24 +473,12 @@ impl Parse for JustifyItems { return Ok(JustifyItems(baseline)); } - // auto | normal | stretch - // - // FIXME(emilio): auto is no longer a keyword in the current spec, and - // has been renamed to legacy, but that needs different changes because - // right now it's the initial value for both style systems, and has that - // weird behavior of "inheriting" into descendants. - // - // Fix this in both. - // - // See also: - // https://bugs.webkit.org/show_bug.cgi?id=172711 - // https://bugs.chromium.org/p/chromium/issues/detail?id=726148 - // - if let Ok(value) = input.try(parse_auto_normal_stretch) { + // normal | stretch + if let Ok(value) = input.try(parse_normal_stretch) { return Ok(JustifyItems(value)); } - // [ legacy || [ left | right | center ] ] + // legacy | [ legacy && [ left | right | center ] ] if let Ok(value) = input.try(parse_legacy) { return Ok(JustifyItems(value)); } @@ -567,29 +566,30 @@ fn parse_self_position<'i, 't>( }) } -// [ legacy && [ left | right | center ] ] -fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - let a_location = input.current_source_location(); - let a = input.expect_ident()?.clone(); - let b_location = input.current_source_location(); - let b = input.expect_ident()?; - if a.eq_ignore_ascii_case("legacy") { - (match_ignore_ascii_case! { &b, - "left" => Ok(AlignFlags::LEGACY | AlignFlags::LEFT), - "right" => Ok(AlignFlags::LEGACY | AlignFlags::RIGHT), - "center" => Ok(AlignFlags::LEGACY | AlignFlags::CENTER), - _ => Err(()) - }).map_err(|()| { - b_location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(b.clone())) - }) - } else if b.eq_ignore_ascii_case("legacy") { - (match_ignore_ascii_case! { &a, - "left" => Ok(AlignFlags::LEGACY | AlignFlags::LEFT), - "right" => Ok(AlignFlags::LEGACY | AlignFlags::RIGHT), - "center" => Ok(AlignFlags::LEGACY | AlignFlags::CENTER), - _ => Err(()) - }).map_err(|()| a_location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(a))) - } else { - Err(a_location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) - } +fn parse_left_right_center<'i, 't>( + input: &mut Parser<'i, 't>, +) -> Result> { + Ok(try_match_ident_ignore_ascii_case! { input, + "left" => AlignFlags::LEFT, + "right" => AlignFlags::RIGHT, + "center" => AlignFlags::CENTER, + }) +} + +// legacy | [ legacy && [ left | right | center ] ] +fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { + let flags = try_match_ident_ignore_ascii_case! { input, + "legacy" => { + let flags = input.try(parse_left_right_center) + .unwrap_or(AlignFlags::empty()); + + return Ok(AlignFlags::LEGACY | flags) + } + "left" => AlignFlags::LEFT, + "right" => AlignFlags::RIGHT, + "center" => AlignFlags::CENTER, + }; + + input.expect_ident_matching("legacy")?; + Ok(AlignFlags::LEGACY | flags) } From 76a14d6a6470fe6e290a11ae0954635710c19568 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Wed, 18 Apr 2018 10:41:56 -0700 Subject: [PATCH 02/31] style: Switch stylo function signature checking to use generated bindings. Bug: 1451956 Reviewed-by: xidorn MozReview-Commit-ID: A7sWaD2PInN --- ports/geckolib/tests/build.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/geckolib/tests/build.rs b/ports/geckolib/tests/build.rs index ab21e2186cd..7feb9d10405 100644 --- a/ports/geckolib/tests/build.rs +++ b/ports/geckolib/tests/build.rs @@ -11,8 +11,11 @@ use std::io::{BufRead, BufReader, Write}; use std::path::Path; fn main() { + // https://github.com/rust-lang/cargo/issues/3544 + let style_out_dir = env::var_os("DEP_FOR SOME REASON THE LINKS KEY IS REQUIRED \ + TO PASS DATA AROUND BETWEEN BUILD SCRIPTS_OUT_DIR").unwrap(); let root_path = Path::new("../../../"); - let bindings_file = root_path.join("components/style/gecko/generated/bindings.rs"); + let bindings_file = Path::new(&style_out_dir).join("gecko/bindings.rs"); let glue_file = root_path.join("ports/geckolib/glue.rs"); println!("cargo:rerun-if-changed=build.rs"); @@ -70,9 +73,6 @@ fn main() { } } - // https://github.com/rust-lang/cargo/issues/3544 - let style_out_dir = env::var_os("DEP_FOR SOME REASON THE LINKS KEY IS REQUIRED \ - TO PASS DATA AROUND BETWEEN BUILD SCRIPTS_OUT_DIR").unwrap(); File::create(out_dir.join("bindings.rs")) .unwrap() .write_all(format!("include!(concat!({:?}, \"/gecko/structs.rs\"));", From bc1126ee8c9bc768d0caf09043436b52ff311efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 17 Apr 2018 13:30:04 +0200 Subject: [PATCH 03/31] style: Update font-weight property and descriptor to css-fonts-4. Bug: 1454596 Reviewed-by: xidorn MozReview-Commit-ID: 27aS2UrgXjs --- components/style/font_face.rs | 43 ++---- components/style/gecko/rules.rs | 39 ++++-- .../gecko_bindings/sugar/ns_css_value.rs | 4 +- components/style/properties/gecko.mako.rs | 4 +- .../helpers/animated_properties.mako.rs | 17 +-- .../style/properties/longhand/font.mako.rs | 18 +-- components/style/values/computed/font.rs | 76 ++++++----- components/style/values/specified/font.rs | 127 +++++++++++++----- components/style/values/specified/mod.rs | 7 + ports/geckolib/glue.rs | 5 +- 10 files changed, 199 insertions(+), 141 deletions(-) diff --git a/components/style/font_face.rs b/components/style/font_face.rs index a890822d02f..d47dd71b274 100644 --- a/components/style/font_face.rs +++ b/components/style/font_face.rs @@ -9,7 +9,7 @@ #![deny(missing_docs)] #[cfg(feature = "gecko")] -use computed_values::{font_stretch, font_style, font_weight}; +use computed_values::{font_stretch, font_style}; use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; use cssparser::{CowRcStr, SourceLocation}; #[cfg(feature = "gecko")] @@ -27,7 +27,7 @@ use style_traits::{StyleParseErrorKind, ToCss}; use style_traits::values::SequenceWriter; use values::computed::font::FamilyName; #[cfg(feature = "gecko")] -use values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings}; +use values::specified::font::{AbsoluteFontWeight, SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings}; use values::specified::url::SpecifiedUrl; /// A source for a font-face rule. @@ -92,38 +92,21 @@ pub enum FontDisplay { Optional, } -/// A font-weight value for a @font-face rule. -/// The font-weight CSS property specifies the weight or boldness of the font. -#[cfg(feature = "gecko")] -#[derive(Clone, Debug, Eq, PartialEq, ToCss)] -pub enum FontWeight { - /// Numeric font weights for fonts that provide more than just normal and bold. - Weight(font_weight::T), - /// Normal font weight. Same as 400. - Normal, - /// Bold font weight. Same as 700. - Bold, -} +/// The font-weight descriptor: +/// +/// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-weight +#[derive(Clone, Debug, PartialEq, ToCss)] +pub struct FontWeight(pub AbsoluteFontWeight, pub Option); -#[cfg(feature = "gecko")] impl Parse for FontWeight { fn parse<'i, 't>( - _: &ParserContext, + context: &ParserContext, input: &mut Parser<'i, 't>, - ) -> Result> { - let result = input.try(|input| { - let ident = input.expect_ident().map_err(|_| ())?; - match_ignore_ascii_case! { &ident, - "normal" => Ok(FontWeight::Normal), - "bold" => Ok(FontWeight::Bold), - _ => Err(()) - } - }); - result.or_else(|_| { - font_weight::T::from_int(input.expect_integer()?) - .map(FontWeight::Weight) - .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) - }) + ) -> Result> { + let first = AbsoluteFontWeight::parse(context, input)?; + let second = + input.try(|input| AbsoluteFontWeight::parse(context, input)).ok(); + Ok(FontWeight(first, second)) } } diff --git a/components/style/gecko/rules.rs b/components/style/gecko/rules.rs index 2f144279656..599f61b63d7 100644 --- a/components/style/gecko/rules.rs +++ b/components/style/gecko/rules.rs @@ -5,7 +5,7 @@ //! Bindings for CSS Rule objects use byteorder::{BigEndian, WriteBytesExt}; -use computed_values::{font_stretch, font_style, font_weight}; +use computed_values::{font_stretch, font_style}; use counter_style::{self, CounterBound}; use cssparser::UnicodeRange; use font_face::{FontDisplay, FontWeight, Source}; @@ -15,6 +15,7 @@ use properties::longhands::font_language_override; use std::str; use values::computed::font::FamilyName; use values::generics::font::FontTag; +use values::specified::font::AbsoluteFontWeight; use values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings}; impl<'a> ToNsCssValue for &'a FamilyName { @@ -23,19 +24,9 @@ impl<'a> ToNsCssValue for &'a FamilyName { } } -impl ToNsCssValue for font_weight::T { +impl<'a> ToNsCssValue for &'a AbsoluteFontWeight { fn convert(self, nscssvalue: &mut nsCSSValue) { - nscssvalue.set_font_weight(self.0) - } -} - -impl<'a> ToNsCssValue for &'a FontWeight { - fn convert(self, nscssvalue: &mut nsCSSValue) { - match *self { - FontWeight::Normal => nscssvalue.set_enum(structs::NS_FONT_WEIGHT_NORMAL as i32), - FontWeight::Bold => nscssvalue.set_enum(structs::NS_FONT_WEIGHT_BOLD as i32), - FontWeight::Weight(weight) => nscssvalue.set_font_weight(weight.0), - } + nscssvalue.set_font_weight(self.compute().0) } } @@ -77,6 +68,28 @@ impl<'a> ToNsCssValue for &'a SpecifiedFontVariationSettings { } } +impl<'a> ToNsCssValue for &'a FontWeight { + fn convert(self, nscssvalue: &mut nsCSSValue) { + let FontWeight(ref first, ref second) = *self; + + let second = match *second { + None => { + nscssvalue.set_from(first); + return; + } + Some(ref second) => second, + }; + + let mut a = nsCSSValue::null(); + let mut b = nsCSSValue::null(); + + a.set_from(first); + b.set_from(second); + + nscssvalue.set_pair(&a, &b); + } +} + impl<'a> ToNsCssValue for &'a font_language_override::SpecifiedValue { fn convert(self, nscssvalue: &mut nsCSSValue) { match *self { diff --git a/components/style/gecko_bindings/sugar/ns_css_value.rs b/components/style/gecko_bindings/sugar/ns_css_value.rs index 45693561510..ef89c723dce 100644 --- a/components/style/gecko_bindings/sugar/ns_css_value.rs +++ b/components/style/gecko_bindings/sugar/ns_css_value.rs @@ -178,8 +178,8 @@ impl nsCSSValue { } /// Set to a font weight - pub fn set_font_weight(&mut self, w: u16) { - unsafe { bindings::Gecko_CSSValue_SetFontWeight(self, w as f32) } + pub fn set_font_weight(&mut self, w: f32) { + unsafe { bindings::Gecko_CSSValue_SetFontWeight(self, w) } } fn set_int_internal(&mut self, value: i32, unit: nsCSSUnit) { diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 82e52853fea..b6a473477a6 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -2607,9 +2607,7 @@ fn static_assert() { pub fn clone_font_weight(&self) -> longhands::font_weight::computed_value::T { let weight: f32 = unsafe { Gecko_FontWeight_ToFloat(self.gecko.mFont.weight) }; - debug_assert!(weight >= 0.0 && - weight <= ::std::u16::MAX as f32); - longhands::font_weight::computed_value::T(weight as u16) + longhands::font_weight::computed_value::T(weight) } ${impl_simple_type_with_conversion("font_synthesis", "mFont.synthesis")} diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index a06d9f62f71..fa87f1b43fb 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -873,20 +873,6 @@ impl ToAnimatedZero for MaxLength { fn to_animated_zero(&self) -> Result { Err(()) } } -/// -impl Animate for FontWeight { - #[inline] - fn animate(&self, other: &Self, procedure: Procedure) -> Result { - let a = self.0 as f64; - let b = other.0 as f64; - const NORMAL: f64 = 400.; - let (this_weight, other_weight) = procedure.weights(); - let weight = (a - NORMAL) * this_weight + (b - NORMAL) * other_weight + NORMAL; - let weight = (weight.max(100.).min(900.) / 100.).round() * 100.; - Ok(FontWeight(weight as u16)) - } -} - impl ToAnimatedZero for FontWeight { #[inline] fn to_animated_zero(&self) -> Result { @@ -897,8 +883,7 @@ impl ToAnimatedZero for FontWeight { /// impl Animate for FontStretch { #[inline] - fn animate(&self, other: &Self, procedure: Procedure) -> Result - { + fn animate(&self, other: &Self, procedure: Procedure) -> Result { let from = f64::from(*self); let to = f64::from(*other); let normal = f64::from(FontStretch::Normal); diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 0d246d3b358..dd4c6e84789 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -43,14 +43,16 @@ ${helpers.single_keyword_system("font-variant-caps", animation_value_type="discrete", servo_restyle_damage="rebuild_and_reflow")} -${helpers.predefined_type("font-weight", - "FontWeight", - initial_value="computed::FontWeight::normal()", - initial_specified_value="specified::FontWeight::Normal", - animation_value_type="ComputedValue", - flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", - spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight", - servo_restyle_damage="rebuild_and_reflow")} +${helpers.predefined_type( + "font-weight", + "FontWeight", + initial_value="computed::FontWeight::normal()", + initial_specified_value="specified::FontWeight::normal()", + animation_value_type="Number", + flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", + spec="https://drafts.csswg.org/css-fonts/#propdef-font-weight", + servo_restyle_damage="rebuild_and_reflow", +)} ${helpers.predefined_type("font-size", "FontSize", diff --git a/components/style/values/computed/font.rs b/components/style/values/computed/font.rs index c270969a52f..cdc77fe3368 100644 --- a/components/style/values/computed/font.rs +++ b/components/style/values/computed/font.rs @@ -25,20 +25,35 @@ use values::animated::{ToAnimatedValue, ToAnimatedZero}; use values::computed::{Context, Integer, NonNegativeLength, Number, ToComputedValue}; use values::generics::font::{FeatureTagValue, FontSettings}; use values::generics::font::{KeywordInfo as GenericKeywordInfo, VariationValue}; -use values::specified::font as specified; +use values::specified::font::{self as specified, MIN_FONT_WEIGHT, MAX_FONT_WEIGHT}; use values::specified::length::{FontBaseSize, NoCalcLength}; pub use values::computed::Length as MozScriptMinSize; pub use values::specified::font::{FontSynthesis, MozScriptSizeMultiplier, XLang, XTextZoom}; -/// As of CSS Fonts Module Level 3, only the following values are -/// valid: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 +/// A value for the font-weight property per: /// -/// However, system fonts may provide other values. Pango -/// may provide 350, 380, and 1000 (on top of the existing values), for example. -#[derive(Clone, ComputeSquaredDistance, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToCss)] +/// https://drafts.csswg.org/css-fonts-4/#propdef-font-weight +/// +/// This is effectively just a `Number`. +#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, + ToCss)] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] -pub struct FontWeight(pub u16); +pub struct FontWeight(pub Number); + +impl ToAnimatedValue for FontWeight { + type AnimatedValue = Number; + + #[inline] + fn to_animated_value(self) -> Self::AnimatedValue { + self.0 + } + + #[inline] + fn from_animated_value(animated: Self::AnimatedValue) -> Self { + FontWeight(animated.max(MIN_FONT_WEIGHT).min(MAX_FONT_WEIGHT)) + } +} #[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToAnimatedZero, ToCss)] @@ -57,21 +72,12 @@ pub type KeywordInfo = GenericKeywordInfo; impl FontWeight { /// Value for normal pub fn normal() -> Self { - FontWeight(400) + FontWeight(400.) } /// Value for bold pub fn bold() -> Self { - FontWeight(700) - } - - /// Convert from an integer to Weight - pub fn from_int(n: i32) -> Result { - if n >= 100 && n <= 900 && n % 100 == 0 { - Ok(FontWeight(n as u16)) - } else { - Err(()) - } + FontWeight(700.) } /// Convert from an Gecko weight @@ -80,33 +86,39 @@ impl FontWeight { // we allow a wider range of weights than is parseable // because system fonts may provide custom values let weight = unsafe { bindings::Gecko_FontWeight_ToFloat(weight) }; - FontWeight(weight as u16) + FontWeight(weight) } /// Weither this weight is bold pub fn is_bold(&self) -> bool { - self.0 > 500 + self.0 > 500. } - /// Return the bolder weight + /// Return the bolder weight. + /// + /// See the table in: + /// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values pub fn bolder(self) -> Self { - if self.0 < 400 { - FontWeight(400) - } else if self.0 < 600 { - FontWeight(700) + if self.0 < 350. { + FontWeight(400.) + } else if self.0 < 550. { + FontWeight(700.) } else { - FontWeight(900) + FontWeight(self.0.max(900.)) } } - /// Returns the lighter weight + /// Return the lighter weight. + /// + /// See the table in: + /// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values pub fn lighter(self) -> Self { - if self.0 < 600 { - FontWeight(100) - } else if self.0 < 800 { - FontWeight(400) + if self.0 < 550. { + FontWeight(self.0.min(100.)) + } else if self.0 < 750. { + FontWeight(400.) } else { - FontWeight(700) + FontWeight(700.) } } } diff --git a/components/style/values/specified/font.rs b/components/style/values/specified/font.rs index a386a329ac8..3b39f9224b2 100644 --- a/components/style/values/specified/font.rs +++ b/components/style/values/specified/font.rs @@ -27,29 +27,43 @@ use values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX}; const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8; const DEFAULT_SCRIPT_SIZE_MULTIPLIER: f64 = 0.71; -#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss)] -/// A specified font-weight value +/// The minimum font-weight value per: +/// +/// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values +pub const MIN_FONT_WEIGHT: f32 = 1.; + +/// The maximum font-weight value per: +/// +/// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values +pub const MAX_FONT_WEIGHT: f32 = 1000.; + +/// A specified font-weight value. +/// +/// https://drafts.csswg.org/css-fonts-4/#propdef-font-weight +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] pub enum FontWeight { - /// Normal variant - Normal, - /// Bold variant - Bold, + /// `` + Absolute(AbsoluteFontWeight), /// Bolder variant Bolder, /// Lighter variant Lighter, - /// Computed weight variant - Weight(computed::FontWeight), - /// System font varaint + /// System font variant. System(SystemFont), } impl FontWeight { + /// `normal` + #[inline] + pub fn normal() -> Self { + FontWeight::Absolute(AbsoluteFontWeight::Normal) + } + /// Get a specified FontWeight from a gecko keyword pub fn from_gecko_keyword(kw: u32) -> Self { - computed::FontWeight::from_int(kw as i32) - .map(FontWeight::Weight) - .expect("Found unexpected value in style struct for font-weight property") + debug_assert!(kw % 100 == 0); + debug_assert!(kw as f32 <= MAX_FONT_WEIGHT); + FontWeight::Absolute(AbsoluteFontWeight::Weight(Number::new(kw as f32))) } /// Get a specified FontWeight from a SystemFont @@ -69,27 +83,17 @@ impl FontWeight { impl Parse for FontWeight { fn parse<'i, 't>( - _: &ParserContext, + context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result> { - let result = match *input.next()? { - Token::Ident(ref ident) => { - match_ignore_ascii_case! { ident, - "normal" => Ok(FontWeight::Normal), - "bold" => Ok(FontWeight::Bold), - "bolder" => Ok(FontWeight::Bolder), - "lighter" => Ok(FontWeight::Lighter), - _ => Err(()), - } - }, - Token::Number { - int_value: Some(value), - .. - } => computed::FontWeight::from_int(value).map(FontWeight::Weight), - _ => Err(()), - }; + if let Ok(absolute) = input.try(|input| AbsoluteFontWeight::parse(context, input)) { + return Ok(FontWeight::Absolute(absolute)); + } - result.map_err(|_| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) + Ok(try_match_ident_ignore_ascii_case! { input, + "bolder" => FontWeight::Bolder, + "lighter" => FontWeight::Lighter, + }) } } @@ -99,9 +103,7 @@ impl ToComputedValue for FontWeight { #[inline] fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { match *self { - FontWeight::Weight(weight) => weight, - FontWeight::Normal => computed::FontWeight::normal(), - FontWeight::Bold => computed::FontWeight::bold(), + FontWeight::Absolute(ref abs) => abs.compute(), FontWeight::Bolder => context .builder .get_parent_font() @@ -126,7 +128,64 @@ impl ToComputedValue for FontWeight { #[inline] fn from_computed_value(computed: &computed::FontWeight) -> Self { - FontWeight::Weight(*computed) + FontWeight::Absolute(AbsoluteFontWeight::Weight( + Number::from_computed_value(&computed.0) + )) + } +} + +/// An absolute font-weight value for a @font-face rule. +/// +/// https://drafts.csswg.org/css-fonts-4/#font-weight-absolute-values +#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] +pub enum AbsoluteFontWeight { + /// A ``, with the additional constraints specified in: + /// + /// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values + Weight(Number), + /// Normal font weight. Same as 400. + Normal, + /// Bold font weight. Same as 700. + Bold, +} + +impl AbsoluteFontWeight { + /// Returns the computed value for this absolute font weight. + pub fn compute(&self) -> computed::FontWeight { + match *self { + AbsoluteFontWeight::Weight(weight) => { + computed::FontWeight( + weight.get().max(MIN_FONT_WEIGHT).min(MAX_FONT_WEIGHT) + ) + }, + AbsoluteFontWeight::Normal => computed::FontWeight::normal(), + AbsoluteFontWeight::Bold => computed::FontWeight::bold(), + } + } +} + +impl Parse for AbsoluteFontWeight { + fn parse<'i, 't>( + context: &ParserContext, + input: &mut Parser<'i, 't>, + ) -> Result> { + if let Ok(number) = input.try(|input| Number::parse(context, input)) { + // We could add another AllowedNumericType value, but it doesn't + // seem worth it just for a single property with such a weird range, + // so we do the clamping here manually. + if !number.was_calc() && + (number.get() < MIN_FONT_WEIGHT || number.get() > MAX_FONT_WEIGHT) { + return Err(input.new_custom_error( + StyleParseErrorKind::UnspecifiedError + )) + } + return Ok(AbsoluteFontWeight::Weight(number)) + } + + Ok(try_match_ident_ignore_ascii_case! { input, + "normal" => AbsoluteFontWeight::Normal, + "bold" => AbsoluteFontWeight::Bold, + }) } } diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 570651ea2ef..0fa01d23db8 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -201,7 +201,14 @@ impl Number { } } + /// Returns whether this number came from a `calc()` expression. + #[inline] + pub fn was_calc(&self) -> bool { + self.calc_clamping_mode.is_some() + } + /// Returns the numeric value, clamped if needed. + #[inline] pub fn get(&self) -> f32 { self.calc_clamping_mode .map_or(self.value, |mode| mode.clamp(self.value)) diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 3a476640de1..27d3c3093a3 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -5395,10 +5395,9 @@ pub extern "C" fn Servo_ParseFontShorthandForMatching( font_stretch::SpecifiedValue::Keyword(ref kw) => kw, font_stretch::SpecifiedValue::System(_) => return false, }); + match font.font_weight { - FontWeight::Weight(w) => weight.set_from(w), - FontWeight::Normal => weight.set_enum(structs::NS_FONT_WEIGHT_NORMAL as i32), - FontWeight::Bold => weight.set_enum(structs::NS_FONT_WEIGHT_BOLD as i32), + FontWeight::Absolute(w) => weight.set_font_weight(w.compute().0), // Resolve relative font weights against the initial of font-weight // (normal, which is equivalent to 400). FontWeight::Bolder => weight.set_enum(structs::NS_FONT_WEIGHT_BOLD as i32), From c06e3dcd589d5188be70cda9a6c9ef495dc8c78b Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Tue, 13 Feb 2018 17:23:59 -0800 Subject: [PATCH 04/31] style: Pass a bonafide nsACString to Servo. This will allow the Rust code hold a copy-free strong reference to the string past callstack unwind. Bug: 1454460 Reviewed-by: bz MozReview-Commit-ID: HCop9h2abZU --- ports/geckolib/glue.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 27d3c3093a3..8c99a5c5979 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -1130,8 +1130,7 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes( loader: *mut Loader, stylesheet: *mut ServoStyleSheet, load_data: *mut SheetLoadData, - data: *const u8, - data_len: usize, + bytes: *const nsACString, mode: SheetParsingMode, extra_data: *mut URLExtraData, line_number_offset: u32, @@ -1139,7 +1138,7 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes( reusable_sheets: *mut LoaderReusableStyleSheets, ) -> RawServoStyleSheetContentsStrong { let global_style_data = &*GLOBAL_STYLE_DATA; - let input = unsafe { ::std::str::from_utf8_unchecked(::std::slice::from_raw_parts(data, data_len)) }; + let input: &str = unsafe { (*bytes).as_str_unchecked() }; let origin = match mode { SheetParsingMode::eAuthorSheetFeatures => Origin::Author, From dfa019c884ae2a8f1d4109adfd947690098c1d0f Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Wed, 14 Feb 2018 16:39:35 -0800 Subject: [PATCH 05/31] style: Parse sheets on the thread pool. Note that we also drop the dead optional aReusableSheets argument from the async parsing path, since it was always null. Bug: 1346988 Reviewed-by: bz,emilio MozReview-Commit-ID: KddpGFdaqEe --- .../style/gecko_bindings/sugar/refptr.rs | 6 ++ components/style/stylesheets/import_rule.rs | 7 +- ports/geckolib/glue.rs | 68 ++++++++++++-- ports/geckolib/lib.rs | 1 + ports/geckolib/stylesheet_loader.rs | 91 +++++++++++++++++-- 5 files changed, 152 insertions(+), 21 deletions(-) diff --git a/components/style/gecko_bindings/sugar/refptr.rs b/components/style/gecko_bindings/sugar/refptr.rs index 0d8fb817a85..76a7021ef5b 100644 --- a/components/style/gecko_bindings/sugar/refptr.rs +++ b/components/style/gecko_bindings/sugar/refptr.rs @@ -312,3 +312,9 @@ impl_threadsafe_refcount!( Gecko_AddRefSharedFontListArbitraryThread, Gecko_ReleaseSharedFontListArbitraryThread ); + +impl_threadsafe_refcount!( + ::gecko_bindings::structs::SheetLoadDataHolder, + Gecko_AddRefSheetLoadDataHolderArbitraryThread, + Gecko_ReleaseSheetLoadDataHolderArbitraryThread +); diff --git a/components/style/stylesheets/import_rule.rs b/components/style/stylesheets/import_rule.rs index fb50ec69732..576cb31eff3 100644 --- a/components/style/stylesheets/import_rule.rs +++ b/components/style/stylesheets/import_rule.rs @@ -171,10 +171,9 @@ pub struct ImportRule { /// The `` this `@import` rule is loading. pub url: CssUrl, - /// The stylesheet is always present. - /// - /// It contains an empty list of rules and namespace set that is updated - /// when it loads. + /// The stylesheet is always present. However, in the case of gecko async + /// parsing, we don't actually have a Gecko sheet at first, and so the + /// ImportSheet just has stub behavior until it appears. pub stylesheet: ImportSheet, /// The line and column of the rule's source code. diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 8c99a5c5979..77b46fb0ee1 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -6,6 +6,7 @@ use cssparser::{ParseErrorKind, Parser, ParserInput, SourceLocation}; use cssparser::ToCss as ParserToCss; use env_logger::Builder; use malloc_size_of::MallocSizeOfOps; +use nsstring::nsCString; use selectors::{NthIndexCache, SelectorList}; use selectors::matching::{MatchingContext, MatchingMode, matches_selector}; use servo_arc::{Arc, ArcBorrow, RawOffsetArc}; @@ -92,7 +93,8 @@ use style::gecko_bindings::structs; use style::gecko_bindings::structs::{CallerType, CSSPseudoElementType, CompositeOperation}; use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets}; use style::gecko_bindings::structs::{RawServoStyleRule, ComputedStyleStrong, RustString}; -use style::gecko_bindings::structs::{ServoStyleSheet, SheetLoadData, SheetParsingMode, nsAtom, nsCSSPropertyID}; +use style::gecko_bindings::structs::{ServoStyleSheet, SheetLoadData, SheetLoadDataHolder}; +use style::gecko_bindings::structs::{SheetParsingMode, nsAtom, nsCSSPropertyID}; use style::gecko_bindings::structs::{nsCSSFontDesc, nsCSSCounterDesc}; use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint, PropertyValuePair}; use style::gecko_bindings::structs::AtomArray; @@ -145,6 +147,7 @@ use style::stylesheets::{DocumentRule, FontFaceRule, FontFeatureValuesRule, Impo use style::stylesheets::{KeyframesRule, MediaRule, NamespaceRule, Origin, OriginSet, PageRule}; use style::stylesheets::{StyleRule, StylesheetContents, SupportsRule}; use style::stylesheets::StylesheetLoader as StyleStylesheetLoader; +use style::stylesheets::import_rule::ImportSheet; use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframesStepValue}; use style::stylesheets::supports_rule::parse_condition_or_declaration; use style::stylist::{add_size_of_ua_cache, AuthorStylesEnabled, RuleInclusion, Stylist}; @@ -163,7 +166,7 @@ use style::values::specified::gecko::{IntersectionObserverRootMargin, PixelOrPer use style::values::specified::source_size_list::SourceSizeList; use style_traits::{CssWriter, ParsingMode, StyleParseErrorKind, ToCss}; use super::error_reporter::ErrorReporter; -use super::stylesheet_loader::StylesheetLoader; +use super::stylesheet_loader::{AsyncStylesheetParser, StylesheetLoader}; /* * For Gecko->Servo function calls, we need to redeclare the same signature that was declared in @@ -1122,6 +1125,15 @@ pub extern "C" fn Servo_StyleSheet_Empty(mode: SheetParsingMode) -> RawServoStyl ).into_strong() } +fn mode_to_origin(mode: SheetParsingMode) -> Origin { + match mode { + SheetParsingMode::eAuthorSheetFeatures => Origin::Author, + SheetParsingMode::eUserSheetFeatures => Origin::User, + SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent, + SheetParsingMode::eSafeAgentSheetFeatures => Origin::UserAgent, + } +} + /// Note: The load_data corresponds to this sheet, and is passed as the parent /// load data for child sheet loads. It may be null for certain cases where we /// know we won't have child loads. @@ -1140,13 +1152,6 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes( let global_style_data = &*GLOBAL_STYLE_DATA; let input: &str = unsafe { (*bytes).as_str_unchecked() }; - let origin = match mode { - SheetParsingMode::eAuthorSheetFeatures => Origin::Author, - SheetParsingMode::eUserSheetFeatures => Origin::User, - SheetParsingMode::eAgentSheetFeatures => Origin::UserAgent, - SheetParsingMode::eSafeAgentSheetFeatures => Origin::UserAgent, - }; - let reporter = ErrorReporter::new(stylesheet, loader, extra_data); let url_data = unsafe { RefPtr::from_ptr_ref(&extra_data) }; let loader = if loader.is_null() { @@ -1163,12 +1168,44 @@ pub extern "C" fn Servo_StyleSheet_FromUTF8Bytes( Arc::new(StylesheetContents::from_str( - input, url_data.clone(), origin, + input, url_data.clone(), mode_to_origin(mode), &global_style_data.shared_lock, loader, &reporter, quirks_mode.into(), line_number_offset) ).into_strong() } +#[no_mangle] +pub extern "C" fn Servo_StyleSheet_FromUTF8BytesAsync( + load_data: *mut SheetLoadDataHolder, + extra_data: *mut URLExtraData, + bytes: *const nsACString, + mode: SheetParsingMode, + line_number_offset: u32, + quirks_mode: nsCompatibility, +) { + let (load_data, extra_data, bytes) = unsafe { + let mut b = nsCString::new(); + b.assign(&*bytes); + (RefPtr::new(load_data), RefPtr::new(extra_data), b) + }; + let async_parser = AsyncStylesheetParser::new( + load_data, + extra_data, + bytes, + mode_to_origin(mode), + quirks_mode.into(), + line_number_offset + ); + + if let Some(thread_pool) = STYLE_THREAD_POOL.style_thread_pool.as_ref() { + thread_pool.spawn(|| { + async_parser.parse(); + }); + } else { + async_parser.parse(); + } +} + #[no_mangle] pub extern "C" fn Servo_StyleSet_AppendStyleSheet( raw_data: RawServoStyleSetBorrowed, @@ -2051,6 +2088,17 @@ pub extern "C" fn Servo_ImportRule_GetSheet( }) } +#[no_mangle] +pub extern "C" fn Servo_ImportRule_SetSheet( + rule: RawServoImportRuleBorrowed, + sheet: *mut ServoStyleSheet, +) { + write_locked_arc(rule, |rule: &mut ImportRule| { + let sheet = unsafe { GeckoStyleSheet::new(sheet) }; + rule.stylesheet = ImportSheet::new(sheet); + }) +} + #[no_mangle] pub extern "C" fn Servo_Keyframe_GetKeyText( keyframe: RawServoKeyframeBorrowed, diff --git a/ports/geckolib/lib.rs b/ports/geckolib/lib.rs index 80c22e54707..d48a096df64 100644 --- a/ports/geckolib/lib.rs +++ b/ports/geckolib/lib.rs @@ -9,6 +9,7 @@ extern crate env_logger; extern crate libc; #[macro_use] extern crate log; extern crate malloc_size_of; +extern crate nsstring; extern crate selectors; extern crate servo_arc; extern crate smallvec; diff --git a/ports/geckolib/stylesheet_loader.rs b/ports/geckolib/stylesheet_loader.rs index 1dfe30e8bdb..0c320fee897 100644 --- a/ports/geckolib/stylesheet_loader.rs +++ b/ports/geckolib/stylesheet_loader.rs @@ -3,15 +3,24 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use cssparser::SourceLocation; +use nsstring::nsCString; use servo_arc::Arc; +use style::context::QuirksMode; +use style::error_reporting::NullReporter; use style::gecko::data::GeckoStyleSheet; +use style::gecko::global_style_data::GLOBAL_STYLE_DATA; +use style::gecko_bindings::bindings; use style::gecko_bindings::bindings::Gecko_LoadStyleSheet; -use style::gecko_bindings::structs::{Loader, ServoStyleSheet, SheetLoadData, LoaderReusableStyleSheets}; +use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets}; +use style::gecko_bindings::structs::{ServoStyleSheet, SheetLoadData, SheetLoadDataHolder}; +use style::gecko_bindings::structs::URLExtraData; use style::gecko_bindings::sugar::ownership::FFIArcHelpers; +use style::gecko_bindings::sugar::refptr::RefPtr; use style::media_queries::MediaList; use style::parser::ParserContext; use style::shared_lock::{Locked, SharedRwLock}; -use style::stylesheets::{ImportRule, StylesheetLoader as StyleStylesheetLoader}; +use style::stylesheets::{ImportRule, Origin, StylesheetLoader as StyleStylesheetLoader}; +use style::stylesheets::StylesheetContents; use style::stylesheets::import_rule::ImportSheet; use style::values::CssUrl; @@ -41,15 +50,11 @@ impl StyleStylesheetLoader for StylesheetLoader { // so this raw pointer will still be valid. let child_sheet = unsafe { - let (spec_bytes, spec_len) = url.as_slice_components(); - let base_url_data = url.extra_data.get(); Gecko_LoadStyleSheet(self.0, self.1, self.2, self.3, - base_url_data, - spec_bytes, - spec_len as u32, + url.for_ffi(), media.into_strong()) }; @@ -60,3 +65,75 @@ impl StyleStylesheetLoader for StylesheetLoader { Arc::new(lock.wrap(ImportRule { url, source_location, stylesheet })) } } + +pub struct AsyncStylesheetParser { + load_data: RefPtr, + extra_data: RefPtr, + bytes: nsCString, + origin: Origin, + quirks_mode: QuirksMode, + line_number_offset: u32, +} + +impl AsyncStylesheetParser { + pub fn new( + load_data: RefPtr, + extra_data: RefPtr, + bytes: nsCString, + origin: Origin, + quirks_mode: QuirksMode, + line_number_offset: u32, + ) -> Self { + AsyncStylesheetParser { + load_data, + extra_data, + bytes, + origin, + quirks_mode, + line_number_offset, + } + } + + pub fn parse(self) { + let global_style_data = &*GLOBAL_STYLE_DATA; + let input: &str = unsafe { (*self.bytes).as_str_unchecked() }; + + // Note: Parallel CSS parsing doesn't report CSS errors. When errors + // are being logged, Gecko prevents the parallel parsing path from + // running. + let sheet = Arc::new(StylesheetContents::from_str( + input, self.extra_data.clone(), self.origin, + &global_style_data.shared_lock, Some(&self), &NullReporter, + self.quirks_mode.into(), self.line_number_offset) + ); + + unsafe { + bindings::Gecko_StyleSheet_FinishAsyncParse(self.load_data.get(), sheet.into_strong()); + } + } +} + +impl StyleStylesheetLoader for AsyncStylesheetParser { + fn request_stylesheet( + &self, + url: CssUrl, + source_location: SourceLocation, + _context: &ParserContext, + lock: &SharedRwLock, + media: Arc>, + ) -> Arc> { + let stylesheet = ImportSheet::new_pending(self.origin, self.quirks_mode); + let rule = Arc::new(lock.wrap(ImportRule { url: url.clone(), source_location, stylesheet })); + + unsafe { + bindings::Gecko_LoadStyleSheetAsync( + self.load_data.get(), + url.for_ffi(), + media.into_strong(), + rule.clone().into_strong() + ); + } + + rule + } +} From ff9325de5ecb9a341b48adbe1e3a5a21ee69f335 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 11 Apr 2018 13:44:30 +1000 Subject: [PATCH 06/31] style: Use snake_case naming for nsCSSPropertyID of alias as well. Bug: 1452542 Reviewed-by: emilio MozReview-Commit-ID: 242ms8wBDIU --- components/style/properties/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 938b2c2c2bf..327fab9ffd5 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -406,7 +406,7 @@ class Alias(object): return self.enabled_in == "content" def nscsspropertyid(self): - return "nsCSSPropertyID::eCSSPropertyAlias_%s" % self.camel_case + return "nsCSSPropertyID::eCSSPropertyAlias_%s" % self.ident class Method(object): From 2cd06807fa7178db43e720312628257967d972d8 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 11 Apr 2018 13:46:08 +1000 Subject: [PATCH 07/31] style: Have ENABLED_IN flags in nsCSSPropList.h match those in Servo side. Bug: 1452542 Reviewed-by: emilio MozReview-Commit-ID: 48t5u1D5rZX --- components/style/properties/longhand/ui.mako.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/style/properties/longhand/ui.mako.rs b/components/style/properties/longhand/ui.mako.rs index 5f2215760f8..cddc689e6a6 100644 --- a/components/style/properties/longhand/ui.mako.rs +++ b/components/style/properties/longhand/ui.mako.rs @@ -41,19 +41,20 @@ ${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", - enabled_in="chrome", spec="None (Nonstandard internal property)")} +// TODO(bug 1419695) This should be hidden from content. ${helpers.predefined_type("-moz-window-transform", "Transform", "generics::transform::Transform::none()", products="gecko", gecko_ffi_name="mSpecifiedWindowTransform", animation_value_type="ComputedValue", - enabled_in="chrome", spec="None (Nonstandard internal property)")} +// TODO(bug 1419695) This should be hidden from content. ${helpers.predefined_type("-moz-window-transform-origin", "TransformOrigin", "computed::TransformOrigin::initial_value()", @@ -61,7 +62,6 @@ ${helpers.predefined_type("-moz-window-transform-origin", gecko_ffi_name="mWindowTransformOrigin", products="gecko", boxed=True, - enabled_in="chrome", spec="None (Nonstandard internal property)")} // TODO(emilio): Probably also should be hidden from content. From 78f9672b6ce5ad7517c6257224e9ef36eae01c29 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Mon, 16 Apr 2018 14:08:20 +1000 Subject: [PATCH 08/31] style: Generate property list from Servo data. Bug: 1452542 Reviewed-by: emilio,froydnj MozReview-Commit-ID: CwK2oL88r6F --- components/style/properties/build.py | 8 +++++++- components/style/properties/data.py | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/components/style/properties/build.py b/components/style/properties/build.py index 326859ea6d8..04418723ee4 100644 --- a/components/style/properties/build.py +++ b/components/style/properties/build.py @@ -21,7 +21,7 @@ RE_PYTHON_ADDR = re.compile(r'<.+? object at 0x[0-9a-fA-F]+>') def main(): - usage = "Usage: %s [ servo | gecko ] [ style-crate | html ]" % sys.argv[0] + usage = "Usage: %s [ servo | gecko ] [ style-crate | geckolib