Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x | import { UiWindow } from "../types/wrapper" /** * MutationObserver for observing URL changes. */ export class UrlObserver { private eventListeners: { [event: string]: ((...args: unknown[]) => void)[] } = {} private mutationObserver: MutationObserver | null private prevPathname: string private uiWindow: UiWindow /** * Constructor for UrlObserver. */ constructor(uiWindow: UiWindow) { this.uiWindow = uiWindow this.prevPathname = this.uiWindow.getWindow().location.pathname this.mutationObserver = null } /** * Attach an event listener for the specified event. * * @param {string} event - The event name. * @param {Function} listener - The event listener function. * @returns {void} */ on(event: string, listener: (...args: unknown[]) => void): void { if (!this.eventListeners[event]) { this.eventListeners[event] = [] } this.eventListeners[event].push(listener) } /** * Emit an event to notify listeners. * * @private * @param {string} event - The event name. * @param {any[]} args - Arguments to pass to the listeners. * @returns {void} */ private emit(event: string, ...args: unknown[]): void { const listeners = this.eventListeners[event] if (listeners) { for (const listener of listeners) { listener(...args) } } } /** * Handle a mutation event. * * @private * @param {MutationRecord[]} mutationsList - A list of MutationRecord objects. * @returns {void} */ private handleMutation(mutationsList: MutationRecord[]): void { for (const mutation of mutationsList) { if (mutation.type !== "childList" && mutation.type !== "attributes") continue const currentPathname = this.uiWindow.getWindow().location.pathname if (currentPathname === this.prevPathname) continue this.prevPathname = currentPathname this.emit("url-mutation") } } /** * Start observing URL changes. * * @public * @returns {void} */ public startObserving(): void { if (this.mutationObserver) return this.mutationObserver = new MutationObserver( (mutationsList: MutationRecord[]) => this.handleMutation(mutationsList) ) this.mutationObserver.observe(this.uiWindow.getDocument().documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ["href"] }) } /** * Stop observing URL changes. * * @public * @returns {void} */ public stopObserving(): void { if (!this.mutationObserver) return this.mutationObserver.disconnect() this.mutationObserver = null } } |