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
}
}
|