generated at
scrapbox-line-info-2
scrapboxの行のDOMからいろいろな情報を取得するAPI
使い方を変えた
line(lineDOM).id line(lineDOM).isHead のように使う
lineDOM には div.line を入れる
実装方法はscrapbox-char-infoと同じ

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.js
import {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; }
行内の文字列を取得する
記法込みの文字列を取得するために、 textContent ではなくscrapbox.Page.linesを用いる
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.js
export const line = (lineDOM, id = undefined, index = undefined) => index !== undefined ? new Line({index}) : id !== undefined ? new Line({id}) : lineDOM ? new Line({lineDOM}) : undefined;

#2021-05-08 15:33:21
#2021-01-10 10:30:07
#2020-12-26 04:15:39
#2020-12-25 11:11:02
#2020-12-18 03:53:24