Commit 16ecfab2 authored by techird's avatar techird

文件整理

parent 2c75abba
[submodule "kity"]
path = kity
url = https://github.com/fex-team/kity.git
[submodule "fui"]
path = fui
[submodule "lib/kity"]
path = lib/kity
url = https://github.com/fex-team/kity
[submodule "lib/fui"]
path = lib/fui
url = https://github.com/fex-team/fui
[submodule "lib/fio"]
path = lib/fio
url = https://github.com/fex-team/fio
......@@ -18,24 +18,13 @@ module.exports = function(grunt) {
' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>\n' +
' * ====================================================\n' +
' */\n\n',
buildPath = 'import.js',
srcPath = 'src/',
distPath = 'dist/';
var getPath = function(readFile) {
' */\n\n';
var sources = require('fs').readFileSync(readFile);
sources = /paths\s=\s\[([\s\S]*?)\]/ig.exec(sources);
sources = sources[1].replace(/\/\/.*\n/g, '\n').replace(/'|"|\n|\t|\s/g, '');
sources = sources.split(',');
sources.forEach(function(filepath, index) {
sources[index] = srcPath + filepath;
});
return sources;
var sources = require('./import.js');
var srcPath = 'src/',
distPath = 'dist/';
};
console.log(sources);
// Project configuration.
grunt.initConfig({
......@@ -52,7 +41,7 @@ module.exports = function(grunt) {
return src + '\n';
}
},
src: getPath(buildPath),
src: sources,
dest: distPath + 'kityminder.all.js'
}
},
......@@ -73,7 +62,7 @@ module.exports = function(grunt) {
copy: {
dir: {
files: [{
src: ['dialogs/**', 'lang/**', 'lib/**', 'social/**', 'themes/**', 'index.html', 'download.php'],
src: ['ui/theme/**', 'index.html', 'download.php'],
dest: distPath
}]
},
......@@ -90,7 +79,7 @@ module.exports = function(grunt) {
},
mise: {
files: [{
src: ['LICENSE', 'favicon.ico', 'README.md'],
src: ['LICENSE', 'favicon.ico', 'README.md', 'CHANGELOG.md'],
dest: distPath
}]
}
......
(function() {
// 用于存储整个快捷菜单的机构信息的字符串
var helpInfo = '';
$.ajax({
type: 'get',
dataType: 'text',
url: 'dialogs/help/operation.txt',
success: function(text) {
createHelpHtml(text);
}
});
function createHelpHtml(text) {
var txt = text;
// 用于存储获取的某一行数据
var line = '';
// 用于临时存储处理一条line字符串之后的结果
var result = '';
// 判断是否为第一个份菜单,用于控制div.shortcuts-table标签前是否添加</div>。
var isFirstTable = true;
// // 判断是否为每份菜单的第一项
// var isFirstTr = true;
// 正则表达式 start
// 1、匹配菜单分类标题
var reg_thead = /^##/g;
// 2、匹配菜单项
var reg_tcell = /\:/g;
// 3、匹配键值
var reg_key = /\`(.+?)\`/g;
// var 4、匹配快捷键组合选择
var reg_opt = /or|\+|,/gi;
// 菜单分类标题1
var temp = '';
var xmlhttp;
var arr, keys, info;
// help-container start
helpInfo += '<div class="help-container' + (kity.Browser.mac ? ' mac' : '') + '">';
// help-header start
helpInfo += '<h2 class="help-header">操作说明</h2>';
// help-header end
// help-article start
helpInfo += '<div class="help-article row">';
// 开始读取operation.txt文件信息
txt.split('\n').forEach(function(line) {
result = '';
// 如果line以##开头,表明是菜单分类标题
if (reg_thead.test(line)) {
// isFirstTr = true;
// 如果不是第一个分类菜单,那么就需要在添加下一个开始标签之前,为上一个菜单添加结束标签
if (!isFirstTable) {
result += '</table>';
}
// 处理第一个分类菜单后,就需要把标示第一个分类菜单的变量改变
else {
isFirstTable = false;
}
temp = line.substring(line.lastIndexOf(' '));
result += '<table class="shortcuts-table "><tr><td></td><td><span class="shortcuts-thead">' + temp + '</span></td>';
} else if (/\S/.test(line)) {
// else if(reg_tcell.test(line)) {
result += '<tr class="shortcuts-tbody"><td class="shortcuts-group"><div class="right">';
arr = line.split(':');
keys = arr[0];
info = arr[1];
keys = keys.toLowerCase().replace(reg_key, '<span class="shortcuts-key label $1">$1</span>');
result += keys;
result += '</div></td><td class="shortcuts-use">' + info + '</td>';
// 加最后一项的结尾标签
result += '</tr>';
}
// 处理完每一行之后,将result添加到helpInfo之后
helpInfo += result;
result = '';
});
// 要在处理完最后一个分类菜单后,为这个菜单添加结束标签
helpInfo += '<table>';
// 读取operation.txt文件信息完毕
helpInfo += '</div>';
// help-article end
helpInfo += '</div>';
// // help-container end
// $("#help").html(helpInfo);
KM.registerWidget('help', {
tpl: helpInfo,
initContent: function(km) {
var lang = km.getLang('dialogs.help'),
html;
if (lang) {
html = $.parseTmpl(this.tpl, lang);
}
this.root().html(html);
},
initEvent: function(km, $w) {
}
});
}
})();
\ No newline at end of file
## 节点操作
`Enter`: 插入兄弟节点
`Tab`: 插入子节点
`Delete`: 删除节点
`Up`, `Down`, `Left`, `Right`: 节点导航
`Alt` + `Up`, `Alt` + `Down`: 向上/向下调整顺序
`/`: 展开/收起节点
`F2`: 编辑节点
`Ctrl` + `A`: 全选节点
`Ctrl` + `C`: 复制节点
`Ctrl` + `X`: 剪切节点
`Ctrl` + `V`: 粘贴节点
`Ctrl` + `B`: 加粗
`Ctrl` + `I`: 斜体
## 视野控制
`Space`: 切换编辑/抓手模式
`滚轮`: 移动视野
`右键拖动`: 拖动视野
`空白处双击`: 居中根节点
`+`, `-`: 放大/缩小视野
## 文件操作
`Ctrl` + `N`: 新建
`Ctrl` + `S`: 保存
`Ctrl` + `Shift` + `S`: 分享
## 后悔药
`Ctrl` + `Z`: 撤销
`Ctrl` + `Y`: 重做
\ No newline at end of file
(function(utils) {
//todo 这里先写死成中文
var content = '<div class="hyperlink-content" style="padding:20px;width:360px;">';
content += '<style>';
content += '.kmui-dialog-<%= container %> input{';
content += 'width: 74%;';
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, utils.extend({
'container': 'hyperlink'
}, lang));
}
this.root().html(html);
},
initEvent: function(km, $w) {
var $btn = $w.find('#hyperlink_insert');
$btn.attr('disabled', 'disabled');
var $href = $w.find('#hyperlink_href').on('input', function() {
var url = $href.val();
if (!/^https?\:\/\/(\w+\.)+\w+/.test(url)) {
$href.css('color', 'red');
$href.data('error', true);
$btn.attr('disabled', 'disabled');
} else {
$href.css('color', 'black');
$href.data('error', false);
$btn.removeAttr('disabled');
}
});
$btn.on('click', function() {
if ($btn.attr('disabled')) return;
var url = $w.find('#hyperlink_href').val();
km.execCommand('hyperlink', url);
$w.kmui().hide();
});
$w.find('#hyperlink_href').on('keydown', function(e) {
if (e.keyCode === 13) {
$btn.click();
}
});
var url = km.queryCommandValue('hyperlink');
var $input = $w.find('#hyperlink_href');
$input.val(url || 'http://');
setTimeout(function() {
$input.select();
});
},
width: 400
});
})(KM.Utils);
\ No newline at end of file
(function(utils) {
var content = '<div class="image-content" style="padding:20px;width:360px;">';
content += '<style>';
content += '.kmui-dialog-<%= container %> input{';
content += 'width: 74%;';
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="image_href"/>';
content += '<button id="image_insert">插入</button>';
content += '<hr style="height: 0; border: none; border-top: 1px solid #ccc;">';
content += '<img id="image_preview" style="max-width: 360px;"/>';
content += '</div>';
KM.registerWidget('image', {
tpl: content,
initContent: function(km) {
var lang = km.getLang('dialogs.image'),
html;
if (lang) {
html = $.parseTmpl(this.tpl, utils.extend({
'container': 'image'
}, lang));
}
this.root().html(html);
},
initEvent: function(km, $w) {
var $btn = $w.find('#image_insert').attr('disabled', 'disabled');
var $href = $w.find('#image_href').on('input', function() {
var url = $href.val();
if (!/^https?\:\/\/(\w+\.)+\w+/.test(url)) {
$href.css('color', 'red');
$href.data('error', true);
} else {
$href.css('color', 'black');
$href.data('error', false);
}
$w.find('#image_preview').attr('src', $href.val());
});
$w.find('#image_preview').on('load', function() {
$btn.removeAttr('disabled');
}).on('error', function() {
$btn.attr('disabled', 'disabled');
});
$btn.on('click', function() {
if ($btn.attr('disabled')) return;
km.execCommand('image', $href.val());
$w.kmui().hide();
});
$href.on('keydown', function(e) {
if (e.keyCode === 13) {
$btn.click();
}
});
var url = km.queryCommandValue('image');
var $input = $w.find('#image_href');
$input.val(url || 'http://');
if (url) $w.find('#image_preview').attr('src', url);
setTimeout(function() {
$input.select();
});
},
width: 400
});
})(KM.Utils);
\ No newline at end of file
(function (utils) {
KM.registerWidget('markers', {
tpl: "<style>" +
".kmui-dialog-<%= container %> .priority .icon{background:url(dialogs/markers/images/iconpriority.png) 0 0}" +
".kmui-dialog-<%= container %> .progress .icon{background:url(dialogs/markers/images/iconprogress.png) 0 0}" +
".kmui-dialog-<%= container %> .icon.p2{background-position: -20px 0}" +
".kmui-dialog-<%= container %> .icon.p3{background-position: -40px 0}" +
".kmui-dialog-<%= container %> .icon.p4{background-position: -60px 0}" +
".kmui-dialog-<%= container %> .icon.p5{background-position: -80px 0}" +
".kmui-dialog-<%= container %> .icon.p6{background-position: -100px 0}" +
".kmui-dialog-<%= container %> .icon.p7{background-position: -120px 0}" +
".kmui-dialog-<%= container %> .icon.p8{background-position: -140px 0}" +
".kmui-dialog-<%= container %> .icon.p9{background-position: -160px 0}" +
".kmui-dialog-<%= container %> .icon.p0{background-position: -180px 0}" +
".kmui-dialog-<%= container %> ul li{width:40%;display:inline-block}" +
".kmui-dialog-<%= container %> h4{padding:5px 10px; margin:0; background:#eee}" +
"</style>" +
"<h4><%= priority %></h3>" +
"<ul class='icon-list priority'>" +
"<li value='1' type='priority'><span class='icon p1'></span><span><%= priority %>1</span></li>" +
"<li value='2' type='priority'><span class='icon p2'></span><span><%= priority %>2</span></li>" +
"<li value='3' type='priority'><span class='icon p3'></span><span><%= priority %>3</span></li>" +
"<li value='4' type='priority'><span class='icon p4'></span><span><%= priority %>4</span></li>" +
"<li value='5' type='priority'><span class='icon p5'></span><span><%= priority %>5</span></li>" +
"<li value='6' type='priority'><span class='icon p6'></span><span><%= priority %>6</span></li>" +
"<li value='7' type='priority'><span class='icon p7'></span><span><%= priority %>7</span></li>" +
"<li value='8' type='priority'><span class='icon p8'></span><span><%= priority %>8</span></li>" +
"<li value='9' type='priority'><span class='icon p9'></span><span><%= priority %>9</span></li>" +
"<li value='0' type='priority'><span class='icon p0'></span><span><%= none %></span></li>" +
"</ul>" +
"<h4><%= progress.title %></h4>" +
"<ul class='icon-list progress'>" +
"<li value='1' type='progress'><span class='icon p1'></span><span><%= progress.notdone %></span></li>" +
"<li value='2' type='progress'><span class='icon p2'></span><span><%= progress.done1 %></span></li>" +
"<li value='3' type='progress'><span class='icon p3'></span><span><%= progress.done2 %></span></li>" +
"<li value='4' type='progress'><span class='icon p4'></span><span><%= progress.done3 %></span></li>" +
"<li value='5' type='progress'><span class='icon p5'></span><span><%= progress.done4 %></span></li>" +
"<li value='6' type='progress'><span class='icon p6'></span><span><%= progress.done5 %></span></li>" +
"<li value='7' type='progress'><span class='icon p7'></span><span><%= progress.done6 %></span></li>" +
"<li value='8' type='progress'><span class='icon p8'></span><span><%= progress.done7 %></span></li>" +
"<li value='9' type='progress'><span class='icon p9'></span><span><%= progress.done %></span></li>" +
"<li value='0' type='progress'><span class='icon p0'></span><span><%= none %></span></li>" +
"</ul>",
initContent: function (km, $w) {
var lang = km.getLang('dialogs.markers');
if (lang) {
var html = $.parseTmpl(this.tpl, utils.extend({
'container': 'markers'
}, lang));
}
this.root().html(html);
var valPri = km.queryCommandValue("priority") || 0;
var valPro = km.queryCommandValue("progress") || 0;
$w.find("li[type='priority']").removeClass("active");
$w.find("li[type='priority'][value='" + valPri + "']").addClass("active");
$w.find("li[type='progress']").removeClass("active");
$w.find("li[type='progress'][value='" + valPro + "']").addClass("active");
},
initEvent: function (km, $w) {
$w.on("click", "li", function () {
var $this = $(this);
$this.siblings().removeClass("active");
var val = $this.val();
var type = $this.attr("type");
km.execCommand(type, val);
});
km.on('interactchange', function (e) {
var valPri = this.queryCommandValue("priority");
var valPro = this.queryCommandValue("progress");
$w.find("li[type='priority']").removeClass("active");
$w.find("li[type='priority'][value='" + valPri + "']").addClass("active");
$w.find("li[type='progress']").removeClass("active");
$w.find("li[type='progress'][value='" + valPro + "']").addClass("active");
});
},
width: 200
})
})(KM.Utils);
\ No newline at end of file
( function () {
//todo 这里先写死成中文
var preferenceContent = '<div class="help-content" style="padding:20px;width:360px;">';
preferenceContent += '<h3>展开属性设置</h3>';
preferenceContent += '<p><label><input type="checkbox" name="expand" />打开时展开全部节点(刷新页面生效)</label></p>';
preferenceContent += '<p><hr/></p>';
preferenceContent += '<p><button id="reset_preference">重置</button></p>';
//preferenceContent += '<p><label><b style="color:red">有些偏好设置会在你下次刷新页面时生效</b></label></p>';
preferenceContent += '</div>';
//todo 偏好设置暂时都在这里处理
//用于在reset所有偏好时,清除这个dialog下的所有偏好
var allPreferences = {};
function checkEverything( km, $w ) {
checkExpand( km, $w )
}
function initEverything( km, $w ) {
initExpand( km, $w )
}
//展开
function initExpand( km, $w ) {
var expand = km.getOptions( 'defaultExpand' );
$w.find( '[name=expand]' )[ 0 ].checked = expand && expand.defaultLayer == 0;
allPreferences[ 'defaultExpand' ] = null;
}
function checkExpand( km, $w ) {
var checked = $w.find( '[name=expand]' )[ 0 ].checked;
if ( checked ) {
km.setPreferences( 'defaultExpand', {
'defaultLayer': 0,
'defaultSubShow': 0
} )
} else {
km.setPreferences( 'defaultExpand' )
}
}
//重置偏好
function resetPreferences( km ) {
km.setPreferences( allPreferences )
}
KM.registerWidget( 'preference', {
tpl: preferenceContent,
initContent: function ( km ) {
var lang = km.getLang( 'dialogs.help' ),
html;
if ( lang ) {
html = $.parseTmpl( this.tpl, lang );
}
this.root().html( html );
},
initEvent: function ( km, $w ) {
//绑定默认值
initEverything( km, $w );
$w.find( '#reset_preference' ).on( 'click', function ( e ) {
resetPreferences( km );
//重置系统默认的偏好设置
initEverything( km, $w )
} );
$w.on( 'click', '.kmui-close', function ( e ) {
checkEverything( km, $w );
km.fire( 'preferencechange' )
} );
},
width: 400
} );
} )();
\ No newline at end of file
(function(utils) {
KM.registerWidget('resource', {
tpl: '<div class="resource-container">' +
'<div class="add-resource">' +
'<input type="text" /><button class="button">添加</button>' +
'<ul class="global-resource"></ul>' +
'</div>' +
'</div>' +
'<div class="no-selected">未选中节点</div>',
initContent: function(km, $w) {
var lang = km.getLang('dialogs.resource'),
html = $.parseTmpl(this.tpl, lang);
this.root().html(html);
},
initEvent: function(km, $w) {
var $container = $w.find('.resource-container');
var $noSelected = $w.find('.no-selected');
var $current = $w.find('.current-resource').hide();
var $addInput = $w.find('.add-resource input');
var $addButton = $w.find('.add-resource button');
var $global = $w.find('.global-resource');
function switchDisplay() {
if (!km.getSelectedNodes().length) {
$container.hide();
$noSelected.show();
} else {
$container.show();
$noSelected.hide();
}
}
function addResource() {
var resource = $addInput.val();
var origin = km.queryCommandValue('resource');
if (resource) {
origin.push(resource);
km.execCommand('resource', origin);
}
$addInput.val(null);
}
$addInput.on('inputcomplete', function(e) {
addResource();
});
$addButton.on('click', addResource);
switchDisplay();
$global.delegate('input[type=checkbox]', 'change', function() {
km.execCommand('resource', $global.find('input[type=checkbox]:checked').map(function(index, chk) {
return $(chk).data('resource');
}).toArray());
});
km.on('interactchange', function(e) {
var resource = this.queryCommandValue("resource");
var used = this.getUsedResource();
switchDisplay();
$global.empty().append(used.map(function(name) {
var $li = $('<li></li>'),
$label = $('<label></label>').appendTo($li),
$chk = $('<input type="checkbox" />')
.data('resource', name)
.prop('checked', ~resource.indexOf(name))
.appendTo($label);
$label.append(name);
var color = km.getResourceColor(name);
return $li.css({
color: color.dec('l', 60).toString(),
backgroundColor: ~resource.indexOf(name) ? color : color.dec('a', 0.85).toRGBA()
});
}));
}).fire('interactchange');
},
width: 250
});
})(KM.Utils);
\ No newline at end of file
Subproject commit 94c73eb27e9e8d12bdc3b63fd9f0aded9d1c359d
......@@ -3,75 +3,135 @@
*/
(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.compatibility.js',
'core/minder.data.js',
'core/minder.event.js',
'core/minder.module.js',
'core/minder.command.js',
'core/minder.node.js',
'core/minder.select.js',
'core/keymap.js',
'core/minder.lang.js',
'core/minder.defaultoptions.js',
'core/minder.preference.js',
'core/browser.js',
'core/layout.js',
'core/connect.js',
'core/render.js',
'core/theme.js',
'core/template.js',
'layout/default.js',
'layout/default.connect.js',
'layout/bottom.js',
'layout/filetree.js',
'theme/default.js',
'theme/snow.js',
'theme/fresh.js',
'template/structure.js',
'module/node.js',
'module/text.js',
'module/expand.js',
'module/outline.js',
'module/geometry.js',
'module/history.js',
'module/progress.js',
'module/priority.js',
'module/image.js',
'module/resource.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/hyperlink.js',
'module/arrange.js',
'module/paste.js',
'module/style.js',
'protocal/xmind.js',
'protocal/freemind.js',
'protocal/mindmanager.js',
'protocal/plain.js',
'protocal/json.js',
'protocal/png.js',
'protocal/svg.js'
/* Kity 依赖库 */
'lib/kity/dist/kity.js',
/* 核心代码 */
'src/core/kityminder.js',
'src/core/utils.js',
'src/core/command.js',
'src/core/node.js',
'src/core/module.js',
'src/core/event.js',
'src/core/minder.js',
'src/core/minder.data.compatibility.js',
'src/core/minder.data.js',
'src/core/minder.event.js',
'src/core/minder.module.js',
'src/core/minder.command.js',
'src/core/minder.node.js',
'src/core/minder.select.js',
'src/core/keymap.js',
'src/core/minder.lang.js',
'src/core/minder.defaultoptions.js',
'src/core/minder.preference.js',
'src/core/browser.js',
'src/core/layout.js',
'src/core/connect.js',
'src/core/render.js',
'src/core/theme.js',
'src/core/template.js',
/* 布局 */
'src/layout/default.js',
'src/layout/default.connect.js',
'src/layout/bottom.js',
'src/layout/filetree.js',
/* 皮肤 */
'src/theme/default.js',
'src/theme/snow.js',
'src/theme/fresh.js',
/* 模板 */
'src/template/structure.js',
/* 模块 */
'src/module/node.js',
'src/module/text.js',
'src/module/expand.js',
'src/module/outline.js',
'src/module/geometry.js',
'src/module/history.js',
'src/module/progress.js',
'src/module/priority.js',
'src/module/image.js',
'src/module/resource.js',
'src/module/view.js',
'src/module/dragtree.js',
'src/module/dropfile.js',
'src/module/keyboard.js',
'src/module/select.js',
'src/module/history.js',
'src/module/editor.js',
'src/module/editor.range.js',
'src/module/editor.receiver.js',
'src/module/editor.selection.js',
'src/module/basestyle.js',
'src/module/font.js',
'src/module/zoom.js',
'src/module/hyperlink.js',
'src/module/arrange.js',
'src/module/paste.js',
'src/module/style.js',
/* 格式支持 */
'src/protocal/xmind.js',
'src/protocal/freemind.js',
'src/protocal/mindmanager.js',
'src/protocal/plain.js',
'src/protocal/json.js',
'src/protocal/png.js',
'src/protocal/svg.js',
/* UI 依赖库 */
'lib/jquery-2.1.0.min.js',
'lib/promise-1.0.0.js',
'lib/ZeroClipboard.min.js',
'lib/fui/dev-lib/jhtmls.min.js',
'lib/fui/dist/fui.all.js',
'lib/fio/dist/fio.js',
'lib/fio/provider/netdisk/netdisk.js',
/* 导入依赖 */
'lib/jquery.xml2json.js',
'lib/zip.js',
/* UI 代码 */
'ui/ui.js',
'ui/fuix.js',
'ui/mainmenu.js',
'ui/commandbutton.js',
'ui/commandbuttonset.js',
'ui/commandinputmenu.js',
'ui/history.js',
'ui/tabs.js',
'ui/title.js',
'ui/account.js',
'ui/template.js',
'ui/theme.js',
'ui/layout.js',
'ui/style.js',
'ui/font.js',
'ui/color.js',
'ui/insertnode.js',
'ui/arrange.js',
'ui/nodeop.js',
'ui/priority.js',
'ui/progress.js',
'ui/resource.js',
'ui/attachment.js',
'ui/link.js',
'ui/image.js'
];
var basePath = 'src/';
if (typeof(module) === 'object' && module.exports) {
module.exports = paths;
} else if (document) {
while (paths.length) {
document.write('<script type="text/javascript" src="' + basePath + paths.shift() + '"></script>');
/* jshint browser:true */
window.document.write('<script type="text/javascript" src="' + paths.shift() + '"></script>');
}
}
})();
\ No newline at end of file
......@@ -9,31 +9,13 @@
<title>百度脑图 - 便捷的思维导图工具</title>
<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">
/* global ZeroClipboard: true */
ZeroClipboard.setDefaults({ moviePath: 'lib/ZeroClipboard.swf' });
</script>
<script src="kity/dist/kity.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="fui/dev-lib/jhtmls.min.js"></script>
<script src="fui/dist/fui.all.js"></script>
<script src="ui/ui.js" charset="utf-8"></script>
<script src="lib/zip.js" charset="utf-8"></script>
<script>
/* global zip: true */
zip.inflateJSPath = 'lib/inflate.js';
</script>
<script src="lib/jquery.xml2json.js" charset="utf-8"></script>
<link rel="stylesheet" href="fui/theme/default/fui.all.css" />
<link rel="stylesheet" href="lib/fui/theme/default/fui.all.css" />
<link href="ui/theme/default/css/default.all.css" type="text/css" rel="stylesheet" />
<link href="favicon.ico" type="image/x-icon" rel="shortcut icon">
<link href="favicon.ico" type="image/x-icon" rel="apple-touch-icon-precomposed">
</head>
......@@ -113,16 +95,24 @@
<!--脑图启动代码-->
<script>
/* global km:true */
/* jshint browser:true */
// create km instance
km = KM.getMinder('kityminder', window.KITYMINDER_CONFIG);
// init ui for instance
km.initUI();
/* global km:true, ZeroClipboard:true, zip:true */
/* jshint browser:true */
$(function() {
/* 依赖库初始化 */
ZeroClipboard.setDefaults({ moviePath: 'lib/ZeroClipboard.swf' });
zip.inflateJSPath = 'lib/inflate.js';
});
// create km instance
km = KM.getMinder('kityminder', window.KITYMINDER_CONFIG);
// init ui for instance
km.initUI();
// New Version Notify
$(function() {
// New Version Notify
$(function() {
var lastVersion = localStorage.lastKMVersion;
$('#km-version').text( 'v' + KM.version );
......@@ -131,19 +121,19 @@
$( '#km-version' ).addClass( 'new-version' );
localStorage.lastKMVersion = KM.version;
}
});
});
km.on('unziperror', function(ev) {
alert('文件解析错误,文件可能已损坏!');
});
km.on('unziperror', function(ev) {
window.alert('文件解析错误,文件可能已损坏!');
});
km.on('parseerror', function(ev) {
alert('文件解析错误,文件可能已损坏!');
});
km.on('parseerror', function(ev) {
window.alert('文件解析错误,文件可能已损坏!');
});
km.on('unknownprotocal', function(ev) {
alert('不支持的文件格式!');
});
km.on('unknownprotocal', function(ev) {
window.alert('不支持的文件格式!');
});
</script>
......
Subproject commit fec9187f532aea5284d1fac25767dcca9ad43ce4
(function() {
window.KITYMINDER_CONFIG = {
// 定义
//modules: [],
......
......@@ -6,4 +6,6 @@
* 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
!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
Subproject commit 60076bbe6543f4874d1c7d0bab15b20d63657e72
Subproject commit 1d06c3d95c08e412abc67e7abd063db75d731867
Subproject commit f83c5f109addefd4f89ba11b4dfa88c191809e77
!function(){var a,b,c,d;!function(){var e={},f={};a=function(a,b,c){e[a]={deps:b,callback:c}},d=c=b=function(a){function c(b){if("."!==b.charAt(0))return b;for(var c=b.split("/"),d=a.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(d._eak_seen=e,f[a])return f[a];if(f[a]={},!e[a])throw new Error("Could not find module "+a);for(var g,h=e[a],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)"exports"===i[l]?k.push(g={}):k.push(b(c(i[l])));var n=j.apply(this,k);return f[a]=g||n}}(),a("promise/all",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){f(a,b)}}function f(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&e(g.then)?g.then(d(j),c):f(j,g)})}var d=a.isArray,e=a.isFunction;b.all=c}),a("promise/asap",["exports"],function(a){"use strict";function b(){return function(){process.nextTick(e)}}function c(){var a=0,b=new i(e),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function d(){return function(){j.setTimeout(e,1)}}function e(){for(var a=0;a<k.length;a++){var b=k[a],c=b[0],d=b[1];c(d)}k=[]}function f(a,b){var c=k.push([a,b]);1===c&&g()}var g,h="undefined"!=typeof window?window:{},i=h.MutationObserver||h.WebKitMutationObserver,j="undefined"!=typeof global?global:this,k=[];g="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():i?c():d(),a.asap=f}),a("promise/cast",["exports"],function(a){"use strict";function b(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}a.cast=b}),a("promise/config",["exports"],function(a){"use strict";function b(a,b){return 2!==arguments.length?c[a]:(c[a]=b,void 0)}var c={instrument:!1};a.config=c,a.configure=b}),a("promise/polyfill",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(){var a="Promise"in window&&"cast"in window.Promise&&"resolve"in window.Promise&&"reject"in window.Promise&&"all"in window.Promise&&"race"in window.Promise&&function(){var a;return new window.Promise(function(b){a=b}),f(a)}();a||(window.Promise=e)}var e=a.Promise,f=b.isFunction;c.polyfill=d}),a("promise/promise",["./config","./utils","./cast","./all","./race","./resolve","./reject","./asap","exports"],function(a,b,c,d,e,f,g,h,i){"use strict";function j(a){if(!w(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof j))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],k(a,this)}function k(a,b){function c(a){p(b,a)}function d(a){r(b,a)}try{a(c,d)}catch(e){d(e)}}function l(a,b,c,d){var e,f,g,h,i=w(c);if(i)try{e=c(d),g=!0}catch(j){h=!0,f=j}else e=d,g=!0;o(b,e)||(i&&g?p(b,e):h?r(b,f):a===F?p(b,e):a===G&&r(b,e))}function m(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+F]=c,e[f+G]=d}function n(a,b){for(var c,d,e=a._subscribers,f=a._detail,g=0;g<e.length;g+=3)c=e[g],d=e[g+b],l(b,c,d,f);a._subscribers=null}function o(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(v(b)&&(d=b.then,w(d)))return d.call(b,function(d){return c?!0:(c=!0,b!==d?p(a,d):q(a,d),void 0)},function(b){return c?!0:(c=!0,r(a,b),void 0)}),!0}catch(e){return c?!0:(r(a,e),!0)}return!1}function p(a,b){a===b?q(a,b):o(a,b)||q(a,b)}function q(a,b){a._state===D&&(a._state=E,a._detail=b,u.async(s,a))}function r(a,b){a._state===D&&(a._state=E,a._detail=b,u.async(t,a))}function s(a){n(a,a._state=F)}function t(a){n(a,a._state=G)}var u=a.config,v=(a.configure,b.objectOrFunction),w=b.isFunction,x=(b.now,c.cast),y=d.all,z=e.race,A=f.resolve,B=g.reject,C=h.asap;u.async=C;var D=void 0,E=0,F=1,G=2;j.prototype={constructor:j,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;u.async(function(){l(c._state,d,e[c._state-1],c._detail)})}else m(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},j.all=y,j.cast=x,j.race=z,j.resolve=A,j.reject=B,i.Promise=j}),a("promise/race",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var d=a.isArray;b.race=c}),a("promise/reject",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b,c){c(a)})}a.reject=b}),a("promise/resolve",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b){b(a)})}a.resolve=b}),a("promise/utils",["exports"],function(a){"use strict";function b(a){return c(a)||"object"==typeof a&&null!==a}function c(a){return"function"==typeof a}function d(a){return"[object Array]"===Object.prototype.toString.call(a)}var e=Date.now||function(){return(new Date).getTime()};a.objectOrFunction=b,a.isFunction=c,a.isArray=d,a.now=e}),b("promise/polyfill").polyfill()}();
\ No newline at end of file
(function() {
var define, requireModule, require, requirejs;
(function() {
var registry = {}, seen = {};
define = function(name, deps, callback) {
registry[name] = { deps: deps, callback: callback };
};
requirejs = require = requireModule = function(name) {
requirejs._eak_seen = registry;
if (seen[name]) { return seen[name]; }
seen[name] = {};
if (!registry[name]) {
throw new Error("Could not find module " + name);
}
var mod = registry[name],
deps = mod.deps,
callback = mod.callback,
reified = [],
exports;
for (var i=0, l=deps.length; i<l; i++) {
if (deps[i] === 'exports') {
reified.push(exports = {});
} else {
reified.push(requireModule(resolve(deps[i])));
}
}
var value = callback.apply(this, reified);
return seen[name] = exports || value;
function resolve(child) {
if (child.charAt(0) !== '.') { return child; }
var parts = child.split("/");
var parentBase = name.split("/").slice(0, -1);
for (var i=0, l=parts.length; i<l; i++) {
var part = parts[i];
if (part === '..') { parentBase.pop(); }
else if (part === '.') { continue; }
else { parentBase.push(part); }
}
return parentBase.join("/");
}
};
})();
define("promise/all",
["./utils","exports"],
function(__dependency1__, __exports__) {
"use strict";
/* global toString */
var isArray = __dependency1__.isArray;
var isFunction = __dependency1__.isFunction;
/**
Returns a promise that is fulfilled when all the given promises have been
fulfilled, or rejected if any of them become rejected. The return promise
is fulfilled with an array that gives all the values in the order they were
passed in the `promises` array argument.
Example:
```javascript
var promise1 = RSVP.resolve(1);
var promise2 = RSVP.resolve(2);
var promise3 = RSVP.resolve(3);
var promises = [ promise1, promise2, promise3 ];
RSVP.all(promises).then(function(array){
// The array here would be [ 1, 2, 3 ];
});
```
If any of the `promises` given to `RSVP.all` are rejected, the first promise
that is rejected will be given as an argument to the returned promises's
rejection handler. For example:
Example:
```javascript
var promise1 = RSVP.resolve(1);
var promise2 = RSVP.reject(new Error("2"));
var promise3 = RSVP.reject(new Error("3"));
var promises = [ promise1, promise2, promise3 ];
RSVP.all(promises).then(function(array){
// Code here never runs because there are rejected promises!
}, function(error) {
// error.message === "2"
});
```
@method all
@for RSVP
@param {Array} promises
@param {String} label
@return {Promise} promise that is fulfilled when all `promises` have been
fulfilled, or rejected if any of them become rejected.
*/
function all(promises) {
/*jshint validthis:true */
var Promise = this;
if (!isArray(promises)) {
throw new TypeError('You must pass an array to all.');
}
return new Promise(function(resolve, reject) {
var results = [], remaining = promises.length,
promise;
if (remaining === 0) {
resolve([]);
}
function resolver(index) {
return function(value) {
resolveAll(index, value);
};
}
function resolveAll(index, value) {
results[index] = value;
if (--remaining === 0) {
resolve(results);
}
}
for (var i = 0; i < promises.length; i++) {
promise = promises[i];
if (promise && isFunction(promise.then)) {
promise.then(resolver(i), reject);
} else {
resolveAll(i, promise);
}
}
});
}
__exports__.all = all;
});
define("promise/asap",
["exports"],
function(__exports__) {
"use strict";
var browserGlobal = (typeof window !== 'undefined') ? window : {};
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
var local = (typeof global !== 'undefined') ? global : (this === undefined? window:this);
// node
function useNextTick() {
return function() {
process.nextTick(flush);
};
}
function useMutationObserver() {
var iterations = 0;
var observer = new BrowserMutationObserver(flush);
var node = document.createTextNode('');
observer.observe(node, { characterData: true });
return function() {
node.data = (iterations = ++iterations % 2);
};
}
function useSetTimeout() {
return function() {
local.setTimeout(flush, 1);
};
}
var queue = [];
function flush() {
for (var i = 0; i < queue.length; i++) {
var tuple = queue[i];
var callback = tuple[0], arg = tuple[1];
callback(arg);
}
queue = [];
}
var scheduleFlush;
// Decide what async method to use to triggering processing of queued callbacks:
if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') {
scheduleFlush = useNextTick();
} else if (BrowserMutationObserver) {
scheduleFlush = useMutationObserver();
} else {
scheduleFlush = useSetTimeout();
}
function asap(callback, arg) {
var length = queue.push([callback, arg]);
if (length === 1) {
// If length is 1, that means that we need to schedule an async flush.
// If additional callbacks are queued before the queue is flushed, they
// will be processed by this flush that we are scheduling.
scheduleFlush();
}
}
__exports__.asap = asap;
});
define("promise/config",
["exports"],
function(__exports__) {
"use strict";
var config = {
instrument: false
};
function configure(name, value) {
if (arguments.length === 2) {
config[name] = value;
} else {
return config[name];
}
}
__exports__.config = config;
__exports__.configure = configure;
});
define("promise/polyfill",
["./promise","./utils","exports"],
function(__dependency1__, __dependency2__, __exports__) {
"use strict";
/*global self*/
var RSVPPromise = __dependency1__.Promise;
var isFunction = __dependency2__.isFunction;
function polyfill() {
var local;
if (typeof global !== 'undefined') {
local = global;
} else if (typeof window !== 'undefined' && window.document) {
local = window;
} else {
local = self;
}
var es6PromiseSupport =
"Promise" in local &&
// Some of these methods are missing from
// Firefox/Chrome experimental implementations
"resolve" in local.Promise &&
"reject" in local.Promise &&
"all" in local.Promise &&
"race" in local.Promise &&
// Older version of the spec had a resolver object
// as the arg rather than a function
(function() {
var resolve;
new local.Promise(function(r) { resolve = r; });
return isFunction(resolve);
}());
if (!es6PromiseSupport) {
local.Promise = RSVPPromise;
}
}
__exports__.polyfill = polyfill;
});
define("promise/promise",
["./config","./utils","./all","./race","./resolve","./reject","./asap","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
"use strict";
var config = __dependency1__.config;
var configure = __dependency1__.configure;
var objectOrFunction = __dependency2__.objectOrFunction;
var isFunction = __dependency2__.isFunction;
var now = __dependency2__.now;
var all = __dependency3__.all;
var race = __dependency4__.race;
var staticResolve = __dependency5__.resolve;
var staticReject = __dependency6__.reject;
var asap = __dependency7__.asap;
var counter = 0;
config.async = asap; // default async is asap;
function Promise(resolver) {
if (!isFunction(resolver)) {
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
}
if (!(this instanceof Promise)) {
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
}
this._subscribers = [];
invokeResolver(resolver, this);
}
function invokeResolver(resolver, promise) {
function resolvePromise(value) {
resolve(promise, value);
}
function rejectPromise(reason) {
reject(promise, reason);
}
try {
resolver(resolvePromise, rejectPromise);
} catch(e) {
rejectPromise(e);
}
}
function invokeCallback(settled, promise, callback, detail) {
var hasCallback = isFunction(callback),
value, error, succeeded, failed;
if (hasCallback) {
try {
value = callback(detail);
succeeded = true;
} catch(e) {
failed = true;
error = e;
}
} else {
value = detail;
succeeded = true;
}
if (handleThenable(promise, value)) {
return;
} else if (hasCallback && succeeded) {
resolve(promise, value);
} else if (failed) {
reject(promise, error);
} else if (settled === FULFILLED) {
resolve(promise, value);
} else if (settled === REJECTED) {
reject(promise, value);
}
}
var PENDING = void 0;
var SEALED = 0;
var FULFILLED = 1;
var REJECTED = 2;
function subscribe(parent, child, onFulfillment, onRejection) {
var subscribers = parent._subscribers;
var length = subscribers.length;
subscribers[length] = child;
subscribers[length + FULFILLED] = onFulfillment;
subscribers[length + REJECTED] = onRejection;
}
function publish(promise, settled) {
var child, callback, subscribers = promise._subscribers, detail = promise._detail;
for (var i = 0; i < subscribers.length; i += 3) {
child = subscribers[i];
callback = subscribers[i + settled];
invokeCallback(settled, child, callback, detail);
}
promise._subscribers = null;
}
Promise.prototype = {
constructor: Promise,
_state: undefined,
_detail: undefined,
_subscribers: undefined,
then: function(onFulfillment, onRejection) {
var promise = this;
var thenPromise = new this.constructor(function() {});
if (this._state) {
var callbacks = arguments;
config.async(function invokePromiseCallback() {
invokeCallback(promise._state, thenPromise, callbacks[promise._state - 1], promise._detail);
});
} else {
subscribe(this, thenPromise, onFulfillment, onRejection);
}
return thenPromise;
},
'catch': function(onRejection) {
return this.then(null, onRejection);
}
};
Promise.all = all;
Promise.race = race;
Promise.resolve = staticResolve;
Promise.reject = staticReject;
function handleThenable(promise, value) {
var then = null,
resolved;
try {
if (promise === value) {
throw new TypeError("A promises callback cannot return that same promise.");
}
if (objectOrFunction(value)) {
then = value.then;
if (isFunction(then)) {
then.call(value, function(val) {
if (resolved) { return true; }
resolved = true;
if (value !== val) {
resolve(promise, val);
} else {
fulfill(promise, val);
}
}, function(val) {
if (resolved) { return true; }
resolved = true;
reject(promise, val);
});
return true;
}
}
} catch (error) {
if (resolved) { return true; }
reject(promise, error);
return true;
}
return false;
}
function resolve(promise, value) {
if (promise === value) {
fulfill(promise, value);
} else if (!handleThenable(promise, value)) {
fulfill(promise, value);
}
}
function fulfill(promise, value) {
if (promise._state !== PENDING) { return; }
promise._state = SEALED;
promise._detail = value;
config.async(publishFulfillment, promise);
}
function reject(promise, reason) {
if (promise._state !== PENDING) { return; }
promise._state = SEALED;
promise._detail = reason;
config.async(publishRejection, promise);
}
function publishFulfillment(promise) {
publish(promise, promise._state = FULFILLED);
}
function publishRejection(promise) {
publish(promise, promise._state = REJECTED);
}
__exports__.Promise = Promise;
});
define("promise/race",
["./utils","exports"],
function(__dependency1__, __exports__) {
"use strict";
/* global toString */
var isArray = __dependency1__.isArray;
/**
`RSVP.race` allows you to watch a series of promises and act as soon as the
first promise given to the `promises` argument fulfills or rejects.
Example:
```javascript
var promise1 = new RSVP.Promise(function(resolve, reject){
setTimeout(function(){
resolve("promise 1");
}, 200);
});
var promise2 = new RSVP.Promise(function(resolve, reject){
setTimeout(function(){
resolve("promise 2");
}, 100);
});
RSVP.race([promise1, promise2]).then(function(result){
// result === "promise 2" because it was resolved before promise1
// was resolved.
});
```
`RSVP.race` is deterministic in that only the state of the first completed
promise matters. For example, even if other promises given to the `promises`
array argument are resolved, but the first completed promise has become
rejected before the other promises became fulfilled, the returned promise
will become rejected:
```javascript
var promise1 = new RSVP.Promise(function(resolve, reject){
setTimeout(function(){
resolve("promise 1");
}, 200);
});
var promise2 = new RSVP.Promise(function(resolve, reject){
setTimeout(function(){
reject(new Error("promise 2"));
}, 100);
});
RSVP.race([promise1, promise2]).then(function(result){
// Code here never runs because there are rejected promises!
}, function(reason){
// reason.message === "promise2" because promise 2 became rejected before
// promise 1 became fulfilled
});
```
@method race
@for RSVP
@param {Array} promises array of promises to observe
@param {String} label optional string for describing the promise returned.
Useful for tooling.
@return {Promise} a promise that becomes fulfilled with the value the first
completed promises is resolved with if the first completed promise was
fulfilled, or rejected with the reason that the first completed promise
was rejected with.
*/
function race(promises) {
/*jshint validthis:true */
var Promise = this;
if (!isArray(promises)) {
throw new TypeError('You must pass an array to race.');
}
return new Promise(function(resolve, reject) {
var results = [], promise;
for (var i = 0; i < promises.length; i++) {
promise = promises[i];
if (promise && typeof promise.then === 'function') {
promise.then(resolve, reject);
} else {
resolve(promise);
}
}
});
}
__exports__.race = race;
});
define("promise/reject",
["exports"],
function(__exports__) {
"use strict";
/**
`RSVP.reject` returns a promise that will become rejected with the passed
`reason`. `RSVP.reject` is essentially shorthand for the following:
```javascript
var promise = new RSVP.Promise(function(resolve, reject){
reject(new Error('WHOOPS'));
});
promise.then(function(value){
// Code here doesn't run because the promise is rejected!
}, function(reason){
// reason.message === 'WHOOPS'
});
```
Instead of writing the above, your code now simply becomes the following:
```javascript
var promise = RSVP.reject(new Error('WHOOPS'));
promise.then(function(value){
// Code here doesn't run because the promise is rejected!
}, function(reason){
// reason.message === 'WHOOPS'
});
```
@method reject
@for RSVP
@param {Any} reason value that the returned promise will be rejected with.
@param {String} label optional string for identifying the returned promise.
Useful for tooling.
@return {Promise} a promise that will become rejected with the given
`reason`.
*/
function reject(reason) {
/*jshint validthis:true */
var Promise = this;
return new Promise(function (resolve, reject) {
reject(reason);
});
}
__exports__.reject = reject;
});
define("promise/resolve",
["exports"],
function(__exports__) {
"use strict";
function resolve(value) {
/*jshint validthis:true */
if (value && typeof value === 'object' && value.constructor === this) {
return value;
}
var Promise = this;
return new Promise(function(resolve) {
resolve(value);
});
}
__exports__.resolve = resolve;
});
define("promise/utils",
["exports"],
function(__exports__) {
"use strict";
function objectOrFunction(x) {
return isFunction(x) || (typeof x === "object" && x !== null);
}
function isFunction(x) {
return typeof x === "function";
}
function isArray(x) {
return Object.prototype.toString.call(x) === "[object Array]";
}
// Date.now is not available in browsers < IE9
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Compatibility
var now = Date.now || function() { return new Date().getTime(); };
__exports__.objectOrFunction = objectOrFunction;
__exports__.isFunction = isFunction;
__exports__.isArray = isArray;
__exports__.now = now;
});
requireModule('promise/polyfill').polyfill();
}());
\ No newline at end of file
.niceblue{color:#fff;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%);}
.dropdown{padding-right:28px;position:relative}.dropdown:after{content:' ';display:block;position:absolute;right:10px;top:12px;width:0;height:0;border:solid;border-width:4px 5px;border-color:#333 transparent transparent transparent}
.dropdown:active:after,.dropdown.active:after{border-color:#fff transparent transparent transparent}
button{font-family:Arial,"Heiti SC","Microsoft Yahei";outline:none;display:inline-block;vertical-align:middle;padding:0 15px;height:30px;font-size:13px;line-height:30px;text-align:center;color:#000;text-decoration:none;border:none;margin-left:5px;background:none;color:#fff;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,button.active{background:#007fcc;box-shadow:inset 0 2px 3px rgba(0,0,0,0.2)}
button[disabled]{cursor:default;background:#ccc}
.draft-menu.kmui-dropdown-menu{margin-top:24px;margin-left:1px}.draft-menu.kmui-dropdown-menu span.update-time{float:right;color:#ccc;margin-left:40px;padding-right:16px}
.draft-menu.kmui-dropdown-menu li.draft-item a{position:relative}.draft-menu.kmui-dropdown-menu li.draft-item a:before{content:' ';display:block;width:24px;height:24px;background:url(../themes/default/images/draft.png) no-repeat 0 -24px;position:absolute;left:4px;top:2px}
.draft-menu.kmui-dropdown-menu li.draft-item:hover a:before{background-position:0 -48px}
.draft-menu.kmui-dropdown-menu li.draft-item{position:relative}.draft-menu.kmui-dropdown-menu li.draft-item:hover a.delete{display:block}
.draft-menu.kmui-dropdown-menu li.draft-item a.delete{display:none;cursor:pointer;position:absolute;width:20px;height:20px;right:4px;top:4px;padding:0;background:url(../themes/default/images/close-button.png) no-repeat 0 0}.draft-menu.kmui-dropdown-menu li.draft-item a.delete:before{display:none}
.draft-menu.kmui-dropdown-menu li.draft-item a.delete:hover{background-position:0 -20px}
.draft-menu.kmui-dropdown-menu.kmui-combobox-menu .kmui-combobox-checked{overflow:hidden;opacity:1;color:#ccc}.draft-menu.kmui-dropdown-menu.kmui-combobox-menu .kmui-combobox-checked .kmui-combobox-icon{float:left;margin:5px 0;width:28px;background-position:center 0;opacity:.3}
.draft-menu.kmui-dropdown-menu.kmui-combobox-menu .kmui-combobox-checked .kmui-combobox-item-label{display:block;margin-left:28px}
.draft-menu.kmui-dropdown-menu.kmui-combobox-menu .kmui-combobox-checked:hover{color:#ccc}.draft-menu.kmui-dropdown-menu.kmui-combobox-menu .kmui-combobox-checked:hover .kmui-combobox-icon{background-position:center 0}
.file-menu.kmui-dropdown-menu{margin-top:24px;margin-left:1px;box-shadow:0 1px 5px rgba(0,0,0,0.3)}.file-menu.kmui-dropdown-menu #save-button,.file-menu.kmui-dropdown-menu #manage-file-button{display:none}
.file-menu.kmui-dropdown-menu.logined #save-button,.file-menu.kmui-dropdown-menu.logined #manage-file-button{display:block}
.file-menu.kmui-dropdown-menu.logined #net-hint-buttom{display:none}
.user-menu.kmui-dropdown-menu{margin-top:24px;margin-left:-25px;min-width:130px;box-shadow:0 1px 5px rgba(0,0,0,0.3)}.user-menu.kmui-dropdown-menu li a{padding-left:40px}
#share-dialog{position:absolute;padding:20px;left:50%;top:40%;margin-left:-175px;margin-top:-100px;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:255px;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 #copy-share-url{display:inline-block;margin:0;width:75px;height:28px;line-height:28px;vertical-align:middle;color:#fff;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%);}#share-dialog #copy-share-url:hover,#share-dialog #copy-share-url.hover{background:#009fff}
#share-dialog #copy-share-url:active,#share-dialog #copy-share-url.active{background:#007fcc;box-shadow:inset 0 2px 3px rgba(0,0,0,0.2)}
#share-dialog #share-platform{margin-bottom:0}
{"version":3,"file":"social.css","sources":["social.less"],"names":[],"mappings":"AAAA;EACI,YAAA;EACA,YAAY,+DAAZ;;EACA,YAAY,gDAAgD,yBAAwB,yBAAwB,0BAA5G;;EACA,YAAY,kEAAZ;;EACA,YAAY,6DAAZ;;EACA,YAAY,8DAAZ;;EACA,YAAY,gEAAZ;;;AAGJ;EACI,mBAAA;EACA,kBAAA;;AACA,SAAC;EACG,SAAS,GAAT;EACA,cAAA;EACA,kBAAA;EACA,WAAA;EACA,SAAA;EACA,QAAA;EACA,SAAA;EACA,aAAA;EACA,qBAAA;EACA,sDAAA;;AAGA,SADH,OACI;AAAD,SADO,OACN;EACG,sDAAA;;AAKZ;EACI,oBAAoB,YAAY,iBAAhC;EACA,aAAA;EACA,qBAAA;EACA,sBAAA;EACA,eAAA;EACA,YAAA;EACA,eAAA;EACA,iBAAA;EACA,kBAAA;EACA,WAAA;EACA,qBAAA;EACA,YAAA;EACA,gBAAA;EACA,gBAAA;EA7CA,YAAA;EACA,YAAY,+DAAZ;;EACA,YAAY,gDAAgD,yBAAwB,yBAAwB,0BAA5G;;EACA,YAAY,kEAAZ;;EACA,YAAY,6DAAZ;;EACA,YAAY,8DAAZ;;EACA,YAAY,gEAAZ;;;AA2CA,MAAC;AAAQ,MAAC;EACN,mBAAA;;AAGJ,MAAC;AAAS,MAAC;EACP,mBAAA;EACA,8CAAA;;AAGJ,MAAC;EACG,eAAA;EACA,gBAAA;;AAIR,WAAW;EACP,gBAAA;EACA,gBAAA;;AAFJ,WAAW,mBAGP,KAAI;EACA,YAAA;EACA,WAAA;EACA,iBAAA;EACA,mBAAA;;AAPR,WAAW,mBASP,GAAE,WAAY;EACV,kBAAA;;AACA,WAXG,mBASP,GAAE,WAAY,EAET;EACG,SAAS,GAAT;EACA,cAAA;EACA,WAAA;EACA,YAAA;EACA,qEAAA;EACA,kBAAA;EACA,SAAA;EACA,QAAA;;AAnBZ,WAAW,mBAsBP,GAAE,WAAW,MAAO,EAAC;EACjB,4BAAA;;AAvBR,WAAW,mBAyBP,GAAE;EACE,kBAAA;;AACA,WA3BG,mBAyBP,GAAE,WAEG,MAAO,EAAC;EACL,cAAA;;AA5BZ,WAAW,mBAyBP,GAAE,WAKE,EAAC;EACG,aAAA;EACA,eAAA;EACA,kBAAA;EACA,WAAA;EACA,YAAA;EACA,UAAA;EACA,QAAA;EACA,UAAA;EACA,wEAAA;;AACA,WAxCD,mBAyBP,GAAE,WAKE,EAAC,OAUI;EACG,aAAA;;AAEJ,WA3CD,mBAyBP,GAAE,WAKE,EAAC,OAaI;EACG,4BAAA;;AAIZ,WAhDO,mBAgDN,mBAAoB;EACjB,gBAAA;EACA,UAAA;EACA,WAAA;;AAHJ,WAhDO,mBAgDN,mBAAoB,uBAIjB;EACI,WAAA;EACA,aAAA;EACA,WAAA;EACA,6BAAA;EACA,WAAA;;AATR,WAhDO,mBAgDN,mBAAoB,uBAWjB;EACI,cAAA;EACA,iBAAA;;AAEJ,WA/DG,mBAgDN,mBAAoB,uBAehB;EACG,WAAA;;AADJ,WA/DG,mBAgDN,mBAAoB,uBAehB,MAEG;EACI,6BAAA;;AAMhB,UAAU;EACN,gBAAA;EACA,gBAAA;EACA,0CAAA;;AAHJ,UAAU,mBAKN;AALJ,UAAU,mBAKQ;EACV,aAAA;;AAGJ,UATM,mBASL,QACG;AADJ,UATM,mBASL,QACiB;EACV,cAAA;;AAFR,UATM,mBASL,QAIG;EACI,aAAA;;AAIZ,UAAU;EACN,gBAAA;EACA,kBAAA;EACA,gBAAA;EACA,0CAAA;;AAJJ,UAAU,mBAMN,GAAG;EACC,kBAAA;;AAIR;EACI,kBAAA;EACA,aAAA;EACA,SAAA;EACA,QAAA;EACA,mBAAA;EACA,kBAAA;EACA,iBAAA;EACA,YAAA;EACA,2CAAA;EACA,aAAA;;AAVJ,aAYI;EACI,SAAA;EACA,eAAA;EACA,WAAA;;AAfR,aAkBI;EACI,YAAA;EACA,YAAA;EACA,iBAAA;EACA,kBAAA;EACA,sBAAA;EACA,sBAAA;EACA,iBAAA;EACA,gBAAA;;AACA,aATJ,MASK;EACG,sBAAA;EACA,aAAA;;AA7BZ,aAiCI;AAjCJ,aAiCO;EACC,mBAAA;;AAlCR,aAqCI;EACI,qBAAA;EACA,SAAA;EACA,WAAA;EACA,YAAA;EACA,iBAAA;EACA,sBAAA;EAhNJ,YAAA;EACA,YAAY,+DAAZ;;EACA,YAAY,gDAAgD,yBAAwB,yBAAwB,0BAA5G;;EACA,YAAY,kEAAZ;;EACA,YAAY,6DAAZ;;EACA,YAAY,8DAAZ;;EACA,YAAY,gEAAZ;;;AAgNI,aAZJ,gBAYK;AAAQ,aAZb,gBAYc;EACN,mBAAA;;AAGJ,aAhBJ,gBAgBK;AAAS,aAhBd,gBAgBe;EACP,mBAAA;EACA,8CAAA;;AAvDZ,aA4DI;EACI,gBAAA"}
\ No newline at end of file
/* global Promise: true */
/**
* 百度脑图社会化功能
*
* 1. 百度账号登录
* 2. 百度云存储
* 3. 分享
* 4. 草稿箱同步
* 5. 配置文件同步
* @author techird
*/
$.extend($.fn, {
disabled: function(value) {
if (value === undefined) return !!this.attr('disabled');
if (value) {
this.attr('disabled', 'disabled');
} else {
this.removeAttr('disabled');
}
return this;
},
loading: function(text) {
if (text) {
this.disabled(true);
this.attr('origin-text', this.text());
this.text(text);
} else {
this.text(this.attr('origin-text'));
this.removeAttr('origin-text');
this.disabled(false);
}
return this;
},
text: (function() {
var originFn = $.fn.text;
return function() {
var textSpan = this.children('span.text');
if (textSpan.length) {
return originFn.apply(textSpan, arguments);
} else {
return originFn.apply(this, arguments);
}
};
})()
});
/**
* 核心业务逻辑
*/
$(function() {
// UI 元素
var $panel, $title, $menu, $user, $share_btn, $save_btn, $file_btn, $tool_btn, $file_menu, $login_btn, $user_btn, $user_menu,
$draft_btn, $draft_menu, $share_dialog, $share_url, $copy_url_btn,
// 当前文件的远端路径
remotePath = null,
// 当前登录的账户
currentAccount,
// 当前连接是否指示要加载一个分享的脑图
isShareLink,
isPathLink,
uuid = function() {
return ((+new Date() * 10000) + (Math.random() * 9999)).toString(36);
},
// 当前脑图的分享ID
shareId = uuid(),
titleSuffix = document.title || '百度脑图',
// 脑图实例
minder = window.km,
// 草稿箱实例
draftManager,
// 当前是否要检测文档内容是否变化的开关
watchingChanges = true,
notice = (function() {
return window.alert;
})(),
wordLimit = function(word, limit) {
limit = limit || 15;
return word.length > limit ? (word.substr(0, limit - 3) + '...') : word;
};
start();
function start() {
initUI();
initFrontia();
if (checkLogin()) {
return;
}
loadShare();
bindShortCuts();
bindDraft();
if (draftManager) watchChanges();
if (draftManager && !loadPath() && !isShareLink) loadDraft(0);
}
function createFileMenu() {
var menus = [{
label: '新建',
click: newFile
}, {
divider: true
}];
// 导入菜单组
var acceptFiles = [];
KityMinder.getSupportedProtocals().forEach(function(name) {
var p = KityMinder.findProtocal(name);
if (p.decode) {
acceptFiles.push(p.fileExtension);
}
});
function importUseEncoding(encoding) {
return function() {
$('<input type="file" />')
.attr('accept', acceptFiles.join(','))
.on('change', function(e) {
e = e.originalEvent;
minder.importFile(e.target.files[0], encoding);
}).click();
};
}
menus = menus.concat([{
label: '导入...',
click: importUseEncoding('utf8')
}, {
label: '以 GBK 编码导入...',
click: importUseEncoding('gbk')
}, {
divider: true
}]);
// 导出菜单组
KityMinder.getSupportedProtocals().forEach(function(name) {
var p = KityMinder.findProtocal(name);
if (p.encode) {
var text = p.fileDescription + '(' + p.fileExtension + ')';
menus.push({
label: '导出 ' + text,
click: function() {
minder.exportFile(name);
}
});
}
});
menus = menus.concat([{
divider: true,
}, {
label: '请登录',
click: login,
id: 'net-hint-buttom'
}, {
label: '保存到百度云 (Ctrl + S)',
click: save,
id: 'save-button'
}, {
divider: true
}]);
return menus;
}
// 创建 UI
function initUI() {
$panel = $('#panel');
$menu = $('<div id="menu"></div>').appendTo($panel);
$user = $('<div id="user"></div>').appendTo($panel);
$title = $('<h1 id="title"></h1>').appendTo($panel);
$file_btn = $('<button id="file-btn">文件</button>').addClass('dropdown').appendTo($menu);
$file_menu = $.kmuidropmenu({
data: createFileMenu()
})
.addClass('file-menu')
.appendTo('body');
$file_menu.kmui().attachTo($file_btn);
$save_btn = $('#save-btn').find('a');
$share_btn = $('<button id="share-btn">分享</button>').click(share).appendTo($user);
$draft_btn = $('<button id="draft-btn">草稿箱</button>').addClass('dropdown').appendTo($menu);
$draft_menu = $.kmuidropmenu().addClass('draft-menu kmui-combobox-menu').appendTo('body');
$draft_menu.kmui().attachTo($draft_btn);
$draft_menu.on('aftershow', showDraftList);
$tool_btn = $('<button id="tool-btn" title="打开/收起工具箱">工具箱</button>').appendTo($menu);
$tool_btn.click(function() {
var hide = !localStorage.hide_toolbar;
$('#kityminder div.kmui-btn-toolbar').css('display', hide ? 'none' : 'block');
if (hide) {
$tool_btn.removeClass('active');
localStorage.hide_toolbar = true;
} else {
$tool_btn.addClass('active');
delete localStorage.hide_toolbar;
}
}).click().click();
$login_btn = $('<button id="login-btn">登录</button>').appendTo($user).click(login);
$user_btn = $('<button id="user-btn">用户</button>').addClass('dropdown').appendTo($user);
$user_menu = $.kmuidropmenu({
data: [{
label: '个人中心',
click: function() {
window.open('http://i.baidu.com/', '_blank');
}
}, {
label: '管理云文件',
click: function() {
window.open('http://pan.baidu.com/disk/home#dir/path=/apps/kityminder');
},
id: 'manage-file-button'
}, {
divider: true,
}, {
label: '注销',
click: logout
}]
}).addClass('user-menu').appendTo('body').kmui().attachTo($user_btn);
$share_dialog = $('#share-dialog');
$share_url = $('#share-url');
$copy_url_btn = $('#copy-share-url');
$share_dialog.mousedown(function(e) {
e.stopPropagation();
});
$('body').delegate('#global-zeroclipboard-html-bridge', 'mousedown', function(e) {
e.stopPropagation();
});
var copyTrickTimer = 0;
$('body').on('mousedown', function(e) {
copyTrickTimer = setTimeout(function() {
$share_dialog.hide();
$share_btn.loading(false);
$copy_url_btn.loading(false);
}, 30);
});
if (window.ZeroClipboard) {
var clip = new window.ZeroClipboard($copy_url_btn, {
hoverClass: 'hover',
activeClass: 'active'
});
clip.on('dataRequested', function(client, args) {
$copy_url_btn.loading('已复制');
clearTimeout(copyTrickTimer);
});
}
}
// 初始化云平台 frontia
function initFrontia() {
var AK = 'wiE55BGOG8BkGnpPs6UNtPbb';
baidu.frontia.init(AK);
baidu.frontia.social.setLoginCallback({
success: setAccount,
error: function(error) {
notice('登录失败!');
}
});
}
// 检查 URL 是否分享连接,是则加载分享内容
function loadShare() {
var pattern = /(?:shareId|share_id)=(\w+)([&#]|$)/;
var match = pattern.exec(window.location) || pattern.exec(document.referrer);
if (!match) return;
var shareId = match[1];
$.ajax({
url: 'http://naotu.baidu.com/mongo.php',
data: {
action: 'find',
id: shareId
},
dataType: 'json',
success: function(data) {
if (data.error) {
return notice(data.error);
}
if (draftManager) {
var draft = draftManager.openByPath('share/' + shareId);
if (draft) {
draftManager.load();
} else {
draftManager.create('share/' + shareId);
minder.importData(data.shareMinder.data, 'json');
}
} else {
minder.importData(data.shareMinder.data, 'json');
}
$title.loading(false);
setRemotePath(null, false);
},
error: function() {
notice('请求分享文件失败,请重试!');
}
});
$title.loading('正在加载分享内容...');
isShareLink = true;
}
// 检查 URL 是否请求加载用户文件,是则加载
function loadPath() {
var pattern = /path=(.+?)([&#]|$)/;
// documemt.referrer 是为了支持被嵌在 iframe 里的情况
var match = pattern.exec(window.location) || pattern.exec(document.referrer);
if (!match) return;
if (!currentAccount) {
setTimeout(function() {
if (!currentAccount) return login();
setRemotePath(decodeURIComponent(match[1], true));
loadRemote();
}, 1000);
return false;
}
setRemotePath(decodeURIComponent(match[1], true));
loadRemote();
return true;
}
function setRemotePath(path, saved) {
var filename;
remotePath = path;
filename = remotePath ? getFileName(remotePath) : minder.getMinderTitle();
if (!saved) filename = '* ' + filename;
$title.text(filename)
document.title = [filename, titleSuffix].join(' - ');
}
// 检查是否在 Cookie 中登录过了
function checkLogin() {
var account = baidu.frontia.getCurrentAccount();
if (account) {
login();
return true;
}
return false;
}
// 用户点击登录按钮主动登录
function login() {
baidu.frontia.social.login({
response_type: 'token',
media_type: 'baidu',
redirect_uri: window.location.href,
client_type: 'web'
});
$login_btn.text('正在登录...').css('text-decoration', 'none');
}
function logout() {
baidu.frontia.logOutCurrentAccount();
setAccount(null);
$file_menu.removeClass('logined');
$user.removeClass('logined');
}
// 设置用户后为其初始化
function setAccount(account) {
currentAccount = account;
if (account) {
loadAvator();
loadUserFiles();
window.location.hash = '';
$user_btn.text(account.accountName);
}
$file_menu.addClass('logined');
$user.addClass('logined');
}
// 加载用户头像
function loadAvator() {
currentAccount.getDetailInfo({
success: function(user) {
$('<img />').attr({
'src': user.extra.headurl,
'width': 32,
'height': 32
}).prependTo($user_btn);
}
});
}
// 加载用户最近使用的文件
function loadUserFiles() {
if (loadUserFiles.tryCount) {
console.warn('加载用户最近使用的文件失败:第 ' + loadUserFiles.tryCount + '次');
}
if (loadUserFiles.tryCount > 3) {
notice('加载最近脑图失败!');
loadUserFiles.tryCount = 0;
return;
}
var sto = baidu.frontia.personalStorage;
if (loadUserFiles.tryCount === 0) {
loadUserFiles.$loadingMenuItem = $file_menu.kmui().appendItem({
item: {
label: '正在加载最近脑图...',
disabled: 'disabled'
}
});
}
sto.listFile('apps/kityminder/', {
by: 'time',
success: function(result) {
if (result.list.length) {
loadUserFiles.$loadingMenuItem.remove();
addToRecentMenu(result.list.filter(function(file) {
return getFileFormat(file.path) in fileLoader;
}));
//syncPreference(result.list);
}
},
error: loadUserFiles
});
loadUserFiles.tryCount++;
}
loadUserFiles.tryCount = 0;
// 同步用户配置文件
function syncPreference(fileList) {
// frontia 接口对象引用
var sto = baidu.frontia.personalStorage;
// 配置文件在网盘的路径
var remotePreferencesPath = '/apps/kityminder/app.preferences';
// 检查是否存在线上的配置文件
var hasRemotePreferences = ~fileList.map(function(file) {
return file.path;
}).indexOf(remotePreferencesPath);
// 记录远端配置的和本地配置的版本
// - 远端配置保存在 json 内容的 version 字段中
// - 本地配置用 localStorage 来记录
var remoteVersion = 0,
localVersion = localStorage.preferencesVersion || 0;
// 远端配置和本地配置的内容
var remotePreferences, localPreferences;
// 远端有配置,下载远端配置
if (hasRemotePreferences) {
downloadPreferences();
}
// 绑定实例上配置改变的事件,配置有变需要上传
minder.on('preferenceschange', function() {
localStorage.preferencesVersion = ++localVersion;
uploadPreferences();
});
// 下载远端配置
function downloadPreferences() {
// 比较远端和本地版本
// - 远端版本较新则设置本地版本为远端版本
// - 本地版本较新则上传本地版本
function merge(remote) {
remoteVersion = remote.version;
remotePreferences = remote.preferences;
localPreferences = minder.getPreferences();
if (localVersion < remoteVersion) {
minder.resetPreferences(remotePreferences);
} else if (localVersion > remoteVersion) {
uploadPreferences();
}
}
// 下载配置的过程
// 需要先获得下载的 URL 再使用 ajax 请求内容
sto.getFileUrl(remotePreferencesPath, {
success: function(url) {
$.ajax({
url: url,
cache: false,
dataType: 'json',
success: merge,
error: function() {
notice('下载配置失败!');
}
});
}
});
}
// 上传本地配置
function uploadPreferences() {
localPreferences = minder.getPreferences();
// 上传的数据需要附带版本信息
var data = {
version: localVersion,
preferences: localPreferences
};
var text = JSON.stringify(data);
sto.uploadTextFile(text, remotePreferencesPath, {
// 文件重复选择覆盖
ondup: sto.constant.ONDUP_OVERWRITE,
success: function(savedFile) {
console && console.log('配置已上传');
},
error: function(e) {
notice('上传配置失败');
}
});
}
}
// 加载当前 remoteUrl 中制定的文件
function loadRemote() {
if (loadRemote.tryCount) {
console.warn('加载用户文件失败:第 ' + loadUserFiles.tryCount + '次');
}
// 失败重试判断
if (loadRemote.tryCount > 3) {
notice('加载脑图失败!');
loadRemote.tryCount = 0;
return;
}
var sto = baidu.frontia.personalStorage;
$title.loading('加载“' + getFileName(remotePath) + '”...');
sto.getFileUrl(remotePath, {
success: function(url) {
// the url to download the file on cloud dist
var format = getFileFormat(remotePath);
if (format in fileLoader) {
fileLoader[format](url);
}
loadRemote.tryCount = 0;
},
error: loadRemote
});
loadRemote.tryCount++;
}
loadRemote.tryCount = 0;
function getFileFormat(fileUrl) {
return fileUrl.split('.').pop();
}
var fileLoader = {
'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({
cache: false,
url: url,
dataType: 'text',
success: function(result) {
importFile(result, 'freemind');
}
});
}
// 见文件数据导入minder
function importFile(data, format) {
watchingChanges = false;
minder.importData(data, format);
if (draftManager) {
if (!draftManager.openByPath(remotePath)) {
draftManager.create();
}
draftManager.save(remotePath);
draftManager.sync();
}
minder.execCommand('camera', minder.getRoot(), 300);
$title.loading(false).text(getFileName(remotePath));
watchingChanges = true;
}
// 添加文件到最近文件列表
function addToRecentMenu(list) {
list.splice(12);
list.forEach(function(file) {
$file_menu.kmui().appendItem({
item: {
label: getFileName(file.path),
value: file.path
},
click: openFile
});
});
}
// 从路径中抽取文件名
function getFileName(path) {
return path.split('/').pop();
}
// 点击文件菜单
function openFile(e) {
var path = $(this).data('value');
var draft = draftManager && draftManager.getCurrent();
if (draft && draft.path == path) {
if (!draft.sync && window.confirm('“' + getFileName(path) + '”在草稿箱包含未保存的更改,确定加载网盘版本覆盖草稿箱中的版本吗?')) {
setRemotePath(path, true);
loadRemote();
}
} else if (draftManager) {
draft = draftManager.openByPath(path);
setRemotePath(path, !draft || draft.sync);
if (draft) {
watchingChanges = false;
draftManager.load();
watchingChanges = true;
} else {
loadRemote();
}
} else {
setRemotePath(path, true);
loadRemote();
}
}
// 新建文件
function newFile() {
setRemotePath(null, true);
draftManager.create();
minder.importData('新建脑图', 'plain');
minder.execCommand('camera', minder.getRoot(), 300);
}
function generateRemotePath(filename) {
return '/apps/kityminder/' + filename + '.km';
}
function save() {
if (!currentAccount) return alert('请先登录!');
if (save.busy) {
return;
}
var uploadPath, filename;
// 确定上传文件名
if (!remotePath) {
filename = window.prompt('请输入文件名: ', minder.getMinderTitle().replace(/[\/\\\:\?\|\<\>\"\'\*]/g, ''));
if (!filename) return;
filename = filename.replace(/[\/\\\:\?\|\<\>\"\'\*]/g, '');
uploadPath = generateRemotePath(filename);
} else {
uploadPath = remotePath;
}
save.busy = true;
var data = minder.exportData('json');
var sto = baidu.frontia.personalStorage;
function error(reason) {
notice('保存到云盘失败,可能是网络问题导致!\n建议您将脑图以 .km 格式导出到本地!');
$title.loading(false);
clearTimeout(timeout);
save.busy = false;
}
var timeout = setTimeout(function() {
error('保存到云盘超时,可能是网络不稳定导致。');
}, 15000);
function upload() {
if (upload.tryCount) {
console.warn('保存文件失败!(第 ' + upload.tryCount + ' 次)');
}
if (upload.tryCount > 3) {
error();
upload.tryCount = 0;
return;
}
$title.loading('正在保存 “' + getFileName(uploadPath) + '” ...');
sto.uploadTextFile(data, uploadPath, {
ondup: remotePath ? sto.constant.ONDUP_OVERWRITE : sto.constant.ONDUP_NEWCOPY,
success: function(savedFile) {
if (savedFile.path) {
if (!remotePath) {
addToRecentMenu([savedFile]);
}
setRemotePath(savedFile.path, true);
if (draftManager) {
draftManager.save(remotePath);
draftManager.sync();
}
clearTimeout(timeout);
save.busy = false;
upload.tryCount = 0;
} else {
upload();
}
},
error: upload
});
upload.tryCount++;
}
upload.tryCount = 0;
upload();
}
function share() {
if ($share_btn.disabled()) {
return;
}
var baseUrl = /^(.*?)(\?|\#|$)/.exec(window.location.href)[1];
var shareUrl = baseUrl + '?shareId=' + shareId,
shareData = new baidu.frontia.Data({
shareMinder: {
id: shareId,
data: minder.exportData('json')
}
});
var shareConfig = window._bd_share_config.common,
resetShare = window._bd_share_main.init;
$share_btn.loading('正在分享...');
$.ajax({
url: 'http://naotu.baidu.com/mongo.php',
type: 'POST',
data: {
action: 'insert',
record: JSON.stringify({
shareMinder: {
id: shareId,
data: minder.exportData('json')
}
})
},
success: function(result) {
if (result.error) {
notice(result.error);
} else {
$share_dialog.show();
$share_url.val(shareUrl)[0].select();
}
$share_btn.loading(false);
},
error: function() {
notice('分享失败,可能是当前的环境不支持该操作。');
$share_btn.loading(false);
}
});
shareConfig.bdTitle = shareConfig.bdText = minder.getMinderTitle();
shareConfig.bdDesc = shareConfig.bdText = '“' + minder.getMinderTitle() + '” - 我用百度脑图制作的思维导图,快看看吧!(地址:' + shareUrl + ')';
shareConfig.bdUrl = shareUrl;
resetShare();
}
function bindShortCuts() {
$(document.body).keydown(function(e) {
var keyCode = e.keyCode || e.which;
//添加快捷键
if ((e.ctrlKey || e.metaKey)) {
switch (keyCode) {
//保存
case KM.keymap.s:
e.preventDefault();
if (e.shiftKey) {
share();
} else {
setTimeout(function() {
save();
});
}
break;
case KM.keymap.n:
e.preventDefault();
setTimeout(function() {
newFile();
});
break;
}
}
});
}
function watchChanges() {
var lastContent = minder.exportData('json');
minder.on('contentchange', function() {
if (!watchingChanges || lastContent == minder.exportData('json')) return;
var current = draftManager.save();
setRemotePath(remotePath, current.sync);
lastContent = minder.exportData('json');
});
}
function showDraftList() {
var list = draftManager.list(),
draft, $draft, index;
if (!list.length) {
draftManager.create();
list = draftManager.list();
}
$draft_menu.empty();
if (draftManager.getCurrent()) {
draft = list.shift();
$draft_menu.append('<li disabled="disabled" class="current-draft kmui-combobox-item kmui-combobox-item-disabled kmui-combobox-checked">' +
'<span class="kmui-combobox-icon"></span>' +
'<label class="kmui-combobox-item-label">' +
'<span class="update-time">' + getFriendlyTimeSpan(+new Date(draft.update), +new Date()) + '</span>' + wordLimit(draft.name) +
'</label>' +
'</li>');
$draft_menu.append('<li class="kmui-divider"></li>');
index = 1;
} else {
index = 0;
}
while (list.length) {
draft = list.shift();
$draft = $('<li class="draft-item">' +
'<a href="#">' + '<span class="update-time">' + getFriendlyTimeSpan(+new Date(draft.update), +new Date()) + '</span>' + wordLimit(draft.name) + '</a><a class="delete" title="删除该草稿"></a></li>');
$draft.data('draft-index', index++);
$draft.appendTo($draft_menu);
}
if (index > 1) {
$draft_menu.append('<li class="kmui-divider"></li>');
$draft_menu.append('<li class="draft-clear"><a href="#">清空草稿箱</a></li>');
}
//adjustDraftMenu();
}
function adjustDraftMenu() {
var pos = $draft_btn.offset();
pos.top -= $draft_menu.outerHeight() + 5;
$draft_menu.offset(pos);
}
function bindDraft() {
draftManager = window.draftManager;
if (!draftManager) {
if (window.DraftManager) {
draftManager = window.draftManager = new window.DraftManager(minder);
}
}
$draft_menu.delegate('a.delete', 'click', function(e) {
var $li = $(this).closest('li.draft-item');
draftManager.remove(+$li.data('draft-index'));
$li.remove();
showDraftList();
e.stopPropagation();
})
.delegate('li.draft-clear', 'click', function(e) {
if (window.confirm('确认清除草稿箱吗?')) {
draftManager.clear();
showDraftList();
}
e.stopPropagation();
})
.delegate('li.draft-item', 'click', function(e) {
loadDraft(+$(this).data('draft-index'));
});
}
function loadDraft(index) {
var draft = draftManager.open(index),
isRemote;
if (!draft) return;
isRemote = draft.path.indexOf('/apps/kityminder') === 0;
if (isRemote) {
setRemotePath(draft.path, draft.sync);
}
watchingChanges = false;
draftManager.load();
watchingChanges = true;
if (!isRemote) {
setRemotePath(null, false);
}
minder.execCommand('camera', null, 300);
}
function getFriendlyTimeSpan(t1_in_ms, t2_in_ms) {
var ms = Math.abs(t1_in_ms - t2_in_ms),
s = ms / 1000,
m = s / 60,
h = m / 60,
d = h / 24;
if (s < 60) return "刚刚";
if (m < 60) return (m | 0) + "分钟前";
if (h < 24) return (h | 0) + "小时前";
if (d <= 30) return (d | 0) + "天前";
return "很久之前";
}
window.social = {
setRemotePath: setRemotePath,
watchChanges: function(value) {
watchingChanges = value;
}
};
});
\ No newline at end of file
.niceblue {
color: white;
background: -moz-linear-gradient(top, #0099f2 0%, #4096ee 0%, #0076dd 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#0099f2), color-stop(0%,#4096ee), color-stop(100%,#0076dd)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #0099f2 0%,#4096ee 0%,#0076dd 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #0099f2 0%,#4096ee 0%,#0076dd 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #0099f2 0%,#4096ee 0%,#0076dd 100%); /* IE10+ */
background: linear-gradient(to bottom, #0099f2 0%,#4096ee 0%,#0076dd 100%); /* W3C */
}
.dropdown {
padding-right: 28px;
position: relative;
&:after {
content: ' ';
display: block;
position: absolute;
right: 10px;
top: 12px;
width: 0;
height: 0;
border: solid;
border-width: 4px 5px;
border-color: #333 transparent transparent transparent;
}
&:active, &.active {
&:after {
border-color: #fff transparent transparent transparent;
}
}
}
button {
font-family: Arial, "Heiti SC", "Microsoft Yahei";
outline: none;
display: inline-block;
vertical-align: middle;
padding: 0 15px;
height: 30px;
font-size: 13px;
line-height: 30px;
text-align: center;
color: #000;
text-decoration: none;
border: none;
margin-left: 5px;
background: none;
.niceblue;
&:hover, &.hover {
background: #009fff;
}
&:active, &.active {
background: darken(#009fff, 10%);
box-shadow: inset 0 2px 3px rgba(0,0,0, .2);
}
&[disabled] {
cursor: default;
background: #ccc;
}
}
.draft-menu.kmui-dropdown-menu {
margin-top: 24px;
margin-left: 1px;
span.update-time {
float: right;
color: #CCC;
margin-left: 40px;
padding-right: 16px;
}
li.draft-item a {
position: relative;
&:before {
content: ' ';
display: block;
width: 24px;
height: 24px;
background: url(../themes/default/images/draft.png) no-repeat 0 -24px;
position: absolute;
left: 4px;
top: 2px;
}
}
li.draft-item:hover a:before {
background-position: 0 -48px;
}
li.draft-item {
position: relative;
&:hover a.delete{
display: block;
}
a.delete {
display: none;
cursor: pointer;
position: absolute;
width: 20px;
height: 20px;
right: 4px;
top: 4px;
padding: 0;
background: url(../themes/default/images/close-button.png) no-repeat 0 0;
&:before {
display: none;
}
&:hover {
background-position: 0 -20px;
}
}
}
&.kmui-combobox-menu .kmui-combobox-checked {
overflow: hidden;
opacity: 1;
color: #CCC;
.kmui-combobox-icon {
float: left;
margin: 5px 0;
width: 28px;
background-position: center 0;
opacity: .3;
}
.kmui-combobox-item-label {
display: block;
margin-left: 28px;
}
&:hover {
color: #CCC;
.kmui-combobox-icon {
background-position: center 0;
}
}
}
}
.file-menu.kmui-dropdown-menu {
margin-top: 24px;
margin-left: 1px;
box-shadow: 0px 1px 5px rgba(0,0,0, .3);
#save-button, #manage-file-button {
display: none;
}
&.logined {
#save-button, #manage-file-button{
display: block;
}
#net-hint-buttom {
display: none;
}
}
}
.user-menu.kmui-dropdown-menu {
margin-top: 24px;
margin-left: -25px;
min-width: 130px;
box-shadow: 0px 1px 5px rgba(0,0,0, .3);
li a {
padding-left: 40px;
}
}
#share-dialog {
position: absolute;
padding: 20px;
left: 50%;
top: 40%;
margin-left: -175px;
margin-top: -100px;
background: white;
width: 350px;
box-shadow: 1px 2px 16px rgba(0, 0, 0, .5);
display: none;
h3 {
margin: 0;
font-size: 16px;
color: #666;
}
input {
width: 255px;
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 {
margin: 20px 0 30px;
}
#copy-share-url {
display: inline-block;
margin: 0;
width: 75px;
height: 28px;
line-height: 28px;
vertical-align: middle;
color: white;
.niceblue;
&:hover, &.hover {
background: #009fff;
}
&:active, &.active {
background: darken(#009fff, 10%);
box-shadow: inset 0 2px 3px rgba(0,0,0, .2);
}
}
#share-platform {
margin-bottom: 0;
}
}
\ No newline at end of file
......@@ -41,36 +41,4 @@
}
});
var uiModule = [
'fuix',
'mainmenu',
'commandbutton',
'commandbuttonset',
'commandinputmenu',
'history',
'tabs',
'title',
'account',
'template',
'theme',
'layout',
'style',
'font',
'color',
'insertnode',
'arrange',
'nodeop',
'priority',
'progress',
'resource',
'attachment',
'link',
'image'
];
/* jshint evil: true */
uiModule.forEach(function(module) {
document.write('<script src="ui/' + module + '.js"></script>');
});
})();
\ 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