mobile版scrapboxのtext-inputにfocusを当て
目的
mobile版scrapboxでUserScriptから文字入力できる状態にしたい
画面を触らず、物理キーボードのみで編集できるようにするために必要
背景
mobile版scrapboxでは、画面を長押しすることでキーボードが表示され、文字入力できるようになる
理由とか:/villagepump/スマホからscrapbox編集する人#5fc3bf908ee92a0000b6937b
タッチパネルのみで操作するなら問題ない
しかし、物理キーボードで操作するとなると面倒なことになる
キーボードが隠れるたびに、画面に手を伸ばして長押ししてキーボードをいちいち出さないといけない
そこで、UserScriptからなんとか長押しをemulateできないか試してみることにした
成果
scrapbox-pointer-emulation@0.1.0#6123008d1280f000002f0899
作業log
実験用コード
code:js
(async () => {
const {focusEnd} = await import("https://scrapbox.io/api/code/takker/scrapbox-motion-emulation/script.js");
scrapBindings.push({key:"i", command: async () => {await focusEnd();return false}, type: "browser"});
})();
うまくいったもの
code:js
export async function mimicHoldDown(element, {button = 0, X, Y, shiftKey = false, ctrlKey = false, altKey = false, holding = 1000, wait = 10} = {}) {
const touch = new Touch({
identifier: 0,
target: element,
clientX: X,
clientY: Y,
pageX: X + window.scrollX,
pageY: Y + window.scrollY,
});
const mouseOptions = {
button: 0,
clientX: X,
clientY: Y,
changedTouches: touch,
touches: touch,
bubbles: true,
cancelable: true,
shiftKey: shiftKey,
ctrlKey: ctrlKey,
altKey: altKey,
view: window,
};
element.dispatchEvent(new TouchEvent("touchstart", mouseOptions));
element.dispatchEvent(new MouseEvent("mousedown", mouseOptions));
await sleep(holding);
element.dispatchEvent(new MouseEvent("mouseup", mouseOptions));
element.dispatchEvent(new TouchEvent("touchend", mouseOptions));
element.dispatchEvent(new MouseEvent("click", mouseOptions));
await sleep(wait); // 少し待つ
}
elementはspan.textにした
長押しは1秒で十分
うまくいかなかったもの
MouseEventを使う
code:js
export async function mimicHoldDown(element, {button = 0, X, Y, shiftKey = false, ctrlKey = false, altKey = false, holding = 2000, wait = 10} = {}) {
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));
await sleep(holding);
element.dispatchEvent(new MouseEvent("mouseup", mouseOptions));
element.dispatchEvent(new MouseEvent("click", mouseOptions));
await sleep(wait); // 少し待つ
}
これで行末を長押しするようにしてみたところ、行末への移動はできたがキーボードを表示する事はできなかった
TouchEventを同時に出す
TouchEventを使ったらこんなエラーが出た
code:log
index.js:formatted:117319 Uncaught TypeError: Cannot read property 'pageX' of undefined
at getPageX (index.js:formatted:117319)
at getInitialValues (index.js:formatted:117288)
at MobilePointerEvent.resetSwipeCursor (index.js:formatted:117059)
at MobilePointerEvent.onTouchStart (index.js:formatted:117075)
at HTMLDivElement.wrapper (index.js:formatted:2361)
at HTMLDivElement.dispatch (index.js:formatted:9774)
at HTMLDivElement.pe.handle (index.js:formatted:9712)
at HTMLDivElement.wrapped (index.js:formatted:32685)
at mimicHoldDown (script.js:34)
at focusEnd (script.js:24)
at command (<anonymous>:3:60)
at c (VM743 mousetrap.min.js:5)
at d.k._handleKey (VM743 mousetrap.min.js:7)
at d.handleKey (VM743 mousetrap.min.js:10)
at HTMLDocument.e (VM743 mousetrap.min.js:5)
at HTMLDocument.wrapped (index.js:formatted:32685)
どうやらTouchEvent.changedTouchesにTouchを入れておかないといけないみたい
入れた
code:js
export async function mimicHoldDown(element, {button = 0, X, Y, shiftKey = false, ctrlKey = false, altKey = false, holding = 1000, wait = 10} = {}) {
const touch = new Touch({
identifier: 0,
target: element,
clientX: X,
clientY: Y,
});
const mouseOptions = {
button: 0,
clientX: X,
clientY: Y,
changedTouches: touch,
touches: touch,
bubbles: true,
cancelable: true,
shiftKey: shiftKey,
ctrlKey: ctrlKey,
altKey: altKey,
view: window,
};
element.dispatchEvent(new TouchEvent("touchstart", mouseOptions));
element.dispatchEvent(new MouseEvent("mousedown", mouseOptions));
await sleep(holding);
element.dispatchEvent(new MouseEvent("mouseup", mouseOptions));
element.dispatchEvent(new TouchEvent("touchend", mouseOptions));
element.dispatchEvent(new MouseEvent("click", mouseOptions));
await sleep(wait); // 少し待つ
}
12:42:16 反応なし……
elementをspan.textに替えたりしたのに……
何が行けないのだろう?takker.icon
実際に長押ししたときのEventとの違い
関係なさそうなやつ
cancelBubble: true
defaultPrevented: true
composed: true
pageXとpageYがある
12:53:47 ↑を入れたらキーボードでてきた!
#2021-08-23 12:21:08