mirror of
https://github.com/lexmount/moli.git
synced 2026-10-06 00:00:56 +00:00
fix(html): complete obsolete element reflections
This commit is contained in:
@@ -430,14 +430,15 @@ pub(super) use global_attributes::{
|
||||
html_label_getter_function, html_long_desc_getter_function, html_lowsrc_getter_function,
|
||||
html_margin_height_getter_function, html_margin_width_getter_function,
|
||||
html_media_getter_function, html_name_getter_function, html_name_setter_function,
|
||||
html_no_href_getter_function, html_no_shade_getter_function, html_no_shade_setter_function,
|
||||
html_ping_getter_function, html_rel_getter_function, html_rel_setter_function,
|
||||
html_scrolling_getter_function, html_shape_getter_function, html_size_getter_function,
|
||||
html_sizes_getter_function, html_type_getter_function, html_use_map_getter_function,
|
||||
html_value_getter_function, html_value_type_getter_function, html_version_getter_function,
|
||||
html_vspace_getter_function, html_width_getter_function, image_decoding_setter_function,
|
||||
image_long_desc_setter_function, image_lowsrc_setter_function, link_target_getter_function,
|
||||
link_target_setter_function, node_access_key_getter_function,
|
||||
html_no_href_getter_function, html_no_resize_getter_function, html_no_resize_setter_function,
|
||||
html_no_shade_getter_function, html_no_shade_setter_function, html_ping_getter_function,
|
||||
html_rel_getter_function, html_rel_setter_function, html_scrolling_getter_function,
|
||||
html_shape_getter_function, html_size_getter_function, html_sizes_getter_function,
|
||||
html_true_speed_getter_function, html_true_speed_setter_function, html_type_getter_function,
|
||||
html_use_map_getter_function, html_value_getter_function, html_value_type_getter_function,
|
||||
html_version_getter_function, html_vspace_getter_function, html_width_getter_function,
|
||||
image_decoding_setter_function, image_long_desc_setter_function, image_lowsrc_setter_function,
|
||||
link_target_getter_function, link_target_setter_function, node_access_key_getter_function,
|
||||
node_access_key_label_getter_function, node_access_key_setter_function,
|
||||
node_allow_fullscreen_getter_function, node_allow_fullscreen_setter_function,
|
||||
node_autocapitalize_getter_function, node_autocapitalize_setter_function,
|
||||
@@ -1808,6 +1809,25 @@ struct HtmlBodyElementLegacyPrototypeDeclaration {
|
||||
bg_color: (),
|
||||
}
|
||||
|
||||
#[derive(WebApiFunctionTemplate)]
|
||||
#[webapi(interface = web_api_interfaces::HTMLFrameSetElement, enumerable)]
|
||||
struct HtmlFrameSetElementLegacyPrototypeDeclaration {
|
||||
#[webapi(
|
||||
accessor_property,
|
||||
getter = dom_string_reflection_getter_function,
|
||||
setter = dom_string_reflection_setter_function,
|
||||
data = DomStringReflection::FrameSetCols
|
||||
)]
|
||||
cols: (),
|
||||
#[webapi(
|
||||
accessor_property,
|
||||
getter = dom_string_reflection_getter_function,
|
||||
setter = dom_string_reflection_setter_function,
|
||||
data = DomStringReflection::FrameSetRows
|
||||
)]
|
||||
rows: (),
|
||||
}
|
||||
|
||||
#[derive(WebApiFunctionTemplate)]
|
||||
#[webapi(interface = web_api_interfaces::HTMLHRElement, enumerable)]
|
||||
struct HtmlHrElementLegacyPrototypeDeclaration {
|
||||
@@ -1843,6 +1863,13 @@ struct HtmlHrElementLegacyPrototypeDeclaration {
|
||||
#[derive(WebApiFunctionTemplate)]
|
||||
#[webapi(interface = web_api_interfaces::HTMLFontElement, enumerable)]
|
||||
struct HtmlFontElementLegacyPrototypeDeclaration {
|
||||
#[webapi(
|
||||
accessor_property,
|
||||
getter = dom_string_reflection_getter_function,
|
||||
setter = dom_string_reflection_setter_function,
|
||||
data = DomStringReflection::FontFace
|
||||
)]
|
||||
face: (),
|
||||
#[webapi(
|
||||
accessor_property,
|
||||
getter = html_size_getter_function,
|
||||
@@ -1862,6 +1889,12 @@ struct HtmlFontElementLegacyPrototypeDeclaration {
|
||||
#[derive(WebApiFunctionTemplate)]
|
||||
#[webapi(interface = web_api_interfaces::HTMLMarqueeElement, enumerable)]
|
||||
struct HtmlMarqueeElementLegacyPrototypeDeclaration {
|
||||
#[webapi(
|
||||
accessor_property = "trueSpeed",
|
||||
getter = html_true_speed_getter_function,
|
||||
setter = html_true_speed_setter_function
|
||||
)]
|
||||
true_speed: (),
|
||||
#[webapi(
|
||||
accessor_property = "loop",
|
||||
getter = marquee_loop_getter_function,
|
||||
@@ -3924,6 +3957,12 @@ struct HtmlEmbedElementUrlPrototypeDeclaration {
|
||||
#[derive(WebApiFunctionTemplate)]
|
||||
#[webapi(interface = web_api_interfaces::HTMLFrameElement, enumerable)]
|
||||
struct HtmlFrameElementLegacyPrototypeDeclaration {
|
||||
#[webapi(
|
||||
accessor_property = "noResize",
|
||||
getter = html_no_resize_getter_function,
|
||||
setter = html_no_resize_setter_function
|
||||
)]
|
||||
no_resize: (),
|
||||
#[webapi(
|
||||
accessor_property,
|
||||
getter = generic_src_getter_function,
|
||||
@@ -7120,7 +7159,10 @@ pub(crate) fn install_element_template_bindings<'s>(
|
||||
HtmlBodyElementLegacyPrototypeDeclaration,
|
||||
),
|
||||
"HTMLFrameSetElement" => {
|
||||
install!(HtmlBodyOrFrameSetEventHandlersPrototypeDeclaration)
|
||||
install!(
|
||||
HtmlBodyOrFrameSetEventHandlersPrototypeDeclaration,
|
||||
HtmlFrameSetElementLegacyPrototypeDeclaration,
|
||||
);
|
||||
}
|
||||
"HTMLHRElement" => install!(HtmlHrElementLegacyPrototypeDeclaration),
|
||||
"HTMLFontElement" => install!(HtmlFontElementLegacyPrototypeDeclaration),
|
||||
|
||||
@@ -20,8 +20,8 @@ use super::reflection::{
|
||||
use super::{
|
||||
attribute_property_getter_from_object_or_detached,
|
||||
boolean_attribute_property_getter_from_object_or_detached, element_attribute,
|
||||
form_associated_form_owner, html_element_getter_receiver, html_element_setter_receiver,
|
||||
property_dom_string_value, resolve_url_like_attribute,
|
||||
element_has_attribute, form_associated_form_owner, html_element_getter_receiver,
|
||||
html_element_setter_receiver, property_dom_string_value, resolve_url_like_attribute,
|
||||
set_attribute_property_on_object_or_detached,
|
||||
set_boolean_attribute_property_on_object_or_detached,
|
||||
set_dom_string_attribute_property_on_object, set_reflected_attribute,
|
||||
@@ -1219,6 +1219,117 @@ pub(in crate::native_bridge) fn html_no_shade_setter_function<'s>(
|
||||
rv.set_undefined();
|
||||
}
|
||||
|
||||
fn html_boolean_attribute_getter<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
receiver: v8::Local<'s, v8::Object>,
|
||||
interface: &'static str,
|
||||
member: &'static str,
|
||||
local_name: &'static str,
|
||||
attribute: &'static str,
|
||||
mut rv: v8::ReturnValue<'s, v8::Value>,
|
||||
) {
|
||||
let Some((runtime_ptr, handle)) =
|
||||
html_element_getter_receiver(scope, receiver, interface, member, local_name)
|
||||
else {
|
||||
rv.set_bool(false);
|
||||
return;
|
||||
};
|
||||
rv.set_bool(element_has_attribute(
|
||||
unsafe { &*runtime_ptr },
|
||||
handle,
|
||||
attribute,
|
||||
));
|
||||
}
|
||||
|
||||
fn html_boolean_attribute_setter<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
receiver: v8::Local<'s, v8::Object>,
|
||||
value: v8::Local<'s, v8::Value>,
|
||||
interface: &'static str,
|
||||
member: &'static str,
|
||||
local_name: &'static str,
|
||||
attribute: &'static str,
|
||||
) {
|
||||
let Some((runtime_ptr, handle)) =
|
||||
html_element_setter_receiver(scope, receiver, interface, member, local_name)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
set_reflected_boolean_attribute(
|
||||
scope,
|
||||
runtime_ptr,
|
||||
handle,
|
||||
attribute,
|
||||
value.boolean_value(scope),
|
||||
);
|
||||
}
|
||||
|
||||
pub(in crate::native_bridge) fn html_no_resize_getter_function<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
args: v8::FunctionCallbackArguments<'s>,
|
||||
rv: v8::ReturnValue<'s, v8::Value>,
|
||||
) {
|
||||
html_boolean_attribute_getter(
|
||||
scope,
|
||||
args.this(),
|
||||
"HTMLFrameElement",
|
||||
"noResize",
|
||||
"frame",
|
||||
"noresize",
|
||||
rv,
|
||||
);
|
||||
}
|
||||
|
||||
pub(in crate::native_bridge) fn html_no_resize_setter_function<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
args: v8::FunctionCallbackArguments<'s>,
|
||||
mut rv: v8::ReturnValue<'_, v8::Value>,
|
||||
) {
|
||||
html_boolean_attribute_setter(
|
||||
scope,
|
||||
args.this(),
|
||||
args.get(0),
|
||||
"HTMLFrameElement",
|
||||
"noResize",
|
||||
"frame",
|
||||
"noresize",
|
||||
);
|
||||
rv.set_undefined();
|
||||
}
|
||||
|
||||
pub(in crate::native_bridge) fn html_true_speed_getter_function<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
args: v8::FunctionCallbackArguments<'s>,
|
||||
rv: v8::ReturnValue<'s, v8::Value>,
|
||||
) {
|
||||
html_boolean_attribute_getter(
|
||||
scope,
|
||||
args.this(),
|
||||
"HTMLMarqueeElement",
|
||||
"trueSpeed",
|
||||
"marquee",
|
||||
"truespeed",
|
||||
rv,
|
||||
);
|
||||
}
|
||||
|
||||
pub(in crate::native_bridge) fn html_true_speed_setter_function<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
args: v8::FunctionCallbackArguments<'s>,
|
||||
mut rv: v8::ReturnValue<'_, v8::Value>,
|
||||
) {
|
||||
html_boolean_attribute_setter(
|
||||
scope,
|
||||
args.this(),
|
||||
args.get(0),
|
||||
"HTMLMarqueeElement",
|
||||
"trueSpeed",
|
||||
"marquee",
|
||||
"truespeed",
|
||||
);
|
||||
rv.set_undefined();
|
||||
}
|
||||
|
||||
pub(in crate::native_bridge) fn node_allow_fullscreen_getter_function<'s>(
|
||||
scope: &mut v8::PinScope<'s, '_>,
|
||||
args: v8::FunctionCallbackArguments<'s>,
|
||||
|
||||
@@ -180,9 +180,12 @@ pub(super) enum DomStringReflection {
|
||||
EmbedHeight,
|
||||
EmbedType,
|
||||
EmbedWidth,
|
||||
FontFace,
|
||||
FontSize,
|
||||
FrameFrameBorder,
|
||||
FrameScrolling,
|
||||
FrameSetCols,
|
||||
FrameSetRows,
|
||||
HrColor,
|
||||
HrSize,
|
||||
HrWidth,
|
||||
@@ -382,6 +385,15 @@ const DOM_STRING_REFLECTION_DESCRIPTORS: &[(DomStringReflection, DomStringReflec
|
||||
DomStringReflection::EmbedWidth,
|
||||
DomStringReflectionDescriptor::new("HTMLEmbedElement", "width", "width"),
|
||||
),
|
||||
(
|
||||
DomStringReflection::FontFace,
|
||||
DomStringReflectionDescriptor::new_html_element(
|
||||
"HTMLFontElement",
|
||||
"font",
|
||||
"face",
|
||||
"face",
|
||||
),
|
||||
),
|
||||
(
|
||||
DomStringReflection::FontSize,
|
||||
DomStringReflectionDescriptor::new("HTMLFontElement", "size", "size"),
|
||||
@@ -394,6 +406,24 @@ const DOM_STRING_REFLECTION_DESCRIPTORS: &[(DomStringReflection, DomStringReflec
|
||||
DomStringReflection::FrameScrolling,
|
||||
DomStringReflectionDescriptor::new("HTMLFrameElement", "scrolling", "scrolling"),
|
||||
),
|
||||
(
|
||||
DomStringReflection::FrameSetCols,
|
||||
DomStringReflectionDescriptor::new_html_element(
|
||||
"HTMLFrameSetElement",
|
||||
"frameset",
|
||||
"cols",
|
||||
"cols",
|
||||
),
|
||||
),
|
||||
(
|
||||
DomStringReflection::FrameSetRows,
|
||||
DomStringReflectionDescriptor::new_html_element(
|
||||
"HTMLFrameSetElement",
|
||||
"frameset",
|
||||
"rows",
|
||||
"rows",
|
||||
),
|
||||
),
|
||||
(
|
||||
DomStringReflection::HrColor,
|
||||
DomStringReflectionDescriptor::new("HTMLHRElement", "color", "color"),
|
||||
|
||||
+82
@@ -1398,6 +1398,88 @@ fn detached_frame_legacy_accessors_use_owner_prototypes() {
|
||||
assert_eq!(result, "ok");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detached_obsolete_element_reflectors_use_owner_prototypes() {
|
||||
let mut vm = new_storage_test_vm("https://detached-obsolete-reflectors.test/");
|
||||
|
||||
let result = vm
|
||||
.eval(
|
||||
r#"
|
||||
(() => {
|
||||
const doc = document.implementation.createHTMLDocument("");
|
||||
const frameset = doc.createElement("frameset");
|
||||
const frame = doc.createElement("frame");
|
||||
const font = doc.createElement("font");
|
||||
const marquee = doc.createElement("marquee");
|
||||
const div = doc.createElement("div");
|
||||
|
||||
const assert = (condition, message) => {
|
||||
if (!condition) throw new Error(message);
|
||||
};
|
||||
const own = (object, name) => Object.prototype.hasOwnProperty.call(object, name);
|
||||
const throwsTypeError = callback => {
|
||||
try {
|
||||
callback();
|
||||
return false;
|
||||
} catch (error) {
|
||||
return error.name === "TypeError";
|
||||
}
|
||||
};
|
||||
const cases = [
|
||||
[HTMLFrameSetElement.prototype, frameset, "cols", "40%,60%", "cols"],
|
||||
[HTMLFrameSetElement.prototype, frameset, "rows", "100,*", "rows"],
|
||||
[HTMLFontElement.prototype, font, "face", "serif, sans-serif", "face"],
|
||||
];
|
||||
|
||||
for (const [prototype, element, name, value, attribute] of cases) {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(prototype, name);
|
||||
assert(!!descriptor, `${name} descriptor`);
|
||||
assert(typeof descriptor.get === "function", `${name} getter`);
|
||||
assert(typeof descriptor.set === "function", `${name} setter`);
|
||||
assert(descriptor.enumerable && descriptor.configurable, `${name} descriptor flags`);
|
||||
assert(!own(HTMLElement.prototype, name), `${name} owner`);
|
||||
assert(!(name in div), `${name} should not be on div`);
|
||||
assert(throwsTypeError(() => descriptor.get.call(div)), `${name} getter brand`);
|
||||
assert(throwsTypeError(() => descriptor.set.call(div, value)), `${name} setter brand`);
|
||||
assert(element[name] === "", `${name} default`);
|
||||
element[name] = value;
|
||||
assert(element[name] === value, `${name} value`);
|
||||
assert(element.getAttribute(attribute) === value, `${name} attribute`);
|
||||
assert(!own(element, name), `${name} should stay inherited`);
|
||||
}
|
||||
|
||||
for (const [prototype, element, name, attribute] of [
|
||||
[HTMLFrameElement.prototype, frame, "noResize", "noresize"],
|
||||
[HTMLMarqueeElement.prototype, marquee, "trueSpeed", "truespeed"],
|
||||
]) {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(prototype, name);
|
||||
assert(!!descriptor, `${name} descriptor`);
|
||||
assert(typeof descriptor.get === "function", `${name} getter`);
|
||||
assert(typeof descriptor.set === "function", `${name} setter`);
|
||||
assert(descriptor.enumerable && descriptor.configurable, `${name} descriptor flags`);
|
||||
assert(!own(HTMLElement.prototype, name), `${name} owner`);
|
||||
assert(!(name in div), `${name} should not be on div`);
|
||||
assert(throwsTypeError(() => descriptor.get.call(div)), `${name} getter brand`);
|
||||
assert(throwsTypeError(() => descriptor.set.call(div, true)), `${name} setter brand`);
|
||||
assert(element[name] === false, `${name} default`);
|
||||
element.setAttribute(attribute, "false");
|
||||
assert(element[name] === true, `${name} attribute presence`);
|
||||
element[name] = false;
|
||||
assert(!element.hasAttribute(attribute), `${name} false removes attribute`);
|
||||
element[name] = true;
|
||||
assert(element.getAttribute(attribute) === "", `${name} true adds attribute`);
|
||||
assert(!own(element, name), `${name} should stay inherited`);
|
||||
}
|
||||
|
||||
return "ok";
|
||||
})()
|
||||
"#,
|
||||
)
|
||||
.expect("detached obsolete element reflectors should evaluate");
|
||||
|
||||
assert_eq!(result, "ok");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detached_resource_legacy_accessors_use_owner_prototypes() {
|
||||
let mut vm =
|
||||
|
||||
Reference in New Issue
Block a user