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