mirror of
https://github.com/servo/servo.git
synced 2025-08-09 23:45:35 +01:00
Auto merge of #19211 - KiChjang:text-decoration-line, r=emilio
Move text-decoration-line out of mako Part of #19015. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/19211) <!-- Reviewable:end -->
This commit is contained in:
commit
6f1d9a198f
10 changed files with 172 additions and 147 deletions
|
@ -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};
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue