diff --git a/dev/Common/Html.js b/dev/Common/Html.js index b2d929afa..08dc2b559 100644 --- a/dev/Common/Html.js +++ b/dev/Common/Html.js @@ -721,168 +721,7 @@ export const .replace(/\n/g, '
'); blockquoteSwitcher(); return tmpl.innerHTML.trim(); - }, - - WYSIWYGS = ko.observableArray(); - -WYSIWYGS.push({ - name: 'Squire', - construct: (owner, container, onReady) => onReady(new SquireUI(container)) -}); - -rl.registerWYSIWYG = (name, construct) => WYSIWYGS.push({name, construct}); - -export class HtmlEditor { - /** - * @param {Object} element - * @param {Function=} onBlur - * @param {Function=} onReady - * @param {Function=} onModeChange - */ - constructor(element, onReady = null, onModeChange = null, onBlur = null) { - this.blurTimer = 0; - - this.onBlur = onBlur; - this.onModeChange = onModeChange; - - if (element) { - onReady = onReady ? [onReady] : []; - this.onReady = fn => onReady.push(fn); - // TODO: make 'which' user configurable - 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)); - editor.on('mode', () => { - this.blurTrigger(); - this.onModeChange?.(!this.isPlain()); - }); - this.onReady = fn => fn(); - onReady.forEach(fn => fn()); - },1)); - } - } - - blurTrigger() { - if (this.onBlur) { - clearTimeout(this.blurTimer); - this.blurTimer = setTimeout(() => this.onBlur?.(), 200); - } - } - - /** - * @returns {boolean} - */ - isHtml() { - return this.editor ? !this.isPlain() : false; - } - - /** - * @returns {boolean} - */ - isPlain() { - return this.editor ? 'plain' === this.editor.mode : false; - } - - /** - * @returns {void} - */ - clearCachedSignature() { - this.onReady(() => this.editor.execCommand('insertSignature', { - clearCache: true - })); - } - - /** - * @param {string} signature - * @param {bool} html - * @param {bool} insertBefore - * @returns {void} - */ - setSignature(signature, html, insertBefore = false) { - this.onReady(() => this.editor.execCommand('insertSignature', { - isHtml: html, - insertBefore: insertBefore, - signature: signature - })); - } - - /** - * @param {boolean=} wrapIsHtml = false - * @returns {string} - */ - getData() { - let result = ''; - if (this.editor) { - try { - if (this.isPlain()) { - result = this.editor.getPlainData(); - } else { - result = this.editor.getData(); - } - } catch (e) {} // eslint-disable-line no-empty - } - return result; - } - - /** - * @returns {string} - */ - getDataWithHtmlMark() { - return (this.isHtml() ? ':HTML:' : '') + this.getData(); - } - - modeWysiwyg() { - this.onReady(() => this.editor.setMode('wysiwyg')); - } - modePlain() { - this.onReady(() => this.editor.setMode('plain')); - } - - setHtmlOrPlain(text) { - text.startsWith(':HTML:') - ? this.setHtml(text.slice(6)) - : this.setPlain(text); - } - - setData(mode, data) { - this.onReady(() => { - const editor = this.editor; - this.clearCachedSignature(); - try { - editor.setMode(mode); - if (this.isPlain()) { - editor.setPlainData(data); - } else { - editor.setData(data); - } - } catch (e) { console.error(e); } - }); - } - - setHtml(html) { - this.setData('wysiwyg', html/*.replace(/]*><\/p>/gi, '')*/); - } - - setPlain(txt) { - this.setData('plain', txt); - } - - focus() { - this.onReady(() => this.editor.focus()); - } - - blur() { - this.onReady(() => this.editor.blur()); - } - - clear() { - this.onReady(() => this.isPlain() ? this.setPlain('') : this.setHtml('')); - } -} + }; rl.Utils = { htmlToPlain: htmlToPlain, diff --git a/dev/Common/HtmlEditor.js b/dev/Common/HtmlEditor.js new file mode 100644 index 000000000..0bbfdbdea --- /dev/null +++ b/dev/Common/HtmlEditor.js @@ -0,0 +1,163 @@ +import { SettingsUserStore } from 'Stores/User/Settings'; + +export const + WYSIWYGS = ko.observableArray(); + +WYSIWYGS.push({ + name: 'Squire', + construct: (owner, container, onReady) => onReady(new SquireUI(container)) +}); + +rl.registerWYSIWYG = (name, construct) => WYSIWYGS.push({name, construct}); + +export class HtmlEditor { + /** + * @param {Object} element + * @param {Function=} onBlur + * @param {Function=} onReady + * @param {Function=} onModeChange + */ + constructor(element, onReady = null, onModeChange = null, onBlur = null) { + this.blurTimer = 0; + + this.onBlur = onBlur; + this.onModeChange = onModeChange; + + if (element) { + onReady = onReady ? [onReady] : []; + this.onReady = fn => onReady.push(fn); + // TODO: make 'which' user configurable + 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)); + editor.on('mode', () => { + this.blurTrigger(); + this.onModeChange?.(!this.isPlain()); + }); + this.onReady = fn => fn(); + onReady.forEach(fn => fn()); + },1)); + } + } + + blurTrigger() { + if (this.onBlur) { + clearTimeout(this.blurTimer); + this.blurTimer = setTimeout(() => this.onBlur?.(), 200); + } + } + + /** + * @returns {boolean} + */ + isHtml() { + return this.editor ? !this.isPlain() : false; + } + + /** + * @returns {boolean} + */ + isPlain() { + return this.editor ? 'plain' === this.editor.mode : false; + } + + /** + * @returns {void} + */ + clearCachedSignature() { + this.onReady(() => this.editor.execCommand('insertSignature', { + clearCache: true + })); + } + + /** + * @param {string} signature + * @param {bool} html + * @param {bool} insertBefore + * @returns {void} + */ + setSignature(signature, html, insertBefore = false) { + this.onReady(() => this.editor.execCommand('insertSignature', { + isHtml: html, + insertBefore: insertBefore, + signature: signature + })); + } + + /** + * @param {boolean=} wrapIsHtml = false + * @returns {string} + */ + getData() { + let result = ''; + if (this.editor) { + try { + if (this.isPlain()) { + result = this.editor.getPlainData(); + } else { + result = this.editor.getData(); + } + } catch (e) {} // eslint-disable-line no-empty + } + return result; + } + + /** + * @returns {string} + */ + getDataWithHtmlMark() { + return (this.isHtml() ? ':HTML:' : '') + this.getData(); + } + + modeWysiwyg() { + this.onReady(() => this.editor.setMode('wysiwyg')); + } + modePlain() { + this.onReady(() => this.editor.setMode('plain')); + } + + setHtmlOrPlain(text) { + text.startsWith(':HTML:') + ? this.setHtml(text.slice(6)) + : this.setPlain(text); + } + + setData(mode, data) { + this.onReady(() => { + const editor = this.editor; + this.clearCachedSignature(); + try { + editor.setMode(mode); + if (this.isPlain()) { + editor.setPlainData(data); + } else { + editor.setData(data); + } + } catch (e) { console.error(e); } + }); + } + + setHtml(html) { + this.setData('wysiwyg', html/*.replace(/]*><\/p>/gi, '')*/); + } + + setPlain(txt) { + this.setData('plain', txt); + } + + focus() { + this.onReady(() => this.editor.focus()); + } + + blur() { + this.onReady(() => this.editor.blur()); + } + + clear() { + this.onReady(() => this.isPlain() ? this.setPlain('') : this.setHtml('')); + } +} diff --git a/dev/External/User/ko.js b/dev/External/User/ko.js index 7affba8d5..78dc965eb 100644 --- a/dev/External/User/ko.js +++ b/dev/External/User/ko.js @@ -1,7 +1,7 @@ import 'External/ko'; import ko from 'ko'; import { RFC822 } from 'Common/File'; -import { HtmlEditor } from 'Common/Html'; +import { HtmlEditor } from 'Common/HtmlEditor'; import { timeToNode } from 'Common/Translator'; import { doc, elementById, addEventsListeners, dropdowns, leftPanelDisabled } from 'Common/Globals'; import { EmailAddressesComponent } from 'Component/EmailAddresses'; diff --git a/dev/Settings/User/General.js b/dev/Settings/User/General.js index 3c2584c5b..cb1cdc73b 100644 --- a/dev/Settings/User/General.js +++ b/dev/Settings/User/General.js @@ -5,7 +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 { WYSIWYGS } from 'Common/HtmlEditor'; import { isArray } from 'Common/Utils'; import { addSubscribablesTo, addComputablesTo } from 'External/ko'; import { i18n, translateTrigger, translatorReload, convertLangName } from 'Common/Translator'; diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js index 336e33f94..35a33fc1f 100644 --- a/dev/View/Popup/Compose.js +++ b/dev/View/Popup/Compose.js @@ -11,7 +11,8 @@ import { } from 'Common/EnumsUser'; import { pInt, isArray, arrayLength, b64Encode } from 'Common/Utils'; -import { encodeHtml, HtmlEditor, htmlToPlain } from 'Common/Html'; +import { encodeHtml, htmlToPlain } from 'Common/Html'; +import { HtmlEditor } from 'Common/HtmlEditor'; import { koArrayWithDestroy, addObservablesTo, addComputablesTo, addSubscribablesTo } from 'External/ko'; import { UNUSED_OPTION_VALUE } from 'Common/Consts';