mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibWeb: Position absolute block-level boxes below previous siblings
Whether an absbox is positioned below or to the right of its previous sibling in an `InlineFormattingContext` is determined by the display-outside value before blockification, so we store the pre-blockification `display` value in `ComputedValues` to access it in `InlineFormattingContext` and position the box accordingly.
This commit is contained in:
parent
7867fef8d7
commit
5b1eba7ac8
|
|
@ -132,6 +132,16 @@ void ComputedProperties::revert_property(PropertyID id, ComputedProperties const
|
|||
set_property_inherited(id, style_for_revert.is_property_inherited(id) ? Inherited::Yes : Inherited::No);
|
||||
}
|
||||
|
||||
Display ComputedProperties::display_before_box_type_transformation() const
|
||||
{
|
||||
return m_display_before_box_type_transformation;
|
||||
}
|
||||
|
||||
void ComputedProperties::set_display_before_box_type_transformation(Display value)
|
||||
{
|
||||
m_display_before_box_type_transformation = value;
|
||||
}
|
||||
|
||||
void ComputedProperties::set_animated_property(PropertyID id, NonnullRefPtr<StyleValue const> value, Inherited inherited)
|
||||
{
|
||||
m_animated_property_values.set(id, move(value));
|
||||
|
|
|
|||
|
|
@ -186,6 +186,9 @@ public:
|
|||
MixBlendMode mix_blend_mode() const;
|
||||
Optional<FlyString> view_transition_name() const;
|
||||
|
||||
Display display_before_box_type_transformation() const;
|
||||
void set_display_before_box_type_transformation(Display value);
|
||||
|
||||
static Vector<Transformation> transformations_for_style_value(StyleValue const& value);
|
||||
Vector<Transformation> transformations() const;
|
||||
TransformBox transform_box() const;
|
||||
|
|
@ -279,6 +282,8 @@ private:
|
|||
|
||||
HashMap<PropertyID, NonnullRefPtr<StyleValue const>> m_animated_property_values;
|
||||
|
||||
Display m_display_before_box_type_transformation { InitialValues::display() };
|
||||
|
||||
int m_math_depth { InitialValues::math_depth() };
|
||||
RefPtr<Gfx::FontCascadeList const> m_font_list;
|
||||
RefPtr<Gfx::Font const> m_first_available_computed_font;
|
||||
|
|
|
|||
|
|
@ -487,6 +487,7 @@ public:
|
|||
CSS::ContentData content() const { return m_noninherited.content; }
|
||||
CSS::PointerEvents pointer_events() const { return m_inherited.pointer_events; }
|
||||
CSS::Display display() const { return m_noninherited.display; }
|
||||
CSS::Display display_before_box_type_transformation() const { return m_noninherited.display_before_box_type_transformation; }
|
||||
Optional<int> const& z_index() const { return m_noninherited.z_index; }
|
||||
Variant<LengthOrCalculated, NumberOrCalculated> tab_size() const { return m_inherited.tab_size; }
|
||||
CSS::TextAlign text_align() const { return m_inherited.text_align; }
|
||||
|
|
@ -756,6 +757,7 @@ protected:
|
|||
CSS::Clear clear { InitialValues::clear() };
|
||||
CSS::Clip clip { InitialValues::clip() };
|
||||
CSS::Display display { InitialValues::display() };
|
||||
CSS::Display display_before_box_type_transformation { InitialValues::display() };
|
||||
Optional<int> z_index;
|
||||
// FIXME: Store this as flags in a u8.
|
||||
Vector<CSS::TextDecorationLine> text_decoration_line { InitialValues::text_decoration_line() };
|
||||
|
|
@ -955,6 +957,7 @@ public:
|
|||
void set_list_style_type(CSS::ListStyleType value) { m_inherited.list_style_type = move(value); }
|
||||
void set_list_style_position(CSS::ListStylePosition value) { m_inherited.list_style_position = move(value); }
|
||||
void set_display(CSS::Display value) { m_noninherited.display = value; }
|
||||
void set_display_before_box_type_transformation(CSS::Display value) { m_noninherited.display_before_box_type_transformation = value; }
|
||||
void set_backdrop_filter(CSS::Filter const& backdrop_filter) { m_noninherited.backdrop_filter = backdrop_filter; }
|
||||
void set_filter(CSS::Filter const& filter) { m_noninherited.filter = filter; }
|
||||
void set_border_bottom_left_radius(CSS::BorderRadiusData value)
|
||||
|
|
|
|||
|
|
@ -2154,6 +2154,8 @@ void StyleComputer::compute_property_values(ComputedProperties& style) const
|
|||
|
||||
style.set_property(property_id, absolutized_value, is_inherited);
|
||||
});
|
||||
|
||||
style.set_display_before_box_type_transformation(style.display());
|
||||
}
|
||||
|
||||
void StyleComputer::resolve_effective_overflow_values(ComputedProperties& style) const
|
||||
|
|
|
|||
|
|
@ -503,8 +503,10 @@ StaticPositionRect InlineFormattingContext::calculate_static_position_rect(Box c
|
|||
|
||||
CSSPixelPoint position;
|
||||
if (auto const* sibling = box.previous_sibling()) {
|
||||
// We're calculating the position for an absolutely positioned box with a previous sibling in an IFC. We need to
|
||||
// position the box at the top right corner of the last fragment of this sibling.
|
||||
// We're calculating the position for an absolutely positioned box with a previous sibling in an IFC.
|
||||
// We need to position the box...
|
||||
// ...below the last fragment of this sibling, if the display-outside value (before box type transformation) is block.
|
||||
// ...at the top right corner of the last fragment of this sibling otherwise.
|
||||
LineBoxFragment const* last_fragment = nullptr;
|
||||
auto const& cb_state = m_state.get(*sibling->containing_block());
|
||||
for (auto const& line_box : cb_state.line_boxes) {
|
||||
|
|
@ -514,8 +516,15 @@ StaticPositionRect InlineFormattingContext::calculate_static_position_rect(Box c
|
|||
}
|
||||
}
|
||||
if (last_fragment) {
|
||||
position.set_x(last_fragment->offset().x() + last_fragment->width());
|
||||
position.set_y(last_fragment->offset().y());
|
||||
if (box.display_before_box_type_transformation().is_block_outside()) {
|
||||
// Display-outside value is block => position below
|
||||
position.set_x(0);
|
||||
position.set_y(last_fragment->offset().y() + last_fragment->height());
|
||||
} else {
|
||||
// Display-outside value is not block => position to the right
|
||||
position.set_x(last_fragment->offset().x() + last_fragment->width());
|
||||
position.set_y(last_fragment->offset().y());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -571,6 +571,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
|
|||
border_top_right_radius.as_border_radius().vertical_radius() });
|
||||
}
|
||||
computed_values.set_display(computed_style.display());
|
||||
computed_values.set_display_before_box_type_transformation(computed_style.display_before_box_type_transformation());
|
||||
|
||||
computed_values.set_flex_direction(computed_style.flex_direction());
|
||||
computed_values.set_flex_wrap(computed_style.flex_wrap());
|
||||
|
|
@ -968,6 +969,15 @@ CSS::Display Node::display() const
|
|||
return computed_values().display();
|
||||
}
|
||||
|
||||
CSS::Display Node::display_before_box_type_transformation() const
|
||||
{
|
||||
if (!has_style()) {
|
||||
return CSS::Display(CSS::DisplayOutside::Inline, CSS::DisplayInside::Flow);
|
||||
}
|
||||
|
||||
return computed_values().display_before_box_type_transformation();
|
||||
}
|
||||
|
||||
bool Node::is_inline() const
|
||||
{
|
||||
return display().is_inline_outside();
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ public:
|
|||
virtual bool can_have_children() const { return true; }
|
||||
|
||||
CSS::Display display() const;
|
||||
CSS::Display display_before_box_type_transformation() const;
|
||||
|
||||
bool is_inline() const;
|
||||
bool is_inline_block() const;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not-inline
|
||||
BlockContainer <html> at [0,0] [0+0+0 800 0+0+0] [0+0+0 34 0+0+0] [BFC] children: not-inline
|
||||
BlockContainer <body> at [8,8] [8+0+0 784 0+0+8] [8+0+0 18 0+0+8] children: inline
|
||||
frag 0 from TextNode start: 0, length: 3, rect: [8,8 27.15625x18] baseline: 13.796875
|
||||
"foo"
|
||||
TextNode <#text> (not painted)
|
||||
BlockContainer <div> at [8,26] positioned [0+0+0 27.640625 0+0+0] [0+0+0 18 0+0+0] [BFC] children: inline
|
||||
frag 0 from TextNode start: 0, length: 3, rect: [8,26 27.640625x18] baseline: 13.796875
|
||||
"bar"
|
||||
TextNode <#text> (not painted)
|
||||
TextNode <#text> (not painted)
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x34]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x18]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>) [8,26 27.640625x18]
|
||||
TextPaintable (TextNode<#text>)
|
||||
|
||||
SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto)
|
||||
SC for BlockContainer<HTML> [0,0 800x34] [children: 0] (z-index: auto)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
<!DOCTYPE html>
|
||||
foo <div style="position:absolute">bar</div>
|
||||
Loading…
Reference in New Issue
Block a user