fix(dom): keep child document base URI live

This commit is contained in:
ldm0
2026-09-08 02:00:31 +08:00
parent f9b6254163
commit 4da2e7cb01
2 changed files with 34 additions and 26 deletions
@@ -8,7 +8,7 @@ use crate::native_bridge::{
document::detached_native_handle_for_runtime, node::remove_child_to_current_reaction_queue,
throw_dom_exception,
};
use crate::util::{context_host_ptr_from_global_bridge, set_private_value, v8_string, v8str};
use crate::util::{context_host_ptr_from_global_bridge, set_private_value, v8str};
use moli_webapi_declare::WebApiObject;
use url::Url;
@@ -248,31 +248,6 @@ fn install_child_document_stream_methods<'s>(
child_document_native_handle_for_runtime(scope, runtime_ptr, document)
{
let runtime = unsafe { &mut *runtime_ptr };
let base_url = runtime
.child_browsing_context_base_url(handle)
.map(|base_url| {
if moli_url::is_about_blank(&base_url)
&& runtime
.child_browsing_context_current_url(handle)
.as_ref()
.is_some_and(moli_url::is_about_blank)
&& runtime.child_browsing_context_inherits_parent_origin(handle)
{
runtime.document_base_url_for_child_context(handle)
} else {
base_url
}
});
if let Some(base_url) = base_url
&& let Some(value) = v8_string(scope, base_url.as_str())
{
crate::native_bridge::helpers::set_object_slot(
scope,
document,
"baseURI",
value.into(),
);
}
if !runtime.dom_host().is_connected(document_handle) {
runtime
.dom_host_mut()
@@ -1413,6 +1413,39 @@ fn detached_child_document_anchor_resolves_url_properties() {
"about:blank|https://child-window-anchor.test/path/page.html|[object HTMLAnchorElement]|false|true|true|https://child-window-anchor.test/item?id=1#frag|https:|child-window-anchor.test|child-window-anchor.test||/item|?id=1|#frag|/"
);
}
#[test]
fn child_document_base_uri_tracks_connected_base_href_mutations() {
let mut vm = new_storage_test_vm("https://child-base-uri.test/path/page.html");
let result = vm
.eval(
r#"
(() => {
const frame = document.createElement('iframe');
(document.body || document.documentElement || document).appendChild(frame);
const childDocument = frame.contentDocument;
const base = childDocument.body.appendChild(childDocument.createElement('base'));
const before = childDocument.baseURI;
base.href = 'sub/';
const image = childDocument.createElement('img');
image.src = 'asset.png';
return JSON.stringify({
before,
after: childDocument.baseURI,
image: image.src,
ownsBaseUri: Object.prototype.hasOwnProperty.call(childDocument, 'baseURI')
});
})()
"#,
)
.expect("child document base URL should remain live");
assert_eq!(
result,
r#"{"before":"https://child-base-uri.test/path/page.html","after":"https://child-base-uri.test/path/sub/","image":"https://child-base-uri.test/path/sub/asset.png","ownsBaseUri":false}"#
);
}
#[test]
fn detached_html_elements_use_specific_prototypes_for_common_tags() {
let mut vm = new_storage_test_vm("https://detached-html-element-prototypes.test/");