LibWeb: Layout foreignObject as block-level element with hidden overflow

This is according to the default user-agent style from the SVG2 spec.

In order for this to work correctly, we also have to assign width and
height to foreignObject boxes during SVG layout, since they are handled
manually by SVGFormattingContext.
This commit is contained in:
Andreas Kling 2025-07-07 19:30:38 +02:00 committed by Andreas Kling
commit b4708510fb
Notes: github-actions[bot] 2025-07-09 12:37:48 +00:00
4 changed files with 35 additions and 17 deletions

View file

@ -282,6 +282,8 @@ void SVGFormattingContext::layout_svg_element(Box const& child)
bfc.run(*m_available_space);
auto& child_state = m_state.get_mutable(child);
child_state.set_content_offset(child_state.offset.translated(m_svg_offset));
child_state.set_content_width(child.computed_values().width().to_px(child, m_available_space->width.to_px_or_zero()));
child_state.set_content_height(child.computed_values().height().to_px(child, m_available_space->height.to_px_or_zero()));
child.for_each_child_of_type<SVGMaskBox>([&](SVGMaskBox const& child) {
layout_svg_element(child);
return IterationDecision::Continue;

View file

@ -32,3 +32,8 @@ symbol {
:link, :visited {
cursor: pointer;
}
foreignObject {
display: block;
overflow: hidden;
}

View file

@ -1,14 +1,16 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x166 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x150 children: not-inline
SVGSVGBox <svg> at (8,8) content-size 300x150 [SVG] children: inline
TextNode <#text>
SVGSVGBox <svg> at (8,8) content-size 300x150 [SVG] children: not-inline
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
SVGForeignObjectBox <foreignObject> at (8,8) content-size 100x200 [BFC] children: not-inline
BlockContainer <(anonymous)> at (8,8) content-size 300x0 children: inline
TextNode <#text>
BlockContainer <div.el> at (8,8) content-size 50x60 positioned [BFC] children: not-inline
TextNode <#text>
TextNode <#text>
BlockContainer <(anonymous)> (not painted) children: inline
TextNode <#text>
BlockContainer <(anonymous)> at (8,158) content-size 784x0 children: inline
TextNode <#text>

View file

@ -1,22 +1,31 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x116 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x100 children: inline
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 100x100] baseline: 100
SVGSVGBox <svg> at (8,8) content-size 100x100 [SVG] children: inline
SVGForeignObjectBox <foreignObject> at (8,8) content-size 100x100 [BFC] children: not-inline
BlockContainer <div> at (8,8) content-size 100x18 children: inline
frag 0 from TextNode start: 0, length: 3, rect: [8,8 27.15625x18] baseline: 13.796875
BlockContainer <html> at (0,0) content-size 800x316 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x300 children: not-inline
BlockContainer <(anonymous)> at (8,8) content-size 784x100 children: inline
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 100x100] baseline: 100
SVGSVGBox <svg> at (8,8) content-size 100x100 [SVG] children: inline
BlockContainer <(anonymous)> at (8,108) content-size 784x100 children: not-inline continuation
SVGForeignObjectBox <foreignObject> at (8,108) content-size 100x100 [BFC] children: not-inline
BlockContainer <div> at (8,108) content-size 100x18 children: inline
frag 0 from TextNode start: 0, length: 3, rect: [8,108 27.15625x18] baseline: 13.796875
"foo"
TextNode <#text>
BlockContainer <(anonymous)> at (8,208) content-size 784x100 children: inline
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,208 100x100] baseline: 100
SVGSVGBox <svg> at (8,208) content-size 100x100 [SVG] children: not-inline continuation
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x116]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x100]
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 100x100]
SVGForeignObjectPaintable (SVGForeignObjectBox<foreignObject>) [8,8 100x100]
PaintableWithLines (BlockContainer<DIV>) [8,8 100x18]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x316]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x300]
PaintableWithLines (BlockContainer(anonymous)) [8,8 784x100]
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 100x100]
PaintableWithLines (BlockContainer(anonymous)) [8,108 784x100]
SVGForeignObjectPaintable (SVGForeignObjectBox<foreignObject>) [8,108 100x100]
PaintableWithLines (BlockContainer<DIV>) [8,108 100x18]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer(anonymous)) [8,208 784x100]
SVGSVGPaintable (SVGSVGBox<svg>) [8,208 100x100]
SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto)
SC for BlockContainer<HTML> [0,0 800x116] [children: 1] (z-index: auto)
SC for SVGForeignObjectBox<foreignObject> [8,8 100x100] [children: 0] (z-index: auto)
SC for BlockContainer<HTML> [0,0 800x316] [children: 1] (z-index: auto)
SC for SVGForeignObjectBox<foreignObject> [8,108 100x100] [children: 0] (z-index: auto)