Issues (4868)

api/js/jsapi/jsapi.js (14 issues)

1
/**
2
 * eGroupWare - API
3
 * http://www.egroupware.org
4
 *
5
 * This file was originally created Tyamad, but their content is now completly removed!
6
 * It still contains some commonly used javascript functions, always included by EGroupware.
7
 *
8
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
9
 * @package api
10
 * @subpackage jsapi
11
 * @version $Id$
12
 */
13
14
/***********************************************\
15
*               INITIALIZATION                  *
16
\***********************************************/
17
if (document.all)
18
{
19
	navigator.userAgent.toLowerCase().indexOf('msie 5') != -1 ? is_ie5 = true : is_ie5 = false;
20
	is_ie = true;
21
	is_moz1_6 = false;
22
	is_mozilla = false;
23
	is_ns4 = false;
24
}
25
else if (document.getElementById)
26
{
27
	navigator.userAgent.toLowerCase().match('mozilla.*rv[:]1\.6.*gecko') ? is_moz1_6 = true : is_moz1_6 = false;
28
	is_ie = false;
29
	is_ie5 = false;
30
	is_mozilla = true;
31
	is_ns4 = false;
32
}
33
else if (document.layers)
34
{
35
	is_ie = false;
36
	is_ie5 = false;
37
	is_moz1_6 = false;
38
	is_mozilla = false;
39
	is_ns4 = true;
40
}
41
42
//console.log('is_ie='+is_ie+', is_ie5='+is_ie5+', is_mozilla='+is_mozilla+', is_moz1_6='+is_moz1_6+', is_ns4='+is_ns4);
43
44
/**
45
 * Check whether the console object is defined - if not, define one
46
 */
47
if (typeof window.console == 'undefined')
48
{
49
	window.console = {
50
		'log': function() {
51
		},
52
		'warn': function() {
53
		},
54
		'error': function() {
55
		},
56
		'info': function() {
57
		}
58
	}
59
}
60
61
/**
62
 * Seperates all script tags from the given html code and returns the seperately
63
 *
64
 * @param object _html object that the html code
65
 *  from which the script should be seperated
66
 *	The html code has to be stored in _html.html,
67
 *	the result js will be written to _html.js.
68
 */
69
70
egw_seperateJavaScript = function(_html)
71
{
72
	var html = typeof _html.html == 'string'?_html.html:'';
73
74
	var in_pos = html.search(/<script/im);
75
	var out_pos = html.search(/<\/script>/im);
76
	while (in_pos > -1 && out_pos > -1)
77
	{
78
		/*Seperate the whole <script...</script> tag */
79
		var js_str = html.substring(in_pos, out_pos+9);
80
81
		/*Remove the initial tag */
82
		/*js_str = js_str.substring(js_str.search(/>/) + 1);*/
83
		_html.js += js_str;
84
85
86
		html = html.substring(0, in_pos) + html.substring(out_pos + 9);
87
88
		var in_pos = html.search(/<script/im);
89
		var out_pos = html.search(/<\/script>/im);
90
	}
91
92
	_html.html = html;
93
}
94
95
/**
96
 * Inserts the script tags inside the given html into the dom tree
97
 */
98
function egw_insertJS(_html)
99
{
100
	// Insert each script element seperately
101
	if (_html)
102
	{
103
104
		var in_pos = -1;
105
		var out_pos = -1;
106
107
		do {
108
109
			// Search in and out position
110
			var in_pos = _html.search(/<script/im);
111
			var out_pos = _html.search(/<\/script>/im);
112
113
			// Copy the text inside the script tags...
114
			if (in_pos > -1 && out_pos > -1)
115
			{
116
				if (out_pos > in_pos)
117
				{
118
					var scriptStart = _html.indexOf("\>", in_pos);
119
					if (scriptStart > in_pos)
120
					{
121
						var script = _html.substring(scriptStart + 1,
122
							out_pos);
123
						try
124
						{
125
							// And insert them as real script tags
126
							var tag = document.createElement("script");
127
							tag.setAttribute("type", "text/javascript");
128
							tag.text = script;
129
							document.getElementsByTagName("head")[0].appendChild(tag);
130
						}
131
						catch (e)
132
						{
133
							if (typeof console != "undefined" && typeof console.log != "undefined")
134
							{
135
								console.log('Error while inserting JS code:', _e);
0 ignored issues
show
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
136
							}
137
						}
138
					}
139
				}
140
				_html = _html.substr(out_pos + 9);
141
			}
142
143
		} while (in_pos > -1 && out_pos > -1)
144
	}
145
}
146
147
/**
148
 * Returns the top window which contains the current egw_instance, even for popup windows
149
 */
150
function egw_topWindow()
151
{
152
	if (typeof window.parent != "undefined" && typeof window.parent.top != "undefined")
153
	{
154
		return window.parent.top;
155
	}
156
157
	if (typeof window.opener != "undefined" && typeof window.opener.top != "undefined")
158
	{
159
		return window.opener.top;
160
	}
161
162
	return window.top;
163
}
164
165
/**
166
 * Returns the window object of the current application
167
 * @param string _app is the name of the application which requests the window object
168
 */
169
function egw_appWindow(_app)
170
{
171
	var framework = egw_getFramework();
172
	if(framework && framework.egw_appWindow) return framework.egw_appWindow(_app);
173
	return window;
174
}
175
176
/**
177
 * Open _url in window of _app
178
 * @param _app
179
 * @param _url
180
 */
181
function egw_appWindowOpen(_app, _url)
182
{
183
	if (typeof _url == "undefined") {
184
		_url = "about:blank";
185
	}
186
	window.location = _url;
187
}
188
189
/**
190
 * Returns the current egw application
191
 * @param string _name is only used for fallback, if an onlder version of jdots is used.
192
 */
193
function egw_getApp(_name)
194
{
195
	return window.parent.framework.getApplicationByName(_name);
196
}
197
198
/**
199
 * Returns the name of the currently active application
200
 *
201
 * @deprecated use egw(window).app_name()
202
 */
203
function egw_getAppName()
204
{
205
	if (typeof egw_appName == 'undefined')
206
	{
207
		return 'egroupware';
208
	}
209
	else
210
	{
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
211
		return egw_appName;
212
	}
213
}
214
215
/**
216
 * Refresh given application _targetapp display of entry _app _id, incl. outputting _msg
217
 *
218
 * Default implementation here only reloads window with it's current url with an added msg=_msg attached
219
 *
220
 * @param {string} _msg message (already translated) to show, eg. 'Entry deleted'
221
 * @param {string} _app application name
222
 * @param {(string|number)} _id id of entry to refresh or null
223
 * @param {string} _type either 'update', 'edit', 'delete', 'add' or null
224
 * - update: request just modified data from given rows.  Sorting is not considered,
225
 *		so if the sort field is changed, the row will not be moved.
226
 * - edit: rows changed, but sorting may be affected.  Requires full reload.
227
 * - delete: just delete the given rows clientside (no server interaction neccessary)
228
 * - add: requires full reload for proper sorting
229
 * @param {string} _targetapp which app's window should be refreshed, default current
230
 * @param {(string|RegExp)} _replace regular expression to replace in url
231
 * @param {string} _with
232
 * @param {string} _msg_type 'error', 'warning' or 'success' (default)
233
  * @deprecated use egw(window).refresh() instead
234
 */
235
function egw_refresh(_msg, _app, _id, _type, _targetapp, _replace, _with, _msg_type)
236
{
237
	egw(window).refresh(_msg, _app, _id, _type, _targetapp, _replace, _with, _msg_type);
238
}
239
240
/**
241
 * Display an error or regular message
242
 *
243
 * @param {string} _msg message to show
244
 * @param {string} _type 'error', 'warning' or 'success' (default)
245
 * @deprecated use egw(window).message(_msg, _type)
246
 */
247
function egw_message(_msg, _type)
248
{
249
	egw(window).message(_msg, _type);
250
}
251
252
/**
253
 * Update app-header and website-title
254
 *
255
 * @param {string} _header
256
 * @param {string} _app Application name, if not for the current app
257
   @deprecated use egw(window).app_header(_header, _app)
258
*/
259
function egw_app_header(_header,_app)
260
{
261
	egw(window).app_header(_header, _app);
262
}
263
264
/**
265
 * View an EGroupware entry: opens a popup of correct size or redirects window.location to requested url
266
 *
267
 * Examples:
268
 * - egw_open(123,'infolog') or egw_open('infolog:123') opens popup to edit or view (if no edit rights) infolog entry 123
269
 * - egw_open('infolog:123','timesheet','add') opens popup to add new timesheet linked to infolog entry 123
270
 * - egw_open(123,'addressbook','view') opens addressbook view for entry 123 (showing linked infologs)
271
 * - egw_open('','addressbook','view_list',{ search: 'Becker' }) opens list of addresses containing 'Becker'
272
 *
273
 * @param string|int id either just the id or "app:id" if app==""
274
 * @param string app app-name or empty (app is part of id)
275
 * @param string type default "edit", possible "view", "view_list", "edit" (falls back to "view") and "add"
276
 * @param object|string extra extra url parameters to append as object or string
277
 * @param string target target of window to open
278
 * @deprecated use egw.open()
279
 */
280
function egw_open(id, app, type, extra, target)
281
{
282
	window.egw.open(id, app, type, extra, target);
283
}
284
285
window.egw_getFramework = function()
286
{
287
	if (typeof window.framework != 'undefined')
288
	{
289
		return framework;
290
	}
291
	else if (typeof window.parent.egw_getFramework != "undefined" && window != window.parent)
292
	{
293
		return window.parent.egw_getFramework();
294
	}
295
	else
296
	{
297
		return null;
298
	}
299
}
300
301
/**
302
 * Register a custom method to refresh an application in an intelligent way
303
 *
304
 * This function will be called any time the application needs to be refreshed.
305
 * The default is to just reload, but with more detailed knowledge of the application
306
 * internals, it should be possible to only refresh what is needed.
307
 *
308
 * The refresh function signature is:
309
 * function (_msg, _app, _id, _type);
310
 * returns void
311
 * @see egw_refresh()
312
 *
313
 * @param appname String Name of the application
314
 * @param refresh_func function to call when refreshing
315
 */
316
window.register_app_refresh = function(appname, refresh_func)
317
{
318
	var framework = window.egw_getFramework();
319
	if(framework != null && typeof framework.register_app_refresh == "function")
320
	{
321
		framework.register_app_refresh(appname,refresh_func);
322
	}
323
	else
324
	{
325
		if(typeof window.app_refresh != "function")
326
		{
327
			// Define the app_refresh stuff here
328
			window.app_refresh = function(_msg, appname, _id, _type) {
329
				if(window.app_refresh.registry[appname])
330
				{
331
					window.app_refresh.registry[appname].call(this,_msg,appname,_id,_type);
332
				}
333
			};
334
			window.app_refresh.registry = {};
335
			window.app_refresh.registered = function(appname) {
336
				return (typeof window.app_refresh.registry[appname] == "function");
337
			};
338
		}
339
		window.app_refresh.registry[appname] = refresh_func;
340
	}
341
}
342
343
344
function egw_set_checkbox_multiselect_enabled(_id, _enabled)
345
{
346
	//Retrieve the checkbox_multiselect base div
347
	var ms = document.getElementById('exec['+_id+']');
348
	if (ms !== null)
349
	{
350
		//Set the background color
351
		var label_color = "";
352
		if (_enabled)
353
		{
354
			ms.style.backgroundColor = "white";
355
			label_color = "black";
356
		}
357
		else
358
		{
359
			ms.style.backgroundColor = "#EEEEEE";
360
			label_color = "gray"
361
		}
362
363
		//Enable/Disable all children input elements
364
		for (var i = 0; i <ms.childNodes.length; i++)
365
		{
366
			if (ms.childNodes[i].nodeName == 'LABEL')
367
			{
368
				ms.childNodes[i].style.color = label_color;
369
				if ((ms.childNodes[i].childNodes.length >= 1) &&
370
					(ms.childNodes[i].childNodes[0].nodeName == 'INPUT'))
371
				{
372
					ms.childNodes[i].childNodes[0].disabled = !_enabled;
373
					ms.childNodes[i].childNodes[0].checked &= _enabled;
374
				}
375
			}
376
		}
377
	}
378
}
379
380
/**
381
 * Open a (centered) popup window with given size and url
382
 *
383
 * @param {string} _url
384
 * @param {string} _windowName or "_blank"
385
 * @param {number} _width
386
 * @param {number} _height
387
 * @param {type} _status "yes" or "no" to display status bar of popup
388
 * @param {string|boolean} _app app-name for framework to set correct opener or false for current app
389
 * @param {boolean} _returnID true: return window, false: return undefined
390
 * @returns {DOMWindow|undefined}
391
 * @deprecated use egw.openPopup(_url, _width, _height, _windowName, _app, _returnID, _status)
392
 */
393
function egw_openWindowCentered2(_url, _windowName, _width, _height, _status, _app, _returnID)
394
{
395
	return egw(window).openPopup(_url, _width, _height, _windowName, _app, _returnID, _status);
396
}
397
398
/**
399
 * @deprecated use egw.openPopup(_url, _width, _height, _windowName, _app, _returnID, _status)
400
 */
401
function egw_openWindowCentered(_url, _windowName, _width, _height)
402
{
403
	return egw_openWindowCentered2(_url, _windowName, _width, _height, 'no', false, true);
404
}
405
406
// return the left position of the window
407
function egw_getWindowLeft()
408
{
409
	// workaround for Fennec bug https://bugzilla.mozilla.org/show_bug.cgi?format=multiple&id=648250 window.(outerHeight|outerWidth|screenX|screenY) throw exception
410
	try {
411
		if(is_mozilla) return window.screenX;
412
	}
413
	catch (e) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
414
415
	return window.screenLeft;
416
}
417
418
// return the left position of the window
419
function egw_getWindowTop()
420
{
421
	// workaround for Fennec bug https://bugzilla.mozilla.org/show_bug.cgi?format=multiple&id=648250 window.(outerHeight|outerWidth|screenX|screenY) throw exception
422
	try {
423
		if(is_mozilla) return window.screenY;
424
	}
425
	catch (e) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
426
427
	return window.screenTop-90;
428
}
429
430
// get the outerWidth of the browser window. For IE we simply return the innerWidth
431
function egw_getWindowInnerWidth()
432
{
433
	if (is_mozilla)
434
	{
435
		return window.innerWidth;
436
	}
437
	else
438
	{
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
439
		// works only after the body has parsed
440
		//return document.body.offsetWidth;
441
		return document.body.clientWidth;
442
		//return document.documentElement.clientWidth;
443
	}
444
}
445
446
// get the outerHeight of the browser window. For IE we simply return the innerHeight
447
function egw_getWindowInnerHeight()
448
{
449
	if (is_mozilla)
450
	{
451
		return window.innerHeight;
452
	}
453
	else
454
	{
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
455
		// works only after the body has parsed
456
		//return document.body.offsetHeight;
457
		//return document.body.clientHeight;
458
		return document.documentElement.clientHeight;
459
	}
460
}
461
462
// get the outerWidth of the browser window. For IE we simply return the innerWidth
463
function egw_getWindowOuterWidth()
464
{
465
	// workaround for Fennec bug https://bugzilla.mozilla.org/show_bug.cgi?format=multiple&id=648250 window.(outerHeight|outerWidth|screenX|screenY) throw exception
466
	try {
467
		if (is_mozilla) return window.outerWidth;
468
	}
469
	catch (e) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
470
471
	return egw_getWindowInnerWidth();
472
}
473
474
// get the outerHeight of the browser window. For IE we simply return the innerHeight
475
function egw_getWindowOuterHeight()
476
{
477
	// workaround for Fennec bug https://bugzilla.mozilla.org/show_bug.cgi?format=multiple&id=648250 window.(outerHeight|outerWidth|screenX|screenY) throw exception
478
	try {
479
		if (is_mozilla) return window.outerHeight;
480
	}
481
	catch (e) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
482
483
	return egw_getWindowInnerHeight();
484
}
485
486
// ie selectbox dropdown menu hack. as ie is not able to resize dropdown menus from selectboxes, we
487
// read the content of the dropdown menu and present it as popup resized for the user. if the user
488
// clicks/seleckts a value, the selection is posted back to the origial selectbox
489
function dropdown_menu_hack(el)
490
{
491
	if(el.runtimeStyle)
492
	{
493
		if(typeof(enable_ie_dropdownmenuhack) !== 'undefined')
494
		{
495
			if (enable_ie_dropdownmenuhack==1){
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
496
497
			}
498
			else
499
				return;
500
		} else {
501
			return;
502
		}
503
		if(el.runtimeStyle.behavior.toLowerCase()=="none"){return;}
504
		el.runtimeStyle.behavior="none";
505
506
		if (el.multiple ==1) {return;}
507
		if (el.size > 1) {return;}
508
509
		var ie5 = (document.namespaces==null);
510
		el.ondblclick = function(e)
511
		{
512
			window.event.returnValue=false;
513
			return false;
514
		}
515
516
		if(window.createPopup==null)
517
		{
518
			var fid = "dropdown_menu_hack_" + Date.parse(new Date());
519
520
			window.createPopup = function()
521
			{
522
				if(window.createPopup.frameWindow==null)
523
				{
524
					el.insertAdjacentHTML("MyFrame","<iframe id='"+fid+"' name='"+fid+"' src='about:blank' frameborder='1' scrolling='no'></></iframe>");
525
					var f = document.frames[fid];
526
					f.document.open();
527
					f.document.write("<html><body></body></html>");
528
					f.document.close();
529
					f.fid = fid;
530
531
532
					var fwin = document.getElementById(fid);
533
					fwin.style.cssText="position:absolute;top:0;left:0;display:none;z-index:99999;";
534
535
536
					f.show = function(px,py,pw,ph,baseElement)
537
					{
538
						py = py + baseElement.getBoundingClientRect().top + Math.max( document.body.scrollTop, document.documentElement.scrollTop) ;
539
						px = px + baseElement.getBoundingClientRect().left + Math.max( document.body.scrollLeft, document.documentElement.scrollLeft) ;
540
						fwin.style.width = pw + "px";
541
						fwin.style.height = ph + "px";
542
						fwin.style.posLeft =px ;
543
						fwin.style.posTop = py ;
544
						fwin.style.display="block";
545
					}
546
547
548
					f_hide = function(e)
549
					{
550
						if(window.event && window.event.srcElement && window.event.srcElement.tagName && window.event.srcElement.tagName.toLowerCase()=="select"){return true;}
551
						fwin.style.display="none";
552
					}
553
					f.hide = f_hide;
554
					document.attachEvent("onclick",f_hide);
555
					document.attachEvent("onkeydown",f_hide);
556
557
				}
558
				return f;
0 ignored issues
show
The variable f does not seem to be initialized in case window.createPopup.frameWindow == null on line 522 is false. Are you sure this can never be the case?
Loading history...
559
			}
560
		}
561
562
		function showMenu()
0 ignored issues
show
The function showMenu is declared conditionally. This is not supported by all runtimes. Consider moving it to root scope or using var showMenu = function() { /* ... */ }; instead.
Loading history...
563
		{
564
565
			function selectMenu(obj)
566
			{
567
				var o = document.createElement("option");
568
				o.value = obj.value;
569
				//alert("val"+o.value+', text:'+obj.innerHTML+'selected:'+obj.selectedIndex);
570
				o.text = obj.innerHTML;
571
				o.text = o.text.replace('<NOBR>','');
572
				o.text = o.text.replace('</NOBR>','');
573
				//if there is no value, you should not try to set the innerHTML, as it screws up the empty selection ...
574
				if (o.value != '') o.innerHTML = o.text;
575
				while(el.options.length>0){el.options[0].removeNode(true);}
576
				el.appendChild(o);
577
				el.title = o.innerHTML;
578
				el.contentIndex = obj.selectedIndex ;
579
				el.menu.hide();
580
				if(el.onchange)
581
				{
582
					el.onchange();
583
				}
584
			}
585
586
587
			el.menu.show(0 , el.offsetHeight , 10, 10, el);
588
			var mb = el.menu.document.body;
589
590
			mb.style.cssText ="border:solid 1px black;margin:0;padding:0;overflow-y:auto;overflow-x:auto;background:white;font:12px Tahoma, sans-serif;";
591
			var t = el.contentHTML;
592
			//alert("1"+t);
593
			t = t.replace(/<select/gi,'<div');
594
			//alert("2"+t);
595
			t = t.replace(/<option/gi,'<span');
596
			//alert("3"+t);
597
			t = t.replace(/<\/option/gi,'</span');
598
			//alert("4"+t);
599
			t = t.replace(/<\/select/gi,'</div');
600
			t = t.replace(/<optgroup label=\"([\w\s\wäöüßÄÖÜ]*[^>])*">/gi,'<span value="i-opt-group-lable-i">$1</span>');
601
			t = t.replace(/<\/optgroup>/gi,'<span value="">---</span>');
602
			mb.innerHTML = t;
603
			//mb.innerHTML = "<div><span value='dd:ff'>gfgfg</span></div>";
604
605
			el.select = mb.all.tags("div")[0];
606
			el.select.style.cssText="list-style:none;margin:0;padding:0;";
607
			mb.options = el.select.getElementsByTagName("span");
608
609
			for(var i=0;i<mb.options.length;i++)
610
			{
611
				//alert('Value:'+mb.options[i].value + ', Text:'+ mb.options[i].innerHTML);
612
				mb.options[i].selectedIndex = i;
613
				mb.options[i].style.cssText = "list-style:none;margin:0;padding:1px 2px;width/**/:100%;white-space:nowrap;"
614
				if (mb.options[i].value != 'i-opt-group-lable-i') mb.options[i].style.cssText = mb.options[i].style.cssText + "cursor:hand;cursor:pointer;";
615
				mb.options[i].title =mb.options[i].innerHTML;
616
				mb.options[i].innerHTML ="<nobr>" + mb.options[i].innerHTML + "</nobr>";
617
				if (mb.options[i].value == 'i-opt-group-lable-i') mb.options[i].innerHTML = "<b><i>"+mb.options[i].innerHTML+"</b></i>";
618
				if (mb.options[i].value != 'i-opt-group-lable-i') mb.options[i].onmouseover = function()
619
				{
620
					if( mb.options.selected )
621
					{mb.options.selected.style.background="white";mb.options.selected.style.color="black";}
622
					mb.options.selected = this;
623
					this.style.background="#333366";this.style.color="white";
624
				}
625
				mb.options[i].onmouseout = function(){this.style.background="white";this.style.color="black";}
626
				if (mb.options[i].value != 'i-opt-group-lable-i')
627
				{
628
					mb.options[i].onmousedown = function(){selectMenu(this); }
629
					mb.options[i].onkeydown = function(){selectMenu(this); }
630
				}
631
				if(i == el.contentIndex)
632
				{
633
					mb.options[i].style.background="#333366";
634
					mb.options[i].style.color="white";
635
					mb.options.selected = mb.options[i];
636
				}
637
			}
638
			var mw = Math.max( ( el.select.offsetWidth + 22 ), el.offsetWidth + 22 );
639
			mw = Math.max( mw, ( mb.scrollWidth+22) );
640
			var mh = mb.options.length * 15 + 8 ;
641
			var mx = (ie5)?-3:0;
642
			var docW = document.documentElement.offsetWidth ;
643
			var sideW = docW - el.getBoundingClientRect().left ;
644
			if (sideW < mw)
645
			{
646
				//alert(el.getBoundingClientRect().left+' Avail: '+docW+' Mx:'+mx+' My:'+my);
647
				// if it does not fit into the window on the right side, move it to the left
648
				mx = mx -mw + sideW-5;
649
			}
650
			var my = el.offsetHeight -2;
651
			my=my+5;
652
			var docH = document.documentElement.offsetHeight ;
653
			var bottomH = docH - el.getBoundingClientRect().bottom ;
654
			mh = Math.min(mh, Math.max(( docH - el.getBoundingClientRect().top - 50),100) );
655
			if(( bottomH < mh) )
656
			{
657
				mh = Math.max( (bottomH - 12),10);
658
				if( mh <100 )
659
				{
660
					my = -100 ;
661
				}
662
				mh = Math.max(mh,100);
663
			}
664
			self.focus();
665
			el.menu.show( mx , my , mw, mh , el);
666
			sync=null;
667
			if(mb.options.selected)
668
			{
669
				mb.scrollTop = mb.options.selected.offsetTop;
670
			}
671
			window.onresize = function(){el.menu.hide()};
672
		}
673
674
		function switchMenu()
0 ignored issues
show
The function switchMenu is declared conditionally. This is not supported by all runtimes. Consider moving it to root scope or using var switchMenu = function() { /* ... */ }; instead.
Loading history...
675
		{
676
			if(event.keyCode)
677
			{
678
				if(event.keyCode==40){ el.contentIndex++ ;}
679
				else if(event.keyCode==38){ el.contentIndex--; }
680
			}
681
			else if(event.wheelDelta )
682
			{
683
				if (event.wheelDelta >= 120)
684
					el.contentIndex++ ;
685
				else if (event.wheelDelta <= -120)
686
					el.contentIndex-- ;
687
			}
688
			else{return true;}
689
			if( el.contentIndex > (el.contentOptions.length-1) ){ el.contentIndex =0;}
690
			else if (el.contentIndex<0){el.contentIndex = el.contentOptions.length-1 ;}
691
			var o = document.createElement("option");
692
			o.value = el.contentOptions[el.contentIndex].value;
693
			o.innerHTML = el.contentOptions[el.contentIndex].text;
694
			while(el.options.length>0){el.options[0].removeNode(true);}
695
			el.appendChild(o);
696
			el.title = o.innerHTML;
697
		}
698
		if(dropdown_menu_hack.menu ==null)
699
		{
700
			dropdown_menu_hack.menu = window.createPopup();
701
			document.attachEvent("onkeydown",dropdown_menu_hack.menu.hide);
702
		}
703
		el.menu = dropdown_menu_hack.menu ;
704
		el.contentOptions = new Array();
705
		el.contentIndex = el.selectedIndex;
706
		el.contentHTML = el.outerHTML;
707
708
		for(var i=0;i<el.options.length;i++)
709
		{
710
711
			el.contentOptions [el.contentOptions.length] =
712
			{
713
				"value": el.options[i].value,"text": el.options[i].innerHTML
714
			};
715
			if(!el.options[i].selected){el.options[i].removeNode(true);i--;};
0 ignored issues
show
Complexity Coding Style introduced by
You seem to be assigning a new value to the loop variable i here. Please check if this was indeed your intention. Even if it was, consider using another kind of loop instead.
Loading history...
716
		}
717
		el.onkeydown = switchMenu;
718
		el.onclick = showMenu;
719
		el.onmousewheel= switchMenu;
720
	}
721
}
722
723
/**
724
 * Use frameworks (framed template) link handler to open a url
725
 *
726
 * @param _link
727
 * @param _app
728
 * @deprecated use egw(window).link_handler(_link, _app) instead
729
 */
730
function egw_link_handler(_link, _app)
731
{
732
	egw(window).link_handler(_link, _app);
733
}
734
735
/**
736
 * Support functions for uiaccountselection class
737
 *
738
 * @ToDo: should be removed if uiaccountsel class is no longer in use
739
 */
740
function addOption(id,label,value,do_onchange)
741
{
742
	selectBox = document.getElementById(id);
743
	for (var i=0; i < selectBox.length; i++) {
744
	//		check existing entries if they're already there and only select them in that case
745
		if (selectBox.options[i].value == value) {
746
			selectBox.options[i].selected = true;
747
			break;
748
		}
749
	}
750
	if (i >= selectBox.length) {
751
		if (!do_onchange) {
752
			if (selectBox.length && selectBox.options[0].value=='') selectBox.options[0] = null;
753
			selectBox.multiple=true;
754
			selectBox.size=4;
755
		}
756
		selectBox.options[selectBox.length] = new Option(label,value,false,true);
757
	}
758
	if (selectBox.onchange && do_onchange) selectBox.onchange();
759
}
760
761
/**
762
 *
763
 * @param {string} _mime current mime type
764
 * @returns {object|null} returns object of filemanager editor hook
765
 */
766
function egw_get_file_editor_prefered_mimes(_mime)
767
{
768
	var fe = jQuery.extend(true, {},egw.link_get_registry('filemanager-editor'));
769
	var ex_mimes = egw.preference('collab_excluded_mimes', 'filemanager');
770
	var dblclick_action = egw.preference('document_doubleclick_action', 'filemanager');
771
	if (dblclick_action == 'download' && typeof _mime === 'string')
772
	{
773
		ex_mimes = !ex_mimes ? _mime : ex_mimes+','+_mime;
774
	}
775
	if (fe && fe.mime && ex_mimes && typeof ex_mimes === 'string')
776
	{
777
		ex_mimes = ex_mimes.split(',');
778
		for (var mime in fe.mime)
779
		{
780
			for (var i in ex_mimes)
781
			{
782
				if (ex_mimes[i] == mime) delete(fe.mime[mime]);
783
			}
784
		}
785
	}
786
	return fe && fe.mime?fe:null;
787
}
788
/**
789
 * Install click handlers for popup and multiple triggers of uiaccountselection
790
 */
791
jQuery(function(){
792
	jQuery(document).on('click', '.uiaccountselection_trigger',function(){
793
		var selectBox = document.getElementById(this.id.replace(/(_multiple|_popup)$/, ''));
794
		if (selectBox)
795
		{
796
			var link = selectBox.getAttribute('data-popup-link');
797
798
			if (selectBox.multiple || this.id.match(/_popup$/))
799
			{
800
				window.open(link, 'uiaccountsel', 'width=600,height=420,toolbar=no,scrollbars=yes,resizable=yes');
801
			}
802
			else
803
			{
804
				selectBox.size = 4;
805
				selectBox.multiple = true;
806
				if (selectBox.options[0].value=='') selectBox.options[0] = null;
807
808
				if (!jQuery(selectBox).hasClass('groupmembers') && !jQuery(selectBox).hasClass('selectbox'))	// no popup!
809
				{
810
					this.src = egw.image('search');
811
					this.title = egw.lang('Search accounts');
812
				}
813
				else
814
				{
815
					this.style.display = 'none';
816
					selectBox.style.width = '100%';
817
				}
818
			}
819
		}
820
	});
821
	jQuery(document).on('change', 'select.uiaccountselection',function(e){
822
		if (this.value == 'popup')
823
		{
824
			var link = this.getAttribute('data-popup-link');
825
			window.open(link, 'uiaccountsel', 'width=600,height=420,toolbar=no,scrollbars=yes,resizable=yes');
826
			e.preventDefault();
827
		}
828
	});
829
});
830
831
// IE does not support ES6 therefore we need to use polyfill function
832
Number.isInteger = Number.isInteger || function(value) {
0 ignored issues
show
Compatibility Best Practice introduced by
You are extending the built-in type Number. This may have unintended consequences on other objects using this built-in type. Consider subclassing instead.
Loading history...
833
  return typeof value === 'number' &&
834
    isFinite(value) &&
835
    Math.floor(value) === value;
836
};