generated at
scrapbox-cursor-emulation
2021-03-14 21:38:36 deprecated
scrapbox-motion-emulationに名前を変更した
以降はこちらを開発する
hr
scriptからScrapbox editorのcursor操作を行うAPI

2021-01-17
15:43:23 goHeadWithoutBlank() をキー操作だけで動かすようにした
2020-12-30 22:27:31 scrapbox-cursor-position-3にversion upした
ctrl + d / ctrl + u のバグが消えた

import
cursor.js
import {press} from '/api/code/takker/scrapbox-keyboard-emulation-2/script.js'; import { jumpTo, jumpToHead, jumpToLast, jumpToHeadWithoutBlank, jumpToLastWithoutBlank, } from '/api/code/takker/scrapbox-cursor-jumper-2/script.js'; import {char as c} from '/api/code/takker/scrapbox-char-accessor/script.js'; import {line as l} from '/api/code/takker/scrapbox-line-accessor/script.js'; import {cursor} from '/api/code/takker/scrapbox-cursor-position-4/script.js'; import {scrapboxDOM} from '/api/code/takker/scrapbox-dom-accessor/script.js';

utilities
cursor.js
const range = n => [...Array(n).keys()];

cursorの移動
cursor.js
export 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'); } }

行内移動
cursor.js
export function goHeadWithoutBlank() { press('End'); press('Home'); } export function goEndWithoutBlank() { const lineObj = cursor().line; lineObj?.DOM?.scrollIntoView?.({block: 'center'}); jumpToLastWithoutBlank(lineObj); } export function goHead() { press('Home'); press('Home'); } export function goEnd() { press('End'); }

行移動
2021-01-17 14:06:38 画面内に表示されていたらscrollしないようにしたい
takkerの場合headerを常に頭に表示しているので、その分を除いて計算する必要がある
↑これもしかしていらなかったりする?
要素に対して直接mouse eventを発生させているわけだし
2021-01-17 16:05:02 いらなかった!
おそらく要素が描画されてなくてもいけるんじゃないか?
ただその場合は要素が見えないのであまり意味がない
cursor.js
function isViewable(element) { const {top, bottom} = element.getBoundingClientRect(); return top >= 0 && bottom <= window.innerHeight; }
cursor.js
export function goHeadLine() { const target = scrapboxDOM.lines.firstElementChild; if (!isViewable(target)) target.scrollIntoView({block: 'center'}); jumpToHead(l(target)); } export function goLastLine() { const target = scrapboxDOM.lines.lastElementChild; if (!isViewable(target)) target.scrollIntoView({block: 'center'}); jumpToLast(l(target)); } export function goLine(indexOrIdOrDOM) { // 旧式引数への対処 if (indexOrIdOrDOM.id) indexOrIdOrDOM = indexOrIdOrDOM.id; if (indexOrIdOrDOM.index) indexOrIdOrDOM = indexOrIdOrDOM.index; const lineObj = l(indexOrIdOrDOM); if (!isViewable(lineObj.DOM)) lineObj.DOM.scrollIntoView({block: 'center'}); jumpToLast(lineObj); }

scroll
画面内に表示できる行数の最大数を返す関数 getVisibleLineCount() を使って、どのくらいscrollするかを決める
cursor.js
function getVisibleLineCount() { return Math.round(window.innerHeight / scrapboxDOM.lines.lastElementChild.clientHeight); } export function scrollHalfUp(count = 1) { let index = Math.round(cursor().line.index - getVisibleLineCount() / 2 * count); index = index < 0 ? 0 : index; goLine(index); } export function scrollHalfDown(count = 1) { let index = Math.round((cursor().line.index + getVisibleLineCount() / 2) * count); index = index < scrapboxDOM.lines.children.length ? index : scrapboxDOM.lines.children.length - 1; goLine(index); } export function scrollUp(count = 1) { for (const _ of range(count)) { press('PageUp'); } } export function scrollDown(count = 1) { for (const _ of range(count)) { press('PageDown'); } }

任意のspan.c-*に飛ぶ

#2021-03-14 21:39:21
#2021-01-17 15:53:11