/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
usecrate::derives::*; usecrate::parser::{Parse, ParserContext}; use cssparser::Parser; use std::fmt::{self, Write}; use style_traits::{CssWriter, KeywordsCollectFn, ParseError, SpecifiedValueInfo, ToCss};
/// Mask for the additional flags above. const FLAG_BITS = 0b11100000;
}
}
impl AlignFlags { /// Returns the enumeration value stored in the lower 5 bits. #[inline] pubfn value(&self) -> Self {
*self & !AlignFlags::FLAG_BITS
}
/// Returns an updated value with the same flags. #[inline] pubfn with_value(&self, value: AlignFlags) -> Self {
debug_assert!(!value.intersects(Self::FLAG_BITS));
value | self.flags()
}
/// Returns the flags stored in the upper 3 bits. #[inline] pubfn flags(&self) -> Self {
*self & AlignFlags::FLAG_BITS
}
}
impl ToCss for AlignFlags { fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where
W: Write,
{ let flags = self.flags(); let value = self.value(); match flags {
AlignFlags::LEGACY => {
dest.write_str("legacy")?; if value.is_empty() { return Ok(());
}
dest.write_char(' ')?;
},
AlignFlags::SAFE => dest.write_str("safe ")?,
AlignFlags::UNSAFE => dest.write_str("unsafe ")?,
_ => {
debug_assert_eq!(flags, AlignFlags::empty());
},
}
/// The initial value 'normal' #[inline] pubfn new(primary: AlignFlags) -> Self { Self { primary }
}
/// Returns whether this value is a <baseline-position>. pubfn is_baseline_position(&self) -> bool {
matches!( self.primary.value(),
AlignFlags::BASELINE | AlignFlags::LAST_BASELINE
)
}
/// Parse a value for align-content pubfn parse_block<'i>(
_: &ParserContext,
input: &mut Parser<'i, '_>,
) -> Result<Self, ParseError<'i>> { Self::parse(input, AxisDirection::Block)
}
/// Parse a value for justify-content pubfn parse_inline<'i>(
_: &ParserContext,
input: &mut Parser<'i, '_>,
) -> Result<Self, ParseError<'i>> { Self::parse(input, AxisDirection::Inline)
}
fn parse<'i, 't>(
input: &mut Parser<'i, 't>,
axis: AxisDirection,
) -> Result<Self, ParseError<'i>> { // NOTE Please also update the `list_keywords` function below // when this function is updated.
// Try to parse normal first if input
.try_parse(|i| i.expect_ident_matching("normal"))
.is_ok()
{ return Ok(ContentDistribution::normal());
}
// Parse <baseline-position>, but only on the block axis. if axis == AxisDirection::Block { iflet Ok(value) = input.try_parse(parse_baseline) { return Ok(ContentDistribution::new(value));
}
}
impl SpecifiedValueInfo for ContentDistribution { fn collect_completion_keywords(f: KeywordsCollectFn) {
f(&["normal"]);
list_baseline_keywords(f); // block-axis only
list_content_distribution_keywords(f);
list_overflow_position_keywords(f);
f(&["start", "end", "flex-start", "flex-end", "center"]);
f(&["left", "right"]); // inline-axis only
}
}
/// The specified value of the {align,justify}-self properties. /// /// <https://drafts.csswg.org/css-align/#self-alignment> /// <https://drafts.csswg.org/css-align/#propdef-align-self> #[derive(
Clone,
Copy,
Debug,
Deref,
Eq,
MallocSizeOf,
PartialEq,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
ToTyped,
)] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[repr(C)] #[typed(todo_derive_fields)] pubstruct SelfAlignment(pub AlignFlags);
impl SelfAlignment { /// The initial value 'auto' #[inline] pubfn auto() -> Self {
SelfAlignment(AlignFlags::AUTO)
}
/// Returns whether this value is valid for both axis directions. pubfn is_valid_on_both_axes(&self) -> bool { matchself.0.value() { // left | right are only allowed on the inline axis.
AlignFlags::LEFT | AlignFlags::RIGHT => false,
/// Parse a self-alignment value on one of the axes. fn parse<'i, 't>(
input: &mut Parser<'i, 't>,
axis: AxisDirection,
) -> Result<Self, ParseError<'i>> { // NOTE Please also update the `list_keywords` function below // when this function is updated.
// <baseline-position> // // It's weird that this accepts <baseline-position>, but not // justify-content... iflet Ok(value) = input.try_parse(parse_baseline) { return Ok(SelfAlignment(value));
}
// auto | normal | stretch iflet Ok(value) = input.try_parse(parse_auto_normal_stretch) { return Ok(SelfAlignment(value));
}
// <overflow-position>? <self-position> let overflow_position = input
.try_parse(parse_overflow_position)
.unwrap_or(AlignFlags::empty()); let self_position = parse_self_position(input, axis)?;
Ok(SelfAlignment(overflow_position | self_position))
}
/// Performs a flip of the position, that is, for self-start we return self-end, for left /// we return right, etc. pubfn flip_position(self) -> Self { let flipped_value = matchself.0.value() {
AlignFlags::START => AlignFlags::END,
AlignFlags::END => AlignFlags::START,
AlignFlags::FLEX_START => AlignFlags::FLEX_END,
AlignFlags::FLEX_END => AlignFlags::FLEX_START,
AlignFlags::LEFT => AlignFlags::RIGHT,
AlignFlags::RIGHT => AlignFlags::LEFT,
AlignFlags::SELF_START => AlignFlags::SELF_END,
AlignFlags::SELF_END => AlignFlags::SELF_START,
impl SpecifiedValueInfo for SelfAlignment { fn collect_completion_keywords(f: KeywordsCollectFn) { // TODO: This technically lists left/right for align-self. Not amazing but also not sure // worth fixing here, could be special-cased on the caller. Self::list_keywords(f, AxisDirection::Block);
}
}
/// Value of the `align-items` and `justify-items` properties /// /// <https://drafts.csswg.org/css-align/#propdef-align-items> /// <https://drafts.csswg.org/css-align/#propdef-justify-items> #[derive(
Clone,
Copy,
Debug,
Deref,
Eq,
MallocSizeOf,
PartialEq,
ToComputedValue,
ToCss,
ToResolvedValue,
ToShmem,
ToTyped,
)] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] #[repr(C)] #[typed(todo_derive_fields)] pubstruct ItemPlacement(pub AlignFlags);
impl ItemPlacement { /// The value 'normal' #[inline] pubfn normal() -> Self { Self(AlignFlags::NORMAL)
}
}
impl ItemPlacement { /// Parse a value for align-items pubfn parse_block<'i>(
_: &ParserContext,
input: &mut Parser<'i, '_>,
) -> Result<Self, ParseError<'i>> { Self::parse(input, AxisDirection::Block)
}
/// Parse a value for justify-items pubfn parse_inline<'i>(
_: &ParserContext,
input: &mut Parser<'i, '_>,
) -> Result<Self, ParseError<'i>> { Self::parse(input, AxisDirection::Inline)
}
fn parse<'i, 't>(
input: &mut Parser<'i, 't>,
axis: AxisDirection,
) -> Result<Self, ParseError<'i>> { // NOTE Please also update `impl SpecifiedValueInfo` below when // this function is updated.
// normal | stretch fn parse_normal_stretch<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> { // NOTE Please also update the `list_normal_stretch` function below // when this function is updated.
try_match_ident_ignore_ascii_case! { input, "normal" => Ok(AlignFlags::NORMAL), "stretch" => Ok(AlignFlags::STRETCH),
}
}
if static_prefs::pref!("layout.css.anchor-positioning.enabled") {
f(&["anchor-center"]);
}
if axis == AxisDirection::Inline {
f(&["left", "right"]);
}
}
fn parse_left_right_center<'i, 't>(
input: &mut Parser<'i, 't>,
) -> Result<AlignFlags, ParseError<'i>> { // NOTE Please also update the `list_legacy_keywords` function below // when this function is updated.
Ok(try_match_ident_ignore_ascii_case! { input, "left" => AlignFlags::LEFT, "right" => AlignFlags::RIGHT, "center" => AlignFlags::CENTER,
})
}
// legacy | [ legacy && [ left | right | center ] ] fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseError<'i>> { // NOTE Please also update the `list_legacy_keywords` function below // when this function is updated. let flags = try_match_ident_ignore_ascii_case! { input, "legacy" => { let flags = input.try_parse(parse_left_right_center)
.unwrap_or(AlignFlags::empty());
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.