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

233 by mattgiuca
Added a shaky implementation of EditArea as the text editor.
1
/******
2
 *
3
 *	EditArea 
4
 * 	Developped by Christophe Dolivet
5
 *	Released under LGPL license
6
 *
7
******/
8
9
	function EditArea(){
10
		this.error= false;	// to know if load is interrrupt
11
		
12
		this.inlinePopup= new Array({popup_id: "area_search_replace", icon_id: "search"},
13
									{popup_id: "edit_area_help", icon_id: "help"});
14
		this.plugins= new Object();
15
	
16
		this.line_number=0;
17
		
18
		this.nav=parent.editAreaLoader.nav; 	// navigator identification
19
		
20
		this.last_selection=new Object();		
21
		this.last_text_to_highlight="";
22
		this.last_hightlighted_text= "";
23
		this.syntax_list= new Array();
24
		this.allready_used_syntax= new Object();
25
		
26
		this.textareaFocused= false;
27
		this.previous= new Array();
28
		this.next= new Array();
29
		this.last_undo="";
30
		this.files= new Object();
31
		this.filesIdAssoc= new Object();
32
		this.curr_file= '';
33
		//this.loaded= false;
34
		this.assocBracket=new Object();
35
		this.revertAssocBracket= new Object();		
36
		// bracket selection init 
37
		this.assocBracket["("]=")";
38
		this.assocBracket["{"]="}";
39
		this.assocBracket["["]="]";		
40
		for(var index in this.assocBracket){
41
			this.revertAssocBracket[this.assocBracket[index]]=index;
42
		}
43
		
44
		
45
		
46
		/*this.textarea="";	
47
		
48
		this.state="declare";
49
		this.code = new Array(); // store highlight syntax for languagues*/
50
		// font datas
51
		this.lineHeight= 16;
52
		/*this.default_font_family= "monospace";
53
		this.default_font_size= 10;*/
54
		this.tab_nb_char= 8;	//nb of white spaces corresponding to a tabulation
55
		if(this.nav['isOpera'])
56
			this.tab_nb_char= 6;
57
58
		this.is_tabbing= false;
59
		
60
		this.fullscreen= {'isFull': false};
61
		
62
		this.isResizing=false;	// resize var
63
		
64
		// init with settings and ID
65
		this.id= area_id;
66
		this.settings= editAreas[this.id]["settings"];
67
		
68
		if((""+this.settings['replace_tab_by_spaces']).match(/^[0-9]+$/))
69
		{
70
			this.tab_nb_char= this.settings['replace_tab_by_spaces'];
71
			this.tabulation="";
72
			for(var i=0; i<this.tab_nb_char; i++)
73
				this.tabulation+=" ";
74
		}else{
75
			this.tabulation="\t";
76
		}
77
			
78
		// retrieve the init parameter for syntax
79
		if(this.settings["syntax_selection_allow"] && this.settings["syntax_selection_allow"].length>0)
80
			this.syntax_list= this.settings["syntax_selection_allow"].replace(/ /g,"").split(",");
81
		
82
		if(this.settings['syntax'])
83
			this.allready_used_syntax[this.settings['syntax']]=true;
84
	};
85
	
86
	
87
	//called by the toggle_on
88
	EditArea.prototype.update_size= function(){
89
		
90
		if(editAreas[editArea.id] && editAreas[editArea.id]["displayed"]==true){
91
			if(editArea.fullscreen['isFull']){	
92
				parent.document.getElementById("frame_"+editArea.id).style.width= parent.document.getElementsByTagName("html")[0].clientWidth + "px";
93
				parent.document.getElementById("frame_"+editArea.id).style.height= parent.document.getElementsByTagName("html")[0].clientHeight + "px";
94
			}
95
		
96
			if(editArea.tab_browsing_area.style.display=='block' && !editArea.nav['isIE'])
97
			{
98
				editArea.tab_browsing_area.style.height= "0px";
99
				editArea.tab_browsing_area.style.height= (editArea.result.offsetTop - editArea.tab_browsing_area.offsetTop -1)+"px";
100
			}
101
			
102
			var height= document.body.offsetHeight - editArea.get_all_toolbar_height() - 4;
103
			editArea.result.style.height= height +"px";
104
			
105
			var width=document.body.offsetWidth -2;
106
			editArea.result.style.width= width+"px";
107
			//alert("result h: "+ height+" w: "+width+"\ntoolbar h: "+this.get_all_toolbar_height()+"\nbody_h: "+document.body.offsetHeight);
108
			
109
			// check that the popups don't get out of the screen
110
			for(var i=0; i<editArea.inlinePopup.length; i++){
111
				var popup= document.getElementById(editArea.inlinePopup[i]["popup_id"]);
112
				var max_left= document.body.offsetWidth- popup.offsetWidth;
113
				var max_top= document.body.offsetHeight- popup.offsetHeight;
114
				if(popup.offsetTop>max_top)
115
					popup.style.top= max_top+"px";
116
				if(popup.offsetLeft>max_left)
117
					popup.style.left= max_left+"px";
118
			}
119
		}		
120
	};
121
122
	EditArea.prototype.init= function(){
123
		this.textarea= document.getElementById("textarea");
124
		this.container= document.getElementById("container");
125
		this.result= document.getElementById("result");
126
		this.content_highlight= document.getElementById("content_highlight");
127
		this.selection_field= document.getElementById("selection_field");
128
		this.processing_screen= document.getElementById("processing");
129
		this.editor_area= document.getElementById("editor");
130
		this.tab_browsing_area= document.getElementById("tab_browsing_area");
131
		
132
		if(syntax_selec= document.getElementById("syntax_selection"))
133
		{
134
			// set up syntax selection lsit in the toolbar
135
			for(var i=0; i<this.syntax_list.length; i++) {
136
				var syntax= this.syntax_list[i];
137
				var option= document.createElement("option");
138
				option.value= syntax;
139
				if(syntax==this.settings['syntax'])
140
					option.selected= "selected";
141
				option.innerHTML= this.get_translation("syntax_" + syntax, "word");
142
				syntax_selec.appendChild(option);
143
			}
144
		}
145
		
146
		// add plugins buttons in the toolbar
147
		spans= parent.getChildren(document.getElementById("toolbar_1"), "span", "", "", "all", -1);
148
		
149
		for(var i=0; i<spans.length; i++){
150
		
151
			id=spans[i].id.replace(/tmp_tool_(.*)/, "$1");
152
			if(id!= spans[i].id){
153
				for(var j in this.plugins){
154
					if(typeof(this.plugins[j].get_control_html)=="function" ){
155
						html=this.plugins[j].get_control_html(id);
156
						if(html!=false){
157
							html= this.get_translation(html, "template");
158
							var new_span= document.createElement("span");
159
							new_span.innerHTML= html;				
160
							var father= spans[i].parentNode;
161
							spans[i].parentNode.replaceChild(new_span, spans[i]);	
162
							break; // exit the for loop					
163
						}
164
					}
165
				}
166
			}
167
		}
168
		
169
		
170
		
171
		// init datas
172
		this.textarea.value=editAreas[this.id]["textarea"].value;
173
		if(this.settings["debug"])
174
			this.debug=parent.document.getElementById("edit_area_debug_"+this.id);
175
		
176
		// init size		
177
		//this.update_size();
178
		
179
		if(document.getElementById("redo") != null)
180
			this.switchClassSticky(document.getElementById("redo"), 'editAreaButtonDisabled', true);
181
		
182
		
183
		// insert css rules for highlight mode		
184
		if(typeof(parent.editAreaLoader.syntax[this.settings["syntax"]])!="undefined"){
185
			for(var i in parent.editAreaLoader.syntax){
186
				this.add_style(parent.editAreaLoader.syntax[i]["styles"]);
187
			}
188
		}
189
		// init key events
190
		if(this.nav['isOpera'])
191
			document.getElementById("editor").onkeypress= keyDown;
192
		else
193
			document.getElementById("editor").onkeydown= keyDown;
194
	/*	if(this.nav['isIE'] || this.nav['isFirefox'])
195
			this.textarea.onkeydown= keyDown;
196
		else if
197
			this.textarea.onkeypress= keyDown;*/
198
		for(var i=0; i<this.inlinePopup.length; i++){
199
			if(this.nav['isIE'] || this.nav['isFirefox'])
200
				document.getElementById(this.inlinePopup[i]["popup_id"]).onkeydown= keyDown;
201
			else
202
				document.getElementById(this.inlinePopup[i]["popup_id"]).onkeypress= keyDown;
203
		}
204
		
205
		if(this.settings["allow_resize"]=="both" || this.settings["allow_resize"]=="x" || this.settings["allow_resize"]=="y")
206
			this.allow_resize(true);
207
		
208
		parent.editAreaLoader.toggle(this.id, "on");
209
		//this.textarea.focus();
210
		// line selection init
211
		this.change_smooth_selection_mode(editArea.smooth_selection);
212
		// highlight
213
		this.execCommand("change_highlight", this.settings["start_highlight"]);
214
		
215
		// get font size datas		
216
		this.set_font(editArea.settings["font_family"], editArea.settings["font_size"]);
217
		
218
		// set unselectable text
219
		children= parent.getChildren(document.body, "", "selec", "none", "all", -1);
220
		for(var i=0; i<children.length; i++){
221
			if(this.nav['isIE'])
222
				children[i].unselectable = true; // IE
223
			else
224
				children[i].onmousedown= function(){return false};
225
		/*	children[i].style.MozUserSelect = "none"; // Moz
226
			children[i].style.KhtmlUserSelect = "none";  // Konqueror/Safari*/
227
		}
228
		
229
		if(this.nav['isGecko']){
230
			this.textarea.spellcheck= this.settings["gecko_spellcheck"];
231
		}
232
		
233
		if(this.nav['isOpera']){
234
			this.editor_area.style.position= "absolute";
235
			this.selection_field.style.marginTop= "-1pt";			
236
			this.selection_field.style.paddingTop= "1pt";
237
			document.getElementById("cursor_pos").style.marginTop= "-1pt";
238
			document.getElementById("end_bracket").style.marginTop= "-1pt";
239
			this.content_highlight.style.marginTop= "-1pt";
240
			/*document.getElementById("end_bracket").style.marginTop="1px";*/
241
		}
242
		
243
		if(this.nav['isSafari']){
244
			this.editor_area.style.position= "absolute";
245
			this.selection_field.style.marginTop= "-1pt";			
246
			this.selection_field.style.paddingTop= "1pt";
247
			this.selection_field.style.marginLeft= "3px";			
248
			this.content_highlight.style.marginTop= "-1pt";
249
			this.content_highlight.style.marginLeft= "3px";
250
			document.getElementById("cursor_pos").style.marginLeft= "3px";	
251
			document.getElementById("end_bracket").style.marginLeft= "3px";	
252
			
253
		}
254
		
255
		// si le textarea n'est pas grand, un click sous le textarea doit provoquer un focus sur le textarea
256
		parent.editAreaLoader.add_event(this.result, "click", function(e){ if((e.target || e.srcElement)==editArea.result) { editArea.area_select(editArea.textarea.value.length, 0);}  });
257
		
258
		if(this.settings['is_multi_files']!=false)
259
			this.open_file({'id': this.curr_file, 'text': ''});
260
	
261
		
262
		setTimeout("editArea.focus();editArea.manage_size();editArea.execCommand('EA_load');", 10);		
263
		//start checkup routine
264
		this.check_undo();
265
		this.check_line_selection(true);
266
		this.scroll_to_view();
267
		
268
		for(var i in this.plugins){
269
			if(typeof(this.plugins[i].onload)=="function")
270
				this.plugins[i].onload();
271
		}
272
		if(this.settings['fullscreen']==true)
273
			this.toggle_full_screen(true);
274
	
275
		parent.editAreaLoader.add_event(window, "resize", editArea.update_size);
276
		parent.editAreaLoader.add_event(parent.window, "resize", editArea.update_size);
277
		parent.editAreaLoader.add_event(top.window, "resize", editArea.update_size);
278
		parent.editAreaLoader.add_event(window, "unload", function(){if(editAreas[editArea.id] && editAreas[editArea.id]["displayed"]) editArea.execCommand("EA_unload");});
279
		
280
		/*date= new Date();
281
		alert(date.getTime()- parent.editAreaLoader.start_time);*/
282
	};
283
	
284
	
285
	EditArea.prototype.manage_size= function(onlyOneTime){
286
		if(!editAreas[this.id])
287
			return false;
288
		if(editAreas[this.id]["displayed"]==true && this.textareaFocused)
289
		{
290
			var resized= false;
291
			
292
			//1) Manage display width
293
			//1.1) Calc the new width to use for display
294
			var area_width= this.textarea.scrollWidth;
295
			var area_height= this.textarea.scrollHeight;
296
			if(this.nav['isOpera']){
297
				area_height= this.last_selection['nb_line']*this.lineHeight;
298
				area_width=10000; /* TODO: find a better way to fix the width problem */								
299
			}
300
			
301
			if(this.nav['isIE']>=7)
302
				area_width-=45;
303
	
304
			if(this.nav['isGecko'] && this.smooth_selection && this.last_selection["nb_line"])
305
				area_height= this.last_selection["nb_line"]*this.lineHeight;
306
			
307
			//1.2) the width is not the same, we must resize elements
308
			if(this.textarea.previous_scrollWidth!=area_width)
309
			{	
310
				if(!this.nav['isOpera'] && this.textarea.style.width && (this.textarea.style.width.replace("px","") < area_width))
311
					area_width+=50;
312
			
313
				if(this.nav['isGecko'] || this.nav['isOpera'])
314
					this.container.style.width= (area_width+45)+"px";
315
				else
316
					this.container.style.width= area_width+"px";
317
				this.textarea.style.width= area_width+"px";
318
				this.content_highlight.style.width= area_width+"px";	
319
				this.textarea.previous_scrollWidth=area_width;
320
				resized=true;
321
			}	
322
			
323
			
324
			//2) Manage display height
325
			//2.1) Calc the new height to use for display
326
			var area_height = this.textarea.scrollHeight;
327
			if(this.nav['isOpera']){
328
				area_height= this.last_selection['nb_line']*this.lineHeight;
329
			}
330
			
331
			if(this.nav['isGecko'] && this.smooth_selection && this.last_selection["nb_line"])
332
				area_height= this.last_selection["nb_line"]*this.lineHeight;
333
			//2.2) the width is not the same, we must resize elements 
334
			if(this.textarea.previous_scrollHeight!=area_height)	
335
			{	
336
				this.container.style.height= (area_height+2)+"px";
337
				this.textarea.style.height= area_height+"px";
338
				this.content_highlight.style.height= area_height+"px";	
339
				this.textarea.previous_scrollHeight= area_height;
340
				resized=true;
341
			}
342
		
343
			//3) if there is new lines, we add new line numbers in the line numeration area
344
			if(this.last_selection["nb_line"] >= this.line_number)
345
			{
346
				var div_line_number="";
347
				for(i=this.line_number+1; i<this.last_selection["nb_line"]+100; i++)
348
				{
349
					div_line_number+=i+"<br />";
350
					this.line_number++;
351
				}
352
				var span= document.createElement("span");
353
				if(this.nav['isIE'])
354
					span.unselectable=true;
355
				span.innerHTML=div_line_number;         
356
				document.getElementById("line_number").appendChild(span);       
357
			}
358
		
359
			//4) be sure the text is well displayed
360
			this.textarea.scrollTop="0px";
361
			this.textarea.scrollLeft="0px";
362
			if(resized==true){
363
				this.scroll_to_view();
364
			}
365
		}
366
		if(!onlyOneTime)
367
			setTimeout("editArea.manage_size();", 100);
368
	};
369
	
370
	EditArea.prototype.add_event = function(obj, name, handler) {
371
		if (this.nav['isIE']) {
372
			obj.attachEvent("on" + name, handler);
373
		} else{
374
			obj.addEventListener(name, handler, false);
375
		}
376
	};
377
	
378
	EditArea.prototype.execCommand= function(cmd, param){
379
		
380
		for(var i in this.plugins){
381
			if(typeof(this.plugins[i].execCommand)=="function"){
382
				if(!this.plugins[i].execCommand(cmd, param))
383
					return;
384
			}
385
		}
386
		switch(cmd){
387
			case "save":
388
				if(this.settings["save_callback"].length>0)
389
					eval("parent."+this.settings["save_callback"]+"('"+ this.id +"', editArea.textarea.value);");
390
				break;
391
			case "load":
392
				if(this.settings["load_callback"].length>0)
393
					eval("parent."+this.settings["load_callback"]+"('"+ this.id +"');");
394
				break;
395
			case "onchange":
396
				if(this.settings["change_callback"].length>0)
397
					eval("parent."+this.settings["change_callback"]+"('"+ this.id +"');");
398
				break;		
399
			case "EA_load":
400
				if(this.settings["EA_load_callback"].length>0)
401
					eval("parent."+this.settings["EA_load_callback"]+"('"+ this.id +"');");
402
				break;
403
			case "EA_unload":
404
				if(this.settings["EA_unload_callback"].length>0)
405
					eval("parent."+this.settings["EA_unload_callback"]+"('"+ this.id +"');");
406
				break;
407
			case "toggle_on":
408
				if(this.settings["EA_toggle_on_callback"].length>0)
409
					eval("parent."+this.settings["EA_toggle_on_callback"]+"('"+ this.id +"');");
410
				break;
411
			case "toggle_off":
412
				if(this.settings["EA_toggle_off_callback"].length>0)
413
					eval("parent."+this.settings["EA_toggle_off_callback"]+"('"+ this.id +"');");
414
				break;
415
			case "re_sync":
416
				if(!this.do_highlight)
417
					break;
418
			case "file_switch_on":
419
				if(this.settings["EA_file_switch_on_callback"].length>0)
420
					eval("parent."+this.settings["EA_file_switch_on_callback"]+"(param);");
421
				break;
422
			case "file_switch_off":
423
				if(this.settings["EA_file_switch_off_callback"].length>0)
424
					eval("parent."+this.settings["EA_file_switch_off_callback"]+"(param);");
425
				break;
426
			case "file_close":
427
				if(this.settings["EA_file_close_callback"].length>0)
428
					return eval("parent."+this.settings["EA_file_close_callback"]+"(param);");
429
				break;
430
			
431
			default:
432
				if(typeof(eval("editArea."+cmd))=="function")
433
				{
434
					if(this.settings["debug"])
435
						eval("editArea."+ cmd +"(param);");
436
					else
437
						try{eval("editArea."+ cmd +"(param);");}catch(e){};
438
				}
439
		}
440
	};
441
	
442
	EditArea.prototype.get_translation= function(word, mode){
443
		if(mode=="template")
444
			return parent.editAreaLoader.translate(word, this.settings["language"], mode);
445
		else
446
			return parent.editAreaLoader.get_word_translation(word, this.settings["language"]);
447
	};
448
	
449
	EditArea.prototype.add_plugin= function(plug_name, plug_obj){
450
		for(var i=0; i<this.settings["plugins"].length; i++){
451
			if(this.settings["plugins"][i]==plug_name){
452
				this.plugins[plug_name]=plug_obj;
453
				plug_obj.baseURL=parent.editAreaLoader.baseURL + "plugins/" + plug_name + "/";
454
				if( typeof(plug_obj.init)=="function" )
455
					plug_obj.init();
456
			}
457
		}
458
	};
459
	
460
	EditArea.prototype.load_css= function(url){
461
		try{
462
			link = document.createElement("link");
463
			link.type = "text/css";
464
			link.rel= "stylesheet";
465
			link.media="all";
466
			link.href = url;
467
			head = document.getElementsByTagName("head");
468
			head[0].appendChild(link);
469
		}catch(e){
470
			document.write("<link href='"+ url +"' rel='stylesheet' type='text/css' />");
471
		}
472
	};
473
	
474
	EditArea.prototype.load_script= function(url){
475
		try{
476
			script = document.createElement("script");
477
			script.type = "text/javascript";
478
			script.src  = url;
479
			head = document.getElementsByTagName("head");
480
			head[0].appendChild(script);
481
		}catch(e){
482
			document.write("<script type='text/javascript' src='" + url + "'><"+"/script>");
483
		}
484
	};
485
	
486
	// add plugin translation to language translation array
487
	EditArea.prototype.add_lang= function(language, values){
488
		if(!parent.editAreaLoader.lang[language])
489
			parent.editAreaLoader.lang[language]=new Object();
490
		for(var i in values)
491
			parent.editAreaLoader.lang[language][i]= values[i];
492
	};
493
494
	var editArea = new EditArea();	
495
	editArea.add_event(window, "load", init);
496
	
497
	function init(){		
498
		setTimeout("editArea.init();  ", 10);
499
	};