mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
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:
parent
3bd62cf0cd
commit
51c1dfee2d
7 changed files with 113 additions and 2 deletions
|
@ -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",
|
||||
|
|
|
@ -385,6 +385,7 @@ class Longhand(object):
|
|||
"TextDecorationLine",
|
||||
"TextEmphasisPosition",
|
||||
"TextTransform",
|
||||
"TextUnderlinePosition",
|
||||
"TouchAction",
|
||||
"TransformStyle",
|
||||
"UserSelect",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue