Mercurial > eldonilo > lightstring
diff lightstring.js @ 2:f31a75c3b6c8
code cleaning
author | Sonny Piers <sonny.piers@gmail.com> |
---|---|
date | Sun, 18 Dec 2011 22:57:47 +0100 |
parents | 96087680669f |
children | 029c12b8f048 |
line wrap: on
line diff
--- a/lightstring.js +++ b/lightstring.js @@ -1,13 +1,30 @@ 'use strict'; +/** + Copyright (c) 2011, Sonny Piers <sonny at fastmail dot net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + var Lightstring = { NS: {}, stanza: {}, }; -Lightstring.Connection = function (aURL) { +Lightstring.Connection = function (aService) { var parser = new DOMParser(); var serializer = new XMLSerializer(); + this.service = aService; this.handlers = {}; this.iqid = 1024; this.getNewId = function() { @@ -20,27 +37,48 @@ Lightstring.Connection = function (aURL) this.serialize = function(elm) { return serializer.serializeToString(elm); }; - this.connect = function(jid, password) { - this.domain = jid.split('@')[1]; - this.node = jid.split('@')[0]; - this.jid = jid; - this.password = password; - if(typeof WebSocket === 'undefined') - this.socket = new MozWebSocket(aURL); + this.connect = function(aJid, aPassword) { + if(aJid) + this.jid = aJid; + if(this.jid) { + this.domain = this.jid.split('@')[1]; + this.node = this.jid.split('@')[0]; + this.resource = this.jid.split('/')[1]; + } + if(aPassword) + this.password = aPassword; + + if(!this.jid) + throw "Lightstring: Connection.jid is undefined."; + if(!this.password) + throw "Lightstring: Connection.password is undefined."; + if(!this.service) + throw "Lightstring: Connection.service is undefined."; + + //"Bug 695635 - tracking bug: unprefix WebSockets" https://bugzil.la/695635 + if(MozWebSocket) + this.socket = new MozWebSocket(this.service); + else if(WebSocket) + this.socket = new WebSocket(this.service); else - this.socket = new WebSocket(aURL); + this.emit('error', 'No WebSocket support.'); var that = this; this.socket.addEventListener('open', function() { - that.emit('open'); - that.send("<stream:stream to='"+that.domain+"' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' />"); + that.emit('connecting'); + //FIXME there shouldn't be an ending "/" + that.send( + "<stream:stream to='"+that.domain+"'\ + xmlns='jabber:client'\ + xmlns:stream='http://etherx.jabber.org/streams'\ + version='1.0'/>" + ); }); - this.socket.addEventListener('error', function(err) { - that.emit('error'); + this.socket.addEventListener('error', function(e) { + that.emit('error', e.data); }); - this.socket.addEventListener('close', function(close) { - that.emit('close'); - that.emit('disconnected'); + this.socket.addEventListener('close', function(e) { + that.emit('disconnected', e.data); }); this.socket.addEventListener('message', function(e) { that.emit('XMLInput', e.data); @@ -48,29 +86,21 @@ Lightstring.Connection = function (aURL) that.emit('DOMInput', elm); that.emit(elm.tagName, elm); - if((elm.tagName === 'iq')) + if(elm.tagName === 'iq') that.emit(elm.getAttribute('id'), elm); }); }; - - - - this.send = function(stanza, callback) { - //FIXME support for E4X - //~ if(typeof stanza === 'xml') { - //~ stanza = stanza.toXMLString(); - //~ } - if(stanza.cnode) { - stanza = stanza.toString(); - //~ console.log(typeof stanza); - } - if(typeof stanza === 'string') { - var str = stanza; - var elm = this.parse(stanza); + this.send = function(aStanza, aCallback) { + if(typeof aStanza === 'string') { + var str = aStanza; + var elm = this.parse(str); + } + else if(aStanza instanceof Element) { + var elm = aStanza; + var str = this.serialize(elm); } else { - var elm = stanza; - var str = this.serialize(stanza); + that.emit('error', 'Unsupported data type.'); } @@ -80,7 +110,11 @@ Lightstring.Connection = function (aURL) elm.setAttribute('id', this.getNewId()) str = this.serialize(elm) } - if(callback) this.on(elm.getAttribute('id'), callback); + if(aCallback) + this.on(elm.getAttribute('id'), aCallback); + } + else if(aCallback) { + that.emit('warning', 'Callback can\'t be called with non-iq stanza.'); } @@ -89,11 +123,11 @@ Lightstring.Connection = function (aURL) this.emit('DOMOutput', elm); }; this.disconnect = function() { + this.emit('disconnecting'); this.send('</stream:stream>'); - this.emit('disconnected'); this.socket.close(); + this.emit('disconnected'); }; - //FIXME Callbacks sucks, better idea? this.emit = function(name, data) { var handlers = this.handlers[name]; if(!handlers) @@ -130,27 +164,53 @@ Lightstring.Connection = function (aURL) //FIXME support SCRAM-SHA1 && allow specify method preferences if('DIGEST-MD5' in mechanisms) - that.send("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='DIGEST-MD5'/>"); + that.send( + "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'\ + mechanism='DIGEST-MD5'/>" + ); else if('PLAIN' in mechanisms) { - var token = btoa(that.jid + "\u0000" + that.jid.split('@')[0] + "\u0000" + that.password); - that.send("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>"+token+"</auth>"); + var token = btoa( + that.jid + + "\u0000" + + that.jid.node + + "\u0000" + + that.password + ); + that.send( + "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'\ + mechanism='PLAIN'>"+token+"</auth>" + ); } } //XMPP features else { that.emit('features', stanza); //Bind http://xmpp.org/rfcs/rfc3920.html#bind - that.send("<iq type='set' xmlns='jabber:client'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/></iq>", function() { + that.send( + "<iq type='set' xmlns='jabber:client'>\ + <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>\ + </iq>", + function() { //Session http://xmpp.org/rfcs/rfc3921.html#session - that.send("<iq type='set' xmlns='jabber:client'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>", function() { - that.emit('connected'); - }); + that.send( + "<iq type='set' xmlns='jabber:client'>\ + <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>\ + </iq>", + function() { + that.emit('connected'); + } + ); }); } }); //Internal this.on('success', function(stanza, that) { - that.send("<stream:stream to='"+that.domain+"' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' />"); + that.send( + "<stream:stream to='"+that.domain+"'\ + xmlns='jabber:client'\ + xmlns:stream='http://etherx.jabber.org/streams'\ + version='1.0' />" + ); }); //Internal this.on('challenge', function(stanza, that) { @@ -195,7 +255,6 @@ Lightstring.Connection = function (aURL) if (host !== null) { digest_uri = digest_uri + "/" + host; } - var A1 = MD5.hash(that.node + ":" + realm + ":" + that.password) + ":" + nonce + ":" + cnonce; @@ -215,7 +274,9 @@ Lightstring.Connection = function (aURL) cnonce + ":auth:" + MD5.hexdigest(A2))) + ','; responseText += 'charset="utf-8"'; - - that.send("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>"+btoa(responseText)+"</response>"); + that.send( + "<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>" + +btoa(responseText)+ + "</response>"); }); };