Skip to content

Commit 958ab10

Browse files
committed
Add cleanup mechanism and debounce observer callbacks.
1 parent c849fff commit 958ab10

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

js/replace-dom.ts

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ import { getRootVariable } from './css-loader';
33
const INTERVAL_MS = 8;
44
const TIMEOUT_MS = 50;
55

6+
interface BaseObject {
7+
id: string;
8+
}
9+
610
interface ImageSrc {
711
light: string;
812
dark: string;
913
}
1014

11-
interface ReplaceImageObject {
12-
id: string;
15+
interface ImageObject extends BaseObject {
1316
src: ImageSrc;
1417
alt: string;
1518
}
@@ -36,10 +39,10 @@ const waitForStyle = (property: string): Promise<string> => {
3639
});
3740
};
3841

39-
const replaceProc = async (replaceImageObjectArray: ReplaceImageObject[]): Promise<void> => {
42+
const replaceProc = async (imageObjectArray: ImageObject[]): Promise<void> => {
4043
const scheme = await waitForStyle('--color-scheme');
4144

42-
for (const x of replaceImageObjectArray) {
45+
for (const x of imageObjectArray) {
4346
const elm = document.getElementById(x.id);
4447

4548
if (elm === null) {
@@ -57,16 +60,32 @@ const replaceProc = async (replaceImageObjectArray: ReplaceImageObject[]): Promi
5760
}
5861
};
5962

60-
export const replaceId = (replaceImageObjectArray: ReplaceImageObject[]): void => {
61-
replaceProc(replaceImageObjectArray);
63+
const debounce = <T extends BaseObject>(fn: (...args: T[]) => void, delay: number): ((...args: T[]) => void) => {
64+
let timeoutId: ReturnType<typeof setTimeout>;
65+
66+
return (...args: T[]) => {
67+
clearTimeout(timeoutId);
68+
timeoutId = setTimeout(() => fn(...args), delay);
69+
};
70+
};
71+
72+
export const replaceId = (imageObjectArray: ImageObject[]): (() => void) => {
73+
replaceProc(imageObjectArray);
74+
75+
const debouncedReplace = debounce(() => replaceProc(imageObjectArray), 150);
6276

6377
const observer = new MutationObserver(mutations => {
6478
for (const x of mutations) {
6579
if (x.attributeName === 'class') {
66-
replaceProc(replaceImageObjectArray);
80+
debouncedReplace();
6781
}
6882
}
6983
});
7084

7185
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
86+
87+
// Cleanup function that can be called when needed
88+
return () => {
89+
observer.disconnect();
90+
};
7291
};

0 commit comments

Comments
 (0)