The results of Guy Bedford's help

Egroupware will load into addressbook & show rows
Most base files should be bundled server-side & included
rollup.config.js controls the process

Still needs work:
- consider /dist directory for best-practice
- cleanup
- other built-in apps
- EPL / external apps need Guy's multi-stage work
This commit is contained in:
nathangray 2021-06-25 14:49:24 -06:00
parent e822511be4
commit 3add958afa
45 changed files with 3546 additions and 7523 deletions

View File

@ -13,7 +13,7 @@
*/ */
import { EgwApp } from '../../api/js/jsapi/egw_app'; import { EgwApp } from '../../api/js/jsapi/egw_app';
import { et2_nextmatch } from "../../api/js/etemplate/et2_extension_nextmatch"; import { et2_nextmatch } from "../../api/js/etemplate/et2_extension_nextmatch";
import { egw } from "../../api/js/jsapi/egw_global"; import { egw } from "../../api/js/jsapi/egw_global.js";
/** /**
* UI for Addressbook CRM view * UI for Addressbook CRM view
* *

View File

@ -16,7 +16,7 @@
import {EgwApp, PushData} from '../../api/js/jsapi/egw_app'; import {EgwApp, PushData} from '../../api/js/jsapi/egw_app';
import {etemplate2} from "../../api/js/etemplate/etemplate2"; import {etemplate2} from "../../api/js/etemplate/etemplate2";
import {et2_nextmatch} from "../../api/js/etemplate/et2_extension_nextmatch"; import {et2_nextmatch} from "../../api/js/etemplate/et2_extension_nextmatch";
import {egw} from "../../api/js/jsapi/egw_global"; import {egw} from "../../api/js/jsapi/egw_global.js";
/** /**
* UI for Addressbook CRM view * UI for Addressbook CRM view

File diff suppressed because it is too large Load Diff

View File

@ -17,8 +17,8 @@ import {EgwApp, PushData} from '../../api/js/jsapi/egw_app';
import {etemplate2} from "../../api/js/etemplate/etemplate2"; import {etemplate2} from "../../api/js/etemplate/etemplate2";
import {et2_dialog} from "../../api/js/etemplate/et2_widget_dialog"; import {et2_dialog} from "../../api/js/etemplate/et2_widget_dialog";
import {et2_selectbox} from "../../api/js/etemplate/et2_widget_selectbox"; import {et2_selectbox} from "../../api/js/etemplate/et2_widget_selectbox";
import {nm_action, fetchAll} from "../../api/js/etemplate/et2_extension_nextmatch_actions.js"; import {nm_action, fetchAll} from "../../api/js/etemplate/et2_extension_nextmatch_actions";
import "./CRM.js"; import "./CRM";
import {egw} from "../../api/js/jsapi/egw_global"; import {egw} from "../../api/js/jsapi/egw_global";
/** /**

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ import {EgwApp, PushData} from '../../api/js/jsapi/egw_app';
import {etemplate2} from "../../api/js/etemplate/etemplate2"; import {etemplate2} from "../../api/js/etemplate/etemplate2";
import {et2_dialog} from "../../api/js/etemplate/et2_widget_dialog"; import {et2_dialog} from "../../api/js/etemplate/et2_widget_dialog";
import {et2_createWidget} from "../../api/js/etemplate/et2_core_widget"; import {et2_createWidget} from "../../api/js/etemplate/et2_core_widget";
import {egw} from "../../api/js/jsapi/egw_global"; import {egw} from "../../api/js/jsapi/egw_global.js";
import {egwActionObject, egwAction} from '../../api/js/egw_action/egw_action.js'; import {egwActionObject, egwAction} from '../../api/js/egw_action/egw_action.js';
/** /**
* UI for Admin * UI for Admin

View File

@ -43,9 +43,7 @@ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $
exit; exit;
} }
$content = "import './js/jsapi/egw_config.js';\n"; $content = 'egw.set_configs('.$config.", window.egw && window.egw.window !== window);\n";
$content .= "import './js/jsapi/egw_links.js';\n\n";
$content .= 'egw.set_configs('.$config.", window.egw && window.egw.window !== window);\n";
$content .= 'egw.set_link_registry('.$link_registry.", undefined, window.egw && window.egw.window !== window);\n"; $content .= '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 // we run our own gzip compression, to set a correct Content-Length of the encoded content

View File

@ -48,7 +48,7 @@ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $
exit; exit;
} }
if (empty($_GET['debug'])) $content = "import './js/jsapi/egw_images.js';\n\negw.set_images(".$content.", egw && egw.window !== window);\n"; if (empty($_GET['debug'])) $content = "\n\negw.set_images(".$content.", egw && egw.window !== window);\n";
// we run our own gzip compression, to set a correct Content-Length of the encoded content // 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')) if (in_array('gzip', explode(',',$_SERVER['HTTP_ACCEPT_ENCODING'])) && function_exists('gzencode'))

View File

@ -11,6 +11,7 @@
/*egw:uses /*egw:uses
egw_action_common; egw_action_common;
*/ */
import "../jsapi/egw.js";
import { import {
EGW_AO_STATE_NORMAL, EGW_AO_STATE_NORMAL,
EGW_AO_STATE_VISIBLE, EGW_AO_STATE_VISIBLE,

View File

@ -7,7 +7,10 @@
* @link https://www.egroupware.org * @link https://www.egroupware.org
* @author Andreas Stöckel * @author Andreas Stöckel
*/ */
import { egw } from "../jsapi/egw_global"; import "../../../vendor/bower-asset/jquery/dist/jquery.min.js";
import "../../../vendor/bower-asset/jquery-ui/jquery-ui.js";
import "../jquery/jquery.noconflict.js";
import { egw } from "../jsapi/egw_global.js";
/** /**
* Loads the given URL asynchronously from the server * Loads the given URL asynchronously from the server
* *

View File

@ -8,7 +8,10 @@
* @author Andreas Stöckel * @author Andreas Stöckel
*/ */
import {egw} from "../jsapi/egw_global"; import "../../../vendor/bower-asset/jquery/dist/jquery.min.js";
import "../../../vendor/bower-asset/jquery-ui/jquery-ui.js";
import "../jquery/jquery.noconflict.js";
import {egw} from "../jsapi/egw_global.js";
/** /**
* Loads the given URL asynchronously from the server * Loads the given URL asynchronously from the server

View File

@ -15,6 +15,7 @@
et2_core_inputWidget; et2_core_inputWidget;
et2_core_valueWidget; et2_core_valueWidget;
*/ */
import "../../../vendor/bower-asset/jquery-ui/jquery-ui.js";
import { et2_csvSplit, et2_no_init } from "./et2_core_common"; import { et2_csvSplit, et2_no_init } from "./et2_core_common";
import { ClassWithAttributes } from "./et2_core_inheritance"; import { ClassWithAttributes } from "./et2_core_inheritance";
import { et2_createWidget, et2_register_widget, et2_widget } from "./et2_core_widget"; import { et2_createWidget, et2_register_widget, et2_widget } from "./et2_core_widget";

View File

@ -17,6 +17,7 @@
et2_core_valueWidget; et2_core_valueWidget;
*/ */
import "../../../vendor/bower-asset/jquery-ui/jquery-ui.js";
import {et2_csvSplit, et2_no_init} from "./et2_core_common"; import {et2_csvSplit, et2_no_init} from "./et2_core_common";
import {ClassWithAttributes} from "./et2_core_inheritance"; import {ClassWithAttributes} from "./et2_core_inheritance";
import {et2_createWidget, et2_register_widget, et2_widget, WidgetConfig} from "./et2_core_widget"; import {et2_createWidget, et2_register_widget, et2_widget, WidgetConfig} from "./et2_core_widget";

View File

@ -12,6 +12,7 @@
et2_core_inputWidget; et2_core_inputWidget;
api.Resumable.resumable; api.Resumable.resumable;
*/ */
import "../Resumable/resumable.js";
import { et2_inputWidget } from "./et2_core_inputWidget"; import { et2_inputWidget } from "./et2_core_inputWidget";
import { et2_register_widget } from "./et2_core_widget"; import { et2_register_widget } from "./et2_core_widget";
import { ClassWithAttributes } from "./et2_core_inheritance"; import { ClassWithAttributes } from "./et2_core_inheritance";

View File

@ -13,7 +13,7 @@
et2_core_inputWidget; et2_core_inputWidget;
api.Resumable.resumable; api.Resumable.resumable;
*/ */
import "../Resumable/resumable.js";
import {et2_inputWidget} from "./et2_core_inputWidget"; import {et2_inputWidget} from "./et2_core_inputWidget";
import {et2_register_widget, WidgetConfig} from "./et2_core_widget"; import {et2_register_widget, WidgetConfig} from "./et2_core_widget";
import {ClassWithAttributes} from "./et2_core_inheritance"; import {ClassWithAttributes} from "./et2_core_inheritance";

View File

@ -16,6 +16,8 @@
et2_core_DOMWidget; et2_core_DOMWidget;
et2_core_inputWidget; et2_core_inputWidget;
*/ */
import "../../../vendor/bower-asset/jquery/dist/jquery.min.js";
import "../jquery/chosen/chosen.jquery.js";
import { et2_no_init } from "./et2_core_common"; import { et2_no_init } from "./et2_core_common";
import { ClassWithAttributes } from "./et2_core_inheritance"; import { ClassWithAttributes } from "./et2_core_inheritance";
import { et2_register_widget } from "./et2_core_widget"; import { et2_register_widget } from "./et2_core_widget";

View File

@ -18,6 +18,8 @@
et2_core_inputWidget; et2_core_inputWidget;
*/ */
import "../../../vendor/bower-asset/jquery/dist/jquery.min.js";
import "../jquery/chosen/chosen.jquery.js";
import {et2_no_init} from "./et2_core_common"; import {et2_no_init} from "./et2_core_common";
import {ClassWithAttributes} from "./et2_core_inheritance"; import {ClassWithAttributes} from "./et2_core_inheritance";
import {et2_register_widget, et2_widget, WidgetConfig} from "./et2_core_widget"; import {et2_register_widget, et2_widget, WidgetConfig} from "./et2_core_widget";

File diff suppressed because it is too large Load Diff

View File

@ -9,69 +9,6 @@
* @copyright EGroupware GmbH 2011-2021 * @copyright EGroupware GmbH 2011-2021
*/ */
/*egw:uses
// Include all widget classes here
et2_widget_template;
et2_widget_grid;
et2_widget_box;
et2_widget_hbox;
et2_widget_groupbox;
et2_widget_split;
et2_widget_button;
et2_widget_color;
et2_widget_description;
et2_widget_entry;
et2_widget_textbox;
et2_widget_number;
et2_widget_password;
et2_widget_url;
et2_widget_selectbox;
et2_widget_checkbox;
et2_widget_radiobox;
et2_widget_date;
et2_widget_dialog;
et2_widget_diff;
et2_widget_dropdown_button;
et2_widget_styles;
et2_widget_favorites;
et2_widget_html;
et2_widget_htmlarea;
et2_widget_tabs;
et2_widget_taglist;
et2_widget_timestamper;
et2_widget_toolbar;
et2_widget_tree;
et2_widget_historylog;
et2_widget_hrule;
et2_widget_image;
et2_widget_iframe;
et2_widget_file;
et2_widget_link;
et2_widget_progress;
et2_widget_portlet;
et2_widget_selectAccount;
et2_widget_ajaxSelect;
et2_widget_vfs;
et2_widget_video;
et2_widget_audio;
et2_widget_barcode;
et2_widget_itempicker;
et2_widget_script;
et2_widget_countdown;
et2_extension_nextmatch;
et2_extension_customfields;
// Requirements for the etemplate2 object
et2_core_common;
et2_core_xml;
et2_core_arrayMgr;
et2_core_interfaces;
et2_core_legacyJSFunctions;
// Include the client side api core
jsapi.egw_core;
jsapi.egw_json;
*/
import {et2_widget} from "./et2_core_widget"; import {et2_widget} from "./et2_core_widget";
import {et2_baseWidget, et2_container} from "./et2_core_baseWidget"; import {et2_baseWidget, et2_container} from "./et2_core_baseWidget";
@ -86,8 +23,9 @@ import {et2_nextmatch, et2_nextmatch_header_bar} from "./et2_extension_nextmatch
import {et2_tabbox} from "./et2_widget_tabs"; import {et2_tabbox} from "./et2_widget_tabs";
import '../jsapi/egw_json.js'; import '../jsapi/egw_json.js';
import {egwIsMobile} from "../egw_action/egw_action_common.js"; import {egwIsMobile} from "../egw_action/egw_action_common.js";
import './et2-button'; //import './et2-button';
/* Include all widget classes here, we only care about them registering, not importing anything /* Include all widget classes here, we only care about them registering, not importing anything*/
import './et2_widget_vfs'; // Vfs must be first (before et2_widget_file) due to import cycle
import './et2_widget_template'; import './et2_widget_template';
import './et2_widget_grid'; import './et2_widget_grid';
import './et2_widget_box'; import './et2_widget_box';
@ -128,7 +66,6 @@ import './et2_widget_progress';
import './et2_widget_portlet'; import './et2_widget_portlet';
import './et2_widget_selectAccount'; import './et2_widget_selectAccount';
import './et2_widget_ajaxSelect'; import './et2_widget_ajaxSelect';
import './et2_widget_vfs';
import './et2_widget_video'; import './et2_widget_video';
import './et2_widget_audio'; import './et2_widget_audio';
import './et2_widget_barcode'; import './et2_widget_barcode';
@ -137,7 +74,7 @@ import './et2_widget_script';
import './et2_widget_countdown'; import './et2_widget_countdown';
import './et2_extension_nextmatch'; import './et2_extension_nextmatch';
import './et2_extension_customfields'; import './et2_extension_customfields';
*/
/** /**
* The etemplate2 class manages a certain etemplate2 instance. * The etemplate2 class manages a certain etemplate2 instance.

View File

@ -24,6 +24,7 @@ window.fw_base = (function(){ "use strict"; return Class.extend(
* @returns {undefined} * @returns {undefined}
*/ */
init: function (_sidemenuId, _tabsId, _webserverUrl, _sideboxSizeCallback){ init: function (_sidemenuId, _tabsId, _webserverUrl, _sideboxSizeCallback){
window.framework = this;
/* Get the base div */ /* Get the base div */
this.sidemenuDiv = document.getElementById(_sidemenuId); this.sidemenuDiv = document.getElementById(_sidemenuId);
this.tabsDiv = document.getElementById(_tabsId); this.tabsDiv = document.getElementById(_tabsId);
@ -1380,4 +1381,4 @@ window.fw_base = (function(){ "use strict"; return Class.extend(
gauge.width(this.firstload_animation_gauge+"%"); gauge.width(this.firstload_animation_gauge+"%");
if (_gauge == 100) window.setTimeout(function(){jQuery('#egw_fw_firstload').remove();},1000); if (_gauge == 100) window.setTimeout(function(){jQuery('#egw_fw_firstload').remove();},1000);
} }
});}).call(this); });}).call(window);

View File

@ -14,7 +14,7 @@
import '../egw_action/egw_action_common.js'; import '../egw_action/egw_action_common.js';
import '../jsapi/egw_inheritance.js'; import '../jsapi/egw_inheritance.js';
import '../etemplate/etemplate2.js'; // otherwise et2_load json-response-handler is not (yet) available import '../etemplate/etemplate2'; // otherwise et2_load json-response-handler is not (yet) available
/** /**
* Constants definition * Constants definition
@ -378,4 +378,4 @@ window.fw_browser = (function(){ "use strict"; return Class.extend(
{ {
this.browse('about:blank', this.type == EGW_BROWSER_TYPE_IFRAME); this.browse('about:blank', this.type == EGW_BROWSER_TYPE_IFRAME);
} }
});}).call(this); });}).call(window);

View File

@ -16,6 +16,10 @@
framework.fw_classes; framework.fw_classes;
egw_inheritance.js; egw_inheritance.js;
*/ */
import "../../../vendor/bower-asset/jquery/dist/jquery.min.js";
import "../jquery/jquery.noconflict.js";
import "../../../vendor/bower-asset/jquery-ui/jquery-ui.js";
import './fw_base.js'; import './fw_base.js';
import './fw_browser.js'; import './fw_browser.js';
import './fw_ui.js'; import './fw_ui.js';

View File

@ -12,6 +12,10 @@
/api/js/jquery/mousewheel/mousewheel.js; /api/js/jquery/mousewheel/mousewheel.js;
egw_inheritance.js; egw_inheritance.js;
*/ */
import "../../../vendor/bower-asset/jquery/dist/jquery.min.js";
import "../jquery/jquery.noconflict.js";
import "../../../vendor/bower-asset/jquery-ui/jquery-ui.js";
import '../jsapi/egw_inheritance.js'; import '../jsapi/egw_inheritance.js';
/** /**
@ -189,7 +193,7 @@ window.fw_ui_sidemenu_entry = (function(){ "use strict"; return Class.extend(
jQuery(this.headerDiv).remove(); jQuery(this.headerDiv).remove();
jQuery(this.contentDiv).remove(); jQuery(this.contentDiv).remove();
} }
});}).call(this); });}).call(window);
/** /**
* *
@ -290,7 +294,7 @@ window.fw_ui_sidemenu = (function(){ "use strict"; return Class.extend(
this.entries = new Array(); this.entries = new Array();
} }
});}).call(this); });}).call(window);
/** /**
* Class: egw_fw_ui_tab * Class: egw_fw_ui_tab

View File

@ -113,7 +113,7 @@
this.SelectParser = SelectParser; this.SelectParser = SelectParser;
}).call(this); }).call(window);
(function() { (function() {
var AbstractChosen, root; var AbstractChosen, root;
@ -458,7 +458,7 @@
root.AbstractChosen = AbstractChosen; root.AbstractChosen = AbstractChosen;
}).call(this); }).call(window);
(function() { (function() {
var $, Chosen, root, _ref, var $, Chosen, root, _ref,
@ -1211,4 +1211,4 @@
root.Chosen = Chosen; root.Chosen = Chosen;
}).call(this); }).call(window);

View File

@ -12,13 +12,12 @@
egw_inheritance; egw_inheritance;
/api/js/es6-promise.min.js; /api/js/es6-promise.min.js;
*/ */
import {EgwApp} from "./egw_app";
import './egw_inheritance.js'; import './egw_inheritance.js';
import {et2_createWidget} from "../etemplate/et2_core_widget"; import {et2_createWidget} from "../etemplate/et2_core_widget";
import {etemplate2} from "../etemplate/etemplate2";
import {et2_dialog} from "../etemplate/et2_widget_dialog"; import {et2_dialog} from "../etemplate/et2_widget_dialog";
import {et2_nextmatch} from "../etemplate/et2_extension_nextmatch"; import {et2_nextmatch} from "../etemplate/et2_extension_nextmatch";
import {et2_favorites} from "../etemplate/et2_widget_favorites"; import {et2_favorites} from "../etemplate/et2_widget_favorites";
import {EgwApp} from "./egw_app";
/** /**
* Common base class for application javascript * Common base class for application javascript
@ -2061,4 +2060,4 @@ export const AppJS = (function(){ "use strict"; return Class.extend(
}); });
} }
});}).call(this); });}).call(window);

View File

@ -78,7 +78,7 @@ window.app = {classes: {}};
window.egw_appName = egw_script.getAttribute('data-app'); window.egw_appName = egw_script.getAttribute('data-app');
// split includes in legacy js and modules // split includes in legacy js and modules
const legacy_js_regexp = /\/dhtmlx|jquery|magicsuggest|resumable/; const legacy_js_regexp = /do_not_match_anything/;
// check if egw object was injected by window open // check if egw object was injected by window open
if (typeof window.egw == 'undefined') if (typeof window.egw == 'undefined')
@ -190,6 +190,7 @@ window.app = {classes: {}};
*/ */
async function legacy_js_import(_src, _baseurl) async function legacy_js_import(_src, _baseurl)
{ {
console.log("Legacy import: ", _src,_baseurl);
if (!Array.isArray(_src)) _src = [].concat(_src); if (!Array.isArray(_src)) _src = [].concat(_src);
return Promise.all(_src.map(src => { return Promise.all(_src.map(src => {
return new Promise(function(_resolve, _reject) return new Promise(function(_resolve, _reject)
@ -207,9 +208,8 @@ window.app = {classes: {}};
} }
const egw_modules = [ const egw_modules = [
'egw_core', 'egw_debug', 'egw_preferences', 'egw_lang', 'egw_links', 'egw_open', 'egw_user', // TODO: Dev mode should remove .min or remap it with importmap
'egw_config', 'egw_images', 'egw_jsonq', 'egw_files', 'egw_json', 'egw_store', 'egw_tooltip', 'egw_css', 'egw.min'
'egw_calendar', 'egw_ready', 'egw_data', 'egw_tail', 'egw_message', 'egw_notification', 'jsapi',
]; ];
// make our promise global, as legacy code calls egw_LAB.wait which we assign to egw_ready.then // make our promise global, as legacy code calls egw_LAB.wait which we assign to egw_ready.then
window.egw_LAB = window.egw_ready = window.egw_LAB = window.egw_ready =
@ -218,7 +218,7 @@ window.app = {classes: {}};
.catch((err) => {console.error(rel_src+": "+err.message)})))) .catch((err) => {console.error(rel_src+": "+err.message)}))))
.then(() => Promise.all(include.filter((src) => src.match(legacy_js_regexp) === null) //.reverse() .then(() => Promise.all(include.filter((src) => src.match(legacy_js_regexp) === null) //.reverse()
.map(rel_src => import(window.egw_webserverUrl+'/'+rel_src) .map(rel_src => import(window.egw_webserverUrl+'/'+rel_src)
.catch((err) => {console.error(rel_src+": "+err.message)}) .catch((err) => {window.setTimeout(() => {throw err;},0)})
))).then(() => ))).then(() =>
{ {
// We need to override the globalEval to mitigate potential execution of // We need to override the globalEval to mitigate potential execution of
@ -371,7 +371,7 @@ window.app = {classes: {}};
// load etemplate2 template(s) // load etemplate2 template(s)
jQuery('form.et2_container[data-etemplate]').each( function(index, node) jQuery('form.et2_container[data-etemplate]').each( function(index, node)
{ {
import('../etemplate/etemplate2.js').then((module) => { import('../etemplate/etemplate2').then((module) => {
const data = JSON.parse(node.getAttribute('data-etemplate')) || {}; const data = JSON.parse(node.getAttribute('data-etemplate')) || {};
if (popup || window.opener && !egwIsMobile()) { if (popup || window.opener && !egwIsMobile()) {
// Resize popup when et2 load is done // Resize popup when et2 load is done

View File

@ -18,6 +18,11 @@
// egw_jquery; // egw_jquery;
egw_css; egw_css;
*/ */
import "../../../vendor/bower-asset/jquery/dist/jquery.min.js";
import "../../../vendor/bower-asset/jquery-ui/jquery-ui.js";
import "../jquery/jquery.noconflict.js";
import "../jquery/jquery-ui-timepicker-addon.js";
import './egw_core.js'; import './egw_core.js';
/** /**

View File

@ -10,6 +10,7 @@
* @version $Id$ * @version $Id$
*/ */
import "./egw.js";
/** /**
* This code setups the egw namespace and adds the "extend" function, which is * This code setups the egw namespace and adds the "extend" function, which is
* used by extension modules to inject their content into the egw object. * used by extension modules to inject their content into the egw object.

View File

@ -14,7 +14,7 @@
egw_core; egw_core;
egw_debug; egw_debug;
*/ */
import './egw_core.js'; import './egw.js';
import './egw_json.js'; // for egw.registerJSONPlugin import './egw_json.js'; // for egw.registerJSONPlugin
/** /**

View File

@ -13,7 +13,7 @@
* @author Andreas Stöckel * @author Andreas Stöckel
*/ */
import {EgwApp} from "./egw_app"; //import {EgwApp} from "./egw_app";
/** /**
* Global egw object (for now created by the diverse JavaScript files) with a TypeScript interface * Global egw object (for now created by the diverse JavaScript files) with a TypeScript interface

View File

@ -33,7 +33,7 @@ egw.extend('jquery', egw.MODULE_WND_LOCAL, function(_app, _wnd)
// Include the jQuery and jQuery UI library. // Include the jQuery and jQuery UI library.
var token = ready.readyWaitFor(); var token = ready.readyWaitFor();
files.includeJS([ files.includeJS([
this.webserverUrl + '/vendor/bower-asset/jquery/dist/jquery.js', this.webserverUrl + '/vendor/bower-asset/jquery/dist/jquery.min.js',
this.webserverUrl + '/vendor/bower-asset/jquery-ui/jquery-ui.js', this.webserverUrl + '/vendor/bower-asset/jquery-ui/jquery-ui.js',
this.webserverUrl + '/api/js/jquery/jquery.html5_upload.js' this.webserverUrl + '/api/js/jquery/jquery.html5_upload.js'
], function () { ], function () {

View File

@ -17,7 +17,7 @@
egw_files; egw_files;
egw_debug; egw_debug;
*/ */
import './egw_core.js'; import './egw.js';
import './egw_utils.js'; import './egw_utils.js';
/** /**

View File

@ -0,0 +1,33 @@
/**
* Circular dependancy resolution file
* Here we force the order of includes
*/
import "../../../vendor/bower-asset/jquery/dist/jquery.min.js";
import "../../../vendor/bower-asset/jquery-ui/jquery-ui.js";
import "../jquery/jquery.noconflict.js";
import "./egw.js";
import "./egw_core.js";
import "./egw_debug.js";
import "./egw_preferences.js";
import "./egw_lang.js";
import "./egw_links.js";
import "./egw_open.js";
import "./egw_user.js";
import "./egw_config.js";
import "./egw_images.js";
import "./egw_jsonq.js";
import "./egw_files.js";
import "./egw_json.js";
import "./egw_store.js";
import "./egw_tooltip.js";
import "./egw_css.js";
import "./egw_calendar.js";
import "./egw_ready.js";
import "./egw_data.js";
import "./egw_tail.js";
import "./egw_inheritance.js";
import "./egw_message.js";
import "./egw_notification.js";
import "./jsapi.js";

View File

@ -60,7 +60,7 @@ if (!count(Api\Translation::$lang_arr))
Api\Translation::add_app($_GET['app'], 'en'); Api\Translation::add_app($_GET['app'], 'en');
} }
$content = "import './js/jsapi/egw_lang.js';\n\n"; $content = "";
// fix for phrases containing \n // fix for phrases containing \n
$content .= 'egw.set_lang_arr("'.$_GET['app'].'", '.str_replace('\\\\n', '\\n', $content .= '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)). json_encode(Api\Translation::$lang_arr, JSON_PARTIAL_OUTPUT_ON_ERROR|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE)).

View File

@ -141,7 +141,7 @@ class Etemplate extends Etemplate\Widget\Template
unset($hook_data); unset($hook_data);
// Include the etemplate2 javascript code // Include the etemplate2 javascript code
Framework::includeJS('etemplate', 'etemplate2', 'api'); //Framework::includeJS('etemplate', 'etemplate2', 'api');
if (!$this->rel_path) throw new Exception\AssertionFailed("No (valid) template '$this->name' found!"); if (!$this->rel_path) throw new Exception\AssertionFailed("No (valid) template '$this->name' found!");
@ -232,9 +232,13 @@ class Etemplate extends Etemplate\Widget\Template
} }
else // first call else // first call
{ {
// check if application of template has a app.js file --> load it // check if application of template has a app.js file --> load it, preferring local min file if there
list($app) = explode('.',$this->name); list($app) = explode('.',$this->name);
if (file_exists(EGW_SERVER_ROOT.'/'.$app.'/js/app.js')) if (file_exists(EGW_SERVER_ROOT.'/'.$app.'/js/app.min.js'))
{
Framework::includeJS('.','app.min',$app,true);
}
else if (file_exists(EGW_SERVER_ROOT.'/'.$app.'/js/app.js'))
{ {
Framework::includeJS('.','app',$app,true); Framework::includeJS('.','app',$app,true);
} }

View File

@ -167,10 +167,9 @@ abstract class Framework extends Framework\Extra
// always load jquery (not -ui) first // always load jquery (not -ui) first
'/vendor/bower-asset/jquery/dist/jquery.js', '/vendor/bower-asset/jquery/dist/jquery.js',
'/api/js/jquery/jquery.noconflict.js',
// always include javascript helper functions // always include javascript helper functions
'/api/js/jsapi/jsapi.js', '/api/js/jsapi.min.js',
'/api/js/jsapi/egw.js', '/api/js/jsapi/egw.min.js',
)); ));
} }
@ -1081,15 +1080,12 @@ abstract class Framework extends Framework\Extra
}, self::get_script_links(true, false, $map), array(1)); }, self::get_script_links(true, false, $map), array(1));
$extra['app'] = $GLOBALS['egw_info']['flags']['currentapp']; $extra['app'] = $GLOBALS['egw_info']['flags']['currentapp'];
// add import-map before (!) first module // Static things we want to make sure are loaded first
$java_script .= '<script type="importmap" nonce="'.htmlspecialchars(ContentSecurityPolicy::addNonce('script-src')).'">'."\n".
json_encode(self::getImportMap(), JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT)."\n".
"</script>\n";
$java_script .='<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.44/dist/themes/base.css"> $java_script .='<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.44/dist/themes/base.css">
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.44/dist/shoelace.js"></script>'; <script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.44/dist/shoelace.js"></script>';
// load our clientside entrypoint egw.js // load our clientside entrypoint egw.js
$java_script .= '<script type="module" src="'.$GLOBALS['egw_info']['server']['webserver_url']. $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"'; '/api/js/jsapi/egw.min.js" id="egw_script_id"';
// add values of extra parameter and class var as data attributes to script tag of egw.js // add values of extra parameter and class var as data attributes to script tag of egw.js
foreach($extra+self::$extra as $name => $value) foreach($extra+self::$extra as $name => $value)

View File

@ -29,7 +29,7 @@ class Bundle
*/ */
static $bundle2minurl = array( static $bundle2minurl = array(
'api' => '/api/js/jsapi.min.js', 'api' => '/api/js/jsapi.min.js',
'et2' => '/api/js/etemplate/etemplate2.min.js', // 'et2' => '/api/js/etemplate/etemplate2.min.js',
'et21'=> '/api/js/etemplate/etemplate2.min.js', 'et21'=> '/api/js/etemplate/etemplate2.min.js',
'pixelegg' => '/pixelegg/js/fw_pixelegg.min.js', 'pixelegg' => '/pixelegg/js/fw_pixelegg.min.js',
'jdots' => '/jdots/js/fw_jdots.min.js', 'jdots' => '/jdots/js/fw_jdots.min.js',
@ -115,7 +115,7 @@ class Bundle
$path = $min_path; $path = $min_path;
$mod = $min_mod; $mod = $min_mod;
} }
$to_include[$file] = $path.'?'.$mod.($query ? '&'.$query : ''); $to_include[$file] = $path;//.'?'.$mod.($query ? '&'.$query : '');
} }
} }
} }
@ -150,12 +150,12 @@ class Bundle
// TinyMCE must be included before bundled files, as it depends on it! // TinyMCE must be included before bundled files, as it depends on it!
if (strpos($path, '/tinymce/tinymce.min.js') !== false) if (strpos($path, '/tinymce/tinymce.min.js') !== false)
{ {
$to_include_first[] = $path . '?' . $mod; $to_include_first[] = $path;// . '?' . $mod;
} }
// for now minify does NOT support query parameters, nor php files generating javascript // for now minify does NOT support query parameters, nor php files generating javascript
elseif ($debug_minify || $query || substr($path, -3) != '.js' || empty($minurl)) elseif ($debug_minify || $query || substr($path, -3) != '.js' || empty($minurl))
{ {
$path .= '?'. $mod.($query ? '&'.$query : ''); //$path .= '?'. $mod.($query ? '&'.$query : '');
$to_include[] = $path; $to_include[] = $path;
} }
else else
@ -165,7 +165,7 @@ class Bundle
} }
if (!$debug_minify && $to_minify) if (!$debug_minify && $to_minify)
{ {
$path = $minurl.'?'.filemtime(EGW_SERVER_ROOT.$minurl); $path = $minurl;//.'?'.filemtime(EGW_SERVER_ROOT.$minurl);
/* no more dynamic minifying /* no more dynamic minifying
if (!empty($minurl) && file_exists(EGW_SERVER_ROOT.$minurl) && if (!empty($minurl) && file_exists(EGW_SERVER_ROOT.$minurl) &&
($mod=filemtime(EGW_SERVER_ROOT.$minurl)) >= $max_modified) ($mod=filemtime(EGW_SERVER_ROOT.$minurl)) >= $max_modified)
@ -217,6 +217,7 @@ class Bundle
*/ */
public static function all(bool $all_apps = false) public static function all(bool $all_apps = false)
{ {
return [];
$inc_mgr = new IncludeMgr(); $inc_mgr = new IncludeMgr();
$bundles = array(); $bundles = array();
@ -350,7 +351,7 @@ class Bundle
{ {
if (($key = array_search($file, $files))) if (($key = array_search($file, $files)))
{ {
$map[$prefix . $file] = $prefix . $file . '?' . filemtime(EGW_SERVER_ROOT . $file); $map[$prefix . $file] = $prefix . $file ;//. '?' . filemtime(EGW_SERVER_ROOT . $file);
unset($files[$key]); unset($files[$key]);
} }
} }
@ -380,12 +381,12 @@ class Bundle
{ {
// use bundle / minified url as target or not // use bundle / minified url as target or not
if (!$use_bundle) $target = $file; if (!$use_bundle) $target = $file;
$map[$prefix . $file] = $prefix.$target.'?'.filemtime(EGW_SERVER_ROOT.$target); $map[$prefix . $file] = $prefix.$target;//.'?'.filemtime(EGW_SERVER_ROOT.$target);
// typescript unfortunately has currently no option to add ".js" to it's es6 import statements // typescript unfortunately has currently no option to add ".js" to it's es6 import statements
// therefore we add extra entries without .js extension to the map // therefore we add extra entries without .js extension to the map
if (file_exists(EGW_SERVER_ROOT.substr($file, 0, -3) . '.ts')) if (file_exists(EGW_SERVER_ROOT.substr($file, 0, -3) . '.ts'))
{ {
$map[$prefix . substr($file, 0, -3)] = $prefix.$target.'?'.filemtime(EGW_SERVER_ROOT.$target); $map[$prefix . substr($file, 0, -3)] = $prefix.$target;//.'?'.filemtime(EGW_SERVER_ROOT.$target);
} }
} }
} }

View File

@ -200,7 +200,7 @@ class IncludeMgr
$this->debug_processing_file = $path; $this->debug_processing_file = $path;
// Parse the given file for dependencies // Parse the given file for dependencies
$uses = $this->parse_file($path); $uses = [];//$this->parse_file($path);
foreach ((array)$uses as $entry) foreach ((array)$uses as $entry)
{ {

View File

@ -44,8 +44,7 @@ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $
exit; exit;
} }
$content = "import './js/jsapi/egw_preferences.js';\nimport './js/jsapi/egw_user.js';\n\n"; $content = 'egw.set_preferences('.$preferences.", 'common', egw && egw.window !== window);\n";
$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_preferences('.$ab_preferences.", 'addressbook', egw && egw.window !== window);\n";
$content .= 'egw.set_user('.$user.", egw && egw.window !== window);\n"; $content .= 'egw.set_user('.$user.", egw && egw.window !== window);\n";

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,8 @@
'use strict'; 'use strict';
import "../../api/js/jsapi/egw_ready.js";
import "../../api/js/framework/fw_base.js";
/** /**
* Installs app.notifications used to poll notifications from server and display them * Installs app.notifications used to poll notifications from server and display them
*/ */

1514
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,14 +4,44 @@
"license": "GPL-2.0", "license": "GPL-2.0",
"version": "21.1.20210316", "version": "21.1.20210316",
"repository": {}, "repository": {},
"scripts": {
"build": "rollup -c",
"build:watch": "rollup -cw"
},
"devDependencies": { "devDependencies": {
"@babel/preset-typescript": "^7.14.5",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-typescript": "^8.2.1",
"@types/jquery": "^3.5.5", "@types/jquery": "^3.5.5",
"@types/jqueryui": "^1.12.14", "@types/jqueryui": "^1.12.14",
"grunt": "^1.3.0", "grunt": "^1.3.0",
"grunt-contrib-cssmin": "^2.2.1", "grunt-contrib-cssmin": "^2.2.1",
"grunt-newer": "^1.3.0", "grunt-newer": "^1.3.0",
"grunt-terser": "^1.0.0", "grunt-terser": "^1.0.0",
"rimraf": "^3.0.2",
"rollup": "^2.52.2",
"rollup-plugin-terser": "^7.0.2",
"terser": "^4.8.0", "terser": "^4.8.0",
"typescript": "^3.9.7" "typescript": "^3.9.7"
},
"jshintConfig": {
"esversion": 6,
"boss": true,
"curly": true,
"eqeqeq": true,
"eqnull": true,
"expr": true,
"noarg": true,
"smarttabs": true,
"trailing": true,
"node": true,
"undef": true,
"unused": true,
"globals": {
"egw": true,
"app": true
}
},
"dependencies": {
} }
} }

View File

@ -13,6 +13,8 @@
framework.fw_desktop; framework.fw_desktop;
/pixelegg/js/slider.js; /pixelegg/js/slider.js;
*/ */
import "../../vendor/bower-asset/jquery-ui/jquery-ui.js";
import "../../api/js/jquery/mousewheel/mousewheel.js";
import '../../api/js/framework/fw_desktop.js'; import '../../api/js/framework/fw_desktop.js';
import './slider.js'; import './slider.js';
@ -159,3 +161,4 @@ import './slider.js';
}); });
}); });
})(window); })(window);
console.log("Pixelegg loaded");

View File

@ -9,12 +9,133 @@
* @type {import('rollup').RollupOptions} * @type {import('rollup').RollupOptions}
*/ */
import path from 'path';
import babel from '@babel/core';
import { readFileSync } from "fs";
import rimraf from 'rimraf';
import { minify } from 'terser';
export default [{ // Best practice: use this
// Main bundle //rimraf.sync('./dist/');
input: "./api/js/jsapi/egw.js", rimraf.sync('./chunks/');
// Turn on minification
const do_minify = false;
export default {
treeshake: false,
input: {
// Output : Input
// Note the .ts extension on the input - we build directly from the TypeScript when available
"pixelegg/js/fw_pixelegg.min": "pixelegg/js/fw_pixelegg.js",
"api/js/etemplate/etemplate2.min":"api/js/etemplate/etemplate2.ts",
"api/js/egw_action/egw_dragdrop_dhtmlx_tree.min":"api/js/egw_action/egw_dragdrop_dhtmlx_tree.js",
"api/js/jsapi/egw.min": "api/js/jsapi/egw_modules.js",
"api/js/jsapi.min": 'api/js/jsapi/jsapi.js',
// Should be just built-in apps, but until rollup supports multi-level we need them all
"addressbook/js/app": "addressbook/js/app.ts",
"admin/js/app": "admin/js/app.ts",
"calendar/js/app.min" : "calendar/js/app.ts",
"notifications/js/notificationajaxpopup.min":"notifications/js/notificationajaxpopup.js",
"status/js/app": "status/js/app.ts",
"kanban/js/app":"kanban/js/app.ts",
"rocketchat/js/app.min":"rocketchat/js/app.js"
},
external: function(id,parentId,isResolved) {
if(!isResolved)
{
return;
}
if(id.includes("/vendor/"))
{
return true;
}
},
output: { output: {
file: "./api/js/jsapi.min.js", // TODO: Hashed entries, when server supports
format: "iife" //entryFileNames: '[name]-[hash].js',
entryFileNames: '[name].js',
chunkFileNames: 'chunks/[name]-[hash].js',
// Best practice: use this:
//dir: './dist',
dir: '.',
sourcemap: true
},
plugins: [{
resolveId (id, parentId) {
if(id.endsWith(".js") && parentId)
{
const tsPath =path.resolve(path.dirname(parentId), id.slice(0,-3) + '.ts');
try {
readFileSync(tsPath);
console.warn(id + " is a TS file loaded with wrong extension. Remove the extension on the import in " + parentId);
}
catch (e) {}
}
else if (!id.endsWith('.js') && !id.endsWith('.ts')) {
const tsPath =path.resolve(path.dirname(parentId), id + '.ts');
const jsPath =path.resolve(path.dirname(parentId), id + '.js');
try {
readFileSync(tsPath);
}
catch (e) {
return jsPath;
}
return tsPath;
}
}
}, {
transform (code, id) {
if (id.endsWith('.ts'))
return new Promise((resolve, reject) => {
return babel.transform(code, {
filename: id,
sourceMaps: true,
ast: false,
compact: false,
sourceType: 'module',
parserOpts: {
// plugins: stage3Syntax,
errorRecovery: true
},
presets: ['@babel/preset-typescript']
}, function (err, result) {
if (err)
return reject(err);
resolve(result);
});
});
}
},
{
transform (code,id) {
if(!do_minify || id.includes(".min"))
{
return;
}
return minify(code, {
mangle: false,
output: {
preamble: `/*!
* EGroupware (http://www.egroupware.org/) minified Javascript
*
* full sources are available under https://github.com/EGroupware/egroupware/
*
* build ${Date.now()}
*/
`
}
});
}
}],
// Custom warning handler to give more information about circular dependencies
onwarn: function(warning,warn) {
console.warn(warning);
} }
}];
};