这个前端系列算个天坑了,自己坑自己。最近炉石也冲上传说了,没啥好玩的事,和朋友聊天时安利我看一部叫《IT狂人》的剧,于是想到把这个坑给填一填。
自从用hexo构筑个人博客后就开始用markdown,但是用了好几个编辑器都没有一个适合自己使用的。于是前段时间就照着教程自己动手敲了一个,从这篇开始,我会把整个开发过程记录成系列随笔。其实nodejs已经不能算前端了,勉强和javascript搭上点关系,但是实在不想再开新坑,将就这个标题继续用吧0v0,这样我的blog也有干货持续更新了。
简介
先介绍下开发过程中用到的一些开源项目:
- nw.js,用webkit和node做基于web技术的跨平台客户端软件
- CodeMirror,基于web技术实现的文本编辑器,实现了大部分的IDE功能
- angularjs,google的mvvm框架,这个相信不用我多做介绍。我用得不熟,觉得好用就开袋即食,没有深入的了解
项目结构
大概讲一下目录和文件的用途:
incudtl.dat
,nw.exe
,nw.pak
这3个是nw.js在windows运行所必须的文件。package.json
nw.js的配置文件
{
"name": "HexoMD",
"description": "Markdown for hexo",
"main": "app/index.html", //程序入口页面
"author": "shurrik",
"license": "MIT",
"directories": {
"test": "no"
},
"devDependencies": {},
"window": {
"title": "HexoMD",
"icon": "app/img/logo.png",
"toolbar": false, //是否显示地址栏工具条(很重要)
"frame": false, //是否显示程序边框
"width": 1000,
"height": 700,
"position": "center",
"min_width": 600,
"min_height": 400
}
}
app目录
程序的所有源代码的根目录app/lib
存放angular,jquery,codemirror等开源库/框架的源代码app/helpers
存放一些nodejs的工具函数app/modules
程序代码在这个目录,按功能模块分成不同的子目录app/package.json
node模块配置,注意与上层的package.json不同
主界面
代码都在github上,我这里只贴出部分。
界面采用三栏布局,分别为导航栏
、内容区
,工具条
。为了美观,我在配置里去掉了系统自带的边框,因此要实现自定义的拖动窗口功能还需要增加一些设置。所谓的设置,其实只要加上对应的样式即可,功能都由nw.js实现了。
.navbar{
-webkit-app-region: drag;
}
另外为了让编辑器看起来更像客户端一点,我禁用掉了文本选择,防止一些被作为按钮的a标签被选中。
html{
height: 100%;
-webkit-user-select: none;
}
app.js
app.js作为程序的入口点,定义了整个项目的结构,需要特别拿出来说一下。
angular.module('hmd', ['ui.router','hmd.studio'])
定义angular模块,modules
所有的业务模块都会放到单独的子目录里,如这里注册的hmd.studio
//模块根目录
var baseModuleDir = './app/modules/';
//引入模块,模块内js文件会被自动加载到页面中
hmd.regModule = function (name, reqModule) {
hmd[name] = angular.module('hmd.' + name, reqModule || []);
hmd[name].moduleName = name;
//模块存储数据的目录
hmd[name].dataPath = hmd.storeDir + '\\' + hmd[name].moduleName;
fs.readdirSync(baseModuleDir + name)
.forEach(function (file) {
if (~file.indexOf('.js')) {
document.write('<script src="modules/' + name + '/' + file + '"></script>');
}
});
};
导航栏按钮
导航栏右边有3个按钮,分别为最小化、最大化、关闭,在modules根目录的directives.js
用于实现。
(function () {
var gui = require('nw.gui'), win = gui.Window.get(),winMaximize = false;
angular.module('hmd.directives', [])
//最小化窗口
.directive('hmdMinisize', [function () {
return function (scope, elem) {
$(elem[0]).on('click', function () {
win.minimize();
});
};
}])
//最大化与还原窗口
.directive('hmdMaxToggle', [function () {
return function (scope, elem) {
//窗口最大化和还原时会触发对应的事件,在事件里去控制按钮样式.
//TODO:这里的实现应该可以更优雅一点,以后再说
win.on('maximize', function () {
winMaximize = true;
$(elem[0]).find('i').removeClass('glyphicon-fullscreen').addClass('glyphicon-resize-small');
});
win.on('unmaximize', function () {
winMaximize = false;
$(elem[0]).find('i').removeClass('glyphicon-resize-small').addClass('glyphicon-fullscreen');
});
//切换窗口状态
$(elem[0]).on('click', function () {
if (winMaximize) {
win.unmaximize();
}
else {
win.maximize();
}
});
};
}])
//关闭应用程序
.directive('hmdClose', [function () {
return function (scope, elem) {
$(elem[0]).on('click', function () {
require('nw.gui').Window.get().close();
});
};
}]);
})();
定义了全局directive模块angular.module('hmd.directives', [])
,接下来将directive应用到按钮上,将script添加到index.html的app.js之后。
app.js里的angular模块注册里增加hmd.directives模块angular.module('hmd', ['ui.router','hmd.directives','hmd.studio'])
总结
到此页面布局方面基本完成,编辑器功能的实现放在后面继续写。还有我对angularjs
了解并不深,很多用法总感觉有问题,有空再深入看看angularjs吧。