Extend the use of ResizeObserver by dropping all knockoutjs observable this.resizerTrigger in mail composer

As benefit this also drops the CustomEvent('resize.real')
This commit is contained in:
djmaze 2020-08-19 11:30:31 +02:00
parent 35c9f3fff5
commit d1c06a8ece
10 changed files with 48 additions and 117 deletions

View file

@ -31,20 +31,6 @@ class AbstractApp extends AbstractBoot {
this.isLocalAutocomplete = true; this.isLocalAutocomplete = true;
this.lastErrorTime = 0; this.lastErrorTime = 0;
addEventListener(
'resize',
(()=>{
const iH = $win.height(),
iW = $win.height();
if ($win.__sizes[0] !== iH || $win.__sizes[1] !== iW) {
$win.__sizes[0] = iH;
$win.__sizes[1] = iW;
dispatchEvent(new CustomEvent('resize.real'));
}
}).throttle(50)
);
const $doc = document; const $doc = document;
$doc.addEventListener('keydown', (event) => { $doc.addEventListener('keydown', (event) => {
if (event && event.ctrlKey) { if (event && event.ctrlKey) {

View file

@ -80,31 +80,6 @@ import { AbstractApp } from 'App/Abstract';
const doc = document; const doc = document;
if (!window.ResizeObserver) {
window.ResizeObserver = class {
constructor(callback) {
callback = callback.debounce(250);
this.observer = new MutationObserver(mutations => {
let i = mutations.length;
while (i--) {
if ('style' == mutations[i].attributeName) {
callback();
break;
}
}
});
}
disconnect() {
this.observer.disconnect();
}
observe(target) {
this.observer.observe(target, { attributes: true });
}
};
}
class AppUser extends AbstractApp { class AppUser extends AbstractApp {
constructor() { constructor() {
super(Remote); super(Remote);

View file

@ -2,7 +2,6 @@ import ko from 'ko';
import { KeyState } from 'Common/Enums'; import { KeyState } from 'Common/Enums';
const $win = jQuery(window); const $win = jQuery(window);
$win.__sizes = [0, 0];
export { $win }; export { $win };

16
dev/External/ko.js vendored
View file

@ -245,22 +245,6 @@ ko.bindingHandlers.initDom = {
init: (element, fValueAccessor) => fValueAccessor()(element) init: (element, fValueAccessor) => fValueAccessor()(element)
}; };
ko.bindingHandlers.initResizeTrigger = {
init: (element, fValueAccessor) =>
element.style.height = element.style.minHeight = ko.unwrap(fValueAccessor())[1] + 'px',
update: (element, fValueAccessor) => {
const values = ko.unwrap(fValueAccessor());
let offset = element.getBoundingClientRect().top + pageYOffset;
if (0 < offset) {
offset += parseInt(values[2], 10) || 0;
element.style.height = element.style.minHeight = Math.max(
parseInt(values[1], 10) || 0,
window.innerHeight - offset
) + 'px';
}
}
};
ko.bindingHandlers.appendDom = { ko.bindingHandlers.appendDom = {
update: (element, fValueAccessor) => { update: (element, fValueAccessor) => {
$(element) $(element)

View file

@ -2,9 +2,10 @@
.b-compose { .b-compose {
&.modal { &.modal {
width: 98%;
width: 850px; max-width: 1000px;
margin: 10px auto; margin: 10px auto;
/* height: 94vh;*/
.modal-body { .modal-body {
overflow: auto; overflow: auto;
@ -15,6 +16,9 @@
.textAreaParent, .attachmentAreaParent { .textAreaParent, .attachmentAreaParent {
overflow: hidden; overflow: hidden;
position: relative; position: relative;
height: 200px;
min-height: 200px;
} }
.attachmentAreaParent { .attachmentAreaParent {

View file

@ -186,10 +186,6 @@ html.ssm-state-desktop-large {
left: 500px; left: 500px;
} }
.b-compose.modal {
width: 1000px;
}
.b-contacts-content.modal { .b-contacts-content.modal {
width: 900px; width: 900px;
} }
@ -213,10 +209,6 @@ html.ssm-state-desktop {
left: 400px; left: 400px;
} }
.b-compose.modal {
width: 1000px;
}
.b-contacts-content.modal { .b-contacts-content.modal {
width: 900px; width: 900px;
} }
@ -244,10 +236,6 @@ html.ssm-state-tablet, html.ssm-state-mobile {
left: 310px; left: 310px;
} }
.b-compose.modal {
width: 720px;
}
.b-contacts-content.modal { .b-contacts-content.modal {
width: 700px; width: 700px;
} }
@ -261,10 +249,6 @@ html.ssm-state-tablet, html.ssm-state-mobile {
html.ssm-state-tablet { html.ssm-state-tablet {
.b-compose.modal {
width: 720px;
}
.b-contacts-content.modal { .b-contacts-content.modal {
width: 800px; width: 800px;
} }

View file

@ -337,7 +337,7 @@ html.no-rgba .modal {
.popups { .popups {
position: absolute; position: fixed;
top: 0; top: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
@ -449,4 +449,4 @@ html.rl-mobile {
opacity: .6; opacity: .6;
} }
} }
} }

View file

@ -84,8 +84,6 @@ class ComposePopupView extends AbstractViewNext {
this.sLastFocusedField = 'to'; this.sLastFocusedField = 'to';
this.resizerTrigger = this.resizerTrigger.debounce(50).bind(this);
this.allowContacts = !!AppStore.contactsIsAllowed(); this.allowContacts = !!AppStore.contactsIsAllowed();
this.allowFolders = !!Settings.capa(Capa.Folders); this.allowFolders = !!Settings.capa(Capa.Folders);
@ -141,11 +139,7 @@ class ComposePopupView extends AbstractViewNext {
this.sendErrorDesc = ko.observable(''); this.sendErrorDesc = ko.observable('');
this.savedErrorDesc = ko.observable(''); this.savedErrorDesc = ko.observable('');
this.sendError.subscribe((value) => { this.sendError.subscribe(value => !value && this.sendErrorDesc(''));
if (!value) {
this.sendErrorDesc('');
}
});
this.savedError.subscribe(value => !value && this.savedErrorDesc('')); this.savedError.subscribe(value => !value && this.savedErrorDesc(''));
@ -217,9 +211,6 @@ class ComposePopupView extends AbstractViewNext {
this.attachmentsPlace = ko.observable(false); this.attachmentsPlace = ko.observable(false);
this.attachments.subscribe(this.resizerTrigger);
this.attachmentsPlace.subscribe(this.resizerTrigger);
this.attachmentsInErrorCount.subscribe((value) => { this.attachmentsInErrorCount.subscribe((value) => {
if (0 === value) { if (0 === value) {
this.attachmentsInErrorError(false); this.attachmentsInErrorError(false);
@ -278,14 +269,6 @@ class ComposePopupView extends AbstractViewNext {
} }
}); });
this.resizer = ko.observable(false).extend({ throttle: 50 });
this.resizer.subscribe(() => {
if (this.oEditor) {
this.oEditor.resize();
}
});
this.canBeSentOrSaved = ko.computed(() => !this.sending() && !this.saving()); this.canBeSentOrSaved = ko.computed(() => !this.sending() && !this.saving());
setInterval(() => { setInterval(() => {
@ -302,16 +285,14 @@ class ComposePopupView extends AbstractViewNext {
} }
}, 120000); }, 120000);
this.showCc.subscribe(this.resizerTrigger);
this.showBcc.subscribe(this.resizerTrigger);
this.showReplyTo.subscribe(this.resizerTrigger);
this.bDisabeCloseOnEsc = true; this.bDisabeCloseOnEsc = true;
this.sDefaultKeyScope = KeyState.Compose; this.sDefaultKeyScope = KeyState.Compose;
this.tryToClosePopup = this.tryToClosePopup.debounce(200); this.tryToClosePopup = this.tryToClosePopup.debounce(200);
this.iTimer = 0; this.iTimer = 0;
this.resizeObserver = new ResizeObserver(this.resizerTrigger.throttle(50).bind(this));
} }
getMessageRequestParams(sSaveFolder) getMessageRequestParams(sSaveFolder)
@ -660,6 +641,8 @@ class ComposePopupView extends AbstractViewNext {
this.to.focused(false); this.to.focused(false);
routeOn(); routeOn();
this.resizeObserver.disconnect();
} }
editor(fOnInit) { editor(fOnInit) {
@ -671,7 +654,6 @@ class ComposePopupView extends AbstractViewNext {
null, null,
() => { () => {
fOnInit(this.oEditor); fOnInit(this.oEditor);
this.resizerTrigger();
}, },
(bHtml) => { (bHtml) => {
this.isHtml(!!bHtml); this.isHtml(!!bHtml);
@ -680,7 +662,6 @@ class ComposePopupView extends AbstractViewNext {
// }, 1000); // }, 1000);
} else if (this.oEditor) { } else if (this.oEditor) {
fOnInit(this.oEditor); fOnInit(this.oEditor);
this.resizerTrigger();
} }
} }
} }
@ -1077,7 +1058,12 @@ class ComposePopupView extends AbstractViewNext {
this.currentIdentity(identity); this.currentIdentity(identity);
} }
this.resizerTrigger(); let el = document.querySelector('.b-compose');
this.resizeObserver.compose = el;
this.resizeObserver.popups = el.parentNode; // el.closest('.popups');
this.resizeObserver.els = [el.querySelector('.textAreaParent'), el.querySelector('.attachmentAreaParent')];
this.resizeObserver.observe(el);
this.resizeObserver.observe(el.querySelector('.b-header'));
} }
onMessageUploadAttachments(sResult, oData) { onMessageUploadAttachments(sResult, oData) {
@ -1113,10 +1099,6 @@ class ComposePopupView extends AbstractViewNext {
} }
} }
onShowWithDelay() {
this.resizerTrigger();
}
tryToClosePopup() { tryToClosePopup() {
const PopupsAskViewModel = require('View/Popup/Ask'); const PopupsAskViewModel = require('View/Popup/Ask');
if (!isPopupVisible(PopupsAskViewModel) && this.modalVisibility()) { if (!isPopupVisible(PopupsAskViewModel) && this.modalVisibility()) {
@ -1179,14 +1161,6 @@ class ComposePopupView extends AbstractViewNext {
} }
return false; return false;
}); });
addEventListener('resize.real', this.resizerTrigger);
setInterval(() => {
if (this.modalVisibility() && this.oEditor) {
this.oEditor.resize();
}
}, 5000);
} }
/** /**
@ -1542,7 +1516,17 @@ class ComposePopupView extends AbstractViewNext {
} }
resizerTrigger() { resizerTrigger() {
this.resizer(!this.resizer()); let top = 0;
this.resizeObserver.els.forEach(element => top = Math.max(top, element.getBoundingClientRect().top));
if (0 < top) {
top = this.resizeObserver.popups.clientHeight - this.resizeObserver.compose.offsetTop - 50 - top;
this.resizeObserver.els.forEach(element =>
element.style.height = Math.max(top, Math.max(200,parseInt(element.style.minHeight,10))) + 'px'
);
if (this.oEditor) {
this.oEditor.resize();
}
}
} }
} }

View file

@ -14,3 +14,19 @@ Array.prototype.flat || Object.defineProperty(Array.prototype, 'flat', {
}, },
writable: true writable: true
}); });
if (!window.ResizeObserver) {
window.ResizeObserver = class {
constructor(callback) {
this.observer = new MutationObserver(callback.debounce(250));
}
disconnect() {
this.observer.disconnect();
}
observe(target) {
this.observer.observe(target, { attributes: true, subtree: true, attributeFilter: ['style'] });
}
};
}

View file

@ -185,7 +185,7 @@
</div> </div>
</div> </div>
<div class="attachmentAreaParent b-content" style="height: 200px; min-height: 200px" data-bind="visible: attachmentsPlace, initResizeTrigger: [resizer(), 200, 57]"> <div class="attachmentAreaParent b-content" data-bind="visible: attachmentsPlace">
<div class="content g-scrollbox"> <div class="content g-scrollbox">
<div class="content-wrapper"> <div class="content-wrapper">
<div class="b-attachment-place" data-bind="visible: addAttachmentEnabled() && dragAndDropEnabled() && dragAndDropVisible(), initDom: composeUploaderDropPlace, css: {'dragAndDropOver': dragAndDropOver}"> <div class="b-attachment-place" data-bind="visible: addAttachmentEnabled() && dragAndDropEnabled() && dragAndDropVisible(), initDom: composeUploaderDropPlace, css: {'dragAndDropOver': dragAndDropOver}">
@ -199,8 +199,7 @@
</div> </div>
</div> </div>
<div class="textAreaParent" style="height: 200px; min-height: 200px" <div class="textAreaParent" data-bind="visible: !attachmentsPlace(), initDom: composeEditorArea"></div>
data-bind="visible: !attachmentsPlace(), initDom: composeEditorArea, initResizeTrigger: [resizer(), 200, 40]"></div>
</div> </div>
</div> </div>
</div> </div>