mirror of
https://github.com/lexmount/moli.git
synced 2026-10-31 00:06:19 +00:00
fix(html): retain meta refresh inserted by load callbacks
Keep the pre-load registration that preserves refreshes across meta adoption,
and also scan after owner load callbacks when no refresh is armed. This retains
support for callbacks that insert a new refresh without canceling the original
document's refresh when its element was moved or removed.
Add deterministic Window-load and iframe-load insertion tests. Both fail before
this fix, and the full Release WPT probe also exposed dynamic-append.html timing
out at 7e79f9c154a; that incomplete validation was stopped before Cases refresh.
Fixes: 7e79f9c154 (fix(html): arm child meta refresh before load callbacks)
Validation:
- cargo fmt --all
- cargo clippy --workspace --all-targets --all-features -- -D warnings
- cargo nextest run --no-fail-fast
This commit is contained in:
@@ -453,6 +453,11 @@ impl JsContextHost {
|
||||
self.trace_stale_child_load_delivery(action, "owner_element_load");
|
||||
return ChildFrameLoadDeliveryPhaseResult::after_callback(None);
|
||||
}
|
||||
// Load callbacks may insert a new refresh, but must not cancel an
|
||||
// existing document-owned refresh by moving its meta element away.
|
||||
if !self.child_meta_refresh_navigations.contains_key(&handle) {
|
||||
self.queue_child_meta_refresh_navigation_if_needed(scope, handle);
|
||||
}
|
||||
ChildFrameLoadDeliveryPhaseResult::after_callback(progress)
|
||||
}
|
||||
|
||||
|
||||
+55
@@ -1358,6 +1358,61 @@ async fn detached_child_navigation_error_exposes_committed_entry_during_dispatch
|
||||
"committed:true|error:true:true:AbortError|finished-rejected:AbortError||true"
|
||||
);
|
||||
}
|
||||
async fn assert_child_meta_refresh_can_be_inserted_during_load(in_window_load: bool) {
|
||||
let loader = ResourceRequestClient::new(&moli_fetch::FetchConfig::default()).expect("loader");
|
||||
let mut vm = new_storage_test_vm_with_loader("https://child-meta-refresh.test/", &loader);
|
||||
vm.eval(&format!(
|
||||
"globalThis.insertInWindowLoad = {in_window_load};"
|
||||
))
|
||||
.unwrap();
|
||||
vm.eval(
|
||||
r#"
|
||||
const root = document.documentElement || document.appendChild(document.createElement('html'));
|
||||
const frame = document.createElement('iframe');
|
||||
frame.onload = () => {
|
||||
if (!insertInWindowLoad) {
|
||||
frame.contentDocument.body.innerHTML = '<meta http-equiv="refresh" content="0;url=about:srcdoc#dynamic">';
|
||||
}
|
||||
};
|
||||
frame.srcdoc = `<script>
|
||||
onload = () => {
|
||||
if (parent.insertInWindowLoad) {
|
||||
document.body.innerHTML = '<meta http-equiv="refresh" content="0;url=about:srcdoc#dynamic">';
|
||||
}
|
||||
};
|
||||
<\/script><p>source</p>`;
|
||||
root.appendChild(frame);
|
||||
'queued'
|
||||
"#,
|
||||
)
|
||||
.expect("dynamic child refresh setup should evaluate");
|
||||
vm.drain_pending_child_frame_work_for_test();
|
||||
assert_eq!(
|
||||
vm.eval("String(frame.contentDocument.querySelectorAll('meta').length)")
|
||||
.unwrap(),
|
||||
"1",
|
||||
"the load callback should insert the refresh element",
|
||||
);
|
||||
vm.advance_timers_until_deadline_for_test(&loader)
|
||||
.await
|
||||
.expect("dynamically inserted refresh should run");
|
||||
assert_eq!(
|
||||
vm.eval("frame.contentWindow.location.href").unwrap(),
|
||||
"about:srcdoc#dynamic",
|
||||
"a refresh inserted by a load callback must be scheduled",
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn child_meta_refresh_can_be_inserted_in_window_load_callback() {
|
||||
assert_child_meta_refresh_can_be_inserted_during_load(true).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn child_meta_refresh_can_be_inserted_in_owner_load_callback() {
|
||||
assert_child_meta_refresh_can_be_inserted_during_load(false).await;
|
||||
}
|
||||
|
||||
async fn assert_child_meta_refresh_survives_adoption_during_load(source_loads_first: bool) {
|
||||
let loader = ResourceRequestClient::new(&moli_fetch::FetchConfig::default()).expect("loader");
|
||||
let mut vm = new_storage_test_vm_with_loader("https://child-meta-refresh.test/", &loader);
|
||||
|
||||
Reference in New Issue
Block a user