UNPKG

@rx-angular/template

Version:

**Fully** Reactive Component Template Rendering in Angular. @rx-angular/template aims to be a reflection of Angular's built in renderings just reactive.

1 lines 8.15 kB
{"version":3,"file":"template-unpatch.mjs","sources":["../../../../libs/template/unpatch/src/lib/unpatch.directive.ts","../../../../libs/template/unpatch/src/template-unpatch.ts"],"sourcesContent":["import {\n AfterViewInit,\n Directive,\n ElementRef,\n Input,\n OnChanges,\n OnDestroy,\n SimpleChanges,\n} from '@angular/core';\nimport { getZoneUnPatchedApi } from '@rx-angular/cdk/internals/core';\nimport {\n focusEvents,\n inputEvents,\n keyboardEvents,\n mouseEvents,\n touchEvents,\n wheelEvents,\n} from '@rx-angular/cdk/zone-configurations';\nimport { BehaviorSubject, Subscription } from 'rxjs';\n\nconst zonePatchedEvents: string[] = [\n ...focusEvents,\n ...mouseEvents,\n ...wheelEvents,\n ...inputEvents,\n ...keyboardEvents,\n ...touchEvents,\n];\n\n/**\n *\n * @description\n *\n * This function takes an elem and event and re-applies the listeners from the passed event to the\n * passed element with the zone un-patched version of it.\n *\n * @param elem {HTMLElement} - The elem to re-apply the listeners to.\n * @param event {string} - The name of the event from which to re-apply the listeners.\n *\n * @returns void\n */\nexport function unpatchEventListener(\n element: HTMLElement & {\n eventListeners?: (event: string) => EventListenerOrEventListenerObject[];\n },\n event: string\n): EventListenerOrEventListenerObject[] {\n // `EventTarget` is patched only in the browser environment, thus\n // running this code on the server-side will throw an exception:\n // `TypeError: element.eventListeners is not a function`.\n if (typeof element.eventListeners !== 'function') {\n return;\n }\n\n const eventListeners = element.eventListeners(event);\n\n // Return if no event listeners are present\n if (!Array.isArray(eventListeners) || eventListeners.length === 0) {\n return;\n }\n\n const addEventListener = getZoneUnPatchedApi(\n element,\n 'addEventListener'\n ).bind(element) as typeof element.addEventListener;\n\n const listeners: EventListenerOrEventListenerObject[] = [];\n eventListeners.forEach((listener) => {\n // Remove and reapply listeners with patched API\n element.removeEventListener(event, listener);\n // Reapply listeners with un-patched API\n addEventListener(event, listener);\n\n listeners.push(listener);\n });\n\n return listeners;\n}\n\n/**\n * @Directive RxUnpatch\n *\n * @description\n *\n * The `unpatch` directive helps in partially migrating to zone-less apps as well as getting rid\n * of unnecessary renderings through zones `addEventListener` patches.\n * It can be used on any element you apply event bindings.\n *\n * The current way of binding events to the DOM is to use output bindings:\n * ```html\n * <button (click)=\"doStuff($event)\">click me</button>\n * ```\n *\n * The problem is that every event registered over `()` syntax, e.g. `(click)`\n * marks the component and all its ancestors as dirty and re-renders the whole component tree.\n * This is because zone.js patches the native browser API and whenever one of the patched APIs is used it re-renders.\n *\n * So even if your button is not related to a change that needs a re-render the app will re-render completely.\n * This leads to bad performance. This is especially helpful if you work with frequently fired events like 'mousemove'\n *\n * `unpatch` directive solves that problem.\n *\n * Included Features:\n * - by default un-patch all registered listeners of the host it is applied on\n * - un-patch only a specified set of registered event listeners\n * - works zone independent (it directly checks the widow for patched APIs and un-patches them without the use of `runOutsideZone` which brings more performance)\n * - Not interfering with any logic executed by the registered callback\n *\n * @usageNotes\n *\n * The `unpatch` directive can be used like shown here:\n * ```html\n * <button [unpatch] (click)=\"triggerSomeMethod($event)\">click me</button>\n * <button [unpatch]=\"['mousemove']\" (mousemove)=\"doStuff2($event)\" (click)=\"doStuff($event)\">click me</button>\n * ```\n *\n * @publicApi\n */\n@Directive({ selector: '[unpatch]', standalone: true })\nexport class RxUnpatch implements OnChanges, AfterViewInit, OnDestroy {\n /**\n * @description\n * List of events that the element should be unpatched from. When input is empty or undefined,\n * the element is unpatched from all zone-patched events.\n *\n * Full list of zone-patched browser events can be found in\n * [this document](https://github.com/angular/angular/blob/master/packages/zone.js/STANDARD-APIS.md#browser).\n *\n */\n @Input('unpatch') events?: string[];\n\n private subscription = new Subscription();\n private events$ = new BehaviorSubject<string[]>(zonePatchedEvents);\n private listeners = new Map<string, EventListenerOrEventListenerObject[]>();\n\n constructor(private host: ElementRef<HTMLElement>) {}\n\n ngOnChanges({ events }: SimpleChanges): void {\n if (events && Array.isArray(this.events)) {\n this.events$.next(this.events);\n }\n }\n\n ngAfterViewInit(): void {\n this.subscription = this.events$.subscribe((events) => {\n this.reapplyUnPatchedEventListeners(events);\n });\n }\n\n ngOnDestroy() {\n this.subscription.unsubscribe();\n\n for (const [event, listeners = []] of this.listeners) {\n listeners.forEach((listener) => {\n this.host.nativeElement.removeEventListener(event, listener);\n });\n }\n }\n\n private reapplyUnPatchedEventListeners(events: string[]): void {\n for (const event of events) {\n const listeners = unpatchEventListener(this.host.nativeElement, event);\n this.listeners.set(event, listeners);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}