-
Notifications
You must be signed in to change notification settings - Fork 71
feat(mind):为编辑器添加插入思维导图功能 #293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
kagol
merged 26 commits into
opentiny:ospp-2025/flowchart
from
shenyaofeng:ospp-2025/flowchart
Aug 7, 2025
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
d9b8b61
feat: add insert flowChart and mindChart
shenyaofeng c2a1639
fix: update mindmap style
shenyaofeng 52e7239
fix: update mindmap ability
shenyaofeng f225469
fix: update mindmap node error
shenyaofeng 2fb6c36
fix:flow content delete and edit
shenyaofeng 13db14b
fix: add mindmap adjust size
shenyaofeng 2f4d886
fix:node content delete
shenyaofeng ef86d9a
fix(mind): 调整思维导图文件结构
shenyaofeng 2f84edb
fix:删除防抖函数
shenyaofeng ab00d0e
fix:更新mind
shenyaofeng ad953be
fix:添加右键删除节点内容
shenyaofeng 3e4e33f
fix:快捷键添加思维导图
shenyaofeng e34b6d6
fix:删除工具栏
shenyaofeng 7e02c27
Merge branch 'ospp-2025/flowchart' of https://github.com/opentiny/tin…
shenyaofeng c9e4343
fix(mind):更新快捷键插入思维导图图标
shenyaofeng d5829b1
fix(mind):取消硬编码
shenyaofeng 7227b2a
fix:更新依赖包
shenyaofeng ce3d2de
fix(mind):完善国际化
shenyaofeng ad38183
fix(mind-map):更新模块名称与将国际化和样式放入mind-map文件夹中
shenyaofeng 9450055
fix(mind-map):规范思维导图相关变量名称
shenyaofeng 5ee0db1
fix(mind-map):删除思维导图多余样式文件
shenyaofeng f4aacc5
fix(mind-map):规范思维导图相关变量名称
shenyaofeng a7c759a
fix(mind-map):规范思维导图相关类名称
shenyaofeng df69f4f
fix(mind-map):删除打印
shenyaofeng f127b1b
fix(mind-map):规范思维导图样式文件名称
shenyaofeng 369af95
fix(mind-map):调整思维导图控制面板图标与样式
shenyaofeng File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
packages/fluent-editor/src/modules/mind-map/formats/mind-map-blot.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| import type { Root } from 'parchment' | ||
| import type { BlockEmbed as TypeBlockEmbed } from 'quill/blots/block' | ||
| import type FluentEditor from '../../../core/fluent-editor' | ||
| import Quill from 'quill' | ||
| import SimpleMindMap from 'simple-mind-map' | ||
| import Drag from 'simple-mind-map/src/plugins/Drag.js' | ||
| import Export from 'simple-mind-map/src/plugins/Export.js' | ||
| import { initContextMenu } from '../modules/context-menu' | ||
| import { createControlPanel } from '../modules/control-panel' | ||
| import '../style/mind-map.scss' | ||
|
|
||
| const BlockEmbed = Quill.import('blots/embed') as typeof TypeBlockEmbed | ||
|
|
||
| class MindMapPlaceholderBlot extends BlockEmbed { | ||
| static blotName = 'mind-map-placeholder' | ||
| static tagName = 'div' | ||
| static className = 'ql-mind-map' | ||
| mindMap: SimpleMindMap | null = null | ||
| data: any | ||
| zoomCount = 0 | ||
| contextMenu: HTMLElement | null = null | ||
| currentNode: any = null | ||
|
|
||
| constructor(scroll: Root, domNode: HTMLElement) { | ||
| super(scroll, domNode) | ||
| this.domNode.classList.add('ql-mind-map-container') | ||
| this.domNode.style.height = '500px' | ||
| this.domNode.style.border = '1px solid #e8e8e8' | ||
| this.data = MindMapPlaceholderBlot.value(this.domNode) | ||
| this.initMindMap() | ||
| } | ||
|
|
||
| static value(domNode: HTMLElement): any { | ||
| const dataStr = JSON.parse(domNode.getAttribute('data-mind-map')) | ||
| return dataStr.root ? dataStr.root : dataStr | ||
| } | ||
|
|
||
| static create(value: any): HTMLElement { | ||
| const node = super.create() as HTMLElement | ||
| if (value) { | ||
| node.setAttribute('data-mind-map', JSON.stringify(value)) | ||
| } | ||
| return node | ||
| } | ||
|
|
||
| initMindMap(): void { | ||
| if (this.domNode.isConnected) { | ||
| this.insertMindMapEditor() | ||
| } | ||
| else { | ||
| const observer = new MutationObserver(() => { | ||
| if (this.domNode.isConnected) { | ||
| this.insertMindMapEditor() | ||
| observer.disconnect() | ||
| } | ||
| }) | ||
| observer.observe(document.body, { childList: true, subtree: true }) | ||
| } | ||
| } | ||
|
|
||
| insertMindMapEditor(): void { | ||
| this.domNode.style.width = '100%' | ||
| this.domNode.style.height = '500px' | ||
| while (this.domNode.firstChild) { | ||
| this.domNode.removeChild(this.domNode.firstChild) | ||
| } | ||
| SimpleMindMap.usePlugin(Drag).usePlugin(Export) | ||
| this.mindMap = new SimpleMindMap ({ | ||
| el: this.domNode, | ||
| mousewheelAction: 'zoom', | ||
| disableMouseWheelZoom: true, | ||
| data: this.data, | ||
| } as any) | ||
|
|
||
| const handleScroll = () => { | ||
| if (this.mindMap && this.domNode && this.domNode.isConnected) { | ||
| this.mindMap.getElRectInfo() | ||
| } | ||
| } | ||
|
|
||
| window.addEventListener('scroll', handleScroll, { passive: true }) | ||
|
|
||
| this.domNode.addEventListener('remove', () => { | ||
| window.removeEventListener('scroll', handleScroll) | ||
| }) | ||
| const quill = this.scroll as unknown as FluentEditor | ||
| createControlPanel(this, quill) // 创建控制面板 | ||
| initContextMenu(this, quill) // 初始化右键菜单 | ||
| this.mindMap.on('node_tree_render_end', () => { | ||
| this.data = this.mindMap.getData({}) | ||
| this.domNode.setAttribute('data-mind-map', JSON.stringify(this.data)) | ||
| this.scroll.update([], {}) | ||
| }) | ||
| if (this.mindMap) { | ||
| this.mindMap.setData(this.data) | ||
| } | ||
| } | ||
|
|
||
| value(): any { | ||
| return this.data | ||
| } | ||
| } | ||
|
|
||
| Quill.register(MindMapPlaceholderBlot) | ||
|
|
||
| export default MindMapPlaceholderBlot |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| export const MIND_MAP_EN_US = { | ||
| 'mindMap.contextMenu.copy': 'Copy', | ||
| 'mindMap.contextMenu.cut': 'Cut', | ||
| 'mindMap.contextMenu.paste': 'Paste', | ||
| 'mindMap.contextMenu.deleteContent': 'Delete', | ||
| 'mindMap.controlPanel.zoomOut': 'Out', | ||
| 'mindMap.controlPanel.zoomIn': 'In', | ||
| 'mindMap.controlPanel.fit': 'Fit', | ||
| 'mindMap.controlPanel.back': 'Back', | ||
| 'mindMap.controlPanel.forward': 'Forward', | ||
| 'mindMap.controlPanel.export': 'Export', | ||
| 'mindMap.controlPanel.import': 'Import', | ||
| 'mindMap.controlPanel.inserChildNode': 'Child', | ||
| 'mindMap.controlPanel.inserNode': 'Node', | ||
| 'mindMap.controlPanel.inserParentNode': 'Parent', | ||
| 'mindMap.controlPanel.removeNode': 'Remove', | ||
| 'mindMap.controlPanel.zoomOutTitle': 'Zoom Out View', | ||
| 'mindMap.controlPanel.zoomInTitle': 'Zoom In View', | ||
| 'mindMap.controlPanel.fitTitle': 'Fit View Size', | ||
| 'mindMap.controlPanel.backTitle': 'Step Back', | ||
| 'mindMap.controlPanel.forwardTitle': 'Step Forward', | ||
| 'mindMap.controlPanel.exportTitle': 'Export Mind Map', | ||
| 'mindMap.controlPanel.importTitle': 'Import Mind Map', | ||
| 'mindMap.controlPanel.inserChildNodeTitle': 'Insert Child Node', | ||
| 'mindMap.controlPanel.inserNodeTitle': 'Insert Sibling Node', | ||
| 'mindMap.controlPanel.inserParentNodeTitle': 'Insert Parent Node', | ||
| 'mindMap.controlPanel.removeNodeTitle': 'Delete Current Node', | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import { MIND_MAP_EN_US } from './en-us' | ||
| import { MIND_MAP_ZH_CN } from './zh-cn' | ||
|
|
||
| export function registerMindMapI18N(I18N: any) { | ||
| I18N.register({ | ||
| 'en-US': MIND_MAP_EN_US, | ||
| 'zh-CN': MIND_MAP_ZH_CN, | ||
| }, false) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| export const MIND_MAP_ZH_CN = { | ||
| 'mindMap.contextMenu.copy': '复制', | ||
| 'mindMap.contextMenu.cut': '剪切', | ||
| 'mindMap.contextMenu.paste': '粘贴', | ||
| 'mindMap.contextMenu.deleteContent': '删除', | ||
| 'mindMap.controlPanel.zoomOut': '缩小', | ||
| 'mindMap.controlPanel.zoomIn': '放大', | ||
| 'mindMap.controlPanel.fit': '适应', | ||
| 'mindMap.controlPanel.back': '上一步', | ||
| 'mindMap.controlPanel.forward': '下一步', | ||
| 'mindMap.controlPanel.export': '导出', | ||
| 'mindMap.controlPanel.import': '导入', | ||
| 'mindMap.controlPanel.inserChildNode': '子节点', | ||
| 'mindMap.controlPanel.inserNode': '同级节点', | ||
| 'mindMap.controlPanel.inserParentNode': '父节点', | ||
| 'mindMap.controlPanel.removeNode': '删除', | ||
| 'mindMap.controlPanel.zoomOutTitle': '缩小视图', | ||
| 'mindMap.controlPanel.zoomInTitle': '放大视图', | ||
| 'mindMap.controlPanel.fitTitle': '适应视图大小', | ||
| 'mindMap.controlPanel.backTitle': '后退一步', | ||
| 'mindMap.controlPanel.forwardTitle': '前进一步', | ||
| 'mindMap.controlPanel.exportTitle': '导出思维导图', | ||
| 'mindMap.controlPanel.importTitle': '导入思维导图', | ||
| 'mindMap.controlPanel.inserChildNodeTitle': '插入子节点', | ||
| 'mindMap.controlPanel.inserNodeTitle': '插入同级节点', | ||
| 'mindMap.controlPanel.inserParentNodeTitle': '插入父节点', | ||
| 'mindMap.controlPanel.removeNodeTitle': '删除当前节点', | ||
| } |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import type Quill from 'quill' | ||
| import './formats/mind-map-blot' | ||
|
|
||
| export class MindMapModule { | ||
| quill: Quill | ||
| toolbar: any | ||
|
|
||
| constructor(quill: Quill, options: any) { | ||
| this.quill = quill | ||
| this.toolbar = quill.getModule('toolbar') | ||
| const domNode = document.querySelector('.ql-mind-map') | ||
|
|
||
| if (domNode) { | ||
| domNode.addEventListener('click', () => { | ||
| this.insertMindMapEditor() | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| public insertMindMapEditor(): void { | ||
| const range = this.quill.getSelection() | ||
| if (range) { | ||
| const defaultData = { | ||
| data: { | ||
| text: '根节点', | ||
| expand: true, | ||
| uid: '36bae545-da0b-4c08-be14-ff05f7f05d0a', | ||
| isActive: false, | ||
| }, | ||
| children: [ | ||
| { | ||
| data: { | ||
| text: '二级节点', | ||
| uid: 'ef0895d2-b5cc-4214-b0ee-e29f8f02420d', | ||
| expand: true, | ||
| richText: false, | ||
| isActive: false, | ||
| }, | ||
| children: [], | ||
| }, | ||
| ], | ||
| smmVersion: '0.14.0-fix.1', | ||
| } | ||
| this.quill.insertEmbed(range.index, 'mind-map-placeholder', defaultData, 'user') | ||
| this.quill.setSelection(range.index + 1, 0) | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.