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