generated at
scrapbox-line-clicker
hr
mouse clickをscriptから発生させて、scrapbox edtor内の行頭 or 行末にcursorを移動させるAPI
リンク、code blockの先頭、画像、動画、tableの先頭の内部をクリックしてもcursorを移動できないので、行内へのjumpは出来ないようにしている

使用できる関数一覧
行頭に飛ぶ
jumpHeadChar()
行末に飛ぶ
jumpLastChar()
最初の非空白文字に飛ぶ
jumpHeadCharWithoutBlank()
最後の非空白文字に飛ぶ
jumpLastCharWithoutBlank()

旧ver.のscrapbox-cursor-jumperとの違い
scroll処理をomitした
責務の分離をやりたかった
関数を実行する前に、目的の行が画面上に表示されるようにscroll処理を行う必要が生じるようになった
行idではなく行のDOMを渡す
click イベントも発生させるようにしてみた
なにか変化するのかどうかはわからない

実装したいもの
任意の文字に飛ぶ関数
scrapbox-keyboard-emulation-2と組み合わせる必要がある

import
script.js
import {line} from '/api/code/takker/scrapbox-line-info-2/script.js';

行頭行末移動
script.js
export function jumpHeadChar({lineDOM, shiftKey = false, ctrlKey = false, altKey = false} = {}) { const {left, top, height} = lineDOM.getBoundingClientRect(); //console.log(`right = ${right}, top = ${top}, height = ${height}, breakNum = ${breakNum}`); execClick({element: lineDOM, X: left, Y: top + height - height / (2 * line(lineDOM).breakNum + 2), shiftKey, ctrlKey, altKey}); } export function jumpLastChar({lineDOM, shiftKey = false, ctrlKey = false, altKey = false} = {}) { const textDOM = lineDOM.getElementsByClassName('text')[0]; const {right, top, height} = textDOM.getBoundingClientRect(); //console.log(`right = ${right}, top = ${top}, height = ${height}, breakNum = ${breakNum}`); execClick({element: textDOM, X: right, Y: top + height - height / (2 * line(lineDOM).breakNum + 2), shiftKey, ctrlKey, altKey}); }

非空白文字を除いた場所に移動
script.js
export function jumpHeadCharWithoutBlank({ lineDOM, shiftKey = false, ctrlKey = false, altKey = false} = {}) { const textDOM = lineDOM.getElementsByClassName('text')[0]; const {left, top, height} = line(lineDOM).headNonBlankCharDOM.getBoundingClientRect(); //console.log(`right = ${right}, top = ${top}, height = ${height}, breakNum = ${breakNum}`); execClick({element: textDOM, X: left, Y: top + height / 2, shiftKey, ctrlKey, altKey}); } export function jumpLastCharWithoutBlank({ lineDOM, shiftKey = false, ctrlKey = false, altKey = false} = {}) { const textDOM = lineDOM.getElementsByClassName('text')[0]; const {right, top, height} = line(lineDOM).lastNonBlankCharDOM.getBoundingClientRect(); execClick({element: textDOM, X: right, Y: top + height / 2, shiftKey, ctrlKey, altKey}); }

MouseEventを発生させる処理
script.js
function execClick({element, X, Y, shiftKey, ctrlKey, altKey}) { const mouseOptions = { button: 0, clientX: X, clientY: Y, bubbles: true, cancelable: true, shiftKey: shiftKey, ctrlKey: ctrlKey, altKey: altKey, view: window, }; element.dispatchEvent(new MouseEvent("mousedown", mouseOptions)); element.dispatchEvent(new MouseEvent("mouseup", mouseOptions)); element.dispatchEvent(new MouseEvent("click", mouseOptions)); }

hr
テストコード
test.js
import {installCDN} from '/api/code/villagepump/install-CDN/script.js' import { jumpHeadChar, jumpLastChar, jumpHeadCharWithoutBlank, jumpLastCharWithoutBlank, } from '/api/code/takker/scrapbox-line-clicker/script.js'; import {scrapboxDOM} from '/api/code/takker/scrapbox-dom-accessor/script.js'; (async () => { await installCDN({ id: 'mousetrap-for-scrapbox', src: '//cdnjs.cloudflare.com/ajax/libs/mousetrap/1.6.5/mousetrap.min.js', }); const moustrapOnEdit = new Mousetrap(scrapboxDOM.editor); const lines = document.getElementsByClassName('lines')[0]; for (let i = 0; i < 10; i++) { moustrapOnEdit.bind(`alt+x ${i}`, e =>{ _log(`${e.key} is pressed.`); e.stopPropagation(); e.preventDefault(); getLine(i).scrollIntoView({block: 'center'}); jumpHeadChar({lineDOM: getLine(i)}) }); moustrapOnEdit.bind(`alt+g ${i}`, e =>{ _log(`${e.key} is pressed.`); e.stopPropagation(); e.preventDefault(); getLine(lines.children.length - 1 - i).scrollIntoView({block: 'center'}); jumpLastChar({lineDOM: getLine(lines.children.length - 1 - i)}) }); moustrapOnEdit.bind(`ctrl+alt+x ${i}`, e =>{ _log(`${e.key} is pressed.`); e.stopPropagation(); e.preventDefault(); getLine(i).scrollIntoView({block: 'center'}); jumpHeadCharWithoutBlank({lineDOM: getLine(i)}) }); moustrapOnEdit.bind(`ctrl+alt+g ${i}`, e =>{ _log(`${e.key} is pressed.`); e.stopPropagation(); e.preventDefault(); getLine(lines.children.length - 1 - i).scrollIntoView({block: 'center'}); jumpLastCharWithoutBlank({lineDOM: getLine(lines.children.length - 1 - i)}) }); } function _log(msg, ...objects){ if (objects.length > 0) { console.log(`[test-code] ${msg}`, objects); return; } console.log(`[test-code] ${msg}`); } function getLine(number) { return lines.children[number]; } _log('ready to start'); })();

#2020-12-18 07:42:54