diff options
author | Keith Yeung <kungfukeith11@gmail.com> | 2017-11-13 23:20:59 -0800 |
---|---|---|
committer | Keith Yeung <kungfukeith11@gmail.com> | 2017-11-14 13:13:23 -0800 |
commit | 6f59a45cdc3e675c2e7b1251906f1e5cb5a3dedf (patch) | |
tree | 2737754c02aa39339b3a4e27cf188a63f445354f | |
parent | ccc739d635b8071e0375fbf6c9fb2eb2366882eb (diff) | |
download | servo-6f59a45cdc3e675c2e7b1251906f1e5cb5a3dedf.tar.gz servo-6f59a45cdc3e675c2e7b1251906f1e5cb5a3dedf.zip |
Move text-decoration-line out of mako
-rw-r--r-- | components/style/macros.rs | 17 | ||||
-rw-r--r-- | components/style/properties/data.py | 3 | ||||
-rw-r--r-- | components/style/properties/helpers.mako.rs | 4 | ||||
-rw-r--r-- | components/style/properties/longhand/text.mako.rs | 130 | ||||
-rw-r--r-- | components/style/properties/properties.mako.rs | 17 | ||||
-rw-r--r-- | components/style/values/computed/mod.rs | 2 | ||||
-rw-r--r-- | components/style/values/computed/text.rs | 29 | ||||
-rw-r--r-- | components/style/values/specified/mod.rs | 2 | ||||
-rw-r--r-- | components/style/values/specified/text.rs | 109 | ||||
-rw-r--r-- | ports/geckolib/glue.rs | 6 |
10 files changed, 172 insertions, 147 deletions
diff --git a/components/style/macros.rs b/components/style/macros.rs index 200fd61a8c4..c614a2292ca 100644 --- a/components/style/macros.rs +++ b/components/style/macros.rs @@ -124,3 +124,20 @@ macro_rules! define_keyword_type { impl $crate::values::animated::AnimatedValueAsComputed for $name {} }; } + +#[cfg(feature = "gecko")] +macro_rules! impl_bitflags_conversions { + ($name: ident) => { + impl From<u8> for $name { + fn from(bits: u8) -> $name { + $name::from_bits(bits).expect("bits contain valid flag") + } + } + + impl From<$name> for u8 { + fn from(v: $name) -> u8 { + v.bits() + } + } + }; +} diff --git a/components/style/properties/data.py b/components/style/properties/data.py index 2ba16b710e8..8f35cf4150a 100644 --- a/components/style/properties/data.py +++ b/components/style/properties/data.py @@ -147,7 +147,7 @@ def arg_to_bool(arg): class Longhand(object): def __init__(self, style_struct, name, spec=None, animation_value_type=None, derived_from=None, keyword=None, predefined_type=None, custom_cascade=False, experimental=False, internal=False, - need_index=False, gecko_ffi_name=None, + need_index=False, custom_cascade_function=None, gecko_ffi_name=None, allowed_in_keyframe_block=True, cast_type='u8', logical=False, alias=None, extra_prefixes=None, boxed=False, flags=None, allowed_in_page_rule=False, allow_quirks=False, ignored_when_colors_disabled=False, @@ -163,6 +163,7 @@ class Longhand(object): self.style_struct = style_struct self.experimental = ("layout.%s.enabled" % name) if experimental else None self.custom_cascade = custom_cascade + self.custom_cascade_function = custom_cascade_function if custom_cascade else None self.internal = internal self.need_index = need_index self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index 1d4358bb120..27d0cb907db 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -394,7 +394,9 @@ } } - % if property.custom_cascade: + % if property.custom_cascade and property.custom_cascade_function: + ${property.custom_cascade_function}(declaration, context); + % elif property.custom_cascade: cascade_property_custom(declaration, context); % endif % else: diff --git a/components/style/properties/longhand/text.mako.rs b/components/style/properties/longhand/text.mako.rs index c43fe99fd13..f4e485eb363 100644 --- a/components/style/properties/longhand/text.mako.rs +++ b/components/style/properties/longhand/text.mako.rs @@ -25,127 +25,15 @@ ${helpers.single_keyword("unicode-bidi", animation_value_type="discrete", spec="https://drafts.csswg.org/css-writing-modes/#propdef-unicode-bidi")} -<%helpers:longhand name="text-decoration-line" - custom_cascade="${product == 'servo'}" - animation_value_type="discrete" - flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", - spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-line"> - use std::fmt; - use style_traits::ToCss; - - bitflags! { - #[derive(MallocSizeOf, ToComputedValue)] - pub struct SpecifiedValue: u8 { - const NONE = 0; - const UNDERLINE = 0x01; - const OVERLINE = 0x02; - const LINE_THROUGH = 0x04; - const BLINK = 0x08; - % if product == "gecko": - /// Only set by presentation attributes - /// - /// Setting this will mean that text-decorations use the color - /// specified by `color` in quirks mode. - /// - /// For example, this gives <a href=foo><font color="red">text</font></a> - /// a red text decoration - const COLOR_OVERRIDE = 0x10; - % endif - } - } - - impl ToCss for SpecifiedValue { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - let mut has_any = false; - - macro_rules! write_value { - ($line:path => $css:expr) => { - if self.contains($line) { - if has_any { - dest.write_str(" ")?; - } - dest.write_str($css)?; - has_any = true; - } - } - } - write_value!(SpecifiedValue::UNDERLINE => "underline"); - write_value!(SpecifiedValue::OVERLINE => "overline"); - write_value!(SpecifiedValue::LINE_THROUGH => "line-through"); - write_value!(SpecifiedValue::BLINK => "blink"); - if !has_any { - dest.write_str("none")?; - } - - Ok(()) - } - } - pub mod computed_value { - pub type T = super::SpecifiedValue; - #[allow(non_upper_case_globals)] - pub const none: T = super::SpecifiedValue { - bits: 0 - }; - } - #[inline] pub fn get_initial_value() -> computed_value::T { - computed_value::none - } - #[inline] - pub fn get_initial_specified_value() -> SpecifiedValue { - SpecifiedValue::empty() - } - /// none | [ underline || overline || line-through || blink ] - pub fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) - -> Result<SpecifiedValue, ParseError<'i>> { - let mut result = SpecifiedValue::empty(); - if input.try(|input| input.expect_ident_matching("none")).is_ok() { - return Ok(result) - } - let mut empty = true; - - loop { - let result: Result<_, ParseError> = input.try(|input| { - let location = input.current_source_location(); - match input.expect_ident() { - Ok(ident) => { - (match_ignore_ascii_case! { &ident, - "underline" => if result.contains(SpecifiedValue::UNDERLINE) { Err(()) } - else { empty = false; result.insert(SpecifiedValue::UNDERLINE); Ok(()) }, - "overline" => if result.contains(SpecifiedValue::OVERLINE) { Err(()) } - else { empty = false; result.insert(SpecifiedValue::OVERLINE); Ok(()) }, - "line-through" => if result.contains(SpecifiedValue::LINE_THROUGH) { Err(()) } - else { - empty = false; - result.insert(SpecifiedValue::LINE_THROUGH); Ok(()) - }, - "blink" => if result.contains(SpecifiedValue::BLINK) { Err(()) } - else { empty = false; result.insert(SpecifiedValue::BLINK); Ok(()) }, - _ => Err(()) - }).map_err(|()| { - location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())) - }) - } - Err(e) => return Err(e.into()) - } - }); - if result.is_err() { - break; - } - } - - if !empty { Ok(result) } else { Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) } - } - - % if product == "servo": - fn cascade_property_custom(_declaration: &PropertyDeclaration, - context: &mut computed::Context) { - longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(context); - } - % endif - - #[cfg(feature = "gecko")] - impl_bitflags_conversions!(SpecifiedValue); -</%helpers:longhand> +${helpers.predefined_type("text-decoration-line", + "TextDecorationLine", + "specified::TextDecorationLine::none()", + initial_specified_value="specified::TextDecorationLine::none()", + custom_cascade= product == 'servo', + custom_cascade_function="specified::TextDecorationLine::cascade_property_custom", + animation_value_type="discrete", + flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", + spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-line")} ${helpers.single_keyword("text-decoration-style", "solid double dotted dashed wavy -moz-none", diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index bd3ee49c298..8dcb484df71 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -56,23 +56,6 @@ macro_rules! property_name { ($s: tt) => { atom!($s) } } -#[cfg(feature = "gecko")] -macro_rules! impl_bitflags_conversions { - ($name: ident) => { - impl From<u8> for $name { - fn from(bits: u8) -> $name { - $name::from_bits(bits).expect("bits contain valid flag") - } - } - - impl From<$name> for u8 { - fn from(v: $name) -> u8 { - v.bits() - } - } - }; -} - <%! from data import Method, Keyword, to_rust_ident, to_camel_case, SYSTEM_FONT_LONGHANDS import os.path diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index bf3bbf712c5..07b079aade0 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -47,7 +47,7 @@ pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, pub use self::gecko::ScrollSnapPoint; pub use self::rect::LengthOrNumberRect; pub use super::{Auto, Either, None_}; -pub use super::specified::BorderStyle; +pub use super::specified::{BorderStyle, TextDecorationLine}; pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNone, LengthOrNumber, LengthOrPercentage}; pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength}; pub use self::length::{CSSPixelLength, NonNegativeLength, NonNegativeLengthOrPercentage}; diff --git a/components/style/values/computed/text.rs b/components/style/values/computed/text.rs index 4c724f7e418..b488f1eacc5 100644 --- a/components/style/values/computed/text.rs +++ b/components/style/values/computed/text.rs @@ -13,7 +13,7 @@ use values::computed::length::{Length, LengthOrPercentage}; use values::generics::text::InitialLetter as GenericInitialLetter; use values::generics::text::LineHeight as GenericLineHeight; use values::generics::text::Spacing; -use values::specified::text::TextOverflowSide; +use values::specified::text::{TextOverflowSide, TextDecorationLine}; /// A computed value for the `initial-letter` property. pub type InitialLetter = GenericInitialLetter<CSSFloat, CSSInteger>; @@ -74,3 +74,30 @@ impl ToCss for TextOverflow { Ok(()) } } + +impl ToCss for TextDecorationLine { + fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + let mut has_any = false; + + macro_rules! write_value { + ($line:path => $css:expr) => { + if self.contains($line) { + if has_any { + dest.write_str(" ")?; + } + dest.write_str($css)?; + has_any = true; + } + } + } + write_value!(TextDecorationLine::UNDERLINE => "underline"); + write_value!(TextDecorationLine::OVERLINE => "overline"); + write_value!(TextDecorationLine::LINE_THROUGH => "line-through"); + write_value!(TextDecorationLine::BLINK => "blink"); + if !has_any { + dest.write_str("none")?; + } + + Ok(()) + } +} diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 3827b638e4b..ddf0a0f4aaa 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -51,7 +51,7 @@ pub use self::percentage::Percentage; pub use self::position::{Position, PositionComponent}; pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth}; pub use self::table::XSpan; -pub use self::text::{InitialLetter, LetterSpacing, LineHeight, TextOverflow, WordSpacing}; +pub use self::text::{InitialLetter, LetterSpacing, LineHeight, TextDecorationLine, TextOverflow, WordSpacing}; pub use self::time::Time; pub use self::transform::{TimingFunction, Transform, TransformOrigin}; pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent; diff --git a/components/style/values/specified/text.rs b/components/style/values/specified/text.rs index 251bb1861b8..e9d19a772ea 100644 --- a/components/style/values/specified/text.rs +++ b/components/style/values/specified/text.rs @@ -6,9 +6,11 @@ use cssparser::{Parser, Token}; use parser::{Parse, ParserContext}; +#[cfg(feature = "servo")] +use properties::{longhands, PropertyDeclaration}; use selectors::parser::SelectorParseErrorKind; #[allow(unused_imports)] use std::ascii::AsciiExt; -use style_traits::ParseError; +use style_traits::{ParseError, StyleParseErrorKind}; use values::computed::{Context, ToComputedValue}; use values::computed::text::LineHeight as ComputedLineHeight; use values::computed::text::TextOverflow as ComputedTextOverflow; @@ -242,3 +244,108 @@ impl ToComputedValue for TextOverflow { } } } + +bitflags! { + #[derive(MallocSizeOf, ToComputedValue)] + /// Specified keyword values for the text-decoration-line property. + pub struct TextDecorationLine: u8 { + /// No text decoration line is specified + const NONE = 0; + /// Underline + const UNDERLINE = 0x01; + /// Overline + const OVERLINE = 0x02; + /// Line through + const LINE_THROUGH = 0x04; + /// Blink + const BLINK = 0x08; + #[cfg(feature = "gecko")] + /// Only set by presentation attributes + /// + /// Setting this will mean that text-decorations use the color + /// specified by `color` in quirks mode. + /// + /// For example, this gives <a href=foo><font color="red">text</font></a> + /// a red text decoration + const COLOR_OVERRIDE = 0x10; + } +} + +#[cfg(feature = "gecko")] +impl_bitflags_conversions!(TextDecorationLine); + +impl TextDecorationLine { + #[inline] + /// Returns the initial value of text-decoration-line + pub fn none() -> Self { + TextDecorationLine::NONE + } + + #[cfg(feature = "servo")] + #[inline] + /// Custom cascade for the text-decoration-line property in servo + pub fn cascade_property_custom(_declaration: &PropertyDeclaration, context: &mut Context) { + longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(context); + } +} + +impl Parse for TextDecorationLine { + /// none | [ underline || overline || line-through || blink ] + fn parse<'i, 't>( + _context: &ParserContext, + input: &mut Parser<'i, 't> + ) -> Result<TextDecorationLine, ParseError<'i>> { + let mut result = TextDecorationLine::NONE; + if input.try(|input| input.expect_ident_matching("none")).is_ok() { + return Ok(result) + } + + loop { + let result: Result<_, ParseError> = input.try(|input| { + try_match_ident_ignore_ascii_case! { input, + "underline" => { + if result.contains(TextDecorationLine::UNDERLINE) { + Err(()) + } else { + result.insert(TextDecorationLine::UNDERLINE); + Ok(()) + } + } + "overline" => { + if result.contains(TextDecorationLine::OVERLINE) { + Err(()) + } else { + result.insert(TextDecorationLine::OVERLINE); + Ok(()) + } + } + "line-through" => { + if result.contains(TextDecorationLine::LINE_THROUGH) { + Err(()) + } else { + result.insert(TextDecorationLine::LINE_THROUGH); + Ok(()) + } + } + "blink" => { + if result.contains(TextDecorationLine::BLINK) { + Err(()) + } else { + result.insert(TextDecorationLine::BLINK); + Ok(()) + } + } + } + }); + if result.is_err() { + break; + } + } + + if !result.is_empty() { + Ok(result) + } else { + Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) + } + } +} diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 04ff917fa1e..295c4aa7a75 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -3371,10 +3371,10 @@ pub extern "C" fn Servo_DeclarationBlock_SetTextDecorationColorOverride( declarations: RawServoDeclarationBlockBorrowed, ) { use style::properties::PropertyDeclaration; - use style::properties::longhands::text_decoration_line; + use style::values::specified::text::TextDecorationLine; - let mut decoration = text_decoration_line::computed_value::none; - decoration |= text_decoration_line::SpecifiedValue::COLOR_OVERRIDE; + let mut decoration = TextDecorationLine::none(); + decoration |= TextDecorationLine::COLOR_OVERRIDE; let decl = PropertyDeclaration::TextDecorationLine(decoration); write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| { decls.push(decl, Importance::Normal, DeclarationSource::CssOm); |