From a066cea4a76fd1112465e7df132e6dcaa68ea7d2 Mon Sep 17 00:00:00 2001 From: fantasticit Date: Fri, 29 Apr 2022 11:56:44 +0800 Subject: [PATCH] tiptap: refactor utils --- .../src/components/document/editor/editor.tsx | 2 +- .../src/tiptap/extensions/attachment.ts | 4 +- .../src/tiptap/extensions/blockquote.ts | 8 +- .../src/tiptap/extensions/bullet-list.ts | 4 +- .../client/src/tiptap/extensions/callout.ts | 5 +- .../src/tiptap/extensions/code-block.ts | 6 +- packages/client/src/tiptap/extensions/code.ts | 2 +- .../cursor-plugin/index.ts | 0 .../collaboration-cursor/index.ts | 0 .../collaboration/collaboration.ts | 0 .../collaboration/helpers/is-change-origin.ts | 0 .../{ => extensions}/collaboration/index.ts | 0 .../tiptap/extensions/color-highlighter.ts | 2 +- .../client/src/tiptap/extensions/countdown.ts | 4 +- .../tiptap/extensions/document-children.ts | 4 +- .../tiptap/extensions/document-reference.ts | 4 +- .../client/src/tiptap/extensions/emoji.ts | 7 +- .../src/tiptap/extensions/html-marks.ts | 4 +- .../client/src/tiptap/extensions/iframe.ts | 4 +- .../client/src/tiptap/extensions/image.ts | 2 +- .../client/src/tiptap/extensions/indent.ts | 109 ++++-------------- .../client/src/tiptap/extensions/katex.ts | 2 +- .../client/src/tiptap/extensions/loading.ts | 2 +- .../client/src/tiptap/extensions/mention.ts | 4 +- packages/client/src/tiptap/extensions/mind.ts | 4 +- .../src/tiptap/extensions/ordered-list.ts | 3 +- .../client/src/tiptap/extensions/paste.ts | 33 ++++-- .../src/tiptap/extensions/quick-insert.tsx | 9 +- .../client/src/tiptap/extensions/selection.ts | 4 +- .../client/src/tiptap/extensions/status.ts | 4 +- .../src/tiptap/extensions/table-cell.tsx | 4 +- .../src/tiptap/extensions/table-header.tsx | 2 +- .../client/src/tiptap/extensions/task-item.ts | 4 +- .../client/src/tiptap/extensions/task-list.ts | 2 +- .../client/src/tiptap/extensions/title.tsx | 5 +- packages/client/src/tiptap/index.ts | 4 +- .../markdown-to-html/markdownItContainer.ts | 2 +- .../prosemirror-to-markdown/helpers.ts | 2 +- .../markdown/prosemirror-to-markdown/index.ts | 72 ++++++------ .../src/tiptap/menus/_components/size.tsx | 1 - .../client/src/tiptap/menus/align/index.tsx | 2 +- .../tiptap/menus/background-color/index.tsx | 2 +- .../src/tiptap/menus/blockquote/index.tsx | 2 +- .../client/src/tiptap/menus/bold/index.tsx | 2 +- .../src/tiptap/menus/bullet-list/index.tsx | 2 +- .../src/tiptap/menus/callout/bubble.tsx | 10 +- .../client/src/tiptap/menus/code/index.tsx | 2 +- .../src/tiptap/menus/countdown/bubble.tsx | 6 +- .../tiptap/menus/document-children/bubble.tsx | 4 +- .../menus/document-reference/bubble.tsx | 6 +- .../src/tiptap/menus/fontsize/index.tsx | 2 +- .../client/src/tiptap/menus/heading/index.tsx | 2 +- .../tiptap/menus/horizontal-rule/index.tsx | 2 +- .../client/src/tiptap/menus/ident/index.tsx | 2 +- .../client/src/tiptap/menus/iframe/bubble.tsx | 6 +- .../client/src/tiptap/menus/image/bubble.tsx | 8 +- .../client/src/tiptap/menus/insert/index.tsx | 3 +- .../client/src/tiptap/menus/italic/index.tsx | 2 +- .../client/src/tiptap/menus/link/bubble.tsx | 9 +- .../client/src/tiptap/menus/link/index.tsx | 2 +- .../client/src/tiptap/menus/link/modal.tsx | 2 +- .../client/src/tiptap/menus/link/service.ts | 2 +- .../client/src/tiptap/menus/mind/bubble.tsx | 8 +- .../src/tiptap/menus/ordered-list/index.tsx | 2 +- .../client/src/tiptap/menus/search/index.tsx | 2 +- .../client/src/tiptap/menus/strike/index.tsx | 2 +- .../src/tiptap/menus/subscript/index.tsx | 2 +- .../src/tiptap/menus/superscript/index.tsx | 2 +- .../client/src/tiptap/menus/table/bubble.tsx | 6 +- .../src/tiptap/menus/task-list/index.tsx | 2 +- .../src/tiptap/menus/text-color/index.tsx | 2 +- .../src/tiptap/menus/underline/index.tsx | 2 +- .../is-active.ts => prose-utils/active.ts} | 0 .../tiptap/{utils => prose-utils}/clamp.ts | 0 .../src/tiptap/{utils => prose-utils}/code.ts | 2 +- .../tiptap/{utils => prose-utils}/color.ts | 0 .../{utils => prose-utils}/delete-node.ts | 0 .../dataset.ts => prose-utils/dom-dataset.ts} | 0 .../src/tiptap/{utils => prose-utils}/dom.ts | 0 .../tiptap/{utils => prose-utils}/download.ts | 0 .../editor-container-size.ts} | 0 .../src/tiptap/{utils => prose-utils}/file.ts | 17 +++ .../client/src/tiptap/prose-utils/index.ts | 20 ++++ .../{utils => prose-utils}/lowlight-plugin.ts | 0 .../find-position.ts => prose-utils/mark.ts} | 17 +++ .../mention.ts} | 0 .../src/tiptap/{utils => prose-utils}/node.ts | 0 .../client/src/tiptap/prose-utils/position.ts | 61 ++++++++++ .../tiptap/{utils => prose-utils}/table.ts | 0 .../client/src/tiptap/prose-utils/text.ts | 16 +++ .../src/tiptap/{utils => prose-utils}/type.ts | 0 .../tiptap/{utils => prose-utils}/upload.ts | 0 .../valid-url.ts => prose-utils/url.ts} | 0 .../src/tiptap/utils/list-input-rule.ts | 21 ---- .../client/src/tiptap/utils/mark-utils.ts | 16 --- .../tiptap/wrappers/attachment/file-icon.tsx | 2 +- .../src/tiptap/wrappers/attachment/index.tsx | 3 +- .../wrappers/attachment/player/index.tsx | 2 +- .../wrappers/document-reference/index.tsx | 2 +- .../src/tiptap/wrappers/iframe/index.tsx | 2 +- .../src/tiptap/wrappers/image/index.tsx | 8 +- .../client/src/tiptap/wrappers/mind/index.tsx | 7 +- 102 files changed, 334 insertions(+), 306 deletions(-) rename packages/client/src/tiptap/{ => extensions}/collaboration-cursor/cursor-plugin/index.ts (100%) rename packages/client/src/tiptap/{ => extensions}/collaboration-cursor/index.ts (100%) rename packages/client/src/tiptap/{ => extensions}/collaboration/collaboration.ts (100%) rename packages/client/src/tiptap/{ => extensions}/collaboration/helpers/is-change-origin.ts (100%) rename packages/client/src/tiptap/{ => extensions}/collaboration/index.ts (100%) rename packages/client/src/tiptap/{utils/is-active.ts => prose-utils/active.ts} (100%) rename packages/client/src/tiptap/{utils => prose-utils}/clamp.ts (100%) rename packages/client/src/tiptap/{utils => prose-utils}/code.ts (92%) rename packages/client/src/tiptap/{utils => prose-utils}/color.ts (100%) rename packages/client/src/tiptap/{utils => prose-utils}/delete-node.ts (100%) rename packages/client/src/tiptap/{utils/dataset.ts => prose-utils/dom-dataset.ts} (100%) rename packages/client/src/tiptap/{utils => prose-utils}/dom.ts (100%) rename packages/client/src/tiptap/{utils => prose-utils}/download.ts (100%) rename packages/client/src/tiptap/{utils/editor.ts => prose-utils/editor-container-size.ts} (100%) rename packages/client/src/tiptap/{utils => prose-utils}/file.ts (79%) create mode 100644 packages/client/src/tiptap/prose-utils/index.ts rename packages/client/src/tiptap/{utils => prose-utils}/lowlight-plugin.ts (100%) rename packages/client/src/tiptap/{utils/find-position.ts => prose-utils/mark.ts} (53%) rename packages/client/src/tiptap/{utils/find-mention.ts => prose-utils/mention.ts} (100%) rename packages/client/src/tiptap/{utils => prose-utils}/node.ts (100%) create mode 100644 packages/client/src/tiptap/prose-utils/position.ts rename packages/client/src/tiptap/{utils => prose-utils}/table.ts (100%) create mode 100644 packages/client/src/tiptap/prose-utils/text.ts rename packages/client/src/tiptap/{utils => prose-utils}/type.ts (100%) rename packages/client/src/tiptap/{utils => prose-utils}/upload.ts (100%) rename packages/client/src/tiptap/{utils/valid-url.ts => prose-utils/url.ts} (100%) delete mode 100644 packages/client/src/tiptap/utils/list-input-rule.ts delete mode 100644 packages/client/src/tiptap/utils/mark-utils.ts diff --git a/packages/client/src/components/document/editor/editor.tsx b/packages/client/src/components/document/editor/editor.tsx index ca389198..21a0e9e0 100644 --- a/packages/client/src/components/document/editor/editor.tsx +++ b/packages/client/src/components/document/editor/editor.tsx @@ -18,7 +18,7 @@ import { getIndexdbProvider, destoryIndexdbProvider, } from 'tiptap'; -import { findMentions } from 'tiptap/utils/find-mention'; +import { findMentions } from 'tiptap/prose-utils'; import { useCollaborationDocument } from 'data/document'; import { DataRender } from 'components/data-render'; import { Banner } from 'components/banner'; diff --git a/packages/client/src/tiptap/extensions/attachment.ts b/packages/client/src/tiptap/extensions/attachment.ts index 74fafbaa..f23a58f6 100644 --- a/packages/client/src/tiptap/extensions/attachment.ts +++ b/packages/client/src/tiptap/extensions/attachment.ts @@ -1,7 +1,7 @@ import { Node, mergeAttributes } from '@tiptap/core'; import { ReactNodeViewRenderer } from '@tiptap/react'; -import { AttachmentWrapper } from '../wrappers/attachment'; -import { getDatasetAttribute } from '../utils/dataset'; +import { getDatasetAttribute } from 'tiptap/prose-utils'; +import { AttachmentWrapper } from 'tiptap/wrappers/attachment'; declare module '@tiptap/core' { interface Commands { diff --git a/packages/client/src/tiptap/extensions/blockquote.ts b/packages/client/src/tiptap/extensions/blockquote.ts index 561611ef..05b0157d 100644 --- a/packages/client/src/tiptap/extensions/blockquote.ts +++ b/packages/client/src/tiptap/extensions/blockquote.ts @@ -1,28 +1,24 @@ import { Blockquote as BuiltInBlockquote } from '@tiptap/extension-blockquote'; import { wrappingInputRule } from '@tiptap/core'; -import { getParents } from '../utils/dom'; -import { getMarkdownSource } from '../markdown/markdown-to-prosemirror'; +import { getParents } from 'tiptap/prose-utils'; +import { getMarkdownSource } from 'tiptap/markdown/markdown-to-prosemirror'; export const Blockquote = BuiltInBlockquote.extend({ addAttributes() { return { ...this.parent?.(), - multiline: { default: false, parseHTML: (element) => { const source = getMarkdownSource(element); const parentsIncludeBlockquote = getParents(element).some((p) => p.nodeName.toLowerCase() === 'blockquote'); - return source && !source.startsWith('>') && !parentsIncludeBlockquote; }, }, }; }, - addInputRules() { const multilineInputRegex = /^\s*>>>\s$/gm; - return [ ...this.parent?.(), wrappingInputRule({ diff --git a/packages/client/src/tiptap/extensions/bullet-list.ts b/packages/client/src/tiptap/extensions/bullet-list.ts index 2f245501..583ff579 100644 --- a/packages/client/src/tiptap/extensions/bullet-list.ts +++ b/packages/client/src/tiptap/extensions/bullet-list.ts @@ -1,16 +1,14 @@ import { BulletList as BuiltInBulletList } from '@tiptap/extension-bullet-list'; -import { getMarkdownSource } from '../markdown/markdown-to-prosemirror'; +import { getMarkdownSource } from 'tiptap/markdown/markdown-to-prosemirror'; export const BulletList = BuiltInBulletList.extend({ addAttributes() { return { ...this.parent?.(), - bullet: { default: '*', parseHTML(element) { const bullet = getMarkdownSource(element)?.charAt(0); - return '*+-'.includes(bullet) ? bullet : '*'; }, }, diff --git a/packages/client/src/tiptap/extensions/callout.ts b/packages/client/src/tiptap/extensions/callout.ts index b1f005b4..b5bfb67c 100644 --- a/packages/client/src/tiptap/extensions/callout.ts +++ b/packages/client/src/tiptap/extensions/callout.ts @@ -1,7 +1,6 @@ import { Node, mergeAttributes, wrappingInputRule } from '@tiptap/core'; import { ReactNodeViewRenderer } from '@tiptap/react'; -import { CalloutWrapper } from '../wrappers/callout'; -import { getDatasetAttribute } from '../utils/dataset'; +import { CalloutWrapper } from 'tiptap/wrappers/callout'; declare module '@tiptap/core' { interface Commands { @@ -73,7 +72,7 @@ export const Callout = Node.create({ addInputRules() { return [ wrappingInputRule({ - find: /^:::([\dA-Za-z]*) $/, + find: /^:::callout $/, type: this.type, getAttributes: (match) => { return { type: match[1] }; diff --git a/packages/client/src/tiptap/extensions/code-block.ts b/packages/client/src/tiptap/extensions/code-block.ts index e6254cf3..dadfa9a0 100644 --- a/packages/client/src/tiptap/extensions/code-block.ts +++ b/packages/client/src/tiptap/extensions/code-block.ts @@ -1,9 +1,9 @@ -import { lowlight } from 'lowlight/lib/all'; import { Node, textblockTypeInputRule, mergeAttributes } from '@tiptap/core'; import { Plugin, PluginKey, TextSelection } from 'prosemirror-state'; import { ReactNodeViewRenderer } from '@tiptap/react'; -import { LowlightPlugin } from '../utils/lowlight-plugin'; -import { CodeBlockWrapper } from '../wrappers/code-block'; +import { lowlight } from 'lowlight/lib/all'; +import { LowlightPlugin } from 'tiptap/prose-utils'; +import { CodeBlockWrapper } from 'tiptap/wrappers/code-block'; export interface CodeBlockOptions { /** diff --git a/packages/client/src/tiptap/extensions/code.ts b/packages/client/src/tiptap/extensions/code.ts index 12cfda15..097ed8bd 100644 --- a/packages/client/src/tiptap/extensions/code.ts +++ b/packages/client/src/tiptap/extensions/code.ts @@ -1,5 +1,5 @@ import BuiltInCode from '@tiptap/extension-code'; -import { EXTENSION_PRIORITY_LOWER } from '../constants'; +import { EXTENSION_PRIORITY_LOWER } from 'tiptap/constants'; export const Code = BuiltInCode.extend({ excludes: null, diff --git a/packages/client/src/tiptap/collaboration-cursor/cursor-plugin/index.ts b/packages/client/src/tiptap/extensions/collaboration-cursor/cursor-plugin/index.ts similarity index 100% rename from packages/client/src/tiptap/collaboration-cursor/cursor-plugin/index.ts rename to packages/client/src/tiptap/extensions/collaboration-cursor/cursor-plugin/index.ts diff --git a/packages/client/src/tiptap/collaboration-cursor/index.ts b/packages/client/src/tiptap/extensions/collaboration-cursor/index.ts similarity index 100% rename from packages/client/src/tiptap/collaboration-cursor/index.ts rename to packages/client/src/tiptap/extensions/collaboration-cursor/index.ts diff --git a/packages/client/src/tiptap/collaboration/collaboration.ts b/packages/client/src/tiptap/extensions/collaboration/collaboration.ts similarity index 100% rename from packages/client/src/tiptap/collaboration/collaboration.ts rename to packages/client/src/tiptap/extensions/collaboration/collaboration.ts diff --git a/packages/client/src/tiptap/collaboration/helpers/is-change-origin.ts b/packages/client/src/tiptap/extensions/collaboration/helpers/is-change-origin.ts similarity index 100% rename from packages/client/src/tiptap/collaboration/helpers/is-change-origin.ts rename to packages/client/src/tiptap/extensions/collaboration/helpers/is-change-origin.ts diff --git a/packages/client/src/tiptap/collaboration/index.ts b/packages/client/src/tiptap/extensions/collaboration/index.ts similarity index 100% rename from packages/client/src/tiptap/collaboration/index.ts rename to packages/client/src/tiptap/extensions/collaboration/index.ts diff --git a/packages/client/src/tiptap/extensions/color-highlighter.ts b/packages/client/src/tiptap/extensions/color-highlighter.ts index 200a5404..00a178f5 100644 --- a/packages/client/src/tiptap/extensions/color-highlighter.ts +++ b/packages/client/src/tiptap/extensions/color-highlighter.ts @@ -1,6 +1,6 @@ import { Extension } from '@tiptap/core'; import { Plugin } from 'prosemirror-state'; -import { findColors } from '../utils/color'; +import { findColors } from 'tiptap/prose-utils'; export const ColorHighlighter = Extension.create({ name: 'colorHighlighter', diff --git a/packages/client/src/tiptap/extensions/countdown.ts b/packages/client/src/tiptap/extensions/countdown.ts index 74366367..95e29fb2 100644 --- a/packages/client/src/tiptap/extensions/countdown.ts +++ b/packages/client/src/tiptap/extensions/countdown.ts @@ -1,7 +1,7 @@ import { Node, mergeAttributes } from '@tiptap/core'; import { ReactNodeViewRenderer } from '@tiptap/react'; -import { CountdownWrapper } from '../wrappers/countdown'; -import { getDatasetAttribute } from '../utils/dataset'; +import { CountdownWrapper } from 'tiptap/wrappers/countdown'; +import { getDatasetAttribute } from 'tiptap/prose-utils'; declare module '@tiptap/core' { interface Commands { diff --git a/packages/client/src/tiptap/extensions/document-children.ts b/packages/client/src/tiptap/extensions/document-children.ts index 28416652..f2498d41 100644 --- a/packages/client/src/tiptap/extensions/document-children.ts +++ b/packages/client/src/tiptap/extensions/document-children.ts @@ -1,7 +1,7 @@ import { Node, mergeAttributes, wrappingInputRule } from '@tiptap/core'; import { ReactNodeViewRenderer } from '@tiptap/react'; -import { DocumentChildrenWrapper } from '../wrappers/document-children'; -import { getDatasetAttribute } from '../utils/dataset'; +import { DocumentChildrenWrapper } from 'tiptap/wrappers/document-children'; +import { getDatasetAttribute } from 'tiptap/prose-utils'; declare module '@tiptap/core' { interface Commands { diff --git a/packages/client/src/tiptap/extensions/document-reference.ts b/packages/client/src/tiptap/extensions/document-reference.ts index 6d01c781..9ea65d77 100644 --- a/packages/client/src/tiptap/extensions/document-reference.ts +++ b/packages/client/src/tiptap/extensions/document-reference.ts @@ -1,7 +1,7 @@ import { Node, mergeAttributes, wrappingInputRule } from '@tiptap/core'; import { ReactNodeViewRenderer } from '@tiptap/react'; -import { DocumentReferenceWrapper } from '../wrappers/document-reference'; -import { getDatasetAttribute } from '../utils/dataset'; +import { DocumentReferenceWrapper } from 'tiptap/wrappers/document-reference'; +import { getDatasetAttribute } from 'tiptap/prose-utils'; declare module '@tiptap/core' { interface Commands { diff --git a/packages/client/src/tiptap/extensions/emoji.ts b/packages/client/src/tiptap/extensions/emoji.ts index dea6263d..4e46af3a 100644 --- a/packages/client/src/tiptap/extensions/emoji.ts +++ b/packages/client/src/tiptap/extensions/emoji.ts @@ -1,12 +1,11 @@ -import { Node, findParentNode } from '@tiptap/core'; +import { Node } from '@tiptap/core'; import { ReactRenderer } from '@tiptap/react'; import { Plugin, PluginKey } from 'prosemirror-state'; -import { Decoration, DecorationSet } from 'prosemirror-view'; import Suggestion from '@tiptap/suggestion'; import tippy from 'tippy.js'; import { EXTENSION_PRIORITY_HIGHEST } from 'tiptap/constants'; -import { EmojiList } from '../wrappers/emoji-list'; -import { emojiSearch, emojisToName } from '../wrappers/emoji-list/emojis'; +import { EmojiList } from 'tiptap/wrappers/emoji-list'; +import { emojiSearch, emojisToName } from 'tiptap/wrappers/emoji-list/emojis'; declare module '@tiptap/core' { interface Commands { diff --git a/packages/client/src/tiptap/extensions/html-marks.ts b/packages/client/src/tiptap/extensions/html-marks.ts index e56292fc..5ed3c868 100644 --- a/packages/client/src/tiptap/extensions/html-marks.ts +++ b/packages/client/src/tiptap/extensions/html-marks.ts @@ -1,6 +1,6 @@ import { Mark, mergeAttributes, markInputRule } from '@tiptap/core'; -import { PARSE_HTML_PRIORITY_LOWEST } from '../constants'; -import { markInputRegex, extractMarkAttributesFromMatch } from '../utils/mark-utils'; +import { PARSE_HTML_PRIORITY_LOWEST } from 'tiptap/constants'; +import { markInputRegex, extractMarkAttributesFromMatch } from 'tiptap/prose-utils'; export const marks = [{ name: 'underline', tag: 'u' }]; diff --git a/packages/client/src/tiptap/extensions/iframe.ts b/packages/client/src/tiptap/extensions/iframe.ts index 4892b56e..9fc37937 100644 --- a/packages/client/src/tiptap/extensions/iframe.ts +++ b/packages/client/src/tiptap/extensions/iframe.ts @@ -1,7 +1,7 @@ import { Node, mergeAttributes } from '@tiptap/core'; import { ReactNodeViewRenderer } from '@tiptap/react'; -import { IframeWrapper } from '../wrappers/iframe'; -import { getDatasetAttribute } from '../utils/dataset'; +import { IframeWrapper } from 'tiptap/wrappers/iframe'; +import { getDatasetAttribute } from 'tiptap/prose-utils'; declare module '@tiptap/core' { interface Commands { diff --git a/packages/client/src/tiptap/extensions/image.ts b/packages/client/src/tiptap/extensions/image.ts index 84dffad3..c3721553 100644 --- a/packages/client/src/tiptap/extensions/image.ts +++ b/packages/client/src/tiptap/extensions/image.ts @@ -1,6 +1,6 @@ import { Image as BuiltInImage } from '@tiptap/extension-image'; import { ReactNodeViewRenderer } from '@tiptap/react'; -import { ImageWrapper } from '../wrappers/image'; +import { ImageWrapper } from 'tiptap/wrappers/image'; const resolveImageEl = (element) => (element.nodeName === 'IMG' ? element : element.querySelector('img')); diff --git a/packages/client/src/tiptap/extensions/indent.ts b/packages/client/src/tiptap/extensions/indent.ts index 13c5156e..9423f804 100644 --- a/packages/client/src/tiptap/extensions/indent.ts +++ b/packages/client/src/tiptap/extensions/indent.ts @@ -1,16 +1,7 @@ import { Command, Extension } from '@tiptap/core'; import { sinkListItem, liftListItem } from 'prosemirror-schema-list'; import { TextSelection, AllSelection, Transaction } from 'prosemirror-state'; -import { isListActive } from '../utils/is-active'; -import { clamp } from '../utils/clamp'; -import { getNodeType } from '../utils/type'; -import { isListNode } from '../utils/node'; - -type IndentOptions = { - types: string[]; - indentLevels: number[]; - defaultIndentLevel: number; -}; +import { isListActive, getNodeType } from 'tiptap/prose-utils'; declare module '@tiptap/core' { interface Commands { @@ -21,35 +12,12 @@ declare module '@tiptap/core' { } } -export enum IndentProps { - min = 0, - max = 210, - more = 30, - less = -30, -} +export type Options = { + type: 'space' | 'tab'; + size: number; +}; -function setNodeIndentMarkup(tr: Transaction, pos: number, delta: number): Transaction { - if (!tr.doc) return tr; - - const node = tr.doc.nodeAt(pos); - if (!node) return tr; - - const minIndent = IndentProps.min; - const maxIndent = IndentProps.max; - - const indent = clamp((node.attrs.indent || 0) + delta, minIndent, maxIndent); - - if (indent === node.attrs.indent) return tr; - - const nodeAttrs = { - ...node.attrs, - indent, - }; - - return tr.setNodeMarkup(pos, node.type, nodeAttrs, node.marks); -} - -function updateIndentLevel(tr: Transaction, delta: number): Transaction { +const updateIndent = (tr: Transaction, options: Options): Transaction => { const { doc, selection } = tr; if (!doc || !selection) return tr; @@ -58,50 +26,23 @@ function updateIndentLevel(tr: Transaction, delta: number): Transaction { return tr; } - const { from, to } = selection; + const { to } = selection; - doc.nodesBetween(from, to, (node, pos) => { - const nodeType = node.type; + const text = options.type === 'space' ? Array(options.size).fill(' ').join('') : '\t'; - if (nodeType.name === 'paragraph' || nodeType.name === 'heading') { - tr = setNodeIndentMarkup(tr, pos, delta); - return false; - } - if (isListNode(node)) { - return false; - } - return true; - }); + return tr.insertText(text, to); +}; - return tr; -} - -export const Indent = Extension.create({ +export const Indent = Extension.create({ name: 'indent', addOptions() { - return { - types: ['heading', 'paragraph'], - indentLevels: [0, 30, 60, 90, 120, 150, 180, 210], - defaultIndentLevel: 0, + const options: Options = { + type: 'space', + size: 2, }; - }, - addGlobalAttributes() { - return [ - { - types: this.options.types, - attributes: { - indent: { - default: this.options.defaultIndentLevel, - renderHTML: (attributes) => ({ - style: `margin-left: ${attributes.indent}px!important;`, - }), - parseHTML: (element) => parseInt(element.style.marginLeft) || this.options.defaultIndentLevel, - }, - }, - }, - ]; + return options; }, addCommands() { @@ -115,15 +56,11 @@ export const Indent = Extension.create({ return sinkListItem(type)(state, dispatch); } - const { selection } = state; - tr = tr.setSelection(selection); - tr = updateIndentLevel(tr, IndentProps.more); - - if (tr.docChanged) { - dispatch && dispatch(tr); + const _tr = updateIndent(tr, this.options); + if (_tr.docChanged) { + dispatch?.(_tr); return true; } - return false; }, outdent: @@ -135,15 +72,11 @@ export const Indent = Extension.create({ return liftListItem(type)(state, dispatch); } - const { selection } = state; - tr = tr.setSelection(selection); - tr = updateIndentLevel(tr, IndentProps.less); - - if (tr.docChanged) { - dispatch && dispatch(tr); + const _tr = updateIndent(tr, this.options); + if (_tr.docChanged) { + dispatch?.(_tr); return true; } - return false; }, }; diff --git a/packages/client/src/tiptap/extensions/katex.ts b/packages/client/src/tiptap/extensions/katex.ts index bab1373d..06f74b40 100644 --- a/packages/client/src/tiptap/extensions/katex.ts +++ b/packages/client/src/tiptap/extensions/katex.ts @@ -1,6 +1,6 @@ import { Node, mergeAttributes, nodeInputRule } from '@tiptap/core'; import { ReactNodeViewRenderer } from '@tiptap/react'; -import { KatexWrapper } from '../wrappers/katex'; +import { KatexWrapper } from 'tiptap/wrappers/katex'; type IKatexAttrs = { text?: string; diff --git a/packages/client/src/tiptap/extensions/loading.ts b/packages/client/src/tiptap/extensions/loading.ts index 4707fe64..6edaafb2 100644 --- a/packages/client/src/tiptap/extensions/loading.ts +++ b/packages/client/src/tiptap/extensions/loading.ts @@ -1,6 +1,6 @@ import { Node } from '@tiptap/core'; import { ReactNodeViewRenderer } from '@tiptap/react'; -import { LoadingWrapper } from '../wrappers/loading'; +import { LoadingWrapper } from 'tiptap/wrappers/loading'; export const Loading = Node.create({ name: 'loading', diff --git a/packages/client/src/tiptap/extensions/mention.ts b/packages/client/src/tiptap/extensions/mention.ts index bf9b9bef..e4af7f9a 100644 --- a/packages/client/src/tiptap/extensions/mention.ts +++ b/packages/client/src/tiptap/extensions/mention.ts @@ -2,8 +2,8 @@ import BulitInMention from '@tiptap/extension-mention'; import { ReactRenderer } from '@tiptap/react'; import tippy from 'tippy.js'; import { getUsers } from 'services/user'; -import { getDatasetAttribute } from '../utils/dataset'; -import { MentionList } from '../wrappers/mention-list'; +import { getDatasetAttribute } from 'tiptap/prose-utils'; +import { MentionList } from 'tiptap/wrappers/mention-list'; const suggestion = { items: async ({ query }) => { diff --git a/packages/client/src/tiptap/extensions/mind.ts b/packages/client/src/tiptap/extensions/mind.ts index 0e37dd46..7466e537 100644 --- a/packages/client/src/tiptap/extensions/mind.ts +++ b/packages/client/src/tiptap/extensions/mind.ts @@ -1,7 +1,7 @@ import { Node, mergeAttributes, nodeInputRule } from '@tiptap/core'; import { ReactNodeViewRenderer } from '@tiptap/react'; -import { MindWrapper } from '../wrappers/mind'; -import { getDatasetAttribute } from '../utils/dataset'; +import { MindWrapper } from 'tiptap/wrappers/mind'; +import { getDatasetAttribute } from 'tiptap/prose-utils'; const DEFAULT_MIND_DATA = { root: { data: { text: '中心节点' }, children: [] }, diff --git a/packages/client/src/tiptap/extensions/ordered-list.ts b/packages/client/src/tiptap/extensions/ordered-list.ts index 9b5fea25..8fe72ca9 100644 --- a/packages/client/src/tiptap/extensions/ordered-list.ts +++ b/packages/client/src/tiptap/extensions/ordered-list.ts @@ -1,11 +1,10 @@ import { OrderedList as BuiltInOrderedList } from '@tiptap/extension-ordered-list'; -import { getMarkdownSource } from '../markdown/markdown-to-prosemirror'; +import { getMarkdownSource } from 'tiptap/markdown/markdown-to-prosemirror'; export const OrderedList = BuiltInOrderedList.extend({ addAttributes() { return { ...this.parent?.(), - parens: { default: false, parseHTML: (element) => /^[0-9]+\)/.test(getMarkdownSource(element)), diff --git a/packages/client/src/tiptap/extensions/paste.ts b/packages/client/src/tiptap/extensions/paste.ts index b8edc9ee..e29bd772 100644 --- a/packages/client/src/tiptap/extensions/paste.ts +++ b/packages/client/src/tiptap/extensions/paste.ts @@ -1,15 +1,29 @@ import { Extension } from '@tiptap/core'; import { Plugin, PluginKey } from 'prosemirror-state'; -import { EXTENSION_PRIORITY_HIGHEST } from '../constants'; -import { handleFileEvent } from '../utils/upload'; -import { isInCode, LANGUAGES } from '../utils/code'; +import { EXTENSION_PRIORITY_HIGHEST } from 'tiptap/constants'; +import { handleFileEvent, isInCode, LANGUAGES, isTitleNode } from 'tiptap/prose-utils'; import { isMarkdown, normalizePastedMarkdown, markdownToProsemirror, prosemirrorToMarkdown, -} from '../markdown/markdown-to-prosemirror'; -import { isTitleNode } from '../utils/node'; +} from 'tiptap/markdown/markdown-to-prosemirror'; + +const isPureText = (content): boolean => { + if (!content) return false; + + if (Array.isArray(content)) { + if (content.length > 1) return false; + return isPureText(content[0]); + } + + const child = content['content']; + if (child) { + return isPureText(child); + } + + return content['type'] === 'text'; +}; export const Paste = Extension.create({ name: 'paste', @@ -25,6 +39,7 @@ export const Paste = Extension.create({ if (view.props.editable && !view.props.editable(view.state)) { return false; } + if (!event.clipboardData) return false; const files = Array.from(event.clipboardData.files); @@ -116,16 +131,18 @@ export const Paste = Extension.create({ return false; }, clipboardTextSerializer: (slice) => { - const doc = slice.content; + const isText = isPureText(slice.content.toJSON()); + if (isText) { + return slice.content.textBetween(0, slice.content.size, '\n\n'); + } + const doc = slice.content; if (!doc) { return ''; } - const content = prosemirrorToMarkdown({ content: doc, }); - return content; }, }, diff --git a/packages/client/src/tiptap/extensions/quick-insert.tsx b/packages/client/src/tiptap/extensions/quick-insert.tsx index 695f4928..edb1131d 100644 --- a/packages/client/src/tiptap/extensions/quick-insert.tsx +++ b/packages/client/src/tiptap/extensions/quick-insert.tsx @@ -1,11 +1,10 @@ -import { Node, findParentNode } from '@tiptap/core'; +import tippy from 'tippy.js'; +import { Node } from '@tiptap/core'; import { ReactRenderer } from '@tiptap/react'; import { Plugin, PluginKey } from 'prosemirror-state'; -import { Decoration, DecorationSet } from 'prosemirror-view'; import Suggestion from '@tiptap/suggestion'; -import tippy from 'tippy.js'; -import { MenuList } from '../wrappers/menu-list'; -import { QUICK_INSERT_ITEMS } from '../menus/quick-insert'; +import { MenuList } from 'tiptap/wrappers/menu-list'; +import { QUICK_INSERT_ITEMS } from 'tiptap/menus/quick-insert'; import { EXTENSION_PRIORITY_HIGHEST } from 'tiptap/constants'; export const QuickInsertPluginKey = new PluginKey('quickInsert'); diff --git a/packages/client/src/tiptap/extensions/selection.ts b/packages/client/src/tiptap/extensions/selection.ts index 474b5068..703cf199 100644 --- a/packages/client/src/tiptap/extensions/selection.ts +++ b/packages/client/src/tiptap/extensions/selection.ts @@ -1,8 +1,8 @@ import { Extension } from '@tiptap/core'; import { Plugin, PluginKey, NodeSelection, TextSelection, Selection, AllSelection } from 'prosemirror-state'; import { Decoration, DecorationSet } from 'prosemirror-view'; -import { getCurrentNode, isInCodeBlock, isInCallout } from '../utils/node'; -import { EXTENSION_PRIORITY_HIGHEST } from '../constants'; +import { getCurrentNode, isInCodeBlock, isInCallout } from 'tiptap/prose-utils'; +import { EXTENSION_PRIORITY_HIGHEST } from 'tiptap/constants'; export const selectionPluginKey = new PluginKey('selection'); diff --git a/packages/client/src/tiptap/extensions/status.ts b/packages/client/src/tiptap/extensions/status.ts index 9c115088..9e02fb2e 100644 --- a/packages/client/src/tiptap/extensions/status.ts +++ b/packages/client/src/tiptap/extensions/status.ts @@ -1,7 +1,7 @@ import { Node, mergeAttributes } from '@tiptap/core'; import { ReactNodeViewRenderer } from '@tiptap/react'; -import { StatusWrapper } from '../wrappers/status'; -import { getDatasetAttribute } from '../utils/dataset'; +import { StatusWrapper } from 'tiptap/wrappers/status'; +import { getDatasetAttribute } from 'tiptap/prose-utils'; type IStatusAttrs = { color?: string; diff --git a/packages/client/src/tiptap/extensions/table-cell.tsx b/packages/client/src/tiptap/extensions/table-cell.tsx index 1ead13d5..21c08d0f 100644 --- a/packages/client/src/tiptap/extensions/table-cell.tsx +++ b/packages/client/src/tiptap/extensions/table-cell.tsx @@ -13,8 +13,8 @@ import { isTableSelected, selectRow, selectTable, -} from '../utils/table'; -import { FloatMenuView } from '../views/float-menu'; +} from 'tiptap/prose-utils'; +import { FloatMenuView } from 'tiptap/views/float-menu'; export const TableCell = BuiltInTableCell.extend({ addAttributes() { diff --git a/packages/client/src/tiptap/extensions/table-header.tsx b/packages/client/src/tiptap/extensions/table-header.tsx index 28e5716c..2f7e87da 100644 --- a/packages/client/src/tiptap/extensions/table-header.tsx +++ b/packages/client/src/tiptap/extensions/table-header.tsx @@ -6,7 +6,7 @@ import { IconDelete, IconPlus } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; import { Plugin, PluginKey } from 'prosemirror-state'; import { Decoration, DecorationSet } from 'prosemirror-view'; -import { getCellsInRow, isColumnSelected, isTableSelected, selectColumn } from '../utils/table'; +import { getCellsInRow, isColumnSelected, isTableSelected, selectColumn } from 'tiptap/prose-utils'; import { FloatMenuView } from '../views/float-menu'; export const TableHeader = BuiltInTableHeader.extend({ diff --git a/packages/client/src/tiptap/extensions/task-item.ts b/packages/client/src/tiptap/extensions/task-item.ts index ec5d8285..1915b7cf 100644 --- a/packages/client/src/tiptap/extensions/task-item.ts +++ b/packages/client/src/tiptap/extensions/task-item.ts @@ -1,10 +1,8 @@ import { wrappingInputRule } from '@tiptap/core'; -import { ReactNodeViewRenderer } from '@tiptap/react'; import { TaskItem as BuiltInTaskItem } from '@tiptap/extension-task-item'; import { Plugin } from 'prosemirror-state'; import { findParentNodeClosestToPos } from 'prosemirror-utils'; -import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants'; -import { TaskItemWrapper } from '../wrappers/task-item'; +import { PARSE_HTML_PRIORITY_HIGHEST } from 'tiptap/constants'; const CustomTaskItem = BuiltInTaskItem.extend({ parseHTML() { diff --git a/packages/client/src/tiptap/extensions/task-list.ts b/packages/client/src/tiptap/extensions/task-list.ts index 2233788e..dedb4e99 100644 --- a/packages/client/src/tiptap/extensions/task-list.ts +++ b/packages/client/src/tiptap/extensions/task-list.ts @@ -1,5 +1,5 @@ import { TaskList as BuiltInTaskList } from '@tiptap/extension-task-list'; -import { PARSE_HTML_PRIORITY_HIGHEST } from '../constants'; +import { PARSE_HTML_PRIORITY_HIGHEST } from 'tiptap/constants'; export const TaskList = BuiltInTaskList.extend({ parseHTML() { diff --git a/packages/client/src/tiptap/extensions/title.tsx b/packages/client/src/tiptap/extensions/title.tsx index 71e2c917..17127c0f 100644 --- a/packages/client/src/tiptap/extensions/title.tsx +++ b/packages/client/src/tiptap/extensions/title.tsx @@ -1,7 +1,6 @@ import { Node, mergeAttributes } from '@tiptap/core'; -import { Plugin, PluginKey } from 'prosemirror-state'; -import { isInTitle } from '../utils/node'; -import { TextSelection } from 'prosemirror-state'; +import { Plugin, PluginKey, TextSelection } from 'prosemirror-state'; +import { isInTitle } from 'tiptap/prose-utils'; export interface TitleOptions { HTMLAttributes: Record; diff --git a/packages/client/src/tiptap/index.ts b/packages/client/src/tiptap/index.ts index 3ff1a2c4..579a6142 100644 --- a/packages/client/src/tiptap/index.ts +++ b/packages/client/src/tiptap/index.ts @@ -1,6 +1,6 @@ import { HocuspocusProvider } from '@hocuspocus/provider'; -import { Collaboration } from './collaboration'; -import { CollaborationCursor } from './collaboration-cursor'; +import { Collaboration } from './extensions/collaboration'; +import { CollaborationCursor } from './extensions/collaboration-cursor'; import History from '@tiptap/extension-history'; import { getRandomColor } from 'helpers/color'; import { Document } from './extensions/document'; diff --git a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownItContainer.ts b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownItContainer.ts index a81bdd11..f98493aa 100644 --- a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownItContainer.ts +++ b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownItContainer.ts @@ -1,5 +1,5 @@ import container from 'markdown-it-container'; -import { strToJSON, jsonToDOMDataset } from '../../../utils/dataset'; +import { strToJSON, jsonToDOMDataset } from 'tiptap/prose-utils'; export const createMarkdownContainer = (types: string | Array) => (md) => { if (!Array.isArray(types)) { diff --git a/packages/client/src/tiptap/markdown/prosemirror-to-markdown/helpers.ts b/packages/client/src/tiptap/markdown/prosemirror-to-markdown/helpers.ts index e2e8750f..c40548dc 100644 --- a/packages/client/src/tiptap/markdown/prosemirror-to-markdown/helpers.ts +++ b/packages/client/src/tiptap/markdown/prosemirror-to-markdown/helpers.ts @@ -1,4 +1,4 @@ -import { jsonToStr } from '../../utils/dataset'; +import { jsonToStr } from 'tiptap/prose-utils'; const uniq = (arr: string[]) => [...new Set(arr)]; diff --git a/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts b/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts index 59017622..46b82ee3 100644 --- a/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts +++ b/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts @@ -1,40 +1,40 @@ import { MarkdownSerializer as ProseMirrorMarkdownSerializer, defaultMarkdownSerializer } from 'prosemirror-markdown'; -import { Attachment } from '../../extensions/attachment'; -import { Bold } from '../../extensions/bold'; -import { BulletList } from '../../extensions/bullet-list'; -import { Callout } from '../../extensions/callout'; -import { Code } from '../../extensions/code'; -import { CodeBlock } from '../../extensions/code-block'; -import { Countdown } from '../../extensions/countdown'; -import { DocumentChildren } from '../../extensions/document-children'; -import { DocumentReference } from '../../extensions/document-reference'; -import { HardBreak } from '../../extensions/hard-break'; -import { Heading } from '../../extensions/heading'; -import { HorizontalRule } from '../../extensions/horizontal-rule'; -import { marks } from '../../extensions/html-marks'; -import { Mention } from '../../extensions/mention'; -import { Iframe } from '../../extensions/iframe'; -import { Image } from '../../extensions/image'; -import { Italic } from '../../extensions/italic'; -import { Katex } from '../../extensions/katex'; -import { Link } from '../../extensions/link'; -import { ListItem } from '../../extensions/listItem'; -import { Mind } from '../../extensions/mind'; -import { OrderedList } from '../../extensions/ordered-list'; -import { Paragraph } from '../../extensions/paragraph'; -import { Status } from '../../extensions/status'; -import { Strike } from '../../extensions/strike'; -import { Subscript } from '../../extensions/subscript'; -import { Superscript } from '../../extensions/superscript'; -import { Table } from '../../extensions/table'; -import { TableCell } from '../../extensions/table-cell'; -import { TableHeader } from '../../extensions/table-header'; -import { TableRow } from '../../extensions/table-row'; -import { Text } from '../../extensions/text'; -import { TaskItem } from '../../extensions/task-item'; -import { TaskList } from '../../extensions/task-list'; -import { TextStyle } from '../../extensions/text-style'; -import { Title } from '../../extensions/title'; +import { Attachment } from 'tiptap/extensions/attachment'; +import { Bold } from 'tiptap/extensions/bold'; +import { BulletList } from 'tiptap/extensions/bullet-list'; +import { Callout } from 'tiptap/extensions/callout'; +import { Code } from 'tiptap/extensions/code'; +import { CodeBlock } from 'tiptap/extensions/code-block'; +import { Countdown } from 'tiptap/extensions/countdown'; +import { DocumentChildren } from 'tiptap/extensions/document-children'; +import { DocumentReference } from 'tiptap/extensions/document-reference'; +import { HardBreak } from 'tiptap/extensions/hard-break'; +import { Heading } from 'tiptap/extensions/heading'; +import { HorizontalRule } from 'tiptap/extensions/horizontal-rule'; +import { marks } from 'tiptap/extensions/html-marks'; +import { Mention } from 'tiptap/extensions/mention'; +import { Iframe } from 'tiptap/extensions/iframe'; +import { Image } from 'tiptap/extensions/image'; +import { Italic } from 'tiptap/extensions/italic'; +import { Katex } from 'tiptap/extensions/katex'; +import { Link } from 'tiptap/extensions/link'; +import { ListItem } from 'tiptap/extensions/listItem'; +import { Mind } from 'tiptap/extensions/mind'; +import { OrderedList } from 'tiptap/extensions/ordered-list'; +import { Paragraph } from 'tiptap/extensions/paragraph'; +import { Status } from 'tiptap/extensions/status'; +import { Strike } from 'tiptap/extensions/strike'; +import { Subscript } from 'tiptap/extensions/subscript'; +import { Superscript } from 'tiptap/extensions/superscript'; +import { Table } from 'tiptap/extensions/table'; +import { TableCell } from 'tiptap/extensions/table-cell'; +import { TableHeader } from 'tiptap/extensions/table-header'; +import { TableRow } from 'tiptap/extensions/table-row'; +import { Text } from 'tiptap/extensions/text'; +import { TaskItem } from 'tiptap/extensions/task-item'; +import { TaskList } from 'tiptap/extensions/task-list'; +import { TextStyle } from 'tiptap/extensions/text-style'; +import { Title } from 'tiptap/extensions/title'; import { isPlainURL, renderHardBreak, diff --git a/packages/client/src/tiptap/menus/_components/size.tsx b/packages/client/src/tiptap/menus/_components/size.tsx index 499c428e..ccd14219 100644 --- a/packages/client/src/tiptap/menus/_components/size.tsx +++ b/packages/client/src/tiptap/menus/_components/size.tsx @@ -1,7 +1,6 @@ import { useCallback, useRef } from 'react'; import { Button, Form, Dropdown } from '@douyinfe/semi-ui'; import { FormApi } from '@douyinfe/semi-ui/lib/es/form'; -import { number } from 'lib0'; type ISize = { width: number; height: number }; diff --git a/packages/client/src/tiptap/menus/align/index.tsx b/packages/client/src/tiptap/menus/align/index.tsx index 44eb2c2c..f3ee85a5 100644 --- a/packages/client/src/tiptap/menus/align/index.tsx +++ b/packages/client/src/tiptap/menus/align/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Editor } from '@tiptap/core'; import { Button, Dropdown, Tooltip } from '@douyinfe/semi-ui'; import { IconAlignLeft, IconAlignCenter, IconAlignRight, IconAlignJustify } from '@douyinfe/semi-icons'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const Align: React.FC<{ editor: Editor }> = ({ editor }) => { const current = (() => { diff --git a/packages/client/src/tiptap/menus/background-color/index.tsx b/packages/client/src/tiptap/menus/background-color/index.tsx index bad757a6..3246012a 100644 --- a/packages/client/src/tiptap/menus/background-color/index.tsx +++ b/packages/client/src/tiptap/menus/background-color/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { IconMark } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; import { ColorPicker } from '../_components/color-picker'; export const BackgroundColor: React.FC<{ editor: Editor }> = ({ editor }) => { diff --git a/packages/client/src/tiptap/menus/blockquote/index.tsx b/packages/client/src/tiptap/menus/blockquote/index.tsx index 9ad0a16a..b242320c 100644 --- a/packages/client/src/tiptap/menus/blockquote/index.tsx +++ b/packages/client/src/tiptap/menus/blockquote/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { Tooltip } from 'components/tooltip'; import { IconQuote } from 'components/icons'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const Blockquote: React.FC<{ editor: Editor }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/menus/bold/index.tsx b/packages/client/src/tiptap/menus/bold/index.tsx index 19ca782d..6c10c658 100644 --- a/packages/client/src/tiptap/menus/bold/index.tsx +++ b/packages/client/src/tiptap/menus/bold/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { IconBold } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const Bold: React.FC<{ editor: Editor }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/menus/bullet-list/index.tsx b/packages/client/src/tiptap/menus/bullet-list/index.tsx index 59b67f5c..7a962a64 100644 --- a/packages/client/src/tiptap/menus/bullet-list/index.tsx +++ b/packages/client/src/tiptap/menus/bullet-list/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { IconList } from 'components/icons'; import { Tooltip } from 'components/tooltip'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const BulletList: React.FC<{ editor: Editor }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/menus/callout/bubble.tsx b/packages/client/src/tiptap/menus/callout/bubble.tsx index c9b569da..eff1e6e8 100644 --- a/packages/client/src/tiptap/menus/callout/bubble.tsx +++ b/packages/client/src/tiptap/menus/callout/bubble.tsx @@ -1,14 +1,14 @@ +import { useCallback } from 'react'; import { Editor } from '@tiptap/core'; import { Space, Button, Popover, Typography } from '@douyinfe/semi-ui'; import { IconDelete } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; import { IconDrawBoard } from 'components/icons'; -import { BubbleMenu } from '../../views/bubble-menu'; -import { Divider } from '../../divider'; -import { Callout } from '../../extensions/callout'; -import { deleteNode } from '../../utils/delete-node'; +import { BubbleMenu } from 'tiptap/views/bubble-menu'; +import { Divider } from 'tiptap/divider'; +import { Callout } from 'tiptap/extensions/callout'; +import { deleteNode } from 'tiptap/prose-utils'; import styles from './bubble.module.scss'; -import { useCallback } from 'react'; const { Text } = Typography; diff --git a/packages/client/src/tiptap/menus/code/index.tsx b/packages/client/src/tiptap/menus/code/index.tsx index 2c2c61db..e8d046dc 100644 --- a/packages/client/src/tiptap/menus/code/index.tsx +++ b/packages/client/src/tiptap/menus/code/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { IconCode } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const Code: React.FC<{ editor: Editor }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/menus/countdown/bubble.tsx b/packages/client/src/tiptap/menus/countdown/bubble.tsx index aba3cee6..d41b6698 100644 --- a/packages/client/src/tiptap/menus/countdown/bubble.tsx +++ b/packages/client/src/tiptap/menus/countdown/bubble.tsx @@ -2,9 +2,9 @@ import { useCallback } from 'react'; import { Space, Button } from '@douyinfe/semi-ui'; import { IconEdit, IconDelete } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { BubbleMenu } from '../../views/bubble-menu'; -import { Countdown } from '../../extensions/countdown'; -import { Divider } from '../../divider'; +import { BubbleMenu } from 'tiptap/views/bubble-menu'; +import { Countdown } from 'tiptap/extensions/countdown'; +import { Divider } from 'tiptap/divider'; import { triggerOpenCountSettingModal } from '../_event'; export const CountdownBubbleMenu = ({ editor }) => { diff --git a/packages/client/src/tiptap/menus/document-children/bubble.tsx b/packages/client/src/tiptap/menus/document-children/bubble.tsx index 03f01896..0b27b334 100644 --- a/packages/client/src/tiptap/menus/document-children/bubble.tsx +++ b/packages/client/src/tiptap/menus/document-children/bubble.tsx @@ -2,8 +2,8 @@ import { useCallback } from 'react'; import { Space, Button } from '@douyinfe/semi-ui'; import { IconDelete } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { BubbleMenu } from '../../views/bubble-menu'; -import { DocumentChildren } from '../../extensions/document-children'; +import { BubbleMenu } from 'tiptap/views/bubble-menu'; +import { DocumentChildren } from 'tiptap/extensions/document-children'; export const DocumentChildrenBubbleMenu = ({ editor }) => { const deleteNode = useCallback(() => editor.chain().deleteSelection().run(), [editor]); diff --git a/packages/client/src/tiptap/menus/document-reference/bubble.tsx b/packages/client/src/tiptap/menus/document-reference/bubble.tsx index 79ea047b..61203cc0 100644 --- a/packages/client/src/tiptap/menus/document-reference/bubble.tsx +++ b/packages/client/src/tiptap/menus/document-reference/bubble.tsx @@ -6,9 +6,9 @@ import { Tooltip } from 'components/tooltip'; import { DataRender } from 'components/data-render'; import { IconDocument } from 'components/icons'; import { useWikiTocs } from 'data/wiki'; -import { BubbleMenu } from '../../views/bubble-menu'; -import { DocumentReference } from '../../extensions/document-reference'; -import { Divider } from '../../divider'; +import { BubbleMenu } from 'tiptap/views/bubble-menu'; +import { DocumentReference } from 'tiptap/extensions/document-reference'; +import { Divider } from 'tiptap/divider'; const { Text } = Typography; diff --git a/packages/client/src/tiptap/menus/fontsize/index.tsx b/packages/client/src/tiptap/menus/fontsize/index.tsx index ae9bddc2..e391238a 100644 --- a/packages/client/src/tiptap/menus/fontsize/index.tsx +++ b/packages/client/src/tiptap/menus/fontsize/index.tsx @@ -1,7 +1,7 @@ import React, { useCallback } from 'react'; import { Select } from '@douyinfe/semi-ui'; import { Editor } from '@tiptap/core'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const FONT_SIZES = [12, 13, 14, 15, 16, 19, 22, 24, 29, 32, 40, 48]; diff --git a/packages/client/src/tiptap/menus/heading/index.tsx b/packages/client/src/tiptap/menus/heading/index.tsx index ef0a4e73..fa2db036 100644 --- a/packages/client/src/tiptap/menus/heading/index.tsx +++ b/packages/client/src/tiptap/menus/heading/index.tsx @@ -1,7 +1,7 @@ import React, { useCallback } from 'react'; import { Editor } from '@tiptap/core'; import { Select } from '@douyinfe/semi-ui'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; const getCurrentCaretTitle = (editor) => { if (editor.isActive('heading', { level: 1 })) return 1; diff --git a/packages/client/src/tiptap/menus/horizontal-rule/index.tsx b/packages/client/src/tiptap/menus/horizontal-rule/index.tsx index 85fcd2d5..e897fc61 100644 --- a/packages/client/src/tiptap/menus/horizontal-rule/index.tsx +++ b/packages/client/src/tiptap/menus/horizontal-rule/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { Tooltip } from 'components/tooltip'; import { IconHorizontalRule } from 'components/icons'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const HorizontalRule: React.FC<{ editor: Editor }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/menus/ident/index.tsx b/packages/client/src/tiptap/menus/ident/index.tsx index 352d4562..0d5db9fb 100644 --- a/packages/client/src/tiptap/menus/ident/index.tsx +++ b/packages/client/src/tiptap/menus/ident/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { IconIndentLeft, IconIndentRight } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const Ident: React.FC<{ editor: Editor }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/menus/iframe/bubble.tsx b/packages/client/src/tiptap/menus/iframe/bubble.tsx index 1aaf5553..9ef1560c 100644 --- a/packages/client/src/tiptap/menus/iframe/bubble.tsx +++ b/packages/client/src/tiptap/menus/iframe/bubble.tsx @@ -4,9 +4,9 @@ import { FormApi } from '@douyinfe/semi-ui/lib/es/form'; import { IconEdit, IconExternalOpen, IconLineHeight, IconDelete } from '@douyinfe/semi-icons'; import { useToggle } from 'hooks/use-toggle'; import { Tooltip } from 'components/tooltip'; -import { BubbleMenu } from '../../views/bubble-menu'; -import { Iframe } from '../../extensions/iframe'; -import { Divider } from '../../divider'; +import { BubbleMenu } from 'tiptap/views/bubble-menu'; +import { Iframe } from 'tiptap/extensions/iframe'; +import { Divider } from 'tiptap/divider'; import { Size } from '../_components/size'; const { Text } = Typography; diff --git a/packages/client/src/tiptap/menus/image/bubble.tsx b/packages/client/src/tiptap/menus/image/bubble.tsx index 47032692..4372651c 100644 --- a/packages/client/src/tiptap/menus/image/bubble.tsx +++ b/packages/client/src/tiptap/menus/image/bubble.tsx @@ -2,11 +2,11 @@ import React, { useEffect, useState } from 'react'; import { Space, Button } from '@douyinfe/semi-ui'; import { IconAlignLeft, IconAlignCenter, IconAlignRight, IconLineHeight, IconDelete } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { BubbleMenu } from '../../views/bubble-menu'; -import { Divider } from '../../divider'; -import { Image } from '../../extensions/image'; +import { BubbleMenu } from 'tiptap/views/bubble-menu'; +import { Divider } from 'tiptap/divider'; +import { Image } from 'tiptap/extensions/image'; +import { getEditorContainerDOMSize } from 'tiptap/prose-utils'; import { Size } from '../_components/size'; -import { getEditorContainerDOMSize } from '../../utils/editor'; export const ImageBubbleMenu = ({ editor }) => { const attrs = editor.getAttributes(Image.name); diff --git a/packages/client/src/tiptap/menus/insert/index.tsx b/packages/client/src/tiptap/menus/insert/index.tsx index 74984d9a..938afb53 100644 --- a/packages/client/src/tiptap/menus/insert/index.tsx +++ b/packages/client/src/tiptap/menus/insert/index.tsx @@ -20,8 +20,7 @@ import { GridSelect } from 'components/grid-select'; import { useToggle } from 'hooks/use-toggle'; import { useUser } from 'data/user'; import { createKeysLocalStorageLRUCache } from 'helpers/lru-cache'; -import { isTitleActive } from '../../utils/is-active'; -import { getEditorContainerDOMSize } from '../../utils/editor'; +import { isTitleActive, getEditorContainerDOMSize } from 'tiptap/prose-utils'; import { createCountdown } from '../countdown/service'; const insertMenuLRUCache = createKeysLocalStorageLRUCache('TIPTAP_INSERT_MENU', 3); diff --git a/packages/client/src/tiptap/menus/italic/index.tsx b/packages/client/src/tiptap/menus/italic/index.tsx index 4d338161..0038e9b3 100644 --- a/packages/client/src/tiptap/menus/italic/index.tsx +++ b/packages/client/src/tiptap/menus/italic/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { IconItalic } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const Italic: React.FC<{ editor: Editor }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/menus/link/bubble.tsx b/packages/client/src/tiptap/menus/link/bubble.tsx index 6d1367f7..87d87b70 100644 --- a/packages/client/src/tiptap/menus/link/bubble.tsx +++ b/packages/client/src/tiptap/menus/link/bubble.tsx @@ -2,11 +2,10 @@ import { useEffect, useState, useRef, useCallback } from 'react'; import { Space, Button } from '@douyinfe/semi-ui'; import { IconExternalOpen, IconUnlink, IconEdit } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { Divider } from '../../divider'; -import { BubbleMenu } from '../../views/bubble-menu'; -import { Link } from '../../extensions/link'; -import { isMarkActive } from '../../utils/is-active'; -import { findMarkPosition } from '../../utils/find-position'; +import { Divider } from 'tiptap/divider'; +import { BubbleMenu } from 'tiptap/views/bubble-menu'; +import { Link } from 'tiptap/extensions/link'; +import { isMarkActive, findMarkPosition } from 'tiptap/prose-utils'; import { triggerOpenLinkSettingModal } from '../_event'; export const LinkBubbleMenu = ({ editor }) => { diff --git a/packages/client/src/tiptap/menus/link/index.tsx b/packages/client/src/tiptap/menus/link/index.tsx index 2482f454..3015fc22 100644 --- a/packages/client/src/tiptap/menus/link/index.tsx +++ b/packages/client/src/tiptap/menus/link/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { Tooltip } from 'components/tooltip'; import { IconLink } from 'components/icons'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; import { createOrToggleLink } from './service'; import { LinkBubbleMenu } from './bubble'; import { LinkSettingModal } from './modal'; diff --git a/packages/client/src/tiptap/menus/link/modal.tsx b/packages/client/src/tiptap/menus/link/modal.tsx index 75153c65..d0cd4726 100644 --- a/packages/client/src/tiptap/menus/link/modal.tsx +++ b/packages/client/src/tiptap/menus/link/modal.tsx @@ -3,7 +3,7 @@ import { Form, Modal } from '@douyinfe/semi-ui'; import { FormApi } from '@douyinfe/semi-ui/lib/es/form'; import { Editor } from '@tiptap/core'; import { useToggle } from 'hooks/use-toggle'; -import { isValidURL } from '../../utils/valid-url'; +import { isValidURL } from 'tiptap/prose-utils'; import { event, OPEN_LINK_SETTING_MODAL } from '../_event'; type IProps = { editor: Editor }; diff --git a/packages/client/src/tiptap/menus/link/service.ts b/packages/client/src/tiptap/menus/link/service.ts index 15e005a5..ee967864 100644 --- a/packages/client/src/tiptap/menus/link/service.ts +++ b/packages/client/src/tiptap/menus/link/service.ts @@ -1,5 +1,5 @@ import { Editor } from '@tiptap/core'; -import { isMarkActive } from '../../utils/is-active'; +import { isMarkActive } from 'tiptap/prose-utils'; import { triggerOpenLinkSettingModal } from '../_event'; /** diff --git a/packages/client/src/tiptap/menus/mind/bubble.tsx b/packages/client/src/tiptap/menus/mind/bubble.tsx index 0b86087c..b7442c32 100644 --- a/packages/client/src/tiptap/menus/mind/bubble.tsx +++ b/packages/client/src/tiptap/menus/mind/bubble.tsx @@ -2,11 +2,11 @@ import { useCallback } from 'react'; import { Space, Button } from '@douyinfe/semi-ui'; import { IconLineHeight, IconDelete } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { BubbleMenu } from '../../views/bubble-menu'; -import { Mind } from '../../extensions/mind'; +import { BubbleMenu } from 'tiptap/views/bubble-menu'; +import { Mind } from 'tiptap/extensions/mind'; +import { Divider } from 'tiptap/divider'; +import { getEditorContainerDOMSize } from 'tiptap/prose-utils'; import { Size } from '../_components/size'; -import { Divider } from '../../divider'; -import { getEditorContainerDOMSize } from '../../utils/editor'; export const MindBubbleMenu = ({ editor }) => { const attrs = editor.getAttributes(Mind.name); diff --git a/packages/client/src/tiptap/menus/ordered-list/index.tsx b/packages/client/src/tiptap/menus/ordered-list/index.tsx index f821c361..f9d5a128 100644 --- a/packages/client/src/tiptap/menus/ordered-list/index.tsx +++ b/packages/client/src/tiptap/menus/ordered-list/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { IconOrderedList } from 'components/icons'; import { Tooltip } from 'components/tooltip'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const OrderedList: React.FC<{ editor: Editor }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/menus/search/index.tsx b/packages/client/src/tiptap/menus/search/index.tsx index 26389547..24daa994 100644 --- a/packages/client/src/tiptap/menus/search/index.tsx +++ b/packages/client/src/tiptap/menus/search/index.tsx @@ -3,7 +3,7 @@ import { Popover, Button, Typography, Input, Space } from '@douyinfe/semi-ui'; import { Editor } from '@tiptap/core'; import { Tooltip } from 'components/tooltip'; import { IconSearchReplace } from 'components/icons'; -import { SearchNReplace } from '../../extensions/search'; +import { SearchNReplace } from 'tiptap/extensions/search'; const { Text } = Typography; diff --git a/packages/client/src/tiptap/menus/strike/index.tsx b/packages/client/src/tiptap/menus/strike/index.tsx index c1d6da78..9abedded 100644 --- a/packages/client/src/tiptap/menus/strike/index.tsx +++ b/packages/client/src/tiptap/menus/strike/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { IconStrikeThrough } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const Strike: React.FC<{ editor: Editor }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/menus/subscript/index.tsx b/packages/client/src/tiptap/menus/subscript/index.tsx index 78eba568..cc690b1d 100644 --- a/packages/client/src/tiptap/menus/subscript/index.tsx +++ b/packages/client/src/tiptap/menus/subscript/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Button } from '@douyinfe/semi-ui'; import { IconSub } from 'components/icons'; import { Tooltip } from 'components/tooltip'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const Subscript: React.FC<{ editor: any }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/menus/superscript/index.tsx b/packages/client/src/tiptap/menus/superscript/index.tsx index 378c54f2..28e603e0 100644 --- a/packages/client/src/tiptap/menus/superscript/index.tsx +++ b/packages/client/src/tiptap/menus/superscript/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Button } from '@douyinfe/semi-ui'; import { IconSup } from 'components/icons'; import { Tooltip } from 'components/tooltip'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const Superscript: React.FC<{ editor: any }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/menus/table/bubble.tsx b/packages/client/src/tiptap/menus/table/bubble.tsx index 8e0602a4..2be81435 100644 --- a/packages/client/src/tiptap/menus/table/bubble.tsx +++ b/packages/client/src/tiptap/menus/table/bubble.tsx @@ -14,9 +14,9 @@ import { IconTableHeaderCell, } from 'components/icons'; import { Tooltip } from 'components/tooltip'; -import { Divider } from '../../divider'; -import { BubbleMenu } from '../../views/bubble-menu'; -import { Table } from '../../extensions/table'; +import { Divider } from 'tiptap/divider'; +import { BubbleMenu } from 'tiptap/views/bubble-menu'; +import { Table } from 'tiptap/extensions/table'; export const TableBubbleMenu = ({ editor }) => { return ( diff --git a/packages/client/src/tiptap/menus/task-list/index.tsx b/packages/client/src/tiptap/menus/task-list/index.tsx index b52a85c7..882b9acf 100644 --- a/packages/client/src/tiptap/menus/task-list/index.tsx +++ b/packages/client/src/tiptap/menus/task-list/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { Tooltip } from 'components/tooltip'; import { IconTask } from 'components/icons'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const TaskList: React.FC<{ editor: Editor }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/menus/text-color/index.tsx b/packages/client/src/tiptap/menus/text-color/index.tsx index c84b7b94..5d68c125 100644 --- a/packages/client/src/tiptap/menus/text-color/index.tsx +++ b/packages/client/src/tiptap/menus/text-color/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { IconFont } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; import { ColorPicker } from '../_components/color-picker'; export const TextColor: React.FC<{ editor: Editor }> = ({ editor }) => { diff --git a/packages/client/src/tiptap/menus/underline/index.tsx b/packages/client/src/tiptap/menus/underline/index.tsx index 80d63d74..4d6da7e6 100644 --- a/packages/client/src/tiptap/menus/underline/index.tsx +++ b/packages/client/src/tiptap/menus/underline/index.tsx @@ -3,7 +3,7 @@ import { Editor } from '@tiptap/core'; import { Button } from '@douyinfe/semi-ui'; import { IconUnderline } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; -import { isTitleActive } from '../../utils/is-active'; +import { isTitleActive } from 'tiptap/prose-utils'; export const Underline: React.FC<{ editor: Editor }> = ({ editor }) => { if (!editor) { diff --git a/packages/client/src/tiptap/utils/is-active.ts b/packages/client/src/tiptap/prose-utils/active.ts similarity index 100% rename from packages/client/src/tiptap/utils/is-active.ts rename to packages/client/src/tiptap/prose-utils/active.ts diff --git a/packages/client/src/tiptap/utils/clamp.ts b/packages/client/src/tiptap/prose-utils/clamp.ts similarity index 100% rename from packages/client/src/tiptap/utils/clamp.ts rename to packages/client/src/tiptap/prose-utils/clamp.ts diff --git a/packages/client/src/tiptap/utils/code.ts b/packages/client/src/tiptap/prose-utils/code.ts similarity index 92% rename from packages/client/src/tiptap/utils/code.ts rename to packages/client/src/tiptap/prose-utils/code.ts index 18c5b325..d19897c0 100644 --- a/packages/client/src/tiptap/utils/code.ts +++ b/packages/client/src/tiptap/prose-utils/code.ts @@ -1,7 +1,7 @@ import { EditorState } from 'prosemirror-state'; // @ts-ignore import { lowlight } from 'lowlight'; -import { isMarkActive } from './is-active'; +import { isMarkActive } from './active'; export const LANGUAGES = lowlight.listLanguages().reduce((a, language) => { a[language] = language; diff --git a/packages/client/src/tiptap/utils/color.ts b/packages/client/src/tiptap/prose-utils/color.ts similarity index 100% rename from packages/client/src/tiptap/utils/color.ts rename to packages/client/src/tiptap/prose-utils/color.ts diff --git a/packages/client/src/tiptap/utils/delete-node.ts b/packages/client/src/tiptap/prose-utils/delete-node.ts similarity index 100% rename from packages/client/src/tiptap/utils/delete-node.ts rename to packages/client/src/tiptap/prose-utils/delete-node.ts diff --git a/packages/client/src/tiptap/utils/dataset.ts b/packages/client/src/tiptap/prose-utils/dom-dataset.ts similarity index 100% rename from packages/client/src/tiptap/utils/dataset.ts rename to packages/client/src/tiptap/prose-utils/dom-dataset.ts diff --git a/packages/client/src/tiptap/utils/dom.ts b/packages/client/src/tiptap/prose-utils/dom.ts similarity index 100% rename from packages/client/src/tiptap/utils/dom.ts rename to packages/client/src/tiptap/prose-utils/dom.ts diff --git a/packages/client/src/tiptap/utils/download.ts b/packages/client/src/tiptap/prose-utils/download.ts similarity index 100% rename from packages/client/src/tiptap/utils/download.ts rename to packages/client/src/tiptap/prose-utils/download.ts diff --git a/packages/client/src/tiptap/utils/editor.ts b/packages/client/src/tiptap/prose-utils/editor-container-size.ts similarity index 100% rename from packages/client/src/tiptap/utils/editor.ts rename to packages/client/src/tiptap/prose-utils/editor-container-size.ts diff --git a/packages/client/src/tiptap/utils/file.ts b/packages/client/src/tiptap/prose-utils/file.ts similarity index 79% rename from packages/client/src/tiptap/utils/file.ts rename to packages/client/src/tiptap/prose-utils/file.ts index f904b3d1..43762227 100644 --- a/packages/client/src/tiptap/utils/file.ts +++ b/packages/client/src/tiptap/prose-utils/file.ts @@ -53,6 +53,23 @@ export const normalizeFileType = (fileType): FileType => { return 'file'; }; +export const readImageAsBase64 = (file: File): Promise<{ alt: string; src: string }> => { + return new Promise((resolve) => { + const reader = new FileReader(); + reader.addEventListener( + 'load', + () => { + resolve({ + alt: file.name, + src: reader.result as string, + }); + }, + false + ); + reader.readAsDataURL(file); + }); +}; + export const getImageWidthHeight = (url: string): Promise<{ width: number | string; height: number | string }> => { return new Promise((resolve) => { const img = document.createElement('img'); diff --git a/packages/client/src/tiptap/prose-utils/index.ts b/packages/client/src/tiptap/prose-utils/index.ts new file mode 100644 index 00000000..f824aa8b --- /dev/null +++ b/packages/client/src/tiptap/prose-utils/index.ts @@ -0,0 +1,20 @@ +export * from './active'; +export * from './clamp'; +export * from './code'; +export * from './color'; +export * from './delete-node'; +export * from './dom-dataset'; +export * from './dom'; +export * from './download'; +export * from './editor-container-size'; +export * from './file'; +export * from './lowlight-plugin'; +export * from './mark'; +export * from './mention'; +export * from './node'; +export * from './position'; +export * from './table'; +export * from './text'; +export * from './type'; +export * from './upload'; +export * from './url'; diff --git a/packages/client/src/tiptap/utils/lowlight-plugin.ts b/packages/client/src/tiptap/prose-utils/lowlight-plugin.ts similarity index 100% rename from packages/client/src/tiptap/utils/lowlight-plugin.ts rename to packages/client/src/tiptap/prose-utils/lowlight-plugin.ts diff --git a/packages/client/src/tiptap/utils/find-position.ts b/packages/client/src/tiptap/prose-utils/mark.ts similarity index 53% rename from packages/client/src/tiptap/utils/find-position.ts rename to packages/client/src/tiptap/prose-utils/mark.ts index aad16ee0..9bb6a4a2 100644 --- a/packages/client/src/tiptap/utils/find-position.ts +++ b/packages/client/src/tiptap/prose-utils/mark.ts @@ -1,5 +1,22 @@ import { EditorState } from 'prosemirror-state'; +export const markInputRegex = (tag) => new RegExp(`(<(${tag})((?: \\w+=".+?")+)?>([^<]+))$`, 'gm'); + +export const extractMarkAttributesFromMatch = ([, , , attrsString]) => { + const attrRegex = /(\w+)="(.+?)"/g; + const attrs = {}; + + let key; + let value; + + do { + [, key, value] = attrRegex.exec(attrsString) || []; + if (key) attrs[key] = value; + } while (key); + + return attrs; +}; + export function findMarkPosition(state: EditorState, mark, from, to) { let markPos = { start: -1, end: -1 }; state.doc.nodesBetween(from, to, (node, pos) => { diff --git a/packages/client/src/tiptap/utils/find-mention.ts b/packages/client/src/tiptap/prose-utils/mention.ts similarity index 100% rename from packages/client/src/tiptap/utils/find-mention.ts rename to packages/client/src/tiptap/prose-utils/mention.ts diff --git a/packages/client/src/tiptap/utils/node.ts b/packages/client/src/tiptap/prose-utils/node.ts similarity index 100% rename from packages/client/src/tiptap/utils/node.ts rename to packages/client/src/tiptap/prose-utils/node.ts diff --git a/packages/client/src/tiptap/prose-utils/position.ts b/packages/client/src/tiptap/prose-utils/position.ts new file mode 100644 index 00000000..46c62e44 --- /dev/null +++ b/packages/client/src/tiptap/prose-utils/position.ts @@ -0,0 +1,61 @@ +/* Copyright 2021, Milkdown by Mirone. */ +import type { EditorView } from 'prosemirror-view'; + +type Point = [top: number, left: number]; + +export const calculateNodePosition = ( + view: EditorView, + target: HTMLElement, + handler: (selectedRect: DOMRect, targetRect: DOMRect, parentRect: DOMRect) => Point +) => { + const state = view.state; + const { from } = state.selection; + + const { node } = view.domAtPos(from); + const element = node instanceof Text ? node.parentElement : node; + if (!(element instanceof HTMLElement)) { + throw new Error(); + } + + const selectedNodeRect = element.getBoundingClientRect(); + const targetNodeRect = target.getBoundingClientRect(); + const parentNodeRect = target.parentElement?.getBoundingClientRect(); + if (!parentNodeRect) { + throw new Error(); + } + + const [top, left] = handler(selectedNodeRect, targetNodeRect, parentNodeRect); + + target.style.top = top + 'px'; + target.style.left = left + 'px'; +}; + +type Rect = { + left: number; + right: number; + top: number; + bottom: number; +}; + +export const calculateTextPosition = ( + view: EditorView, + target: HTMLElement, + handler: (start: Rect, end: Rect, targetRect: DOMRect, parentRect: DOMRect) => Point +) => { + const state = view.state; + const { from, to } = state.selection; + const start = view.coordsAtPos(from); + const end = view.coordsAtPos(to); + + const targetNodeRect = target.getBoundingClientRect(); + const parent = target.parentElement; + if (!parent) { + throw new Error(); + } + const parentNodeRect = parent.getBoundingClientRect(); + + const [top, left] = handler(start, end, targetNodeRect, parentNodeRect); + + target.style.top = top + 'px'; + target.style.left = left + 'px'; +}; diff --git a/packages/client/src/tiptap/utils/table.ts b/packages/client/src/tiptap/prose-utils/table.ts similarity index 100% rename from packages/client/src/tiptap/utils/table.ts rename to packages/client/src/tiptap/prose-utils/table.ts diff --git a/packages/client/src/tiptap/prose-utils/text.ts b/packages/client/src/tiptap/prose-utils/text.ts new file mode 100644 index 00000000..be5e9fe9 --- /dev/null +++ b/packages/client/src/tiptap/prose-utils/text.ts @@ -0,0 +1,16 @@ +type R = Record; + +export const isPureText = (content: R | R[] | undefined | null): boolean => { + if (!content) return false; + if (Array.isArray(content)) { + if (content.length > 1) return false; + return isPureText(content[0]); + } + + const child = content['content']; + if (child) { + return isPureText(child as R[]); + } + + return content['type'] === 'text'; +}; diff --git a/packages/client/src/tiptap/utils/type.ts b/packages/client/src/tiptap/prose-utils/type.ts similarity index 100% rename from packages/client/src/tiptap/utils/type.ts rename to packages/client/src/tiptap/prose-utils/type.ts diff --git a/packages/client/src/tiptap/utils/upload.ts b/packages/client/src/tiptap/prose-utils/upload.ts similarity index 100% rename from packages/client/src/tiptap/utils/upload.ts rename to packages/client/src/tiptap/prose-utils/upload.ts diff --git a/packages/client/src/tiptap/utils/valid-url.ts b/packages/client/src/tiptap/prose-utils/url.ts similarity index 100% rename from packages/client/src/tiptap/utils/valid-url.ts rename to packages/client/src/tiptap/prose-utils/url.ts diff --git a/packages/client/src/tiptap/utils/list-input-rule.ts b/packages/client/src/tiptap/utils/list-input-rule.ts deleted file mode 100644 index e0503cfe..00000000 --- a/packages/client/src/tiptap/utils/list-input-rule.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { InputRule, wrappingInputRule } from '@tiptap/core'; - -/** - * Wrapping input handler that will append the content of the last match - * - * @param {RegExp} find find param for the wrapping input rule - * @param {object} type Node Type object - * @param {*} getAttributes handler to get the attributes - */ -export function listInputRule(find, type, getAttributes = null) { - const handler = ({ state, range, match }) => { - const wrap = wrappingInputRule({ find, type, getAttributes }); - // @ts-ignore - wrap.handler({ state, range, match }); - // Insert the first character after bullet if there is one - if (match.length >= 3) { - state.tr.insertText(match[2]); - } - }; - return new InputRule({ find, handler }); -} diff --git a/packages/client/src/tiptap/utils/mark-utils.ts b/packages/client/src/tiptap/utils/mark-utils.ts deleted file mode 100644 index 27c78ec7..00000000 --- a/packages/client/src/tiptap/utils/mark-utils.ts +++ /dev/null @@ -1,16 +0,0 @@ -export const markInputRegex = (tag) => new RegExp(`(<(${tag})((?: \\w+=".+?")+)?>([^<]+))$`, 'gm'); - -export const extractMarkAttributesFromMatch = ([, , , attrsString]) => { - const attrRegex = /(\w+)="(.+?)"/g; - const attrs = {}; - - let key; - let value; - - do { - [, key, value] = attrRegex.exec(attrsString) || []; - if (key) attrs[key] = value; - } while (key); - - return attrs; -}; diff --git a/packages/client/src/tiptap/wrappers/attachment/file-icon.tsx b/packages/client/src/tiptap/wrappers/attachment/file-icon.tsx index e2db6ca1..52ecc11d 100644 --- a/packages/client/src/tiptap/wrappers/attachment/file-icon.tsx +++ b/packages/client/src/tiptap/wrappers/attachment/file-icon.tsx @@ -1,5 +1,5 @@ import { IconFile, IconSong, IconVideo, IconImage } from '@douyinfe/semi-icons'; -import { normalizeFileType } from '../../utils/file'; +import { normalizeFileType } from 'tiptap/prose-utils'; export const getFileTypeIcon = (fileType: string) => { const type = normalizeFileType(fileType); diff --git a/packages/client/src/tiptap/wrappers/attachment/index.tsx b/packages/client/src/tiptap/wrappers/attachment/index.tsx index 9df42f7e..43940fa6 100644 --- a/packages/client/src/tiptap/wrappers/attachment/index.tsx +++ b/packages/client/src/tiptap/wrappers/attachment/index.tsx @@ -5,9 +5,8 @@ import { Button, Typography, Spin, Collapsible, Space } from '@douyinfe/semi-ui' import { IconDownload, IconPlayCircle, IconClose } from '@douyinfe/semi-icons'; import { Tooltip } from 'components/tooltip'; import { useToggle } from 'hooks/use-toggle'; -import { download } from '../../utils/download'; +import { download, normalizeFileSize, extractFileExtension, extractFilename } from 'tiptap/prose-utils'; import { uploadFile } from 'services/file'; -import { normalizeFileSize, extractFileExtension, extractFilename } from '../../utils/file'; import { Player } from './player'; import { getFileTypeIcon } from './file-icon'; import styles from './index.module.scss'; diff --git a/packages/client/src/tiptap/wrappers/attachment/player/index.tsx b/packages/client/src/tiptap/wrappers/attachment/player/index.tsx index 54e9446e..c5d98e5c 100644 --- a/packages/client/src/tiptap/wrappers/attachment/player/index.tsx +++ b/packages/client/src/tiptap/wrappers/attachment/player/index.tsx @@ -7,7 +7,7 @@ import { extractFilename, normalizeFileType, FileType, -} from '../../../utils/file'; +} from 'tiptap/prose-utils'; import { PDFPlayer } from './pdf-player'; import styles from './index.module.scss'; diff --git a/packages/client/src/tiptap/wrappers/document-reference/index.tsx b/packages/client/src/tiptap/wrappers/document-reference/index.tsx index 55f81eec..8ac737dd 100644 --- a/packages/client/src/tiptap/wrappers/document-reference/index.tsx +++ b/packages/client/src/tiptap/wrappers/document-reference/index.tsx @@ -1,10 +1,10 @@ +import { useMemo } from 'react'; import { NodeViewWrapper } from '@tiptap/react'; import { useRouter } from 'next/router'; import Link from 'next/link'; import cls from 'classnames'; import { IconDocument } from 'components/icons'; import styles from './index.module.scss'; -import { useMemo } from 'react'; export const DocumentReferenceWrapper = ({ editor, node, updateAttributes }) => { const { pathname } = useRouter(); diff --git a/packages/client/src/tiptap/wrappers/iframe/index.tsx b/packages/client/src/tiptap/wrappers/iframe/index.tsx index 7aae71fe..088513a2 100644 --- a/packages/client/src/tiptap/wrappers/iframe/index.tsx +++ b/packages/client/src/tiptap/wrappers/iframe/index.tsx @@ -3,7 +3,7 @@ import cls from 'classnames'; import { NodeViewWrapper } from '@tiptap/react'; import { Typography } from '@douyinfe/semi-ui'; import { Resizeable } from 'components/resizeable'; -import { getEditorContainerDOMSize } from '../../utils/editor'; +import { getEditorContainerDOMSize } from 'tiptap/prose-utils'; import styles from './index.module.scss'; const { Text } = Typography; diff --git a/packages/client/src/tiptap/wrappers/image/index.tsx b/packages/client/src/tiptap/wrappers/image/index.tsx index 8f564cca..cf201387 100644 --- a/packages/client/src/tiptap/wrappers/image/index.tsx +++ b/packages/client/src/tiptap/wrappers/image/index.tsx @@ -5,8 +5,12 @@ import { LazyLoadImage } from 'react-lazy-load-image-component'; import { Resizeable } from 'components/resizeable'; import { useToggle } from 'hooks/use-toggle'; import { uploadFile } from 'services/file'; -import { extractFileExtension, extractFilename, getImageWidthHeight } from '../../utils/file'; -import { getEditorContainerDOMSize } from '../../utils/editor'; +import { + extractFileExtension, + extractFilename, + getImageWidthHeight, + getEditorContainerDOMSize, +} from 'tiptap/prose-utils'; import styles from './index.module.scss'; const { Text } = Typography; diff --git a/packages/client/src/tiptap/wrappers/mind/index.tsx b/packages/client/src/tiptap/wrappers/mind/index.tsx index 31b896cc..71b930f0 100644 --- a/packages/client/src/tiptap/wrappers/mind/index.tsx +++ b/packages/client/src/tiptap/wrappers/mind/index.tsx @@ -5,9 +5,8 @@ import { Spin, Typography } from '@douyinfe/semi-ui'; import deepEqual from 'deep-equal'; import { Resizeable } from 'components/resizeable'; import { useToggle } from 'hooks/use-toggle'; -import { clamp } from '../../utils/clamp'; -import { getEditorContainerDOMSize } from '../../utils/editor'; -import { Mind } from '../../extensions/mind'; +import { clamp, getEditorContainerDOMSize } from 'tiptap/prose-utils'; +import { Mind } from 'tiptap/extensions/mind'; import { loadKityMinder } from './kityminder'; import { Toolbar } from './toolbar'; import { MIN_ZOOM, MAX_ZOOM, ZOOM_STEP } from './toolbar/constant'; @@ -205,8 +204,6 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => { minder.execCommand('theme', theme); }, [theme]); - console.log(width, height); - return (