summaryrefslogtreecommitdiff
path: root/source/libs/on-pr-file-load.ts
diff options
context:
space:
mode:
authorGravatar Federico Brigante <github@bfred.it> 2020-01-07 00:19:09 +0700
committerGravatar GitHub <noreply@github.com> 2020-01-07 00:19:09 +0700
commit7f1f2c52d8deeb0fddb7a7322af7dd090ac19461 (patch)
tree6d5aba6a51777875918a609e4fdf2534870169be /source/libs/on-pr-file-load.ts
parentdac2a0302aad5462c3a6b896fc66b18391c73d12 (diff)
downloadrefined-github-7f1f2c52d8deeb0fddb7a7322af7dd090ac19461.tar.gz
refined-github-7f1f2c52d8deeb0fddb7a7322af7dd090ac19461.tar.zst
refined-github-7f1f2c52d8deeb0fddb7a7322af7dd090ac19461.zip
Keep features working after clicking the browser’s Back button (#2639)
Diffstat (limited to 'source/libs/on-pr-file-load.ts')
-rw-r--r--source/libs/on-pr-file-load.ts33
1 files changed, 15 insertions, 18 deletions
diff --git a/source/libs/on-pr-file-load.ts b/source/libs/on-pr-file-load.ts
index b06c8d4a..1c3f3330 100644
--- a/source/libs/on-pr-file-load.ts
+++ b/source/libs/on-pr-file-load.ts
@@ -1,22 +1,19 @@
-import select from 'select-dom';
+import mem from 'mem';
+import delegate, {DelegateSubscription, DelegateEventHandler, DelegateEvent} from 'delegate-it';
-// In PRs' Files tab, some files are loaded progressively later.
-const handlers = new WeakMap<EventListener, EventListener>();
+const fragmentSelector = [
+ 'include-fragment.diff-progressive-loader', // Incremental file loader on scroll
+ 'include-fragment.js-diff-entry-loader' // File diff loader on clicking "Load Diff"
+].join();
-export default function onPrFileLoad(callback: EventListener): void {
- // When a fragment loads, more fragments might be nested in it. The following code avoids duplicate event handlers.
- const recursiveCallback = handlers.get(callback) ?? ((event: Event) => {
- callback(event);
- onPrFileLoad(callback);
- });
- handlers.set(callback, recursiveCallback);
+// This lets you call `onPrFileLoad` multiple times with the same callback but only ever a `load` listener is registered
+const getDeduplicatedHandler = mem((callback: EventListener): DelegateEventHandler => {
+ return (event: DelegateEvent) => event.delegateTarget.addEventListener('load', callback);
+});
- const fragments = select.all([
- 'include-fragment.diff-progressive-loader', // Incremental file loader on scroll
- 'include-fragment.js-diff-entry-loader' // File diff loader on clicking "Load Diff"
- ].join());
-
- for (const fragment of fragments) {
- fragment.addEventListener('load', recursiveCallback);
- }
+export default function onPrFileLoad(callback: EventListener): DelegateSubscription {
+ // `loadstart` is fired when the fragment is still attached so event delegation works.
+ // `load` is fired after it’s detached, so `delegate` would never listen to it.
+ // This is why we listen to a global `loadstart` and then add a specific `load` listener on the element, which is fired even when the element is detached.
+ return delegate(fragmentSelector, 'loadstart', getDeduplicatedHandler(callback), true);
}