📗

Tiptapコードリーディング:Document

に公開

Tiptapを開発に採用する上で、ノードやマークを拡張して独自のものを作りたいということは往々にしてあります。
提供している機能のコードが綺麗にまとめられていることもあり、それらを読んで勉強することにしました。
雑でも続けることが目標。

最初はTiptap (ProseMirror)の3種の神器の1つ、Documentです。
基本的にこれがないと動きません。

Document

Documentのドキュメントです。(v3)
https://tiptap.dev/docs/editor/extensions/nodes/document

Documentはエディターのルート要素で、これがなければ動きません。

Tiptapを動作させる最小限のコードがこちらになります。

export default () => {
  const editor = useEditor({
    extensions: [Document, Paragraph, Text],
    content: `
        <p>The Document extension is required. Though, you can write your own implementation, e. g. to give it custom name.</p>
      `,
  })

  if (!editor) {
    return null
  }

  return <EditorContent editor={editor} />
}

さて、Documentノードの実装コードを確認するとスッキリしてますね
https://github.com/ueberdosis/tiptap/blob/main/packages/extension-document/src/document.ts

シンプルですね。Node APIはドキュメントが整備されており、ありがたい。

TiptapはProseMirrorのラッパーということで、依存先のライブラリに色濃く影響を受けています。
topNonecontentはProseMirrorの設定の1つです。
contentはノードのgroupで指定することができます。より具体的にはProseMirrorのドキュメントに書いてあります。正規表現に似てますね。

const groupSchema = new Schema({
  nodes: {
    doc: {content: "block+"},
    paragraph: {group: "block", content: "text*"},
    blockquote: {group: "block", content: "block+"},
    text: {}
  }
})

例えば、これだと以下と等価になります。

block+ => (paragraph | blockquote)+

細かいところだと、?は0か1, *は0以上, +は1以上ですね。
他にもblock{2}みたいな個数指定もあるみたいです。

Documentはblockグループを一個以上受け取るノードです。Parahraphがブロックグループなので、シンプルな構成だと一個以上のParagraphを受け取ると考えても良さそう。

topNodeはルート要素であることを明示的に指定するものっぽい。ここにしか出てこなさそうなので、重要度は低めかも。

終わりに

次はParagraphについて書きます〜

Discussion