/* Jappix - An open social platform These are the Jappix Mobile lightweight JS script ------------------------------------------------- License: AGPL Author: Vanaryon Last revision: 10/07/11 */ /* BEGIN CONNECTION FUNCTIONS */ function doLogin(aForm) { try { // Reset the panels resetPanel(); // Get the values var xid = aForm.xid.value; var username, domain; // A domain is specified if(xid.indexOf('@') != -1) { username = getXIDNick(xid); domain = getXIDHost(xid); // Domain is locked and not the same if((LOCK_HOST == 'on') && (domain != HOST_MAIN)) { showThis('error'); return false; } } // No "@" in the XID, we should add the default domain else { username = xid; domain = HOST_MAIN; } var pwd = aForm.pwd.value; var reg = false; if(aForm.reg) reg = aForm.reg.checked; // Enough parameters if(username && domain && pwd) { // Show the info notification showThis('info'); // We define the http binding parameters oArgs = new Object(); if(HOST_BOSH_MAIN) oArgs.httpbase = HOST_BOSH_MAIN; else oArgs.httpbase = HOST_BOSH; // We create the new http-binding connection con = new JSJaCHttpBindingConnection(oArgs); // And we handle everything that happen con.registerHandler('message', handleMessage); con.registerHandler('presence', handlePresence); con.registerHandler('iq', handleIQ); con.registerHandler('onconnect', handleConnected); con.registerHandler('onerror', handleError); con.registerHandler('ondisconnect', handleDisconnected); // We retrieve what the user typed in the login inputs oArgs = new Object(); oArgs.username = username; oArgs.domain = domain; oArgs.resource = JAPPIX_RESOURCE + ' Mobile (' + (new Date()).getTime() + ')'; oArgs.pass = pwd; oArgs.secure = true; oArgs.xmllang = XML_LANG; // Register? if(reg) oArgs.register = true; // We connect ! con.connect(oArgs); } // Not enough parameters else showThis('error'); } catch(e) { // An error happened resetPanel('error'); } finally { return false; } } function doLogout() { con.disconnect(); } /* END CONNECTION FUNCTIONS */ /* BEGIN SHOW/HIDE FUNCTIONS */ function showThis(id) { document.getElementById(id).style.display = 'block'; } function hideThis(id) { document.getElementById(id).style.display = 'none'; } function resetPanel(id) { // Hide the opened panels hideThis('info'); hideThis('error'); //Show the target panel if(id) showThis(id); } function resetDOM() { // Reset the "secret" input values document.getElementById('pwd').value = ''; // Remove the useless DOM elements var body = document.getElementsByTagName('body')[0]; body.removeChild(document.getElementById('talk')); body.removeChild(document.getElementById('chat')); } /* END SHOW/HIDE FUNCTIONS */ /* BEGIN SYSTEM FUNCTIONS */ function exists(id) { if(!document.getElementById(id)) return false; else return true; } function _e(string) { return string; } function encodeOnclick(str) { return str.replace(/'/g, '\\$&').replace(/"/g, '"'); } function getJappixLocation() { var url = window.location.href; // If the URL has variables, remove them if(url.indexOf('?') != -1) url = url.split('?')[0]; if(url.indexOf('#') != -1) url = url.split('#')[0]; // No "/" at the end if(!url.match(/(.+)\/$/)) url += '/'; return url; } /* END SYSTEM FUNCTIONS */ /* BEGIN HANDLING FUNCTIONS */ function handleMessage(msg) { var type = msg.getType(); if(type == 'chat' || type == 'normal') { // Get the body var body = msg.getBody(); if(body) { // Get the values var xid = cutResource(msg.getFrom()); var hash = hex_md5(xid); var nick = getNick(xid, hash); // No nickname? if(!nick) nick = xid; // Create the chat if it does not exist chat(xid, nick); // Display the message displayMessage(xid, body, nick, hash); } } } function handlePresence(pre) { // Define the variables var xid = cutResource(pre.getFrom()); var hash = hex_md5(xid); var type = pre.getType(); var show = pre.getShow(); // Online buddy: show it! if(!type) { showThis('buddy-' + hash); // Display the correct presence switch(show) { case 'chat': displayPresence(hash, show); break; case 'away': displayPresence(hash, show); break; case 'xa': displayPresence(hash, show); break; case 'dnd': displayPresence(hash, show); break; default: displayPresence(hash, 'available'); break; } } else hideThis('buddy-' + hash); } function handleIQ(iq) { // Get the content var iqFrom = iq.getFrom(); var iqID = iq.getID(); var iqQueryXMLNS = iq.getQueryXMLNS(); var iqType = iq.getType(); // Create the response if((iqType == 'get') && ((iqQueryXMLNS == NS_DISCO_INFO) || (iqQueryXMLNS == NS_VERSION))) { var iqResponse = new JSJaCIQ(); iqResponse.setID(iqID); iqResponse.setTo(iqFrom); iqResponse.setType('result'); } // Disco#infos query if((iqQueryXMLNS == NS_DISCO_INFO) && (iqType == 'get')) { /* REF: http://xmpp.org/extensions/xep-0030.html */ var iqQuery = iqResponse.setQuery(NS_DISCO_INFO); // We set the name of the client iqQuery.appendChild(iq.appendNode('identity', { 'category': 'client', 'type': 'mobile', 'name': 'Jappix Mobile' })); // We set all the supported features var fArray = new Array( NS_DISCO_INFO, NS_VERSION ); for(i in fArray) iqQuery.appendChild(iq.buildNode('feature', {'var': fArray[i]})); con.send(iqResponse); } // Software version query else if((iqQueryXMLNS == NS_VERSION) && (iqType == 'get')) { /* REF: http://xmpp.org/extensions/xep-0092.html */ var iqQuery = iqResponse.setQuery(NS_VERSION); iqQuery.appendChild(iq.buildNode('name', 'Jappix Mobile')); iqQuery.appendChild(iq.buildNode('version', JAPPIX_VERSION)); iqQuery.appendChild(iq.buildNode('os', BrowserDetect.OS)); con.send(iqResponse); } } function handleConnected() { // Reset the elements hideThis('home'); resetPanel(); // Create the talk page document.getElementsByTagName('body')[0].innerHTML += '<div id="talk">' + '<div class="header">' + '<div class="mobile-images"></div>' + '<button onclick="doLogout();">' + _e("Disconnect") + '</button>' + '</div>' + '<div id="roster"></div>' + '</div>' + '<div id="chat">' + '<div class="header">' + '<div class="mobile-images"></div>' + '<button onclick="returnToRoster();">' + _e("Previous") + '</button>' + '</div>' + '<div id="chans"></div>' + '</div>'; // Get the roster items getRoster(); } function handleError(error) { resetPanel('error'); } function handleDisconnected() { // Reset the elements resetDOM(); // Show the home page showThis('home'); } function handleRoster(iq) { // Error: send presence anyway if(!iq || (iq.getType() != 'result')) return sendPresence('', 'available', 1); // Define some pre-vars var current, xid, nick, oneBuddy, oneID, hash; var roster = document.getElementById('roster'); // Get roster items var iqNode = iq.getNode(); var bItems = iqNode.getElementsByTagName('item'); // Display each elements from the roster for(var i = 0; i < bItems.length; i++) { // Get the values current = iqNode.getElementsByTagName('item').item(i); xid = current.getAttribute('jid').htmlEnc(); nick = current.getAttribute('name'); hash = hex_md5(xid); // No defined nick? if(!nick) nick = getDirectNick(xid); // Display the values oneBuddy = document.createElement('a'); oneID = 'buddy-' + hash; oneBuddy.setAttribute('href', '#'); oneBuddy.setAttribute('id', oneID); oneBuddy.setAttribute('class', 'one-buddy'); oneBuddy.setAttribute('onclick', 'return chat(\'' + encodeOnclick(xid) + '\', \'' + encodeOnclick(nick) + '\');'); oneBuddy.innerHTML = nick.htmlEnc(); roster.appendChild(oneBuddy); } // Start handling buddies presence sendPresence('', 'available', 1); } /* END HANDLING FUNCTIONS */ /* BEGIN SENDING FUNCTIONS */ function sendMessage(aForm) { try { var body = aForm.body.value; var xid = aForm.xid.value; var hash = hex_md5(xid); if(body && xid) { // Send the message var aMsg = new JSJaCMessage(); aMsg.setTo(xid); aMsg.setType('chat'); aMsg.setBody(body); con.send(aMsg); // Clear our input aForm.body.value = ''; // Display the message we sent displayMessage(xid, body, 'me', hash); } } finally { return false; } } function sendPresence(type, show, priority, status) { var presence = new JSJaCPresence(); if(type) presence.setType(type); if(show) presence.setShow(show); if(priority) presence.setPriority(priority); if(status) presence.setStatus(status); con.send(presence); } /* END SENDING FUNCTIONS */ /* BEGIN GETTING FUNCTIONS */ function getRoster() { iq = new JSJaCIQ(); iq.setType('get'); iq.setQuery(NS_ROSTER); con.send(iq, handleRoster); } function getDirectNick(xid) { return explodeThis('@', xid, 0); } function getNick(xid, hash) { var path = 'buddy-' + hash; if(exists(path)) return document.getElementById(path).innerHTML; else getDirectNick(xid); } /* END GETTING FUNCTIONS */ /* BEGIN RESOURCES FUNCTIONS */ function explodeThis(toEx, toStr, i) { // Get the index of our char to explode var index = toStr.indexOf(toEx); // We split if necessary the string if(index != -1) { if(i == 0) toStr = toStr.substr(0, index); else toStr = toStr.substr(index + 1); } // We return the value return toStr; } function cutResource(aXID) { return explodeThis('/', aXID, 0); } function getXIDNick(aXID) { return explodeThis('@', aXID, 0); } function getXIDHost(aXID) { return explodeThis('@', aXID, 1); } /* END RESOURCES FUNCTIONS */ /* BEGIN CHAT FUNCTIONS */ function filter(msg) { var msg = msg // Encode in HTML .htmlEnc() // Highlighted text .replace(/(\s|^)\*(.+)\*(\s|$)/gi,'$1<em>$2</em>$3'); // Links msg = applyLinks(msg, 'mini'); return msg; } function displayMessage(xid, body, nick, hash) { // Get the path var path = 'content-' + hash; // Display the message html = '<span><b'; if(nick == 'me') html += ' class="me">' + _e("You"); else html += ' class="him">' + nick; html += '</b> ' + filter(body) + '</span>'; document.getElementById(path).innerHTML += html; // Scroll to the last element document.getElementById(path).lastChild.scrollIntoView(); } function returnToRoster() { // Hide the chats hideThis('chat'); // Show the roster showThis('talk'); } function chatSwitch(hash) { // Hide the roster page hideThis('talk'); // Hide the other chats var divs = document.getElementsByTagName('div'); for(var i = 0; i < divs.length; i++) { if(divs.item(i).getAttribute('class') == 'one-chat') divs.item(i).style.display = 'none'; } // Show the chat showThis('chat'); showThis(hash); } function createChat(xid, nick, hash) { // Define the variables var chat = document.getElementById('chans'); var oneChat = document.createElement('div'); // Apply the DOM modification oneChat.setAttribute('id', 'chat-' + hash); oneChat.setAttribute('class', 'one-chat'); oneChat.innerHTML = '<p>' + nick + '</p><div id="content-' + hash + '"></div><form action="#" method="post" onsubmit="return sendMessage(this);"><input type="text" name="body" /><input type="hidden" name="xid" value="' + xid + '" /><input type="submit" class="submit" value="OK" /></form>'; chat.appendChild(oneChat); } function chat(xid, nick) { var hash = hex_md5(xid); // If the chat was not yet opened if(!exists('chat-' + hash)) { // No nick? if(!nick) nick = getNick(xid, hash); // Create the chat createChat(xid, nick, hash); } // Switch to the chat chatSwitch('chat-' + hash); return false; } /* END CHAT FUNCTIONS */ /* BEGIN PRESENCE FUNCTIONS */ function displayPresence(hash, show) { document.getElementById('buddy-' + hash).setAttribute('class', 'one-buddy ' + show); } /* END PRESENCE FUNCTIONS */ /* BEGIN DOCUMENT EVENTS FUNCTIONS */ onbeforeunload = doLogout; /* END DOCUMENT EVENTS FUNCTIONS */