#1 从零开始制作在线 代码编辑器

#1 从零开始制作在线 代码编辑器_第1张图片

上一篇
#0 从零开始制作在线 代码编辑器

目录结构和说明


目录初始结构

创建一些目录以及文件,如图1-1 所示。这里只是随手创的,也可以自定目录结构。

#1 从零开始制作在线 代码编辑器_第2张图片
1-1 目录结构

目录说明

  • serval/script/harusame-dom.js 提供了创建 DOM 的工具,比createElement(tagName) 那种要稍微方便一点,创建方式借鉴了虚拟DOM。使用方式就在这里说明了,之后也不细说。
// 创建元素节点
var $node = SatoriDom.compile(e('div', {'class': 'demo', 'id': 'demo'}, '这里是文本节点: parent', [
    e('div', {'class': 'child'}, [
        e('p', '这里是文本节点: child x child')
    ])
]))

console.log($node.tagName) // DIV

// 其他可能用到的方式
function template_submit (data) {
    var $event_node = SatoriDom.compile(e('input', {'class': 'i-have-event', 'type': 'submit'}))

    $event_node.addEventListener('click', function (event) {
        console.log('You click me:' + data.content)
    })

    return SatoriDom.compile(e('form', {'class': 'this-is-a-form'}, [
        $event_node
    ]))
}

  • serval/script/harusame-template.js 存放了一些模板,把与创建DOM 相关的代码抽离出来,避免其在逻辑代码中占用很多篇幅。

  • serval/script/harusame-cursor.js 光标会被单独抽象成一个类。

  • serval/script/harusame-serval.js 绑定整个编辑器的事件,以及逻辑的处理,最重要的部分。

  • serval/style/normalize.scss 见 normalize.scss 官网,这里改了后缀只是方便后缀格式相同....

  • serval/style/harusame-code.scss 是目录 serval/style/code/ 下所有需要高亮的语言的样式的 入口,这样便于以后做其他语言的样式扩展。这里先有能力解决 js 的语法高亮再想着其他语言吧。

  • serval/style/harusame-serval.scss 描述了编辑器样式。

先直接描绘出成型后的编辑器


对着已有的优秀的编辑器观察,把看到的东西抽象成几部分,再根据这些编写成 DOMs 。
这里对着 Sublime Text 3 截了一张图 1-2:

#1 从零开始制作在线 代码编辑器_第3张图片
1-2 Sublime Text 3

挺小也挺简单的一张图,但是包含了想做的编辑器的大部分所需 DOMs,或者称他为组件,这里说下明确当前要做的部分:

  • 行号 ( 6 ~ 15)
  • 光标 ( 第七行最后的白色竖线),与多重光标(7, 9, 15)
  • 选中行提示(比如第七行)
  • 选中内容提示(比如第九行,第 13 ~ 15 行)
    这里插入一点,以下内容会是显而易见的,但是也是编辑器组成中最最重要的,尽量把这些理所当然的也把它梳理出来,毕竟他们也需要 DOM 来显示
  • 行的内容(比如第七行的 state = {
  • 编辑器样式(比如这里深灰色,行号的灰色,非关键词的白色)
    以下是一些肉眼看不到的
  • 行能够接受键盘输入
  • 点击一个位置,光标会自动偏移到该行中,离点击字符最近的位置。
  • 行号无法选中

至于一些其他的细节:代码高亮,成对的括号提示等,这里会放在以后再做/说。

于是根据这些梳理好的内容,转换成 DOMs:

  • 编辑器容器 设置编辑器的背景颜色等,也是存放 其他容器的容器(父节点)
  • 光标容器 存放 所有光标 的元素节点
  • 行容器 存放 一行 的元素节点,包括它的行号,以及行的内容
  • 选择容器 存放比如 当前选择行,选择内容 的背景高亮的元素节点
  • 键盘输入事件接收器 正如之前所说(好像说了),一个 div 本身是不能接受键盘事件的,需要一个接受键盘事件的容器,再将事件的处理逻辑与相应的元素节点绑定。

以上就是需要的 DOMs 了,包含关系也基本没啥问题了:

文件路径 serval/index

1
                            
                            const PI = 3.1415
                        
2
                            console.info('PI', PI)
                        
3