diff --git a/src/vs/base/browser/builder.ts b/src/vs/base/browser/builder.ts index 79e7f4fc9fc..cc2d4d08d0e 100644 --- a/src/vs/base/browser/builder.ts +++ b/src/vs/base/browser/builder.ts @@ -7,7 +7,7 @@ import 'vs/css!./builder'; import {Promise} from 'vs/base/common/winjs.base'; import types = require('vs/base/common/types'); -import {IDisposable} from 'vs/base/common/lifecycle'; +import {IDisposable, disposeAll} from 'vs/base/common/lifecycle'; import strings = require('vs/base/common/strings'); import assert = require('vs/base/common/assert'); import DOM = require('vs/base/browser/dom'); @@ -133,8 +133,8 @@ export class Builder implements IDisposable { private offdom: boolean; private container: HTMLElement; private createdElements: HTMLElement[]; - private toUnbind: { [type: string]: { (): void; }[]; }; - private captureToUnbind: { [type: string]: { (): void; }[]; }; + private toUnbind: { [type: string]: IDisposable[]; }; + private captureToUnbind: { [type: string]: IDisposable[]; }; private browserService: BrowserService.IBrowserService; constructor(element?: HTMLElement, offdom?: boolean) { @@ -146,7 +146,7 @@ export class Builder implements IDisposable { this.createdElements = []; this.toUnbind = {}; - this.captureToUnbind = {}; + this.captureToUnbind = {}; this.browserService = BrowserService.getService(); } @@ -561,9 +561,9 @@ export class Builder implements IDisposable { /** * Registers listener on event types on the current element. */ - public on(type: string, fn: (e: Event, builder: Builder, unbind: { (): void; }) => void, listenerToUnbindContainer?: { (): void; }[], useCapture?: boolean): Builder; - public on(typeArray: string[], fn: (e: Event, builder: Builder, unbind: { (): void; }) => void, listenerToUnbindContainer?: { (): void; }[], useCapture?: boolean): Builder; - public on(arg1: any, fn: (e: Event, builder: Builder, unbind: { (): void; }) => void, listenerToUnbindContainer?: { (): void; }[], useCapture?: boolean): Builder { + public on(type: string, fn: (e: Event, builder: Builder, unbind: IDisposable) => void, listenerToUnbindContainer?: IDisposable[], useCapture?: boolean): Builder; + public on(typeArray: string[], fn: (e: Event, builder: Builder, unbind: IDisposable) => void, listenerToUnbindContainer?: IDisposable[], useCapture?: boolean): Builder; + public on(arg1: any, fn: (e: Event, builder: Builder, unbind: IDisposable) => void, listenerToUnbindContainer?: IDisposable[], useCapture?: boolean): Builder { // Event Type Array if (types.isArray(arg1)) { @@ -577,7 +577,7 @@ export class Builder implements IDisposable { let type = arg1; // Add Listener - let unbind: { (): void; } = DOM.addListener(this.currentElement, type, (e: Event) => { + let unbind: IDisposable = DOM.addDisposableListener(this.currentElement, type, (e: Event) => { fn(e, this, unbind); // Pass in Builder as Second Argument }, useCapture || false); @@ -595,7 +595,7 @@ export class Builder implements IDisposable { } // Bind to Element - let listenerBinding: { (): void; }[] = this.getProperty(LISTENER_BINDING_ID, []); + let listenerBinding: IDisposable[] = this.getProperty(LISTENER_BINDING_ID, []); listenerBinding.push(unbind); this.setProperty(LISTENER_BINDING_ID, listenerBinding); @@ -627,15 +627,11 @@ export class Builder implements IDisposable { let type = arg1; if (useCapture) { if (this.captureToUnbind[type]) { - while (this.captureToUnbind[type].length) { - this.captureToUnbind[type].pop()(); - } + this.captureToUnbind[type] = disposeAll(this.captureToUnbind[type]); } } else { if (this.toUnbind[type]) { - while (this.toUnbind[type].length) { - this.toUnbind[type].pop()(); - } + this.toUnbind[type] = disposeAll(this.toUnbind[type]); } } } @@ -647,9 +643,9 @@ export class Builder implements IDisposable { * Registers listener on event types on the current element and removes * them after first invocation. */ - public once(type: string, fn: (e: Event, builder: Builder, unbind: { (): void; }) => void, listenerToUnbindContainer?: { (): void; }[], useCapture?: boolean): Builder; - public once(typesArray: string[], fn: (e: Event, builder: Builder, unbind: { (): void; }) => void, listenerToUnbindContainer?: { (): void; }[], useCapture?: boolean): Builder; - public once(arg1: any, fn: (e: Event, builder: Builder, unbind: { (): void; }) => void, listenerToUnbindContainer?: { (): void; }[], useCapture?: boolean): Builder { + public once(type: string, fn: (e: Event, builder: Builder, unbind: IDisposable) => void, listenerToUnbindContainer?: IDisposable[], useCapture?: boolean): Builder; + public once(typesArray: string[], fn: (e: Event, builder: Builder, unbind: IDisposable) => void, listenerToUnbindContainer?: IDisposable[], useCapture?: boolean): Builder; + public once(arg1: any, fn: (e: Event, builder: Builder, unbind: IDisposable) => void, listenerToUnbindContainer?: IDisposable[], useCapture?: boolean): Builder { // Event Type Array if (types.isArray(arg1)) { @@ -663,9 +659,9 @@ export class Builder implements IDisposable { let type = arg1; // Add Listener - let unbind: { (): void; } = DOM.addListener(this.currentElement, type, (e: Event) => { + let unbind: IDisposable = DOM.addDisposableListener(this.currentElement, type, (e: Event) => { fn(e, this, unbind); // Pass in Builder as Second Argument - unbind(); + unbind.dispose(); }, useCapture || false); // Add to Array if passed in @@ -683,9 +679,9 @@ export class Builder implements IDisposable { * parameter "cancelBubble" is set to true, it will also prevent bubbling * of the event. */ - public preventDefault(type: string, cancelBubble: boolean, listenerToUnbindContainer?: { (): void; }[], useCapture?: boolean): Builder; - public preventDefault(typesArray: string[], cancelBubble: boolean, listenerToUnbindContainer?: { (): void; }[], useCapture?: boolean): Builder; - public preventDefault(arg1: any, cancelBubble: boolean, listenerToUnbindContainer?: { (): void; }[], useCapture?: boolean): Builder { + public preventDefault(type: string, cancelBubble: boolean, listenerToUnbindContainer?: IDisposable[], useCapture?: boolean): Builder; + public preventDefault(typesArray: string[], cancelBubble: boolean, listenerToUnbindContainer?: IDisposable[], useCapture?: boolean): Builder; + public preventDefault(arg1: any, cancelBubble: boolean, listenerToUnbindContainer?: IDisposable[], useCapture?: boolean): Builder { let fn = function(e: Event) { e.preventDefault(); @@ -1691,10 +1687,10 @@ export class Builder implements IDisposable { if (hasData(element)) { // Listeners - let listeners = data(element)[LISTENER_BINDING_ID]; + let listeners: IDisposable[] = data(element)[LISTENER_BINDING_ID]; if (types.isArray(listeners)) { while (listeners.length) { - listeners.pop()(); + listeners.pop().dispose(); } } @@ -1757,10 +1753,10 @@ export class Builder implements IDisposable { if (hasData(this.currentElement)) { // Listeners - let listeners = data(this.currentElement)[LISTENER_BINDING_ID]; + let listeners: IDisposable[] = data(this.currentElement)[LISTENER_BINDING_ID]; if (types.isArray(listeners)) { while (listeners.length) { - listeners.pop()(); + listeners.pop().dispose(); } } @@ -1773,17 +1769,13 @@ export class Builder implements IDisposable { for (type in this.toUnbind) { if (this.toUnbind.hasOwnProperty(type) && types.isArray(this.toUnbind[type])) { - while (this.toUnbind[type].length) { - this.toUnbind[type].pop()(); - } + this.toUnbind[type] = disposeAll(this.toUnbind[type]); } } for (type in this.captureToUnbind) { if (this.captureToUnbind.hasOwnProperty(type) && types.isArray(this.captureToUnbind[type])) { - while (this.captureToUnbind[type].length) { - this.captureToUnbind[type].pop()(); - } + this.captureToUnbind[type] = disposeAll(this.captureToUnbind[type]); } } diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 5ac6f2784c4..6b05568414d 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; +import * as mouseEvent from 'vs/base/browser/mouseEvent'; +import * as keyboardEvent from 'vs/base/browser/keyboardEvent'; import {isChrome, isWebKit} from 'vs/base/browser/browser'; import types = require('vs/base/common/types'); import {EventEmitter} from 'vs/base/common/eventEmitter'; import {IDisposable} from 'vs/base/common/lifecycle'; -import mouseEvent = require('vs/base/browser/mouseEvent'); -import keyboardEvent = require('vs/base/browser/keyboardEvent'); import {onUnexpectedError} from 'vs/base/common/errors'; import browserService = require('vs/base/browser/browserService'); @@ -268,16 +268,16 @@ function setTransform(domNode: HTMLElement, desiredValue: string): void { } })(); -export function addListener(node: Element, type: string, handler: (event: any) => void, useCapture?: boolean): () => void; -export function addListener(node: Window, type: string, handler: (event: any) => void, useCapture?: boolean): () => void; -export function addListener(node: Document, type: string, handler: (event: any) => void, useCapture?: boolean): () => void; -export function addListener(node: any, type: string, handler: (event: any) => void, useCapture?: boolean): () => void { +function _addListener(node: Element, type: string, handler: (event: any) => void, useCapture?: boolean): () => void; +function _addListener(node: Window, type: string, handler: (event: any) => void, useCapture?: boolean): () => void; +function _addListener(node: Document, type: string, handler: (event: any) => void, useCapture?: boolean): () => void; +function _addListener(node: any, type: string, handler: (event: any) => void, useCapture?: boolean): () => void { let wrapHandler = function(e): void { e = e || window.event; handler(e); }; - if (types.isFunction(node.addEventListener)) { + if (typeof node.addEventListener === 'function') { node.addEventListener(type, wrapHandler, useCapture || false); return function() { if (!wrapHandler) { @@ -301,7 +301,7 @@ export function addDisposableListener(node: Element, type: string, handler: (eve export function addDisposableListener(node: Window, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable; export function addDisposableListener(node: Document, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable; export function addDisposableListener(node: any, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable { - let dispose = addListener(node, type, handler, useCapture); + let dispose = _addListener(node, type, handler, useCapture); return { dispose: dispose }; @@ -351,7 +351,7 @@ export let addStandardDisposableListener: IAddStandardDisposableListenerSignatur }; export function addNonBubblingMouseOutListener(node: Element, handler: (event: any) => void): () => void { - return addListener(node, 'mouseout', (e: MouseEvent) => { + return _addListener(node, 'mouseout', (e: MouseEvent) => { // Mouse out bubbles, so this is an attempt to ignore faux mouse outs coming from children elements let toElement = (e.relatedTarget || e.toElement); while (toElement && toElement !== node) { @@ -548,7 +548,7 @@ function timeoutThrottledListener(node: any, type: string, handler: (event: R lastEvent = null; }; - let unbinder = addListener(node, type, function(e) { + let unbinder = _addListener(node, type, function(e) { lastEvent = eventMerger(lastEvent, e); let elapsedTime = (new Date()).getTime() - lastHandlerTime; @@ -572,12 +572,12 @@ function timeoutThrottledListener(node: any, type: string, handler: (event: R }; } -export function addThrottledListener(node: any, type: string, handler: (event: R) => void, eventMerger?: IEventMerger, minimumTimeMs?: number): () => void { +export function _addThrottledListener(node: any, type: string, handler: (event: R) => void, eventMerger?: IEventMerger, minimumTimeMs?: number): () => void { return timeoutThrottledListener(node, type, handler, eventMerger, minimumTimeMs); } export function addDisposableThrottledListener(node: any, type: string, handler: (event: R) => void, eventMerger?: IEventMerger, minimumTimeMs?: number): IDisposable { - let dispose = addThrottledListener(node, type, handler, eventMerger, minimumTimeMs); + let dispose = _addThrottledListener(node, type, handler, eventMerger, minimumTimeMs); return { dispose: dispose }; @@ -1031,8 +1031,8 @@ export function trackFocus(element: HTMLElement): IFocusTracker { }; // bind - unbind.push(addListener(element, EventType.FOCUS, onFocus, true)); - unbind.push(addListener(element, EventType.BLUR, onBlur, true)); + unbind.push(_addListener(element, EventType.FOCUS, onFocus, true)); + unbind.push(_addListener(element, EventType.BLUR, onBlur, true)); return result; } diff --git a/src/vs/base/browser/touch.ts b/src/vs/base/browser/touch.ts index 484179d6305..ad2855d3836 100644 --- a/src/vs/base/browser/touch.ts +++ b/src/vs/base/browser/touch.ts @@ -5,7 +5,7 @@ 'use strict'; import arrays = require('vs/base/common/arrays'); -import {IDisposable, cAll} from 'vs/base/common/lifecycle'; +import {IDisposable, disposeAll} from 'vs/base/common/lifecycle'; import DomUtils = require('vs/base/browser/dom'); export namespace EventType { @@ -68,7 +68,7 @@ export class Gesture implements IDisposable { private static SCROLL_FRICTION = -0.005; private targetElement: HTMLElement; - private callOnTarget: Function[]; + private callOnTarget: IDisposable[]; private handle: IDisposable; private activeTouches: { [id: number]: TouchData; }; @@ -89,7 +89,7 @@ export class Gesture implements IDisposable { } public set target(element: HTMLElement) { - cAll(this.callOnTarget); + this.callOnTarget = disposeAll(this.callOnTarget); this.activeTouches = {}; @@ -99,9 +99,9 @@ export class Gesture implements IDisposable { return; } - this.callOnTarget.push(DomUtils.addListener(this.targetElement, 'touchstart', (e) => this.onTouchStart(e))); - this.callOnTarget.push(DomUtils.addListener(this.targetElement, 'touchend', (e) => this.onTouchEnd(e))); - this.callOnTarget.push(DomUtils.addListener(this.targetElement, 'touchmove', (e) => this.onTouchMove(e))); + this.callOnTarget.push(DomUtils.addDisposableListener(this.targetElement, 'touchstart', (e) => this.onTouchStart(e))); + this.callOnTarget.push(DomUtils.addDisposableListener(this.targetElement, 'touchend', (e) => this.onTouchEnd(e))); + this.callOnTarget.push(DomUtils.addDisposableListener(this.targetElement, 'touchmove', (e) => this.onTouchMove(e))); } private static newGestureEvent(type: string): GestureEvent { diff --git a/src/vs/base/browser/ui/findinput/findInput.ts b/src/vs/base/browser/ui/findinput/findInput.ts index e204dc1825a..ee917960ef2 100644 --- a/src/vs/base/browser/ui/findinput/findInput.ts +++ b/src/vs/base/browser/ui/findinput/findInput.ts @@ -49,8 +49,6 @@ export class FindInput extends Widget { private validation:IInputValidator; private label:string; - private optionsKeyListener: () => void; - private regex:Checkbox; private wholeWords:Checkbox; private caseSensitive:Checkbox; @@ -259,8 +257,7 @@ export class FindInput extends Widget { // Arrow-Key support to navigate between options let indexes = [this.caseSensitive.domNode, this.wholeWords.domNode, this.regex.domNode]; - this.optionsKeyListener = dom.addListener(this.domNode, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => { - let event = new StandardKeyboardEvent(e); + this.onkeydown(this.domNode, (event: StandardKeyboardEvent) => { if (event.equals(CommonKeybindings.LEFT_ARROW) || event.equals(CommonKeybindings.RIGHT_ARROW) || event.equals(CommonKeybindings.ESCAPE)) { let index = indexes.indexOf(document.activeElement); if (index >= 0) { @@ -315,11 +312,6 @@ export class FindInput extends Widget { } public dispose(): void { - if (this.optionsKeyListener) { - this.optionsKeyListener(); - this.optionsKeyListener = null; - } - super.dispose(); } } diff --git a/src/vs/base/browser/ui/progressbar/progressbar.ts b/src/vs/base/browser/ui/progressbar/progressbar.ts index 64f13bda8a7..7002d64ca74 100644 --- a/src/vs/base/browser/ui/progressbar/progressbar.ts +++ b/src/vs/base/browser/ui/progressbar/progressbar.ts @@ -12,6 +12,7 @@ import browser = require('vs/base/browser/browser'); import {Builder, $} from 'vs/base/browser/builder'; import DOM = require('vs/base/browser/dom'); import uuid = require('vs/base/common/uuid'); +import {IDisposable,disposeAll} from 'vs/base/common/lifecycle'; const css_done = 'done'; const css_active = 'active'; @@ -25,7 +26,7 @@ const css_progress_bit = 'progress-bit'; */ export class ProgressBar { - private toUnbind: { (): void; }[]; + private toUnbind: IDisposable[]; private workedVal: number; private element: Builder; private animationRunning: boolean; @@ -238,8 +239,6 @@ export class ProgressBar { } public dispose(): void { - while (this.toUnbind.length) { - this.toUnbind.pop()(); - } + this.toUnbind = disposeAll(this.toUnbind); } } \ No newline at end of file diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 138bbb674ba..1dffa38f4d0 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -194,8 +194,8 @@ export class AbstractCollapsibleView extends HeaderView { protected state: CollapsibleState; private ariaHeaderLabel: string; - private headerClickListener: () => void; - private headerKeyListener: () => void; + private headerClickListener: lifecycle.IDisposable; + private headerKeyListener: lifecycle.IDisposable; private focusTracker: dom.IFocusTracker; constructor(opts: ICollapsibleViewOptions) { @@ -218,7 +218,7 @@ export class AbstractCollapsibleView extends HeaderView { this.header.setAttribute('aria-label', this.ariaHeaderLabel); } this.header.setAttribute('aria-expanded', String(this.state === CollapsibleState.EXPANDED)); - this.headerKeyListener = dom.addListener(this.header, dom.EventType.KEY_DOWN, (e) => { + this.headerKeyListener = dom.addDisposableListener(this.header, dom.EventType.KEY_DOWN, (e) => { let event = new StandardKeyboardEvent(e); let eventHandled = false; if (event.equals(CommonKeybindings.ENTER) || event.equals(CommonKeybindings.SPACE) || (event.equals(CommonKeybindings.LEFT_ARROW) && this.state === CollapsibleState.EXPANDED) || (event.equals(CommonKeybindings.RIGHT_ARROW) && this.state === CollapsibleState.COLLAPSED)) { @@ -241,7 +241,7 @@ export class AbstractCollapsibleView extends HeaderView { }); // Mouse access - this.headerClickListener = dom.addListener(this.header, dom.EventType.CLICK, () => this.toggleExpansion()); + this.headerClickListener = dom.addDisposableListener(this.header, dom.EventType.CLICK, () => this.toggleExpansion()); // Track state of focus in header so that other components can adjust styles based on that // (for example show or hide actions based on the state of being focused or not) @@ -318,12 +318,12 @@ export class AbstractCollapsibleView extends HeaderView { public dispose(): void { if (this.headerClickListener) { - this.headerClickListener(); + this.headerClickListener.dispose(); this.headerClickListener = null; } if (this.headerKeyListener) { - this.headerKeyListener(); + this.headerKeyListener.dispose(); this.headerKeyListener = null; } diff --git a/src/vs/base/browser/ui/timer/timer.ts b/src/vs/base/browser/ui/timer/timer.ts index dbe89450682..54d0485cd8a 100644 --- a/src/vs/base/browser/ui/timer/timer.ts +++ b/src/vs/base/browser/ui/timer/timer.ts @@ -7,7 +7,7 @@ import 'vs/css!./timer'; import {TimeKeeper, ITimerEvent, getTimeKeeper} from 'vs/base/common/timer'; -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; +import {IDisposable, disposeAll} from 'vs/base/common/lifecycle'; import DomUtils = require('vs/base/browser/dom'); interface IUnmatchedStartTimerEvent { @@ -17,7 +17,7 @@ interface IUnmatchedStartTimerEvent { export class TimeKeeperRenderer { - private listenersToRemove: ListenerUnbind[]; + private listenersToRemove: IDisposable[]; private timeKeeper: TimeKeeper; private outerDomNode: HTMLElement; private domNode: HTMLElement; @@ -50,10 +50,7 @@ export class TimeKeeperRenderer { public destroy(): void { document.body.removeChild(this.outerDomNode); window.clearInterval(this.intervalTokenId); - this.listenersToRemove.forEach(function(element) { - element(); - }); - this.listenersToRemove = []; + this.listenersToRemove = disposeAll(this.listenersToRemove); } private _createDomNode(): HTMLElement { @@ -64,14 +61,14 @@ export class TimeKeeperRenderer { let cancel: HTMLInputElement = document.createElement('input'); cancel.type = 'button'; cancel.value = 'Clear'; - this.listenersToRemove.push(DomUtils.addListener(cancel, 'click', () => this._onClear())); + this.listenersToRemove.push(DomUtils.addDisposableListener(cancel, 'click', () => this._onClear())); this.outerDomNode.appendChild(cancel); // Text filter this.textFilterDomNode = document.createElement('input'); this.textFilterDomNode.type = 'text'; this.textFilterDomNode.className = 'textFilter'; - this.listenersToRemove.push(DomUtils.addListener(this.textFilterDomNode, 'keydown', () => this.onTextFilterChange())); + this.listenersToRemove.push(DomUtils.addDisposableListener(this.textFilterDomNode, 'keydown', () => this.onTextFilterChange())); this.textFilter = ''; this.outerDomNode.appendChild(document.createTextNode('Filter')); this.outerDomNode.appendChild(this.textFilterDomNode); @@ -81,7 +78,7 @@ export class TimeKeeperRenderer { this.timeFilterDomNode.type = 'text'; this.timeFilterDomNode.value = '0'; this.timeFilterDomNode.className = 'timeFilter'; - this.listenersToRemove.push(DomUtils.addListener(this.timeFilterDomNode, 'keydown', () => this.onTimeFilterChange())); + this.listenersToRemove.push(DomUtils.addDisposableListener(this.timeFilterDomNode, 'keydown', () => this.onTimeFilterChange())); this.timeFilter = 0; this.outerDomNode.appendChild(document.createTextNode('Hide time under')); this.outerDomNode.appendChild(this.timeFilterDomNode); @@ -89,7 +86,7 @@ export class TimeKeeperRenderer { let hide: HTMLInputElement = document.createElement('input'); hide.type = 'button'; hide.value = 'Close'; - this.listenersToRemove.push(DomUtils.addListener(hide, 'click', () => { + this.listenersToRemove.push(DomUtils.addDisposableListener(hide, 'click', () => { this.onHide(); })); this.outerDomNode.appendChild(hide); diff --git a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts index 54a7911023a..986350ecfea 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts @@ -26,6 +26,7 @@ import {DefaultController, ClickBehavior} from 'vs/base/parts/tree/browser/treeD import DOM = require('vs/base/browser/dom'); import {IActionProvider} from 'vs/base/parts/tree/browser/actionsRenderer'; import {KeyCode} from 'vs/base/common/keyCodes'; +import {IDisposable,disposeAll} from 'vs/base/common/lifecycle'; export interface IQuickOpenCallbacks { onOk: () => void; @@ -600,15 +601,13 @@ export class QuickOpenWidget implements IModelProvider { // Otherwise return promise that only fulfills when the CSS transition has ended return new Promise((c, e) => { - let unbind: { (): void; }[] = []; + let unbind: IDisposable[] = []; let complete = false; let completeHandler = () => { if (!complete) { complete = true; - while (unbind.length) { - unbind.pop()(); - } + unbind = disposeAll(unbind); c(null); } diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index 400cf943f5d..46786df7455 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -152,7 +152,7 @@ export class ViewItem implements IViewItem { public needsRender: boolean; public uri: string; - public unbindDragStart: () =>void; + public unbindDragStart: Lifecycle.IDisposable; public loadingPromise: WinJS.Promise; public _styles: any; @@ -269,14 +269,14 @@ export class ViewItem implements IViewItem { if (uri !== this.uri) { if (this.unbindDragStart) { - this.unbindDragStart(); - delete this.unbindDragStart; + this.unbindDragStart.dispose(); + this.unbindDragStart = null; } if (uri) { this.uri = uri; this.draggable = true; - this.unbindDragStart = DOM.addListener(this.element, 'dragstart', (e) => { + this.unbindDragStart = DOM.addDisposableListener(this.element, 'dragstart', (e) => { this.onDragStart(e); }); } else { @@ -321,7 +321,7 @@ export class ViewItem implements IViewItem { } if (this.unbindDragStart) { - this.unbindDragStart(); + this.unbindDragStart.dispose(); this.unbindDragStart = null; } @@ -406,7 +406,7 @@ export class TreeView extends HeightMap implements IScrollable { private modelListeners: { (): void; }[]; private model: Model.TreeModel; - private viewListeners: { (): void; }[]; + private viewListeners: Lifecycle.IDisposable[]; private domNode: HTMLElement; private wrapper: HTMLElement; private rowsContainer: HTMLElement; @@ -513,23 +513,23 @@ export class TreeView extends HeightMap implements IScrollable { var focusTracker = DOM.trackFocus(this.domNode); focusTracker.addFocusListener((e: FocusEvent) => this.onFocus(e)); focusTracker.addBlurListener((e: FocusEvent) => this.onBlur(e)); - this.viewListeners.push(() => { focusTracker.dispose(); }); + this.viewListeners.push(focusTracker); - this.viewListeners.push(DOM.addListener(this.domNode, 'keydown', (e) => this.onKeyDown(e))); - this.viewListeners.push(DOM.addListener(this.domNode, 'keyup', (e) => this.onKeyUp(e))); - this.viewListeners.push(DOM.addListener(this.domNode, 'mousedown', (e) => this.onMouseDown(e))); - this.viewListeners.push(DOM.addListener(this.domNode, 'mouseup', (e) => this.onMouseUp(e))); - this.viewListeners.push(DOM.addListener(this.wrapper, 'click', (e) => this.onClick(e))); - this.viewListeners.push(DOM.addListener(this.domNode, 'contextmenu', (e) => this.onContextMenu(e))); - this.viewListeners.push(DOM.addListener(this.wrapper, Touch.EventType.Tap, (e) => this.onTap(e))); - this.viewListeners.push(DOM.addListener(this.wrapper, Touch.EventType.Change, (e) => this.onTouchChange(e))); + this.viewListeners.push(DOM.addDisposableListener(this.domNode, 'keydown', (e) => this.onKeyDown(e))); + this.viewListeners.push(DOM.addDisposableListener(this.domNode, 'keyup', (e) => this.onKeyUp(e))); + this.viewListeners.push(DOM.addDisposableListener(this.domNode, 'mousedown', (e) => this.onMouseDown(e))); + this.viewListeners.push(DOM.addDisposableListener(this.domNode, 'mouseup', (e) => this.onMouseUp(e))); + this.viewListeners.push(DOM.addDisposableListener(this.wrapper, 'click', (e) => this.onClick(e))); + this.viewListeners.push(DOM.addDisposableListener(this.domNode, 'contextmenu', (e) => this.onContextMenu(e))); + this.viewListeners.push(DOM.addDisposableListener(this.wrapper, Touch.EventType.Tap, (e) => this.onTap(e))); + this.viewListeners.push(DOM.addDisposableListener(this.wrapper, Touch.EventType.Change, (e) => this.onTouchChange(e))); if(Browser.isIE11orEarlier) { - this.viewListeners.push(DOM.addListener(this.wrapper, 'MSPointerDown', (e) => this.onMsPointerDown(e))); - this.viewListeners.push(DOM.addListener(this.wrapper, 'MSGestureTap', (e) => this.onMsGestureTap(e))); + this.viewListeners.push(DOM.addDisposableListener(this.wrapper, 'MSPointerDown', (e) => this.onMsPointerDown(e))); + this.viewListeners.push(DOM.addDisposableListener(this.wrapper, 'MSGestureTap', (e) => this.onMsGestureTap(e))); // these events come too fast, we throttle them - this.viewListeners.push(DOM.addThrottledListener(this.wrapper, 'MSGestureChange', (e) => this.onThrottledMsGestureChange(e), (lastEvent:IThrottledGestureEvent, event:MSGestureEvent): IThrottledGestureEvent => { + this.viewListeners.push(DOM.addDisposableThrottledListener(this.wrapper, 'MSGestureChange', (e) => this.onThrottledMsGestureChange(e), (lastEvent:IThrottledGestureEvent, event:MSGestureEvent): IThrottledGestureEvent => { event.stopPropagation(); event.preventDefault(); @@ -544,10 +544,10 @@ export class TreeView extends HeightMap implements IScrollable { })); } - this.viewListeners.push(DOM.addListener(window, 'dragover', (e) => this.onDragOver(e))); - this.viewListeners.push(DOM.addListener(window, 'drop', (e) => this.onDrop(e))); - this.viewListeners.push(DOM.addListener(window, 'dragend', (e) => this.onDragEnd(e))); - this.viewListeners.push(DOM.addListener(window, 'dragleave', (e) => this.onDragOver(e))); + this.viewListeners.push(DOM.addDisposableListener(window, 'dragover', (e) => this.onDragOver(e))); + this.viewListeners.push(DOM.addDisposableListener(window, 'drop', (e) => this.onDrop(e))); + this.viewListeners.push(DOM.addDisposableListener(window, 'dragend', (e) => this.onDragEnd(e))); + this.viewListeners.push(DOM.addDisposableListener(window, 'dragleave', (e) => this.onDragOver(e))); this.wrapper.appendChild(this.rowsContainer); this.domNode.appendChild(this.scrollableElement.getDomNode()); @@ -1647,10 +1647,7 @@ export class TreeView extends HeightMap implements IScrollable { this.releaseModel(); this.modelListeners = null; - while (this.viewListeners.length) { - this.viewListeners.pop()(); - } - this.viewListeners = null; + this.viewListeners = Lifecycle.disposeAll(this.viewListeners); if (this.domNode.parentNode) { this.domNode.parentNode.removeChild(this.domNode); diff --git a/src/vs/base/test/browser/builder.test.ts b/src/vs/base/test/browser/builder.test.ts index 0960391fdd6..b71d475b7a2 100644 --- a/src/vs/base/test/browser/builder.test.ts +++ b/src/vs/base/test/browser/builder.test.ts @@ -9,6 +9,7 @@ import { Build, Builder, MultiBuilder, Binding, Dimension, Position, Box, $ } fr import * as Types from 'vs/base/common/types'; import * as DomUtils from 'vs/base/browser/dom'; import { Promise } from 'vs/base/common/winjs.base'; +import { IDisposable } from 'vs/base/common/lifecycle'; var withElementsBySelector = function(selector: string, offdom: boolean = false) { var elements = window.document.querySelectorAll(selector); @@ -1220,14 +1221,16 @@ suite("Builder", () => { var b = Build.withElementById(fixtureId); var unbindCounter = 0; - var old = DomUtils.addListener; + var old = DomUtils.addDisposableListener; try { - DomUtils.addListener = function(node, type, handler) { - var unbind = old.call(null, node, type, handler); + DomUtils.addDisposableListener = function(node, type, handler) { + var unbind:IDisposable = old.call(null, node, type, handler); - return function() { - unbindCounter++; - unbind.call(null); + return { + dispose: function() { + unbindCounter++; + unbind.dispose(); + } }; }; @@ -1246,7 +1249,7 @@ suite("Builder", () => { b.empty(); assert.strictEqual(unbindCounter, 8); } finally { - DomUtils.addListener = old; + DomUtils.addDisposableListener = old; } }); @@ -1405,14 +1408,16 @@ suite("Builder", () => { var b = Build.withElementById(fixtureId); var unbindCounter = 0; - var old = DomUtils.addListener; + var old = DomUtils.addDisposableListener; try { - DomUtils.addListener = function(node, type, handler) { - var unbind = old.call(null, node, type, handler); + DomUtils.addDisposableListener = function(node, type, handler) { + var unbind:IDisposable = old.call(null, node, type, handler); - return function() { - unbindCounter++; - unbind.call(null); + return { + dispose: function() { + unbindCounter++; + unbind.dispose(); + } }; }; @@ -1433,7 +1438,7 @@ suite("Builder", () => { b.destroy(); assert.strictEqual(unbindCounter, 16); } finally { - DomUtils.addListener = old; + DomUtils.addDisposableListener = old; } }); diff --git a/src/vs/base/worker/defaultWorkerFactory.ts b/src/vs/base/worker/defaultWorkerFactory.ts index c70e3ca4a80..3493ee2b120 100644 --- a/src/vs/base/worker/defaultWorkerFactory.ts +++ b/src/vs/base/worker/defaultWorkerFactory.ts @@ -5,6 +5,7 @@ 'use strict'; import dom = require('vs/base/browser/dom'); +import lifecycle = require('vs/base/common/lifecycle'); import env = require('vs/base/common/flags'); import {IWorker, IWorkerCallback, IWorkerFactory} from 'vs/base/common/worker/workerClient'; @@ -57,8 +58,11 @@ class FrameWorker implements IWorker { private loaded: boolean; private beforeLoadMessages: any[]; + private _listeners: lifecycle.IDisposable[]; + constructor(id: number, onMessageCallback:IWorkerCallback) { this.id = id; + this._listeners = []; // Collect all messages sent to the worker until the iframe is loaded this.loaded = false; @@ -69,15 +73,19 @@ class FrameWorker implements IWorker { this.iframe.src = require.toUrl('./workerMainCompatibility.html'); ( this.iframe).frameborder = this.iframe.height = this.iframe.width = '0'; this.iframe.style.display = 'none'; - dom.addListener(this.iframe, 'load', () => this.onLoaded()); + this._listeners.push(dom.addDisposableListener(this.iframe, 'load', () => this.onLoaded())); this.onMessage = function(ev:any) { onMessageCallback(ev.data); }; - dom.addListener(window, 'message', this.onMessage); + this._listeners.push(dom.addDisposableListener(window, 'message', this.onMessage)); document.body.appendChild(this.iframe); } + public dispose(): void { + this._listeners = lifecycle.disposeAll(this._listeners); + } + private iframeId(): string { return 'worker_iframe_' + this.id; } diff --git a/src/vs/editor/browser/controller/mouseHandler.ts b/src/vs/editor/browser/controller/mouseHandler.ts index 0d7b9cd622b..ef7add9788c 100644 --- a/src/vs/editor/browser/controller/mouseHandler.ts +++ b/src/vs/editor/browser/controller/mouseHandler.ts @@ -94,7 +94,7 @@ export class MouseHandler extends ViewEventHandler implements Lifecycle.IDisposa public viewController:EditorBrowser.IViewController; public viewHelper:EditorBrowser.IPointerHandlerHelper; public mouseTargetFactory: MouseTarget.MouseTargetFactory; - public listenersToRemove:EventEmitter.ListenerUnbind[]; + public listenersToRemove:Lifecycle.IDisposable[]; private toDispose:Lifecycle.IDisposable[]; private hideTextAreaTimeout: number; @@ -145,25 +145,25 @@ export class MouseHandler extends ViewEventHandler implements Lifecycle.IDisposa this.lastMouseLeaveTime = -1; - this.listenersToRemove.push(DomUtils.addListener(this.viewHelper.viewDomNode, 'contextmenu', + this.listenersToRemove.push(DomUtils.addDisposableListener(this.viewHelper.viewDomNode, 'contextmenu', (e: MouseEvent) => this._onContextMenu(e))); this._mouseMoveEventHandler = new EventGateKeeper((e) => this._onMouseMove(e), () => !this.viewHelper.isDirty()); this.toDispose.push(this._mouseMoveEventHandler); - this.listenersToRemove.push(DomUtils.addThrottledListener(this.viewHelper.viewDomNode, 'mousemove', + this.listenersToRemove.push(DomUtils.addDisposableThrottledListener(this.viewHelper.viewDomNode, 'mousemove', this._mouseMoveEventHandler.handler, createMouseMoveEventMerger(this.mouseTargetFactory), MouseHandler.MOUSE_MOVE_MINIMUM_TIME)); this._mouseDownThenMoveEventHandler = new EventGateKeeper((e) => this._onMouseDownThenMove(e), () => !this.viewHelper.isDirty()); this.toDispose.push(this._mouseDownThenMoveEventHandler); - this.listenersToRemove.push(DomUtils.addListener(this.viewHelper.viewDomNode, 'mouseup', + this.listenersToRemove.push(DomUtils.addDisposableListener(this.viewHelper.viewDomNode, 'mouseup', (e: MouseEvent) => this._onMouseUp(e))); - this.listenersToRemove.push(DomUtils.addNonBubblingMouseOutListener(this.viewHelper.viewDomNode, + this.listenersToRemove.push(DomUtils.addDisposableNonBubblingMouseOutListener(this.viewHelper.viewDomNode, (e:MouseEvent) => this._onMouseLeave(e))); - this.listenersToRemove.push(DomUtils.addListener(this.viewHelper.viewDomNode, 'mousedown', + this.listenersToRemove.push(DomUtils.addDisposableListener(this.viewHelper.viewDomNode, 'mousedown', (e: MouseEvent) => this._onMouseDown(e))); @@ -172,10 +172,7 @@ export class MouseHandler extends ViewEventHandler implements Lifecycle.IDisposa public dispose(): void { this.context.removeEventHandler(this); - this.listenersToRemove.forEach((element) => { - element(); - }); - this.listenersToRemove = []; + this.listenersToRemove = Lifecycle.disposeAll(this.listenersToRemove); this.toDispose = Lifecycle.disposeAll(this.toDispose); this._unhook(); if (this.hideTextAreaTimeout !== -1) { diff --git a/src/vs/editor/browser/controller/pointerHandler.ts b/src/vs/editor/browser/controller/pointerHandler.ts index 537a7c92413..cad83ea41e0 100644 --- a/src/vs/editor/browser/controller/pointerHandler.ts +++ b/src/vs/editor/browser/controller/pointerHandler.ts @@ -66,8 +66,8 @@ class MsPointerHandler extends MouseHandler.MouseHandler implements Lifecycle.ID penGesture.addPointer(e.pointerId); } }); - this.listenersToRemove.push(DomUtils.addThrottledListener(this.viewHelper.linesContentDomNode, 'MSGestureChange', (e) => this._onGestureChange(e), gestureChangeEventMerger)); - this.listenersToRemove.push(DomUtils.addListener(this.viewHelper.linesContentDomNode, 'MSGestureTap', (e) => this._onCaptureGestureTap(e), true)); + this.listenersToRemove.push(DomUtils.addDisposableThrottledListener(this.viewHelper.linesContentDomNode, 'MSGestureChange', (e) => this._onGestureChange(e), gestureChangeEventMerger)); + this.listenersToRemove.push(DomUtils.addDisposableListener(this.viewHelper.linesContentDomNode, 'MSGestureTap', (e) => this._onCaptureGestureTap(e), true)); } }, 100); this._lastPointerType = 'mouse'; @@ -145,8 +145,8 @@ class StandardPointerHandler extends MouseHandler.MouseHandler implements Lifecy penGesture.addPointer(e.pointerId); } }); - this.listenersToRemove.push(DomUtils.addThrottledListener(this.viewHelper.linesContentDomNode, 'MSGestureChange', (e) => this._onGestureChange(e), gestureChangeEventMerger)); - this.listenersToRemove.push(DomUtils.addListener(this.viewHelper.linesContentDomNode, 'MSGestureTap', (e) => this._onCaptureGestureTap(e), true)); + this.listenersToRemove.push(DomUtils.addDisposableThrottledListener(this.viewHelper.linesContentDomNode, 'MSGestureChange', (e) => this._onGestureChange(e), gestureChangeEventMerger)); + this.listenersToRemove.push(DomUtils.addDisposableListener(this.viewHelper.linesContentDomNode, 'MSGestureTap', (e) => this._onCaptureGestureTap(e), true)); } }, 100); this._lastPointerType = 'mouse'; @@ -196,8 +196,8 @@ class TouchHandler extends MouseHandler.MouseHandler { this.gesture = new Touch.Gesture(this.viewHelper.linesContentDomNode); - this.listenersToRemove.push(DomUtils.addListener(this.viewHelper.linesContentDomNode, Touch.EventType.Tap, (e) => this.onTap(e))); - this.listenersToRemove.push(DomUtils.addListener(this.viewHelper.linesContentDomNode, Touch.EventType.Change, (e) => this.onChange(e))); + this.listenersToRemove.push(DomUtils.addDisposableListener(this.viewHelper.linesContentDomNode, Touch.EventType.Tap, (e) => this.onTap(e))); + this.listenersToRemove.push(DomUtils.addDisposableListener(this.viewHelper.linesContentDomNode, Touch.EventType.Change, (e) => this.onChange(e))); } public dispose(): void { diff --git a/src/vs/editor/contrib/codelens/browser/codelens.ts b/src/vs/editor/contrib/codelens/browser/codelens.ts index 9485be264f7..de1167ed734 100644 --- a/src/vs/editor/contrib/codelens/browser/codelens.ts +++ b/src/vs/editor/contrib/codelens/browser/codelens.ts @@ -54,7 +54,7 @@ class CodeLensContentWidget implements EditorBrowser.IContentWidget { private _id: string; private _domNode: HTMLElement; - private _subscription: Function; + private _subscription: lifecycle.IDisposable; private _symbolRange: EditorCommon.IEditorRange; private _widgetPosition: EditorBrowser.IContentWidgetPosition; private _editor: EditorBrowser.ICodeEditor; @@ -73,7 +73,7 @@ class CodeLensContentWidget implements EditorBrowser.IContentWidget { this._domNode.innerHTML = ' '; dom.addClass(this._domNode, 'codelens-decoration'); dom.addClass(this._domNode, 'invisible-cl'); - this._subscription = dom.addListener(this._domNode, 'click', e => { + this._subscription = dom.addDisposableListener(this._domNode, 'click', e => { let element = e.target; if (element.tagName === 'A' && element.id) { let command = this._commands[element.id]; @@ -90,7 +90,7 @@ class CodeLensContentWidget implements EditorBrowser.IContentWidget { } public dispose(): void { - this._subscription(); + this._subscription.dispose(); this._symbolRange = null; } diff --git a/src/vs/editor/contrib/quickFix/browser/lightBulpWidget.ts b/src/vs/editor/contrib/quickFix/browser/lightBulpWidget.ts index f9d87040ae9..3af015d1d78 100644 --- a/src/vs/editor/contrib/quickFix/browser/lightBulpWidget.ts +++ b/src/vs/editor/contrib/quickFix/browser/lightBulpWidget.ts @@ -17,7 +17,7 @@ class LightBulpWidget implements EditorBrowser.IContentWidget, lifecycle.IDispos private domNode: HTMLElement; private visible: boolean; private onclick: (pos: EditorCommon.IPosition) => void; - private listenersToRemove:eventEmitter.ListenerUnbind[]; + private toDispose:lifecycle.IDisposable[]; // Editor.IContentWidget.allowEditorOverflow public allowEditorOverflow = true; @@ -25,16 +25,13 @@ class LightBulpWidget implements EditorBrowser.IContentWidget, lifecycle.IDispos constructor(editor: EditorBrowser.ICodeEditor, onclick: (pos: EditorCommon.IPosition) => void) { this.editor = editor; this.onclick = onclick; - this.listenersToRemove = []; + this.toDispose = []; this.editor.addContentWidget(this); } public dispose(): void { this.editor.removeContentWidget(this); - this.listenersToRemove.forEach((element) => { - element(); - }); - this.listenersToRemove = []; + this.toDispose = lifecycle.disposeAll(this.toDispose); } public getId(): string { @@ -47,7 +44,7 @@ class LightBulpWidget implements EditorBrowser.IContentWidget, lifecycle.IDispos this.domNode.style.width = '20px'; this.domNode.style.height = '20px'; this.domNode.className = 'lightbulp-glyph'; - this.listenersToRemove.push(DomUtils.addListener(this.domNode, 'click',(e) => { + this.toDispose.push(DomUtils.addDisposableListener(this.domNode, 'click',(e) => { this.editor.focus(); this.onclick(this.position); })); diff --git a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts index a470452f1f9..533e9ae21a0 100644 --- a/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts +++ b/src/vs/workbench/browser/parts/statusbar/statusbarPart.ts @@ -166,7 +166,7 @@ class StatusBarEntryItem implements IStatusbarItem { } public render(el: HTMLElement): IDisposable { - let toDispose: { (): void; }[] = []; + let toDispose: IDisposable[] = []; dom.addClass(el, 'statusbar-entry'); // Text Container @@ -196,9 +196,7 @@ class StatusBarEntryItem implements IStatusbarItem { return { dispose: () => { - while (toDispose.length) { - toDispose.pop()(); - } + toDispose = disposeAll(toDispose); } }; } diff --git a/src/vs/workbench/electron-browser/shell.ts b/src/vs/workbench/electron-browser/shell.ts index f1c8c715753..44cfe19b719 100644 --- a/src/vs/workbench/electron-browser/shell.ts +++ b/src/vs/workbench/electron-browser/shell.ts @@ -20,7 +20,7 @@ import objects = require('vs/base/common/objects'); import dom = require('vs/base/browser/dom'); import aria = require('vs/base/browser/ui/aria/aria'); import {Emitter} from 'vs/base/common/event'; -import {IDisposable} from 'vs/base/common/lifecycle'; +import {disposeAll, IDisposable} from 'vs/base/common/lifecycle'; import errors = require('vs/base/common/errors'); import {ContextViewService} from 'vs/platform/contextview/browser/contextViewService'; import {ContextMenuService} from 'vs/workbench/services/contextview/electron-browser/contextmenuService'; @@ -168,7 +168,7 @@ export class WorkbenchShell { private keybindingService: WorkbenchKeybindingService; private container: HTMLElement; - private toUnbind: { (): void; }[]; + private toUnbind: IDisposable[]; private previousErrorValue: string; private previousErrorTime: number; private content: HTMLElement; @@ -411,7 +411,7 @@ export class WorkbenchShell { this.setTheme(themeId, false); - this.toUnbind.push(this.storageService.addListener(StorageEventType.STORAGE, (e: StorageEvent) => { + this.toUnbind.push(this.storageService.addListener2(StorageEventType.STORAGE, (e: StorageEvent) => { if (e.key === Preferences.THEME) { this.setTheme(e.newValue); } @@ -557,9 +557,7 @@ export class WorkbenchShell { this.storageService.dispose(); // Listeners - while (this.toUnbind.length) { - this.toUnbind.pop()(); - } + this.toUnbind = disposeAll(this.toUnbind); // Container $(this.container).empty(); diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index 327d8302255..8f6cee31cd8 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -17,7 +17,7 @@ import * as Objects from 'vs/base/common/objects'; import { IStringDictionary } from 'vs/base/common/collections'; import { Action } from 'vs/base/common/actions'; import * as Dom from 'vs/base/browser/dom'; -import { IDisposable, cAll } from 'vs/base/common/lifecycle'; +import { IDisposable, disposeAll } from 'vs/base/common/lifecycle'; import { EventEmitter, ListenerUnbind } from 'vs/base/common/eventEmitter'; import * as Builder from 'vs/base/browser/builder'; import URI from 'vs/base/common/uri'; @@ -324,7 +324,7 @@ class StatusBarItem implements statusbar.IStatusbarItem { public render(container: HTMLElement): IDisposable { - let callOnDispose: Function[] = [], + let callOnDispose: IDisposable[] = [], element = document.createElement('div'), // icon = document.createElement('a'), progress = document.createElement('div'), @@ -362,7 +362,7 @@ class StatusBarItem implements statusbar.IStatusbarItem { // this.outputService.showOutput(TaskService.OutputChannel, e.ctrlKey || e.metaKey, true); // })); - callOnDispose.push(Dom.addListener(label, 'click', (e:MouseEvent) => { + callOnDispose.push(Dom.addDisposableListener(label, 'click', (e:MouseEvent) => { this.quickOpenService.show('!'); })); @@ -389,7 +389,7 @@ class StatusBarItem implements statusbar.IStatusbarItem { updateLabel(this.markerService.getStatistics()); }); - callOnDispose.push(this.taskService.addListener(TaskServiceEvents.Active, () => { + callOnDispose.push(this.taskService.addListener2(TaskServiceEvents.Active, () => { this.activeCount++; if (this.activeCount === 1) { let index = 1; @@ -406,7 +406,7 @@ class StatusBarItem implements statusbar.IStatusbarItem { } })); - callOnDispose.push(this.taskService.addListener(TaskServiceEvents.Inactive, (data:TaskServiceEventData) => { + callOnDispose.push(this.taskService.addListener2(TaskServiceEvents.Inactive, (data:TaskServiceEventData) => { this.activeCount--; if (this.activeCount === 0) { $(progress).hide(); @@ -415,7 +415,7 @@ class StatusBarItem implements statusbar.IStatusbarItem { } })); - callOnDispose.push(this.taskService.addListener(TaskServiceEvents.Terminated, () => { + callOnDispose.push(this.taskService.addListener2(TaskServiceEvents.Terminated, () => { if (this.activeCount !== 0) { $(progress).hide(); if (this.intervalToken) { @@ -429,7 +429,9 @@ class StatusBarItem implements statusbar.IStatusbarItem { container.appendChild(element); return { - dispose: () => cAll(callOnDispose) + dispose: () => { + callOnDispose = disposeAll(callOnDispose); + } }; } }