--- /dev/null
+/******\r
+ *\r
+ * EditArea \r
+ * Developped by Christophe Dolivet\r
+ * Released under LGPL, Apache and BSD licenses (use the one you want)\r
+ *\r
+******/\r
+\r
+function EditAreaLoader(){\r
+ var t=this;\r
+ t.version= "0.8.1.1";\r
+ date= new Date();\r
+ t.start_time=date.getTime();\r
+ t.win= "loading"; // window loading state\r
+ t.error= false; // to know if load is interrrupt\r
+ t.baseURL="";\r
+ //t.suffix="";\r
+ t.template="";\r
+ t.lang= {}; // array of loaded speech language\r
+ t.load_syntax= {}; // array of loaded syntax language for highlight mode\r
+ t.syntax= {}; // array of initilized syntax language for highlight mode\r
+ t.loadedFiles= [];\r
+ t.waiting_loading= {}; // files that must be loaded in order to allow the script to really start\r
+ // scripts that must be loaded in the iframe\r
+ t.scripts_to_load= ["elements_functions", "resize_area", "reg_syntax"];\r
+ t.sub_scripts_to_load= ["edit_area", "manage_area" ,"edit_area_functions", "keyboard", "search_replace", "highlight", "regexp"];\r
+ \r
+ t.resize= []; // contain resizing datas\r
+ t.hidden= {}; // store datas of the hidden textareas\r
+ \r
+ t.default_settings= {\r
+ //id: "src" // id of the textarea to transform\r
+ debug: false\r
+ ,smooth_selection: true\r
+ ,font_size: "10" // not for IE\r
+ ,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
+ ,start_highlight: false // if start with highlight\r
+ ,toolbar: "search, go_to_line, fullscreen, |, undo, redo, |, select_font,|, change_smooth_selection, highlight, reset_highlight, word_wrap, |, help"\r
+ ,begin_toolbar: "" // "new_document, save, load, |"\r
+ ,end_toolbar: "" // or end_toolbar\r
+ ,is_multi_files: false // enable the multi file mode (the textarea content is ignored)\r
+ ,allow_resize: "both" // possible values: "no", "both", "x", "y"\r
+ ,show_line_colors: false // if the highlight is disabled for the line currently beeing edited (if enabled => heavy CPU use)\r
+ ,min_width: 400\r
+ ,min_height: 125\r
+ ,replace_tab_by_spaces: false\r
+ ,allow_toggle: true // true or false\r
+ ,language: "en"\r
+ ,syntax: ""\r
+ ,syntax_selection_allow: "basic,brainfuck,c,coldfusion,cpp,css,html,java,js,pas,perl,php,python,ruby,robotstxt,sql,tsql,vb,xml"\r
+ ,display: "onload" // onload or later\r
+ ,max_undo: 30\r
+ ,browsers: "known" // all or known\r
+ ,plugins: "" // comma separated plugin list\r
+ ,gecko_spellcheck: false // enable/disable by default the gecko_spellcheck\r
+ ,fullscreen: false\r
+ ,is_editable: true\r
+ ,cursor_position: "begin"\r
+ ,word_wrap: false // define if the text is wrapped of not in the textarea\r
+ ,autocompletion: false // NOT IMPLEMENTED \r
+ ,load_callback: "" // click on load button (function name)\r
+ ,save_callback: "" // click on save button (function name)\r
+ ,change_callback: "" // textarea onchange trigger (function name)\r
+ ,submit_callback: "" // form submited (function name)\r
+ ,EA_init_callback: "" // EditArea initiliazed (function name)\r
+ ,EA_delete_callback: "" // EditArea deleted (function name)\r
+ ,EA_load_callback: "" // EditArea fully loaded and displayed (function name)\r
+ ,EA_unload_callback: "" // EditArea delete while being displayed (function name)\r
+ ,EA_toggle_on_callback: "" // EditArea toggled on (function name)\r
+ ,EA_toggle_off_callback: "" // EditArea toggled off (function name)\r
+ ,EA_file_switch_on_callback: "" // a new tab is selected (called for the newly selected file)\r
+ ,EA_file_switch_off_callback: "" // a new tab is selected (called for the previously selected file)\r
+ ,EA_file_close_callback: "" // close a tab\r
+ };\r
+ \r
+ t.advanced_buttons = [\r
+ // id, button img, command (it will try to find the translation of "id"), is_file_specific\r
+ ['new_document', 'newdocument.gif', 'new_document', false],\r
+ ['search', 'search.gif', 'show_search', false],\r
+ ['go_to_line', 'go_to_line.gif', 'go_to_line', false],\r
+ ['undo', 'undo.gif', 'undo', true],\r
+ ['redo', 'redo.gif', 'redo', true],\r
+ ['change_smooth_selection', 'smooth_selection.gif', 'change_smooth_selection_mode', true],\r
+ ['reset_highlight', 'reset_highlight.gif', 'resync_highlight', true],\r
+ ['highlight', 'highlight.gif','change_highlight', true],\r
+ ['help', 'help.gif', 'show_help', false],\r
+ ['save', 'save.gif', 'save', false],\r
+ ['load', 'load.gif', 'load', false],\r
+ ['fullscreen', 'fullscreen.gif', 'toggle_full_screen', false],\r
+ ['word_wrap', 'word_wrap.gif', 'toggle_word_wrap', true],\r
+ ['autocompletion', 'autocompletion.gif', 'toggle_autocompletion', true]\r
+ ];\r
+ \r
+ // navigator identification\r
+ t.set_browser_infos(t);\r
+\r
+ if(t.isIE>=6 || t.isGecko || ( t.isWebKit && !t.isSafari<3 ) || t.isOpera>=9 || t.isCamino )\r
+ t.isValidBrowser=true;\r
+ else\r
+ t.isValidBrowser=false;\r
+\r
+ t.set_base_url(); \r
+ \r
+ for(var i=0; i<t.scripts_to_load.length; i++){\r
+ 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
+ t.waiting_loading[t.scripts_to_load[i]+ ".js"]= false;\r
+ }\r
+ t.add_event(window, "load", EditAreaLoader.prototype.window_loaded);\r
+};\r
+ \r
+EditAreaLoader.prototype ={\r
+ has_error : function(){\r
+ this.error= true;\r
+ // set to empty all EditAreaLoader functions\r
+ for(var i in EditAreaLoader.prototype){\r
+ EditAreaLoader.prototype[i]=function(){}; \r
+ }\r
+ },\r
+ \r
+ // add browser informations to the object passed in parameter\r
+ set_browser_infos : function(o){\r
+ ua= navigator.userAgent;\r
+ \r
+ // general detection\r
+ o.isWebKit = /WebKit/.test(ua);\r
+ o.isGecko = !o.isWebKit && /Gecko/.test(ua);\r
+ o.isMac = /Mac/.test(ua);\r
+ \r
+ o.isIE = (navigator.appName == "Microsoft Internet Explorer");\r
+ if(o.isIE){\r
+ o.isIE = ua.replace(/^.*?MSIE\s+([0-9\.]+).*$/, "$1");\r
+ if(o.isIE<6)\r
+ o.has_error();\r
+ }\r
+\r
+ if(o.isOpera = (ua.indexOf('Opera') != -1)){ \r
+ o.isOpera= ua.replace(/^.*?Opera.*?([0-9\.]+).*$/i, "$1");\r
+ if(o.isOpera<9)\r
+ o.has_error();\r
+ o.isIE=false; \r
+ }\r
+\r
+ if(o.isFirefox =(ua.indexOf('Firefox') != -1))\r
+ o.isFirefox = ua.replace(/^.*?Firefox.*?([0-9\.]+).*$/i, "$1");\r
+ // Firefox clones \r
+ if( ua.indexOf('Iceweasel') != -1 )\r
+ o.isFirefox = ua.replace(/^.*?Iceweasel.*?([0-9\.]+).*$/i, "$1");\r
+ if( ua.indexOf('GranParadiso') != -1 )\r
+ o.isFirefox = ua.replace(/^.*?GranParadiso.*?([0-9\.]+).*$/i, "$1");\r
+ if( ua.indexOf('BonEcho') != -1 )\r
+ o.isFirefox = ua.replace(/^.*?BonEcho.*?([0-9\.]+).*$/i, "$1");\r
+ if( ua.indexOf('SeaMonkey') != -1)\r
+ o.isFirefox = (ua.replace(/^.*?SeaMonkey.*?([0-9\.]+).*$/i, "$1") ) + 1;\r
+ \r
+ if(o.isCamino =(ua.indexOf('Camino') != -1))\r
+ o.isCamino = ua.replace(/^.*?Camino.*?([0-9\.]+).*$/i, "$1");\r
+ \r
+ if(o.isSafari =(ua.indexOf('Safari') != -1))\r
+ o.isSafari= ua.replace(/^.*?Version\/([0-9]+\.[0-9]+).*$/i, "$1");\r
+ \r
+ if(o.isChrome =(ua.indexOf('Chrome') != -1)) {\r
+ o.isChrome = ua.replace(/^.*?Chrome.*?([0-9\.]+).*$/i, "$1");\r
+ o.isSafari = false;\r
+ }\r
+ \r
+ },\r
+ \r
+ window_loaded : function(){\r
+ editAreaLoader.win="loaded";\r
+ \r
+ // add events on forms\r
+ if (document.forms) {\r
+ for (var i=0; i<document.forms.length; i++) {\r
+ var form = document.forms[i];\r
+ form.edit_area_replaced_submit=null;\r
+ try {\r
+ \r
+ form.edit_area_replaced_submit = form.onsubmit;\r
+ form.onsubmit="";\r
+ } catch (e) {// Do nothing\r
+ }\r
+ editAreaLoader.add_event(form, "submit", EditAreaLoader.prototype.submit);\r
+ editAreaLoader.add_event(form, "reset", EditAreaLoader.prototype.reset);\r
+ }\r
+ }\r
+ editAreaLoader.add_event(window, "unload", function(){for(var i in editAreas){editAreaLoader.delete_instance(i);}}); // ini callback\r
+ },\r
+ \r
+ // init the checkup of the selection of the IE textarea\r
+ init_ie_textarea : function(id){\r
+ var a=document.getElementById(id);\r
+ try{\r
+ if(a && typeof(a.focused)=="undefined"){\r
+ a.focus();\r
+ a.focused=true;\r
+ a.selectionStart= a.selectionEnd= 0; \r
+ get_IE_selection(a);\r
+ editAreaLoader.add_event(a, "focus", IE_textarea_focus);\r
+ editAreaLoader.add_event(a, "blur", IE_textarea_blur);\r
+ \r
+ }\r
+ }catch(ex){}\r
+ },\r
+ \r
+ init : function(settings){\r
+ var t=this,s=settings,i;\r
+ \r
+ if(!s["id"])\r
+ t.has_error();\r
+ if(t.error)\r
+ return;\r
+ // if an instance of the editor already exists for this textarea => delete the previous one\r
+ if(editAreas[s["id"]])\r
+ t.delete_instance(s["id"]);\r
+ \r
+ // init settings\r
+ for(i in t.default_settings){\r
+ if(typeof(s[i])=="undefined")\r
+ s[i]=t.default_settings[i];\r
+ }\r
+ \r
+ if(s["browsers"]=="known" && t.isValidBrowser==false){\r
+ return;\r
+ }\r
+ \r
+ if(s["begin_toolbar"].length>0)\r
+ s["toolbar"]= s["begin_toolbar"] +","+ s["toolbar"];\r
+ if(s["end_toolbar"].length>0)\r
+ s["toolbar"]= s["toolbar"] +","+ s["end_toolbar"];\r
+ s["tab_toolbar"]= s["toolbar"].replace(/ /g,"").split(",");\r
+ \r
+ s["plugins"]= s["plugins"].replace(/ /g,"").split(",");\r
+ for(i=0; i<s["plugins"].length; i++){\r
+ if(s["plugins"][i].length==0)\r
+ s["plugins"].splice(i,1);\r
+ }\r
+ // alert(settings["plugins"].length+": "+ settings["plugins"].join(","));\r
+ t.get_template();\r
+ t.load_script(t.baseURL + "langs/"+ s["language"] + ".js");\r
+ \r
+ if(s["syntax"].length>0){\r
+ s["syntax"]=s["syntax"].toLowerCase();\r
+ t.load_script(t.baseURL + "reg_syntax/"+ s["syntax"] + ".js");\r
+ }\r
+ //alert(this.template);\r
+ \r
+ editAreas[s["id"]]= {"settings": s};\r
+ editAreas[s["id"]]["displayed"]=false;\r
+ editAreas[s["id"]]["hidden"]=false;\r
+ \r
+ //if(settings["display"]=="onload")\r
+ t.start(s["id"]);\r
+ },\r
+ \r
+ // delete an instance of an EditArea\r
+ delete_instance : function(id){\r
+ var d=document,fs=window.frames,span,iframe;\r
+ editAreaLoader.execCommand(id, "EA_delete");\r
+ if(fs["frame_"+id] && fs["frame_"+id].editArea)\r
+ {\r
+ if(editAreas[id]["displayed"])\r
+ editAreaLoader.toggle(id, "off");\r
+ fs["frame_"+id].editArea.execCommand("EA_unload");\r
+ }\r
+\r
+ // remove toggle infos and debug textarea\r
+ span= d.getElementById("EditAreaArroundInfos_"+id);\r
+ if(span)\r
+ span.parentNode.removeChild(span);\r
+\r
+ // remove the iframe\r
+ iframe= d.getElementById("frame_"+id);\r
+ if(iframe){\r
+ iframe.parentNode.removeChild(iframe);\r
+ //delete iframe;\r
+ try {\r
+ delete fs["frame_"+id];\r
+ } catch (e) {// Do nothing\r
+ }\r
+ } \r
+\r
+ delete editAreas[id];\r
+ },\r
+\r
+ \r
+ start : function(id){\r
+ var t=this,d=document,f,span,father,next,html='',html_toolbar_content='',template,content,i;\r
+ \r
+ // check that the window is loaded\r
+ if(t.win!="loaded"){\r
+ setTimeout("editAreaLoader.start('"+id+"');", 50);\r
+ return;\r
+ }\r
+ \r
+ // check that all needed scripts are loaded\r
+ for( i in t.waiting_loading){\r
+ if(t.waiting_loading[i]!="loaded" && typeof(t.waiting_loading[i])!="function"){\r
+ setTimeout("editAreaLoader.start('"+id+"');", 50);\r
+ return;\r
+ }\r
+ }\r
+ \r
+ // wait until language and syntax files are loaded\r
+ if(!t.lang[editAreas[id]["settings"]["language"]] || (editAreas[id]["settings"]["syntax"].length>0 && !t.load_syntax[editAreas[id]["settings"]["syntax"]]) ){\r
+ setTimeout("editAreaLoader.start('"+id+"');", 50);\r
+ return;\r
+ }\r
+ // init the regexp for syntax highlight\r
+ if(editAreas[id]["settings"]["syntax"].length>0)\r
+ t.init_syntax_regexp();\r
+ \r
+ \r
+ // display toggle option and debug area\r
+ if(!d.getElementById("EditAreaArroundInfos_"+id) && (editAreas[id]["settings"]["debug"] || editAreas[id]["settings"]["allow_toggle"]))\r
+ {\r
+ span= d.createElement("span");\r
+ span.id= "EditAreaArroundInfos_"+id;\r
+ if(editAreas[id]["settings"]["allow_toggle"]){\r
+ checked=(editAreas[id]["settings"]["display"]=="onload")?"checked='checked'":"";\r
+ html+="<div id='edit_area_toggle_"+i+"'>";\r
+ html+="<input id='edit_area_toggle_checkbox_"+ id +"' class='toggle_"+ id +"' type='checkbox' onclick='editAreaLoader.toggle(\""+ id +"\");' accesskey='e' "+checked+" />";\r
+ html+="<label for='edit_area_toggle_checkbox_"+ id +"'>{$toggle}</label></div>"; \r
+ }\r
+ if(editAreas[id]["settings"]["debug"])\r
+ 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
+ html= t.translate(html, editAreas[id]["settings"]["language"]); \r
+ span.innerHTML= html; \r
+ father= d.getElementById(id).parentNode;\r
+ next= d.getElementById(id).nextSibling;\r
+ if(next==null)\r
+ father.appendChild(span);\r
+ else\r
+ father.insertBefore(span, next);\r
+ }\r
+ \r
+ if(!editAreas[id]["initialized"])\r
+ {\r
+ t.execCommand(id, "EA_init"); // ini callback\r
+ if(editAreas[id]["settings"]["display"]=="later"){\r
+ editAreas[id]["initialized"]= true;\r
+ return;\r
+ }\r
+ }\r
+ \r
+ if(t.isIE){ // launch IE selection checkup\r
+ t.init_ie_textarea(id);\r
+ }\r
+ \r
+ // get toolbar content\r
+ area=editAreas[id];\r
+ \r
+ for(i=0; i<area["settings"]["tab_toolbar"].length; i++){\r
+ // alert(this.tab_toolbar[i]+"\n"+ this.get_control_html(this.tab_toolbar[i]));\r
+ html_toolbar_content+= t.get_control_html(area["settings"]["tab_toolbar"][i], area["settings"]["language"]);\r
+ }\r
+ // translate toolbar text here for chrome 2\r
+ html_toolbar_content = t.translate(html_toolbar_content, area["settings"]["language"], "template"); \r
+ \r
+ \r
+ // create javascript import rules for the iframe if the javascript has not been already loaded by the compressor\r
+ if(!t.iframe_script){\r
+ t.iframe_script="";\r
+ for(i=0; i<t.sub_scripts_to_load.length; i++)\r
+ t.iframe_script+='<script language="javascript" type="text/javascript" src="'+ t.baseURL + t.sub_scripts_to_load[i] +'.js"></script>';\r
+ }\r
+ \r
+ // add plugins scripts if not already loaded by the compressor (but need to load language in all the case)\r
+ for(i=0; i<area["settings"]["plugins"].length; i++){\r
+ //if(typeof(area["settings"]["plugins"][i])=="function") continue;\r
+ if(!t.all_plugins_loaded)\r
+ t.iframe_script+='<script language="javascript" type="text/javascript" src="'+ t.baseURL + 'plugins/' + area["settings"]["plugins"][i] + '/' + area["settings"]["plugins"][i] +'.js"></script>';\r
+ t.iframe_script+='<script language="javascript" type="text/javascript" src="'+ t.baseURL + 'plugins/' + area["settings"]["plugins"][i] + '/langs/' + area["settings"]["language"] +'.js"></script>';\r
+ }\r
+ \r
+ \r
+ // create css link for the iframe if the whole css text has not been already loaded by the compressor\r
+ if(!t.iframe_css){\r
+ t.iframe_css="<link href='"+ t.baseURL +"edit_area.css' rel='stylesheet' type='text/css' />";\r
+ }\r
+ \r
+ \r
+ // create template\r
+ template= t.template.replace(/\[__BASEURL__\]/g, t.baseURL);\r
+ template= template.replace("[__TOOLBAR__]",html_toolbar_content);\r
+ \r
+ \r
+ // fill template with good language sentences\r
+ template= t.translate(template, area["settings"]["language"], "template");\r
+ \r
+ // add css_code\r
+ template= template.replace("[__CSSRULES__]", t.iframe_css); \r
+ // add js_code\r
+ template= template.replace("[__JSCODE__]", t.iframe_script);\r
+ \r
+ // add version_code\r
+ template= template.replace("[__EA_VERSION__]", t.version);\r
+ //template=template.replace(/\{\$([^\}]+)\}/gm, this.traduc_template);\r
+ \r
+ //editAreas[area["settings"]["id"]]["template"]= template;\r
+ \r
+ area.textarea=d.getElementById(area["settings"]["id"]);\r
+ editAreas[area["settings"]["id"]]["textarea"]=area.textarea;\r
+ \r
+ // if removing previous instances from DOM before (fix from Marcin)\r
+ if(typeof(window.frames["frame_"+area["settings"]["id"]])!='undefined') \r
+ delete window.frames["frame_"+area["settings"]["id"]];\r
+ \r
+ // insert template in the document after the textarea\r
+ father= area.textarea.parentNode;\r
+ /* var container= document.createElement("div");\r
+ container.id= "EditArea_frame_container_"+area["settings"]["id"];\r
+ */ \r
+ content= d.createElement("iframe");\r
+ content.name= "frame_"+area["settings"]["id"];\r
+ content.id= "frame_"+area["settings"]["id"];\r
+ content.style.borderWidth= "0px";\r
+ setAttribute(content, "frameBorder", "0"); // IE\r
+ content.style.overflow="hidden";\r
+ content.style.display="none";\r
+\r
+ \r
+ next= area.textarea.nextSibling;\r
+ if(next==null)\r
+ father.appendChild(content);\r
+ else\r
+ father.insertBefore(content, next) ; \r
+ f=window.frames["frame_"+area["settings"]["id"]];\r
+ f.document.open();\r
+ f.editAreas=editAreas;\r
+ f.area_id= area["settings"]["id"]; \r
+ f.document.area_id= area["settings"]["id"]; \r
+ f.document.write(template);\r
+ f.document.close();\r
+\r
+ // frame.editAreaLoader=this;\r
+ //editAreas[area["settings"]["id"]]["displayed"]=true;\r
+ \r
+ },\r
+ \r
+ toggle : function(id, toggle_to){\r
+\r
+ /* if((editAreas[id]["displayed"]==true && toggle_to!="on") || toggle_to=="off"){\r
+ this.toggle_off(id);\r
+ }else if((editAreas[id]["displayed"]==false && toggle_to!="off") || toggle_to=="on"){\r
+ this.toggle_on(id);\r
+ }*/\r
+ if(!toggle_to)\r
+ toggle_to= (editAreas[id]["displayed"]==true)?"off":"on";\r
+ if(editAreas[id]["displayed"]==true && toggle_to=="off"){\r
+ this.toggle_off(id);\r
+ }else if(editAreas[id]["displayed"]==false && toggle_to=="on"){\r
+ this.toggle_on(id);\r
+ }\r
+ \r
+ return false;\r
+ },\r
+ \r
+ // static function\r
+ toggle_off : function(id){\r
+ var fs=window.frames,f,t,parNod,nxtSib,selStart,selEnd,scrollTop,scrollLeft;\r
+ if(fs["frame_"+id])\r
+ { \r
+ f = fs["frame_"+id];\r
+ t = editAreas[id]["textarea"];\r
+ if(f.editArea.fullscreen['isFull'])\r
+ f.editArea.toggle_full_screen(false);\r
+ editAreas[id]["displayed"]=false;\r
+ \r
+ // set wrap to off to keep same display mode (some browser get problem with this, so it need more complex operation \r
+ t.wrap = "off"; // for IE\r
+ setAttribute(t, "wrap", "off"); // for Firefox \r
+ parNod = t.parentNode;\r
+ nxtSib = t.nextSibling;\r
+ parNod.removeChild(t); \r
+ parNod.insertBefore(t, nxtSib);\r
+ \r
+ // restore values\r
+ t.value= f.editArea.textarea.value;\r
+ selStart = f.editArea.last_selection["selectionStart"];\r
+ selEnd = f.editArea.last_selection["selectionEnd"];\r
+ scrollTop = f.document.getElementById("result").scrollTop;\r
+ scrollLeft = f.document.getElementById("result").scrollLeft;\r
+ \r
+ \r
+ document.getElementById("frame_"+id).style.display='none';\r
+ \r
+ t.style.display="inline";\r
+\r
+ try{ // IE will give an error when trying to focus an invisible or disabled textarea\r
+ t.focus();\r
+ } catch(e){};\r
+ if(this.isIE){\r
+ t.selectionStart= selStart;\r
+ t.selectionEnd = selEnd;\r
+ t.focused = true;\r
+ set_IE_selection(t);\r
+ }else{\r
+ if(this.isOpera && this.isOpera < 9.6 ){ // Opera bug when moving selection start and selection end\r
+ t.setSelectionRange(0, 0);\r
+ }\r
+ try{\r
+ t.setSelectionRange(selStart, selEnd);\r
+ } catch(e) {};\r
+ }\r
+ t.scrollTop= scrollTop;\r
+ t.scrollLeft= scrollLeft;\r
+ f.editArea.execCommand("toggle_off");\r
+\r
+ }\r
+ }, \r
+ \r
+ // static function\r
+ toggle_on : function(id){\r
+ var fs=window.frames,f,t,selStart=0,selEnd=0,scrollTop=0,scrollLeft=0,curPos,elem;\r
+ \r
+ if(fs["frame_"+id])\r
+ {\r
+ f = fs["frame_"+id];\r
+ t = editAreas[id]["textarea"];\r
+ area= f.editArea;\r
+ area.textarea.value= t.value;\r
+ \r
+ // store display values;\r
+ curPos = editAreas[id]["settings"]["cursor_position"];\r
+\r
+ if(t.use_last==true)\r
+ {\r
+ selStart = t.last_selectionStart;\r
+ selEnd = t.last_selectionEnd;\r
+ scrollTop = t.last_scrollTop;\r
+ scrollLeft = t.last_scrollLeft;\r
+ t.use_last=false;\r
+ }\r
+ else if( curPos == "auto" )\r
+ {\r
+ try{\r
+ selStart = t.selectionStart;\r
+ selEnd = t.selectionEnd;\r
+ scrollTop = t.scrollTop;\r
+ scrollLeft = t.scrollLeft;\r
+ //alert(scrollTop);\r
+ }catch(ex){}\r
+ }\r
+ \r
+ // set to good size\r
+ this.set_editarea_size_from_textarea(id, document.getElementById("frame_"+id));\r
+ t.style.display="none"; \r
+ document.getElementById("frame_"+id).style.display="inline";\r
+ area.execCommand("focus"); // without this focus opera doesn't manage well the iframe body height\r
+ \r
+ \r
+ // restore display values\r
+ editAreas[id]["displayed"]=true;\r
+ area.execCommand("update_size");\r
+ \r
+ f.document.getElementById("result").scrollTop= scrollTop;\r
+ f.document.getElementById("result").scrollLeft= scrollLeft;\r
+ area.area_select(selStart, selEnd-selStart);\r
+ area.execCommand("toggle_on");\r
+\r
+ \r
+ }\r
+ else\r
+ {\r
+ /* if(this.isIE)\r
+ get_IE_selection(document.getElementById(id)); */ \r
+ elem= document.getElementById(id); \r
+ elem.last_selectionStart= elem.selectionStart;\r
+ elem.last_selectionEnd= elem.selectionEnd;\r
+ elem.last_scrollTop= elem.scrollTop;\r
+ elem.last_scrollLeft= elem.scrollLeft;\r
+ elem.use_last=true;\r
+ editAreaLoader.start(id);\r
+ }\r
+ }, \r
+ \r
+ set_editarea_size_from_textarea : function(id, frame){ \r
+ var elem,width,height;\r
+ elem = document.getElementById(id);\r
+ \r
+ width = Math.max(editAreas[id]["settings"]["min_width"], elem.offsetWidth)+"px";\r
+ height = Math.max(editAreas[id]["settings"]["min_height"], elem.offsetHeight)+"px";\r
+ if(elem.style.width.indexOf("%")!=-1)\r
+ width = elem.style.width;\r
+ if(elem.style.height.indexOf("%")!=-1)\r
+ height = elem.style.height;\r
+ //alert("h: "+height+" w: "+width);\r
+ \r
+ frame.style.width= width;\r
+ frame.style.height= height;\r
+ },\r
+ \r
+ set_base_url : function(){\r
+ var t=this,elems,i,docBasePath;\r
+\r
+ if( !this.baseURL ){\r
+ elems = document.getElementsByTagName('script');\r
+ \r
+ for( i=0; i<elems.length; i++ ){\r
+ if (elems[i].src && elems[i].src.match(/edit_area_[^\\\/]*$/i) ) {\r
+ var src = elems[i].src;\r
+ src = src.substring(0, src.lastIndexOf('/'));\r
+ this.baseURL = src;\r
+ this.file_name= elems[i].src.substr(elems[i].src.lastIndexOf("/")+1);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ \r
+ docBasePath = document.location.href;\r
+ if (docBasePath.indexOf('?') != -1)\r
+ docBasePath = docBasePath.substring(0, docBasePath.indexOf('?'));\r
+ docBasePath = docBasePath.substring(0, docBasePath.lastIndexOf('/'));\r
+ \r
+ // If not HTTP absolute\r
+ if (t.baseURL.indexOf('://') == -1 && t.baseURL.charAt(0) != '/') {\r
+ // If site absolute\r
+ t.baseURL = docBasePath + "/" + t.baseURL;\r
+ }\r
+ t.baseURL +="/"; \r
+ },\r
+ \r
+ get_button_html : function(id, img, exec, isFileSpecific, baseURL) {\r
+ var cmd,html;\r
+ if(!baseURL)\r
+ baseURL= this.baseURL;\r
+ cmd = 'editArea.execCommand(\'' + exec + '\')';\r
+ html = '<a id="a_'+ id +'" href="javascript:' + cmd + '" onclick="' + cmd + ';return false;" onmousedown="return false;" target="_self" fileSpecific="'+ (isFileSpecific?'yes':'no') +'">';\r
+ 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
+ return html;\r
+ },\r
+\r
+ get_control_html : function(button_name, lang) { \r
+ var t=this,i,but,html,si;\r
+ for (i=0; i<t.advanced_buttons.length; i++)\r
+ {\r
+ but = t.advanced_buttons[i]; \r
+ if (but[0] == button_name)\r
+ {\r
+ return t.get_button_html(but[0], but[1], but[2], but[3]);\r
+ } \r
+ } \r
+ \r
+ switch (button_name){\r
+ case "*":\r
+ case "return":\r
+ return "<br />";\r
+ case "|":\r
+ case "separator":\r
+ return '<img src="'+ t.baseURL +'images/spacer.gif" width="1" height="15" class="editAreaSeparatorLine">';\r
+ case "select_font":\r
+ html= "<select id='area_font_size' onchange='javascript:editArea.execCommand(\"change_font_size\")' fileSpecific='yes'>";\r
+ html+="<option value='-1'>{$font_size}</option>";\r
+ si=[8,9,10,11,12,14];\r
+ for( i=0;i<si.length;i++){\r
+ html+="<option value='"+si[i]+"'>"+si[i]+" pt</option>";\r
+ }\r
+ html+="</select>";\r
+ return html;\r
+ case "syntax_selection":\r
+ html= "<select id='syntax_selection' onchange='javascript:editArea.execCommand(\"change_syntax\", this.value)' fileSpecific='yes'>";\r
+ html+="<option value='-1'>{$syntax_selection}</option>";\r
+ html+="</select>";\r
+ return html;\r
+ }\r
+ \r
+ return "<span id='tmp_tool_"+button_name+"'>["+button_name+"]</span>"; \r
+ },\r
+ \r
+ \r
+ get_template : function(){\r
+ if(this.template=="")\r
+ {\r
+ var xhr_object = null; \r
+ if(window.XMLHttpRequest) // Firefox \r
+ xhr_object = new XMLHttpRequest(); \r
+ else if(window.ActiveXObject) // Internet Explorer \r
+ xhr_object = new ActiveXObject("Microsoft.XMLHTTP"); \r
+ else { // XMLHttpRequest not supported\r
+ alert("XMLHTTPRequest not supported. EditArea not loaded"); \r
+ return; \r
+ } \r
+ \r
+ xhr_object.open("GET", this.baseURL+"template.html", false); \r
+ xhr_object.send(null); \r
+ if(xhr_object.readyState == 4) \r
+ this.template=xhr_object.responseText;\r
+ else\r
+ this.has_error();\r
+ }\r
+ },\r
+ \r
+ // translate text\r
+ translate : function(text, lang, mode){\r
+ if(mode=="word")\r
+ text=editAreaLoader.get_word_translation(text, lang);\r
+ else if(mode="template"){\r
+ editAreaLoader.current_language= lang;\r
+ text=text.replace(/\{\$([^\}]+)\}/gm, editAreaLoader.translate_template);\r
+ }\r
+ return text;\r
+ },\r
+ \r
+ translate_template : function(){\r
+ return editAreaLoader.get_word_translation(EditAreaLoader.prototype.translate_template.arguments[1], editAreaLoader.current_language);\r
+ },\r
+ \r
+ get_word_translation : function(val, lang){\r
+ var i;\r
+ \r
+ for( i in editAreaLoader.lang[lang]){\r
+ if(i == val)\r
+ return editAreaLoader.lang[lang][i];\r
+ }\r
+ return "_"+val;\r
+ },\r
+ \r
+ load_script : function(url){\r
+ var t=this,d=document,script,head;\r
+ \r
+ if( t.loadedFiles[url] )\r
+ return; \r
+ //alert("load: "+url);\r
+ try{\r
+ script= d.createElement("script");\r
+ script.type= "text/javascript";\r
+ script.src= url;\r
+ script.charset= "UTF-8";\r
+ d.getElementsByTagName("head")[0].appendChild(script);\r
+ }catch(e){\r
+ d.write('<sc'+'ript language="javascript" type="text/javascript" src="' + url + '" charset="UTF-8"></sc'+'ript>');\r
+ }\r
+ \r
+ t.loadedFiles[url] = true;\r
+ },\r
+ \r
+ add_event : function(obj, name, handler) {\r
+ try{\r
+ if (obj.attachEvent) {\r
+ obj.attachEvent("on" + name, handler);\r
+ } else{\r
+ obj.addEventListener(name, handler, false);\r
+ }\r
+ }catch(e){}\r
+ },\r
+ \r
+ remove_event : function(obj, name, handler){\r
+ try{\r
+ if (obj.detachEvent)\r
+ obj.detachEvent("on" + name, handler);\r
+ else\r
+ obj.removeEventListener(name, handler, false);\r
+ }catch(e){}\r
+ },\r
+\r
+\r
+ // reset all the editareas in the form that have been reseted\r
+ reset : function(e){\r
+ var formObj,is_child,i,x;\r
+ \r
+ formObj = editAreaLoader.isIE ? window.event.srcElement : e.target;\r
+ if(formObj.tagName!='FORM')\r
+ formObj= formObj.form;\r
+ \r
+ for( i in editAreas ){ \r
+ is_child= false;\r
+ for( x=0;x<formObj.elements.length;x++ ) {\r
+ if(formObj.elements[x].id == i)\r
+ is_child=true;\r
+ }\r
+ \r
+ if(window.frames["frame_"+i] && is_child && editAreas[i]["displayed"]==true){\r
+ \r
+ var exec= 'window.frames["frame_'+ i +'"].editArea.textarea.value= document.getElementById("'+ i +'").value;';\r
+ exec+= 'window.frames["frame_'+ i +'"].editArea.execCommand("focus");';\r
+ exec+= 'window.frames["frame_'+ i +'"].editArea.check_line_selection();';\r
+ exec+= 'window.frames["frame_'+ i +'"].editArea.execCommand("reset");';\r
+ window.setTimeout(exec, 10);\r
+ }\r
+ } \r
+ return;\r
+ },\r
+ \r
+ \r
+ // prepare all the textarea replaced by an editarea to be submited\r
+ submit : function(e){ \r
+ var formObj,is_child,fs=window.frames,i,x;\r
+ formObj = editAreaLoader.isIE ? window.event.srcElement : e.target;\r
+ if(formObj.tagName!='FORM')\r
+ formObj= formObj.form;\r
+ \r
+ for( i in editAreas){\r
+ is_child= false;\r
+ for( x=0;x<formObj.elements.length;x++ ) {\r
+ if(formObj.elements[x].id == i)\r
+ is_child=true;\r
+ }\r
+ \r
+ if(is_child)\r
+ {\r
+ if(fs["frame_"+i] && editAreas[i]["displayed"]==true)\r
+ document.getElementById(i).value= fs["frame_"+ i].editArea.textarea.value;\r
+ editAreaLoader.execCommand(i,"EA_submit");\r
+ }\r
+ } \r
+ if( typeof(formObj.edit_area_replaced_submit) == "function" ){\r
+ res= formObj.edit_area_replaced_submit();\r
+ if(res==false){\r
+ if(editAreaLoader.isIE)\r
+ return false;\r
+ else\r
+ e.preventDefault();\r
+ }\r
+ }\r
+ return;\r
+ },\r
+ \r
+ // allow to get the value of the editarea\r
+ getValue : function(id){\r
+ if(window.frames["frame_"+id] && editAreas[id]["displayed"]==true){\r
+ return window.frames["frame_"+ id].editArea.textarea.value; \r
+ }else if(elem=document.getElementById(id)){\r
+ return elem.value;\r
+ }\r
+ return false;\r
+ },\r
+ \r
+ // allow to set the value of the editarea\r
+ setValue : function(id, new_val){\r
+ var fs=window.frames;\r
+ \r
+ if( ( f=fs["frame_"+id] ) && editAreas[id]["displayed"]==true){\r
+ f.editArea.textarea.value= new_val; \r
+ f.editArea.execCommand("focus"); \r
+ f.editArea.check_line_selection(false); \r
+ f.editArea.execCommand("onchange");\r
+ }else if(elem=document.getElementById(id)){\r
+ elem.value= new_val;\r
+ }\r
+ },\r
+ \r
+ // allow to get infos on the selection: array(start, end)\r
+ getSelectionRange : function(id){\r
+ var sel,eA,fs=window.frames;\r
+ \r
+ sel= {"start": 0, "end": 0};\r
+ if(fs["frame_"+id] && editAreas[id]["displayed"]==true){\r
+ eA= fs["frame_"+ id].editArea;\r
+\r
+ sel["start"] = eA.textarea.selectionStart;\r
+ sel["end"] = eA.textarea.selectionEnd;\r
+ \r
+ }else if( elem=document.getElementById(id) ){\r
+ sel= getSelectionRange(elem);\r
+ }\r
+ return sel;\r
+ },\r
+ \r
+ // allow to set the selection with the given start and end positions\r
+ setSelectionRange : function(id, new_start, new_end){\r
+ var fs=window.frames;\r
+ \r
+ if(fs["frame_"+id] && editAreas[id]["displayed"]==true){\r
+ fs["frame_"+ id].editArea.area_select(new_start, new_end-new_start); \r
+ // make an auto-scroll to the selection\r
+ if(!this.isIE){\r
+ fs["frame_"+ id].editArea.check_line_selection(false); \r
+ fs["frame_"+ id].editArea.scroll_to_view();\r
+ } \r
+ }else if(elem=document.getElementById(id)){\r
+ setSelectionRange(elem, new_start, new_end);\r
+ }\r
+ },\r
+ \r
+ getSelectedText : function(id){\r
+ var sel= this.getSelectionRange(id);\r
+ \r
+ return this.getValue(id).substring(sel["start"], sel["end"]);\r
+ },\r
+ \r
+ setSelectedText : function(id, new_val){\r
+ var fs=window.frames,d=document,sel,text,scrollTop,scrollLeft,new_sel_end;\r
+ \r
+ new_val = new_val.replace(/\r/g, ""); \r
+ sel = this.getSelectionRange(id);\r
+ text = this.getValue(id);\r
+ if(fs["frame_"+id] && editAreas[id]["displayed"]==true){\r
+ scrollTop = fs["frame_"+ id].document.getElementById("result").scrollTop;\r
+ scrollLeft = fs["frame_"+ id].document.getElementById("result").scrollLeft;\r
+ }else{\r
+ scrollTop = d.getElementById(id).scrollTop;\r
+ scrollLeft = d.getElementById(id).scrollLeft;\r
+ }\r
+ \r
+ text = text.substring(0, sel["start"])+ new_val +text.substring(sel["end"]);\r
+ this.setValue(id, text);\r
+ new_sel_end = sel["start"]+ new_val.length;\r
+ this.setSelectionRange(id, sel["start"], new_sel_end);\r
+ \r
+ \r
+ // fix \r problem for selection length count on IE & Opera\r
+ if(new_val != this.getSelectedText(id).replace(/\r/g, "")){\r
+ this.setSelectionRange(id, sel["start"], new_sel_end+ new_val.split("\n").length -1);\r
+ }\r
+ // restore scrolling position\r
+ if(fs["frame_"+id] && editAreas[id]["displayed"]==true){\r
+ fs["frame_"+ id].document.getElementById("result").scrollTop= scrollTop;\r
+ fs["frame_"+ id].document.getElementById("result").scrollLeft= scrollLeft;\r
+ fs["frame_"+ id].editArea.execCommand("onchange");\r
+ }else{\r
+ d.getElementById(id).scrollTop= scrollTop;\r
+ d.getElementById(id).scrollLeft= scrollLeft;\r
+ }\r
+ },\r
+ \r
+ insertTags : function(id, open_tag, close_tag){\r
+ var old_sel,new_sel;\r
+ \r
+ old_sel = this.getSelectionRange(id);\r
+ text = open_tag + this.getSelectedText(id) + close_tag;\r
+ \r
+ editAreaLoader.setSelectedText(id, text);\r
+ \r
+ new_sel = this.getSelectionRange(id);\r
+ if(old_sel["end"] > old_sel["start"]) // if text was selected, cursor at the end\r
+ this.setSelectionRange(id, new_sel["end"], new_sel["end"]);\r
+ else // cursor in the middle\r
+ this.setSelectionRange(id, old_sel["start"]+open_tag.length, old_sel["start"]+open_tag.length);\r
+ },\r
+ \r
+ // hide both EditArea and normal textarea\r
+ hide : function(id){\r
+ var fs= window.frames,d=document,t=this,scrollTop,scrollLeft,span;\r
+ if(d.getElementById(id) && !t.hidden[id])\r
+ {\r
+ t.hidden[id]= {};\r
+ t.hidden[id]["selectionRange"]= t.getSelectionRange(id);\r
+ if(d.getElementById(id).style.display!="none")\r
+ {\r
+ t.hidden[id]["scrollTop"]= d.getElementById(id).scrollTop;\r
+ t.hidden[id]["scrollLeft"]= d.getElementById(id).scrollLeft;\r
+ }\r
+ \r
+ if(fs["frame_"+id])\r
+ {\r
+ t.hidden[id]["toggle"]= editAreas[id]["displayed"];\r
+ \r
+ if(fs["frame_"+id] && editAreas[id]["displayed"]==true){\r
+ scrollTop = fs["frame_"+ id].document.getElementById("result").scrollTop;\r
+ scrollLeft = fs["frame_"+ id].document.getElementById("result").scrollLeft;\r
+ }else{\r
+ scrollTop = d.getElementById(id).scrollTop;\r
+ scrollLeft = d.getElementById(id).scrollLeft;\r
+ }\r
+ t.hidden[id]["scrollTop"]= scrollTop;\r
+ t.hidden[id]["scrollLeft"]= scrollLeft;\r
+ \r
+ if(editAreas[id]["displayed"]==true)\r
+ editAreaLoader.toggle_off(id);\r
+ }\r
+ \r
+ // hide toggle button and debug box\r
+ span= d.getElementById("EditAreaArroundInfos_"+id);\r
+ if(span){\r
+ span.style.display='none';\r
+ }\r
+ \r
+ // hide textarea\r
+ d.getElementById(id).style.display= "none";\r
+ }\r
+ },\r
+ \r
+ // restore hidden EditArea and normal textarea\r
+ show : function(id){\r
+ var fs= window.frames,d=document,t=this,span;\r
+ if((elem=d.getElementById(id)) && t.hidden[id])\r
+ {\r
+ elem.style.display= "inline";\r
+ elem.scrollTop= t.hidden[id]["scrollTop"];\r
+ elem.scrollLeft= t.hidden[id]["scrollLeft"];\r
+ span= d.getElementById("EditAreaArroundInfos_"+id);\r
+ if(span){\r
+ span.style.display='inline';\r
+ }\r
+ \r
+ if(fs["frame_"+id])\r
+ {\r
+ \r
+ // restore toggle button and debug box\r
+ \r
+ \r
+ // restore textarea\r
+ elem.style.display= "inline";\r
+ \r
+ // restore EditArea\r
+ if(t.hidden[id]["toggle"]==true)\r
+ editAreaLoader.toggle_on(id);\r
+ \r
+ scrollTop = t.hidden[id]["scrollTop"];\r
+ scrollLeft = t.hidden[id]["scrollLeft"];\r
+ \r
+ if(fs["frame_"+id] && editAreas[id]["displayed"]==true){\r
+ fs["frame_"+ id].document.getElementById("result").scrollTop = scrollTop;\r
+ fs["frame_"+ id].document.getElementById("result").scrollLeft = scrollLeft;\r
+ }else{\r
+ elem.scrollTop = scrollTop;\r
+ elem.scrollLeft = scrollLeft;\r
+ }\r
+ \r
+ }\r
+ // restore selection\r
+ sel = t.hidden[id]["selectionRange"];\r
+ t.setSelectionRange(id, sel["start"], sel["end"]);\r
+ delete t.hidden[id]; \r
+ }\r
+ },\r
+ \r
+ // get the current file datas (for multi file editing mode)\r
+ getCurrentFile : function(id){\r
+ return this.execCommand(id, 'get_file', this.execCommand(id, 'curr_file'));\r
+ },\r
+ \r
+ // get the given file datas (for multi file editing mode)\r
+ getFile : function(id, file_id){\r
+ return this.execCommand(id, 'get_file', file_id);\r
+ },\r
+ \r
+ // get all the openned files datas (for multi file editing mode)\r
+ getAllFiles : function(id){\r
+ return this.execCommand(id, 'get_all_files()');\r
+ },\r
+ \r
+ // open a file (for multi file editing mode)\r
+ openFile : function(id, file_infos){\r
+ return this.execCommand(id, 'open_file', file_infos);\r
+ },\r
+ \r
+ // close the given file (for multi file editing mode)\r
+ closeFile : function(id, file_id){\r
+ return this.execCommand(id, 'close_file', file_id);\r
+ },\r
+ \r
+ // close the given file (for multi file editing mode)\r
+ setFileEditedMode : function(id, file_id, to){\r
+ var reg1,reg2;\r
+ reg1 = new RegExp('\\\\', 'g');\r
+ reg2 = new RegExp('"', 'g');\r
+ return this.execCommand(id, 'set_file_edited_mode("'+ file_id.replace(reg1, '\\\\').replace(reg2, '\\"') +'", '+ to +')');\r
+ },\r
+ \r
+ \r
+ // allow to access to editarea functions and datas (for advanced users only)\r
+ execCommand : function(id, cmd, fct_param){\r
+ switch(cmd){\r
+ case "EA_init":\r
+ if(editAreas[id]['settings']["EA_init_callback"].length>0)\r
+ eval(editAreas[id]['settings']["EA_init_callback"]+"('"+ id +"');");\r
+ break;\r
+ case "EA_delete":\r
+ if(editAreas[id]['settings']["EA_delete_callback"].length>0)\r
+ eval(editAreas[id]['settings']["EA_delete_callback"]+"('"+ id +"');");\r
+ break;\r
+ case "EA_submit":\r
+ if(editAreas[id]['settings']["submit_callback"].length>0)\r
+ eval(editAreas[id]['settings']["submit_callback"]+"('"+ id +"');");\r
+ break;\r
+ }\r
+ if(window.frames["frame_"+id] && window.frames["frame_"+ id].editArea){\r
+ if(fct_param!=undefined)\r
+ return eval('window.frames["frame_'+ id +'"].editArea.'+ cmd +'(fct_param);');\r
+ else\r
+ return eval('window.frames["frame_'+ id +'"].editArea.'+ cmd +';'); \r
+ }\r
+ return false;\r
+ }\r
+};\r
+ \r
+ var editAreaLoader= new EditAreaLoader();\r
+ var editAreas= {};\r
+\r