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 0c35c759bf..3f81a71198 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 @@ -287,7 +287,7 @@ fn child_document_open_callback<'s>( return; } if child_document_has_throw_on_dynamic_markup_insertion_counter(scope, document) { - throw_dynamic_markup_invalid_state(scope); + throw_dynamic_markup_invalid_state(scope, document); return; } let _ = begin_child_document_stream_replacement(scope, handle, document); @@ -322,7 +322,7 @@ fn child_document_write_or_writeln_callback<'s>( }; let document = args.this(); if child_document_has_throw_on_dynamic_markup_insertion_counter(scope, document) { - throw_dynamic_markup_invalid_state(scope); + throw_dynamic_markup_invalid_state(scope, document); return; } let mut chunk = String::new(); @@ -392,7 +392,7 @@ fn child_document_close_callback<'s>( }; let document = args.this(); if child_document_has_throw_on_dynamic_markup_insertion_counter(scope, document) { - throw_dynamic_markup_invalid_state(scope); + throw_dynamic_markup_invalid_state(scope, document); return; } let Some(host_ptr) = context_host_ptr_from_global_bridge(scope) else { @@ -507,9 +507,15 @@ fn child_document_has_throw_on_dynamic_markup_insertion_counter<'s>( .unwrap_or(false) } -fn throw_dynamic_markup_invalid_state(scope: &mut v8::PinScope<'_, '_>) { +fn throw_dynamic_markup_invalid_state<'s>( + scope: &mut v8::PinScope<'s, '_>, + document: v8::Local<'s, v8::Object>, +) { + let relevant_context = crate::native_bridge::node_relevant_context(scope, document) + .unwrap_or_else(|| scope.get_current_context()); + let relevant_scope = &mut v8::ContextScope::new(scope, relevant_context); throw_dom_exception( - scope, + relevant_scope, "InvalidStateError", 11, "The object is in an invalid state.", diff --git a/moli-renderer-v8/src/script_vm/tests/dom_elements/custom_elements.rs b/moli-renderer-v8/src/script_vm/tests/dom_elements/custom_elements.rs index 09345eb119..1949775166 100644 --- a/moli-renderer-v8/src/script_vm/tests/dom_elements/custom_elements.rs +++ b/moli-renderer-v8/src/script_vm/tests/dom_elements/custom_elements.rs @@ -8268,6 +8268,90 @@ async fn child_document_write_custom_element_reaction_queue_wpt_shape() { assert_eq!(result, expected); } +#[tokio::test(flavor = "current_thread")] +async fn child_dynamic_markup_counter_exceptions_use_document_realm() { + let loader = ResourceRequestClient::new(&moli_fetch::FetchConfig::default()).expect("loader"); + let mut vm = new_page_task_executor_test_vm_with_loader( + "https://dynamic-markup-exception-realm.test/", + &loader, + ); + + vm.eval( + r#" + (() => { + globalThis.__dynamicMarkupExceptionRealm = "pending"; + new Promise((resolve) => { + const frame = document.createElement("iframe"); + frame.srcdoc = ""; + frame.onload = () => resolve(frame.contentWindow); + (document.body || document.documentElement || document).appendChild(frame); + }).then((childWindow) => { + const childDocument = childWindow.document; + childDocument.open(); + const results = []; + class DynamicMarkupProbe extends childWindow.HTMLElement { + constructor() { + super(); + const probe = (label, callback) => { + try { + callback(); + results.push([label, "no throw"]); + } catch (error) { + results.push([ + label, + error.name, + error.code, + error instanceof childWindow.DOMException, + error instanceof DOMException + ]); + } + }; + probe("open", () => childDocument.open()); + probe("open-type", () => childDocument.open("text/html")); + probe("close", () => childDocument.close()); + probe("write", () => childDocument.write("write")); + probe("writeln", () => childDocument.writeln("writeln")); + globalThis.__dynamicMarkupExceptionRealm = JSON.stringify({ + distinctConstructors: childWindow.DOMException !== DOMException, + results + }); + } + } + childWindow.customElements.define( + "dynamic-markup-probe", + DynamicMarkupProbe + ); + childDocument.write( + "