Commit 3b0a3b78 authored by JC Brand's avatar JC Brand

Indented code.

parent 0121914c
...@@ -39,435 +39,435 @@ ...@@ -39,435 +39,435 @@
} }
}(this, function (Strophe, $build, $iq, $msg, $pres) { }(this, function (Strophe, $build, $iq, $msg, $pres) {
Strophe.addConnectionPlugin('roster', { Strophe.addConnectionPlugin('roster', {
/** Function: init /** Function: init
* Plugin init * Plugin init
* *
* Parameters: * Parameters:
* (Strophe.Connection) conn - Strophe connection * (Strophe.Connection) conn - Strophe connection
*/
init: function(conn)
{
this._connection = conn;
this._callbacks = [];
/** Property: items
* Roster items
* [
* {
* name : "",
* jid : "",
* subscription : "",
* ask : "",
* groups : ["", ""],
* resources : {
* myresource : {
* show : "",
* status : "",
* priority : ""
* }
* }
* }
* ]
*/
this.items = [];
/** Property: ver
* current roster revision
* always null if server doesn't support xep 237
*/ */
this.ver = null; init: function(conn)
// Override the connect and attach methods to always add presence and roster handlers.
// They are removed when the connection disconnects, so must be added on connection.
var oldCallback, roster = this, _connect = conn.connect, _attach = conn.attach;
var newCallback = function(status)
{ {
if (status == Strophe.Status.ATTACHED || status == Strophe.Status.CONNECTED) this._connection = conn;
this._callbacks = [];
/** Property: items
* Roster items
* [
* {
* name : "",
* jid : "",
* subscription : "",
* ask : "",
* groups : ["", ""],
* resources : {
* myresource : {
* show : "",
* status : "",
* priority : ""
* }
* }
* }
* ]
*/
this.items = [];
/** Property: ver
* current roster revision
* always null if server doesn't support xep 237
*/
this.ver = null;
// Override the connect and attach methods to always add presence and roster handlers.
// They are removed when the connection disconnects, so must be added on connection.
var oldCallback, roster = this, _connect = conn.connect, _attach = conn.attach;
var newCallback = function(status)
{ {
try if (status == Strophe.Status.ATTACHED || status == Strophe.Status.CONNECTED)
{ {
// Presence subscription try
conn.addHandler(roster._onReceivePresence.bind(roster), null, 'presence', null, null, null); {
conn.addHandler(roster._onReceiveIQ.bind(roster), Strophe.NS.ROSTER, 'iq', "set", null, null); // Presence subscription
conn.addHandler(roster._onReceivePresence.bind(roster), null, 'presence', null, null, null);
conn.addHandler(roster._onReceiveIQ.bind(roster), Strophe.NS.ROSTER, 'iq', "set", null, null);
}
catch (e)
{
Strophe.error(e);
}
} }
catch (e) if (typeof oldCallback === "function") {
{ oldCallback.apply(this, arguments);
Strophe.error(e);
} }
};
conn.connect = function(jid, pass, callback, wait, hold, route)
{
oldCallback = callback;
if (typeof jid == "undefined")
jid = null;
if (typeof pass == "undefined")
pass = null;
callback = newCallback;
_connect.apply(conn, [jid, pass, callback, wait, hold, route]);
};
conn.attach = function(jid, sid, rid, callback, wait, hold, wind)
{
oldCallback = callback;
if (typeof jid == "undefined")
jid = null;
if (typeof sid == "undefined")
sid = null;
if (typeof rid == "undefined")
rid = null;
callback = newCallback;
_attach.apply(conn, [jid, sid, rid, callback, wait, hold, wind]);
};
Strophe.addNamespace('ROSTER_VER', 'urn:xmpp:features:rosterver');
Strophe.addNamespace('NICK', 'http://jabber.org/protocol/nick');
},
/** Function: supportVersioning
* return true if roster versioning is enabled on server
*/
supportVersioning: function()
{
return (this._connection.features && this._connection.features.getElementsByTagName('ver').length > 0);
},
/** Function: get
* Get Roster on server
*
* Parameters:
* (Function) userCallback - callback on roster result
* (String) ver - current rev of roster
* (only used if roster versioning is enabled)
* (Array) items - initial items of ver
* (only used if roster versioning is enabled)
* In browser context you can use sessionStorage
* to store your roster in json (JSON.stringify())
*/
get: function(userCallback, ver, items)
{
var attrs = {xmlns: Strophe.NS.ROSTER};
if (this.supportVersioning())
{
// empty rev because i want an rev attribute in the result
attrs.ver = ver || '';
this.items = items || [];
} }
if (typeof oldCallback === "function") { var iq = $iq({type: 'get', 'id' : this._connection.getUniqueId('roster')}).c('query', attrs);
oldCallback.apply(this, arguments); return this._connection.sendIQ(iq,
} this._onReceiveRosterSuccess.bind(this, userCallback),
}; this._onReceiveRosterError.bind(this, userCallback));
conn.connect = function(jid, pass, callback, wait, hold, route) },
/** Function: registerCallback
* register callback on roster (presence and iq)
*
* Parameters:
* (Function) call_back
*/
registerCallback: function(call_back)
{ {
oldCallback = callback; this._callbacks.push(call_back);
if (typeof jid == "undefined") },
jid = null; /** Function: findItem
if (typeof pass == "undefined") * Find item by JID
pass = null; *
callback = newCallback; * Parameters:
_connect.apply(conn, [jid, pass, callback, wait, hold, route]); * (String) jid
}; */
conn.attach = function(jid, sid, rid, callback, wait, hold, wind) findItem : function(jid)
{ {
oldCallback = callback; try {
if (typeof jid == "undefined") for (var i = 0; i < this.items.length; i++)
jid = null; {
if (typeof sid == "undefined") if (this.items[i] && this.items[i].jid == jid)
sid = null; {
if (typeof rid == "undefined") return this.items[i];
rid = null; }
callback = newCallback; }
_attach.apply(conn, [jid, sid, rid, callback, wait, hold, wind]); } catch (e)
}; {
Strophe.error(e);
Strophe.addNamespace('ROSTER_VER', 'urn:xmpp:features:rosterver'); }
Strophe.addNamespace('NICK', 'http://jabber.org/protocol/nick'); return false;
}, },
/** Function: supportVersioning /** Function: removeItem
* return true if roster versioning is enabled on server * Remove item by JID
*/ *
supportVersioning: function() * Parameters:
{ * (String) jid
return (this._connection.features && this._connection.features.getElementsByTagName('ver').length > 0); */
}, removeItem : function(jid)
/** Function: get
* Get Roster on server
*
* Parameters:
* (Function) userCallback - callback on roster result
* (String) ver - current rev of roster
* (only used if roster versioning is enabled)
* (Array) items - initial items of ver
* (only used if roster versioning is enabled)
* In browser context you can use sessionStorage
* to store your roster in json (JSON.stringify())
*/
get: function(userCallback, ver, items)
{
var attrs = {xmlns: Strophe.NS.ROSTER};
if (this.supportVersioning())
{ {
// empty rev because i want an rev attribute in the result
attrs.ver = ver || '';
this.items = items || [];
}
var iq = $iq({type: 'get', 'id' : this._connection.getUniqueId('roster')}).c('query', attrs);
return this._connection.sendIQ(iq,
this._onReceiveRosterSuccess.bind(this, userCallback),
this._onReceiveRosterError.bind(this, userCallback));
},
/** Function: registerCallback
* register callback on roster (presence and iq)
*
* Parameters:
* (Function) call_back
*/
registerCallback: function(call_back)
{
this._callbacks.push(call_back);
},
/** Function: findItem
* Find item by JID
*
* Parameters:
* (String) jid
*/
findItem : function(jid)
{
try {
for (var i = 0; i < this.items.length; i++) for (var i = 0; i < this.items.length; i++)
{ {
if (this.items[i] && this.items[i].jid == jid) if (this.items[i] && this.items[i].jid == jid)
{ {
return this.items[i]; this.items.splice(i, 1);
return true;
} }
} }
} catch (e) return false;
},
/** Function: subscribe
* Subscribe presence
*
* Parameters:
* (String) jid
* (String) message (optional)
* (String) nick (optional)
*/
subscribe: function(jid, message, nick) {
var pres = $pres({to: jid, type: "subscribe"});
if (message && message !== "") {
pres.c("status").t(message).up();
}
if (nick && nick !== "") {
pres.c('nick', {'xmlns': Strophe.NS.NICK}).t(nick).up();
}
this._connection.send(pres);
},
/** Function: unsubscribe
* Unsubscribe presence
*
* Parameters:
* (String) jid
* (String) message
*/
unsubscribe: function(jid, message)
{ {
Strophe.error(e); var pres = $pres({to: jid, type: "unsubscribe"});
} if (message && message !== "")
return false; pres.c("status").t(message);
}, this._connection.send(pres);
/** Function: removeItem },
* Remove item by JID /** Function: authorize
* * Authorize presence subscription
* Parameters: *
* (String) jid * Parameters:
*/ * (String) jid
removeItem : function(jid) * (String) message
{ */
for (var i = 0; i < this.items.length; i++) authorize: function(jid, message)
{
var pres = $pres({to: jid, type: "subscribed"});
if (message && message !== "")
pres.c("status").t(message);
this._connection.send(pres);
},
/** Function: unauthorize
* Unauthorize presence subscription
*
* Parameters:
* (String) jid
* (String) message
*/
unauthorize: function(jid, message)
{ {
if (this.items[i] && this.items[i].jid == jid) var pres = $pres({to: jid, type: "unsubscribed"});
if (message && message !== "")
pres.c("status").t(message);
this._connection.send(pres);
},
/** Function: add
* Add roster item
*
* Parameters:
* (String) jid - item jid
* (String) name - name
* (Array) groups
* (Function) call_back
*/
add: function(jid, name, groups, call_back)
{
var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: jid,
name: name});
for (var i = 0; i < groups.length; i++)
{ {
this.items.splice(i, 1); iq.c('group').t(groups[i]).up();
return true;
} }
} this._connection.sendIQ(iq, call_back, call_back);
return false; },
}, /** Function: update
/** Function: subscribe * Update roster item
* Subscribe presence *
* * Parameters:
* Parameters: * (String) jid - item jid
* (String) jid * (String) name - name
* (String) message (optional) * (Array) groups
* (String) nick (optional) * (Function) call_back
*/ */
subscribe: function(jid, message, nick) { update: function(jid, name, groups, call_back)
var pres = $pres({to: jid, type: "subscribe"});
if (message && message !== "") {
pres.c("status").t(message).up();
}
if (nick && nick !== "") {
pres.c('nick', {'xmlns': Strophe.NS.NICK}).t(nick).up();
}
this._connection.send(pres);
},
/** Function: unsubscribe
* Unsubscribe presence
*
* Parameters:
* (String) jid
* (String) message
*/
unsubscribe: function(jid, message)
{
var pres = $pres({to: jid, type: "unsubscribe"});
if (message && message !== "")
pres.c("status").t(message);
this._connection.send(pres);
},
/** Function: authorize
* Authorize presence subscription
*
* Parameters:
* (String) jid
* (String) message
*/
authorize: function(jid, message)
{
var pres = $pres({to: jid, type: "subscribed"});
if (message && message !== "")
pres.c("status").t(message);
this._connection.send(pres);
},
/** Function: unauthorize
* Unauthorize presence subscription
*
* Parameters:
* (String) jid
* (String) message
*/
unauthorize: function(jid, message)
{
var pres = $pres({to: jid, type: "unsubscribed"});
if (message && message !== "")
pres.c("status").t(message);
this._connection.send(pres);
},
/** Function: add
* Add roster item
*
* Parameters:
* (String) jid - item jid
* (String) name - name
* (Array) groups
* (Function) call_back
*/
add: function(jid, name, groups, call_back)
{
var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: jid,
name: name});
for (var i = 0; i < groups.length; i++)
{ {
iq.c('group').t(groups[i]).up(); var item = this.findItem(jid);
} if (!item)
this._connection.sendIQ(iq, call_back, call_back); {
}, throw "item not found";
/** Function: update }
* Update roster item var newName = name || item.name;
* var newGroups = groups || item.groups;
* Parameters: var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: item.jid,
* (String) jid - item jid name: newName});
* (String) name - name for (var i = 0; i < newGroups.length; i++)
* (Array) groups {
* (Function) call_back iq.c('group').t(newGroups[i]).up();
*/ }
update: function(jid, name, groups, call_back) return this._connection.sendIQ(iq, call_back, call_back);
{ },
var item = this.findItem(jid); /** Function: remove
if (!item) * Remove roster item
*
* Parameters:
* (String) jid - item jid
* (Function) call_back
*/
remove: function(jid, call_back)
{ {
throw "item not found"; var item = this.findItem(jid);
} if (!item)
var newName = name || item.name; {
var newGroups = groups || item.groups; throw "item not found";
var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: item.jid, }
name: newName}); var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: item.jid,
for (var i = 0; i < newGroups.length; i++) subscription: "remove"});
this._connection.sendIQ(iq, call_back, call_back);
},
/** PrivateFunction: _onReceiveRosterSuccess
*
*/
_onReceiveRosterSuccess: function(userCallback, stanza)
{ {
iq.c('group').t(newGroups[i]).up(); this._updateItems(stanza);
} if (typeof userCallback === "function") {
return this._connection.sendIQ(iq, call_back, call_back); userCallback(this.items);
}, }
/** Function: remove },
* Remove roster item /** PrivateFunction: _onReceiveRosterError
* *
* Parameters: */
* (String) jid - item jid _onReceiveRosterError: function(userCallback, stanza)
* (Function) call_back
*/
remove: function(jid, call_back)
{
var item = this.findItem(jid);
if (!item)
{ {
throw "item not found";
}
var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: item.jid,
subscription: "remove"});
this._connection.sendIQ(iq, call_back, call_back);
},
/** PrivateFunction: _onReceiveRosterSuccess
*
*/
_onReceiveRosterSuccess: function(userCallback, stanza)
{
this._updateItems(stanza);
if (typeof userCallback === "function") {
userCallback(this.items); userCallback(this.items);
} },
}, /** PrivateFunction: _onReceivePresence
/** PrivateFunction: _onReceiveRosterError * Handle presence
* */
*/ _onReceivePresence : function(presence)
_onReceiveRosterError: function(userCallback, stanza)
{
userCallback(this.items);
},
/** PrivateFunction: _onReceivePresence
* Handle presence
*/
_onReceivePresence : function(presence)
{
// TODO: from is optional
var jid = presence.getAttribute('from');
var from = Strophe.getBareJidFromJid(jid);
var item = this.findItem(from);
// not in roster
if (!item)
{ {
// TODO: from is optional
var jid = presence.getAttribute('from');
var from = Strophe.getBareJidFromJid(jid);
var item = this.findItem(from);
// not in roster
if (!item)
{
return true;
}
var type = presence.getAttribute('type');
if (type == 'unavailable')
{
delete item.resources[Strophe.getResourceFromJid(jid)];
}
else if (!type)
{
// TODO: add timestamp
item.resources[Strophe.getResourceFromJid(jid)] = {
show : (presence.getElementsByTagName('show').length !== 0) ? Strophe.getText(presence.getElementsByTagName('show')[0]) : "",
status : (presence.getElementsByTagName('status').length !== 0) ? Strophe.getText(presence.getElementsByTagName('status')[0]) : "",
priority : (presence.getElementsByTagName('priority').length !== 0) ? Strophe.getText(presence.getElementsByTagName('priority')[0]) : ""
};
}
else
{
// Stanza is not a presence notification. (It's probably a subscription type stanza.)
return true;
}
this._call_backs(this.items, item);
return true; return true;
} },
var type = presence.getAttribute('type'); /** PrivateFunction: _call_backs
if (type == 'unavailable') *
{ */
delete item.resources[Strophe.getResourceFromJid(jid)]; _call_backs : function(items, item)
}
else if (!type)
{ {
// TODO: add timestamp for (var i = 0; i < this._callbacks.length; i++) // [].forEach my love ...
item.resources[Strophe.getResourceFromJid(jid)] = { {
show : (presence.getElementsByTagName('show').length !== 0) ? Strophe.getText(presence.getElementsByTagName('show')[0]) : "", this._callbacks[i](items, item);
status : (presence.getElementsByTagName('status').length !== 0) ? Strophe.getText(presence.getElementsByTagName('status')[0]) : "", }
priority : (presence.getElementsByTagName('priority').length !== 0) ? Strophe.getText(presence.getElementsByTagName('priority')[0]) : "" },
}; /** PrivateFunction: _onReceiveIQ
} * Handle roster push.
else */
_onReceiveIQ : function(iq)
{ {
// Stanza is not a presence notification. (It's probably a subscription type stanza.) var id = iq.getAttribute('id');
var from = iq.getAttribute('from');
// Receiving client MUST ignore stanza unless it has no from or from = user's JID.
if (from && from !== "" && from != this._connection.jid && from != Strophe.getBareJidFromJid(this._connection.jid))
return true;
var iqresult = $iq({type: 'result', id: id, from: this._connection.jid});
this._connection.send(iqresult);
this._updateItems(iq);
return true; return true;
} },
this._call_backs(this.items, item); /** PrivateFunction: _updateItems
return true; * Update items from iq
}, */
/** PrivateFunction: _call_backs _updateItems : function(iq)
*
*/
_call_backs : function(items, item)
{
for (var i = 0; i < this._callbacks.length; i++) // [].forEach my love ...
{ {
this._callbacks[i](items, item); var query = iq.getElementsByTagName('query');
} if (query.length !== 0)
}, {
/** PrivateFunction: _onReceiveIQ this.ver = query.item(0).getAttribute('ver');
* Handle roster push. var self = this;
*/ Strophe.forEachChild(query.item(0), 'item',
_onReceiveIQ : function(iq) function (item)
{ {
var id = iq.getAttribute('id'); self._updateItem(item);
var from = iq.getAttribute('from'); }
// Receiving client MUST ignore stanza unless it has no from or from = user's JID. );
if (from && from !== "" && from != this._connection.jid && from != Strophe.getBareJidFromJid(this._connection.jid)) }
return true; this._call_backs(this.items);
var iqresult = $iq({type: 'result', id: id, from: this._connection.jid}); },
this._connection.send(iqresult); /** PrivateFunction: _updateItem
this._updateItems(iq); * Update internal representation of roster item
return true; */
}, _updateItem : function(item)
/** PrivateFunction: _updateItems
* Update items from iq
*/
_updateItems : function(iq)
{
var query = iq.getElementsByTagName('query');
if (query.length !== 0)
{ {
this.ver = query.item(0).getAttribute('ver'); var jid = item.getAttribute("jid");
var self = this; var name = item.getAttribute("name");
Strophe.forEachChild(query.item(0), 'item', var subscription = item.getAttribute("subscription");
function (item) var ask = item.getAttribute("ask");
var groups = [];
Strophe.forEachChild(item, 'group',
function(group)
{ {
self._updateItem(item); groups.push(Strophe.getText(group));
} }
); );
}
this._call_backs(this.items); if (subscription == "remove")
},
/** PrivateFunction: _updateItem
* Update internal representation of roster item
*/
_updateItem : function(item)
{
var jid = item.getAttribute("jid");
var name = item.getAttribute("name");
var subscription = item.getAttribute("subscription");
var ask = item.getAttribute("ask");
var groups = [];
Strophe.forEachChild(item, 'group',
function(group)
{ {
groups.push(Strophe.getText(group)); this.removeItem(jid);
return;
} }
);
if (subscription == "remove")
{
this.removeItem(jid);
return;
}
item = this.findItem(jid); item = this.findItem(jid);
if (!item) if (!item)
{ {
this.items.push({ this.items.push({
name : name, name : name,
jid : jid, jid : jid,
subscription : subscription, subscription : subscription,
ask : ask, ask : ask,
groups : groups, groups : groups,
resources : {} resources : {}
}); });
} }
else else
{ {
item.name = name; item.name = name;
item.subscription = subscription; item.subscription = subscription;
item.ask = ask; item.ask = ask;
item.groups = groups; item.groups = groups;
}
} }
} });
});
})); }));
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment