Asynchronous updates.
[cocanwiki.git] / html / _js / editor.js
index 84b930e..1bf5b82 100644 (file)
@@ -1,26 +1,30 @@
 /* Javascript for OCAMLWIKI.
  * Copyright (C) 2004 Merjis Ltd.
- * $Id: editor.js,v 1.4 2004/10/26 17:50:23 rich Exp $
+ * $Id: editor.js,v 1.6 2004/12/20 11:57:27 rich Exp $
  */
 
-var delay = 1000;              // Delay in milliseconds before updating.
+// Delay in milliseconds between updates.
+var delay = 1000;
 
-function update_preview (content_id, preview_id)
+// This function is called when the content has changed (eg. from a keypress).
+function content_changed (content_id, preview_id)
 {
-  // Updating is quite expensive, so only update after a period of apparent
-  // inactivity.
   var preview = document.getElementById (preview_id);
-  if (preview.timer) clearTimeout (preview.timer);
-  preview.timer =
-    setTimeout ("update_preview_now ('" + content_id + "', '" +
-               preview_id + "')", delay);
+
+  // Set a flag to indicate that the content has changed.
+  preview.updated = true;
+
+  // If there's not an asynchronous preview in progress at the moment,
+  // then start one.
+  start_update (content_id, preview_id, preview);
 }
 
-function update_preview_now (content_id, preview_id)
+function start_update (content_id, preview_id, preview)
 {
-  // Remove the timer.
-  var preview = document.getElementById (preview_id);
-  if (preview.timer) preview.timer = null;
+  if (!preview) preview = document.getElementById (preview_id);
+
+  // Do nothing if a preview is already in progress.
+  if (preview.in_progress) return;
 
   // Get the Wiki-markup content from the content textarea.
   var content = document.getElementById (content_id).value;
@@ -30,11 +34,26 @@ function update_preview_now (content_id, preview_id)
     new ActiveXObject ('Microsoft.XMLHTTP') : new XMLHttpRequest ();
   if (http)
     {
-      http.open ('POST', '/_bin/preview.cmo', false);
+      // Set a handler for state changes.
+      http.onreadystatechange = function () {
+       preview_state_change (content_id, preview_id, preview, http);
+      };
+      // 'true' argument means we want to do this asynchronously.
+      http.open ('POST', '/_bin/preview.cmo', true);
       http.setRequestHeader ('Content-Type',
                             'application/x-www-form-urlencoded');
       http.send ('content=' + encodeURIComponent (content));
 
+      // A preview is "in progress".
+      preview.in_progress = true;
+      preview.updated = false;
+    }
+}
+
+function preview_state_change (content_id, preview_id, preview, http)
+{
+  if (http.readyState == 4) {  // If state is "loaded".
+    if (http.status == 200) {  // Request status is 200 OK.
       var xhtml = http.responseText;
 
       // Next line fails with my copy of IE if the text contains a
@@ -42,6 +61,39 @@ function update_preview_now (content_id, preview_id)
       // "Unknown runtime error"
       preview.innerHTML = xhtml;
     }
+
+    // A preview is not in progress now.
+    preview.in_progress = false;
+
+    // Have there been further updates since this preview started?  If so
+    // then we need to start another preview.
+    if (preview.updated) start_update (content_id, preview_id, preview);
+  }
+}
+
+// Update the preview field synchronously.
+function synch_update (content_id, preview_id)
+{
+  var preview = document.getElementById (preview_id);
+
+  // Get the Wiki-markup content from the content textarea.
+  var content = document.getElementById (content_id).value;
+
+  // Send the Wiki-markup to the server to be turned into XHTML.
+  var http = document.all ?
+    new ActiveXObject ('Microsoft.XMLHTTP') : new XMLHttpRequest ();
+  if (http)
+    {
+      http.open ('POST', '/_bin/preview.cmo', false);
+      http.setRequestHeader ('Content-Type',
+                            'application/x-www-form-urlencoded');
+      http.send ('content=' + encodeURIComponent (content));
+
+      if (http.readyState == 4 && http.status == 200) {
+       var xhtml = http.responseText;
+       preview.innerHTML = xhtml;
+      }
+    }
 }
 
 // Initialise the edit_buttons for a section.
@@ -129,7 +181,7 @@ function link (content_id, preview_id)
   };
   var warning = "Select an area of text first.";
   replace_selection (content_id, fn, warning);
-  update_preview_now (content_id, preview_id);
+  start_update (content_id, preview_id);
 }
 
 function bold (content_id, preview_id)
@@ -142,7 +194,7 @@ function bold (content_id, preview_id)
   };
   var warning = "Select an area of text first.";
   replace_selection (content_id, fn, warning);
-  update_preview_now (content_id, preview_id);
+  start_update (content_id, preview_id);
 }
 
 function italic (content_id, preview_id)
@@ -155,7 +207,7 @@ function italic (content_id, preview_id)
   };
   var warning = "Select an area of text first.";
   replace_selection (content_id, fn, warning);
-  update_preview_now (content_id, preview_id);
+  start_update (content_id, preview_id);
 }
 
 function strikeout (content_id, preview_id)
@@ -168,7 +220,7 @@ function strikeout (content_id, preview_id)
   };
   var warning = "Select an area of text first.";
   replace_selection (content_id, fn, warning);
-  update_preview_now (content_id, preview_id);
+  start_update (content_id, preview_id);
 }
 
 function bullet (content_id, preview_id)
@@ -181,7 +233,7 @@ function bullet (content_id, preview_id)
   };
   var warning = "Select some whole lines of text first.";
   replace_selection (content_id, fn, warning);
-  update_preview_now (content_id, preview_id);
+  start_update (content_id, preview_id);
 }
 
 function numbered (content_id, preview_id)
@@ -194,5 +246,5 @@ function numbered (content_id, preview_id)
   };
   var warning = "Select some whole lines of text first.";
   replace_selection (content_id, fn, warning);
-  update_preview_now (content_id, preview_id);
+  start_update (content_id, preview_id);
 }