mirror of
https://github.com/lexmount/moli.git
synced 2026-10-06 08:00:59 +00:00
feat(svg): expose remaining filter element interfaces
This commit is contained in:
@@ -95,6 +95,12 @@ pub fn svg_element_interface_name(local_name: &str) -> &'static str {
|
||||
"defs" => "SVGDefsElement",
|
||||
"desc" => "SVGDescElement",
|
||||
"ellipse" => "SVGEllipseElement",
|
||||
"feComponentTransfer" => "SVGFEComponentTransferElement",
|
||||
"feFlood" => "SVGFEFloodElement",
|
||||
"feImage" => "SVGFEImageElement",
|
||||
"feMerge" => "SVGFEMergeElement",
|
||||
"feMergeNode" => "SVGFEMergeNodeElement",
|
||||
"feTile" => "SVGFETileElement",
|
||||
"foreignObject" => "SVGForeignObjectElement",
|
||||
"g" => "SVGGElement",
|
||||
"image" => "SVGImageElement",
|
||||
|
||||
@@ -129,6 +129,30 @@ const NODE_BRIDGE_DESCRIPTORS: &[BridgeDescriptor] = &[
|
||||
SpecializedTemplateInstaller::None,
|
||||
SVG_GEOMETRY_RUNTIME_INSTALL_GROUPS,
|
||||
),
|
||||
descriptor(
|
||||
web_api_interfaces::SVGFEComponentTransferElement::DESCRIPTOR,
|
||||
ELEMENT_GROUPS,
|
||||
),
|
||||
descriptor(
|
||||
web_api_interfaces::SVGFEFloodElement::DESCRIPTOR,
|
||||
ELEMENT_GROUPS,
|
||||
),
|
||||
descriptor(
|
||||
web_api_interfaces::SVGFEImageElement::DESCRIPTOR,
|
||||
ELEMENT_GROUPS,
|
||||
),
|
||||
descriptor(
|
||||
web_api_interfaces::SVGFEMergeElement::DESCRIPTOR,
|
||||
ELEMENT_GROUPS,
|
||||
),
|
||||
descriptor(
|
||||
web_api_interfaces::SVGFEMergeNodeElement::DESCRIPTOR,
|
||||
ELEMENT_GROUPS,
|
||||
),
|
||||
descriptor(
|
||||
web_api_interfaces::SVGFETileElement::DESCRIPTOR,
|
||||
ELEMENT_GROUPS,
|
||||
),
|
||||
descriptor(
|
||||
web_api_interfaces::SVGForeignObjectElement::DESCRIPTOR,
|
||||
ELEMENT_GROUPS,
|
||||
|
||||
@@ -2161,6 +2161,7 @@ mod queue_microtask;
|
||||
mod rendering_update;
|
||||
mod script_terminal_completion;
|
||||
mod streams;
|
||||
mod svg_filter_interfaces;
|
||||
mod url_components;
|
||||
mod webgl_interfaces;
|
||||
mod webidl_collections;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn svg_filter_interfaces_preserve_native_inheritance_and_realm_contracts() {
|
||||
let mut vm = new_storage_page_task_executor_test_vm("https://svg-filter-interfaces.test/");
|
||||
vm.eval("document.body.innerHTML = '<iframe id=child></iframe>'")
|
||||
.unwrap();
|
||||
assert_eq!(vm.eval(r#"(() => {
|
||||
const assert = (ok, message) => { if (!ok) throw Error(message); };
|
||||
const ns = 'http://www.w3.org/2000/svg';
|
||||
const child = document.getElementById('child').contentWindow;
|
||||
const detached = document.implementation.createHTMLDocument('');
|
||||
const xml = new DOMParser().parseFromString('<svg xmlns="' + ns + '"/>', 'image/svg+xml');
|
||||
for (const [name, parentName] of [["SVGFEComponentTransferElement","SVGElement"],["SVGFEFloodElement","SVGElement"],["SVGFEImageElement","SVGElement"],["SVGFEMergeElement","SVGElement"],["SVGFEMergeNodeElement","SVGElement"],["SVGFETileElement","SVGElement"]]) {
|
||||
for (const w of [window, child]) {
|
||||
const C = w[name], parent = w[parentName];
|
||||
assert(typeof C === 'function' && C.name === name, name + ' exposed');
|
||||
assert(Object.getPrototypeOf(C.prototype) === parent.prototype, name + ' prototype inheritance');
|
||||
assert(Object.getPrototypeOf(C) === parent, name + ' interface inheritance');
|
||||
let error;
|
||||
try { new C(); } catch (caught) { error = caught; }
|
||||
assert(error instanceof w.TypeError, name + ' illegal constructor realm');
|
||||
}
|
||||
}
|
||||
const nodeType = Object.getOwnPropertyDescriptor(Node.prototype, 'nodeType').get;
|
||||
for (const [tag, name] of [["feComponentTransfer","SVGFEComponentTransferElement"],["feFlood","SVGFEFloodElement"],["feImage","SVGFEImageElement"],["feMerge","SVGFEMergeElement"],["feMergeNode","SVGFEMergeNodeElement"],["feTile","SVGFETileElement"]]) {
|
||||
for (const [doc, w] of [[document, window], [child.document, child], [detached, window], [xml, window]]) {
|
||||
const element = doc.createElementNS(ns, tag), C = w[name];
|
||||
assert(element instanceof C && element instanceof w.SVGElement && element instanceof w.Node, tag + ' native factory brand');
|
||||
assert(Object.getPrototypeOf(element) === C.prototype && element.constructor === C, tag + ' factory prototype');
|
||||
assert(Object.prototype.toString.call(element) === '[object ' + name + ']', tag + ' native tag');
|
||||
assert(element.cloneNode(false) instanceof C, tag + ' cloned brand');
|
||||
assert(doc.importNode(element, false) instanceof C, tag + ' imported brand');
|
||||
element.setAttribute('data-test', 'value');
|
||||
assert(element.getAttribute('data-test') === 'value' && nodeType.call(element) === 1, tag + ' inherited DOM behavior');
|
||||
for (const receiver of [Object.create(element), new Proxy(element, {})]) {
|
||||
let error;
|
||||
try { nodeType.call(receiver); } catch (caught) { error = caught; }
|
||||
assert(error instanceof TypeError, tag + ' rejects forged native identity');
|
||||
}
|
||||
assert(!(doc.createElement(tag) instanceof C), tag + ' namespace-sensitive factory');
|
||||
}
|
||||
const parsed = new DOMParser().parseFromString('<svg xmlns="' + ns + '"><' + tag + '/></svg>', 'image/svg+xml');
|
||||
assert(parsed.documentElement.firstElementChild instanceof window[name], tag + ' parsed XML brand');
|
||||
}
|
||||
return true;
|
||||
})()"#).unwrap(), "true");
|
||||
}
|
||||
@@ -392,6 +392,12 @@ interfaces! {
|
||||
SVGDescElement: SVGElement;
|
||||
SVGElement: Element;
|
||||
SVGEllipseElement: SVGGeometryElement;
|
||||
SVGFEComponentTransferElement: SVGElement;
|
||||
SVGFEFloodElement: SVGElement;
|
||||
SVGFEImageElement: SVGElement;
|
||||
SVGFEMergeElement: SVGElement;
|
||||
SVGFEMergeNodeElement: SVGElement;
|
||||
SVGFETileElement: SVGElement;
|
||||
SVGForeignObjectElement: SVGGraphicsElement;
|
||||
SVGGElement: SVGGraphicsElement;
|
||||
SVGGeometryElement: SVGGraphicsElement;
|
||||
|
||||
Reference in New Issue
Block a user