Use jQuery.slim

Underscore.js _.uniq(_.compact( to native Array.filter((value, index, self) => !!value && self.indexOf(value) == index)
Underscore.js _.compact to native Array.filter(value => !!value)
Underscore.js _.uniq to native Array.filter((value, index, self) => self.indexOf(value) == index)
Underscore.js _.values to native Object.values
Underscore.js _.flatten to native Array.flat
Underscore.js _.union to native Array.concat + unique filter
Underscore.js _.reduce to native Array.reduce
Underscore.js _.escape replaced with advanced htmlspecialchars()
Underscore.js _.memoize replaced
Now Underscore.js is a slim custom version (only _.debounce, _.defer & _.throttle)
This commit is contained in:
djmaze 2020-07-23 16:06:16 +02:00
parent 996a71ad8a
commit dca0ff02ed
27 changed files with 515 additions and 353 deletions

View file

@ -51,6 +51,12 @@ This fork has the following changes:
* CRLF => LF line endings * CRLF => LF line endings
* Ongoing removal of jQuery and Underscore.js dependencies (things are native these days) * Ongoing removal of jQuery and Underscore.js dependencies (things are native these days)
### slim jQuery and Underscore.js
js: 1.14.0 = 7960367 / native = 5127981 bytes
js/min: 1.14.0 = 1766594 / native = 1405850 bytes
360.744 bytes is nut much, but it already feels faster.
### PHP73 branch ### PHP73 branch
There's a branch with only the PHP 7.3 changes at There's a branch with only the PHP 7.3 changes at

View file

@ -86,15 +86,13 @@ class AdminApp extends AbstractApp {
}); });
if (isArray(data.Result.List)) { if (isArray(data.Result.List)) {
list = _.compact( list = data.Result.List.map(item => {
data.Result.List.map(item => { if (item) {
if (item) { item.loading = ko.observable(!isUnd(loading[item.file]));
item.loading = ko.observable(!isUnd(loading[item.file])); return 'core' === item.type && !item.canBeInstalled ? null : item;
return 'core' === item.type && !item.canBeInstalled ? null : item; }
} return null;
return null; }).filter(value => !!value);
})
);
} }
PackageStore.packages(list); PackageStore.packages(list);

View file

@ -321,7 +321,8 @@ class AppUser extends AbstractApp {
}; };
} }
this.moveCache[hash].Uid = _.union(this.moveCache[hash].Uid, uidsForMove); this.moveCache[hash].Uid = this.moveCache[hash].Uid.concat(uidsForMove)
.filter((value, index, self) => self.indexOf(value) == index);
this.messagesMoveTrigger(); this.messagesMoveTrigger();
} }
@ -520,7 +521,9 @@ class AppUser extends AbstractApp {
.getKeyId() .getKeyId()
.toHex() .toHex()
.toLowerCase(), .toLowerCase(),
_.uniq(_.compact(oItem.getKeyIds().map(item => (item && item.toHex ? item.toHex() : null)))), oItem.getKeyIds()
.map(item => (item && item.toHex ? item.toHex() : null))
.filter((value, index, self) => !!value && self.indexOf(value) == index),
aUsers, aUsers,
aEmails, aEmails,
oItem.isPrivate(), oItem.isPrivate(),
@ -634,12 +637,10 @@ class AppUser extends AbstractApp {
delegateRunOnDestroy(TemplateStore.templates()); delegateRunOnDestroy(TemplateStore.templates());
TemplateStore.templates( TemplateStore.templates(
_.compact( data.Result.Templates.map(templateData => {
data.Result.Templates.map(templateData => { const template = new TemplateModel();
const template = new TemplateModel(); return template.parse(templateData) ? template : null;
return template.parse(templateData) ? template : null; }).filter(value => !!value)
})
)
); );
} }
}); });
@ -819,7 +820,8 @@ class AppUser extends AbstractApp {
messages = MessageStore.messageListChecked(); messages = MessageStore.messageListChecked();
} }
rootUids = _.uniq(_.compact(messages.map(oMessage => (oMessage && oMessage.uid ? oMessage.uid : null)))); rootUids = messages.map(oMessage => oMessage && oMessage.uid ? oMessage.uid : null)
.filter((value, index, self) => !!value && self.indexOf(value) == index);
if ('' !== sFolderFullNameRaw && 0 < rootUids.length) { if ('' !== sFolderFullNameRaw && 0 < rootUids.length) {
switch (iSetAction) { switch (iSetAction) {
@ -880,7 +882,7 @@ class AppUser extends AbstractApp {
Remote.suggestions((result, data) => { Remote.suggestions((result, data) => {
if (StorageResultType.Success === result && data && isArray(data.Result)) { if (StorageResultType.Success === result && data && isArray(data.Result)) {
autocompleteCallback( autocompleteCallback(
_.compact(data.Result.map(item => (item && item[0] ? new EmailModel(item[0], item[1]) : null))) data.Result.map(item => (item && item[0] ? new EmailModel(item[0], item[1]) : null)).filter(value => !!value)
); );
} else if (StorageResultType.Abort !== result) { } else if (StorageResultType.Abort !== result) {
autocompleteCallback([]); autocompleteCallback([]);
@ -899,10 +901,10 @@ class AppUser extends AbstractApp {
} }
if (bExpanded) { if (bExpanded) {
aExpandedList.push(sFullNameHash); if (!aExpandedList.includes(sFullNameHash))
aExpandedList = _.uniq(aExpandedList); aExpandedList.push(sFullNameHash);
} else { } else {
aExpandedList = _.without(aExpandedList, sFullNameHash); aExpandedList = aExpandedList.filter(value => value !== sFullNameHash);
} }
Local.set(ClientSideKeyName.ExpandedFolders, aExpandedList); Local.set(ClientSideKeyName.ExpandedFolders, aExpandedList);

View file

@ -18,7 +18,49 @@ export const FileType = {
'Presentation': 'presentation', 'Presentation': 'presentation',
'Certificate': 'certificate', 'Certificate': 'certificate',
'CertificateBin': 'certificate-bin', 'CertificateBin': 'certificate-bin',
'Archive': 'archive' 'Archive': 'archive',
getIconClass: function(type) {
let result = ['icon-file', ''];
switch (type) {
case this.Text:
case this.Eml:
case this.WordText:
result[0] += '-text';
break;
case this.Html:
case this.Code:
result[0] += '-code';
break;
case this.Image:
result[0] += '-image';
break;
case this.Audio:
result[0] += '-music';
break;
case this.Video:
result[0] += '-movie';
break;
case this.Archive:
result[0] += '-zip';
break;
case this.Certificate:
case this.CertificateBin:
result[0] += '-certificate';
break;
case this.Sheet:
result[0] += '-excel';
break;
case this.Presentation:
result[0] += '-chart-graph';
break;
case this.Pdf:
result['icon-none', 'pdf'];
break;
// no default
}
return result;
}
}; };
/** /**

View file

@ -11,13 +11,25 @@ import { jassl } from 'Common/Jassl';
const trim = $.trim; const trim = $.trim;
const isArray = Array.isArray; const isArray = Array.isArray;
const isObject = _.isObject; const isObject = v => typeof v === 'object';
const isFunc = _.isFunction; const isFunc = v => typeof v === 'function';
const isUnd = _.isUndefined; const isUnd = v => undefined === v;
const noop = () => {}; // eslint-disable-line no-empty-function const noop = () => {}; // eslint-disable-line no-empty-function
const noopTrue = () => true; const noopTrue = () => true;
const noopFalse = () => false; const noopFalse = () => false;
var htmlspecialchars = ((de,se,gt,lt,sq,dq,bt) => {
return (str, quote_style = 3, double_encode = true) => {
str = (''+str)
.replace(double_encode?de:se,'&amp;')
.replace(gt,'&lt;')
.replace(lt,'&gt;')
.replace(bt,'&#x60;');
if (quote_style & 1) { str = str.replace(sq,'&#x27;'); }
return (quote_style & 2) ? str.replace(dq,'&quot;') : str;
};
})(/&/g,/&(?![\w#]+;)/gi,/</g,/>/g,/'/g,/"/g,/`/g);
export { trim, isArray, isObject, isFunc, isUnd, noop, noopTrue, noopFalse, jassl }; export { trim, isArray, isObject, isFunc, isUnd, noop, noopTrue, noopFalse, jassl };
/** /**
@ -167,7 +179,7 @@ export function fakeMd5(len = 32) {
* @returns {string} * @returns {string}
*/ */
export function encodeHtml(text) { export function encodeHtml(text) {
return isNormal(text) ? _.escape(text.toString()) : ''; return isNormal(text) ? htmlspecialchars(text.toString()) : '';
} }
/** /**
@ -449,7 +461,7 @@ export function createCommandLegacy(context, fExecute, fCanExecute = true) {
* @param {string} theme * @param {string} theme
* @returns {string} * @returns {string}
*/ */
export const convertThemeName = _.memoize((theme) => { export const convertThemeName = theme => {
if ('@custom' === theme.substr(-7)) { if ('@custom' === theme.substr(-7)) {
theme = trim(theme.substring(0, theme.length - 7)); theme = trim(theme.substring(0, theme.length - 7));
} }
@ -458,9 +470,9 @@ export const convertThemeName = _.memoize((theme) => {
theme theme
.replace(/[^a-zA-Z0-9]+/g, ' ') .replace(/[^a-zA-Z0-9]+/g, ' ')
.replace(/([A-Z])/g, ' $1') .replace(/([A-Z])/g, ' $1')
.replace(/[\s]+/g, ' ') .replace(/\s+/g, ' ')
); );
}); };
/** /**
* @param {string} name * @param {string} name
@ -713,7 +725,7 @@ export function htmlToPlain(html) {
.replace(/[\n]/gm, '<br />') .replace(/[\n]/gm, '<br />')
.replace(/[\r]/gm, '') .replace(/[\r]/gm, '')
: '', : '',
fixAttibuteValue = (...args) => (args && 1 < args.length ? '' + args[1] + _.escape(args[2]) : ''), fixAttibuteValue = (...args) => (args && 1 < args.length ? '' + args[1] + htmlspecialchars(args[2]) : ''),
convertLinks = (...args) => (args && 1 < args.length ? trim(args[1]) : ''); convertLinks = (...args) => (args && 1 < args.length ? trim(args[1]) : '');
text = html text = html
@ -1384,7 +1396,7 @@ export function mailToHelper(mailToUrl, PopupComposeViewModel) {
if (!isUnd(params.to)) { if (!isUnd(params.to)) {
to = EmailModel.parseEmailLine(decodeURIComponent(email + ',' + params.to)); to = EmailModel.parseEmailLine(decodeURIComponent(email + ',' + params.to));
to = _.values( to = Object.values(
to.reduce((result, value) => { to.reduce((result, value) => {
if (value) { if (value) {
if (result[value.email]) { if (result[value.email]) {

35
dev/External/ko.js vendored
View file

@ -13,7 +13,8 @@ const ko = window.ko,
element.__opentip.deactivate(); element.__opentip.deactivate();
} }
}); });
}; },
isFunction = v => typeof v === 'function';
ko.bindingHandlers.updateWidth = { ko.bindingHandlers.updateWidth = {
init: (element, fValueAccessor) => { init: (element, fValueAccessor) => {
@ -145,7 +146,7 @@ ko.bindingHandlers.tooltip = {
Globals = require('Common/Globals'); Globals = require('Common/Globals');
if (!Globals.bMobileDevice || isMobile) { if (!Globals.bMobileDevice || isMobile) {
const sValue = !ko.isObservable(fValue) && _.isFunction(fValue) ? fValue() : ko.unwrap(fValue); const sValue = !ko.isObservable(fValue) && isFunction(fValue) ? fValue() : ko.unwrap(fValue);
element.__opentip = new Opentip(element, { element.__opentip = new Opentip(element, {
'style': 'rainloopTip', 'style': 'rainloopTip',
@ -203,7 +204,7 @@ ko.bindingHandlers.tooltip = {
Globals = require('Common/Globals'); Globals = require('Common/Globals');
if ((!Globals.bMobileDevice || isMobile) && element.__opentip) { if ((!Globals.bMobileDevice || isMobile) && element.__opentip) {
const sValue = !ko.isObservable(fValue) && _.isFunction(fValue) ? fValue() : ko.unwrap(fValue); const sValue = !ko.isObservable(fValue) && isFunction(fValue) ? fValue() : ko.unwrap(fValue);
if (sValue) { if (sValue) {
element.__opentip.setContent(isI18N ? require('Common/Translator').i18n(sValue) : sValue); element.__opentip.setContent(isI18N ? require('Common/Translator').i18n(sValue) : sValue);
element.__opentip.activate(); element.__opentip.activate();
@ -240,7 +241,7 @@ ko.bindingHandlers.tooltipErrorTip = {
update: (element, fValueAccessor) => { update: (element, fValueAccessor) => {
const $el = $(element), const $el = $(element),
fValue = fValueAccessor(), fValue = fValueAccessor(),
value = !ko.isObservable(fValue) && _.isFunction(fValue) ? fValue() : ko.unwrap(fValue), value = !ko.isObservable(fValue) && isFunction(fValue) ? fValue() : ko.unwrap(fValue),
openTips = element.__opentip; openTips = element.__opentip;
if (openTips) { if (openTips) {
@ -797,8 +798,7 @@ ko.bindingHandlers.saveTrigger = {
ko.bindingHandlers.emailsTags = { ko.bindingHandlers.emailsTags = {
init: (element, fValueAccessor, fAllBindingsAccessor) => { init: (element, fValueAccessor, fAllBindingsAccessor) => {
const Utils = require('Common/Utils'), const EmailModel = require('Model/Email').default,
EmailModel = require('Model/Email').default,
$el = $(element), $el = $(element),
fValue = fValueAccessor(), fValue = fValueAccessor(),
fAllBindings = fAllBindingsAccessor(), fAllBindings = fAllBindingsAccessor(),
@ -817,20 +817,18 @@ ko.bindingHandlers.emailsTags = {
inputDelimiters: inputDelimiters, inputDelimiters: inputDelimiters,
autoCompleteSource: fAutoCompleteSource, autoCompleteSource: fAutoCompleteSource,
splitHook: (value) => { splitHook: (value) => {
const v = Utils.trim(value); const v = value.trim();
if (v && inputDelimiters.includes(v.substr(-1))) { if (v && inputDelimiters.includes(v.substr(-1))) {
return EmailModel.splitEmailLine(value); return EmailModel.splitEmailLine(value);
} }
return null; return null;
}, },
parseHook: (input) => parseHook: (input) =>
_.flatten( input.map(inputValue => {
input.map(inputValue => { const values = EmailModel.parseEmailLine(inputValue);
const values = EmailModel.parseEmailLine(inputValue); return values.length ? values : inputValue;
return values.length ? values : inputValue; }).flat(Infinity).map(
}) item => (item.toLine ? [item.toLine(false), item] : [item, null])
).map(
item => (_.isObject(item) ? [item.toLine(false), item] : [item, null])
), ),
change: (event) => { change: (event) => {
$el.data('EmailsTagsValue', event.target.value); $el.data('EmailsTagsValue', event.target.value);
@ -872,7 +870,7 @@ ko.bindingHandlers.command = {
if (!command.canExecute) { if (!command.canExecute) {
const __realCanExecute = command.__realCanExecute; const __realCanExecute = command.__realCanExecute;
if (_.isFunction(__realCanExecute)) { if (isFunction(__realCanExecute)) {
command.canExecute = ko.computed(() => command.enabled() && __realCanExecute.call(viewModel, viewModel)); command.canExecute = ko.computed(() => command.enabled() && __realCanExecute.call(viewModel, viewModel));
} else { } else {
command.canExecute = ko.computed(() => command.enabled() && !!__realCanExecute); command.canExecute = ko.computed(() => command.enabled() && !!__realCanExecute);
@ -912,11 +910,10 @@ ko.bindingHandlers.command = {
// extenders // extenders
ko.extenders.trimmer = (target) => { ko.extenders.trimmer = (target) => {
const Utils = require('Common/Utils'), const result = ko.computed({
result = ko.computed({
read: target, read: target,
write: (newValue) => { write: (newValue) => {
target(Utils.trim(newValue.toString())); target(newValue.toString().trim());
} }
}); });
@ -1116,7 +1113,7 @@ ko.observable.fn.deleteAccessHelper = function() {
ko.observable.fn.validateFunc = function(fFunc) { ko.observable.fn.validateFunc = function(fFunc) {
this.hasFuncError = ko.observable(false); this.hasFuncError = ko.observable(false);
if (_.isFunction(fFunc)) { if (isFunction(fFunc)) {
this.subscribe((value) => { this.subscribe((value) => {
this.hasFuncError(!fFunc(value)); this.hasFuncError(!fFunc(value));
}); });

View file

@ -1,5 +1,4 @@
import window from 'window'; import window from 'window';
import _ from '_';
import ko from 'ko'; import ko from 'ko';
import { FileType } from 'Common/Enums'; import { FileType } from 'Common/Enums';
@ -22,159 +21,123 @@ import Audio from 'Common/Audio';
* @param {string} sMimeType * @param {string} sMimeType
* @returns {string} * @returns {string}
*/ */
export const staticFileType = _.memoize((ext, mimeType) => { export const staticFileType = (() => {
ext = trim(ext).toLowerCase(); let cache = {};
mimeType = trim(mimeType).toLowerCase(); return (ext, mimeType) => {
ext = trim(ext).toLowerCase();
mimeType = trim(mimeType).toLowerCase();
let result = FileType.Unknown; let key = ext + mimeType;
const mimeTypeParts = mimeType.split('/'); if (cache[key]) {
return cache[key];
}
switch (true) { let result = FileType.Unknown;
case 'image' === mimeTypeParts[0] || ['png', 'jpg', 'jpeg', 'gif', 'bmp'].includes(ext): const mimeTypeParts = mimeType.split('/');
result = FileType.Image;
break;
case 'audio' === mimeTypeParts[0] || ['mp3', 'ogg', 'oga', 'wav'].includes(ext):
result = FileType.Audio;
break;
case 'video' === mimeTypeParts[0] || ['mkv', 'avi'].includes(ext):
result = FileType.Video;
break;
case ['php', 'js', 'css'].includes(ext):
result = FileType.Code;
break;
case 'eml' === ext || ['message/delivery-status', 'message/rfc822'].includes(mimeType):
result = FileType.Eml;
break;
case ('text' === mimeTypeParts[0] && 'html' !== mimeTypeParts[1]) || ['txt', 'log'].includes(ext):
result = FileType.Text;
break;
case 'text/html' === mimeType || ['html'].includes(ext):
result = FileType.Html;
break;
case [
'zip',
'7z',
'tar',
'rar',
'gzip',
'bzip',
'bzip2',
'x-zip',
'x-7z',
'x-rar',
'x-tar',
'x-gzip',
'x-bzip',
'x-bzip2',
'x-zip-compressed',
'x-7z-compressed',
'x-rar-compressed'
].includes(mimeTypeParts[1]) || ['zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2'].includes(ext):
result = FileType.Archive;
break;
case ['pdf', 'x-pdf'].includes(mimeTypeParts[1]) || ['pdf'].includes(ext):
result = FileType.Pdf;
break;
case ['application/pgp-signature', 'application/pgp-keys'].includes(mimeType) ||
['asc', 'pem', 'ppk'].includes(ext):
result = FileType.Certificate;
break;
case ['application/pkcs7-signature'].includes(mimeType) || ['p7s'].includes(ext):
result = FileType.CertificateBin;
break;
case [
'rtf',
'msword',
'vnd.msword',
'vnd.openxmlformats-officedocument.wordprocessingml.document',
'vnd.openxmlformats-officedocument.wordprocessingml.template',
'vnd.ms-word.document.macroEnabled.12',
'vnd.ms-word.template.macroEnabled.12'
].includes(mimeTypeParts[1]):
result = FileType.WordText;
break;
case [
'excel',
'ms-excel',
'vnd.ms-excel',
'vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'vnd.openxmlformats-officedocument.spreadsheetml.template',
'vnd.ms-excel.sheet.macroEnabled.12',
'vnd.ms-excel.template.macroEnabled.12',
'vnd.ms-excel.addin.macroEnabled.12',
'vnd.ms-excel.sheet.binary.macroEnabled.12'
].includes(mimeTypeParts[1]):
result = FileType.Sheet;
break;
case [
'powerpoint',
'ms-powerpoint',
'vnd.ms-powerpoint',
'vnd.openxmlformats-officedocument.presentationml.presentation',
'vnd.openxmlformats-officedocument.presentationml.template',
'vnd.openxmlformats-officedocument.presentationml.slideshow',
'vnd.ms-powerpoint.addin.macroEnabled.12',
'vnd.ms-powerpoint.presentation.macroEnabled.12',
'vnd.ms-powerpoint.template.macroEnabled.12',
'vnd.ms-powerpoint.slideshow.macroEnabled.12'
].includes(mimeTypeParts[1]):
result = FileType.Presentation;
break;
// no default
}
return result; switch (true) {
}); case 'image' === mimeTypeParts[0] || ['png', 'jpg', 'jpeg', 'gif', 'bmp'].includes(ext):
result = FileType.Image;
break;
case 'audio' === mimeTypeParts[0] || ['mp3', 'ogg', 'oga', 'wav'].includes(ext):
result = FileType.Audio;
break;
case 'video' === mimeTypeParts[0] || ['mkv', 'avi'].includes(ext):
result = FileType.Video;
break;
case ['php', 'js', 'css'].includes(ext):
result = FileType.Code;
break;
case 'eml' === ext || ['message/delivery-status', 'message/rfc822'].includes(mimeType):
result = FileType.Eml;
break;
case ('text' === mimeTypeParts[0] && 'html' !== mimeTypeParts[1]) || ['txt', 'log'].includes(ext):
result = FileType.Text;
break;
case 'text/html' === mimeType || ['html'].includes(ext):
result = FileType.Html;
break;
case [
'zip',
'7z',
'tar',
'rar',
'gzip',
'bzip',
'bzip2',
'x-zip',
'x-7z',
'x-rar',
'x-tar',
'x-gzip',
'x-bzip',
'x-bzip2',
'x-zip-compressed',
'x-7z-compressed',
'x-rar-compressed'
].includes(mimeTypeParts[1]) || ['zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2'].includes(ext):
result = FileType.Archive;
break;
case ['pdf', 'x-pdf'].includes(mimeTypeParts[1]) || ['pdf'].includes(ext):
result = FileType.Pdf;
break;
case ['application/pgp-signature', 'application/pgp-keys'].includes(mimeType) ||
['asc', 'pem', 'ppk'].includes(ext):
result = FileType.Certificate;
break;
case ['application/pkcs7-signature'].includes(mimeType) || ['p7s'].includes(ext):
result = FileType.CertificateBin;
break;
case [
'rtf',
'msword',
'vnd.msword',
'vnd.openxmlformats-officedocument.wordprocessingml.document',
'vnd.openxmlformats-officedocument.wordprocessingml.template',
'vnd.ms-word.document.macroEnabled.12',
'vnd.ms-word.template.macroEnabled.12'
].includes(mimeTypeParts[1]):
result = FileType.WordText;
break;
case [
'excel',
'ms-excel',
'vnd.ms-excel',
'vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'vnd.openxmlformats-officedocument.spreadsheetml.template',
'vnd.ms-excel.sheet.macroEnabled.12',
'vnd.ms-excel.template.macroEnabled.12',
'vnd.ms-excel.addin.macroEnabled.12',
'vnd.ms-excel.sheet.binary.macroEnabled.12'
].includes(mimeTypeParts[1]):
result = FileType.Sheet;
break;
case [
'powerpoint',
'ms-powerpoint',
'vnd.ms-powerpoint',
'vnd.openxmlformats-officedocument.presentationml.presentation',
'vnd.openxmlformats-officedocument.presentationml.template',
'vnd.openxmlformats-officedocument.presentationml.slideshow',
'vnd.ms-powerpoint.addin.macroEnabled.12',
'vnd.ms-powerpoint.presentation.macroEnabled.12',
'vnd.ms-powerpoint.template.macroEnabled.12',
'vnd.ms-powerpoint.slideshow.macroEnabled.12'
].includes(mimeTypeParts[1]):
result = FileType.Presentation;
break;
// no default
}
return cache[key] = result;
};
})();
/** /**
* @param {string} sFileType * @param {string} sFileType
* @returns {string} * @returns {string}
*/ */
export const staticIconClass = _.memoize((fileType) => { export const staticIconClass = fileType => FileType.getIconClass(fileType);
let resultText = '',
resultClass = 'icon-file';
switch (fileType) {
case FileType.Text:
case FileType.Eml:
case FileType.WordText:
resultClass = 'icon-file-text';
break;
case FileType.Html:
case FileType.Code:
resultClass = 'icon-file-code';
break;
case FileType.Image:
resultClass = 'icon-file-image';
break;
case FileType.Audio:
resultClass = 'icon-file-music';
break;
case FileType.Video:
resultClass = 'icon-file-movie';
break;
case FileType.Archive:
resultClass = 'icon-file-zip';
break;
case FileType.Certificate:
case FileType.CertificateBin:
resultClass = 'icon-file-certificate';
break;
case FileType.Sheet:
resultClass = 'icon-file-excel';
break;
case FileType.Presentation:
resultClass = 'icon-file-chart-graph';
break;
case FileType.Pdf:
resultText = 'pdf';
resultClass = 'icon-none';
break;
// no default
}
return [resultClass, resultText];
});
/** /**
* @static * @static
@ -187,7 +150,8 @@ export const staticCombinedIconClass = (data) => {
if (isNonEmptyArray(data)) { if (isNonEmptyArray(data)) {
result = 'icon-attachment'; result = 'icon-attachment';
types = _.uniq(_.compact(data.map(item => (item ? staticFileType(getFileExtension(item[0]), item[1]) : '')))); types = data.map(item => item ? staticFileType(getFileExtension(item[0]), item[1]) : '')
.filter((value, index, self) => !!value && self.indexOf(value) == index);
if (types && 1 === types.length && types[0]) { if (types && 1 === types.length && types[0]) {
switch (types[0]) { switch (types[0]) {

View file

@ -1,4 +1,3 @@
import _ from '_';
import addressparser from 'emailjs-addressparser'; import addressparser from 'emailjs-addressparser';
import { trim, encodeHtml, isNonEmptyArray } from 'Common/Utils'; import { trim, encodeHtml, isNonEmptyArray } from 'Common/Utils';
@ -184,11 +183,9 @@ class EmailModel {
static parseEmailLine(line) { static parseEmailLine(line) {
const parsedResult = addressparser(line); const parsedResult = addressparser(line);
if (isNonEmptyArray(parsedResult)) { if (isNonEmptyArray(parsedResult)) {
return _.compact( return parsedResult.map(item =>
parsedResult.map(item => item.address ? new EmailModel(item.address.replace(/^[<]+(.*)[>]+$/g, '$1'), item.name || '') : null
item.address ? new EmailModel(item.address.replace(/^[<]+(.*)[>]+$/g, '$1'), item.name || '') : null ).filter(value => !!value);
)
);
} }
return []; return [];

View file

@ -1,4 +1,3 @@
import _ from '_';
import ko from 'ko'; import ko from 'ko';
import { FilterRulesType, FiltersAction } from 'Common/Enums'; import { FilterRulesType, FiltersAction } from 'Common/Enums';
@ -230,12 +229,10 @@ class FilterModel extends AbstractModel {
if (isNonEmptyArray(json.Conditions)) { if (isNonEmptyArray(json.Conditions)) {
this.conditions( this.conditions(
_.compact( json.Conditions.map(aData => {
json.Conditions.map(aData => { const filterCondition = new FilterConditionModel();
const filterCondition = new FilterConditionModel(); return filterCondition && filterCondition.parse(aData) ? filterCondition : null;
return filterCondition && filterCondition.parse(aData) ? filterCondition : null; }).filter(value => !!value)
})
)
); );
} }

View file

@ -1,4 +1,3 @@
import _ from '_';
import $ from '$'; import $ from '$';
import ko from 'ko'; import ko from 'ko';
import moment from 'moment'; import moment from 'moment';
@ -200,13 +199,9 @@ class MessageModel extends AbstractModel {
* @returns {Array} * @returns {Array}
*/ */
getEmails(properties) { getEmails(properties) {
return _.compact( return properties.reduce((carry, property) => carry.concat(this[property]), []).map(
_.uniq( oItem => oItem ? oItem.email : ''
_.reduce(properties, (carry, property) => carry.concat(this[property]), []).map( ).filter((value, index, self) => !!value && self.indexOf(value) == index);
(oItem) => (oItem ? oItem.email : '')
)
)
);
} }
/** /**

View file

@ -1,4 +1,3 @@
import _ from '_';
import ko from 'ko'; import ko from 'ko';
import { windowResizeCallback, isArray, trim, delegateRunOnDestroy } from 'Common/Utils'; import { windowResizeCallback, isArray, trim, delegateRunOnDestroy } from 'Common/Utils';
@ -113,12 +112,10 @@ class FiltersUserSettings {
this.serverError(false); this.serverError(false);
this.filters( this.filters(
_.compact( data.Result.Filters.map(aItem => {
data.Result.Filters.map(aItem => { const filter = new FilterModel();
const filter = new FilterModel(); return filter && filter.parse(aItem) ? filter : null;
return filter && filter.parse(aItem) ? filter : null; }).filter(value => !!value)
})
)
); );
this.modules(data.Result.Modules ? data.Result.Modules : {}); this.modules(data.Result.Modules ? data.Result.Modules : {});

View file

@ -1,5 +1,4 @@
import ko from 'ko'; import ko from 'ko';
import _ from '_';
import { Magics } from 'Common/Enums'; import { Magics } from 'Common/Enums';
import * as Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
@ -17,7 +16,9 @@ class AccountUserStore {
} }
computers() { computers() {
this.accountsEmails = ko.computed(() => _.compact(this.accounts().map(item => (item ? item.email : null)))); this.accountsEmails = ko.computed(
() => this.accounts().map(item => (item ? item.email : null)).filter(value => !!value)
);
this.accountsUnreadCount = ko.computed(() => 0); this.accountsUnreadCount = ko.computed(() => 0);
// this.accountsUnreadCount = ko.computed(() => { // this.accountsUnreadCount = ko.computed(() => {

View file

@ -1,5 +1,4 @@
import ko from 'ko'; import ko from 'ko';
import _ from '_';
import { settingsGet } from 'Storage/Settings'; import { settingsGet } from 'Storage/Settings';
@ -95,7 +94,7 @@ class FolderUserStore {
}); });
this.folderListSystem = ko.computed(() => this.folderListSystem = ko.computed(() =>
_.compact(this.folderListSystemNames().map(name => getFolderFromCacheList(name))) this.folderListSystemNames().map(name => getFolderFromCacheList(name)).filter(value => !!value)
); );
this.folderMenuForMove = ko.computed(() => this.folderMenuForMove = ko.computed(() =>
@ -203,7 +202,7 @@ class FolderUserStore {
return limit <= result.length; return limit <= result.length;
}); });
return _.uniq(result); return result.filter((value, index, self) => self.indexOf(value) == index);
} }
} }

View file

@ -1,4 +1,3 @@
import _ from '_';
import ko from 'ko'; import ko from 'ko';
class IdentityUserStore { class IdentityUserStore {
@ -6,7 +5,9 @@ class IdentityUserStore {
this.identities = ko.observableArray([]); this.identities = ko.observableArray([]);
this.identities.loading = ko.observable(false).extend({ throttle: 100 }); this.identities.loading = ko.observable(false).extend({ throttle: 100 });
this.identitiesIDS = ko.computed(() => _.compact(this.identities().map(item => (item ? item.id : null)))); this.identitiesIDS = ko.computed(
() => this.identities().map(item => (item ? item.id : null)).filter(value => !!value)
);
} }
} }

View file

@ -153,7 +153,9 @@ class MessageUserStore {
focusedMessage = this.selectorMessageFocused(); focusedMessage = this.selectorMessageFocused();
if (checked.length) { if (checked.length) {
return _.union(checked, selectedMessage ? [selectedMessage] : []); return selectedMessage
? checked.concat([selectedMessage]).filter((value, index, self) => self.indexOf(value) == index)
: checked;
} else if (selectedMessage) { } else if (selectedMessage) {
return [selectedMessage]; return [selectedMessage];
} }
@ -167,7 +169,7 @@ class MessageUserStore {
if (message) { if (message) {
result.push(message.uid); result.push(message.uid);
if (1 < message.threadsLen()) { if (1 < message.threadsLen()) {
result = _.union(result, message.threads()); result = result.concat(message.threads()).filter((value, index, self) => self.indexOf(value) == index);
} }
} }
}); });

View file

@ -42,62 +42,36 @@ class PgpUserStore {
} }
findPublicKeysByEmail(email) { findPublicKeysByEmail(email) {
return _.compact( return this.openpgpkeysPublic().map(item => {
_.flatten( const key = item && item.emails.includes(email) ? item : null;
this.openpgpkeysPublic().map(item => { return key ? key.getNativeKeys() : [null];
const key = item && item.emails.includes(email) ? item : null; }).flat().filter(value => !!value);
return key ? key.getNativeKeys() : [null];
}),
true
)
);
} }
findPublicKeysBySigningKeyIds(signingKeyIds) { findPublicKeysBySigningKeyIds(signingKeyIds) {
return _.compact( return signingKeyIds.map(id => {
_.flatten( const key = id && id.toHex ? this.findPublicKeyByHex(id.toHex()) : null;
signingKeyIds.map(id => { return key ? key.getNativeKeys() : [null];
const key = id && id.toHex ? this.findPublicKeyByHex(id.toHex()) : null; }).flat().filter(value => !!value);
return key ? key.getNativeKeys() : [null];
}),
true
)
);
} }
findPrivateKeysByEncryptionKeyIds(encryptionKeyIds, recipients, returnWrapKeys) { findPrivateKeysByEncryptionKeyIds(encryptionKeyIds, recipients, returnWrapKeys) {
let result = isArray(encryptionKeyIds) let result = isArray(encryptionKeyIds)
? _.compact( ? encryptionKeyIds.map(id => {
_.flatten( const key = id && id.toHex ? this.findPrivateKeyByHex(id.toHex()) : null;
encryptionKeyIds.map(id => { return key ? (returnWrapKeys ? [key] : key.getNativeKeys()) : [null];
const key = id && id.toHex ? this.findPrivateKeyByHex(id.toHex()) : null; }).flat().filter(value => !!value)
return key ? (returnWrapKeys ? [key] : key.getNativeKeys()) : [null];
}),
true
)
)
: []; : [];
if (0 === result.length && isNonEmptyArray(recipients)) { if (0 === result.length && isNonEmptyArray(recipients)) {
result = _.uniq( result = recipients.map(sEmail => {
_.compact( const keys = sEmail ? this.findAllPrivateKeysByEmailNotNative(sEmail) : null;
_.flatten( return keys
recipients.map(sEmail => { ? returnWrapKeys
const keys = sEmail ? this.findAllPrivateKeysByEmailNotNative(sEmail) : null; ? keys
return keys : keys.map(key => key.getNativeKeys()).flat()
? returnWrapKeys : [null];
? keys }).flat().filter((key, index, self) => key => !!key.id && self.indexOf(key) == index);
: _.flatten(
keys.map(key => key.getNativeKeys()),
true
)
: [null];
}),
true
)
),
(key) => key.id
);
} }
return result; return result;
@ -297,7 +271,7 @@ class PgpUserStore {
} else if (validPrivateKey) { } else if (validPrivateKey) {
const keyIds = isNonEmptyArray(signingKeyIds) ? signingKeyIds : null, const keyIds = isNonEmptyArray(signingKeyIds) ? signingKeyIds : null,
additional = keyIds additional = keyIds
? _.compact(keyIds.map(item => (item && item.toHex ? item.toHex() : null))).join(', ') ? keyIds.map(item => (item && item.toHex ? item.toHex() : null)).filter(value => !!value).join(', ')
: ''; : '';
store.controlsHelper( store.controlsHelper(
@ -354,7 +328,7 @@ class PgpUserStore {
} else { } else {
const keyIds = isNonEmptyArray(signingKeyIds) ? signingKeyIds : null, const keyIds = isNonEmptyArray(signingKeyIds) ? signingKeyIds : null,
additional = keyIds additional = keyIds
? _.compact(keyIds.map(item => (item && item.toHex ? item.toHex() : null))).join(', ') ? keyIds.map(item => (item && item.toHex ? item.toHex() : null)).filter(value => !!value).join(', ')
: ''; : '';
store.controlsHelper( store.controlsHelper(

View file

@ -1,5 +1,4 @@
import ko from 'ko'; import ko from 'ko';
import _ from '_';
// import Remote from 'Remote/User/Ajax'; // import Remote from 'Remote/User/Ajax';
@ -16,7 +15,7 @@ class TemplateUserStore {
subscribers() { subscribers() {
this.templates.subscribe((list) => { this.templates.subscribe((list) => {
this.templatesNames(_.compact(list.map(item => (item ? item.name : null)))); this.templatesNames(list.map(item => (item ? item.name : null)).filter(value => !!value));
}); });
// this.templatesNames.subscribe((aList) => { // this.templatesNames.subscribe((aList) => {

View file

@ -600,13 +600,13 @@ class ComposePopupView extends AbstractViewNext {
case ComposeType.ReplyAll: case ComposeType.ReplyAll:
case ComposeType.Forward: case ComposeType.Forward:
case ComposeType.ForwardAsAttachment: case ComposeType.ForwardAsAttachment:
_.union(message.to, message.cc, message.bcc).forEach(fEachHelper); message.to.concat(message.cc, message.bcc).forEach(fEachHelper);
if (!resultIdentity) { if (!resultIdentity) {
message.deliveredTo.forEach(fEachHelper); message.deliveredTo.forEach(fEachHelper);
} }
break; break;
case ComposeType.Draft: case ComposeType.Draft:
_.union(message.from, message.replyTo).forEach(fEachHelper); message.from.concat(message.replyTo).forEach(fEachHelper);
break; break;
// no default // no default
} }
@ -859,7 +859,8 @@ class ComposePopupView extends AbstractViewNext {
addEmailsTo(fKoValue, emails) { addEmailsTo(fKoValue, emails) {
if (isNonEmptyArray(emails)) { if (isNonEmptyArray(emails)) {
const value = trim(fKoValue()), const value = trim(fKoValue()),
values = _.uniq(_.compact(emails.map(item => (item ? item.toLine(false) : null)))); values = emails.map(item => item ? item.toLine(false) : null)
.filter((value, index, self) => !!value && self.indexOf(value) == index);
fKoValue(value + ('' === value ? '' : ', ') + trim(values.join(', '))); fKoValue(value + ('' === value ? '' : ', ') + trim(values.join(', ')));
} }

View file

@ -1,4 +1,3 @@
import _ from '_';
import $ from '$'; import $ from '$';
import ko from 'ko'; import ko from 'ko';
import key from 'key'; import key from 'key';
@ -44,7 +43,9 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
this.signKey = ko.observable(null); this.signKey = ko.observable(null);
this.encryptKeys = ko.observableArray([]); this.encryptKeys = ko.observableArray([]);
this.encryptKeysView = ko.computed(() => _.compact(this.encryptKeys().map(oKey => (oKey ? oKey.key : null)))); this.encryptKeysView = ko.computed(
() => this.encryptKeys().map(oKey => (oKey ? oKey.key : null)).filter(value => !!value)
);
this.privateKeysOptions = ko.computed(() => { this.privateKeysOptions = ko.computed(() => {
const opts = PgpStore.openpgpkeysPrivate().map((oKey, iIndex) => { const opts = PgpStore.openpgpkeysPrivate().map((oKey, iIndex) => {
@ -59,7 +60,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
})); }));
}); });
return _.compact(_.flatten(opts, true)); return opts.flat().filter(value => !!value);
}); });
this.publicKeysOptions = ko.computed(() => { this.publicKeysOptions = ko.computed(() => {
@ -74,7 +75,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
'class': index % 2 ? 'odd' : 'even' 'class': index % 2 ? 'odd' : 'even'
})); }));
}); });
return _.compact(_.flatten(opts, true)); return opts.flat().filter(value => !!value);
}); });
this.submitRequest = ko.observable(false); this.submitRequest = ko.observable(false);
@ -159,7 +160,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
this.encryptKeys().forEach(oKey => { this.encryptKeys().forEach(oKey => {
if (oKey && oKey.key) { if (oKey && oKey.key) {
aPublicKeys = aPublicKeys.concat(_.compact(_.flatten(oKey.key.getNativeKeys()))); aPublicKeys = aPublicKeys.concat(oKey.key.getNativeKeys().flat(Infinity).filter(value => !!value));
} else if (oKey && oKey.email) { } else if (oKey && oKey.email) {
this.notification( this.notification(
i18n('PGP_NOTIFICATIONS/NO_PUBLIC_KEYS_FOUND_FOR', { i18n('PGP_NOTIFICATIONS/NO_PUBLIC_KEYS_FOUND_FOR', {
@ -355,13 +356,11 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
} }
rec = rec.join(', ').split(','); rec = rec.join(', ').split(',');
rec = _.compact( rec = rec.map(value => {
rec.map(value => {
email.clear(); email.clear();
email.parse(trim(value)); email.parse(trim(value));
return '' === email.email ? false : email.email; return '' === email.email ? false : email.email;
}) }).filter(value => !!value);
);
if (identity && identity.email()) { if (identity && identity.email()) {
emailLine = identity.email(); emailLine = identity.email();
@ -383,28 +382,22 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
if (rec && 0 < rec.length) { if (rec && 0 < rec.length) {
this.encryptKeys( this.encryptKeys(
_.uniq( rec.map(recEmail => {
_.compact( const keys = PgpStore.findAllPublicKeysByEmailNotNative(recEmail);
_.flatten( return keys
rec.map(recEmail => { ? keys.map(publicKey => ({
const keys = PgpStore.findAllPublicKeysByEmailNotNative(recEmail); 'empty': !publicKey,
return keys 'selected': ko.observable(!!publicKey),
? keys.map(publicKey => ({ 'removable': ko.observable(
'empty': !publicKey, !this.sign() || !this.signKey() || this.signKey().key.id !== publicKey.id
'selected': ko.observable(!!publicKey), ),
'removable': ko.observable( 'users': publicKey ? publicKey.users || [recEmail] : [recEmail],
!this.sign() || !this.signKey() || this.signKey().key.id !== publicKey.id 'hash': publicKey ? publicKey.id.substr(KEY_NAME_SUBSTR).toUpperCase() : '',
), 'key': publicKey
'users': publicKey ? publicKey.users || [recEmail] : [recEmail], }))
'hash': publicKey ? publicKey.id.substr(KEY_NAME_SUBSTR).toUpperCase() : '', : [];
'key': publicKey }).flat().filter(
})) (encryptKey, index, self) => encryptKey => !!encryptKey.hash && self.indexOf(encryptKey) == index
: [];
}),
true
)
),
(encryptKey) => encryptKey.hash
) )
); );

View file

@ -1,5 +1,4 @@
import window from 'window'; import window from 'window';
import _ from '_';
import $ from '$'; import $ from '$';
import ko from 'ko'; import ko from 'ko';
import key from 'key'; import key from 'key';
@ -171,7 +170,9 @@ class ContactsPopupView extends AbstractViewNext {
const checked = this.contactsChecked(), const checked = this.contactsChecked(),
selected = this.currentContact(); selected = this.currentContact();
return _.union(checked, selected ? [selected] : []); return selected
? checked.concat([selected]).filter((value, index, self) => self.indexOf(value) == index)
: checked;
}); });
this.contactsCheckedOrSelectedUids = ko.computed(() => this.contactsCheckedOrSelectedUids = ko.computed(() =>
@ -253,7 +254,7 @@ class ContactsPopupView extends AbstractViewNext {
return null; return null;
}); });
aE = _.compact(aE); aE = aE.filter(value => !!value);
} }
if (isNonEmptyArray(aE)) { if (isNonEmptyArray(aE)) {
@ -596,7 +597,7 @@ class ContactsPopupView extends AbstractViewNext {
return contact.parse(item) ? contact : null; return contact.parse(item) ? contact : null;
}); });
list = _.compact(list); list = list.filter(value => !!value);
count = pInt(data.Result.Count); count = pInt(data.Result.Count);
count = 0 < count ? count : 0; count = 0 < count ? count : 0;

View file

@ -453,11 +453,11 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
// aTo = [], // aTo = [],
// EmailModel = require('Model/Email').default, // EmailModel = require('Model/Email').default,
// fParseEmailLine = function(sLine) { // fParseEmailLine = function(sLine) {
// return sLine ? _.compact([window.decodeURIComponent(sLine)].map(sItem => { // return sLine ? [window.decodeURIComponent(sLine)].map(sItem => {
// var oEmailModel = new EmailModel(); // var oEmailModel = new EmailModel();
// oEmailModel.parse(sItem); // oEmailModel.parse(sItem);
// return '' !== oEmailModel.email ? oEmailModel : null; // return '' !== oEmailModel.email ? oEmailModel : null;
// })) : null; // }).filter(value => !!value) : null;
// } // }
// ; // ;
// //
@ -477,26 +477,24 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
listIndex = 0; listIndex = 0;
const div = $('<div>'), const div = $('<div>'),
dynamicEls = _.compact( dynamicEls = this.message().attachments().map(item => {
this.message().attachments().map(item => { if (item && !item.isLinked && item.isImage()) {
if (item && !item.isLinked && item.isImage()) { if (item === attachment) {
if (item === attachment) { index = listIndex;
index = listIndex;
}
listIndex += 1;
return {
src: item.linkPreview(),
thumb: item.linkThumbnail(),
subHtml: item.fileName,
downloadUrl: item.linkPreview()
};
} }
return null; listIndex += 1;
})
); return {
src: item.linkPreview(),
thumb: item.linkThumbnail(),
subHtml: item.fileName,
downloadUrl: item.linkPreview()
};
}
return null;
}).filter(value => !!value);
if (0 < dynamicEls.length) { if (0 < dynamicEls.length) {
div.on('onBeforeOpen.lg', () => { div.on('onBeforeOpen.lg', () => {
@ -885,7 +883,7 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
getAttachmentsHashes() { getAttachmentsHashes() {
const atts = this.message() ? this.message().attachments() : []; const atts = this.message() ? this.message().attachments() : [];
return _.compact(atts.map(item => (item && !item.isLinked && item.checked() ? item.download : ''))); return atts.map(item => (item && !item.isLinked && item.checked() ? item.download : '')).filter(value => !!value);
} }
downloadAsZip() { downloadAsZip() {

16
dev/polyfill.js Normal file
View file

@ -0,0 +1,16 @@
Array.prototype.flat || Object.defineProperty(Array.prototype, 'flat', {
configurable: true,
value: function flat(depth) {
depth = isNaN(depth) ? 1 : Number(depth);
return depth ? Array.prototype.reduce.call(this, (acc, cur) => {
if (Array.isArray(cur)) {
acc.push.apply(acc, flat.call(cur, depth - 1));
} else {
acc.push(cur);
}
return acc;
}, []) : this.slice();
},
writable: true
});

View file

@ -103,8 +103,7 @@
"raw-loader": "4.0.0", "raw-loader": "4.0.0",
"rimraf": "3.0.2", "rimraf": "3.0.2",
"simplestatemanager": "4.1.1", "simplestatemanager": "4.1.1",
"style-loader": "1.1.3", "style-loader": "1.1.3"
"underscore": "1.9.2"
}, },
"dependencies": { "dependencies": {
"gulp-terser": "^1.2.0", "gulp-terser": "^1.2.0",

View file

@ -72,7 +72,8 @@ config.paths.js = {
libs: { libs: {
name: 'libs.js', name: 'libs.js',
src: [ src: [
'node_modules/jquery/dist/jquery.min.js', 'dev/polyfill.js',
'node_modules/jquery/dist/jquery.slim.min.js',
'vendors/jquery-ui/js/jquery-ui-1.12.1.custom.min.js', // custom 'vendors/jquery-ui/js/jquery-ui-1.12.1.custom.min.js', // custom
'vendors/inputosaurus/inputosaurus.js', // custom (modified) 'vendors/inputosaurus/inputosaurus.js', // custom (modified)
'vendors/routes/signals.min.js', // fixed 'vendors/routes/signals.min.js', // fixed
@ -82,7 +83,7 @@ config.paths.js = {
'vendors/keymaster/keymaster.js', // custom (modified) 'vendors/keymaster/keymaster.js', // custom (modified)
'vendors/qr.js/qr.min.js', // fixed (license) 'vendors/qr.js/qr.min.js', // fixed (license)
'vendors/bootstrap/js/bootstrap.min.js', // fixed 'vendors/bootstrap/js/bootstrap.min.js', // fixed
'node_modules/underscore/underscore-min.js', 'vendors/underscore/underscore-min.custom.js',
'node_modules/moment/min/moment.min.js', 'node_modules/moment/min/moment.min.js',
'node_modules/knockout/build/output/knockout-latest.js', 'node_modules/knockout/build/output/knockout-latest.js',
'node_modules/knockout-sortable/build/knockout-sortable.min.js ', 'node_modules/knockout-sortable/build/knockout-sortable.min.js ',

View file

@ -0,0 +1,6 @@
// Underscore.js 1.9.2
// https://underscorejs.org
// (c) 2009-2018 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
(()=>{var e=function(t){return t instanceof e?t:this instanceof e?void 0:new e(t)};"undefined"==typeof exports||exports.nodeType?("object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||this||{})._=e:("undefined"!=typeof module&&!module.nodeType&&module.exports&&(exports=module.exports=e),exports._=e);e.VERSION="1.9.2";var t=function(e,t,n,o,l){if(!(o instanceof t))return e.apply(n,l);var r,u="object"!=typeof(r=e.prototype)?{}:Object.create(r),i=e.apply(u,l);return"object"==typeof i?i:u};e.defer=(()=>{var e=(e,t,...n)=>setTimeout(()=>e.apply(null,n),t),n=function(...o){for(var l=0,r=[o[l++],1];l<o.length;)r.push(o[l++]);return t(e,n,this,this,r)};return n})(),e.throttle=function(e,t,n){var o,l,r,u,i=0;n||(n={});var a=function(){i=!1===n.leading?0:Date.now(),o=null,u=e.apply(l,r),o||(l=r=null)},f=function(){var f=Date.now();i||!1!==n.leading||(i=f);var p=t-(f-i);return l=this,r=arguments,p<=0||p>t?(o&&(clearTimeout(o),o=null),i=f,u=e.apply(l,r),o||(l=r=null)):o||!1===n.trailing||(o=setTimeout(a,p)),u};return f.cancel=function(){clearTimeout(o),i=0,o=l=r=null},f},e.debounce=function(e,t,n){var o,l,r=function(t,n){o=null,n&&(l=e.apply(t,n))},u=function(...u){if(o&&clearTimeout(o),n){var i=!o;o=setTimeout(r,t),i&&(l=e.apply(this,u))}else{var a=this;o=setTimeout(()=>r.apply(null,[a,u]),t)}return l};return u.cancel=function(){clearTimeout(o),o=null},u},"function"==typeof define&&define.amd&&define("underscore",[],function(){return e})})();

169
vendors/underscore/underscore.custom.js vendored Normal file
View file

@ -0,0 +1,169 @@
// Underscore.js 1.9.2
// https://underscorejs.org
// (c) 2009-2018 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
/*
_.debounce
_.defer
_.throttle
*/
(() => {
// Baseline setup
// --------------
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) {
if (obj instanceof _) return obj;
if (!(this instanceof _)) return new _(obj);
};
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for their old module API. If we're in
// the browser, add `_` as a global object.
// (`nodeType` is checked to ensure that `module`
// and `exports` are not HTML elements.)
if (typeof exports != 'undefined' && !exports.nodeType) {
if (typeof module != 'undefined' && !module.nodeType && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
// Establish the root object, `window` (`self`) in the browser, `global`
// on the server, or `this` in some virtual machines. We use `self`
// instead of `window` for `WebWorker` support.
var root = typeof self == 'object' && self.self === self && self ||
typeof global == 'object' && global.global === global && global ||
this ||
{};
root._ = _;
}
// Current version.
_.VERSION = '1.9.2';
// An internal function for creating a new object that inherits from another.
var baseCreate = function(prototype) {
if (typeof prototype !== 'object') return {};
return Object.create(prototype);
};
// Function (ahem) Functions
// ------------------
// Determines whether to execute a function as a constructor
// or a normal function with the provided arguments.
var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
var self = baseCreate(sourceFunc.prototype);
var result = sourceFunc.apply(self, args);
return (typeof result === 'object') ? result : self;
};
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_.defer = (() => {
var func = (func, wait, ...args) => setTimeout(() => func.apply(null, args), wait);
var bound = function(...params) {
var position = 0;
var args = [params[position++], 1];
while (position < params.length) args.push(params[position++]);
return executeBound(func, bound, this, this, args);
};
return bound;
})();
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time. Normally, the throttled function will run
// as much as it can, without ever going more than once per `wait` duration;
// but if you'd like to disable the execution on the leading edge, pass
// `{leading: false}`. To disable execution on the trailing edge, ditto.
_.throttle = function(func, wait, options) {
var timeout, context, args, result;
var previous = 0;
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : Date.now();
timeout = null;
result = func.apply(context, args);
if (!timeout) context = args = null;
};
var throttled = function() {
var now = Date.now();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
};
throttled.cancel = function() {
clearTimeout(timeout);
previous = 0;
timeout = context = args = null;
};
return throttled;
};
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
var timeout, result;
var later = function(context, args) {
timeout = null;
if (args) result = func.apply(context, args);
};
var debounced = function(...args) {
if (timeout) clearTimeout(timeout);
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(later, wait);
if (callNow) result = func.apply(this, args);
} else {
var obj = this;
timeout = setTimeout(() => later.apply(null, [obj, args]), wait);
}
return result;
};
debounced.cancel = function() {
clearTimeout(timeout);
timeout = null;
};
return debounced;
};
// AMD registration happens at the end for compatibility with AMD loaders
// that may not enforce next-turn semantics on modules. Even though general
// practice for AMD registration is to be anonymous, underscore registers
// as a named module because, like jQuery, it is a base library that is
// popular enough to be bundled in a third party lib, but not be part of
// an AMD load request. Those cases could generate an error when an
// anonymous define() is called outside of a loader request.
if (typeof define == 'function' && define.amd) {
define('underscore', [], function() {
return _;
});
}
})();

View file

@ -6775,11 +6775,6 @@ unc-path-regex@^0.1.2:
version "0.1.2" version "0.1.2"
resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
underscore@1.9.2:
version "1.9.2"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.2.tgz#0c8d6f536d6f378a5af264a72f7bec50feb7cf2f"
integrity sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ==
undertaker-registry@^1.0.0: undertaker-registry@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50" resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50"