UNPKG

penlf

Version:

a simple rich text editor.

237 lines (208 loc) 6.73 kB
require('./PenlfDefaultTheme.scss') function exec(command) { let value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; return document.execCommand(command, false, value); } function addEventListener(parent, type, listener) { return parent.addEventListener(type, listener); } function queryCommandValue(command) { return document.queryCommandValue(command); } function queryCommandState(command) { return document.queryCommandState(command); } function init(editorOfHtmlElement, savedHandler, moreActions) { let actions = [ // 加粗 { name: "bold", icon: "<b>B</b>", title: "加粗", type: 'button', state: () => { return queryCommandState('bold'); }, result: () => { return exec('bold') } }, // 斜体 { name: "italic", icon: "<i>I</i>", title: "斜体", type: 'button', state: () => { return queryCommandState('italic'); }, result: () => { return exec('italic') } }, // 下划线 { name: "underline", icon: "<u>U</u>", title: "下划线", type: 'button', state: () => { return queryCommandState('underline'); }, result: () => { exec('underline') } }, // h1-h4 { name: "heading1", icon: "<b>H1</b>", title: "一级标题", type: 'button', result: () => { return exec('formatBlock', '<h1>') } }, { name: "heading2", icon: "<b>H2</b>", title: "二级标题", type: 'button', result: () => { return exec('formatBlock', '<h2>') } }, { name: "heading3", icon: "<b>H3</b>", title: "三级标题", type: 'button', result: () => { return exec('formatBlock', '<h3>') } }, { name: "heading4", icon: "<b>H4</b>", title: "四级标题", type: 'button', result: () => { return exec('formatBlock', '<h4>') } }, { name: "quote", icon: "“”", title: "引用", type: 'button', result: () => { return exec('formatBlock', '<blockquote>'); } }, { name: "oList", icon: "·", title: "有序列表", type: 'button', result: () => { return exec('insertOrderedList'); } }, { name: "uList", icon: "123", title: "无序列表", type: 'button', result: () => { return exec('insertUnorderedList'); } }, { name: "line", icon: "line", title: "分割线", type: 'button', result: () => { exec('insertHorizontalRule') exec('formatBlock', '<p>') } }, ] if (moreActions) for (let i = 0; i < moreActions.length; i++) actions.push(moreActions[i]) editorOfHtmlElement.className = "RichTextEditor" // 初始化editor let editor = document.createElement('div'); editor.id = 'editor' editor.className = 'editor' editor.contentEditable = 'true' editor.style.overflow = 'auto' // 初始化actionsBar let actionsBar = document.createElement('div'); actionsBar.className = 'actionsBar' // 初始化按钮 actions.forEach((action) => { if (Object.keys(action).includes('init')) { action.init(editor, action, actionsBar) return } let button = document.createElement('button') button.classList.add('icon') button.classList.add(action.icon) button.innerHTML = action.icon // 更改样式的处理器 let changeCssHandler = () => { if (Object.keys(action).includes('state')) { if (action.state()) { button.classList.add('using') } else button.classList.remove('using') } } button.onclick = () => { action.result() changeCssHandler() } addEventListener(editor, 'keyup', changeCssHandler) addEventListener(editor, 'mouseup', changeCssHandler) addEventListener(editor, 'click', changeCssHandler) editorOfHtmlElement.appendChild(actionsBar) editorOfHtmlElement.appendChild(editor) actionsBar.appendChild(button) }) let continuousEnterInPre = 0 editor.onkeydown = (event) => { // 处理引用段的跳出 if (event.key === 'Enter' && queryCommandValue('formatBlock') === 'blockquote') { setTimeout(function () { return exec('formatBlock', '<p>'); }, 0); } // 处理代码段的跳出 if (event.key === 'Enter' && queryCommandValue('formatBlock') === 'pre') { continuousEnterInPre++ if (continuousEnterInPre >= 2) { setTimeout(function () { return exec('formatBlock', '<p>'); }, 0); } else { } } else continuousEnterInPre = 0 } // 快捷键绑定 addEventListener(editor, 'keydown', function (e) { if (e.keyCode === 83 && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)) { e.preventDefault(); // 保存 if (savedHandler) savedHandler(editor.innerHTML) else console.log("save") } }); exec('defaultParagraphSeparator', 'p') } function penlf(editor, saveHandler, moreActions) { if (typeof editor !== 'string') throw new Error("type of 'editor' variate must be 'string'.") init(document.querySelector(editor), saveHandler, moreActions) return {version: "0.3(beta)"} } window.penlf = penlf export default penlf // module.exports = editor