diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 86854011fdd..47fc562325b 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -934,6 +934,7 @@ set(SOURCES SVG/SVGLineElement.cpp SVG/SVGMaskElement.cpp SVG/SVGMetadataElement.cpp + SVG/SVGNumber.cpp SVG/SVGPathElement.cpp SVG/SVGPolygonElement.cpp SVG/SVGPolylineElement.cpp diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index a79a9291f64..0e9ebc9b450 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -1117,6 +1117,7 @@ class SVGLength; class SVGLineElement; class SVGMaskElement; class SVGMetadataElement; +class SVGNumber; class SVGPathElement; class SVGPolygonElement; class SVGPolylineElement; diff --git a/Libraries/LibWeb/SVG/SVGNumber.cpp b/Libraries/LibWeb/SVG/SVGNumber.cpp new file mode 100644 index 00000000000..3618803444e --- /dev/null +++ b/Libraries/LibWeb/SVG/SVGNumber.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025, Jelle Raaijmakers + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Web::SVG { + +GC_DEFINE_ALLOCATOR(SVGNumber); + +GC::Ref SVGNumber::create(JS::Realm& realm, float value, ReadOnly read_only) +{ + return realm.create(realm, value, read_only); +} + +SVGNumber::SVGNumber(JS::Realm& realm, float value, ReadOnly read_only) + : PlatformObject(realm) + , m_value(value) + , m_read_only(read_only) +{ +} + +void SVGNumber::initialize(JS::Realm& realm) +{ + WEB_SET_PROTOTYPE_FOR_INTERFACE(SVGNumber); + Base::initialize(realm); +} + +// https://www.w3.org/TR/SVG2/types.html#__svg__SVGNumber__value +WebIDL::ExceptionOr SVGNumber::set_value(float value) +{ + // 1. If the SVGNumber is read only, then throw a NoModificationAllowedError. + if (m_read_only == ReadOnly::Yes) + return WebIDL::NoModificationAllowedError::create(realm(), "Cannot modify value of read-only SVGNumber"_utf16); + + // 2. Set the SVGNumber's value to the value being assigned to the value member. + m_value = value; + + // FIXME: 3. If the SVGNumber reflects an element of the base value of a reflected attribute, then reserialize the + // reflected attribute. + + return {}; +} + +} diff --git a/Libraries/LibWeb/SVG/SVGNumber.h b/Libraries/LibWeb/SVG/SVGNumber.h new file mode 100644 index 00000000000..599a4037d4e --- /dev/null +++ b/Libraries/LibWeb/SVG/SVGNumber.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025, Jelle Raaijmakers + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Web::SVG { + +// https://www.w3.org/TR/SVG2/types.html#InterfaceSVGNumber +class SVGNumber final : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(SVGNumber, Bindings::PlatformObject); + GC_DECLARE_ALLOCATOR(SVGNumber); + +public: + enum class ReadOnly : u8 { + Yes, + No, + }; + + [[nodiscard]] static GC::Ref create(JS::Realm&, float value, ReadOnly); + virtual ~SVGNumber() override = default; + + float value() const { return m_value; } + WebIDL::ExceptionOr set_value(float value); + + ReadOnly read_only() const { return m_read_only; } + +private: + SVGNumber(JS::Realm&, float value, ReadOnly); + + virtual void initialize(JS::Realm&) override; + + float m_value { 0 }; + + // https://www.w3.org/TR/SVG2/types.html#ReadOnlyNumber + ReadOnly m_read_only; +}; + +} diff --git a/Libraries/LibWeb/SVG/SVGNumber.idl b/Libraries/LibWeb/SVG/SVGNumber.idl new file mode 100644 index 00000000000..80736af7962 --- /dev/null +++ b/Libraries/LibWeb/SVG/SVGNumber.idl @@ -0,0 +1,5 @@ +// https://www.w3.org/TR/SVG2/types.html#InterfaceSVGNumber +[Exposed=Window] +interface SVGNumber { + attribute float value; +}; diff --git a/Libraries/LibWeb/idl_files.cmake b/Libraries/LibWeb/idl_files.cmake index 868c1b672be..70afa78ad71 100644 --- a/Libraries/LibWeb/idl_files.cmake +++ b/Libraries/LibWeb/idl_files.cmake @@ -403,6 +403,7 @@ libweb_js_bindings(SVG/SVGLineElement) libweb_js_bindings(SVG/SVGLinearGradientElement) libweb_js_bindings(SVG/SVGMaskElement) libweb_js_bindings(SVG/SVGMetadataElement) +libweb_js_bindings(SVG/SVGNumber) libweb_js_bindings(SVG/SVGPathElement) libweb_js_bindings(SVG/SVGPolygonElement) libweb_js_bindings(SVG/SVGPolylineElement) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 67f7188e568..b81a8942c38 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -122,6 +122,7 @@ static bool is_platform_object(Type const& type) "ServiceWorkerContainer"sv, "ServiceWorkerRegistration"sv, "SVGAnimationElement"sv, + "SVGNumber"sv, "SVGTransform"sv, "ShadowRoot"sv, "SourceBuffer"sv, diff --git a/Tests/LibWeb/Text/expected/all-window-properties.txt b/Tests/LibWeb/Text/expected/all-window-properties.txt index 2eb0079296d..a91395d6646 100644 --- a/Tests/LibWeb/Text/expected/all-window-properties.txt +++ b/Tests/LibWeb/Text/expected/all-window-properties.txt @@ -397,6 +397,7 @@ SVGLinearGradientElement SVGMaskElement SVGMatrix SVGMetadataElement +SVGNumber SVGPathElement SVGPoint SVGPolygonElement diff --git a/Tests/LibWeb/Text/expected/wpt-import/svg/idlharness.window.txt b/Tests/LibWeb/Text/expected/wpt-import/svg/idlharness.window.txt index 485957b702f..b296c4dbf26 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/svg/idlharness.window.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/svg/idlharness.window.txt @@ -2,8 +2,8 @@ Harness status: OK Found 1781 tests -970 Pass -811 Fail +977 Pass +804 Fail Pass idl_test setup Pass idl_test validation Pass Partial interface Document: original interface defined @@ -85,13 +85,13 @@ Fail SVGGeometryElement interface: operation isPointInFill(optional DOMPointInit Fail SVGGeometryElement interface: operation isPointInStroke(optional DOMPointInit) Pass SVGGeometryElement interface: operation getTotalLength() Pass SVGGeometryElement interface: operation getPointAtLength(float) -Fail SVGNumber interface: existence and properties of interface object -Fail SVGNumber interface object length -Fail SVGNumber interface object name -Fail SVGNumber interface: existence and properties of interface prototype object -Fail SVGNumber interface: existence and properties of interface prototype object's "constructor" property -Fail SVGNumber interface: existence and properties of interface prototype object's @@unscopables property -Fail SVGNumber interface: attribute value +Pass SVGNumber interface: existence and properties of interface object +Pass SVGNumber interface object length +Pass SVGNumber interface object name +Pass SVGNumber interface: existence and properties of interface prototype object +Pass SVGNumber interface: existence and properties of interface prototype object's "constructor" property +Pass SVGNumber interface: existence and properties of interface prototype object's @@unscopables property +Pass SVGNumber interface: attribute value Fail SVGNumber must be primary interface of objects.svg.createSVGNumber() Fail Stringification of objects.svg.createSVGNumber() Fail SVGNumber interface: objects.svg.createSVGNumber() must inherit property "value" with the proper type