Anki 2.1.50 Beta 1 & 2

Thanks for the clarifications, that makes sense. A shortcut for copy notes would be also great, yes, personally I don’t have any preferences.

1 Like

In some cases, the review window doesn’t refresh correctly after executing some command (typically delete note or forget note) in the browser:

(While reviewing a card) > Browser > Delete note > Close Browser > The review window get irresponsive and this warning message is displayed:
Error1

Using Qt5

Please let me know how you go with the latest git.

Thanks, though this disables caching it programwide? Including in the reviewer, where it would be useful. I’d suggest disabling caching entirely, but only for the card browser & previewer.

edit: Also, though this is minor, it be neat if one could set C-b/-i to work with <b> & <i> again as it was previously (→ CSS rules; and AnkiDroid’s formating still adds them) rather than <strong> & <em>. (The former are meant for rendering only, the latter also for TTS-emphasis.)

The card browser does not (no longer?) refocus the field when moving across cards of the same note type.

Example:

  1. You want to check changes across cards
  2. Select the first card & relevant field
  3. Ctrl-n etc. to another card of the same type

Expected: Card browser retains that field in view.

Actual outcome: When there’s enough differing content the in other (prior) fields – so their rendered height varies sufficiently – the selected field will not be in view.

e: Unrelated, but since .50’s big changes, Anki constantly logs this to the console:

JS error /_anki/legacyPageData?id=<longnumber>:1 Uncaught ReferenceError: $ is not defined

2 Likes

I also get

JS error /_anki/legacyPageData?id=1894106667328:1 Uncaught TypeError: Cannot read property 'classList' of null

after opening any note in the Browse screen in Preview and closing it again. I ruled out my own js by testing it on a note without any javascript.

I suspect defaulting to the deck of the currently selected card may be the least surprising option for users?

That doesn’t seem to happen for me - did you rule out add-ons?

@hengiesel I presume there was a reason it was switched to strong/em?

Yes, no add-ons being used. The issue seems to happen randomly, but it definitely happens (often) in my system. I’ll keep trying to find a pattern to reproduce the issue with a 100% probability.

I worded it in that awkward way because I was thinking about Notes mode, in which case the note’s first card is the current card by definition.
I’ll make a PR.

1 Like

About the JS issue in the previewer: It occurs when an inline script tries to execute a function from a previously sourced external file. Like so:

<script src="_foo.js"></script>
<script>fooFct()</script>

Yields Uncaught ReferenceError: fooFct is not defined.

It also won’t preview the {{type::}} fields like the template editor’s previewer does.

It’s not specific to the previewer, it can also happen in the reviewer and clayout when an external js file is first loaded into the webview, and moreover, it’s been happening since long before 2.1.50 beta. It’s probably not an issue that needs to be fixed, but maybe something that users should deal with on their own.

One way to get external scripts to work as expected is to use document.createElement("script") to dynamically create a script element, insert it into the document, and return a Promise when it’s done loading.

Alternatively, you can use import() function, as closet add-on does.

An advantage of dynamic loading is that you can avoid reloading a large external script every time you flip a card by checking if an object exists in the global namespace and loading the script only if it does not exists.

Here is an example

_foo.js

function foo() {
    console.log("foo");
}

_bar.js

function bar() {
    foo();
}

Card Temlate

function injectScript({ src, fname = null }) {
    return fname && fname in globalThis
        ? Promise.resolve()
        : new Promise((resolve) => {
              const script = document.createElement("script");
              script.src = src;
              script.addEventListener("load", () => resolve());
              document.head.appendChild(script);
          });
}

function baz() {
    bar();
}

Promise.all(
    [
        { src: "_foo.js", fname: "foo" },
        { src: "_bar.js", fname: "bar" },
    ].map(injectScript),
).then(() => baz());
3 Likes

You have a point about dynamic loading, I should check it out.

(Though IIRC AnkiDroid resets the entire webview anyway on flipping? Except for cookies.)

Still, the bugged behavior only occurs to me in the separate previewer – never in the reviewer/card types previewer, and never on AnkiDroid (I don’t have AnkiMobile to test its behavior).

It doesn’t always happen in all cases, and I think it depends on the file size and how the script is written. I have uploaded a sample deck.

In my environment (Win10), this script always gives an error at the very beginning question side of the review session.
js_error


I think it is probably right. So, in most cases, script tags should work just like a normal web page.

That’s… odd. It fails for me (Arch) as well, but only in the reviewer. Both previewers are fine.

For me it’s not related to size or script though, I tried replacing _marked.min.js’s content with a single-line parameter-less function that either did nothing but return a fixed string or console.log something – same failure.

Then I replaced _marked.min.js with my deck’s file that (in it) hasn’t bugged out in ~ three years – same failure. Changed it to the way I call it in my deck – same failure.

But then I noticed that my script runs on its own on the Front, and function calls from the template only occur on the Back. So I figured to try appending the call from the template into _marked.min.js, like so…

document.getElementById("markdown-output").innerHTML = marked.parse('# Marked in browser\n\nRendered by **marked**.');

… and it worked.

So the cause seems to be that for some reason the Front side, the first time it’s shown in a review run, mustn’t call any external functions (if loaded/called directly).

Probably an issue that goes beyond this 2.1.50 thread, though.

Not sure if I am doing something wrong here, but for me, links inserted via create_link always get the callback function of the last inserted link.

gui_hooks.top_toolbar_did_init_links.append(on_toolbar_init)

def on_toolbar_init(links, top_toolbar):
    lnk1 = top_toolbar.create_link("","Test 1", test_link_1)
    links.insert(len(links)-1, lnk1)
    lnk2 = top_toolbar.create_link("","Test 2", test_link_2)
    links.insert(len(links)-1, lnk2)

def test_link_1():
   print("link 1 clicked")
def test_link_2():
   print("link 2 clicked")

This prints link 2 clicked when clicking on Test 1

@hkr @nwwt Thanks, that’s a useful repro case, and we should fix this on Anki’s side. The relevant code is on reviewer/index.ts:75. We used to use jQuery to replace the HTML, but are now doing it ourselves. When we set .innerHTML, script tags are not executed, so the code there replaces the script tags in order to trigger them to load. Presumably the remote script is fetched asynchronously, so we end up running the next inline script before the symbol is defined.

To fix this, I guess we should investigate to see if there’s a better way to get the scripts to run than the method we’re currently using. If there isn’t, then presumably we could fix it by making the function asynchronous, and awaiting the loading of any remote scripts before continuing the loop.

@prollo command arg must be unique

2 Likes

Have you two ruled out add-ons for this? I cannot recreate this.

Removing .style.width sounds reasonable. I’ll address it in a PR.

The former are meant for rendering only, the latter also for TTS-emphasis.

How do you use TTS within Anki?

It seemed to be good practice among other WYSIWYG editors out there, and I thought it was a painless switch, as browsers have the CSS defined for them.
I was also thinking about a time when, we might apply Template CSS in the browser, and then it might also be slightly less awkward to redefine the CSS for strong, than it would be for b.
But none of these are strong reasons to stick with strong / em.

@nwwt the fact that other editors are using strong/em by default makes me worry they may be aware of something I’m not. You said it affects TTS; is that some standard behaviour that is documented somewhere, or is it an implementation detail of the TTS engine you’re using?

see eg. the Mozilla reference (strong, em), which also links the actual standard.

That these elements are rendered the same is coincidence / a visual limitation.

The <strong> element is for content that is of greater importance, while the <b> element is used to draw attention to text without indicating that it’s more important.

While <em> is used to change the meaning of a sentence as spoken emphasis does (“I love carrots” vs. "I love carrots "), <strong> is used to give portions of a sentence added importance (e.g., " Warning! This is very dangerous. ")

The <em> element represents stress emphasis of its contents, while the <i> element represents text that is set off from the normal prose, such a foreign word, fictional character thoughts, or when the text refers to the definition of a word instead of representing its semantic meaning.
<em:>: “Just do it already!”, or: “We had to do something about it”.
<i>: “The Queen Mary sailed last night”.

2 Likes

Hi!@dae ! :slightly_smiling_face:

Why does 2.1.50 no longer support Tab windows (like 2.1.49 in the picture)? I miss it very much.

Two things spotted.

First, when I type in Japanese almost always the first letter is doubled. I always get it when going to another field using tab.

edit. It happens with QT6.

Second, the background of the card editor differs. It turns out it’s also in 2.1.49. I may be nitpicking but it stands out to me.

Also when the menu was white in 49 it looked better in my opinion.