mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:27:44 +00:00
LibWeb: Implement SVGUseElement#href
Required by Ruffle.
b196c8d1bc/web/packages/core/src/shadow-template.ts (L601-L602)
This commit is contained in:
parent
968bec9844
commit
54972e3ceb
5 changed files with 178 additions and 2 deletions
114
Tests/LibWeb/Text/expected/SVG/svg-href.txt
Normal file
114
Tests/LibWeb/Text/expected/SVG/svg-href.txt
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
---------------
|
||||||
|
use - no-xlink-href
|
||||||
|
---------------
|
||||||
|
element.href instanceof SVGAnimatedString -> true
|
||||||
|
element.href === element.href -> true
|
||||||
|
element.href.baseVal ->
|
||||||
|
element.href.animVal ->
|
||||||
|
element.href.baseVal === element.href.animVal -> true
|
||||||
|
element.getAttribute("xlink:href") -> null
|
||||||
|
element.getAttribute("href") -> null
|
||||||
|
setting baseVal...
|
||||||
|
done, new values:
|
||||||
|
element.href.baseVal -> testSet
|
||||||
|
element.href.animVal -> testSet
|
||||||
|
element.href.baseVal === element.href.animVal -> true
|
||||||
|
element.getAttribute("xlink:href") -> null
|
||||||
|
element.getAttribute("href") -> testSet
|
||||||
|
animVal should be readonly:
|
||||||
|
TypeError: Cannot set property 'animVal' of [object SVGAnimatedString]
|
||||||
|
---------------
|
||||||
|
use - explicit-xlink-href
|
||||||
|
---------------
|
||||||
|
element.href instanceof SVGAnimatedString -> true
|
||||||
|
element.href === element.href -> true
|
||||||
|
element.href.baseVal -> test1
|
||||||
|
element.href.animVal -> test1
|
||||||
|
element.href.baseVal === element.href.animVal -> true
|
||||||
|
element.getAttribute("xlink:href") -> test1
|
||||||
|
element.getAttribute("href") -> null
|
||||||
|
setting baseVal...
|
||||||
|
done, new values:
|
||||||
|
element.href.baseVal -> testSet
|
||||||
|
element.href.animVal -> testSet
|
||||||
|
element.href.baseVal === element.href.animVal -> true
|
||||||
|
element.getAttribute("xlink:href") -> testSet
|
||||||
|
element.getAttribute("href") -> null
|
||||||
|
animVal should be readonly:
|
||||||
|
TypeError: Cannot set property 'animVal' of [object SVGAnimatedString]
|
||||||
|
---------------
|
||||||
|
use - implicit-xlink-href
|
||||||
|
---------------
|
||||||
|
element.href instanceof SVGAnimatedString -> true
|
||||||
|
element.href === element.href -> true
|
||||||
|
element.href.baseVal -> test2
|
||||||
|
element.href.animVal -> test2
|
||||||
|
element.href.baseVal === element.href.animVal -> true
|
||||||
|
element.getAttribute("xlink:href") -> null
|
||||||
|
element.getAttribute("href") -> test2
|
||||||
|
setting baseVal...
|
||||||
|
done, new values:
|
||||||
|
element.href.baseVal -> testSet
|
||||||
|
element.href.animVal -> testSet
|
||||||
|
element.href.baseVal === element.href.animVal -> true
|
||||||
|
element.getAttribute("xlink:href") -> null
|
||||||
|
element.getAttribute("href") -> testSet
|
||||||
|
animVal should be readonly:
|
||||||
|
TypeError: Cannot set property 'animVal' of [object SVGAnimatedString]
|
||||||
|
---------------
|
||||||
|
textPath - no-xlink-href
|
||||||
|
---------------
|
||||||
|
element.href instanceof SVGAnimatedString -> true
|
||||||
|
element.href === element.href -> true
|
||||||
|
element.href.baseVal ->
|
||||||
|
element.href.animVal ->
|
||||||
|
element.href.baseVal === element.href.animVal -> true
|
||||||
|
element.getAttribute("xlink:href") -> null
|
||||||
|
element.getAttribute("href") -> null
|
||||||
|
setting baseVal...
|
||||||
|
done, new values:
|
||||||
|
element.href.baseVal -> testSet
|
||||||
|
element.href.animVal -> testSet
|
||||||
|
element.href.baseVal === element.href.animVal -> true
|
||||||
|
element.getAttribute("xlink:href") -> null
|
||||||
|
element.getAttribute("href") -> testSet
|
||||||
|
animVal should be readonly:
|
||||||
|
TypeError: Cannot set property 'animVal' of [object SVGAnimatedString]
|
||||||
|
---------------
|
||||||
|
textPath - explicit-xlink-href
|
||||||
|
---------------
|
||||||
|
element.href instanceof SVGAnimatedString -> true
|
||||||
|
element.href === element.href -> true
|
||||||
|
element.href.baseVal -> test1
|
||||||
|
element.href.animVal -> test1
|
||||||
|
element.href.baseVal === element.href.animVal -> true
|
||||||
|
element.getAttribute("xlink:href") -> test1
|
||||||
|
element.getAttribute("href") -> null
|
||||||
|
setting baseVal...
|
||||||
|
done, new values:
|
||||||
|
element.href.baseVal -> testSet
|
||||||
|
element.href.animVal -> testSet
|
||||||
|
element.href.baseVal === element.href.animVal -> true
|
||||||
|
element.getAttribute("xlink:href") -> testSet
|
||||||
|
element.getAttribute("href") -> null
|
||||||
|
animVal should be readonly:
|
||||||
|
TypeError: Cannot set property 'animVal' of [object SVGAnimatedString]
|
||||||
|
---------------
|
||||||
|
textPath - implicit-xlink-href
|
||||||
|
---------------
|
||||||
|
element.href instanceof SVGAnimatedString -> true
|
||||||
|
element.href === element.href -> true
|
||||||
|
element.href.baseVal -> test2
|
||||||
|
element.href.animVal -> test2
|
||||||
|
element.href.baseVal === element.href.animVal -> true
|
||||||
|
element.getAttribute("xlink:href") -> null
|
||||||
|
element.getAttribute("href") -> test2
|
||||||
|
setting baseVal...
|
||||||
|
done, new values:
|
||||||
|
element.href.baseVal -> testSet
|
||||||
|
element.href.animVal -> testSet
|
||||||
|
element.href.baseVal === element.href.animVal -> true
|
||||||
|
element.getAttribute("xlink:href") -> null
|
||||||
|
element.getAttribute("href") -> testSet
|
||||||
|
animVal should be readonly:
|
||||||
|
TypeError: Cannot set property 'animVal' of [object SVGAnimatedString]
|
57
Tests/LibWeb/Text/input/SVG/svg-href.html
Normal file
57
Tests/LibWeb/Text/input/SVG/svg-href.html
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" id="svg-element">
|
||||||
|
<use class="no-xlink-href"></use>
|
||||||
|
<use class="explicit-xlink-href" xlink:href="test1"></use>
|
||||||
|
<use class="implicit-xlink-href" href="test2"></use>
|
||||||
|
<text class="ignore">
|
||||||
|
<textPath class="no-xlink-href"></textPath>
|
||||||
|
<textPath class="explicit-xlink-href" xlink:href="test1"></textPath>
|
||||||
|
<textPath class="implicit-xlink-href" href="test2"></textPath>
|
||||||
|
</text>
|
||||||
|
</svg>
|
||||||
|
<script>
|
||||||
|
function dumpAttribute(element) {
|
||||||
|
"use strict";
|
||||||
|
println("---------------");
|
||||||
|
println(`${element.tagName} - ${element.getAttribute("class")}`);
|
||||||
|
println("---------------");
|
||||||
|
println(`element.href instanceof SVGAnimatedString -> ${element.href instanceof SVGAnimatedString}`);
|
||||||
|
println(`element.href === element.href -> ${element.href === element.href}`);
|
||||||
|
println(`element.href.baseVal -> ${element.href.baseVal}`);
|
||||||
|
println(`element.href.animVal -> ${element.href.animVal}`);
|
||||||
|
println(`element.href.baseVal === element.href.animVal -> ${element.href.baseVal === element.href.animVal}`);
|
||||||
|
println(`element.getAttribute("xlink:href") -> ${element.getAttribute("xlink:href")}`);
|
||||||
|
println(`element.getAttribute("href") -> ${element.getAttribute("href")}`);
|
||||||
|
println("setting baseVal...");
|
||||||
|
element.href.baseVal = "testSet";
|
||||||
|
println("done, new values:");
|
||||||
|
println(`element.href.baseVal -> ${element.href.baseVal}`);
|
||||||
|
println(`element.href.animVal -> ${element.href.animVal}`);
|
||||||
|
println(`element.href.baseVal === element.href.animVal -> ${element.href.baseVal === element.href.animVal}`);
|
||||||
|
println(`element.getAttribute("xlink:href") -> ${element.getAttribute("xlink:href")}`);
|
||||||
|
println(`element.getAttribute("href") -> ${element.getAttribute("href")}`);
|
||||||
|
println("animVal should be readonly:")
|
||||||
|
try {
|
||||||
|
element.href.animVal = "invalid";
|
||||||
|
} catch (e) {
|
||||||
|
println(`${e.name}: ${e.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dumpTree(element) {
|
||||||
|
for (const child of Array.from(element.children))
|
||||||
|
{
|
||||||
|
if (child.getAttribute("class") !== "ignore")
|
||||||
|
{
|
||||||
|
dumpAttribute(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
dumpTree(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
const svgElement = document.getElementById("svg-element");
|
||||||
|
dumpTree(svgElement);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -44,6 +44,7 @@ void SVGUseElement::initialize(JS::Realm& realm)
|
||||||
void SVGUseElement::visit_edges(Cell::Visitor& visitor)
|
void SVGUseElement::visit_edges(Cell::Visitor& visitor)
|
||||||
{
|
{
|
||||||
Base::visit_edges(visitor);
|
Base::visit_edges(visitor);
|
||||||
|
SVGURIReferenceMixin::visit_edges(visitor);
|
||||||
visitor.visit(m_document_observer);
|
visitor.visit(m_document_observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,13 @@
|
||||||
#include <LibWeb/DOM/DocumentObserver.h>
|
#include <LibWeb/DOM/DocumentObserver.h>
|
||||||
#include <LibWeb/SVG/SVGAnimatedLength.h>
|
#include <LibWeb/SVG/SVGAnimatedLength.h>
|
||||||
#include <LibWeb/SVG/SVGGraphicsElement.h>
|
#include <LibWeb/SVG/SVGGraphicsElement.h>
|
||||||
|
#include <LibWeb/SVG/SVGURIReference.h>
|
||||||
|
|
||||||
namespace Web::SVG {
|
namespace Web::SVG {
|
||||||
|
|
||||||
class SVGUseElement final : public SVGGraphicsElement {
|
class SVGUseElement final
|
||||||
|
: public SVGGraphicsElement
|
||||||
|
, public SVGURIReferenceMixin<SupportsXLinkHref::Yes> {
|
||||||
WEB_PLATFORM_OBJECT(SVGUseElement, SVGGraphicsElement);
|
WEB_PLATFORM_OBJECT(SVGUseElement, SVGGraphicsElement);
|
||||||
JS_DECLARE_ALLOCATOR(SVGUseElement);
|
JS_DECLARE_ALLOCATOR(SVGUseElement);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#import <SVG/SVGAnimatedLength.idl>
|
#import <SVG/SVGAnimatedLength.idl>
|
||||||
#import <SVG/SVGElement.idl>
|
#import <SVG/SVGElement.idl>
|
||||||
#import <SVG/SVGGraphicsElement.idl>
|
#import <SVG/SVGGraphicsElement.idl>
|
||||||
|
#import <SVG/SVGURIReference.idl>
|
||||||
|
|
||||||
// https://svgwg.org/svg2-draft/struct.html#InterfaceSVGUseElement
|
// https://svgwg.org/svg2-draft/struct.html#InterfaceSVGUseElement
|
||||||
[Exposed=Window]
|
[Exposed=Window]
|
||||||
|
@ -13,4 +14,4 @@ interface SVGUseElement : SVGGraphicsElement {
|
||||||
[SameObject] readonly attribute SVGElement? animatedInstanceRoot;
|
[SameObject] readonly attribute SVGElement? animatedInstanceRoot;
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: SVGUseElement includes SVGURIReference;
|
SVGUseElement includes SVGURIReference;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue