From c840aa140bf054fa3bbcac34410d564633016d13 Mon Sep 17 00:00:00 2001 From: fantasticit Date: Sun, 9 Apr 2023 12:13:13 +0800 Subject: [PATCH] close #232 --- .../client/src/tiptap/editor/tocs/index.tsx | 8 ++-- .../client/src/tiptap/editor/tocs/util.ts | 44 ++++++++++++++----- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/packages/client/src/tiptap/editor/tocs/index.tsx b/packages/client/src/tiptap/editor/tocs/index.tsx index 265bee73..aa13776d 100644 --- a/packages/client/src/tiptap/editor/tocs/index.tsx +++ b/packages/client/src/tiptap/editor/tocs/index.tsx @@ -9,7 +9,7 @@ import { TableOfContents } from 'tiptap/core/extensions/table-of-contents'; import { findNode } from 'tiptap/prose-utils'; import styles from './index.module.scss'; -import { flattenHeadingsToTree } from './util'; +import { flattenHeadingsToTree, parseHeadingsToTocs } from './util'; interface IHeading { level: number; @@ -124,7 +124,7 @@ export const Tocs: React.FC<{ editor: Editor; getContainer: () => HTMLElement }> editor.view.dispatch(transaction); setHeadings(headings); - setNestedHeadings(flattenHeadingsToTree(headings)); + setNestedHeadings(parseHeadingsToTocs(headings)); }, [editor]); useEffect(() => { @@ -161,7 +161,7 @@ export const Tocs: React.FC<{ editor: Editor; getContainer: () => HTMLElement }> ? headings.map((toc) => { return ( @@ -171,7 +171,7 @@ export const Tocs: React.FC<{ editor: Editor; getContainer: () => HTMLElement }> /> ); }) - : nestedHeadings.map((toc) => )} + : nestedHeadings.map((toc) => )} ); diff --git a/packages/client/src/tiptap/editor/tocs/util.ts b/packages/client/src/tiptap/editor/tocs/util.ts index d651dc22..485fb22b 100644 --- a/packages/client/src/tiptap/editor/tocs/util.ts +++ b/packages/client/src/tiptap/editor/tocs/util.ts @@ -1,18 +1,38 @@ -export const flattenHeadingsToTree = (tocs) => { - const result = []; - const levels = [result]; +export const parseHeadingsToTocs = (headings) => { + const list = JSON.parse(JSON.stringify(headings)); + const ret = []; - tocs.forEach((o) => { - let offset = -1; - let parent = levels[o.level + offset]; + list.forEach((heading, index) => { + const prev = list[index - 1]; - while (!parent) { - offset -= 1; - parent = levels[o.level + offset]; + if (!prev) { + ret.push(heading); + } else { + if (prev.level < heading.level) { + heading.parent = prev; + prev.children = prev.children || []; + prev.children.push(heading); + } else { + let parent = prev.parent; + + let shouldContinue = true; + + while (shouldContinue) { + if (!parent) { + shouldContinue = false; + ret.push(heading); + } else if (parent.level < heading.level) { + heading.parent = parent; + parent.children = parent.children || []; + parent.children.push(heading); + shouldContinue = false; + } else { + parent = parent.parent; + } + } + } } - - parent.push({ ...o, children: (levels[o.level] = []) }); }); - return result; + return ret; };