1 /* Javascript for OCAMLWIKI.
2 * Copyright (C) 2004 Merjis Ltd.
3 * $Id: editor.js,v 1.5 2004/11/14 14:23:27 rich Exp $
6 // Delay in milliseconds before updating.
7 // We will adjust this during editing to take into account the actual
8 // average round trip time measured during update_preview_now.
11 // This is used to measure the average round trip time.
14 var rtt = 0; // Actual average RTT measured (ms).
16 function update_preview (content_id, preview_id)
18 // Updating is quite expensive, so only update after a period of apparent
20 var preview = document.getElementById (preview_id);
21 if (preview.timer) clearTimeout (preview.timer);
23 setTimeout ("update_preview_now ('" + content_id + "', '" +
24 preview_id + "')", delay);
27 function update_preview_now (content_id, preview_id)
30 var preview = document.getElementById (preview_id);
31 if (preview.timer) preview.timer = null;
33 // Get the Wiki-markup content from the content textarea.
34 var content = document.getElementById (content_id).value;
36 // Time how long it takes to send the document to the server.
37 var start_time = (new Date()).getTime();
39 // Send the Wiki-markup to the server to be turned into XHTML.
40 var http = document.all ?
41 new ActiveXObject ('Microsoft.XMLHTTP') : new XMLHttpRequest ();
44 http.open ('POST', '/_bin/preview.cmo', false);
45 http.setRequestHeader ('Content-Type',
46 'application/x-www-form-urlencoded');
47 http.send ('content=' + encodeURIComponent (content));
49 var xhtml = http.responseText;
51 // Next line fails with my copy of IE if the text contains a
52 // link (ie. <a href...>). It is unclear why. The error is:
53 // "Unknown runtime error"
54 preview.innerHTML = xhtml;
57 // Finish timer and recompute RTT.
58 var end_time = (new Date()).getTime();
59 rtt_sum += end_time - start_time;
61 rtt = rtt_sum / rtt_n;
63 // Recompute the next delay period.
67 // Initialise the edit_buttons for a section.
68 // We do this in Javascript so that non-Javascript users won't see
69 // any buttons (they wouldn't be functional for them anyway).
70 function init_edit_buttons (div_id, content_id, preview_id)
72 // HTML for the edit buttons.
73 var args = "'" + content_id + "', '" + preview_id + "'";
74 var edit_buttons_html =
75 "<a onmousedown=\"link(" + args + "); return false;\" title=\"Select some text and click this to make a link\"><u>Link</u></a>" +
76 "<span class=\"spacer\"></span>" +
77 "<a onmousedown=\"bold(" + args + "); return false;\" title=\"Select some text and click this to make it bold\"><strong>Bold</strong></a>" +
78 "<a onmousedown=\"italic(" + args + "); return false;\" title=\"Select some text and click this to make it italic\"><em>Italic</em></a>" +
79 "<a onmousedown=\"strikeout(" + args + "); return false;\" title=\"Select some text and click this to strike through it\"><s>Strike</s></a>" +
80 "<span class=\"spacer\"></span>" +
81 "<a onmousedown=\"bullet(" + args + "); return false;\" title=\"Select lines of text and click this to make it a bullet list\"><big>∙—</big></a>" +
82 "<a onmousedown=\"numbered(" + args + "); return false;\" title=\"Select lines of text and click this to make it a numbered list\">1—</a>" +
85 var div = document.getElementById (div_id);
86 div.innerHTML = edit_buttons_html;
89 function replace_selection (content_id, fn, warning)
91 var textarea = document.getElementById (content_id);
93 if (textarea.setSelectionRange) { // Mozilla
94 var start = textarea.selectionStart;
95 var end = textarea.selectionEnd;
97 var text = textarea.value.substring (start, end);
98 var replacement = fn (text);
99 textarea.value = textarea.value.substring (0, start) +
100 replacement + textarea.value.substring (end);
102 if (warning) alert (warning);
103 } else if (document.selection) { // IE
104 var range = document.selection.createRange ();
105 if (range.parentElement () == textarea && range.text != "") {
106 var text = range.text;
107 var len = text.length;
109 // IE6 bug workaround: If the end of the selection is the end of
110 // a line, then we must remember to append a \n character after
111 // doing the replacement. Note the incredible lengths we have to
112 // go to here because IE is a piece of shit.
113 var dup = range.duplicate ();
114 dup.moveEnd ("character", 2);
116 dup.text.substring (dup.text.length-3, dup.text.length-1) == "\r\n";
118 // Replace \r\n with just \n.
119 text = text.replace ("\r\n", "\n");
121 // IE's selections often include a trailing space or carriage
122 // return. Ignore this whitespace when calling the replacement
125 if ((ar = text.match (/(\s+)$/))) {
127 text = text.substring (0, len - ws.length);
128 replacement = fn (text);
129 replacement = replacement + ws;
131 replacement = fn (range.text);
133 // See IE bug workaround above.
134 if (append) replacement += "\n";
136 range.text = replacement;
138 if (warning) alert (warning);
142 function link (content_id, preview_id)
144 var fn = function (text) {
145 if (ar = text.match (/^\[\[(.*)\]\]$/))
148 return "[[" + text + "]]";
150 var warning = "Select an area of text first.";
151 replace_selection (content_id, fn, warning);
152 update_preview_now (content_id, preview_id);
155 function bold (content_id, preview_id)
157 var fn = function (text) {
158 if (ar = text.match (/^<b>(.*)<\/b>$/))
161 return "<b>" + text + "</b>";
163 var warning = "Select an area of text first.";
164 replace_selection (content_id, fn, warning);
165 update_preview_now (content_id, preview_id);
168 function italic (content_id, preview_id)
170 var fn = function (text) {
171 if (ar = text.match (/^<i>(.*)<\/i>$/))
174 return "<i>" + text + "</i>";
176 var warning = "Select an area of text first.";
177 replace_selection (content_id, fn, warning);
178 update_preview_now (content_id, preview_id);
181 function strikeout (content_id, preview_id)
183 var fn = function (text) {
184 if (ar = text.match (/^<s>(.*)<\/s>$/))
187 return "<s>" + text + "</s>";
189 var warning = "Select an area of text first.";
190 replace_selection (content_id, fn, warning);
191 update_preview_now (content_id, preview_id);
194 function bullet (content_id, preview_id)
196 var fn = function (text) {
197 if (text.match (/^\*/))
198 return text.replace (/^\* /gm, "");
200 return "* " + text.replace (/\n/g, "\n* ");
202 var warning = "Select some whole lines of text first.";
203 replace_selection (content_id, fn, warning);
204 update_preview_now (content_id, preview_id);
207 function numbered (content_id, preview_id)
209 var fn = function (text) {
210 if (text.match (/^#/))
211 return text.replace (/^# /gm, "");
213 return "# " + text.replace (/\n/g, "\n# ");
215 var warning = "Select some whole lines of text first.";
216 replace_selection (content_id, fn, warning);
217 update_preview_now (content_id, preview_id);