4 * Developped by Christophe Dolivet
\r
5 * Released under LGPL, Apache and BSD licenses (use the one you want)
\r
9 function EditAreaLoader(){
\r
11 t.version= "0.8.1.1";
\r
13 t.start_time=date.getTime();
\r
14 t.win= "loading"; // window loading state
\r
15 t.error= false; // to know if load is interrrupt
\r
19 t.lang= {}; // array of loaded speech language
\r
20 t.load_syntax= {}; // array of loaded syntax language for highlight mode
\r
21 t.syntax= {}; // array of initilized syntax language for highlight mode
\r
23 t.waiting_loading= {}; // files that must be loaded in order to allow the script to really start
\r
24 // scripts that must be loaded in the iframe
\r
25 t.scripts_to_load= ["elements_functions", "resize_area", "reg_syntax"];
\r
26 t.sub_scripts_to_load= ["edit_area", "manage_area" ,"edit_area_functions", "keyboard", "search_replace", "highlight", "regexp"];
\r
28 t.resize= []; // contain resizing datas
\r
29 t.hidden= {}; // store datas of the hidden textareas
\r
31 t.default_settings= {
\r
32 //id: "src" // id of the textarea to transform
\r
34 ,smooth_selection: true
\r
35 ,font_size: "10" // not for IE
\r
36 ,font_family: "monospace" // can be "verdana,monospace". Allow non monospace font but Firefox get smaller tabulation with non monospace fonts. IE doesn't change the tabulation width and Opera doesn't take this option into account...
\r
37 ,start_highlight: false // if start with highlight
\r
38 ,toolbar: "search, go_to_line, fullscreen, |, undo, redo, |, select_font,|, change_smooth_selection, highlight, reset_highlight, word_wrap, |, help"
\r
39 ,begin_toolbar: "" // "new_document, save, load, |"
\r
40 ,end_toolbar: "" // or end_toolbar
\r
41 ,is_multi_files: false // enable the multi file mode (the textarea content is ignored)
\r
42 ,allow_resize: "both" // possible values: "no", "both", "x", "y"
\r
43 ,show_line_colors: false // if the highlight is disabled for the line currently beeing edited (if enabled => heavy CPU use)
\r
46 ,replace_tab_by_spaces: false
\r
47 ,allow_toggle: true // true or false
\r
50 ,syntax_selection_allow: "basic,brainfuck,c,coldfusion,cpp,css,html,java,js,pas,perl,php,python,ruby,robotstxt,sql,tsql,vb,xml"
\r
51 ,display: "onload" // onload or later
\r
53 ,browsers: "known" // all or known
\r
54 ,plugins: "" // comma separated plugin list
\r
55 ,gecko_spellcheck: false // enable/disable by default the gecko_spellcheck
\r
58 ,cursor_position: "begin"
\r
59 ,word_wrap: false // define if the text is wrapped of not in the textarea
\r
60 ,autocompletion: false // NOT IMPLEMENTED
\r
61 ,load_callback: "" // click on load button (function name)
\r
62 ,save_callback: "" // click on save button (function name)
\r
63 ,change_callback: "" // textarea onchange trigger (function name)
\r
64 ,submit_callback: "" // form submited (function name)
\r
65 ,EA_init_callback: "" // EditArea initiliazed (function name)
\r
66 ,EA_delete_callback: "" // EditArea deleted (function name)
\r
67 ,EA_load_callback: "" // EditArea fully loaded and displayed (function name)
\r
68 ,EA_unload_callback: "" // EditArea delete while being displayed (function name)
\r
69 ,EA_toggle_on_callback: "" // EditArea toggled on (function name)
\r
70 ,EA_toggle_off_callback: "" // EditArea toggled off (function name)
\r
71 ,EA_file_switch_on_callback: "" // a new tab is selected (called for the newly selected file)
\r
72 ,EA_file_switch_off_callback: "" // a new tab is selected (called for the previously selected file)
\r
73 ,EA_file_close_callback: "" // close a tab
\r
76 t.advanced_buttons = [
\r
77 // id, button img, command (it will try to find the translation of "id"), is_file_specific
\r
78 ['new_document', 'newdocument.gif', 'new_document', false],
\r
79 ['search', 'search.gif', 'show_search', false],
\r
80 ['go_to_line', 'go_to_line.gif', 'go_to_line', false],
\r
81 ['undo', 'undo.gif', 'undo', true],
\r
82 ['redo', 'redo.gif', 'redo', true],
\r
83 ['change_smooth_selection', 'smooth_selection.gif', 'change_smooth_selection_mode', true],
\r
84 ['reset_highlight', 'reset_highlight.gif', 'resync_highlight', true],
\r
85 ['highlight', 'highlight.gif','change_highlight', true],
\r
86 ['help', 'help.gif', 'show_help', false],
\r
87 ['save', 'save.gif', 'save', false],
\r
88 ['load', 'load.gif', 'load', false],
\r
89 ['fullscreen', 'fullscreen.gif', 'toggle_full_screen', false],
\r
90 ['word_wrap', 'word_wrap.gif', 'toggle_word_wrap', true],
\r
91 ['autocompletion', 'autocompletion.gif', 'toggle_autocompletion', true]
\r
94 // navigator identification
\r
95 t.set_browser_infos(t);
\r
97 if(t.isIE>=6 || t.isGecko || ( t.isWebKit && !t.isSafari<3 ) || t.isOpera>=9 || t.isCamino )
\r
98 t.isValidBrowser=true;
\r
100 t.isValidBrowser=false;
\r
104 for(var i=0; i<t.scripts_to_load.length; i++){
\r
105 setTimeout("editAreaLoader.load_script('"+t.baseURL + t.scripts_to_load[i]+ ".js');", 1); // let the time to Object editAreaLoader to be created before loading additionnal scripts
\r
106 t.waiting_loading[t.scripts_to_load[i]+ ".js"]= false;
\r
108 t.add_event(window, "load", EditAreaLoader.prototype.window_loaded);
\r
111 EditAreaLoader.prototype ={
\r
112 has_error : function(){
\r
114 // set to empty all EditAreaLoader functions
\r
115 for(var i in EditAreaLoader.prototype){
\r
116 EditAreaLoader.prototype[i]=function(){};
\r
120 // add browser informations to the object passed in parameter
\r
121 set_browser_infos : function(o){
\r
122 ua= navigator.userAgent;
\r
124 // general detection
\r
125 o.isWebKit = /WebKit/.test(ua);
\r
126 o.isGecko = !o.isWebKit && /Gecko/.test(ua);
\r
127 o.isMac = /Mac/.test(ua);
\r
129 o.isIE = (navigator.appName == "Microsoft Internet Explorer");
\r
131 o.isIE = ua.replace(/^.*?MSIE\s+([0-9\.]+).*$/, "$1");
\r
136 if(o.isOpera = (ua.indexOf('Opera') != -1)){
\r
137 o.isOpera= ua.replace(/^.*?Opera.*?([0-9\.]+).*$/i, "$1");
\r
143 if(o.isFirefox =(ua.indexOf('Firefox') != -1))
\r
144 o.isFirefox = ua.replace(/^.*?Firefox.*?([0-9\.]+).*$/i, "$1");
\r
146 if( ua.indexOf('Iceweasel') != -1 )
\r
147 o.isFirefox = ua.replace(/^.*?Iceweasel.*?([0-9\.]+).*$/i, "$1");
\r
148 if( ua.indexOf('GranParadiso') != -1 )
\r
149 o.isFirefox = ua.replace(/^.*?GranParadiso.*?([0-9\.]+).*$/i, "$1");
\r
150 if( ua.indexOf('BonEcho') != -1 )
\r
151 o.isFirefox = ua.replace(/^.*?BonEcho.*?([0-9\.]+).*$/i, "$1");
\r
152 if( ua.indexOf('SeaMonkey') != -1)
\r
153 o.isFirefox = (ua.replace(/^.*?SeaMonkey.*?([0-9\.]+).*$/i, "$1") ) + 1;
\r
155 if(o.isCamino =(ua.indexOf('Camino') != -1))
\r
156 o.isCamino = ua.replace(/^.*?Camino.*?([0-9\.]+).*$/i, "$1");
\r
158 if(o.isSafari =(ua.indexOf('Safari') != -1))
\r
159 o.isSafari= ua.replace(/^.*?Version\/([0-9]+\.[0-9]+).*$/i, "$1");
\r
161 if(o.isChrome =(ua.indexOf('Chrome') != -1)) {
\r
162 o.isChrome = ua.replace(/^.*?Chrome.*?([0-9\.]+).*$/i, "$1");
\r
163 o.isSafari = false;
\r
168 window_loaded : function(){
\r
169 editAreaLoader.win="loaded";
\r
171 // add events on forms
\r
172 if (document.forms) {
\r
173 for (var i=0; i<document.forms.length; i++) {
\r
174 var form = document.forms[i];
\r
175 form.edit_area_replaced_submit=null;
\r
178 form.edit_area_replaced_submit = form.onsubmit;
\r
180 } catch (e) {// Do nothing
\r
182 editAreaLoader.add_event(form, "submit", EditAreaLoader.prototype.submit);
\r
183 editAreaLoader.add_event(form, "reset", EditAreaLoader.prototype.reset);
\r
186 editAreaLoader.add_event(window, "unload", function(){for(var i in editAreas){editAreaLoader.delete_instance(i);}}); // ini callback
\r
189 // init the checkup of the selection of the IE textarea
\r
190 init_ie_textarea : function(id){
\r
191 var a=document.getElementById(id);
\r
193 if(a && typeof(a.focused)=="undefined"){
\r
196 a.selectionStart= a.selectionEnd= 0;
\r
197 get_IE_selection(a);
\r
198 editAreaLoader.add_event(a, "focus", IE_textarea_focus);
\r
199 editAreaLoader.add_event(a, "blur", IE_textarea_blur);
\r
205 init : function(settings){
\r
206 var t=this,s=settings,i;
\r
212 // if an instance of the editor already exists for this textarea => delete the previous one
\r
213 if(editAreas[s["id"]])
\r
214 t.delete_instance(s["id"]);
\r
217 for(i in t.default_settings){
\r
218 if(typeof(s[i])=="undefined")
\r
219 s[i]=t.default_settings[i];
\r
222 if(s["browsers"]=="known" && t.isValidBrowser==false){
\r
226 if(s["begin_toolbar"].length>0)
\r
227 s["toolbar"]= s["begin_toolbar"] +","+ s["toolbar"];
\r
228 if(s["end_toolbar"].length>0)
\r
229 s["toolbar"]= s["toolbar"] +","+ s["end_toolbar"];
\r
230 s["tab_toolbar"]= s["toolbar"].replace(/ /g,"").split(",");
\r
232 s["plugins"]= s["plugins"].replace(/ /g,"").split(",");
\r
233 for(i=0; i<s["plugins"].length; i++){
\r
234 if(s["plugins"][i].length==0)
\r
235 s["plugins"].splice(i,1);
\r
237 // alert(settings["plugins"].length+": "+ settings["plugins"].join(","));
\r
239 t.load_script(t.baseURL + "langs/"+ s["language"] + ".js");
\r
241 if(s["syntax"].length>0){
\r
242 s["syntax"]=s["syntax"].toLowerCase();
\r
243 t.load_script(t.baseURL + "reg_syntax/"+ s["syntax"] + ".js");
\r
245 //alert(this.template);
\r
247 editAreas[s["id"]]= {"settings": s};
\r
248 editAreas[s["id"]]["displayed"]=false;
\r
249 editAreas[s["id"]]["hidden"]=false;
\r
251 //if(settings["display"]=="onload")
\r
255 // delete an instance of an EditArea
\r
256 delete_instance : function(id){
\r
257 var d=document,fs=window.frames,span,iframe;
\r
258 editAreaLoader.execCommand(id, "EA_delete");
\r
259 if(fs["frame_"+id] && fs["frame_"+id].editArea)
\r
261 if(editAreas[id]["displayed"])
\r
262 editAreaLoader.toggle(id, "off");
\r
263 fs["frame_"+id].editArea.execCommand("EA_unload");
\r
266 // remove toggle infos and debug textarea
\r
267 span= d.getElementById("EditAreaArroundInfos_"+id);
\r
269 span.parentNode.removeChild(span);
\r
271 // remove the iframe
\r
272 iframe= d.getElementById("frame_"+id);
\r
274 iframe.parentNode.removeChild(iframe);
\r
277 delete fs["frame_"+id];
\r
278 } catch (e) {// Do nothing
\r
282 delete editAreas[id];
\r
286 start : function(id){
\r
287 var t=this,d=document,f,span,father,next,html='',html_toolbar_content='',template,content,i;
\r
289 // check that the window is loaded
\r
290 if(t.win!="loaded"){
\r
291 setTimeout("editAreaLoader.start('"+id+"');", 50);
\r
295 // check that all needed scripts are loaded
\r
296 for( i in t.waiting_loading){
\r
297 if(t.waiting_loading[i]!="loaded" && typeof(t.waiting_loading[i])!="function"){
\r
298 setTimeout("editAreaLoader.start('"+id+"');", 50);
\r
303 // wait until language and syntax files are loaded
\r
304 if(!t.lang[editAreas[id]["settings"]["language"]] || (editAreas[id]["settings"]["syntax"].length>0 && !t.load_syntax[editAreas[id]["settings"]["syntax"]]) ){
\r
305 setTimeout("editAreaLoader.start('"+id+"');", 50);
\r
308 // init the regexp for syntax highlight
\r
309 if(editAreas[id]["settings"]["syntax"].length>0)
\r
310 t.init_syntax_regexp();
\r
313 // display toggle option and debug area
\r
314 if(!d.getElementById("EditAreaArroundInfos_"+id) && (editAreas[id]["settings"]["debug"] || editAreas[id]["settings"]["allow_toggle"]))
\r
316 span= d.createElement("span");
\r
317 span.id= "EditAreaArroundInfos_"+id;
\r
318 if(editAreas[id]["settings"]["allow_toggle"]){
\r
319 checked=(editAreas[id]["settings"]["display"]=="onload")?"checked='checked'":"";
\r
320 html+="<div id='edit_area_toggle_"+i+"'>";
\r
321 html+="<input id='edit_area_toggle_checkbox_"+ id +"' class='toggle_"+ id +"' type='checkbox' onclick='editAreaLoader.toggle(\""+ id +"\");' accesskey='e' "+checked+" />";
\r
322 html+="<label for='edit_area_toggle_checkbox_"+ id +"'>{$toggle}</label></div>";
\r
324 if(editAreas[id]["settings"]["debug"])
\r
325 html+="<textarea id='edit_area_debug_"+ id +"' spellcheck='off' style='z-index: 20; width: 100%; height: 120px;overflow: auto; border: solid black 1px;'></textarea><br />";
\r
326 html= t.translate(html, editAreas[id]["settings"]["language"]);
\r
327 span.innerHTML= html;
\r
328 father= d.getElementById(id).parentNode;
\r
329 next= d.getElementById(id).nextSibling;
\r
331 father.appendChild(span);
\r
333 father.insertBefore(span, next);
\r
336 if(!editAreas[id]["initialized"])
\r
338 t.execCommand(id, "EA_init"); // ini callback
\r
339 if(editAreas[id]["settings"]["display"]=="later"){
\r
340 editAreas[id]["initialized"]= true;
\r
345 if(t.isIE){ // launch IE selection checkup
\r
346 t.init_ie_textarea(id);
\r
349 // get toolbar content
\r
350 area=editAreas[id];
\r
352 for(i=0; i<area["settings"]["tab_toolbar"].length; i++){
\r
353 // alert(this.tab_toolbar[i]+"\n"+ this.get_control_html(this.tab_toolbar[i]));
\r
354 html_toolbar_content+= t.get_control_html(area["settings"]["tab_toolbar"][i], area["settings"]["language"]);
\r
356 // translate toolbar text here for chrome 2
\r
357 html_toolbar_content = t.translate(html_toolbar_content, area["settings"]["language"], "template");
\r
360 // create javascript import rules for the iframe if the javascript has not been already loaded by the compressor
\r
361 if(!t.iframe_script){
\r
362 t.iframe_script="";
\r
363 for(i=0; i<t.sub_scripts_to_load.length; i++)
\r
364 t.iframe_script+='<script language="javascript" type="text/javascript" src="'+ t.baseURL + t.sub_scripts_to_load[i] +'.js"></script>';
\r
367 // add plugins scripts if not already loaded by the compressor (but need to load language in all the case)
\r
368 for(i=0; i<area["settings"]["plugins"].length; i++){
\r
369 //if(typeof(area["settings"]["plugins"][i])=="function") continue;
\r
370 if(!t.all_plugins_loaded)
\r
371 t.iframe_script+='<script language="javascript" type="text/javascript" src="'+ t.baseURL + 'plugins/' + area["settings"]["plugins"][i] + '/' + area["settings"]["plugins"][i] +'.js"></script>';
\r
372 t.iframe_script+='<script language="javascript" type="text/javascript" src="'+ t.baseURL + 'plugins/' + area["settings"]["plugins"][i] + '/langs/' + area["settings"]["language"] +'.js"></script>';
\r
376 // create css link for the iframe if the whole css text has not been already loaded by the compressor
\r
378 t.iframe_css="<link href='"+ t.baseURL +"edit_area.css' rel='stylesheet' type='text/css' />";
\r
383 template= t.template.replace(/\[__BASEURL__\]/g, t.baseURL);
\r
384 template= template.replace("[__TOOLBAR__]",html_toolbar_content);
\r
387 // fill template with good language sentences
\r
388 template= t.translate(template, area["settings"]["language"], "template");
\r
391 template= template.replace("[__CSSRULES__]", t.iframe_css);
\r
393 template= template.replace("[__JSCODE__]", t.iframe_script);
\r
395 // add version_code
\r
396 template= template.replace("[__EA_VERSION__]", t.version);
\r
397 //template=template.replace(/\{\$([^\}]+)\}/gm, this.traduc_template);
\r
399 //editAreas[area["settings"]["id"]]["template"]= template;
\r
401 area.textarea=d.getElementById(area["settings"]["id"]);
\r
402 editAreas[area["settings"]["id"]]["textarea"]=area.textarea;
\r
404 // if removing previous instances from DOM before (fix from Marcin)
\r
405 if(typeof(window.frames["frame_"+area["settings"]["id"]])!='undefined')
\r
406 delete window.frames["frame_"+area["settings"]["id"]];
\r
408 // insert template in the document after the textarea
\r
409 father= area.textarea.parentNode;
\r
410 /* var container= document.createElement("div");
\r
411 container.id= "EditArea_frame_container_"+area["settings"]["id"];
\r
413 content= d.createElement("iframe");
\r
414 content.name= "frame_"+area["settings"]["id"];
\r
415 content.id= "frame_"+area["settings"]["id"];
\r
416 content.style.borderWidth= "0px";
\r
417 setAttribute(content, "frameBorder", "0"); // IE
\r
418 content.style.overflow="hidden";
\r
419 content.style.display="none";
\r
422 next= area.textarea.nextSibling;
\r
424 father.appendChild(content);
\r
426 father.insertBefore(content, next) ;
\r
427 f=window.frames["frame_"+area["settings"]["id"]];
\r
429 f.editAreas=editAreas;
\r
430 f.area_id= area["settings"]["id"];
\r
431 f.document.area_id= area["settings"]["id"];
\r
432 f.document.write(template);
\r
433 f.document.close();
\r
435 // frame.editAreaLoader=this;
\r
436 //editAreas[area["settings"]["id"]]["displayed"]=true;
\r
440 toggle : function(id, toggle_to){
\r
442 /* if((editAreas[id]["displayed"]==true && toggle_to!="on") || toggle_to=="off"){
\r
443 this.toggle_off(id);
\r
444 }else if((editAreas[id]["displayed"]==false && toggle_to!="off") || toggle_to=="on"){
\r
445 this.toggle_on(id);
\r
448 toggle_to= (editAreas[id]["displayed"]==true)?"off":"on";
\r
449 if(editAreas[id]["displayed"]==true && toggle_to=="off"){
\r
450 this.toggle_off(id);
\r
451 }else if(editAreas[id]["displayed"]==false && toggle_to=="on"){
\r
452 this.toggle_on(id);
\r
459 toggle_off : function(id){
\r
460 var fs=window.frames,f,t,parNod,nxtSib,selStart,selEnd,scrollTop,scrollLeft;
\r
461 if(fs["frame_"+id])
\r
463 f = fs["frame_"+id];
\r
464 t = editAreas[id]["textarea"];
\r
465 if(f.editArea.fullscreen['isFull'])
\r
466 f.editArea.toggle_full_screen(false);
\r
467 editAreas[id]["displayed"]=false;
\r
469 // set wrap to off to keep same display mode (some browser get problem with this, so it need more complex operation
\r
470 t.wrap = "off"; // for IE
\r
471 setAttribute(t, "wrap", "off"); // for Firefox
\r
472 parNod = t.parentNode;
\r
473 nxtSib = t.nextSibling;
\r
474 parNod.removeChild(t);
\r
475 parNod.insertBefore(t, nxtSib);
\r
478 t.value= f.editArea.textarea.value;
\r
479 selStart = f.editArea.last_selection["selectionStart"];
\r
480 selEnd = f.editArea.last_selection["selectionEnd"];
\r
481 scrollTop = f.document.getElementById("result").scrollTop;
\r
482 scrollLeft = f.document.getElementById("result").scrollLeft;
\r
485 document.getElementById("frame_"+id).style.display='none';
\r
487 t.style.display="inline";
\r
489 try{ // IE will give an error when trying to focus an invisible or disabled textarea
\r
493 t.selectionStart= selStart;
\r
494 t.selectionEnd = selEnd;
\r
496 set_IE_selection(t);
\r
498 if(this.isOpera && this.isOpera < 9.6 ){ // Opera bug when moving selection start and selection end
\r
499 t.setSelectionRange(0, 0);
\r
502 t.setSelectionRange(selStart, selEnd);
\r
505 t.scrollTop= scrollTop;
\r
506 t.scrollLeft= scrollLeft;
\r
507 f.editArea.execCommand("toggle_off");
\r
513 toggle_on : function(id){
\r
514 var fs=window.frames,f,t,selStart=0,selEnd=0,scrollTop=0,scrollLeft=0,curPos,elem;
\r
516 if(fs["frame_"+id])
\r
518 f = fs["frame_"+id];
\r
519 t = editAreas[id]["textarea"];
\r
521 area.textarea.value= t.value;
\r
523 // store display values;
\r
524 curPos = editAreas[id]["settings"]["cursor_position"];
\r
526 if(t.use_last==true)
\r
528 selStart = t.last_selectionStart;
\r
529 selEnd = t.last_selectionEnd;
\r
530 scrollTop = t.last_scrollTop;
\r
531 scrollLeft = t.last_scrollLeft;
\r
534 else if( curPos == "auto" )
\r
537 selStart = t.selectionStart;
\r
538 selEnd = t.selectionEnd;
\r
539 scrollTop = t.scrollTop;
\r
540 scrollLeft = t.scrollLeft;
\r
541 //alert(scrollTop);
\r
545 // set to good size
\r
546 this.set_editarea_size_from_textarea(id, document.getElementById("frame_"+id));
\r
547 t.style.display="none";
\r
548 document.getElementById("frame_"+id).style.display="inline";
\r
549 area.execCommand("focus"); // without this focus opera doesn't manage well the iframe body height
\r
552 // restore display values
\r
553 editAreas[id]["displayed"]=true;
\r
554 area.execCommand("update_size");
\r
556 f.document.getElementById("result").scrollTop= scrollTop;
\r
557 f.document.getElementById("result").scrollLeft= scrollLeft;
\r
558 area.area_select(selStart, selEnd-selStart);
\r
559 area.execCommand("toggle_on");
\r
566 get_IE_selection(document.getElementById(id)); */
\r
567 elem= document.getElementById(id);
\r
568 elem.last_selectionStart= elem.selectionStart;
\r
569 elem.last_selectionEnd= elem.selectionEnd;
\r
570 elem.last_scrollTop= elem.scrollTop;
\r
571 elem.last_scrollLeft= elem.scrollLeft;
\r
572 elem.use_last=true;
\r
573 editAreaLoader.start(id);
\r
577 set_editarea_size_from_textarea : function(id, frame){
\r
578 var elem,width,height;
\r
579 elem = document.getElementById(id);
\r
581 width = Math.max(editAreas[id]["settings"]["min_width"], elem.offsetWidth)+"px";
\r
582 height = Math.max(editAreas[id]["settings"]["min_height"], elem.offsetHeight)+"px";
\r
583 if(elem.style.width.indexOf("%")!=-1)
\r
584 width = elem.style.width;
\r
585 if(elem.style.height.indexOf("%")!=-1)
\r
586 height = elem.style.height;
\r
587 //alert("h: "+height+" w: "+width);
\r
589 frame.style.width= width;
\r
590 frame.style.height= height;
\r
593 set_base_url : function(){
\r
594 var t=this,elems,i,docBasePath;
\r
596 if( !this.baseURL ){
\r
597 elems = document.getElementsByTagName('script');
\r
599 for( i=0; i<elems.length; i++ ){
\r
600 if (elems[i].src && elems[i].src.match(/edit_area_[^\\\/]*$/i) ) {
\r
601 var src = elems[i].src;
\r
602 src = src.substring(0, src.lastIndexOf('/'));
\r
603 this.baseURL = src;
\r
604 this.file_name= elems[i].src.substr(elems[i].src.lastIndexOf("/")+1);
\r
610 docBasePath = document.location.href;
\r
611 if (docBasePath.indexOf('?') != -1)
\r
612 docBasePath = docBasePath.substring(0, docBasePath.indexOf('?'));
\r
613 docBasePath = docBasePath.substring(0, docBasePath.lastIndexOf('/'));
\r
615 // If not HTTP absolute
\r
616 if (t.baseURL.indexOf('://') == -1 && t.baseURL.charAt(0) != '/') {
\r
617 // If site absolute
\r
618 t.baseURL = docBasePath + "/" + t.baseURL;
\r
623 get_button_html : function(id, img, exec, isFileSpecific, baseURL) {
\r
626 baseURL= this.baseURL;
\r
627 cmd = 'editArea.execCommand(\'' + exec + '\')';
\r
628 html = '<a id="a_'+ id +'" href="javascript:' + cmd + '" onclick="' + cmd + ';return false;" onmousedown="return false;" target="_self" fileSpecific="'+ (isFileSpecific?'yes':'no') +'">';
\r
629 html += '<img id="' + id + '" src="'+ baseURL +'images/' + img + '" title="{$' + id + '}" width="20" height="20" class="editAreaButtonNormal" onmouseover="editArea.switchClass(this,\'editAreaButtonOver\');" onmouseout="editArea.restoreClass(this);" onmousedown="editArea.restoreAndSwitchClass(this,\'editAreaButtonDown\');" /></a>';
\r
633 get_control_html : function(button_name, lang) {
\r
634 var t=this,i,but,html,si;
\r
635 for (i=0; i<t.advanced_buttons.length; i++)
\r
637 but = t.advanced_buttons[i];
\r
638 if (but[0] == button_name)
\r
640 return t.get_button_html(but[0], but[1], but[2], but[3]);
\r
644 switch (button_name){
\r
650 return '<img src="'+ t.baseURL +'images/spacer.gif" width="1" height="15" class="editAreaSeparatorLine">';
\r
651 case "select_font":
\r
652 html= "<select id='area_font_size' onchange='javascript:editArea.execCommand(\"change_font_size\")' fileSpecific='yes'>";
\r
653 html+="<option value='-1'>{$font_size}</option>";
\r
654 si=[8,9,10,11,12,14];
\r
655 for( i=0;i<si.length;i++){
\r
656 html+="<option value='"+si[i]+"'>"+si[i]+" pt</option>";
\r
660 case "syntax_selection":
\r
661 html= "<select id='syntax_selection' onchange='javascript:editArea.execCommand(\"change_syntax\", this.value)' fileSpecific='yes'>";
\r
662 html+="<option value='-1'>{$syntax_selection}</option>";
\r
667 return "<span id='tmp_tool_"+button_name+"'>["+button_name+"]</span>";
\r
671 get_template : function(){
\r
672 if(this.template=="")
\r
674 var xhr_object = null;
\r
675 if(window.XMLHttpRequest) // Firefox
\r
676 xhr_object = new XMLHttpRequest();
\r
677 else if(window.ActiveXObject) // Internet Explorer
\r
678 xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
\r
679 else { // XMLHttpRequest not supported
\r
680 alert("XMLHTTPRequest not supported. EditArea not loaded");
\r
684 xhr_object.open("GET", this.baseURL+"template.html", false);
\r
685 xhr_object.send(null);
\r
686 if(xhr_object.readyState == 4)
\r
687 this.template=xhr_object.responseText;
\r
694 translate : function(text, lang, mode){
\r
696 text=editAreaLoader.get_word_translation(text, lang);
\r
697 else if(mode="template"){
\r
698 editAreaLoader.current_language= lang;
\r
699 text=text.replace(/\{\$([^\}]+)\}/gm, editAreaLoader.translate_template);
\r
704 translate_template : function(){
\r
705 return editAreaLoader.get_word_translation(EditAreaLoader.prototype.translate_template.arguments[1], editAreaLoader.current_language);
\r
708 get_word_translation : function(val, lang){
\r
711 for( i in editAreaLoader.lang[lang]){
\r
713 return editAreaLoader.lang[lang][i];
\r
718 load_script : function(url){
\r
719 var t=this,d=document,script,head;
\r
721 if( t.loadedFiles[url] )
\r
723 //alert("load: "+url);
\r
725 script= d.createElement("script");
\r
726 script.type= "text/javascript";
\r
728 script.charset= "UTF-8";
\r
729 d.getElementsByTagName("head")[0].appendChild(script);
\r
731 d.write('<sc'+'ript language="javascript" type="text/javascript" src="' + url + '" charset="UTF-8"></sc'+'ript>');
\r
734 t.loadedFiles[url] = true;
\r
737 add_event : function(obj, name, handler) {
\r
739 if (obj.attachEvent) {
\r
740 obj.attachEvent("on" + name, handler);
\r
742 obj.addEventListener(name, handler, false);
\r
747 remove_event : function(obj, name, handler){
\r
749 if (obj.detachEvent)
\r
750 obj.detachEvent("on" + name, handler);
\r
752 obj.removeEventListener(name, handler, false);
\r
757 // reset all the editareas in the form that have been reseted
\r
758 reset : function(e){
\r
759 var formObj,is_child,i,x;
\r
761 formObj = editAreaLoader.isIE ? window.event.srcElement : e.target;
\r
762 if(formObj.tagName!='FORM')
\r
763 formObj= formObj.form;
\r
765 for( i in editAreas ){
\r
767 for( x=0;x<formObj.elements.length;x++ ) {
\r
768 if(formObj.elements[x].id == i)
\r
772 if(window.frames["frame_"+i] && is_child && editAreas[i]["displayed"]==true){
\r
774 var exec= 'window.frames["frame_'+ i +'"].editArea.textarea.value= document.getElementById("'+ i +'").value;';
\r
775 exec+= 'window.frames["frame_'+ i +'"].editArea.execCommand("focus");';
\r
776 exec+= 'window.frames["frame_'+ i +'"].editArea.check_line_selection();';
\r
777 exec+= 'window.frames["frame_'+ i +'"].editArea.execCommand("reset");';
\r
778 window.setTimeout(exec, 10);
\r
785 // prepare all the textarea replaced by an editarea to be submited
\r
786 submit : function(e){
\r
787 var formObj,is_child,fs=window.frames,i,x;
\r
788 formObj = editAreaLoader.isIE ? window.event.srcElement : e.target;
\r
789 if(formObj.tagName!='FORM')
\r
790 formObj= formObj.form;
\r
792 for( i in editAreas){
\r
794 for( x=0;x<formObj.elements.length;x++ ) {
\r
795 if(formObj.elements[x].id == i)
\r
801 if(fs["frame_"+i] && editAreas[i]["displayed"]==true)
\r
802 document.getElementById(i).value= fs["frame_"+ i].editArea.textarea.value;
\r
803 editAreaLoader.execCommand(i,"EA_submit");
\r
806 if( typeof(formObj.edit_area_replaced_submit) == "function" ){
\r
807 res= formObj.edit_area_replaced_submit();
\r
809 if(editAreaLoader.isIE)
\r
812 e.preventDefault();
\r
818 // allow to get the value of the editarea
\r
819 getValue : function(id){
\r
820 if(window.frames["frame_"+id] && editAreas[id]["displayed"]==true){
\r
821 return window.frames["frame_"+ id].editArea.textarea.value;
\r
822 }else if(elem=document.getElementById(id)){
\r
828 // allow to set the value of the editarea
\r
829 setValue : function(id, new_val){
\r
830 var fs=window.frames;
\r
832 if( ( f=fs["frame_"+id] ) && editAreas[id]["displayed"]==true){
\r
833 f.editArea.textarea.value= new_val;
\r
834 f.editArea.execCommand("focus");
\r
835 f.editArea.check_line_selection(false);
\r
836 f.editArea.execCommand("onchange");
\r
837 }else if(elem=document.getElementById(id)){
\r
838 elem.value= new_val;
\r
842 // allow to get infos on the selection: array(start, end)
\r
843 getSelectionRange : function(id){
\r
844 var sel,eA,fs=window.frames;
\r
846 sel= {"start": 0, "end": 0};
\r
847 if(fs["frame_"+id] && editAreas[id]["displayed"]==true){
\r
848 eA= fs["frame_"+ id].editArea;
\r
850 sel["start"] = eA.textarea.selectionStart;
\r
851 sel["end"] = eA.textarea.selectionEnd;
\r
853 }else if( elem=document.getElementById(id) ){
\r
854 sel= getSelectionRange(elem);
\r
859 // allow to set the selection with the given start and end positions
\r
860 setSelectionRange : function(id, new_start, new_end){
\r
861 var fs=window.frames;
\r
863 if(fs["frame_"+id] && editAreas[id]["displayed"]==true){
\r
864 fs["frame_"+ id].editArea.area_select(new_start, new_end-new_start);
\r
865 // make an auto-scroll to the selection
\r
867 fs["frame_"+ id].editArea.check_line_selection(false);
\r
868 fs["frame_"+ id].editArea.scroll_to_view();
\r
870 }else if(elem=document.getElementById(id)){
\r
871 setSelectionRange(elem, new_start, new_end);
\r
875 getSelectedText : function(id){
\r
876 var sel= this.getSelectionRange(id);
\r
878 return this.getValue(id).substring(sel["start"], sel["end"]);
\r
881 setSelectedText : function(id, new_val){
\r
882 var fs=window.frames,d=document,sel,text,scrollTop,scrollLeft,new_sel_end;
\r
884 new_val = new_val.replace(/\r/g, "");
\r
885 sel = this.getSelectionRange(id);
\r
886 text = this.getValue(id);
\r
887 if(fs["frame_"+id] && editAreas[id]["displayed"]==true){
\r
888 scrollTop = fs["frame_"+ id].document.getElementById("result").scrollTop;
\r
889 scrollLeft = fs["frame_"+ id].document.getElementById("result").scrollLeft;
\r
891 scrollTop = d.getElementById(id).scrollTop;
\r
892 scrollLeft = d.getElementById(id).scrollLeft;
\r
895 text = text.substring(0, sel["start"])+ new_val +text.substring(sel["end"]);
\r
896 this.setValue(id, text);
\r
897 new_sel_end = sel["start"]+ new_val.length;
\r
898 this.setSelectionRange(id, sel["start"], new_sel_end);
\r
901 // fix \r problem for selection length count on IE & Opera
\r
902 if(new_val != this.getSelectedText(id).replace(/\r/g, "")){
\r
903 this.setSelectionRange(id, sel["start"], new_sel_end+ new_val.split("\n").length -1);
\r
905 // restore scrolling position
\r
906 if(fs["frame_"+id] && editAreas[id]["displayed"]==true){
\r
907 fs["frame_"+ id].document.getElementById("result").scrollTop= scrollTop;
\r
908 fs["frame_"+ id].document.getElementById("result").scrollLeft= scrollLeft;
\r
909 fs["frame_"+ id].editArea.execCommand("onchange");
\r
911 d.getElementById(id).scrollTop= scrollTop;
\r
912 d.getElementById(id).scrollLeft= scrollLeft;
\r
916 insertTags : function(id, open_tag, close_tag){
\r
917 var old_sel,new_sel;
\r
919 old_sel = this.getSelectionRange(id);
\r
920 text = open_tag + this.getSelectedText(id) + close_tag;
\r
922 editAreaLoader.setSelectedText(id, text);
\r
924 new_sel = this.getSelectionRange(id);
\r
925 if(old_sel["end"] > old_sel["start"]) // if text was selected, cursor at the end
\r
926 this.setSelectionRange(id, new_sel["end"], new_sel["end"]);
\r
927 else // cursor in the middle
\r
928 this.setSelectionRange(id, old_sel["start"]+open_tag.length, old_sel["start"]+open_tag.length);
\r
931 // hide both EditArea and normal textarea
\r
932 hide : function(id){
\r
933 var fs= window.frames,d=document,t=this,scrollTop,scrollLeft,span;
\r
934 if(d.getElementById(id) && !t.hidden[id])
\r
937 t.hidden[id]["selectionRange"]= t.getSelectionRange(id);
\r
938 if(d.getElementById(id).style.display!="none")
\r
940 t.hidden[id]["scrollTop"]= d.getElementById(id).scrollTop;
\r
941 t.hidden[id]["scrollLeft"]= d.getElementById(id).scrollLeft;
\r
944 if(fs["frame_"+id])
\r
946 t.hidden[id]["toggle"]= editAreas[id]["displayed"];
\r
948 if(fs["frame_"+id] && editAreas[id]["displayed"]==true){
\r
949 scrollTop = fs["frame_"+ id].document.getElementById("result").scrollTop;
\r
950 scrollLeft = fs["frame_"+ id].document.getElementById("result").scrollLeft;
\r
952 scrollTop = d.getElementById(id).scrollTop;
\r
953 scrollLeft = d.getElementById(id).scrollLeft;
\r
955 t.hidden[id]["scrollTop"]= scrollTop;
\r
956 t.hidden[id]["scrollLeft"]= scrollLeft;
\r
958 if(editAreas[id]["displayed"]==true)
\r
959 editAreaLoader.toggle_off(id);
\r
962 // hide toggle button and debug box
\r
963 span= d.getElementById("EditAreaArroundInfos_"+id);
\r
965 span.style.display='none';
\r
969 d.getElementById(id).style.display= "none";
\r
973 // restore hidden EditArea and normal textarea
\r
974 show : function(id){
\r
975 var fs= window.frames,d=document,t=this,span;
\r
976 if((elem=d.getElementById(id)) && t.hidden[id])
\r
978 elem.style.display= "inline";
\r
979 elem.scrollTop= t.hidden[id]["scrollTop"];
\r
980 elem.scrollLeft= t.hidden[id]["scrollLeft"];
\r
981 span= d.getElementById("EditAreaArroundInfos_"+id);
\r
983 span.style.display='inline';
\r
986 if(fs["frame_"+id])
\r
989 // restore toggle button and debug box
\r
992 // restore textarea
\r
993 elem.style.display= "inline";
\r
995 // restore EditArea
\r
996 if(t.hidden[id]["toggle"]==true)
\r
997 editAreaLoader.toggle_on(id);
\r
999 scrollTop = t.hidden[id]["scrollTop"];
\r
1000 scrollLeft = t.hidden[id]["scrollLeft"];
\r
1002 if(fs["frame_"+id] && editAreas[id]["displayed"]==true){
\r
1003 fs["frame_"+ id].document.getElementById("result").scrollTop = scrollTop;
\r
1004 fs["frame_"+ id].document.getElementById("result").scrollLeft = scrollLeft;
\r
1006 elem.scrollTop = scrollTop;
\r
1007 elem.scrollLeft = scrollLeft;
\r
1011 // restore selection
\r
1012 sel = t.hidden[id]["selectionRange"];
\r
1013 t.setSelectionRange(id, sel["start"], sel["end"]);
\r
1014 delete t.hidden[id];
\r
1018 // get the current file datas (for multi file editing mode)
\r
1019 getCurrentFile : function(id){
\r
1020 return this.execCommand(id, 'get_file', this.execCommand(id, 'curr_file'));
\r
1023 // get the given file datas (for multi file editing mode)
\r
1024 getFile : function(id, file_id){
\r
1025 return this.execCommand(id, 'get_file', file_id);
\r
1028 // get all the openned files datas (for multi file editing mode)
\r
1029 getAllFiles : function(id){
\r
1030 return this.execCommand(id, 'get_all_files()');
\r
1033 // open a file (for multi file editing mode)
\r
1034 openFile : function(id, file_infos){
\r
1035 return this.execCommand(id, 'open_file', file_infos);
\r
1038 // close the given file (for multi file editing mode)
\r
1039 closeFile : function(id, file_id){
\r
1040 return this.execCommand(id, 'close_file', file_id);
\r
1043 // close the given file (for multi file editing mode)
\r
1044 setFileEditedMode : function(id, file_id, to){
\r
1046 reg1 = new RegExp('\\\\', 'g');
\r
1047 reg2 = new RegExp('"', 'g');
\r
1048 return this.execCommand(id, 'set_file_edited_mode("'+ file_id.replace(reg1, '\\\\').replace(reg2, '\\"') +'", '+ to +')');
\r
1052 // allow to access to editarea functions and datas (for advanced users only)
\r
1053 execCommand : function(id, cmd, fct_param){
\r
1056 if(editAreas[id]['settings']["EA_init_callback"].length>0)
\r
1057 eval(editAreas[id]['settings']["EA_init_callback"]+"('"+ id +"');");
\r
1060 if(editAreas[id]['settings']["EA_delete_callback"].length>0)
\r
1061 eval(editAreas[id]['settings']["EA_delete_callback"]+"('"+ id +"');");
\r
1064 if(editAreas[id]['settings']["submit_callback"].length>0)
\r
1065 eval(editAreas[id]['settings']["submit_callback"]+"('"+ id +"');");
\r
1068 if(window.frames["frame_"+id] && window.frames["frame_"+ id].editArea){
\r
1069 if(fct_param!=undefined)
\r
1070 return eval('window.frames["frame_'+ id +'"].editArea.'+ cmd +'(fct_param);');
\r
1072 return eval('window.frames["frame_'+ id +'"].editArea.'+ cmd +';');
\r
1078 var editAreaLoader= new EditAreaLoader();
\r
1079 var editAreas= {};
\r