跳转至

F2E_6markdown编辑器的实现-01

这个前端系列算个天坑了,自己坑自己。最近炉石也冲上传说了,没啥好玩的事,和朋友聊天时安利我看一部叫《IT狂人》的剧,于是想到把这个坑给填一填。

自从用hexo构筑个人博客后就开始用markdown,但是用了好几个编辑器都没有一个适合自己使用的。于是前段时间就照着教程自己动手敲了一个,从这篇开始,我会把整个开发过程记录成系列随笔。其实nodejs已经不能算前端了,勉强和javascript搭上点关系,但是实在不想再开新坑,将就这个标题继续用吧0v0,这样我的blog也有干货持续更新了。

简介

先介绍下开发过程中用到的一些开源项目:

  1. nw.js,用webkit和node做基于web技术的跨平台客户端软件
  2. CodeMirror,基于web技术实现的文本编辑器,实现了大部分的IDE功能
  3. angularjs,google的mvvm框架,这个相信不用我多做介绍。我用得不熟,觉得好用就开袋即食,没有深入的了解

项目结构

大概讲一下目录和文件的用途:

  1. incudtl.dat,nw.exe,nw.pak这3个是nw.js在windows运行所必须的文件。
  2. package.jsonnw.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 }

} ```

  1. app目录 程序的所有源代码的根目录
  2. app/lib 存放angular,jquery,codemirror等开源库/框架的源代码
  3. app/helpers 存放一些nodejs的工具函数
  4. app/modules 程序代码在这个目录,按功能模块分成不同的子目录
  5. 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吧。