--- /dev/null
+/*
+
+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());
+}