another attempt at enforcing script load order
See discussion on 36e20fd110 (commitcomment-62861929)
This commit is contained in:
parent
aaaea03c72
commit
a6c65efd36
@ -59,7 +59,34 @@ export function _queueAction(action: Callback): void {
|
|||||||
_updatingQueue = _updatingQueue.then(action);
|
_updatingQueue = _updatingQueue.then(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setInnerHTML(element: Element, html: string): void {
|
// Setting innerHTML does not evaluate the contents of script tags, so we need
|
||||||
|
// to add them again in order to trigger the download/evaluation. Promise resolves
|
||||||
|
// when download/evaluation has completed.
|
||||||
|
function replaceScript(oldScript: HTMLScriptElement): Promise<void> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const newScript = document.createElement("script");
|
||||||
|
let mustWaitForNetwork = true;
|
||||||
|
if (oldScript.src) {
|
||||||
|
newScript.addEventListener("load", () => resolve());
|
||||||
|
newScript.addEventListener("error", () => resolve());
|
||||||
|
} else {
|
||||||
|
mustWaitForNetwork = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const attribute of oldScript.attributes) {
|
||||||
|
newScript.setAttribute(attribute.name, attribute.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
newScript.appendChild(document.createTextNode(oldScript.innerHTML));
|
||||||
|
oldScript.replaceWith(newScript);
|
||||||
|
|
||||||
|
if (!mustWaitForNetwork) {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setInnerHTML(element: Element, html: string): Promise<void> {
|
||||||
for (const oldVideo of element.getElementsByTagName("video")) {
|
for (const oldVideo of element.getElementsByTagName("video")) {
|
||||||
oldVideo.pause();
|
oldVideo.pause();
|
||||||
|
|
||||||
@ -73,14 +100,7 @@ function setInnerHTML(element: Element, html: string): void {
|
|||||||
element.innerHTML = html;
|
element.innerHTML = html;
|
||||||
|
|
||||||
for (const oldScript of element.getElementsByTagName("script")) {
|
for (const oldScript of element.getElementsByTagName("script")) {
|
||||||
const newScript = document.createElement("script");
|
await replaceScript(oldScript);
|
||||||
|
|
||||||
for (const attribute of oldScript.attributes) {
|
|
||||||
newScript.setAttribute(attribute.name, attribute.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
newScript.appendChild(document.createTextNode(oldScript.innerHTML));
|
|
||||||
oldScript.parentNode!.replaceChild(newScript, oldScript);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,9 +140,9 @@ export async function _updateQA(
|
|||||||
qa.style.opacity = "0";
|
qa.style.opacity = "0";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setInnerHTML(qa, html);
|
await setInnerHTML(qa, html);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setInnerHTML(qa, renderError("html")(error));
|
await setInnerHTML(qa, renderError("html")(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
await _runHook(onUpdateHook);
|
await _runHook(onUpdateHook);
|
||||||
|
Loading…
Reference in New Issue
Block a user