LinkObserver
カーソルがいるリンクの文字列の変更を監視するclass
変更があったら通知する
2021-02-06 21:26:44 やっていることが大げさな気がする
要はcursorがリンクの中にいるかどうかさえわかればいい
クラスにするまでもなさそう
判定関数で十分
2020-12-03
01:37:19 triggerを文字から正規表現に変えた
00:32:10 triggerが空の場合でも変更監視できるようにした
既知の問題
🔳
を含む行だと判定処理に失敗する
script.js constructor(editor, {
trigger // 監視対象のリンクのpattern
}= {}) {
this.raw = undefined; // []つきリンク文字列
this.target = undefined; // []をとったリンク文字列
this.editor = editor;
this.trigger = trigger;
}
// 監視を更新する
reload(cursor) {
// focusがcursorになかったら何もしない
if(editor.getElementsByClassName('cursor-line').length == 0) return false;
const oldRaw = this.raw
this.raw = this._getLinkIncludingCursor(cursor);
this.target = this.raw?.replace(/\[(.*)\]/,'$1');
//console.log(`Found a link: ${this.raw}`);
return oldRaw !== this.raw ;
}
script.js // cursorを含む外部projectへのリンクを取得する関数
_getLinkIncludingCursor(cursor){
const cursorLine = editor
.getElementsByClassName('cursor-line')[0];
if(!cursorLine) return undefined;
// 現在行からリンクを探す
const LinkStrings = [...cursorLine.getElementsByClassName('page-link')];
// 要素の左端の相対座標を取得する
const getLeftPosition = targetElement => targetElement.getBoundingClientRect().left - cursorLine.getBoundingClientRect().left;
// cursorを含む文字列のみ抽出
const targetLink = LinkStrings
// cursorを含む外部projectリンクは一つしかないはずなので、filterではなくfindを使う
.find(a => {
// 正規表現に合わなかったらfalse
if(!this.trigger.test(a.textContent.replace(/\[(.*)\]$/,'$1'))) return false;
// '['の右端の座標
const startLeft = getLeftPosition(a.firstElementChild);
// ']'の左端の座標
const endLeft = getLeftPosition(a.lastElementChild);
// cursorの左端の座標
const cursorLeft = parseInt(cursor.style.left);
return startLeft <= cursorLeft && cursorLeft <= endLeft;
});
return targetLink?.innerText;
}
}