DEV: Refactor stylesheet live-reloading (#13755)

We have had reports of tabs freezing in Firefox, and reporting an error
in this line. I haven't been able to reproduce, but I suspect the
`forEach` loop is at the heart of the issue, so I have replaced it with
(hopefully) a safer call.

* More refactoring
* Do not reload stylesheets with unchanged filenames
* Select last matching stylesheet
This commit is contained in:
Penar Musaraj 2021-07-15 23:43:31 -04:00 committed by GitHub
parent 1cadae3879
commit 207c3085fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -60,12 +60,22 @@ export default {
// Refresh if necessary // Refresh if necessary
document.location.reload(true); document.location.reload(true);
} else if (me.new_href && me.target) { } else if (me.new_href && me.target) {
const link_target = me.theme_id const link_target = !!me.theme_id
? `[data-target="${me.target}"][data-theme-id="${me.theme_id}"]` ? `[data-target='${me.target}'][data-theme-id='${me.theme_id}']`
: `[data-target="${me.target}"]`; : `[data-target='${me.target}']`;
document.querySelectorAll(`link${link_target}`).forEach((link) => {
this.refreshCSS(link, me.new_href); const links = document.querySelectorAll(`link${link_target}`);
}); if (links.length > 0) {
const lastLink = links[links.length - 1];
// this check is useful when message-bus has multiple file updates
// it avoids the browser doing a lot of work for nothing
// should the filenames be unchanged
if (
lastLink.href.split("/").pop() !== me.new_href.split("/").pop()
) {
this.refreshCSS(lastLink, me.new_href);
}
}
} }
}); });
}, },
@ -74,21 +84,14 @@ export default {
}, },
refreshCSS(node, newHref) { refreshCSS(node, newHref) {
if (node.dataset.reloading) {
clearTimeout(node.dataset.timeout);
}
node.dataset.reloading = true;
let reloaded = node.cloneNode(true); let reloaded = node.cloneNode(true);
reloaded.href = newHref; reloaded.href = newHref;
node.insertAdjacentElement("afterend", reloaded); node.insertAdjacentElement("afterend", reloaded);
let timeout = setTimeout(() => { setTimeout(() => {
node.parentNode.removeChild(node); if (node && node.parentNode) {
reloaded.dataset.reloading = false; node.parentNode.removeChild(node);
}, 2000); }
}, 500);
node.dataset.timeout = timeout;
}, },
}; };