~azzar1/unity/add-show-desktop-key

233 by mattgiuca
Added a shaky implementation of EditArea as the text editor.
1
	EditArea.prototype.focus = function() {
2
		this.textarea.focus();
3
		this.textareaFocused=true;
4
	};
5
6
7
	EditArea.prototype.check_line_selection= function(timer_checkup){
8
		//if(do_highlight==false){
9
		/*if(this.once!=1){
10
			alert("ONCE a"+ this.isResizing);
11
			this.once=1;
12
		}*/
13
		if(!editAreas[this.id])
14
			return false;
15
		
16
		time=new Date;
17
		t1=t2=t3= time.getTime();
18
		
19
		if(!this.smooth_selection && !this.do_highlight){
20
			//formatArea();
21
		}else if(this.textareaFocused && editAreas[this.id]["displayed"]==true && this.isResizing==false){
22
			infos= this.get_selection_infos();
23
			time=new Date;
24
			t2= time.getTime();
25
			
26
			//if(this.last_selection["line_start"] != infos["line_start"] || this.last_selection["line_nb"] != infos["line_nb"] || infos["full_text"] != this.last_selection["full_text"]){
27
			if(this.last_selection["line_start"] != infos["line_start"] || this.last_selection["line_nb"] != infos["line_nb"] || infos["full_text"] != this.last_selection["full_text"] || this.reload_highlight){
28
			// if selection change
29
				
30
				new_top=this.lineHeight * (infos["line_start"]-1);
31
				new_height=Math.max(0, this.lineHeight * infos["line_nb"]);
32
				new_width=Math.max(this.textarea.scrollWidth, this.container.clientWidth -50);
33
				
34
				this.selection_field.style.top=new_top+"px";	
35
				this.selection_field.style.width=new_width+"px";
36
				this.selection_field.style.height=new_height+"px";	
37
				document.getElementById("cursor_pos").style.top=new_top+"px";	
38
		
39
				if(this.do_highlight==true){
40
					var curr_text=infos["full_text"].split("\n");
41
					var content="";
42
					//alert("length: "+curr_text.length+ " i: "+ Math.max(0,infos["line_start"]-1)+ " end: "+Math.min(curr_text.length, infos["line_start"]+infos["line_nb"]-1)+ " line: "+infos["line_start"]+" [0]: "+curr_text[0]+" [1]: "+curr_text[1]);
43
					var start=Math.max(0,infos["line_start"]-1);
44
					var end=Math.min(curr_text.length, infos["line_start"]+infos["line_nb"]-1);
45
					
46
					//curr_text[start]= curr_text[start].substr(0,infos["curr_pos"]-1) +"¤_overline_¤"+ curr_text[start].substr(infos["curr_pos"]-1);
47
					for(i=start; i< end; i++){
48
						content+= curr_text[i]+"\n";	
49
					}
50
					
51
					content= content.replace(/&/g,"&amp;");
52
					content= content.replace(/</g,"&lt;");
53
					content= content.replace(/>/g,"&gt;");
54
					
55
					if(this.nav['isIE'] || this.nav['isOpera'])
56
						this.selection_field.innerHTML= "<pre>" + content.replace("\n", "<br/>") + "</pre>";	
57
					else
58
						this.selection_field.innerHTML=content;
59
						
60
					if(this.reload_highlight || (infos["full_text"] != this.last_text_to_highlight && (this.last_selection["line_start"]!=infos["line_start"] || this.last_selection["line_nb"]!=infos["line_nb"] || this.last_selection["nb_line"]!=infos["nb_line"]) ) )
61
						this.maj_highlight(infos);
62
				}		
63
			}
64
			time=new Date;
65
			t3= time.getTime();
66
			
67
			// manage bracket finding
68
			if(infos["line_start"] != this.last_selection["line_start"] || infos["curr_pos"] != this.last_selection["curr_pos"] || infos["full_text"].length!=this.last_selection["full_text"].length || this.reload_highlight){
69
				// move _cursor_pos
70
				var selec_char= infos["curr_line"].charAt(infos["curr_pos"]-1);
71
				var no_real_move=true;
72
				if(infos["line_nb"]==1 && (this.assocBracket[selec_char] || this.revertAssocBracket[selec_char]) ){
73
					
74
					no_real_move=false;					
75
					//findEndBracket(infos["line_start"], infos["curr_pos"], selec_char);
76
					if(this.findEndBracket(infos, selec_char) === true){
77
						document.getElementById("end_bracket").style.visibility="visible";
78
						document.getElementById("cursor_pos").style.visibility="visible";
79
						document.getElementById("cursor_pos").innerHTML= selec_char;
80
						document.getElementById("end_bracket").innerHTML= (this.assocBracket[selec_char] || this.revertAssocBracket[selec_char]);
81
					}else{
82
						document.getElementById("end_bracket").style.visibility="hidden";
83
						document.getElementById("cursor_pos").style.visibility="hidden";
84
					}
85
				}else{
86
					document.getElementById("cursor_pos").style.visibility="hidden";
87
					document.getElementById("end_bracket").style.visibility="hidden";
88
				}
89
				//alert("move cursor");
90
				this.displayToCursorPosition("cursor_pos", infos["line_start"], infos["curr_pos"]-1, infos["curr_line"], no_real_move);
91
				if(infos["line_nb"]==1 && infos["line_start"]!=this.last_selection["line_start"])
92
					this.scroll_to_view();
93
			}
94
			this.last_selection=infos;
95
		}
96
		time=new Date;
97
		tend= time.getTime();
98
		//this.debug.value="tps total: "+ (tend-t1) + " tps get_infos: "+ (t2-t1)+ " tps jaune: "+ (t3-t2) +" tps cursor: "+ (tend-t3)+" "+typeof(infos);
99
		
100
		if(timer_checkup){
101
			if(this.do_highlight==true)	//can slow down check speed when highlight mode is on
102
				setTimeout("editArea.check_line_selection(true)", 50);
103
			else
104
				setTimeout("editArea.check_line_selection(true)", 50);
105
		}
106
	};
107
108
109
	EditArea.prototype.get_selection_infos= function(){
110
		if(this.nav['isIE'])
111
			this.getIESelection();
112
		start=this.textarea.selectionStart;
113
		end=this.textarea.selectionEnd;		
114
		
115
		if(this.last_selection["selectionStart"]==start && this.last_selection["selectionEnd"]==end && this.last_selection["full_text"]==this.textarea.value)
116
			return this.last_selection;
117
			
118
		if(this.tabulation!="\t" && this.textarea.value.indexOf("\t")!=-1) 
119
		{	// can append only after copy/paste 
120
			var len= this.textarea.value.length;
121
			this.textarea.value=this.replace_tab(this.textarea.value);
122
			start=end= start+(this.textarea.value.length-len);
123
			this.area_select(start, 0);
124
		}
125
		var selections=new Object();
126
		selections["selectionStart"]= start;
127
		selections["selectionEnd"]= end;		
128
		selections["full_text"]= this.textarea.value;
129
		selections["line_start"]=1;
130
		selections["line_nb"]=1;
131
		selections["curr_pos"]=0;
132
		selections["curr_line"]="";
133
		selections["indexOfCursor"]=0;
134
		selections["selec_direction"]= this.last_selection["selec_direction"];
135
		
136
		//return selections;	
137
		
138
		var splitTab=selections["full_text"].split("\n");
139
		var nbLine=Math.max(0, splitTab.length);		
140
		var nbChar=Math.max(0, selections["full_text"].length - (nbLine - 1));	// (remove \n caracters from the count)
141
		if(selections["full_text"].indexOf("\r")!=-1)
142
			nbChar= nbChar - (nbLine -1);		// (remove \r caracters from the count)
143
		selections["nb_line"]=nbLine;		
144
		selections["nb_char"]=nbChar;		
145
		if(start>0){
146
			var str=selections["full_text"].substr(0,start);
147
			selections["curr_pos"]= start - str.lastIndexOf("\n");
148
			selections["line_start"]=Math.max(1, str.split("\n").length);
149
		}else{
150
			selections["curr_pos"]=1;
151
		}
152
		if(end>start){
153
			selections["line_nb"]=selections["full_text"].substring(start,end).split("\n").length;
154
		}
155
		selections["indexOfCursor"]=this.textarea.selectionStart;		
156
		selections["curr_line"]=splitTab[Math.max(0,selections["line_start"]-1)];
157
		
158
		
159
		// determine in with direction the direction grow
160
		if(selections["selectionStart"]==this.last_selection["selectionStart"]){
161
			if(selections["selectionEnd"]>this.last_selection["selectionEnd"])
162
				selections["selec_direction"]= "down";
163
			else if(selections["selectionEnd"] == this.last_selection["selectionStart"])
164
				selections["selec_direction"]= this.last_selection["selec_direction"];
165
		}else if(selections["selectionStart"] == this.last_selection["selectionEnd"] && selections["selectionEnd"]>this.last_selection["selectionEnd"]){
166
			selections["selec_direction"]= "down";
167
		}else{
168
			selections["selec_direction"]= "up";
169
		}
170
			
171
		document.getElementById("nbLine").innerHTML= nbLine;		
172
		document.getElementById("nbChar").innerHTML= nbChar;		
173
		document.getElementById("linePos").innerHTML=selections["line_start"];
174
		document.getElementById("currPos").innerHTML=selections["curr_pos"];
175
		
176
		return selections;		
177
	};
178
	
179
	// set IE position in Firefox mode (textarea.selectionStart and textarea.selectionEnd)
180
	EditArea.prototype.getIESelection= function(){	
181
		var range = document.selection.createRange();
182
		var stored_range = range.duplicate();
183
		stored_range.moveToElementText( this.textarea );
184
		stored_range.setEndPoint( 'EndToEnd', range );
185
		if(stored_range.parentElement() !=this.textarea)
186
			return;
187
	
188
		// the range don't take care of empty lines in the end of the selection
189
		var scrollTop= this.result.scrollTop + document.body.scrollTop;
190
		
191
		var relative_top= range.offsetTop - parent.calculeOffsetTop(this.textarea) + scrollTop;
192
		
193
		var line_start = Math.round((relative_top / this.lineHeight) +1);
194
		
195
		var line_nb=Math.round(range.boundingHeight / this.lineHeight);
196
					
197
		var range_start=stored_range.text.length - range.text.length;
198
		var tab=this.textarea.value.substr(0, range_start).split("\n");			
199
		range_start+= (line_start - tab.length)*2;		// add missing empty lines to the selection
200
		this.textarea.selectionStart = range_start;
201
		
202
		var range_end=this.textarea.selectionStart + range.text.length;
203
		tab=this.textarea.value.substr(0, range_start + range.text.length).split("\n");			
204
		range_end+= (line_start + line_nb - 1 - tab.length)*2;
205
		
206
		this.textarea.selectionEnd = range_end;
207
		/*this.textarea.selectionStart = 10;
208
		this.textarea.selectionEnd = 50;*/
209
	};
210
	
211
	// select the text for IE (and take care of \r caracters)
212
	EditArea.prototype.setIESelection= function(){
213
		var nbLineStart=this.textarea.value.substr(0, this.textarea.selectionStart).split("\n").length - 1;
214
		var nbLineEnd=this.textarea.value.substr(0, this.textarea.selectionEnd).split("\n").length - 1;
215
		var range = document.selection.createRange();
216
		range.moveToElementText( this.textarea );
217
		range.setEndPoint( 'EndToStart', range );
218
		
219
		range.moveStart('character', this.textarea.selectionStart - nbLineStart);
220
		range.moveEnd('character', this.textarea.selectionEnd - nbLineEnd - (this.textarea.selectionStart - nbLineStart)  );
221
		range.select();
222
	};
223
	
224
	EditArea.prototype.tab_selection= function(){
225
		if(this.is_tabbing)
226
			return;
227
		this.is_tabbing=true;
228
		//infos=getSelectionInfos();
229
		//if( document.selection ){
230
		if( this.nav['isIE'] )
231
			this.getIESelection();
232
		/* Insertion du code de formatage */
233
		var start = this.textarea.selectionStart;
234
		var end = this.textarea.selectionEnd;
235
		var insText = this.textarea.value.substring(start, end);
236
		
237
		/* Insert tabulation and ajust cursor position */
238
		var pos_start=start;
239
		var pos_end=end;
240
		if (insText.length == 0) {
241
			// if only one line selected
242
			this.textarea.value = this.textarea.value.substr(0, start) + this.tabulation + this.textarea.value.substr(end);
243
			pos_start = start + this.tabulation.length;
244
			pos_end=pos_start;
245
		} else {
246
			start= Math.max(0, this.textarea.value.substr(0, start).lastIndexOf("\n")+1);
247
			endText=this.textarea.value.substr(end);
248
			startText=this.textarea.value.substr(0, start);
249
			tmp= this.textarea.value.substring(start, end).split("\n");
250
			insText= this.tabulation+tmp.join("\n"+this.tabulation);
251
			this.textarea.value = startText + insText + endText;
252
			pos_start = start;
253
			pos_end= this.textarea.value.indexOf("\n", startText.length + insText.length);
254
			if(pos_end==-1)
255
				pos_end=this.textarea.value.length;
256
			//pos = start + repdeb.length + insText.length + ;
257
		}
258
		this.textarea.selectionStart = pos_start;
259
		this.textarea.selectionEnd = pos_end;
260
		
261
		//if( document.selection ){
262
		if(this.nav['isIE']){
263
			this.setIESelection();
264
			setTimeout("editArea.is_tabbing=false;", 100);	// IE can't accept to make 2 tabulation without a little break between both
265
		}else
266
			this.is_tabbing=false;	
267
		
268
  	};
269
	
270
	EditArea.prototype.invert_tab_selection= function(){
271
		if(this.is_tabbing)
272
			return;
273
		this.is_tabbing=true;
274
		//infos=getSelectionInfos();
275
		//if( document.selection ){
276
		if(this.nav['isIE'])
277
			this.getIESelection();
278
		
279
		var start = this.textarea.selectionStart;
280
		var end = this.textarea.selectionEnd;
281
		var insText = this.textarea.value.substring(start, end);
282
		
283
		/* Tab remove and cursor seleciton adjust */
284
		var pos_start=start;
285
		var pos_end=end;
286
		if (insText.length == 0) {
287
			if(this.textarea.value.substring(start-this.tabulation.length, start)==this.tabulation)
288
			{
289
				this.textarea.value = this.textarea.value.substr(0, start-this.tabulation.length) + this.textarea.value.substr(end);
290
				pos_start= Math.max(0, start-this.tabulation.length);
291
				pos_end=pos_start;
292
			}	
293
			/*
294
			this.textarea.value = this.textarea.value.substr(0, start) + this.tabulation + insText + this.textarea.value.substr(end);
295
			pos_start = start + this.tabulation.length;
296
			pos_end=pos_start;*/
297
		} else {
298
			start= this.textarea.value.substr(0, start).lastIndexOf("\n")+1;
299
			endText=this.textarea.value.substr(end);
300
			startText=this.textarea.value.substr(0, start);
301
			tmp= this.textarea.value.substring(start, end).split("\n");
302
			insText="";
303
			for(i=0; i<tmp.length; i++){				
304
				for(j=0; j<this.tab_nb_char; j++){
305
					if(tmp[i].charAt(0)=="\t"){
306
						tmp[i]=tmp[i].substr(1);
307
						j=this.tab_nb_char;
308
					}else if(tmp[i].charAt(0)==" ")
309
						tmp[i]=tmp[i].substr(1);
310
				}		
311
				insText+=tmp[i];
312
				if(i<tmp.length-1)
313
					insText+="\n";
314
			}
315
			//insText+="_";
316
			this.textarea.value = startText + insText + endText;
317
			pos_start = start;
318
			pos_end= this.textarea.value.indexOf("\n", startText.length + insText.length);
319
			if(pos_end==-1)
320
				pos_end=this.textarea.value.length;
321
			//pos = start + repdeb.length + insText.length + ;
322
		}
323
		this.textarea.selectionStart = pos_start;
324
		this.textarea.selectionEnd = pos_end;
325
		
326
		//if( document.selection ){
327
		if(this.nav['isIE']){
328
			// select the text for IE
329
			this.setIESelection();
330
			setTimeout("editArea.is_tabbing=false;", 100);	// IE can accept to make 2 tabulation without a little break between both
331
		}else
332
			this.is_tabbing=false;
333
  	};
334
	
335
	EditArea.prototype.press_enter= function(){		
336
		if(!this.smooth_selection)
337
			return false;
338
		if(this.nav['isIE'])
339
			this.getIESelection();
340
		var scrollTop= this.result.scrollTop;
341
		var scrollLeft= this.result.scrollLeft;
342
		var start=this.textarea.selectionStart;
343
		var end= this.textarea.selectionEnd;
344
		var start_last_line= Math.max(0 , this.textarea.value.substring(0, start).lastIndexOf("\n") + 1 );
345
		var begin_line= this.textarea.value.substring(start_last_line, start).replace(/^([ \t]*).*/gm, "$1");
346
		if(begin_line=="\n" || begin_line=="\r" || begin_line.length==0)
347
			return false;
348
			
349
		if(this.nav['isIE'] || this.nav['isOpera']){
350
			begin_line="\r\n"+ begin_line;
351
		}else{
352
			begin_line="\n"+ begin_line;
353
		}	
354
		//alert(start_last_line+" strat: "+start +"\n"+this.textarea.value.substring(start_last_line, start)+"\n_"+begin_line+"_")
355
		this.textarea.value= this.textarea.value.substring(0, start) + begin_line + this.textarea.value.substring(end);
356
		
357
		this.area_select(start+ begin_line.length ,0);
358
		// during this process IE scroll back to the top of the textarea
359
		if(this.nav['isIE']){
360
			this.result.scrollTop= scrollTop;
361
			this.result.scrollLeft= scrollLeft;
362
		}
363
		return true;
364
		
365
	};
366
	
367
	
368
	EditArea.prototype.findEndBracket= function(infos, bracket){
369
			
370
		var start=infos["indexOfCursor"];
371
		var normal_order=true;
372
		//curr_text=infos["full_text"].split("\n");
373
		if(this.assocBracket[bracket])
374
			endBracket=this.assocBracket[bracket];
375
		else if(this.revertAssocBracket[bracket]){
376
			endBracket=this.revertAssocBracket[bracket];
377
			normal_order=false;
378
		}	
379
		var end=-1;
380
		var nbBracketOpen=0;
381
		
382
		for(var i=start; i<infos["full_text"].length && i>=0; ){
383
			if(infos["full_text"].charAt(i)==endBracket){				
384
				nbBracketOpen--;
385
				if(nbBracketOpen<=0){
386
					//i=infos["full_text"].length;
387
					end=i;
388
					break;
389
				}
390
			}else if(infos["full_text"].charAt(i)==bracket)
391
				nbBracketOpen++;
392
			if(normal_order)
393
				i++;
394
			else
395
				i--;
396
		}
397
		
398
		//end=infos["full_text"].indexOf("}", start);
399
		if(end==-1)
400
			return false;	
401
		var endLastLine=infos["full_text"].substr(0, end).lastIndexOf("\n");			
402
		if(endLastLine==-1)
403
			line=1;
404
		else
405
			line= infos["full_text"].substr(0, endLastLine).split("\n").length + 1;
406
					
407
		var curPos= end - endLastLine;
408
		
409
		this.displayToCursorPosition("end_bracket", line, curPos, infos["full_text"].substring(endLastLine +1, end));
410
		return true;
411
	};
412
	
413
	EditArea.prototype.displayToCursorPosition= function(id, start_line, cur_pos, lineContent, no_real_move){
414
		var elem= document.getElementById("test_font_size");
415
		var dest= document.getElementById(id);
416
		var postLeft=0;
417
		elem.innerHTML="<pre><span id='test_font_size_inner'>"+lineContent.substr(0, cur_pos).replace(/&/g,"&amp;").replace(/</g,"&lt;")+"</span></pre>";
418
		posLeft= 45 + document.getElementById('test_font_size_inner').offsetWidth;
419
420
		var posTop=this.lineHeight * (start_line-1);
421
	
422
		if(no_real_move!=true){	// when the cursor is hidden no need to move him
423
			dest.style.top=posTop+"px";
424
			dest.style.left=posLeft+"px";		
425
		}
426
		// usefull for smarter scroll
427
		dest.cursor_top=posTop;
428
		dest.cursor_left=posLeft;
429
		
430
	//	document.getElementById(id).style.marginLeft=posLeft+"px";
431
		
432
	};
433
	
434
	
435
	EditArea.prototype.area_select= function(start, length){
436
		this.textarea.focus();
437
		
438
		start= Math.max(0, Math.min(this.textarea.value.length, start));
439
		end= Math.max(start, Math.min(this.textarea.value.length, start+length));
440
441
		if(this.nav['isIE']){
442
			this.textarea.selectionStart = start;
443
			this.textarea.selectionEnd = end;		
444
			this.setIESelection();
445
		}else{
446
			if(this.nav['isOpera']){	// Opera bug when moving selection start and selection end
447
				/*this.textarea.selectionEnd = 1;	
448
				this.textarea.selectionStart = 0;			
449
				this.textarea.selectionEnd = 1;	
450
				this.textarea.selectionStart = 0;
451
				this.textarea.selectionEnd = 0;	
452
				this.textarea.selectionStart = 0;
453
				this.textarea.selectionEnd = 0;	
454
				this.textarea.selectionStart = 0;*/
455
				this.textarea.setSelectionRange(0, 0);
456
			}
457
			this.textarea.setSelectionRange(start, end);
458
		}
459
		this.check_line_selection();
460
	};
461
	
462
	
463
	EditArea.prototype.area_get_selection= function(){
464
		var text="";
465
		if( document.selection ){
466
			var range = document.selection.createRange();
467
			text=range.text;
468
		}else{
469
			text= this.textarea.value.substring(this.textarea.selectionStart, this.textarea.selectionEnd);
470
		}
471
		return text;			
472
	};