Commit d652a8fb authored by techird's avatar techird

stash

parent e2ac6d1e
/**
* 开发版本的文件导入
*/
(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>');
}
......
......@@ -62,8 +62,8 @@
</body>
<script>
// create km instance
window.km = KM.getKityMinder('kityminder');
km = KM.getKityMinder('kityminder');
// New Version Notify
$(function() {
......
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
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
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
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
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 MinderNode();
node.appendChild( childNode );
importNode( childNode, childrenTreeData[ i ], km );
if (!childrenTreeData) return;
for (var i = 0; i < childrenTreeData.length; i++) {
var childNode = km.createNode();
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
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
// 模块声明周期维护
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
......@@ -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
// 选区管理
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
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
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
......@@ -46,7 +46,7 @@ kity.extendClass(Minder, {
* @param {String} name 要使用的主题的名称
*/
useTheme: function(name) {
if (!KityMinder._theme[name]) {
if (!KityMinder._themes[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._themes[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
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 {
'<':'&lt;',
'&':'&amp;',
'"':'&quot;',
'>':'&gt;',
"'":'&#39;'
'<': '&lt;',
'&': '&amp;',
'"': '&quot;',
'>': '&gt;',
"'": '&#39;'
}[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
/* 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
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
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
//接收者
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( /[\u200b\t\r\n]/g, '' );
var text = me.container.textContent.replace(/[\u200b\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( /[\u200b\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(/[\u200b\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
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
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;
}
}
......
/* 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
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
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
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment