fix(renderer): complete metadata element reflection

This commit is contained in:
ldm0
2026-09-27 19:22:00 +08:00
parent add98e5090
commit 8f0bbaf726
6 changed files with 120 additions and 15 deletions
@@ -4173,6 +4173,20 @@ struct HtmlLinkElementUrlPrototypeDeclaration {
data = DomStringReflection::LinkIntegrity
)]
integrity: (),
#[webapi(
accessor_property,
getter = dom_string_reflection_getter_function,
setter = dom_string_reflection_setter_function,
data = DomStringReflection::LinkRev
)]
rev: (),
#[webapi(
accessor_property,
getter = dom_string_reflection_getter_function,
setter = dom_string_reflection_setter_function,
data = DomStringReflection::LinkType
)]
r#type: (),
}
#[derive(WebApiFunctionTemplate)]
@@ -4406,6 +4420,13 @@ struct HtmlMetaElementPrototypeDeclaration {
setter = meta_http_equiv_setter_function
)]
http_equiv: (),
#[webapi(
accessor_property,
getter = dom_string_reflection_getter_function,
setter = dom_string_reflection_setter_function,
data = DomStringReflection::MetaScheme
)]
scheme: (),
}
#[derive(WebApiFunctionTemplate)]
@@ -4478,6 +4499,13 @@ struct HtmlAreaElementPrototypeDeclaration {
setter_data = DomStringReflection::AreaDownload
)]
download: (),
#[webapi(
accessor_property,
getter = html_hreflang_getter_function,
setter = dom_string_reflection_setter_function,
setter_data = DomStringReflection::AreaHreflang
)]
hreflang: (),
#[webapi(
accessor_property,
getter = html_shape_getter_function,
@@ -4492,6 +4520,13 @@ struct HtmlAreaElementPrototypeDeclaration {
setter_data = UsvStringReflection::AreaPing
)]
ping: (),
#[webapi(
accessor_property,
getter = html_type_getter_function,
setter = dom_string_reflection_setter_function,
setter_data = DomStringReflection::AreaType
)]
r#type: (),
#[webapi(
accessor_property = "noHref",
getter = html_no_href_getter_function,
@@ -173,8 +173,10 @@ pub(super) enum DomStringReflection {
AreaAlt,
AreaCoords,
AreaDownload,
AreaHreflang,
AreaReferrerPolicy,
AreaShape,
AreaType,
BrClear,
DataValue,
EmbedHeight,
@@ -209,11 +211,14 @@ pub(super) enum DomStringReflection {
LinkIntegrity,
LinkMedia,
LinkReferrerPolicy,
LinkRev,
LinkType,
LiType,
MarqueeBgColor,
MarqueeHeight,
MarqueeWidth,
MetaMedia,
MetaScheme,
ModDateTime,
ObjectArchive,
ObjectCode,
@@ -345,6 +350,10 @@ const DOM_STRING_REFLECTION_DESCRIPTORS: &[(DomStringReflection, DomStringReflec
DomStringReflection::AreaDownload,
DomStringReflectionDescriptor::new("HTMLAreaElement", "download", "download"),
),
(
DomStringReflection::AreaHreflang,
DomStringReflectionDescriptor::new("HTMLAreaElement", "hreflang", "hreflang"),
),
(
DomStringReflection::AreaReferrerPolicy,
DomStringReflectionDescriptor::new(
@@ -357,6 +366,10 @@ const DOM_STRING_REFLECTION_DESCRIPTORS: &[(DomStringReflection, DomStringReflec
DomStringReflection::AreaShape,
DomStringReflectionDescriptor::new("HTMLAreaElement", "shape", "shape"),
),
(
DomStringReflection::AreaType,
DomStringReflectionDescriptor::new("HTMLAreaElement", "type", "type"),
),
(
DomStringReflection::BrClear,
DomStringReflectionDescriptor::new_html_element(
@@ -530,6 +543,24 @@ const DOM_STRING_REFLECTION_DESCRIPTORS: &[(DomStringReflection, DomStringReflec
"referrerPolicy",
),
),
(
DomStringReflection::LinkRev,
DomStringReflectionDescriptor::new_html_element(
"HTMLLinkElement",
"link",
"rev",
"rev",
),
),
(
DomStringReflection::LinkType,
DomStringReflectionDescriptor::new_html_element(
"HTMLLinkElement",
"link",
"type",
"type",
),
),
(
DomStringReflection::LiType,
DomStringReflectionDescriptor::new("HTMLLIElement", "type", "type"),
@@ -550,6 +581,15 @@ const DOM_STRING_REFLECTION_DESCRIPTORS: &[(DomStringReflection, DomStringReflec
DomStringReflection::MetaMedia,
DomStringReflectionDescriptor::new("HTMLMetaElement", "media", "media"),
),
(
DomStringReflection::MetaScheme,
DomStringReflectionDescriptor::new_html_element(
"HTMLMetaElement",
"meta",
"scheme",
"scheme",
),
),
(
DomStringReflection::ModDateTime,
DomStringReflectionDescriptor::new("HTMLModElement", "datetime", "dateTime"),
@@ -1460,9 +1460,9 @@ fn hyperlink_metadata_accessors_use_owner_prototypes() {
accessor(HTMLAnchorElement.prototype, "hreflang");
accessor(HTMLAreaElement.prototype, "download");
accessor(HTMLAreaElement.prototype, "ping");
accessor(HTMLAreaElement.prototype, "hreflang");
accessor(HTMLAreaElement.prototype, "type");
accessor(HTMLLinkElement.prototype, "hreflang");
assert(!own(HTMLAreaElement.prototype, "hreflang"), "area hreflang should be removed");
assert(!own(HTMLAreaElement.prototype, "type"), "area type should be removed");
for (const name of ["download", "ping", "hreflang"]) {
assert(!own(HTMLElement.prototype, name), `HTMLElement should not own ${name}`);
}
@@ -1479,15 +1479,11 @@ fn hyperlink_metadata_accessors_use_owner_prototypes() {
);
const cases = [
[document.createElement("a"), parsed.querySelector("a"), ["download", "ping", "hreflang"], "anchor"],
[document.createElement("area"), parsed.querySelector("area"), ["download", "ping"], "area"],
[document.createElement("area"), parsed.querySelector("area"), ["download", "ping", "hreflang", "type"], "area"],
[document.createElement("link"), parsed.querySelector("link"), ["hreflang"], "link"]
];
for (const [live, detached, names, label] of cases) {
for (const element of [live, detached]) {
if (label === "area") {
assert(!("hreflang" in element), "area instance should not expose hreflang");
assert(!("type" in element), "area instance should not expose type");
}
for (const name of names) {
assert(!own(element, name), `${label}.${name} should not be own before set`);
}
@@ -1519,6 +1515,15 @@ fn hyperlink_metadata_accessors_use_owner_prototypes() {
assert(!own(element, "hreflang"), `${label}.hreflang should stay inherited`);
assert(element.hreflang === `${label}-lang`, `${label}.hreflang after delete`);
}
if (names.includes("type")) {
element.type = `${label}/type`;
assert(!own(element, "type"), `${label}.type should not be own after set`);
assert(element.type === `${label}/type`, `${label}.type value`);
assert(element.getAttribute("type") === `${label}/type`, `${label}.type attr`);
assert(delete element.type, `${label}.type delete`);
assert(!own(element, "type"), `${label}.type should stay inherited`);
assert(element.type === `${label}/type`, `${label}.type after delete`);
}
}
}
return "ok";
@@ -1162,7 +1162,7 @@ fn detached_simple_structural_accessors_use_owner_prototypes() {
[HTMLOptGroupElement.prototype, ["disabled"]],
[HTMLDetailsElement.prototype, ["open"]],
[HTMLDialogElement.prototype, ["open", "returnValue"]],
[HTMLMetaElement.prototype, ["content", "httpEquiv"]],
[HTMLMetaElement.prototype, ["content", "httpEquiv", "scheme"]],
[HTMLTitleElement.prototype, ["text"]]
];
for (const [prototype, names] of prototypeCases) {
@@ -1195,6 +1195,7 @@ fn detached_simple_structural_accessors_use_owner_prototypes() {
[dialog, "open", true, "", "open"],
[meta, "content", "width=device-width", "width=device-width", "content"],
[meta, "httpEquiv", "refresh", "refresh", "http-equiv"],
[meta, "scheme", "utf-8", "utf-8", "scheme"],
[title, "text", "Page Title", "Page Title", null]
];
@@ -1274,11 +1275,13 @@ fn detached_simple_specialized_accessors_reject_incompatible_receivers() {
const ol = doc.createElement("ol");
const optgroup = doc.createElement("optgroup");
const details = doc.createElement("details");
const link = doc.createElement("link");
const meta = doc.createElement("meta");
const style = doc.createElement("style");
const title = doc.createElement("title");
const div = doc.createElement("div");
const text = doc.createTextNode("x");
const elements = [li, ol, optgroup, details, meta, title, div];
const elements = [li, ol, optgroup, details, link, meta, style, title, div];
const cases = [
[HTMLLIElement.prototype, "value", li, 7],
@@ -1287,8 +1290,13 @@ fn detached_simple_specialized_accessors_reject_incompatible_receivers() {
[HTMLOListElement.prototype, "type", ol, "A"],
[HTMLOptGroupElement.prototype, "disabled", optgroup, true],
[HTMLDetailsElement.prototype, "open", details, true],
[HTMLLinkElement.prototype, "integrity", link, "sha256-test"],
[HTMLLinkElement.prototype, "rev", link, "made"],
[HTMLLinkElement.prototype, "type", link, "text/css"],
[HTMLMetaElement.prototype, "content", meta, "width=device-width"],
[HTMLMetaElement.prototype, "httpEquiv", meta, "refresh"],
[HTMLMetaElement.prototype, "scheme", meta, "utf-8"],
[HTMLStyleElement.prototype, "type", style, "text/less"],
[HTMLTitleElement.prototype, "text", title, "Page Title"]
];
@@ -918,6 +918,9 @@ fn detached_resource_template_accessors_use_owner_prototypes() {
}
accessor(HTMLLinkElement.prototype, "disabled");
accessor(HTMLIFrameElement.prototype, "csp");
for (const name of ["integrity", "rev", "type"]) {
accessor(HTMLLinkElement.prototype, name);
}
accessor(HTMLIFrameElement.prototype, "sandbox");
accessor(HTMLIFrameElement.prototype, "allowFullscreen");
for (const name of ["default", "kind", "src", "srclang", "label"]) {
@@ -966,17 +969,31 @@ fn detached_resource_template_accessors_use_owner_prototypes() {
}
for (const link of linkElements) {
assert(!own(link, "disabled"), "link.disabled should not be own before set");
for (const name of ["disabled", "integrity", "rev", "type"]) {
assert(!own(link, name), `link.${name} should not be own before set`);
}
assert(link.integrity === "" && link.rev === "" && link.type === "", "link string defaults");
link.integrity = "sha256-test";
link.rev = "made";
link.type = "text/css";
assert(link.integrity === "sha256-test" && link.getAttribute("integrity") === "sha256-test", "link integrity");
assert(link.rev === "made" && link.getAttribute("rev") === "made", "link rev");
assert(link.type === "text/css" && link.getAttribute("type") === "text/css", "link type");
link.disabled = true;
assert(link.disabled === true, "link disabled true");
assert(link.getAttribute("disabled") === "", "link disabled attr");
assert(!own(link, "disabled"), "link.disabled should stay inherited after true");
for (const name of ["disabled", "integrity", "rev", "type"]) {
assert(!own(link, name), `link.${name} should stay inherited after set`);
}
link.disabled = false;
assert(link.disabled === false, "link disabled false");
assert(link.getAttribute("disabled") === null, "link disabled attr removed");
assert(!own(link, "disabled"), "link.disabled should stay inherited after false");
assert(delete link.disabled, "link.disabled delete");
assert(!own(link, "disabled"), "link.disabled should stay inherited after delete");
for (const name of ["disabled", "integrity", "rev", "type"]) {
assert(delete link[name], `link.${name} delete`);
assert(!own(link, name), `link.${name} should stay inherited after delete`);
}
assert(link.integrity === "sha256-test" && link.rev === "made" && link.type === "text/css", "link strings after delete");
}
for (const iframe of iframeElements) {
@@ -2018,11 +2018,11 @@ fn detached_specialized_element_surfaces_are_inherited() {
[id("label"), ["control", "form", "htmlFor"], "label"],
[id("legend"), ["form"], "legend"],
[id("li"), ["value"], "li"],
[id("link"), ["media", "rel", "relList", "target"], "link"],
[id("link"), ["integrity", "media", "rel", "relList", "rev", "target", "type"], "link"],
[id("map"), ["name"], "map"],
[id("marquee"), ["bgColor", "hspace", "vspace"], "marquee"],
[id("menu"), ["compact"], "menu"],
[id("meta"), ["content", "httpEquiv", "media", "name"], "meta"],
[id("meta"), ["content", "httpEquiv", "media", "name", "scheme"], "meta"],
[id("meter"), ["high", "labels", "low", "max", "min", "optimum", "value"], "meter"],
[id("object"), ["archive", "border", "code", "codeBase", "codeType", "contentDocument", "contentWindow", "data", "declare", "form", "hspace", "name", "standby", "type", "useMap", "validity", "validationMessage", "vspace", "willValidate", "checkValidity", "reportValidity", "setCustomValidity"], "object"],
[id("ol"), ["compact", "reversed", "start", "type"], "ol"],