Clean up dynamically inserted assets when template is unmounted #274
This commit is contained in:
@ -15,7 +15,7 @@ export function usePrepareTemplate(params: {
|
|||||||
htmlClassName: string | undefined;
|
htmlClassName: string | undefined;
|
||||||
bodyClassName: string | undefined;
|
bodyClassName: string | undefined;
|
||||||
}) {
|
}) {
|
||||||
const { doFetchDefaultThemeResources, stylesCommon, styles, url, scripts, htmlClassName, bodyClassName } = params;
|
const { doFetchDefaultThemeResources, stylesCommon = [], styles = [], url, scripts = [], htmlClassName, bodyClassName } = params;
|
||||||
|
|
||||||
const [isReady, setReady] = useReducer(() => true, !doFetchDefaultThemeResources);
|
const [isReady, setReady] = useReducer(() => true, !doFetchDefaultThemeResources);
|
||||||
|
|
||||||
@ -26,36 +26,49 @@ export function usePrepareTemplate(params: {
|
|||||||
|
|
||||||
let isUnmounted = false;
|
let isUnmounted = false;
|
||||||
|
|
||||||
Promise.all(
|
const removeArray: (() => void)[] = [];
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const prLoadedArray: Promise<void>[] = [];
|
||||||
|
|
||||||
[
|
[
|
||||||
...(stylesCommon ?? []).map(relativePath => pathJoin(url.resourcesCommonPath, relativePath)),
|
...stylesCommon.map(relativePath => pathJoin(url.resourcesCommonPath, relativePath)),
|
||||||
...(styles ?? []).map(relativePath => pathJoin(url.resourcesPath, relativePath))
|
...styles.map(relativePath => pathJoin(url.resourcesPath, relativePath))
|
||||||
]
|
]
|
||||||
.reverse()
|
.reverse()
|
||||||
.map(href =>
|
.forEach(href => {
|
||||||
headInsert({
|
const { prLoaded, remove } = headInsert({
|
||||||
"type": "css",
|
"type": "css",
|
||||||
href,
|
"position": "prepend",
|
||||||
"position": "prepend"
|
href
|
||||||
})
|
});
|
||||||
)
|
|
||||||
).then(() => {
|
removeArray.push(remove);
|
||||||
|
|
||||||
|
prLoadedArray.push(prLoaded);
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.all(prLoadedArray);
|
||||||
|
|
||||||
if (isUnmounted) {
|
if (isUnmounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setReady();
|
setReady();
|
||||||
});
|
})();
|
||||||
|
|
||||||
(scripts ?? []).forEach(relativePath =>
|
scripts.forEach(relativePath => {
|
||||||
headInsert({
|
const { remove } = headInsert({
|
||||||
"type": "javascript",
|
"type": "javascript",
|
||||||
"src": pathJoin(url.resourcesPath, relativePath)
|
"src": pathJoin(url.resourcesPath, relativePath)
|
||||||
})
|
});
|
||||||
);
|
|
||||||
|
removeArray.push(remove);
|
||||||
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
isUnmounted = true;
|
isUnmounted = true;
|
||||||
|
removeArray.forEach(remove => remove());
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -22,17 +22,24 @@ export default function LoginOtp(props: PageProps<Extract<KcContext, { pageId: "
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let isCleanedUp = false;
|
let isCleanedUp = false;
|
||||||
|
|
||||||
headInsert({
|
const { prLoaded, remove } = headInsert({
|
||||||
"type": "javascript",
|
"type": "javascript",
|
||||||
"src": pathJoin(kcContext.url.resourcesCommonPath, "node_modules/jquery/dist/jquery.min.js")
|
"src": pathJoin(kcContext.url.resourcesCommonPath, "node_modules/jquery/dist/jquery.min.js")
|
||||||
}).then(() => {
|
});
|
||||||
if (isCleanedUp) return;
|
|
||||||
|
(async () => {
|
||||||
|
await prLoaded;
|
||||||
|
|
||||||
|
if (isCleanedUp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
evaluateInlineScript();
|
evaluateInlineScript();
|
||||||
});
|
})();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
isCleanedUp = true;
|
isCleanedUp = true;
|
||||||
|
remove();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ export function headInsert(
|
|||||||
type: "javascript";
|
type: "javascript";
|
||||||
src: string;
|
src: string;
|
||||||
}
|
}
|
||||||
) {
|
): { remove: () => void; prLoaded: Promise<void> } {
|
||||||
const htmlElement = document.createElement(
|
const htmlElement = document.createElement(
|
||||||
(() => {
|
(() => {
|
||||||
switch (params.type) {
|
switch (params.type) {
|
||||||
@ -66,5 +66,8 @@ export function headInsert(
|
|||||||
})()
|
})()
|
||||||
](htmlElement);
|
](htmlElement);
|
||||||
|
|
||||||
return dLoaded.pr;
|
return {
|
||||||
|
"prLoaded": dLoaded.pr,
|
||||||
|
"remove": () => htmlElement.remove()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user