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 { 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
*

View File

@ -16,7 +16,7 @@
import {EgwApp, PushData} from '../../api/js/jsapi/egw_app';
import {etemplate2} from "../../api/js/etemplate/etemplate2";
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

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 {et2_dialog} from "../../api/js/etemplate/et2_widget_dialog";
import {et2_selectbox} from "../../api/js/etemplate/et2_widget_selectbox";
import {nm_action, fetchAll} from "../../api/js/etemplate/et2_extension_nextmatch_actions.js";
import "./CRM.js";
import {nm_action, fetchAll} from "../../api/js/etemplate/et2_extension_nextmatch_actions";
import "./CRM";
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 {et2_dialog} from "../../api/js/etemplate/et2_widget_dialog";
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';
/**
* UI for Admin

View File

@ -43,9 +43,7 @@ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $
exit;
}
$content = "import './js/jsapi/egw_config.js';\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_configs('.$config.", 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

View File

@ -48,7 +48,7 @@ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $
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
if (in_array('gzip', explode(',',$_SERVER['HTTP_ACCEPT_ENCODING'])) && function_exists('gzencode'))

View File

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

View File

@ -7,7 +7,10 @@
* @link https://www.egroupware.org
* @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
*

View File

@ -8,7 +8,10 @@
* @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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,6 +16,8 @@
et2_core_DOMWidget;
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 { ClassWithAttributes } from "./et2_core_inheritance";
import { et2_register_widget } from "./et2_core_widget";

View File

@ -18,6 +18,8 @@
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 {ClassWithAttributes} from "./et2_core_inheritance";
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
*/
/*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_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 '../jsapi/egw_json.js';
import {egwIsMobile} from "../egw_action/egw_action_common.js";
import './et2-button';
/* Include all widget classes here, we only care about them registering, not importing anything
//import './et2-button';
/* 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_grid';
import './et2_widget_box';
@ -128,7 +66,6 @@ import './et2_widget_progress';
import './et2_widget_portlet';
import './et2_widget_selectAccount';
import './et2_widget_ajaxSelect';
import './et2_widget_vfs';
import './et2_widget_video';
import './et2_widget_audio';
import './et2_widget_barcode';
@ -137,7 +74,7 @@ import './et2_widget_script';
import './et2_widget_countdown';
import './et2_extension_nextmatch';
import './et2_extension_customfields';
*/
/**
* 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}
*/
init: function (_sidemenuId, _tabsId, _webserverUrl, _sideboxSizeCallback){
window.framework = this;
/* Get the base div */
this.sidemenuDiv = document.getElementById(_sidemenuId);
this.tabsDiv = document.getElementById(_tabsId);
@ -1380,4 +1381,4 @@ window.fw_base = (function(){ "use strict"; return Class.extend(
gauge.width(this.firstload_animation_gauge+"%");
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 '../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
@ -378,4 +378,4 @@ window.fw_browser = (function(){ "use strict"; return Class.extend(
{
this.browse('about:blank', this.type == EGW_BROWSER_TYPE_IFRAME);
}
});}).call(this);
});}).call(window);

View File

@ -16,6 +16,10 @@
framework.fw_classes;
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_browser.js';
import './fw_ui.js';

View File

@ -12,6 +12,10 @@
/api/js/jquery/mousewheel/mousewheel.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';
/**
@ -189,7 +193,7 @@ window.fw_ui_sidemenu_entry = (function(){ "use strict"; return Class.extend(
jQuery(this.headerDiv).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();
}
});}).call(this);
});}).call(window);
/**
* Class: egw_fw_ui_tab

View File

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

View File

@ -12,13 +12,12 @@
egw_inheritance;
/api/js/es6-promise.min.js;
*/
import {EgwApp} from "./egw_app";
import './egw_inheritance.js';
import {et2_createWidget} from "../etemplate/et2_core_widget";
import {etemplate2} from "../etemplate/etemplate2";
import {et2_dialog} from "../etemplate/et2_widget_dialog";
import {et2_nextmatch} from "../etemplate/et2_extension_nextmatch";
import {et2_favorites} from "../etemplate/et2_widget_favorites";
import {EgwApp} from "./egw_app";
/**
* 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');
// 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
if (typeof window.egw == 'undefined')
@ -190,6 +190,7 @@ window.app = {classes: {}};
*/
async function legacy_js_import(_src, _baseurl)
{
console.log("Legacy import: ", _src,_baseurl);
if (!Array.isArray(_src)) _src = [].concat(_src);
return Promise.all(_src.map(src => {
return new Promise(function(_resolve, _reject)
@ -207,9 +208,8 @@ window.app = {classes: {}};
}
const egw_modules = [
'egw_core', 'egw_debug', 'egw_preferences', 'egw_lang', 'egw_links', 'egw_open', 'egw_user',
'egw_config', 'egw_images', 'egw_jsonq', 'egw_files', 'egw_json', 'egw_store', 'egw_tooltip', 'egw_css',
'egw_calendar', 'egw_ready', 'egw_data', 'egw_tail', 'egw_message', 'egw_notification', 'jsapi',
// TODO: Dev mode should remove .min or remap it with importmap
'egw.min'
];
// make our promise global, as legacy code calls egw_LAB.wait which we assign to egw_ready.then
window.egw_LAB = window.egw_ready =
@ -218,7 +218,7 @@ window.app = {classes: {}};
.catch((err) => {console.error(rel_src+": "+err.message)}))))
.then(() => Promise.all(include.filter((src) => src.match(legacy_js_regexp) === null) //.reverse()
.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(() =>
{
// We need to override the globalEval to mitigate potential execution of
@ -371,7 +371,7 @@ window.app = {classes: {}};
// load etemplate2 template(s)
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')) || {};
if (popup || window.opener && !egwIsMobile()) {
// Resize popup when et2 load is done

View File

@ -18,6 +18,11 @@
// egw_jquery;
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';
/**

View File

@ -10,6 +10,7 @@
* @version $Id$
*/
import "./egw.js";
/**
* 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.

View File

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

View File

@ -13,7 +13,7 @@
* @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

View File

@ -33,7 +33,7 @@ egw.extend('jquery', egw.MODULE_WND_LOCAL, function(_app, _wnd)
// Include the jQuery and jQuery UI library.
var token = ready.readyWaitFor();
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 + '/api/js/jquery/jquery.html5_upload.js'
], function () {

View File

@ -17,7 +17,7 @@
egw_files;
egw_debug;
*/
import './egw_core.js';
import './egw.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');
}
$content = "import './js/jsapi/egw_lang.js';\n\n";
$content = "";
// fix for phrases containing \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)).

View File

@ -141,7 +141,7 @@ class Etemplate extends Etemplate\Widget\Template
unset($hook_data);
// 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!");
@ -232,9 +232,13 @@ class Etemplate extends Etemplate\Widget\Template
}
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);
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);
}

View File

@ -167,10 +167,9 @@ abstract class Framework extends Framework\Extra
// always load jquery (not -ui) first
'/vendor/bower-asset/jquery/dist/jquery.js',
'/api/js/jquery/jquery.noconflict.js',
// always include javascript helper functions
'/api/js/jsapi/jsapi.js',
'/api/js/jsapi/egw.js',
'/api/js/jsapi.min.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));
$extra['app'] = $GLOBALS['egw_info']['flags']['currentapp'];
// add import-map before (!) first module
$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";
// Static things we want to make sure are loaded first
$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>';
// 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"';
'/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
foreach($extra+self::$extra as $name => $value)

View File

@ -29,7 +29,7 @@ class Bundle
*/
static $bundle2minurl = array(
'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',
'pixelegg' => '/pixelegg/js/fw_pixelegg.min.js',
'jdots' => '/jdots/js/fw_jdots.min.js',
@ -115,7 +115,7 @@ class Bundle
$path = $min_path;
$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!
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
elseif ($debug_minify || $query || substr($path, -3) != '.js' || empty($minurl))
{
$path .= '?'. $mod.($query ? '&'.$query : '');
//$path .= '?'. $mod.($query ? '&'.$query : '');
$to_include[] = $path;
}
else
@ -165,7 +165,7 @@ class Bundle
}
if (!$debug_minify && $to_minify)
{
$path = $minurl.'?'.filemtime(EGW_SERVER_ROOT.$minurl);
$path = $minurl;//.'?'.filemtime(EGW_SERVER_ROOT.$minurl);
/* no more dynamic minifying
if (!empty($minurl) && file_exists(EGW_SERVER_ROOT.$minurl) &&
($mod=filemtime(EGW_SERVER_ROOT.$minurl)) >= $max_modified)
@ -217,6 +217,7 @@ class Bundle
*/
public static function all(bool $all_apps = false)
{
return [];
$inc_mgr = new IncludeMgr();
$bundles = array();
@ -350,7 +351,7 @@ class Bundle
{
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]);
}
}
@ -380,12 +381,12 @@ class Bundle
{
// use bundle / minified url as target or not
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
// therefore we add extra entries without .js extension to the map
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;
// Parse the given file for dependencies
$uses = $this->parse_file($path);
$uses = [];//$this->parse_file($path);
foreach ((array)$uses as $entry)
{

View File

@ -44,8 +44,7 @@ if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $
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_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';
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
*/

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",
"version": "21.1.20210316",
"repository": {},
"scripts": {
"build": "rollup -c",
"build:watch": "rollup -cw"
},
"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/jqueryui": "^1.12.14",
"grunt": "^1.3.0",
"grunt-contrib-cssmin": "^2.2.1",
"grunt-newer": "^1.3.0",
"grunt-terser": "^1.0.0",
"rimraf": "^3.0.2",
"rollup": "^2.52.2",
"rollup-plugin-terser": "^7.0.2",
"terser": "^4.8.0",
"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;
/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 './slider.js';
@ -159,3 +161,4 @@ import './slider.js';
});
});
})(window);
console.log("Pixelegg loaded");

View File

@ -9,12 +9,133 @@
* @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 [{
// Main bundle
input: "./api/js/jsapi/egw.js",
// Best practice: use this
//rimraf.sync('./dist/');
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: {
file: "./api/js/jsapi.min.js",
format: "iife"
// TODO: Hashed entries, when server supports
//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);
}
}];
};