r2161 - try using CodePress for RackCode editing
authorDenis Ovsienko <infrastation@yandex.ru>
Thu, 21 Aug 2008 11:17:32 +0000 (11:17 +0000)
committerDenis Ovsienko <infrastation@yandex.ru>
Thu, 21 Aug 2008 11:17:32 +0000 (11:17 +0000)
16 files changed:
COPYING
inc/interface.php
index.php
js/codepress/codepress.css [new file with mode: 0644]
js/codepress/codepress.html [new file with mode: 0644]
js/codepress/codepress.js [new file with mode: 0644]
js/codepress/engines/gecko.js [new file with mode: 0644]
js/codepress/engines/khtml.js [new file with mode: 0644]
js/codepress/engines/msie.js [new file with mode: 0644]
js/codepress/engines/older.js [new file with mode: 0644]
js/codepress/engines/opera.js [new file with mode: 0644]
js/codepress/images/line-numbers.png [new file with mode: 0644]
js/codepress/languages/generic.css [new file with mode: 0644]
js/codepress/languages/generic.js [new file with mode: 0644]
js/codepress/languages/text.css [new file with mode: 0644]
js/codepress/languages/text.js [new file with mode: 0644]

diff --git a/COPYING b/COPYING
index 43c3bf1..bab01bb 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -58,3 +58,9 @@ produced by Tango Desktop Project.
 ----------------------8<----------------------8<----------------------
 
 Dragon ASCII art (c) Daniel C. Au
+
+----------------------8<----------------------8<----------------------
+
+RackTables includes portions of the CodePress Online Real Time Syntax
+Highlighting Editor (http://codepress.org), which is copyright (C) 2006
+Fernando M.A.d.S. <fermads@gmail.com> and is distributed under GNU LGPL license.
index a88e14b..46fb28d 100644 (file)
@@ -5002,9 +5002,11 @@ function renderRackCodeEditor ()
        showMessageOrError();
        printOpFormIntro ('saveRackCode');
        echo '<table border=0 align=center>';
-       echo "<tr><td><textarea rows=50 cols=80 name=rackcode>" . $text . "</textarea></td></tr>\n";
+       echo "<tr><td><textarea rows=40 cols=100 name=rackcode id=RCTA class='codepress text'>";
+       echo $text . "</textarea></td></tr>\n";
        echo "<tr><td align=center>";
-       printImageHREF ('SAVE', 'Save changes', TRUE);
+       echo "<input type='submit' value='Proceed' onclick='RCTA.toggleEditor();'>";
+//     printImageHREF ('SAVE', 'Save changes', TRUE);
        echo "</td></tr>";
        echo '</table>';
        echo "</form>";
index cb1be99..abc9078 100644 (file)
--- a/index.php
+++ b/index.php
@@ -37,6 +37,7 @@ foreach (array ('F', 'A', 'U', 'T', 'Th', 'Tw', 'Thw') as $statecode)
 }
        </style>
        <script language='javascript' type='text/javascript' src='js/live_validation.js'></script>
+       <script language='javascript' type='text/javascript' src='js/codepress/codepress.js'></script>
        <script type="text/javascript">
        function init() {
                document.add_new_range.range.setAttribute('match', "^\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\.\\d\\d?\\d?\\/\\d\\d?$");
diff --git a/js/codepress/codepress.css b/js/codepress/codepress.css
new file mode 100644 (file)
index 0000000..2186820
--- /dev/null
@@ -0,0 +1,21 @@
+body {\r
+       margin-top:13px;\r
+       _margin-top:14px;\r
+       background:white;\r
+       margin-left:32px;\r
+       font-family:monospace;\r
+       font-size:13px;\r
+       white-space:pre;\r
+       background-image:url("images/line-numbers.png");\r
+       background-repeat:repeat-y;\r
+       background-position:0 3px;\r
+       line-height:16px;\r
+       height:100%;\r
+}\r
+pre {margin:0;}\r
+html>body{background-position:0 2px;}\r
+P {margin:0;padding:0;border:0;outline:0;display:block;white-space:pre;}\r
+b, i, s, u, a, em, tt, ins, big, cite, strong, var, dfn {text-decoration:none;font-weight:normal;font-style:normal;font-size:13px;}\r
+\r
+body.hide-line-numbers {background:white;margin-left:16px;}\r
+body.show-line-numbers {background-image:url("images/line-numbers.png");margin-left:32px;}
\ No newline at end of file
diff --git a/js/codepress/codepress.html b/js/codepress/codepress.html
new file mode 100644 (file)
index 0000000..20270fe
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+<html>\r
+<head>\r
+       <title>CodePress - Real Time Syntax Highlighting Editor written in JavaScript</title>\r
+       <meta name="description" content="CodePress - source code editor window" />\r
+\r
+       <script type="text/javascript">\r
+       var language = 'generic';\r
+       var engine = 'older';\r
+       var ua = navigator.userAgent;\r
+       var ts = (new Date).getTime(); // timestamp to avoid cache\r
+       var lh = location.href;\r
+       \r
+       if(ua.match('MSIE')) engine = 'msie';\r
+       else if(ua.match('KHTML')) engine = 'khtml'; \r
+       else if(ua.match('Opera')) engine = 'opera'; \r
+       else if(ua.match('Gecko')) engine = 'gecko';\r
+\r
+       if(lh.match('language=')) language = lh.replace(/.*language=(.*?)(&.*)?$/,'$1');\r
+\r
+       document.write('<link type="text/css" href="codepress.css?ts='+ts+'" rel="stylesheet" />');\r
+       document.write('<link type="text/css" href="languages/'+language+'.css?ts='+ts+'" rel="stylesheet" id="cp-lang-style" />');\r
+       document.write('<scr'+'ipt type="text/javascript" src="engines/'+engine+'.js?ts='+ts+'"></scr'+'ipt>');\r
+       document.write('<scr'+'ipt type="text/javascript" src="languages/'+language+'.js?ts='+ts+'"></scr'+'ipt>');\r
+       </script>\r
+\r
+</head>\r
+\r
+<script type="text/javascript">\r
+if(engine == "msie" || engine == "gecko") document.write('<body><pre> </pre></body>');\r
+else if(engine == "opera") document.write('<body></body>');\r
+// else if(engine == "khtml") document.write('<body> </body>');\r
+</script>\r
+\r
+</html>\r
diff --git a/js/codepress/codepress.js b/js/codepress/codepress.js
new file mode 100644 (file)
index 0000000..96ea2e3
--- /dev/null
@@ -0,0 +1,138 @@
+/*\r
+ * CodePress - Real Time Syntax Highlighting Editor written in JavaScript - http://codepress.org/\r
+ * \r
+ * Copyright (C) 2006 Fernando M.A.d.S. <fermads@gmail.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify it under the terms of the \r
+ * GNU Lesser General Public License as published by the Free Software Foundation.\r
+ * \r
+ * Read the full licence: http://www.opensource.org/licenses/lgpl-license.php\r
+ */\r
+\r
+CodePress = function(obj) {\r
+       var self = document.createElement('iframe');\r
+       self.textarea = obj;\r
+       self.textarea.disabled = true;\r
+       self.textarea.style.overflow = 'hidden';\r
+       self.style.height = self.textarea.clientHeight +'px';\r
+       self.style.width = self.textarea.clientWidth +'px';\r
+       self.textarea.style.overflow = 'auto';\r
+       self.style.border = '1px solid gray';\r
+       self.frameBorder = 0; // remove IE internal iframe border\r
+       self.style.visibility = 'hidden';\r
+       self.style.position = 'absolute';\r
+       self.options = self.textarea.className;\r
+       \r
+       self.initialize = function() {\r
+               self.editor = self.contentWindow.CodePress;\r
+               self.editor.body = self.contentWindow.document.getElementsByTagName('body')[0];\r
+               self.editor.setCode(self.textarea.value);\r
+               self.setOptions();\r
+               self.editor.syntaxHighlight('init');\r
+               self.textarea.style.display = 'none';\r
+               self.style.position = 'static';\r
+               self.style.visibility = 'visible';\r
+               self.style.display = 'inline';\r
+       }\r
+       \r
+       // obj can by a textarea id or a string (code)\r
+       self.edit = function(obj,language) {\r
+               if(obj) self.textarea.value = document.getElementById(obj) ? document.getElementById(obj).value : obj;\r
+               if(!self.textarea.disabled) return;\r
+               self.language = language ? language : self.getLanguage();\r
+               self.src = CodePress.path+'codepress.html?language='+self.language+'&ts='+(new Date).getTime();\r
+               if(self.attachEvent) self.attachEvent('onload',self.initialize);\r
+               else self.addEventListener('load',self.initialize,false);\r
+       }\r
+\r
+       self.getLanguage = function() {\r
+               for (language in CodePress.languages) \r
+                       if(self.options.match('\\b'+language+'\\b')) \r
+                               return CodePress.languages[language] ? language : 'generic';\r
+       }\r
+       \r
+       self.setOptions = function() {\r
+               if(self.options.match('autocomplete-off')) self.toggleAutoComplete();\r
+               if(self.options.match('readonly-on')) self.toggleReadOnly();\r
+               if(self.options.match('linenumbers-off')) self.toggleLineNumbers();\r
+       }\r
+       \r
+       self.getCode = function() {\r
+               return self.textarea.disabled ? self.editor.getCode() : self.textarea.value;\r
+       }\r
+\r
+       self.setCode = function(code) {\r
+               self.textarea.disabled ? self.editor.setCode(code) : self.textarea.value = code;\r
+       }\r
+\r
+       self.toggleAutoComplete = function() {\r
+               self.editor.autocomplete = (self.editor.autocomplete) ? false : true;\r
+       }\r
+       \r
+       self.toggleReadOnly = function() {\r
+               self.textarea.readOnly = (self.textarea.readOnly) ? false : true;\r
+               if(self.style.display != 'none') // prevent exception on FF + iframe with display:none\r
+                       self.editor.readOnly(self.textarea.readOnly ? true : false);\r
+       }\r
+       \r
+       self.toggleLineNumbers = function() {\r
+               var cn = self.editor.body.className;\r
+               self.editor.body.className = (cn==''||cn=='show-line-numbers') ? 'hide-line-numbers' : 'show-line-numbers';\r
+       }\r
+       \r
+       self.toggleEditor = function() {\r
+               if(self.textarea.disabled) {\r
+                       self.textarea.value = self.getCode();\r
+                       self.textarea.disabled = false;\r
+                       self.style.display = 'none';\r
+                       self.textarea.style.display = 'inline';\r
+               }\r
+               else {\r
+                       self.textarea.disabled = true;\r
+                       self.setCode(self.textarea.value);\r
+                       self.editor.syntaxHighlight('init');\r
+                       self.style.display = 'inline';\r
+                       self.textarea.style.display = 'none';\r
+               }\r
+       }\r
+\r
+       self.edit();\r
+       return self;\r
+}\r
+\r
+CodePress.languages = {        \r
+       csharp : 'C#', \r
+       css : 'CSS', \r
+       generic : 'Generic',\r
+       html : 'HTML',\r
+       java : 'Java', \r
+       javascript : 'JavaScript', \r
+       perl : 'Perl', \r
+       ruby : 'Ruby',  \r
+       php : 'PHP', \r
+       text : 'Text', \r
+       sql : 'SQL',\r
+       vbscript : 'VBScript'\r
+}\r
+\r
+\r
+CodePress.run = function() {\r
+       s = document.getElementsByTagName('script');\r
+       for(var i=0,n=s.length;i<n;i++) {\r
+               if(s[i].src.match('codepress.js')) {\r
+                       CodePress.path = s[i].src.replace('codepress.js','');\r
+               }\r
+       }\r
+       t = document.getElementsByTagName('textarea');\r
+       for(var i=0,n=t.length;i<n;i++) {\r
+               if(t[i].className.match('codepress')) {\r
+                       id = t[i].id;\r
+                       t[i].id = id+'_cp';\r
+                       eval(id+' = new CodePress(t[i])');\r
+                       t[i].parentNode.insertBefore(eval(id), t[i]);\r
+               } \r
+       }\r
+}\r
+\r
+if(window.attachEvent) window.attachEvent('onload',CodePress.run);\r
+else window.addEventListener('DOMContentLoaded',CodePress.run,false);\r
diff --git a/js/codepress/engines/gecko.js b/js/codepress/engines/gecko.js
new file mode 100644 (file)
index 0000000..a9e38a9
--- /dev/null
@@ -0,0 +1,293 @@
+/*\r
+ * CodePress - Real Time Syntax Highlighting Editor written in JavaScript - http://codepress.org/\r
+ * \r
+ * Copyright (C) 2007 Fernando M.A.d.S. <fermads@gmail.com>\r
+ *\r
+ * Developers:\r
+ *             Fernando M.A.d.S. <fermads@gmail.com>\r
+ *             Michael Hurni <michael.hurni@gmail.com>\r
+ * Contributors:       \r
+ *             Martin D. Kirk\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify it under the terms of the \r
+ * GNU Lesser General Public License as published by the Free Software Foundation.\r
+ * \r
+ * Read the full licence: http://www.opensource.org/licenses/lgpl-license.php\r
+ */\r
+\r
+CodePress = {\r
+       scrolling : false,\r
+       autocomplete : true,\r
+\r
+       // set initial vars and start sh\r
+       initialize : function() {\r
+               if(typeof(editor)=='undefined' && !arguments[0]) return;\r
+               body = document.getElementsByTagName('body')[0];\r
+               body.innerHTML = body.innerHTML.replace(/\n/g,"");\r
+               chars = '|32|46|62|8|'; // charcodes that trigger syntax highlighting\r
+               cc = '\u2009'; // carret char\r
+               editor = document.getElementsByTagName('pre')[0];\r
+               document.designMode = 'on';\r
+               document.addEventListener('keypress', this.keyHandler, true);\r
+               window.addEventListener('scroll', function() { if(!CodePress.scrolling) CodePress.syntaxHighlight('scroll') }, false);\r
+               completeChars = this.getCompleteChars();\r
+               completeEndingChars =  this.getCompleteEndingChars();\r
+       },\r
+\r
+       // treat key bindings\r
+       keyHandler : function(evt) {\r
+       keyCode = evt.keyCode;  \r
+               charCode = evt.charCode;\r
+               fromChar = String.fromCharCode(charCode);\r
+\r
+               if((evt.ctrlKey || evt.metaKey) && evt.shiftKey && charCode!=90)  { // shortcuts = ctrl||appleKey+shift+key!=z(undo) \r
+                       CodePress.shortcuts(charCode?charCode:keyCode);\r
+               }\r
+               else if( (completeEndingChars.indexOf('|'+fromChar+'|')!= -1 || completeChars.indexOf('|'+fromChar+'|')!=-1) && CodePress.autocomplete) { // auto complete\r
+                       if(!CodePress.completeEnding(fromChar))\r
+                            CodePress.complete(fromChar);\r
+               }\r
+           else if(chars.indexOf('|'+charCode+'|')!=-1||keyCode==13) { // syntax highlighting\r
+                       top.setTimeout(function(){CodePress.syntaxHighlight('generic');},100);\r
+               }\r
+               else if(keyCode==9 || evt.tabKey) {  // snippets activation (tab)\r
+                       CodePress.snippets(evt);\r
+               }\r
+               else if(keyCode==46||keyCode==8) { // save to history when delete or backspace pressed\r
+                       CodePress.actions.history[CodePress.actions.next()] = editor.innerHTML;\r
+               }\r
+               else if((charCode==122||charCode==121||charCode==90) && evt.ctrlKey) { // undo and redo\r
+                       (charCode==121||evt.shiftKey) ? CodePress.actions.redo() :  CodePress.actions.undo(); \r
+                       evt.preventDefault();\r
+               }\r
+               else if(charCode==118 && evt.ctrlKey)  { // handle paste\r
+                       top.setTimeout(function(){CodePress.syntaxHighlight('generic');},100);\r
+               }\r
+               else if(charCode==99 && evt.ctrlKey)  { // handle cut\r
+                       //alert(window.getSelection().getRangeAt(0).toString().replace(/\t/g,'FFF'));\r
+               }\r
+\r
+       },\r
+\r
+       // put cursor back to its original position after every parsing\r
+       findString : function() {\r
+               if(self.find(cc))\r
+                       window.getSelection().getRangeAt(0).deleteContents();\r
+       },\r
+       \r
+       // split big files, highlighting parts of it\r
+       split : function(code,flag) {\r
+               if(flag=='scroll') {\r
+                       this.scrolling = true;\r
+                       return code;\r
+               }\r
+               else {\r
+                       this.scrolling = false;\r
+                       mid = code.indexOf(cc);\r
+                       if(mid-2000<0) {ini=0;end=4000;}\r
+                       else if(mid+2000>code.length) {ini=code.length-4000;end=code.length;}\r
+                       else {ini=mid-2000;end=mid+2000;}\r
+                       code = code.substring(ini,end);\r
+                       return code;\r
+               }\r
+       },\r
+       \r
+       getEditor : function() {\r
+               if(!document.getElementsByTagName('pre')[0]) {\r
+                       body = document.getElementsByTagName('body')[0];\r
+                       if(!body.innerHTML) return body;\r
+                       if(body.innerHTML=="<br>") body.innerHTML = "<pre> </pre>";\r
+                       else body.innerHTML = "<pre>"+body.innerHTML+"</pre>";\r
+               }\r
+               return document.getElementsByTagName('pre')[0];\r
+       },\r
+       \r
+       // syntax highlighting parser\r
+       syntaxHighlight : function(flag) {\r
+               //if(document.designMode=='off') document.designMode='on'\r
+               if(flag != 'init') { window.getSelection().getRangeAt(0).insertNode(document.createTextNode(cc));}\r
+               editor = CodePress.getEditor();\r
+               o = editor.innerHTML;\r
+               o = o.replace(/<br>/g,'\n');\r
+               o = o.replace(/<.*?>/g,'');\r
+               x = z = this.split(o,flag);\r
+               x = x.replace(/\n/g,'<br>');\r
+\r
+               if(arguments[1]&&arguments[2]) x = x.replace(arguments[1],arguments[2]);\r
+       \r
+               for(i=0;i<Language.syntax.length;i++) \r
+                       x = x.replace(Language.syntax[i].input,Language.syntax[i].output);\r
+\r
+               editor.innerHTML = this.actions.history[this.actions.next()] = (flag=='scroll') ? x : o.split(z).join(x);\r
+               if(flag!='init') this.findString();\r
+       },\r
+       \r
+       getLastWord : function() {\r
+               var rangeAndCaret = CodePress.getRangeAndCaret();\r
+               words = rangeAndCaret[0].substring(rangeAndCaret[1]-40,rangeAndCaret[1]);\r
+               words = words.replace(/[\s\n\r\);\W]/g,'\n').split('\n');\r
+               return words[words.length-1].replace(/[\W]/gi,'').toLowerCase();\r
+       },\r
+       \r
+       snippets : function(evt) {\r
+               var snippets = Language.snippets;       \r
+               var trigger = this.getLastWord();\r
+               for (var i=0; i<snippets.length; i++) {\r
+                       if(snippets[i].input == trigger) {\r
+                               var content = snippets[i].output.replace(/</g,'&lt;');\r
+                               content = content.replace(/>/g,'&gt;');\r
+                               if(content.indexOf('$0')<0) content += cc;\r
+                               else content = content.replace(/\$0/,cc);\r
+                               content = content.replace(/\n/g,'<br>');\r
+                               var pattern = new RegExp(trigger+cc,'gi');\r
+                               evt.preventDefault(); // prevent the tab key from being added\r
+                               this.syntaxHighlight('snippets',pattern,content);\r
+                       }\r
+               }\r
+       },\r
+       \r
+       readOnly : function() {\r
+               document.designMode = (arguments[0]) ? 'off' : 'on';\r
+       },\r
+\r
+       complete : function(trigger) {\r
+               window.getSelection().getRangeAt(0).deleteContents();\r
+               var complete = Language.complete;\r
+               for (var i=0; i<complete.length; i++) {\r
+                       if(complete[i].input == trigger) {\r
+                               var pattern = new RegExp('\\'+trigger+cc);\r
+                               var content = complete[i].output.replace(/\$0/g,cc);\r
+                               parent.setTimeout(function () { CodePress.syntaxHighlight('complete',pattern,content)},0); // wait for char to appear on screen\r
+                       }\r
+               }\r
+       },\r
+\r
+       getCompleteChars : function() {\r
+               var cChars = '';\r
+               for(var i=0;i<Language.complete.length;i++)\r
+                       cChars += '|'+Language.complete[i].input;\r
+               return cChars+'|';\r
+       },\r
+       \r
+       getCompleteEndingChars : function() {\r
+               var cChars = '';\r
+               for(var i=0;i<Language.complete.length;i++)\r
+                       cChars += '|'+Language.complete[i].output.charAt(Language.complete[i].output.length-1);\r
+               return cChars+'|';\r
+       },\r
+       \r
+       completeEnding : function(trigger) {\r
+               var range = window.getSelection().getRangeAt(0);\r
+               try {\r
+                       range.setEnd(range.endContainer, range.endOffset+1)\r
+               }\r
+               catch(e) {\r
+                       return false;\r
+               }\r
+               var next_character = range.toString()\r
+               range.setEnd(range.endContainer, range.endOffset-1)\r
+               if(next_character != trigger) return false;\r
+               else {\r
+                       range.setEnd(range.endContainer, range.endOffset+1)\r
+                       range.deleteContents();\r
+                       return true;\r
+               }\r
+       },\r
+       \r
+       shortcuts : function() {\r
+               var cCode = arguments[0];\r
+               if(cCode==13) cCode = '[enter]';\r
+               else if(cCode==32) cCode = '[space]';\r
+               else cCode = '['+String.fromCharCode(charCode).toLowerCase()+']';\r
+               for(var i=0;i<Language.shortcuts.length;i++)\r
+                       if(Language.shortcuts[i].input == cCode)\r
+                               this.insertCode(Language.shortcuts[i].output,false);\r
+       },\r
+       \r
+       getRangeAndCaret : function() { \r
+               var range = window.getSelection().getRangeAt(0);\r
+               var range2 = range.cloneRange();\r
+               var node = range.endContainer;                  \r
+               var caret = range.endOffset;\r
+               range2.selectNode(node);        \r
+               return [range2.toString(),caret];\r
+       },\r
+       \r
+       insertCode : function(code,replaceCursorBefore) {\r
+               var range = window.getSelection().getRangeAt(0);\r
+               var node = window.document.createTextNode(code);\r
+               var selct = window.getSelection();\r
+               var range2 = range.cloneRange();\r
+               // Insert text at cursor position\r
+               selct.removeAllRanges();\r
+               range.deleteContents();\r
+               range.insertNode(node);\r
+               // Move the cursor to the end of text\r
+               range2.selectNode(node);                \r
+               range2.collapse(replaceCursorBefore);\r
+               selct.removeAllRanges();\r
+               selct.addRange(range2);\r
+       },\r
+       \r
+       // get code from editor\r
+       getCode : function() {\r
+               if(!document.getElementsByTagName('pre')[0] || editor.innerHTML == '')\r
+                       editor = CodePress.getEditor();\r
+               var code = editor.innerHTML;\r
+               code = code.replace(/<br>/g,'\n');\r
+               code = code.replace(/\u2009/g,'');\r
+               code = code.replace(/<.*?>/g,'');\r
+               code = code.replace(/&lt;/g,'<');\r
+               code = code.replace(/&gt;/g,'>');\r
+               code = code.replace(/&amp;/gi,'&');\r
+               return code;\r
+       },\r
+\r
+       // put code inside editor\r
+       setCode : function() {\r
+               var code = arguments[0];\r
+               code = code.replace(/\u2009/gi,'');\r
+               code = code.replace(/&/gi,'&amp;');\r
+               code = code.replace(/</g,'&lt;');\r
+               code = code.replace(/>/g,'&gt;');\r
+               editor.innerHTML = code;\r
+               if (code == '')\r
+                       document.getElementsByTagName('body')[0].innerHTML = '';\r
+       },\r
+\r
+       // undo and redo methods\r
+       actions : {\r
+               pos : -1, // actual history position\r
+               history : [], // history vector\r
+               \r
+               undo : function() {\r
+                       editor = CodePress.getEditor();\r
+                       if(editor.innerHTML.indexOf(cc)==-1){\r
+                               if(editor.innerHTML != " ")\r
+                                       window.getSelection().getRangeAt(0).insertNode(document.createTextNode(cc));\r
+                               this.history[this.pos] = editor.innerHTML;\r
+                       }\r
+                       this.pos --;\r
+                       if(typeof(this.history[this.pos])=='undefined') this.pos ++;\r
+                       editor.innerHTML = this.history[this.pos];\r
+                       if(editor.innerHTML.indexOf(cc)>-1) editor.innerHTML+=cc;\r
+                       CodePress.findString();\r
+               },\r
+               \r
+               redo : function() {\r
+                       // editor = CodePress.getEditor();\r
+                       this.pos++;\r
+                       if(typeof(this.history[this.pos])=='undefined') this.pos--;\r
+                       editor.innerHTML = this.history[this.pos];\r
+                       CodePress.findString();\r
+               },\r
+               \r
+               next : function() { // get next vector position and clean old ones\r
+                       if(this.pos>20) this.history[this.pos-21] = undefined;\r
+                       return ++this.pos;\r
+               }\r
+       }\r
+}\r
+\r
+Language={};\r
+window.addEventListener('load', function() { CodePress.initialize('new'); }, true);
\ No newline at end of file
diff --git a/js/codepress/engines/khtml.js b/js/codepress/engines/khtml.js
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/js/codepress/engines/msie.js b/js/codepress/engines/msie.js
new file mode 100644 (file)
index 0000000..fd609b2
--- /dev/null
@@ -0,0 +1,304 @@
+/*\r
+ * CodePress - Real Time Syntax Highlighting Editor written in JavaScript - http://codepress.org/\r
+ * \r
+ * Copyright (C) 2007 Fernando M.A.d.S. <fermads@gmail.com>\r
+ *\r
+ * Developers:\r
+ *             Fernando M.A.d.S. <fermads@gmail.com>\r
+ *             Michael Hurni <michael.hurni@gmail.com>\r
+ * Contributors:       \r
+ *             Martin D. Kirk\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify it under the terms of the \r
+ * GNU Lesser General Public License as published by the Free Software Foundation.\r
+ * \r
+ * Read the full licence: http://www.opensource.org/licenses/lgpl-license.php\r
+ */\r
+\r
+CodePress = {\r
+       scrolling : false,\r
+       autocomplete : true,\r
+       \r
+       // set initial vars and start sh\r
+       initialize : function() {\r
+               if(typeof(editor)=='undefined' && !arguments[0]) return;\r
+               chars = '|32|46|62|'; // charcodes that trigger syntax highlighting\r
+               cc = '\u2009'; // carret char\r
+               editor = document.getElementsByTagName('pre')[0];\r
+               editor.contentEditable = 'true';\r
+               document.getElementsByTagName('body')[0].onfocus = function() {editor.focus();}\r
+               document.attachEvent('onkeydown', this.metaHandler);\r
+               document.attachEvent('onkeypress', this.keyHandler);\r
+               window.attachEvent('onscroll', function() { if(!CodePress.scrolling) setTimeout(function(){CodePress.syntaxHighlight('scroll')},1)});\r
+               completeChars = this.getCompleteChars();\r
+               completeEndingChars =  this.getCompleteEndingChars();\r
+               setTimeout(function() { window.scroll(0,0) },50); // scroll IE to top\r
+       },\r
+       \r
+       // treat key bindings\r
+       keyHandler : function(evt) {\r
+               charCode = evt.keyCode;\r
+               fromChar = String.fromCharCode(charCode);\r
+               \r
+               if( (completeEndingChars.indexOf('|'+fromChar+'|')!= -1 || completeChars.indexOf('|'+fromChar+'|')!=-1  )&& CodePress.autocomplete) { // auto complete\r
+                       if(!CodePress.completeEnding(fromChar))\r
+                            CodePress.complete(fromChar);\r
+               }\r
+           else if(chars.indexOf('|'+charCode+'|')!=-1||charCode==13) { // syntax highlighting\r
+                       CodePress.syntaxHighlight('generic');\r
+               }\r
+       },\r
+\r
+       metaHandler : function(evt) {\r
+               keyCode = evt.keyCode;\r
+               \r
+               if(keyCode==9 || evt.tabKey) { \r
+                       CodePress.snippets();\r
+               }\r
+               else if((keyCode==122||keyCode==121||keyCode==90) && evt.ctrlKey) { // undo and redo\r
+                       (keyCode==121||evt.shiftKey) ? CodePress.actions.redo() :  CodePress.actions.undo(); \r
+                       evt.returnValue = false;\r
+               }\r
+               else if(keyCode==34||keyCode==33) { // handle page up/down for IE\r
+                       self.scrollBy(0, (keyCode==34) ? 200 : -200); \r
+                       evt.returnValue = false;\r
+               }\r
+               else if(keyCode==46||keyCode==8) { // save to history when delete or backspace pressed\r
+                       CodePress.actions.history[CodePress.actions.next()] = editor.innerHTML;\r
+               }\r
+               else if((evt.ctrlKey || evt.metaKey) && evt.shiftKey && keyCode!=90)  { // shortcuts = ctrl||appleKey+shift+key!=z(undo) \r
+                       CodePress.shortcuts(keyCode);\r
+                       evt.returnValue = false;\r
+               }\r
+               else if(keyCode==86 && evt.ctrlKey)  { // handle paste\r
+                       window.clipboardData.setData('Text',window.clipboardData.getData('Text').replace(/\t/g,'\u2008'));\r
+                       top.setTimeout(function(){CodePress.syntaxHighlight('paste');},10);\r
+               }\r
+               else if(keyCode==67 && evt.ctrlKey)  { // handle cut\r
+                       // window.clipboardData.setData('Text',x[0]);\r
+                       // code = window.clipboardData.getData('Text');\r
+               }\r
+       },\r
+\r
+       // put cursor back to its original position after every parsing\r
+       \r
+       \r
+       findString : function() {\r
+               range = self.document.body.createTextRange();\r
+               if(range.findText(cc)){\r
+                       range.select();\r
+                       range.text = '';\r
+               }\r
+       },\r
+       \r
+       // split big files, highlighting parts of it\r
+       split : function(code,flag) {\r
+               if(flag=='scroll') {\r
+                       this.scrolling = true;\r
+                       return code;\r
+               }\r
+               else {\r
+                       this.scrolling = false;\r
+                       mid = code.indexOf(cc);\r
+                       if(mid-2000<0) {ini=0;end=4000;}\r
+                       else if(mid+2000>code.length) {ini=code.length-4000;end=code.length;}\r
+                       else {ini=mid-2000;end=mid+2000;}\r
+                       code = code.substring(ini,end);\r
+                       return code.substring(code.indexOf('<P>'),code.lastIndexOf('</P>')+4);\r
+               }\r
+       },\r
+       \r
+       // syntax highlighting parser\r
+       syntaxHighlight : function(flag) {\r
+               if(flag!='init') document.selection.createRange().text = cc;\r
+               o = editor.innerHTML;\r
+               if(flag=='paste') { // fix pasted text\r
+                       o = o.replace(/<BR>/g,'\r\n'); \r
+                       o = o.replace(/\u2008/g,'\t');\r
+               }\r
+               o = o.replace(/<P>/g,'\n');\r
+               o = o.replace(/<\/P>/g,'\r');\r
+               o = o.replace(/<.*?>/g,'');\r
+               o = o.replace(/&nbsp;/g,'');                    \r
+               o = '<PRE><P>'+o+'</P></PRE>';\r
+               o = o.replace(/\n\r/g,'<P></P>');\r
+               o = o.replace(/\n/g,'<P>');\r
+               o = o.replace(/\r/g,'<\/P>');\r
+               o = o.replace(/<P>(<P>)+/,'<P>');\r
+               o = o.replace(/<\/P>(<\/P>)+/,'</P>');\r
+               o = o.replace(/<P><\/P>/g,'<P><BR/></P>');\r
+               x = z = this.split(o,flag);\r
+\r
+               if(arguments[1]&&arguments[2]) x = x.replace(arguments[1],arguments[2]);\r
+       \r
+               for(i=0;i<Language.syntax.length;i++) \r
+                       x = x.replace(Language.syntax[i].input,Language.syntax[i].output);\r
+                       \r
+               editor.innerHTML = this.actions.history[this.actions.next()] = (flag=='scroll') ? x : o.replace(z,x);\r
+               if(flag!='init') this.findString();\r
+       },\r
+\r
+       snippets : function(evt) {\r
+               var snippets = Language.snippets;\r
+               var trigger = this.getLastWord();\r
+               for (var i=0; i<snippets.length; i++) {\r
+                       if(snippets[i].input == trigger) {\r
+                               var content = snippets[i].output.replace(/</g,'&lt;');\r
+                               content = content.replace(/>/g,'&gt;');\r
+                               if(content.indexOf('$0')<0) content += cc;\r
+                               else content = content.replace(/\$0/,cc);\r
+                               content = content.replace(/\n/g,'</P><P>');\r
+                               var pattern = new RegExp(trigger+cc,"gi");\r
+                               this.syntaxHighlight('snippets',pattern,content);\r
+                       }\r
+               }\r
+       },\r
+       \r
+       readOnly : function() {\r
+               editor.contentEditable = (arguments[0]) ? 'false' : 'true';\r
+       },\r
+       \r
+       complete : function(trigger) {\r
+               var complete = Language.complete;\r
+               for (var i=0; i<complete.length; i++) {\r
+                       if(complete[i].input == trigger) {\r
+                               var pattern = new RegExp('\\'+trigger+cc);\r
+                               var content = complete[i].output.replace(/\$0/g,cc);\r
+                               setTimeout(function () { CodePress.syntaxHighlight('complete',pattern,content)},0); // wait for char to appear on screen\r
+                       }\r
+               }\r
+       },\r
+       \r
+       getCompleteChars : function() {\r
+               var cChars = '';\r
+               for(var i=0;i<Language.complete.length;i++)\r
+                       cChars += '|'+Language.complete[i].input;\r
+               return cChars+'|';\r
+       },\r
+\r
+       getCompleteEndingChars : function() {\r
+               var cChars = '';\r
+               for(var i=0;i<Language.complete.length;i++)\r
+                       cChars += '|'+Language.complete[i].output.charAt(Language.complete[i].output.length-1);\r
+               return cChars+'|';\r
+       },\r
+\r
+       completeEnding : function(trigger) {\r
+               var range = document.selection.createRange();\r
+               try {\r
+                       range.moveEnd('character', 1)\r
+               }\r
+               catch(e) {\r
+                       return false;\r
+               }\r
+               var next_character = range.text\r
+               range.moveEnd('character', -1)\r
+               if(next_character != trigger )  return false;\r
+               else {\r
+                       range.moveEnd('character', 1)\r
+                       range.text=''\r
+                       return true;\r
+               }\r
+       },      \r
+\r
+       shortcuts : function() {\r
+               var cCode = arguments[0];\r
+               if(cCode==13) cCode = '[enter]';\r
+               else if(cCode==32) cCode = '[space]';\r
+               else cCode = '['+String.fromCharCode(keyCode).toLowerCase()+']';\r
+               for(var i=0;i<Language.shortcuts.length;i++)\r
+                       if(Language.shortcuts[i].input == cCode)\r
+                               this.insertCode(Language.shortcuts[i].output,false);\r
+       },\r
+       \r
+       getLastWord : function() {\r
+               var rangeAndCaret = CodePress.getRangeAndCaret();\r
+               words = rangeAndCaret[0].substring(rangeAndCaret[1]-40,rangeAndCaret[1]);\r
+               words = words.replace(/[\s\n\r\);\W]/g,'\n').split('\n');\r
+               return words[words.length-1].replace(/[\W]/gi,'').toLowerCase();\r
+       }, \r
+\r
+       getRangeAndCaret : function() { \r
+               var range = document.selection.createRange();\r
+               var caret = Math.abs(range.moveStart('character', -1000000)+1);\r
+               range = this.getCode();\r
+               range = range.replace(/\n\r/gi,'  ');\r
+               range = range.replace(/\n/gi,'');\r
+               return [range.toString(),caret];\r
+       },\r
+       \r
+       insertCode : function(code,replaceCursorBefore) {\r
+               var repdeb = '';\r
+               var repfin = '';\r
+               \r
+               if(replaceCursorBefore) { repfin = code; }\r
+               else { repdeb = code; }\r
+               \r
+               if(typeof document.selection != 'undefined') {\r
+                       var range = document.selection.createRange();\r
+                       range.text = repdeb + repfin;\r
+                       range = document.selection.createRange();\r
+                       range.move('character', -repfin.length);\r
+                       range.select(); \r
+               }       \r
+       },\r
+\r
+       // get code from editor \r
+       getCode : function() {\r
+               var code = editor.innerHTML;\r
+               code = code.replace(/<br>/g,'\n');\r
+               code = code.replace(/<\/p>/gi,'\r');\r
+               code = code.replace(/<p>/i,''); // IE first line fix\r
+               code = code.replace(/<p>/gi,'\n');\r
+               code = code.replace(/&nbsp;/gi,'');\r
+               code = code.replace(/\u2009/g,'');\r
+               code = code.replace(/<.*?>/g,'');\r
+               code = code.replace(/&lt;/g,'<');\r
+               code = code.replace(/&gt;/g,'>');\r
+               code = code.replace(/&amp;/gi,'&');\r
+               return code;\r
+       },\r
+\r
+       // put code inside editor\r
+       setCode : function() {\r
+               var code = arguments[0];\r
+               code = code.replace(/\u2009/gi,'');\r
+               code = code.replace(/&/gi,'&amp;');             \r
+               code = code.replace(/</g,'&lt;');\r
+        code = code.replace(/>/g,'&gt;');\r
+               editor.innerHTML = '<pre>'+code+'</pre>';\r
+       },\r
+\r
+       \r
+       // undo and redo methods\r
+       actions : {\r
+               pos : -1, // actual history position\r
+               history : [], // history vector\r
+               \r
+               undo : function() {\r
+                       if(editor.innerHTML.indexOf(cc)==-1){\r
+                               document.selection.createRange().text = cc;\r
+                               this.history[this.pos] = editor.innerHTML;\r
+                       }\r
+                       this.pos--;\r
+                       if(typeof(this.history[this.pos])=='undefined') this.pos++;\r
+                       editor.innerHTML = this.history[this.pos];\r
+                       CodePress.findString();\r
+               },\r
+               \r
+               redo : function() {\r
+                       this.pos++;\r
+                       if(typeof(this.history[this.pos])=='undefined') this.pos--;\r
+                       editor.innerHTML = this.history[this.pos];\r
+                       CodePress.findString();\r
+               },\r
+               \r
+               next : function() { // get next vector position and clean old ones\r
+                       if(this.pos>20) this.history[this.pos-21] = undefined;\r
+                       return ++this.pos;\r
+               }\r
+       }\r
+}\r
+\r
+Language={};\r
+window.attachEvent('onload', function() { CodePress.initialize('new');});
\ No newline at end of file
diff --git a/js/codepress/engines/older.js b/js/codepress/engines/older.js
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/js/codepress/engines/opera.js b/js/codepress/engines/opera.js
new file mode 100644 (file)
index 0000000..152c763
--- /dev/null
@@ -0,0 +1,260 @@
+/*\r
+ * CodePress - Real Time Syntax Highlighting Editor written in JavaScript - http://codepress.org/\r
+ * \r
+ * Copyright (C) 2007 Fernando M.A.d.S. <fermads@gmail.com>\r
+ *\r
+ * Contributors :\r
+ *\r
+ *     Michael Hurni <michael.hurni@gmail.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify it under the terms of the \r
+ * GNU Lesser General Public License as published by the Free Software Foundation.\r
+ * \r
+ * Read the full licence: http://www.opensource.org/licenses/lgpl-license.php\r
+ */\r
+\r
+\r
+CodePress = {\r
+       scrolling : false,\r
+       autocomplete : true,\r
+\r
+       // set initial vars and start sh\r
+       initialize : function() {\r
+               if(typeof(editor)=='undefined' && !arguments[0]) return;\r
+               chars = '|32|46|62|'; // charcodes that trigger syntax highlighting\r
+               cc = '\u2009'; // control char\r
+               editor = document.getElementsByTagName('body')[0];\r
+               document.designMode = 'on';\r
+               document.addEventListener('keyup', this.keyHandler, true);\r
+               window.addEventListener('scroll', function() { if(!CodePress.scrolling) CodePress.syntaxHighlight('scroll') }, false);\r
+               completeChars = this.getCompleteChars();\r
+//             CodePress.syntaxHighlight('init');\r
+       },\r
+\r
+       // treat key bindings\r
+       keyHandler : function(evt) {\r
+       keyCode = evt.keyCode;  \r
+               charCode = evt.charCode;\r
+\r
+               if((evt.ctrlKey || evt.metaKey) && evt.shiftKey && charCode!=90)  { // shortcuts = ctrl||appleKey+shift+key!=z(undo) \r
+                       CodePress.shortcuts(charCode?charCode:keyCode);\r
+               }\r
+               else if(completeChars.indexOf('|'+String.fromCharCode(charCode)+'|')!=-1 && CodePress.autocomplete) { // auto complete\r
+                       CodePress.complete(String.fromCharCode(charCode));\r
+               }\r
+           else if(chars.indexOf('|'+charCode+'|')!=-1||keyCode==13) { // syntax highlighting\r
+                       CodePress.syntaxHighlight('generic');\r
+               }\r
+               else if(keyCode==9 || evt.tabKey) {  // snippets activation (tab)\r
+                       CodePress.snippets(evt);\r
+               }\r
+               else if(keyCode==46||keyCode==8) { // save to history when delete or backspace pressed\r
+                       CodePress.actions.history[CodePress.actions.next()] = editor.innerHTML;\r
+               }\r
+               else if((charCode==122||charCode==121||charCode==90) && evt.ctrlKey) { // undo and redo\r
+                       (charCode==121||evt.shiftKey) ? CodePress.actions.redo() :  CodePress.actions.undo(); \r
+                       evt.preventDefault();\r
+               }\r
+               else if(keyCode==86 && evt.ctrlKey)  { // paste\r
+                       // TODO: pasted text should be parsed and highlighted\r
+               }\r
+       },\r
+\r
+       // put cursor back to its original position after every parsing\r
+       findString : function() {\r
+               var sel = window.getSelection();\r
+               var range = window.document.createRange();\r
+               var span = window.document.getElementsByTagName('span')[0];\r
+                       \r
+               range.selectNode(span);\r
+               sel.removeAllRanges();\r
+               sel.addRange(range);\r
+               span.parentNode.removeChild(span);\r
+               //if(self.find(cc))\r
+               //window.getSelection().getRangeAt(0).deleteContents();\r
+       },\r
+       \r
+       // split big files, highlighting parts of it\r
+       split : function(code,flag) {\r
+               if(flag=='scroll') {\r
+                       this.scrolling = true;\r
+                       return code;\r
+               }\r
+               else {\r
+                       this.scrolling = false;\r
+                       mid = code.indexOf('<SPAN>');\r
+                       if(mid-2000<0) {ini=0;end=4000;}\r
+                       else if(mid+2000>code.length) {ini=code.length-4000;end=code.length;}\r
+                       else {ini=mid-2000;end=mid+2000;}\r
+                       code = code.substring(ini,end);\r
+                       return code;\r
+               }\r
+       },\r
+       \r
+       // syntax highlighting parser\r
+       syntaxHighlight : function(flag) {\r
+               //if(document.designMode=='off') document.designMode='on'\r
+               if(flag!='init') {\r
+                       var span = document.createElement('span');\r
+                       window.getSelection().getRangeAt(0).insertNode(span);\r
+               }\r
+\r
+               o = editor.innerHTML;\r
+//             o = o.replace(/<br>/g,'\r\n');\r
+//             o = o.replace(/<(b|i|s|u|a|em|tt|ins|big|cite|strong)?>/g,'');\r
+               //alert(o)\r
+               o = o.replace(/<(?!span|\/span|br).*?>/gi,'');\r
+//             alert(o)\r
+//             x = o;\r
+               x = z = this.split(o,flag);\r
+               //alert(z)\r
+//             x = x.replace(/\r\n/g,'<br>');\r
+               x = x.replace(/\t/g, '        ');\r
+\r
+\r
+               if(arguments[1]&&arguments[2]) x = x.replace(arguments[1],arguments[2]);\r
+       \r
+               for(i=0;i<Language.syntax.length;i++) \r
+                       x = x.replace(Language.syntax[i].input,Language.syntax[i].output);\r
+\r
+               editor.innerHTML = this.actions.history[this.actions.next()] = (flag=='scroll') ? x : o.split(z).join(x); \r
+\r
+               if(flag!='init') this.findString();\r
+       },\r
+       \r
+       getLastWord : function() {\r
+               var rangeAndCaret = CodePress.getRangeAndCaret();\r
+               words = rangeAndCaret[0].substring(rangeAndCaret[1]-40,rangeAndCaret[1]);\r
+               words = words.replace(/[\s\n\r\);\W]/g,'\n').split('\n');\r
+               return words[words.length-1].replace(/[\W]/gi,'').toLowerCase();\r
+       }, \r
+       \r
+       snippets : function(evt) {\r
+               var snippets = Language.snippets;       \r
+               var trigger = this.getLastWord();\r
+               for (var i=0; i<snippets.length; i++) {\r
+                       if(snippets[i].input == trigger) {\r
+                               var content = snippets[i].output.replace(/</g,'&lt;');\r
+                               content = content.replace(/>/g,'&gt;');\r
+                               if(content.indexOf('$0')<0) content += cc;\r
+                               else content = content.replace(/\$0/,cc);\r
+                               content = content.replace(/\n/g,'<br>');\r
+                               var pattern = new RegExp(trigger+cc,'gi');\r
+                               evt.preventDefault(); // prevent the tab key from being added\r
+                               this.syntaxHighlight('snippets',pattern,content);\r
+                       }\r
+               }\r
+       },\r
+       \r
+       readOnly : function() {\r
+               document.designMode = (arguments[0]) ? 'off' : 'on';\r
+       },\r
+\r
+       complete : function(trigger) {\r
+               window.getSelection().getRangeAt(0).deleteContents();\r
+               var complete = Language.complete;\r
+               for (var i=0; i<complete.length; i++) {\r
+                       if(complete[i].input == trigger) {\r
+                               var pattern = new RegExp('\\'+trigger+cc);\r
+                               var content = complete[i].output.replace(/\$0/g,cc);\r
+                               parent.setTimeout(function () { CodePress.syntaxHighlight('complete',pattern,content)},0); // wait for char to appear on screen\r
+                       }\r
+               }\r
+       },\r
+\r
+       getCompleteChars : function() {\r
+               var cChars = '';\r
+               for(var i=0;i<Language.complete.length;i++)\r
+                       cChars += '|'+Language.complete[i].input;\r
+               return cChars+'|';\r
+       },\r
+\r
+       shortcuts : function() {\r
+               var cCode = arguments[0];\r
+               if(cCode==13) cCode = '[enter]';\r
+               else if(cCode==32) cCode = '[space]';\r
+               else cCode = '['+String.fromCharCode(charCode).toLowerCase()+']';\r
+               for(var i=0;i<Language.shortcuts.length;i++)\r
+                       if(Language.shortcuts[i].input == cCode)\r
+                               this.insertCode(Language.shortcuts[i].output,false);\r
+       },\r
+       \r
+       getRangeAndCaret : function() { \r
+               var range = window.getSelection().getRangeAt(0);\r
+               var range2 = range.cloneRange();\r
+               var node = range.endContainer;                  \r
+               var caret = range.endOffset;\r
+               range2.selectNode(node);        \r
+               return [range2.toString(),caret];\r
+       },\r
+       \r
+       insertCode : function(code,replaceCursorBefore) {\r
+               var range = window.getSelection().getRangeAt(0);\r
+               var node = window.document.createTextNode(code);\r
+               var selct = window.getSelection();\r
+               var range2 = range.cloneRange();\r
+               // Insert text at cursor position\r
+               selct.removeAllRanges();\r
+               range.deleteContents();\r
+               range.insertNode(node);\r
+               // Move the cursor to the end of text\r
+               range2.selectNode(node);                \r
+               range2.collapse(replaceCursorBefore);\r
+               selct.removeAllRanges();\r
+               selct.addRange(range2);\r
+       },\r
+       \r
+       // get code from editor\r
+       getCode : function() {\r
+               var code = editor.innerHTML;\r
+               code = code.replace(/<br>/g,'\n');\r
+               code = code.replace(/\u2009/g,'');\r
+               code = code.replace(/<.*?>/g,'');\r
+               code = code.replace(/&lt;/g,'<');\r
+               code = code.replace(/&gt;/g,'>');\r
+               code = code.replace(/&amp;/gi,'&');\r
+               return code;\r
+       },\r
+\r
+       // put code inside editor\r
+       setCode : function() {\r
+               var code = arguments[0];\r
+               code = code.replace(/\u2009/gi,'');\r
+               code = code.replace(/&/gi,'&amp;');\r
+               code = code.replace(/</g,'&lt;');\r
+        code = code.replace(/>/g,'&gt;');\r
+               editor.innerHTML = code;\r
+       },\r
+\r
+       // undo and redo methods\r
+       actions : {\r
+               pos : -1, // actual history position\r
+               history : [], // history vector\r
+               \r
+               undo : function() {\r
+                       if(editor.innerHTML.indexOf(cc)==-1){\r
+                               window.getSelection().getRangeAt(0).insertNode(document.createTextNode(cc));\r
+                               this.history[this.pos] = editor.innerHTML;\r
+                       }\r
+                       this.pos--;\r
+                       if(typeof(this.history[this.pos])=='undefined') this.pos++;\r
+                       editor.innerHTML = this.history[this.pos];\r
+                       CodePress.findString();\r
+               },\r
+               \r
+               redo : function() {\r
+                       this.pos++;\r
+                       if(typeof(this.history[this.pos])=='undefined') this.pos--;\r
+                       editor.innerHTML = this.history[this.pos];\r
+                       CodePress.findString();\r
+               },\r
+               \r
+               next : function() { // get next vector position and clean old ones\r
+                       if(this.pos>20) this.history[this.pos-21] = undefined;\r
+                       return ++this.pos;\r
+               }\r
+       }\r
+}\r
+\r
+Language={};\r
+window.addEventListener('load', function() { CodePress.initialize('new'); }, true);\r
diff --git a/js/codepress/images/line-numbers.png b/js/codepress/images/line-numbers.png
new file mode 100644 (file)
index 0000000..ffea4e6
Binary files /dev/null and b/js/codepress/images/line-numbers.png differ
diff --git a/js/codepress/languages/generic.css b/js/codepress/languages/generic.css
new file mode 100644 (file)
index 0000000..3d52b6b
--- /dev/null
@@ -0,0 +1,9 @@
+/*\r
+ * CodePress color styles for generic syntax highlighting\r
+ */\r
+\r
+b {color:#7F0055;font-weight:bold;} /* reserved words */\r
+u {color:darkblue;font-weight:bold;} /* special words */\r
+i, i b, i s, i u, i em {color:green;font-weight:normal;} /* comments */\r
+s, s b, s em {color:#2A00FF;font-weight:normal;} /* strings */\r
+em {font-weight:bold;} /* special chars */
\ No newline at end of file
diff --git a/js/codepress/languages/generic.js b/js/codepress/languages/generic.js
new file mode 100644 (file)
index 0000000..8289da0
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+ * CodePress regular expressions for generic syntax highlighting\r
+ */\r
\r
+// generic languages\r
+Language.syntax = [\r
+       { input : /\"(.*?)(\"|<br>|<\/P>)/g, output : '<s>"$1$2</s>' }, // strings double quote\r
+       { input : /\'(.*?)(\'|<br>|<\/P>)/g, output : '<s>\'$1$2</s>' }, // strings single quote\r
+       { input : /\b(abstract|continue|for|new|switch|default|goto|boolean|do|if|private|this|break|double|protected|throw|byte|else|import|public|throws|case|return|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|const|float|while|function|label)\b/g, output : '<b>$1</b>' }, // reserved words\r
+       { input : /([\(\){}])/g, output : '<em>$1</em>' }, // special chars;\r
+       { input : /([^:]|^)\/\/(.*?)(<br|<\/P)/g, output : '$1<i>//$2</i>$3' }, // comments //\r
+       { input : /\/\*(.*?)\*\//g, output : '<i>/*$1*/</i>' } // comments /* */\r
+]\r
+\r
+Language.snippets = []\r
+\r
+Language.complete = [\r
+       { input : '\'', output : '\'$0\'' },\r
+       { input : '"', output : '"$0"' },\r
+       { input : '(', output : '\($0\)' },\r
+       { input : '[', output : '\[$0\]' },\r
+       { input : '{', output : '{\n\t$0\n}' }          \r
+]\r
+\r
+Language.shortcuts = []\r
diff --git a/js/codepress/languages/text.css b/js/codepress/languages/text.css
new file mode 100644 (file)
index 0000000..8e5ba28
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+ * CodePress color styles for Text syntax highlighting\r
+ */\r
+\r
+/* do nothing as expected */\r
diff --git a/js/codepress/languages/text.js b/js/codepress/languages/text.js
new file mode 100644 (file)
index 0000000..1895430
--- /dev/null
@@ -0,0 +1,9 @@
+/*\r
+ * CodePress regular expressions for Text syntax highlighting\r
+ */\r
+\r
+// plain text\r
+Language.syntax = []\r
+Language.snippets = []\r
+Language.complete = []\r
+Language.shortcuts = []\r