diff --git a/Userland/Libraries/LibWeb/CSS/ComputedValues.h b/Userland/Libraries/LibWeb/CSS/ComputedValues.h index efa80e1e96..8e207e10b2 100644 --- a/Userland/Libraries/LibWeb/CSS/ComputedValues.h +++ b/Userland/Libraries/LibWeb/CSS/ComputedValues.h @@ -22,7 +22,7 @@ public: static CSS::Position position() { return CSS::Position::Static; } static CSS::TextDecorationLine text_decoration_line() { return CSS::TextDecorationLine::None; } static CSS::TextTransform text_transform() { return CSS::TextTransform::None; } - static CSS::Display display() { return CSS::Display::Inline; } + static CSS::Display display() { return CSS::Display { CSS::Display::Outside::Inline, CSS::Display::Inside::Flow }; } static Color color() { return Color::Black; } static Color background_color() { return Color::Transparent; } static CSS::Repeat background_repeat() { return CSS::Repeat::Repeat; } diff --git a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp index 2398bab657..87f5943e8a 100644 --- a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp +++ b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp @@ -44,41 +44,78 @@ static CSS::ValueID to_css_value_id(CSS::BoxSizing value) VERIFY_NOT_REACHED(); } -static CSS::ValueID to_css_value_id(CSS::Display value) +static RefPtr style_value_for_display(CSS::Display display) { - switch (value) { - case CSS::Display::None: - return CSS::ValueID::None; - case CSS::Display::Block: - return CSS::ValueID::Block; - case CSS::Display::Inline: - return CSS::ValueID::Inline; - case CSS::Display::InlineBlock: - return CSS::ValueID::InlineBlock; - case CSS::Display::ListItem: - return CSS::ValueID::ListItem; - case CSS::Display::Table: - return CSS::ValueID::Table; - case CSS::Display::TableRow: - return CSS::ValueID::TableRow; - case CSS::Display::TableCell: - return CSS::ValueID::TableCell; - case CSS::Display::TableHeaderGroup: - return CSS::ValueID::TableHeaderGroup; - case CSS::Display::TableRowGroup: - return CSS::ValueID::TableRowGroup; - case CSS::Display::TableFooterGroup: - return CSS::ValueID::TableFooterGroup; - case CSS::Display::TableColumn: - return CSS::ValueID::TableColumn; - case CSS::Display::TableColumnGroup: - return CSS::ValueID::TableColumnGroup; - case CSS::Display::TableCaption: - return CSS::ValueID::TableCaption; - case CSS::Display::Flex: - return CSS::ValueID::Flex; + if (display.is_none()) + return IdentifierStyleValue::create(CSS::ValueID::None); + + if (display.it_outside_and_inside()) { + NonnullRefPtrVector values; + switch (display.outside()) { + case CSS::Display::Outside::Inline: + values.append(IdentifierStyleValue::create(CSS::ValueID::Inline)); + break; + case CSS::Display::Outside::Block: + values.append(IdentifierStyleValue::create(CSS::ValueID::Block)); + break; + case CSS::Display::Outside::RunIn: + values.append(IdentifierStyleValue::create(CSS::ValueID::RunIn)); + break; + } + switch (display.inside()) { + case CSS::Display::Inside::Flow: + values.append(IdentifierStyleValue::create(CSS::ValueID::Flow)); + break; + case CSS::Display::Inside::FlowRoot: + values.append(IdentifierStyleValue::create(CSS::ValueID::FlowRoot)); + break; + case CSS::Display::Inside::Table: + values.append(IdentifierStyleValue::create(CSS::ValueID::Table)); + break; + case CSS::Display::Inside::Flex: + values.append(IdentifierStyleValue::create(CSS::ValueID::Flex)); + break; + case CSS::Display::Inside::Grid: + values.append(IdentifierStyleValue::create(CSS::ValueID::Grid)); + break; + case CSS::Display::Inside::Ruby: + values.append(IdentifierStyleValue::create(CSS::ValueID::Ruby)); + break; + } + + return StyleValueList::create(move(values)); } - VERIFY_NOT_REACHED(); + + if (display.is_internal()) { + switch (display.internal()) { + case CSS::Display::Internal::TableRowGroup: + return IdentifierStyleValue::create(CSS::ValueID::TableRowGroup); + case CSS::Display::Internal::TableHeaderGroup: + return IdentifierStyleValue::create(CSS::ValueID::TableHeaderGroup); + case CSS::Display::Internal::TableFooterGroup: + return IdentifierStyleValue::create(CSS::ValueID::TableFooterGroup); + case CSS::Display::Internal::TableRow: + return IdentifierStyleValue::create(CSS::ValueID::TableRow); + case CSS::Display::Internal::TableCell: + return IdentifierStyleValue::create(CSS::ValueID::TableCell); + case CSS::Display::Internal::TableColumnGroup: + return IdentifierStyleValue::create(CSS::ValueID::TableColumnGroup); + case CSS::Display::Internal::TableColumn: + return IdentifierStyleValue::create(CSS::ValueID::TableColumn); + case CSS::Display::Internal::TableCaption: + return IdentifierStyleValue::create(CSS::ValueID::TableCaption); + case CSS::Display::Internal::RubyBase: + return IdentifierStyleValue::create(CSS::ValueID::RubyBase); + case CSS::Display::Internal::RubyText: + return IdentifierStyleValue::create(CSS::ValueID::RubyText); + case CSS::Display::Internal::RubyBaseContainer: + return IdentifierStyleValue::create(CSS::ValueID::RubyBaseContainer); + case CSS::Display::Internal::RubyTextContainer: + return IdentifierStyleValue::create(CSS::ValueID::RubyTextContainer); + } + } + + TODO(); } static CSS::ValueID to_css_value_id(CSS::Float value) @@ -427,7 +464,7 @@ RefPtr ResolvedCSSStyleDeclaration::style_value_for_property(Layout: case CSS::PropertyID::Cursor: return IdentifierStyleValue::create(to_css_value_id(layout_node.computed_values().cursor())); case CSS::PropertyID::Display: - return IdentifierStyleValue::create(to_css_value_id(layout_node.computed_values().display())); + return style_value_for_display(layout_node.computed_values().display()); case CSS::PropertyID::ZIndex: { auto maybe_z_index = layout_node.computed_values().z_index(); if (!maybe_z_index.has_value()) diff --git a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp index 872af5b496..33b02ba3e5 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp @@ -530,40 +530,40 @@ CSS::Display StyleProperties::display() const { auto value = property(CSS::PropertyID::Display); if (!value.has_value() || !value.value()->is_identifier()) - return CSS::Display::Inline; + return CSS::Display::from_short(CSS::Display::Short::Inline); switch (value.value()->to_identifier()) { case CSS::ValueID::None: - return CSS::Display::None; + return CSS::Display::from_short(CSS::Display::Short::None); case CSS::ValueID::Block: - return CSS::Display::Block; + return CSS::Display::from_short(CSS::Display::Short::Block); case CSS::ValueID::Inline: - return CSS::Display::Inline; + return CSS::Display::from_short(CSS::Display::Short::Inline); case CSS::ValueID::InlineBlock: - return CSS::Display::InlineBlock; + return CSS::Display::from_short(CSS::Display::Short::InlineBlock); case CSS::ValueID::ListItem: - return CSS::Display::ListItem; + return CSS::Display::from_short(CSS::Display::Short::ListItem); case CSS::ValueID::Table: - return CSS::Display::Table; + return CSS::Display::from_short(CSS::Display::Short::Table); case CSS::ValueID::TableRow: - return CSS::Display::TableRow; + return CSS::Display { CSS::Display::Internal::TableRow }; case CSS::ValueID::TableCell: - return CSS::Display::TableCell; + return CSS::Display { CSS::Display::Internal::TableCell }; case CSS::ValueID::TableColumn: - return CSS::Display::TableColumn; + return CSS::Display { CSS::Display::Internal::TableColumn }; case CSS::ValueID::TableColumnGroup: - return CSS::Display::TableColumnGroup; + return CSS::Display { CSS::Display::Internal::TableColumnGroup }; case CSS::ValueID::TableCaption: - return CSS::Display::TableCaption; + return CSS::Display { CSS::Display::Internal::TableCaption }; case CSS::ValueID::TableRowGroup: - return CSS::Display::TableRowGroup; + return CSS::Display { CSS::Display::Internal::TableRowGroup }; case CSS::ValueID::TableHeaderGroup: - return CSS::Display::TableHeaderGroup; + return CSS::Display { CSS::Display::Internal::TableHeaderGroup }; case CSS::ValueID::TableFooterGroup: - return CSS::Display::TableFooterGroup; + return CSS::Display { CSS::Display::Internal::TableFooterGroup }; case CSS::ValueID::Flex: - return CSS::Display::Flex; + return CSS::Display::from_short(CSS::Display::Short::Flex); default: - return CSS::Display::Block; + return CSS::Display::from_short(CSS::Display::Short::Block); } } diff --git a/Userland/Libraries/LibWeb/CSS/StyleValue.h b/Userland/Libraries/LibWeb/CSS/StyleValue.h index a250980b99..31cc3a17d5 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleValue.h +++ b/Userland/Libraries/LibWeb/CSS/StyleValue.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -90,24 +91,6 @@ enum class Cursor { ZoomOut, }; -enum class Display { - None, - Block, - Inline, - InlineBlock, - ListItem, - Table, - TableRow, - TableCell, - TableHeaderGroup, - TableRowGroup, - TableFooterGroup, - TableColumn, - TableColumnGroup, - TableCaption, - Flex, -}; - enum class FlexBasis { Content, Length, diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index 5045d96650..9462e61b46 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -110,48 +110,48 @@ RefPtr Element::create_layout_node() const_cast(*this).m_specified_css_values = style; auto display = style->display(); - if (display == CSS::Display::None) + if (display.is_none()) return nullptr; if (local_name() == "noscript" && document().is_scripting_enabled()) return nullptr; - switch (display) { - case CSS::Display::None: - VERIFY_NOT_REACHED(); - break; - case CSS::Display::Block: - return adopt_ref(*new Layout::BlockBox(document(), this, move(style))); - case CSS::Display::Inline: - if (style->float_().value_or(CSS::Float::None) != CSS::Float::None) - return adopt_ref(*new Layout::BlockBox(document(), this, move(style))); - return adopt_ref(*new Layout::InlineNode(document(), *this, move(style))); - case CSS::Display::ListItem: - return adopt_ref(*new Layout::ListItemBox(document(), *this, move(style))); - case CSS::Display::Table: + if (display.is_table_inside()) return adopt_ref(*new Layout::TableBox(document(), this, move(style))); - case CSS::Display::TableRow: + + if (display.is_list_item()) + return adopt_ref(*new Layout::ListItemBox(document(), *this, move(style))); + + if (display.is_table_row()) return adopt_ref(*new Layout::TableRowBox(document(), this, move(style))); - case CSS::Display::TableCell: + + if (display.is_table_cell()) return adopt_ref(*new Layout::TableCellBox(document(), this, move(style))); - case CSS::Display::TableRowGroup: - case CSS::Display::TableHeaderGroup: - case CSS::Display::TableFooterGroup: + + if (display.is_table_row_group() || display.is_table_header_group() || display.is_table_footer_group()) return adopt_ref(*new Layout::TableRowGroupBox(document(), *this, move(style))); - case CSS::Display::InlineBlock: { - auto inline_block = adopt_ref(*new Layout::BlockBox(document(), this, move(style))); - inline_block->set_inline(true); - return inline_block; - } - case CSS::Display::Flex: - return adopt_ref(*new Layout::BlockBox(document(), this, move(style))); - case CSS::Display::TableColumn: - case CSS::Display::TableColumnGroup: - case CSS::Display::TableCaption: + + if (display.is_table_column() || display.is_table_column_group() || display.is_table_caption()) { // FIXME: This is just an incorrect placeholder until we improve table layout support. return adopt_ref(*new Layout::BlockBox(document(), this, move(style))); } - VERIFY_NOT_REACHED(); + + if (display.is_inline_outside()) { + if (display.is_flow_root_inside()) { + auto block = adopt_ref(*new Layout::BlockBox(document(), this, move(style))); + block->set_inline(true); + return block; + } + if (display.is_flow_inside()) + return adopt_ref(*new Layout::InlineNode(document(), *this, move(style))); + + TODO(); + } + + if (display.is_flow_inside() || display.is_flow_root_inside() || display.is_flex_inside()) + return adopt_ref(*new Layout::BlockBox(document(), this, move(style))); + + TODO(); } void Element::parse_attribute(const FlyString& name, const String& value) @@ -209,7 +209,7 @@ void Element::recompute_style() auto new_specified_css_values = document().style_computer().compute_style(*this); m_specified_css_values = new_specified_css_values; if (!layout_node()) { - if (new_specified_css_values->display() == CSS::Display::None) + if (new_specified_css_values->display().is_none()) return; // We need a new layout tree here! Layout::TreeBuilder tree_builder; diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index ba7c2f1210..b67e4d7fa4 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -176,7 +176,7 @@ void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool sho builder.appendff(" {}floating{}", floating_color_on, color_off); if (box.is_inline_block()) builder.appendff(" {}inline-block{}", inline_block_color_on, color_off); - if (box.computed_values().display() == CSS::Display::Flex) + if (box.computed_values().display().is_flex_inside()) builder.appendff(" {}flex-container{}", flex_color_on, color_off); if (box.is_flex_item()) builder.appendff(" {}flex-item{}", flex_color_on, color_off); diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 6fc6fd757d..2b092f926b 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -26,6 +26,7 @@ class CSSRuleList; class CSSStyleDeclaration; class CSSStyleRule; class CSSStyleSheet; +class Display; class ElementInlineCSSStyleDeclaration; class Length; class MediaList; @@ -38,7 +39,6 @@ class Selector; class StyleProperties; class StyleComputer; class StyleSheet; -enum class Display; class StyleValue; class BackgroundRepeatStyleValue; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLBRElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLBRElement.cpp index 8d35f793eb..ce8dcd9746 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLBRElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLBRElement.cpp @@ -22,7 +22,7 @@ HTMLBRElement::~HTMLBRElement() RefPtr HTMLBRElement::create_layout_node() { auto style = document().style_computer().compute_style(*this); - if (style->display() == CSS::Display::None) + if (style->display().is_none()) return nullptr; return adopt_ref(*new Layout::BreakNode(document(), *this, move(style))); } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp index 0b70f6983b..f3773c315b 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp @@ -40,7 +40,7 @@ unsigned HTMLCanvasElement::height() const RefPtr HTMLCanvasElement::create_layout_node() { auto style = document().style_computer().compute_style(*this); - if (style->display() == CSS::Display::None) + if (style->display().is_none()) return nullptr; return adopt_ref(*new Layout::CanvasBox(document(), *this, move(style))); } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp index 4d6c32adb1..8265d0099a 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp @@ -71,7 +71,7 @@ void HTMLImageElement::parse_attribute(const FlyString& name, const String& valu RefPtr HTMLImageElement::create_layout_node() { auto style = document().style_computer().compute_style(*this); - if (style->display() == CSS::Display::None) + if (style->display().is_none()) return nullptr; return adopt_ref(*new Layout::ImageBox(document(), *this, move(style), m_image_loader)); } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 52d30e5d6b..43b32e99ca 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -47,7 +47,7 @@ RefPtr HTMLInputElement::create_layout_node() return nullptr; auto style = document().style_computer().compute_style(*this); - if (style->display() == CSS::Display::None) + if (style->display().is_none()) return nullptr; if (type().equals_ignoring_case("submit") || type().equals_ignoring_case("button")) diff --git a/Userland/Libraries/LibWeb/HTML/HTMLLabelElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLLabelElement.cpp index 4907d4ece2..e2e469c321 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLLabelElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLLabelElement.cpp @@ -22,7 +22,7 @@ HTMLLabelElement::~HTMLLabelElement() RefPtr HTMLLabelElement::create_layout_node() { auto style = document().style_computer().compute_style(*this); - if (style->display() == CSS::Display::None) + if (style->display().is_none()) return nullptr; auto layout_node = adopt_ref(*new Layout::Label(document(), this, move(style))); diff --git a/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp index eea0acc7a1..41a3180d6e 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLObjectElement.cpp @@ -47,7 +47,7 @@ RefPtr HTMLObjectElement::create_layout_node() return HTMLElement::create_layout_node(); auto style = document().style_computer().compute_style(*this); - if (style->display() == CSS::Display::None) + if (style->display().is_none()) return nullptr; if (m_image_loader.has_image()) return adopt_ref(*new Layout::ImageBox(document(), *this, move(style), m_image_loader)); diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp index a65afd4229..a22eb9e848 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -50,16 +50,23 @@ bool FormattingContext::creates_block_formatting_context(const Box& box) if ((overflow_y != CSS::Overflow::Visible) && (overflow_y != CSS::Overflow::Clip)) return true; + auto display = box.computed_values().display(); + + if (display.is_flow_root_inside()) + return true; + // FIXME: inline-flex as well - if (box.parent() && box.parent()->computed_values().display() == CSS::Display::Flex) { - // FIXME: Flex items (direct children of the element with display: flex or inline-flex) if they are neither flex nor grid nor table containers themselves. - if (box.computed_values().display() != CSS::Display::Flex) - return true; + if (box.parent()) { + auto parent_display = box.parent()->computed_values().display(); + if (parent_display.is_flex_inside()) { + // FIXME: Flex items (direct children of the element with display: flex or inline-flex) if they are neither flex nor grid nor table containers themselves. + if (!display.is_flex_inside()) + return true; + } } // FIXME: table-caption // FIXME: anonymous table cells - // FIXME: display: flow-root // FIXME: Elements with contain: layout, content, or paint. // FIXME: grid // FIXME: multicol @@ -67,37 +74,46 @@ bool FormattingContext::creates_block_formatting_context(const Box& box) return false; } -void FormattingContext::layout_inside(Box& box, LayoutMode layout_mode) +void FormattingContext::layout_inside(Box& child_box, LayoutMode layout_mode) { - if (is(box)) { - SVGFormattingContext context(box, this); - context.run(box, layout_mode); + auto context_display = context_box().computed_values().display(); + + if (is(child_box)) { + SVGFormattingContext context(child_box, this); + context.run(child_box, layout_mode); return; } - if (box.computed_values().display() == CSS::Display::Flex) { - FlexFormattingContext context(box, this); - context.run(box, layout_mode); + auto child_display = child_box.computed_values().display(); + + if (child_display.is_flex_inside()) { + FlexFormattingContext context(child_box, this); + context.run(child_box, layout_mode); return; } - if (creates_block_formatting_context(box)) { - BlockFormattingContext context(box, this); - context.run(box, layout_mode); + if (creates_block_formatting_context(child_box)) { + BlockFormattingContext context(child_box, this); + context.run(child_box, layout_mode); return; } - if (is(box)) { - TableFormattingContext context(box, this); - context.run(box, layout_mode); - } else if (box.children_are_inline()) { - InlineFormattingContext context(box, this); - context.run(box, layout_mode); - } else { - // FIXME: This needs refactoring! - VERIFY(is_block_formatting_context()); - run(box, layout_mode); + if (child_display.is_table_inside()) { + TableFormattingContext context(child_box, this); + context.run(child_box, layout_mode); + return; } + + VERIFY(is_block_formatting_context()); + + if (child_box.children_are_inline()) { + InlineFormattingContext context(child_box, this); + context.run(child_box, layout_mode); + return; + } + + VERIFY(child_display.is_flow_inside()); + run(child_box, layout_mode); } static float greatest_child_width(const Box& box) diff --git a/Userland/Libraries/LibWeb/Layout/TableBox.h b/Userland/Libraries/LibWeb/Layout/TableBox.h index fe1bafc514..2f4e8bd667 100644 --- a/Userland/Libraries/LibWeb/Layout/TableBox.h +++ b/Userland/Libraries/LibWeb/Layout/TableBox.h @@ -16,7 +16,7 @@ public: TableBox(DOM::Document&, DOM::Element*, CSS::ComputedValues); virtual ~TableBox() override; - static CSS::Display static_display() { return CSS::Display::Table; } + static CSS::Display static_display() { return CSS::Display::from_short(CSS::Display::Short::Table); } }; } diff --git a/Userland/Libraries/LibWeb/Layout/TableCellBox.h b/Userland/Libraries/LibWeb/Layout/TableCellBox.h index 1cb021a117..78943403a9 100644 --- a/Userland/Libraries/LibWeb/Layout/TableCellBox.h +++ b/Userland/Libraries/LibWeb/Layout/TableCellBox.h @@ -21,7 +21,7 @@ public: size_t colspan() const; - static CSS::Display static_display() { return CSS::Display::TableCell; } + static CSS::Display static_display() { return CSS::Display { CSS::Display::Internal::TableCell }; } private: virtual float width_of_logical_containing_block() const override; diff --git a/Userland/Libraries/LibWeb/Layout/TableRowBox.h b/Userland/Libraries/LibWeb/Layout/TableRowBox.h index 5e573151c8..e7f6b1f783 100644 --- a/Userland/Libraries/LibWeb/Layout/TableRowBox.h +++ b/Userland/Libraries/LibWeb/Layout/TableRowBox.h @@ -16,7 +16,7 @@ public: TableRowBox(DOM::Document&, DOM::Element*, CSS::ComputedValues); virtual ~TableRowBox() override; - static CSS::Display static_display() { return CSS::Display::TableRow; } + static CSS::Display static_display() { return CSS::Display { CSS::Display::Internal::TableRow }; } }; } diff --git a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp index 98d3d92f35..7fa72fe08a 100644 --- a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -33,7 +33,7 @@ static Layout::Node& insertion_parent_for_inline_node(Layout::NodeWithStyle& lay if (layout_parent.is_inline() && !layout_parent.is_inline_block()) return layout_parent; - if (layout_parent.computed_values().display() == CSS::Display::Flex) { + if (layout_parent.computed_values().display().is_flex_inside()) { layout_parent.append_child(layout_parent.create_anonymous_wrapper()); } @@ -97,7 +97,7 @@ void TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::Context& if (!dom_node.parent_or_shadow_host()) { m_layout_root = layout_node; } else { - if (layout_node->is_inline() && !(layout_node->is_inline_block() && m_parent_stack.last()->computed_values().display() == CSS::Display::Flex)) { + if (layout_node->is_inline() && !(layout_node->is_inline_block() && m_parent_stack.last()->computed_values().display().is_flex_inside())) { // Inlines can be inserted into the nearest ancestor. auto& insertion_point = insertion_parent_for_inline_node(*m_parent_stack.last()); insertion_point.append_child(*layout_node); @@ -147,11 +147,23 @@ RefPtr TreeBuilder::build(DOM::Node& dom_node) return move(m_layout_root); } -template -void TreeBuilder::for_each_in_tree_with_display(NodeWithStyle& root, Callback callback) +template +void TreeBuilder::for_each_in_tree_with_internal_display(NodeWithStyle& root, Callback callback) { root.for_each_in_inclusive_subtree_of_type([&](auto& box) { - if (box.computed_values().display() == display) + auto const& display = box.computed_values().display(); + if (display.is_internal() && display.internal() == internal) + callback(box); + return IterationDecision::Continue; + }); +} + +template +void TreeBuilder::for_each_in_tree_with_inside_display(NodeWithStyle& root, Callback callback) +{ + root.for_each_in_inclusive_subtree_of_type([&](auto& box) { + auto const& display = box.computed_values().display(); + if (display.it_outside_and_inside() && display.inside() == inside) callback(box); return IterationDecision::Continue; }); @@ -173,16 +185,16 @@ void TreeBuilder::remove_irrelevant_boxes(NodeWithStyle& root) NonnullRefPtrVector to_remove; // Children of a table-column. - for_each_in_tree_with_display(root, [&](Box& table_column) { + for_each_in_tree_with_internal_display(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_display(root, [&](Box& table_column_group) { + for_each_in_tree_with_internal_display(root, [&](Box& table_column_group) { table_column_group.for_each_child([&](auto& child) { - if (child.computed_values().display() != CSS::Display::TableColumn) + if (child.computed_values().display().is_table_column()) to_remove.append(child); }); }); @@ -200,15 +212,17 @@ void TreeBuilder::remove_irrelevant_boxes(NodeWithStyle& root) static bool is_table_track(CSS::Display display) { - return display == CSS::Display::TableRow || display == CSS::Display::TableColumn; + return display.is_table_row() || display.is_table_column(); } static bool is_table_track_group(CSS::Display display) { // Unless explicitly mentioned otherwise, mentions of table-row-groups in this spec also encompass the specialized // table-header-groups and table-footer-groups. - return display == CSS::Display::TableRowGroup || display == CSS::Display::TableHeaderGroup || display == CSS::Display::TableFooterGroup - || display == CSS::Display::TableColumnGroup; + return display.is_table_row_group() + || display.is_table_header_group() + || display.is_table_footer_group() + || display.is_table_column_group(); } static bool is_not_proper_table_child(const Node& node) @@ -216,7 +230,7 @@ static bool is_not_proper_table_child(const Node& node) if (!node.has_style()) return true; auto display = node.computed_values().display(); - return !is_table_track_group(display) && !is_table_track(display) && display != CSS::Display::TableCaption; + return !is_table_track_group(display) && !is_table_track(display) && !display.is_table_caption(); } static bool is_not_table_row(const Node& node) @@ -224,7 +238,7 @@ static bool is_not_table_row(const Node& node) if (!node.has_style()) return true; auto display = node.computed_values().display(); - return display != CSS::Display::TableRow; + return !display.is_table_row(); } static bool is_not_table_cell(const Node& node) @@ -232,7 +246,7 @@ static bool is_not_table_cell(const Node& node) if (!node.has_style()) return true; auto display = node.computed_values().display(); - return display != CSS::Display::TableCell; + return !display.is_table_cell(); } template @@ -276,33 +290,33 @@ static void wrap_in_anonymous(NonnullRefPtrVector& 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_display(root, [&](auto& parent) { + for_each_in_tree_with_inside_display(root, [&](auto& parent) { for_each_sequence_of_consecutive_children_matching(parent, is_not_proper_table_child, [&](auto sequence, auto nearest_sibling) { wrap_in_anonymous(sequence, nearest_sibling); }); }); // 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_display(root, [&](auto& parent) { + for_each_in_tree_with_internal_display(root, [&](auto& parent) { for_each_sequence_of_consecutive_children_matching(parent, is_not_table_row, [&](auto& sequence, auto nearest_sibling) { wrap_in_anonymous(sequence, nearest_sibling); }); }); // 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_display(root, [&](auto& parent) { + for_each_in_tree_with_internal_display(root, [&](auto& parent) { for_each_sequence_of_consecutive_children_matching(parent, is_not_table_row, [&](auto& sequence, auto nearest_sibling) { wrap_in_anonymous(sequence, nearest_sibling); }); }); - for_each_in_tree_with_display(root, [&](auto& parent) { + for_each_in_tree_with_internal_display(root, [&](auto& parent) { for_each_sequence_of_consecutive_children_matching(parent, is_not_table_row, [&](auto& sequence, auto nearest_sibling) { wrap_in_anonymous(sequence, nearest_sibling); }); }); // 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_display(root, [&](auto& parent) { + for_each_in_tree_with_internal_display(root, [&](auto& parent) { for_each_sequence_of_consecutive_children_matching(parent, is_not_table_cell, [&](auto& sequence, auto nearest_sibling) { wrap_in_anonymous(sequence, nearest_sibling); }); diff --git a/Userland/Libraries/LibWeb/Layout/TreeBuilder.h b/Userland/Libraries/LibWeb/Layout/TreeBuilder.h index a0a711ffc5..ae000a4765 100644 --- a/Userland/Libraries/LibWeb/Layout/TreeBuilder.h +++ b/Userland/Libraries/LibWeb/Layout/TreeBuilder.h @@ -28,8 +28,11 @@ private: void push_parent(Layout::NodeWithStyle& node) { m_parent_stack.append(&node); } void pop_parent() { m_parent_stack.take_last(); } - template - void for_each_in_tree_with_display(NodeWithStyle& root, Callback); + template + void for_each_in_tree_with_internal_display(NodeWithStyle& root, Callback); + + template + void for_each_in_tree_with_inside_display(NodeWithStyle& root, Callback); void fixup_tables(NodeWithStyle& root); void remove_irrelevant_boxes(NodeWithStyle& root); diff --git a/Userland/Libraries/LibWeb/SVG/SVGGElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGGElement.cpp index ec905ef6cd..fc1a7ff177 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGGElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGGElement.cpp @@ -19,7 +19,7 @@ SVGGElement::SVGGElement(DOM::Document& document, QualifiedName qualified_name) RefPtr SVGGElement::create_layout_node() { auto style = document().style_computer().compute_style(*this); - if (style->display() == CSS::Display::None) + if (style->display().is_none()) return nullptr; return adopt_ref(*new Layout::SVGGraphicsBox(document(), *this, move(style))); } diff --git a/Userland/Libraries/LibWeb/SVG/SVGPathElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGPathElement.cpp index 741df4a6b6..03f9ca48d8 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGPathElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGPathElement.cpp @@ -446,7 +446,7 @@ SVGPathElement::SVGPathElement(DOM::Document& document, QualifiedName qualified_ RefPtr SVGPathElement::create_layout_node() { auto style = document().style_computer().compute_style(*this); - if (style->display() == CSS::Display::None) + if (style->display().is_none()) return nullptr; return adopt_ref(*new Layout::SVGPathBox(document(), *this, move(style))); } diff --git a/Userland/Libraries/LibWeb/SVG/SVGSVGElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGSVGElement.cpp index 9be889f5c9..f001ebd778 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGSVGElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGSVGElement.cpp @@ -22,7 +22,7 @@ SVGSVGElement::SVGSVGElement(DOM::Document& document, QualifiedName qualified_na RefPtr SVGSVGElement::create_layout_node() { auto style = document().style_computer().compute_style(*this); - if (style->display() == CSS::Display::None) + if (style->display().is_none()) return nullptr; return adopt_ref(*new Layout::SVGSVGBox(document(), *this, move(style))); }