generated at
externalLinkObserver
入力補完対象の外部プロジェクトリンクの変更を監視するclass
変更があったときのみ入力候補を更新する

script.js
export class externalLinkObserver { constructor(editor) { this.linkString = undefined; this.leftCharIndex = 0; // 左端の'['の文字番号 this.rightCharIndex = 0; // 右端の']'の文字番号 this.editor = editor; } // 監視を更新する reload(cursor) { // focusがcursorになかったら何もしない if(editor.getElementsByClassName('cursor-line').length == 0) return false; const targetLinkData = this.getLinkIncludingCursor(cursor); //console.log(`targetLinkData: ${targetLinkData}`); // 見つからなければundefinedを入れる if(!targetLinkData){ // 変更があったかどうかのflag const result = this.linkString != targetLinkData; this.linkString = targetLinkData; this.leftCharIndex = 0; this.rightCharIndex = 0; return result; } // 変更があったかどうかのflag // リンクの位置がずれても文字列に変化がなければ更新なしと判定する const result = this.linkString != targetLinkData[0]; this.linkString = targetLinkData[0]; this.leftCharIndex = targetLinkData[1]; this.rightCharIndex = targetLinkData[2]; return result; } // cursorを含む外部projectへのリンクを取得する関数 getLinkIncludingCursor(cursor){ // cursorのいる行から外部projectへのリンクを取得する let text= 'No line is focused.' if(editor.getElementsByClassName('cursor-line').length!=0){ text = editor.getElementsByClassName('cursor-line')[0].textContent; } // 取得した行から外部projectへのリンクに相当する文字列のみを抜き出す const matchedLinks = [...text.matchAll(/\[\/[^\s!"#%&'()\*\+,\-\.\/\{\|\}<>_~\]][^\]]*\]/g)]; // cursorを含む文字列のみ抽出 const targetLinkData = matchedLinks // cursorを含む外部projectリンクは一つしかないはずなので、filterではなくfindを使う .find(match => { const cursorLine = editor .getElementsByClassName('cursor-line')[0];

座標取得は少し工夫が必要
firefox対策
script.js
// 要素の左端の相対座標を取得する const getLeftPosition = target => target.getBoundingClientRect().left - cursorLine.getBoundingClientRect().left; // '['の右端の座標 const startLeft = getLeftPosition(cursorLine .getElementsByClassName(`c-${match.index}`)[0]); // ']'の左端の座標 const endLeft = getLeftPosition(cursorLine .getElementsByClassName(`c-${match.index + match[0].length -1}`)[0]); // cursorの左端の座標 const cursorLeft = parseInt(cursor.style.left); return startLeft <= cursorLeft && cursorLeft <= endLeft; }); if(!targetLinkData) { return undefined; } return [targetLinkData[0], targetLinkData.index, targetLinkData.index + targetLinkData[0].length -1]; } }

UserScript