LibWeb: Add place-self css property support

This commit is contained in:
Aliaksandr Kalenik 2023-08-04 14:04:05 +02:00 committed by Andreas Kling
parent f24aab662f
commit da2cd73bcf
12 changed files with 190 additions and 0 deletions

View file

@ -0,0 +1,61 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (1,1) content-size 798x262.40625 [BFC] children: not-inline
BlockContainer <body> at (10,10) content-size 780x244.40625 children: not-inline
Box <div.grid> at (31,31) content-size 738x39.46875 [GFC] children: not-inline
BlockContainer <div.start> at (32,32) content-size 50.203125x17.46875 [BFC] children: inline
line 0 width: 50.203125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 6, rect: [32,32 50.203125x17.46875]
"Start1"
TextNode <#text>
BlockContainer <div.item-padding> at (411,42) content-size 347x17.46875 [BFC] children: inline
line 0 width: 52.671875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 6, rect: [411,42 52.671875x17.46875]
"Start2"
TextNode <#text>
BlockContainer <(anonymous)> at (10,91.46875) content-size 780x0 children: inline
TextNode <#text>
Box <div.grid> at (31,112.46875) content-size 738x39.46875 [GFC] children: not-inline
BlockContainer <div.center> at (185.796875,123.46875) content-size 59.390625x17.46875 [BFC] children: inline
line 0 width: 59.390625, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 7, rect: [185.796875,123.46875 59.390625x17.46875]
"Center1"
TextNode <#text>
BlockContainer <div.item-padding> at (411,123.46875) content-size 347x17.46875 [BFC] children: inline
line 0 width: 61.859375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 7, rect: [411,123.46875 61.859375x17.46875]
"Center2"
TextNode <#text>
BlockContainer <(anonymous)> at (10,172.9375) content-size 780x0 children: inline
TextNode <#text>
Box <div.grid> at (31,193.9375) content-size 738x39.46875 [GFC] children: not-inline
BlockContainer <div.end> at (363.328125,214.9375) content-size 35.671875x17.46875 [BFC] children: inline
line 0 width: 35.671875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 4, rect: [363.328125,214.9375 35.671875x17.46875]
"End1"
TextNode <#text>
BlockContainer <div.item-padding> at (411,204.9375) content-size 347x17.46875 [BFC] children: inline
line 0 width: 38.140625, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 4, rect: [411,204.9375 38.140625x17.46875]
"End2"
TextNode <#text>
PaintableWithLines (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x264.40625]
PaintableWithLines (BlockContainer<BODY>) [9,9 782x246.40625]
PaintableBox (Box<DIV>.grid) [10,10 780x81.46875]
PaintableWithLines (BlockContainer<DIV>.start) [31,31 52.203125x19.46875]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<DIV>.item-padding) [400,31 369x39.46875]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer(anonymous)) [10,91.46875 780x0]
PaintableBox (Box<DIV>.grid) [10,91.46875 780x81.46875]
PaintableWithLines (BlockContainer<DIV>.center) [184.796875,122.46875 61.390625x19.46875]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<DIV>.item-padding) [400,112.46875 369x39.46875]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer(anonymous)) [10,172.9375 780x0]
PaintableBox (Box<DIV>.grid) [10,172.9375 780x81.46875]
PaintableWithLines (BlockContainer<DIV>.end) [362.328125,213.9375 37.671875x19.46875]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<DIV>.item-padding) [400,193.9375 369x39.46875]
TextPaintable (TextNode<#text>)

View file

@ -0,0 +1,11 @@
<!DOCTYPE html><style>
* { border: 1px solid black; }
.grid { display: grid; grid-template-columns: auto auto; padding: 20px; }
.start { place-self: start; }
.center { place-self: center; }
.end { place-self: end; }
.item-padding { padding: 10px;}
</style>
<div class="grid"><div class="start">Start1</div><div class="item-padding">Start2</div></div>
<div class="grid"><div class="center">Center1</div><div class="item-padding">Center2</div></div>
<div class="grid"><div class="end">End1</div><div class="item-padding">End2</div></div>

View file

@ -111,6 +111,7 @@ set(SOURCES
CSS/StyleValues/OverflowStyleValue.cpp
CSS/StyleValues/PlaceContentStyleValue.cpp
CSS/StyleValues/PlaceItemsStyleValue.cpp
CSS/StyleValues/PlaceSelfStyleValue.cpp
CSS/StyleValues/PositionStyleValue.cpp
CSS/StyleValues/RadialGradientStyleValue.cpp
CSS/StyleValues/RectStyleValue.cpp

View file

@ -72,6 +72,7 @@
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
#include <LibWeb/CSS/StyleValues/PlaceContentStyleValue.h>
#include <LibWeb/CSS/StyleValues/PlaceItemsStyleValue.h>
#include <LibWeb/CSS/StyleValues/PlaceSelfStyleValue.h>
#include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
#include <LibWeb/CSS/StyleValues/RadialGradientStyleValue.h>
#include <LibWeb/CSS/StyleValues/RatioStyleValue.h>
@ -6314,6 +6315,25 @@ ErrorOr<RefPtr<StyleValue>> Parser::parse_place_items_value(Vector<ComponentValu
return PlaceItemsStyleValue::create(*maybe_align_items_value, *maybe_justify_items_value);
}
ErrorOr<RefPtr<StyleValue>> Parser::parse_place_self_value(Vector<ComponentValue> const& component_values)
{
auto tokens = TokenStream { component_values };
auto maybe_align_self_value = TRY(parse_css_value_for_property(PropertyID::AlignSelf, tokens));
if (!maybe_align_self_value)
return nullptr;
if (component_values.size() == 1) {
if (!property_accepts_identifier(PropertyID::JustifySelf, maybe_align_self_value->to_identifier()))
return nullptr;
return PlaceSelfStyleValue::create(*maybe_align_self_value, *maybe_align_self_value);
}
auto maybe_justify_self_value = TRY(parse_css_value_for_property(PropertyID::JustifySelf, tokens));
if (!maybe_justify_self_value)
return nullptr;
return PlaceItemsStyleValue::create(*maybe_align_self_value, *maybe_justify_self_value);
}
ErrorOr<RefPtr<StyleValue>> Parser::parse_text_decoration_value(Vector<ComponentValue> const& component_values)
{
RefPtr<StyleValue> decoration_line;
@ -7555,6 +7575,10 @@ Parser::ParseErrorOr<NonnullRefPtr<StyleValue>> Parser::parse_css_value(Property
if (auto parsed_value = FIXME_TRY(parse_place_items_value(component_values)))
return parsed_value.release_nonnull();
return ParseError::SyntaxError;
case PropertyID::PlaceSelf:
if (auto parsed_value = FIXME_TRY(parse_place_self_value(component_values)))
return parsed_value.release_nonnull();
return ParseError::SyntaxError;
case PropertyID::TextDecoration:
if (auto parsed_value = FIXME_TRY(parse_text_decoration_value(component_values)))
return parsed_value.release_nonnull();

View file

@ -323,6 +323,7 @@ private:
ErrorOr<RefPtr<StyleValue>> parse_overflow_value(Vector<ComponentValue> const&);
ErrorOr<RefPtr<StyleValue>> parse_place_content_value(Vector<ComponentValue> const&);
ErrorOr<RefPtr<StyleValue>> parse_place_items_value(Vector<ComponentValue> const&);
ErrorOr<RefPtr<StyleValue>> parse_place_self_value(Vector<ComponentValue> const&);
enum class AllowInsetKeyword {
No,
Yes,

View file

@ -1785,6 +1785,14 @@
"justify-items"
]
},
"place-self": {
"inherited": false,
"initial": "normal",
"longhands": [
"align-self",
"justify-self"
]
},
"pointer-events": {
"affects-layout": false,
"inherited": true,

View file

@ -55,6 +55,7 @@
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
#include <LibWeb/CSS/StyleValues/PlaceContentStyleValue.h>
#include <LibWeb/CSS/StyleValues/PlaceItemsStyleValue.h>
#include <LibWeb/CSS/StyleValues/PlaceSelfStyleValue.h>
#include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
#include <LibWeb/CSS/StyleValues/RectStyleValue.h>
#include <LibWeb/CSS/StyleValues/StyleValueList.h>
@ -473,6 +474,19 @@ static void set_property_expanding_shorthands(StyleProperties& style, CSS::Prope
return;
}
if (property_id == CSS::PropertyID::PlaceSelf) {
if (value.is_place_self()) {
auto const& place_self = value.as_place_self();
set_longhand_property(CSS::PropertyID::AlignSelf, place_self.align_self());
set_longhand_property(CSS::PropertyID::JustifySelf, place_self.justify_self());
return;
}
set_longhand_property(CSS::PropertyID::AlignSelf, value);
set_longhand_property(CSS::PropertyID::JustifySelf, value);
return;
}
if (property_id == CSS::PropertyID::Border) {
set_property_expanding_shorthands(style, CSS::PropertyID::BorderTop, value, document, declaration, properties_for_revert);
set_property_expanding_shorthands(style, CSS::PropertyID::BorderRight, value, document, declaration, properties_for_revert);

View file

@ -51,6 +51,7 @@
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
#include <LibWeb/CSS/StyleValues/PlaceContentStyleValue.h>
#include <LibWeb/CSS/StyleValues/PlaceItemsStyleValue.h>
#include <LibWeb/CSS/StyleValues/PlaceSelfStyleValue.h>
#include <LibWeb/CSS/StyleValues/PositionStyleValue.h>
#include <LibWeb/CSS/StyleValues/RadialGradientStyleValue.h>
#include <LibWeb/CSS/StyleValues/RatioStyleValue.h>
@ -325,6 +326,12 @@ PlaceItemsStyleValue const& StyleValue::as_place_items() const
return static_cast<PlaceItemsStyleValue const&>(*this);
}
PlaceSelfStyleValue const& StyleValue::as_place_self() const
{
VERIFY(is_place_self());
return static_cast<PlaceSelfStyleValue const&>(*this);
}
PositionStyleValue const& StyleValue::as_position() const
{
VERIFY(is_position());

View file

@ -127,6 +127,7 @@ public:
Percentage,
PlaceContent,
PlaceItems,
PlaceSelf,
Position,
RadialGradient,
Ratio,
@ -187,6 +188,7 @@ public:
bool is_percentage() const { return type() == Type::Percentage; }
bool is_place_content() const { return type() == Type::PlaceContent; }
bool is_place_items() const { return type() == Type::PlaceItems; }
bool is_place_self() const { return type() == Type::PlaceSelf; }
bool is_position() const { return type() == Type::Position; }
bool is_radial_gradient() const { return type() == Type::RadialGradient; }
bool is_ratio() const { return type() == Type::Ratio; }
@ -246,6 +248,7 @@ public:
PercentageStyleValue const& as_percentage() const;
PlaceContentStyleValue const& as_place_content() const;
PlaceItemsStyleValue const& as_place_items() const;
PlaceSelfStyleValue const& as_place_self() const;
PositionStyleValue const& as_position() const;
RadialGradientStyleValue const& as_radial_gradient() const;
RatioStyleValue const& as_ratio() const;
@ -301,6 +304,7 @@ public:
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()); }
PlaceItemsStyleValue& as_place_items() { return const_cast<PlaceItemsStyleValue&>(const_cast<StyleValue const&>(*this).as_place_items()); }
PlaceSelfStyleValue& as_place_self() { return const_cast<PlaceSelfStyleValue&>(const_cast<StyleValue const&>(*this).as_place_self()); }
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()); }
RatioStyleValue& as_ratio() { return const_cast<RatioStyleValue&>(const_cast<StyleValue const&>(*this).as_ratio()); }

View file

@ -0,0 +1,16 @@
/*
* Copyright (c) 2023, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "PlaceSelfStyleValue.h"
namespace Web::CSS {
ErrorOr<String> PlaceSelfStyleValue::to_string() const
{
return String::formatted("{} {}", TRY(m_properties.align_self->to_string()), TRY(m_properties.justify_self->to_string()));
}
}

View file

@ -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 PlaceSelfStyleValue final : public StyleValueWithDefaultOperators<PlaceSelfStyleValue> {
public:
static ErrorOr<ValueComparingNonnullRefPtr<PlaceSelfStyleValue>> create(ValueComparingNonnullRefPtr<StyleValue> align_self, ValueComparingNonnullRefPtr<StyleValue> justify_self)
{
return adopt_nonnull_ref_or_enomem(new (nothrow) PlaceSelfStyleValue(move(align_self), move(justify_self)));
}
virtual ~PlaceSelfStyleValue() override = default;
ValueComparingNonnullRefPtr<StyleValue> align_self() const { return m_properties.align_self; }
ValueComparingNonnullRefPtr<StyleValue> justify_self() const { return m_properties.justify_self; }
virtual ErrorOr<String> to_string() const override;
bool properties_equal(PlaceSelfStyleValue const& other) const { return m_properties == other.m_properties; }
private:
PlaceSelfStyleValue(ValueComparingNonnullRefPtr<StyleValue> align_self, ValueComparingNonnullRefPtr<StyleValue> justify_self)
: StyleValueWithDefaultOperators(Type::PlaceSelf)
, m_properties { .align_self = move(align_self), .justify_self = move(justify_self) }
{
}
struct Properties {
ValueComparingNonnullRefPtr<StyleValue> align_self;
ValueComparingNonnullRefPtr<StyleValue> justify_self;
bool operator==(Properties const&) const = default;
} m_properties;
};
}

View file

@ -149,6 +149,7 @@ class PercentageOrCalculated;
class PercentageStyleValue;
class PlaceContentStyleValue;
class PlaceItemsStyleValue;
class PlaceSelfStyleValue;
class PositionStyleValue;
class PropertyOwningCSSStyleDeclaration;
class RadialGradientStyleValue;