From 14003d0ba01eeb9a264d15fac514dd4b4bd89ff7 Mon Sep 17 00:00:00 2001 From: TGuoW <15768620356@163.com> Date: Mon, 3 Oct 2022 14:19:52 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=AE=BE=E7=BD=AE=20m?= =?UTF-8?q?axlength=20=E5=90=8E=E7=B2=98=E8=B4=B4=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/constants/index.ts | 12 ++++ .../core/src/editor/plugins/with-content.ts | 14 +---- .../src/editor/plugins/with-max-length.ts | 60 ++++++++++++++++++- 3 files changed, 72 insertions(+), 14 deletions(-) create mode 100644 packages/core/src/constants/index.ts diff --git a/packages/core/src/constants/index.ts b/packages/core/src/constants/index.ts new file mode 100644 index 00000000..cee25f9c --- /dev/null +++ b/packages/core/src/constants/index.ts @@ -0,0 +1,12 @@ +export const IGNORE_TAGS = new Set([ + 'doctype', + '!doctype', + 'meta', + 'script', + 'style', + 'link', + 'frame', + 'iframe', + 'title', + 'svg', // TODO 暂时忽略 +]) diff --git a/packages/core/src/editor/plugins/with-content.ts b/packages/core/src/editor/plugins/with-content.ts index 33891495..74303207 100644 --- a/packages/core/src/editor/plugins/with-content.ts +++ b/packages/core/src/editor/plugins/with-content.ts @@ -16,19 +16,7 @@ import { ElementWithId } from '../interface' import { PARSE_ELEM_HTML_CONF, TEXT_TAGS } from '../../parse-html/index' import parseElemHtml from '../../parse-html/parse-elem-html' import { htmlToContent } from '../../create/helper' - -const IGNORE_TAGS = new Set([ - 'doctype', - '!doctype', - 'meta', - 'script', - 'style', - 'link', - 'frame', - 'iframe', - 'title', - 'svg', // TODO 暂时忽略 -]) +import { IGNORE_TAGS } from '../../constants' /** * 把 elem 插入到编辑器 diff --git a/packages/core/src/editor/plugins/with-max-length.ts b/packages/core/src/editor/plugins/with-max-length.ts index a5c06785..57c8900b 100644 --- a/packages/core/src/editor/plugins/with-max-length.ts +++ b/packages/core/src/editor/plugins/with-max-length.ts @@ -7,10 +7,12 @@ import { Editor, Node } from 'slate' import { IDomEditor, DomEditor } from '../..' +import { IGNORE_TAGS } from '../../constants' +import { NodeType } from '../../utils/dom' export const withMaxLength = (editor: T) => { const e = editor as T & IDomEditor - const { insertText, insertNode, insertFragment } = e + const { insertText, insertNode, insertFragment, dangerouslyInsertHtml } = e // 处理 text e.insertText = (text: string) => { @@ -67,11 +69,67 @@ export const withMaxLength = (editor: T) => { return } + // 只有一个 node 时,使用 insertFragment ,防止换行 + if (fragment.length === 1) { + const node = fragment[0] + const leftLength = DomEditor.getLeftLengthOfMaxLength(e) + const text = Node.string(node) + + if (leftLength < text.length) { + // 已经触发 maxLength ,不再插入 + return + } + + insertFragment(fragment) + return + } // 有 maxLength ,则分别插入 node fragment.forEach(n => { e.insertNode(n) //【注意】这里必须使用 `e.insertNode` ,而不是 insertNode }) } + e.dangerouslyInsertHtml = (html: string = '', isRecursive = false) => { + if (!html) return + + const { maxLength } = e.getConfig() + if (!maxLength) { + // 无 maxLength + dangerouslyInsertHtml(html, isRecursive) + return + } + const leftLength = DomEditor.getLeftLengthOfMaxLength(e) + if (leftLength <= 0) { + // 已经触发 maxLength ,不再输入文字 + return + } + + // ------------- 把 html 转换为 DOM nodes ------------- + const div = document.createElement('div') + div.innerHTML = html + const text = Array.from(div.childNodes).reduce((acc, node) => { + const { nodeType, nodeName } = node + if (!node) { + return acc + } + // Text Node + if (nodeType === NodeType.TEXT_NODE) return acc + (node.textContent || '') + + // Element Node + if (nodeType === NodeType.ELEMENT_NODE) { + // 过滤掉忽略的 tag + if (IGNORE_TAGS.has(nodeName.toLowerCase())) return acc + else return acc + (node.textContent || '') + } + return acc + }, '') + + if (leftLength < text.length) { + return + } + + dangerouslyInsertHtml(html, isRecursive) + } + return e // 返回 editor 实例 }