Artifact 89cf1ff3b6a65f2362b88d40fc8d6e82d13bf4da:


(function(){window.textEditor=function(a){if(!document.getElementById(a))throw new Error("Invalid ID parameter: "+a);this.id=a;this.textarea=document.getElementById(a);this.shortcuts=[];if(!('selectionStart' in this.textarea))return false;this.preventKeyPress=false;this.textarea.addEventListener('keydown',this.keyEvent.bind(this),true);this.textarea.addEventListener('keypress',this.keyEvent.bind(this),true);return true;};textEditor.prototype.keyEvent=function(a){var a=a||window.event;if(this.preventKeyPress&&a.type=='keypress'){this.preventKeyPress=false;return this.preventDefault(a);}for(var b in this.shortcuts){var c=this.shortcuts[b];if(a.metaKey)continue;if((a.ctrlKey&&!c.ctrl)||(c.ctrl&&!a.ctrlKey))continue;if((a.shiftKey&&!c.shift)||(c.shift&&!a.shiftKey))continue;if((a.altKey&&!c.alt)||(c.alt&&!a.altKey))continue;if(!(b=this.matchKeyPress(c.key,a)))continue;if(typeof c.callback!='function'){var d=(c.ctrl?'Ctrl-':'')+(c.alt?'Alt-':'');d+=(c.shift?'Shift-':'')+c;throw new Error("Invalid callback type for shortcut "+d);}var e=c.callback.call(this,a,b);if(a.type=='keydown'&&e)this.preventKeyPress=true;return e?this.preventDefault(a):true;}return true;};textEditor.prototype.matchKeyPress=function(a,b){if(b.defaultPrevented||!b.key)return;return(b.key.toLowerCase()==a.toLowerCase());};textEditor.prototype.preventDefault=function(a){if(a.preventDefault)a.preventDefault();if(a.stopPropagation)a.stopPropagation();a.returnValue=false;a.cancelBubble=true;return false;};textEditor.prototype.getSelection=function(){var a=this.textarea;var b=a.selectionEnd-a.selectionStart;return{start:a.selectionStart,end:a.selectionEnd,length:b,text:a.value.substr(a.selectionStart,b)};};textEditor.prototype.replaceSelection=function(a,b){var c=this.textarea;var d=a.start;var e=d+b.length;c.value=c.value.substr(0,d)+b+c.value.substr(a.end,c.value.length);this.setSelection(d,e);return{start:d,end:e,length:b.length,text:b};};textEditor.prototype.insertAtPosition=function(a,b,c){var d=a+b.length;var e=this.textarea;e.value=e.value.substr(0,a)+b+e.value.substr(a,e.value.length-a);if(!c)c=d;return this.setSelection(c,c);};textEditor.prototype.setSelection=function(a,b){var c=this.textarea;c.focus();c.selectionStart=a;c.selectionEnd=b;return this.getSelection();};textEditor.prototype.scrollToSelection=function(a){var b=this.textarea;var c=b.value.substr(a.end);b.value=b.value.substr(0,a.end);b.scrollTop=100000;var d=b.scrollTop;b.value+=c;b.scrollTop=d;this.setSelection(a.start,a.end);};textEditor.prototype.wrapSelection=function(a,b,c){var d=this.textarea;var e=d.scrollTop;var f=a.text;var a=this.replaceSelection(a,b+f+c);if(f=='')a=this.setSelection(a.start+b.length,a.start+b.length);d.scrollTop=e;return a;};}());(function(){function a(a){function b(){}b.prototype=a;return new b();}String.prototype.repeat=function(a){return new Array(a+1).join(this);};window.codeEditor=function(a){var b=textEditor.call(this,a);if(!b)return false;this.onlinechange=null;this.onlinenumberchange=null;this.fullscreen=false;this.nb_lines=0;this.current_line=0;this.search_str=null;this.search_pos=0;this.params={indent_size:4,tab_size:4,convert_tabs:true,lang:{search:"Text to search?\n(regexps allowed, begin them with '/')",replace:"Text for replacement?\n(use $1, $2... for regexp replacement)",search_selection:"Text to replace in selection?\n(regexps allowed, begin them with '/')",replace_result:"%d occurence found and replaced.",goto:"Line to go to:",no_search_result:"No search result found."}};that=this;this.init();this.textarea.spellcheck=false;this.shortcuts.push({shift:true,key:'tab',callback:this.indent});this.shortcuts.push({key:'tab',callback:this.indent});this.shortcuts.push({ctrl:true,key:'f',callback:this.search});this.shortcuts.push({ctrl:true,key:'h',callback:this.searchAndReplace});this.shortcuts.push({ctrl:true,key:'g',callback:this.goToLine});this.shortcuts.push({key:'F3',callback:this.searchNext});this.shortcuts.push({key:'backspace',callback:this.backspace});this.shortcuts.push({key:'enter',callback:this.enter});this.shortcuts.push({key:'"',callback:this.insertBrackets});this.shortcuts.push({key:'[',callback:this.insertBrackets});this.shortcuts.push({key:'{',callback:this.insertBrackets});this.shortcuts.push({key:'(',callback:this.insertBrackets});this.shortcuts.push({key:'F11',callback:this.toggleFullscreen});this.textarea.addEventListener('keypress',this.keyEvent.bind(this),true);this.textarea.addEventListener('keydown',this.keyEvent.bind(this),true);};codeEditor.prototype=a(textEditor.prototype);codeEditor.prototype.init=function(){var a=this;this.nb_lines=this.countLines();this.parent=document.createElement('div');this.parent.className='codeEditor';this.lineCounter=document.createElement('span');this.lineCounter.className='lineCount';for(i=1;i<=this.nb_lines;i++)this.lineCounter.innerHTML+='<b>'+i+'</b>';this.lineCounter.innerHTML+='<i>---</i>';this.parent.appendChild(this.lineCounter);var b=document.createElement('div');b.className='container';b.appendChild(this.textarea.cloneNode(true));this.parent.appendChild(b);var c=this.textarea.parentNode;c.appendChild(this.parent);c.removeChild(this.textarea);this.textarea=this.parent.getElementsByTagName('textarea')[0];this.textarea.wrap='off';if(this.params.convert_tabs){this.textarea.value=this.textarea.value.replace(/[ ]{1,7}\t/g,' '.repeat(this.params.tab_size));this.textarea.value=this.textarea.value.replace(/\t/g,' '.repeat(this.params.tab_size));}this.textarea.addEventListener('focus',function(){a.update();},false);this.textarea.addEventListener('keyup',function(){a.update();},false);this.textarea.addEventListener('click',function(){a.update();},false);this.textarea.addEventListener('scroll',function(){a.lineCounter.scrollTop=a.textarea.scrollTop;},false);};codeEditor.prototype.update=function(){var a=this.getSelection();var b=this.getLineNumberFromPosition(a);var c=this.countLines();this.search_pos=a.end;if(c!=this.nb_lines){var d=this.lineCounter.getElementsByTagName('b');for(var e=this.nb_lines;e>c;e--)this.lineCounter.removeChild(d[e-1]);var f=this.lineCounter.lastChild;for(var e=d.length;e<c;e++){var g=document.createElement('b');g.innerHTML=e+1;this.lineCounter.insertBefore(g,f);}this.nb_lines=c;if(typeof this.onlinenumberchange==='function')this.onlinenumberchange.call(this);}if(b!=this.current_line){var d=this.lineCounter.getElementsByTagName('b');for(var e=0;e<this.nb_lines;e++)d[e].className='';d[b].className='current';this.current_line=b;if(typeof this.onlinechange==='function')this.onlinechange.call(this);}};codeEditor.prototype.countLines=function(){var a=this.textarea.value.match(/(\r?\n)/g);return a?a.length+1:1;};codeEditor.prototype.getLineNumberFromPosition=function(a){var a=a||this.getSelection();if(a.start==0)return 0;var b=this.textarea.value.substr(0,a.start).match(/(\r?\n)/g);return b?b.length:0;};codeEditor.prototype.getLines=function(){return this.textarea.value.split("\n");};codeEditor.prototype.getLine=function(a){return this.textarea.value.split("\n",a+1)[a];};codeEditor.prototype.getLinePosition=function(a,b){var c=0;for(i=0;i<a.length;i++){if(i==b)return{start:c+i,end:c+a[i].length,length:a[i].length,text:a[i]};c+=a[i].length;}return false;};codeEditor.prototype.selectLines=function(a){for(var b=a.start;b>0;b--)if(this.textarea.value.substr(b,1)=="\n"){a.start=b+1;break;}for(var b=a.end-1;b<this.textarea.length;b++)if(this.textarea.value.substr(b,1)=="\n"){a.end=b-1;break;}this.setSelection(a.start,a.end);return a;};codeEditor.prototype.goToLine=function(a){var b=window.prompt(that.params.lang.goto);if(!b)return;var c=this.textarea.value.split("\n",parseInt(b,10)).join("\n").length;this.scrollToSelection(this.setSelection(c,c));return true;};codeEditor.prototype.indent=function(a,b){var c=this.getSelection();var d=a.shiftKey;var e=this.getLines();var f=this.getLineNumberFromPosition(c);var g=this.getLinePosition(e,f);var h=(c.end>g.end)?true:false;if((c.length==0||!h)&&c.start!=g.start){this.insertAtPosition(c.start,' '.repeat(this.params.indent_size));return true;}if(c.length==0&&c.start==g.start){var i=(f-1 in e)?e[f-1].match(/^(\s+)/):false;if(!i||g.length!=0)var j=' '.repeat(this.params.indent_size);else var j=' '.repeat(i[1].length);this.insertAtPosition(c.start,j);return true;}c=this.selectLines(c);var k=this.textarea.value.substr(c.start,(c.end-c.start));var e=k.split("\n");if(d){var l=new RegExp('^[ ]{1,'+this.params.indent_size+'}');for(var m=0;m<e.length;m++)e[m]=e[m].replace(l,'');}else for(var m=0;m<e.length;m++)e[m]=' '.repeat(this.params.indent_size)+e[m];k=e.join("\n");this.replaceSelection(c,k);return true;};codeEditor.prototype.search=function(){if(!(this.search_str=window.prompt(this.params.lang.search,this.search_str)))return;this.search_pos=0;return this.searchNext();};codeEditor.prototype.searchNext=function(){if(!this.search_str)return true;var a=this.getSelection();var b=a.end>=this.search_pos?this.search_pos:a.start;var c=this.textarea.value.substr(b);var d=this.getSearchRegexp(this.search_str);var e=c.search(d);if(e==-1)return window.alert(this.params.lang.no_search_result);var f=c.match(d);a.start=b+e;a.end=a.start+f[0].length;a.length=f[0].length;a.text=f[0];this.setSelection(a.start,a.end);this.search_pos=a.end;this.scrollToSelection(a);return true;};codeEditor.prototype.getSearchRegexp=function(a,b){var c,d;if(a.substr(0,1)=='/'){var e=a.lastIndexOf("/");c=a.substr(1,e-1);d=a.substr(e+1).replace(/g/,'');}else{c=a.replace(/([\/$^.?()[\]{}\\])/,'\\$1');d='i';}if(b)d+='g';return new RegExp(c,d);};codeEditor.prototype.searchAndReplace=function(a){var b=this.getSelection();var c=b.length!=0?this.params.lang.search_selection:this.params.lang.search;if(!(s=window.prompt(c,this.search_str))||!(r=window.prompt(that.params.lang.replace)))return true;var d=this.getSearchRegexp(s,true);if(b.length==0){var e=this.textarea.value.match(d).length;this.textarea.value=this.textarea.value.replace(d,r);}else{var e=b.text.match(d).length;this.replaceSelection(b,b.text.replace(d,r));}window.alert(this.params.lang.replace_result.replace(/%d/g,e));return true;};codeEditor.prototype.enter=function(a){var b=this.getSelection();var c=this.getLineNumberFromPosition(b);var d='';c=this.getLine(c);if(this.textarea.value.substr(b.start-1,1)=='{')d+=' '.repeat(this.params.indent_size);if(match=c.match(/^(\s+)/))d+=match[1];if(!d)return false;this.insertAtPosition(b.start,"\n"+d);return true;};codeEditor.prototype.backspace=function(a){var b=this.getSelection();if(b.length>0)return false;var c=this.textarea.value.substr(b.start-2,2);if(c=='""'||c=="''"||c=='{}'||c=='()'||c=='[]'){b.start-=2;this.replaceSelection(b,'');return true;}var c=this.textarea.value.substr(b.start-20,20);if((pos=c.search(/^(\s+)$/m))!=-1){b.start-=this.params.indent_size;this.replaceSelection(b,'');return true;}return false;};codeEditor.prototype.insertBrackets=function(a,b){var c=this.getSelection();var d=b;var e=d;switch(d){case '(':e=')';break;case '[':e=']';break;case '{':e='}';break;}if(c.length==0)this.insertAtPosition(c.start,d+e,c.start+1);else this.wrapSelection(c,d,e);return true;};codeEditor.prototype.toggleFullscreen=function(a){var b=this.parent.className.split(' ');for(var c=0;c<b.length;c++)if(b[c]=='fullscreen'){b.splice(c,1);this.parent.className=b.join(' ');this.fullscreen=false;return true;}b.push('fullscreen');this.parent.className=b.join(' ');this.fullscreen=true;return true;};}());