Skip to content

Commit

Permalink
feat: use AbortController to remove/abort events (#1136)
Browse files Browse the repository at this point in the history
  • Loading branch information
SalmenBejaoui authored Jan 31, 2025
1 parent 1ed7586 commit 7b66758
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 64 deletions.
7 changes: 5 additions & 2 deletions docs/src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function ThemeWatcher() {
let { resolvedTheme, setTheme } = useTheme();

useEffect(() => {
const controller = new AbortController();
let media = window.matchMedia("(prefers-color-scheme: dark)");

function onMediaChange() {
Expand All @@ -28,10 +29,12 @@ function ThemeWatcher() {
}

onMediaChange();
media.addEventListener("change", onMediaChange);
media.addEventListener("change", onMediaChange, {
signal: controller.signal,
});

return () => {
media.removeEventListener("change", onMediaChange);
controller.abort();
};
}, [resolvedTheme, setTheme]);

Expand Down
8 changes: 6 additions & 2 deletions docs/src/components/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -297,17 +297,21 @@ function SearchDialog({
return;
}

const controller = new AbortController();

function onKeyDown(event: KeyboardEvent) {
if (event.key === "k" && (event.metaKey || event.ctrlKey)) {
event.preventDefault();
setOpen(true);
}
}

window.addEventListener("keydown", onKeyDown);
window.addEventListener("keydown", onKeyDown, {
signal: controller.signal,
});

return () => {
window.removeEventListener("keydown", onKeyDown);
controller.abort();
};
}, [open, setOpen]);

Expand Down
13 changes: 9 additions & 4 deletions docs/src/components/SectionProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,19 @@ function useVisibleSections(sectionStore: StoreApi<SectionState>) {
setVisibleSections(newVisibleSections);
}

const controller = new AbortController();
let raf = window.requestAnimationFrame(() => checkVisibleSections());
window.addEventListener("scroll", checkVisibleSections, { passive: true });
window.addEventListener("resize", checkVisibleSections);
window.addEventListener("scroll", checkVisibleSections, {
passive: true,
signal: controller.signal,
});
window.addEventListener("resize", checkVisibleSections, {
signal: controller.signal,
});

return () => {
window.cancelAnimationFrame(raf);
window.removeEventListener("scroll", checkVisibleSections);
window.removeEventListener("resize", checkVisibleSections);
controller.abort();
};
}, [setVisibleSections, sections]);
}
Expand Down
21 changes: 15 additions & 6 deletions packages/react/src/components/dropzone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -450,9 +450,12 @@ export function useDropzone({
}
};

window.addEventListener("focus", onWindowFocus, false);
const controller = new AbortController();
window.addEventListener("focus", onWindowFocus, {
signal: controller.signal,
});
return () => {
window.removeEventListener("focus", onWindowFocus, false);
controller.abort();
};
}, [state.isFileDialogActive]);

Expand All @@ -466,13 +469,19 @@ export function useDropzone({
};
const onDocumentDragOver = (e: Pick<Event, "preventDefault">) =>
e.preventDefault();
const controller = new AbortController();

document.addEventListener("dragover", onDocumentDragOver, false);
document.addEventListener("drop", onDocumentDrop, false);
document.addEventListener("dragover", onDocumentDragOver, {
capture: false,
signal: controller.signal,
});
document.addEventListener("drop", onDocumentDrop, {
capture: false,
signal: controller.signal,
});

return () => {
document.removeEventListener("dragover", onDocumentDragOver);
document.removeEventListener("drop", onDocumentDrop);
controller.abort();
};
}, []);

Expand Down
7 changes: 5 additions & 2 deletions packages/react/src/utils/usePaste.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ export const usePaste = (callback: PasteCallback) => {
const stableCallback = useEvent(callback);

useEffect(() => {
window.addEventListener("paste", stableCallback);
const controller = new AbortController();
window.addEventListener("paste", stableCallback, {
signal: controller.signal,
});
return () => {
window.removeEventListener("paste", stableCallback);
controller.abort();
};
}, [stableCallback]);
};
7 changes: 5 additions & 2 deletions packages/solid/src/components/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ export function UploadButton<
createEffect(() => {
if (!appendOnPaste) return;

const controller = new AbortController();
const pasteHandler = (e: ClipboardEvent) => {
if (document.activeElement !== inputRef) return;

Expand All @@ -168,9 +169,11 @@ export function UploadButton<

if (mode === "auto") uploadFiles(files());
};
document.addEventListener("paste", pasteHandler);
document.addEventListener("paste", pasteHandler, {
signal: controller.signal,
});

onCleanup(() => document.removeEventListener("paste", pasteHandler));
onCleanup(() => controller.abort());
});

const styleFieldArg = {
Expand Down
29 changes: 21 additions & 8 deletions packages/solid/src/components/dropzone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ export const UploadDropzone = <
createEffect(() => {
if (!appendOnPaste) return;

const controller = new AbortController();
const pasteHandler = (e: ClipboardEvent) => {
if (document.activeElement !== rootRef) return;

Expand All @@ -212,10 +213,12 @@ export const UploadDropzone = <

if (mode === "auto") uploadFiles(files());
};
document.addEventListener("paste", pasteHandler);
document.addEventListener("paste", pasteHandler, {
signal: controller.signal,
});

onCleanup(() => {
document.removeEventListener("paste", pasteHandler);
controller.abort();
});
});

Expand Down Expand Up @@ -371,6 +374,7 @@ export function createDropzone(_props: DropzoneOptions) {
const [state, setState] = createStore(initialState);

createEffect(() => {
const controller = new AbortController();
const onWindowFocus = () => {
if (state.isFileDialogActive) {
setTimeout(() => {
Expand All @@ -386,13 +390,17 @@ export function createDropzone(_props: DropzoneOptions) {
}
};

window.addEventListener("focus", onWindowFocus, false);
window.addEventListener("focus", onWindowFocus, {
capture: false,
signal: controller.signal,
});
onCleanup(() => {
window.removeEventListener("focus", onWindowFocus, false);
controller.abort();
});
});

createEffect(() => {
const controller = new AbortController();
const onDocumentDrop = (event: DropEvent) => {
const root = rootRef();

Expand All @@ -406,12 +414,17 @@ export function createDropzone(_props: DropzoneOptions) {
const onDocumentDragOver = (e: Pick<Event, "preventDefault">) =>
e.preventDefault();

document.addEventListener("dragover", onDocumentDragOver, false);
document.addEventListener("drop", onDocumentDrop, false);
document.addEventListener("dragover", onDocumentDragOver, {
capture: false,
signal: controller.signal,
});
document.addEventListener("drop", onDocumentDrop, {
capture: false,
signal: controller.signal,
});

onCleanup(() => {
document.removeEventListener("dragover", onDocumentDragOver, false);
document.removeEventListener("drop", onDocumentDrop, false);
controller.abort();
});
});

Expand Down
5 changes: 3 additions & 2 deletions packages/svelte/src/lib/component/UploadButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
})();
onMount(() => {
const controller = new AbortController()
const handlePaste = (event: ClipboardEvent) => {
if (!appendOnPaste) return;
// eslint-disable-next-line no-undef
Expand All @@ -123,10 +124,10 @@
if (mode === "auto") uploadFiles(files);
};
// eslint-disable-next-line no-undef
document.addEventListener("paste", handlePaste);
document.addEventListener("paste", handlePaste, { signal: controller.signal });
// eslint-disable-next-line no-undef
return () => document.removeEventListener("paste", handlePaste);
return () => controller.abort();
});
$: styleFieldArg = {
Expand Down
7 changes: 5 additions & 2 deletions packages/svelte/src/lib/component/UploadDropzone.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@
onMount(() => {
if (!appendOnPaste) return;
const controller = new AbortController()
const handlePaste = (event: ClipboardEvent) => {
// eslint-disable-next-line no-undef
if (document.activeElement !== rootRef) return;
Expand All @@ -172,10 +173,12 @@
if (mode === "auto") uploadFiles(files);
};
// eslint-disable-next-line no-undef
document.addEventListener("paste", handlePaste);
document.addEventListener("paste", handlePaste, {
signal: controller.signal
});
// eslint-disable-next-line no-undef
return () => document.removeEventListener("paste", handlePaste);
return () => controller.abort();
});
$: styleFieldArg = {
Expand Down
68 changes: 42 additions & 26 deletions packages/svelte/src/lib/component/create-dropzone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export function createDropzone(_props: DropzoneOptions) {
const [state, dispatch] = reducible(reducer, initialState);

onMount(() => {
const controller = new AbortController();
const onWindowFocus = () => {
if (get(state).isFileDialogActive) {
setTimeout(() => {
Expand All @@ -66,14 +67,18 @@ export function createDropzone(_props: DropzoneOptions) {
}, 300);
}
};
window.addEventListener("focus", onWindowFocus, false);
window.addEventListener("focus", onWindowFocus, {
capture: false,
signal: controller.signal,
});

return () => {
window.removeEventListener("focus", onWindowFocus, false);
controller.abort();
};
});

onMount(() => {
const controller = new AbortController();
const onDocumentDrop = (event: DropEvent) => {
const root = get(rootRef);
if (root?.contains(event.target as Node)) {
Expand All @@ -87,12 +92,17 @@ export function createDropzone(_props: DropzoneOptions) {
const onDocumentDragOver = (e: Pick<Event, "preventDefault">) =>
e.preventDefault();

document.addEventListener("dragover", onDocumentDragOver, false);
document.addEventListener("drop", onDocumentDrop, false);
document.addEventListener("dragover", onDocumentDragOver, {
capture: false,
signal: controller.signal,
});
document.addEventListener("drop", onDocumentDrop, {
capture: false,
signal: controller.signal,
});

return () => {
document.removeEventListener("dragover", onDocumentDragOver, false);
document.removeEventListener("drop", onDocumentDrop, false);
controller.abort();
};
});

Expand Down Expand Up @@ -270,30 +280,32 @@ export function createDropzone(_props: DropzoneOptions) {
// We should be able to refactor this when svelte 5 is released to bring it more inline
// with the rest of the dropzone implementations
const dropzoneRoot: Action<HTMLElement> = (node) => {
const controller = new AbortController();
rootRef.set(node);
node.setAttribute("role", "presentation");
if (!get(props).disabled) {
node.setAttribute("tabindex", "0");
node.addEventListener("keydown", onKeyDown);
node.addEventListener("focus", onFocus);
node.addEventListener("blur", onBlur);
node.addEventListener("click", onClick);
node.addEventListener("dragenter", onDragEnter);
node.addEventListener("dragover", onDragOver);
node.addEventListener("dragleave", onDragLeave);
node.addEventListener("drop", onDropCb);
node.addEventListener("keydown", onKeyDown, {
signal: controller.signal,
});
node.addEventListener("focus", onFocus, { signal: controller.signal });
node.addEventListener("blur", onBlur, { signal: controller.signal });
node.addEventListener("click", onClick, { signal: controller.signal });
node.addEventListener("dragenter", onDragEnter, {
signal: controller.signal,
});
node.addEventListener("dragover", onDragOver, {
signal: controller.signal,
});
node.addEventListener("dragleave", onDragLeave, {
signal: controller.signal,
});
node.addEventListener("drop", onDropCb, { signal: controller.signal });
}
return {
destroy() {
rootRef.set(null);
node.removeEventListener("keydown", onKeyDown);
node.removeEventListener("focus", onFocus);
node.removeEventListener("blur", onBlur);
node.removeEventListener("click", onClick);
node.removeEventListener("dragenter", onDragEnter);
node.removeEventListener("dragover", onDragOver);
node.removeEventListener("dragleave", onDragLeave);
node.removeEventListener("drop", onDropCb);
controller.abort();
},
};
};
Expand All @@ -303,6 +315,7 @@ export function createDropzone(_props: DropzoneOptions) {
node,
options: DropzoneOptions,
) => {
const controller = new AbortController();
inputRef.set(node);
node.style.display = "none";
node.setAttribute("type", "file");
Expand All @@ -313,8 +326,12 @@ export function createDropzone(_props: DropzoneOptions) {
safeSetAttribute(node, "accept", accept);
});

node.addEventListener("change", onDropCb);
node.addEventListener("click", onInputElementClick);
node.addEventListener("change", onDropCb, {
signal: controller.signal,
});
node.addEventListener("click", onInputElementClick, {
signal: controller.signal,
});

return {
update(options: DropzoneOptions) {
Expand All @@ -325,8 +342,7 @@ export function createDropzone(_props: DropzoneOptions) {
destroy() {
inputRef.set(null);
acceptAttrUnsub();
node.removeEventListener("change", onDropCb);
node.removeEventListener("click", onInputElementClick);
controller.abort();
},
};
};
Expand Down
Loading

0 comments on commit 7b66758

Please sign in to comment.