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); |
|
|
|
|
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
|
|
|
{ |
|
|
|
|
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) {} |
|
|
|
|
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) {} |
|
|
|
|
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
|
|
|
{ |
|
|
|
|
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
|
|
|
{ |
|
|
|
|
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) {} |
|
|
|
|
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) {} |
|
|
|
|
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){ |
|
|
|
|
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; |
|
|
|
|
559
|
|
|
} |
560
|
|
|
} |
561
|
|
|
|
562
|
|
|
function showMenu() |
|
|
|
|
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() |
|
|
|
|
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--;}; |
|
|
|
|
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) { |
|
|
|
|
833
|
|
|
return typeof value === 'number' && |
834
|
|
|
isFinite(value) && |
835
|
|
|
Math.floor(value) === value; |
836
|
|
|
}; |