diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 1457eed4318..b0ea79ae4e6 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -6160,8 +6160,9 @@ let global = DomRoot::downcast::(global).unwrap(); cx, &args, &*global, - GetProtoObject, - )""" % self.descriptor.name) + PrototypeList::ID::%s, + CreateInterfaceObjects, + )""" % (self.descriptor.name, MakeNativeName(self.descriptor.name))) else: ctorName = GetConstructorNameForReporting(self.descriptor, self.constructor) preamble += """ diff --git a/components/script/dom/bindings/htmlconstructor.rs b/components/script/dom/bindings/htmlconstructor.rs index 703bfeb7c70..5b6c92727a9 100644 --- a/components/script/dom/bindings/htmlconstructor.rs +++ b/components/script/dom/bindings/htmlconstructor.rs @@ -9,10 +9,10 @@ use html5ever::{local_name, namespace_url, ns, LocalName}; use js::conversions::ToJSValConvertible; use js::glue::{UnwrapObjectDynamic, UnwrapObjectStatic}; use js::jsapi::{CallArgs, CurrentGlobalOrNull, JSAutoRealm, JSObject}; -use js::jsval::UndefinedValue; -use js::rust::wrappers::{JS_GetProperty, JS_SetPrototype, JS_WrapObject}; +use js::rust::wrappers::{JS_SetPrototype, JS_WrapObject}; use js::rust::{HandleObject, MutableHandleObject, MutableHandleValue}; +use super::utils::ProtoOrIfaceArray; use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use crate::dom::bindings::codegen::Bindings::{ HTMLAnchorElementBinding, HTMLAreaElementBinding, HTMLAudioElementBinding, @@ -38,9 +38,11 @@ use crate::dom::bindings::codegen::Bindings::{ HTMLTimeElementBinding, HTMLTitleElementBinding, HTMLTrackElementBinding, HTMLUListElementBinding, HTMLVideoElementBinding, }; +use crate::dom::bindings::codegen::PrototypeList; use crate::dom::bindings::conversions::DerivedFrom; use crate::dom::bindings::error::{throw_dom_exception, Error}; use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::interface::get_desired_proto; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::DomRoot; use crate::dom::create::create_native_html_element; @@ -49,7 +51,7 @@ use crate::dom::element::{Element, ElementCreator}; use crate::dom::globalscope::GlobalScope; use crate::dom::htmlelement::HTMLElement; use crate::dom::window::Window; -use crate::script_runtime::JSContext; +use crate::script_runtime::{JSContext, JSContext as SafeJSContext}; use crate::script_thread::ScriptThread; // https://html.spec.whatwg.org/multipage/#htmlconstructor @@ -58,7 +60,8 @@ unsafe fn html_constructor( window: &Window, call_args: &CallArgs, check_type: fn(&Element) -> bool, - get_proto_object: fn(JSContext, HandleObject, MutableHandleObject), + proto_id: PrototypeList::ID, + creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray), ) -> Result<(), ()> { let document = window.Document(); let global = window.upcast::(); @@ -142,40 +145,7 @@ unsafe fn html_constructor( // Step 6 rooted!(in(*cx) let mut prototype = ptr::null_mut::()); - { - rooted!(in(*cx) let mut proto_val = UndefinedValue()); - let _ac = JSAutoRealm::new(*cx, new_target_unwrapped.get()); - if !JS_GetProperty( - *cx, - new_target_unwrapped.handle(), - b"prototype\0".as_ptr() as *const _, - proto_val.handle_mut(), - ) { - return Err(()); - } - - if !proto_val.is_object() { - // Step 7 of https://html.spec.whatwg.org/multipage/#htmlconstructor. - // This fallback behavior is designed to match analogous behavior for the - // JavaScript built-ins. So we enter the realm of our underlying - // newTarget object and fall back to the prototype object from that global. - // XXX The spec says to use GetFunctionRealm(), which is not actually - // the same thing as what we have here (e.g. in the case of scripted callable proxies - // whose target is not same-realm with the proxy, or bound functions, etc). - // https://bugzilla.mozilla.org/show_bug.cgi?id=1317658 - - rooted!(in(*cx) let global_object = CurrentGlobalOrNull(*cx)); - get_proto_object(cx, global_object.handle(), prototype.handle_mut()); - } else { - // Step 6 - prototype.set(proto_val.to_object()); - } - } - - // Wrap prototype in this context since it is from the newTarget realm - if !JS_WrapObject(*cx, prototype.handle_mut()) { - return Err(()); - } + get_desired_proto(cx, &call_args, proto_id, creator, prototype.handle_mut())?; let entry = definition.construction_stack.borrow().last().cloned(); let result = match entry { @@ -409,7 +379,8 @@ pub(crate) unsafe fn call_html_constructor + DomObject>( cx: JSContext, args: &CallArgs, global: &Window, - get_proto_object: fn(JSContext, HandleObject, MutableHandleObject), + proto_id: PrototypeList::ID, + creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray), ) -> bool { fn element_derives_interface>(element: &Element) -> bool { element.is::() @@ -420,7 +391,8 @@ pub(crate) unsafe fn call_html_constructor + DomObject>( global, args, element_derives_interface::, - get_proto_object, + proto_id, + creator, ) .is_ok() } diff --git a/tests/wpt/meta-legacy-layout/custom-elements/htmlconstructor/newtarget-customized-builtins.html.ini b/tests/wpt/meta-legacy-layout/custom-elements/htmlconstructor/newtarget-customized-builtins.html.ini deleted file mode 100644 index 61d65764ac3..00000000000 --- a/tests/wpt/meta-legacy-layout/custom-elements/htmlconstructor/newtarget-customized-builtins.html.ini +++ /dev/null @@ -1,12 +0,0 @@ -[newtarget-customized-builtins.html] - [If prototype is not object (null), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements)] - expected: FAIL - - [If prototype is not object (undefined), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements)] - expected: FAIL - - [If prototype is not object (5), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements)] - expected: FAIL - - [If prototype is not object (string), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements)] - expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/custom-elements/htmlconstructor/newtarget.html.ini b/tests/wpt/meta-legacy-layout/custom-elements/htmlconstructor/newtarget.html.ini deleted file mode 100644 index 292c32aad7e..00000000000 --- a/tests/wpt/meta-legacy-layout/custom-elements/htmlconstructor/newtarget.html.ini +++ /dev/null @@ -1,28 +0,0 @@ -[newtarget.html] - [Custom Elements: [HTMLConstructor\] derives prototype from NewTarget] - expected: FAIL - - [If prototype is not object (string), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements)] - expected: FAIL - - [If prototype is not object (null), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements)] - expected: FAIL - - [If prototype is not object (undefined), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements)] - expected: FAIL - - [If prototype is not object (undefined), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements)] - expected: FAIL - - [If prototype is not object (5), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements)] - expected: FAIL - - [If prototype is not object (string), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements)] - expected: FAIL - - [If prototype is not object (5), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements)] - expected: FAIL - - [If prototype is not object (null), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements)] - expected: FAIL - diff --git a/tests/wpt/meta/custom-elements/htmlconstructor/newtarget-customized-builtins.html.ini b/tests/wpt/meta/custom-elements/htmlconstructor/newtarget-customized-builtins.html.ini deleted file mode 100644 index 61d65764ac3..00000000000 --- a/tests/wpt/meta/custom-elements/htmlconstructor/newtarget-customized-builtins.html.ini +++ /dev/null @@ -1,12 +0,0 @@ -[newtarget-customized-builtins.html] - [If prototype is not object (null), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements)] - expected: FAIL - - [If prototype is not object (undefined), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements)] - expected: FAIL - - [If prototype is not object (5), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements)] - expected: FAIL - - [If prototype is not object (string), derives the fallback from NewTarget's GetFunctionRealm (customized built-in elements)] - expected: FAIL diff --git a/tests/wpt/meta/custom-elements/htmlconstructor/newtarget.html.ini b/tests/wpt/meta/custom-elements/htmlconstructor/newtarget.html.ini deleted file mode 100644 index bc2e3cf1804..00000000000 --- a/tests/wpt/meta/custom-elements/htmlconstructor/newtarget.html.ini +++ /dev/null @@ -1,12 +0,0 @@ -[newtarget.html] - [If prototype is not object (null), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements)] - expected: FAIL - - [If prototype is not object (undefined), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements)] - expected: FAIL - - [If prototype is not object (5), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements)] - expected: FAIL - - [If prototype is not object (string), derives the fallback from NewTarget's GetFunctionRealm (autonomous custom elements)] - expected: FAIL