jiti-meet/debian/missing-source/libs/strophe/strophe.caps.jsonly.js

241 lines
6.2 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Entity Capabilities (XEP-0115)
*
* Depends on disco plugin.
*
* See: http://xmpp.org/extensions/xep-0115.html
*
* Authors:
* - Michael Weibel <michael.weibel@gmail.com>
*
* Copyright:
* - Michael Weibel <michael.weibel@gmail.com>
*/
Strophe.addConnectionPlugin('caps', {
/** Constant: HASH
* Hash used
*
* Currently only sha-1 is supported.
*/
HASH: 'sha-1',
/** Variable: node
* Client which is being used.
*
* Can be overwritten as soon as Strophe has been initialized.
*/
node: 'http://strophe.im/strophejs/',
/** PrivateVariable: _ver
* Own generated version string
*/
_ver: '',
/** PrivateVariable: _connection
* Strophe connection
*/
_connection: null,
/** PrivateVariable: _knownCapabilities
* A hashtable containing version-strings and their capabilities, serialized
* as string.
*
* TODO: Maybe those caps shouldn't be serialized.
*/
_knownCapabilities: {},
/** PrivateVariable: _jidVerIndex
* A hashtable containing jids and their versions for better lookup of capabilities.
*/
_jidVerIndex: {},
/** Function: init
* Initialize plugin:
* - Add caps namespace
* - Add caps feature to disco plugin
* - Add handler for caps stanzas
*
* Parameters:
* (Strophe.Connection) conn - Strophe connection
*/
init: function(conn) {
this._connection = conn;
Strophe.addNamespace('CAPS', 'http://jabber.org/protocol/caps');
if (!this._connection.disco) {
throw "Caps plugin requires the disco plugin to be installed.";
}
this._connection.disco.addFeature(Strophe.NS.CAPS);
this._connection.addHandler(this._delegateCapabilities.bind(this), Strophe.NS.CAPS);
},
/** Function: generateCapsAttrs
* Returns the attributes for generating the "c"-stanza containing the own version
*
* Returns:
* (Object) - attributes
*/
generateCapsAttrs: function() {
return {
'xmlns': Strophe.NS.CAPS,
'hash': this.HASH,
'node': this.node,
'ver': this.generateVer()
};
},
/** Function: generateVer
* Returns the base64 encoded version string (encoded itself with sha1)
*
* Returns:
* (String) - version
*/
generateVer: function() {
if (this._ver !== "") {
return this._ver;
}
var ver = "",
identities = this._connection.disco._identities.sort(this._sortIdentities),
identitiesLen = identities.length,
features = this._connection.disco._features.sort(),
featuresLen = features.length;
for(var i = 0; i < identitiesLen; i++) {
var curIdent = identities[i];
ver += curIdent.category + "/" + curIdent.type + "/" + curIdent.lang + "/" + curIdent.name + "<";
}
for(var i = 0; i < featuresLen; i++) {
ver += features[i] + '<';
}
this._ver = b64_sha1(ver);
return this._ver;
},
/** Function: getCapabilitiesByJid
* Returns serialized capabilities of a jid (if available).
* Otherwise null.
*
* Parameters:
* (String) jid - Jabber id
*
* Returns:
* (String|null) - capabilities, serialized; or null when not available.
*/
getCapabilitiesByJid: function(jid) {
if (this._jidVerIndex[jid]) {
return this._knownCapabilities[this._jidVerIndex[jid]];
}
return null;
},
/** PrivateFunction: _delegateCapabilities
* Checks if the version has already been saved.
* If yes: do nothing.
* If no: Request capabilities
*
* Parameters:
* (Strophe.Builder) stanza - Stanza
*
* Returns:
* (Boolean)
*/
_delegateCapabilities: function(stanza) {
var from = stanza.getAttribute('from'),
c = stanza.querySelector('c'),
ver = c.getAttribute('ver'),
node = c.getAttribute('node');
if (!this._knownCapabilities[ver]) {
return this._requestCapabilities(from, node, ver);
} else {
this._jidVerIndex[from] = ver;
}
if (!this._jidVerIndex[from] || !this._jidVerIndex[from] !== ver) {
this._jidVerIndex[from] = ver;
}
return true;
},
/** PrivateFunction: _requestCapabilities
* Requests capabilities from the one which sent the caps-info stanza.
* This is done using disco info.
*
* Additionally, it registers a handler for handling the reply.
*
* Parameters:
* (String) to - Destination jid
* (String) node - Node attribute of the caps-stanza
* (String) ver - Version of the caps-stanza
*
* Returns:
* (Boolean) - true
*/
_requestCapabilities: function(to, node, ver) {
if (to !== this._connection.jid) {
var id = this._connection.disco.info(to, node + '#' + ver);
this._connection.addHandler(this._handleDiscoInfoReply.bind(this), Strophe.NS.DISCO_INFO, 'iq', 'result', id, to);
}
return true;
},
/** PrivateFunction: _handleDiscoInfoReply
* Parses the disco info reply and adds the version & it's capabilities to the _knownCapabilities variable.
* Additionally, it adds the jid & the version to the _jidVerIndex variable for a better lookup.
*
* Parameters:
* (Strophe.Builder) stanza - Disco info stanza
*
* Returns:
* (Boolean) - false, to automatically remove the handler.
*/
_handleDiscoInfoReply: function(stanza) {
var query = stanza.querySelector('query'),
node = query.getAttribute('node').split('#'),
ver = node[1],
from = stanza.getAttribute('from');
if (!this._knownCapabilities[ver]) {
var childNodes = query.childNodes,
childNodesLen = childNodes.length;
this._knownCapabilities[ver] = [];
for(var i = 0; i < childNodesLen; i++) {
var node = childNodes[i];
this._knownCapabilities[ver].push({name: node.nodeName, attributes: node.attributes});
}
this._jidVerIndex[from] = ver;
} else if (!this._jidVerIndex[from] || !this._jidVerIndex[from] !== ver) {
this._jidVerIndex[from] = ver;
}
return false;
},
/** PrivateFunction: _sortIdentities
* Sorts two identities according the sorting requirements in XEP-0115.
*
* Parameters:
* (Object) a - Identity a
* (Object) b - Identity b
*
* Returns:
* (Integer) - 1, 0 or -1; according to which one's greater.
*/
_sortIdentities: function(a, b) {
if (a.category > b.category) {
return 1;
}
if (a.category < b.category) {
return -1;
}
if (a.type > b.type) {
return 1;
}
if (a.type < b.type) {
return -1;
}
if (a.lang > b.lang) {
return 1;
}
if (a.lang < b.lang) {
return -1;
}
return 0;
}
});