LibWeb: Move <display-foo> definitions into Enums.json

This eliminates a fair bit of boilerplate.
This commit is contained in:
Sam Atkins 2023-09-04 17:39:15 +01:00 committed by Sam Atkins
parent 3b0980c89f
commit 125d161b3f
Notes: sideshowbarker 2024-07-17 03:27:40 +09:00
10 changed files with 182 additions and 313 deletions

View File

@ -59,7 +59,7 @@ public:
static CSS::TextDecorationStyle text_decoration_style() { return CSS::TextDecorationStyle::Solid; }
static CSS::TextTransform text_transform() { return CSS::TextTransform::None; }
static CSS::LengthPercentage text_indent() { return CSS::Length::make_px(0); }
static CSS::Display display() { return CSS::Display { CSS::Display::Outside::Inline, CSS::Display::Inside::Flow }; }
static CSS::Display display() { return CSS::Display { CSS::DisplayOutside::Inline, CSS::DisplayInside::Flow }; }
static Color color() { return Color::Black; }
static Color stop_color() { return Color::Black; }
static CSS::BackdropFilter backdrop_filter() { return BackdropFilter::make_none(); }

View File

@ -42,90 +42,17 @@ String Display::to_string() const
if (*this == Display::from_short(Display::Short::InlineTable))
return "inline-table"_string;
switch (m_value.outside_inside.outside) {
case Outside::Block:
builder.append("block"sv);
break;
case Outside::Inline:
builder.append("inline"sv);
break;
case Outside::RunIn:
builder.append("run-in"sv);
break;
}
builder.append(CSS::to_string(m_value.outside_inside.outside));
builder.append(' ');
switch (m_value.outside_inside.inside) {
case Inside::Flow:
builder.append("flow"sv);
break;
case Inside::FlowRoot:
builder.append("flow-root"sv);
break;
case Inside::Table:
builder.append("table"sv);
break;
case Inside::Flex:
builder.append("flex"sv);
break;
case Inside::Grid:
builder.append("grid"sv);
break;
case Inside::Ruby:
builder.append("ruby"sv);
break;
}
builder.append(CSS::to_string(m_value.outside_inside.inside));
if (m_value.outside_inside.list_item == ListItem::Yes)
builder.append(" list-item"sv);
break;
case Type::Internal:
switch (m_value.internal) {
case Internal::TableRowGroup:
builder.append("table-row-group"sv);
break;
case Internal::TableHeaderGroup:
builder.append("table-header-group"sv);
break;
case Internal::TableFooterGroup:
builder.append("table-footer-group"sv);
break;
case Internal::TableRow:
builder.append("table-row"sv);
break;
case Internal::TableCell:
builder.append("table-cell"sv);
break;
case Internal::TableColumnGroup:
builder.append("table-column-group"sv);
break;
case Internal::TableColumn:
builder.append("table-column"sv);
break;
case Internal::TableCaption:
builder.append("table-caption"sv);
break;
case Internal::RubyBase:
builder.append("ruby-base"sv);
break;
case Internal::RubyText:
builder.append("ruby-text"sv);
break;
case Internal::RubyBaseContainer:
builder.append("ruby-base-container"sv);
break;
case Internal::RubyTextContainer:
builder.append("ruby-text-container"sv);
break;
}
builder.append(CSS::to_string(m_value.internal));
break;
case Type::Box:
switch (m_value.box) {
case Box::Contents:
builder.append("contents"sv);
break;
case Box::None:
builder.append("none"sv);
break;
}
builder.append(CSS::to_string(m_value.box));
break;
};
return MUST(builder.to_string());

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -8,6 +9,7 @@
#include <AK/Assertions.h>
#include <AK/String.h>
#include <LibWeb/CSS/Enums.h>
namespace Web::CSS {
@ -35,41 +37,6 @@ public:
VERIFY_NOT_REACHED();
}
enum class Outside {
Block,
Inline,
RunIn,
};
enum class Inside {
Flow,
FlowRoot,
Table,
Flex,
Grid,
Ruby,
};
enum class Internal {
TableRowGroup,
TableHeaderGroup,
TableFooterGroup,
TableRow,
TableCell,
TableColumnGroup,
TableColumn,
TableCaption,
RubyBase,
RubyText,
RubyBaseContainer,
RubyTextContainer,
};
enum class Box {
Contents,
None,
};
enum class ListItem {
No,
Yes,
@ -82,35 +49,35 @@ public:
};
bool is_internal() const { return m_type == Type::Internal; }
Internal internal() const
DisplayInternal internal() const
{
VERIFY(is_internal());
return m_value.internal;
}
bool is_table_column() const { return is_internal() && internal() == Internal::TableColumn; }
bool is_table_row_group() const { return is_internal() && internal() == Internal::TableRowGroup; }
bool is_table_header_group() const { return is_internal() && internal() == Internal::TableHeaderGroup; }
bool is_table_footer_group() const { return is_internal() && internal() == Internal::TableFooterGroup; }
bool is_table_row() const { return is_internal() && internal() == Internal::TableRow; }
bool is_table_cell() const { return is_internal() && internal() == Internal::TableCell; }
bool is_table_column_group() const { return is_internal() && internal() == Internal::TableColumnGroup; }
bool is_table_caption() const { return is_internal() && internal() == Internal::TableCaption; }
bool is_table_column() const { return is_internal() && internal() == DisplayInternal::TableColumn; }
bool is_table_row_group() const { return is_internal() && internal() == DisplayInternal::TableRowGroup; }
bool is_table_header_group() const { return is_internal() && internal() == DisplayInternal::TableHeaderGroup; }
bool is_table_footer_group() const { return is_internal() && internal() == DisplayInternal::TableFooterGroup; }
bool is_table_row() const { return is_internal() && internal() == DisplayInternal::TableRow; }
bool is_table_cell() const { return is_internal() && internal() == DisplayInternal::TableCell; }
bool is_table_column_group() const { return is_internal() && internal() == DisplayInternal::TableColumnGroup; }
bool is_table_caption() const { return is_internal() && internal() == DisplayInternal::TableCaption; }
bool is_none() const { return m_type == Type::Box && m_value.box == Box::None; }
bool is_contents() const { return m_type == Type::Box && m_value.box == Box::Contents; }
bool is_none() const { return m_type == Type::Box && m_value.box == DisplayBox::None; }
bool is_contents() const { return m_type == Type::Box && m_value.box == DisplayBox::Contents; }
Type type() const { return m_type; }
bool is_outside_and_inside() const { return m_type == Type::OutsideAndInside; }
Outside outside() const
DisplayOutside outside() const
{
VERIFY(is_outside_and_inside());
return m_value.outside_inside.outside;
}
bool is_block_outside() const { return is_outside_and_inside() && outside() == Outside::Block; }
bool is_inline_outside() const { return is_outside_and_inside() && outside() == Outside::Inline; }
bool is_block_outside() const { return is_outside_and_inside() && outside() == DisplayOutside::Block; }
bool is_inline_outside() const { return is_outside_and_inside() && outside() == DisplayOutside::Inline; }
bool is_inline_block() const { return is_inline_outside() && is_flow_root_inside(); }
ListItem list_item() const
@ -121,18 +88,18 @@ public:
bool is_list_item() const { return is_outside_and_inside() && list_item() == ListItem::Yes; }
Inside inside() const
DisplayInside inside() const
{
VERIFY(is_outside_and_inside());
return m_value.outside_inside.inside;
}
bool is_flow_inside() const { return is_outside_and_inside() && inside() == Inside::Flow; }
bool is_flow_root_inside() const { return is_outside_and_inside() && inside() == Inside::FlowRoot; }
bool is_table_inside() const { return is_outside_and_inside() && inside() == Inside::Table; }
bool is_flex_inside() const { return is_outside_and_inside() && inside() == Inside::Flex; }
bool is_grid_inside() const { return is_outside_and_inside() && inside() == Inside::Grid; }
bool is_ruby_inside() const { return is_outside_and_inside() && inside() == Inside::Ruby; }
bool is_flow_inside() const { return is_outside_and_inside() && inside() == DisplayInside::Flow; }
bool is_flow_root_inside() const { return is_outside_and_inside() && inside() == DisplayInside::FlowRoot; }
bool is_table_inside() const { return is_outside_and_inside() && inside() == DisplayInside::Table; }
bool is_flex_inside() const { return is_outside_and_inside() && inside() == DisplayInside::Flex; }
bool is_grid_inside() const { return is_outside_and_inside() && inside() == DisplayInside::Grid; }
bool is_ruby_inside() const { return is_outside_and_inside() && inside() == DisplayInside::Ruby; }
enum class Short {
None,
@ -158,44 +125,44 @@ public:
{
switch (short_) {
case Short::None:
return Display { Box::None };
return Display { DisplayBox::None };
case Short::Contents:
return Display { Box::Contents };
return Display { DisplayBox::Contents };
case Short::Block:
return Display { Outside::Block, Inside::Flow };
return Display { DisplayOutside::Block, DisplayInside::Flow };
case Short::Inline:
return Display { Outside::Inline, Inside::Flow };
return Display { DisplayOutside::Inline, DisplayInside::Flow };
case Short::Flow:
return Display { Outside::Block, Inside::Flow };
return Display { DisplayOutside::Block, DisplayInside::Flow };
case Short::FlowRoot:
return Display { Outside::Block, Inside::FlowRoot };
return Display { DisplayOutside::Block, DisplayInside::FlowRoot };
case Short::InlineBlock:
return Display { Outside::Inline, Inside::FlowRoot };
return Display { DisplayOutside::Inline, DisplayInside::FlowRoot };
case Short::RunIn:
return Display { Outside::RunIn, Inside::Flow };
return Display { DisplayOutside::RunIn, DisplayInside::Flow };
case Short::ListItem:
return Display { Outside::Block, Inside::Flow, ListItem::Yes };
return Display { DisplayOutside::Block, DisplayInside::Flow, ListItem::Yes };
case Short::InlineListItem:
return Display { Outside::Inline, Inside::Flow, ListItem::Yes };
return Display { DisplayOutside::Inline, DisplayInside::Flow, ListItem::Yes };
case Short::Flex:
return Display { Outside::Block, Inside::Flex };
return Display { DisplayOutside::Block, DisplayInside::Flex };
case Short::InlineFlex:
return Display { Outside::Inline, Inside::Flex };
return Display { DisplayOutside::Inline, DisplayInside::Flex };
case Short::Grid:
return Display { Outside::Block, Inside::Grid };
return Display { DisplayOutside::Block, DisplayInside::Grid };
case Short::InlineGrid:
return Display { Outside::Inline, Inside::Grid };
return Display { DisplayOutside::Inline, DisplayInside::Grid };
case Short::Ruby:
return Display { Outside::Inline, Inside::Ruby };
return Display { DisplayOutside::Inline, DisplayInside::Ruby };
case Short::Table:
return Display { Outside::Block, Inside::Table };
return Display { DisplayOutside::Block, DisplayInside::Table };
case Short::InlineTable:
return Display { Outside::Inline, Inside::Table };
return Display { DisplayOutside::Inline, DisplayInside::Table };
}
VERIFY_NOT_REACHED();
}
Display(Outside outside, Inside inside)
Display(DisplayOutside outside, DisplayInside inside)
: m_type(Type::OutsideAndInside)
{
m_value.outside_inside = {
@ -205,7 +172,7 @@ public:
};
}
Display(Outside outside, Inside inside, ListItem list_item)
Display(DisplayOutside outside, DisplayInside inside, ListItem list_item)
: m_type(Type::OutsideAndInside)
{
m_value.outside_inside = {
@ -215,13 +182,13 @@ public:
};
}
explicit Display(Internal internal)
explicit Display(DisplayInternal internal)
: m_type(Type::Internal)
{
m_value.internal = internal;
}
explicit Display(Box box)
explicit Display(DisplayBox box)
: m_type(Type::Box)
{
m_value.box = box;
@ -231,12 +198,12 @@ private:
Type m_type {};
union {
struct {
Outside outside;
Inside inside;
DisplayOutside outside;
DisplayInside inside;
ListItem list_item;
} outside_inside;
Internal internal;
Box box;
DisplayInternal internal;
DisplayBox box;
} m_value {};
};

View File

@ -133,6 +133,43 @@
"zoom-in",
"zoom-out"
],
"display-box": [
"contents",
"none"
],
"display-inside": [
"flow",
"flow-root",
"table",
"flex",
"grid",
"ruby"
],
"display-internal": [
"table-row-group",
"table-header-group",
"table-footer-group",
"table-row",
"table-cell",
"table-column-group",
"table-column",
"table-caption",
"ruby-base",
"ruby-text",
"ruby-base-container",
"ruby-text-container"
],
"display-legacy": [
"inline-block",
"inline-table",
"inline-flex",
"inline-grid"
],
"display-outside": [
"block",
"inline",
"run-in"
],
"fill-rule": [
"nonzero",
"evenodd"

View File

@ -3543,111 +3543,64 @@ RefPtr<StyleValue> Parser::parse_content_value(Vector<ComponentValue> const& com
// https://www.w3.org/TR/css-display-3/#the-display-properties
RefPtr<StyleValue> Parser::parse_display_value(Vector<ComponentValue> const& component_values)
{
auto parse_inside = [](ValueID identifier) -> Optional<Display::Inside> {
switch (identifier) {
case ValueID::Flow:
return Display::Inside::Flow;
case ValueID::FlowRoot:
return Display::Inside::FlowRoot;
case ValueID::Table:
return Display::Inside::Table;
case ValueID::Flex:
return Display::Inside::Flex;
case ValueID::Grid:
return Display::Inside::Grid;
case ValueID::Ruby:
return Display::Inside::Ruby;
default:
return {};
}
};
auto parse_outside = [](ValueID identifier) -> Optional<Display::Outside> {
switch (identifier) {
case ValueID::Block:
return Display::Outside::Block;
case ValueID::Inline:
return Display::Outside::Inline;
case ValueID::RunIn:
return Display::Outside::RunIn;
default:
return {};
}
};
auto parse_single_component_display = [&](Vector<ComponentValue> const& component_values) -> Optional<Display> {
if (auto identifier = parse_identifier_value(component_values.first())) {
switch (identifier->to_identifier()) {
// display-outside
case ValueID::Block:
return Display::from_short(Display::Short::Block);
case ValueID::Inline:
return Display::from_short(Display::Short::Inline);
case ValueID::RunIn:
return Display::from_short(Display::Short::RunIn);
// display-inside
case ValueID::Flow:
return Display::from_short(Display::Short::Flow);
case ValueID::FlowRoot:
return Display::from_short(Display::Short::FlowRoot);
case ValueID::Table:
return Display::from_short(Display::Short::Table);
case ValueID::Flex:
return Display::from_short(Display::Short::Flex);
case ValueID::Grid:
return Display::from_short(Display::Short::Grid);
case ValueID::Ruby:
return Display::from_short(Display::Short::Ruby);
// display-listitem
case ValueID::ListItem:
if (auto identifier_value = parse_identifier_value(component_values.first())) {
auto identifier = identifier_value->to_identifier();
if (identifier == ValueID::ListItem)
return Display::from_short(Display::Short::ListItem);
// display-internal
case ValueID::TableRowGroup:
return Display { Display::Internal::TableRowGroup };
case ValueID::TableHeaderGroup:
return Display { Display::Internal::TableHeaderGroup };
case ValueID::TableFooterGroup:
return Display { Display::Internal::TableFooterGroup };
case ValueID::TableRow:
return Display { Display::Internal::TableRow };
case ValueID::TableCell:
return Display { Display::Internal::TableCell };
case ValueID::TableColumnGroup:
return Display { Display::Internal::TableColumnGroup };
case ValueID::TableColumn:
return Display { Display::Internal::TableColumn };
case ValueID::TableCaption:
return Display { Display::Internal::TableCaption };
case ValueID::RubyBase:
return Display { Display::Internal::RubyBase };
case ValueID::RubyText:
return Display { Display::Internal::RubyText };
case ValueID::RubyBaseContainer:
return Display { Display::Internal::RubyBaseContainer };
case ValueID::RubyTextContainer:
return Display { Display::Internal::RubyTextContainer };
if (auto display_outside = value_id_to_display_outside(identifier); display_outside.has_value()) {
switch (display_outside.value()) {
case DisplayOutside::Block:
return Display::from_short(Display::Short::Block);
case DisplayOutside::Inline:
return Display::from_short(Display::Short::Inline);
case DisplayOutside::RunIn:
return Display::from_short(Display::Short::RunIn);
}
}
// display-box
case ValueID::Contents:
return Display::from_short(Display::Short::Contents);
case ValueID::None:
return Display::from_short(Display::Short::None);
if (auto display_inside = value_id_to_display_inside(identifier); display_inside.has_value()) {
switch (display_inside.value()) {
case DisplayInside::Flow:
return Display::from_short(Display::Short::Flow);
case DisplayInside::FlowRoot:
return Display::from_short(Display::Short::FlowRoot);
case DisplayInside::Table:
return Display::from_short(Display::Short::Table);
case DisplayInside::Flex:
return Display::from_short(Display::Short::Flex);
case DisplayInside::Grid:
return Display::from_short(Display::Short::Grid);
case DisplayInside::Ruby:
return Display::from_short(Display::Short::Ruby);
}
}
// display-legacy
case ValueID::InlineBlock:
return Display::from_short(Display::Short::InlineBlock);
case ValueID::InlineTable:
return Display::from_short(Display::Short::InlineTable);
case ValueID::InlineFlex:
return Display::from_short(Display::Short::InlineFlex);
case ValueID::InlineGrid:
return Display::from_short(Display::Short::InlineGrid);
if (auto display_internal = value_id_to_display_internal(identifier); display_internal.has_value()) {
return Display { display_internal.value() };
}
default:
return OptionalNone {};
if (auto display_box = value_id_to_display_box(identifier); display_box.has_value()) {
switch (display_box.value()) {
case DisplayBox::Contents:
return Display::from_short(Display::Short::Contents);
case DisplayBox::None:
return Display::from_short(Display::Short::None);
}
}
if (auto display_legacy = value_id_to_display_legacy(identifier); display_legacy.has_value()) {
switch (display_legacy.value()) {
case DisplayLegacy::InlineBlock:
return Display::from_short(Display::Short::InlineBlock);
case DisplayLegacy::InlineTable:
return Display::from_short(Display::Short::InlineTable);
case DisplayLegacy::InlineFlex:
return Display::from_short(Display::Short::InlineFlex);
case DisplayLegacy::InlineGrid:
return Display::from_short(Display::Short::InlineGrid);
}
}
}
return OptionalNone {};
@ -3655,8 +3608,8 @@ RefPtr<StyleValue> Parser::parse_display_value(Vector<ComponentValue> const& com
auto parse_multi_component_display = [&](Vector<ComponentValue> const& component_values) -> Optional<Display> {
auto list_item = Display::ListItem::No;
Optional<Display::Inside> inside;
Optional<Display::Outside> outside;
Optional<DisplayInside> inside;
Optional<DisplayOutside> outside;
for (size_t i = 0; i < component_values.size(); ++i) {
if (auto value = parse_identifier_value(component_values[i])) {
@ -3667,13 +3620,13 @@ RefPtr<StyleValue> Parser::parse_display_value(Vector<ComponentValue> const& com
list_item = Display::ListItem::Yes;
continue;
}
if (auto inside_value = parse_inside(identifier); inside_value.has_value()) {
if (auto inside_value = value_id_to_display_inside(identifier); inside_value.has_value()) {
if (inside.has_value())
return {};
inside = inside_value.value();
continue;
}
if (auto outside_value = parse_outside(identifier); outside_value.has_value()) {
if (auto outside_value = value_id_to_display_outside(identifier); outside_value.has_value()) {
if (outside.has_value())
return {};
outside = outside_value.value();
@ -3688,10 +3641,10 @@ RefPtr<StyleValue> Parser::parse_display_value(Vector<ComponentValue> const& com
// The spec does not allow any other inside values to be combined with list-item
// <display-outside>? && [ flow | flow-root ]? && list-item
if (list_item == Display::ListItem::Yes && inside.has_value() && inside != Display::Inside::Flow && inside != Display::Inside::FlowRoot)
if (list_item == Display::ListItem::Yes && inside.has_value() && inside != DisplayInside::Flow && inside != DisplayInside::FlowRoot)
return {};
return Display { outside.value_or(Display::Outside::Block), inside.value_or(Display::Inside::Flow), list_item };
return Display { outside.value_or(DisplayOutside::Block), inside.value_or(DisplayInside::Flow), list_item };
};
Optional<Display> display;

View File

@ -724,29 +724,14 @@
"initial": "inline",
"max-values": 3,
"valid-identifiers": [
"block",
"contents",
"flex",
"flow-root",
"grid",
"inline",
"inline-block",
"inline-flex",
"inline-grid",
"inline-table",
"list-item",
"none",
"ruby",
"run-in",
"table",
"table-caption",
"table-cell",
"table-column",
"table-column-group",
"table-footer-group",
"table-header-group",
"table-row",
"table-row-group"
"list-item"
],
"valid-types": [
"display-outside",
"display-inside",
"display-internal",
"display-box",
"display-legacy"
]
},
"fill": {

View File

@ -2258,9 +2258,9 @@ void StyleComputer::transform_box_type_if_needed(StyleProperties& style, DOM::El
// For legacy reasons, if an inline block box (inline flow-root) is blockified, it becomes a block box (losing its flow-root nature).
// For consistency, a run-in flow-root box also blockifies to a block box.
if (display.is_inline_block()) {
new_display = CSS::Display { CSS::Display::Outside::Block, CSS::Display::Inside::Flow, display.list_item() };
new_display = CSS::Display { CSS::DisplayOutside::Block, CSS::DisplayInside::Flow, display.list_item() };
} else {
new_display = CSS::Display { CSS::Display::Outside::Block, display.inside(), display.list_item() };
new_display = CSS::Display { CSS::DisplayOutside::Block, display.inside(), display.list_item() };
}
}
break;
@ -2281,10 +2281,10 @@ void StyleComputer::transform_box_type_if_needed(StyleProperties& style, DOM::El
// If a block box (block flow) is inlinified, its inner display type is set to flow-root so that it remains a block container.
if (display.is_block_outside() && display.is_flow_inside()) {
new_display = CSS::Display { CSS::Display::Outside::Inline, CSS::Display::Inside::FlowRoot, display.list_item() };
new_display = CSS::Display { CSS::DisplayOutside::Inline, CSS::DisplayInside::FlowRoot, display.list_item() };
}
new_display = CSS::Display { CSS::Display::Outside::Inline, display.inside(), display.list_item() };
new_display = CSS::Display { CSS::DisplayOutside::Inline, display.inside(), display.list_item() };
}
break;
}

View File

@ -830,7 +830,7 @@ CSS::Display Node::display() const
{
if (!has_style()) {
// NOTE: No style means this is dumb text content.
return CSS::Display(CSS::Display::Outside::Inline, CSS::Display::Inside::Flow);
return CSS::Display(CSS::DisplayOutside::Inline, CSS::DisplayInside::Flow);
}
return computed_values().display();
@ -856,7 +856,7 @@ bool Node::is_inline_table() const
JS::NonnullGCPtr<NodeWithStyle> NodeWithStyle::create_anonymous_wrapper() const
{
auto wrapper = heap().allocate_without_realm<BlockContainer>(const_cast<DOM::Document&>(document()), nullptr, m_computed_values.clone_inherited_values());
static_cast<CSS::MutableComputedValues&>(wrapper->m_computed_values).set_display(CSS::Display(CSS::Display::Outside::Block, CSS::Display::Inside::Flow));
static_cast<CSS::MutableComputedValues&>(wrapper->m_computed_values).set_display(CSS::Display(CSS::DisplayOutside::Block, CSS::DisplayInside::Flow));
wrapper->m_font = m_font;
wrapper->m_line_height = m_line_height;
return *wrapper;

View File

@ -302,7 +302,7 @@ ErrorOr<void> TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::
layout_node = document.heap().allocate_without_realm<Layout::Viewport>(static_cast<DOM::Document&>(dom_node), *style);
} else if (is<DOM::Text>(dom_node)) {
layout_node = document.heap().allocate_without_realm<Layout::TextNode>(document, static_cast<DOM::Text&>(dom_node));
display = CSS::Display(CSS::Display::Outside::Inline, CSS::Display::Inside::Flow);
display = CSS::Display(CSS::DisplayOutside::Inline, CSS::DisplayInside::Flow);
}
if (!layout_node)
@ -377,7 +377,7 @@ ErrorOr<void> TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::
// FIXME: Only apply alignment when box overflows
auto flex_computed_values = parent.computed_values().clone_inherited_values();
auto& mutable_flex_computed_values = static_cast<CSS::MutableComputedValues&>(flex_computed_values);
mutable_flex_computed_values.set_display(CSS::Display { CSS::Display::Outside::Block, CSS::Display::Inside::Flex });
mutable_flex_computed_values.set_display(CSS::Display { CSS::DisplayOutside::Block, CSS::DisplayInside::Flex });
mutable_flex_computed_values.set_justify_content(CSS::JustifyContent::Center);
mutable_flex_computed_values.set_flex_direction(CSS::FlexDirection::Column);
mutable_flex_computed_values.set_height(CSS::Size::make_percentage(CSS::Percentage(100)));
@ -430,7 +430,7 @@ JS::GCPtr<Layout::Node> TreeBuilder::build(DOM::Node& dom_node)
return move(m_layout_root);
}
template<CSS::Display::Internal internal, typename Callback>
template<CSS::DisplayInternal internal, typename Callback>
void TreeBuilder::for_each_in_tree_with_internal_display(NodeWithStyle& root, Callback callback)
{
root.for_each_in_inclusive_subtree_of_type<Box>([&](auto& box) {
@ -441,7 +441,7 @@ void TreeBuilder::for_each_in_tree_with_internal_display(NodeWithStyle& root, Ca
});
}
template<CSS::Display::Inside inside, typename Callback>
template<CSS::DisplayInside inside, typename Callback>
void TreeBuilder::for_each_in_tree_with_inside_display(NodeWithStyle& root, Callback callback)
{
root.for_each_in_inclusive_subtree_of_type<Box>([&](auto& box) {
@ -467,14 +467,14 @@ void TreeBuilder::remove_irrelevant_boxes(NodeWithStyle& root)
Vector<JS::Handle<Node>> to_remove;
// Children of a table-column.
for_each_in_tree_with_internal_display<CSS::Display::Internal::TableColumn>(root, [&](Box& table_column) {
for_each_in_tree_with_internal_display<CSS::DisplayInternal::TableColumn>(root, [&](Box& table_column) {
table_column.for_each_child([&](auto& child) {
to_remove.append(child);
});
});
// Children of a table-column-group which are not a table-column.
for_each_in_tree_with_internal_display<CSS::Display::Internal::TableColumnGroup>(root, [&](Box& table_column_group) {
for_each_in_tree_with_internal_display<CSS::DisplayInternal::TableColumnGroup>(root, [&](Box& table_column_group) {
table_column_group.for_each_child([&](auto& child) {
if (!child.display().is_table_column())
to_remove.append(child);
@ -596,35 +596,35 @@ static void wrap_in_anonymous(Vector<JS::Handle<Node>>& sequence, Node* nearest_
void TreeBuilder::generate_missing_child_wrappers(NodeWithStyle& root)
{
// An anonymous table-row box must be generated around each sequence of consecutive children of a table-root box which are not proper table child boxes.
for_each_in_tree_with_inside_display<CSS::Display::Inside::Table>(root, [&](auto& parent) {
for_each_in_tree_with_inside_display<CSS::DisplayInside::Table>(root, [&](auto& parent) {
for_each_sequence_of_consecutive_children_matching(parent, is_not_proper_table_child, [&](auto sequence, auto nearest_sibling) {
wrap_in_anonymous<Box>(sequence, nearest_sibling, CSS::Display { CSS::Display::Internal::TableRow });
wrap_in_anonymous<Box>(sequence, nearest_sibling, CSS::Display { CSS::DisplayInternal::TableRow });
});
});
// An anonymous table-row box must be generated around each sequence of consecutive children of a table-row-group box which are not table-row boxes.
for_each_in_tree_with_internal_display<CSS::Display::Internal::TableRowGroup>(root, [&](auto& parent) {
for_each_in_tree_with_internal_display<CSS::DisplayInternal::TableRowGroup>(root, [&](auto& parent) {
for_each_sequence_of_consecutive_children_matching(parent, is_not_table_row, [&](auto& sequence, auto nearest_sibling) {
wrap_in_anonymous<Box>(sequence, nearest_sibling, CSS::Display { CSS::Display::Internal::TableRow });
wrap_in_anonymous<Box>(sequence, nearest_sibling, CSS::Display { CSS::DisplayInternal::TableRow });
});
});
// Unless explicitly mentioned otherwise, mentions of table-row-groups in this spec also encompass the specialized
// table-header-groups and table-footer-groups.
for_each_in_tree_with_internal_display<CSS::Display::Internal::TableHeaderGroup>(root, [&](auto& parent) {
for_each_in_tree_with_internal_display<CSS::DisplayInternal::TableHeaderGroup>(root, [&](auto& parent) {
for_each_sequence_of_consecutive_children_matching(parent, is_not_table_row, [&](auto& sequence, auto nearest_sibling) {
wrap_in_anonymous<Box>(sequence, nearest_sibling, CSS::Display { CSS::Display::Internal::TableRow });
wrap_in_anonymous<Box>(sequence, nearest_sibling, CSS::Display { CSS::DisplayInternal::TableRow });
});
});
for_each_in_tree_with_internal_display<CSS::Display::Internal::TableFooterGroup>(root, [&](auto& parent) {
for_each_in_tree_with_internal_display<CSS::DisplayInternal::TableFooterGroup>(root, [&](auto& parent) {
for_each_sequence_of_consecutive_children_matching(parent, is_not_table_row, [&](auto& sequence, auto nearest_sibling) {
wrap_in_anonymous<Box>(sequence, nearest_sibling, CSS::Display { CSS::Display::Internal::TableRow });
wrap_in_anonymous<Box>(sequence, nearest_sibling, CSS::Display { CSS::DisplayInternal::TableRow });
});
});
// An anonymous table-cell box must be generated around each sequence of consecutive children of a table-row box which are not table-cell boxes. !Testcase
for_each_in_tree_with_internal_display<CSS::Display::Internal::TableRow>(root, [&](auto& parent) {
for_each_in_tree_with_internal_display<CSS::DisplayInternal::TableRow>(root, [&](auto& parent) {
for_each_sequence_of_consecutive_children_matching(parent, is_not_table_cell, [&](auto& sequence, auto nearest_sibling) {
wrap_in_anonymous<BlockContainer>(sequence, nearest_sibling, CSS::Display { CSS::Display::Internal::TableCell });
wrap_in_anonymous<BlockContainer>(sequence, nearest_sibling, CSS::Display { CSS::DisplayInternal::TableCell });
});
});
}
@ -636,7 +636,7 @@ Vector<JS::Handle<Box>> TreeBuilder::generate_missing_parents(NodeWithStyle& roo
// An anonymous table-row box must be generated around each sequence of consecutive table-cell boxes whose parent is not a table-row.
if (is_not_table_row(parent)) {
for_each_sequence_of_consecutive_children_matching(parent, is_table_cell, [&](auto& sequence, auto nearest_sibling) {
wrap_in_anonymous<Box>(sequence, nearest_sibling, CSS::Display { CSS::Display::Internal::TableRow });
wrap_in_anonymous<Box>(sequence, nearest_sibling, CSS::Display { CSS::DisplayInternal::TableRow });
});
}
@ -705,7 +705,7 @@ static void fixup_row(Box& row_box, TableGrid const& table_grid, size_t row_inde
missing_cells_run_has_started = true;
auto row_computed_values = row_box.computed_values().clone_inherited_values();
auto& cell_computed_values = static_cast<CSS::MutableComputedValues&>(row_computed_values);
cell_computed_values.set_display(Web::CSS::Display { CSS::Display::Internal::TableCell });
cell_computed_values.set_display(Web::CSS::Display { CSS::DisplayInternal::TableCell });
// Ensure that the cell (with zero content height) will have the same height as the row by setting vertical-align to middle.
cell_computed_values.set_vertical_align(CSS::VerticalAlign::Middle);
auto cell_box = row_box.heap().template allocate_without_realm<BlockContainer>(row_box.document(), nullptr, cell_computed_values);

View File

@ -30,10 +30,10 @@ private:
void push_parent(Layout::NodeWithStyle& node) { m_ancestor_stack.append(node); }
void pop_parent() { m_ancestor_stack.take_last(); }
template<CSS::Display::Internal, typename Callback>
template<CSS::DisplayInternal, typename Callback>
void for_each_in_tree_with_internal_display(NodeWithStyle& root, Callback);
template<CSS::Display::Inside, typename Callback>
template<CSS::DisplayInside, typename Callback>
void for_each_in_tree_with_inside_display(NodeWithStyle& root, Callback);
void fixup_tables(NodeWithStyle& root);