mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-24 10:18:59 +00:00
LibWeb/CSS: Take AbstractElement in box-type transformation functions
This commit is contained in:
parent
44e70d9087
commit
cdbaa73576
Notes:
github-actions[bot]
2025-09-11 16:47:28 +00:00
Author: https://github.com/AtkinsSJ
Commit: cdbaa73576
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6118
2 changed files with 28 additions and 28 deletions
|
@ -2196,29 +2196,29 @@ enum class BoxTypeTransformation {
|
||||||
Inlinify,
|
Inlinify,
|
||||||
};
|
};
|
||||||
|
|
||||||
static BoxTypeTransformation required_box_type_transformation(ComputedProperties const& style, DOM::Element const& element, Optional<CSS::PseudoElement> const& pseudo_element)
|
static BoxTypeTransformation required_box_type_transformation(ComputedProperties const& style, DOM::AbstractElement abstract_element)
|
||||||
{
|
{
|
||||||
// NOTE: We never blockify <br> elements. They are always inline.
|
// NOTE: We never blockify <br> elements. They are always inline.
|
||||||
// There is currently no way to express in CSS how a <br> element really behaves.
|
// There is currently no way to express in CSS how a <br> element really behaves.
|
||||||
// Spec issue: https://github.com/whatwg/html/issues/2291
|
// Spec issue: https://github.com/whatwg/html/issues/2291
|
||||||
if (is<HTML::HTMLBRElement>(element))
|
if (!abstract_element.pseudo_element().has_value() && is<HTML::HTMLBRElement>(abstract_element.element()))
|
||||||
return BoxTypeTransformation::None;
|
return BoxTypeTransformation::None;
|
||||||
|
|
||||||
// Absolute positioning or floating an element blockifies the box’s display type. [CSS2]
|
// Absolute positioning or floating an element blockifies the box’s display type. [CSS2]
|
||||||
if (style.position() == CSS::Positioning::Absolute || style.position() == CSS::Positioning::Fixed || style.float_() != CSS::Float::None)
|
if (style.position() == Positioning::Absolute || style.position() == Positioning::Fixed || style.float_() != Float::None)
|
||||||
return BoxTypeTransformation::Blockify;
|
return BoxTypeTransformation::Blockify;
|
||||||
|
|
||||||
// FIXME: Containment in a ruby container inlinifies the box’s display type, as described in [CSS-RUBY-1].
|
// FIXME: Containment in a ruby container inlinifies the box’s display type, as described in [CSS-RUBY-1].
|
||||||
|
|
||||||
// NOTE: If we're computing style for a pseudo-element, the effective parent will be the originating element itself, not its parent.
|
// NOTE: If we're computing style for a pseudo-element, the effective parent will be the originating element itself, not its parent.
|
||||||
auto parent = element.element_to_inherit_style_from(pseudo_element);
|
auto parent = abstract_element.element_to_inherit_style_from();
|
||||||
|
|
||||||
// Climb out of `display: contents` context.
|
// Climb out of `display: contents` context.
|
||||||
while (parent && parent->computed_properties() && parent->computed_properties()->display().is_contents())
|
while (parent.has_value() && parent->computed_properties() && parent->computed_properties()->display().is_contents())
|
||||||
parent = parent->element_to_inherit_style_from({});
|
parent = parent->element_to_inherit_style_from();
|
||||||
|
|
||||||
// A parent with a grid or flex display value blockifies the box’s display type. [CSS-GRID-1] [CSS-FLEXBOX-1]
|
// A parent with a grid or flex display value blockifies the box’s display type. [CSS-GRID-1] [CSS-FLEXBOX-1]
|
||||||
if (parent && parent->computed_properties()) {
|
if (parent.has_value() && parent->computed_properties()) {
|
||||||
auto const& parent_display = parent->computed_properties()->display();
|
auto const& parent_display = parent->computed_properties()->display();
|
||||||
if (parent_display.is_grid_inside() || parent_display.is_flex_inside())
|
if (parent_display.is_grid_inside() || parent_display.is_flex_inside())
|
||||||
return BoxTypeTransformation::Blockify;
|
return BoxTypeTransformation::Blockify;
|
||||||
|
@ -2228,7 +2228,7 @@ static BoxTypeTransformation required_box_type_transformation(ComputedProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-display/#transformations
|
// https://drafts.csswg.org/css-display/#transformations
|
||||||
void StyleComputer::transform_box_type_if_needed(ComputedProperties& style, DOM::Element const& element, Optional<CSS::PseudoElement> pseudo_element) const
|
void StyleComputer::transform_box_type_if_needed(ComputedProperties& style, DOM::AbstractElement abstract_element) const
|
||||||
{
|
{
|
||||||
// 2.7. Automatic Box Type Transformations
|
// 2.7. Automatic Box Type Transformations
|
||||||
|
|
||||||
|
@ -2238,13 +2238,13 @@ void StyleComputer::transform_box_type_if_needed(ComputedProperties& style, DOM:
|
||||||
|
|
||||||
auto display = style.display();
|
auto display = style.display();
|
||||||
|
|
||||||
if (display.is_none() || (display.is_contents() && !element.is_document_element()))
|
if (display.is_none() || (display.is_contents() && !abstract_element.element().is_document_element()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-display/#root
|
// https://drafts.csswg.org/css-display/#root
|
||||||
// The root element’s display type is always blockified, and its principal box always establishes an independent formatting context.
|
// The root element’s display type is always blockified, and its principal box always establishes an independent formatting context.
|
||||||
if (element.is_document_element() && !display.is_block_outside()) {
|
if (abstract_element.element().is_document_element() && !display.is_block_outside()) {
|
||||||
style.set_property(CSS::PropertyID::Display, DisplayStyleValue::create(Display::from_short(CSS::Display::Short::Block)));
|
style.set_property(PropertyID::Display, DisplayStyleValue::create(Display::from_short(Display::Short::Block)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2254,20 +2254,20 @@ void StyleComputer::transform_box_type_if_needed(ComputedProperties& style, DOM:
|
||||||
// https://w3c.github.io/mathml-core/#new-display-math-value
|
// https://w3c.github.io/mathml-core/#new-display-math-value
|
||||||
// For elements that are not MathML elements, if the specified value of display is inline math or block math
|
// For elements that are not MathML elements, if the specified value of display is inline math or block math
|
||||||
// then the computed value is block flow and inline flow respectively.
|
// then the computed value is block flow and inline flow respectively.
|
||||||
if (element.namespace_uri() != Namespace::MathML)
|
if (abstract_element.element().namespace_uri() != Namespace::MathML)
|
||||||
new_display = CSS::Display { display.outside(), CSS::DisplayInside::Flow };
|
new_display = Display { display.outside(), DisplayInside::Flow };
|
||||||
// For the mtable element the computed value is block table and inline table respectively.
|
// For the mtable element the computed value is block table and inline table respectively.
|
||||||
else if (element.tag_name().equals_ignoring_ascii_case("mtable"sv))
|
else if (abstract_element.element().tag_name().equals_ignoring_ascii_case("mtable"sv))
|
||||||
new_display = CSS::Display { display.outside(), CSS::DisplayInside::Table };
|
new_display = Display { display.outside(), DisplayInside::Table };
|
||||||
// For the mtr element, the computed value is table-row.
|
// For the mtr element, the computed value is table-row.
|
||||||
else if (element.tag_name().equals_ignoring_ascii_case("mtr"sv))
|
else if (abstract_element.element().tag_name().equals_ignoring_ascii_case("mtr"sv))
|
||||||
new_display = CSS::Display { CSS::DisplayInternal::TableRow };
|
new_display = Display { DisplayInternal::TableRow };
|
||||||
// For the mtd element, the computed value is table-cell.
|
// For the mtd element, the computed value is table-cell.
|
||||||
else if (element.tag_name().equals_ignoring_ascii_case("mtd"sv))
|
else if (abstract_element.element().tag_name().equals_ignoring_ascii_case("mtd"sv))
|
||||||
new_display = CSS::Display { CSS::DisplayInternal::TableCell };
|
new_display = Display { DisplayInternal::TableCell };
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (required_box_type_transformation(style, element, pseudo_element)) {
|
switch (required_box_type_transformation(style, abstract_element)) {
|
||||||
case BoxTypeTransformation::None:
|
case BoxTypeTransformation::None:
|
||||||
break;
|
break;
|
||||||
case BoxTypeTransformation::Blockify:
|
case BoxTypeTransformation::Blockify:
|
||||||
|
@ -2275,16 +2275,16 @@ void StyleComputer::transform_box_type_if_needed(ComputedProperties& style, DOM:
|
||||||
return;
|
return;
|
||||||
// If a layout-internal box is blockified, its inner display type converts to flow so that it becomes a block container.
|
// If a layout-internal box is blockified, its inner display type converts to flow so that it becomes a block container.
|
||||||
if (display.is_internal()) {
|
if (display.is_internal()) {
|
||||||
new_display = CSS::Display::from_short(CSS::Display::Short::Block);
|
new_display = Display::from_short(Display::Short::Block);
|
||||||
} else {
|
} else {
|
||||||
VERIFY(display.is_outside_and_inside());
|
VERIFY(display.is_outside_and_inside());
|
||||||
|
|
||||||
// For legacy reasons, if an inline block box (inline flow-root) is blockified, it becomes a block box (losing its flow-root nature).
|
// 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.
|
// For consistency, a run-in flow-root box also blockifies to a block box.
|
||||||
if (display.is_inline_block()) {
|
if (display.is_inline_block()) {
|
||||||
new_display = CSS::Display { CSS::DisplayOutside::Block, CSS::DisplayInside::Flow, display.list_item() };
|
new_display = Display { DisplayOutside::Block, DisplayInside::Flow, display.list_item() };
|
||||||
} else {
|
} else {
|
||||||
new_display = CSS::Display { CSS::DisplayOutside::Block, display.inside(), display.list_item() };
|
new_display = Display { DisplayOutside::Block, display.inside(), display.list_item() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2305,16 +2305,16 @@ void StyleComputer::transform_box_type_if_needed(ComputedProperties& style, DOM:
|
||||||
|
|
||||||
// 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 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()) {
|
if (display.is_block_outside() && display.is_flow_inside()) {
|
||||||
new_display = CSS::Display { CSS::DisplayOutside::Inline, CSS::DisplayInside::FlowRoot, display.list_item() };
|
new_display = Display { DisplayOutside::Inline, DisplayInside::FlowRoot, display.list_item() };
|
||||||
}
|
}
|
||||||
|
|
||||||
new_display = CSS::Display { CSS::DisplayOutside::Inline, display.inside(), display.list_item() };
|
new_display = Display { DisplayOutside::Inline, display.inside(), display.list_item() };
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_display != display)
|
if (new_display != display)
|
||||||
style.set_property(CSS::PropertyID::Display, DisplayStyleValue::create(new_display));
|
style.set_property(PropertyID::Display, DisplayStyleValue::create(new_display));
|
||||||
}
|
}
|
||||||
|
|
||||||
GC::Ref<ComputedProperties> StyleComputer::create_document_style() const
|
GC::Ref<ComputedProperties> StyleComputer::create_document_style() const
|
||||||
|
@ -2638,7 +2638,7 @@ GC::Ref<ComputedProperties> StyleComputer::compute_properties(DOM::AbstractEleme
|
||||||
compute_property_values(computed_style);
|
compute_property_values(computed_style);
|
||||||
|
|
||||||
// 5. Run automatic box type transformations
|
// 5. Run automatic box type transformations
|
||||||
transform_box_type_if_needed(computed_style, abstract_element.element(), abstract_element.pseudo_element());
|
transform_box_type_if_needed(computed_style, abstract_element);
|
||||||
|
|
||||||
// 6. Apply any property-specific computed value logic
|
// 6. Apply any property-specific computed value logic
|
||||||
resolve_effective_overflow_values(computed_style);
|
resolve_effective_overflow_values(computed_style);
|
||||||
|
|
|
@ -239,7 +239,7 @@ private:
|
||||||
void compute_math_depth(ComputedProperties&, Optional<DOM::AbstractElement>) const;
|
void compute_math_depth(ComputedProperties&, Optional<DOM::AbstractElement>) const;
|
||||||
void start_needed_transitions(ComputedProperties const& old_style, ComputedProperties& new_style, DOM::AbstractElement) const;
|
void start_needed_transitions(ComputedProperties const& old_style, ComputedProperties& new_style, DOM::AbstractElement) const;
|
||||||
void resolve_effective_overflow_values(ComputedProperties&) const;
|
void resolve_effective_overflow_values(ComputedProperties&) const;
|
||||||
void transform_box_type_if_needed(ComputedProperties&, DOM::Element const&, Optional<CSS::PseudoElement>) const;
|
void transform_box_type_if_needed(ComputedProperties&, DOM::AbstractElement) const;
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
void for_each_stylesheet(CascadeOrigin, Callback) const;
|
void for_each_stylesheet(CascadeOrigin, Callback) const;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue