VulpesOS/gaia/apps/calendar/js/common/responder.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

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;
});