changeset 8:7b2ca4d5af6d

Add a resend-whole-state button and make it works.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Thu, 02 Feb 2012 15:45:25 +0100
parents 853dcbe8f06f
children d3b37bbb2b88
files config.js index.xhtml script2.js sxe-document.js
diffstat 4 files changed, 78 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/config.js
+++ b/config.js
@@ -1,5 +1,5 @@
 'use strict';
 
-const SERVICE = 'ws://plugsbee.com:5280/';
-const JID = 'test@linkmauve.fr';
-const PASSWORD = 'test';
+var SERVICE = 'ws://ws.plugsbee.com/';
+var JID = 'test@linkmauve.fr';
+var PASSWORD = 'test';
--- a/index.xhtml
+++ b/index.xhtml
@@ -19,6 +19,7 @@
 <body>
   <div id="state"/>
   <button id="host">Host</button>
+  <button id="resend-state">Resend the whole state</button>
   <form id="toolbar">
     <dl>
       <dt> edit: </dt>
@@ -100,7 +101,7 @@
 
   <section id="document" contenteditable="true">
     <h2> Go ahead, edit away! </h2>
-    <p> Here's a typical paragraph element </p>
+    <p> Here's a <span style="color:red">typical</span> paragraph element </p>
     <ol><li> and now a list </li><li> with only      </li><li> three items    </li></ol>
   </section>
 
--- a/script2.js
+++ b/script2.js
@@ -111,7 +111,6 @@ var initiate = function(jid, sid) {
 
 var accept = function(sid) {
   var doc = documents[sid];
-  doc.empty();
   var accept = "<iq to='" + doc.initiator + "' type='set'>" +
                  "<jingle xmlns='" + Lightstring.ns.jingle.main + "'" +
                         " action='session-accept'" +
@@ -228,7 +227,8 @@ conn.on('iq/' + Lightstring.ns.jingle + 
 });
 
 var connect = function(sid) {
-  var host = documents[sid].host;
+  var doc = documents[sid];
+  var host = doc.host;
   var identities = roster[host].identities;
   var type = 'chat';
   identities.forEach(function(identity) {
@@ -244,6 +244,61 @@ var connect = function(sid) {
                   "</sxe>" +
                 "</message>";
   conn.send(message);
+  doc.participants[conn.jid.full] = type;
+};
+
+var offerState = function(to, type, sid) {
+  var message = "<message to='" + to + "'" +
+                        " type='" + type + "'>" +
+                  "<sxe xmlns='" + Lightstring.ns['sxe'] + "'" +
+                      " id='" + Lightstring.newId('sxe') + "'" +
+                      " session='" + sid + "'>" +
+                    "<state-offer>" +
+                      "<description xmlns='" + Lightstring.ns['jingle_apps_xhtml'] + "'/>" +
+                    "</state-offer>" +
+                  "</sxe>" +
+                "</message>";
+  conn.send(message);
+};
+
+var sendState = function(sid) {
+  var doc = documents[sid];
+  var initialState = doc.createState([]).map(function(element) {
+    return Lightstring.DOM2XML(element);
+  }).join('');
+  if (conn.jid.full in doc.participants) { // participant
+    var type = 'chat'; //XXX
+    var message = "<message to='" + doc.host + "'" +
+                          " type='" + type + "'>" +
+                    "<sxe xmlns='" + Lightstring.ns['sxe'] + "'" +
+                        " id='" + Lightstring.newId('sxe') + "'" +
+                        " session='" + sid + "'>" +
+                      "<state>" +
+                        "<document-begin prolog='" + doc.prolog + "'/>" +
+                         initialState +
+                        "<document-end last-sender='' last-id=''/>" +
+                      "</state>" +
+                    "</sxe>" +
+                  "</message>";
+    conn.send(message);
+  } else { // host
+    for (var jid in doc.participants) {
+      var type = doc.participants[jid];
+      var message = "<message to='" + jid + "'" +
+                            " type='" + type + "'>" +
+                      "<sxe xmlns='" + Lightstring.ns['sxe'] + "'" +
+                          " id='" + Lightstring.newId('sxe') + "'" +
+                          " session='" + sid + "'>" +
+                        "<state>" +
+                          "<document-begin prolog='" + doc.prolog + "'/>" +
+                           initialState +
+                          "<document-end last-sender='' last-id=''/>" +
+                        "</state>" +
+                      "</sxe>" +
+                    "</message>";
+      conn.send(message);
+    }
+  }
 };
 
 conn.on('message/' + Lightstring.ns['sxe'] + ':sxe', function(stanza) {
@@ -262,26 +317,17 @@ conn.on('message/' + Lightstring.ns['sxe
   var payload = sxe.firstChild; //TODO: really?
   switch (payload.localName) {
     case 'connect':
-      var message = "<message to='" + from + "'" +
-                            " type='" + type + "'>" +
-                      "<sxe xmlns='" + Lightstring.ns['sxe'] + "'" +
-                          " id='" + Lightstring.newId('sxe') + "'" +
-                          " session='" + sid + "'>" +
-                        "<state-offer>" +
-                          "<description xmlns='" + Lightstring.ns['jingle_apps_xhtml'] + "'/>" +
-                        "</state-offer>" +
-                      "</sxe>" +
-                    "</message>";
-      conn.send(message);
+      offerState(from, type, sid);
+      doc.participants[from] = type;
       break;
     case 'state-offer':
       var description = payload.firstChild;
       if (description.namespaceURI !== Lightstring.ns['jingle_apps_xhtml'])
         return terminate(sid, 'unsupported-applications');
 
-      var accept = false;
+      var accept = /*false;
       if (from === doc.host || from === doc.initiator)
-        accept = true;
+        accept =*/ true;
 
       //TODO: refuse if proposed multiple times.
 
@@ -296,32 +342,14 @@ conn.on('message/' + Lightstring.ns['sxe
       conn.send(message);
       break;
     case 'accept-state':
-      console.log(doc);
-      var initialState = doc.createState([]);
-      console.log(initialState);
-      initialState = initialState.map(function(element) {
-        return Lightstring.DOM2XML(element);
-      }).join('');
-      console.log(initialState);
-      var message = "<message to='" + from + "'" +
-                            " type='" + type + "'>" +
-                      "<sxe xmlns='" + Lightstring.ns['sxe'] + "'" +
-                          " id='" + Lightstring.newId('sxe') + "'" +
-                          " session='" + sid + "'>" +
-                        "<state>" +
-                          "<document-begin prolog='" + doc.prolog + "'/>" +
-                           initialState +
-                          "<document-end last-sender='' last-id=''/>" +
-                        "</state>" +
-                      "</sxe>" +
-                    "</message>";
-      conn.send(message);
+      sendState(sid);
       break;
     case 'refuse-state':
       terminate(sid, 'decline');
       break;
     case 'state':
       var elements = payload.children;
+      doc.empty();
       doc.processState(from, elements);
       break;
     default:
@@ -349,6 +377,11 @@ document.getElementById('host').addEvent
   host(Lightstring.newId('sess'), 'My First XHTML Document');
 }, false);
 
+document.getElementById('resend-state').addEventListener('click', function() {
+  for (var sid in documents)
+    sendState(sid);
+}, false);
+
 conn.on('output', function(stanza) {
   console.log('out:', stanza.DOM || stanza.XML);
 });
--- a/sxe-document.js
+++ b/sxe-document.js
@@ -25,6 +25,7 @@ var Document = function(initiator, name,
   this.initiator = initiator;
   this.name = name;
   this.host = host;
+  this.participants = {};
 
   this.prolog = prolog || 'data:application/xhtml+xml,%3C%3Fxml%20version%3D%271.0%27%3F%3E%0A%3C%21DOCTYPE%20html%3E%0A';
   this.state = 'not-started';
@@ -87,8 +88,8 @@ Document.prototype = {
     var i = 0;
     var first = elements[0];
     if (first.localName === 'document-begin') {
-      if (this.state !== 'not-started')
-        return; //TODO: the session has already started.
+      /*if (this.state !== 'not-started')
+        return;*/ //TODO: the session has already started.
       i = 1;
       this.prolog = first.getAttributeNS(null, 'prolog');
       this.state = 'getting-session';
@@ -123,7 +124,7 @@ Document.prototype = {
 
     for (var i = 0; i < children.length; i++) {
       var child = children[i];
-      var element = document.createElementNS(Lightstring.NS.sxe, 'new');
+      var element = document.createElementNS(Lightstring.ns['sxe'], 'new');
       var rid = Lightstring.newId('GUID');
       element.setAttributeNS(null, 'rid', rid);
 
@@ -139,7 +140,7 @@ Document.prototype = {
 
           //TODO: move that elsewhere, or make it prettier.
           var convertAttr = function(attr) {
-            var element = document.createElementNS(Lightstring.NS.sxe, 'new');
+            var element = document.createElementNS(Lightstring.ns['sxe'], 'new');
             element.setAttributeNS(null, 'type', 'attr');
             var arid = Lightstring.newId('GUID');
             element.setAttributeNS(null, 'rid', arid);