render: honor item self alignment
This commit is contained in:
1 parent
c333619703
commit
ba92928ff5
2 files changed
+96
No files matched your search
@@ -287,6 +287,8 @@ pub struct LayoutStyle {
|
||||
/// one field for both made `text-align:left` shrink-wrap flex children.
|
||||
pub text_align: Option<taffy::AlignItems>,
|
||||
pub align_items: Option<taffy::AlignItems>,
|
||||
pub align_self: Option<taffy::AlignSelf>,
|
||||
pub justify_self: Option<taffy::JustifySelf>,
|
||||
pub flex_direction: Option<taffy::FlexDirection>,
|
||||
pub flex_wrap: Option<taffy::FlexWrap>,
|
||||
pub justify_content: Option<taffy::JustifyContent>,
|
||||
@@ -717,6 +719,8 @@ pub(crate) fn to_taffy_style(style: &LayoutStyle) -> Style {
|
||||
// `align-items` has no effect on a block formatting context.
|
||||
s.align_items = None;
|
||||
}
|
||||
s.align_self = style.align_self;
|
||||
s.justify_self = style.justify_self;
|
||||
if let Some(jc) = style.justify_content {
|
||||
s.justify_content = Some(jc);
|
||||
}
|
||||
|
||||
@@ -431,6 +431,22 @@ fn apply_value(style: &mut LayoutStyle, name: &str, value: &str) {
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
"align-self" => {
|
||||
if let Some(value) = self_alignment_value(value) {
|
||||
style.align_self = value;
|
||||
}
|
||||
},
|
||||
"justify-self" => {
|
||||
if let Some(value) = self_alignment_value(value) {
|
||||
style.justify_self = value;
|
||||
}
|
||||
},
|
||||
"place-self" => {
|
||||
if let Some((align, justify)) = self_alignment_pair(value) {
|
||||
style.align_self = align;
|
||||
style.justify_self = justify;
|
||||
}
|
||||
},
|
||||
"justify-content" => {
|
||||
match value {
|
||||
"center" => style.justify_content = Some(taffy::JustifyContent::CENTER),
|
||||
@@ -677,6 +693,57 @@ fn apply_value(style: &mut LayoutStyle, name: &str, value: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse the common CSS Box Alignment values that taffy can represent.
|
||||
///
|
||||
/// The outer option distinguishes an invalid declaration from `auto`, which
|
||||
/// resets a preceding declaration to the inherited item-alignment behavior.
|
||||
fn self_alignment_value(value: &str) -> Option<Option<taffy::AlignSelf>> {
|
||||
let normalized = value.trim().to_ascii_lowercase();
|
||||
let alignment = match normalized.as_str() {
|
||||
"auto" => return Some(None),
|
||||
"normal" => taffy::AlignSelf::STRETCH,
|
||||
"start" | "self-start" => taffy::AlignSelf::START,
|
||||
"end" | "self-end" => taffy::AlignSelf::END,
|
||||
"flex-start" => taffy::AlignSelf::FLEX_START,
|
||||
"flex-end" => taffy::AlignSelf::FLEX_END,
|
||||
"center" => taffy::AlignSelf::CENTER,
|
||||
"baseline" | "first baseline" => taffy::AlignSelf::BASELINE,
|
||||
"stretch" => taffy::AlignSelf::STRETCH,
|
||||
"safe start" | "safe self-start" => taffy::AlignSelf::SAFE_START,
|
||||
"safe end" | "safe self-end" => taffy::AlignSelf::SAFE_END,
|
||||
"safe flex-start" => taffy::AlignSelf::SAFE_FLEX_START,
|
||||
"safe flex-end" => taffy::AlignSelf::SAFE_FLEX_END,
|
||||
"safe center" => taffy::AlignSelf::SAFE_CENTER,
|
||||
"unsafe start" | "unsafe self-start" => taffy::AlignSelf::START,
|
||||
"unsafe end" | "unsafe self-end" => taffy::AlignSelf::END,
|
||||
"unsafe flex-start" => taffy::AlignSelf::FLEX_START,
|
||||
"unsafe flex-end" => taffy::AlignSelf::FLEX_END,
|
||||
"unsafe center" => taffy::AlignSelf::CENTER,
|
||||
_ => return None,
|
||||
};
|
||||
Some(Some(alignment))
|
||||
}
|
||||
|
||||
fn self_alignment_pair(
|
||||
value: &str,
|
||||
) -> Option<(Option<taffy::AlignSelf>, Option<taffy::JustifySelf>)> {
|
||||
if let Some(alignment) = self_alignment_value(value) {
|
||||
return Some((alignment, alignment));
|
||||
}
|
||||
let tokens: Vec<&str> = value.split_whitespace().collect();
|
||||
for split in 1..tokens.len() {
|
||||
let align = tokens[..split].join(" ");
|
||||
let justify = tokens[split..].join(" ");
|
||||
if let (Some(align), Some(justify)) = (
|
||||
self_alignment_value(&align),
|
||||
self_alignment_value(&justify),
|
||||
) {
|
||||
return Some((align, justify));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Parse the subset of `transform` obscura applies at paint time: `translate`,
|
||||
/// `translateX`, `translateY` (px and %, stored unresolved so % can resolve
|
||||
/// against the element's own border box later) and `scale`/`scaleX`/`scaleY`.
|
||||
@@ -2609,6 +2676,31 @@ mod tests {
|
||||
assert!(invalid.internal_flex_container);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn item_self_alignment_parses_and_resets() {
|
||||
let aligned = compute_style(
|
||||
"div",
|
||||
Some("align-self:safe center;justify-self:flex-end"),
|
||||
);
|
||||
assert_eq!(aligned.align_self, Some(taffy::AlignSelf::SAFE_CENTER));
|
||||
assert_eq!(aligned.justify_self, Some(taffy::JustifySelf::FLEX_END));
|
||||
|
||||
let reset = compute_style(
|
||||
"div",
|
||||
Some("align-self:center;align-self:auto;justify-self:end;justify-self:auto"),
|
||||
);
|
||||
assert_eq!(reset.align_self, None);
|
||||
assert_eq!(reset.justify_self, None);
|
||||
|
||||
let normal = compute_style("div", Some("align-self:normal;justify-self:normal"));
|
||||
assert_eq!(normal.align_self, Some(taffy::AlignSelf::STRETCH));
|
||||
assert_eq!(normal.justify_self, Some(taffy::JustifySelf::STRETCH));
|
||||
|
||||
let shorthand = compute_style("div", Some("place-self:safe center flex-end"));
|
||||
assert_eq!(shorthand.align_self, Some(taffy::AlignSelf::SAFE_CENTER));
|
||||
assert_eq!(shorthand.justify_self, Some(taffy::JustifySelf::FLEX_END));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn font_shorthand_expands_layout_fields_and_resets_omissions() {
|
||||
let s = compute_style(
|
||||
|
||||
Reference in new issue
Block a user