或许,这个简陋的项目更应该被称为
Electron && JavaScript
的最佳实践!
最初这个项目是基于Steve Kinney的 《Electron跨平台开发实战》 一书第三章的Fire Sale项目。这本书写的挺好,通俗易懂,并且比较有借鉴价值。本来的计划是抛开那本书重新构建Neeto的架构,但有些代码我也不想做重复工作,所以就没有另开一个工程。
这个项目用了很多node仓库里的第三方模块,没有这些模块我也很难在十天左右的开发工期里完成Neeto的编写。比较核心的有下面这几个:
"jquery": "^3.4.1"
"mdui": "^0.4.3"
一个Google MD设计规范的UI库"showdown": "^1.9.1"
Neeto使用的markdown语法解析器"showdown-highlight": "^2.1.3"
showdown的代码语法解析插件"showdown-katex": "^0.6.0"
showdown的LaTeX语法解析插件"simplemde": "^1.11.2"
替代原本的textarea组件,实现更加丰富的操作不过我在写Neeto时基本没有用到当下流行的第三方库:Vue or React or Angular
,因为我想要在下个版本中用Vue重写Neeto,有很多方面都有改进的空间。并且因为我是基本上用的纯JavaScript
写的,所以好多地方都十分的原始而简陋。我执意用原生js写的另一个目的就是尽可能熟悉js的一些用法,包括回调,异步,非阻塞性等等。
说到思路,不得提我最喜欢的Markdown编辑器-Typora
毫无疑问,我相信Typora
一定是Windows与MacOs上最优秀的编辑器,简洁,功能丰富,设计优雅。我的数据结构复习与汇编复习都是用Typora
完成的,它是如此的完美以至于让我都快忘记了它的一些瑕疵。
它所见即所得(WYSIWYG)的实现效果让我理所当然的觉得,一款编辑器不就应该这样吗。当你写下你的灵感,编辑器将你的灵感完整无误地渲染成你所想的样子。
因此我在改写之时,就准备将Typora
作为Neeto最好的榜样,并且我希望能比Typora
做的更好!
所以说,这个项目更像是补全,弥补我在Typora
中未能得到的遗憾:
可以比较清晰的看到,我所想要实现的几个需求基本上都与网络相关,而Typora
给自己的定位就仅仅是
Readable & Writable
读写是Typora
的核心功能,可以预见,作者并不准备为Typora
提供与网络相关的功能,在win与mac两个平台上,也仅仅只有mac可以用一个插件来上传本地图片。
Neeto的后期计划表里也有打算实现插件系统,不过应该会是很后面
我在这个版本Version_1.0.8
中,使用json文件来存储图床的配置信息,这只是实验性的尝试,并不保证长期有效性
后续我会支持更多的图床,如阿里云OSS,腾讯云COS,七牛云CDN等等。
什么是图床:
图床是网络图片的一种存储方式,Web页面通过一条URL来获取图片。用户将图片上传到图床之后,图床服务器返回一条JSON消息,其中包含上传图片的网络URL,使用图床给定的图片链接就可以在多个地方调用图片,而不会出现本地图片无法直接使用的尴尬场面。
点击Neeto头部的菜单栏,可以看到文件菜单选项。
点击之后会出现复制成功的提示
然后直接前往微信公众号后台粘贴就可以实现带格式粘贴。
使用时需要注意的几个地方:
图片上传技巧
可以将图片直接拖入左侧的文本编辑区域,也可以用QQ,Wechat等软件的截图工具截图后,直接在文本编辑区内粘贴,粘贴成功后顶部会出现LightTip提示上传成功。
这个功能是基于原书上拖入事件更改的,但我觉得是一个很有意思的部分,可以通过这一部分理解JS的处理哲学。
// 监听drop事件--JavaScript是事件驱动的
smde.codemirror.on("drop", function (editor, e) {
//获取文件对象
const file = getDroppedFile(e)
//获取dataTransfer对象
var df = e.dataTransfer
//处理文件
dealWithFile(file, df)
});
const dealWithFile = (file, df) => {
// 文件对象数组
var dropFiles = []
console.log(file)
if (fileTypeIsSupported(file)) {
// 如果这个文件是图片类型的,就去处理这个文件对象
if (file.type.indexOf("image") !== -1) {
// 获取图片的File对象
if (df.items !== undefined) {
// Chrome有items属性,对Chrome的单独处理
for (var i = 0; i < df.items.length; i++) {
var item = df.items[i];
console.log(item.getAsFile())
// 用webkitGetAsEntry禁止上传目录
if (item.kind === "file" && item.webkitGetAsEntry().isFile) {
var dropFile = item.getAsFile();
// 判断完这个对象之后压入数组中
dropFiles.push(dropFile);
}
}
}
// 上传到图床
dropFiles.forEach(file => {
// formdata的作用是构建post的请求body部分
const formdata = new FormData()
formdata.append('image', file)
// loading是加载动画的一段语句,在图片上传的过程中用于占位
smde.codemirror.doc.replaceSelection(loading)
if (baseConfig.picBedUrl) {
uploadToPicBeds(formdata, baseConfig.picBedUrl, baseConfig.token)
.then(res => {
var finalUrl = ``
smde.codemirror.doc.undoSelection()
smde.codemirror.doc.replaceSelection(finalUrl)
rendererMarkDownToHtml(smde.value())
//LightTip是LuLuUI库的一个组件,我认为挺好看的,所以很多地方都用到了这个组件
new LightTip().success('图床图片上传成功', 2000);
})
.catch(res => {
smde.codemirror.doc.undoSelection()
new LightTip().error('图床图片上传失败,请检查图床配置', 4000);
finalUrl = `![${file.name}](${file.path})`
smde.codemirror.doc.replaceSelection(finalUrl)
rendererMarkDownToHtml(smde.value())
})
} else {
var finalUrl = `![${file.name}](${file.path})`
smde.codemirror.doc.undoSelection()
smde.codemirror.doc.replaceSelection(finalUrl)
rendererMarkDownToHtml(smde.value())
new LightTip().success('本地图片添加成功', 2000);
}
});
} else {
mainProcess.openFile(currentWindow, file.path)
}
} else {
new LightTip().error('该文件类型暂时无法上传', 4000);
}
}
不得不承认,有很多地方我都没有做完,甚至完成度只有 60 60% 60,但我急于进入Vue的学习开发,就不得不将纯JavaScript的版本早点完结。
如果你使用了Neeto并且有任何意见或是反馈,请及时告知我,告知的方法也很简单,点击左侧下部的小飞机按钮,填写建议还有您的联系方式即可,万分感谢
Markdown Guide
Emphasis
**bold**
*italics*
~~strikethrough~~
Headers
# Big header
## Medium header
### Small header
#### Tiny header
Lists
* Generic list item
* Generic list item
* Generic list item
1. Numbered list item
2. Numbered list item
3. Numbered list item
Links
[Text to display](http://www.example.com)
Quotes
> This is a quote.
> It can span multiple lines!
Images Need to upload an image? Imgur has a great interface.
![](http://www.example.com/image.jpg)
Tables
| Column 1 | Column 2 | Column 3 |
| -------- | -------- | -------- |
| John | Doe | Male |
| Mary | Smith | Female |
Or without aligning the columns...
| Column 1 | Column 2 | Column 3 |
| -------- | -------- | -------- |
| John | Doe | Male |
| Mary | Smith | Female |
Displaying code
`var example = "hello!";`
Or spanning multiple lines...
code
var example = "hello!";
alert(example);
code
数学公式实现:支持LaTeX语法
α , β , B , γ , Γ , π , Π , ϕ , φ , μ , Φ \alpha, \beta, \Beta, \gamma, \Gamma, \pi, \Pi, \phi, \varphi, \mu, \Phi α,β,B,γ,Γ,π,Π,ϕ,φ,μ,Φ
cos ( 2 θ ) = cos 2 θ − sin 2 θ \cos(2 \theta) = \cos ^ 2 \theta - \sin ^ 2 \theta cos(2θ)=cos2θ−sin2θ
lim x → ∞ ( e ( − x ) ) = 0 \lim_{x \to \infty}^ (e^(-x)) = 0 limx→∞(e(−x))=0
写在最后
说实话吧,好长一段时间里我都听不喜欢前端的,因为在我的刻板前端不就是切图吗,然后写点小动画,有什么前途,但是说来容易做时难啊,真正放开手去做的时候才能切身感受到前端也已经不仅仅是前端了,不过,还是要两头兼顾,前后端都要掌握。
最后一些屁话,应该没有人真的会看到这里吧。说真的,大学越活越糊涂我是真的有点难受,学习也整不起来,技术也学不明白,身体也没有很好//PS:本武汉(回来的)人已经14天未见异常了,所以我不是患者!!但是我好像有点感冒…
可以前往Neeto官网 查看源码和更多信息,项目已经在GitHub和Gitea开源了,如果可以的话,能为我点个Star吗!!!!这对我真的很重要(cxx语气)