mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 15:57:35 +00:00
LibWeb: Add support for "place-items" CSS property
Adds support for place-items property which allows to specify both align-items and justify-items in a single declaration.
This commit is contained in:
parent
a74c56bc1b
commit
a8587fe54e
12 changed files with 135 additions and 0 deletions
8
Tests/LibWeb/Layout/expected/grid/place-items-center.txt
Normal file
8
Tests/LibWeb/Layout/expected/grid/place-items-center.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
|
BlockContainer <html> at (1,1) content-size 798x37.46875 [BFC] children: not-inline
|
||||||
|
Box <body> at (10,10) content-size 780x19.46875 [GFC] children: not-inline
|
||||||
|
BlockContainer <div> at (362.9375,11) content-size 74.125x17.46875 [BFC] children: inline
|
||||||
|
line 0 width: 74.125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||||
|
frag 0 from TextNode start: 0, length: 8, rect: [362.9375,11 74.125x17.46875]
|
||||||
|
"Download"
|
||||||
|
TextNode <#text>
|
9
Tests/LibWeb/Layout/input/grid/place-items-center.html
Normal file
9
Tests/LibWeb/Layout/input/grid/place-items-center.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html><style>
|
||||||
|
* {
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
}
|
||||||
|
</style><body><div>Download
|
|
@ -110,6 +110,7 @@ set(SOURCES
|
||||||
CSS/StyleValues/NumberStyleValue.cpp
|
CSS/StyleValues/NumberStyleValue.cpp
|
||||||
CSS/StyleValues/OverflowStyleValue.cpp
|
CSS/StyleValues/OverflowStyleValue.cpp
|
||||||
CSS/StyleValues/PlaceContentStyleValue.cpp
|
CSS/StyleValues/PlaceContentStyleValue.cpp
|
||||||
|
CSS/StyleValues/PlaceItemsStyleValue.cpp
|
||||||
CSS/StyleValues/PositionStyleValue.cpp
|
CSS/StyleValues/PositionStyleValue.cpp
|
||||||
CSS/StyleValues/RadialGradientStyleValue.cpp
|
CSS/StyleValues/RadialGradientStyleValue.cpp
|
||||||
CSS/StyleValues/RectStyleValue.cpp
|
CSS/StyleValues/RectStyleValue.cpp
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
#include <LibWeb/CSS/StyleValues/OverflowStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/OverflowStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/PlaceContentStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/PlaceContentStyleValue.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/PlaceItemsStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/RadialGradientStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/RadialGradientStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/RatioStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/RatioStyleValue.h>
|
||||||
|
@ -6222,6 +6223,25 @@ ErrorOr<RefPtr<StyleValue>> Parser::parse_place_content_value(Vector<ComponentVa
|
||||||
return PlaceContentStyleValue::create(maybe_align_content_value.release_nonnull(), maybe_justify_content_value.release_nonnull());
|
return PlaceContentStyleValue::create(maybe_align_content_value.release_nonnull(), maybe_justify_content_value.release_nonnull());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorOr<RefPtr<StyleValue>> Parser::parse_place_items_value(Vector<ComponentValue> const& component_values)
|
||||||
|
{
|
||||||
|
auto tokens = TokenStream { component_values };
|
||||||
|
auto maybe_align_items_value = TRY(parse_css_value_for_property(PropertyID::AlignItems, tokens));
|
||||||
|
if (!maybe_align_items_value)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (component_values.size() == 1) {
|
||||||
|
if (!property_accepts_identifier(PropertyID::JustifyItems, maybe_align_items_value->to_identifier()))
|
||||||
|
return nullptr;
|
||||||
|
return PlaceItemsStyleValue::create(*maybe_align_items_value, *maybe_align_items_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto maybe_justify_items_value = TRY(parse_css_value_for_property(PropertyID::JustifyItems, tokens));
|
||||||
|
if (!maybe_justify_items_value)
|
||||||
|
return nullptr;
|
||||||
|
return PlaceItemsStyleValue::create(*maybe_align_items_value, *maybe_justify_items_value);
|
||||||
|
}
|
||||||
|
|
||||||
ErrorOr<RefPtr<StyleValue>> Parser::parse_text_decoration_value(Vector<ComponentValue> const& component_values)
|
ErrorOr<RefPtr<StyleValue>> Parser::parse_text_decoration_value(Vector<ComponentValue> const& component_values)
|
||||||
{
|
{
|
||||||
RefPtr<StyleValue> decoration_line;
|
RefPtr<StyleValue> decoration_line;
|
||||||
|
@ -7456,6 +7476,10 @@ Parser::ParseErrorOr<NonnullRefPtr<StyleValue>> Parser::parse_css_value(Property
|
||||||
if (auto parsed_value = FIXME_TRY(parse_place_content_value(component_values)))
|
if (auto parsed_value = FIXME_TRY(parse_place_content_value(component_values)))
|
||||||
return parsed_value.release_nonnull();
|
return parsed_value.release_nonnull();
|
||||||
return ParseError::SyntaxError;
|
return ParseError::SyntaxError;
|
||||||
|
case PropertyID::PlaceItems:
|
||||||
|
if (auto parsed_value = FIXME_TRY(parse_place_items_value(component_values)))
|
||||||
|
return parsed_value.release_nonnull();
|
||||||
|
return ParseError::SyntaxError;
|
||||||
case PropertyID::TextDecoration:
|
case PropertyID::TextDecoration:
|
||||||
if (auto parsed_value = FIXME_TRY(parse_text_decoration_value(component_values)))
|
if (auto parsed_value = FIXME_TRY(parse_text_decoration_value(component_values)))
|
||||||
return parsed_value.release_nonnull();
|
return parsed_value.release_nonnull();
|
||||||
|
|
|
@ -326,6 +326,7 @@ private:
|
||||||
ErrorOr<RefPtr<StyleValue>> parse_list_style_value(Vector<ComponentValue> const&);
|
ErrorOr<RefPtr<StyleValue>> parse_list_style_value(Vector<ComponentValue> const&);
|
||||||
ErrorOr<RefPtr<StyleValue>> parse_overflow_value(Vector<ComponentValue> const&);
|
ErrorOr<RefPtr<StyleValue>> parse_overflow_value(Vector<ComponentValue> const&);
|
||||||
ErrorOr<RefPtr<StyleValue>> parse_place_content_value(Vector<ComponentValue> const&);
|
ErrorOr<RefPtr<StyleValue>> parse_place_content_value(Vector<ComponentValue> const&);
|
||||||
|
ErrorOr<RefPtr<StyleValue>> parse_place_items_value(Vector<ComponentValue> const&);
|
||||||
enum class AllowInsetKeyword {
|
enum class AllowInsetKeyword {
|
||||||
No,
|
No,
|
||||||
Yes,
|
Yes,
|
||||||
|
|
|
@ -1765,6 +1765,14 @@
|
||||||
"justify-content"
|
"justify-content"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"place-items": {
|
||||||
|
"inherited": false,
|
||||||
|
"initial": "normal",
|
||||||
|
"longhands": [
|
||||||
|
"align-items",
|
||||||
|
"justify-items"
|
||||||
|
]
|
||||||
|
},
|
||||||
"pointer-events": {
|
"pointer-events": {
|
||||||
"affects-layout": false,
|
"affects-layout": false,
|
||||||
"inherited": true,
|
"inherited": true,
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include <LibWeb/CSS/StyleValues/OverflowStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/OverflowStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/PlaceContentStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/PlaceContentStyleValue.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/PlaceItemsStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/RectStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/RectStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
|
||||||
|
@ -432,6 +433,19 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (property_id == CSS::PropertyID::PlaceItems) {
|
||||||
|
if (value.is_place_items()) {
|
||||||
|
auto const& place_items = value.as_place_items();
|
||||||
|
style.set_property(CSS::PropertyID::AlignItems, place_items.align_items());
|
||||||
|
style.set_property(CSS::PropertyID::JustifyItems, place_items.justify_items());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
style.set_property(CSS::PropertyID::AlignItems, value);
|
||||||
|
style.set_property(CSS::PropertyID::JustifyItems, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (property_id == CSS::PropertyID::Border) {
|
if (property_id == CSS::PropertyID::Border) {
|
||||||
set_property_expanding_shorthands(style, CSS::PropertyID::BorderTop, value, document, declaration);
|
set_property_expanding_shorthands(style, CSS::PropertyID::BorderTop, value, document, declaration);
|
||||||
set_property_expanding_shorthands(style, CSS::PropertyID::BorderRight, value, document, declaration);
|
set_property_expanding_shorthands(style, CSS::PropertyID::BorderRight, value, document, declaration);
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include <LibWeb/CSS/StyleValues/OverflowStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/OverflowStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/PlaceContentStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/PlaceContentStyleValue.h>
|
||||||
|
#include <LibWeb/CSS/StyleValues/PlaceItemsStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/RadialGradientStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/RadialGradientStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/RatioStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/RatioStyleValue.h>
|
||||||
|
@ -318,6 +319,12 @@ PlaceContentStyleValue const& StyleValue::as_place_content() const
|
||||||
return static_cast<PlaceContentStyleValue const&>(*this);
|
return static_cast<PlaceContentStyleValue const&>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlaceItemsStyleValue const& StyleValue::as_place_items() const
|
||||||
|
{
|
||||||
|
VERIFY(is_place_items());
|
||||||
|
return static_cast<PlaceItemsStyleValue const&>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
PositionStyleValue const& StyleValue::as_position() const
|
PositionStyleValue const& StyleValue::as_position() const
|
||||||
{
|
{
|
||||||
VERIFY(is_position());
|
VERIFY(is_position());
|
||||||
|
|
|
@ -126,6 +126,7 @@ public:
|
||||||
Overflow,
|
Overflow,
|
||||||
Percentage,
|
Percentage,
|
||||||
PlaceContent,
|
PlaceContent,
|
||||||
|
PlaceItems,
|
||||||
Position,
|
Position,
|
||||||
RadialGradient,
|
RadialGradient,
|
||||||
Ratio,
|
Ratio,
|
||||||
|
@ -184,6 +185,7 @@ public:
|
||||||
bool is_overflow() const { return type() == Type::Overflow; }
|
bool is_overflow() const { return type() == Type::Overflow; }
|
||||||
bool is_percentage() const { return type() == Type::Percentage; }
|
bool is_percentage() const { return type() == Type::Percentage; }
|
||||||
bool is_place_content() const { return type() == Type::PlaceContent; }
|
bool is_place_content() const { return type() == Type::PlaceContent; }
|
||||||
|
bool is_place_items() const { return type() == Type::PlaceItems; }
|
||||||
bool is_position() const { return type() == Type::Position; }
|
bool is_position() const { return type() == Type::Position; }
|
||||||
bool is_radial_gradient() const { return type() == Type::RadialGradient; }
|
bool is_radial_gradient() const { return type() == Type::RadialGradient; }
|
||||||
bool is_ratio() const { return type() == Type::Ratio; }
|
bool is_ratio() const { return type() == Type::Ratio; }
|
||||||
|
@ -241,6 +243,7 @@ public:
|
||||||
OverflowStyleValue const& as_overflow() const;
|
OverflowStyleValue const& as_overflow() const;
|
||||||
PercentageStyleValue const& as_percentage() const;
|
PercentageStyleValue const& as_percentage() const;
|
||||||
PlaceContentStyleValue const& as_place_content() const;
|
PlaceContentStyleValue const& as_place_content() const;
|
||||||
|
PlaceItemsStyleValue const& as_place_items() const;
|
||||||
PositionStyleValue const& as_position() const;
|
PositionStyleValue const& as_position() const;
|
||||||
RadialGradientStyleValue const& as_radial_gradient() const;
|
RadialGradientStyleValue const& as_radial_gradient() const;
|
||||||
RatioStyleValue const& as_ratio() const;
|
RatioStyleValue const& as_ratio() const;
|
||||||
|
@ -295,6 +298,7 @@ public:
|
||||||
OverflowStyleValue& as_overflow() { return const_cast<OverflowStyleValue&>(const_cast<StyleValue const&>(*this).as_overflow()); }
|
OverflowStyleValue& as_overflow() { return const_cast<OverflowStyleValue&>(const_cast<StyleValue const&>(*this).as_overflow()); }
|
||||||
PercentageStyleValue& as_percentage() { return const_cast<PercentageStyleValue&>(const_cast<StyleValue const&>(*this).as_percentage()); }
|
PercentageStyleValue& as_percentage() { return const_cast<PercentageStyleValue&>(const_cast<StyleValue const&>(*this).as_percentage()); }
|
||||||
PlaceContentStyleValue& as_place_content() { return const_cast<PlaceContentStyleValue&>(const_cast<StyleValue const&>(*this).as_place_content()); }
|
PlaceContentStyleValue& as_place_content() { return const_cast<PlaceContentStyleValue&>(const_cast<StyleValue const&>(*this).as_place_content()); }
|
||||||
|
PlaceItemsStyleValue& as_place_items() { return const_cast<PlaceItemsStyleValue&>(const_cast<StyleValue const&>(*this).as_place_items()); }
|
||||||
PositionStyleValue& as_position() { return const_cast<PositionStyleValue&>(const_cast<StyleValue const&>(*this).as_position()); }
|
PositionStyleValue& as_position() { return const_cast<PositionStyleValue&>(const_cast<StyleValue const&>(*this).as_position()); }
|
||||||
RadialGradientStyleValue& as_radial_gradient() { return const_cast<RadialGradientStyleValue&>(const_cast<StyleValue const&>(*this).as_radial_gradient()); }
|
RadialGradientStyleValue& as_radial_gradient() { return const_cast<RadialGradientStyleValue&>(const_cast<StyleValue const&>(*this).as_radial_gradient()); }
|
||||||
RatioStyleValue& as_ratio() { return const_cast<RatioStyleValue&>(const_cast<StyleValue const&>(*this).as_ratio()); }
|
RatioStyleValue& as_ratio() { return const_cast<RatioStyleValue&>(const_cast<StyleValue const&>(*this).as_ratio()); }
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PlaceItemsStyleValue.h"
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
ErrorOr<String> PlaceItemsStyleValue::to_string() const
|
||||||
|
{
|
||||||
|
return String::formatted("{} {}", TRY(m_properties.align_items->to_string()), TRY(m_properties.justify_items->to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibWeb/CSS/StyleValue.h>
|
||||||
|
|
||||||
|
namespace Web::CSS {
|
||||||
|
|
||||||
|
class PlaceItemsStyleValue final : public StyleValueWithDefaultOperators<PlaceItemsStyleValue> {
|
||||||
|
public:
|
||||||
|
static ErrorOr<ValueComparingNonnullRefPtr<PlaceItemsStyleValue>> create(ValueComparingNonnullRefPtr<StyleValue> align_items, ValueComparingNonnullRefPtr<StyleValue> justify_items)
|
||||||
|
{
|
||||||
|
return adopt_nonnull_ref_or_enomem(new (nothrow) PlaceItemsStyleValue(move(align_items), move(justify_items)));
|
||||||
|
}
|
||||||
|
virtual ~PlaceItemsStyleValue() override = default;
|
||||||
|
|
||||||
|
ValueComparingNonnullRefPtr<StyleValue> align_items() const { return m_properties.align_items; }
|
||||||
|
ValueComparingNonnullRefPtr<StyleValue> justify_items() const { return m_properties.justify_items; }
|
||||||
|
|
||||||
|
virtual ErrorOr<String> to_string() const override;
|
||||||
|
|
||||||
|
bool properties_equal(PlaceItemsStyleValue const& other) const { return m_properties == other.m_properties; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PlaceItemsStyleValue(ValueComparingNonnullRefPtr<StyleValue> align_items, ValueComparingNonnullRefPtr<StyleValue> justify_items)
|
||||||
|
: StyleValueWithDefaultOperators(Type::PlaceItems)
|
||||||
|
, m_properties { .align_items = move(align_items), .justify_items = move(justify_items) }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Properties {
|
||||||
|
ValueComparingNonnullRefPtr<StyleValue> align_items;
|
||||||
|
ValueComparingNonnullRefPtr<StyleValue> justify_items;
|
||||||
|
bool operator==(Properties const&) const = default;
|
||||||
|
} m_properties;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -146,6 +146,7 @@ class Percentage;
|
||||||
class PercentageOrCalculated;
|
class PercentageOrCalculated;
|
||||||
class PercentageStyleValue;
|
class PercentageStyleValue;
|
||||||
class PlaceContentStyleValue;
|
class PlaceContentStyleValue;
|
||||||
|
class PlaceItemsStyleValue;
|
||||||
class PositionStyleValue;
|
class PositionStyleValue;
|
||||||
class PropertyOwningCSSStyleDeclaration;
|
class PropertyOwningCSSStyleDeclaration;
|
||||||
class RadialGradientStyleValue;
|
class RadialGradientStyleValue;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue