mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-07 16:37:02 +03:00
Merge pull request #1796 from SergeyMosin/compact-composer-plugin-v1.0.5
Compact composer plugin v1.0.5
This commit is contained in:
commit
156481583d
3 changed files with 29 additions and 31 deletions
|
|
@ -1,3 +1,8 @@
|
||||||
|
/* Prevent collapse of empty elements so that the caret can be placed in there */
|
||||||
|
.CompactComposer *:empty::before {
|
||||||
|
content: "\200B";
|
||||||
|
}
|
||||||
|
|
||||||
.CompactComposer .squire-toolbar {
|
.CompactComposer .squire-toolbar {
|
||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ class CompactComposerPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||||
NAME = 'Compact Composer',
|
NAME = 'Compact Composer',
|
||||||
AUTHOR = 'Sergey Mosin',
|
AUTHOR = 'Sergey Mosin',
|
||||||
URL = 'https://github.com/the-djmaze/snappymail/pull/1466',
|
URL = 'https://github.com/the-djmaze/snappymail/pull/1466',
|
||||||
VERSION = '1.0.4',
|
VERSION = '1.0.5',
|
||||||
RELEASE = '2024-04-23',
|
RELEASE = '2024-08-08',
|
||||||
REQUIRED = '2.34.0',
|
REQUIRED = '2.34.0',
|
||||||
LICENSE = 'AGPL v3',
|
LICENSE = 'AGPL v3',
|
||||||
DESCRIPTION = 'WYSIWYG editor with a compact toolbar';
|
DESCRIPTION = 'WYSIWYG editor with a compact toolbar';
|
||||||
|
|
|
||||||
|
|
@ -17,18 +17,28 @@
|
||||||
addEventListener('rl-view-model', e => {
|
addEventListener('rl-view-model', e => {
|
||||||
const vm = e.detail;
|
const vm = e.detail;
|
||||||
if ('PopupsCompose' === vm.viewModelTemplateID && rl.settings.get('editorWysiwyg') === 'CompactComposer') {
|
if ('PopupsCompose' === vm.viewModelTemplateID && rl.settings.get('editorWysiwyg') === 'CompactComposer') {
|
||||||
vm.querySelector('.tabs label[for="tab-body"]').dataset.bind = "visible: canMailvelope";
|
// add visible binding to the label
|
||||||
|
const bodyLabel = vm.querySelector('.tabs label[for="tab-body"]');
|
||||||
|
bodyLabel.dataset.bind = 'visible: canMailvelope';
|
||||||
|
// re-apply the binding
|
||||||
|
const labelNext = bodyLabel.nextElementSibling;
|
||||||
|
ko.removeNode(bodyLabel);
|
||||||
|
labelNext.parentElement.insertBefore(bodyLabel, labelNext);
|
||||||
|
ko.applyBindingAccessorsToNode(bodyLabel, null, vm);
|
||||||
|
|
||||||
// Now move the attachments tab to the bottom of the screen
|
// Now move the attachments tab to the bottom of the screen
|
||||||
const
|
const area = vm.querySelector('.tabs .attachmentAreaParent');
|
||||||
input = vm.querySelector('.tabs input[value="attachments"]'),
|
vm.querySelector('.tabs input[value="attachments"]').remove();
|
||||||
label = vm.querySelector('.tabs label[for="tab-attachments"]'),
|
vm.querySelector('.tabs label[for="tab-attachments"]').remove();
|
||||||
area = vm.querySelector('.tabs .attachmentAreaParent');
|
area.querySelector('.no-attachments-desc').remove();
|
||||||
input.remove();
|
|
||||||
label.remove();
|
|
||||||
area.remove();
|
|
||||||
area.classList.add('compact');
|
area.classList.add('compact');
|
||||||
area.querySelector('.b-attachment-place').dataset.bind = "visible: addAttachmentEnabled(), css: {dragAndDropOver: dragAndDropVisible}";
|
|
||||||
vm.viewModelDom.append(area);
|
vm.viewModelDom.append(area);
|
||||||
|
// Add and re-apply the bindings for the attachment-place
|
||||||
|
const place = area.querySelector('.b-attachment-place');
|
||||||
|
ko.removeNode(place);
|
||||||
|
area.insertBefore(place, area.firstElementChild);
|
||||||
|
place.dataset.bind = 'visible: addAttachmentEnabled(), css: {dragAndDropOver: dragAndDropVisible}';
|
||||||
|
ko.applyBindingAccessorsToNode(place, null, vm);
|
||||||
// There is a better way to do this probably,
|
// There is a better way to do this probably,
|
||||||
// but we need this for drag and drop to work
|
// but we need this for drag and drop to work
|
||||||
e.detail.attachmentsArea = e.detail.bodyArea;
|
e.detail.attachmentsArea = e.detail.bodyArea;
|
||||||
|
|
@ -36,10 +46,6 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
const
|
const
|
||||||
removeElements = 'HEAD,LINK,META,NOSCRIPT,SCRIPT,TEMPLATE,TITLE',
|
|
||||||
allowedElements = 'A,B,BLOCKQUOTE,BR,DIV,EM,FONT,H1,H2,H3,H4,H5,H6,HR,I,IMG,LI,OL,P,SPAN,STRONG,TABLE,TD,TH,TR,U,UL',
|
|
||||||
allowedAttributes = 'abbr,align,background,bgcolor,border,cellpadding,cellspacing,class,color,colspan,dir,face,frame,height,href,hspace,id,lang,rowspan,rules,scope,size,src,style,target,type,usemap,valign,vspace,width'.split(','),
|
|
||||||
|
|
||||||
// TODO: labels translations
|
// TODO: labels translations
|
||||||
i18n = (str, def) => rl.i18n(str) || def,
|
i18n = (str, def) => rl.i18n(str) || def,
|
||||||
|
|
||||||
|
|
@ -95,21 +101,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
pasteSanitizer = (event) => {
|
pasteSanitizer = (event) => {
|
||||||
const frag = event.detail.fragment;
|
return rl.Utils.cleanHtml(event.detail.html).html;
|
||||||
frag.querySelectorAll('a:empty,span:empty').forEach(el => el.remove());
|
|
||||||
frag.querySelectorAll(removeElements).forEach(el => el.remove());
|
|
||||||
frag.querySelectorAll('*').forEach(el => {
|
|
||||||
if (!el.matches(allowedElements)) {
|
|
||||||
el.replaceWith(getFragmentOfChildren(el));
|
|
||||||
} else if (el.hasAttributes()) {
|
|
||||||
[...el.attributes].forEach(attr => {
|
|
||||||
let name = attr.name.toLowerCase();
|
|
||||||
if (!allowedAttributes.includes(name)) {
|
|
||||||
el.removeAttribute(name);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
pasteImageHandler = (e, squire) => {
|
pasteImageHandler = (e, squire) => {
|
||||||
|
|
@ -317,7 +309,8 @@
|
||||||
clr.style.left = (input.offsetLeft + input.parentNode.offsetLeft) + 'px';
|
clr.style.left = (input.offsetLeft + input.parentNode.offsetLeft) + 'px';
|
||||||
clr.style.width = input.offsetWidth + 'px';
|
clr.style.width = input.offsetWidth + 'px';
|
||||||
|
|
||||||
clr.value = '';
|
// firefox does not call "onchange" for #000 if we use clr.value=''
|
||||||
|
clr.value = '#00ff0c';
|
||||||
clr.onchange = () => {
|
clr.onchange = () => {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case 'color':
|
case 'color':
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue