diff --git a/moli-renderer-v8/src/native_bridge/element.rs b/moli-renderer-v8/src/native_bridge/element.rs index f9ac0af2c..bf7322464 100644 --- a/moli-renderer-v8/src/native_bridge/element.rs +++ b/moli-renderer-v8/src/native_bridge/element.rs @@ -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, diff --git a/moli-renderer-v8/src/native_bridge/element/reflection.rs b/moli-renderer-v8/src/native_bridge/element/reflection.rs index fde02a8bc..cf4244b28 100644 --- a/moli-renderer-v8/src/native_bridge/element/reflection.rs +++ b/moli-renderer-v8/src/native_bridge/element/reflection.rs @@ -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"), diff --git a/moli-renderer-v8/src/script_vm/tests/dom_elements/detached/detached_document_and_element_surfaces.rs b/moli-renderer-v8/src/script_vm/tests/dom_elements/detached/detached_document_and_element_surfaces.rs index 83bfc3a51..b20e90961 100644 --- a/moli-renderer-v8/src/script_vm/tests/dom_elements/detached/detached_document_and_element_surfaces.rs +++ b/moli-renderer-v8/src/script_vm/tests/dom_elements/detached/detached_document_and_element_surfaces.rs @@ -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"; diff --git a/moli-renderer-v8/src/script_vm/tests/dom_elements/detached/form_controls_and_legacy_elements.rs b/moli-renderer-v8/src/script_vm/tests/dom_elements/detached/form_controls_and_legacy_elements.rs index 896b49178..66646856e 100644 --- a/moli-renderer-v8/src/script_vm/tests/dom_elements/detached/form_controls_and_legacy_elements.rs +++ b/moli-renderer-v8/src/script_vm/tests/dom_elements/detached/form_controls_and_legacy_elements.rs @@ -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"] ]; diff --git a/moli-renderer-v8/src/script_vm/tests/dom_elements/detached/legacy_resources_and_document_mutations.rs b/moli-renderer-v8/src/script_vm/tests/dom_elements/detached/legacy_resources_and_document_mutations.rs index e42641058..19834d6a8 100644 --- a/moli-renderer-v8/src/script_vm/tests/dom_elements/detached/legacy_resources_and_document_mutations.rs +++ b/moli-renderer-v8/src/script_vm/tests/dom_elements/detached/legacy_resources_and_document_mutations.rs @@ -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) { diff --git a/moli-renderer-v8/src/script_vm/tests/dom_elements/live_document.rs b/moli-renderer-v8/src/script_vm/tests/dom_elements/live_document.rs index c9e476512..659256112 100644 --- a/moli-renderer-v8/src/script_vm/tests/dom_elements/live_document.rs +++ b/moli-renderer-v8/src/script_vm/tests/dom_elements/live_document.rs @@ -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"],