350 lines
6.8 KiB
JavaScript
350 lines
6.8 KiB
JavaScript
|
/*
|
||
|
|
||
|
Jappix - An open social platform
|
||
|
These are the CAPS JS script for Jappix
|
||
|
|
||
|
-------------------------------------------------
|
||
|
|
||
|
License: AGPL
|
||
|
Author: Vanaryon
|
||
|
Last revision: 26/08/11
|
||
|
|
||
|
*/
|
||
|
|
||
|
// Returns an array of the Jappix disco#infos
|
||
|
function myDiscoInfos() {
|
||
|
var fArray = new Array(
|
||
|
NS_MUC,
|
||
|
NS_MUC_USER,
|
||
|
NS_MUC_ADMIN,
|
||
|
NS_MUC_OWNER,
|
||
|
NS_MUC_CONFIG,
|
||
|
NS_DISCO_INFO,
|
||
|
NS_DISCO_ITEMS,
|
||
|
NS_PUBSUB_RI,
|
||
|
NS_BOSH,
|
||
|
NS_CAPS,
|
||
|
NS_MOOD,
|
||
|
NS_ACTIVITY,
|
||
|
NS_TUNE,
|
||
|
NS_GEOLOC,
|
||
|
NS_NICK,
|
||
|
NS_URN_ADATA,
|
||
|
NS_URN_AMETA,
|
||
|
NS_URN_MBLOG,
|
||
|
NS_URN_INBOX,
|
||
|
NS_MOOD + NS_NOTIFY,
|
||
|
NS_ACTIVITY + NS_NOTIFY,
|
||
|
NS_TUNE + NS_NOTIFY,
|
||
|
NS_GEOLOC + NS_NOTIFY,
|
||
|
NS_URN_MBLOG + NS_NOTIFY,
|
||
|
NS_URN_INBOX + NS_NOTIFY,
|
||
|
NS_URN_DELAY,
|
||
|
NS_ROSTER,
|
||
|
NS_ROSTERX,
|
||
|
NS_HTTP_AUTH,
|
||
|
NS_CHATSTATES,
|
||
|
NS_XHTML_IM,
|
||
|
NS_IPV6,
|
||
|
NS_LAST,
|
||
|
NS_PRIVATE,
|
||
|
NS_REGISTER,
|
||
|
NS_SEARCH,
|
||
|
NS_COMMANDS,
|
||
|
NS_VERSION,
|
||
|
NS_XDATA,
|
||
|
NS_VCARD,
|
||
|
NS_URN_TIME,
|
||
|
NS_URN_PING,
|
||
|
NS_URN_ARCHIVE,
|
||
|
NS_URN_AR_PREF,
|
||
|
NS_URN_RECEIPTS,
|
||
|
NS_PRIVACY,
|
||
|
NS_IQOOB,
|
||
|
NS_XOOB
|
||
|
);
|
||
|
|
||
|
return fArray;
|
||
|
}
|
||
|
|
||
|
// Gets the disco#infos of an entity
|
||
|
function getDiscoInfos(to, caps) {
|
||
|
// No CAPS
|
||
|
if(!caps) {
|
||
|
logThis('No CAPS: ' + to, 2);
|
||
|
|
||
|
displayDiscoInfos(to, '');
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Get the stored disco infos
|
||
|
var xml = XMLFromString(getPersistent('caps', caps));
|
||
|
|
||
|
// Yet stored
|
||
|
if(xml) {
|
||
|
logThis('CAPS from cache: ' + to, 3);
|
||
|
|
||
|
displayDiscoInfos(to, xml);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
logThis('CAPS from the network: ' + to, 3);
|
||
|
|
||
|
// Not stored: get the disco#infos
|
||
|
var iq = new JSJaCIQ();
|
||
|
|
||
|
iq.setTo(to);
|
||
|
iq.setType('get');
|
||
|
iq.setQuery(NS_DISCO_INFO);
|
||
|
|
||
|
con.send(iq, handleDiscoInfos);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// Handles the disco#infos of an entity
|
||
|
function handleDiscoInfos(iq) {
|
||
|
if(!iq || (iq.getType() == 'error'))
|
||
|
return;
|
||
|
|
||
|
// IQ received, get some values
|
||
|
var from = fullXID(getStanzaFrom(iq));
|
||
|
var query = iq.getQuery();
|
||
|
|
||
|
// Generate the CAPS-processing values
|
||
|
var identities = new Array();
|
||
|
var features = new Array();
|
||
|
var data_forms = new Array();
|
||
|
|
||
|
// Identity values
|
||
|
$(query).find('identity').each(function() {
|
||
|
var pCategory = $(this).attr('category');
|
||
|
var pType = $(this).attr('type');
|
||
|
var pLang = $(this).attr('xml:lang');
|
||
|
var pName = $(this).attr('name');
|
||
|
|
||
|
if(!pCategory)
|
||
|
pCategory = '';
|
||
|
if(!pType)
|
||
|
pType = '';
|
||
|
if(!pLang)
|
||
|
pLang = '';
|
||
|
if(!pName)
|
||
|
pName = '';
|
||
|
|
||
|
identities.push(pCategory + '/' + pType + '/' + pLang + '/' + pName);
|
||
|
});
|
||
|
|
||
|
// Feature values
|
||
|
$(query).find('feature').each(function() {
|
||
|
var pVar = $(this).attr('var');
|
||
|
|
||
|
// Add the current value to the array
|
||
|
if(pVar)
|
||
|
features.push(pVar);
|
||
|
});
|
||
|
|
||
|
// Data-form values
|
||
|
$(query).find('x[xmlns=' + NS_XDATA + ']').each(function() {
|
||
|
// Initialize some stuffs
|
||
|
var pString = '';
|
||
|
var sortVar = new Array();
|
||
|
|
||
|
// Add the form type field
|
||
|
$(this).find('field[var=FORM_TYPE] value').each(function() {
|
||
|
var cText = $(this).text();
|
||
|
|
||
|
if(cText)
|
||
|
pString += cText + '<';
|
||
|
});
|
||
|
|
||
|
// Add the var attributes into an array
|
||
|
$(this).find('field:not([var=FORM_TYPE])').each(function() {
|
||
|
var cVar = $(this).attr('var');
|
||
|
|
||
|
if(cVar)
|
||
|
sortVar.push(cVar);
|
||
|
});
|
||
|
|
||
|
// Sort the var attributes
|
||
|
sortVar = sortVar.sort();
|
||
|
|
||
|
// Loop this sorted var attributes
|
||
|
for(i in sortVar) {
|
||
|
// Initialize the value sorting
|
||
|
var sortVal = new Array();
|
||
|
|
||
|
// Append it to the string
|
||
|
pString += sortVar[i] + '<';
|
||
|
|
||
|
// Add each value to the array
|
||
|
$(this).find('field[var=' + sortVar[i] + '] value').each(function() {
|
||
|
sortVal.push($(this).text());
|
||
|
});
|
||
|
|
||
|
// Sort the values
|
||
|
sortVal = sortVal.sort();
|
||
|
|
||
|
// Append the values to the string
|
||
|
for(j in sortVal)
|
||
|
pString += sortVal[j] + '<';
|
||
|
}
|
||
|
|
||
|
// Any string?
|
||
|
if(pString) {
|
||
|
// Remove the undesired double '<' from the string
|
||
|
if(pString.match(/(.+)(<)+$/))
|
||
|
pString = pString.substring(0, pString.length - 1);
|
||
|
|
||
|
// Add the current string to the array
|
||
|
data_forms.push(pString);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Process the CAPS
|
||
|
var caps = processCaps(identities, features, data_forms);
|
||
|
|
||
|
// Get the XML string
|
||
|
var xml = xmlToString(query);
|
||
|
|
||
|
// Store the disco infos
|
||
|
setPersistent('caps', caps, xml);
|
||
|
|
||
|
// This is our server
|
||
|
if(from == getServer()) {
|
||
|
// Handle the features
|
||
|
handleFeatures(xml);
|
||
|
|
||
|
logThis('Got our server CAPS', 3);
|
||
|
}
|
||
|
|
||
|
else {
|
||
|
// Display the disco infos
|
||
|
displayDiscoInfos(from, xml);
|
||
|
|
||
|
logThis('Got CAPS: ' + from, 3);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Displays the disco#infos everywhere needed for an entity
|
||
|
function displayDiscoInfos(from, xml) {
|
||
|
// Generate the chat path
|
||
|
var xid = bareXID(from);
|
||
|
|
||
|
// This comes from a private groupchat chat?
|
||
|
if(isPrivate(xid))
|
||
|
xid = from;
|
||
|
|
||
|
hash = hex_md5(xid);
|
||
|
|
||
|
// Support indicators
|
||
|
var xhtml_im = false;
|
||
|
var iq_oob = false;
|
||
|
var x_oob = false;
|
||
|
var receipts = false;
|
||
|
|
||
|
// Display the supported features
|
||
|
$(xml).find('feature').each(function() {
|
||
|
var current = $(this).attr('var');
|
||
|
|
||
|
// xHTML-IM
|
||
|
if(current == NS_XHTML_IM)
|
||
|
xhtml_im = true;
|
||
|
|
||
|
// Out of Band Data (IQ)
|
||
|
if(current == NS_IQOOB)
|
||
|
iq_oob = true;
|
||
|
|
||
|
// Out of Band Data (X)
|
||
|
if(current == NS_XOOB)
|
||
|
x_oob = true;
|
||
|
|
||
|
// Receipts
|
||
|
else if(current == NS_URN_RECEIPTS)
|
||
|
receipts = true;
|
||
|
});
|
||
|
|
||
|
// Paths
|
||
|
var path = $('#' + hash);
|
||
|
var message_area = path.find('.message-area');
|
||
|
var style = path.find('.chat-tools-style');
|
||
|
var file = path.find('.chat-tools-file');
|
||
|
|
||
|
// Apply xHTML-IM
|
||
|
if(xhtml_im)
|
||
|
style.show();
|
||
|
else {
|
||
|
// Remove the tooltip elements
|
||
|
style.hide();
|
||
|
style.find('.bubble-style').remove();
|
||
|
|
||
|
// Reset the markers
|
||
|
message_area.removeAttr('style')
|
||
|
.removeAttr('data-color')
|
||
|
.removeAttr('data-bold')
|
||
|
.removeAttr('data-italic')
|
||
|
.removeAttr('data-underline');
|
||
|
}
|
||
|
|
||
|
// Apply Out of Band Data
|
||
|
if(iq_oob || x_oob) {
|
||
|
file.show();
|
||
|
|
||
|
// Set a marker
|
||
|
if(iq_oob)
|
||
|
file.attr('data-oob', 'iq');
|
||
|
else
|
||
|
file.attr('data-oob', 'x');
|
||
|
}
|
||
|
|
||
|
else {
|
||
|
// Remove the tooltip elements
|
||
|
file.hide();
|
||
|
file.find('.bubble-style').remove();
|
||
|
|
||
|
// Reset the marker
|
||
|
file.removeAttr('data-oob');
|
||
|
}
|
||
|
|
||
|
// Apply receipts
|
||
|
if(receipts)
|
||
|
message_area.attr('data-receipts', 'true');
|
||
|
else
|
||
|
message_area.removeAttr('data-receipts');
|
||
|
}
|
||
|
|
||
|
// Generates the CAPS hash
|
||
|
function processCaps(cIdentities, cFeatures, cDataForms) {
|
||
|
// Initialize
|
||
|
var cString = '';
|
||
|
|
||
|
// Sort the arrays
|
||
|
cIdentities = cIdentities.sort();
|
||
|
cFeatures = cFeatures.sort();
|
||
|
cDataForms = cDataForms.sort();
|
||
|
|
||
|
// Process the sorted identity string
|
||
|
for(a in cIdentities)
|
||
|
cString += cIdentities[a] + '<';
|
||
|
|
||
|
// Process the sorted feature string
|
||
|
for(b in cFeatures)
|
||
|
cString += cFeatures[b] + '<';
|
||
|
|
||
|
// Process the sorted data-form string
|
||
|
for(c in cDataForms)
|
||
|
cString += cDataForms[c] + '<';
|
||
|
|
||
|
// Process the SHA-1 hash
|
||
|
var cHash = b64_sha1(cString);
|
||
|
|
||
|
return cHash;
|
||
|
}
|
||
|
|
||
|
// Generates the Jappix CAPS hash
|
||
|
function myCaps() {
|
||
|
return processCaps(new Array('client/web//Jappix'), myDiscoInfos(), new Array());
|
||
|
}
|