How to fallback to default keystroke handlers for shortcuts?

Hi everyone,
I’m working on an add-on that changes the behavior of scrolling keystrokes such as “Up” and “Down” for certain card types but not other. For example, for “IR3” cards, scroll 5% of the page when “Up” or “Down” button is pressed.

To achieve this, I’ve setup handlers for up/down shortcuts:

        addHook('reviewStateShortcuts', self.setReviewShortcuts)
    def setReviewShortcuts(self, shortcuts):
        shortcuts.extend([
            ('Down', self.lineDown),
            ('Up', self.lineUp)
        ])

However, I’m not sure how to fall back to the default scrolling behavior:


    def lineUp(self):
        if isIrCard():
            currentPos = self._getCurrentPosition()
            movementSize = self.viewportHeight * self.settings['lineScrollFactor']
            newPos = max(0, (currentPos - movementSize))
            mw.web.eval('window.scrollTo(0, {});'.format(newPos))
        else:
            # Fall back to default scrolling behavior. How?

Any help is appreciated. Thank you in advance :slight_smile: .

Since the default behavior of the arrow keys is not defined in the reviewer, I think one way to go about this is to register a JavaScript keydown handler instead, and maintain some global JS flag to determine whether the current card is an IR card, calling event.preventDefault() only for IR cards.

In Python side


import json

from anki.cards import Card
from aqt import gui_hooks

def on_question_shown(card: Card) -> None:
    mw.reviewer.web.eval(f"var isIrCard = {json.dumps(isIrCard())};")


gui_hooks.reviewer_did_show_question.append(on_question_shown)
# TODO: Inject the JS code below and the scroll settings - see the webview_will_set_content docs
# gui_hooks.webview_will_set_content.append(on_webview_will_set_content)

In JavaScript side

document.addEventListener("keydown", (e) => {
  if (isIrCard) {
    if (e.code === "ArrowUp") {
      window.scrollTo(0, 100); // TODO: use the scroll settings
      e.preventDefault();
    }
    // TODO: Handle ArrowDown
  }
  // Do nothing for non-IR cards
});

Not tested

3 Likes

This looks promising. I’ll try it.
Thank you!

@abdo thanks for the hint. It works! (with some tweaks for existing code)

Here’s a sample PR in case anyone faces a similar issue in the future: Move movement keys handling to js by tvhong · Pull Request #4 · tvhong/incremental-reading · GitHub

1 Like