From d49f8bc45fe5d53cfeaa6911ace2d0d1cf1cd280 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 17 Mar 2016 18:12:36 +0000 Subject: [PATCH] fix situation where multiple app.js objects are used, eg. InfoLog and CRM view in Addressbook: - etemplate2 creates a private app object instead of using window.app with just prototypes, if template is not from current app - fixed all cases where window.app was used to use just app, to use evtl. private object - app_base no longer assigns itself to window.app (window.app[this.appname] = this), as that breaks private app objects - et2_compileLegacyJS replaces app.appname with widget.getInstanceManager().app_obj.appname - etemplate2 stores either private or global app object in app_obj attribute --- etemplate/js/et2_core_common.js | 2 +- etemplate/js/et2_core_legacyJSFunctions.js | 7 +++- etemplate/js/et2_extension_nextmatch.js | 6 +-- etemplate/js/etemplate2.js | 16 ++++---- infolog/js/app.js | 5 ++- phpgwapi/js/egw_action/egw_action_common.js | 20 ++++----- phpgwapi/js/egw_json.js | 14 +++---- phpgwapi/js/framework/fw_browser.js | 10 ++--- phpgwapi/js/jsapi/app_base.js | 45 ++++++++++----------- phpgwapi/js/jsapi/egw.js | 8 ++-- 10 files changed, 70 insertions(+), 63 deletions(-) diff --git a/etemplate/js/et2_core_common.js b/etemplate/js/et2_core_common.js index d5457e76c3..fc1f454722 100644 --- a/etemplate/js/et2_core_common.js +++ b/etemplate/js/et2_core_common.js @@ -237,7 +237,7 @@ function et2_checkType(_val, _type, _attr, _widget) // Check to see if it's a string in app.appname.function format, and wrap it in // a closure to make sure context is preserved - if(typeof _val == "string" && _val.substr(0,4) == "app." && window.app) + if(typeof _val == "string" && _val.substr(0,4) == "app." && app) { var parts = _val.split('.'); var func = parts.pop(); diff --git a/etemplate/js/et2_core_legacyJSFunctions.js b/etemplate/js/et2_core_legacyJSFunctions.js index 25eef39566..e312fe0f4d 100644 --- a/etemplate/js/et2_core_legacyJSFunctions.js +++ b/etemplate/js/et2_core_legacyJSFunctions.js @@ -28,8 +28,8 @@ * - window.open() replaces it with egw_openWindowCentered2() * - xajax_doXMLHTTP('etemplate. replace ajax calls in widgets with special handler not requiring etemplate run rights * - * @param string _val onclick, onchange, ... action - * @param string _cname name-prefix / name-space + * @param {string} _val onclick, onchange, ... action + * @param {et2_widget} widget * @ToDo replace xajax_doXMLHTTP with egw.json() * @ToDo replace (common) cases of confirm with new dialog, idea: calling function supplys function to call after confirm * @ToDo template::styles(name) inserts the styles of a named template @@ -131,6 +131,9 @@ { _code += '(ev,widget)'; } + // use app object from etemplate2, which might be private and not just window.app + _code = _code.replace(/(window\.)?app\./, 'widget.getInstanceManager().app_obj.'); + var func = new Function('ev', 'widget', _code); } catch(e) { _widget.egw().debug('error', 'Error while compiling JS code ', _code); diff --git a/etemplate/js/et2_extension_nextmatch.js b/etemplate/js/et2_extension_nextmatch.js index f7dfb363d9..aabd72525c 100644 --- a/etemplate/js/et2_extension_nextmatch.js +++ b/etemplate/js/et2_extension_nextmatch.js @@ -544,10 +544,10 @@ var et2_nextmatch = (function(){ "use strict"; return et2_DOMWidget.extend([et2_ // Highlight matching favorite in sidebox if(this.getInstanceManager().app) { - var app = this.getInstanceManager().app; - if(window.app[app] && window.app[app].highlight_favorite) + var appname = this.getInstanceManager().app; + if(app[appname] && app[appname].highlight_favorite) { - window.app[app].highlight_favorite(); + app[appname].highlight_favorite(); } } } diff --git a/etemplate/js/etemplate2.js b/etemplate/js/etemplate2.js index acd13b1207..e23c94fbcb 100644 --- a/etemplate/js/etemplate2.js +++ b/etemplate/js/etemplate2.js @@ -353,6 +353,12 @@ etemplate2.prototype.load = function(_name, _url, _data, _callback, _app) egw().debug("info", "Loaded data", _data); var currentapp = this.app = _data.currentapp || egw().app_name(); + var appname = _name.split('.')[0]; + // if no app object provided and template app is not currentapp (eg. infolog CRM view) + // create private app object / closure with just classes / prototypes + if (!_app && appname && appname != currentapp) app = { classes: window.app.classes }; + // remember used app object, to eg. use: onchange="widget.getInstanceMgr().app_object[app].callback()" + this.app_obj = app; // extract $content['msg'] and call egw.message() with it var msg = _data.content.msg; @@ -390,10 +396,6 @@ etemplate2.prototype.load = function(_name, _url, _data, _callback, _app) if (!$j.isArray(_data.langRequire)) _data.langRequire = []; egw(currentapp, window).langRequire(window, _data.langRequire, function() { - // Appname should be first part of the template name - var split = _name.split('.'); - var appname = split[0]; - // Initialize application js var app_callback = null; // Only initialize once @@ -407,7 +409,7 @@ etemplate2.prototype.load = function(_name, _url, _data, _callback, _app) { (function() { new app[appname]();}).call(); } - else if (typeof app[appname] !== "object") + else if (appname && typeof app[appname] !== "object") { egw.debug("warn", "Did not load '%s' JS object",appname); } @@ -531,11 +533,11 @@ etemplate2.prototype.load = function(_name, _url, _data, _callback, _app) { app_callback.call(window,this,_name); } - if(appname != this.app && typeof window.app[this.app] == "object") + if(appname && appname != this.app && typeof app[this.app] == "object") { // Loaded a template from a different application? // Let the application that loaded it know too - window.app[this.app].et2_ready(this, this.name); + app[this.app].et2_ready(this, this.name); } $j(this.DOMContainer).trigger('load', this); diff --git a/infolog/js/app.js b/infolog/js/app.js index d164442f5e..310b5b61bd 100644 --- a/infolog/js/app.js +++ b/infolog/js/app.js @@ -75,7 +75,7 @@ app.classes.infolog = AppJS.extend( } else { - // Trigger print command if the infolog oppend for printing porpuse + // Trigger print command if the infolog oppend for printing purpose this.infolog_print_preview_onload(); } break; @@ -766,6 +766,9 @@ app.classes.infolog = AppJS.extend( */ _get_stylite: function(callback,attrs) { + // use app object from etemplate2, which might be private and not just window.app + var app = this.et2.getInstanceManager().app_obj; + if (!app.stylite) { var self = this; diff --git a/phpgwapi/js/egw_action/egw_action_common.js b/phpgwapi/js/egw_action/egw_action_common.js index 26f706e895..196da77642 100644 --- a/phpgwapi/js/egw_action/egw_action_common.js +++ b/phpgwapi/js/egw_action/egw_action_common.js @@ -236,7 +236,7 @@ egwEventQueue.prototype.queue = function(_proc, _context, _args, _id) var key = ""; - // _id must be a string and evaluate to true - if this is not + // _id must be a string and evaluate to true - if this is not // generate an unique key. if (typeof _id != "string" || !_id) { @@ -366,10 +366,10 @@ egwFnct.prototype.setValue = function(_value) { this.fnct = _value; } - + // Global function (on window) else if (typeof _value == "string" && - _value.substr(0,11) == "javaScript:" && + _value.substr(0,11) == "javaScript:" && typeof window[_value.substr(11)] == "function") { this.fnct = window[_value.substr(11)]; @@ -379,20 +379,20 @@ egwFnct.prototype.setValue = function(_value) { this.value = _value; } - + // egw application specific function else if (typeof _value == "string" && - _value.substr(0,15) == "javaScript:app." && window.app) + _value.substr(0,15) == "javaScript:app." && app) { var parts = _value.split("."); - if(parts.length == 3 && typeof window.app[parts[1]] == "object" && - typeof window.app[parts[1]][parts[2]] == "function") + if(parts.length == 3 && typeof app[parts[1]] == "object" && + typeof app[parts[1]][parts[2]] == "function") { - this.fnct = window.app[parts[1]][parts[2]]; - this.context = window.app[parts[1]]; + this.fnct = app[parts[1]][parts[2]]; + this.context = app[parts[1]]; } } - + // Something, but could not figure it out else if (_value) { diff --git a/phpgwapi/js/egw_json.js b/phpgwapi/js/egw_json.js index dfa3a85bf8..75ee1a1c87 100644 --- a/phpgwapi/js/egw_json.js +++ b/phpgwapi/js/egw_json.js @@ -481,22 +481,22 @@ egw_json_request.prototype.handleResponse = function(data, textStatus, XMLHttpRe } hasResponse = true; } else if (typeof res.data.func == "string" && - res.data.func.substr(0,4) == "app." && window.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 window.app[parts[1]] == 'undefined' && - typeof window.app.classes[parts[1]] == 'function') + if (parts.length == 3 && typeof app[parts[1]] == 'undefined' && + typeof app.classes[parts[1]] == 'function') { - window.app[parts[1]] = new window.app.classes[parts[1]](); + app[parts[1]] = new app.classes[parts[1]](); } - if(parts.length == 3 && typeof window.app[parts[1]] == "object" && - typeof window.app[parts[1]][parts[2]] == "function") + if(parts.length == 3 && typeof app[parts[1]] == "object" && + typeof app[parts[1]][parts[2]] == "function") { try { - this.context = window.app[parts[1]][parts[2]].apply(window.app[parts[1]], res.data.parms); + this.context = app[parts[1]][parts[2]].apply(app[parts[1]], res.data.parms); } catch (e) { diff --git a/phpgwapi/js/framework/fw_browser.js b/phpgwapi/js/framework/fw_browser.js index 4e5a822cfe..6f8198a41f 100644 --- a/phpgwapi/js/framework/fw_browser.js +++ b/phpgwapi/js/framework/fw_browser.js @@ -130,10 +130,10 @@ var fw_browser = (function(){ "use strict"; return Class.extend( browse: function(_url) { // check if app has its own linkHandler and it accepts the link (returns true), or returns different url instead - if (typeof window.app == 'object' && typeof window.app[this.app.appName] == 'object' && - typeof window.app[this.app.appName].linkHandler == 'function') + if (typeof app == 'object' && typeof app[this.app.appName] == 'object' && + typeof app[this.app.appName].linkHandler == 'function') { - var ret = window.app[this.app.appName].linkHandler.call(window.app[this.app.appName], _url); + var ret = app[this.app.appName].linkHandler.call(app[this.app.appName], _url); { if (ret === true) return this.loadingDeferred.promise(); if (typeof ret === 'string') @@ -195,9 +195,9 @@ var fw_browser = (function(){ "use strict"; return Class.extend( } // Destroy application js - if(window.app[this.app.appName] && window.app[this.app.appName].destroy) + if(app[this.app.appName] && app[this.app.appName].destroy) { - window.app[this.app.appName].destroy(); + app[this.app.appName].destroy(); } // Unload etemplate2, if there diff --git a/phpgwapi/js/jsapi/app_base.js b/phpgwapi/js/jsapi/app_base.js index 82ae72f4b7..a12661463c 100644 --- a/phpgwapi/js/jsapi/app_base.js +++ b/phpgwapi/js/jsapi/app_base.js @@ -117,8 +117,6 @@ var AppJS = (function(){ "use strict"; return Class.extend( * is not yet ready. */ init: function() { - window.app[this.appname] = this; - this.egw = egw(this.appname, window); // Initialize sidebox for non-popups. @@ -132,7 +130,7 @@ var AppJS = (function(){ "use strict"; return Class.extend( sidebox= $j('#favorite_sidebox_'+this.appname,egw_fw.sidemenuDiv); } // Make sure we're running in the top window when we init sidebox - if(window.top.app[this.appname] !== this && window.top.app[this.appname]) + if(window.app[this.appname] === this && window.top.app[this.appname] !== this && window.top.app[this.appname]) { window.top.app[this.appname]._init_sidebox(sidebox); } @@ -145,14 +143,14 @@ var AppJS = (function(){ "use strict"; return Class.extend( /** * Clean up any created objects & references - * @param {pbject} _app local app object + * @param {object} _app local app object */ destroy: function(_app) { delete this.et2; if (this.sidebox) this.sidebox.off(); delete this.sidebox; - if (!_app) delete window.app[this.appname]; + if (!_app) delete app[this.appname]; }, /** @@ -389,7 +387,7 @@ var AppJS = (function(){ "use strict"; return Class.extend( * @param {object} _action * @param {object} _senders * @param {boolean} _noEdit defines whether to set edit button or not default is false - * @param {function} callback function to run after et2 is loaded + * @param {function} et2_callback function to run after et2 is loaded */ viewEntry: function(_action, _senders, _noEdit, et2_callback) { @@ -1156,6 +1154,8 @@ var AppJS = (function(){ "use strict"; return Class.extend( * ] * } * } + * + * @param {DOMNode} div */ egwTutorial_init: function(div) { @@ -1536,23 +1536,22 @@ var AppJS = (function(){ "use strict"; return Class.extend( var dialog = function(_content, _callback) { return et2_createWidget("dialog", { - callback: function(_button_id, _value) { - if (typeof _callback == "function") - { - _callback.call(this, _button_id, _value.value); - } - }, - title: egw.lang('PGP Encryption Installation'), - buttons: buttons, - dialog_type: 'info', - value: { - content: _content - }, - template: egw.webserverUrl+'/etemplate/templates/default/pgp_installation.xet', - class: "pgp_installation", - modal: true, - //resizable:false, - + callback: function(_button_id, _value) { + if (typeof _callback == "function") + { + _callback.call(this, _button_id, _value.value); + } + }, + title: egw.lang('PGP Encryption Installation'), + buttons: buttons, + dialog_type: 'info', + value: { + content: _content + }, + template: egw.webserverUrl+'/etemplate/templates/default/pgp_installation.xet', + class: "pgp_installation", + modal: true + //resizable:false, }); }; var content = [ diff --git a/phpgwapi/js/jsapi/egw.js b/phpgwapi/js/jsapi/egw.js index 12167fc8ab..f26ebe1bbf 100644 --- a/phpgwapi/js/jsapi/egw.js +++ b/phpgwapi/js/jsapi/egw.js @@ -227,9 +227,9 @@ // instanciate app object var appname = window.egw_appName; - if (window.app && typeof window.app[appname] != 'object' && typeof window.app.classes[appname] == 'function') + if (app && typeof app[appname] != 'object' && typeof app.classes[appname] == 'function') { - window.app[appname] = new window.app.classes[appname](); + app[appname] = new app.classes[appname](); } // set sidebox for tabed templates @@ -392,9 +392,9 @@ function et2_call(_func) parent = parent[parts[i]]; } // check if we need a not yet instanciated app.js object --> instanciate it now - else if (i == 1 && parts[0] == 'app' && typeof window.app.classes[parts[1]] == 'function') + else if (i == 1 && parts[0] == 'app' && typeof app.classes[parts[1]] == 'function') { - parent = parent[parts[1]] = new window.app.classes[parts[1]](); + parent = parent[parts[1]] = new app.classes[parts[1]](); } } if (typeof parent[func] == 'function')