generated at
StringObserver
hr
入力補完対象の外部project linkの変更を監視するclass
変更があったときのみ入力候補を更新する
更新とか
2020-09-01 09:24:28 サロゲートペアに対応した?対応できなかった
2020-08-26 23:51:28 入力補完対象の文字列を探すのに使う正規表現を外から指定できるようにした
クラス名を変えた
emoji-completionからも使うから、 externalLinkObserver だとなんか変

既知の問題
🔳 を含む行だと判定処理に失敗する
matchAll がサロゲートペアを含んだ文字列の文字数を計算できないのが原因

script.js
export class StringObserver {

script.js
constructor(editor, {regex = /\[\/[^\s!"#%&'()\*\+,\-\.\/\{\|\}<>_~\]][^\]]*\]/ug, makeRaw = string => string.substr(2, string.length - 3)} = {}) { this.raw = undefined; // 監視対象の文字列 this.target = undefined; // 加工した文字列 this.editor = editor; this.regex = regex; this.makeRaw = makeRaw; } // 監視を更新する 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 ? this.makeRaw(this.raw) : undefined; return oldRaw !== this.raw ; } // cursorを含む外部projectへのリンクを取得する関数 _getLinkIncludingCursor(cursor){ const cursorLine = editor .getElementsByClassName('cursor-line')[0]; if(!cursorLine) return undefined; // cursorのいる行から正規表現にマッチする文字列の情報を全て取り出す const matchedWords = [...cursorLine.textContent.matchAll(this.regex)];

座標取得は少し工夫が必要
firefox対策
script.js
// 要素の左端の相対座標を取得する const getLeftPosition = targetElement => targetElement.getBoundingClientRect().left - cursorLine.getBoundingClientRect().left; // cursorを含む文字列のみ抽出 const targetWord = matchedWords // cursorを含む外部projectリンクは一つしかないはずなので、filterではなくfindを使う .find(match => { //console.log(`matched ${match[0]}, index: ${match.index}`); const start = cursorLine .getElementsByClassName(`c-${match.index}`)[0]; const end = cursorLine .getElementsByClassName(`c-${match.index + match[0].length -1}`)[0]; // '['の右端の座標 const startLeft = getLeftPosition(start); // ']'の左端の座標 const endLeft = getLeftPosition(end); // cursorの左端の座標 const cursorLeft = parseInt(cursor.style.left); return startLeft <= cursorLeft && cursorLeft <= endLeft; }); return targetWord?.[0]; } }