From 67d440f59be7ff71b2094489499fb94574f19913 Mon Sep 17 00:00:00 2001 From: Stanimir Karoserov Date: Wed, 11 Jun 2014 15:59:24 +0300 Subject: [PATCH] added event handling code --- BCL.csproj | 1 + ui/core/event-manager.ts | 99 ++++++++++++++++++++++++++++++++++++++++ ui/core/observable.ts | 71 +++++++++++++++++++--------- 3 files changed, 150 insertions(+), 21 deletions(-) create mode 100644 ui/core/event-manager.ts diff --git a/BCL.csproj b/BCL.csproj index 26c484dee..e88f9728c 100644 --- a/BCL.csproj +++ b/BCL.csproj @@ -258,6 +258,7 @@ + diff --git a/ui/core/event-manager.ts b/ui/core/event-manager.ts new file mode 100644 index 000000000..e6e2026ee --- /dev/null +++ b/ui/core/event-manager.ts @@ -0,0 +1,99 @@ + +/** +This is currently for reference only. Use Observable instead. +Unlike Observable, EventManager provides additional user data (called context) + +Usage: + +``` +var eventManagerModule = require("ui/core/event-manager"); + +var eventManager = new eventManagerModule.EventManager(); +eventManager.on("click", function(eventData, context) { + console.log("clicked with data: " + eventData + ", context: " + context); +}, "context"); + +eventManager.emit("click"); +eventManager.emit("click", "click1"); + +var f = function(eventData, context) { + console.log("tested with data: " + eventData + ", context: " + context); +}; + +eventManager.on("test1, click", f); + +eventManager.emit("click", "should be doubled"); +eventManager.emit("test1"); + +eventManager.off("click", f); +eventManager.emit("click", "click3"); + +eventManager.off("test1"); +eventManager.emit("test1", "test3"); +``` +*/ +export interface EventHandler { + (eventData?: any, context?: any): void; +} + +interface Event { + func: EventHandler; + context: any; +} + +export class EventManager { + + private events: any = {}; + + public on(events: string, func: EventHandler, context?: any) { + var eventNames: Array = events.split(","); + var that = this; + eventNames.forEach(function (event: string) { + var eventTrimmed = event.trim(); + var newEvent: Event = { func: func, context: context }; + var ev: Array = that.events[eventTrimmed]; + if (!ev) { + ev = [newEvent]; + that.events[eventTrimmed] = ev; + } + else { + ev.push(newEvent); + } + }); + } + + public off(events: string, func?: EventHandler) { + var eventNames:Array = events.split(","); + var that = this; + eventNames.forEach(function (event: string) { + var eventTrimmed = event.trim(); + if (!func) { + that.events[eventTrimmed] = undefined; + } + else { + var ev: Array = that.events[eventTrimmed]; + if (ev) { + ev.forEach(function (e:Event, idx:number) { + if (e.func == func) { + ev.splice(idx, 1); + return; + } + }); + } + } + }); + } + + public emit(events: string, eventData?: any) { + var eventNames:Array = events.split(","); + var that = this; + eventNames.forEach(function (event: string) { + var ev: Array = that.events[event.trim()]; + if (ev) { + ev.forEach(function (e: Event) { + e.func(eventData, e.context); + }); + } + }); + } +} diff --git a/ui/core/observable.ts b/ui/core/observable.ts index 2418f9c64..8e31d3017 100644 --- a/ui/core/observable.ts +++ b/ui/core/observable.ts @@ -3,9 +3,12 @@ Changed } -export interface ChangeData { +export interface EventData { eventName: string; sender: Observable; +} + +export interface ChangeData extends EventData { phase?: ChangePhase; } @@ -19,29 +22,46 @@ export class Observable { public static propertyChangeEvent = "propertyChange"; private _observers = {}; + public on: (eventNames: string, callback: (data: EventData) => void) => void; + public off: (eventNames: string, callback?: any) => void; + public addListener: (eventNames: string, callback: (data: EventData) => void) => void; + public removeListener: (eventNames: string, callback?: any) => void; + // true to track the Changing phase, false otherwise private _trackChanging = false; constructor(body?: any) { - // TODO: Not implemented + this.on = this.addListener = this.addObserver; + this.off = this.removeListener = this.removeObserver; } - public addObserver(eventName: string, callback: (data: ChangeData) => void) { - this.verifyCallback(callback); - var list = this.getEventList(eventName, true); - list.push(callback); + public addObserver(eventNames: string, callback: (data: EventData) => void) { + Observable.verifyCallback(callback); + var events: Array = eventNames.split(","); + var that = this; + events.forEach(function (event: string) { + var list = that.getEventList(event.trim(), true); + list.push(callback); + }); } - public removeObserver(eventName: string, callback: any) { - var list = this.getEventList(eventName, false); - if (!list) { - return; - } - - var index = list.indexOf(callback); - if (index >= 0) { - list.splice(index, 1); - } + public removeObserver(eventNames: string, callback?: any) { + var events: Array = eventNames.split(","); + var that = this; + events.forEach(function (event: string) { + if (callback) { + var list = that.getEventList(event.trim(), false); + if (list) { + var index = list.indexOf(callback); + if (index >= 0) { + list.splice(index, 1); + } + } + } + else { + that._observers[event.trim()] = undefined; + } + }); } public setProperty(name: string, value: any) { @@ -77,7 +97,7 @@ export class Observable { } // The method will return true if the change is accepted, false otherwise - public notify(data: ChangeData) { + public notify(data: EventData) { var observers = this.getEventList(data.eventName); if (!observers) { return; @@ -105,23 +125,32 @@ export class Observable { }; } - private getEventList(eventName: string, createIfNeeded?: boolean): Array<(data: ChangeData) => void> { + private getEventList(eventName: string, createIfNeeded?: boolean): Array<(data: EventData) => void> { if (!eventName) { throw new TypeError("EventName must be valid string."); } - var list = void>>this._observers[eventName]; + var list = void>>this._observers[eventName]; if (!list && createIfNeeded) { - list = new Array<(data: ChangeData) => void>(); + list = []; this._observers[eventName] = list; } return list; } - private verifyCallback(callback: any) { + private static verifyCallback(callback: any) { if (!callback || typeof callback !== "function") { throw new TypeError("Callback must be a valid function."); } } + + public emit(eventNames: string) { + var events: Array = eventNames.split(","); + var that = this; + events.forEach(function (event: string) { + that.notify({ eventName: event.trim(), sender: this }); + }); + } + } \ No newline at end of file