# HG changeset patch # User Sonny Piers # Date 1326595648 -3600 # Node ID 9fbd0e3678b54219331184a05df8f10804817c8c # Parent efe98c3634e4c2376aee78ee919e0f4a461ddb25 add comments, jsdoc syntax + move the parser and the serializer to the Lightstring namespace so they don't get recreated at every new Lightstring.Connection diff --git a/lightstring.js b/lightstring.js --- a/lightstring.js +++ b/lightstring.js @@ -16,27 +16,66 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/** + * @namespace No code from lightstring should be callable outside this namespace/scope. + */ var Lightstring = { + /** + * @namespace Holds XMPP namespaces. + * + */ NS: {}, + /** + * @namespace Holds XMPP stanza builders. + * + */ stanza: {}, + /** + * @private + */ + parser: new DOMParser(), + /** + * @private + */ + serializer: new XMLSerializer(), + /** + * @function Transforms a XML string to a DOM object. + * @param {String} aString XML string + * @returns {Object} Domified XML. + */ + xml2dom: function(aString) { + return this.parser.parseFromString(aString, 'text/xml').documentElement; + }, + /** + * @function Transforms a DOM object to a XML string. + * @param {Object} aString DOM object + * @returns {String} Stringified DOM. + */ + dom2xml: function(aElement) { + return this.serializer.serializeToString(aElement); + }, }; +/** + * @constructor Creates a new Lightstring connection + * @param {String} [aService] The Websocket service URL. + * @memberOf Lightstring + */ Lightstring.Connection = function (aService) { - var parser = new DOMParser(); - var serializer = new XMLSerializer(); - this.service = aService; + if(aService) + this.service = aService; this.handlers = {}; this.iqid = 1024; this.getNewId = function() { this.iqid++; return 'sendiq:'+this.iqid; }; - this.parse = function(str) { - return parser.parseFromString(str, 'text/xml').documentElement; - }; - this.serialize = function(elm) { - return serializer.serializeToString(elm); - }; + /** + * @function Create and open a websocket then go though the XMPP authentification process. + * @param {String} [aJid] The JID (Jabber id) to use. + * @param {String} [aPassword] The associated password. + */ this.connect = function(aJid, aPassword) { this.emit('connecting'); if(aJid) @@ -68,17 +107,13 @@ Lightstring.Connection = function (aServ this.socket.addEventListener('open', function() { if(this.protocol !== 'xmpp') throw "Lightstring: The server located at "+that.service+" is not XMPP aware."; + //FIXME no ending "/" - node-xmpp-bosh bug var stream = ""; - //FIXME should be this but doesn't works with node-xmpp-bosh - //~ var stream = - //~ ""; + that.socket.send(stream) that.emit('XMLOutput', stream); }); @@ -90,7 +125,7 @@ Lightstring.Connection = function (aServ }); this.socket.addEventListener('message', function(e) { that.emit('XMLInput', e.data); - var elm = that.parse(e.data); + var elm = Lightstring.xml2dom(e.data); that.emit('DOMInput', elm); that.emit(elm.tagName, elm); @@ -98,14 +133,19 @@ Lightstring.Connection = function (aServ that.emit(elm.getAttribute('id'), elm); }); }; + /** + * @function Send a message. + * @param {String|Object} aStanza The message to send. + * @param {Function} [aCallback] A callback that will be called when the answer will answer. + */ this.send = function(aStanza, aCallback) { if(typeof aStanza === 'string') { var str = aStanza; - var elm = this.parse(str); + var elm = Lightstring.xml2dom(str); } else if(aStanza instanceof Element) { var elm = aStanza; - var str = this.serialize(elm); + var str = this.dom2xml(elm); } else { that.emit('error', 'Unsupported data type.'); @@ -116,7 +156,7 @@ Lightstring.Connection = function (aServ var id = elm.getAttribute('id'); if(!id) { elm.setAttribute('id', this.getNewId()) - str = this.serialize(elm) + str = Lightstring.dom2xml(elm) } if(aCallback) this.on(elm.getAttribute('id'), aCallback); @@ -130,35 +170,47 @@ Lightstring.Connection = function (aServ this.emit('XMLOutput', str); this.emit('DOMOutput', elm); }; + /** + * @function Close the XMPP stream and the socket. + */ this.disconnect = function() { this.emit('disconnecting'); this.send(''); this.socket.close(); }; - this.emit = function(name, data) { - var handlers = this.handlers[name]; + /** + * @function Emit an event. + * @param {String} aName The event name. + * @param {Function|Array|Object} [aData] Data about the event. + */ + this.emit = function(aName, aData) { + var handlers = this.handlers[aName]; if(!handlers) return; //FIXME Better idea than passing the context as argument? for(var i=0; i" ); }); - //Internal this.on('failure', function(stanza, that) { that.emit('conn-error', stanza.firstChild.tagName); }); - //Internal this.on('challenge', function(stanza, that) { //FIXME this is mostly Strophe code