generated at
Scrapboxみたいなのを実装する
やらないといけないことは
ワークスペースと記事の管理
リンクのグラフの保持
合理的に実装するならDBに放り込んでおくのがよさげ?
私はやらない、普通に使っていれば異常な量の記事などできないし個人用途であればプレーンテキストからインメモリ構築するくらいで事足りる
サーバーとして立ち上げるなら起動の速度はそこまで問題じゃない
DBに依存するほうがだるい
履歴のコミット
どんな精度でやるのが効率いいんだろうか
WYSIWYGにこだわらずに旧来のWiKiとして実装するとこの辺りは簡素化する
Wikiスタイルでやるなら(私の場合)Vimに貼り付けて書くことになるので手間が増える
自動で保存してほしいならVim等のスワップが参考になりそう
一定時間編集しない場合
一定の文字数を入力した場合
Scrapboxの挙動を見ると打った端から保存している
こうなると保存タイミングよりUndoの間隔の方を気にするべきでは
明示的にコミットボタンを押させると全てが解決する
全てを記録しておいて、最後の編集から一定時間が経過したらコミットとかでよさそう
ワークスペースをハッシュマップとして扱うのがベストだろうか
実体とリンクを分離しておくととても管理しやすい気がする
フロントのページ部分
肝だと思う
ScrapboxはReactで実装されてるらしい
カーソルはエディタのDOMのトップに存在しており、位置を計算して出現させているっぽい
テキストをクリックすると追従する
どうやってるんだ
幅1のsvg-rectが置いてある
位置はjQueryで計算して出しているらしい
jQueryを使わないにしてもElement.getBoundingClientRect()を駆使したらいけそう
HackMDが使っているCodeMirrorを読んでいて知った
入力には隠しtextareaが使われている
カーソルの横に置いてあり、一緒にeditorというdivに包まれている
position: absolute; でいい感じに配置したものを overflow: hidden; で消している
違った、 opacity: 0;
overflow: hidden; はtextareaが広がるのを防ぐためだった
恐らく、これに入力されたものをReactでページに書き出した上で鯖にコミットしている
行ごとにdivに包まれており、中にはテロメアとテキスト本体が入っている
IDが振られている
ジャンプのためかと
UUIDっぽい
テロメア
テキスト
インデントはスペースがspanに包まれて置かれている
インデントの数だけ置いてあるな
自前実装バグらせてようやくこれの意図が分かった
カーソルの置き場になっている
自前実装はインデントを特別扱いしていたが、Scrapboxはそうではない
カーソルを置けるし文字を入れることもできる
単に描画する時に先頭のスペースやタブをインデント扱いしているにすぎない
クリックした時にinputになる文章として運用するならこれを置いておけば抜き差しは楽にできそう
叩き台みたいなもんだけど作ってみた
spanですらない
Gistに置くの微妙な気がしたのでこちらにも置いた
これも違った
行ノードに2つ要素が挿入されている
1つはインデント
absolute に配置されていてdotの配置のために置かれている
width でインデント分広げてある
もう1つは本文
margin-left でインデント分のマージンを取る
要素同士独立しているのがミソ
bulletはdotというclassのspanが置かれている
CSSで出してるっぽい
描画がなされる以外はインデント用のスペースと同じ気がする
top,rightを設定することでそれっぽい位置に配置
width,heightを設定してサイズを調整
border-radius: 50%; で丸める
文字は要素ごとに分割され、更に文字ごとに分割されている
カーソルを置くためだと思う
文字には字数ごとに別のクラスが振ってある
悪用できそう