mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +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
|
@ -124,3 +124,20 @@ macro_rules! define_keyword_type {
|
||||||
impl $crate::values::animated::AnimatedValueAsComputed for $name {}
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ def arg_to_bool(arg):
|
||||||
class Longhand(object):
|
class Longhand(object):
|
||||||
def __init__(self, style_struct, name, spec=None, animation_value_type=None, derived_from=None, keyword=None,
|
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,
|
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',
|
allowed_in_keyframe_block=True, cast_type='u8',
|
||||||
logical=False, alias=None, extra_prefixes=None, boxed=False,
|
logical=False, alias=None, extra_prefixes=None, boxed=False,
|
||||||
flags=None, allowed_in_page_rule=False, allow_quirks=False, ignored_when_colors_disabled=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.style_struct = style_struct
|
||||||
self.experimental = ("layout.%s.enabled" % name) if experimental else None
|
self.experimental = ("layout.%s.enabled" % name) if experimental else None
|
||||||
self.custom_cascade = custom_cascade
|
self.custom_cascade = custom_cascade
|
||||||
|
self.custom_cascade_function = custom_cascade_function if custom_cascade else None
|
||||||
self.internal = internal
|
self.internal = internal
|
||||||
self.need_index = need_index
|
self.need_index = need_index
|
||||||
self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case
|
self.gecko_ffi_name = gecko_ffi_name or "m" + self.camel_case
|
||||||
|
|
|
@ -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);
|
cascade_property_custom(declaration, context);
|
||||||
% endif
|
% endif
|
||||||
% else:
|
% else:
|
||||||
|
|
|
@ -25,127 +25,15 @@ ${helpers.single_keyword("unicode-bidi",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
spec="https://drafts.csswg.org/css-writing-modes/#propdef-unicode-bidi")}
|
spec="https://drafts.csswg.org/css-writing-modes/#propdef-unicode-bidi")}
|
||||||
|
|
||||||
<%helpers:longhand name="text-decoration-line"
|
${helpers.predefined_type("text-decoration-line",
|
||||||
custom_cascade="${product == 'servo'}"
|
"TextDecorationLine",
|
||||||
animation_value_type="discrete"
|
"specified::TextDecorationLine::none()",
|
||||||
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
initial_specified_value="specified::TextDecorationLine::none()",
|
||||||
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-line">
|
custom_cascade= product == 'servo',
|
||||||
use std::fmt;
|
custom_cascade_function="specified::TextDecorationLine::cascade_property_custom",
|
||||||
use style_traits::ToCss;
|
animation_value_type="discrete",
|
||||||
|
flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
|
||||||
bitflags! {
|
spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-line")}
|
||||||
#[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.single_keyword("text-decoration-style",
|
${helpers.single_keyword("text-decoration-style",
|
||||||
"solid double dotted dashed wavy -moz-none",
|
"solid double dotted dashed wavy -moz-none",
|
||||||
|
|
|
@ -56,23 +56,6 @@ macro_rules! property_name {
|
||||||
($s: tt) => { atom!($s) }
|
($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
|
from data import Method, Keyword, to_rust_ident, to_camel_case, SYSTEM_FONT_LONGHANDS
|
||||||
import os.path
|
import os.path
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection,
|
||||||
pub use self::gecko::ScrollSnapPoint;
|
pub use self::gecko::ScrollSnapPoint;
|
||||||
pub use self::rect::LengthOrNumberRect;
|
pub use self::rect::LengthOrNumberRect;
|
||||||
pub use super::{Auto, Either, None_};
|
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::{CalcLengthOrPercentage, Length, LengthOrNone, LengthOrNumber, LengthOrPercentage};
|
||||||
pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength};
|
pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength};
|
||||||
pub use self::length::{CSSPixelLength, NonNegativeLength, NonNegativeLengthOrPercentage};
|
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::InitialLetter as GenericInitialLetter;
|
||||||
use values::generics::text::LineHeight as GenericLineHeight;
|
use values::generics::text::LineHeight as GenericLineHeight;
|
||||||
use values::generics::text::Spacing;
|
use values::generics::text::Spacing;
|
||||||
use values::specified::text::TextOverflowSide;
|
use values::specified::text::{TextOverflowSide, TextDecorationLine};
|
||||||
|
|
||||||
/// A computed value for the `initial-letter` property.
|
/// A computed value for the `initial-letter` property.
|
||||||
pub type InitialLetter = GenericInitialLetter<CSSFloat, CSSInteger>;
|
pub type InitialLetter = GenericInitialLetter<CSSFloat, CSSInteger>;
|
||||||
|
@ -74,3 +74,30 @@ impl ToCss for TextOverflow {
|
||||||
Ok(())
|
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::position::{Position, PositionComponent};
|
||||||
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth};
|
pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind, SVGStrokeDashArray, SVGWidth};
|
||||||
pub use self::table::XSpan;
|
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::time::Time;
|
||||||
pub use self::transform::{TimingFunction, Transform, TransformOrigin};
|
pub use self::transform::{TimingFunction, Transform, TransformOrigin};
|
||||||
pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
|
pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent;
|
||||||
|
|
|
@ -6,9 +6,11 @@
|
||||||
|
|
||||||
use cssparser::{Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
|
#[cfg(feature = "servo")]
|
||||||
|
use properties::{longhands, PropertyDeclaration};
|
||||||
use selectors::parser::SelectorParseErrorKind;
|
use selectors::parser::SelectorParseErrorKind;
|
||||||
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
#[allow(unused_imports)] use std::ascii::AsciiExt;
|
||||||
use style_traits::ParseError;
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
use values::computed::{Context, ToComputedValue};
|
use values::computed::{Context, ToComputedValue};
|
||||||
use values::computed::text::LineHeight as ComputedLineHeight;
|
use values::computed::text::LineHeight as ComputedLineHeight;
|
||||||
use values::computed::text::TextOverflow as ComputedTextOverflow;
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3373,10 +3373,10 @@ pub extern "C" fn Servo_DeclarationBlock_SetTextDecorationColorOverride(
|
||||||
declarations: RawServoDeclarationBlockBorrowed,
|
declarations: RawServoDeclarationBlockBorrowed,
|
||||||
) {
|
) {
|
||||||
use style::properties::PropertyDeclaration;
|
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;
|
let mut decoration = TextDecorationLine::none();
|
||||||
decoration |= text_decoration_line::SpecifiedValue::COLOR_OVERRIDE;
|
decoration |= TextDecorationLine::COLOR_OVERRIDE;
|
||||||
let decl = PropertyDeclaration::TextDecorationLine(decoration);
|
let decl = PropertyDeclaration::TextDecorationLine(decoration);
|
||||||
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
write_locked_arc(declarations, |decls: &mut PropertyDeclarationBlock| {
|
||||||
decls.push(decl, Importance::Normal, DeclarationSource::CssOm);
|
decls.push(decl, Importance::Normal, DeclarationSource::CssOm);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue