allow templates and add-ons to hook into reviewer updated/shown

eg

from anki.hooks import addHook

def prepare(q):
    return q + """
<script>
onUpdateHook.push(function () {
    window.scrollTo(0, 2000);
})
</script>"""

addHook('prepareQuestion', prepare)
This commit is contained in:
Damien Elmes 2017-08-28 14:54:22 +10:00
parent 76b4343c5e
commit a96ddfc3fd
2 changed files with 21 additions and 7 deletions

View file

@ -11,7 +11,7 @@ import html.parser
from anki.lang import _, ngettext from anki.lang import _, ngettext
from aqt.qt import * from aqt.qt import *
from anki.utils import stripHTML, json from anki.utils import stripHTML, json
from anki.hooks import addHook, runHook from anki.hooks import addHook, runHook, runFilter
from anki.sound import playFromText, clearAudioQueue, play from anki.sound import playFromText, clearAudioQueue, play
from aqt.utils import mungeQA, tooltip, askUserDialog, \ from aqt.utils import mungeQA, tooltip, askUserDialog, \
downArrow downArrow
@ -167,6 +167,7 @@ The front of this card is empty. Please run Tools>Empty Cards.""")
playFromText(q) playFromText(q)
# render & update bottom # render & update bottom
q = self._mungeQA(q) q = self._mungeQA(q)
q = runFilter("prepareQuestion", q)
bodyclass = "card card%d" % (c.ord+1) bodyclass = "card card%d" % (c.ord+1)
@ -210,6 +211,7 @@ The front of this card is empty. Please run Tools>Empty Cards.""")
if self.autoplay(c): if self.autoplay(c):
playFromText(a) playFromText(a)
a = self._mungeQA(a) a = self._mungeQA(a)
a = runFilter("prepareAnswer", a)
# render and update bottom # render and update bottom
self.web.eval("_showAnswer(%s);" % json.dumps(a)) self.web.eval("_showAnswer(%s);" % json.dumps(a))
self._showEaseButtons() self._showEaseButtons()

View file

@ -4,7 +4,19 @@ var typeans;
var qFade = 100; var qFade = 100;
var aFade = 0; var aFade = 0;
var onUpdateHook;
var onShownHook;
function _runHook(arr) {
for (var i=0; i<arr.length; i++) {
arr[i]();
}
}
function _updateQA(html, fadeTime, onupdate, onshown) { function _updateQA(html, fadeTime, onupdate, onshown) {
onUpdateHook = [onupdate];
onShownHook = [onshown];
// fade out current text // fade out current text
var qa = $("#qa"); var qa = $("#qa");
qa.fadeTo(fadeTime, 0, function() { qa.fadeTo(fadeTime, 0, function() {
@ -15,7 +27,7 @@ function _updateQA(html, fadeTime, onupdate, onshown) {
qa.text("Invalid HTML on card: "+err); qa.text("Invalid HTML on card: "+err);
} }
_removeStylingFromMathjaxCloze(); _removeStylingFromMathjaxCloze();
onupdate(qa); _runHook(onUpdateHook);
// don't allow drags of images, which cause them to be deleted // don't allow drags of images, which cause them to be deleted
$("img").attr("draggable", false); $("img").attr("draggable", false);
@ -26,19 +38,19 @@ function _updateQA(html, fadeTime, onupdate, onshown) {
// and reveal when processing is done // and reveal when processing is done
MathJax.Hub.Queue(function () { MathJax.Hub.Queue(function () {
qa.fadeTo(fadeTime, 1, function () { qa.fadeTo(fadeTime, 1, function () {
onshown(qa); _runHook(onShownHook);
}); });
}); });
}); });
} }
function _showQuestion(q, bodyclass) { function _showQuestion(q, bodyclass) {
_updateQA(q, qFade, function(obj) { _updateQA(q, qFade, function() {
// return to top of window // return to top of window
window.scrollTo(0, 0); window.scrollTo(0, 0);
document.body.className = bodyclass; document.body.className = bodyclass;
}, function(obj) { }, function() {
// focus typing area if visible // focus typing area if visible
typeans = document.getElementById("typeans"); typeans = document.getElementById("typeans");
if (typeans) { if (typeans) {
@ -48,7 +60,7 @@ function _showQuestion(q, bodyclass) {
} }
function _showAnswer(a, bodyclass) { function _showAnswer(a, bodyclass) {
_updateQA(a, aFade, function(obj) { _updateQA(a, aFade, function() {
if (bodyclass) { if (bodyclass) {
// when previewing // when previewing
document.body.className = bodyclass; document.body.className = bodyclass;
@ -59,7 +71,7 @@ function _showAnswer(a, bodyclass) {
if (e[0]) { if (e[0]) {
e[0].scrollIntoView(); e[0].scrollIntoView();
} }
}, function(obj) { }, function() {
}); });
} }