summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-11-10 13:49:26 +0100
committerAndreas Kling <kling@serenityos.org>2022-11-16 13:01:21 +0100
commit05556846822752788198cec70be63bcd86ea61cb (patch)
tree8ebc781f154ab183a7fe0602f245284e97cb0e92
parente9eba663618582bf4160911cbbb2fa61a979b939 (diff)
downloadserenity-05556846822752788198cec70be63bcd86ea61cb.zip
LibWeb: Sketch out basic support for SVG <foreignObject> elements
This patch adds basic DOM construction and IDL bindings for foreign objects in SVG trees.
-rw-r--r--Userland/Libraries/LibWeb/CMakeLists.txt1
-rw-r--r--Userland/Libraries/LibWeb/DOM/ElementFactory.cpp3
-rw-r--r--Userland/Libraries/LibWeb/Forward.h1
-rw-r--r--Userland/Libraries/LibWeb/SVG/SVGForeignObjectElement.cpp81
-rw-r--r--Userland/Libraries/LibWeb/SVG/SVGForeignObjectElement.h41
-rw-r--r--Userland/Libraries/LibWeb/SVG/SVGForeignObjectElement.idl11
-rw-r--r--Userland/Libraries/LibWeb/idl_files.cmake1
7 files changed, 139 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt
index 5d053ab8ea..03e44cf3a8 100644
--- a/Userland/Libraries/LibWeb/CMakeLists.txt
+++ b/Userland/Libraries/LibWeb/CMakeLists.txt
@@ -408,6 +408,7 @@ set(SOURCES
SVG/SVGPathElement.cpp
SVG/SVGCircleElement.cpp
SVG/SVGEllipseElement.cpp
+ SVG/SVGForeignObjectElement.cpp
SVG/SVGLength.cpp
SVG/SVGLineElement.cpp
SVG/SVGPolygonElement.cpp
diff --git a/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp b/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp
index 350ab64d2f..72281d0c51 100644
--- a/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp
+++ b/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp
@@ -81,6 +81,7 @@
#include <LibWeb/SVG/SVGClipPathElement.h>
#include <LibWeb/SVG/SVGDefsElement.h>
#include <LibWeb/SVG/SVGEllipseElement.h>
+#include <LibWeb/SVG/SVGForeignObjectElement.h>
#include <LibWeb/SVG/SVGGElement.h>
#include <LibWeb/SVG/SVGLineElement.h>
#include <LibWeb/SVG/SVGPathElement.h>
@@ -273,6 +274,8 @@ JS::NonnullGCPtr<Element> create_element(Document& document, FlyString local_nam
return *realm.heap().allocate<SVG::SVGDefsElement>(realm, document, move(qualified_name));
if (lowercase_tag_name == SVG::TagNames::ellipse)
return *realm.heap().allocate<SVG::SVGEllipseElement>(realm, document, move(qualified_name));
+ if (lowercase_tag_name.equals_ignoring_case(SVG::TagNames::foreignObject))
+ return *realm.heap().allocate<SVG::SVGForeignObjectElement>(realm, document, move(qualified_name));
if (lowercase_tag_name == SVG::TagNames::line)
return *realm.heap().allocate<SVG::SVGLineElement>(realm, document, move(qualified_name));
if (lowercase_tag_name == SVG::TagNames::path)
diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h
index 053690612d..b296efc7f6 100644
--- a/Userland/Libraries/LibWeb/Forward.h
+++ b/Userland/Libraries/LibWeb/Forward.h
@@ -403,6 +403,7 @@ class SVGClipPathElement;
class SVGDefsElement;
class SVGElement;
class SVGEllipseElement;
+class SVGForeignObjectElement;
class SVGGeometryElement;
class SVGGraphicsElement;
class SVGLength;
diff --git a/Userland/Libraries/LibWeb/SVG/SVGForeignObjectElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGForeignObjectElement.cpp
new file mode 100644
index 0000000000..75bd7a2c00
--- /dev/null
+++ b/Userland/Libraries/LibWeb/SVG/SVGForeignObjectElement.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibWeb/Bindings/Intrinsics.h>
+#include <LibWeb/HTML/Parser/HTMLParser.h>
+#include <LibWeb/Layout/BlockContainer.h>
+#include <LibWeb/SVG/AttributeNames.h>
+#include <LibWeb/SVG/SVGAnimatedLength.h>
+#include <LibWeb/SVG/SVGForeignObjectElement.h>
+#include <LibWeb/SVG/SVGLength.h>
+
+namespace Web::SVG {
+
+SVGForeignObjectElement::SVGForeignObjectElement(DOM::Document& document, DOM::QualifiedName qualified_name)
+ : SVGGraphicsElement(document, move(qualified_name))
+{
+ set_prototype(&Bindings::cached_web_prototype(realm(), "SVGForeignObjectElement"));
+}
+
+SVGForeignObjectElement::~SVGForeignObjectElement() = default;
+
+void SVGForeignObjectElement::initialize(JS::Realm& realm)
+{
+ Base::initialize(realm);
+
+ // FIXME: These never actually get updated!
+ m_x = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, 0), SVGLength::create(realm, 0, 0));
+ m_y = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, 0), SVGLength::create(realm, 0, 0));
+ m_width = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, 0), SVGLength::create(realm, 0, 0));
+ m_height = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, 0), SVGLength::create(realm, 0, 0));
+}
+
+void SVGForeignObjectElement::visit_edges(Cell::Visitor& visitor)
+{
+ Base::visit_edges(visitor);
+ visitor.visit(m_x);
+ visitor.visit(m_y);
+ visitor.visit(m_width);
+ visitor.visit(m_height);
+}
+
+JS::GCPtr<Layout::Node> SVGForeignObjectElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties> style)
+{
+ return heap().allocate_without_realm<Layout::BlockContainer>(document(), this, move(style));
+}
+
+void SVGForeignObjectElement::apply_presentational_hints(CSS::StyleProperties& style) const
+{
+ Base::apply_presentational_hints(style);
+
+ if (auto width_value = HTML::parse_dimension_value(attribute(SVG::AttributeNames::width)))
+ style.set_property(CSS::PropertyID::Width, width_value.release_nonnull());
+
+ if (auto height_value = HTML::parse_dimension_value(attribute(SVG::AttributeNames::height)))
+ style.set_property(CSS::PropertyID::Height, height_value.release_nonnull());
+}
+
+JS::NonnullGCPtr<SVG::SVGAnimatedLength> SVGForeignObjectElement::x()
+{
+ return *m_x;
+}
+
+JS::NonnullGCPtr<SVG::SVGAnimatedLength> SVGForeignObjectElement::y()
+{
+ return *m_y;
+}
+
+JS::NonnullGCPtr<SVG::SVGAnimatedLength> SVGForeignObjectElement::width()
+{
+ return *m_width;
+}
+
+JS::NonnullGCPtr<SVG::SVGAnimatedLength> SVGForeignObjectElement::height()
+{
+ return *m_height;
+}
+
+}
diff --git a/Userland/Libraries/LibWeb/SVG/SVGForeignObjectElement.h b/Userland/Libraries/LibWeb/SVG/SVGForeignObjectElement.h
new file mode 100644
index 0000000000..4c7b2f12f0
--- /dev/null
+++ b/Userland/Libraries/LibWeb/SVG/SVGForeignObjectElement.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibWeb/SVG/SVGGraphicsElement.h>
+
+namespace Web::SVG {
+
+// https://svgwg.org/svg2-draft/embedded.html#InterfaceSVGForeignObjectElement
+class SVGForeignObjectElement final : public SVGGraphicsElement {
+ WEB_PLATFORM_OBJECT(SVGForeignObjectElement, SVGGraphicsElement);
+
+public:
+ virtual ~SVGForeignObjectElement() override;
+
+ virtual JS::GCPtr<Layout::Node> create_layout_node(NonnullRefPtr<CSS::StyleProperties>) override;
+
+ JS::NonnullGCPtr<SVG::SVGAnimatedLength> x();
+ JS::NonnullGCPtr<SVG::SVGAnimatedLength> y();
+ JS::NonnullGCPtr<SVG::SVGAnimatedLength> width();
+ JS::NonnullGCPtr<SVG::SVGAnimatedLength> height();
+
+private:
+ SVGForeignObjectElement(DOM::Document& document, DOM::QualifiedName qualified_name);
+
+ virtual void initialize(JS::Realm&) override;
+ virtual void visit_edges(Cell::Visitor&) override;
+
+ virtual void apply_presentational_hints(CSS::StyleProperties&) const override;
+
+ JS::GCPtr<SVG::SVGAnimatedLength> m_x;
+ JS::GCPtr<SVG::SVGAnimatedLength> m_y;
+ JS::GCPtr<SVG::SVGAnimatedLength> m_width;
+ JS::GCPtr<SVG::SVGAnimatedLength> m_height;
+};
+
+}
diff --git a/Userland/Libraries/LibWeb/SVG/SVGForeignObjectElement.idl b/Userland/Libraries/LibWeb/SVG/SVGForeignObjectElement.idl
new file mode 100644
index 0000000000..618734ce46
--- /dev/null
+++ b/Userland/Libraries/LibWeb/SVG/SVGForeignObjectElement.idl
@@ -0,0 +1,11 @@
+#import <SVG/SVGAnimatedLength.idl>
+
+[Exposed=Window]
+interface SVGForeignObjectElement : SVGGraphicsElement {
+
+ [SameObject] readonly attribute SVGAnimatedLength x;
+ [SameObject] readonly attribute SVGAnimatedLength y;
+ [SameObject] readonly attribute SVGAnimatedLength width;
+ [SameObject] readonly attribute SVGAnimatedLength height;
+
+};
diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake
index 7863bd2fee..602c1651fc 100644
--- a/Userland/Libraries/LibWeb/idl_files.cmake
+++ b/Userland/Libraries/LibWeb/idl_files.cmake
@@ -172,6 +172,7 @@ libweb_js_bindings(SVG/SVGGeometryElement)
libweb_js_bindings(SVG/SVGGraphicsElement)
libweb_js_bindings(SVG/SVGCircleElement)
libweb_js_bindings(SVG/SVGEllipseElement)
+libweb_js_bindings(SVG/SVGForeignObjectElement)
libweb_js_bindings(SVG/SVGLength)
libweb_js_bindings(SVG/SVGLineElement)
libweb_js_bindings(SVG/SVGPathElement)