Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kityminder-core
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
吴志俊
kityminder-core
Commits
d652a8fb
Commit
d652a8fb
authored
Jun 05, 2014
by
techird
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
stash
parent
e2ac6d1e
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
1627 additions
and
1346 deletions
+1627
-1346
import.js
import.js
+88
-84
index.html
index.html
+2
-2
layout.js
src/adapter/layout.js
+19
-19
event.js
src/core/event.js
+17
-17
kityminder.js
src/core/kityminder.js
+40
-33
layout.js
src/core/layout.js
+44
-0
minder.data.js
src/core/minder.data.js
+66
-96
minder.js
src/core/minder.js
+107
-104
minder.module.js
src/core/minder.module.js
+64
-37
minder.node.js
src/core/minder.node.js
+28
-15
minder.select.js
src/core/minder.select.js
+90
-95
node.js
src/core/node.js
+181
-170
render.js
src/core/render.js
+68
-0
theme.js
src/core/theme.js
+14
-18
utils.js
src/core/utils.js
+96
-94
default.js
src/layout/default.js
+11
-0
basestyle.js
src/module/basestyle.js
+45
-45
editor.js
src/module/editor.js
+106
-78
editor.receiver.js
src/module/editor.receiver.js
+190
-191
geometry.js
src/module/geometry.js
+113
-99
keyboard.js
src/module/keyboard.js
+41
-40
outline.js
src/module/outline.js
+35
-0
select.js
src/module/select.js
+51
-51
view.js
src/module/view.js
+81
-58
default.js
src/theme/default.js
+30
-0
No files found.
import.js
View file @
d652a8fb
/**
* 开发版本的文件导入
*/
(
function
()
{
(
function
()
{
var
paths
=
[
'core/kityminder.js'
,
'core/utils.js'
,
'core/command.js'
,
'core/node.js'
,
'core/module.js'
,
'core/event.js'
,
'core/minder.js'
,
'core/minder.data.js'
,
'core/minder.event.js'
,
'core/minder.module.js'
,
'core/minder.command.js'
,
'core/minder.node.js'
,
'core/keymap.js'
,
'core/minder.lang.js'
,
'core/minder.defaultoptions.js'
,
'core/minder.preference.js'
,
'core/browser.js'
,
'module/geometry.js'
,
'module/history.js'
,
'module/icon.js'
,
'module/image.js'
,
'module/resource.js'
,
'module/layout.js'
,
'module/layout.default.js'
,
'module/layout.bottom.js'
,
'core/minder.select.js'
,
'module/view.js'
,
'module/dragtree.js'
,
'module/dropfile.js'
,
'module/keyboard.js'
,
'module/select.js'
,
'module/history.js'
,
'module/editor.js'
,
'module/editor.range.js'
,
'module/editor.receiver.js'
,
'module/editor.selection.js'
,
'module/basestyle.js'
,
'module/font.js'
,
'module/zoom.js'
,
'module/nodetext.js'
,
'module/hyperlink.js'
,
'module/expand.js'
,
'ui/jquery-ui-1.10.4.custom.min.js'
,
'ui/widget.js'
,
'ui/button.js'
,
'ui/toolbar.js'
,
'ui/menu.js'
,
'ui/dropmenu.js'
,
'ui/splitbutton.js'
,
'ui/colorsplitbutton.js'
,
'ui/popup.js'
,
'ui/scale.js'
,
'ui/colorpicker.js'
,
'ui/combobox.js'
,
'ui/buttoncombobox.js'
,
'ui/modal.js'
,
'ui/tooltip.js'
,
'ui/tab.js'
,
'ui/separator.js'
,
'ui/scale.js'
,
'adapter/utils.js'
,
'adapter/adapter.js'
,
'adapter/button.js'
,
'adapter/combobox.js'
,
'adapter/color.js'
,
'adapter/saveto.js'
,
'adapter/tooltips.js'
,
'adapter/layout.js'
,
'adapter/node.js'
,
'adapter/contextmenu.js'
,
'adapter/dialog.js'
,
'adapter/hyperlink.js'
,
'adapter/image.js'
,
'adapter/zoom.js'
,
'protocal/xmind.js'
,
'protocal/freemind.js'
,
'protocal/mindmanager.js'
,
'protocal/plain.js'
,
'protocal/json.js'
,
'protocal/png.js'
,
'protocal/svg.js'
],
baseURL
=
'src/'
,
doc
=
document
;
'core/kityminder.js'
,
'core/utils.js'
,
'core/command.js'
,
'core/node.js'
,
'core/module.js'
,
'core/event.js'
,
'core/minder.js'
,
'core/minder.data.js'
,
'core/minder.event.js'
,
'core/minder.module.js'
,
'core/minder.command.js'
,
'core/minder.node.js'
,
'core/keymap.js'
,
'core/minder.lang.js'
,
'core/minder.defaultoptions.js'
,
'core/minder.preference.js'
,
'core/browser.js'
,
'core/layout.js'
,
'core/render.js'
,
'core/theme.js'
,
'layout/default.js'
,
'theme/default.js'
,
'module/outline.js'
,
'module/geometry.js'
,
'module/history.js'
,
'module/icon.js'
,
'module/image.js'
,
'module/resource.js'
,
'core/minder.select.js'
,
'module/view.js'
,
'module/dragtree.js'
,
'module/dropfile.js'
,
'module/keyboard.js'
,
'module/select.js'
,
'module/history.js'
,
'module/editor.js'
,
'module/editor.range.js'
,
'module/editor.receiver.js'
,
'module/editor.selection.js'
,
'module/basestyle.js'
,
'module/font.js'
,
'module/zoom.js'
,
'module/nodetext.js'
,
'module/hyperlink.js'
,
'module/expand.js'
,
'ui/jquery-ui-1.10.4.custom.min.js'
,
'ui/widget.js'
,
'ui/button.js'
,
'ui/toolbar.js'
,
'ui/menu.js'
,
'ui/dropmenu.js'
,
'ui/splitbutton.js'
,
'ui/colorsplitbutton.js'
,
'ui/popup.js'
,
'ui/scale.js'
,
'ui/colorpicker.js'
,
'ui/combobox.js'
,
'ui/buttoncombobox.js'
,
'ui/modal.js'
,
'ui/tooltip.js'
,
'ui/tab.js'
,
'ui/separator.js'
,
'ui/scale.js'
,
'adapter/utils.js'
,
'adapter/adapter.js'
,
'adapter/button.js'
,
'adapter/combobox.js'
,
'adapter/color.js'
,
'adapter/saveto.js'
,
'adapter/tooltips.js'
,
//'adapter/layout.js',
'adapter/node.js'
,
'adapter/contextmenu.js'
,
'adapter/dialog.js'
,
'adapter/hyperlink.js'
,
'adapter/image.js'
,
'adapter/zoom.js'
,
'protocal/xmind.js'
,
'protocal/freemind.js'
,
'protocal/mindmanager.js'
,
'protocal/plain.js'
,
'protocal/json.js'
,
'protocal/png.js'
,
'protocal/svg.js'
],
baseURL
=
'src/'
,
doc
=
document
;
while
(
paths
.
length
)
{
doc
.
write
(
'<script type="text/javascript" src="'
+
baseURL
+
paths
.
shift
()
+
'"></script>'
);
}
...
...
index.html
View file @
d652a8fb
...
...
@@ -62,8 +62,8 @@
</body>
<script>
// create km instance
window
.
km
=
KM
.
getKityMinder
(
'kityminder'
);
km
=
KM
.
getKityMinder
(
'kityminder'
);
// New Version Notify
$
(
function
()
{
...
...
src/adapter/layout.js
View file @
d652a8fb
KM
.
registerToolbarUI
(
'switchlayout'
,
function
(
name
)
{
KM
.
registerToolbarUI
(
'switchlayout'
,
function
(
name
)
{
var
me
=
this
,
label
=
me
.
getLang
(
'tooltips.'
+
name
),
options
=
{
...
...
@@ -16,24 +16,24 @@ KM.registerToolbarUI('switchlayout', function (name) {
return
null
;
}
utils
.
each
(
options
.
items
,
function
(
i
,
item
)
{
utils
.
each
(
options
.
items
,
function
(
i
,
item
)
{
options
.
items
[
i
]
=
me
.
getLang
(
'layout'
)[
item
];
});
//实例化
$combox
=
$
.
kmuibuttoncombobox
(
options
).
css
(
'zIndex'
,
me
.
getOptions
(
'zIndex'
)
+
1
);
var
comboboxWidget
=
$combox
.
kmui
();
comboboxWidget
.
on
(
'comboboxselect'
,
function
(
evt
,
res
)
{
comboboxWidget
.
on
(
'comboboxselect'
,
function
(
evt
,
res
)
{
me
.
execCommand
(
name
,
res
.
value
);
me
.
initStyle
();
}).
on
(
"beforeshow"
,
function
()
{
}).
on
(
"beforeshow"
,
function
()
{
if
(
$combox
.
parent
().
length
===
0
)
{
$combox
.
appendTo
(
me
.
$container
.
find
(
'.kmui-dialog-container'
));
}
});
//状态反射
me
.
on
(
'interactchange'
,
function
()
{
me
.
on
(
'interactchange'
,
function
()
{
var
state
=
this
.
queryCommandState
(
name
),
value
=
this
.
queryCommandValue
(
name
);
//设置按钮状态
...
...
@@ -48,19 +48,19 @@ KM.registerToolbarUI('switchlayout', function (name) {
});
// var data = [];
// utils.each(me.getLayoutStyleItems(), function (i, v) {
// data.push({
// label: me.getLang('tooltips.' + name) + ' ' + v,
// cmdName: 'switchlayout',
// exec: function () {
// me.execCommand('switchlayout', v);
// }
// });
// });
// data.push({
// divider: 1
// });
// me.addContextmenu(data);
// var data = [];
// utils.each(me.getLayoutStyleItems(), function (i, v) {
// data.push({
// label: me.getLang('tooltips.' + name) + ' ' + v,
// cmdName: 'switchlayout',
// exec: function () {
// me.execCommand('switchlayout', v);
// }
// });
// });
// data.push({
// divider: 1
// });
// me.addContextmenu(data);
return
comboboxWidget
.
button
().
addClass
(
'kmui-combobox'
);
});
\ No newline at end of file
src/core/event.js
View file @
d652a8fb
var
MinderEvent
=
kity
.
createClass
(
'MindEvent'
,
{
constructor
:
function
(
type
,
params
,
canstop
)
{
var
MinderEvent
=
kity
.
createClass
(
'MindEvent'
,
{
constructor
:
function
(
type
,
params
,
canstop
)
{
params
=
params
||
{};
if
(
params
.
getType
&&
params
.
getType
()
==
'ShapeEvent'
)
{
if
(
params
.
getType
&&
params
.
getType
()
==
'ShapeEvent'
)
{
this
.
kityEvent
=
params
;
this
.
originEvent
=
params
.
originEvent
;
this
.
getPosition
=
params
.
getPosition
.
bind
(
params
);
}
else
if
(
params
.
target
&&
params
.
preventDefault
)
{
this
.
getPosition
=
params
.
getPosition
.
bind
(
params
);
}
else
if
(
params
.
target
&&
params
.
preventDefault
)
{
this
.
originEvent
=
params
;
}
else
{
kity
.
Utils
.
extend
(
this
,
params
);
kity
.
Utils
.
extend
(
this
,
params
);
}
this
.
type
=
type
;
this
.
_canstop
=
canstop
||
false
;
},
getTargetNode
:
function
()
{
getTargetNode
:
function
()
{
var
findShape
=
this
.
kityEvent
&&
this
.
kityEvent
.
targetShape
;
if
(
!
findShape
)
return
null
;
while
(
!
findShape
.
minderNode
&&
findShape
.
container
)
{
if
(
!
findShape
)
return
null
;
while
(
!
findShape
.
minderNode
&&
findShape
.
container
)
{
findShape
=
findShape
.
container
;
}
return
findShape
.
minderNode
||
null
;
},
stopPropagation
:
function
()
{
stopPropagation
:
function
()
{
this
.
_stoped
=
true
;
},
stopPropagationImmediately
:
function
()
{
stopPropagationImmediately
:
function
()
{
this
.
_immediatelyStoped
=
true
;
this
.
_stoped
=
true
;
},
shouldStopPropagation
:
function
()
{
shouldStopPropagation
:
function
()
{
return
this
.
_canstop
&&
this
.
_stoped
;
},
shouldStopPropagationImmediately
:
function
()
{
shouldStopPropagationImmediately
:
function
()
{
return
this
.
_canstop
&&
this
.
_immediatelyStoped
;
},
preventDefault
:
function
()
{
preventDefault
:
function
()
{
this
.
originEvent
.
preventDefault
();
},
isRightMB
:
function
()
{
isRightMB
:
function
()
{
var
isRightMB
=
false
;
if
(
!
this
.
originEvent
)
{
if
(
!
this
.
originEvent
)
{
return
false
;
}
if
(
"which"
in
this
.
originEvent
)
...
...
@@ -53,4 +53,4 @@ var MinderEvent = kity.createClass( 'MindEvent', {
isRightMB
=
this
.
originEvent
.
button
==
2
;
return
isRightMB
;
}
}
);
\ No newline at end of file
});
\ No newline at end of file
src/core/kityminder.js
View file @
d652a8fb
var
KityMinder
=
window
.
KM
=
window
.
KityMinder
=
function
()
{
var
instanceMap
=
{},
instanceId
=
0
;
return
{
version
:
'1.1.3.1'
,
createMinder
:
function
(
renderTarget
,
options
)
{
options
=
options
||
{};
options
.
renderTo
=
Utils
.
isString
(
renderTarget
)
?
document
.
getElementById
(
renderTarget
)
:
renderTarget
;
var
minder
=
new
Minder
(
options
);
this
.
addMinder
(
options
.
renderTo
,
minder
);
return
minder
;
},
addMinder
:
function
(
target
,
minder
)
{
var
id
;
if
(
typeof
(
target
)
===
'string'
)
{
id
=
target
;
}
else
{
id
=
target
.
id
||
(
"KM_INSTANCE_"
+
instanceId
++
);
}
instanceMap
[
id
]
=
minder
;
},
getMinder
:
function
(
target
,
options
)
{
var
id
;
if
(
typeof
(
target
)
===
'string'
)
{
id
=
target
;
}
else
{
id
=
target
.
id
||
(
"KM_INSTANCE_"
+
instanceId
++
);
}
return
instanceMap
[
id
]
||
this
.
createMinder
(
target
,
options
);
},
//挂接多语言
LANG
:
{}
};
var
KityMinder
=
window
.
KM
=
window
.
KityMinder
=
function
()
{
var
instanceMap
=
{},
instanceId
=
0
,
uuidMap
=
{};
return
{
version
:
'1.1.3.1'
,
uuid
:
function
(
name
)
{
name
=
name
||
'unknown'
;
uuidMap
[
name
]
=
uuidMap
[
name
]
||
0
;
++
uuidMap
[
name
];
return
name
+
'_'
+
uuidMap
[
name
];
},
createMinder
:
function
(
renderTarget
,
options
)
{
options
=
options
||
{};
options
.
renderTo
=
Utils
.
isString
(
renderTarget
)
?
document
.
getElementById
(
renderTarget
)
:
renderTarget
;
var
minder
=
new
Minder
(
options
);
this
.
addMinder
(
options
.
renderTo
,
minder
);
return
minder
;
},
addMinder
:
function
(
target
,
minder
)
{
var
id
;
if
(
typeof
(
target
)
===
'string'
)
{
id
=
target
;
}
else
{
id
=
target
.
id
||
(
"KM_INSTANCE_"
+
instanceId
++
);
}
instanceMap
[
id
]
=
minder
;
},
getMinder
:
function
(
target
,
options
)
{
var
id
;
if
(
typeof
(
target
)
===
'string'
)
{
id
=
target
;
}
else
{
id
=
target
.
id
||
(
"KM_INSTANCE_"
+
instanceId
++
);
}
return
instanceMap
[
id
]
||
this
.
createMinder
(
target
,
options
);
},
//挂接多语言
LANG
:
{}
};
}();
\ No newline at end of file
src/core/layout.js
View file @
d652a8fb
var
Layout
=
kity
.
createClass
(
'Layout'
,
{
doLayout
:
function
(
node
)
{
throw
new
Error
(
'Not Implement: Layout.doLayout()'
);
}
});
Utils
.
extend
(
KityMinder
,
{
_layout
:
{},
registerLayout
:
function
(
name
,
layout
)
{
KityMinder
.
_layout
[
name
]
=
layout
;
if
(
!
KityMinder
.
_defaultLayout
)
{
KityMinder
.
_defaultLayout
=
name
;
}
}
});
kity
.
extendClass
(
MinderNode
,
{
getLayout
:
function
()
{
var
layout
=
this
.
getData
(
'layout'
);
layout
=
layout
||
(
this
.
isRoot
()
?
KityMinder
.
_defaultLayout
:
this
.
parent
.
getLayout
());
return
layout
;
},
layout
:
function
(
name
)
{
if
(
name
)
{
this
.
setData
(
'layout'
,
name
);
}
var
LayoutClass
=
KityMinder
.
_layout
[
this
.
getLayout
()];
var
layout
=
new
LayoutClass
();
layout
.
doLayout
(
this
);
return
this
;
},
getTreeBox
:
function
()
{
var
box
=
this
.
getContentBox
();
this
.
getChildren
().
forEach
(
function
(
child
)
{
box
=
KityMinder
.
Geometry
.
mergeBox
(
child
.
getTreeBox
(),
box
);
});
return
box
;
}
});
\ No newline at end of file
src/core/minder.data.js
View file @
d652a8fb
Utils
.
extend
(
KityMinder
,
{
Utils
.
extend
(
KityMinder
,
{
_protocals
:
{},
registerProtocal
:
function
(
name
,
protocalDeal
)
{
KityMinder
.
_protocals
[
name
]
=
protocalDeal
();
registerProtocal
:
function
(
name
,
protocalDeal
)
{
KityMinder
.
_protocals
[
name
]
=
protocalDeal
();
},
findProtocal
:
function
(
name
)
{
return
KityMinder
.
_protocals
[
name
]
||
null
;
findProtocal
:
function
(
name
)
{
return
KityMinder
.
_protocals
[
name
]
||
null
;
},
getSupportedProtocals
:
function
()
{
return
Utils
.
keys
(
KityMinder
.
_protocals
).
sort
(
function
(
a
,
b
)
{
return
KityMinder
.
_protocals
[
b
].
recognizePriority
-
KityMinder
.
_protocals
[
a
].
recognizePriority
;
}
);
getSupportedProtocals
:
function
()
{
return
Utils
.
keys
(
KityMinder
.
_protocals
).
sort
(
function
(
a
,
b
)
{
return
KityMinder
.
_protocals
[
b
].
recognizePriority
-
KityMinder
.
_protocals
[
a
].
recognizePriority
;
});
},
getAllRegisteredProtocals
:
function
()
{
getAllRegisteredProtocals
:
function
()
{
return
KityMinder
.
_protocals
;
}
}
);
});
// 这里的 Json 是一个对象
function
exportNode
(
node
)
{
function
exportNode
(
node
)
{
var
exported
=
{};
exported
.
data
=
node
.
getData
();
var
childNodes
=
node
.
getChildren
();
if
(
childNodes
.
length
)
{
if
(
childNodes
.
length
)
{
exported
.
children
=
[];
for
(
var
i
=
0
;
i
<
childNodes
.
length
;
i
++
)
{
exported
.
children
.
push
(
exportNode
(
childNodes
[
i
]
)
);
for
(
var
i
=
0
;
i
<
childNodes
.
length
;
i
++
)
{
exported
.
children
.
push
(
exportNode
(
childNodes
[
i
])
);
}
}
return
exported
;
...
...
@@ -36,61 +36,62 @@ var DEFAULT_TEXT = {
'sub'
:
'topic'
};
function
importNode
(
node
,
json
,
km
)
{
function
importNode
(
node
,
json
,
km
)
{
var
data
=
json
.
data
;
for
(
var
field
in
data
)
{
node
.
setData
(
field
,
data
[
field
]
);
for
(
var
field
in
data
)
{
node
.
setData
(
field
,
data
[
field
]
);
}
node
.
setData
(
'text'
,
data
.
text
||
km
.
getLang
(
DEFAULT_TEXT
[
node
.
getType
()
]
)
);
node
.
setData
(
'text'
,
data
.
text
||
km
.
getLang
(
DEFAULT_TEXT
[
node
.
getType
()]));
node
.
render
();
var
childrenTreeData
=
json
.
children
;
if
(
!
childrenTreeData
)
return
;
for
(
var
i
=
0
;
i
<
childrenTreeData
.
length
;
i
++
)
{
var
childNode
=
new
Minder
Node
();
node
.
appendChild
(
childNode
);
importNode
(
childNode
,
childrenTreeData
[
i
],
km
);
if
(
!
childrenTreeData
)
return
;
for
(
var
i
=
0
;
i
<
childrenTreeData
.
length
;
i
++
)
{
var
childNode
=
km
.
create
Node
();
node
.
appendChild
(
childNode
);
importNode
(
childNode
,
childrenTreeData
[
i
],
km
);
}
return
node
;
}
// 导入导出
kity
.
extendClass
(
Minder
,
{
exportData
:
function
(
protocalName
)
{
kity
.
extendClass
(
Minder
,
{
exportData
:
function
(
protocalName
)
{
var
json
,
protocal
;
json
=
exportNode
(
this
.
getRoot
()
);
protocal
=
KityMinder
.
findProtocal
(
protocalName
);
json
=
exportNode
(
this
.
getRoot
()
);
protocal
=
KityMinder
.
findProtocal
(
protocalName
);
if
(
this
.
_fire
(
new
MinderEvent
(
'beforeexport'
,
{
if
(
this
.
_fire
(
new
MinderEvent
(
'beforeexport'
,
{
json
:
json
,
protocalName
:
protocalName
,
protocal
:
protocal
},
true
)
)
===
true
)
return
;
},
true
))
===
true
)
return
;
if
(
protocal
)
{
return
protocal
.
encode
(
json
,
this
);
if
(
protocal
)
{
return
protocal
.
encode
(
json
,
this
);
}
else
{
return
json
;
}
},
importData
:
function
(
local
,
protocalName
)
{
importData
:
function
(
local
,
protocalName
)
{
var
json
,
protocal
;
if
(
protocalName
)
{
protocal
=
KityMinder
.
findProtocal
(
protocalName
);
if
(
protocalName
)
{
protocal
=
KityMinder
.
findProtocal
(
protocalName
);
}
else
{
KityMinder
.
getSupportedProtocals
().
every
(
function
(
name
)
{
var
test
=
KityMinder
.
findProtocal
(
name
);
if
(
test
.
recognize
&&
test
.
recognize
(
local
)
)
{
KityMinder
.
getSupportedProtocals
().
every
(
function
(
name
)
{
var
test
=
KityMinder
.
findProtocal
(
name
);
if
(
test
.
recognize
&&
test
.
recognize
(
local
)
)
{
protocal
=
test
;
}
return
!
protocal
;
}
);
});
}
if
(
!
protocal
)
{
throw
new
Error
(
"Unsupported protocal: "
+
protocalName
);
if
(
!
protocal
)
{
throw
new
Error
(
'Unsupported protocal: '
+
protocalName
);
}
var
params
=
{
...
...
@@ -100,73 +101,42 @@ kity.extendClass( Minder, {
};
// 是否需要阻止导入
var
stoped
=
this
.
_fire
(
new
MinderEvent
(
'beforeimport'
,
params
,
true
)
);
if
(
stoped
)
return
this
;
var
stoped
=
this
.
_fire
(
new
MinderEvent
(
'beforeimport'
,
params
,
true
)
);
if
(
stoped
)
return
this
;
json
=
params
.
json
||
(
params
.
json
=
protocal
.
decode
(
local
));
//*******************
function
ts
(
d
,
str
,
last
)
{
var
h
=
d
.
getHours
(),
m
=
d
.
getMinutes
(),
s
=
d
.
getSeconds
(),
ms
=
d
.
getMilliseconds
();
if
(
last
)
{
console
.
log
(
'--- '
+
str
+
': '
+
(
d
-
last
)
+
' ---'
);
}
else
{
console
.
log
(
'--- '
+
str
+
' ---'
);
}
return
d
;
}
//var t1 = ts( new Date(), '开始解析' );
//*******************
json
=
params
.
json
||
(
params
.
json
=
protocal
.
decode
(
local
)
);
if
(
typeof
json
===
'object'
&&
'then'
in
json
)
{
if
(
typeof
json
===
'object'
&&
'then'
in
json
)
{
var
self
=
this
;
json
.
then
(
local
,
function
(
data
)
{
//*******************
//var t2 = ts( new Date(), '解压解析耗时', t1 );
//*******************
self
.
_afterImportData
(
data
,
params
);
//*******************
//ts( new Date(), '渲染耗时', t2 );
//*******************
}
);
json
.
then
(
local
,
function
(
data
)
{
self
.
_doImport
(
data
,
params
);
});
}
else
{
//*******************
//var t2 = ts( new Date(), '解压解析耗时', t1 );
//*******************
this
.
_afterImportData
(
json
,
params
);
//*******************
//ts( new Date(), '渲染耗时', t2 );
//*******************
this
.
_doImport
(
json
,
params
);
}
return
this
;
},
_
afterImportData
:
function
(
json
,
params
)
{
this
.
_fire
(
new
MinderEvent
(
'preimport'
,
params
,
false
)
);
_
doImport
:
function
(
json
,
params
)
{
this
.
_fire
(
new
MinderEvent
(
'preimport'
,
params
,
false
)
);
// 删除当前所有节点
while
(
this
.
_root
.
getChildren
().
length
)
{
this
.
_root
.
removeChild
(
0
);
while
(
this
.
_root
.
getChildren
().
length
)
{
this
.
removeNode
(
this
.
_root
.
getChildren
()[
0
]
);
}
var
curLayout
=
this
.
_root
.
getData
(
"currentstyle"
);
this
.
_root
.
setData
();
this
.
_root
.
setData
(
"currentstyle"
,
curLayout
);
importNode
(
this
.
_root
,
json
,
this
);
this
.
fire
(
'beforeimport'
);
this
.
_fire
(
new
MinderEvent
(
'import'
,
params
,
false
)
);
this
.
_firePharse
(
{
importNode
(
this
.
_root
,
json
,
this
);
this
.
_root
.
layout
();
this
.
fire
(
'beforeimport'
,
params
);
this
.
fire
(
'import'
,
params
);
this
.
_firePharse
({
type
:
'contentchange'
}
);
this
.
_firePharse
(
{
});
this
.
_firePharse
({
type
:
'interactchange'
}
);
});
}
}
);
\ No newline at end of file
});
\ No newline at end of file
src/core/minder.js
View file @
d652a8fb
var
Minder
=
KityMinder
.
Minder
=
kity
.
createClass
(
"KityMinder"
,
{
constructor
:
function
(
options
)
{
this
.
_options
=
Utils
.
extend
(
window
.
KITYMINDER_CONFIG
||
{},
options
);
this
.
setDefaultOptions
(
KM
.
defaultOptions
);
var
Minder
=
KityMinder
.
Minder
=
kity
.
createClass
(
'KityMinder'
,
{
constructor
:
function
(
options
)
{
this
.
_options
=
Utils
.
extend
(
window
.
KITYMINDER_CONFIG
||
{},
options
);
this
.
setDefaultOptions
(
KM
.
defaultOptions
);
this
.
_initEvents
();
this
.
_initMinder
();
this
.
_initSelection
();
...
...
@@ -10,17 +10,19 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
this
.
_initContextmenu
();
this
.
_initModules
();
if
(
this
.
getOptions
(
'readOnly'
)
===
true
)
{
if
(
this
.
getOptions
(
'readOnly'
)
===
true
)
{
this
.
setDisabled
();
}
this
.
fire
(
'ready'
);
this
.
getRoot
().
render
().
layout
();
this
.
fire
(
'ready'
);
},
getOptions
:
function
(
key
)
{
getOptions
:
function
(
key
)
{
var
val
;
if
(
key
)
{
if
(
key
)
{
val
=
this
.
getPreferences
(
key
);
return
val
===
null
||
val
===
undefined
?
this
.
_options
[
key
]
:
val
;
}
else
{
return
val
===
null
||
val
===
undefined
?
this
.
_options
[
key
]
:
val
;
}
else
{
val
=
this
.
getPreferences
();
if
(
val
)
{
return
utils
.
extend
(
val
,
this
.
_options
,
true
);
...
...
@@ -29,150 +31,153 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
}
}
},
setDefaultOptions
:
function
(
key
,
val
,
cover
)
{
setDefaultOptions
:
function
(
key
,
val
,
cover
)
{
var
obj
=
{};
if
(
Utils
.
isString
(
key
)
)
{
obj
[
key
]
=
val
;
if
(
Utils
.
isString
(
key
)
)
{
obj
[
key
]
=
val
;
}
else
{
obj
=
key
;
}
utils
.
extend
(
this
.
_options
,
obj
,
!
cover
);
utils
.
extend
(
this
.
_options
,
obj
,
!
cover
);
},
setOptions
:
function
(
key
,
val
)
{
this
.
setPreferences
(
key
,
val
);
setOptions
:
function
(
key
,
val
)
{
this
.
setPreferences
(
key
,
val
);
},
_initMinder
:
function
()
{
_initMinder
:
function
()
{
this
.
_paper
=
new
kity
.
Paper
();
this
.
_paper
.
getNode
().
setAttribute
(
'contenteditable'
,
true
);
this
.
_paper
.
getNode
().
ondragstart
=
function
(
e
)
{
this
.
_paper
.
getNode
().
setAttribute
(
'contenteditable'
,
true
);
this
.
_paper
.
getNode
().
ondragstart
=
function
(
e
)
{
e
.
preventDefault
();
};
this
.
_addRenderContainer
();
this
.
_root
=
new
MinderNode
(
this
.
getLang
().
maintopic
);
this
.
_root
.
setType
(
"root"
);
if
(
this
.
_options
.
renderTo
)
{
this
.
renderTo
(
this
.
_options
.
renderTo
);
//this._paper.setStyle( 'font-family', 'Arial,"Microsoft YaHei",sans-serif' );
this
.
setRoot
(
this
.
createNode
(
this
.
getLang
().
maintopic
));
if
(
this
.
_options
.
renderTo
)
{
this
.
renderTo
(
this
.
_options
.
renderTo
);
}
},
_addRenderContainer
:
function
()
{
this
.
_rc
=
new
kity
.
Group
();
this
.
_paper
.
addShape
(
this
.
_rc
);
_addRenderContainer
:
function
()
{
this
.
_rc
=
new
kity
.
Group
().
setId
(
KityMinder
.
uuid
(
'minder'
));
this
.
_paper
.
addShape
(
this
.
_rc
);
},
renderTo
:
function
(
target
)
{
this
.
_paper
.
renderTo
(
this
.
_renderTarget
=
target
);
renderTo
:
function
(
target
)
{
this
.
_paper
.
renderTo
(
this
.
_renderTarget
=
target
);
this
.
_bindEvents
();
},
getRenderContainer
:
function
()
{
getRenderContainer
:
function
()
{
return
this
.
_rc
;
},
getPaper
:
function
()
{
getPaper
:
function
()
{
return
this
.
_paper
;
},
getRenderTarget
:
function
()
{
getRenderTarget
:
function
()
{
return
this
.
_renderTarget
;
},
_initShortcutKey
:
function
()
{
_initShortcutKey
:
function
()
{
this
.
_shortcutkeys
=
{};
this
.
_bindshortcutKeys
();
},
isTextEditStatus
:
function
()
{
isTextEditStatus
:
function
()
{
return
false
;
},
addShortcutKeys
:
function
(
cmd
,
keys
)
{
var
obj
=
{},
km
=
this
;
if
(
keys
)
{
obj
[
cmd
]
=
keys
;
addShortcutKeys
:
function
(
cmd
,
keys
)
{
var
obj
=
{},
km
=
this
;
if
(
keys
)
{
obj
[
cmd
]
=
keys
;
}
else
{
obj
=
cmd
;
}
utils
.
each
(
obj
,
function
(
k
,
v
)
{
km
.
_shortcutkeys
[
k
.
toLowerCase
()
]
=
v
;
}
);
utils
.
each
(
obj
,
function
(
k
,
v
)
{
km
.
_shortcutkeys
[
k
.
toLowerCase
()
]
=
v
;
});
},
getShortcutKey
:
function
(
cmdName
)
{
return
this
.
_shortcutkeys
[
cmdName
];
getShortcutKey
:
function
(
cmdName
)
{
return
this
.
_shortcutkeys
[
cmdName
];
},
_bindshortcutKeys
:
function
()
{
_bindshortcutKeys
:
function
()
{
var
me
=
this
,
shortcutkeys
=
this
.
_shortcutkeys
;
function
checkkey
(
key
,
keyCode
,
e
)
{
switch
(
key
)
{
case
'ctrl'
:
case
'cmd'
:
if
(
e
.
ctrlKey
||
e
.
metaKey
)
{
return
true
;
}
break
;
case
'alt'
:
if
(
e
.
altKey
)
{
return
true
;
}
break
;
case
'shift'
:
if
(
e
.
shiftKey
)
{
return
true
;
}
function
checkkey
(
key
,
keyCode
,
e
)
{
switch
(
key
)
{
case
'ctrl'
:
case
'cmd'
:
if
(
e
.
ctrlKey
||
e
.
metaKey
)
{
return
true
;
}
break
;
case
'alt'
:
if
(
e
.
altKey
)
{
return
true
;
}
break
;
case
'shift'
:
if
(
e
.
shiftKey
)
{
return
true
;
}
}
if
(
keyCode
==
keymap
[
key
]
)
{
if
(
keyCode
==
keymap
[
key
]
)
{
return
true
;
}
return
false
;
}
me
.
on
(
'keydown'
,
function
(
e
)
{
me
.
on
(
'keydown'
,
function
(
e
)
{
var
originEvent
=
e
.
originEvent
;
var
keyCode
=
originEvent
.
keyCode
||
originEvent
.
which
;
for
(
var
i
in
shortcutkeys
)
{
var
keys
=
shortcutkeys
[
i
].
toLowerCase
().
split
(
'+'
);
for
(
var
i
in
shortcutkeys
)
{
var
keys
=
shortcutkeys
[
i
].
toLowerCase
().
split
(
'+'
);
var
current
=
0
;
utils
.
each
(
keys
,
function
(
i
,
k
)
{
if
(
checkkey
(
k
,
keyCode
,
originEvent
)
)
{
utils
.
each
(
keys
,
function
(
i
,
k
)
{
if
(
checkkey
(
k
,
keyCode
,
originEvent
)
)
{
current
++
;
}
}
);
});
if
(
current
==
keys
.
length
)
{
if
(
me
.
queryCommandState
(
i
)
!=
-
1
)
me
.
execCommand
(
i
);
if
(
current
==
keys
.
length
)
{
if
(
me
.
queryCommandState
(
i
)
!=
-
1
)
me
.
execCommand
(
i
);
originEvent
.
preventDefault
();
break
;
}
}
}
);
});
},
_initContextmenu
:
function
()
{
_initContextmenu
:
function
()
{
this
.
contextmenus
=
[];
},
addContextmenu
:
function
(
item
)
{
if
(
utils
.
isArray
(
item
)
)
{
this
.
contextmenus
=
this
.
contextmenus
.
concat
(
item
);
addContextmenu
:
function
(
item
)
{
if
(
utils
.
isArray
(
item
)
)
{
this
.
contextmenus
=
this
.
contextmenus
.
concat
(
item
);
}
else
{
this
.
contextmenus
.
push
(
item
);
this
.
contextmenus
.
push
(
item
);
}
return
this
;
},
getContextmenu
:
function
()
{
getContextmenu
:
function
()
{
return
this
.
contextmenus
;
},
_initStatus
:
function
()
{
this
.
_status
=
"normal"
;
this
.
_rollbackStatus
=
"normal"
;
_initStatus
:
function
()
{
this
.
_status
=
'normal'
;
this
.
_rollbackStatus
=
'normal'
;
},
setStatus
:
function
(
status
)
{
if
(
status
)
{
setStatus
:
function
(
status
)
{
if
(
status
)
{
this
.
_rollbackStatus
=
this
.
_status
;
this
.
_status
=
status
;
}
else
{
...
...
@@ -180,50 +185,48 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
}
return
this
;
},
rollbackStatus
:
function
()
{
rollbackStatus
:
function
()
{
this
.
_status
=
this
.
_rollbackStatus
;
},
getStatus
:
function
()
{
getStatus
:
function
()
{
return
this
.
_status
;
},
setDisabled
:
function
()
{
setDisabled
:
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
===
false
)
{
return
me
.
bkqueryCommandState
.
apply
(
me
,
arguments
);
me
.
queryCommandState
=
function
(
type
)
{
var
cmd
=
this
.
_getCommand
(
type
);
if
(
cmd
&&
cmd
.
enableReadOnly
===
false
)
{
return
me
.
bkqueryCommandState
.
apply
(
me
,
arguments
);
}
return
-
1
;
};
me
.
queryCommandValue
=
function
(
type
)
{
var
cmd
=
this
.
_getCommand
(
type
);
if
(
cmd
&&
cmd
.
enableReadOnly
===
false
)
{
return
me
.
bkqueryCommandValue
.
apply
(
me
,
arguments
);
me
.
queryCommandValue
=
function
(
type
)
{
var
cmd
=
this
.
_getCommand
(
type
);
if
(
cmd
&&
cmd
.
enableReadOnly
===
false
)
{
return
me
.
bkqueryCommandValue
.
apply
(
me
,
arguments
);
}
return
null
;
};
this
.
setStatus
(
'readonly'
);
me
.
fire
(
'interactchange'
);
this
.
setStatus
(
'readonly'
);
me
.
fire
(
'interactchange'
);
},
setEnabled
:
function
()
{
setEnabled
:
function
()
{
var
me
=
this
;
if
(
me
.
bkqueryCommandState
)
{
if
(
me
.
bkqueryCommandState
)
{
me
.
queryCommandState
=
me
.
bkqueryCommandState
;
delete
me
.
bkqueryCommandState
;
}
if
(
me
.
bkqueryCommandValue
)
{
if
(
me
.
bkqueryCommandValue
)
{
me
.
queryCommandValue
=
me
.
bkqueryCommandValue
;
delete
me
.
bkqueryCommandValue
;
}
this
.
rollbackStatus
();
me
.
fire
(
'interactchange'
);
me
.
fire
(
'interactchange'
);
}
}
);
\ No newline at end of file
});
\ No newline at end of file
src/core/minder.module.js
View file @
d652a8fb
// 模块声明周期维护
kity
.
extendClass
(
Minder
,
{
_initModules
:
function
()
{
kity
.
extendClass
(
Minder
,
{
_initModules
:
function
()
{
var
modulesPool
=
KityMinder
.
getModules
();
var
modulesToLoad
=
this
.
_options
.
modules
||
Utils
.
keys
(
modulesPool
);
var
modulesToLoad
=
this
.
_options
.
modules
||
Utils
.
keys
(
modulesPool
);
this
.
_commands
=
{};
this
.
_query
=
{};
this
.
_modules
=
{};
var
i
,
name
,
type
,
module
,
moduleDeals
,
dealCommands
,
dealEvents
;
this
.
_renderers
=
{
center
:
[],
left
:
[],
right
:
[],
top
:
[],
bottom
:
[],
outline
:
[]
};
var
i
,
name
,
type
,
module
,
moduleDeals
,
dealCommands
,
dealEvents
,
dealRenderers
;
var
me
=
this
;
for
(
i
=
0
;
i
<
modulesToLoad
.
length
;
i
++
)
{
name
=
modulesToLoad
[
i
];
for
(
i
=
0
;
i
<
modulesToLoad
.
length
;
i
++
)
{
name
=
modulesToLoad
[
i
];
if
(
!
modulesPool
[
name
]
)
continue
;
if
(
!
modulesPool
[
name
]
)
continue
;
//执行模块初始化,抛出后续处理对象
moduleDeals
=
modulesPool
[
name
].
call
(
me
);
this
.
_modules
[
name
]
=
moduleDeals
;
//
执行模块初始化,抛出后续处理对象
moduleDeals
=
modulesPool
[
name
].
call
(
me
);
this
.
_modules
[
name
]
=
moduleDeals
;
if
(
moduleDeals
.
init
)
{
moduleDeals
.
init
.
call
(
me
,
this
.
_options
);
if
(
moduleDeals
.
init
)
{
moduleDeals
.
init
.
call
(
me
,
this
.
_options
);
}
//command加入命令池子
//
command加入命令池子
dealCommands
=
moduleDeals
.
commands
;
for
(
name
in
dealCommands
)
{
this
.
_commands
[
name
.
toLowerCase
()
]
=
new
dealCommands
[
name
]();
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
]
);
if
(
dealEvents
)
{
for
(
type
in
dealEvents
)
{
me
.
on
(
type
,
dealEvents
[
type
]
);
}
}
if
(
moduleDeals
.
defaultOptions
)
{
this
.
setDefaultOptions
(
moduleDeals
.
defaultOptions
);
// 渲染器
dealRenderers
=
moduleDeals
.
renderers
;
if
(
dealRenderers
)
{
for
(
type
in
dealRenderers
)
{
if
(
!
(
type
in
this
.
_renderers
))
continue
;
if
(
Utils
.
isArray
(
dealRenderers
[
type
]))
{
this
.
_renderers
[
type
]
=
this
.
_renderers
[
type
].
concat
(
dealRenderers
[
type
]);
}
else
{
this
.
_renderers
[
type
].
push
(
dealRenderers
[
type
]);
}
}
}
if
(
moduleDeals
.
defaultOptions
)
{
this
.
setDefaultOptions
(
moduleDeals
.
defaultOptions
);
}
//添加模块的快捷键
if
(
moduleDeals
.
addShortcutKeys
)
{
this
.
addShortcutKeys
(
moduleDeals
.
addShortcutKeys
);
if
(
moduleDeals
.
addShortcutKeys
)
{
this
.
addShortcutKeys
(
moduleDeals
.
addShortcutKeys
);
}
//添加邮件菜单
if
(
moduleDeals
.
contextmenu
)
{
if
(
moduleDeals
.
contextmenu
)
{
this
.
addContextmenu
(
moduleDeals
.
contextmenu
);
}
}
},
_garbage
:
function
()
{
_garbage
:
function
()
{
this
.
clearSelect
();
while
(
this
.
_root
.
getChildren
().
length
)
{
this
.
_root
.
removeChild
(
0
);
while
(
this
.
_root
.
getChildren
().
length
)
{
this
.
_root
.
removeChild
(
0
);
}
},
destroy
:
function
()
{
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
);
for
(
var
key
in
modules
)
{
if
(
!
modules
[
key
].
destroy
)
continue
;
modules
[
key
].
destroy
.
call
(
this
);
}
},
reset
:
function
()
{
reset
:
function
()
{
var
modules
=
this
.
_modules
;
this
.
_garbage
();
for
(
var
key
in
modules
)
{
if
(
!
modules
[
key
].
reset
)
continue
;
modules
[
key
].
reset
.
call
(
this
);
for
(
var
key
in
modules
)
{
if
(
!
modules
[
key
].
reset
)
continue
;
modules
[
key
].
reset
.
call
(
this
);
}
}
}
);
\ No newline at end of file
});
\ No newline at end of file
src/core/minder.node.js
View file @
d652a8fb
...
...
@@ -3,35 +3,48 @@ kity.extendClass(Minder, {
getRoot
:
function
()
{
return
this
.
_root
;
},
setRoot
:
function
(
root
)
{
this
.
_root
=
root
;
root
.
minder
=
this
;
},
createNode
:
function
(
unknown
)
{
var
node
=
new
MinderNode
(
unknown
);
this
.
handelNodeCreate
(
node
);
return
node
;
},
removeNode
:
function
(
node
)
{
if
(
node
.
parent
)
{
node
.
parent
.
removeChild
(
node
);
this
.
handelNodeRemove
(
node
);
}
},
handelNodeInsert
:
function
(
node
)
{
handelNodeCreate
:
function
(
node
)
{
var
rc
=
this
.
_rc
;
// node.traverse( function ( current
) {
// rc.addShape( current.getRenderContainer()
);
// }
);
node
.
traverse
(
function
(
current
)
{
rc
.
addShape
(
current
.
getRenderContainer
()
);
}
);
rc
.
addShape
(
node
.
getRenderContainer
());
},
handelNodeRemove
:
function
(
node
)
{
var
rc
=
this
.
_rc
;
node
.
traverse
(
function
(
current
)
{
rc
.
removeShape
(
current
.
getRenderContainer
());
});
},
renderNodes
:
function
(
nodes
)
{
var
km
=
this
;
if
(
nodes
instanceof
Array
)
{
if
(
nodes
.
length
===
0
)
return
false
;
for
(
var
i
=
0
;
i
<
nodes
.
length
;
i
++
)
{
km
.
renderNode
(
nodes
[
i
]);
}
}
else
{
km
.
renderNode
(
nodes
);
}
},
getMinderTitle
:
function
()
{
return
this
.
getRoot
().
getText
();
}
});
kity
.
extendClass
(
MinderNode
,
{
getMinder
:
function
()
{
return
this
.
root
.
minder
;
}
});
\ No newline at end of file
src/core/minder.select.js
View file @
d652a8fb
// 选区管理
kity
.
extendClass
(
Minder
,
function
()
{
function
highlightNode
(
km
,
node
)
{
if
(
node
){
node
.
setTmpData
(
"highlight"
,
true
);
km
.
highlightNode
(
node
);
kity
.
extendClass
(
Minder
,
{
_initSelection
:
function
()
{
this
.
_selectedNodes
=
[];
},
renderChangedSelection
:
function
(
changed
)
{
var
i
=
0
;
while
(
i
<
changed
.
length
)
changed
[
i
++
].
render
();
},
getSelectedNodes
:
function
()
{
//不能克隆返回,会对当前选区操作,从而影响querycommand
return
this
.
_selectedNodes
;
},
getSelectedNode
:
function
()
{
return
this
.
getSelectedNodes
()[
0
]
||
null
;
},
removeAllSelectedNodes
:
function
()
{
var
me
=
this
;
var
changed
=
this
.
_selectedNodes
;
this
.
_selectedNodes
=
[];
this
.
renderChangedSelection
(
changed
);
return
this
.
fire
(
'selectionclear'
);
},
removeSelectedNodes
:
function
(
nodes
)
{
var
me
=
this
;
nodes
=
Utils
.
isArray
(
nodes
)
?
nodes
:
[
nodes
];
Utils
.
each
(
nodes
,
function
(
i
,
n
)
{
var
index
;
if
((
index
=
me
.
_selectedNodes
.
indexOf
(
n
))
===
-
1
)
return
;
me
.
_selectedNodes
.
splice
(
index
,
1
);
});
this
.
renderChangedSelection
(
nodes
);
return
this
;
},
select
:
function
(
nodes
,
isToggleSelect
)
{
if
(
isToggleSelect
)
{
this
.
removeAllSelectedNodes
();
}
}
var
me
=
this
;
nodes
=
Utils
.
isArray
(
nodes
)
?
nodes
:
[
nodes
];
Utils
.
each
(
nodes
,
function
(
i
,
n
)
{
if
(
me
.
_selectedNodes
.
indexOf
(
n
)
!==
-
1
)
return
;
me
.
_selectedNodes
.
push
(
n
);
});
this
.
renderChangedSelection
(
nodes
);
return
this
;
},
function
unhighlightNode
(
km
,
node
)
{
if
(
node
){
node
.
setTmpData
(
"highlight"
,
false
);
km
.
highlightNode
(
node
);
//当前选区中的节点在给定的节点范围内的保留选中状态,
//没在给定范围的取消选中,给定范围中的但没在当前选中范围的也做选中效果
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
{
_initSelection
:
function
()
{
this
.
_selectedNodes
=
[];
},
getSelectedNodes
:
function
()
{
//不能克隆返回,会对当前选区操作,从而影响querycommand
return
this
.
_selectedNodes
;
},
getSelectedNode
:
function
()
{
return
this
.
getSelectedNodes
()[
0
]
||
null
;
},
removeAllSelectedNodes
:
function
()
{
var
me
=
this
;
Utils
.
each
(
this
.
getSelectedNodes
(),
function
(
i
,
n
)
{
unhighlightNode
(
me
,
n
);
}
);
this
.
_selectedNodes
=
[];
return
this
.
fire
(
'selectionclear'
);
},
removeSelectedNodes
:
function
(
nodes
)
{
var
me
=
this
;
Utils
.
each
(
Utils
.
isArray
(
nodes
)
?
nodes
:
[
nodes
],
function
(
i
,
n
)
{
var
index
;
if
(
(
index
=
me
.
_selectedNodes
.
indexOf
(
n
)
)
===
-
1
)
return
;
me
.
_selectedNodes
.
splice
(
index
,
1
);
unhighlightNode
(
me
,
n
);
}
);
return
this
;
},
select
:
function
(
nodes
,
isToggleSelect
)
{
if
(
isToggleSelect
)
{
this
.
removeAllSelectedNodes
();
}
var
me
=
this
;
Utils
.
each
(
Utils
.
isArray
(
nodes
)
?
nodes
:
[
nodes
],
function
(
i
,
n
)
{
if
(
me
.
_selectedNodes
.
indexOf
(
n
)
!==
-
1
)
return
;
me
.
_selectedNodes
.
push
(
n
);
highlightNode
(
me
,
n
);
}
);
return
this
;
},
return
this
;
},
isNodeSelected
:
function
(
node
)
{
return
node
.
getTmpData
(
'highlight'
)
===
true
;
},
//当前选区中的节点在给定的节点范围内的保留选中状态,
//没在给定范围的取消选中,给定范围中的但没在当前选中范围的也做选中效果
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
()
{
var
nodes
=
this
.
getSelectedNodes
().
slice
(
0
),
isSingleSelect
:
function
()
{
return
this
.
_selectedNodes
.
length
==
1
;
},
getSelectedAncestors
:
function
()
{
var
nodes
=
this
.
getSelectedNodes
().
slice
(
0
),
ancestors
=
[],
judge
;
// 根节点不参与计算
var
rootIndex
=
nodes
.
indexOf
(
this
.
getRoot
()
);
if
(
~
rootIndex
)
{
nodes
.
splice
(
rootIndex
,
1
);
}
// 根节点不参与计算
var
rootIndex
=
nodes
.
indexOf
(
this
.
getRoot
()
);
if
(
~
rootIndex
)
{
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 列表中是否存在 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
();
}
);
// 按照拓扑排序
nodes
.
sort
(
function
(
node1
,
node2
)
{
return
node1
.
getLevel
()
-
node2
.
getLevel
();
}
);
// 因为是拓扑有序的,所以只需往上查找
while
(
(
judge
=
nodes
.
pop
()
)
)
{
if
(
!
hasAncestor
(
nodes
,
judge
)
)
{
ancestors
.
push
(
judge
);
}
// 因为是拓扑有序的,所以只需往上查找
while
((
judge
=
nodes
.
pop
()))
{
if
(
!
hasAncestor
(
nodes
,
judge
))
{
ancestors
.
push
(
judge
);
}
return
ancestors
;
}
};
}()
);
\ No newline at end of file
return
ancestors
;
}
});
kity
.
extendClass
(
MinderNode
,
{
isSelected
:
function
()
{
return
(
~
this
.
getMinder
().
getSelectedNodes
().
indexOf
(
this
));
}
});
\ No newline at end of file
src/core/node.js
View file @
d652a8fb
var
MinderNode
=
KityMinder
.
MinderNode
=
kity
.
createClass
(
"MinderNode"
,
{
constructor
:
function
(
options
)
{
var
MinderNode
=
KityMinder
.
MinderNode
=
kity
.
createClass
(
'MinderNode'
,
{
/**
* 创建一个节点
*
* @param {KityMinder} minder
* 节点绑定的脑图的实例
*
* @param {String|Object} unknown
* 节点的初始数据或文本
*/
constructor
:
function
(
unknown
)
{
this
.
parent
=
null
;
this
.
root
=
this
;
this
.
children
=
[];
this
.
data
=
{};
this
.
tmpData
=
{};
if
(
Utils
.
isString
(
options
)
)
{
this
.
setData
(
'text'
,
options
);
this
.
initContainers
();
if
(
Utils
.
isString
(
unknown
))
{
this
.
setText
(
unknown
);
}
else
{
this
.
setData
(
options
);
this
.
setData
(
unknown
);
}
this
.
setData
(
"layout"
,
{}
);
},
setType
:
function
(
type
)
{
this
.
setData
(
'type'
,
type
);
initContainers
:
function
()
{
this
.
rc
=
new
kity
.
Group
().
setId
(
KityMinder
.
uuid
(
'minder_node'
));
this
.
rc
.
minderNode
=
this
;
},
/**
* 判断节点是否根节点
*/
isRoot
:
function
()
{
return
this
.
root
===
this
;
},
/**
* 获取节点的根节点
*/
getRoot
:
function
()
{
return
this
.
root
||
this
;
},
/**
* 获得节点的父节点
*/
getParent
:
function
()
{
return
this
.
parent
;
},
getLevel
:
function
()
{
/**
* 获得节点的深度
*/
getLevel
:
function
()
{
var
level
=
0
,
parent
=
this
.
parent
;
while
(
parent
)
{
while
(
parent
)
{
level
++
;
parent
=
parent
.
parent
;
}
return
level
;
},
getType
:
function
(
type
)
{
var
cached
=
this
.
getData
(
'type'
);
if
(
cached
)
{
return
cached
;
/**
* 获得节点的类型(root|main|sub)
*/
getType
:
function
(
type
)
{
if
(
this
.
type
)
{
return
this
.
type
;
}
var
level
=
Math
.
min
(
this
.
getLevel
(),
2
);
cached
=
[
'root'
,
'main'
,
'sub'
][
level
];
this
.
setData
(
'type'
,
cached
);
return
cached
;
},
setText
:
function
(
text
)
{
this
.
setData
(
'text'
,
text
);
this
.
getTextShape
().
setContent
(
text
);
},
getText
:
function
()
{
return
this
.
getData
(
'text'
);
},
isRoot
:
function
()
{
return
this
.
getParent
()
===
null
?
true
:
false
;
},
getParent
:
function
()
{
return
this
.
parent
;
this
.
type
=
[
'root'
,
'main'
,
'sub'
][
Math
.
min
(
this
.
getLevel
(),
2
)];
return
this
.
type
;
},
getDepth
:
function
()
{
var
depth
=
0
,
p
=
this
.
parent
;
while
(
p
)
{
/**
* 判断当前节点是否被测试节点的祖先
* @param {MinderNode} test 被测试的节点
*/
isAncestorOf
:
function
(
test
)
{
var
p
=
test
.
parent
;
while
(
p
)
{
if
(
p
==
this
)
return
true
;
p
=
p
.
parent
;
depth
++
;
}
return
depth
;
return
false
;
},
getRoot
:
function
()
{
var
root
=
this
;
while
(
root
.
parent
)
{
root
=
root
.
parent
;
}
return
root
;
/**
* 设置节点的文本数据
* @param {String} text 文本数据
*/
setText
:
function
(
text
)
{
this
.
setData
(
'text'
,
text
)
;
},
isAncestorOf
:
function
(
test
)
{
var
p
=
test
.
parent
;
while
(
p
)
{
if
(
p
==
this
)
return
true
;
p
=
p
.
parent
;
}
return
false
;
/**
* 获取节点的文本数据
* @return {String}
*/
getText
:
function
()
{
return
this
.
getData
(
'text'
);
},
preTraverse
:
function
(
fn
)
{
/**
* 先序遍历当前节点树
* @param {Function} fn 遍历函数
*/
preTraverse
:
function
(
fn
)
{
var
children
=
this
.
getChildren
();
fn
(
this
);
for
(
var
i
=
0
;
i
<
children
.
length
;
i
++
)
{
children
[
i
].
preTraverse
(
fn
);
var
value
=
fn
(
this
);
for
(
var
i
=
0
;
i
<
children
.
length
;
i
++
)
{
value
=
children
[
i
].
preTraverse
(
fn
,
value
);
}
},
postTraverse
:
function
(
fn
)
{
/**
* 后序遍历当前节点树
* @param {Function} fn 遍历函数
*/
postTraverse
:
function
(
fn
)
{
var
children
=
this
.
getChildren
();
for
(
var
i
=
0
;
i
<
children
.
length
;
i
++
)
{
children
[
i
].
postTraverse
(
fn
);
var
value
;
for
(
var
i
=
0
;
i
<
children
.
length
;
i
++
)
{
value
=
children
[
i
].
postTraverse
(
fn
,
value
);
}
fn
(
this
);
fn
(
this
,
value
);
},
traverse
:
function
(
fn
)
{
return
this
.
postTraverse
(
fn
);
traverse
:
function
(
fn
)
{
return
this
.
postTraverse
(
fn
);
},
getChildren
:
function
()
{
getChildren
:
function
()
{
return
this
.
children
;
},
getIndex
:
function
()
{
return
this
.
parent
?
this
.
parent
.
children
.
indexOf
(
this
)
:
-
1
;
getIndex
:
function
()
{
return
this
.
parent
?
this
.
parent
.
children
.
indexOf
(
this
)
:
-
1
;
},
insertChild
:
function
(
node
,
index
)
{
if
(
index
===
undefined
)
{
insertChild
:
function
(
node
,
index
)
{
if
(
index
===
undefined
)
{
index
=
this
.
children
.
length
;
}
if
(
node
.
parent
)
{
node
.
parent
.
removeChild
(
node
);
if
(
node
.
parent
)
{
node
.
parent
.
removeChild
(
node
);
}
node
.
parent
=
this
;
node
.
root
=
node
.
parent
.
root
;
node
.
root
=
this
.
root
;
this
.
children
.
splice
(
index
,
0
,
node
);
this
.
children
.
splice
(
index
,
0
,
node
);
},
appendChild
:
function
(
node
)
{
return
this
.
insertChild
(
node
);
appendChild
:
function
(
node
)
{
return
this
.
insertChild
(
node
);
},
prependChild
:
function
(
node
)
{
return
this
.
insertChild
(
node
,
0
);
prependChild
:
function
(
node
)
{
return
this
.
insertChild
(
node
,
0
);
},
removeChild
:
function
(
elem
)
{
removeChild
:
function
(
elem
)
{
var
index
=
elem
,
removed
;
if
(
elem
instanceof
MinderNode
)
{
index
=
this
.
children
.
indexOf
(
elem
);
if
(
elem
instanceof
MinderNode
)
{
index
=
this
.
children
.
indexOf
(
elem
);
}
if
(
index
>=
0
)
{
removed
=
this
.
children
.
splice
(
index
,
1
)[
0
];
if
(
index
>=
0
)
{
removed
=
this
.
children
.
splice
(
index
,
1
)[
0
];
removed
.
parent
=
null
;
}
},
getChild
:
function
(
index
)
{
return
this
.
children
[
index
];
getChild
:
function
(
index
)
{
return
this
.
children
[
index
];
},
getFirstChild
:
function
()
{
return
this
.
children
[
0
];
getFirstChild
:
function
()
{
return
this
.
children
[
0
];
},
getLastChild
:
function
()
{
return
this
.
children
[
this
.
children
.
length
-
1
];
getLastChild
:
function
()
{
return
this
.
children
[
this
.
children
.
length
-
1
];
},
getData
:
function
(
name
)
{
if
(
name
===
undefined
)
{
getData
:
function
(
name
)
{
if
(
name
===
undefined
)
{
return
this
.
data
;
}
return
this
.
data
[
name
];
return
this
.
data
[
name
];
},
setData
:
function
(
name
,
value
)
{
if
(
name
===
undefined
)
{
setData
:
function
(
name
,
value
)
{
if
(
name
===
undefined
)
{
this
.
data
=
{};
}
else
if
(
utils
.
isObject
(
name
)
)
{
Utils
.
extend
(
this
.
data
,
name
);
}
else
if
(
utils
.
isObject
(
name
)
)
{
Utils
.
extend
(
this
.
data
,
name
);
}
else
{
if
(
value
===
undefined
)
{
this
.
data
[
name
]
=
null
;
delete
this
.
data
[
name
];
if
(
value
===
undefined
)
{
this
.
data
[
name
]
=
null
;
delete
this
.
data
[
name
];
}
else
{
this
.
data
[
name
]
=
value
;
this
.
data
[
name
]
=
value
;
}
}
},
getRenderContainer
:
function
()
{
getRenderContainer
:
function
()
{
return
this
.
rc
;
},
getCommonAncestor
:
function
(
node
)
{
return
Utils
.
getNodeCommonAncestor
(
this
,
node
);
getCommonAncestor
:
function
(
node
)
{
return
Utils
.
getNodeCommonAncestor
(
this
,
node
);
},
contains
:
function
(
node
)
{
if
(
this
===
node
)
{
return
true
;
}
if
(
this
===
node
.
parent
)
{
return
true
;
}
var
isContain
=
false
;
Utils
.
each
(
this
.
getChildren
(),
function
(
i
,
n
)
{
isContain
=
n
.
contains
(
node
);
if
(
isContain
===
true
)
{
return
false
;
}
}
);
return
isContain
;
contains
:
function
(
node
)
{
return
this
==
node
||
this
.
isAncestorOf
(
node
);
},
clone
:
function
()
{
function
cloneNode
(
parent
,
isClonedNode
)
{
var
_tmp
=
new
KM
.
MinderNode
(
isClonedNode
.
getText
()
);
_tmp
.
data
=
Utils
.
clonePlainObject
(
isClonedNode
.
getData
()
);
_tmp
.
tmpData
=
Utils
.
clonePlainObject
(
isClonedNode
.
getTmpData
()
);
_tmp
.
parent
=
parent
;
clone
:
function
()
{
function
cloneNode
(
parent
,
isClonedNode
)
{
var
cloned
=
new
KM
.
MinderNode
();
cloned
.
data
=
Utils
.
clonePlainObject
(
isClonedNode
.
getData
());
cloned
.
tmpData
=
Utils
.
clonePlainObject
(
isClonedNode
.
getTmpData
());
if
(
parent
)
{
parent
.
children
.
push
(
_tmp
);
if
(
parent
)
{
parent
.
appendChild
(
cloned
);
}
for
(
var
i
=
0
,
ci
;
(
ci
=
isClonedNode
.
children
[
i
++
]
);
)
{
cloneNode
(
_tmp
,
ci
);
for
(
var
i
=
0
,
ci
;
(
ci
=
isClonedNode
.
children
[
i
++
]);
)
{
cloneNode
(
cloned
,
ci
);
}
return
_tmp
;
return
cloned
;
}
return
function
()
{
return
cloneNode
(
null
,
this
);
};
}(),
equals
:
function
(
node
)
{
if
(
node
.
children
.
length
!=
this
.
children
.
length
)
{
return
cloneNode
(
null
,
this
);
},
equals
:
function
(
node
)
{
if
(
node
.
children
.
length
!=
this
.
children
.
length
)
{
return
false
;
}
if
(
utils
.
compareObject
(
node
.
getData
(),
this
.
getData
()
)
===
false
)
{
if
(
utils
.
compareObject
(
node
.
getData
(),
this
.
getData
())
===
false
)
{
return
false
;
}
if
(
utils
.
compareObject
(
node
.
getTmpData
(),
this
.
getTmpData
()
)
===
false
)
{
if
(
utils
.
compareObject
(
node
.
getTmpData
(),
this
.
getTmpData
())
===
false
)
{
return
false
;
}
for
(
var
i
=
0
,
ci
;
(
ci
=
this
.
children
[
i
]
);
i
++
)
{
if
(
ci
.
equals
(
node
.
children
[
i
]
)
===
false
)
{
for
(
var
i
=
0
,
ci
;
(
ci
=
this
.
children
[
i
]);
i
++
)
{
if
(
ci
.
equals
(
node
.
children
[
i
])
===
false
)
{
return
false
;
}
}
return
true
;
},
getTextShape
:
function
()
{
var
textShape
;
utils
.
each
(
this
.
getContRc
().
getShapesByType
(
'text'
),
function
(
i
,
t
)
{
if
(
t
.
getAttr
(
'_nodeTextShape'
)
)
{
textShape
=
t
;
return
false
;
}
}
);
return
textShape
;
},
isSelected
:
function
()
{
return
this
.
getTmpData
(
'highlight'
)
===
true
;
},
clearChildren
:
function
()
{
clearChildren
:
function
()
{
this
.
children
=
[];
},
isHighlight
:
function
()
{
return
this
.
getTmpData
(
'highlight'
)
},
select
:
function
(){
this
.
setTmpData
(
'highlight'
,
true
)
},
setTmpData
:
function
(
a
,
v
)
{
setTmpData
:
function
(
a
,
v
)
{
var
me
=
this
;
if
(
utils
.
isObject
(
a
)
)
{
utils
.
each
(
a
,
function
(
key
,
val
)
{
me
.
setTmpData
(
key
,
val
)
}
)
if
(
utils
.
isObject
(
a
)
)
{
utils
.
each
(
a
,
function
(
key
,
val
)
{
me
.
setTmpData
(
key
,
val
);
}
);
}
if
(
v
===
undefined
||
v
===
null
||
v
===
''
)
{
delete
this
.
tmpData
[
a
];
if
(
v
===
undefined
||
v
===
null
||
v
===
''
)
{
delete
this
.
tmpData
[
a
];
}
else
{
this
.
tmpData
[
a
]
=
v
;
this
.
tmpData
[
a
]
=
v
;
}
},
getTmpData
:
function
(
a
)
{
if
(
a
===
undefined
)
{
getTmpData
:
function
(
a
)
{
if
(
a
===
undefined
)
{
return
this
.
tmpData
;
}
return
this
.
tmpData
[
a
]
return
this
.
tmpData
[
a
];
},
setValue
:
function
(
node
){
setValue
:
function
(
node
)
{
this
.
data
=
{};
this
.
setData
(
utils
.
clonePlainObject
(
node
.
getData
()));
this
.
tmpData
=
{};
this
.
setTmpData
(
utils
.
clonePlainObject
(
node
.
getTmpData
()));
return
this
;
}
}
);
\ No newline at end of file
});
\ No newline at end of file
src/core/render.js
View file @
d652a8fb
var
Renderer
=
kity
.
createClass
(
'Renderer'
,
{
create
:
function
(
node
)
{
throw
new
Error
(
'Not implement: Renderer.create()'
);
},
update
:
function
(
node
)
{
throw
new
Error
(
'Not implement: Renderer.update()'
);
}
});
kity
.
extendClass
(
MinderNode
,
{
getContentBox
:
function
()
{
return
this
.
_contentBox
;
}
});
kity
.
extendClass
(
Minder
,
{
_createRendererForNode
:
function
(
node
)
{
var
registered
=
this
.
_renderers
;
var
renderers
=
[];
renderers
=
renderers
.
concat
(
registered
.
center
);
renderers
=
renderers
.
concat
(
registered
.
left
);
renderers
=
renderers
.
concat
(
registered
.
right
);
renderers
=
renderers
.
concat
(
registered
.
top
);
renderers
=
renderers
.
concat
(
registered
.
bottom
);
renderers
=
renderers
.
concat
(
registered
.
outline
);
node
.
_renderers
=
renderers
.
map
(
function
(
Renderer
)
{
var
renderer
=
new
Renderer
();
renderer
.
create
(
node
);
return
renderer
;
});
},
renderNode
:
function
(
node
)
{
var
rendererClasses
=
this
.
_renderers
,
g
=
KityMinder
.
Geometry
,
contentBox
=
node
.
_contentBox
=
g
.
wrapBox
({
left
:
0
,
right
:
0
,
top
:
0
,
bottom
:
0
});
var
i
,
latestBox
;
if
(
!
node
.
_renderers
)
{
this
.
_createRendererForNode
(
node
);
}
for
(
i
=
0
;
i
<
node
.
_renderers
.
length
;
i
++
)
{
latestBox
=
node
.
_renderers
[
i
].
update
(
node
);
if
(
latestBox
)
{
node
.
_contentBox
=
contentBox
=
g
.
mergeBox
(
contentBox
,
latestBox
);
}
}
}
});
kity
.
extendClass
(
MinderNode
,
{
render
:
function
()
{
this
.
getMinder
().
renderNode
(
this
);
return
this
;
},
getContentBox
:
function
()
{
return
this
.
_contentBox
;
}
});
\ No newline at end of file
src/core/theme.js
View file @
d652a8fb
...
...
@@ -46,7 +46,7 @@ kity.extendClass(Minder, {
* @param {String} name 要使用的主题的名称
*/
useTheme
:
function
(
name
)
{
if
(
!
KityMinder
.
_theme
[
name
])
{
if
(
!
KityMinder
.
_theme
s
[
name
])
{
return
false
;
}
...
...
@@ -72,7 +72,7 @@ kity.extendClass(Minder, {
* @param {String} item 样式名称
*/
getStyle
:
function
(
item
)
{
var
theme
=
KityMinder
.
_theme
[
this
.
getTheme
()];
var
theme
=
KityMinder
.
_theme
s
[
this
.
getTheme
()];
var
segment
,
dir
,
selector
,
value
,
matcher
;
if
(
item
in
theme
)
return
theme
[
item
];
...
...
@@ -81,7 +81,7 @@ kity.extendClass(Minder, {
// 比如 item 为 'pading-left'
// theme 里有 {'padding': [10, 20]} 的定义,则可以返回 20
segment
=
item
.
split
(
'-'
);
if
(
segment
.
length
<
2
)
return
;
if
(
segment
.
length
<
2
)
return
null
;
dir
=
segment
.
pop
();
item
=
segment
.
join
(
'-'
);
...
...
@@ -95,24 +95,20 @@ kity.extendClass(Minder, {
}
return
null
;
}
});
kity
.
extendClass
(
Node
,
{
},
/**
* 获
得
节点的样式
* @param {String} name 样式名称
* 获
取指定
节点的样式
* @param {String} name 样式名称
,可以不加节点类型的前缀
*/
getStyle
:
function
(
name
)
{
var
minder
=
this
.
minder
,
value
;
if
(
!
this
.
minder
)
return
null
;
value
=
minder
.
getStyle
(
name
);
getNodeStyle
:
function
(
node
,
name
)
{
var
value
=
this
.
getStyle
(
name
);
return
value
!==
null
?
value
:
this
.
getStyle
(
node
.
getType
()
+
'-'
+
name
);
}
});
return
value
!==
null
?
value
:
minder
.
getStyle
(
this
.
getType
()
+
'-'
+
name
);
kity
.
extendClass
(
MinderNode
,
{
getStyle
:
function
(
name
)
{
return
this
.
getMinder
().
getNodeStyle
(
this
,
name
);
}
});
\ No newline at end of file
src/core/utils.js
View file @
d652a8fb
var
utils
=
Utils
=
KityMinder
.
Utils
=
{
extend
:
kity
.
Utils
.
extend
.
bind
(
kity
.
Utils
),
extend
:
kity
.
Utils
.
extend
.
bind
(
kity
.
Utils
),
listen
:
function
(
element
,
type
,
handler
)
{
var
types
=
utils
.
isArray
(
type
)
?
type
:
utils
.
trim
(
type
).
split
(
/
\s
+/
),
listen
:
function
(
element
,
type
,
handler
)
{
var
types
=
utils
.
isArray
(
type
)
?
type
:
utils
.
trim
(
type
).
split
(
/
\s
+/
),
k
=
types
.
length
;
if
(
k
)
while
(
k
--
)
{
type
=
types
[
k
];
if
(
element
.
addEventListener
)
{
element
.
addEventListener
(
type
,
handler
,
false
);
if
(
k
)
while
(
k
--
)
{
type
=
types
[
k
];
if
(
element
.
addEventListener
)
{
element
.
addEventListener
(
type
,
handler
,
false
);
}
else
{
if
(
!
handler
.
_d
)
{
if
(
!
handler
.
_d
)
{
handler
.
_d
=
{
els
:
[]
};
}
var
key
=
type
+
handler
.
toString
(),
index
=
utils
.
indexOf
(
handler
.
_d
.
els
,
element
);
if
(
!
handler
.
_d
[
key
]
||
index
==
-
1
)
{
if
(
index
==
-
1
)
{
handler
.
_d
.
els
.
push
(
element
);
index
=
utils
.
indexOf
(
handler
.
_d
.
els
,
element
);
if
(
!
handler
.
_d
[
key
]
||
index
==
-
1
)
{
if
(
index
==
-
1
)
{
handler
.
_d
.
els
.
push
(
element
);
}
if
(
!
handler
.
_d
[
key
]
)
{
handler
.
_d
[
key
]
=
function
(
evt
)
{
return
handler
.
call
(
evt
.
srcElement
,
evt
||
window
.
event
);
if
(
!
handler
.
_d
[
key
]
)
{
handler
.
_d
[
key
]
=
function
(
evt
)
{
return
handler
.
call
(
evt
.
srcElement
,
evt
||
window
.
event
);
};
}
element
.
attachEvent
(
'on'
+
type
,
handler
.
_d
[
key
]
);
element
.
attachEvent
(
'on'
+
type
,
handler
.
_d
[
key
]
);
}
}
}
element
=
null
;
},
trim
:
function
(
str
)
{
return
str
.
replace
(
/
(
^
[
\t\n\r]
+
)
|
([
\t\n\r]
+$
)
/g
,
''
);
trim
:
function
(
str
)
{
return
str
.
replace
(
/
(
^
[
\t\n\r]
+
)
|
([
\t\n\r]
+$
)
/g
,
''
);
},
each
:
function
(
obj
,
iterator
,
context
)
{
if
(
obj
==
null
)
return
;
if
(
obj
.
length
===
+
obj
.
length
)
{
for
(
var
i
=
0
,
l
=
obj
.
length
;
i
<
l
;
i
++
)
{
if
(
iterator
.
call
(
context
,
i
,
obj
[
i
],
obj
)
===
false
)
each
:
function
(
obj
,
iterator
,
context
)
{
if
(
obj
==
null
)
return
;
if
(
obj
.
length
===
+
obj
.
length
)
{
for
(
var
i
=
0
,
l
=
obj
.
length
;
i
<
l
;
i
++
)
{
if
(
iterator
.
call
(
context
,
i
,
obj
[
i
],
obj
)
===
false
)
return
false
;
}
}
else
{
for
(
var
key
in
obj
)
{
if
(
obj
.
hasOwnProperty
(
key
)
)
{
if
(
iterator
.
call
(
context
,
key
,
obj
[
key
],
obj
)
===
false
)
for
(
var
key
in
obj
)
{
if
(
obj
.
hasOwnProperty
(
key
)
)
{
if
(
iterator
.
call
(
context
,
key
,
obj
[
key
],
obj
)
===
false
)
return
false
;
}
}
}
},
addCssRule
:
function
(
key
,
style
,
doc
)
{
addCssRule
:
function
(
key
,
style
,
doc
)
{
var
head
,
node
;
if
(
style
===
undefined
||
style
&&
style
.
nodeType
&&
style
.
nodeType
==
9
)
{
if
(
style
===
undefined
||
style
&&
style
.
nodeType
&&
style
.
nodeType
==
9
)
{
//获取样式
doc
=
style
&&
style
.
nodeType
&&
style
.
nodeType
==
9
?
style
:
(
doc
||
document
);
node
=
doc
.
getElementById
(
key
);
doc
=
style
&&
style
.
nodeType
&&
style
.
nodeType
==
9
?
style
:
(
doc
||
document
);
node
=
doc
.
getElementById
(
key
);
return
node
?
node
.
innerHTML
:
undefined
;
}
doc
=
doc
||
document
;
node
=
doc
.
getElementById
(
key
);
node
=
doc
.
getElementById
(
key
);
//清除样式
if
(
style
===
''
)
{
if
(
node
)
{
node
.
parentNode
.
removeChild
(
node
);
if
(
style
===
''
)
{
if
(
node
)
{
node
.
parentNode
.
removeChild
(
node
);
return
true
}
return
false
;
}
//添加样式
if
(
node
)
{
if
(
node
)
{
node
.
innerHTML
=
style
;
}
else
{
node
=
doc
.
createElement
(
'style'
);
node
=
doc
.
createElement
(
'style'
);
node
.
id
=
key
;
node
.
innerHTML
=
style
;
doc
.
getElementsByTagName
(
'head'
)[
0
].
appendChild
(
node
);
doc
.
getElementsByTagName
(
'head'
)[
0
].
appendChild
(
node
);
}
},
keys
:
function
(
plain
)
{
keys
:
function
(
plain
)
{
var
keys
=
[];
for
(
var
key
in
plain
)
{
if
(
plain
.
hasOwnProperty
(
key
)
)
{
keys
.
push
(
key
);
for
(
var
key
in
plain
)
{
if
(
plain
.
hasOwnProperty
(
key
)
)
{
keys
.
push
(
key
);
}
}
return
keys
;
},
proxy
:
function
(
fn
,
context
)
{
return
function
()
{
return
fn
.
apply
(
context
,
arguments
);
proxy
:
function
(
fn
,
context
)
{
return
function
()
{
return
fn
.
apply
(
context
,
arguments
);
};
},
indexOf
:
function
(
array
,
item
,
start
)
{
indexOf
:
function
(
array
,
item
,
start
)
{
var
index
=
-
1
;
start
=
this
.
isNumber
(
start
)
?
start
:
0
;
this
.
each
(
array
,
function
(
v
,
i
)
{
if
(
i
>=
start
&&
v
===
item
)
{
start
=
this
.
isNumber
(
start
)
?
start
:
0
;
this
.
each
(
array
,
function
(
v
,
i
)
{
if
(
i
>=
start
&&
v
===
item
)
{
index
=
i
;
return
false
;
}
}
);
});
return
index
;
},
argsToArray
:
function
(
args
,
index
)
{
return
Array
.
prototype
.
slice
.
call
(
args
,
index
||
0
);
argsToArray
:
function
(
args
,
index
)
{
return
Array
.
prototype
.
slice
.
call
(
args
,
index
||
0
);
},
clonePlainObject
:
function
(
source
,
target
)
{
clonePlainObject
:
function
(
source
,
target
)
{
var
tmp
;
target
=
target
||
{};
for
(
var
i
in
source
)
{
...
...
@@ -125,32 +125,32 @@ var utils = Utils = KityMinder.Utils = {
}
return
target
;
},
compareObject
:
function
(
source
,
target
)
{
compareObject
:
function
(
source
,
target
)
{
var
tmp
;
if
(
this
.
isEmptyObject
(
source
)
!==
this
.
isEmptyObject
(
target
))
{
if
(
this
.
isEmptyObject
(
source
)
!==
this
.
isEmptyObject
(
target
))
{
return
false
}
if
(
this
.
getObjectLength
(
source
)
!=
this
.
getObjectLength
(
target
))
{
if
(
this
.
getObjectLength
(
source
)
!=
this
.
getObjectLength
(
target
))
{
return
false
;
}
for
(
var
p
in
source
)
{
if
(
source
.
hasOwnProperty
(
p
))
{
for
(
var
p
in
source
)
{
if
(
source
.
hasOwnProperty
(
p
))
{
tmp
=
source
[
p
];
if
(
target
[
p
]
===
undefined
)
{
if
(
target
[
p
]
===
undefined
)
{
return
false
;
}
if
(
this
.
isObject
(
tmp
)
||
this
.
isArray
(
tmp
))
{
if
(
this
.
isObject
(
target
[
p
])
!==
this
.
isObject
(
tmp
))
{
if
(
this
.
isObject
(
target
[
p
])
!==
this
.
isObject
(
tmp
))
{
return
false
;
}
if
(
this
.
isArray
(
tmp
)
!==
this
.
isArray
(
target
[
p
]))
{
if
(
this
.
isArray
(
tmp
)
!==
this
.
isArray
(
target
[
p
]))
{
return
false
;
}
if
(
this
.
compareObject
(
tmp
,
target
[
p
])
===
false
)
{
if
(
this
.
compareObject
(
tmp
,
target
[
p
])
===
false
)
{
return
false
}
}
else
{
if
(
tmp
!=
target
[
p
])
{
if
(
tmp
!=
target
[
p
])
{
return
false
}
}
...
...
@@ -158,35 +158,37 @@ var utils = Utils = KityMinder.Utils = {
}
return
true
;
},
getObjectLength
:
function
(
obj
)
{
getObjectLength
:
function
(
obj
)
{
if
(
this
.
isArray
(
obj
)
||
this
.
isString
(
obj
))
return
obj
.
length
;
var
count
=
0
;
for
(
var
key
in
obj
)
if
(
obj
.
hasOwnProperty
(
key
))
count
++
;
for
(
var
key
in
obj
)
if
(
obj
.
hasOwnProperty
(
key
))
count
++
;
return
count
;
},
isEmptyObject
:
function
(
obj
)
{
isEmptyObject
:
function
(
obj
)
{
if
(
obj
==
null
)
return
true
;
if
(
this
.
isArray
(
obj
)
||
this
.
isString
(
obj
))
return
obj
.
length
===
0
;
for
(
var
key
in
obj
)
if
(
obj
.
hasOwnProperty
(
key
))
return
false
;
for
(
var
key
in
obj
)
if
(
obj
.
hasOwnProperty
(
key
))
return
false
;
return
true
;
},
getNodeCommonAncestor
:
function
(
nodeA
,
nodeB
)
{
if
(
nodeA
===
nodeB
)
{
getNodeCommonAncestor
:
function
(
nodeA
,
nodeB
)
{
if
(
nodeA
===
nodeB
)
{
return
nodeA
.
parent
}
if
(
nodeA
.
contains
(
nodeB
)
)
{
if
(
nodeA
.
contains
(
nodeB
)
)
{
return
this
}
if
(
nodeB
.
contains
(
nodeA
)
)
{
if
(
nodeB
.
contains
(
nodeA
)
)
{
return
nodeB
}
var
parent
=
nodeA
.
parent
;
while
(
!
parent
.
contains
(
nodeB
)
)
{
while
(
!
parent
.
contains
(
nodeB
)
)
{
parent
=
parent
.
parent
;
}
return
parent
;
},
loadFile
:
function
()
{
loadFile
:
function
()
{
var
tmpList
=
[];
function
getItem
(
doc
,
obj
)
{
...
...
@@ -202,7 +204,7 @@ var utils = Utils = KityMinder.Utils = {
}
return
function
(
doc
,
obj
,
fn
)
{
return
function
(
doc
,
obj
,
fn
)
{
var
item
=
getItem
(
doc
,
obj
);
if
(
item
)
{
if
(
item
.
ready
)
{
...
...
@@ -213,14 +215,14 @@ var utils = Utils = KityMinder.Utils = {
return
;
}
tmpList
.
push
({
doc
:
doc
,
url
:
obj
.
src
||
obj
.
href
,
funs
:[
fn
]
doc
:
doc
,
url
:
obj
.
src
||
obj
.
href
,
funs
:
[
fn
]
});
if
(
!
doc
.
body
)
{
var
html
=
[];
for
(
var
p
in
obj
)
{
if
(
p
==
'tag'
)
continue
;
if
(
p
==
'tag'
)
continue
;
html
.
push
(
p
+
'="'
+
obj
[
p
]
+
'"'
)
}
doc
.
write
(
'<'
+
obj
.
tag
+
' '
+
html
.
join
(
' '
)
+
' ></'
+
obj
.
tag
+
'>'
);
...
...
@@ -234,7 +236,7 @@ var utils = Utils = KityMinder.Utils = {
for
(
var
p
in
obj
)
{
element
.
setAttribute
(
p
,
obj
[
p
]);
}
element
.
onload
=
element
.
onreadystatechange
=
function
()
{
element
.
onload
=
element
.
onreadystatechange
=
function
()
{
if
(
!
this
.
readyState
||
/loaded|complete/
.
test
(
this
.
readyState
))
{
item
=
getItem
(
doc
,
obj
);
if
(
item
.
funs
.
length
>
0
)
{
...
...
@@ -246,13 +248,13 @@ var utils = Utils = KityMinder.Utils = {
element
.
onload
=
element
.
onreadystatechange
=
null
;
}
};
// element.onerror = function () {
// throw Error('The load ' + (obj.href || obj.src) + ' fails,check the url settings of file ')
// };
// element.onerror = function () {
// throw Error('The load ' + (obj.href || obj.src) + ' fails,check the url settings of file ')
// };
doc
.
getElementsByTagName
(
"head"
)[
0
].
appendChild
(
element
);
}
}(),
clone
:
function
(
source
,
target
)
{
clone
:
function
(
source
,
target
)
{
var
tmp
;
target
=
target
||
{};
for
(
var
i
in
source
)
{
...
...
@@ -268,17 +270,17 @@ var utils = Utils = KityMinder.Utils = {
}
return
target
;
},
unhtml
:
function
(
str
,
reg
)
{
return
str
?
str
.
replace
(
reg
||
/
[
&<">'
](?:(
amp|lt|quot|gt|#39|nbsp
)
;
)?
/g
,
function
(
a
,
b
)
{
unhtml
:
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
]
}
})
:
''
;
...
...
@@ -286,8 +288,8 @@ var utils = Utils = KityMinder.Utils = {
};
Utils
.
each
(
[
'String'
,
'Function'
,
'Array'
,
'Number'
,
'RegExp'
,
'Object'
],
function
(
i
,
v
)
{
KityMinder
.
Utils
[
'is'
+
v
]
=
function
(
obj
)
{
return
Object
.
prototype
.
toString
.
apply
(
obj
)
==
'[object '
+
v
+
']'
;
Utils
.
each
(
[
'String'
,
'Function'
,
'Array'
,
'Number'
,
'RegExp'
,
'Object'
],
function
(
i
,
v
)
{
KityMinder
.
Utils
[
'is'
+
v
]
=
function
(
obj
)
{
return
Object
.
prototype
.
toString
.
apply
(
obj
)
==
'[object '
+
v
+
']'
;
}
}
);
\ No newline at end of file
});
\ No newline at end of file
src/layout/default.js
0 → 100644
View file @
d652a8fb
/* global Layout:true */
KityMinder
.
registerLayout
(
'default'
,
kity
.
createClass
({
base
:
Layout
,
doLayout
:
function
(
node
)
{
node
.
getChildren
().
forEach
(
function
(
childNode
)
{
childNode
.
layout
();
});
}
}));
\ No newline at end of file
src/module/basestyle.js
View file @
d652a8fb
KityMinder
.
registerModule
(
"basestylemodule"
,
function
()
{
KityMinder
.
registerModule
(
"basestylemodule"
,
function
()
{
var
km
=
this
;
return
{
"commands"
:
{
"bold"
:
kity
.
createClass
(
"boldCommand"
,
{
"bold"
:
kity
.
createClass
(
"boldCommand"
,
{
base
:
Command
,
execute
:
function
()
{
execute
:
function
()
{
var
nodes
=
km
.
getSelectedNodes
();
if
(
this
.
queryState
(
'bold'
)
==
1
)
{
utils
.
each
(
nodes
,
function
(
i
,
n
)
{
n
.
setData
(
'bold'
);
n
.
getTextShape
().
setAttr
(
'font-weight'
);
km
.
updateLayout
(
n
);
}
);
if
(
this
.
queryState
(
'bold'
)
==
1
)
{
utils
.
each
(
nodes
,
function
(
i
,
n
)
{
n
.
setData
(
'bold'
);
n
.
getTextShape
().
setAttr
(
'font-weight'
);
km
.
updateLayout
(
n
);
});
}
else
{
utils
.
each
(
nodes
,
function
(
i
,
n
)
{
n
.
setData
(
'bold'
,
true
);
n
.
getTextShape
().
setAttr
(
'font-weight'
,
'bold'
);
km
.
updateLayout
(
n
);
}
);
utils
.
each
(
nodes
,
function
(
i
,
n
)
{
n
.
setData
(
'bold'
,
true
);
n
.
getTextShape
().
setAttr
(
'font-weight'
,
'bold'
);
km
.
updateLayout
(
n
);
});
}
},
queryState
:
function
()
{
queryState
:
function
()
{
var
nodes
=
km
.
getSelectedNodes
(),
result
=
0
;
if
(
nodes
.
length
===
0
)
{
if
(
nodes
.
length
===
0
)
{
return
-
1
;
}
utils
.
each
(
nodes
,
function
(
i
,
n
)
{
if
(
n
&&
n
.
getData
(
'bold'
)
)
{
utils
.
each
(
nodes
,
function
(
i
,
n
)
{
if
(
n
&&
n
.
getData
(
'bold'
)
)
{
result
=
1
;
return
false
;
}
}
);
});
return
result
;
}
}
),
"italic"
:
kity
.
createClass
(
"italicCommand"
,
{
}),
"italic"
:
kity
.
createClass
(
"italicCommand"
,
{
base
:
Command
,
execute
:
function
()
{
execute
:
function
()
{
var
nodes
=
km
.
getSelectedNodes
();
if
(
this
.
queryState
(
'italic'
)
==
1
)
{
utils
.
each
(
nodes
,
function
(
i
,
n
)
{
n
.
setData
(
'italic'
);
n
.
getTextShape
().
setAttr
(
'font-style'
);
km
.
updateLayout
(
n
);
}
);
if
(
this
.
queryState
(
'italic'
)
==
1
)
{
utils
.
each
(
nodes
,
function
(
i
,
n
)
{
n
.
setData
(
'italic'
);
n
.
getTextShape
().
setAttr
(
'font-style'
);
km
.
updateLayout
(
n
);
});
}
else
{
utils
.
each
(
nodes
,
function
(
i
,
n
)
{
n
.
setData
(
'italic'
,
true
);
n
.
getTextShape
().
setAttr
(
'font-style'
,
'italic'
);
km
.
updateLayout
(
n
);
}
);
utils
.
each
(
nodes
,
function
(
i
,
n
)
{
n
.
setData
(
'italic'
,
true
);
n
.
getTextShape
().
setAttr
(
'font-style'
,
'italic'
);
km
.
updateLayout
(
n
);
});
}
},
queryState
:
function
()
{
queryState
:
function
()
{
var
nodes
=
km
.
getSelectedNodes
(),
result
=
0
;
if
(
nodes
.
length
===
0
)
{
if
(
nodes
.
length
===
0
)
{
return
-
1
;
}
utils
.
each
(
nodes
,
function
(
i
,
n
)
{
if
(
n
&&
n
.
getData
(
'italic'
)
)
{
utils
.
each
(
nodes
,
function
(
i
,
n
)
{
if
(
n
&&
n
.
getData
(
'italic'
)
)
{
result
=
1
;
return
false
;
}
}
);
});
return
result
;
}
}
)
})
},
addShortcutKeys
:
{
"bold"
:
"ctrl+b"
,
//bold
"italic"
:
"ctrl+i"
//italic
},
"events"
:
{
"afterrendernodecenter"
:
function
(
e
)
{
"afterrendernodecenter"
:
function
(
e
)
{
//加粗
if
(
e
.
node
.
getData
(
'bold'
)
)
{
e
.
node
.
getTextShape
().
setAttr
(
'font-weight'
,
'bold'
);
if
(
e
.
node
.
getData
(
'bold'
)
)
{
e
.
node
.
getTextShape
().
setAttr
(
'font-weight'
,
'bold'
);
}
if
(
e
.
node
.
getData
(
'italic'
)
)
{
e
.
node
.
getTextShape
().
setAttr
(
'font-style'
,
'italic'
);
if
(
e
.
node
.
getData
(
'italic'
)
)
{
e
.
node
.
getTextShape
().
setAttr
(
'font-style'
,
'italic'
);
}
}
}
};
}
);
\ No newline at end of file
});
\ No newline at end of file
src/module/editor.js
View file @
d652a8fb
KityMinder
.
registerModule
(
"TextEditModule"
,
function
()
{
/* global Renderer: true */
KityMinder
.
registerModule
(
'TextEditModule'
,
function
()
{
var
km
=
this
;
var
sel
=
new
Minder
.
Selection
();
var
receiver
=
new
Minder
.
Receiver
(
this
);
...
...
@@ -10,15 +12,13 @@ KityMinder.registerModule( "TextEditModule", function () {
var
oneTime
=
0
;
var
lastEvtPosition
,
dir
=
1
;
var
lastEvtPosition
,
dir
=
1
;
km
.
isTextEditStatus
=
function
(){
km
.
isTextEditStatus
=
function
()
{
return
km
.
receiver
.
isTextEditStatus
();
};
km
.
textEditNode
=
function
(
node
){
km
.
textEditNode
=
function
(
node
)
{
var
textShape
=
node
.
getTextShape
();
this
.
setStatus
(
'textedit'
);
...
...
@@ -41,47 +41,45 @@ KityMinder.registerModule( "TextEditModule", function () {
.
updateRange
(
range
).
setTextEditStatus
(
true
);
sel
.
setData
(
'relatedNode'
,
node
);
sel
.
setData
(
'relatedNode'
,
node
);
};
var
selectionByClick
=
false
;
var
dragmoveTimer
;
return
{
"events"
:
{
'ready'
:
function
()
{
'events'
:
{
'ready'
:
function
()
{
this
.
_renderTarget
.
appendChild
(
receiver
.
container
);
},
//插入光标
"afterinitstyle"
:
function
(){
this
.
getRenderContainer
().
addShape
(
sel
);
},
'normal.beforemousedown textedit.beforemousedown'
:
function
(
e
){
if
(
e
.
isRightMB
()){
'normal.beforemousedown textedit.beforemousedown'
:
function
(
e
)
{
if
(
e
.
isRightMB
())
{
e
.
stopPropagationImmediately
();
return
;
}
sel
.
setHide
();
var
node
=
e
.
getTargetNode
();
if
(
!
node
)
{
if
(
!
node
)
{
var
selectionShape
=
e
.
kityEvent
.
targetShape
;
if
(
selectionShape
&&
selectionShape
.
getType
()
==
'Selection'
)
{
if
(
selectionShape
&&
selectionShape
.
getType
()
==
'Selection'
)
{
selectionByClick
=
true
;
node
=
selectionShape
.
getData
(
'relatedNode'
);
e
.
stopPropagationImmediately
();
}
if
(
this
.
getStatus
()
==
'textedit'
)
if
(
this
.
getStatus
()
==
'textedit'
)
this
.
fire
(
'contentchange'
);
km
.
setStatus
(
'normal'
);
}
if
(
node
)
{
if
(
node
)
{
var
textShape
=
node
.
getTextShape
();
textShape
.
setStyle
(
'cursor'
,
'default'
);
textShape
.
setStyle
(
'cursor'
,
'default'
);
if
(
this
.
isSingleSelect
()
&&
node
.
isSelected
())
{
// && e.kityEvent.targetShape.getType().toLowerCase()== 'text'
if
(
this
.
isSingleSelect
()
&&
node
.
isSelected
())
{
// && e.kityEvent.targetShape.getType().toLowerCase()== 'text'
sel
.
collapse
();
sel
.
setSelectionShowStatus
(
true
);
node
.
getTextShape
().
setStyle
(
'cursor'
,
'text'
);
node
.
getTextShape
().
setStyle
(
'cursor'
,
'text'
);
km
.
setStatus
(
'textedit'
);
receiver
.
setTextEditStatus
(
true
)
.
setSelection
(
sel
)
...
...
@@ -94,10 +92,10 @@ KityMinder.registerModule( "TextEditModule", function () {
.
setCurrentIndex
(
e
.
getPosition
(
this
.
getRenderContainer
()))
.
updateSelection
()
.
setRange
(
range
);
sel
.
setData
(
'relatedNode'
,
node
);
sel
.
setData
(
'relatedNode'
,
node
);
mouseDownStatus
=
true
;
lastEvtPosition
=
e
.
getPosition
(
this
.
getRenderContainer
());
if
(
selectionByClick
)
{
if
(
selectionByClick
)
{
sel
.
setShow
();
selectionByClick
=
false
;
}
...
...
@@ -105,16 +103,18 @@ KityMinder.registerModule( "TextEditModule", function () {
}
}
},
//当输入键值是内容时,进入textedit状态
'normal.beforekeydown'
:
function
(
e
)
{
'normal.beforekeydown'
:
function
(
e
)
{
var
node
=
this
.
getSelectedNode
();
if
(
node
){
if
(
this
.
isSingleSelect
()
&&
node
.
isSelected
())
{
var
orgEvt
=
e
.
originEvent
,
keyCode
=
orgEvt
.
keyCode
;
if
(
!
keymap
.
notContentInput
[
keyCode
]
&&
range
.
nativeSel
.
rangeCount
!==
0
&&
!
orgEvt
.
ctrlKey
&&
!
orgEvt
.
metaKey
&&
!
orgEvt
.
shiftKey
&&
!
orgEvt
.
altKey
){
if
(
node
)
{
if
(
this
.
isSingleSelect
()
&&
node
.
isSelected
())
{
var
orgEvt
=
e
.
originEvent
,
keyCode
=
orgEvt
.
keyCode
;
if
(
!
keymap
.
notContentInput
[
keyCode
]
&&
range
.
nativeSel
.
rangeCount
!==
0
&&
!
orgEvt
.
ctrlKey
&&
!
orgEvt
.
metaKey
&&
!
orgEvt
.
shiftKey
&&
!
orgEvt
.
altKey
)
{
var
nativeRange
=
range
.
nativeSel
.
getRangeAt
(
0
);
if
(
nativeRange
&&
(
nativeRange
.
startContainer
===
receiver
.
container
||
receiver
.
container
.
contains
(
nativeRange
.
startContainer
)))
{
if
(
nativeRange
&&
(
nativeRange
.
startContainer
===
receiver
.
container
||
receiver
.
container
.
contains
(
nativeRange
.
startContainer
)))
{
km
.
setStatus
(
'textedit'
);
sel
.
setSelectionShowStatus
(
true
);
km
.
fire
(
'saveScene'
);
...
...
@@ -124,15 +124,17 @@ KityMinder.registerModule( "TextEditModule", function () {
}
}
},
//当节点选区通过键盘发生变化时,输入状态要准备好
'normal.keyup'
:
function
(
e
)
{
'normal.keyup'
:
function
(
e
)
{
var
node
=
this
.
getSelectedNode
();
if
(
node
){
if
(
this
.
isSingleSelect
()
&&
node
.
isSelected
())
{
var
orgEvt
=
e
.
originEvent
,
keyCode
=
orgEvt
.
keyCode
;
if
(
keymap
.
isSelectedNodeKey
[
keyCode
]
&&
km
.
getStatus
()
!=
'textedit'
&&
!
orgEvt
.
ctrlKey
&&
!
orgEvt
.
metaKey
&&
!
orgEvt
.
shiftKey
&&
!
orgEvt
.
altKey
){
if
(
node
)
{
if
(
this
.
isSingleSelect
()
&&
node
.
isSelected
())
{
var
orgEvt
=
e
.
originEvent
,
keyCode
=
orgEvt
.
keyCode
;
if
(
keymap
.
isSelectedNodeKey
[
keyCode
]
&&
km
.
getStatus
()
!=
'textedit'
&&
!
orgEvt
.
ctrlKey
&&
!
orgEvt
.
metaKey
&&
!
orgEvt
.
shiftKey
&&
!
orgEvt
.
altKey
)
{
//准备输入状态
//准备输入状态
var
textShape
=
node
.
getTextShape
();
sel
.
setHide
();
...
...
@@ -151,29 +153,29 @@ KityMinder.registerModule( "TextEditModule", function () {
.
setContainerTxt
(
textShape
.
getContent
())
.
updateRange
(
range
).
setTextEditStatus
(
true
);
sel
.
setData
(
'relatedNode'
,
node
);
sel
.
setData
(
'relatedNode'
,
node
);
}
}
}
},
'normal.mouseup textedit.mouseup'
:
function
(
e
)
{
'normal.mouseup textedit.mouseup'
:
function
(
e
)
{
if
(
mouseDownStatus
)
{
if
(
!
sel
.
collapsed
)
{
if
(
mouseDownStatus
)
{
if
(
!
sel
.
collapsed
)
{
try
{
try
{
receiver
.
updateRange
(
range
);
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
log
(
error
);
}
}
else
sel
.
setShow
();
}
else
{
}
else
sel
.
setShow
();
}
else
{
//当选中节点后,输入状态准备
var
node
=
e
.
getTargetNode
();
if
(
node
)
{
if
(
this
.
isSingleSelect
()
&&
node
.
isSelected
())
{
if
(
node
)
{
if
(
this
.
isSingleSelect
()
&&
node
.
isSelected
())
{
//准备输入状态
var
textShape
=
node
.
getTextShape
();
...
...
@@ -193,7 +195,7 @@ KityMinder.registerModule( "TextEditModule", function () {
.
setContainerTxt
(
textShape
.
getContent
())
.
updateRange
(
range
).
setTextEditStatus
(
true
);
sel
.
setData
(
'relatedNode'
,
node
);
sel
.
setData
(
'relatedNode'
,
node
);
}
}
...
...
@@ -203,28 +205,28 @@ KityMinder.registerModule( "TextEditModule", function () {
mouseDownStatus
=
false
;
oneTime
=
0
;
},
'textedit.beforemousemove'
:
function
(
e
)
{
if
(
mouseDownStatus
)
{
'textedit.beforemousemove'
:
function
(
e
)
{
if
(
mouseDownStatus
)
{
e
.
stopPropagationImmediately
();
var
offset
=
e
.
getPosition
(
this
.
getRenderContainer
());
if
(
Math
.
abs
(
offset
.
y
-
lastEvtPosition
.
y
)
>=
2
&&
Math
.
abs
(
lastEvtPosition
.
x
-
offset
.
x
)
<=
2
)
{
if
(
Math
.
abs
(
offset
.
y
-
lastEvtPosition
.
y
)
>=
2
&&
Math
.
abs
(
lastEvtPosition
.
x
-
offset
.
x
)
<=
2
)
{
sel
.
setHide
();
mouseDownStatus
=
false
;
return
;
}
dir
=
offset
.
x
>
lastEvtPosition
.
x
?
1
:
(
offset
.
x
<
lastEvtPosition
.
x
?
-
1
:
dir
);
receiver
.
updateSelectionByMousePosition
(
offset
,
dir
)
dir
=
offset
.
x
>
lastEvtPosition
.
x
?
1
:
(
offset
.
x
<
lastEvtPosition
.
x
?
-
1
:
dir
);
receiver
.
updateSelectionByMousePosition
(
offset
,
dir
)
.
updateSelectionShow
(
dir
);
lastEvtPosition
=
e
.
getPosition
(
this
.
getRenderContainer
());
}
},
'normal.dblclick textedit.dblclick'
:
function
(
e
)
{
'normal.dblclick textedit.dblclick'
:
function
(
e
)
{
var
text
=
e
.
kityEvent
.
targetShape
;
if
(
text
.
getType
().
toLowerCase
()
==
'text'
)
{
var
text
=
e
.
kityEvent
.
targetShape
;
if
(
text
.
getType
().
toLowerCase
()
==
'text'
)
{
sel
.
setStartOffset
(
0
);
sel
.
setEndOffset
(
text
.
getContent
().
length
);
...
...
@@ -234,9 +236,9 @@ KityMinder.registerModule( "TextEditModule", function () {
km
.
setStatus
(
'textedit'
);
}
},
'restoreScene'
:
function
()
{
'restoreScene'
:
function
()
{
var
node
=
this
.
getSelectedNode
();
if
(
node
&&
this
.
isSingleSelect
())
{
if
(
node
&&
this
.
isSingleSelect
())
{
var
textShape
=
node
.
getTextShape
();
sel
.
setHide
();
sel
.
setStartOffset
(
0
);
...
...
@@ -255,37 +257,37 @@ KityMinder.registerModule( "TextEditModule", function () {
.
updateRange
(
range
).
setTextEditStatus
(
true
);
km
.
setStatus
(
'normal'
);
sel
.
setData
(
'relatedNode'
,
node
);
}
else
{
sel
.
setData
(
'relatedNode'
,
node
);
}
else
{
receiver
.
clear
();
}
},
'stopTextEdit'
:
function
()
{
'stopTextEdit'
:
function
()
{
sel
.
setHide
();
receiver
.
clear
().
setTextEditStatus
(
false
);
km
.
setStatus
(
'normal'
);
},
"resize"
:
function
(
e
)
{
"resize"
:
function
(
e
)
{
sel
.
setHide
();
},
"execCommand"
:
function
(
e
)
{
"execCommand"
:
function
(
e
)
{
var
cmds
=
{
'appendchildnode'
:
1
,
'appendsiblingnode'
:
1
,
'editnode'
:
1
'appendchildnode'
:
1
,
'appendsiblingnode'
:
1
,
'editnode'
:
1
};
if
(
cmds
[
e
.
commandName
]
)
{
if
(
cmds
[
e
.
commandName
])
{
var
node
=
km
.
getSelectedNode
();
if
(
!
node
)
{
if
(
!
node
)
{
return
;
}
var
textShape
=
node
.
getTextShape
();
textShape
.
setStyle
(
'cursor'
,
'default'
);
node
.
getTextShape
().
setStyle
(
'cursor'
,
'text'
);
textShape
.
setStyle
(
'cursor'
,
'default'
);
node
.
getTextShape
().
setStyle
(
'cursor'
,
'text'
);
km
.
setStatus
(
'textedit'
);
receiver
.
setTextEditStatus
(
true
)
.
setSelection
(
sel
)
...
...
@@ -310,14 +312,14 @@ KityMinder.registerModule( "TextEditModule", function () {
}
if
((
e
.
commandName
==
'priority'
||
e
.
commandName
==
'progress'
)
&&
this
.
getStatus
()
==
'textedit'
)
{
if
((
e
.
commandName
==
'priority'
||
e
.
commandName
==
'progress'
)
&&
this
.
getStatus
()
==
'textedit'
)
{
receiver
.
setBaseOffset
()
.
getTextOffsetData
();
if
(
sel
.
collapsed
)
{
if
(
sel
.
collapsed
)
{
receiver
.
updateSelection
();
}
else
{
}
else
{
receiver
.
updateSelectionShow
(
1
);
}
return
;
...
...
@@ -325,24 +327,50 @@ KityMinder.registerModule( "TextEditModule", function () {
}
receiver
.
clear
().
setTextEditStatus
(
false
);
if
(
this
.
getStatus
()
==
'textedit'
)
{
if
(
this
.
getStatus
()
==
'textedit'
)
{
this
.
setStatus
(
'normal'
);
}
},
'selectionclear'
:
function
()
{
'selectionclear'
:
function
()
{
km
.
setStatus
(
'normal'
);
receiver
.
setTextEditStatus
(
false
).
clear
();
},
blur
:
function
()
{
'blur'
:
function
()
{
receiver
.
clear
();
},
'import'
:
function
()
{
'import'
:
function
()
{
km
.
setStatus
(
'normal'
);
receiver
.
setTextEditStatus
(
false
).
clear
();
},
'textedit.mousewheel'
:
function
()
{
'textedit.mousewheel'
:
function
()
{
receiver
.
setContainerStyle
();
}
},
'renderers'
:
{
center
:
kity
.
createClass
(
'TextRenderer'
,
{
base
:
Renderer
,
create
:
function
(
node
)
{
var
textShape
=
new
kity
.
Text
()
.
setVerticalAlign
(
'middle'
)
.
setId
(
KityMinder
.
uuid
(
'node_text'
));
node
.
getRenderContainer
().
addShape
(
textShape
);
node
.
getTextShape
=
function
()
{
return
textShape
;
};
},
update
:
function
(
node
)
{
return
node
.
getTextShape
()
.
setContent
(
node
.
getText
())
.
setFont
({
family
:
node
.
getStyle
(
'font-family'
),
size
:
node
.
getStyle
(
'font-size'
)
})
.
fill
(
node
.
getData
(
'color'
)
||
node
.
getStyle
(
'color'
))
.
getBoundaryBox
();
}
})
}
};
}
);
\ No newline at end of file
});
\ No newline at end of file
src/module/editor.receiver.js
View file @
d652a8fb
//接收者
Minder
.
Receiver
=
kity
.
createClass
(
'Receiver'
,
{
clear
:
function
()
{
Minder
.
Receiver
=
kity
.
createClass
(
'Receiver'
,
{
clear
:
function
()
{
this
.
container
.
innerHTML
=
''
;
if
(
this
.
selection
)
{
if
(
this
.
selection
)
{
this
.
selection
.
setHide
();
}
if
(
this
.
range
)
{
if
(
this
.
range
)
{
this
.
range
.
nativeSel
.
removeAllRanges
();
}
this
.
index
=
0
;
this
.
isTypeText
=
false
;
return
this
;
},
setTextEditStatus
:
function
(
status
)
{
setTextEditStatus
:
function
(
status
)
{
this
.
textEditStatus
=
status
||
false
;
return
this
;
},
isTextEditStatus
:
function
()
{
isTextEditStatus
:
function
()
{
return
this
.
textEditStatus
;
},
constructor
:
function
(
km
)
{
constructor
:
function
(
km
)
{
var
me
=
this
;
this
.
setKityMinder
(
km
);
this
.
setKityMinder
(
km
);
this
.
textEditStatus
=
false
;
var
_div
=
document
.
createElement
(
'div'
);
_div
.
setAttribute
(
'contenteditable'
,
true
);
var
_div
=
document
.
createElement
(
'div'
);
_div
.
setAttribute
(
'contenteditable'
,
true
);
_div
.
className
=
'km_receiver'
;
this
.
container
=
_div
;
if
(
browser
.
ie
&&
browser
.
version
==
11
)
{
utils
.
listen
(
this
.
container
,
'keydown keypress keyup'
,
function
(
e
)
{
me
.
keyboardEvents
.
call
(
me
,
new
MinderEvent
(
e
.
type
==
'keyup'
?
"beforekeyup"
:
e
.
type
,
e
)
);
}
);
if
(
browser
.
ie
&&
browser
.
version
==
11
)
{
utils
.
listen
(
this
.
container
,
'keydown keypress keyup'
,
function
(
e
)
{
me
.
keyboardEvents
.
call
(
me
,
new
MinderEvent
(
e
.
type
==
'keyup'
?
"beforekeyup"
:
e
.
type
,
e
)
);
});
}
utils
.
addCssRule
(
'km_receiver_css'
,
' .km_receiver{white-space:nowrap;position:absolute;padding:0;margin:0;word-wrap:break-word;clip:rect(1em 1em 1em 1em);}'
);
//
this
.
km
.
on
(
'textedit.beforekeyup textedit.keydown textedit.keypress textedit.paste'
,
utils
.
proxy
(
this
.
keyboardEvents
,
this
)
);
utils
.
addCssRule
(
'km_receiver_css'
,
' .km_receiver{white-space:nowrap;position:absolute;padding:0;margin:0;word-wrap:break-word;clip:rect(1em 1em 1em 1em);}'
);
//
this
.
km
.
on
(
'textedit.beforekeyup textedit.keydown textedit.keypress textedit.paste'
,
utils
.
proxy
(
this
.
keyboardEvents
,
this
)
);
this
.
timer
=
null
;
this
.
index
=
0
;
},
setRange
:
function
(
range
,
index
)
{
setRange
:
function
(
range
,
index
)
{
this
.
index
=
index
||
this
.
index
;
var
text
=
this
.
container
.
firstChild
;
this
.
range
=
range
;
range
.
setStart
(
text
||
this
.
container
,
this
.
index
).
collapse
(
true
);
range
.
setStart
(
text
||
this
.
container
,
this
.
index
).
collapse
(
true
);
var
me
=
this
;
setTimeout
(
function
()
{
setTimeout
(
function
()
{
me
.
container
.
focus
();
range
.
select
();
}
);
});
return
this
;
},
setTextShape
:
function
(
textShape
)
{
if
(
!
textShape
)
{
setTextShape
:
function
(
textShape
)
{
if
(
!
textShape
)
{
textShape
=
new
kity
.
Text
();
}
this
.
textShape
=
textShape
;
this
.
container
.
innerHTML
=
utils
.
unhtml
(
textShape
.
getContent
()
);
this
.
container
.
innerHTML
=
utils
.
unhtml
(
textShape
.
getContent
()
);
return
this
;
},
setTextShapeSize
:
function
(
size
)
{
this
.
textShape
.
setSize
(
size
);
setTextShapeSize
:
function
(
size
)
{
this
.
textShape
.
setSize
(
size
);
return
this
;
},
getTextShapeHeight
:
function
()
{
getTextShapeHeight
:
function
()
{
return
this
.
textShape
.
getRenderBox
().
height
;
},
appendTextShapeToPaper
:
function
(
paper
)
{
paper
.
addShape
(
this
.
textShape
);
appendTextShapeToPaper
:
function
(
paper
)
{
paper
.
addShape
(
this
.
textShape
);
return
this
;
},
setKityMinder
:
function
(
km
)
{
setKityMinder
:
function
(
km
)
{
this
.
km
=
km
;
return
this
;
},
setMinderNode
:
function
(
node
)
{
setMinderNode
:
function
(
node
)
{
this
.
minderNode
=
node
;
return
this
;
},
keyboardEvents
:
function
(
e
)
{
keyboardEvents
:
function
(
e
)
{
clearTimeout
(
this
.
timer
);
clearTimeout
(
this
.
timer
);
var
me
=
this
;
var
orgEvt
=
e
.
originEvent
;
var
keyCode
=
orgEvt
.
keyCode
;
var
keys
=
KityMinder
.
keymap
;
function
setTextToContainer
()
{
if
(
!
me
.
range
.
hasNativeRange
())
{
if
(
!
me
.
range
.
hasNativeRange
())
{
return
;
}
var
text
=
me
.
container
.
textContent
.
replace
(
/
[\u
200b
\t\r\n]
/g
,
''
);
var
text
=
me
.
container
.
textContent
.
replace
(
/
[\u
200b
\t\r\n]
/g
,
''
);
if
(
me
.
textShape
.
getOpacity
()
===
0
)
{
me
.
textShape
.
setOpacity
(
1
);
if
(
me
.
textShape
.
getOpacity
()
===
0
)
{
me
.
textShape
.
setOpacity
(
1
);
}
//#46 修复在ff下定位到文字后方空格光标不移动问题
if
(
browser
.
gecko
&&
/
\s
$/
.
test
(
text
)
)
{
if
(
browser
.
gecko
&&
/
\s
$/
.
test
(
text
)
)
{
text
+=
"
\
u200b"
;
}
me
.
minderNode
.
setText
(
text
);
if
(
text
.
length
===
0
)
{
me
.
minderNode
.
setText
(
'a'
);
me
.
minderNode
.
setText
(
text
);
if
(
text
.
length
===
0
)
{
me
.
minderNode
.
setText
(
'a'
);
}
me
.
setContainerStyle
();
me
.
km
.
updateLayout
(
me
.
minderNode
);
me
.
minderNode
.
render
().
layout
();
me
.
textShape
=
me
.
minderNode
.
getTextShape
();
if
(
text
.
length
===
0
)
{
me
.
textShape
.
setOpacity
(
0
);
if
(
text
.
length
===
0
)
{
me
.
textShape
.
setOpacity
(
0
);
}
me
.
setBaseOffset
();
me
.
updateTextData
();
...
...
@@ -118,9 +117,9 @@ Minder.Receiver = kity.createClass( 'Receiver', {
me
.
updateIndex
();
if
(
me
.
selection
.
getSelectionShowStatus
())
{
if
(
me
.
selection
.
getSelectionShowStatus
())
{
me
.
updateSelection
();
me
.
timer
=
setTimeout
(
function
()
{
me
.
timer
=
setTimeout
(
function
()
{
me
.
selection
.
setShow
();
},
500
);
}
...
...
@@ -128,144 +127,144 @@ Minder.Receiver = kity.createClass( 'Receiver', {
}
switch
(
e
.
type
)
{
case
'keydown'
:
this
.
isTypeText
=
keyCode
==
229
||
keyCode
===
0
;
switch
(
keyCode
)
{
case
keys
.
Enter
:
case
keys
.
Tab
:
this
.
selection
.
setHide
();
this
.
clear
().
setTextEditStatus
(
false
);
this
.
km
.
fire
(
'contentchange'
);
this
.
km
.
setStatus
(
'normal'
);
e
.
preventDefault
();
return
;
case
keymap
.
Shift
:
case
keymap
.
Control
:
case
keymap
.
Alt
:
case
keymap
.
Cmd
:
return
;
}
if
(
e
.
originEvent
.
ctrlKey
||
e
.
originEvent
.
metaKey
)
{
switch
(
e
.
type
)
{
case
'keydown'
:
this
.
isTypeText
=
keyCode
==
229
||
keyCode
===
0
;
switch
(
keyCode
)
{
case
keys
.
Enter
:
case
keys
.
Tab
:
this
.
selection
.
setHide
();
this
.
clear
().
setTextEditStatus
(
false
);
this
.
km
.
fire
(
'contentchange'
);
this
.
km
.
setStatus
(
'normal'
);
e
.
preventDefault
();
return
;
case
keymap
.
Shift
:
case
keymap
.
Control
:
case
keymap
.
Alt
:
case
keymap
.
Cmd
:
return
;
}
//粘贴
if
(
keyCode
==
keymap
.
v
)
{
if
(
e
.
originEvent
.
ctrlKey
||
e
.
originEvent
.
metaKey
)
{
setTimeout
(
function
()
{
me
.
range
.
updateNativeRange
().
insertNode
(
$
(
'<span>$$_kityminder_bookmark_$$</span>'
)[
0
]
);
me
.
container
.
innerHTML
=
utils
.
unhtml
(
me
.
container
.
textContent
.
replace
(
/
[\u
200b
\t\r\n]
/g
,
''
)
);
var
index
=
me
.
container
.
textContent
.
indexOf
(
'$$_kityminder_bookmark_$$'
);
me
.
container
.
textContent
=
me
.
container
.
textContent
.
replace
(
'$$_kityminder_bookmark_$$'
,
''
);
me
.
range
.
setStart
(
me
.
container
.
firstChild
,
index
).
collapse
(
true
).
select
();
setTextToContainer
();
},
100
);
}
//剪切
if
(
keyCode
==
keymap
.
x
)
{
setTimeout
(
function
()
{
setTextToContainer
();
},
100
);
}
return
;
}
//粘贴
if
(
keyCode
==
keymap
.
v
)
{
setTimeout
(
function
(){
setTextToContainer
();
});
break
;
case
'beforekeyup'
:
switch
(
keyCode
)
{
case
keymap
.
Enter
:
case
keymap
.
Tab
:
case
keymap
.
F2
:
if
(
keymap
.
Enter
==
keyCode
&&
(
this
.
isTypeText
||
browser
.
mac
&&
browser
.
gecko
)){
setTextToContainer
();
setTimeout
(
function
()
{
me
.
range
.
updateNativeRange
().
insertNode
(
$
(
'<span>$$_kityminder_bookmark_$$</span>'
)[
0
]);
me
.
container
.
innerHTML
=
utils
.
unhtml
(
me
.
container
.
textContent
.
replace
(
/
[\u
200b
\t\r\n]
/g
,
''
));
var
index
=
me
.
container
.
textContent
.
indexOf
(
'$$_kityminder_bookmark_$$'
);
me
.
container
.
textContent
=
me
.
container
.
textContent
.
replace
(
'$$_kityminder_bookmark_$$'
,
''
);
me
.
range
.
setStart
(
me
.
container
.
firstChild
,
index
).
collapse
(
true
).
select
();
setTextToContainer
();
},
100
);
}
if
(
this
.
keydownNode
===
this
.
minderNode
)
{
this
.
rollbackStatus
();
this
.
setTextEditStatus
(
false
);
this
.
clear
();
//剪切
if
(
keyCode
==
keymap
.
x
)
{
setTimeout
(
function
()
{
setTextToContainer
();
},
100
);
}
e
.
preventDefault
();
return
;
case
keymap
.
Del
:
case
keymap
.
Backspace
:
case
keymap
.
Spacebar
:
}
setTimeout
(
function
()
{
setTextToContainer
();
return
;
}
});
break
;
case
'beforekeyup'
:
switch
(
keyCode
)
{
case
keymap
.
Enter
:
case
keymap
.
Tab
:
case
keymap
.
F2
:
if
(
keymap
.
Enter
==
keyCode
&&
(
this
.
isTypeText
||
browser
.
mac
&&
browser
.
gecko
))
{
setTextToContainer
();
}
if
(
this
.
keydownNode
===
this
.
minderNode
)
{
this
.
rollbackStatus
();
this
.
setTextEditStatus
(
false
);
this
.
clear
();
}
e
.
preventDefault
();
return
;
case
keymap
.
Del
:
case
keymap
.
Backspace
:
case
keymap
.
Spacebar
:
setTextToContainer
();
return
;
}
if
(
this
.
isTypeText
)
{
setTextToContainer
();
}
if
(
browser
.
mac
&&
browser
.
gecko
)
setTextToContainer
();
return
true
;
if
(
this
.
isTypeText
)
{
setTextToContainer
();
}
if
(
browser
.
mac
&&
browser
.
gecko
)
setTextToContainer
();
return
true
;
}
},
updateIndex
:
function
()
{
updateIndex
:
function
()
{
this
.
index
=
this
.
range
.
getStart
().
startOffset
;
return
this
;
},
updateTextData
:
function
()
{
updateTextData
:
function
()
{
this
.
textShape
.
textData
=
this
.
getTextOffsetData
();
return
this
;
},
setSelection
:
function
(
selection
)
{
setSelection
:
function
(
selection
)
{
this
.
selection
=
selection
;
return
this
;
},
updateSelection
:
function
()
{
updateSelection
:
function
()
{
this
.
selection
.
setShowHold
();
this
.
selection
.
bringTop
();
//更新模拟选区的范围
this
.
selection
.
setStartOffset
(
this
.
index
).
collapse
(
true
);
if
(
this
.
index
==
this
.
textData
.
length
)
{
if
(
this
.
index
===
0
)
{
this
.
selection
.
setPosition
(
this
.
getBaseOffset
()
);
this
.
selection
.
setStartOffset
(
this
.
index
).
collapse
(
true
);
if
(
this
.
index
==
this
.
textData
.
length
)
{
if
(
this
.
index
===
0
)
{
this
.
selection
.
setPosition
(
this
.
getBaseOffset
()
);
}
else
{
this
.
selection
.
setPosition
(
{
x
:
this
.
textData
[
this
.
index
-
1
].
x
+
this
.
textData
[
this
.
index
-
1
].
width
,
y
:
this
.
textData
[
this
.
index
-
1
].
y
}
);
this
.
selection
.
setPosition
({
x
:
this
.
textData
[
this
.
index
-
1
].
x
+
this
.
textData
[
this
.
index
-
1
].
width
,
y
:
this
.
textData
[
this
.
index
-
1
].
y
});
}
}
else
{
this
.
selection
.
setPosition
(
this
.
textData
[
this
.
index
]
);
this
.
selection
.
setPosition
(
this
.
textData
[
this
.
index
]
);
}
return
this
;
},
getBaseOffset
:
function
(
refer
)
{
var
rb
=
this
.
textShape
.
getRenderBox
(
refer
||
this
.
km
.
getRenderContainer
()
);
getBaseOffset
:
function
(
refer
)
{
var
rb
=
this
.
textShape
.
getRenderBox
(
refer
||
this
.
km
.
getRenderContainer
()
);
// if(!this.pr) {
// this.km.getRenderContainer().addShape(this.pr = new kity.Rect().stroke('green'));
// }
// this.pr.setSize(rb.width, rb.height).setPosition(rb.x, rb.y);
return
rb
;
},
setBaseOffset
:
function
()
{
this
.
offset
=
this
.
textShape
.
getRenderBox
(
this
.
km
.
getRenderContainer
()
);
setBaseOffset
:
function
()
{
this
.
offset
=
this
.
textShape
.
getRenderBox
(
this
.
km
.
getRenderContainer
()
);
return
this
;
},
setContainerStyle
:
function
()
{
var
textShapeBox
=
this
.
getBaseOffset
(
'screen'
);
this
.
container
.
style
.
cssText
=
";left:"
+
textShapeBox
.
x
+
'px;top:'
+
(
textShapeBox
.
y
+
textShapeBox
.
height
*
0.1
)
+
'px;width:'
+
textShapeBox
.
width
+
'px;height:'
+
textShapeBox
.
height
+
'px;'
;
setContainerStyle
:
function
()
{
var
textShapeBox
=
this
.
getBaseOffset
(
'screen'
);
this
.
container
.
style
.
cssText
=
";left:"
+
textShapeBox
.
x
+
'px;top:'
+
(
textShapeBox
.
y
+
textShapeBox
.
height
*
0.1
)
+
'px;width:'
+
textShapeBox
.
width
+
'px;height:'
+
textShapeBox
.
height
+
'px;'
;
if
(
!
this
.
selection
.
isShow
()
)
{
if
(
!
this
.
selection
.
isShow
()
)
{
var
paperContainer
=
this
.
km
.
getPaper
();
var
width
=
paperContainer
.
node
.
parentNode
.
clientWidth
;
var
height
=
paperContainer
.
node
.
parentNode
.
clientHeight
;
if
(
width
<
this
.
container
.
offsetWidth
+
this
.
container
.
offsetLeft
)
{
this
.
km
.
getRenderContainer
().
translate
(
width
/
-
3
,
0
);
if
(
width
<
this
.
container
.
offsetWidth
+
this
.
container
.
offsetLeft
)
{
this
.
km
.
getRenderContainer
().
translate
(
width
/
-
3
,
0
);
this
.
setContainerStyle
();
}
else
if
(
height
<
this
.
container
.
offsetTop
+
this
.
container
.
offsetHeight
)
{
this
.
km
.
getRenderContainer
().
translate
(
0
,
height
/
-
3
);
}
else
if
(
height
<
this
.
container
.
offsetTop
+
this
.
container
.
offsetHeight
)
{
this
.
km
.
getRenderContainer
().
translate
(
0
,
height
/
-
3
);
this
.
setContainerStyle
();
}
}
...
...
@@ -273,39 +272,39 @@ Minder.Receiver = kity.createClass( 'Receiver', {
return
this
;
},
getTextOffsetData
:
function
()
{
getTextOffsetData
:
function
()
{
var
text
=
this
.
textShape
.
getContent
();
var
box
;
this
.
textData
=
[];
for
(
var
i
=
0
,
l
=
text
.
length
;
i
<
l
;
i
++
)
{
for
(
var
i
=
0
,
l
=
text
.
length
;
i
<
l
;
i
++
)
{
try
{
box
=
this
.
textShape
.
getExtentOfChar
(
i
);
}
catch
(
e
)
{
console
.
log
(
e
);
box
=
this
.
textShape
.
getExtentOfChar
(
i
);
}
catch
(
e
)
{
console
.
log
(
e
);
}
this
.
textData
.
push
(
{
this
.
textData
.
push
({
x
:
box
.
x
+
this
.
offset
.
x
,
y
:
this
.
offset
.
y
,
width
:
box
.
width
,
height
:
box
.
height
}
);
});
}
return
this
;
},
setCurrentIndex
:
function
(
offset
)
{
setCurrentIndex
:
function
(
offset
)
{
var
me
=
this
;
this
.
getTextOffsetData
();
var
hadChanged
=
false
;
utils
.
each
(
this
.
textData
,
function
(
i
,
v
)
{
utils
.
each
(
this
.
textData
,
function
(
i
,
v
)
{
//点击开始之前
if
(
i
===
0
&&
offset
.
x
<=
v
.
x
)
{
if
(
i
===
0
&&
offset
.
x
<=
v
.
x
)
{
me
.
index
=
0
;
return
false
;
}
if
(
offset
.
x
>=
v
.
x
&&
offset
.
x
<=
v
.
x
+
v
.
width
)
{
if
(
offset
.
x
-
v
.
x
>
v
.
width
/
2
)
{
if
(
offset
.
x
>=
v
.
x
&&
offset
.
x
<=
v
.
x
+
v
.
width
)
{
if
(
offset
.
x
-
v
.
x
>
v
.
width
/
2
)
{
me
.
index
=
i
+
1
;
}
else
{
...
...
@@ -315,100 +314,100 @@ Minder.Receiver = kity.createClass( 'Receiver', {
hadChanged
=
true
;
return
false
;
}
if
(
i
==
me
.
textData
.
length
-
1
&&
offset
.
x
>=
v
.
x
)
{
if
(
i
==
me
.
textData
.
length
-
1
&&
offset
.
x
>=
v
.
x
)
{
me
.
index
=
me
.
textData
.
length
;
return
false
;
}
}
);
});
return
this
;
},
setSelectionHeight
:
function
()
{
this
.
selection
.
setHeight
(
this
.
getTextShapeHeight
()
);
setSelectionHeight
:
function
()
{
this
.
selection
.
setHeight
(
this
.
getTextShapeHeight
()
);
return
this
;
},
updateSelectionByMousePosition
:
function
(
offset
,
dir
)
{
updateSelectionByMousePosition
:
function
(
offset
,
dir
)
{
var
me
=
this
;
utils
.
each
(
this
.
textData
,
function
(
i
,
v
)
{
utils
.
each
(
this
.
textData
,
function
(
i
,
v
)
{
//点击开始之前
if
(
i
===
0
&&
offset
.
x
<=
v
.
x
)
{
me
.
selection
.
setStartOffset
(
0
);
if
(
i
===
0
&&
offset
.
x
<=
v
.
x
)
{
me
.
selection
.
setStartOffset
(
0
);
return
false
;
}
if
(
i
==
me
.
textData
.
length
-
1
&&
offset
.
x
>=
v
.
x
)
{
me
.
selection
.
setEndOffset
(
me
.
textData
.
length
);
if
(
i
==
me
.
textData
.
length
-
1
&&
offset
.
x
>=
v
.
x
)
{
me
.
selection
.
setEndOffset
(
me
.
textData
.
length
);
return
false
;
}
if
(
offset
.
x
>=
v
.
x
&&
offset
.
x
<=
v
.
x
+
v
.
width
)
{
if
(
offset
.
x
>=
v
.
x
&&
offset
.
x
<=
v
.
x
+
v
.
width
)
{
if
(
me
.
index
==
i
)
{
if
(
i
===
0
)
{
me
.
selection
.
setStartOffset
(
i
);
if
(
me
.
index
==
i
)
{
if
(
i
===
0
)
{
me
.
selection
.
setStartOffset
(
i
);
}
if
(
offset
.
x
<=
v
.
x
+
v
.
width
/
2
)
{
if
(
offset
.
x
<=
v
.
x
+
v
.
width
/
2
)
{
me
.
selection
.
collapse
();
}
else
{
me
.
selection
.
setEndOffset
(
i
+
(
(
me
.
selection
.
endOffset
>
i
||
dir
==
1
)
&&
i
!=
me
.
textData
.
length
-
1
?
1
:
0
)
);
me
.
selection
.
setEndOffset
(
i
+
((
me
.
selection
.
endOffset
>
i
||
dir
==
1
)
&&
i
!=
me
.
textData
.
length
-
1
?
1
:
0
)
);
}
}
else
if
(
i
>
me
.
index
)
{
me
.
selection
.
setStartOffset
(
me
.
index
);
me
.
selection
.
setEndOffset
(
i
+
1
);
}
else
if
(
i
>
me
.
index
)
{
me
.
selection
.
setStartOffset
(
me
.
index
);
me
.
selection
.
setEndOffset
(
i
+
1
);
}
else
{
if
(
dir
==
1
)
{
me
.
selection
.
setStartOffset
(
i
+
(
offset
.
x
>=
v
.
x
+
v
.
width
/
2
&&
i
!=
me
.
textData
.
length
-
1
?
1
:
0
)
);
if
(
dir
==
1
)
{
me
.
selection
.
setStartOffset
(
i
+
(
offset
.
x
>=
v
.
x
+
v
.
width
/
2
&&
i
!=
me
.
textData
.
length
-
1
?
1
:
0
)
);
}
else
{
me
.
selection
.
setStartOffset
(
i
);
me
.
selection
.
setStartOffset
(
i
);
}
me
.
selection
.
setEndOffset
(
me
.
index
);
me
.
selection
.
setEndOffset
(
me
.
index
);
}
return
false
;
}
}
);
});
return
this
;
},
updateSelectionShow
:
function
()
{
var
startOffset
=
this
.
textData
[
this
.
selection
.
startOffset
],
endOffset
=
this
.
textData
[
this
.
selection
.
endOffset
],
updateSelectionShow
:
function
()
{
var
startOffset
=
this
.
textData
[
this
.
selection
.
startOffset
],
endOffset
=
this
.
textData
[
this
.
selection
.
endOffset
],
width
=
0
;
if
(
this
.
selection
.
collapsed
)
{
this
.
selection
.
updateShow
(
startOffset
||
this
.
textData
[
this
.
textData
.
length
-
1
],
1
);
if
(
this
.
selection
.
collapsed
)
{
this
.
selection
.
updateShow
(
startOffset
||
this
.
textData
[
this
.
textData
.
length
-
1
],
1
);
return
this
;
}
if
(
!
endOffset
)
{
if
(
!
endOffset
)
{
try
{
var
lastOffset
=
this
.
textData
[
this
.
textData
.
length
-
1
];
var
lastOffset
=
this
.
textData
[
this
.
textData
.
length
-
1
];
width
=
lastOffset
.
x
-
startOffset
.
x
+
lastOffset
.
width
;
}
catch
(
e
)
{
console
.
log
(
'e'
);
}
catch
(
e
)
{
console
.
log
(
'e'
);
}
}
else
{
width
=
endOffset
.
x
-
startOffset
.
x
;
}
this
.
selection
.
updateShow
(
startOffset
,
width
);
this
.
selection
.
updateShow
(
startOffset
,
width
);
return
this
;
},
updateRange
:
function
(
range
)
{
updateRange
:
function
(
range
)
{
var
node
=
this
.
container
.
firstChild
;
range
.
setStart
(
node
,
this
.
selection
.
startOffset
);
range
.
setEnd
(
node
,
this
.
selection
.
endOffset
);
range
.
setStart
(
node
,
this
.
selection
.
startOffset
);
range
.
setEnd
(
node
,
this
.
selection
.
endOffset
);
range
.
select
();
return
this
;
},
setIndex
:
function
(
index
)
{
setIndex
:
function
(
index
)
{
this
.
index
=
index
;
return
this
;
},
setContainerTxt
:
function
(
txt
)
{
setContainerTxt
:
function
(
txt
)
{
this
.
container
.
textContent
=
txt
;
return
this
;
}
}
);
\ No newline at end of file
});
\ No newline at end of file
src/module/geometry.js
View file @
d652a8fb
KityMinder
.
Geometry
=
(
function
()
{
var
g
=
{};
var
min
=
Math
.
min
,
max
=
Math
.
max
,
abs
=
Math
.
abs
;
var
own
=
Object
.
prototype
.
hasOwnProperty
;
KityMinder
.
Geometry
=
(
function
()
{
var
g
=
{};
var
min
=
Math
.
min
,
max
=
Math
.
max
,
abs
=
Math
.
abs
;
var
own
=
Object
.
prototype
.
hasOwnProperty
;
g
.
isNumberInRange
=
function
(
number
,
range
)
{
return
number
>
range
[
0
]
&&
number
<
range
[
1
];
};
g
.
isNumberInRange
=
function
(
number
,
range
)
{
return
number
>
range
[
0
]
&&
number
<
range
[
1
];
};
g
.
getDistance
=
function
(
p1
,
p2
)
{
return
kity
.
Vector
.
fromPoints
(
p1
,
p2
).
length
();
};
g
.
getDistance
=
function
(
p1
,
p2
)
{
return
kity
.
Vector
.
fromPoints
(
p1
,
p2
).
length
();
};
function
wrapBox
(
box
)
{
box
.
width
=
box
.
right
-
box
.
left
;
box
.
height
=
box
.
bottom
-
box
.
top
;
box
.
x
=
box
.
left
;
box
.
y
=
box
.
top
;
return
box
;
}
function
wrapBox
(
box
)
{
box
.
width
=
box
.
right
-
box
.
left
;
box
.
height
=
box
.
bottom
-
box
.
top
;
box
.
x
=
box
.
left
;
box
.
y
=
box
.
top
;
return
box
;
}
g
.
getBox
=
function
(
p1
,
p2
)
{
return
wrapBox
(
{
left
:
min
(
p1
.
x
,
p2
.
x
),
right
:
max
(
p1
.
x
,
p2
.
x
),
top
:
min
(
p1
.
y
,
p2
.
y
),
bottom
:
max
(
p1
.
y
,
p2
.
y
)
}
);
};
function
uniformBox
(
box
)
{
// duck check
if
(
'x'
in
box
)
{
box
.
left
=
box
.
x
;
box
.
right
=
box
.
x
+
box
.
width
;
box
.
top
=
box
.
y
;
box
.
bottom
=
box
.
y
+
box
.
height
;
}
}
g
.
mergeBox
=
function
(
b1
,
b2
)
{
return
wrapBox
(
{
left
:
min
(
b1
.
left
,
b2
.
left
),
right
:
max
(
b1
.
right
,
b2
.
right
),
top
:
min
(
b1
.
top
,
b2
.
top
),
bottom
:
max
(
b1
.
bottom
,
b2
.
bottom
)
}
);
};
g
.
wrapBox
=
wrapBox
;
g
.
getBoxRange
=
function
(
box
)
{
return
{
x
:
[
box
.
left
,
box
.
right
],
y
:
[
box
.
top
,
box
.
bottom
]
};
};
g
.
getBox
=
function
(
p1
,
p2
)
{
return
wrapBox
({
left
:
min
(
p1
.
x
,
p2
.
x
),
right
:
max
(
p1
.
x
,
p2
.
x
),
top
:
min
(
p1
.
y
,
p2
.
y
),
bottom
:
max
(
p1
.
y
,
p2
.
y
)
});
};
g
.
getBoxVertex
=
function
(
box
)
{
return
{
leftTop
:
{
x
:
box
.
left
,
y
:
box
.
top
},
rightTop
:
{
x
:
box
.
right
,
y
:
box
.
top
},
leftBottom
:
{
x
:
box
.
left
,
y
:
box
.
bottom
},
rightBottom
:
{
x
:
box
.
right
,
y
:
box
.
bottom
}
};
};
g
.
mergeBox
=
function
(
b1
,
b2
)
{
uniformBox
(
b1
);
uniformBox
(
b2
);
return
wrapBox
({
left
:
min
(
b1
.
left
,
b2
.
left
),
right
:
max
(
b1
.
right
,
b2
.
right
),
top
:
min
(
b1
.
top
,
b2
.
top
),
bottom
:
max
(
b1
.
bottom
,
b2
.
bottom
)
});
};
g
.
isPointInsideBox
=
function
(
p
,
b
)
{
var
ranges
=
g
.
getBoxRange
(
b
);
return
g
.
isNumberInRange
(
p
.
x
,
ranges
.
x
)
&&
g
.
isNumberInRange
(
p
.
y
,
ranges
.
y
);
};
g
.
getBoxRange
=
function
(
box
)
{
return
{
x
:
[
box
.
left
,
box
.
right
],
y
:
[
box
.
top
,
box
.
bottom
]
};
};
g
.
isBoxIntersect
=
function
(
b1
,
b2
)
{
var
minx
=
max
(
b1
.
left
,
b2
.
left
),
miny
=
max
(
b1
.
top
,
b2
.
top
),
maxx
=
min
(
b1
.
right
,
b2
.
right
),
maxy
=
min
(
b1
.
bottom
,
b2
.
bottom
);
return
minx
<
maxx
&&
miny
<
maxy
;
};
g
.
getBoxVertex
=
function
(
box
)
{
return
{
leftTop
:
{
x
:
box
.
left
,
y
:
box
.
top
},
rightTop
:
{
x
:
box
.
right
,
y
:
box
.
top
},
leftBottom
:
{
x
:
box
.
left
,
y
:
box
.
bottom
},
rightBottom
:
{
x
:
box
.
right
,
y
:
box
.
bottom
}
};
};
g
.
snapToSharp
=
function
(
unknown
)
{
if
(
utils
.
isNumber
(
unknown
)
)
{
return
(
unknown
|
0
)
+
0.5
;
}
if
(
utils
.
isArray
(
unknown
)
)
{
return
unknown
.
map
(
g
.
snapToSharp
);
}
[
'x'
,
'y'
,
'left'
,
'top'
,
'right'
,
'bottom'
].
forEach
(
function
(
n
)
{
if
(
own
.
call
(
unknown
,
n
)
)
{
unknown
[
n
]
=
g
.
snapToSharp
(
unknown
[
n
]
);
}
}
);
return
unknown
;
};
g
.
isPointInsideBox
=
function
(
p
,
b
)
{
var
ranges
=
g
.
getBoxRange
(
b
);
return
g
.
isNumberInRange
(
p
.
x
,
ranges
.
x
)
&&
g
.
isNumberInRange
(
p
.
y
,
ranges
.
y
);
};
g
.
expandBox
=
function
(
box
,
sizeX
,
sizeY
)
{
if
(
sizeY
===
undefined
)
{
sizeY
=
sizeX
;
}
return
wrapBox
(
{
left
:
box
.
left
-
sizeX
,
top
:
box
.
top
-
sizeY
,
right
:
box
.
right
+
sizeX
,
bottom
:
box
.
bottom
+
sizeY
}
);
};
g
.
isBoxIntersect
=
function
(
b1
,
b2
)
{
var
minx
=
max
(
b1
.
left
,
b2
.
left
),
miny
=
max
(
b1
.
top
,
b2
.
top
),
maxx
=
min
(
b1
.
right
,
b2
.
right
),
maxy
=
min
(
b1
.
bottom
,
b2
.
bottom
);
return
minx
<
maxx
&&
miny
<
maxy
;
};
return
g
;
}
)();
\ No newline at end of file
g
.
snapToSharp
=
function
(
unknown
)
{
if
(
utils
.
isNumber
(
unknown
))
{
return
(
unknown
|
0
)
+
0.5
;
}
if
(
utils
.
isArray
(
unknown
))
{
return
unknown
.
map
(
g
.
snapToSharp
);
}
[
'x'
,
'y'
,
'left'
,
'top'
,
'right'
,
'bottom'
].
forEach
(
function
(
n
)
{
if
(
own
.
call
(
unknown
,
n
))
{
unknown
[
n
]
=
g
.
snapToSharp
(
unknown
[
n
]);
}
});
return
unknown
;
};
g
.
expandBox
=
function
(
box
,
sizeX
,
sizeY
)
{
if
(
sizeY
===
undefined
)
{
sizeY
=
sizeX
;
}
return
wrapBox
({
left
:
box
.
left
-
sizeX
,
top
:
box
.
top
-
sizeY
,
right
:
box
.
right
+
sizeX
,
bottom
:
box
.
bottom
+
sizeY
});
};
return
g
;
})();
\ No newline at end of file
src/module/keyboard.js
View file @
d652a8fb
KityMinder
.
registerModule
(
"KeyboardModule"
,
function
()
{
KityMinder
.
registerModule
(
"KeyboardModule"
,
function
()
{
var
min
=
Math
.
min
,
max
=
Math
.
max
,
abs
=
Math
.
abs
,
...
...
@@ -8,7 +8,7 @@ KityMinder.registerModule("KeyboardModule", function () {
function
buildPositionNetwork
(
root
)
{
var
pointIndexes
=
[],
p
;
root
.
traverse
(
function
(
node
)
{
root
.
traverse
(
function
(
node
)
{
p
=
node
.
getRenderContainer
().
getRenderBox
(
'top'
);
// bugfix: 不应导航到收起的节点(判断其尺寸是否存在)
...
...
@@ -129,51 +129,52 @@ KityMinder.registerModule("KeyboardModule", function () {
}
return
{
"events"
:
{
contentchange
:
function
()
{
'events'
:
{
'contentchange'
:
function
()
{
buildPositionNetwork
(
this
.
getRoot
());
},
"normal.keydown"
:
function
(
e
)
{
'normal.keydown'
:
function
(
e
)
{
var
keys
=
KityMinder
.
keymap
;
var
node
=
e
.
getTargetNode
();
this
.
receiver
.
keydownNode
=
node
;
switch
(
e
.
originEvent
.
keyCode
)
{
case
keys
.
Enter
:
this
.
execCommand
(
'appendSiblingNode'
,
new
MinderNode
(
this
.
getLang
().
topic
));
e
.
preventDefault
();
break
;
case
keys
.
Tab
:
this
.
execCommand
(
'appendChildNode'
,
new
MinderNode
(
this
.
getLang
().
topic
));
e
.
preventDefault
();
break
;
case
keys
.
Backspace
:
case
keys
.
Del
:
e
.
preventDefault
();
this
.
execCommand
(
'removenode'
);
break
;
case
keys
.
F2
:
e
.
preventDefault
();
this
.
execCommand
(
'editnode'
);
break
;
case
keys
.
Left
:
navigateTo
(
this
,
'left'
);
e
.
preventDefault
();
break
;
case
keys
.
Up
:
navigateTo
(
this
,
'top'
);
e
.
preventDefault
();
break
;
case
keys
.
Right
:
navigateTo
(
this
,
'right'
);
e
.
preventDefault
();
break
;
case
keys
.
Down
:
navigateTo
(
this
,
'down'
);
e
.
preventDefault
();
break
;
case
keys
.
Enter
:
this
.
execCommand
(
'appendSiblingNode'
,
new
MinderNode
(
this
,
this
.
getLang
().
topic
));
e
.
preventDefault
();
break
;
case
keys
.
Tab
:
this
.
execCommand
(
'appendChildNode'
,
new
MinderNode
(
this
,
this
.
getLang
().
topic
));
e
.
preventDefault
();
break
;
case
keys
.
Backspace
:
case
keys
.
Del
:
e
.
preventDefault
();
this
.
execCommand
(
'removenode'
);
break
;
case
keys
.
F2
:
e
.
preventDefault
();
this
.
execCommand
(
'editnode'
);
break
;
case
keys
.
Left
:
navigateTo
(
this
,
'left'
);
e
.
preventDefault
();
break
;
case
keys
.
Up
:
navigateTo
(
this
,
'top'
);
e
.
preventDefault
();
break
;
case
keys
.
Right
:
navigateTo
(
this
,
'right'
);
e
.
preventDefault
();
break
;
case
keys
.
Down
:
navigateTo
(
this
,
'down'
);
e
.
preventDefault
();
break
;
}
}
...
...
src/module/outline.js
0 → 100644
View file @
d652a8fb
/* global Renderer: true */
KityMinder
.
registerModule
(
'OutlineModule'
,
function
()
{
return
{
renderers
:
{
outline
:
kity
.
createClass
(
'OutlineRenderer'
,
{
base
:
Renderer
,
create
:
function
(
node
)
{
var
outline
=
this
.
outline
=
new
kity
.
Rect
().
setId
(
KityMinder
.
uuid
(
'node_outline'
));
node
.
getRenderContainer
().
prependShape
(
outline
);
},
update
:
function
(
node
)
{
var
contentBox
=
node
.
getContentBox
();
var
paddingLeft
=
node
.
getStyle
(
'padding-left'
),
paddingRight
=
node
.
getStyle
(
'padding-right'
),
paddingTop
=
node
.
getStyle
(
'padding-top'
),
paddingBottom
=
node
.
getStyle
(
'padding-bottom'
);
this
.
outline
.
setPosition
(
contentBox
.
x
-
paddingLeft
,
contentBox
.
y
-
paddingTop
)
.
setSize
(
contentBox
.
width
+
paddingLeft
+
paddingRight
,
contentBox
.
height
+
paddingTop
+
paddingBottom
)
.
setRadius
(
node
.
getStyle
(
'radius'
))
.
fill
(
node
.
isSelected
()
?
node
.
getStyle
(
'selected-background'
)
:
node
.
getStyle
(
'background'
));
}
})
}
};
});
\ No newline at end of file
src/module/select.js
View file @
d652a8fb
KityMinder
.
registerModule
(
"Select"
,
function
()
{
KityMinder
.
registerModule
(
"Select"
,
function
()
{
var
minder
=
this
;
var
g
=
KityMinder
.
Geometry
;
// 在实例上渲染框选矩形、计算框选范围的对象
var
marqueeActivator
=
(
function
()
{
var
marqueeActivator
=
(
function
()
{
// 记录选区的开始位置(mousedown的位置)
var
startPosition
=
null
;
// 选区的图形
var
marqueeShape
=
new
kity
.
Path
().
fill
(
'rgba(255,255,255,.3)'
).
stroke
(
'white'
);
var
marqueeShape
=
new
kity
.
Path
().
fill
(
'rgba(255,255,255,.3)'
).
stroke
(
'white'
);
// 标记是否已经启动框选状态
// 并不是 mousedown 发生之后就启动框选状态,而是检测到移动了一定的距离(MARQUEE_MODE_THRESHOLD)之后
...
...
@@ -17,126 +17,126 @@ KityMinder.registerModule( "Select", function () {
var
MARQUEE_MODE_THRESHOLD
=
10
;
return
{
selectStart
:
function
(
e
)
{
selectStart
:
function
(
e
)
{
// 只接受左键
if
(
e
.
originEvent
.
button
)
return
;
if
(
e
.
originEvent
.
button
)
return
;
// 清理不正确状态
if
(
startPosition
)
{
if
(
startPosition
)
{
return
this
.
selectEnd
();
}
startPosition
=
g
.
snapToSharp
(
e
.
getPosition
()
);
startPosition
=
g
.
snapToSharp
(
e
.
getPosition
()
);
},
selectMove
:
function
(
e
)
{
if
(
minder
.
isTextEditStatus
()
)
{
selectMove
:
function
(
e
)
{
if
(
minder
.
isTextEditStatus
()
)
{
return
;
}
if
(
!
startPosition
)
return
;
if
(
!
startPosition
)
return
;
var
p1
=
startPosition
,
p2
=
e
.
getPosition
();
// 检测是否要进入选区模式
if
(
!
marqueeMode
)
{
if
(
!
marqueeMode
)
{
// 距离没达到阈值,退出
if
(
g
.
getDistance
(
p1
,
p2
)
<
MARQUEE_MODE_THRESHOLD
)
{
if
(
g
.
getDistance
(
p1
,
p2
)
<
MARQUEE_MODE_THRESHOLD
)
{
return
;
}
// 已经达到阈值,记录下来并且重置选区形状
marqueeMode
=
true
;
minder
.
getPaper
().
addShape
(
marqueeShape
);
marqueeShape
.
setOpacity
(
0.8
).
getDrawer
().
clear
();
minder
.
getPaper
().
addShape
(
marqueeShape
);
marqueeShape
.
setOpacity
(
0.8
).
getDrawer
().
clear
();
}
var
marquee
=
g
.
getBox
(
p1
,
p2
),
var
marquee
=
g
.
getBox
(
p1
,
p2
),
selectedNodes
=
[];
// 使其犀利
g
.
snapToSharp
(
marquee
);
g
.
snapToSharp
(
marquee
);
// 选区形状更新
marqueeShape
.
getDrawer
().
pipe
(
function
()
{
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
.
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
.
getRenderContainer
().
getRenderBox
(
"top"
);
if
(
g
.
isBoxIntersect
(
renderBox
,
marquee
)
)
{
selectedNodes
.
push
(
node
);
minder
.
getRoot
().
traverse
(
function
(
node
)
{
var
renderBox
=
node
.
getRenderContainer
().
getRenderBox
(
"top"
);
if
(
g
.
isBoxIntersect
(
renderBox
,
marquee
)
)
{
selectedNodes
.
push
(
node
);
}
}
);
});
// 应用选中范围
minder
.
select
(
selectedNodes
,
true
);
minder
.
select
(
selectedNodes
,
true
);
},
selectEnd
:
function
(
e
)
{
if
(
startPosition
)
{
selectEnd
:
function
(
e
)
{
if
(
startPosition
)
{
startPosition
=
null
;
}
if
(
marqueeMode
)
{
marqueeShape
.
fadeOut
(
200
,
'ease'
,
0
,
function
()
{
if
(
marqueeShape
.
remove
)
marqueeShape
.
remove
();
}
);
if
(
marqueeMode
)
{
marqueeShape
.
fadeOut
(
200
,
'ease'
,
0
,
function
()
{
if
(
marqueeShape
.
remove
)
marqueeShape
.
remove
();
});
marqueeMode
=
false
;
}
}
};
}
)();
})();
var
lastDownNode
=
null
;
return
{
"events"
:
{
"normal.mousedown textedit.mousedown"
:
function
(
e
)
{
'events'
:
{
'normal.mousedown textedit.mousedown'
:
function
(
e
)
{
var
downNode
=
e
.
getTargetNode
();
// 没有点中节点:
// 清除选中状态,并且标记选区开始位置
if
(
!
downNode
)
{
if
(
!
downNode
)
{
this
.
removeAllSelectedNodes
();
marqueeActivator
.
selectStart
(
e
);
marqueeActivator
.
selectStart
(
e
);
this
.
setStatus
(
'normal'
)
this
.
setStatus
(
'normal'
)
;
}
// 点中了节点,并且按了 shift 键:
// 被点中的节点切换选中状态
else
if
(
e
.
originEvent
.
shiftKey
)
{
this
.
toggleSelect
(
downNode
);
else
if
(
e
.
originEvent
.
shiftKey
)
{
this
.
toggleSelect
(
downNode
);
}
// 点中的节点没有被选择:
// 单选点中的节点
else
if
(
!
downNode
.
isSelected
()
)
{
this
.
select
(
downNode
,
true
);
else
if
(
!
downNode
.
isSelected
()
)
{
this
.
select
(
downNode
,
true
);
}
// 点中的节点被选中了,并且不是单选:
// 完成整个点击之后需要使其变为单选。
// 不能马上变为单选,因为可能是需要拖动选中的多个节点
else
if
(
!
this
.
isSingleSelect
()
)
{
else
if
(
!
this
.
isSingleSelect
()
)
{
lastDownNode
=
downNode
;
}
},
"normal.mousemove textedit.mousemove"
:
marqueeActivator
.
selectMove
,
"normal.mouseup textedit.mouseup"
:
function
(
e
)
{
'normal.mousemove textedit.mousemove'
:
marqueeActivator
.
selectMove
,
'normal.mouseup textedit.mouseup'
:
function
(
e
)
{
var
upNode
=
e
.
getTargetNode
();
// 如果 mouseup 发生在 lastDownNode 外,是无需理会的
if
(
upNode
&&
upNode
==
lastDownNode
)
{
this
.
select
(
lastDownNode
,
true
);
if
(
upNode
&&
upNode
==
lastDownNode
)
{
this
.
select
(
lastDownNode
,
true
);
lastDownNode
=
null
;
}
// 清理一下选择状态
marqueeActivator
.
selectEnd
(
e
);
marqueeActivator
.
selectEnd
(
e
);
}
}
};
}
);
\ No newline at end of file
});
\ No newline at end of file
src/module/view.js
View file @
d652a8fb
var
ViewDragger
=
kity
.
createClass
(
"ViewDragger"
,
{
constructor
:
function
(
minder
)
{
var
ViewDragger
=
kity
.
createClass
(
"ViewDragger"
,
{
constructor
:
function
(
minder
)
{
this
.
_minder
=
minder
;
this
.
_enabled
=
false
;
this
.
_offset
=
{
...
...
@@ -8,132 +8,138 @@ var ViewDragger = kity.createClass( "ViewDragger", {
};
this
.
_bind
();
},
isEnabled
:
function
()
{
isEnabled
:
function
()
{
return
this
.
_enabled
;
},
setEnabled
:
function
(
value
)
{
setEnabled
:
function
(
value
)
{
var
paper
=
this
.
_minder
.
getPaper
();
paper
.
setStyle
(
'cursor'
,
value
?
'pointer'
:
'default'
);
paper
.
setStyle
(
'cursor'
,
value
?
'-webkit-grab'
:
'default'
);
paper
.
setStyle
(
'cursor'
,
value
?
'pointer'
:
'default'
);
paper
.
setStyle
(
'cursor'
,
value
?
'-webkit-grab'
:
'default'
);
this
.
_enabled
=
value
;
},
move
:
function
(
offset
)
{
this
.
_minder
.
getRenderContainer
().
translate
(
offset
.
x
,
offset
.
y
);
move
:
function
(
offset
)
{
this
.
_minder
.
getRenderContainer
().
translate
(
offset
.
x
,
offset
.
y
);
},
_bind
:
function
()
{
_bind
:
function
()
{
var
dragger
=
this
,
isRootDrag
=
false
,
lastPosition
=
null
,
currentPosition
=
null
;
this
.
_minder
.
on
(
'normal.mousedown readonly.mousedown readonly.touchstart'
,
function
(
e
)
{
this
.
_minder
.
on
(
'normal.mousedown readonly.mousedown readonly.touchstart'
,
function
(
e
)
{
// 点击未选中的根节点临时开启
if
(
e
.
getTargetNode
()
==
this
.
getRoot
()
&&
(
!
this
.
getRoot
().
isSelected
()
||
!
this
.
isSingleSelect
()
)
)
{
if
(
e
.
getTargetNode
()
==
this
.
getRoot
()
&&
(
!
this
.
getRoot
().
isSelected
()
||
!
this
.
isSingleSelect
())
)
{
lastPosition
=
e
.
getPosition
();
isRootDrag
=
true
;
}
}
)
})
.
on
(
'normal.mousemove normal.touchmove'
,
function
(
e
)
{
.
on
(
'normal.mousemove normal.touchmove'
,
function
(
e
)
{
if
(
!
isRootDrag
)
return
;
var
offset
=
kity
.
Vector
.
fromPoints
(
lastPosition
,
e
.
getPosition
());
if
(
offset
.
length
()
>
3
)
this
.
setStatus
(
'hand'
);
var
offset
=
kity
.
Vector
.
fromPoints
(
lastPosition
,
e
.
getPosition
());
if
(
offset
.
length
()
>
3
)
this
.
setStatus
(
'hand'
);
})
.
on
(
'hand.beforemousedown hand.beforetouchend'
,
function
(
e
)
{
.
on
(
'hand.beforemousedown hand.beforetouchend'
,
function
(
e
)
{
// 已经被用户打开拖放模式
if
(
dragger
.
isEnabled
()
)
{
if
(
dragger
.
isEnabled
()
)
{
lastPosition
=
e
.
getPosition
();
e
.
stopPropagation
();
}
}
)
})
.
on
(
'hand.beforemousemove hand.beforetouchmove'
,
function
(
e
)
{
if
(
lastPosition
)
{
.
on
(
'hand.beforemousemove hand.beforetouchmove'
,
function
(
e
)
{
if
(
lastPosition
)
{
currentPosition
=
e
.
getPosition
();
// 当前偏移加上历史偏移
var
offset
=
kity
.
Vector
.
fromPoints
(
lastPosition
,
currentPosition
);
dragger
.
move
(
offset
);
var
offset
=
kity
.
Vector
.
fromPoints
(
lastPosition
,
currentPosition
);
dragger
.
move
(
offset
);
e
.
stopPropagation
();
e
.
preventDefault
();
e
.
originEvent
.
preventDefault
();
lastPosition
=
currentPosition
;
}
}
)
})
.
on
(
'mouseup'
,
function
(
e
)
{
.
on
(
'mouseup'
,
function
(
e
)
{
lastPosition
=
null
;
// 临时拖动需要还原状态
if
(
isRootDrag
)
{
dragger
.
setEnabled
(
false
);
if
(
isRootDrag
)
{
dragger
.
setEnabled
(
false
);
isRootDrag
=
false
;
this
.
rollbackStatus
();
}
}
);
});
}
}
);
});
KityMinder
.
registerModule
(
'View'
,
function
()
{
KityMinder
.
registerModule
(
'View'
,
function
()
{
var
km
=
this
;
var
ToggleHandCommand
=
kity
.
createClass
(
"ToggleHandCommand"
,
{
var
ToggleHandCommand
=
kity
.
createClass
(
"ToggleHandCommand"
,
{
base
:
Command
,
execute
:
function
(
minder
)
{
execute
:
function
(
minder
)
{
minder
.
_viewDragger
.
setEnabled
(
!
minder
.
_viewDragger
.
isEnabled
()
);
if
(
minder
.
_viewDragger
.
isEnabled
()
)
{
minder
.
setStatus
(
'hand'
);
minder
.
_viewDragger
.
setEnabled
(
!
minder
.
_viewDragger
.
isEnabled
()
);
if
(
minder
.
_viewDragger
.
isEnabled
()
)
{
minder
.
setStatus
(
'hand'
);
}
else
{
minder
.
rollbackStatus
();
}
this
.
setContentChanged
(
false
);
this
.
setContentChanged
(
false
);
},
queryState
:
function
(
minder
)
{
queryState
:
function
(
minder
)
{
return
minder
.
_viewDragger
.
isEnabled
()
?
1
:
0
;
},
enableReadOnly
:
false
}
);
});
var
CameraCommand
=
kity
.
createClass
(
"CameraCommand"
,
{
var
CameraCommand
=
kity
.
createClass
(
"CameraCommand"
,
{
base
:
Command
,
execute
:
function
(
km
,
focusNode
)
{
execute
:
function
(
km
,
focusNode
,
noAnimate
)
{
focusNode
=
focusNode
||
km
.
getRoot
();
var
viewport
=
km
.
getPaper
().
getViewPort
();
var
offset
=
focusNode
.
getRenderContainer
().
getRenderBox
(
'view'
);
var
offset
=
focusNode
.
getRenderContainer
().
getRenderBox
(
'view'
);
var
dx
=
viewport
.
center
.
x
-
offset
.
x
-
offset
.
width
/
2
,
dy
=
viewport
.
center
.
y
-
offset
.
y
;
km
.
getRenderContainer
().
fxTranslate
(
dx
,
dy
,
1000
,
"easeOutQuint"
);
this
.
setContentChanged
(
false
);
if
(
noAnimate
)
{
km
.
getRenderContainer
().
translate
(
dx
,
dy
);
}
else
{
km
.
getRenderContainer
().
fxTranslate
(
dx
,
dy
,
1000
,
"easeOutQuint"
);
}
this
.
setContentChanged
(
false
);
},
enableReadOnly
:
false
}
);
});
return
{
init
:
function
()
{
this
.
_viewDragger
=
new
ViewDragger
(
this
);
init
:
function
()
{
this
.
_viewDragger
=
new
ViewDragger
(
this
);
},
commands
:
{
'hand'
:
ToggleHandCommand
,
'camera'
:
CameraCommand
},
events
:
{
keyup
:
function
(
e
)
{
if
(
e
.
originEvent
.
keyCode
==
keymap
.
Spacebar
&&
this
.
getSelectedNodes
().
length
===
0
)
{
this
.
execCommand
(
'hand'
);
keyup
:
function
(
e
)
{
if
(
e
.
originEvent
.
keyCode
==
keymap
.
Spacebar
&&
this
.
getSelectedNodes
().
length
===
0
)
{
this
.
execCommand
(
'hand'
);
e
.
preventDefault
();
}
},
mousewheel
:
function
(
e
)
{
mousewheel
:
function
(
e
)
{
var
dx
,
dy
;
e
=
e
.
originEvent
;
if
(
e
.
ctrlKey
||
e
.
shiftKey
)
return
;
if
(
e
.
ctrlKey
||
e
.
shiftKey
)
return
;
if
(
'wheelDeltaX'
in
e
)
{
if
(
'wheelDeltaX'
in
e
)
{
dx
=
e
.
wheelDeltaX
||
0
;
dy
=
e
.
wheelDeltaY
||
0
;
...
...
@@ -145,18 +151,35 @@ KityMinder.registerModule( 'View', function () {
}
this
.
_viewDragger
.
move
(
{
this
.
_viewDragger
.
move
({
x
:
dx
/
2.5
,
y
:
dy
/
2.5
}
);
});
e
.
preventDefault
();
},
'normal.dblclick readonly.dblclick'
:
function
(
e
)
{
if
(
e
.
kityEvent
.
targetShape
instanceof
kity
.
Paper
)
{
this
.
execCommand
(
'camera'
,
this
.
getRoot
()
);
'normal.dblclick readonly.dblclick'
:
function
(
e
)
{
if
(
e
.
kityEvent
.
targetShape
instanceof
kity
.
Paper
)
{
this
.
execCommand
(
'camera'
,
this
.
getRoot
()
);
}
},
ready
:
function
()
{
this
.
execCommand
(
'camera'
,
null
,
true
);
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
.
getRenderContainer
().
translate
(
(
a
.
width
-
b
.
width
)
/
2
,
(
a
.
height
-
b
.
height
)
/
2
);
this
.
_lastClientSize
=
a
;
}
}
};
}
);
\ No newline at end of file
});
\ No newline at end of file
src/theme/default.js
0 → 100644
View file @
d652a8fb
KityMinder
.
registerTheme
(
'default'
,
{
'root-color'
:
'#430'
,
'root-background'
:
'#e9df98'
,
'root-stroke'
:
'none'
,
'root-font-size'
:
24
,
'root-padding'
:
[
15
,
25
],
'root-margin'
:
0
,
'root-radius'
:
30
,
'root-space'
:
10
,
'main-color'
:
'#333'
,
'main-background'
:
'#a4c5c0'
,
'main-stroke'
:
'none'
,
'main-font-size'
:
16
,
'main-padding'
:
[
6
,
20
],
'main-margin'
:
[
0
,
10
,
30
,
50
],
'main-radius'
:
10
,
'main-space'
:
5
,
'sub-color'
:
'white'
,
'sub-background'
:
'none'
,
'sub-stroke'
:
'white'
,
'sub-font-size'
:
12
,
'sub-padding'
:
[
5
,
10
],
'sub-margin'
:
[
0
,
10
,
20
,
6
],
'sub-radius'
:
0
,
'sub-space'
:
5
,
'selected-background'
:
'rgb(254, 219, 0)'
});
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment