Reduce JavaScript footprint

This commit is contained in:
the-djmaze 2022-10-10 13:52:56 +02:00
parent 689126c57d
commit b12852bd08
42 changed files with 240 additions and 426 deletions

View file

@ -27,12 +27,10 @@ export class AbstractCollectionModel extends Array
forEachObjectEntry(json, (key, value) => '@' !== key[0] && (result[key] = value));
json = json['@Collection'];
}
if (isArray(json)) {
json.forEach(item => {
item && itemCallback && (item = itemCallback(item, result));
item && result.push(item);
});
}
isArray(json) && json.forEach(item => {
item && itemCallback && (item = itemCallback(item, result));
item && result.push(item);
});
}
return result;
}

View file

@ -38,12 +38,12 @@ export class ComposeAttachmentModel extends AbstractModel {
this.addComputables({
progressText: () => {
const p = this.progress();
return 0 === p ? '' : '' + (98 < p ? 100 : p) + '%';
return 1 > p ? '' : (100 < p ? 100 : p) + '%';
},
progressStyle: () => {
const p = this.progress();
return 0 === p ? '' : 'width:' + (98 < p ? 100 : p) + '%';
return 1 > p ? '' : 'width:' + (100 < p ? 100 : p) + '%';
},
title: () => this.error() || this.fileName(),
@ -54,14 +54,9 @@ export class ComposeAttachmentModel extends AbstractModel {
},
mimeType: () => FileInfo.getContentType(this.fileName()),
fileExt: () => FileInfo.getExtension(this.fileName())
fileExt: () => FileInfo.getExtension(this.fileName()),
iconClass: () => FileInfo.getIconClass(this.fileExt(), this.mimeType())
});
}
/**
* @returns {string}
*/
iconClass() {
return FileInfo.getIconClass(this.fileExt(), this.mimeType());
}
}

View file

@ -114,8 +114,6 @@ export class ContactModel extends AbstractModel {
this.adr = ko.observableArray();
this.addComputables({
hasValidName: () => !!(this.givenName() || this.surName()),
fullName: () => [this.namePrefix(), this.givenName(), this.middleName(), this.surName()].join(' ').trim(),
display: () => {

View file

@ -27,18 +27,14 @@ function addressparser(str) {
tokens.forEach(token => {
if (token.type === 'operator' && (token.value === ',' || token.value === ';')) {
if (address.length) {
addresses.push(address);
}
address.length && addresses.push(address);
address = [];
} else {
address.push(token);
}
});
if (address.length) {
addresses.push(address);
}
address.length && addresses.push(address);
addresses.forEach(address => {
address = _handleAddress(address);
@ -205,9 +201,7 @@ class Tokenizer
this.list.forEach(node => {
node.value = (node.value || '').toString().trim();
if (node.value) {
list.push(node);
}
node.value && list.push(node);
});
return list;
@ -361,37 +355,26 @@ export class EmailModel extends AbstractModel {
}
static splitEmailLine(line) {
const parsedResult = addressparser(line);
if (parsedResult.length) {
const result = [];
let exists = false;
parsedResult.forEach((item) => {
const address = item.address
? new EmailModel(item.address.replace(/^[<]+(.*)[>]+$/g, '$1'), item.name || '')
: null;
const result = [];
let exists = false;
addressparser(line).forEach(item => {
const address = item.address
? new EmailModel(item.address.replace(/^[<]+(.*)[>]+$/g, '$1'), item.name || '')
: null;
if (address?.email) {
exists = true;
}
if (address?.email) {
exists = true;
}
result.push(address ? address.toLine() : item.name);
});
return exists ? result : null;
}
return null;
result.push(address ? address.toLine() : item.name);
});
return exists ? result : null;
}
static parseEmailLine(line) {
const parsedResult = addressparser(line);
if (parsedResult.length) {
return parsedResult.map(item =>
item.address ? new EmailModel(item.address.replace(/^[<]+(.*)[>]+$/g, '$1'), item.name || '') : null
).filter(v => v);
}
return [];
return addressparser(line).map(item =>
item.address ? new EmailModel(item.address.replace(/^[<]+(.*)[>]+$/g, '$1'), item.name || '') : null
).filter(v => v);
}
/**
@ -400,19 +383,15 @@ export class EmailModel extends AbstractModel {
*/
parse(emailAddress) {
emailAddress = emailAddress.trim();
if (!emailAddress) {
return false;
if (emailAddress) {
const result = addressparser(emailAddress);
if (result.length) {
this.name = result[0].name || '';
this.email = result[0].address || '';
this.clearDuplicateName();
return true;
}
}
const result = addressparser(emailAddress);
if (result.length) {
this.name = result[0].name || '';
this.email = result[0].address || '';
this.clearDuplicateName();
return true;
}
return false;
}
}

View file

@ -21,17 +21,4 @@ export class EmailCollectionModel extends AbstractCollectionModel
toString(friendlyView, wrapWithLink) {
return this.map(email => email.toLine(friendlyView, wrapWithLink)).join(', ');
}
/**
* @returns {string}
*/
toStringClear() {
const result = [];
this.forEach(email => {
if (email?.email && email?.name) {
result.push(email.email);
}
});
return result.join(', ');
}
}

View file

@ -14,7 +14,7 @@ import { MessagelistUserStore } from 'Stores/User/Messagelist';
import { SettingsUserStore } from 'Stores/User/Settings';
import { sortFolders } from 'Common/Folders';
import { i18n, trigger as translatorTrigger } from 'Common/Translator';
import { i18n, translateTrigger } from 'Common/Translator';
import { AbstractModel } from 'Knoin/AbstractModel';
@ -76,17 +76,9 @@ export const
*/
setExpandedFolder = (sFullName, bExpanded) => {
let aExpandedList = Local.get(ClientSideKeyNameExpandedFolders);
if (!isArray(aExpandedList)) {
aExpandedList = [];
}
if (bExpanded) {
aExpandedList.includes(sFullName) || aExpandedList.push(sFullName);
} else {
aExpandedList = aExpandedList.filter(value => value !== sFullName);
}
Local.set(ClientSideKeyNameExpandedFolders, aExpandedList);
aExpandedList = new Set(isArray(aExpandedList) ? aExpandedList : []);
bExpanded ? aExpandedList.add(sFullName) : aExpandedList.delete(sFullName);
Local.set(ClientSideKeyNameExpandedFolders, [...aExpandedList]);
},
foldersFilter = ko.observable(''),
@ -99,8 +91,7 @@ export const
Remote.abort('Folders')
.post('Folders', FolderUserStore.foldersLoading)
.then(data => {
data = FolderCollectionModel.reviveFromJson(data.Result);
data?.storeIt();
FolderCollectionModel.reviveFromJson(data.Result)?.storeIt();
fCallback?.(true);
// Repeat every 15 minutes?
// this.foldersTimeout = setTimeout(loadFolders, 900000);
@ -281,25 +272,15 @@ export class FolderModel extends AbstractModel {
this.totalEmails = koComputable({
read: this.totalEmailsValue,
write: (iValue) => {
if (isPosNumeric(iValue)) {
this.totalEmailsValue(iValue);
} else {
this.totalEmailsValue.valueHasMutated();
}
}
write: iValue =>
isPosNumeric(iValue) ? this.totalEmailsValue(iValue) : this.totalEmailsValue.valueHasMutated()
})
.extend({ notify: 'always' });
this.unreadEmails = koComputable({
read: this.unreadEmailsValue,
write: (value) => {
if (isPosNumeric(value)) {
this.unreadEmailsValue(value);
} else {
this.unreadEmailsValue.valueHasMutated();
}
}
write: value =>
isPosNumeric(value) ? this.unreadEmailsValue(value) : this.unreadEmailsValue.valueHasMutated()
})
.extend({ notify: 'always' });
/*
@ -397,13 +378,14 @@ export class FolderModel extends AbstractModel {
const
unread = folder.unreadEmails(),
type = folder.type();
// TODO: make isSystemFolder() optional in Settings
return ((!folder.isSystemFolder() || type == FolderType.Inbox) && unread) ? unread : null;
},
localName: () => {
let name = folder.name();
if (folder.isSystemFolder()) {
translatorTrigger();
translateTrigger();
name = getSystemFolderName(folder.type(), name);
}
return name;
@ -411,7 +393,7 @@ export class FolderModel extends AbstractModel {
manageFolderSystemName: () => {
if (folder.isSystemFolder()) {
translatorTrigger();
translateTrigger();
let suffix = getSystemFolderName(folder.type(), getKolabFolderName(folder.kolabType()));
if (folder.name() !== suffix && 'inbox' !== suffix.toLowerCase()) {
return '(' + suffix + ')';
@ -420,24 +402,22 @@ export class FolderModel extends AbstractModel {
return '';
},
hasUnreadMessages: () => 0 < folder.unreadEmails() && folder.printableUnreadCount(),
hasSubscribedUnreadMessagesSubfolders: () =>
!!folder.subFolders().find(
folder => folder.hasUnreadMessages() | folder.hasSubscribedUnreadMessagesSubfolders()
folder => folder.printableUnreadCount() | folder.hasSubscribedUnreadMessagesSubfolders()
)
/*
!!folder.subFolders().filter(
folder => folder.printableUnreadCount() | folder.hasSubscribedUnreadMessagesSubfolders()
).length
*/
// ,href: () => folder.canBeSelected() && mailBox(folder.fullNameHash)
});
folder.addSubscribables({
editing: value => value && folder.nameForEdit(folder.name()),
unreadEmails: unread => {
if (FolderType.Inbox === folder.type()) {
fireEvent('mailbox.inbox-unread-count', unread);
}
}
unreadEmails: unread => FolderType.Inbox === folder.type() && fireEvent('mailbox.inbox-unread-count', unread)
});
}
return folder;

View file

@ -1,5 +1,3 @@
import { koComputable } from 'External/ko';
import { AbstractModel } from 'Knoin/AbstractModel';
export class IdentityModel extends AbstractModel {
@ -23,8 +21,6 @@ export class IdentityModel extends AbstractModel {
askDelete: false
});
this.canBeDeleted = koComputable(() => !!this.id());
}
/**

View file

@ -5,7 +5,7 @@ import { i18n } from 'Common/Translator';
import { doc, SettingsGet } from 'Common/Globals';
import { encodeHtml, plainToHtml, cleanHtml } from 'Common/Html';
import { isArray, arrayLength, forEachObjectEntry } from 'Common/Utils';
import { arrayLength, forEachObjectEntry } from 'Common/Utils';
import { serverRequestRaw, proxy } from 'Common/Links';
import { FolderUserStore, isAllowedKeyword } from 'Stores/User/Folder';
@ -32,15 +32,12 @@ const
toggleTag = (message, keyword) => {
const lower = keyword.toLowerCase(),
isSet = message.flags().includes(lower);
flags = message.flags,
isSet = flags.includes(lower);
Remote.request('MessageSetKeyword', iError => {
if (!iError) {
if (isSet) {
message.flags.remove(lower);
} else {
message.flags.push(lower);
}
// MessageFlagsCache.setFor(message.folder, message.uid, message.flags());
isSet ? flags.remove(lower) : flags.push(lower);
// MessageFlagsCache.setFor(message.folder, message.uid, flags());
}
}, {
Folder: message.folder,
@ -56,11 +53,9 @@ const
* @param {Map} localEmails
*/
replyHelper = (emails, unic, localEmails) =>
emails.forEach(email => {
if (!unic[email.email] && !localEmails.has(email.email)) {
localEmails.set(email.email, email);
}
});
emails.forEach(email =>
unic[email.email] || localEmails.has(email.email) || localEmails.set(email.email, email)
);
doc.body.append(hcont);
@ -222,16 +217,6 @@ export class MessageModel extends AbstractModel {
return spam ? i18n(this.isSpam() ? 'GLOBAL/SPAM' : 'GLOBAL/NOT_SPAM') + ': ' + spam : '';
}
/**
* @param {Array} properties
* @returns {Array}
*/
getEmails(properties) {
return properties.reduce((carry, property) => carry.concat(this[property]), []).map(
oItem => oItem ? oItem.email : ''
).validUnique();
}
/**
* @returns {string}
*/
@ -240,9 +225,11 @@ export class MessageModel extends AbstractModel {
}
computeSenderEmail() {
const list = [FolderUserStore.sentFolder(), FolderUserStore.draftsFolder()].includes(this.folder) ? 'to' : 'from';
this.senderEmailsString(this[list].toString(true));
this.senderClearEmailsString(this[list].toStringClear());
const list = this[
[FolderUserStore.sentFolder(), FolderUserStore.draftsFolder()].includes(this.folder) ? 'to' : 'from'
];
this.senderEmailsString(list.toString(true));
this.senderClearEmailsString(list.map(email => email?.email).filter(email => email).join(', '));
}
/**
@ -349,21 +336,6 @@ export class MessageModel extends AbstractModel {
return classes.join(' ');
}
/**
* @return array
* https://datatracker.ietf.org/doc/html/rfc5788
*/
keywords() {
return this.flags().filter(value => '\\' !== value[0]);
}
/**
* @returns {string}
*/
fromAsSingleEmail() {
return (isArray(this.from) && this.from[0]?.email) || '';
}
/**
* @returns {string}
*/
@ -491,7 +463,7 @@ export class MessageModel extends AbstractModel {
* @param {boolean=} print = false
*/
popupMessage() {
this.viewPopupMessage(false);
this.viewPopupMessage();
}
printMessage() {