feat(events): adds support for bubbling native events (^event).
Refactor - move DomEventManager into its own plugin.
This commit is contained in:
4
modules/angular2/src/core/application.js
vendored
4
modules/angular2/src/core/application.js
vendored
@ -16,7 +16,7 @@ import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||
import {XHR} from 'angular2/src/core/compiler/xhr/xhr';
|
||||
import {XHRImpl} from 'angular2/src/core/compiler/xhr/xhr_impl';
|
||||
import {EventManager} from 'angular2/src/core/events/event_manager';
|
||||
import {EventManager, DomEventsPlugin} from 'angular2/src/core/events/event_manager';
|
||||
import {HammerGesturesPlugin} from 'angular2/src/core/events/hammer_gestures';
|
||||
import {Binding} from 'angular2/src/di/binding';
|
||||
|
||||
@ -75,7 +75,7 @@ function _injectorBindings(appComponentType): List<Binding> {
|
||||
[appViewToken]),
|
||||
bind(LifeCycle).toFactory((exceptionHandler) => new LifeCycle(exceptionHandler, null, assertionsEnabled()),[ExceptionHandler]),
|
||||
bind(EventManager).toFactory((zone) => {
|
||||
var plugins = [new HammerGesturesPlugin()];
|
||||
var plugins = [new HammerGesturesPlugin(), new DomEventsPlugin()];
|
||||
return new EventManager(plugins, zone);
|
||||
}, [VmTurnZone]),
|
||||
bind(ShadowDomStrategy).toValue(new NativeShadowDomStrategy()),
|
||||
|
@ -1,8 +1,10 @@
|
||||
import {isBlank, BaseException, isPresent} from 'angular2/src/facade/lang';
|
||||
import {isBlank, BaseException, isPresent, StringWrapper} from 'angular2/src/facade/lang';
|
||||
import {DOM, Element} from 'angular2/src/facade/dom';
|
||||
import {List, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
|
||||
|
||||
var BUBBLE_SYMBOL = '^';
|
||||
|
||||
export class EventManager {
|
||||
_plugins: List<EventManagerPlugin>;
|
||||
_zone: VmTurnZone;
|
||||
@ -16,13 +18,13 @@ export class EventManager {
|
||||
}
|
||||
|
||||
addEventListener(element: Element, eventName: string, handler: Function) {
|
||||
var plugin = this._findPluginFor(eventName);
|
||||
|
||||
if (isPresent(plugin)) {
|
||||
plugin.addEventListener(element, eventName, handler);
|
||||
} else {
|
||||
this._addNativeEventListener(element, eventName, handler);
|
||||
var shouldSupportBubble = eventName[0] == BUBBLE_SYMBOL;
|
||||
if (shouldSupportBubble) {
|
||||
eventName = StringWrapper.substring(eventName, 1);
|
||||
}
|
||||
|
||||
var plugin = this._findPluginFor(eventName);
|
||||
plugin.addEventListener(element, eventName, handler, shouldSupportBubble);
|
||||
}
|
||||
|
||||
getZone(): VmTurnZone {
|
||||
@ -37,30 +39,56 @@ export class EventManager {
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
_addNativeEventListener(element: Element, eventName: string, handler: Function) {
|
||||
this._zone.runOutsideAngular(() => {
|
||||
DOM.on(element, eventName, (event) => {
|
||||
if (event.target === element) {
|
||||
this._zone.run(function() {
|
||||
handler(event);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
throw new BaseException(`No event manager plugin found for event ${eventName}`);
|
||||
}
|
||||
}
|
||||
|
||||
export class EventManagerPlugin {
|
||||
manager: EventManager;
|
||||
|
||||
// We are assuming here that all plugins support bubbled and non-bubbled events.
|
||||
// That is equivalent to having supporting $event.target
|
||||
// The bubbling flag (currently ^) is stripped before calling the supports and
|
||||
// addEventListener methods.
|
||||
supports(eventName: string): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
addEventListener(element: Element, eventName: string, handler: Function) {
|
||||
addEventListener(element: Element, eventName: string, handler: Function,
|
||||
shouldSupportBubble: boolean) {
|
||||
throw "not implemented";
|
||||
}
|
||||
}
|
||||
|
||||
export class DomEventsPlugin extends EventManagerPlugin {
|
||||
manager: EventManager;
|
||||
|
||||
// This plugin should come last in the list of plugins, because it accepts all
|
||||
// events.
|
||||
supports(eventName: string): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
addEventListener(element: Element, eventName: string, handler: Function,
|
||||
shouldSupportBubble: boolean) {
|
||||
var outsideHandler = shouldSupportBubble ?
|
||||
DomEventsPlugin.bubbleCallback(element, handler, this.manager._zone) :
|
||||
DomEventsPlugin.sameElementCallback(element, handler, this.manager._zone);
|
||||
|
||||
this.manager._zone.runOutsideAngular(() => {
|
||||
DOM.on(element, eventName, outsideHandler);
|
||||
});
|
||||
}
|
||||
|
||||
static sameElementCallback(element, handler, zone) {
|
||||
return (event) => {
|
||||
if (event.target === element) {
|
||||
zone.run(() => handler(event));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static bubbleCallback(element, handler, zone) {
|
||||
return (event) => zone.run(() => handler(event));
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ class HammerGesturesPlugin extends HammerGesturesPluginCommon {
|
||||
return true;
|
||||
}
|
||||
|
||||
addEventListener(Element element, String eventName, Function handler) {
|
||||
addEventListener(Element element, String eventName, Function handler, bool shouldSupportBubble) {
|
||||
if (shouldSupportBubble) throw new BaseException('Hammer.js plugin does not support bubbling gestures.');
|
||||
var zone = this.manager.getZone();
|
||||
eventName = eventName.toLowerCase();
|
||||
|
||||
|
@ -17,7 +17,8 @@ export class HammerGesturesPlugin extends HammerGesturesPluginCommon {
|
||||
return true;
|
||||
}
|
||||
|
||||
addEventListener(element:Element, eventName:string, handler:Function) {
|
||||
addEventListener(element:Element, eventName:string, handler:Function, shouldSupportBubble: boolean) {
|
||||
if (shouldSupportBubble) throw new BaseException('Hammer.js plugin does not support bubbling gestures.');
|
||||
var zone = this.manager.getZone();
|
||||
eventName = eventName.toLowerCase();
|
||||
|
||||
|
Reference in New Issue
Block a user