mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-08-04 06:31:02 +02:00
addressbook
admin
api
images
inc
js
Resumable
dhtmlxMenu
dhtmlxtree
egw_action
etemplate
framework
jquery
jsapi
app_base.js
egw.js
egw_app.ts
egw_calendar.js
egw_config.js
egw_core.js
egw_css.js
egw_data.js
egw_debug.js
egw_files.js
egw_global.d.ts
egw_global.js
egw_images.js
egw_inheritance.js
egw_json.js
egw_jsonq.js
egw_lang.js
egw_links.js
egw_message.js
egw_modules.js
egw_notification.js
egw_open.js
egw_preferences.js
egw_ready.js
egw_store.js
egw_tail.js
egw_timer.js
egw_tooltip.js
egw_user.js
egw_utils.js
jsapi.js
offline
tinymce
egw_json.js
es6-promise.min.js
login.js
tapandswipe.ts
lang
ntlm
setup
src
templates
tests
anon_images.php
anon_lavatar.php
asyncservices.php
asyncwrapper.php
avatar.php
categories.php
changepwd.php
config.php
emclient-signatures.php
etemplate.php
images.php
lang.php
oauth.php
thumbnail.php
tinymce.php
user.php
calendar
doc
emailadmin
filemanager
files
home
importexport
infolog
mail
notifications
pixelegg
preferences
resources
saml
setup
timesheet
.gitignore
.htaccess
.travis.yml
Gruntfile.js
LICENSE.md
README.md
SECURITY.md
about.php
composer.json
composer.lock
groupdav.htaccess
groupdav.php
header.inc.php.template
index.php
install-cli.php
json.php
login.php
logout.php
manifest.json
move-images
package-lock.json
package.json
redirect.php
remote.php
rollup.config.js
service-worker.js
share.php
status.php
tsconfig.json
updateGruntfile.php
web-test-runner.config.mjs
webdav.php
with egw composition happening in main window the used import statement happens in that context and NOT in the window (eg. popup or iframe) this module is instantiated for!
240 lines
6.6 KiB
JavaScript
240 lines
6.6 KiB
JavaScript
/**
|
|
* EGroupware clientside API object
|
|
*
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
* @package etemplate
|
|
* @subpackage api
|
|
* @link http://www.egroupware.org
|
|
* @author Andreas Stöckel (as AT stylite.de)
|
|
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
|
*/
|
|
|
|
/*egw:uses
|
|
egw_core;
|
|
egw_ready;
|
|
egw_debug;
|
|
*/
|
|
import './egw_core.js';
|
|
|
|
/**
|
|
* @augments Class
|
|
* @param {string} _app application name object is instanciated for
|
|
* @param {object} _wnd window object is instanciated for
|
|
*/
|
|
egw.extend('files', egw.MODULE_WND_LOCAL, function(_app, _wnd)
|
|
{
|
|
"use strict";
|
|
|
|
var egw = this;
|
|
|
|
/**
|
|
* Remove optional timestamp attached as query parameter, eg. /path/name.js?12345678[&other=val]
|
|
*
|
|
* Examples:
|
|
* /path/file.js --> /path/file.js
|
|
* /path/file.js?123456 --> /path/file.js
|
|
* /path/file.php?123456¶m=value --> /path/file.php?param=value
|
|
* /path/file.php?param=value&123456 --> /path/file.php?param=value
|
|
*
|
|
* @param _src url
|
|
* @return url with timestamp stripped off
|
|
*/
|
|
function removeTS(_src)
|
|
{
|
|
return _src.replace(/[?&][0-9]+&?/, '?').replace(/\?$/, '');
|
|
}
|
|
|
|
/**
|
|
* RegExp to extract string with comma-separated files from a bundle-url
|
|
*
|
|
* @type RegExp
|
|
*/
|
|
var bundle2files_regexp = /phpgwapi\/inc\/min\/\?b=[^&]+&f=([^&]+)/;
|
|
|
|
/**
|
|
* Regexp to detect and remove .min.js extension
|
|
*
|
|
* @type RegExp
|
|
*/
|
|
var min_js_regexp = /\.min\.js$/;
|
|
|
|
/**
|
|
* Return array of files-sources from bundle(s) incl. bundle-src itself
|
|
*
|
|
* @param {string|Array} _srcs all url's have to be egw releativ!
|
|
* @returns {Array}
|
|
*/
|
|
function files_from_bundles(_srcs)
|
|
{
|
|
var files = [];
|
|
|
|
if (typeof _srcs == 'string') _srcs = [_srcs];
|
|
|
|
for(var n=0; n < _srcs.length; ++n)
|
|
{
|
|
var file = _srcs[n];
|
|
files.push(file.replace(min_js_regexp, '.js'));
|
|
var contains = file.match(bundle2files_regexp);
|
|
|
|
if (contains && contains.length > 1)
|
|
{
|
|
var bundle = contains[1].split(',');
|
|
for(var i=0; i < bundle.length; ++i)
|
|
{
|
|
files.push(bundle[i].replace(min_js_regexp, '.js'));
|
|
}
|
|
}
|
|
}
|
|
return files;
|
|
}
|
|
|
|
/**
|
|
* Strip of egw_url from given urls (if containing it)
|
|
*
|
|
* @param {array} _urls absolute urls
|
|
* @returns {array} relativ urls
|
|
*/
|
|
function strip_egw_url(_urls)
|
|
{
|
|
var egw_url = egw.webserverUrl;
|
|
if (egw_url.charAt(egw_url.length-1) != '/') egw_url += '/';
|
|
|
|
for(var i=0; i < _urls.length; ++i)
|
|
{
|
|
var file = _urls[i];
|
|
// check if egw_url is only path and urls contains full url incl. protocol
|
|
// --> prefix it with our protocol and host, as eg. splitting by just '/' will fail!
|
|
var need_full_url = egw_url[0] == '/' && file.substr(0,4) == 'http' ? window.location.protocol+'//'+window.location.host : '';
|
|
var parts = file.split(need_full_url+egw_url);
|
|
if (parts.length > 1)
|
|
{
|
|
// discard protocol and host
|
|
parts.shift();
|
|
_urls[i] = parts.join(need_full_url+egw_url);
|
|
}
|
|
}
|
|
return _urls;
|
|
}
|
|
|
|
/**
|
|
* Array which contains all currently bound in javascript and css files.
|
|
*/
|
|
var files = [];
|
|
// add already included scripts
|
|
var tags = jQuery('script', _wnd.document);
|
|
for(var i=0; i < tags.length; ++i)
|
|
{
|
|
files.push(removeTS(tags[i].src));
|
|
}
|
|
// add already included css
|
|
tags = jQuery('link[type="text/css"]', _wnd.document);
|
|
for(var i=0; i < tags.length; ++i)
|
|
{
|
|
files.push(removeTS(tags[i].href));
|
|
}
|
|
// make urls egw-relative
|
|
files = strip_egw_url(files);
|
|
// resolve bundles and replace .min.js with .js
|
|
files = files_from_bundles(files);
|
|
|
|
return {
|
|
/**
|
|
* Load and execute javascript file(s) in order
|
|
*
|
|
* Deprecated because with egw composition happening in main window the used import statement happens in that context
|
|
* and NOT in the window (eg. popup or iframe) this module is instantiated for!
|
|
*
|
|
* @memberOf egw
|
|
* @param {string|array} _jsFiles (array of) urls to include
|
|
* @param {function} _callback called after JS files are loaded and executed
|
|
* @param {object} _context
|
|
* @param {string} _prefix prefix for _jsFiles
|
|
* @deprecated use es6 import statement: Promise.all([].concat(_jsFiles).map((src)=>import(_prefix+src))).then(...)
|
|
* @return Promise
|
|
*/
|
|
includeJS: function(_jsFiles, _callback, _context, _prefix)
|
|
{
|
|
// Also allow including a single javascript file
|
|
if (typeof _jsFiles === 'string')
|
|
{
|
|
_jsFiles = [_jsFiles];
|
|
}
|
|
// filter out files included by script-tag via egw.js
|
|
_jsFiles = _jsFiles.filter((src) => src.match(egw.legacy_js_regexp) === null);
|
|
let promise;
|
|
if (_jsFiles.length === 1) // running this in below case fails when loading app.js from etemplate.load()
|
|
{
|
|
const src = _jsFiles[0];
|
|
promise = import(_prefix ? _prefix+src : src)
|
|
.catch((err) => {
|
|
console.error(src+": "+err.message);
|
|
return Promise.reject(err.message);
|
|
});
|
|
}
|
|
else
|
|
{
|
|
promise = Promise.all(_jsFiles.map((src) => {
|
|
import(_prefix ? _prefix+src : src)
|
|
.catch((err) => {
|
|
console.error(src+": "+err.message);
|
|
return Promise.reject(err.message);
|
|
})
|
|
}));
|
|
}
|
|
return typeof _callback === 'undefined' ? promise : promise.then(_callback.call(_context));
|
|
},
|
|
|
|
/**
|
|
* Check if file is already included and optional mark it as included if not yet included
|
|
*
|
|
* Check does NOT differenciate between file.min.js and file.js.
|
|
* Only .js get's recored in files for further checking, if _add_if_not set.
|
|
*
|
|
* @param {string} _file
|
|
* @param {boolean} _add_if_not if true mark file as included
|
|
* @return boolean true if file already included, false if not
|
|
*/
|
|
included: function(_file, _add_if_not)
|
|
{
|
|
var file = removeTS(_file).replace(min_js_regexp, '.js');
|
|
var not_inc = files.indexOf(file) == -1;
|
|
|
|
if (not_inc && _add_if_not)
|
|
{
|
|
files = files.concat(files_from_bundles(file));
|
|
}
|
|
return !not_inc;
|
|
},
|
|
|
|
/**
|
|
* Include a CSS file
|
|
*
|
|
* @param {string|array} _cssFiles full url of file to include
|
|
*/
|
|
includeCSS: function(_cssFiles)
|
|
{
|
|
if (typeof _cssFiles == 'string') _cssFiles = [_cssFiles];
|
|
_cssFiles = strip_egw_url(_cssFiles);
|
|
|
|
for(var n=0; n < _cssFiles.length; ++n)
|
|
{
|
|
var file = _cssFiles[n];
|
|
if (!this.included(file, true)) // check if included and marks as such if not
|
|
{
|
|
// Create the node which is used to include the css file
|
|
var cssnode = _wnd.document.createElement('link');
|
|
cssnode.type = "text/css";
|
|
cssnode.rel = "stylesheet";
|
|
cssnode.href = egw.webserverUrl+'/'+file;
|
|
|
|
// Get the head node and append the newly created "link" nod to it
|
|
var head = _wnd.document.getElementsByTagName('head')[0];
|
|
head.appendChild(cssnode);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
});
|
|
|
|
|