scrapbox-char-info
Scrapboxのeditor上の1文字を表す
span.c-*から文字番号や行番号などの情報を取得するAPI
2021-01-15 10:22:20 リンクを取得できるようにした
2021-01-10 10:30:33 undefined | null
を cursor()
に渡したとき、 undefined
を返すようにした
従来は Type Error
が発生していた
実装
内部はclassで作る
外部にはnewをwrapした関数を公開する
newを表に出さないようにして見た目をよくする
script.jsimport {scrapboxDOM} from '/api/code/takker/scrapbox-dom-accessor/script.js';
const charSelector = 'span[class^="c-"]';
class Char {
constructor({charDOM}) {
if (!charDOM?.matches?.(charSelector)) throw Error(`${charDOM} is not span.c-*.`);
this.charDOM = charDOM;
}
span.c-*
でなければ例外を投げる
提供する機能
文字の列番号
script.js get index() {
return parseInt(this.charDOM.className.replace(/c-(\d+)/,'$1'));
}
中身の文字
script.js get text() {
return this.charDOM.textContent;
}
文字がある行
script.js get line() {
return this.charDOM.closest('div.line');
}
行の先頭の文字か
script.js get isHead() {
return this.index === 0;
}
行の末尾の文字か
script.js get isEnd() {
return this._chars.pop().className === this.charDOM.className;
}
前の文字
this._charDOM
だと死んだDOMしか取得できない
代わりに this.line
から間接的に取得する
script.js get next() {
if (this.isHead) return undefined;
const charDOM = this.line.getElementsByClassName(`c-${this.index + 1}`)?.[0];
return new Char({charDOM});
}
後ろの文字
script.js get prev() {
if (this.isEnd) return undefined;
const charDOM = this.line.getElementsByClassName(`c-${this.index - 1}`)?.[0];
return new Char({charDOM});
}
追加したい機能
非空白文字を除いた先頭/末尾判定
左右の文字のDOMを返す
(やれたらやる) 文字の種類
リンク
画像
コードブロック
etc.
文字を囲むリンクを取得する
内部リンクと外部リンクのどちらかを取得する
script.js get link() {
const livingLink = this.charDOM.closest('a');
if (livingLink) {
return {
type: internalLink.type,
href: internalLink.href,
dom: internalLink,
}
}
// 記法がむき出しになり、リンクとしての機能を果たしていない外部リンク
// URLしかないリンクだとバグる
const deadLink = this.charDOM.closest('span.link');
if (deadLink) {
const [text, href] = deadLink.textContent.replace(/\[(.+?)\]/,'$1').split(/\s/);
return {
type: 'link',
href,
text,
}
}
return undefined;
}
内部で使用する関数
script.js get _chars() {
return [...this.line.querySelectorAll(charSelector)];
}
}
外部公開用
文字のDOMだけでなく、文字番号でも作成できるようにしたい
script.jsexport const char = (charDOM) => charDOM ? new Char({charDOM}) : undefined;