diff --git a/moli-renderer-v8/src/context_bootstrap.rs b/moli-renderer-v8/src/context_bootstrap.rs index c758896d59..52d4261724 100644 --- a/moli-renderer-v8/src/context_bootstrap.rs +++ b/moli-renderer-v8/src/context_bootstrap.rs @@ -55,6 +55,7 @@ pub(crate) use exposed_interfaces::{ ready_interface_template_names as lazy_ready_constructor_template_names, storage_interface_materialization_count as lazy_storage_constructor_materialization_count, }; +pub(crate) use indexed_db::dispatch_indexed_db_event_callback; mod location_history_storage; mod location_navigation; mod location_runtime; @@ -347,14 +348,12 @@ pub(crate) use self::media_queries::{ dispatch_media_query_list_change_events, dispatch_simple_event_target_event, dispatch_simple_event_target_event_collecting_errors, evaluate_match_media_query_list_with_viewport, initialize_simple_event_target, - install_simple_event_target_handlers, install_simple_event_target_methods, - invoke_simple_event_listener, is_simple_event_target, + install_simple_event_target_handlers, invoke_simple_event_listener, is_simple_event_target, simple_event_target_add_event_listener_callback, simple_event_target_dispatch_event_callback, simple_event_target_handler_getter_callback, simple_event_target_handler_setter_callback, simple_event_target_inspector_listener_snapshots, simple_event_target_remove_event_listener_callback, simple_object_event_listeners_snapshot, - simple_object_event_set_handler, simple_object_event_target_add_listener, - simple_object_event_target_remove_listener, simple_object_has_event_listeners, + simple_object_event_set_handler, simple_object_has_event_listeners, }; pub(crate) use self::message_ports::{ MessagePortDeliveryRunResult, MessagePortRealmBinding, detach_message_port_owner_for_transfer, diff --git a/moli-renderer-v8/src/context_bootstrap/broadcast_channel.rs b/moli-renderer-v8/src/context_bootstrap/broadcast_channel.rs index 896f6642e9..f0d8104ab7 100644 --- a/moli-renderer-v8/src/context_bootstrap/broadcast_channel.rs +++ b/moli-renderer-v8/src/context_bootstrap/broadcast_channel.rs @@ -45,27 +45,6 @@ struct BroadcastChannelObjectDeclaration<'scope> { #[webapi(slot = SIMPLE_EVENT_TARGET_LISTENERS_SLOT, init = "null_object")] event_listeners: (), - - #[webapi( - method, - enumerable, - callback = simple_event_target_add_event_listener_callback - )] - add_event_listener: (), - - #[webapi( - method, - enumerable, - callback = simple_event_target_remove_event_listener_callback - )] - remove_event_listener: (), - - #[webapi( - method, - enumerable, - callback = simple_event_target_dispatch_event_callback - )] - dispatch_event: (), } #[derive(WebApiFunctionTemplate)] diff --git a/moli-renderer-v8/src/context_bootstrap/exposed_interfaces/metadata.rs b/moli-renderer-v8/src/context_bootstrap/exposed_interfaces/metadata.rs index 4d97431efb..0e08df84da 100644 --- a/moli-renderer-v8/src/context_bootstrap/exposed_interfaces/metadata.rs +++ b/moli-renderer-v8/src/context_bootstrap/exposed_interfaces/metadata.rs @@ -19,6 +19,10 @@ pub(in crate::context_bootstrap) const STORAGE_INTERFACE_NAMES: &[&str] = &[ ]; pub(in crate::context_bootstrap) const WORKER_SHARED_INTERFACE_NAMES: &[&str] = &[ + "NetworkInformation", + "ServiceWorkerContainer", + "ServiceWorkerRegistration", + "ServiceWorker", "DOMRectReadOnly", "DOMRect", "DOMPointReadOnly", @@ -117,6 +121,10 @@ pub(in crate::context_bootstrap) const WORKER_SHARED_INTERFACE_NAMES: &[&str] = ]; const SECURE_CONTEXT_ONLY_INTERFACE_NAMES: &[&str] = &[ + "BatteryManager", + "ServiceWorkerContainer", + "ServiceWorkerRegistration", + "ServiceWorker", "PaymentRequestUpdateEvent", "PaymentMethodChangeEvent", "AuthenticatorAssertionResponse", diff --git a/moli-renderer-v8/src/context_bootstrap/indexed_db/event_target.rs b/moli-renderer-v8/src/context_bootstrap/indexed_db/event_target.rs index ed186083cc..93e22ba032 100644 --- a/moli-renderer-v8/src/context_bootstrap/indexed_db/event_target.rs +++ b/moli-renderer-v8/src/context_bootstrap/indexed_db/event_target.rs @@ -5,5 +5,5 @@ mod target; mod version_change; pub(super) use self::dispatch::*; -pub(super) use self::target::*; +pub(crate) use self::target::dispatch_indexed_db_event_callback; pub(in crate::context_bootstrap) use self::version_change::*; diff --git a/moli-renderer-v8/src/context_bootstrap/indexed_db/event_target/target.rs b/moli-renderer-v8/src/context_bootstrap/indexed_db/event_target/target.rs index c7909bda56..6cf78f211a 100644 --- a/moli-renderer-v8/src/context_bootstrap/indexed_db/event_target/target.rs +++ b/moli-renderer-v8/src/context_bootstrap/indexed_db/event_target/target.rs @@ -1,33 +1,6 @@ use super::*; -use crate::context_bootstrap::{ - simple_object_event_target_add_listener, simple_object_event_target_remove_listener, -}; -pub(in crate::context_bootstrap::indexed_db) fn idb_event_target_add_event_listener_callback<'s>( - scope: &mut v8::PinScope<'s, '_>, - args: v8::FunctionCallbackArguments<'s>, - _rv: v8::ReturnValue<'_, v8::Value>, -) { - if !require_idb_event_target(scope, args.this()) { - return; - } - simple_object_event_target_add_listener(scope, &args); -} - -pub(in crate::context_bootstrap::indexed_db) fn idb_event_target_remove_event_listener_callback< - 's, ->( - scope: &mut v8::PinScope<'s, '_>, - args: v8::FunctionCallbackArguments<'s>, - _rv: v8::ReturnValue<'_, v8::Value>, -) { - if !require_idb_event_target(scope, args.this()) { - return; - } - simple_object_event_target_remove_listener(scope, &args); -} - -pub(in crate::context_bootstrap::indexed_db) fn idb_event_target_dispatch_event_callback<'s>( +pub(crate) fn dispatch_indexed_db_event_callback<'s>( scope: &mut v8::PinScope<'s, '_>, args: v8::FunctionCallbackArguments<'s>, mut rv: v8::ReturnValue<'s, v8::Value>, diff --git a/moli-renderer-v8/src/context_bootstrap/indexed_db/install.rs b/moli-renderer-v8/src/context_bootstrap/indexed_db/install.rs index 79f2ad02cb..95fa0b81f1 100644 --- a/moli-renderer-v8/src/context_bootstrap/indexed_db/install.rs +++ b/moli-renderer-v8/src/context_bootstrap/indexed_db/install.rs @@ -3,10 +3,8 @@ use super::{ idb_cursor_continue_primary_key_callback, idb_cursor_delete_callback, idb_cursor_update_callback, idb_database_close_callback, idb_database_create_object_store_callback, idb_database_delete_object_store_callback, - idb_database_transaction_callback, idb_event_target_add_event_listener_callback, - idb_event_target_dispatch_event_callback, idb_event_target_remove_event_listener_callback, - idb_factory_cmp_callback, idb_factory_databases_callback, idb_factory_delete_database_callback, - idb_factory_open_callback, + idb_database_transaction_callback, idb_factory_cmp_callback, idb_factory_databases_callback, + idb_factory_delete_database_callback, idb_factory_open_callback, idb_index_count_callback as idb_index_count_callback_in_current_context, idb_index_get_all_callback as idb_index_get_all_callback_in_current_context, idb_index_get_all_keys_callback as idb_index_get_all_keys_callback_in_current_context, @@ -144,10 +142,8 @@ indexed_db_receiver_realm_callback!( ); mod constructors; -mod helpers; mod state; pub(in crate::context_bootstrap) use self::constructors::install_indexed_db_template_bindings; -use self::helpers::*; pub(in crate::context_bootstrap) use self::state::ensure_indexed_db_runtime_state; pub(crate) use self::state::{install_worker_indexed_db_runtime_state, window_indexed_db_getter}; diff --git a/moli-renderer-v8/src/context_bootstrap/indexed_db/install/constructors/database_transaction.rs b/moli-renderer-v8/src/context_bootstrap/indexed_db/install/constructors/database_transaction.rs index a8fdffc3ae..d98bac4baa 100644 --- a/moli-renderer-v8/src/context_bootstrap/indexed_db/install/constructors/database_transaction.rs +++ b/moli-renderer-v8/src/context_bootstrap/indexed_db/install/constructors/database_transaction.rs @@ -33,11 +33,9 @@ pub(super) fn install_database_and_transaction_template_bindings<'s>( ) { match interface_name { "IDBDatabase" => { - install_idb_event_target_methods(scope, prototype); IdbDatabasePrototypeDeclaration::initialize_prototype_template(scope, prototype); } "IDBTransaction" => { - install_idb_event_target_methods(scope, prototype); IdbTransactionPrototypeDeclaration::initialize_prototype_template(scope, prototype); } _ => {} diff --git a/moli-renderer-v8/src/context_bootstrap/indexed_db/install/constructors/factory_request.rs b/moli-renderer-v8/src/context_bootstrap/indexed_db/install/constructors/factory_request.rs index 3d45eea60d..724a5fe5a7 100644 --- a/moli-renderer-v8/src/context_bootstrap/indexed_db/install/constructors/factory_request.rs +++ b/moli-renderer-v8/src/context_bootstrap/indexed_db/install/constructors/factory_request.rs @@ -20,11 +20,7 @@ pub(super) fn install_factory_and_request_template_bindings<'s>( prototype: v8::Local<'s, v8::ObjectTemplate>, interface_name: &str, ) { - match interface_name { - "IDBFactory" => { - IdbFactoryPrototypeDeclaration::initialize_prototype_template(scope, prototype); - } - "IDBRequest" => install_idb_event_target_methods(scope, prototype), - _ => {} + if interface_name == "IDBFactory" { + IdbFactoryPrototypeDeclaration::initialize_prototype_template(scope, prototype); } } diff --git a/moli-renderer-v8/src/context_bootstrap/indexed_db/install/helpers.rs b/moli-renderer-v8/src/context_bootstrap/indexed_db/install/helpers.rs deleted file mode 100644 index bd69f960de..0000000000 --- a/moli-renderer-v8/src/context_bootstrap/indexed_db/install/helpers.rs +++ /dev/null @@ -1,24 +0,0 @@ -use super::*; -use moli_webapi_declare::WebApiFunctionTemplate; - -#[derive(WebApiFunctionTemplate)] -#[webapi(name = "IDBEventTarget", enumerable)] -struct IdbEventTargetPrototypeDeclaration { - #[webapi(method, length = 2, callback = idb_event_target_add_event_listener_callback)] - add_event_listener: (), - #[webapi( - method, - length = 2, - callback = idb_event_target_remove_event_listener_callback - )] - remove_event_listener: (), - #[webapi(method, length = 1, callback = idb_event_target_dispatch_event_callback)] - dispatch_event: (), -} - -pub(super) fn install_idb_event_target_methods<'s>( - scope: &mut v8::PinScope<'s, '_, ()>, - prototype: v8::Local<'s, v8::ObjectTemplate>, -) { - IdbEventTargetPrototypeDeclaration::initialize_prototype_template(scope, prototype); -} diff --git a/moli-renderer-v8/src/context_bootstrap/indexed_db/mod.rs b/moli-renderer-v8/src/context_bootstrap/indexed_db/mod.rs index 0a4fbb154b..2b7cc2b3e3 100644 --- a/moli-renderer-v8/src/context_bootstrap/indexed_db/mod.rs +++ b/moli-renderer-v8/src/context_bootstrap/indexed_db/mod.rs @@ -28,6 +28,7 @@ use self::backend::*; use self::core::*; use self::cursor::*; use self::database::*; +pub(crate) use self::event_target::dispatch_indexed_db_event_callback; use self::event_target::*; use self::operation_state::*; use self::runtime::*; diff --git a/moli-renderer-v8/src/context_bootstrap/media_queries.rs b/moli-renderer-v8/src/context_bootstrap/media_queries.rs index 73ac3159fe..74ce774843 100644 --- a/moli-renderer-v8/src/context_bootstrap/media_queries.rs +++ b/moli-renderer-v8/src/context_bootstrap/media_queries.rs @@ -13,13 +13,12 @@ pub(crate) use self::events::{ SimpleObjectEventListenerInspectorSnapshot, SimpleObjectEventListenerSnapshot, dispatch_simple_event_target_event, dispatch_simple_event_target_event_collecting_errors, initialize_simple_event_target, install_simple_event_target_handlers, - install_simple_event_target_methods, invoke_simple_event_listener, is_simple_event_target, + invoke_simple_event_listener, is_simple_event_target, simple_event_target_add_event_listener_callback, simple_event_target_dispatch_event_callback, simple_event_target_handler_getter_callback, simple_event_target_handler_setter_callback, simple_event_target_inspector_listener_snapshots, simple_event_target_remove_event_listener_callback, simple_object_event_listeners_snapshot, - simple_object_event_set_handler, simple_object_event_target_add_listener, - simple_object_event_target_remove_listener, simple_object_has_event_listeners, + simple_object_event_set_handler, simple_object_has_event_listeners, }; pub(super) use self::events::{ media_query_list_add_listener_callback, media_query_list_remove_listener_callback, diff --git a/moli-renderer-v8/src/context_bootstrap/media_queries/events.rs b/moli-renderer-v8/src/context_bootstrap/media_queries/events.rs index d128e11300..e3a873da06 100644 --- a/moli-renderer-v8/src/context_bootstrap/media_queries/events.rs +++ b/moli-renderer-v8/src/context_bootstrap/media_queries/events.rs @@ -15,12 +15,11 @@ pub(crate) use simple_event_target::{ SimpleObjectEventListenerInspectorSnapshot, SimpleObjectEventListenerSnapshot, dispatch_simple_event_target_event, dispatch_simple_event_target_event_collecting_errors, initialize_simple_event_target, install_simple_event_target_handlers, - install_simple_event_target_methods, invoke_simple_event_listener, is_simple_event_target, + invoke_simple_event_listener, is_simple_event_target, simple_event_target_add_event_listener_callback, simple_event_target_dispatch_event_callback, simple_event_target_handler_getter_callback, simple_event_target_handler_setter_callback, simple_event_target_inspector_listener_snapshots, simple_event_target_remove_event_listener_callback, simple_object_event_listeners_snapshot, simple_object_event_remove_listener_value_for_type, simple_object_event_set_handler, - simple_object_event_target_add_listener, simple_object_event_target_register_webidl_listener, - simple_object_event_target_remove_listener, simple_object_has_event_listeners, + simple_object_event_target_register_webidl_listener, simple_object_has_event_listeners, }; diff --git a/moli-renderer-v8/src/context_bootstrap/media_queries/events/simple_event_target.rs b/moli-renderer-v8/src/context_bootstrap/media_queries/events/simple_event_target.rs index cca3b4d8e1..1e91315c0e 100644 --- a/moli-renderer-v8/src/context_bootstrap/media_queries/events/simple_event_target.rs +++ b/moli-renderer-v8/src/context_bootstrap/media_queries/events/simple_event_target.rs @@ -3,7 +3,6 @@ use super::*; mod callbacks; mod dispatch; mod handlers; -mod install; mod listeners; mod state; @@ -20,7 +19,7 @@ pub(crate) use handlers::{ install_simple_event_target_handlers, simple_event_target_handler_getter_callback, simple_event_target_handler_setter_callback, }; -pub(crate) use install::install_simple_event_target_methods; +pub(crate) use listeners::simple_object_event_target_register_webidl_listener; pub(crate) use listeners::{ SimpleObjectEventListenerInspectorSnapshot, SimpleObjectEventListenerSnapshot, simple_event_target_inspector_listener_snapshots, simple_object_event_listeners_snapshot, @@ -33,10 +32,6 @@ use listeners::{ simple_object_event_target_add_listener_for_target, simple_object_event_target_remove_listener_for_target, }; -pub(crate) use listeners::{ - simple_object_event_target_add_listener, simple_object_event_target_register_webidl_listener, - simple_object_event_target_remove_listener, -}; use state::{ ResolvedSimpleEventTarget, SimpleEventListenerRegistry, resolve_simple_event_target, simple_object_event_listener_registry, diff --git a/moli-renderer-v8/src/context_bootstrap/media_queries/events/simple_event_target/install.rs b/moli-renderer-v8/src/context_bootstrap/media_queries/events/simple_event_target/install.rs deleted file mode 100644 index 784fc688b4..0000000000 --- a/moli-renderer-v8/src/context_bootstrap/media_queries/events/simple_event_target/install.rs +++ /dev/null @@ -1,33 +0,0 @@ -use super::*; -use crate::web_api_interfaces; -use moli_webapi_declare::WebApiObject; - -#[derive(WebApiObject)] -#[webapi( - interface = web_api_interfaces::EventTarget, - prototype = "Object", - enumerable, - receiver -)] -struct SimpleEventTargetMethodsDeclaration { - #[webapi(method, length = 2, callback = simple_event_target_add_event_listener_callback)] - add_event_listener: (), - #[webapi( - method, - length = 2, - callback = simple_event_target_remove_event_listener_callback - )] - remove_event_listener: (), - #[webapi(method, length = 1, callback = simple_event_target_dispatch_event_callback)] - dispatch_event: (), -} - -pub(crate) fn install_simple_event_target_methods<'s>( - scope: &mut v8::PinScope<'s, '_>, - target: v8::Local<'s, v8::Object>, -) { - initialize_simple_event_target(scope, target); - SimpleEventTargetMethodsDeclaration::new() - .initialize(scope, target) - .expect("simple event target declaration should initialize"); -} diff --git a/moli-renderer-v8/src/context_bootstrap/media_queries/events/simple_event_target/listeners.rs b/moli-renderer-v8/src/context_bootstrap/media_queries/events/simple_event_target/listeners.rs index d4a1b75a74..4145c0e951 100644 --- a/moli-renderer-v8/src/context_bootstrap/media_queries/events/simple_event_target/listeners.rs +++ b/moli-renderer-v8/src/context_bootstrap/media_queries/events/simple_event_target/listeners.rs @@ -186,13 +186,6 @@ impl<'s> SimpleObjectEventListenerSnapshot<'s> { } } -pub(crate) fn simple_object_event_target_add_listener<'s>( - scope: &mut v8::PinScope<'s, '_>, - args: &v8::FunctionCallbackArguments<'s>, -) { - simple_object_event_target_add_listener_for_target(scope, args, args.this(), None); -} - pub(super) fn simple_object_event_target_add_listener_for_target<'s>( scope: &mut v8::PinScope<'s, '_>, args: &v8::FunctionCallbackArguments<'s>, @@ -309,13 +302,6 @@ fn simple_object_event_target_register_resolved_listener<'s>( } } -pub(crate) fn simple_object_event_target_remove_listener<'s>( - scope: &mut v8::PinScope<'s, '_>, - args: &v8::FunctionCallbackArguments<'s>, -) { - simple_object_event_target_remove_listener_for_target(scope, args, args.this(), None); -} - pub(super) fn simple_object_event_target_remove_listener_for_target<'s>( scope: &mut v8::PinScope<'s, '_>, args: &v8::FunctionCallbackArguments<'s>, diff --git a/moli-renderer-v8/src/context_bootstrap/navigation_entry/wrappers.rs b/moli-renderer-v8/src/context_bootstrap/navigation_entry/wrappers.rs index dae5085722..bd18b11cab 100644 --- a/moli-renderer-v8/src/context_bootstrap/navigation_entry/wrappers.rs +++ b/moli-renderer-v8/src/context_bootstrap/navigation_entry/wrappers.rs @@ -119,7 +119,7 @@ fn allocate_in_current_realm<'s>( .bind(scope) .expect("NavigationHistoryEntry declaration should bind"); native::bind_entry(scope, wrapper, record); - media_queries::install_simple_event_target_methods(scope, wrapper); + media_queries::initialize_simple_event_target(scope, wrapper); shared_event_targets::install_handlers(scope, wrapper, true); set_runtime_window_owner(scope, wrapper, owner); wrapper diff --git a/moli-renderer-v8/src/context_bootstrap/navigation_surface/runtime.rs b/moli-renderer-v8/src/context_bootstrap/navigation_surface/runtime.rs index 692749c4a7..f9f69ce6e8 100644 --- a/moli-renderer-v8/src/context_bootstrap/navigation_surface/runtime.rs +++ b/moli-renderer-v8/src/context_bootstrap/navigation_surface/runtime.rs @@ -84,7 +84,7 @@ pub(in crate::context_bootstrap) fn build_navigation_runtime_state<'s>( let navigation = NavigationRuntimeObjectDeclaration::new(current_entry) .bind(scope) .map_err(anyhow::Error::from)?; - super::media_queries::install_simple_event_target_methods(scope, navigation); + super::media_queries::initialize_simple_event_target(scope, navigation); super::super::shared_event_targets::install_handlers(scope, navigation, false); let owner = history_window_owner(scope, window); if window_has_shared_history(scope, window) diff --git a/moli-renderer-v8/src/context_bootstrap/navigator_runtime/navigator.rs b/moli-renderer-v8/src/context_bootstrap/navigator_runtime/navigator.rs index 6cf96b52b6..661555f76a 100644 --- a/moli-renderer-v8/src/context_bootstrap/navigator_runtime/navigator.rs +++ b/moli-renderer-v8/src/context_bootstrap/navigator_runtime/navigator.rs @@ -290,7 +290,6 @@ struct PermissionStatusPrototypeDeclaration { #[derive(Default, WebApiObject)] #[webapi( interface = web_api_interfaces::NetworkInformation, - prototype = "Object", receiver )] struct NavigatorConnectionDeclaration { @@ -312,24 +311,11 @@ struct NavigatorConnectionDeclaration { #[webapi(accessor_property, getter = navigator_connection_save_data_getter_callback, enumerable)] save_data: (), - #[webapi(data_property, enumerable, init = "null")] + #[webapi(accessor_property, enumerable, getter = simple_event_target_handler_getter_callback, setter = simple_event_target_handler_setter_callback, data = v8str(scope, "onchange"), setter_data = v8str(scope, "onchange"))] onchange: (), - #[webapi( - method, - enumerable, - length = 2, - callback = navigator_connection_event_target_noop_callback - )] - add_event_listener: (), - - #[webapi( - method, - enumerable, - length = 2, - callback = navigator_connection_event_target_noop_callback - )] - remove_event_listener: (), + #[webapi(slot = SIMPLE_EVENT_TARGET_LISTENERS_SLOT, init = "null_object")] + event_listeners: (), } #[derive(WebApiObject)] @@ -401,7 +387,7 @@ struct NavigatorUaDataPrototypeMethodsDeclaration { } #[derive(Default, WebApiObject)] -#[webapi(interface = web_api_interfaces::ServiceWorkerContainer, prototype = "Object")] +#[webapi(interface = web_api_interfaces::ServiceWorkerContainer)] struct ServiceWorkerContainerDeclaration { #[webapi(slot = SIMPLE_EVENT_TARGET_LISTENERS_SLOT, init = "null_object")] event_listeners: (), @@ -451,15 +437,6 @@ struct ServiceWorkerContainerDeclaration { )] get_registrations: (), - #[webapi(method, enumerable, callback = simple_event_target_add_event_listener_callback)] - add_event_listener: (), - - #[webapi(method, enumerable, callback = simple_event_target_remove_event_listener_callback)] - remove_event_listener: (), - - #[webapi(method, enumerable, callback = simple_event_target_dispatch_event_callback)] - dispatch_event: (), - #[webapi( accessor_property, enumerable, @@ -807,13 +784,6 @@ fn navigator_connection_save_data_getter_callback<'s>( ); } -fn navigator_connection_event_target_noop_callback<'s>( - _scope: &mut v8::PinScope<'s, '_>, - _args: v8::FunctionCallbackArguments<'s>, - _rv: v8::ReturnValue<'_, v8::Value>, -) { -} - fn navigator_get_autoplay_policy_callback<'s>( scope: &mut v8::PinScope<'s, '_>, args: v8::FunctionCallbackArguments<'s>, diff --git a/moli-renderer-v8/src/context_bootstrap/navigator_runtime/screen.rs b/moli-renderer-v8/src/context_bootstrap/navigator_runtime/screen.rs index 76c6c380e3..21225778e0 100644 --- a/moli-renderer-v8/src/context_bootstrap/navigator_runtime/screen.rs +++ b/moli-renderer-v8/src/context_bootstrap/navigator_runtime/screen.rs @@ -1,7 +1,5 @@ use super::super::media_queries::{ dispatch_simple_event_target_event, initialize_simple_event_target, - simple_event_target_add_event_listener_callback, simple_event_target_dispatch_event_callback, - simple_event_target_remove_event_listener_callback, }; use super::super::*; use crate::util::{ @@ -121,44 +119,6 @@ struct ScreenOrientationPrototypeMethodsDeclaration { unlock: (), } -#[derive(Default, WebApiFunctionTemplate)] -#[webapi(interface = web_api_interfaces::Screen, enumerable)] -struct ScreenEventTargetMethodsDeclaration { - #[webapi(method, length = 2, callback = screen_event_target_add_event_listener_callback)] - add_event_listener: (), - #[webapi( - method, - length = 2, - callback = screen_event_target_remove_event_listener_callback - )] - remove_event_listener: (), - #[webapi(method, length = 1, callback = screen_event_target_dispatch_event_callback)] - dispatch_event: (), -} - -#[derive(Default, WebApiFunctionTemplate)] -#[webapi(interface = web_api_interfaces::ScreenOrientation, enumerable)] -struct ScreenOrientationEventTargetMethodsDeclaration { - #[webapi( - method, - length = 2, - callback = screen_orientation_event_target_add_event_listener_callback - )] - add_event_listener: (), - #[webapi( - method, - length = 2, - callback = screen_orientation_event_target_remove_event_listener_callback - )] - remove_event_listener: (), - #[webapi( - method, - length = 1, - callback = screen_orientation_event_target_dispatch_event_callback - )] - dispatch_event: (), -} - fn new_not_supported_dom_exception<'s>( scope: &mut v8::PinScope<'s, '_>, message: &str, @@ -228,78 +188,6 @@ fn screen_orientation_unlock_callback<'s>( rv.set(v8::undefined(scope).into()); } -fn screen_event_target_add_event_listener_callback<'s>( - scope: &mut v8::PinScope<'s, '_>, - args: v8::FunctionCallbackArguments<'s>, - rv: v8::ReturnValue<'s, v8::Value>, -) { - if !web_api_interfaces::Screen::is_instance(scope, args.this()) { - throw_type_error(scope, "Illegal invocation"); - return; - } - simple_event_target_add_event_listener_callback(scope, args, rv); -} - -fn screen_event_target_remove_event_listener_callback<'s>( - scope: &mut v8::PinScope<'s, '_>, - args: v8::FunctionCallbackArguments<'s>, - rv: v8::ReturnValue<'s, v8::Value>, -) { - if !web_api_interfaces::Screen::is_instance(scope, args.this()) { - throw_type_error(scope, "Illegal invocation"); - return; - } - simple_event_target_remove_event_listener_callback(scope, args, rv); -} - -fn screen_event_target_dispatch_event_callback<'s>( - scope: &mut v8::PinScope<'s, '_>, - args: v8::FunctionCallbackArguments<'s>, - rv: v8::ReturnValue<'s, v8::Value>, -) { - if !web_api_interfaces::Screen::is_instance(scope, args.this()) { - throw_type_error(scope, "Illegal invocation"); - return; - } - simple_event_target_dispatch_event_callback(scope, args, rv); -} - -fn screen_orientation_event_target_add_event_listener_callback<'s>( - scope: &mut v8::PinScope<'s, '_>, - args: v8::FunctionCallbackArguments<'s>, - rv: v8::ReturnValue<'s, v8::Value>, -) { - if !web_api_interfaces::ScreenOrientation::is_instance(scope, args.this()) { - throw_type_error(scope, "Illegal invocation"); - return; - } - simple_event_target_add_event_listener_callback(scope, args, rv); -} - -fn screen_orientation_event_target_remove_event_listener_callback<'s>( - scope: &mut v8::PinScope<'s, '_>, - args: v8::FunctionCallbackArguments<'s>, - rv: v8::ReturnValue<'s, v8::Value>, -) { - if !web_api_interfaces::ScreenOrientation::is_instance(scope, args.this()) { - throw_type_error(scope, "Illegal invocation"); - return; - } - simple_event_target_remove_event_listener_callback(scope, args, rv); -} - -fn screen_orientation_event_target_dispatch_event_callback<'s>( - scope: &mut v8::PinScope<'s, '_>, - args: v8::FunctionCallbackArguments<'s>, - rv: v8::ReturnValue<'s, v8::Value>, -) { - if !web_api_interfaces::ScreenOrientation::is_instance(scope, args.this()) { - throw_type_error(scope, "Illegal invocation"); - return; - } - simple_event_target_dispatch_event_callback(scope, args, rv); -} - pub(in crate::context_bootstrap) fn install_screen_template_bindings<'s>( scope: &mut v8::PinScope<'s, '_, ()>, template: v8::Local<'s, v8::FunctionTemplate>, @@ -309,15 +197,11 @@ pub(in crate::context_bootstrap) fn install_screen_template_bindings<'s>( match interface_name { "Screen" => { ScreenPrototypeAccessorsDeclaration::initialize_prototype_template(scope, prototype); - ScreenEventTargetMethodsDeclaration::initialize_prototype_template(scope, prototype); } "ScreenOrientation" => { ScreenOrientationPrototypeAccessorsDeclaration::initialize_prototype_template( scope, prototype, ); - ScreenOrientationEventTargetMethodsDeclaration::initialize_prototype_template( - scope, prototype, - ); ScreenOrientationPrototypeMethodsDeclaration::initialize_prototype_template( scope, prototype, ); diff --git a/moli-renderer-v8/src/context_bootstrap/notification_runtime.rs b/moli-renderer-v8/src/context_bootstrap/notification_runtime.rs index 98e87d3dc9..3e29bc1521 100644 --- a/moli-renderer-v8/src/context_bootstrap/notification_runtime.rs +++ b/moli-renderer-v8/src/context_bootstrap/notification_runtime.rs @@ -1,8 +1,7 @@ use super::{ SIMPLE_EVENT_TARGET_LISTENERS_SLOT, global_constructor_object, - simple_event_target_add_event_listener_callback, simple_event_target_dispatch_event_callback, simple_event_target_handler_getter_callback, simple_event_target_handler_setter_callback, - simple_event_target_remove_event_listener_callback, structured_clone_value_for_storage, + structured_clone_value_for_storage, }; use crate::web_api_interfaces; use crate::{ @@ -98,27 +97,6 @@ struct NotificationObjectDeclaration<'scope> { #[webapi(slot = SIMPLE_EVENT_TARGET_LISTENERS_SLOT, init = "null_object")] event_listeners: (), - #[webapi( - method, - enumerable, - callback = simple_event_target_add_event_listener_callback - )] - add_event_listener: (), - - #[webapi( - method, - enumerable, - callback = simple_event_target_remove_event_listener_callback - )] - remove_event_listener: (), - - #[webapi( - method, - enumerable, - callback = simple_event_target_dispatch_event_callback - )] - dispatch_event: (), - #[webapi(method, enumerable, callback = notification_close_callback)] close: (), } @@ -563,10 +541,6 @@ fn initialize_notification_object<'s>( require_interaction: metadata.require_interaction, actions: action_array, event_listeners: (), - - add_event_listener: (), - remove_event_listener: (), - dispatch_event: (), close: (), } .initialize(scope, notification) diff --git a/moli-renderer-v8/src/context_bootstrap/performance_runtime/install.rs b/moli-renderer-v8/src/context_bootstrap/performance_runtime/install.rs index 287e942a3d..d7af869935 100644 --- a/moli-renderer-v8/src/context_bootstrap/performance_runtime/install.rs +++ b/moli-renderer-v8/src/context_bootstrap/performance_runtime/install.rs @@ -376,7 +376,7 @@ pub(in crate::context_bootstrap) fn install_worker_performance_runtime_state<'s> ) .bind(scope) .map_err(|error| anyhow!("failed to create worker performance: {error}"))?; - install_simple_event_target_methods(scope, performance); + initialize_simple_event_target(scope, performance); set_private_value(scope, global, WINDOW_PERFORMANCE_SLOT, performance.into()); Ok(()) @@ -431,7 +431,7 @@ pub(super) fn create_performance_object<'s>( PERFORMANCE_NAVIGATION_NAME_SEED_SLOT, navigation_entry_name.into(), ); - install_simple_event_target_methods(scope, performance); + initialize_simple_event_target(scope, performance); performance } diff --git a/moli-renderer-v8/src/context_bootstrap/shared_worker_host.rs b/moli-renderer-v8/src/context_bootstrap/shared_worker_host.rs index c6eac27003..db5eb55e62 100644 --- a/moli-renderer-v8/src/context_bootstrap/shared_worker_host.rs +++ b/moli-renderer-v8/src/context_bootstrap/shared_worker_host.rs @@ -11,9 +11,7 @@ use super::{ document_referrer_policy_for_native_document, }, shared::SIMPLE_EVENT_TARGET_LISTENERS_SLOT, - simple_event_target_add_event_listener_callback, simple_event_target_dispatch_event_callback, - simple_event_target_remove_event_listener_callback, simple_object_event_listeners_snapshot, - simple_object_event_set_handler, + simple_object_event_listeners_snapshot, simple_object_event_set_handler, worker_host::{ document_query_encoding_override, is_cross_origin_http_worker_script, materialize_worker_script_source, resolve_worker_script_url, throw_worker_dom_exception, @@ -61,19 +59,6 @@ struct SharedWorkerObjectDeclaration<'scope> { #[webapi(slot = SHARED_WORKER_ONERROR_SLOT, init = "null")] onerror_slot: (), - #[webapi(method, enumerable, callback = simple_event_target_add_event_listener_callback)] - add_event_listener: (), - - #[webapi( - method, - enumerable, - callback = simple_event_target_remove_event_listener_callback - )] - remove_event_listener: (), - - #[webapi(method, enumerable, callback = simple_event_target_dispatch_event_callback)] - dispatch_event: (), - #[webapi( accessor_property, enumerable, diff --git a/moli-renderer-v8/src/context_bootstrap/specs/registry.rs b/moli-renderer-v8/src/context_bootstrap/specs/registry.rs index f5d991f800..248f17f138 100644 --- a/moli-renderer-v8/src/context_bootstrap/specs/registry.rs +++ b/moli-renderer-v8/src/context_bootstrap/specs/registry.rs @@ -4,6 +4,26 @@ use crate::web_api_interfaces; use std::collections::HashSet; const CONSTRUCTOR_SPECS_BEFORE_STREAMS: &[ConstructorSpec] = &[ + ConstructorSpec { + interface: web_api_interfaces::BatteryManager::DESCRIPTOR, + kind: ConstructorKind::Illegal, + }, + ConstructorSpec { + interface: web_api_interfaces::NetworkInformation::DESCRIPTOR, + kind: ConstructorKind::Illegal, + }, + ConstructorSpec { + interface: web_api_interfaces::ServiceWorkerContainer::DESCRIPTOR, + kind: ConstructorKind::Illegal, + }, + ConstructorSpec { + interface: web_api_interfaces::ServiceWorkerRegistration::DESCRIPTOR, + kind: ConstructorKind::Illegal, + }, + ConstructorSpec { + interface: web_api_interfaces::ServiceWorker::DESCRIPTOR, + kind: ConstructorKind::Illegal, + }, ConstructorSpec { interface: web_api_interfaces::PaymentRequestUpdateEvent::DESCRIPTOR, kind: ConstructorKind::PaymentRequestUpdateEvent, diff --git a/moli-renderer-v8/src/context_bootstrap/web_audio_runtime.rs b/moli-renderer-v8/src/context_bootstrap/web_audio_runtime.rs index c523b1e63e..119537f4e4 100644 --- a/moli-renderer-v8/src/context_bootstrap/web_audio_runtime.rs +++ b/moli-renderer-v8/src/context_bootstrap/web_audio_runtime.rs @@ -1,8 +1,4 @@ -use super::media_queries::{ - dispatch_simple_event_target_event, simple_event_target_add_event_listener_callback, - simple_event_target_dispatch_event_callback, - simple_event_target_remove_event_listener_callback, -}; +use super::media_queries::dispatch_simple_event_target_event; use super::*; use crate::native_bridge::throw_dom_exception; use crate::util::{ @@ -145,16 +141,6 @@ struct OfflineAudioContextObjectDeclaration<'scope> { state: &'static str, #[webapi(data_property)] destination: v8::Local<'scope, v8::Object>, - #[webapi(method, enumerable, callback = simple_event_target_add_event_listener_callback)] - add_event_listener: (), - #[webapi( - method, - enumerable, - callback = simple_event_target_remove_event_listener_callback - )] - remove_event_listener: (), - #[webapi(method, enumerable, callback = simple_event_target_dispatch_event_callback)] - dispatch_event: (), } #[derive(WebApiObject)] diff --git a/moli-renderer-v8/src/context_bootstrap/websocket.rs b/moli-renderer-v8/src/context_bootstrap/websocket.rs index 2c5e041943..68de667873 100644 --- a/moli-renderer-v8/src/context_bootstrap/websocket.rs +++ b/moli-renderer-v8/src/context_bootstrap/websocket.rs @@ -1,8 +1,4 @@ -use super::media_queries::{ - dispatch_simple_event_target_event, simple_event_target_add_event_listener_callback, - simple_event_target_dispatch_event_callback, - simple_event_target_remove_event_listener_callback, simple_object_event_set_handler, -}; +use super::media_queries::{dispatch_simple_event_target_event, simple_object_event_set_handler}; use super::shared::{ READABLE_STREAM_HWM_SLOT, READABLE_STREAM_PENDING_READS_SLOT, SIMPLE_EVENT_TARGET_LISTENERS_SLOT, WRITABLE_STREAM_SINK_SLOT, diff --git a/moli-renderer-v8/src/context_bootstrap/websocket/constructor.rs b/moli-renderer-v8/src/context_bootstrap/websocket/constructor.rs index 7898131075..ce785f2282 100644 --- a/moli-renderer-v8/src/context_bootstrap/websocket/constructor.rs +++ b/moli-renderer-v8/src/context_bootstrap/websocket/constructor.rs @@ -50,19 +50,6 @@ struct WebSocketObjectDeclaration { #[webapi(slot = SIMPLE_EVENT_TARGET_LISTENERS_SLOT, init = "null_object")] event_listeners: (), - - #[webapi(method, enumerable, callback = simple_event_target_add_event_listener_callback)] - add_event_listener: (), - - #[webapi( - method, - enumerable, - callback = simple_event_target_remove_event_listener_callback - )] - remove_event_listener: (), - - #[webapi(method, enumerable, callback = simple_event_target_dispatch_event_callback)] - dispatch_event: (), } #[derive(WebApiObject)] diff --git a/moli-renderer-v8/src/context_bootstrap/window_runtime/navigator.rs b/moli-renderer-v8/src/context_bootstrap/window_runtime/navigator.rs index 65a39a7856..96a571d736 100644 --- a/moli-renderer-v8/src/context_bootstrap/window_runtime/navigator.rs +++ b/moli-renderer-v8/src/context_bootstrap/window_runtime/navigator.rs @@ -286,7 +286,7 @@ struct StorageUsageDetailsObjectDeclaration { } #[derive(WebApiObject)] -#[webapi(prototype = "Object", interface = web_api_interfaces::BatteryManager, data_properties, receiver)] +#[webapi(interface = web_api_interfaces::BatteryManager, data_properties, receiver)] struct NavigatorBatteryStatusObjectDeclaration { #[webapi(data_property, enumerable)] charging: bool, @@ -297,26 +297,20 @@ struct NavigatorBatteryStatusObjectDeclaration { #[webapi(data_property, enumerable)] level: f64, - #[webapi(data_property, enumerable, init = "null")] + #[webapi(accessor_property, enumerable, getter = simple_event_target_handler_getter_callback, setter = simple_event_target_handler_setter_callback, data = v8str(scope, "onchargingchange"), setter_data = v8str(scope, "onchargingchange"))] onchargingchange: (), - #[webapi(data_property, enumerable, init = "null")] + #[webapi(accessor_property, enumerable, getter = simple_event_target_handler_getter_callback, setter = simple_event_target_handler_setter_callback, data = v8str(scope, "onchargingtimechange"), setter_data = v8str(scope, "onchargingtimechange"))] onchargingtimechange: (), - #[webapi(data_property, enumerable, init = "null")] + #[webapi(accessor_property, enumerable, getter = simple_event_target_handler_getter_callback, setter = simple_event_target_handler_setter_callback, data = v8str(scope, "ondischargingtimechange"), setter_data = v8str(scope, "ondischargingtimechange"))] ondischargingtimechange: (), - #[webapi(data_property, enumerable, init = "null")] + #[webapi(accessor_property, enumerable, getter = simple_event_target_handler_getter_callback, setter = simple_event_target_handler_setter_callback, data = v8str(scope, "onlevelchange"), setter_data = v8str(scope, "onlevelchange"))] onlevelchange: (), - #[webapi(method, length = 2, callback = battery_event_target_noop_callback)] - add_event_listener: (), - - #[webapi(method, length = 2, callback = battery_event_target_noop_callback)] - remove_event_listener: (), - - #[webapi(method, length = 1, callback = battery_dispatch_event_callback)] - dispatch_event: (), + #[webapi(slot = SIMPLE_EVENT_TARGET_LISTENERS_SLOT, init = "null_object")] + event_listeners: (), } #[derive(WebApiObject)] @@ -610,21 +604,6 @@ pub(in crate::context_bootstrap) fn navigator_get_battery_callback<'s>( rv.set(resolver.get_promise(scope).into()); } -fn battery_event_target_noop_callback<'s>( - _scope: &mut v8::PinScope<'s, '_>, - _args: v8::FunctionCallbackArguments<'s>, - _rv: v8::ReturnValue<'_, v8::Value>, -) { -} - -fn battery_dispatch_event_callback<'s>( - scope: &mut v8::PinScope<'s, '_>, - _args: v8::FunctionCallbackArguments<'s>, - mut rv: v8::ReturnValue<'_, v8::Value>, -) { - rv.set(v8::Boolean::new(scope, true).into()); -} - pub(in crate::context_bootstrap) fn navigator_permissions_query_callback<'s>( scope: &mut v8::PinScope<'s, '_>, args: v8::FunctionCallbackArguments<'s>, diff --git a/moli-renderer-v8/src/context_bootstrap/window_runtime/service_worker.rs b/moli-renderer-v8/src/context_bootstrap/window_runtime/service_worker.rs index a8952b9f3b..bd0b50767e 100644 --- a/moli-renderer-v8/src/context_bootstrap/window_runtime/service_worker.rs +++ b/moli-renderer-v8/src/context_bootstrap/window_runtime/service_worker.rs @@ -97,25 +97,6 @@ struct ServiceWorkerRegistrationObjectDeclaration<'scope> { #[webapi(data_property = "navigationPreload", readonly)] navigation_preload: Option>, - - #[webapi( - method = "addEventListener", - callback = service_worker_registration_add_event_listener_callback, - length = 2 - )] - add_event_listener: (), - #[webapi( - method = "removeEventListener", - callback = simple_event_target_remove_event_listener_callback, - length = 2 - )] - remove_event_listener: (), - #[webapi( - method = "dispatchEvent", - callback = simple_event_target_dispatch_event_callback, - length = 1 - )] - dispatch_event: (), } #[derive(WebApiObject)] @@ -293,27 +274,6 @@ struct ServiceWorkerObjectDeclaration { #[webapi(method = "postMessage", callback = service_worker_post_message_callback, length = 1)] post_message: (), - - #[webapi( - method = "addEventListener", - callback = service_worker_worker_add_event_listener_callback, - length = 2 - )] - add_event_listener: (), - - #[webapi( - method = "removeEventListener", - callback = simple_event_target_remove_event_listener_callback, - length = 2 - )] - remove_event_listener: (), - - #[webapi( - method = "dispatchEvent", - callback = simple_event_target_dispatch_event_callback, - length = 1 - )] - dispatch_event: (), } #[derive(WebApiObject)] @@ -2847,22 +2807,6 @@ fn mark_service_worker_worker_event_target<'s>( initialize_simple_event_target(scope, worker); } -fn service_worker_registration_add_event_listener_callback<'s>( - scope: &mut v8::PinScope<'s, '_>, - args: v8::FunctionCallbackArguments<'s>, - rv: v8::ReturnValue<'s, v8::Value>, -) { - simple_event_target_add_event_listener_callback(scope, args, rv); -} - -fn service_worker_worker_add_event_listener_callback<'s>( - scope: &mut v8::PinScope<'s, '_>, - args: v8::FunctionCallbackArguments<'s>, - rv: v8::ReturnValue<'s, v8::Value>, -) { - simple_event_target_add_event_listener_callback(scope, args, rv); -} - fn service_worker_post_message_callback<'s>( scope: &mut v8::PinScope<'s, '_>, args: v8::FunctionCallbackArguments<'s>, diff --git a/moli-renderer-v8/src/context_bootstrap/worker_host/constructor.rs b/moli-renderer-v8/src/context_bootstrap/worker_host/constructor.rs index 7b76abf075..5ed1fd624a 100644 --- a/moli-renderer-v8/src/context_bootstrap/worker_host/constructor.rs +++ b/moli-renderer-v8/src/context_bootstrap/worker_host/constructor.rs @@ -75,19 +75,6 @@ struct WorkerObjectDeclaration { #[webapi(slot = WORKER_ONERROR_SLOT, init = "null")] onerror_slot: (), - #[webapi(method, enumerable, callback = simple_event_target_add_event_listener_callback)] - add_event_listener: (), - - #[webapi( - method, - enumerable, - callback = simple_event_target_remove_event_listener_callback - )] - remove_event_listener: (), - - #[webapi(method, enumerable, callback = simple_event_target_dispatch_event_callback)] - dispatch_event: (), - #[webapi( accessor_property, enumerable, diff --git a/moli-renderer-v8/src/context_bootstrap/worker_host/mod.rs b/moli-renderer-v8/src/context_bootstrap/worker_host/mod.rs index e33503b949..ec3d3db74e 100644 --- a/moli-renderer-v8/src/context_bootstrap/worker_host/mod.rs +++ b/moli-renderer-v8/src/context_bootstrap/worker_host/mod.rs @@ -1,7 +1,4 @@ -use super::media_queries::{ - simple_event_target_add_event_listener_callback, simple_event_target_dispatch_event_callback, - simple_event_target_remove_event_listener_callback, simple_object_event_set_handler, -}; +use super::media_queries::simple_object_event_set_handler; use super::shared::SIMPLE_EVENT_TARGET_LISTENERS_SLOT; use crate::{ util::context_host_ptr_from_global_bridge, diff --git a/moli-renderer-v8/src/context_bootstrap/worker_host/tests.rs b/moli-renderer-v8/src/context_bootstrap/worker_host/tests.rs index 5841f678d2..1a1dd4797e 100644 --- a/moli-renderer-v8/src/context_bootstrap/worker_host/tests.rs +++ b/moli-renderer-v8/src/context_bootstrap/worker_host/tests.rs @@ -29,6 +29,12 @@ fn setup_worker_context() -> (v8::OwnedIsolate, v8::Global) { let worker_tmpl = v8::FunctionTemplate::builder(worker_constructor_callback) .length(1) .build(scope); + let event_target = crate::context_bootstrap::prepare_worker_event_target_template( + scope, + crate::context_bootstrap::exposed_interfaces::RealmKind::DedicatedWorker, + ) + .expect("standalone Worker tests need the inherited EventTarget template"); + worker_tmpl.inherit(event_target); let class_name = v8::String::new(scope, "Worker").unwrap(); worker_tmpl.set_class_name(class_name); @@ -55,6 +61,12 @@ fn setup_worker_context() -> (v8::OwnedIsolate, v8::Global) { let context = v8::Context::new(scope, Default::default()); let ctx_scope = &mut v8::ContextScope::new(scope, context); let global = context.global(ctx_scope); + let event_target_constructor = event_target.get_function(ctx_scope).unwrap(); + let _ = global.set( + ctx_scope, + crate::util::v8str(ctx_scope, "EventTarget").into(), + event_target_constructor.into(), + ); crate::context_bootstrap::exposed_interfaces::install_worker_exposed_interfaces( ctx_scope, @@ -500,12 +512,15 @@ fn constructor_declared_event_target_slots_ignore_reflection_and_spoofing() { throw new Error(`Worker internals should not be reflected: ${reflected.join(",")}`); } const expectedMethods = { - addEventListener: "true:true:true:true:function:0:addEventListener", - removeEventListener: "true:true:true:true:function:0:removeEventListener", - dispatchEvent: "true:true:true:true:function:0:dispatchEvent" + addEventListener: "true:true:true:true:function:2:addEventListener", + removeEventListener: "true:true:true:true:function:2:removeEventListener", + dispatchEvent: "true:true:true:true:function:1:dispatchEvent" }; for (const [name, shape] of Object.entries(expectedMethods)) { - const descriptor = Object.getOwnPropertyDescriptor(w, name); + if (Object.hasOwn(w, name) || w[name] !== EventTarget.prototype[name]) { + throw new Error(`${name} must be inherited from EventTarget.prototype`); + } + const descriptor = Object.getOwnPropertyDescriptor(EventTarget.prototype, name); const actual = [ !!descriptor, descriptor && descriptor.enumerable, diff --git a/moli-renderer-v8/src/native_bridge/context_host/popups.rs b/moli-renderer-v8/src/native_bridge/context_host/popups.rs index f1d716280f..6efa12c17d 100644 --- a/moli-renderer-v8/src/native_bridge/context_host/popups.rs +++ b/moli-renderer-v8/src/native_bridge/context_host/popups.rs @@ -9,7 +9,7 @@ use crate::{ SIMPLE_EVENT_TARGET_LISTENERS_SLOT, SharedWebStorageStore, WINDOW_NAME_SLOT, apply_local_window_location_navigation, clear_simple_window_event_handler_values, deep_clone_shared_web_storage_store, dispatch_simple_event_target_event, - install_navigation_bootstrap_entry_for_holder, install_simple_event_target_methods, + initialize_simple_event_target, install_navigation_bootstrap_entry_for_holder, install_simple_window_event_handlers, install_storage_aliases_for_window, install_window_location_history_navigation_runtime_state, new_shared_web_storage_store, scoped_indexed_db_factory, sync_document_location_runtime_state_from_window, @@ -803,6 +803,9 @@ impl JsContextHost { .bridge .bindings .instantiate_window_shell(scope, host_ptr); + crate::web_api_interfaces::Window::DESCRIPTOR + .initialize(scope, window) + .ok()?; if let Some(dom_exception) = global_constructor_object(scope, "DOMException") { // Lightweight popups share the opener's V8 realm, so their // synthetic Window shell must expose the same realm constructor @@ -866,7 +869,7 @@ impl JsContextHost { } } let _ = install_storage_aliases_for_window(scope, window); - install_simple_event_target_methods(scope, window); + initialize_simple_event_target(scope, window); install_simple_window_event_handlers(scope, window); let _ = LightweightPopupWindowMethodsDeclaration::default().initialize(scope, window); let initial_document_owner = self.allocate_lightweight_popup_document_owner(popup_id); diff --git a/moli-renderer-v8/src/runtime/page_vm/tests/worker/service_and_shared_worker_lifecycle.rs b/moli-renderer-v8/src/runtime/page_vm/tests/worker/service_and_shared_worker_lifecycle.rs index bb92670845..359a051bee 100644 --- a/moli-renderer-v8/src/runtime/page_vm/tests/worker/service_and_shared_worker_lifecycle.rs +++ b/moli-renderer-v8/src/runtime/page_vm/tests/worker/service_and_shared_worker_lifecycle.rs @@ -989,12 +989,14 @@ async fn shared_worker_declared_surface_ignores_reflection_and_spoofing() { throw new Error(`SharedWorker internals should not be reflected: ${reflected.join(",")}`); } const expectedMethods = { - addEventListener: "true:true:true:true:function:0:addEventListener", - removeEventListener: "true:true:true:true:function:0:removeEventListener", - dispatchEvent: "true:true:true:true:function:0:dispatchEvent" + addEventListener: "true:true:true:true:function:2:addEventListener", + removeEventListener: "true:true:true:true:function:2:removeEventListener", + dispatchEvent: "true:true:true:true:function:1:dispatchEvent" }; for (const [name, shape] of Object.entries(expectedMethods)) { - const descriptor = Object.getOwnPropertyDescriptor(worker, name); + if (Object.hasOwn(worker, name) || worker[name] !== EventTarget.prototype[name]) + throw new Error(`inherited EventTarget method ${name}`); + const descriptor = Object.getOwnPropertyDescriptor(EventTarget.prototype, name); const actual = [ !!descriptor, descriptor && descriptor.enumerable, diff --git a/moli-renderer-v8/src/script_vm/tests/browser_api/broadcast_channel.rs b/moli-renderer-v8/src/script_vm/tests/browser_api/broadcast_channel.rs index 3f32c81039..904111257f 100644 --- a/moli-renderer-v8/src/script_vm/tests/browser_api/broadcast_channel.rs +++ b/moli-renderer-v8/src/script_vm/tests/browser_api/broadcast_channel.rs @@ -735,7 +735,9 @@ fn broadcast_channel_ordered_handler_slot_ignores_reflection_and_spoofing() { name === "__moliSimpleEventTargetOrderedHandlers" ); const summarize = name => { - const descriptor = Object.getOwnPropertyDescriptor(channel, name); + if (Object.hasOwn(channel, name) || channel[name] !== EventTarget.prototype[name]) + throw new Error(`inherited EventTarget method ${name}`); + const descriptor = Object.getOwnPropertyDescriptor(EventTarget.prototype, name); return [ !!descriptor, descriptor && descriptor.enumerable, @@ -774,7 +776,7 @@ fn broadcast_channel_ordered_handler_slot_ignores_reflection_and_spoofing() { assert_eq!( result, - r#"{"ownBefore":[],"publicSpoof":["spoofedListeners",false],"add":"true:true:true:true:function:0:addEventListener","remove":"true:true:true:true:function:0:removeEventListener","dispatch":"true:true:true:true:function:0:dispatchEvent","calls":["listener","handler"]}"# + r#"{"ownBefore":[],"publicSpoof":["spoofedListeners",false],"add":"true:true:true:true:function:2:addEventListener","remove":"true:true:true:true:function:2:removeEventListener","dispatch":"true:true:true:true:function:1:dispatchEvent","calls":["listener","handler"]}"# ); } diff --git a/moli-renderer-v8/src/script_vm/tests/browser_api/event_target_prototype.rs b/moli-renderer-v8/src/script_vm/tests/browser_api/event_target_prototype.rs index 9b41a14989..5914ca0cb7 100644 --- a/moli-renderer-v8/src/script_vm/tests/browser_api/event_target_prototype.rs +++ b/moli-renderer-v8/src/script_vm/tests/browser_api/event_target_prototype.rs @@ -1,5 +1,24 @@ use super::*; +#[test] +fn event_target_interfaces_inherit_canonical_operations() { + let mut vm = new_storage_html_test_vm("https://event-target-inheritance.test/"); + vm.eval(include_str!( + "../../../../tests/fixtures/event-target-inheritance.js" + )) + .expect("interface inheritance matrix should run"); + assert_eq!(vm.eval("String(!__eventTargetInheritance.pending && __eventTargetInheritance.rows.every(row => row[1]))").unwrap(), "true"); + assert_eq!(vm.eval("String(__eventTargetInheritance.rows.some(row => row[0] === 'battery: native inheritance'))").unwrap(), "true"); + vm.eval( + r#"(() => { + const popup = open('about:blank', 'inherited-event-target'); + try { __eventTargetInheritance.inspect(popup, 'lightweight popup'); } + finally { popup.close(); } + })()"#, + ) + .expect("popup should inherit EventTarget operations"); +} + #[test] fn event_target_prototype_methods_preserve_native_state_and_realm_semantics() { let mut vm = new_parsed_test_vm( diff --git a/moli-renderer-v8/src/script_vm/tests/browser_api/media.rs b/moli-renderer-v8/src/script_vm/tests/browser_api/media.rs index 217a79bbea..aae77f2142 100644 --- a/moli-renderer-v8/src/script_vm/tests/browser_api/media.rs +++ b/moli-renderer-v8/src/script_vm/tests/browser_api/media.rs @@ -2567,11 +2567,12 @@ fn web_audio_methods_preserve_own_and_shared_prototype_descriptors() { return JSON.stringify({ ctxKeys: Object.keys(ctx).join(","), + inheritedEvents: ["addEventListener", "removeEventListener", "dispatchEvent"].every(name => !Object.hasOwn(ctx, name) && ctx[name] === EventTarget.prototype[name]), oscKeys: Object.keys(osc).join(","), compKeys: Object.keys(comp).join(","), analyserKeys: Object.keys(analyser).join(","), paramKeys: Object.keys(osc.frequency).join(","), - ctx: ["addEventListener", "removeEventListener", "dispatchEvent"].map(name => describe(ctx, name)), + ctx: ["addEventListener", "removeEventListener", "dispatchEvent"].map(name => describe(EventTarget.prototype, name)), graph: ["connect", "disconnect"].map(name => describe(AudioNode.prototype, name)), shared: [ctx.destination, osc, comp, analyser].every(node => ["connect", "disconnect"].every(name => @@ -2586,7 +2587,7 @@ fn web_audio_methods_preserve_own_and_shared_prototype_descriptors() { assert_eq!( result, - r#"{"ctxKeys":"addEventListener,removeEventListener,dispatchEvent","oscKeys":"","compKeys":"","analyserKeys":"","paramKeys":"","ctx":["addEventListener:true:true:true:function:addEventListener:0","removeEventListener:true:true:true:function:removeEventListener:0","dispatchEvent:true:true:true:function:dispatchEvent:0"],"graph":["connect:true:true:true:function:connect:1","disconnect:true:true:true:function:disconnect:0"],"shared":true,"oscStart":"start:false:true:true:function:start:1","param":"setValueAtTime:false:true:true:function:setValueAtTime:2"}"# + r#"{"ctxKeys":"","inheritedEvents":true,"oscKeys":"","compKeys":"","analyserKeys":"","paramKeys":"","ctx":["addEventListener:true:true:true:function:addEventListener:2","removeEventListener:true:true:true:function:removeEventListener:2","dispatchEvent:true:true:true:function:dispatchEvent:1"],"graph":["connect:true:true:true:function:connect:1","disconnect:true:true:true:function:disconnect:0"],"shared":true,"oscStart":"start:false:true:true:function:start:1","param":"setValueAtTime:false:true:true:function:setValueAtTime:2"}"# ); } diff --git a/moli-renderer-v8/src/script_vm/tests/browser_api/misc/extracted/events_errors.rs b/moli-renderer-v8/src/script_vm/tests/browser_api/misc/extracted/events_errors.rs index bbf0454e40..73c2cb28b7 100644 --- a/moli-renderer-v8/src/script_vm/tests/browser_api/misc/extracted/events_errors.rs +++ b/moli-renderer-v8/src/script_vm/tests/browser_api/misc/extracted/events_errors.rs @@ -705,7 +705,9 @@ fn navigator_battery_status_declares_event_target_methods() { navigator.getBattery().then((battery) => { const fakeBattery = Object.create(battery); const summarize = name => { - const descriptor = Object.getOwnPropertyDescriptor(battery, name); + if (Object.hasOwn(battery, name) || battery[name] !== EventTarget.prototype[name]) + throw new Error(`inherited EventTarget method ${name}`); + const descriptor = Object.getOwnPropertyDescriptor(EventTarget.prototype, name); return [ !!descriptor, descriptor && descriptor.enumerable, @@ -728,7 +730,7 @@ fn navigator_battery_status_declares_event_target_methods() { summarize("addEventListener"), summarize("removeEventListener"), summarize("dispatchEvent"), - battery.dispatchEvent({ type: "chargingchange" }), + battery.dispatchEvent(new Event("chargingchange")), String(battery.addEventListener("chargingchange", () => {})), String(battery.removeEventListener("chargingchange", () => {})), methodOutcome("addEventListener", "chargingchange", () => {}), @@ -747,7 +749,7 @@ fn navigator_battery_status_declares_event_target_methods() { assert_eq!( result, - "false|true:false:true:true:function:2:addEventListener|true:false:true:true:function:2:removeEventListener|true:false:true:true:function:1:dispatchEvent|true|undefined|undefined|throw:TypeError|throw:TypeError|throw:TypeError" + "false|true:true:true:true:function:2:addEventListener|true:true:true:true:function:2:removeEventListener|true:true:true:true:function:1:dispatchEvent|true|undefined|undefined|throw:TypeError|throw:TypeError|throw:TypeError" ); } #[test] diff --git a/moli-renderer-v8/src/script_vm/tests/browser_api/misc/extracted/webidl_surface.rs b/moli-renderer-v8/src/script_vm/tests/browser_api/misc/extracted/webidl_surface.rs index 1d872068d4..c8ecdbe625 100644 --- a/moli-renderer-v8/src/script_vm/tests/browser_api/misc/extracted/webidl_surface.rs +++ b/moli-renderer-v8/src/script_vm/tests/browser_api/misc/extracted/webidl_surface.rs @@ -865,8 +865,8 @@ fn navigator_runtime_subobjects_keep_declared_brand_and_methods() { Object.getOwnPropertyNames(connection) .filter(name => name.startsWith("__moliNavigatorConnection")) .join(","), - summarizeOwnMethod(connection, "addEventListener"), - summarizeOwnMethod(connection, "removeEventListener"), + summarizeOwnMethod(EventTarget.prototype, "addEventListener"), + summarizeOwnMethod(EventTarget.prototype, "removeEventListener"), String(connection.addEventListener("change", () => {})), String(connection.removeEventListener("change", () => {})), methodOutcome(connection, fakeConnection, "addEventListener", "change", () => {}), @@ -924,7 +924,7 @@ fn navigator_runtime_subobjects_keep_declared_brand_and_methods() { assert_eq!( result, - r#"{"permissions":"true|[object Permissions]|false|function|1","storage":"true|[object StorageManager]|false|false|false|false||true|true|true|true|persisted|0|persist|0|estimate|0|false:undefined:::::|[object Promise]|[object Promise]","connection":"[object Object]|string|unknown|Infinity|string|4g|10|50|false|true|type,downlinkMax,effectiveType,downlink,rtt,saveData,onchange,addEventListener,removeEventListener||true:function:addEventListener:2:true:true:true|true:function:removeEventListener:2:true:true:true|undefined|undefined|throw:TypeError|throw:TypeError","mediaDevices":"true|[object MediaDevices]|false|false||enumerateDevices|0|getUserMedia|1|true:function:enumerateDevices:0:true:true:true|true:function:getUserMedia:1:true:true:true","clipboard":"true|true|[object Clipboard]|false|false||true|true|true|true|readText|0|writeText|1|true:function:readText:0:true:true:true|true:function:writeText:1:true:true:true|[object Promise]|[object Promise]","userActivation":"undefined|[object Object]|boolean|false|false|isActive,hasBeenActive|true|throw:TypeError|throw:TypeError"}"# + r#"{"permissions":"true|[object Permissions]|false|function|1","storage":"true|[object StorageManager]|false|false|false|false||true|true|true|true|persisted|0|persist|0|estimate|0|false:undefined:::::|[object Promise]|[object Promise]","connection":"[object NetworkInformation]|string|unknown|Infinity|string|4g|10|50|false|true|type,downlinkMax,effectiveType,downlink,rtt,saveData,onchange||true:function:addEventListener:2:true:true:true|true:function:removeEventListener:2:true:true:true|undefined|undefined|throw:TypeError|throw:TypeError","mediaDevices":"true|[object MediaDevices]|false|false||enumerateDevices|0|getUserMedia|1|true:function:enumerateDevices:0:true:true:true|true:function:getUserMedia:1:true:true:true","clipboard":"true|true|[object Clipboard]|false|false||true|true|true|true|readText|0|writeText|1|true:function:readText:0:true:true:true|true:function:writeText:1:true:true:true|[object Promise]|[object Promise]","userActivation":"undefined|[object Object]|boolean|false|false|isActive,hasBeenActive|true|throw:TypeError|throw:TypeError"}"# ); let receiver_errors = vm .eval( @@ -1753,7 +1753,10 @@ fn notification_declared_surface_uses_private_slots_and_methods() { }); const summarize = (target, name) => { - const descriptor = Object.getOwnPropertyDescriptor(target, name); + const inherited = ["addEventListener", "removeEventListener", "dispatchEvent"].includes(name); + if (inherited && (Object.hasOwn(target, name) || target[name] !== EventTarget.prototype[name])) + throw new Error(`${name} should be inherited from EventTarget`); + const descriptor = Object.getOwnPropertyDescriptor(inherited ? EventTarget.prototype : target, name); return [ !!descriptor, descriptor && descriptor.enumerable, @@ -1848,7 +1851,7 @@ fn notification_declared_surface_uses_private_slots_and_methods() { assert_eq!( result, - "none|title:function:get title:0:undefined:true:true,data:function:get data:0:undefined:true:true,actions:function:get actions:0:undefined:true:true|real|42|0|throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError|throw:TypeError,throw:TypeError,throw:TypeError|true|true:true:true:true:function:0:requestPermission|true|true:true:true:true:function:0:addEventListener|true:true:true:true:function:0:removeEventListener|true:true:true:true:function:0:dispatchEvent|true|listener" + "none|title:function:get title:0:undefined:true:true,data:function:get data:0:undefined:true:true,actions:function:get actions:0:undefined:true:true|real|42|0|throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError,throw:TypeError|throw:TypeError,throw:TypeError,throw:TypeError|true|true:true:true:true:function:0:requestPermission|false|true:true:true:true:function:2:addEventListener|true:true:true:true:function:2:removeEventListener|true:true:true:true:function:1:dispatchEvent|true|listener" ); } diff --git a/moli-renderer-v8/src/script_vm/tests/post_parse.rs b/moli-renderer-v8/src/script_vm/tests/post_parse.rs index a70158d79e..fbe7484917 100644 --- a/moli-renderer-v8/src/script_vm/tests/post_parse.rs +++ b/moli-renderer-v8/src/script_vm/tests/post_parse.rs @@ -4061,7 +4061,10 @@ fn indexed_db_declared_methods_have_webidl_operation_descriptors() { [IDBKeyRange, "upperBound", 1], ]; for (const [target, name, length] of methods) { - const descriptor = Object.getOwnPropertyDescriptor(target, name); + const inherited = ["addEventListener", "removeEventListener", "dispatchEvent"].includes(name); + if (inherited && (Object.hasOwn(target, name) || target[name] !== EventTarget.prototype[name])) + throw new Error(`${name} should be inherited from EventTarget`); + const descriptor = Object.getOwnPropertyDescriptor(inherited ? EventTarget.prototype : target, name); if (!descriptor || typeof descriptor.value !== "function") { throw new Error(`${name} should be a declared function`); } diff --git a/moli-renderer-v8/src/script_vm/tests/websocket.rs b/moli-renderer-v8/src/script_vm/tests/websocket.rs index 2f0d1612d9..1f08730a9b 100644 --- a/moli-renderer-v8/src/script_vm/tests/websocket.rs +++ b/moli-renderer-v8/src/script_vm/tests/websocket.rs @@ -498,12 +498,14 @@ fn websocket_wpt_target_event_target_listener_options_and_objects() { throw new Error(`WebSocket simple EventTarget internals should not be reflected: ${simpleOwn.join(',')}`); } const expected = { - addEventListener: 'true:true:true:true:function:0:addEventListener', - removeEventListener: 'true:true:true:true:function:0:removeEventListener', - dispatchEvent: 'true:true:true:true:function:0:dispatchEvent' + addEventListener: 'true:true:true:true:function:2:addEventListener', + removeEventListener: 'true:true:true:true:function:2:removeEventListener', + dispatchEvent: 'true:true:true:true:function:1:dispatchEvent' }; for (const [name, shape] of Object.entries(expected)) { - const descriptor = Object.getOwnPropertyDescriptor(socket, name); + if (Object.hasOwn(socket, name) || socket[name] !== EventTarget.prototype[name]) + throw new Error(`inherited EventTarget method ${name}`); + const descriptor = Object.getOwnPropertyDescriptor(EventTarget.prototype, name); const actual = [ !!descriptor, descriptor && descriptor.enumerable, diff --git a/moli-renderer-v8/src/web_api_interfaces.rs b/moli-renderer-v8/src/web_api_interfaces.rs index fd70b62fc5..6ca560ca9e 100644 --- a/moli-renderer-v8/src/web_api_interfaces.rs +++ b/moli-renderer-v8/src/web_api_interfaces.rs @@ -49,7 +49,7 @@ interfaces! { AudioWorkletNode: AudioNode; BaseAudioContext: EventTarget; BarProp; - BatteryManager; + BatteryManager: EventTarget; BeforeUnloadEvent: Event; BiquadFilterNode: AudioNode; Blob; @@ -537,12 +537,12 @@ interfaces! { SVGTransform; SVGTransformList; SVGUseElement: SVGGraphicsElement; - Screen; + Screen: EventTarget; ScreenOrientation: EventTarget; SecurityPolicyViolationEvent: Event; Selection; ServiceWorker: EventTarget; - ServiceWorkerContainer; + ServiceWorkerContainer: EventTarget; ServiceWorkerGlobalScope: WorkerGlobalScope; ServiceWorkerRegistration: EventTarget; ShadowRoot: DocumentFragment; diff --git a/moli-renderer-v8/src/window_host.rs b/moli-renderer-v8/src/window_host.rs index 4a929b58ee..f34ceae336 100644 --- a/moli-renderer-v8/src/window_host.rs +++ b/moli-renderer-v8/src/window_host.rs @@ -307,6 +307,15 @@ pub(super) fn event_target_dispatch_event_callback<'s>( args: v8::FunctionCallbackArguments<'s>, mut rv: v8::ReturnValue<'s, v8::Value>, ) { + // IndexedDB retains its transaction-owner dispatch scope while sharing the + // public EventTarget operation with every other interface. + if crate::web_api_interfaces::IDBDatabase::is_instance(scope, args.this()) + || crate::web_api_interfaces::IDBRequest::is_instance(scope, args.this()) + || crate::web_api_interfaces::IDBTransaction::is_instance(scope, args.this()) + { + crate::context_bootstrap::dispatch_indexed_db_event_callback(scope, args, rv); + return; + } if is_simple_event_target(scope, args.this()) { simple_event_target_dispatch_event_callback(scope, args, rv); return; diff --git a/moli-renderer-v8/src/worker/global_scope/bootstrap.rs b/moli-renderer-v8/src/worker/global_scope/bootstrap.rs index c59fb97560..9a550fa5b9 100644 --- a/moli-renderer-v8/src/worker/global_scope/bootstrap.rs +++ b/moli-renderer-v8/src/worker/global_scope/bootstrap.rs @@ -204,7 +204,7 @@ pub(in crate::worker) fn install_worker_global_scope<'s>( )?; crate::context_bootstrap::install_worker_indexed_db_runtime_state(scope, global)?; crate::context_bootstrap::install_worker_base64_runtime_state(scope, global)?; - install_simple_event_target_methods(scope, global); + initialize_simple_event_target(scope, global); let script_url = state.borrow().current_script_url.clone(); let origin = script_url diff --git a/moli-renderer-v8/src/worker/global_scope/mod.rs b/moli-renderer-v8/src/worker/global_scope/mod.rs index 83af774e2e..e6073153c4 100644 --- a/moli-renderer-v8/src/worker/global_scope/mod.rs +++ b/moli-renderer-v8/src/worker/global_scope/mod.rs @@ -51,8 +51,8 @@ use super::{ }; use crate::context_bootstrap::WebCryptoTaskResult; use crate::context_bootstrap::{ - WebCryptoRejection, install_simple_event_target_methods, - simple_object_event_listeners_snapshot, simple_object_event_set_handler, + WebCryptoRejection, initialize_simple_event_target, simple_object_event_listeners_snapshot, + simple_object_event_set_handler, }; use crate::network::loads::{ResourceLoadDisposition, ResourceLoadKind, ResourceLoadLease}; use crate::network_host::xhr_has_upload_listeners; diff --git a/moli-renderer-v8/src/worker/global_scope/service_worker_api.rs b/moli-renderer-v8/src/worker/global_scope/service_worker_api.rs index 34043bcb42..42fbe5041c 100644 --- a/moli-renderer-v8/src/worker/global_scope/service_worker_api.rs +++ b/moli-renderer-v8/src/worker/global_scope/service_worker_api.rs @@ -195,7 +195,7 @@ pub(in crate::worker) fn build_service_worker_global_service_worker<'s>( SERVICE_WORKER_VERSION_ID_SLOT, version_id_value.into(), ); - install_simple_event_target_methods(scope, worker); + initialize_simple_event_target(scope, worker); Ok(worker) } diff --git a/moli-renderer-v8/src/worker/thread/tests/event_target_prototype.rs b/moli-renderer-v8/src/worker/thread/tests/event_target_prototype.rs index 0c0ff090e6..6f71e4db0f 100644 --- a/moli-renderer-v8/src/worker/thread/tests/event_target_prototype.rs +++ b/moli-renderer-v8/src/worker/thread/tests/event_target_prototype.rs @@ -1,5 +1,28 @@ use super::*; +#[tokio::test] +async fn worker_interfaces_inherit_canonical_event_target_operations() { + ensure_v8(); + let probe = include_str!("../../../../tests/fixtures/event-target-inheritance.js"); + let mut handle = spawn_worker( + format!( + "{probe}; postMessage({{pending: __eventTargetInheritance.pending, rows: __eventTargetInheritance.rows}}); close();" + ), + "https://event-target-inheritance.test/worker.js".into(), + ); + let message = timeout(TIMEOUT, handle.recv()).await.unwrap().unwrap(); + let result: serde_json::Value = serde_json::from_str(&expect_post_json(message)).unwrap(); + assert_eq!(result["pending"], false); + assert!( + result["rows"] + .as_array() + .unwrap() + .iter() + .all(|row| row[1] == true), + "{result}" + ); +} + #[tokio::test] async fn worker_event_target_prototype_methods_preserve_native_state() { ensure_v8(); diff --git a/moli-renderer-v8/tests/fixtures/event-target-inheritance.js b/moli-renderer-v8/tests/fixtures/event-target-inheritance.js new file mode 100644 index 0000000000..9d296abd9e --- /dev/null +++ b/moli-renderer-v8/tests/fixtures/event-target-inheritance.js @@ -0,0 +1,76 @@ +(() => { + const rows = []; + const methods = ['addEventListener', 'removeEventListener', 'dispatchEvent']; + const check = (condition, label) => { + rows.push([label, !!condition]); + if (!condition) throw Error(label); + }; + const inspect = (target, label) => { + check(target instanceof EventTarget, label + ': native inheritance'); + for (const name of methods) { + check(!Object.hasOwn(target, name), label + ': no own ' + name); + check(target[name] === EventTarget.prototype[name], label + ': inherited ' + name); + } + const calls = []; + function listener(event) { + calls.push(this === target && event.target === target && event.currentTarget === target && + event.composedPath()[0] === target); + event.preventDefault(); + } + target.addEventListener('inheritance-probe', listener, {once: true}); + const event = new Event('inheritance-probe', {cancelable: true}); + check(!target.dispatchEvent(event) && calls.length === 1 && calls[0], label + ': dispatch identity'); + check(target.dispatchEvent(new Event('inheritance-probe')) && calls.length === 1, label + ': once'); + check(event.currentTarget === null && event.composedPath().length === 0, label + ': cleanup'); + const original = EventTarget.prototype.addEventListener; + let inheritedCalls = 0; + try { + EventTarget.prototype.addEventListener = function(...args) { + inheritedCalls++; + return Reflect.apply(original, this, args); + }; + target.addEventListener('inheritance-probe', listener); + check(inheritedCalls === 1, label + ': prototype replacement'); + } finally { + EventTarget.prototype.addEventListener = original; + target.removeEventListener('inheritance-probe', listener); + } + }; + const prototypes = ['EventTarget', 'Performance', 'BroadcastChannel', 'Worker', 'SharedWorker', + 'Notification', 'WebSocket', 'OfflineAudioContext', 'BatteryManager', 'NetworkInformation', + 'ServiceWorkerContainer', 'ServiceWorkerRegistration', 'ServiceWorker', 'Screen', + 'ScreenOrientation', 'Navigation', 'NavigationHistoryEntry', 'IDBRequest', 'IDBDatabase', 'IDBTransaction']; + for (const name of prototypes) { + if (typeof globalThis[name] !== 'function') continue; + const prototype = globalThis[name].prototype; + for (const method of methods) { + check(prototype[method] === EventTarget.prototype[method], name + ': canonical ' + method); + if (name !== 'EventTarget') check(!Object.hasOwn(prototype, method), name + ': no duplicate ' + method); + } + } + inspect(globalThis, 'global'); + inspect(performance, 'performance'); + inspect(new EventTarget(), 'EventTarget'); + inspect(new FileReader(), 'FileReader'); + inspect(new AbortController().signal, 'AbortSignal'); + const channel = new MessageChannel(); + try { inspect(channel.port1, 'MessagePort'); } finally { channel.port1.close(); channel.port2.close(); } + const broadcast = new BroadcastChannel('inheritance-probe'); + try { inspect(broadcast, 'BroadcastChannel'); } finally { broadcast.close(); } + if (typeof window !== 'undefined') { + inspect(navigation, 'navigation'); + if (navigation.currentEntry) inspect(navigation.currentEntry, 'NavigationHistoryEntry'); + inspect(screen, 'screen'); + inspect(screen.orientation, 'screen.orientation'); + inspect(navigator.connection, 'navigator.connection'); + if (navigator.serviceWorker) inspect(navigator.serviceWorker, 'navigator.serviceWorker'); + } + globalThis.__eventTargetInheritance = {rows, pending: false, inspect}; + if (typeof navigator.getBattery === 'function') { + __eventTargetInheritance.pending = true; + navigator.getBattery().then(battery => { + try { inspect(battery, 'battery'); } finally { __eventTargetInheritance.pending = false; } + }, () => { rows.push(['battery: resolved', false]); __eventTargetInheritance.pending = false; }); + } + return true; +})()