diff --git a/packages/client/global.d.ts b/packages/client/global.d.ts index 8964b54d..820cc6e9 100644 --- a/packages/client/global.d.ts +++ b/packages/client/global.d.ts @@ -1,3 +1,3 @@ interface Window { - kityminder: any; + MindElixir: any; } diff --git a/packages/client/src/components/icons/IconMindCenter.tsx b/packages/client/src/components/icons/IconMindCenter.tsx new file mode 100644 index 00000000..d85c7ef5 --- /dev/null +++ b/packages/client/src/components/icons/IconMindCenter.tsx @@ -0,0 +1,21 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconMindCenter: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconMindFull.tsx b/packages/client/src/components/icons/IconMindFull.tsx new file mode 100644 index 00000000..a59059a1 --- /dev/null +++ b/packages/client/src/components/icons/IconMindFull.tsx @@ -0,0 +1,17 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconMindFull: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconMindLeft.tsx b/packages/client/src/components/icons/IconMindLeft.tsx new file mode 100644 index 00000000..491c2e27 --- /dev/null +++ b/packages/client/src/components/icons/IconMindLeft.tsx @@ -0,0 +1,17 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconMindLeft: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconMindRight.tsx b/packages/client/src/components/icons/IconMindRight.tsx new file mode 100644 index 00000000..dbee4b12 --- /dev/null +++ b/packages/client/src/components/icons/IconMindRight.tsx @@ -0,0 +1,17 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconMindRight: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/IconMindSide.tsx b/packages/client/src/components/icons/IconMindSide.tsx new file mode 100644 index 00000000..0172df37 --- /dev/null +++ b/packages/client/src/components/icons/IconMindSide.tsx @@ -0,0 +1,14 @@ +import { Icon } from '@douyinfe/semi-ui'; + +export const IconMindSide: React.FC<{ style?: React.CSSProperties }> = ({ style = {} }) => { + return ( + + + + } + /> + ); +}; diff --git a/packages/client/src/components/icons/index.tsx b/packages/client/src/components/icons/index.tsx index 380417df..6ccd142c 100644 --- a/packages/client/src/components/icons/index.tsx +++ b/packages/client/src/components/icons/index.tsx @@ -52,3 +52,9 @@ export * from './IconCountdown'; export * from './IconDrawBoard'; export * from './IconCallout'; export * from './IconStructure'; + +export * from './IconMindLeft'; +export * from './IconMindRight'; +export * from './IconMindSide'; +export * from './IconMindFull'; +export * from './IconMindCenter'; diff --git a/packages/client/src/pages/feature/excel.tsx b/packages/client/src/pages/feature/excel.tsx new file mode 100644 index 00000000..5201731f --- /dev/null +++ b/packages/client/src/pages/feature/excel.tsx @@ -0,0 +1,39 @@ +import type { NextPage } from 'next'; +import React, { useEffect, useMemo, useRef } from 'react'; +import { SingleColumnLayout } from 'layouts/single-column'; + +const Page: NextPage = () => { + const $container = useRef(); + + useEffect(() => { + import('mind-elixir').then((module) => { + const MindElixir = module.default; + const ME = new MindElixir({ + el: '#js-mind-map', + direction: MindElixir.LEFT, + data: { nodeData: { id: '078b6f27dc8acf92', topic: '中心节点', root: true, children: [] }, linkData: {} }, + draggable: true, // default true + contextMenu: true, // default true + toolBar: true, // default true + nodeMenu: false, // default true + keypress: true, // default true + locale: 'zh_CN', + }); + ME.init(); + + setTimeout(() => { + console.log(ME, ME.getAllData()); + }, 1000); + }); + }, []); + + return ( + +
+ 1 +
+
+ ); +}; + +export default Page; diff --git a/packages/client/src/tiptap/extensions/mind.ts b/packages/client/src/tiptap/extensions/mind.ts index 6a4b9498..0d0ec1ae 100644 --- a/packages/client/src/tiptap/extensions/mind.ts +++ b/packages/client/src/tiptap/extensions/mind.ts @@ -5,10 +5,8 @@ import { MindWrapper } from 'tiptap/wrappers/mind'; import { getDatasetAttribute } from 'tiptap/prose-utils'; const DEFAULT_MIND_DATA = { - root: { data: { text: '中心节点' }, children: [] }, - template: 'default', - theme: 'classic', - version: '1.4.43', + nodeData: { topic: '中心节点', root: true, children: [] }, + linkData: {}, }; export interface IMindAttrs { diff --git a/packages/client/src/tiptap/menus/_components/color-picker/index.tsx b/packages/client/src/tiptap/menus/_components/color-picker/index.tsx index ddff878f..5f6924f6 100644 --- a/packages/client/src/tiptap/menus/_components/color-picker/index.tsx +++ b/packages/client/src/tiptap/menus/_components/color-picker/index.tsx @@ -87,7 +87,7 @@ export const ColorPicker: React.FC<{
onSetColor(null)}> diff --git a/packages/client/src/tiptap/prose-utils/uuid.ts b/packages/client/src/tiptap/prose-utils/uuid.ts new file mode 100644 index 00000000..34fee6c2 --- /dev/null +++ b/packages/client/src/tiptap/prose-utils/uuid.ts @@ -0,0 +1,15 @@ +export function uuid() { + var s = []; + + var hexDigits = '0123456789abcdef'; + + for (var 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(''); + return uuid; +} diff --git a/packages/client/src/tiptap/styles/kityminder.scss b/packages/client/src/tiptap/styles/kityminder.scss deleted file mode 100644 index 7b4c4740..00000000 --- a/packages/client/src/tiptap/styles/kityminder.scss +++ /dev/null @@ -1,2141 +0,0 @@ -/* stylelint-disable */ -.km-view { - position: relative; - font-family: STHeitiSC-Light, STHeiti, Hei, 'Heiti SC', 'Microsoft Yahei', Arial, sans-serif; - user-select: none; - user-select: none; -} - -.km-view .km-receiver { - position: absolute; - top: -99999px; - left: -99999px; - width: 20px; - height: 20px; - margin: 0; - outline: none; -} - -.km-view image { - cursor: zoom-in; -} - -.km-image-viewer { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 99999; - background: rgb(0 0 0 / 75%); -} - -.km-image-viewer .km-image-viewer-container { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - overflow: auto; - text-align: center; - white-space: nowrap; -} - -.km-image-viewer .km-image-viewer-container::before { - display: inline-block; - width: 0; - height: 100%; - font-size: 0; - vertical-align: middle; - content: ''; -} - -.km-image-viewer .km-image-viewer-container img { - vertical-align: middle; - cursor: zoom-out; -} - -.km-image-viewer .km-image-viewer-container img.limited { - max-width: 100%; - max-height: 100%; - cursor: zoom-in; -} - -.km-image-viewer .km-image-viewer-toolbar { - z-index: 1; - text-align: right; - background: rgb(0 0 0 / 75%); - transition: all 0.25s; -} - -.km-image-viewer .km-image-viewer-toolbar.hidden { - opacity: 0; - transform: translate(0, -100%); -} - -.km-image-viewer .km-image-viewer-btn { - width: 44px; - height: 44px; - cursor: pointer; - background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjY0IiBoZWlnaHQ9Ijg4IiB2aWV3Qm94PSIwIDAgMjY0IDg4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjx0aXRsZT5kZWZhdWx0LXNraW4gMjwvdGl0bGU+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48Zz48cGF0aCBkPSJNNjcuMDAyIDU5LjV2My43NjhjLTYuMzA3Ljg0LTkuMTg0IDUuNzUtMTAuMDAyIDkuNzMyIDIuMjItMi44MyA1LjU2NC01LjA5OCAxMC4wMDItNS4wOThWNzEuNUw3MyA2NS41ODUgNjcuMDAyIDU5LjV6IiBpZD0iU2hhcGUiIGZpbGw9IiNmZmYiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMTMgMjl2LTVoMnYzaDN2MmgtNXpNMTMgMTVoNXYyaC0zdjNoLTJ2LTV6TTMxIDE1djVoLTJ2LTNoLTN2LTJoNXpNMzEgMjloLTV2LTJoM3YtM2gydjV6IiBpZD0iU2hhcGUiLz48L2c+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTYyIDI0djVoLTJ2LTNoLTN2LTJoNXpNNjIgMjBoLTV2LTJoM3YtM2gydjV6TTcwIDIwdi01aDJ2M2gzdjJoLTV6TTcwIDI0aDV2MmgtM3YzaC0ydi01eiIvPjwvZz48cGF0aCBkPSJNMjAuNTg2IDY2bC01LjY1Ni01LjY1NiAxLjQxNC0xLjQxNEwyMiA2NC41ODZsNS42NTYtNS42NTYgMS40MTQgMS40MTRMMjMuNDE0IDY2bDUuNjU2IDUuNjU2LTEuNDE0IDEuNDE0TDIyIDY3LjQxNGwtNS42NTYgNS42NTYtMS40MTQtMS40MTRMMjAuNTg2IDY2eiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xMTEuNzg1IDY1LjAzTDExMCA2My41bDMtMy41aC0xMHYtMmgxMGwtMy0zLjUgMS43ODUtMS40NjhMMTE3IDU5bC01LjIxNSA2LjAzeiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xNTIuMjE1IDY1LjAzTDE1NCA2My41bC0zLTMuNWgxMHYtMmgtMTBsMy0zLjUtMS43ODUtMS40NjhMMTQ3IDU5bDUuMjE1IDYuMDN6IiBmaWxsPSIjZmZmIi8+PGc+PHBhdGggaWQ9IlJlY3RhbmdsZS0xMSIgZmlsbD0iI2ZmZiIgZD0iTTE2MC45NTcgMjguNTQzbC0zLjI1LTMuMjUtMS40MTMgMS40MTQgMy4yNSAzLjI1eiIvPjxwYXRoIGQ9Ik0xNTIuNSAyN2MzLjAzOCAwIDUuNS0yLjQ2MiA1LjUtNS41cy0yLjQ2Mi01LjUtNS41LTUuNS01LjUgMi40NjItNS41IDUuNSAyLjQ2MiA1LjUgNS41IDUuNXoiIGlkPSJPdmFsLTEiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTUwIDIxaDV2MWgtNXoiLz48L2c+PGc+PHBhdGggZD0iTTExNi45NTcgMjguNTQzbC0xLjQxNCAxLjQxNC0zLjI1LTMuMjUgMS40MTQtMS40MTQgMy4yNSAzLjI1eiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xMDguNSAyN2MzLjAzOCAwIDUuNS0yLjQ2MiA1LjUtNS41cy0yLjQ2Mi01LjUtNS41LTUuNS01LjUgMi40NjItNS41IDUuNSAyLjQ2MiA1LjUgNS41IDUuNXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTA2IDIxaDV2MWgtNXoiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTA5LjA0MyAxOS4wMDhsLS4wODUgNS0xLS4wMTcuMDg1LTV6Ii8+PC9nPjwvZz48L2c+PC9zdmc+); - border: 0; - outline: 0; -} - -.km-image-viewer .km-image-viewer-toolbar { - position: absolute; - top: 0; - right: 0; - left: 0; -} - -.km-image-viewer .km-image-viewer-close { - background-position: 0 -44px; -} - -.km-editor { - position: relative; - z-index: 2; - overflow: hidden; -} - -.km-editor > .mask { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - display: block; - background-color: transparent; -} - -.km-editor > .receiver { - position: absolute; - top: 0; - left: 0; - z-index: -1000; - width: auto; - max-width: 300px; - min-height: 1.4em; - padding: 3px 5px; - margin-top: -5px; - margin-left: -3px; - overflow: hidden; - font-size: 14px; - line-height: 1.4em; - word-break: break-all; - word-wrap: break-word; - pointer-events: none; - background: white; - border: none; - outline: none; - opacity: 0; - box-shadow: 0 0 20px rgb(0 0 0 / 50%); - box-sizing: border-box; - user-select: text; -} - -.km-editor > .receiver.debug { - z-index: 0; - background: none; - outline: 1px solid green; - opacity: 1; -} - -.km-editor > .receiver.input { - z-index: 999; - pointer-events: all; - background: white; - color: #333; - outline: none; - opacity: 1; -} - -div.minder-editor-container { - position: absolute; - top: 40px; - right: 0; - bottom: 0; - left: 0; - font-family: Arial, 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; -} - -.minder-editor { - position: absolute; - top: 92px; - right: 0; - bottom: 0; - left: 0; -} - -.minder-viewer { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; -} - -.control-panel { - position: absolute; - top: 0; - right: 0; - bottom: 0; - width: 250px; - border-left: 1px solid #ccc; -} - -.minder-divider { - position: absolute; - top: 0; - right: 250px; - bottom: 0; - width: 2px; - cursor: ew-resize; - background-color: #fbfbfb; -} - -.panel-body { - padding: 10px; -} - -.upload-image { - position: absolute; - z-index: -1; - width: 0.1px; - height: 0.1px; - overflow: hidden; - opacity: 0; -} - -.top-tab .nav-tabs { - height: 32px; - background-color: #e1e1e1; - border: 0; -} - -.top-tab .nav-tabs li { - margin: 0; -} - -.top-tab .nav-tabs li a { - padding: 6px 15px; - margin: 0; - vertical-align: middle; - border: 0; - border-radius: 0; -} - -.top-tab .nav-tabs li a:hover, -.top-tab .nav-tabs li a:focus { - background: inherit; - border: 0; -} - -.top-tab .nav-tabs li.active a { - background-color: #fff; - border: 0; -} - -.top-tab .nav-tabs li.active a:hover, -.top-tab .nav-tabs li.active a:focus { - border: 0; -} - -.top-tab .tab-content { - height: 60px; - background-color: #fff; - border-bottom: 1px solid #dbdbdb; -} - -.top-tab .tab-pane { - font-size: 0; -} - -.km-btn-group { - display: inline-block; - padding: 0 5px; - margin: 5px 0; - vertical-align: middle; - border-right: 1px dashed #eee; -} - -.km-btn-item { - display: inline-block; - margin: 0 3px; - font-size: 0; - cursor: default; -} - -.km-btn-item[disabled] { - opacity: 0.5; -} - -.km-btn-item[disabled]:hover, -.km-btn-item[disabled]:active { - background-color: #fff; -} - -.km-btn-item .km-btn-icon { - display: inline-block; - - /* background: url(images/icons.png) no-repeat; */ - background-position: 0 20px; - width: 20px; - height: 20px; - padding: 2px; - margin: 1px; - vertical-align: middle; -} - -.km-btn-item .km-btn-caption { - display: inline-block; - font-size: 12px; - vertical-align: middle; -} - -.km-btn-item:hover { - background-color: #eff3fa; -} - -.km-btn-item:active { - background-color: #c4d0ee; -} - -.do-group { - width: 38px; -} - -.undo .km-btn-icon { - background-position: 0 -1240px; -} - -.redo .km-btn-icon { - background-position: 0 -1220px; -} - -.append-group { - width: 212px; -} - -.append-child-node .km-btn-icon { - background-position: 0 0; -} - -.append-sibling-node .km-btn-icon { - background-position: 0 -20px; -} - -.append-parent-node .km-btn-icon { - background-position: 0 -40px; -} - -.arrange-group { - width: 64px; -} - -.arrange-up .km-btn-icon { - background-position: 0 -280px; -} - -.arrange-down .km-btn-icon { - background-position: 0 -300px; -} - -.operation-group { - width: 64px; -} - -.edit-node .km-btn-icon { - background-position: 0 -60px; -} - -.remove-node .km-btn-icon { - background-position: 0 -80px; -} - -.btn-group-vertical { - margin: 5px; - vertical-align: middle; -} - -.btn-group-vertical .hyperlink, -.btn-group-vertical .hyperlink-caption { - width: 40px; - padding: 0; - margin: 0; - border: none !important; - border-radius: 0 !important; -} - -.btn-group-vertical .hyperlink:hover, -.btn-group-vertical .hyperlink-caption:hover { - background-color: #eff3fa; -} - -.btn-group-vertical .hyperlink:active, -.btn-group-vertical .hyperlink-caption:active { - background-color: #c4d0ee; -} - -.btn-group-vertical .hyperlink.active, -.btn-group-vertical .hyperlink-caption.active { - box-shadow: none; - background-color: #eff3fa; -} - -.btn-group-vertical .hyperlink { - height: 25px; - - /* background: url(images/icons.png) no-repeat center -100px; */ -} - -.btn-group-vertical .hyperlink-caption { - height: 20px; -} - -.btn-group-vertical .hyperlink-caption .caption { - font-size: 12px; -} - -.open > .dropdown-toggle.btn-default { - background-color: #eff3fa; -} - -.btn-group-vertical .image-btn, -.btn-group-vertical .image-btn-caption { - width: 40px; - padding: 0; - margin: 0; - border: none !important; - border-radius: 0 !important; -} - -.btn-group-vertical .image-btn:hover, -.btn-group-vertical .image-btn-caption:hover { - background-color: #eff3fa; -} - -.btn-group-vertical .image-btn:active, -.btn-group-vertical .image-btn-caption:active { - background-color: #c4d0ee; -} - -.btn-group-vertical .image-btn.active, -.btn-group-vertical .image-btn-caption.active { - box-shadow: none; - background-color: #eff3fa; -} - -.btn-group-vertical .image-btn { - height: 25px; - - /* background: url(images/icons.png) no-repeat center -125px; */ -} - -.btn-group-vertical .image-btn-caption { - height: 20px; -} - -.btn-group-vertical .image-btn-caption .caption { - font-size: 12px; -} - -.image-preview { - display: block; - max-width: 50%; -} - -.modal-body .tab-pane { - padding-top: 15px; - font-size: inherit; -} - -.search-result { - height: 370px; - margin-top: 15px; - overflow: hidden; -} - -.search-result ul { - height: 100%; - padding: 0; - margin: 0; - overflow-x: hidden; - overflow-y: auto; - clear: both; - list-style: none; -} - -.search-result ul li { - position: relative; - display: block; - float: left; - width: 130px; - height: 130px; - padding: 0; - margin: 6px; - overflow: hidden; - font-size: 12px; - line-height: 130px; - text-align: center; - vertical-align: top; - list-style: none; - cursor: pointer; - border: 2px solid #fcfcfc; -} - -.search-result ul li.selected { - border: 2px solid #fc8383; -} - -.search-result ul li img { - max-width: 126px; - max-height: 130px; - vertical-align: middle; -} - -.search-result ul li span { - position: absolute; - right: 0; - bottom: 0; - left: 0; - display: block; - height: 20px; - overflow: hidden; - line-height: 20px; - color: white; - text-overflow: ellipsis; - word-break: break-all; - white-space: nowrap; - background: rgb(0 0 0 / 50%); - opacity: 0; - transform: translate(0, 20px); - transform: translate(0, 20px); - transform: translate(0, 20px); - transition: all 0.2s ease; - transition: all 0.2s ease; -} - -.search-result ul li:hover span { - opacity: 1; - transform: translate(0, 0); - transform: translate(0, 0); - transform: translate(0, 0); -} -@media (min-width: 768px) { - .form-inline .form-control { - width: 422px; - } -} - -.btn-group-vertical { - margin: 5px; - vertical-align: top; -} - -.btn-group-vertical.note-btn-group { - border-right: 1px dashed #eee; - padding-right: 5px; -} - -.btn-group-vertical .note-btn, -.btn-group-vertical .note-btn-caption { - width: 40px; - padding: 0; - margin: 0; - border: none !important; - border-radius: 0 !important; -} - -.btn-group-vertical .note-btn:hover, -.btn-group-vertical .note-btn-caption:hover { - background-color: #eff3fa; -} - -.btn-group-vertical .note-btn:active, -.btn-group-vertical .note-btn-caption:active { - background-color: #c4d0ee; -} - -.btn-group-vertical .note-btn.active, -.btn-group-vertical .note-btn-caption.active { - box-shadow: none; - background-color: #eff3fa; -} - -.btn-group-vertical .note-btn { - height: 25px; - - /* background: url(images/icons.png) no-repeat center -1150px; */ -} - -.btn-group-vertical .note-btn-caption { - height: 20px; -} - -.btn-group-vertical .note-btn-caption .caption { - font-size: 12px; -} - -.open > .dropdown-toggle.btn-default { - background-color: #eff3fa; -} - -.gfm-render { - font-size: 12px; - line-height: 1.8em; - color: #333; - user-select: text; -} - -.gfm-render blockquote, -.gfm-render ul, -.gfm-render table, -.gfm-render p, -.gfm-render pre, -.gfm-render hr { - margin: 1em 0; - cursor: text; -} - -.gfm-render blockquote:first-child:last-child, -.gfm-render ul:first-child:last-child, -.gfm-render table:first-child:last-child, -.gfm-render p:first-child:last-child, -.gfm-render pre:first-child:last-child, -.gfm-render hr:first-child:last-child { - margin: 0; -} - -.gfm-render img { - max-width: 100%; -} - -.gfm-render a { - color: blue; -} - -.gfm-render a:hover { - color: red; -} - -.gfm-render blockquote { - display: block; - padding-left: 10px; - margin-left: 2em; - font-style: italic; - color: #da8e68; - border-left: 4px solid #e4ad91; -} - -.gfm-render ul, -.gfm-render ol { - padding-left: 3em; -} - -.gfm-render table { - width: 100%; - border-collapse: collapse; - margin: 1em 0; -} - -.gfm-render table th, -.gfm-render table td { - padding: 2px 4px; - border: 1px solid #666; -} - -.gfm-render table th { - background: rgb(45 141 234 / 20%); -} - -.gfm-render table tr:nth-child(even) td { - background: rgb(45 141 234 / 3%); -} - -.gfm-render em { - color: red; -} - -.gfm-render del { - color: #999; -} - -.gfm-render pre { - padding: 5px; - word-break: break-all; - word-wrap: break-word; - background: rgb(45 141 234 / 10%); - border-radius: 5px; -} - -.gfm-render code { - /* display: inline-block; */ - padding: 0 5px; - background: rgb(45 141 234 / 10%); - border-radius: 3px; -} - -.gfm-render pre code { - background: none; -} - -.gfm-render hr { - border: none; - border-top: 1px solid #ccc; -} - -.gfm-render .highlight { - color: red; - background: yellow; -} - -.km-note { - position: absolute; - top: 92px; - right: 0; - bottom: 0; - left: auto; - z-index: 3; - width: 300px; - padding: 5px 10px; - background: white; - border-left: 1px solid #babfcd; -} - -.km-note.panel { - padding: 0; - margin: 0; -} - -.km-note.panel .panel-heading h3 { - display: inline-block; -} - -.km-note.panel .panel-heading .close-note-editor { - display: inline-block; - float: right; - width: 15px; - height: 15px; -} - -.km-note.panel .panel-heading .close-note-editor:hover { - cursor: pointer; -} - -.km-note.panel .panel-body { - padding: 0; -} - -.km-note .CodeMirror { - position: absolute; - top: 41px; - bottom: 0; - height: auto; - font-family: consolas; - font-size: 14px; - line-height: 1.3em; - cursor: text; -} - -.km-note-tips { - padding: 3px 8px; - color: #ccc; -} - -#previewer-content { - position: absolute; - z-index: 10; - max-width: 400px; - max-height: 200px; - padding: 5px 15px; - overflow: auto; - font-size: 12px; - line-height: 1.8em; - color: #333; - word-break: break-all; - background: #ffd; - border-radius: 5px; - box-shadow: 0 0 15px rgb(0 0 0 / 50%); - user-select: text; -} - -#previewer-content blockquote, -#previewer-content ul, -#previewer-content table, -#previewer-content p, -#previewer-content pre, -#previewer-content hr { - margin: 1em 0; - cursor: text; -} - -#previewer-content blockquote:first-child:last-child, -#previewer-content ul:first-child:last-child, -#previewer-content table:first-child:last-child, -#previewer-content p:first-child:last-child, -#previewer-content pre:first-child:last-child, -#previewer-content hr:first-child:last-child { - margin: 0; -} - -#previewer-content img { - max-width: 100%; -} - -#previewer-content a { - color: blue; -} - -#previewer-content a:hover { - color: red; -} - -#previewer-content blockquote { - display: block; - padding-left: 10px; - margin-left: 2em; - font-style: italic; - color: #da8e68; - border-left: 4px solid #e4ad91; -} - -#previewer-content ul, -#previewer-content ol { - padding-left: 3em; -} - -#previewer-content table { - width: 100%; - border-collapse: collapse; - margin: 1em 0; -} - -#previewer-content table th, -#previewer-content table td { - padding: 2px 4px; - border: 1px solid #666; -} - -#previewer-content table th { - background: rgb(45 141 234 / 20%); -} - -#previewer-content table tr:nth-child(even) td { - background: rgb(45 141 234 / 3%); -} - -#previewer-content em { - color: red; -} - -#previewer-content del { - color: #999; -} - -#previewer-content pre { - padding: 5px; - word-break: break-all; - word-wrap: break-word; - background: rgb(45 141 234 / 10%); - border-radius: 5px; -} - -#previewer-content code { - /* display: inline-block; */ - padding: 0 5px; - background: rgb(45 141 234 / 10%); - border-radius: 3px; -} - -#previewer-content pre code { - background: none; -} - -#previewer-content hr { - border: none; - border-top: 1px solid #ccc; -} - -#previewer-content .highlight { - color: red; - background: yellow; -} - -#previewer-content.ng-hide { - top: -99999px !important; - left: -99999px !important; - display: block !important; -} - -.panel-body { - padding: 10px; -} - -.tab-content .km-priority { - display: inline-block; - width: 140px; - margin: 5px; - font-size: inherit; - vertical-align: middle; - border-right: 1px dashed #eee; -} - -.tab-content .km-priority .km-priority-item { - padding: 1px; - margin: 0 1px; -} - -.tab-content .km-priority .km-priority-item .km-priority-icon { - /* background: url(images/iconpriority.png) repeat-y; */ - background-color: transparent; -} - -.tab-content .km-priority .km-priority-item .km-priority-icon.priority-0 { - background-position: 0 20px; -} - -.tab-content .km-priority .km-priority-item .km-priority-icon.priority-1 { - background-position: 0 0; -} - -.tab-content .km-priority .km-priority-item .km-priority-icon.priority-2 { - background-position: 0 -20px; -} - -.tab-content .km-priority .km-priority-item .km-priority-icon.priority-3 { - background-position: 0 -40px; -} - -.tab-content .km-priority .km-priority-item .km-priority-icon.priority-4 { - background-position: 0 -60px; -} - -.tab-content .km-priority .km-priority-item .km-priority-icon.priority-5 { - background-position: 0 -80px; -} - -.tab-content .km-priority .km-priority-item .km-priority-icon.priority-6 { - background-position: 0 -100px; -} - -.tab-content .km-priority .km-priority-item .km-priority-icon.priority-7 { - background-position: 0 -120px; -} - -.tab-content .km-priority .km-priority-item .km-priority-icon.priority-8 { - background-position: 0 -140px; -} - -.tab-content .km-priority .km-priority-item .km-priority-icon.priority-9 { - background-position: 0 -160px; -} - -.tab-content .km-progress { - display: inline-block; - width: 140px; - margin: 5px; - font-size: inherit; - vertical-align: middle; - border-right: 1px dashed #eee; -} - -.tab-content .km-progress .km-progress-item { - padding: 1px; - margin: 0 1px; -} - -.tab-content .km-progress .km-progress-item .km-progress-icon { - /* background: url(images/iconprogress.png) repeat-y; */ - background-color: transparent; -} - -.tab-content .km-progress .km-progress-item .km-progress-icon.progress-0 { - background-position: 0 20px; -} - -.tab-content .km-progress .km-progress-item .km-progress-icon.progress-1 { - background-position: 0 0; -} - -.tab-content .km-progress .km-progress-item .km-progress-icon.progress-2 { - background-position: 0 -20px; -} - -.tab-content .km-progress .km-progress-item .km-progress-icon.progress-3 { - background-position: 0 -40px; -} - -.tab-content .km-progress .km-progress-item .km-progress-icon.progress-4 { - background-position: 0 -60px; -} - -.tab-content .km-progress .km-progress-item .km-progress-icon.progress-5 { - background-position: 0 -80px; -} - -.tab-content .km-progress .km-progress-item .km-progress-icon.progress-6 { - background-position: 0 -100px; -} - -.tab-content .km-progress .km-progress-item .km-progress-icon.progress-7 { - background-position: 0 -120px; -} - -.tab-content .km-progress .km-progress-item .km-progress-icon.progress-8 { - background-position: 0 -140px; -} - -.tab-content .km-progress .km-progress-item .km-progress-icon.progress-9 { - background-position: 0 -160px; -} - -.resource-editor { - display: inline-block; - margin: 5px; - vertical-align: middle; -} - -.resource-editor .input-group, -.resource-editor .km-resource { - font-size: 12px; -} - -.resource-editor .input-group { - width: 168px; - height: 20px; -} - -.resource-editor .resource-dropdown { - position: relative; - width: 168px; - margin-top: -1px; - border: 1px solid #ccc; - border-bottom-right-radius: 4px; - border-bottom-left-radius: 4px; -} - -.resource-editor .resource-dropdown .km-resource { - position: absolute; - width: 154px; - max-height: 500px; - padding: 0; - margin-bottom: 3px; - overflow: scroll; - list-style-type: none; -} - -.resource-editor .resource-dropdown .km-resource.open { - z-index: 3; - background-color: #fff; -} - -.resource-editor .resource-dropdown .km-resource li { - display: inline-block; - padding: 1px 2px; - margin: 2px 3px; - border-radius: 4px; -} - -.resource-editor .resource-dropdown .km-resource li[disabled] { - opacity: 0.5; -} - -.resource-editor .resource-dropdown .resource-caret { - display: block; - float: right; - width: 12px; - height: 24px; - padding: 8px 1px; - vertical-align: middle; -} - -.resource-editor .resource-dropdown .resource-caret:hover { - background-color: #eff3fa; -} - -.resource-editor .resource-dropdown .resource-caret:active { - background-color: #c4d0ee; -} - -.resource-editor input.form-control, -.resource-editor .btn { - font-size: 12px; -} - -.resource-editor input.form-control { - height: 24px; - padding: 2px 4px; - border-bottom-left-radius: 0; -} - -.resource-editor .input-group-btn { - line-height: 24px; -} - -.resource-editor .input-group-btn .btn { - height: 24px; - padding: 2px 4px; - border-bottom-right-radius: 0; -} - -.temp-panel { - display: inline-block; - margin: 5px 5px 5px 10px; - vertical-align: middle; - border-right: 1px dashed #eee; -} - -.temp-list { - min-width: 124px; -} - -.temp-item-wrap { - display: inline-block; - width: 50px; - height: 40px; - padding: 0 2px; - margin: 5px; -} - -.temp-item { - display: inline-block; - width: 50px; - height: 40px; - - /* background-image: url(images/template.png); */ - background-repeat: no-repeat; -} - -.temp-item.default { - background-position: 0 0; -} - -.temp-item.structure { - background-position: -50px 0; -} - -.temp-item.filetree { - background-position: -100px 0; -} - -.temp-item.right { - background-position: -150px 0; -} - -.temp-item.fish-bone { - background-position: -200px 0; -} - -.temp-item.tianpan { - background-position: -250px 0; -} - -.current-temp-item { - width: 74px; - padding: 0 0 0 5px; - border: 1px solid #fff; -} - -.current-temp-item:hover { - background-color: #eff3fa; -} - -.current-temp-item[disabled] { - opacity: 0.5; -} - -.current-temp-item .caret { - margin-left: 5px; -} - -.temp-item-selected { - background-color: #87a9da; -} - -.theme-panel { - display: inline-block; - height: 42px; - padding: 0 5px 0 0; - margin: 5px; - vertical-align: middle; - border-right: 1px dashed #eee; -} - -.theme-list { - min-width: 162px; -} - -div a.theme-item { - display: inline-block; - width: 70px; - height: 30px; - padding: 0 5px; - font-size: 12px; - line-height: 30px; - color: #000; - text-align: center; - text-decoration: none; - cursor: pointer; -} - -.theme-item-selected { - width: 100px; - padding: 6px 7px; - border: 1px solid #fff; -} - -.theme-item-selected:hover { - background-color: #eff3fa; -} - -.theme-item-selected .caret { - margin-left: 5px; -} - -.theme-item-selected[disabled] { - opacity: 0.5; -} - -.theme-item-wrap { - display: inline-block; - width: 80px; - height: 40px; - padding: 5px; -} - -.theme-item-wrap:hover { - background-color: #eff3fa; -} - -.readjust-layout { - display: inline-block; - padding: 0 10px 0 5px; - vertical-align: middle; - border-right: 1px dashed #eee; -} - -.btn-icon { - display: block; - width: 25px; - height: 25px; - margin-left: 12px; -} - -.btn-label { - font-size: 12px; -} - -.btn-wrap { - display: inline-block; - width: 50px; - height: 42px; - text-decoration: none; - cursor: pointer; -} - -.btn-wrap[disabled] span { - opacity: 0.5; -} - -.btn-wrap[disabled] { - cursor: default; -} - -.btn-wrap[disabled]:hover { - background-color: transparent; -} - -.btn-wrap[disabled]:active { - background-color: transparent; -} - -.btn-wrap:link { - text-decoration: none; -} - -.btn-wrap:visited { - text-decoration: none; -} - -.btn-wrap:hover { - text-decoration: none; - background-color: #eff3fa; -} - -.btn-wrap:active { - background-color: #c4d0ee; -} - -.reset-layout-icon { - /* background: url(images/icons.png) no-repeat; */ - background-position: 0 -150px; -} - -.style-operator { - display: inline-block; - padding: 0 5px; - vertical-align: middle; - border-right: 1px dashed #eee; -} - -.style-operator .clear-style { - vertical-align: middle; -} - -.clear-style-icon { - /* background: url(images/icons.png) no-repeat; */ - background-position: 0 -175px; -} - -.s-btn-group-vertical { - display: inline-block; - vertical-align: middle; -} - -.s-btn-icon { - display: inline-block; - width: 20px; - height: 20px; - margin-right: 3px; - vertical-align: middle; -} - -.s-btn-label { - display: inline-block; - font-size: 12px; - vertical-align: middle; -} - -.s-btn-wrap { - display: inline-block; - padding: 0 5px 0 3px; - font-size: 0; - text-decoration: none; -} - -.s-btn-wrap[disabled] span { - opacity: 0.5; -} - -.s-btn-wrap[disabled] { - cursor: default; -} - -.s-btn-wrap[disabled]:hover { - background-color: transparent; -} - -.s-btn-wrap[disabled]:active { - background-color: transparent; -} - -.s-btn-wrap:hover { - text-decoration: none; - background-color: #eff3fa; -} - -.s-btn-wrap:active { - background-color: #c4d0ee; -} - -.copy-style-icon { - /* background: url(images/icons.png) no-repeat; */ - background-position: 0 -200px; -} - -.paste-style-wrap { - display: block; -} - -.paste-style-icon { - /* background: url(images/icons.png) no-repeat; */ - background-position: 0 -220px; -} - -.font-operator { - display: inline-block; - width: 170px; - padding: 0 5px; - font-size: 12px; - vertical-align: middle; -} - -.font-operator .font-size-list { - display: inline-block; - padding: 2px 4px; - border: 1px solid #eee; -} - -.font-operator .font-family-list { - display: inline-block; - padding: 2px 4px; - border: 1px solid #eee; -} - -.current-font-item a { - display: inline-block; - text-decoration: none; -} - -.current-font-family { - width: 75px; - height: 18px; - overflow: hidden; - vertical-align: bottom; -} - -.current-font-size { - width: 32px; - height: 18px; - overflow: hidden; - vertical-align: bottom; -} - -.current-font-item[disabled] { - opacity: 0.5; -} - -.font-item { - line-height: 1em; - text-align: left; -} - -.font-item-selected { - background-color: #87a9da; -} - -.font-bold, -.font-italics { - display: inline-block; - margin: 0 3px; - - /* background: url(images/icons.png) no-repeat; */ - cursor: pointer; -} - -.font-bold:hover, -.font-italics:hover { - background-color: #eff3fa; -} - -.font-bold:active, -.font-italics:active { - background-color: #c4d0ee; -} - -.font-bold[disabled], -.font-italics[disabled] { - opacity: 0.5; -} - -.font-bold { - background-position: 0 -240px; -} - -.font-italics { - background-position: 0 -260px; -} - -.font-bold-selected, -.font-italics-selected { - background-color: #87a9da; -} - -.font-color-wrap { - display: inline-block; - width: 30px; - height: 22px; - margin: 3px 3px 0 0; - font-size: 0; - vertical-align: middle; - border: 1px #efefef solid; - user-select: none; - user-select: none; - user-select: none; - user-select: none; -} - -.font-color-wrap[disabled] { - opacity: 0.5; -} - -.font-color-wrap .quick-font-color { - display: inline-block; - width: 20px; - height: 16px; - font-size: 14px; - line-height: 16px; - color: #000; - text-align: center; - vertical-align: top; - cursor: default; -} - -.font-color-wrap .quick-font-color:hover { - background-color: #eff3fa; -} - -.font-color-wrap .quick-font-color:active { - background-color: #c4d0ee; -} - -.font-color-wrap .quick-font-color[disabled] { - opacity: 0.5; -} - -.font-color-wrap .font-color-preview { - display: inline-block; - width: 12px; - height: 2px; - margin: 0 4px; - background-color: #000; -} - -.font-color-wrap .font-color-preview[disabled] { - opacity: 0.5; -} - -.font-color { - display: inline-block; - width: 8px; - height: 16px; -} - -.font-color:hover { - background-color: #eff3fa; -} - -.font-color:active { - background-color: #c4d0ee; -} - -.font-color[disabled] { - opacity: 0.5; -} - -.font-color .caret { - margin-top: 7px; - margin-left: -2px; -} - -.bg-color-wrap { - display: inline-block; - width: 30px; - height: 22px; - margin: 3px 3px 0 0; - font-size: 0; - vertical-align: middle; - border: 1px #efefef solid; - user-select: none; - user-select: none; - user-select: none; - user-select: none; -} - -.bg-color-wrap[disabled] { - opacity: 0.5; -} - -.bg-color-wrap .quick-bg-color { - display: inline-block; - width: 20px; - height: 16px; - font-size: 14px; - line-height: 16px; - color: #000; - text-align: center; - vertical-align: top; - cursor: default; - - /* background: url(images/icons.png) no-repeat center -1260px; */ -} - -.bg-color-wrap .quick-bg-color:hover { - background-color: #eff3fa; -} - -.bg-color-wrap .quick-bg-color:active { - background-color: #c4d0ee; -} - -.bg-color-wrap .quick-bg-color[disabled] { - opacity: 0.5; -} - -.bg-color-wrap .bg-color-preview { - display: inline-block; - width: 12px; - height: 2px; - margin: 0 4px; - background-color: #fff; -} - -.bg-color-wrap .bg-color-preview[disabled] { - opacity: 0.5; -} - -.bg-color { - display: inline-block; - width: 8px; - height: 16px; -} - -.bg-color:hover { - background-color: #eff3fa; -} - -.bg-color:active { - background-color: #c4d0ee; -} - -.bg-color[disabled] { - opacity: 0.5; -} - -.bg-color .caret { - margin-top: 7px; - margin-left: -2px; -} - -.btn-group-vertical { - margin: 5px; - vertical-align: middle; -} - -.btn-group-vertical .expand, -.btn-group-vertical .expand-caption { - width: 40px; - padding: 0; - margin: 0; - border: none !important; - border-radius: 0 !important; -} - -.btn-group-vertical .expand:hover, -.btn-group-vertical .expand-caption:hover { - background-color: #eff3fa; -} - -.btn-group-vertical .expand:active, -.btn-group-vertical .expand-caption:active { - background-color: #c4d0ee; -} - -.btn-group-vertical .expand.active, -.btn-group-vertical .expand-caption.active { - box-shadow: none; - background-color: #eff3fa; -} - -.btn-group-vertical .expand { - height: 25px; - - /* background: url(images/icons.png) no-repeat 0 -995px; */ - background-position-x: 50%; -} - -.btn-group-vertical .expand-caption { - height: 20px; -} - -.btn-group-vertical .expand-caption .caption { - font-size: 12px; -} - -.btn-group-vertical { - margin: 5px; - vertical-align: middle; -} - -.btn-group-vertical .select, -.btn-group-vertical .select-caption { - width: 40px; - padding: 0; - margin: 0; - border: none !important; - border-radius: 0 !important; -} - -.btn-group-vertical .select:hover, -.btn-group-vertical .select-caption:hover { - background-color: #eff3fa; -} - -.btn-group-vertical .select:active, -.btn-group-vertical .select-caption:active { - background-color: #c4d0ee; -} - -.btn-group-vertical .select.active, -.btn-group-vertical .select-caption.active { - box-shadow: none; - background-color: #eff3fa; -} - -.btn-group-vertical .select { - height: 25px; - - /* background: url(images/icons.png) no-repeat 7px -1175px; */ -} - -.btn-group-vertical .select-caption { - height: 20px; -} - -.btn-group-vertical .select-caption .caption { - font-size: 12px; -} - -.btn-group-vertical { - margin: 5px; - vertical-align: middle; -} - -.btn-group-vertical .search, -.btn-group-vertical .search-caption { - width: 40px; - padding: 0; - margin: 0; - border: none !important; - border-radius: 0 !important; -} - -.btn-group-vertical .search:hover, -.btn-group-vertical .search-caption:hover { - background-color: #eff3fa; -} - -.btn-group-vertical .search:active, -.btn-group-vertical .search-caption:active { - background-color: #c4d0ee; -} - -.btn-group-vertical .search.active, -.btn-group-vertical .search-caption.active { - box-shadow: none; - background-color: #eff3fa; -} - -.btn-group-vertical .search { - height: 25px; - - /* background: url(images/icons.png) no-repeat 0 -345px; */ - background-position-x: 50%; -} - -.btn-group-vertical .search-caption { - height: 20px; -} - -.btn-group-vertical .search-caption .caption { - font-size: 12px; -} - -.search-box { - position: relative; - top: 0; - z-index: 3; - float: right; - width: 360px; - height: 40px; - padding: 3px 6px; - background-color: #fff; - border: 1px solid #dbdbdb; - opacity: 1; -} - -.search-box .search-input-wrap, -.search-box .prev-and-next-btn { - float: left; -} - -.search-box .close-search { - float: right; - width: 16px; - height: 16px; - padding: 1px; - margin-top: 6px; - margin-right: 10px; - border-radius: 100%; -} - -.search-box .close-search .glyphicon { - top: -1px; -} - -.search-box .close-search:hover { - background-color: #efefef; -} - -.search-box .close-search:active { - background-color: #999; -} - -.search-box .search-input-wrap { - width: 240px; -} - -.search-box .prev-and-next-btn { - margin-left: 5px; -} - -.search-box .prev-and-next-btn .btn:focus { - outline: none; -} - -.search-box .search-addon { - background-color: #fff; -} - -.tool-group { - padding: 0; -} - -.tool-group[disabled] { - opacity: 0.5; -} - -.tool-group .tool-group-item { - display: inline-block; - border-radius: 4px; -} - -.tool-group .tool-group-item .tool-group-icon { - width: 20px; - height: 20px; - padding: 2px; - margin: 1px; -} - -.tool-group .tool-group-item:hover { - background-color: #eff3fa; -} - -.tool-group .tool-group-item:active { - background-color: #c4d0ee; -} - -.tool-group .tool-group-item.active { - background-color: #c4d0ee; -} - -.nav-bar { - position: absolute; - bottom: 10px; - left: 10px; - z-index: 10; - width: 35px; - height: 240px; - padding: 5px 0; - color: #fff; - background: #fc8383; - border-radius: 4px; - box-shadow: 3px 3px 10px rgb(0 0 0 / 20%); - transition: -webkit-transform 0.7s 0.1s ease; - transition: transform 0.7s 0.1s ease; -} - -.nav-bar .nav-btn { - width: 35px; - height: 24px; - line-height: 24px; - text-align: center; -} - -.nav-bar .nav-btn .icon { - display: block; - - /* background: url(images/icons.png); */ - width: 20px; - height: 20px; - margin: 2px auto; -} - -.nav-bar .nav-btn.active { - background-color: #5a6378; -} - -.nav-bar .zoom-in .icon { - background-position: 0 -730px; -} - -.nav-bar .zoom-out .icon { - background-position: 0 -750px; -} - -.nav-bar .hand .icon { - background-position: 0 -770px; - width: 25px; - height: 25px; - margin: 0 auto; -} - -.nav-bar .camera .icon { - background-position: 0 -870px; - width: 25px; - height: 25px; - margin: 0 auto; -} - -.nav-bar .nav-trigger .icon { - background-position: 0 -845px; - width: 25px; - height: 25px; - margin: 0 auto; -} - -.nav-bar .zoom-pan { - position: relative; - width: 2px; - height: 70px; - margin: 3px auto; - overflow: visible; - background: white; - box-shadow: 0 1px #e50000; -} - -.nav-bar .zoom-pan .origin { - position: absolute; - left: -9px; - width: 20px; - height: 8px; - margin-top: -4px; - background: transparent; -} - -.nav-bar .zoom-pan .origin::after { - position: absolute; - top: 3px; - left: 7px; - display: block; - width: 6px; - height: 2px; - background: white; - content: ' '; -} - -.nav-bar .zoom-pan .indicator { - position: absolute; - left: -3px; - width: 8px; - height: 8px; - margin-top: -4px; - background: white; - border-radius: 100%; -} - -.nav-previewer { - position: absolute; - bottom: 30px; - left: 45px; - z-index: 9; - width: 140px; - height: 120px; - padding: 1px; - cursor: crosshair; - background: #fff; - border-radius: 0 2px 2px 0; - box-shadow: 0 0 8px rgb(0 0 0 / 20%); - transition: -webkit-transform 0.7s 0.1s ease; - transition: transform 0.7s 0.1s ease; -} - -.nav-previewer.grab { - cursor: move; - cursor: grabbing; - cursor: grabbing; - cursor: grabbing; -} - -.hotbox { - position: absolute; - top: 0; - left: 0; - overflow: visible; - font-family: Arial, 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; -} - -.hotbox .state { - position: absolute; - display: none; - overflow: visible; -} - -.hotbox .state .center .button, -.hotbox .state .ring .button { - position: absolute; - width: 70px; - height: 70px; - margin-top: -35px; - margin-left: -35px; - border-radius: 100%; - box-shadow: 0 0 30px rgb(0 0 0 / 30%); -} - -.hotbox .state .center .label, -.hotbox .state .ring .label, -.hotbox .state .center .key, -.hotbox .state .ring .key { - display: block; - line-height: 1.4em; - text-align: center; - vertical-align: middle; -} - -.hotbox .state .center .label, -.hotbox .state .ring .label { - margin-top: 17px; - font-size: 16px; - font-weight: normal; - line-height: 1em; - color: black; -} - -.hotbox .state .center .key, -.hotbox .state .ring .key { - font-size: 12px; - color: #999; -} - -.hotbox .state .ring-shape { - position: absolute; - top: -25px; - left: -25px; - border: 25px solid rgb(0 0 0 / 30%); - border-radius: 100%; - box-sizing: content-box; -} - -.hotbox .state .top, -.hotbox .state .bottom { - position: absolute; - white-space: nowrap; -} - -.hotbox .state .top .button, -.hotbox .state .bottom .button { - position: relative; - display: inline-block; - padding: 8px 15px; - margin: 0 10px; - border-radius: 15px; - box-shadow: 0 0 30px rgb(0 0 0 / 30%); -} - -.hotbox .state .top .button .label, -.hotbox .state .bottom .button .label { - font-size: 14px; - line-height: 14px; - line-height: 1em; - color: black; - vertical-align: middle; -} - -.hotbox .state .top .button .key, -.hotbox .state .bottom .button .key { - margin-left: 3px; - font-size: 12px; - line-height: 12px; - color: #999; - vertical-align: middle; -} - -.hotbox .state .top .button .key::before, -.hotbox .state .bottom .button .key::before { - content: '('; -} - -.hotbox .state .top .button .key::after, -.hotbox .state .bottom .button .key::after { - content: ')'; -} - -.hotbox .state .button { - overflow: hidden; - cursor: default; - background: #f9f9f9; -} - -.hotbox .state .button .key, -.hotbox .state .button .label { - opacity: 0.3; -} - -.hotbox .state .button.enabled { - background: white; -} - -.hotbox .state .button.enabled .key, -.hotbox .state .button.enabled .label { - opacity: 1; -} - -.hotbox .state .button.enabled:hover { - background: #e87372; -} - -.hotbox .state .button.enabled:hover .label { - color: white; -} - -.hotbox .state .button.enabled:hover .key { - color: #fadfdf; -} - -.hotbox .state .button.enabled.selected { - animation: selected 0.1s ease; - background: #e45d5c; -} - -.hotbox .state .button.enabled.selected .label { - color: white; -} - -.hotbox .state .button.enabled.selected .key { - color: #fadfdf; -} - -.hotbox .state .button.enabled.pressed, -.hotbox .state .button.enabled:active { - background: #ff974d; -} - -.hotbox .state .button.enabled.pressed .label, -.hotbox .state .button.enabled:active .label { - color: white; -} - -.hotbox .state .button.enabled.pressed .key, -.hotbox .state .button.enabled:active .key { - color: #fff0e6; -} - -.hotbox .state.active { - display: block; -} - -@keyframes selected { - 0% { - transform: scale(1); - } - - 50% { - transform: scale(1.1); - } - - 100% { - transform: scale(1); - } -} - -.hotbox-key-receiver { - position: absolute; - top: -999999px; - left: -999999px; - width: 20px; - height: 20px; - margin: 0; - outline: none; -} diff --git a/packages/client/src/tiptap/styles/mind/context-menu.scss b/packages/client/src/tiptap/styles/mind/context-menu.scss new file mode 100644 index 00000000..30e2970f --- /dev/null +++ b/packages/client/src/tiptap/styles/mind/context-menu.scss @@ -0,0 +1,65 @@ +/* stylelint-disable */ +cmenu { + position: fixed; + top: 0; + left: 0; + z-index: 99; + width: 100%; + height: 100%; +} + +cmenu .menu-list { + position: fixed; + padding: 0; + margin: 0; + font: 300 15px Roboto, sans-serif; + color: #333; + list-style: none; + box-shadow: 0 12px 15px 0 rgb(0 0 0 / 20%); +} + +cmenu .menu-list * { + transition: color 0.4s, background-color 0.4s; +} + +cmenu .menu-list li { + min-width: 150px; + padding: 6px 10px; + overflow: hidden; + white-space: nowrap; + background-color: #fff; + border-bottom: 1px solid #ecf0f1; +} + +cmenu .menu-list li a { + color: #333; + text-decoration: none; +} + +cmenu .menu-list li.disabled { + color: #5e5e5e; + background-color: #f7f7f7; +} + +cmenu .menu-list li.disabled:hover { + cursor: default; + background-color: #f7f7f7; +} + +cmenu .menu-list li:hover { + cursor: pointer; + background-color: #ecf0f1; +} + +cmenu .menu-list li:first-child { + border-radius: 5px 5px 0 0; +} + +cmenu .menu-list li:last-child { + border-bottom: 0; + border-radius: 0 0 5px 5px; +} + +cmenu .menu-list li span:last-child { + float: right; +} diff --git a/packages/client/src/tiptap/styles/mind/index.scss b/packages/client/src/tiptap/styles/mind/index.scss new file mode 100644 index 00000000..cbaae83e --- /dev/null +++ b/packages/client/src/tiptap/styles/mind/index.scss @@ -0,0 +1,30 @@ +/* stylelint-disable */ +@import './context-menu.scss'; +@import './mobile-menu.scss'; +@import './node-menu.scss'; +@import './toolbar.scss'; +@import './mind.scss'; + +.map-container { + &.is-fullscreen { + position: fixed; + top: 0; + left: 0; + z-index: 1000; + width: 100vw; + height: 100vh; + } +} + +.map-container .map-canvas .selected { + outline: none !important; + border-color: rgb(9 109 217); +} + +.map-container .map-canvas root tpc { + line-height: 20px; +} + +#input-box { + color: #333 !important; +} diff --git a/packages/client/src/tiptap/styles/mind/mind.scss b/packages/client/src/tiptap/styles/mind/mind.scss new file mode 100644 index 00000000..19a8fa1d --- /dev/null +++ b/packages/client/src/tiptap/styles/mind/mind.scss @@ -0,0 +1,290 @@ +/* stylelint-disable */ +.mind-elixir { + position: relative; + -webkit-tap-highlight-color: rgb(0 0 0 / 0%); +} + +.mind-elixir .hyper-link { + text-decoration: none; +} + +.map-container { + width: 100%; + height: 100%; + overflow: scroll; + font-size: 15px; + user-select: none; +} + +.map-container::-webkit-scrollbar { + width: 0; + height: 0; +} + +.map-container .focus-mode { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: #fff; +} + +.map-container .map-canvas { + position: relative; + width: 20000px; + height: 20000px; + background-color: var(--semi-color-fill-0); + transform: scale(1); + user-select: none; + transition: all 0.3s; +} + +.map-container .map-canvas .selected { + outline: 2px solid #4dc4ff; +} + +.map-container .map-canvas root { + position: absolute; +} + +tpc { + border: 1px solid transparent; + + &::selection { + background-color: transparent !important; + } + + &.is-editing, + &.selected { + border: 1px solid rgb(9 109 217) !important; + + &::selection { + background-color: rgb(180 213 254 / 50%) !important; + } + } +} + +.map-container .map-canvas root tpc { + display: block; + padding: 10px 15px; + font-size: 25px; + color: #fff; + white-space: pre-wrap; + background-color: #3370ff; + border: 1px solid transparent; + border-radius: 5px; +} + +.map-container .map-canvas root tpc #input-box { + padding: 10px 15px; +} + +.map-container .box > grp { + position: absolute; +} + +.map-container .box > grp > t > tpc { + padding: 8px 10px; + margin: 0; + color: var(--semi-color-text-0); + background-color: var(--semi-color-fill-1); + border-radius: 5px; +} + +.map-container .box > grp > t > tpc #input-box { + padding: 8px 10px; +} + +.map-container .box .lhs { + direction: rtl; +} + +.map-container .box .lhs tpc { + direction: ltr; +} + +.map-container .box grp { + display: block; + pointer-events: none; +} + +.map-container .box children, +.map-container .box t { + display: inline-block; + vertical-align: middle; +} + +.map-container .box t { + position: relative; + padding: 0 15px; + margin-top: 10px; + cursor: pointer; +} + +.map-container .box t tpc { + position: relative; + display: block; + max-width: 800px; + padding: 5px; + line-height: 1; + color: var(--semi-color-text-1); + white-space: pre-wrap; + pointer-events: all; + border-radius: 3px; +} + +.map-container .box t tpc #input-box { + padding: 5px; +} + +.map-container .box t tpc .tags { + direction: ltr; +} + +.map-container .box t tpc .tags span { + display: inline-block; + height: 16px; + padding: 2px 4px; + margin: 0; + margin-top: 2px; + margin-right: 3px; + font-size: 12px; + line-height: 16px; + color: #276f86; + background: #d6f0f8; + border-radius: 3px; +} + +.map-container .box t tpc .icons { + display: inline-block; + direction: ltr; + margin-right: 10px; +} + +.map-container .box t tpc .insert-preview { + position: absolute; + left: 0; + z-index: 9; + width: 100%; +} + +.map-container .box t tpc .before { + top: -14px; + height: 14px; +} + +.map-container .box t tpc .show { + pointer-events: none; + background: #7ad5ff; + opacity: 0.7; +} + +.map-container .box t tpc .in { + top: 0; + height: 100%; +} + +.map-container .box t tpc .after { + bottom: -14px; + height: 14px; +} + +.map-container .box t epd { + position: absolute; + z-index: 9; + width: 12px; + height: 12px; + line-height: 8px; + color: #494c4f; + text-align: center; + pointer-events: all; + background-color: #fff; + border: 1px solid #4f4f4f; + border-radius: 50%; +} + +.map-container .box t epd.minus { + transition: all 0.3s; + opacity: 0; +} + +.map-container .box t epd.minus:hover { + opacity: 1; +} + +.map-container .icon { + width: 1em; + height: 1em; + overflow: hidden; + vertical-align: -0.15em; + fill: currentcolor; +} + +.map-container .svg2nd, +.map-container .svg3rd, +.map-container .topiclinks, +.map-container .linkcontroller { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 102%; +} + +.map-container .topiclinks, +.map-container .linkcontroller { + pointer-events: none; +} + +.map-container .topiclinks g, +.map-container .linkcontroller g { + pointer-events: all; +} + +.map-container .svg2nd, +.map-container .svg3rd { + z-index: -1; + pointer-events: none; +} + +.map-container .topiclinks *, +.map-container .linkcontroller * { + z-index: 100; +} + +.map-container .topiclinks g { + cursor: pointer; +} + +.down t, +.down children { + display: block !important; +} + +.down grp { + display: inline-block !important; +} + +.circle { + position: absolute; + width: 10px; + height: 10px; + margin-top: -5px; + margin-left: -5px; + cursor: pointer; + background: #aaa; + border-radius: 100%; +} + +#input-box { + position: absolute; + top: 0; + left: 0; + z-index: 11; + width: max-content; + max-width: 800px; + background-color: #fff; + direction: ltr; + user-select: auto; +} diff --git a/packages/client/src/tiptap/styles/mind/mobile-menu.scss b/packages/client/src/tiptap/styles/mind/mobile-menu.scss new file mode 100644 index 00000000..2267657d --- /dev/null +++ b/packages/client/src/tiptap/styles/mind/mobile-menu.scss @@ -0,0 +1,48 @@ +/* stylelint-disable */ +mmenu { + position: absolute; + bottom: 70px; + left: 20px; + z-index: 99; + padding: 0; + margin: 0; + overflow: hidden; + color: #333; + border-radius: 5px; + box-shadow: 0 12px 15px 0 rgb(0 0 0 / 20%); +} + +mmenu * { + transition: color 0.4s, background-color 0.4s; +} + +mmenu div { + float: left; + width: 30px; + padding: 8px; + overflow: hidden; + text-align: center; + white-space: nowrap; + background-color: #fff; + border-bottom: 1px solid #ecf0f1; +} + +mmenu div a { + color: #333; + text-decoration: none; +} + +mmenu div.disabled { + color: #5e5e5e; + background-color: #f7f7f7; +} + +mmenu div.disabled:hover { + cursor: default; + background-color: #f7f7f7; +} + +mmenu div:hover { + cursor: pointer; + background-color: #ecf0f1; +} diff --git a/packages/client/src/tiptap/styles/mind/node-menu.scss b/packages/client/src/tiptap/styles/mind/node-menu.scss new file mode 100644 index 00000000..612e0dc1 --- /dev/null +++ b/packages/client/src/tiptap/styles/mind/node-menu.scss @@ -0,0 +1,11 @@ +.node-toolbar-container { + position: absolute; + display: flex; + padding: 4px; + overflow-x: auto; + background-color: var(--semi-color-nav-bg); + border: 1px solid var(--semi-color-border); + border-radius: 3px; + align-items: center; + box-shadow: var(--box-shadow); +} diff --git a/packages/client/src/tiptap/styles/mind/toolbar.scss b/packages/client/src/tiptap/styles/mind/toolbar.scss new file mode 100644 index 00000000..96f62812 --- /dev/null +++ b/packages/client/src/tiptap/styles/mind/toolbar.scss @@ -0,0 +1,42 @@ +/* stylelint-disable */ +.toolbar { + position: absolute; + display: flex; + padding: 8px; + overflow-x: auto; + color: #fff; + background-color: var(--semi-color-nav-bg); + border: 1px solid var(--semi-color-border); + border-radius: 3px; + align-items: center; + box-shadow: var(--box-shadow); +} + +.toolbar span:active { + opacity: 0.5; +} + +.rb { + right: 20px; + bottom: 20px; + font-family: iconfont; +} + +.rb span + span { + margin-left: 10px; +} + +.lt { + top: 20px; + left: 20px; + font-size: 20px; + flex-direction: column; +} + +.lt span { + display: block; +} + +.lt span + span { + margin-top: 10px; +} diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/expose.js b/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/expose.js deleted file mode 100644 index ddaea0e9..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/expose.js +++ /dev/null @@ -1,3 +0,0 @@ -define('expose', function(require, exports, module) { - module.exports = window.HotBox = require('./hotbox'); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/hotbox.js b/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/hotbox.js deleted file mode 100644 index 62dd9b74..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/hotbox.js +++ /dev/null @@ -1,636 +0,0 @@ -define(function(require, exports, module) { - var key = require('./key'); - var KeyControl = require('./keycontrol'); - - /**** Dom Utils ****/ - function createElement(name) { - return document.createElement(name); - } - - function setElementAttribute(element, name, value) { - element.setAttribute(name, value); - } - - function getElementAttribute(element, name) { - return element.getAttribute(name); - } - - function addElementClass(element, name) { - element.classList.add(name); - } - - function removeElementClass(element, name) { - element.classList.remove(name); - } - - function appendChild(parent, child) { - parent.appendChild(child); - } - /*******************/ - - var IDLE = HotBox.STATE_IDLE = 'idle'; - var div = 'div'; - - /** - * Simple Formatter - */ - function format(template, args) { - if (typeof(args) != 'object') { - args = [].slice.apply(arguments, 1); - } - return String(template).replace(/\{(\w+)\}/g, function(match, name) { - return args[name] || match; - }); - } - - /** - * Hot Box Class - */ - function HotBox($container) { - if (typeof($container) == 'string') { - $container = document.querySelector($container); - } - if (!$container || !($container instanceof HTMLElement)) { - throw new Error('No container or not invalid container for hot box'); - } - - // 创建 HotBox Dom 解构 - var $hotBox = createElement(div); - addElementClass($hotBox, 'hotbox'); - appendChild($container, $hotBox); - - // 保存 Dom 解构和父容器 - this.$element = $hotBox; - this.$container = $container; - - // 标示是否是输入法状态 - this.isIME = false; - - /** - * @Desc: 增加一个browser用于判断浏览器类型,方便解决兼容性问题 - * @Editor: Naixor - * @Date: 2015.09.14 - */ - this.browser = { - sg: /se[\s\S]+metasr/.test(navigator.userAgent.toLowerCase()) - }; - - /* - * added by zhangbobell - * 2015.09.22 - * 增加父状态机,以解决在父 FSM 下状态控制的问题,最好的解决办法是增加一个函数队列 - * 将其中的函数一起执行。//TODO - * */ - this._parentFSM = {}; - - // 记录位置 - this.position = {}; - - // 已定义的状态(string => HotBoxState) - var _states = {}; - - // 主状态(HotBoxState) - var _mainState = null; - - // 当前状态(HotBoxState) - var _currentState = IDLE; - - // 当前状态堆栈 - var _stateStack = []; - - // 实例引用 - var _this = this; - var _controler; - - /** - * Controller: { - * constructor(hotbox: HotBox), - * active: () => void - * } - */ - function _control(Controller) { - if (_controler) { - _controler.active(); - return; - } - - Controller = Controller || KeyControl; - - _controler = new Controller(_this); - _controler.active(); - - $hotBox.onmousedown = function(e) { - e.stopPropagation(); - e.preventDefault(); - }; - - return _this; - } - - function _dispatchKey(e) { - var type = e.type.toLowerCase(); - e.keyHash = key.hash(e); - e.isKey = function(keyExpression) { - if (!keyExpression) return false; - var expressions = keyExpression.split(/\s*\|\s*/); - while(expressions.length) { - if (e.keyHash == key.hash(expressions.shift())) return true; - } - return false; - }; - e[type] = true; - // Boot: keyup and activeKey pressed on IDLE, active main state. - if (e.keyup && _this.activeKey && e.isKey(_this.activeKey) && _currentState == IDLE && _mainState) { - _activeState('main', { - x: $container.clientWidth / 2, - y: $container.clientHeight / 2 - }); - return; - } - var handleState = _currentState == IDLE ? _mainState : _currentState; - if (handleState) { - var handleResult = handleState.handleKeyEvent(e); - if (typeof(_this.onkeyevent) == 'function') { - e.handleResult = handleResult; - _this.onkeyevent(e, handleResult); - } - return handleResult; - } - return null; - } - - function _addState(name) { - if (!name) return _currentState; - if (name == IDLE) { - throw new Error('Can not define or use the `idle` state.'); - } - _states[name] = _states[name] || new HotBoxState(this, name); - if (name == 'main') { - _mainState = _states[name]; - } - return _states[name]; - } - - function _activeState(name, position) { - _this.position = position; - - // 回到 IDLE - if (name == IDLE) { - if (_currentState != IDLE) { - _stateStack.shift().deactive(); - _stateStack = []; - } - _currentState = IDLE; - } - // 回退一个状态 - else if (name == 'back') { - if (_currentState != IDLE) { - _currentState.deactive(); - _stateStack.shift(); - _currentState = _stateStack[0]; - if (_currentState) { - _currentState.active(); - } else { - _currentState = 'idle'; - } - } - } - // 切换到具体状态 - else { - if (_currentState != IDLE) { - _currentState.deactive(); - } - var newState = _states[name]; - _stateStack.unshift(newState); - if (typeof(_this.position) == 'function') { - position = _this.position(position); - } - newState.active(position); - _currentState = newState; - } - } - - function setParentFSM(fsm) { - _this._parentFSM = fsm; - } - - function getParentFSM() { - return _this._parentFSM; - } - - this.control = _control; - this.state = _addState; - this.active = _activeState; - this.dispatch = _dispatchKey; - this.setParentFSM = setParentFSM; - this.getParentFSM = getParentFSM; - this.activeKey = 'space'; - this.actionKey = 'space'; - } - - /** - * 表示热盒某个状态,包含这些状态需要的 Dom 对象 - */ - function HotBoxState(hotBox, stateName) { - - var BUTTON_SELECTED_CLASS = 'selected'; - var BUTTON_PRESSED_CLASS = 'pressed'; - var STATE_ACTIVE_CLASS = 'active'; - - // 状态容器 - var $state = createElement(div); - - // 四种可见的按钮容器 - var $center = createElement(div); - var $ring = createElement(div); - var $ringShape = createElement('div'); - var $top = createElement(div); - var $bottom = createElement(div); - - // 添加 CSS 类 - addElementClass($state, 'state'); - addElementClass($state, stateName); - addElementClass($center, 'center'); - addElementClass($ring, 'ring'); - addElementClass($ringShape, 'ring-shape'); - addElementClass($top, 'top'); - addElementClass($bottom, 'bottom'); - - // 摆放容器 - appendChild(hotBox.$element, $state); - appendChild($state, $ringShape); - appendChild($state, $center); - appendChild($state, $ring); - appendChild($state, $top); - appendChild($state, $bottom); - - // 记住状态名称 - this.name = stateName; - - // 五种按钮:中心,圆环,上栏,下栏,幕后 - var buttons = { - center: null, - ring: [], - top: [], - bottom: [], - behind: [] - }; - var allButtons = []; - var selectedButton = null; - var pressedButton = null; - - var stateActived = false; - // 布局,添加按钮后,标记需要布局 - var needLayout = true; - - function layout() { - var radius = buttons.ring.length * 15; - layoutRing(radius); - layoutTop(radius); - layoutBottom(radius); - indexPosition(); - needLayout = false; - - function layoutRing(radius) { - var ring = buttons.ring; - var step = 2 * Math.PI / ring.length; - - if (buttons.center) { - buttons.center.indexedPosition = [0, 0]; - } - - $ringShape.style.marginLeft = $ringShape.style.marginTop = -radius + 'px'; - $ringShape.style.width = $ringShape.style.height = (radius + radius) + 'px'; - - var $button, angle, x, y; - for (var i = 0; i < ring.length; i++) { - $button = ring[i].$button; - angle = step * i - Math.PI / 2; - x = radius * Math.cos(angle); - y = radius * Math.sin(angle); - ring[i].indexedPosition = [x, y]; - $button.style.left = x + 'px'; - $button.style.top = y + 'px'; - } - } - - function layoutTop(radius) { - var xOffset = -$top.clientWidth / 2; - var yOffset = -radius * 2 - $top.clientHeight / 2; - $top.style.marginLeft = xOffset + 'px'; - $top.style.marginTop = yOffset + 'px'; - buttons.top.forEach(function(topButton) { - var $button = topButton.$button; - topButton.indexedPosition = [xOffset + $button.offsetLeft + $button.clientWidth / 2, yOffset]; - }); - } - function layoutBottom(radius) { - var xOffset = -$bottom.clientWidth / 2; - var yOffset = radius * 2 - $bottom.clientHeight / 2; - $bottom.style.marginLeft = xOffset + 'px'; - $bottom.style.marginTop = yOffset + 'px'; - buttons.bottom.forEach(function(bottomButton) { - var $button = bottomButton.$button; - bottomButton.indexedPosition = [xOffset + $button.offsetLeft + $button.clientWidth / 2, yOffset]; - }); - } - function indexPosition() { - var positionedButtons = allButtons.filter(function(button) { - return button.indexedPosition; - }); - - positionedButtons.forEach(findNeightbour); - - function findNeightbour(button) { - var neighbor = {}; - var coef = 0; - var minCoef = {}; - var homePosition = button.indexedPosition; - var candidatePosition, dx, dy, ds; - var possible, dir; - var abs = Math.abs; - - positionedButtons.forEach(function(candidate) { - if (button == candidate) return; - - candidatePosition = candidate.indexedPosition; - - possible = []; - - dx = candidatePosition[0] - homePosition[0]; - dy = candidatePosition[1] - homePosition[1]; - ds = Math.sqrt(dx * dx + dy * dy); - - if (abs(dx) > 2) { - possible.push(dx > 0 ? 'right' : 'left'); - possible.push(ds + abs(dy)); // coef for right/left neighbor - } - if (abs(dy) > 2) { - possible.push(dy > 0 ? 'down' : 'up'); - possible.push(ds + abs(dx)); // coef for up/down neighbor - } - - while (possible.length) { - dir = possible.shift(); - coef = possible.shift(); - if (!neighbor[dir] || coef < minCoef[dir]) { - neighbor[dir] = candidate; - minCoef[dir] = coef; - } - } - }); - - button.neighbor = neighbor; - } - } - } - - function alwaysEnable() { - return true; - } - - // 为状态创建按钮 - function createButton(option) { - var $button = createElement(div); - addElementClass($button, 'button'); - var render = option.render || defaultButtonRender; - $button.innerHTML = render(format, option); - - switch (option.position) { - case 'center': appendChild($center, $button); break; - case 'ring': appendChild($ring, $button); break; - case 'top': appendChild($top, $button); break; - case 'bottom': appendChild($bottom, $button); break; - } - - return { - action: option.action, - enable: option.enable || alwaysEnable, - beforeShow: option.beforeShow, - key: option.key, - next: option.next, - label: option.label, - data: option.data || null, - $button: $button - }; - } - - // 默认按钮渲染 - function defaultButtonRender(format, option) { - return format('{label}{key}', { - label: option.label, - key: option.key && option.key.split('|')[0] - }); - } - - // 为当前状态添加按钮 - this.button = function(option) { - var button = createButton(option); - if (option.position == 'center') { - buttons.center = button; - } else if (buttons[option.position]) { - buttons[option.position].push(button); - } - allButtons.push(button); - needLayout = true; - }; - - function activeState(position) { - position = position || { - x: hotBox.$container.clientWidth / 2, - y: hotBox.$container.clientHeight / 2 - }; - if (position) { - $state.style.left = position.x + 'px'; - $state.style.top = position.y + 'px'; - } - allButtons.forEach(function(button) { - var $button = button.$button; - if ($button) { - $button.classList[button.enable() ? 'add' : 'remove']('enabled'); - } - - if (button.beforeShow) { - button.beforeShow(); - } - }); - addElementClass($state, STATE_ACTIVE_CLASS); - if (needLayout) { - layout(); - } - if (!selectedButton) { - select(buttons.center || buttons.ring[0] || buttons.top[0] || buttons.bottom[0]); - } - stateActived = true; - } - - function deactiveState() { - removeElementClass($state, STATE_ACTIVE_CLASS); - select(null); - stateActived = false; - } - - // 激活当前状态 - this.active = activeState; - - // 反激活当前状态 - this.deactive = deactiveState; - - function press(button) { - if (pressedButton && pressedButton.$button) { - removeElementClass(pressedButton.$button, BUTTON_PRESSED_CLASS); - } - pressedButton = button; - if (pressedButton && pressedButton.$button) { - addElementClass(pressedButton.$button, BUTTON_PRESSED_CLASS); - } - } - - function select(button) { - if (selectedButton && selectedButton.$button) { - if (selectedButton.$button) { - removeElementClass(selectedButton.$button, BUTTON_SELECTED_CLASS); - } - } - selectedButton = button; - if (selectedButton && selectedButton.$button) { - addElementClass(selectedButton.$button, BUTTON_SELECTED_CLASS); - } - } - - $state.onmouseup = function(e) { - if (e.button) return; - var target = e.target; - while (target && target != $state) { - if (target.classList.contains('button')) { - allButtons.forEach(function(button) { - if (button.$button == target) { - execute(button); - } - }); - } - target = target.parentNode; - } - }; - - this.handleKeyEvent = function(e) { - var handleResult = null; - /** - * @Desc: 搜狗浏览器下esc只触发keyup,因此做兼容性处理 - * @Editor: Naixor - * @Date: 2015.09.14 - */ - if (hotBox.browser.sg) { - if (e.isKey('esc')) { - if (pressedButton) { // 若存在已经按下的按钮,则取消操作 - if (!e.isKey(pressedButton.key)) { // the button is not esc - press(null); - } - } else { - hotBox.active('back', hotBox.position); - } - return 'back'; - }; - }; - if (e.keydown || (hotBox.isIME && e.keyup)) { - allButtons.forEach(function(button) { - if (button.enable() && e.isKey(button.key)) { - if (stateActived || hotBox.hintDeactiveMainState) { - select(button); - press(button); - handleResult = 'buttonpress'; - - // 如果是 keyup 事件触发的,因为没有后续的按键事件,所以就直接执行 - if(e.keyup) { - execute(button); - handleResult = 'execute'; - return handleResult; - } - } else { - execute(button); - handleResult = 'execute'; - } - e.preventDefault(); - e.stopPropagation(); - if (!stateActived && hotBox.hintDeactiveMainState) { - hotBox.active(stateName, hotBox.position); - } - } - }); - if (stateActived) { - if (e.isKey('esc')) { - if (pressedButton) { // 若存在已经按下的按钮,则取消操作 - if (!e.isKey(pressedButton.key)) { // the button is not esc - press(null); - } - } else { - hotBox.active('back', hotBox.position); - } - return 'back'; - } - ['up', 'down', 'left', 'right'].forEach(function(dir) { - if (!e.isKey(dir)) return; - if (!selectedButton) { - select(buttons.center || buttons.ring[0] || buttons.top[0] || buttons.bottom[0]); - return; - } - var neighbor = selectedButton.neighbor[dir]; - while (neighbor && !neighbor.enable()) { - neighbor = neighbor.neighbor[dir]; - } - if (neighbor) { - select(neighbor); - } - handleResult = 'navigate'; - }); - - // 若是由 keyup 触发的,则直接执行选中的按钮 - if (e.isKey('space') && e.keyup) { - execute(selectedButton); - e.preventDefault(); - e.stopPropagation(); - handleResult = 'execute'; - } else if (e.isKey('space') && selectedButton) { - press(selectedButton); - handleResult = 'buttonpress'; - } else if (pressedButton && pressedButton != selectedButton) { - press(null); - handleResult = 'selectcancel'; - } - } - } - else if (e.keyup && (stateActived || !hotBox.hintDeactiveMainState)) { - if (pressedButton) { - if (e.isKey('space') && selectedButton == pressedButton || e.isKey(pressedButton.key)) { - execute(pressedButton); - e.preventDefault(); - e.stopPropagation(); - handleResult = 'execute'; - } - } - } - - /* - * Add by zhangbobell 2015.09.06 - * 增加了下面这一个判断因为 safari 下开启输入法后,所有的 keydown 的 keycode 都为 229, - * 只能以 keyup 的 keycode 进行判断 - * */ - hotBox.isIME = (e.keyCode == 229 && e.keydown); - - return handleResult; - }; - - function execute(button) { - if (button) { - if (!button.enable || button.enable()) { - if (button.action) button.action(button); - hotBox.active(button.next || IDLE, hotBox.position); - } - press(null); - select(null); - } - } - } - - module.exports = HotBox; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/key.js b/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/key.js deleted file mode 100644 index 023dd5cc..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/key.js +++ /dev/null @@ -1,59 +0,0 @@ -define(function(require, exports, module) { - var keymap = require('./keymap'); - - var CTRL_MASK = 0x1000; - var ALT_MASK = 0x2000; - var SHIFT_MASK = 0x4000; - - function hash(unknown) { - if (typeof(unknown) == 'string') { - return hashKeyExpression(unknown); - } - return hashKeyEvent(unknown); - } - function is(a, b) { - return a && b && hash(a) == hash(b); - } - exports.hash = hash; - exports.is = is; - - - function hashKeyEvent(keyEvent) { - var hashCode = 0; - if (keyEvent.ctrlKey || keyEvent.metaKey) { - hashCode |= CTRL_MASK; - } - if (keyEvent.altKey) { - hashCode |= ALT_MASK; - } - if (keyEvent.shiftKey) { - hashCode |= SHIFT_MASK; - } - // Shift, Control, Alt KeyCode ignored. - if ([16, 17, 18, 91].indexOf(keyEvent.keyCode) == -1) { - hashCode |= keyEvent.keyCode; - } - return hashCode; - } - - function hashKeyExpression(keyExpression) { - var hashCode = 0; - keyExpression.toLowerCase().split(/\s*\+\s*/).forEach(function(name) { - switch(name) { - case 'ctrl': - case 'cmd': - hashCode |= CTRL_MASK; - break; - case 'alt': - hashCode |= ALT_MASK; - break; - case 'shift': - hashCode |= SHIFT_MASK; - break; - default: - hashCode |= keymap[name]; - } - }); - return hashCode; - } -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/keycontrol.js b/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/keycontrol.js deleted file mode 100644 index d6ab3166..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/keycontrol.js +++ /dev/null @@ -1,68 +0,0 @@ -define(function(require, exports, module) { - - var key = require('./key'); - var FOCUS_CLASS = 'hotbox-focus'; - var RECEIVER_CLASS = 'hotbox-key-receiver'; - - function KeyControl(hotbox) { - var _this = this; - var _receiver; - var _actived = true; - var _receiverIsSelfCreated = false; - var $container = hotbox.$container; - - _createReceiver(); - _bindReceiver(); - _bindContainer(); - _active(); - - function _createReceiver() { - _receiver = document.createElement('input'); - _receiver.classList.add(RECEIVER_CLASS); - $container.appendChild(_receiver); - _receiverIsSelfCreated = true; - } - - function _bindReceiver() { - _receiver.onkeyup = _handle; - _receiver.onkeypress = _handle; - _receiver.onkeydown = _handle; - _receiver.onfocus = _active; - _receiver.onblur = _deactive; - if (_receiverIsSelfCreated) { - _receiver.oninput = function(e) { _receiver.value = null; }; - } - } - - function _bindContainer() { - $container.onmousedown = function(e) { - _active(); - e.preventDefault(); - }; - } - - function _handle(keyEvent) { - if (!_actived) return; - hotbox.dispatch(keyEvent); - } - - function _active() { - _receiver.select(); - _receiver.focus(); - _actived = true; - $container.classList.add(FOCUS_CLASS); - } - - function _deactive() { - _receiver.blur(); - _actived = false; - $container.classList.remove(FOCUS_CLASS); - } - - this.handle = _handle; - this.active = _active; - this.deactive = _deactive; - } - - module.exports = KeyControl; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/keymap.js b/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/keymap.js deleted file mode 100644 index 3ed6433a..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/hotbox/keymap.js +++ /dev/null @@ -1,82 +0,0 @@ -define(function(require, exports, module) { - var keymap = { - - 'Shift': 16, - 'Control': 17, - 'Alt': 18, - 'CapsLock': 20, - - 'BackSpace': 8, - 'Tab': 9, - 'Enter': 13, - 'Esc': 27, - 'Space': 32, - - 'PageUp': 33, - 'PageDown': 34, - 'End': 35, - 'Home': 36, - - 'Insert': 45, - - 'Left': 37, - 'Up': 38, - 'Right': 39, - 'Down': 40, - - 'Direction': { - 37: 1, - 38: 1, - 39: 1, - 40: 1 - }, - - 'Delete': 46, - - 'NumLock': 144, - - 'Cmd': 91, - 'CmdFF': 224, - 'F1': 112, - 'F2': 113, - 'F3': 114, - 'F4': 115, - 'F5': 116, - 'F6': 117, - 'F7': 118, - 'F8': 119, - 'F9': 120, - 'F10': 121, - 'F11': 122, - 'F12': 123, - - '`': 192, - '=': 187, - '-': 189, - - '/': 191, - '.': 190 - }; - - // 小写适配 - for (var key in keymap) { - if (keymap.hasOwnProperty(key)) { - keymap[key.toLowerCase()] = keymap[key]; - } - } - var aKeyCode = 65; - var aCharCode = 'a'.charCodeAt(0); - - // letters - 'abcdefghijklmnopqrstuvwxyz'.split('').forEach(function(letter) { - keymap[letter] = aKeyCode + (letter.charCodeAt(0) - aCharCode); - }); - - // numbers - var n = 9; - do { - keymap[n.toString()] = n + 48; - } while (n--); - - module.exports = keymap; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/index.ts b/packages/client/src/tiptap/wrappers/mind/kityminder/index.ts deleted file mode 100644 index a8867f91..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -export const loadKityMinder = async (): Promise => { - if (typeof window !== 'undefined') { - if (window.kityminder) { - if (window.kityminder.Editor) { - return; - } - } - } - - await import('kity'); - await import('./kity-core/kityminder'); - await import('./kity-editor/expose-editor'); -}; diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/arc.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/arc.js deleted file mode 100644 index 3720b05a..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/arc.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @fileOverview - * - * 圆弧连线 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function(require, exports, module) { - var kity = require('../core/kity'); - var connect = require('../core/connect'); - - var connectMarker = new kity.Marker().pipe(function() { - var r = 7; - var dot = new kity.Circle(r - 1); - this.addShape(dot); - this.setRef(r - 1, 0).setViewBox(-r, -r, r + r, r + r).setWidth(r).setHeight(r); - this.dot = dot; - this.node.setAttribute('markerUnits', 'userSpaceOnUse'); - }); - - connect.register('arc', function(node, parent, connection, width, color) { - - var box = node.getLayoutBox(), - pBox = parent.getLayoutBox(); - - var start, end, vector; - var abs = Math.abs; - var pathData = []; - var side = box.x > pBox.x ? 'right' : 'left'; - - node.getMinder().getPaper().addResource(connectMarker); - - start = new kity.Point(pBox.cx, pBox.cy); - end = side == 'left' ? - new kity.Point(box.right + 2, box.cy) : - new kity.Point(box.left - 2, box.cy); - - vector = kity.Vector.fromPoints(start, end); - pathData.push('M', start); - pathData.push('A', abs(vector.x), abs(vector.y), 0, 0, (vector.x * vector.y > 0 ? 0 : 1), end); - - connection.setMarker(connectMarker); - connectMarker.dot.fill(color); - - connection.setPathData(pathData); - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/arc_tp.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/arc_tp.js deleted file mode 100644 index e68bedd1..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/arc_tp.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * - * 圆弧连线 - * - * @author: along - * @copyright: bpd729@163.com , 2015 - */ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var connect = require('../core/connect'); - - var connectMarker = new kity.Marker().pipe(function () { - var r = 7; - var dot = new kity.Circle(r - 1); - this.addShape(dot); - this.setRef(r - 1, 0).setViewBox(-r, -r, r + r, r + r).setWidth(r).setHeight(r); - this.dot = dot; - this.node.setAttribute('markerUnits', 'userSpaceOnUse'); - }); - - /** - * 天盘图连线除了连接当前节点和前一个节点外, 还需要渲染当前节点和后一个节点的连接, 防止样式上的断线 - * 这是天盘图与其余的模板不同的地方 - */ - connect.register('arc_tp', function (node, parent, connection, width, color) { - var end_box = node.getLayoutBox(), - start_box = parent.getLayoutBox(); - - var index = node.getIndex(); - var nextNode = parent.getChildren()[index + 1]; - - - if (node.getIndex() > 0) { - start_box = parent.getChildren()[index - 1].getLayoutBox(); - } - - - var start, end, vector; - var abs = Math.abs; - var pathData = []; - var side = end_box.x > start_box.x ? 'right' : 'left'; - - node.getMinder().getPaper().addResource(connectMarker); - - - start = new kity.Point(start_box.cx, start_box.cy); - end = new kity.Point(end_box.cx, end_box.cy); - - var jl = Math.sqrt(Math.pow((start.x - end.x), 2) + Math.pow((start.y - end.y), 2)); //两圆中心点距离 - - jl = node.getIndex() == 0 ? jl * 0.4 : jl; - - - vector = kity.Vector.fromPoints(start, end); - pathData.push('M', start); - pathData.push('A', jl, jl, 0, 0, 1, end); - - - connection.setMarker(connectMarker); - connectMarker.dot.fill(color); - connection.setPathData(pathData); - - - // 设置下一个的节点的连接线 - if (nextNode && nextNode.getConnection()) { - var nextConnection = nextNode.getConnection(); - var next_end_box = nextNode.getLayoutBox(); - var next_end = new kity.Point(next_end_box.cx, next_end_box.cy); - - var jl2 = Math.sqrt(Math.pow((end.x - next_end.x), 2) + Math.pow((end.y - next_end.y), 2)); //两圆中心点距离 - - pathData = []; - - pathData.push('M', end); - pathData.push('A', jl2, jl2, 0, 0, 1, next_end); - - nextConnection.setMarker(connectMarker); - connectMarker.dot.fill(color); - - nextConnection.setPathData(pathData); - - } - - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/bezier.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/bezier.js deleted file mode 100644 index f1cc3d3f..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/bezier.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @fileOverview - * - * 提供折线相连的方法 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function(require, exports, module) { - var kity = require('../core/kity'); - var connect = require('../core/connect'); - - connect.register('bezier', function(node, parent, connection) { - - // 连线起点和终点 - var po = parent.getLayoutVertexOut(), - pi = node.getLayoutVertexIn(); - - // 连线矢量和方向 - var v = parent.getLayoutVectorOut().normalize(); - - var r = Math.round; - var abs = Math.abs; - - var pathData = []; - pathData.push('M', r(po.x), r(po.y)); - - if (abs(v.x) > abs(v.y)) { - // x - direction - var hx = (pi.x + po.x) / 2; - pathData.push('C', hx, po.y, hx, pi.y, pi.x, pi.y); - } else { - // y - direction - var hy = (pi.y + po.y) / 2; - pathData.push('C', po.x, hy, pi.x, hy, pi.x, pi.y); - } - - connection.setMarker(null); - connection.setPathData(pathData); - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/fish-bone-master.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/fish-bone-master.js deleted file mode 100644 index 6da3c2e6..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/fish-bone-master.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @fileOverview - * - * 鱼骨头主干连线 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function(require, exports, module) { - var kity = require('../core/kity'); - var connect = require('../core/connect'); - - connect.register('fish-bone-master', function(node, parent, connection) { - - var pout = parent.getLayoutVertexOut(), - pin = node.getLayoutVertexIn(); - - var abs = Math.abs; - - var dy = abs(pout.y - pin.y), - dx = abs(pout.x - pin.x); - - var pathData = []; - - pathData.push('M', pout.x, pout.y); - pathData.push('h', dx - dy); - pathData.push('L', pin.x, pin.y); - - connection.setMarker(null); - connection.setPathData(pathData); - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/l.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/l.js deleted file mode 100644 index c678f664..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/l.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @fileOverview - * - * "L" 连线 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function(require, exports, module) { - var kity = require('../core/kity'); - var connect = require('../core/connect'); - - connect.register('l', function(node, parent, connection) { - - var po = parent.getLayoutVertexOut(); - var pi = node.getLayoutVertexIn(); - var vo = parent.getLayoutVectorOut(); - - var pathData = []; - var r = Math.round, - abs = Math.abs; - - pathData.push('M', po.round()); - if (abs(vo.x) > abs(vo.y)) { - pathData.push('H', r(pi.x)); - } else { - pathData.push('V', pi.y); - } - pathData.push('L', pi); - - connection.setPathData(pathData); - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/poly.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/poly.js deleted file mode 100644 index 27612fd7..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/poly.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @fileOverview - * - * 提供折线相连的方法 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function(require, exports, module) { - var kity = require('../core/kity'); - var connect = require('../core/connect'); - - connect.register('poly', function(node, parent, connection, width) { - - // 连线起点和终点 - var po = parent.getLayoutVertexOut(), - pi = node.getLayoutVertexIn(); - - // 连线矢量和方向 - var v = parent.getLayoutVectorOut().normalize(); - - var r = Math.round; - var abs = Math.abs; - - var pathData = []; - pathData.push('M', r(po.x), r(po.y)); - - switch (true) { - case abs(v.x) > abs(v.y) && v.x < 0: - // left - pathData.push('h', -parent.getStyle('margin-left')); - pathData.push('v', pi.y - po.y); - pathData.push('H', pi.x); - break; - - case abs(v.x) > abs(v.y) && v.x >= 0: - // right - pathData.push('h', parent.getStyle('margin-right')); - pathData.push('v', pi.y - po.y); - pathData.push('H', pi.x); - break; - - case abs(v.x) <= abs(v.y) && v.y < 0: - // top - pathData.push('v', -parent.getStyle('margin-top')); - pathData.push('h', pi.x - po.x); - pathData.push('V', pi.y); - break; - - case abs(v.x) <= abs(v.y) && v.y >= 0: - // bottom - pathData.push('v', parent.getStyle('margin-bottom')); - pathData.push('h', pi.x - po.x); - pathData.push('V', pi.y); - break; - - } - - connection.setMarker(null); - connection.setPathData(pathData); - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/under.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/under.js deleted file mode 100644 index d7f21aaa..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/connect/under.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @fileOverview - * - * 下划线连线 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function(require, exports, module) { - var kity = require('../core/kity'); - var connect = require('../core/connect'); - - connect.register('under', function(node, parent, connection, width, color) { - - var box = node.getLayoutBox(), - pBox = parent.getLayoutBox(); - - var start, end, vector; - var abs = Math.abs; - var pathData = []; - var side = box.x > pBox.x ? 'right' : 'left'; - - - var radius = node.getStyle('connect-radius'); - var underY = box.bottom + 3; - var startY = parent.getType() == 'sub' ? pBox.bottom + 3 : pBox.cy; - var p1, p2, p3, mx; - - if (side == 'right') { - p1 = new kity.Point(pBox.right, startY); - p2 = new kity.Point(box.left - 10, underY); - p3 = new kity.Point(box.right, underY); - } else { - p1 = new kity.Point(pBox.left, startY); - p2 = new kity.Point(box.right + 10, underY); - p3 = new kity.Point(box.left, underY); - } - - mx = (p1.x + p2.x) / 2; - - pathData.push('M', p1); - pathData.push('C', mx, p1.y, mx, p2.y, p2); - pathData.push('L', p3); - - connection.setMarker(null); - - connection.setPathData(pathData); - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/_boxv.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/_boxv.js deleted file mode 100644 index 7ebc6b9b..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/_boxv.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @fileOverview - * - * 调试工具:为 kity.Box 提供一个可视化的渲染 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function(require, exports, module) { - var kity = require('./kity'); - var Minder = require('./minder'); - - if (location.href.indexOf('boxv') != -1) { - - var vrect; - - Object.defineProperty(kity.Box.prototype, 'visualization', { - get: function() { - if (!vrect) return null; - return vrect.setBox(this); - } - }); - - Minder.registerInitHook(function() { - this.on('paperrender', function() { - vrect = new kity.Rect(); - vrect.fill('rgba(200, 200, 200, .5)'); - vrect.stroke('orange'); - this.getRenderContainer().addShape(vrect); - }); - }); - } -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/animate.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/animate.js deleted file mode 100644 index 75d266f7..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/animate.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @fileOverview - * - * 动画控制 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - var Minder = require('./minder'); - - var animateDefaultOptions = { - enableAnimation: true, - layoutAnimationDuration: 300, - viewAnimationDuration: 100, - zoomAnimationDuration: 300 - }; - var resoredAnimationOptions = {}; - - Minder.registerInitHook(function() { - this.setDefaultOptions(animateDefaultOptions); - if (!this.getOption('enableAnimation')) { - this.disableAnimation(); - } - }); - - Minder.prototype.enableAnimation = function() { - for (var name in animateDefaultOptions) { - if (animateDefaultOptions.hasOwnProperty(name)) { - this.setOption(resoredAnimationOptions[name]); - } - } - }; - - Minder.prototype.disableAnimation = function() { - for (var name in animateDefaultOptions) { - if (animateDefaultOptions.hasOwnProperty(name)) { - resoredAnimationOptions[name] = this.getOption(name); - this.setOption(name, 0); - } - } - }; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/command.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/command.js deleted file mode 100644 index f36a3da2..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/command.js +++ /dev/null @@ -1,169 +0,0 @@ -define(function(require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Minder = require('./minder'); - var MinderNode = require('./node'); - var MinderEvent = require('./event'); - - var COMMAND_STATE_NORMAL = 0; - var COMMAND_STATE_DISABLED = -1; - var COMMAND_STATE_ACTIVED = 1; - - /** - * 表示一个命令,包含命令的查询及执行 - */ - var Command = kity.createClass('Command', { - constructor: function() { - this._isContentChange = true; - this._isSelectionChange = false; - }, - - execute: function(minder, args) { - throw new Error('Not Implement: Command.execute()'); - }, - - setContentChanged: function(val) { - this._isContentChange = !!val; - }, - - isContentChanged: function() { - return this._isContentChange; - }, - - setSelectionChanged: function(val) { - this._isSelectionChange = !!val; - }, - - isSelectionChanged: function() { - return this._isContentChange; - }, - - queryState: function(km) { - return COMMAND_STATE_NORMAL; - }, - - queryValue: function(km) { - return 0; - }, - - isNeedUndo: function() { - return true; - } - }); - - Command.STATE_NORMAL = COMMAND_STATE_NORMAL; - Command.STATE_ACTIVE = COMMAND_STATE_ACTIVED; - Command.STATE_DISABLED = COMMAND_STATE_DISABLED; - - kity.extendClass(Minder, { - _getCommand: function(name) { - return this._commands[name.toLowerCase()]; - }, - - _queryCommand: function(name, type, args) { - var cmd = this._getCommand(name); - if (cmd) { - var queryCmd = cmd['query' + type]; - if (queryCmd) - return queryCmd.apply(cmd, [this].concat(args)); - } - return 0; - }, - - /** - * @method queryCommandState() - * @for Minder - * @description 查询指定命令的状态 - * - * @grammar queryCommandName(name) => {number} - * - * @param {string} name 要查询的命令名称 - * - * @return {number} - * -1: 命令不存在或命令当前不可用 - * 0: 命令可用 - * 1: 命令当前可用并且已经执行过 - */ - queryCommandState: function(name) { - return this._queryCommand(name, 'State', [].slice.call(arguments, 1)); - }, - - /** - * @method queryCommandValue() - * @for Minder - * @description 查询指定命令当前的执行值 - * - * @grammar queryCommandValue(name) => {any} - * - * @param {string} name 要查询的命令名称 - * - * @return {any} - * 如果命令不存在,返回 undefined - * 不同命令具有不同返回值,具体请查看 [Command](command) 章节 - */ - queryCommandValue: function(name) { - return this._queryCommand(name, 'Value', [].slice.call(arguments, 1)); - }, - - /** - * @method execCommand() - * @for Minder - * @description 执行指定的命令。 - * - * @grammar execCommand(name, args...) - * - * @param {string} name 要执行的命令名称 - * @param {argument} args 要传递给命令的其它参数 - */ - execCommand: function(name) { - if (!name) return null; - - name = name.toLowerCase(); - - var cmdArgs = [].slice.call(arguments, 1), - cmd, stoped, result, eventParams; - var me = this; - cmd = this._getCommand(name); - - eventParams = { - command: cmd, - commandName: name.toLowerCase(), - commandArgs: cmdArgs - }; - if (!cmd || !~this.queryCommandState(name)) { - return false; - } - - if (!this._hasEnterExecCommand) { - this._hasEnterExecCommand = true; - - stoped = this._fire(new MinderEvent('beforeExecCommand', eventParams, true)); - - if (!stoped) { - this._fire(new MinderEvent('preExecCommand', eventParams, false)); - - result = cmd.execute.apply(cmd, [me].concat(cmdArgs)); - - this._fire(new MinderEvent('execCommand', eventParams, false)); - - if (cmd.isContentChanged()) { - this._firePharse(new MinderEvent('contentchange')); - } - - this._interactChange(); - } - this._hasEnterExecCommand = false; - } else { - result = cmd.execute.apply(cmd, [me].concat(cmdArgs)); - - if (!this._hasEnterExecCommand) { - this._interactChange(); - } - } - - return result === undefined ? null : result; - } - }); - - module.exports = Command; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/compatibility.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/compatibility.js deleted file mode 100644 index e836b648..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/compatibility.js +++ /dev/null @@ -1,92 +0,0 @@ -define(function(require, exports, module) { - var utils = require('./utils'); - - function compatibility(json) { - - var version = json.version || (json.root ? '1.4.0' : '1.1.3'); - - switch (version) { - case '1.1.3': - c_113_120(json); - /* falls through */ - case '1.2.0': - case '1.2.1': - c_120_130(json); - /* falls through */ - case '1.3.0': - case '1.3.1': - case '1.3.2': - case '1.3.3': - case '1.3.4': - case '1.3.5': - /* falls through */ - c_130_140(json); - } - return json; - } - - function traverse(node, fn) { - fn(node); - if (node.children) node.children.forEach(function(child) { - traverse(child, fn); - }); - } - - /* 脑图数据升级 */ - function c_120_130(json) { - traverse(json, function(node) { - var data = node.data; - delete data.layout_bottom_offset; - delete data.layout_default_offset; - delete data.layout_filetree_offset; - }); - } - - /** - * 脑图数据升级 - * v1.1.3 => v1.2.0 - * */ - function c_113_120(json) { - // 原本的布局风格 - var ocs = json.data.currentstyle; - delete json.data.currentstyle; - - // 为 1.2 选择模板,同时保留老版本文件的皮肤 - if (ocs == 'bottom') { - json.template = 'structure'; - json.theme = 'snow'; - } else if (ocs == 'default') { - json.template = 'default'; - json.theme = 'classic'; - } - - traverse(json, function(node) { - var data = node.data; - - // 升级优先级、进度图标 - if ('PriorityIcon' in data) { - data.priority = data.PriorityIcon; - delete data.PriorityIcon; - } - if ('ProgressIcon' in data) { - data.progress = 1 + ((data.ProgressIcon - 1) << 1); - delete data.ProgressIcon; - } - - // 删除过时属性 - delete data.point; - delete data.layout; - }); - } - - function c_130_140(json) { - json.root = { - data: json.data, - children: json.children - }; - delete json.data; - delete json.children; - } - - return compatibility; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/connect.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/connect.js deleted file mode 100644 index 451feb7f..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/connect.js +++ /dev/null @@ -1,126 +0,0 @@ -define(function(require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Module = require('./module'); - var Minder = require('./minder'); - var MinderNode = require('./node'); - - // 连线提供方 - var _connectProviders = {}; - - function register(name, provider) { - _connectProviders[name] = provider; - } - - register('default', function(node, parent, connection) { - connection.setPathData([ - 'M', parent.getLayoutVertexOut(), - 'L', node.getLayoutVertexIn() - ]); - }); - - kity.extendClass(MinderNode, { - /** - * @private - * @method getConnect() - * @for MinderNode - * @description 获取当前节点的连线类型 - * - * @grammar getConnect() => {string} - */ - getConnect: function() { - return this.data.connect || 'default'; - }, - - getConnectProvider: function() { - return _connectProviders[this.getConnect()] || _connectProviders['default']; - }, - - /** - * @private - * @method getConnection() - * @for MinderNode - * @description 获取当前节点的连线对象 - * - * @grammar getConnection() => {kity.Path} - */ - getConnection: function() { - return this._connection || null; - } - }); - - kity.extendClass(Minder, { - - getConnectContainer: function() { - return this._connectContainer; - }, - - createConnect: function(node) { - if (node.isRoot()) return; - - var connection = new kity.Path(); - - node._connection = connection; - - this._connectContainer.addShape(connection); - this.updateConnect(node); - }, - - removeConnect: function(node) { - var me = this; - node.traverse(function(node) { - me._connectContainer.removeShape(node._connection); - node._connection = null; - }); - }, - - updateConnect: function(node) { - - var connection = node._connection; - var parent = node.parent; - - if (!parent || !connection) return; - - if (parent.isCollapsed()) { - connection.setVisible(false); - return; - } - connection.setVisible(true); - - var provider = node.getConnectProvider(); - - var strokeColor = node.getStyle('connect-color') || 'white', - strokeWidth = node.getStyle('connect-width') || 2; - - connection.stroke(strokeColor, strokeWidth); - - provider(node, parent, connection, strokeWidth, strokeColor); - - if (strokeWidth % 2 === 0) { - connection.setTranslate(0.5, 0.5); - } else { - connection.setTranslate(0, 0); - } - } - }); - - Module.register('Connect', { - init: function() { - this._connectContainer = new kity.Group().setId(utils.uuid('minder_connect_group')); - this.getRenderContainer().prependShape(this._connectContainer); - }, - events: { - 'nodeattach': function(e) { - this.createConnect(e.node); - }, - 'nodedetach': function(e) { - this.removeConnect(e.node); - }, - 'layoutapply layoutfinish noderender': function(e) { - this.updateConnect(e.node); - } - } - }); - - exports.register = register; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/data.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/data.js deleted file mode 100644 index a851000f..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/data.js +++ /dev/null @@ -1,362 +0,0 @@ -define(function(require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Minder = require('./minder'); - var MinderNode = require('./node'); - var MinderEvent = require('./event'); - var compatibility = require('./compatibility'); - var Promise = require('./promise'); - - var protocols = {}; - - function registerProtocol(name, protocol) { - protocols[name] = protocol; - - for (var pname in protocols) { - if (protocols.hasOwnProperty(pname)) { - protocols[pname] = protocols[pname]; - protocols[pname].name = pname; - } - } - } - - function getRegisterProtocol(name) { - return name === undefined ? protocols : (protocols[name] || null); - } - - exports.registerProtocol = registerProtocol; - exports.getRegisterProtocol = getRegisterProtocol; - - // 导入导出 - kity.extendClass(Minder, { - - // 自动导入 - setup: function(target) { - if (typeof target == 'string') { - target = document.querySelector(target); - } - if (!target) return; - var protocol = target.getAttribute('minder-data-type'); - if (protocol in protocols) { - var data = target.textContent; - target.textContent = null; - this.renderTo(target); - this.importData(protocol, data); - } - return this; - }, - - /** - * @method exportJson() - * @for Minder - * @description - * 导出当前脑图数据为 JSON 对象,导出的数据格式请参考 [Data](data) 章节。 - * @grammar exportJson() => {plain} - */ - exportJson: function() { - /* 导出 node 上整棵树的数据为 JSON */ - function exportNode(node) { - var exported = {}; - exported.data = node.getData(); - var childNodes = node.getChildren(); - exported.children = []; - for (var i = 0; i < childNodes.length; i++) { - exported.children.push(exportNode(childNodes[i])); - } - return exported; - } - - var json = { - root: exportNode(this.getRoot()) - }; - - json.template = this.getTemplate(); - json.theme = this.getTheme(); - json.version = Minder.version; - - return JSON.parse(JSON.stringify(json)); - }, - - /** - * function Text2Children(MinderNode, String) - * @param {MinderNode} node 要导入数据的节点 - * @param {String} text 导入的text数据 - * @Desc: 用于批量插入子节点,并不会修改被插入的父节点 - * @Editor: Naixor - * @Date: 2015.9.21 - * @example: 用于批量导入如下类型的节点 - * 234 - * 3456346 asadf - * 12312414 - * wereww - * 12314 - * 1231412 - * 13123 - */ - Text2Children: function (node, text) { - if (!(node instanceof kityminder.Node)) { - return; - // throw new Error('Json2Children::node is not a kityminder.Node type!'); - }; - var children = [], - jsonMap = {}, - level = 0; - - var LINE_SPLITTER = /\r|\n|\r\n/, - TAB_REGEXP = /^(\t|\x20{4})/; - - var lines = text.split(LINE_SPLITTER), - line = '', jsonNode, i = 0; - var minder = this; - - function isEmpty(line) { - return line === "" && !/\S/.test(line); - } - - function getNode(line) { - return { - data: { - text: line.replace(/^(\t|\x20{4})+/, '').replace(/(\t|\x20{4})+$/, '') - }, - children: [] - } - } - - function getLevel(text) { - var level = 0; - while (TAB_REGEXP.test(text)) { - text = text.replace(TAB_REGEXP, ''); - level++; - } - return level; - } - - function addChild(parent, node) { - parent.children.push(node); - } - - function importChildren(node, children) { - for (var i = 0, l = children.length; i < l; i++) { - var childNode = minder.createNode(null, node); - childNode.setData('text', children[i].data.text || ''); - importChildren(childNode, children[i].children); - } - } - - while ((line = lines[i++]) !== undefined) { - line = line.replace(/ /g, ''); - if (isEmpty(line)) continue; - - level = getLevel(line); - jsonNode = getNode(line); - if (level === 0) { - jsonMap = {}; - children.push(jsonNode); - jsonMap[0] = children[children.length-1]; - } else { - if (!jsonMap[level-1]) { - throw new Error('Invalid local format'); - }; - addChild(jsonMap[level-1], jsonNode); - jsonMap[level] = jsonNode; - } - } - - importChildren(node, children); - minder.refresh(); - }, - - /** - * @method exportNode(MinderNode) - * @param {MinderNode} node 当前要被导出的节点 - * @return {Object} 返回只含有data和children的Object - * @Editor: Naixor - * @Date: 2015.9.22 - */ - exportNode: function (node) { - var exported = {}; - exported.data = node.getData(); - var childNodes = node.getChildren(); - exported.children = []; - for (var i = 0; i < childNodes.length; i++) { - exported.children.push(this.exportNode(childNodes[i])); - } - return exported; - }, - /** - * @method importNode() - * @description 根据纯json {data, children}数据转换成为脑图节点 - * @Editor: Naixor - * @Date: 2015.9.20 - */ - importNode: function(node, json) { - var data = json.data; - node.data = {}; - - for (var field in data) { - node.setData(field, data[field]); - } - - var childrenTreeData = json.children || []; - for (var i = 0; i < childrenTreeData.length; i++) { - var childNode = this.createNode(null, node); - this.importNode(childNode, childrenTreeData[i]); - } - return node; - }, - - /** - * @method importJson() - * @for Minder - * @description 导入脑图数据,数据为 JSON 对象,具体的数据字段形式请参考 [Data](data) 章节。 - * - * @grammar importJson(json) => {this} - * - * @param {plain} json 要导入的数据 - */ - importJson: function(json) { - if (!json) return; - - /** - * @event preimport - * @for Minder - * @when 导入数据之前 - */ - this._fire(new MinderEvent('preimport', null, false)); - - // 删除当前所有节点 - while (this._root.getChildren().length) { - this.removeNode(this._root.getChildren()[0]); - } - - json = compatibility(json); - - this.importNode(this._root, json.root); - - this.setTemplate(json.template || 'default'); - this.setTheme(json.theme || null); - this.refresh(); - - /** - * @event import,contentchange,interactchange - * @for Minder - * @when 导入数据之后 - */ - this.fire('import'); - - this._firePharse({ - type: 'contentchange' - }); - - this._interactChange(); - - return this; - }, - - /** - * @method exportData() - * @for Minder - * @description 使用指定使用的数据协议,导入脑图数据 - * - * @grammar exportData(protocol) => Promise - * - * @param {string} protocol 指定的数据协议(默认内置五种数据协议 `json`、`text`、`markdown`、`svg` 和 `png`) - */ - exportData: function(protocolName, option) { - var json, protocol; - - json = this.exportJson(); - - // 指定了协议进行导出,需要检测协议是否支持 - if (protocolName) { - protocol = protocols[protocolName]; - - if (!protocol || !protocol.encode) { - return Promise.reject(new Error('Not supported protocol:' + protocolName)); - } - } - - // 导出前抛个事件 - this._fire(new MinderEvent('beforeexport', { - json: json, - protocolName: protocolName, - protocol: protocol - })); - - return Promise.resolve(protocol.encode(json, this, option)); - }, - - /** - * @method importData() - * @for Minder - * @description 使用指定的数据协议,导入脑图数据,覆盖当前实例的脑图 - * - * @grammar importData(protocol, callback) => Promise - * - * @param {string} protocol 指定的用于解析数据的数据协议(默认内置三种数据协议 `json`、`text` 和 `markdown` 的支持) - * @param {any} data 要导入的数据 - */ - importData: function(protocolName, data, option) { - var json, protocol; - var minder = this; - - // 指定了协议进行导入,需要检测协议是否支持 - if (protocolName) { - protocol = protocols[protocolName]; - - if (!protocol || !protocol.decode) { - return Promise.reject(new Error('Not supported protocol:' + protocolName)); - } - } - - var params = { - local: data, - protocolName: protocolName, - protocol: protocol - }; - - // 导入前抛事件 - this._fire(new MinderEvent('beforeimport', params)); - - return Promise.resolve(protocol.decode(data, this, option)).then(function(json) { - minder.importJson(json); - return json; - }); - }, - - /** - * @method decodeData() - * @for Minder - * @description 使用指定的数据协议,解析为脑图数据,与 importData 的区别在于:不覆盖当前实例的脑图 - * - * @grammar decodeData(protocol, callback) => Promise - * - * @param {string} protocol 指定的用于解析数据的数据协议(默认内置三种数据协议 `json`、`text` 和 `markdown` 的支持) - * @param {any} data 要导入的数据 - */ - decodeData: function(protocolName, data, option) { - var json, protocol; - var minder = this; - - // 指定了协议进行导入,需要检测协议是否支持 - if (protocolName) { - protocol = protocols[protocolName]; - - if (!protocol || !protocol.decode) { - return Promise.reject(new Error('Not supported protocol:' + protocolName)); - } - } - - var params = { - local: data, - protocolName: protocolName, - protocol: protocol - }; - - // 导入前抛事件 - this._fire(new MinderEvent('beforeimport', params)); - - return Promise.resolve(protocol.decode(data, this, option)) - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/event.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/event.js deleted file mode 100644 index 049bcd72..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/event.js +++ /dev/null @@ -1,263 +0,0 @@ -define(function (require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Minder = require('./minder'); - - /** - * @class MinderEvent - * @description 表示一个脑图中发生的事件 - */ - var MinderEvent = kity.createClass('MindEvent', { - constructor: function (type, params, canstop) { - params = params || {}; - if (params.getType && params.getType() == 'ShapeEvent') { - /** - * @property kityEvent - * @for MinderEvent - * @description 如果事件是从一个 kity 的事件派生的,会有 kityEvent 属性指向原来的 kity 事件 - * @type {KityEvent} - */ - this.kityEvent = params; - - /** - * @property originEvent - * @for MinderEvent - * @description 如果事件是从原声 Dom 事件派生的(如 click、mousemove 等),会有 originEvent 指向原来的 Dom 事件 - * @type {DomEvent} - */ - this.originEvent = params.originEvent; - } else if (params.target && params.preventDefault) { - this.originEvent = params; - } else { - kity.Utils.extend(this, params); - } - - /** - * @property type - * @for MinderEvent - * @description 事件的类型,如 `click`、`contentchange` 等 - * @type {string} - */ - this.type = type; - this._canstop = canstop || false; - }, - - /** - * @method getPosition() - * @for MinderEvent - * @description 如果事件是从一个 kity 事件派生的,会有 `getPosition()` 获取事件发生的坐标 - * - * @grammar getPosition(refer) => {kity.Point} - * - * @param {string|kity.Shape} refer - * 参照的坐标系, - * `"screen"` - 以浏览器屏幕为参照坐标系 - * `"minder"` - (默认)以脑图画布为参照坐标系 - * `{kity.Shape}` - 指定以某个 kity 图形为参照坐标系 - */ - getPosition: function (refer) { - if (!this.kityEvent) return; - if (!refer || refer == 'minder') { - return this.kityEvent.getPosition(this.minder.getRenderContainer()); - } - return this.kityEvent.getPosition.call(this.kityEvent, refer); - }, - - /** - * @method getTargetNode() - * @for MinderEvent - * @description 当发生的事件是鼠标事件时,获取事件位置命中的脑图节点 - * - * @grammar getTargetNode() => {MinderNode} - */ - getTargetNode: function () { - var findShape = this.kityEvent && this.kityEvent.targetShape; - if (!findShape) return null; - while (!findShape.minderNode && findShape.container) { - findShape = findShape.container; - } - var node = findShape.minderNode; - if (node && findShape.getOpacity() < 1) return null; - return node || null; - }, - - /** - * @method stopPropagation() - * @for MinderEvent - * @description 当发生的事件是鼠标事件时,获取事件位置命中的脑图节点 - * - * @grammar getTargetNode() => {MinderNode} - */ - stopPropagation: function () { - this._stoped = true; - }, - - stopPropagationImmediately: function () { - this._immediatelyStoped = true; - this._stoped = true; - }, - - shouldStopPropagation: function () { - return this._canstop && this._stoped; - }, - - shouldStopPropagationImmediately: function () { - return this._canstop && this._immediatelyStoped; - }, - preventDefault: function () { - this.originEvent.preventDefault(); - }, - isRightMB: function () { - var isRightMB = false; - if (!this.originEvent) { - return false; - } - if ('which' in this.originEvent) isRightMB = this.originEvent.which == 3; - else if ('button' in this.originEvent) isRightMB = this.originEvent.button == 2; - return isRightMB; - }, - getKeyCode: function () { - var evt = this.originEvent; - return evt.keyCode || evt.which; - }, - }); - - Minder.registerInitHook(function (option) { - this._initEvents(); - }); - - kity.extendClass(Minder, { - _initEvents: function () { - this._eventCallbacks = {}; - }, - - _resetEvents: function () { - this._initEvents(); - this._bindEvents(); - }, - - _bindEvents: function () { - /* jscs:disable maximumLineLength */ - this._paper.on( - 'click dblclick mousedown contextmenu mouseup mousemove mouseover mousewheel DOMMouseScroll touchstart touchmove touchend dragenter dragleave drop', - this._firePharse.bind(this) - ); - if (window) { - window.addEventListener('resize', this._firePharse.bind(this)); - } - }, - - /** - * @method dispatchKeyEvent - * @description 派发键盘(相关)事件到脑图实例上,让实例的模块处理 - * @grammar dispatchKeyEvent(e) => {this} - * @param {Event} e 原生的 Dom 事件对象 - */ - dispatchKeyEvent: function (e) { - this._firePharse(e); - }, - - _firePharse: function (e) { - var beforeEvent, preEvent, executeEvent; - - if (e.type == 'DOMMouseScroll') { - e.type = 'mousewheel'; - e.wheelDelta = e.originEvent.wheelDelta = e.originEvent.detail * -10; - e.wheelDeltaX = e.originEvent.mozMovementX; - e.wheelDeltaY = e.originEvent.mozMovementY; - } - - beforeEvent = new MinderEvent('before' + e.type, e, true); - if (this._fire(beforeEvent)) { - return; - } - preEvent = new MinderEvent('pre' + e.type, e, true); - executeEvent = new MinderEvent(e.type, e, true); - - if (this._fire(preEvent) || this._fire(executeEvent)) this._fire(new MinderEvent('after' + e.type, e, false)); - }, - - _interactChange: function (e) { - var me = this; - if (me._interactScheduled) return; - setTimeout(function () { - me._fire(new MinderEvent('interactchange')); - me._interactScheduled = false; - }, 100); - me._interactScheduled = true; - }, - - _listen: function (type, callback) { - var callbacks = this._eventCallbacks[type] || (this._eventCallbacks[type] = []); - callbacks.push(callback); - }, - - _fire: function (e) { - /** - * @property minder - * @description 产生事件的 Minder 对象 - * @for MinderShape - * @type {Minder} - */ - e.minder = this; - - var status = this.getStatus(); - var callbacks = this._eventCallbacks[e.type.toLowerCase()] || []; - - if (status) { - callbacks = callbacks.concat(this._eventCallbacks[status + '.' + e.type.toLowerCase()] || []); - } - - if (callbacks.length === 0) { - return; - } - - var lastStatus = this.getStatus(); - for (var i = 0; i < callbacks.length; i++) { - callbacks[i].call(this, e); - - /* this.getStatus() != lastStatus ||*/ - if (e.shouldStopPropagationImmediately()) { - break; - } - } - - return e.shouldStopPropagation(); - }, - - on: function (name, callback) { - var km = this; - name.split(/\s+/).forEach(function (n) { - km._listen(n.toLowerCase(), callback); - }); - return this; - }, - - off: function (name, callback) { - var types = name.split(/\s+/); - var i, j, callbacks, removeIndex; - for (i = 0; i < types.length; i++) { - callbacks = this._eventCallbacks[types[i].toLowerCase()]; - if (callbacks) { - removeIndex = null; - for (j = 0; j < callbacks.length; j++) { - if (callbacks[j] == callback) { - removeIndex = j; - } - } - if (removeIndex !== null) { - callbacks.splice(removeIndex, 1); - } - } - } - }, - - fire: function (type, params) { - var e = new MinderEvent(type, params); - this._fire(e); - return this; - }, - }); - - module.exports = MinderEvent; -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/focus.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/focus.js deleted file mode 100644 index 4139d994..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/focus.js +++ /dev/null @@ -1,43 +0,0 @@ -define(function (require, exports, module) { - var kity = require('./kity'); - var Minder = require('./minder'); - - Minder.registerInitHook(function () { - this.on('beforemousedown', function (e) { - // FIXME:如果遇到事件触发问题,需要检查这里 - if (e.kityEvent.targetShape.__KityClassName === 'Paper') return; - e.preventDefault(); - this.focus(); - }); - this.on('paperrender', function () { - this.focus(); - }); - }); - - kity.extendClass(Minder, { - focus: function () { - if (!this.isFocused()) { - var renderTarget = this._renderTarget; - renderTarget.classList.add('focus'); - this.renderNodeBatch(this.getSelectedNodes()); - } - this.fire('focus'); - return this; - }, - - blur: function () { - if (this.isFocused()) { - var renderTarget = this._renderTarget; - renderTarget.classList.remove('focus'); - this.renderNodeBatch(this.getSelectedNodes()); - } - this.fire('blur'); - return this; - }, - - isFocused: function () { - var renderTarget = this._renderTarget; - return renderTarget && renderTarget.classList.contains('focus'); - }, - }); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/keymap.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/keymap.js deleted file mode 100644 index 99e5e88a..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/keymap.js +++ /dev/null @@ -1,128 +0,0 @@ -define(function(require, exports, module) { - var keymap = { - 'Backspace': 8, - 'Tab': 9, - 'Enter': 13, - - 'Shift': 16, - 'Control': 17, - 'Alt': 18, - 'CapsLock': 20, - - 'Esc': 27, - - 'Spacebar': 32, - - 'PageUp': 33, - 'PageDown': 34, - 'End': 35, - 'Home': 36, - - 'Insert': 45, - - 'Left': 37, - 'Up': 38, - 'Right': 39, - 'Down': 40, - - 'direction': { - 37: 1, - 38: 1, - 39: 1, - 40: 1 - }, - - 'Del': 46, - - 'NumLock': 144, - - 'Cmd': 91, - 'CmdFF': 224, - 'F1': 112, - 'F2': 113, - 'F3': 114, - 'F4': 115, - 'F5': 116, - 'F6': 117, - 'F7': 118, - 'F8': 119, - 'F9': 120, - 'F10': 121, - 'F11': 122, - 'F12': 123, - - '`': 192, - '=': 187, - '-': 189, - - '/': 191, - '.': 190, - controlKeys: { - 16: 1, - 17: 1, - 18: 1, - 20: 1, - 91: 1, - 224: 1 - }, - 'notContentChange': { - 13: 1, - 9: 1, - - 33: 1, - 34: 1, - 35: 1, - 36: 1, - - 16: 1, - 17: 1, - 18: 1, - 20: 1, - 91: 1, - - //上下左右 - 37: 1, - 38: 1, - 39: 1, - 40: 1, - - 113: 1, - 114: 1, - 115: 1, - 144: 1, - 27: 1 - }, - - 'isSelectedNodeKey': { - //上下左右 - 37: 1, - 38: 1, - 39: 1, - 40: 1, - 13: 1, - 9: 1 - } - }; - - // 小写适配 - for (var key in keymap) { - if (keymap.hasOwnProperty(key)) { - keymap[key.toLowerCase()] = keymap[key]; - } - } - var aKeyCode = 65; - var aCharCode = 'a'.charCodeAt(0); - - // letters - 'abcdefghijklmnopqrstuvwxyz'.split('').forEach(function(letter) { - keymap[letter] = aKeyCode + (letter.charCodeAt(0) - aCharCode); - }); - - // numbers - var n = 9; - do { - keymap[n.toString()] = n + 48; - } while (--n); - - module.exports = keymap; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/keyreceiver.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/keyreceiver.js deleted file mode 100644 index 1206e494..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/keyreceiver.js +++ /dev/null @@ -1,66 +0,0 @@ -define(function(require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Minder = require('./minder'); - - function listen(element, type, handler) { - type.split(' ').forEach(function(name) { - element.addEventListener(name, handler, false); - }); - } - - Minder.registerInitHook(function(option) { - this.setDefaultOptions({ - enableKeyReceiver: true - }); - if (this.getOption('enableKeyReceiver')) { - this.on('paperrender', function() { - this._initKeyReceiver(); - }); - } - }); - - kity.extendClass(Minder, { - _initKeyReceiver: function() { - - if (this._keyReceiver) return; - - var receiver = this._keyReceiver = document.createElement('input'); - receiver.classList.add('km-receiver'); - - var renderTarget = this._renderTarget; - renderTarget.appendChild(receiver); - - var minder = this; - - listen(receiver, 'keydown keyup keypress copy paste blur focus input', function(e) { - switch (e.type) { - case 'blur': - minder.blur(); - break; - case 'focus': - minder.focus(); - break; - case 'input': - receiver.value = null; - break; - } - minder._firePharse(e); - e.preventDefault(); - }); - - this.on('focus', function() { - receiver.select(); - receiver.focus(); - }); - this.on('blur', function() { - receiver.blur(); - }); - - if (this.isFocused()) { - receiver.select(); - receiver.focus(); - } - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/kity.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/kity.js deleted file mode 100644 index c95bf84c..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/kity.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @fileOverview - * - * Kity 引入 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - module.exports = window.kity; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/layout.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/layout.js deleted file mode 100644 index 666deae7..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/layout.js +++ /dev/null @@ -1,523 +0,0 @@ -define(function(require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Minder = require('./minder'); - var MinderNode = require('./node'); - var MinderEvent = require('./event'); - var Command = require('./command'); - - var _layouts = {}; - var _defaultLayout; - - function register(name, layout) { - _layouts[name] = layout; - _defaultLayout = _defaultLayout || name; - } - - /** - * @class Layout 布局基类,具体布局需要从该类派生 - */ - var Layout = kity.createClass('Layout', { - - /** - * @abstract - * - * 子类需要实现的布局算法,该算法输入一个节点,排布该节点的子节点(相对父节点的变换) - * - * @param {MinderNode} node 需要布局的节点 - * - * @example - * - * doLayout: function(node) { - * var children = node.getChildren(); - * // layout calculation - * children[i].setLayoutTransform(new kity.Matrix().translate(x, y)); - * } - */ - doLayout: function(parent, children) { - throw new Error('Not Implement: Layout.doLayout()'); - }, - - /** - * 对齐指定的节点 - * - * @param {Array} nodes 要对齐的节点 - * @param {string} border 对齐边界,允许取值 left, right, top, bottom - * - */ - align: function(nodes, border, offset) { - var me = this; - offset = offset || 0; - nodes.forEach(function(node) { - var tbox = me.getTreeBox([node]); - var matrix = node.getLayoutTransform(); - switch (border) { - case 'left': - return matrix.translate(offset - tbox.left, 0); - case 'right': - return matrix.translate(offset - tbox.right, 0); - case 'top': - return matrix.translate(0, offset - tbox.top); - case 'bottom': - return matrix.translate(0, offset - tbox.bottom); - } - }); - }, - - stack: function(nodes, axis, distance) { - var me = this; - - var position = 0; - - distance = distance || function(node, next, axis) { - return node.getStyle({ - x: 'margin-right', - y: 'margin-bottom' - }[axis]) + next.getStyle({ - x: 'margin-left', - y: 'margin-top' - }[axis]); - }; - - nodes.forEach(function(node, index, nodes) { - var tbox = me.getTreeBox([node]); - - var size = { - x: tbox.width, - y: tbox.height - }[axis]; - var offset = { - x: tbox.left, - y: tbox.top - }[axis]; - - var matrix = node.getLayoutTransform(); - - if (axis == 'x') { - matrix.translate(position - offset, 0); - } else { - matrix.translate(0, position - offset); - } - position += size; - if (nodes[index + 1]) - position += distance(node, nodes[index + 1], axis); - }); - return position; - }, - - move: function(nodes, dx, dy) { - nodes.forEach(function(node) { - node.getLayoutTransform().translate(dx, dy); - }); - }, - - /** - * 工具方法:获取给点的节点所占的布局区域 - * - * @param {MinderNode[]} nodes 需要计算的节点 - * - * @return {Box} 计算结果 - */ - getBranchBox: function(nodes) { - var box = new kity.Box(); - var i, node, matrix, contentBox; - for (i = 0; i < nodes.length; i++) { - node = nodes[i]; - matrix = node.getLayoutTransform(); - contentBox = node.getContentBox(); - box = box.merge(matrix.transformBox(contentBox)); - } - - return box; - }, - - /** - * 工具方法:计算给定的节点的子树所占的布局区域 - * - * @param {MinderNode} nodes 需要计算的节点 - * - * @return {Box} 计算的结果 - */ - getTreeBox: function(nodes) { - - var i, node, matrix, treeBox; - - var box = new kity.Box(); - - if (!(nodes instanceof Array)) nodes = [nodes]; - - for (i = 0; i < nodes.length; i++) { - node = nodes[i]; - matrix = node.getLayoutTransform(); - - treeBox = node.getContentBox(); - - if (node.isExpanded() && node.children.length) { - treeBox = treeBox.merge(this.getTreeBox(node.children)); - } - - box = box.merge(matrix.transformBox(treeBox)); - } - - return box; - }, - - getOrderHint: function(node) { - return []; - } - }); - - Layout.register = register; - - Minder.registerInitHook(function(options) { - this.refresh(); - }); - - /** - * 布局支持池子管理 - */ - utils.extend(Minder, { - - getLayoutList: function() { - return _layouts; - }, - - getLayoutInstance: function(name) { - var LayoutClass = _layouts[name]; - if (!LayoutClass) throw new Error('Missing Layout: ' + name); - var layout = new LayoutClass(); - return layout; - } - }); - - /** - * MinderNode 上的布局支持 - */ - kity.extendClass(MinderNode, { - - /** - * 获得当前节点的布局名称 - * - * @return {String} - */ - getLayout: function() { - var layout = this.getData('layout'); - - layout = layout || (this.isRoot() ? _defaultLayout : this.parent.getLayout()); - - return layout; - }, - - setLayout: function(name) { - if (name) { - if (name == 'inherit') { - this.setData('layout'); - } else { - this.setData('layout', name); - } - } - return this; - }, - - layout: function(name) { - - this.setLayout(name).getMinder().layout(); - - return this; - }, - - getLayoutInstance: function() { - return Minder.getLayoutInstance(this.getLayout()); - }, - - getOrderHint: function(refer) { - return this.parent.getLayoutInstance().getOrderHint(this); - }, - - /** - * 获取当前节点相对于父节点的布局变换 - */ - getLayoutTransform: function() { - return this._layoutTransform || new kity.Matrix(); - }, - - /** - * 第一轮布局计算后,获得的全局布局位置 - * - * @return {[type]} [description] - */ - getGlobalLayoutTransformPreview: function() { - var pMatrix = this.parent ? this.parent.getLayoutTransform() : new kity.Matrix(); - var matrix = this.getLayoutTransform(); - var offset = this.getLayoutOffset(); - if (offset) { - matrix = matrix.clone().translate(offset.x, offset.y); - } - return pMatrix.merge(matrix); - }, - - getLayoutPointPreview: function() { - return this.getGlobalLayoutTransformPreview().transformPoint(new kity.Point()); - }, - - /** - * 获取节点相对于全局的布局变换 - */ - getGlobalLayoutTransform: function() { - if (this._globalLayoutTransform) { - return this._globalLayoutTransform; - } else if (this.parent) { - return this.parent.getGlobalLayoutTransform(); - } else { - return new kity.Matrix(); - } - }, - - /** - * 设置当前节点相对于父节点的布局变换 - */ - setLayoutTransform: function(matrix) { - this._layoutTransform = matrix; - return this; - }, - - /** - * 设置当前节点相对于全局的布局变换(冗余优化) - */ - setGlobalLayoutTransform: function(matrix) { - this.getRenderContainer().setMatrix(this._globalLayoutTransform = matrix); - return this; - }, - - setVertexIn: function(p) { - this._vertexIn = p; - }, - - setVertexOut: function(p) { - this._vertexOut = p; - }, - - getVertexIn: function() { - return this._vertexIn || new kity.Point(); - }, - - getVertexOut: function() { - return this._vertexOut || new kity.Point(); - }, - - getLayoutVertexIn: function() { - return this.getGlobalLayoutTransform().transformPoint(this.getVertexIn()); - }, - - getLayoutVertexOut: function() { - return this.getGlobalLayoutTransform().transformPoint(this.getVertexOut()); - }, - - setLayoutVectorIn: function(v) { - this._layoutVectorIn = v; - return this; - }, - - setLayoutVectorOut: function(v) { - this._layoutVectorOut = v; - return this; - }, - - getLayoutVectorIn: function() { - return this._layoutVectorIn || new kity.Vector(); - }, - - getLayoutVectorOut: function() { - return this._layoutVectorOut || new kity.Vector(); - }, - - getLayoutBox: function() { - var matrix = this.getGlobalLayoutTransform(); - return matrix.transformBox(this.getContentBox()); - }, - - getLayoutPoint: function() { - var matrix = this.getGlobalLayoutTransform(); - return matrix.transformPoint(new kity.Point()); - }, - - getLayoutOffset: function() { - if (!this.parent) return new kity.Point(); - - // 影响当前节点位置的是父节点的布局 - var data = this.getData('layout_' + this.parent.getLayout() + '_offset'); - - if (data) return new kity.Point(data.x, data.y); - - return new kity.Point(); - }, - - setLayoutOffset: function(p) { - if (!this.parent) return this; - - this.setData('layout_' + this.parent.getLayout() + '_offset', p ? { - x: p.x, - y: p.y - } : undefined); - - return this; - }, - - hasLayoutOffset: function() { - return !!this.getData('layout_' + this.parent.getLayout() + '_offset'); - }, - - resetLayoutOffset: function() { - return this.setLayoutOffset(null); - }, - - getLayoutRoot: function() { - if (this.isLayoutRoot()) { - return this; - } - return this.parent.getLayoutRoot(); - }, - - isLayoutRoot: function() { - return this.getData('layout') || this.isRoot(); - } - }); - - /** - * Minder 上的布局支持 - */ - kity.extendClass(Minder, { - - layout: function() { - - var duration = this.getOption('layoutAnimationDuration'); - - this.getRoot().traverse(function(node) { - // clear last results - node.setLayoutTransform(null); - }); - - function layoutNode(node, round) { - - // layout all children first - // 剪枝:收起的节点无需计算 - if (node.isExpanded() || true) { - node.children.forEach(function(child) { - layoutNode(child, round); - }); - } - - var layout = node.getLayoutInstance(); - // var childrenInFlow = node.getChildren().filter(function(child) { - // return !child.hasLayoutOffset(); - // }); - layout.doLayout(node, node.getChildren(), round); - } - - // 第一轮布局 - layoutNode(this.getRoot(), 1); - - // 第二轮布局 - layoutNode(this.getRoot(), 2); - - var minder = this; - this.applyLayoutResult(this.getRoot(), duration, function() { - /** - * 当节点>200, 不使用动画时, 此处逻辑变为同步逻辑, 外部minder.on事件无法 - * 被提前录入, 因此增加setTimeout - * @author Naixor - */ - setTimeout(function () { - minder.fire('layoutallfinish'); - }, 0); - }); - - return this.fire('layout'); - }, - - refresh: function() { - this.getRoot().renderTree(); - this.layout().fire('contentchange')._interactChange(); - return this; - }, - - applyLayoutResult: function(root, duration, callback) { - root = root || this.getRoot(); - var me = this; - - var complex = root.getComplex(); - - function consume() { - if (!--complex) { - if (callback) { - callback(); - } - } - } - - // 节点复杂度大于 100,关闭动画 - if (complex > 200) duration = 0; - - function applyMatrix(node, matrix) { - node.setGlobalLayoutTransform(matrix); - - me.fire('layoutapply', { - node: node, - matrix: matrix - }); - } - - function apply(node, pMatrix) { - var matrix = node.getLayoutTransform().merge(pMatrix.clone()); - var lastMatrix = node.getGlobalLayoutTransform() || new kity.Matrix(); - - var offset = node.getLayoutOffset(); - matrix.translate(offset.x, offset.y); - - matrix.m.e = Math.round(matrix.m.e); - matrix.m.f = Math.round(matrix.m.f); - - // 如果当前有动画,停止动画 - if (node._layoutTimeline) { - node._layoutTimeline.stop(); - node._layoutTimeline = null; - } - - // 如果要求以动画形式来更新,创建动画 - if (duration) { - node._layoutTimeline = new kity.Animator(lastMatrix, matrix, applyMatrix) - .start(node, duration, 'ease') - .on('finish', function() { - //可能性能低的时候会丢帧,手动添加一帧 - setTimeout(function() { - applyMatrix(node, matrix); - me.fire('layoutfinish', { - node: node, - matrix: matrix - }); - consume(); - }, 150); - }); - } - - // 否则直接更新 - else { - applyMatrix(node, matrix); - me.fire('layoutfinish', { - node: node, - matrix: matrix - }); - consume(); - } - - for (var i = 0; i < node.children.length; i++) { - apply(node.children[i], matrix); - } - } - apply(root, root.parent ? root.parent.getGlobalLayoutTransform() : new kity.Matrix()); - return this; - } - }); - - module.exports = Layout; -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/minder.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/minder.js deleted file mode 100644 index 469fb6fc..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/minder.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @fileOverview - * - * KityMinder 类,暴露在 window 上的唯一变量 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - - var _initHooks = []; - - var Minder = kity.createClass('Minder', { - constructor: function(options) { - this._options = utils.extend({}, options); - - var initHooks = _initHooks.slice(); - - var initHook; - while (initHooks.length) { - initHook = initHooks.shift(); - if (typeof(initHook) == 'function') { - initHook.call(this, this._options); - } - } - - this.fire('finishInitHook'); - } - }); - - Minder.version = '1.4.43'; - - Minder.registerInitHook = function(hook) { - _initHooks.push(hook); - }; - - module.exports = Minder; -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/module.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/module.js deleted file mode 100644 index 9adaf2c3..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/module.js +++ /dev/null @@ -1,149 +0,0 @@ -define(function (require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Minder = require('./minder'); - - /* 已注册的模块 */ - var _modules = {}; - - exports.register = function (name, module) { - _modules[name] = module; - }; - - /* 模块初始化 */ - Minder.registerInitHook(function () { - this._initModules(); - }); - - // 模块声明周期维护 - kity.extendClass(Minder, { - _initModules: function () { - var modulesPool = _modules; - var modulesToLoad = this._options.modules || utils.keys(modulesPool); - - this._commands = {}; - this._query = {}; - this._modules = {}; - this._rendererClasses = {}; - - var i, name, type, module, moduleDeals, dealCommands, dealEvents, dealRenderers; - - var me = this; - for (i = 0; i < modulesToLoad.length; i++) { - name = modulesToLoad[i]; - - if (!modulesPool[name]) continue; - - // 执行模块初始化,抛出后续处理对象 - - if (typeof modulesPool[name] == 'function') { - moduleDeals = modulesPool[name].call(me); - } else { - moduleDeals = modulesPool[name]; - } - this._modules[name] = moduleDeals; - - if (!moduleDeals) continue; - - if (moduleDeals.defaultOptions) { - me.setDefaultOptions(moduleDeals.defaultOptions); - } - - if (moduleDeals.init) { - moduleDeals.init.call(me, this._options); - } - - /** - * @Desc: 判断是否支持原生clipboard事件,如果支持,则对pager添加其监听 - * @Editor: Naixor - * @Date: 2015.9.20 - */ - /** - * 由于当前脑图解构问题,clipboard暂时全权交由玩不托管 - * @Editor: Naixor - * @Date: 2015.9.24 - */ - // if (name === 'ClipboardModule' && this.supportClipboardEvent && !kity.Browser.gecko) { - // var on = function () { - // var clipBoardReceiver = this.clipBoardReceiver || document; - - // if (document.addEventListener) { - // clipBoardReceiver.addEventListener.apply(this, arguments); - // } else { - // arguments[0] = 'on' + arguments[0]; - // clipBoardReceiver.attachEvent.apply(this, arguments); - // } - // } - // for (var command in moduleDeals.clipBoardEvents) { - // on(command, moduleDeals.clipBoardEvents[command]); - // } - // }; - - // command加入命令池子 - dealCommands = moduleDeals.commands; - for (name in dealCommands) { - this._commands[name.toLowerCase()] = new dealCommands[name](); - } - - // 绑定事件 - dealEvents = moduleDeals.events; - if (dealEvents) { - for (type in dealEvents) { - me.on(type, dealEvents[type]); - } - } - - // 渲染器 - dealRenderers = moduleDeals.renderers; - - if (dealRenderers) { - for (type in dealRenderers) { - this._rendererClasses[type] = this._rendererClasses[type] || []; - - if (utils.isArray(dealRenderers[type])) { - this._rendererClasses[type] = this._rendererClasses[type].concat(dealRenderers[type]); - } else { - this._rendererClasses[type].push(dealRenderers[type]); - } - } - } - - //添加模块的快捷键 - if (moduleDeals.commandShortcutKeys) { - this.addCommandShortcutKeys(moduleDeals.commandShortcutKeys); - } - } - }, - - _garbage: function () { - // this.clearSelect(); - - while (this._root.getChildren().length) { - this._root.removeChild(0); - } - }, - - destroy: function () { - var modules = this._modules; - - this._resetEvents(); - this._garbage(); - - for (var key in modules) { - if (!modules[key].destroy) continue; - modules[key].destroy.call(this); - } - }, - - reset: function () { - var modules = this._modules; - - this._garbage(); - - for (var key in modules) { - if (!modules[key].reset) continue; - modules[key].reset.call(this); - } - }, - }); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/node.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/node.js deleted file mode 100644 index b4ad8a3b..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/node.js +++ /dev/null @@ -1,407 +0,0 @@ -define(function(require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Minder = require('./minder'); - - /** - * @class MinderNode - * - * 表示一个脑图节点 - */ - var MinderNode = kity.createClass('MinderNode', { - - /** - * 创建一个游离的脑图节点 - * - * @param {String|Object} textOrData - * 节点的初始数据或文本 - */ - constructor: function(textOrData) { - - // 指针 - this.parent = null; - this.root = this; - this.children = []; - - // 数据 - this.data = { - id: utils.guid(), - created: +new Date() - }; - - // 绘图容器 - this.initContainers(); - - if (utils.isString(textOrData)) { - this.setText(textOrData); - } else if (utils.isObject(textOrData)) { - utils.extend(this.data, textOrData); - } - }, - - initContainers: function() { - this.rc = new kity.Group().setId(utils.uuid('minder_node')); - this.rc.minderNode = this; - }, - - /** - * 判断节点是否根节点 - */ - isRoot: function() { - return this.root === this; - }, - - /** - * 判断节点是否叶子 - */ - isLeaf: function() { - return this.children.length === 0; - }, - - /** - * 获取节点的根节点 - */ - getRoot: function() { - return this.root || this; - }, - - /** - * 获得节点的父节点 - */ - getParent: function() { - return this.parent; - }, - - getSiblings: function() { - var children = this.parent.children; - var siblings = []; - var self = this; - children.forEach(function(child) { - if (child != self) siblings.push(child); - }); - return siblings; - }, - - /** - * 获得节点的深度 - */ - getLevel: function() { - var level = 0, - ancestor = this.parent; - while (ancestor) { - level++; - ancestor = ancestor.parent; - } - return level; - }, - - /** - * 获得节点的复杂度(即子树中节点的数量) - */ - getComplex: function() { - var complex = 0; - this.traverse(function() { - complex++; - }); - return complex; - }, - - /** - * 获得节点的类型(root|main|sub) - */ - getType: function(type) { - this.type = ['root', 'main', 'sub'][Math.min(this.getLevel(), 2)]; - return this.type; - }, - - /** - * 判断当前节点是否被测试节点的祖先 - * @param {MinderNode} test 被测试的节点 - */ - isAncestorOf: function(test) { - var ancestor = test.parent; - while (ancestor) { - if (ancestor == this) return true; - ancestor = ancestor.parent; - } - return false; - }, - - getData: function(key) { - return key ? this.data[key] : this.data; - }, - - setData: function(key, value) { - if (typeof key == 'object') { - var data = key; - for (key in data) if (data.hasOwnProperty(key)) { - this.data[key] = data[key]; - } - } - else { - this.data[key] = value; - } - return this; - }, - - /** - * 设置节点的文本数据 - * @param {String} text 文本数据 - */ - setText: function(text) { - return this.data.text = text; - }, - - /** - * 获取节点的文本数据 - * @return {String} - */ - getText: function() { - return this.data.text || null; - }, - - /** - * 先序遍历当前节点树 - * @param {Function} fn 遍历函数 - */ - preTraverse: function(fn, excludeThis) { - var children = this.getChildren(); - if (!excludeThis) fn(this); - for (var i = 0; i < children.length; i++) { - children[i].preTraverse(fn); - } - }, - - /** - * 后序遍历当前节点树 - * @param {Function} fn 遍历函数 - */ - postTraverse: function(fn, excludeThis) { - var children = this.getChildren(); - for (var i = 0; i < children.length; i++) { - children[i].postTraverse(fn); - } - if (!excludeThis) fn(this); - }, - - traverse: function(fn, excludeThis) { - return this.postTraverse(fn, excludeThis); - }, - - getChildren: function() { - return this.children; - }, - - getIndex: function() { - return this.parent ? this.parent.children.indexOf(this) : -1; - }, - - insertChild: function(node, index) { - if (index === undefined) { - index = this.children.length; - } - if (node.parent) { - node.parent.removeChild(node); - } - node.parent = this; - node.root = this.root; - - this.children.splice(index, 0, node); - }, - - appendChild: function(node) { - return this.insertChild(node); - }, - - prependChild: function(node) { - return this.insertChild(node, 0); - }, - - removeChild: function(elem) { - var index = elem, - removed; - if (elem instanceof MinderNode) { - index = this.children.indexOf(elem); - } - if (index >= 0) { - removed = this.children.splice(index, 1)[0]; - removed.parent = null; - removed.root = removed; - } - }, - - clearChildren: function() { - this.children = []; - }, - - getChild: function(index) { - return this.children[index]; - }, - - getRenderContainer: function() { - return this.rc; - }, - - getCommonAncestor: function(node) { - return MinderNode.getCommonAncestor(this, node); - }, - - contains: function(node) { - return this == node || this.isAncestorOf(node); - }, - - clone: function() { - var cloned = new MinderNode(); - - cloned.data = utils.clone(this.data); - - this.children.forEach(function(child) { - cloned.appendChild(child.clone()); - }); - - return cloned; - }, - - compareTo: function(node) { - - if (!utils.comparePlainObject(this.data, node.data)) return false; - if (!utils.comparePlainObject(this.temp, node.temp)) return false; - if (this.children.length != node.children.length) return false; - - var i = 0; - while (this.children[i]) { - if (!this.children[i].compareTo(node.children[i])) return false; - i++; - } - - return true; - }, - - getMinder: function() { - return this.getRoot().minder; - } - }); - - MinderNode.getCommonAncestor = function(nodeA, nodeB) { - if (nodeA instanceof Array) { - return MinderNode.getCommonAncestor.apply(this, nodeA); - } - switch (arguments.length) { - case 1: - return nodeA.parent || nodeA; - - case 2: - if (nodeA.isAncestorOf(nodeB)) { - return nodeA; - } - if (nodeB.isAncestorOf(nodeA)) { - return nodeB; - } - var ancestor = nodeA.parent; - while (ancestor && !ancestor.isAncestorOf(nodeB)) { - ancestor = ancestor.parent; - } - return ancestor; - - default: - return Array.prototype.reduce.call(arguments, - function(prev, current) { - return MinderNode.getCommonAncestor(prev, current); - }, - nodeA - ); - } - }; - - kity.extendClass(Minder, { - - getRoot: function() { - return this._root; - }, - - setRoot: function(root) { - this._root = root; - root.minder = this; - }, - - getAllNode: function() { - var nodes = []; - this.getRoot().traverse(function(node) { - nodes.push(node); - }); - return nodes; - }, - - getNodeById: function(id) { - return this.getNodesById([id])[0]; - }, - - getNodesById: function(ids) { - var nodes = this.getAllNode(); - var result = []; - nodes.forEach(function(node) { - if (ids.indexOf(node.getData('id')) != -1) { - result.push(node); - } - }); - return result; - }, - - createNode: function(textOrData, parent, index) { - var node = new MinderNode(textOrData); - this.fire('nodecreate', { - node: node, - parent: parent, - index: index - }); - this.appendNode(node, parent, index); - return node; - }, - - appendNode: function(node, parent, index) { - if (parent) parent.insertChild(node, index); - this.attachNode(node); - return this; - }, - - removeNode: function(node) { - if (node.parent) { - node.parent.removeChild(node); - this.detachNode(node); - this.fire('noderemove', { - node: node - }); - } - }, - - attachNode: function(node) { - var rc = this.getRenderContainer(); - node.traverse(function(current) { - current.attached = true; - rc.addShape(current.getRenderContainer()); - }); - rc.addShape(node.getRenderContainer()); - this.fire('nodeattach', { - node: node - }); - }, - - detachNode: function(node) { - var rc = this.getRenderContainer(); - node.traverse(function(current) { - current.attached = false; - rc.removeShape(current.getRenderContainer()); - }); - this.fire('nodedetach', { - node: node - }); - }, - - getMinderTitle: function() { - return this.getRoot().getText(); - } - - }); - - module.exports = MinderNode; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/option.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/option.js deleted file mode 100644 index c7c055f8..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/option.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @fileOverview - * - * 提供脑图选项支持 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Minder = require('./minder'); - - Minder.registerInitHook(function(options) { - this._defaultOptions = {}; - }); - - kity.extendClass(Minder, { - setDefaultOptions: function(options) { - utils.extend(this._defaultOptions, options); - return this; - }, - getOption: function(key) { - if (key) { - return key in this._options ? this._options[key] : this._defaultOptions[key]; - } else { - return utils.extend({}, this._defaultOptions, this._options); - } - }, - setOption: function(key, value) { - this._options[key] = value; - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/paper.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/paper.js deleted file mode 100644 index 9cae4ffa..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/paper.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @fileOverview - * - * 初始化渲染容器 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Minder = require('./minder'); - - Minder.registerInitHook(function() { - this._initPaper(); - }); - - kity.extendClass(Minder, { - - _initPaper: function() { - - this._paper = new kity.Paper(); - this._paper._minder = this; - this._paper.getNode().ondragstart = function(e) { - e.preventDefault(); - }; - this._paper.shapeNode.setAttribute('transform', 'translate(0.5, 0.5)'); - - this._addRenderContainer(); - - this.setRoot(this.createNode()); - - if (this._options.renderTo) { - this.renderTo(this._options.renderTo); - } - }, - - _addRenderContainer: function() { - this._rc = new kity.Group().setId(utils.uuid('minder')); - this._paper.addShape(this._rc); - }, - - renderTo: function(target) { - if (typeof(target) == 'string') { - target = document.querySelector(target); - } - if (target) { - if (target.tagName.toLowerCase() == 'script') { - var newTarget = document.createElement('div'); - newTarget.id = target.id; - newTarget.class = target.class; - target.parentNode.insertBefore(newTarget, target); - target.parentNode.removeChild(target); - target = newTarget; - } - target.classList.add('km-view'); - this._paper.renderTo(this._renderTarget = target); - this._bindEvents(); - this.fire('paperrender'); - } - return this; - }, - - getRenderContainer: function() { - return this._rc; - }, - - getPaper: function() { - return this._paper; - }, - - getRenderTarget: function() { - return this._renderTarget; - }, - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/patch.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/patch.js deleted file mode 100644 index 0ef99c19..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/patch.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * @fileOverview - * - * 打补丁 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - var kity = require('./kity'); - var Minder = require('./minder'); - - function insertNode(minder, info, parent, index) { - parent = minder.createNode(info.data, parent, index); - info.children.forEach(function(childInfo, index) { - insertNode(minder, childInfo, parent, index); - }); - return parent; - } - - function applyPatch(minder, patch) { - // patch.op - 操作,包括 remove, add, replace - // patch.path - 路径,如 '/root/children/1/data' - // patch.value - 数据,如 { text: "思路" } - var path = patch.path.split('/'); - path.shift(); - - var changed = path.shift(); - var node; - - if (changed == 'root') { - - var dataIndex = path.indexOf('data'); - if (dataIndex > -1) { - changed = 'data'; - var dataPath = path.splice(dataIndex + 1); - patch.dataPath = dataPath; - } else { - changed = 'node'; - } - - node = minder.getRoot(); - var segment, index; - while (segment = path.shift()) { - if (segment == 'children') continue; - if (typeof index != 'undefined') node = node.getChild(index); - index = +segment; - } - patch.index = index; - patch.node = node; - } - - var express = patch.express = [changed, patch.op].join('.'); - - switch (express) { - case 'theme.replace': - minder.useTheme(patch.value); - break; - case 'template.replace': - minder.useTemplate(patch.value); - break; - case 'node.add': - insertNode(minder, patch.value, patch.node, patch.index).renderTree(); - minder.layout(); - break; - case 'node.remove': - minder.removeNode(patch.node.getChild(patch.index)); - minder.layout(); - break; - case 'data.add': - case 'data.replace': - case 'data.remove': - var data = patch.node.data; - var field; - path = patch.dataPath.slice(); - while (data && path.length > 1) { - field = path.shift(); - if (field in data) { - data = data[field]; - } else if (patch.op != 'remove') { - data = data[field] = {}; - } - } - if (data) { - field = path.shift(); - data[field] = patch.value; - } - if (field == 'expandState') { - node.renderTree(); - } else { - node.render(); - } - minder.layout(); - } - - minder.fire('patch', { 'patch' : patch } ); - } - - kity.extendClass(Minder, { - applyPatches: function(patches) { - for (var i = 0; i < patches.length; i++) { - applyPatch(this, patches[i]); - } - - this.fire('contentchange'); - return this; - } - }); - -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/promise.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/promise.js deleted file mode 100644 index 5e39ad89..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/promise.js +++ /dev/null @@ -1,214 +0,0 @@ -define(function(require, exports, module) { - /*! - ** Thenable -- Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable - ** Copyright (c) 2013-2014 Ralf S. Engelschall - ** Licensed under The MIT License - ** Source-Code distributed on - */ - - /* promise states [Promises/A+ 2.1] */ - var STATE_PENDING = 0; /* [Promises/A+ 2.1.1] */ - var STATE_FULFILLED = 1; /* [Promises/A+ 2.1.2] */ - var STATE_REJECTED = 2; /* [Promises/A+ 2.1.3] */ - - /* promise object constructor */ - var Promise = function(executor) { - /* optionally support non-constructor/plain-function call */ - if (!(this instanceof Promise)) - return new Promise(executor); - - /* initialize object */ - this.id = 'Thenable/1.0.7'; - this.state = STATE_PENDING; /* initial state */ - this.fulfillValue = undefined; /* initial value */ /* [Promises/A+ 1.3, 2.1.2.2] */ - this.rejectReason = undefined; /* initial reason */ /* [Promises/A+ 1.5, 2.1.3.2] */ - this.onFulfilled = []; /* initial handlers */ - this.onRejected = []; /* initial handlers */ - - /* support optional executor function */ - if (typeof executor === 'function') - executor.call(this, this.fulfill.bind(this), this.reject.bind(this)); - }; - - /* Promise API methods */ - Promise.prototype = { - /* promise resolving methods */ - fulfill: function(value) { return deliver(this, STATE_FULFILLED, 'fulfillValue', value); }, - reject: function(value) { return deliver(this, STATE_REJECTED, 'rejectReason', value); }, - - /* 'The then Method' [Promises/A+ 1.1, 1.2, 2.2] */ - then: function(onFulfilled, onRejected) { - var curr = this; - var next = new Promise(); /* [Promises/A+ 2.2.7] */ - curr.onFulfilled.push( - resolver(onFulfilled, next, 'fulfill')); /* [Promises/A+ 2.2.2/2.2.6] */ - curr.onRejected.push( - resolver(onRejected, next, 'reject')); /* [Promises/A+ 2.2.3/2.2.6] */ - execute(curr); - return next; /* [Promises/A+ 2.2.7, 3.3] */ - } - }; - - Promise.all = function (arr) { - return new Promise(function(resolve, reject) { - var len = arr.length, - i = 0, - res = 0, - results = []; - - if (len === 0) { - resolve(results); - } - - while (i < len) { - arr[i].then( - function (result) { - results.push(result); - if (++res === len) { - resolve(results); - } - }, - function (val) { - reject(val); - } - ); - i++; - } - }); - }; - - /* deliver an action */ - var deliver = function(curr, state, name, value) { - if (curr.state === STATE_PENDING) { - curr.state = state; /* [Promises/A+ 2.1.2.1, 2.1.3.1] */ - curr[name] = value; /* [Promises/A+ 2.1.2.2, 2.1.3.2] */ - execute(curr); - } - return curr; - }; - - /* execute all handlers */ - var execute = function(curr) { - if (curr.state === STATE_FULFILLED) - execute_handlers(curr, 'onFulfilled', curr.fulfillValue); - else if (curr.state === STATE_REJECTED) - execute_handlers(curr, 'onRejected', curr.rejectReason); - }; - - /* execute particular set of handlers */ - var execute_handlers = function(curr, name, value) { - /* global process: true */ - /* global setImmediate: true */ - /* global setTimeout: true */ - - /* short-circuit processing */ - if (curr[name].length === 0) - return; - - /* iterate over all handlers, exactly once */ - var handlers = curr[name]; - curr[name] = []; /* [Promises/A+ 2.2.2.3, 2.2.3.3] */ - var func = function() { - for (var i = 0; i < handlers.length; i++) - handlers[i](value); /* [Promises/A+ 2.2.5] */ - }; - - /* execute procedure asynchronously */ /* [Promises/A+ 2.2.4, 3.1] */ - if (typeof process === 'object' && typeof process.nextTick === 'function') - process.nextTick(func); - else if (typeof setImmediate === 'function') - setImmediate(func); - else - setTimeout(func, 0); - }; - - /* generate a resolver function */ - var resolver = function(cb, next, method) { - return function(value) { - if (typeof cb !== 'function') /* [Promises/A+ 2.2.1, 2.2.7.3, 2.2.7.4] */ - next[method].call(next, value); /* [Promises/A+ 2.2.7.3, 2.2.7.4] */ - else { - var result; - try { - if (value instanceof Promise) { - result = value.then(cb); - } - else result = cb(value); - } /* [Promises/A+ 2.2.2.1, 2.2.3.1, 2.2.5, 3.2] */ - catch (e) { - next.reject(e); /* [Promises/A+ 2.2.7.2] */ - return; - } - resolve(next, result); /* [Promises/A+ 2.2.7.1] */ - } - }; - }; - - /* 'Promise Resolution Procedure' */ /* [Promises/A+ 2.3] */ - var resolve = function(promise, x) { - /* sanity check arguments */ /* [Promises/A+ 2.3.1] */ - if (promise === x) { - promise.reject(new TypeError('cannot resolve promise with itself')); - return; - } - - /* surgically check for a 'then' method - (mainly to just call the 'getter' of 'then' only once) */ - var then; - if ((typeof x === 'object' && x !== null) || typeof x === 'function') { - try { then = x.then; } /* [Promises/A+ 2.3.3.1, 3.5] */ - catch (e) { - promise.reject(e); /* [Promises/A+ 2.3.3.2] */ - return; - } - } - - /* handle own Thenables [Promises/A+ 2.3.2] - and similar 'thenables' [Promises/A+ 2.3.3] */ - if (typeof then === 'function') { - var resolved = false; - try { - /* call retrieved 'then' method */ /* [Promises/A+ 2.3.3.3] */ - then.call(x, - /* resolvePromise */ /* [Promises/A+ 2.3.3.3.1] */ - function(y) { - if (resolved) return; resolved = true; /* [Promises/A+ 2.3.3.3.3] */ - if (y === x) /* [Promises/A+ 3.6] */ - promise.reject(new TypeError('circular thenable chain')); - else - resolve(promise, y); - }, - - /* rejectPromise */ /* [Promises/A+ 2.3.3.3.2] */ - function(r) { - if (resolved) return; resolved = true; /* [Promises/A+ 2.3.3.3.3] */ - promise.reject(r); - } - ); - } - catch (e) { - if (!resolved) /* [Promises/A+ 2.3.3.3.3] */ - promise.reject(e); /* [Promises/A+ 2.3.3.3.4] */ - } - return; - } - - /* handle other values */ - promise.fulfill(x); /* [Promises/A+ 2.3.4, 2.3.3.4] */ - }; - - Promise.resolve = function(value) { - return new Promise(function(resolve) { - resolve(value); - }); - }; - - Promise.reject = function(reason) { - return new Promise(function(resolve, reject) { - reject(reason); - }); - }; - - /* export API */ - module.exports = Promise; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/readonly.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/readonly.js deleted file mode 100644 index cfa2bf26..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/readonly.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @fileOverview - * - * 只读模式支持 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function (require, exports, module) { - var kity = require('./kity'); - var Minder = require('./minder'); - var MinderEvent = require('./event'); - - Minder.registerInitHook(function (options) { - if (options.readOnly) { - this.setDisabled(); - } - }); - - kity.extendClass(Minder, { - disable: function () { - var me = this; - //禁用命令 - me.bkqueryCommandState = me.queryCommandState; - me.bkqueryCommandValue = me.queryCommandValue; - me.queryCommandState = function (type) { - var cmd = this._getCommand(type); - if (cmd && cmd.enableReadOnly) { - return me.bkqueryCommandState.apply(me, arguments); - } - return -1; - }; - me.queryCommandValue = function (type) { - var cmd = this._getCommand(type); - if (cmd && cmd.enableReadOnly) { - return me.bkqueryCommandValue.apply(me, arguments); - } - return null; - }; - this.setStatus('readonly'); - me._interactChange(); - }, - - enable: function () { - var me = this; - - if (me.bkqueryCommandState) { - me.queryCommandState = me.bkqueryCommandState; - delete me.bkqueryCommandState; - } - if (me.bkqueryCommandValue) { - me.queryCommandValue = me.bkqueryCommandValue; - delete me.bkqueryCommandValue; - } - - this.setStatus('normal'); - - me._interactChange(); - }, - }); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/render.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/render.js deleted file mode 100644 index ae4a5e0f..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/render.js +++ /dev/null @@ -1,261 +0,0 @@ -define(function(require, exports, module) { - - var kity = require('./kity'); - var Minder = require('./minder'); - var MinderNode = require('./node'); - - var Renderer = kity.createClass('Renderer', { - constructor: function(node) { - this.node = node; - }, - - create: function(node) { - throw new Error('Not implement: Renderer.create()'); - }, - - shouldRender: function(node) { - return true; - }, - - watchChange: function(data) { - var changed; - - if (this.watchingData === undefined) { - changed = true; - } else if (this.watchingData != data) { - changed = true; - } else { - changed = false; - } - - this.watchingData = data; - }, - - shouldDraw: function(node) { - return true; - }, - - update: function(shape, node, box) { - if (this.shouldDraw()) this.draw(shape, node); - return this.place(shape, node, box); - }, - - draw: function(shape, node) { - throw new Error('Not implement: Renderer.draw()'); - }, - - place: function(shape, node, box) { - throw new Error('Not implement: Renderer.place()'); - }, - - getRenderShape: function() { - return this._renderShape || null; - }, - - setRenderShape: function(shape) { - this._renderShape = shape; - } - }); - - function createMinderExtension() { - - function createRendererForNode(node, registered) { - var renderers = []; - - ['center', 'left', 'right', 'top', 'bottom', 'outline', 'outside'].forEach(function(section) { - var before = 'before' + section; - var after = 'after' + section; - - if (registered[before]) { - renderers = renderers.concat(registered[before]); - } - if (registered[section]) { - renderers = renderers.concat(registered[section]); - } - if (registered[after]) { - renderers = renderers.concat(registered[after]); - } - }); - - node._renderers = renderers.map(function(Renderer) { - return new Renderer(node); - }); - } - - return { - renderNodeBatch: function(nodes) { - var rendererClasses = this._rendererClasses; - var lastBoxes = []; - var rendererCount = 0; - var i, j, renderer, node; - - if (!nodes.length) return; - - for (j = 0; j < nodes.length; j++) { - node = nodes[j]; - if (!node._renderers) { - createRendererForNode(node, rendererClasses); - } - node._contentBox = new kity.Box(); - this.fire('beforerender', { - node: node - }); - } - - // 所有节点渲染器数量是一致的 - rendererCount = nodes[0]._renderers.length; - - for (i = 0; i < rendererCount; i++) { - - // 获取延迟盒子数据 - for (j = 0; j < nodes.length; j++) { - if (typeof(lastBoxes[j]) == 'function') { - lastBoxes[j] = lastBoxes[j](); - } - if (!(lastBoxes[j] instanceof kity.Box)) { - lastBoxes[j] = new kity.Box(lastBoxes[j]); - } - } - - for (j = 0; j < nodes.length; j++) { - node = nodes[j]; - renderer = node._renderers[i]; - - // 合并盒子 - if (lastBoxes[j]) { - node._contentBox = node._contentBox.merge(lastBoxes[j]); - renderer.contentBox = lastBoxes[j]; - } - - // 判断当前上下文是否应该渲染 - if (renderer.shouldRender(node)) { - - // 应该渲染,但是渲染图形没创建过,需要创建 - if (!renderer.getRenderShape()) { - renderer.setRenderShape(renderer.create(node)); - if (renderer.bringToBack) { - node.getRenderContainer().prependShape(renderer.getRenderShape()); - } else { - node.getRenderContainer().appendShape(renderer.getRenderShape()); - } - } - - // 强制让渲染图形显示 - renderer.getRenderShape().setVisible(true); - - // 更新渲染图形 - lastBoxes[j] = renderer.update(renderer.getRenderShape(), node, node._contentBox); - } - - // 如果不应该渲染,但是渲染图形创建过了,需要隐藏起来 - else if (renderer.getRenderShape()) { - renderer.getRenderShape().setVisible(false); - lastBoxes[j] = null; - } - } - } - - for (j = 0; j < nodes.length; j++) { - this.fire('noderender', { - node: nodes[j] - }); - } - }, - - renderNode: function(node) { - var rendererClasses = this._rendererClasses; - var i, latestBox, renderer; - - if (!node._renderers) { - createRendererForNode(node, rendererClasses); - } - - this.fire('beforerender', { - node: node - }); - - node._contentBox = new kity.Box(); - - node._renderers.forEach(function(renderer) { - - // 判断当前上下文是否应该渲染 - if (renderer.shouldRender(node)) { - - // 应该渲染,但是渲染图形没创建过,需要创建 - if (!renderer.getRenderShape()) { - renderer.setRenderShape(renderer.create(node)); - if (renderer.bringToBack) { - node.getRenderContainer().prependShape(renderer.getRenderShape()); - } else { - node.getRenderContainer().appendShape(renderer.getRenderShape()); - } - } - - // 强制让渲染图形显示 - renderer.getRenderShape().setVisible(true); - - // 更新渲染图形 - latestBox = renderer.update(renderer.getRenderShape(), node, node._contentBox); - - if (typeof(latestBox) == 'function') latestBox = latestBox(); - - // 合并渲染区域 - if (latestBox) { - node._contentBox = node._contentBox.merge(latestBox); - renderer.contentBox = latestBox; - } - } - - // 如果不应该渲染,但是渲染图形创建过了,需要隐藏起来 - else if (renderer.getRenderShape()) { - renderer.getRenderShape().setVisible(false); - } - - }); - - this.fire('noderender', { - node: node - }); - } - }; - } - - kity.extendClass(Minder, createMinderExtension()); - - kity.extendClass(MinderNode, { - render: function() { - if (!this.attached) return; - this.getMinder().renderNode(this); - return this; - }, - renderTree: function() { - if (!this.attached) return; - var list = []; - this.traverse(function(node) { - list.push(node); - }); - this.getMinder().renderNodeBatch(list); - return this; - }, - getRenderer: function(type) { - var rs = this._renderers; - if (!rs) return null; - for (var i = 0; i < rs.length; i++) { - if (rs[i].getType() == type) return rs[i]; - } - return null; - }, - getContentBox: function() { - //if (!this._contentBox) this.render(); - return this.parent && this.parent.isCollapsed() ? new kity.Box() : (this._contentBox || new kity.Box()); - }, - getRenderBox: function(rendererType, refer) { - var renderer = rendererType && this.getRenderer(rendererType); - var contentBox = renderer ? renderer.contentBox : this.getContentBox(); - var ctm = kity.Matrix.getCTM(this.getRenderContainer(), refer || 'paper'); - return ctm.transformBox(contentBox); - } - }); - - module.exports = Renderer; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/select.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/select.js deleted file mode 100644 index 4366b22b..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/select.js +++ /dev/null @@ -1,146 +0,0 @@ - -define(function(require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Minder = require('./minder'); - var MinderNode = require('./node'); - - Minder.registerInitHook(function() { - this._initSelection(); - }); - - // 选区管理 - kity.extendClass(Minder, { - _initSelection: function() { - this._selectedNodes = []; - }, - renderChangedSelection: function(last) { - var current = this.getSelectedNodes(); - var changed = []; - - current.forEach(function(node) { - if (last.indexOf(node) == -1) { - changed.push(node); - } - }); - - last.forEach(function(node) { - if (current.indexOf(node) == -1) { - changed.push(node); - } - }); - - if (changed.length) { - this._interactChange(); - this.fire('selectionchange'); - } - while (changed.length) { - changed.shift().render(); - } - }, - getSelectedNodes: function() { - //不能克隆返回,会对当前选区操作,从而影响querycommand - return this._selectedNodes; - }, - getSelectedNode: function() { - return this.getSelectedNodes()[0] || null; - }, - removeAllSelectedNodes: function() { - var me = this; - var last = this._selectedNodes.splice(0); - this._selectedNodes = []; - this.renderChangedSelection(last); - return this.fire('selectionclear'); - }, - removeSelectedNodes: function(nodes) { - var me = this; - var last = this._selectedNodes.slice(0); - nodes = utils.isArray(nodes) ? nodes : [nodes]; - - nodes.forEach(function(node) { - var index; - if ((index = me._selectedNodes.indexOf(node)) === -1) return; - me._selectedNodes.splice(index, 1); - }); - - this.renderChangedSelection(last); - return this; - }, - select: function(nodes, isSingleSelect) { - var lastSelect = this.getSelectedNodes().slice(0); - if (isSingleSelect) { - this._selectedNodes = []; - } - var me = this; - nodes = utils.isArray(nodes) ? nodes : [nodes]; - nodes.forEach(function(node) { - if (me._selectedNodes.indexOf(node) !== -1) return; - me._selectedNodes.unshift(node); - }); - this.renderChangedSelection(lastSelect); - return this; - }, - selectById: function(ids, isSingleSelect) { - ids = utils.isArray(ids) ? ids : [ids]; - var nodes = this.getNodesById(ids); - return this.select(nodes, isSingleSelect); - }, - //当前选区中的节点在给定的节点范围内的保留选中状态, - //没在给定范围的取消选中,给定范围中的但没在当前选中范围的也做选中效果 - toggleSelect: function(node) { - if (utils.isArray(node)) { - node.forEach(this.toggleSelect.bind(this)); - } else { - if (node.isSelected()) this.removeSelectedNodes(node); - else this.select(node); - } - return this; - }, - - isSingleSelect: function() { - return this._selectedNodes.length == 1; - }, - - getSelectedAncestors: function(includeRoot) { - var nodes = this.getSelectedNodes().slice(0), - ancestors = [], - judge; - - // 根节点不参与计算 - var rootIndex = nodes.indexOf(this.getRoot()); - if (~rootIndex && !includeRoot) { - nodes.splice(rootIndex, 1); - } - - // 判断 nodes 列表中是否存在 judge 的祖先 - function hasAncestor(nodes, judge) { - for (var i = nodes.length - 1; i >= 0; --i) { - if (nodes[i].isAncestorOf(judge)) return true; - } - return false; - } - - // 按照拓扑排序 - nodes.sort(function(node1, node2) { - return node1.getLevel() - node2.getLevel(); - }); - - // 因为是拓扑有序的,所以只需往上查找 - while ((judge = nodes.pop())) { - if (!hasAncestor(nodes, judge)) { - ancestors.push(judge); - } - } - - return ancestors; - } - }); - - kity.extendClass(MinderNode, { - isSelected: function() { - var minder = this.getMinder(); - return minder && minder.getSelectedNodes().indexOf(this) != -1; - } - }); - -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/shortcut.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/shortcut.js deleted file mode 100644 index 57682e85..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/shortcut.js +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @fileOverview - * - * 添加快捷键支持 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function(require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var keymap = require('./keymap'); - var Minder = require('./minder'); - var MinderEvent = require('./event'); - - /** - * 计算包含 meta 键的 keycode - * - * @param {String|KeyEvent} unknown - */ - function getMetaKeyCode(unknown) { - var CTRL_MASK = 0x1000; - var ALT_MASK = 0x2000; - var SHIFT_MASK = 0x4000; - var metaKeyCode = 0; - - if (typeof(unknown) == 'string') { - // unknown as string - unknown.toLowerCase().split(/\+\s*/).forEach(function(name) { - switch(name) { - case 'ctrl': - case 'cmd': - metaKeyCode |= CTRL_MASK; - break; - case 'alt': - metaKeyCode |= ALT_MASK; - break; - case 'shift': - metaKeyCode |= SHIFT_MASK; - break; - default: - metaKeyCode |= keymap[name]; - } - }); - } else { - // unknown as key event - if (unknown.ctrlKey || unknown.metaKey) { - metaKeyCode |= CTRL_MASK; - } - if (unknown.altKey) { - metaKeyCode |= ALT_MASK; - } - if (unknown.shiftKey) { - metaKeyCode |= SHIFT_MASK; - } - metaKeyCode |= unknown.keyCode; - } - - return metaKeyCode; - } - kity.extendClass(MinderEvent, { - isShortcutKey: function(keyCombine) { - var keyEvent = this.originEvent; - if (!keyEvent) return false; - - return getMetaKeyCode(keyCombine) == getMetaKeyCode(keyEvent); - } - }); - - Minder.registerInitHook(function() { - this._initShortcutKey(); - }); - - kity.extendClass(Minder, { - - _initShortcutKey: function() { - this._bindShortcutKeys(); - }, - - _bindShortcutKeys: function() { - var map = this._shortcutKeys = {}; - var has = 'hasOwnProperty'; - this.on('keydown', function(e) { - for (var keys in map) { - if (!map[has](keys)) continue; - if (e.isShortcutKey(keys)) { - var fn = map[keys]; - if (fn.__statusCondition && fn.__statusCondition != this.getStatus()) return; - fn(); - e.preventDefault(); - } - } - }); - }, - - addShortcut: function(keys, fn) { - var binds = this._shortcutKeys; - keys.split(/\|\s*/).forEach(function(combine) { - var parts = combine.split('::'); - var status; - if (parts.length > 1) { - combine = parts[1]; - status = parts[0]; - fn.__statusCondition = status; - } - binds[combine] = fn; - }); - }, - - addCommandShortcutKeys: function(cmd, keys) { - var binds = this._commandShortcutKeys || (this._commandShortcutKeys = {}); - var obj = {}, - km = this; - if (keys) { - obj[cmd] = keys; - } else { - obj = cmd; - } - - var minder = this; - - utils.each(obj, function(keys, command) { - - binds[command] = keys; - - minder.addShortcut(keys, function execCommandByShortcut() { - /** - * 之前判断有问题,由 === 0 改为 !== -1 - * @editor Naixor - * @Date 2015-12-2 - */ - if (minder.queryCommandState(command) !== -1) { - minder.execCommand(command); - } - }); - }); - }, - - getCommandShortcutKey: function(cmd) { - var binds = this._commandShortcutKeys; - return binds && binds[cmd] || null; - }, - - /** - * @Desc: 添加一个判断是否支持原生Clipboard的变量,用于对ctrl + v和ctrl + c的处理 - * @Editor: Naixor - * @Date: 2015.9.20 - */ - supportClipboardEvent: (function(window) { - return !!window.ClipboardEvent; - })(window) - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/status.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/status.js deleted file mode 100644 index a3ae2e1d..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/status.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @fileOverview - * - * 状态切换控制 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function(require, exports, module) { - var kity = require('./kity'); - var Minder = require('./minder'); - - var sf = ~window.location.href.indexOf('status'); - var tf = ~window.location.href.indexOf('trace'); - - Minder.registerInitHook(function() { - this._initStatus(); - }); - - kity.extendClass(Minder, { - - _initStatus: function() { - this._status = 'normal'; - this._rollbackStatus = 'normal'; - }, - - setStatus: function(status, force) { - // 在 readonly 模式下,只有 force 为 true 才能切换回来 - if (this._status == 'readonly' && !force) return this; - if (status != this._status) { - this._rollbackStatus = this._status; - this._status = status; - this.fire('statuschange', { - lastStatus: this._rollbackStatus, - currentStatus: this._status - }); - if (sf) { - /* global console: true */ - console.log(window.event.type, this._rollbackStatus, '->', this._status); - if (tf) { - console.trace(); - } - } - } - return this; - }, - - rollbackStatus: function() { - this.setStatus(this._rollbackStatus); - }, - getRollbackStatus:function(){ - return this._rollbackStatus; - }, - getStatus: function() { - return this._status; - } - }); - -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/template.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/template.js deleted file mode 100644 index 1d56c270..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/template.js +++ /dev/null @@ -1,97 +0,0 @@ -define(function (require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Minder = require('./minder'); - var Command = require('./command'); - var MinderNode = require('./node'); - var Module = require('./module'); - - var _templates = {}; - - function register(name, supports) { - _templates[name] = supports; - } - exports.register = register; - - utils.extend(Minder, { - getTemplateList: function () { - return _templates; - }, - }); - - kity.extendClass( - Minder, - (function () { - var originGetTheme = Minder.prototype.getTheme; - return { - useTemplate: function (name, duration) { - this.setTemplate(name); - this.refresh(duration || 800); - }, - - getTemplate: function () { - return this._template || 'default'; - }, - - setTemplate: function (name) { - this._template = name || null; - }, - - getTemplateSupport: function (method) { - var supports = _templates[this.getTemplate()]; - return supports && supports[method]; - }, - - getTheme: function (node) { - var support = this.getTemplateSupport('getTheme') || originGetTheme; - return support.call(this, node); - }, - }; - })() - ); - - kity.extendClass( - MinderNode, - (function () { - var originGetLayout = MinderNode.prototype.getLayout; - var originGetConnect = MinderNode.prototype.getConnect; - return { - getLayout: function () { - var support = this.getMinder().getTemplateSupport('getLayout') || originGetLayout; - return support.call(this, this); - }, - - getConnect: function () { - var support = this.getMinder().getTemplateSupport('getConnect') || originGetConnect; - return support.call(this, this); - }, - }; - })() - ); - - Module.register('TemplateModule', { - /** - * @command Template - * @description 设置当前脑图的模板 - * @param {string} name 模板名称 - * 允许使用的模板可以使用 `kityminder.Minder.getTemplateList()` 查询 - * @state - * 0: 始终可用 - * @return 返回当前的模板名称 - */ - commands: { - template: kity.createClass('TemplateCommand', { - base: Command, - - execute: function (minder, name) { - minder.useTemplate(name); - minder.execCommand('camera'); - }, - - queryValue: function (minder) { - return minder.getTemplate() || 'default'; - }, - }), - }, - }); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/theme.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/theme.js deleted file mode 100644 index 20a11d4e..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/theme.js +++ /dev/null @@ -1,175 +0,0 @@ -define(function(require, exports, module) { - var kity = require('./kity'); - var utils = require('./utils'); - var Minder = require('./minder'); - var MinderNode = require('./node'); - var Module = require('./module'); - var Command = require('./command'); - - var cssLikeValueMatcher = { - left: function(value) { - return 3 in value && value[3] || - 1 in value && value[1] || - value[0]; - }, - right: function(value) { - return 1 in value && value[1] || value[0]; - }, - top: function(value) { - return value[0]; - }, - bottom: function(value) { - return 2 in value && value[2] || value[0]; - } - }; - - var _themes = {}; - - /** - * 注册一个主题 - * - * @param {String} name 主题的名称 - * @param {Plain} theme 主题的样式描述 - * - * @example - * Minder.registerTheme('default', { - * 'root-color': 'red', - * 'root-stroke': 'none', - * 'root-padding': [10, 20] - * }); - */ - function register(name, theme) { - _themes[name] = theme; - } - exports.register = register; - - utils.extend(Minder, { - getThemeList: function() { - return _themes; - } - }); - - kity.extendClass(Minder, { - - /** - * 切换脑图实例上的主题 - * @param {String} name 要使用的主题的名称 - */ - useTheme: function(name) { - - this.setTheme(name); - this.refresh(800); - - return true; - }, - - setTheme: function(name) { - if (name && !_themes[name]) throw new Error('Theme ' + name + ' not exists!'); - var lastTheme = this._theme; - this._theme = name || null; - var container = this.getRenderTarget(); - if (container) { - container.classList.remove('km-theme-' + lastTheme); - if (name) { - container.classList.add('km-theme-' + name); - } - container.style.background = this.getStyle('background'); - } - this.fire('themechange', { - theme: name - }); - return this; - }, - - /** - * 获取脑图实例上的当前主题 - * @return {[type]} [description] - */ - getTheme: function(node) { - return this._theme || this.getOption('defaultTheme') || 'fresh-blue'; - }, - - getThemeItems: function(node) { - var theme = this.getTheme(node); - return _themes[this.getTheme(node)]; - }, - - /** - * 获得脑图实例上的样式 - * @param {String} item 样式名称 - */ - getStyle: function(item, node) { - var items = this.getThemeItems(node); - var segment, dir, selector, value, matcher; - - if (item in items) return items[item]; - - // 尝试匹配 CSS 数组形式的值 - // 比如 item 为 'pading-left' - // theme 里有 {'padding': [10, 20]} 的定义,则可以返回 20 - segment = item.split('-'); - if (segment.length < 2) return null; - - dir = segment.pop(); - item = segment.join('-'); - - if (item in items) { - value = items[item]; - if (utils.isArray(value) && (matcher = cssLikeValueMatcher[dir])) { - return matcher(value); - } - if (!isNaN(value)) return value; - } - - return null; - }, - - /** - * 获取指定节点的样式 - * @param {String} name 样式名称,可以不加节点类型的前缀 - */ - getNodeStyle: function(node, name) { - var value = this.getStyle(node.getType() + '-' + name, node); - return value !== null ? value : this.getStyle(name, node); - } - }); - - kity.extendClass(MinderNode, { - getStyle: function(name) { - return this.getMinder().getNodeStyle(this, name); - } - }); - - Module.register('Theme', { - defaultOptions: { - defaultTheme: 'fresh-blue' - }, - commands: { - /** - * @command Theme - * @description 设置当前脑图的主题 - * @param {string} name 主题名称 - * 允许使用的主题可以使用 `kityminder.Minder.getThemeList()` 查询 - * @state - * 0: 始终可用 - * @return 返回当前的主题名称 - */ - 'theme': kity.createClass('ThemeCommand', { - base: Command, - - execute: function(km, name) { - return km.useTheme(name); - }, - - queryValue: function(km) { - return km.getTheme() || 'default'; - } - }) - } - }); - - Minder.registerInitHook(function() { - this.setTheme(); - }); - -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/utils.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/utils.js deleted file mode 100644 index 955b4e72..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/core/utils.js +++ /dev/null @@ -1,65 +0,0 @@ -define(function(require, exports) { - var kity = require('./kity'); - var uuidMap = {}; - - exports.extend = kity.Utils.extend.bind(kity.Utils); - exports.each = kity.Utils.each.bind(kity.Utils); - - exports.uuid = function(group) { - uuidMap[group] = uuidMap[group] ? uuidMap[group] + 1 : 1; - return group + uuidMap[group]; - }; - - exports.guid = function() { - return (+new Date() * 1e6 + Math.floor(Math.random() * 1e6)).toString(36); - }; - - exports.trim = function(str) { - return str.replace(/(^[ \t\n\r]+)|([ \t\n\r]+$)/g, ''); - }; - - exports.keys = function(plain) { - var keys = []; - for (var key in plain) { - if (plain.hasOwnProperty(key)) { - keys.push(key); - } - } - return keys; - }; - - exports.clone = function(source) { - return JSON.parse(JSON.stringify(source)); - }; - - exports.comparePlainObject = function(a, b) { - return JSON.stringify(a) == JSON.stringify(b); - }; - - exports.encodeHtml = function(str, reg) { - return str ? str.replace(reg || /[&<">'](?:(amp|lt|quot|gt|#39|nbsp);)?/g, function(a, b) { - if (b) { - return a; - } else { - return { - '<': '<', - '&': '&', - '"': '"', - '>': '>', - '\'': ''' - }[a]; - } - }) : ''; - }; - - exports.clearWhiteSpace = function(str) { - return str.replace(/[\u200b\t\r\n]/g, ''); - }; - - exports.each(['String', 'Function', 'Array', 'Number', 'RegExp', 'Object'], function(v) { - var toString = Object.prototype.toString; - exports['is' + v] = function(obj) { - return toString.apply(obj) == '[object ' + v + ']'; - }; - }); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/expose-kityminder.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/expose-kityminder.js deleted file mode 100644 index 32e5e870..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/expose-kityminder.js +++ /dev/null @@ -1,3 +0,0 @@ -define('expose-kityminder', function(require, exports, module) { - module.exports = window.kityminder = require('./kityminder'); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/kityminder.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/kityminder.js deleted file mode 100644 index cfcc2cdd..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/kityminder.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @fileOverview - * - * 默认导出(全部模块) - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function (require, exports, module) { - var kityminder = { - version: require('./core/minder').version, - }; - - // 核心导出,大写的部分导出类,小写的部分简单 require 一下 - // 这里顺序是有讲究的,调整前先弄清楚依赖关系。 - require('./core/utils'); - kityminder.Minder = require('./core/minder'); - kityminder.Command = require('./core/command'); - kityminder.Node = require('./core/node'); - require('./core/option'); - require('./core/animate'); - kityminder.Event = require('./core/event'); - kityminder.data = require('./core/data'); - require('./core/compatibility'); - kityminder.KeyMap = require('./core/keymap'); - require('./core/shortcut'); - require('./core/status'); - require('./core/paper'); - require('./core/select'); - require('./core/focus'); - require('./core/keyreceiver'); - kityminder.Module = require('./core/module'); - require('./core/readonly'); - kityminder.Render = require('./core/render'); - kityminder.Connect = require('./core/connect'); - kityminder.Layout = require('./core/layout'); - kityminder.Theme = require('./core/theme'); - kityminder.Template = require('./core/template'); - kityminder.Promise = require('./core/promise'); - require('./core/_boxv'); - require('./core/patch'); - - // 模块依赖 - require('./module/arrange'); - require('./module/basestyle'); - require('./module/clipboard'); - require('./module/dragtree'); - require('./module/expand'); - require('./module/font'); - require('./module/hyperlink'); - require('./module/image'); - require('./module/image-viewer'); - require('./module/keynav'); - require('./module/layout'); - require('./module/node'); - require('./module/note'); - require('./module/outline'); - require('./module/priority'); - require('./module/progress'); - require('./module/resource'); - require('./module/select'); - require('./module/style'); - require('./module/text'); - require('./module/view'); - require('./module/zoom'); - - require('./protocol/json'); - require('./protocol/text'); - require('./protocol/markdown'); - require('./protocol/svg'); - require('./protocol/png'); - - require('./layout/mind'); - require('./layout/btree'); - require('./layout/filetree'); - require('./layout/fish-bone-master'); - require('./layout/fish-bone-slave'); - require('./layout/tianpan'); - - require('./theme/default'); - require('./theme/snow'); - require('./theme/fresh'); - require('./theme/fish'); - require('./theme/snow'); - require('./theme/wire'); - require('./theme/tianpan'); - - require('./connect/arc'); - require('./connect/arc_tp'); - require('./connect/bezier'); - require('./connect/fish-bone-master'); - require('./connect/l'); - require('./connect/poly'); - require('./connect/under'); - - require('./template/default'); - require('./template/structure'); - require('./template/filetree'); - require('./template/right'); - require('./template/fish-bone'); - require('./template/tianpan'); - - window.kityminder = kityminder; - module.exports = kityminder; -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/btree.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/btree.js deleted file mode 100644 index 1f7f9c69..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/btree.js +++ /dev/null @@ -1,143 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var Layout = require('../core/layout'); - - ['left', 'right', 'top', 'bottom'].forEach(registerLayoutForDirection); - - function registerLayoutForDirection(name) { - - var axis = (name == 'left' || name == 'right') ? 'x' : 'y'; - var dir = (name == 'left' || name == 'top') ? -1 : 1; - - var oppsite = { - 'left': 'right', - 'right': 'left', - 'top': 'bottom', - 'bottom': 'top', - 'x': 'y', - 'y': 'x' - }; - - function getOrderHint(node) { - var hint = []; - var box = node.getLayoutBox(); - var offset = 5; - - if (axis == 'x') { - hint.push({ - type: 'up', - node: node, - area: new kity.Box({ - x: box.x, - y: box.top - node.getStyle('margin-top') - offset, - width: box.width, - height: node.getStyle('margin-top') - }), - path: ['M', box.x, box.top - offset, 'L', box.right, box.top - offset] - }); - - hint.push({ - type: 'down', - node: node, - area: new kity.Box({ - x: box.x, - y: box.bottom + offset, - width: box.width, - height: node.getStyle('margin-bottom') - }), - path: ['M', box.x, box.bottom + offset, 'L', box.right, box.bottom + offset] - }); - } else { - hint.push({ - type: 'up', - node: node, - area: new kity.Box({ - x: box.left - node.getStyle('margin-left') - offset, - y: box.top, - width: node.getStyle('margin-left'), - height: box.height - }), - path: ['M', box.left - offset, box.top, 'L', box.left - offset, box.bottom] - }); - - hint.push({ - type: 'down', - node: node, - area: new kity.Box({ - x: box.right + offset, - y: box.top, - width: node.getStyle('margin-right'), - height: box.height - }), - path: ['M', box.right + offset, box.top, 'L', box.right + offset, box.bottom] - }); - } - return hint; - } - - Layout.register(name, kity.createClass({ - - base: Layout, - - doLayout: function(parent, children) { - - var pbox = parent.getContentBox(); - - if (axis == 'x') { - parent.setVertexOut(new kity.Point(pbox[name], pbox.cy)); - parent.setLayoutVectorOut(new kity.Vector(dir, 0)); - } else { - parent.setVertexOut(new kity.Point(pbox.cx, pbox[name])); - parent.setLayoutVectorOut(new kity.Vector(0, dir)); - } - - if (!children.length) { - return false; - } - - children.forEach(function(child) { - var cbox = child.getContentBox(); - child.setLayoutTransform(new kity.Matrix()); - - if (axis == 'x') { - child.setVertexIn(new kity.Point(cbox[oppsite[name]], cbox.cy)); - child.setLayoutVectorIn(new kity.Vector(dir, 0)); - } else { - child.setVertexIn(new kity.Point(cbox.cx, cbox[oppsite[name]])); - child.setLayoutVectorIn(new kity.Vector(0, dir)); - } - }); - - this.align(children, oppsite[name]); - this.stack(children, oppsite[axis]); - - var bbox = this.getBranchBox(children); - var xAdjust = 0, yAdjust = 0; - - if (axis == 'x') { - xAdjust = pbox[name]; - xAdjust += dir * parent.getStyle('margin-' + name); - xAdjust += dir * children[0].getStyle('margin-' + oppsite[name]); - - yAdjust = pbox.bottom; - yAdjust -= pbox.height / 2; - yAdjust -= bbox.height / 2; - yAdjust -= bbox.y; - } else { - xAdjust = pbox.right; - xAdjust -= pbox.width / 2; - xAdjust -= bbox.width / 2; - xAdjust -= bbox.x; - - yAdjust = pbox[name]; - yAdjust += dir * parent.getStyle('margin-' + name); - yAdjust += dir * children[0].getStyle('margin-' + oppsite[name]); - } - - this.move(children, xAdjust, yAdjust); - }, - - getOrderHint: getOrderHint - })); - } -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/filetree.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/filetree.js deleted file mode 100644 index 4f1e715c..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/filetree.js +++ /dev/null @@ -1,89 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var Layout = require('../core/layout'); - - [-1, 1].forEach(registerLayoutForDir); - - function registerLayoutForDir(dir) { - var name = 'filetree-' + (dir > 0 ? 'down' : 'up'); - - Layout.register(name, kity.createClass({ - base: Layout, - - doLayout: function(parent, children, round) { - var pBox = parent.getContentBox(); - var indent = 20; - - parent.setVertexOut(new kity.Point(pBox.left + indent, dir > 0 ? pBox.bottom : pBox.top)); - parent.setLayoutVectorOut(new kity.Vector(0, dir)); - - if (!children.length) return; - - children.forEach(function(child) { - var cbox = child.getContentBox(); - child.setLayoutTransform(new kity.Matrix()); - - child.setVertexIn(new kity.Point(cbox.left, cbox.cy)); - child.setLayoutVectorIn(new kity.Vector(1, 0)); - }); - - this.align(children, 'left'); - this.stack(children, 'y'); - - var xAdjust = 0; - xAdjust += pBox.left; - xAdjust += indent; - xAdjust += children[0].getStyle('margin-left'); - - var yAdjust = 0; - - if (dir > 0) { - yAdjust += pBox.bottom; - yAdjust += parent.getStyle('margin-bottom'); - yAdjust += children[0].getStyle('margin-top'); - } else { - yAdjust -= this.getTreeBox(children).bottom; - yAdjust += pBox.top; - yAdjust -= parent.getStyle('margin-top'); - yAdjust -= children[0].getStyle('margin-bottom'); - } - - this.move(children, xAdjust, yAdjust); - - }, - - getOrderHint: function(node) { - var hint = []; - var box = node.getLayoutBox(); - var offset = node.getLevel() > 1 ? 3 : 5; - - hint.push({ - type: 'up', - node: node, - area: new kity.Box({ - x: box.x, - y: box.top - node.getStyle('margin-top') - offset, - width: box.width, - height: node.getStyle('margin-top') - }), - path: ['M', box.x, box.top - offset, 'L', box.right, box.top - offset] - }); - - hint.push({ - type: 'down', - node: node, - area: new kity.Box({ - x: box.x, - y: box.bottom + offset, - width: box.width, - height: node.getStyle('margin-bottom') - }), - path: ['M', box.x, box.bottom + offset, 'L', box.right, box.bottom + offset] - }); - return hint; - } - })); - - } - -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/fish-bone-master.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/fish-bone-master.js deleted file mode 100644 index 9948cd3c..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/fish-bone-master.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @fileOverview - * - * 鱼骨图主骨架布局 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function(require, exports, module) { - var kity = require('../core/kity'); - var Layout = require('../core/layout'); - - Layout.register('fish-bone-master', kity.createClass('FishBoneMasterLayout', { - base: Layout, - - doLayout: function(parent, children, round) { - - var upPart = [], - downPart = []; - - var child = children[0]; - var pBox = parent.getContentBox(); - - parent.setVertexOut(new kity.Point(pBox.right, pBox.cy)); - parent.setLayoutVectorOut(new kity.Vector(1, 0)); - - if (!child) return; - - var cBox = child.getContentBox(); - var pMarginRight = parent.getStyle('margin-right'); - var cMarginLeft = child.getStyle('margin-left'); - var cMarginTop = child.getStyle('margin-top'); - var cMarginBottom = child.getStyle('margin-bottom'); - - children.forEach(function(child, index) { - child.setLayoutTransform(new kity.Matrix()); - var cBox = child.getContentBox(); - - if (index % 2) { - downPart.push(child); - child.setVertexIn(new kity.Point(cBox.left, cBox.top)); - child.setLayoutVectorIn(new kity.Vector(1, 1)); - } - else { - upPart.push(child); - child.setVertexIn(new kity.Point(cBox.left, cBox.bottom)); - child.setLayoutVectorIn(new kity.Vector(1, -1)); - } - - }); - - this.stack(upPart, 'x'); - this.stack(downPart, 'x'); - - this.align(upPart, 'bottom'); - this.align(downPart, 'top'); - - var xAdjust = pBox.right + pMarginRight + cMarginLeft; - var yAdjustUp = pBox.cy - cMarginBottom - parent.getStyle('margin-top'); - var yAdjustDown = pBox.cy + cMarginTop + parent.getStyle('margin-bottom'); - - this.move(upPart, xAdjust, yAdjustUp); - this.move(downPart, xAdjust + cMarginLeft, yAdjustDown); - } - })); - -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/fish-bone-slave.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/fish-bone-slave.js deleted file mode 100644 index 4234be5f..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/fish-bone-slave.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * @fileOverview - * - * - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function(require, exports, module) { - var kity = require('../core/kity'); - var Layout = require('../core/layout'); - - Layout.register('fish-bone-slave', kity.createClass('FishBoneSlaveLayout', { - base: Layout, - - doLayout: function (parent, children, round) { - - var layout = this; - var abs = Math.abs; - var GOLD_CUT = 1 - 0.618; - - var pBox = parent.getContentBox(); - var vi = parent.getLayoutVectorIn(); - - parent.setLayoutVectorOut(vi); - - var goldX = pBox.left + pBox.width * GOLD_CUT; - var pout = new kity.Point(goldX, vi.y > 0 ? pBox.bottom : pBox.top); - parent.setVertexOut(pout); - - var child = children[0]; - if (!child) return; - - var cBox = child.getContentBox(); - - children.forEach(function(child, index) { - child.setLayoutTransform(new kity.Matrix()); - child.setLayoutVectorIn(new kity.Vector(1, 0)); - child.setVertexIn(new kity.Point(cBox.left, cBox.cy)); - }); - - this.stack(children, 'y'); - this.align(children, 'left'); - - var xAdjust = 0, yAdjust = 0; - xAdjust += pout.x; - - if (parent.getLayoutVectorOut().y < 0) { - yAdjust -= this.getTreeBox(children).bottom; - yAdjust += parent.getContentBox().top; - yAdjust -= parent.getStyle('margin-top'); - yAdjust -= child.getStyle('margin-bottom'); - } else { - yAdjust += parent.getContentBox().bottom; - yAdjust += parent.getStyle('margin-bottom'); - yAdjust += child.getStyle('margin-top'); - } - - this.move(children, xAdjust, yAdjust); - - if (round == 2) { - children.forEach(function(child) { - var m = child.getLayoutTransform(); - var cbox = child.getContentBox(); - var pin = m.transformPoint(new kity.Point(cbox.left, 0)); - layout.move([child], abs(pin.y - pout.y), 0); - }); - } - } - })); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/mind.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/mind.js deleted file mode 100644 index 86ba4772..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/mind.js +++ /dev/null @@ -1,62 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var Layout = require('../core/layout'); - var Minder = require('../core/minder'); - - Layout.register('mind', kity.createClass({ - base: Layout, - - doLayout: function(node, children) { - var layout = this; - var half = Math.ceil(node.children.length / 2); - var right = []; - var left = []; - - children.forEach(function(child) { - if (child.getIndex() < half) right.push(child); - else left.push(child); - }); - - var leftLayout = Minder.getLayoutInstance('left'); - var rightLayout = Minder.getLayoutInstance('right'); - - leftLayout.doLayout(node, left); - rightLayout.doLayout(node, right); - - var box = node.getContentBox(); - node.setVertexOut(new kity.Point(box.cx, box.cy)); - node.setLayoutVectorOut(new kity.Vector(0, 0)); - }, - - getOrderHint: function(node) { - var hint = []; - var box = node.getLayoutBox(); - var offset = 5; - - hint.push({ - type: 'up', - node: node, - area: new kity.Box({ - x: box.x, - y: box.top - node.getStyle('margin-top') - offset, - width: box.width, - height: node.getStyle('margin-top') - }), - path: ['M', box.x, box.top - offset, 'L', box.right, box.top - offset] - }); - - hint.push({ - type: 'down', - node: node, - area: new kity.Box({ - x: box.x, - y: box.bottom + offset, - width: box.width, - height: node.getStyle('margin-bottom') - }), - path: ['M', box.x, box.bottom + offset, 'L', box.right, box.bottom + offset] - }); - return hint; - } - })); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/tianpan.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/tianpan.js deleted file mode 100644 index 9ce27acf..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/layout/tianpan.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @fileOverview - * - * 天盘模板 - * - * @author: along - * @copyright: bpd729@163.com, 2015 - */ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var Layout = require('../core/layout'); - var Minder = require('../core/minder'); - - Layout.register('tianpan', kity.createClass({ - base: Layout, - - doLayout: function (parent, children) { - if (children.length == 0) return; - - var layout = this; - var pbox = parent.getContentBox(); - - var x, y,box; - var _theta = 5; - var _r = Math.max(pbox.width, 50); - children.forEach(function (child, index) { - child.setLayoutTransform(new kity.Matrix()); - box = layout.getTreeBox(child); - _r = Math.max(Math.max(box.width, box.height), _r); - }) - _r = _r / 1.5 / Math.PI; - - children.forEach(function (child, index) { - x = _r * (Math.cos(_theta) + Math.sin(_theta) * _theta); - y = _r * (Math.sin(_theta) - Math.cos(_theta) * _theta); - - _theta += (0.9 - index * 0.02); - child.setLayoutVectorIn(new kity.Vector(1, 0)); - child.setVertexIn(new kity.Point(pbox.cx, pbox.cy)); - child.setLayoutTransform(new kity.Matrix()); - layout.move([child], x, y); - }); - }, - - getOrderHint: function (node) { - var hint = []; - var box = node.getLayoutBox(); - var offset = 5; - - hint.push({ - type: 'up', - node: node, - area: { - x: box.x, - y: box.top - node.getStyle('margin-top') - offset, - width: box.width, - height: node.getStyle('margin-top') - }, - path: ['M', box.x, box.top - offset, 'L', box.right, box.top - offset] - }); - - hint.push({ - type: 'down', - node: node, - area: { - x: box.x, - y: box.bottom + offset, - width: box.width, - height: node.getStyle('margin-bottom') - }, - path: ['M', box.x, box.bottom + offset, 'L', box.right, box.bottom + offset] - }); - return hint; - } - })); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/arrange.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/arrange.js deleted file mode 100644 index 5365e6c3..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/arrange.js +++ /dev/null @@ -1,156 +0,0 @@ - -define(function(require, exports, module) { - var kity = require('../core/kity'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - - kity.extendClass(MinderNode, { - arrange: function(index) { - var parent = this.parent; - if (!parent) return; - var sibling = parent.children; - - if (index < 0 || index >= sibling.length) return; - sibling.splice(this.getIndex(), 1); - sibling.splice(index, 0, this); - return this; - } - }); - - function asc(nodeA, nodeB) { - return nodeA.getIndex() - nodeB.getIndex(); - } - function desc(nodeA, nodeB) { - return -asc(nodeA, nodeB); - } - - function canArrange(km) { - var selected = km.getSelectedNode(); - return selected && selected.parent && selected.parent.children.length > 1; - } - - - /** - * @command ArrangeUp - * @description 向上调整选中节点的位置 - * @shortcut Alt + Up - * @state - * 0: 当前选中了具有相同父亲的节点 - * -1: 其它情况 - */ - var ArrangeUpCommand = kity.createClass('ArrangeUpCommand', { - base: Command, - - execute: function(km) { - var nodes = km.getSelectedNodes(); - nodes.sort(asc); - var lastIndexes = nodes.map(function(node) { - return node.getIndex(); - }); - nodes.forEach(function(node, index) { - node.arrange(lastIndexes[index] - 1); - }); - km.layout(300); - }, - - queryState: function(km) { - var selected = km.getSelectedNode(); - return selected ? 0 : -1; - } - }); - - /** - * @command ArrangeDown - * @description 向下调整选中节点的位置 - * @shortcut Alt + Down - * @state - * 0: 当前选中了具有相同父亲的节点 - * -1: 其它情况 - */ - var ArrangeDownCommand = kity.createClass('ArrangeUpCommand', { - base: Command, - - execute: function(km) { - var nodes = km.getSelectedNodes(); - nodes.sort(desc); - var lastIndexes = nodes.map(function(node) { - return node.getIndex(); - }); - nodes.forEach(function(node, index) { - node.arrange(lastIndexes[index] + 1); - }); - km.layout(300); - }, - - queryState: function(km) { - var selected = km.getSelectedNode(); - return selected ? 0 : -1; - } - }); - - /** - * @command Arrange - * @description 调整选中节点的位置 - * @param {number} index 调整后节点的新位置 - * @state - * 0: 当前选中了具有相同父亲的节点 - * -1: 其它情况 - */ - var ArrangeCommand = kity.createClass('ArrangeCommand', { - base: Command, - - execute: function(km, index) { - var nodes = km.getSelectedNodes().slice(); - - if (!nodes.length) return; - - var ancestor = MinderNode.getCommonAncestor(nodes); - - if (ancestor != nodes[0].parent) return; - - var indexed = nodes.map(function(node) { - return { - index: node.getIndex(), - node: node - }; - }); - - var asc = Math.min.apply(Math, indexed.map(function(one) { return one.index; })) >= index; - - indexed.sort(function(a, b) { - return asc ? (b.index - a.index) : (a.index - b.index); - }); - - indexed.forEach(function(one) { - one.node.arrange(index); - }); - - km.layout(300); - }, - - queryState: function(km) { - var selected = km.getSelectedNode(); - return selected ? 0 : -1; - } - }); - - Module.register('ArrangeModule', { - commands: { - 'arrangeup': ArrangeUpCommand, - 'arrangedown': ArrangeDownCommand, - 'arrange': ArrangeCommand - }, - contextmenu: [{ - command: 'arrangeup' - }, { - command: 'arrangedown' - }, { - divider: true - }], - commandShortcutKeys: { - 'arrangeup': 'normal::alt+Up', - 'arrangedown': 'normal::alt+Down' - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/basestyle.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/basestyle.js deleted file mode 100644 index e607ebef..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/basestyle.js +++ /dev/null @@ -1,126 +0,0 @@ - -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - - var TextRenderer = require('./text'); - - Module.register('basestylemodule', function() { - var km = this; - - function getNodeDataOrStyle(node, name) { - return node.getData(name) || node.getStyle(name); - } - - TextRenderer.registerStyleHook(function(node, textGroup) { - - var fontWeight = getNodeDataOrStyle(node,'font-weight'); - var fontStyle = getNodeDataOrStyle(node, 'font-style'); - var styleHash = [fontWeight, fontStyle].join('/'); - - textGroup.eachItem(function(index,item) { - item.setFont({ - 'weight': fontWeight, - 'style': fontStyle - }); - }); - - }); - return { - 'commands': { - /** - * @command Bold - * @description 加粗选中的节点 - * @shortcut Ctrl + B - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - * 1: 当前已选中的节点已加粗 - */ - 'bold': kity.createClass('boldCommand', { - base: Command, - - execute: function(km) { - - var nodes = km.getSelectedNodes(); - if (this.queryState('bold') == 1) { - nodes.forEach(function(n) { - n.setData('font-weight').render(); - }); - } else { - nodes.forEach(function(n) { - n.setData('font-weight', 'bold').render(); - }); - } - km.layout(); - }, - queryState: function() { - var nodes = km.getSelectedNodes(), - result = 0; - if (nodes.length === 0) { - return -1; - } - nodes.forEach(function(n) { - if (n && n.getData('font-weight')) { - result = 1; - return false; - } - }); - return result; - } - }), - /** - * @command Italic - * @description 加斜选中的节点 - * @shortcut Ctrl + I - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - * 1: 当前已选中的节点已加斜 - */ - 'italic': kity.createClass('italicCommand', { - base: Command, - - execute: function(km) { - - var nodes = km.getSelectedNodes(); - if (this.queryState('italic') == 1) { - nodes.forEach(function(n) { - n.setData('font-style').render(); - }); - } else { - nodes.forEach(function(n) { - n.setData('font-style', 'italic').render(); - }); - } - - km.layout(); - }, - queryState: function() { - var nodes = km.getSelectedNodes(), - result = 0; - if (nodes.length === 0) { - return -1; - } - nodes.forEach(function(n) { - if (n && n.getData('font-style')) { - result = 1; - return false; - } - }); - return result; - } - }) - }, - commandShortcutKeys: { - 'bold': 'ctrl+b', //bold - 'italic': 'ctrl+i' //italic - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/clipboard.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/clipboard.js deleted file mode 100644 index a7026213..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/clipboard.js +++ /dev/null @@ -1,172 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - - Module.register('ClipboardModule', function() { - var km = this, - _clipboardNodes = [], - _selectedNodes = []; - - function appendChildNode(parent, child) { - _selectedNodes.push(child); - km.appendNode(child, parent); - child.render(); - child.setLayoutOffset(null); - var children = child.children.map(function(node) { - return node.clone(); - }); - - /* - * fixed bug: Modified on 2015.08.05 - * 原因:粘贴递归 append 时没有清空原来父节点的子节点,而父节点被复制的时候,是连同子节点一起复制过来的 - * 解决办法:增加了下面这一行代码 - * by: @zhangbobell zhangbobell@163.com - */ - child.clearChildren(); - - for (var i = 0, ci; - (ci = children[i]); i++) { - appendChildNode(child, ci); - } - } - - function sendToClipboard(nodes) { - if (!nodes.length) return; - nodes.sort(function(a, b) { - return a.getIndex() - b.getIndex(); - }); - _clipboardNodes = nodes.map(function(node) { - return node.clone(); - }); - } - - /** - * @command Copy - * @description 复制当前选中的节点 - * @shortcut Ctrl + C - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - */ - var CopyCommand = kity.createClass('CopyCommand', { - base: Command, - - execute: function(km) { - sendToClipboard(km.getSelectedAncestors(true)); - this.setContentChanged(false); - } - }); - - /** - * @command Cut - * @description 剪切当前选中的节点 - * @shortcut Ctrl + X - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - */ - var CutCommand = kity.createClass('CutCommand', { - base: Command, - - execute: function(km) { - var ancestors = km.getSelectedAncestors(); - - if (ancestors.length === 0) return; - - sendToClipboard(ancestors); - - km.select(MinderNode.getCommonAncestor(ancestors), true); - - ancestors.slice().forEach(function(node) { - km.removeNode(node); - }); - - km.layout(300); - } - }); - - /** - * @command Paste - * @description 粘贴已复制的节点到每一个当前选中的节点上 - * @shortcut Ctrl + V - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - */ - var PasteCommand = kity.createClass('PasteCommand', { - base: Command, - - execute: function(km) { - if (_clipboardNodes.length) { - var nodes = km.getSelectedNodes(); - if (!nodes.length) return; - - for (var i = 0, ni; ni = _clipboardNodes[i]; i++) { - for (var j = 0, node; node = nodes[j]; j++) { - appendChildNode(node, ni.clone()); - } - } - - km.select(_selectedNodes, true); - _selectedNodes = []; - - km.layout(300); - } - }, - - queryState: function(km) { - return km.getSelectedNode() ? 0 : -1; - } - }); - - /** - * @Desc: 若支持原生clipboadr事件则基于原生扩展,否则使用km的基础事件只处理节点的粘贴复制 - * @Editor: Naixor - * @Date: 2015.9.20 - */ - if (km.supportClipboardEvent && !kity.Browser.gecko) { - var Copy = function (e) { - this.fire('beforeCopy', e); - } - - var Cut = function (e) { - this.fire('beforeCut', e); - } - - var Paste = function (e) { - this.fire('beforePaste', e); - } - - return { - 'commands': { - 'copy': CopyCommand, - 'cut': CutCommand, - 'paste': PasteCommand - }, - 'clipBoardEvents': { - 'copy': Copy.bind(km), - 'cut': Cut.bind(km), - 'paste': Paste.bind(km) - }, - sendToClipboard: sendToClipboard - }; - } else { - return { - 'commands': { - 'copy': CopyCommand, - 'cut': CutCommand, - 'paste': PasteCommand - }, - 'commandShortcutKeys': { - 'copy': 'normal::ctrl+c|', - 'cut': 'normal::ctrl+x', - 'paste': 'normal::ctrl+v' - }, - sendToClipboard: sendToClipboard - }; - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/dragtree.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/dragtree.js deleted file mode 100644 index dba04be8..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/dragtree.js +++ /dev/null @@ -1,405 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - - // 矩形的变形动画定义 - var MoveToParentCommand = kity.createClass('MoveToParentCommand', { - base: Command, - execute: function(minder, nodes, parent) { - var node; - for (var i = 0; i < nodes.length; i++) { - node = nodes[i]; - if (node.parent) { - node.parent.removeChild(node); - parent.appendChild(node); - node.render(); - } - } - parent.expand(); - minder.select(nodes, true); - } - }); - - var DropHinter = kity.createClass('DropHinter', { - base: kity.Group, - - constructor: function() { - this.callBase(); - this.rect = new kity.Rect(); - this.addShape(this.rect); - }, - - render: function(target) { - this.setVisible(!!target); - if (target) { - this.rect - .setBox(target.getLayoutBox()) - .setRadius(target.getStyle('radius') || 0) - .stroke( - target.getStyle('drop-hint-color') || 'yellow', - target.getStyle('drop-hint-width') || 2 - ); - this.bringTop(); - } - } - }); - - var OrderHinter = kity.createClass('OrderHinter', { - base: kity.Group, - - constructor: function() { - this.callBase(); - this.area = new kity.Rect(); - this.path = new kity.Path(); - this.addShapes([this.area, this.path]); - }, - - render: function(hint) { - this.setVisible(!!hint); - if (hint) { - this.area.setBox(hint.area); - this.area.fill(hint.node.getStyle('order-hint-area-color') || 'rgba(0, 255, 0, .5)'); - this.path.setPathData(hint.path); - this.path.stroke( - hint.node.getStyle('order-hint-path-color') || '#0f0', - hint.node.getStyle('order-hint-path-width') || 1); - } - } - }); - - // 对拖动对象的一个替代盒子,控制整个拖放的逻辑,包括: - // 1. 从节点列表计算出拖动部分 - // 2. 计算可以 drop 的节点,产生 drop 交互提示 - var TreeDragger = kity.createClass('TreeDragger', { - - constructor: function(minder) { - this._minder = minder; - this._dropHinter = new DropHinter(); - this._orderHinter = new OrderHinter(); - minder.getRenderContainer().addShapes([this._dropHinter, this._orderHinter]); - }, - - dragStart: function(position) { - // 只记录开始位置,不马上开启拖放模式 - // 这个位置同时是拖放范围收缩时的焦点位置(中心) - this._startPosition = position; - }, - - dragMove: function(position) { - // 启动拖放模式需要最小的移动距离 - var DRAG_MOVE_THRESHOLD = 10; - - if (!this._startPosition) return; - - var movement = kity.Vector.fromPoints(this._dragPosition || this._startPosition, position); - var minder = this._minder; - - this._dragPosition = position; - - if (!this._dragMode) { - // 判断拖放模式是否该启动 - if (kity.Vector.fromPoints(this._dragPosition, this._startPosition).length() < DRAG_MOVE_THRESHOLD) { - return; - } - if (!this._enterDragMode()) { - return; - } - } - - for (var i = 0; i < this._dragSources.length; i++) { - this._dragSources[i].setLayoutOffset(this._dragSources[i].getLayoutOffset().offset(movement)); - minder.applyLayoutResult(this._dragSources[i]); - } - - if (!this._dropTest()) { - this._orderTest(); - } else { - this._renderOrderHint(this._orderSucceedHint = null); - } - }, - - dragEnd: function() { - this._startPosition = null; - this._dragPosition = null; - - if (!this._dragMode) { - return; - } - - this._fadeDragSources(1); - - if (this._dropSucceedTarget) { - - this._dragSources.forEach(function(source) { - source.setLayoutOffset(null); - }); - - this._minder.layout(-1); - - this._minder.execCommand('movetoparent', this._dragSources, this._dropSucceedTarget); - - } else if (this._orderSucceedHint) { - - var hint = this._orderSucceedHint; - var index = hint.node.getIndex(); - - var sourceIndexes = this._dragSources.map(function(source) { - // 顺便干掉布局偏移 - source.setLayoutOffset(null); - return source.getIndex(); - }); - - var maxIndex = Math.max.apply(Math, sourceIndexes); - var minIndex = Math.min.apply(Math, sourceIndexes); - - if (index < minIndex && hint.type == 'down') index++; - if (index > maxIndex && hint.type == 'up') index--; - - hint.node.setLayoutOffset(null); - - this._minder.execCommand('arrange', index); - this._renderOrderHint(null); - } else { - this._minder.fire('savescene'); - } - this._minder.layout(300); - this._leaveDragMode(); - this._minder.fire('contentchange'); - }, - - // 进入拖放模式: - // 1. 计算拖放源和允许的拖放目标 - // 2. 标记已启动 - _enterDragMode: function() { - this._calcDragSources(); - if (!this._dragSources.length) { - this._startPosition = null; - return false; - } - this._fadeDragSources(0.5); - this._calcDropTargets(); - this._calcOrderHints(); - this._dragMode = true; - this._minder.setStatus('dragtree'); - return true; - }, - - // 从选中的节点计算拖放源 - // 并不是所有选中的节点都作为拖放源,如果选中节点中存在 A 和 B, - // 并且 A 是 B 的祖先,则 B 不作为拖放源 - // - // 计算过程: - // 1. 将节点按照树高排序,排序后只可能是前面节点是后面节点的祖先 - // 2. 从后往前枚举排序的结果,如果发现枚举目标之前存在其祖先, - // 则排除枚举目标作为拖放源,否则加入拖放源 - _calcDragSources: function() { - this._dragSources = this._minder.getSelectedAncestors(); - }, - - _fadeDragSources: function(opacity) { - var minder = this._minder; - this._dragSources.forEach(function(source) { - source.getRenderContainer().setOpacity(opacity, 200); - source.traverse(function(node) { - if (opacity < 1) { - minder.detachNode(node); - } else { - minder.attachNode(node); - } - }, true); - }); - }, - - - // 计算拖放目标可以释放的节点列表(释放意味着成为其子树),存在这条限制规则: - // - 不能拖放到拖放目标的子树上(允许拖放到自身,因为多选的情况下可以把其它节点加入) - // - // 1. 加入当前节点(初始为根节点)到允许列表 - // 2. 对于当前节点的每一个子节点: - // (1) 如果是拖放目标的其中一个节点,忽略(整棵子树被剪枝) - // (2) 如果不是拖放目标之一,以当前子节点为当前节点,回到 1 计算 - // 3. 返回允许列表 - // - _calcDropTargets: function() { - - function findAvailableParents(nodes, root) { - var availables = [], - i; - availables.push(root); - root.getChildren().forEach(function(test) { - for (i = 0; i < nodes.length; i++) { - if (nodes[i] == test) return; - } - availables = availables.concat(findAvailableParents(nodes, test)); - }); - return availables; - } - - this._dropTargets = findAvailableParents(this._dragSources, this._minder.getRoot()); - this._dropTargetBoxes = this._dropTargets.map(function(source) { - return source.getLayoutBox(); - }); - }, - - _calcOrderHints: function() { - var sources = this._dragSources; - var ancestor = MinderNode.getCommonAncestor(sources); - - // 只有一个元素选中,公共祖先是其父 - if (ancestor == sources[0]) ancestor = sources[0].parent; - - if (sources.length === 0 || ancestor != sources[0].parent) { - this._orderHints = []; - return; - } - - var siblings = ancestor.children; - - this._orderHints = siblings.reduce(function(hint, sibling) { - if (sources.indexOf(sibling) == -1) { - hint = hint.concat(sibling.getOrderHint()); - } - return hint; - }, []); - }, - - _leaveDragMode: function() { - this._dragMode = false; - this._dropSucceedTarget = null; - this._orderSucceedHint = null; - this._renderDropHint(null); - this._renderOrderHint(null); - this._minder.rollbackStatus(); - }, - - _drawForDragMode: function() { - this._text.setContent(this._dragSources.length + ' items'); - this._text.setPosition(this._startPosition.x, this._startPosition.y + 5); - this._minder.getRenderContainer().addShape(this); - }, - - /** - * 通过 judge 函数判断 targetBox 和 sourceBox 的位置交叉关系 - * @param targets -- 目标节点 - * @param targetBoxMapper -- 目标节点与对应 Box 的映射关系 - * @param judge -- 判断函数 - * @returns {*} - * @private - */ - _boxTest: function(targets, targetBoxMapper, judge) { - var sourceBoxes = this._dragSources.map(function(source) { - return source.getLayoutBox(); - }); - - var i, j, target, sourceBox, targetBox; - - judge = judge || function(intersectBox, sourceBox, targetBox) { - return intersectBox && !intersectBox.isEmpty(); - }; - - for (i = 0; i < targets.length; i++) { - - target = targets[i]; - targetBox = targetBoxMapper.call(this, target, i); - - for (j = 0; j < sourceBoxes.length; j++) { - sourceBox = sourceBoxes[j]; - - var intersectBox = sourceBox.intersect(targetBox); - if (judge(intersectBox, sourceBox, targetBox)) { - return target; - } - } - } - - return null; - }, - - _dropTest: function() { - this._dropSucceedTarget = this._boxTest(this._dropTargets, function(target, i) { - return this._dropTargetBoxes[i]; - }, function(intersectBox, sourceBox, targetBox) { - function area(box) { - return box.width * box.height; - } - if (!intersectBox) return false; - /* - * Added by zhangbobell, 2015.9.8 - * - * 增加了下面一行判断,修复了循环比较中 targetBox 为折叠节点时,intersetBox 面积为 0, - * 而 targetBox 的 width 和 height 均为 0 - * 此时造成了满足以下的第二个条件而返回 true - * */ - if (!area(intersectBox)) return false; - // 面积判断,交叉面积大于其中的一半 - if (area(intersectBox) > 0.5 * Math.min(area(sourceBox), area(targetBox))) return true; - // 有一个边完全重合的情况,也认为两个是交叉的 - if (intersectBox.width + 1 >= Math.min(sourceBox.width, targetBox.width)) return true; - if (intersectBox.height + 1 >= Math.min(sourceBox.height, targetBox.height)) return true; - return false; - }); - this._renderDropHint(this._dropSucceedTarget); - return !!this._dropSucceedTarget; - }, - - _orderTest: function() { - this._orderSucceedHint = this._boxTest(this._orderHints, function(hint) { - return hint.area; - }); - this._renderOrderHint(this._orderSucceedHint); - return !!this._orderSucceedHint; - }, - - _renderDropHint: function(target) { - this._dropHinter.render(target); - }, - - _renderOrderHint: function(hint) { - this._orderHinter.render(hint); - }, - preventDragMove: function() { - this._startPosition = null; - } - }); - - Module.register('DragTree', function() { - var dragger; - - return { - init: function() { - dragger = new TreeDragger(this); - window.addEventListener('mouseup', function() { - dragger.dragEnd(); - }); - }, - events: { - 'normal.mousedown inputready.mousedown': function(e) { - // 单选中根节点也不触发拖拽 - if (e.originEvent.button) return; - if (e.getTargetNode() && e.getTargetNode() != this.getRoot()) { - dragger.dragStart(e.getPosition()); - } - }, - 'normal.mousemove dragtree.mousemove': function(e) { - dragger.dragMove(e.getPosition()); - }, - 'normal.mouseup dragtree.beforemouseup': function(e) { - dragger.dragEnd(); - //e.stopPropagation(); - e.preventDefault(); - }, - 'statuschange': function(e) { - if (e.lastStatus == 'textedit' && e.currentStatus == 'normal') { - dragger.preventDragMove(); - } - } - }, - commands: { - 'movetoparent': MoveToParentCommand - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/expand.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/expand.js deleted file mode 100644 index 9b2f8389..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/expand.js +++ /dev/null @@ -1,293 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - var keymap = require('../core/keymap'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - Module.register('Expand', function() { - var minder = this; - var EXPAND_STATE_DATA = 'expandState', - STATE_EXPAND = 'expand', - STATE_COLLAPSE = 'collapse'; - - // 将展开的操作和状态读取接口拓展到 MinderNode 上 - kity.extendClass(MinderNode, { - - /** - * 展开节点 - * @param {Policy} policy 展开的策略,默认为 KEEP_STATE - */ - expand: function() { - this.setData(EXPAND_STATE_DATA, STATE_EXPAND); - return this; - }, - - /** - * 收起节点 - */ - collapse: function() { - this.setData(EXPAND_STATE_DATA, STATE_COLLAPSE); - return this; - }, - - /** - * 判断节点当前的状态是否为展开 - */ - isExpanded: function() { - var expanded = this.getData(EXPAND_STATE_DATA) !== STATE_COLLAPSE; - return expanded && (this.isRoot() || this.parent.isExpanded()); - }, - - /** - * 判断节点当前的状态是否为收起 - */ - isCollapsed: function() { - return !this.isExpanded(); - } - }); - - /** - * @command Expand - * @description 展开当前选中的节点,保证其可见 - * @param {bool} justParents 是否只展开到父亲 - * * `false` - (默认)保证选中的节点以及其子树可见 - * * `true` - 只保证选中的节点可见,不展开其子树 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - */ - var ExpandCommand = kity.createClass('ExpandCommand', { - base: Command, - - execute: function(km, justParents) { - var node = km.getSelectedNode(); - if (!node) return; - if (justParents) { - node = node.parent; - } - while (node.parent) { - node.expand(); - node = node.parent; - } - node.renderTree(); - km.layout(100); - }, - - queryState: function(km) { - var node = km.getSelectedNode(); - return node && !node.isRoot() && !node.isExpanded() ? 0 : -1; - } - }); - - /** - * @command ExpandToLevel - * @description 展开脑图到指定的层级 - * @param {number} level 指定展开到的层级,最少值为 1。 - * @state - * 0: 一直可用 - */ - var ExpandToLevelCommand = kity.createClass('ExpandToLevelCommand', { - base: Command, - execute: function(km, level) { - km.getRoot().traverse(function(node) { - if (node.getLevel() < level) node.expand(); - if (node.getLevel() == level && !node.isLeaf()) node.collapse(); - }); - km.refresh(100); - }, - enableReadOnly: true - }); - - /** - * @command Collapse - * @description 收起当前节点的子树 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - */ - var CollapseCommand = kity.createClass('CollapseCommand', { - base: Command, - - execute: function(km) { - var node = km.getSelectedNode(); - if (!node) return; - - node.collapse(); - node.renderTree(); - km.layout(); - }, - - queryState: function(km) { - var node = km.getSelectedNode(); - return node && !node.isRoot() && node.isExpanded() ? 0 : -1; - } - }); - - var Expander = kity.createClass('Expander', { - base: kity.Group, - - constructor: function(node) { - this.callBase(); - this.radius = 6; - this.outline = new kity.Circle(this.radius).stroke('gray').fill('white'); - this.sign = new kity.Path().stroke('gray'); - this.addShapes([this.outline, this.sign]); - this.initEvent(node); - this.setId(utils.uuid('node_expander')); - this.setStyle('cursor', 'pointer'); - }, - - initEvent: function(node) { - this.on('mousedown', function(e) { - minder.select([node], true); - if (node.isExpanded()) { - node.collapse(); - } else { - node.expand(); - } - node.renderTree().getMinder().layout(100); - node.getMinder().fire('contentchange'); - e.stopPropagation(); - e.preventDefault(); - }); - this.on('dblclick click mouseup', function(e) { - e.stopPropagation(); - e.preventDefault(); - }); - }, - - setState: function(state) { - if (state == 'hide') { - this.setVisible(false); - return; - } - this.setVisible(true); - var pathData = ['M', 1.5 - this.radius, 0, 'L', this.radius - 1.5, 0]; - if (state == STATE_COLLAPSE) { - pathData.push(['M', 0, 1.5 - this.radius, 'L', 0, this.radius - 1.5]); - } - this.sign.setPathData(pathData); - } - }); - - var ExpanderRenderer = kity.createClass('ExpanderRenderer', { - base: Renderer, - - create: function(node) { - if (node.isRoot()) return; - this.expander = new Expander(node); - node.getRenderContainer().prependShape(this.expander); - node.expanderRenderer = this; - this.node = node; - return this.expander; - }, - - shouldRender: function(node) { - return !node.isRoot(); - }, - - update: function(expander, node, box) { - if (!node.parent) return; - - var visible = node.parent.isExpanded(); - - expander.setState(visible && node.children.length ? node.getData(EXPAND_STATE_DATA) : 'hide'); - - var vector = node.getLayoutVectorIn().normalize(expander.radius + node.getStyle('stroke-width')); - var position = node.getVertexIn().offset(vector.reverse()); - - this.expander.setTranslate(position); - } - }); - - return { - commands: { - 'expand': ExpandCommand, - 'expandtolevel': ExpandToLevelCommand, - 'collapse': CollapseCommand - }, - events: { - 'layoutapply': function(e) { - var r = e.node.getRenderer('ExpanderRenderer'); - if (r.getRenderShape()) { - r.update(r.getRenderShape(), e.node); - } - }, - 'beforerender': function(e) { - var node = e.node; - var visible = !node.parent || node.parent.isExpanded(); - var minder = this; - - node.getRenderContainer().setVisible(visible); - if (!visible) e.stopPropagation(); - }, - 'normal.keydown': function(e) { - if (this.getStatus() == 'textedit') return; - if (e.originEvent.keyCode == keymap['/']) { - var node = this.getSelectedNode(); - if (!node || node == this.getRoot()) return; - var expanded = node.isExpanded(); - this.getSelectedNodes().forEach(function(node) { - if (expanded) node.collapse(); - else node.expand(); - node.renderTree(); - }); - this.layout(100); - this.fire('contentchange'); - e.preventDefault(); - e.stopPropagationImmediately(); - } - if (e.isShortcutKey('Alt+`')) { - this.execCommand('expandtolevel', 9999); - } - for (var i = 1; i < 6; i++) { - if (e.isShortcutKey('Alt+' + i)) { - this.execCommand('expandtolevel', i); - } - } - } - }, - renderers: { - outside: ExpanderRenderer - }, - contextmenu: [{ - command: 'expandtoleaf', - query: function() { - return !minder.getSelectedNode(); - }, - fn: function(minder) { - minder.execCommand('expandtolevel', 9999); - } - }, { - command: 'expandtolevel1', - query: function() { - return !minder.getSelectedNode(); - }, - fn: function(minder) { - minder.execCommand('expandtolevel', 1); - } - }, { - command: 'expandtolevel2', - query: function() { - return !minder.getSelectedNode(); - }, - fn: function(minder) { - minder.execCommand('expandtolevel', 2); - } - },{ - command: 'expandtolevel3', - query: function() { - return !minder.getSelectedNode(); - }, - fn: function(minder) { - minder.execCommand('expandtolevel', 3); - } - }, { - divider: true - }] - }; - }); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/font.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/font.js deleted file mode 100644 index 11ffd7b2..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/font.js +++ /dev/null @@ -1,159 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - - var TextRenderer = require('./text'); - - function getNodeDataOrStyle(node, name) { - return node.getData(name) || node.getStyle(name); - } - - TextRenderer.registerStyleHook(function(node, textGroup) { - var dataColor = node.getData('color'); - var selectedColor = node.getStyle('selected-color'); - var styleColor = node.getStyle('color'); - - var foreColor = dataColor || (node.isSelected() && selectedColor ? selectedColor : styleColor); - var fontFamily = getNodeDataOrStyle(node, 'font-family'); - var fontSize = getNodeDataOrStyle(node, 'font-size'); - - textGroup.fill(foreColor); - - textGroup.eachItem(function(index, item) { - item.setFont({ - 'family': fontFamily, - 'size': fontSize - }); - }); - }); - - - Module.register('fontmodule', { - 'commands': { - /** - * @command ForeColor - * @description 设置选中节点的字体颜色 - * @param {string} color 表示颜色的字符串 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - * @return 如果只有一个节点选中,返回已选中节点的字体颜色;否则返回 'mixed'。 - */ - 'forecolor': kity.createClass('fontcolorCommand', { - base: Command, - execute: function(km, color) { - var nodes = km.getSelectedNodes(); - nodes.forEach(function(n) { - n.setData('color', color); - n.render(); - }); - }, - queryState: function(km) { - return km.getSelectedNodes().length === 0 ? -1 : 0; - }, - queryValue: function(km) { - if (km.getSelectedNodes().length == 1) { - return km.getSelectedNodes()[0].getData('color'); - } - return 'mixed'; - } - }), - - /** - * @command Background - * @description 设置选中节点的背景颜色 - * @param {string} color 表示颜色的字符串 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - * @return 如果只有一个节点选中,返回已选中节点的背景颜色;否则返回 'mixed'。 - */ - 'background': kity.createClass('backgroudCommand', { - base: Command, - - execute: function(km, color) { - var nodes = km.getSelectedNodes(); - nodes.forEach(function(n) { - n.setData('background', color); - n.render(); - }); - }, - queryState: function(km) { - return km.getSelectedNodes().length === 0 ? -1 : 0; - }, - queryValue: function(km) { - if (km.getSelectedNodes().length == 1) { - return km.getSelectedNodes()[0].getData('background'); - } - return 'mixed'; - } - }), - - - /** - * @command FontFamily - * @description 设置选中节点的字体 - * @param {string} family 表示字体的字符串 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - * @return 返回首个选中节点的字体 - */ - 'fontfamily': kity.createClass('fontfamilyCommand', { - base: Command, - - execute: function(km, family) { - var nodes = km.getSelectedNodes(); - nodes.forEach(function(n) { - n.setData('font-family', family); - n.render(); - km.layout(); - }); - }, - queryState: function(km) { - return km.getSelectedNodes().length === 0 ? -1 : 0; - }, - queryValue: function(km) { - var node = km.getSelectedNode(); - if (node) return node.getData('font-family'); - return null; - } - }), - - /** - * @command FontSize - * @description 设置选中节点的字体大小 - * @param {number} size 字体大小(px) - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - * @return 返回首个选中节点的字体大小 - */ - 'fontsize': kity.createClass('fontsizeCommand', { - base: Command, - - execute: function(km, size) { - var nodes = km.getSelectedNodes(); - nodes.forEach(function(n) { - n.setData('font-size', size); - n.render(); - km.layout(300); - }); - }, - queryState: function(km) { - return km.getSelectedNodes().length === 0 ? -1 : 0; - }, - queryValue: function(km) { - var node = km.getSelectedNode(); - if (node) return node.getData('font-size'); - return null; - } - }) - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/hyperlink.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/hyperlink.js deleted file mode 100644 index a26c5a59..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/hyperlink.js +++ /dev/null @@ -1,127 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - // jscs:disable maximumLineLength - var linkShapePath = 'M16.614,10.224h-1.278c-1.668,0-3.07-1.07-3.599-2.556h4.877c0.707,0,1.278-0.571,1.278-1.278V3.834 c0-0.707-0.571-1.278-1.278-1.278h-4.877C12.266,1.071,13.668,0,15.336,0h1.278c2.116,0,3.834,1.716,3.834,3.834V6.39 C20.448,8.508,18.73,10.224,16.614,10.224z M5.112,5.112c0-0.707,0.573-1.278,1.278-1.278h7.668c0.707,0,1.278,0.571,1.278,1.278 S14.765,6.39,14.058,6.39H6.39C5.685,6.39,5.112,5.819,5.112,5.112z M2.556,3.834V6.39c0,0.707,0.573,1.278,1.278,1.278h4.877 c-0.528,1.486-1.932,2.556-3.599,2.556H3.834C1.716,10.224,0,8.508,0,6.39V3.834C0,1.716,1.716,0,3.834,0h1.278 c1.667,0,3.071,1.071,3.599,2.556H3.834C3.129,2.556,2.556,3.127,2.556,3.834z'; - - Module.register('hyperlink',{ - 'commands': { - - /** - * @command HyperLink - * @description 为选中的节点添加超链接 - * @param {string} url 超链接的 URL,设置为 null 移除 - * @param {string} title 超链接的说明 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - * @return 返回首个选中节点的超链接信息,JSON 对象: `{url: url, title: title}` - */ - 'hyperlink': kity.createClass('hyperlink', { - base: Command, - - execute: function(km, url, title) { - var nodes = km.getSelectedNodes(); - nodes.forEach(function(n) { - n.setData('hyperlink', url); - n.setData('hyperlinkTitle', url && title); - n.render(); - }); - km.layout(); - }, - queryState: function(km) { - var nodes = km.getSelectedNodes(), - result = 0; - if (nodes.length === 0) { - return -1; - } - nodes.forEach(function(n) { - if (n && n.getData('hyperlink')) { - result = 0; - return false; - } - }); - return result; - }, - queryValue: function(km) { - var node = km.getSelectedNode(); - return { - url: node.getData('hyperlink'), - title: node.getData('hyperlinkTitle') - }; - } - }) - }, - 'renderers': { - right: kity.createClass('hyperlinkrender', { - base: Renderer, - - create: function() { - - var link = new kity.HyperLink(); - var linkshape = new kity.Path(); - var outline = new kity.Rect(24, 22, -2, -6, 4).fill('rgba(255, 255, 255, 0)'); - - - linkshape.setPathData(linkShapePath).fill('#666'); - link.addShape(outline); - link.addShape(linkshape); - link.setTarget('_blank'); - link.setStyle('cursor', 'pointer'); - - link.on('mouseover', function() { - outline.fill('rgba(255, 255, 200, .8)'); - }).on('mouseout', function() { - outline.fill('rgba(255, 255, 255, 0)'); - }); - return link; - }, - - shouldRender: function(node) { - return node.getData('hyperlink'); - }, - - update: function(link, node, box) { - - var href = node.getData('hyperlink'); - link.setHref('#'); - - var allowed = ['^http:', '^https:', '^ftp:', '^mailto:']; - for (var i = 0; i < allowed.length; i++) { - var regex = new RegExp(allowed[i]); - if (regex.test(href)) { - link.setHref(href); - break; - } - } - var title = node.getData('hyperlinkTitle'); - - if (title) { - title = [title, '(', href, ')'].join(''); - } else { - title = href; - } - - link.node.setAttributeNS('http://www.w3.org/1999/xlink', 'title', title); - - var spaceRight = node.getStyle('space-right'); - - link.setTranslate(box.right + spaceRight + 2, -5); - return new kity.Box({ - x: box.right + spaceRight, - y: -11, - width: 24, - height: 22 - }); - } - }) - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/image-viewer.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/image-viewer.js deleted file mode 100644 index 5ff3a6d8..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/image-viewer.js +++ /dev/null @@ -1,111 +0,0 @@ -define(function(require, exports, module) { - - var kity = require('../core/kity'); - var keymap = require('../core/keymap'); - - var Module = require('../core/module'); - var Command = require('../core/command'); - - Module.register('ImageViewer', function() { - - function createEl(name, classNames, children) { - var el = document.createElement(name); - addClass(el, classNames); - children && children.length && children.forEach(function (child) { - el.appendChild(child); - }); - return el; - } - - function on(el, event, handler) { - el.addEventListener(event, handler); - } - - function addClass(el, classNames) { - classNames && classNames.split(' ').forEach(function (className) { - el.classList.add(className); - }); - } - - function removeClass(el, classNames) { - classNames && classNames.split(' ').forEach(function (className) { - el.classList.remove(className); - }); - } - - var ImageViewer = kity.createClass('ImageViewer', { - constructor: function () { - var btnClose = createEl('button', 'km-image-viewer-btn km-image-viewer-close'); - var btnSource = createEl('button', 'km-image-viewer-btn km-image-viewer-source'); - var image = this.image = createEl('img'); - var toolbar = this.toolbar = createEl('div', 'km-image-viewer-toolbar', [btnSource, btnClose]); - var container = createEl('div', 'km-image-viewer-container', [image]); - var viewer = this.viewer = createEl('div', 'km-image-viewer', [toolbar, container]); - this.hotkeyHandler = this.hotkeyHandler.bind(this) - on(btnClose, 'click', this.close.bind(this)); - on(btnSource, 'click', this.viewSource.bind(this)); - on(image, 'click', this.zoomImage.bind(this)); - on(viewer, 'contextmenu', this.toggleToolbar.bind(this)); - on(document, 'keydown', this.hotkeyHandler); - }, - dispose: function () { - this.close(); - document.removeEventListener('remove', this.hotkeyHandler); - }, - hotkeyHandler: function (e) { - if (!this.actived) { - return; - } - if (e.keyCode === keymap['esc']) { - this.close(); - } - }, - toggleToolbar: function (e) { - e && e.preventDefault(); - this.toolbar.classList.toggle('hidden'); - }, - zoomImage: function (restore) { - var image = this.image; - if (typeof restore === 'boolean') { - restore && addClass(image, 'limited'); - } - else { - image.classList.toggle('limited'); - } - }, - viewSource: function (src) { - window.open(this.image.src); - }, - open: function (src) { - var input = document.querySelector('input'); - if (input) { - input.focus(); - input.blur(); - } - this.image.src = src; - this.zoomImage(true); - document.body.appendChild(this.viewer); - this.actived = true; - }, - close: function () { - this.image.src = ''; - document.body.removeChild(this.viewer); - this.actived = false; - } - }); - - return { - init: function() { - this.viewer = new ImageViewer(); - }, - events: { - 'normal.dblclick': function(e) { - var shape = e.kityEvent.targetShape - if (shape.__KityClassName === 'Image' && shape.url) { - this.viewer.open(shape.url); - } - } - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/image.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/image.js deleted file mode 100644 index 8eb1d80c..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/image.js +++ /dev/null @@ -1,147 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - Module.register('image', function() { - function loadImageSize(url, callback) { - var img = document.createElement('img'); - img.onload = function() { - callback(img.width, img.height); - }; - img.onerror = function() { - callback(null); - }; - img.src = url; - } - - function fitImageSize(width, height, maxWidth, maxHeight) { - var ratio = width / height, - fitRatio = maxWidth / maxHeight; - - // 宽高比大于最大尺寸的宽高比,以宽度为标准适应 - if (width > maxWidth && ratio > fitRatio) { - width = maxWidth; - height = width / ratio; - } else if (height > maxHeight) { - height = maxHeight; - width = height * ratio; - } - - return { - width: width | 0, - height: height | 0 - }; - } - - /** - * @command Image - * @description 为选中的节点添加图片 - * @param {string} url 图片的 URL,设置为 null 移除 - * @param {string} title 图片的说明 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - * @return 返回首个选中节点的图片信息,JSON 对象: `{url: url, title: title}` - */ - var ImageCommand = kity.createClass('ImageCommand', { - base: Command, - - execute: function(km, url, title) { - var nodes = km.getSelectedNodes(); - - loadImageSize(url, function(width, height) { - nodes.forEach(function(n) { - var size = fitImageSize( - width, height, - km.getOption('maxImageWidth'), - km.getOption('maxImageHeight')); - n.setData('image', url); - n.setData('imageTitle', url && title); - n.setData('imageSize', url && size); - n.render(); - }); - km.fire('saveScene'); - km.layout(300); - }); - - }, - queryState: function(km) { - var nodes = km.getSelectedNodes(), - result = 0; - if (nodes.length === 0) { - return -1; - } - nodes.forEach(function(n) { - if (n && n.getData('image')) { - result = 0; - return false; - } - }); - return result; - }, - queryValue: function(km) { - var node = km.getSelectedNode(); - return { - url: node.getData('image'), - title: node.getData('imageTitle') - }; - } - }); - - var ImageRenderer = kity.createClass('ImageRenderer', { - base: Renderer, - - create: function(node) { - return new kity.Image(node.getData('image')); - }, - - shouldRender: function(node) { - return node.getData('image'); - }, - - update: function(image, node, box) { - var url = node.getData('image'); - var title = node.getData('imageTitle'); - var size = node.getData('imageSize'); - var spaceTop = node.getStyle('space-top'); - - if (!size) return; - - if (title) { - image.node.setAttributeNS('http://www.w3.org/1999/xlink', 'title', title); - } - - var x = box.cx - size.width / 2; - var y = box.y - size.height - spaceTop; - - image - .setUrl(url) - .setX(x | 0) - .setY(y | 0) - .setWidth(size.width | 0) - .setHeight(size.height | 0); - - return new kity.Box(x | 0, y | 0, size.width | 0, size.height | 0); - } - }); - - return { - 'defaultOptions': { - 'maxImageWidth': 200, - 'maxImageHeight': 200 - }, - 'commands': { - 'image': ImageCommand - }, - 'renderers': { - 'top': ImageRenderer - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/keynav.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/keynav.js deleted file mode 100644 index 4b90289a..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/keynav.js +++ /dev/null @@ -1,171 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - var keymap = require('../core/keymap'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - Module.register('KeyboardModule', function() { - var min = Math.min, - max = Math.max, - abs = Math.abs, - sqrt = Math.sqrt, - exp = Math.exp; - - function buildPositionNetwork(root) { - var pointIndexes = [], - p; - root.traverse(function(node) { - p = node.getLayoutBox(); - - // bugfix: 不应导航到收起的节点(判断其尺寸是否存在) - if (p.width && p.height) { - pointIndexes.push({ - left: p.x, - top: p.y, - right: p.x + p.width, - bottom: p.y + p.height, - width: p.width, - height: p.height, - node: node - }); - } - }); - for (var i = 0; i < pointIndexes.length; i++) { - findClosestPointsFor(pointIndexes, i); - } - } - - // 这是金泉的点子,赞! - // 求两个不相交矩形的最近距离 - function getCoefedDistance(box1, box2) { - var xMin, xMax, yMin, yMax, xDist, yDist, dist, cx, cy; - xMin = min(box1.left, box2.left); - xMax = max(box1.right, box2.right); - yMin = min(box1.top, box2.top); - yMax = max(box1.bottom, box2.bottom); - - xDist = xMax - xMin - box1.width - box2.width; - yDist = yMax - yMin - box1.height - box2.height; - - if (xDist < 0) dist = yDist; - else if (yDist < 0) dist = xDist; - else dist = sqrt(xDist * xDist + yDist * yDist); - - var node1 = box1.node; - var node2 = box2.node; - - // sibling - if (node1.parent == node2.parent) { - dist /= 10; - } - // parent - if (node2.parent == node1) { - dist /= 5; - } - - return dist; - } - - function findClosestPointsFor(pointIndexes, iFind) { - var find = pointIndexes[iFind]; - var most = {}, - quad; - var current, dist; - - for (var i = 0; i < pointIndexes.length; i++) { - - if (i == iFind) continue; - current = pointIndexes[i]; - - dist = getCoefedDistance(current, find); - - // left check - if (current.right < find.left) { - if (!most.left || dist < most.left.dist) { - most.left = { - dist: dist, - node: current.node - }; - } - } - - // right check - if (current.left > find.right) { - if (!most.right || dist < most.right.dist) { - most.right = { - dist: dist, - node: current.node - }; - } - } - - // top check - if (current.bottom < find.top) { - if (!most.top || dist < most.top.dist) { - most.top = { - dist: dist, - node: current.node - }; - } - } - - // bottom check - if (current.top > find.bottom) { - if (!most.down || dist < most.down.dist) { - most.down = { - dist: dist, - node: current.node - }; - } - } - } - find.node._nearestNodes = { - right: most.right && most.right.node || null, - top: most.top && most.top.node || null, - left: most.left && most.left.node || null, - down: most.down && most.down.node || null - }; - } - - function navigateTo(km, direction) { - var referNode = km.getSelectedNode(); - if (!referNode) { - km.select(km.getRoot()); - buildPositionNetwork(km.getRoot()); - return; - } - if (!referNode._nearestNodes) { - buildPositionNetwork(km.getRoot()); - } - var nextNode = referNode._nearestNodes[direction]; - if (nextNode) { - km.select(nextNode, true); - } - } - - // 稀释用 - var lastFrame; - return { - 'events': { - 'layoutallfinish': function() { - var root = this.getRoot(); - buildPositionNetwork(root); - }, - 'normal.keydown readonly.keydown': function(e) { - var minder = this; - ['left', 'right', 'up', 'down'].forEach(function(key) { - if (e.isShortcutKey(key)) { - navigateTo(minder, key == 'up' ? 'top' : key); - e.preventDefault(); - } - }); - } - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/layout.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/layout.js deleted file mode 100644 index 4bcedf61..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/layout.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * @fileOverview - * - * 布局模块 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function(require, exports, module) { - var kity = require('../core/kity'); - var Command = require('../core/command'); - var Module = require('../core/module'); - - /** - * @command Layout - * @description 设置选中节点的布局 - * 允许使用的布局可以使用 `kityminder.Minder.getLayoutList()` 查询 - * @param {string} name 布局的名称,设置为 null 则使用继承或默认的布局 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - * @return 返回首个选中节点的布局名称 - */ - var LayoutCommand = kity.createClass('LayoutCommand', { - base: Command, - - execute: function(minder, name) { - var nodes = minder.getSelectedNodes(); - nodes.forEach(function(node) { - node.layout(name); - }); - }, - - queryValue: function(minder) { - var node = minder.getSelectedNode(); - if (node) { - return node.getData('layout'); - } - }, - - queryState: function(minder) { - return minder.getSelectedNode() ? 0 : -1; - } - }); - - /** - * @command ResetLayout - * @description 重设选中节点的布局,如果当前没有选中的节点,重设整个脑图的布局 - * @state - * 0: 始终可用 - * @return 返回首个选中节点的布局名称 - */ - var ResetLayoutCommand = kity.createClass('ResetLayoutCommand', { - base: Command, - - execute: function(minder) { - var nodes = minder.getSelectedNodes(); - - if (!nodes.length) nodes = [minder.getRoot()]; - - nodes.forEach(function(node) { - node.traverse(function(child) { - child.resetLayoutOffset(); - if (!child.isRoot()) { - child.setData('layout', null); - } - }); - }); - minder.layout(300); - }, - - enableReadOnly: true - }); - - Module.register('LayoutModule', { - commands: { - 'layout': LayoutCommand, - 'resetlayout': ResetLayoutCommand - }, - contextmenu: [{ - command: 'resetlayout' - }, { - divider: true - }], - - commandShortcutKeys: { - 'resetlayout': 'Ctrl+Shift+L' - } - }); - -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/node.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/node.js deleted file mode 100644 index 28a8fb99..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/node.js +++ /dev/null @@ -1,150 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - /** - * @command AppendChildNode - * @description 添加子节点到选中的节点中 - * @param {string|object} textOrData 要插入的节点的文本或数据 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - */ - var AppendChildCommand = kity.createClass('AppendChildCommand', { - base: Command, - execute: function(km, text) { - var parent = km.getSelectedNode(); - if (!parent) { - return null; - } - var node = km.createNode(text, parent); - km.select(node, true); - if (parent.isExpanded()) { - node.render(); - } - else { - parent.expand(); - parent.renderTree(); - } - km.layout(600); - }, - queryState: function(km) { - var selectedNode = km.getSelectedNode(); - return selectedNode ? 0 : -1; - } - }); - - /** - * @command AppendSiblingNode - * @description 添加选中的节点的兄弟节点 - * @param {string|object} textOrData 要添加的节点的文本或数据 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - */ - var AppendSiblingCommand = kity.createClass('AppendSiblingCommand', { - base: Command, - execute: function(km, text) { - var sibling = km.getSelectedNode(); - var parent = sibling.parent; - if (!parent) { - return km.execCommand('AppendChildNode', text); - } - var node = km.createNode(text, parent, sibling.getIndex() + 1); - node.setGlobalLayoutTransform(sibling.getGlobalLayoutTransform()); - km.select(node, true); - node.render(); - km.layout(600); - }, - queryState: function(km) { - var selectedNode = km.getSelectedNode(); - return selectedNode ? 0 : -1; - } - }); - - /** - * @command RemoveNode - * @description 移除选中的节点 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - */ - var RemoveNodeCommand = kity.createClass('RemoverNodeCommand', { - base: Command, - execute: function(km) { - var nodes = km.getSelectedNodes(); - var ancestor = MinderNode.getCommonAncestor.apply(null, nodes); - var index = nodes[0].getIndex(); - - nodes.forEach(function(node) { - if (!node.isRoot()) km.removeNode(node); - }); - if (nodes.length == 1) { - var selectBack = ancestor.children[index - 1] || ancestor.children[index]; - km.select(selectBack || ancestor || km.getRoot(), true); - } else { - km.select(ancestor || km.getRoot(), true); - } - km.layout(600); - }, - queryState: function(km) { - var selectedNode = km.getSelectedNode(); - return selectedNode && !selectedNode.isRoot() ? 0 : -1; - } - }); - - var AppendParentCommand = kity.createClass('AppendParentCommand', { - base: Command, - execute: function(km, text) { - var nodes = km.getSelectedNodes(); - - nodes.sort(function(a, b) { - return a.getIndex() - b.getIndex(); - }); - var parent = nodes[0].parent; - - var newParent = km.createNode(text, parent, nodes[0].getIndex()); - nodes.forEach(function(node) { - newParent.appendChild(node); - }); - newParent.setGlobalLayoutTransform(nodes[nodes.length >> 1].getGlobalLayoutTransform()); - - km.select(newParent, true); - km.layout(600); - }, - queryState: function(km) { - var nodes = km.getSelectedNodes(); - if (!nodes.length) return -1; - var parent = nodes[0].parent; - if (!parent) return -1; - for (var i = 1; i < nodes.length; i++) { - if (nodes[i].parent != parent) return -1; - } - return 0; - } - }); - - Module.register('NodeModule', function() { - return { - commands: { - 'AppendChildNode': AppendChildCommand, - 'AppendSiblingNode': AppendSiblingCommand, - 'RemoveNode': RemoveNodeCommand, - 'AppendParentNode': AppendParentCommand - }, - - 'commandShortcutKeys': { - 'appendsiblingnode': 'normal::Enter', - 'appendchildnode': 'normal::Insert|Tab', - 'appendparentnode': 'normal::Shift+Tab|normal::Shift+Insert', - 'removenode': 'normal::Del|Backspace' - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/note.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/note.js deleted file mode 100644 index e5159ded..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/note.js +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @fileOverview - * - * 支持节点详细信息(HTML)格式 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - Module.register('NoteModule', function() { - - var NOTE_PATH = 'M9,9H3V8h6L9,9L9,9z M9,7H3V6h6V7z M9,5H3V4h6V5z M8.5,11H2V2h8v7.5 M9,12l2-2V1H1v11'; - - - /** - * @command Note - * @description 设置节点的备注信息 - * @param {string} note 要设置的备注信息,设置为 null 则移除备注信息 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - */ - var NoteCommand = kity.createClass('NoteCommand', { - base: Command, - - execute: function(minder, note) { - var node = minder.getSelectedNode(); - node.setData('note', note); - node.render(); - node.getMinder().layout(300); - }, - - queryState: function(minder) { - return minder.getSelectedNodes().length === 1 ? 0 : -1; - }, - - queryValue: function(minder) { - var node = minder.getSelectedNode(); - return node && node.getData('note'); - } - }); - - var NoteIcon = kity.createClass('NoteIcon', { - base: kity.Group, - - constructor: function() { - this.callBase(); - this.width = 16; - this.height = 17; - this.rect = new kity.Rect(16, 17, 0.5, -8.5, 2).fill('transparent'); - this.path = new kity.Path().setPathData(NOTE_PATH).setTranslate(2.5, -6.5); - this.addShapes([this.rect, this.path]); - - this.on('mouseover', function() { - this.rect.fill('rgba(255, 255, 200, .8)'); - }).on('mouseout', function() { - this.rect.fill('transparent'); - }); - - this.setStyle('cursor', 'pointer'); - } - }); - - var NoteIconRenderer = kity.createClass('NoteIconRenderer', { - base: Renderer, - - create: function(node) { - var icon = new NoteIcon(); - icon.on('mousedown', function(e) { - e.preventDefault(); - node.getMinder().fire('editnoterequest'); - }); - icon.on('mouseover', function() { - node.getMinder().fire('shownoterequest', {node: node, icon: icon}); - }); - icon.on('mouseout', function() { - node.getMinder().fire('hidenoterequest', {node: node, icon: icon}); - }); - return icon; - }, - - shouldRender: function(node) { - return node.getData('note'); - }, - - update: function(icon, node, box) { - var x = box.right + node.getStyle('space-left'); - var y = box.cy; - - icon.path.fill(node.getStyle('color')); - icon.setTranslate(x, y); - - return new kity.Box(x, Math.round(y - icon.height / 2), icon.width, icon.height); - } - - }); - - return { - renderers: { - right: NoteIconRenderer - }, - commands: { - 'note': NoteCommand - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/outline.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/outline.js deleted file mode 100644 index 499bf428..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/outline.js +++ /dev/null @@ -1,165 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - var OutlineRenderer = kity.createClass('OutlineRenderer', { - base: Renderer, - - create: function(node) { - - var outline = new kity.Rect() - .setId(utils.uuid('node_outline')); - - this.bringToBack = true; - - return outline; - }, - - update: function(outline, node, box) { - - var shape = node.getStyle('shape'); - - var paddingLeft = node.getStyle('padding-left'), - paddingRight = node.getStyle('padding-right'), - paddingTop = node.getStyle('padding-top'), - paddingBottom = node.getStyle('padding-bottom'); - - var outlineBox = { - x: box.x - paddingLeft, - y: box.y - paddingTop, - width: box.width + paddingLeft + paddingRight, - height: box.height + paddingTop + paddingBottom - }; - - - var radius = node.getStyle('radius'); - // 天盘图圆形的情况 - if (shape && shape == 'circle') { - var p = Math.pow; - var r = Math.round; - - radius = r(Math.sqrt(p(outlineBox.width, 2) + p(outlineBox.height, 2)) / 2); - - outlineBox.x = box.cx - radius; - outlineBox.y = box.cy - radius; - outlineBox.width = 2 * radius; - outlineBox.height = 2 * radius; - } - - var prefix = node.isSelected() ? (node.getMinder().isFocused() ? 'selected-' : 'blur-selected-') : ''; - outline - .setPosition(outlineBox.x, outlineBox.y) - .setSize(outlineBox.width, outlineBox.height) - .setRadius(radius) - .fill(node.getData('background') || node.getStyle(prefix + 'background') || node.getStyle('background')) - .stroke(node.getStyle(prefix + 'stroke' || node.getStyle('stroke')), - node.getStyle(prefix + 'stroke-width')); - - return new kity.Box(outlineBox); - } - }); - - var ShadowRenderer = kity.createClass('ShadowRenderer', { - base: Renderer, - - create: function(node) { - this.bringToBack = true; - return new kity.Rect(); - }, - - shouldRender: function(node) { - return node.getStyle('shadow'); - }, - - update: function(shadow, node, box) { - shadow.setPosition(box.x + 4, box.y + 5) - .fill(node.getStyle('shadow')); - - var shape = node.getStyle('shape'); - if(!shape){ - shadow.setSize(box.width, box.height); - shadow.setRadius(node.getStyle('radius')); - - }else if(shape=='circle'){ - var width= Math.max(box.width,box.height); - shadow.setSize(width, width); - shadow.setRadius(width/2); - } - } - }); - - var marker = new kity.Marker(); - - marker.setWidth(10); - marker.setHeight(12); - marker.setRef(0, 0); - marker.setViewBox(-6, -4, 8, 10); - - marker.addShape(new kity.Path().setPathData('M-5-3l5,3,-5,3').stroke('#33ffff')); - - var wireframeOption = /wire/.test(window.location.href); - var WireframeRenderer = kity.createClass('WireframeRenderer', { - base: Renderer, - - create: function() { - var wireframe = new kity.Group(); - var oxy = this.oxy = new kity.Path() - .stroke('#f6f') - .setPathData('M0,-50L0,50M-50,0L50,0'); - - var box = this.wireframe = new kity.Rect() - .stroke('lightgreen'); - - var vectorIn = this.vectorIn = new kity.Path() - .stroke('#66ffff'); - var vectorOut = this.vectorOut = new kity.Path() - .stroke('#66ffff'); - - vectorIn.setMarker(marker, 'end'); - vectorOut.setMarker(marker, 'end'); - - return wireframe.addShapes([oxy, box, vectorIn, vectorOut]); - }, - - shouldRender: function() { - return wireframeOption; - }, - - update: function(created, node, box) { - this.wireframe - .setPosition(box.x, box.y) - .setSize(box.width, box.height); - var pin = node.getVertexIn(); - var pout = node.getVertexOut(); - var vin = node.getLayoutVectorIn().normalize(30); - var vout = node.getLayoutVectorOut().normalize(30); - this.vectorIn.setPathData(['M', pin.offset(vin.reverse()), 'L', pin]); - this.vectorOut.setPathData(['M', pout, 'l', vout]); - } - }); - - Module.register('OutlineModule', function() { - return { - events: (!wireframeOption ? null : { - 'ready': function() { - this.getPaper().addResource(marker); - }, - 'layoutallfinish': function() { - this.getRoot().traverse(function(node) { - node.getRenderer('WireframeRenderer').update(null, node, node.getContentBox()); - }); - } - }), - renderers: { - outline: OutlineRenderer, - outside: [ShadowRenderer, WireframeRenderer] - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/priority.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/priority.js deleted file mode 100644 index a7b7452c..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/priority.js +++ /dev/null @@ -1,156 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - Module.register('PriorityModule', function() { - var minder = this; - - // Designed by Akikonata - // [MASK, BACK] - var PRIORITY_COLORS = [null, ['#FF1200', '#840023'], // 1 - red - ['#0074FF', '#01467F'], // 2 - blue - ['#00AF00', '#006300'], // 3 - green - ['#FF962E', '#B25000'], // 4 - orange - ['#A464FF', '#4720C4'], // 5 - purple - ['#A3A3A3', '#515151'], // 6,7,8,9 - gray - ['#A3A3A3', '#515151'], - ['#A3A3A3', '#515151'], - ['#A3A3A3', '#515151'], - ]; // hue from 1 to 5 - - // jscs:disable maximumLineLength - var BACK_PATH = 'M0,13c0,3.866,3.134,7,7,7h6c3.866,0,7-3.134,7-7V7H0V13z'; - var MASK_PATH = 'M20,10c0,3.866-3.134,7-7,7H7c-3.866,0-7-3.134-7-7V7c0-3.866,3.134-7,7-7h6c3.866,0,7,3.134,7,7V10z'; - - var PRIORITY_DATA = 'priority'; - - // 优先级图标的图形 - var PriorityIcon = kity.createClass('PriorityIcon', { - base: kity.Group, - - constructor: function() { - this.callBase(); - this.setSize(20); - this.create(); - this.setId(utils.uuid('node_priority')); - }, - - setSize: function(size) { - this.width = this.height = size; - }, - - create: function() { - var white, back, mask, number; // 4 layer - - white = new kity.Path().setPathData(MASK_PATH).fill('white'); - back = new kity.Path().setPathData(BACK_PATH).setTranslate(0.5, 0.5); - mask = new kity.Path().setPathData(MASK_PATH).setOpacity(0.8).setTranslate(0.5, 0.5); - - number = new kity.Text() - .setX(this.width / 2 - 0.5).setY(this.height / 2) - .setTextAnchor('middle') - .setVerticalAlign('middle') - .setFontItalic(true) - .setFontSize(12) - .fill('white'); - - this.addShapes([back, mask, number]); - this.mask = mask; - this.back = back; - this.number = number; - }, - - setValue: function(value) { - var back = this.back, - mask = this.mask, - number = this.number; - - var color = PRIORITY_COLORS[value]; - - if (color) { - back.fill(color[1]); - mask.fill(color[0]); - } - - number.setContent(value); - } - }); - - /** - * @command Priority - * @description 设置节点的优先级信息 - * @param {number} value 要设置的优先级(添加一个优先级小图标) - * 取值为 0 移除优先级信息; - * 取值为 1 - 9 设置优先级,超过 9 的优先级不渲染 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - */ - var PriorityCommand = kity.createClass('SetPriorityCommand', { - base: Command, - execute: function(km, value) { - var nodes = km.getSelectedNodes(); - for (var i = 0; i < nodes.length; i++) { - nodes[i].setData(PRIORITY_DATA, value || null).render(); - } - km.layout(); - }, - queryValue: function(km) { - var nodes = km.getSelectedNodes(); - var val; - for (var i = 0; i < nodes.length; i++) { - val = nodes[i].getData(PRIORITY_DATA); - if (val) break; - } - return val || null; - }, - - queryState: function(km) { - return km.getSelectedNodes().length ? 0 : -1; - } - }); - return { - 'commands': { - 'priority': PriorityCommand - }, - 'renderers': { - left: kity.createClass('PriorityRenderer', { - base: Renderer, - - create: function(node) { - return new PriorityIcon(); - }, - - shouldRender: function(node) { - return node.getData(PRIORITY_DATA); - }, - - update: function(icon, node, box) { - var data = node.getData(PRIORITY_DATA); - var spaceLeft = node.getStyle('space-left'), - x, y; - - icon.setValue(data); - x = box.left - icon.width - spaceLeft; - y = -icon.height / 2; - - icon.setTranslate(x, y); - - return new kity.Box({ - x: x, - y: y, - width: icon.width, - height: icon.height - }); - } - }) - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/progress.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/progress.js deleted file mode 100644 index a7fa451a..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/progress.js +++ /dev/null @@ -1,160 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - Module.register('ProgressModule', function() { - var minder = this; - - var PROGRESS_DATA = 'progress'; - - // Designed by Akikonata - var BG_COLOR = '#FFED83'; - var PIE_COLOR = '#43BC00'; - var SHADOW_PATH = 'M10,3c4.418,0,8,3.582,8,8h1c0-5.523-3.477-10-9-10S1,5.477,1,11h1C2,6.582,5.582,3,10,3z'; - var SHADOW_COLOR = '#8E8E8E'; - - // jscs:disable maximumLineLength - var FRAME_PATH = 'M10,0C4.477,0,0,4.477,0,10c0,5.523,4.477,10,10,10s10-4.477,10-10C20,4.477,15.523,0,10,0zM10,18c-4.418,0-8-3.582-8-8s3.582-8,8-8s8,3.582,8,8S14.418,18,10,18z'; - - var FRAME_GRAD = new kity.LinearGradient().pipe(function(g) { - g.setStartPosition(0, 0); - g.setEndPosition(0, 1); - g.addStop(0, '#fff'); - g.addStop(1, '#ccc'); - }); - var CHECK_PATH = 'M15.812,7.896l-6.75,6.75l-4.5-4.5L6.25,8.459l2.812,2.803l5.062-5.053L15.812,7.896z'; - var CHECK_COLOR = '#EEE'; - - minder.getPaper().addResource(FRAME_GRAD); - - // 进度图标的图形 - var ProgressIcon = kity.createClass('ProgressIcon', { - base: kity.Group, - - constructor: function(value) { - this.callBase(); - this.setSize(20); - this.create(); - this.setValue(value); - this.setId(utils.uuid('node_progress')); - this.translate(0.5, 0.5); - }, - - setSize: function(size) { - this.width = this.height = size; - }, - - create: function() { - - var bg, pie, shadow, frame, check; - - bg = new kity.Circle(9) - .fill(BG_COLOR); - - pie = new kity.Pie(9, 0) - .fill(PIE_COLOR); - - shadow = new kity.Path() - .setPathData(SHADOW_PATH) - .setTranslate(-10, -10) - .fill(SHADOW_COLOR); - - frame = new kity.Path() - .setTranslate(-10, -10) - .setPathData(FRAME_PATH) - .fill(FRAME_GRAD); - - check = new kity.Path() - .setTranslate(-10, -10) - .setPathData(CHECK_PATH) - .fill(CHECK_COLOR); - - this.addShapes([bg, pie, shadow, check, frame]); - this.pie = pie; - this.check = check; - }, - - setValue: function(value) { - this.pie.setAngle(-360 * (value - 1) / 8); - this.check.setVisible(value == 9); - } - }); - - /** - * @command Progress - * @description 设置节点的进度信息(添加一个进度小图标) - * @param {number} value 要设置的进度 - * 取值为 0 移除进度信息; - * 取值为 1 表示未开始; - * 取值为 2 表示完成 1/8; - * 取值为 3 表示完成 2/8; - * 取值为 4 表示完成 3/8; - * 其余类推,取值为 9 表示全部完成 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - */ - var ProgressCommand = kity.createClass('ProgressCommand', { - base: Command, - execute: function(km, value) { - var nodes = km.getSelectedNodes(); - for (var i = 0; i < nodes.length; i++) { - nodes[i].setData(PROGRESS_DATA, value || null).render(); - } - km.layout(); - }, - queryValue: function(km) { - var nodes = km.getSelectedNodes(); - var val; - for (var i = 0; i < nodes.length; i++) { - val = nodes[i].getData(PROGRESS_DATA); - if (val) break; - } - return val || null; - }, - - queryState: function(km) { - return km.getSelectedNodes().length ? 0 : -1; - } - }); - - return { - 'commands': { - 'progress': ProgressCommand - }, - 'renderers': { - left: kity.createClass('ProgressRenderer', { - base: Renderer, - - create: function(node) { - return new ProgressIcon(); - }, - - shouldRender: function(node) { - return node.getData(PROGRESS_DATA); - }, - - update: function(icon, node, box) { - var data = node.getData(PROGRESS_DATA); - var spaceLeft = node.getStyle('space-left'); - var x, y; - - icon.setValue(data); - - x = box.left - icon.width - spaceLeft; - y = -icon.height / 2; - icon.setTranslate(x + icon.width / 2, y + icon.height / 2); - - return new kity.Box(x, y, icon.width, icon.height); - } - }) - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/resource.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/resource.js deleted file mode 100644 index d672f6c4..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/resource.js +++ /dev/null @@ -1,314 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - Module.register('Resource', function() { - - // String Hash - // https://github.com/drostie/sha3-js/edit/master/blake32.min.js - var blake32=(function(){var k,g,r,l,m,o,p,q,t,w,x;x=4*(1<<30);k=[0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19];m=[0x243F6A88,0x85A308D3,0x13198A2E,0x03707344,0xA4093822,0x299F31D0,0x082EFA98,0xEC4E6C89,0x452821E6,0x38D01377,0xBE5466CF,0x34E90C6C,0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917];w=function(i){if(i<0){i+=x}return("00000000"+i.toString(16)).slice(-8)};o=[[16,50,84,118,152,186,220,254],[174,132,249,109,193,32,123,53],[139,12,37,223,234,99,23,73],[151,19,205,235,98,165,4,143],[9,117,66,250,30,203,134,211],[194,166,176,56,212,87,239,145],[92,241,222,164,112,54,41,184],[189,231,28,147,5,79,104,162],[246,158,59,128,44,125,65,90],[42,72,103,81,191,233,195,13]];p=function(a,b,n){var s=q[a]^q[b];q[a]=(s>>>n)|(s<<(32-n))};g=function(i,a,b,c,d){var u=l+o[r][i]%16,v=l+(o[r][i]>>4);a%=4;b=4+b%4;c=8+c%4;d=12+d%4;q[a]+=q[b]+(t[u]^m[v%16]);p(d,a,16);q[c]+=q[d];p(b,c,12);q[a]+=q[b]+(t[v]^m[u%16]);p(d,a,8);q[c]+=q[d];p(b,c,7)};return function(a,b){if(!(b instanceof Array&&b.length===4)){b=[0,0,0,0]}var c,d,e,L,f,h,j,i;d=k.slice(0);c=m.slice(0,8);for(r=0;r<4;r+=1){c[r]^=b[r]}e=a.length*16;f=(e%512>446||e%512===0)?0:e;if(e%512===432){a+="\u8001"}else{a+="\u8000";while(a.length%32!==27){a+="\u0000"}a+="\u0001"}t=[];for(i=0;i= 0; i--) { - ch = str.charCodeAt(i); - hash ^= ((hash << 5) + ch + (hash >> 2)); - } - return (hash & 0x7FFFFFFF); - }, - - /** - * 获取脑图中某个资源对应的颜色 - * - * 如果存在同名资源,则返回已经分配给该资源的颜色,否则分配给该资源一个颜色,并且返回 - * - * 如果资源数超过颜色序列数量,返回哈希颜色 - * - * @param {String} resource 资源名称 - * @return {Color} - */ - getResourceColor: function(resource) { - var colorMapping = this._getResourceColorIndexMapping(); - var nextIndex; - - if (!Object.prototype.hasOwnProperty.call(colorMapping, resource)) { - // 找不到找下个可用索引 - nextIndex = this._getNextResourceColorIndex(); - colorMapping[resource] = nextIndex; - } - - // 资源过多,找不到可用索引颜色,统一返回哈希函数得到的颜色 - return RESOURCE_COLOR_SERIES[colorMapping[resource]] || kity.Color.createHSL(Math.floor(this.getHashCode(resource) / 0x7FFFFFFF * 359), 100, 85); - }, - - /** - * 获得已使用的资源的列表 - * - * @return {Array} - */ - getUsedResource: function() { - var mapping = this._getResourceColorIndexMapping(); - var used = [], - resource; - - for (resource in mapping) { - if (Object.prototype.hasOwnProperty.call(mapping, resource)) { - used.push(resource); - } - } - - return used; - }, - - /** - * 获取脑图下一个可用的资源颜色索引 - * - * @return {int} - */ - _getNextResourceColorIndex: function() { - // 获取现有颜色映射 - // resource => color_index - var colorMapping = this._getResourceColorIndexMapping(); - - var resource, used, i; - - used = []; - - // 抽取已经使用的值到 used 数组 - for (resource in colorMapping) { - if (Object.prototype.hasOwnProperty.call(colorMapping, resource)) { - used.push(colorMapping[resource]); - } - } - - // 枚举所有的可用值,如果还没被使用,返回 - for (i = 0; i < RESOURCE_COLOR_SERIES.length; i++) { - if (!~used.indexOf(i)) return i; - } - - // 没有可用的颜色了 - return -1; - }, - - // 获取现有颜色映射 - // resource => color_index - _getResourceColorIndexMapping: function() { - return this._resourceColorMapping || (this._resourceColorMapping = {}); - } - - }); - - - /** - * @class 设置资源的命令 - * - * @example - * - * // 设置选中节点资源为 "张三" - * minder.execCommand('resource', ['张三']); - * - * // 添加资源 "李四" 到选中节点 - * var resource = minder.queryCommandValue(); - * resource.push('李四'); - * minder.execCommand('resource', resource); - * - * // 清除选中节点的资源 - * minder.execCommand('resource', null); - */ - var ResourceCommand = kity.createClass('ResourceCommand', { - - base: Command, - - execute: function(minder, resource) { - var nodes = minder.getSelectedNodes(); - - if (typeof(resource) == 'string') { - resource = [resource]; - } - - nodes.forEach(function(node) { - node.setData('resource', resource).render(); - }); - - minder.layout(200); - }, - - queryValue: function(minder) { - var nodes = minder.getSelectedNodes(); - var resource = []; - - nodes.forEach(function(node) { - var nodeResource = node.getData('resource'); - - if (!nodeResource) return; - - nodeResource.forEach(function(name) { - if (!~resource.indexOf(name)) { - resource.push(name); - } - }); - }); - - return resource; - }, - - queryState: function(km) { - return km.getSelectedNode() ? 0 : -1; - } - }); - - /** - * @class 资源的覆盖图形 - * - * 该类为一个资源以指定的颜色渲染一个动态的覆盖图形 - */ - var ResourceOverlay = kity.createClass('ResourceOverlay', { - base: kity.Group, - - constructor: function() { - this.callBase(); - - var text, rect; - - rect = this.rect = new kity.Rect().setRadius(4); - - text = this.text = new kity.Text() - .setFontSize(12) - .setVerticalAlign('middle'); - - this.addShapes([rect, text]); - }, - - setValue: function(resourceName, color) { - var paddingX = 8, - paddingY = 4, - borderRadius = 4; - var text, box, rect; - - text = this.text; - - if (resourceName == this.lastResourceName) { - - box = this.lastBox; - - } else { - - text.setContent(resourceName); - - box = text.getBoundaryBox(); - this.lastResourceName = resourceName; - this.lastBox = box; - - } - - text.setX(paddingX).fill(color.dec('l', 70)); - - rect = this.rect; - rect.setPosition(0, box.y - paddingY); - this.width = Math.round(box.width + paddingX * 2); - this.height = Math.round(box.height + paddingY * 2); - rect.setSize(this.width, this.height); - rect.fill(color); - } - }); - - /** - * @class 资源渲染器 - */ - var ResourceRenderer = kity.createClass('ResourceRenderer', { - base: Renderer, - - create: function(node) { - this.overlays = []; - return new kity.Group(); - }, - - shouldRender: function(node) { - return node.getData('resource') && node.getData('resource').length; - }, - - update: function(container, node, box) { - var spaceRight = node.getStyle('space-right'); - - var overlays = this.overlays; - - /* 修复 resource 数组中出现 null 的 bug - * @Author zhangbobell - * @date 2016-01-15 - */ - var resource = node.getData("resource").filter(function(ele) { - return ele !== null; - }); - if (resource.length === 0) { - return; - } - var minder = node.getMinder(); - var i, overlay, x; - - x = 0; - for (i = 0; i < resource.length; i++) { - - x += spaceRight; - - overlay = overlays[i]; - if (!overlay) { - overlay = new ResourceOverlay(); - overlays.push(overlay); - container.addShape(overlay); - } - overlay.setVisible(true); - overlay.setValue(resource[i], minder.getResourceColor(resource[i])); - overlay.setTranslate(x, -1); - - x += overlay.width; - } - - while ((overlay = overlays[i++])) overlay.setVisible(false); - - container.setTranslate(box.right, 0); - - return new kity.Box({ - x: box.right, - y: Math.round(-overlays[0].height / 2), - width: x, - height: overlays[0].height - }); - } - }); - - return { - commands: { - 'resource': ResourceCommand - }, - - renderers: { - right: ResourceRenderer - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/select.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/select.js deleted file mode 100644 index 28c6a9ff..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/select.js +++ /dev/null @@ -1,184 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - Module.register('Select', function() { - var minder = this; - var rc = minder.getRenderContainer(); - - // 在实例上渲染框选矩形、计算框选范围的对象 - var marqueeActivator = (function() { - - // 记录选区的开始位置(mousedown的位置) - var startPosition = null; - - // 选区的图形 - var marqueeShape = new kity.Path(); - - // 标记是否已经启动框选状态 - // 并不是 mousedown 发生之后就启动框选状态,而是检测到移动了一定的距离(MARQUEE_MODE_THRESHOLD)之后 - var marqueeMode = false; - var MARQUEE_MODE_THRESHOLD = 10; - - return { - selectStart: function(e) { - // 只接受左键 - if (e.originEvent.button || e.originEvent.altKey) return; - - // 清理不正确状态 - if (startPosition) { - return this.selectEnd(); - } - - startPosition = e.getPosition(rc).round(); - }, - selectMove: function(e) { - if (minder.getStatus() == 'textedit') { - return; - } - if (!startPosition) return; - - var p1 = startPosition, - p2 = e.getPosition(rc); - - // 检测是否要进入选区模式 - if (!marqueeMode) { - // 距离没达到阈值,退出 - if (kity.Vector.fromPoints(p1, p2).length() < MARQUEE_MODE_THRESHOLD) { - return; - } - // 已经达到阈值,记录下来并且重置选区形状 - marqueeMode = true; - rc.addShape(marqueeShape); - marqueeShape - .fill(minder.getStyle('marquee-background')) - .stroke(minder.getStyle('marquee-stroke')).setOpacity(0.8).getDrawer().clear(); - } - - var marquee = new kity.Box(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y), - selectedNodes = []; - - // 使其犀利 - marquee.left = Math.round(marquee.left); - marquee.top = Math.round(marquee.top); - marquee.right = Math.round(marquee.right); - marquee.bottom = Math.round(marquee.bottom); - - // 选区形状更新 - marqueeShape.getDrawer().pipe(function() { - this.clear(); - this.moveTo(marquee.left, marquee.top); - this.lineTo(marquee.right, marquee.top); - this.lineTo(marquee.right, marquee.bottom); - this.lineTo(marquee.left, marquee.bottom); - this.close(); - }); - - // 计算选中范围 - minder.getRoot().traverse(function(node) { - var renderBox = node.getLayoutBox(); - if (!renderBox.intersect(marquee).isEmpty()) { - selectedNodes.push(node); - } - }); - - // 应用选中范围 - minder.select(selectedNodes, true); - - // 清除多余的东西 - window.getSelection().removeAllRanges(); - }, - selectEnd: function(e) { - if (startPosition) { - startPosition = null; - } - if (marqueeMode) { - marqueeShape.fadeOut(200, 'ease', 0, function() { - if (marqueeShape.remove) marqueeShape.remove(); - }); - marqueeMode = false; - } - } - }; - })(); - - var lastDownNode = null, - lastDownPosition = null; - return { - 'init': function() { - window.addEventListener('mouseup', function() { - marqueeActivator.selectEnd(); - }); - }, - 'events': { - 'mousedown': function(e) { - - var downNode = e.getTargetNode(); - - // 没有点中节点: - // 清除选中状态,并且标记选区开始位置 - if (!downNode) { - this.removeAllSelectedNodes(); - marqueeActivator.selectStart(e); - - this.setStatus('normal'); - } - - // 点中了节点,并且按了 shift 键: - // 被点中的节点切换选中状态 - else if (e.isShortcutKey('Ctrl')) { - this.toggleSelect(downNode); - } - - // 点中的节点没有被选择: - // 单选点中的节点 - else if (!downNode.isSelected()) { - this.select(downNode, true); - } - - // 点中的节点被选中了,并且不是单选: - // 完成整个点击之后需要使其变为单选。 - // 不能马上变为单选,因为可能是需要拖动选中的多个节点 - else if (!this.isSingleSelect()) { - lastDownNode = downNode; - lastDownPosition = e.getPosition(); - } - }, - 'mousemove': marqueeActivator.selectMove, - 'mouseup': function(e) { - var upNode = e.getTargetNode(); - - // 如果 mouseup 发生在 lastDownNode 外,是无需理会的 - if (upNode && upNode == lastDownNode) { - var upPosition = e.getPosition(); - var movement = kity.Vector.fromPoints(lastDownPosition, upPosition); - if (movement.length() < 1) this.select(lastDownNode, true); - lastDownNode = null; - } - - // 清理一下选择状态 - marqueeActivator.selectEnd(e); - }, - //全选操作 - 'normal.keydown': function(e) { - - if (e.isShortcutKey('ctrl+a')) { - var selectedNodes = []; - - this.getRoot().traverse(function(node) { - selectedNodes.push(node); - }); - this.select(selectedNodes, true); - e.preventDefault(); - } - } - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/style.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/style.js deleted file mode 100644 index 02e21eb3..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/style.js +++ /dev/null @@ -1,114 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - Module.register('StyleModule', function() { - var styleNames = ['font-size', 'font-family', 'font-weight', 'font-style', 'background', 'color']; - var styleClipBoard = null; - - function hasStyle(node) { - var data = node.getData(); - for (var i = 0; i < styleNames.length; i++) { - if (styleNames[i] in data) return true; - } - } - - return { - 'commands': { - /** - * @command CopyStyle - * @description 拷贝选中节点的当前样式,包括字体、字号、粗体、斜体、背景色、字体色 - * @state - * 0: 当前有选中的节点 - * -1: 当前没有选中的节点 - */ - 'copystyle': kity.createClass('CopyStyleCommand', { - base: Command, - - execute: function(minder) { - var node = minder.getSelectedNode(); - var nodeData = node.getData(); - styleClipBoard = {}; - styleNames.forEach(function(name) { - if (name in nodeData) styleClipBoard[name] = nodeData[name]; - else { - styleClipBoard[name] = null; - delete styleClipBoard[name]; - } - }); - return styleClipBoard; - }, - - queryState: function(minder) { - var nodes = minder.getSelectedNodes(); - if (nodes.length !== 1) return -1; - return hasStyle(nodes[0]) ? 0 : -1; - } - }), - - /** - * @command PasteStyle - * @description 粘贴已拷贝的样式到选中的节点上,包括字体、字号、粗体、斜体、背景色、字体色 - * @state - * 0: 当前有选中的节点,并且已经有复制的样式 - * -1: 当前没有选中的节点,或者没有复制的样式 - */ - 'pastestyle': kity.createClass('PastStyleCommand', { - base: Command, - - execute: function(minder) { - minder.getSelectedNodes().forEach(function(node) { - for (var name in styleClipBoard) { - if (styleClipBoard.hasOwnProperty(name)) - node.setData(name, styleClipBoard[name]); - } - }); - minder.renderNodeBatch(minder.getSelectedNodes()); - minder.layout(300); - return styleClipBoard; - }, - - queryState: function(minder) { - return (styleClipBoard && minder.getSelectedNodes().length) ? 0 : -1; - } - }), - - /** - * @command ClearStyle - * @description 移除选中节点的样式,包括字体、字号、粗体、斜体、背景色、字体色 - * @state - * 0: 当前有选中的节点,并且至少有一个设置了至少一种样式 - * -1: 其它情况 - */ - 'clearstyle': kity.createClass('ClearStyleCommand', { - base: Command, - execute: function(minder) { - minder.getSelectedNodes().forEach(function(node) { - styleNames.forEach(function(name) { - node.setData(name); - }); - }); - minder.renderNodeBatch(minder.getSelectedNodes()); - minder.layout(300); - return styleClipBoard; - }, - - queryState: function(minder) { - var nodes = minder.getSelectedNodes(); - if (!nodes.length) return -1; - for (var i = 0; i < nodes.length; i++) { - if (hasStyle(nodes[i])) return 0; - } - return -1; - } - }) - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/text.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/text.js deleted file mode 100644 index 3a0f1cff..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/text.js +++ /dev/null @@ -1,288 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - /** - * 针对不同系统、不同浏览器、不同字体做居中兼容性处理 - * 暂时未增加Linux的处理 - */ - var FONT_ADJUST = { - 'safari': { - '微软雅黑,Microsoft YaHei': -0.17, - '楷体,楷体_GB2312,SimKai': -0.1, - '隶书, SimLi': -0.1, - 'comic sans ms': -0.23, - 'impact,chicago': -0.15, - 'times new roman': -0.1, - 'arial black,avant garde': -0.17, - 'default': 0 - }, - 'ie': { - 10: { - '微软雅黑,Microsoft YaHei': -0.17, - 'comic sans ms': -0.17, - 'impact,chicago': -0.08, - 'times new roman': 0.04, - 'arial black,avant garde': -0.17, - 'default': -0.15 - }, - 11: { - '微软雅黑,Microsoft YaHei': -0.17, - 'arial,helvetica,sans-serif': -0.17, - 'comic sans ms': -0.17, - 'impact,chicago': -0.08, - 'times new roman': 0.04, - 'sans-serif': -0.16, - 'arial black,avant garde': -0.17, - 'default': -0.15 - } - }, - 'edge': { - '微软雅黑,Microsoft YaHei': -0.15, - 'arial,helvetica,sans-serif': -0.17, - 'comic sans ms': -0.17, - 'impact,chicago': -0.08, - 'sans-serif': -0.16, - 'arial black,avant garde': -0.17, - 'default': -0.15 - }, - 'sg': { - '微软雅黑,Microsoft YaHei': -0.15, - 'arial,helvetica,sans-serif': -0.05, - 'comic sans ms': -0.22, - 'impact,chicago': -0.16, - 'times new roman': -0.03, - 'arial black,avant garde': -0.22, - 'default': -0.15 - }, - 'chrome': { - 'Mac': { - 'andale mono': -0.05, - 'comic sans ms': -0.3, - 'impact,chicago': -0.13, - 'times new roman': -0.1, - 'arial black,avant garde': -0.17, - 'default': 0 - }, - 'Win': { - '微软雅黑,Microsoft YaHei': -0.15, - 'arial,helvetica,sans-serif': -0.02, - 'arial black,avant garde': -0.2, - 'comic sans ms': -0.2, - 'impact,chicago': -0.12, - 'times new roman': -0.02, - 'default': -0.15 - }, - 'Lux': { - 'andale mono': -0.05, - 'comic sans ms': -0.3, - 'impact,chicago': -0.13, - 'times new roman': -0.1, - 'arial black,avant garde': -0.17, - 'default': 0 - } - }, - 'firefox': { - 'Mac': { - '微软雅黑,Microsoft YaHei': -0.2, - '宋体,SimSun': 0.05, - 'comic sans ms': -0.2, - 'impact,chicago': -0.15, - 'arial black,avant garde': -0.17, - 'times new roman': -0.1, - 'default': 0.05 - }, - 'Win': { - '微软雅黑,Microsoft YaHei': -0.16, - 'andale mono': -0.17, - 'arial,helvetica,sans-serif': -0.17, - 'comic sans ms': -0.22, - 'impact,chicago': -0.23, - 'times new roman': -0.22, - 'sans-serif': -0.22, - 'arial black,avant garde': -0.17, - 'default': -0.16 - }, - 'Lux': { - "宋体,SimSun": -0.2, - "微软雅黑,Microsoft YaHei": -0.2, - "黑体, SimHei": -0.2, - "隶书, SimLi": -0.2, - "楷体,楷体_GB2312,SimKai": -0.2, - "andale mono": -0.2, - "arial,helvetica,sans-serif": -0.2, - "comic sans ms": -0.2, - "impact,chicago": -0.2, - "times new roman": -0.2, - "sans-serif": -0.2, - "arial black,avant garde": -0.2, - "default": -0.16 - } - }, - }; - - var TextRenderer = kity.createClass('TextRenderer', { - base: Renderer, - - create: function() { - return new kity.Group().setId(utils.uuid('node_text')); - }, - - update: function(textGroup, node) { - - function getDataOrStyle(name) { - return node.getData(name) || node.getStyle(name); - } - - var nodeText = node.getText(); - var textArr = nodeText ? nodeText.split('\n') : [' ']; - - var lineHeight = node.getStyle('line-height'); - - var fontSize = getDataOrStyle('font-size'); - var fontFamily = getDataOrStyle('font-family') || 'default'; - - var height = (lineHeight * fontSize) * textArr.length - (lineHeight - 1) * fontSize; - var yStart = -height / 2; - var Browser = kity.Browser; - var adjust; - - if (Browser.chrome || Browser.opera || Browser.bd ||Browser.lb === "chrome") { - adjust = FONT_ADJUST['chrome'][Browser.platform][fontFamily]; - } else if (Browser.gecko) { - adjust = FONT_ADJUST['firefox'][Browser.platform][fontFamily]; - } else if (Browser.sg) { - adjust = FONT_ADJUST['sg'][fontFamily]; - } else if (Browser.safari) { - adjust = FONT_ADJUST['safari'][fontFamily]; - } else if (Browser.ie) { - adjust = FONT_ADJUST['ie'][Browser.version][fontFamily]; - } else if (Browser.edge) { - adjust = FONT_ADJUST['edge'][fontFamily]; - } else if (Browser.lb) { - // 猎豹浏览器的ie内核兼容性模式下 - adjust = 0.9; - } - - textGroup.setTranslate(0, (adjust || 0) * fontSize); - - var rBox = new kity.Box(), - r = Math.round; - - this.setTextStyle(node, textGroup); - - var textLength = textArr.length; - - var textGroupLength = textGroup.getItems().length; - - var i, ci, textShape, text; - - if (textLength < textGroupLength) { - for (i = textLength, ci; ci = textGroup.getItem(i);) { - textGroup.removeItem(i); - } - } else if (textLength > textGroupLength) { - var growth = textLength - textGroupLength; - while (growth--) { - textShape = new kity.Text() - .setAttr('text-rendering', 'inherit'); - if (kity.Browser.ie || kity.Browser.edge) { - textShape.setVerticalAlign('top'); - } else { - textShape.setAttr('dominant-baseline', 'text-before-edge'); - } - textGroup.addItem(textShape); - } - } - - for (i = 0, text, textShape; - (text = textArr[i], textShape = textGroup.getItem(i)); i++) { - textShape.setContent(text); - if (kity.Browser.ie || kity.Browser.edge) { - textShape.fixPosition(); - } - } - - this.setTextStyle(node, textGroup); - - var textHash = node.getText() + - ['font-size', 'font-name', 'font-weight', 'font-style'].map(getDataOrStyle).join('/'); - - if (node._currentTextHash == textHash && node._currentTextGroupBox) return node._currentTextGroupBox; - - node._currentTextHash = textHash; - - return function() { - textGroup.eachItem(function(i, textShape) { - var y = yStart + i * fontSize * lineHeight; - - textShape.setY(y); - var bbox = textShape.getBoundaryBox(); - rBox = rBox.merge(new kity.Box(0, y, bbox.height && bbox.width || 1, fontSize)); - }); - - var nBox = new kity.Box(r(rBox.x), r(rBox.y), r(rBox.width), r(rBox.height)); - - node._currentTextGroupBox = nBox; - return nBox; - }; - - }, - - setTextStyle: function(node, text) { - var hooks = TextRenderer._styleHooks; - hooks.forEach(function(hook) { - hook(node, text); - }); - } - }); - - var TextCommand = kity.createClass({ - base: Command, - execute: function(minder, text) { - var node = minder.getSelectedNode(); - if (node) { - node.setText(text); - node.render(); - minder.layout(); - } - }, - queryState: function(minder) { - return minder.getSelectedNodes().length == 1 ? 0 : -1; - }, - queryValue: function(minder) { - var node = minder.getSelectedNode(); - return node ? node.getText() : null; - } - }); - - utils.extend(TextRenderer, { - _styleHooks: [], - - registerStyleHook: function(fn) { - TextRenderer._styleHooks.push(fn); - } - }); - - kity.extendClass(MinderNode, { - getTextGroup: function() { - return this.getRenderer('TextRenderer').getRenderShape(); - } - }); - - Module.register('text', { - 'commands': { - 'text': TextCommand - }, - 'renderers': { - center: TextRenderer - } - }); - - module.exports = TextRenderer; -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/view.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/view.js deleted file mode 100644 index 7f4f823f..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/view.js +++ /dev/null @@ -1,404 +0,0 @@ -define(function (require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - var ViewDragger = kity.createClass('ViewDragger', { - constructor: function (minder) { - this._minder = minder; - this._enabled = false; - this._bind(); - var me = this; - this._minder.getViewDragger = function () { - return me; - }; - this.setEnabled(false); - }, - - isEnabled: function () { - return this._enabled; - }, - - setEnabled: function (value) { - var paper = this._minder.getPaper(); - paper.setStyle('cursor', value ? 'pointer' : 'default'); - paper.setStyle('cursor', value ? '-webkit-grab' : 'default'); - this._enabled = value; - }, - timeline: function () { - return this._moveTimeline; - }, - - move: function (offset, duration) { - var minder = this._minder; - - var targetPosition = this.getMovement().offset(offset); - - this.moveTo(targetPosition, duration); - }, - - moveTo: function (position, duration) { - if (duration) { - var dragger = this; - - if (this._moveTimeline) this._moveTimeline.stop(); - - this._moveTimeline = this._minder - .getRenderContainer() - .animate( - new kity.Animator(this.getMovement(), position, function (target, value) { - dragger.moveTo(value); - }), - duration, - 'easeOutCubic' - ) - .timeline(); - - this._moveTimeline.on('finish', function () { - dragger._moveTimeline = null; - }); - - return this; - } - - this._minder.getRenderContainer().setTranslate(position.round()); - this._minder.fire('viewchange'); - }, - - getMovement: function () { - var translate = this._minder.getRenderContainer().transform.translate; - return translate ? translate[0] : new kity.Point(); - }, - - getView: function () { - var minder = this._minder; - var c = minder._lastClientSize || { - width: minder.getRenderTarget().clientWidth, - height: minder.getRenderTarget().clientHeight, - }; - var m = this.getMovement(); - var box = new kity.Box(0, 0, c.width, c.height); - var viewMatrix = minder.getPaper().getViewPortMatrix(); - return viewMatrix.inverse().translate(-m.x, -m.y).transformBox(box); - }, - - _bind: function () { - var dragger = this, - isTempDrag = false, - lastPosition = null, - currentPosition = null; - - function dragEnd(e) { - if (!lastPosition) return; - - lastPosition = null; - - e.stopPropagation(); - - // 临时拖动需要还原状态 - if (isTempDrag) { - dragger.setEnabled(false); - isTempDrag = false; - if (dragger._minder.getStatus() == 'hand') dragger._minder.rollbackStatus(); - } - var paper = dragger._minder.getPaper(); - paper.setStyle('cursor', dragger._minder.getStatus() == 'hand' ? '-webkit-grab' : 'default'); - - dragger._minder.fire('viewchanged'); - } - - this._minder - .on( - 'normal.mousedown normal.touchstart ' + - 'inputready.mousedown inputready.touchstart ' + - 'readonly.mousedown readonly.touchstart', - function (e) { - if (e.originEvent.button == 2) { - e.originEvent.preventDefault(); // 阻止中键拉动 - } - // 点击未选中的根节点临时开启 - if (e.getTargetNode() == this.getRoot() || e.originEvent.button == 2 || e.originEvent.altKey) { - lastPosition = e.getPosition('view'); - isTempDrag = true; - } - } - ) - - .on( - 'normal.mousemove normal.touchmove ' + - 'readonly.mousemove readonly.touchmove ' + - 'inputready.mousemove inputready.touchmove', - function (e) { - if (e.type == 'touchmove') { - e.preventDefault(); // 阻止浏览器的后退事件 - } - if (!isTempDrag) return; - var offset = kity.Vector.fromPoints(lastPosition, e.getPosition('view')); - if (offset.length() > 10) { - this.setStatus('hand', true); - var paper = dragger._minder.getPaper(); - paper.setStyle('cursor', '-webkit-grabbing'); - } - } - ) - - .on('hand.beforemousedown hand.beforetouchstart', function (e) { - // 已经被用户打开拖放模式 - if (dragger.isEnabled()) { - lastPosition = e.getPosition('view'); - e.stopPropagation(); - var paper = dragger._minder.getPaper(); - paper.setStyle('cursor', '-webkit-grabbing'); - } - }) - - .on('hand.beforemousemove hand.beforetouchmove', function (e) { - if (lastPosition) { - currentPosition = e.getPosition('view'); - - // 当前偏移加上历史偏移 - var offset = kity.Vector.fromPoints(lastPosition, currentPosition); - dragger.move(offset); - e.stopPropagation(); - e.preventDefault(); - e.originEvent.preventDefault(); - lastPosition = currentPosition; - } - }) - - .on('mouseup touchend', dragEnd); - - window.addEventListener('mouseup', dragEnd); - this._minder.on('contextmenu', function (e) { - e.preventDefault(); - }); - }, - }); - - Module.register('View', function () { - var km = this; - - /** - * @command Hand - * @description 切换抓手状态,抓手状态下,鼠标拖动将拖动视野,而不是创建选区 - * @state - * 0: 当前不是抓手状态 - * 1: 当前是抓手状态 - */ - var ToggleHandCommand = kity.createClass('ToggleHandCommand', { - base: Command, - execute: function (minder) { - if (minder.getStatus() != 'hand') { - minder.setStatus('hand', true); - } else { - minder.rollbackStatus(); - } - this.setContentChanged(false); - }, - queryState: function (minder) { - return minder.getStatus() == 'hand' ? 1 : 0; - }, - enableReadOnly: true, - }); - - /** - * @command Camera - * @description 设置当前视野的中心位置到某个节点上 - * @param {kityminder.MinderNode} focusNode 要定位的节点 - * @param {number} duration 设置视野移动的动画时长(单位 ms),设置为 0 不使用动画 - * @state - * 0: 始终可用 - */ - var CameraCommand = kity.createClass('CameraCommand', { - base: Command, - execute: function (km, focusNode) { - const dragger = km._viewDragger; - const duration = km.getOption('viewAnimationDuration'); - let dx = 0; - let dy = 0; - - // if (!focusNode || focusNode.type === 'root') { - // // 默认居中 - // const parentNode = km.getPaper().node; - // const shapeNode = km.getRoot().rc.container.node; - // const { width: pw, height: ph, x: px, y: py } = parentNode.getBoundingClientRect(); - // const { width: sw, height: sh, x, y } = shapeNode.getBBox(); - // dx = pw / 2 - x - sw / 2; - // dy = ph / 2 - y - sh / 2; - // dragger.moveTo(new kity.Point(dx, dy), duration); - // } else { - focusNode = focusNode || km.getRoot(); - var viewport = km.getPaper().getViewPort(); - var offset = focusNode.getRenderContainer().getRenderBox('view'); - dx = viewport.center.x - offset.x - offset.width / 2; - dy = viewport.center.y - offset.y; - dragger.move(new kity.Point(dx, dy), duration); - // } - - this.setContentChanged(false); - }, - enableReadOnly: true, - }); - - /** - * @command Move - * @description 指定方向移动当前视野 - * @param {string} dir 移动方向 - * 取值为 'left',视野向左移动一半 - * 取值为 'right',视野向右移动一半 - * 取值为 'up',视野向上移动一半 - * 取值为 'down',视野向下移动一半 - * @param {number} duration 视野移动的动画时长(单位 ms),设置为 0 不使用动画 - * @state - * 0: 始终可用 - */ - var MoveCommand = kity.createClass('MoveCommand', { - base: Command, - - execute: function (km, dir) { - var dragger = km._viewDragger; - var size = km._lastClientSize; - var duration = km.getOption('viewAnimationDuration'); - switch (dir) { - case 'up': - dragger.move(new kity.Point(0, size.height / 2), duration); - break; - case 'down': - dragger.move(new kity.Point(0, -size.height / 2), duration); - break; - case 'left': - dragger.move(new kity.Point(size.width / 2, 0), duration); - break; - case 'right': - dragger.move(new kity.Point(-size.width / 2, 0), duration); - break; - } - }, - - enableReadOnly: true, - }); - - return { - init: function () { - this._viewDragger = new ViewDragger(this); - }, - commands: { - hand: ToggleHandCommand, - camera: CameraCommand, - move: MoveCommand, - }, - events: { - 'statuschange': function (e) { - this._viewDragger.setEnabled(e.currentStatus == 'hand'); - }, - 'mousewheel': function (e) { - var dx, dy; - e = e.originEvent; - if (e.ctrlKey || e.shiftKey) return; - if ('wheelDeltaX' in e) { - dx = e.wheelDeltaX || 0; - dy = e.wheelDeltaY || 0; - } else { - dx = 0; - dy = e.wheelDelta; - } - - this._viewDragger.move({ - x: dx / 2.5, - y: dy / 2.5, - }); - - var me = this; - clearTimeout(this._mousewheeltimer); - this._mousewheeltimer = setTimeout(function () { - me.fire('viewchanged'); - }, 100); - - e.preventDefault(); - }, - 'normal.dblclick readonly.dblclick': function (e) { - if (e.kityEvent.targetShape instanceof kity.Paper) { - this.execCommand('camera', this.getRoot(), 800); - } - }, - 'paperrender finishInitHook': function () { - if (!this.getRenderTarget()) { - return; - } - this.execCommand('camera', null, 0); - this._lastClientSize = { - width: this.getRenderTarget().clientWidth, - height: this.getRenderTarget().clientHeight, - }; - }, - 'resize': function (e) { - var a = { - width: this.getRenderTarget().clientWidth, - height: this.getRenderTarget().clientHeight, - }, - b = this._lastClientSize; - this._viewDragger.move(new kity.Point(((a.width - b.width) / 2) | 0, ((a.height - b.height) / 2) | 0)); - this._lastClientSize = a; - }, - 'selectionchange layoutallfinish': function (e) { - var selected = this.getSelectedNode(); - var minder = this; - - /* - * Added by zhangbobell 2015.9.9 - * windows 10 的 edge 浏览器在全部动画停止后,优先级图标不显示 text, - * 因此再次触发一次 render 事件,让浏览器重绘 - * */ - if (kity.Browser.edge) { - this.fire('paperrender'); - } - if (!selected) return; - - var dragger = this._viewDragger; - var timeline = dragger.timeline(); - - /* - * Added by zhangbobell 2015.09.25 - * 如果之前有动画,那么就先暂时返回,等之前动画结束之后再次执行本函数 - * 以防止 view 动画变动了位置,导致本函数执行的时候位置计算不对 - * - * fixed bug : 初始化的时候中心节点位置不固定(有的时候在左上角,有的时候在中心) - * */ - if (timeline) { - timeline.on('finish', function () { - minder.fire('selectionchange'); - }); - - return; - } - - var view = dragger.getView(); - var focus = selected.getLayoutBox(); - var space = 50; - var dx = 0, - dy = 0; - - if (focus.right > view.right) { - dx += view.right - focus.right - space; - } else if (focus.left < view.left) { - dx += view.left - focus.left + space; - } - - if (focus.bottom > view.bottom) { - dy += view.bottom - focus.bottom - space; - } - if (focus.top < view.top) { - dy += view.top - focus.top + space; - } - - if (dx || dy) dragger.move(new kity.Point(dx, dy), 100); - }, - }, - }; - }); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/zoom.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/zoom.js deleted file mode 100644 index 9a784f97..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/module/zoom.js +++ /dev/null @@ -1,200 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var utils = require('../core/utils'); - - var Minder = require('../core/minder'); - var MinderNode = require('../core/node'); - var Command = require('../core/command'); - var Module = require('../core/module'); - var Renderer = require('../core/render'); - - Module.register('Zoom', function() { - var me = this; - - var timeline; - - function setTextRendering() { - var value = me._zoomValue >= 100 ? 'optimize-speed' : 'geometricPrecision'; - me.getRenderContainer().setAttr('text-rendering', value); - } - - function fixPaperCTM(paper) { - var node = paper.shapeNode; - var ctm = node.getCTM(); - var matrix = new kity.Matrix(ctm.a, ctm.b, ctm.c, ctm.d, (ctm.e | 0) + 0.5, (ctm.f | 0) + 0.5); - node.setAttribute('transform', 'matrix(' + matrix.toString() + ')'); - } - - kity.extendClass(Minder, { - zoom: function(value) { - var paper = this.getPaper(); - var viewport = paper.getViewPort(); - viewport.zoom = value / 100; - viewport.center = { - x: viewport.center.x, - y: viewport.center.y - }; - paper.setViewPort(viewport); - if (value == 100) fixPaperCTM(paper); - }, - getZoomValue: function() { - return this._zoomValue; - } - }); - - function zoomMinder(minder, value) { - var paper = minder.getPaper(); - var viewport = paper.getViewPort(); - - if (!value) return; - - setTextRendering(); - - var duration = minder.getOption('zoomAnimationDuration'); - if (minder.getRoot().getComplex() > 200 || !duration) { - minder._zoomValue = value; - minder.zoom(value); - minder.fire('viewchange'); - } else { - var animator = new kity.Animator({ - beginValue: minder._zoomValue, - finishValue: value, - setter: function(target, value) { - target.zoom(value); - } - }); - minder._zoomValue = value; - if (timeline) { - timeline.pause(); - } - timeline = animator.start(minder, duration, 'easeInOutSine'); - timeline.on('finish', function() { - minder.fire('viewchange'); - }); - } - minder.fire('zoom', { - zoom: value - }); - } - - /** - * @command Zoom - * @description 缩放当前的视野到一定的比例(百分比) - * @param {number} value 设置的比例,取值 100 则为原尺寸 - * @state - * 0: 始终可用 - */ - var ZoomCommand = kity.createClass('Zoom', { - base: Command, - execute: zoomMinder, - queryValue: function(minder) { - return minder._zoomValue; - } - }); - - /** - * @command ZoomIn - * @description 放大当前的视野到下一个比例等级(百分比) - * @shortcut = - * @state - * 0: 如果当前脑图的配置中还有下一个比例等级 - * -1: 其它情况 - */ - var ZoomInCommand = kity.createClass('ZoomInCommand', { - base: Command, - execute: function(minder) { - zoomMinder(minder, this.nextValue(minder)); - }, - queryState: function(minder) { - return +!this.nextValue(minder); - }, - nextValue: function(minder) { - var stack = minder.getOption('zoom'), - i; - for (i = 0; i < stack.length; i++) { - if (stack[i] > minder._zoomValue) return stack[i]; - } - return 0; - }, - enableReadOnly: true - }); - - /** - * @command ZoomOut - * @description 缩小当前的视野到上一个比例等级(百分比) - * @shortcut - - * @state - * 0: 如果当前脑图的配置中还有上一个比例等级 - * -1: 其它情况 - */ - var ZoomOutCommand = kity.createClass('ZoomOutCommand', { - base: Command, - execute: function(minder) { - zoomMinder(minder, this.nextValue(minder)); - }, - queryState: function(minder) { - return +!this.nextValue(minder); - }, - nextValue: function(minder) { - var stack = minder.getOption('zoom'), - i; - for (i = stack.length - 1; i >= 0; i--) { - if (stack[i] < minder._zoomValue) return stack[i]; - } - return 0; - }, - enableReadOnly: true - }); - - return { - init: function() { - this._zoomValue = 100; - this.setDefaultOptions({ - zoom: [10, 20, 50, 100, 200] - }); - setTextRendering(); - }, - commands: { - 'zoomin': ZoomInCommand, - 'zoomout': ZoomOutCommand, - 'zoom': ZoomCommand - }, - events: { - 'normal.mousewheel readonly.mousewheel': function(e) { - if (!e.originEvent.ctrlKey && !e.originEvent.metaKey) return; - - var delta = e.originEvent.wheelDelta; - var me = this; - - if (!kity.Browser.mac) { - delta = -delta; - } - - // 稀释 - if (Math.abs(delta) > 100) { - clearTimeout(this._wheelZoomTimeout); - } else { - return; - } - - this._wheelZoomTimeout = setTimeout(function() { - var value; - var lastValue = me.getPaper()._zoom || 1; - if (delta < 0) { - me.execCommand('zoomin'); - } else if (delta > 0) { - me.execCommand('zoomout'); - } - }, 100); - - e.originEvent.preventDefault(); - } - }, - - commandShortcutKeys: { - 'zoomin': 'ctrl+=', - 'zoomout': 'ctrl+-' - } - }; - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/json.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/json.js deleted file mode 100644 index 2f9657dc..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/json.js +++ /dev/null @@ -1,18 +0,0 @@ -define(function(require, exports, module) { - var data = require('../core/data'); - - data.registerProtocol('json', module.exports = { - fileDescription: 'KityMinder 格式', - fileExtension: '.km', - dataType: 'text', - mineType: 'application/json', - - encode: function(json) { - return JSON.stringify(json); - }, - - decode: function(local) { - return JSON.parse(local); - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/markdown.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/markdown.js deleted file mode 100644 index 3029f299..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/markdown.js +++ /dev/null @@ -1,158 +0,0 @@ -define(function(require, exports, module) { - var data = require('../core/data'); - var LINE_ENDING_SPLITER = /\r\n|\r|\n/; - var EMPTY_LINE = ''; - var NOTE_MARK_START = ''; - var NOTE_MARK_CLOSE = ''; - - function encode(json) { - - return _build(json, 1).join('\n'); - } - - function _build(node, level) { - var lines = []; - - level = level || 1; - - var sharps = _generateHeaderSharp(level); - lines.push(sharps + ' ' + node.data.text); - lines.push(EMPTY_LINE); - - var note = node.data.note; - if (note) { - var hasSharp = /^#/.test(note); - if (hasSharp) { - lines.push(NOTE_MARK_START); - note = note.replace(/^#+/gm, function($0) { - return sharps + $0; - }); - } - lines.push(note); - if (hasSharp) { - lines.push(NOTE_MARK_CLOSE); - } - lines.push(EMPTY_LINE); - } - - if (node.children) node.children.forEach(function(child) { - lines = lines.concat(_build(child, level + 1)); - }); - - return lines; - } - - function _generateHeaderSharp(level) { - var sharps = ''; - while (level--) sharps += '#'; - return sharps; - } - - function decode(markdown) { - - var json, - parentMap = {}, - lines, line, lineInfo, level, node, parent, noteProgress, codeBlock; - - // 一级标题转换 `{title}\n===` => `# {title}` - markdown = markdown.replace(/^(.+)\n={3,}/, function($0, $1) { - return '# ' + $1; - }); - - lines = markdown.split(LINE_ENDING_SPLITER); - - // 按行分析 - for (var i = 0; i < lines.length; i++) { - line = lines[i]; - - lineInfo = _resolveLine(line); - - // 备注标记处理 - if (lineInfo.noteClose) { - noteProgress = false; - continue; - } else if (lineInfo.noteStart) { - noteProgress = true; - continue; - } - - // 代码块处理 - codeBlock = lineInfo.codeBlock ? !codeBlock : codeBlock; - - // 备注条件:备注标签中,非标题定义,或标题越位 - if (noteProgress || codeBlock || !lineInfo.level || lineInfo.level > level + 1) { - if (node) _pushNote(node, line); - continue; - } - - // 标题处理 - level = lineInfo.level; - node = _initNode(lineInfo.content, parentMap[level - 1]); - parentMap[level] = node; - } - - _cleanUp(parentMap[1]); - return parentMap[1]; - } - - function _initNode(text, parent) { - var node = { - data: { - text: text, - note: '' - } - }; - if (parent) { - if (parent.children) parent.children.push(node); - else parent.children = [node]; - } - return node; - } - - function _pushNote(node, line) { - node.data.note += line + '\n'; - } - - function _isEmpty(line) { - return !/\S/.test(line); - } - - function _resolveLine(line) { - var match = /^(#+)?\s*(.*)$/.exec(line); - return { - level: match[1] && match[1].length || null, - content: match[2], - noteStart: line == NOTE_MARK_START, - noteClose: line == NOTE_MARK_CLOSE, - codeBlock: /^\s*```/.test(line) - }; - } - - function _cleanUp(node) { - if (!/\S/.test(node.data.note)) { - node.data.note = null; - delete node.data.note; - } else { - var notes = node.data.note.split('\n'); - while (notes.length && !/\S/.test(notes[0])) notes.shift(); - while (notes.length && !/\S/.test(notes[notes.length - 1])) notes.pop(); - node.data.note = notes.join('\n'); - } - if (node.children) node.children.forEach(_cleanUp); - } - - data.registerProtocol('markdown', module.exports = { - fileDescription: 'Markdown/GFM 格式', - fileExtension: '.md', - mineType: 'text/markdown', - dataType: 'text', - - encode: function(json) { - return encode(json.root); - }, - - decode: function(markdown) { - return decode(markdown); - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/png.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/png.js deleted file mode 100644 index 22096c8d..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/png.js +++ /dev/null @@ -1,273 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var data = require('../core/data'); - var Promise = require('../core/promise'); - - var DomURL = window.URL || window.webkitURL || window; - - function loadImage(info, callback) { - return new Promise(function(resolve, reject) { - var image = document.createElement("img"); - image.onload = function() { - resolve({ - element: this, - x: info.x, - y: info.y, - width: info.width, - height: info.height - }); - }; - image.onerror = function(err) { - reject(err); - }; - - image.crossOrigin = 'anonymous'; - image.src = info.url; - }); - } - - /** - * xhrLoadImage: 通过 xhr 加载保存在 BOS 上的图片 - * @note: BOS 上的 CORS 策略是取 headers 里面的 Origin 字段进行判断 - * 而通过 image 的 src 的方式是无法传递 origin 的,因此需要通过 xhr 进行 - */ - function xhrLoadImage(info, callback) { - return Promise(function (resolve, reject) { - var xmlHttp = new XMLHttpRequest(); - - xmlHttp.open('GET', info.url + '?_=' + Date.now(), true); - xmlHttp.responseType = 'blob'; - xmlHttp.onreadystatechange = function () { - if (xmlHttp.readyState === 4 && xmlHttp.status === 200) { - var blob = xmlHttp.response; - - var image = document.createElement('img'); - - image.src = DomURL.createObjectURL(blob); - image.onload = function () { - DomURL.revokeObjectURL(image.src); - resolve({ - element: image, - x: info.x, - y: info.y, - width: info.width, - height: info.height - }); - }; - } - }; - - xmlHttp.send(); - }); - } - - function getSVGInfo(minder) { - var paper = minder.getPaper(), - paperTransform, - domContainer = paper.container, - svgXml, - svgContainer, - svgDom, - - renderContainer = minder.getRenderContainer(), - renderBox = renderContainer.getRenderBox(), - width = renderBox.width + 1, - height = renderBox.height + 1, - - blob, svgUrl, img; - - // 保存原始变换,并且移动到合适的位置 - paperTransform = paper.shapeNode.getAttribute('transform'); - paper.shapeNode.setAttribute('transform', 'translate(0.5, 0.5)'); - renderContainer.translate(-renderBox.x, -renderBox.y); - - // 获取当前的 XML 代码 - svgXml = paper.container.innerHTML; - - // 回复原始变换及位置 - renderContainer.translate(renderBox.x, renderBox.y); - paper.shapeNode.setAttribute('transform', paperTransform); - - // 过滤内容 - svgContainer = document.createElement('div'); - svgContainer.innerHTML = svgXml; - svgDom = svgContainer.querySelector('svg'); - svgDom.setAttribute('width', renderBox.width + 1); - svgDom.setAttribute('height', renderBox.height + 1); - svgDom.setAttribute('style', 'font-family: Arial, "Microsoft Yahei","Heiti SC";'); - - svgContainer = document.createElement('div'); - svgContainer.appendChild(svgDom); - - svgXml = svgContainer.innerHTML; - - // Dummy IE - svgXml = svgXml.replace(' xmlns="http://www.w3.org/2000/svg" ' + - 'xmlns:NS1="" NS1:ns1:xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:NS2="" NS2:xmlns:ns1=""', ''); - - // svg 含有   符号导出报错 Entity 'nbsp' not defined ,含有控制字符触发Load Image 会触发报错 - svgXml = svgXml.replace(/ |[\x00-\x1F\x7F-\x9F]/g, ""); - - // fix title issue in safari - // @ http://stackoverflow.com/questions/30273775/namespace-prefix-ns1-for-href-on-tagelement-is-not-defined-setattributens - svgXml = svgXml.replace(/NS\d+:title/gi, 'xlink:title'); - - blob = new Blob([svgXml], { - type: 'image/svg+xml' - }); - - svgUrl = DomURL.createObjectURL(blob); - - //svgUrl = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgXml); - - var imagesInfo = []; - - // 遍历取出图片信息 - traverse(minder.getRoot()); - - function traverse(node) { - var nodeData = node.data; - - if (nodeData.image) { - minder.renderNode(node); - var nodeData = node.data; - var imageUrl = nodeData.image; - var imageSize = nodeData.imageSize; - var imageRenderBox = node.getRenderBox("ImageRenderer", minder.getRenderContainer()); - var imageInfo = { - url: imageUrl, - width: imageSize.width, - height: imageSize.height, - x: -renderContainer.getBoundaryBox().x + imageRenderBox.x, - y: -renderContainer.getBoundaryBox().y + imageRenderBox.y - }; - - imagesInfo.push(imageInfo); - } - - // 若节点折叠,则直接返回 - if (nodeData.expandState === 'collapse') { - return; - } - - var children = node.getChildren(); - for (var i = 0; i < children.length; i++) { - traverse(children[i]); - } - } - - return { - width: width, - height: height, - dataUrl: svgUrl, - xml: svgXml, - imagesInfo: imagesInfo - }; - } - - - function encode(json, minder, option) { - - var resultCallback; - - /* 绘制 PNG 的画布及上下文 */ - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('2d'); - - /* 尝试获取背景图片 URL 或背景颜色 */ - var bgDeclare = minder.getStyle('background').toString(); - var bgUrl = /url\(\"(.+)\"\)/.exec(bgDeclare); - var bgColor = kity.Color.parse(bgDeclare); - - /* 获取 SVG 文件内容 */ - var svgInfo = getSVGInfo(minder); - var width = option && option.width && option.width > svgInfo.width ? option.width : svgInfo.width; - var height = option && option.height && option.height > svgInfo.height ? option.height : svgInfo.height; - var offsetX = option && option.width && option.width > svgInfo.width ? (option.width - svgInfo.width)/2 : 0; - var offsetY = option && option.height && option.height > svgInfo.height ? (option.height - svgInfo.height)/2 : 0; - var svgDataUrl = svgInfo.dataUrl; - var imagesInfo = svgInfo.imagesInfo; - - /* 画布的填充大小 */ - var padding = 20; - - canvas.width = width + padding * 2; - canvas.height = height + padding * 2; - - function fillBackground(ctx, style) { - ctx.save(); - ctx.fillStyle = style; - ctx.fillRect(0, 0, canvas.width, canvas.height); - ctx.restore(); - } - - function drawImage(ctx, image, x, y, width, height) { - if (width && height) { - ctx.drawImage(image, x + padding, y + padding, width, height); - } else { - ctx.drawImage(image, x + padding, y + padding); - } - } - - function generateDataUrl(canvas) { - return canvas.toDataURL('image/png'); - } - - // 加载节点上的图片 - function loadImages(imagesInfo) { - var imagePromises = imagesInfo.map(function(imageInfo) { - return xhrLoadImage(imageInfo); - }); - - return Promise.all(imagePromises); - } - - function drawSVG() { - var svgData = {url: svgDataUrl}; - - return loadImage(svgData).then(function($image) { - drawImage(ctx, $image.element, offsetX, offsetY, $image.width, $image.height); - return loadImages(imagesInfo); - }).then(function($images) { - for(var i = 0; i < $images.length; i++) { - drawImage(ctx, $images[i].element, $images[i].x + offsetX, $images[i].y + offsetY, $images[i].width, $images[i].height); - } - - DomURL.revokeObjectURL(svgDataUrl); - document.body.appendChild(canvas); - var pngBase64 = generateDataUrl(canvas); - - document.body.removeChild(canvas); - return pngBase64; - }, function(err) { - // 这里处理 reject,出错基本上是因为跨域, - // 出错后依然导出,只不过没有图片。 - alert('脑图的节点中包含跨域图片,导出的 png 中节点图片不显示,你可以替换掉这些跨域的图片并重试。'); - DomURL.revokeObjectURL(svgDataUrl); - document.body.appendChild(canvas); - - var pngBase64 = generateDataUrl(canvas); - document.body.removeChild(canvas); - return pngBase64; - }); - } - - if (bgUrl) { - var bgInfo = {url: bgUrl[1]}; - return loadImage(bgInfo).then(function($image) { - fillBackground(ctx, ctx.createPattern($image.element, "repeat")); - return drawSVG(); - }); - } else { - fillBackground(ctx, bgColor.toString()); - return drawSVG(); - } - } - data.registerProtocol("png", module.exports = { - fileDescription: "PNG 图片", - fileExtension: ".png", - mineType: "image/png", - dataType: "base64", - encode: encode - }); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/svg.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/svg.js deleted file mode 100644 index 96a25e07..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/svg.js +++ /dev/null @@ -1,243 +0,0 @@ -define(function(require, exports, module) { - var data = require('../core/data'); - - /** - * 导出svg时删除全部svg元素中的transform - * @auth Naixor - * @method removeTransform - * @param {[type]} svgDom [description] - * @return {[type]} [description] - */ - function cleanSVG(svgDom, x, y) { - function getTransformToElement(target, source) { - var matrix; - try { - matrix = source.getScreenCTM().inverse(); - } catch (e) { - throw new Error("Can not inverse source element' ctm."); - } - return matrix.multiply(target.getScreenCTM()); - } - function dealWithPath(d, dealWithPattern) { - if (!(dealWithPattern instanceof Function)) { - dealWithPattern = function() {}; - } - var strArr = [], pattern = [], cache = []; - for (var i = 0, l = d.length; i < l; i++) { - switch (d[i]) { - case "M": - case "L": - case "T": - case "S": - case "A": - case "C": - case "H": - case "V": - case "Q": { - if (cache.length) { - pattern.push(cache.join("")); - cache = []; - } - // 脑图的path格式真奇怪...偶尔就给我蹦出来一个"..V123 C..", 那空格几个意思 - - - if (pattern[pattern.length-1] === ",") { - pattern.pop(); - } - if (pattern.length) { - dealWithPattern(pattern); - strArr.push(pattern.join("")); - pattern = []; - } - pattern.push(d[i]); - break; - } - case "Z": - case "z": { - pattern.push(cache.join(""), d[i]); - dealWithPattern(pattern); - strArr.push(pattern.join("")); - cache = []; - pattern = []; - break; - } - case ".": - case "e": { - cache.push(d[i]); - break; - } - case "-": { - if (d[i-1] !== "e") { - if (cache.length) { - pattern.push(cache.join(""), ","); - } - cache = []; - } - cache.push("-"); - break; - } - case " ": - case ",": { - if (cache.length) { - pattern.push(cache.join(""), ","); - cache = []; - } - break; - } - default: { - if (/\d/.test(d[i])) { - cache.push(d[i]); - } else { - // m a c s q h v l t z情况 - if (cache.length) { - pattern.push(cache.join(""), d[i]); - cache = []; - } else { - // 脑图的path格式真奇怪...偶尔就给我蹦出来一个"..V123 c..", 那空格几个意思 - - - if (pattern[pattern.length-1] === ",") { - pattern.pop(); - } - pattern.push(d[i]); - } - } - if (i + 1 === l) { - if (cache.length) { - pattern.push(cache.join("")); - } - dealWithPattern(pattern); - strArr.push(pattern.join("")); - cache = null; - pattern = null; - } - } - } - } - return strArr.join(""); - } - - function replaceWithNode(svgNode, parentX, parentY) { - if (!svgNode) { - return; - } - if (svgNode.tagName === "defs") { - return; - } - if (svgNode.getAttribute('fill') === 'transparent') { - svgNode.setAttribute('fill', 'none'); - } - if (svgNode.getAttribute('marker-end')) { - svgNode.removeAttribute('marker-end'); - } - parentX = parentX || 0; - parentY = parentY || 0; - if (svgNode.getAttribute("transform")) { - var ctm = getTransformToElement(svgNode, svgNode.parentElement); - parentX -= ctm.e; - parentY -= ctm.f; - svgNode.removeAttribute("transform"); - } - switch (svgNode.tagName.toLowerCase()) { - case "g": - break; - case "path": { - var d = svgNode.getAttribute("d"); - if (d) { - d = dealWithPath(d, function(pattern) { - switch (pattern[0]) { - case "V": { - pattern[1] = +pattern[1] - parentY; - break; - } - case "H": { - pattern[1] = +pattern[1] - parentX; - break; - } - case "M": - case "L": - case "T": { - pattern[1] = +pattern[1] - parentX; - pattern[3] = +pattern[3] - parentY; - break; - } - case "Q": - case "S": { - pattern[1] = +pattern[1] - parentX; - pattern[3] = +pattern[3] - parentY; - pattern[5] = +pattern[5] - parentX; - pattern[7] = +pattern[7] - parentY; - break; - } - case "A": { - pattern[11] = +pattern[11] - parentX; - pattern[13] = +pattern[13] - parentY; - break; - } - case "C": { - pattern[1] = +pattern[1] - parentX; - pattern[3] = +pattern[3] - parentY; - pattern[5] = +pattern[5] - parentX; - pattern[7] = +pattern[7] - parentY; - pattern[9] = +pattern[9] - parentX; - pattern[11] = +pattern[11] - parentY; - } - } - }); - svgNode.setAttribute("d", d); - svgNode.removeAttribute("transform"); - } - return; - } - case "image": - case "text": { - if (parentX && parentY) { - var x = +svgNode.getAttribute("x") || 0, y = +svgNode.getAttribute("y") || 0; - svgNode.setAttribute("x", x - parentX); - svgNode.setAttribute("y", y - parentY); - } - if (svgNode.getAttribute("dominant-baseline")) { - svgNode.removeAttribute("dominant-baseline"); - svgNode.setAttribute("dy", ".8em"); - } - svgNode.removeAttribute("transform"); - return; - } - } - if (svgNode.children) { - for (var i = 0, l = svgNode.children.length; i < l; i++) { - replaceWithNode(svgNode.children[i], parentX, parentY); - } - } - } - svgDom.style.visibility = "hidden"; - replaceWithNode(svgDom, x || 0, y || 0); - svgDom.style.visibility = "visible"; - } - data.registerProtocol("svg", module.exports = { - fileDescription: "SVG 矢量图", - fileExtension: ".svg", - mineType: "image/svg+xml", - dataType: "text", - encode: function(json, minder) { - var paper = minder.getPaper(), paperTransform = paper.shapeNode.getAttribute("transform"), svgXml, svgContainer, svgDom, renderContainer = minder.getRenderContainer(), renderBox = renderContainer.getRenderBox(), transform = renderContainer.getTransform(), width = renderBox.width, height = renderBox.height, padding = 20; - paper.shapeNode.setAttribute("transform", "translate(0.5, 0.5)"); - svgXml = paper.container.innerHTML; - paper.shapeNode.setAttribute("transform", paperTransform); - svgContainer = document.createElement("div"); - document.body.appendChild(svgContainer); - svgContainer.innerHTML = svgXml; - svgDom = svgContainer.querySelector("svg"); - svgDom.setAttribute("width", width + padding * 2 | 0); - svgDom.setAttribute("height", height + padding * 2 | 0); - svgDom.setAttribute("style", "background: " + minder.getStyle("background"));//"font-family: Arial, Microsoft Yahei, Heiti SC; " + - svgDom.setAttribute("viewBox", [ 0, 0, width + padding * 2 | 0, height + padding * 2 | 0 ].join(" ")); - tempSvgContainer = document.createElement("div"); - cleanSVG(svgDom, renderBox.x - padding | 0, renderBox.y - padding | 0); - document.body.removeChild(svgContainer); - tempSvgContainer.appendChild(svgDom); - // need a xml with width and height - svgXml = tempSvgContainer.innerHTML; - // svg 含有   符号导出报错 Entity 'nbsp' not defined - svgXml = svgXml.replace(/ /g, " "); - // svg 含有   符号导出报错 Entity 'nbsp' not defined - return svgXml; - } - }); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/text.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/text.js deleted file mode 100644 index ad740af6..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/protocol/text.js +++ /dev/null @@ -1,237 +0,0 @@ -define(function(require, exports, module) { - var data = require('../core/data'); - var Browser = require('../core/kity').Browser; - - /** - * @Desc: 增加对不容浏览器下节点中文本\t匹配的处理,不同浏览器下\t无法正确匹配,导致无法使用TAB来批量导入节点 - * @Editor: Naixor - * @Date: 2015.9.17 - */ - var LINE_ENDING = '\r', - LINE_ENDING_SPLITER = /\r\n|\r|\n/, - TAB_CHAR = (function(Browser) { - if (Browser.gecko) { - return { - REGEXP: new RegExp('^(\t|'+ String.fromCharCode(160,160,32,160) +')'), - DELETE: new RegExp('^(\t|'+ String.fromCharCode(160,160,32,160) +')+') - } - } else if (Browser.ie || Browser.edge) { - // ie系列和edge比较特别,\t在div中会被直接转义成SPACE故只好使用SPACE来做处理 - return { - REGEXP: new RegExp('^('+ String.fromCharCode(32) +'|'+ String.fromCharCode(160) +')'), - DELETE: new RegExp('^('+ String.fromCharCode(32) +'|'+ String.fromCharCode(160) +')+') - } - } else { - return { - REGEXP: /^(\t|\x20{4})/, - DELETE: /^(\t|\x20{4})+/ - } - } - })(Browser); - - function repeat(s, n) { - var result = ''; - while (n--) result += s; - return result; - } - - /** - * 对节点text中的换行符进行处理 - * @method encodeWrap - * @param {String} nodeText MinderNode.data.text - * @return {String} \n -> '\n'; \\n -> '\\n' - */ - function encodeWrap(nodeText) { - if (!nodeText) { - return ''; - } - var textArr = [], - WRAP_TEXT = ['\\', 'n']; - for (var i = 0, j = 0, l = nodeText.length; i < l; i++) { - if (nodeText[i] === '\n' || nodeText[i] === '\r') { - textArr.push('\\n'); - j = 0; - continue; - } - if (nodeText[i] === WRAP_TEXT[j]) { - j++; - if (j === 2) { - j = 0; - textArr.push('\\\\n'); - } - continue; - } - switch (j) { - case 0: { - textArr.push(nodeText[i]); - break; - } - case 1: { - textArr.push(nodeText[i-1], nodeText[i]); - } - } - j = 0; - } - return textArr.join(''); - } - - /** - * 将文本内容中的'\n'和'\\n'分别转换成\n和\\n - * @method decodeWrap - * @param {[type]} text [description] - * @return {[type]} [description] - */ - function decodeWrap(text) { - if (!text) { - return ''; - } - var textArr = [], - WRAP_TEXT = ['\\', '\\', 'n']; - for (var i = 0, j = 0, l = text.length; i < l; i++) { - if (text[i] === WRAP_TEXT[j]) { - j++; - if (j === 3) { - j = 0; - textArr.push('\\n'); - } - continue; - } - switch (j) { - case 0: { - textArr.push(text[i]); - j = 0; - break; - } - case 1: { - if (text[i] === 'n') { - textArr.push('\n'); - } else { - textArr.push(text[i-1], text[i]); - } - j = 0; - break; - } - case 2: { - textArr.push(text[i-2]); - if (text[i] !== '\\') { - j = 0; - textArr.push(text[i-1], text[i]); - } - break; - } - } - } - return textArr.join(''); - } - - function encode(json, level) { - var local = ''; - level = level || 0; - local += repeat('\t', level); - local += encodeWrap(json.data.text) + LINE_ENDING; - if (json.children) { - json.children.forEach(function(child) { - local += encode(child, level + 1); - }); - } - return local; - } - - function isEmpty(line) { - return !/\S/.test(line); - } - - function getLevel(line) { - var level = 0; - while (TAB_CHAR.REGEXP.test(line)) { - line = line.replace(TAB_CHAR.REGEXP, ''); - level++; - } - - return level; - } - - function getNode(line) { - return { - data: { - text: decodeWrap(line.replace(TAB_CHAR.DELETE, "")) - } - }; - } - - function decode(local) { - var json, - parentMap = {}, - lines = local.split(LINE_ENDING_SPLITER), - line, level, node; - - function addChild(parent, child) { - var children = parent.children || (parent.children = []); - children.push(child); - } - - for (var i = 0; i < lines.length; i++) { - line = lines[i]; - if (isEmpty(line)) continue; - - level = getLevel(line); - node = getNode(line); - - if (level === 0) { - if (json) { - throw new Error('Invalid local format'); - } - json = node; - } else { - if (!parentMap[level - 1]) { - throw new Error('Invalid local format'); - } - addChild(parentMap[level - 1], node); - } - parentMap[level] = node; - } - return json; - } - - /** - * @Desc: 增加一个将当前选中节点转换成text的方法 - * @Editor: Naixor - * @Date: 2015.9.21 - */ - function Node2Text(node) { - function exportNode(node) { - var exported = {}; - exported.data = node.getData(); - var childNodes = node.getChildren(); - exported.children = []; - for (var i = 0; i < childNodes.length; i++) { - exported.children.push(exportNode(childNodes[i])); - } - return exported; - } - if (!node) return; - if (/^\s*$/.test(node.data.text)) { - node.data.text = "分支主题"; - } - return encode(exportNode(node)); - } - - data.registerProtocol('text', module.exports = { - fileDescription: '大纲文本', - fileExtension: '.txt', - dataType: 'text', - mineType: 'text/plain', - - encode: function(json) { - return encode(json.root, 0); - }, - - decode: function(local) { - return decode(local); - }, - - Node2Text: function(node) { - return Node2Text(node); - } - }); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/default.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/default.js deleted file mode 100644 index 0e20fea1..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/default.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @fileOverview - * - * 默认模板 - 脑图模板 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - var template = require('../core/template'); - - template.register('default', { - - getLayout: function(node) { - - if (node.getData('layout')) return node.getData('layout'); - - var level = node.getLevel(); - - // 根节点 - if (level === 0) { - return 'mind'; - } - - // 一级节点 - if (level === 1) { - return node.getLayoutPointPreview().x > 0 ? 'right': 'left'; - } - - return node.parent.getLayout(); - }, - - getConnect: function(node) { - if (node.getLevel() == 1) return 'arc'; - return 'under'; - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/filetree.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/filetree.js deleted file mode 100644 index dd68b12a..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/filetree.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @fileOverview - * - * 文件夹模板 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - var template = require('../core/template'); - - template.register('filetree', { - - getLayout: function(node) { - if (node.getData('layout')) return node.getData('layout'); - if (node.isRoot()) return 'bottom'; - - return 'filetree-down'; - }, - - getConnect: function(node) { - if (node.getLevel() == 1) { - return 'poly'; - } - return 'l'; - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/fish-bone.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/fish-bone.js deleted file mode 100644 index 71e8076e..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/fish-bone.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @fileOverview - * - * 默认模板 - 鱼骨头模板 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - var template = require('../core/template'); - - template.register('fish-bone', { - - getLayout: function(node) { - - if (node.getData('layout')) return node.getData('layout'); - - var level = node.getLevel(); - - // 根节点 - if (level === 0) { - return 'fish-bone-master'; - } - - // 一级节点 - if (level === 1) { - return 'fish-bone-slave'; - } - - return node.getLayoutPointPreview().y > 0 ? 'filetree-up': 'filetree-down'; - }, - - getConnect: function(node) { - switch (node.getLevel()) { - case 1: return 'fish-bone-master'; - case 2: return 'line'; - default: return 'l'; - } - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/right.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/right.js deleted file mode 100644 index 6d1c206c..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/right.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @fileOverview - * - * 往右布局结构模板 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - var template = require('../core/template'); - - template.register('right', { - - getLayout: function(node) { - return node.getData('layout') || 'right'; - }, - - getConnect: function(node) { - if (node.getLevel() == 1) return 'arc'; - return 'bezier'; - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/structure.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/structure.js deleted file mode 100644 index 4af7eab9..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/structure.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @fileOverview - * - * 组织结构图模板 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - var template = require('../core/template'); - - template.register('structure', { - - getLayout: function(node) { - return node.getData('layout') || 'bottom'; - }, - - getConnect: function(node) { - return 'poly'; - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/tianpan.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/tianpan.js deleted file mode 100644 index cc92ada5..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/template/tianpan.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @fileOverview - * - * 天盘模板 - * - * @author: along - * @copyright: bpd729@163.com, 2015 - */ -define(function(require, exports, module) { - var template = require('../core/template'); - - template.register('tianpan', { - getLayout: function (node) { - if (node.getData('layout')) return node.getData('layout'); - var level = node.getLevel(); - - // 根节点 - if (level === 0) { - return 'tianpan'; - } - - return node.parent.getLayout(); - }, - - getConnect: function (node) { - return 'arc_tp'; - } - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/default.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/default.js deleted file mode 100644 index 54c1b860..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/default.js +++ /dev/null @@ -1,66 +0,0 @@ -define(function(require, exports, module) { - var theme = require('../core/theme'); - - ['classic', 'classic-compact'].forEach(function(name) { - var compact = name == 'classic-compact'; - - /* jscs:disable maximumLineLength */ - theme.register(name, { - 'background': '#3A4144 url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQzg5QTQ0NDhENzgxMUUzOENGREE4QTg0RDgzRTZDNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQzg5QTQ0NThENzgxMUUzOENGREE4QTg0RDgzRTZDNyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkMwOEQ1NDRGOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkMwOEQ1NDUwOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+e9P33AAAACVJREFUeNpisXJ0YUACTAyoAMr/+eM7EGGRZ4FQ7BycEAZAgAEAHbEGtkoQm/wAAAAASUVORK5CYII=") repeat', - - 'root-color': '#430', - 'root-background': '#e9df98', - 'root-stroke': '#e9df98', - 'root-font-size': 24, - 'root-padding': compact ? [10, 25] : [15, 25], - 'root-margin': compact ? [15, 25] : [30, 100], - 'root-radius': 30, - 'root-space': 10, - 'root-shadow': 'rgba(0, 0, 0, .25)', - - 'main-color': '#333', - 'main-background': '#a4c5c0', - 'main-stroke': '#a4c5c0', - 'main-font-size': 16, - 'main-padding': compact ? [5, 15] : [6, 20], - 'main-margin': compact ? [5, 10] : 20, - 'main-radius': 10, - 'main-space': 5, - 'main-shadow': 'rgba(0, 0, 0, .25)', - - 'sub-color': 'white', - 'sub-background': 'transparent', - 'sub-stroke': 'none', - 'sub-font-size': 12, - 'sub-padding': [5, 10], - 'sub-margin': compact ? [5, 10] : [15, 20], - 'sub-tree-margin': 30, - 'sub-radius': 5, - 'sub-space': 5, - - 'connect-color': 'white', - 'connect-width': 2, - 'main-connect-width': 3, - 'connect-radius': 5, - - 'selected-background': 'rgb(254, 219, 0)', - 'selected-stroke': 'rgb(254, 219, 0)', - 'selected-color': 'black', - - 'marquee-background': 'rgba(255,255,255,.3)', - 'marquee-stroke': 'white', - - 'drop-hint-color': 'yellow', - 'sub-drop-hint-width': 2, - 'main-drop-hint-width': 4, - 'root-drop-hint-width': 4, - - 'order-hint-area-color': 'rgba(0, 255, 0, .5)', - 'order-hint-path-color': '#0f0', - 'order-hint-path-width': 1, - - 'text-selection-color': 'rgb(27,171,255)', - 'line-height':1.5 - }); - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/fish.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/fish.js deleted file mode 100644 index 71d88aaa..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/fish.js +++ /dev/null @@ -1,57 +0,0 @@ -define(function(require, exports, module) { - var theme = require('../core/theme'); - - theme.register('fish', { - 'background': '#3A4144 url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQzg5QTQ0NDhENzgxMUUzOENGREE4QTg0RDgzRTZDNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQzg5QTQ0NThENzgxMUUzOENGREE4QTg0RDgzRTZDNyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkMwOEQ1NDRGOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkMwOEQ1NDUwOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+e9P33AAAACVJREFUeNpisXJ0YUACTAyoAMr/+eM7EGGRZ4FQ7BycEAZAgAEAHbEGtkoQm/wAAAAASUVORK5CYII=") repeat', - - 'root-color': '#430', - 'root-background': '#e9df98', - 'root-stroke': '#e9df98', - 'root-font-size': 24, - 'root-padding': [35, 35], - 'root-margin': 30, - 'root-radius': 100, - 'root-space': 10, - 'root-shadow': 'rgba(0, 0, 0, .25)', - - 'main-color': '#333', - 'main-background': '#a4c5c0', - 'main-stroke': '#a4c5c0', - 'main-font-size': 16, - 'main-padding': [6, 20], - 'main-margin': [20, 20], - 'main-radius': 5, - 'main-space': 5, - 'main-shadow': 'rgba(0, 0, 0, .25)', - - 'sub-color': 'black', - 'sub-background': 'white', - 'sub-stroke': 'white', - 'sub-font-size': 12, - 'sub-padding': [5, 10], - 'sub-margin': [10], - 'sub-radius': 5, - 'sub-space': 5, - - 'connect-color': 'white', - 'connect-width': 3, - 'main-connect-width': 3, - 'connect-radius': 5, - - 'selected-background': 'rgb(254, 219, 0)', - 'selected-stroke': 'rgb(254, 219, 0)', - - 'marquee-background': 'rgba(255,255,255,.3)', - 'marquee-stroke': 'white', - - 'drop-hint-color': 'yellow', - 'drop-hint-width': 4, - - 'order-hint-area-color': 'rgba(0, 255, 0, .5)', - 'order-hint-path-color': '#0f0', - 'order-hint-path-width': 1, - - 'text-selection-color': 'rgb(27,171,255)', - 'line-height':1.5 - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/fresh.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/fresh.js deleted file mode 100644 index 49ef3e1f..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/fresh.js +++ /dev/null @@ -1,78 +0,0 @@ -define(function(require, exports, module) { - var kity = require('../core/kity'); - var theme = require('../core/theme'); - - function hsl(h, s, l) { - return kity.Color.createHSL(h, s, l); - } - - function generate(h, compat) { - return { - 'background': '#fbfbfb', - - 'root-color': 'white', - 'root-background': hsl(h, 37, 60), - 'root-stroke': hsl(h, 37, 60), - 'root-font-size': 16, - 'root-padding': compat ? [6, 12] : [12, 24], - 'root-margin': compat ? 10 : [30, 100], - 'root-radius': 5, - 'root-space': 10, - - 'main-color': 'black', - 'main-background': hsl(h, 33, 95), - 'main-stroke': hsl(h, 37, 60), - 'main-stroke-width': 1, - 'main-font-size': 14, - 'main-padding': [6, 20], - 'main-margin': compat ? 8 : 20, - 'main-radius': 3, - 'main-space': 5, - - 'sub-color': 'black', - 'sub-background': 'transparent', - 'sub-stroke': 'none', - 'sub-font-size': 12, - 'sub-padding': compat ? [3, 5] : [5, 10], - 'sub-margin': compat ? [4, 8] : [15, 20], - 'sub-radius': 5, - 'sub-space': 5, - - 'connect-color': hsl(h, 37, 60), - 'connect-width': 1, - 'connect-radius': 5, - - 'selected-stroke': hsl(h, 26, 30), - 'selected-stroke-width': '3', - 'blur-selected-stroke': hsl(h, 10, 60), - - 'marquee-background': hsl(h, 100, 80).set('a', 0.1), - 'marquee-stroke': hsl(h, 37, 60), - - 'drop-hint-color': hsl(h, 26, 35), - 'drop-hint-width': 5, - - 'order-hint-area-color': hsl(h, 100, 30).set('a', 0.5), - 'order-hint-path-color': hsl(h, 100, 25), - 'order-hint-path-width': 1, - - 'text-selection-color': hsl(h, 100, 20), - 'line-height':1.5 - }; - } - - var plans = { - red: 0, - soil: 25, - green: 122, - blue: 204, - purple: 246, - pink: 334 - }; - var name; - for (name in plans) { - theme.register('fresh-' + name, generate(plans[name])); - theme.register('fresh-' + name + '-compat', generate(plans[name], true)); - } - -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/snow.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/snow.js deleted file mode 100644 index 08ba9280..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/snow.js +++ /dev/null @@ -1,62 +0,0 @@ -define(function(require, exports, module) { - var theme = require('../core/theme'); - - ['snow', 'snow-compact'].forEach(function(name) { - var compact = name == 'snow-compact'; - - /* jscs:disable maximumLineLength */ - theme.register(name, { - 'background': '#3A4144 url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQzg5QTQ0NDhENzgxMUUzOENGREE4QTg0RDgzRTZDNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQzg5QTQ0NThENzgxMUUzOENGREE4QTg0RDgzRTZDNyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkMwOEQ1NDRGOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkMwOEQ1NDUwOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+e9P33AAAACVJREFUeNpisXJ0YUACTAyoAMr/+eM7EGGRZ4FQ7BycEAZAgAEAHbEGtkoQm/wAAAAASUVORK5CYII=") repeat', - - 'root-color': '#430', - 'root-background': '#e9df98', - 'root-stroke': '#e9df98', - 'root-font-size': 24, - 'root-padding': compact ? [5, 10] : [15, 25], - 'root-margin': compact ? 15 : 30, - 'root-radius': 5, - 'root-space': 10, - 'root-shadow': 'rgba(0, 0, 0, .25)', - - 'main-color': '#333', - 'main-background': '#a4c5c0', - 'main-stroke': '#a4c5c0', - 'main-font-size': 16, - 'main-padding': compact ? [4, 10] : [6, 20], - 'main-margin': compact ? [5, 10] : [20, 40], - 'main-radius': 5, - 'main-space': 5, - 'main-shadow': 'rgba(0, 0, 0, .25)', - - 'sub-color': 'black', - 'sub-background': 'white', - 'sub-stroke': 'white', - 'sub-font-size': 12, - 'sub-padding': [5, 10], - 'sub-margin': compact ? [5, 10] : [10, 20], - 'sub-radius': 5, - 'sub-space': 5, - - 'connect-color': 'white', - 'connect-width': 2, - 'main-connect-width': 3, - 'connect-radius': 5, - - 'selected-background': 'rgb(254, 219, 0)', - 'selected-stroke': 'rgb(254, 219, 0)', - - 'marquee-background': 'rgba(255,255,255,.3)', - 'marquee-stroke': 'white', - - 'drop-hint-color': 'yellow', - 'drop-hint-width': 4, - - 'order-hint-area-color': 'rgba(0, 255, 0, .5)', - 'order-hint-path-color': '#0f0', - 'order-hint-path-width': 1, - - 'text-selection-color': 'rgb(27,171,255)', - 'line-height':1.5 - }); - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/tianpan.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/tianpan.js deleted file mode 100644 index 333a6772..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/tianpan.js +++ /dev/null @@ -1,74 +0,0 @@ -define(function(require, exports, module) { - var theme = require('../core/theme'); - - ['tianpan', 'tianpan-compact'].forEach(function (name) { - var compact = name == 'tianpan-compact'; - - theme.register(name, { - 'background': '#3A4144 url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQzg5QTQ0NDhENzgxMUUzOENGREE4QTg0RDgzRTZDNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQzg5QTQ0NThENzgxMUUzOENGREE4QTg0RDgzRTZDNyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkMwOEQ1NDRGOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkMwOEQ1NDUwOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+e9P33AAAACVJREFUeNpisXJ0YUACTAyoAMr/+eM7EGGRZ4FQ7BycEAZAgAEAHbEGtkoQm/wAAAAASUVORK5CYII=") repeat', - - 'root-color': '#430', - 'root-background': '#e9df98', - 'root-stroke': '#e9df98', - 'root-font-size': 25, - 'root-padding': compact ? 15 : 20, - 'root-margin': compact ? [15, 25] : 100, - 'root-radius': 30, - 'root-space': 10, - 'root-shadow': 'rgba(0, 0, 0, .25)', - 'root-shape': 'circle', - - 'main-color': '#333', - 'main-background': '#a4c5c0', - 'main-stroke': '#a4c5c0', - 'main-font-size': 15, - 'main-padding': compact ? 10 : 12, - 'main-margin': compact ? 10 : 12, - 'main-radius': 10, - 'main-space': 5, - 'main-shadow': 'rgba(0, 0, 0, .25)', - 'main-shape': 'circle', - - 'sub-color': '#333', - 'sub-background': '#99ca6a', - 'sub-stroke': '#a4c5c0', - 'sub-font-size': 13, - 'sub-padding': 5, - 'sub-margin': compact ? 6 : 10, - 'sub-tree-margin': 30, - 'sub-radius': 5, - 'sub-space': 5, - 'sub-shadow': 'rgba(0, 0, 0, .25)', - 'sub-shape': 'circle', - - 'connect-color': 'white', - 'connect-width': 2, - 'main-connect-width': 3, - 'connect-radius': 5, - - 'selected-background': 'rgb(254, 219, 0)', - 'selected-stroke': 'rgb(254, 219, 0)', - 'selected-color': 'black', - - 'marquee-background': 'rgba(255,255,255,.3)', - 'marquee-stroke': 'white', - - 'drop-hint-color': 'yellow', - 'sub-drop-hint-width': 2, - 'main-drop-hint-width': 4, - 'root-drop-hint-width': 4, - - 'order-hint-area-color': 'rgba(0, 255, 0, .5)', - 'order-hint-path-color': '#0f0', - 'order-hint-path-width': 1, - - 'text-selection-color': 'rgb(27,171,255)', - 'line-height': 1.4 - }); - }); -}); - - - - - diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/wire.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/wire.js deleted file mode 100644 index a0eaacda..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-core/theme/wire.js +++ /dev/null @@ -1,34 +0,0 @@ -define(function(require, exports, module) { - var theme = require('../core/theme'); - - theme.register('wire', { - 'background': 'black', - - 'color': '#999', - 'stroke': 'none', - 'padding': 10, - 'margin': 20, - 'font-size': 14, - - 'connect-color': '#999', - 'connect-width': 1, - - 'selected-background': '#999', - 'selected-color': 'black', - - 'marquee-background': 'rgba(255,255,255,.3)', - 'marquee-stroke': 'white', - - 'drop-hint-color': 'yellow', - 'sub-drop-hint-width': 2, - 'main-drop-hint-width': 4, - 'root-drop-hint-width': 4, - - 'order-hint-area-color': 'rgba(0, 255, 0, .5)', - 'order-hint-path-color': '#0f0', - 'order-hint-path-width': 1, - - 'text-selection-color': 'rgb(27,171,255)', - 'line-height':1.5 - }); -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/editor.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/editor.js deleted file mode 100644 index 4c62d085..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/editor.js +++ /dev/null @@ -1,38 +0,0 @@ -define(function (require, exports, module) { - /** - * 运行时 - */ - var runtimes = []; - - function assemble(runtime) { - runtimes.push(runtime); - } - - function KMEditor(selector, blackList) { - this.selector = selector; - for (var i = 0; i < runtimes.length; i++) { - if (typeof runtimes[i] == 'function') { - runtimes[i].call(this, this); - } - } - } - - KMEditor.assemble = assemble; - - assemble(require('./runtime/container')); - assemble(require('./runtime/fsm')); - assemble(require('./runtime/minder')); - assemble(require('./runtime/receiver')); - assemble(require('./runtime/hotbox')); - assemble(require('./runtime/input')); - assemble(require('./runtime/clipboard-mimetype')); - assemble(require('./runtime/clipboard')); - assemble(require('./runtime/drag')); - assemble(require('./runtime/node')); - assemble(require('./runtime/history')); - assemble(require('./runtime/jumping')); - assemble(require('./runtime/priority')); - assemble(require('./runtime/progress')); - - return (module.exports = KMEditor); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/expose-editor.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/expose-editor.js deleted file mode 100644 index 823926f2..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/expose-editor.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @fileOverview - * - * 打包暴露 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define('expose-editor', function (require, exports, module) { - return (module.exports = window.kityminder.Editor = require('./editor')); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/hotbox.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/hotbox.js deleted file mode 100644 index 08c95dd0..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/hotbox.js +++ /dev/null @@ -1,5 +0,0 @@ -import Hotbox from '../hotbox/hotbox'; - -define(function (require, exports, module) { - return (module.exports = Hotbox); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/lang.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/lang.js deleted file mode 100644 index c7d8611c..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/lang.js +++ /dev/null @@ -1,3 +0,0 @@ -define(function(require, exports, module) { - -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/minder.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/minder.js deleted file mode 100644 index 34d0c41b..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/minder.js +++ /dev/null @@ -1,3 +0,0 @@ -define(function (require, exports, module) { - return (module.exports = window.kityminder.Minder); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/clipboard-mimetype.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/clipboard-mimetype.js deleted file mode 100644 index 33ef0369..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/clipboard-mimetype.js +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @Desc: 新增一个用于处理系统ctrl+c ctrl+v等方式导入导出节点的MIMETYPE处理,如系统不支持clipboardEvent或者是FF则不初始化改class - * @Editor: Naixor - * @Date: 2015.9.21 - */ -define(function(require, exports, module) { - function MimeType() { - /** - * 私有变量 - */ - var SPLITOR = '\uFEFF'; - var MIMETYPE = { - 'application/km': '\uFFFF' - }; - var SIGN = { - '\uFEFF': 'SPLITOR', - '\uFFFF': 'application/km' - }; - - /** - * 用于将一段纯文本封装成符合其数据格式的文本 - * @method process private - * @param {MIMETYPE} mimetype 数据格式 - * @param {String} text 原始文本 - * @return {String} 符合该数据格式下的文本 - * @example - * var str = "123"; - * str = process('application/km', str); // 返回的内容再经过MimeType判断会读取出其数据格式为application/km - * process('text/plain', str); // 若接受到一个非纯文本信息,则会将其转换为新的数据格式 - */ - function process(mimetype, text) { - if (!this.isPureText(text)) { - var _mimetype = this.whichMimeType(text); - if (!_mimetype) { - throw new Error('unknow mimetype!'); - }; - text = this.getPureText(text); - }; - if (mimetype === false) { - return text; - }; - return mimetype + SPLITOR + text; - } - - /** - * 注册数据类型的标识 - * @method registMimeTypeProtocol public - * @param {String} type 数据类型 - * @param {String} sign 标识 - */ - this.registMimeTypeProtocol = function(type, sign) { - if (sign && SIGN[sign]) { - throw new Error('sing has registed!'); - } - if (type && !!MIMETYPE[type]) { - throw new Error('mimetype has registed!'); - }; - SIGN[sign] = type; - MIMETYPE[type] = sign; - } - - /** - * 获取已注册数据类型的协议 - * @method getMimeTypeProtocol public - * @param {String} type 数据类型 - * @param {String} text|undefiend 文本内容或不传入 - * @return {String|Function} - * @example - * text若不传入则直接返回对应数据格式的处理(process)方法 - * 若传入文本则直接调用对应的process方法进行处理,此时返回处理后的内容 - * var m = new MimeType(); - * var kmprocess = m.getMimeTypeProtocol('application/km'); - * kmprocess("123") === m.getMimeTypeProtocol('application/km', "123"); - * - */ - this.getMimeTypeProtocol = function(type, text) { - var mimetype = MIMETYPE[type] || false; - - if (text === undefined) { - return process.bind(this, mimetype); - }; - - return process(mimetype, text); - } - - this.getSpitor = function() { - return SPLITOR; - } - - this.getMimeType = function(sign) { - if (sign !== undefined) { - return SIGN[sign] || null; - }; - return MIMETYPE; - } - } - - MimeType.prototype.isPureText = function(text) { - return !(~text.indexOf(this.getSpitor())); - } - - MimeType.prototype.getPureText = function(text) { - if (this.isPureText(text)) { - return text; - }; - return text.split(this.getSpitor())[1]; - } - - MimeType.prototype.whichMimeType = function(text) { - if (this.isPureText(text)) { - return null; - }; - return this.getMimeType(text.split(this.getSpitor())[0]); - } - - function MimeTypeRuntime() { - if (this.minder.supportClipboardEvent && !kity.Browser.gecko) { - this.MimeType = new MimeType(); - }; - } - - return module.exports = MimeTypeRuntime; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/clipboard.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/clipboard.js deleted file mode 100644 index e01e3543..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/clipboard.js +++ /dev/null @@ -1,188 +0,0 @@ -/** - * @Desc: 处理editor的clipboard事件,只在支持ClipboardEvent并且不是FF的情况下工作 - * @Editor: Naixor - * @Date: 2015.9.21 - */ -define(function(require, exports, module) { - - function ClipboardRuntime () { - var minder = this.minder; - var Data = window.kityminder.data; - - if (!minder.supportClipboardEvent || kity.Browser.gecko) { - return; - }; - - var fsm = this.fsm; - var receiver = this.receiver; - var MimeType = this.MimeType; - - var kmencode = MimeType.getMimeTypeProtocol('application/km'), - decode = Data.getRegisterProtocol('json').decode; - var _selectedNodes = []; - - /* - * 增加对多节点赋值粘贴的处理 - */ - function encode (nodes) { - var _nodes = []; - for (var i = 0, l = nodes.length; i < l; i++) { - _nodes.push(minder.exportNode(nodes[i])); - } - return kmencode(Data.getRegisterProtocol('json').encode(_nodes)); - } - - var beforeCopy = function (e) { - if (document.activeElement == receiver.element) { - var clipBoardEvent = e; - var state = fsm.state(); - - switch (state) { - case 'input': { - break; - } - case 'normal': { - var nodes = [].concat(minder.getSelectedNodes()); - if (nodes.length) { - // 这里由于被粘贴复制的节点的id信息也都一样,故做此算法 - // 这里有个疑问,使用node.getParent()或者node.parent会离奇导致出现非选中节点被渲染成选中节点,因此使用isAncestorOf,而没有使用自行回溯的方式 - if (nodes.length > 1) { - var targetLevel; - nodes.sort(function(a, b) { - return a.getLevel() - b.getLevel(); - }); - targetLevel = nodes[0].getLevel(); - if (targetLevel !== nodes[nodes.length-1].getLevel()) { - var plevel, pnode, - idx = 0, l = nodes.length, pidx = l-1; - - pnode = nodes[pidx]; - - while (pnode.getLevel() !== targetLevel) { - idx = 0; - while (idx < l && nodes[idx].getLevel() === targetLevel) { - if (nodes[idx].isAncestorOf(pnode)) { - nodes.splice(pidx, 1); - break; - } - idx++; - } - pidx--; - pnode = nodes[pidx]; - } - }; - }; - var str = encode(nodes); - clipBoardEvent.clipboardData.setData('text/plain', str); - } - e.preventDefault(); - break; - } - } - } - } - - var beforeCut = function (e) { - if (document.activeElement == receiver.element) { - if (minder.getStatus() !== 'normal') { - e.preventDefault(); - return; - }; - - var clipBoardEvent = e; - var state = fsm.state(); - - switch (state) { - case 'input': { - break; - } - case 'normal': { - var nodes = minder.getSelectedNodes(); - if (nodes.length) { - clipBoardEvent.clipboardData.setData('text/plain', encode(nodes)); - minder.execCommand('removenode'); - } - e.preventDefault(); - break; - } - } - }; - } - - var beforePaste = function(e) { - if (document.activeElement == receiver.element) { - if (minder.getStatus() !== 'normal') { - e.preventDefault(); - return; - }; - - var clipBoardEvent = e; - var state = fsm.state(); - var textData = clipBoardEvent.clipboardData.getData('text/plain'); - - switch (state) { - case 'input': { - // input状态下如果格式为application/km则不进行paste操作 - if (!MimeType.isPureText(textData)) { - e.preventDefault(); - return; - }; - break; - } - case 'normal': { - /* - * 针对normal状态下通过对选中节点粘贴导入子节点文本进行单独处理 - */ - var sNodes = minder.getSelectedNodes(); - - if (MimeType.whichMimeType(textData) === 'application/km') { - var nodes = decode(MimeType.getPureText(textData)); - var _node; - sNodes.forEach(function(node) { - // 由于粘贴逻辑中为了排除子节点重新排序导致逆序,因此复制的时候倒过来 - for (var i = nodes.length-1; i >= 0; i--) { - _node = minder.createNode(null, node); - minder.importNode(_node, nodes[i]); - _selectedNodes.push(_node); - node.appendChild(_node); - } - }); - minder.select(_selectedNodes, true); - _selectedNodes = []; - - minder.refresh(); - } - else if (clipBoardEvent.clipboardData && clipBoardEvent.clipboardData.items[0].type.indexOf('image') > -1) { - var imageFile = clipBoardEvent.clipboardData.items[0].getAsFile(); - var serverService = angular.element(document.body).injector().get('server'); - - return serverService.uploadImage(imageFile).then(function (json) { - var resp = json.data; - if (resp.errno === 0) { - minder.execCommand('image', resp.data.url); - } - }); - } - else { - sNodes.forEach(function(node) { - minder.Text2Children(node, textData); - }); - } - e.preventDefault(); - break; - } - } - } - } - /** - * 由editor的receiver统一处理全部事件,包括clipboard事件 - * @Editor: Naixor - * @Date: 2015.9.24 - */ - document.addEventListener('copy', beforeCopy); - document.addEventListener('cut', beforeCut); - document.addEventListener('paste', beforePaste); - } - - return module.exports = ClipboardRuntime; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/container.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/container.js deleted file mode 100644 index 258ac1a3..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/container.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @fileOverview - * - * 初始化编辑器的容器 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - - /** - * 最先执行的 Runtime,初始化编辑器容器 - */ - function ContainerRuntime() { - var container; - - if (typeof(this.selector) == 'string') { - container = document.querySelector(this.selector); - } else { - container = this.selector; - } - - if (!container) throw new Error('Invalid selector: ' + this.selector); - - // 这个类名用于给编辑器添加样式 - container.classList.add('km-editor'); - - // 暴露容器给其他运行时使用 - this.container = container; - } - - return module.exports = ContainerRuntime; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/drag.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/drag.js deleted file mode 100644 index 3fc185f7..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/drag.js +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @fileOverview - * - * 用于拖拽节点时屏蔽键盘事件 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - - var Hotbox = require('../hotbox'); - var Debug = require('../tool/debug'); - var debug = new Debug('drag'); - - function DragRuntime() { - var fsm = this.fsm; - var minder = this.minder; - var hotbox = this.hotbox; - var receiver = this.receiver; - var receiverElement = receiver.element; - - // setup everything to go - setupFsm(); - - // listen the fsm changes, make action. - function setupFsm() { - - // when jumped to drag mode, enter - fsm.when('* -> drag', function() { - // now is drag mode - }); - - fsm.when('drag -> *', function(exit, enter, reason) { - if (reason == 'drag-finish') { - // now exit drag mode - } - }); - } - - var downX, downY; - var MOUSE_HAS_DOWN = 0; - var MOUSE_HAS_UP = 1; - var BOUND_CHECK = 20; - var flag = MOUSE_HAS_UP; - var maxX, maxY, osx, osy, containerY; - var freeHorizen = false, freeVirtical = false; - var frame; - - function move(direction, speed) { - if (!direction) { - freeHorizen = freeVirtical = false; - frame && kity.releaseFrame(frame); - frame = null; - return; - } - if (!frame) { - frame = kity.requestFrame((function (direction, speed, minder) { - return function (frame) { - switch (direction) { - case 'left': - minder._viewDragger.move({x: -speed, y: 0}, 0); - break; - case 'top': - minder._viewDragger.move({x: 0, y: -speed}, 0); - break; - case 'right': - minder._viewDragger.move({x: speed, y: 0}, 0); - break; - case 'bottom': - minder._viewDragger.move({x: 0, y: speed}, 0); - break; - default: - return; - } - frame.next(); - }; - })(direction, speed, minder)); - } - } - - minder.on('mousedown', function(e) { - flag = MOUSE_HAS_DOWN; - var rect = minder.getPaper().container.getBoundingClientRect(); - downX = e.originEvent.clientX; - downY = e.originEvent.clientY; - containerY = rect.top; - maxX = rect.width; - maxY = rect.height; - }); - - minder.on('mousemove', function(e) { - if (fsm.state() === 'drag' && flag == MOUSE_HAS_DOWN && minder.getSelectedNode() - && (Math.abs(downX - e.originEvent.clientX) > BOUND_CHECK - || Math.abs(downY - e.originEvent.clientY) > BOUND_CHECK)) { - osx = e.originEvent.clientX; - osy = e.originEvent.clientY - containerY; - - if (osx < BOUND_CHECK) { - move('right', BOUND_CHECK - osx); - } else if (osx > maxX - BOUND_CHECK) { - move('left', BOUND_CHECK + osx - maxX); - } else { - freeHorizen = true; - } - if (osy < BOUND_CHECK) { - move('bottom', osy); - } else if (osy > maxY - BOUND_CHECK) { - move('top', BOUND_CHECK + osy - maxY); - } else { - freeVirtical = true; - } - if (freeHorizen && freeVirtical) { - move(false); - } - } - if (fsm.state() !== 'drag' - && flag === MOUSE_HAS_DOWN - && minder.getSelectedNode() - && (Math.abs(downX - e.originEvent.clientX) > BOUND_CHECK - || Math.abs(downY - e.originEvent.clientY) > BOUND_CHECK)) { - - if (fsm.state() === 'hotbox') { - hotbox.active(Hotbox.STATE_IDLE); - } - - return fsm.jump('drag', 'user-drag'); - } - }); - - window.addEventListener('mouseup', function () { - flag = MOUSE_HAS_UP; - if (fsm.state() === 'drag') { - move(false); - return fsm.jump('normal', 'drag-finish'); - } - }, false); - } - - return module.exports = DragRuntime; -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/fsm.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/fsm.js deleted file mode 100644 index c9ed5cbd..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/fsm.js +++ /dev/null @@ -1,121 +0,0 @@ -/** - * @fileOverview - * - * 编辑器状态机 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - - var Debug = require('../tool/debug'); - var debug = new Debug('fsm'); - - function handlerConditionMatch(condition, when, exit, enter) { - if (condition.when != when) return false; - if (condition.enter != '*' && condition.enter != enter) return false; - if (condition.exit != '*' && condition.exit != exit) return; - return true; - } - - function FSM(defaultState) { - var currentState = defaultState; - var BEFORE_ARROW = ' - '; - var AFTER_ARROW = ' -> '; - var handlers = []; - - /** - * 状态跳转 - * - * 会通知所有的状态跳转监视器 - * - * @param {string} newState 新状态名称 - * @param {any} reason 跳转的原因,可以作为参数传递给跳转监视器 - */ - this.jump = function(newState, reason) { - if (!reason) throw new Error('Please tell fsm the reason to jump'); - - var oldState = currentState; - var notify = [oldState, newState].concat([].slice.call(arguments, 1)); - var i, handler; - - // 跳转前 - for (i = 0; i < handlers.length; i++) { - handler = handlers[i]; - if (handlerConditionMatch(handler.condition, 'before', oldState, newState)) { - if (handler.apply(null, notify)) return; - } - } - - currentState = newState; - debug.log('[{0}] {1} -> {2}', reason, oldState, newState); - - // 跳转后 - for (i = 0; i < handlers.length; i++) { - handler = handlers[i]; - if (handlerConditionMatch(handler.condition, 'after', oldState, newState)) { - handler.apply(null, notify); - } - } - return currentState; - }; - - /** - * 返回当前状态 - * @return {string} - */ - this.state = function() { - return currentState; - }; - - /** - * 添加状态跳转监视器 - * - * @param {string} condition - * 监视的时机 - * "* => *" (默认) - * - * @param {Function} handler - * 监视函数,当状态跳转的时候,会接收三个参数 - * * from - 跳转前的状态 - * * to - 跳转后的状态 - * * reason - 跳转的原因 - */ - this.when = function(condition, handler) { - if (arguments.length == 1) { - handler = condition; - condition = '* -> *'; - } - - var when, resolved, exit, enter; - - resolved = condition.split(BEFORE_ARROW); - if (resolved.length == 2) { - when = 'before'; - } else { - resolved = condition.split(AFTER_ARROW); - if (resolved.length == 2) { - when = 'after'; - } - } - if (!when) throw new Error('Illegal fsm condition: ' + condition); - - exit = resolved[0]; - enter = resolved[1]; - - handler.condition = { - when: when, - exit: exit, - enter: enter - }; - - handlers.push(handler); - }; - } - - function FSMRumtime() { - this.fsm = new FSM('normal'); - } - - return module.exports = FSMRumtime; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/history.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/history.js deleted file mode 100644 index e95c1619..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/history.js +++ /dev/null @@ -1,133 +0,0 @@ -/** - * @fileOverview - * - * 历史管理 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - - -define(function(require, exports, module) { - var jsonDiff = require('../tool/jsondiff'); - - function HistoryRuntime() { - var minder = this.minder; - var hotbox = this.hotbox; - - var MAX_HISTORY = 100; - - var lastSnap; - var patchLock; - var undoDiffs; - var redoDiffs; - - function reset() { - undoDiffs = []; - redoDiffs = []; - lastSnap = minder.exportJson(); - } - - function makeUndoDiff() { - var headSnap = minder.exportJson(); - var diff = jsonDiff(headSnap, lastSnap); - if (diff.length) { - undoDiffs.push(diff); - while (undoDiffs.length > MAX_HISTORY) { - undoDiffs.shift(); - } - lastSnap = headSnap; - return true; - } - } - - function makeRedoDiff() { - var revertSnap = minder.exportJson(); - redoDiffs.push(jsonDiff(revertSnap, lastSnap)); - lastSnap = revertSnap; - } - - function undo() { - patchLock = true; - var undoDiff = undoDiffs.pop(); - if (undoDiff) { - minder.applyPatches(undoDiff); - makeRedoDiff(); - } - patchLock = false; - } - - function redo() { - patchLock = true; - var redoDiff = redoDiffs.pop(); - if (redoDiff) { - minder.applyPatches(redoDiff); - makeUndoDiff(); - } - patchLock = false; - } - - function changed() { - if (patchLock) return; - if (makeUndoDiff()) redoDiffs = []; - } - - function hasUndo() { - return !!undoDiffs.length; - } - - function hasRedo() { - return !!redoDiffs.length; - } - - function updateSelection(e) { - if (!patchLock) return; - var patch = e.patch; - switch (patch.express) { - case 'node.add': - minder.select(patch.node.getChild(patch.index), true); - break; - case 'node.remove': - case 'data.replace': - case 'data.remove': - case 'data.add': - minder.select(patch.node, true); - break; - } - } - - this.history = { - reset: reset, - undo: undo, - redo: redo, - hasUndo: hasUndo, - hasRedo: hasRedo - }; - reset(); - minder.on('contentchange', changed); - minder.on('import', reset); - minder.on('patch', updateSelection); - - var main = hotbox.state('main'); - main.button({ - position: 'top', - label: '撤销', - key: 'Ctrl + Z', - enable: hasUndo, - action: undo, - next: 'idle' - }); - main.button({ - position: 'top', - label: '重做', - key: 'Ctrl + Y', - enable: hasRedo, - action: redo, - next: 'idle' - }); - } - - window.diff = jsonDiff; - - return module.exports = HistoryRuntime; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/hotbox.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/hotbox.js deleted file mode 100644 index 568b9028..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/hotbox.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @fileOverview - * - * 热盒 Runtime - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function (require, exports, module) { - var Hotbox = require('../hotbox'); - - function HotboxRuntime() { - var fsm = this.fsm; - var minder = this.minder; - var receiver = this.receiver; - var container = this.container; - - if (minder.preventEdit) { - return; - } - - var hotbox = new Hotbox(container); - hotbox.setParentFSM(fsm); - fsm.when('normal -> hotbox', function (exit, enter, reason) { - if (minder.preventEdit) { - return; - } - - var node = minder.getSelectedNode(); - var position; - if (node) { - var box = node.getRenderBox(); - position = { - x: box.cx, - y: box.cy, - }; - } - hotbox.active('main', position); - }); - fsm.when('normal -> normal', function (exit, enter, reason, e) { - if (reason == 'shortcut-handle') { - var handleResult = hotbox.dispatch(e); - if (handleResult) { - e.preventDefault(); - } else { - minder.dispatchKeyEvent(e); - } - } - }); - fsm.when('modal -> normal', function (exit, enter, reason, e) { - if (reason == 'import-text-finish') { - receiver.element.focus(); - } - }); - this.hotbox = hotbox; - } - - return (module.exports = HotboxRuntime); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/input.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/input.js deleted file mode 100644 index 783d9857..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/input.js +++ /dev/null @@ -1,373 +0,0 @@ -/** - * @fileOverview - * - * 文本输入支持 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function (require, exports, module) { - require('../tool/innertext'); - - var Debug = require('../tool/debug'); - var debug = new Debug('input'); - - function InputRuntime() { - var fsm = this.fsm; - var minder = this.minder; - var hotbox = this.hotbox; - var receiver = this.receiver; - var receiverElement = receiver.element; - var isGecko = window.kity.Browser.gecko; - - if (minder.disableEdit) { - return; - } - - // setup everything to go - setupReciverElement(); - setupFsm(); - setupHotbox(); - // expose editText() - this.editText = editText; - // listen the fsm changes, make action. - function setupFsm() { - // when jumped to input mode, enter - fsm.when('* -> input', enterInputMode); - // when exited, commit or exit depends on the exit reason - fsm.when('input -> *', function (exit, enter, reason) { - switch (reason) { - case 'input-cancel': - return exitInputMode(); - - case 'input-commit': - default: - return commitInputResult(); - } - }); - // lost focus to commit - receiver.onblur(function (e) { - if (fsm.state() == 'input') { - fsm.jump('normal', 'input-commit'); - } - }); - minder.on('beforemousedown', function () { - if (fsm.state() == 'input') { - fsm.jump('normal', 'input-commit'); - } - }); - minder.on('dblclick', function () { - if (minder.getSelectedNode() && minder._status !== 'readonly') { - editText(); - } - }); - } - // let the receiver follow the current selected node position - function setupReciverElement() { - if (debug.flaged) { - receiverElement.classList.add('debug'); - } - receiverElement.onmousedown = function (e) { - // e.stopPropagation(); - }; - minder.on('layoutallfinish viewchange viewchanged selectionchange', function (e) { - // viewchange event is too frequenced, lazy it - if (e.type == 'viewchange' && fsm.state() != 'input') return; - updatePosition(); - }); - updatePosition(); - } - // edit entrance in hotbox - function setupHotbox() { - hotbox.state('main').button({ - position: 'center', - label: '编辑', - key: 'F2', - enable: function () { - return minder.queryCommandState('text') != -1; - }, - action: editText, - }); - } - /** - * 增加对字体的鉴别,以保证用户在编辑状态ctrl/cmd + b/i所触发的加粗斜体与显示一致 - * @editor Naixor - * @Date 2015-12-2 - */ - // edit for the selected node - function editText() { - if (minder.preventEdit) { - return; - } - - var node = minder.getSelectedNode(); - if (!node) { - return; - } - var textContainer = receiverElement; - receiverElement.innerText = ''; - if (node.getData('font-weight') === 'bold') { - var b = document.createElement('b'); - textContainer.appendChild(b); - textContainer = b; - } - if (node.getData('font-style') === 'italic') { - var i = document.createElement('i'); - textContainer.appendChild(i); - textContainer = i; - } - textContainer.innerText = minder.queryCommandValue('text'); - if (isGecko) { - receiver.fixFFCaretDisappeared(); - } - fsm.jump('input', 'input-request'); - receiver.selectAll(); - } - /** - * 增加对字体的鉴别,以保证用户在编辑状态ctrl/cmd + b/i所触发的加粗斜体与显示一致 - * @editor Naixor - * @Date 2015-12-2 - */ - function enterInputMode() { - if (minder.preventEdit) { - return; - } - - var node = minder.getSelectedNode(); - if (node) { - var fontSize = node.getData('font-size') || node.getStyle('font-size'); - receiverElement.style.fontSize = fontSize + 'px'; - receiverElement.style.minWidth = 0; - receiverElement.style.minWidth = receiverElement.clientWidth + 'px'; - receiverElement.style.fontWeight = node.getData('font-weight') || ''; - receiverElement.style.fontStyle = node.getData('font-style') || ''; - receiverElement.classList.add('input'); - receiverElement.focus(); - } - } - /** - * 按照文本提交操作处理 - * @Desc: 从其他节点复制文字到另一个节点时部分浏览器(chrome)会自动包裹一个span标签,这样试用一下逻辑出来的就不是text节点二是span节点因此导致undefined的情况发生 - * @Warning: 下方代码使用[].slice.call来将HTMLDomCollection处理成为Array,ie8及以下会有问题 - * @Editor: Naixor - * @Date: 2015.9.16 - */ - function commitInputText(textNodes) { - var text = ''; - var TAB_CHAR = '\t', - ENTER_CHAR = '\n', - STR_CHECK = /\S/, - SPACE_CHAR = ' ', // 针对FF,SG,BD,LB,IE等浏览器下SPACE的charCode存在为32和160的情况做处理 - SPACE_CHAR_REGEXP = new RegExp('( |' + String.fromCharCode(160) + ')'), - BR = document.createElement('br'); - var isBold = false, - isItalic = false; - for (var str, _divChildNodes, space_l, space_num, tab_num, i = 0, l = textNodes.length; i < l; i++) { - str = textNodes[i]; - switch (Object.prototype.toString.call(str)) { - // 正常情况处理 - case '[object HTMLBRElement]': { - text += ENTER_CHAR; - break; - } - - case '[object Text]': { - // SG下会莫名其妙的加上 影响后续判断,干掉! - /** - * FF下的wholeText会导致如下问题: - * |123| -> 在一个节点中输入一段字符,此时TextNode为[#Text 123] - * 提交并重新编辑,在后面追加几个字符 - * |123abc| -> 此时123为一个TextNode为[#Text 123, #Text abc],但是对这两个任意取值wholeText均为全部内容123abc - * 上述BUG仅存在在FF中,故将wholeText更改为textContent - */ - str = str.textContent.replace(' ', ' '); - if (!STR_CHECK.test(str)) { - space_l = str.length; - while (space_l--) { - if (SPACE_CHAR_REGEXP.test(str[space_l])) { - text += SPACE_CHAR; - } else if (str[space_l] === TAB_CHAR) { - text += TAB_CHAR; - } - } - } else { - text += str; - } - break; - } - - // ctrl + b/i 会给字体加上/标签来实现黑体和斜体 - case '[object HTMLElement]': { - switch (str.nodeName) { - case 'B': { - isBold = true; - break; - } - - case 'I': { - isItalic = true; - break; - } - - default: { - } - } - [].splice.apply(textNodes, [i, 1].concat([].slice.call(str.childNodes))); - l = textNodes.length; - i--; - break; - } - - // 被增加span标签的情况会被处理成正常情况并会推交给上面处理 - case '[object HTMLSpanElement]': { - [].splice.apply(textNodes, [i, 1].concat([].slice.call(str.childNodes))); - l = textNodes.length; - i--; - break; - } - - // 若标签为image标签,则判断是否为合法url,是将其加载进来 - case '[object HTMLImageElement]': { - if (str.src) { - if (/http(|s):\/\//.test(str.src)) { - minder.execCommand('Image', str.src, str.alt); - } else { - } - } - break; - } - - // 被增加div标签的情况会被处理成正常情况并会推交给上面处理 - case '[object HTMLDivElement]': { - _divChildNodes = []; - for (var di = 0, l = str.childNodes.length; di < l; di++) { - _divChildNodes.push(str.childNodes[di]); - } - _divChildNodes.push(BR); - [].splice.apply(textNodes, [i, 1].concat(_divChildNodes)); - l = textNodes.length; - i--; - break; - } - - default: { - if (str && str.childNodes.length) { - _divChildNodes = []; - for (var di = 0, l = str.childNodes.length; di < l; di++) { - _divChildNodes.push(str.childNodes[di]); - } - _divChildNodes.push(BR); - [].splice.apply(textNodes, [i, 1].concat(_divChildNodes)); - l = textNodes.length; - i--; - } else { - if (str && str.textContent !== undefined) { - text += str.textContent; - } else { - text += ''; - } - } - } - } - } - text = text.replace(/^\n*|\n*$/g, ''); - text = text.replace(new RegExp('(\n|\r|\n\r)( |' + String.fromCharCode(160) + '){4}', 'g'), '$1\t'); - minder.getSelectedNode().setText(text); - if (isBold) { - minder.queryCommandState('bold') || minder.execCommand('bold'); - } else { - minder.queryCommandState('bold') && minder.execCommand('bold'); - } - if (isItalic) { - minder.queryCommandState('italic') || minder.execCommand('italic'); - } else { - minder.queryCommandState('italic') && minder.execCommand('italic'); - } - exitInputMode(); - return text; - } - /** - * 判断节点的文本信息是否是 - * @Desc: 从其他节点复制文字到另一个节点时部分浏览器(chrome)会自动包裹一个span标签,这样使用以下逻辑出来的就不是text节点二是span节点因此导致undefined的情况发生 - * @Notice: 此处逻辑应该拆分到 kityminder-core/core/data中去,单独增加一个对某个节点importJson的事件 - * @Editor: Naixor - * @Date: 2015.9.16 - */ - function commitInputNode(node, text) { - try { - minder.decodeData('text', text).then(function (json) { - function importText(node, json, minder) { - var data = json.data; - node.setText(data.text || ''); - var childrenTreeData = json.children || []; - for (var i = 0; i < childrenTreeData.length; i++) { - var childNode = minder.createNode(null, node); - importText(childNode, childrenTreeData[i], minder); - } - return node; - } - importText(node, json, minder); - minder.fire('contentchange'); - minder.getRoot().renderTree(); - minder.layout(300); - }); - } catch (e) { - minder.fire('contentchange'); - minder.getRoot().renderTree(); - // 无法被转换成脑图节点则不处理 - if (e.toString() !== 'Error: Invalid local format') { - throw e; - } - } - } - function commitInputResult() { - /** - * @Desc: 进行如下处理: - * 根据用户的输入判断是否生成新的节点 - * fix #83 https://github.com/fex-team/kityminder-editor/issues/83 - * @Editor: Naixor - * @Date: 2015.9.16 - */ - var textNodes = [].slice.call(receiverElement.childNodes); - /** - * @Desc: 增加setTimeout的原因:ie下receiverElement.innerHTML=""会导致后 - * 面commitInputText中使用textContent报错,不要问我什么原因! - * @Editor: Naixor - * @Date: 2015.12.14 - */ - setTimeout(function () { - // 解决过大内容导致SVG窜位问题 - receiverElement.innerHTML = ''; - }, 0); - var node = minder.getSelectedNode(); - textNodes = commitInputText(textNodes); - commitInputNode(node, textNodes); - if (node.type == 'root') { - var rootText = minder.getRoot().getText(); - minder.fire('initChangeRoot', { - text: rootText, - }); - } - } - function exitInputMode() { - receiverElement.classList.remove('input'); - receiver.selectAll(); - } - function updatePosition() { - var planed = updatePosition; - var focusNode = minder.getSelectedNode(); - if (!focusNode) return; - if (!planed.timer) { - planed.timer = setTimeout(function () { - var box = focusNode.getRenderBox('TextRenderer'); - receiverElement.style.left = Math.round(box.x) + 'px'; - receiverElement.style.top = (debug.flaged ? Math.round(box.bottom + 30) : Math.round(box.y)) + 'px'; - //receiverElement.focus(); - planed.timer = 0; - }); - } - } - } - - return (module.exports = InputRuntime); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/jumping.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/jumping.js deleted file mode 100644 index 3a48446c..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/jumping.js +++ /dev/null @@ -1,193 +0,0 @@ -/** - * @fileOverview - * - * 根据按键控制状态机的跳转 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function (require, exports, module) { - var Hotbox = require('../hotbox'); - - // Nice: http://unixpapa.com/js/key.html - function isIntendToInput(e) { - if (e.ctrlKey || e.metaKey || e.altKey) return false; - - // a-zA-Z - if (e.keyCode >= 65 && e.keyCode <= 90) return true; - - // 0-9 以及其上面的符号 - if (e.keyCode >= 48 && e.keyCode <= 57) return true; - - // 小键盘区域 (除回车外) - if (e.keyCode != 108 && e.keyCode >= 96 && e.keyCode <= 111) return true; - - // 小键盘区域 (除回车外) - // @yinheli from pull request - if (e.keyCode != 108 && e.keyCode >= 96 && e.keyCode <= 111) return true; - - // 输入法 - if (e.keyCode == 229 || e.keyCode === 0) return true; - - return false; - } - /** - * @Desc: 下方使用receiver.enable()和receiver.disable()通过 - * 修改div contenteditable属性的hack来解决开启热核后依然无法屏蔽浏览器输入的bug; - * 特别: win下FF对于此种情况必须要先blur在focus才能解决,但是由于这样做会导致用户 - * 输入法状态丢失,因此对FF暂不做处理 - * @Editor: Naixor - * @Date: 2015.09.14 - */ - function JumpingRuntime() { - var fsm = this.fsm; - var minder = this.minder; - var receiver = this.receiver; - var container = this.container; - var receiverElement = receiver.element; - var hotbox = this.hotbox; - var compositionLock = false; - - // normal -> * - receiver.listen('normal', function (e) { - // 为了防止处理进入edit模式而丢失处理的首字母,此时receiver必须为enable - receiver.enable(); - // normal -> hotbox - if (e.is('Space')) { - e.preventDefault(); - // safari下Space触发hotbox,然而这时Space已在receiver上留下作案痕迹,因此抹掉 - if (kity.Browser.safari) { - receiverElement.innerHTML = ''; - } - return fsm.jump('hotbox', 'space-trigger'); - } - - /** - * check - * @editor Naixor - * @Date 2015-12-2 - */ - switch (e.type) { - case 'keydown': { - if (minder.getSelectedNode()) { - if (isIntendToInput(e)) { - return fsm.jump('input', 'user-input'); - } - } else { - receiverElement.innerHTML = ''; - } - // normal -> normal shortcut - fsm.jump('normal', 'shortcut-handle', e); - break; - } - case 'keyup': { - break; - } - default: { - } - } - }); - - // hotbox -> normal - receiver.listen('hotbox', function (e) { - receiver.disable(); - e.preventDefault(); - var handleResult = hotbox.dispatch(e); - if (hotbox.state() == Hotbox.STATE_IDLE && fsm.state() == 'hotbox') { - return fsm.jump('normal', 'hotbox-idle'); - } - }); - - // input => normal - receiver.listen('input', function (e) { - receiver.enable(); - if (e.type == 'keydown') { - if (e.is('Enter')) { - e.preventDefault(); - return fsm.jump('normal', 'input-commit'); - } - if (e.is('Esc')) { - e.preventDefault(); - return fsm.jump('normal', 'input-cancel'); - } - if (e.is('Tab') || e.is('Shift + Tab')) { - e.preventDefault(); - } - } else if (e.type == 'keyup' && e.is('Esc')) { - e.preventDefault(); - if (!compositionLock) { - return fsm.jump('normal', 'input-cancel'); - } - } else if (e.type == 'compositionstart') { - compositionLock = true; - } else if (e.type == 'compositionend') { - setTimeout(function () { - compositionLock = false; - }); - } - }); - - ////////////////////////////////////////////// - /// 右键呼出热盒 - /// 判断的标准是:按下的位置和结束的位置一致 - ////////////////////////////////////////////// - var downX, downY; - var MOUSE_RB = 2; // 右键 - - container.addEventListener( - 'mousedown', - function (e) { - if (e.button == MOUSE_RB) { - e.preventDefault(); - } - if (fsm.state() == 'hotbox') { - hotbox.active(Hotbox.STATE_IDLE); - fsm.jump('normal', 'blur'); - } else if (fsm.state() == 'normal' && e.button == MOUSE_RB) { - downX = e.clientX; - downY = e.clientY; - } - }, - false - ); - - container.addEventListener( - 'mousewheel', - function (e) { - if (fsm.state() == 'hotbox') { - hotbox.active(Hotbox.STATE_IDLE); - fsm.jump('normal', 'mousemove-blur'); - } - }, - false - ); - - container.addEventListener('contextmenu', function (e) { - e.preventDefault(); - }); - - container.addEventListener( - 'mouseup', - function (e) { - if (fsm.state() != 'normal') { - return; - } - if (e.button != MOUSE_RB || e.clientX != downX || e.clientY != downY) { - return; - } - if (!minder.getSelectedNode()) { - return; - } - fsm.jump('hotbox', 'content-menu'); - }, - false - ); - - // 阻止热盒事件冒泡,在热盒正确执行前导致热盒关闭 - hotbox.$element.addEventListener('mousedown', function (e) { - e.stopPropagation(); - }); - } - - return (module.exports = JumpingRuntime); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/minder.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/minder.js deleted file mode 100644 index 7a0d85a4..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/minder.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @fileOverview - * - * 脑图示例运行时 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function(require, exports, module) { - var Minder = require('../minder'); - - function MinderRuntime() { - - // 不使用 kityminder 的按键处理,由 ReceiverRuntime 统一处理 - var minder = new Minder({ - enableKeyReceiver: false, - enableAnimation: true - }); - - // 渲染,初始化 - minder.renderTo(this.selector); - minder.setTheme(null); - minder.select(minder.getRoot(), true); - minder.execCommand('name', '中心主题'); - - // 导出给其它 Runtime 使用 - this.minder = minder; - } - - return module.exports = MinderRuntime; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/node.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/node.js deleted file mode 100644 index b8bf9a66..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/node.js +++ /dev/null @@ -1,112 +0,0 @@ -define(function(require, exports, module) { - - function NodeRuntime() { - var runtime = this; - var minder = this.minder; - var hotbox = this.hotbox; - var fsm = this.fsm; - - var main = hotbox.state('main'); - - var buttons = [ - '前移:Alt+Up:ArrangeUp', - '下级:Tab|Insert:AppendChildNode', - '同级:Enter:AppendSiblingNode', - '后移:Alt+Down:ArrangeDown', - '删除:Delete|Backspace:RemoveNode', - '上级:Shift+Tab|Shift+Insert:AppendParentNode' - //'全选:Ctrl+A:SelectAll' - ]; - - var AppendLock = 0; - - buttons.forEach(function(button) { - var parts = button.split(':'); - var label = parts.shift(); - var key = parts.shift(); - var command = parts.shift(); - main.button({ - position: 'ring', - label: label, - key: key, - action: function() { - if (command.indexOf('Append') === 0) { - AppendLock++; - minder.execCommand(command, '分支主题'); - - // provide in input runtime - function afterAppend () { - if (!--AppendLock) { - runtime.editText(); - } - minder.off('layoutallfinish', afterAppend); - } - minder.on('layoutallfinish', afterAppend); - } else { - minder.execCommand(command); - fsm.jump('normal', 'command-executed'); - } - }, - enable: function() { - return minder.queryCommandState(command) != -1; - } - }); - }); - - main.button({ - position: 'bottom', - label: '导入节点', - key: 'Alt + V', - enable: function() { - var selectedNodes = minder.getSelectedNodes(); - return selectedNodes.length == 1; - }, - action: importNodeData, - next: 'idle' - }); - - main.button({ - position: 'bottom', - label: '导出节点', - key: 'Alt + C', - enable: function() { - var selectedNodes = minder.getSelectedNodes(); - return selectedNodes.length == 1; - }, - action: exportNodeData, - next: 'idle' - }); - - function importNodeData() { - minder.fire('importNodeData'); - } - - function exportNodeData() { - minder.fire('exportNodeData'); - } - - //main.button({ - // position: 'ring', - // key: '/', - // action: function(){ - // if (!minder.queryCommandState('expand')) { - // minder.execCommand('expand'); - // } else if (!minder.queryCommandState('collapse')) { - // minder.execCommand('collapse'); - // } - // }, - // enable: function() { - // return minder.queryCommandState('expand') != -1 || minder.queryCommandState('collapse') != -1; - // }, - // beforeShow: function() { - // if (!minder.queryCommandState('expand')) { - // this.$button.children[0].innerHTML = '展开'; - // } else { - // this.$button.children[0].innerHTML = '收起'; - // } - // } - //}) - } - - return module.exports = NodeRuntime; -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/priority.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/priority.js deleted file mode 100644 index 3b91dcc1..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/priority.js +++ /dev/null @@ -1,51 +0,0 @@ -define(function(require, exports, module){ - - function PriorityRuntime() { - var minder = this.minder; - var hotbox = this.hotbox; - - var main = hotbox.state('main'); - - main.button({ - position: 'top', - label: '优先级', - key: 'P', - next: 'priority', - enable: function() { - return minder.queryCommandState('priority') != -1; - } - }); - - var priority = hotbox.state('priority'); - '123456789'.replace(/./g, function(p) { - priority.button({ - position: 'ring', - label: 'P' + p, - key: p, - action: function() { - minder.execCommand('Priority', p); - } - }); - }); - - priority.button({ - position: 'center', - label: '移除', - key: 'Del', - action: function() { - minder.execCommand('Priority', 0); - } - }); - - priority.button({ - position: 'top', - label: '返回', - key: 'esc', - next: 'back' - }); - - } - - return module.exports = PriorityRuntime; - -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/progress.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/progress.js deleted file mode 100644 index 3ce7d30c..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/progress.js +++ /dev/null @@ -1,52 +0,0 @@ -define(function(require, exports, module){ - - function ProgressRuntime() { - var minder = this.minder; - var hotbox = this.hotbox; - - var main = hotbox.state('main'); - - main.button({ - position: 'top', - label: '进度', - key: 'G', - next: 'progress', - enable: function() { - return minder.queryCommandState('progress') != -1; - } - }); - - var progress = hotbox.state('progress'); - '012345678'.replace(/./g, function(p) { - progress.button({ - position: 'ring', - label: 'G' + p, - key: p, - action: function() { - minder.execCommand('Progress', parseInt(p) + 1); - } - }); - }); - - progress.button({ - position: 'center', - label: '移除', - key: 'Del', - action: function() { - minder.execCommand('Progress', 0); - } - }); - - progress.button({ - position: 'top', - label: '返回', - key: 'esc', - next: 'back' - }); - - - } - - return module.exports = ProgressRuntime; - -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/receiver.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/receiver.js deleted file mode 100644 index 1dc96e22..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/runtime/receiver.js +++ /dev/null @@ -1,143 +0,0 @@ -/** - * @fileOverview - * - * 键盘事件接收/分发器 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - -define(function (require, exports, module) { - var key = require('../tool/key'); - - function ReceiverRuntime() { - var fsm = this.fsm; - var minder = this.minder; - var me = this; - - // 接收事件的 div - var element = document.createElement('div'); - element.contentEditable = true; - /** - * @Desc: 增加tabindex属性使得element的contenteditable不管是trur还是false都能有focus和blur事件 - * @Editor: Naixor - * @Date: 2015.09.14 - */ - element.setAttribute('tabindex', -1); - element.classList.add('receiver'); - element.onkeydown = element.onkeypress = element.onkeyup = dispatchKeyEvent; - element.addEventListener('compositionstart', dispatchKeyEvent); - // element.addEventListener('compositionend', dispatchKeyEvent); - this.container.appendChild(element); - - // receiver 对象 - var receiver = { - element: element, - selectAll: function () { - // 保证有被选中的 - if (!element.innerHTML) element.innerHTML = ' '; - var range = document.createRange(); - var selection = window.getSelection(); - range.selectNodeContents(element); - selection.removeAllRanges(); - selection.addRange(range); - element.focus(); - }, - /** - * @Desc: 增加enable和disable方法用于解决热核态的输入法屏蔽问题 - * @Editor: Naixor - * @Date: 2015.09.14 - */ - enable: function () { - element.setAttribute('contenteditable', true); - }, - disable: function () { - element.setAttribute('contenteditable', false); - }, - /** - * @Desc: hack FF下div contenteditable的光标丢失BUG - * @Editor: Naixor - * @Date: 2015.10.15 - */ - fixFFCaretDisappeared: function () { - element.removeAttribute('contenteditable'); - element.setAttribute('contenteditable', 'true'); - element.blur(); - element.focus(); - }, - /** - * 以此事件代替通过mouse事件来判断receiver丢失焦点的事件 - * @editor Naixor - * @Date 2015-12-2 - */ - onblur: function (handler) { - element.onblur = handler; - }, - }; - receiver.selectAll(); - - minder.on('beforemousedown', receiver.selectAll); - minder.on('receiverfocus', receiver.selectAll); - minder.on('readonly', function () { - // 屏蔽minder的事件接受,删除receiver和hotbox - minder.disable(); - editor.receiver.element.parentElement.removeChild(editor.receiver.element); - editor.hotbox.$container.removeChild(editor.hotbox.$element); - }); - - // 侦听器,接收到的事件会派发给所有侦听器 - var listeners = []; - - // 侦听指定状态下的事件,如果不传 state,侦听所有状态 - receiver.listen = function (state, listener) { - if (arguments.length == 1) { - listener = state; - state = '*'; - } - listener.notifyState = state; - listeners.push(listener); - }; - - function dispatchKeyEvent(e) { - e.is = function (keyExpression) { - var subs = keyExpression.split('|'); - for (var i = 0; i < subs.length; i++) { - if (key.is(this, subs[i])) return true; - } - return false; - }; - var listener, jumpState; - for (var i = 0; i < listeners.length; i++) { - listener = listeners[i]; - // 忽略不在侦听状态的侦听器 - if (listener.notifyState != '*' && listener.notifyState != fsm.state()) { - continue; - } - - /** - * - * 对于所有的侦听器,只允许一种处理方式:跳转状态。 - * 如果侦听器确定要跳转,则返回要跳转的状态。 - * 每个事件只允许一个侦听器进行状态跳转 - * 跳转动作由侦听器自行完成(因为可能需要在跳转时传递 reason),返回跳转结果即可。 - * 比如: - * - * ```js - * receiver.listen('normal', function(e) { - * if (isSomeReasonForJumpState(e)) { - * return fsm.jump('newstate', e); - * } - * }); - * ``` - */ - if (listener.call(null, e)) { - return; - } - } - } - - this.receiver = receiver; - } - - return (module.exports = ReceiverRuntime); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/debug.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/debug.js deleted file mode 100644 index 53a47734..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/debug.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @fileOverview - * - * 支持各种调试后门 - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ -define(function (require, exports, module) { - var format = require('./format'); - - function noop() {} - - function stringHash(str) { - var hash = 0; - for (var i = 0; i < str.length; i++) { - hash += str.charCodeAt(i); - } - return hash; - } - - /* global console */ - function Debug(flag) { - if (typeof window === 'undefined') return; - - var debugMode = (this.flaged = window.location.search.indexOf(flag) != -1); - - if (debugMode) { - var h = stringHash(flag) % 360; - - var flagStyle = format( - 'background: hsl({0}, 50%, 80%); ' + - 'color: hsl({0}, 100%, 30%); ' + - 'padding: 2px 3px; ' + - 'margin: 1px 3px 0 0;' + - 'border-radius: 2px;', - h - ); - - var textStyle = 'background: none; color: black;'; - this.log = function () { - var output = format.apply(null, arguments); - console.log(format('%c{0}%c{1}', flag, output), flagStyle, textStyle); - }; - } else { - this.log = noop; - } - } - - return (module.exports = Debug); -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/format.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/format.js deleted file mode 100644 index 2e168dc2..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/format.js +++ /dev/null @@ -1,11 +0,0 @@ -define(function(require, exports, module) { - function format(template, args) { - if (typeof(args) != 'object') { - args = [].slice.call(arguments, 1); - } - return String(template).replace(/\{(\w+)\}/ig, function(match, $key) { - return args[$key] || $key; - }); - } - return module.exports = format; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/innertext.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/innertext.js deleted file mode 100644 index 912fdb9c..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/innertext.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @fileOverview - * - * innerText polyfill - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - - -define(function(require, exports, module) { - if ((!('innerText' in document.createElement('a'))) && ('getSelection' in window)) { - HTMLElement.prototype.__defineGetter__('innerText', function() { - var selection = window.getSelection(), - ranges = [], - str, i; - - // Save existing selections. - for (i = 0; i < selection.rangeCount; i++) { - ranges[i] = selection.getRangeAt(i); - } - - // Deselect everything. - selection.removeAllRanges(); - - // Select `el` and all child nodes. - // 'this' is the element .innerText got called on - selection.selectAllChildren(this); - - // Get the string representation of the selected nodes. - str = selection.toString(); - - // Deselect everything. Again. - selection.removeAllRanges(); - - // Restore all formerly existing selections. - for (i = 0; i < ranges.length; i++) { - selection.addRange(ranges[i]); - } - - // Oh look, this is what we wanted. - // String representation of the element, close to as rendered. - return str; - }); - HTMLElement.prototype.__defineSetter__('innerText', function(text) { - /** - * @Desc: 解决FireFox节点内容删除后text为null,出现报错的问题 - * @Editor: Naixor - * @Date: 2015.9.16 - */ - this.innerHTML = (text || '').replace(//g, '>').replace(/\n/g, '
'); - }); - } -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/jsondiff.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/jsondiff.js deleted file mode 100644 index dac36e1c..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/jsondiff.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @fileOverview - * - * - * - * @author: techird - * @copyright: Baidu FEX, 2014 - */ - - -define(function(require, exports, module) { - /*! - * https://github.com/Starcounter-Jack/Fast-JSON-Patch - * json-patch-duplex.js 0.5.0 - * (c) 2013 Joachim Wester - * MIT license - */ - - var _objectKeys = (function () { - if (Object.keys) - return Object.keys; - - return function (o) { - var keys = []; - for (var i in o) { - if (o.hasOwnProperty(i)) { - keys.push(i); - } - } - return keys; - }; - })(); - function escapePathComponent(str) { - if (str.indexOf('/') === -1 && str.indexOf('~') === -1) - return str; - return str.replace(/~/g, '~0').replace(/\//g, '~1'); - } - function deepClone(obj) { - if (typeof obj === "object") { - return JSON.parse(JSON.stringify(obj)); - } else { - return obj; - } - } - - // Dirty check if obj is different from mirror, generate patches and update mirror - function _generate(mirror, obj, patches, path) { - var newKeys = _objectKeys(obj); - var oldKeys = _objectKeys(mirror); - var changed = false; - var deleted = false; - - for (var t = oldKeys.length - 1; t >= 0; t--) { - var key = oldKeys[t]; - var oldVal = mirror[key]; - if (obj.hasOwnProperty(key)) { - var newVal = obj[key]; - if (typeof oldVal == "object" && oldVal != null && typeof newVal == "object" && newVal != null) { - _generate(oldVal, newVal, patches, path + "/" + escapePathComponent(key)); - } else { - if (oldVal != newVal) { - changed = true; - patches.push({ op: "replace", path: path + "/" + escapePathComponent(key), value: deepClone(newVal) }); - } - } - } else { - patches.push({ op: "remove", path: path + "/" + escapePathComponent(key) }); - deleted = true; // property has been deleted - } - } - - if (!deleted && newKeys.length == oldKeys.length) { - return; - } - - for (var t = 0; t < newKeys.length; t++) { - var key = newKeys[t]; - if (!mirror.hasOwnProperty(key)) { - patches.push({ op: "add", path: path + "/" + escapePathComponent(key), value: deepClone(obj[key]) }); - } - } - } - - function compare(tree1, tree2) { - var patches = []; - _generate(tree1, tree2, patches, ''); - return patches; - } - - return module.exports = compare; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/key.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/key.js deleted file mode 100644 index 5a403b9c..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/key.js +++ /dev/null @@ -1,69 +0,0 @@ -define(function(require, exports, module) { - var keymap = require('./keymap'); - - var CTRL_MASK = 0x1000; - var ALT_MASK = 0x2000; - var SHIFT_MASK = 0x4000; - - function hash(unknown) { - if (typeof(unknown) == 'string') { - return hashKeyExpression(unknown); - } - return hashKeyEvent(unknown); - } - function is(a, b) { - return a && b && hash(a) == hash(b); - } - exports.hash = hash; - exports.is = is; - - - function hashKeyEvent(keyEvent) { - var hashCode = 0; - if (keyEvent.ctrlKey || keyEvent.metaKey) { - hashCode |= CTRL_MASK; - } - if (keyEvent.altKey) { - hashCode |= ALT_MASK; - } - if (keyEvent.shiftKey) { - hashCode |= SHIFT_MASK; - } - // Shift, Control, Alt KeyCode ignored. - if ([16, 17, 18, 91].indexOf(keyEvent.keyCode) === -1) { - /** - * 解决浏览器输入法状态下对keyDown的keyCode判断不准确的问题,使用keyIdentifier, - * 可以解决chrome和safari下的各种问题,其他浏览器依旧有问题,然而那并不影响我们对特 - * 需判断的按键进行判断(比如Space在safari输入法态下就是229,其他的就不是) - * @editor Naixor - * @Date 2015-12-2 - */ - if (keyEvent.keyCode === 229 && keyEvent.keyIdentifier) { - return hashCode |= parseInt(keyEvent.keyIdentifier.substr(2), 16); - } - hashCode |= keyEvent.keyCode; - } - return hashCode; - } - - function hashKeyExpression(keyExpression) { - var hashCode = 0; - keyExpression.toLowerCase().split(/\s*\+\s*/).forEach(function(name) { - switch(name) { - case 'ctrl': - case 'cmd': - hashCode |= CTRL_MASK; - break; - case 'alt': - hashCode |= ALT_MASK; - break; - case 'shift': - hashCode |= SHIFT_MASK; - break; - default: - hashCode |= keymap[name]; - } - }); - return hashCode; - } -}); diff --git a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/keymap.js b/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/keymap.js deleted file mode 100644 index 0e587da5..00000000 --- a/packages/client/src/tiptap/wrappers/mind/kityminder/kity-editor/tool/keymap.js +++ /dev/null @@ -1,82 +0,0 @@ -define(function(require, exports, module) { - var keymap = { - - 'Shift': 16, - 'Control': 17, - 'Alt': 18, - 'CapsLock': 20, - - 'BackSpace': 8, - 'Tab': 9, - 'Enter': 13, - 'Esc': 27, - 'Space': 32, - - 'PageUp': 33, - 'PageDown': 34, - 'End': 35, - 'Home': 36, - - 'Insert': 45, - - 'Left': 37, - 'Up': 38, - 'Right': 39, - 'Down': 40, - - 'Direction': { - 37: 1, - 38: 1, - 39: 1, - 40: 1 - }, - - 'Del': 46, - - 'NumLock': 144, - - 'Cmd': 91, - 'CmdFF': 224, - 'F1': 112, - 'F2': 113, - 'F3': 114, - 'F4': 115, - 'F5': 116, - 'F6': 117, - 'F7': 118, - 'F8': 119, - 'F9': 120, - 'F10': 121, - 'F11': 122, - 'F12': 123, - - '`': 192, - '=': 187, - '-': 189, - - '/': 191, - '.': 190 - }; - - // 小写适配 - for (var key in keymap) { - if (keymap.hasOwnProperty(key)) { - keymap[key.toLowerCase()] = keymap[key]; - } - } - var aKeyCode = 65; - var aCharCode = 'a'.charCodeAt(0); - - // letters - 'abcdefghijklmnopqrstuvwxyz'.split('').forEach(function(letter) { - keymap[letter] = aKeyCode + (letter.charCodeAt(0) - aCharCode); - }); - - // numbers - var n = 9; - do { - keymap[n.toString()] = n + 48; - } while (--n); - - module.exports = keymap; -}); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/const.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/const.ts new file mode 100644 index 00000000..cd8f03ba --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/const.ts @@ -0,0 +1,9 @@ +export const LEFT = 0; +export const RIGHT = 1; +export const SIDE = 2; +export const DOWN = 3; + +export const GAP = 15; +export const PRIMARY_NODE_HORIZONTAL_GAP = 65; +export const PRIMARY_NODE_VERTICAL_GAP = 25; +export const TURNPOINT_R = 8; diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/customLink.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/customLink.ts new file mode 100644 index 00000000..34afd5f9 --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/customLink.ts @@ -0,0 +1,250 @@ +import { LinkDragMoveHelper, generateUUID, getArrowPoints, calcP1, calcP4 } from './utils/index'; +import { createSvgGroup } from './utils/svg'; + +// TODO Link label +export const createLink = function (from, to, isInitPaint, obj) { + const map = this.map.getBoundingClientRect(); + if (!from || !to) { + return; // not expand + } + const pfrom = from.getBoundingClientRect(); + const pto = to.getBoundingClientRect(); + const fromCenterX = (pfrom.x + pfrom.width / 2 - map.x) / this.scaleVal; + const fromCenterY = (pfrom.y + pfrom.height / 2 - map.y) / this.scaleVal; + const toCenterX = (pto.x + pto.width / 2 - map.x) / this.scaleVal; + const toCenterY = (pto.y + pto.height / 2 - map.y) / this.scaleVal; + + let p2x, p2y, p3x, p3y; + if (isInitPaint) { + p2x = fromCenterX + obj.delta1.x; + p2y = fromCenterY + obj.delta1.y; + p3x = toCenterX + obj.delta2.x; + p3y = toCenterY + obj.delta2.y; + } else { + if ((fromCenterY + toCenterY) / 2 - fromCenterY <= pfrom.height / 2) { + // the situation that two div is too close + p2x = (pfrom.x + pfrom.width - map.x) / this.scaleVal + 100; + p2y = fromCenterY; + p3x = (pto.x + pto.width - map.x) / this.scaleVal + 100; + p3y = toCenterY; + } else { + p2x = (fromCenterX + toCenterX) / 2; + p2y = (fromCenterY + toCenterY) / 2; + p3x = (fromCenterX + toCenterX) / 2; + p3y = (fromCenterY + toCenterY) / 2; + } + } + + const fromData = { + cx: fromCenterX, + cy: fromCenterY, + w: pfrom.width, + h: pfrom.height, + }; + const toData = { + cx: toCenterX, + cy: toCenterY, + w: pto.width, + h: pto.height, + }; + + const p1 = calcP1(fromData, p2x, p2y); + const p1x = p1.x; + const p1y = p1.y; + + const p4 = calcP4(toData, p3x, p3y); + const p4x = p4.x; + const p4y = p4.y; + + const arrowPoint = getArrowPoints(p3x, p3y, p4x, p4y); + + // TODO link lable + // const halfx = p1x / 8 + (p2x * 3) / 8 + (p3x * 3) / 8 + p4x / 8 + // const halfy = p1y / 8 + (p2y * 3) / 8 + (p3y * 3) / 8 + p4y / 8 + + const newSvgGroup = createSvgGroup( + `M ${p1x} ${p1y} C ${p2x} ${p2y} ${p3x} ${p3y} ${p4x} ${p4y}`, + `M ${arrowPoint.x1} ${arrowPoint.y1} L ${p4x} ${p4y} L ${arrowPoint.x2} ${arrowPoint.y2}` + ); + + let newLinkObj; + if (isInitPaint) { + newLinkObj = { + id: obj.id, + label: '', + from, + to, + delta1: { + x: p2x - fromCenterX, + y: p2y - fromCenterY, + }, + delta2: { + x: p3x - toCenterX, + y: p3y - toCenterY, + }, + }; + // overwrite + this.linkData[obj.id] = newLinkObj; + newSvgGroup.linkObj = newLinkObj; + newSvgGroup.dataset.linkid = obj.id; + } else { + newLinkObj = { + id: generateUUID(), + label: '', + from, + to, + delta1: { + x: p2x - fromCenterX, + y: p2y - fromCenterY, + }, + delta2: { + x: p3x - toCenterX, + y: p3y - toCenterY, + }, + }; + // new + this.linkData[newLinkObj.id] = newLinkObj; + newSvgGroup.linkObj = newLinkObj; + newSvgGroup.dataset.linkid = newLinkObj.id; + this.currentLink = newSvgGroup; + } + this.linkSvgGroup.appendChild(newSvgGroup); + if (!isInitPaint) { + this.showLinkController(p2x, p2y, p3x, p3y, newLinkObj, fromData, toData); + } +}; + +export const removeLink = function (linkSvg) { + let link; + if (linkSvg) { + link = linkSvg; + } else { + link = this.currentLink; + } + if (!link) return; + console.log(link); + this.hideLinkController(); + const id = link.linkObj.id; + console.log(id); + delete this.linkData[id]; + link.remove(); + link = null; +}; +export const selectLink = function (targetElement) { + this.currentLink = targetElement; + const obj = targetElement.linkObj; + const from = obj.from; + const to = obj.to; + + const map = this.map.getBoundingClientRect(); + const pfrom = from.getBoundingClientRect(); + const pto = to.getBoundingClientRect(); + const fromCenterX = (pfrom.x + pfrom.width / 2 - map.x) / this.scaleVal; + const fromCenterY = (pfrom.y + pfrom.height / 2 - map.y) / this.scaleVal; + const toCenterX = (pto.x + pto.width / 2 - map.x) / this.scaleVal; + const toCenterY = (pto.y + pto.height / 2 - map.y) / this.scaleVal; + + const fromData = { + cx: fromCenterX, + cy: fromCenterY, + w: pfrom.width, + h: pfrom.height, + }; + const toData = { + cx: toCenterX, + cy: toCenterY, + w: pto.width, + h: pto.height, + }; + + const p2x = fromCenterX + obj.delta1.x; + const p2y = fromCenterY + obj.delta1.y; + const p3x = toCenterX + obj.delta2.x; + const p3y = toCenterY + obj.delta2.y; + + this.showLinkController(p2x, p2y, p3x, p3y, obj, fromData, toData); +}; +export const hideLinkController = function () { + this.linkController.style.display = 'none'; + this.P2.style.display = 'none'; + this.P3.style.display = 'none'; +}; +export const showLinkController = function (p2x, p2y, p3x, p3y, linkObj, fromData, toData) { + this.linkController.style.display = 'initial'; + this.P2.style.display = 'initial'; + this.P3.style.display = 'initial'; + + const p1 = calcP1(fromData, p2x, p2y); + let p1x = p1.x; + let p1y = p1.y; + + const p4 = calcP4(toData, p3x, p3y); + let p4x = p4.x; + let p4y = p4.y; + + this.P2.style.cssText = `top:${p2y}px;left:${p2x}px;`; + this.P3.style.cssText = `top:${p3y}px;left:${p3x}px;`; + this.line1.setAttribute('x1', p1x); + this.line1.setAttribute('y1', p1y); + this.line1.setAttribute('x2', p2x); + this.line1.setAttribute('y2', p2y); + this.line2.setAttribute('x1', p3x); + this.line2.setAttribute('y1', p3y); + this.line2.setAttribute('x2', p4x); + this.line2.setAttribute('y2', p4y); + + if (this.helper1) { + this.helper1.destory(this.map); + this.helper2.destory(this.map); + } + + this.helper1 = new LinkDragMoveHelper(this.P2); + this.helper2 = new LinkDragMoveHelper(this.P3); + + this.helper1.init(this.map, (deltaX, deltaY) => { + /** + * user will control bezier with p2 & p3 + * p1 & p4 is depend on p2 & p3 + */ + p2x = p2x - deltaX / this.scaleVal; + p2y = p2y - deltaY / this.scaleVal; + + const p1 = calcP1(fromData, p2x, p2y); + p1x = p1.x; + p1y = p1.y; + + this.P2.style.top = p2y + 'px'; + this.P2.style.left = p2x + 'px'; + this.currentLink.children[0].setAttribute('d', `M ${p1x} ${p1y} C ${p2x} ${p2y} ${p3x} ${p3y} ${p4x} ${p4y}`); + this.line1.setAttribute('x1', p1x); + this.line1.setAttribute('y1', p1y); + this.line1.setAttribute('x2', p2x); + this.line1.setAttribute('y2', p2y); + linkObj.delta1.x = p2x - fromData.cx; + linkObj.delta1.y = p2y - fromData.cy; + }); + + this.helper2.init(this.map, (deltaX, deltaY) => { + p3x = p3x - deltaX / this.scaleVal; + p3y = p3y - deltaY / this.scaleVal; + + const p4 = calcP4(toData, p3x, p3y); + p4x = p4.x; + p4y = p4.y; + const arrowPoint = getArrowPoints(p3x, p3y, p4x, p4y); + + this.P3.style.top = p3y + 'px'; + this.P3.style.left = p3x + 'px'; + this.currentLink.children[0].setAttribute('d', `M ${p1x} ${p1y} C ${p2x} ${p2y} ${p3x} ${p3y} ${p4x} ${p4y}`); + this.currentLink.children[1].setAttribute( + 'd', + `M ${arrowPoint.x1} ${arrowPoint.y1} L ${p4x} ${p4y} L ${arrowPoint.x2} ${arrowPoint.y2}` + ); + this.line2.setAttribute('x1', p3x); + this.line2.setAttribute('y1', p3y); + this.line2.setAttribute('x2', p4x); + this.line2.setAttribute('y2', p4y); + linkObj.delta2.x = p3x - toData.cx; + linkObj.delta2.y = p3y - toData.cy; + }); +}; diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/i18n.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/i18n.ts new file mode 100644 index 00000000..92766f95 --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/i18n.ts @@ -0,0 +1,99 @@ +const cn = { + addChild: '插入子节点', + addParent: '插入父节点', + addSibling: '插入同级节点', + removeNode: '删除节点', + focus: '专注', + cancelFocus: '取消专注', + moveUp: '上移', + moveDown: '下移', + link: '连接', + clickTips: '请点击目标节点', + + font: '文字', + background: '背景', + tag: '标签', + icon: '图标', + tagsSeparate: '多个标签半角逗号分隔', + iconsSeparate: '多个图标半角逗号分隔', +}; +export default { + cn, + zh_CN: cn, + zh_TW: { + addChild: '插入子節點', + addParent: '插入父節點', + addSibling: '插入同級節點', + removeNode: '刪除節點', + focus: '專注', + cancelFocus: '取消專注', + moveUp: '上移', + moveDown: '下移', + link: '連接', + clickTips: '請點擊目標節點', + + font: '文字', + background: '背景', + tag: '標簽', + icon: '圖標', + tagsSeparate: '多個標簽半角逗號分隔', + iconsSeparate: '多個圖標半角逗號分隔', + }, + en: { + addChild: 'Add child', + addParent: 'Add parent', + addSibling: 'Add sibling', + removeNode: 'Remove node', + focus: 'Focus Mode', + cancelFocus: 'Cancel Focus Mode', + moveUp: 'Move up', + moveDown: 'Move down', + link: 'Link', + clickTips: 'Please click the target node', + + font: 'Font', + background: 'Background', + tag: 'Tag', + icon: 'Icon', + tagsSeparate: 'Separate tags by comma', + iconsSeparate: 'Separate icons by comma', + }, + ja: { + addChild: '子ノードを追加する', + addParent: '親ノードを追加します', + addSibling: '兄弟ノードを追加する', + removeNode: 'ノードを削除', + focus: '集中', + cancelFocus: '集中解除', + moveUp: '上へ移動', + moveDown: '下へ移動', + link: 'コネクト', + clickTips: 'ターゲットノードをクリックしてください', + + font: 'フォント', + background: 'バックグラウンド', + tag: 'タグ', + icon: 'アイコン', + tagsSeparate: '複数タグはカンマ区切り', + iconsSeparate: '複数アイコンはカンマ区切り', + }, + pt: { + addChild: 'Adicionar item filho', + addParent: 'Adicionar item pai', + addSibling: 'Adicionar item irmao', + removeNode: 'Remover item', + focus: 'Modo Foco', + cancelFocus: 'Cancelar Modo Foco', + moveUp: 'Mover para cima', + moveDown: 'Mover para baixo', + link: 'Link', + clickTips: 'Favor clicar no item alvo', + + font: 'Fonte', + background: 'Cor de fundo', + tag: 'Tag', + icon: 'Icone', + tagsSeparate: 'Separe tags por virgula', + iconsSeparate: 'Separe icones por virgula', + }, +}; diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/iconfont/iconfont.js b/packages/client/src/tiptap/wrappers/mind/mind-elixir/iconfont/iconfont.js new file mode 100644 index 00000000..b8ff4bda --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/iconfont/iconfont.js @@ -0,0 +1 @@ +!function(t){var c,l,a,e,o,i,n='',h=(h=document.getElementsByTagName("script"))[h.length-1].getAttribute("data-injectcss");if(h&&!t.__iconfont__svg__cssinject__){t.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(t){console&&console.log(t)}}function d(){o||(o=!0,a())}c=function(){var t,c,l,a;(a=document.createElement("div")).innerHTML=n,n=null,(l=a.getElementsByTagName("svg")[0])&&(l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.width=0,l.style.height=0,l.style.overflow="hidden",t=l,(c=document.body).firstChild?(a=t,(l=c.firstChild).parentNode.insertBefore(a,l)):c.appendChild(t))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(c,0):(l=function(){document.removeEventListener("DOMContentLoaded",l,!1),c()},document.addEventListener("DOMContentLoaded",l,!1)):document.attachEvent&&(a=c,e=t.document,o=!1,(i=function(){try{e.documentElement.doScroll("left")}catch(t){return void setTimeout(i,50)}d()})(),e.onreadystatechange=function(){"complete"==e.readyState&&(e.onreadystatechange=null,d())})}(window); \ No newline at end of file diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/index.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/index.ts new file mode 100644 index 00000000..0e680455 --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/index.ts @@ -0,0 +1,431 @@ +import { LEFT, RIGHT, SIDE } from './const'; +import { isMobile, addParentLink, getObjById, generateUUID, generateNewObj } from './utils/index'; +import { + findEle, + createInputDiv, + layout, + Topic, + createChildren, + createGroup, + createTop, + createTopic, +} from './utils/dom'; +import { createLinkSvg, createLine } from './utils/svg'; +import { + selectNode, + unselectNode, + selectNextSibling, + selectPrevSibling, + selectFirstChild, + selectParent, + getAllDataString, + getAllData, + getAllDataMd, + scale, + toCenter, + focusNode, + cancelFocus, + initLeft, + initRight, + initSide, + setLocale, + enableEdit, + disableEdit, + expandNode, + refresh, +} from './interact'; +import { + insertSibling, + insertBefore, + insertParent, + addChild, + copyNode, + moveNode, + removeNode, + moveUpNode, + moveDownNode, + beginEdit, + updateNodeStyle, + updateNodeTags, + updateNodeIcons, + processPrimaryNode, + setNodeTopic, + moveNodeBefore, + moveNodeAfter, +} from './nodeOperation'; +import { createLink, removeLink, selectLink, hideLinkController, showLinkController } from './customLink'; +import linkDiv from './linkDiv'; +import initMouseEvent from './mouse'; + +import contextMenu from './plugin/contextMenu'; +import toolBar from './plugin/toolBar'; +import nodeMenu from './plugin/nodeMenu'; +import nodeDraggable from './plugin/nodeDraggable'; +import keypress from './plugin/keypress'; +import mobileMenu from './plugin/mobileMenu'; +import Bus from './utils/pubsub'; +import './iconfont/iconfont.js'; + +// TODO show up animation +export const E = findEle; +type LinkObj = object; +type operation = { + name: string; +}; +export interface NodeObj { + topic: string; + id: string; + style?: { + fontSize?: string; + color?: string; + background?: string; + fontWeight?: string; + }; + parent?: NodeObj; + children?: NodeObj[]; + tags?: string[]; + icons?: string[]; + hyperLink?: string; + expanded?: boolean; + direction?: number; + root?: boolean; +} + +export interface NodeElement extends HTMLElement { + nodeObj: Object; +} +export interface MindElixirData { + nodeData: NodeObj; + linkData?: LinkObj; +} +export interface MindElixirInstance { + mindElixirBox: HTMLElement; + nodeData: NodeObj; + linkData: LinkObj; + currentNode: Topic | null; + currentLink: SVGElement | null; + inputDiv: HTMLElement | null; + scaleVal: number; + tempDirection: number | null; + bus: object; // wip + + // wip + history: operation[]; + isUndo: boolean; + undo: () => void; + + direction: number; + locale: string; + draggable: boolean; + editable: boolean; + contextMenu: boolean; + contextMenuOption: object; + toolBar: boolean; + nodeMenu: boolean; + keypress: boolean; + before: object; + newTopicName: string; + allowUndo: boolean; + overflowHidden: boolean; + primaryLinkStyle: number; + primaryNodeHorizontalGap: number; + primaryNodeVerticalGap: number; + mobileMenu: boolean; +} +export interface Options { + el: string; + data: MindElixirData; + direction?: number; + locale?: string; + draggable?: boolean; + editable?: boolean; + contextMenu?: boolean; + contextMenuOption?: object; + toolBar?: boolean; + nodeMenu?: boolean; + keypress?: boolean; + before?: object; + newTopicName?: string; + allowUndo?: boolean; + overflowHidden?: boolean; + primaryLinkStyle?: number; + primaryNodeHorizontalGap?: number; + primaryNodeVerticalGap?: number; + mobileMenu?: boolean; +} +const $d = document; +/** + * @export MindElixir + * @example + * let mind = new MindElixir({ + el: '#map', + direction: 2, + data: data, + draggable: true, + editable: true, + contextMenu: true, + toolBar: true, + nodeMenu: true, + keypress: true, +}) +mind.init() + * + */ +function MindElixir( + this: MindElixirInstance, + { + el, + data, + direction, + locale, + draggable, + editable, + contextMenu, + contextMenuOption, + toolBar, + nodeMenu, + keypress, + before, + newTopicName, + allowUndo, + primaryLinkStyle, + overflowHidden, + primaryNodeHorizontalGap, + primaryNodeVerticalGap, + mobileMenu, + }: Options +) { + const box = document.querySelector(el) as HTMLElement; + if (!box) return; + this.mindElixirBox = box; + this.before = before || {}; + this.nodeData = data.nodeData; + this.linkData = data.linkData || {}; + this.locale = locale; + this.contextMenuOption = contextMenuOption; + this.contextMenu = contextMenu === undefined ? true : contextMenu; + this.toolBar = toolBar === undefined ? true : toolBar; + this.nodeMenu = nodeMenu === undefined ? true : nodeMenu; + this.keypress = keypress === undefined ? true : keypress; + this.mobileMenu = mobileMenu; + // record the direction before enter focus mode, must true in focus mode, reset to null after exit focus + // todo move direction to data + this.direction = typeof direction === 'number' ? direction : 1; + this.draggable = draggable === undefined ? true : draggable; + this.newTopicName = newTopicName; + this.editable = editable === undefined ? true : editable; + this.allowUndo = allowUndo === undefined ? true : allowUndo; + // this.parentMap = {} // deal with large amount of nodes + this.currentNode = null; // the selected element + this.currentLink = null; // the selected link svg element + this.inputDiv = null; // editor + this.scaleVal = 1; + this.tempDirection = null; + this.primaryLinkStyle = primaryLinkStyle || 0; + this.overflowHidden = overflowHidden; + this.primaryNodeHorizontalGap = primaryNodeHorizontalGap; + this.primaryNodeVerticalGap = primaryNodeVerticalGap; + + this.bus = new Bus(); + (this.bus as any).addListener('operation', (operation: operation) => { + if (this.isUndo) { + this.isUndo = false; + return; + } + if ( + ['moveNode', 'removeNode', 'addChild', 'finishEdit', 'editStyle', 'editTags', 'editIcons'].includes( + operation.name + ) + ) { + this.history.push(operation); + // console.log(operation, this.history) + } + }); + + this.history = []; // TODO + this.isUndo = false; + this.undo = function () { + const operation = this.history.pop(); + if (!operation) return; + this.isUndo = true; + if (operation.name === 'moveNode') { + this.moveNode(E(operation.obj.fromObj.id), E(operation.obj.originParentId)); + } else if (operation.name === 'removeNode') { + if (operation.originSiblingId) { + this.insertBefore(E(operation.originSiblingId), operation.obj); + } else { + this.addChild(E(operation.originParentId), operation.obj); + } + } else if (operation.name === 'addChild' || operation.name === 'copyNode') { + this.removeNode(E(operation.obj.id)); + } else if (operation.name === 'finishEdit') { + this.setNodeTopic(E(operation.obj.id), operation.origin); + } else { + this.isUndo = false; + } + }; +} + +function beforeHook(fn: (el: any, node?: any) => void) { + return async function (...args: unknown[]) { + if (!this.before[fn.name] || (await this.before[fn.name].apply(this, args))) { + fn.apply(this, args); + } + }; +} + +MindElixir.prototype = { + addParentLink, + getObjById, + generateNewObj, + // node operation + insertSibling: beforeHook(insertSibling), + insertBefore: beforeHook(insertBefore), + insertParent: beforeHook(insertParent), + addChild: beforeHook(addChild), + copyNode: beforeHook(copyNode), + moveNode: beforeHook(moveNode), + removeNode: beforeHook(removeNode), + moveUpNode: beforeHook(moveUpNode), + moveDownNode: beforeHook(moveDownNode), + beginEdit: beforeHook(beginEdit), + moveNodeBefore: beforeHook(moveNodeBefore), + moveNodeAfter: beforeHook(moveNodeAfter), + updateNodeStyle, + updateNodeTags, + updateNodeIcons, + processPrimaryNode, + setNodeTopic, + + createLink, + removeLink, + selectLink, + hideLinkController, + showLinkController, + + layout, + linkDiv, + createInputDiv, + + createChildren, + createGroup, + createTop, + createTopic, + + selectNode, + unselectNode, + selectNextSibling, + selectPrevSibling, + selectFirstChild, + selectParent, + getAllDataString, + getAllData, + getAllDataMd, + scale, + toCenter, + focusNode, + cancelFocus, + initLeft, + initRight, + initSide, + setLocale, + enableEdit, + disableEdit, + expandNode, + refresh, + + init: function () { + /** + * @function + * @global + * @name E + * @param {string} id Node id. + * @return {TargetElement} Target element. + * @example + * E('bd4313fbac40284b') + */ + addParentLink(this.nodeData); + this.mindElixirBox.className += ' mind-elixir'; + this.mindElixirBox.innerHTML = ''; + + this.container = $d.createElement('div'); // map container + this.container.className = 'map-container'; + + if (this.overflowHidden) this.container.style.overflow = 'hidden'; + + this.map = $d.createElement('div'); // map-canvas Element + this.map.className = 'map-canvas'; + this.map.setAttribute('tabindex', '0'); + this.container.appendChild(this.map); + this.mindElixirBox.appendChild(this.container); + this.root = $d.createElement('root'); + + this.box = $d.createElement('children'); + this.box.className = 'box'; + + this.svg2nd = createLinkSvg('svg2nd'); // main link container + this.linkController = createLinkSvg('linkcontroller'); // bezier controller container + this.P2 = $d.createElement('div'); // bezier P2 + this.P3 = $d.createElement('div'); // bezier P3 + this.P2.className = this.P3.className = 'circle'; + this.line1 = createLine(0, 0, 0, 0); // bezier auxiliary line1 + this.line2 = createLine(0, 0, 0, 0); // bezier auxiliary line2 + this.linkController.appendChild(this.line1); + this.linkController.appendChild(this.line2); + + this.linkSvgGroup = createLinkSvg('topiclinks'); // storage user custom link svg + + this.map.appendChild(this.root); + this.map.appendChild(this.box); + this.map.appendChild(this.svg2nd); + this.map.appendChild(this.linkController); + this.map.appendChild(this.linkSvgGroup); + this.map.appendChild(this.P2); + this.map.appendChild(this.P3); + + // plugin + this.toolBar && toolBar(this); + this.nodeMenu && nodeMenu(this); + this.keypress && keypress(this); + + if (isMobile() && this.mobileMenu) { + mobileMenu(this); + } else { + this.contextMenu && contextMenu(this, this.contextMenuOption); + } + this.draggable && nodeDraggable(this); + + this.toCenter(); + this.layout(); + this.linkDiv(); + if (!this.overflowHidden) initMouseEvent(this); + }, +}; + +MindElixir.LEFT = LEFT; +MindElixir.RIGHT = RIGHT; +MindElixir.SIDE = SIDE; +/** + * @memberof MindElixir + * @static + */ +MindElixir.version = '0.17.0'; +MindElixir.E = findEle; + +/** + * @function new + * @memberof MindElixir + * @static + * @param {String} topic root topic + */ +MindElixir.new = (topic: string): MindElixirData => ({ + nodeData: { + id: generateUUID(), + topic: topic || 'new topic', + root: true, + children: [], + }, + linkData: {}, +}); + +export default MindElixir; diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/interact.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/interact.ts new file mode 100644 index 00000000..bf888054 --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/interact.ts @@ -0,0 +1,333 @@ +import { findEle } from './utils/dom'; +/** + * @exports - + * workaround for jsdoc + */ +/** + * @exports MapInteraction + * @namespace MapInteraction + */ +function getData(instance) { + return instance.isFocusMode ? instance.nodeDataBackup : instance.nodeData; +} +/** + * @function + * @instance + * @name selectNode + * @memberof MapInteraction + * @description Select a node and add solid border to it. + * @param {TargetElement} el - Target element return by E('...'), default value: currentTarget. + */ +export const selectNode = function (targetElement, isNewNode, clickEvent) { + if (!targetElement) return; + console.time('selectNode'); + if (typeof targetElement === 'string') { + return this.selectNode(findEle(targetElement)); + } + if (this.currentNode) this.currentNode.classList.remove('selected'); + targetElement.classList.add('selected'); + this.currentNode = targetElement; + if (isNewNode) { + this.bus.fire('selectNewNode', targetElement.nodeObj, clickEvent); + } else { + this.bus.fire('selectNode', targetElement.nodeObj, clickEvent); + } + console.timeEnd('selectNode'); +}; +export const unselectNode = function () { + if (this.currentNode) { + this.currentNode.classList.remove('selected'); + } + this.currentNode = null; + this.bus.fire('unselectNode'); +}; +export const selectNextSibling = function () { + if (!this.currentNode || this.currentNode.dataset.nodeid === 'meroot') return; + + const sibling = this.currentNode.parentElement.parentElement.nextSibling; + let target: HTMLElement; + const grp = this.currentNode.parentElement.parentElement; + if (grp.className === 'rhs' || grp.className === 'lhs') { + const siblingList = this.mindElixirBox.querySelectorAll('.' + grp.className); + const i = Array.from(siblingList).indexOf(grp); + if (i + 1 < siblingList.length) { + target = siblingList[i + 1].firstChild.firstChild; + } else { + return false; + } + } else if (sibling) { + target = sibling.firstChild.firstChild; + } else { + return false; + } + this.selectNode(target); + return true; +}; +export const selectPrevSibling = function () { + if (!this.currentNode || this.currentNode.dataset.nodeid === 'meroot') return; + + const sibling = this.currentNode.parentElement.parentElement.previousSibling; + let target; + const grp = this.currentNode.parentElement.parentElement; + if (grp.className === 'rhs' || grp.className === 'lhs') { + const siblingList = this.mindElixirBox.querySelectorAll('.' + grp.className); + const i = Array.from(siblingList).indexOf(grp); + if (i - 1 >= 0) { + target = siblingList[i - 1].firstChild.firstChild; + } else { + return false; + } + } else if (sibling) { + target = sibling.firstChild.firstChild; + } else { + return false; + } + this.selectNode(target); + return true; +}; +export const selectFirstChild = function () { + if (!this.currentNode) return; + const children = this.currentNode.parentElement.nextSibling; + if (children && children.firstChild) { + const target = children.firstChild.firstChild.firstChild; + this.selectNode(target); + } +}; +export const selectParent = function () { + if (!this.currentNode || this.currentNode.dataset.nodeid === 'meroot') return; + + const parent = this.currentNode.parentElement.parentElement.parentElement.previousSibling; + if (parent) { + const target = parent.firstChild; + this.selectNode(target); + } +}; +/** + * @function + * @instance + * @name getAllDataString + * @description Get all node data as string. + * @memberof MapInteraction + * @return {string} + */ +export const getAllDataString = function () { + const data = { + nodeData: getData(this), + linkData: this.linkData, + }; + return JSON.stringify(data, (k, v) => { + if (k === 'parent') return undefined; + if (k === 'from') return v.nodeObj.id; + if (k === 'to') return v.nodeObj.id; + return v; + }); +}; +/** + * @function + * @instance + * @name getAllData + * @description Get all node data as object. + * @memberof MapInteraction + * @return {Object} + */ +export const getAllData = function (): object { + const data = { + nodeData: getData(this), + linkData: this.linkData, + }; + return JSON.parse( + JSON.stringify(data, (k, v) => { + if (k === 'parent') return undefined; + if (k === 'from') return v.nodeObj.id; + if (k === 'to') return v.nodeObj.id; + return v; + }) + ); +}; + +/** + * @function + * @instance + * @name getAllDataMd + * @description Get all node data as markdown. + * @memberof MapInteraction + * @return {String} + */ +export const getAllDataMd = function (): string { + const data = getData(this); + let mdString = '# ' + data.topic + '\n\n'; + function writeMd(children, deep) { + for (let i = 0; i < children.length; i++) { + if (deep <= 6) { + mdString += ''.padStart(deep, '#') + ' ' + children[i].topic + '\n\n'; + } else { + mdString += ''.padStart(deep - 7, '\t') + '- ' + children[i].topic + '\n'; + } + if (children[i].children) { + writeMd(children[i].children, deep + 1); + } + } + } + writeMd(data.children, 2); + return mdString; +}; + +/** + * @function + * @instance + * @name enableEdit + * @memberof MapInteraction + */ +export const enableEdit = function () { + this.editable = true; +}; + +/** + * @function + * @instance + * @name disableEdit + * @memberof MapInteraction + */ +export const disableEdit = function () { + this.editable = false; +}; + +/** + * @function + * @instance + * @name scale + * @description Change the scale of the mind map. + * @memberof MapInteraction + * @param {number} + */ +export const scale = function (scaleVal) { + this.scaleVal = scaleVal; + this.map.style.transform = 'scale(' + scaleVal + ')'; +}; +/** + * @function + * @instance + * @name toCenter + * @description Reset position of the map to center. + * @memberof MapInteraction + */ +export const toCenter = function () { + this.container.scrollTo(10000 - this.container.offsetWidth / 2, 10000 - this.container.offsetHeight / 2); +}; +export const install = function (plugin) { + plugin(this); +}; +/** + * @function + * @instance + * @name focusNode + * @description Enter focus mode, set the target element as root. + * @memberof MapInteraction + * @param {TargetElement} el - Target element return by E('...'), default value: currentTarget. + */ +export const focusNode = function (tpcEl) { + if (tpcEl.nodeObj.root) return; + if (this.tempDirection === null) { + this.tempDirection = this.direction; + } + if (!this.isFocusMode) { + this.nodeDataBackup = this.nodeData; // help reset focus mode + this.isFocusMode = true; + } + this.nodeData = tpcEl.nodeObj; + this.nodeData.root = true; + this.initRight(); +}; +/** + * @function + * @instance + * @name cancelFocus + * @description Exit focus mode. + * @memberof MapInteraction + */ +export const cancelFocus = function () { + this.isFocusMode = false; + if (this.tempDirection !== null) { + delete this.nodeData.root; + this.nodeData = this.nodeDataBackup; + this.direction = this.tempDirection; + this.tempDirection = null; + this.init(); + } +}; +/** + * @function + * @instance + * @name initLeft + * @description Child nodes will distribute on the left side of the root node. + * @memberof MapInteraction + */ +export const initLeft = function () { + this.direction = 0; + this.init(); +}; +/** + * @function + * @instance + * @name initRight + * @description Child nodes will distribute on the right side of the root node. + * @memberof MapInteraction + */ +export const initRight = function () { + this.direction = 1; + this.init(); +}; +/** + * @function + * @instance + * @name initSide + * @description Child nodes will distribute on both left and right side of the root node. + * @memberof MapInteraction + */ +export const initSide = function () { + this.direction = 2; + this.init(); +}; + +/** + * @function + * @instance + * @name setLocale + * @memberof MapInteraction + */ +export const setLocale = function (locale) { + this.locale = locale; + this.init(); +}; + +export const expandNode = function (el, isExpand) { + const node = el.nodeObj; + if (typeof isExpand === 'boolean') { + node.expanded = isExpand; + } else if (node.expanded !== false) { + node.expanded = false; + } else { + node.expanded = true; + } + // TODO 在此函数构造 html 结构,而非调用 layout + this.layout(); + // linkDiv 已实现只更新特定主节点 + this.linkDiv(); + this.bus.fire('expandNode', node); +}; + +/** + * @function + * @instance + * @name refresh + * @description Refresh mind map, you can use it after modified `this.nodeData` + * @memberof MapInteraction + */ +export const refresh = function () { + // add parent property to every node + this.addParentLink(this.nodeData); + // create dom element for every node + this.layout(); + // generate links between nodes + this.linkDiv(); +}; diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/linkDiv.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/linkDiv.ts new file mode 100644 index 00000000..0021d7a7 --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/linkDiv.ts @@ -0,0 +1,248 @@ +import { createPath, createMainPath, createLinkSvg } from './utils/svg'; +import { findEle, Expander } from './utils/dom'; +import { SIDE, GAP, TURNPOINT_R, PRIMARY_NODE_HORIZONTAL_GAP, PRIMARY_NODE_VERTICAL_GAP } from './const'; + +/** + * Link nodes with svg, + * only link specific node if `primaryNode` is present + * + * procedure: + * 1. calculate position of primary nodes + * 2. layout primary node, generate primary link + * 3. generate links inside primary node + * 4. generate custom link + * @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; + console.time('linkDiv'); + const root = this.root; + root.style.cssText = `top:${10000 - root.offsetHeight / 2}px;left:${10000 - root.offsetWidth / 2}px;`; + const primaryNodeList = this.box.children; + this.svg2nd.innerHTML = ''; + + // 1. calculate position of primary nodes + let totalHeight = 0; + let shortSide: string; // l or r + let shortSideGap = 0; // balance heigt of two side + let currentOffsetL = 0; // left side total offset + let currentOffsetR = 0; // right side total offset + let totalHeightL = 0; + let totalHeightR = 0; + let base: number; + + if (this.direction === SIDE) { + let countL = 0; + let countR = 0; + let totalHeightLWithoutGap = 0; + let totalHeightRWithoutGap = 0; + for (let i = 0; i < primaryNodeList.length; i++) { + const el = primaryNodeList[i]; + if (el.className === 'lhs') { + totalHeightL += el.offsetHeight + primaryNodeVerticalGap; + totalHeightLWithoutGap += el.offsetHeight; + countL += 1; + } else { + totalHeightR += el.offsetHeight + primaryNodeVerticalGap; + totalHeightRWithoutGap += el.offsetHeight; + countR += 1; + } + } + if (totalHeightL > totalHeightR) { + base = 10000 - Math.max(totalHeightL) / 2; + shortSide = 'r'; + shortSideGap = (totalHeightL - totalHeightRWithoutGap) / (countR - 1); + } else { + base = 10000 - Math.max(totalHeightR) / 2; + shortSide = 'l'; + shortSideGap = (totalHeightR - totalHeightLWithoutGap) / (countL - 1); + } + } else { + for (let i = 0; i < primaryNodeList.length; i++) { + const el = primaryNodeList[i]; + totalHeight += el.offsetHeight + primaryNodeVerticalGap; + } + base = 10000 - totalHeight / 2; + } + + // 2. layout primary node, generate primary link + let primaryPath = ''; + const alignRight = 10000 - root.offsetWidth / 2 - primaryNodeHorizontalGap; + const alignLeft = 10000 + root.offsetWidth / 2 + primaryNodeHorizontalGap; + for (let i = 0; i < primaryNodeList.length; i++) { + let x2, y2; + const el = primaryNodeList[i]; + const elOffsetH = el.offsetHeight; + if (el.className === 'lhs') { + el.style.top = base + currentOffsetL + 'px'; + el.style.left = alignRight - el.offsetWidth + 'px'; + x2 = alignRight - 15; // padding + y2 = base + currentOffsetL + elOffsetH / 2; + + // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#path_commands + let LEFT = 10000; + if (this.primaryLinkStyle === 2) { + if (this.direction === SIDE) { + LEFT = 10000 - root.offsetWidth / 6; + } + if (y2 < 10000) { + primaryPath += `M ${LEFT} 10000 V ${y2 + 20} C ${LEFT} ${y2} ${LEFT} ${y2} ${LEFT - 20} ${y2} H ${x2}`; + } else { + primaryPath += `M ${LEFT} 10000 V ${y2 - 20} C ${LEFT} ${y2} ${LEFT} ${y2} ${LEFT - 20} ${y2} H ${x2}`; + } + } else { + primaryPath += `M 10000 10000 C 10000 10000 ${10000 + 2 * primaryNodeHorizontalGap * 0.03} ${y2} ${x2} ${y2}`; + } + + if (shortSide === 'l') { + currentOffsetL += elOffsetH + shortSideGap; + } else { + currentOffsetL += elOffsetH + primaryNodeVerticalGap; + } + } else { + el.style.top = base + currentOffsetR + 'px'; + el.style.left = alignLeft + 'px'; + x2 = alignLeft + 15; // padding + y2 = base + currentOffsetR + elOffsetH / 2; + + let LEFT = 10000; + if (this.primaryLinkStyle === 2) { + if (this.direction === SIDE) { + LEFT = 10000 + root.offsetWidth / 6; + } + if (y2 < 10000) { + primaryPath += `M ${LEFT} 10000 V ${y2 + 20} C ${LEFT} ${y2} ${LEFT} ${y2} ${LEFT + 20} ${y2} H ${x2}`; + } else { + primaryPath += `M ${LEFT} 10000 V ${y2 - 20} C ${LEFT} ${y2} ${LEFT} ${y2} ${LEFT + 20} ${y2} H ${x2}`; + } + } else { + primaryPath += `M 10000 10000 C 10000 10000 ${10000 + 2 * primaryNodeHorizontalGap * 0.03} ${y2} ${x2} ${y2}`; + } + if (shortSide === 'r') { + currentOffsetR += elOffsetH + shortSideGap; + } else { + currentOffsetR += elOffsetH + primaryNodeVerticalGap; + } + } + // set position of expander + const expander = el.children[0].children[1]; + if (expander) { + expander.style.top = (expander.parentNode.offsetHeight - expander.offsetHeight) / 2 + 'px'; + if (el.className === 'lhs') { + expander.style.left = -10 + 'px'; + } else { + expander.style.left = expander.parentNode.offsetWidth - 10 + 'px'; + } + } + } + this.svg2nd.appendChild(createMainPath(primaryPath)); + + // 3. generate link inside primary node + for (let i = 0; i < primaryNodeList.length; i++) { + const el = primaryNodeList[i]; + if (primaryNode && primaryNode !== primaryNodeList[i]) { + continue; + } + if (el.childElementCount) { + const svg = createLinkSvg('svg3rd'); + // svg tag name is lower case + if (el.lastChild.tagName === 'svg') el.lastChild.remove(); + el.appendChild(svg); + const parent = el.children[0]; + const children = el.children[1].children; + path = ''; + loopChildren(children, parent, true); + svg.appendChild(createPath(path)); + } + } + + // 4. generate custom link + this.linkSvgGroup.innerHTML = ''; + for (const prop in this.linkData) { + const link = this.linkData[prop]; + if (typeof link.from === 'string') { + this.createLink(findEle(link.from), findEle(link.to), true, link); + } else { + this.createLink(findEle(link.from.nodeObj.id), findEle(link.to.nodeObj.id), true, link); + } + } + console.timeEnd('linkDiv'); +} + +let path = ''; +function loopChildren(children: HTMLCollection, parent: HTMLElement, first?: boolean) { + const parentOT = parent.offsetTop; + const parentOL = parent.offsetLeft; + const parentOW = parent.offsetWidth; + const parentOH = parent.offsetHeight; + for (let i = 0; i < children.length; i++) { + const child: HTMLElement = children[i] as HTMLElement; + const childT: HTMLElement = child.children[0] as HTMLElement; // t tag inside the child dom + const childTOT = childT.offsetTop; + const childTOH = childT.offsetHeight; + let y1: number; + if (first) { + y1 = parentOT + parentOH / 2; + } else { + y1 = parentOT + parentOH; + } + const y2 = childTOT + childTOH; + let x1: number, x2: number, xMiddle: number; + const direction = child.offsetParent.className; + if (direction === 'lhs') { + x1 = parentOL + GAP; + xMiddle = parentOL; + x2 = parentOL - childT.offsetWidth; + + if (childTOT + childTOH < parentOT + parentOH / 2 + 50 && childTOT + childTOH > parentOT + parentOH / 2 - 50) { + // 相差+-50内直接直线 + path += `M ${x1} ${y1} H ${xMiddle} V ${y2} H ${x2}`; + } else if (childTOT + childTOH >= parentOT + parentOH / 2) { + // 子底部低于父中点 + path += `M ${x1} ${y1} H ${xMiddle} V ${y2 - TURNPOINT_R} A ${TURNPOINT_R} ${TURNPOINT_R} 0 0 1 ${ + xMiddle - TURNPOINT_R + } ${y2} H ${x2}`; + } else { + // 子底部高于父中点 + path += `M ${x1} ${y1} H ${xMiddle} V ${y2 + TURNPOINT_R} A ${TURNPOINT_R} ${TURNPOINT_R} 0 0 0 ${ + xMiddle - TURNPOINT_R + } ${y2} H ${x2}`; + } + } else if (direction === 'rhs') { + x1 = parentOL + parentOW - GAP; + xMiddle = parentOL + parentOW; + x2 = parentOL + parentOW + childT.offsetWidth; + + if (childTOT + childTOH < parentOT + parentOH / 2 + 50 && childTOT + childTOH > parentOT + parentOH / 2 - 50) { + path += `M ${x1} ${y1} H ${xMiddle} V ${y2} H ${x2}`; + } else if (childTOT + childTOH >= parentOT + parentOH / 2) { + path += `M ${x1} ${y1} H ${xMiddle} V ${y2 - TURNPOINT_R} A ${TURNPOINT_R} ${TURNPOINT_R} 0 0 0 ${ + xMiddle + TURNPOINT_R + } ${y2} H ${x2}`; + } else { + path += `M ${x1} ${y1} H ${xMiddle} V ${y2 + TURNPOINT_R} A ${TURNPOINT_R} ${TURNPOINT_R} 0 0 1 ${ + xMiddle + TURNPOINT_R + } ${y2} H ${x2}`; + } + } + + const expander = childT.children[1] as Expander; + if (expander) { + expander.style.top = (childT.offsetHeight - expander.offsetHeight) / 2 + 'px'; + if (direction === 'lhs') { + expander.style.left = -10 + 'px'; + } else if (direction === 'rhs') { + expander.style.left = childT.offsetWidth - 10 + 'px'; + } + // this property is added in the layout phase + if (!expander.expanded) continue; + } else { + // expander not exist + continue; + } + // traversal + const nextChildren = child.children[1].children; + if (nextChildren.length > 0) loopChildren(nextChildren, childT); + } +} diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/mouse.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/mouse.ts new file mode 100644 index 00000000..447b01df --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/mouse.ts @@ -0,0 +1,52 @@ +import { dragMoveHelper } from './utils/index'; +export default function (mind) { + mind.map.addEventListener('click', (e) => { + // if (dragMoveHelper.afterMoving) return + // e.preventDefault() // can cause a tag don't work + if (e.target.nodeName === 'EPD') { + mind.expandNode(e.target.previousSibling); + } else if (e.target.parentElement.nodeName === 'T' || e.target.parentElement.nodeName === 'ROOT') { + mind.selectNode(e.target, false, e); + } else if (e.target.nodeName === 'path') { + if (e.target.parentElement.nodeName === 'g') { + mind.selectLink(e.target.parentElement); + } + } else if (e.target.className === 'circle') { + // skip circle + } else { + mind.unselectNode(); + mind.hideLinkController(); + } + }); + + mind.map.addEventListener('dblclick', (e) => { + e.preventDefault(); + if (!mind.editable) return; + if (e.target.parentElement.nodeName === 'T' || e.target.parentElement.nodeName === 'ROOT') { + mind.beginEdit(e.target); + } + }); + + /** + * drag and move + */ + mind.map.addEventListener('mousemove', (e) => { + // click trigger mousemove in windows chrome + // the 'true' is a string + if (e.target.contentEditable !== 'true') { + dragMoveHelper.onMove(e, mind.container); + } + }); + mind.map.addEventListener('mousedown', (e) => { + if (e.target.contentEditable !== 'true') { + dragMoveHelper.afterMoving = false; + dragMoveHelper.mousedown = true; + } + }); + mind.map.addEventListener('mouseleave', (e) => { + dragMoveHelper.clear(); + }); + mind.map.addEventListener('mouseup', (e) => { + dragMoveHelper.clear(); + }); +} diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/nodeOperation.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/nodeOperation.ts new file mode 100644 index 00000000..b1e90a5d --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/nodeOperation.ts @@ -0,0 +1,600 @@ +import type { NodeElement, NodeObj } from './index'; + +import { + moveNodeObj, + removeNodeObj, + insertNodeObj, + insertBeforeNodeObj, + insertParentNodeObj, + checkMoveValid, + addParentLink, + moveUpObj, + moveDownObj, + moveNodeBeforeObj, + moveNodeAfterObj, + refreshIds, +} from './utils/index'; +import { findEle, createExpander, shapeTpc } from './utils/dom'; +import { rgbHex } from './utils/index'; +import { LEFT, RIGHT, SIDE } from './const'; +const $d = document; + +/** + * @exports NodeOperation + * @namespace NodeOperation + */ +export const updateNodeStyle = function (object) { + if (!object.style) return; + const nodeEle = findEle(object.id, this); + const origin = { + color: nodeEle.style.color && rgbHex(nodeEle.style.color), + background: nodeEle.style.background && rgbHex(nodeEle.style.background), + fontSize: nodeEle.style.fontSize && nodeEle.style.fontSize + 'px', + fontWeight: nodeEle.style.fontWeight, + }; + nodeEle.style.color = object.style.color; + nodeEle.style.background = object.style.background; + nodeEle.style.fontSize = object.style.fontSize + 'px'; + nodeEle.style.fontWeight = object.style.fontWeight || 'normal'; + this.linkDiv(); + this.bus.fire('operation', { + name: 'editStyle', + obj: object, + origin, + }); +}; + +export const updateNodeTags = function (object, tags) { + if (!tags) return; + const oldVal = object.tags; + object.tags = tags; + const nodeEle = findEle(object.id); + shapeTpc(nodeEle, object); + this.linkDiv(); + this.bus.fire('operation', { + name: 'editTags', + obj: object, + origin: oldVal, + }); +}; + +export const updateNodeIcons = function (object, icons) { + if (!icons) return; + const oldVal = object.icons; + object.icons = icons; + const nodeEle = findEle(object.id); + shapeTpc(nodeEle, object); + this.linkDiv(); + this.bus.fire('operation', { + name: 'editIcons', + obj: object, + origin: oldVal, + }); +}; + +export const updateNodeHyperLink = function (object, hyperLink) { + if (!hyperLink) return; + const oldVal = object.hyperLink; + object.hyperLink = hyperLink; + const nodeEle = findEle(object.id); + shapeTpc(nodeEle, object); + this.linkDiv(); + this.bus.fire('operation', { + name: 'editHyperLink', + obj: object, + origin: oldVal, + }); +}; + +export const updateNodeSvgChart = function () { + // TODO +}; + +/** + * @function + * @instance + * @name insertSibling + * @memberof NodeOperation + * @description Create a sibling node. + * @param {TargetElement} el - Target element return by E('...'), default value: currentTarget. + * @param {node} node - New node information. + * @example + * insertSibling(E('bd4313fbac40284b')) + */ +export const insertSibling = function (el, node) { + const nodeEle = el || this.currentNode; + if (!nodeEle) return; + const nodeObj = nodeEle.nodeObj; + if (nodeObj.root === true) { + this.addChild(); + return; + } + const newNodeObj = node || this.generateNewObj(); + insertNodeObj(nodeObj, newNodeObj); + addParentLink(this.nodeData); + const t = nodeEle.parentElement; + console.time('insertSibling_DOM'); + + const { grp, top } = this.createGroup(newNodeObj); + + const children = t.parentNode.parentNode; + children.insertBefore(grp, t.parentNode.nextSibling); + if (children.className === 'box') { + this.processPrimaryNode(grp, newNodeObj); + this.linkDiv(); + } else { + this.linkDiv(grp.offsetParent); + } + if (!node) { + this.createInputDiv(top.children[0]); + } + this.selectNode(top.children[0], true); + console.timeEnd('insertSibling_DOM'); + this.bus.fire('operation', { + name: 'insertSibling', + obj: newNodeObj, + }); +}; + +/** + * @function + * @instance + * @name insertBefore + * @memberof NodeOperation + * @description Create a sibling node before the selected node. + * @param {TargetElement} el - Target element return by E('...'), default value: currentTarget. + * @param {node} node - New node information. + * @example + * insertBefore(E('bd4313fbac40284b')) + */ +export const insertBefore = function (el, node) { + const nodeEle = el || this.currentNode; + if (!nodeEle) return; + const nodeObj = nodeEle.nodeObj; + if (nodeObj.root === true) { + this.addChild(); + return; + } + const newNodeObj = node || this.generateNewObj(); + insertBeforeNodeObj(nodeObj, newNodeObj); + addParentLink(this.nodeData); + const t = nodeEle.parentElement; + console.time('insertSibling_DOM'); + + const { grp, top } = this.createGroup(newNodeObj); + + const children = t.parentNode.parentNode; + children.insertBefore(grp, t.parentNode); + if (children.className === 'box') { + this.processPrimaryNode(grp, newNodeObj); + this.linkDiv(); + } else { + this.linkDiv(grp.offsetParent); + } + if (!node) { + this.createInputDiv(top.children[0]); + } + this.selectNode(top.children[0], true); + console.timeEnd('insertSibling_DOM'); + this.bus.fire('operation', { + name: 'insertSibling', + obj: newNodeObj, + }); +}; + +/** + * @function + * @instance + * @name insertParent + * @memberof NodeOperation + * @description Create a parent node of the selected node. + * @param {TargetElement} el - Target element return by E('...'), default value: currentTarget. + * @param {node} node - New node information. + * @example + * insertParent(E('bd4313fbac40284b')) + */ +export const insertParent = function (el, node) { + const nodeEle = el || this.currentNode; + if (!nodeEle) return; + const nodeObj = nodeEle.nodeObj; + if (nodeObj.root === true) { + return; + } + const newNodeObj = node || this.generateNewObj(); + insertParentNodeObj(nodeObj, newNodeObj); + addParentLink(this.nodeData); + const grp0 = nodeEle.parentElement.parentElement; + console.time('insertParent_DOM'); + const { grp, top } = this.createGroup(newNodeObj, true); + const children = grp0.parentNode; + children.insertBefore(grp, grp0.nextSibling); + + const c = $d.createElement('children'); + c.appendChild(grp0); + top.appendChild(createExpander(true)); + top.parentElement.insertBefore(c, top.nextSibling); + + if (children.className === 'box') { + grp.className = grp0.className; + grp0.className = ''; + grp0.querySelector('.svg3rd').remove(); + this.linkDiv(); + } else { + this.linkDiv(grp.offsetParent); + } + + if (!node) { + this.createInputDiv(top.children[0]); + } + this.selectNode(top.children[0], true); + console.timeEnd('insertParent_DOM'); + this.bus.fire('operation', { + name: 'insertParent', + obj: newNodeObj, + }); +}; + +export const addChildFunction = function (nodeEle, node) { + if (!nodeEle) return; + const nodeObj = nodeEle.nodeObj; + if (nodeObj.expanded === false) { + this.expandNode(nodeEle, true); + // dom had resetted + nodeEle = findEle(nodeObj.id); + } + const newNodeObj = node || this.generateNewObj(); + if (nodeObj.children) nodeObj.children.push(newNodeObj); + else nodeObj.children = [newNodeObj]; + addParentLink(this.nodeData); + + const top = nodeEle.parentElement; + + const { grp, top: newTop } = this.createGroup(newNodeObj); + + if (top.tagName === 'T') { + if (top.children[1]) { + top.nextSibling.appendChild(grp); + } else { + const c = $d.createElement('children'); + c.appendChild(grp); + top.appendChild(createExpander(true)); + top.parentElement.insertBefore(c, top.nextSibling); + } + this.linkDiv(grp.offsetParent); + } else if (top.tagName === 'ROOT') { + this.processPrimaryNode(grp, newNodeObj); + top.nextSibling.appendChild(grp); + this.linkDiv(); + } + return { newTop, newNodeObj }; +}; + +/** + * @function + * @instance + * @name addChild + * @memberof NodeOperation + * @description Create a child node. + * @param {TargetElement} el - Target element return by E('...'), default value: currentTarget. + * @param {node} node - New node information. + * @example + * addChild(E('bd4313fbac40284b')) + */ +export const addChild = function (el: NodeElement, node: NodeObj) { + console.time('addChild'); + const nodeEle = el || this.currentNode; + if (!nodeEle) return; + const { newTop, newNodeObj } = addChildFunction.call(this, nodeEle, node); + console.timeEnd('addChild'); + if (!node) { + this.createInputDiv(newTop.children[0]); + } + this.selectNode(newTop.children[0], true); + this.bus.fire('operation', { + name: 'addChild', + obj: newNodeObj, + }); +}; +// uncertain link disappear sometimes?? +// TODO while direction = SIDE, move up won't change the direction of primary node + +/** + * @function + * @instance + * @name copyNode + * @memberof NodeOperation + * @description Copy node to another node. + * @param {TargetElement} node - Target element return by E('...'), default value: currentTarget. + * @param {TargetElement} to - The target(as parent node) you want to copy to. + * @example + * copyNode(E('bd4313fbac402842'),E('bd4313fbac402839')) + */ +export const copyNode = function (node: NodeElement, to: NodeElement) { + console.time('copyNode'); + const deepCloneObj = JSON.parse( + JSON.stringify(node.nodeObj, (k, v) => { + if (k === 'parent') return undefined; + return v; + }) + ); + refreshIds(deepCloneObj); + const { newNodeObj } = addChildFunction.call(this, to, deepCloneObj); + console.timeEnd('copyNode'); + this.bus.fire('operation', { + name: 'copyNode', + obj: newNodeObj, + }); +}; + +/** + * @function + * @instance + * @name moveUpNode + * @memberof NodeOperation + * @description Move the target node up. + * @param {TargetElement} el - Target element return by E('...'), default value: currentTarget. + * @example + * moveUpNode(E('bd4313fbac40284b')) + */ +export const moveUpNode = function (el) { + const nodeEle = el || this.currentNode; + if (!nodeEle) return; + const grp = nodeEle.parentNode.parentNode; + const obj = nodeEle.nodeObj; + moveUpObj(obj); + grp.parentNode.insertBefore(grp, grp.previousSibling); + this.linkDiv(); + this.bus.fire('operation', { + name: 'moveUpNode', + obj, + }); +}; + +/** + * @function + * @instance + * @name moveDownNode + * @memberof NodeOperation + * @description Move the target node down. + * @param {TargetElement} el - Target element return by E('...'), default value: currentTarget. + * @example + * moveDownNode(E('bd4313fbac40284b')) + */ +export const moveDownNode = function (el) { + const nodeEle = el || this.currentNode; + if (!nodeEle) return; + const grp = nodeEle.parentNode.parentNode; + const obj = nodeEle.nodeObj; + moveDownObj(obj); + if (grp.nextSibling) { + grp.parentNode.insertBefore(grp, grp.nextSibling.nextSibling); + } else { + grp.parentNode.prepend(grp); + } + this.linkDiv(); + this.bus.fire('operation', { + name: 'moveDownNode', + obj, + }); +}; + +/** + * @function + * @instance + * @name removeNode + * @memberof NodeOperation + * @description Remove the target node. + * @param {TargetElement} el - Target element return by E('...'), default value: currentTarget. + * @example + * removeNode(E('bd4313fbac40284b')) + */ +export const removeNode = function (el) { + const nodeEle = el || this.currentNode; + if (!nodeEle) return; + const nodeObj = nodeEle.nodeObj; + if (nodeObj.root === true) { + throw new Error('Can not remove root node'); + } + const index = nodeObj.parent.children.findIndex((node) => node === nodeObj); + const next = nodeObj.parent.children[index + 1]; + const originSiblingId = next && next.id; + + const childrenLength = removeNodeObj(nodeObj); + const t = nodeEle.parentNode; + if (t.tagName === 'ROOT') { + return; + } + if (childrenLength === 0) { + // remove epd when children length === 0 + const parentT = t.parentNode.parentNode.previousSibling; + // root doesn't have epd + if (parentT.tagName !== 'ROOT') { + parentT.children[1].remove(); + } + this.selectParent(); + } else { + // select sibling automatically + const success = this.selectPrevSibling(); + if (!success) this.selectNextSibling(); + } + for (const prop in this.linkData) { + // MAYBEBUG should traversal all children node + const link = this.linkData[prop]; + if (link.from === t.firstChild || link.to === t.firstChild) { + this.removeLink(this.mindElixirBox.querySelector(`[data-linkid=${this.linkData[prop].id}]`)); + } + } + // remove GRP + t.parentNode.remove(); + this.linkDiv(); + this.bus.fire('operation', { + name: 'removeNode', + obj: nodeObj, + originSiblingId, + originParentId: nodeObj.parent.id, + }); +}; + +/** + * @function + * @instance + * @name moveNode + * @memberof NodeOperation + * @description Move a node to another node (as child node). + * @param {TargetElement} from - The target you want to move. + * @param {TargetElement} to - The target(as parent node) you want to move to. + * @example + * moveNode(E('bd4313fbac402842'),E('bd4313fbac402839')) + */ +export const moveNode = function (from, to) { + const fromObj = from.nodeObj; + const toObj = to.nodeObj; + const originParentId = fromObj.parent.id; + if (toObj.expanded === false) { + this.expandNode(to, true); + from = findEle(fromObj.id); + to = findEle(toObj.id); + } + if (!checkMoveValid(fromObj, toObj)) { + console.warn('Invalid move'); + return; + } + console.time('moveNode'); + moveNodeObj(fromObj, toObj); + addParentLink(this.nodeData); // update parent property + const fromTop = from.parentElement; + const fromChilren = fromTop.parentNode.parentNode; + const toTop = to.parentElement; + if (fromChilren.className === 'box') { + // clear svg group of primary node + fromTop.parentNode.lastChild.remove(); + } else if (fromTop.parentNode.className === 'box') { + fromTop.style.cssText = ''; // clear style + } + if (toTop.tagName === 'T') { + if (fromChilren.className === 'box') { + // clear direaction class of primary node + fromTop.parentNode.className = ''; + } + if (toTop.children[1]) { + // expander exist + toTop.nextSibling.appendChild(fromTop.parentNode); + } else { + // expander not exist, no child + const c = $d.createElement('children'); + c.appendChild(fromTop.parentNode); + toTop.appendChild(createExpander(true)); + toTop.parentElement.insertBefore(c, toTop.nextSibling); + } + } else if (toTop.tagName === 'ROOT') { + this.processPrimaryNode(fromTop.parentNode, fromObj); + toTop.nextSibling.appendChild(fromTop.parentNode); + } + this.linkDiv(); + this.bus.fire('operation', { + name: 'moveNode', + obj: { fromObj, toObj, originParentId }, + }); + console.timeEnd('moveNode'); +}; + +/** + * @function + * @instance + * @name moveNodeBefore + * @memberof NodeOperation + * @description Move a node and become previous node of another node. + * @param {TargetElement} from + * @param {TargetElement} to + * @example + * moveNodeBefore(E('bd4313fbac402842'),E('bd4313fbac402839')) + */ +export const moveNodeBefore = function (from, to) { + const fromObj = from.nodeObj; + const toObj = to.nodeObj; + const originParentId = fromObj.parent.id; + moveNodeBeforeObj(fromObj, toObj); + addParentLink(this.nodeData); + const fromTop = from.parentElement; + const fromGrp = fromTop.parentNode; + const toTop = to.parentElement; + const toGrp = toTop.parentNode; + const toChilren = toTop.parentNode.parentNode; + toChilren.insertBefore(fromGrp, toGrp); + this.linkDiv(); + this.bus.fire('operation', { + name: 'moveNodeBefore', + obj: { fromObj, toObj, originParentId }, + }); +}; + +/** + * @function + * @instance + * @name moveNodeAfter + * @memberof NodeOperation + * @description Move a node and become next node of another node. + * @param {TargetElement} from + * @param {TargetElement} to + * @example + * moveNodeAfter(E('bd4313fbac402842'),E('bd4313fbac402839')) + */ +export const moveNodeAfter = function (from, to) { + const fromObj = from.nodeObj; + const toObj = to.nodeObj; + const originParentId = fromObj.parent.id; + moveNodeAfterObj(fromObj, toObj); + addParentLink(this.nodeData); + const fromTop = from.parentElement; + const fromGrp = fromTop.parentNode; + const toTop = to.parentElement; + const toGrp = toTop.parentNode; + const toChilren = toTop.parentNode.parentNode; + toChilren.insertBefore(fromGrp, toGrp.nextSibling); + this.linkDiv(); + this.bus.fire('operation', { + name: 'moveNodeAfter', + obj: { fromObj, toObj, originParentId }, + }); +}; + +/** + * @function + * @instance + * @name beginEdit + * @memberof NodeOperation + * @description Begin to edit the target node. + * @param {TargetElement} el - Target element return by E('...'), default value: currentTarget. + * @example + * beginEdit(E('bd4313fbac40284b')) + */ +export const beginEdit = function (el) { + const nodeEle = el || this.currentNode; + if (!nodeEle) return; + this.createInputDiv(nodeEle); +}; + +export const setNodeTopic = function (tpc, topic) { + tpc.childNodes[0].textContent = topic; + tpc.nodeObj.topic = topic; + this.linkDiv(); +}; + +// Judge L or R +export function processPrimaryNode(primaryNode, obj) { + if (this.direction === LEFT) { + primaryNode.className = 'lhs'; + } else if (this.direction === RIGHT) { + primaryNode.className = 'rhs'; + } else if (this.direction === SIDE) { + const l = $d.querySelectorAll('.lhs').length; + const r = $d.querySelectorAll('.rhs').length; + if (l <= r) { + primaryNode.className = 'lhs'; + obj.direction = LEFT; + } else { + primaryNode.className = 'rhs'; + obj.direction = RIGHT; + } + } +} diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/contextMenu.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/contextMenu.ts new file mode 100644 index 00000000..10073f7f --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/contextMenu.ts @@ -0,0 +1,167 @@ +import i18n from '../i18n'; +import { encodeHTML } from '../utils/index'; + +export default function (mind, option) { + const createTips = (words) => { + const div = document.createElement('div'); + div.innerText = words; + div.style.cssText = 'position:absolute;bottom:20px;left:50%;transform:translateX(-50%);'; + return div; + }; + const createLi = (id, name, keyname) => { + const li = document.createElement('li'); + li.id = id; + li.innerHTML = `${encodeHTML(name)}${encodeHTML(keyname)}`; + return li; + }; + const locale = i18n[mind.locale] ? mind.locale : 'en'; + + const add_child = createLi('cm-add_child', i18n[locale].addChild, 'tab'); + const add_parent = createLi('cm-add_parent', i18n[locale].addParent, ''); + const add_sibling = createLi('cm-add_sibling', i18n[locale].addSibling, 'enter'); + const remove_child = createLi('cm-remove_child', i18n[locale].removeNode, 'delete'); + const focus = createLi('cm-fucus', i18n[locale].focus, ''); + const unfocus = createLi('cm-unfucus', i18n[locale].cancelFocus, ''); + const up = createLi('cm-up', i18n[locale].moveUp, 'PgUp'); + const down = createLi('cm-down', i18n[locale].moveDown, 'Pgdn'); + const link = createLi('cm-down', i18n[locale].link, ''); + + const menuUl = document.createElement('ul'); + menuUl.className = 'menu-list'; + menuUl.appendChild(add_child); + menuUl.appendChild(add_parent); + menuUl.appendChild(add_sibling); + menuUl.appendChild(remove_child); + if (!option || option.focus) { + menuUl.appendChild(focus); + menuUl.appendChild(unfocus); + } + menuUl.appendChild(up); + menuUl.appendChild(down); + if (!option || option.link) { + menuUl.appendChild(link); + } + if (option && option.extend) { + for (let i = 0; i < option.extend.length; i++) { + const item = option.extend[i]; + const dom = createLi(item.name, item.name, item.key || ''); + menuUl.appendChild(dom); + dom.onclick = (e) => { + item.onclick(e); + }; + } + } + const menuContainer = document.createElement('cmenu'); + menuContainer.appendChild(menuUl); + menuContainer.hidden = true; + + mind.container.append(menuContainer); + let isRoot = true; + mind.container.oncontextmenu = function (e) { + e.preventDefault(); + if (!mind.editable) return; + // console.log(e.pageY, e.screenY, e.clientY) + const target = e.target; + if (target.tagName === 'TPC') { + if (target.parentElement.tagName === 'ROOT') { + isRoot = true; + } else { + isRoot = false; + } + if (isRoot) { + focus.className = 'disabled'; + up.className = 'disabled'; + down.className = 'disabled'; + add_sibling.className = 'disabled'; + remove_child.className = 'disabled'; + } else { + focus.className = ''; + up.className = ''; + down.className = ''; + add_sibling.className = ''; + remove_child.className = ''; + } + mind.selectNode(target); + menuContainer.hidden = false; + const height = menuUl.offsetHeight; + const width = menuUl.offsetWidth; + if (height + e.clientY > window.innerHeight) { + menuUl.style.top = ''; + menuUl.style.bottom = '0px'; + } else { + menuUl.style.bottom = ''; + menuUl.style.top = e.clientY + 15 + 'px'; + } + if (width + e.clientX > window.innerWidth) { + menuUl.style.left = ''; + menuUl.style.right = '0px'; + } else { + menuUl.style.right = ''; + menuUl.style.left = e.clientX + 10 + 'px'; + } + } + }; + + menuContainer.onclick = (e) => { + if (e.target === menuContainer) menuContainer.hidden = true; + }; + + add_child.onclick = (e) => { + mind.addChild(); + menuContainer.hidden = true; + }; + add_parent.onclick = (e) => { + mind.insertParent(); + menuContainer.hidden = true; + }; + add_sibling.onclick = (e) => { + if (isRoot) return; + mind.insertSibling(); + menuContainer.hidden = true; + }; + remove_child.onclick = (e) => { + if (isRoot) return; + mind.removeNode(); + menuContainer.hidden = true; + }; + focus.onclick = (e) => { + if (isRoot) return; + mind.focusNode(mind.currentNode); + menuContainer.hidden = true; + }; + unfocus.onclick = (e) => { + mind.cancelFocus(); + menuContainer.hidden = true; + }; + up.onclick = (e) => { + if (isRoot) return; + mind.moveUpNode(); + menuContainer.hidden = true; + }; + down.onclick = (e) => { + if (isRoot) return; + mind.moveDownNode(); + menuContainer.hidden = true; + }; + link.onclick = (e) => { + menuContainer.hidden = true; + const from = mind.currentNode; + const tips = createTips(i18n[locale].clickTips); + mind.container.appendChild(tips); + mind.map.addEventListener( + 'click', + (e) => { + e.preventDefault(); + tips.remove(); + if (e.target.parentElement.nodeName === 'T' || e.target.parentElement.nodeName === 'ROOT') { + mind.createLink(from, mind.currentNode); + } else { + console.log('取消连接'); + } + }, + { + once: true, + } + ); + }; +} diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/keypress.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/keypress.ts new file mode 100644 index 00000000..05f4f372 --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/keypress.ts @@ -0,0 +1,99 @@ +export default function (mind) { + const key2func = { + 13: () => { + // enter + mind.insertSibling(); + }, + 9: () => { + // tab + mind.addChild(); + }, + 113: () => { + // f2 + mind.beginEdit(); + }, + 38: () => { + // up + mind.selectPrevSibling(); + }, + 40: () => { + // down + mind.selectNextSibling(); + }, + 37: () => { + // left + if (!mind.currentNode) return; + if (mind.currentNode.offsetParent.offsetParent.className === 'rhs') { + mind.selectParent(); + } else if (mind.currentNode.offsetParent.offsetParent.className === 'lhs' || mind.currentNode.nodeObj.root) { + mind.selectFirstChild(); + } + }, + 39: () => { + // right + if (!mind.currentNode) return; + if (mind.currentNode.offsetParent.offsetParent.className === 'rhs' || mind.currentNode.nodeObj.root) { + mind.selectFirstChild(); + } else if (mind.currentNode.offsetParent.offsetParent.className === 'lhs') { + mind.selectParent(); + } + }, + 33() { + // pageUp + mind.moveUpNode(); + }, + 34() { + // pageDown + mind.moveDownNode(); + }, + 67(e) { + if (e.metaKey || e.ctrlKey) { + // ctrl c + mind.waitCopy = mind.currentNode; + } + }, + 86(e) { + if (!mind.waitCopy) return; + if (e.metaKey || e.ctrlKey) { + // ctrl v + mind.copyNode(mind.waitCopy, mind.currentNode); + mind.waitCopy = null; + } + }, + // ctrl z + 90: (e) => { + if (!mind.allowUndo) return; + if (e.metaKey || e.ctrlKey) mind.undo(); + }, + // ctrl + + 187: (e) => { + if (e.metaKey || e.ctrlKey) { + if (mind.scaleVal > 1.6) return; + mind.scale((mind.scaleVal += 0.2)); + } + }, + // ctrl - + 189: (e) => { + if (e.metaKey || e.ctrlKey) { + if (mind.scaleVal < 0.6) return; + mind.scale((mind.scaleVal -= 0.2)); + } + }, + }; + + document.addEventListener('keydown', (e) => { + if (!mind.editable) return; + + if (mind.shouldPreventDefault && mind.shouldPreventDefault()) { + e.preventDefault(); + } + + if (e.keyCode === 8 || e.keyCode === 46) { + // del,backspace + if (mind.currentLink) mind.removeLink(); + else mind.removeNode(); + } else { + key2func[e.keyCode] && key2func[e.keyCode](e); + } + }); +} diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/mobileMenu.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/mobileMenu.ts new file mode 100644 index 00000000..45529921 --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/mobileMenu.ts @@ -0,0 +1,151 @@ +export default function (mind, option?) { + const createLi = (id, name) => { + const div = document.createElement('div'); + div.id = id; + div.innerHTML = ``; + return div; + }; + + const add_child = createLi('cm-add_child', 'zijiedian'); + const add_sibling = createLi('cm-add_sibling', 'tongjijiedian-'); + const remove_child = createLi('cm-remove_child', 'shanchu2'); + // let focus = createLi('cm-fucus', i18n[locale].focus, '') + // let unfocus = createLi('cm-unfucus', i18n[locale].cancelFocus, '') + const up = createLi('cm-up', 'rising'); + const down = createLi('cm-down', 'falling'); + const edit = createLi('cm-edit', 'edit'); + // let link = createLi('cm-down', i18n[locale].link, '') + + const menuUl = document.createElement('ul'); + menuUl.className = 'menu-list'; + // if (!option || option.link) { + // menuUl.appendChild(link) + // } + if (option && option.extend) { + for (let i = 0; i < option.extend.length; i++) { + const item = option.extend[i]; + const dom = createLi(item.name, item.name); + menuUl.appendChild(dom); + dom.onclick = (e) => { + item.onclick(e); + }; + } + } + const menuContainer = document.createElement('mmenu'); + menuContainer.appendChild(add_child); + menuContainer.appendChild(add_sibling); + menuContainer.appendChild(remove_child); + // if (!option || option.focus) { + // menuContainer.appendChild(focus) + // menuContainer.appendChild(unfocus) + // } + menuContainer.appendChild(up); + menuContainer.appendChild(down); + menuContainer.appendChild(edit); + menuContainer.hidden = true; + + mind.container.append(menuContainer); + let isRoot = true; + // mind.container.onclick = function (e) { + // e.preventDefault() + // // console.log(e.pageY, e.screenY, e.clientY) + // let target = e.target + // if (target.tagName === 'TPC') { + // if (target.parentElement.tagName === 'ROOT') { + // isRoot = true + // } else { + // isRoot = false + // } + // // if (isRoot) { + // // focus.className = 'disabled' + // // up.className = 'disabled' + // // down.className = 'disabled' + // // add_sibling.className = 'disabled' + // // remove_child.className = 'disabled' + // // } else { + // // focus.className = '' + // // up.className = '' + // // down.className = '' + // // add_sibling.className = '' + // // remove_child.className = '' + // // } + // mind.selectNode(target) + // menuContainer.hidden = false + // let height = menuUl.offsetHeight + // let width = menuUl.offsetWidth + // let rect = target.getBoundingClientRect() + // // menuUl.style.top = rect.top - 10 - height + 'px' + // // menuUl.style.left = rect.left - (width - rect.width) / 2 + 'px' + // // menuUl.style.left = e.clientX + 'px' + // } + // } + + mind.bus.addListener('unselectNode', function () { + menuContainer.hidden = true; + }); + mind.bus.addListener('selectNode', function (nodeObj) { + menuContainer.hidden = false; + if (nodeObj.root) { + isRoot = true; + } else { + isRoot = false; + } + }); + menuContainer.onclick = (e) => { + if (e.target === menuContainer) menuContainer.hidden = true; + }; + + add_child.onclick = (e) => { + mind.addChild(); + }; + add_sibling.onclick = (e) => { + if (isRoot) return; + mind.insertSibling(); + }; + remove_child.onclick = (e) => { + if (isRoot) return; + mind.removeNode(); + }; + // focus.onclick = e => { + // if (isRoot) return + // mind.focusNode(mind.currentNode) + // menuContainer.hidden = true + // } + // unfocus.onclick = e => { + // mind.cancelFocus() + // menuContainer.hidden = true + // } + up.onclick = (e) => { + if (isRoot) return; + mind.moveUpNode(); + }; + down.onclick = (e) => { + if (isRoot) return; + mind.moveDownNode(); + }; + edit.onclick = (e) => { + mind.beginEdit(); + }; + // link.onclick = e => { + // let from = mind.currentNode + // mind.map.addEventListener( + // 'click', + // e => { + // e.preventDefault() + // if ( + // e.target.parentElement.nodeName === 'T' || + // e.target.parentElement.nodeName === 'ROOT' + // ) { + // mind.createLink(from, mind.currentNode) + // } else { + // console.log('取消连接') + // } + // }, + // { + // once: true, + // } + // ) + // } +} diff --git a/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/nodeDraggable.ts b/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/nodeDraggable.ts new file mode 100644 index 00000000..8f28ca01 --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/nodeDraggable.ts @@ -0,0 +1,102 @@ +import { dragMoveHelper, throttle } from '../utils/index'; +import { findEle as E, Topic, Group } from '../utils/dom'; +// https://html.spec.whatwg.org/multipage/dnd.html#drag-and-drop-processing-model + +const $d = document; +const insertPreview = function (el, insertLocation) { + if (!insertLocation) { + clearPreview(el); + return el; + } + const query = el.getElementsByClassName('insert-preview'); + const className = `insert-preview ${insertLocation} show`; + if (query.length > 0) { + query[0].className = className; + } else { + const insertPreviewEL = $d.createElement('div'); + insertPreviewEL.className = className; + el.appendChild(insertPreviewEL); + } + return el; +}; + +const clearPreview = function (el) { + if (!el) return; + const query = el.getElementsByClassName('insert-preview'); + for (const queryElement of query || []) { + queryElement.remove(); + } +}; + +const canPreview = function (el: Element, dragged: Topic) { + const isContain = dragged.parentNode.parentNode.contains(el); + return el && el.tagName === 'TPC' && el !== dragged && !isContain && (el as Topic).nodeObj.root !== true; +}; + +export default function (mind) { + let dragged: Topic; + let insertLocation: string; + let meet: Element; + const threshold = 12; + + mind.map.addEventListener('dragstart', function (e) { + dragged = e.target; + (dragged.parentNode.parentNode as Group).style.opacity = '0.5'; + dragMoveHelper.clear(); + }); + + mind.map.addEventListener('dragend', async function (e: DragEvent) { + e.preventDefault(); + (e.target as HTMLElement).style.opacity = ''; + clearPreview(meet); + const obj = dragged.nodeObj; + switch (insertLocation) { + case 'before': + mind.moveNodeBefore(dragged, meet); + mind.selectNode(E(obj.id)); + break; + case 'after': + mind.moveNodeAfter(dragged, meet); + mind.selectNode(E(obj.id)); + break; + case 'in': + mind.moveNode(dragged, meet); + break; + } + (dragged.parentNode.parentNode as Group).style.opacity = '1'; + dragged = null; + }); + + mind.map.addEventListener( + 'dragover', + throttle(function (e: DragEvent) { + // console.log('drag', e) + clearPreview(meet); + // minus threshold infer that postion of the cursor is above topic + const topMeet = $d.elementFromPoint(e.clientX, e.clientY - threshold); + if (canPreview(topMeet, dragged)) { + meet = topMeet; + const y = topMeet.getBoundingClientRect().y; + if (e.clientY > y + topMeet.clientHeight) { + insertLocation = 'after'; + } else if (e.clientY > y + topMeet.clientHeight / 2) { + insertLocation = 'in'; + } + } else { + const bottomMeet = $d.elementFromPoint(e.clientX, e.clientY + threshold); + if (canPreview(bottomMeet, dragged)) { + meet = bottomMeet; + const y = bottomMeet.getBoundingClientRect().y; + if (e.clientY < y) { + insertLocation = 'before'; + } else if (e.clientY < y + bottomMeet.clientHeight / 2) { + insertLocation = 'in'; + } + } else { + insertLocation = meet = null; + } + } + if (meet) insertPreview(meet, insertLocation); + }, 200) + ); +} 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 new file mode 100644 index 00000000..664bf664 --- /dev/null +++ b/packages/client/src/tiptap/wrappers/mind/mind-elixir/plugin/nodeMenu.tsx @@ -0,0 +1,113 @@ +import tippy from 'tippy.js'; +import ReactDOM from 'react-dom'; +import { Button, Tooltip, Space } from '@douyinfe/semi-ui'; +import { IconBold, IconFont, IconMark } from '@douyinfe/semi-icons'; +import { ColorPicker } from 'tiptap/menus/_components/color-picker'; +import { findEle } from '../utils/dom'; + +const Toolbar = ({ toggleBold, setFontColor, setBackgroundColor }) => { + return ( + + +
- ); -};