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); }