LibWeb: Stub (and implement) SVGSVGElement methods and attributes

This implements trivial functions and stubs out the rest.

Implemented:

```
[SameObject] readonly attribute SVGAnimatedLength x;
[SameObject] readonly attribute SVGAnimatedLength y;
[SameObject] readonly attribute SVGAnimatedLength width;
[SameObject] readonly attribute SVGAnimatedLength height;

undefined deselectAll();

SVGLength createSVGLength();
DOMPoint createSVGPoint();
DOMMatrix createSVGMatrix();
DOMRect createSVGRect();
SVGTransform createSVGTransform();

Element getElementById(DOMString elementId);

unsigned long suspendRedraw(unsigned long maxWaitMilliseconds);
undefined unsuspendRedraw(unsigned long suspendHandleID);
undefined unsuspendRedrawAll();
undefined forceRedraw();
```

Stubbed:

```
attribute float currentScale;
[SameObject] readonly attribute DOMPointReadOnly currentTranslate;

NodeList getIntersectionList(
  DOMRectReadOnly rect, SVGElement? referenceElement);
NodeList getEnclosureList(
  DOMRectReadOnly rect, SVGElement? referenceElement);
boolean checkIntersection(SVGElement element, DOMRectReadOnly rect);
boolean checkEnclosure(SVGElement element, DOMRectReadOnly rect);
```
This commit is contained in:
MacDue 2024-04-01 00:51:24 +01:00 committed by Alexander Kalenik
commit 59cd086199
Notes: sideshowbarker 2024-07-17 04:03:27 +09:00
4 changed files with 182 additions and 4 deletions

View file

@ -41,6 +41,7 @@ static bool is_platform_object(Type const& type)
"CryptoKey"sv, "CryptoKey"sv,
"Document"sv, "Document"sv,
"DocumentType"sv, "DocumentType"sv,
"DOMRectReadOnly"sv,
"EventTarget"sv, "EventTarget"sv,
"FileList"sv, "FileList"sv,
"FormData"sv, "FormData"sv,

View file

@ -11,11 +11,13 @@
#include <LibWeb/CSS/StyleValues/PercentageStyleValue.h> #include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
#include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/Event.h> #include <LibWeb/DOM/Event.h>
#include <LibWeb/DOM/StaticNodeList.h>
#include <LibWeb/HTML/Parser/HTMLParser.h> #include <LibWeb/HTML/Parser/HTMLParser.h>
#include <LibWeb/Layout/SVGSVGBox.h> #include <LibWeb/Layout/SVGSVGBox.h>
#include <LibWeb/SVG/AttributeNames.h> #include <LibWeb/SVG/AttributeNames.h>
#include <LibWeb/SVG/SVGAnimatedRect.h> #include <LibWeb/SVG/SVGAnimatedRect.h>
#include <LibWeb/SVG/SVGSVGElement.h> #include <LibWeb/SVG/SVGSVGElement.h>
#include <LibWeb/Selection/Selection.h>
namespace Web::SVG { namespace Web::SVG {
@ -149,4 +151,101 @@ Optional<ViewBox> SVGSVGElement::view_box() const
return {}; return {};
} }
JS::NonnullGCPtr<SVGAnimatedLength> SVGSVGElement::x() const
{
return svg_animated_length_for_property(CSS::PropertyID::X);
}
JS::NonnullGCPtr<SVGAnimatedLength> SVGSVGElement::y() const
{
return svg_animated_length_for_property(CSS::PropertyID::Y);
}
JS::NonnullGCPtr<SVGAnimatedLength> SVGSVGElement::width() const
{
return svg_animated_length_for_property(CSS::PropertyID::Width);
}
JS::NonnullGCPtr<SVGAnimatedLength> SVGSVGElement::height() const
{
return svg_animated_length_for_property(CSS::PropertyID::Height);
}
float SVGSVGElement::current_scale() const
{
dbgln("(STUBBED) SVGSVGElement::current_scale(). Called on: {}", debug_description());
return 1.0f;
}
void SVGSVGElement::set_current_scale(float)
{
dbgln("(STUBBED) SVGSVGElement::set_current_scale(). Called on: {}", debug_description());
}
JS::NonnullGCPtr<Geometry::DOMPointReadOnly> SVGSVGElement::current_translate() const
{
dbgln("(STUBBED) SVGSVGElement::current_translate(). Called on: {}", debug_description());
return Geometry::DOMPointReadOnly::create(realm());
}
JS::NonnullGCPtr<DOM::NodeList> SVGSVGElement::get_intersection_list(JS::NonnullGCPtr<Geometry::DOMRectReadOnly>, JS::GCPtr<SVGElement>) const
{
dbgln("(STUBBED) SVGSVGElement::get_intersection_list(). Called on: {}", debug_description());
return DOM::StaticNodeList::create(realm(), {});
}
JS::NonnullGCPtr<DOM::NodeList> SVGSVGElement::get_enclosure_list(JS::NonnullGCPtr<Geometry::DOMRectReadOnly>, JS::GCPtr<SVGElement>) const
{
dbgln("(STUBBED) SVGSVGElement::get_enclosure_list(). Called on: {}", debug_description());
return DOM::StaticNodeList::create(realm(), {});
}
bool SVGSVGElement::check_intersection(JS::NonnullGCPtr<SVGElement>, JS::NonnullGCPtr<Geometry::DOMRectReadOnly>) const
{
dbgln("(STUBBED) SVGSVGElement::check_intersection(). Called on: {}", debug_description());
return false;
}
bool SVGSVGElement::check_enclosure(JS::NonnullGCPtr<SVGElement>, JS::NonnullGCPtr<Geometry::DOMRectReadOnly>) const
{
dbgln("(STUBBED) SVGSVGElement::check_enclosure(). Called on: {}", debug_description());
return false;
}
void SVGSVGElement::deselect_all() const
{
// This is equivalent to calling document.getSelection().removeAllRanges() on the document that this svg element is in.
if (auto selection = document().get_selection())
selection->remove_all_ranges();
}
JS::NonnullGCPtr<SVGLength> SVGSVGElement::create_svg_length() const
{
// A new, detached SVGLength object whose value is the unitless <number> 0.
return SVGLength::create(realm(), SVGLength::SVG_LENGTHTYPE_NUMBER, 0);
}
JS::NonnullGCPtr<Geometry::DOMPoint> SVGSVGElement::create_svg_point() const
{
// A new, detached DOMPoint object whose coordinates are all 0.
return Geometry::DOMPoint::from_point(vm(), Geometry::DOMPointInit {});
}
JS::NonnullGCPtr<Geometry::DOMMatrix> SVGSVGElement::create_svg_matrix() const
{
// A new, detached DOMMatrix object representing the identity matrix.
return Geometry::DOMMatrix::create(realm());
}
JS::NonnullGCPtr<Geometry::DOMRect> SVGSVGElement::create_svg_rect() const
{
// A new, DOMRect object whose x, y, width and height are all 0.
return Geometry::DOMRect::construct_impl(realm(), 0, 0, 0, 0).release_value_but_fixme_should_propagate_errors();
}
JS::NonnullGCPtr<SVGTransform> SVGSVGElement::create_svg_transform() const
{
return SVGTransform::create(realm());
}
} }

View file

@ -7,15 +7,24 @@
#pragma once #pragma once
#include <LibGfx/Bitmap.h> #include <LibGfx/Bitmap.h>
#include <LibWeb/DOM/NonElementParentNode.h>
#include <LibWeb/Geometry/DOMMatrix.h>
#include <LibWeb/Geometry/DOMPoint.h>
#include <LibWeb/SVG/AttributeParser.h> #include <LibWeb/SVG/AttributeParser.h>
#include <LibWeb/SVG/SVGAnimatedLength.h>
#include <LibWeb/SVG/SVGGraphicsElement.h> #include <LibWeb/SVG/SVGGraphicsElement.h>
#include <LibWeb/SVG/SVGLength.h>
#include <LibWeb/SVG/SVGTransform.h>
#include <LibWeb/SVG/SVGViewport.h> #include <LibWeb/SVG/SVGViewport.h>
#include <LibWeb/SVG/ViewBox.h> #include <LibWeb/SVG/ViewBox.h>
#include <LibWeb/WebIDL/Types.h>
namespace Web::SVG { namespace Web::SVG {
class SVGSVGElement final : public SVGGraphicsElement class SVGSVGElement final : public SVGGraphicsElement
, public SVGViewport { , public SVGViewport
// SVGSVGElement is not strictly a NonElementParentNode, but it implements the same get_element_by_id() method.
, public DOM::NonElementParentNode<SVGSVGElement> {
WEB_PLATFORM_OBJECT(SVGSVGElement, SVGGraphicsElement); WEB_PLATFORM_OBJECT(SVGSVGElement, SVGGraphicsElement);
JS_DECLARE_ALLOCATOR(SVGSVGElement); JS_DECLARE_ALLOCATOR(SVGSVGElement);
@ -34,6 +43,43 @@ public:
JS::NonnullGCPtr<SVGAnimatedRect> view_box_for_bindings() { return *m_view_box_for_bindings; } JS::NonnullGCPtr<SVGAnimatedRect> view_box_for_bindings() { return *m_view_box_for_bindings; }
JS::NonnullGCPtr<SVGAnimatedLength> x() const;
JS::NonnullGCPtr<SVGAnimatedLength> y() const;
JS::NonnullGCPtr<SVGAnimatedLength> width() const;
JS::NonnullGCPtr<SVGAnimatedLength> height() const;
float current_scale() const;
void set_current_scale(float);
JS::NonnullGCPtr<Geometry::DOMPointReadOnly> current_translate() const;
JS::NonnullGCPtr<DOM::NodeList> get_intersection_list(JS::NonnullGCPtr<Geometry::DOMRectReadOnly> rect, JS::GCPtr<SVGElement> reference_element) const;
JS::NonnullGCPtr<DOM::NodeList> get_enclosure_list(JS::NonnullGCPtr<Geometry::DOMRectReadOnly> rect, JS::GCPtr<SVGElement> reference_element) const;
bool check_intersection(JS::NonnullGCPtr<SVGElement> element, JS::NonnullGCPtr<Geometry::DOMRectReadOnly> rect) const;
bool check_enclosure(JS::NonnullGCPtr<SVGElement> element, JS::NonnullGCPtr<Geometry::DOMRectReadOnly> rect) const;
void deselect_all() const;
JS::NonnullGCPtr<SVGLength> create_svg_length() const;
JS::NonnullGCPtr<Geometry::DOMPoint> create_svg_point() const;
JS::NonnullGCPtr<Geometry::DOMMatrix> create_svg_matrix() const;
JS::NonnullGCPtr<Geometry::DOMRect> create_svg_rect() const;
JS::NonnullGCPtr<SVGTransform> create_svg_transform() const;
// Deprecated methods that have no effect when called, but which are kept for compatibility reasons.
WebIDL::UnsignedLong suspend_redraw(WebIDL::UnsignedLong max_wait_milliseconds) const
{
(void)max_wait_milliseconds;
// When the suspendRedraw method is called, it must return 1.
return 1;
}
void unsuspend_redraw(WebIDL::UnsignedLong suspend_handle_id) const
{
(void)suspend_handle_id;
}
void unsuspend_redraw_all() const {};
void force_redraw() const {};
private: private:
SVGSVGElement(DOM::Document&, DOM::QualifiedName); SVGSVGElement(DOM::Document&, DOM::QualifiedName);

View file

@ -1,10 +1,42 @@
#import <SVG/SVGGraphicsElement.idl> #import <SVG/SVGGraphicsElement.idl>
#import <SVG/SVGFitToViewBox.idl> #import <SVG/SVGFitToViewBox.idl>
#import <Geometry/DOMRectReadOnly.idl>
// https://svgwg.org/svg2-draft/struct.html#InterfaceSVGSVGElement // https://svgwg.org/svg2-draft/struct.html#InterfaceSVGSVGElement
[Exposed=Window] [Exposed=Window]
interface SVGSVGElement : SVGGraphicsElement { interface SVGSVGElement : SVGGraphicsElement {
[SameObject] readonly attribute SVGAnimatedLength x;
[SameObject] readonly attribute SVGAnimatedLength y;
[SameObject] readonly attribute SVGAnimatedLength width;
[SameObject] readonly attribute SVGAnimatedLength height;
attribute float currentScale;
[SameObject] readonly attribute DOMPointReadOnly currentTranslate;
NodeList getIntersectionList(DOMRectReadOnly rect, SVGElement? referenceElement);
NodeList getEnclosureList(DOMRectReadOnly rect, SVGElement? referenceElement);
boolean checkIntersection(SVGElement element, DOMRectReadOnly rect);
boolean checkEnclosure(SVGElement element, DOMRectReadOnly rect);
undefined deselectAll();
// FIMXE: SVGNumber createSVGNumber();
SVGLength createSVGLength();
// FIXME: SVGAngle createSVGAngle();
DOMPoint createSVGPoint();
DOMMatrix createSVGMatrix();
DOMRect createSVGRect();
SVGTransform createSVGTransform();
// FIXME: SVGTransform createSVGTransformFromMatrix(optional DOMMatrix2DInit matrix = {});
Element getElementById(DOMString elementId);
// Deprecated methods that have no effect when called,
// but which are kept for compatibility reasons.
unsigned long suspendRedraw(unsigned long maxWaitMilliseconds);
undefined unsuspendRedraw(unsigned long suspendHandleID);
undefined unsuspendRedrawAll();
undefined forceRedraw();
}; };
SVGSVGElement includes SVGFitToViewBox; SVGSVGElement includes SVGFitToViewBox;