aboutsummaryrefslogtreecommitdiffstats
path: root/lib/caldav/responder.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/caldav/responder.js')
-rw-r--r--lib/caldav/responder.js209
1 files changed, 209 insertions, 0 deletions
diff --git a/lib/caldav/responder.js b/lib/caldav/responder.js
new file mode 100644
index 0000000..b4abd21
--- /dev/null
+++ b/lib/caldav/responder.js
@@ -0,0 +1,209 @@
+/**
+@namespace
+*/
+(function(module, ns) {
+
+ /**
+ * Constructor
+ *
+ * @param {Object} list of events to add onto responder.
+ */
+ function Responder(events) {
+ this._$events = Object.create(null);
+
+ if (typeof(events) !== 'undefined') {
+ this.addEventListener(events);
+ }
+ };
+
+ /**
+ * Stringifies request to websocket
+ *
+ *
+ * @param {String} command command name.
+ * @param {Object} data object to be sent over the wire.
+ * @return {String} json object.
+ */
+ Responder.stringify = function stringify(command, data) {
+ return JSON.stringify([command, data]);
+ };
+
+ /**
+ * Parses request from WebSocket.
+ *
+ * @param {String} json json string to translate.
+ * @return {Object} ex: { event: 'test', data: {} }.
+ */
+ Responder.parse = function parse(json) {
+ var data;
+ try {
+ data = (json.forEach) ? json : JSON.parse(json);
+ } catch (e) {
+ throw new Error("Could not parse json: '" + json + '"');
+ }
+
+ return {event: data[0], data: data[1]};
+ };
+
+ Responder.prototype = {
+ parse: Responder.parse,
+ stringify: Responder.stringify,
+
+ /**
+ * Events on this instance
+ *
+ * @type Object
+ */
+ _$events: null,
+
+ /**
+ * Recieves json string event and dispatches an event.
+ *
+ * @param {String|Object} json data object to respond to.
+ * @param {String} json.event event to emit.
+ * @param {Object} json.data data to emit with event.
+ * @param {Object} [params] option number of params to pass to emit.
+ * @return {Object} result of WebSocketCommon.parse.
+ */
+ respond: function respond(json) {
+ var event = Responder.parse(json),
+ args = Array.prototype.slice.call(arguments).slice(1);
+
+ args.unshift(event.data);
+ args.unshift(event.event);
+
+ this.emit.apply(this, args);
+
+ return event;
+ },
+
+ //TODO: Extract event emitter logic
+
+ /**
+ * Adds an event listener to this object.
+ *
+ *
+ * @param {String} type event name.
+ * @param {Function} callback event callback.
+ */
+ addEventListener: function addEventListener(type, callback) {
+ var event;
+
+ if (typeof(callback) === 'undefined' && typeof(type) === 'object') {
+ for (event in type) {
+ if (type.hasOwnProperty(event)) {
+ this.addEventListener(event, type[event]);
+ }
+ }
+
+ return this;
+ }
+
+ if (!(type in this._$events)) {
+ this._$events[type] = [];
+ }
+
+ this._$events[type].push(callback);
+
+ return this;
+ },
+
+ /**
+ * Adds an event listener which will
+ * only fire once and then remove itself.
+ *
+ *
+ * @param {String} type event name.
+ * @param {Function} callback fired when event is emitted.
+ */
+ once: function once(type, callback) {
+ var self = this;
+ function onceCb() {
+ self.removeEventListener(type, onceCb);
+ callback.apply(this, arguments);
+ }
+
+ this.addEventListener(type, onceCb);
+
+ return this;
+ },
+
+ /**
+ * Emits an event.
+ *
+ * Accepts any number of additional arguments to pass unto
+ * event listener.
+ *
+ * @param {String} eventName name of the event to emit.
+ * @param {Object} [arguments] additional arguments to pass.
+ */
+ emit: function emit() {
+ var args = Array.prototype.slice.call(arguments),
+ event = args.shift(),
+ eventList,
+ self = this;
+
+ if (event in this._$events) {
+ eventList = this._$events[event];
+
+ eventList.forEach(function(callback) {
+ callback.apply(self, args);
+ });
+ }
+
+ return this;
+ },
+
+ /**
+ * Removes all event listeners for a given event type
+ *
+ *
+ * @param {String} event event type to remove.
+ */
+ removeAllEventListeners: function removeAllEventListeners(name) {
+ if (name in this._$events) {
+ //reuse array
+ this._$events[name].length = 0;
+ }
+
+ return this;
+ },
+
+ /**
+ * Removes a single event listener from a given event type
+ * and callback function.
+ *
+ *
+ * @param {String} eventName event name.
+ * @param {Function} callback same instance of event handler.
+ */
+ removeEventListener: function removeEventListener(name, callback) {
+ var i, length, events;
+
+ if (!(name in this._$events)) {
+ return false;
+ }
+
+ events = this._$events[name];
+
+ for (i = 0, length = events.length; i < length; i++) {
+ if (events[i] && events[i] === callback) {
+ events.splice(i, 1);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ };
+
+ Responder.prototype.on = Responder.prototype.addEventListener;
+ module.exports = Responder;
+
+}.apply(
+ this,
+ (this.CalDav) ?
+ [CalDav('responder'), CalDav] :
+ [module, require('./caldav')]
+));