Ben-love-zy / web-editor-markdown

A Markdown editor in browser with collaborative editing
MIT License
395 stars 94 forks source link

没太明白 MNode 是个什么样的结构 #6

Open jiulu313 opened 1 year ago

jiulu313 commented 1 year ago

大神,能不能给点解答,源码里面 MNode 类型 里面有 pre, next 了,是个双链表,怎么还有个 firstChild, lastChild 类型 有点不太明白了

`export class MNode { type: NodeType; parent: MNode | null = null; firstChild: MNode | null = null; lastChild: MNode | null = null; prev: MNode | null = null; next: MNode | null = null; open: boolean = true; stringContent: string = ''; sourceStart: number; sourceEnd: number; blockMarkerBefore: string | undefined = ''; // 标识占位符(叶子块需要,目前只有代码块和标题需要,因为其他叶子快内部可以包含p标签) blockMarkerAfter: string | undefined = ''; // 标识占位符(叶子块需要,目前只有代码块和标题需要,因为其他叶子快内部可以包含p标签) marker: string = ''; // 是否是文本标记符占位节点 isShow: boolean = true; // 是否需要显示和隐藏(隐藏的话直接不创建dom节点,占位场景) // lastLineBlank: boolean = false; // 末尾是否存在空白行,用于换行时容器切换

constructor (sourceStart: number) { this.sourceStart = sourceStart; }`

jiulu313 commented 1 year ago

解析 md 内容的时候,生成AST,应该节点里面有children的,这个里面没有 不过还在继续深入研究,如果大神能给点点拨更好了

谢谢

Ben-love-zy commented 1 year ago

MNode各个节点的节点树,是一颗链表树,pre, next可以用于找到兄弟节点,firstChild可用于找到子节点,找到firstChild第一个字子节点后,通过firstChild-> next 就可以继续找到所有子节点,也就是children了。这里通过链表去实现 而不是children数组,方便节点高效操作

Ben-love-zy commented 1 year ago

也可以了解下treewalker ,就是用来遍历这种结构的,和真实dom结构一样

jiulu313 commented 1 year ago
/** 当前位置前移,1个tab对应4个空格 */
export function advanceOffset (line: string, offset: number, column: number, count: number, forColumns?: boolean) {
  let char, spaceInTab = 0;
  while (count > 0 && (char = line[offset])) {
    if (char === "\t") {
      spaceInTab = 4 - (column % 4); // 一个tab内还剩余多少个空格
      if (forColumns) {
        const inTab = spaceInTab > count; // 剩余空格足够满足本次移动
        const columnDelta = inTab ? count : spaceInTab; // 最多移动一个tab
        offset += inTab ? 0 : 1; // 剩余空格足够满足本次移动,则offset不用移动,说明在一个tab字符内
        column += columnDelta;
        count -= columnDelta;
      } else {
        column += spaceInTab;
        spaceInTab = 0;
        offset += 1;
        count -= 1;
      }
    } else {
      offset += 1;
      column += 1;
      count -= 1;
    }
  }
  return { offset, column, spaceInTab }
}

这个函数是啥意思啊 我琢磨了一下午,没琢磨明白 就感觉好像是删除的时候用的 望大佬能解释一下

Ben-love-zy commented 1 year ago

为了 换行打 tab 缩进的时候,能够对齐上一行的 tab 。而不会因为下一行先输入了一个空格再输入tab,与上一行错位

jiulu313 commented 1 year ago

这样啊,明白了 对 了,刚才MNode的结构,是不是就是下面的那样? 对于红色节点,它的 pre, next ,firstChild, lastChild 如下 image