[[Reading view]] および [[Editing view]] において、[[内部リンク]]を[[ポインティングデバイス]]でクリックしたときに、[[内部リンク]]が指すファイルのパスを取得する方法。 クリックイベントの処理をinterceptし、パスを取得した後、必要に応じて独自の処理を追加する。 ```ts import { getActiveEditor } from "src/lib/helpers/editors/basic"; import { getLinkTokenAtOffset, linkText2Path } from "src/lib/helpers/links"; import { map } from "src/lib/utils/guard"; const handler = async (ev: MouseEvent) => { // 特定の修飾キーとセットの場合のみ発動させる場合はearly returnする // if (!ev.metaKey || ev.button !== 0) { // return; // } // リンクの要素を取得. Live PreviewがあるのでEditing viewかどうかだけでは判定不可 const linkEl = (ev.target as HTMLElement).closest( ".cm-hmd-internal-link,.internal-link", ); if (!linkEl) { return; } // クリックの対象として内部リンクの要素が存在するなら、伝播を停止する // (標準の挙動がキャンセルされるのは偶然かも..?) ev.stopPropagation(); // リンクを構成するテキストを取得 const linkText = // プレビュー表示の場合 linkEl.getAttribute("data-href") ?? // 編集表示の場合 map( getActiveEditor()?.cm, (cm) => getLinkTokenAtOffset(cm.posAtDOM(linkEl))?.text, ); if (!linkText) { return; } // リンク対象のファイルパスに変換 const path = linkText2Path(linkText); }; document.addEventListener("click", handler, true); ``` > [!note] > 以下の関数は[[🦉Carnelian]]の実装を確認すること。 > > - `getActiveEditor` > - `getLinkFileAtOffset` > - `linkText2Path` > - `map` > [!caution] > `onunload` のときにhandlerの解除を忘れないように。 > > ```ts > document.removeEventListener("click", handler, true); > ``` ## 参考 - [carnelian/src/services/link-click-service.ts at bc29f95246cf8b1bbd85481491ae145bffe4a028 · tadashi-aikawa/carnelian](https://github.com/tadashi-aikawa/carnelian/blob/bc29f95246cf8b1bbd85481491ae145bffe4a028/src/services/link-click-service.ts?plain=1#L10)