Runs: Chrome 158.0.8110.0 (wpt@5ffee20ed, 2026-10-17) | Firefox 160.0a1 (wpt@d8b153fad, 2026-10-16) | Safari 254 preview (wpt@51a43ba4a, 2026-10-17) | Ladybird 1.0-401b1 (wpt@470a7adf8, 2026-10-17) | Servo Servo 0.7 (wpt@df642c414, 2026-10-17) | Blitz fb8d6c15e (wpt@cd1d8aa5b, 2026-10-17)
| Chrome | Firefox | Safari | Ladybird | Servo | Blitz | |
|---|---|---|---|---|---|---|
| Total | 1/1 | 1/1 | 1/1 | 1/1 | 0/1 | NOT RUN |
| Subtest | Chrome | Firefox | Safari | Ladybird | Servo | Blitz |
|---|---|---|---|---|---|---|
| Removing the element from the default policy during the pre-navigation check of its javascript: URL src should not fire a load event at it. | PASS | PASS | PASS | PASS | FAIL | — |
/trusted-types/navigate-to-javascript-url-009.html
<!DOCTYPE html> <meta name="variant" content="?iframe"> <meta name="variant" content="?frame"> <meta http-equiv="Content-Security-Policy" content="require-trusted-types-for 'script'"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script> // A javascript: URL in the src attribute of a freshly inserted iframe or frame // is navigated to with initialInsertion set to true, which is the one case // where "navigate to a javascript: URL" fires a load event at the container // when no Document is produced. The default policy runs author code in the // middle of that algorithm, so it can remove the element first, leaving the // navigable without a container to fire the load event at. // // navigate-to-javascript-url-007-crash.html covers the same re-entrancy for a // window.location navigation, where initialInsertion is false and this branch // is not reached. promise_test(async _ => { let javaScriptExecuted = false; window.executeJavaScript = _ => { javaScriptExecuted = true; }; let loadEvents = 0; const element = document.createElement(location.search.substring(1)); element.addEventListener("load", _ => { loadEvents++; }); element.src = "javascript:parent.executeJavaScript()"; document.head.appendChild(element); // The policy container of the synthetic request is snapshotted from the // document that inserted the element, but the element's initial about:blank // document inherits the same CSP, so install the default policy on both to // keep the test independent of which global the pre-navigation check // consults. See https://github.com/w3c/trusted-types/issues/548. const removeElement = { createScript: s => { element.remove(); return s; } }; trustedTypes.createPolicy("default", removeElement); element.contentWindow.trustedTypes.createPolicy("default", removeElement); // Wait for the queued navigation task to have run. if (window.requestIdleCallback) { await new Promise(resolve => requestIdleCallback(resolve)); } else { await new Promise(resolve => requestAnimationFrame(_ => requestAnimationFrame(resolve))); } assert_false(javaScriptExecuted, "JavaScript shouldn't have been executed"); assert_equals(loadEvents, 0, "No load event should be fired at the removed element"); }, "Removing the element from the default policy during the pre-navigation check of its javascript: URL src should not fire a load event at it."); </script>