Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
236 lines
5.6 KiB
JavaScript
Executable file
236 lines
5.6 KiB
JavaScript
Executable file
// this code is from test-agent might use native dom events
|
|
// or something else in the future to replace this.
|
|
define(function(require, exports, module) {
|
|
'use strict';
|
|
|
|
/**
|
|
* @param {Object} list of events to add onto responder.
|
|
*/
|
|
function Responder(events) {
|
|
this._$events = Object.create(null);
|
|
|
|
// Buffer for emitWhenListener that hangs onto events dispatched for topics
|
|
// no one is currently listening for. Inspired by email's function
|
|
// of the same name.
|
|
this.buffer = {};
|
|
|
|
if (typeof(events) !== 'undefined') {
|
|
this.addEventListener(events);
|
|
}
|
|
}
|
|
module.exports = Responder;
|
|
|
|
/**
|
|
* 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 data;
|
|
};
|
|
|
|
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);
|
|
var args = Array.prototype.slice.call(arguments).slice(1);
|
|
this.emit.apply(this, event.concat(args));
|
|
return event;
|
|
},
|
|
|
|
/**
|
|
* 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.flushTopicBuffer(type);
|
|
},
|
|
|
|
/**
|
|
* 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() {
|
|
/*jshint validthis:true */
|
|
self.removeEventListener(type, onceCb);
|
|
callback.apply(this, arguments);
|
|
}
|
|
|
|
this.addEventListener(type, onceCb);
|
|
return this.flushTopicBuffer(type);
|
|
},
|
|
|
|
flushTopicBuffer: function flushTopicBuffer(topic) {
|
|
if (!(topic in this.buffer)) {
|
|
// Nothing to flush.
|
|
return this;
|
|
}
|
|
|
|
this.buffer[topic].forEach(args => {
|
|
args.unshift(topic);
|
|
this.emit.apply(this, args);
|
|
});
|
|
|
|
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) {
|
|
if (typeof(callback) === 'object' && callback.handleEvent) {
|
|
callback.handleEvent({ type: event, data: args });
|
|
} else {
|
|
callback.apply(self, args);
|
|
}
|
|
});
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
emitWhenListener: function emitWhenListener() {
|
|
var args = Array.prototype.slice.call(arguments);
|
|
var event = args.shift();
|
|
|
|
if (event in this._$events && this._$events[event].length) {
|
|
// Someone is already listening for this event, so this is just
|
|
// a regular old emit.
|
|
return this.emit.apply(this, arguments);
|
|
}
|
|
|
|
if (!(event in this.buffer)) {
|
|
this.buffer[event] = [];
|
|
}
|
|
|
|
// Now just push the call info onto the topic buffer.
|
|
this.buffer[event].push(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;
|
|
Responder.prototype.off = Responder.prototype.removeEventListener;
|
|
|
|
});
|