diff --git a/README.md b/README.md index 2c92d9c48..f5551002f 100644 --- a/README.md +++ b/README.md @@ -86,21 +86,21 @@ Things might work in Edge 18, Firefox 50-62 and Chrome 54-68 due to one polyfill |js/* |1.14.0 |native | |----------- |--------: |--------: | -|admin.js |2.130.942 | 939.722 | -|app.js |4.184.455 |2.559.620 | +|admin.js |2.130.942 | 938.738 | +|app.js |4.184.455 |2.556.224 | |boot.js | 671.522 | 7.265 | -|libs.js | 647.614 | 312.269 | +|libs.js | 647.614 | 312.343 | |polyfills.js | 325.834 | 0 | -|TOTAL |7.960.367 |3.818.876 | +|TOTAL |7.960.367 |3.814.570 | |js/min/* |1.14.0 |native |gzip 1.14 |gzip |brotli | |--------------- |--------: |--------: |--------: |--------: |--------: | -|admin.min.js | 252.147 | 128.874 | 73.657 | 37.574 | 32.236 | -|app.min.js | 511.202 | 349.777 |140.462 | 91.836 | 73.775 | +|admin.min.js | 252.147 | 128.761 | 73.657 | 37.546 | 32.178 | +|app.min.js | 511.202 | 349.280 |140.462 | 91.746 | 73.635 | |boot.min.js | 66.007 | 4.258 | 22.567 | 1.946 | 1.648 | -|libs.min.js | 572.545 | 295.716 |176.720 | 91.532 | 80.863 | +|libs.min.js | 572.545 | 295.754 |176.720 | 91.521 | 80.871 | |polyfills.min.js | 32.452 | 0 | 11.312 | 0 | 0 | -|TOTAL |1.434.353 | 778.625 |424.718 |222.888 |188.522 | +|TOTAL |1.434.353 | 778.053 |424.718 |222.759 |188.332 | 655.728 bytes (201.830 gzip) is not much, but it feels faster. diff --git a/dev/App/User.js b/dev/App/User.js index e00c2135c..fcd90c3d8 100644 --- a/dev/App/User.js +++ b/dev/App/User.js @@ -1,6 +1,5 @@ import { isPosNumeric, - isNonEmptyArray, pInt, pString, delegateRunOnDestroy, @@ -89,9 +88,9 @@ class AppUser extends AbstractApp { // wakeUp const interval = 3600000; // 60m - var lastTime = (new Date()).getTime(); + var lastTime = Date.now(); setInterval(() => { - const currentTime = (new Date()).getTime(); + const currentTime = Date.now(); if (currentTime > (lastTime + interval + 1000)) { if (rl.hash.check()) { this.reload(); @@ -645,10 +644,10 @@ class AppUser extends AbstractApp { */ folderInformationMultiply(boot = false) { const folders = FolderStore.getNextFolderNames(); - if (isNonEmptyArray(folders)) { + if (Array.isNotEmpty(folders)) { Remote.folderInformationMultiply((sResult, oData) => { if (StorageResultType.Success === sResult) { - if (oData && oData.Result && oData.Result.List && isNonEmptyArray(oData.Result.List)) { + if (oData && oData.Result && oData.Result.List && Array.isNotEmpty(oData.Result.List)) { const utc = Date.now() / 1000; oData.Result.List.forEach(item => { const hash = getFolderHash(item.Folder), @@ -685,7 +684,7 @@ class AppUser extends AbstractApp { } else if (unreadCountChange) { if (folder.fullNameRaw === FolderStore.currentFolderFullNameRaw()) { const list = MessageStore.messageList(); - if (isNonEmptyArray(list)) { + if (Array.isNotEmpty(list)) { this.folderInformation(folder.fullNameRaw, list); } } diff --git a/dev/Common/Cache.js b/dev/Common/Cache.js index 8c3cac982..d6184b311 100644 --- a/dev/Common/Cache.js +++ b/dev/Common/Cache.js @@ -265,7 +265,7 @@ export function storeMessageFlagsToCache(message) { * @param {Array} flags */ export function storeMessageFlagsToCacheByFolderAndUid(folder, uid, flags) { - if (Array.isArray(flags) && flags.length) { + if (Array.isNotEmpty(flags)) { setMessageFlagsToCache(folder, uid, flags); } } @@ -279,7 +279,7 @@ export function storeMessageFlagsToCacheBySetAction(folder, uid, setAction) { let unread = 0; const flags = getMessageFlagsFromCache(folder, uid); - if (Array.isArray(flags) && flags.length) { + if (Array.isNotEmpty(flags)) { if (flags[0]) { unread = 1; } diff --git a/dev/Common/Utils.js b/dev/Common/Utils.js index df28ebd66..abc3d20a2 100644 --- a/dev/Common/Utils.js +++ b/dev/Common/Utils.js @@ -41,14 +41,6 @@ export function pString(value) { return null != value ? '' + value : ''; } -/** - * @param {*} values - * @returns {boolean} - */ -export function isNonEmptyArray(values) { - return isArray(values) && values.length; -} - /** * @param {string} queryString * @returns {Object} diff --git a/dev/External/ko.js b/dev/External/ko.js index c84b7ab6f..38441b8ce 100644 --- a/dev/External/ko.js +++ b/dev/External/ko.js @@ -485,7 +485,7 @@ ko.extenders.limitedList = (target, limitedList) => { const currentValue = ko.unwrap(target), list = ko.unwrap(limitedList); - if (Array.isArray(list) && list.length) { + if (Array.isNotEmpty(list)) { if (list.includes(newValue)) { target(newValue); } else if (list.includes(currentValue, list)) { diff --git a/dev/Helper/Message.js b/dev/Helper/Message.js index 915ded2d7..7cb7329b3 100644 --- a/dev/Helper/Message.js +++ b/dev/Helper/Message.js @@ -1,4 +1,3 @@ -import { isNonEmptyArray } from 'Common/Utils'; import { EmailModel } from 'Model/Email'; /** @@ -9,7 +8,7 @@ import { EmailModel } from 'Model/Email'; */ export function emailArrayToString(emails, friendlyView = false, wrapWithLink = false) { const result = []; - if (isNonEmptyArray(emails)) { + if (Array.isNotEmpty(emails)) { emails.forEach(email => result.push(email.toLine(friendlyView, wrapWithLink))); } @@ -22,7 +21,7 @@ export function emailArrayToString(emails, friendlyView = false, wrapWithLink = */ export function emailArrayToStringClear(emails) { const result = []; - if (isNonEmptyArray(emails)) { + if (Array.isNotEmpty(emails)) { emails.forEach(email => { if (email && email.email && email.name) { result.push(email.email); @@ -39,7 +38,7 @@ export function emailArrayToStringClear(emails) { */ export function emailArrayFromJson(json) { const result = []; - if (isNonEmptyArray(json)) { + if (Array.isNotEmpty(json)) { json.forEach(email => { email = EmailModel.newInstanceFromJson(email); if (email) { diff --git a/dev/Knoin/AbstractScreen.js b/dev/Knoin/AbstractScreen.js index 103af7f76..e3c82bdce 100644 --- a/dev/Knoin/AbstractScreen.js +++ b/dev/Knoin/AbstractScreen.js @@ -44,7 +44,7 @@ export class AbstractScreen { fMatcher = null; const routes = this.routes(); - if (Array.isArray(routes) && routes.length) { + if (Array.isNotEmpty(routes)) { fMatcher = (this.onRoute || (()=>{})).bind(this); route = new Crossroads(); diff --git a/dev/Knoin/Knoin.js b/dev/Knoin/Knoin.js index a7f57a9c8..d9e5dfff1 100644 --- a/dev/Knoin/Knoin.js +++ b/dev/Knoin/Knoin.js @@ -12,7 +12,7 @@ let currentScreen = null, const SCREENS = {}, qs = s => document.querySelector(s), - isNonEmptyArray = values => Array.isArray(values) && values.length, + isNonEmptyArray = Array.isNotEmpty, autofocus = dom => { // if (!bMobileDevice) { const af = dom.querySelector('[autofocus]'); diff --git a/dev/Model/Attachment.js b/dev/Model/Attachment.js index 5def8ee3b..ce39b29d6 100644 --- a/dev/Model/Attachment.js +++ b/dev/Model/Attachment.js @@ -2,7 +2,7 @@ import ko from 'ko'; import { FileType } from 'Common/Enums'; import { bMobileDevice } from 'Common/Globals'; -import { pInt, isNonEmptyArray, getFileExtension, friendlySize } from 'Common/Utils'; +import { pInt, getFileExtension, friendlySize } from 'Common/Utils'; import { attachmentDownload, attachmentPreview, @@ -149,7 +149,7 @@ export const staticCombinedIconClass = (data) => { let result = '', types = []; - if (isNonEmptyArray(data)) { + if (Array.isNotEmpty(data)) { result = 'icon-attachment'; types = data.map(item => item ? staticFileType(getFileExtension(item[0]), item[1]) : '') .filter((value, index, self) => !!value && self.indexOf(value) == index); diff --git a/dev/Model/Contact.js b/dev/Model/Contact.js index 2c0d47d21..7480d972a 100644 --- a/dev/Model/Contact.js +++ b/dev/Model/Contact.js @@ -1,7 +1,7 @@ import ko from 'ko'; import { ContactPropertyType } from 'Common/Enums'; -import { isNonEmptyArray, pInt, pString } from 'Common/Utils'; +import { pInt, pString } from 'Common/Utils'; import { emptyContactPic } from 'Common/Links'; import { AbstractModel } from 'Knoin/AbstractModel'; @@ -28,7 +28,7 @@ class ContactModel extends AbstractModel { let name = '', email = ''; - if (isNonEmptyArray(this.properties)) { + if (Array.isNotEmpty(this.properties)) { this.properties.forEach(property => { if (property) { if (ContactPropertyType.FirstName === property[0]) { @@ -56,7 +56,7 @@ class ContactModel extends AbstractModel { this.display = pString(json.Display); this.readOnly = !!json.ReadOnly; - if (isNonEmptyArray(json.Properties)) { + if (Array.isNotEmpty(json.Properties)) { json.Properties.forEach(property => { if (property && property.Type && null != property.Value && null != property.TypeStr) { this.properties.push([pInt(property.Type), pString(property.Value), pString(property.TypeStr)]); diff --git a/dev/Model/Filter.js b/dev/Model/Filter.js index 0d55b5d6b..8c8a844f9 100644 --- a/dev/Model/Filter.js +++ b/dev/Model/Filter.js @@ -1,7 +1,7 @@ import ko from 'ko'; import { FilterRulesType, FiltersAction } from 'Common/Enums'; -import { pString, isNonEmptyArray, fakeMd5, delegateRunOnDestroy } from 'Common/Utils'; +import { pString, fakeMd5, delegateRunOnDestroy } from 'Common/Utils'; import { i18n } from 'Common/Translator'; import { getFolderFromCacheList } from 'Common/Cache'; @@ -225,7 +225,7 @@ class FilterModel extends AbstractModel { this.conditions([]); - if (isNonEmptyArray(json.Conditions)) { + if (Array.isNotEmpty(json.Conditions)) { this.conditions( json.Conditions.map(aData => { const filterCondition = new FilterConditionModel(); diff --git a/dev/Model/Message.js b/dev/Model/Message.js index 7e6d13046..6b8fbfc4e 100644 --- a/dev/Model/Message.js +++ b/dev/Model/Message.js @@ -7,8 +7,7 @@ import { pInt, deModule, encodeHtml, - friendlySize, - isNonEmptyArray + friendlySize } from 'Common/Utils'; import { messageViewLink, messageDownloadLink } from 'Common/Links'; @@ -257,7 +256,7 @@ class MessageModel extends AbstractModel { this.bcc = emailArrayFromJson(json.Bcc); this.replyTo = emailArrayFromJson(json.ReplyTo); this.deliveredTo = emailArrayFromJson(json.DeliveredTo); - this.unsubsribeLinks = isNonEmptyArray(json.UnsubsribeLinks) ? json.UnsubsribeLinks : []; + this.unsubsribeLinks = Array.isNotEmpty(json.UnsubsribeLinks) ? json.UnsubsribeLinks : []; this.subject(json.Subject); if (isArray(json.SubjectParts)) { @@ -341,7 +340,7 @@ class MessageModel extends AbstractModel { attachment = null; const result = []; - if (json && 'Collection/AttachmentCollection' === json['@Object'] && isNonEmptyArray(json['@Collection'])) { + if (json && 'Collection/AttachmentCollection' === json['@Object'] && Array.isNotEmpty(json['@Collection'])) { for (index = 0, len = json['@Collection'].length; index < len; index++) { attachment = AttachmentModel.newInstanceFromJson(json['@Collection'][index]); if (attachment) { @@ -408,7 +407,7 @@ class MessageModel extends AbstractModel { */ fromDkimData() { let result = ['none', '']; - if (isNonEmptyArray(this.from) && 1 === this.from.length && this.from[0] && this.from[0].dkimStatus) { + if (Array.isNotEmpty(this.from) && 1 === this.from.length && this.from[0] && this.from[0].dkimStatus) { result = [this.from[0].dkimStatus, this.from[0].dkimValue || '']; } @@ -492,7 +491,7 @@ class MessageModel extends AbstractModel { let result = null; const attachments = this.attachments(); - if (isNonEmptyArray(attachments)) { + if (Array.isNotEmpty(attachments)) { cid = cid.replace(/^<+/, '').replace(/>+$/, ''); result = attachments.find(item => cid === item.cidWithOutTags); } @@ -508,7 +507,7 @@ class MessageModel extends AbstractModel { let result = null; const attachments = this.attachments(); - if (isNonEmptyArray(attachments)) { + if (Array.isNotEmpty(attachments)) { result = attachments.find(item => contentLocation === item.contentLocation); } diff --git a/dev/Model/OpenPgpKey.js b/dev/Model/OpenPgpKey.js index 0f6e964e2..e69f20d84 100644 --- a/dev/Model/OpenPgpKey.js +++ b/dev/Model/OpenPgpKey.js @@ -1,7 +1,5 @@ import ko from 'ko'; -import { isNonEmptyArray } from 'Common/Utils'; - import { AbstractModel } from 'Knoin/AbstractModel'; import PgpStore from 'Stores/User/Pgp'; @@ -23,7 +21,7 @@ class OpenPgpKeyModel extends AbstractModel { this.index = index; this.id = ID; - this.ids = isNonEmptyArray(IDs) ? IDs : [ID]; + this.ids = Array.isNotEmpty(IDs) ? IDs : [ID]; this.guid = guID; this.user = ''; this.users = userIDs; diff --git a/dev/Remote/User/Ajax.js b/dev/Remote/User/Ajax.js index bb65fbc12..055bc16d8 100644 --- a/dev/Remote/User/Ajax.js +++ b/dev/Remote/User/Ajax.js @@ -445,7 +445,7 @@ class RemoteUserAjax extends AbstractAjaxRemote { let request = true; const uids = []; - if (Array.isArray(list) && list.length) { + if (Array.isNotEmpty(list)) { request = false; list.forEach(messageListItem => { if (!getMessageFlagsFromCache(messageListItem.folderFullNameRaw, messageListItem.uid)) { diff --git a/dev/Stores/User/App.js b/dev/Stores/User/App.js index e92e35d40..a3a288257 100644 --- a/dev/Stores/User/App.js +++ b/dev/Stores/User/App.js @@ -2,7 +2,6 @@ import ko from 'ko'; import { Focused, KeyState } from 'Common/Enums'; import { keyScope, leftPanelDisabled } from 'Common/Globals'; -import { isNonEmptyArray } from 'Common/Utils'; import { AbstractAppStore } from 'Stores/AbstractApp'; @@ -70,7 +69,7 @@ class AppUserStore extends AbstractAppStore { this.contactsIsAllowed(!!Settings.get('ContactsIsAllowed')); const attachmentsActions = Settings.app('attachmentsActions'); - this.attachmentsActions(isNonEmptyArray(attachmentsActions) ? attachmentsActions : []); + this.attachmentsActions(Array.isNotEmpty(attachmentsActions) ? attachmentsActions : []); this.devEmail = Settings.get('DevEmail'); this.devPassword = Settings.get('DevPassword'); diff --git a/dev/Stores/User/Folder.js b/dev/Stores/User/Folder.js index dbccc594f..ffac4b2d3 100644 --- a/dev/Stores/User/Folder.js +++ b/dev/Stores/User/Folder.js @@ -68,7 +68,7 @@ class FolderUserStore { trashFolder = this.trashFolder(), archiveFolder = this.archiveFolder(); - if (Array.isArray(folders) && folders.length) { + if (Array.isNotEmpty(folders)) { if (sentFolder && UNUSED_OPTION_VALUE !== sentFolder) { list.push(sentFolder); } diff --git a/dev/Stores/User/Message.js b/dev/Stores/User/Message.js index 50ee31c2e..9183a21d0 100644 --- a/dev/Stores/User/Message.js +++ b/dev/Stores/User/Message.js @@ -240,7 +240,7 @@ class MessageUserStore { initUidNextAndNewMessages(folder, uidNext, newMessages) { if (getFolderInboxName() === folder && uidNext) { - if (Array.isArray(newMessages) && newMessages.length) { + if (Array.isNotEmpty(newMessages)) { newMessages.forEach(item => { addNewMessageCache(folder, item.Uid); }); diff --git a/dev/Stores/User/Pgp.js b/dev/Stores/User/Pgp.js index dd7c74244..5b5dc2b65 100644 --- a/dev/Stores/User/Pgp.js +++ b/dev/Stores/User/Pgp.js @@ -1,7 +1,7 @@ import ko from 'ko'; import { i18n } from 'Common/Translator'; -import { isNonEmptyArray, pString } from 'Common/Utils'; +import { pString } from 'Common/Utils'; import AccountStore from 'Stores/User/Account'; @@ -51,7 +51,7 @@ function domControlEncryptedClickHelper(store, dom, armoredMessage, recipients) decryptedMessage.getText() ); } else if (validPrivateKey) { - const keyIds = isNonEmptyArray(signingKeyIds) ? signingKeyIds : null, + const keyIds = Array.isNotEmpty(signingKeyIds) ? signingKeyIds : null, additional = keyIds ? keyIds.map(item => (item && item.toHex ? item.toHex() : null)).filter(value => !!value).join(', ') : ''; @@ -107,7 +107,7 @@ function domControlSignedClickHelper(store, dom, armoredMessage) { message.getText() ); } else { - const keyIds = isNonEmptyArray(signingKeyIds) ? signingKeyIds : null, + const keyIds = Array.isNotEmpty(signingKeyIds) ? signingKeyIds : null, additional = keyIds ? keyIds.map(item => (item && item.toHex ? item.toHex() : null)).filter(value => !!value).join(', ') : ''; @@ -183,7 +183,7 @@ class PgpUserStore { }).flat().filter(value => !!value) : []; - if (!result.length && isNonEmptyArray(recipients)) { + if (!result.length && Array.isNotEmpty(recipients)) { result = recipients.map(sEmail => { const keys = sEmail ? this.findAllPrivateKeysByEmailNotNative(sEmail) : null; return keys diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js index d5ba7ac86..f41bfa0a9 100644 --- a/dev/View/Popup/Compose.js +++ b/dev/View/Popup/Compose.js @@ -12,7 +12,6 @@ import { } from 'Common/Enums'; import { - isNonEmptyArray, replySubjectAdd, encodeHtml, inFocus, @@ -263,7 +262,7 @@ class ComposePopupView extends AbstractViewNext { }); this.attachmentsInProcess.subscribe(value => { - if (this.attachmentsInProcessError() && isNonEmptyArray(value)) { + if (this.attachmentsInProcessError() && Array.isNotEmpty(value)) { this.attachmentsInProcessError(false); } }); @@ -772,7 +771,7 @@ class ComposePopupView extends AbstractViewNext { * @param {Array} emails */ addEmailsTo(fKoValue, emails) { - if (isNonEmptyArray(emails)) { + if (Array.isNotEmpty(emails)) { const value = fKoValue().trim(), values = emails.map(item => item ? item.toLine(false) : null) .filter((value, index, self) => !!value && self.indexOf(value) == index); @@ -842,15 +841,15 @@ class ComposePopupView extends AbstractViewNext { excludeEmail[identity.email()] = true; } - if (isNonEmptyArray(aToEmails)) { + if (Array.isNotEmpty(aToEmails)) { this.to(this.emailArrayToStringLineHelper(aToEmails)); } - if (isNonEmptyArray(aCcEmails)) { + if (Array.isNotEmpty(aCcEmails)) { this.cc(this.emailArrayToStringLineHelper(aCcEmails)); } - if (isNonEmptyArray(aBccEmails)) { + if (Array.isNotEmpty(aBccEmails)) { this.bcc(this.emailArrayToStringLineHelper(aBccEmails)); } @@ -915,7 +914,7 @@ class ComposePopupView extends AbstractViewNext { this.subject(sSubject); this.prepearMessageAttachments(message, lineComposeType); - this.aDraftInfo = isNonEmptyArray(aDraftInfo) && 3 === aDraftInfo.length ? aDraftInfo : null; + this.aDraftInfo = Array.isNotEmpty(aDraftInfo) && 3 === aDraftInfo.length ? aDraftInfo : null; this.sInReplyTo = message.sInReplyTo; this.sReferences = message.sReferences; break; @@ -929,7 +928,7 @@ class ComposePopupView extends AbstractViewNext { this.subject(sSubject); this.prepearMessageAttachments(message, lineComposeType); - this.aDraftInfo = isNonEmptyArray(aDraftInfo) && 3 === aDraftInfo.length ? aDraftInfo : null; + this.aDraftInfo = Array.isNotEmpty(aDraftInfo) && 3 === aDraftInfo.length ? aDraftInfo : null; this.sInReplyTo = message.sInReplyTo; this.sReferences = message.sReferences; break; @@ -1021,7 +1020,7 @@ class ComposePopupView extends AbstractViewNext { this.setFocusInPopup(); }); - } else if (isNonEmptyArray(oMessageOrArray)) { + } else if (Array.isNotEmpty(oMessageOrArray)) { oMessageOrArray.forEach(item => { this.addMessageAsAttachment(item); }); @@ -1047,7 +1046,7 @@ class ComposePopupView extends AbstractViewNext { } const downloads = this.getAttachmentsDownloadsForUpload(); - if (isNonEmptyArray(downloads)) { + if (Array.isNotEmpty(downloads)) { Remote.messageUploadAttachments(()=>this.onMessageUploadAttachments(), downloads); } @@ -1375,7 +1374,7 @@ class ComposePopupView extends AbstractViewNext { this.addMessageAsAttachment(message); } else { const attachments = message.attachments(); - (isNonEmptyArray(attachments) ? attachments : []).forEach(item => { + (Array.isNotEmpty(attachments) ? attachments : []).forEach(item => { let add = false; switch (type) { case ComposeType.Reply: diff --git a/dev/View/Popup/Contacts.js b/dev/View/Popup/Contacts.js index 607504b7f..91efa954a 100644 --- a/dev/View/Popup/Contacts.js +++ b/dev/View/Popup/Contacts.js @@ -13,7 +13,6 @@ import { import { delegateRunOnDestroy, computedPagenatorHelper, - isNonEmptyArray, fakeMd5, pInt } from 'Common/Utils'; @@ -229,7 +228,7 @@ class ContactsPopupView extends AbstractViewNext { bccEmails = null; const aC = this.contactsCheckedOrSelected(); - if (isNonEmptyArray(aC)) { + if (Array.isNotEmpty(aC)) { aE = aC.map(oItem => { if (oItem) { const data = oItem.getNameAndEmailHelper(), @@ -246,7 +245,7 @@ class ContactsPopupView extends AbstractViewNext { aE = aE.filter(value => !!value); } - if (isNonEmptyArray(aE)) { + if (Array.isNotEmpty(aE)) { this.bBackToCompose = false; hideScreenPopup(ContactsPopupView); @@ -511,7 +510,7 @@ class ContactsPopupView extends AbstractViewNext { if (contact) { id = contact.idContact; - if (isNonEmptyArray(contact.properties)) { + if (Array.isNotEmpty(contact.properties)) { contact.properties.forEach(property => { if (property && property[0]) { if (ContactPropertyType.LastName === property[0]) { @@ -579,7 +578,7 @@ class ContactsPopupView extends AbstractViewNext { list = []; if (StorageResultType.Success === result && data && data.Result && data.Result.List) { - if (isNonEmptyArray(data.Result.List)) { + if (Array.isNotEmpty(data.Result.List)) { list = data.Result.List.map(item => { const contact = new ContactModel(); return contact.parse(item) ? contact : null; diff --git a/dev/View/Popup/Plugin.js b/dev/View/Popup/Plugin.js index 8e34e56cd..0980714d5 100644 --- a/dev/View/Popup/Plugin.js +++ b/dev/View/Popup/Plugin.js @@ -83,7 +83,7 @@ class PluginPopupView extends AbstractViewNext { this.readme(oPlugin.Readme); const config = oPlugin.Config; - if (Array.isArray(config) && config.length) { + if (Array.isNotEmpty(config)) { this.configures( config.map(item => ({ 'value': ko.observable(item[0]), diff --git a/dev/View/User/MailBox/MessageView.js b/dev/View/User/MailBox/MessageView.js index 5b9f41883..f51112fad 100644 --- a/dev/View/User/MailBox/MessageView.js +++ b/dev/View/User/MailBox/MessageView.js @@ -16,7 +16,6 @@ import { import { $htmlCL, leftPanelDisabled, keyScopeReal, useKeyboardShortcuts, moveAction } from 'Common/Globals'; import { - isNonEmptyArray, inFocus, removeSelection, removeInFocus, @@ -213,7 +212,7 @@ class MessageViewMailBoxUserView extends AbstractViewNext { this.viewFromDkimStatusTitle = ko.computed(() => { const status = this.viewFromDkimData(); - if (isNonEmptyArray(status)) { + if (Array.isNotEmpty(status)) { if (status[0] && status[1]) { return status[1]; } else if (status[0]) { diff --git a/dev/prototype-element.js b/dev/prototype-element.js deleted file mode 100644 index 8982e4294..000000000 --- a/dev/prototype-element.js +++ /dev/null @@ -1,13 +0,0 @@ - -(()=>{ - Element.prototype.closestWithin = function(selector, parent) { - const el = this.closest(selector); - return (el && el !== parent && parent.contains(el)) ? el : null; - }; - - Element.fromHTML = string => { - const template = document.createElement('template'); - template.innerHTML = string.trim(); - return template.content.firstChild; - }; -})(); diff --git a/dev/prototype-function.js b/dev/prototype-function.js deleted file mode 100644 index 5dfd80000..000000000 --- a/dev/prototype-function.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Every time the function is executed, - * it will delay the execution with the given amount of milliseconds. - */ -if (!Function.prototype.debounce) { - Function.prototype.debounce = function(ms) { - let func = this, timer; - return function(...args) { - timer && clearTimeout(timer); - timer = setTimeout(()=>{ - func.apply(this, args) - timer = 0; - }, ms); - }; - }; -} - -/** - * No matter how many times the event is executed, - * the function will be executed only once, after the given amount of milliseconds. - */ -if (!Function.prototype.throttle) { - Function.prototype.throttle = function(ms) { - let func = this, timer; - return function(...args) { - if (!timer) { - timer = setTimeout(()=>{ - func.apply(this, args) - timer = 0; - }, ms); - } - }; - }; -} diff --git a/dev/prototype-date.js b/dev/prototype.js similarity index 82% rename from dev/prototype-date.js rename to dev/prototype.js index 5465dc9cd..5b3fad43d 100644 --- a/dev/prototype-date.js +++ b/dev/prototype.js @@ -1,5 +1,6 @@ (w=>{ + Array.isNotEmpty = array => Array.isArray(array) && array.length; // Import momentjs locales function w.moment = { @@ -167,7 +168,7 @@ // Simulate momentjs fromNow function Date.prototype.fromNow = function() { let format, - seconds = ((new Date()).getTime() - this.getTime()) / 1000, + seconds = (Date.now() - this.getTime()) / 1000, str = locale.relativeTime[0 < seconds ? 'past' : 'future']; seconds = Math.abs(seconds); if (60 > seconds) { @@ -195,4 +196,50 @@ return str.replace('%s', locale.relativeTime[format].replace('%d', seconds)); } + Element.prototype.closestWithin = function(selector, parent) { + const el = this.closest(selector); + return (el && el !== parent && parent.contains(el)) ? el : null; + }; + + Element.fromHTML = string => { + const template = document.createElement('template'); + template.innerHTML = string.trim(); + return template.content.firstChild; + }; + + /** + * Every time the function is executed, + * it will delay the execution with the given amount of milliseconds. + */ + if (!Function.prototype.debounce) { + Function.prototype.debounce = function(ms) { + let func = this, timer; + return function(...args) { + timer && clearTimeout(timer); + timer = setTimeout(()=>{ + func.apply(this, args) + timer = 0; + }, ms); + }; + }; + } + + /** + * No matter how many times the event is executed, + * the function will be executed only once, after the given amount of milliseconds. + */ + if (!Function.prototype.throttle) { + Function.prototype.throttle = function(ms) { + let func = this, timer; + return function(...args) { + if (!timer) { + timer = setTimeout(()=>{ + func.apply(this, args) + timer = 0; + }, ms); + } + }; + }; + } + })(this); diff --git a/tasks/config.js b/tasks/config.js index cf3771c28..9d6d89fe6 100644 --- a/tasks/config.js +++ b/tasks/config.js @@ -70,6 +70,7 @@ config.paths.js = { name: 'libs.js', src: [ 'dev/polyfill.js', + 'dev/prototype.js', 'node_modules/jquery/dist/jquery.slim.min.js', 'vendors/jquery-ui/js/jquery-ui-1.12.1.custom.min.js', // custom 'vendors/inputosaurus/inputosaurus.js', // custom (modified) @@ -80,9 +81,6 @@ config.paths.js = { 'vendors/keymaster/keymaster.js', // custom (modified) 'vendors/qr.js/qr.min.js', // fixed (license) 'vendors/bootstrap/js/bootstrap.native.min.js', // fixed - 'dev/prototype-date.js', - 'dev/prototype-element.js', - 'dev/prototype-function.js', 'node_modules/knockout/build/output/knockout-latest.js', 'node_modules/knockout-sortable/build/knockout-sortable.min.js ', 'node_modules/simplestatemanager/dist/ssm.min.js',