Bladeren bron

LibWeb: Make SVG <svg> elements behave as CSS replaced elements

This makes SVG-in-HTML behave quite a bit better by following general
replaced layout rules. It also turns <svg> elements into inline-level
boxes instead of block-level boxes.
Andreas Kling 3 jaren geleden
bovenliggende
commit
28b771560a

+ 5 - 0
Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp

@@ -14,6 +14,7 @@
 #include <LibWeb/Layout/InlineLevelIterator.h>
 #include <LibWeb/Layout/LineBuilder.h>
 #include <LibWeb/Layout/ReplacedBox.h>
+#include <LibWeb/Layout/SVGSVGBox.h>
 
 namespace Web::Layout {
 
@@ -109,6 +110,10 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l
 
     if (is<ReplacedBox>(box)) {
         auto& replaced = verify_cast<ReplacedBox>(box);
+
+        if (is<SVGSVGBox>(box))
+            (void)layout_inside(replaced, layout_mode);
+
         box_state.content_width = compute_width_for_replaced_element(m_state, replaced);
         box_state.content_height = compute_height_for_replaced_element(m_state, replaced);
         return;

+ 1 - 1
Userland/Libraries/LibWeb/Layout/SVGBox.cpp

@@ -9,7 +9,7 @@
 namespace Web::Layout {
 
 SVGBox::SVGBox(DOM::Document& document, SVG::SVGElement& element, NonnullRefPtr<CSS::StyleProperties> style)
-    : BlockContainer(document, &element, move(style))
+    : Box(document, &element, move(style))
 {
 }
 

+ 1 - 1
Userland/Libraries/LibWeb/Layout/SVGBox.h

@@ -12,7 +12,7 @@
 
 namespace Web::Layout {
 
-class SVGBox : public BlockContainer {
+class SVGBox : public Box {
 public:
     SVGBox(DOM::Document&, SVG::SVGElement&, NonnullRefPtr<CSS::StyleProperties>);
     virtual ~SVGBox() override = default;

+ 2 - 2
Userland/Libraries/LibWeb/Layout/SVGSVGBox.cpp

@@ -4,13 +4,13 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
-#include <LibWeb/Layout/SVGSVGBox.h>
+#include <LibWeb/Layout/ReplacedBox.h>
 #include <LibWeb/Painting/SVGSVGPaintable.h>
 
 namespace Web::Layout {
 
 SVGSVGBox::SVGSVGBox(DOM::Document& document, SVG::SVGSVGElement& element, NonnullRefPtr<CSS::StyleProperties> properties)
-    : SVGGraphicsBox(document, element, properties)
+    : ReplacedBox(document, element, move(properties))
 {
 }
 

+ 3 - 3
Userland/Libraries/LibWeb/Layout/SVGSVGBox.h

@@ -6,17 +6,17 @@
 
 #pragma once
 
-#include <LibWeb/Layout/SVGGraphicsBox.h>
+#include <LibWeb/Layout/ReplacedBox.h>
 #include <LibWeb/SVG/SVGSVGElement.h>
 
 namespace Web::Layout {
 
-class SVGSVGBox final : public SVGGraphicsBox {
+class SVGSVGBox final : public ReplacedBox {
 public:
     SVGSVGBox(DOM::Document&, SVG::SVGSVGElement&, NonnullRefPtr<CSS::StyleProperties>);
     virtual ~SVGSVGBox() override = default;
 
-    SVG::SVGSVGElement& dom_node() { return verify_cast<SVG::SVGSVGElement>(SVGGraphicsBox::dom_node()); }
+    SVG::SVGSVGElement& dom_node() { return verify_cast<SVG::SVGSVGElement>(ReplacedBox::dom_node()); }
 
     virtual bool can_have_children() const override { return true; }
 

+ 2 - 0
Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp

@@ -145,6 +145,8 @@ void TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder::Context&
 
     if (!dom_node.parent_or_shadow_host()) {
         m_layout_root = layout_node;
+    } else if (layout_node->is_svg_box()) {
+        m_parent_stack.last()->append_child(*layout_node);
     } else {
         insert_node_into_inline_or_block_ancestor(layout_node);
     }

+ 1 - 1
Userland/Libraries/LibWeb/Painting/SVGPaintable.cpp

@@ -10,7 +10,7 @@
 namespace Web::Painting {
 
 SVGPaintable::SVGPaintable(Layout::SVGBox const& layout_box)
-    : PaintableWithLines(layout_box)
+    : PaintableBox(layout_box)
 {
 }
 

+ 1 - 1
Userland/Libraries/LibWeb/Painting/SVGPaintable.h

@@ -11,7 +11,7 @@
 
 namespace Web::Painting {
 
-class SVGPaintable : public PaintableWithLines {
+class SVGPaintable : public PaintableBox {
 public:
     virtual void before_children_paint(PaintContext&, PaintPhase) const override;
     virtual void after_children_paint(PaintContext&, PaintPhase) const override;

+ 3 - 3
Userland/Libraries/LibWeb/Painting/SVGSVGPaintable.cpp

@@ -15,7 +15,7 @@ NonnullRefPtr<SVGSVGPaintable> SVGSVGPaintable::create(Layout::SVGSVGBox const&
 }
 
 SVGSVGPaintable::SVGSVGPaintable(Layout::SVGSVGBox const& layout_box)
-    : SVGGraphicsPaintable(layout_box)
+    : PaintableBox(layout_box)
 {
 }
 
@@ -32,12 +32,12 @@ void SVGSVGPaintable::before_children_paint(PaintContext& context, PaintPhase ph
     if (!context.has_svg_context())
         context.set_svg_context(SVGContext(absolute_rect()));
 
-    SVGGraphicsPaintable::before_children_paint(context, phase);
+    PaintableBox::before_children_paint(context, phase);
 }
 
 void SVGSVGPaintable::after_children_paint(PaintContext& context, PaintPhase phase) const
 {
-    SVGGraphicsPaintable::after_children_paint(context, phase);
+    PaintableBox::after_children_paint(context, phase);
     if (phase != PaintPhase::Foreground)
         return;
     context.clear_svg_context();

+ 2 - 2
Userland/Libraries/LibWeb/Painting/SVGSVGPaintable.h

@@ -7,11 +7,11 @@
 #pragma once
 
 #include <LibWeb/Layout/SVGSVGBox.h>
-#include <LibWeb/Painting/SVGGraphicsPaintable.h>
+#include <LibWeb/Painting/PaintableBox.h>
 
 namespace Web::Painting {
 
-class SVGSVGPaintable : public SVGGraphicsPaintable {
+class SVGSVGPaintable : public PaintableBox {
 public:
     static NonnullRefPtr<SVGSVGPaintable> create(Layout::SVGSVGBox const&);