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); bfc.run(*m_available_space);
auto& child_state = m_state.get_mutable(child); auto& child_state = m_state.get_mutable(child);
child_state.set_content_offset(child_state.offset.translated(m_svg_offset)); 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) { child.for_each_child_of_type<SVGMaskBox>([&](SVGMaskBox const& child) {
layout_svg_element(child); layout_svg_element(child);
return IterationDecision::Continue; return IterationDecision::Continue;

View file

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

View file

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

View file

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