comparison lightstring.js @ 106:c06ec02217ee

many changes
author Sonny Piers <sonny@fastmail.net>
date Tue, 26 Jun 2012 12:02:14 +0200
parents f14558915187
children 5cb4733c5189
comparison
equal deleted inserted replaced
105:fb50311997b5 106:c06ec02217ee
70 /** 70 /**
71 * @function Transforms a XML string to a DOM object. 71 * @function Transforms a XML string to a DOM object.
72 * @param {String} aString XML string. 72 * @param {String} aString XML string.
73 * @return {Object} Domified XML. 73 * @return {Object} Domified XML.
74 */ 74 */
75 XML2DOM: function(aString) { 75 parse: function(aString) {
76 var DOM = null; 76 var el = null;
77 //FIXME webkit doesn't throw an error when the parsing fails
77 try { 78 try {
78 DOM = this.parser.parseFromString(aString, 'text/xml').documentElement; 79 el = this.parser.parseFromString(aString, 'text/xml').documentElement;
79 } 80 }
80 catch (e) { 81 catch (e) {
81 //TODO: error 82 //TODO: error
82 } 83 }
83 finally { 84 finally {
84 return DOM; 85 return el;
85 }; 86 };
86 }, 87 },
87 /** 88 /**
88 * @function Transforms a DOM object to a XML string. 89 * @function Transforms a DOM object to a XML string.
89 * @param {Object} aString DOM object. 90 * @param {Object} aString DOM object.
90 * @return {String} Stringified DOM. 91 * @return {String} Stringified DOM.
91 */ 92 */
92 DOM2XML: function(aElement) { 93 serialize: function(aElement) {
93 var XML = null; 94 var string = null;
94 try { 95 try {
95 XML = this.serializer.serializeToString(aElement); 96 string = this.serializer.serializeToString(aElement);
96 } 97 }
97 catch (e) { 98 catch (e) {
98 //TODO: error 99 //TODO: error
99 } 100 }
100 finally { 101 finally {
101 return XML; 102 return string;
102 }; 103 };
103 }, 104 },
104 /** 105 /**
105 * @function Get an unique identifier. 106 * @function Get an unique identifier.
106 * @param {String} [aString] Prefix to put before the identifier. 107 * @param {String} [aString] Prefix to put before the identifier.
120 * @constructor Creates a new Lightstring connection 121 * @constructor Creates a new Lightstring connection
121 * @param {String} [aService] The connection manager URL. 122 * @param {String} [aService] The connection manager URL.
122 * @memberOf Lightstring 123 * @memberOf Lightstring
123 */ 124 */
124 Lightstring.Connection = function(aService) { 125 Lightstring.Connection = function(aService) {
126 var that = this;
127 window.addEventListener('message', function(e) {
128 that.send(e.data.send)
129 });
125 if (aService) 130 if (aService)
126 this.service = aService; 131 this.service = aService;
127 /** 132 /**
128 * @namespace Holds connection events handlers 133 * @namespace Holds connection events handlers
129 */ 134 */
156 return a.protocol.replace(':', ''); 161 return a.protocol.replace(':', '');
157 } 162 }
158 var protocol = getProtocol(this.service); 163 var protocol = getProtocol(this.service);
159 164
160 if (protocol.match('http')) 165 if (protocol.match('http'))
161 this.connection = new Lightstring.BOSHConnection(this.service); 166 this.connection = new Lightstring.BOSHConnection(this.service, this.jid);
162 else if (protocol.match('ws')) 167 else if (protocol.match('ws'))
163 this.connection = new Lightstring.WebSocketConnection(this.service); 168 this.connection = new Lightstring.WebSocketConnection(this.service, this.jid);
164 169
165 this.connection.open(); 170 this.connection.open();
166 171
167 var that = this; 172 var that = this;
168 173
171 }); 176 });
172 this.connection.on('out', function(stanza) { 177 this.connection.on('out', function(stanza) {
173 that.emit('out', stanza); 178 that.emit('out', stanza);
174 }); 179 });
175 this.connection.on('in', function(stanza) { 180 this.connection.on('in', function(stanza) {
176 var stanza = new Lightstring.Stanza(stanza);
177
178 //FIXME: node-xmpp-bosh sends a self-closing stream:stream tag; it is wrong! 181 //FIXME: node-xmpp-bosh sends a self-closing stream:stream tag; it is wrong!
179 that.emit('stanza', stanza); 182 that.emit('stanza', stanza);
180 183
181 if (!stanza.DOM) 184 if (!stanza.el)
182 return; 185 return;
183 186
184 var name = stanza.DOM.localName; 187 var el = stanza.el;
185 188
186 //Authentication 189 //Authentication
187 //FIXME SASL mechanisms and XMPP features can be both in a stream:features 190 //FIXME SASL mechanisms and XMPP features can be both in a stream:features
188 if (name === 'features') { 191 if (el.localName === 'features') {
189 //SASL mechanisms 192 var children = el.childNodes;
190 if (stanza.DOM.firstChild.localName === 'mechanisms') { 193 for (var i = 0, length = children.length; i < length; i++) {
191 stanza.mechanisms = []; 194 //SASL mechanisms
192 var nodes = stanza.DOM.getElementsByTagName('mechanism'); 195 if(children[i].localName === 'mechanisms') {
193 for (var i = 0; i < nodes.length; i++) 196 stanza.mechanisms = [];
194 stanza.mechanisms.push(nodes[i].textContent); 197 var nodes = el.getElementsByTagName('mechanism');
195 that.emit('mechanisms', stanza); 198 for (var i = 0; i < nodes.length; i++)
199 stanza.mechanisms.push(nodes[i].textContent);
200 that.emit('mechanisms', stanza);
201 return;
202 }
196 } 203 }
197 //XMPP features 204 //XMPP features
198 else { 205 // else {
199 //TODO: stanza.features 206 //TODO: stanza.features
200 that.emit('features', stanza); 207 that.emit('features', stanza);
201 } 208 // }
202 } 209 }
203 else if (name === 'challenge') { 210 else if (el.localName === 'challenge') {
204 that.emit('challenge', stanza); 211 that.emit('challenge', stanza);
205 } 212 }
206 else if (name === 'failure') { 213 else if (el.localName === 'failure') {
207 that.emit('failure', stanza); 214 that.emit('failure', stanza);
208 } 215 }
209 else if (name === 'success') { 216 else if (el.localName === 'success') {
210 that.emit('success', stanza); 217 that.emit('success', stanza);
211 } 218 }
212 219
213 //Iq callbacks 220 //Iq callbacks
214 else if (name === 'iq') { 221 else if (el.localName === 'iq') {
215 var payload = stanza.DOM.firstChild; 222 var payload = el.firstChild;
216 if (payload) 223 if (payload)
217 that.emit('iq/' + payload.namespaceURI + ':' + payload.localName, stanza); 224 that.emit('iq/' + payload.namespaceURI + ':' + payload.localName, stanza);
218 225
219 var id = stanza.DOM.getAttribute('id'); 226 var id = el.getAttribute('id');
220 if (!(id && id in that.callbacks)) 227 if (!(id && id in that.callbacks))
221 return; 228 return;
222 229
223 var type = stanza.DOM.getAttribute('type'); 230 var type = el.getAttribute('type');
224 if (type !== 'result' && type !== 'error') 231 if (type !== 'result' && type !== 'error')
225 return; //TODO: warning 232 return; //TODO: warning
226 233
227 var callback = that.callbacks[id]; 234 var callback = that.callbacks[id];
228 if (type === 'result' && callback.success) 235 if (type === 'result' && callback.success)
231 callback.error.call(that, stanza); 238 callback.error.call(that, stanza);
232 239
233 delete that.callbacks[id]; 240 delete that.callbacks[id];
234 } 241 }
235 242
236 else if (name === 'presence' || name === 'message') { 243 else if (el.localName === 'presence' || el.localName === 'message') {
237 that.emit(name, stanza); 244 that.emit(name, stanza);
238 } 245 }
239 }); 246 });
240 }; 247 };
241 /** 248 /**
250 var stanza = aStanza; 257 var stanza = aStanza;
251 258
252 if (!stanza) 259 if (!stanza)
253 return; 260 return;
254 261
255 if (stanza.DOM.tagName === 'iq') { 262 if (stanza.el.tagName === 'iq') {
256 var type = stanza.DOM.getAttribute('type'); 263 var type = stanza.el.getAttribute('type');
257 if (type !== 'get' || type !== 'set') 264 if (type !== 'get' || type !== 'set')
258 ; //TODO: error 265 ; //TODO: error
259 266
260 var callback = {success: aSuccess, error: aError}; 267 var callback = {success: aSuccess, error: aError};
261 268
262 var id = stanza.DOM.getAttribute('id'); 269 var id = stanza.el.getAttribute('id');
263 if (!id) { 270 if (!id) {
264 var id = Lightstring.newId('sendiq:'); 271 var id = Lightstring.newId('sendiq:');
265 stanza.DOM.setAttribute('id', id); 272 stanza.el.setAttribute('id', id);
266 } 273 }
267 274
268 this.callbacks[id] = callback; 275 this.callbacks[id] = callback;
269 276
270 } 277 }
271 else if (aSuccess || aError) 278 else if (aSuccess || aError)
272 ; //TODO: warning (no callback without iq) 279 ; //TODO: warning (no callback without iq)
273 280
274 281 this.connection.send(stanza.toString());
275 //FIXME this.socket.send(stanza.XML); (need some work on Lightstring.Stanza)
276 var fixme = Lightstring.DOM2XML(stanza.DOM);
277 stanza.XML = fixme;
278 this.connection.send(fixme);
279 this.emit('output', stanza);
280 }; 282 };
281 /** 283 /**
282 * @function Closes the XMPP stream and the socket. 284 * @function Closes the XMPP stream and the socket.
283 */ 285 */
284 Lightstring.Connection.prototype.disconnect = function() { 286 Lightstring.Connection.prototype.disconnect = function() {
285 this.emit('disconnecting'); 287 this.emit('disconnecting');
286 var stream = Lightstring.stanzas.stream.close(); 288 var stream = Lightstring.stanzas.stream.close();
287 this.socket.send(stream); 289 this.socket.send(stream);
288 this.emit('XMLOutput', stream); 290 this.emit('out', stream);
289 this.socket.close(); 291 this.socket.close();
290 }; 292 };
291 Lightstring.Connection.prototype.load = function() { 293 Lightstring.Connection.prototype.load = function() {
292 for (var i = 0; i < arguments.length; i++) { 294 for (var i = 0; i < arguments.length; i++) {
293 var name = arguments[i]; 295 var name = arguments[i];