scrapbox-motion-emulation
scriptからScrapbox editorのcursor操作を行うAPI
2021-08-23
2021-06-12
12:52:35 import漏れがあった
2021-06-10
17:25:32 色々バグ修正
2021-06-08
23:21:41 update libraries
2021-03-14
22:02:47 一部の関数を非同期化した
dependencies
script.jsimport {press} from '../scrapbox-keyboard-emulation-2/script.js';
import {mimicClick, mimicHoldDown} from '../scrapbox-pointer-emulation@0.1.0/script.js';
import {
getLine,
getIndentCount,
getLineDOM,
getLineNo,
getHeadLineDOM,
getTailLineDOM,
getHeadCharDOM,
getTailCharDOM,
getCharDOM,
} from '../scrapbox-access-nodes@0.1.0/script.js';
import {position} from '../scrapbox-cursor-position-6/script.js';
import {scrapboxDOM} from '../scrapbox-dom-accessor/script.js';
import {isHeightViewable} from '../要素が画面内にあるかどうかの判定/script.js';
utilities
script.jsconst range = n => [...Array(n).keys()];
(mobile版scrapbox用)行末にカーソルを移動させて文字入力できる状態にする
script.jsexport async function focusEnd(holding = 1000) {
const target = (position().line ?? getHeadLineDOM())?.getElementsByClassName('text')?.[0];
if (!isHeightViewable(target)) target.scrollIntoView({block: 'center'});
const {right, top, height} = target.getBoundingClientRect();
await mimicHoldDown(target, {X: right + 1, Y: top + height / 2, holding});
}
cursorの移動
script.jsexport function moveLeft(count = 1) {
for (const _ of range(count)) {
press('ArrowLeft');
}
}
export function moveUp(count = 1) {
for (const _ of range(count)) {
press('ArrowUp');
}
}
export function moveDown(count = 1) {
for (const _ of range(count)) {
press('ArrowDown');
}
}
export function moveRight(count = 1) {
for (const _ of range(count)) {
press('ArrowRight');
}
}
行内移動
script.jsexport function goHeadWithoutBlank() {
press('End');
press('Home');
}
export function goEndWithoutBlank() {
press('End');
moveLeft(getIndentCount(position().line));
}
export function goHead() {
press('Home');
press('Home');
}
export function goEnd() {
press('End');
}
行移動
描画領域外にあるときは、スクロールして見えるようにしてから移動する
script.jsexport async function goHeadLine() {
const target = getHeadLineDOM();
if (!isHeightViewable(target)) target.scrollIntoView({block: 'center'});
const charDOM = getHeadCharDOM(target);
const {left, top} = charDOM.getBoundingClientRect();
await mimicClick(target, {X: left, Y: top});
}
行末に飛ぶときは span.text
に対してeventを発火させる
script.jsexport async function goLastLine() {
await _goLine(getTailLineDOM());
}
任意の行の行末に移動する
script.jsexport async function goLine(value) {
await _goLine(getLineDOM(value));
}
async function _goLine(target) {
if (!isHeightViewable(target)) target.scrollIntoView({block: 'center'});
const {right, top, height} = target.getElementsByClassName('text')[0].getBoundingClientRect();
await mimicClick(target, {X: right + 1, Y: top + height / 2});
}
任意の文字に直接飛ぶ
script.jsexport async function goChar(line, pos) {
const charDOM = getCharDOM(line, pos);
if (!isHeightViewable(charDOM)) charDOM.scrollIntoView({block: 'center'});
const {left, top} = charDOM.getBoundingClientRect();
await mimicClick(charDOM, {X: left, Y: top});
}
scroll
画面内に表示できる行数の最大数を返す関数 getVisibleLineCount()
を使って、どのくらいscrollするかを決める
script.jsfunction getVisibleLineCount() {
return Math.round(window.innerHeight /
getTailLineDOM().clientHeight);
}
export async function scrollHalfUp(count = 1) {
const index = Math.round((getLineNo(position().line) - getVisibleLineCount() / 2) * count);
await goLine(Math.max(index, 0));
}
export async function scrollHalfDown(count = 1) {
const index = Math.round((getLineNo(position().line) + getVisibleLineCount() / 2) * count);
await goLine(Math.min(index, scrapbox.Page.lines.length - 1));
}
export function scrollUp(count = 1) {
for (const _ of range(count)) {
press('PageUp');
}
}
export function scrollDown(count = 1) {
for (const _ of range(count)) {
press('PageDown');
}
}