mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:47:34 +00:00
LibWeb: Honor align-self
over align-items
when non-auto on flex item
This commit is contained in:
parent
3b3af58cf6
commit
2f0657739b
9 changed files with 84 additions and 10 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -38,6 +38,7 @@ public:
|
||||||
static CSS::ImageRendering image_rendering() { return CSS::ImageRendering::Auto; }
|
static CSS::ImageRendering image_rendering() { return CSS::ImageRendering::Auto; }
|
||||||
static CSS::JustifyContent justify_content() { return CSS::JustifyContent::FlexStart; }
|
static CSS::JustifyContent justify_content() { return CSS::JustifyContent::FlexStart; }
|
||||||
static CSS::AlignItems align_items() { return CSS::AlignItems::Stretch; }
|
static CSS::AlignItems align_items() { return CSS::AlignItems::Stretch; }
|
||||||
|
static CSS::AlignSelf align_self() { return CSS::AlignSelf::Auto; }
|
||||||
static CSS::Overflow overflow() { return CSS::Overflow::Visible; }
|
static CSS::Overflow overflow() { return CSS::Overflow::Visible; }
|
||||||
static CSS::BoxSizing box_sizing() { return CSS::BoxSizing::ContentBox; }
|
static CSS::BoxSizing box_sizing() { return CSS::BoxSizing::ContentBox; }
|
||||||
static CSS::PointerEvents pointer_events() { return CSS::PointerEvents::Auto; }
|
static CSS::PointerEvents pointer_events() { return CSS::PointerEvents::Auto; }
|
||||||
|
@ -150,6 +151,7 @@ public:
|
||||||
float flex_shrink() const { return m_noninherited.flex_shrink; }
|
float flex_shrink() const { return m_noninherited.flex_shrink; }
|
||||||
int order() const { return m_noninherited.order; }
|
int order() const { return m_noninherited.order; }
|
||||||
CSS::AlignItems align_items() const { return m_noninherited.align_items; }
|
CSS::AlignItems align_items() const { return m_noninherited.align_items; }
|
||||||
|
CSS::AlignSelf align_self() const { return m_noninherited.align_self; }
|
||||||
float opacity() const { return m_noninherited.opacity; }
|
float opacity() const { return m_noninherited.opacity; }
|
||||||
CSS::Visibility visibility() const { return m_inherited.visibility; }
|
CSS::Visibility visibility() const { return m_inherited.visibility; }
|
||||||
CSS::ImageRendering image_rendering() const { return m_inherited.image_rendering; }
|
CSS::ImageRendering image_rendering() const { return m_inherited.image_rendering; }
|
||||||
|
@ -264,6 +266,7 @@ protected:
|
||||||
float flex_shrink { InitialValues::flex_shrink() };
|
float flex_shrink { InitialValues::flex_shrink() };
|
||||||
int order { InitialValues::order() };
|
int order { InitialValues::order() };
|
||||||
CSS::AlignItems align_items { InitialValues::align_items() };
|
CSS::AlignItems align_items { InitialValues::align_items() };
|
||||||
|
CSS::AlignSelf align_self { InitialValues::align_self() };
|
||||||
CSS::JustifyContent justify_content { InitialValues::justify_content() };
|
CSS::JustifyContent justify_content { InitialValues::justify_content() };
|
||||||
CSS::Overflow overflow_x { InitialValues::overflow() };
|
CSS::Overflow overflow_x { InitialValues::overflow() };
|
||||||
CSS::Overflow overflow_y { InitialValues::overflow() };
|
CSS::Overflow overflow_y { InitialValues::overflow() };
|
||||||
|
@ -333,6 +336,7 @@ public:
|
||||||
void set_flex_shrink(float value) { m_noninherited.flex_shrink = value; }
|
void set_flex_shrink(float value) { m_noninherited.flex_shrink = value; }
|
||||||
void set_order(int value) { m_noninherited.order = value; }
|
void set_order(int value) { m_noninherited.order = value; }
|
||||||
void set_align_items(CSS::AlignItems value) { m_noninherited.align_items = value; }
|
void set_align_items(CSS::AlignItems value) { m_noninherited.align_items = value; }
|
||||||
|
void set_align_self(CSS::AlignSelf value) { m_noninherited.align_self = value; }
|
||||||
void set_opacity(float value) { m_noninherited.opacity = value; }
|
void set_opacity(float value) { m_noninherited.opacity = value; }
|
||||||
void set_justify_content(CSS::JustifyContent value) { m_noninherited.justify_content = value; }
|
void set_justify_content(CSS::JustifyContent value) { m_noninherited.justify_content = value; }
|
||||||
void set_box_shadow(Vector<ShadowData>&& value) { m_noninherited.box_shadow = move(value); }
|
void set_box_shadow(Vector<ShadowData>&& value) { m_noninherited.box_shadow = move(value); }
|
||||||
|
|
|
@ -1,10 +1,28 @@
|
||||||
{
|
{
|
||||||
"align-items": [
|
"align-items": [
|
||||||
"flex-start",
|
|
||||||
"flex-end",
|
|
||||||
"center",
|
|
||||||
"baseline",
|
"baseline",
|
||||||
"stretch"
|
"center",
|
||||||
|
"flex-end",
|
||||||
|
"flex-start",
|
||||||
|
"normal",
|
||||||
|
"safe",
|
||||||
|
"self-end",
|
||||||
|
"self-start",
|
||||||
|
"stretch",
|
||||||
|
"unsafe"
|
||||||
|
],
|
||||||
|
"align-self": [
|
||||||
|
"auto",
|
||||||
|
"baseline",
|
||||||
|
"center",
|
||||||
|
"flex-end",
|
||||||
|
"flex-start",
|
||||||
|
"normal",
|
||||||
|
"safe",
|
||||||
|
"self-end",
|
||||||
|
"self-start",
|
||||||
|
"stretch",
|
||||||
|
"unsafe"
|
||||||
],
|
],
|
||||||
"background-attachment": [
|
"background-attachment": [
|
||||||
"fixed",
|
"fixed",
|
||||||
|
|
|
@ -181,8 +181,8 @@
|
||||||
"nwse-resize",
|
"nwse-resize",
|
||||||
"oblique",
|
"oblique",
|
||||||
"opaque",
|
"opaque",
|
||||||
"optimizespeed",
|
|
||||||
"optimizequality",
|
"optimizequality",
|
||||||
|
"optimizespeed",
|
||||||
"outset",
|
"outset",
|
||||||
"outside",
|
"outside",
|
||||||
"overline",
|
"overline",
|
||||||
|
@ -217,9 +217,12 @@
|
||||||
"ruby-text-container",
|
"ruby-text-container",
|
||||||
"run-in",
|
"run-in",
|
||||||
"s-resize",
|
"s-resize",
|
||||||
|
"safe",
|
||||||
"sans-serif",
|
"sans-serif",
|
||||||
"scroll",
|
"scroll",
|
||||||
"se-resize",
|
"se-resize",
|
||||||
|
"self-end",
|
||||||
|
"self-start",
|
||||||
"separate",
|
"separate",
|
||||||
"serif",
|
"serif",
|
||||||
"slow",
|
"slow",
|
||||||
|
@ -262,6 +265,7 @@
|
||||||
"ui-sans-serif",
|
"ui-sans-serif",
|
||||||
"ui-serif",
|
"ui-serif",
|
||||||
"underline",
|
"underline",
|
||||||
|
"unsafe",
|
||||||
"upper-alpha",
|
"upper-alpha",
|
||||||
"upper-latin",
|
"upper-latin",
|
||||||
"upper-roman",
|
"upper-roman",
|
||||||
|
|
|
@ -6,6 +6,13 @@
|
||||||
"align-items"
|
"align-items"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"align-self": {
|
||||||
|
"inherited": false,
|
||||||
|
"initial": "auto",
|
||||||
|
"valid-types": [
|
||||||
|
"align-self"
|
||||||
|
]
|
||||||
|
},
|
||||||
"background": {
|
"background": {
|
||||||
"affects-layout": false,
|
"affects-layout": false,
|
||||||
"inherited": false,
|
"inherited": false,
|
||||||
|
|
|
@ -310,6 +310,12 @@ Optional<CSS::AlignItems> StyleProperties::align_items() const
|
||||||
return value_id_to_align_items(value->to_identifier());
|
return value_id_to_align_items(value->to_identifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<CSS::AlignSelf> StyleProperties::align_self() const
|
||||||
|
{
|
||||||
|
auto value = property(CSS::PropertyID::AlignSelf);
|
||||||
|
return value_id_to_align_self(value->to_identifier());
|
||||||
|
}
|
||||||
|
|
||||||
Optional<CSS::Position> StyleProperties::position() const
|
Optional<CSS::Position> StyleProperties::position() const
|
||||||
{
|
{
|
||||||
auto value = property(CSS::PropertyID::Position);
|
auto value = property(CSS::PropertyID::Position);
|
||||||
|
|
|
@ -67,6 +67,7 @@ public:
|
||||||
float flex_shrink() const;
|
float flex_shrink() const;
|
||||||
int order() const;
|
int order() const;
|
||||||
Optional<CSS::AlignItems> align_items() const;
|
Optional<CSS::AlignItems> align_items() const;
|
||||||
|
Optional<CSS::AlignSelf> align_self() const;
|
||||||
float opacity() const;
|
float opacity() const;
|
||||||
Optional<CSS::Visibility> visibility() const;
|
Optional<CSS::Visibility> visibility() const;
|
||||||
Optional<CSS::ImageRendering> image_rendering() const;
|
Optional<CSS::ImageRendering> image_rendering() const;
|
||||||
|
|
|
@ -1072,13 +1072,12 @@ void FlexFormattingContext::calculate_cross_size_of_each_flex_line(float const c
|
||||||
// https://www.w3.org/TR/css-flexbox-1/#algo-stretch
|
// https://www.w3.org/TR/css-flexbox-1/#algo-stretch
|
||||||
void FlexFormattingContext::determine_used_cross_size_of_each_flex_item()
|
void FlexFormattingContext::determine_used_cross_size_of_each_flex_item()
|
||||||
{
|
{
|
||||||
// FIXME: Get the alignment via "align-self" of the item (which accesses "align-items" of the parent if unset)
|
|
||||||
for (auto& flex_line : m_flex_lines) {
|
for (auto& flex_line : m_flex_lines) {
|
||||||
for (auto& flex_item : flex_line.items) {
|
for (auto& flex_item : flex_line.items) {
|
||||||
// If a flex item has align-self: stretch, its computed cross size property is auto,
|
// If a flex item has align-self: stretch, its computed cross size property is auto,
|
||||||
// and neither of its cross-axis margins are auto, the used outer cross size is the used cross size of its flex line,
|
// and neither of its cross-axis margins are auto, the used outer cross size is the used cross size of its flex line,
|
||||||
// clamped according to the item’s used min and max cross sizes.
|
// clamped according to the item’s used min and max cross sizes.
|
||||||
if (flex_item->box.computed_values().align_items() == CSS::AlignItems::Stretch
|
if (alignment_for_item(*flex_item) == CSS::AlignItems::Stretch
|
||||||
&& is_cross_auto(flex_item->box)
|
&& is_cross_auto(flex_item->box)
|
||||||
&& !flex_item->margins.cross_before_is_auto
|
&& !flex_item->margins.cross_before_is_auto
|
||||||
&& !flex_item->margins.cross_after_is_auto) {
|
&& !flex_item->margins.cross_after_is_auto) {
|
||||||
|
@ -1201,14 +1200,43 @@ void FlexFormattingContext::dump_items() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSS::AlignItems FlexFormattingContext::alignment_for_item(FlexItem const& item) const
|
||||||
|
{
|
||||||
|
switch (item.box.computed_values().align_self()) {
|
||||||
|
case CSS::AlignSelf::Auto:
|
||||||
|
return flex_container().computed_values().align_items();
|
||||||
|
case CSS::AlignSelf::Normal:
|
||||||
|
return CSS::AlignItems::Normal;
|
||||||
|
case CSS::AlignSelf::SelfStart:
|
||||||
|
return CSS::AlignItems::SelfStart;
|
||||||
|
case CSS::AlignSelf::SelfEnd:
|
||||||
|
return CSS::AlignItems::SelfEnd;
|
||||||
|
case CSS::AlignSelf::FlexStart:
|
||||||
|
return CSS::AlignItems::FlexStart;
|
||||||
|
case CSS::AlignSelf::FlexEnd:
|
||||||
|
return CSS::AlignItems::FlexEnd;
|
||||||
|
case CSS::AlignSelf::Center:
|
||||||
|
return CSS::AlignItems::Center;
|
||||||
|
case CSS::AlignSelf::Baseline:
|
||||||
|
return CSS::AlignItems::Baseline;
|
||||||
|
case CSS::AlignSelf::Stretch:
|
||||||
|
return CSS::AlignItems::Stretch;
|
||||||
|
case CSS::AlignSelf::Safe:
|
||||||
|
return CSS::AlignItems::Safe;
|
||||||
|
case CSS::AlignSelf::Unsafe:
|
||||||
|
return CSS::AlignItems::Unsafe;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FlexFormattingContext::align_all_flex_items_along_the_cross_axis()
|
void FlexFormattingContext::align_all_flex_items_along_the_cross_axis()
|
||||||
{
|
{
|
||||||
// FIXME: Get the alignment via "align-self" of the item (which accesses "align-items" of the parent if unset)
|
|
||||||
// FIXME: Take better care of margins
|
// FIXME: Take better care of margins
|
||||||
float line_cross_offset = 0;
|
float line_cross_offset = 0;
|
||||||
for (auto& flex_line : m_flex_lines) {
|
for (auto& flex_line : m_flex_lines) {
|
||||||
for (auto* flex_item : flex_line.items) {
|
for (auto* flex_item : flex_line.items) {
|
||||||
switch (flex_container().computed_values().align_items()) {
|
switch (alignment_for_item(*flex_item)) {
|
||||||
case CSS::AlignItems::Baseline:
|
case CSS::AlignItems::Baseline:
|
||||||
// FIXME: Implement this
|
// FIXME: Implement this
|
||||||
// Fallthrough
|
// Fallthrough
|
||||||
|
|
|
@ -116,6 +116,8 @@ private:
|
||||||
|
|
||||||
void calculate_cross_size_of_each_flex_line(float cross_min_size, float cross_max_size);
|
void calculate_cross_size_of_each_flex_line(float cross_min_size, float cross_max_size);
|
||||||
|
|
||||||
|
CSS::AlignItems alignment_for_item(FlexItem const&) const;
|
||||||
|
|
||||||
void determine_used_cross_size_of_each_flex_item();
|
void determine_used_cross_size_of_each_flex_item();
|
||||||
|
|
||||||
void distribute_any_remaining_free_space();
|
void distribute_any_remaining_free_space();
|
||||||
|
|
|
@ -423,6 +423,10 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
|
||||||
if (align_items.has_value())
|
if (align_items.has_value())
|
||||||
computed_values.set_align_items(align_items.value());
|
computed_values.set_align_items(align_items.value());
|
||||||
|
|
||||||
|
auto align_self = computed_style.align_self();
|
||||||
|
if (align_self.has_value())
|
||||||
|
computed_values.set_align_self(align_self.value());
|
||||||
|
|
||||||
auto position = computed_style.position();
|
auto position = computed_style.position();
|
||||||
if (position.has_value())
|
if (position.has_value())
|
||||||
computed_values.set_position(position.value());
|
computed_values.set_position(position.value());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue