From e36c6c4cecedd8b601bb3a4432e4025a0f1b6382 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Mon, 1 Mar 2021 11:50:22 +0200 Subject: [PATCH] move global et2_call function to egw.call and egw.apply methods, ensuring app.js is loaded, if not yet loaded, also using that as apply plugin for egw.json --- api/js/framework/fw_base.js | 2 +- api/js/jsapi/egw.js | 38 +++---------- api/js/jsapi/egw_global.d.ts | 18 +++++++ api/js/jsapi/egw_json.js | 102 ++++++++++++++++++++++++----------- 4 files changed, 95 insertions(+), 65 deletions(-) diff --git a/api/js/framework/fw_base.js b/api/js/framework/fw_base.js index 4821fbb61f..237d347c17 100644 --- a/api/js/framework/fw_base.js +++ b/api/js/framework/fw_base.js @@ -708,7 +708,7 @@ var fw_base = (function(){ "use strict"; return Class.extend( tabLinkHandler: function(_link, _extra) { - var app = this.parseAppFromUrl(_link); + var app = typeof _extra.appName === 'string' ? _extra : this.parseAppFromUrl(_link); if (app) { var appname = app.appName+"-"+btoa(_extra.id ? _extra.id : _link).replace(/=/g,'i'); diff --git a/api/js/jsapi/egw.js b/api/js/jsapi/egw.js index 5192a953de..86951e5d54 100644 --- a/api/js/jsapi/egw.js +++ b/api/js/jsapi/egw.js @@ -472,39 +472,13 @@ var exports = {}; * Call a function specified by it's name (possibly dot separated, eg. "app.myapp.myfunc") * * @param {string} _func dot-separated function name - * variable number of arguments - * @returns {Boolean} + * @param {mixed} ...args variable number of arguments + * @returns {Mixed|Promise} + * @deprecated use egw.call(_func, ...) or egw.apply(_func, args) */ function et2_call(_func) { - var args = [].slice.call(arguments); // convert arguments to array - var func = args.shift(); - var parent = window; - - if (typeof _func == 'string') - { - var parts = _func.split('.'); - func = parts.pop(); - for(var i=0; i < parts.length; ++i) - { - if (typeof parent[parts[i]] != 'undefined') - { - parent = parent[parts[i]]; - } - // check if we need a not yet instanciated app.js object --> instanciate it now - else if (i == 1 && parts[0] == 'app' && typeof app.classes[parts[1]] == 'function') - { - parent = parent[parts[1]] = new app.classes[parts[1]](); - } - } - if (typeof parent[func] == 'function') - { - func = parent[func]; - } - } - if (typeof func != 'function') - { - throw _func+" is not a function!"; - } - return func.apply(parent, args); + let args = [].slice.call(arguments); // convert arguments to array + let func = args.shift(); + return egw.apply(func, args, window); } diff --git a/api/js/jsapi/egw_global.d.ts b/api/js/jsapi/egw_global.d.ts index 1c062cb719..7a3ec78573 100644 --- a/api/js/jsapi/egw_global.d.ts +++ b/api/js/jsapi/egw_global.d.ts @@ -792,6 +792,24 @@ declare interface IegwWndLocal extends IegwGlobal */ request(_menuaction: string, param2: any[]): Promise; + /** + * Call a function specified by it's name (possibly dot separated, eg. "app.myapp.myfunc") + * + * @param {string} _func dot-separated function name + * @param {mixed} ...args variable number of arguments + * @returns {mixed|Promise} + */ + call(_func : string|Function, ...args : any) : Promise|any + /** + * Call a function specified by it's name (possibly dot separated, eg. "app.myapp.myfunc") + * + * @param {string} _func dot-separated function name + * @param {array} args arguments + * @param {object} _context + * @returns {mixed|Promise} + */ + apply(_func : string|Function, args : Array, _context : Object) : Promise|any + /** * Registers a new handler plugin. * diff --git a/api/js/jsapi/egw_json.js b/api/js/jsapi/egw_json.js index c9abfd9c45..2a7e441b08 100644 --- a/api/js/jsapi/egw_json.js +++ b/api/js/jsapi/egw_json.js @@ -481,6 +481,74 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd) return myPromise; }, + /** + * Call a function specified by it's name (possibly dot separated, eg. "app.myapp.myfunc") + * + * @param {string} _func dot-separated function name + * @param {mixed} ...args variable number of arguments + * @returns {mixed|Promise} + */ + call: function(_func) + { + let args = [].slice.call(arguments); // convert arguments to array + let func = args.shift(); + + return this.apply(func, args); + }, + + /** + * Call a function specified by it's name (possibly dot separated, eg. "app.myapp.myfunc") + * + * @param {string} _func dot-separated function name + * @param {array} args arguments + * @param {object} _context + * @returns {mixed|Promise} + */ + apply: function(_func, args, _context) + { + let parent = _context || window; + let func; + + if (typeof _func === 'string') + { + let parts = _func.split('.'); + func = parts.pop(); + for(var i=0; i < parts.length; ++i) + { + if (typeof parent[parts[i]] !== 'undefined') + { + parent = parent[parts[i]]; + } + // check if we need a not yet included app.js object --> include it now and return a Promise + else if (i == 1 && parts[0] == 'app' && typeof app.classes[parts[1]] === 'undefined') + { + const self = this; + return new Promise(function(resolve, reject) + { + self.includeJS('/'+parts[1]+'/js/app.js', function () + { + resolve(self.apply(_func, args)); + }, self, self.webserverUrl); + }); + } + // check if we need a not yet instanciated app.js object --> instanciate it now + else if (i == 1 && parts[0] == 'app' && typeof app.classes[parts[1]] === 'function') + { + parent = parent[parts[1]] = new app.classes[parts[1]](); + } + } + if (typeof parent[func] == 'function') + { + func = parent[func]; + } + } + if (typeof func != 'function') + { + throw _func+" is not a function!"; + } + return func.apply(parent, args); + }, + /** * Registers a new handler plugin. * @@ -645,38 +713,8 @@ egw.extend('json', egw.MODULE_WND_LOCAL, function(_app, _wnd) json.registerJSONPlugin(function(type, res, req) { if (typeof res.data.func == 'string') { - var parts = res.data.func.split('.'); - var func = parts.pop(); - var parent = req.egw.window; - for(var i=0; i < parts.length; ++i) - { - if (typeof parent[parts[i]] != 'undefined') - { - parent = parent[parts[i]]; - } - // check if we need a not yet instanciated app.js object --> instanciate it now - else if (i == 1 && parts[0] == 'app' && typeof req.egw.window.app.classes[parts[1]] == 'function') - { - parent = parent[parts[1]] = new req.egw.window.app.classes[parts[1]](); - } - } - if (typeof parent[func] == 'function') - { - try - { - parent[func].apply(parent, res.data.parms); - } - catch (e) - { - req.egw.debug('error', e.message, ' in function', res.data.func, - 'Parameters', res.data.parms); - } - return true; - } - else - { - throw '"' + res.data.func + '" is not a callable function (type is ' + typeof parent[func] + ')'; - } + req.egw.apply(res.data.func, res.data.parms, req.egw.window); + return true; } throw 'Invalid parameters'; }, null, 'apply');