mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-22 09:18:55 +00:00
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:
parent
f9a13ecb13
commit
676f5837b3
Notes:
github-actions[bot]
2025-08-27 09:51:30 +00:00
Author: https://github.com/gmta
Commit: 676f5837b3
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5994
16 changed files with 175 additions and 113 deletions
|
@ -14,16 +14,21 @@ GC_DEFINE_ALLOCATOR(SVGAnimatedLength);
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGAnimatedLength::create(JS::Realm& realm, GC::Ref<SVGLength> base_val, GC::Ref<SVGLength> anim_val)
|
GC::Ref<SVGAnimatedLength> SVGAnimatedLength::create(JS::Realm& realm, GC::Ref<SVGLength> base_val, GC::Ref<SVGLength> anim_val)
|
||||||
{
|
{
|
||||||
return realm.create<SVGAnimatedLength>(realm, move(base_val), move(anim_val));
|
return realm.create<SVGAnimatedLength>(realm, base_val, anim_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
SVGAnimatedLength::SVGAnimatedLength(JS::Realm& realm, GC::Ref<SVGLength> base_val, GC::Ref<SVGLength> anim_val)
|
SVGAnimatedLength::SVGAnimatedLength(JS::Realm& realm, GC::Ref<SVGLength> base_val, GC::Ref<SVGLength> anim_val)
|
||||||
: PlatformObject(realm)
|
: PlatformObject(realm)
|
||||||
, m_base_val(move(base_val))
|
, m_base_val(base_val)
|
||||||
, m_anim_val(move(anim_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());
|
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;
|
SVGAnimatedLength::~SVGAnimatedLength() = default;
|
||||||
|
@ -34,7 +39,7 @@ void SVGAnimatedLength::initialize(JS::Realm& realm)
|
||||||
Base::initialize(realm);
|
Base::initialize(realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVGAnimatedLength::visit_edges(Cell::Visitor& visitor)
|
void SVGAnimatedLength::visit_edges(Visitor& visitor)
|
||||||
{
|
{
|
||||||
Base::visit_edges(visitor);
|
Base::visit_edges(visitor);
|
||||||
visitor.visit(m_base_val);
|
visitor.visit(m_base_val);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
|
* Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
|
||||||
* Copyright (c) 2023, Preston Taylor <95388976+PrestonLTaylor@users.noreply.github.com>
|
* Copyright (c) 2023, Preston Taylor <95388976+PrestonLTaylor@users.noreply.github.com>
|
||||||
|
* Copyright (c) 2025, Jelle Raaijmakers <jelle@ladybird.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -298,17 +299,28 @@ GC::Ptr<SVGElement> SVGElement::viewport_element()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GC::Ref<SVGAnimatedLength> 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<SVGAnimatedLength> SVGElement::svg_animated_length_for_property(CSS::PropertyID property) const
|
GC::Ref<SVGAnimatedLength> SVGElement::svg_animated_length_for_property(CSS::PropertyID property) const
|
||||||
{
|
{
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// 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 const computed_properties = this->computed_properties()) {
|
||||||
if (auto length = computed_properties->length_percentage(property); length.has_value())
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ public:
|
||||||
bool should_include_in_accessibility_tree() const;
|
bool should_include_in_accessibility_tree() const;
|
||||||
virtual Optional<ARIA::Role> default_role() const override;
|
virtual Optional<ARIA::Role> default_role() const override;
|
||||||
|
|
||||||
|
GC::Ref<SVGAnimatedLength> fake_animated_length_fixme() const;
|
||||||
GC::Ref<SVGAnimatedLength> svg_animated_length_for_property(CSS::PropertyID) const;
|
GC::Ref<SVGAnimatedLength> svg_animated_length_for_property(CSS::PropertyID) const;
|
||||||
|
|
||||||
virtual bool is_presentational_hint(FlyString const&) const override;
|
virtual bool is_presentational_hint(FlyString const&) const override;
|
||||||
|
|
|
@ -81,9 +81,9 @@ GC::Ref<SVGAnimatedLength> SVGEllipseElement::cx() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// FIXME: Create a proper animated value when animations are supported.
|
||||||
auto base_length = SVGLength::create(realm(), 0, m_center_x.value_or(0));
|
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));
|
auto anim_length = SVGLength::create(realm(), 0, m_center_x.value_or(0), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG11/shapes.html#EllipseElementCYAttribute
|
// https://www.w3.org/TR/SVG11/shapes.html#EllipseElementCYAttribute
|
||||||
|
@ -91,9 +91,9 @@ GC::Ref<SVGAnimatedLength> SVGEllipseElement::cy() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// FIXME: Create a proper animated value when animations are supported.
|
||||||
auto base_length = SVGLength::create(realm(), 0, m_center_y.value_or(0));
|
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));
|
auto anim_length = SVGLength::create(realm(), 0, m_center_y.value_or(0), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG11/shapes.html#EllipseElementRXAttribute
|
// https://www.w3.org/TR/SVG11/shapes.html#EllipseElementRXAttribute
|
||||||
|
@ -101,9 +101,9 @@ GC::Ref<SVGAnimatedLength> SVGEllipseElement::rx() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// FIXME: Create a proper animated value when animations are supported.
|
||||||
auto base_length = SVGLength::create(realm(), 0, m_radius_x.value_or(0));
|
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));
|
auto anim_length = SVGLength::create(realm(), 0, m_radius_x.value_or(0), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG11/shapes.html#EllipseElementRYAttribute
|
// https://www.w3.org/TR/SVG11/shapes.html#EllipseElementRYAttribute
|
||||||
|
@ -111,9 +111,9 @@ GC::Ref<SVGAnimatedLength> SVGEllipseElement::ry() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// FIXME: Create a proper animated value when animations are supported.
|
||||||
auto base_length = SVGLength::create(realm(), 0, m_radius_y.value_or(0));
|
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));
|
auto anim_length = SVGLength::create(realm(), 0, m_radius_y.value_or(0), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,10 @@ void SVGForeignObjectElement::initialize(JS::Realm& realm)
|
||||||
Base::initialize(realm);
|
Base::initialize(realm);
|
||||||
|
|
||||||
// FIXME: These never actually get updated!
|
// FIXME: These never actually get updated!
|
||||||
m_x = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, 0), SVGLength::create(realm, 0, 0));
|
m_x = fake_animated_length_fixme();
|
||||||
m_y = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, 0), SVGLength::create(realm, 0, 0));
|
m_y = fake_animated_length_fixme();
|
||||||
m_width = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, 0), SVGLength::create(realm, 0, 0));
|
m_width = fake_animated_length_fixme();
|
||||||
m_height = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, 0), SVGLength::create(realm, 0, 0));
|
m_height = fake_animated_length_fixme();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVGForeignObjectElement::visit_edges(Cell::Visitor& visitor)
|
void SVGForeignObjectElement::visit_edges(Cell::Visitor& visitor)
|
||||||
|
|
|
@ -81,10 +81,8 @@ void SVGImageElement::attribute_changed(FlyString const& name, Optional<String>
|
||||||
// https://svgwg.org/svg2-draft/embedded.html#__svg__SVGImageElement__x
|
// https://svgwg.org/svg2-draft/embedded.html#__svg__SVGImageElement__x
|
||||||
GC::Ref<SVG::SVGAnimatedLength> SVGImageElement::x()
|
GC::Ref<SVG::SVGAnimatedLength> SVGImageElement::x()
|
||||||
{
|
{
|
||||||
if (!m_x) {
|
if (!m_x)
|
||||||
auto& realm = this->realm();
|
m_x = fake_animated_length_fixme();
|
||||||
m_x = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, 0), SVGLength::create(realm, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return *m_x;
|
return *m_x;
|
||||||
}
|
}
|
||||||
|
@ -92,10 +90,8 @@ GC::Ref<SVG::SVGAnimatedLength> SVGImageElement::x()
|
||||||
// https://svgwg.org/svg2-draft/embedded.html#__svg__SVGImageElement__y
|
// https://svgwg.org/svg2-draft/embedded.html#__svg__SVGImageElement__y
|
||||||
GC::Ref<SVG::SVGAnimatedLength> SVGImageElement::y()
|
GC::Ref<SVG::SVGAnimatedLength> SVGImageElement::y()
|
||||||
{
|
{
|
||||||
if (!m_y) {
|
if (!m_y)
|
||||||
auto& realm = this->realm();
|
m_y = fake_animated_length_fixme();
|
||||||
m_y = SVGAnimatedLength::create(realm, SVGLength::create(realm, 0, 0), SVGLength::create(realm, 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return *m_y;
|
return *m_y;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +101,10 @@ GC::Ref<SVG::SVGAnimatedLength> SVGImageElement::width()
|
||||||
{
|
{
|
||||||
if (!m_width) {
|
if (!m_width) {
|
||||||
auto& realm = this->realm();
|
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;
|
return *m_width;
|
||||||
|
@ -116,7 +115,10 @@ GC::Ref<SVG::SVGAnimatedLength> SVGImageElement::height()
|
||||||
{
|
{
|
||||||
if (!m_height) {
|
if (!m_height) {
|
||||||
auto& realm = this->realm();
|
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;
|
return *m_height;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
|
* Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
|
||||||
|
* Copyright (c) 2025, Jelle Raaijmakers <jelle@ladybird.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -13,19 +14,20 @@ namespace Web::SVG {
|
||||||
|
|
||||||
GC_DEFINE_ALLOCATOR(SVGLength);
|
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.
|
// FIXME: We can't tell if a CSS::LengthPercentage was a unitless length.
|
||||||
(void)SVG_LENGTHTYPE_NUMBER;
|
(void)SVG_LENGTHTYPE_NUMBER;
|
||||||
if (length_percentage.is_percentage())
|
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())
|
if (length_percentage.is_length())
|
||||||
return SVGLength::create(
|
return create(
|
||||||
realm, [&] {
|
realm, [&] {
|
||||||
switch (length_percentage.length().type()) {
|
switch (length_percentage.length().type()) {
|
||||||
case CSS::Length::Type::Em:
|
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;
|
return SVG_LENGTHTYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
}(),
|
}(),
|
||||||
length_percentage.length().raw_value());
|
length_percentage.length().raw_value(), read_only);
|
||||||
return SVGLength::create(realm, SVG_LENGTHTYPE_UNKNOWN, 0);
|
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)
|
: PlatformObject(realm)
|
||||||
, m_unit_type(unit_type)
|
|
||||||
, m_value(value)
|
, 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;
|
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)
|
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_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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,23 +30,32 @@ public:
|
||||||
static constexpr unsigned short SVG_LENGTHTYPE_PT = 9;
|
static constexpr unsigned short SVG_LENGTHTYPE_PT = 9;
|
||||||
static constexpr unsigned short SVG_LENGTHTYPE_PC = 10;
|
static constexpr unsigned short SVG_LENGTHTYPE_PC = 10;
|
||||||
|
|
||||||
[[nodiscard]] static GC::Ref<SVGLength> create(JS::Realm&, u8 unit_type, float value);
|
enum class ReadOnly : u8 {
|
||||||
virtual ~SVGLength() override;
|
Yes,
|
||||||
|
No,
|
||||||
|
};
|
||||||
|
|
||||||
u8 unit_type() const { return m_unit_type; }
|
[[nodiscard]] static GC::Ref<SVGLength> create(JS::Realm&, u8 unit_type, float value, ReadOnly);
|
||||||
|
virtual ~SVGLength() override;
|
||||||
|
|
||||||
float value() const { return m_value; }
|
float value() const { return m_value; }
|
||||||
WebIDL::ExceptionOr<void> set_value(float value);
|
WebIDL::ExceptionOr<void> set_value(float value);
|
||||||
|
|
||||||
[[nodiscard]] static GC::Ref<SVGLength> 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<SVGLength> from_length_percentage(JS::Realm&, CSS::LengthPercentage const&, ReadOnly);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SVGLength(JS::Realm&, u8 unit_type, float value);
|
SVGLength(JS::Realm&, u8 unit_type, float value, ReadOnly);
|
||||||
|
|
||||||
virtual void initialize(JS::Realm&) override;
|
virtual void initialize(JS::Realm&) override;
|
||||||
|
|
||||||
u8 m_unit_type { 0 };
|
|
||||||
float m_value { 0 };
|
float m_value { 0 };
|
||||||
|
u8 m_unit_type { 0 };
|
||||||
|
|
||||||
|
// https://svgwg.org/svg2-draft/types.html#ReadOnlyLength
|
||||||
|
ReadOnly m_read_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,9 +66,9 @@ GC::Ref<SVGAnimatedLength> SVGLineElement::x1() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// 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 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());
|
auto anim_length = SVGLength::create(realm(), 0, m_x1.value_or({ 0, false }).value(), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG11/shapes.html#LineElementY1Attribute
|
// https://www.w3.org/TR/SVG11/shapes.html#LineElementY1Attribute
|
||||||
|
@ -76,9 +76,9 @@ GC::Ref<SVGAnimatedLength> SVGLineElement::y1() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// 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 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());
|
auto anim_length = SVGLength::create(realm(), 0, m_y1.value_or({ 0, false }).value(), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG11/shapes.html#LineElementX2Attribute
|
// https://www.w3.org/TR/SVG11/shapes.html#LineElementX2Attribute
|
||||||
|
@ -86,9 +86,9 @@ GC::Ref<SVGAnimatedLength> SVGLineElement::x2() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// 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 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());
|
auto anim_length = SVGLength::create(realm(), 0, m_x2.value_or({ 0, false }).value(), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG11/shapes.html#LineElementY2Attribute
|
// https://www.w3.org/TR/SVG11/shapes.html#LineElementY2Attribute
|
||||||
|
@ -96,9 +96,9 @@ GC::Ref<SVGAnimatedLength> SVGLineElement::y2() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// 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 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());
|
auto anim_length = SVGLength::create(realm(), 0, m_y2.value_or({ 0, false }).value(), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,26 +162,22 @@ Optional<Painting::PaintStyle> SVGLinearGradientElement::to_gfx_paint_style(SVGP
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGLinearGradientElement::x1() const
|
GC::Ref<SVGAnimatedLength> SVGLinearGradientElement::x1() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement this properly.
|
return fake_animated_length_fixme();
|
||||||
return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGLinearGradientElement::y1() const
|
GC::Ref<SVGAnimatedLength> SVGLinearGradientElement::y1() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement this properly.
|
return fake_animated_length_fixme();
|
||||||
return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGLinearGradientElement::x2() const
|
GC::Ref<SVGAnimatedLength> SVGLinearGradientElement::x2() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement this properly.
|
return fake_animated_length_fixme();
|
||||||
return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGLinearGradientElement::y2() const
|
GC::Ref<SVGAnimatedLength> SVGLinearGradientElement::y2() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement this properly.
|
return fake_animated_length_fixme();
|
||||||
return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,38 +218,32 @@ Optional<Painting::PaintStyle> SVGRadialGradientElement::to_gfx_paint_style(SVGP
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGRadialGradientElement::cx() const
|
GC::Ref<SVGAnimatedLength> SVGRadialGradientElement::cx() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement this properly.
|
return fake_animated_length_fixme();
|
||||||
return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGRadialGradientElement::cy() const
|
GC::Ref<SVGAnimatedLength> SVGRadialGradientElement::cy() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement this properly.
|
return fake_animated_length_fixme();
|
||||||
return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGRadialGradientElement::fx() const
|
GC::Ref<SVGAnimatedLength> SVGRadialGradientElement::fx() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement this properly.
|
return fake_animated_length_fixme();
|
||||||
return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGRadialGradientElement::fy() const
|
GC::Ref<SVGAnimatedLength> SVGRadialGradientElement::fy() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement this properly.
|
return fake_animated_length_fixme();
|
||||||
return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGRadialGradientElement::fr() const
|
GC::Ref<SVGAnimatedLength> SVGRadialGradientElement::fr() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement this properly.
|
return fake_animated_length_fixme();
|
||||||
return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGRadialGradientElement::r() const
|
GC::Ref<SVGAnimatedLength> SVGRadialGradientElement::r() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement this properly.
|
return fake_animated_length_fixme();
|
||||||
return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,9 +158,9 @@ GC::Ref<SVGAnimatedLength> SVGRectElement::x() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// FIXME: Create a proper animated value when animations are supported.
|
||||||
auto base_length = SVGLength::create(realm(), 0, m_x.value_or(0));
|
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));
|
auto anim_length = SVGLength::create(realm(), 0, m_x.value_or(0), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG11/shapes.html#RectElementYAttribute
|
// https://www.w3.org/TR/SVG11/shapes.html#RectElementYAttribute
|
||||||
|
@ -168,9 +168,9 @@ GC::Ref<SVGAnimatedLength> SVGRectElement::y() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// FIXME: Create a proper animated value when animations are supported.
|
||||||
auto base_length = SVGLength::create(realm(), 0, m_y.value_or(0));
|
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));
|
auto anim_length = SVGLength::create(realm(), 0, m_y.value_or(0), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG11/shapes.html#RectElementWidthAttribute
|
// https://www.w3.org/TR/SVG11/shapes.html#RectElementWidthAttribute
|
||||||
|
@ -178,9 +178,9 @@ GC::Ref<SVGAnimatedLength> SVGRectElement::width() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// FIXME: Create a proper animated value when animations are supported.
|
||||||
auto base_length = SVGLength::create(realm(), 0, m_width.value_or(0));
|
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));
|
auto anim_length = SVGLength::create(realm(), 0, m_width.value_or(0), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG11/shapes.html#RectElementHeightAttribute
|
// https://www.w3.org/TR/SVG11/shapes.html#RectElementHeightAttribute
|
||||||
|
@ -188,9 +188,9 @@ GC::Ref<SVGAnimatedLength> SVGRectElement::height() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// FIXME: Create a proper animated value when animations are supported.
|
||||||
auto base_length = SVGLength::create(realm(), 0, m_height.value_or(0));
|
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));
|
auto anim_length = SVGLength::create(realm(), 0, m_height.value_or(0), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG11/shapes.html#RectElementRXAttribute
|
// https://www.w3.org/TR/SVG11/shapes.html#RectElementRXAttribute
|
||||||
|
@ -198,9 +198,9 @@ GC::Ref<SVGAnimatedLength> SVGRectElement::rx() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// FIXME: Create a proper animated value when animations are supported.
|
||||||
auto base_length = SVGLength::create(realm(), 0, m_radius_x.value_or(0));
|
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));
|
auto anim_length = SVGLength::create(realm(), 0, m_radius_x.value_or(0), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG11/shapes.html#RectElementRYAttribute
|
// https://www.w3.org/TR/SVG11/shapes.html#RectElementRYAttribute
|
||||||
|
@ -208,9 +208,9 @@ GC::Ref<SVGAnimatedLength> SVGRectElement::ry() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// FIXME: Create a proper animated value when animations are supported.
|
||||||
auto base_length = SVGLength::create(realm(), 0, m_radius_y.value_or(0));
|
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));
|
auto anim_length = SVGLength::create(realm(), 0, m_radius_y.value_or(0), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,7 +274,7 @@ void SVGSVGElement::deselect_all() const
|
||||||
GC::Ref<SVGLength> SVGSVGElement::create_svg_length() const
|
GC::Ref<SVGLength> SVGSVGElement::create_svg_length() const
|
||||||
{
|
{
|
||||||
// A new, detached SVGLength object whose value is the unitless <number> 0.
|
// A new, detached SVGLength object whose value is the unitless <number> 0.
|
||||||
return SVGLength::create(realm(), SVGLength::SVG_LENGTHTYPE_NUMBER, 0);
|
return SVGLength::create(realm(), SVGLength::SVG_LENGTHTYPE_NUMBER, 0, SVGLength::ReadOnly::No);
|
||||||
}
|
}
|
||||||
|
|
||||||
GC::Ref<Geometry::DOMPoint> SVGSVGElement::create_svg_point() const
|
GC::Ref<Geometry::DOMPoint> SVGSVGElement::create_svg_point() const
|
||||||
|
|
|
@ -215,9 +215,9 @@ GC::Ref<SVGAnimatedLength> SVGUseElement::x() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// FIXME: Create a proper animated value when animations are supported.
|
||||||
auto base_length = SVGLength::create(realm(), 0, m_x.value_or(0));
|
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));
|
auto anim_length = SVGLength::create(realm(), 0, m_x.value_or(0), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG11/shapes.html#RectElementYAttribute
|
// https://www.w3.org/TR/SVG11/shapes.html#RectElementYAttribute
|
||||||
|
@ -225,21 +225,19 @@ GC::Ref<SVGAnimatedLength> SVGUseElement::y() const
|
||||||
{
|
{
|
||||||
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
// FIXME: Populate the unit type when it is parsed (0 here is "unknown").
|
||||||
// FIXME: Create a proper animated value when animations are supported.
|
// FIXME: Create a proper animated value when animations are supported.
|
||||||
auto base_length = SVGLength::create(realm(), 0, m_y.value_or(0));
|
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));
|
auto anim_length = SVGLength::create(realm(), 0, m_y.value_or(0), SVGLength::ReadOnly::Yes);
|
||||||
return SVGAnimatedLength::create(realm(), move(base_length), move(anim_length));
|
return SVGAnimatedLength::create(realm(), base_length, anim_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGUseElement::width() const
|
GC::Ref<SVGAnimatedLength> SVGUseElement::width() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement this properly.
|
return fake_animated_length_fixme();
|
||||||
return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GC::Ref<SVGAnimatedLength> SVGUseElement::height() const
|
GC::Ref<SVGAnimatedLength> SVGUseElement::height() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement this properly.
|
return fake_animated_length_fixme();
|
||||||
return SVGAnimatedLength::create(realm(), SVGLength::create(realm(), 0, 0), SVGLength::create(realm(), 0, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://svgwg.org/svg2-draft/struct.html#TermInstanceRoot
|
// https://svgwg.org/svg2-draft/struct.html#TermInstanceRoot
|
||||||
|
|
|
@ -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
|
23
Tests/LibWeb/Text/input/SVG/svg-rect-animated-length.html
Normal file
23
Tests/LibWeb/Text/input/SVG/svg-rect-animated-length.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect id="rect" x="1" y="2" width="3" height="4" />
|
||||||
|
</svg>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
println(`rect.x.baseVal: ${rect.x.baseVal.value}`);
|
||||||
|
println(`rect.x.animVal: ${rect.x.animVal.value}`);
|
||||||
|
println(`rect.y.baseVal: ${rect.y.baseVal.value}`);
|
||||||
|
println(`rect.y.animVal: ${rect.y.animVal.value}`);
|
||||||
|
println(`rect.width.baseVal: ${rect.width.baseVal.value}`);
|
||||||
|
println(`rect.width.animVal: ${rect.width.animVal.value}`);
|
||||||
|
println(`rect.height.baseVal: ${rect.height.baseVal.value}`);
|
||||||
|
println(`rect.height.animVal: ${rect.height.animVal.value}`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
rect.x.animVal.value = 2;
|
||||||
|
} catch (e) {
|
||||||
|
println(`Expected exception: ${e}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue