From 33daf69bcb231cdceb9e2d92f27c1be4d816a6b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E5=A4=A9?= Date: Mon, 16 Sep 2019 17:27:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90neditor=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/neditor/index.js | 479 ------------------------------------------- src/neditor/index.wc | 13 +- 2 files changed, 9 insertions(+), 483 deletions(-) delete mode 100644 src/neditor/index.js diff --git a/src/neditor/index.js b/src/neditor/index.js deleted file mode 100644 index cd8a1c9..0000000 --- a/src/neditor/index.js +++ /dev/null @@ -1,479 +0,0 @@ -/** - * neditor - * @author yutent - * @date 2019/07/05 13:44:10 - */ - -'use strict' - -const log = console.log - -import iconList from './icon' - -const ACTTION = { - bold: 'bold', - italic: 'italic', - under: 'underline', - delete: 'strikeThrough', - left: 'justifyLeft', - center: 'justifyCenter', - right: 'justifyRight', - image: 'insertImage', - font: 'fontSize', - color: 'foreColor', - link: 'createLink', - ordered: 'insertOrderedList', - unordered: 'insertUnorderedList' -} - -const DEFAULT_TOOLS = [ - 'font', - 'color', - 'bold', - 'italic', - 'under', - 'delete', - 'ordered', - 'unordered', - 'left', - 'center', - 'right', - 'link', - 'image' -] - -export default class Nedtior extends HTMLElement { - // 监听属性变化 - static get observedAttributes() { - return ['toolbar', 'value'] - } - - constructor() { - super() - this.root = this.attachShadow({ mode: 'open' }) - - this.render() - this.__TOOLBAR__ = this.root.children[2] - this.__FONT__ = this.root.children[3] - this.__COLOR__ = this.root.children[4] - this.__LINK__ = this.root.children[5] - this.__LINK_BTN__ = this.__LINK__.querySelector('span') - this.__EDITOR__ = this.root.lastElementChild - } - - render() { - this.root.innerHTML = ` - - - -
- ${this._parseTools()} -
-
- 大号字体 - 中号字体 - 小号字体 -
-
- - - - - - - - - - - - -
- -
- ` - } - - // 解析工具栏 - _parseTools() { - const tools = this.tools || DEFAULT_TOOLS - - return tools - .map( - it => - `${ - it === 'image' ? '' : '' - }` - ) - .join('') - } - - get value() { - return this.__EDITOR__.innerHTML - } - - set value(val) { - if (this.__EDITOR__ && this.__EDITOR__.innerHTML !== val) { - this.__EDITOR__.innerHTML = val - } - } - - set toolbar(val) { - if (val && Array.isArray(val)) { - this.tools = val - if (this.__TOOLBAR__) { - if (this.tools.length) { - this.__TOOLBAR__.style.display = 'flex' - this.__TOOLBAR__.innerHTML = this._parseTools() - } else { - this.__TOOLBAR__.style.display = 'none' - } - } - } - } - - // 保存选中 - saveSelection() { - var gs = this.root.getSelection() - if (gs.getRangeAt && gs.rangeCount) { - this.__SELECT__ = gs.getRangeAt(0) - } - } - - // 清除选中并重置选中 - restoreSelection() { - var gs = this.root.getSelection() - if (this.__SELECT__) { - try { - gs.removeAllRanges() - } catch (err) {} - gs.addRange(this.__SELECT__) - } - } - - // 执行命令 - exec(cmd, val = '') { - document.execCommand(cmd, false, val) - } - - // 处理图片 - _handleImage(file) { - this.dispatchEvent( - new CustomEvent('upload', { - detail: { - file, - send: link => { - this.__EDITOR__.focus() - this.restoreSelection() - this.exec(ACTTION.image, link) - this.saveSelection() - // 修正插入的图片,宽度不得超出容器 - this.__EDITOR__.querySelectorAll('img').forEach(_ => { - _.style.maxWidth = '100%' - }) - } - } - }) - ) - } - - connectedCallback() { - const LINK_INPUT = this.__LINK__.querySelector('input') - const FILE_INPUT = this.__TOOLBAR__.querySelector('input') - - document.execCommand('styleWithCSS', null, true) - - // 这里有一个彩蛋 - if (FILE_INPUT) { - FILE_INPUT.addEventListener( - 'change', - ev => { - this._handleImage(FILE_INPUT.files[0]) - }, - false - ) - } - - // 工具栏点击事件 - this.__toolFn = ev => { - if (ev.target === ev.currentTarget) { - return - } - let target = ev.target - while (target.tagName !== 'SPAN') { - target = target.parentNode - } - var act = target.dataset.act - var val = '' - - switch (act) { - case 'font': - this.__COLOR__.classList.remove('fadein') - this.__LINK__.classList.remove('fadein') - - if (this.__FONT__.classList.contains('fadein')) { - this.__FONT__.classList.remove('fadein') - } else { - this.__FONT__.classList.add('fadein') - } - break - - case 'color': - this.__LINK__.classList.remove('fadein') - this.__FONT__.classList.remove('fadein') - if (this.__COLOR__.classList.contains('fadein')) { - this.__COLOR__.classList.remove('fadein') - } else { - this.__COLOR__.classList.add('fadein') - } - break - - case 'link': - this.__COLOR__.classList.remove('fadein') - this.__FONT__.classList.remove('fadein') - if (this.__LINK__.classList.contains('fadein')) { - this.__LINK__.classList.remove('fadein') - } else { - this.__LINK__.classList.add('fadein') - } - break - - case 'image': - // 这里不作任何处理 - break - - default: - this.__EDITOR__.focus() - this.restoreSelection() - this.exec(ACTTION[act]) - this.saveSelection() - } - } - - // 字体大小设置 - this.__fontFn = ev => { - if (ev.target === ev.currentTarget) { - return - } - this.__FONT__.classList.remove('fadein') - this.__EDITOR__.focus() - this.restoreSelection() - this.exec(ACTTION.font, ev.target.dataset.size) - this.saveSelection() - } - - // 颜色 - this.__colorFn = ev => { - if (ev.target === ev.currentTarget) { - return - } - this.__COLOR__.classList.remove('fadein') - this.__EDITOR__.focus() - this.restoreSelection() - this.exec(ACTTION.color, ev.target.dataset.color) - this.saveSelection() - } - - // 超链接 - this.__linkFn = ev => { - if (LINK_INPUT.value) { - this.__LINK__.classList.remove('fadein') - this.__EDITOR__.focus() - this.restoreSelection() - this.exec(ACTTION.link, LINK_INPUT.value) - this.saveSelection() - LINK_INPUT.value = '' - } - } - - //监听鼠标事件的,以缓存选中状态 - this.__mouseFn = ev => { - this.__FONT__.classList.remove('fadein') - this.__COLOR__.classList.remove('fadein') - this.__LINK__.classList.remove('fadein') - this.saveSelection() - } - - // 粘贴板事件 - this.__pasteFn = ev => { - ev.preventDefault() - - var txt = ev.clipboardData.getData('text/plain') - var items = ev.clipboardData.items - - if (txt) { - return this.exec('insertText', txt) - } - - if (items && items.length) { - let blob = null - for (let it of items) { - if (it.type.indexOf('image') > -1) { - blob = it.getAsFile() - } - } - this._handleImage(blob) - } - } - - this.__TOOLBAR__.addEventListener('click', this.__toolFn, false) - this.__FONT__.addEventListener('click', this.__fontFn, false) - this.__COLOR__.addEventListener('click', this.__colorFn, false) - this.__LINK_BTN__.addEventListener('click', this.__linkFn, false) - this.__EDITOR__.addEventListener('mouseup', this.__mouseFn, false) - this.__EDITOR__.addEventListener('paste', this.__pasteFn, false) - - this.__observer = new MutationObserver(_ => { - this.dispatchEvent( - new CustomEvent('updated', { - detail: this.value - }) - ) - }) - - this.__observer.observe(this.__EDITOR__, { - childList: true, - subtree: true, - characterData: true - }) - } - - disconnectedCallback() { - this.__TOOLBAR__.removeEventListener('click', this.__toolFn) - this.__FONT__.removeEventListener('click', this.__fontFn) - this.__COLOR__.removeEventListener('click', this.__colorFn) - this.__LINK_BTN__.removeEventListener('click', this.__linkFn) - this.__EDITOR__.removeEventListener('mouseup', this.__mouseFn) - this.__EDITOR__.removeEventListener('paste', this.__pasteFn) - - this.__observer.disconnect() - } - - attributeChangedCallback(name, old, val) { - switch (name) { - case 'toolbar': - if (typeof val === 'string') { - try { - val = val.split(',') - } catch (err) {} - } - this.toolbar = val - break - - case 'value': - this.value = val - break - - default: - break - } - } -} - -customElements.define('do-neditor', Nedtior) diff --git a/src/neditor/index.wc b/src/neditor/index.wc index db467c2..7323d19 100644 --- a/src/neditor/index.wc +++ b/src/neditor/index.wc @@ -259,7 +259,7 @@ export default class Neditor { var ct = this.root.children[1] this.__TOOLBAR__ = ct.children[0] - this.__EDITOR__ = ct.children[1] + this.__EDITOR__ = ct.children[1].firstElementChild this.__FONT__ = ct.children[2] this.__COLOR__ = ct.children[3] @@ -272,9 +272,7 @@ export default class Neditor { } set value(val) { - if (this.__EDITOR__ && this.__EDITOR__.innerHTML !== val) { - this.__EDITOR__.innerHTML = val - } + this.__EDITOR__.innerHTML = val } _updateToolbar() { @@ -354,6 +352,7 @@ export default class Neditor { // 工具栏点击事件 this._toolFn = bind(this.__TOOLBAR__, 'click', ev => { + this.restoreSelection() if (ev.target === ev.currentTarget) { return } @@ -452,6 +451,12 @@ export default class Neditor { this.saveSelection() }) + clickOutside(this, ev => { + this.__FONT__.classList.remove('fadein') + this.__COLOR__.classList.remove('fadein') + this.__LINK__.classList.remove('fadein') + }) + // 粘贴板事件 this.__pasteFn = bind(this.__EDITOR__, 'paste', ev => { ev.preventDefault()