aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Yeung <kungfukeith11@gmail.com>2017-11-13 23:20:59 -0800
committerKeith Yeung <kungfukeith11@gmail.com>2017-11-14 13:13:23 -0800
commit6f59a45cdc3e675c2e7b1251906f1e5cb5a3dedf (patch)
tree2737754c02aa39339b3a4e27cf188a63f445354f
parentccc739d635b8071e0375fbf6c9fb2eb2366882eb (diff)
downloadservo-6f59a45cdc3e675c2e7b1251906f1e5cb5a3dedf.tar.gz
servo-6f59a45cdc3e675c2e7b1251906f1e5cb5a3dedf.zip
Move text-decoration-line out of mako
-rw-r--r--components/style/macros.rs17
-rw-r--r--components/style/properties/data.py3
-rw-r--r--components/style/properties/helpers.mako.rs4
-rw-r--r--components/style/properties/longhand/text.mako.rs130
-rw-r--r--components/style/properties/properties.mako.rs17
-rw-r--r--components/style/values/computed/mod.rs2
-rw-r--r--components/style/values/computed/text.rs29
-rw-r--r--components/style/values/specified/mod.rs2
-rw-r--r--components/style/values/specified/text.rs109
-rw-r--r--ports/geckolib/glue.rs6
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);