LibWeb: Implement SVGLength's read-only property

An SVGLength can be read-only, e.g. all animVal values cannot be
modified. Implement this for all instantiations of SVGLength.

While we're here, add `fake_animated_length_fixme()` so we can easily
find all sites where we need to improve our animated length game.
This commit is contained in:
Jelle Raaijmakers 2025-08-26 16:51:46 +02:00 committed by Jelle Raaijmakers
commit 676f5837b3
Notes: github-actions[bot] 2025-08-27 09:51:30 +00:00
16 changed files with 175 additions and 113 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
* Copyright (c) 2025, Jelle Raaijmakers <jelle@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -13,19 +14,20 @@ namespace Web::SVG {
GC_DEFINE_ALLOCATOR(SVGLength);
GC::Ref<SVGLength> SVGLength::create(JS::Realm& realm, u8 unit_type, float value)
GC::Ref<SVGLength> SVGLength::create(JS::Realm& realm, u8 unit_type, float value, ReadOnly read_only)
{
return realm.create<SVGLength>(realm, unit_type, value);
return realm.create<SVGLength>(realm, unit_type, value, read_only);
}
GC::Ref<SVGLength> SVGLength::from_length_percentage(JS::Realm& realm, CSS::LengthPercentage const& length_percentage)
GC::Ref<SVGLength> 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> 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<void> SVGLength::set_value(float value)
{
// FIXME: Raise an exception if this <length> 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 <number> 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 {};
}