From d7a4639d6b90e38f5af7c31aa94434b59b046f31 Mon Sep 17 00:00:00 2001 From: djmaze Date: Sun, 25 Oct 2020 11:46:58 +0100 Subject: [PATCH] Prevent memory leaks in *Model --- dev/Knoin/AbstractModel.js | 48 +++++---- dev/Model/Account.js | 11 +- dev/Model/ComposeAttachment.js | 29 ++--- dev/Model/Contact.js | 12 +-- dev/Model/ContactProperty.js | 14 +-- dev/Model/Filter.js | 102 +++++++++--------- dev/Model/FilterCondition.js | 28 ++--- dev/Model/Folder.js | 46 ++++---- dev/Model/Identity.js | 19 ++-- dev/Model/Message.js | 75 +++++++------ dev/View/Popup/Contacts.js | 26 ++--- dev/View/Popup/Filter.js | 6 +- .../templates/Views/User/PopupsFilter.html | 4 +- .../User/SettingsFiltersActionDiscard.html | 2 +- .../User/SettingsFiltersActionForward.html | 2 +- .../SettingsFiltersActionMoveToFolder.html | 2 +- .../Views/User/SettingsFiltersActionNone.html | 2 +- .../User/SettingsFiltersActionReject.html | 2 +- .../User/SettingsFiltersActionVacation.html | 4 +- .../User/SettingsFiltersConditionDefault.html | 4 +- .../User/SettingsFiltersConditionMore.html | 4 +- .../User/SettingsFiltersConditionSize.html | 4 +- 22 files changed, 221 insertions(+), 225 deletions(-) diff --git a/dev/Knoin/AbstractModel.js b/dev/Knoin/AbstractModel.js index afb84793a..27c47dfcd 100644 --- a/dev/Knoin/AbstractModel.js +++ b/dev/Knoin/AbstractModel.js @@ -5,50 +5,52 @@ function disposeOne(disposable) { } } -function typeCast(current, value) { - switch (typeof current) +function typeCast(curValue, newValue) { + switch (typeof curValue) { - case 'boolean': return !!value; - case 'number': return isFinite(value) ? parseFloat(value) : 0; - case 'string': return null != value ? '' + value : ''; + case 'boolean': return !!newValue; + case 'number': return isFinite(newValue) ? parseFloat(newValue) : 0; + case 'string': return null != newValue ? '' + newValue : ''; case 'object': - if (current.constructor.reviveFromJson) { - return current.constructor.reviveFromJson(value) || undefined; + if (curValue.constructor.reviveFromJson) { + return curValue.constructor.reviveFromJson(newValue) || undefined; } - if (!Array.isArray(current) || !Array.isArray(value)) + if (!Array.isArray(curValue) || !Array.isArray(newValue)) return undefined; } - return value; + return newValue; } export class AbstractModel { disposables = []; - /** - * @param {string} modelName = '' - */ constructor() { /* if (new.target === AbstractModel) { throw new Error("Can't instantiate AbstractModel!"); } - this.sModelName = new.target.name; */ } - regDisposables(value) { - if (Array.isArray(value)) { - value.forEach(item => this.disposables.push(item)); - } else if (value) { - this.disposables.push(value); - } + addObservables(obj) { + Object.entries(obj).forEach(([key, value]) => this[key] = ko.observable(value) ); +/* + Object.entries(obj).forEach(([key, value]) => + this[key] = Array.isArray(value) ? ko.observableArray(value) : ko.observable(value) + ); +*/ + } + + addSubscribables(obj) { + Object.entries(obj).forEach(([key, fn]) => this.disposables.push( this[key].subscribe(fn) ) ); } onDestroy() { - if (Array.isArray(this.disposables)) { - this.disposables.forEach(disposeOne); - } - Object.values(this).forEach(disposeOne); + this.disposables.forEach(disposeOne); + Object.entries(this).forEach(([key, value]) => { + disposeOne(value); + this[key] = null; + }); } /** diff --git a/dev/Model/Account.js b/dev/Model/Account.js index 69c44db5a..daa843f9d 100644 --- a/dev/Model/Account.js +++ b/dev/Model/Account.js @@ -1,5 +1,3 @@ -import ko from 'ko'; - import { change } from 'Common/Links'; import { AbstractModel } from 'Knoin/AbstractModel'; @@ -15,10 +13,11 @@ class AccountModel extends AbstractModel { this.email = email; - this.count = ko.observable(count); - - this.deleteAccess = ko.observable(false); - this.canBeDeleted = ko.observable(!!canBeDelete); + this.addObservables({ + count: count, + deleteAccess: false, + canBeDeleted: !!canBeDelete + }); this.canBeEdit = this.canBeDeleted; } diff --git a/dev/Model/ComposeAttachment.js b/dev/Model/ComposeAttachment.js index 531308e55..3f8f5c9eb 100644 --- a/dev/Model/ComposeAttachment.js +++ b/dev/Model/ComposeAttachment.js @@ -24,16 +24,18 @@ class ComposeAttachmentModel extends AbstractModel { this.contentLocation = contentLocation; this.fromMessage = false; - this.fileName = ko.observable(fileName); - this.size = ko.observable(size); - this.tempName = ko.observable(''); + this.addObservables({ + fileName: fileName, + size: size, + tempName: '', - this.progress = ko.observable(0); - this.error = ko.observable(''); - this.waiting = ko.observable(true); - this.uploading = ko.observable(false); - this.enabled = ko.observable(true); - this.complete = ko.observable(false); + progress: 0, + error: '', + waiting: true, + uploading: false, + enabled: true, + complete: false + }); this.progressText = ko.computed(() => { const p = this.progress(); @@ -56,15 +58,6 @@ class ComposeAttachmentModel extends AbstractModel { this.mimeType = ko.computed(() => File.getContentType(this.fileName())); this.fileExt = ko.computed(() => File.getExtension(this.fileName())); - - this.regDisposables([ - this.progressText, - this.progressStyle, - this.title, - this.friendlySize, - this.mimeType, - this.fileExt - ]); } static fromAttachment(item) diff --git a/dev/Model/Contact.js b/dev/Model/Contact.js index 8ae626c5c..c669a7e2d 100644 --- a/dev/Model/Contact.js +++ b/dev/Model/Contact.js @@ -1,5 +1,3 @@ -import ko from 'ko'; - import { ContactPropertyModel } from 'Model/ContactProperty'; import { ContactPropertyType } from 'Common/Enums'; @@ -14,10 +12,12 @@ class ContactModel extends AbstractModel { this.properties = []; this.readOnly = false; - this.focused = ko.observable(false); - this.selected = ko.observable(false); - this.checked = ko.observable(false); - this.deleted = ko.observable(false); + this.addObservables({ + focused: false, + selected: false, + checked: false, + deleted: false + }); } /** diff --git a/dev/Model/ContactProperty.js b/dev/Model/ContactProperty.js index 3eaabcb7f..85b5f6b7e 100644 --- a/dev/Model/ContactProperty.js +++ b/dev/Model/ContactProperty.js @@ -17,12 +17,14 @@ class ContactPropertyModel extends AbstractModel { constructor(type = ContactPropertyType.Unknown, typeStr = '', value = '', focused = false, placeholder = '') { super(); - this.type = ko.observable(pInt(type)); - this.typeStr = ko.observable(pString(typeStr)); - this.focused = ko.observable(!!focused); - this.value = ko.observable(pString(value)); + this.addObservables({ + type: pInt(type), + typeStr: pString(typeStr), + focused: !!focused, + value: pString(value), - this.placeholder = ko.observable(placeholder); + placeholder: placeholder + }); this.placeholderValue = ko.computed(() => { const v = this.placeholder(); @@ -30,8 +32,6 @@ class ContactPropertyModel extends AbstractModel { }); this.largeValue = ko.computed(() => ContactPropertyType.Note === this.type()); - - this.regDisposables([this.placeholderValue, this.largeValue]); } toJSON() { diff --git a/dev/Model/Filter.js b/dev/Model/Filter.js index 9e92c9290..6714eeb4c 100644 --- a/dev/Model/Filter.js +++ b/dev/Model/Filter.js @@ -15,42 +15,38 @@ class FilterModel extends AbstractModel { constructor() { super(); - this.enabled = ko.observable(true); - this.id = ''; - this.name = ko.observable(''); - this.name.error = ko.observable(false); - this.name.focused = ko.observable(false); + this.addObservables({ + enabled: true, + deleteAccess: false, + canBeDeleted: true, + + name: '', + nameError: false, + nameFocused: false, + + conditionsType: FilterRulesType.Any, + + // Actions + actionValue: '', + actionValueError: false, + + actionValueSecond: '', + actionValueThird: '', + + actionValueFourth: '', + actionValueFourthError: false, + + actionMarkAsRead: false, + + actionKeep: true, + actionNoStop: false, + + actionType: FiltersAction.MoveTo + }); this.conditions = ko.observableArray([]); - this.conditionsType = ko.observable(FilterRulesType.Any); - - // Actions - this.actionValue = ko.observable(''); - this.actionValue.error = ko.observable(false); - - this.actionValueSecond = ko.observable(''); - this.actionValueThird = ko.observable(''); - - this.actionValueFourth = ko.observable(''); - this.actionValueFourth.error = ko.observable(false); - - this.actionMarkAsRead = ko.observable(false); - - this.actionKeep = ko.observable(true); - this.actionNoStop = ko.observable(false); - - this.actionType = ko.observable(FiltersAction.MoveTo); - - this.actionType.subscribe(() => { - this.actionValue(''); - this.actionValue.error(false); - this.actionValueSecond(''); - this.actionValueThird(''); - this.actionValueFourth(''); - this.actionValueFourth.error(false); - }); const fGetRealFolderName = (folderFullNameRaw) => { const folder = getFolderFromCacheList(folderFullNameRaw); @@ -115,14 +111,18 @@ class FilterModel extends AbstractModel { return result; }); - this.regDisposables(this.name.subscribe(sValue => this.name.error(!sValue))); - - this.regDisposables(this.actionValue.subscribe(sValue => this.actionValue.error(!sValue))); - - this.regDisposables([this.actionNoStop, this.actionTemplate]); - - this.deleteAccess = ko.observable(false); - this.canBeDeleted = ko.observable(true); + this.addSubscribables({ + name: sValue => this.nameError(!sValue), + actionValue: sValue => this.actionValueError(!sValue), + actionType: () => { + this.actionValue(''); + this.actionValueError(false); + this.actionValueSecond(''); + this.actionValueThird(''); + this.actionValueFourth(''); + this.actionValueFourthError(false); + } + }); } generateID() { @@ -131,14 +131,12 @@ class FilterModel extends AbstractModel { verify() { if (!this.name()) { - this.name.error(true); + this.nameError(true); return false; } - if (this.conditions().length) { - if (this.conditions().find(cond => cond && !cond.verify())) { - return false; - } + if (this.conditions().length && this.conditions().find(cond => cond && !cond.verify())) { + return false; } if (!this.actionValue()) { @@ -149,13 +147,13 @@ class FilterModel extends AbstractModel { FiltersAction.Vacation ].includes(this.actionType()) ) { - this.actionValue.error(true); + this.actionValueError(true); return false; } } if (FiltersAction.Forward === this.actionType() && !this.actionValue().includes('@')) { - this.actionValue.error(true); + this.actionValueError(true); return false; } @@ -164,12 +162,12 @@ class FilterModel extends AbstractModel { this.actionValueFourth() && !this.actionValueFourth().includes('@') ) { - this.actionValueFourth.error(true); + this.actionValueFourthError(true); return false; } - this.name.error(false); - this.actionValue.error(false); + this.nameError(false); + this.actionValueError(false); return true; } @@ -240,7 +238,7 @@ class FilterModel extends AbstractModel { filter.enabled(this.enabled()); filter.name(this.name()); - filter.name.error(this.name.error()); + filter.nameError(this.nameError()); filter.conditionsType(this.conditionsType()); @@ -249,7 +247,7 @@ class FilterModel extends AbstractModel { filter.actionType(this.actionType()); filter.actionValue(this.actionValue()); - filter.actionValue.error(this.actionValue.error()); + filter.actionValueError(this.actionValueError()); filter.actionValueSecond(this.actionValueSecond()); filter.actionValueThird(this.actionValueThird()); diff --git a/dev/Model/FilterCondition.js b/dev/Model/FilterCondition.js index 9d3624a00..a097c6028 100644 --- a/dev/Model/FilterCondition.js +++ b/dev/Model/FilterCondition.js @@ -8,13 +8,15 @@ class FilterConditionModel extends AbstractModel { constructor() { super(); - this.field = ko.observable(FilterConditionField.From); - this.type = ko.observable(FilterConditionType.Contains); - this.value = ko.observable(''); - this.value.error = ko.observable(false); + this.addObservables({ + field: FilterConditionField.From, + type: FilterConditionType.Contains, + value: '', + valueError: false, - this.valueSecond = ko.observable(''); - this.valueSecond.error = ko.observable(false); + valueSecond: '', + valueSecondError: false + }); this.template = ko.computed(() => { let template = ''; @@ -33,22 +35,22 @@ class FilterConditionModel extends AbstractModel { return template; }, this); - this.field.subscribe(() => { - this.value(''); - this.valueSecond(''); + this.addSubscribables({ + field: () => { + this.value(''); + this.valueSecond(''); + } }); - - this.regDisposables([this.template]); } verify() { if (!this.value()) { - this.value.error(true); + this.valueError(true); return false; } if (FilterConditionField.Header === this.field() && !this.valueSecond()) { - this.valueSecond.error(true); + this.valueSecondError(true); return false; } diff --git a/dev/Model/Folder.js b/dev/Model/Folder.js index 7603e3dfd..4dd60a1eb 100644 --- a/dev/Model/Folder.js +++ b/dev/Model/Folder.js @@ -11,7 +11,6 @@ class FolderModel extends AbstractModel { constructor() { super(); - this.name = ko.observable(''); this.fullName = ''; this.fullNameRaw = ''; this.fullNameHash = ''; @@ -23,23 +22,27 @@ class FolderModel extends AbstractModel { this.selectable = false; this.existen = true; - this.type = ko.observable(FolderType.User); + this.addObservables({ + name: '', + type: FolderType.User, + + focused: false, + selected: false, + edited: false, + subScribed: true, + checkable: false, + deleteAccess: false, + + nameForEdit: '', + + privateMessageCountAll: 0, + privateMessageCountUnread: 0, + + collapsedPrivate: true + }); - this.focused = ko.observable(false); - this.selected = ko.observable(false); - this.edited = ko.observable(false); - this.subScribed = ko.observable(true); - this.checkable = ko.observable(false); this.subFolders = ko.observableArray(new FolderCollectionModel); - this.deleteAccess = ko.observable(false); this.actionBlink = ko.observable(false).extend({ falseTimeout: 1000 }); - - this.nameForEdit = ko.observable(''); - - this.privateMessageCountAll = ko.observable(0); - this.privateMessageCountUnread = ko.observable(0); - - this.collapsedPrivate = ko.observable(true); } /** @@ -230,14 +233,15 @@ class FolderModel extends AbstractModel { ) ); - // subscribe - folder.name.subscribe(value => folder.nameForEdit(value)); + folder.addSubscribables({ + name: value => folder.nameForEdit(value), - folder.edited.subscribe(value => value && folder.nameForEdit(folder.name())); + edited: value => value && folder.nameForEdit(folder.name()), - folder.messageCountUnread.subscribe((unread) => { - if (FolderType.Inbox === folder.type()) { - dispatchEvent(new CustomEvent('mailbox.inbox-unread-count', {detail:unread})); + messageCountUnread: unread => { + if (FolderType.Inbox === folder.type()) { + dispatchEvent(new CustomEvent('mailbox.inbox-unread-count', {detail:unread})); + } } }); } diff --git a/dev/Model/Identity.js b/dev/Model/Identity.js index c3c5e6349..fefe6aa55 100644 --- a/dev/Model/Identity.js +++ b/dev/Model/Identity.js @@ -10,17 +10,20 @@ class IdentityModel extends AbstractModel { constructor(id, email) { super(); - this.id = ko.observable(id || ''); - this.email = ko.observable(email); - this.name = ko.observable(''); + this.addObservables({ + id: id || '', + email: email, + name: '', - this.replyTo = ko.observable(''); - this.bcc = ko.observable(''); + replyTo: '', + bcc: '', - this.signature = ko.observable(''); - this.signatureInsertBefore = ko.observable(false); + signature: '', + signatureInsertBefore: false, + + deleteAccess: false + }); - this.deleteAccess = ko.observable(false); this.canBeDeleted = ko.computed(() => !!this.id()); } diff --git a/dev/Model/Message.js b/dev/Model/Message.js index e534fd731..c90bbac68 100644 --- a/dev/Model/Message.js +++ b/dev/Model/Message.js @@ -31,57 +31,56 @@ class MessageModel extends AbstractModel { this._reset(); - this.subject = ko.observable(''); - this.subjectPrefix = ko.observable(''); - this.subjectSuffix = ko.observable(''); - this.size = ko.observable(0); - this.dateTimeStampInUTC = ko.observable(0); - this.priority = ko.observable(MessagePriority.Normal); + this.addObservables({ + subject: '', + subjectPrefix: '', + subjectSuffix: '', + size: 0, + dateTimeStampInUTC: 0, + priority: MessagePriority.Normal, - this.senderEmailsString = ko.observable(''); - this.senderClearEmailsString = ko.observable(''); + senderEmailsString: '', + senderClearEmailsString: '', - this.newForAnimation = ko.observable(false); + newForAnimation: false, - this.deleted = ko.observable(false); - this.isDeleted = ko.observable(false); - this.isUnseen = ko.observable(false); - this.isFlagged = ko.observable(false); - this.isAnswered = ko.observable(false); - this.isForwarded = ko.observable(false); - this.isReadReceipt = ko.observable(false); + deleted: false, + isDeleted: false, + isUnseen: false, + isFlagged: false, + isAnswered: false, + isForwarded: false, + isReadReceipt: false, - this.focused = ko.observable(false); - this.selected = ko.observable(false); - this.checked = ko.observable(false); - this.hasAttachments = ko.observable(false); - this.attachmentsSpecData = ko.observableArray([]); + focused: false, + selected: false, + checked: false, + hasAttachments: false, + + isHtml: false, + hasImages: false, + + isPgpSigned: false, + isPgpEncrypted: false, + pgpSignedVerifyStatus: SignedVerifyStatus.None, + pgpSignedVerifyUser: '', + + readReceipt: '', + + hasUnseenSubMessage: false, + hasFlaggedSubMessage: false + }); this.attachmentIconClass = ko.computed(() => File.getCombinedIconClass(this.hasAttachments() ? this.attachmentsSpecData() : []) ); - this.isHtml = ko.observable(false); - this.hasImages = ko.observable(false); - this.attachments = ko.observable(new AttachmentCollectionModel); - - this.isPgpSigned = ko.observable(false); - this.isPgpEncrypted = ko.observable(false); - this.pgpSignedVerifyStatus = ko.observable(SignedVerifyStatus.None); - this.pgpSignedVerifyUser = ko.observable(''); - - this.priority = ko.observable(MessagePriority.Normal); - this.readReceipt = ko.observable(''); - - this.hasUnseenSubMessage = ko.observable(false); - this.hasFlaggedSubMessage = ko.observable(false); - + this.attachments = ko.observableArray(new AttachmentCollectionModel); + this.attachmentsSpecData = ko.observableArray([]); this.threads = ko.observableArray([]); this.threadsLen = ko.computed(() => this.threads().length); this.isImportant = ko.computed(() => MessagePriority.High === this.priority()); - - this.regDisposables([this.attachmentIconClass, this.threadsLen, this.isImportant]); } _reset() { diff --git a/dev/View/Popup/Contacts.js b/dev/View/Popup/Contacts.js index 41f1df6aa..803eb01f2 100644 --- a/dev/View/Popup/Contacts.js +++ b/dev/View/Popup/Contacts.js @@ -55,10 +55,9 @@ class ContactsPopupView extends AbstractViewNext { this.importUploaderButton = ko.observable(null); this.contactsPage = ko.observable(1); - this.contactsPageCount = ko.computed(() => { - const iPage = Math.ceil(this.contactsCount() / CONTACTS_PER_PAGE); - return 0 >= iPage ? 1 : iPage; - }); + this.contactsPageCount = ko.computed(() => + Math.max(1, Math.ceil(this.contactsCount() / CONTACTS_PER_PAGE)) + ); this.contactsPaginator = ko.computed(computedPaginatorHelper(this.contactsPage, this.contactsPageCount)); @@ -104,10 +103,7 @@ class ContactsPopupView extends AbstractViewNext { this.viewPropertiesNames().filter(property => !!trim(property.value())) ); - const propertyFocused = (property) => { - const focused = property.focused(); - return !trim(property.value()) && !focused; - }; + const propertyFocused = property => !trim(property.value()) && !property.focused(); this.viewPropertiesEmailsEmptyAndOnFocused = ko.computed(() => this.viewPropertiesEmails().filter(propertyFocused) @@ -117,7 +113,9 @@ class ContactsPopupView extends AbstractViewNext { this.viewPropertiesPhones().filter(propertyFocused) ); - this.viewPropertiesWebEmptyAndOnFocused = ko.computed(() => this.viewPropertiesWeb().filter(propertyFocused)); + this.viewPropertiesWebEmptyAndOnFocused = ko.computed(() => + this.viewPropertiesWeb().filter(propertyFocused) + ); this.viewPropertiesOtherEmptyAndOnFocused = ko.computed(() => this.viewPropertiesOther().filter(propertyFocused) @@ -141,9 +139,7 @@ class ContactsPopupView extends AbstractViewNext { this.useCheckboxesInList = SettingsStore.useCheckboxesInList; - this.search.subscribe(() => { - this.reloadContactList(); - }); + this.search.subscribe(() => this.reloadContactList()); this.contactsChecked = ko.computed(() => this.contacts().filter(item => item.checked())); @@ -170,14 +166,14 @@ class ContactsPopupView extends AbstractViewNext { '.e-contact-item.focused' ); - this.selector.on('onItemSelect', (contact) => { - this.populateViewContact(contact ? contact : null); + this.selector.on('onItemSelect', contact => { + this.populateViewContact(contact || null); if (!contact) { this.emptySelection(true); } }); - this.selector.on('onItemGetUid', (contact) => (contact ? contact.generateUid() : '')); + this.selector.on('onItemGetUid', contact => contact ? contact.generateUid() : ''); this.bDropPageAfterDelete = false; diff --git a/dev/View/Popup/Filter.js b/dev/View/Popup/Filter.js index bda7f1761..0813f769c 100644 --- a/dev/View/Popup/Filter.js +++ b/dev/View/Popup/Filter.js @@ -33,7 +33,7 @@ class FilterPopupView extends AbstractViewNext { this.selectedFolderValue.subscribe(() => { if (this.filter()) { - this.filter().actionValue.error(false); + this.filter().actionValueError(false); } }); @@ -157,13 +157,13 @@ class FilterPopupView extends AbstractViewNext { this.isNew(!bEdit); if (!bEdit && oFilter) { - oFilter.name.focused(true); + oFilter.nameFocused(true); } } onShowWithDelay() { if (this.isNew() && this.filter()/* && !rl.settings.app('mobile')*/) { - this.filter().name.focused(true); + this.filter().nameFocused(true); } } } diff --git a/snappymail/v/0.0.0/app/templates/Views/User/PopupsFilter.html b/snappymail/v/0.0.0/app/templates/Views/User/PopupsFilter.html index 3154a94ba..36b958c3f 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/PopupsFilter.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/PopupsFilter.html @@ -11,10 +11,10 @@
-
+
diff --git a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionDiscard.html b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionDiscard.html index 4eace6776..cbaeb1145 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionDiscard.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionDiscard.html @@ -1,4 +1,4 @@ -
+
+
diff --git a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionMoveToFolder.html b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionMoveToFolder.html index 529d20fdf..e97c18378 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionMoveToFolder.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionMoveToFolder.html @@ -1,4 +1,4 @@ -
+
diff --git a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionNone.html b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionNone.html index 4eace6776..cbaeb1145 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionNone.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionNone.html @@ -1,4 +1,4 @@ -
+
+
diff --git a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionVacation.html b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionVacation.html index 0e12a70fc..c90c0bf09 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionVacation.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersActionVacation.html @@ -11,7 +11,7 @@ }">
-
+
@@ -26,7 +26,7 @@ data-i18n="[placeholder]POPUPS_FILTER/VACATION_SUBJECT_LABEL" />
-
+
diff --git a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionDefault.html b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionDefault.html index 7bf8c166d..0948e32bf 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionDefault.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionDefault.html @@ -1,4 +1,4 @@ -
+
  @@ -9,4 +9,4 @@ data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }"> -
\ No newline at end of file +
diff --git a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionMore.html b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionMore.html index 61ac82ede..1ce102281 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionMore.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionMore.html @@ -1,4 +1,4 @@ -
+
  @@ -11,4 +11,4 @@ data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }"> -
\ No newline at end of file +
diff --git a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionSize.html b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionSize.html index 0830dc800..235ab0fbe 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionSize.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/SettingsFiltersConditionSize.html @@ -1,4 +1,4 @@ -
+
  @@ -9,4 +9,4 @@ data-bind="click: function (oCondition) { $root.removeCondition(oCondition); }"> -
\ No newline at end of file +