X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=html%2F_js%2Feditor.js;h=1bf5b8262f34576cb9a2b5bdea004053730f9069;hb=e336401181f56f19ec18175d47462e7a5d5f07e2;hp=ad33c6e39e1ad3fb7d89cdd517bc073328c4fb70;hpb=3062d573a7617339324c23cdd4755f8f04956b92;p=cocanwiki.git
diff --git a/html/_js/editor.js b/html/_js/editor.js
index ad33c6e..1bf5b82 100644
--- a/html/_js/editor.js
+++ b/html/_js/editor.js
@@ -1,26 +1,30 @@
/* Javascript for OCAMLWIKI.
* Copyright (C) 2004 Merjis Ltd.
- * $Id: editor.js,v 1.1 2004/09/07 10:14:09 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,4 +61,190 @@ 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.
+// We do this in Javascript so that non-Javascript users won't see
+// any buttons (they wouldn't be functional for them anyway).
+function init_edit_buttons (div_id, content_id, preview_id)
+{
+ // HTML for the edit buttons.
+ var args = "'" + content_id + "', '" + preview_id + "'";
+ var edit_buttons_html =
+ "Link" +
+ "" +
+ "Bold" +
+ "Italic" +
+ "Strike" +
+ "" +
+ "∙—" +
+ "1—" +
+ "
"
+ ;
+ var div = document.getElementById (div_id);
+ div.innerHTML = edit_buttons_html;
+}
+
+function replace_selection (content_id, fn, warning)
+{
+ var textarea = document.getElementById (content_id);
+
+ if (textarea.setSelectionRange) { // Mozilla
+ var start = textarea.selectionStart;
+ var end = textarea.selectionEnd;
+ if (start != end) {
+ var text = textarea.value.substring (start, end);
+ var replacement = fn (text);
+ textarea.value = textarea.value.substring (0, start) +
+ replacement + textarea.value.substring (end);
+ } else
+ if (warning) alert (warning);
+ } else if (document.selection) { // IE
+ var range = document.selection.createRange ();
+ if (range.parentElement () == textarea && range.text != "") {
+ var text = range.text;
+ var len = text.length;
+
+ // IE6 bug workaround: If the end of the selection is the end of
+ // a line, then we must remember to append a \n character after
+ // doing the replacement. Note the incredible lengths we have to
+ // go to here because IE is a piece of shit.
+ var dup = range.duplicate ();
+ dup.moveEnd ("character", 2);
+ append =
+ dup.text.substring (dup.text.length-3, dup.text.length-1) == "\r\n";
+
+ // Replace \r\n with just \n.
+ text = text.replace ("\r\n", "\n");
+
+ // IE's selections often include a trailing space or carriage
+ // return. Ignore this whitespace when calling the replacement
+ // function.
+ var replacement;
+ if ((ar = text.match (/(\s+)$/))) {
+ var ws = ar[1];
+ text = text.substring (0, len - ws.length);
+ replacement = fn (text);
+ replacement = replacement + ws;
+ } else
+ replacement = fn (range.text);
+
+ // See IE bug workaround above.
+ if (append) replacement += "\n";
+
+ range.text = replacement;
+ } else
+ if (warning) alert (warning);
+ }
+}
+
+function link (content_id, preview_id)
+{
+ var fn = function (text) {
+ if (ar = text.match (/^\[\[(.*)\]\]$/))
+ return ar[1];
+ else
+ return "[[" + text + "]]";
+ };
+ var warning = "Select an area of text first.";
+ replace_selection (content_id, fn, warning);
+ start_update (content_id, preview_id);
+}
+
+function bold (content_id, preview_id)
+{
+ var fn = function (text) {
+ if (ar = text.match (/^(.*)<\/b>$/))
+ return ar[1];
+ else
+ return "" + text + "";
+ };
+ var warning = "Select an area of text first.";
+ replace_selection (content_id, fn, warning);
+ start_update (content_id, preview_id);
+}
+
+function italic (content_id, preview_id)
+{
+ var fn = function (text) {
+ if (ar = text.match (/^(.*)<\/i>$/))
+ return ar[1];
+ else
+ return "" + text + "";
+ };
+ var warning = "Select an area of text first.";
+ replace_selection (content_id, fn, warning);
+ start_update (content_id, preview_id);
+}
+
+function strikeout (content_id, preview_id)
+{
+ var fn = function (text) {
+ if (ar = text.match (/^(.*)<\/s>$/))
+ return ar[1];
+ else
+ return "" + text + "";
+ };
+ var warning = "Select an area of text first.";
+ replace_selection (content_id, fn, warning);
+ start_update (content_id, preview_id);
+}
+
+function bullet (content_id, preview_id)
+{
+ var fn = function (text) {
+ if (text.match (/^\*/))
+ return text.replace (/^\* /gm, "");
+ else
+ return "* " + text.replace (/\n/g, "\n* ");
+ };
+ var warning = "Select some whole lines of text first.";
+ replace_selection (content_id, fn, warning);
+ start_update (content_id, preview_id);
+}
+
+function numbered (content_id, preview_id)
+{
+ var fn = function (text) {
+ if (text.match (/^#/))
+ return text.replace (/^# /gm, "");
+ else
+ return "# " + text.replace (/\n/g, "\n# ");
+ };
+ var warning = "Select some whole lines of text first.";
+ replace_selection (content_id, fn, warning);
+ start_update (content_id, preview_id);
}