Improve switching of wysiwyg/plain composer

This commit is contained in:
djmaze 2021-02-02 12:23:32 +01:00
parent cd2b3ace89
commit 90ee39b114
7 changed files with 103 additions and 135 deletions

View file

@ -66,7 +66,14 @@ class HtmlEditor {
* @returns {boolean} * @returns {boolean}
*/ */
isHtml() { isHtml() {
return this.editor ? 'plain' !== this.editor.mode : false; return this.editor ? !this.isPlain() : false;
}
/**
* @returns {boolean}
*/
isPlain() {
return this.editor ? 'plain' === this.editor.mode : false;
} }
/** /**
@ -100,7 +107,7 @@ class HtmlEditor {
let result = ''; let result = '';
if (this.editor) { if (this.editor) {
try { try {
if ('plain' === this.editor.mode && this.editor.plugins.plain && this.editor.__plain) { if (this.isPlain() && this.editor.plugins.plain && this.editor.__plain) {
result = this.editor.__plain.getRawData(); result = this.editor.__plain.getRawData();
} else { } else {
result = wrapIsHtml result = wrapIsHtml
@ -123,59 +130,45 @@ class HtmlEditor {
return (this.isHtml() ? ':HTML:' : '') + this.getData(wrapIsHtml); return (this.isHtml() ? ':HTML:' : '') + this.getData(wrapIsHtml);
} }
modeToggle(plain) { modeWysiwyg() {
if (this.editor) { try {
try { this.editor && this.editor.setMode('wysiwyg');
if (plain) { } catch (e) { console.error(e); }
if ('plain' === this.editor.mode) { }
this.editor.setMode('wysiwyg'); modePlain() {
} try {
} else if ('wysiwyg' === this.editor.mode) { this.editor && this.editor.setMode('plain');
this.editor.setMode('plain'); } catch (e) { console.error(e); }
}
} catch (e) {} // eslint-disable-line no-empty
}
} }
setHtmlOrPlain(text, focus) { setHtmlOrPlain(text) {
if (':HTML:' === text.substr(0, 6)) { if (':HTML:' === text.substr(0, 6)) {
this.setHtml(text.substr(6), focus); this.setHtml(text.substr(6));
} else { } else {
this.setPlain(text, focus); this.setPlain(text);
} }
} }
setHtml(html, focus) { setData(mode, data) {
if (this.editor && this.__inited) { if (this.editor && this.__inited) {
this.clearCachedSignature(); this.clearCachedSignature();
this.modeToggle(true);
html = html.replace(/<p[^>]*><\/p>/gi, '');
try { try {
this.editor.setData(html); this.editor.setMode(mode);
} catch (e) {} // eslint-disable-line no-empty if (this.isPlain() && this.editor.plugins.plain && this.editor.__plain) {
this.editor.__plain.setRawData(data);
focus && this.focus(); } else {
this.editor.setData(data);
}
} catch (e) { console.error(e); }
} }
} }
setPlain(plain, focus) { setHtml(html) {
if (this.editor && this.__inited) { this.setData('wysiwyg', html/*.replace(/<p[^>]*><\/p>/gi, '')*/);
this.clearCachedSignature(); }
this.modeToggle(false); setPlain(txt) {
if ('plain' === this.editor.mode && this.editor.plugins.plain && this.editor.__plain) { this.setData('plain', txt);
this.editor.__plain.setRawData(plain);
} else {
try {
this.editor.setData(plain);
} catch (e) {} // eslint-disable-line no-empty
}
focus && this.focus();
}
} }
init() { init() {
@ -208,7 +201,7 @@ class HtmlEditor {
this.editor.on('focus', () => this.blurTimer && clearTimeout(this.blurTimer)); this.editor.on('focus', () => this.blurTimer && clearTimeout(this.blurTimer));
this.editor.on('mode', () => { this.editor.on('mode', () => {
this.blurTrigger(); this.blurTrigger();
this.onModeChange && this.onModeChange('plain' !== this.editor.mode); this.onModeChange && this.onModeChange(!this.isPlain());
}); });
} }
} }
@ -234,8 +227,8 @@ class HtmlEditor {
} catch (e) {} // eslint-disable-line no-empty } catch (e) {} // eslint-disable-line no-empty
} }
clear(focus) { clear() {
this.setHtml('', focus); this.setHtml('');
} }
} }

View file

@ -85,7 +85,7 @@ export function htmlToPlain(html) {
args && 1 < args.length args && 1 < args.length
? args[1] ? args[1]
.toString() .toString()
.replace(/[\n]/gm, '<br />') .replace(/[\n]/gm, '<br/>')
.replace(/[\r]/gm, '') .replace(/[\r]/gm, '')
: '', : '',
fixAttibuteValue = (...args) => (args && 1 < args.length ? '' + args[1] + encodeHtml(args[2]) : ''), fixAttibuteValue = (...args) => (args && 1 < args.length ? '' + args[1] + encodeHtml(args[2]) : ''),
@ -204,7 +204,7 @@ export function plainToHtml(plain) {
.replace(/</g, '&lt;') .replace(/</g, '&lt;')
.replace(/~~~blockquote~~~[\s]*/g, '<blockquote>') .replace(/~~~blockquote~~~[\s]*/g, '<blockquote>')
.replace(/[\s]*~~~\/blockquote~~~/g, '</blockquote>') .replace(/[\s]*~~~\/blockquote~~~/g, '</blockquote>')
.replace(/\n/g, '<br />'); .replace(/\n/g, '<br/>');
} }
rl.Utils = { rl.Utils = {

View file

@ -85,7 +85,7 @@ export function createCKEditor(element)
reader.onloadend = () => { reader.onloadend = () => {
if (reader.result && 'wysiwyg' === editor.mode) { if (reader.result && 'wysiwyg' === editor.mode) {
try { try {
editor.setData(editor.getData().replace(imageId, `<img src="${reader.result}" />`)); editor.setData(editor.getData().replace(imageId, `<img src="${reader.result}"/>`));
} catch (e) {} // eslint-disable-line no-empty } catch (e) {} // eslint-disable-line no-empty
} }
}; };

View file

@ -491,20 +491,20 @@ class SquireUI
} }
setMode(mode) { setMode(mode) {
let cl = this.container.classList; if (this.mode != mode) {
cl.remove('squire-mode-'+this.mode); let cl = this.container.classList;
if ('plain' == mode) { cl.remove('squire-mode-'+this.mode);
let html = this.squire.getHTML(); if ('plain' == mode) {
this.plain.value = rl.Utils.htmlToPlain(html, true).trim(); this.plain.value = rl.Utils.htmlToPlain(this.squire.getHTML(), true).trim();
} else { } else {
let plain = this.plain.value; this.setData(rl.Utils.plainToHtml(this.plain.value, true));
this.setData(rl.Utils.plainToHtml(plain, true)); mode = 'wysiwyg';
mode = 'wysiwyg'; }
this.mode = mode; // 'wysiwyg' or 'plain'
cl.add('squire-mode-'+mode);
this.onModeChange && this.onModeChange();
setTimeout(()=>this.focus(),1);
} }
this.mode = mode; // 'wysiwyg' or 'plain'
cl.add('squire-mode-'+mode);
this.onModeChange && this.onModeChange();
setTimeout(()=>this.focus(),1);
} }
// CKeditor gimmicks used by HtmlEditor // CKeditor gimmicks used by HtmlEditor
@ -551,6 +551,7 @@ class SquireUI
} }
setData(html) { setData(html) {
// this.plain.value = html;
this.squire.setHTML(trimLines(html)); this.squire.setHTML(trimLines(html));
} }

View file

@ -1,7 +1,7 @@
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8"/>
<meta name="viewport" content="user-scalable=no" /> <meta name="viewport" content="user-scalable=no"/>
<title>{{subject}}</title> <title>{{subject}}</title>
<style> <style>
html, body { html, body {

View file

@ -528,11 +528,7 @@ class ComposePopupView extends AbstractViewPopup {
openOpenPgpPopup() { openOpenPgpPopup() {
if (PgpStore.capaOpenPGP() && this.oEditor && !this.oEditor.isHtml()) { if (PgpStore.capaOpenPGP() && this.oEditor && !this.oEditor.isHtml()) {
showScreenPopup(ComposeOpenPgpPopupView, [ showScreenPopup(ComposeOpenPgpPopupView, [
(result) => { result => this.editor(editor => editor.setPlain(result)),
this.editor((editor) => {
editor.setPlain(result);
});
},
this.oEditor.getData(false), this.oEditor.getData(false),
this.currentIdentity(), this.currentIdentity(),
this.to(), this.to(),
@ -568,9 +564,7 @@ class ComposePopupView extends AbstractViewPopup {
} }
}; };
identities.forEach((item, index) => { identities.forEach((item, index) => identitiesCache[item.email()] = [item, index]);
identitiesCache[item.email()] = [item, index];
});
if (message) { if (message) {
switch (composeType) { switch (composeType) {
@ -700,9 +694,7 @@ class ComposePopupView extends AbstractViewPopup {
} }
} }
converSignature(signature) { convertSignature(signature) {
signature = signature.replace(/[\r]/g, '');
let fromLine = this.oLastMessage ? this.emailArrayToStringLineHelper(this.oLastMessage.from, true) : ''; let fromLine = this.oLastMessage ? this.emailArrayToStringLineHelper(this.oLastMessage.from, true) : '';
if (fromLine) { if (fromLine) {
signature = signature.replace(/{{FROM-FULL}}/g, fromLine); signature = signature.replace(/{{FROM-FULL}}/g, fromLine);
@ -714,39 +706,24 @@ class ComposePopupView extends AbstractViewPopup {
signature = signature.replace(/{{FROM}}/g, fromLine); signature = signature.replace(/{{FROM}}/g, fromLine);
} }
signature = signature.replace(/[\s]{1,2}{{FROM}}/g, '{{FROM}}'); return signature
signature = signature.replace(/[\s]{1,2}{{FROM-FULL}}/g, '{{FROM-FULL}}'); .replace(/[\r]/g, '')
.replace(/[\s]{1,2}?{{FROM}}/g, '')
signature = signature.replace(/{{FROM}}/g, ''); .replace(/[\s]{1,2}?{{FROM-FULL}}/g, '')
signature = signature.replace(/{{FROM-FULL}}/g, ''); .replace(/{{DATE}}/g, new Date().format('LLLL'))
.replace(/{{TIME}}/g, new Date().format('LT'))
if (signature.includes('{{DATE}}')) { .replace(/{{MOMENT:[^}]+}}/g, '');
signature = signature.replace(/{{DATE}}/g, new Date().format('LLLL'));
}
if (signature.includes('{{TIME}}')) {
signature = signature.replace(/{{TIME}}/g, new Date().format('LT'));
}
signature = signature.replace(/{{MOMENT:[^}]+}}/g, '');
return signature;
} }
setSignatureFromIdentity(identity) { setSignatureFromIdentity(identity) {
if (identity) { if (identity) {
this.editor((editor) => { this.editor(editor => {
let isHtml = false, let signature = identity.signature(),
signature = identity.signature(); isHtml = signature && ':HTML:' === signature.substr(0, 6);
if (signature) { editor.setSignature(
if (':HTML:' === signature.substr(0, 6)) { this.convertSignature(isHtml ? signature.substr(6) : signature),
isHtml = true; isHtml, !!identity.signatureInsertBefore());
signature = signature.substr(6);
}
}
editor.setSignature(this.converSignature(signature), isHtml, !!identity.signatureInsertBefore());
}); });
} }
} }
@ -798,7 +775,7 @@ class ComposePopupView extends AbstractViewPopup {
onWarmUp() { onWarmUp() {
if (this.modalVisibility && !this.modalVisibility()) { if (this.modalVisibility && !this.modalVisibility()) {
this.editor(editor => editor.modeToggle(false)); this.editor(editor => editor.modeWysiwyg());
} }
} }
@ -827,6 +804,11 @@ class ComposePopupView extends AbstractViewPopup {
return aList.map(item => item.toLine(bFriendly)).join(', '); return aList.map(item => item.toLine(bFriendly)).join(', ');
} }
isPlainEditor() {
let type = this.editorDefaultType();
return EditorDefaultType.Html !== type && EditorDefaultType.HtmlForced !== type;
}
/** /**
* @param {string=} sType = ComposeType.Empty * @param {string=} sType = ComposeType.Empty
* @param {?MessageModel|Array=} oMessageOrArray = null * @param {?MessageModel|Array=} oMessageOrArray = null
@ -980,8 +962,8 @@ class ComposePopupView extends AbstractViewPopup {
'EMAIL': sFrom 'EMAIL': sFrom
}); });
sText = sText.replace(/<img[^>]+>/g, '').replace(/<a\s[^>]+><\/a>/g, ''); sText = sText.replace(/<img[^>]+>/g, '').replace(/<a\s[^>]+><\/a>/g, '').trim();
sText = '<br /><br />' + sReplyTitle + ':' + '<br /><br />' + '<blockquote>' + sText.trim() + '</blockquote>'; sText = '<br/><br/>' + sReplyTitle + ':<br/><br/><blockquote>' + sText + '</blockquote>';
break; break;
@ -990,28 +972,28 @@ class ComposePopupView extends AbstractViewPopup {
sTo = message.toToLine(false, true); sTo = message.toToLine(false, true);
sCc = message.ccToLine(false, true); sCc = message.ccToLine(false, true);
sText = sText =
'<br /><br />' + '<br/><br/>' +
i18n('COMPOSE/FORWARD_MESSAGE_TOP_TITLE') + i18n('COMPOSE/FORWARD_MESSAGE_TOP_TITLE') +
'<br />' + '<br/>' +
i18n('GLOBAL/FROM') + i18n('GLOBAL/FROM') +
': ' + ': ' +
sFrom + sFrom +
'<br />' + '<br/>' +
i18n('GLOBAL/TO') + i18n('GLOBAL/TO') +
': ' + ': ' +
sTo + sTo +
(sCc.length ? '<br />' + i18n('GLOBAL/CC') + ': ' + sCc : '') + (sCc.length ? '<br/>' + i18n('GLOBAL/CC') + ': ' + sCc : '') +
'<br />' + '<br/>' +
i18n('COMPOSE/FORWARD_MESSAGE_TOP_SENT') + i18n('COMPOSE/FORWARD_MESSAGE_TOP_SENT') +
': ' + ': ' +
encodeHtml(sDate) + encodeHtml(sDate) +
'<br />' + '<br/>' +
i18n('GLOBAL/SUBJECT') + i18n('GLOBAL/SUBJECT') +
': ' + ': ' +
encodeHtml(sSubject) + encodeHtml(sSubject) +
'<br /><br />' + '<br/><br/>' +
sText.trim() + sText.trim() +
'<br /><br />'; '<br/><br/>';
break; break;
case ComposeType.ForwardAsAttachment: case ComposeType.ForwardAsAttachment:
@ -1020,14 +1002,14 @@ class ComposePopupView extends AbstractViewPopup {
// no default // no default
} }
this.editor((editor) => { this.editor(editor => {
editor.setHtml(sText, false); editor.setHtml(sText);
if ( if (
EditorDefaultType.PlainForced === this.editorDefaultType() || EditorDefaultType.PlainForced === this.editorDefaultType() ||
(!message.isHtml() && EditorDefaultType.HtmlForced !== this.editorDefaultType()) (!message.isHtml() && EditorDefaultType.HtmlForced !== this.editorDefaultType())
) { ) {
editor.modeToggle(false); editor.modePlain();
} }
if (identity && ComposeType.Draft !== lineComposeType && ComposeType.EditAsNew !== lineComposeType) { if (identity && ComposeType.Draft !== lineComposeType && ComposeType.EditAsNew !== lineComposeType) {
@ -1041,14 +1023,11 @@ class ComposePopupView extends AbstractViewPopup {
sText = null != sCustomPlainText ? '' + sCustomPlainText : ''; sText = null != sCustomPlainText ? '' + sCustomPlainText : '';
this.editor((editor) => { this.editor(editor => {
editor.setHtml(sText, false); editor.setHtml(sText);
if ( if (this.isPlainEditor()) {
EditorDefaultType.Html !== this.editorDefaultType() && editor.modePlain();
EditorDefaultType.HtmlForced !== this.editorDefaultType()
) {
editor.modeToggle(false);
} }
if (identity) { if (identity) {
@ -1058,18 +1037,13 @@ class ComposePopupView extends AbstractViewPopup {
this.setFocusInPopup(); this.setFocusInPopup();
}); });
} else if (isNonEmptyArray(oMessageOrArray)) { } else if (isNonEmptyArray(oMessageOrArray)) {
oMessageOrArray.forEach(item => { oMessageOrArray.forEach(item => this.addMessageAsAttachment(item));
this.addMessageAsAttachment(item);
});
this.editor((editor) => { this.editor(editor => {
editor.setHtml('', false); if (this.isPlainEditor()) {
editor.setPlain('')
if ( } else {
EditorDefaultType.Html !== this.editorDefaultType() && editor.setHtml('');
EditorDefaultType.HtmlForced !== this.editorDefaultType()
) {
editor.modeToggle(false);
} }
if (identity && ComposeType.Draft !== lineComposeType && ComposeType.EditAsNew !== lineComposeType) { if (identity && ComposeType.Draft !== lineComposeType && ComposeType.EditAsNew !== lineComposeType) {
@ -1508,7 +1482,7 @@ class ComposePopupView extends AbstractViewPopup {
this.saving(false); this.saving(false);
if (this.oEditor) { if (this.oEditor) {
this.oEditor.clear(false); this.oEditor.clear();
} }
} }

View file

@ -85,7 +85,7 @@ class TemplatePopupView extends AbstractViewPopup {
this.submitError(''); this.submitError('');
if (this.editor) { if (this.editor) {
this.editor.setPlain('', false); this.editor.setPlain('');
} }
} }