angular / zone.js

Implements Zones for JavaScript
https://github.com/angular/angular/tree/master/packages/zone.js/
MIT License
3.25k stars 408 forks source link

Calling `EventTarget.removeEventListener` twice causes errors #283

Closed sjelin closed 8 years ago

sjelin commented 8 years ago

Consider the following code snippet:

var elem = document.body;
var listener = function (event) {};
elem.addEventListener('click', listener, false);
elem.removeEventListener('click', listener, false);
elem.removeEventListener('click', listener, false);

According to the DOM spec, the second removeEventListener should do nothing. However, with zone.js loaded it produces the following error message:

    Error: Task does not support cancellation, or is already canceled.
        at ZoneDelegate.cancelTask (/usr/local/google/home/sjelin/zone.js/test/browser_entry_point.ts:382:24)
        at Zone.cancelTask (/usr/local/google/home/sjelin/zone.js/test/browser_entry_point.ts:292:45)
        at zoneAwareRemoveEventListener (/usr/local/google/home/sjelin/zone.js/test/browser_entry_point.ts:970:25)
        at HTMLBodyElement.removeEventListener (eval at createNamedFn (/usr/local/google/home/sjelin/zone.js/test/browser_entry_point.ts:1051:18), <anonymous>:3:46)
        at Object.<anonymous> (/usr/local/google/home/sjelin/zone.js/test/browser_entry_point.ts:2354:19)

Basically, the problem is that the patched removeEventListener will cancel the task, but never removes it from the list of registered tasks. So when the second removeEventListener happens it tries to cancel the task again, leading to the problem. I suggest we start removing it from the list of registered tasks, unless there is a reason it has to stay there.

mhevery commented 8 years ago

Sounds good to me.

arsenys commented 8 years ago

I have the exactly the same problem. I have an Angular2 app with Semantic-UI. After upgrading zone.js from 0.5.x to 0.6.x almost every Semantic-UI component, such as modal window or dropdown throws the SafeSubscriber errors, whether its Task does not support cancellation, or is already canceled. or undefined is not an object (evaluating 'task.zone') errors from SafeSubscriber.