source: trunk/plugins/LocalFilesEditor/editarea/edit_area.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: 17.0 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
9        function EditArea(){
10                var t=this;
11                t.error= false; // to know if load is interrrupt
12               
13                t.inlinePopup= [{popup_id: "area_search_replace", icon_id: "search"},
14                                                                        {popup_id: "edit_area_help", icon_id: "help"}];
15                t.plugins= {};
16       
17                t.line_number=0;
18               
19                parent.editAreaLoader.set_browser_infos(t);     // navigator identification
20                // fix IE8 detection as we run in IE7 emulate mode through X-UA <meta> tag
21                if( t.isIE >= 8 )
22                        t.isIE  = 7;
23               
24                t.last_selection={};           
25                t.last_text_to_highlight="";
26                t.last_hightlighted_text= "";
27                t.syntax_list= [];
28                t.allready_used_syntax= {};
29                t.check_line_selection_timer= 50;       // the timer delay for modification and/or selection change detection
30               
31                t.textareaFocused= false;
32                t.highlight_selection_line= null;
33                t.previous= [];
34                t.next= [];
35                t.last_undo="";
36                t.files= {};
37                t.filesIdAssoc= {};
38                t.curr_file= '';
39                //t.loaded= false;
40                t.assocBracket={};
41                t.revertAssocBracket= {};               
42                // bracket selection init
43                t.assocBracket["("]=")";
44                t.assocBracket["{"]="}";
45                t.assocBracket["["]="]";               
46                for(var index in t.assocBracket){
47                        t.revertAssocBracket[t.assocBracket[index]]=index;
48                }
49                t.is_editable= true;
50               
51               
52                /*t.textarea="";       
53               
54                t.state="declare";
55                t.code = []; // store highlight syntax for languagues*/
56                // font datas
57                t.lineHeight= 16;
58                /*t.default_font_family= "monospace";
59                t.default_font_size= 10;*/
60                t.tab_nb_char= 8;       //nb of white spaces corresponding to a tabulation
61                if(t.isOpera)
62                        t.tab_nb_char= 6;
63
64                t.is_tabbing= false;
65               
66                t.fullscreen= {'isFull': false};
67               
68                t.isResizing=false;     // resize var
69               
70                // init with settings and ID (area_id is a global var defined by editAreaLoader on iframe creation
71                t.id= area_id;
72                t.settings= editAreas[t.id]["settings"];
73               
74                if((""+t.settings['replace_tab_by_spaces']).match(/^[0-9]+$/))
75                {
76                        t.tab_nb_char= t.settings['replace_tab_by_spaces'];
77                        t.tabulation="";
78                        for(var i=0; i<t.tab_nb_char; i++)
79                                t.tabulation+=" ";
80                }else{
81                        t.tabulation="\t";
82                }
83                       
84                // retrieve the init parameter for syntax
85                if(t.settings["syntax_selection_allow"] && t.settings["syntax_selection_allow"].length>0)
86                        t.syntax_list= t.settings["syntax_selection_allow"].replace(/ /g,"").split(",");
87               
88                if(t.settings['syntax'])
89                        t.allready_used_syntax[t.settings['syntax']]=true;
90               
91               
92        };
93        EditArea.prototype.init= function(){
94                var t=this, a, s=t.settings;
95                t.textarea                      = _$("textarea");
96                t.container                     = _$("container");
97                t.result                        = _$("result");
98                t.content_highlight     = _$("content_highlight");
99                t.selection_field       = _$("selection_field");
100                t.selection_field_text= _$("selection_field_text");
101                t.processing_screen     = _$("processing");
102                t.editor_area           = _$("editor");
103                t.tab_browsing_area     = _$("tab_browsing_area");
104                t.test_font_size        = _$("test_font_size");
105                a = t.textarea;
106               
107                if(!s['is_editable'])
108                        t.set_editable(false);
109               
110                t.set_show_line_colors( s['show_line_colors'] );
111               
112                if(syntax_selec= _$("syntax_selection"))
113                {
114                        // set up syntax selection lsit in the toolbar
115                        for(var i=0; i<t.syntax_list.length; i++) {
116                                var syntax= t.syntax_list[i];
117                                var option= document.createElement("option");
118                                option.value= syntax;
119                                if(syntax==s['syntax'])
120                                        option.selected= "selected";
121                                dispSyntax      = parent.editAreaLoader.syntax_display_name[ syntax ];
122                                option.innerHTML= typeof( dispSyntax ) == 'undefined' ? syntax.substring( 0, 1 ).toUpperCase() + syntax.substring( 1 ) : dispSyntax;//t.get_translation("syntax_" + syntax, "word");
123                                syntax_selec.appendChild(option);
124                        }
125                }
126               
127                // add plugins buttons in the toolbar
128                spans= parent.getChildren(_$("toolbar_1"), "span", "", "", "all", -1);
129               
130                for(var i=0; i<spans.length; i++){
131               
132                        id=spans[i].id.replace(/tmp_tool_(.*)/, "$1");
133                        if(id!= spans[i].id){
134                                for(var j in t.plugins){
135                                        if(typeof(t.plugins[j].get_control_html)=="function" ){
136                                                html=t.plugins[j].get_control_html(id);
137                                                if(html!=false){
138                                                        html= t.get_translation(html, "template");
139                                                        var new_span= document.createElement("span");
140                                                        new_span.innerHTML= html;                               
141                                                        var father= spans[i].parentNode;
142                                                        spans[i].parentNode.replaceChild(new_span, spans[i]);   
143                                                        break; // exit the for loop                                     
144                                                }
145                                        }
146                                }
147                        }
148                }
149               
150                // init datas
151                //a.value       = 'a';//editAreas[t.id]["textarea"].value;
152       
153                if(s["debug"])
154                {
155                        t.debug=parent.document.getElementById("edit_area_debug_"+t.id);
156                }
157                // init size           
158                //this.update_size();
159               
160                if(_$("redo") != null)
161                        t.switchClassSticky(_$("redo"), 'editAreaButtonDisabled', true);
162               
163                // insert css rules for highlight mode         
164                if(typeof(parent.editAreaLoader.syntax[s["syntax"]])!="undefined"){
165                        for(var i in parent.editAreaLoader.syntax){
166                                if (typeof(parent.editAreaLoader.syntax[i]["styles"]) != "undefined"){
167                                        t.add_style(parent.editAreaLoader.syntax[i]["styles"]);
168                                }
169                        }
170                }
171       
172                // init key events
173                if(t.isOpera)
174                        _$("editor").onkeypress = keyDown;
175                else
176                        _$("editor").onkeydown  = keyDown;
177
178                for(var i=0; i<t.inlinePopup.length; i++){
179                        if(t.isOpera)
180                                _$(t.inlinePopup[i]["popup_id"]).onkeypress     = keyDown;
181                        else
182                                _$(t.inlinePopup[i]["popup_id"]).onkeydown      = keyDown;
183                }
184               
185                if(s["allow_resize"]=="both" || s["allow_resize"]=="x" || s["allow_resize"]=="y")
186                        t.allow_resize(true);
187               
188                parent.editAreaLoader.toggle(t.id, "on");
189                //a.focus();
190                // line selection init
191                t.change_smooth_selection_mode(editArea.smooth_selection);
192                // highlight
193                t.execCommand("change_highlight", s["start_highlight"]);
194       
195                // get font size datas         
196                t.set_font(editArea.settings["font_family"], editArea.settings["font_size"]);
197               
198                // set unselectable text
199                children= parent.getChildren(document.body, "", "selec", "none", "all", -1);
200                for(var i=0; i<children.length; i++){
201                        if(t.isIE)
202                                children[i].unselectable = true; // IE
203                        else
204                                children[i].onmousedown= function(){return false};
205                /*      children[i].style.MozUserSelect = "none"; // Moz
206                        children[i].style.KhtmlUserSelect = "none";  // Konqueror/Safari*/
207                }
208               
209                a.spellcheck= s["gecko_spellcheck"];
210       
211                /** Browser specific style fixes **/
212               
213                // fix rendering bug for highlighted lines beginning with no tabs
214                if( t.isFirefox >= '3' ) {
215                        t.content_highlight.style.paddingLeft= "1px";
216                        t.selection_field.style.paddingLeft= "1px";
217                        t.selection_field_text.style.paddingLeft= "1px";
218                }
219               
220                if(t.isIE && t.isIE < 8 ){
221                        a.style.marginTop= "-1px";
222                }
223                /*
224                if(t.isOpera){
225                        t.editor_area.style.position= "absolute";
226                }*/
227               
228                if( t.isSafari ){
229                        t.editor_area.style.position    = "absolute";
230                        a.style.marginLeft              ="-3px";
231                        if( t.isSafari < 3.2 ) // Safari 3.0 (3.1?)
232                                a.style.marginTop       ="1px";
233                }
234               
235                // si le textarea n'est pas grand, un click sous le textarea doit provoquer un focus sur le textarea
236                parent.editAreaLoader.add_event(t.result, "click", function(e){ if((e.target || e.srcElement)==editArea.result) { editArea.area_select(editArea.textarea.value.length, 0);}  });
237               
238                if(s['is_multi_files']!=false)
239                        t.open_file({'id': t.curr_file, 'text': ''});
240       
241                t.set_word_wrap( s['word_wrap'] );
242               
243                setTimeout("editArea.focus();editArea.manage_size();editArea.execCommand('EA_load');", 10);             
244                //start checkup routine
245                t.check_undo();
246                t.check_line_selection(true);
247                t.scroll_to_view();
248               
249                for(var i in t.plugins){
250                        if(typeof(t.plugins[i].onload)=="function")
251                                t.plugins[i].onload();
252                }
253                if(s['fullscreen']==true)
254                        t.toggle_full_screen(true);
255       
256                parent.editAreaLoader.add_event(window, "resize", editArea.update_size);
257                parent.editAreaLoader.add_event(parent.window, "resize", editArea.update_size);
258                parent.editAreaLoader.add_event(top.window, "resize", editArea.update_size);
259                parent.editAreaLoader.add_event(window, "unload", function(){
260                        // in case where editAreaLoader have been already cleaned
261                        if( parent.editAreaLoader )
262                        {
263                                parent.editAreaLoader.remove_event(parent.window, "resize", editArea.update_size);
264                                parent.editAreaLoader.remove_event(top.window, "resize", editArea.update_size);
265                        }
266                        if(editAreas[editArea.id] && editAreas[editArea.id]["displayed"]){
267                                editArea.execCommand("EA_unload");
268                        }
269                });
270               
271               
272                /*date= new Date();
273                alert(date.getTime()- parent.editAreaLoader.start_time);*/
274        };
275       
276       
277       
278        //called by the toggle_on
279        EditArea.prototype.update_size= function(){
280                var d=document,pd=parent.document,height,width,popup,maxLeft,maxTop;
281               
282                if( typeof editAreas != 'undefined' && editAreas[editArea.id] && editAreas[editArea.id]["displayed"]==true){
283                        if(editArea.fullscreen['isFull']){     
284                                pd.getElementById("frame_"+editArea.id).style.width             = pd.getElementsByTagName("html")[0].clientWidth + "px";
285                                pd.getElementById("frame_"+editArea.id).style.height    = pd.getElementsByTagName("html")[0].clientHeight + "px";
286                        }
287                       
288                        if(editArea.tab_browsing_area.style.display=='block' && ( !editArea.isIE || editArea.isIE >= 8 ) )
289                        {
290                                editArea.tab_browsing_area.style.height = "0px";
291                                editArea.tab_browsing_area.style.height = (editArea.result.offsetTop - editArea.tab_browsing_area.offsetTop -1)+"px";
292                        }
293                       
294                        height  = d.body.offsetHeight - editArea.get_all_toolbar_height() - 4;
295                        editArea.result.style.height    = height +"px";
296                       
297                        width   = d.body.offsetWidth -2;
298                        editArea.result.style.width             = width+"px";
299                        //alert("result h: "+ height+" w: "+width+"\ntoolbar h: "+this.get_all_toolbar_height()+"\nbody_h: "+document.body.offsetHeight);
300                       
301                        // check that the popups don't get out of the screen
302                        for( i=0; i < editArea.inlinePopup.length; i++ )
303                        {
304                                popup   = _$(editArea.inlinePopup[i]["popup_id"]);
305                                maxLeft = d.body.offsetWidth - popup.offsetWidth;
306                                maxTop  = d.body.offsetHeight - popup.offsetHeight;
307                                if( popup.offsetTop > maxTop )
308                                        popup.style.top         = maxTop+"px";
309                                if( popup.offsetLeft > maxLeft )
310                                        popup.style.left        = maxLeft+"px";
311                        }
312                       
313                        editArea.manage_size( true );
314                        editArea.fixLinesHeight( editArea.textarea.value, 0,-1);
315                }               
316        };
317       
318       
319        EditArea.prototype.manage_size= function(onlyOneTime){
320                if(!editAreas[this.id])
321                        return false;
322                       
323                if(editAreas[this.id]["displayed"]==true && this.textareaFocused)
324                {
325                        var area_height,resized= false;
326                       
327                        //1) Manage display width
328                        //1.1) Calc the new width to use for display
329                        if( !this.settings['word_wrap'] )
330                        {
331                                var area_width= this.textarea.scrollWidth;
332                                area_height= this.textarea.scrollHeight;
333                                // bug on old opera versions
334                                if(this.isOpera && this.isOpera < 9.6 ){
335                                        area_width=10000;                                                               
336                                }
337                                //1.2) the width is not the same, we must resize elements
338                                if(this.textarea.previous_scrollWidth!=area_width)
339                                {       
340                                        this.container.style.width= area_width+"px";
341                                        this.textarea.style.width= area_width+"px";
342                                        this.content_highlight.style.width= area_width+"px";   
343                                        this.textarea.previous_scrollWidth=area_width;
344                                        resized=true;
345                                }
346                        }
347                        // manage wrap width
348                        if( this.settings['word_wrap'] )
349                        {
350                                newW=this.textarea.offsetWidth;
351                                if( this.isFirefox || this.isIE )
352                                        newW-=2;
353                                if( this.isSafari )
354                                        newW-=6;
355                                this.content_highlight.style.width=this.selection_field_text.style.width=this.selection_field.style.width=this.test_font_size.style.width=newW+"px";
356                        }
357                       
358                        //2) Manage display height
359                        //2.1) Calc the new height to use for display
360                        if( this.isOpera || this.isFirefox || this.isSafari ) { 
361                                area_height= this.getLinePosTop( this.last_selection["nb_line"] + 1 );
362                        } else {
363                                area_height = this.textarea.scrollHeight;
364                        }       
365                        //2.2) the width is not the same, we must resize elements
366                        if(this.textarea.previous_scrollHeight!=area_height)   
367                        {       
368                                this.container.style.height= (area_height+2)+"px";
369                                this.textarea.style.height= area_height+"px";
370                                this.content_highlight.style.height= area_height+"px"; 
371                                this.textarea.previous_scrollHeight= area_height;
372                                resized=true;
373                        }
374               
375                        //3) if there is new lines, we add new line numbers in the line numeration area
376                        if(this.last_selection["nb_line"] >= this.line_number)
377                        {
378                                var newLines= '', destDiv=_$("line_number"), start=this.line_number, end=this.last_selection["nb_line"]+100;
379                                for( i = start+1; i < end; i++ )
380                                {
381                                        newLines+='<div id="line_'+ i +'">'+i+"</div>";
382                                        this.line_number++;
383                                }
384                                destDiv.innerHTML= destDiv.innerHTML + newLines;
385                                if(this.settings['word_wrap']){
386                                        this.fixLinesHeight( this.textarea.value, start, -1 );
387                                }
388                        }
389               
390                        //4) be sure the text is well displayed
391                        this.textarea.scrollTop="0px";
392                        this.textarea.scrollLeft="0px";
393                        if(resized==true){
394                                this.scroll_to_view();
395                        }
396                }
397               
398                if(!onlyOneTime)
399                        setTimeout("editArea.manage_size();", 100);
400        };
401       
402        EditArea.prototype.execCommand= function(cmd, param){
403               
404                for(var i in this.plugins){
405                        if(typeof(this.plugins[i].execCommand)=="function"){
406                                if(!this.plugins[i].execCommand(cmd, param))
407                                        return;
408                        }
409                }
410                switch(cmd){
411                        case "save":
412                                if(this.settings["save_callback"].length>0)
413                                        eval("parent."+this.settings["save_callback"]+"('"+ this.id +"', editArea.textarea.value);");
414                                break;
415                        case "load":
416                                if(this.settings["load_callback"].length>0)
417                                        eval("parent."+this.settings["load_callback"]+"('"+ this.id +"');");
418                                break;
419                        case "onchange":
420                                if(this.settings["change_callback"].length>0)
421                                        eval("parent."+this.settings["change_callback"]+"('"+ this.id +"');");
422                                break;         
423                        case "EA_load":
424                                if(this.settings["EA_load_callback"].length>0)
425                                        eval("parent."+this.settings["EA_load_callback"]+"('"+ this.id +"');");
426                                break;
427                        case "EA_unload":
428                                if(this.settings["EA_unload_callback"].length>0)
429                                        eval("parent."+this.settings["EA_unload_callback"]+"('"+ this.id +"');");
430                                break;
431                        case "toggle_on":
432                                if(this.settings["EA_toggle_on_callback"].length>0)
433                                        eval("parent."+this.settings["EA_toggle_on_callback"]+"('"+ this.id +"');");
434                                break;
435                        case "toggle_off":
436                                if(this.settings["EA_toggle_off_callback"].length>0)
437                                        eval("parent."+this.settings["EA_toggle_off_callback"]+"('"+ this.id +"');");
438                                break;
439                        case "re_sync":
440                                if(!this.do_highlight)
441                                        break;
442                        case "file_switch_on":
443                                if(this.settings["EA_file_switch_on_callback"].length>0)
444                                        eval("parent."+this.settings["EA_file_switch_on_callback"]+"(param);");
445                                break;
446                        case "file_switch_off":
447                                if(this.settings["EA_file_switch_off_callback"].length>0)
448                                        eval("parent."+this.settings["EA_file_switch_off_callback"]+"(param);");
449                                break;
450                        case "file_close":
451                                if(this.settings["EA_file_close_callback"].length>0)
452                                        return eval("parent."+this.settings["EA_file_close_callback"]+"(param);");
453                                break;
454                       
455                        default:
456                                if(typeof(eval("editArea."+cmd))=="function")
457                                {
458                                        if(this.settings["debug"])
459                                                eval("editArea."+ cmd +"(param);");
460                                        else
461                                                try{eval("editArea."+ cmd +"(param);");}catch(e){};
462                                }
463                }
464        };
465       
466        EditArea.prototype.get_translation= function(word, mode){
467                if(mode=="template")
468                        return parent.editAreaLoader.translate(word, this.settings["language"], mode);
469                else
470                        return parent.editAreaLoader.get_word_translation(word, this.settings["language"]);
471        };
472       
473        EditArea.prototype.add_plugin= function(plug_name, plug_obj){
474                for(var i=0; i<this.settings["plugins"].length; i++){
475                        if(this.settings["plugins"][i]==plug_name){
476                                this.plugins[plug_name]=plug_obj;
477                                plug_obj.baseURL=parent.editAreaLoader.baseURL + "plugins/" + plug_name + "/";
478                                if( typeof(plug_obj.init)=="function" )
479                                        plug_obj.init();
480                        }
481                }
482        };
483       
484        EditArea.prototype.load_css= function(url){
485                try{
486                        link = document.createElement("link");
487                        link.type = "text/css";
488                        link.rel= "stylesheet";
489                        link.media="all";
490                        link.href = url;
491                        head = document.getElementsByTagName("head");
492                        head[0].appendChild(link);
493                }catch(e){
494                        document.write("<link href='"+ url +"' rel='stylesheet' type='text/css' />");
495                }
496        };
497       
498        EditArea.prototype.load_script= function(url){
499                try{
500                        script = document.createElement("script");
501                        script.type = "text/javascript";
502                        script.src  = url;
503                        script.charset= "UTF-8";
504                        head = document.getElementsByTagName("head");
505                        head[0].appendChild(script);
506                }catch(e){
507                        document.write("<script type='text/javascript' src='" + url + "' charset=\"UTF-8\"><"+"/script>");
508                }
509        };
510       
511        // add plugin translation to language translation array
512        EditArea.prototype.add_lang= function(language, values){
513                if(!parent.editAreaLoader.lang[language])
514                        parent.editAreaLoader.lang[language]={};
515                for(var i in values)
516                        parent.editAreaLoader.lang[language][i]= values[i];
517        };
518       
519        // short cut for document.getElementById()
520        function _$(id){return document.getElementById( id );};
521
522        var editArea = new EditArea(); 
523        parent.editAreaLoader.add_event(window, "load", init);
524       
525        function init(){               
526                setTimeout("editArea.init();  ", 10);
527        };
Note: See TracBrowser for help on using the repository browser.