mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-21 23:43:17 +01:00
replace LAB.js with native es5 loading
This commit is contained in:
parent
688f970ec0
commit
592b7fb97d
@ -43,8 +43,10 @@ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $
|
||||
exit;
|
||||
}
|
||||
|
||||
$content = 'egw.set_configs('.$config.", egw && egw.window !== window);\n";
|
||||
$content .= 'egw.set_link_registry('.$link_registry.", undefined, egw && egw.window !== window);\n";
|
||||
$content = "import './js/jsapi/egw_config.js';\n";
|
||||
$content .= "import './js/jsapi/egw_links.js';\n\n";
|
||||
$content .= 'window.egw.set_configs('.$config.", window.egw && window.egw.window !== window);\n";
|
||||
$content .= 'window.egw.set_link_registry('.$link_registry.", undefined, window.egw && window.egw.window !== window);\n";
|
||||
|
||||
// we run our own gzip compression, to set a correct Content-Length of the encoded content
|
||||
if (in_array('gzip', explode(',',$_SERVER['HTTP_ACCEPT_ENCODING'])) && function_exists('gzencode'))
|
||||
|
@ -48,7 +48,7 @@ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($_GET['debug'])) $content = 'egw.set_images('.$content.", egw && egw.window !== window);\n";
|
||||
if (empty($_GET['debug'])) $content = "import './js/jsapi/egw_images.js';\n\nwindow.egw.set_images(".$content.", window.egw && window.egw.window !== window);\n";
|
||||
|
||||
// we run our own gzip compression, to set a correct Content-Length of the encoded content
|
||||
if (in_array('gzip', explode(',',$_SERVER['HTTP_ACCEPT_ENCODING'])) && function_exists('gzencode'))
|
||||
|
@ -451,7 +451,7 @@ egwFnct.prototype.exec = function()
|
||||
*/
|
||||
var _egw_mobileBrowser = null;
|
||||
|
||||
function egwIsMobile() {
|
||||
window.egwIsMobile = function() {
|
||||
|
||||
if (_egw_mobileBrowser == null)
|
||||
{
|
||||
|
@ -15,16 +15,15 @@
|
||||
*/
|
||||
|
||||
/* The egw_json_request is the javaScript side implementation of class.egw_json.inc.php.*/
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
function _egw_json_escape_string(input)
|
||||
{
|
||||
function _egw_json_escape_string(input) {
|
||||
var len = input.length;
|
||||
var res = "";
|
||||
|
||||
for (var i = 0; i < len; i++)
|
||||
{
|
||||
switch (input.charAt(i))
|
||||
{
|
||||
for (var i = 0; i < len; i++) {
|
||||
switch (input.charAt(i)) {
|
||||
case '"':
|
||||
res += '\\"';
|
||||
break;
|
||||
@ -63,12 +62,10 @@ function _egw_json_escape_string(input)
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
function _egw_json_encode_simple(input)
|
||||
{
|
||||
switch (input.constructor)
|
||||
{
|
||||
function _egw_json_encode_simple(input) {
|
||||
switch (input.constructor) {
|
||||
case String:
|
||||
return '"' + _egw_json_escape_string(input) + '"';
|
||||
|
||||
@ -81,26 +78,25 @@ function _egw_json_encode_simple(input)
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function egw_json_encode(input)
|
||||
{
|
||||
window.egw_json_encode = function (input) {
|
||||
egw.debug("warn", "Function %s is deprecated, use egw.jsonEncode() instead", arguments.callee.name);
|
||||
return egw.jsonEncode(input);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Some variables needed to store which JS and CSS files have already be included
|
||||
*/
|
||||
var egw_json_files = {};
|
||||
var egw_json_files = {};
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Initialize the egw_json_files object with all files which are already bound in
|
||||
*/
|
||||
jQuery(document).ready(function() {
|
||||
jQuery("script, link").each(function() {
|
||||
jQuery(document).ready(function () {
|
||||
jQuery("script, link").each(function () {
|
||||
var file = false;
|
||||
if (jQuery(this).attr("src")) {
|
||||
file = jQuery(this).attr("src");
|
||||
@ -111,18 +107,17 @@ jQuery(document).ready(function() {
|
||||
egw_json_files[file] = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
/**
|
||||
* Variable which stores all currently registered plugins
|
||||
*/
|
||||
var _egw_json_plugins = [];
|
||||
var _egw_json_plugins = [];
|
||||
|
||||
/**
|
||||
/**
|
||||
* Register a plugin for the egw_json handler
|
||||
*/
|
||||
function egw_json_register_plugin(_callback, _context)
|
||||
{
|
||||
window.egw_json_register_plugin = function (_callback, _context) {
|
||||
egw.debug("warn", "Function %s is deprecated", arguments.callee.name);
|
||||
//Default the context parameter to "window"
|
||||
if (typeof _context == 'undefined') {
|
||||
@ -134,20 +129,18 @@ function egw_json_register_plugin(_callback, _context)
|
||||
'callback': _callback,
|
||||
'context': _context
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Function used internally to pass a response to all registered plugins
|
||||
*/
|
||||
function _egw_json_plugin_handle(_type, _response, _context) {
|
||||
for (var i = 0; i < _egw_json_plugins.length; i++)
|
||||
{
|
||||
function _egw_json_plugin_handle(_type, _response, _context) {
|
||||
for (var i = 0; i < _egw_json_plugins.length; i++) {
|
||||
try {
|
||||
var plugin = _egw_json_plugins[i];
|
||||
|
||||
var context = plugin.context;
|
||||
if (!plugin.context && typeof _context != "undefined")
|
||||
{
|
||||
if (!plugin.context && typeof _context != "undefined") {
|
||||
context = _context;
|
||||
}
|
||||
|
||||
@ -155,17 +148,16 @@ function _egw_json_plugin_handle(_type, _response, _context) {
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
if (typeof console != 'undefined')
|
||||
{
|
||||
if (typeof console != 'undefined') {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** The constructor of the egw_json_request class.
|
||||
/** The constructor of the egw_json_request class.
|
||||
*
|
||||
* @param string _menuaction the menuaction function which should be called and
|
||||
* which handles the actual request. If the menuaction is a full featured
|
||||
@ -173,31 +165,24 @@ function _egw_json_plugin_handle(_type, _response, _context) {
|
||||
* @param array _parameters which should be passed to the menuaction function.
|
||||
* @param object _context is the context which will be used for the callbacks (not callback of sendRequest!)
|
||||
*/
|
||||
function egw_json_request(_menuaction, _parameters, _context)
|
||||
{
|
||||
window.egw_json_request = function (_menuaction, _parameters, _context) {
|
||||
egw.debug("warn", "Function %s is deprecated", arguments.callee.name);
|
||||
this.context = window.document;
|
||||
if (typeof _context != 'undefined')
|
||||
this.context = _context;
|
||||
|
||||
if (typeof _parameters != 'undefined')
|
||||
{
|
||||
if (typeof _parameters != 'undefined') {
|
||||
this.parameters = _parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this.parameters = new Array;
|
||||
}
|
||||
|
||||
// Check whether the supplied menuaction parameter is a full featured url
|
||||
// or just a menuaction
|
||||
if (_menuaction.match(/json.php\?menuaction=[a-z_0-9]*\.[a-z_0-9]*\.[a-z_0-9]*/i))
|
||||
{
|
||||
if (_menuaction.match(/json.php\?menuaction=[a-z_0-9]*\.[a-z_0-9]*\.[a-z_0-9]*/i)) {
|
||||
// Menuaction is a full featured url
|
||||
this.url = _menuaction;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// We only got a menu action, assemble the url manually.
|
||||
this.url = this._assembleAjaxUrl(_menuaction);
|
||||
}
|
||||
@ -210,46 +195,41 @@ function egw_json_request(_menuaction, _parameters, _context)
|
||||
this.loadedJSFiles = {};
|
||||
this.handleResponseDone = false;
|
||||
this.app = null;
|
||||
if (window.egw_alertHandler)
|
||||
{
|
||||
if (window.egw_alertHandler) {
|
||||
this.alertHandler = window.egw_alertHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Sets the "application" object which is passed to egw_appWindowOpen when a redirect is done
|
||||
*/
|
||||
egw_json_request.prototype.setAppObject = function(_app)
|
||||
{
|
||||
window.egw_json_request.prototype.setAppObject = function (_app) {
|
||||
this.app = _app;
|
||||
}
|
||||
}
|
||||
|
||||
egw_json_request.prototype._assembleAjaxUrl = function(_menuaction)
|
||||
{
|
||||
window.egw_json_request.prototype._assembleAjaxUrl = function (_menuaction) {
|
||||
// Retrieve the webserver url
|
||||
var webserver_url = window.egw_webserverUrl || egw_topWindow().egw_webserverUrl;
|
||||
|
||||
// Check whether the webserver_url is really set
|
||||
// Don't check for !webserver_url as it might be empty.
|
||||
// Thank you to Ingo Ratsdorf for reporting this.
|
||||
if (typeof webserver_url == "undefined")
|
||||
{
|
||||
if (typeof webserver_url == "undefined") {
|
||||
throw "Internal JS error, top window not found, webserver url could not be retrieved.";
|
||||
}
|
||||
|
||||
// Add the ajax relevant parts
|
||||
return webserver_url + '/json.php?menuaction=' + _menuaction;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Sends the AJAX JSON request.
|
||||
*
|
||||
* @param boolean _async specifies whether the request should be handeled asynchronously (true, the sendRequest function immediately returns to the caller) or asynchronously (false, the sendRequest function waits until the request is received)
|
||||
* @param _callback is an additional callback function which should be called upon a "data" response is received
|
||||
* @param _sender context (this) of _callback (different from _context param of constructor used for standard callbacks!)
|
||||
*/
|
||||
egw_json_request.prototype.sendRequest = function(_async, _callback, _sender)
|
||||
{
|
||||
*/
|
||||
window.egw_json_request.prototype.sendRequest = function (_async, _callback, _sender) {
|
||||
egw.debug("warn", "egw_json_request is deprecated\n\
|
||||
Use egw.json(menuaction, parameters [,callback, context, async, sender]).sendRequest() instead.");
|
||||
//Store the sender and callback parameter inside this class
|
||||
@ -273,94 +253,79 @@ Use egw.json(menuaction, parameters [,callback, context, async, sender]).sendReq
|
||||
};
|
||||
|
||||
//Send the request via the jquery AJAX interface to the server
|
||||
this.request = jQuery.ajax({url: this.url,
|
||||
this.request = jQuery.ajax({
|
||||
url: this.url,
|
||||
async: is_async,
|
||||
context: this,
|
||||
data: request_obj,
|
||||
dataType: 'json',
|
||||
type: 'POST',
|
||||
success: this.handleResponse,
|
||||
error: function(_xmlhttp,_err) {
|
||||
error: function (_xmlhttp, _err) {
|
||||
window.console.error('Ajax request to ' + this.url + ' failed: ' + _err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
egw_json_request.prototype.abort = function()
|
||||
{
|
||||
window.egw_json_request.prototype.abort = function () {
|
||||
this.request.abort();
|
||||
}
|
||||
}
|
||||
|
||||
egw_json_request.prototype.alertFunc = function(_message, _details)
|
||||
{
|
||||
window.egw_json_request.prototype.alertFunc = function (_message, _details) {
|
||||
alert(_message);
|
||||
if(_details) _egw_json_debug_log(_message, _details);
|
||||
}
|
||||
if (_details) _egw_json_debug_log(_message, _details);
|
||||
}
|
||||
|
||||
function _egw_json_debug_log(_msg, _e)
|
||||
{
|
||||
if (typeof console != "undefined" && typeof console.log != "undefined")
|
||||
{
|
||||
function _egw_json_debug_log(_msg, _e) {
|
||||
if (typeof console != "undefined" && typeof console.log != "undefined") {
|
||||
console.log(_msg, _e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Displays an json error message */
|
||||
egw_json_request.prototype.jsonError = function(_msg, _e)
|
||||
{
|
||||
var msg = 'EGW JSON Error: '+_msg;
|
||||
/* Displays an json error message */
|
||||
window.egw_json_request.prototype.jsonError = function (_msg, _e) {
|
||||
var msg = 'EGW JSON Error: ' + _msg;
|
||||
|
||||
//Log and show the error message
|
||||
_egw_json_debug_log(msg, _e);
|
||||
this.alertHandler(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Internal function which handles the response from the server */
|
||||
egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRequest)
|
||||
{
|
||||
/* Internal function which handles the response from the server */
|
||||
window.egw_json_request.prototype.handleResponse = function (data, textStatus, XMLHttpRequest) {
|
||||
this.handleResponseDone = false;
|
||||
if (data && data.response)
|
||||
{
|
||||
if (data && data.response) {
|
||||
var hasResponse = false;
|
||||
// Try to load files using API
|
||||
if(egw && egw().includeJS)
|
||||
{
|
||||
if (egw && egw().includeJS) {
|
||||
var js_files = [];
|
||||
var css_files = [];
|
||||
for (var i = data.response.length - 1; i > 0; --i)
|
||||
{
|
||||
for (var i = data.response.length - 1; i > 0; --i) {
|
||||
var res = data.response[i];
|
||||
if(res.type == 'js' && typeof res.data == 'string')
|
||||
{
|
||||
if (res.type == 'js' && typeof res.data == 'string') {
|
||||
js_files.unshift(res.data);
|
||||
this.loadedJSFiles[res.data] = false;
|
||||
data.response.splice(i,1);
|
||||
data.response.splice(i, 1);
|
||||
}
|
||||
}
|
||||
if(js_files.length > 0)
|
||||
{
|
||||
egw().includeJS(js_files, function() {
|
||||
for(var i = 0; i < js_files.length; i++)
|
||||
{
|
||||
if (js_files.length > 0) {
|
||||
egw().includeJS(js_files, function () {
|
||||
for (var i = 0; i < js_files.length; i++) {
|
||||
this.loadedJSFiles[js_files[i]] = true;
|
||||
}
|
||||
this.checkLoadFinish();
|
||||
},this);
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < data.response.length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (var i = 0; i < data.response.length; i++) {
|
||||
try {
|
||||
var res = data.response[i];
|
||||
|
||||
switch (data.response[i].type)
|
||||
{
|
||||
switch (data.response[i].type) {
|
||||
case 'alert':
|
||||
//Check whether all needed parameters have been passed and call the alertHandler function
|
||||
if ((typeof res.data.message != 'undefined') &&
|
||||
(typeof res.data.details != 'undefined'))
|
||||
{
|
||||
(typeof res.data.details != 'undefined')) {
|
||||
this.alertHandler(
|
||||
res.data.message,
|
||||
res.data.details)
|
||||
@ -372,15 +337,12 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
//Check whether all needed parameters have been passed and call the alertHandler function
|
||||
if ((typeof res.data.id != 'undefined') &&
|
||||
(typeof res.data.key != 'undefined') &&
|
||||
(typeof res.data.value != 'undefined'))
|
||||
{
|
||||
(typeof res.data.value != 'undefined')) {
|
||||
var obj = document.getElementById(res.data.id);
|
||||
if (obj)
|
||||
{
|
||||
if (obj) {
|
||||
obj[res.data.key] = res.data.value;
|
||||
|
||||
if (res.data.key == "innerHTML")
|
||||
{
|
||||
if (res.data.key == "innerHTML") {
|
||||
egw_insertJS(res.data.value);
|
||||
}
|
||||
|
||||
@ -391,22 +353,17 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
break;
|
||||
case 'data':
|
||||
//Callback the caller in order to allow him to handle the data
|
||||
if (this.callback)
|
||||
{
|
||||
if (this.callback) {
|
||||
this.callback.call(this.sender, res.data);
|
||||
hasResponse = true;
|
||||
}
|
||||
break;
|
||||
case 'script':
|
||||
if (typeof res.data == 'string')
|
||||
{
|
||||
try
|
||||
{
|
||||
if (typeof res.data == 'string') {
|
||||
try {
|
||||
var func = new Function(res.data);
|
||||
func.call(window);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
} catch (e) {
|
||||
e.code = res.data;
|
||||
_egw_json_debug_log(e);
|
||||
}
|
||||
@ -415,38 +372,31 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
throw 'Invalid parameters';
|
||||
break;
|
||||
case 'apply':
|
||||
if (typeof res.data.func == 'string' && typeof window[res.data.func] == 'function')
|
||||
{
|
||||
try
|
||||
{
|
||||
if (typeof res.data.func == 'string' && typeof window[res.data.func] == 'function') {
|
||||
try {
|
||||
window[res.data.func].apply(window, res.data.parms);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
} catch (e) {
|
||||
_egw_json_debug_log(e, {'Function': res.data.func, 'Parameters': res.data.parms});
|
||||
}
|
||||
hasResponse = true;
|
||||
} else if (typeof res.data.func == "string" &&
|
||||
res.data.func.substr(0,4) == "app." && app)
|
||||
{
|
||||
res.data.func.substr(0, 4) == "app." && app) {
|
||||
|
||||
var parts = res.data.func.split(".");
|
||||
// check if we need a not yet instanciated app.js object --> instanciate it now
|
||||
if (parts.length == 3 && typeof app[parts[1]] == 'undefined' &&
|
||||
typeof app.classes[parts[1]] == 'function')
|
||||
{
|
||||
typeof app.classes[parts[1]] == 'function') {
|
||||
app[parts[1]] = new app.classes[parts[1]]();
|
||||
}
|
||||
if(parts.length == 3 && typeof app[parts[1]] == "object" &&
|
||||
typeof app[parts[1]][parts[2]] == "function")
|
||||
{
|
||||
try
|
||||
{
|
||||
if (parts.length == 3 && typeof app[parts[1]] == "object" &&
|
||||
typeof app[parts[1]][parts[2]] == "function") {
|
||||
try {
|
||||
this.context = app[parts[1]][parts[2]].apply(app[parts[1]], res.data.parms);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
_egw_json_debug_log(e, {'Function': res.data.func, 'Parameters': res.data.parms});
|
||||
} catch (e) {
|
||||
_egw_json_debug_log(e, {
|
||||
'Function': res.data.func,
|
||||
'Parameters': res.data.parms
|
||||
});
|
||||
}
|
||||
}
|
||||
hasResponse = true;
|
||||
@ -456,15 +406,11 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
break;
|
||||
case 'jquery':
|
||||
if (typeof res.data.select == 'string' &&
|
||||
typeof res.data.func == 'string')
|
||||
{
|
||||
try
|
||||
{
|
||||
typeof res.data.func == 'string') {
|
||||
try {
|
||||
var jQueryObject = jQuery(res.data.select, this.context);
|
||||
jQueryObject[res.data.func].apply(jQueryObject, res.data.parms);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
} catch (e) {
|
||||
_egw_json_debug_log(e, {'Function': res.data.func, 'Parameters': res.data.parms});
|
||||
}
|
||||
hasResponse = true;
|
||||
@ -475,17 +421,13 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
//console.log(res.data.url);
|
||||
if (typeof res.data.url == 'string' &&
|
||||
typeof res.data.global == 'boolean' &&
|
||||
typeof res.data.app == 'string')
|
||||
{
|
||||
typeof res.data.app == 'string') {
|
||||
//Special handling for framework reload
|
||||
res.data.global |= (res.data.url.indexOf("?cd=10") > 0);
|
||||
|
||||
if (res.data.global)
|
||||
{
|
||||
if (res.data.global) {
|
||||
egw_topWindow().location.href = res.data.url;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
egw_appWindowOpen(res.data.app, res.data.url);
|
||||
}
|
||||
|
||||
@ -494,11 +436,9 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
throw 'Invalid parameters';
|
||||
break;
|
||||
case 'css':
|
||||
if (typeof res.data == 'string')
|
||||
{
|
||||
if (typeof res.data == 'string') {
|
||||
//Check whether the requested file had already be included
|
||||
if (!egw_json_files[res.data])
|
||||
{
|
||||
if (!egw_json_files[res.data]) {
|
||||
egw_json_files[res.data] = true;
|
||||
|
||||
//Get the head node and append a new link node with the stylesheet url to it
|
||||
@ -514,11 +454,9 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
throw 'Invalid parameters';
|
||||
break;
|
||||
case 'js':
|
||||
if (typeof res.data == 'string')
|
||||
{
|
||||
if (typeof res.data == 'string') {
|
||||
//Check whether the requested file had already be included
|
||||
if (!egw_json_files[res.data])
|
||||
{
|
||||
if (!egw_json_files[res.data]) {
|
||||
egw_json_files[res.data] = true;
|
||||
|
||||
//Get the head node and append a new script node with the js file to it
|
||||
@ -538,7 +476,7 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
var self = this;
|
||||
|
||||
//FF, Opera, Chrome
|
||||
scriptnode.onload = function(e) {
|
||||
scriptnode.onload = function (e) {
|
||||
var file = e.target._originalSrc;
|
||||
if (typeof console != 'undefined' && typeof console.log != 'undefined')
|
||||
console.log("Retrieved JS file '%s' from server", file);
|
||||
@ -548,12 +486,10 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
};
|
||||
|
||||
//IE
|
||||
if (typeof scriptnode.readyState != 'undefined')
|
||||
{
|
||||
if (typeof scriptnode.readyState != 'undefined') {
|
||||
if (scriptnode.readyState != 'complete' &&
|
||||
scriptnode.readyState != 'loaded')
|
||||
{
|
||||
scriptnode.onreadystatechange = function() {
|
||||
scriptnode.readyState != 'loaded') {
|
||||
scriptnode.onreadystatechange = function () {
|
||||
var node = window.event.srcElement;
|
||||
if (node.readyState == 'complete' || node.readyState == 'loaded') {
|
||||
var file = node._originalSrc;
|
||||
@ -564,9 +500,7 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
self.checkLoadFinish();
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
this.loadedJSFiles[res.data] = true;
|
||||
}
|
||||
}
|
||||
@ -576,8 +510,7 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
throw 'Invalid parameters';
|
||||
break;
|
||||
case 'error':
|
||||
if (typeof res.data == 'string')
|
||||
{
|
||||
if (typeof res.data == 'string') {
|
||||
this.jsonError(res.data);
|
||||
hasResponse = true;
|
||||
} else
|
||||
@ -587,14 +520,13 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
|
||||
//Try to handle the json response with all registered plugins
|
||||
hasResponse |= _egw_json_plugin_handle(data.response[i].type, res, this.context);
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
this.jsonError('Internal JSON handler error', e);
|
||||
}
|
||||
}
|
||||
|
||||
/* If no explicit response has been specified, call the callback (if one was set) */
|
||||
if (!hasResponse && this.callback && data.response[i])
|
||||
{
|
||||
if (!hasResponse && this.callback && data.response[i]) {
|
||||
this.callback.call(this.sender, data.response[i].data);
|
||||
}
|
||||
|
||||
@ -602,41 +534,34 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe
|
||||
|
||||
this.checkLoadFinish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* The "onLoadFinish" handler gets called after all JS-files have been loaded
|
||||
* successfully
|
||||
*/
|
||||
egw_json_request.prototype.checkLoadFinish = function()
|
||||
{
|
||||
window.egw_json_request.prototype.checkLoadFinish = function () {
|
||||
var complete = true;
|
||||
for (var key in this.loadedJSFiles) {
|
||||
complete = complete && this.loadedJSFiles[key];
|
||||
}
|
||||
|
||||
if (complete && this.onLoadFinish && this.handleResponseDone)
|
||||
{
|
||||
if (complete && this.onLoadFinish && this.handleResponseDone) {
|
||||
this.onLoadFinish.call(this.sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function egw_json_getFormValues(_form, _filterClass)
|
||||
{
|
||||
window.egw_json_getFormValues = function (_form, _filterClass) {
|
||||
egw.debug("warn", "Function %s is deprecated", arguments.callee.name);
|
||||
var elem = null;
|
||||
if (typeof _form == 'object')
|
||||
{
|
||||
if (typeof _form == 'object') {
|
||||
elem = _form;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
elem = document.getElementsByName(_form)[0];
|
||||
}
|
||||
|
||||
var serialized = new Object;
|
||||
if (typeof elem != "undefined" && elem && elem.childNodes)
|
||||
{
|
||||
if (typeof elem != "undefined" && elem && elem.childNodes) {
|
||||
if (typeof _filterClass == 'undefined')
|
||||
_filterClass = null;
|
||||
|
||||
@ -644,18 +569,16 @@ function egw_json_getFormValues(_form, _filterClass)
|
||||
}
|
||||
|
||||
return serialized;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Deprecated legacy xajax wrapper functions for the new egw_json interface
|
||||
*/
|
||||
_xajax_doXMLHTTP = function(_async, _menuaction, _arguments)
|
||||
{
|
||||
let _xajax_doXMLHTTP = function (_async, _menuaction, _arguments) {
|
||||
egw.debug("warn", "Function %s is deprecated", arguments.callee.name);
|
||||
/* Assemble the parameter array */
|
||||
var paramarray = new Array();
|
||||
for (var i = 1; i < _arguments.length; i++)
|
||||
{
|
||||
for (var i = 1; i < _arguments.length; i++) {
|
||||
paramarray[paramarray.length] = _arguments[i];
|
||||
}
|
||||
|
||||
@ -666,42 +589,38 @@ _xajax_doXMLHTTP = function(_async, _menuaction, _arguments)
|
||||
request.sendRequest(_async);
|
||||
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
||||
xajax_doXMLHTTP = function(_menuaction)
|
||||
{
|
||||
window.xajax_doXMLHTTP = function (_menuaction) {
|
||||
return _xajax_doXMLHTTP(true, _menuaction, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
xajax_doXMLHTTPsync = function(_menuaction)
|
||||
{
|
||||
window.xajax_doXMLHTTPsync = function (_menuaction) {
|
||||
return _xajax_doXMLHTTP(false, _menuaction, arguments);
|
||||
};
|
||||
};
|
||||
|
||||
window.xajax = {
|
||||
"getFormValues": function(_form)
|
||||
{
|
||||
window.xajax = {
|
||||
"getFormValues": function (_form) {
|
||||
return egw_json_getFormValues(_form);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
/*
|
||||
The following code is adapted from the xajax project which is licensed under
|
||||
the following license
|
||||
@copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
|
||||
@copyright Copyright (c) 2008-2009 by Joseph Woolley, Steffen Konerow, Jared White & J. Max Wilson
|
||||
@license http://www.xajaxproject.org/bsd_license.txt BSD License
|
||||
*/
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
* used internally by the legacy "egw_json_response.getFormValues" to recursively
|
||||
* run over all form elements
|
||||
* @param serialized is the object which will contain the form data
|
||||
* @param children is the children node of the form we're runing over
|
||||
* @param string _filterClass if given only return
|
||||
*/
|
||||
function _egw_json_getFormValues(serialized, children, _filterClass)
|
||||
{
|
||||
function _egw_json_getFormValues(serialized, children, _filterClass) {
|
||||
egw.debug("warn", "Function %s is deprecated", arguments.callee.name);
|
||||
//alert('_egw_json_getFormValues(,,'+_filterClass+')');
|
||||
for (var i = 0; i < children.length; ++i) {
|
||||
@ -710,52 +629,43 @@ function _egw_json_getFormValues(serialized, children, _filterClass)
|
||||
if (typeof child.childNodes != "undefined")
|
||||
_egw_json_getFormValues(serialized, child.childNodes, _filterClass);
|
||||
|
||||
if ((!_filterClass || jQuery(child).hasClass(_filterClass)) && typeof child.name != "undefined")
|
||||
{
|
||||
if ((!_filterClass || jQuery(child).hasClass(_filterClass)) && typeof child.name != "undefined") {
|
||||
//alert('_egw_json_getFormValues(,,'+_filterClass+') calling _egw_json_getFormValue for name='+child.name+', class='+child.class+', value='+child.value);
|
||||
_egw_json_getFormValue(serialized, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _egw_json_getObjectLength(_obj)
|
||||
{
|
||||
function _egw_json_getObjectLength(_obj) {
|
||||
var res = 0;
|
||||
for (key in _obj)
|
||||
{
|
||||
for (key in _obj) {
|
||||
if (_obj.hasOwnProperty(key))
|
||||
res++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* used internally to serialize
|
||||
*/
|
||||
function _egw_json_getFormValue(serialized, child)
|
||||
{
|
||||
function _egw_json_getFormValue(serialized, child) {
|
||||
//Return if the child doesn't have a name, is disabled, or is a radio-/checkbox and not checked
|
||||
if ((typeof child.name == "undefined") || (child.disabled && child.disabled == true) ||
|
||||
(child.type && (child.type == 'radio' || child.type == 'checkbox' || child.type == 'button' || child.type == 'submit') && (!child.checked)))
|
||||
{
|
||||
(child.type && (child.type == 'radio' || child.type == 'checkbox' || child.type == 'button' || child.type == 'submit') && (!child.checked))) {
|
||||
return;
|
||||
}
|
||||
|
||||
var name = child.name;
|
||||
var values = null;
|
||||
|
||||
if ('select-multiple' == child.type)
|
||||
{
|
||||
if ('select-multiple' == child.type) {
|
||||
values = new Array;
|
||||
for (var j = 0; j < child.length; ++j)
|
||||
{
|
||||
for (var j = 0; j < child.length; ++j) {
|
||||
var option = child.options[j];
|
||||
if (option.selected == true)
|
||||
values.push(option.value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
values = child.value;
|
||||
}
|
||||
|
||||
@ -771,14 +681,14 @@ function _egw_json_getFormValue(serialized, child)
|
||||
|
||||
var p = serialized; // pointer reset
|
||||
while (a.length != 0) {
|
||||
var sa = a.substr(0, a.indexOf(']')+1);
|
||||
var sa = a.substr(0, a.indexOf(']') + 1);
|
||||
|
||||
var lk = k; //save last key
|
||||
var lp = p; //save last pointer
|
||||
|
||||
a = a.substr(a.indexOf(']')+1);
|
||||
a = a.substr(a.indexOf(']') + 1);
|
||||
p = p[k];
|
||||
k = sa.substr(1, sa.length-2);
|
||||
k = sa.substr(1, sa.length - 2);
|
||||
if (k == '') {
|
||||
if ('select-multiple' == child.type) {
|
||||
k = lk; //restore last key
|
||||
@ -787,17 +697,16 @@ function _egw_json_getFormValue(serialized, child)
|
||||
k = _egw_json_getObjectLength(p);
|
||||
}
|
||||
}
|
||||
if (typeof p[k] == 'undefined')
|
||||
{
|
||||
if (typeof p[k] == 'undefined') {
|
||||
p[k] = new Object;
|
||||
}
|
||||
}
|
||||
p[k] = values;
|
||||
} else {
|
||||
//Add the value to the result object with the given name
|
||||
if (typeof values != "undefined")
|
||||
{
|
||||
if (typeof values != "undefined") {
|
||||
serialized[name] = values;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).call(window);
|
@ -11,8 +11,10 @@
|
||||
vendor.bower-asset.jquery.dist.jquery;
|
||||
egw_inheritance.js;
|
||||
*/
|
||||
import '../../../vendor/bower-asset/jquery/dist/jquery.js';
|
||||
import '../jsapi/egw_inheritance.js';
|
||||
|
||||
var fw_base = (function(){ "use strict"; return Class.extend(
|
||||
window.fw_base = (function(){ "use strict"; return Class.extend(
|
||||
{
|
||||
/**
|
||||
* Framework base class constructor sets up basic initialization
|
||||
|
@ -12,14 +12,19 @@
|
||||
egw_inheritance.js;
|
||||
*/
|
||||
|
||||
import '../../../vendor/bower-asset/jquery/dist/jquery.js';
|
||||
import '../egw_action/egw_action_common.js';
|
||||
import '../jsapi/egw_inheritance.js';
|
||||
import '../etemplate/etemplate2.js'; // otherwise et2_load json-response-handler is not (yet) available
|
||||
|
||||
/**
|
||||
* Constants definition
|
||||
*/
|
||||
EGW_BROWSER_TYPE_NONE = 0;
|
||||
EGW_BROWSER_TYPE_IFRAME = 1;
|
||||
EGW_BROWSER_TYPE_DIV = 2;
|
||||
window.EGW_BROWSER_TYPE_NONE = 0;
|
||||
window.EGW_BROWSER_TYPE_IFRAME = 1;
|
||||
window.EGW_BROWSER_TYPE_DIV = 2;
|
||||
|
||||
var fw_browser = (function(){ "use strict"; return Class.extend(
|
||||
window.fw_browser = (function(){ "use strict"; return Class.extend(
|
||||
{
|
||||
/**
|
||||
* @param {string} _app
|
||||
|
@ -10,7 +10,11 @@
|
||||
/*----------------------------
|
||||
Class egw_fw_class_application
|
||||
----------------------------*/
|
||||
/**
|
||||
(function()
|
||||
{
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* application class constructor
|
||||
*
|
||||
* @param {type} _parentFw
|
||||
@ -23,9 +27,8 @@
|
||||
* @param {type} _internalName
|
||||
* @returns {egw_fw_class_application}
|
||||
*/
|
||||
function egw_fw_class_application(_parentFw, _appName, _displayName, _icon,
|
||||
_indexUrl, _sideboxWidth, _baseUrl, _internalName)
|
||||
{
|
||||
window.egw_fw_class_application = function(_parentFw, _appName, _displayName, _icon,
|
||||
_indexUrl, _sideboxWidth, _baseUrl, _internalName) {
|
||||
//Copy the application properties
|
||||
this.appName = _appName;
|
||||
this.internalName = _internalName;
|
||||
@ -49,23 +52,22 @@ function egw_fw_class_application(_parentFw, _appName, _displayName, _icon,
|
||||
this.sidemenuEntry = null;
|
||||
this.tab = null;
|
||||
this.browser = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* destroy application object and its relative parts
|
||||
*/
|
||||
egw_fw_class_application.prototype.destroy = function()
|
||||
{
|
||||
window.egw_fw_class_application.prototype.destroy = function () {
|
||||
delete this.tab;
|
||||
if (this.sidemenuEntry) this.sidemenuEntry.remove();
|
||||
delete this.sidemenuEntry;
|
||||
delete this.browser;
|
||||
delete (framework.applications[this.appName]);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns an menuaction inside the jdots_framework for this application.
|
||||
* without a "this" context (by directly calling egw_fw_class_application.prototype.getAjaxUrl)
|
||||
* without a "this" context (by directly calling window.egw_fw_class_application.prototype.getAjaxUrl)
|
||||
* or passing null to a "call" call "home" will be used as application name and
|
||||
* the the base url will be omitted (default behaviour for all applications which)
|
||||
* lie inside the default egw instance.
|
||||
@ -73,13 +75,11 @@ egw_fw_class_application.prototype.destroy = function()
|
||||
* @param {string} _fun is the function which shall be called on the server.
|
||||
* @param {string} _ajax_exec_url contains menuaction for _fun === 'ajax_exec'
|
||||
*/
|
||||
egw_fw_class_application.prototype.getMenuaction = function(_fun, _ajax_exec_url)
|
||||
{
|
||||
window.egw_fw_class_application.prototype.getMenuaction = function (_fun, _ajax_exec_url) {
|
||||
var baseUrl = '';
|
||||
var appName = 'home';
|
||||
|
||||
if (this)
|
||||
{
|
||||
if (this) {
|
||||
baseUrl = this.getBaseUrl();
|
||||
appName = this.internalName;
|
||||
}
|
||||
@ -87,19 +87,18 @@ egw_fw_class_application.prototype.getMenuaction = function(_fun, _ajax_exec_url
|
||||
// Check whether the baseurl is actually set. If not, then this application
|
||||
// resides inside the same egw instance as the jdots framework. We'll simply
|
||||
// return a menu action and not a full featured url here.
|
||||
if (baseUrl != '')
|
||||
{
|
||||
if (baseUrl != '') {
|
||||
baseUrl = baseUrl + 'json.php?menuaction=';
|
||||
}
|
||||
|
||||
var menuaction = _ajax_exec_url ? _ajax_exec_url.match(/menuaction=([^&]+)/) : null;
|
||||
|
||||
// use template handler to call current framework, eg. pixelegg
|
||||
return baseUrl + appName + '.jdots_framework.' + _fun + '.template'+
|
||||
(menuaction ? '.'+menuaction[1] : '');
|
||||
};
|
||||
return baseUrl + appName + '.jdots_framework.' + _fun + '.template' +
|
||||
(menuaction ? '.' + menuaction[1] : '');
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns the base url for this application. If the application resides inside
|
||||
* the default egw instance, '' will be returned unless the _force parameter is
|
||||
* set to true.
|
||||
@ -108,43 +107,38 @@ egw_fw_class_application.prototype.getMenuaction = function(_fun, _ajax_exec_url
|
||||
* webserverUrl instead of '' if the application resides inside the main
|
||||
* egw instance.
|
||||
*/
|
||||
egw_fw_class_application.prototype.getBaseUrl = function(_force)
|
||||
{
|
||||
if (this.baseUrl)
|
||||
{
|
||||
window.egw_fw_class_application.prototype.getBaseUrl = function (_force) {
|
||||
if (this.baseUrl) {
|
||||
return this.baseUrl;
|
||||
}
|
||||
else if ((typeof _force != 'undefined') && _force)
|
||||
{
|
||||
} else if ((typeof _force != 'undefined') && _force) {
|
||||
return egw_topWindow().egw_webserverUrl;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
};
|
||||
}).call(window);
|
||||
|
||||
function egw_fw_getMenuaction(_fun)
|
||||
window.egw_fw_getMenuaction = function(_fun)
|
||||
{
|
||||
return egw_fw_class_application.prototype.getMenuaction.call(null, _fun);
|
||||
return window.egw_fw_class_application.prototype.getMenuaction.call(null, _fun);
|
||||
}
|
||||
|
||||
/*----------------------------
|
||||
Class egw_fw_class_callback
|
||||
----------------------------*/
|
||||
|
||||
function egw_fw_class_callback(_context, _proc)
|
||||
window.egw_fw_class_callback = function(_context, _proc)
|
||||
{
|
||||
this.context = _context;
|
||||
this.proc = _proc;
|
||||
}
|
||||
|
||||
egw_fw_class_callback.prototype.call = function()
|
||||
window.egw_fw_class_callback.prototype.call = function()
|
||||
{
|
||||
return this.proc.apply(this.context, arguments);
|
||||
};
|
||||
|
||||
array_remove = function(array, index)
|
||||
window.array_remove = function(array, index)
|
||||
{
|
||||
array.splice(index, 1);
|
||||
};
|
||||
|
@ -16,6 +16,12 @@
|
||||
framework.fw_classes;
|
||||
egw_inheritance.js;
|
||||
*/
|
||||
import '../../../vendor/bower-asset/jquery/dist/jquery.js';
|
||||
import './fw_base.js';
|
||||
import './fw_browser.js';
|
||||
import './fw_ui.js';
|
||||
import './fw_classes.js';
|
||||
import '../jsapi/egw_inheritance.js';
|
||||
|
||||
/**
|
||||
*
|
||||
@ -29,8 +35,8 @@
|
||||
*
|
||||
* @type @exp;fw_ui_sidemenu_entry@call;extend
|
||||
*/
|
||||
var desktop_ui_sidemenu_entry = fw_ui_sidemenu_entry.extend({
|
||||
|
||||
window.desktop_ui_sidemenu_entry = fw_ui_sidemenu_entry.extend(
|
||||
{
|
||||
/**
|
||||
* Override fw_ui_sidemenu_entry class constructor
|
||||
*
|
||||
@ -91,7 +97,7 @@
|
||||
*
|
||||
* @type @exp;fw_ui_sidemenu@call;extend
|
||||
*/
|
||||
var desktop_ui_sidemenu = fw_ui_sidemenu.extend(
|
||||
window.desktop_ui_sidemenu = fw_ui_sidemenu.extend(
|
||||
{
|
||||
init: function(_baseDiv, _sortCallback)
|
||||
{
|
||||
|
@ -12,6 +12,10 @@
|
||||
/api/js/jquery/mousewheel/mousewheel.js;
|
||||
egw_inheritance.js;
|
||||
*/
|
||||
import '../../../vendor/bower-asset/jquery/dist/jquery.js';
|
||||
import '../../../vendor/bower-asset/jquery-ui/jquery-ui.js';
|
||||
import '../jquery/mousewheel/mousewheel.js';
|
||||
import '../jsapi/egw_inheritance.js';
|
||||
|
||||
/**
|
||||
* ui siemenu entry class
|
||||
@ -19,7 +23,7 @@
|
||||
*
|
||||
* @type @exp;Class@call;extend
|
||||
*/
|
||||
var fw_ui_sidemenu_entry = (function(){ "use strict"; return Class.extend(
|
||||
window.fw_ui_sidemenu_entry = (function(){ "use strict"; return Class.extend(
|
||||
{
|
||||
/**
|
||||
* Framework ui sidemenu entry class constructor
|
||||
@ -194,7 +198,7 @@ var fw_ui_sidemenu_entry = (function(){ "use strict"; return Class.extend(
|
||||
*
|
||||
* @type @exp;Class@call;extend
|
||||
*/
|
||||
var fw_ui_sidemenu = (function(){ "use strict"; return Class.extend(
|
||||
window.fw_ui_sidemenu = (function(){ "use strict"; return Class.extend(
|
||||
{
|
||||
/**
|
||||
* The constructor of the egw_fw_ui_sidemenu.
|
||||
@ -310,7 +314,7 @@ var fw_ui_sidemenu = (function(){ "use strict"; return Class.extend(
|
||||
* @param {int} _pos is the position where the tab will be inserted
|
||||
* @param {string} application status (e.g. status="5")
|
||||
*/
|
||||
function egw_fw_ui_tab(_parent, _contHeaderDiv, _contDiv, _icon, _callback,
|
||||
window.egw_fw_ui_tab = function(_parent, _contHeaderDiv, _contDiv, _icon, _callback,
|
||||
_closeCallback, _tag, _pos, _status)
|
||||
{
|
||||
this.parent = _parent;
|
||||
@ -452,7 +456,7 @@ function egw_fw_ui_tab(_parent, _contHeaderDiv, _contDiv, _icon, _callback,
|
||||
* @param {int} _value if set to 0 the notification gets reset if nothing set
|
||||
* it will increase the notification value by one
|
||||
*/
|
||||
egw_fw_ui_tab.prototype.setNotification = function(_value)
|
||||
window.egw_fw_ui_tab.prototype.setNotification = function(_value)
|
||||
{
|
||||
this.notification = typeof _value != 'undefined' ? _value : this.notification+1;
|
||||
jQuery(this.notificationDiv).text(this.notification).toggle(this.notification > 0);
|
||||
@ -463,7 +467,7 @@ egw_fw_ui_tab.prototype.setNotification = function(_value)
|
||||
*
|
||||
* @param {string} _title HTML/Text which should be displayed.
|
||||
*/
|
||||
egw_fw_ui_tab.prototype.setTitle = function(_title)
|
||||
window.egw_fw_ui_tab.prototype.setTitle = function(_title)
|
||||
{
|
||||
this.title = _title;
|
||||
jQuery(this.headerH1).empty();
|
||||
@ -475,7 +479,7 @@ egw_fw_ui_tab.prototype.setTitle = function(_title)
|
||||
*
|
||||
* @param {string} _hint Text which should be displayed.
|
||||
*/
|
||||
egw_fw_ui_tab.prototype.setHint = function(_hint)
|
||||
window.egw_fw_ui_tab.prototype.setHint = function(_hint)
|
||||
{
|
||||
this.hint = _hint;
|
||||
egw().tooltipBind(jQuery(this.headerDiv), _hint);
|
||||
@ -486,7 +490,7 @@ egw_fw_ui_tab.prototype.setHint = function(_hint)
|
||||
*
|
||||
* @param {string} _content HTML/Text which should be displayed.
|
||||
*/
|
||||
egw_fw_ui_tab.prototype.setContent = function(_content)
|
||||
window.egw_fw_ui_tab.prototype.setContent = function(_content)
|
||||
{
|
||||
jQuery(this.contentDiv).empty();
|
||||
jQuery(this.contentDiv).append(_content);
|
||||
@ -496,7 +500,7 @@ egw_fw_ui_tab.prototype.setContent = function(_content)
|
||||
* Shows the content of the tab. Only one tab should be displayed at once. By using egw_fw_ui_tabs.showTab
|
||||
* you can assure this.
|
||||
*/
|
||||
egw_fw_ui_tab.prototype.show = function()
|
||||
window.egw_fw_ui_tab.prototype.show = function()
|
||||
{
|
||||
jQuery(this.headerDiv).addClass("egw_fw_ui_tab_header_active");
|
||||
var content = jQuery(this.contentDiv);
|
||||
@ -519,7 +523,7 @@ egw_fw_ui_tab.prototype.show = function()
|
||||
/**
|
||||
* Hides the content of this tab.
|
||||
*/
|
||||
egw_fw_ui_tab.prototype.hide = function()
|
||||
window.egw_fw_ui_tab.prototype.hide = function()
|
||||
{
|
||||
jQuery(this.headerDiv).removeClass("egw_fw_ui_tab_header_active");
|
||||
var content = jQuery(this.contentDiv);
|
||||
@ -538,7 +542,7 @@ egw_fw_ui_tab.prototype.hide = function()
|
||||
/**
|
||||
* hide tab header only
|
||||
*/
|
||||
egw_fw_ui_tab.prototype.hideTabHeader = function()
|
||||
window.egw_fw_ui_tab.prototype.hideTabHeader = function()
|
||||
{
|
||||
jQuery(this.headerDiv).hide();
|
||||
};
|
||||
@ -546,7 +550,7 @@ egw_fw_ui_tab.prototype.hideTabHeader = function()
|
||||
/**
|
||||
* Removes this tab and all its content.
|
||||
*/
|
||||
egw_fw_ui_tab.prototype.remove = function()
|
||||
window.egw_fw_ui_tab.prototype.remove = function()
|
||||
{
|
||||
this.hide();
|
||||
jQuery(this.contentDiv).remove();
|
||||
@ -558,7 +562,7 @@ egw_fw_ui_tab.prototype.remove = function()
|
||||
*
|
||||
* @param {boolean} _closeable if true, the close button is shown, if false, the close button is hidden. default is true.
|
||||
*/
|
||||
egw_fw_ui_tab.prototype.setCloseable = function(_closeable)
|
||||
window.egw_fw_ui_tab.prototype.setCloseable = function(_closeable)
|
||||
{
|
||||
this.closeable = _closeable;
|
||||
if (_closeable)
|
||||
@ -579,7 +583,7 @@ egw_fw_ui_tab.prototype.setCloseable = function(_closeable)
|
||||
*
|
||||
* @param {object} _contDiv specifies "div" element the tab ui element should be displayed in.
|
||||
*/
|
||||
function egw_fw_ui_tabs(_contDiv)
|
||||
window.egw_fw_ui_tabs = function(_contDiv)
|
||||
{
|
||||
this.contDiv = _contDiv;
|
||||
|
||||
@ -609,7 +613,7 @@ function egw_fw_ui_tabs(_contDiv)
|
||||
* @param {string} _text is the text which will be seen in the appHeader.
|
||||
* @param {string} _msg_class css class for message
|
||||
*/
|
||||
egw_fw_ui_tabs.prototype.setAppHeader = function(_text, _msg_class)
|
||||
window.egw_fw_ui_tabs.prototype.setAppHeader = function(_text, _msg_class)
|
||||
{
|
||||
this.appHeader.text(_text);
|
||||
this.appHeader.prop('class', "egw_fw_ui_app_header");
|
||||
@ -623,7 +627,7 @@ egw_fw_ui_tabs.prototype.setAppHeader = function(_text, _msg_class)
|
||||
* to switch back to the last tab when a tab is closed. Double entries in the tab history
|
||||
* may appear whenever a tab is deleted.
|
||||
*/
|
||||
egw_fw_ui_tabs.prototype.cleanHistory = function()
|
||||
window.egw_fw_ui_tabs.prototype.cleanHistory = function()
|
||||
{
|
||||
for (var i = this.tabHistory.length - 1; i >= 0; i--)
|
||||
{
|
||||
@ -643,7 +647,7 @@ egw_fw_ui_tabs.prototype.cleanHistory = function()
|
||||
* @param {int} _pos specifies the position in the tab list. If _pos is -1, the tab will be added to the end of the tab list
|
||||
* @param {string} application status
|
||||
*/
|
||||
egw_fw_ui_tabs.prototype.addTab = function(_icon, _callback, _closeCallback, _tag, _pos, _status)
|
||||
window.egw_fw_ui_tabs.prototype.addTab = function(_icon, _callback, _closeCallback, _tag, _pos, _status)
|
||||
{
|
||||
var pos = -1;
|
||||
if (typeof _pos != 'undefined')
|
||||
@ -684,7 +688,7 @@ egw_fw_ui_tabs.prototype.addTab = function(_icon, _callback, _closeCallback, _ta
|
||||
*
|
||||
* @param {object} _tab is the object which should be closed.
|
||||
*/
|
||||
egw_fw_ui_tabs.prototype.removeTab = function(_tab)
|
||||
window.egw_fw_ui_tabs.prototype.removeTab = function(_tab)
|
||||
{
|
||||
//Delete the deleted tab from the history
|
||||
for (var i = this.tabHistory.length - 1; i >= 0; i--)
|
||||
@ -734,7 +738,7 @@ egw_fw_ui_tabs.prototype.removeTab = function(_tab)
|
||||
*
|
||||
* @param {object} _tab is the object which should be opened.
|
||||
*/
|
||||
egw_fw_ui_tabs.prototype.showTab = function(_tab)
|
||||
window.egw_fw_ui_tabs.prototype.showTab = function(_tab)
|
||||
{
|
||||
if (this.activeTab != _tab && (_tab.status != '5' || _tab.tag.isFrameworkTab))
|
||||
{
|
||||
@ -765,7 +769,7 @@ egw_fw_ui_tabs.prototype.showTab = function(_tab)
|
||||
*
|
||||
* @param {boolean} _closeable
|
||||
*/
|
||||
egw_fw_ui_tabs.prototype.setCloseable = function(_closeable)
|
||||
window.egw_fw_ui_tabs.prototype.setCloseable = function(_closeable)
|
||||
{
|
||||
for (var i = 0; i < this.tabs.length; i++)
|
||||
{
|
||||
@ -777,7 +781,7 @@ egw_fw_ui_tabs.prototype.setCloseable = function(_closeable)
|
||||
* Clears all data, removes all tabs, independently from the question, whether they may be closed or
|
||||
* not.
|
||||
*/
|
||||
egw_fw_ui_tabs.prototype.clean = function()
|
||||
window.egw_fw_ui_tabs.prototype.clean = function()
|
||||
{
|
||||
//Remove all tabs, clean the tabs array
|
||||
for (var i = 0; i < this.tabs.length; i++)
|
||||
@ -798,7 +802,7 @@ egw_fw_ui_tabs.prototype.clean = function()
|
||||
*
|
||||
* @return {boolean} returns true if the open tab is not the last visible tab otherwise false
|
||||
*/
|
||||
egw_fw_ui_tabs.prototype._isNotTheLastTab = function()
|
||||
window.egw_fw_ui_tabs.prototype._isNotTheLastTab = function()
|
||||
{
|
||||
var n = 0;
|
||||
for (var i in this.tabs)
|
||||
@ -815,7 +819,7 @@ egw_fw_ui_tabs.prototype._isNotTheLastTab = function()
|
||||
* @param {string} _appname
|
||||
* @returns {object|boolean} returns tab object, returns false if no tab found
|
||||
*/
|
||||
egw_fw_ui_tabs.prototype.getTab = function(_appname)
|
||||
window.egw_fw_ui_tabs.prototype.getTab = function(_appname)
|
||||
{
|
||||
for (var i = 0; i < this.tabs.length; i++)
|
||||
{
|
||||
@ -840,7 +844,7 @@ egw_fw_ui_tabs.prototype.getTab = function(_appname)
|
||||
* @param {object} _tag
|
||||
*/
|
||||
|
||||
function egw_fw_ui_category(_contDiv, _name, _title, _content, _callback, _animationCallback, _tag)
|
||||
window.egw_fw_ui_category = function(_contDiv, _name, _title, _content, _callback, _animationCallback, _tag)
|
||||
{
|
||||
//Copy the parameters
|
||||
this.contDiv = _contDiv;
|
||||
@ -906,7 +910,7 @@ function egw_fw_ui_category(_contDiv, _name, _title, _content, _callback, _anima
|
||||
jQuery(this.headerDiv).append(this.contentDiv);
|
||||
}
|
||||
|
||||
egw_fw_ui_category.prototype.open = function(_instantly)
|
||||
window.egw_fw_ui_category.prototype.open = function(_instantly)
|
||||
{
|
||||
this.callback.call(this, true);
|
||||
jQuery(this.headerDiv).addClass('egw_fw_ui_category_active')
|
||||
@ -926,7 +930,7 @@ egw_fw_ui_category.prototype.open = function(_instantly)
|
||||
jQuery("li:first-child", this.headerDiv).eq(0).focus();
|
||||
};
|
||||
|
||||
egw_fw_ui_category.prototype.close = function(_instantly)
|
||||
window.egw_fw_ui_category.prototype.close = function(_instantly)
|
||||
{
|
||||
this.callback.call(this, false);
|
||||
jQuery(this.headerDiv).removeClass('egw_fw_ui_category_active')
|
||||
@ -945,7 +949,7 @@ egw_fw_ui_category.prototype.close = function(_instantly)
|
||||
}
|
||||
};
|
||||
|
||||
egw_fw_ui_category.prototype.remove = function()
|
||||
window.egw_fw_ui_category.prototype.remove = function()
|
||||
{
|
||||
//Delete the content and header div
|
||||
jQuery(this.contDiv).remove();
|
||||
@ -958,7 +962,7 @@ egw_fw_ui_category.prototype.remove = function()
|
||||
* @param {object} _contDiv
|
||||
*/
|
||||
|
||||
function egw_fw_ui_scrollarea(_contDiv)
|
||||
window.egw_fw_ui_scrollarea = function(_contDiv)
|
||||
{
|
||||
this.startScrollSpeed = 50.0; //in px/sec
|
||||
this.endScrollSpeed = 250.0; //in px/sec
|
||||
@ -1059,7 +1063,7 @@ function egw_fw_ui_scrollarea(_contDiv)
|
||||
this.update();
|
||||
}
|
||||
|
||||
egw_fw_ui_scrollarea.prototype.setScrollPos = function(_pos)
|
||||
window.egw_fw_ui_scrollarea.prototype.setScrollPos = function(_pos)
|
||||
{
|
||||
var scrollArea = egw.preference('scroll_area', 'common') == 1 ? true : false;
|
||||
if (this.buttonsVisible)
|
||||
@ -1116,12 +1120,12 @@ egw_fw_ui_scrollarea.prototype.setScrollPos = function(_pos)
|
||||
}
|
||||
};
|
||||
|
||||
egw_fw_ui_scrollarea.prototype.scrollDelta = function(_delta)
|
||||
window.egw_fw_ui_scrollarea.prototype.scrollDelta = function(_delta)
|
||||
{
|
||||
this.setScrollPos(this.scrollPos + _delta);
|
||||
};
|
||||
|
||||
egw_fw_ui_scrollarea.prototype.toggleButtons = function(_visible)
|
||||
window.egw_fw_ui_scrollarea.prototype.toggleButtons = function(_visible)
|
||||
{
|
||||
if (_visible)
|
||||
{
|
||||
@ -1141,7 +1145,7 @@ egw_fw_ui_scrollarea.prototype.toggleButtons = function(_visible)
|
||||
this.buttonsVisible = _visible;
|
||||
};
|
||||
|
||||
egw_fw_ui_scrollarea.prototype.update = function()
|
||||
window.egw_fw_ui_scrollarea.prototype.update = function()
|
||||
{
|
||||
//Get the height of the content and the outer box
|
||||
this.contHeight = jQuery(this.scrollDiv).outerHeight();
|
||||
@ -1151,7 +1155,7 @@ egw_fw_ui_scrollarea.prototype.update = function()
|
||||
this.setScrollPos(this.scrollPos);
|
||||
};
|
||||
|
||||
egw_fw_ui_scrollarea.prototype.getScrollDelta = function(_timeGap)
|
||||
window.egw_fw_ui_scrollarea.prototype.getScrollDelta = function(_timeGap)
|
||||
{
|
||||
//Calculate the current scroll speed
|
||||
var curScrollSpeed = this.startScrollSpeed + this.scrollSpeedAccel * this.scrollTime;
|
||||
@ -1167,7 +1171,7 @@ egw_fw_ui_scrollarea.prototype.getScrollDelta = function(_timeGap)
|
||||
return curScrollSpeed * _timeGap;
|
||||
};
|
||||
|
||||
egw_fw_ui_scrollarea.prototype.mouseOverCallback = function(_context)
|
||||
window.egw_fw_ui_scrollarea.prototype.mouseOverCallback = function(_context)
|
||||
{
|
||||
//Do the scrolling
|
||||
_context.scrollDelta(_context.getScrollDelta(_context.timerInterval) *
|
||||
@ -1181,7 +1185,7 @@ egw_fw_ui_scrollarea.prototype.mouseOverCallback = function(_context)
|
||||
}
|
||||
};
|
||||
|
||||
egw_fw_ui_scrollarea.prototype.mouseOverToggle = function(_over, _dir)
|
||||
window.egw_fw_ui_scrollarea.prototype.mouseOverToggle = function(_over, _dir)
|
||||
{
|
||||
this.mouseOver = _over;
|
||||
this.dir = _dir;
|
||||
@ -1202,10 +1206,10 @@ egw_fw_ui_scrollarea.prototype.mouseOverToggle = function(_over, _dir)
|
||||
* egw_fw_ui_splitter class
|
||||
*/
|
||||
|
||||
var EGW_SPLITTER_HORIZONTAL = 0;
|
||||
var EGW_SPLITTER_VERTICAL = 1;
|
||||
window.EGW_SPLITTER_HORIZONTAL = 0;
|
||||
window.EGW_SPLITTER_VERTICAL = 1;
|
||||
|
||||
function egw_fw_ui_splitter(_contDiv, _orientation, _resizeCallback, _constraints, _tag)
|
||||
window.egw_fw_ui_splitter = function(_contDiv, _orientation, _resizeCallback, _constraints, _tag)
|
||||
{
|
||||
//Copy the parameters
|
||||
this.tag = _tag;
|
||||
@ -1293,7 +1297,7 @@ function egw_fw_ui_splitter(_contDiv, _orientation, _resizeCallback, _constraint
|
||||
jQuery(this.contDiv).append(this.splitterDiv);
|
||||
}
|
||||
|
||||
egw_fw_ui_splitter.prototype.clipDelta = function(_delta)
|
||||
window.egw_fw_ui_splitter.prototype.clipDelta = function(_delta)
|
||||
{
|
||||
var result = _delta;
|
||||
|
||||
@ -1319,7 +1323,7 @@ egw_fw_ui_splitter.prototype.clipDelta = function(_delta)
|
||||
return result;
|
||||
};
|
||||
|
||||
egw_fw_ui_splitter.prototype.dragStartHandler = function(event, ui)
|
||||
window.egw_fw_ui_splitter.prototype.dragStartHandler = function(event, ui)
|
||||
{
|
||||
switch (this.orientation)
|
||||
{
|
||||
@ -1332,7 +1336,7 @@ egw_fw_ui_splitter.prototype.dragStartHandler = function(event, ui)
|
||||
}
|
||||
};
|
||||
|
||||
egw_fw_ui_splitter.prototype.dragHandler = function(event, ui)
|
||||
window.egw_fw_ui_splitter.prototype.dragHandler = function(event, ui)
|
||||
{
|
||||
/* var delta = 0;
|
||||
switch (this.orientation)
|
||||
@ -1351,7 +1355,7 @@ egw_fw_ui_splitter.prototype.dragHandler = function(event, ui)
|
||||
};
|
||||
|
||||
|
||||
egw_fw_ui_splitter.prototype.dragStopHandler = function(event, ui)
|
||||
window.egw_fw_ui_splitter.prototype.dragStopHandler = function(event, ui)
|
||||
{
|
||||
var delta = 0;
|
||||
switch (this.orientation)
|
||||
@ -1377,7 +1381,7 @@ egw_fw_ui_splitter.prototype.dragStopHandler = function(event, ui)
|
||||
* Disable/Enable drabbale splitter
|
||||
* @param {type} _state
|
||||
*/
|
||||
egw_fw_ui_splitter.prototype.set_disable = function (_state)
|
||||
window.egw_fw_ui_splitter.prototype.set_disable = function (_state)
|
||||
{
|
||||
jQuery(this.splitterDiv).draggable(_state?'disable':'enable');
|
||||
};
|
||||
@ -1390,7 +1394,7 @@ egw_fw_ui_splitter.prototype.set_disable = function (_state)
|
||||
* @param {object} _callbackContext context of the toggleCallback
|
||||
* @returns {egw_fw_ui_toggleSidebar}
|
||||
*/
|
||||
function egw_fw_ui_toggleSidebar (_contentDiv, _toggleCallback, _callbackContext)
|
||||
window.egw_fw_ui_toggleSidebar = function(_contentDiv, _toggleCallback, _callbackContext)
|
||||
{
|
||||
var self = this;
|
||||
this.toggleCallback = _toggleCallback;
|
||||
@ -1416,7 +1420,7 @@ function egw_fw_ui_toggleSidebar (_contentDiv, _toggleCallback, _callbackContext
|
||||
* Toggle menu on/off
|
||||
* @param {object} _callbackContext context of the toggleCallback
|
||||
*/
|
||||
egw_fw_ui_toggleSidebar.prototype.onToggle = function(_callbackContext)
|
||||
window.egw_fw_ui_toggleSidebar.prototype.onToggle = function(_callbackContext)
|
||||
{
|
||||
if (typeof this.toggleAudio != 'undefined') this.toggleAudio[0].play();
|
||||
if (this.contDiv.hasClass('egw_fw_sidebar_toggleOn'))
|
||||
@ -1444,7 +1448,7 @@ egw_fw_ui_toggleSidebar.prototype.onToggle = function(_callbackContext)
|
||||
* @param {type} _toggleCallback callback function to handle toggle preference and resize
|
||||
* @param {type} _context context of callback function
|
||||
*/
|
||||
egw_fw_ui_toggleSidebar.prototype.set_toggle = function (_state, _toggleCallback, _context)
|
||||
window.egw_fw_ui_toggleSidebar.prototype.set_toggle = function (_state, _toggleCallback, _context)
|
||||
{
|
||||
this.contDiv.toggleClass('egw_fw_sidebar_toggleOn',_state === 'on'?true:false);
|
||||
_context.splitterUi.set_disable(_state === 'on'?true:false);
|
||||
|
@ -17,6 +17,7 @@
|
||||
* @description Adds a handler for a custom event 'taphold' that handles a
|
||||
* tap and hold on touch interfaces.
|
||||
*/
|
||||
import '../../../../vendor/bower-asset/jquery/dist/jquery.js';
|
||||
(function($) {
|
||||
var TAP_AND_HOLD_TRIGGER_TIMER = 600;
|
||||
var MAX_DISTANCE_ALLOWED_IN_TAP_AND_HOLD_EVENT = 40;
|
||||
|
2
api/js/jquery/jquery-ui-timepicker-addon.js
vendored
2
api/js/jquery/jquery-ui-timepicker-addon.js
vendored
@ -1,6 +1,8 @@
|
||||
/*! jQuery Timepicker Addon - v1.6.1 - 2015-11-14
|
||||
* http://trentrichardson.com/examples/timepicker
|
||||
* Copyright (c) 2015 Trent Richardson; Licensed MIT */
|
||||
import '../../../vendor/bower-asset/jquery/dist/jquery.js';
|
||||
import '../../../vendor/bower-asset/jquery-ui/jquery-ui.js';
|
||||
(function (factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery', 'jquery-ui'], factory);
|
||||
|
@ -12,5 +12,6 @@
|
||||
/*egw:uses
|
||||
/vendor/bower-asset/jquery/dist/jquery.js;
|
||||
*/
|
||||
import '../../../vendor/bower-asset/jquery/dist/jquery.js';
|
||||
|
||||
jQuery.noConflict();
|
@ -15,6 +15,7 @@
|
||||
egw_inheritance;
|
||||
/api/js/es6-promise.min.js;
|
||||
*/
|
||||
import './egw_inheritance.js';
|
||||
|
||||
/**
|
||||
* Object to collect instanciated appliction objects
|
||||
@ -28,7 +29,7 @@
|
||||
*
|
||||
* @type object
|
||||
*/
|
||||
app = {classes: {}};
|
||||
window.app = {classes: {}};
|
||||
|
||||
/**
|
||||
* Common base class for application javascript
|
||||
|
@ -4,10 +4,9 @@
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package etemplate
|
||||
* @subpackage api
|
||||
* @link http://www.egroupware.org
|
||||
* @link https://www.egroupware.org
|
||||
* @author Andreas Stöckel (as AT stylite.de)
|
||||
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/*egw:uses
|
||||
@ -165,8 +164,40 @@
|
||||
window.focus();
|
||||
}
|
||||
|
||||
window.egw_LAB = $LAB.setOptions({AlwaysPreserveOrder:true,BasePath:window.egw_webserverUrl+'/'});
|
||||
window.egw_LAB.script(include).wait(function()
|
||||
/**
|
||||
* Import JavaScript legacy code: global scope, non-strict and executed in order
|
||||
*
|
||||
* @param String|Array _src
|
||||
* @param String|undefined _baseurl
|
||||
* @return {Promise<Promise<unknown>[]>}
|
||||
*/
|
||||
async function legacy_js_import(_src, _baseurl)
|
||||
{
|
||||
if (!Array.isArray(_src)) _src = [].concat(_src);
|
||||
return Promise.all(_src.map(src => {
|
||||
return new Promise(function(_resolve, _reject)
|
||||
{
|
||||
const script = document.createElement('script');
|
||||
script.src = (_baseurl ? _baseurl+'/' : '')+src;
|
||||
script.async = _src.length === 1;
|
||||
script.onload = _resolve;
|
||||
script.onerror = _reject;
|
||||
document.head.appendChild(script);
|
||||
})
|
||||
// catch and display, but not stop execution
|
||||
.catch((err) => { alert(src+":\n\n"+err.message)});
|
||||
}));
|
||||
}
|
||||
|
||||
// split includes in legacy js and modules
|
||||
const legacy_regexp = /dhtmlx/;
|
||||
// make our promise global, as legacy code calls egw_LAB.wait which we assign to egw_ready.then
|
||||
window.egw_LAB = window.egw_ready = Promise.all(
|
||||
[legacy_js_import(include.filter((src) => src.match(legacy_regexp) !== null), window.egw_webserverUrl)]
|
||||
.concat(include.filter((src) => src.match(legacy_regexp) === null)
|
||||
.map(rel_src => import(window.egw_webserverUrl+'/'+rel_src)
|
||||
.catch((err) => { alert(rel_src+":\n\n"+err.message)})
|
||||
))).then(() =>
|
||||
{
|
||||
// We need to override the globalEval to mitigate potential execution of
|
||||
// script tag. This issue is relevant to jQuery 1.12.4, we need to check
|
||||
@ -252,7 +283,7 @@
|
||||
catch(e) {
|
||||
// ignore SecurityError exception if opener is different security context / cross-origin
|
||||
}
|
||||
// instanciate app object
|
||||
// instantiate app object
|
||||
var appname = window.egw_appName;
|
||||
if (app && typeof app[appname] != 'object' && typeof app.classes[appname] == 'function')
|
||||
{
|
||||
@ -444,7 +475,9 @@
|
||||
// ignore SecurityError exception if top is different security context / cross-origin
|
||||
}
|
||||
});
|
||||
});
|
||||
}, (e) => alert(e.message+"\n\n"+e.stack));
|
||||
//
|
||||
window.egw_LAB.wait = window.egw_ready.then;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -459,7 +492,7 @@
|
||||
})();
|
||||
|
||||
// get TypeScript modules working with our loader
|
||||
function require(_file)
|
||||
window.require = function(_file)
|
||||
{
|
||||
switch(_file)
|
||||
{
|
||||
@ -468,7 +501,7 @@ function require(_file)
|
||||
}
|
||||
return window.exports;
|
||||
}
|
||||
var exports = {};
|
||||
window.exports = {};
|
||||
|
||||
/**
|
||||
* Call a function specified by it's name (possibly dot separated, eg. "app.myapp.myfunc")
|
||||
@ -478,7 +511,7 @@ var exports = {};
|
||||
* @returns {Mixed|Promise}
|
||||
* @deprecated use egw.callFunc(_func, ...) or egw.applyFunc(_func, args)
|
||||
*/
|
||||
function et2_call(_func)
|
||||
window.et2_call = function(_func)
|
||||
{
|
||||
return egw.applyFunc(_func, [].slice.call(arguments, 1), window);
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
"use strict";
|
||||
/**
|
||||
* EGroupware clientside Application javascript base object
|
||||
*
|
||||
@ -10,16 +9,13 @@
|
||||
* @author Hadi Nategh <hn@groupware.org>
|
||||
* @author Nathan Gray <ng@groupware.org>
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EgwApp = void 0;
|
||||
require("jquery");
|
||||
require("jqueryui");
|
||||
require("../jsapi/egw_global");
|
||||
var etemplate2_1 = require("../etemplate/etemplate2");
|
||||
var et2_extension_nextmatch_1 = require("../etemplate/et2_extension_nextmatch");
|
||||
var et2_widget_dialog_1 = require("../etemplate/et2_widget_dialog");
|
||||
var et2_core_widget_1 = require("../etemplate/et2_core_widget");
|
||||
var et2_widget_favorites_1 = require("../etemplate/et2_widget_favorites");
|
||||
import 'jquery';
|
||||
import 'jqueryui';
|
||||
import { etemplate2 } from "../etemplate/etemplate2";
|
||||
import { et2_nextmatch } from "../etemplate/et2_extension_nextmatch";
|
||||
import { et2_dialog } from "../etemplate/et2_widget_dialog";
|
||||
import { et2_createWidget } from "../etemplate/et2_core_widget";
|
||||
import { et2_favorites } from "../etemplate/et2_widget_favorites";
|
||||
/**
|
||||
* Common base class for application javascript
|
||||
* Each app should extend as needed.
|
||||
@ -50,12 +46,12 @@ var et2_widget_favorites_1 = require("../etemplate/et2_widget_favorites");
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
var EgwApp = /** @class */ (function () {
|
||||
export class EgwApp {
|
||||
/**
|
||||
* Initialization and setup goes here, but the etemplate2 object
|
||||
* is not yet ready.
|
||||
*/
|
||||
function EgwApp(appname) {
|
||||
constructor(appname) {
|
||||
/**
|
||||
* PGP begin and end tags
|
||||
*/
|
||||
@ -97,18 +93,18 @@ var EgwApp = /** @class */ (function () {
|
||||
* Clean up any created objects & references
|
||||
* @param {object} _app local app object
|
||||
*/
|
||||
EgwApp.prototype.destroy = function (_app) {
|
||||
destroy(_app) {
|
||||
delete this.et2;
|
||||
if (this.sidebox)
|
||||
this.sidebox.off();
|
||||
delete this.sidebox;
|
||||
if (!_app)
|
||||
delete app[this.appname];
|
||||
var index = -1;
|
||||
let index = -1;
|
||||
if ((index = EgwApp._instances.indexOf(this)) >= 0) {
|
||||
EgwApp._instances.splice(index, 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This function is called when the etemplate2 object is loaded
|
||||
* and ready. If you must store a reference to the et2 object,
|
||||
@ -118,7 +114,7 @@ var EgwApp = /** @class */ (function () {
|
||||
* @param {etemplate2} et2
|
||||
* @param {string} name template name
|
||||
*/
|
||||
EgwApp.prototype.et2_ready = function (et2, name) {
|
||||
et2_ready(et2, name) {
|
||||
if (this.et2 !== null) {
|
||||
egw.debug('log', "Changed et2 object");
|
||||
}
|
||||
@ -129,7 +125,7 @@ var EgwApp = /** @class */ (function () {
|
||||
}
|
||||
// Highlights the favorite based on initial list state
|
||||
this.highlight_favorite();
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Observer method receives update notifications from all applications
|
||||
*
|
||||
@ -149,8 +145,8 @@ var EgwApp = /** @class */ (function () {
|
||||
* or null, if not triggered on server-side, which adds that info
|
||||
* @return {false|*} false to stop regular refresh, thought all observers are run
|
||||
*/
|
||||
EgwApp.prototype.observer = function (_msg, _app, _id, _type, _msg_type, _links) {
|
||||
};
|
||||
observer(_msg, _app, _id, _type, _msg_type, _links) {
|
||||
}
|
||||
/**
|
||||
* Handle a push notification about entry changes from the websocket
|
||||
*
|
||||
@ -169,7 +165,7 @@ var EgwApp = /** @class */ (function () {
|
||||
* @param {object|null} pushData.acl Extra data for determining relevance. eg: owner or responsible to decide if update is necessary
|
||||
* @param {number} pushData.account_id User that caused the notification
|
||||
*/
|
||||
EgwApp.prototype.push = function (pushData) {
|
||||
push(pushData) {
|
||||
var _a;
|
||||
// don't care about other apps data, reimplement if your app does care eg. calendar
|
||||
if (pushData.app !== this.appname)
|
||||
@ -191,7 +187,7 @@ var EgwApp = /** @class */ (function () {
|
||||
return;
|
||||
}
|
||||
// Nextmatch does the hard part of updating. Try to find one.
|
||||
var nm = (_a = this.et2) === null || _a === void 0 ? void 0 : _a.getDOMWidgetById('nm');
|
||||
let nm = (_a = this.et2) === null || _a === void 0 ? void 0 : _a.getDOMWidgetById('nm');
|
||||
if (!nm) {
|
||||
return;
|
||||
}
|
||||
@ -202,7 +198,7 @@ var EgwApp = /** @class */ (function () {
|
||||
}
|
||||
// Pass actual refresh on to just nextmatch
|
||||
nm.refresh(pushData.id, pushData.type);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Check grants to see if we can quickly tell if this entry is not for us
|
||||
*
|
||||
@ -214,31 +210,27 @@ var EgwApp = /** @class */ (function () {
|
||||
*
|
||||
* @return boolean Entry has ACL access
|
||||
*/
|
||||
EgwApp.prototype._push_grant_check = function (pushData, grant_fields, appname) {
|
||||
var grants = egw.grants(appname || this.appname);
|
||||
_push_grant_check(pushData, grant_fields, appname) {
|
||||
let grants = egw.grants(appname || this.appname);
|
||||
// No grants known
|
||||
if (!grants)
|
||||
return true;
|
||||
var _loop_1 = function (i) {
|
||||
var grant_field = pushData.acl[grant_fields[i]];
|
||||
// check user has a grant from owner or something
|
||||
for (let i = 0; i < grant_fields.length; i++) {
|
||||
let grant_field = pushData.acl[grant_fields[i]];
|
||||
if (["number", "string"].indexOf(typeof grant_field) >= 0 && grants[grant_field] !== 'undefined') {
|
||||
return { value: true };
|
||||
// ACL access
|
||||
return true;
|
||||
}
|
||||
else if (!Object.keys(grants).filter(function (grant_account) {
|
||||
return grant_field.indexOf(grant_account) >= 0 ||
|
||||
grant_field.indexOf(parseInt(grant_account)).length;
|
||||
})) {
|
||||
return { value: false };
|
||||
return false;
|
||||
}
|
||||
};
|
||||
// check user has a grant from owner or something
|
||||
for (var i = 0; i < grant_fields.length; i++) {
|
||||
var state_1 = _loop_1(i);
|
||||
if (typeof state_1 === "object")
|
||||
return state_1.value;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Check pushData.acl values against a list of fields to see if we care about this entry based on current nextmatch
|
||||
* filter values. This is not a definitive yes or no (the server will tell us when we ask), we just want to cheaply
|
||||
@ -248,59 +240,52 @@ var EgwApp = /** @class */ (function () {
|
||||
* @param filter_fields List of filter field names eg: [owner, cat_id]
|
||||
* @return boolean True if the nextmatch filters might include the entry, false if not
|
||||
*/
|
||||
EgwApp.prototype._push_field_filter = function (pushData, nm, filter_fields) {
|
||||
var filters = {};
|
||||
for (var i = 0; i < filter_fields.length; i++) {
|
||||
_push_field_filter(pushData, nm, filter_fields) {
|
||||
let filters = {};
|
||||
for (let i = 0; i < filter_fields.length; i++) {
|
||||
filters[filter_fields[i]] = {
|
||||
col: filter_fields[i],
|
||||
filter_values: []
|
||||
};
|
||||
}
|
||||
// Get current filter values
|
||||
var value = nm.getValue();
|
||||
let value = nm.getValue();
|
||||
if (!value || !value.col_filter)
|
||||
return false;
|
||||
for (var _i = 0, _a = Object.values(filters); _i < _a.length; _i++) {
|
||||
var field_filter = _a[_i];
|
||||
var val = value.col_filter[field_filter.col];
|
||||
for (let field_filter of Object.values(filters)) {
|
||||
let val = value.col_filter[field_filter.col];
|
||||
if (val && (typeof val == "string" && val.trim().length > 0 ||
|
||||
typeof val == "object" && !jQuery.isEmptyObject(val))) {
|
||||
field_filter.filter_values.push(val);
|
||||
}
|
||||
}
|
||||
var _loop_2 = function (field_filter) {
|
||||
// check filters against pushData.acl data
|
||||
for (let field_filter of Object.values(filters)) {
|
||||
// no filter set
|
||||
if (field_filter.filter_values.length == 0)
|
||||
return "continue";
|
||||
continue;
|
||||
// acl value is a scalar (not array) --> check contained in filter
|
||||
if (pushData.acl && typeof pushData.acl[field_filter.col] !== 'object') {
|
||||
if (field_filter.filter_values.indexOf(pushData.acl[field_filter.col]) < 0) {
|
||||
return { value: false };
|
||||
return false;
|
||||
}
|
||||
return "continue";
|
||||
continue;
|
||||
}
|
||||
// acl value is an array (eg. tr_assigned) --> check intersection with filter
|
||||
if (!field_filter.filter_values.filter(function (account) { return pushData.acl[field_filter.col].indexOf(account) >= 0; }).length) {
|
||||
return { value: false };
|
||||
if (!field_filter.filter_values.filter(account => pushData.acl[field_filter.col].indexOf(account) >= 0).length) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
// check filters against pushData.acl data
|
||||
for (var _b = 0, _c = Object.values(filters); _b < _c.length; _b++) {
|
||||
var field_filter = _c[_b];
|
||||
var state_2 = _loop_2(field_filter);
|
||||
if (typeof state_2 === "object")
|
||||
return state_2.value;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Get (possible) app-specific uid
|
||||
*
|
||||
* @param {object} pushData see push method for individual attributes
|
||||
*/
|
||||
EgwApp.prototype.uid = function (pushData) {
|
||||
uid(pushData) {
|
||||
return pushData.app + '::' + pushData.id;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Open an entry.
|
||||
*
|
||||
@ -310,12 +295,12 @@ var EgwApp = /** @class */ (function () {
|
||||
* @param _action
|
||||
* @param _senders
|
||||
*/
|
||||
EgwApp.prototype.open = function (_action, _senders) {
|
||||
open(_action, _senders) {
|
||||
var id_app = _senders[0].id.split('::');
|
||||
egw.open(id_app[1], this.appname);
|
||||
};
|
||||
EgwApp.prototype._do_action = function (action_id, selected) {
|
||||
};
|
||||
}
|
||||
_do_action(action_id, selected) {
|
||||
}
|
||||
/**
|
||||
* A generic method to action to server asynchronously
|
||||
*
|
||||
@ -327,7 +312,7 @@ var EgwApp = /** @class */ (function () {
|
||||
* @param {egwAction} _action
|
||||
* @param {egwActionObject[]} _elems
|
||||
*/
|
||||
EgwApp.prototype.action = function (_action, _elems) {
|
||||
action(_action, _elems) {
|
||||
// let user confirm select-all
|
||||
var select_all = _action.getManager().getActionById("select_all");
|
||||
var confirm_msg = (_elems.length > 1 || select_all && select_all.checked) &&
|
||||
@ -336,11 +321,11 @@ var EgwApp = /** @class */ (function () {
|
||||
if (typeof confirm_msg != 'undefined') {
|
||||
var that = this;
|
||||
var action_id = _action.id;
|
||||
et2_widget_dialog_1.et2_dialog.show_dialog(function (button_id, value) {
|
||||
if (button_id != et2_widget_dialog_1.et2_dialog.NO_BUTTON) {
|
||||
et2_dialog.show_dialog(function (button_id, value) {
|
||||
if (button_id != et2_dialog.NO_BUTTON) {
|
||||
that._do_action(action_id, _elems);
|
||||
}
|
||||
}, confirm_msg, egw.lang('Confirmation required'), null, et2_widget_dialog_1.et2_dialog.BUTTONS_YES_NO, et2_widget_dialog_1.et2_dialog.QUESTION_MESSAGE);
|
||||
}, confirm_msg, egw.lang('Confirmation required'), null, et2_dialog.BUTTONS_YES_NO, et2_dialog.QUESTION_MESSAGE);
|
||||
}
|
||||
else if (typeof this._do_action == 'function') {
|
||||
this._do_action(_action.id, _elems);
|
||||
@ -361,7 +346,7 @@ var EgwApp = /** @class */ (function () {
|
||||
nm.getInstanceManager().submit();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Set the application's state to the given state.
|
||||
*
|
||||
@ -376,7 +361,7 @@ var EgwApp = /** @class */ (function () {
|
||||
* @param {string} template template name to check, instead of trying all templates of current app
|
||||
* @return {boolean} false - Returns false to stop event propagation
|
||||
*/
|
||||
EgwApp.prototype.setState = function (state, template) {
|
||||
setState(state, template) {
|
||||
var _a;
|
||||
// State should be an object, not a string, but we'll parse
|
||||
if (typeof state == "string") {
|
||||
@ -397,7 +382,7 @@ var EgwApp = /** @class */ (function () {
|
||||
}
|
||||
// Try and find a nextmatch widget, and set its filters
|
||||
var nextmatched = false;
|
||||
var et2 = template ? etemplate2_1.etemplate2.getByTemplate(template) : etemplate2_1.etemplate2.getByApplication(this.appname);
|
||||
var et2 = template ? etemplate2.getByTemplate(template) : etemplate2.getByApplication(this.appname);
|
||||
for (var i = 0; i < et2.length; i++) {
|
||||
et2[i].widgetContainer.iterateOver(function (_widget) {
|
||||
// Firefox has trouble with spaces in search
|
||||
@ -417,7 +402,7 @@ var EgwApp = /** @class */ (function () {
|
||||
}
|
||||
_widget.applyFilters(state.state || state.filter || {});
|
||||
nextmatched = true;
|
||||
}, this, et2_extension_nextmatch_1.et2_nextmatch);
|
||||
}, this, et2_nextmatch);
|
||||
if (nextmatched)
|
||||
return false;
|
||||
}
|
||||
@ -434,7 +419,7 @@ var EgwApp = /** @class */ (function () {
|
||||
}
|
||||
egw.open_link(url, undefined, undefined, this.appname);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Retrieve the current state of the application for future restoration
|
||||
*
|
||||
@ -447,17 +432,17 @@ var EgwApp = /** @class */ (function () {
|
||||
*
|
||||
* @return {object} Application specific map representing the current state
|
||||
*/
|
||||
EgwApp.prototype.getState = function () {
|
||||
getState() {
|
||||
var state = {};
|
||||
// Try and find a nextmatch widget, and set its filters
|
||||
var et2 = etemplate2_1.etemplate2.getByApplication(this.appname);
|
||||
var et2 = etemplate2.getByApplication(this.appname);
|
||||
for (var i = 0; i < et2.length; i++) {
|
||||
et2[i].widgetContainer.iterateOver(function (_widget) {
|
||||
state = _widget.getValue();
|
||||
}, this, et2_extension_nextmatch_1.et2_nextmatch);
|
||||
}, this, et2_nextmatch);
|
||||
}
|
||||
return state;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Function to load selected row from nm into a template view
|
||||
*
|
||||
@ -466,7 +451,7 @@ var EgwApp = /** @class */ (function () {
|
||||
* @param {boolean} _noEdit defines whether to set edit button or not default is false
|
||||
* @param {function} et2_callback function to run after et2 is loaded
|
||||
*/
|
||||
EgwApp.prototype.viewEntry = function (_action, _senders, _noEdit, et2_callback) {
|
||||
viewEntry(_action, _senders, _noEdit, et2_callback) {
|
||||
//full id in nm
|
||||
var id = _senders[0].id;
|
||||
// flag for edit button
|
||||
@ -551,7 +536,7 @@ var EgwApp = /** @class */ (function () {
|
||||
'validation_errors': this.et2.getArrayMgr('validation_errors').data
|
||||
};
|
||||
// etemplate2 object for view
|
||||
this.et2_view = new etemplate2_1.etemplate2(this.viewTemplate[0], '');
|
||||
this.et2_view = new etemplate2(this.viewTemplate[0], '');
|
||||
framework.pushState('view');
|
||||
if (templateName) {
|
||||
this.et2_view.load(this.appname + '.' + templateName, templateURL, data, typeof et2_callback == 'function' ? et2_callback : function () { }, app);
|
||||
@ -559,13 +544,13 @@ var EgwApp = /** @class */ (function () {
|
||||
// define a global close function for view template
|
||||
// in order to be able to destroy view on action
|
||||
this.et2_view.close = destroy;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Initializes actions and handlers on sidebox (delete)
|
||||
*
|
||||
* @param {jQuery} sidebox jQuery of DOM node
|
||||
*/
|
||||
EgwApp.prototype._init_sidebox = function (sidebox) {
|
||||
_init_sidebox(sidebox) {
|
||||
// Initialize egw tutorial sidebox, but only for non-popups, as calendar edit app.js has this.et2 set to tutorial et2 object
|
||||
if (!this.egw.is_popup()) {
|
||||
var egw_fw = egw_getFramework();
|
||||
@ -638,7 +623,7 @@ var EgwApp = /** @class */ (function () {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Add a new favorite
|
||||
*
|
||||
@ -648,7 +633,7 @@ var EgwApp = /** @class */ (function () {
|
||||
*
|
||||
* @param {object} [state] State settings to be merged into the application state
|
||||
*/
|
||||
EgwApp.prototype.add_favorite = function (state) {
|
||||
add_favorite(state) {
|
||||
if (typeof this.favorite_popup == "undefined" || // Create popup if it's not defined yet
|
||||
(this.favorite_popup && typeof this.favorite_popup.group != "undefined"
|
||||
&& !this.favorite_popup.group.isAttached())) // recreate the favorite popup if the group selectbox is not attached (eg. after et2 submit)
|
||||
@ -704,30 +689,30 @@ var EgwApp = /** @class */ (function () {
|
||||
console.log(this);
|
||||
// Stop the normal bubbling if this is called on click
|
||||
return false;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Update favorite items in nm fav. menu
|
||||
*
|
||||
*/
|
||||
EgwApp.prototype._refresh_fav_nm = function () {
|
||||
_refresh_fav_nm() {
|
||||
var self = this;
|
||||
if (etemplate2_1.etemplate2 && etemplate2_1.etemplate2.getByApplication) {
|
||||
var et2 = etemplate2_1.etemplate2.getByApplication(self.appname);
|
||||
if (etemplate2 && etemplate2.getByApplication) {
|
||||
var et2 = etemplate2.getByApplication(self.appname);
|
||||
for (var i = 0; i < et2.length; i++) {
|
||||
et2[i].widgetContainer.iterateOver(function (_widget) {
|
||||
_widget.stored_filters = _widget.load_favorites(self.appname);
|
||||
_widget.init_filters(_widget);
|
||||
}, self, et2_widget_favorites_1.et2_favorites);
|
||||
}, self, et2_favorites);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error("_refresh_fav_nm():Either et2 is not ready/ not there yet. Make sure that etemplate2 is ready before call this method.");
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create the "Add new" popup dialog
|
||||
*/
|
||||
EgwApp.prototype._create_favorite_popup = function () {
|
||||
_create_favorite_popup() {
|
||||
var self = this;
|
||||
var favorite_prefix = 'favorite_';
|
||||
// Clear old, if existing
|
||||
@ -758,7 +743,7 @@ var EgwApp = /** @class */ (function () {
|
||||
var apps = egw().user('apps');
|
||||
var is_admin = (typeof apps['admin'] != "undefined");
|
||||
if (is_admin) {
|
||||
this.favorite_popup.group = et2_core_widget_1.et2_createWidget("select-account", {
|
||||
this.favorite_popup.group = et2_createWidget("select-account", {
|
||||
id: "favorite[group]",
|
||||
account_type: "groups",
|
||||
empty_label: "Groups",
|
||||
@ -855,14 +840,14 @@ var EgwApp = /** @class */ (function () {
|
||||
}
|
||||
}, this));
|
||||
return false;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Delete a favorite from the list and update preferences
|
||||
* Registered as a handler on the delete icons
|
||||
*
|
||||
* @param {jQuery.event} event event object
|
||||
*/
|
||||
EgwApp.prototype.delete_favorite = function (event) {
|
||||
delete_favorite(event) {
|
||||
// Don't do the menu
|
||||
event.stopImmediatePropagation();
|
||||
var app = event.data;
|
||||
@ -874,7 +859,7 @@ var EgwApp = /** @class */ (function () {
|
||||
line.addClass('loading');
|
||||
// Make sure first
|
||||
var do_delete = function (button_id) {
|
||||
if (button_id != et2_widget_dialog_1.et2_dialog.YES_BUTTON) {
|
||||
if (button_id != et2_dialog.YES_BUTTON) {
|
||||
line.removeClass('loading');
|
||||
return;
|
||||
}
|
||||
@ -897,16 +882,16 @@ var EgwApp = /** @class */ (function () {
|
||||
}, jQuery(trash).parentsUntil("li").parent(), true, jQuery(trash).parentsUntil("li").parent());
|
||||
request.sendRequest(true);
|
||||
};
|
||||
et2_widget_dialog_1.et2_dialog.show_dialog(do_delete, (egw.lang("Delete") + " " + name + "?"), egw.lang("Delete"), null, et2_widget_dialog_1.et2_dialog.BUTTONS_YES_NO, et2_widget_dialog_1.et2_dialog.QUESTION_MESSAGE);
|
||||
et2_dialog.show_dialog(do_delete, (egw.lang("Delete") + " " + name + "?"), egw.lang("Delete"), null, et2_dialog.BUTTONS_YES_NO, et2_dialog.QUESTION_MESSAGE);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Mark the favorite closest matching the current state
|
||||
*
|
||||
* Closest matching takes into account not set values, so we pick the favorite
|
||||
* with the most matching values without a value that differs.
|
||||
*/
|
||||
EgwApp.prototype.highlight_favorite = function () {
|
||||
highlight_favorite() {
|
||||
if (!this.sidebox)
|
||||
return;
|
||||
var state = this.getState();
|
||||
@ -992,11 +977,11 @@ var EgwApp = /** @class */ (function () {
|
||||
if (best_match) {
|
||||
jQuery('li[data-id="' + best_match + '"]', this.sidebox).addClass('ui-state-highlight');
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Fix scrolling iframe browsed by iPhone/iPod/iPad touch devices
|
||||
*/
|
||||
EgwApp.prototype._fix_iFrameScrolling = function () {
|
||||
_fix_iFrameScrolling() {
|
||||
if (/iPhone|iPod|iPad/.test(navigator.userAgent)) {
|
||||
jQuery("iframe").on({
|
||||
load: function () {
|
||||
@ -1014,24 +999,24 @@ var EgwApp = /** @class */ (function () {
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Set document title, uses getWindowTitle to get the correct title,
|
||||
* otherwise set it with uniqueID as default title
|
||||
*/
|
||||
EgwApp.prototype._set_Window_title = function () {
|
||||
_set_Window_title() {
|
||||
var title = this.getWindowTitle();
|
||||
if (title) {
|
||||
document.title = this.et2._inst.uniqueId + ": " + title;
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Window title getter function in order to set the window title
|
||||
* this can be overridden on each application app.js file to customize the title value
|
||||
*
|
||||
* @returns {string} window title
|
||||
*/
|
||||
EgwApp.prototype.getWindowTitle = function () {
|
||||
getWindowTitle() {
|
||||
var titleWidget = this.et2.getWidgetById('title');
|
||||
if (titleWidget) {
|
||||
return titleWidget.options.value;
|
||||
@ -1039,7 +1024,7 @@ var EgwApp = /** @class */ (function () {
|
||||
else {
|
||||
return this.et2._inst.uniqueId;
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Handler for drag and drop when dragging nextmatch rows from mail app
|
||||
* and dropped on a row in the current application. We copy the mail into
|
||||
@ -1062,7 +1047,7 @@ var EgwApp = /** @class */ (function () {
|
||||
* @param {egwActionObject[]} _selected Dragged mail rows
|
||||
* @param {egwActionObject} _target Current application's nextmatch row the mail was dropped on
|
||||
*/
|
||||
EgwApp.prototype.handle_dropped_mail = function (_action, _selected, _target) {
|
||||
handle_dropped_mail(_action, _selected, _target) {
|
||||
/**
|
||||
* Mail doesn't support link system, so we copy it to VFS
|
||||
*/
|
||||
@ -1081,13 +1066,13 @@ var EgwApp = /** @class */ (function () {
|
||||
egw.refresh(data.msg || '', ids[0], ids[1], 'update');
|
||||
}).sendRequest(true);
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Get json data for videos from the given url
|
||||
*
|
||||
* @return {Promise, object} return Promise, json object as resolved result and error message in case of failure
|
||||
*/
|
||||
EgwApp.prototype.egwTutorialGetData = function () {
|
||||
egwTutorialGetData() {
|
||||
var self = this;
|
||||
return new Promise(function (_resolve, _reject) {
|
||||
var resolve = _resolve;
|
||||
@ -1099,7 +1084,7 @@ var EgwApp = /** @class */ (function () {
|
||||
}).sendRequest();
|
||||
}, 0);
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create and Render etemplate2 for egroupware tutorial
|
||||
* sidebox option. The .xet file is stored in api/templates/default/egw_tutorials
|
||||
@ -1132,9 +1117,9 @@ var EgwApp = /** @class */ (function () {
|
||||
*
|
||||
* @param {DOMNode} div
|
||||
*/
|
||||
EgwApp.prototype.egwTutorial_init = function (div) {
|
||||
egwTutorial_init(div) {
|
||||
// et2 object
|
||||
var etemplate = new etemplate2_1.etemplate2(div, '');
|
||||
var etemplate = new etemplate2(div, '');
|
||||
var template = egw.webserverUrl + '/api/templates/default/egw_tutorial.xet?1';
|
||||
this.egwTutorialGetData().then(function (_data) {
|
||||
var lang = egw.preference('lang');
|
||||
@ -1160,27 +1145,27 @@ var EgwApp = /** @class */ (function () {
|
||||
}, function (_err) {
|
||||
console.log(_err);
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Open popup to show given tutorial id
|
||||
* @param {string} _tuid tutorial object id
|
||||
* - tuid: appname-lang-index
|
||||
*/
|
||||
EgwApp.prototype.egwTutorialPopup = function (_tuid) {
|
||||
egwTutorialPopup(_tuid) {
|
||||
var url = egw.link('/index.php', 'menuaction=api.EGroupware\\Api\\Framework\\Tutorial.popup&tuid=' + _tuid);
|
||||
egw.open_link(url, '_blank', '960x580');
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Function to set video iframe base on selected tutorial from tutorials box
|
||||
*
|
||||
* @param {string} _url
|
||||
*/
|
||||
EgwApp.prototype.tutorial_videoOnClick = function (_url) {
|
||||
var frame = etemplate2_1.etemplate2.getByApplication('api')[0].widgetContainer.getWidgetById('src');
|
||||
tutorial_videoOnClick(_url) {
|
||||
var frame = etemplate2.getByApplication('api')[0].widgetContainer.getWidgetById('src');
|
||||
if (frame) {
|
||||
frame.set_value(_url);
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Function calls on discard checkbox and will set
|
||||
* the egw_tutorial_noautoload preference
|
||||
@ -1188,17 +1173,17 @@ var EgwApp = /** @class */ (function () {
|
||||
* @param {type} egw
|
||||
* @param {type} widget
|
||||
*/
|
||||
EgwApp.prototype.tutorial_autoloadDiscard = function (egw, widget) {
|
||||
tutorial_autoloadDiscard(egw, widget) {
|
||||
if (widget) {
|
||||
this.egw.set_preference('common', 'egw_tutorial_noautoload', widget.get_value());
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Check if Mailvelope is available, open (or create) "egroupware" keyring and call callback with it
|
||||
*
|
||||
* @param {function} _callback called if and only if mailvelope is available (context is this!)
|
||||
*/
|
||||
EgwApp.prototype.mailvelopeAvailable = function (_callback) {
|
||||
mailvelopeAvailable(_callback) {
|
||||
var self = this;
|
||||
var callback = jQuery.proxy(_callback, this);
|
||||
if (typeof mailvelope !== 'undefined') {
|
||||
@ -1209,7 +1194,7 @@ var EgwApp = /** @class */ (function () {
|
||||
self.mailvelopeOpenKeyring().then(callback);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* mailvelope object contains SyncHandlers
|
||||
*
|
||||
@ -1218,7 +1203,7 @@ var EgwApp = /** @class */ (function () {
|
||||
* @property {function} backup function called by Mailvelope to upload a public keyring backup
|
||||
* @property {function} restore function called by Mailvelope to restore a public keyring backup
|
||||
*/
|
||||
EgwApp.prototype.mailvelopeSyncHandler = function () {
|
||||
mailvelopeSyncHandler() {
|
||||
return {
|
||||
/**
|
||||
* function called by Mailvelope to upload a public keyring
|
||||
@ -1304,7 +1289,7 @@ var EgwApp = /** @class */ (function () {
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Function for backup file operations
|
||||
*
|
||||
@ -1318,7 +1303,7 @@ var EgwApp = /** @class */ (function () {
|
||||
* @param {type} _errorCallback function called when the operation fails
|
||||
* @param {type} _data data which needs to be stored in file via PUT command
|
||||
*/
|
||||
EgwApp.prototype._mailvelopeBackupFileOperator = function (_url, _cmd, _successCallback, _errorCallback, _data) {
|
||||
_mailvelopeBackupFileOperator(_url, _cmd, _successCallback, _errorCallback, _data) {
|
||||
var ajaxObj = {
|
||||
url: _url || egw.webserverUrl + '/webdav.php/home/' + egw.user('account_lid') + '/.PGP-Key-Backup',
|
||||
method: _cmd,
|
||||
@ -1341,7 +1326,7 @@ var EgwApp = /** @class */ (function () {
|
||||
break;
|
||||
}
|
||||
jQuery.ajax(ajaxObj);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create backup dialog
|
||||
* @param {string} _selector DOM selector to attach backupDialog
|
||||
@ -1349,7 +1334,7 @@ var EgwApp = /** @class */ (function () {
|
||||
*
|
||||
* @returns {Promise.<backupPopupId, Error>}
|
||||
*/
|
||||
EgwApp.prototype.mailvelopeCreateBackupDialog = function (_selector, _initSetup) {
|
||||
mailvelopeCreateBackupDialog(_selector, _initSetup) {
|
||||
var self = this;
|
||||
var selector = _selector || 'body';
|
||||
var initSetup = _initSetup;
|
||||
@ -1377,22 +1362,22 @@ var EgwApp = /** @class */ (function () {
|
||||
reject(_err);
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Delete backup key from filesystem
|
||||
*/
|
||||
EgwApp.prototype.mailvelopeDeleteBackup = function () {
|
||||
mailvelopeDeleteBackup() {
|
||||
var self = this;
|
||||
et2_widget_dialog_1.et2_dialog.show_dialog(function (_button_id) {
|
||||
if (_button_id == et2_widget_dialog_1.et2_dialog.YES_BUTTON) {
|
||||
et2_dialog.show_dialog(function (_button_id) {
|
||||
if (_button_id == et2_dialog.YES_BUTTON) {
|
||||
self._mailvelopeBackupFileOperator(undefined, 'DELETE', function () {
|
||||
self.egw.message(self.egw.lang('The backup key has been deleted.'));
|
||||
}, function (_err) {
|
||||
self.egw.message(self.egw.lang('Was not able to delete the backup key because %1', _err));
|
||||
});
|
||||
}
|
||||
}, self.egw.lang('Are you sure, you would like to delete the backup key?'), self.egw.lang('Delete backup key'), {}, et2_widget_dialog_1.et2_dialog.BUTTONS_YES_NO_CANCEL, et2_widget_dialog_1.et2_dialog.QUESTION_MESSAGE, undefined, self.egw);
|
||||
};
|
||||
}, self.egw.lang('Are you sure, you would like to delete the backup key?'), self.egw.lang('Delete backup key'), {}, et2_dialog.BUTTONS_YES_NO_CANCEL, et2_dialog.QUESTION_MESSAGE, undefined, self.egw);
|
||||
}
|
||||
/**
|
||||
* Create mailvelope restore dialog
|
||||
* @param {string} _selector DOM selector to attach restorDialog
|
||||
@ -1400,7 +1385,7 @@ var EgwApp = /** @class */ (function () {
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
EgwApp.prototype.mailvelopeCreateRestoreDialog = function (_selector, _restorePassword) {
|
||||
mailvelopeCreateRestoreDialog(_selector, _restorePassword) {
|
||||
var self = this;
|
||||
var restorePassword = _restorePassword;
|
||||
var selector = _selector || 'body';
|
||||
@ -1425,13 +1410,13 @@ var EgwApp = /** @class */ (function () {
|
||||
reject(_err);
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create a dialog to show all backup/restore options
|
||||
*
|
||||
* @returns {undefined}
|
||||
*/
|
||||
EgwApp.prototype.mailvelopeCreateBackupRestoreDialog = function () {
|
||||
mailvelopeCreateBackupRestoreDialog() {
|
||||
var self = this;
|
||||
var appname = egw.app_name();
|
||||
var menu = [
|
||||
@ -1447,7 +1432,7 @@ var EgwApp = /** @class */ (function () {
|
||||
{ label: "Backup Key", image: "save", onclick: "app." + appname + ".mailvelopeCreateBackupDialog('#_mvelo', false)" }
|
||||
];
|
||||
var dialog = function (_content, _callback) {
|
||||
return et2_core_widget_1.et2_createWidget("dialog", {
|
||||
return et2_createWidget("dialog", {
|
||||
callback: function (_button_id, _value) {
|
||||
if (typeof _callback == "function") {
|
||||
_callback.call(this, _button_id, _value.value);
|
||||
@ -1482,18 +1467,18 @@ var EgwApp = /** @class */ (function () {
|
||||
else {
|
||||
this.mailvelopeInstallationOffer();
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create a dialog and offers installation option for installing mailvelope plugin
|
||||
* plus it offers a video tutorials to get the user morte familiar with mailvelope
|
||||
*/
|
||||
EgwApp.prototype.mailvelopeInstallationOffer = function () {
|
||||
mailvelopeInstallationOffer() {
|
||||
var buttons = [
|
||||
{ "text": egw.lang('Install'), id: 'install', image: 'check', "default": true },
|
||||
{ "text": egw.lang('Close'), id: 'close', image: 'cancelled' }
|
||||
];
|
||||
var dialog = function (_content, _callback) {
|
||||
return et2_core_widget_1.et2_createWidget("dialog", {
|
||||
return et2_createWidget("dialog", {
|
||||
callback: function (_button_id, _value) {
|
||||
if (typeof _callback == "function") {
|
||||
_callback.call(this, _button_id, _value.value);
|
||||
@ -1528,23 +1513,23 @@ var EgwApp = /** @class */ (function () {
|
||||
else if (typeof InstallTrigger != 'undefined' && InstallTrigger.enabled()) {
|
||||
InstallTrigger.install({ mailvelope: "https://download.mailvelope.com/releases/latest/mailvelope.firefox.xpi" }, function (_url, _status) {
|
||||
if (_status == 0) {
|
||||
et2_widget_dialog_1.et2_dialog.alert(egw.lang('Mailvelope addon installation succeded. Now you may configure the options.'));
|
||||
et2_dialog.alert(egw.lang('Mailvelope addon installation succeded. Now you may configure the options.'));
|
||||
return;
|
||||
}
|
||||
else {
|
||||
et2_widget_dialog_1.et2_dialog.alert(egw.lang('Mailvelope addon installation failed! Please try again.'));
|
||||
et2_dialog.alert(egw.lang('Mailvelope addon installation failed! Please try again.'));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Open (or create) "egroupware" keyring and call callback with it
|
||||
*
|
||||
* @returns {Promise.<Keyring, Error>} Keyring or Error with message
|
||||
*/
|
||||
EgwApp.prototype.mailvelopeOpenKeyring = function () {
|
||||
mailvelopeOpenKeyring() {
|
||||
var self = this;
|
||||
return new Promise(function (_resolve, _reject) {
|
||||
if (self.mailvelope_keyring)
|
||||
@ -1595,16 +1580,16 @@ var EgwApp = /** @class */ (function () {
|
||||
});
|
||||
delete buttons[1].default;
|
||||
}
|
||||
et2_widget_dialog_1.et2_dialog.show_dialog(function (_button_id) {
|
||||
if (_button_id != et2_widget_dialog_1.et2_dialog.NO_BUTTON) {
|
||||
et2_dialog.show_dialog(function (_button_id) {
|
||||
if (_button_id != et2_dialog.NO_BUTTON) {
|
||||
var keys = {};
|
||||
keys[self.egw.user('account_id')] = _pubKey;
|
||||
self.egw.json('addressbook.addressbook_bo.ajax_set_pgp_keys', [keys, _button_id != et2_widget_dialog_1.et2_dialog.YES_BUTTON ? true : undefined]).sendRequest()
|
||||
self.egw.json('addressbook.addressbook_bo.ajax_set_pgp_keys', [keys, _button_id != et2_dialog.YES_BUTTON ? true : undefined]).sendRequest()
|
||||
.then(function (_data) {
|
||||
self.egw.message(_data.response['0'].data);
|
||||
});
|
||||
}
|
||||
}, self.egw.lang('It is recommended to store your public key in addressbook, so other users can write you encrypted mails.'), self.egw.lang('Store your public key in Addressbook?'), {}, buttons, et2_widget_dialog_1.et2_dialog.QUESTION_MESSAGE, undefined, self.egw);
|
||||
}, self.egw.lang('It is recommended to store your public key in addressbook, so other users can write you encrypted mails.'), self.egw.lang('Store your public key in Addressbook?'), {}, buttons, et2_dialog.QUESTION_MESSAGE, undefined, self.egw);
|
||||
}, function (_err) {
|
||||
self.egw.message(_err.message + "\n\n" +
|
||||
self.egw.lang("You will NOT be able to send or receive encrypted mails before completing that step!"), 'error');
|
||||
@ -1618,25 +1603,25 @@ var EgwApp = /** @class */ (function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Mailvelope uses Domain without first part: eg. "stylite.de" for "egw.stylite.de"
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
EgwApp.prototype._mailvelopeDomain = function () {
|
||||
_mailvelopeDomain() {
|
||||
var parts = document.location.hostname.split('.');
|
||||
if (parts.length > 1)
|
||||
parts.shift();
|
||||
return parts.join('.');
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Check if we have a key for all recipients
|
||||
*
|
||||
* @param {Array} _recipients
|
||||
* @returns {Promise.<Array, Error>} Array of recipients or Error with recipients without key
|
||||
*/
|
||||
EgwApp.prototype.mailvelopeGetCheckRecipients = function (_recipients) {
|
||||
mailvelopeGetCheckRecipients(_recipients) {
|
||||
// replace rfc822 addresses with raw email, as Mailvelop does not like them and lowercase all email
|
||||
var rfc822_preg = /<([^'" <>]+)>$/;
|
||||
var recipients = _recipients.map(function (_recipient) {
|
||||
@ -1686,7 +1671,7 @@ var EgwApp = /** @class */ (function () {
|
||||
reject(_err);
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Check if the share action is enabled for this entry
|
||||
*
|
||||
@ -1695,9 +1680,9 @@ var EgwApp = /** @class */ (function () {
|
||||
* @param {egwActionObject} _target
|
||||
* @returns {boolean} if action is enabled
|
||||
*/
|
||||
EgwApp.prototype.is_share_enabled = function (_action, _entries, _target) {
|
||||
is_share_enabled(_action, _entries, _target) {
|
||||
return true;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* create a share-link for the given entry
|
||||
*
|
||||
@ -1710,7 +1695,7 @@ var EgwApp = /** @class */ (function () {
|
||||
* @param {Object} _extra Additional (app-specific or special) parameters
|
||||
* @returns {Boolean} returns false if not successful
|
||||
*/
|
||||
EgwApp.prototype.share_link = function (_action, _senders, _target, _writable, _files, _callback, _extra) {
|
||||
share_link(_action, _senders, _target, _writable, _files, _callback, _extra) {
|
||||
var path = _senders[0].id;
|
||||
if (!path) {
|
||||
return this.egw.message(this.egw.lang('Missing share path. Unable to create share.'), 'error');
|
||||
@ -1731,8 +1716,8 @@ var EgwApp = /** @class */ (function () {
|
||||
_extra = {};
|
||||
}
|
||||
return egw.json('EGroupware\\Api\\Sharing::ajax_create', [_action.id, path, _writable, _files, _extra], _callback ? _callback : this._share_link_callback, this, true, this).sendRequest();
|
||||
};
|
||||
EgwApp.prototype.share_merge = function (_action, _senders, _target) {
|
||||
}
|
||||
share_merge(_action, _senders, _target) {
|
||||
var parent = _action.parent.parent;
|
||||
var _writable = false;
|
||||
var _files = false;
|
||||
@ -1755,12 +1740,12 @@ var EgwApp = /** @class */ (function () {
|
||||
// Process document after all shares created
|
||||
return nm_action(_action, _senders, _target);
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Share-link callback
|
||||
* @param {object} _data
|
||||
*/
|
||||
EgwApp.prototype._share_link_callback = function (_data) {
|
||||
_share_link_callback(_data) {
|
||||
if (_data.msg || _data.share_link)
|
||||
window.egw_refresh(_data.msg, this.appname);
|
||||
var copy_link_to_clipboard = function (evt) {
|
||||
@ -1777,7 +1762,7 @@ var EgwApp = /** @class */ (function () {
|
||||
egw.message('Failed to copy the link!');
|
||||
};
|
||||
jQuery("body").on("click", "[name=share_link]", copy_link_to_clipboard);
|
||||
et2_core_widget_1.et2_createWidget("dialog", {
|
||||
et2_createWidget("dialog", {
|
||||
callback: function (button_id, value) {
|
||||
jQuery("body").off("click", "[name=share_link]", copy_link_to_clipboard);
|
||||
return true;
|
||||
@ -1787,7 +1772,7 @@ var EgwApp = /** @class */ (function () {
|
||||
width: 450,
|
||||
value: { content: { "share_link": _data.share_link } }
|
||||
});
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Keep a list of all EgwApp instances
|
||||
*
|
||||
@ -1796,27 +1781,25 @@ var EgwApp = /** @class */ (function () {
|
||||
* @private
|
||||
* @param app_obj
|
||||
*/
|
||||
EgwApp._register_instance = function (app_obj) {
|
||||
static _register_instance(app_obj) {
|
||||
// Reject improper objects
|
||||
if (!app_obj.appname)
|
||||
return;
|
||||
EgwApp._instances.push(app_obj);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Iterator over all app instances
|
||||
*
|
||||
* Use for(const app of EgwApp) {...} to iterate over all app objects.
|
||||
*/
|
||||
EgwApp[Symbol.iterator] = function () {
|
||||
static [Symbol.iterator]() {
|
||||
return EgwApp._instances[Symbol.iterator]();
|
||||
};
|
||||
/**
|
||||
}
|
||||
}
|
||||
/**
|
||||
* In some cases (CRM) a private, disconnected app instance is created instead of
|
||||
* using the global. We want to be able to access them for observer() & push(), so
|
||||
* we track all instances.
|
||||
*/
|
||||
EgwApp._instances = [];
|
||||
return EgwApp;
|
||||
}());
|
||||
exports.EgwApp = EgwApp;
|
||||
EgwApp._instances = [];
|
||||
//# sourceMappingURL=egw_app.js.map
|
@ -19,6 +19,7 @@
|
||||
// egw_jquery;
|
||||
egw_css;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
/**
|
||||
* Date and timepicker
|
||||
|
@ -13,6 +13,7 @@
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
egw.extend('config', egw.MODULE_GLOBAL, function()
|
||||
{
|
||||
|
@ -13,6 +13,7 @@
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
/**
|
||||
* Module which allows to add stylesheet rules at runtime. Exports the following
|
||||
|
@ -14,6 +14,8 @@
|
||||
egw_core;
|
||||
egw_debug;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
import './egw_json.js'; // for egw.registerJSONPlugin
|
||||
|
||||
/**
|
||||
* Module storing and updating row data
|
||||
|
@ -13,6 +13,7 @@
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
/**
|
||||
* Log debug messages to browser console and persistent html5 localStorage
|
||||
|
@ -15,6 +15,7 @@
|
||||
egw_ready;
|
||||
egw_debug;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
/**
|
||||
* @augments Class
|
||||
@ -146,17 +147,19 @@ egw.extend('files', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
* @param {function} _callback called after JS files are loaded and executed
|
||||
* @param {object} _context
|
||||
* @param {string} _prefix prefix for _jsFiles
|
||||
* @return Promise
|
||||
*/
|
||||
includeJS: function(_jsFiles, _callback, _context, _prefix)
|
||||
{
|
||||
// use egw_LAB object of correct window, not always the main window
|
||||
var egw_LAB = (this.window || window).egw_LAB;
|
||||
|
||||
// Also allow including a single javascript file
|
||||
if (typeof _jsFiles === 'string')
|
||||
{
|
||||
_jsFiles = [_jsFiles];
|
||||
}
|
||||
const promise = import(_prefix ? _jsFiles.map((src) => _prefix+src) : _jsFiles);
|
||||
return typeof _callback === 'undefined' ? promise : promise.then(_callback.call(_context));
|
||||
|
||||
// @todo check the prefix stuff
|
||||
// LABjs uses prefix only if url is not absolute, so removing leading / if necessary and add it to prefix
|
||||
if (_prefix)
|
||||
{
|
||||
|
@ -13,6 +13,7 @@
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
egw.extend('images', egw.MODULE_GLOBAL, function()
|
||||
{
|
||||
|
@ -14,6 +14,7 @@
|
||||
egw_files;
|
||||
egw_ready;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
/**
|
||||
* NOT USED
|
||||
|
@ -17,6 +17,8 @@
|
||||
egw_files;
|
||||
egw_debug;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
import './egw_utils.js';
|
||||
|
||||
/**
|
||||
* Module sending json requests
|
||||
@ -57,7 +59,7 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
* @param {object} _sender
|
||||
* @param {egw} _egw
|
||||
*/
|
||||
function json_request(_menuaction, _parameters, _callback, _context,
|
||||
window.json_request = function(_menuaction, _parameters, _callback, _context,
|
||||
_async, _sender, _egw)
|
||||
{
|
||||
// Copy the parameters
|
||||
@ -103,7 +105,7 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
* @param {function} error option error callback(_msg) used instead our default this.error
|
||||
* @param {int} reconnect timeout in ms (internal)
|
||||
*/
|
||||
json_request.prototype.openWebSocket = function(url, tokens, account_id, error, reconnect)
|
||||
window.json_request.prototype.openWebSocket = function(url, tokens, account_id, error, reconnect)
|
||||
{
|
||||
const min_reconnect_time = 1000;
|
||||
const max_reconnect_time = 300000;
|
||||
@ -191,7 +193,7 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
*
|
||||
* @return {jqXHR|boolean} jQuery jqXHR request object or for async==="keepalive" boolean is returned
|
||||
*/
|
||||
json_request.prototype.sendRequest = function(async, method, error)
|
||||
window.json_request.prototype.sendRequest = function(async, method, error)
|
||||
{
|
||||
if(typeof async != "undefined")
|
||||
{
|
||||
@ -242,7 +244,7 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
* @param {XMLHTTP} _xmlhttp
|
||||
* @param {string} _err
|
||||
*/
|
||||
json_request.prototype.handleError = function(_xmlhttp, _err) {
|
||||
window.json_request.prototype.handleError = function(_xmlhttp, _err) {
|
||||
// Don't error about an abort
|
||||
if(_err !== 'abort')
|
||||
{
|
||||
@ -269,7 +271,7 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
||||
}
|
||||
};
|
||||
|
||||
json_request.prototype.handleResponse = function(data) {
|
||||
window.json_request.prototype.handleResponse = function(data) {
|
||||
if (data && typeof data.response != 'undefined')
|
||||
{
|
||||
if (egw.preference('show_generation_time', 'common', false) == "1")
|
||||
|
@ -14,6 +14,7 @@
|
||||
egw_core;
|
||||
egw_debug;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
egw.extend('jsonq', egw.MODULE_GLOBAL, function()
|
||||
{
|
||||
|
@ -15,6 +15,7 @@
|
||||
egw_files;
|
||||
egw_ready;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
/**
|
||||
* @augments Class
|
||||
|
@ -13,6 +13,7 @@
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
/**
|
||||
* @augments Class
|
||||
|
@ -12,6 +12,8 @@
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
import './egw_json.js'; // for registerJSONPlugin
|
||||
|
||||
/**
|
||||
* Methods to display a success or error message and the app-header
|
||||
|
@ -12,6 +12,7 @@
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
/**
|
||||
* Methods to display browser notification
|
||||
|
@ -14,6 +14,7 @@
|
||||
egw_core;
|
||||
egw_links;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
/**
|
||||
* @augments Class
|
||||
|
@ -13,6 +13,7 @@
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
egw.extend('preferences', egw.MODULE_GLOBAL, function()
|
||||
{
|
||||
|
@ -14,6 +14,7 @@
|
||||
egw_utils;
|
||||
egw_debug;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
/**
|
||||
* @augments Class
|
||||
|
@ -14,6 +14,7 @@
|
||||
egw_ready;
|
||||
egw_debug;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
/**
|
||||
* Store is a wrapper around browser based, persistant storage.
|
||||
|
@ -10,6 +10,8 @@
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
import '../../../vendor/bower-asset/jquery/dist/jquery.js';
|
||||
import './egw_json.js';
|
||||
|
||||
jQuery(function()
|
||||
{
|
||||
@ -73,7 +75,7 @@ jQuery(function()
|
||||
jQuery('input[id^="empty_log"]').on('click',function(){
|
||||
button_log(this.getAttribute('id'));
|
||||
});
|
||||
egw_LAB.wait(function() {
|
||||
//egw_LAB.wait(function() {
|
||||
jQuery(document).ready(function()
|
||||
{
|
||||
if (typeof filename !='undefined' && filename.length > 0)
|
||||
@ -83,5 +85,5 @@ jQuery(function()
|
||||
}
|
||||
});
|
||||
jQuery(window).resize(resize_log);
|
||||
});
|
||||
//});
|
||||
});
|
||||
|
@ -14,6 +14,7 @@
|
||||
vendor.bower-asset.jquery.dist.jquery;
|
||||
egw_core;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -13,6 +13,7 @@
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
egw.extend('user', egw.MODULE_GLOBAL, function()
|
||||
{
|
||||
|
@ -12,6 +12,7 @@
|
||||
/*egw:uses
|
||||
egw_core;
|
||||
*/
|
||||
import './egw_core.js';
|
||||
|
||||
egw.extend('utils', egw.MODULE_GLOBAL, function()
|
||||
{
|
||||
|
@ -11,35 +11,9 @@
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/***********************************************\
|
||||
* INITIALIZATION *
|
||||
\***********************************************/
|
||||
if (document.all)
|
||||
{
|
||||
navigator.userAgent.toLowerCase().indexOf('msie 5') != -1 ? is_ie5 = true : is_ie5 = false;
|
||||
is_ie = true;
|
||||
is_moz1_6 = false;
|
||||
is_mozilla = false;
|
||||
is_ns4 = false;
|
||||
}
|
||||
else if (document.getElementById)
|
||||
{
|
||||
navigator.userAgent.toLowerCase().match('mozilla.*rv[:]1\.6.*gecko') ? is_moz1_6 = true : is_moz1_6 = false;
|
||||
is_ie = false;
|
||||
is_ie5 = false;
|
||||
is_mozilla = true;
|
||||
is_ns4 = false;
|
||||
}
|
||||
else if (document.layers)
|
||||
{
|
||||
is_ie = false;
|
||||
is_ie5 = false;
|
||||
is_moz1_6 = false;
|
||||
is_mozilla = false;
|
||||
is_ns4 = true;
|
||||
}
|
||||
'use strict';
|
||||
|
||||
//console.log('is_ie='+is_ie+', is_ie5='+is_ie5+', is_mozilla='+is_mozilla+', is_moz1_6='+is_moz1_6+', is_ns4='+is_ns4);
|
||||
import '../../../vendor/bower-asset/jquery/dist/jquery.js';
|
||||
|
||||
/**
|
||||
* Check whether the console object is defined - if not, define one
|
||||
@ -67,7 +41,7 @@ if (typeof window.console == 'undefined')
|
||||
* the result js will be written to _html.js.
|
||||
*/
|
||||
|
||||
egw_seperateJavaScript = function(_html)
|
||||
window.egw_seperateJavaScript = function(_html)
|
||||
{
|
||||
var html = typeof _html.html == 'string'?_html.html:'';
|
||||
|
||||
@ -95,7 +69,7 @@ egw_seperateJavaScript = function(_html)
|
||||
/**
|
||||
* Inserts the script tags inside the given html into the dom tree
|
||||
*/
|
||||
function egw_insertJS(_html)
|
||||
window.egw_insertJS = function(_html)
|
||||
{
|
||||
// Insert each script element seperately
|
||||
if (_html)
|
||||
@ -147,7 +121,7 @@ function egw_insertJS(_html)
|
||||
/**
|
||||
* Returns the top window which contains the current egw_instance, even for popup windows
|
||||
*/
|
||||
function egw_topWindow()
|
||||
window.egw_topWindow = function()
|
||||
{
|
||||
return egw.top;
|
||||
}
|
||||
@ -156,7 +130,7 @@ function egw_topWindow()
|
||||
* Returns the window object of the current application
|
||||
* @param string _app is the name of the application which requests the window object
|
||||
*/
|
||||
function egw_appWindow(_app)
|
||||
window.egw_appWindow = function(_app)
|
||||
{
|
||||
var framework = egw_getFramework();
|
||||
if(framework && framework.egw_appWindow) return framework.egw_appWindow(_app);
|
||||
@ -168,7 +142,7 @@ function egw_appWindow(_app)
|
||||
* @param _app
|
||||
* @param _url
|
||||
*/
|
||||
function egw_appWindowOpen(_app, _url)
|
||||
window.egw_appWindowOpen = function(_app, _url)
|
||||
{
|
||||
if (typeof _url == "undefined") {
|
||||
_url = "about:blank";
|
||||
@ -180,7 +154,7 @@ function egw_appWindowOpen(_app, _url)
|
||||
* Returns the current egw application
|
||||
* @param string _name is only used for fallback, if an onlder version of jdots is used.
|
||||
*/
|
||||
function egw_getApp(_name)
|
||||
window.egw_getApp = function(_name)
|
||||
{
|
||||
return window.parent.framework.getApplicationByName(_name);
|
||||
}
|
||||
@ -190,7 +164,7 @@ function egw_getApp(_name)
|
||||
*
|
||||
* @deprecated use egw(window).app_name()
|
||||
*/
|
||||
function egw_getAppName()
|
||||
window.egw_getAppName = function()
|
||||
{
|
||||
if (typeof egw_appName == 'undefined')
|
||||
{
|
||||
@ -222,7 +196,7 @@ function egw_getAppName()
|
||||
* @param {string} _msg_type 'error', 'warning' or 'success' (default)
|
||||
* @deprecated use egw(window).refresh() instead
|
||||
*/
|
||||
function egw_refresh(_msg, _app, _id, _type, _targetapp, _replace, _with, _msg_type)
|
||||
window.egw_refresh = function(_msg, _app, _id, _type, _targetapp, _replace, _with, _msg_type)
|
||||
{
|
||||
egw(window).refresh(_msg, _app, _id, _type, _targetapp, _replace, _with, _msg_type);
|
||||
}
|
||||
@ -234,7 +208,7 @@ function egw_refresh(_msg, _app, _id, _type, _targetapp, _replace, _with, _msg_t
|
||||
* @param {string} _type 'error', 'warning' or 'success' (default)
|
||||
* @deprecated use egw(window).message(_msg, _type)
|
||||
*/
|
||||
function egw_message(_msg, _type)
|
||||
window.egw_message = function(_msg, _type)
|
||||
{
|
||||
egw(window).message(_msg, _type);
|
||||
}
|
||||
@ -246,7 +220,7 @@ function egw_message(_msg, _type)
|
||||
* @param {string} _app Application name, if not for the current app
|
||||
@deprecated use egw(window).app_header(_header, _app)
|
||||
*/
|
||||
function egw_app_header(_header,_app)
|
||||
window.egw_app_header = function(_header,_app)
|
||||
{
|
||||
egw(window).app_header(_header, _app);
|
||||
}
|
||||
@ -267,7 +241,7 @@ function egw_app_header(_header,_app)
|
||||
* @param string target target of window to open
|
||||
* @deprecated use egw.open()
|
||||
*/
|
||||
function egw_open(id, app, type, extra, target)
|
||||
window.egw_open = function(id, app, type, extra, target)
|
||||
{
|
||||
window.egw.open(id, app, type, extra, target);
|
||||
}
|
||||
@ -332,7 +306,7 @@ window.register_app_refresh = function(appname, refresh_func)
|
||||
}
|
||||
|
||||
|
||||
function egw_set_checkbox_multiselect_enabled(_id, _enabled)
|
||||
window.egw_set_checkbox_multiselect_enabled = function(_id, _enabled)
|
||||
{
|
||||
//Retrieve the checkbox_multiselect base div
|
||||
var ms = document.getElementById('exec['+_id+']');
|
||||
@ -381,7 +355,7 @@ function egw_set_checkbox_multiselect_enabled(_id, _enabled)
|
||||
* @returns {DOMWindow|undefined}
|
||||
* @deprecated use egw.openPopup(_url, _width, _height, _windowName, _app, _returnID, _status)
|
||||
*/
|
||||
function egw_openWindowCentered2(_url, _windowName, _width, _height, _status, _app, _returnID)
|
||||
window.egw_openWindowCentered2 = function(_url, _windowName, _width, _height, _status, _app, _returnID)
|
||||
{
|
||||
return egw(window).openPopup(_url, _width, _height, _windowName, _app, _returnID, _status);
|
||||
}
|
||||
@ -389,17 +363,17 @@ function egw_openWindowCentered2(_url, _windowName, _width, _height, _status, _a
|
||||
/**
|
||||
* @deprecated use egw.openPopup(_url, _width, _height, _windowName, _app, _returnID, _status)
|
||||
*/
|
||||
function egw_openWindowCentered(_url, _windowName, _width, _height)
|
||||
window.egw_openWindowCentered = function(_url, _windowName, _width, _height)
|
||||
{
|
||||
return egw_openWindowCentered2(_url, _windowName, _width, _height, 'no', false, true);
|
||||
}
|
||||
|
||||
// return the left position of the window
|
||||
function egw_getWindowLeft()
|
||||
window.egw_getWindowLeft = function()
|
||||
{
|
||||
// workaround for Fennec bug https://bugzilla.mozilla.org/show_bug.cgi?format=multiple&id=648250 window.(outerHeight|outerWidth|screenX|screenY) throw exception
|
||||
try {
|
||||
if(is_mozilla) return window.screenX;
|
||||
return window.screenX;
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
@ -407,11 +381,11 @@ function egw_getWindowLeft()
|
||||
}
|
||||
|
||||
// return the left position of the window
|
||||
function egw_getWindowTop()
|
||||
window.egw_getWindowTop = function()
|
||||
{
|
||||
// workaround for Fennec bug https://bugzilla.mozilla.org/show_bug.cgi?format=multiple&id=648250 window.(outerHeight|outerWidth|screenX|screenY) throw exception
|
||||
try {
|
||||
if(is_mozilla) return window.screenY;
|
||||
return window.screenY;
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
@ -419,43 +393,23 @@ function egw_getWindowTop()
|
||||
}
|
||||
|
||||
// get the outerWidth of the browser window. For IE we simply return the innerWidth
|
||||
function egw_getWindowInnerWidth()
|
||||
window.egw_getWindowInnerWidth = function()
|
||||
{
|
||||
if (is_mozilla)
|
||||
{
|
||||
return window.innerWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
// works only after the body has parsed
|
||||
//return document.body.offsetWidth;
|
||||
return document.body.clientWidth;
|
||||
//return document.documentElement.clientWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// get the outerHeight of the browser window. For IE we simply return the innerHeight
|
||||
function egw_getWindowInnerHeight()
|
||||
window.egw_getWindowInnerHeight = function()
|
||||
{
|
||||
if (is_mozilla)
|
||||
{
|
||||
return window.innerHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
// works only after the body has parsed
|
||||
//return document.body.offsetHeight;
|
||||
//return document.body.clientHeight;
|
||||
return document.documentElement.clientHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// get the outerWidth of the browser window. For IE we simply return the innerWidth
|
||||
function egw_getWindowOuterWidth()
|
||||
window.egw_getWindowOuterWidth = function()
|
||||
{
|
||||
// workaround for Fennec bug https://bugzilla.mozilla.org/show_bug.cgi?format=multiple&id=648250 window.(outerHeight|outerWidth|screenX|screenY) throw exception
|
||||
try {
|
||||
if (is_mozilla) return window.outerWidth;
|
||||
return window.outerWidth;
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
@ -463,11 +417,11 @@ function egw_getWindowOuterWidth()
|
||||
}
|
||||
|
||||
// get the outerHeight of the browser window. For IE we simply return the innerHeight
|
||||
function egw_getWindowOuterHeight()
|
||||
window.egw_getWindowOuterHeight = function()
|
||||
{
|
||||
// workaround for Fennec bug https://bugzilla.mozilla.org/show_bug.cgi?format=multiple&id=648250 window.(outerHeight|outerWidth|screenX|screenY) throw exception
|
||||
try {
|
||||
if (is_mozilla) return window.outerHeight;
|
||||
return window.outerHeight;
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
@ -477,7 +431,7 @@ function egw_getWindowOuterHeight()
|
||||
// ie selectbox dropdown menu hack. as ie is not able to resize dropdown menus from selectboxes, we
|
||||
// read the content of the dropdown menu and present it as popup resized for the user. if the user
|
||||
// clicks/seleckts a value, the selection is posted back to the origial selectbox
|
||||
function dropdown_menu_hack(el)
|
||||
window.dropdown_menu_hack = function(el)
|
||||
{
|
||||
if(el.runtimeStyle)
|
||||
{
|
||||
@ -536,14 +490,13 @@ function dropdown_menu_hack(el)
|
||||
}
|
||||
|
||||
|
||||
f_hide = function(e)
|
||||
f.hide = function(e)
|
||||
{
|
||||
if(window.event && window.event.srcElement && window.event.srcElement.tagName && window.event.srcElement.tagName.toLowerCase()=="select"){return true;}
|
||||
fwin.style.display="none";
|
||||
}
|
||||
f.hide = f_hide;
|
||||
document.attachEvent("onclick",f_hide);
|
||||
document.attachEvent("onkeydown",f_hide);
|
||||
document.attachEvent("onclick",f.hide);
|
||||
document.attachEvent("onkeydown",f.hide);
|
||||
|
||||
}
|
||||
return f;
|
||||
@ -654,7 +607,6 @@ function dropdown_menu_hack(el)
|
||||
}
|
||||
self.focus();
|
||||
el.menu.show( mx , my , mw, mh , el);
|
||||
sync=null;
|
||||
if(mb.options.selected)
|
||||
{
|
||||
mb.scrollTop = mb.options.selected.offsetTop;
|
||||
@ -718,7 +670,7 @@ function dropdown_menu_hack(el)
|
||||
* @param _app
|
||||
* @deprecated use egw(window).link_handler(_link, _app) instead
|
||||
*/
|
||||
function egw_link_handler(_link, _app)
|
||||
window.egw_link_handler = function(_link, _app)
|
||||
{
|
||||
egw(window).link_handler(_link, _app);
|
||||
}
|
||||
@ -728,9 +680,9 @@ function egw_link_handler(_link, _app)
|
||||
*
|
||||
* @ToDo: should be removed if uiaccountsel class is no longer in use
|
||||
*/
|
||||
function addOption(id,label,value,do_onchange)
|
||||
window.addOption = function(id,label,value,do_onchange)
|
||||
{
|
||||
selectBox = document.getElementById(id);
|
||||
let selectBox = document.getElementById(id);
|
||||
for (var i=0; i < selectBox.length; i++) {
|
||||
// check existing entries if they're already there and only select them in that case
|
||||
if (selectBox.options[i].value == value) {
|
||||
@ -754,7 +706,7 @@ function addOption(id,label,value,do_onchange)
|
||||
* @param {string} _mime current mime type
|
||||
* @returns {object|null} returns object of filemanager editor hook
|
||||
*/
|
||||
function egw_get_file_editor_prefered_mimes(_mime)
|
||||
window.egw_get_file_editor_prefered_mimes = function(_mime)
|
||||
{
|
||||
var fe = jQuery.extend(true, {},egw.link_get_registry('filemanager-editor'));
|
||||
var ex_mimes = egw.preference('collab_excluded_mimes', 'filemanager');
|
||||
|
5
api/js/labjs/LAB-debug.min.js
vendored
5
api/js/labjs/LAB-debug.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
5
api/js/labjs/LAB.min.js
vendored
5
api/js/labjs/LAB.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1,514 +0,0 @@
|
||||
/*! LAB.js (LABjs :: Loading And Blocking JavaScript)
|
||||
v2.0.3 (c) Kyle Simpson
|
||||
MIT License
|
||||
*/
|
||||
|
||||
(function(global){
|
||||
var _$LAB = global.$LAB,
|
||||
|
||||
// constants for the valid keys of the options object
|
||||
_UseLocalXHR = "UseLocalXHR",
|
||||
_AlwaysPreserveOrder = "AlwaysPreserveOrder",
|
||||
_AllowDuplicates = "AllowDuplicates",
|
||||
_CacheBust = "CacheBust",
|
||||
/*!START_DEBUG*/_Debug = "Debug",/*!END_DEBUG*/
|
||||
_BasePath = "BasePath",
|
||||
|
||||
// stateless variables used across all $LAB instances
|
||||
root_page = /^[^?#]*\//.exec(location.href)[0],
|
||||
root_domain = /^\w+\:\/\/\/?[^\/]+/.exec(root_page)[0],
|
||||
append_to = document.head || document.getElementsByTagName("head"),
|
||||
|
||||
// inferences... ick, but still necessary
|
||||
opera_or_gecko = (global.opera && Object.prototype.toString.call(global.opera) == "[object Opera]") || ("MozAppearance" in document.documentElement.style),
|
||||
|
||||
/*!START_DEBUG*/
|
||||
// console.log() and console.error() wrappers
|
||||
log_msg = function(){},
|
||||
log_error = log_msg,
|
||||
/*!END_DEBUG*/
|
||||
|
||||
// feature sniffs (yay!)
|
||||
test_script_elem = document.createElement("script"),
|
||||
explicit_preloading = typeof test_script_elem.preload == "boolean", // http://wiki.whatwg.org/wiki/Script_Execution_Control#Proposal_1_.28Nicholas_Zakas.29
|
||||
real_preloading = explicit_preloading || (test_script_elem.readyState && test_script_elem.readyState == "uninitialized"), // will a script preload with `src` set before DOM append?
|
||||
script_ordered_async = !real_preloading && test_script_elem.async === true, // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
|
||||
|
||||
// XHR preloading (same-domain) and cache-preloading (remote-domain) are the fallbacks (for some browsers)
|
||||
xhr_or_cache_preloading = !real_preloading && !script_ordered_async && !opera_or_gecko
|
||||
;
|
||||
|
||||
/*!START_DEBUG*/
|
||||
// define console wrapper functions if applicable
|
||||
if (global.console && global.console.log) {
|
||||
if (!global.console.error) global.console.error = global.console.log;
|
||||
log_msg = function(msg) { global.console.log(msg); };
|
||||
log_error = function(msg,err) { global.console.error(msg,err); };
|
||||
}
|
||||
/*!END_DEBUG*/
|
||||
|
||||
// test for function
|
||||
function is_func(func) { return Object.prototype.toString.call(func) == "[object Function]"; }
|
||||
|
||||
// test for array
|
||||
function is_array(arr) { return Object.prototype.toString.call(arr) == "[object Array]"; }
|
||||
|
||||
// make script URL absolute/canonical
|
||||
function canonical_uri(src,base_path) {
|
||||
var absolute_regex = /^\w+\:\/\//;
|
||||
|
||||
// is `src` is protocol-relative (begins with // or ///), prepend protocol
|
||||
if (/^\/\/\/?/.test(src)) {
|
||||
src = location.protocol + src;
|
||||
}
|
||||
// is `src` page-relative? (not an absolute URL, and not a domain-relative path, beginning with /)
|
||||
else if (!absolute_regex.test(src) && src.charAt(0) != "/") {
|
||||
// prepend `base_path`, if any
|
||||
src = (base_path || "") + src;
|
||||
}
|
||||
// make sure to return `src` as absolute
|
||||
return absolute_regex.test(src) ? src : ((src.charAt(0) == "/" ? root_domain : root_page) + src);
|
||||
}
|
||||
|
||||
// merge `source` into `target`
|
||||
function merge_objs(source,target) {
|
||||
for (var k in source) { if (source.hasOwnProperty(k)) {
|
||||
target[k] = source[k]; // TODO: does this need to be recursive for our purposes?
|
||||
}}
|
||||
return target;
|
||||
}
|
||||
|
||||
// does the chain group have any ready-to-execute scripts?
|
||||
function check_chain_group_scripts_ready(chain_group) {
|
||||
var any_scripts_ready = false;
|
||||
for (var i=0; i<chain_group.scripts.length; i++) {
|
||||
if (chain_group.scripts[i].ready && chain_group.scripts[i].exec_trigger) {
|
||||
any_scripts_ready = true;
|
||||
chain_group.scripts[i].exec_trigger();
|
||||
chain_group.scripts[i].exec_trigger = null;
|
||||
}
|
||||
}
|
||||
return any_scripts_ready;
|
||||
}
|
||||
|
||||
// creates a script load listener
|
||||
function create_script_load_listener(elem,registry_item,flag,onload) {
|
||||
elem.onload = elem.onreadystatechange = function() {
|
||||
if ((elem.readyState && elem.readyState != "complete" && elem.readyState != "loaded") || registry_item[flag]) return;
|
||||
elem.onload = elem.onreadystatechange = null;
|
||||
onload();
|
||||
};
|
||||
}
|
||||
|
||||
// script executed handler
|
||||
function script_executed(registry_item) {
|
||||
registry_item.ready = registry_item.finished = true;
|
||||
for (var i=0; i<registry_item.finished_listeners.length; i++) {
|
||||
registry_item.finished_listeners[i]();
|
||||
}
|
||||
registry_item.ready_listeners = [];
|
||||
registry_item.finished_listeners = [];
|
||||
}
|
||||
|
||||
// make the request for a scriptha
|
||||
function request_script(chain_opts,script_obj,registry_item,onload,preload_this_script) {
|
||||
// setTimeout() "yielding" prevents some weird race/crash conditions in older browsers
|
||||
setTimeout(function(){
|
||||
var script, src = script_obj.real_src, xhr;
|
||||
|
||||
// don't proceed until `append_to` is ready to append to
|
||||
if ("item" in append_to) { // check if `append_to` ref is still a live node list
|
||||
if (!append_to[0]) { // `append_to` node not yet ready
|
||||
// try again in a little bit -- note: will re-call the anonymous function in the outer setTimeout, not the parent `request_script()`
|
||||
setTimeout(arguments.callee,25);
|
||||
return;
|
||||
}
|
||||
// reassign from live node list ref to pure node ref -- avoids nasty IE bug where changes to DOM invalidate live node lists
|
||||
append_to = append_to[0];
|
||||
}
|
||||
script = document.createElement("script");
|
||||
if (script_obj.type) script.type = script_obj.type;
|
||||
if (script_obj.charset) script.charset = script_obj.charset;
|
||||
|
||||
// should preloading be used for this script?
|
||||
if (preload_this_script) {
|
||||
// real script preloading?
|
||||
if (real_preloading) {
|
||||
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload: "+src);/*!END_DEBUG*/
|
||||
registry_item.elem = script;
|
||||
if (explicit_preloading) { // explicit preloading (aka, Zakas' proposal)
|
||||
script.preload = true;
|
||||
script.onpreload = onload;
|
||||
}
|
||||
else {
|
||||
script.onreadystatechange = function(){
|
||||
if (script.readyState == "loaded") onload();
|
||||
};
|
||||
}
|
||||
script.src = src;
|
||||
// NOTE: no append to DOM yet, appending will happen when ready to execute
|
||||
}
|
||||
// same-domain and XHR allowed? use XHR preloading
|
||||
else if (preload_this_script && src.indexOf(root_domain) == 0 && chain_opts[_UseLocalXHR]) {
|
||||
xhr = new XMLHttpRequest(); // note: IE never uses XHR (it supports true preloading), so no more need for ActiveXObject fallback for IE <= 7
|
||||
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload (xhr): "+src);/*!END_DEBUG*/
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState == 4) {
|
||||
xhr.onreadystatechange = function(){}; // fix a memory leak in IE
|
||||
registry_item.text = xhr.responseText + "\n//@ sourceURL=" + src; // http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
|
||||
onload();
|
||||
}
|
||||
};
|
||||
xhr.open("GET",src);
|
||||
xhr.send();
|
||||
}
|
||||
// as a last resort, use cache-preloading
|
||||
else {
|
||||
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload (cache): "+src);/*!END_DEBUG*/
|
||||
script.type = "text/cache-script";
|
||||
create_script_load_listener(script,registry_item,"ready",function() {
|
||||
append_to.removeChild(script);
|
||||
onload();
|
||||
});
|
||||
script.src = src;
|
||||
append_to.insertBefore(script,append_to.firstChild);
|
||||
}
|
||||
}
|
||||
// use async=false for ordered async? parallel-load-serial-execute http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
|
||||
else if (script_ordered_async) {
|
||||
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script load (ordered async): "+src);/*!END_DEBUG*/
|
||||
script.async = false;
|
||||
create_script_load_listener(script,registry_item,"finished",onload);
|
||||
script.src = src;
|
||||
append_to.insertBefore(script,append_to.firstChild);
|
||||
}
|
||||
// otherwise, just a normal script element
|
||||
else {
|
||||
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script load: "+src);/*!END_DEBUG*/
|
||||
create_script_load_listener(script,registry_item,"finished",onload);
|
||||
script.src = src;
|
||||
append_to.insertBefore(script,append_to.firstChild);
|
||||
}
|
||||
},0);
|
||||
}
|
||||
|
||||
// create a clean instance of $LAB
|
||||
function create_sandbox() {
|
||||
var global_defaults = {},
|
||||
can_use_preloading = real_preloading || xhr_or_cache_preloading,
|
||||
queue = [],
|
||||
registry = {},
|
||||
instanceAPI
|
||||
;
|
||||
|
||||
// global defaults
|
||||
global_defaults[_UseLocalXHR] = true;
|
||||
global_defaults[_AlwaysPreserveOrder] = false;
|
||||
global_defaults[_AllowDuplicates] = false;
|
||||
global_defaults[_CacheBust] = false;
|
||||
/*!START_DEBUG*/global_defaults[_Debug] = false;/*!END_DEBUG*/
|
||||
global_defaults[_BasePath] = "";
|
||||
|
||||
// execute a script that has been preloaded already
|
||||
function execute_preloaded_script(chain_opts,script_obj,registry_item) {
|
||||
var script;
|
||||
|
||||
function preload_execute_finished() {
|
||||
if (script != null) { // make sure this only ever fires once
|
||||
script = null;
|
||||
script_executed(registry_item);
|
||||
}
|
||||
}
|
||||
|
||||
if (registry[script_obj.src].finished) return;
|
||||
if (!chain_opts[_AllowDuplicates]) registry[script_obj.src].finished = true;
|
||||
|
||||
script = registry_item.elem || document.createElement("script");
|
||||
if (script_obj.type) script.type = script_obj.type;
|
||||
if (script_obj.charset) script.charset = script_obj.charset;
|
||||
create_script_load_listener(script,registry_item,"finished",preload_execute_finished);
|
||||
|
||||
// script elem was real-preloaded
|
||||
if (registry_item.elem) {
|
||||
registry_item.elem = null;
|
||||
}
|
||||
// script was XHR preloaded
|
||||
else if (registry_item.text) {
|
||||
script.onload = script.onreadystatechange = null; // script injection doesn't fire these events
|
||||
script.text = registry_item.text;
|
||||
}
|
||||
// script was cache-preloaded
|
||||
else {
|
||||
script.src = script_obj.real_src;
|
||||
}
|
||||
append_to.insertBefore(script,append_to.firstChild);
|
||||
|
||||
// manually fire execution callback for injected scripts, since events don't fire
|
||||
if (registry_item.text) {
|
||||
preload_execute_finished();
|
||||
}
|
||||
}
|
||||
|
||||
// process the script request setup
|
||||
function do_script(chain_opts,script_obj,chain_group,preload_this_script) {
|
||||
var registry_item,
|
||||
registry_items,
|
||||
ready_cb = function(){ script_obj.ready_cb(script_obj,function(){ execute_preloaded_script(chain_opts,script_obj,registry_item); }); },
|
||||
finished_cb = function(){ script_obj.finished_cb(script_obj,chain_group); }
|
||||
;
|
||||
|
||||
script_obj.src = canonical_uri(script_obj.src,chain_opts[_BasePath]);
|
||||
script_obj.real_src = script_obj.src +
|
||||
// append cache-bust param to URL?
|
||||
(chain_opts[_CacheBust] ? ((/\?.*$/.test(script_obj.src) ? "&_" : "?_") + ~~(Math.random()*1E9) + "=") : "")
|
||||
;
|
||||
|
||||
if (!registry[script_obj.src]) registry[script_obj.src] = {items:[],finished:false};
|
||||
registry_items = registry[script_obj.src].items;
|
||||
|
||||
// allowing duplicates, or is this the first recorded load of this script?
|
||||
if (chain_opts[_AllowDuplicates] || registry_items.length == 0) {
|
||||
registry_item = registry_items[registry_items.length] = {
|
||||
ready:false,
|
||||
finished:false,
|
||||
ready_listeners:[ready_cb],
|
||||
finished_listeners:[finished_cb]
|
||||
};
|
||||
|
||||
request_script(chain_opts,script_obj,registry_item,
|
||||
// which callback type to pass?
|
||||
(
|
||||
(preload_this_script) ? // depends on script-preloading
|
||||
function(){
|
||||
registry_item.ready = true;
|
||||
for (var i=0; i<registry_item.ready_listeners.length; i++) {
|
||||
registry_item.ready_listeners[i]();
|
||||
}
|
||||
registry_item.ready_listeners = [];
|
||||
} :
|
||||
function(){ script_executed(registry_item); }
|
||||
),
|
||||
// signal if script-preloading should be used or not
|
||||
preload_this_script
|
||||
);
|
||||
}
|
||||
else {
|
||||
registry_item = registry_items[0];
|
||||
if (registry_item.finished) {
|
||||
finished_cb();
|
||||
}
|
||||
else {
|
||||
registry_item.finished_listeners.push(finished_cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// creates a closure for each separate chain spawned from this $LAB instance, to keep state cleanly separated between chains
|
||||
function create_chain() {
|
||||
var chainedAPI,
|
||||
chain_opts = merge_objs(global_defaults,{}),
|
||||
chain = [],
|
||||
exec_cursor = 0,
|
||||
scripts_currently_loading = false,
|
||||
group
|
||||
;
|
||||
|
||||
// called when a script has finished preloading
|
||||
function chain_script_ready(script_obj,exec_trigger) {
|
||||
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("script preload finished: "+script_obj.real_src);/*!END_DEBUG*/
|
||||
script_obj.ready = true;
|
||||
script_obj.exec_trigger = exec_trigger;
|
||||
advance_exec_cursor(); // will only check for 'ready' scripts to be executed
|
||||
}
|
||||
|
||||
// called when a script has finished executing
|
||||
function chain_script_executed(script_obj,chain_group) {
|
||||
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("script execution finished: "+script_obj.real_src);/*!END_DEBUG*/
|
||||
script_obj.ready = script_obj.finished = true;
|
||||
script_obj.exec_trigger = null;
|
||||
// check if chain group is all finished
|
||||
for (var i=0; i<chain_group.scripts.length; i++) {
|
||||
if (!chain_group.scripts[i].finished) return;
|
||||
}
|
||||
// chain_group is all finished if we get this far
|
||||
chain_group.finished = true;
|
||||
advance_exec_cursor();
|
||||
}
|
||||
|
||||
// main driver for executing each part of the chain
|
||||
function advance_exec_cursor() {
|
||||
while (exec_cursor < chain.length) {
|
||||
if (is_func(chain[exec_cursor])) {
|
||||
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("$LAB.wait() executing: "+chain[exec_cursor]);/*!END_DEBUG*/
|
||||
try { chain[exec_cursor++](); } catch (err) {
|
||||
/*!START_DEBUG*/if (chain_opts[_Debug]) log_error("$LAB.wait() error caught: ",err);/*!END_DEBUG*/
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (!chain[exec_cursor].finished) {
|
||||
if (check_chain_group_scripts_ready(chain[exec_cursor])) continue;
|
||||
break;
|
||||
}
|
||||
exec_cursor++;
|
||||
}
|
||||
// we've reached the end of the chain (so far)
|
||||
if (exec_cursor == chain.length) {
|
||||
scripts_currently_loading = false;
|
||||
group = false;
|
||||
}
|
||||
}
|
||||
|
||||
// setup next chain script group
|
||||
function init_script_chain_group() {
|
||||
if (!group || !group.scripts) {
|
||||
chain.push(group = {scripts:[],finished:true});
|
||||
}
|
||||
}
|
||||
|
||||
// API for $LAB chains
|
||||
chainedAPI = {
|
||||
// start loading one or more scripts
|
||||
script:function(){
|
||||
for (var i=0; i<arguments.length; i++) {
|
||||
(function(script_obj,script_list){
|
||||
var splice_args;
|
||||
|
||||
if (!is_array(script_obj)) {
|
||||
script_list = [script_obj];
|
||||
}
|
||||
for (var j=0; j<script_list.length; j++) {
|
||||
init_script_chain_group();
|
||||
script_obj = script_list[j];
|
||||
|
||||
if (is_func(script_obj)) script_obj = script_obj();
|
||||
if (!script_obj) continue;
|
||||
if (is_array(script_obj)) {
|
||||
// set up an array of arguments to pass to splice()
|
||||
splice_args = [].slice.call(script_obj); // first include the actual array elements we want to splice in
|
||||
splice_args.unshift(j,1); // next, put the `index` and `howMany` parameters onto the beginning of the splice-arguments array
|
||||
[].splice.apply(script_list,splice_args); // use the splice-arguments array as arguments for splice()
|
||||
j--; // adjust `j` to account for the loop's subsequent `j++`, so that the next loop iteration uses the same `j` index value
|
||||
continue;
|
||||
}
|
||||
if (typeof script_obj == "string") script_obj = {src:script_obj};
|
||||
script_obj = merge_objs(script_obj,{
|
||||
ready:false,
|
||||
ready_cb:chain_script_ready,
|
||||
finished:false,
|
||||
finished_cb:chain_script_executed
|
||||
});
|
||||
group.finished = false;
|
||||
group.scripts.push(script_obj);
|
||||
|
||||
do_script(chain_opts,script_obj,group,(can_use_preloading && scripts_currently_loading));
|
||||
scripts_currently_loading = true;
|
||||
|
||||
if (chain_opts[_AlwaysPreserveOrder]) chainedAPI.wait();
|
||||
}
|
||||
})(arguments[i],arguments[i]);
|
||||
}
|
||||
return chainedAPI;
|
||||
},
|
||||
// force LABjs to pause in execution at this point in the chain, until the execution thus far finishes, before proceeding
|
||||
wait:function(){
|
||||
if (arguments.length > 0) {
|
||||
for (var i=0; i<arguments.length; i++) {
|
||||
chain.push(arguments[i]);
|
||||
}
|
||||
group = chain[chain.length-1];
|
||||
}
|
||||
else group = false;
|
||||
|
||||
advance_exec_cursor();
|
||||
|
||||
return chainedAPI;
|
||||
}
|
||||
};
|
||||
|
||||
// the first chain link API (includes `setOptions` only this first time)
|
||||
return {
|
||||
script:chainedAPI.script,
|
||||
wait:chainedAPI.wait,
|
||||
setOptions:function(opts){
|
||||
merge_objs(opts,chain_opts);
|
||||
return chainedAPI;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// API for each initial $LAB instance (before chaining starts)
|
||||
instanceAPI = {
|
||||
// main API functions
|
||||
setGlobalDefaults:function(opts){
|
||||
merge_objs(opts,global_defaults);
|
||||
return instanceAPI;
|
||||
},
|
||||
setOptions:function(){
|
||||
return create_chain().setOptions.apply(null,arguments);
|
||||
},
|
||||
script:function(){
|
||||
return create_chain().script.apply(null,arguments);
|
||||
},
|
||||
wait:function(){
|
||||
return create_chain().wait.apply(null,arguments);
|
||||
},
|
||||
|
||||
// built-in queuing for $LAB `script()` and `wait()` calls
|
||||
// useful for building up a chain programmatically across various script locations, and simulating
|
||||
// execution of the chain
|
||||
queueScript:function(){
|
||||
queue[queue.length] = {type:"script", args:[].slice.call(arguments)};
|
||||
return instanceAPI;
|
||||
},
|
||||
queueWait:function(){
|
||||
queue[queue.length] = {type:"wait", args:[].slice.call(arguments)};
|
||||
return instanceAPI;
|
||||
},
|
||||
runQueue:function(){
|
||||
var $L = instanceAPI, len=queue.length, i=len, val;
|
||||
for (;--i>=0;) {
|
||||
val = queue.shift();
|
||||
$L = $L[val.type].apply(null,val.args);
|
||||
}
|
||||
return $L;
|
||||
},
|
||||
|
||||
// rollback `[global].$LAB` to what it was before this file was loaded, the return this current instance of $LAB
|
||||
noConflict:function(){
|
||||
global.$LAB = _$LAB;
|
||||
return instanceAPI;
|
||||
},
|
||||
|
||||
// create another clean instance of $LAB
|
||||
sandbox:function(){
|
||||
return create_sandbox();
|
||||
}
|
||||
};
|
||||
|
||||
return instanceAPI;
|
||||
}
|
||||
|
||||
// create the main instance of $LAB
|
||||
global.$LAB = create_sandbox();
|
||||
|
||||
|
||||
/* The following "hack" was suggested by Andrea Giammarchi and adapted from: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html
|
||||
NOTE: this hack only operates in FF and then only in versions where document.readyState is not present (FF < 3.6?).
|
||||
|
||||
The hack essentially "patches" the **page** that LABjs is loaded onto so that it has a proper conforming document.readyState, so that if a script which does
|
||||
proper and safe dom-ready detection is loaded onto a page, after dom-ready has passed, it will still be able to detect this state, by inspecting the now hacked
|
||||
document.readyState property. The loaded script in question can then immediately trigger any queued code executions that were waiting for the DOM to be ready.
|
||||
For instance, jQuery 1.4+ has been patched to take advantage of document.readyState, which is enabled by this hack. But 1.3.2 and before are **not** safe or
|
||||
fixed by this hack, and should therefore **not** be lazy-loaded by script loader tools such as LABjs.
|
||||
*/
|
||||
(function(addEvent,domLoaded,handler){
|
||||
if (document.readyState == null && document[addEvent]){
|
||||
document.readyState = "loading";
|
||||
document[addEvent](domLoaded,handler = function(){
|
||||
document.removeEventListener(domLoaded,handler,false);
|
||||
document.readyState = "complete";
|
||||
},false);
|
||||
}
|
||||
})("addEventListener","DOMContentLoaded");
|
||||
|
||||
})(this);
|
@ -7,6 +7,8 @@
|
||||
* @link https://www.egroupware.org
|
||||
*/
|
||||
|
||||
import '../../vendor/bower-asset/jquery/dist/jquery.js'; // also ensures egw_LAB.wait exists!
|
||||
|
||||
/* if login page is not in top window, set top windows location to it */
|
||||
if (top !== window) top.location = window.location;
|
||||
|
||||
|
@ -60,10 +60,11 @@ if (!count(Api\Translation::$lang_arr))
|
||||
Api\Translation::add_app($_GET['app'], 'en');
|
||||
}
|
||||
|
||||
$content = "import './js/jsapi/egw_lang.js';\n\n";
|
||||
// fix for phrases containing \n
|
||||
$content = 'egw.set_lang_arr("'.$_GET['app'].'", '.str_replace('\\\\n', '\\n',
|
||||
$content .= 'window.egw.set_lang_arr("'.$_GET['app'].'", '.str_replace('\\\\n', '\\n',
|
||||
json_encode(Api\Translation::$lang_arr, JSON_PARTIAL_OUTPUT_ON_ERROR|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)).
|
||||
', egw && egw.window !== window);';
|
||||
', window.egw && window.egw.window !== window);';
|
||||
|
||||
// we run our own gzip compression, to set a correct Content-Length of the encoded content
|
||||
if (in_array('gzip', explode(',',$_SERVER['HTTP_ACCEPT_ENCODING'])) && function_exists('gzencode'))
|
||||
|
@ -58,7 +58,7 @@ abstract class Framework extends Framework\Extra
|
||||
/**
|
||||
* Application specific template directories to try in given order for CSS
|
||||
*
|
||||
* @var string
|
||||
* @var string[]
|
||||
*/
|
||||
var $template_dirs = array();
|
||||
|
||||
@ -1053,7 +1053,7 @@ abstract class Framework extends Framework\Extra
|
||||
{
|
||||
$java_script .= $GLOBALS['egw_info']['flags']['java_script_thirst'] . "\n";
|
||||
}
|
||||
// add configuration, link-registry, images, user-data and -perferences for non-popup windows
|
||||
// add configuration, link-registry, images, user-data and -preferences for non-popup windows
|
||||
// specifying etag in url to force reload, as we send expires header
|
||||
if ($GLOBALS['egw_info']['flags']['js_link_registry'] || isset($_GET['cd']) && $_GET['cd'] === 'popup')
|
||||
{
|
||||
@ -1074,13 +1074,19 @@ abstract class Framework extends Framework\Extra
|
||||
}
|
||||
|
||||
$extra['url'] = $GLOBALS['egw_info']['server']['webserver_url'];
|
||||
$extra['include'] = array_map(function($str){return substr($str,1);}, self::get_script_links(true), array(1));
|
||||
$map = null;
|
||||
$extra['include'] = array_map(static function($str){
|
||||
return substr($str,1);
|
||||
}, self::get_script_links(true, false, $map), array(1));
|
||||
$extra['app'] = $GLOBALS['egw_info']['flags']['currentapp'];
|
||||
|
||||
// Load LABjs ONCE here
|
||||
$java_script .= '<script type="text/javascript" src="'.$GLOBALS['egw_info']['server']['webserver_url'].
|
||||
'/api/js/labjs/LAB.src.js?'.filemtime(EGW_SERVER_ROOT.'/api/js/labjs/LAB.src.js')."\"></script>\n".
|
||||
'<script type="text/javascript" src="'.$GLOBALS['egw_info']['server']['webserver_url'].
|
||||
// add import-map before (!) first module
|
||||
$java_script .= '<script type="importmap" nonce="'.htmlspecialchars(ContentSecurityPolicy::addNonce('script-src')).'">'."\n".
|
||||
json_encode(['imports' => self::addUrlPrefix($map)], JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT)."\n".
|
||||
"</script>\n";
|
||||
|
||||
// load our clientside entrypoint egw.js
|
||||
$java_script .= '<script type="module" src="'.$GLOBALS['egw_info']['server']['webserver_url'].
|
||||
'/api/js/jsapi/egw.js?'.filemtime(EGW_SERVER_ROOT.'/api/js/jsapi/egw.js').'" id="egw_script_id"';
|
||||
|
||||
// add values of extra parameter and class var as data attributes to script tag of egw.js
|
||||
@ -1114,6 +1120,27 @@ abstract class Framework extends Framework\Extra
|
||||
return $java_script;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add EGroupware URL prefix eg. '/egroupware' to files AND bundles
|
||||
*
|
||||
* @param array $map
|
||||
* @return array
|
||||
*/
|
||||
protected static function addUrlPrefix(array $map)
|
||||
{
|
||||
if (substr($prefix = $GLOBALS['egw_info']['server']['webserver_url'], 0, 4) === 'http')
|
||||
{
|
||||
$prefix = parse_url($prefix, PHP_URL_PATH);
|
||||
}
|
||||
$ret = [];
|
||||
foreach($map as $file => $bundle)
|
||||
{
|
||||
$ret[$prefix.$file] = $prefix.$bundle;
|
||||
}
|
||||
$ret['jsapi/egw_json'] = $ret['/egw-test/api/js/jsapi/egw_json.js'];
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* List available themes
|
||||
*
|
||||
@ -1466,11 +1493,12 @@ abstract class Framework extends Framework\Extra
|
||||
*
|
||||
* @param boolean $return_pathes =false false: return Html script tags, true: return array of file pathes relative to webserver_url
|
||||
* @param boolean $clear_files =false true clear files after returning them
|
||||
* @param array& $map on return map file => bundle
|
||||
* @return string|array see $return_pathes parameter
|
||||
*/
|
||||
static public function get_script_links($return_pathes=false, $clear_files=false)
|
||||
static public function get_script_links($return_pathes=false, $clear_files=false, array &$map=null)
|
||||
{
|
||||
$to_include = Framework\Bundle::js_includes(self::$js_include_mgr->get_included_files($clear_files));
|
||||
$to_include = Framework\Bundle::js_includes(self::$js_include_mgr->get_included_files($clear_files), $map);
|
||||
|
||||
if ($return_pathes)
|
||||
{
|
||||
|
@ -183,8 +183,6 @@ abstract class Ajax extends Api\Framework
|
||||
if (self::$header_done) return '';
|
||||
self::$header_done = true;
|
||||
|
||||
$this->send_headers();
|
||||
|
||||
// catch error echo'ed before the header, ob_start'ed in the header.inc.php
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
@ -267,6 +265,8 @@ abstract class Ajax extends Api\Framework
|
||||
$this->tpl->set_var($this->_get_header($extra));
|
||||
$content = $this->tpl->fp('out','head').$content;
|
||||
|
||||
$this->send_headers();
|
||||
|
||||
if (!$do_framework)
|
||||
{
|
||||
return $content;
|
||||
|
@ -39,9 +39,10 @@ class Bundle
|
||||
* Devide js-includes in bundles of javascript files to include eg. api or etemplate2, if minifying is enabled
|
||||
*
|
||||
* @param array $js_includes files to include with egw relative url
|
||||
* @param array& $to_include on return map file => bundle
|
||||
* @return array egw relative urls to include incl. bundels/minify urls, if enabled
|
||||
*/
|
||||
public static function js_includes(array $js_includes)
|
||||
public static function js_includes(array $js_includes, array &$to_include=null)
|
||||
{
|
||||
$file2bundle = array();
|
||||
if ($GLOBALS['egw_info']['server']['debug_minify'] !== 'True')
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/**
|
||||
* EGroupware: Class which manages including js files and modules
|
||||
* (lateron this might be extended to css)
|
||||
* (later on this might be extended to css)
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
@ -9,7 +9,6 @@
|
||||
* @subpackage framework
|
||||
* @author Andreas Stöckel
|
||||
* @copyright (c) 2011 Stylite
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
namespace EGroupware\Api\Framework;
|
||||
@ -18,8 +17,15 @@ namespace EGroupware\Api\Framework;
|
||||
* Syntax for including JS files form others
|
||||
* -----------------------------------------
|
||||
*
|
||||
* Write a comment starting with "/*egw:uses". A linebreak has to follow.
|
||||
* Then write all files which have to be included seperated by ";". A JS file
|
||||
* a) ES5 or TypeScript module imports: import {...} from '<relative path or EGroupware absolute path>'
|
||||
*
|
||||
* - import './egw_core.js';
|
||||
* - import { something } from '../../vendor/class.js';
|
||||
* - import { something } from './other'; (in TS without extension!)
|
||||
* @ToDo import { something } from 'module/sub'
|
||||
*
|
||||
* b) Write a comment starting with "/*egw:uses". A linebreak has to follow.
|
||||
* Then write all files which have to be included separated by ";". A JS file
|
||||
* include may have the following syntax:
|
||||
*
|
||||
* 1) File in the same directory as the current file. Simply write the filename
|
||||
@ -76,6 +82,11 @@ class IncludeMgr
|
||||
*/
|
||||
private $debug_processing_file = false;
|
||||
|
||||
/**
|
||||
* @var bool true: echo out debug info, for direct call see end of this file
|
||||
*/
|
||||
private $debug_parsing_imports = false;
|
||||
|
||||
/**
|
||||
* Parses the js file for includes and returns all required files
|
||||
*/
|
||||
@ -87,68 +98,58 @@ class IncludeMgr
|
||||
// Mark the file as parsed
|
||||
$this->parsed_files[$file] = true;
|
||||
|
||||
// extension to add, if dependency has none
|
||||
$extension = substr($file, -3) === '.ts' ? '.ts' : '.js';
|
||||
|
||||
$modules = $modules2 = [];
|
||||
// Try to open the given file
|
||||
$f = fopen(EGW_SERVER_ROOT.$file, "r");
|
||||
if ($f !== false)
|
||||
if (($header = file_get_contents(EGW_SERVER_ROOT.$file, false, null, 0, 2048)))
|
||||
{
|
||||
// Only read a maximum of 32 lines until the comment occurs.
|
||||
$cnt = 0;
|
||||
$in_uses = false;
|
||||
$uses = "";
|
||||
|
||||
// Read a line
|
||||
$line = fgets($f);
|
||||
while ($cnt < 32 && $line !== false)
|
||||
if ($this->debug_parsing_imports) echo "<p>$file</p>\n";
|
||||
$matches = null;
|
||||
if (preg_match_all('/import\s+({[^}]+}\s*from\s+)?["\']([^;\s]+)["\']/', $header, $matches))
|
||||
{
|
||||
// Remove everything behind "//"
|
||||
$pos = strpos($line, "//");
|
||||
if ($pos !== false)
|
||||
{
|
||||
$line = substr($line, 0, $pos);
|
||||
if ($this->debug_parsing_imports) echo "imports:<div style='white-space: pre'>".json_encode($matches, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)."</div>\n";
|
||||
$modules = $matches[2];
|
||||
}
|
||||
|
||||
if (!$in_uses)
|
||||
// either use es5 import or old /*egw:uses */ annotation
|
||||
elseif (preg_match('#/\*egw:uses(.*);\s+\*/#sU', $header, $matches) &&
|
||||
($matches = array_filter(preg_split('/;[^\n]*\n\s*/', trim($matches[1])), static function($use)
|
||||
{
|
||||
$cnt++;
|
||||
$in_uses = strpos($line, "/*egw:uses") !== false;
|
||||
}
|
||||
else
|
||||
return !preg_match('#^\s*//#', $use); // filter out commented out ones
|
||||
})))
|
||||
{
|
||||
// Check whether we are at the end of the comment
|
||||
$pos = strpos($line, "*/");
|
||||
|
||||
if ($pos === false)
|
||||
{
|
||||
$uses .= $line;
|
||||
if ($this->debug_parsing_imports) echo "egw:uses:<div style='white-space: pre'>".json_encode($matches, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)."</div>\n";
|
||||
$modules = array_merge($modules, $matches);
|
||||
}
|
||||
else
|
||||
{
|
||||
$uses .= substr($line, 0, $pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$line = fgets($f);
|
||||
}
|
||||
|
||||
// Close the file again
|
||||
fclose($f);
|
||||
|
||||
// Split the "require" string at ";"
|
||||
$modules = explode(";", $uses);
|
||||
$modules2 = array();
|
||||
|
||||
// Split all modules at "." and remove entries with empty parts
|
||||
foreach ($modules as $mod)
|
||||
{
|
||||
// Remove trailing space characters
|
||||
$mod = trim($mod);
|
||||
|
||||
if ($mod)
|
||||
{
|
||||
if ($mod !== trim($mod))
|
||||
{
|
||||
throw new \Exception("'$mod' contains whitespace!");
|
||||
}
|
||||
// Split the given module string at the dot, if this isn't
|
||||
// an absolute path (initialized by "/").
|
||||
if ($mod[0] != '/')
|
||||
// an relative (starting ./) or absolute path (initialized by "/").
|
||||
if (substr($mod, 0, 2) === './')
|
||||
{
|
||||
if (!preg_match('/\.(js|ts)$/', $mod)) $mod .= $extension;
|
||||
$mod = [dirname($file).substr($mod, 1)];
|
||||
}
|
||||
elseif (substr($mod, 0, 3) === '../')
|
||||
{
|
||||
if (!preg_match('/\.(js|ts)$/', $mod)) $mod .= $extension;
|
||||
$dir = dirname($file);
|
||||
while(substr($mod, 0, 3) === '../')
|
||||
{
|
||||
$mod = substr($mod, 3);
|
||||
$dir = dirname($dir);
|
||||
}
|
||||
$mod = [($dir !== '/' ? $dir : '').'/'.$mod];
|
||||
}
|
||||
elseif ($mod[0] != '/')
|
||||
{
|
||||
$mod = explode(".", $mod, 3);
|
||||
}
|
||||
@ -419,13 +420,29 @@ class IncludeMgr
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get importMap for browser
|
||||
*/
|
||||
public function getImportMap()
|
||||
{
|
||||
$files = $this->get_included_files();
|
||||
$imports = array_combine(array_map(static function($url)
|
||||
{
|
||||
return parse_url($url, PHP_URL_PATH);
|
||||
}, $files), $files);
|
||||
|
||||
return ['imports' => $imports];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $files =null optional files to include as for include_files method
|
||||
* @param bool $debug_parsing_imports =false true: echo out debug infos
|
||||
*/
|
||||
public function __construct(array $files = null)
|
||||
public function __construct(array $files = null, bool $debug_parsing_imports=false)
|
||||
{
|
||||
$this->debug_parsing_imports = $debug_parsing_imports;
|
||||
if (isset($files) && is_array($files))
|
||||
{
|
||||
$this->include_files($files);
|
||||
@ -438,9 +455,10 @@ class IncludeMgr
|
||||
if (isset($_SERVER['SCRIPT_FILENAME']) && $_SERVER['SCRIPT_FILENAME'] == __FILE__)
|
||||
{
|
||||
define('EGW_SERVER_ROOT', dirname(dirname(dirname(__DIR__))));
|
||||
include_once(EGW_SERVER_ROOT.'/phpgwapi/inc/common_functions.inc.php');
|
||||
define('EGW_INCLUDE_ROOT', dirname(dirname(dirname(__DIR__))));
|
||||
include_once(EGW_SERVER_ROOT.'/api/src/loader/common.php');
|
||||
|
||||
$mgr = new IncludeMgr();
|
||||
$mgr = new IncludeMgr(null, true);
|
||||
echo "<html>\n<head>\n\t<title>Dependencies</title>\n</head>\n<body>\n";
|
||||
|
||||
$paths = !empty($_GET['path']) ? (array)$_GET['path'] : (array)'/stylite/js/filemanager/filemanager.js';
|
||||
|
@ -99,6 +99,24 @@ class ContentSecurityPolicy
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a nonce to a given source
|
||||
*
|
||||
* @param string $source
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function addNonce($source='script-src')
|
||||
{
|
||||
static $nonce=null;
|
||||
if (!isset($nonce))
|
||||
{
|
||||
$nonce = base64_encode(random_bytes(16));
|
||||
self::add($source, "'nonce-$nonce'");
|
||||
}
|
||||
return $nonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Content-Security-Policy attributes for script-src: 'unsafe-eval' and/or 'unsafe-inline'
|
||||
*
|
||||
|
@ -44,9 +44,10 @@ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $
|
||||
exit;
|
||||
}
|
||||
|
||||
$content = 'egw.set_preferences('.$preferences.", 'common', egw && egw.window !== window);\n";
|
||||
$content .= 'egw.set_preferences('.$ab_preferences.", 'addressbook', egw && egw.window !== window);\n";
|
||||
$content .= 'egw.set_user('.$user.", egw && egw.window !== window);\n";
|
||||
$content = "import './js/jsapi/egw_preferences.js';\nimport './js/jsapi/egw_user.js';\n\n";
|
||||
$content .= 'window.egw.set_preferences('.$preferences.", 'common', window.egw && window.egw.window !== window);\n";
|
||||
$content .= 'window.egw.set_preferences('.$ab_preferences.", 'addressbook', window.egw && window.egw.window !== window);\n";
|
||||
$content .= 'window.egw.set_user('.$user.", window.egw && egw.window !== window.window);\n";
|
||||
|
||||
// we run our own gzip compression, to set a correct Content-Length of the encoded content
|
||||
if (in_array('gzip', explode(',',$_SERVER['HTTP_ACCEPT_ENCODING'])) && function_exists('gzencode'))
|
||||
|
@ -28,7 +28,7 @@ if ($GLOBALS['egw_info']['user']['apps']['notifications'])
|
||||
$minjs = $GLOBALS['egw_info']['server']['debug_minify'] === 'True' ? '' : '.min';
|
||||
echo '<script src="'. $GLOBALS['egw_info']['server']['webserver_url']. '/notifications/js/notificationajaxpopup'.$minjs.'.js?'.
|
||||
filemtime(EGW_SERVER_ROOT.'/notifications/js/notificationajaxpopup'.$minjs.'.js').
|
||||
'" type="text/javascript" id="notifications_script_id" data-poll-interval="'.$popup_poll_interval.
|
||||
'" type="module" id="notifications_script_id" data-poll-interval="'.$popup_poll_interval.
|
||||
'" data-langRequire="'. htmlspecialchars(json_encode($langRequire)).'"></script>';
|
||||
echo '
|
||||
<div id="egwpopup" style="display: none; z-index: 999;">
|
||||
|
@ -9,11 +9,17 @@
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import '../../vendor/bower-asset/jquery/dist/jquery.js';
|
||||
|
||||
/**
|
||||
* Installs app.notifications used to poll notifications from server and display them
|
||||
*/
|
||||
(function()
|
||||
{
|
||||
const egw = window.egw; // fix undefined egw
|
||||
|
||||
var notifymessages = {};
|
||||
|
||||
var _currentRawData = [];
|
||||
@ -905,9 +911,9 @@
|
||||
return counter;
|
||||
};
|
||||
|
||||
var lab = egw_LAB || $LAB;
|
||||
var self = notifications;
|
||||
lab.wait(function(){
|
||||
window.egw_ready.then(function()
|
||||
{
|
||||
var langRequire = jQuery('#notifications_script_id').attr('data-langRequire');
|
||||
egw.langRequire(window, [JSON.parse(langRequire)], function()
|
||||
{
|
||||
|
@ -13,6 +13,10 @@
|
||||
framework.fw_desktop;
|
||||
/pixelegg/js/slider.js;
|
||||
*/
|
||||
import '../../vendor/bower-asset/jquery/dist/jquery.js';
|
||||
import '../../api/js/framework/fw_desktop.js';
|
||||
import './slider.js';
|
||||
|
||||
(function(window){
|
||||
"use strict";
|
||||
|
||||
@ -20,7 +24,7 @@
|
||||
* jdots framework object defenition
|
||||
* here we can add framework methods and also override fw_desktop methods if it is neccessary
|
||||
*/
|
||||
var fw_pixelegg = fw_desktop.extend(
|
||||
window.fw_pixelegg = fw_desktop.extend(
|
||||
{
|
||||
/**
|
||||
* Callback to calculate height of browser iframe or div
|
||||
@ -111,7 +115,7 @@
|
||||
/**
|
||||
* Initialise framework
|
||||
*/
|
||||
egw_LAB.wait(function() {
|
||||
window.egw_ready.then(function() {
|
||||
function egw_setSideboxSize(_size)
|
||||
{
|
||||
document.getElementById('egw_fw_main').style.marginLeft = _size + 'px';
|
||||
|
@ -1,4 +1,4 @@
|
||||
<script src="./api/js/login.js" type="text/javascript"></script>
|
||||
<script src="./api/js/login.js" type="module"></script>
|
||||
|
||||
|
||||
<div id="loginMainDiv" style="background-image:url({background_file})" class="{stock_background_class}">
|
||||
|
Loading…
Reference in New Issue
Block a user