synchronize BlazorScriptReload changes

This commit is contained in:
sbwalker
2025-02-14 09:17:44 -05:00
parent c40a483ffa
commit 049ddef531

View File

@ -1,8 +1,8 @@
const scriptKeys = new Set(); const scriptKeys = new Set();
export function onUpdate() { export function onUpdate() {
// determine if this is an enhanced navigation // determine if this is an initial request
let enhancedNavigation = scriptKeys.size !== 0; let initialRequest = scriptKeys.size === 0;
// iterate over all script elements in document // iterate over all script elements in document
const scripts = document.getElementsByTagName('script'); const scripts = document.getElementsByTagName('script');
@ -11,7 +11,7 @@ export function onUpdate() {
if (script.hasAttribute('data-reload')) { if (script.hasAttribute('data-reload')) {
let key = getKey(script); let key = getKey(script);
if (enhancedNavigation) { if (!initialRequest) {
// reload the script if data-reload is "always" or "true"... or if the script has not been loaded previously and data-reload is "once" // reload the script if data-reload is "always" or "true"... or if the script has not been loaded previously and data-reload is "once"
let dataReload = script.getAttribute('data-reload'); let dataReload = script.getAttribute('data-reload');
if ((dataReload === 'always' || dataReload === 'true') || (!scriptKeys.has(key) && dataReload == 'once')) { if ((dataReload === 'always' || dataReload === 'true') || (!scriptKeys.has(key) && dataReload == 'once')) {
@ -40,7 +40,7 @@ function getKey(script) {
function reloadScript(script) { function reloadScript(script) {
try { try {
if (isValid(script)) { if (isValid(script)) {
replaceScript(script); injectScript(script);
} }
} catch (error) { } catch (error) {
console.error(`Blazor Script Reload failed to load script: ${getKey(script)}`, error); console.error(`Blazor Script Reload failed to load script: ${getKey(script)}`, error);
@ -55,16 +55,17 @@ function isValid(script) {
return true; return true;
} }
function replaceScript(script) { function injectScript(script) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var newScript = document.createElement('script'); var newScript = document.createElement('script');
// replicate attributes and content // replicate attributes and content
for (let i = 0; i < script.attributes.length; i++) { for (let i = 0; i < script.attributes.length; i++) {
newScript.setAttribute(script.attributes[i].name, script.attributes[i].value); if (script.attributes[i].name !== 'data-reload') {
newScript.setAttribute(script.attributes[i].name, script.attributes[i].value);
}
} }
newScript.innerHTML = script.innerHTML; newScript.innerHTML = script.innerHTML;
newScript.removeAttribute('data-reload');
// dynamically injected scripts cannot be async or deferred // dynamically injected scripts cannot be async or deferred
newScript.async = false; newScript.async = false;
@ -73,10 +74,10 @@ function replaceScript(script) {
newScript.onload = () => resolve(); newScript.onload = () => resolve();
newScript.onerror = (error) => reject(error); newScript.onerror = (error) => reject(error);
// remove existing script element // inject script element in head to force execution in Blazor
script.remove();
// replace with new script element to force reload in Blazor
document.head.appendChild(newScript); document.head.appendChild(newScript);
// remove data-reload attribute
script.removeAttribute('data-reload');
}); });
} }