diff --git a/moli-renderer-v8/src/native_bridge/context_host/child_documents/bootstrap_commit.rs b/moli-renderer-v8/src/native_bridge/context_host/child_documents/bootstrap_commit.rs index d34b048870..0267ac4a31 100644 --- a/moli-renderer-v8/src/native_bridge/context_host/child_documents/bootstrap_commit.rs +++ b/moli-renderer-v8/src/native_bridge/context_host/child_documents/bootstrap_commit.rs @@ -217,7 +217,7 @@ impl JsContextHost { ChildDocumentCommitResult::from_install(install) } else { self.disconnect_shared_worker_clients_for_child_context(handle); - self.clear_child_window_document_event_state(scope, handle); + self.clear_child_window_event_listeners(handle); self.replace_child_custom_elements_registry_for_document_commit(scope, handle); self.clear_child_browsing_context_current_document(handle); ChildDocumentCommitResult::ready(None) diff --git a/moli-renderer-v8/src/native_bridge/context_host/child_documents/commit.rs b/moli-renderer-v8/src/native_bridge/context_host/child_documents/commit.rs index 6e72fae2c1..6782f67e3c 100644 --- a/moli-renderer-v8/src/native_bridge/context_host/child_documents/commit.rs +++ b/moli-renderer-v8/src/native_bridge/context_host/child_documents/commit.rs @@ -355,7 +355,7 @@ impl JsContextHost { FrameLocalWindowOwnerTransition::Replaced { .. } => { self.disconnect_shared_worker_clients_for_child_context(handle); if !preserve_window_event_state { - self.clear_child_window_document_event_state(scope, handle); + self.clear_child_window_event_listeners(handle); } self.replace_child_custom_elements_registry_for_document_commit(scope, handle); } diff --git a/moli-renderer-v8/src/native_bridge/context_host/child_documents/loads.rs b/moli-renderer-v8/src/native_bridge/context_host/child_documents/loads.rs index 51d3208e24..e21ec9ebab 100644 --- a/moli-renderer-v8/src/native_bridge/context_host/child_documents/loads.rs +++ b/moli-renderer-v8/src/native_bridge/context_host/child_documents/loads.rs @@ -779,7 +779,7 @@ impl JsContextHost { if replaces_existing_document { self.disconnect_shared_worker_clients_for_child_context(handle); } - self.clear_child_window_document_event_state(scope, handle); + self.clear_child_window_event_listeners(handle); self.replace_child_custom_elements_registry_for_document_commit(scope, handle); self.clear_child_browsing_context_current_document(handle); self.clear_pending_service_worker_child_client(handle); diff --git a/moli-renderer-v8/src/native_bridge/context_host/child_events.rs b/moli-renderer-v8/src/native_bridge/context_host/child_events.rs index 0f7a75a040..8eafbab984 100644 --- a/moli-renderer-v8/src/native_bridge/context_host/child_events.rs +++ b/moli-renderer-v8/src/native_bridge/context_host/child_events.rs @@ -1,4 +1,4 @@ -use super::{JsContextHost, child_frame_runtime::WINDOW_EVENT_HANDLER_PROPERTIES}; +use super::JsContextHost; use crate::{ context_bootstrap::{ EVENT_DISPATCHING_SLOT, EVENT_STOP_IMMEDIATE_PROPAGATION_SLOT, EVENT_STOP_PROPAGATION_SLOT, @@ -81,20 +81,6 @@ impl JsContextHost { ChildWindowEventRegistrationId(self.next_child_window_event_registration_id) } - pub(in crate::native_bridge::context_host) fn clear_child_window_document_event_state( - &mut self, - scope: &mut v8::PinScope<'_, '_>, - handle: DomHandle, - ) { - if let Some(window) = self.child_window_proxy_records.live_window(scope, handle) { - let null = v8::null(scope).into(); - for name in WINDOW_EVENT_HANDLER_PROPERTIES { - let _ = window.set(scope, v8str(scope, name).into(), null); - } - } - self.clear_child_window_event_listeners(handle); - } - pub(crate) fn child_window_event_listener_callback_ids( &self, handle: DomHandle, diff --git a/moli-renderer-v8/src/native_bridge/context_host/child_frame_runtime/document.rs b/moli-renderer-v8/src/native_bridge/context_host/child_frame_runtime/document.rs index 0b2246a2c8..8f5c34ab32 100644 --- a/moli-renderer-v8/src/native_bridge/context_host/child_frame_runtime/document.rs +++ b/moli-renderer-v8/src/native_bridge/context_host/child_frame_runtime/document.rs @@ -676,7 +676,7 @@ impl JsContextHost { ), ); - host.clear_child_window_document_event_state(scope, child_handle); + host.clear_child_window_event_listeners(child_handle); host.clear_event_callbacks_for_document_replacement(document_handle, false); for child in children { let _ = remove_child_to_current_reaction_queue( diff --git a/moli-renderer-v8/src/script_vm/tests/browser_api/event_handlers.rs b/moli-renderer-v8/src/script_vm/tests/browser_api/event_handlers.rs index f0686a05cf..d26a29f1e4 100644 --- a/moli-renderer-v8/src/script_vm/tests/browser_api/event_handlers.rs +++ b/moli-renderer-v8/src/script_vm/tests/browser_api/event_handlers.rs @@ -2,6 +2,7 @@ use super::*; mod child_window; mod compilation; +mod document_replacement; mod object_values; mod parser_merged_body; mod popup; diff --git a/moli-renderer-v8/src/script_vm/tests/browser_api/event_handlers/document_replacement.js b/moli-renderer-v8/src/script_vm/tests/browser_api/event_handlers/document_replacement.js index 40c66de4b8..d3e2f52684 100644 --- a/moli-renderer-v8/src/script_vm/tests/browser_api/event_handlers/document_replacement.js +++ b/moli-renderer-v8/src/script_vm/tests/browser_api/event_handlers/document_replacement.js @@ -13,18 +13,31 @@ before[key] === after[key]); } function withWindow(owner, run) { - if (owner !== 'root') throw new Error('unexpected document owner'); - // Finish a replacement stream first so write() starts a destructive stream. - document.open(); - document.close(); - return run(window); + let frame; + let target; + if (owner === 'root') target = window; + else if (owner === 'popup') target = open(); + else { + frame = document.createElement('iframe'); + document.body.appendChild(frame); + target = frame.contentWindow; + } + try { + // Finish a replacement stream first so the write case is destructive. + target.document.open(); + target.document.close(); + return run(target); + } finally { + if (frame) frame.remove(); + if (owner === 'popup') target.close(); + } } function replace(target, operation) { if (operation === 'open') target.document.open(); else target.document.write('replacement'); target.document.close(); } - for (const owner of ['root']) { + for (const owner of ['child', 'popup', 'root']) { for (const operation of ['open', 'write']) { for (const mode of ['native', 'deleted', 'replaced', 'throwing-setter', 'read-only']) { check(`${owner}:${operation}:${mode}`, () => withWindow(owner, target => { @@ -51,7 +64,15 @@ } finally { Object.defineProperty(target, 'onresize', native); } })); } - + check(`${owner}:${operation}:pending-content-cleared`, () => withWindow(owner, target => { + target.document.body.setAttribute('onresize', '}'); + replace(target, operation); + let errors = 0; + try { + target.onerror = () => { ++errors; return true; }; + return target.onresize === null && errors === 0; + } finally { target.onerror = null; } + })); } } const failures = rows.filter(row => !row.pass); diff --git a/moli-renderer-v8/src/script_vm/tests/browser_api/event_handlers/document_replacement.rs b/moli-renderer-v8/src/script_vm/tests/browser_api/event_handlers/document_replacement.rs index ffdaa6c160..14ab6e96e9 100644 --- a/moli-renderer-v8/src/script_vm/tests/browser_api/event_handlers/document_replacement.rs +++ b/moli-renderer-v8/src/script_vm/tests/browser_api/event_handlers/document_replacement.rs @@ -1,7 +1,7 @@ use super::*; #[test] -fn root_document_replacement_clears_native_handlers_without_changing_public_descriptors() { +fn document_replacement_clears_native_handlers_without_changing_public_descriptors() { let mut vm = new_storage_html_test_vm("https://document-handler-cleanup.test/"); vm.eval(include_str!("document_replacement.js")).unwrap(); assert_eq!(