diff --git a/Libraries/LibWeb/SVG/SVGAnimatedLength.cpp b/Libraries/LibWeb/SVG/SVGAnimatedLength.cpp index 0eacbbddd0d..33585e41064 100644 --- a/Libraries/LibWeb/SVG/SVGAnimatedLength.cpp +++ b/Libraries/LibWeb/SVG/SVGAnimatedLength.cpp @@ -14,16 +14,21 @@ GC_DEFINE_ALLOCATOR(SVGAnimatedLength); GC::Ref SVGAnimatedLength::create(JS::Realm& realm, GC::Ref base_val, GC::Ref anim_val) { - return realm.create(realm, move(base_val), move(anim_val)); + return realm.create(realm, base_val, anim_val); } SVGAnimatedLength::SVGAnimatedLength(JS::Realm& realm, GC::Ref base_val, GC::Ref anim_val) : PlatformObject(realm) - , m_base_val(move(base_val)) - , m_anim_val(move(anim_val)) + , m_base_val(base_val) + , m_anim_val(anim_val) { - // The object referenced by animVal will always be distinct from the one referenced by baseVal, even when the attribute is not animated. + // The object referenced by animVal will always be distinct from the one referenced by baseVal, even when the + // attribute is not animated. VERIFY(m_base_val.ptr() != m_anim_val.ptr()); + + // https://svgwg.org/svg2-draft/types.html#InterfaceSVGLength + // SVGLength objects reflected through the animVal IDL attribute are always read only. + VERIFY(m_anim_val->read_only() == SVGLength::ReadOnly::Yes); } SVGAnimatedLength::~SVGAnimatedLength() = default; @@ -34,7 +39,7 @@ void SVGAnimatedLength::initialize(JS::Realm& realm) Base::initialize(realm); } -void SVGAnimatedLength::visit_edges(Cell::Visitor& visitor) +void SVGAnimatedLength::visit_edges(Visitor& visitor) { Base::visit_edges(visitor); visitor.visit(m_base_val); diff --git a/Libraries/LibWeb/SVG/SVGElement.cpp b/Libraries/LibWeb/SVG/SVGElement.cpp index bd584b86ce7..daf7317989a 100644 --- a/Libraries/LibWeb/SVG/SVGElement.cpp +++ b/Libraries/LibWeb/SVG/SVGElement.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2020, Matthew Olsson * Copyright (c) 2023, Preston Taylor <95388976+PrestonLTaylor@users.noreply.github.com> + * Copyright (c) 2025, Jelle Raaijmakers * * SPDX-License-Identifier: BSD-2-Clause */ @@ -298,17 +299,28 @@ GC::Ptr SVGElement::viewport_element() return nullptr; } +GC::Ref SVGElement::fake_animated_length_fixme() const +{ + // FIXME: All callers of this method must implement their animated length correctly. + auto base_length = SVGLength::create(realm(), 0, 0, SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, 0, SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); +} + GC::Ref SVGElement::svg_animated_length_for_property(CSS::PropertyID property) const { // FIXME: Create a proper animated value when animations are supported. - auto make_length = [&] { + auto make_length = [&](SVGLength::ReadOnly read_only) { if (auto const computed_properties = this->computed_properties()) { if (auto length = computed_properties->length_percentage(property); length.has_value()) - return SVGLength::from_length_percentage(realm(), *length); + return SVGLength::from_length_percentage(realm(), *length, read_only); } - return SVGLength::create(realm(), 0, 0.0f); + return SVGLength::create(realm(), 0, 0, read_only); }; - return SVGAnimatedLength::create(realm(), make_length(), make_length()); + return SVGAnimatedLength::create( + realm(), + make_length(SVGLength::ReadOnly::No), + make_length(SVGLength::ReadOnly::Yes)); } } diff --git a/Libraries/LibWeb/SVG/SVGElement.h b/Libraries/LibWeb/SVG/SVGElement.h index 781e70f583f..9ecb4cec318 100644 --- a/Libraries/LibWeb/SVG/SVGElement.h +++ b/Libraries/LibWeb/SVG/SVGElement.h @@ -30,6 +30,7 @@ public: bool should_include_in_accessibility_tree() const; virtual Optional default_role() const override; + GC::Ref fake_animated_length_fixme() const; GC::Ref svg_animated_length_for_property(CSS::PropertyID) const; virtual bool is_presentational_hint(FlyString const&) const override; diff --git a/Libraries/LibWeb/SVG/SVGEllipseElement.cpp b/Libraries/LibWeb/SVG/SVGEllipseElement.cpp index 6846a7ef45e..16fc48cbabd 100644 --- a/Libraries/LibWeb/SVG/SVGEllipseElement.cpp +++ b/Libraries/LibWeb/SVG/SVGEllipseElement.cpp @@ -81,9 +81,9 @@ GC::Ref SVGEllipseElement::cx() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_center_x.value_or(0)); - auto anim_length = SVGLength::create(realm(), 0, m_center_x.value_or(0)); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_center_x.value_or(0), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_center_x.value_or(0), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } // https://www.w3.org/TR/SVG11/shapes.html#EllipseElementCYAttribute @@ -91,9 +91,9 @@ GC::Ref SVGEllipseElement::cy() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_center_y.value_or(0)); - auto anim_length = SVGLength::create(realm(), 0, m_center_y.value_or(0)); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_center_y.value_or(0), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_center_y.value_or(0), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } // https://www.w3.org/TR/SVG11/shapes.html#EllipseElementRXAttribute @@ -101,9 +101,9 @@ GC::Ref SVGEllipseElement::rx() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_radius_x.value_or(0)); - auto anim_length = SVGLength::create(realm(), 0, m_radius_x.value_or(0)); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_radius_x.value_or(0), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_radius_x.value_or(0), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } // https://www.w3.org/TR/SVG11/shapes.html#EllipseElementRYAttribute @@ -111,9 +111,9 @@ GC::Ref SVGEllipseElement::ry() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_radius_y.value_or(0)); - auto anim_length = SVGLength::create(realm(), 0, m_radius_y.value_or(0)); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_radius_y.value_or(0), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_radius_y.value_or(0), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } } diff --git a/Libraries/LibWeb/SVG/SVGForeignObjectElement.cpp b/Libraries/LibWeb/SVG/SVGForeignObjectElement.cpp index 4c089704fe2..a26abc0f696 100644 --- a/Libraries/LibWeb/SVG/SVGForeignObjectElement.cpp +++ b/Libraries/LibWeb/SVG/SVGForeignObjectElement.cpp @@ -32,10 +32,10 @@ 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)); + m_x = fake_animated_length_fixme(); + m_y = fake_animated_length_fixme(); + m_width = fake_animated_length_fixme(); + m_height = fake_animated_length_fixme(); } void SVGForeignObjectElement::visit_edges(Cell::Visitor& visitor) diff --git a/Libraries/LibWeb/SVG/SVGImageElement.cpp b/Libraries/LibWeb/SVG/SVGImageElement.cpp index f15723fcedd..cdc05fcdbd0 100644 --- a/Libraries/LibWeb/SVG/SVGImageElement.cpp +++ b/Libraries/LibWeb/SVG/SVGImageElement.cpp @@ -81,10 +81,8 @@ void SVGImageElement::attribute_changed(FlyString const& name, Optional // https://svgwg.org/svg2-draft/embedded.html#__svg__SVGImageElement__x GC::Ref SVGImageElement::x() { - if (!m_x) { - auto& realm = this->realm(); - m_x = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, 0), SVGLength::create(realm, 0, 0)); - } + if (!m_x) + m_x = fake_animated_length_fixme(); return *m_x; } @@ -92,10 +90,8 @@ GC::Ref SVGImageElement::x() // https://svgwg.org/svg2-draft/embedded.html#__svg__SVGImageElement__y GC::Ref SVGImageElement::y() { - if (!m_y) { - auto& realm = this->realm(); - m_y = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, 0), SVGLength::create(realm, 0, 0)); - } + if (!m_y) + m_y = fake_animated_length_fixme(); return *m_y; } @@ -105,7 +101,10 @@ GC::Ref SVGImageElement::width() { if (!m_width) { auto& realm = this->realm(); - m_width = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, intrinsic_width().value_or(0).to_double()), SVGLength::create(realm, 0, 0)); + m_width = SVGAnimatedLength::create( + realm, + SVGLength::create(realm, 0, intrinsic_width().value_or(0).to_double(), SVGLength::ReadOnly::No), + SVGLength::create(realm, 0, 0, SVGLength::ReadOnly::Yes)); } return *m_width; @@ -116,7 +115,10 @@ GC::Ref SVGImageElement::height() { if (!m_height) { auto& realm = this->realm(); - m_height = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, intrinsic_height().value_or(0).to_double()), SVGLength::create(realm, 0, 0)); + m_height = SVGAnimatedLength::create( + realm, + SVGLength::create(realm, 0, intrinsic_height().value_or(0).to_double(), SVGLength::ReadOnly::No), + SVGLength::create(realm, 0, 0, SVGLength::ReadOnly::Yes)); } return *m_height; diff --git a/Libraries/LibWeb/SVG/SVGLength.cpp b/Libraries/LibWeb/SVG/SVGLength.cpp index ffd5b4dd03a..c4d929b30b4 100644 --- a/Libraries/LibWeb/SVG/SVGLength.cpp +++ b/Libraries/LibWeb/SVG/SVGLength.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2022, Tim Flynn + * Copyright (c) 2025, Jelle Raaijmakers * * SPDX-License-Identifier: BSD-2-Clause */ @@ -13,19 +14,20 @@ namespace Web::SVG { GC_DEFINE_ALLOCATOR(SVGLength); -GC::Ref SVGLength::create(JS::Realm& realm, u8 unit_type, float value) +GC::Ref SVGLength::create(JS::Realm& realm, u8 unit_type, float value, ReadOnly read_only) { - return realm.create(realm, unit_type, value); + return realm.create(realm, unit_type, value, read_only); } -GC::Ref SVGLength::from_length_percentage(JS::Realm& realm, CSS::LengthPercentage const& length_percentage) +GC::Ref SVGLength::from_length_percentage(JS::Realm& realm, CSS::LengthPercentage const& length_percentage, + ReadOnly read_only) { // FIXME: We can't tell if a CSS::LengthPercentage was a unitless length. (void)SVG_LENGTHTYPE_NUMBER; if (length_percentage.is_percentage()) - return SVGLength::create(realm, SVG_LENGTHTYPE_PERCENTAGE, length_percentage.percentage().value()); + return create(realm, SVG_LENGTHTYPE_PERCENTAGE, length_percentage.percentage().value(), read_only); if (length_percentage.is_length()) - return SVGLength::create( + return create( realm, [&] { switch (length_percentage.length().type()) { case CSS::Length::Type::Em: @@ -48,14 +50,15 @@ GC::Ref SVGLength::from_length_percentage(JS::Realm& realm, CSS::Leng return SVG_LENGTHTYPE_UNKNOWN; } }(), - length_percentage.length().raw_value()); - return SVGLength::create(realm, SVG_LENGTHTYPE_UNKNOWN, 0); + length_percentage.length().raw_value(), read_only); + return create(realm, SVG_LENGTHTYPE_UNKNOWN, 0, read_only); } -SVGLength::SVGLength(JS::Realm& realm, u8 unit_type, float value) +SVGLength::SVGLength(JS::Realm& realm, u8 unit_type, float value, ReadOnly read_only) : PlatformObject(realm) - , m_unit_type(unit_type) , m_value(value) + , m_unit_type(unit_type) + , m_read_only(read_only) { } @@ -67,11 +70,21 @@ void SVGLength::initialize(JS::Realm& realm) SVGLength::~SVGLength() = default; -// https://www.w3.org/TR/SVG11/types.html#__svg__SVGLength__value +// https://svgwg.org/svg2-draft/types.html#__svg__SVGLength__value WebIDL::ExceptionOr SVGLength::set_value(float value) { - // FIXME: Raise an exception if this is read-only. + // 1. If the SVGLength object is read only, then throw a NoModificationAllowedError. + if (m_read_only == ReadOnly::Yes) + return WebIDL::NoModificationAllowedError::create(realm(), "Cannot modify value of read-only SVGLength"_utf16); + + // 2. Let value be the value being assigned to value. + // 3. Set the SVGLength's value to a whose value is value. m_value = value; + m_unit_type = SVG_LENGTHTYPE_NUMBER; + + // FIXME: 4. If the SVGLength reflects the base value of a reflected attribute, reflects a presentation attribute, or + // reflects an element of the base value of a reflected attribute, then reserialize the reflected attribute. + return {}; } diff --git a/Libraries/LibWeb/SVG/SVGLength.h b/Libraries/LibWeb/SVG/SVGLength.h index 2bba7f89096..66f90fc775d 100644 --- a/Libraries/LibWeb/SVG/SVGLength.h +++ b/Libraries/LibWeb/SVG/SVGLength.h @@ -30,23 +30,32 @@ public: static constexpr unsigned short SVG_LENGTHTYPE_PT = 9; static constexpr unsigned short SVG_LENGTHTYPE_PC = 10; - [[nodiscard]] static GC::Ref create(JS::Realm&, u8 unit_type, float value); - virtual ~SVGLength() override; + enum class ReadOnly : u8 { + Yes, + No, + }; - u8 unit_type() const { return m_unit_type; } + [[nodiscard]] static GC::Ref create(JS::Realm&, u8 unit_type, float value, ReadOnly); + virtual ~SVGLength() override; float value() const { return m_value; } WebIDL::ExceptionOr set_value(float value); - [[nodiscard]] static GC::Ref from_length_percentage(JS::Realm&, CSS::LengthPercentage const&); + u8 unit_type() const { return m_unit_type; } + ReadOnly read_only() const { return m_read_only; } + + [[nodiscard]] static GC::Ref from_length_percentage(JS::Realm&, CSS::LengthPercentage const&, ReadOnly); private: - SVGLength(JS::Realm&, u8 unit_type, float value); + SVGLength(JS::Realm&, u8 unit_type, float value, ReadOnly); virtual void initialize(JS::Realm&) override; - u8 m_unit_type { 0 }; float m_value { 0 }; + u8 m_unit_type { 0 }; + + // https://svgwg.org/svg2-draft/types.html#ReadOnlyLength + ReadOnly m_read_only; }; } diff --git a/Libraries/LibWeb/SVG/SVGLineElement.cpp b/Libraries/LibWeb/SVG/SVGLineElement.cpp index fc2370c6b3a..3b0010144e6 100644 --- a/Libraries/LibWeb/SVG/SVGLineElement.cpp +++ b/Libraries/LibWeb/SVG/SVGLineElement.cpp @@ -66,9 +66,9 @@ GC::Ref SVGLineElement::x1() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_x1.value_or({ 0, false }).value()); - auto anim_length = SVGLength::create(realm(), 0, m_x1.value_or({ 0, false }).value()); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_x1.value_or({ 0, false }).value(), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_x1.value_or({ 0, false }).value(), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } // https://www.w3.org/TR/SVG11/shapes.html#LineElementY1Attribute @@ -76,9 +76,9 @@ GC::Ref SVGLineElement::y1() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_y1.value_or({ 0, false }).value()); - auto anim_length = SVGLength::create(realm(), 0, m_y1.value_or({ 0, false }).value()); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_y1.value_or({ 0, false }).value(), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_y1.value_or({ 0, false }).value(), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } // https://www.w3.org/TR/SVG11/shapes.html#LineElementX2Attribute @@ -86,9 +86,9 @@ GC::Ref SVGLineElement::x2() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_x2.value_or({ 0, false }).value()); - auto anim_length = SVGLength::create(realm(), 0, m_x2.value_or({ 0, false }).value()); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_x2.value_or({ 0, false }).value(), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_x2.value_or({ 0, false }).value(), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } // https://www.w3.org/TR/SVG11/shapes.html#LineElementY2Attribute @@ -96,9 +96,9 @@ GC::Ref SVGLineElement::y2() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_y2.value_or({ 0, false }).value()); - auto anim_length = SVGLength::create(realm(), 0, m_y2.value_or({ 0, false }).value()); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_y2.value_or({ 0, false }).value(), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_y2.value_or({ 0, false }).value(), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } } diff --git a/Libraries/LibWeb/SVG/SVGLinearGradientElement.cpp b/Libraries/LibWeb/SVG/SVGLinearGradientElement.cpp index faa2e5c46c2..29940668c55 100644 --- a/Libraries/LibWeb/SVG/SVGLinearGradientElement.cpp +++ b/Libraries/LibWeb/SVG/SVGLinearGradientElement.cpp @@ -162,26 +162,22 @@ Optional SVGLinearGradientElement::to_gfx_paint_style(SVGP GC::Ref SVGLinearGradientElement::x1() const { - // FIXME: Implement this properly. - return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0)); + return fake_animated_length_fixme(); } GC::Ref SVGLinearGradientElement::y1() const { - // FIXME: Implement this properly. - return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0)); + return fake_animated_length_fixme(); } GC::Ref SVGLinearGradientElement::x2() const { - // FIXME: Implement this properly. - return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0)); + return fake_animated_length_fixme(); } GC::Ref SVGLinearGradientElement::y2() const { - // FIXME: Implement this properly. - return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0)); + return fake_animated_length_fixme(); } } diff --git a/Libraries/LibWeb/SVG/SVGRadialGradientElement.cpp b/Libraries/LibWeb/SVG/SVGRadialGradientElement.cpp index 412ee052ad3..b8f5fa05c53 100644 --- a/Libraries/LibWeb/SVG/SVGRadialGradientElement.cpp +++ b/Libraries/LibWeb/SVG/SVGRadialGradientElement.cpp @@ -218,38 +218,32 @@ Optional SVGRadialGradientElement::to_gfx_paint_style(SVGP GC::Ref SVGRadialGradientElement::cx() const { - // FIXME: Implement this properly. - return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0)); + return fake_animated_length_fixme(); } GC::Ref SVGRadialGradientElement::cy() const { - // FIXME: Implement this properly. - return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0)); + return fake_animated_length_fixme(); } GC::Ref SVGRadialGradientElement::fx() const { - // FIXME: Implement this properly. - return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0)); + return fake_animated_length_fixme(); } GC::Ref SVGRadialGradientElement::fy() const { - // FIXME: Implement this properly. - return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0)); + return fake_animated_length_fixme(); } GC::Ref SVGRadialGradientElement::fr() const { - // FIXME: Implement this properly. - return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0)); + return fake_animated_length_fixme(); } GC::Ref SVGRadialGradientElement::r() const { - // FIXME: Implement this properly. - return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0)); + return fake_animated_length_fixme(); } } diff --git a/Libraries/LibWeb/SVG/SVGRectElement.cpp b/Libraries/LibWeb/SVG/SVGRectElement.cpp index 8f821330c45..1eed1e00eee 100644 --- a/Libraries/LibWeb/SVG/SVGRectElement.cpp +++ b/Libraries/LibWeb/SVG/SVGRectElement.cpp @@ -158,9 +158,9 @@ GC::Ref SVGRectElement::x() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_x.value_or(0)); - auto anim_length = SVGLength::create(realm(), 0, m_x.value_or(0)); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_x.value_or(0), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_x.value_or(0), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } // https://www.w3.org/TR/SVG11/shapes.html#RectElementYAttribute @@ -168,9 +168,9 @@ GC::Ref SVGRectElement::y() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_y.value_or(0)); - auto anim_length = SVGLength::create(realm(), 0, m_y.value_or(0)); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_y.value_or(0), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_y.value_or(0), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } // https://www.w3.org/TR/SVG11/shapes.html#RectElementWidthAttribute @@ -178,9 +178,9 @@ GC::Ref SVGRectElement::width() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_width.value_or(0)); - auto anim_length = SVGLength::create(realm(), 0, m_width.value_or(0)); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_width.value_or(0), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_width.value_or(0), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } // https://www.w3.org/TR/SVG11/shapes.html#RectElementHeightAttribute @@ -188,9 +188,9 @@ GC::Ref SVGRectElement::height() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_height.value_or(0)); - auto anim_length = SVGLength::create(realm(), 0, m_height.value_or(0)); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_height.value_or(0), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_height.value_or(0), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } // https://www.w3.org/TR/SVG11/shapes.html#RectElementRXAttribute @@ -198,9 +198,9 @@ GC::Ref SVGRectElement::rx() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_radius_x.value_or(0)); - auto anim_length = SVGLength::create(realm(), 0, m_radius_x.value_or(0)); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_radius_x.value_or(0), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_radius_x.value_or(0), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } // https://www.w3.org/TR/SVG11/shapes.html#RectElementRYAttribute @@ -208,9 +208,9 @@ GC::Ref SVGRectElement::ry() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_radius_y.value_or(0)); - auto anim_length = SVGLength::create(realm(), 0, m_radius_y.value_or(0)); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_radius_y.value_or(0), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_radius_y.value_or(0), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } } diff --git a/Libraries/LibWeb/SVG/SVGSVGElement.cpp b/Libraries/LibWeb/SVG/SVGSVGElement.cpp index 712d53bfe66..a541e79ea59 100644 --- a/Libraries/LibWeb/SVG/SVGSVGElement.cpp +++ b/Libraries/LibWeb/SVG/SVGSVGElement.cpp @@ -274,7 +274,7 @@ void SVGSVGElement::deselect_all() const GC::Ref 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); + return SVGLength::create(realm(), SVGLength::SVG_LENGTHTYPE_NUMBER, 0, SVGLength::ReadOnly::No); } GC::Ref SVGSVGElement::create_svg_point() const diff --git a/Libraries/LibWeb/SVG/SVGUseElement.cpp b/Libraries/LibWeb/SVG/SVGUseElement.cpp index 51c579bb164..c5329339a7d 100644 --- a/Libraries/LibWeb/SVG/SVGUseElement.cpp +++ b/Libraries/LibWeb/SVG/SVGUseElement.cpp @@ -215,9 +215,9 @@ GC::Ref SVGUseElement::x() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_x.value_or(0)); - auto anim_length = SVGLength::create(realm(), 0, m_x.value_or(0)); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_x.value_or(0), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_x.value_or(0), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } // https://www.w3.org/TR/SVG11/shapes.html#RectElementYAttribute @@ -225,21 +225,19 @@ GC::Ref SVGUseElement::y() const { // FIXME: Populate the unit type when it is parsed (0 here is "unknown"). // FIXME: Create a proper animated value when animations are supported. - auto base_length = SVGLength::create(realm(), 0, m_y.value_or(0)); - auto anim_length = SVGLength::create(realm(), 0, m_y.value_or(0)); - return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length)); + auto base_length = SVGLength::create(realm(), 0, m_y.value_or(0), SVGLength::ReadOnly::No); + auto anim_length = SVGLength::create(realm(), 0, m_y.value_or(0), SVGLength::ReadOnly::Yes); + return SVGAnimatedLength::create(realm(), base_length, anim_length); } GC::Ref SVGUseElement::width() const { - // FIXME: Implement this properly. - return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0)); + return fake_animated_length_fixme(); } GC::Ref SVGUseElement::height() const { - // FIXME: Implement this properly. - return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0)); + return fake_animated_length_fixme(); } // https://svgwg.org/svg2-draft/struct.html#TermInstanceRoot diff --git a/Tests/LibWeb/Text/expected/SVG/svg-rect-animated-length.txt b/Tests/LibWeb/Text/expected/SVG/svg-rect-animated-length.txt new file mode 100644 index 00000000000..f9df33f76b6 --- /dev/null +++ b/Tests/LibWeb/Text/expected/SVG/svg-rect-animated-length.txt @@ -0,0 +1,9 @@ +rect.x.baseVal: 1 +rect.x.animVal: 1 +rect.y.baseVal: 2 +rect.y.animVal: 2 +rect.width.baseVal: 3 +rect.width.animVal: 3 +rect.height.baseVal: 4 +rect.height.animVal: 4 +Expected exception: NoModificationAllowedError: Cannot modify value of read-only SVGLength diff --git a/Tests/LibWeb/Text/input/SVG/svg-rect-animated-length.html b/Tests/LibWeb/Text/input/SVG/svg-rect-animated-length.html new file mode 100644 index 00000000000..f6f00bc4c2f --- /dev/null +++ b/Tests/LibWeb/Text/input/SVG/svg-rect-animated-length.html @@ -0,0 +1,23 @@ + + + + + +