Commit 9a0a93f3 authored by Akikonata's avatar Akikonata

Merge branch 'dev' of https://github.com/fex-team/kityminder into dev

parents b74c7499 e9d426ce
......@@ -19,6 +19,7 @@
5. 优化了输入文字时的卡顿效果
6. 优化了当输入中文时,中文显示位置与光标距离过远的问题
7. html标签转码问题
8. 修复撤销按钮点击后,重做按钮还是不可点问题
## v1.1.2
......
......@@ -75,11 +75,24 @@ module.exports = function ( grunt ) {
files: [ {
src: [ 'dialogs/**', 'lang/**', 'lib/**', 'social/**', 'themes/**', 'index.html' ],
dest: distPath
}, {
src: [ 'kity/dist/kitygraph.all.min.js' ],
dest: distPath + 'lib/',
flatten: true
} ]
}]
},
kity: {
expand: true,
cwd: 'kity/dist/',
src: '**',
dest: distPath + 'lib/'
},
km_config: {
expand: true,
src: 'kityminder.config.js',
dest: distPath
},
mise: {
files: [{
src: ['LICENSE', 'favicon.ico', 'README.md'],
dest: distPath
}]
}
},
replace: {
......@@ -89,6 +102,18 @@ module.exports = function ( grunt ) {
replacements: [ {
from: /kity\/dist\/kitygraph\.all\.js/ig,
to: 'lib/kitygraph.all.min.js'
}, {
from: /import\.js/,
to: 'kityminder.all.min.js'
} ]
},
noCache: {
src: distPath + 'index.html',
overwrite: true,
replacements: [ {
from: /src=\"(.+?)\.js\"/ig,
to: 'src="$1.js?_=' + +new Date() + '"'
} ]
}
},
......
( function () {
( function (utils) {
//todo 这里先写死成中文
var content = '<div class="hyperlink-content" style="padding:20px;width:360px;">';
content += '<style>';
......@@ -61,4 +61,4 @@
},
width: 400
} );
} )();
\ No newline at end of file
} )(KM.Utils);
\ No newline at end of file
( function () {
( function (utils) {
KM.registerWidget( 'markers', {
tpl: "<style>" +
".kmui-dialog-<%= container %> .priority .icon{background:url(dialogs/markers/images/iconpriority.png) 0 0}" +
......@@ -55,4 +55,4 @@
width: 200
} )
} )();
\ No newline at end of file
} )(KM.Utils);
Copyright (c) 2014, FEX,Baidu.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the {organization} nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
Kity Minder
==========
## 简介
KityMinder 是百度 FEX 团队的 f-cube 小组(原UEditor小组)的又一力作。作为一款在线的脑图编辑工具,它有着很多Native编辑工具的交互体验。KM与UE有着一样的宗旨,就是注重最终用户的使用体验。同时,它充分发挥了Web云存储的优势,可以直接将编辑中的脑图同步到云端。此外,借由独创的 “云盘分享”功能,用户可以一键将当前编辑的脑图直接生成在线链接共享给其他用户,实现无缝沟通。
![KityMinder](summary.jpg "KityMinder 界面")
KM是基于SVG技术实现,使用JavaScript+html实现。支持绝大多数的主流浏览器。
支持列表如下
1. Chrome
2. Firefox
3. Safari
4. IE9+
## 线上版本
产品地址:[http://naotu.baidu.com](http://naotu.baidu.com)
注意:由于历史原因,有三个发布过的公开地址:
1. [~~http://fex-team.baidu.com/kityminder/dist~~](http://fex-team.baidu.com/kityminder/dist)
2. [~~http://kitygraph.github.io/kityminder/dist~~](http://kitygraph.github.io/kityminder/dist)
3. [http://fex.baidu.com/kityminder/dist](http://fex.baidu.com/kityminder/dist)
第 1 个地址已经失效;
第 2 个地址不再维护更新(原因是我们项目地址迁移到了 fex-team);
第 3 个地址是更新频率最高的地址,新功能可以在这里尝鲜;
[产品地址](http://naotu.baidu.com)已经稳定,请大家放心使用。地址变动频繁带来的不便,请谅解。
## 依赖说明
KityMinder 依赖 Kity 库。刚下载的压缩包或者刚从 github 拉下来的代码会有一个空的 kity 目录。要运行调试,必须加载 Kity 的依赖:
1. 如果你下载的是 KityMinder 的压缩包,那么需要手动下载 [Kity](http://kitygraph.github.io/kityminder/kity/dist/kitygraph.all.js) 库到 kity/dist/kitygraph.all.js
2. 如果你是从 github 上拉源代码下来的,那么可以更新一下子模块:
```bash
cd YOUR_KITYMINDER_PATH
git submodule init
git submodule update
```
## 联系我们
邮件: kity@baidu.com
讨论群: 374918234
#github-url{position:absolute;width:130px;height:130px;right:-90px;top:60px;background-color:#fff;border-radius:65px;box-shadow:-3px 1px 10px rgba(0,0,0,0.3);-webkit-transition:all .2s ease;-moz-transition:all .2s ease;-ms-transition:all .2s ease;transition:all .2s ease;opacity:.3;cursor:pointer}#github-url:hover{-webkit-transform:translate(-280px);-moz-transform:translate(-280px);-ms-transform:translate(-280px);transform:translate(-280px);opacity:1}
#github-url:before{content:' ';display:block;position:absolute;width:300px;height:130px;left:65px;top:0;background:rgba(0,0,0,0.001)}
#github-url:after{content:' ';display:block;position:absolute;width:130px;height:130px;background:url(../img/github_mark.png) no-repeat 5px 4px}
#github-url a{display:block;position:absolute;top:40px;font-size:18px;width:300px;height:40px;padding:10px 0 10px 20px;line-height:40px;color:#000;left:120px;border-radius:0 25px 25px 0;background-color:#fff}
#about{position:absolute;bottom:10px;right:10px;height:24px;line-height:24px;color:#888;font-family:Arial;font-size:13px;font-weight:normal;margin:0;text-shadow:0 1px 1px #000}#about a{color:#888}#about a:hover{color:#fff}
#km-version.new-version{position:relative;padding-right:30px}
#km-version.new-version:after{content:'NEW';color:#ff0;position:absolute;top:-10px;right:-5px;display:block;background:#f00;padding:0 5px;border-radius:4px;text-shadow:none;box-shadow:-1px 1px 3px rgba(0,0,0,0.3);-webkit-transform:scale(.6);-moz-transform:scale(.6);-ms-transform:scale(.6);transform:scale(.6)}
@bg: #FFF;
#github-url {
position: absolute;
width: 130px;
height: 130px;
right: -90px;
top: 60px;
background-color: @bg;
border-radius: 65px;
box-shadow: -3px 1px 10px rgba(0,0,0,.3);
-webkit-transition: all .2s ease;
-moz-transition: all .2s ease;
-ms-transition: all .2s ease;
transition: all .2s ease;
opacity: .3;
cursor: pointer;
&:hover {
-webkit-transform: translate(-280px);
-moz-transform: translate(-280px);
-ms-transform: translate(-280px);
transform: translate(-280px);
opacity: 1;
}
&:before {
content: ' ';
display: block;
position: absolute;
width: 300px;
height: 130px;
left: 65px;
top: 0;
background: rgba(0,0,0,0.001);
}
&:after {
content: ' ';
display: block;
position: absolute;
width: 130px;
height: 130px;
background: url(../img/github_mark.png) no-repeat 5px 4px;
}
a {
display: block;
position: absolute;
top: 40px;
font-size: 18px;
width: 300px;
height: 40px;
padding: 10px 0 10px 20px;
line-height: 40px;
color: black;
left: 120px;
border-radius: 0 25px 25px 0;
background-color: @bg;
}
}
#about {
position: absolute;
bottom: 10px;
right: 10px;
height: 24px;
line-height: 24px;
color: #888;
font-family: Arial;
font-size: 13px;
font-weight: normal;
margin: 0;
text-shadow: 0 1px 1px black;
a {
color: #888;
&:hover {
color: white;
}
}
}
#km-version.new-version {
position: relative;
padding-right: 30px;
}
#km-version.new-version:after {
content: 'NEW';
color: yellow;
position: absolute;
top: -10px;
right: -5px;
display: block;
background: red;
padding: 0 5px;
border-radius: 4px;
text-shadow: none;
box-shadow: -1px 1px 3px rgba(0,0,0,.3);
-webkit-transform: scale(.6);
-moz-transform: scale(.6);
-ms-transform: scale(.6);
transform: scale(.6);
}
\ No newline at end of file
.priority .icon {background:url(../dialogs/icons/iconpriority.png) 0 0}
.progress .icon{background:url(../dialogs/icons/iconprogress.png) 0 0}
.icon.p2{background-position: -20px 0}
.icon.p3{background-position: -40px 0}
.icon.p4{background-position: -60px 0}
.icon.p5{background-position: -80px 0}
\ No newline at end of file
......@@ -6,8 +6,10 @@
helpContent += '<ul>';
helpContent += ' <li><h3>插入子节点:</h3>在选中的节点中按 Tab 键</li>';
helpContent += ' <li><h3>插入同级节点:</h3>在选中的节点中按 Enter/Return 键</li>';
helpContent += ' <li><h3>编辑节点:</h3>刚插入的子节点和同级节点会进入编辑模式;其他节点双击也能进入编辑模式;编辑模式下可以编辑节点的文本</li>';
helpContent += ' <li><h3>设置节点样式:</h3>你可以选中一个或多个节点后,在工具栏中改变选中节点的样式。也可以使用快捷键来使用这些功能:撤销(Ctrl+Z)、重做(Ctrl+Y)、加粗(Ctrl+B)、斜体(Ctrl+I)</li>';
helpContent += ' <li><h3>编辑节点:</h3>选中节点直接输入文字、双击节点或选中节点按F2键均可进入编辑模式</li>';
helpContent += ' <li><h3>设置节点文本格式:</h3>你可以选中一个或多个节点后,在工具栏中改变选中节点的文本格式。也可以使用快捷键来使用这些功能:撤销(Ctrl+Z)、重做(Ctrl+Y)、加粗(Ctrl+B)、斜体(Ctrl+I)</li>';
helpContent += ' <li><h3>添加标签:</h3>选中节点,点击工具栏上的‘添加标签’按钮可以为节点添加/删除标签</li>';
helpContent += ' <li><h3>添加/删除超链接:</h3>选中节点,点击工具栏上的‘添加超链接’/‘删除超链接’按钮可以为节点添加、删除超链接</li>';
helpContent += '</ul>';
helpContent += '<h2>导入导出</h2>';
......@@ -36,6 +38,7 @@
helpContent += ' <li><h3>视野拖动:</h3>根节点未被选中的情况下,拖动根节点可以拖动视野;或者使用空格键切换拖动状态</li>';
helpContent += ' <li><h3>视野缩放:</h3>点击工具栏中的“放大”和“缩小”按钮可以缩放视野,或者按着 Ctrl 键使用滚轮缩放</li>';
helpContent += ' <li><h3>视野复位:</h3>双击空白处,可以将视野复位</li>';
helpContent += ' <li><h3>展开/收起节点:</h3>选中单个节点,点击工具栏中的“展开节点”和“收起节点”按钮可以展开/收起节点下的全部子节点</li>';
helpContent += '</ul>';
helpContent += '</div>';
......
( function () {
( function (utils) {
//todo 这里先写死成中文
var content = '<div class="hyperlink-content" style="padding:20px;width:360px;">';
content += '<p><label>输入链接: <input id="hyperlink_href" style="width:90%;" /></label></p>';
content += '<p style="text-align:right"><button id="hyperlink_insert">插入</button></p>';
content += '<style>';
content += '.kmui-dialog-<%= container %> input{';
content += 'width: 75%;';
content += 'padding: 6px 12px;';
content += 'font-size: 14px;';
content += 'line-height: 1.42857143;';
content += 'color: #555;';
content += 'background-color: #fff;';
content += 'background-image: none;';
content += 'border: 1px solid #ccc;';
content += 'border-radius: 4px; -webkit-box-shadow: inset 0 1px 1px rgba( 0, 0, 0, .075 );'
content += 'box-shadow: inset 0 1px 1px rgba( 0, 0, 0, .075 ); -webkit-transition: border-color ease-in-out .15s,';
content += 'box-shadow ease-in-out .15s;';
content += 'transition: border-color ease-in-out .15s,';
content += 'box-shadow ease-in-out .15s;';
content += '}';
content += '.kmui-dialog-<%= container %> input:focus{';
content += 'border-color: #66afe9;';
content += 'outline: 0;';
content += '-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);';
content += 'box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);';
content += '}';
content += '.kmui-dialog-<%= container %> button{';
content += 'height:34px;';
content += 'line-height:34px;';
content += 'vertical-align:1px';
content += '}';
content += '</style>';
content += '<input id="hyperlink_href"/>';
content += '<button id="hyperlink_insert">插入</button>';
content += '</div>';
KM.registerWidget( 'hyperlink', {
tpl: content,
initContent: function ( km ) {
var lang = km.getLang( 'dialogs.hyperlink' ),
html;
if ( lang ) {
html = $.parseTmpl( this.tpl, lang );
html = $.parseTmpl( this.tpl, utils.extend( {
'container': 'hyperlink'
}, lang ) );
}
this.root().html( html );
},
initEvent: function ( km, $w ) {
$w.find('#hyperlink_insert').on('click',function(){
km.execCommand('hyperlink',$w.find('#hyperlink_href').val());
$w.find( '#hyperlink_insert' ).on( 'click', function () {
km.execCommand( 'hyperlink', $w.find( '#hyperlink_href' ).val() );
$w.kmui().hide();
});
var url = km.queryCommandValue('hyperlink');
var $input = $w.find('#hyperlink_href');
$input.val(url || 'http://');
setTimeout(function(){
} );
var url = km.queryCommandValue( 'hyperlink' );
var $input = $w.find( '#hyperlink_href' );
$input.val( url || 'http://' );
setTimeout( function () {
$input.focus()
})
} )
},
width: 400
} );
} )();
\ No newline at end of file
} )(KM.Utils);
\ No newline at end of file
( function () {
( function (utils) {
KM.registerWidget( 'markers', {
tpl:"<style>"+
".kmui-dialog-<%= container %> .priority .icon{background:url(dialogs/markers/images/iconpriority.png) 0 0}"+
......@@ -53,4 +53,4 @@
width: 200
} )
} )();
\ No newline at end of file
} )(KM.Utils);
\ No newline at end of file
......@@ -2,27 +2,31 @@
<html>
<head>
<meta charset="utf-8">
<meta name="title" content="百度脑图">
<meta name="keyword" content="脑图,kity,svg,minder,百度,fex,前端,在线">
<meta name="description" content="百度脑图,便捷的脑图编辑工具。让您在线上直接创建、保存并分享你的思路。">
<script src="lib/jquery-2.1.0.min.js" charset="utf-8"></script>
<script src="lib/ZeroClipboard.min.js" charset="utf-8"></script>
<script src="lib/jquery-2.1.0.min.js?_=1399572740859" charset="utf-8"></script>
<script src="lib/ZeroClipboard.min.js?_=1399572740859" charset="utf-8"></script>
<script type="text/javascript">
ZeroClipboard.setDefaults( { moviePath: 'lib/ZeroClipboard.swf' } );
</script>
<script src="lib/kitygraph.all.min.js" charset="utf-8"></script>
<script src="import.js" charset="utf-8"></script>
<script src="kityminder.config.js" charset="utf-8"></script>
<script src="lang/zh-cn/zh-cn.js" charset="utf-8"></script>
<script src="lib/kitygraph.all.min.js?_=1399572740859" charset="utf-8"></script>
<script src="kityminder.all.min.js?_=1399572740859" charset="utf-8"></script>
<script src="kityminder.config.js?_=1399572740859" charset="utf-8"></script>
<script src="lang/zh-cn/zh-cn.js?_=1399572740859" charset="utf-8"></script>
<script src="lib/zip.js" charset="utf-8"></script>
<script src="lib/zip.js?_=1399572740859" charset="utf-8"></script>
<script>
zip.inflateJSPath = 'lib/inflate.js';
</script>
<script src="lib/jquery.xml2json.js" charset="utf-8"></script>
<script src="lib/baidu-frontia-js-full-1.0.0.js" charset="utf-8"></script>
<script src="social/draftmanager.js" charset="utf-8"></script>
<script src="social/social.js" charset="utf-8"></script>
<script src="lib/jquery.xml2json.js?_=1399572740859" charset="utf-8"></script>
<script src="lib/baidu-frontia-js-full-1.0.0.js?_=1399572740859" charset="utf-8"></script>
<script src="social/draftmanager.js?_=1399572740859" charset="utf-8"></script>
<script src="social/social.js?_=1399572740859" charset="utf-8"></script>
<link href="social/social.css" rel="stylesheet">
<link href="themes/default/css/import.css" type="text/css" rel="stylesheet" />
......@@ -48,10 +52,38 @@
</p>
</div>
<p id="about">
KityMinder <a id="km-version" href="https://github.com/fex-team/kityminder/blob/dev/CHANGELOG.md" target="blank"></a>, Powered by f-cube, <a href="http://fex.baidu.com" target="_blank">FEX</a> |
<a href="https://github.com/fex-team/kityminder.git" target="_blank">Source</a>
<a href="https://github.com/fex-team/kityminder/issues/new" target="_blank">Bug</a> |
<a href="mailto:kity@baidu.com" target="_blank">Contact Us</a>
</p>
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdMini":"2","bdMiniList":[],"bdPic":"","bdStyle":"1","bdSize":"32"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
</body>
<script>
// create km instance
window.km = KM.getKityMinder('kityminder');
// New Version Notify
$(function() {
var lastVersion = localStorage.lastKMVersion;
$('#km-version').text( 'v' + KM.version );
if( lastVersion != KM.version ) {
$( '#km-version' ).addClass( 'new-version' );
localStorage.lastKMVersion = KM.version;
}
});
</script>
<!--Baidu Tongji Code-->
<script type="text/javascript">
if (document.domain == 'naotu.baidu.com') {
var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F0703917f224067c887f3664479a03887' type='text/javascript'%3E%3C/script%3E"));
}
</script>
</html>
\ No newline at end of file
/*!
* ====================================================
* kityminder - v1.0.0 - 2014-05-08
* kityminder - v1.0.0 - 2014-05-09
* https://github.com/fex-team/kityminder
* GitHub: https://github.com/fex-team/kityminder.git
* Copyright (c) 2014 f-cube @ FEX; Licensed MIT
......@@ -313,6 +313,21 @@ 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) {
if (b) {
return a;
} else {
return {
'<':'&lt;',
'&':'&amp;',
'"':'&quot;',
'>':'&gt;',
"'":'&#39;'
}[a]
}
}) : '';
}
};
......@@ -1130,7 +1145,7 @@ kity.extendClass( Minder, {
return d;
}
var t1 = ts( new Date(), '开始解析' );
//var t1 = ts( new Date(), '开始解析' );
//*******************
json = params.json || ( params.json = protocal.decode( local ) );
......@@ -1139,20 +1154,20 @@ kity.extendClass( Minder, {
var self = this;
json.then( local, function ( data ) {
//*******************
var t2 = ts( new Date(), '解压解析耗时', t1 );
//var t2 = ts( new Date(), '解压解析耗时', t1 );
//*******************
self._afterImportData( data, params );
//*******************
ts( new Date(), '渲染耗时', t2 );
//ts( new Date(), '渲染耗时', t2 );
//*******************
} );
} else {
//*******************
var t2 = ts( new Date(), '解压解析耗时', t1 );
//var t2 = ts( new Date(), '解压解析耗时', t1 );
//*******************
this._afterImportData( json, params );
//*******************
ts( new Date(), '渲染耗时', t2 );
//ts( new Date(), '渲染耗时', t2 );
//*******************
}
return this;
......@@ -1471,6 +1486,14 @@ kity.extendClass( Minder, {
this._hasEnterExecCommand = false;
} else {
result = cmd.execute.apply( cmd, [ me ].concat( cmdArgs ) );
if(!this._hasEnterExecCommand){
if ( cmd.isSelectionChanged() ) {
this._firePharse( new MinderEvent( 'selectionchange' ) );
}
this._firePharse( new MinderEvent( 'interactchange' ) );
}
}
return result === undefined ? null : result;
......@@ -2584,7 +2607,7 @@ KityMinder.registerModule( "LayoutModule", function () {
return null;
}
km.select( selectedNode, true );
km.textEditNode(selectedNode);
km.textEditNode( selectedNode );
},
queryState: function ( km ) {
var selectedNode = km.getSelectedNode();
......@@ -2618,6 +2641,7 @@ KityMinder.registerModule( "LayoutModule", function () {
var ico = e.kityEvent.targetShape && e.kityEvent.targetShape.container;
if ( ico && ico.class === "shicon" ) {
this.expandNode( ico );
this.fire( 'contentchange' );
}
},
"resize": function ( e ) {
......@@ -3377,6 +3401,7 @@ KityMinder.registerModule( "LayoutDefault", function () {
if ( focus ) {
showNodeInView( node );
}
parent.expand();
var shicon = parent.getLayout().shicon;
if ( shicon ) shicon.switchState( true );
},
......@@ -4158,21 +4183,21 @@ var ViewDragger = kity.createClass( "ViewDragger", {
lastPosition = null,
currentPosition = null;
this._minder.on( 'normal.beforemousedown readonly.beforemousedown readonly.beforetouchstart', function ( e ) {
this._minder.on( 'normal.mousedown readonly.mousedown readonly.touchstart', function ( e ) {
// 点击未选中的根节点临时开启
if ( e.getTargetNode() == this.getRoot() &&
( !this.getRoot().isSelected() || !this.isSingleSelect() ) ) {
lastPosition = e.getPosition();
dragger.setEnabled( true );
isRootDrag = true;
e.originEvent.preventDefault();
var me = this;
setTimeout( function () {
me.setStatus( 'hand' );
}, 1 );
}
} )
.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' );
})
.on( 'hand.beforemousedown hand.beforetouchend', function ( e ) {
// 已经被用户打开拖放模式
if ( dragger.isEnabled() ) {
......@@ -4195,7 +4220,7 @@ var ViewDragger = kity.createClass( "ViewDragger", {
}
} )
.on( 'hand.mouseup', function ( e ) {
.on( 'mouseup', function ( e ) {
lastPosition = null;
// 临时拖动需要还原状态
......@@ -4228,7 +4253,7 @@ KityMinder.registerModule( 'View', function () {
queryState: function ( minder ) {
return minder._viewDragger.isEnabled() ? 1 : 0;
},
enableReadOnly : false
enableReadOnly: false
} );
var CameraCommand = kity.createClass( "CameraCommand", {
......@@ -4241,7 +4266,7 @@ KityMinder.registerModule( 'View', function () {
km.getRenderContainer().fxTranslate( dx, dy, 1000, "easeOutQuint" );
this.setContentChanged( false );
},
enableReadOnly : false
enableReadOnly: false
} );
return {
......@@ -4284,10 +4309,11 @@ KityMinder.registerModule( 'View', function () {
e.preventDefault();
},
'normal.dblclick readonly.dblclick': function ( e ) {
if ( e.getTargetNode() ) return;
if ( e.kityEvent.targetShape instanceof kity.Paper ) {
this.execCommand( 'camera', this.getRoot() );
}
}
}
};
} );
......@@ -4311,14 +4337,17 @@ var MoveToParentCommand = kity.createClass( 'MoveToParentCommand', {
base: Command,
execute: function ( minder, nodes, parent ) {
var node;
if ( ( !parent.isExpanded() ) && ( parent.getChildren().length > 0 ) && ( parent.getType() !== 'root' ) ) {
minder.expandNode( parent );
}
for ( var i = nodes.length - 1; i >= 0; i-- ) {
node = nodes[ i ];
if ( node.getParent() ) {
minder.removeNode( [ node ] );
if ( !parent.isExpanded() && parent.getChildren().length > 0 && parent.getType() !== 'root' ) {
minder.expandNode( parent );
}
minder.appendChildNode( parent, node );
if ( node.isExpanded() && node.getChildren().length !== 0 ) {
minder.expandNode( node );
}
}
}
minder.select( nodes, true );
......@@ -5395,7 +5424,7 @@ Minder.Receiver = kity.createClass( 'Receiver', {
textShape = new kity.Text();
}
this.textShape = textShape;
this.container.innerHTML = textShape.getContent();
this.container.innerHTML = utils.unhtml(textShape.getContent());
return this;
},
setTextShapeSize: function ( size ) {
......@@ -5439,9 +5468,7 @@ Minder.Receiver = kity.createClass( 'Receiver', {
me.setContainerStyle();
me.minderNode.setText( text );
if ( text.length == 0 ) {
me.minderNode.setText( 'a' );
}
me.km.updateLayout( me.minderNode );
......@@ -5491,7 +5518,7 @@ Minder.Receiver = kity.createClass( 'Receiver', {
setTimeout( function () {
me.range.updateNativeRange().insertNode( $( '<span>$$_kityminder_bookmark_$$</span>' )[ 0 ] );
me.container.innerHTML = me.container.textContent.replace( /[\u200b\t\r\n]/g, '' );
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();
......@@ -6064,72 +6091,88 @@ KityMinder.registerModule( "fontmodule", function () {
} );
KityMinder.registerModule( 'Zoom', function () {
var MAX_ZOOM = 2,
MIN_ZOOM = kity.Browser.chrome ? 1 : 0.5,
ZOOM_STEP = Math.sqrt( 2 );
var me = this;
function zoom( minder, rate ) {
var timeline;
me.setOptions( 'zoom', [ 50, 80, 100, 120, 150, 200 ] );
function zoomMinder( minder, zoom ) {
var paper = minder.getPaper();
var viewbox = paper.getViewBox();
var zoomValue = minder._zoomValue;
var w = viewbox.width,
h = viewbox.height,
x = viewbox.x,
y = viewbox.y;
var ww = w * rate,
hh = h * rate,
xx = x + ( w - ww ) / 2,
yy = y + ( h - hh ) / 2;
var viewport = paper.getViewPort();
if ( !zoom ) return;
var animator = new kity.Animator( {
beginValue: viewbox,
finishValue: {
width: ww,
height: hh,
x: xx,
y: yy
},
beginValue: viewport.zoom,
finishValue: zoom / 100,
setter: function ( target, value ) {
target.setViewBox( value.x, value.y, value.width, value.height );
viewport.zoom = value;
target.setViewPort( viewport );
}
} );
minder.zoom = zoom;
if ( timeline ) {
timeline.pause();
}
timeline = animator.start( paper, 500, 'ease' );
}
animator.start( paper, 500, 'ease' );
minder._zoomValue = zoomValue *= rate;
var ZoomCommand = kity.createClass( 'Zoom', {
base: Command,
execute: zoomMinder,
queryValue: function ( minder ) {
return minder.zoom;
}
} );
var ZoomInCommand = kity.createClass( 'ZoomInCommand', {
base: Command,
execute: function ( minder ) {
if ( !this.queryState( minder ) ) {
zoom( minder, 1 / ZOOM_STEP );
}
zoomMinder( minder, this.nextValue( minder ) );
},
queryState: function ( minder ) {
return ( minder._zoomValue > 1 / MAX_ZOOM ) ? 0 : -1;
return ~this.nextValue( minder );
},
nextValue: function ( minder ) {
var stack = minder.getOptions( 'zoom' ),
i;
for ( i = 0; i < stack.length; i++ ) {
if ( stack[ i ] > minder.zoom ) return stack[ i ];
}
return 0;
},
enableReadOnly : false
enableReadOnly: false
} );
var ZoomOutCommand = kity.createClass( 'ZoomOutCommand', {
base: Command,
execute: function ( minder ) {
if ( !this.queryState( minder ) ) {
zoom( minder, ZOOM_STEP );
}
zoomMinder( minder, this.nextValue( minder ) );
},
queryState: function ( minder ) {
return ( minder._zoomValue < 1 / MIN_ZOOM ) ? 0 : -1;
return ~this.nextValue( minder );
},
nextValue: function ( minder ) {
var stack = minder.getOptions( 'zoom' ),
i;
for ( i = stack.length - 1; i >= 0; i-- ) {
if ( stack[ i ] < minder.zoom ) return stack[ i ];
}
return 0;
},
enableReadOnly : false
enableReadOnly: false
} );
return {
init: function () {
this.zoom = 100;
},
commands: {
'zoom-in': ZoomInCommand,
'zoom-out': ZoomOutCommand
'zoom-out': ZoomOutCommand,
'zoom': ZoomCommand
},
events: {
'normal.keydown': function ( e ) {
var me = this;
......@@ -6282,6 +6325,7 @@ KityMinder.registerModule( "hyperlink", function () {
} );
KityMinder.registerModule( "Expand", function () {
var minder = this;
var EXPAND_STATE_DATA = 'expandState',
STATE_EXPAND = 'expand',
STATE_COLLAPSE = 'collapse';
......@@ -6294,27 +6338,71 @@ KityMinder.registerModule( "Expand", function () {
_buffer.shift();
}
}
//获取选中的最上层节点
var filterDuplicate = function ( nodes ) {
var _buffer = ( [] ).concat( nodes );
var resultSet = [];
for ( var i = 0; i < _buffer.length; i++ ) {
var parent = _buffer[ i ].getParent();
if ( !parent ) {
resultSet = [ _buffer[ i ] ];
break;
} else {
//筛选
while ( parent ) {
if ( _buffer.indexOf( parent ) !== -1 ) {
_buffer[ i ] = null;
break;
}
parent = parent.getParent();
}
if ( _buffer[ i ] ) resultSet.push( _buffer[ i ] );
}
}
return resultSet;
}
// var getCommonParents = function ( nodes ) {
// var _buffer = [];
// var resultSet = [];
// for ( var i = 0; i < nodes.length; i++ ) {
// _buffer.push( nodes[ i ] );
// }
// while ( _buffer.length !== 0 ) {
// var parent = _buffer[ 0 ].getParent();
// if ( parent.getType() === 'root' || _buffer.length === 1 ) {
// resultSet.push( _buffer[ 0 ] );
// } else {
// if ( _buffer.indexOf( parent ) === -1 ) {
// _buffer.push( parent );
// }
// }
// _buffer.shift();
// }
// return resultSet;
// }
var expandAll = function ( km, deal ) {
var selectedNodes = km.getSelectedNodes();
var topNodes = filterDuplicate( selectedNodes );
if ( selectedNodes.length === 0 || selectedNodes[ 0 ].getType() === 'root' || topNodes[ 0 ].getType() === 'root' ) {
layerTravel( km.getRoot(), function ( n ) {
if ( deal === 'expand' ) n.expand();
else n.collapse();
} );
km.initStyle();
} else {
for ( var i = 0; i < topNodes.length; i++ ) {
var node = topNodes[ i ];
var children = node.getChildren();
if ( children.length === 0 ) {
continue;
} else {
layerTravel( node, function ( n ) {
if ( n !== node ) {
if ( deal === 'expand' ) n.expand();
else n.collapse();
}
} );
var judge_val;
if ( deal === 'expand' ) {
judge_val = !node.isExpanded();
} else {
judge_val = node.isExpanded();
}
if ( judge_val ) {
km.expandNode( node );
} else {
km.expandNode( node );
km.expandNode( node );
}
}
}
}
for ( var j = 0; j < selectedNodes.length; j++ ) {
km.highlightNode( selectedNodes[ j ] );
}
}
// var setOptionValue = function ( root, layer, sub ) {
// var cur_layer = 1;
......@@ -6429,28 +6517,7 @@ KityMinder.registerModule( "Expand", function () {
return {
base: Command,
execute: function ( km ) {
var selectedNodes = km.getSelectedNodes();
if ( selectedNodes.length === 0 || selectedNodes[ 0 ].getType() === 'root' ) {
layerTravel( km.getRoot(), function ( n ) {
n.expand();
} );
km.initStyle();
} else {
var selectedNode = km.getSelectedNode();
var children = selectedNode.getChildren();
if ( children.length === 0 ) {
return false;
}
layerTravel( selectedNode, function ( n ) {
if ( n !== selectedNode ) n.expand();
} );
if ( !selectedNode.isExpanded() ) {
km.expandNode( selectedNode );
} else {
km.expandNode( selectedNode );
km.expandNode( selectedNode );
}
}
expandAll( km, 'expand' );
},
queryState: function ( km ) {
return 0;
......@@ -6461,30 +6528,11 @@ KityMinder.registerModule( "Expand", function () {
return {
base: Command,
execute: function ( km ) {
var selectedNodes = km.getSelectedNodes();
if ( selectedNodes.length === 0 || selectedNodes[ 0 ].getType() === 'root' ) {
layerTravel( km.getRoot(), function ( n ) {
n.collapse();
} );
km.initStyle();
} else {
var selectedNode = km.getSelectedNode();
var children = selectedNode.getChildren();
if ( children.length === 0 ) {
return false;
}
if ( selectedNode.isExpanded() ) {
layerTravel( selectedNode, function ( n ) {
if ( n !== selectedNode ) n.collapse();
} );
km.expandNode( selectedNode );
}
}
expandAll( km, 'collapse' );
},
queryState: function ( km ) {
return 0;
}
};
} )() );
return {
......@@ -7929,7 +7977,7 @@ KM.ui.define( 'modal', {
if ( !$obj.data( '$mergeObj' ) ) {
$obj.data( '$mergeObj', me.root() );
$obj.on( 'click', function () {
$obj.on( 'wrapclick', function () {
me.toggle( $obj )
} );
me.data( '$mergeObj', $obj )
......@@ -8911,6 +8959,22 @@ KM.registerToolbarUI( 'hyperlink', function ( name ) {
} );
me.addContextmenu( [ {
label: me.getLang( 'hyperlink.hyperlink' ),
exec: function (url) {
$dialog.kmui().show();
this.execCommand( 'hyperlink', url )
},
cmdName: 'hyperlink'
},{
label: me.getLang( 'hyperlink.unhyperlink' ),
exec: function (url) {
this.execCommand( 'unhyperlink' )
},
cmdName: 'hyperlink'
}
]);
me.on( 'interactchange', function () {
var state = this.queryCommandState( name );
$btn.kmui().disabled( state == -1 ).active( state == 1 )
......@@ -8918,6 +8982,72 @@ KM.registerToolbarUI( 'hyperlink', function ( name ) {
return $btn;
} );
KM.registerToolbarUI( 'zoom', function ( name ) {
var me = this,
label = me.getLang( 'tooltips.' + name ),
options = {
label: label,
title: label,
comboboxName: name,
items: me.getOptions( name ) || [],
itemStyles: [],
value: me.getOptions( name ),
autowidthitem: [],
enabledRecord: false
},
$combox = null;
if ( options.items.length == 0 ) {
return null;
}
//实例化
$combox = $.kmuibuttoncombobox( transForInserttopic( options ) ).css( 'zIndex', me.getOptions( 'zIndex' ) + 1 );
var comboboxWidget = $combox.kmui();
comboboxWidget.on( 'comboboxselect', function ( evt, res ) {
me.execCommand('zoom', res.value );
} ).on( "beforeshow", function () {
if ( $combox.parent().length === 0 ) {
$combox.appendTo( me.$container.find( '.kmui-dialog-container' ) );
}
} );
//状态反射
me.on( 'interactchange', function () {
var state = this.queryCommandState( name ),
value = this.queryCommandValue( name );
//设置按钮状态
comboboxWidget.button().kmui().disabled( state == -1 ).active( state == 1 );
if ( value ) {
//设置label
comboboxWidget.selectItemByLabel( value + '%' );
}
} );
//comboboxWidget.button().kmui().disabled(-1);
return comboboxWidget.button().addClass( 'kmui-combobox' );
function transForInserttopic( options ) {
var tempItems = [];
utils.each( options.items, function ( k, v ) {
options.value.push( v );
tempItems.push( v + '%' );
options.autowidthitem.push( $.wordCountAdaptive( tempItems[ tempItems.length - 1 ] ) );
} );
options.items = tempItems;
return options;
}
} );
/*
http://www.xmind.net/developer/
......
This source diff could not be displayed because it is too large. You can view the blob instead.
( function () {
function getKMBasePath( docUrl, confUrl ) {
return getBasePath( docUrl || self.document.URL || self.location.href, confUrl || getConfigFilePath() );
}
function getConfigFilePath() {
var configPath = document.getElementsByTagName( 'script' );
return configPath[ configPath.length - 1 ].src;
}
function getBasePath( docUrl, confUrl ) {
var basePath = confUrl;
if ( /^(\/|\\\\)/.test( confUrl ) ) {
basePath = /^.+?\w(\/|\\\\)/.exec( docUrl )[ 0 ] + confUrl.replace( /^(\/|\\\\)/, '' );
} else if ( !/^[a-z]+:/i.test( confUrl ) ) {
docUrl = docUrl.split( "#" )[ 0 ].split( "?" )[ 0 ].replace( /[^\\\/]+$/, '' );
basePath = docUrl + "" + confUrl;
}
return optimizationPath( basePath );
}
function optimizationPath( path ) {
var protocol = /^[a-z]+:\/\//.exec( path )[ 0 ],
tmp = null,
res = [];
path = path.replace( protocol, "" ).split( "?" )[ 0 ].split( "#" )[ 0 ];
path = path.replace( /\\/g, '/' ).split( /\// );
path[ path.length - 1 ] = "";
while ( path.length ) {
if ( ( tmp = path.shift() ) === ".." ) {
res.pop();
} else if ( tmp !== "." ) {
res.push( tmp );
}
}
return protocol + res.join( "/" );
}
window.KITYMINDER_CONFIG = {
'KITYMINDER_HOME_URL': getKMBasePath(),
//定义工具栏
toolbars: [
'hand | zoom-in zoom zoom-out | collapsenode expandnode | undo redo | bold italic | fontfamily fontsize forecolor | saveto | hyperlink unhyperlink | markers | node | help'
]
//只读模式,默认是false
//readOnly: true
//设置主题
//,defaultlayoutstyle : 'default' //设置默认的主题
//,layoutstyle : [] //添加有那些主图
//回退相关选项
//,maxUndoCount:20 //最大可回退的次数,默认20
//语言默认是zh-cn
//,lang:'zh-cn'
//设置km整体的z-index大小
//,zIndex : 1000
//设置初始加载时展开的层数和子节点数目阈值
//默认是全部展开,0表示全部展开
// ,
// defaultExpand: {
// defaultLayer: 2,
// defaultSubShow: 5
// }
//配置放大缩小的比例
//,zoom:[50,80,100,120,150,200]
};
} )();
\ No newline at end of file
......@@ -13,16 +13,15 @@ KityMinder.LANG[ 'zh-cn' ] = {
'node': '节点操作',
'saveto': '导出',
'hand': '允许拖拽',
'zoom-in': '放大',
'zoom-out': '缩小',
'zoom': '放大缩小',
'markers': '添加标签',
'switchlayout': '切换主题',
'help': '帮助',
'preference': '偏好设置',
'hyperlink':'插入链接',
'unhyperlink':"删除链接",
'expandnode':"展开节点",
'collapsenode':"闭合节点"
'hyperlink': '插入链接',
'unhyperlink': "删除链接",
'expandnode': "展开节点",
'collapsenode': "收起节点"
},
'popupcolor': {
'clearColor': '清空颜色',
......@@ -49,7 +48,7 @@ KityMinder.LANG[ 'zh-cn' ] = {
'help': {
},
hyperlink:{}
hyperlink: {}
},
'node': {
'appendsiblingnode': '插入同级节点',
......@@ -60,6 +59,10 @@ KityMinder.LANG[ 'zh-cn' ] = {
'layout': {
'default': '左右展开',
'bottom': '向下展开'
},
'hyperlink':{
'hyperlink':'插入超链接',
'unhyperlink':"取消超链接"
}
};
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -41,6 +41,9 @@ html, body, #kityminder, div.kmui-editor-body {
/*line-height: 0;*/
overflow: hidden;
}
svg {
font-family: Arial, "Microsoft Yahei","Heiti SC",sans-serif;
svg, body {
font-family: Arial, "Microsoft Yahei", "Heiti SC", sans-serif;
}
#about{position:absolute;bottom:10px;right:10px;height:24px;line-height:24px;color:#888;font-family:Arial;font-size:13px;font-weight:normal;margin:0;text-shadow:0 1px 1px #000}#about a{color:#888}#about a:hover{color:#fff}
#km-version.new-version{position:relative;padding-right:30px}
#km-version.new-version:after{content:'NEW';color:#ff0;position:absolute;top:-10px;right:-5px;display:block;background:#f00;padding:0 5px;border-radius:4px;text-shadow:none;box-shadow:-1px 1px 3px rgba(0,0,0,0.3);-webkit-transform:scale(.6);-moz-transform:scale(.6);-ms-transform:scale(.6);transform:scale(.6)}
......@@ -2,6 +2,10 @@
<html>
<head>
<meta charset="utf-8">
<meta name="title" content="百度脑图">
<meta name="keyword" content="脑图,kity,svg,minder,百度,fex,前端,在线">
<meta name="description" content="百度脑图,便捷的脑图编辑工具。让您在线上直接创建、保存并分享你的思路。">
<script src="lib/jquery-2.1.0.min.js" charset="utf-8"></script>
<script src="lib/ZeroClipboard.min.js" charset="utf-8"></script>
......@@ -48,10 +52,38 @@
</p>
</div>
<p id="about">
KityMinder <a id="km-version" href="https://github.com/fex-team/kityminder/blob/dev/CHANGELOG.md" target="blank"></a>, Powered by f-cube, <a href="http://fex.baidu.com" target="_blank">FEX</a> |
<a href="https://github.com/fex-team/kityminder.git" target="_blank">Source</a>
<a href="https://github.com/fex-team/kityminder/issues/new" target="_blank">Bug</a> |
<a href="mailto:kity@baidu.com" target="_blank">Contact Us</a>
</p>
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdMini":"2","bdMiniList":[],"bdPic":"","bdStyle":"1","bdSize":"32"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
</body>
<script>
// create km instance
window.km = KM.getKityMinder('kityminder');
// New Version Notify
$(function() {
var lastVersion = localStorage.lastKMVersion;
$('#km-version').text( 'v' + KM.version );
if( lastVersion != KM.version ) {
$( '#km-version' ).addClass( 'new-version' );
localStorage.lastKMVersion = KM.version;
}
});
</script>
<!--Baidu Tongji Code-->
<script type="text/javascript">
if (document.domain == 'naotu.baidu.com') {
var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F0703917f224067c887f3664479a03887' type='text/javascript'%3E%3C/script%3E"));
}
</script>
</html>
\ No newline at end of file
......@@ -66,6 +66,14 @@ kity.extendClass( Minder, {
this._hasEnterExecCommand = false;
} else {
result = cmd.execute.apply( cmd, [ me ].concat( cmdArgs ) );
if(!this._hasEnterExecCommand){
if ( cmd.isSelectionChanged() ) {
this._firePharse( new MinderEvent( 'selectionchange' ) );
}
this._firePharse( new MinderEvent( 'interactchange' ) );
}
}
return result === undefined ? null : result;
......
......@@ -41,6 +41,9 @@ html, body, #kityminder, div.kmui-editor-body {
/*line-height: 0;*/
overflow: hidden;
}
svg {
font-family: Arial, "Microsoft Yahei","Heiti SC",sans-serif;
svg, body {
font-family: Arial, "Microsoft Yahei", "Heiti SC", sans-serif;
}
#about{position:absolute;bottom:10px;right:10px;height:24px;line-height:24px;color:#888;font-family:Arial;font-size:13px;font-weight:normal;margin:0;text-shadow:0 1px 1px #000}#about a{color:#888}#about a:hover{color:#fff}
#km-version.new-version{position:relative;padding-right:30px}
#km-version.new-version:after{content:'NEW';color:#ff0;position:absolute;top:-10px;right:-5px;display:block;background:#f00;padding:0 5px;border-radius:4px;text-shadow:none;box-shadow:-1px 1px 3px rgba(0,0,0,0.3);-webkit-transform:scale(.6);-moz-transform:scale(.6);-ms-transform:scale(.6);transform:scale(.6)}
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