2015-05-26 12:25:39 -04:00
|
|
|
import {
|
|
|
|
describe,
|
|
|
|
ddescribe,
|
|
|
|
it,
|
|
|
|
iit,
|
|
|
|
xit,
|
|
|
|
xdescribe,
|
|
|
|
expect,
|
|
|
|
beforeEach,
|
|
|
|
el
|
|
|
|
} from 'angular2/test_lib';
|
|
|
|
import {
|
|
|
|
EventManager,
|
|
|
|
EventManagerPlugin,
|
|
|
|
DomEventsPlugin
|
|
|
|
} from 'angular2/src/render/dom/events/event_manager';
|
2015-05-07 09:38:57 -04:00
|
|
|
import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
2015-02-09 09:11:31 -05:00
|
|
|
import {List, ListWrapper, Map, MapWrapper} from 'angular2/src/facade/collection';
|
2015-02-27 17:50:06 -05:00
|
|
|
import {DOM} from 'angular2/src/dom/dom_adapter';
|
2015-02-09 09:11:31 -05:00
|
|
|
|
|
|
|
export function main() {
|
2015-02-19 22:10:16 -05:00
|
|
|
var domEventPlugin;
|
|
|
|
|
2015-05-26 12:25:39 -04:00
|
|
|
beforeEach(() => { domEventPlugin = new DomEventsPlugin(); });
|
2015-02-19 22:10:16 -05:00
|
|
|
|
2015-02-09 09:11:31 -05:00
|
|
|
describe('EventManager', () => {
|
|
|
|
|
|
|
|
it('should delegate event bindings to plugins', () => {
|
|
|
|
var element = el('<div></div>');
|
|
|
|
var handler = (e) => e;
|
|
|
|
var plugin = new FakeEventManagerPlugin(['click']);
|
2015-05-07 09:38:57 -04:00
|
|
|
var manager = new EventManager([plugin, domEventPlugin], new FakeNgZone());
|
2015-02-09 09:11:31 -05:00
|
|
|
manager.addEventListener(element, 'click', handler);
|
2015-06-17 19:21:40 -04:00
|
|
|
expect(plugin._nonBubbleEventHandlers.get('click')).toBe(handler);
|
2015-02-19 22:10:16 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should delegate bubbling events to plugins', () => {
|
|
|
|
var element = el('<div></div>');
|
|
|
|
var handler = (e) => e;
|
|
|
|
var plugin = new FakeEventManagerPlugin(['click']);
|
2015-05-07 09:38:57 -04:00
|
|
|
var manager = new EventManager([plugin, domEventPlugin], new FakeNgZone());
|
2015-02-19 22:10:16 -05:00
|
|
|
manager.addEventListener(element, '^click', handler);
|
2015-06-17 19:21:40 -04:00
|
|
|
expect(plugin._bubbleEventHandlers.get('click')).toBe(handler);
|
2015-02-09 09:11:31 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should delegate event bindings to the first plugin supporting the event', () => {
|
|
|
|
var element = el('<div></div>');
|
|
|
|
var clickHandler = (e) => e;
|
|
|
|
var dblClickHandler = (e) => e;
|
2015-05-26 12:25:39 -04:00
|
|
|
var plugin1 = new FakeEventManagerPlugin(['dblclick']);
|
2015-02-09 09:11:31 -05:00
|
|
|
var plugin2 = new FakeEventManagerPlugin(['click', 'dblclick']);
|
2015-05-07 09:38:57 -04:00
|
|
|
var manager = new EventManager([plugin1, plugin2], new FakeNgZone());
|
2015-02-09 09:11:31 -05:00
|
|
|
manager.addEventListener(element, 'click', clickHandler);
|
|
|
|
manager.addEventListener(element, 'dblclick', dblClickHandler);
|
2015-06-18 00:42:56 -04:00
|
|
|
expect(plugin1._nonBubbleEventHandlers.has('click')).toBe(false);
|
2015-06-17 19:21:40 -04:00
|
|
|
expect(plugin2._nonBubbleEventHandlers.get('click')).toBe(clickHandler);
|
2015-06-18 00:42:56 -04:00
|
|
|
expect(plugin2._nonBubbleEventHandlers.has('dblclick')).toBe(false);
|
2015-06-17 19:21:40 -04:00
|
|
|
expect(plugin1._nonBubbleEventHandlers.get('dblclick')).toBe(dblClickHandler);
|
2015-02-09 09:11:31 -05:00
|
|
|
});
|
|
|
|
|
2015-02-19 22:10:16 -05:00
|
|
|
it('should throw when no plugin can handle the event', () => {
|
2015-02-09 09:11:31 -05:00
|
|
|
var element = el('<div></div>');
|
2015-02-19 22:10:16 -05:00
|
|
|
var plugin = new FakeEventManagerPlugin(['dblclick']);
|
2015-05-07 09:38:57 -04:00
|
|
|
var manager = new EventManager([plugin], new FakeNgZone());
|
2015-02-19 22:10:16 -05:00
|
|
|
expect(() => manager.addEventListener(element, 'click', null))
|
2015-05-26 12:25:39 -04:00
|
|
|
.toThrowError('No event manager plugin found for event click');
|
2015-02-19 22:10:16 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('by default events are only caught on same element', () => {
|
|
|
|
var element = el('<div><div></div></div>');
|
|
|
|
var child = DOM.firstChild(element);
|
2015-02-09 09:11:31 -05:00
|
|
|
var dispatchedEvent = DOM.createMouseEvent('click');
|
|
|
|
var receivedEvent = null;
|
|
|
|
var handler = (e) => { receivedEvent = e; };
|
2015-05-07 09:38:57 -04:00
|
|
|
var manager = new EventManager([domEventPlugin], new FakeNgZone());
|
2015-02-09 09:11:31 -05:00
|
|
|
manager.addEventListener(element, 'click', handler);
|
2015-02-19 22:10:16 -05:00
|
|
|
DOM.dispatchEvent(child, dispatchedEvent);
|
|
|
|
|
|
|
|
expect(receivedEvent).toBe(null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('bubbled events are caught when fired from a child', () => {
|
|
|
|
var element = el('<div><div></div></div>');
|
|
|
|
// Workaround for https://bugs.webkit.org/show_bug.cgi?id=122755
|
2015-04-21 13:30:55 -04:00
|
|
|
DOM.appendChild(DOM.defaultDoc().body, element);
|
2015-02-19 22:10:16 -05:00
|
|
|
|
|
|
|
var child = DOM.firstChild(element);
|
|
|
|
var dispatchedEvent = DOM.createMouseEvent('click');
|
|
|
|
var receivedEvent = null;
|
|
|
|
var handler = (e) => { receivedEvent = e; };
|
2015-05-07 09:38:57 -04:00
|
|
|
var manager = new EventManager([domEventPlugin], new FakeNgZone());
|
2015-02-19 22:10:16 -05:00
|
|
|
manager.addEventListener(element, '^click', handler);
|
|
|
|
DOM.dispatchEvent(child, dispatchedEvent);
|
|
|
|
|
2015-02-09 09:11:31 -05:00
|
|
|
expect(receivedEvent).toBe(dispatchedEvent);
|
|
|
|
});
|
2015-04-02 09:56:58 -04:00
|
|
|
|
|
|
|
it('should add and remove global event listeners with correct bubbling', () => {
|
|
|
|
var element = el('<div><div></div></div>');
|
2015-04-21 13:30:55 -04:00
|
|
|
DOM.appendChild(DOM.defaultDoc().body, element);
|
2015-04-02 09:56:58 -04:00
|
|
|
var dispatchedEvent = DOM.createMouseEvent('click');
|
|
|
|
var receivedEvent = null;
|
|
|
|
var handler = (e) => { receivedEvent = e; };
|
2015-05-07 09:38:57 -04:00
|
|
|
var manager = new EventManager([domEventPlugin], new FakeNgZone());
|
2015-04-02 09:56:58 -04:00
|
|
|
|
|
|
|
var remover = manager.addGlobalEventListener("document", '^click', handler);
|
|
|
|
DOM.dispatchEvent(element, dispatchedEvent);
|
|
|
|
expect(receivedEvent).toBe(dispatchedEvent);
|
|
|
|
|
|
|
|
receivedEvent = null;
|
|
|
|
remover();
|
|
|
|
DOM.dispatchEvent(element, dispatchedEvent);
|
|
|
|
expect(receivedEvent).toBe(null);
|
|
|
|
|
|
|
|
remover = manager.addGlobalEventListener("document", 'click', handler);
|
|
|
|
DOM.dispatchEvent(element, dispatchedEvent);
|
|
|
|
expect(receivedEvent).toBe(null);
|
|
|
|
});
|
2015-02-09 09:11:31 -05:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
class FakeEventManagerPlugin extends EventManagerPlugin {
|
|
|
|
_supports: List<string>;
|
2015-05-26 12:25:39 -04:00
|
|
|
_nonBubbleEventHandlers: Map<string, Function>;
|
|
|
|
_bubbleEventHandlers: Map<string, Function>;
|
2015-02-09 09:11:31 -05:00
|
|
|
constructor(supports: List<string>) {
|
|
|
|
super();
|
|
|
|
this._supports = supports;
|
2015-06-17 19:21:40 -04:00
|
|
|
this._nonBubbleEventHandlers = new Map();
|
|
|
|
this._bubbleEventHandlers = new Map();
|
2015-02-09 09:11:31 -05:00
|
|
|
}
|
|
|
|
|
2015-05-26 12:25:39 -04:00
|
|
|
supports(eventName: string): boolean { return ListWrapper.contains(this._supports, eventName); }
|
2015-02-09 09:11:31 -05:00
|
|
|
|
2015-02-27 17:50:06 -05:00
|
|
|
addEventListener(element, eventName: string, handler: Function, shouldSupportBubble: boolean) {
|
2015-06-17 19:21:40 -04:00
|
|
|
if (shouldSupportBubble) {
|
|
|
|
this._bubbleEventHandlers.set(eventName, handler);
|
|
|
|
} else {
|
|
|
|
this._nonBubbleEventHandlers.set(eventName, handler);
|
|
|
|
}
|
2015-05-26 12:25:39 -04:00
|
|
|
return () => {
|
|
|
|
MapWrapper.delete(
|
|
|
|
shouldSupportBubble ? this._bubbleEventHandlers : this._nonBubbleEventHandlers, eventName)
|
|
|
|
};
|
2015-02-09 09:11:31 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-07 09:38:57 -04:00
|
|
|
class FakeNgZone extends NgZone {
|
2015-05-26 12:25:39 -04:00
|
|
|
constructor() { super({enableLongStackTrace: false}); }
|
2015-02-09 09:11:31 -05:00
|
|
|
|
2015-05-26 12:25:39 -04:00
|
|
|
run(fn) { fn(); }
|
2015-02-09 09:11:31 -05:00
|
|
|
|
2015-05-26 12:25:39 -04:00
|
|
|
runOutsideAngular(fn) { return fn(); }
|
2015-02-09 09:11:31 -05:00
|
|
|
}
|