233
by mattgiuca
Added a shaky implementation of EditArea as the text editor. |
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(document.getElementById("highlight"), 'editAreaButtonDisabled', true); |
|
5 |
this.switchClassSticky(document.getElementById("reset_highlight"), 'editAreaButtonDisabled', true); |
|
6 |
return false; |
|
7 |
}
|
|
8 |
||
9 |
if(this.do_highlight==change_to) |
|
10 |
return false; |
|
11 |
||
12 |
||
13 |
if(this.nav['isIE']) |
|
14 |
this.getIESelection(); |
|
15 |
var pos_start= this.textarea.selectionStart; |
|
16 |
var pos_end= this.textarea.selectionEnd; |
|
17 |
||
18 |
if(this.do_highlight===true || change_to==false) |
|
19 |
this.disable_highlight(); |
|
20 |
else
|
|
21 |
this.enable_highlight(); |
|
22 |
this.textarea.focus(); |
|
23 |
this.textarea.selectionStart = pos_start; |
|
24 |
this.textarea.selectionEnd = pos_end; |
|
25 |
if(this.nav['isIE']) |
|
26 |
this.setIESelection(); |
|
27 |
||
28 |
};
|
|
29 |
||
30 |
EditArea.prototype.disable_highlight= function(displayOnly){ |
|
31 |
document.getElementById("selection_field").innerHTML=""; |
|
32 |
this.content_highlight.style.visibility="hidden"; |
|
33 |
// replacing the node is far more faster than deleting it's content in firefox
|
|
34 |
var new_Obj= this.content_highlight.cloneNode(false); |
|
35 |
new_Obj.innerHTML= ""; |
|
36 |
this.content_highlight.parentNode.insertBefore(new_Obj, this.content_highlight); |
|
37 |
this.content_highlight.parentNode.removeChild(this.content_highlight); |
|
38 |
this.content_highlight= new_Obj; |
|
39 |
var old_class= parent.getAttribute(this.textarea,"class"); |
|
40 |
if(old_class){ |
|
41 |
var new_class= old_class.replace("hidden",""); |
|
42 |
parent.setAttribute(this.textarea, "class", new_class); |
|
43 |
}
|
|
44 |
||
45 |
this.textarea.style.backgroundColor="transparent"; // needed in order to see the bracket finders |
|
46 |
||
47 |
//var icon= document.getElementById("highlight");
|
|
48 |
//setAttribute(icon, "class", getAttribute(icon, "class").replace(/ selected/g, "") );
|
|
49 |
//this.restoreClass(icon);
|
|
50 |
//this.switchClass(icon,'editAreaButtonNormal');
|
|
51 |
this.switchClassSticky(document.getElementById("highlight"), 'editAreaButtonNormal', true); |
|
52 |
this.switchClassSticky(document.getElementById("reset_highlight"), 'editAreaButtonDisabled', true); |
|
53 |
||
54 |
this.do_highlight=false; |
|
55 |
||
56 |
this.switchClassSticky(document.getElementById("change_smooth_selection"), 'editAreaButtonSelected', true); |
|
57 |
if(typeof(this.smooth_selection_before_highlight)!="undefined" && this.smooth_selection_before_highlight===false){ |
|
58 |
this.change_smooth_selection_mode(false); |
|
59 |
}
|
|
60 |
||
61 |
// this.textarea.style.backgroundColor="#FFFFFF";
|
|
62 |
};
|
|
63 |
||
64 |
EditArea.prototype.enable_highlight= function(){ |
|
65 |
this.show_waiting_screen(); |
|
66 |
||
67 |
this.content_highlight.style.visibility="visible"; |
|
68 |
var new_class=parent.getAttribute(this.textarea,"class")+" hidden"; |
|
69 |
parent.setAttribute(this.textarea, "class", new_class); |
|
70 |
||
71 |
if(this.nav['isIE']) |
|
72 |
this.textarea.style.backgroundColor="#FFFFFF"; // IE can't manage mouse click outside text range without this |
|
73 |
||
74 |
//var icon= document.getElementById("highlight");
|
|
75 |
//setAttribute(icon, "class", getAttribute(icon, "class") + " selected");
|
|
76 |
//this.switchClass(icon,'editAreaButtonSelected');
|
|
77 |
//this.switchClassSticky(document.getElementById("highlight"), 'editAreaButtonNormal', false);
|
|
78 |
this.switchClassSticky(document.getElementById("highlight"), 'editAreaButtonSelected', false); |
|
79 |
this.switchClassSticky(document.getElementById("reset_highlight"), 'editAreaButtonNormal', false); |
|
80 |
||
81 |
this.smooth_selection_before_highlight=this.smooth_selection; |
|
82 |
if(!this.smooth_selection) |
|
83 |
this.change_smooth_selection_mode(true); |
|
84 |
this.switchClassSticky(document.getElementById("change_smooth_selection"), 'editAreaButtonDisabled', true); |
|
85 |
||
86 |
||
87 |
this.do_highlight=true; |
|
88 |
this.resync_highlight(); |
|
89 |
||
90 |
this.hide_waiting_screen(); |
|
91 |
//area.onkeyup="";
|
|
92 |
/*if(!displayOnly){
|
|
93 |
this.do_highlight=true;
|
|
94 |
this.reSync();
|
|
95 |
if(this.state=="loaded")
|
|
96 |
this.textarea.focus();
|
|
97 |
}*/
|
|
98 |
||
99 |
};
|
|
100 |
||
101 |
||
102 |
EditArea.prototype.maj_highlight= function(infos){ |
|
103 |
if(this.last_highlight_base_text==infos["full_text"] && this.resync_highlight!==true) |
|
104 |
return; |
|
105 |
||
106 |
//var infos= this.getSelectionInfos();
|
|
107 |
if(infos["full_text"].indexOf("\r")!=-1) |
|
108 |
text_to_highlight= infos["full_text"].replace(/\r/g, ""); |
|
109 |
else
|
|
110 |
text_to_highlight= infos["full_text"]; |
|
111 |
||
112 |
// for optimisation process
|
|
113 |
var start_line_pb=-1; |
|
114 |
var end_line_pb=-1; |
|
115 |
||
116 |
var stay_begin=""; |
|
117 |
var stay_end=""; |
|
118 |
||
119 |
||
120 |
var debug_opti=""; |
|
121 |
||
122 |
// for speed mesure
|
|
123 |
var date= new Date(); |
|
124 |
var tps_start=date.getTime(); |
|
125 |
var tps_middle_opti=date.getTime(); |
|
126 |
||
127 |
||
128 |
// OPTIMISATION: will search to update only changed lines
|
|
129 |
if(this.reload_highlight===true){ |
|
130 |
this.reload_highlight=false; |
|
131 |
}else if(text_to_highlight.length==0){ |
|
132 |
text_to_highlight="\n "; |
|
133 |
}else{ |
|
134 |
var base_step=200; |
|
135 |
||
136 |
var cpt= 0; |
|
137 |
var end= Math.min(text_to_highlight.length, this.last_text_to_highlight.length); |
|
138 |
var step= base_step; |
|
139 |
// find how many chars are similar at the begin of the text
|
|
140 |
while(cpt<end && step>=1){ |
|
141 |
if(this.last_text_to_highlight.substr(cpt, step) == text_to_highlight.substr(cpt, step)){ |
|
142 |
cpt+= step; |
|
143 |
}else{ |
|
144 |
step= Math.floor(step/2); |
|
145 |
}
|
|
146 |
}
|
|
147 |
var pos_start_change=cpt; |
|
148 |
var line_start_change= text_to_highlight.substr(0, pos_start_change).split("\n").length -1; |
|
149 |
||
150 |
cpt_last= this.last_text_to_highlight.length; |
|
151 |
cpt= text_to_highlight.length; |
|
152 |
step= base_step; |
|
153 |
// find how many chars are similar at the end of the text
|
|
154 |
while(cpt>=0 && cpt_last>=0 && step>=1){ |
|
155 |
if(this.last_text_to_highlight.substr(cpt_last-step, step) == text_to_highlight.substr(cpt-step, step)){ |
|
156 |
cpt-= step; |
|
157 |
cpt_last-= step; |
|
158 |
}else{ |
|
159 |
step= Math.floor(step/2); |
|
160 |
}
|
|
161 |
}
|
|
162 |
//cpt_last=Math.max(0, cpt_last);
|
|
163 |
var pos_new_end_change= cpt; |
|
164 |
var pos_last_end_change= cpt_last; |
|
165 |
if(pos_new_end_change<=pos_start_change){ |
|
166 |
if(this.last_text_to_highlight.length < text_to_highlight.length){ |
|
167 |
pos_new_end_change= pos_start_change + text_to_highlight.length - this.last_text_to_highlight.length; |
|
168 |
pos_last_end_change= pos_start_change; |
|
169 |
}else{ |
|
170 |
pos_last_end_change= pos_start_change + this.last_text_to_highlight.length - text_to_highlight.length; |
|
171 |
pos_new_end_change= pos_start_change; |
|
172 |
}
|
|
173 |
}
|
|
174 |
var change_new_text= text_to_highlight.substring(pos_start_change, pos_new_end_change); |
|
175 |
var change_last_text= this.last_text_to_highlight.substring(pos_start_change, pos_last_end_change); |
|
176 |
||
177 |
var line_new_end_change= text_to_highlight.substr(0, pos_new_end_change).split("\n").length -1; |
|
178 |
var line_last_end_change= this.last_text_to_highlight.substr(0, pos_last_end_change).split("\n").length -1; |
|
179 |
||
180 |
var change_new_text_line= text_to_highlight.split("\n").slice(line_start_change, line_new_end_change+1).join("\n"); |
|
181 |
var change_last_text_line= this.last_text_to_highlight.split("\n").slice(line_start_change, line_last_end_change+1).join("\n"); |
|
182 |
||
183 |
// check if it can only reparse the changed text
|
|
184 |
var trace_new= this.get_syntax_trace(change_new_text_line); |
|
185 |
var trace_last= this.get_syntax_trace(change_last_text_line); |
|
186 |
if(trace_new == trace_last){ |
|
187 |
||
188 |
||
189 |
||
190 |
date= new Date(); |
|
191 |
tps_middle_opti=date.getTime(); |
|
192 |
||
193 |
stay_begin= this.last_hightlighted_text.split("\n").slice(0, line_start_change).join("\n"); |
|
194 |
if(line_start_change>0) |
|
195 |
stay_begin+= "\n"; |
|
196 |
stay_end= this.last_hightlighted_text.split("\n").slice(line_last_end_change+1).join("\n"); |
|
197 |
if(stay_end.length>0) |
|
198 |
stay_end= "\n"+stay_end; |
|
199 |
||
200 |
||
201 |
if(stay_begin.length==0 && pos_last_end_change==-1) |
|
202 |
change_new_text_line+="\n"; |
|
203 |
text_to_highlight=change_new_text_line; |
|
204 |
||
205 |
}
|
|
206 |
if(this.settings["debug"]){ |
|
207 |
debug_opti= (trace_new == trace_last)?"Optimisation": "No optimisation"; |
|
208 |
debug_opti+= " start: "+pos_start_change +"("+line_start_change+")"; |
|
209 |
debug_opti+=" end_new: "+ pos_new_end_change+"("+line_new_end_change+")"; |
|
210 |
debug_opti+=" end_last: "+ pos_last_end_change+"("+line_last_end_change+")"; |
|
211 |
debug_opti+="\nchanged_text: "+change_new_text+" => trace: "+trace_new; |
|
212 |
debug_opti+="\nchanged_last_text: "+change_last_text+" => trace: "+trace_last; |
|
213 |
//debug_opti+= "\nchanged: "+ infos["full_text"].substring(pos_start_change, pos_new_end_change);
|
|
214 |
debug_opti+= "\nchanged_line: "+change_new_text_line; |
|
215 |
debug_opti+= "\nlast_changed_line: "+change_last_text_line; |
|
216 |
debug_opti+="\nstay_begin: "+ stay_begin.slice(-200); |
|
217 |
debug_opti+="\nstay_end: "+ stay_end; |
|
218 |
//debug_opti="start: "+stay_begin_len+ "("+nb_line_start_unchanged+") end: "+ (stay_end_len)+ "("+(splited.length-nb_line_end_unchanged)+") ";
|
|
219 |
//debug_opti+="changed: "+ text_to_highlight.substring(stay_begin_len, text_to_highlight.length-stay_end_len)+" \n";
|
|
220 |
||
221 |
//debug_opti+="changed: "+ stay_begin.substr(stay_begin.length-200)+ "----------"+ text_to_highlight+"------------------"+ stay_end.substr(0,200) +"\n";
|
|
222 |
debug_opti+="\n"; |
|
223 |
}
|
|
224 |
||
225 |
||
226 |
// END OPTIMISATION
|
|
227 |
}
|
|
228 |
date= new Date(); |
|
229 |
tps_end_opti=date.getTime(); |
|
230 |
||
231 |
// apply highlight
|
|
232 |
var updated_highlight= this.colorize_text(text_to_highlight); |
|
233 |
||
234 |
// get the new highlight content
|
|
235 |
||
236 |
date= new Date(); |
|
237 |
tps2=date.getTime(); |
|
238 |
//updated_highlight= "<div class='keywords'>"+updated_highlight+"</div>";
|
|
239 |
var hightlighted_text= stay_begin + updated_highlight + stay_end; |
|
240 |
//parent.document.getElementById("test_pre").innerHTML="<div class='keywords'>"+hightlighted_text+"</div>";
|
|
241 |
//this.previous_hightlight_content= tab_text.join("<br>");
|
|
242 |
||
243 |
date= new Date(); |
|
244 |
inner1=date.getTime(); |
|
245 |
||
246 |
// update the content of the highlight div by first updating a clone node (as there is no display in the same time for this node it's quite faster (5*))
|
|
247 |
var new_Obj= this.content_highlight.cloneNode(false); |
|
248 |
//new_Obj.innerHTML= "<div class='keywords'>"+hightlighted_text+"</div>";
|
|
249 |
if(this.nav['isIE'] || this.nav['isOpera']) |
|
250 |
new_Obj.innerHTML= "<pre><span class='"+ this.settings["syntax"] +"'>" + hightlighted_text.replace("\n", "<br/>") + "</span></pre>"; |
|
251 |
else
|
|
252 |
new_Obj.innerHTML= "<span class='"+ this.settings["syntax"] +"'>"+ hightlighted_text +"</span>"; |
|
253 |
this.content_highlight.parentNode.insertBefore(new_Obj, this.content_highlight); |
|
254 |
this.content_highlight.parentNode.removeChild(this.content_highlight); |
|
255 |
this.content_highlight= new_Obj; |
|
256 |
if(infos["full_text"].indexOf("\r")!=-1) |
|
257 |
this.last_text_to_highlight= infos["full_text"].replace(/\r/g, ""); |
|
258 |
else
|
|
259 |
this.last_text_to_highlight= infos["full_text"]; |
|
260 |
this.last_hightlighted_text= hightlighted_text; |
|
261 |
date= new Date(); |
|
262 |
tps3=date.getTime(); |
|
263 |
||
264 |
if(this.settings["debug"]){ |
|
265 |
tot1=tps_end_opti-tps_start; |
|
266 |
tot_middle=tps_end_opti- tps_middle_opti; |
|
267 |
tot2=tps2-tps_end_opti; |
|
268 |
tps_join=inner1-tps2; |
|
269 |
tps_td2=tps3-inner1; |
|
270 |
//lineNumber=tab_text.length;
|
|
271 |
//this.debug.value+=" \nNB char: "+document.getElementById("src").value.length+" Nb line: "+ lineNumber;
|
|
272 |
this.debug.value= "Tps optimisation "+tot1+" (second part: "+tot_middle+") | tps reg exp: "+tot2+" | tps join: "+tps_join; |
|
273 |
this.debug.value+= " | tps update highlight content: "+tps_td2+"("+tps3+")\n"; |
|
274 |
this.debug.value+=debug_opti; |
|
275 |
// this.debug.value+= "highlight\n"+hightlighted_text;
|
|
276 |
}
|
|
277 |
||
278 |
};
|
|
279 |
||
280 |
EditArea.prototype.resync_highlight= function(reload_now){ |
|
281 |
this.reload_highlight=true; |
|
282 |
this.last_highlight_base_text=""; |
|
283 |
this.focus(); |
|
284 |
if(reload_now) |
|
285 |
this.check_line_selection(false); |
|
286 |
};
|