144 lines
4.3 KiB
JavaScript
144 lines
4.3 KiB
JavaScript
(function (root) {
|
|
'use strict';
|
|
|
|
var documentRef = root.document;
|
|
var editors = {};
|
|
var submitBound = false;
|
|
var toolbarKeys = [
|
|
'headerSelect', 'fontSize', 'color', 'bgColor', '|',
|
|
'bold', 'italic', 'underline', 'through', '|',
|
|
'justifyLeft', 'justifyCenter', 'justifyRight', 'justifyJustify', '|',
|
|
'insertTable', 'clearStyle', 'insertLink', 'undo', 'redo'
|
|
];
|
|
|
|
function findTextarea(target) {
|
|
if (!target || !documentRef) return null;
|
|
if (typeof target === 'string') return documentRef.querySelector(target);
|
|
if (target.nodeType === 1) return target;
|
|
return target[0] || null;
|
|
}
|
|
|
|
function ensureId(textarea) {
|
|
if (!textarea.id) textarea.id = 'rich-editor-' + Math.floor(Math.random() * 1000000);
|
|
return textarea.id;
|
|
}
|
|
|
|
function fieldValue(editor) {
|
|
return String(editor.getText() || '').trim() ? editor.getHtml() : '';
|
|
}
|
|
|
|
function syncEditor(instance) {
|
|
instance.textarea.value = fieldValue(instance.editor);
|
|
}
|
|
|
|
function createRichEditor(target, options) {
|
|
var textarea = findTextarea(target);
|
|
var settings = options || {};
|
|
var id;
|
|
var host;
|
|
var toolbar;
|
|
var content;
|
|
var editor;
|
|
var wangEditor = root.wangEditor;
|
|
var instance;
|
|
|
|
if (!textarea || !wangEditor || !wangEditor.createEditor || !wangEditor.createToolbar) return null;
|
|
if (textarea.dataset.wangEditorInitialized === 'true') return editors[textarea.id] || null;
|
|
|
|
id = ensureId(textarea);
|
|
host = documentRef.createElement('div');
|
|
host.className = 'rich-editor-host';
|
|
toolbar = documentRef.createElement('div');
|
|
toolbar.className = 'rich-editor-toolbar';
|
|
toolbar.id = id + '-toolbar';
|
|
content = documentRef.createElement('div');
|
|
content.className = 'rich-editor-content';
|
|
content.id = id + '-content';
|
|
host.appendChild(toolbar);
|
|
host.appendChild(content);
|
|
textarea.insertAdjacentElement('afterend', host);
|
|
|
|
try {
|
|
editor = wangEditor.createEditor({
|
|
selector: '#' + content.id,
|
|
html: textarea.value || '',
|
|
config: Object.assign({
|
|
placeholder: textarea.getAttribute('placeholder') || '请输入内容',
|
|
onChange: function (currentEditor) {
|
|
textarea.value = fieldValue(currentEditor);
|
|
},
|
|
onBlur: function (currentEditor) {
|
|
textarea.value = fieldValue(currentEditor);
|
|
}
|
|
}, settings.editorConfig || {}),
|
|
mode: settings.mode || 'default'
|
|
});
|
|
wangEditor.createToolbar({
|
|
editor: editor,
|
|
selector: '#' + toolbar.id,
|
|
config: Object.assign({ toolbarKeys: toolbarKeys }, settings.toolbarConfig || {}),
|
|
mode: settings.mode || 'default'
|
|
});
|
|
} catch (error) {
|
|
host.remove();
|
|
return null;
|
|
}
|
|
|
|
textarea.hidden = true;
|
|
textarea.setAttribute('aria-hidden', 'true');
|
|
textarea.dataset.wangEditorInitialized = 'true';
|
|
instance = {
|
|
textarea: textarea,
|
|
editor: editor,
|
|
sync: function () { syncEditor(instance); },
|
|
getHtml: function () { return fieldValue(editor); },
|
|
getText: function () { return editor.getText(); }
|
|
};
|
|
editors[id] = instance;
|
|
instance.sync();
|
|
return instance;
|
|
}
|
|
|
|
function initRichEditors(rootNode, options) {
|
|
var scope = rootNode || documentRef;
|
|
var instances = {};
|
|
|
|
if (!scope || !scope.querySelectorAll) return instances;
|
|
Array.prototype.forEach.call(scope.querySelectorAll('.js-rich-editor'), function (textarea) {
|
|
var instance = createRichEditor(textarea, options);
|
|
|
|
if (instance) instances[textarea.id] = instance;
|
|
});
|
|
return instances;
|
|
}
|
|
|
|
function bindFormSync() {
|
|
if (submitBound || !documentRef) return;
|
|
submitBound = true;
|
|
documentRef.addEventListener('submit', function (event) {
|
|
Object.keys(editors).forEach(function (id) {
|
|
var instance = editors[id];
|
|
|
|
if (instance.textarea.form === event.target) instance.sync();
|
|
});
|
|
});
|
|
}
|
|
|
|
function initAll() {
|
|
bindFormSync();
|
|
return initRichEditors(documentRef);
|
|
}
|
|
|
|
root.AppRichEditor = {
|
|
init: createRichEditor,
|
|
initAll: initRichEditors,
|
|
syncAll: function () {
|
|
Object.keys(editors).forEach(function (id) { editors[id].sync(); });
|
|
}
|
|
};
|
|
|
|
if (!documentRef) return;
|
|
if (documentRef.readyState === 'loading') documentRef.addEventListener('DOMContentLoaded', initAll);
|
|
else initAll();
|
|
})(window);
|