source: trunk/plugins/LocalFilesEditor/editarea/edit_area_loader.js @ 5160

Last change on this file since 5160 was 5160, checked in by patdenice, 14 years ago

Editor
Update editarea to 0.8.2.
Remove CSS tab.
Fix jQuery path.

File size: 36.6 KB
Line 
1/******
2 *
3 *      EditArea
4 *      Developped by Christophe Dolivet
5 *      Released under LGPL, Apache and BSD licenses (use the one you want)
6 *
7******/
8
9function EditAreaLoader(){
10        var t=this;
11        t.version= "0.8.2";
12        date= new Date();
13        t.start_time=date.getTime();
14        t.win= "loading";       // window loading state
15        t.error= false; // to know if load is interrrupt
16        t.baseURL="";
17        //t.suffix="";
18        t.template="";
19        t.lang= {};     // array of loaded speech language
20        t.load_syntax= {};      // array of loaded syntax language for highlight mode
21        t.syntax= {};   // array of initilized syntax language for highlight mode
22        t.loadedFiles= [];
23        t.waiting_loading= {};  // files that must be loaded in order to allow the script to really start
24        // scripts that must be loaded in the iframe
25        t.scripts_to_load= ["elements_functions", "resize_area", "reg_syntax"];
26        t.sub_scripts_to_load= ["edit_area", "manage_area" ,"edit_area_functions", "keyboard", "search_replace", "highlight", "regexp"];
27        t.syntax_display_name= { /*syntax_display_name_AUTO-FILL-BY-COMPRESSOR*/ };
28       
29        t.resize= []; // contain resizing datas
30        t.hidden= {};   // store datas of the hidden textareas
31       
32        t.default_settings= {
33                //id: "src"     // id of the textarea to transform
34                debug: false
35                ,smooth_selection: true
36                ,font_size: "10"                // not for IE
37                ,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...
38                ,start_highlight: false // if start with highlight
39                ,toolbar: "search, go_to_line, fullscreen, |, undo, redo, |, select_font,|, change_smooth_selection, highlight, reset_highlight, word_wrap, |, help"
40                ,begin_toolbar: ""              //  "new_document, save, load, |"
41                ,end_toolbar: ""                // or end_toolbar
42                ,is_multi_files: false          // enable the multi file mode (the textarea content is ignored)
43                ,allow_resize: "both"   // possible values: "no", "both", "x", "y"
44                ,show_line_colors: false        // if the highlight is disabled for the line currently beeing edited (if enabled => heavy CPU use)
45                ,min_width: 400
46                ,min_height: 125
47                ,replace_tab_by_spaces: false
48                ,allow_toggle: true             // true or false
49                ,language: "en"
50                ,syntax: ""
51                ,syntax_selection_allow: "basic,brainfuck,c,coldfusion,cpp,css,html,java,js,pas,perl,php,python,ruby,robotstxt,sql,tsql,vb,xml"
52                ,display: "onload"              // onload or later
53                ,max_undo: 30
54                ,browsers: "known"      // all or known
55                ,plugins: "" // comma separated plugin list
56                ,gecko_spellcheck: false        // enable/disable by default the gecko_spellcheck
57                ,fullscreen: false
58                ,is_editable: true
59                ,cursor_position: "begin"
60                ,word_wrap: false               // define if the text is wrapped of not in the textarea
61                ,autocompletion: false  // NOT IMPLEMENTED                     
62                ,load_callback: ""              // click on load button (function name)
63                ,save_callback: ""              // click on save button (function name)
64                ,change_callback: ""    // textarea onchange trigger (function name)
65                ,submit_callback: ""    // form submited (function name)
66                ,EA_init_callback: ""   // EditArea initiliazed (function name)
67                ,EA_delete_callback: "" // EditArea deleted (function name)
68                ,EA_load_callback: ""   // EditArea fully loaded and displayed (function name)
69                ,EA_unload_callback: "" // EditArea delete while being displayed (function name)
70                ,EA_toggle_on_callback: ""      // EditArea toggled on (function name)
71                ,EA_toggle_off_callback: ""     // EditArea toggled off (function name)
72                ,EA_file_switch_on_callback: "" // a new tab is selected (called for the newly selected file)
73                ,EA_file_switch_off_callback: ""        // a new tab is selected (called for the previously selected file)
74                ,EA_file_close_callback: ""             // close a tab
75        };
76       
77        t.advanced_buttons = [
78                        // id, button img, command (it will try to find the translation of "id"), is_file_specific
79                        ['new_document', 'newdocument.gif', 'new_document', false],
80                        ['search', 'search.gif', 'show_search', false],
81                        ['go_to_line', 'go_to_line.gif', 'go_to_line', false],
82                        ['undo', 'undo.gif', 'undo', true],
83                        ['redo', 'redo.gif', 'redo', true],
84                        ['change_smooth_selection', 'smooth_selection.gif', 'change_smooth_selection_mode', true],
85                        ['reset_highlight', 'reset_highlight.gif', 'resync_highlight', true],
86                        ['highlight', 'highlight.gif','change_highlight', true],
87                        ['help', 'help.gif', 'show_help', false],
88                        ['save', 'save.gif', 'save', false],
89                        ['load', 'load.gif', 'load', false],
90                        ['fullscreen', 'fullscreen.gif', 'toggle_full_screen', false],
91                        ['word_wrap', 'word_wrap.gif', 'toggle_word_wrap', true],
92                        ['autocompletion', 'autocompletion.gif', 'toggle_autocompletion', true]
93                ];
94                       
95        // navigator identification
96        t.set_browser_infos(t);
97
98        if(t.isIE>=6 || t.isGecko || ( t.isWebKit && !t.isSafari<3 ) || t.isOpera>=9  || t.isCamino )
99                t.isValidBrowser=true;
100        else
101                t.isValidBrowser=false;
102
103        t.set_base_url();               
104       
105        for(var i=0; i<t.scripts_to_load.length; i++){
106                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
107                t.waiting_loading[t.scripts_to_load[i]+ ".js"]= false;
108        }
109        t.add_event(window, "load", EditAreaLoader.prototype.window_loaded);
110};
111       
112EditAreaLoader.prototype ={
113        has_error : function(){
114                this.error= true;
115                // set to empty all EditAreaLoader functions
116                for(var i in EditAreaLoader.prototype){
117                        EditAreaLoader.prototype[i]=function(){};               
118                }
119        },
120       
121        // add browser informations to the object passed in parameter
122        set_browser_infos : function(o){
123                ua= navigator.userAgent;
124               
125                // general detection
126                o.isWebKit      = /WebKit/.test(ua);
127                o.isGecko       = !o.isWebKit && /Gecko/.test(ua);
128                o.isMac         = /Mac/.test(ua);
129               
130                o.isIE  = (navigator.appName == "Microsoft Internet Explorer");
131                if(o.isIE){
132                        o.isIE = ua.replace(/^.*?MSIE\s+([0-9\.]+).*$/, "$1");
133                        if(o.isIE<6)
134                                o.has_error();
135                }
136
137                if(o.isOpera = (ua.indexOf('Opera') != -1)){   
138                        o.isOpera= ua.replace(/^.*?Opera.*?([0-9\.]+).*$/i, "$1");
139                        if(o.isOpera<9)
140                                o.has_error();
141                        o.isIE=false;                   
142                }
143
144                if(o.isFirefox =(ua.indexOf('Firefox') != -1))
145                        o.isFirefox = ua.replace(/^.*?Firefox.*?([0-9\.]+).*$/i, "$1");
146                // Firefox clones       
147                if( ua.indexOf('Iceweasel') != -1 )
148                        o.isFirefox     = ua.replace(/^.*?Iceweasel.*?([0-9\.]+).*$/i, "$1");
149                if( ua.indexOf('GranParadiso') != -1 )
150                        o.isFirefox     = ua.replace(/^.*?GranParadiso.*?([0-9\.]+).*$/i, "$1");
151                if( ua.indexOf('BonEcho') != -1 )
152                        o.isFirefox     = ua.replace(/^.*?BonEcho.*?([0-9\.]+).*$/i, "$1");
153                if( ua.indexOf('SeaMonkey') != -1)
154                        o.isFirefox = (ua.replace(/^.*?SeaMonkey.*?([0-9\.]+).*$/i, "$1") ) + 1;
155                       
156                if(o.isCamino =(ua.indexOf('Camino') != -1))
157                        o.isCamino = ua.replace(/^.*?Camino.*?([0-9\.]+).*$/i, "$1");
158                       
159                if(o.isSafari =(ua.indexOf('Safari') != -1))
160                        o.isSafari= ua.replace(/^.*?Version\/([0-9]+\.[0-9]+).*$/i, "$1");
161       
162                if(o.isChrome =(ua.indexOf('Chrome') != -1)) {
163                        o.isChrome = ua.replace(/^.*?Chrome.*?([0-9\.]+).*$/i, "$1");
164                        o.isSafari      = false;
165                }
166               
167        },
168       
169        window_loaded : function(){
170                editAreaLoader.win="loaded";
171               
172                // add events on forms
173                if (document.forms) {
174                        for (var i=0; i<document.forms.length; i++) {
175                                var form = document.forms[i];
176                                form.edit_area_replaced_submit=null;
177                                try {
178                                       
179                                        form.edit_area_replaced_submit = form.onsubmit;
180                                        form.onsubmit="";
181                                } catch (e) {// Do nothing
182                                }
183                                editAreaLoader.add_event(form, "submit", EditAreaLoader.prototype.submit);
184                                editAreaLoader.add_event(form, "reset", EditAreaLoader.prototype.reset);
185                        }
186                }
187                editAreaLoader.add_event(window, "unload", function(){for(var i in editAreas){editAreaLoader.delete_instance(i);}});    // ini callback
188        },
189       
190        // init the checkup of the selection of the IE textarea
191        init_ie_textarea : function(id){
192                var a=document.getElementById(id);
193                try{
194                        if(a && typeof(a.focused)=="undefined"){
195                                a.focus();
196                                a.focused=true;
197                                a.selectionStart= a.selectionEnd= 0;                   
198                                get_IE_selection(a);
199                                editAreaLoader.add_event(a, "focus", IE_textarea_focus);
200                                editAreaLoader.add_event(a, "blur", IE_textarea_blur);
201                               
202                        }
203                }catch(ex){}
204        },
205               
206        init : function(settings){
207                var t=this,s=settings,i;
208               
209                if(!s["id"])
210                        t.has_error();
211                if(t.error)
212                        return;
213                // if an instance of the editor already exists for this textarea => delete the previous one
214                if(editAreas[s["id"]])
215                        t.delete_instance(s["id"]);
216       
217                // init settings
218                for(i in t.default_settings){
219                        if(typeof(s[i])=="undefined")
220                                s[i]=t.default_settings[i];
221                }
222               
223                if(s["browsers"]=="known" && t.isValidBrowser==false){
224                        return;
225                }
226               
227                if(s["begin_toolbar"].length>0)
228                        s["toolbar"]= s["begin_toolbar"] +","+ s["toolbar"];
229                if(s["end_toolbar"].length>0)
230                        s["toolbar"]= s["toolbar"] +","+ s["end_toolbar"];
231                s["tab_toolbar"]= s["toolbar"].replace(/ /g,"").split(",");
232               
233                s["plugins"]= s["plugins"].replace(/ /g,"").split(",");
234                for(i=0; i<s["plugins"].length; i++){
235                        if(s["plugins"][i].length==0)
236                                s["plugins"].splice(i,1);
237                }
238        //      alert(settings["plugins"].length+": "+ settings["plugins"].join(","));
239                t.get_template();
240                t.load_script(t.baseURL + "langs/"+ s["language"] + ".js");
241               
242                if(s["syntax"].length>0){
243                        s["syntax"]=s["syntax"].toLowerCase();
244                        t.load_script(t.baseURL + "reg_syntax/"+ s["syntax"] + ".js");
245                }
246                //alert(this.template);
247               
248                editAreas[s["id"]]= {"settings": s};
249                editAreas[s["id"]]["displayed"]=false;
250                editAreas[s["id"]]["hidden"]=false;
251               
252                //if(settings["display"]=="onload")
253                t.start(s["id"]);
254        },
255       
256        // delete an instance of an EditArea
257        delete_instance : function(id){
258                var d=document,fs=window.frames,span,iframe;
259                editAreaLoader.execCommand(id, "EA_delete");
260                if(fs["frame_"+id] && fs["frame_"+id].editArea)
261                {
262                        if(editAreas[id]["displayed"])
263                                editAreaLoader.toggle(id, "off");
264                        fs["frame_"+id].editArea.execCommand("EA_unload");
265                }
266
267                // remove toggle infos and debug textarea
268                span= d.getElementById("EditAreaArroundInfos_"+id);
269                if(span)
270                        span.parentNode.removeChild(span);
271
272                // remove the iframe
273                iframe= d.getElementById("frame_"+id);
274                if(iframe){
275                        iframe.parentNode.removeChild(iframe);
276                        //delete iframe;
277                        try {
278                                delete fs["frame_"+id];
279                        } catch (e) {// Do nothing
280                        }
281                }       
282
283                delete editAreas[id];
284        },
285
286       
287        start : function(id){
288                var t=this,d=document,f,span,father,next,html='',html_toolbar_content='',template,content,i;
289               
290                // check that the window is loaded
291                if(t.win!="loaded"){
292                        setTimeout("editAreaLoader.start('"+id+"');", 50);
293                        return;
294                }
295               
296                // check that all needed scripts are loaded
297                for( i in t.waiting_loading){
298                        if(t.waiting_loading[i]!="loaded" && typeof(t.waiting_loading[i])!="function"){
299                                setTimeout("editAreaLoader.start('"+id+"');", 50);
300                                return;
301                        }
302                }
303               
304                // wait until language and syntax files are loaded
305                if(!t.lang[editAreas[id]["settings"]["language"]] || (editAreas[id]["settings"]["syntax"].length>0 && !t.load_syntax[editAreas[id]["settings"]["syntax"]]) ){
306                        setTimeout("editAreaLoader.start('"+id+"');", 50);
307                        return;
308                }
309                // init the regexp for syntax highlight
310                if(editAreas[id]["settings"]["syntax"].length>0)
311                        t.init_syntax_regexp();
312               
313                       
314                // display toggle option and debug area
315                if(!d.getElementById("EditAreaArroundInfos_"+id) && (editAreas[id]["settings"]["debug"] || editAreas[id]["settings"]["allow_toggle"]))
316                {
317                        span= d.createElement("span");
318                        span.id= "EditAreaArroundInfos_"+id;
319                        if(editAreas[id]["settings"]["allow_toggle"]){
320                                checked=(editAreas[id]["settings"]["display"]=="onload")?"checked='checked'":"";
321                                html+="<div id='edit_area_toggle_"+i+"'>";
322                                html+="<input id='edit_area_toggle_checkbox_"+ id +"' class='toggle_"+ id +"' type='checkbox' onclick='editAreaLoader.toggle(\""+ id +"\");' accesskey='e' "+checked+" />";
323                                html+="<label for='edit_area_toggle_checkbox_"+ id +"'>{$toggle}</label></div>";       
324                        }
325                        if(editAreas[id]["settings"]["debug"])
326                                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 />";                           
327                        html= t.translate(html, editAreas[id]["settings"]["language"]);                         
328                        span.innerHTML= html;                           
329                        father= d.getElementById(id).parentNode;
330                        next= d.getElementById(id).nextSibling;
331                        if(next==null)
332                                father.appendChild(span);
333                        else
334                                father.insertBefore(span, next);
335                }
336               
337                if(!editAreas[id]["initialized"])
338                {
339                        t.execCommand(id, "EA_init");   // ini callback
340                        if(editAreas[id]["settings"]["display"]=="later"){
341                                editAreas[id]["initialized"]= true;
342                                return;
343                        }
344                }
345               
346                if(t.isIE){     // launch IE selection checkup
347                        t.init_ie_textarea(id);
348                }
349                               
350                // get toolbar content
351                var area=editAreas[id];
352               
353                for(i=0; i<area["settings"]["tab_toolbar"].length; i++){
354                //      alert(this.tab_toolbar[i]+"\n"+ this.get_control_html(this.tab_toolbar[i]));
355                        html_toolbar_content+= t.get_control_html(area["settings"]["tab_toolbar"][i], area["settings"]["language"]);
356                }
357                // translate toolbar text here for chrome 2
358                html_toolbar_content = t.translate(html_toolbar_content, area["settings"]["language"], "template"); 
359               
360               
361                // create javascript import rules for the iframe if the javascript has not been already loaded by the compressor
362                if(!t.iframe_script){
363                        t.iframe_script="";
364                        for(i=0; i<t.sub_scripts_to_load.length; i++)
365                                t.iframe_script+='<script language="javascript" type="text/javascript" src="'+ t.baseURL + t.sub_scripts_to_load[i] +'.js"></script>';
366                }
367               
368                // add plugins scripts if not already loaded by the compressor (but need to load language in all the case)
369                for(i=0; i<area["settings"]["plugins"].length; i++){
370                        //if(typeof(area["settings"]["plugins"][i])=="function") continue;
371                        if(!t.all_plugins_loaded)
372                                t.iframe_script+='<script language="javascript" type="text/javascript" src="'+ t.baseURL + 'plugins/' + area["settings"]["plugins"][i] + '/' + area["settings"]["plugins"][i] +'.js"></script>';
373                        t.iframe_script+='<script language="javascript" type="text/javascript" src="'+ t.baseURL + 'plugins/' + area["settings"]["plugins"][i] + '/langs/' + area["settings"]["language"] +'.js"></script>';
374                }
375       
376               
377                // create css link for the iframe if the whole css text has not been already loaded by the compressor
378                if(!t.iframe_css){
379                        t.iframe_css="<link href='"+ t.baseURL +"edit_area.css' rel='stylesheet' type='text/css' />";
380                }
381               
382               
383                // create template
384                template= t.template.replace(/\[__BASEURL__\]/g, t.baseURL);
385                template= template.replace("[__TOOLBAR__]",html_toolbar_content);
386                       
387               
388                // fill template with good language sentences
389                template= t.translate(template, area["settings"]["language"], "template");
390               
391                // add css_code
392                template= template.replace("[__CSSRULES__]", t.iframe_css);                             
393                // add js_code
394                template= template.replace("[__JSCODE__]", t.iframe_script);
395               
396                // add version_code
397                template= template.replace("[__EA_VERSION__]", t.version);
398                //template=template.replace(/\{\$([^\}]+)\}/gm, this.traduc_template);
399               
400                //editAreas[area["settings"]["id"]]["template"]= template;
401               
402                area.textarea=d.getElementById(area["settings"]["id"]);
403                editAreas[area["settings"]["id"]]["textarea"]=area.textarea;
404       
405                // if removing previous instances from DOM before (fix from Marcin)
406                if(typeof(window.frames["frame_"+area["settings"]["id"]])!='undefined') 
407                        delete window.frames["frame_"+area["settings"]["id"]];
408               
409                // insert template in the document after the textarea
410                father= area.textarea.parentNode;
411        /*      var container= document.createElement("div");
412                container.id= "EditArea_frame_container_"+area["settings"]["id"];
413        */     
414                content= d.createElement("iframe");
415                content.name= "frame_"+area["settings"]["id"];
416                content.id= "frame_"+area["settings"]["id"];
417                content.style.borderWidth= "0px";
418                setAttribute(content, "frameBorder", "0"); // IE
419                content.style.overflow="hidden";
420                content.style.display="none";
421
422               
423                next= area.textarea.nextSibling;
424                if(next==null)
425                        father.appendChild(content);
426                else
427                        father.insertBefore(content, next) ;           
428                f=window.frames["frame_"+area["settings"]["id"]];
429                f.document.open();
430                f.editAreas=editAreas;
431                f.area_id= area["settings"]["id"];     
432                f.document.area_id= area["settings"]["id"];     
433                f.document.write(template);
434                f.document.close();
435
436        //      frame.editAreaLoader=this;
437                //editAreas[area["settings"]["id"]]["displayed"]=true;
438               
439        },
440       
441        toggle : function(id, toggle_to){
442
443        /*      if((editAreas[id]["displayed"]==true  && toggle_to!="on") || toggle_to=="off"){
444                        this.toggle_off(id);
445                }else if((editAreas[id]["displayed"]==false  && toggle_to!="off") || toggle_to=="on"){
446                        this.toggle_on(id);
447                }*/
448                if(!toggle_to)
449                        toggle_to= (editAreas[id]["displayed"]==true)?"off":"on";
450                if(editAreas[id]["displayed"]==true  && toggle_to=="off"){
451                        this.toggle_off(id);
452                }else if(editAreas[id]["displayed"]==false  && toggle_to=="on"){
453                        this.toggle_on(id);
454                }
455       
456                return false;
457        },
458       
459        // static function
460        toggle_off : function(id){
461                var fs=window.frames,f,t,parNod,nxtSib,selStart,selEnd,scrollTop,scrollLeft;
462                if(fs["frame_"+id])
463                {       
464                        f       = fs["frame_"+id];
465                        t       = editAreas[id]["textarea"];
466                        if(f.editArea.fullscreen['isFull'])
467                                f.editArea.toggle_full_screen(false);
468                        editAreas[id]["displayed"]=false;
469                       
470                        // set wrap to off to keep same display mode (some browser get problem with this, so it need more complex operation             
471                        t.wrap = "off"; // for IE
472                        setAttribute(t, "wrap", "off"); // for Firefox 
473                        parNod = t.parentNode;
474                        nxtSib = t.nextSibling;
475                        parNod.removeChild(t); 
476                        parNod.insertBefore(t, nxtSib);
477                       
478                        // restore values
479                        t.value= f.editArea.textarea.value;
480                        selStart        = f.editArea.last_selection["selectionStart"];
481                        selEnd          = f.editArea.last_selection["selectionEnd"];
482                        scrollTop       = f.document.getElementById("result").scrollTop;
483                        scrollLeft      = f.document.getElementById("result").scrollLeft;
484                       
485                       
486                        document.getElementById("frame_"+id).style.display='none';
487               
488                        t.style.display="inline";
489
490                        try{    // IE will give an error when trying to focus an invisible or disabled textarea
491                                t.focus();
492                        } catch(e){};
493                        if(this.isIE){
494                                t.selectionStart= selStart;
495                                t.selectionEnd  = selEnd;
496                                t.focused               = true;
497                                set_IE_selection(t);
498                        }else{
499                                if(this.isOpera && this.isOpera < 9.6 ){        // Opera bug when moving selection start and selection end
500                                        t.setSelectionRange(0, 0);
501                                }
502                                try{
503                                        t.setSelectionRange(selStart, selEnd);
504                                } catch(e) {};
505                        }
506                        t.scrollTop= scrollTop;
507                        t.scrollLeft= scrollLeft;
508                        f.editArea.execCommand("toggle_off");
509
510                }
511        },     
512       
513        // static function
514        toggle_on : function(id){
515                var fs=window.frames,f,t,selStart=0,selEnd=0,scrollTop=0,scrollLeft=0,curPos,elem;
516                       
517                if(fs["frame_"+id])
518                {
519                        f       = fs["frame_"+id];
520                        t       = editAreas[id]["textarea"];
521                        area= f.editArea;
522                        area.textarea.value= t.value;
523                       
524                        // store display values;
525                        curPos  = editAreas[id]["settings"]["cursor_position"];
526
527                        if(t.use_last==true)
528                        {
529                                selStart        = t.last_selectionStart;
530                                selEnd          = t.last_selectionEnd;
531                                scrollTop       = t.last_scrollTop;
532                                scrollLeft      = t.last_scrollLeft;
533                                t.use_last=false;
534                        }
535                        else if( curPos == "auto" )
536                        {
537                                try{
538                                        selStart        = t.selectionStart;
539                                        selEnd          = t.selectionEnd;
540                                        scrollTop       = t.scrollTop;
541                                        scrollLeft      = t.scrollLeft;
542                                        //alert(scrollTop);
543                                }catch(ex){}
544                        }
545                       
546                        // set to good size
547                        this.set_editarea_size_from_textarea(id, document.getElementById("frame_"+id));
548                        t.style.display="none";                 
549                        document.getElementById("frame_"+id).style.display="inline";
550                        area.execCommand("focus"); // without this focus opera doesn't manage well the iframe body height
551                       
552                       
553                        // restore display values
554                        editAreas[id]["displayed"]=true;
555                        area.execCommand("update_size");
556                       
557                        f.document.getElementById("result").scrollTop= scrollTop;
558                        f.document.getElementById("result").scrollLeft= scrollLeft;
559                        area.area_select(selStart, selEnd-selStart);
560                        area.execCommand("toggle_on");
561
562                       
563                }
564                else
565                {
566                /*      if(this.isIE)
567                                get_IE_selection(document.getElementById(id));  */     
568                        elem= document.getElementById(id);     
569                        elem.last_selectionStart= elem.selectionStart;
570                        elem.last_selectionEnd= elem.selectionEnd;
571                        elem.last_scrollTop= elem.scrollTop;
572                        elem.last_scrollLeft= elem.scrollLeft;
573                        elem.use_last=true;
574                        editAreaLoader.start(id);
575                }
576        },     
577       
578        set_editarea_size_from_textarea : function(id, frame){ 
579                var elem,width,height;
580                elem    = document.getElementById(id);
581               
582                width   = Math.max(editAreas[id]["settings"]["min_width"], elem.offsetWidth)+"px";
583                height  = Math.max(editAreas[id]["settings"]["min_height"], elem.offsetHeight)+"px";
584                if(elem.style.width.indexOf("%")!=-1)
585                        width   = elem.style.width;
586                if(elem.style.height.indexOf("%")!=-1)
587                        height  = elem.style.height;
588                //alert("h: "+height+" w: "+width);
589       
590                frame.style.width= width;
591                frame.style.height= height;
592        },
593               
594        set_base_url : function(){
595                var t=this,elems,i,docBasePath;
596
597                if( !this.baseURL ){
598                        elems = document.getElementsByTagName('script');
599       
600                        for( i=0; i<elems.length; i++ ){
601                                if (elems[i].src && elems[i].src.match(/edit_area_[^\\\/]*$/i) ) {
602                                        var src = unescape( elems[i].src ); // use unescape for utf-8 encoded urls
603                                        src = src.substring(0, src.lastIndexOf('/'));
604                                        this.baseURL = src;
605                                        this.file_name= elems[i].src.substr(elems[i].src.lastIndexOf("/")+1);
606                                        break;
607                                }
608                        }
609                }
610               
611                docBasePath     = document.location.href;
612                if (docBasePath.indexOf('?') != -1)
613                        docBasePath     = docBasePath.substring(0, docBasePath.indexOf('?'));
614                docBasePath     = docBasePath.substring(0, docBasePath.lastIndexOf('/'));
615       
616                // If not HTTP absolute
617                if (t.baseURL.indexOf('://') == -1 && t.baseURL.charAt(0) != '/') {
618                        // If site absolute
619                        t.baseURL = docBasePath + "/" + t.baseURL;
620                }
621                t.baseURL       +="/"; 
622        },
623       
624        get_button_html : function(id, img, exec, isFileSpecific, baseURL) {
625                var cmd,html;
626                if(!baseURL)
627                        baseURL= this.baseURL;
628                cmd     = 'editArea.execCommand(\'' + exec + '\')';
629                html    = '<a id="a_'+ id +'" href="javascript:' + cmd + '" onclick="' + cmd + ';return false;" onmousedown="return false;" target="_self" fileSpecific="'+ (isFileSpecific?'yes':'no') +'">';
630                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>';
631                return html;
632        },
633
634        get_control_html : function(button_name, lang) {               
635                var t=this,i,but,html,si;
636                for (i=0; i<t.advanced_buttons.length; i++)
637                {
638                        but = t.advanced_buttons[i];                   
639                        if (but[0] == button_name)
640                        {
641                                return t.get_button_html(but[0], but[1], but[2], but[3]);
642                        }       
643                }               
644                               
645                switch (button_name){
646                        case "*":
647                        case "return":
648                                return "<br />";
649                        case "|":
650                        case "separator":
651                                return '<img src="'+ t.baseURL +'images/spacer.gif" width="1" height="15" class="editAreaSeparatorLine">';
652                        case "select_font":
653                                html= "<select id='area_font_size' onchange='javascript:editArea.execCommand(\"change_font_size\")' fileSpecific='yes'>";
654                                html+="<option value='-1'>{$font_size}</option>";
655                                si=[8,9,10,11,12,14];
656                                for( i=0;i<si.length;i++){
657                                        html+="<option value='"+si[i]+"'>"+si[i]+" pt</option>";
658                                }
659                                html+="</select>";
660                                return html;
661                        case "syntax_selection":
662                                html= "<select id='syntax_selection' onchange='javascript:editArea.execCommand(\"change_syntax\", this.value)' fileSpecific='yes'>";
663                                html+="<option value='-1'>{$syntax_selection}</option>";
664                                html+="</select>";
665                                return html;
666                }
667               
668                return "<span id='tmp_tool_"+button_name+"'>["+button_name+"]</span>";         
669        },
670       
671       
672        get_template : function(){
673                if(this.template=="")
674                {
675                        var xhr_object = null; 
676                        if(window.XMLHttpRequest) // Firefox
677                                xhr_object = new XMLHttpRequest(); 
678                        else if(window.ActiveXObject) // Internet Explorer
679                                xhr_object = new ActiveXObject("Microsoft.XMLHTTP"); 
680                        else { // XMLHttpRequest not supported
681                                alert("XMLHTTPRequest not supported. EditArea not loaded"); 
682                                return; 
683                        } 
684                         
685                        xhr_object.open("GET", this.baseURL+"template.html", false); 
686                        xhr_object.send(null); 
687                        if(xhr_object.readyState == 4) 
688                                this.template=xhr_object.responseText;
689                        else
690                                this.has_error();
691                }
692        },
693       
694        // translate text
695        translate : function(text, lang, mode){
696                if(mode=="word")
697                        text=editAreaLoader.get_word_translation(text, lang);
698                else if(mode="template"){
699                        editAreaLoader.current_language= lang;
700                        text=text.replace(/\{\$([^\}]+)\}/gm, editAreaLoader.translate_template);
701                }
702                return text;
703        },
704       
705        translate_template : function(){
706                return editAreaLoader.get_word_translation(EditAreaLoader.prototype.translate_template.arguments[1], editAreaLoader.current_language);
707        },
708       
709        get_word_translation : function(val, lang){
710                var i;
711               
712                for( i in editAreaLoader.lang[lang]){
713                        if(i == val)
714                                return editAreaLoader.lang[lang][i];
715                }
716                return "_"+val;
717        },
718       
719        load_script : function(url){
720                var t=this,d=document,script,head;
721               
722                if( t.loadedFiles[url] )
723                        return; 
724                //alert("load: "+url);
725                try{
726                        script= d.createElement("script");
727                        script.type= "text/javascript";
728                        script.src= url;
729                        script.charset= "UTF-8";
730                        d.getElementsByTagName("head")[0].appendChild(script);
731                }catch(e){
732                        d.write('<sc'+'ript language="javascript" type="text/javascript" src="' + url + '" charset="UTF-8"></sc'+'ript>');
733                }
734               
735                t.loadedFiles[url] = true;
736        },
737       
738        add_event : function(obj, name, handler) {
739                try{
740                        if (obj.attachEvent) {
741                                obj.attachEvent("on" + name, handler);
742                        } else{
743                                obj.addEventListener(name, handler, false);
744                        }
745                }catch(e){}
746        },
747       
748        remove_event : function(obj, name, handler){
749                try{
750                        if (obj.detachEvent)
751                                obj.detachEvent("on" + name, handler);
752                        else
753                                obj.removeEventListener(name, handler, false);
754                }catch(e){}
755        },
756
757
758        // reset all the editareas in the form that have been reseted
759        reset : function(e){
760                var formObj,is_child,i,x;
761               
762                formObj = editAreaLoader.isIE ? window.event.srcElement : e.target;
763                if(formObj.tagName!='FORM')
764                        formObj= formObj.form;
765               
766                for( i in editAreas ){                 
767                        is_child= false;
768                        for( x=0;x<formObj.elements.length;x++ ) {
769                                if(formObj.elements[x].id == i)
770                                        is_child=true;
771                        }
772                       
773                        if(window.frames["frame_"+i] && is_child && editAreas[i]["displayed"]==true){
774                       
775                                var exec= 'window.frames["frame_'+ i +'"].editArea.textarea.value= document.getElementById("'+ i +'").value;';
776                                exec+= 'window.frames["frame_'+ i +'"].editArea.execCommand("focus");';
777                                exec+= 'window.frames["frame_'+ i +'"].editArea.check_line_selection();';
778                                exec+= 'window.frames["frame_'+ i +'"].editArea.execCommand("reset");';
779                                window.setTimeout(exec, 10);
780                        }
781                }               
782                return;
783        },
784       
785       
786        // prepare all the textarea replaced by an editarea to be submited
787        submit : function(e){           
788                var formObj,is_child,fs=window.frames,i,x;
789                formObj = editAreaLoader.isIE ? window.event.srcElement : e.target;
790                if(formObj.tagName!='FORM')
791                        formObj= formObj.form;
792               
793                for( i in editAreas){
794                        is_child= false;
795                        for( x=0;x<formObj.elements.length;x++ ) {
796                                if(formObj.elements[x].id == i)
797                                        is_child=true;
798                        }
799               
800                        if(is_child)
801                        {
802                                if(fs["frame_"+i] && editAreas[i]["displayed"]==true)
803                                        document.getElementById(i).value= fs["frame_"+ i].editArea.textarea.value;
804                                editAreaLoader.execCommand(i,"EA_submit");
805                        }
806                }                               
807                if( typeof(formObj.edit_area_replaced_submit) == "function" ){
808                        res= formObj.edit_area_replaced_submit();
809                        if(res==false){
810                                if(editAreaLoader.isIE)
811                                        return false;
812                                else
813                                        e.preventDefault();
814                        }
815                }
816                return;
817        },
818       
819        // allow to get the value of the editarea
820        getValue : function(id){
821        if(window.frames["frame_"+id] && editAreas[id]["displayed"]==true){
822            return window.frames["frame_"+ id].editArea.textarea.value;       
823        }else if(elem=document.getElementById(id)){
824                return elem.value;
825        }
826        return false;
827    },
828   
829    // allow to set the value of the editarea
830    setValue : function(id, new_val){
831        var fs=window.frames;
832       
833        if( ( f=fs["frame_"+id] ) && editAreas[id]["displayed"]==true){
834                        f.editArea.textarea.value= new_val;     
835                        f.editArea.execCommand("focus"); 
836                        f.editArea.check_line_selection(false); 
837                        f.editArea.execCommand("onchange");
838        }else if(elem=document.getElementById(id)){
839                elem.value= new_val;
840        }
841    },
842           
843    // allow to get infos on the selection: array(start, end)
844    getSelectionRange : function(id){
845        var sel,eA,fs=window.frames;
846       
847        sel= {"start": 0, "end": 0};
848        if(fs["frame_"+id] && editAreas[id]["displayed"]==true){
849                eA= fs["frame_"+ id].editArea;
850
851                        sel["start"]    = eA.textarea.selectionStart;
852                        sel["end"]              = eA.textarea.selectionEnd;
853               
854        }else if( elem=document.getElementById(id) ){
855                sel= getSelectionRange(elem);
856        }
857        return sel;
858    },
859   
860    // allow to set the selection with the given start and end positions
861    setSelectionRange : function(id, new_start, new_end){
862        var fs=window.frames;
863       
864        if(fs["frame_"+id] && editAreas[id]["displayed"]==true){
865            fs["frame_"+ id].editArea.area_select(new_start, new_end-new_start); 
866                        // make an auto-scroll to the selection
867                        if(!this.isIE){
868                                fs["frame_"+ id].editArea.check_line_selection(false); 
869                                fs["frame_"+ id].editArea.scroll_to_view();
870                        }   
871        }else if(elem=document.getElementById(id)){
872                setSelectionRange(elem, new_start, new_end);
873        }
874    },
875   
876    getSelectedText : function(id){
877        var sel= this.getSelectionRange(id);
878       
879        return this.getValue(id).substring(sel["start"], sel["end"]);
880    },
881       
882        setSelectedText : function(id, new_val){
883                var fs=window.frames,d=document,sel,text,scrollTop,scrollLeft,new_sel_end;
884               
885                new_val = new_val.replace(/\r/g, ""); 
886                sel             = this.getSelectionRange(id);
887                text    = this.getValue(id);
888                if(fs["frame_"+id] && editAreas[id]["displayed"]==true){
889                        scrollTop       = fs["frame_"+ id].document.getElementById("result").scrollTop;
890                        scrollLeft      = fs["frame_"+ id].document.getElementById("result").scrollLeft;
891                }else{
892                        scrollTop       = d.getElementById(id).scrollTop;
893                        scrollLeft      = d.getElementById(id).scrollLeft;
894                }
895               
896                text    = text.substring(0, sel["start"])+ new_val +text.substring(sel["end"]);
897                this.setValue(id, text);
898                new_sel_end     = sel["start"]+ new_val.length;
899                this.setSelectionRange(id, sel["start"], new_sel_end);
900               
901               
902                // fix \r problem for selection length count on IE & Opera
903                if(new_val != this.getSelectedText(id).replace(/\r/g, "")){
904                        this.setSelectionRange(id, sel["start"], new_sel_end+ new_val.split("\n").length -1);
905                }
906                // restore scrolling position
907                if(fs["frame_"+id] && editAreas[id]["displayed"]==true){
908                        fs["frame_"+ id].document.getElementById("result").scrollTop= scrollTop;
909                        fs["frame_"+ id].document.getElementById("result").scrollLeft= scrollLeft;
910                        fs["frame_"+ id].editArea.execCommand("onchange");
911                }else{
912                        d.getElementById(id).scrollTop= scrollTop;
913                        d.getElementById(id).scrollLeft= scrollLeft;
914                }
915    },
916   
917    insertTags : function(id, open_tag, close_tag){
918        var old_sel,new_sel;
919       
920        old_sel = this.getSelectionRange(id);
921        text    = open_tag + this.getSelectedText(id) + close_tag;
922         
923                editAreaLoader.setSelectedText(id, text);
924               
925        new_sel = this.getSelectionRange(id);
926        if(old_sel["end"] > old_sel["start"])   // if text was selected, cursor at the end
927                this.setSelectionRange(id, new_sel["end"], new_sel["end"]);
928        else // cursor in the middle
929                this.setSelectionRange(id, old_sel["start"]+open_tag.length, old_sel["start"]+open_tag.length);
930    },
931   
932    // hide both EditArea and normal textarea
933        hide : function(id){
934                var fs= window.frames,d=document,t=this,scrollTop,scrollLeft,span;
935                if(d.getElementById(id) && !t.hidden[id])
936                {
937                        t.hidden[id]= {};
938                        t.hidden[id]["selectionRange"]= t.getSelectionRange(id);
939                        if(d.getElementById(id).style.display!="none")
940                        {
941                                t.hidden[id]["scrollTop"]= d.getElementById(id).scrollTop;
942                                t.hidden[id]["scrollLeft"]= d.getElementById(id).scrollLeft;
943                        }
944                                       
945                        if(fs["frame_"+id])
946                        {
947                                t.hidden[id]["toggle"]= editAreas[id]["displayed"];
948                               
949                                if(fs["frame_"+id] && editAreas[id]["displayed"]==true){
950                                        scrollTop       = fs["frame_"+ id].document.getElementById("result").scrollTop;
951                                        scrollLeft      = fs["frame_"+ id].document.getElementById("result").scrollLeft;
952                                }else{
953                                        scrollTop       = d.getElementById(id).scrollTop;
954                                        scrollLeft      = d.getElementById(id).scrollLeft;
955                                }
956                                t.hidden[id]["scrollTop"]= scrollTop;
957                                t.hidden[id]["scrollLeft"]= scrollLeft;
958                               
959                                if(editAreas[id]["displayed"]==true)
960                                        editAreaLoader.toggle_off(id);
961                        }
962                       
963                        // hide toggle button and debug box
964                        span= d.getElementById("EditAreaArroundInfos_"+id);
965                        if(span){
966                                span.style.display='none';
967                        }
968                       
969                        // hide textarea
970                        d.getElementById(id).style.display= "none";
971                }
972        },
973       
974        // restore hidden EditArea and normal textarea
975        show : function(id){
976                var fs= window.frames,d=document,t=this,span;
977                if((elem=d.getElementById(id)) && t.hidden[id])
978                {
979                        elem.style.display= "inline";
980                        elem.scrollTop= t.hidden[id]["scrollTop"];
981                        elem.scrollLeft= t.hidden[id]["scrollLeft"];
982                        span= d.getElementById("EditAreaArroundInfos_"+id);
983                        if(span){
984                                span.style.display='inline';
985                        }
986                       
987                        if(fs["frame_"+id])
988                        {
989                                                               
990                                // restore toggle button and debug box
991                       
992                               
993                                // restore textarea
994                                elem.style.display= "inline";
995                               
996                                // restore EditArea
997                                if(t.hidden[id]["toggle"]==true)
998                                        editAreaLoader.toggle_on(id);
999                               
1000                                scrollTop       = t.hidden[id]["scrollTop"];
1001                                scrollLeft      = t.hidden[id]["scrollLeft"];
1002                               
1003                                if(fs["frame_"+id] && editAreas[id]["displayed"]==true){
1004                                        fs["frame_"+ id].document.getElementById("result").scrollTop    = scrollTop;
1005                                        fs["frame_"+ id].document.getElementById("result").scrollLeft   = scrollLeft;
1006                                }else{
1007                                        elem.scrollTop  = scrollTop;
1008                                        elem.scrollLeft = scrollLeft;
1009                                }
1010                       
1011                        }
1012                        // restore selection
1013                        sel     = t.hidden[id]["selectionRange"];
1014                        t.setSelectionRange(id, sel["start"], sel["end"]);
1015                        delete t.hidden[id];   
1016                }
1017        },
1018       
1019        // get the current file datas (for multi file editing mode)
1020        getCurrentFile : function(id){
1021                return this.execCommand(id, 'get_file', this.execCommand(id, 'curr_file'));
1022        },
1023       
1024        // get the given file datas (for multi file editing mode)
1025        getFile : function(id, file_id){
1026                return this.execCommand(id, 'get_file', file_id);
1027        },
1028       
1029        // get all the openned files datas (for multi file editing mode)
1030        getAllFiles : function(id){
1031                return this.execCommand(id, 'get_all_files()');
1032        },
1033       
1034        // open a file (for multi file editing mode)
1035        openFile : function(id, file_infos){
1036                return this.execCommand(id, 'open_file', file_infos);
1037        },
1038       
1039        // close the given file (for multi file editing mode)
1040        closeFile : function(id, file_id){
1041                return this.execCommand(id, 'close_file', file_id);
1042        },
1043       
1044        // close the given file (for multi file editing mode)
1045        setFileEditedMode : function(id, file_id, to){
1046                var reg1,reg2;
1047                reg1    = new RegExp('\\\\', 'g');
1048                reg2    = new RegExp('"', 'g');
1049                return this.execCommand(id, 'set_file_edited_mode("'+ file_id.replace(reg1, '\\\\').replace(reg2, '\\"') +'", '+ to +')');
1050        },
1051       
1052       
1053        // allow to access to editarea functions and datas (for advanced users only)
1054        execCommand : function(id, cmd, fct_param){
1055                switch(cmd){
1056                        case "EA_init":
1057                                if(editAreas[id]['settings']["EA_init_callback"].length>0)
1058                                        eval(editAreas[id]['settings']["EA_init_callback"]+"('"+ id +"');");
1059                                break;
1060                        case "EA_delete":
1061                                if(editAreas[id]['settings']["EA_delete_callback"].length>0)
1062                                        eval(editAreas[id]['settings']["EA_delete_callback"]+"('"+ id +"');");
1063                                break;
1064                        case "EA_submit":
1065                                if(editAreas[id]['settings']["submit_callback"].length>0)
1066                                        eval(editAreas[id]['settings']["submit_callback"]+"('"+ id +"');");
1067                                break;
1068                }
1069        if(window.frames["frame_"+id] && window.frames["frame_"+ id].editArea){
1070                        if(fct_param!=undefined)
1071                                return eval('window.frames["frame_'+ id +'"].editArea.'+ cmd +'(fct_param);');
1072                        else
1073                                return eval('window.frames["frame_'+ id +'"].editArea.'+ cmd +';');       
1074        }
1075        return false;
1076    }
1077};
1078       
1079        var editAreaLoader= new EditAreaLoader();
1080        var editAreas= {};
1081
Note: See TracBrowser for help on using the repository browser.