2011-08-23 16:29:56 +02:00
|
|
|
/**
|
|
|
|
* EGroupware clientside API object
|
|
|
|
*
|
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
|
|
* @package etemplate
|
|
|
|
* @subpackage api
|
|
|
|
* @link http://www.egroupware.org
|
|
|
|
* @author Andreas Stöckel (as AT stylite.de)
|
|
|
|
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
|
|
|
* @version $Id$
|
|
|
|
*/
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
2012-03-01 17:24:29 +01:00
|
|
|
/*egw:uses
|
|
|
|
egw_core;
|
2012-03-05 16:02:00 +01:00
|
|
|
egw_debug;
|
2012-03-01 17:24:29 +01:00
|
|
|
egw_preferences;
|
|
|
|
egw_lang;
|
|
|
|
egw_links;
|
2012-03-28 14:37:03 +02:00
|
|
|
egw_open;
|
2012-03-01 17:24:29 +01:00
|
|
|
egw_user;
|
|
|
|
egw_config;
|
|
|
|
egw_images;
|
|
|
|
egw_jsonq;
|
2012-03-05 14:07:38 +01:00
|
|
|
egw_files;
|
2012-03-05 16:02:00 +01:00
|
|
|
egw_json;
|
2013-10-05 11:28:12 +02:00
|
|
|
egw_store;
|
2012-03-06 14:22:01 +01:00
|
|
|
egw_tooltip;
|
2012-03-07 15:04:25 +01:00
|
|
|
egw_css;
|
2012-03-08 12:29:46 +01:00
|
|
|
egw_calendar;
|
2012-03-09 16:32:29 +01:00
|
|
|
egw_ready;
|
2012-03-20 13:05:31 +01:00
|
|
|
egw_data;
|
2014-01-27 15:29:24 +01:00
|
|
|
egw_tail;
|
2013-04-09 10:45:59 +02:00
|
|
|
egw_inheritance;
|
2014-02-06 16:42:33 +01:00
|
|
|
egw_message;
|
2013-04-09 10:45:59 +02:00
|
|
|
app_base;
|
2012-03-01 17:24:29 +01:00
|
|
|
*/
|
2011-08-23 16:29:56 +02:00
|
|
|
|
2013-07-19 10:45:26 +02:00
|
|
|
(function(){
|
|
|
|
var debug = false;
|
|
|
|
var egw_script = document.getElementById('egw_script_id');
|
2014-01-09 13:20:13 +01:00
|
|
|
var start_time = (new Date).getTime();
|
2014-08-21 10:12:31 +02:00
|
|
|
if(typeof console != "undefined" && console.timeline) console.timeline("egw");
|
2013-11-05 19:08:07 +01:00
|
|
|
|
2014-11-27 18:34:06 +01:00
|
|
|
// set opener as early as possible for framework popups (not real popups)
|
|
|
|
if (!window.opener && window.parent !== window)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
if (window.parent.framework && typeof window.parent.framework.popup_idx == 'function' &&
|
|
|
|
window.parent.framework.popup_idx.call(window.parent.framework, window) !== undefined)
|
|
|
|
{
|
|
|
|
window.opener = window.parent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(e) {
|
|
|
|
// ignore SecurityError exception if opener is different security context / cross-origin
|
|
|
|
}
|
|
|
|
}
|
2013-10-07 12:09:08 +02:00
|
|
|
// Flag for if this is opened in a popup
|
2013-12-19 18:18:01 +01:00
|
|
|
var popup = (window.opener != null);
|
2013-11-05 19:08:07 +01:00
|
|
|
|
2013-07-19 10:45:26 +02:00
|
|
|
window.egw_webserverUrl = egw_script.getAttribute('data-url');
|
|
|
|
window.egw_appName = egw_script.getAttribute('data-app');
|
|
|
|
|
|
|
|
// check if egw object was injected by window open
|
|
|
|
if (typeof window.egw == 'undefined')
|
|
|
|
{
|
2014-01-08 16:14:10 +01:00
|
|
|
try {
|
|
|
|
// try finding it in top or opener's top
|
|
|
|
if (window.opener && typeof window.opener.top.egw != 'undefined')
|
|
|
|
{
|
|
|
|
window.egw = window.opener.top.egw;
|
|
|
|
if (typeof window.opener.top.framework != 'undefined') window.framework = window.opener.top.framework;
|
|
|
|
popup = true;
|
|
|
|
if (debug) console.log('found egw object in opener');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(e) {
|
|
|
|
// ignore SecurityError exception if opener is different security context / cross-origin
|
|
|
|
}
|
|
|
|
if (typeof window.egw != 'undefined')
|
2013-07-19 10:45:26 +02:00
|
|
|
{
|
2014-01-08 16:14:10 +01:00
|
|
|
// set in above try block
|
2013-07-19 10:45:26 +02:00
|
|
|
}
|
|
|
|
else if (window.top && typeof window.top.egw != 'undefined')
|
|
|
|
{
|
|
|
|
window.egw = window.top.egw;
|
|
|
|
if (typeof window.top.framework != 'undefined') window.framework = window.top.framework;
|
|
|
|
if (debug) console.log('found egw object in top');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
window.egw = {
|
|
|
|
prefsOnly: true,
|
|
|
|
webserverUrl: egw_webserverUrl
|
|
|
|
};
|
|
|
|
if (debug) console.log('creating new egw object');
|
|
|
|
}
|
|
|
|
}
|
2013-07-19 17:22:37 +02:00
|
|
|
else if (debug) console.log('found injected egw object');
|
2013-11-05 19:08:07 +01:00
|
|
|
|
2013-07-19 10:45:26 +02:00
|
|
|
// check for a framework object
|
|
|
|
if (typeof window.framework == 'undefined')
|
|
|
|
{
|
2014-01-08 16:19:04 +01:00
|
|
|
try {
|
|
|
|
// try finding it in top or opener's top
|
|
|
|
if (window.opener && typeof window.opener.top.framework != 'undefined')
|
|
|
|
{
|
|
|
|
window.framework = window.opener.top.framework;
|
|
|
|
if (debug) console.log('found framework object in opener top');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(e) {
|
|
|
|
// ignore SecurityError exception if opener is different security context / cross-origin
|
|
|
|
}
|
|
|
|
if (typeof window.framework != 'undefined')
|
2013-07-19 10:45:26 +02:00
|
|
|
{
|
2014-01-08 16:19:04 +01:00
|
|
|
// set in above try block
|
2013-07-19 10:45:26 +02:00
|
|
|
}
|
|
|
|
else if (window.top && typeof window.top.framework != 'undefined')
|
|
|
|
{
|
|
|
|
window.framework = window.top.framework;
|
|
|
|
if (debug) console.log('found framework object in top');
|
|
|
|
}
|
|
|
|
// if framework not found, but requested to check for it, redirect to cd=yes to create it
|
2015-05-01 18:34:48 +02:00
|
|
|
else if (egw_script.getAttribute('data-check-framework') && !window.location.search.match(/[&?]cd=/))
|
2013-07-19 10:45:26 +02:00
|
|
|
{
|
|
|
|
window.location.search += window.location.search ? "&cd=yes" : "?cd=yes";
|
|
|
|
}
|
|
|
|
}
|
2013-11-05 19:08:07 +01:00
|
|
|
|
2013-08-26 12:24:11 +02:00
|
|
|
// focus window / call window.focus(), if data-window-focus is specified
|
2013-08-20 15:25:36 +02:00
|
|
|
var window_focus = egw_script.getAttribute('data-window-focus');
|
|
|
|
if (window_focus && JSON.parse(window_focus))
|
|
|
|
{
|
|
|
|
window.focus();
|
|
|
|
}
|
2013-07-19 10:45:26 +02:00
|
|
|
|
|
|
|
window.egw_LAB = $LAB.setOptions({AlwaysPreserveOrder:true,BasePath:window.egw_webserverUrl+'/'});
|
|
|
|
var include = JSON.parse(egw_script.getAttribute('data-include'));
|
2013-11-05 19:08:07 +01:00
|
|
|
|
2013-07-19 10:45:26 +02:00
|
|
|
// remove this script from include, until server-side no longer requires it
|
|
|
|
for(var i=0; i < include.length; ++i)
|
|
|
|
{
|
|
|
|
if (include[i].match(/^phpgwapi\/js\/jsapi\/egw\.js/))
|
|
|
|
{
|
|
|
|
include.splice(i, 1);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-01-09 13:20:13 +01:00
|
|
|
|
2013-11-05 19:08:07 +01:00
|
|
|
window.egw_LAB.script(include).wait(function()
|
|
|
|
{
|
2014-11-26 19:37:36 +01:00
|
|
|
// call egw.link_handler, if attr specified
|
|
|
|
var egw_redirect = egw_script.getAttribute('data-egw-redirect');
|
|
|
|
if (egw_redirect)
|
|
|
|
{
|
|
|
|
// set sidebox for tabed templates, we need to set it now, as framework will not resent it!
|
|
|
|
var sidebox = egw_script.getAttribute('data-setSidebox');
|
|
|
|
if (window.framework && sidebox)
|
|
|
|
{
|
|
|
|
window.framework.setSidebox.apply(window.framework, JSON.parse(sidebox));
|
|
|
|
}
|
|
|
|
egw_redirect = JSON.parse(egw_redirect);
|
|
|
|
egw.link_handler.apply(egw, egw_redirect);
|
|
|
|
return; // do NOT execute any further code, as IE(11) will give errors because framework already redirects
|
|
|
|
}
|
|
|
|
|
|
|
|
// call egw_refresh on opener, if attr specified
|
|
|
|
var refresh_opener = egw_script.getAttribute('data-refresh-opener');
|
|
|
|
if (refresh_opener && window.opener)
|
|
|
|
{
|
|
|
|
refresh_opener = JSON.parse(refresh_opener) || {};
|
2014-12-10 14:33:42 +01:00
|
|
|
window.opener.egw(window.opener).refresh.apply(egw(window.opener), refresh_opener);
|
2014-11-26 19:37:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// close window / call window.close(), if data-window-close is specified
|
|
|
|
var window_close = egw_script.getAttribute('data-window-close');
|
|
|
|
if (window_close)
|
|
|
|
{
|
|
|
|
if (typeof window_close == 'string' && window_close !== '1')
|
|
|
|
{
|
|
|
|
alert(window_close);
|
|
|
|
}
|
|
|
|
// If there's a message & opener, set it
|
|
|
|
if(window.opener && egw_script.getAttribute('data-message'))
|
|
|
|
{
|
|
|
|
egw(window.opener).message(JSON.parse(egw_script.getAttribute('data-message')));
|
|
|
|
}
|
2014-11-27 18:01:47 +01:00
|
|
|
egw(window).close();
|
2014-11-26 19:37:36 +01:00
|
|
|
}
|
|
|
|
|
2014-06-18 15:57:15 +02:00
|
|
|
// call egw.open_link, if popup attr specified
|
|
|
|
var egw_popup = egw_script.getAttribute('data-popup');
|
|
|
|
if (egw_popup)
|
|
|
|
{
|
|
|
|
egw_popup = JSON.parse(egw_popup) || [];
|
|
|
|
egw.open_link.apply(egw, egw_popup);
|
|
|
|
}
|
|
|
|
|
2014-08-21 10:12:31 +02:00
|
|
|
if(typeof console != "undefined" && console.timelineEnd) console.timelineEnd("egw");
|
2014-01-09 13:20:13 +01:00
|
|
|
var end_time = (new Date).getTime();
|
|
|
|
var gen_time_div = $j('#divGenTime_'+window.egw_appName);
|
|
|
|
if (!gen_time_div.length) gen_time_div = $j('.pageGenTime');
|
|
|
|
gen_time_div.append('<span class="asyncIncludeTime">'+egw.lang('async includes took %1s', (end_time-start_time)/1000)+'</span>');
|
|
|
|
|
2013-10-10 11:37:21 +02:00
|
|
|
// Make sure opener knows when we close - start a heartbeat
|
|
|
|
if((popup || window.opener) && window.name != '')
|
2013-10-07 12:09:08 +02:00
|
|
|
{
|
2013-10-10 11:37:21 +02:00
|
|
|
// Timeout is 5 seconds, but it iks only applied(egw_utils) when something asks for the window list
|
|
|
|
window.setInterval(function() {
|
|
|
|
egw().storeWindow(this.egw_appName, this);
|
|
|
|
}, 2000);
|
2013-10-07 12:09:08 +02:00
|
|
|
}
|
2013-11-05 19:08:07 +01:00
|
|
|
|
|
|
|
// instanciate app object
|
|
|
|
var appname = window.egw_appName;
|
2015-01-09 19:58:23 +01:00
|
|
|
if (window.app && typeof window.app[appname] != 'object' && typeof window.app.classes[appname] == 'function')
|
2013-11-05 19:08:07 +01:00
|
|
|
{
|
|
|
|
window.app[appname] = new window.app.classes[appname]();
|
|
|
|
}
|
|
|
|
|
2013-11-29 00:18:36 +01:00
|
|
|
// set sidebox for tabed templates
|
2014-02-21 18:06:11 +01:00
|
|
|
var sidebox = egw_script.getAttribute('data-setSidebox') || jQuery('#late-sidebox').attr('data-setSidebox');
|
2015-01-09 19:58:23 +01:00
|
|
|
if (window.framework && sidebox && sidebox !== 'null')
|
2013-11-29 00:18:36 +01:00
|
|
|
{
|
|
|
|
window.framework.setSidebox.apply(window.framework, JSON.parse(sidebox));
|
|
|
|
}
|
|
|
|
|
2014-11-28 15:00:40 +01:00
|
|
|
var resize_attempt = 0;
|
|
|
|
var resize_popup = function()
|
|
|
|
{
|
|
|
|
var $main_div = $j('#popupMainDiv');
|
|
|
|
var $et2 = $j('.et2_container');
|
|
|
|
var w = {
|
|
|
|
width: egw_getWindowInnerWidth(),
|
|
|
|
height: egw_getWindowInnerHeight()
|
|
|
|
};
|
|
|
|
// Use et2_container for width since #popupMainDiv is full width, but we still need
|
|
|
|
// to take padding/margin into account
|
|
|
|
var delta_width = w.width - ($et2.outerWidth(true) + ($main_div.outerWidth(true) - $main_div.width()));
|
|
|
|
var delta_height = w.height - ($et2.outerHeight(true) + ($main_div.outerHeight(true) - $main_div.height()));
|
2015-10-01 15:19:39 +02:00
|
|
|
|
|
|
|
// Don't let the window gets horizental scrollbar
|
|
|
|
var scrollWidth = document.body.scrollWidth - document.body.clientWidth;
|
|
|
|
if (scrollWidth > 0 && scrollWidth + egw_getWindowOuterWidth() < screen.availWidth) delta_width = -scrollWidth;
|
|
|
|
|
2014-11-28 15:00:40 +01:00
|
|
|
if (delta_height && egw_getWindowOuterHeight() >= egw.availHeight())
|
|
|
|
{
|
|
|
|
delta_height = 0;
|
|
|
|
}
|
2015-01-09 19:58:23 +01:00
|
|
|
if((delta_width != 0 || delta_height != 0) &&
|
2015-01-06 15:52:41 +01:00
|
|
|
(delta_width >2 || delta_height >2 || delta_width<-2 || delta_height < -2))
|
2014-11-28 15:00:40 +01:00
|
|
|
{
|
2015-01-09 19:58:23 +01:00
|
|
|
|
2014-12-01 18:38:52 +01:00
|
|
|
if (window.framework && typeof window.framework.resize_popup != 'undefined')
|
|
|
|
{
|
|
|
|
window.framework.resize_popup($et2.outerWidth(true), $et2.outerHeight(true), window);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-01-06 15:52:41 +01:00
|
|
|
window.resizeTo(egw_getWindowOuterWidth() - delta_width+8, egw_getWindowOuterHeight() - delta_height);
|
2014-12-01 18:38:52 +01:00
|
|
|
}
|
2014-11-28 15:00:40 +01:00
|
|
|
}
|
|
|
|
// trigger a 2. resize, as one is not enough, if window is zoomed
|
|
|
|
if (delta_width && ++resize_attempt < 2)
|
|
|
|
{
|
|
|
|
window.setTimeout(resize_popup, 50);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
resize_attempt = 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-07-21 15:38:23 +02:00
|
|
|
// rest needs DOM to be ready
|
2014-01-10 10:13:56 +01:00
|
|
|
$j(function() {
|
2014-07-21 15:38:23 +02:00
|
|
|
// load etemplate2 template(s)
|
2015-02-06 14:23:40 +01:00
|
|
|
$j('form.et2_container[data-etemplate]').each(function(index, node){
|
2014-07-21 15:38:23 +02:00
|
|
|
var data = JSON.parse(node.getAttribute('data-etemplate')) || {};
|
|
|
|
var currentapp = data.data.currentapp || window.egw_appName;
|
2015-03-17 15:17:01 +01:00
|
|
|
if(popup || window.opener && !egwIsMobile())
|
2014-07-21 15:38:23 +02:00
|
|
|
{
|
|
|
|
// Resize popup when et2 load is done
|
2014-11-28 15:00:40 +01:00
|
|
|
jQuery(node).on('load', function() {
|
|
|
|
window.setTimeout(resize_popup, 50);
|
2014-07-21 15:38:23 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
var et2 = new etemplate2(node, currentapp+".etemplate_new.ajax_process_content.etemplate");
|
|
|
|
et2.load(data.name,data.url,data.data);
|
|
|
|
if (typeof data.response != 'undefined')
|
|
|
|
{
|
|
|
|
var json_request = egw(window).json();
|
|
|
|
json_request.handleResponse({response: data.response});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2014-01-10 10:13:56 +01:00
|
|
|
// set app-header
|
2014-02-06 16:42:33 +01:00
|
|
|
if (window.framework && egw_script.getAttribute('data-app-header'))
|
2013-07-20 15:42:23 +02:00
|
|
|
{
|
2014-02-07 10:11:30 +01:00
|
|
|
egw(window).app_header(egw_script.getAttribute('data-app-header'), appname);
|
2013-07-20 15:42:23 +02:00
|
|
|
}
|
2014-01-10 10:13:56 +01:00
|
|
|
// display a message
|
2014-02-06 16:42:33 +01:00
|
|
|
if (egw_script.getAttribute('data-message'))
|
2013-07-20 15:42:23 +02:00
|
|
|
{
|
2014-04-01 16:16:11 +02:00
|
|
|
var params = JSON.parse(egw_script.getAttribute('data-message')) || [''];
|
|
|
|
egw(window).message.apply(egw(window), params);
|
2013-07-19 10:45:26 +02:00
|
|
|
}
|
2014-03-03 18:35:48 +01:00
|
|
|
// hide location bar for mobile browsers
|
|
|
|
if (egw_script.getAttribute('data-mobile'))
|
|
|
|
{
|
|
|
|
window.scrollTo(0, 1);
|
|
|
|
}
|
2014-01-10 10:13:56 +01:00
|
|
|
});
|
2013-07-19 10:45:26 +02:00
|
|
|
});
|
2013-11-05 19:08:07 +01:00
|
|
|
|
2013-08-20 20:01:49 +02:00
|
|
|
/**
|
2013-11-05 19:08:07 +01:00
|
|
|
*
|
2013-08-20 20:01:49 +02:00
|
|
|
*/
|
|
|
|
window.callManual = function()
|
|
|
|
{
|
|
|
|
if (window.framework)
|
|
|
|
{
|
|
|
|
window.framework.callManual.call(window.framework, window.location.href);
|
|
|
|
}
|
|
|
|
};
|
2013-07-19 10:45:26 +02:00
|
|
|
})();
|
2014-06-23 10:10:40 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Call a function specified by it's name (possibly dot separated, eg. "app.myapp.myfunc")
|
|
|
|
*
|
|
|
|
* @param {string} _func dot-separated function name
|
|
|
|
* variable number of arguments
|
|
|
|
* @returns {Boolean}
|
|
|
|
*/
|
|
|
|
function et2_call(_func)
|
|
|
|
{
|
|
|
|
var args = [].slice.call(arguments); // convert arguments to array
|
|
|
|
var func = args.shift();
|
|
|
|
var parent = window;
|
|
|
|
|
|
|
|
if (typeof _func == 'string')
|
|
|
|
{
|
|
|
|
var parts = _func.split('.');
|
|
|
|
func = parts.pop();
|
|
|
|
for(var i=0; i < parts.length; ++i)
|
|
|
|
{
|
|
|
|
if (typeof parent[parts[i]] != 'undefined')
|
|
|
|
{
|
|
|
|
parent = parent[parts[i]];
|
|
|
|
}
|
|
|
|
// check if we need a not yet instanciated app.js object --> instanciate it now
|
|
|
|
else if (i == 1 && parts[0] == 'app' && typeof window.app.classes[parts[1]] == 'function')
|
|
|
|
{
|
|
|
|
parent = parent[parts[1]] = new window.app.classes[parts[1]]();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (typeof parent[func] == 'function')
|
|
|
|
{
|
|
|
|
func = parent[func];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (typeof func != 'function')
|
|
|
|
{
|
|
|
|
throw _func+" is not a function!";
|
|
|
|
}
|
|
|
|
return func.apply(parent, args);
|
|
|
|
}
|