mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-01-02 21:12:02 +08:00
192 lines
3.9 KiB
JavaScript
192 lines
3.9 KiB
JavaScript
const
|
|
htmlre = /[&<>"']/g,
|
|
htmlmap = {
|
|
'&': '&',
|
|
'<': '<',
|
|
'>': '>',
|
|
'"': '"',
|
|
"'": '''
|
|
};
|
|
|
|
/**
|
|
* @param {string} text
|
|
* @returns {string}
|
|
*/
|
|
export function encodeHtml(text) {
|
|
return (text && text.toString ? text.toString() : ''+text).replace(htmlre, m => htmlmap[m]);
|
|
}
|
|
|
|
export class HtmlEditor {
|
|
/**
|
|
* @param {Object} element
|
|
* @param {Function=} onBlur
|
|
* @param {Function=} onReady
|
|
* @param {Function=} onModeChange
|
|
*/
|
|
constructor(element, onBlur = null, onReady = null, onModeChange = null) {
|
|
this.blurTimer = 0;
|
|
|
|
this.onBlur = onBlur;
|
|
this.onModeChange = onModeChange;
|
|
|
|
if (element) {
|
|
let editor;
|
|
|
|
onReady = onReady ? [onReady] : [];
|
|
this.onReady = fn => onReady.push(fn);
|
|
const readyCallback = () => {
|
|
this.editor = editor;
|
|
this.onReady = fn => fn();
|
|
onReady.forEach(fn => fn());
|
|
};
|
|
|
|
if (rl.createWYSIWYG) {
|
|
editor = rl.createWYSIWYG(element, readyCallback);
|
|
}
|
|
if (!editor) {
|
|
editor = new SquireUI(element);
|
|
setTimeout(readyCallback, 1);
|
|
}
|
|
|
|
editor.on('blur', () => this.blurTrigger());
|
|
editor.on('focus', () => this.blurTimer && clearTimeout(this.blurTimer));
|
|
editor.on('mode', () => {
|
|
this.blurTrigger();
|
|
this.onModeChange && this.onModeChange(!this.isPlain());
|
|
});
|
|
}
|
|
}
|
|
|
|
blurTrigger() {
|
|
if (this.onBlur) {
|
|
clearTimeout(this.blurTimer);
|
|
this.blurTimer = setTimeout(() => this.onBlur && 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(wrapIsHtml = false) {
|
|
let result = '';
|
|
if (this.editor) {
|
|
try {
|
|
if (this.isPlain() && this.editor.plugins.plain && this.editor.__plain) {
|
|
result = this.editor.__plain.getRawData();
|
|
} else {
|
|
result = wrapIsHtml
|
|
? '<div data-html-editor-font-wrapper="true" style="font-family: arial, sans-serif; font-size: 13px;">' +
|
|
this.editor.getData() +
|
|
'</div>'
|
|
: this.editor.getData();
|
|
}
|
|
} catch (e) {} // eslint-disable-line no-empty
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @param {boolean=} wrapIsHtml = false
|
|
* @returns {string}
|
|
*/
|
|
getDataWithHtmlMark(wrapIsHtml = false) {
|
|
return (this.isHtml() ? ':HTML:' : '') + this.getData(wrapIsHtml);
|
|
}
|
|
|
|
modeWysiwyg() {
|
|
this.onReady(() => this.editor.setMode('wysiwyg'));
|
|
}
|
|
modePlain() {
|
|
this.onReady(() => this.editor.setMode('plain'));
|
|
}
|
|
|
|
setHtmlOrPlain(text) {
|
|
if (':HTML:' === text.slice(0, 6)) {
|
|
this.setHtml(text.slice(6));
|
|
} else {
|
|
this.setPlain(text);
|
|
}
|
|
}
|
|
|
|
setData(mode, data) {
|
|
this.onReady(() => {
|
|
const editor = this.editor;
|
|
this.clearCachedSignature();
|
|
try {
|
|
editor.setMode(mode);
|
|
if (this.isPlain() && editor.plugins.plain && editor.__plain) {
|
|
editor.__plain.setRawData(data);
|
|
} else {
|
|
editor.setData(data);
|
|
}
|
|
} catch (e) { console.error(e); }
|
|
});
|
|
}
|
|
|
|
setHtml(html) {
|
|
this.setData('wysiwyg', html/*.replace(/<p[^>]*><\/p>/gi, '')*/);
|
|
}
|
|
|
|
setPlain(txt) {
|
|
this.setData('plain', txt);
|
|
}
|
|
|
|
focus() {
|
|
this.onReady(() => this.editor.focus());
|
|
}
|
|
|
|
hasFocus() {
|
|
try {
|
|
return this.editor && !!this.editor.focusManager.hasFocus;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
blur() {
|
|
this.onReady(() => this.editor.focusManager.blur(true));
|
|
}
|
|
|
|
clear() {
|
|
this.onReady(() => this.isPlain() ? this.setPlain('') : this.setHtml(''));
|
|
}
|
|
}
|