Subversion-Projekte lars-tiefland.content-management

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
 
2
var whizzywig_version = 'Whizzywig v54a';
3
//Copyright © 2005 John Goodman - john.goodman(at)unverse.net  *date 061002
4
//Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
//The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7
var buttonPath;  //path to toolbar button images;  unset or "textbuttons" means don't use images
8
var cssFile;     //url of CSS stylesheet to attach to edit area
9
var imageBrowse; //path to page for image browser
10
var linkBrowse;  //path to page for link browser
11
var idTa;        //id of the textarea to whizzywig (param to makeWhizzyWig)
12
var gentleClean = "true";  //true: cleanUp preserves spans, inline styles and classes; false: deletes same; ask: asks.
13
//OTHER GLOBALS
14
var oW, sel, rng, papa, trail,  ppw; //object of Whizzy,  current sel, range, parent, DOM path (IE), event, popwindow;
15
var sels = '';
16
var buts = '';
17
var vals = new Array();
18
var opts = new Array();
19
var dobut = new Array();
20
 
21
 
22
 
23
function makeWhizzyWig(txtArea, controls){ // make a WhizzyWig from the textarea
24
 idTa = txtArea;
25
 
26
 if ((navigator.userAgent.indexOf('Safari') != -1 ) || !document.getElementById || !document.designMode ) {//no designMode (Safari lies)
27
  tagButs();
28
  alert("Whizzywig "+t("editor not available for your browser"));
29
  return;
30
 }
31
 var taContent = o(idTa).defaultValue ? o(idTa).defaultValue : o(idTa).innerHTML ? o(idTa).innerHTML: ''; //anything in the textarea?
32
 if (!o(idTa).rows < 5) o(idTa).rows='15';//IE won't use % from style
33
 taWidth = o(idTa).style.width ? o(idTa).style.width : o(idTa).cols + "ex";  //grab the width and...
34
 taHeight = o(idTa).style.height ? o(idTa).style.height : o(idTa).rows + "em";  //...height from the textarea
35
 o(idTa).style.color = '#060';
36
 o(idTa).style.zIndex = '2';
37
 h(idTa);
38
 var frm=o(idTa).parentNode;
39
 while (frm.nodeName != 'FORM') frm=frm.parentNode;//if not form, keep trying
40
 if (frm.addEventListener) frm.addEventListener("submit", syncTextarea, false);
41
  else frm.attachEvent("onsubmit", syncTextarea);
42
 w('<style type="text/css">button {vertical-align:middle;padding:0;margin:1px 0} button img{vertical-align:middle;margin:-1px} select{vertical-align:middle;margin:1px}  .ctrl {background:ButtonFace; border:2px outset ButtonShadow; padding:5px;} #sourceTa{color:#060;font-family:mono;} #whizzyWig {border-width:1px}</style>');
43
 sels += 'fontname fontsize formatblock';
44
 buts += ' bold italic underline | left center right | number bullet indent outdent | undo redo  | color hilite rule | link image table | word clean html spellcheck ';
45
 var tbuts = ' tstart add_row_above add_row_below delete_row | add_column_before add_column_after delete_column | table_in_cell';
46
 var t_end = ''; //table controls end, if needed
47
 buts += tbuts;
48
 controls = controls.toLowerCase();
49
 if (!controls || controls == "all")  controls = sels +' newline '+ buts;
50
 else controls += tbuts;
51
 w('<div style="width:'+taWidth+'"><div id="CONTROLS" class="ctrl" unselectable="on">');
52
 gizmos = controls.split(' ');
53
 for (var i = 0; i < gizmos.length; i++) {
54
  if (gizmos[i]){ //make buttons and selects for toolbar, in order requested
55
   if (gizmos[i] == 'tstart') {
56
    w('<div id="TABLE_CONTROLS" style="display:none" unselectable="on">');
57
    t_end = '</div>';
58
   }
59
   else if (gizmos[i] == '|') w('&nbsp;<big style="padding-bottom:2em">|</big>&nbsp;');
60
   else if (gizmos[i] == 'newline') w('<br>');
61
   else if (sels.indexOf(gizmos[i]) != -1) makeSelect(gizmos[i])
62
   else if (buts.indexOf(gizmos[i]) != -1) makeButton(gizmos[i]);
63
  }
64
 }
65
 w(t_end) //table controls end
66
 w(fGo('LINK'));
67
 if (linkBrowse) w('<input type="button" onclick=doWin("'+linkBrowse+'"); value="'+t("Browse")+'"> ');
68
 w(t('Link address (URL)')+': <input type="text" id="lf_url" size="60"><br><input type="button" value="http://" onclick="o(\'lf_url\').value=\'http://\'+o(\'lf_url\').value"> <input type="button" value="mailto:" onclick="o(\'lf_url\').value=\'mailto:\'+o(\'lf_url\').value"><input type="checkbox" id="lf_new">'+t("Open link in new window")+fNo(t("OK"),"insertLink()"));//LINK_FORM end
69
 w(fGo('IMAGE'));
70
 if (imageBrowse) w('<input type="button" onclick=doWin("'+imageBrowse+'"); value="'+t("Browse")+'"> ');
71
 w(t('Image address (URL)')+': <input type="text" id="if_url" size="50"> <label title='+t("to display if image unavailable")+'><br>'+t("Alternate text")+':<input id="if_alt" type="text" size="50"></label><br>'+t("Align")+':<select id="if_side"><option value="none">_&hearts;_ '+t("normal")+'</option><option value="left">&hearts;= &nbsp;'+t("left")+'</option><option value="right">=&hearts; &nbsp;'+t("right")+'</option></select> '+t("Border")+':<input type="text" id="if_border" size="20" value="none" title="'+t("number or CSS e.g. 3px maroon outset")+'"> '+t("Margin")+':<input type="text" id="if_margin" size="20" value="0" title="'+t("number or CSS e.g. 5px 1em")+'">'+fNo(t("Insert Image"),"insertImage()"));//IMAGE_FORM end
72
 w(fGo('TABLE')+t("Rows")+':<input type="text" id="tf_rows" size="2" value="3"> <select id="tf_head"><option value="0">'+t("No header row")+'</option><option value="1">'+t("Include header row")+'</option></select> '+t("Columns")+':<input type="text" id="tf_cols" size="2" value="3"> '+t("Border width")+':<input type="text" id="tf_border" size="2" value="1"> '+fNo(t("Insert Table"),"makeTable()"));//TABLE_FORM end
73
 w(fGo('COLOR')+'<input type="hidden" id="cf_cmd"><div style="background:#000;padding:1px;height:22px;width:125px;float:left"><div id="cPrvw" style="background-color:red; height:100%; width:100%"></div></div> <input type=text id="cf_color" value="red" size=17 onpaste=vC(value) onblur=vC(value)> <input type="button" onmouseover=vC() onclick=sC() value="'+t("OK")+'">  <input type="button" onclick="hideDialogs();" value="'+t("Cancel")+'"><br> '+t("click below or enter a")+' <a href="http://www.unverse.net/colortable.htm" target="_blank">'+t("color name")+'</a><br clear=all> <table border=0 cellspacing=1 cellpadding=0 width=480 bgcolor="#000000">'+"\n");
74
 var wC = new Array("00","33","66","99","CC","FF")  //color table
75
 for (i=0; i<wC.length; i++){
76
  w("<tr>");
77
  for (j=0; j<wC.length; j++){
78
   for (k=0; k<wC.length; k++){
79
    var clr = wC[i]+wC[j]+wC[k];
80
    w(' <td style="background:#'+clr+';height:12px;width:12px" onmouseover=vC("#'+clr+'") onclick=sC("#'+clr+'")></td>'+"\n");
81
   }
82
  }
83
  w('</tr>');
84
 }
85
 w("</table></div>\n"); //end color table,COLOR_FORM
86
 w("</div>\n"); //controls end
87
 w('<div class="ctrl" id="showWYSIWYG" style="display:none"><input type="button" onclick="showDesign();" value="'+t("Hide HTML")+'">');
88
 tagButs();
89
 w('</div>'+"\n");
90
 
91
 w('<iframe style="width:100%;height:'+taHeight+'" src="javascript:;" id="whizzyWig"></iframe></div>'+"\n");
92
 
93
 w('<a href="http://www.unverse.net" style="color:buttonface" title="'+whizzywig_version+'">.</a> ');
94
 var startHTML = "<html>\n";
95
 startHTML += "<head>\n";
96
 if (cssFile) {
97
  startHTML += "<link media=\"all\" type=\"text/css\" href=\"" + cssFile + "\" rel=\"stylesheet\">\n";
98
 }
99
 startHTML += "</head>\n";
100
 startHTML += "<body>\n";
101
 startHTML += tidyD(taContent);
102
 startHTML += "</body>\n";
103
 startHTML += "</html>";
104
 oW = o("whizzyWig").contentWindow;
105
 try {
106
	 oW.document.designMode = "on";
107
 } catch (e) { //not set? try again
108
  setTimeout('oW.designMode = "on";', 100);
109
 }
110
 if (oW.addEventListener)  {
111
	oW.addEventListener("keypress", kb_handler, true); //keyboard shortcuts for Moz
112
	oW.addEventListener("mouseup", whereAmI, false);
113
	oW.addEventListener("keyup", whereAmI, false);
114
 }
115
 oW.document.open();
116
 oW.document.write(startHTML);
117
 oW.document.close();
118
 setTimeout('oW.document.body.onmouseup=whereAmI; oW.document.body.onkeyup=whereAmI;', 100);
119
} //end makeWhizzyWig
120
 
121
 
122
function makeButton(button){  // assemble the button requested
123
 var ucBut = button.substring(0,1).toUpperCase();
124
 ucBut += button.substring(1);
125
 ucBut = t(ucBut.replace(/_/g,' '));
126
 if (!document.frames && button=="word") return; //Paste not allowed from script in Firefox
127
 if (!buttonPath || buttonPath == "textbuttons")
128
  var butHTML = '<button type=button onClick=makeSo("'+button+'")>'+ucBut+"</button>\n";
129
 else var butHTML = '<button  title="'+ucBut+'" type=button onClick=makeSo("'+button+'")><img src="'+buttonPath+button+'.gif" alt="'+ucBut+'" onError="this.parentNode.innerHTML=this.alt"></button>';
130
 w(butHTML);
131
}
132
 
133
function fGo(id){ return '<div id="'+id+'_FORM" style="display:none" onkeypress="if(event.keyCode==13) return false;"><hr>'+"\n"; }//new form
134
 
135
function fNo(txt,go){ //form do it/cancel buttons
136
 return ' <input type="button" onclick="'+go+'" value="'+txt+'"> <input type="button" onclick="hideDialogs();" value='+t("Cancel")+"></div>\n";
137
}
138
 
139
function makeSelect(select){ // assemble the <select> requested
140
 if (select == 'formatblock') {
141
  var h = "Heading";
142
 var values = ["<p>", "<p>", "<h1>", "<h2>", "<h3>", "<h4>", "<h5>", "<h6>", "<address>",  "<pre>"];
143
 var options = [t("Choose style")+":", t("Paragraph"), t(h)+" 1 ", t(h)+" 2 ", t(h)+" 3 ", t(h)+" 4 ", t(h)+" 5 ", t(h)+" 6", t("Address"), t("Fixed width<pre>")];
144
 } else if (select == 'fontname') {
145
var values = ["Arial, Helvetica, sans-serif", "Arial, Helvetica, sans-serif","'Arial Black', Helvetica, sans-serif", "'Comic Sans MS' fantasy", "Courier New, Courier, monospace", "Georgia, serif", "Impact,sans-serif","'Times New Roman', Times, serif", "'Trebuchet MS',sans-serif", "Verdana, Arial, Helvetica, sans-serif"];
146
 var options = [t("Font")+":", "Arial","Arial Black", "Comic", "Courier", "Georgia", "Impact","Times New Roman", "Trebuchet","Verdana"];
147
 } else if (select == 'fontsize') {
148
  var values = ["3", "1", "2", "3", "4", "5", "6", "7"];
149
  var options = [t("Font size")+":", "1 "+t("Small"), "2", "3", "4", "5", "6", "7 "+t("Big")];
150
 } else {
151
	 var values = vals[select];
152
	 var options = opts[select];
153
	}
154
 w('<select id="' + select + '" onchange="doSelect(this.id);">'+"\n");
155
 for (var i = 0; i < values.length; i++) {
156
  w(' <option value="' + values[i] + '">' + options[i] + "</option>\n");
157
 }
158
 w("</select>\n");
159
}
160
 
161
function tagButs() {
162
 w('<input type="button" onclick=\'doTag("<h1>")\' value="H1" title="<H1>"><input type="button" onclick=\'doTag("<h2>")\' value="H2" title="<H2>"><input type="button" onclick=\'doTag("<h3>")\' value="H3" title="<H3>"><input type="button" onclick=\'doTag("<h4>")\' value="H4" title="<H4>"><input type="button" onclick=\'doTag("<p>")\' value="P" title="<P>"><input type="button" onclick=\'doTag("<strong>")\' value="S" title="<STRONG>" style="font-weight:bold"><input type="button" onclick=\'doTag("<em>")\' value="E" title="<EM>" style="font-style:italic;"><input type="button" onclick=\'doTag("<li>")\' value="&bull;&mdash;" title="<LI>"><input type="button" onclick=\'doTag("<a>")\' value="@" title="<A HREF= >"><input type="button" onclick=\'doTag("<img>")\' value="[&hearts;]" title="<IMG SRC= >"><input type="button" onclick=\'doTag("<br />")\' value="&larr;" title="<BR />">');
163
}
164
 
165
function makeSo(command, option) {  //format selected text or line in the whizzy
166
 whereAmI();
167
 hideDialogs();
168
 if (buts.indexOf(command) < buts.indexOf('bold')) {insHTML(dobut[command]); return;}
169
 if (!document.all) oW.document.execCommand('useCSS',false, true); //no spans for bold, italic
170
 if ("leftrightcenterjustify".indexOf(command) !=-1) command = "justify" + command;
171
 else if (command == "number") command = "insertorderedlist";
172
 else if (command == "bullet") command = "insertunorderedlist";
173
 else if (command == "rule") command = "inserthorizontalrule";
174
 switch (command) {
175
  case "color": o('cf_cmd').value="forecolor"; if (textSel()) s('COLOR_FORM'); break;
176
  case "hilite" : o('cf_cmd').value="backcolor"; if (textSel()) s('COLOR_FORM'); break;
177
  case "image" : s('IMAGE_FORM'); break;
178
  case "link" : if (textSel()) s('LINK_FORM'); break;
179
  case "html" : showHTML(); break;
180
  case "table" : doTable(); break;
181
  case "delete_row" : doRow('delete','0'); break;
182
  case "add_row_above" : doRow('add','0'); break;
183
  case "add_row_below" : doRow('add','1'); break;
184
  case "delete_column" : doCol('delete','0'); break;
185
  case "add_column_before" : doCol('add','0'); break;
186
  case "add_column_after" : doCol('add','1'); break;
187
  case "table_in_cell" : hideDialogs(); s('TABLE_FORM'); break;
188
  case "clean" : cleanUp(); break;
189
  case "word" : oW.document.execCommand("paste", false, false); gentleClean=false; cleanUp(); break;
190
  case "spellcheck" : spellCheck(); break;
191
  default: oW.document.execCommand(command, false, option);
192
 }
193
 oW.focus();
194
}
195
 
196
function doSelect(selectname) {  //select on toolbar used - do it
197
 whereAmI();
198
 var idx = o(selectname).selectedIndex;
199
 var selected = o(selectname).options[idx].value;
200
 if (" _formatblock_fontname_fontsize".indexOf('_'+selectname) > 0) {
201
  var cmd = selectname;
202
  oW.document.execCommand(cmd, false, selected);
203
 } else {
204
  insHTML(selected);//insHTML(selected.replace(/insHTML/,''));
205
 }
206
 o(selectname).selectedIndex = 0;
207
 oW.focus();
208
}
209
 
210
function vC(colour) { // view Colour
211
 if (!colour) colour = o('cf_color').value;
212
 o('cPrvw').style.backgroundColor = colour;
213
 o('cf_color').value = colour;
214
}
215
 
216
function sC(color) {  //set Color for text or background
217
 hideDialogs();
218
 var cmd = o('cf_cmd').value;
219
 if  (!color) color = o('cf_color').value;
220
 if (document.selection) rng.select(); //else IE gets lost
221
 if (cmd == "backcolor")  insHTML('<span style="background-color:'+color+'">');
222
 else insHTML('<span style="color:'+color+'">');
223
}
224
 
225
function insertLink(URL) {
226
 hideDialogs();
227
 if (!URL) URL = o("lf_url").value;
228
 var tgt = o("lf_new").checked ? 'target="_blank"' : "";
229
 if (URL) insHTML('<a href="'+URL+'" '+tgt+'>');
230
 else makeSo('unlink', false);
231
}
232
 
233
function insertImage(URL, side, border, margin, alt) { // insert image as specified
234
 hideDialogs();
235
 if (!URL) URL = o("if_url").value;
236
 if (URL) {
237
  if (!alt) alt = o("if_alt").value ? o("if_alt").value: URL.replace(/.*\/(.+)\..*/,"$1");
238
  img = '<img alt="' + alt + '" src="' + URL +'" ';
239
  if (!side) side = o("if_side").value;
240
  if ((side == "left") || (side == "right")) img += 'align="' + side + '"';
241
  if (!border)  border = o("if_border").value;
242
  if (border.match(/^\d+$/)) border+='px solid';
243
  if (!margin) margin = o("if_margin").value;
244
  if (margin.match(/^\d+$/)) margin+='px';
245
  if (border || margin) img += 'style="border:' + border + ';margin:' + margin + ';"';
246
  img += '/>';
247
  insHTML(img);
248
 }
249
}
250
 
251
function doTable(){ //show table controls if in a table, else make table
252
 if (trail.indexOf('TABLE') > 0) s('TABLE_CONTROLS');
253
  else s('TABLE_FORM');
254
}
255
 
256
function doRow(toDo,below) { //insert or delete a table row
257
 var paNode = papa;
258
 while (paNode.tagName != "TR") paNode = paNode.parentNode;
259
 var tRow = paNode.rowIndex;
260
 var tCols = paNode.cells.length;
261
 while (paNode.tagName != "TABLE") paNode = paNode.parentNode;
262
 if (toDo == "delete") paNode.deleteRow(tRow);
263
 else {
264
  var newRow = paNode.insertRow(tRow+parseInt(below)); //1=below  0=above
265
   for (i = 0; i < tCols; i++){
266
    var newCell = newRow.insertCell(i);
267
    newCell.innerHTML = "#";
268
   }
269
 }
270
}
271
 
272
function doCol(toDo,after) { //insert or delete a column
273
 var paNode = papa;
274
 while (paNode.tagName != 'TD') paNode = paNode.parentNode;
275
 var tCol = paNode.cellIndex;
276
 while (paNode.tagName != "TABLE") paNode = paNode.parentNode;
277
 var tRows = paNode.rows.length;
278
 for (i = 0; i < tRows; i++){
279
  if (toDo == "delete") paNode.rows[i].deleteCell(tCol);
280
  else {
281
   var newCell = paNode.rows[i].insertCell(tCol+parseInt(after)); //if after = 0 then before
282
   newCell.innerHTML = "#";
283
  }
284
 }
285
}
286
 
287
function makeTable() { //insert a table
288
 hideDialogs();
289
 var rows = o('tf_rows').value;
290
 var cols = o('tf_cols').value;
291
 var border = o('tf_border').value;
292
 var head = o('tf_head').value;
293
 if ((rows > 0) && (cols > 0)) {
294
  var table = '<table border="' + border + '">';
295
  for (var i=1; i <= rows; i++) {
296
   table = table + "<tr>";
297
   for (var j=1; j <= cols; j++) {
298
    if (i==1) {
299
     if (head=="1") table += "<th>Title"+j+"</th>"; //Title1 Title2 etc.
300
     else table += "<td>"+j+"</td>";
301
    }
302
    else if (j==1) table += "<td>"+i+"</td>";
303
   else table += "<td>#</td>";
304
   }
305
   table += "</tr>";
306
  }
307
  table += " </table>";
308
  insHTML(table);
309
 }
310
}
311
 
312
function doWin(URL) {  //popup  for browse function
313
 ppw=window.open(URL,'popWhizz','toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=640,height=480,top=100');
314
 ppw.focus();
315
}
316
 
317
function spellCheck() {  //check spelling with plugin if available
318
 if (document.all) {
319
 try {
320
  var tmpis = new ActiveXObject("ieSpell.ieSpellExtension");
321
  tmpis.CheckAllLinkedDocuments(document);
322
 }
323
 catch(exception) {
324
  if(exception.number==-2146827859) {
325
  if (confirm("ieSpell is not installed on your computer. \n Click [OK] to go to download page."))
326
    window.open("http://www.iespell.com/download.php","DownLoad");
327
  } else {
328
   alert("Error Loading ieSpell: Exception " + exception.number);
329
  }
330
 }
331
 } else {
332
   if (confirm("Click [OK] for instructions to download and install SpellBound on your computer. \n If you already have it, click [Cancel] then right click in the edit area and select 'Check Spelling'."))
333
     window.open("http://spellbound.sourceforge.net/install","DownLoad");
334
 }
335
}
336
 
337
function cleanUp(){  //clean up crud inserted by Micro$oft Orifice
338
 oW.document.execCommand("removeformat",false,null);
339
// whereAmI();
340
 var h = oW.document.body.innerHTML;
341
 var vicious = false;
342
 if (gentleClean=="ask") vicious=confirm(t('Remove all styles and classes?'));
343
 if (!gentleClean || vicious){
344
	h = h.replace(/<\/?(SPAN|DEL|INS|U|DIR)[^>]*>/gi, "")
345
	.replace(/\b(CLASS|STYLE)=\"[^\"]*\"/gi, "")
346
	.replace(/\b(CLASS|STYLE)=\w+/gi, "");
347
 }
348
 h = h.replace(/<\/?(\?XML|ST1|FONT|SHAPE|V:|O:|F:|F |PATH|LOCK|IMAGEDATA|STROKE|FORMULAS)[^>]*>/gi, "")
349
 .replace(/\bCLASS=\"?MSO\w*\"?/gi, "")
350
 .replace(/[–]/g,'-') //long –
351
 .replace(/[‘’]/g, "'") //single smartquotes ‘’
352
 .replace(/[“”]/g, '"') //double smartquotes “”
353
 .replace(/align="?justify"?/gi, "") //justify sends some browsers mad
354
 .replace(/<(TABLE|TD|TH)(.*)(WIDTH|HEIGHT)[^A-Za-z>]*/gi, "<$1$2") //no fixed size tables
355
 .replace(/<([^>]+)>\s*<\/\1>/gi, ""); //empty tag
356
 oW.document.body.innerHTML = h;
357
 syncTextarea();
358
}
359
 
360
function hideDialogs() {
361
 h('LINK_FORM');
362
 h('IMAGE_FORM');
363
 h('COLOR_FORM');
364
 h('TABLE_FORM');
365
 h('TABLE_CONTROLS');
366
}
367
 
368
function showDesign() {
369
 oW.document.body.innerHTML = tidyD(o(idTa).value);
370
 h(idTa);
371
 h('showWYSIWYG');
372
 s('CONTROLS');
373
 s('whizzyWig');
374
 if(o("whizzyWig").contentDocument) o("whizzyWig").contentDocument.designMode = "on"; //FF loses it on hide
375
 oW.focus();
376
}
377
 
378
function showHTML() {
379
 var t = (window.get_xhtml) ? get_xhtml(oW.document.body) : oW.document.body.innerHTML;
380
 o(idTa).value = tidyH(t);
381
 h('CONTROLS');
382
 h('whizzyWig');
383
 s(idTa);
384
 s('showWYSIWYG');
385
 o(idTa).focus();
386
}
387
 
388
function syncTextarea() { //tidy up before we go-go
389
 var b = oW.document.body;
390
 if (o(idTa).style.display == 'block') b.innerHTML = o(idTa).value;
391
 b.innerHTML = tidyH(b.innerHTML);
392
 o(idTa).value = (window.get_xhtml) ? get_xhtml(b) : b.innerHTML;
393
 o(idTa).value = o(idTa).value.replace(location.href+'#','#'); //IE anchor bug
394
}
395
 
396
function tidyD(h){ //FF designmode likes <B>,<I>...
397
 h = h.replace(/<(\/?)strong([^>]*)>/gi, "<$1B$2>");
398
 h = h.replace(/<(\/?)em([^>]*)>/gi, "<$1I$2>");
399
 return h;
400
}
401
 
402
function tidyH(h){ //...but <B>,<I> deprecated
403
 h = h.replace(/<(\w+)[^>]*>\s*<\/\1>/gi, ""); //empty tag <([^>]+)>\s*<\/\1>
404
 h = h.replace(/(<\/?)[Bb]>/g, "$1strong>");
405
 h = h.replace(/(<\/?)[Ii]>/g, "$1em>");
406
 h = h.replace(/(<\/?)[Bb](\s+[^>]*)>/g, "$1strong$2>");
407
 h = h.replace(/(<\/?)[Ii](\s+[^>]*)>/g, "$1em$2>");
408
 h = h.replace(location.href+'#','#'); //IE anchor bug
409
 return h;
410
}
411
 
412
function kb_handler(evt) { // keyboard controls for Mozilla
413
 if (evt && evt.ctrlKey) {
414
  var key = String.fromCharCode(evt.charCode).toLowerCase();
415
  var cmd = '';
416
  switch (key) {
417
   case 'b': cmd = "bold"; break;
418
   case 'i': cmd = "italic"; break;
419
   case 'u': cmd = "underline"; break;
420
   case 'l': cmd = "link"; break;
421
   case 'm': cmd = "image"; break;
422
  };
423
  if (cmd) {
424
   makeSo(cmd, true);
425
   evt.preventDefault();  // stop the event bubble
426
   evt.stopPropagation();
427
  }
428
 }
429
}
430
 
431
function doTag(html) { // insert HTML into text area
432
 var url;
433
 if (!html) html = prompt("Enter some HTML or text to insert:", "");
434
 o(idTa).focus();
435
 if (html == '<a>') {
436
  url = prompt("Link address:","http://");
437
  html='<a href="'+url+'">';
438
 }
439
 if (html == '<img>') {
440
  url = prompt("Address of image:","http://");
441
  var alt = prompt("Description of image");
442
  html ='<img src="'+url+'" alt="'+alt+'">';
443
 }
444
 var close = '';
445
 if (html.indexOf('<') == 0 && html.indexOf('br') != 1 && html.indexOf('img') != 1)
446
  close = html.replace(/<([a-z0-6]+).*/,"<\/$1>");
447
 if (html != '<strong>' && html != '<em>') close += '\n';
448
 if (document.selection) {
449
		sel = document.selection.createRange();
450
		sel.text = html+sel.text+close;
451
	} else {
452
  	before = o(idTa).value.slice(0,o(idTa).selectionStart);
453
  	sel = o(idTa).value.slice(o(idTa).selectionStart,o(idTa).selectionEnd);
454
  	after = o(idTa).value.slice(o(idTa).selectionEnd);
455
  	o(idTa).value  = before+html+sel+close+after;
456
	}
457
 o(idTa).focus();
458
}
459
 
460
function insHTML(html) { // SHORTER!!! insert HTML at current selection
461
 if (!html) html = prompt("Enter some HTML or text to insert:", "");
462
 if (html.indexOf('js:') == 0) {
463
  try{eval(html.replace(/^js:/,''))} catch(e){};
464
  return;
465
 }
466
 try {
467
  oW.document.execCommand("inserthtml", false, html + sel);
468
 }
469
 catch (e) {
470
  if (document.selection) {
471
   rng.select(); //else IE gets lost
472
   html = html + rng.htmlText;
473
   try { oW.document.selection.createRange().pasteHTML(html); } //
474
   catch (e) { }// catch error if range is bad
475
  }
476
 }
477
}
478
 
479
function whereAmI(evt) {//get current selected range if available REWRITE 060821
480
 oW.focus();
481
 if (oW.getSelection) { //Moz
482
  sel = oW.getSelection();
483
  if (sel) rng = sel.getRangeAt(sel.rangeCount - 1).cloneRange();
484
  papa = (evt && evt.type=='mouseup') ? evt.target : sel.anchorNode;
485
 } else { //IE
486
  sel = oW.document.selection;
487
  rng = sel.createRange();
488
  switch (sel.type) {
489
   case "Text":case "None":
490
    papa = rng.parentElement(); break;
491
   case "Control":
492
    papa = rng.item(0); break;
493
   default:
494
    papa = oW.document.body;
495
  }
496
 }
497
 var paNode = papa;
498
 trail = papa.nodeName;
499
 while (!paNode.nodeName.match(/^(HTML|BODY)/)) {
500
  paNode = paNode.parentNode;
501
  trail = paNode.nodeName + '>' + trail;
502
 }
503
 window.status = trail;
504
}
505
 
506
function textSel() {
507
	if (sel != "" && sel.type != "None") return true;
508
	else {alert(t("Select some text first")); return false;}
509
}
510
function s(id) {o(id).style.display = 'block';} //show element
511
function h(id) {o(id).style.display = 'none';} //hide element
512
function o(id) { return document.getElementById(id); } //get element by ID
513
function w(str) { return document.write(str); } //document write
514
function t(key) {return (window.language && language[key]) ? language[key] :  key;} //translation