editarea-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. data/LICENSE.txt +22 -0
  2. data/README.md +31 -0
  3. data/lib/editarea-rails.rb +8 -0
  4. data/lib/editarea-rails/version.rb +5 -0
  5. data/vendor/assets/images/autocompletion.gif +0 -0
  6. data/vendor/assets/images/close.gif +0 -0
  7. data/vendor/assets/images/fullscreen.gif +0 -0
  8. data/vendor/assets/images/go_to_line.gif +0 -0
  9. data/vendor/assets/images/help.gif +0 -0
  10. data/vendor/assets/images/highlight.gif +0 -0
  11. data/vendor/assets/images/load.gif +0 -0
  12. data/vendor/assets/images/move.gif +0 -0
  13. data/vendor/assets/images/newdocument.gif +0 -0
  14. data/vendor/assets/images/opacity.png +0 -0
  15. data/vendor/assets/images/plugins/charmap/charmap.gif +0 -0
  16. data/vendor/assets/images/plugins/test/css/test.css +3 -0
  17. data/vendor/assets/images/plugins/test/images/Thumbs.db +0 -0
  18. data/vendor/assets/images/plugins/test/images/test.gif +0 -0
  19. data/vendor/assets/images/plugins/test/langs/bg.js +10 -0
  20. data/vendor/assets/images/plugins/test/langs/cs.js +4 -0
  21. data/vendor/assets/images/plugins/test/langs/de.js +4 -0
  22. data/vendor/assets/images/plugins/test/langs/dk.js +4 -0
  23. data/vendor/assets/images/plugins/test/langs/en.js +4 -0
  24. data/vendor/assets/images/plugins/test/langs/eo.js +4 -0
  25. data/vendor/assets/images/plugins/test/langs/es.js +4 -0
  26. data/vendor/assets/images/plugins/test/langs/fr.js +4 -0
  27. data/vendor/assets/images/plugins/test/langs/hr.js +4 -0
  28. data/vendor/assets/images/plugins/test/langs/it.js +4 -0
  29. data/vendor/assets/images/plugins/test/langs/ja.js +4 -0
  30. data/vendor/assets/images/plugins/test/langs/mk.js +4 -0
  31. data/vendor/assets/images/plugins/test/langs/nl.js +4 -0
  32. data/vendor/assets/images/plugins/test/langs/pl.js +4 -0
  33. data/vendor/assets/images/plugins/test/langs/pt.js +4 -0
  34. data/vendor/assets/images/plugins/test/langs/ru.js +4 -0
  35. data/vendor/assets/images/plugins/test/langs/sk.js +4 -0
  36. data/vendor/assets/images/plugins/test/langs/zh.js +4 -0
  37. data/vendor/assets/images/plugins/test/test.js +110 -0
  38. data/vendor/assets/images/plugins/test/test2.js +1 -0
  39. data/vendor/assets/images/processing.gif +0 -0
  40. data/vendor/assets/images/redo.gif +0 -0
  41. data/vendor/assets/images/reset_highlight.gif +0 -0
  42. data/vendor/assets/images/save.gif +0 -0
  43. data/vendor/assets/images/search.gif +0 -0
  44. data/vendor/assets/images/smooth_selection.gif +0 -0
  45. data/vendor/assets/images/spacer.gif +0 -0
  46. data/vendor/assets/images/statusbar_resize.gif +0 -0
  47. data/vendor/assets/images/undo.gif +0 -0
  48. data/vendor/assets/images/word_wrap.gif +0 -0
  49. data/vendor/assets/javascripts/autocompletion.js +491 -0
  50. data/vendor/assets/javascripts/edit_area.js +527 -0
  51. data/vendor/assets/javascripts/edit_area_full.js +38 -0
  52. data/vendor/assets/javascripts/edit_area_functions.js +1202 -0
  53. data/vendor/assets/javascripts/edit_area_loader.js +1081 -0
  54. data/vendor/assets/javascripts/elements_functions.js +336 -0
  55. data/vendor/assets/javascripts/highlight.js +407 -0
  56. data/vendor/assets/javascripts/keyboard.js +145 -0
  57. data/vendor/assets/javascripts/langs/bg.js +54 -0
  58. data/vendor/assets/javascripts/langs/cs.js +48 -0
  59. data/vendor/assets/javascripts/langs/de.js +48 -0
  60. data/vendor/assets/javascripts/langs/dk.js +48 -0
  61. data/vendor/assets/javascripts/langs/en.js +48 -0
  62. data/vendor/assets/javascripts/langs/eo.js +48 -0
  63. data/vendor/assets/javascripts/langs/es.js +48 -0
  64. data/vendor/assets/javascripts/langs/fi.js +48 -0
  65. data/vendor/assets/javascripts/langs/fr.js +48 -0
  66. data/vendor/assets/javascripts/langs/hr.js +48 -0
  67. data/vendor/assets/javascripts/langs/it.js +48 -0
  68. data/vendor/assets/javascripts/langs/ja.js +48 -0
  69. data/vendor/assets/javascripts/langs/mk.js +48 -0
  70. data/vendor/assets/javascripts/langs/nl.js +48 -0
  71. data/vendor/assets/javascripts/langs/pl.js +48 -0
  72. data/vendor/assets/javascripts/langs/pt.js +48 -0
  73. data/vendor/assets/javascripts/langs/ru.js +48 -0
  74. data/vendor/assets/javascripts/langs/sk.js +48 -0
  75. data/vendor/assets/javascripts/langs/zh.js +48 -0
  76. data/vendor/assets/javascripts/manage_area.js +623 -0
  77. data/vendor/assets/javascripts/plugins/charmap/charmap.js +90 -0
  78. data/vendor/assets/javascripts/plugins/charmap/jscripts/map.js +373 -0
  79. data/vendor/assets/javascripts/plugins/charmap/langs/bg.js +12 -0
  80. data/vendor/assets/javascripts/plugins/charmap/langs/cs.js +6 -0
  81. data/vendor/assets/javascripts/plugins/charmap/langs/de.js +6 -0
  82. data/vendor/assets/javascripts/plugins/charmap/langs/dk.js +6 -0
  83. data/vendor/assets/javascripts/plugins/charmap/langs/en.js +6 -0
  84. data/vendor/assets/javascripts/plugins/charmap/langs/eo.js +6 -0
  85. data/vendor/assets/javascripts/plugins/charmap/langs/es.js +6 -0
  86. data/vendor/assets/javascripts/plugins/charmap/langs/fr.js +6 -0
  87. data/vendor/assets/javascripts/plugins/charmap/langs/hr.js +6 -0
  88. data/vendor/assets/javascripts/plugins/charmap/langs/it.js +6 -0
  89. data/vendor/assets/javascripts/plugins/charmap/langs/ja.js +6 -0
  90. data/vendor/assets/javascripts/plugins/charmap/langs/mk.js +6 -0
  91. data/vendor/assets/javascripts/plugins/charmap/langs/nl.js +6 -0
  92. data/vendor/assets/javascripts/plugins/charmap/langs/pl.js +6 -0
  93. data/vendor/assets/javascripts/plugins/charmap/langs/pt.js +6 -0
  94. data/vendor/assets/javascripts/plugins/charmap/langs/ru.js +6 -0
  95. data/vendor/assets/javascripts/plugins/charmap/langs/sk.js +6 -0
  96. data/vendor/assets/javascripts/plugins/charmap/langs/zh.js +6 -0
  97. data/vendor/assets/javascripts/plugins/charmap/popup.html +24 -0
  98. data/vendor/assets/javascripts/plugins/test/langs/bg.js +10 -0
  99. data/vendor/assets/javascripts/plugins/test/langs/cs.js +4 -0
  100. data/vendor/assets/javascripts/plugins/test/langs/de.js +4 -0
  101. data/vendor/assets/javascripts/plugins/test/langs/dk.js +4 -0
  102. data/vendor/assets/javascripts/plugins/test/langs/en.js +4 -0
  103. data/vendor/assets/javascripts/plugins/test/langs/eo.js +4 -0
  104. data/vendor/assets/javascripts/plugins/test/langs/es.js +4 -0
  105. data/vendor/assets/javascripts/plugins/test/langs/fr.js +4 -0
  106. data/vendor/assets/javascripts/plugins/test/langs/hr.js +4 -0
  107. data/vendor/assets/javascripts/plugins/test/langs/it.js +4 -0
  108. data/vendor/assets/javascripts/plugins/test/langs/ja.js +4 -0
  109. data/vendor/assets/javascripts/plugins/test/langs/mk.js +4 -0
  110. data/vendor/assets/javascripts/plugins/test/langs/nl.js +4 -0
  111. data/vendor/assets/javascripts/plugins/test/langs/pl.js +4 -0
  112. data/vendor/assets/javascripts/plugins/test/langs/pt.js +4 -0
  113. data/vendor/assets/javascripts/plugins/test/langs/ru.js +4 -0
  114. data/vendor/assets/javascripts/plugins/test/langs/sk.js +4 -0
  115. data/vendor/assets/javascripts/plugins/test/langs/zh.js +4 -0
  116. data/vendor/assets/javascripts/plugins/test/test.js +110 -0
  117. data/vendor/assets/javascripts/plugins/test/test2.js +1 -0
  118. data/vendor/assets/javascripts/reg_syntax.js +166 -0
  119. data/vendor/assets/javascripts/reg_syntax/basic.js +70 -0
  120. data/vendor/assets/javascripts/reg_syntax/brainfuck.js +45 -0
  121. data/vendor/assets/javascripts/reg_syntax/c.js +63 -0
  122. data/vendor/assets/javascripts/reg_syntax/coldfusion.js +120 -0
  123. data/vendor/assets/javascripts/reg_syntax/cpp.js +66 -0
  124. data/vendor/assets/javascripts/reg_syntax/css.js +85 -0
  125. data/vendor/assets/javascripts/reg_syntax/html.js +51 -0
  126. data/vendor/assets/javascripts/reg_syntax/java.js +57 -0
  127. data/vendor/assets/javascripts/reg_syntax/js.js +94 -0
  128. data/vendor/assets/javascripts/reg_syntax/pas.js +83 -0
  129. data/vendor/assets/javascripts/reg_syntax/perl.js +88 -0
  130. data/vendor/assets/javascripts/reg_syntax/php.js +157 -0
  131. data/vendor/assets/javascripts/reg_syntax/python.js +145 -0
  132. data/vendor/assets/javascripts/reg_syntax/robotstxt.js +25 -0
  133. data/vendor/assets/javascripts/reg_syntax/ruby.js +68 -0
  134. data/vendor/assets/javascripts/reg_syntax/sql.js +56 -0
  135. data/vendor/assets/javascripts/reg_syntax/tsql.js +88 -0
  136. data/vendor/assets/javascripts/reg_syntax/vb.js +53 -0
  137. data/vendor/assets/javascripts/reg_syntax/xml.js +57 -0
  138. data/vendor/assets/javascripts/regexp.js +139 -0
  139. data/vendor/assets/javascripts/resize_area.js +73 -0
  140. data/vendor/assets/javascripts/search_replace.js +174 -0
  141. data/vendor/assets/stylesheets/edit_area.css +530 -0
  142. data/vendor/assets/stylesheets/plugins/charmap/css/charmap.css +64 -0
  143. data/vendor/assets/stylesheets/plugins/test/css/test.css +3 -0
  144. metadata +210 -0
@@ -0,0 +1,336 @@
1
+ /****
2
+ * This page contains some general usefull functions for javascript
3
+ *
4
+ ****/
5
+
6
+
7
+ // need to redefine this functiondue to IE problem
8
+ function getAttribute( elm, aName ) {
9
+ var aValue,taName,i;
10
+ try{
11
+ aValue = elm.getAttribute( aName );
12
+ }catch(exept){}
13
+
14
+ if( ! aValue ){
15
+ for( i = 0; i < elm.attributes.length; i ++ ) {
16
+ taName = elm.attributes[i] .name.toLowerCase();
17
+ if( taName == aName ) {
18
+ aValue = elm.attributes[i] .value;
19
+ return aValue;
20
+ }
21
+ }
22
+ }
23
+ return aValue;
24
+ };
25
+
26
+ // need to redefine this function due to IE problem
27
+ function setAttribute( elm, attr, val ) {
28
+ if(attr=="class"){
29
+ elm.setAttribute("className", val);
30
+ elm.setAttribute("class", val);
31
+ }else{
32
+ elm.setAttribute(attr, val);
33
+ }
34
+ };
35
+
36
+ /* return a child element
37
+ elem: element we are searching in
38
+ elem_type: type of the eleemnt we are searching (DIV, A, etc...)
39
+ elem_attribute: attribute of the searched element that must match
40
+ elem_attribute_match: value that elem_attribute must match
41
+ option: "all" if must return an array of all children, otherwise return the first match element
42
+ depth: depth of search (-1 or no set => unlimited)
43
+ */
44
+ function getChildren(elem, elem_type, elem_attribute, elem_attribute_match, option, depth)
45
+ {
46
+ if(!option)
47
+ var option="single";
48
+ if(!depth)
49
+ var depth=-1;
50
+ if(elem){
51
+ var children= elem.childNodes;
52
+ var result=null;
53
+ var results= [];
54
+ for (var x=0;x<children.length;x++) {
55
+ strTagName = new String(children[x].tagName);
56
+ children_class="?";
57
+ if(strTagName!= "undefined"){
58
+ child_attribute= getAttribute(children[x],elem_attribute);
59
+ if((strTagName.toLowerCase()==elem_type.toLowerCase() || elem_type=="") && (elem_attribute=="" || child_attribute==elem_attribute_match)){
60
+ if(option=="all"){
61
+ results.push(children[x]);
62
+ }else{
63
+ return children[x];
64
+ }
65
+ }
66
+ if(depth!=0){
67
+ result=getChildren(children[x], elem_type, elem_attribute, elem_attribute_match, option, depth-1);
68
+ if(option=="all"){
69
+ if(result.length>0){
70
+ results= results.concat(result);
71
+ }
72
+ }else if(result!=null){
73
+ return result;
74
+ }
75
+ }
76
+ }
77
+ }
78
+ if(option=="all")
79
+ return results;
80
+ }
81
+ return null;
82
+ };
83
+
84
+ function isChildOf(elem, parent){
85
+ if(elem){
86
+ if(elem==parent)
87
+ return true;
88
+ while(elem.parentNode != 'undefined'){
89
+ return isChildOf(elem.parentNode, parent);
90
+ }
91
+ }
92
+ return false;
93
+ };
94
+
95
+ function getMouseX(e){
96
+
97
+ if(e!=null && typeof(e.pageX)!="undefined"){
98
+ return e.pageX;
99
+ }else{
100
+ return (e!=null?e.x:event.x)+ document.documentElement.scrollLeft;
101
+ }
102
+ };
103
+
104
+ function getMouseY(e){
105
+ if(e!=null && typeof(e.pageY)!="undefined"){
106
+ return e.pageY;
107
+ }else{
108
+ return (e!=null?e.y:event.y)+ document.documentElement.scrollTop;
109
+ }
110
+ };
111
+
112
+ function calculeOffsetLeft(r){
113
+ return calculeOffset(r,"offsetLeft")
114
+ };
115
+
116
+ function calculeOffsetTop(r){
117
+ return calculeOffset(r,"offsetTop")
118
+ };
119
+
120
+ function calculeOffset(element,attr){
121
+ var offset=0;
122
+ while(element){
123
+ offset+=element[attr];
124
+ element=element.offsetParent
125
+ }
126
+ return offset;
127
+ };
128
+
129
+ /** return the computed style
130
+ * @param: elem: the reference to the element
131
+ * @param: prop: the name of the css property
132
+ */
133
+ function get_css_property(elem, prop)
134
+ {
135
+ if(document.defaultView)
136
+ {
137
+ return document.defaultView.getComputedStyle(elem, null).getPropertyValue(prop);
138
+ }
139
+ else if(elem.currentStyle)
140
+ {
141
+ var prop = prop.replace(/-\D/gi, function(sMatch)
142
+ {
143
+ return sMatch.charAt(sMatch.length - 1).toUpperCase();
144
+ });
145
+ return elem.currentStyle[prop];
146
+ }
147
+ else return null;
148
+ }
149
+
150
+ /****
151
+ * Moving an element
152
+ ***/
153
+
154
+ var _mCE; // currently moving element
155
+
156
+ /* allow to move an element in a window
157
+ e: the event
158
+ id: the id of the element
159
+ frame: the frame of the element
160
+ ex of use:
161
+ in html: <img id='move_area_search_replace' onmousedown='return parent.start_move_element(event,"area_search_replace", parent.frames["this_frame_id"]);' .../>
162
+ or
163
+ in javascript: document.getElementById("my_div").onmousedown= start_move_element
164
+ */
165
+ function start_move_element(e, id, frame){
166
+ var elem_id=(e.target || e.srcElement).id;
167
+ if(id)
168
+ elem_id=id;
169
+ if(!frame)
170
+ frame=window;
171
+ if(frame.event)
172
+ e=frame.event;
173
+
174
+ _mCE= frame.document.getElementById(elem_id);
175
+ _mCE.frame=frame;
176
+ frame.document.onmousemove= move_element;
177
+ frame.document.onmouseup= end_move_element;
178
+ /*_mCE.onmousemove= move_element;
179
+ _mCE.onmouseup= end_move_element;*/
180
+
181
+ //alert(_mCE.frame.document.body.offsetHeight);
182
+
183
+ mouse_x= getMouseX(e);
184
+ mouse_y= getMouseY(e);
185
+ //window.status=frame+ " elem: "+elem_id+" elem: "+ _mCE + " mouse_x: "+mouse_x;
186
+ _mCE.start_pos_x = mouse_x - (_mCE.style.left.replace("px","") || calculeOffsetLeft(_mCE));
187
+ _mCE.start_pos_y = mouse_y - (_mCE.style.top.replace("px","") || calculeOffsetTop(_mCE));
188
+ return false;
189
+ };
190
+
191
+ function end_move_element(e){
192
+ _mCE.frame.document.onmousemove= "";
193
+ _mCE.frame.document.onmouseup= "";
194
+ _mCE=null;
195
+ };
196
+
197
+ function move_element(e){
198
+ var newTop,newLeft,maxLeft;
199
+
200
+ if( _mCE.frame && _mCE.frame.event )
201
+ e=_mCE.frame.event;
202
+ newTop = getMouseY(e) - _mCE.start_pos_y;
203
+ newLeft = getMouseX(e) - _mCE.start_pos_x;
204
+
205
+ maxLeft = _mCE.frame.document.body.offsetWidth- _mCE.offsetWidth;
206
+ max_top = _mCE.frame.document.body.offsetHeight- _mCE.offsetHeight;
207
+ newTop = Math.min(Math.max(0, newTop), max_top);
208
+ newLeft = Math.min(Math.max(0, newLeft), maxLeft);
209
+
210
+ _mCE.style.top = newTop+"px";
211
+ _mCE.style.left = newLeft+"px";
212
+ return false;
213
+ };
214
+
215
+ /***
216
+ * Managing a textarea (this part need the navigator infos from editAreaLoader
217
+ ***/
218
+
219
+ var nav= editAreaLoader.nav;
220
+
221
+ // allow to get infos on the selection: array(start, end)
222
+ function getSelectionRange(textarea){
223
+ return {"start": textarea.selectionStart, "end": textarea.selectionEnd};
224
+ };
225
+
226
+ // allow to set the selection
227
+ function setSelectionRange(t, start, end){
228
+ t.focus();
229
+
230
+ start = Math.max(0, Math.min(t.value.length, start));
231
+ end = Math.max(start, Math.min(t.value.length, end));
232
+
233
+ if( nav.isOpera && nav.isOpera < 9.6 ){ // Opera bug when moving selection start and selection end
234
+ t.selectionEnd = 1;
235
+ t.selectionStart = 0;
236
+ t.selectionEnd = 1;
237
+ t.selectionStart = 0;
238
+ }
239
+ t.selectionStart = start;
240
+ t.selectionEnd = end;
241
+ //textarea.setSelectionRange(start, end);
242
+
243
+ if(nav.isIE)
244
+ set_IE_selection(t);
245
+ };
246
+
247
+
248
+ // set IE position in Firefox mode (textarea.selectionStart and textarea.selectionEnd). should work as a repeated task
249
+ function get_IE_selection(t){
250
+ var d=document,div,range,stored_range,elem,scrollTop,relative_top,line_start,line_nb,range_start,range_end,tab;
251
+ if(t && t.focused)
252
+ {
253
+ if(!t.ea_line_height)
254
+ { // calculate the lineHeight
255
+ div= d.createElement("div");
256
+ div.style.fontFamily= get_css_property(t, "font-family");
257
+ div.style.fontSize= get_css_property(t, "font-size");
258
+ div.style.visibility= "hidden";
259
+ div.innerHTML="0";
260
+ d.body.appendChild(div);
261
+ t.ea_line_height= div.offsetHeight;
262
+ d.body.removeChild(div);
263
+ }
264
+ //t.focus();
265
+ range = d.selection.createRange();
266
+ try
267
+ {
268
+ stored_range = range.duplicate();
269
+ stored_range.moveToElementText( t );
270
+ stored_range.setEndPoint( 'EndToEnd', range );
271
+ if(stored_range.parentElement() == t){
272
+ // the range don't take care of empty lines in the end of the selection
273
+ elem = t;
274
+ scrollTop = 0;
275
+ while(elem.parentNode){
276
+ scrollTop+= elem.scrollTop;
277
+ elem = elem.parentNode;
278
+ }
279
+
280
+ // var scrollTop= t.scrollTop + document.body.scrollTop;
281
+
282
+ // var relative_top= range.offsetTop - calculeOffsetTop(t) + scrollTop;
283
+ relative_top= range.offsetTop - calculeOffsetTop(t)+ scrollTop;
284
+ // alert("rangeoffset: "+ range.offsetTop +"\ncalcoffsetTop: "+ calculeOffsetTop(t) +"\nrelativeTop: "+ relative_top);
285
+ line_start = Math.round((relative_top / t.ea_line_height) +1);
286
+
287
+ line_nb = Math.round(range.boundingHeight / t.ea_line_height);
288
+
289
+ range_start = stored_range.text.length - range.text.length;
290
+ tab = t.value.substr(0, range_start).split("\n");
291
+ range_start += (line_start - tab.length)*2; // add missing empty lines to the selection
292
+ t.selectionStart = range_start;
293
+
294
+ range_end = t.selectionStart + range.text.length;
295
+ tab = t.value.substr(0, range_start + range.text.length).split("\n");
296
+ range_end += (line_start + line_nb - 1 - tab.length)*2;
297
+ t.selectionEnd = range_end;
298
+ }
299
+ }
300
+ catch(e){}
301
+ }
302
+ if( t && t.id )
303
+ {
304
+ setTimeout("get_IE_selection(document.getElementById('"+ t.id +"'));", 50);
305
+ }
306
+ };
307
+
308
+ function IE_textarea_focus(){
309
+ event.srcElement.focused= true;
310
+ }
311
+
312
+ function IE_textarea_blur(){
313
+ event.srcElement.focused= false;
314
+ }
315
+
316
+ // select the text for IE (take into account the \r difference)
317
+ function set_IE_selection( t ){
318
+ var nbLineStart,nbLineStart,nbLineEnd,range;
319
+ if(!window.closed){
320
+ nbLineStart=t.value.substr(0, t.selectionStart).split("\n").length - 1;
321
+ nbLineEnd=t.value.substr(0, t.selectionEnd).split("\n").length - 1;
322
+ try
323
+ {
324
+ range = document.selection.createRange();
325
+ range.moveToElementText( t );
326
+ range.setEndPoint( 'EndToStart', range );
327
+ range.moveStart('character', t.selectionStart - nbLineStart);
328
+ range.moveEnd('character', t.selectionEnd - nbLineEnd - (t.selectionStart - nbLineStart) );
329
+ range.select();
330
+ }
331
+ catch(e){}
332
+ }
333
+ };
334
+
335
+
336
+ editAreaLoader.waiting_loading["elements_functions.js"]= "loaded";
@@ -0,0 +1,407 @@
1
+ // change_to: "on" or "off"
2
+ EditArea.prototype.change_highlight= function(change_to){
3
+ if(this.settings["syntax"].length==0 && change_to==false){
4
+ this.switchClassSticky(_$("highlight"), 'editAreaButtonDisabled', true);
5
+ this.switchClassSticky(_$("reset_highlight"), 'editAreaButtonDisabled', true);
6
+ return false;
7
+ }
8
+
9
+ if(this.do_highlight==change_to)
10
+ return false;
11
+
12
+
13
+ this.getIESelection();
14
+ var pos_start= this.textarea.selectionStart;
15
+ var pos_end= this.textarea.selectionEnd;
16
+
17
+ if(this.do_highlight===true || change_to==false)
18
+ this.disable_highlight();
19
+ else
20
+ this.enable_highlight();
21
+ this.textarea.focus();
22
+ this.textarea.selectionStart = pos_start;
23
+ this.textarea.selectionEnd = pos_end;
24
+ this.setIESelection();
25
+
26
+ };
27
+
28
+ EditArea.prototype.disable_highlight= function(displayOnly){
29
+ var t= this, a=t.textarea, new_Obj, old_class, new_class;
30
+
31
+ t.selection_field.innerHTML="";
32
+ t.selection_field_text.innerHTML="";
33
+ t.content_highlight.style.visibility="hidden";
34
+ // replacing the node is far more faster than deleting it's content in firefox
35
+ new_Obj= t.content_highlight.cloneNode(false);
36
+ new_Obj.innerHTML= "";
37
+ t.content_highlight.parentNode.insertBefore(new_Obj, t.content_highlight);
38
+ t.content_highlight.parentNode.removeChild(t.content_highlight);
39
+ t.content_highlight= new_Obj;
40
+ old_class= parent.getAttribute( a,"class" );
41
+ if(old_class){
42
+ new_class= old_class.replace( "hidden","" );
43
+ parent.setAttribute( a, "class", new_class );
44
+ }
45
+
46
+ a.style.backgroundColor="transparent"; // needed in order to see the bracket finders
47
+
48
+ //var icon= document.getElementById("highlight");
49
+ //setAttribute(icon, "class", getAttribute(icon, "class").replace(/ selected/g, "") );
50
+ //t.restoreClass(icon);
51
+ //t.switchClass(icon,'editAreaButtonNormal');
52
+ t.switchClassSticky(_$("highlight"), 'editAreaButtonNormal', true);
53
+ t.switchClassSticky(_$("reset_highlight"), 'editAreaButtonDisabled', true);
54
+
55
+ t.do_highlight=false;
56
+
57
+ t.switchClassSticky(_$("change_smooth_selection"), 'editAreaButtonSelected', true);
58
+ if(typeof(t.smooth_selection_before_highlight)!="undefined" && t.smooth_selection_before_highlight===false){
59
+ t.change_smooth_selection_mode(false);
60
+ }
61
+
62
+ // this.textarea.style.backgroundColor="#FFFFFF";
63
+ };
64
+
65
+ EditArea.prototype.enable_highlight= function(){
66
+ var t=this, a=t.textarea, new_class;
67
+ t.show_waiting_screen();
68
+
69
+ t.content_highlight.style.visibility="visible";
70
+ new_class =parent.getAttribute(a,"class")+" hidden";
71
+ parent.setAttribute( a, "class", new_class );
72
+
73
+ // IE can't manage mouse click outside text range without this
74
+ if( t.isIE )
75
+ a.style.backgroundColor="#FFFFFF";
76
+
77
+ t.switchClassSticky(_$("highlight"), 'editAreaButtonSelected', false);
78
+ t.switchClassSticky(_$("reset_highlight"), 'editAreaButtonNormal', false);
79
+
80
+ t.smooth_selection_before_highlight=t.smooth_selection;
81
+ if(!t.smooth_selection)
82
+ t.change_smooth_selection_mode(true);
83
+ t.switchClassSticky(_$("change_smooth_selection"), 'editAreaButtonDisabled', true);
84
+
85
+
86
+ t.do_highlight=true;
87
+ t.resync_highlight();
88
+
89
+ t.hide_waiting_screen();
90
+ };
91
+
92
+ /**
93
+ * Ask to update highlighted text
94
+ * @param Array infos - Array of datas returned by EditArea.get_selection_infos()
95
+ */
96
+ EditArea.prototype.maj_highlight= function(infos){
97
+ // for speed mesure
98
+ var debug_opti="",tps_start= new Date().getTime(), tps_middle_opti=new Date().getTime();
99
+ var t=this, hightlighted_text, updated_highlight;
100
+ var textToHighlight=infos["full_text"], doSyntaxOpti = false, doHtmlOpti = false, stay_begin="", stay_end="", trace_new , trace_last;
101
+
102
+ if(t.last_text_to_highlight==infos["full_text"] && t.resync_highlight!==true)
103
+ return;
104
+
105
+ // OPTIMISATION: will search to update only changed lines
106
+ if(t.reload_highlight===true){
107
+ t.reload_highlight=false;
108
+ }else if(textToHighlight.length==0){
109
+ textToHighlight="\n ";
110
+ }else{
111
+ // get text change datas
112
+ changes = t.checkTextEvolution(t.last_text_to_highlight,textToHighlight);
113
+
114
+ // check if it can only reparse the changed text
115
+ trace_new = t.get_syntax_trace(changes.newTextLine).replace(/\r/g, '');
116
+ trace_last = t.get_syntax_trace(changes.lastTextLine).replace(/\r/g, '');
117
+ doSyntaxOpti = ( trace_new == trace_last );
118
+
119
+ // check if the difference comes only from a new line created
120
+ // => we have to remember that the editor can automaticaly add tabulation or space after the new line)
121
+ if( !doSyntaxOpti && trace_new == "\n"+trace_last && /^[ \t\s]*\n[ \t\s]*$/.test( changes.newText.replace(/\r/g, '') ) && changes.lastText =="" )
122
+ {
123
+ doSyntaxOpti = true;
124
+ }
125
+
126
+ // we do the syntax optimisation
127
+ if( doSyntaxOpti ){
128
+
129
+ tps_middle_opti=new Date().getTime();
130
+
131
+ stay_begin= t.last_hightlighted_text.split("\n").slice(0, changes.lineStart).join("\n");
132
+ if(changes.lineStart>0)
133
+ stay_begin+= "\n";
134
+ stay_end= t.last_hightlighted_text.split("\n").slice(changes.lineLastEnd+1).join("\n");
135
+ if(stay_end.length>0)
136
+ stay_end= "\n"+stay_end;
137
+
138
+ // Final check to see that we're not in the middle of span tags
139
+ if( stay_begin.split('<span').length != stay_begin.split('</span').length
140
+ || stay_end.split('<span').length != stay_end.split('</span').length )
141
+ {
142
+ doSyntaxOpti = false;
143
+ stay_end = '';
144
+ stay_begin = '';
145
+ }
146
+ else
147
+ {
148
+ if(stay_begin.length==0 && changes.posLastEnd==-1)
149
+ changes.newTextLine+="\n";
150
+ textToHighlight=changes.newTextLine;
151
+ }
152
+ }
153
+ if(t.settings["debug"]){
154
+ var ch =changes;
155
+ debug_opti= ( doSyntaxOpti?"Optimisation": "No optimisation" )
156
+ +" start: "+ch.posStart +"("+ch.lineStart+")"
157
+ +" end_new: "+ ch.posNewEnd+"("+ch.lineNewEnd+")"
158
+ +" end_last: "+ ch.posLastEnd+"("+ch.lineLastEnd+")"
159
+ +"\nchanged_text: "+ch.newText+" => trace: "+trace_new
160
+ +"\nchanged_last_text: "+ch.lastText+" => trace: "+trace_last
161
+ //debug_opti+= "\nchanged: "+ infos["full_text"].substring(ch.posStart, ch.posNewEnd);
162
+ + "\nchanged_line: "+ch.newTextLine
163
+ + "\nlast_changed_line: "+ch.lastTextLine
164
+ +"\nstay_begin: "+ stay_begin.slice(-100)
165
+ +"\nstay_end: "+ stay_end.substr( 0, 100 );
166
+ //debug_opti="start: "+stay_begin_len+ "("+nb_line_start_unchanged+") end: "+ (stay_end_len)+ "("+(splited.length-nb_line_end_unchanged)+") ";
167
+ //debug_opti+="changed: "+ textToHighlight.substring(stay_begin_len, textToHighlight.length-stay_end_len)+" \n";
168
+
169
+ //debug_opti+="changed: "+ stay_begin.substr(stay_begin.length-200)+ "----------"+ textToHighlight+"------------------"+ stay_end.substr(0,200) +"\n";
170
+ +"\n";
171
+ }
172
+
173
+
174
+ // END OPTIMISATION
175
+ }
176
+
177
+ tps_end_opti = new Date().getTime();
178
+
179
+ // apply highlight
180
+ updated_highlight = t.colorize_text(textToHighlight);
181
+ tpsAfterReg = new Date().getTime();
182
+
183
+ /***
184
+ * see if we can optimize for updating only the required part of the HTML code
185
+ *
186
+ * The goal here will be to find the text node concerned by the modification and to update it
187
+ */
188
+ //-------------------------------------------
189
+
190
+ // disable latest optimization tricks (introduced in 0.8.1 and removed in 0.8.2), TODO: check for another try later
191
+ doSyntaxOpti = doHtmlOpti = false;
192
+ if( doSyntaxOpti )
193
+ {
194
+ try
195
+ {
196
+ var replacedBloc, i, nbStart = '', nbEnd = '', newHtml, lengthOld, lengthNew;
197
+ replacedBloc = t.last_hightlighted_text.substring( stay_begin.length, t.last_hightlighted_text.length - stay_end.length );
198
+
199
+ lengthOld = replacedBloc.length;
200
+ lengthNew = updated_highlight.length;
201
+
202
+ // find the identical caracters at the beginning
203
+ for( i=0; i < lengthOld && i < lengthNew && replacedBloc.charAt(i) == updated_highlight.charAt(i) ; i++ )
204
+ {
205
+ }
206
+ nbStart = i;
207
+ // find the identical caracters at the end
208
+ for( i=0; i + nbStart < lengthOld && i + nbStart < lengthNew && replacedBloc.charAt(lengthOld-i-1) == updated_highlight.charAt(lengthNew-i-1) ; i++ )
209
+ {
210
+ }
211
+ nbEnd = i;
212
+ //console.log( nbStart, nbEnd, replacedBloc, updated_highlight );
213
+ // get the changes
214
+ lastHtml = replacedBloc.substring( nbStart, lengthOld - nbEnd );
215
+ newHtml = updated_highlight.substring( nbStart, lengthNew - nbEnd );
216
+
217
+ // We can do the optimisation only if we havn't touch to span elements
218
+ if( newHtml.indexOf('<span') == -1 && newHtml.indexOf('</span') == -1
219
+ && lastHtml.indexOf('<span') == -1 && lastHtml.indexOf('</span') == -1 )
220
+ {
221
+ var beginStr, nbOpendedSpan, nbClosedSpan, nbUnchangedChars, span, textNode;
222
+ doHtmlOpti = true;
223
+ beginStr = t.last_hightlighted_text.substr( 0, stay_begin.length + nbStart );
224
+ // fix special chars
225
+ newHtml = newHtml.replace( /&lt;/g, '<').replace( /&gt;/g, '>').replace( /&amp;/g, '&');
226
+
227
+ nbOpendedSpan = beginStr.split('<span').length - 1;
228
+ nbClosedSpan = beginStr.split('</span').length - 1;
229
+ // retrieve the previously opened span (Add 1 for the first level span?)
230
+ span = t.content_highlight.getElementsByTagName('span')[ nbOpendedSpan ];
231
+
232
+ //--------[
233
+ // get the textNode to update
234
+
235
+ // if we're inside a span, we'll take the one that is opened (can be a parent of the current span)
236
+ parentSpan = span;
237
+ maxStartOffset = maxEndOffset = 0;
238
+
239
+ // it will be in the child of the root node
240
+ if( nbOpendedSpan == nbClosedSpan )
241
+ {
242
+ while( parentSpan.parentNode != t.content_highlight && parentSpan.parentNode.tagName != 'PRE' )
243
+ {
244
+ parentSpan = parentSpan.parentNode;
245
+ }
246
+ }
247
+ // get the last opened span
248
+ else
249
+ {
250
+ maxStartOffset = maxEndOffset = beginStr.length + 1;
251
+ // move to parent node for each closed span found after the lastest open span
252
+ nbClosed = beginStr.substr( Math.max( 0, beginStr.lastIndexOf( '<span', maxStartOffset - 1 ) ) ).split('</span').length - 1;
253
+ while( nbClosed > 0 )
254
+ {
255
+ nbClosed--;
256
+ parentSpan = parentSpan.parentNode;
257
+ }
258
+
259
+ // find the position of the last opended tag
260
+ while( parentSpan.parentNode != t.content_highlight && parentSpan.parentNode.tagName != 'PRE' && ( tmpMaxStartOffset = Math.max( 0, beginStr.lastIndexOf( '<span', maxStartOffset - 1 ) ) ) < ( tmpMaxEndOffset = Math.max( 0, beginStr.lastIndexOf( '</span', maxEndOffset - 1 ) ) ) )
261
+ {
262
+ maxStartOffset = tmpMaxStartOffset;
263
+ maxEndOffset = tmpMaxEndOffset;
264
+ }
265
+ }
266
+ // Note: maxEndOffset is no more used but maxStartOffset will be used
267
+
268
+ if( parentSpan.parentNode == t.content_highlight || parentSpan.parentNode.tagName == 'PRE' )
269
+ {
270
+ maxStartOffset = Math.max( 0, beginStr.indexOf( '<span' ) );
271
+ }
272
+
273
+ // find the matching text node (this will be one that will be at the end of the beginStr
274
+ if( maxStartOffset == beginStr.length )
275
+ {
276
+ nbSubSpanBefore = 0;
277
+ }
278
+ else
279
+ {
280
+ lastEndPos = Math.max( 0, beginStr.lastIndexOf( '>', maxStartOffset ) );
281
+
282
+ // count the number of sub spans
283
+ nbSubSpanBefore = beginStr.substr( lastEndPos ).split('<span').length-1;
284
+ }
285
+
286
+ // there is no sub-span before
287
+ if( nbSubSpanBefore == 0 )
288
+ {
289
+ textNode = parentSpan.firstChild;
290
+ }
291
+ // we need to find where is the text node modified
292
+ else
293
+ {
294
+ // take the last direct child (no sub-child)
295
+ lastSubSpan = parentSpan.getElementsByTagName('span')[ nbSubSpanBefore - 1 ];
296
+ while( lastSubSpan.parentNode != parentSpan )
297
+ {
298
+ lastSubSpan = lastSubSpan.parentNode;
299
+ }
300
+
301
+ // associate to next text node following the last sub span
302
+ if( lastSubSpan.nextSibling == null || lastSubSpan.nextSibling.nodeType != 3 )
303
+ {
304
+ textNode = document.createTextNode('');
305
+ lastSubSpan.parentNode.insertBefore( textNode, lastSubSpan.nextSibling );
306
+ }
307
+ else
308
+ {
309
+ textNode = lastSubSpan.nextSibling;
310
+ }
311
+ }
312
+ //--------]
313
+
314
+
315
+ //--------[
316
+ // update the textNode content
317
+
318
+ // number of caracters after the last opened of closed span
319
+ //nbUnchangedChars = ( lastIndex = beginStr.lastIndexOf( '>' ) ) == -1 ? beginStr.length : beginStr.length - ( lastIndex + 1 );
320
+ //nbUnchangedChars = ? beginStr.length : beginStr.substr( lastIndex + 1 ).replace( /&lt;/g, '<').replace( /&gt;/g, '>').replace( /&amp;/g, '&').length;
321
+
322
+ if( ( lastIndex = beginStr.lastIndexOf( '>' ) ) == -1 )
323
+ {
324
+ nbUnchangedChars = beginStr.length;
325
+ }
326
+ else
327
+ {
328
+ nbUnchangedChars = beginStr.substr( lastIndex + 1 ).replace( /&lt;/g, '<').replace( /&gt;/g, '>').replace( /&amp;/g, '&').length;
329
+ //nbUnchangedChars += beginStr.substr( ).replace( /&/g, '&amp;').replace( /</g, '&lt;').replace( />/g, '&gt;').length - beginStr.length;
330
+ }
331
+ //alert( nbUnchangedChars );
332
+ // console.log( span, textNode, nbOpendedSpan,nbClosedSpan, span.nextSibling, textNode.length, nbUnchangedChars, lastHtml, lastHtml.length, newHtml, newHtml.length );
333
+ // alert( textNode.parentNode.className +'-'+ textNode.parentNode.tagName+"\n"+ textNode.data +"\n"+ nbUnchangedChars +"\n"+ lastHtml.length +"\n"+ newHtml +"\n"+ newHtml.length );
334
+ // console.log( nbUnchangedChars, lastIndex, beginStr.length, beginStr.replace(/&/g, '&amp;'), lastHtml.length, '|', newHtml.replace( /\t/g, 't').replace( /\n/g, 'n').replace( /\r/g, 'r'), lastHtml.replace( /\t/g, 't').replace( /\n/g, 'n').replace( /\r/, 'r') );
335
+ // console.log( textNode.data.replace(/&/g, '&amp;') );
336
+ // IE only manage \r for cariage return in textNode and not \n or \r\n
337
+ if( t.isIE )
338
+ {
339
+ nbUnchangedChars -= ( beginStr.substr( beginStr.length - nbUnchangedChars ).split("\n").length - 1 );
340
+ //alert( textNode.data.replace(/\r/g, '_r').replace(/\n/g, '_n'));
341
+ textNode.replaceData( nbUnchangedChars, lastHtml.replace(/\n/g, '').length, newHtml.replace(/\n/g, '') );
342
+ }
343
+ else
344
+ {
345
+ textNode.replaceData( nbUnchangedChars, lastHtml.length, newHtml );
346
+ }
347
+ //--------]
348
+ }
349
+ }
350
+ // an exception shouldn't occured but if replaceData failed at least it won't break everything
351
+ catch( e )
352
+ {
353
+ // throw e;
354
+ // console.log( e );
355
+ doHtmlOpti = false;
356
+ }
357
+
358
+ }
359
+
360
+ /*** END HTML update's optimisation ***/
361
+ // end test
362
+
363
+ // console.log( (TPS6-TPS5), (TPS5-TPS4), (TPS4-TPS3), (TPS3-TPS2), (TPS2-TPS1), _CPT );
364
+ // get the new highlight content
365
+ tpsAfterOpti2 = new Date().getTime();
366
+ hightlighted_text = stay_begin + updated_highlight + stay_end;
367
+ if( !doHtmlOpti )
368
+ {
369
+ // update the content of the highlight div by first updating a clone node (as there is no display in the same time for t node it's quite faster (5*))
370
+ var new_Obj= t.content_highlight.cloneNode(false);
371
+ if( ( t.isIE && t.isIE < 8 ) || ( t.isOpera && t.isOpera < 9.6 ) )
372
+ new_Obj.innerHTML= "<pre><span class='"+ t.settings["syntax"] +"'>" + hightlighted_text + "</span></pre>";
373
+ else
374
+ new_Obj.innerHTML= "<span class='"+ t.settings["syntax"] +"'>"+ hightlighted_text +"</span>";
375
+
376
+ t.content_highlight.parentNode.replaceChild(new_Obj, t.content_highlight);
377
+
378
+ t.content_highlight= new_Obj;
379
+ }
380
+
381
+ t.last_text_to_highlight= infos["full_text"];
382
+ t.last_hightlighted_text= hightlighted_text;
383
+
384
+ tps3=new Date().getTime();
385
+
386
+ if(t.settings["debug"]){
387
+ //lineNumber=tab_text.length;
388
+ //t.debug.value+=" \nNB char: "+_$("src").value.length+" Nb line: "+ lineNumber;
389
+
390
+ t.debug.value= "Tps optimisation "+(tps_end_opti-tps_start)
391
+ +" | tps reg exp: "+ (tpsAfterReg-tps_end_opti)
392
+ +" | tps opti HTML : "+ (tpsAfterOpti2-tpsAfterReg) + ' '+ ( doHtmlOpti ? 'yes' : 'no' )
393
+ +" | tps update highlight content: "+ (tps3-tpsAfterOpti2)
394
+ +" | tpsTotal: "+ (tps3-tps_start)
395
+ + "("+tps3+")\n"+ debug_opti;
396
+ // t.debug.value+= "highlight\n"+hightlighted_text;*/
397
+ }
398
+
399
+ };
400
+
401
+ EditArea.prototype.resync_highlight= function(reload_now){
402
+ this.reload_highlight=true;
403
+ this.last_text_to_highlight="";
404
+ this.focus();
405
+ if(reload_now)
406
+ this.check_line_selection(false);
407
+ };