mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-29 20:19:22 +03:00
Redesign WYSIWYG handling to allow any editor (quill, tiny, etc. etc.)
This commit is contained in:
parent
e6db60e76c
commit
9eb5646aec
12 changed files with 180 additions and 51 deletions
|
|
@ -725,20 +725,12 @@ export const
|
|||
|
||||
WYSIWYGS = ko.observableArray();
|
||||
|
||||
WYSIWYGS.push(['Squire', (owner, container, onReady)=>{
|
||||
let squire = new SquireUI(container);
|
||||
setTimeout(()=>onReady(squire), 1);
|
||||
/*
|
||||
squire.on('blur', () => owner.blurTrigger());
|
||||
squire.on('focus', () => clearTimeout(owner.blurTimer));
|
||||
squire.on('mode', () => {
|
||||
owner.blurTrigger();
|
||||
owner.onModeChange?.(!owner.isPlain());
|
||||
});
|
||||
*/
|
||||
}]);
|
||||
WYSIWYGS.push({
|
||||
name: 'Squire',
|
||||
construct: (owner, container, onReady) => onReady(new SquireUI(container))
|
||||
});
|
||||
|
||||
rl.registerWYSIWYG = (name, construct) => WYSIWYGS.push([name, construct]);
|
||||
rl.registerWYSIWYG = (name, construct) => WYSIWYGS.push({name, construct});
|
||||
|
||||
export class HtmlEditor {
|
||||
/**
|
||||
|
|
@ -747,7 +739,7 @@ export class HtmlEditor {
|
|||
* @param {Function=} onReady
|
||||
* @param {Function=} onModeChange
|
||||
*/
|
||||
constructor(element, onBlur = null, onReady = null, onModeChange = null) {
|
||||
constructor(element, onReady = null, onModeChange = null, onBlur = null) {
|
||||
this.blurTimer = 0;
|
||||
|
||||
this.onBlur = onBlur;
|
||||
|
|
@ -757,10 +749,10 @@ export class HtmlEditor {
|
|||
onReady = onReady ? [onReady] : [];
|
||||
this.onReady = fn => onReady.push(fn);
|
||||
// TODO: make 'which' user configurable
|
||||
// const which = 'CKEditor4',
|
||||
// wysiwyg = WYSIWYGS.find(item => which == item[0]) || WYSIWYGS.find(item => 'Squire' == item[0]);
|
||||
const wysiwyg = WYSIWYGS.find(item => 'Squire' == item[0]);
|
||||
wysiwyg[1](this, element, editor => {
|
||||
const which = SettingsUserStore.editorWysiwyg(),
|
||||
wysiwyg = WYSIWYGS.find(item => which == item.name) || WYSIWYGS.find(item => 'Squire' == item.name);
|
||||
// const wysiwyg = WYSIWYGS.find(item => 'Squire' == item.name);
|
||||
wysiwyg.construct(this, element, editor => setTimeout(()=>{
|
||||
this.editor = editor;
|
||||
editor.on('blur', () => this.blurTrigger());
|
||||
editor.on('focus', () => clearTimeout(this.blurTimer));
|
||||
|
|
@ -770,7 +762,7 @@ export class HtmlEditor {
|
|||
});
|
||||
this.onReady = fn => fn();
|
||||
onReady.forEach(fn => fn());
|
||||
});
|
||||
},1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -826,8 +818,8 @@ export class HtmlEditor {
|
|||
let result = '';
|
||||
if (this.editor) {
|
||||
try {
|
||||
if (this.isPlain() && this.editor.plugins.plain && this.editor.__plain) {
|
||||
result = this.editor.__plain.getRawData();
|
||||
if (this.isPlain()) {
|
||||
result = this.editor.getPlainData();
|
||||
} else {
|
||||
result = this.editor.getData();
|
||||
}
|
||||
|
|
@ -862,8 +854,8 @@ export class HtmlEditor {
|
|||
this.clearCachedSignature();
|
||||
try {
|
||||
editor.setMode(mode);
|
||||
if (this.isPlain() && editor.plugins.plain && editor.__plain) {
|
||||
editor.__plain.setRawData(data);
|
||||
if (this.isPlain()) {
|
||||
editor.setPlainData(data);
|
||||
} else {
|
||||
editor.setData(data);
|
||||
}
|
||||
|
|
@ -883,16 +875,8 @@ export class HtmlEditor {
|
|||
this.onReady(() => this.editor.focus());
|
||||
}
|
||||
|
||||
hasFocus() {
|
||||
try {
|
||||
return !!this.editor?.focusManager.hasFocus;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
blur() {
|
||||
this.onReady(() => this.editor.focusManager.blur(true));
|
||||
this.onReady(() => this.editor.blur());
|
||||
}
|
||||
|
||||
clear() {
|
||||
|
|
|
|||
27
dev/External/SquireUI.js
vendored
27
dev/External/SquireUI.js
vendored
|
|
@ -318,11 +318,6 @@ class SquireUI
|
|||
wysiwyg.className = 'squire-wysiwyg';
|
||||
wysiwyg.dir = 'auto';
|
||||
this.mode = ''; // 'plain' | 'wysiwyg'
|
||||
this.__plain = {
|
||||
getRawData: () => this.plain.value,
|
||||
setRawData: plain => this.plain.value = plain
|
||||
};
|
||||
|
||||
this.container = container;
|
||||
this.squire = squire;
|
||||
this.plain = plain;
|
||||
|
|
@ -530,15 +525,6 @@ class SquireUI
|
|||
console.dir({select:e.range});
|
||||
});
|
||||
*/
|
||||
|
||||
// CKEditor gimmicks used by HtmlEditor
|
||||
this.plugins = {
|
||||
plain: true
|
||||
};
|
||||
this.focusManager = {
|
||||
hasFocus: () => squire._isFocused,
|
||||
blur: () => squire.blur()
|
||||
};
|
||||
}
|
||||
|
||||
doAction(name) {
|
||||
|
|
@ -576,7 +562,6 @@ class SquireUI
|
|||
this.modeSelect.selectedIndex = 'plain' == this.mode ? 1 : 0;
|
||||
}
|
||||
|
||||
// CKeditor gimmicks used by HtmlEditor
|
||||
on(type, fn) {
|
||||
if ('mode' == type) {
|
||||
this.onModeChange = fn;
|
||||
|
|
@ -643,6 +628,18 @@ class SquireUI
|
|||
squire.setSelection( range );
|
||||
}
|
||||
|
||||
getPlainData() {
|
||||
return this.plain.value;
|
||||
}
|
||||
|
||||
setPlainData(text) {
|
||||
this.plain.value = text;
|
||||
}
|
||||
|
||||
blur() {
|
||||
this.squire.blur();
|
||||
}
|
||||
|
||||
focus() {
|
||||
if ('plain' == this.mode) {
|
||||
this.plain.focus();
|
||||
|
|
|
|||
2
dev/External/User/ko.js
vendored
2
dev/External/User/ko.js
vendored
|
|
@ -91,7 +91,7 @@ Object.assign(ko.bindingHandlers, {
|
|||
};
|
||||
|
||||
if (ko.isObservable(fValue)) {
|
||||
editor = new HtmlEditor(element, fUpdateKoValue, fOnReady, fUpdateKoValue);
|
||||
editor = new HtmlEditor(element, fOnReady, fUpdateKoValue, fUpdateKoValue);
|
||||
|
||||
fValue.__fetchEditorValue = fUpdateKoValue;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { SaveSettingStatus } from 'Common/Enums';
|
|||
import { LayoutSideView, LayoutBottomView } from 'Common/EnumsUser';
|
||||
import { setRefreshFoldersInterval } from 'Common/Folders';
|
||||
import { Settings, SettingsGet } from 'Common/Globals';
|
||||
import { WYSIWYGS } from 'Common/Html';
|
||||
import { isArray } from 'Common/Utils';
|
||||
import { addSubscribablesTo, addComputablesTo } from 'External/ko';
|
||||
import { i18n, translateTrigger, translatorReload, convertLangName } from 'Common/Translator';
|
||||
|
|
@ -44,7 +45,7 @@ export class UserSettingsGeneral extends AbstractViewSettings {
|
|||
['useThreads',
|
||||
// These use addSetting()
|
||||
'layout', 'messageReadDelay', 'messagesPerPage', 'checkMailInterval',
|
||||
'editorDefaultType', 'msgDefaultAction', 'maxBlockquotesLevel',
|
||||
'editorDefaultType', 'editorWysiwyg', 'msgDefaultAction', 'maxBlockquotesLevel',
|
||||
// These are in addSettings()
|
||||
'requestReadReceipt', 'requestDsn', 'requireTLS', 'pgpSign', 'pgpEncrypt',
|
||||
'viewHTML', 'viewImages', 'viewImagesWhitelist', 'removeColors', 'allowStyles', 'allowDraftAutosave',
|
||||
|
|
@ -59,6 +60,8 @@ export class UserSettingsGeneral extends AbstractViewSettings {
|
|||
|
||||
this.identities = IdentityUserStore;
|
||||
|
||||
this.wysiwygs = WYSIWYGS;
|
||||
|
||||
addComputablesTo(this, {
|
||||
languageFullName: () => convertLangName(this.language()),
|
||||
|
||||
|
|
@ -80,6 +83,8 @@ export class UserSettingsGeneral extends AbstractViewSettings {
|
|||
];
|
||||
},
|
||||
|
||||
hasWysiwygs: () => 1 < WYSIWYGS().length,
|
||||
|
||||
msgDefaultActions: () => {
|
||||
translateTrigger();
|
||||
return [
|
||||
|
|
@ -99,6 +104,7 @@ export class UserSettingsGeneral extends AbstractViewSettings {
|
|||
});
|
||||
|
||||
this.addSetting('EditorDefaultType');
|
||||
this.addSetting('editorWysiwyg');
|
||||
this.addSetting('MsgDefaultAction');
|
||||
this.addSetting('MessageReadDelay');
|
||||
this.addSetting('MessagesPerPage');
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ export const SettingsUserStore = new class {
|
|||
|
||||
layout: 1,
|
||||
editorDefaultType: 'Html',
|
||||
editorWysiwyg: 'Squire',
|
||||
msgDefaultAction: 1
|
||||
});
|
||||
|
||||
|
|
@ -78,9 +79,10 @@ export const SettingsUserStore = new class {
|
|||
|
||||
init() {
|
||||
const self = this;
|
||||
self.editorDefaultType(SettingsGet('EditorDefaultType'));
|
||||
|
||||
[
|
||||
'EditorDefaultType',
|
||||
'editorWysiwyg',
|
||||
'messageNewWindow',
|
||||
'messageReadAuto',
|
||||
'MsgDefaultAction',
|
||||
|
|
|
|||
|
|
@ -704,7 +704,6 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
// setTimeout(() => {
|
||||
this.oEditor = new HtmlEditor(
|
||||
this.editorArea(),
|
||||
null,
|
||||
() => fOnInit(this.oEditor),
|
||||
bHtml => this.isHtml(!!bHtml)
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue