style: Add support for parsing of the CSS text-underline-position property.

Differential Revision: https://phabricator.services.mozilla.com/D54722
This commit is contained in:
Jonathan Kew 2019-12-04 11:39:15 +00:00 committed by Emilio Cobos Álvarez
parent 3bd62cf0cd
commit 51c1dfee2d
No known key found for this signature in database
GPG key ID: E1152D0994E4BF8A
7 changed files with 113 additions and 2 deletions

View file

@ -10,7 +10,8 @@
# "offset-distance",
# "offset-path",
# "offset-rotate",
# "offset"
# "offset",
# "text-underline-position",
COUNTED_UNKNOWN_PROPERTIES = [
"-webkit-font-smoothing",
"-webkit-tap-highlight-color",
@ -40,7 +41,6 @@ COUNTED_UNKNOWN_PROPERTIES = [
"baseline-shift",
"-webkit-hyphenate-character",
"page",
"text-underline-position",
"-webkit-highlight",
"background-repeat-x",
"-webkit-padding-end",

View file

@ -385,6 +385,7 @@ class Longhand(object):
"TextDecorationLine",
"TextEmphasisPosition",
"TextTransform",
"TextUnderlinePosition",
"TouchAction",
"TransformStyle",
"UserSelect",

View file

@ -391,6 +391,18 @@ ${helpers.predefined_type(
spec="https://drafts.csswg.org/css-text-decor-4/#underline-offset",
)}
// text underline position
${helpers.predefined_type(
"text-underline-position",
"TextUnderlinePosition",
"computed::TextUnderlinePosition::AUTO",
engines="gecko",
animation_value_type="discrete",
gecko_pref="layout.css.text-underline-position.enabled",
has_effect_on_gecko_scrollbars=False,
spec="https://drafts.csswg.org/css-text-decor-3/#text-underline-position-property",
)}
// text decoration skip ink
${helpers.predefined_type(
"text-decoration-skip-ink",

View file

@ -79,6 +79,7 @@ pub use self::text::{InitialLetter, LetterSpacing, LineBreak, LineHeight};
pub use self::text::{OverflowWrap, TextOverflow, WordBreak, WordSpacing};
pub use self::text::{TextAlign, TextEmphasisPosition, TextEmphasisStyle};
pub use self::text::{TextDecorationLength, TextDecorationSkipInk};
pub use self::text::TextUnderlinePosition;
pub use self::time::Time;
pub use self::transform::{Rotate, Scale, Transform, TransformOperation};
pub use self::transform::{TransformOrigin, TransformStyle, Translate};

View file

@ -22,6 +22,7 @@ pub use crate::values::specified::TextAlignKeyword as TextAlign;
pub use crate::values::specified::{LineBreak, OverflowWrap, WordBreak};
pub use crate::values::specified::{TextDecorationLine, TextEmphasisPosition};
pub use crate::values::specified::{TextDecorationSkipInk, TextTransform};
pub use crate::values::specified::TextUnderlinePosition;
/// A computed value for the `initial-letter` property.
pub type InitialLetter = GenericInitialLetter<CSSFloat, CSSInteger>;

View file

@ -84,6 +84,7 @@ pub use self::text::{InitialLetter, LetterSpacing, LineBreak, LineHeight, TextAl
pub use self::text::{OverflowWrap, TextEmphasisPosition, TextEmphasisStyle, WordBreak};
pub use self::text::{TextAlignKeyword, TextDecorationLine, TextOverflow, WordSpacing};
pub use self::text::{TextDecorationLength, TextDecorationSkipInk, TextTransform};
pub use self::text::TextUnderlinePosition;
pub use self::time::Time;
pub use self::transform::{Rotate, Scale, Transform};
pub use self::transform::{TransformOrigin, TransformStyle, Translate};

View file

@ -1054,3 +1054,98 @@ impl TextDecorationLength {
matches!(*self, GenericTextDecorationLength::Auto)
}
}
bitflags! {
#[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
#[value_info(other_values = "auto,under,left,right")]
#[repr(C)]
/// Specified keyword values for the text-underline-position property.
/// (Non-exclusive, but not all combinations are allowed: only `under` may occur
/// together with either `left` or `right`.)
/// https://drafts.csswg.org/css-text-decor-3/#text-underline-position-property
pub struct TextUnderlinePosition: u8 {
/// Use automatic positioning below the alphabetic baseline.
const AUTO = 0;
/// Below the glyph box.
const UNDER = 1 << 0;
/// In vertical mode, place to the left of the text.
const LEFT = 1 << 1;
/// In vertical mode, place to the right of the text.
const RIGHT = 1 << 2;
}
}
impl Parse for TextUnderlinePosition {
fn parse<'i, 't>(
_context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<TextUnderlinePosition, ParseError<'i>> {
let mut result = TextUnderlinePosition::empty();
loop {
let location = input.current_source_location();
let ident = match input.next() {
Ok(&Token::Ident(ref ident)) => ident,
Ok(other) => return Err(location.new_unexpected_token_error(other.clone())),
Err(..) => break,
};
match_ignore_ascii_case! { ident,
"auto" if result.is_empty() => {
return Ok(result);
},
"under" if !result.intersects(TextUnderlinePosition::UNDER) => {
result.insert(TextUnderlinePosition::UNDER);
},
"left" if !result.intersects(TextUnderlinePosition::LEFT |
TextUnderlinePosition::RIGHT) => {
result.insert(TextUnderlinePosition::LEFT);
},
"right" if !result.intersects(TextUnderlinePosition::LEFT |
TextUnderlinePosition::RIGHT) => {
result.insert(TextUnderlinePosition::RIGHT);
},
_ => return Err(location.new_custom_error(
SelectorParseErrorKind::UnexpectedIdent(ident.clone())
)),
}
}
if !result.is_empty() {
Ok(result)
} else {
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
}
}
}
impl ToCss for TextUnderlinePosition {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
if self.is_empty() {
return dest.write_str("auto");
}
let mut writer = SequenceWriter::new(dest, " ");
let mut any = false;
macro_rules! maybe_write {
($ident:ident => $str:expr) => {
if self.contains(TextUnderlinePosition::$ident) {
any = true;
writer.raw_item($str)?;
}
};
}
maybe_write!(UNDER => "under");
maybe_write!(LEFT => "left");
maybe_write!(RIGHT => "right");
debug_assert!(any);
Ok(())
}
}