88 lines
2.5 KiB
JavaScript
88 lines
2.5 KiB
JavaScript
const scriptInfoBySrc = new Map();
|
|
|
|
function getKey(script) {
|
|
if (script.hasAttribute("src") && script.src !== "") {
|
|
return script.src;
|
|
} else {
|
|
return script.innerHTML;
|
|
}
|
|
}
|
|
|
|
export function onUpdate() {
|
|
let timestamp = Date.now();
|
|
let enhancedNavigation = scriptInfoBySrc.size !== 0;
|
|
|
|
// iterate over all script elements in page
|
|
const scripts = document.getElementsByTagName("script");
|
|
for (const script of scripts) {
|
|
let key = getKey(script);
|
|
let scriptInfo = scriptInfoBySrc.get(key);
|
|
if (!scriptInfo) {
|
|
// new script added
|
|
scriptInfo = { timestamp: timestamp };
|
|
scriptInfoBySrc.set(key, scriptInfo);
|
|
if (enhancedNavigation) {
|
|
reloadScript(script);
|
|
}
|
|
} else {
|
|
// existing script
|
|
scriptInfo.timestamp = timestamp;
|
|
if (script.hasAttribute("data-reload") && script.getAttribute("data-reload") === "true") {
|
|
reloadScript(script);
|
|
}
|
|
}
|
|
}
|
|
|
|
// remove scripts that are no longer referenced
|
|
for (const [key, scriptInfo] of scriptInfoBySrc) {
|
|
if (scriptInfo.timestamp !== timestamp) {
|
|
scriptInfoBySrc.delete(key);
|
|
}
|
|
}
|
|
}
|
|
|
|
function reloadScript(script) {
|
|
try {
|
|
replaceScript(script);
|
|
} catch (error) {
|
|
if (script.hasAttribute("src") && script.src !== "") {
|
|
console.error("Failed to load external script: ${script.src}", error);
|
|
} else {
|
|
console.error("Failed to load inline script: ${script.innerHtml}", error);
|
|
}
|
|
}
|
|
}
|
|
|
|
function replaceScript(script) {
|
|
return new Promise((resolve, reject) => {
|
|
var newScript = document.createElement("script");
|
|
|
|
newScript.async = false;
|
|
if (script.type !== "") {
|
|
newScript.type = script.type;
|
|
}
|
|
|
|
if (script.src !== "") {
|
|
newScript.src = script.src;
|
|
if (script.integrity !== "") {
|
|
newScript.integrity = script.integrity;
|
|
}
|
|
if (script.crossorigin !== "") {
|
|
newScript.crossOrigin = script.crossOrigin;
|
|
}
|
|
} else {
|
|
newScript.innerHTML = script.innerHTML;
|
|
}
|
|
|
|
newScript.onload = () => resolve();
|
|
newScript.onerror = (error) => reject(error);
|
|
|
|
// remove existing newScript script
|
|
script.remove();
|
|
|
|
// replace with new newScript to force reload in Blazor
|
|
document.head.appendChild(newScript);
|
|
});
|
|
}
|
|
|