Fix Trusted Types navigation and fragment history loops
This commit is contained in:
1 parent
1179fc2810
commit
5eae6f3b3c
4 files changed
+62
-6
No files matched your search
@@ -32,6 +32,21 @@ export const NAV_RUNTIME = String.raw`
|
||||
|
||||
window.__wrnexusNavInstalled = true;
|
||||
|
||||
var navigationPolicy = null;
|
||||
if (window.trustedTypes) {
|
||||
try {
|
||||
navigationPolicy = window.trustedTypes.createPolicy("wrnexus-navigation", {
|
||||
createHTML: function (value) { return value; },
|
||||
createScriptURL: function (value) { return value; },
|
||||
});
|
||||
} catch (_) {
|
||||
// A restrictive policy may disallow client navigation. Keep the native
|
||||
// document navigation fallback without weakening the site's CSP.
|
||||
}
|
||||
}
|
||||
|
||||
var renderedRoute = location.pathname + location.search;
|
||||
|
||||
var APP_ID = "app";
|
||||
var inFlight = null;
|
||||
var memory = Object.create(null);
|
||||
@@ -341,7 +356,7 @@ export const NAV_RUNTIME = String.raw`
|
||||
);
|
||||
},
|
||||
);
|
||||
element.src = src;
|
||||
element.src = navigationPolicy ? navigationPolicy.createScriptURL(src) : src;
|
||||
if (!script.hasAttribute("async")) {
|
||||
element.async = false;
|
||||
}
|
||||
@@ -518,7 +533,9 @@ export const NAV_RUNTIME = String.raw`
|
||||
}
|
||||
|
||||
function hardNavigate(url) {
|
||||
location.href = url;
|
||||
var destination = new URL(url, location.href);
|
||||
if (destination.href === location.href) location.reload();
|
||||
else location.href = destination.href;
|
||||
}
|
||||
|
||||
function render(html, url, isPop) {
|
||||
@@ -526,7 +543,7 @@ export const NAV_RUNTIME = String.raw`
|
||||
|
||||
try {
|
||||
doc = new DOMParser().parseFromString(
|
||||
html,
|
||||
navigationPolicy ? navigationPolicy.createHTML(html) : html,
|
||||
"text/html",
|
||||
);
|
||||
} catch (_) {
|
||||
@@ -627,6 +644,8 @@ export const NAV_RUNTIME = String.raw`
|
||||
|
||||
}
|
||||
|
||||
var renderedUrl = new URL(url, location.href);
|
||||
renderedRoute = renderedUrl.pathname + renderedUrl.search;
|
||||
restorePage(url, isPop);
|
||||
|
||||
dispatchNavigationEvent(url);
|
||||
@@ -737,6 +756,10 @@ export const NAV_RUNTIME = String.raw`
|
||||
window.addEventListener(
|
||||
"popstate",
|
||||
function () {
|
||||
// Native fragment navigation also emits popstate. The document is
|
||||
// already rendered: fetching it again loses form edits and can loop
|
||||
// when a rejected render falls back to the same fragment URL.
|
||||
if (location.pathname + location.search === renderedRoute) return;
|
||||
navigate(location.href, true);
|
||||
},
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user