Skip to content

Commit 8104fc2

Browse files
iterianiAndrewKushnir
authored andcommitted
refactor(core): Call stopPropagation and preventDefault unconditionally within the patched methods. (#57354)
This fixes a few tests in g3 and is a bug fix for the event dispatcher. Otherwise, bubbling might continue. PR Close #57354
1 parent 7accd9d commit 8104fc2

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

packages/core/primitives/event-dispatch/src/event_dispatcher.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,10 @@ export class EventDispatcher {
9292

9393
function prepareEventForBubbling(eventInfoWrapper: EventInfoWrapper) {
9494
const event = eventInfoWrapper.getEvent();
95+
const originalStopPropagation = eventInfoWrapper.getEvent().stopPropagation.bind(event);
9596
const stopPropagation = () => {
9697
event[PROPAGATION_STOPPED_SYMBOL] = true;
98+
originalStopPropagation();
9799
};
98100
patchEventInstance(event, 'stopPropagation', stopPropagation);
99101
patchEventInstance(event, 'stopImmediatePropagation', stopPropagation);
@@ -107,9 +109,11 @@ function propagationStopped(eventInfoWrapper: EventInfoWrapper) {
107109
function prepareEventForReplay(eventInfoWrapper: EventInfoWrapper) {
108110
const event = eventInfoWrapper.getEvent();
109111
const target = eventInfoWrapper.getTargetElement();
112+
const originalPreventDefault = event.preventDefault.bind(event);
110113
patchEventInstance(event, 'target', target);
111114
patchEventInstance(event, 'eventPhase', EventPhase.REPLAY);
112115
patchEventInstance(event, 'preventDefault', () => {
116+
originalPreventDefault();
113117
throw new Error(
114118
PREVENT_DEFAULT_ERROR_MESSAGE + (ngDevMode ? PREVENT_DEFAULT_ERROR_MESSAGE_DETAILS : ''),
115119
);

packages/core/test/event_dispatch/event_dispatch_spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,35 @@ describe('event dispatch', () => {
188188
bottomEl.click();
189189
expect(onClickSpy).toHaveBeenCalledTimes(1);
190190
});
191+
it('should call the original stopPropagation method', async () => {
192+
@Component({
193+
standalone: true,
194+
selector: 'app',
195+
template: `
196+
<div id="top" (click)="onClick($event)">
197+
<div id="bottom" (click)="onClick($event)"></div>
198+
</div>
199+
`,
200+
})
201+
class SimpleComponent {
202+
onClick(e: Event) {
203+
e.stopPropagation();
204+
e.preventDefault();
205+
}
206+
}
207+
configureTestingModule([SimpleComponent]);
208+
fixture = TestBed.createComponent(SimpleComponent);
209+
const nativeElement = fixture.debugElement.nativeElement;
210+
const bottomEl = nativeElement.querySelector('#bottom')!;
211+
const event = new MouseEvent('click', {bubbles: true});
212+
spyOn(event, 'stopPropagation');
213+
const stopPropagation = event.stopPropagation;
214+
spyOn(event, 'preventDefault');
215+
const preventDefault = event.preventDefault;
216+
bottomEl.dispatchEvent(event);
217+
expect(stopPropagation).toHaveBeenCalled();
218+
expect(preventDefault).toHaveBeenCalled();
219+
});
191220
});
192221

193222
describe('manual listening', () => {

0 commit comments

Comments
 (0)