Commit 9e89a241 authored by techird's avatar techird

stash

parent 46e89843
...@@ -9,9 +9,9 @@ ...@@ -9,9 +9,9 @@
<title>百度脑图 - 便捷的思维导图工具</title> <title>百度脑图 - 便捷的思维导图工具</title>
<script src="kityminder.all.min.js?_=1408430297149" charset="utf-8"></script> <script src="kityminder.all.min.js?_=1409099802809" charset="utf-8"></script>
<script src="kityminder.config.js?_=1408430297149" charset="utf-8"></script> <script src="kityminder.config.js?_=1409099802809" charset="utf-8"></script>
<script src="lang/zh-cn/zh-cn.js?_=1408430297149" charset="utf-8"></script> <script src="lang/zh-cn/zh-cn.js?_=1409099802809" charset="utf-8"></script>
<link href="ui/theme/default/css/default.all.css" type="text/css" rel="stylesheet" /> <link href="ui/theme/default/css/default.all.css" type="text/css" rel="stylesheet" />
......
This diff is collapsed.
This diff is collapsed.
...@@ -47,26 +47,50 @@ KityMinder.LANG['zh-cn'] = { ...@@ -47,26 +47,50 @@ KityMinder.LANG['zh-cn'] = {
'menu': { 'menu': {
'level1': { 'level1': {
'new': '新建',
'open': '打开', 'open': '打开',
'save': '保存', 'save': '保存',
'share': '分享', 'share': '分享',
'help': '帮助', 'help': '帮助',
'setting': '设置' 'setting': '设置'
}, },
'new': {
'header': '新建脑图'
},
'open': { 'open': {
'header': '打开文件', 'header': '打开',
'recent': '最近使用', 'recent': '最近使用',
'netdisk': '百度云盘', 'netdisk': '百度云盘',
'local': '本地文件', 'local': '本地文件',
'draft': '草稿箱' 'draft': '草稿箱'
},
'save': {
'header': '保存到',
'netdisk': '百度网盘',
'local': '导出到本地'
} }
}, },
'mydocument': '我的文档',
'emptydir': '目录为空!',
'pickfile': '选择文件...',
'acceptfile': '支持的格式:{0}',
'dropfile': '或将文件拖至此处',
'unsupportedfile': '不支持的文件格式',
'untitleddoc': '未命名文档',
'login': '登录', 'login': '登录',
'logout': '注销', 'logout': '注销',
'switchuser': '切换账户', 'switchuser': '切换账户',
'userinfo': '个人信息', 'userinfo': '个人信息',
'gotonetdisk': '我的网盘', 'gotonetdisk': '我的网盘',
'requirelogin': '请 <a class="login-button">登录</a> 后使用',
'saveas': '保存为',
'filename': '文件名',
'fileformat': '保存格式',
'save': '保存',
'mkdir': '新建目录',
'newdir': '未命名目录',
'bold': '加粗', 'bold': '加粗',
'italic': '斜体', 'italic': '斜体',
...@@ -112,7 +136,14 @@ KityMinder.LANG['zh-cn'] = { ...@@ -112,7 +136,14 @@ KityMinder.LANG['zh-cn'] = {
'image': '图片', 'image': '图片',
'removelink': '移除已有连接', 'removelink': '移除已有连接',
'removeimage': '移除已有图片', 'removeimage': '移除已有图片',
'resetlayout': '整理布局' 'resetlayout': '整理布局',
'justnow': '刚刚',
'minutesago': '{0} 分钟前',
'hoursago': '{0} 小时前',
'yesterday': '昨天',
'daysago': '{0} 天前',
'longago': '很久之前'
}, },
'popupcolor': { 'popupcolor': {
'clearColor': '清空颜色', 'clearColor': '清空颜色',
...@@ -163,5 +194,4 @@ KityMinder.LANG['zh-cn'] = { ...@@ -163,5 +194,4 @@ KityMinder.LANG['zh-cn'] = {
'resource': { 'resource': {
'resource': '资源...' 'resource': '资源...'
} }
}; };
\ No newline at end of file
This diff is collapsed.
...@@ -73,7 +73,6 @@ ...@@ -73,7 +73,6 @@
'src/module/resource.js', 'src/module/resource.js',
'src/module/view.js', 'src/module/view.js',
'src/module/dragtree.js', 'src/module/dragtree.js',
'src/module/dropfile.js',
'src/module/keyboard.js', 'src/module/keyboard.js',
'src/module/select.js', 'src/module/select.js',
'src/module/history.js', 'src/module/history.js',
...@@ -98,45 +97,74 @@ ...@@ -98,45 +97,74 @@
'src/protocol/png.js', 'src/protocol/png.js',
'src/protocol/svg.js', 'src/protocol/svg.js',
/* UI 代码 */ /* UI 基础 */
'ui/ui.js', 'ui/ui.js',
'ui/eve.js', 'ui/eve.js',
'ui/fuix.js', 'ui/fuix.js',
'ui/fiox.js',
/* UI 组件 */
'ui/widget/commandbutton.js',
'ui/widget/commandbuttonset.js',
'ui/widget/commandinputmenu.js',
'ui/widget/friendlytimespan.js',
'ui/widget/locallist.js',
'ui/widget/fileloader.js',
'ui/widget/netdiskfinder.js',
/* UI 菜单 */
'ui/menu/menu.js',
'ui/menu/header.js',
'ui/menu/level1.js',
/* UI 菜单 - 新建 */
'ui/menu/new/new.js',
/* UI 菜单 - 打开 */
'ui/menu/open/open.js',
'ui/menu/open/local.js',
'ui/menu/open/netdisk.js',
'ui/menu/open/recent.js',
'ui/menu/open/draft.js',
/* UI 菜单 - 保存 */
'ui/menu/save/save.js',
'ui/menu/save/netdisk.js',
'ui/menu/save/download.js',
/* UI 菜单 - 分享 */
'ui/menu/share/share.js',
/* UI Top Bar */
'ui/topbar/history.js',
'ui/topbar/user.js',
'ui/topbar/search.js',
'ui/topbar/title.js',
/* UI Ribbon */
'ui/ribbon/tabs.js',
/* UI Ribbon「思路」面板 */
'ui/ribbon/idea/insert.js',
'ui/ribbon/idea/arrange.js',
'ui/ribbon/idea/operation.js',
'ui/ribbon/idea/attachment.js',
'ui/ribbon/idea/link.js',
'ui/ribbon/idea/image.js',
'ui/ribbon/idea/priority.js',
'ui/ribbon/idea/progress.js',
'ui/ribbon/idea/resource.js',
/* UI Ribbon「展示」面板 */
'ui/ribbon/appearence/template.js',
'ui/ribbon/appearence/theme.js',
'ui/ribbon/appearence/layout.js',
'ui/ribbon/appearence/style.js',
'ui/ribbon/appearence/font.js',
'ui/ribbon/appearence/color.js',
'ui/mainmenu.js', /* UI Ribbon「视图」面板 */
'ui/mainmenu.header.js', 'ui/ribbon/view/level.js'
'ui/mainmenu.level1.js',
'ui/mainmenu.open.js',
'ui/fileloader.js',
'ui/netdisk.js',
'ui/localfile.js',
'ui/commandbutton.js',
'ui/commandbuttonset.js',
'ui/commandinputmenu.js',
'ui/history.js',
'ui/tabs.js',
'ui/user.js',
'ui/search.js',
'ui/title.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/attachment.js',
'ui/link.js',
'ui/image.js',
'ui/priority.js',
'ui/progress.js',
'ui/resource.js'
]; ];
if (typeof(module) === 'object' && module.exports) { if (typeof(module) === 'object' && module.exports) {
......
...@@ -47,18 +47,27 @@ KityMinder.LANG['zh-cn'] = { ...@@ -47,18 +47,27 @@ KityMinder.LANG['zh-cn'] = {
'menu': { 'menu': {
'level1': { 'level1': {
'new': '新建',
'open': '打开', 'open': '打开',
'save': '保存', 'save': '保存',
'share': '分享', 'share': '分享',
'help': '帮助', 'help': '帮助',
'setting': '设置' 'setting': '设置'
}, },
'new': {
'header': '新建脑图'
},
'open': { 'open': {
'header': '打开文件', 'header': '打开',
'recent': '最近使用', 'recent': '最近使用',
'netdisk': '百度云盘', 'netdisk': '百度云盘',
'local': '本地文件', 'local': '本地文件',
'draft': '草稿箱' 'draft': '草稿箱'
},
'save': {
'header': '保存到',
'netdisk': '百度网盘',
'local': '导出到本地'
} }
}, },
...@@ -66,12 +75,22 @@ KityMinder.LANG['zh-cn'] = { ...@@ -66,12 +75,22 @@ KityMinder.LANG['zh-cn'] = {
'emptydir': '目录为空!', 'emptydir': '目录为空!',
'pickfile': '选择文件...', 'pickfile': '选择文件...',
'acceptfile': '支持的格式:{0}', 'acceptfile': '支持的格式:{0}',
'dropfile': '或将文件拖至此处',
'unsupportedfile': '不支持的文件格式',
'untitleddoc': '未命名文档',
'login': '登录', 'login': '登录',
'logout': '注销', 'logout': '注销',
'switchuser': '切换账户', 'switchuser': '切换账户',
'userinfo': '个人信息', 'userinfo': '个人信息',
'gotonetdisk': '我的网盘', 'gotonetdisk': '我的网盘',
'requirelogin': '请 <a class="login-button">登录</a> 后使用',
'saveas': '保存为',
'filename': '文件名',
'fileformat': '保存格式',
'save': '保存',
'mkdir': '新建目录',
'newdir': '未命名目录',
'bold': '加粗', 'bold': '加粗',
'italic': '斜体', 'italic': '斜体',
...@@ -117,7 +136,14 @@ KityMinder.LANG['zh-cn'] = { ...@@ -117,7 +136,14 @@ KityMinder.LANG['zh-cn'] = {
'image': '图片', 'image': '图片',
'removelink': '移除已有连接', 'removelink': '移除已有连接',
'removeimage': '移除已有图片', 'removeimage': '移除已有图片',
'resetlayout': '整理布局' 'resetlayout': '整理布局',
'justnow': '刚刚',
'minutesago': '{0} 分钟前',
'hoursago': '{0} 小时前',
'yesterday': '昨天',
'daysago': '{0} 天前',
'longago': '很久之前'
}, },
'popupcolor': { 'popupcolor': {
'clearColor': '清空颜色', 'clearColor': '清空颜色',
...@@ -168,5 +194,4 @@ KityMinder.LANG['zh-cn'] = { ...@@ -168,5 +194,4 @@ KityMinder.LANG['zh-cn'] = {
'resource': { 'resource': {
'resource': '资源...' 'resource': '资源...'
} }
}; };
\ No newline at end of file
...@@ -20,6 +20,7 @@ kity.extendClass(Minder, { ...@@ -20,6 +20,7 @@ kity.extendClass(Minder, {
for (var name in pool) { for (var name in pool) {
if (pool.hasOwnProperty(name)) if (pool.hasOwnProperty(name))
protocols[name] = pool[name](this); protocols[name] = pool[name](this);
protocols[name].name = name;
} }
}, },
...@@ -28,7 +29,10 @@ kity.extendClass(Minder, { ...@@ -28,7 +29,10 @@ kity.extendClass(Minder, {
}, },
getSupportedProtocols: function() { getSupportedProtocols: function() {
return this._protocols; var protocols = this._protocols;
return Utils.keys(protocols).map(function(name) {
return protocols[name];
});
}, },
exportData: function(protocolName) { exportData: function(protocolName) {
...@@ -104,7 +108,7 @@ kity.extendClass(Minder, { ...@@ -104,7 +108,7 @@ kity.extendClass(Minder, {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
resolve(protocol.decode(local)); resolve(protocol ? protocol.decode(local) : local);
}).then(function(json) { }).then(function(json) {
......
function DraftManager( minder ) {
var current = null,
localStorage = window.localStorage,
drafts,
MAX_SIZE = 15;
init();
function init() {
drafts = localStorage.getItem( 'drafts' );
drafts = drafts ? JSON.parse( drafts ) : [];
}
function store() {
localStorage.setItem( 'drafts', JSON.stringify( drafts.slice( 0, MAX_SIZE ) ) );
}
function create( path ) {
current = {
path: path || 'local/' + ( +new Date() )
};
drafts.unshift( current );
save();
}
function open( index ) {
current = drafts[ index ];
if ( !current ) return false;
// bring it first
drafts.splice( index, 1 );
drafts.unshift( current );
store();
return current;
}
function load() {
if ( current ) {
minder.importData( current.data, 'json' );
}
return current;
}
function getCurrent() {
return current;
}
function openByPath( path ) {
for ( var i = 0; i < drafts.length; i++ ) {
if ( drafts[ i ].path == path ) return open( i );
}
return false;
}
function save( path ) {
if ( !current ) {
create();
} else {
current.path = path || current.path;
current.name = minder.getMinderTitle();
var data = minder.exportData( 'json' );
current.sync = current.sync && (data == current.data);
current.data = data;
current.update = new Date();
store();
}
return current;
}
function sync() {
current.sync = true;
store();
}
function list() {
return drafts.slice( 0, 15 );
}
function remove( remove_index ) {
drafts.splice( remove_index, 1 );
store();
}
function clear() {
drafts.splice( 1 );
store();
}
return {
open: open,
openByPath: openByPath,
load: load,
save: save,
create: create,
list: list,
remove: remove,
clear: clear,
getCurrent: getCurrent,
sync: sync
};
}
\ No newline at end of file
/**
* @fileOverview
*
* 简版事件解耦功能
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('eve', function(minder) { KityMinder.registerUI('eve', function(minder) {
return { return {
setup: function(obj) { setup: function(obj) {
...@@ -31,11 +40,14 @@ KityMinder.registerUI('eve', function(minder) { ...@@ -31,11 +40,14 @@ KityMinder.registerUI('eve', function(minder) {
obj.fire = function fire(name) { obj.fire = function fire(name) {
var list = callbacks[name]; var list = callbacks[name];
var args = [].slice.call(arguments, 1);
if (list) list.forEach(function(callback) { if (list) list.forEach(function(callback) {
callback.apply(obj, [].slice.call(arguments, 1)); callback.apply(obj, args);
}); });
return this; return this;
}; };
return obj;
} }
}; };
}); });
\ No newline at end of file
/**
* @fileOverview
*
* 拓展 fio 的能力
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('fiox', function(minder) {
var eve = minder.getUI('eve');
eve.setup(fio.user);
});
\ No newline at end of file
/**
* @fileOverview
*
* 拓展 FUI 组件的功能
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
kity.extendClass(FUI.Widget, { kity.extendClass(FUI.Widget, {
setEnable: function(value) { setEnable: function(value) {
if (value === false) this.disable(); if (value === false) this.disable();
......
KityMinder.registerUI('history', ['commandbutton'], function(minder, $commandbutton) {
var ret = {};
['undo', 'redo'].forEach(function(command) {
ret[command] = $commandbutton.generate(command).appendTo(document.getElementById('panel'));
});
return ret;
});
\ No newline at end of file
KityMinder.registerUI('mainmenu.header', ['mainmenu'], function (minder, $mainmenu) { /**
* @fileOverview
*
* 菜单头部
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
var $header = $('<div class="main-menu-header"></div>').appendTo($mainmenu); KityMinder.registerUI('menu/header', function (minder) {
var $menu = minder.getUI('menu/menu');
var $header = $('<div class="main-menu-header"></div>').appendTo($menu);
var $backPanel = $('<div class="main-menu-back-panel"></div>').appendTo($header); var $backPanel = $('<div class="main-menu-back-panel"></div>').appendTo($header);
...@@ -10,7 +21,7 @@ KityMinder.registerUI('mainmenu.header', ['mainmenu'], function (minder, $mainme ...@@ -10,7 +21,7 @@ KityMinder.registerUI('mainmenu.header', ['mainmenu'], function (minder, $mainme
className: 'main-menu-back-button', className: 'main-menu-back-button',
label: minder.getLang('ui.back') label: minder.getLang('ui.back')
}).appendTo($backPanel[0]).on('click', function() { }).appendTo($backPanel[0]).on('click', function() {
$mainmenu.removeClass('show'); $menu.removeClass('show');
}); });
return $header; return $header;
......
KityMinder.registerUI('mainmenu.level1', ['mainmenu'], function (minder, $mainmenu) { /**
var tabs = ['open', 'save', 'share', 'help']; * @fileOverview
*
* 一级菜单
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('menu/level1', function(minder) {
var $menu = minder.getUI('menu/menu');
var tabs = ['new', 'open', 'save', 'share', 'help'];
var $l1_tabs = new FUI.Tabs({ var $l1_tabs = new FUI.Tabs({
buttons: tabs.map(function(key) { buttons: tabs.map(function(key) {
...@@ -11,9 +23,9 @@ KityMinder.registerUI('mainmenu.level1', ['mainmenu'], function (minder, $mainme ...@@ -11,9 +23,9 @@ KityMinder.registerUI('mainmenu.level1', ['mainmenu'], function (minder, $mainme
className: 'main-menu-level-1' className: 'main-menu-level-1'
}); });
$l1_tabs.appendTo($mainmenu[0]); $l1_tabs.appendTo($menu[0]);
$l1_tabs.select(0); $l1_tabs.select(2);
var ret = {}; var ret = {};
......
KityMinder.registerUI('mainmenu', function(minder) { /**
* @fileOverview
*
* 主菜单控制
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('menu/menu', function(minder) {
var $mainMenuButton = new FUI.Button({ var $mainMenuButton = new FUI.Button({
id: 'main-menu-btn' id: 'main-menu-btn'
}); });
...@@ -12,7 +22,14 @@ KityMinder.registerUI('mainmenu', function(minder) { ...@@ -12,7 +22,14 @@ KityMinder.registerUI('mainmenu', function(minder) {
$panel.addClass('show'); $panel.addClass('show');
}); });
$panel = $('<div id="main-menu"></div>').appendTo('body'); $panel = $('<div id="main-menu"></div>').appendTo('#content-wrapper');
$(window).keydown(function(e) {
// ESC Pressed
if (e.keyCode == 27) {
$panel.toggleClass('show');
}
});
return $panel.addClass('show2'); return $panel.addClass('show');
}); });
\ No newline at end of file
/**
* @fileOverview
*
* 新建文件菜单
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('menu/new/new', function(minder) {
var $menu = minder.getUI('menu/menu');
var $level1 = minder.getUI('menu/level1');
var eve = minder.getUI('eve');
var $panel = $level1['new'].getContentElement();
var $h2 = $('<h2></h2>')
.text(minder.getLang('ui.menu.new.header'))
.appendTo($panel);
// 模板列表容器
var $ul = $('<ul></ul>')
.addClass('new-file-template-select')
.appendTo($panel);
// 模板容器
var $li;
var templates = KityMinder.getTemplateList();
for (var name in templates) {
$li = $('<li></li>')
.addClass('template-item')
.addClass(name)
.data('template', name)
.append('<a>' + minder.getLang('template')[name] + '</a>')
.appendTo($ul);
}
$ul.delegate('.template-item', 'click', function(e) {
var template = $(e.target).data('template');
minder.importData({
template: template,
version: KityMinder.version,
data: {
text: minder.getLang('template')[template]
}
});
minder.execCommand('camera', minder.getRoot());
$menu.removeClass('show');
});
var ret = {};
eve.setup(ret);
return ret;
});
\ No newline at end of file
/**
* @fileOverview
*
* 草稿箱功能
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('menu/open/draft', function(minder) {
var $open = minder.getUI('menu/open/open');
var $panel = $($open.draft.getContentElement()).addClass('draft-file-list');
var drafts = minder.getUI('widget/locallist').use('draft');
$panel.append('<h2>草稿箱</h2>');
});
\ No newline at end of file
KityMinder.registerUI('localfile', ['mainmenu', 'mainmenu.open', 'fileloader'], function(minder, $menu, $open, $loader) { /**
* @fileOverview
*
* 支持从本地打开文件
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('menu/open/local', function(minder) {
var $menu = minder.getUI('menu/menu');
var $open = minder.getUI('menu/open/open');
var $loader = minder.getUI('widget/fileloader');
// 支持的文件类型 // 支持的文件类型
var supportedExtensions = []; var supportedExtensions = [];
...@@ -50,9 +63,13 @@ KityMinder.registerUI('localfile', ['mainmenu', 'mainmenu.open', 'fileloader'], ...@@ -50,9 +63,13 @@ KityMinder.registerUI('localfile', ['mainmenu', 'mainmenu.open', 'fileloader'],
.text(minder.getLang('ui.pickfile')) .text(minder.getLang('ui.pickfile'))
.appendTo($pick); .appendTo($pick);
$('<span></span>').text(minder.getLang('ui.acceptfile', supportedExtensions)).appendTo($pick); $('<span></span>')
.text(minder.getLang('ui.acceptfile', supportedExtensions))
.appendTo($pick);
var $drop = $('<div class="drop-file"></div>').appendTo($panel); var $drop = $('<div class="drop-file"></div>')
.append($('<span></span>').html(minder.getLang('ui.dropfile')))
.appendTo($panel);
$pickButton.click(function() { $pickButton.click(function() {
var $file = $('<input type="file" />') var $file = $('<input type="file" />')
...@@ -63,6 +80,14 @@ KityMinder.registerUI('localfile', ['mainmenu', 'mainmenu.open', 'fileloader'], ...@@ -63,6 +80,14 @@ KityMinder.registerUI('localfile', ['mainmenu', 'mainmenu.open', 'fileloader'],
}).click(); }).click();
}); });
$('#content-wrapper').on('dragover', function(e) {
$open.select(2); e.preventDefault();
e.stopPropagation();
}).on('drop', function(e) {
e = e.originalEvent;
var file = e.dataTransfer.files[0];
readFile(file).then($loader.load);
$menu.removeClass('show');
e.preventDefault();
});
}); });
\ No newline at end of file
/**
* @fileOverview
*
* 支持从百度网盘打开文件
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('menu/open/netdisk', function(minder) {
var $menu = minder.getUI('menu/menu');
var $open = minder.getUI('menu/open/open');
var $loader = minder.getUI('widget/fileloader');
var $netdiskfinder = minder.getUI('widget/netdiskfinder');
var $eve = minder.getUI('eve');
var ret = $eve.setup({});
/* 网盘面板 */
var $panel = $($open.netdisk.getContentElement());
var $finder = $netdiskfinder.generate($panel, function(file) {
return $loader.support(file);
});
$finder.on('fileclick', openFile);
function openFile(file) {
var protocol = $loader.support(file);
$menu.removeClass('show');
return $loader.load(fio.file.read({
path: file.path,
dataType: protocol.dataType
})).then(function(readed) {
if (readed) ret.fire('fileload', readed);
});
}
ret.loadFileByPath = function(path) {
var file = new fio.file.File(path);
return openFile(file);
};
return ret;
});
\ No newline at end of file
KityMinder.registerUI('mainmenu.open', ['mainmenu.level1', 'eve'], function(minder, $level1, eve) { /**
* @fileOverview
*
* 打开菜单(二级菜单)
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('menu/open/open', function(minder) {
var $level1 = minder.getUI('menu/level1');
var eve = minder.getUI('eve');
var $h2 = $('<h2></h2>') var $h2 = $('<h2></h2>')
.text(minder.getLang('ui.menu.open.header')) .text(minder.getLang('ui.menu.open.header'))
...@@ -15,18 +27,24 @@ KityMinder.registerUI('mainmenu.open', ['mainmenu.level1', 'eve'], function(mind ...@@ -15,18 +27,24 @@ KityMinder.registerUI('mainmenu.open', ['mainmenu.level1', 'eve'], function(mind
}) })
}).appendTo($level1.open); }).appendTo($level1.open);
// 暴露
var ret = {}; var ret = {};
// 暴露每个面板
source.forEach(function(key, index) { source.forEach(function(key, index) {
ret[key] = $tabs.getPanel(index); ret[key] = $tabs.getPanel(index);
}); });
// 支持事件
eve.setup(ret); eve.setup(ret);
// 暴露打开菜单(选项卡)选择事件
$tabs.on('tabsselect', function(e, info) { $tabs.on('tabsselect', function(e, info) {
ret.fire('select', info); ret.fire('select', info);
}); });
// 暴露选择事件
ret.select = $tabs.select.bind($tabs); ret.select = $tabs.select.bind($tabs);
return ret; return ret;
......
/**
* @fileOverview
*
* 最近文件功能
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('menu/open/recent', function(minder) {
var $menu = minder.getUI('menu/menu');
var $open = minder.getUI('menu/open/open');
var $loader = minder.getUI('widget/fileloader');
var frdTime = minder.getUI('widget/friendlytimespan');
var netdisk = minder.getUI('menu/open/netdisk');
var recentList = minder.getUI('widget/locallist').use('recent');
/* 网盘面板 */
var $panel = $($open.recent.getContentElement()).addClass('recent-file-panel');
/* 路径导航 */
var $nav = $('<h2>最近使用</h2>')
.appendTo($panel);
/* 最近文件列表容器 */
var $ul = $('<ul></ul>')
.addClass('recent-file-list')
.appendTo($panel);
renderList();
function renderList() {
$ul.empty();
recentList.forEach(function(item) {
var $li = $('<li></li>')
.addClass('recent-file-item')
.data('path', item.path)
.appendTo($ul);
$('<h4></h4>')
.addClass('file-name')
.text(item.filename)
.appendTo($li);
$('<p></p>')
.addClass('file-title')
.text(item.title)
.appendTo($li);
$('<span></span>')
.addClass('file-time')
.data('time', item.time)
.text(frdTime.display(item.time))
.appendTo($li);
});
}
$ul.delegate('.recent-file-item', 'click', function(e) {
var path = $(e.target)
.closest('.recent-file-item')
.data('path');
netdisk.loadFileByPath(path);
});
netdisk.on('fileload', function(loaded) {
var exist = recentList.findIndex('path', loaded.file.path);
if (~exist) {
recentList.remove(exist);
}
recentList.unshift({
path: loaded.file.path,
filename: loaded.file.filename,
title: loaded.json.data.text || minder.getLang('untitleddoc'),
time: +new Date()
});
renderList();
});
function updateTime() {
$ul.find('.file-time').each(function(index, element) {
$(element).text(frdTime.display($(element).data('time')));
});
}
setInterval(updateTime, 60000);
});
\ No newline at end of file
/**
* @fileOverview
*
*
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
/**
* @fileOverview
*
* 保存文件到网盘的功能
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('menu/save/netdisk', function(minder) {
var $menu = minder.getUI('menu/menu');
var $save = minder.getUI('menu/save/save');
var $netdiskfinder = minder.getUI('widget/netdiskfinder');
var $eve = minder.getUI('eve');
var ret = $eve.setup({});
var protocols = minder.getSupportedProtocols().filter(function(protocol) {
return protocol.encode;
});
/* 网盘面板 */
var $panel = $($save.netdisk.getContentElement()).addClass('netdisk-save-panel');
var $finder = $netdiskfinder.generate($panel, function(file) {
return protocols.some(function(protocol) {
return protocol.fileExtension == file.extension;
}, false);
});
var $selects = $('<div class="netdisk-save-select"></div>')
.appendTo($panel);
$('<label>')
.text(minder.getLang('ui.saveas'))
.appendTo($selects);
var $filename = $('<input>')
.attr('placeholder', minder.getLang('ui.filename'))
.attr('title', minder.getLang('ui.filename'))
.appendTo($selects);
var $format = $('<select>')
.attr('title', minder.getLang('ui.fileformat'))
.appendTo($selects);
protocols.forEach(function(protocol) {
$('<option>')
.text(protocol.fileDescription + '(' + protocol.fileExtension + ')')
.val(protocol.name)
.appendTo($format);
});
$format.val('json');
var $saveBtn = $('<button></button>')
.addClass('save-button')
.text(minder.getLang('ui.save'))
.appendTo($selects);
return ret;
});
\ No newline at end of file
/**
* @fileOverview
*
* 保存菜单(二级菜单)
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('menu/save/save', function(minder) {
var $level1 = minder.getUI('menu/level1');
var eve = minder.getUI('eve');
var $h2 = $('<h2></h2>')
.text(minder.getLang('ui.menu.save.header'))
.appendTo($level1.save.getContentElement());
var source = ['netdisk', 'local'];
var $tabs = new FUI.Tabs({
buttons: source.map(function(key) {
return {
label: minder.getLang('ui.menu.save.' + key),
className: key
};
})
}).appendTo($level1.save);
// 暴露
var ret = eve.setup({});
// 暴露每个面板
source.forEach(function(key, index) {
ret[key] = $tabs.getPanel(index);
});
// 暴露保存菜单(选项卡)选择事件
$tabs.on('tabsselect', function(e, info) {
ret.fire('select', info);
});
// 暴露选择事件
ret.select = $tabs.select.bind($tabs);
return ret;
});
\ No newline at end of file
/**
* @fileOverview
*
*
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
\ No newline at end of file
KityMinder.registerUI('netdisk', ['mainmenu', 'mainmenu.open', 'fileloader'], function(minder, $menu, $open, $loader) {
/* 网盘面板 */
var $panel = $($open.netdisk.getContentElement());
/* 路径导航 */
var $nav = $('<div class="netdisk-nav"></div>')
.appendTo($panel);
/* 显示当前目录文件列表 */
var $list = $('<ul></ul>')
.addClass('netdisk-file-list')
.appendTo($panel);
/* 点击目录中的项目时打开项目 */
$list.delegate('.netdisk-file-list-item', 'click', function(e) {
var $file = $(e.target),
file = $file.data('file');
open(file);
});
$nav.delegate('a', 'click', function(e) {
if ($(e.target).hasClass('dir-back')) {
var parts = currentPath.split('/');
parts.pop(); // 有一个无效部分
parts.pop();
return list(parts.join('/'));
}
list($(e.target).data('path'));
});
var base = '/apps/kityminder';
var currentPath = base;
var supports = {
'.km': 'json',
'.txt': 'plain',
'.xmind': 'xmind',
'.mmap': 'mmap',
'.mm': 'mm'
};
function sign(num) {
return num > 0 ? 1 : (num < 0 ? -1 : 0);
}
function open(file) {
if (file.isDir) return list(file.path);
var protocol = $loader.support(file);
if (!protocol) return;
$loader.load(fio.file.read( {
path: file.path,
dataType: minder.getProtocol(protocol).dataType
} ));
$menu.removeClass('show');
}
function list(path) {
Promise.all([
fio.file.list({
path: path
}),
new Promise(function(resolve, reject) {
$list.transit({
x: -100 * sign(path.length - currentPath.length),
opacity: 0
}, 100, function() {
resolve(null);
});
})
])
.then(renderList, function(error) {
window.alert('加载目录发生错误:' + error);
});
currentPath = path.charAt(path.length - 1) == '/' ? path : path + '/';
updateNav();
}
function renderList(values) {
$list.empty();
if (!values[0].length) {
$list.append('<li class="empty" disabled="disabled">' + minder.getLang('ui.emptydir') + '</li>');
}
values[0].forEach(function(file) {
if (!file.isDir && !supports[file.extension]) return;
$('<li></li>')
.text(file.filename)
.addClass('netdisk-file-list-item')
.addClass(file.isDir ? 'dir' : 'file')
.data('file', file)
.appendTo($list);
});
$list.css({
x: -parseInt($list.css('x'))
}).stop().transit({
x: 0,
opacity: 1
});
}
function updateNav() {
$nav.empty();
if (currentPath != base && currentPath != base + '/') {
$nav.append('<a class="dir-back">Back</a>');
} else {
$nav.append('<span class="my-document"></span>');
}
var path = currentPath.substr(base.length);
var parts = path.split('/');
var processPath = '';
function pathButton(part) {
processPath += part + '/';
var $a = $('<a></a>');
if (part == base) {
$a.text(minder.getLang('ui.mydocument'));
} else {
$a.text(part);
}
return $a.data('path', processPath);
}
$nav.append(pathButton(base));
parts.forEach(function(part) {
if (!part) return;
$nav.append('<span class="spliter"></span>');
$nav.append(pathButton(part));
});
}
$open.once('select', function() {
fio.user.check().then(function() {
list(currentPath);
});
});
});
\ No newline at end of file
KityMinder.registerUI('popupmenu', function() {
$('body').on('mousedown', function() {
$('.popup-menu').removeClass('show');
});
function update() {
}
return {
generate: function(list) {
var $ul = $('<ul>').addClass('popup-menu');
return {
update: function(list) {
}
};
}
};
});
\ No newline at end of file
KityMinder.registerUI('recent', ['mainmenu.open'], function(minder, $openmenu) {
var storage = localStorage;
var recent = storage.recentFiles;
recent = recent ? JSON.decode(recent) : [];
return {
push: function(type, path) {
recent.unshift({
type: type,
path: path,
time: +new Date()
});
},
load: function(index) {
}
};
});
\ No newline at end of file
function generateSerisColor() { /**
* @fileOverview
*
* 节点颜色设置(包括和背景)
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/appearence/color', function(minder) {
function generateSerisColor() {
return ['#e75d66', '#fac75b', '#99ca6a', '#00c5ad', '#3bbce0', '#c9ced1', '#425b71', 'white']; return ['#e75d66', '#fac75b', '#99ca6a', '#00c5ad', '#3bbce0', '#c9ced1', '#425b71', 'white'];
} }
var $commandbuttonset = minder.getUI('widget/commandbuttonset');
var $tabs = minder.getUI('ribbon/tabs');
KityMinder.registerUI('color', ['tabs', 'commandbuttonset'], function(minder, $tabs, $commandbuttonset) {
var $colorPanel = new FUI.LabelPanel({ var $colorPanel = new FUI.LabelPanel({
label: minder.getLang('panels.color') label: minder.getLang('panels.color')
}).appendTo($tabs.edit); }).appendTo($tabs.appearence);
var $backgroundPanel = new FUI.LabelPanel({ var $backgroundPanel = new FUI.LabelPanel({
label: minder.getLang('panels.background') label: minder.getLang('panels.background')
}).appendTo($tabs.edit); }).appendTo($tabs.appearence);
var foreColorList = generateSerisColor(); var foreColorList = generateSerisColor();
......
function fontUI(minder, $tabs, $commandInputMenu, $commandButton) { /**
* @fileOverview
*
* 字体设置(字体字号加粗斜体)
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/appearence/font', function(minder) {
var $tabs = minder.getUI('ribbon/tabs');
var commandinputmenu = minder.getUI('widget/commandinputmenu');
var commandbutton = minder.getUI('widget/commandbutton');
var $fontPanel = new FUI.LabelPanel({ var $fontPanel = new FUI.LabelPanel({
label: minder.getLang('panels.font'), label: minder.getLang('panels.font'),
...@@ -13,7 +26,7 @@ function fontUI(minder, $tabs, $commandInputMenu, $commandButton) { ...@@ -13,7 +26,7 @@ function fontUI(minder, $tabs, $commandInputMenu, $commandButton) {
column: true column: true
}); });
var $fontFamilyMenu = $commandInputMenu.generate('fontfamily', minder.getOptions('fontfamily').map(function(ff) { var $fontFamilyMenu = commandinputmenu.generate('fontfamily', minder.getOptions('fontfamily').map(function(ff) {
return { return {
label: { label: {
text: ff.name, text: ff.name,
...@@ -26,7 +39,7 @@ function fontUI(minder, $tabs, $commandInputMenu, $commandButton) { ...@@ -26,7 +39,7 @@ function fontUI(minder, $tabs, $commandInputMenu, $commandButton) {
}; };
})); }));
var $fontSizeMenu = $commandInputMenu.generate('fontsize', minder.getOptions('fontsize').map(function(fs) { var $fontSizeMenu = commandinputmenu.generate('fontsize', minder.getOptions('fontsize').map(function(fs) {
return { return {
label: { label: {
text: fs, text: fs,
...@@ -41,14 +54,12 @@ function fontUI(minder, $tabs, $commandInputMenu, $commandButton) { ...@@ -41,14 +54,12 @@ function fontUI(minder, $tabs, $commandInputMenu, $commandButton) {
$leftPanel.appendWidgets([$fontFamilyMenu, $fontSizeMenu]); $leftPanel.appendWidgets([$fontFamilyMenu, $fontSizeMenu]);
var $boldButton = $commandButton.generate('bold'); var $boldButton = commandbutton.generate('bold');
var $italicButton = $commandButton.generate('italic'); var $italicButton = commandbutton.generate('italic');
$rightPanel.appendWidgets([$boldButton, $italicButton]); $rightPanel.appendWidgets([$boldButton, $italicButton]);
$fontPanel.appendWidgets([$leftPanel, $rightPanel]); $fontPanel.appendWidgets([$leftPanel, $rightPanel]);
$tabs.edit.appendWidget($fontPanel); $tabs.appearence.appendWidget($fontPanel);
} });
\ No newline at end of file
KityMinder.registerUI('font', ['tabs', 'commandinputmenu', 'commandbutton'], fontUI);
\ No newline at end of file
KityMinder.registerUI('layout', ['tabs', 'commandbuttonset', 'commandbutton'], function(minder, $tabs, $commandbuttonset, $commandbutton) { /**
* @fileOverview
*
* 布局面板
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/appearence/layout', function(minder) {
var $tabs = minder.getUI('ribbon/tabs');
var $commandbuttonset = minder.getUI('widget/commandbuttonset');
var $commandbutton = minder.getUI('widget/commandbutton');
var $layoutPanel = new FUI.LabelPanel({ var $layoutPanel = new FUI.LabelPanel({
id: 'layout-panel', id: 'layout-panel',
label: minder.getLang('panels.layout') label: minder.getLang('panels.layout')
}).appendTo($tabs.edit); }).appendTo($tabs.appearence);
var $layoutSelect = new FUI.DropPanel({ var $layoutSelect = new FUI.DropPanel({
id: 'layout-select' id: 'layout-select'
......
KityMinder.registerUI('style', ['tabs', 'commandbutton'], function(minder, $tabs, $commandbutton) { /**
* @fileOverview
*
* 样式控制
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/appearence/style', function(minder) {
var $tabs = minder.getUI('ribbon/tabs');
var $commandbutton = minder.getUI('widget/commandbutton');
var $stylePanel = new FUI.LabelPanel({ var $stylePanel = new FUI.LabelPanel({
label: minder.getLang('panels.style') label: minder.getLang('panels.style')
}).appendTo($tabs.edit); }).appendTo($tabs.appearence);
$commandbutton.generate('clearstyle').addClass('large').appendTo($stylePanel); $commandbutton.generate('clearstyle').addClass('large').appendTo($stylePanel);
......
KityMinder.registerUI('template', ['tabs'], function(minder, $tabs) { /**
* @fileOverview
*
* 模板选择
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
var buttonset = minder.getUI('commandbuttonset'); KityMinder.registerUI('ribbon/appearence/template', function(minder) {
var $commandbuttonset = minder.getUI('widget/commandbuttonset');
var $tabs = minder.getUI('ribbon/tabs');
var $templatePanel = new FUI.LabelPanel({ var $templatePanel = new FUI.LabelPanel({
id: 'template-panel', id: 'template-panel',
...@@ -11,12 +21,12 @@ KityMinder.registerUI('template', ['tabs'], function(minder, $tabs) { ...@@ -11,12 +21,12 @@ KityMinder.registerUI('template', ['tabs'], function(minder, $tabs) {
id: 'template-select' id: 'template-select'
}); });
$tabs.edit.appendWidget($templatePanel); $tabs.appearence.appendWidget($templatePanel);
$templatePanel.appendWidget($templateSelect); $templatePanel.appendWidget($templateSelect);
var templateList = KityMinder.Utils.keys(KityMinder.getTemplateList()); var templateList = KityMinder.Utils.keys(KityMinder.getTemplateList());
$templateSelect.appendWidget(buttonset.generate('template', templateList)); $templateSelect.appendWidget($commandbuttonset.generate('template', templateList));
return $templatePanel; return $templatePanel;
}); });
\ No newline at end of file
KityMinder.registerUI('theme', ['tabs'], function(minder, $tabs) { /**
* @fileOverview
*
* 皮肤选择
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
var buttonset = minder.getUI('commandbuttonset'); KityMinder.registerUI('ribbon/appearence/theme', function(minder) {
var $commandbuttonset = minder.getUI('widget/commandbuttonset');
var $tabs = minder.getUI('ribbon/tabs');
var $themePanel = new FUI.LabelPanel({ var $themePanel = new FUI.LabelPanel({
id: 'theme-panel', id: 'theme-panel',
...@@ -11,12 +21,12 @@ KityMinder.registerUI('theme', ['tabs'], function(minder, $tabs) { ...@@ -11,12 +21,12 @@ KityMinder.registerUI('theme', ['tabs'], function(minder, $tabs) {
id: 'theme-select' id: 'theme-select'
}); });
$tabs.edit.appendWidget($themePanel); $tabs.appearence.appendWidget($themePanel);
$themePanel.appendWidget($themeSelect); $themePanel.appendWidget($themeSelect);
var themeList = KityMinder.Utils.keys(KityMinder.getThemeList()); var themeList = KityMinder.Utils.keys(KityMinder.getThemeList());
$themeSelect.appendWidget(buttonset.generate('theme', themeList.map(function(theme) { $themeSelect.appendWidget($commandbuttonset.generate('theme', themeList.map(function(theme) {
var style = KityMinder._themes[theme]; var style = KityMinder._themes[theme];
return { return {
label: { label: {
......
KityMinder.registerUI('arrange', ['tabs', 'commandbutton'], function(minder, $tabs, $commandbutton) { /**
* @fileOverview
*
* 排列节点的两个命令按钮
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/idea/arrange', function(minder) {
var $tabs = minder.getUI('ribbon/tabs');
var $commandbutton = minder.getUI('widget/commandbutton');
var $arrangePanel = new FUI.LabelPanel({ var $arrangePanel = new FUI.LabelPanel({
label: minder.getLang('panels.arrange'), label: minder.getLang('panels.arrange'),
column: true column: true
......
KityMinder.registerUI('attachment', ['tabs'], function(minder, $tabs) { /**
* @fileOverview
*
* 附件面板
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/idea/attachment', function(minder) {
var $tabs = minder.getUI('ribbon/tabs');
var $attachmentPanel = new FUI.LabelPanel({ var $attachmentPanel = new FUI.LabelPanel({
label: minder.getLang('panels.attachment'), label: minder.getLang('panels.attachment'),
coloum: true coloum: true
......
KityMinder.registerUI('image', ['attachment'], function (minder, $attachment) { /**
* @fileOverview
*
* 插入和管理图片
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('image', function(minder) {
var $attachment = minder.getUI('ribbon/idea/attachment');
var $imageButtonMenu = new FUI.ButtonMenu({ var $imageButtonMenu = new FUI.ButtonMenu({
id: 'image-button-menu', id: 'image-button-menu',
...@@ -74,7 +85,7 @@ KityMinder.registerUI('image', ['attachment'], function (minder, $attachment) { ...@@ -74,7 +85,7 @@ KityMinder.registerUI('image', ['attachment'], function (minder, $attachment) {
error(false); error(false);
$preview.removeClass('loading'); $preview.removeClass('loading');
}).on('error', function() { }).on('error', function() {
if($preview.attr('src')) error(true); if ($preview.attr('src')) error(true);
$preview.removeClass('loading'); $preview.removeClass('loading');
}); });
......
KityMinder.registerUI('insertnode', ['tabs', 'commandbutton'], function(minder, $tabs, $commandbutton) { /**
* @fileOverview
*
* 插入节点
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/idea/insert', function(minder) {
var $commandbutton = minder.getUI('widget/commandbutton');
var $tabs = minder.getUI('ribbon/tabs');
var $insertNodePanel = new FUI.LabelPanel({ var $insertNodePanel = new FUI.LabelPanel({
label: minder.getLang('panels.insert'), label: minder.getLang('panels.insert'),
column: true column: true
......
KityMinder.registerUI('link', ['attachment'], function(minder, $attachment) { /**
* @fileOverview
*
* 插入和管理超链接
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/idea/link', function(minder) {
var $attachment = minder.getUI('ribbon/idea/attachment');
var $linkButtonMenu = new FUI.ButtonMenu({ var $linkButtonMenu = new FUI.ButtonMenu({
id: 'link-button-menu', id: 'link-button-menu',
......
KityMinder.registerUI('nodeop', ['tabs', 'commandbutton'], function(minder, $tabs, $commandbutton) { /**
* @fileOverview
*
* 节点操作(编辑和删除)
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/idea/operation', function(minder) {
var $commandbutton = minder.getUI('widget/commandbutton');
var $tabs = minder.getUI('ribbon/tabs');
var $opPanel = new FUI.LabelPanel({ var $opPanel = new FUI.LabelPanel({
label: minder.getLang('panels.nodeop'), label: minder.getLang('panels.nodeop'),
column: true column: true
......
KityMinder.registerUI('priority', ['tabs', 'commandbuttonset'], function(minder, $tabs, $commandbuttonset) { /**
* @fileOverview
*
* 添加和修改优先级标签
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/idea/priority', function(minder) {
var $commandbuttonset = minder.getUI('widget/commandbuttonset');
var $tabs = minder.getUI('ribbon/tabs');
var $priorityPanel = new FUI.LabelPanel({ var $priorityPanel = new FUI.LabelPanel({
label: minder.getLang('panels.priority') label: minder.getLang('panels.priority')
......
KityMinder.registerUI('progress', ['tabs', 'commandbuttonset'], function(minder, $tabs, $commandbuttonset) { /**
* @fileOverview
*
* 添加和修改进度标签
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/idea/progress', function(minder) {
var $commandbuttonset = minder.getUI('widget/commandbuttonset');
var $tabs = minder.getUI('ribbon/tabs');
var $progressPanel = new FUI.LabelPanel({ var $progressPanel = new FUI.LabelPanel({
label: minder.getLang('panels.progress') label: minder.getLang('panels.progress')
......
KityMinder.registerUI('resource', ['tabs', 'commandbuttonset'], function(minder, $tabs, $commandbuttonset) { /**
* @fileOverview
*
* 添加和管理资源标签
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/idea/resource', function(minder) {
var $commandbuttonset = minder.getUI('widget/commandbuttonset');
var $tabs = minder.getUI('ribbon/tabs');
var $resourcePanel = new FUI.LabelPanel({ var $resourcePanel = new FUI.LabelPanel({
label: minder.getLang('panels.resource'), label: minder.getLang('panels.resource'),
......
KityMinder.registerUI('tabs', function(minder) { /**
* @fileOverview
*
* Ribbon 选项卡
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('ribbon/tabs', function(minder) {
var $tab = new FUI.Tabs({ var $tab = new FUI.Tabs({
buttons: ['idea', 'appearence', 'view'].map(function(key) { buttons: ['idea', 'appearence', 'view'].map(function(key) {
return minder.getLang('ui.tabs.' + key); return minder.getLang('ui.tabs.' + key);
}) })
}); });
var $title = minder.getUI('topbar/title').$title;
var $header = $('<div id="tab-select"></div>').appendTo('#panel'); var $header = $('<div id="tab-select"></div>');
var $container = $('<div id="tab-container"></div>'); var $container = $('<div id="tab-container"></div>');
$title.before($header);
$('#panel').after($container); $('#panel').after($container);
$tab.appendButtonTo($header[0]); $tab.appendButtonTo($header[0]);
...@@ -27,7 +38,7 @@ KityMinder.registerUI('tabs', function(minder) { ...@@ -27,7 +38,7 @@ KityMinder.registerUI('tabs', function(minder) {
}); });
$tab.idea = $tab.getPanel(0); $tab.idea = $tab.getPanel(0);
$tab.edit = $tab.getPanel(1); $tab.appearence = $tab.getPanel(1);
$tab.view = $tab.getPanel(2); $tab.view = $tab.getPanel(2);
return $tab; return $tab;
......
/**
* @fileOverview
*
*
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
...@@ -2,31 +2,47 @@ ...@@ -2,31 +2,47 @@
position: relative; position: relative;
& > h2 { & > h2 {
&:before {
content: ' ';
display: block;
width: 25px;
height: 25px;
position: absolute;
left: 0;
background: url(../images/icons.png) no-repeat 0 -495px; background: url(../images/icons.png) no-repeat 0 -495px;
} }
}
.pick-file { .pick-file {
padding: 10px 0; padding: 10px 0;
a { a {
display: inline-block; .button;
width: 80px;
height: 30px;
line-height: 30px;
text-align: center;
outline: none;
background: lighten(@tab-active, 20%);
&:hover {
background: lighten(@tab-hover, 20%);
}
&:active {
background: lighten(@tab-active, 15%);
}
cursor: default;
color: @ui-fore;
margin: 0 10px 10px 0; margin: 0 10px 10px 0;
} }
} }
.drop-file { .drop-file {
border: 1px solid #ccc; border: 2px dashed #eee;
.dock(100px, 0, 0); border-radius: 4px;
height: 100px;
width: 100px;
text-align: center;
font-size: 16px;
color: #CCC;
margin: 150px auto;
transition: all .1s ease;
span {
display: block;
margin-top: 25px;
padding: 0 15px;
}
&.accept {
border-color: lighten(@tab-active, 40%);
transform: scale(1.2);
}
&.deny {
border-color: #eee;
color: #eee;
}
} }
} }
\ No newline at end of file
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
transform-origin: 0 0; transform-origin: 0 0;
opacity: 0; opacity: 0;
transition: opacity .25s ease, transform .25s ease; transition: opacity .25s ease, transform .25s ease;
z-index: 10; z-index: 100;
&.show { &.show {
opacity: 1; opacity: 1;
......
.new-file-template-select {
margin: 0;
padding: 0;
list-style: none;
li {
display: inline-block;
position: relative;
width: 120px;
height: 120px;
margin-right: 20px;
margin-bottom: 20px;
cursor: pointer;
a {
display: block;
text-align: center;
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
&:before {
content: ' ';
display: block;
position: absolute;
.dock(0, 0, 24px, 0);
border: 1px solid #ddd;
}
&:after {
content: ' ';
display: block;
position: absolute;
width: 100px;
height: 80px;
left: 50%;
top: 10px;
margin-left: -50px;
background: url(../images/template_large.png) no-repeat;
}
&.default:after {
background-position: 0 0;
}
&.structure:after {
background-position: -100px 0;
}
&.filetree:after {
background-position: -200px 0;
}
&:hover {
a {
color: @main-menu-theme-color;
}
&:before {
border: 1px solid @main-menu-theme-color;
}
}
&:active:before {
background-color: lighten(@main-menu-theme-color, 20%);
}
}
}
\ No newline at end of file
.netdisk-nav { .netdisk-finder-container {
.netdisk-nav {
padding-bottom: 10px; padding-bottom: 10px;
height: 30px; height: 30px;
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
...@@ -51,9 +52,9 @@ ...@@ -51,9 +52,9 @@
background-color: lighten(@tab-active, 55%) background-color: lighten(@tab-active, 55%)
} }
} }
} }
.netdisk-file-list { .netdisk-file-list {
margin: 0; margin: 0;
padding: 0; padding: 0;
list-style: none; list-style: none;
...@@ -111,6 +112,91 @@ ...@@ -111,6 +112,91 @@
top: 20px; top: 20px;
margin-top: -4px; margin-top: -4px;
} }
input {
margin: 0;
outline: none;
width: 61.80%;
}
}
}
}
.netdisk-mkdir {
position: absolute;
right: 0;
top: 0;
}
.login-tip {
display: none;
text-align: center;
font-size: 16px;
color: #999;
margin-top: 30px;
a {
text-decoration: underline;
color: @main-menu-theme-color;
cursor: pointer;
&:hover {
color: lighten(@main-menu-theme-color, 10%);
}
}
}
&.require-login {
.login-tip {
display: block;
}
.netdisk-nav, .netdisk-file-list {
display: none;
}
}
}
// for save
.netdisk-save-panel .netdisk-file-list {
bottom: 60px;
}
.netdisk-save-select {
.dock(auto, 0, 0, 0);
height: 30px;
padding: 10px;
border-top: 1px solid #EEE;
background: #fcfcfc;
label {
display: inline-block;
padding: 0 10px 0 0;
vertical-align: middle;
margin-top: 5px;
}
& > input {
width: 50%;
padding: 2px 5px;
height: 16px;
outline: none;
border: 1px solid lighten(@tab-hover, 30%);
margin: 0;
margin-top: 5px;
&:focus {
border-color: lighten(@tab-active, 40%);
}
vertical-align: middle;
}
& > select {
margin: 5px 0 0 10px;
outline: none;
vertical-align: middle;
} }
& > .save-button {
position: absolute;
right: 10px;
top: 10px;
width: 80px;
} }
} }
\ No newline at end of file
.recent-file-panel {
h2 {
&:before {
content: ' ';
display: block;
width: 25px;
height: 25px;
position: absolute;
left: 0;
top: 2px;
background: url(../images/icons.png) no-repeat 0 -520px;
}
}
& > .recent-file-list {
margin: 0;
padding: 0;
list-style: none;
.recent-file-item {
font-size: 14px;
line-height: 20px;
padding: 10px 20px 10px 40px;
cursor: default;
position: relative;
&:hover {
background-color: lighten(@tab-hover, 55%);
}
&:active {
background-color: lighten(@tab-hover, 50%);
}
.file-name {
margin: 0;
font-weight: normal;
height: 20px;
line-height: 20px;
&:after {
content: ' ';
display: block;
position: absolute;
width: 25px;
height: 25px;
background: url(../images/icons.png) no-repeat 0 -445px;
left: 5px;
top: 10px;
}
}
.file-title {
margin: 0;
margin-top: 5px;
font-size: 12px;
color: #999;
}
.file-time {
position: absolute;
right: 5px;
top: 10px;
font-size: 12px;
color: #999;
}
}
}
}
\ No newline at end of file
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
} }
} }
.command-inputmenu { .command-inputmenu, .fui-input-menu {
& > .fui-input-button { & > .fui-input-button {
position: relative; position: relative;
.fui-input { .fui-input {
...@@ -304,11 +304,28 @@ ...@@ -304,11 +304,28 @@
border-color: red !important; border-color: red !important;
} }
.button, button {
display: inline-block;
height: 30px;
padding: 0 15px;
line-height: 30px;
text-align: center;
outline: none;
background: lighten(@tab-active, 20%);
&:hover {
background: lighten(@tab-hover, 20%);
}
&:active {
background: lighten(@tab-active, 15%);
}
cursor: default;
color: @ui-fore;
border: none;
}
input[type=text] {
padding: 2px 5px;
height: 16px;
outline: none;
border: 1px solid lighten(@tab-hover, 30%);
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
...@@ -7,10 +7,12 @@ ...@@ -7,10 +7,12 @@
@import "_kityminder"; @import "_kityminder";
@import "_mainmenu"; @import "_mainmenu";
@import "_mainmenu.new.less";
@import "_history"; @import "_history";
@import "_tab"; @import "_tab";
@import "_search"; @import "_search";
@import "_user"; @import "_user";
@import "_recent";
@import "_netdisk"; @import "_netdisk";
@import "_localfile"; @import "_localfile";
......
ui/theme/default/images/icons.png

8.28 KB | W: | H:

ui/theme/default/images/icons.png

8.9 KB | W: | H:

ui/theme/default/images/icons.png
ui/theme/default/images/icons.png
ui/theme/default/images/icons.png
ui/theme/default/images/icons.png
  • 2-up
  • Swipe
  • Onion skin
KityMinder.registerUI('title', function (minder) {
var $title = $('<h1>').appendTo('#panel').text('百度脑图');
return $title;
});
\ No newline at end of file
/**
* @fileOverview
*
* 历史控制按钮
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('topbar/history', function(minder) {
var ret = {};
var commandbutton = minder.getUI('widget/commandbutton');
['undo', 'redo'].forEach(function(command) {
ret[command] = commandbutton.generate(command).appendTo(document.getElementById('panel'));
});
return ret;
});
\ No newline at end of file
KityMinder.registerUI('search', function(minder) { /**
* @fileOverview
*
* 搜索节点功能
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('topbar/search', function(minder) {
var $search = $('<div id="search"><input type="search" /></div>').appendTo('#panel'); var $search = $('<div id="search"><input type="search" /></div>').appendTo('#panel');
return $search; return $search;
......
/**
* @fileOverview
*
* 显示并更新脑图文件的标题
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('topbar/title', function(minder) {
var $title = $('<h1>').appendTo('#panel');
var _title = minder.getLang('ui.untitleddoc');
var _saved = false;
function update() {
function setTitle(title) {
$title.text(title);
document.title = title + ' - 百度脑图';
}
if (_saved) {
setTitle(_title);
} else {
setTitle('* ' + _title);
}
}
update();
return {
$title: $title,
setTitle: function(title, saved) {
_title = title;
return this.setSaved(saved);
},
getTitle: function() {
return _title;
},
setSaved: function(saved) {
if (saved !== false) {
_saved = true;
}
update();
return this;
}
};
});
\ No newline at end of file
KityMinder.registerUI('user', function(minder) { /**
* @fileOverview
*
* 用户登录控制
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('topbar/user', function(minder) {
var eve = minder.getUI('eve');
var currentUser; var currentUser;
...@@ -14,6 +24,7 @@ KityMinder.registerUI('user', function(minder) { ...@@ -14,6 +24,7 @@ KityMinder.registerUI('user', function(minder) {
/* 用户按钮 */ /* 用户按钮 */
var $userButton = new FUI.Button({ var $userButton = new FUI.Button({
icon: { icon: {
// 1px 透明图
img: 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=' img: 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='
}, },
className: 'user-button' className: 'user-button'
...@@ -67,6 +78,7 @@ KityMinder.registerUI('user', function(minder) { ...@@ -67,6 +78,7 @@ KityMinder.registerUI('user', function(minder) {
fio.user.check().then(check); fio.user.check().then(check);
$loginButton.on('click', login); $loginButton.on('click', login);
$('body').delegate('.login-button', 'click', login);
function check(user) { function check(user) {
if (user) { if (user) {
...@@ -74,6 +86,7 @@ KityMinder.registerUI('user', function(minder) { ...@@ -74,6 +86,7 @@ KityMinder.registerUI('user', function(minder) {
$userButton.getIconWidget().setImage(user.smallImage); $userButton.getIconWidget().setImage(user.smallImage);
$userButton.show(); $userButton.show();
$loginButton.hide(); $loginButton.hide();
fio.user.fire('login', user);
} else { } else {
$loginButton.show(); $loginButton.show();
$userButton.hide(); $userButton.hide();
...@@ -85,6 +98,7 @@ KityMinder.registerUI('user', function(minder) { ...@@ -85,6 +98,7 @@ KityMinder.registerUI('user', function(minder) {
fio.user.logout(); fio.user.logout();
$loginButton.show(); $loginButton.show();
$userButton.hide(); $userButton.hide();
fio.user.fire('logout');
} }
function login() { function login() {
...@@ -103,6 +117,9 @@ KityMinder.registerUI('user', function(minder) { ...@@ -103,6 +117,9 @@ KityMinder.registerUI('user', function(minder) {
return { return {
getCurrent: function() { getCurrent: function() {
return currentUser; return currentUser;
},
loginLink: function() {
return $('<a></a>').click(login);
} }
}; };
}); });
\ No newline at end of file
/**
* @fileOverview
*
* KityMinder UI 注册及加载机制
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
(function() { (function() {
var uiQueue = []; var uiQueue = [];
...@@ -28,7 +37,7 @@ ...@@ -28,7 +37,7 @@
}); });
// 阻止非脑图事件冒泡 // 阻止非脑图事件冒泡
$('#content-wrapper').delegate('#panel, #tab-container, .fui-dialog', 'click mousedown keydown keyup', function(e) { $('#content-wrapper').delegate('#panel, #tab-container, .fui-dialog, #main-menu', 'click mousedown keydown keyup', function(e) {
e.stopPropagation(); e.stopPropagation();
}); });
......
KityMinder.registerUI('commandbutton', function(minder) { /**
* @fileOverview
*
* 生成绑定到某个命令的按钮
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('widget/commandbutton', function(minder) {
return { return {
generate: function(command, onclick) { generate: function(command, onclick) {
var $button = new FUI.Button({ var $button = new FUI.Button({
label: minder.getLang('ui.' + command), label: minder.getLang('ui.' + command),
......
KityMinder.registerUI('commandbuttonset', function(minder) { /**
* @fileOverview
*
* commandbuttonset.js 生成与指定命令绑定的按钮
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('widget/commandbuttonset', function(minder) {
function mapValueItem(command, valueList) { function mapValueItem(command, valueList) {
return valueList.map(function(value) { return valueList.map(function(value) {
var text = minder.getLang([command, value].join('.')) || value; var text = minder.getLang([command, value].join('.')) || value;
......
KityMinder.registerUI('commandinputmenu', function(minder) { /**
* @fileOverview
*
* 绑定到某个命令的下拉选框
*
*/
KityMinder.registerUI('widget/commandinputmenu', function(minder) {
function generate(command, menuList) { function generate(command, menuList) {
......
KityMinder.registerUI('fileloader', function (minder) { /**
* @fileOverview
*
* 完成加载一个脑图文件的流程
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('widget/fileloader', function(minder) {
var $container = $(minder.getRenderTarget()); var $container = $(minder.getRenderTarget());
...@@ -6,17 +15,27 @@ KityMinder.registerUI('fileloader', function (minder) { ...@@ -6,17 +15,27 @@ KityMinder.registerUI('fileloader', function (minder) {
function getProtocolByExtension(extension) { function getProtocolByExtension(extension) {
for (var protocol in supports) { for (var protocol in supports) {
if (supports[protocol].fileExtension == extension) return protocol; if (supports[protocol].fileExtension == extension) return supports[protocol];
} }
return false; return false;
} }
function load(file) { function load(file) {
var protocol = getProtocolByExtension(file.extension); var protocol = getProtocolByExtension(file.extension);
minder.importData(file.data.content, protocol).then(function() {
return minder.importData(file.data.content, protocol.name).then(function(json) {
var $title = minder.getUI('topbar/title');
$title.setTitle(file.filename);
$container.removeClass('loading'); $container.removeClass('loading');
minder.execCommand('camera', minder.getRoot(), 300); minder.execCommand('camera', minder.getRoot(), 300);
}, error);
return {
file: file,
json: json
};
});
} }
function error(err) { function error(err) {
...@@ -27,7 +46,7 @@ KityMinder.registerUI('fileloader', function (minder) { ...@@ -27,7 +46,7 @@ KityMinder.registerUI('fileloader', function (minder) {
return { return {
load: function(filePromise) { load: function(filePromise) {
$container.addClass('loading'); $container.addClass('loading');
Promise.resolve(filePromise).then(load, error); return Promise.resolve(filePromise).then(load)['catch'](error);
}, },
support: function(file) { support: function(file) {
......
/**
* @fileOverview
*
* 渲染当前时间离指定时间的时长
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('widget/friendlytimespan', function(minder) {
function getFriendlyTimeSpan(t1_in_ms, t2_in_ms) {
t2_in_ms = t2_in_ms || +new Date();
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 minder.getLang('ui.justnow', s | 0);
if (m < 60) return minder.getLang('ui.minutesago', m | 0);
if (h < 24) return minder.getLang('ui.hoursago', h | 0);
if (d < 2) return minder.getLang('ui.yesterday');
if (d <= 30) return minder.getLang('ui.daysago', d | 0);
return minder.getLang("ui.longago");
}
return {
display: getFriendlyTimeSpan
};
});
\ No newline at end of file
/**
* @fileOverview
*
* 提供存储在 LocalStorage 中的列表
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('widget/locallist', function() {
function LocalList(name, maxCount) {
var list;
maxCount = maxCount || 10;
function load() {
list = localStorage.getItem(name);
if (list) {
list = JSON.parse(list);
} else {
list = [];
}
}
function save() {
while (list.length > maxCount) list.pop();
localStorage.setItem(name, JSON.stringify(list));
}
function get(index) {
return list[index];
}
function remove(index) {
list.splice(index, 1);
save();
}
function unshift(item) {
list.unshift(item);
save();
}
function createKeyMatcher(key) {
return function(item, value) {
return item[key] == value;
};
}
function findIndex(matcher, value) {
if (typeof(matcher) == 'string') {
matcher = createKeyMatcher(matcher);
}
for (var i = 0; i < list.length; i++) {
if (matcher(list[i], value)) return i;
}
return -1;
}
function find(matcher, value) {
return get(findIndex(matcher, value));
}
function forEach(callback) {
list.forEach(callback);
}
load();
this.get = get;
this.remove = remove;
this.findIndex = findIndex;
this.find = find;
this.forEach = forEach;
this.unshift = unshift;
}
return {
use: function(name) {
return new LocalList(name);
}
};
});
\ No newline at end of file
/**
* @fileOverview
*
* 网盘的目录访问组件
*
* @author: techird
* @copyright: Baidu FEX, 2014
*/
KityMinder.registerUI('widget/netdiskfinder', function(minder) {
var eve = minder.getUI('eve');
/**
* 生成一个网盘的目录访问组件
*
* @param {JQueryObject} $container 容器
* @param {function} listFilter 一个函数,检查一个文件是否应该被列出
*/
function generate($container, listFilter) {
var finder = eve.setup({});
var base = '/apps/kityminder';
var currentPath = base;
/* 路径导航 */
var $nav = $('<div class="netdisk-nav"></div>')
.appendTo($container);
/* 显示当前目录文件列表 */
var $list = $('<ul class="netdisk-file-list"></ul>')
.appendTo($container);
var $tip = $('<p class="login-tip"></p>')
.html(minder.getLang('ui.requirelogin'))
.appendTo($container);
var $mkdir = $('<a></a>')
.text(minder.getLang('ui.mkdir'))
.addClass('button netdisk-mkdir')
.click(mkdir);
$nav.after($mkdir);
$container.addClass('netdisk-finder-container');
/* 点击目录中的项目时打开项目 */
$list.delegate('.netdisk-file-list-item', 'click', function(e) {
var $file = $(e.target),
file = $file.data('file');
if (file) open(file);
});
/* 点击导航处,切换路径 */
$nav.delegate('a', 'click', function(e) {
if ($(e.target).hasClass('dir-back')) {
var parts = currentPath.split('/');
parts.pop(); // 有一个无效部分
parts.pop();
return list(parts.join('/'));
}
list($(e.target).data('path'));
});
fio.user.on('login', show);
fio.user.on('logout', hide);
hide();
function mkdir() {
var $li = $('<li>').addClass('netdisk-file-list-item dir').prependTo($list);
var $input = $('<input>')
.attr('type', 'text')
.addClass('new-dir-name')
.val(minder.getLang('ui.newdir'))
.appendTo($li);
$input[0].select();
$input.on('keydown', function(e) {
if (e.keyCode == 13) {
var name = $input.val();
$li.remove();
}
});
}
function show() {
$container.removeClass('require-login');
list();
}
function hide() {
$container.addClass('require-login');
}
/**
* 返回数值的符号:
* 正数 => 1
* 0 => 0
* 负数 => -1
*/
function sign(num) {
return num > 0 ? 1 : (num < 0 ? -1 : 0);
}
/**
* 打开选中的文件或目录
*
* @param {fio.file.File} file
*/
function open(file) {
if (file.isDir) return list(file.path);
finder.fire('fileclick', file);
}
function fadeOutList(x) {
return new Promise(function(resolve, reject) {
$list.transit({
x: x,
opacity: 0
}, 100, resolve);
});
}
function fadeInList() {
return new Promise(function(resolve) {
$list.css({
x: -parseInt($list.css('x'))
}).stop().transit({
x: 0,
opacity: 1
}, 100, resolve);
});
}
/**
* 列出指定目录的文件
*/
function list(path) {
path = path || base;
var listPromise = fio.file.list({
path: path
});
var transitPromise = fadeOutList(-100 * sign(path.length - currentPath.length));
Promise.all([listPromise, transitPromise]).then(renderList, function(error) {
window.alert('加载目录发生错误:' + error);
});
currentPath = path.charAt(path.length - 1) == '/' ? path : path + '/';
updateNav();
}
function renderList(values) {
$list.empty();
var files = values[0];
if (!files.length) {
$list.append('<li class="empty" disabled="disabled">' + minder.getLang('ui.emptydir') + '</li>');
} else {
files.forEach(function(file) {
if (!file.isDir && (!listFilter || !listFilter(file))) return;
$('<li></li>')
.text(file.filename)
.addClass('netdisk-file-list-item')
.addClass(file.isDir ? 'dir' : 'file')
.data('file', file)
.appendTo($list);
});
}
fadeInList();
finder.fire('cd', currentPath);
}
function updateNav() {
$nav.empty();
if (currentPath != base && currentPath != base + '/') {
$nav.append('<a class="dir-back">Back</a>');
} else {
$nav.append('<span class="my-document"></span>');
}
var path = currentPath.substr(base.length);
var parts = path.split('/');
var processPath = '';
function pathButton(part) {
processPath += part + '/';
var $a = $('<a></a>');
if (part == base) {
$a.text(minder.getLang('ui.mydocument'));
} else {
$a.text(part);
}
return $a.data('path', processPath);
}
$nav.append(pathButton(base));
parts.forEach(function(part) {
if (!part) return;
$nav.append('<span class="spliter"></span>');
$nav.append(pathButton(part));
});
}
finder.list = list;
return finder;
}
return {
generate: generate
};
});
\ 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