Commit 10aca4ef authored by techird's avatar techird

merge from dev

parents da324edd 4aacef51
...@@ -65,6 +65,9 @@ $dependency = Array( ...@@ -65,6 +65,9 @@ $dependency = Array(
,'src/adapter/node.js' ,'src/adapter/node.js'
,'src/adapter/contextmenu.js' ,'src/adapter/contextmenu.js'
,'src/adapter/dialog.js' ,'src/adapter/dialog.js'
,'src/protocal/xmind.js'
,'src/protocal/freemind.js'
,'src/protocal/mindmanager.js'
,'src/protocal/plain.js' ,'src/protocal/plain.js'
,'src/protocal/json.js' ,'src/protocal/json.js'
,'src/protocal/png.js' ,'src/protocal/png.js'
......
...@@ -4,12 +4,18 @@ ...@@ -4,12 +4,18 @@
<meta charset="utf-8"> <meta charset="utf-8">
<script src="../lib/jquery-2.1.0.min.js" charset="utf-8"></script> <script src="../lib/jquery-2.1.0.min.js" charset="utf-8"></script>
<script src="../lib/ZeroClipboard.min.js" charset="utf-8"></script>
<script type="text/javascript">
ZeroClipboard.setDefaults( { moviePath: '../lib/ZeroClipboard.swf' } );
</script>
<script src="../kity/dist/kitygraph.all.js" charset="utf-8"></script> <script src="../kity/dist/kitygraph.all.js" charset="utf-8"></script>
<script src="../dev/import.php" charset="utf-8"></script> <script src="../dev/import.php" charset="utf-8"></script>
<script src="../kityminder.config.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="../lang/zh-cn/zh-cn.js" charset="utf-8"></script>
<script src="../lib/zip.js" charset="utf-8"></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="../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/draftmanager.js" charset="utf-8"></script>
<script src="../social/social.js" charset="utf-8"></script> <script src="../social/social.js" charset="utf-8"></script>
...@@ -25,7 +31,8 @@ ...@@ -25,7 +31,8 @@
<div id="share-dialog" > <div id="share-dialog" >
<h3>URL分享:</h3> <h3>URL分享:</h3>
<p> <p>
<input id="share-url" type="url" value="" /> <input id="share-url" type="url" value="http://naotu.baidu.com/?shareId=kcev3dd" />
<button id="copy-share-url" data-clipboard-target="share-url" type="button">复制</button>
</p> </p>
<h3>社交分享:</h3> <h3>社交分享:</h3>
<p id="share-platform" class="bdsharebuttonbox"> <p id="share-platform" class="bdsharebuttonbox">
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
<h3>URL分享:</h3> <h3>URL分享:</h3>
<p> <p>
<input id="share-url" type="url" value="" /> <input id="share-url" type="url" value="" />
<button id="copy-share-url" type="button">复制</button>
</p> </p>
<h3>社交分享:</h3> <h3>社交分享:</h3>
<p id="share-platform" class="bdsharebuttonbox"> <p id="share-platform" class="bdsharebuttonbox">
......
/*!
* ZeroClipboard
* The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.
* Copyright (c) 2013 Jon Rohan, James M. Greene
* Licensed MIT
* http://zeroclipboard.org/
* v1.2.3
*/
!function(){"use strict";var a,b=function(){var a=/\-([a-z])/g,b=function(a,b){return b.toUpperCase()};return function(c){return c.replace(a,b)}}(),c=function(a,c){var d,e,f,g,h,i;if(window.getComputedStyle?d=window.getComputedStyle(a,null).getPropertyValue(c):(e=b(c),d=a.currentStyle?a.currentStyle[e]:a.style[e]),"cursor"===c&&(!d||"auto"===d))for(f=a.tagName.toLowerCase(),g=["a"],h=0,i=g.length;i>h;h++)if(f===g[h])return"pointer";return d},d=function(a){if(p.prototype._singleton){a||(a=window.event);var b;this!==window?b=this:a.target?b=a.target:a.srcElement&&(b=a.srcElement),p.prototype._singleton.setCurrent(b)}},e=function(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,c)},f=function(a,b,c){a.removeEventListener?a.removeEventListener(b,c,!1):a.detachEvent&&a.detachEvent("on"+b,c)},g=function(a,b){if(a.addClass)return a.addClass(b),a;if(b&&"string"==typeof b){var c=(b||"").split(/\s+/);if(1===a.nodeType)if(a.className){for(var d=" "+a.className+" ",e=a.className,f=0,g=c.length;g>f;f++)d.indexOf(" "+c[f]+" ")<0&&(e+=" "+c[f]);a.className=e.replace(/^\s+|\s+$/g,"")}else a.className=b}return a},h=function(a,b){if(a.removeClass)return a.removeClass(b),a;if(b&&"string"==typeof b||void 0===b){var c=(b||"").split(/\s+/);if(1===a.nodeType&&a.className)if(b){for(var d=(" "+a.className+" ").replace(/[\n\t]/g," "),e=0,f=c.length;f>e;e++)d=d.replace(" "+c[e]+" "," ");a.className=d.replace(/^\s+|\s+$/g,"")}else a.className=""}return a},i=function(){var a,b,c,d=1;return"function"==typeof document.body.getBoundingClientRect&&(a=document.body.getBoundingClientRect(),b=a.right-a.left,c=document.body.offsetWidth,d=Math.round(100*(b/c))/100),d},j=function(a){var b={left:0,top:0,width:0,height:0,zIndex:999999999},d=c(a,"z-index");if(d&&"auto"!==d&&(b.zIndex=parseInt(d,10)),a.getBoundingClientRect){var e,f,g,h=a.getBoundingClientRect();"pageXOffset"in window&&"pageYOffset"in window?(e=window.pageXOffset,f=window.pageYOffset):(g=i(),e=Math.round(document.documentElement.scrollLeft/g),f=Math.round(document.documentElement.scrollTop/g));var j=document.documentElement.clientLeft||0,k=document.documentElement.clientTop||0;b.left=h.left+e-j,b.top=h.top+f-k,b.width="width"in h?h.width:h.right-h.left,b.height="height"in h?h.height:h.bottom-h.top}return b},k=function(a,b){var c=!(b&&b.useNoCache===!1);return c?(-1===a.indexOf("?")?"?":"&")+"nocache="+(new Date).getTime():""},l=function(a){var b=[],c=[];return a.trustedOrigins&&("string"==typeof a.trustedOrigins?c.push(a.trustedOrigins):"object"==typeof a.trustedOrigins&&"length"in a.trustedOrigins&&(c=c.concat(a.trustedOrigins))),a.trustedDomains&&("string"==typeof a.trustedDomains?c.push(a.trustedDomains):"object"==typeof a.trustedDomains&&"length"in a.trustedDomains&&(c=c.concat(a.trustedDomains))),c.length&&b.push("trustedOrigins="+encodeURIComponent(c.join(","))),"string"==typeof a.amdModuleId&&a.amdModuleId&&b.push("amdModuleId="+encodeURIComponent(a.amdModuleId)),"string"==typeof a.cjsModuleId&&a.cjsModuleId&&b.push("cjsModuleId="+encodeURIComponent(a.cjsModuleId)),b.join("&")},m=function(a,b){if(b.indexOf)return b.indexOf(a);for(var c=0,d=b.length;d>c;c++)if(b[c]===a)return c;return-1},n=function(a){if("string"==typeof a)throw new TypeError("ZeroClipboard doesn't accept query strings.");return a.length?a:[a]},o=function(a,b,c,d,e){e?window.setTimeout(function(){a.call(b,c,d)},0):a.call(b,c,d)},p=function(a,b){if(a&&(p.prototype._singleton||this).glue(a),p.prototype._singleton)return p.prototype._singleton;p.prototype._singleton=this,this.options={};for(var c in s)this.options[c]=s[c];for(var d in b)this.options[d]=b[d];this.handlers={},p.detectFlashSupport()&&v()},q=[];p.prototype.setCurrent=function(b){a=b,this.reposition();var d=b.getAttribute("title");d&&this.setTitle(d);var e=this.options.forceHandCursor===!0||"pointer"===c(b,"cursor");return r.call(this,e),this},p.prototype.setText=function(a){return a&&""!==a&&(this.options.text=a,this.ready()&&this.flashBridge.setText(a)),this},p.prototype.setTitle=function(a){return a&&""!==a&&this.htmlBridge.setAttribute("title",a),this},p.prototype.setSize=function(a,b){return this.ready()&&this.flashBridge.setSize(a,b),this},p.prototype.setHandCursor=function(a){return a="boolean"==typeof a?a:!!a,r.call(this,a),this.options.forceHandCursor=a,this};var r=function(a){this.ready()&&this.flashBridge.setHandCursor(a)};p.version="1.2.3";var s={moviePath:"ZeroClipboard.swf",trustedOrigins:null,text:null,hoverClass:"zeroclipboard-is-hover",activeClass:"zeroclipboard-is-active",allowScriptAccess:"sameDomain",useNoCache:!0,forceHandCursor:!1};p.setDefaults=function(a){for(var b in a)s[b]=a[b]},p.destroy=function(){p.prototype._singleton.unglue(q);var a=p.prototype._singleton.htmlBridge;a.parentNode.removeChild(a),delete p.prototype._singleton},p.detectFlashSupport=function(){var a=!1;if("function"==typeof ActiveXObject)try{new ActiveXObject("ShockwaveFlash.ShockwaveFlash")&&(a=!0)}catch(b){}return!a&&navigator.mimeTypes["application/x-shockwave-flash"]&&(a=!0),a};var t=null,u=null,v=function(){var a,b,c=p.prototype._singleton,d=document.getElementById("global-zeroclipboard-html-bridge");if(!d){var e={};for(var f in c.options)e[f]=c.options[f];e.amdModuleId=t,e.cjsModuleId=u;var g=l(e),h=' <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" id="global-zeroclipboard-flash-bridge" width="100%" height="100%"> <param name="movie" value="'+c.options.moviePath+k(c.options.moviePath,c.options)+'"/> <param name="allowScriptAccess" value="'+c.options.allowScriptAccess+'"/> <param name="scale" value="exactfit"/> <param name="loop" value="false"/> <param name="menu" value="false"/> <param name="quality" value="best" /> <param name="bgcolor" value="#ffffff"/> <param name="wmode" value="transparent"/> <param name="flashvars" value="'+g+'"/> <embed src="'+c.options.moviePath+k(c.options.moviePath,c.options)+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="100%" height="100%" name="global-zeroclipboard-flash-bridge" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" wmode="transparent" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+g+'" scale="exactfit"> </embed> </object>';d=document.createElement("div"),d.id="global-zeroclipboard-html-bridge",d.setAttribute("class","global-zeroclipboard-container"),d.setAttribute("data-clipboard-ready",!1),d.style.position="absolute",d.style.left="-9999px",d.style.top="-9999px",d.style.width="15px",d.style.height="15px",d.style.zIndex="9999",d.innerHTML=h,document.body.appendChild(d)}c.htmlBridge=d,a=document["global-zeroclipboard-flash-bridge"],a&&(b=a.length)&&(a=a[b-1]),c.flashBridge=a||d.children[0].lastElementChild};p.prototype.resetBridge=function(){return this.htmlBridge.style.left="-9999px",this.htmlBridge.style.top="-9999px",this.htmlBridge.removeAttribute("title"),this.htmlBridge.removeAttribute("data-clipboard-text"),h(a,this.options.activeClass),a=null,this.options.text=null,this},p.prototype.ready=function(){var a=this.htmlBridge.getAttribute("data-clipboard-ready");return"true"===a||a===!0},p.prototype.reposition=function(){if(!a)return!1;var b=j(a);return this.htmlBridge.style.top=b.top+"px",this.htmlBridge.style.left=b.left+"px",this.htmlBridge.style.width=b.width+"px",this.htmlBridge.style.height=b.height+"px",this.htmlBridge.style.zIndex=b.zIndex+1,this.setSize(b.width,b.height),this},p.dispatch=function(a,b){p.prototype._singleton.receiveEvent(a,b)},p.prototype.on=function(a,b){for(var c=a.toString().split(/\s/g),d=0;d<c.length;d++)a=c[d].toLowerCase().replace(/^on/,""),this.handlers[a]||(this.handlers[a]=b);return this.handlers.noflash&&!p.detectFlashSupport()&&this.receiveEvent("onNoFlash",null),this},p.prototype.addEventListener=p.prototype.on,p.prototype.off=function(a,b){for(var c=a.toString().split(/\s/g),d=0;d<c.length;d++){a=c[d].toLowerCase().replace(/^on/,"");for(var e in this.handlers)e===a&&this.handlers[e]===b&&delete this.handlers[e]}return this},p.prototype.removeEventListener=p.prototype.off,p.prototype.receiveEvent=function(b,c){b=b.toString().toLowerCase().replace(/^on/,"");var d=a,e=!0;switch(b){case"load":if(c&&parseFloat(c.flashVersion.replace(",",".").replace(/[^0-9\.]/gi,""))<10)return this.receiveEvent("onWrongFlash",{flashVersion:c.flashVersion}),void 0;this.htmlBridge.setAttribute("data-clipboard-ready",!0);break;case"mouseover":g(d,this.options.hoverClass);break;case"mouseout":h(d,this.options.hoverClass),this.resetBridge();break;case"mousedown":g(d,this.options.activeClass);break;case"mouseup":h(d,this.options.activeClass);break;case"datarequested":var f=d.getAttribute("data-clipboard-target"),i=f?document.getElementById(f):null;if(i){var j=i.value||i.textContent||i.innerText;j&&this.setText(j)}else{var k=d.getAttribute("data-clipboard-text");k&&this.setText(k)}e=!1;break;case"complete":this.options.text=null}if(this.handlers[b]){var l=this.handlers[b];"string"==typeof l&&"function"==typeof window[l]&&(l=window[l]),"function"==typeof l&&o(l,d,this,c,e)}},p.prototype.glue=function(a){a=n(a);for(var b=0;b<a.length;b++)-1==m(a[b],q)&&(q.push(a[b]),e(a[b],"mouseover",d));return this},p.prototype.unglue=function(a){a=n(a);for(var b=0;b<a.length;b++){f(a[b],"mouseover",d);var c=m(a[b],q);-1!=c&&q.splice(c,1)}return this},"function"==typeof define&&define.amd?define(["require","exports","module"],function(a,b,c){return t=c&&c.id||null,p}):"object"==typeof module&&module&&"object"==typeof module.exports&&module.exports?(u=module.id||null,module.exports=p):window.ZeroClipboard=p}();
\ No newline at end of file
This diff is collapsed.
/*
### jQuery XML to JSON Plugin v1.3 - 2013-02-18 ###
* http://www.fyneworks.com/ - diego@fyneworks.com
* Licensed under http://en.wikipedia.org/wiki/MIT_License
###
Website: http://www.fyneworks.com/jquery/xml-to-json/
*//*
# INSPIRED BY: http://www.terracoder.com/
AND: http://www.thomasfrank.se/xml_to_json.html
AND: http://www.kawa.net/works/js/xml/objtree-e.html
*//*
This simple script converts XML (document of code) into a JSON object. It is the combination of 2
'xml to json' great parsers (see below) which allows for both 'simple' and 'extended' parsing modes.
*/
// Avoid collisions
;if(window.jQuery) (function($){
// Add function to jQuery namespace
$.extend({
// converts xml documents and xml text to json object
xml2json: function(xml, extended) {
if(!xml) return {}; // quick fail
//### PARSER LIBRARY
// Core function
function parseXML(node, simple){
if(!node) return null;
var txt = '', obj = null, att = null;
var nt = node.nodeType, nn = jsVar(node.localName || node.nodeName);
var nv = node.text || node.nodeValue || '';
/*DBG*/ //if(window.console) console.log(['x2j',nn,nt,nv.length+' bytes']);
if(node.childNodes){
if(node.childNodes.length>0){
/*DBG*/ //if(window.console) console.log(['x2j',nn,'CHILDREN',node.childNodes]);
$.each(node.childNodes, function(n,cn){
var cnt = cn.nodeType, cnn = jsVar(cn.localName || cn.nodeName);
var cnv = cn.text || cn.nodeValue || '';
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>a',cnn,cnt,cnv]);
if(cnt == 8){
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>b',cnn,'COMMENT (ignore)']);
return; // ignore comment node
}
else if(cnt == 3 || cnt == 4 || !cnn){
// ignore white-space in between tags
if(cnv.match(/^\s+$/)){
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>c',cnn,'WHITE-SPACE (ignore)']);
return;
};
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>d',cnn,'TEXT']);
txt += cnv.replace(/^\s+/,'').replace(/\s+$/,'');
// make sure we ditch trailing spaces from markup
}
else{
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>e',cnn,'OBJECT']);
obj = obj || {};
if(obj[cnn]){
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>f',cnn,'ARRAY']);
// http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child
if(!obj[cnn].length) obj[cnn] = myArr(obj[cnn]);
obj[cnn] = myArr(obj[cnn]);
obj[cnn][ obj[cnn].length ] = parseXML(cn, true/* simple */);
obj[cnn].length = obj[cnn].length;
}
else{
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>g',cnn,'dig deeper...']);
obj[cnn] = parseXML(cn);
};
};
});
};//node.childNodes.length>0
};//node.childNodes
if(node.attributes){
if(node.attributes.length>0){
/*DBG*/ //if(window.console) console.log(['x2j',nn,'ATTRIBUTES',node.attributes])
att = {}; obj = obj || {};
$.each(node.attributes, function(a,at){
var atn = jsVar(at.name), atv = at.value;
att[atn] = atv;
if(obj[atn]){
/*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'ARRAY']);
// http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child
//if(!obj[atn].length) obj[atn] = myArr(obj[atn]);//[ obj[ atn ] ];
obj[cnn] = myArr(obj[cnn]);
obj[atn][ obj[atn].length ] = atv;
obj[atn].length = obj[atn].length;
}
else{
/*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'TEXT']);
obj[atn] = atv;
};
});
//obj['attributes'] = att;
};//node.attributes.length>0
};//node.attributes
if(obj){
obj = $.extend( (txt!='' ? new String(txt) : {}),/* {text:txt},*/ obj || {}/*, att || {}*/);
//txt = (obj.text) ? (typeof(obj.text)=='object' ? obj.text : [obj.text || '']).concat([txt]) : txt;
txt = (obj.text) ? ([obj.text || '']).concat([txt]) : txt;
if(txt) obj.text = txt;
txt = '';
};
var out = obj || txt;
//console.log([extended, simple, out]);
if(extended){
if(txt) out = {};//new String(out);
txt = out.text || txt || '';
if(txt) out.text = txt;
if(!simple) out = myArr(out);
};
return out;
};// parseXML
// Core Function End
// Utility functions
var jsVar = function(s){ return String(s || '').replace(/-/g,"_"); };
// NEW isNum function: 01/09/2010
// Thanks to Emile Grau, GigaTecnologies S.L., www.gigatransfer.com, www.mygigamail.com
function isNum(s){
// based on utility function isNum from xml2json plugin (http://www.fyneworks.com/ - diego@fyneworks.com)
// few bugs corrected from original function :
// - syntax error : regexp.test(string) instead of string.test(reg)
// - regexp modified to accept comma as decimal mark (latin syntax : 25,24 )
// - regexp modified to reject if no number before decimal mark : ".7" is not accepted
// - string is "trimmed", allowing to accept space at the beginning and end of string
var regexp=/^((-)?([0-9]+)(([\.\,]{0,1})([0-9]+))?$)/
return (typeof s == "number") || regexp.test(String((s && typeof s == "string") ? jQuery.trim(s) : ''));
};
// OLD isNum function: (for reference only)
//var isNum = function(s){ return (typeof s == "number") || String((s && typeof s == "string") ? s : '').test(/^((-)?([0-9]*)((\.{0,1})([0-9]+))?$)/); };
var myArr = function(o){
// http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child
//if(!o.length) o = [ o ]; o.length=o.length;
if(!$.isArray(o)) o = [ o ]; o.length=o.length;
// here is where you can attach additional functionality, such as searching and sorting...
return o;
};
// Utility functions End
//### PARSER LIBRARY END
// Convert plain text to xml
if(typeof xml=='string') xml = $.text2xml(xml);
// Quick fail if not xml (or if this is a node)
if(!xml.nodeType) return;
if(xml.nodeType == 3 || xml.nodeType == 4) return xml.nodeValue;
// Find xml root node
var root = (xml.nodeType == 9) ? xml.documentElement : xml;
// Convert xml to json
var out = parseXML(root, true /* simple */);
// Clean-up memory
xml = null; root = null;
// Send output
return out;
},
// Convert text to XML DOM
text2xml: function(str) {
// NOTE: I'd like to use jQuery for this, but jQuery makes all tags uppercase
//return $(xml)[0];
/* prior to jquery 1.9 */
/*
var out;
try{
var xml = ((!$.support.opacity && !$.support.style))?new ActiveXObject("Microsoft.XMLDOM"):new DOMParser();
xml.async = false;
}catch(e){ throw new Error("XML Parser could not be instantiated") };
try{
if((!$.support.opacity && !$.support.style)) out = (xml.loadXML(str))?xml:false;
else out = xml.parseFromString(str, "text/xml");
}catch(e){ throw new Error("Error parsing XML string") };
return out;
*/
/* jquery 1.9+ */
return $.parseXML(str);
}
}); // extend $
})(jQuery);
\ No newline at end of file
This diff is collapsed.
#social{position:absolute;right:10px;top:10px;line-height:20px;text-align:right;overflow:hidden} #social{position:absolute;right:10px;top:10px;line-height:20px;text-align:right;overflow:hidden}
.dropdown{padding-right:28px}.dropdown:after{content:' ';display:block;position:absolute;right:10px;top:15px;width:0;height:0;border:solid;border-width:4px 5px;border-color:#fff transparent transparent transparent} .dropdown{padding-right:28px}.dropdown:after{content:' ';display:block;position:absolute;right:10px;top:15px;width:0;height:0;border:solid;border-width:4px 5px;border-color:#fff transparent transparent transparent}
button{font-family:Arial,"Heiti SC","Microsoft Yahei";outline:none;display:inline-block;padding:0 15px;height:35px;font-size:13px;line-height:35px;text-align:center;border-radius:5px;color:#fff;text-decoration:none;border:none;margin-left:5px;cursor:pointer;background:#0099f2;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwOTlmMiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjNDA5NmVlIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzAwNzZkZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);background:-moz-linear-gradient(top, #0099f2 0, #4096ee 0, #0076dd 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0, #0099f2), color-stop(0, #4096ee), color-stop(100%, #0076dd));background:-webkit-linear-gradient(top, #0099f2 0, #4096ee 0, #0076dd 100%);background:-o-linear-gradient(top, #0099f2 0, #4096ee 0, #0076dd 100%);background:-ms-linear-gradient(top, #0099f2 0, #4096ee 0, #0076dd 100%);background:linear-gradient(to bottom, #0099f2 0, #4096ee 0, #0076dd 100%);}button:hover{background:#009fff} button{font-family:Arial,"Heiti SC","Microsoft Yahei";outline:none;display:inline-block;padding:0 15px;height:35px;font-size:13px;line-height:35px;text-align:center;border-radius:5px;color:#fff;text-decoration:none;border:none;margin-left:5px;cursor:pointer;background:#0099f2;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwOTlmMiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjNDA5NmVlIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzAwNzZkZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);background:-moz-linear-gradient(top, #0099f2 0, #4096ee 0, #0076dd 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0, #0099f2), color-stop(0, #4096ee), color-stop(100%, #0076dd));background:-webkit-linear-gradient(top, #0099f2 0, #4096ee 0, #0076dd 100%);background:-o-linear-gradient(top, #0099f2 0, #4096ee 0, #0076dd 100%);background:-ms-linear-gradient(top, #0099f2 0, #4096ee 0, #0076dd 100%);background:linear-gradient(to bottom, #0099f2 0, #4096ee 0, #0076dd 100%);}button:hover,button.hover{background:#009fff}
button:active{background:#007fcc;box-shadow:inset 0 2px 3px rgba(0,0,0,0.2)} button:active,button.active{background:#007fcc;box-shadow:inset 0 2px 3px rgba(0,0,0,0.2)}
button[disabled]{background:#aaa} button[disabled]{background:#aaa;cursor:default}
button.baidu-cloud{padding-left:35px;position:relative}button.baidu-cloud:before{content:' ';display:block;width:24px;height:24px;background:url(../themes/default/images/baiducloud.png);position:absolute;left:7px;top:5px} button.baidu-cloud{padding-left:35px;position:relative}button.baidu-cloud:before{content:' ';display:block;width:24px;height:24px;background:url(../themes/default/images/baiducloud.png);position:absolute;left:7px;top:5px}
button.share{padding-left:35px;position:relative}button.share:before{content:' ';display:block;width:24px;height:24px;background:url(../themes/default/images/share.png) no-repeat;position:absolute;left:7px;top:5px} button.share{padding-left:35px;position:relative}button.share:before{content:' ';display:block;width:24px;height:24px;background:url(../themes/default/images/share.png) no-repeat;position:absolute;left:7px;top:5px}
button img{position:relative;top:3px;border-radius:2px;margin-right:7px} button img{position:relative;top:3px;border-radius:2px;margin-right:7px}
...@@ -19,8 +19,9 @@ button.user-file{position:relative;padding-right:28px}button.user-file:after{con ...@@ -19,8 +19,9 @@ button.user-file{position:relative;padding-right:28px}button.user-file:after{con
.draft-menu.kmui-combobox-menu .kmui-combobox-checked .kmui-combobox-item-label{display:block;margin-left:28px} .draft-menu.kmui-combobox-menu .kmui-combobox-checked .kmui-combobox-item-label{display:block;margin-left:28px}
.draft-menu.kmui-combobox-menu .kmui-combobox-checked:hover{color:#ccc}.draft-menu.kmui-combobox-menu .kmui-combobox-checked:hover .kmui-combobox-icon{background-position:center 0} .draft-menu.kmui-combobox-menu .kmui-combobox-checked:hover{color:#ccc}.draft-menu.kmui-combobox-menu .kmui-combobox-checked:hover .kmui-combobox-icon{background-position:center 0}
.user-file-menu{margin-top:20px;margin-left:1px} .user-file-menu{margin-top:20px;margin-left:1px}
#share-dialog{position:absolute;padding:20px;border-radius:4px;right:10px;top:65px;background:#fff;width:300px;box-shadow:1px 2px 16px rgba(0,0,0,0.5);display:none}#share-dialog h3{margin:0;font-size:16px;color:#666} #share-dialog{position:absolute;padding:20px;border-radius:4px;right:10px;top:65px;background:#fff;width:350px;box-shadow:1px 2px 16px rgba(0,0,0,0.5);display:none}#share-dialog h3{margin:0;font-size:16px;color:#666}
#share-dialog input{width:98%} #share-dialog input{width:260px;height:22px;line-height:22px;padding:4px 4px 0;border:1px solid #999;vertical-align:middle;margin-right:3px;background:#eee}#share-dialog input:focus{border:1px solid #99f;outline:none}
#share-dialog p,#share-dialog #share-platform{margin:20px 0 30px} #share-dialog p,#share-dialog #share-platform{margin:20px 0 30px}
#share-dialog #copy-share-url{display:inline-block;margin:0;width:70px;height:28px;line-height:28px;border-radius:2px;vertical-align:middle}
#share-dialog #share-platform{margin-bottom:0} #share-dialog #share-platform{margin-bottom:0}
#share-dialog:before{position:absolute;content:' ';width:0;height:0;line-height:0;display:block;border:10px solid transparent;border-bottom-color:#fff;right:30px;top:-20px} #share-dialog:before{position:absolute;content:' ';width:0;height:0;line-height:0;display:block;border:10px solid transparent;border-bottom-color:#fff;right:30px;top:-20px}
/* global Promise: true */ /* global Promise: true */
/** /**
* 百度脑图社会化功能
*
* 1. 百度账号登陆
* 2. 百度云存储
* 3. 分享
* 4. 草稿箱
* @author techird * @author techird
*/ */
$.extend( $.fn, { $.extend( $.fn, {
disabled: function ( value ) { disabled: function ( value ) {
if ( value === undefined ) return !!this.attr( 'disabled' ); if ( value === undefined ) return !!this.attr( 'disabled' );
...@@ -49,8 +42,7 @@ $.extend( $.fn, { ...@@ -49,8 +42,7 @@ $.extend( $.fn, {
$( function () { $( function () {
// UI 元素 // UI 元素
var $panel, $login_btn, $save_btn, $share_btn, $user_btn, $user_menu, var $panel, $login_btn, $save_btn, $share_btn, $user_btn, $user_menu, $draft_btn, $draft_menu,
$draft_btn, $draft_menu, $share_dialog, $share_url,
// 当前文件的远端路径 // 当前文件的远端路径
remotePath = null, remotePath = null,
...@@ -65,20 +57,26 @@ $( function () { ...@@ -65,20 +57,26 @@ $( function () {
return ( ( +new Date() * 10000 ) + ( Math.random() * 9999 ) ).toString( 36 ); return ( ( +new Date() * 10000 ) + ( Math.random() * 9999 ) ).toString( 36 );
}, },
// 当前脑图的分享ID // 当前脑图的分享连接
shareId = uuid(), shareId = uuid(),
titleSuffix = document.title || '百度脑图', // 查找 baseUrl
baseUrl = ( function () {
var scripts = document.getElementsByTagName( 'script' );
for ( var i = 0; i < scripts.length; i++ ) {
var index = scripts[ i ].src.indexOf( 'social.js' );
if ( ~index ) {
return scripts[ i ].src.substr( 0, index );
}
}
} )(),
notice = window.alert, notice = window.alert,
// 脑图实例
minder = window.km, minder = window.km,
// 草稿箱 draftManager = window.draftManager || new window.DraftManager( minder ),
draftManager = new window.DraftManager( minder ),
// 当前是否要检测文档内容是否变化的开关
watchingChanges = true; watchingChanges = true;
start(); start();
...@@ -130,19 +128,6 @@ $( function () { ...@@ -130,19 +128,6 @@ $( function () {
$draft_menu = $.kmuidropmenu().addClass( 'draft-menu kmui-combobox-menu' ).appendTo( 'body' ); $draft_menu = $.kmuidropmenu().addClass( 'draft-menu kmui-combobox-menu' ).appendTo( 'body' );
$draft_menu.kmui().attachTo( $draft_btn ); $draft_menu.kmui().attachTo( $draft_btn );
$draft_menu.on( 'aftershow', showDraftList ); $draft_menu.on( 'aftershow', showDraftList );
$share_dialog = $( '#share-dialog' );
$share_url = $( '#share-url' );
$share_dialog.mousedown( function ( e ) {
e.stopPropagation();
} );
$( 'body' ).on( 'mousedown', function ( e ) {
$share_dialog.hide();
$share_btn.loading( false );
} );
} }
// 初始化云平台 frontia // 初始化云平台 frontia
...@@ -173,7 +158,6 @@ $( function () { ...@@ -173,7 +158,6 @@ $( function () {
baidu.frontia.storage.findData( query, { baidu.frontia.storage.findData( query, {
success: function ( ret ) { success: function ( ret ) {
draftManager.create();
minder.importData( ret.result[ 0 ].obj.shareMinder.data, 'json' ); minder.importData( ret.result[ 0 ].obj.shareMinder.data, 'json' );
$share_btn.loading( false ); $share_btn.loading( false );
}, },
...@@ -207,9 +191,6 @@ $( function () { ...@@ -207,9 +191,6 @@ $( function () {
} else if ( currentAccount ) { } else if ( currentAccount ) {
$user_btn.text( '* ' + minder.getMinderTitle() ); $user_btn.text( '* ' + minder.getMinderTitle() );
} }
document.title = [ filename || minder.getMinderTitle(), titleSuffix ].join( ' - ' );
if ( saved ) { if ( saved ) {
$save_btn.disabled( true ).text( '已保存' ); $save_btn.disabled( true ).text( '已保存' );
} else { } else {
...@@ -239,6 +220,8 @@ $( function () { ...@@ -239,6 +220,8 @@ $( function () {
function setAccount( account ) { function setAccount( account ) {
currentAccount = account; currentAccount = account;
$user_btn.prependTo( $panel ); $user_btn.prependTo( $panel );
$save_btn.appendTo( $panel );
$share_btn.appendTo( $panel );
$save_btn.disabled( false ); $save_btn.disabled( false );
$share_btn.disabled( false ); $share_btn.disabled( false );
$login_btn.detach(); $login_btn.detach();
...@@ -289,14 +272,81 @@ $( function () { ...@@ -289,14 +272,81 @@ $( function () {
sto.getFileUrl( remotePath, { sto.getFileUrl( remotePath, {
success: function ( url ) { success: function ( url ) {
// the url to download the file on cloud dist
var arr = remotePath.split( '.' );
var format = arr[ arr.length - 1 ];
if ( format in loadFile ) {
loadFile[ format ]( url );
}
},
error: notice
} );
}
var loadFile = {
'km': loadPlainType,
'json': loadPlainType,
'xmind': loadXMind,
'mmap': loadMindManager,
'mm': loadFreeMind
};
function loadPlainType( url ) {
$.ajax( {
cache: false,
url: url,
dataType: 'text',
success: function ( result ) {
importFile( result, 'json' );
}
} );
}
function loadXMind( url ) {
var xhr = new XMLHttpRequest();
xhr.open( "get", url, true );
xhr.responseType = "blob";
xhr.onload = function () {
if ( this.status == 200 && this.readyState ) {
var blob = this.response;
importFile( blob, 'xmind' );
}
};
xhr.send();
}
function loadMindManager( url ) {
var xhr = new XMLHttpRequest();
xhr.open( "get", url, true );
xhr.responseType = "blob";
xhr.onload = function () {
if ( this.status == 200 && this.readyState ) {
var blob = this.response;
importFile( blob, 'mindmanager' );
}
};
xhr.send();
}
function loadFreeMind( url ) {
$.ajax( { $.ajax( {
cache: false, cache: false,
url: url, url: url,
dataType: 'text', dataType: 'text',
success: function ( result ) { success: function ( result ) {
importFile( result, 'freemind' );
}
} );
}
// 见文件数据导入minder
function importFile( data, format ) {
watchingChanges = false; watchingChanges = false;
minder.importData( result, 'json' ); minder.importData( data, format );
if ( !draftManager.openByPath( remotePath ) ) { if ( !draftManager.openByPath( remotePath ) ) {
draftManager.create(); draftManager.create();
...@@ -308,11 +358,6 @@ $( function () { ...@@ -308,11 +358,6 @@ $( function () {
watchingChanges = true; watchingChanges = true;
} }
} );
},
error: notice
} );
}
// 添加文件到最近文件列表 // 添加文件到最近文件列表
function addToRecentMenu( list ) { function addToRecentMenu( list ) {
...@@ -412,9 +457,9 @@ $( function () { ...@@ -412,9 +457,9 @@ $( function () {
return; return;
} }
var baseUrl = /^(.*?)(\?|\#|$)/.exec( window.location.href )[ 1 ]; var currentUrl = window.location.origin + window.location.pathname,
var shareUrl = baseUrl + '?shareId=' + shareId, shareUrl = currentUrl + '?shareId=' + shareId,
shareData = new baidu.frontia.Data( { shareData = new baidu.frontia.Data( {
shareMinder: { shareMinder: {
...@@ -423,21 +468,41 @@ $( function () { ...@@ -423,21 +468,41 @@ $( function () {
} }
} ); } );
var shareConfig = window._bd_share_config.common,
resetShare = window._bd_share_main.init;
$share_btn.loading( '正在分享...' ); $share_btn.loading( '正在分享...' );
baidu.frontia.storage.insertData( shareData, { baidu.frontia.storage.insertData( shareData, {
success: function () { success: function () {
$share_dialog.show(); var $popup, $url;
$share_url.val( shareUrl )[ 0 ].select();
$popup = $( '<div></div>' ).addClass( 'popup' ).appendTo( 'body' );
$popup.css( {
'position': 'absolute',
'right': 10,
'top': $share_btn.offset().top + $share_btn.height() + 10,
'width': 250,
'padding': 10,
'background': 'white',
'border-radius': '5px',
'box-shadow': '1px 2px 4px rgba(0, 0, 0, .3)'
} );
$popup.append( '<p style="margin: 5px 0; font-size: 12px;">分享成功,请复制URL:</p>' );
$url = $( '<input type="text" style="width: 250px;" value="' + shareUrl + '"></input>' ).appendTo( $popup );
$url[ 0 ].select();
$popup.mousedown( function ( e ) {
e.stopPropagation();
} );
$( 'body' ).one( 'mousedown', function ( e ) {
$popup.fadeOut( 'fast', function () {
$popup.remove();
} );
$share_btn.loading( false );
} );
} }
} ); } );
shareConfig.bdTitle = shareConfig.bdText = minder.getMinderTitle();
shareConfig.bdDesc = shareConfig.bdText = '“' + minder.getMinderTitle() + '” - 我用百度脑图制作的思维导图,快看看吧!(地址:' + shareUrl + ')';
shareConfig.bdUrl = shareUrl;
resetShare();
} }
function bindShortCuts() { function bindShortCuts() {
......
...@@ -48,17 +48,18 @@ button { ...@@ -48,17 +48,18 @@ button {
background: -ms-linear-gradient(top, #0099f2 0%,#4096ee 0%,#0076dd 100%); /* IE10+ */ background: -ms-linear-gradient(top, #0099f2 0%,#4096ee 0%,#0076dd 100%); /* IE10+ */
background: linear-gradient(to bottom, #0099f2 0%,#4096ee 0%,#0076dd 100%); /* W3C */ background: linear-gradient(to bottom, #0099f2 0%,#4096ee 0%,#0076dd 100%); /* W3C */
&:hover { &:hover, &.hover {
background: #009fff; background: #009fff;
} }
&:active { &:active, &.active {
background: darken(#009fff, 10%); background: darken(#009fff, 10%);
box-shadow: inset 0 2px 3px rgba(0,0,0, .2); box-shadow: inset 0 2px 3px rgba(0,0,0, .2);
} }
&[disabled] { &[disabled] {
background: #AAA; background: #AAA;
cursor: default;
} }
&.baidu-cloud { &.baidu-cloud {
...@@ -199,7 +200,7 @@ button { ...@@ -199,7 +200,7 @@ button {
right: 10px; right: 10px;
top: 65px; top: 65px;
background: white; background: white;
width: 300px; width: 350px;
box-shadow: 1px 2px 16px rgba(0, 0, 0, .5); box-shadow: 1px 2px 16px rgba(0, 0, 0, .5);
display: none; display: none;
...@@ -210,13 +211,34 @@ button { ...@@ -210,13 +211,34 @@ button {
} }
input { input {
width: 98%; width: 260px;
height: 22px;
line-height: 22px;
padding: 4px 4px 0;
border: 1px solid #999;
vertical-align: middle;
margin-right: 3px;
background: #EEE;
&:focus {
border: 1px solid #99f;
outline: none;
}
} }
p, #share-platform { p, #share-platform {
margin: 20px 0 30px; margin: 20px 0 30px;
} }
#copy-share-url {
display: inline-block;
margin: 0;
width: 70px;
height: 28px;
line-height: 28px;
border-radius: 2px;
vertical-align: middle;
}
#share-platform { #share-platform {
margin-bottom: 0; margin-bottom: 0;
} }
......
...@@ -17,10 +17,12 @@ KM.registerToolbarUI( 'saveto', function ( name ) { ...@@ -17,10 +17,12 @@ KM.registerToolbarUI( 'saveto', function ( name ) {
utils.each( KityMinder.getAllRegisteredProtocals(), function ( k ) { utils.each( KityMinder.getAllRegisteredProtocals(), function ( k ) {
var p = KityMinder.findProtocal( k ); var p = KityMinder.findProtocal( k );
if( p.encode ){
var text = p.fileDescription + '(' + p.fileExtension + ')'; var text = p.fileDescription + '(' + p.fileExtension + ')';
options.value.push( k ); options.value.push( k );
options.items.push( text ); options.items.push( text );
options.autowidthitem.push( $.wordCountAdaptive( text ), true ); options.autowidthitem.push( $.wordCountAdaptive( text ), true );
}
} ); } );
......
...@@ -97,8 +97,20 @@ kity.extendClass( Minder, { ...@@ -97,8 +97,20 @@ kity.extendClass( Minder, {
json = params.json || ( params.json = protocal.decode( local ) ); json = params.json || ( params.json = protocal.decode( local ) );
this._fire( new MinderEvent( 'preimport', params, false ) ); if( typeof json === 'object' && 'then' in json){
var self = this;
json.then( local, function(data){
self._afterImportData( data, params );
});
}else{
this._afterImportData( json, params );
}
return this;
},
_afterImportData: function( json, params ){
this._fire( new MinderEvent( 'preimport', params, false ) );
// 删除当前所有节点 // 删除当前所有节点
while ( this._root.getChildren().length ) { while ( this._root.getChildren().length ) {
...@@ -114,7 +126,6 @@ kity.extendClass( Minder, { ...@@ -114,7 +126,6 @@ kity.extendClass( Minder, {
this._firePharse( { this._firePharse( {
type: 'interactchange' type: 'interactchange'
} ); } );
return this;
} }
} ); } );
\ No newline at end of file
...@@ -16,13 +16,50 @@ KityMinder.registerModule( "DropFile", function () { ...@@ -16,13 +16,50 @@ KityMinder.registerModule( "DropFile", function () {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
var minder = this; var minder = this;
if ( e.dataTransfer.files ) {
var files = e.dataTransfer.files;
if ( files ) {
var file = files[0];
var ext = file.type || (/(.)\w+$/).exec(file.name)[0];
if( (/xmind/g).test(ext) ){ //xmind zip
importSync( minder, file, 'xmind' );
}else if( (/mmap/g).test(ext) ){ // mindmanager zip
importSync( minder, file, 'mindmanager' );
}else if( (/mm/g).test(ext) ){ //freemind xml
importAsync( minder, file, 'freemind' );
}else{// txt json
importAsync( minder, file );
}
}
}
// 同步加载文件
function importSync( minder, file, protocal ){
minder.importData( file, protocal );//zip文件的import是同步的
manageDraft( minder );
minder.execCommand( 'camera', minder.getRoot() );
}
// 异步加载文件
function importAsync( minder, file, protocal ){
var reader = new FileReader(); var reader = new FileReader();
reader.onload = function ( e ) { reader.onload = function ( e ) {
minder.importData( e.target.result ); minder.importData( e.target.result, protocal );//纯文本文件的import是同步的
manageDraft( minder );
minder.execCommand( 'camera', minder.getRoot() );
}; };
reader.readAsText( e.dataTransfer.files[ 0 ] ); reader.readAsText( file );
}
function manageDraft( minder ){
if( !window.draftManager ){
window.draftManager = new window.DraftManager( minder );
} }
window.draftManager.create();
} }
return { return {
......
...@@ -20,7 +20,6 @@ KityMinder.registerModule( "IconModule", function () { ...@@ -20,7 +20,6 @@ KityMinder.registerModule( "IconModule", function () {
_rc.addShapes( [ _bg, _percent ] ); _rc.addShapes( [ _bg, _percent ] );
node.getIconRc().addShape( _rc ); node.getIconRc().addShape( _rc );
_rc.setTransform( new kity.Matrix().translate( left, 10 ) ); _rc.setTransform( new kity.Matrix().translate( left, 10 ) );
_percent.setTransform( 10, 10 );
switch ( val ) { switch ( val ) {
case 1: case 1:
break; break;
......
KityMinder.registerModule( "KeyboardModule", function () { KityMinder.registerModule( "KeyboardModule", function () {
var min = Math.min,
max = Math.max,
abs = Math.abs,
sqrt = Math.sqrt,
exp = Math.exp;
function buildPositionNetwork( root ) { function buildPositionNetwork( root ) {
var pointIndexes = [], var pointIndexes = [],
...@@ -6,9 +11,14 @@ KityMinder.registerModule( "KeyboardModule", function () { ...@@ -6,9 +11,14 @@ KityMinder.registerModule( "KeyboardModule", function () {
root.traverse( function ( node ) { root.traverse( function ( node ) {
p = node.getRenderContainer().getRenderBox( 'top' ); p = node.getRenderContainer().getRenderBox( 'top' );
pointIndexes.push( { pointIndexes.push( {
x: p.x + p.width / 2, left: p.x,
y: p.y + p.height / 2, top: p.y,
node: node right: p.x + p.width,
bottom: p.y + p.height,
width: p.width,
height: p.height,
node: node,
text: node.getText()
} ); } );
} ); } );
for ( var i = 0; i < pointIndexes.length; i++ ) { for ( var i = 0; i < pointIndexes.length; i++ ) {
...@@ -16,34 +26,101 @@ KityMinder.registerModule( "KeyboardModule", function () { ...@@ -16,34 +26,101 @@ KityMinder.registerModule( "KeyboardModule", function () {
} }
} }
function quadOf( p ) {
return p.x > 0 ? // 这是金泉的点子,赞!
( p.y > 0 ? 1 : 2 ) : // 求两个不相交矩形的最近距离
( p.y < 0 ? 3 : 4 ); function getCoefedDistance( box1, box2 ) {
var xMin, xMax, yMin, yMax, xDist, yDist, dist, cx, cy;
xMin = min( box1.left, box2.left );
xMax = max( box1.right, box2.right );
yMin = min( box1.top, box2.top );
yMax = max( box1.bottom, box2.bottom );
xDist = xMax - xMin - box1.width - box2.width;
yDist = yMax - yMin - box1.height - box2.height;
if ( xDist < 0 ) dist = yDist;
else if ( yDist < 0 ) dist = xDist;
else dist = sqrt( xDist * xDist + yDist * yDist );
return {
cx: dist,
cy: dist
};
}
function coefForX( a, b ) {
return 0.1 * min( abs( a.top - b.top ), abs( a.bottom - b.bottom ) ) + 1;
}
function coefForY( a, b ) {
return 0.1 * min( abs( a.left - b.left ), abs( a.right - b.right ) ) + 1;
} }
function findClosestPointsFor( pointIndexes, iFind ) { function findClosestPointsFor( pointIndexes, iFind ) {
var find = pointIndexes[ iFind ]; var find = pointIndexes[ iFind ];
var matrix = new kity.Matrix().translate( -find.x, -find.y ).rotate( 45 );
var most = {}, quad; var most = {}, quad;
var current; var current, dist;
var table = [];
console.log( 'table for ' + find.text );
for ( var i = 0; i < pointIndexes.length; i++ ) { for ( var i = 0; i < pointIndexes.length; i++ ) {
if ( i == iFind ) continue; if ( i == iFind ) continue;
current = matrix.transformPoint( pointIndexes[ i ].x, pointIndexes[ i ].y ); current = pointIndexes[ i ];
quad = quadOf( current ); dist = getCoefedDistance( current, find );
if ( !most[ quad ] || current.length() < most[ quad ].point.length() ) {
most[ quad ] = { table.push( {
point: current, text: current.text,
node: pointIndexes[ i ].node dist: dist.cx
} );
// left check
if ( current.right < find.left ) {
if ( !most.left || dist.cx < most.left.dist ) {
most.left = {
dist: dist.cx,
node: current.node
}; };
} }
} }
// right check
if ( current.left > find.right ) {
if ( !most.right || dist.cx < most.right.dist ) {
most.right = {
dist: dist.cx,
node: current.node
};
}
}
// top check
if ( current.bottom < find.top ) {
if ( !most.top || dist.cy < most.top.dist ) {
most.top = {
dist: dist.cy,
node: current.node
};
}
}
// bottom check
if ( current.top > find.bottom ) {
if ( !most.down || dist.cy < most.down.dist ) {
most.down = {
dist: dist.cy,
node: current.node
};
}
}
}
console.table( table );
find.node._nearestNodes = { find.node._nearestNodes = {
right: most[ 1 ] && most[ 1 ].node || null, right: most.right && most.right.node || null,
top: most[ 2 ] && most[ 2 ].node || null, top: most.top && most.top.node || null,
left: most[ 3 ] && most[ 3 ].node || null, left: most.left && most.left.node || null,
down: most[ 4 ] && most[ 4 ].node || null down: most.down && most.down.node || null
}; };
} }
......
/*
http://freemind.sourceforge.net/
freemind文件后缀为.mm,实际格式为xml
*/
KityMinder.registerProtocal( 'freemind', function () {
// 标签 map
var markerMap = {
'full-1' : ['PriorityIcon', 1]
,'full-2' : ['PriorityIcon', 2]
,'full-3' : ['PriorityIcon', 3]
,'full-4' : ['PriorityIcon', 4]
,'full-5' : ['PriorityIcon', 5]
,'full-6' : null
,'full-7' : null
,'full-8' : null
,'full-9' : null
,'full-0' : null
};
function processTopic(topic, obj){
//处理文本
obj.data = { text : topic.TEXT };
// 处理标签
if(topic.icon){
var icons = topic.icon;
if(icons.length && icons.length > 0){
for (var i in icons) {
var type = markerMap[ icons[i]['BUILTIN'] ];
type && (obj.data[ type[0] ] = type[1]);
}
}else{
var type = markerMap[ icons['BUILTIN'] ];
type && (obj.data[ type[0] ] = type[1]);
}
}
//处理子节点
if( topic.node ){
var tmp = topic.node;
if( tmp.length && tmp.length > 0 ){ //多个子节点
obj.children = [];
for(var i in tmp){
obj.children.push({});
processTopic(tmp[i], obj.children[i]);
}
}else{ //一个子节点
obj.children = [{}];
processTopic(tmp, obj.children[0]);
}
}
}
function xml2km(xml){
var json = $.xml2json(xml);
var result = {};
processTopic(json.node, result);
return result;
}
return {
fileDescription: 'xmind格式文件',
fileExtension: '.xmind',
decode: function ( local ) {
var json = xml2km( local );
return json;
},
// recognize: recognize,
recognizePriority: -1
};
} );
/*
http://www.mindjet.com/mindmanager/
mindmanager的后缀为.mmap,实际文件格式是zip,解压之后核心文件是Document.xml
*/
KityMinder.registerProtocal( 'mindmanager', function () {
// 标签 map
var markerMap = {
'urn:mindjet:Prio1' : ['PriorityIcon', 1]
,'urn:mindjet:Prio2' : ['PriorityIcon', 2]
,'urn:mindjet:Prio3' : ['PriorityIcon', 3]
,'urn:mindjet:Prio4' : ['PriorityIcon', 4]
,'urn:mindjet:Prio5' : ['PriorityIcon', 5]
,'0' : ['ProgressIcon', 1]
,'25' : ['ProgressIcon', 2]
,'50' : ['ProgressIcon', 3]
,'75' : ['ProgressIcon', 4]
,'100' : ['ProgressIcon', 5]
};
function processTopic(topic, obj){
//处理文本
obj.data = { text : topic.Text && topic.Text.PlainText || '_' }; // 节点默认的文本,没有Text属性
// 处理标签
if(topic.Task){
var type;
if(topic.Task.TaskPriority){
type = markerMap[ topic.Task.TaskPriority ];
type && (obj.data[ type[0] ] = type[1]);
}
if(topic.Task.TaskPercentage){
type = markerMap[ topic.Task.TaskPercentage ];
type && (obj.data[ type[0] ] = type[1]);
}
}
//处理子节点
if( topic.SubTopics && topic.SubTopics.Topic ){
var tmp = topic.SubTopics.Topic;
if( tmp.length && tmp.length > 0 ){ //多个子节点
obj.children = [];
for(var i in tmp){
obj.children.push({});
processTopic(tmp[i], obj.children[i]);
}
}else{ //一个子节点
obj.children = [{}];
processTopic(tmp, obj.children[0]);
}
}
}
function xml2km(xml){
var json = $.xml2json(xml);
var result = {};
processTopic(json.OneTopic.Topic, result);
return result;
}
function getEntries(file, onend) {
zip.createReader(new zip.BlobReader(file), function(zipReader) {
zipReader.getEntries(onend);
}, onerror);
}
return {
fileDescription: 'mindmanager格式文件',
fileExtension: '.mmap',
decode: function ( local ) {
return {
then : function(local, callback){
getEntries( local, function( entries ) {
entries.forEach(function( entry ) {
if(entry.filename == 'Document.xml'){
entry.getData(new zip.TextWriter(), function(text) {
var km = xml2km($.parseXML(text));
callback && callback( km );
});
}
});
});
}
};
},
// recognize: recognize,
recognizePriority: -1
};
} );
...@@ -7,7 +7,105 @@ ...@@ -7,7 +7,105 @@
XMind files are generated in XMind Workbook (.xmind) format, an open format that is based on the principles of OpenDocument. It consists of a ZIP compressed archive containing separate XML documents for content and styles, a .jpg image file for thumbnails, and directories for related attachments. XMind files are generated in XMind Workbook (.xmind) format, an open format that is based on the principles of OpenDocument. It consists of a ZIP compressed archive containing separate XML documents for content and styles, a .jpg image file for thumbnails, and directories for related attachments.
*/ */
KityMinder.registerProtocal( 'xmind', { KityMinder.registerProtocal( 'xmind', function () {
// 标签 map
var markerMap = {
'priority-1' : ['PriorityIcon', 1]
,'priority-2' : ['PriorityIcon', 2]
,'priority-3' : ['PriorityIcon', 3]
,'priority-4' : ['PriorityIcon', 4]
,'priority-5' : ['PriorityIcon', 5]
,'task-start' : ['ProgressIcon', 1]
,'task-quarter' : ['ProgressIcon', 2]
,'task-half' : ['ProgressIcon', 3]
,'task-3quar' : ['ProgressIcon', 4]
,'task-done' : ['ProgressIcon', 5]
,'task-oct' : null
,'task-3oct' : null
,'task-5oct' : null
,'task-7oct' : null
};
function processTopic(topic, obj){
//处理文本
obj.data = { text : topic.title };
// 处理标签
if(topic.marker_refs && topic.marker_refs.marker_ref){
var markers = topic.marker_refs.marker_ref;
if( markers.length && markers.length > 0 ){
for (var i in markers) {
var type = markerMap[ markers[i]['marker_id'] ];
type && (obj.data[ type[0] ] = type[1]);
}
}else{
var type = markerMap[ markers['marker_id'] ];
type && (obj.data[ type[0] ] = type[1]);
}
}
//处理子节点
if( topic.children && topic.children.topics && topic.children.topics.topic ){
var tmp = topic.children.topics.topic;
if( tmp.length && tmp.length > 0 ){ //多个子节点
obj.children = [];
for(var i in tmp){
obj.children.push({});
processTopic(tmp[i], obj.children[i]);
}
}else{ //一个子节点
obj.children = [{}];
processTopic(tmp, obj.children[0]);
}
}
}
function xml2km(xml){
var json = $.xml2json(xml);
var result = {};
processTopic(json.sheet.topic, result);
return result;
}
function getEntries(file, onend) {
zip.createReader(new zip.BlobReader(file), function(zipReader) {
zipReader.getEntries(onend);
}, onerror);
}
return {
fileDescription: 'xmind格式文件',
fileExtension: '.xmind', fileExtension: '.xmind',
decode: function ( local ) {
return {
then : function(local, callback){
getEntries( local, function( entries ) {
entries.forEach(function( entry ) {
if(entry.filename == 'content.xml'){
entry.getData(new zip.TextWriter(), function(text) {
var km = xml2km($.parseXML(text));
callback && callback( km );
});
}
});
});
}
};
},
// recognize: recognize,
recognizePriority: -1
};
} ); } );
...@@ -11,3 +11,6 @@ ...@@ -11,3 +11,6 @@
## 解析和生成目标 ## 解析和生成目标
只解析 KityMinder 支持部分的文件内容;只生成 KityMinder 和 XMind 都支持的文件内容 只解析 KityMinder 支持部分的文件内容;只生成 KityMinder 和 XMind 都支持的文件内容
使用zip.js解开xmind文件,根目录下的content.xml,描述脑图的结构,其中节点属性只有title对kityminder有用,以及children下面的topic(即节点)
将content.xml的结构和属性解析为xmind的km格式即可渲染
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