1 /* Javascript for OCAMLWIKI.
2 * Copyright (C) 2004 Merjis Ltd.
3 * $Id: editor.js,v 1.6 2004/12/20 11:57:27 rich Exp $
6 // Delay in milliseconds between updates.
9 // This function is called when the content has changed (eg. from a keypress).
10 function content_changed (content_id, preview_id)
12 var preview = document.getElementById (preview_id);
14 // Set a flag to indicate that the content has changed.
15 preview.updated = true;
17 // If there's not an asynchronous preview in progress at the moment,
19 start_update (content_id, preview_id, preview);
22 function start_update (content_id, preview_id, preview)
24 if (!preview) preview = document.getElementById (preview_id);
26 // Do nothing if a preview is already in progress.
27 if (preview.in_progress) return;
29 // Get the Wiki-markup content from the content textarea.
30 var content = document.getElementById (content_id).value;
32 // Send the Wiki-markup to the server to be turned into XHTML.
33 var http = document.all ?
34 new ActiveXObject ('Microsoft.XMLHTTP') : new XMLHttpRequest ();
37 // Set a handler for state changes.
38 http.onreadystatechange = function () {
39 preview_state_change (content_id, preview_id, preview, http);
41 // 'true' argument means we want to do this asynchronously.
42 http.open ('POST', '/_bin/preview.cmo', true);
43 http.setRequestHeader ('Content-Type',
44 'application/x-www-form-urlencoded');
45 http.send ('content=' + encodeURIComponent (content));
47 // A preview is "in progress".
48 preview.in_progress = true;
49 preview.updated = false;
53 function preview_state_change (content_id, preview_id, preview, http)
55 if (http.readyState == 4) { // If state is "loaded".
56 if (http.status == 200) { // Request status is 200 OK.
57 var xhtml = http.responseText;
59 // Next line fails with my copy of IE if the text contains a
60 // link (ie. <a href...>). It is unclear why. The error is:
61 // "Unknown runtime error"
62 preview.innerHTML = xhtml;
65 // A preview is not in progress now.
66 preview.in_progress = false;
68 // Have there been further updates since this preview started? If so
69 // then we need to start another preview.
70 if (preview.updated) start_update (content_id, preview_id, preview);
74 // Update the preview field synchronously.
75 function synch_update (content_id, preview_id)
77 var preview = document.getElementById (preview_id);
79 // Get the Wiki-markup content from the content textarea.
80 var content = document.getElementById (content_id).value;
82 // Send the Wiki-markup to the server to be turned into XHTML.
83 var http = document.all ?
84 new ActiveXObject ('Microsoft.XMLHTTP') : new XMLHttpRequest ();
87 http.open ('POST', '/_bin/preview.cmo', false);
88 http.setRequestHeader ('Content-Type',
89 'application/x-www-form-urlencoded');
90 http.send ('content=' + encodeURIComponent (content));
92 if (http.readyState == 4 && http.status == 200) {
93 var xhtml = http.responseText;
94 preview.innerHTML = xhtml;
99 // Initialise the edit_buttons for a section.
100 // We do this in Javascript so that non-Javascript users won't see
101 // any buttons (they wouldn't be functional for them anyway).
102 function init_edit_buttons (div_id, content_id, preview_id)
104 // HTML for the edit buttons.
105 var args = "'" + content_id + "', '" + preview_id + "'";
106 var edit_buttons_html =
107 "<a onmousedown=\"link(" + args + "); return false;\" title=\"Select some text and click this to make a link\"><u>Link</u></a>" +
108 "<span class=\"spacer\"></span>" +
109 "<a onmousedown=\"bold(" + args + "); return false;\" title=\"Select some text and click this to make it bold\"><strong>Bold</strong></a>" +
110 "<a onmousedown=\"italic(" + args + "); return false;\" title=\"Select some text and click this to make it italic\"><em>Italic</em></a>" +
111 "<a onmousedown=\"strikeout(" + args + "); return false;\" title=\"Select some text and click this to strike through it\"><s>Strike</s></a>" +
112 "<span class=\"spacer\"></span>" +
113 "<a onmousedown=\"bullet(" + args + "); return false;\" title=\"Select lines of text and click this to make it a bullet list\"><big>∙—</big></a>" +
114 "<a onmousedown=\"numbered(" + args + "); return false;\" title=\"Select lines of text and click this to make it a numbered list\">1—</a>" +
117 var div = document.getElementById (div_id);
118 div.innerHTML = edit_buttons_html;
121 function replace_selection (content_id, fn, warning)
123 var textarea = document.getElementById (content_id);
125 if (textarea.setSelectionRange) { // Mozilla
126 var start = textarea.selectionStart;
127 var end = textarea.selectionEnd;
129 var text = textarea.value.substring (start, end);
130 var replacement = fn (text);
131 textarea.value = textarea.value.substring (0, start) +
132 replacement + textarea.value.substring (end);
134 if (warning) alert (warning);
135 } else if (document.selection) { // IE
136 var range = document.selection.createRange ();
137 if (range.parentElement () == textarea && range.text != "") {
138 var text = range.text;
139 var len = text.length;
141 // IE6 bug workaround: If the end of the selection is the end of
142 // a line, then we must remember to append a \n character after
143 // doing the replacement. Note the incredible lengths we have to
144 // go to here because IE is a piece of shit.
145 var dup = range.duplicate ();
146 dup.moveEnd ("character", 2);
148 dup.text.substring (dup.text.length-3, dup.text.length-1) == "\r\n";
150 // Replace \r\n with just \n.
151 text = text.replace ("\r\n", "\n");
153 // IE's selections often include a trailing space or carriage
154 // return. Ignore this whitespace when calling the replacement
157 if ((ar = text.match (/(\s+)$/))) {
159 text = text.substring (0, len - ws.length);
160 replacement = fn (text);
161 replacement = replacement + ws;
163 replacement = fn (range.text);
165 // See IE bug workaround above.
166 if (append) replacement += "\n";
168 range.text = replacement;
170 if (warning) alert (warning);
174 function link (content_id, preview_id)
176 var fn = function (text) {
177 if (ar = text.match (/^\[\[(.*)\]\]$/))
180 return "[[" + text + "]]";
182 var warning = "Select an area of text first.";
183 replace_selection (content_id, fn, warning);
184 start_update (content_id, preview_id);
187 function bold (content_id, preview_id)
189 var fn = function (text) {
190 if (ar = text.match (/^<b>(.*)<\/b>$/))
193 return "<b>" + text + "</b>";
195 var warning = "Select an area of text first.";
196 replace_selection (content_id, fn, warning);
197 start_update (content_id, preview_id);
200 function italic (content_id, preview_id)
202 var fn = function (text) {
203 if (ar = text.match (/^<i>(.*)<\/i>$/))
206 return "<i>" + text + "</i>";
208 var warning = "Select an area of text first.";
209 replace_selection (content_id, fn, warning);
210 start_update (content_id, preview_id);
213 function strikeout (content_id, preview_id)
215 var fn = function (text) {
216 if (ar = text.match (/^<s>(.*)<\/s>$/))
219 return "<s>" + text + "</s>";
221 var warning = "Select an area of text first.";
222 replace_selection (content_id, fn, warning);
223 start_update (content_id, preview_id);
226 function bullet (content_id, preview_id)
228 var fn = function (text) {
229 if (text.match (/^\*/))
230 return text.replace (/^\* /gm, "");
232 return "* " + text.replace (/\n/g, "\n* ");
234 var warning = "Select some whole lines of text first.";
235 replace_selection (content_id, fn, warning);
236 start_update (content_id, preview_id);
239 function numbered (content_id, preview_id)
241 var fn = function (text) {
242 if (text.match (/^#/))
243 return text.replace (/^# /gm, "");
245 return "# " + text.replace (/\n/g, "\n# ");
247 var warning = "Select some whole lines of text first.";
248 replace_selection (content_id, fn, warning);
249 start_update (content_id, preview_id);