物理キーボードとiPadの組み合わせでScrapboxを利用する際、画面長押しせずに入力モードに切り替える
ctrl + iで、長押しと同じ動きをする。
Safariで動作確認
code:js
const sleep = (milliseconds) => new Promise(resolve => setTimeout(resolve, milliseconds));
function createTouchEvent(element, type, X, Y) {
console.log(createTouchEvent: ${type});
const touch = new Touch({
identifier: 0,
target: element,
clientX: X,
clientY: Y,
pageX: X + window.scrollX,
pageY: Y + window.scrollY,
});
const touchList = document.createTouchList(touch);
const param = {
type: type,
canBubble: true,
cancelable: true,
view: window,
detail: 0,
screenX: X + window.scrollX,
screenY: Y + window.scrollY,
clientX: X,
clientY: Y,
ctrlKey: false,
altKey: false,
shiftKey: false,
metaKey: false,
touches: touchList,
targetTouches: touchList,
changedTouches: touchList,
scale: 0,
rotation: 0,
touchItem: 0
}
let event = document.createEvent('TouchEvent');
event.initTouchEvent(
param.type,
param.canBubble,
param.cancelable,
param.view,
param.detail,
param.screenX,
param.screenY,
param.clientX,
param.clientY,
param.ctrlKey,
param.altKey,
param.shiftKey,
param.metaKey,
param.touches,
param.targetTouches,
param.changedTouches,
param.scale,
param.rotation);
return event;
}
async function mimicHoldDown(element, {X, Y, holding = 2000, wait = 10} = {}) {
element.dispatchEvent(createTouchEvent(element, 'touchstart', X, Y));
await sleep(holding);
element.dispatchEvent(createTouchEvent(element, 'touchend', X, Y));
await sleep(wait); // 少し待つ
}
function getHeadLineDOM() {
return document.getElementById(L${scrapbox.Page.lines[0].id});
}
function position({pos = 'right'} = {}) {
const {top, left} = document.getElementById('editor').getBoundingClientRect(); // 基準座標
const style = document.getElementsByClassName('cursor')?.0.style; const cursor = {
top: parseInt(style.top),
left: parseInt(style.left),
height: parseInt(style.height),
};
const position = {
x: cursor.left + left + 1,
y: (cursor.top + top) + cursor.height / 2,
};
const targets = document.elementsFromPoint(position.x, position.y);
const char = targets.find(target => target.classList.contains('char-index'));
const line = targets.find(target => target.classList.contains('line'));
return {char, line};
};
function isHeightViewable(element){
const {top, bottom} = element.getBoundingClientRect();
return top >= 0 && bottom <= window.innerHeight;
}
document.addEventListener('keydown', async (e) => {
console.log(e);
switch(e.key) {
case 'i':
if (e.ctrlKey) {
// ctrl + i が入力モード
console.log("入力モード");
const target = (position().line ?? getHeadLineDOM())?.getElementsByClassName('text')?.0; const {right, top, height} = target.getBoundingClientRect();
await mimicHoldDown(target, {X: right + 1, Y: top + height / 2});
}
break;
default:
console.log(e.key)
}
});