Add-on porting notes for Anki 2.1.41

Some porting notes for add-ons wanting to support Anki 2.1.41:

(this has been made a wiki post - please add anything you feel would be useful here, and if you don’t have permission, please reply below)

Type Hints

Most of Anki’s codebase now has type hints, and beta builds are available on PyPI. Instead of just clicking around in your add-on to see what if anything has broken, investing some time getting mypy working is recommended, as it can help alert you to cases where you’re calling a function that doesn’t exist, or has a different type signature. See the beta docs for how to install a beta build into your local Python, and the add-on guide for how you can use it to get code completion and type checking with mypy.

Debug messages

Some deprecated functions will print a message to stdout, which will not be visible if you’re only
using the GUI. While developing add-ons, it’s recommended to run Anki from a console.

  • On Windows, use anki-console.exe
  • On Mac, run /Applications/Anki.app/Contents/MacOS/AnkiMac from Terminal.app
  • On Linux, run ‘anki’ from a terminal

Changes by area

Sidebar

  • The browser sidebar code has moved into sidebar.py.
  • Each section has its own parent node
  • Tags are now shown in a tree
  • If you were using gui_hooks.browser_will_build_tree, some of the stages have been renamed, and some have been added
  • If you were monkey-patching browser functions, using the hook above is recommended.

Browser

  • Add-ons that were monkey-patching the browser startup may fail, as setupSearch()'s call signature has been changed. Switching to one of the browser hooks if appropriate is recommended.
  • To (re)open the browse screen and perform a search, use
aqt.dialogs.open("Browser", self.mw, search=some_text)

or one of the named filters, such as

aqt.dialogs.open("Browser", self.mw, search=SearchTerm(deck="some name that will be automatically escaped"))
  • The preview button has moved into the editor, and the filter button has been removed.
  • The reschedule action has been replaced with “forget” & “set due date”

Editor

  • The underlying javascript/HTML has been reworked, so code that was changing it will need to be reworked.
  • Use getEditorField(n) to access a specific editor field

  • Use forEditorField() if you want to iterate over the editor fields. The first argument is a list, which can have one item for each editor field.

  • If you registered your JS setup code on gui_hooks.editor_will_load_note, note that whereas previously the editor tore down the whole HTML structure, only to rebuild it again, now it will only update components it needs to. To prevent that your code initializes a field multiple times (e.g. adding graphical elements or registering event handlers), a typical pattern would be:

forEditorField([], (field, _data) => {
      if (!field.hasAttribute("has-my-addon")) {
        // setup field
        field.setAttribute("has-my-addon", "")
      }
})
  • Instead of window.getSelection, you need to call .getSelection() on the field div itself.
8 Likes

[added above]

2 Likes

Thanks Henrik, I’ve copied that into the above. I believe you should be able to edit the top post directly if I’ve configured things correctly - any user who’s been around for a while should see an Edit button in the bottom right of the top post. Eg:

1 Like

I think you should also mention that pycmd was replaced by bridgeCommand.
I don’t know whether there is anything to do about it, so I won’t edit the post

bridgeCommand is an alias for pycmd, defined here. bridgeCommand is just a better fit nowadays, as the JavaScript might be executed on Mobile, where the bridge would be Obj-C or Swift (and possible Java in the future).
So while pycmd probably won’t break anytime soon, it’s true that bridgeCommand is the better term going forward.

3 Likes