summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-01-24 14:41:48 +0100
committerAndreas Kling <kling@serenityos.org>2022-01-24 14:44:46 +0100
commit12932d187e1da687d4cd64e18325563578320739 (patch)
treed8ade22e4d758382e4fb265eba74e85d71ce87fb
parent16d69376d829410184342f95b2df363bea6bbcb2 (diff)
LibWeb: Teach StyleComputer about "Automatic Box Type Transformation"
CSS has rules about automatic blockification or inlinification of boxes in certain circumstances. This patch implements automatic blockification of absolutely positioned and floating elements. This makes the smile appear on ACID2. :^)
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleComputer.cpp38
-rw-r--r--Userland/Libraries/LibWeb/CSS/StyleComputer.h1
2 files changed, 39 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
index 58adffc755..322c783636 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
+++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp
@@ -873,6 +873,41 @@ void StyleComputer::absolutize_values(StyleProperties& style, DOM::Element const
}
}
+// https://drafts.csswg.org/css-display/#transformations
+void StyleComputer::transform_box_type_if_needed(StyleProperties& style, DOM::Element const&) const
+{
+ // 2.7. Automatic Box Type Transformations
+
+ // Some layout effects require blockification or inlinification of the box type,
+ // which sets the box’s computed outer display type to block or inline (respectively).
+ // (This has no effect on display types that generate no box at all, such as none or contents.)
+
+ // Additionally:
+
+ // FIXME: If a block box (block flow) is inlinified, its inner display type is set to flow-root so that it remains a block container.
+ //
+ // FIXME: If an inline box (inline flow) is inlinified, it recursively inlinifies all of its in-flow children,
+ // so that no block-level descendants break up the inline formatting context in which it participates.
+ //
+ // FIXME: 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.
+ //
+ // FIXME: If a layout-internal box is blockified, its inner display type converts to flow so that it becomes a block container.
+ // Inlinification has no effect on layout-internal boxes. (However, placement in such an inline context will typically cause them
+ // to be wrapped in an appropriately-typed anonymous inline-level box.)
+
+ // Absolute positioning or floating an element blockifies the box’s display type. [CSS2]
+ auto display = style.display();
+ if (!display.is_none() && !display.is_contents() && !display.is_block_outside()) {
+ if (style.position() == CSS::Position::Absolute || style.position() == CSS::Position::Fixed || style.float_() != CSS::Float::None)
+ style.set_property(CSS::PropertyID::Display, IdentifierStyleValue::create(CSS::ValueID::Block));
+ }
+
+ // FIXME: Containment in a ruby container inlinifies the box’s display type, as described in [CSS-RUBY-1].
+
+ // FIXME: A parent with a grid or flex display value blockifies the box’s display type. [CSS-GRID-1] [CSS-FLEXBOX-1]
+}
+
NonnullRefPtr<StyleProperties> StyleComputer::create_document_style() const
{
auto style = StyleProperties::create();
@@ -897,6 +932,9 @@ NonnullRefPtr<StyleProperties> StyleComputer::compute_style(DOM::Element& elemen
// 4. Default the values, applying inheritance and 'initial' as needed
compute_defaulted_values(style, &element);
+ // 5. Run automatic box type transformations
+ transform_box_type_if_needed(style, element);
+
return style;
}
diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.h b/Userland/Libraries/LibWeb/CSS/StyleComputer.h
index 420c1b21cd..db35fea5b2 100644
--- a/Userland/Libraries/LibWeb/CSS/StyleComputer.h
+++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.h
@@ -78,6 +78,7 @@ private:
void compute_font(StyleProperties&, DOM::Element const*) const;
void compute_defaulted_values(StyleProperties&, DOM::Element const*) const;
void absolutize_values(StyleProperties&, DOM::Element const*) const;
+ void transform_box_type_if_needed(StyleProperties&, DOM::Element const&) const;
void compute_defaulted_property_value(StyleProperties&, DOM::Element const*, CSS::PropertyID) const;