Subversion-Projekte lars-tiefland.content-management

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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