scrapbox-suggest-observer
LinkObserverをより汎用的にしたやつ
/programming-notes/拡張Scrapbox入力補完の開始・終了条件を決めるをtakker.icon用にコピペしただけ
code
code:script.js
import {scrapboxDOM} from '../scrapbox-dom-accessor/script.js';
class CompletionObserver {
register({judge, oncompletion}) {
const id = this._idCounter++;
this._triggers.push({id, judge, oncompletion});
return id;
}
unregister(triggerId) {
this._triggers = this._triggers.filter((_, i) => i !== triggerId);
}
startCompletion() {
const id = scrapboxDOM.cursorLine?.id?.slice?.(1);
if (!id) return;
const newLine = scrapbox.Page.lines.find(line => line.id === id);
this._startCompletion(newLine);
}
constructor() {
this._triggers = [];
this._idCounter = 0;
this._prevLineText = '';
const observer = new MutationObserver(() => {
const id = scrapboxDOM.cursorLine?.id?.slice?.(1);
if (!id) return;
ここの速度が気になる
code:script.js
const newLine = scrapbox.Page.lines.find(line => line.id === id);
if (!newLine || newLine?.text === this._prevLineText) return;
this._prevLineText = newLine.text;
this._startCompletion(newLine);
});
observer.observe(scrapboxDOM.lines, {childList: true, subtree: true});
}
_startCompletion(newLine) {
for (const {judge, oncompletion} of this._triggers) {
const word = judge(newLine);
if (word === undefined) continue;
oncompletion(word);
break;
}
}
}
export const completionObserver = new CompletionObserver();
$ \LaTeX
test code
code:js
import('/api/code/takker/scrapbox-suggest-observer/test1.js');
code:test1.js
import {completionObserver} from './script.js';
import {cursor} from '../scrapbox-cursor-position-5/script.js';
import {scrapboxDOM} from '../scrapbox-dom-accessor/script.js';
// リンク内補完
completionObserver.register({
judge() {
const c = cursor();
const link = (c.left ?? c.right)?.DOM?.closest?.('.page-link');
return link?.type === 'hashTag' ?
link?.textContent?.slice?.(1) :
link?.textContent?.slice?.(1, -1) ??
undefined;
},
oncompletion(linkText) {
console.log(linkText);
},
});
// 数式補完
completionObserver.register({
judge() {
const c = cursor();
const formula = (c.left ?? c.right)?.DOM?.closest?.('.formula');
return formula?.textContent?.slice?.(3, -1) ?? undefined;
},
oncompletion(formulaText) {
console.log(formulaText);
},
});
// <C-Space>で強制補完開始
scrapboxDOM.editor.addEventListener('keydown', e => {
if(!e.ctrlKey || e.key !== ' ') return;
e.preventDefault();
e.stopPropagation();
completionObserver.startCompletion();
});
#2021-02-22 01:26:44