diff --git a/packages/client/src/tiptap/extensions/blockquote.ts b/packages/client/src/tiptap/extensions/blockquote.ts index 05b0157d..4cc04be1 100644 --- a/packages/client/src/tiptap/extensions/blockquote.ts +++ b/packages/client/src/tiptap/extensions/blockquote.ts @@ -20,6 +20,7 @@ export const Blockquote = BuiltInBlockquote.extend({ addInputRules() { const multilineInputRegex = /^\s*>>>\s$/gm; return [ + // eslint-disable-next-line no-unsafe-optional-chaining ...this.parent?.(), wrappingInputRule({ find: multilineInputRegex, diff --git a/packages/client/src/tiptap/extensions/collaboration-cursor/index.ts b/packages/client/src/tiptap/extensions/collaboration-cursor/index.ts index be0125ab..5ccdd3bc 100644 --- a/packages/client/src/tiptap/extensions/collaboration-cursor/index.ts +++ b/packages/client/src/tiptap/extensions/collaboration-cursor/index.ts @@ -101,7 +101,9 @@ const lockCollaborationUserEditingNodes = (extensionThis, users) => { options.collaborationUserCursorCache.set(user.clientId, { user, cursor }); } } - } catch (e) {} + } catch (e) { + // + } }); } }; diff --git a/packages/client/src/tiptap/extensions/paste.ts b/packages/client/src/tiptap/extensions/paste.ts index 78cb6ef1..30535081 100644 --- a/packages/client/src/tiptap/extensions/paste.ts +++ b/packages/client/src/tiptap/extensions/paste.ts @@ -61,7 +61,7 @@ export const Paste = Extension.create({ if (node) { const doc = safeJSONParse(node); - let tr = view.state.tr; + const tr = view.state.tr; const selection = tr.selection; view.dispatch(tr.insert(selection.from - 1, view.state.schema.nodeFromJSON(doc)).scrollIntoView()); return true; diff --git a/packages/client/src/tiptap/extensions/search.ts b/packages/client/src/tiptap/extensions/search.ts index 5d49efb0..3dce9c99 100644 --- a/packages/client/src/tiptap/extensions/search.ts +++ b/packages/client/src/tiptap/extensions/search.ts @@ -182,7 +182,7 @@ const gotoSearchResult = ({ view, tr, searchResults, searchResultCurrentClass, g const result = searchResults[gotoIndex]; if (result) { - let transaction = tr.setMeta('directDecoration', { + const transaction = tr.setMeta('directDecoration', { fromPos: result.from, toPos: result.to, attrs: { class: searchResultCurrentClass }, diff --git a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/html-to-prosemirror/renderer.ts b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/html-to-prosemirror/renderer.ts index 74af89f8..1f603ba8 100644 --- a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/html-to-prosemirror/renderer.ts +++ b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/html-to-prosemirror/renderer.ts @@ -116,7 +116,7 @@ export class Renderer { } renderChildren(node) { - let nodes = []; + const nodes = []; node.childNodes.forEach((child) => { const NodeClass = this.getMatchingNode(child); @@ -180,7 +180,7 @@ export class Renderer { } getMatchingClass(node, classes) { - for (let i in classes) { + for (const i in classes) { const Class = classes[i]; const instance = new Class(node); if (instance.matching()) { diff --git a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/index.tsx b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/index.tsx index ae4e5a9d..d1a56d68 100644 --- a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/index.tsx +++ b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/index.tsx @@ -18,6 +18,7 @@ export * from './markdown-source-map'; const extractImage = (html) => { let matches = []; + // eslint-disable-next-line no-useless-escape while ((matches = html.match(/\\\<\/p\>/g))) { const target = matches[0].match(//)[0]; html = html.replace(matches[0], target); 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 f98493aa..501f1fa2 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 @@ -20,7 +20,7 @@ export const createMarkdownContainer = (types: string | Array) => (md) = if (tag.nesting === 1) { tag.attrSet('class', type); - var m = tag.info.trim().match(regexp); + const m = tag.info.trim().match(regexp); if (m[1]) { const data = strToJSON(m[1]); jsonToDOMDataset(data).forEach(({ key, value }) => { diff --git a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownKatex.ts b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownKatex.ts index b622f132..ab551997 100644 --- a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownKatex.ts +++ b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownKatex.ts @@ -1,9 +1,10 @@ +/* eslint-disable */ // var katex = require('katex'); // Test if potential opening or closing delimieter // Assumes that there is a "$" at state.src[pos] function isValidDelim(state, pos) { - var prevChar, + let prevChar, nextChar, max = state.posMax, can_open = true, @@ -32,7 +33,7 @@ function isValidDelim(state, pos) { } function math_inline(state, silent) { - var start, match, token, res, pos, esc_count; + let start, match, token, res, pos, esc_count; if (state.src[state.pos] !== '$') { return false; @@ -107,7 +108,7 @@ function math_inline(state, silent) { } function math_block(state, start, end, silent) { - var firstLine, + let firstLine, lastLine, next, lastPos, @@ -179,7 +180,7 @@ function escapeHtml(unsafe) { .replace(/'/g, '''); } -var katex = { +let katex = { renderToString: (s, opts) => s, }; @@ -194,7 +195,7 @@ export default function math_plugin(md, options) { options.blockClass = ''; } - var inlineRenderer = function (tokens, idx) { + const inlineRenderer = function (tokens, idx) { return katexBlock(tokens[idx].content); }; @@ -212,7 +213,7 @@ export default function math_plugin(md, options) { } }; - var blockRenderer = function (tokens, idx) { + const blockRenderer = function (tokens, idx) { return katexBlock(tokens[idx].content) + '\n'; }; diff --git a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownTable.ts b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownTable.ts index e4aefb52..1319c4b0 100644 --- a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownTable.ts +++ b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownTable.ts @@ -1,3 +1,5 @@ +/* eslint-disable */ + // Copied from https://github.com/markdown-it/markdown-it/blob/master/lib/rules_block/table.js function isSpace(code) { @@ -10,14 +12,14 @@ function isSpace(code) { } function getLine(state, line) { - var pos = state.bMarks[line] + state.tShift[line], + const pos = state.bMarks[line] + state.tShift[line], max = state.eMarks[line]; return state.src.substr(pos, max - pos); } function escapedSplit(str) { - var result = [], + let result = [], pos = 0, max = str.length, ch, @@ -53,7 +55,7 @@ function escapedSplit(str) { } function table(state, startLine, endLine, silent) { - var ch, + let ch, lineText, pos, i, diff --git a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownTaskList.ts b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownTaskList.ts index 980ea3b9..ac6b28d7 100644 --- a/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownTaskList.ts +++ b/packages/client/src/tiptap/markdown/markdown-to-prosemirror/markdown-to-html/markdownTaskList.ts @@ -50,8 +50,8 @@ export default function markdownItTaskLists( } function attrSet(token, name, value) { - var index = token.attrIndex(name); - var attr = [name, value]; + const index = token.attrIndex(name); + const attr = [name, value]; if (index < 0) { token.attrPush(attr); 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 e6e8625b..3672abd9 100644 --- a/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts +++ b/packages/client/src/tiptap/markdown/prosemirror-to-markdown/index.ts @@ -130,6 +130,7 @@ const SerializerConfig = { [Image.name]: renderImage, [Katex.name]: (state, node) => { state.ensureNewLine(); + // eslint-disable-next-line no-useless-escape state.write(`\$\$${node.attrs.text || ''}\$\$`); state.closeBlock(node); }, diff --git a/packages/client/src/tiptap/menus/_components/size.tsx b/packages/client/src/tiptap/menus/_components/size.tsx index ccd14219..0c5f1748 100644 --- a/packages/client/src/tiptap/menus/_components/size.tsx +++ b/packages/client/src/tiptap/menus/_components/size.tsx @@ -17,7 +17,7 @@ export const Size: React.FC<{ width: number; maxWidth?: number; height: number; $form.current.validate().then((values) => { onOk(values as ISize); }); - }, []); + }, [onOk]); return ( = ({ editor }) => { editor.chain().focus().setCountdown({ title: values.title, date: values.date.valueOf() }).run(); toggleVisible(false); }); - }, []); + }, [editor, toggleVisible]); useEffect(() => { const handler = (data) => { @@ -30,7 +30,7 @@ export const CountdownSettingModal: React.FC = ({ editor }) => { return () => { event.off(OPEN_COUNT_SETTING_MODAL, handler); }; - }, []); + }, [toggleVisible]); return ( toggleVisible(false)}> diff --git a/packages/client/src/tiptap/menus/emoji/index.tsx b/packages/client/src/tiptap/menus/emoji/index.tsx index b00bad8c..9af7f848 100644 --- a/packages/client/src/tiptap/menus/emoji/index.tsx +++ b/packages/client/src/tiptap/menus/emoji/index.tsx @@ -6,11 +6,14 @@ import { IconEmoji } from 'components/icons'; import { EmojiPicker } from 'components/emoji-picker'; export const Emoji: React.FC<{ editor: Editor }> = ({ editor }) => { - const setEmoji = useCallback((emoji) => { - const { selection } = editor.state; - const { $anchor } = selection; - return editor.chain().insertContentAt($anchor.pos, emoji).run(); - }, []); + const setEmoji = useCallback( + (emoji) => { + const { selection } = editor.state; + const { $anchor } = selection; + return editor.chain().insertContentAt($anchor.pos, emoji).run(); + }, + [editor] + ); return ( diff --git a/packages/client/src/tiptap/menus/fontsize/index.tsx b/packages/client/src/tiptap/menus/fontsize/index.tsx index e391238a..95903b98 100644 --- a/packages/client/src/tiptap/menus/fontsize/index.tsx +++ b/packages/client/src/tiptap/menus/fontsize/index.tsx @@ -9,13 +9,16 @@ export const FontSize: React.FC<{ editor: Editor }> = ({ editor }) => { const currentFontSizePx = editor.getAttributes('textStyle').fontSize || '16px'; const currentFontSize = +currentFontSizePx.replace('px', ''); - const toggle = useCallback((val) => { - editor - .chain() - .focus() - .setFontSize(val + 'px') - .run(); - }, []); + const toggle = useCallback( + (val) => { + editor + .chain() + .focus() + .setFontSize(val + 'px') + .run(); + }, + [editor] + ); return ( { const handleCancel = useCallback(() => { toggleVisible(false); - }, []); + }, [toggleVisible]); const handleOk = useCallback(() => { $form.current.validate().then((values) => { @@ -41,7 +41,7 @@ export const IframeBubbleMenu = ({ editor }) => { .run(); toggleVisible(false); }); - }, []); + }, [editor, toggleVisible]); const visitLink = useCallback(() => { window.open(url, '_blank'); @@ -49,7 +49,7 @@ export const IframeBubbleMenu = ({ editor }) => { const openEditLinkModal = useCallback(() => { toggleVisible(true); - }, []); + }, [toggleVisible]); const setSize = useCallback( (size) => { diff --git a/packages/client/src/tiptap/menus/insert/index.tsx b/packages/client/src/tiptap/menus/insert/index.tsx index 741bbc4f..2ddbb0f6 100644 --- a/packages/client/src/tiptap/menus/insert/index.tsx +++ b/packages/client/src/tiptap/menus/insert/index.tsx @@ -154,14 +154,14 @@ export const Insert: React.FC<{ editor: Editor }> = ({ editor }) => { toggleVisible(false); }; }, - [editor, toggleVisible] + [editor, toggleVisible, transformToCommands, user] ); useEffect(() => { if (!visible) return; insertMenuLRUCache.syncFromStorage(); setRecentUsed(transformToCommands(insertMenuLRUCache.get() as string[])); - }, [visible]); + }, [visible, transformToCommands]); if (!editor) { return null; diff --git a/packages/client/src/tiptap/menus/link/bubble.tsx b/packages/client/src/tiptap/menus/link/bubble.tsx index 87d87b70..83ce60ba 100644 --- a/packages/client/src/tiptap/menus/link/bubble.tsx +++ b/packages/client/src/tiptap/menus/link/bubble.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react-hooks/exhaustive-deps */ import { useEffect, useState, useRef, useCallback } from 'react'; import { Space, Button } from '@douyinfe/semi-ui'; import { IconExternalOpen, IconUnlink, IconEdit } from '@douyinfe/semi-icons'; diff --git a/packages/client/src/tiptap/menus/link/modal.tsx b/packages/client/src/tiptap/menus/link/modal.tsx index d0cd4726..712c6a75 100644 --- a/packages/client/src/tiptap/menus/link/modal.tsx +++ b/packages/client/src/tiptap/menus/link/modal.tsx @@ -27,7 +27,7 @@ export const LinkSettingModal: React.FC = ({ editor }) => { view.dispatch(view.state.tr.scrollIntoView()); toggleVisible(false); }); - }, [initialState]); + }, [initialState, editor, toggleVisible]); useEffect(() => { const handler = (data) => { @@ -40,7 +40,7 @@ export const LinkSettingModal: React.FC = ({ editor }) => { return () => { event.off(OPEN_LINK_SETTING_MODAL, handler); }; - }, [editor]); + }, [editor, toggleVisible]); return ( toggleVisible(false)} centered> diff --git a/packages/client/src/tiptap/menus/search/index.tsx b/packages/client/src/tiptap/menus/search/index.tsx index 24daa994..c0950448 100644 --- a/packages/client/src/tiptap/menus/search/index.tsx +++ b/packages/client/src/tiptap/menus/search/index.tsx @@ -15,12 +15,16 @@ export const Search: React.FC<{ editor: Editor }> = ({ editor }) => { const [replaceValue, setReplaceValue] = useState(''); useEffect(() => { - editor?.commands?.setSearchTerm(searchValue); - }, [searchValue]); + if (editor && editor.commands && editor.commands.setSearchTerm) { + editor.commands.setSearchTerm(searchValue); + } + }, [searchValue, editor]); useEffect(() => { - editor?.commands?.setReplaceTerm(replaceValue); - }, [replaceValue]); + if (editor && editor.commands && editor.commands.setReplaceTerm) { + editor.commands.setReplaceTerm(replaceValue); + } + }, [replaceValue, editor]); return ( ) => { * @param transformToJSON 是否要转为 JSON */ export const getDatasetAttribute = - (attribute: string, transformToJSON: boolean = false) => + (attribute: string, transformToJSON = false) => (element: HTMLElement) => { const dataKey = attribute.startsWith('data-') ? attribute : `data-${attribute}`; const value = decodeURIComponent(element.getAttribute(dataKey)); diff --git a/packages/client/src/tiptap/prose-utils/url.ts b/packages/client/src/tiptap/prose-utils/url.ts index 134911a2..351121fd 100644 --- a/packages/client/src/tiptap/prose-utils/url.ts +++ b/packages/client/src/tiptap/prose-utils/url.ts @@ -1,5 +1,5 @@ export function isValidURL(str) { - var pattern = new RegExp( + const pattern = new RegExp( '^(https?:\\/\\/)?' + // protocol '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name '((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address diff --git a/packages/client/src/tiptap/prose-utils/uuid.ts b/packages/client/src/tiptap/prose-utils/uuid.ts index 34fee6c2..ce517f34 100644 --- a/packages/client/src/tiptap/prose-utils/uuid.ts +++ b/packages/client/src/tiptap/prose-utils/uuid.ts @@ -1,15 +1,15 @@ export function uuid() { - var s = []; + const s = []; - var hexDigits = '0123456789abcdef'; + const hexDigits = '0123456789abcdef'; - for (var i = 0; i < 36; i++) { + for (let i = 0; i < 36; i++) { s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); } s[14] = '4'; // bits 12-15 of the time_hi_and_version field to 0010 s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 s[8] = s[13] = s[18] = s[23] = '-'; - var uuid = s.join(''); + const uuid = s.join(''); return uuid; } diff --git a/packages/client/src/tiptap/provider.ts b/packages/client/src/tiptap/provider.ts index dfce8d8e..105f854a 100644 --- a/packages/client/src/tiptap/provider.ts +++ b/packages/client/src/tiptap/provider.ts @@ -48,7 +48,6 @@ export const getProvider = ({ docType, }, maxAttempts: 5, - forceSyncInterval: 100, ...events, } as any); pool.set(targetId, provider); diff --git a/packages/client/src/tiptap/views/bubble-menu/index.tsx b/packages/client/src/tiptap/views/bubble-menu/index.tsx index 265d0577..a57bb199 100644 --- a/packages/client/src/tiptap/views/bubble-menu/index.tsx +++ b/packages/client/src/tiptap/views/bubble-menu/index.tsx @@ -40,7 +40,8 @@ export const BubbleMenu: React.FC = (props) => { editor.registerPlugin(plugin); return () => editor.unregisterPlugin(pluginKey); - }, [props.editor, element]); + // TODO: 检验是否应该是 props.editor + }, [props, element]); return (
diff --git a/packages/client/src/tiptap/wrappers/attachment/index.tsx b/packages/client/src/tiptap/wrappers/attachment/index.tsx index 43940fa6..390c5abe 100644 --- a/packages/client/src/tiptap/wrappers/attachment/index.tsx +++ b/packages/client/src/tiptap/wrappers/attachment/index.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef } from 'react'; +import { useCallback, useEffect, useRef } from 'react'; import cls from 'classnames'; import { NodeViewWrapper } from '@tiptap/react'; import { Button, Typography, Spin, Collapsible, Space } from '@douyinfe/semi-ui'; @@ -20,36 +20,39 @@ export const AttachmentWrapper = ({ editor, node, updateAttributes }) => { const [loading, toggleLoading] = useToggle(false); const [visible, toggleVisible] = useToggle(false); - const selectFile = () => { + const selectFile = useCallback(() => { if (!isEditable || url) return; isEditable && $upload.current.click(); - }; + }, [isEditable, url]); - const handleFile = async (e) => { - const file = e.target.files && e.target.files[0]; - const fileInfo = { - fileName: extractFilename(file.name), - fileSize: file.size, - fileType: file.type, - fileExt: extractFileExtension(file.name), - }; - toggleLoading(true); - try { - const url = await uploadFile(file); - updateAttributes({ ...fileInfo, url }); - toggleLoading(false); - } catch (error) { - updateAttributes({ error: '文件上传失败:' + (error && error.message) || '未知错误' }); - toggleLoading(false); - } - }; + const handleFile = useCallback( + async (e) => { + const file = e.target.files && e.target.files[0]; + const fileInfo = { + fileName: extractFilename(file.name), + fileSize: file.size, + fileType: file.type, + fileExt: extractFileExtension(file.name), + }; + toggleLoading(true); + try { + const url = await uploadFile(file); + updateAttributes({ ...fileInfo, url }); + toggleLoading(false); + } catch (error) { + updateAttributes({ error: '文件上传失败:' + (error && error.message) || '未知错误' }); + toggleLoading(false); + } + }, + [toggleLoading, updateAttributes] + ); useEffect(() => { if (!url && !hasTrigger) { selectFile(); updateAttributes({ hasTrigger: true }); } - }, [url, hasTrigger]); + }, [url, hasTrigger, selectFile, updateAttributes]); const content = (() => { if (isEditable && !url) { diff --git a/packages/client/src/tiptap/wrappers/callout/index.tsx b/packages/client/src/tiptap/wrappers/callout/index.tsx index 369190c1..cd3661e7 100644 --- a/packages/client/src/tiptap/wrappers/callout/index.tsx +++ b/packages/client/src/tiptap/wrappers/callout/index.tsx @@ -8,9 +8,12 @@ export const CalloutWrapper = ({ editor, node, updateAttributes }) => { const { isEditable } = editor; const { emoji, textColor, borderColor, backgroundColor } = node.attrs; - const onSelectEmoji = useCallback((emoji) => { - updateAttributes({ emoji }); - }, []); + const onSelectEmoji = useCallback( + (emoji) => { + updateAttributes({ emoji }); + }, + [updateAttributes] + ); return ( diff --git a/packages/client/src/tiptap/wrappers/document-children/index.tsx b/packages/client/src/tiptap/wrappers/document-children/index.tsx index 5da66111..b346e410 100644 --- a/packages/client/src/tiptap/wrappers/document-children/index.tsx +++ b/packages/client/src/tiptap/wrappers/document-children/index.tsx @@ -17,7 +17,7 @@ export const DocumentChildrenWrapper = ({ editor, node, updateAttributes }) => { const { pathname, query } = useRouter(); let { wikiId, documentId } = node.attrs; if (!wikiId) { - query?.wikiId; + wikiId = query?.wikiId; } if (!documentId) { documentId = query?.documentId; @@ -31,7 +31,7 @@ export const DocumentChildrenWrapper = ({ editor, node, updateAttributes }) => { if (attrs.wikiId !== wikiId || attrs.documentId !== documentId) { updateAttributes({ wikiId, documentId }); } - }, [node.attrs, wikiId, documentId]); + }, [node.attrs, wikiId, documentId, updateAttributes]); return ( ); - }, [wikiId, documentId]); + }, [wikiId, documentId, isEditable, isShare, title]); return ( diff --git a/packages/client/src/tiptap/wrappers/emoji-list/index.tsx b/packages/client/src/tiptap/wrappers/emoji-list/index.tsx index 3ad829da..052f1790 100644 --- a/packages/client/src/tiptap/wrappers/emoji-list/index.tsx +++ b/packages/client/src/tiptap/wrappers/emoji-list/index.tsx @@ -81,3 +81,5 @@ export const EmojiList: React.FC = forwardRef((props, ref) => {
); }); + +EmojiList.displayName = 'EmojiList'; diff --git a/packages/client/src/tiptap/wrappers/iframe/index.tsx b/packages/client/src/tiptap/wrappers/iframe/index.tsx index 088513a2..5164c790 100644 --- a/packages/client/src/tiptap/wrappers/iframe/index.tsx +++ b/packages/client/src/tiptap/wrappers/iframe/index.tsx @@ -13,9 +13,12 @@ export const IframeWrapper = ({ editor, node, updateAttributes }) => { const { url, width, height } = node.attrs; const { width: maxWidth } = getEditorContainerDOMSize(editor); - const onResize = useCallback((size) => { - updateAttributes({ width: size.width, height: size.height }); - }, []); + const onResize = useCallback( + (size) => { + updateAttributes({ width: size.width, height: size.height }); + }, + [updateAttributes] + ); return ( diff --git a/packages/client/src/tiptap/wrappers/image/index.tsx b/packages/client/src/tiptap/wrappers/image/index.tsx index cf201387..ed21fc1d 100644 --- a/packages/client/src/tiptap/wrappers/image/index.tsx +++ b/packages/client/src/tiptap/wrappers/image/index.tsx @@ -22,44 +22,50 @@ export const ImageWrapper = ({ editor, node, updateAttributes }) => { const $upload = useRef(); const [loading, toggleLoading] = useToggle(false); - const onResize = useCallback((size) => { - updateAttributes({ height: size.height, width: size.width }); - }, []); + const onResize = useCallback( + (size) => { + updateAttributes({ height: size.height, width: size.width }); + }, + [updateAttributes] + ); const selectFile = useCallback(() => { if (!isEditable || error || src) return; isEditable && $upload.current.click(); }, [isEditable, error, src]); - const handleFile = useCallback(async (e) => { - const file = e.target.files && e.target.files[0]; + const handleFile = useCallback( + async (e) => { + const file = e.target.files && e.target.files[0]; - const fileInfo = { - fileName: extractFilename(file.name), - fileSize: file.size, - fileType: file.type, - fileExt: extractFileExtension(file.name), - }; + const fileInfo = { + fileName: extractFilename(file.name), + fileSize: file.size, + fileType: file.type, + fileExt: extractFileExtension(file.name), + }; - toggleLoading(true); + toggleLoading(true); - try { - const src = await uploadFile(file); - const size = await getImageWidthHeight(file); - updateAttributes({ ...fileInfo, ...size, src }); - toggleLoading(false); - } catch (error) { - updateAttributes({ error: '图片上传失败:' + (error && error.message) || '未知错误' }); - toggleLoading(false); - } - }, []); + try { + const src = await uploadFile(file); + const size = await getImageWidthHeight(file); + updateAttributes({ ...fileInfo, ...size, src }); + toggleLoading(false); + } catch (error) { + updateAttributes({ error: '图片上传失败:' + (error && error.message) || '未知错误' }); + toggleLoading(false); + } + }, + [updateAttributes, toggleLoading] + ); useEffect(() => { if (!src && !hasTrigger) { selectFile(); updateAttributes({ hasTrigger: true }); } - }, [src, hasTrigger]); + }, [src, hasTrigger, selectFile, updateAttributes]); return ( diff --git a/packages/client/src/tiptap/wrappers/katex/index.tsx b/packages/client/src/tiptap/wrappers/katex/index.tsx index 5bf64ff9..1fd270ea 100644 --- a/packages/client/src/tiptap/wrappers/katex/index.tsx +++ b/packages/client/src/tiptap/wrappers/katex/index.tsx @@ -32,7 +32,7 @@ export const KatexWrapper = ({ editor, node, updateAttributes }) => { ) : ( 点击输入公式 ), - [text] + [text, formatText] ); const onVisibleChange = useCallback( @@ -42,7 +42,7 @@ export const KatexWrapper = ({ editor, node, updateAttributes }) => { updateAttributes({ defaultShowPicker: false }); } }, - [defaultShowPicker, updateAttributes, createUser, user] + [defaultShowPicker, toggleVisible, updateAttributes, createUser, user] ); useEffect(() => { @@ -50,7 +50,7 @@ export const KatexWrapper = ({ editor, node, updateAttributes }) => { toggleVisible(true); setTimeout(() => ref.current?.focus(), 100); } - }, [defaultShowPicker, createUser, user]); + }, [defaultShowPicker, toggleVisible, createUser, user]); return ( diff --git a/packages/client/src/tiptap/wrappers/mention-list/index.tsx b/packages/client/src/tiptap/wrappers/mention-list/index.tsx index 4913951e..eb3109f7 100644 --- a/packages/client/src/tiptap/wrappers/mention-list/index.tsx +++ b/packages/client/src/tiptap/wrappers/mention-list/index.tsx @@ -81,3 +81,5 @@ export const MentionList: React.FC = forwardRef((props, ref) => { ); }); + +MentionList.displayName = 'MentionList'; diff --git a/packages/client/src/tiptap/wrappers/menu-list/index.tsx b/packages/client/src/tiptap/wrappers/menu-list/index.tsx index 45717fdb..905b8255 100644 --- a/packages/client/src/tiptap/wrappers/menu-list/index.tsx +++ b/packages/client/src/tiptap/wrappers/menu-list/index.tsx @@ -87,3 +87,5 @@ export const MenuList: React.FC = forwardRef((props, ref) => { ); }); + +MenuList.displayName = 'MenuList'; diff --git a/packages/client/src/tiptap/wrappers/mind/index.tsx b/packages/client/src/tiptap/wrappers/mind/index.tsx index 6557dd32..1eebd3a6 100644 --- a/packages/client/src/tiptap/wrappers/mind/index.tsx +++ b/packages/client/src/tiptap/wrappers/mind/index.tsx @@ -47,7 +47,7 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => { style={{ ...INHERIT_SIZE_STYLE, overflow: 'hidden' }} > ); - }, [loading, error, width, height]); + }, [loading, error]); const onResize = useCallback( (size) => { @@ -69,11 +69,12 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => { .catch((e) => { setError(e); }); - }, []); + }, [toggleLoading]); // 初始化渲染 useEffect(() => { - if (loading || !$container.current) return; + const container = $container.current; + if (loading || !container) return; const onChange = () => { updateAttributes({ data: mind.getAllData() }); @@ -89,8 +90,8 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => { isEnter = false; }; - $container.current.addEventListener('onmouseenter', onMouseEnter); - $container.current.addEventListener('onMouseLeave', onMouseLeave); + container.addEventListener('onmouseenter', onMouseEnter); + container.addEventListener('onMouseLeave', onMouseLeave); try { mind = new window.MindElixir({ @@ -115,16 +116,18 @@ export const MindWrapper = ({ editor, node, updateAttributes }) => { } return () => { - if ($container.current) { - $container.current.removeEventListener('onmouseenter', onMouseEnter); - $container.current.removeEventListener('onMouseLeave', onMouseLeave); + if (container) { + container.removeEventListener('onmouseenter', onMouseEnter); + container.removeEventListener('onMouseLeave', onMouseLeave); } if (mind) { mind.destroy(); } }; - }, [loading, editor, updateAttributes]); + // data 的更新交给下方 effect + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [loading, editor, updateAttributes, toggleLoading]); useEffect(() => { const mind = $mind.current; diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/linkDiv.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/linkDiv.ts index 0021d7a7..30111db8 100644 --- a/packages/client/src/tiptap/wrappers/mind/mind-elixir/linkDiv.ts +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/linkDiv.ts @@ -14,8 +14,8 @@ import { SIDE, GAP, TURNPOINT_R, PRIMARY_NODE_HORIZONTAL_GAP, PRIMARY_NODE_VERTI * @param {object} primaryNode process the specific primary node only */ export default function linkDiv(primaryNode) { - var primaryNodeHorizontalGap = this.primaryNodeHorizontalGap || PRIMARY_NODE_HORIZONTAL_GAP; - var primaryNodeVerticalGap = this.primaryNodeVerticalGap || PRIMARY_NODE_VERTICAL_GAP; + const primaryNodeHorizontalGap = this.primaryNodeHorizontalGap || PRIMARY_NODE_HORIZONTAL_GAP; + const primaryNodeVerticalGap = this.primaryNodeVerticalGap || PRIMARY_NODE_VERTICAL_GAP; console.time('linkDiv'); const root = this.root; root.style.cssText = `top:${10000 - root.offsetHeight / 2}px;left:${10000 - root.offsetWidth / 2}px;`; diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/nodeMenu.tsx b/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/nodeMenu.tsx index eb816f67..b432519e 100644 --- a/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/nodeMenu.tsx +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/nodeMenu.tsx @@ -86,6 +86,7 @@ const Toolbar = ({ mind, toggleBold, setFontColor, setBackgroundColor, setLink } return () => { mind.bus.removeListener('selectNode', listener); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/utils/dom.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/utils/dom.ts index 5be4e1d9..9cf555c3 100644 --- a/packages/client/src/tiptap/wrappers/mind/mind-elixir/utils/dom.ts +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/utils/dom.ts @@ -137,6 +137,7 @@ export function createInputDiv(tpc: Topic) { div.addEventListener('blur', () => { if (!div) return; // 防止重复blur const node = tpc.nodeObj; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const topic = div.textContent!.trim(); if (topic === '') node.topic = origin; else node.topic = topic; diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/utils/index.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/utils/index.ts index 2968860f..30ed8006 100644 --- a/packages/client/src/tiptap/wrappers/mind/mind-elixir/utils/index.ts +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/utils/index.ts @@ -51,11 +51,12 @@ export function refreshIds(data: NodeObj) { } export const throttle = (fn: (any) => void, wait: number) => { - var pre = Date.now(); + let pre = Date.now(); return function () { - var context = this; - var args = arguments; - var now = Date.now(); + const context = this; + // eslint-disable-next-line prefer-rest-params + const args = arguments; + const now = Date.now(); if (now - pre >= wait) { fn.apply(context, args); pre = Date.now(); @@ -78,7 +79,7 @@ export function getArrowPoints(p3x: number, p3y: number, p4x: number, p4y: numbe } const arrowLength = 20; const arrowAngle = 30; - var a1 = angle + arrowAngle; + const a1 = angle + arrowAngle; const a2 = angle - arrowAngle; return { x1: p4x + Math.cos((Math.PI * a1) / 180) * arrowLength, diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/utils/pubsub.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/utils/pubsub.ts index b50ccfd0..64a96dec 100644 --- a/packages/client/src/tiptap/wrappers/mind/mind-elixir/utils/pubsub.ts +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/utils/pubsub.ts @@ -11,19 +11,19 @@ Bus.prototype = { }, fire: function (type, ...payload) { if (this.handlers[type] instanceof Array) { - var handlers = this.handlers[type]; - for (var i = 0; i < handlers.length; i++) { + const handlers = this.handlers[type]; + for (let i = 0; i < handlers.length; i++) { handlers[i](...payload); } } }, removeListener: function (type, handler) { if (!this.handlers[type]) return; - var handlers = this.handlers[type]; + const handlers = this.handlers[type]; if (!handler) { handlers.length = 0; } else if (handlers.length) { - for (var i = 0; i < handlers.length; i++) { + for (let i = 0; i < handlers.length; i++) { if (handlers[i] === handler) { this.handlers[type].splice(i, 1); } diff --git a/packages/client/src/tiptap/wrappers/status/index.tsx b/packages/client/src/tiptap/wrappers/status/index.tsx index 5c4f22a4..82a4155c 100644 --- a/packages/client/src/tiptap/wrappers/status/index.tsx +++ b/packages/client/src/tiptap/wrappers/status/index.tsx @@ -72,7 +72,7 @@ export const StatusWrapper = ({ editor, node, updateAttributes }) => { updateAttributes({ defaultShowPicker: false }); } }, - [defaultShowPicker, updateAttributes, createUser, user] + [defaultShowPicker, toggleVisible, updateAttributes, createUser, user] ); useEffect(() => { @@ -80,7 +80,7 @@ export const StatusWrapper = ({ editor, node, updateAttributes }) => { toggleVisible(true); setTimeout(() => ref.current?.focus(), 100); } - }, [defaultShowPicker, createUser, user]); + }, [defaultShowPicker, toggleVisible, createUser, user]); useEffect(() => { if (visible) {