mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
fix(core): Account for addEventListener to be passed a Window or Document. (#57282)
This happened to work for other event listeners since both had a addEventListener method. PR Close #57282
This commit is contained in:
parent
5401332b0e
commit
e39b22a932
2 changed files with 49 additions and 7 deletions
|
|
@ -93,15 +93,25 @@ export class GlobalEventDelegation implements OnDestroy {
|
|||
return isEarlyEventType(eventType);
|
||||
}
|
||||
|
||||
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
|
||||
this.eventContractDetails.instance!.addEvent(eventName);
|
||||
sharedStashFunction(element, eventName, handler);
|
||||
getActionCache(element)[eventName] = '';
|
||||
return () => this.removeEventListener(element, eventName, handler);
|
||||
addEventListener(element: HTMLElement, eventType: string, handler: Function): Function {
|
||||
// Note: contrary to the type, Window and Document can be passed in
|
||||
// as well.
|
||||
if (element.nodeType === Node.ELEMENT_NODE) {
|
||||
this.eventContractDetails.instance!.addEvent(eventType);
|
||||
getActionCache(element)[eventType] = '';
|
||||
sharedStashFunction(element, eventType, handler);
|
||||
} else {
|
||||
element.addEventListener(eventType, handler as EventListener);
|
||||
}
|
||||
return () => this.removeEventListener(element, eventType, handler);
|
||||
}
|
||||
|
||||
removeEventListener(element: HTMLElement, eventType: string, callback: Function): void {
|
||||
getActionCache(element)[eventType] = undefined;
|
||||
if (element.nodeType === Node.ELEMENT_NODE) {
|
||||
getActionCache(element)[eventType] = undefined;
|
||||
} else {
|
||||
element.removeEventListener(eventType, callback as EventListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,13 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Component, Renderer2, inject, ɵprovideGlobalEventDelegation} from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
HostListener,
|
||||
Renderer2,
|
||||
inject,
|
||||
ɵprovideGlobalEventDelegation,
|
||||
} from '@angular/core';
|
||||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
function configureTestingModule(components: unknown[]) {
|
||||
|
|
@ -216,5 +222,31 @@ describe('event dispatch', () => {
|
|||
bottomEl.click();
|
||||
expect(onClickSpy).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
it('should allow host listening on the window', async () => {
|
||||
const onClickSpy = jasmine.createSpy();
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'app',
|
||||
template: `
|
||||
<div id="top">
|
||||
<div id="bottom"></div>
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
class SimpleComponent {
|
||||
renderer = inject(Renderer2);
|
||||
destroy!: Function;
|
||||
@HostListener('window:click', ['$event.target'])
|
||||
listen(el: Element) {
|
||||
onClickSpy();
|
||||
}
|
||||
}
|
||||
configureTestingModule([SimpleComponent]);
|
||||
fixture = TestBed.createComponent(SimpleComponent);
|
||||
const nativeElement = fixture.debugElement.nativeElement;
|
||||
const bottomEl = nativeElement.querySelector('#bottom')!;
|
||||
bottomEl.click();
|
||||
expect(onClickSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue