From ada254c7adc3ef22602d728bcc7c7ab8e77a334d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=A6=8F=E6=9C=8B?= Date: Fri, 25 Jun 2021 12:25:14 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=8B=86=E5=88=86=20toolbar=20sele?= =?UTF-8?q?ctor=20=E5=92=8C=20textarea=20selector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/create-rollup-config.js | 47 ++++++---- examples/index.html | 92 ++++++++++++------- packages/basic-modules/rollup.config.js | 2 +- packages/code-highlight/rollup.config.js | 2 +- packages/core/rollup.config.js | 2 +- packages/core/src/assets/bar.less | 1 - packages/core/src/config/index.ts | 1 - packages/core/src/create-editor.ts | 51 ++++------ packages/core/src/menus/bar/Toolbar.ts | 11 ++- packages/core/src/text-area/TextArea.ts | 12 ++- packages/editor/rollup.config.js | 2 +- packages/editor/src/WangEditor.ts | 31 ++++++- packages/list-module/rollup.config.js | 2 +- packages/table-module/rollup.config.js | 2 +- packages/upload-image-module/rollup.config.js | 2 +- packages/video-module/rollup.config.js | 2 +- 16 files changed, 155 insertions(+), 107 deletions(-) diff --git a/build/create-rollup-config.js b/build/create-rollup-config.js index 0cdb91382..da905aa0f 100644 --- a/build/create-rollup-config.js +++ b/build/create-rollup-config.js @@ -9,7 +9,9 @@ import peerDepsExternal from 'rollup-plugin-peer-deps-external' import devConf from './config/dev' import prdConf from './config/prd' +// 环境变量 const ENV = process.env.NODE_ENV || 'production' +const IS_PRD = ENV === 'production' /** * 生成单个 rollup 配置 @@ -19,7 +21,7 @@ function genSingleConfig(customConfig = {}) { const { input, output = {}, plugins = [] } = customConfig let config - if (ENV === 'production') { + if (IS_PRD) { config = prdConf } else { config = devConf @@ -43,38 +45,49 @@ function genSingleConfig(customConfig = {}) { /** * 生成 rollup 配置 - * @param {string} distDir dist dir - * @param {string} name output.name - * @param {Array} plugins rollup plugins + * @param {object} opt { distDir, name, plugins, outputUmdOnDev } */ -function createRollupConfig(distDir, name, plugins = []) { - const configList = [] +function createRollupConfig(opt = {}) { + const { distDir, name, plugins = [], outputUmdOnDev = false } = opt + if (!distDir || !name) { + throw new Error(`Cannot find 'distDir' or 'name' when create rollup config`) + } - // 生成 umd 格式,对应 package.json main - const umdConf = genSingleConfig({ + // 生成 esm 格式,对应 package.json module + const esmConf = genSingleConfig({ // input - 默认为 src/index.ts output: { - file: path.resolve(distDir, 'index.js'), - format: 'umd', + file: path.resolve(distDir, 'index.mjs'), // mjs 格式 + format: 'esm', name, }, plugins, }) - configList.push(umdConf) - // 生成 esm 格式,对应 package.json module - const esmConf = genSingleConfig({ + // 生成 umd 格式,对应 package.json main + const umdConf = genSingleConfig({ // input - 默认为 src/index.ts output: { - file: path.resolve(distDir, 'index.mjs'), // mjs 格式 - format: 'esm', + file: path.resolve(distDir, 'index.js'), + format: 'umd', name, }, plugins, }) - configList.push(esmConf) - return configList + // 返回结果 + if (IS_PRD) { + // 生产环境下,全部输出 + return [esmConf, umdConf] + } else { + // 开发环境,只输出一个即可,提高打包速度 + if (outputUmdOnDev) { + // 强制输出 umd —— 某些 package 打包之后需要在浏览器中引用,如 packages/editor + return umdConf + } + // 默认输出 esm —— rollup 引用,默认只需要 mjs (对应 package.json module ) + return esmConf + } } export default createRollupConfig diff --git a/examples/index.html b/examples/index.html index 3a3d8daf2..f65e1ece5 100644 --- a/examples/index.html +++ b/examples/index.html @@ -1,50 +1,71 @@ - - - - we-2021 demo - - + #editor-toolbar { + border: 1px solid #ccc; + } + + #editor-text-area { + border: 1px solid #ccc; + } + + /* 显示内容 */ + #editor-content-view { + border-top: 1px solid #ccc; + margin-top: 30px; + } + + #editor-content-view td, + #editor-content-view th { + border: 1px solid #ccc; + min-width: 50px; + height: 20px; + } + + #editor-content-view th { + background-color: #f1f1f1; + } + + #editor-content-view blockquote { + border-left: 8px solid #d0e5f2; + padding: 10px 10px; + margin: 10px 0; + background-color: #f1f1f1; + } + + +

index page

-
+ +
+
+
+
+
+ +
+ \ No newline at end of file diff --git a/packages/basic-modules/rollup.config.js b/packages/basic-modules/rollup.config.js index c800e4f93..6c84f93de 100644 --- a/packages/basic-modules/rollup.config.js +++ b/packages/basic-modules/rollup.config.js @@ -4,6 +4,6 @@ import createRollupConfig from '../../build/create-rollup-config' const distDir = path.resolve(__dirname, './dist') const name = 'WangEditorBasicModules' -const configList = createRollupConfig(distDir, name) +const configList = createRollupConfig({ distDir, name }) export default configList diff --git a/packages/code-highlight/rollup.config.js b/packages/code-highlight/rollup.config.js index 183572d24..1964ae0a9 100644 --- a/packages/code-highlight/rollup.config.js +++ b/packages/code-highlight/rollup.config.js @@ -4,6 +4,6 @@ import createRollupConfig from '../../build/create-rollup-config' const distDir = path.resolve(__dirname, './dist') const name = 'WangEditorCodeHighLight' -const configList = createRollupConfig(distDir, name) +const configList = createRollupConfig({ distDir, name }) export default configList diff --git a/packages/core/rollup.config.js b/packages/core/rollup.config.js index 39d18bca0..616505ba8 100644 --- a/packages/core/rollup.config.js +++ b/packages/core/rollup.config.js @@ -4,6 +4,6 @@ import createRollupConfig from '../../build/create-rollup-config' const distDir = path.resolve(__dirname, './dist') const name = 'WangEditorCore' -const configList = createRollupConfig(distDir, name) +const configList = createRollupConfig({ distDir, name }) export default configList diff --git a/packages/core/src/assets/bar.less b/packages/core/src/assets/bar.less index eff5417a1..a522c0ca0 100644 --- a/packages/core/src/assets/bar.less +++ b/packages/core/src/assets/bar.less @@ -27,5 +27,4 @@ .w-e-toolbar { flex-wrap: wrap; position: relative; - border-bottom: 1px solid #F0F0F0; } \ No newline at end of file diff --git a/packages/core/src/config/index.ts b/packages/core/src/config/index.ts index 2efb5a419..027032031 100644 --- a/packages/core/src/config/index.ts +++ b/packages/core/src/config/index.ts @@ -43,7 +43,6 @@ export interface IConfig { } // 传统菜单栏的 menu - toolbarId?: string toolbarKeys?: Array // 悬浮菜单栏 menu hoverbarKeys?: Array diff --git a/packages/core/src/create-editor.ts b/packages/core/src/create-editor.ts index 423dce4e2..665f65172 100644 --- a/packages/core/src/create-editor.ts +++ b/packages/core/src/create-editor.ts @@ -3,7 +3,7 @@ * @author wangfupeng */ -import { createEditor, Node, Editor } from 'slate' +import { createEditor, Node } from 'slate' import { withHistory } from 'slate-history' import { withDOM } from './editor/with-dom' import TextArea from './text-area/TextArea' @@ -22,13 +22,12 @@ import { EDITOR_TO_HOVER_BAR, IS_READ_ONLY, } from './utils/weak-maps' -import { genRandomStr } from './utils/util' -import $ from './utils/dom' type PluginFnType = (editor: T) => T interface ICreateOption { - containerId: string + toolbarSelector?: string + textareaSelector: string config?: IConfig initContent?: Node[] plugins?: PluginFnType[] @@ -47,7 +46,7 @@ function genDefaultInitialContent() { * 创建编辑器 */ function create(option: ICreateOption) { - const { containerId, config = {}, initContent, plugins = [] } = option + const { toolbarSelector, textareaSelector, config = {}, initContent, plugins = [] } = option // 创建实例 let editor = withHistory(withDOM(createEditor())) @@ -55,49 +54,33 @@ function create(option: ICreateOption) { // 处理配置 const editorConfig = genConfig(config || {}) EDITOR_TO_CONFIG.set(editor, editorConfig) + const { toolbarKeys = [], hoverbarKeys = [] } = editorConfig // editor plugins plugins.forEach(plugin => { editor = plugin(editor) }) - // 处理 DOM - let textarea: TextArea + // 创建 textarea DOM + const textarea = new TextArea(textareaSelector) + EDITOR_TO_TEXTAREA.set(editor, textarea) + TEXTAREA_TO_EDITOR.set(textarea, editor) + + // 创建 toolbar DOM let toolbar: Toolbar | null = null - const { toolbarId, toolbarKeys = [], hoverbarKeys = [] } = editorConfig - if (toolbarId) { - // 手动指定了 toolbarId - textarea = new TextArea(containerId) - toolbar = new Toolbar(toolbarId) - } else { - // 未手动指定 toolbarId - const $container = $(`#${containerId}`) - - if (toolbarKeys.length > 0) { - // 要显示 toolbar - const newToolbarId = genRandomStr('toolbar') - const $toolbar = $( - `
` + if (toolbarSelector) { + if (toolbarKeys.length === 0) { + console.warn( + `Cannot find 'toolbarKeys' in editor config\n在 editor config 中未找到 'toolbarKeys'` ) - $container.append($toolbar) - toolbar = new Toolbar(newToolbarId) - editorConfig.toolbarId = newToolbarId } - const newContainerId = genRandomStr('text-container') - const $textContainer = $(`
`) - $textContainer.css('height', '300px') // TODO height 可配置 - $container.append($textContainer) - textarea = new TextArea(newContainerId) - } - EDITOR_TO_TEXTAREA.set(editor, textarea) - TEXTAREA_TO_EDITOR.set(textarea, editor) - if (toolbar) { + toolbar = new Toolbar(toolbarSelector) TOOLBAR_TO_EDITOR.set(toolbar, editor) EDITOR_TO_TOOLBAR.set(editor, toolbar) } - // hoverbar + // 创建 hoverbar DOM let hoverbar: HoverBar | null if (hoverbarKeys.length > 0) { hoverbar = new HoverBar() diff --git a/packages/core/src/menus/bar/Toolbar.ts b/packages/core/src/menus/bar/Toolbar.ts index e148f97b8..40d041e36 100644 --- a/packages/core/src/menus/bar/Toolbar.ts +++ b/packages/core/src/menus/bar/Toolbar.ts @@ -21,10 +21,15 @@ class Toolbar { private menus: { [key: string]: MenuType } = {} private toolbarItems: IBarItem[] = [] - constructor(toolbarId: string) { - const $toolbar = $(`#${toolbarId}`) + constructor(selector: string) { + // 初始化 DOM + const $box = $(selector) + if ($box.length === 0) { + throw new Error(`Cannot find toolbar DOM by selector '${selector}'`) + } + const $toolbar = $(`
`) $toolbar.on('mousedown', e => e.preventDefault()) - + $box.append($toolbar) this.$toolbar = $toolbar // 注册 items 。异步,否则拿不到 editor 实例 diff --git a/packages/core/src/text-area/TextArea.ts b/packages/core/src/text-area/TextArea.ts index 5b44c5403..f0384813c 100644 --- a/packages/core/src/text-area/TextArea.ts +++ b/packages/core/src/text-area/TextArea.ts @@ -24,13 +24,19 @@ class TextArea { isUpdatingSelection: boolean = false latestElement: DOMElement | null = null - constructor(textAreaContainerId: string) { + constructor(selector: string) { // id 不能重复 this.id = ID++ // 初始化 dom - const $textAreaContainer = $(`#${textAreaContainerId}`) - this.$textAreaContainer = $textAreaContainer + const $box = $(selector) + if ($box.length === 0) { + throw new Error(`Cannot find textarea DOM by selector '${selector}'`) + } + const $container = $(`
`) + $container.css('height', '300px') // TODO height 可配置 + $box.append($container) + this.$textAreaContainer = $container // 监听 selection change window.document.addEventListener('selectionchange', this.onDOMSelectionChange) diff --git a/packages/editor/rollup.config.js b/packages/editor/rollup.config.js index 579f21d0c..0b4cfd8f7 100644 --- a/packages/editor/rollup.config.js +++ b/packages/editor/rollup.config.js @@ -4,6 +4,6 @@ import createRollupConfig from '../../build/create-rollup-config' const distDir = path.resolve(__dirname, './dist') const name = 'WangEditor' -const configList = createRollupConfig(distDir, name) +const configList = createRollupConfig({ distDir, name, outputUmdOnDev: true }) export default configList diff --git a/packages/editor/src/WangEditor.ts b/packages/editor/src/WangEditor.ts index 7e91118de..723e79991 100644 --- a/packages/editor/src/WangEditor.ts +++ b/packages/editor/src/WangEditor.ts @@ -32,15 +32,30 @@ import { type PluginType = (editor: T) => T +interface IOption { + toolbarSelector?: string + textareaSelector: string + initContent?: Node[] +} + class WangEditor { // private $container: Dom7Array - private containerId: string + private toolbarSelector: string + private textareaSelector: string private initContent: Node[] config: IConfig = {} editorCore: IDomEditor | null = null // TODO 输出 editor API - constructor(containerId: string, initContent?: Node[]) { - this.containerId = containerId + constructor(opt: IOption) { + const { toolbarSelector = '', textareaSelector, initContent } = opt + if (!textareaSelector) { + throw new Error( + `Cannot find 'textareaSelector' when 'new WangEditor({...})'\n当 new WangEditor({...}) 时需要输入 'textareaSelector' ` + ) + } + + this.toolbarSelector = toolbarSelector + this.textareaSelector = textareaSelector this.initContent = initContent || [] this.config = { @@ -67,10 +82,16 @@ class WangEditor { * 创建 editorCore 实例 */ create() { - const { containerId, config, initContent } = this + const { toolbarSelector, textareaSelector, config, initContent } = this const { plugins } = WangEditor - const editorCore = createEditor({ containerId, config, initContent, plugins }) + const editorCore = createEditor({ + toolbarSelector, + textareaSelector, + config, + initContent, + plugins, + }) this.editorCore = editorCore } diff --git a/packages/list-module/rollup.config.js b/packages/list-module/rollup.config.js index 6a7a867cb..58bce80a9 100644 --- a/packages/list-module/rollup.config.js +++ b/packages/list-module/rollup.config.js @@ -4,6 +4,6 @@ import createRollupConfig from '../../build/create-rollup-config' const distDir = path.resolve(__dirname, './dist') const name = 'WangEditorListModule' -const configList = createRollupConfig(distDir, name) +const configList = createRollupConfig({ distDir, name }) export default configList diff --git a/packages/table-module/rollup.config.js b/packages/table-module/rollup.config.js index 9c299be03..112fbab47 100644 --- a/packages/table-module/rollup.config.js +++ b/packages/table-module/rollup.config.js @@ -4,6 +4,6 @@ import createRollupConfig from '../../build/create-rollup-config' const distDir = path.resolve(__dirname, './dist') const name = 'WangEditorTableModule' -const configList = createRollupConfig(distDir, name) +const configList = createRollupConfig({ distDir, name }) export default configList diff --git a/packages/upload-image-module/rollup.config.js b/packages/upload-image-module/rollup.config.js index 0656fa0a3..2e38c95c0 100644 --- a/packages/upload-image-module/rollup.config.js +++ b/packages/upload-image-module/rollup.config.js @@ -4,6 +4,6 @@ import createRollupConfig from '../../build/create-rollup-config' const distDir = path.resolve(__dirname, './dist') const name = 'WangEditorUploadImageModule' -const configList = createRollupConfig(distDir, name) +const configList = createRollupConfig({ distDir, name }) export default configList diff --git a/packages/video-module/rollup.config.js b/packages/video-module/rollup.config.js index b35f4c69c..c5ed9513b 100644 --- a/packages/video-module/rollup.config.js +++ b/packages/video-module/rollup.config.js @@ -4,6 +4,6 @@ import createRollupConfig from '../../build/create-rollup-config' const distDir = path.resolve(__dirname, './dist') const name = 'WangEditorVideoModule' -const configList = createRollupConfig(distDir, name) +const configList = createRollupConfig({ distDir, name }) export default configList