scrapbox-line-info-2
scrapboxの行のDOMからいろいろな情報を取得するAPI
使い方を変えた
line(lineDOM).id
や line(lineDOM).isHead
のように使う
lineDOM
には div.line
を入れる
2021-05-08 15:33:14 コピペしやすいように相対パスに変えた
2021-01-15 10:06:50 line()
に行idと行番号を渡せるようにした
2021-01-10 10:29:32 line()
に undefined | null
を渡したときに undefined
を返すようにした
2020-12-26 04:18:24 前後の行を取得する関数を追加した
dependencies
script.jsimport {scrapboxDOM} from '../scrapbox-dom-accessor/script.js';
const lineSelector = 'div.line';
class Line {
div.line
そのもの、行ID、行番号のいずれかを受け取る
script.js constructor({lineDOM, id, index}) {
if (index !== undefined) {
id = scrapbox.Page.lines[index]?.id;
if (id === undefined) throw Error(`${index} is out of range`);
}
if (id !== undefined) {
lineDOM = document.getElementById(id);
if (!lineDOM) throw Error(`${id} is an invalid line id.`);
}
if (!lineDOM?.classList?.contains?.('line')
|| lineDOM?.tagName !== 'DIV') throw Error(`${lineDOM} is not div.line`);
this.lineDOM = lineDOM;
}
情報の取得
行番号を取得する
script.js get index() {
return [...scrapboxDOM.lines.children].indexOf(this.lineDOM);
}
行IDを取得する
script.js get id() {
return this.lineDOM.id;
}
行内の文字列を取得する
script.js get text() {
return scrapbox.Page.lines[this.index]?.text;
}
行の折返し数を取得する
script.js get breakNum() {
return Math.floor(this.lineDOM.getBoundingClientRect().height
/ this.lineDOM.clientHeight);
}
DOMの取得
任意の位置の文字のDOM
script.js charDOM(index) {
return this.lineDOM.getElementsByClassName(`c-${index}`)?.[0];
}
行内の全ての文字のDOM
script.js get charDOMs() {
return [...this.lineDOM.querySelectorAll('span[class^="c-"]')];
}
行頭文字/行末文字のDOM
script.js get headCharDOM() {
return this.charDOM(0);
}
get lastCharDOM() {
const index = this.text.length - 1;
// this.textが空行のときは span.c-0 を取得する
return this.charDOM(index < 0 ? 0 : index);
}
空白を除いた行頭文字/行末文字のDOM
script.js get headNonBlankCharDOM() {
//this._log('enter "headNonBlankCharDOM".');
const text = this.text;
if (/^\s+$/.test(text)) return this.lastCharDOM;
if (!/^\s+/.test(text)) return this.headCharDOM;
const spaceNum = text.match(/^\s+/)?.[0].length;
return this.charDOM(spaceNum);
}
get lastNonBlankCharDOM() {
//this._log('enter "lastNonBlankCharDOM".');
const text = this.text;
if (/^\s+$/.test(text)) return this.headCharDOM;
if (!/\s+$/.test(text)) return this.lastCharDOM;
const spaceNum = text.match(/\s+$/)?.[0].length;
return this.charDOM(this.text.length - 1 - spaceNum);
}
行の取得
前の行のDOM
script.js get prevDOM() {
this.lineDOM.previousElementSibling ?? undefined;
}
次の行のDOM
script.js get nextDOM() {
this.lineDOM.nextElementSibling ?? undefined;
}
前の行
script.js get prev() {
const lineDOM = this.prevDOM;
return lineDOM ? new Line({lineDOM}) : undefined;
}
次の行
script.js get next() {
const lineDOM = this.nextDOM;
return lineDOM ? new Line({lineDOM}) : undefined;
}
位置の確認
先頭行かどうか
script.js get isHead() {
return scrapboxDOM.lines.firstElementChild.id === this.lineDOM.id;
}
EOFかどうか
script.js get isLast() {
return scrapboxDOM.lines.lastElementChild.id === this.lineDOM.id;
}
Debug用
script.js _log(msg, ...objects){
if (objects.length > 0) {
console.log(`[scrapbox-line-info-2] ${msg}`, objects);
return;
}
console.log(`[scrapbox-line-info-2] ${msg}`);
}
}
外部に公開する
script.jsexport const line = (lineDOM, id = undefined, index = undefined) =>
index !== undefined ? new Line({index}) :
id !== undefined ? new Line({id}) :
lineDOM ? new Line({lineDOM}) : undefined;