使う側のページと拡張のモジュールから部品を描く関数を呼ぶ手順と、コメントの読み書きの関数の渡し方
文書の印を使わずに、自分のページのデータからビューを描くとき、使う側が書いた要素にコメントを付けられるようにするとき、拡張の印の場所に mdmark のビューを描くときに実行する。 文書に書いた任意のスクリプトは動かない。動くのは mdmark の部品と、使う側が登録した拡張だけ。
dist/ にある型定義(index.d.ts と、それが読み込む .d.ts)を置くmountView を呼ぶimport { mountView } from "https://cdn.jsdelivr.net/gh/shuhei1101/mdmark@{タグ}/dist/index.js";
const handle = await mountView(document.querySelector("#tasks"), {
columns: ["題", "状態", "担当"],
items: [
{ 題: "配色の変数を洗い出す", 状態: "未着手", 担当: "佐藤" },
{ 題: "余白の変数を決める", 状態: "進行中", 担当: "鈴木" },
],
group: "状態",
filter: { 担当: "select" },
});
要素の中に、文書のビューの印で描いたものと同じ見た目と操作のビューを描く。
要素の中身は空にして、class mdmark の要素を 1 つ置き、その中に描く。
列名と項目の値は文字として出し、HTML として解釈しない。
| 引数 | 必須 / 任意 | 説明 |
|---|---|---|
el |
必須 | 描く先の要素 |
opts.columns |
必須 | 列名の配列。表形式のビューの列の並びになる。1 つ以上で、空の文字列と重なりを持たない |
opts.items |
必須 | 項目の配列。列名をキーにして文字列の値を持つオブジェクト。並びは表の行の順で、キーが無い値は空にする |
opts.group |
任意 | ボード表示で列に分ける列名。省くとボード表示を持たず、表形式のビューだけを描く |
opts.default |
任意 | 描いた直後に出すビュー("board" か "table")。省くと、group があればボード表示、無ければ表形式 |
opts.filter |
任意 | 表形式のビューで絞り込みを付ける列名と種類(select・text・date)のオブジェクト |
opts.icons |
任意 | ボードの列の見出しの値からアイコンの名前を引くオブジェクト。既定のアイコンに重ねて上書きする |
ビューの操作は、文書のビューの印と同じ(ビューとコメントを使う)。
アイコンの名前は、ボードの列の見出しのアイコン の使えるアイコンから選ぶ。
戻り値は Promise<{ destroy }> で、部品のモジュールを読み、ビューを描いてから解決する。
型 MdmarkViewOptions と MdmarkViewHandle は、型定義 dist/index.d.ts に書き出して配布物と一緒に配る。
handle.destroy();
destroy は要素の中を空にして、ビューの操作と、絞り込みのドロワーを開いている間だけ受け取る document のイベントを外す。
2 回目以降は何もしない。
同じ要素へもう一度 mountView を呼ぶと、前のビューを片付けてから描く。
el が要素でない、columns が空か重なりを持つ、items が配列でない、group・filter の列名が columns に無い、icons に使えない名前がある、などの誤りは、mountView が TypeError を同期で投げる。
メッセージに誤った引数の名前が入り、要素は書き換えない。
ビューの部品のモジュールを読めないときは、要素の中に題 この箇所を表示できません の知らせの枠を置き、Promise を元のエラーで拒否する。
draw から mountView を呼んで待つimport { mountView } from "https://cdn.jsdelivr.net/gh/shuhei1101/mdmark@{タグ}/dist/index.js";
export async function draw(slot, value) {
const { columns, items, filter } = value.definition;
await mountView(slot, { columns, items, filter });
}
拡張の印の範囲に置いた json のコードブロックを value.definition で受け取り、その値をビューに渡す。
slot は印の場所の要素。
import の URL は、文書を描くページが配布物を読み込んだタグと同じにする。
draw が mountView の Promise を待つと、mount は印の場所を描き終えたものとして扱う。
mount の update と destroy で印の場所を片付けるときは、その中のビューの destroy も行う。
印の定義と登録は 拡張を登録する、固有の部品と CSS を当てる手順は 固有の部品とCSSを当てる。
mountComments も、同じように slot に対して呼べる。
mountComments を呼ぶimport { mountComments } from "https://cdn.jsdelivr.net/gh/shuhei1101/mdmark@{タグ}/dist/index.js";
const handle = await mountComments(document.querySelector("#panel"), {
docId: "panel-setup",
store: {
load: ({ docId }) => fetch(`/api/comments/${docId}`).then((res) => res.json()),
save: ({ docId, comment }) =>
fetch(`/api/comments/${docId}`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(comment),
}).then((res) => res.json()),
},
});
使う側が自分で書いた要素の中の文字を選んで、コメントを付けられるようにする。
mount で描いた文書でなくてもよい。
要素の外の文字を選んでも、コメントのボタンは出ない。
| 引数 | 必須 / 任意 | 説明 |
|---|---|---|
el |
必須 | コメントを付けられる範囲の要素 |
opts.store |
必須 | コメントの読み書きの関数 load・save |
opts.docId |
必須 | 読み書きの関数に渡す、コメントを付ける対象の ID。空でない文字列 |
読み書きの関数の形と、読む人の操作は ビューとコメントを使う と同じ。
呼んだ時点で load を 1 回呼び、返ったコメントの箇所を印で包んでから解決する。
印は要素の文字を変えない。
コメントのボタン・入力欄・吹き出しは document.body に置く。
戻り値は Promise<{ destroy }>。
型 MdmarkCommentStore・MdmarkComment・MdmarkCommentDraft・MdmarkCommentsHandle は、型定義 dist/index.d.ts に書き出して配布物と一緒に配る。
handle.destroy();
印を外して要素の文字を呼ぶ前の並びに戻し、コメントのボタン・入力欄・吹き出しと document の受け取りを外す。
2 回目以降は何もしない。
同じ要素へもう一度 mountComments を呼ぶと、前のコメントを片付けてから付ける。
| 起きたこと | 動き |
|---|---|
el が要素でない、store が load・save の関数を持たない、docId が空か文字列でない |
TypeError を同期で投げる。メッセージに誤った引数の名前が入り、要素は書き換えず、load も呼ばない |
load が失敗する、または返した値がコメントの形に合わない |
例外を投げず、印を付けずに解決する。新しいコメントは付けられる。console.error に出る |
save が失敗する、または返した値がコメントの形に合わない |
例外を投げず、入力欄と本文を残して知らせを出し、印を付けない。console.error に出る |
| コメントの部品のモジュールを読めない | 要素を書き換えず、load を呼ばずに、Promise を元のエラーで拒否する |
即時。呼んだ時点で効く。
部品のモジュール(dist/view.js・dist/comments.js)は、初めて呼んだときに 1 回だけ読む。
配布物を読み込んだ URL の隣から読むため、同じタグの dist/ を配信しておく。
mountView を呼んだ要素の中に、class mdmark の要素と、ボード表示(group を渡したとき)か表形式のビューがある。
「表」を押すと、items の数の行が columns の順で並ぶ。
document.querySelectorAll("#tasks .mdmark-view-table tbody tr").length
items の数が出る。
handle.destroy() を呼んだ後、要素の中が空になっている。
document.querySelector("#tasks").childElementCount
0 が出る。
拡張の印を書いた文書を描く。
印の場所に、定義の項目を並べたビューが出る。
mount の destroy を呼ぶと、印の場所のビューも片付く。
mountComments を呼んだ要素の中の文字を選ぶと、「コメント」のボタンが出る。
本文を書いて保存すると、save が { docId, comment } で 1 回呼ばれ、選んだ文字が class mdmark-comment-mark の印で包まれる。
印から開いた吹き出しの本文は、HTML として解釈されず文字のまま出る。
TypeScript か、// @ts-check を付けた JavaScript で書いたとき、型検査を流す。
npx tsc --noEmit
型エラーが 0 件になる。
呼び出しを消すか、destroy を呼ぶ。
mountView が描いたものは要素ごと空になる。
mountComments が付けた印は外れる。
保存したコメントは使う側の保存先に残るため、消すときは保存先で消す。