Greasy Fork

Greasy Fork is available in English.

Bunpro: Prevent cursor from jumping to end of input field

Restores the cursor position after romaji get converted to kana

当前为 2019-10-10 提交的版本,查看 最新版本

// ==UserScript==
// @name         Bunpro: Prevent cursor from jumping to end of input field
// @description  Restores the cursor position after romaji get converted to kana
// @version      0.1
// @namespace    https://pampel.dev
// @run-at       document-start
// @author       pampel
// @match        https://bunpro.jp/*
// @grant        none
// ==/UserScript==

'use strict';

addEventListener("turbolinks:load", () => {
  let inputElem = document.querySelector("#study-answer-input");
  if (!inputElem)
    return;
  let oldEndPos = 0;
  inputElem.addEventListener('keydown', e => {
    switch (e.key) {
      case 'ArrowLeft':
        oldEndPos = Math.max(oldEndPos - 1, 0);
        break;
      case 'ArrowRight':
        oldEndPos = Math.min(oldEndPos + 1, inputElem.value.length);
        break;
      case 'Home':
      case 'PageUp':
      case 'ArrowUp':
        oldEndPos = 0;
        break;
      case 'End':
      case 'PageDown':
      case 'ArrowDown':
        oldEndPos = inputElem.value.length;
        break;
    }
  });
  let vocals = ["a", "e", "i", "o", "u"];
  let oldLength = 0;
  // firefox version
  inputElem.addEventListener('selectionchange', e => {
    setTimeout(() => {
      if (inputElem.selectionEnd === inputElem.value.length && inputElem.selectionStart === inputElem.selectionEnd) {
        let newEndPos = inputElem.value.length - oldLength + oldEndPos;
        // the selectionchange event is fired on selectionEnd assignment even if the value doesn't change
        // so without this condition the event is fired constantly when the cursor is at the of the input field
        if (inputElem.selectionEnd !== newEndPos)
          inputElem.selectionEnd = newEndPos;
      }
      oldEndPos = inputElem.selectionEnd;
      oldLength = inputElem.value.length;
    }, 0);
  });
  // chrome version
  document.addEventListener('selectionchange', e => {
    if (document.activeElement !== inputElem)
      return;

    if (inputElem.selectionEnd === inputElem.value.length && inputElem.selectionStart === inputElem.selectionEnd)
      inputElem.selectionEnd = inputElem.value.length - oldLength + oldEndPos;

    oldEndPos = inputElem.selectionEnd;
    oldLength = inputElem.value.length;
  });
});