comparison script2.js @ 7:853dcbe8f06f

Make barbecue work with latest Lightstring.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Thu, 02 Feb 2012 12:11:33 +0100
parents 24aa8dccb170
children 7b2ca4d5af6d
comparison
equal deleted inserted replaced
6:24aa8dccb170 7:853dcbe8f06f
23 23
24 var conn = new Lightstring.Connection(SERVICE); 24 var conn = new Lightstring.Connection(SERVICE);
25 var roster = {}; 25 var roster = {};
26 var documents = {}; 26 var documents = {};
27 27
28 Lightstring.NS.sxe = 'urn:xmpp:sxe:0'; 28 Lightstring.plugins['jingle'] = {
29 Lightstring.NS.jingle = { 29 namespaces: {
30 main: 'urn:xmpp:jingle:1', 30 jingle: 'urn:xmpp:jingle:1',
31 transports: { 31 jingle_transports_sxe: 'urn:xmpp:jingle:transports:sxe',
32 sxe: 'urn:xmpp:jingle:transports:sxe' 32 jingle_apps_xhtml: 'urn:xmpp:jingle:apps:xhtml'
33 }, 33 }
34 apps: { 34 };
35 xhtml: 'urn:xmpp:jingle:apps:xhtml' 35 Lightstring.ns['sxe'] = 'urn:xmpp:sxe:0';
36 } 36
37 }; 37 conn.on('iq/' + Lightstring.ns['disco#info'] + ':query', function(stanza) {
38
39 conn.on('iq/' + Lightstring.NS['disco#info'] + ':query', function(stanza) {
40 if (stanza.DOM.getAttributeNS(null, 'type') !== 'get') 38 if (stanza.DOM.getAttributeNS(null, 'type') !== 'get')
41 return; 39 return;
42 40
43 var query = stanza.DOM.firstChild; 41 var query = stanza.DOM.firstChild;
44 if (query.getAttributeNS(null, 'node')) { 42 if (query.getAttributeNS(null, 'node')) {
47 " type='error'/>"; //TODO: precise the error. 45 " type='error'/>"; //TODO: precise the error.
48 conn.send(response); 46 conn.send(response);
49 return; 47 return;
50 } 48 }
51 49
52 var features = [Lightstring.NS.sxe, Lightstring.NS.jingle.transports.sxe]; //TODO: put that elsewhere. 50 var features = [Lightstring.ns['sxe'], Lightstring.ns['jingle_transports_sxe']]; //TODO: put that elsewhere.
53 51
54 var response = "<iq to='" + stanza.DOM.getAttributeNS(null, 'from') + "'" + 52 var response = "<iq to='" + stanza.DOM.getAttributeNS(null, 'from') + "'" +
55 " id='" + stanza.DOM.getAttributeNS(null, 'id') + "'" + 53 " id='" + stanza.DOM.getAttributeNS(null, 'id') + "'" +
56 " type='result'>" + 54 " type='result'>" +
57 "<query xmlns='" + Lightstring.NS['disco#info'] + "'>" + 55 "<query xmlns='" + Lightstring.ns['disco#info'] + "'>" +
58 "<identity category='client' type='browser'/>"; 56 "<identity category='client' type='browser'/>";
59 features.forEach(function(f) { 57 features.forEach(function(f) {
60 response += "<feature var='" + f + "'/>"; 58 response += "<feature var='" + f + "'/>";
61 }); 59 });
62 response += "</query>" + 60 response += "</query>" +
68 conn.on('presence', function(stanza) { 66 conn.on('presence', function(stanza) {
69 var from = new Lightstring.JID(stanza.DOM.getAttributeNS(null, 'from')); 67 var from = new Lightstring.JID(stanza.DOM.getAttributeNS(null, 'from'));
70 if (!from.equals(conn.jid)) { 68 if (!from.equals(conn.jid)) {
71 var type = stanza.DOM.getAttributeNS(null, 'type'); 69 var type = stanza.DOM.getAttributeNS(null, 'type');
72 if (!type) 70 if (!type)
73 Lightstring.discoInfo(conn, from, undefined, function(aData) { 71 conn.disco.info(from, undefined, function(stanza) {
74 roster[from.full] = aData; 72 roster[from.full] = {identities: stanza.identities, features: stanza.features};
73 }, function(stanza) {
74 console.log(from + ' doesn’t handle disco#info.');
75 roster[from.full] = {};
75 }); 76 });
76 else if (type === 'unavailable') 77 else if (type === 'unavailable')
77 delete roster[from.full]; 78 delete roster[from.full];
78 } 79 }
79 }); 80 });
84 85
85 documents[sid] = new Document(conn.jid.full, name, conn.jid.full, 'document'); 86 documents[sid] = new Document(conn.jid.full, name, conn.jid.full, 'document');
86 87
87 for (var jid in roster) { 88 for (var jid in roster) {
88 var contact = roster[jid]; 89 var contact = roster[jid];
89 if ((contact.features.indexOf(Lightstring.NS.sxe) !== -1) && (contact.features.indexOf(Lightstring.NS.jingle.transports.sxe) !== -1)) 90 if ((contact.features.indexOf(Lightstring.ns['sxe']) !== -1) && (contact.features.indexOf(Lightstring.ns['jingle_transports_sxe']) !== -1))
90 initiate(jid, sid); 91 initiate(jid, sid);
91 } 92 }
92 } 93 }
93 94
94 var initiate = function(jid, sid) { 95 var initiate = function(jid, sid) {
95 var initiate = "<iq to='" + jid + "' type='set'>" + 96 var initiate = "<iq to='" + jid + "' type='set'>" +
96 "<jingle xmlns='" + Lightstring.NS.jingle.main + "'" + 97 "<jingle xmlns='" + Lightstring.ns.jingle.main + "'" +
97 " action='session-initiate'" + 98 " action='session-initiate'" +
98 " initiator='" + documents[sid].initiator + "'" + 99 " initiator='" + documents[sid].initiator + "'" +
99 " sid='" + sid + "'>" + 100 " sid='" + sid + "'>" +
100 "<content creator='initiator' name='" + documents[sid].name + "'>" + 101 "<content creator='initiator' name='" + documents[sid].name + "'>" +
101 "<description xmlns='" + Lightstring.NS.jingle.apps.xhtml + "'/>" + 102 "<description xmlns='" + Lightstring.ns['jingle_apps_xhtml'] + "'/>" +
102 "<transport xmlns='" + Lightstring.NS.jingle.transports.sxe + "'>" + 103 "<transport xmlns='" + Lightstring.ns['jingle_transports_sxe'] + "'>" +
103 "<host>" + documents[sid].host + "</host>" + 104 "<host>" + documents[sid].host + "</host>" +
104 "</transport>" + 105 "</transport>" +
105 "</content>" + 106 "</content>" +
106 "</jingle>" + 107 "</jingle>" +
107 "</iq>"; 108 "</iq>";
110 111
111 var accept = function(sid) { 112 var accept = function(sid) {
112 var doc = documents[sid]; 113 var doc = documents[sid];
113 doc.empty(); 114 doc.empty();
114 var accept = "<iq to='" + doc.initiator + "' type='set'>" + 115 var accept = "<iq to='" + doc.initiator + "' type='set'>" +
115 "<jingle xmlns='" + Lightstring.NS.jingle.main + "'" + 116 "<jingle xmlns='" + Lightstring.ns.jingle.main + "'" +
116 " action='session-accept'" + 117 " action='session-accept'" +
117 " initiator='" + doc.initiator + "'" + 118 " initiator='" + doc.initiator + "'" +
118 " sid='" + sid + "'>" + 119 " sid='" + sid + "'>" +
119 "<content creator='initiator' name='" + documents[sid].name + "'>" + 120 "<content creator='initiator' name='" + documents[sid].name + "'>" +
120 "<description xmlns='" + Lightstring.NS.jingle.apps.xhtml + "'/>" + 121 "<description xmlns='" + Lightstring.ns['jingle_apps_xhtml'] + "'/>" +
121 "<transport xmlns='" + Lightstring.NS.jingle.transports.sxe + "'>" + 122 "<transport xmlns='" + Lightstring.ns['jingle_transports_sxe'] + "'>" +
122 "<host>" + doc.host + "</host>" + 123 "<host>" + doc.host + "</host>" +
123 "</transport>" + 124 "</transport>" +
124 "</content>" + 125 "</content>" +
125 "</jingle>" + 126 "</jingle>" +
126 "</iq>"; 127 "</iq>";
135 var terminate = function(sid, reason) { 136 var terminate = function(sid, reason) {
136 if (!(sid in documents)) 137 if (!(sid in documents))
137 return console.log('BIG WARNING!!!'); 138 return console.log('BIG WARNING!!!');
138 139
139 var terminate = "<iq to='" + documents[sid].initiator + "' type='set'>" + 140 var terminate = "<iq to='" + documents[sid].initiator + "' type='set'>" +
140 "<jingle xmlns='" + Lightstring.NS.jingle.main + "'" + 141 "<jingle xmlns='" + Lightstring.ns.jingle.main + "'" +
141 " action='session-terminate'" + 142 " action='session-terminate'" +
142 " host='" + documents[sid].host + "'" + 143 " host='" + documents[sid].host + "'" +
143 " initiator='" + documents[sid].initiator + "'" + 144 " initiator='" + documents[sid].initiator + "'" +
144 " sid='" + sid + "'>" + 145 " sid='" + sid + "'>" +
145 "<reason>" + 146 "<reason>" +
149 "</iq>"; 150 "</iq>";
150 delete documents[sid]; 151 delete documents[sid];
151 conn.send(terminate); 152 conn.send(terminate);
152 }; 153 };
153 154
154 conn.on('iq/' + Lightstring.NS.jingle.main + ':jingle', function(stanza) { 155 conn.on('iq/' + Lightstring.ns.jingle + ':jingle', function(stanza) {
155 conn.send("<iq to='" + stanza.DOM.getAttributeNS(null, 'from') + "'" + 156 conn.send("<iq to='" + stanza.DOM.getAttributeNS(null, 'from') + "'" +
156 " id='" + stanza.DOM.getAttributeNS(null, 'id') + "'" + 157 " id='" + stanza.DOM.getAttributeNS(null, 'id') + "'" +
157 " type='result'/>"); 158 " type='result'/>");
158 159
159 var jingle = stanza.DOM.firstChild; 160 var jingle = stanza.DOM.firstChild;
172 173
173 if (documents[sid]) 174 if (documents[sid])
174 return terminate(sid, 'alternative-session'); //TODO: The XEP: “and wishes to use that [previous] session instead” 175 return terminate(sid, 'alternative-session'); //TODO: The XEP: “and wishes to use that [previous] session instead”
175 176
176 var description = content.getElementsByTagName('description')[0]; //TODO: supporte multiple applications. 177 var description = content.getElementsByTagName('description')[0]; //TODO: supporte multiple applications.
177 if (description.namespaceURI !== Lightstring.NS.jingle.apps.xhtml) 178 if (description.namespaceURI !== Lightstring.ns['jingle_apps_xhtml'])
178 return terminate(sid, 'unsupported-applications'); 179 return terminate(sid, 'unsupported-applications');
179 180
180 var transport = content.getElementsByTagName('transport')[0]; //TODO: supporte multiple transports. 181 var transport = content.getElementsByTagName('transport')[0]; //TODO: supporte multiple transports.
181 if (transport.namespaceURI !== Lightstring.NS.jingle.transports.sxe) 182 if (transport.namespaceURI !== Lightstring.ns['jingle_transports_sxe'])
182 return terminate(sid, 'unsupported-transports'); 183 return terminate(sid, 'unsupported-transports');
183 184
184 var host = transport.textContent; //TODO: verify the presence of the host element. 185 var host = transport.textContent; //TODO: verify the presence of the host element.
185 186
186 documents[sid] = new Document(initiator, name, host, 'document'); 187 documents[sid] = new Document(initiator, name, host, 'document');
196 var name = content.getAttributeNS(null, 'name'); 197 var name = content.getAttributeNS(null, 'name');
197 198
198 alert('Accepted! \\o/'); 199 alert('Accepted! \\o/');
199 200
200 var description = content.getElementsByTagName('description')[0]; //TODO: supporte multiple applications. 201 var description = content.getElementsByTagName('description')[0]; //TODO: supporte multiple applications.
201 if (description.namespaceURI !== Lightstring.NS.jingle.apps.xhtml) 202 if (description.namespaceURI !== Lightstring.ns['jingle_apps_xhtml'])
202 return terminate(sid, 'unsupported-applications'); 203 return terminate(sid, 'unsupported-applications');
203 204
204 var transport = content.getElementsByTagName('transport')[0]; //TODO: supporte multiple transports. 205 var transport = content.getElementsByTagName('transport')[0]; //TODO: supporte multiple transports.
205 if (transport.namespaceURI !== Lightstring.NS.jingle.transports.sxe) 206 if (transport.namespaceURI !== Lightstring.ns['jingle_transports_sxe'])
206 return terminate(sid, 'unsupported-transports'); 207 return terminate(sid, 'unsupported-transports');
207 208
208 var host = transport.textContent; //TODO: verify the presence of the host element. 209 var host = transport.textContent; //TODO: verify the presence of the host element.
209 210
210 var doc = documents[sid]; 211 var doc = documents[sid];
234 if (identity.category === 'conference') 235 if (identity.category === 'conference')
235 type = 'groupchat'; 236 type = 'groupchat';
236 }); 237 });
237 var message = "<message to='" + host + "'" + 238 var message = "<message to='" + host + "'" +
238 " type='" + type + "'>" + 239 " type='" + type + "'>" +
239 "<sxe xmlns='" + Lightstring.NS.sxe + "'" + 240 "<sxe xmlns='" + Lightstring.ns['sxe'] + "'" +
240 " id='" + Lightstring.newId('sxe') + "'" + 241 " id='" + Lightstring.newId('sxe') + "'" +
241 " session='" + sid + "'>" + 242 " session='" + sid + "'>" +
242 "<connect/>" + 243 "<connect/>" +
243 "</sxe>" + 244 "</sxe>" +
244 "</message>"; 245 "</message>";
245 conn.send(message); 246 conn.send(message);
246 }; 247 };
247 248
248 conn.on('message/' + Lightstring.NS.sxe + ':sxe', function(stanza) { 249 conn.on('message/' + Lightstring.ns['sxe'] + ':sxe', function(stanza) {
249 var from = stanza.DOM.getAttributeNS(null, 'from'); 250 var from = stanza.DOM.getAttributeNS(null, 'from');
250 var type = 'chat'; //TODO: always? 251 var type = 'chat'; //TODO: always?
251 var sxe = stanza.DOM.firstChild; //TODO: there can be multiple payloads. 252 var sxe = stanza.DOM.firstChild; //TODO: there can be multiple payloads.
252 var id = sxe.getAttributeNS(null, 'id'); 253 var id = sxe.getAttributeNS(null, 'id');
253 var sid = sxe.getAttributeNS(null, 'session'); 254 var sid = sxe.getAttributeNS(null, 'session');
261 var payload = sxe.firstChild; //TODO: really? 262 var payload = sxe.firstChild; //TODO: really?
262 switch (payload.localName) { 263 switch (payload.localName) {
263 case 'connect': 264 case 'connect':
264 var message = "<message to='" + from + "'" + 265 var message = "<message to='" + from + "'" +
265 " type='" + type + "'>" + 266 " type='" + type + "'>" +
266 "<sxe xmlns='" + Lightstring.NS.sxe + "'" + 267 "<sxe xmlns='" + Lightstring.ns['sxe'] + "'" +
267 " id='" + Lightstring.newId('sxe') + "'" + 268 " id='" + Lightstring.newId('sxe') + "'" +
268 " session='" + sid + "'>" + 269 " session='" + sid + "'>" +
269 "<state-offer>" + 270 "<state-offer>" +
270 "<description xmlns='" + Lightstring.NS.jingle.apps.xhtml + "'/>" + 271 "<description xmlns='" + Lightstring.ns['jingle_apps_xhtml'] + "'/>" +
271 "</state-offer>" + 272 "</state-offer>" +
272 "</sxe>" + 273 "</sxe>" +
273 "</message>"; 274 "</message>";
274 conn.send(message); 275 conn.send(message);
275 break; 276 break;
276 case 'state-offer': 277 case 'state-offer':
277 var description = payload.firstChild; 278 var description = payload.firstChild;
278 if (description.namespaceURI !== Lightstring.NS.jingle.apps.xhtml) 279 if (description.namespaceURI !== Lightstring.ns['jingle_apps_xhtml'])
279 return terminate(sid, 'unsupported-applications'); 280 return terminate(sid, 'unsupported-applications');
280 281
281 var accept = false; 282 var accept = false;
282 if (from === doc.host || from === doc.initiator) 283 if (from === doc.host || from === doc.initiator)
283 accept = true; 284 accept = true;
284 285
285 //TODO: refuse if proposed multiple times. 286 //TODO: refuse if proposed multiple times.
286 287
287 var message = "<message to='" + from + "'" + 288 var message = "<message to='" + from + "'" +
288 " type='" + type + "'>" + 289 " type='" + type + "'>" +
289 "<sxe xmlns='" + Lightstring.NS.sxe + "'" + 290 "<sxe xmlns='" + Lightstring.ns['sxe'] + "'" +
290 " id='" + Lightstring.newId('sxe') + "'" + 291 " id='" + Lightstring.newId('sxe') + "'" +
291 " session='" + sid + "'>" + 292 " session='" + sid + "'>" +
292 "<" + (accept? 'accept': 'refuse') + "-state/>" + 293 "<" + (accept? 'accept': 'refuse') + "-state/>" +
293 "</sxe>" + 294 "</sxe>" +
294 "</message>"; 295 "</message>";
295 conn.send(message); 296 conn.send(message);
296 break; 297 break;
297 case 'accept-state': 298 case 'accept-state':
298 var initialState = doc.createState([]).map(function(element) { 299 console.log(doc);
300 var initialState = doc.createState([]);
301 console.log(initialState);
302 initialState = initialState.map(function(element) {
299 return Lightstring.DOM2XML(element); 303 return Lightstring.DOM2XML(element);
300 }).join(''); 304 }).join('');
305 console.log(initialState);
301 var message = "<message to='" + from + "'" + 306 var message = "<message to='" + from + "'" +
302 " type='" + type + "'>" + 307 " type='" + type + "'>" +
303 "<sxe xmlns='" + Lightstring.NS.sxe + "'" + 308 "<sxe xmlns='" + Lightstring.ns['sxe'] + "'" +
304 " id='" + Lightstring.newId('sxe') + "'" + 309 " id='" + Lightstring.newId('sxe') + "'" +
305 " session='" + sid + "'>" + 310 " session='" + sid + "'>" +
306 "<state>" + 311 "<state>" +
307 "<document-begin prolog='" + doc.prolog + "'/>" + 312 "<document-begin prolog='" + doc.prolog + "'/>" +
308 initialState + 313 initialState +
329 var events = ['connected', 'conn-error', 'connecting', 'disconnected', 'disconnecting']; 334 var events = ['connected', 'conn-error', 'connecting', 'disconnected', 'disconnecting'];
330 var state = document.getElementById('state'); 335 var state = document.getElementById('state');
331 events.forEach(function(e) { 336 events.forEach(function(e) {
332 conn.on(e, function() { 337 conn.on(e, function() {
333 state.innerHTML = e; 338 state.innerHTML = e;
339 return false;
334 }); 340 });
335 }); 341 });
336 })(); 342 })();
337 343
338 conn.on('error', function(a) { 344 conn.on('error', function(a) {
341 347
342 document.getElementById('host').addEventListener('click', function() { 348 document.getElementById('host').addEventListener('click', function() {
343 host(Lightstring.newId('sess'), 'My First XHTML Document'); 349 host(Lightstring.newId('sess'), 'My First XHTML Document');
344 }, false); 350 }, false);
345 351
352 conn.on('output', function(stanza) {
353 console.log('out:', stanza.DOM || stanza.XML);
354 });
355 conn.on('input', function(stanza) {
356 console.log('in:', stanza.DOM || stanza.XML);
357 });
358
346 conn.on('connected', function() { 359 conn.on('connected', function() {
347 conn.on('output', function(stanza) { 360 conn.presence.send(conn);
348 console.log('out:', stanza.DOM); 361 return true;
349 }); 362 });
350 conn.on('input', function(stanza) { 363
351 console.log('in:', stanza.DOM); 364 conn.load('DIGEST-MD5');
352 }); 365 conn.load('presence');
353 366 conn.load('disco');
354 Lightstring.presence(conn); 367 conn.load('jingle');
355 }); 368 conn.disco.addFeatures(Lightstring.ns['jingle_transports_sxe'], Lightstring.ns['sxe']);
356
357 conn.connect(JID + '/' + prompt('Resource?'), PASSWORD); 369 conn.connect(JID + '/' + prompt('Resource?'), PASSWORD);
358
359 register_feature_not_implemented.call(conn);