script.jsexport 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];
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];
}
}