Skip to content

Instantly share code, notes, and snippets.

@tetsuharuohzeki
Last active October 26, 2015 03:24
Show Gist options
  • Save tetsuharuohzeki/19bb32ca511739760a66 to your computer and use it in GitHub Desktop.
Save tetsuharuohzeki/19bb32ca511739760a66 to your computer and use it in GitHub Desktop.
https://github.com/Matt-Esch/virtual-dom のコードを読んだ時のメモ

revision

virtual-dom

  • 特に何も無い
  • 依存するモジュールの関数を引きずり出しているだけ
  • virtual-dom/hは例外で、与えた引数からVNodeを作る為のラッパー

vdom

  • 生成されたパッチを適用し、実際のDOMに変換するのがメイン

create-element.js

  • VNodeを元にDOMの実体を(子孫方向に再帰的に)生成する
  • これに対して, patchを当てていく

apply-property

  • DOM Nodeに対してプロパティの追加・削除を行う.
  • 属性指定されていれば属性を。そうでなければDOM Objectに対してプロパティを生やす.

patch

  • patchRecursiveを呼び出して、patchを当てる
  • が、実体は再帰ではなく、dom-indexを用いてフラット化したツリー全体をloopで舐めている

dom-index.js

  • DOMツリーを再帰的に呼び出して、数値をキーにしてフラット化した構造体に変換して返す
  • 実質的にツリー構造をフラットな配列もどきの構造体に変換して返す

patch-ops.js

  • 具体的なパッチ処理
  • Vpatchをswitchで処理に落とし込んでいる
    • 直和とパターンマッチ欲しいですね

vtree

  • まあ構造体表現的な.
  • diff処理もここで行っている
  • W3C DOMとは異なり, VTextはVNodeとは継承関係に無い. VTextはテキストノード専用のオブジェクト

vnode

  • hookって名前の関数を持ってる値をプロパティとして渡すと、hookになる
    • diff時に, 比較対象が同一おぶじぇくとであれば、プロパティ変更用のpatchを生成する
    • patch適用時に値を用いて処理するためにhook関数を起動する

VText

Vpatch

diff

  • 下っていく(hookとかthunkとかのパッチ作るんだけど、置いておく)
  • だいたい http://calendar.perfplanet.com/2013/diff/ の通り.
  • 基本的に
    • 各vnodeはユニークidとなるkeyを持つことができる
      • keyが同じであれば、tag名と名前空間が同じ場合に, プロパティの更新だけの命令を発効できるなど、差分生成が効率化できる
    • treeをpreorderでトラバースしたリストのように取り扱うのがミソ
      • siblingのノードを比較する場合, indexの増減は現在の子孫ノードの数を考慮する
      • この増減したindexを添字に、パッチのリストを作成する
      • よって、treeのどの位置にノードを追加するのかが一意にわかる
    • rootからの階層が同じものを比較する = subtreeを別のsubtreeに接ぎ木するような場合, 接ぎ木したものを全部再構築する
    • 子の比較を行う場合,
      • keyを元に, 移動前・移動後のノードの順番を検出する
        1. aの方でn番目にあったnodeは, bのk番目というテーブルAを作る
        2. Aテーブル(添字は0からの数値になる)を順に舐める
        3. Aから、bのk番目にあるノードを取得, shuffleに突っ込む. もし順序が変わっていたら, kをn番目に移動させたということとmoveに記録する. k番目がn番目に動いたと同様にreverseに記録する. 次のループへ.
        4. Aにはあるがundefined = 消えた場合, shuffleのn番目は空とし, n番目が消えたとremoveに記録する. 次のループへ.
        5. Aに無い場合, freeIndexを進めて, BからfreeIndexに合致するノードを探す
        6. freeIndexがbの子の数(比較している階層のsiblingの数)を越えていない場合、shuffleのn番目にfreechild(=k)番目のbのノードがあると記録。
        7. freeindex と moveIndexが異なる場合(moveIndex = moveに何番目まで登録されたかを示す)、どこに移動したかの対応関係をmoveとreverseに記録する。
        8. 以上をAのテーブルの添字の最後までループする
      • パッチ適用処理時に, moveとreverse, removesを用いて、挿入位置のオフセットをずらして, 調整する

どこで使ってるのかよくわからんけど面倒くさいから放置

  • VWidget
    • 丸ごと置き換え?
  • VThunk
    • replaceかける模様

カジュアルにfor-in使ってるんだけど大丈夫なんすかね?

  • だいじょうぶなのかな
  • この添字(キー)がリストの中に存在するか否かを演算子として判別するのに使ってる
@milligramme
Copy link

すごく、参考になりました

このurlのページ、改ざんされている?ようで、無関係なページにリダイレクトされます

だいたい http://calendar.perfplanet.com/2013/diff/ の通り.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment