mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-25 05:54:25 -04:00
Merge branch 'loadscript-race-condition' into 'main'
fix $loadScript/$loadStylesheet race condition See merge request PronounsPage/PronounsPage!493
This commit is contained in:
commit
09066acb46
@ -80,13 +80,38 @@ const plugin: Plugin = ({ app, store }, inject) => {
|
||||
store.commit('showTranslationMode');
|
||||
}
|
||||
|
||||
const awaitLoadedClass = (node: Element): Promise<void> => {
|
||||
return new Promise((resolve) => {
|
||||
if (node.classList.contains('loaded')) {
|
||||
resolve();
|
||||
} else {
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
const target = mutation.target as Element;
|
||||
if (target.classList.contains('loaded')) {
|
||||
observer.disconnect();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(node, { attributes: true, attributeFilter: ['class'] });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
inject('loadScript', (name: string, src: string, nonce: string | undefined = undefined): Promise<void> => {
|
||||
if (!process.client || document.querySelectorAll(`script.${name}-script`).length > 0) {
|
||||
if (!process.client) {
|
||||
return new Promise((resolve) => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
const existingScriptNode = document.querySelector(`script.${name}-script`);
|
||||
if (existingScriptNode) {
|
||||
return awaitLoadedClass(existingScriptNode);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script');
|
||||
script.setAttribute('src', src);
|
||||
@ -100,6 +125,7 @@ const plugin: Plugin = ({ app, store }, inject) => {
|
||||
resolve();
|
||||
});
|
||||
script.addEventListener('error', (event) => {
|
||||
script.classList.add('loaded'); // not really loaded, but let's stop other calls from waiting forever, see !493
|
||||
reject(new LoadScriptError(name, src, typeof event === 'string' ? event : event.type));
|
||||
});
|
||||
document.body.appendChild(script);
|
||||
@ -107,20 +133,29 @@ const plugin: Plugin = ({ app, store }, inject) => {
|
||||
});
|
||||
|
||||
inject('loadStylesheet', (name: string, src: string): Promise<void> => {
|
||||
if (!process.client || document.querySelectorAll(`link.${name}-stylesheet`).length > 0) {
|
||||
if (!process.client) {
|
||||
return new Promise((resolve) => {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
const existingLinkNode = document.querySelector(`link.${name}-stylesheet`);
|
||||
if (existingLinkNode) {
|
||||
return awaitLoadedClass(existingLinkNode);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const link = document.createElement('link');
|
||||
link.setAttribute('rel', 'stylesheet');
|
||||
link.setAttribute('href', src);
|
||||
link.classList.add(`${name}-stylesheet`);
|
||||
link.crossOrigin = 'true';
|
||||
link.addEventListener('load', () => resolve());
|
||||
link.addEventListener('load', () => {
|
||||
link.classList.add('loaded');
|
||||
resolve();
|
||||
});
|
||||
link.addEventListener('error', (event) => {
|
||||
link.classList.add('loaded'); // not really loaded, but let's stop other calls from waiting forever, see !493
|
||||
reject(new LoadScriptError(name, src, typeof event === 'string' ? event : event.type));
|
||||
});
|
||||
document.body.appendChild(link);
|
||||
|
Loading…
x
Reference in New Issue
Block a user