Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug(Zone.js): removing capture:true event listener breaks .on* event listeners #54581

Closed
maxpatiiuk opened this issue Feb 22, 2024 · 3 comments
Closed
Assignees
Milestone

Comments

@maxpatiiuk
Copy link

maxpatiiuk commented Feb 22, 2024

Which @angular/* package(s) are the source of the bug?

zone.js

Is this a regression?

Yes

Description

The fix for #31643 introduced a bug

The following code

if (typeof eventName === 'string') {
const onPropertySymbol = ZONE_SYMBOL_PREFIX + 'ON_PROPERTY' + eventName;
target[onPropertySymbol] = null;
}
removes on* property listener when it's not supposed to.
This happens because the code, when checking whether there are no more "capture click" tasks remaining (existingTasks.length === 0), forgets to check whether there are any "non-capture click" tasks present
Though, since on* listeners are non-capturing, maybe this code shouldn't run at all when capture:true events are removed?

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/github-6rdbwr?file=src%2Fmain.ts

Please provide the exception or error you saw

// Make a button
const button = document.createElement('button');
document.body.append(button);

// Set onclick property
button.onclick = () => console.log('onclick!');
console.log(
  'See that onclick prop is set correctly: ',
  (button as any).__zone_symbol__ON_PROPERTYclick
);

// Some unrelated code sets and removes the event listener, WITH CAPTURE:TRUE
button.addEventListener('click', console.log, { capture: true });
button.removeEventListener('click', console.log, { capture: true });

console.log(
  'See that onclick handler was removed (BUG!): ',
  (button as any).__zone_symbol__ON_PROPERTYclick
);
console.log(
  'See that the task still exists:',
  (button as any).__zone_symbol__clickfalse
);

Please provide the environment you discovered this bug in (run ng version)

edit: affects Angular 17 too

(running on Stackblitz, reproducible locally too, even without hot reloading)

@angular/common
16.2.12

@angular/compiler
16.2.12

@angular/core
16.2.12

@angular/platform-browser
16.2.12

@types/jasmine
4.3.6

rxjs
7.8.1

tslib
2.6.2

zone.js
0.13.3

Anything else?

I know that using on* is bad-practice, but it's coming from a library I rely on (for now). The capture:true events being set and removed is also from a library I rely on, so I can't easily remove these preconditions for the bug. As a workaround, I will use element ref to manually add/removeEventListener, but I am sure that there would be other places in my application affected by this bug

cc @JiaLiPassion

@andygup
Copy link

andygup commented Feb 22, 2024

We've also verified this issue exists on version 17.2.2.

@JiaLiPassion JiaLiPassion self-assigned this Feb 25, 2024
JiaLiPassion added a commit to JiaLiPassion/angular that referenced this issue Feb 25, 2024
Close angular#54581

Should not clear `onHandler` when remove capture event listeners.
@JiaLiPassion
Copy link
Contributor

@maxpatiiuk
thank you for reporting the issue and the detail reproduce details, I created a PR to fix this one.

JiaLiPassion added a commit to JiaLiPassion/angular that referenced this issue Feb 27, 2024
Close angular#54581

Should not clear `onHandler` when remove capture event listeners.
@ngbot ngbot bot added this to the needsTriage milestone Feb 27, 2024
dylhunn pushed a commit that referenced this issue Mar 27, 2024
…#54602)

Close #54581

Should not clear `onHandler` when remove capture event listeners.

PR Close #54602
ilirbeqirii pushed a commit to ilirbeqirii/angular that referenced this issue Apr 6, 2024
…angular#54602)

Close angular#54581

Should not clear `onHandler` when remove capture event listeners.

PR Close angular#54602
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Apr 27, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants