]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-includes/js/codepress/engines/gecko.js
Wordpress 2.8
[autoinstalls/wordpress.git] / wp-includes / js / codepress / engines / gecko.js
1 /*
2  * CodePress - Real Time Syntax Highlighting Editor written in JavaScript - http://codepress.org/
3  * 
4  * Copyright (C) 2007 Fernando M.A.d.S. <fermads@gmail.com>
5  *
6  * Developers:
7  *              Fernando M.A.d.S. <fermads@gmail.com>
8  *              Michael Hurni <michael.hurni@gmail.com>
9  * Contributors:        
10  *              Martin D. Kirk
11  *
12  * This program is free software; you can redistribute it and/or modify it under the terms of the 
13  * GNU Lesser General Public License as published by the Free Software Foundation.
14  * 
15  * Read the full licence: http://www.opensource.org/licenses/lgpl-license.php
16  */
17
18 CodePress = {
19         scrolling : false,
20         autocomplete : true,
21
22         // set initial vars and start sh
23         initialize : function() {
24                 if(typeof(editor)=='undefined' && !arguments[0]) return;
25                 body = document.getElementsByTagName('body')[0];
26                 body.innerHTML = body.innerHTML.replace(/\n/g,"");
27                 chars = '|32|46|62|8|'; // charcodes that trigger syntax highlighting
28                 cc = '\u2009'; // carret char
29                 editor = document.getElementsByTagName('pre')[0];
30                 document.designMode = 'on';
31                 document.addEventListener('keypress', this.keyHandler, true);
32                 window.addEventListener('scroll', function() { if(!CodePress.scrolling) CodePress.syntaxHighlight('scroll') }, false);
33                 completeChars = this.getCompleteChars();
34                 completeEndingChars =  this.getCompleteEndingChars();
35         },
36
37         // treat key bindings
38         keyHandler : function(evt) {
39         keyCode = evt.keyCode;  
40                 charCode = evt.charCode;
41                 fromChar = String.fromCharCode(charCode);
42
43                 if((evt.ctrlKey || evt.metaKey) && evt.shiftKey && charCode!=90)  { // shortcuts = ctrl||appleKey+shift+key!=z(undo) 
44                         CodePress.shortcuts(charCode?charCode:keyCode);
45                 }
46                 else if( (completeEndingChars.indexOf('|'+fromChar+'|')!= -1 || completeChars.indexOf('|'+fromChar+'|')!=-1) && CodePress.autocomplete) { // auto complete
47                         if(!CodePress.completeEnding(fromChar))
48                              CodePress.complete(fromChar);
49                 }
50             else if(chars.indexOf('|'+charCode+'|')!=-1||keyCode==13) { // syntax highlighting
51                         top.setTimeout(function(){CodePress.syntaxHighlight('generic');},100);
52                 }
53                 else if(keyCode==9 || evt.tabKey) {  // snippets activation (tab)
54                         CodePress.snippets(evt);
55                 }
56                 else if(keyCode==46||keyCode==8) { // save to history when delete or backspace pressed
57                         CodePress.actions.history[CodePress.actions.next()] = editor.innerHTML;
58                 }
59                 else if((charCode==122||charCode==121||charCode==90) && evt.ctrlKey) { // undo and redo
60                         (charCode==121||evt.shiftKey) ? CodePress.actions.redo() :  CodePress.actions.undo(); 
61                         evt.preventDefault();
62                 }
63                 else if(charCode==118 && evt.ctrlKey)  { // handle paste
64                         top.setTimeout(function(){CodePress.syntaxHighlight('generic');},100);
65                 }
66                 else if(charCode==99 && evt.ctrlKey)  { // handle cut
67                         //alert(window.getSelection().getRangeAt(0).toString().replace(/\t/g,'FFF'));
68                 }
69
70         },
71
72         // put cursor back to its original position after every parsing
73         findString : function() {
74                 if(self.find(cc))
75                         window.getSelection().getRangeAt(0).deleteContents();
76         },
77         
78         // split big files, highlighting parts of it
79         split : function(code,flag) {
80                 if(flag=='scroll') {
81                         this.scrolling = true;
82                         return code;
83                 }
84                 else {
85                         this.scrolling = false;
86                         mid = code.indexOf(cc);
87                         if(mid-2000<0) {ini=0;end=4000;}
88                         else if(mid+2000>code.length) {ini=code.length-4000;end=code.length;}
89                         else {ini=mid-2000;end=mid+2000;}
90                         code = code.substring(ini,end);
91                         return code;
92                 }
93         },
94         
95         getEditor : function() {
96                 if(!document.getElementsByTagName('pre')[0]) {
97                         body = document.getElementsByTagName('body')[0];
98                         if(!body.innerHTML) return body;
99                         if(body.innerHTML=="<br>") body.innerHTML = "<pre> </pre>";
100                         else body.innerHTML = "<pre>"+body.innerHTML+"</pre>";
101                 }
102                 return document.getElementsByTagName('pre')[0];
103         },
104         
105         // syntax highlighting parser
106         syntaxHighlight : function(flag) {
107                 //if(document.designMode=='off') document.designMode='on'
108                 if(flag != 'init') { window.getSelection().getRangeAt(0).insertNode(document.createTextNode(cc));}
109                 editor = CodePress.getEditor();
110                 o = editor.innerHTML;
111                 o = o.replace(/<br>/g,'\n');
112                 o = o.replace(/<.*?>/g,'');
113                 x = z = this.split(o,flag);
114                 x = x.replace(/\n/g,'<br>');
115
116                 if(arguments[1]&&arguments[2]) x = x.replace(arguments[1],arguments[2]);
117         
118                 for(i=0;i<Language.syntax.length;i++) 
119                         x = x.replace(Language.syntax[i].input,Language.syntax[i].output);
120
121                 editor.innerHTML = this.actions.history[this.actions.next()] = (flag=='scroll') ? x : o.split(z).join(x);
122                 if(flag!='init') this.findString();
123         },
124         
125         getLastWord : function() {
126                 var rangeAndCaret = CodePress.getRangeAndCaret();
127                 words = rangeAndCaret[0].substring(rangeAndCaret[1]-40,rangeAndCaret[1]);
128                 words = words.replace(/[\s\n\r\);\W]/g,'\n').split('\n');
129                 return words[words.length-1].replace(/[\W]/gi,'').toLowerCase();
130         },
131         
132         snippets : function(evt) {
133                 var snippets = Language.snippets;       
134                 var trigger = this.getLastWord();
135                 for (var i=0; i<snippets.length; i++) {
136                         if(snippets[i].input == trigger) {
137                                 var content = snippets[i].output.replace(/</g,'&lt;');
138                                 content = content.replace(/>/g,'&gt;');
139                                 if(content.indexOf('$0')<0) content += cc;
140                                 else content = content.replace(/\$0/,cc);
141                                 content = content.replace(/\n/g,'<br>');
142                                 var pattern = new RegExp(trigger+cc,'gi');
143                                 evt.preventDefault(); // prevent the tab key from being added
144                                 this.syntaxHighlight('snippets',pattern,content);
145                         }
146                 }
147         },
148         
149         readOnly : function() {
150                 document.designMode = (arguments[0]) ? 'off' : 'on';
151         },
152
153         complete : function(trigger) {
154                 window.getSelection().getRangeAt(0).deleteContents();
155                 var complete = Language.complete;
156                 for (var i=0; i<complete.length; i++) {
157                         if(complete[i].input == trigger) {
158                                 var pattern = new RegExp('\\'+trigger+cc);
159                                 var content = complete[i].output.replace(/\$0/g,cc);
160                                 parent.setTimeout(function () { CodePress.syntaxHighlight('complete',pattern,content)},0); // wait for char to appear on screen
161                         }
162                 }
163         },
164
165         getCompleteChars : function() {
166                 var cChars = '';
167                 for(var i=0;i<Language.complete.length;i++)
168                         cChars += '|'+Language.complete[i].input;
169                 return cChars+'|';
170         },
171         
172         getCompleteEndingChars : function() {
173                 var cChars = '';
174                 for(var i=0;i<Language.complete.length;i++)
175                         cChars += '|'+Language.complete[i].output.charAt(Language.complete[i].output.length-1);
176                 return cChars+'|';
177         },
178         
179         completeEnding : function(trigger) {
180                 var range = window.getSelection().getRangeAt(0);
181                 try {
182                         range.setEnd(range.endContainer, range.endOffset+1)
183                 }
184                 catch(e) {
185                         return false;
186                 }
187                 var next_character = range.toString()
188                 range.setEnd(range.endContainer, range.endOffset-1)
189                 if(next_character != trigger) return false;
190                 else {
191                         range.setEnd(range.endContainer, range.endOffset+1)
192                         range.deleteContents();
193                         return true;
194                 }
195         },
196         
197         shortcuts : function() {
198                 var cCode = arguments[0];
199                 if(cCode==13) cCode = '[enter]';
200                 else if(cCode==32) cCode = '[space]';
201                 else cCode = '['+String.fromCharCode(charCode).toLowerCase()+']';
202                 for(var i=0;i<Language.shortcuts.length;i++)
203                         if(Language.shortcuts[i].input == cCode)
204                                 this.insertCode(Language.shortcuts[i].output,false);
205         },
206         
207         getRangeAndCaret : function() { 
208                 var range = window.getSelection().getRangeAt(0);
209                 var range2 = range.cloneRange();
210                 var node = range.endContainer;                  
211                 var caret = range.endOffset;
212                 range2.selectNode(node);        
213                 return [range2.toString(),caret];
214         },
215         
216         insertCode : function(code,replaceCursorBefore) {
217                 var range = window.getSelection().getRangeAt(0);
218                 var node = window.document.createTextNode(code);
219                 var selct = window.getSelection();
220                 var range2 = range.cloneRange();
221                 // Insert text at cursor position
222                 selct.removeAllRanges();
223                 range.deleteContents();
224                 range.insertNode(node);
225                 // Move the cursor to the end of text
226                 range2.selectNode(node);                
227                 range2.collapse(replaceCursorBefore);
228                 selct.removeAllRanges();
229                 selct.addRange(range2);
230         },
231         
232         // get code from editor
233         getCode : function() {
234                 if(!document.getElementsByTagName('pre')[0] || editor.innerHTML == '')
235                         editor = CodePress.getEditor();
236                 var code = editor.innerHTML;
237                 code = code.replace(/<br>/g,'\n');
238                 code = code.replace(/\u2009/g,'');
239                 code = code.replace(/<.*?>/g,'');
240                 code = code.replace(/&lt;/g,'<');
241                 code = code.replace(/&gt;/g,'>');
242                 code = code.replace(/&amp;/gi,'&');
243                 return code;
244         },
245
246         // put code inside editor
247         setCode : function() {
248                 var code = arguments[0];
249                 code = code.replace(/\u2009/gi,'');
250                 code = code.replace(/&/gi,'&amp;');
251                 code = code.replace(/</g,'&lt;');
252                 code = code.replace(/>/g,'&gt;');
253                 editor.innerHTML = code;
254                 if (code == '')
255                         document.getElementsByTagName('body')[0].innerHTML = '';
256         },
257
258         // undo and redo methods
259         actions : {
260                 pos : -1, // actual history position
261                 history : [], // history vector
262                 
263                 undo : function() {
264                         editor = CodePress.getEditor();
265                         if(editor.innerHTML.indexOf(cc)==-1){
266                                 if(editor.innerHTML != " ")
267                                         window.getSelection().getRangeAt(0).insertNode(document.createTextNode(cc));
268                                 this.history[this.pos] = editor.innerHTML;
269                         }
270                         this.pos --;
271                         if(typeof(this.history[this.pos])=='undefined') this.pos ++;
272                         editor.innerHTML = this.history[this.pos];
273                         if(editor.innerHTML.indexOf(cc)>-1) editor.innerHTML+=cc;
274                         CodePress.findString();
275                 },
276                 
277                 redo : function() {
278                         // editor = CodePress.getEditor();
279                         this.pos++;
280                         if(typeof(this.history[this.pos])=='undefined') this.pos--;
281                         editor.innerHTML = this.history[this.pos];
282                         CodePress.findString();
283                 },
284                 
285                 next : function() { // get next vector position and clean old ones
286                         if(this.pos>20) this.history[this.pos-21] = undefined;
287                         return ++this.pos;
288                 }
289         }
290 }
291
292 Language={};
293 window.addEventListener('load', function() { CodePress.initialize('new'); }, true);