1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-17 22:47:59 +00:00
seahub/media/aloha-0.22.7/lib/vendor/pubsub/js/pubsub-unminified.js
llj 720ac28c22 [aloha] upgraded to 0.22.7 and added textcolor plugin
* textcolor: fixed plugin bugs, added translation for zh
* image: fixed default.jpg src bug
* added 'ru' support for seaf edit
* rm aloha-0.22.3 and ununsed files in aloha-0.22.7
2013-01-15 14:48:04 +08:00

188 lines
4.9 KiB
JavaScript

/*!
* Aloha Editor
* Author & Copyright (c) 2012 Gentics Software GmbH
* aloha-sales@gentics.com
* Licensed under the terms of http://www.aloha-editor.com/license.html
*
* @overview Provides methods to broker publish/subscribe facilities.
*/
define('PubSub', [], function () {
'use strict';
/**
* A hash of channel names mapped to an array of ids of subscriptions that
* are listening on that channel.
*
* @type {Object<String, Array.<Number>>}
*/
var channels = {};
/**
* A hash of subscription tuples (channel, callback), mapped against unique
* ids assigned to each subscription.
* As subscriptions are removed from this object via `unsub()' this object
* will become a sparse array.
*
* @type {Object<Number, Object>}
*/
var subscriptions = {};
/**
* The last used subscription id. This values is only used and modified in
* `sub().'
*
* @type {number}
*/
var sid = 0;
/**
* Returns the channel to which a subscription matching the given sid is
* listening on.
*
* @param {Number} sid Id of subscription.
* @return {Array.<Object>} sid Id of subscription.
*/
function getSubscriptionChannel(sid) {
return subscriptions[sid] && channels[subscriptions[sid].channel];
}
/**
* Publishes a message `message' on the given channel.
* All callbacks that have sub()scribed to listen on this channel will be
* invoked and receive `message' as their only argument.
*
* @private
* @param {String} channel Name of channel to publish the message on.
* @param {*} message Variable to pass to all callbacks listening on the
* given channel.
* @return {Number} The number of subscribed callbacks that were invoked.
*/
function pub(channel, message) {
if (!channels[channel]) {
return 0;
}
if (!message) {
message = {};
} else if (typeof message !== 'object') {
message = {
data: message
};
}
message.channel = channel;
// Clone a immutable snapshot of the subscription ids that we can
// safetly iterate over.
var sids = channels[channel].slice();
// NB: It is necessary to read the size of the `sids' array on each
// iteration, in case the size changes (via unsubscription) between
// iterations.
var i;
for (i = 0; i < sids.length; ++i) {
subscriptions[sids[i]].callback(message);
}
return i;
}
var PubSub = {
/**
* Subscribes a callback function to a channel. Whenever this channel
* publishes, this function will be invoked. The return value is an id
* which identifies this subscription (a channel, and callback tuple).
* This id can be used to unsubscribe this subscription from the given
* channel.
*
* @param {String} channel Name of channel to listen on.
* @param {Function(Object)} callback Function to be invoked when
* messages are published on the
* given channel.
* @return {Number} Positive integer representing the sid of this
* subscription, that can be used with unsub() if
* subscription succeeds. Otherwise the return value
* is -1;
*/
sub: function (channel, callback) {
if (typeof callback !== 'function') {
return -1;
}
var subscriptionIds = channels[channel];
if (!subscriptionIds) {
subscriptionIds = channels[channel] = [];
}
subscriptionIds.push(++sid);
subscriptions[sid] = {
channel : channel,
callback : callback
};
return sid;
},
/**
* Unsubscribes callback using an sid which was returned by sub() when
* the callback was subscribed. Returns true if a subscription for
* this sid was found and removed, otherwise returns false.
*
* @param {Number} sid Id of subscription.
* @return {Boolean} True if a a subscription matching this sid was
* removed.
*/
unsub: function (sid) {
if (-1 === sid || !subscriptions[sid]) {
return false;
}
var subscriptionIds = getSubscriptionChannel(sid);
// assert(typeof subscriptionIds === 'array')
delete subscriptions[sid];
var j = subscriptionIds.length;
while (j) {
if (subscriptionIds[--j] === sid) {
subscriptionIds.splice(j, 1);
return true;
}
}
return false;
},
/**
* Publishes a message `message' on all channels that can be derived
* from the given channel name.
*
* @param {String} channel Name of channel to publish the message on.
* @param {*} message Variable to pass to all callbacks listening on
* the given channel.
* @return {Number} The number of subscribed callbacks that were
* invoked.
*/
pub: function (channel, message) {
var segments = channel.split('.');
var i;
var len = segments.length;
var channelName = '';
var tally = 0;
for (i = 0; i < len; ++i) {
channelName += (0 === i ? '' : '.') + segments[i];
tally += pub(channelName, message);
}
return tally;
}
};
return PubSub;
});