diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 8078a902212..bc51b049a30 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -41,6 +41,7 @@ static bool is_platform_object(Type const& type) "CryptoKey"sv, "Document"sv, "DocumentType"sv, + "DOMRectReadOnly"sv, "EventTarget"sv, "FileList"sv, "FormData"sv, @@ -3269,7 +3270,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.getter_callback@) retval = "@missing_enum_default_value@"_string; Array valid_values { @valid_enum_values@ }; - + auto found = false; for (auto const& value : valid_values) { if (value.equals_ignoring_ascii_case(retval)) { @@ -3297,7 +3298,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.getter_callback@) // 8. Return the canonical keyword for the state of attributeDefinition that contentAttributeValue corresponds to. // NOTE: We run step 8 here to have a field to assign to attribute_generator.append(R"~~~( - auto retval = impl->attribute(HTML::AttributeNames::@attribute.reflect_name@); + auto retval = impl->attribute(HTML::AttributeNames::@attribute.reflect_name@); )~~~"); // 3. Let attributeDefinition be the attribute definition of element's content attribute whose namespace is null @@ -3326,7 +3327,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.getter_callback@) )~~~"); if (invalid_value_default.has_value()) { attribute_generator.append(R"~~~( - + if (retval.has_value()) { auto found = false; for (auto const& value : valid_values) { diff --git a/Userland/Libraries/LibWeb/SVG/SVGSVGElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGSVGElement.cpp index 5d4e709bbe5..5227f50b02b 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGSVGElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGSVGElement.cpp @@ -11,11 +11,13 @@ #include #include #include +#include #include #include #include #include #include +#include namespace Web::SVG { @@ -149,4 +151,101 @@ Optional SVGSVGElement::view_box() const return {}; } +JS::NonnullGCPtr SVGSVGElement::x() const +{ + return svg_animated_length_for_property(CSS::PropertyID::X); +} + +JS::NonnullGCPtr SVGSVGElement::y() const +{ + return svg_animated_length_for_property(CSS::PropertyID::Y); +} + +JS::NonnullGCPtr SVGSVGElement::width() const +{ + return svg_animated_length_for_property(CSS::PropertyID::Width); +} + +JS::NonnullGCPtr 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 SVGSVGElement::current_translate() const +{ + dbgln("(STUBBED) SVGSVGElement::current_translate(). Called on: {}", debug_description()); + return Geometry::DOMPointReadOnly::create(realm()); +} + +JS::NonnullGCPtr SVGSVGElement::get_intersection_list(JS::NonnullGCPtr, JS::GCPtr) const +{ + dbgln("(STUBBED) SVGSVGElement::get_intersection_list(). Called on: {}", debug_description()); + return DOM::StaticNodeList::create(realm(), {}); +} + +JS::NonnullGCPtr SVGSVGElement::get_enclosure_list(JS::NonnullGCPtr, JS::GCPtr) const +{ + dbgln("(STUBBED) SVGSVGElement::get_enclosure_list(). Called on: {}", debug_description()); + return DOM::StaticNodeList::create(realm(), {}); +} + +bool SVGSVGElement::check_intersection(JS::NonnullGCPtr, JS::NonnullGCPtr) const +{ + dbgln("(STUBBED) SVGSVGElement::check_intersection(). Called on: {}", debug_description()); + return false; +} + +bool SVGSVGElement::check_enclosure(JS::NonnullGCPtr, JS::NonnullGCPtr) 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 SVGSVGElement::create_svg_length() const +{ + // A new, detached SVGLength object whose value is the unitless 0. + return SVGLength::create(realm(), SVGLength::SVG_LENGTHTYPE_NUMBER, 0); +} + +JS::NonnullGCPtr 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 SVGSVGElement::create_svg_matrix() const +{ + // A new, detached DOMMatrix object representing the identity matrix. + return Geometry::DOMMatrix::create(realm()); +} + +JS::NonnullGCPtr 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 SVGSVGElement::create_svg_transform() const +{ + return SVGTransform::create(realm()); +} + } diff --git a/Userland/Libraries/LibWeb/SVG/SVGSVGElement.h b/Userland/Libraries/LibWeb/SVG/SVGSVGElement.h index d8d68264da7..9324f043889 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGSVGElement.h +++ b/Userland/Libraries/LibWeb/SVG/SVGSVGElement.h @@ -7,15 +7,24 @@ #pragma once #include +#include +#include +#include #include +#include #include +#include +#include #include #include +#include namespace Web::SVG { 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 { WEB_PLATFORM_OBJECT(SVGSVGElement, SVGGraphicsElement); JS_DECLARE_ALLOCATOR(SVGSVGElement); @@ -34,6 +43,43 @@ public: JS::NonnullGCPtr view_box_for_bindings() { return *m_view_box_for_bindings; } + JS::NonnullGCPtr x() const; + JS::NonnullGCPtr y() const; + JS::NonnullGCPtr width() const; + JS::NonnullGCPtr height() const; + + float current_scale() const; + void set_current_scale(float); + + JS::NonnullGCPtr current_translate() const; + + JS::NonnullGCPtr get_intersection_list(JS::NonnullGCPtr rect, JS::GCPtr reference_element) const; + JS::NonnullGCPtr get_enclosure_list(JS::NonnullGCPtr rect, JS::GCPtr reference_element) const; + bool check_intersection(JS::NonnullGCPtr element, JS::NonnullGCPtr rect) const; + bool check_enclosure(JS::NonnullGCPtr element, JS::NonnullGCPtr rect) const; + + void deselect_all() const; + + JS::NonnullGCPtr create_svg_length() const; + JS::NonnullGCPtr create_svg_point() const; + JS::NonnullGCPtr create_svg_matrix() const; + JS::NonnullGCPtr create_svg_rect() const; + JS::NonnullGCPtr 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: SVGSVGElement(DOM::Document&, DOM::QualifiedName); diff --git a/Userland/Libraries/LibWeb/SVG/SVGSVGElement.idl b/Userland/Libraries/LibWeb/SVG/SVGSVGElement.idl index e09f07a995a..4c55e4447f8 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGSVGElement.idl +++ b/Userland/Libraries/LibWeb/SVG/SVGSVGElement.idl @@ -1,10 +1,42 @@ #import #import +#import // https://svgwg.org/svg2-draft/struct.html#InterfaceSVGSVGElement [Exposed=Window] 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;