refactor(event_manager): use multi bindings to configure EventManager
Closes #3978
This commit is contained in:
parent
5ebeaf7c9b
commit
855cb16cc7
|
@ -39,7 +39,11 @@ import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
||||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||||
import {XHR} from 'angular2/src/core/render/xhr';
|
import {XHR} from 'angular2/src/core/render/xhr';
|
||||||
import {XHRImpl} from 'angular2/src/core/render/xhr_impl';
|
import {XHRImpl} from 'angular2/src/core/render/xhr_impl';
|
||||||
import {EventManager, DomEventsPlugin} from 'angular2/src/core/render/dom/events/event_manager';
|
import {
|
||||||
|
EventManager,
|
||||||
|
DomEventsPlugin,
|
||||||
|
EVENT_MANAGER_PLUGINS
|
||||||
|
} from 'angular2/src/core/render/dom/events/event_manager';
|
||||||
import {KeyEventsPlugin} from 'angular2/src/core/render/dom/events/key_events';
|
import {KeyEventsPlugin} from 'angular2/src/core/render/dom/events/key_events';
|
||||||
import {HammerGesturesPlugin} from 'angular2/src/core/render/dom/events/hammer_gestures';
|
import {HammerGesturesPlugin} from 'angular2/src/core/render/dom/events/hammer_gestures';
|
||||||
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mapper';
|
||||||
|
@ -111,14 +115,10 @@ function _injectorBindings(appComponentType): Array<Type | Binding | any[]> {
|
||||||
.toFactory((p: Promise<any>) => p.then(ref => ref.instance), [APP_COMPONENT_REF_PROMISE]),
|
.toFactory((p: Promise<any>) => p.then(ref => ref.instance), [APP_COMPONENT_REF_PROMISE]),
|
||||||
bind(LifeCycle).toFactory((exceptionHandler) => new LifeCycle(null, assertionsEnabled()),
|
bind(LifeCycle).toFactory((exceptionHandler) => new LifeCycle(null, assertionsEnabled()),
|
||||||
[ExceptionHandler]),
|
[ExceptionHandler]),
|
||||||
bind(EventManager)
|
EventManager,
|
||||||
.toFactory(
|
new Binding(EVENT_MANAGER_PLUGINS, {toClass: DomEventsPlugin, multi: true}),
|
||||||
(ngZone) => {
|
new Binding(EVENT_MANAGER_PLUGINS, {toClass: KeyEventsPlugin, multi: true}),
|
||||||
var plugins =
|
new Binding(EVENT_MANAGER_PLUGINS, {toClass: HammerGesturesPlugin, multi: true}),
|
||||||
[new HammerGesturesPlugin(), new KeyEventsPlugin(), new DomEventsPlugin()];
|
|
||||||
return new EventManager(plugins, ngZone);
|
|
||||||
},
|
|
||||||
[NgZone]),
|
|
||||||
DomRenderer,
|
DomRenderer,
|
||||||
bind(Renderer).toAlias(DomRenderer),
|
bind(Renderer).toAlias(DomRenderer),
|
||||||
APP_ID_RANDOM_BINDING,
|
APP_ID_RANDOM_BINDING,
|
||||||
|
|
|
@ -1,12 +1,25 @@
|
||||||
import {isBlank, BaseException, isPresent, StringWrapper} from 'angular2/src/core/facade/lang';
|
import {
|
||||||
|
isBlank,
|
||||||
|
BaseException,
|
||||||
|
isPresent,
|
||||||
|
StringWrapper,
|
||||||
|
CONST_EXPR
|
||||||
|
} from 'angular2/src/core/facade/lang';
|
||||||
|
import {ListWrapper} from 'angular2/src/core/facade/collection';
|
||||||
import {DOM} from 'angular2/src/core/dom/dom_adapter';
|
import {DOM} from 'angular2/src/core/dom/dom_adapter';
|
||||||
import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
||||||
|
import {Injectable, Inject, OpaqueToken} from 'angular2/di';
|
||||||
|
|
||||||
|
export const EVENT_MANAGER_PLUGINS: OpaqueToken =
|
||||||
|
CONST_EXPR(new OpaqueToken("EventManagerPlugins"));
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
export class EventManager {
|
export class EventManager {
|
||||||
constructor(public _plugins: EventManagerPlugin[], public _zone: NgZone) {
|
private _plugins: EventManagerPlugin[];
|
||||||
for (var i = 0; i < _plugins.length; i++) {
|
|
||||||
_plugins[i].manager = this;
|
constructor(@Inject(EVENT_MANAGER_PLUGINS) plugins: EventManagerPlugin[], private _zone: NgZone) {
|
||||||
}
|
plugins.forEach(p => p.manager = this);
|
||||||
|
this._plugins = ListWrapper.reversed(plugins);
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventListener(element: HTMLElement, eventName: string, handler: Function) {
|
addEventListener(element: HTMLElement, eventName: string, handler: Function) {
|
||||||
|
@ -48,6 +61,7 @@ export class EventManagerPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
export class DomEventsPlugin extends EventManagerPlugin {
|
export class DomEventsPlugin extends EventManagerPlugin {
|
||||||
manager: EventManager;
|
manager: EventManager;
|
||||||
|
|
||||||
|
@ -56,16 +70,16 @@ export class DomEventsPlugin extends EventManagerPlugin {
|
||||||
supports(eventName: string): boolean { return true; }
|
supports(eventName: string): boolean { return true; }
|
||||||
|
|
||||||
addEventListener(element: HTMLElement, eventName: string, handler: Function) {
|
addEventListener(element: HTMLElement, eventName: string, handler: Function) {
|
||||||
var zone = this.manager._zone;
|
var zone = this.manager.getZone();
|
||||||
var outsideHandler = (event) => zone.run(() => handler(event));
|
var outsideHandler = (event) => zone.run(() => handler(event));
|
||||||
this.manager._zone.runOutsideAngular(() => { DOM.on(element, eventName, outsideHandler); });
|
this.manager.getZone().runOutsideAngular(() => { DOM.on(element, eventName, outsideHandler); });
|
||||||
}
|
}
|
||||||
|
|
||||||
addGlobalEventListener(target: string, eventName: string, handler: Function): Function {
|
addGlobalEventListener(target: string, eventName: string, handler: Function): Function {
|
||||||
var element = DOM.getGlobalEventTarget(target);
|
var element = DOM.getGlobalEventTarget(target);
|
||||||
var zone = this.manager._zone;
|
var zone = this.manager.getZone();
|
||||||
var outsideHandler = (event) => zone.run(() => handler(event));
|
var outsideHandler = (event) => zone.run(() => handler(event));
|
||||||
return this.manager._zone.runOutsideAngular(
|
return this.manager.getZone().runOutsideAngular(
|
||||||
() => { return DOM.onAndCancel(element, eventName, outsideHandler); });
|
() => { return DOM.onAndCancel(element, eventName, outsideHandler); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,11 @@ library angular.events;
|
||||||
import 'dart:html';
|
import 'dart:html';
|
||||||
import './hammer_common.dart';
|
import './hammer_common.dart';
|
||||||
import 'package:angular2/src/core/facade/lang.dart' show BaseException;
|
import 'package:angular2/src/core/facade/lang.dart' show BaseException;
|
||||||
|
import "package:angular2/di.dart" show Injectable;
|
||||||
|
|
||||||
import 'dart:js' as js;
|
import 'dart:js' as js;
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
class HammerGesturesPlugin extends HammerGesturesPluginCommon {
|
class HammerGesturesPlugin extends HammerGesturesPluginCommon {
|
||||||
bool supports(String eventName) {
|
bool supports(String eventName) {
|
||||||
if (!super.supports(eventName)) return false;
|
if (!super.supports(eventName)) return false;
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
import {HammerGesturesPluginCommon} from './hammer_common';
|
import {HammerGesturesPluginCommon} from './hammer_common';
|
||||||
import {isPresent, BaseException} from 'angular2/src/core/facade/lang';
|
import {isPresent, BaseException} from 'angular2/src/core/facade/lang';
|
||||||
|
import {Injectable} from 'angular2/di';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
export class HammerGesturesPlugin extends HammerGesturesPluginCommon {
|
export class HammerGesturesPlugin extends HammerGesturesPluginCommon {
|
||||||
constructor() { super(); }
|
|
||||||
|
|
||||||
supports(eventName: string): boolean {
|
supports(eventName: string): boolean {
|
||||||
if (!super.supports(eventName)) return false;
|
if (!super.supports(eventName)) return false;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
import {StringMapWrapper, ListWrapper} from 'angular2/src/core/facade/collection';
|
import {StringMapWrapper, ListWrapper} from 'angular2/src/core/facade/collection';
|
||||||
import {EventManagerPlugin} from './event_manager';
|
import {EventManagerPlugin} from './event_manager';
|
||||||
import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
||||||
|
import {Injectable} from 'angular2/di';
|
||||||
|
|
||||||
var modifierKeys = ['alt', 'control', 'meta', 'shift'];
|
var modifierKeys = ['alt', 'control', 'meta', 'shift'];
|
||||||
var modifierKeyGetters: StringMap<string, Function> = {
|
var modifierKeyGetters: StringMap<string, Function> = {
|
||||||
|
@ -19,6 +20,7 @@ var modifierKeyGetters: StringMap<string, Function> = {
|
||||||
'shift': (event) => event.shiftKey
|
'shift': (event) => event.shiftKey
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
export class KeyEventsPlugin extends EventManagerPlugin {
|
export class KeyEventsPlugin extends EventManagerPlugin {
|
||||||
constructor() { super(); }
|
constructor() { super(); }
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,11 @@ import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
||||||
|
|
||||||
import {DOM} from 'angular2/src/core/dom/dom_adapter';
|
import {DOM} from 'angular2/src/core/dom/dom_adapter';
|
||||||
|
|
||||||
import {EventManager, DomEventsPlugin} from 'angular2/src/core/render/dom/events/event_manager';
|
import {
|
||||||
|
EventManager,
|
||||||
|
DomEventsPlugin,
|
||||||
|
EVENT_MANAGER_PLUGINS
|
||||||
|
} from 'angular2/src/core/render/dom/events/event_manager';
|
||||||
|
|
||||||
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
|
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
|
||||||
import {MockXHR} from 'angular2/src/core/render/xhr_mock';
|
import {MockXHR} from 'angular2/src/core/render/xhr_mock';
|
||||||
|
@ -144,15 +148,8 @@ function _getAppBindings() {
|
||||||
StyleInliner,
|
StyleInliner,
|
||||||
TestComponentBuilder,
|
TestComponentBuilder,
|
||||||
bind(NgZone).toClass(MockNgZone),
|
bind(NgZone).toClass(MockNgZone),
|
||||||
bind(EventManager)
|
EventManager,
|
||||||
.toFactory(
|
new Binding(EVENT_MANAGER_PLUGINS, {toClass: DomEventsPlugin, multi: true})
|
||||||
(zone) => {
|
|
||||||
var plugins = [
|
|
||||||
new DomEventsPlugin(),
|
|
||||||
];
|
|
||||||
return new EventManager(plugins, zone);
|
|
||||||
},
|
|
||||||
[NgZone]),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,11 @@ import {
|
||||||
PreGeneratedChangeDetection
|
PreGeneratedChangeDetection
|
||||||
} from 'angular2/src/core/change_detection/change_detection';
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
import {DEFAULT_PIPES} from 'angular2/pipes';
|
import {DEFAULT_PIPES} from 'angular2/pipes';
|
||||||
import {EventManager, DomEventsPlugin} from 'angular2/src/core/render/dom/events/event_manager';
|
import {
|
||||||
|
EventManager,
|
||||||
|
DomEventsPlugin,
|
||||||
|
EVENT_MANAGER_PLUGINS
|
||||||
|
} from 'angular2/src/core/render/dom/events/event_manager';
|
||||||
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||||
import {BrowserDomAdapter} from 'angular2/src/core/dom/browser_adapter';
|
import {BrowserDomAdapter} from 'angular2/src/core/dom/browser_adapter';
|
||||||
import {KeyEventsPlugin} from 'angular2/src/core/render/dom/events/key_events';
|
import {KeyEventsPlugin} from 'angular2/src/core/render/dom/events/key_events';
|
||||||
|
@ -87,14 +91,10 @@ function _injectorBindings(): any[] {
|
||||||
return [
|
return [
|
||||||
bind(DOCUMENT)
|
bind(DOCUMENT)
|
||||||
.toValue(DOM.defaultDoc()),
|
.toValue(DOM.defaultDoc()),
|
||||||
bind(EventManager)
|
EventManager,
|
||||||
.toFactory(
|
new Binding(EVENT_MANAGER_PLUGINS, {toClass: DomEventsPlugin, multi: true}),
|
||||||
(ngZone) => {
|
new Binding(EVENT_MANAGER_PLUGINS, {toClass: KeyEventsPlugin, multi: true}),
|
||||||
var plugins =
|
new Binding(EVENT_MANAGER_PLUGINS, {toClass: HammerGesturesPlugin, multi: true}),
|
||||||
[new HammerGesturesPlugin(), new KeyEventsPlugin(), new DomEventsPlugin()];
|
|
||||||
return new EventManager(plugins, ngZone);
|
|
||||||
},
|
|
||||||
[NgZone]),
|
|
||||||
DomRenderer,
|
DomRenderer,
|
||||||
bind(Renderer).toAlias(DomRenderer),
|
bind(Renderer).toAlias(DomRenderer),
|
||||||
APP_ID_RANDOM_BINDING,
|
APP_ID_RANDOM_BINDING,
|
||||||
|
|
|
@ -25,14 +25,15 @@ export function main() {
|
||||||
|
|
||||||
describe('EventManager', () => {
|
describe('EventManager', () => {
|
||||||
|
|
||||||
it('should delegate event bindings to plugins', () => {
|
it('should delegate event bindings to plugins that are passed in from the most generic one to the most specific one',
|
||||||
var element = el('<div></div>');
|
() => {
|
||||||
var handler = (e) => e;
|
var element = el('<div></div>');
|
||||||
var plugin = new FakeEventManagerPlugin(['click']);
|
var handler = (e) => e;
|
||||||
var manager = new EventManager([plugin, domEventPlugin], new FakeNgZone());
|
var plugin = new FakeEventManagerPlugin(['click']);
|
||||||
manager.addEventListener(element, 'click', handler);
|
var manager = new EventManager([domEventPlugin, plugin], new FakeNgZone());
|
||||||
expect(plugin._eventHandler.get('click')).toBe(handler);
|
manager.addEventListener(element, 'click', handler);
|
||||||
});
|
expect(plugin._eventHandler.get('click')).toBe(handler);
|
||||||
|
});
|
||||||
|
|
||||||
it('should delegate event bindings to the first plugin supporting the event', () => {
|
it('should delegate event bindings to the first plugin supporting the event', () => {
|
||||||
var element = el('<div></div>');
|
var element = el('<div></div>');
|
||||||
|
@ -40,7 +41,7 @@ export function main() {
|
||||||
var dblClickHandler = (e) => e;
|
var dblClickHandler = (e) => e;
|
||||||
var plugin1 = new FakeEventManagerPlugin(['dblclick']);
|
var plugin1 = new FakeEventManagerPlugin(['dblclick']);
|
||||||
var plugin2 = new FakeEventManagerPlugin(['click', 'dblclick']);
|
var plugin2 = new FakeEventManagerPlugin(['click', 'dblclick']);
|
||||||
var manager = new EventManager([plugin1, plugin2], new FakeNgZone());
|
var manager = new EventManager([plugin2, plugin1], new FakeNgZone());
|
||||||
manager.addEventListener(element, 'click', clickHandler);
|
manager.addEventListener(element, 'click', clickHandler);
|
||||||
manager.addEventListener(element, 'dblclick', dblClickHandler);
|
manager.addEventListener(element, 'dblclick', dblClickHandler);
|
||||||
expect(plugin1._eventHandler.has('click')).toBe(false);
|
expect(plugin1._eventHandler.has('click')).toBe(false);
|
||||||
|
|
Loading…
Reference in New Issue