-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathfront.html
100 lines (87 loc) · 4.45 KB
/
front.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<div id="cloze-original" hidden="">{{Text}}</div>
<div id="cloze-anki-rendered" hidden="">{{cloze:Text}}</div>
<div id="cloze-overlapping-config" hidden="">{{Overlapping}}</div>
<div id="cloze-js-rendered"></div>
<script>
// This ceremony makes sure the render function is run exactly once:
(function() {
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
var alreadyRendered = false;
function render() {
if (alreadyRendered) return;
var config = document.getElementById("cloze-overlapping-config").innerText.split(/[,\s|.]+/);
var leadingClozes = config[0] === "0" ? 0 : (+config[0] || 1);
var followingClozes = +config[1] || 0;
var showAllClozes = (config[2] || "true").toLowerCase() === "true"; // Set to false to omit, e.g. for long lyrics/poems
var revealAllClozes = (config[3] || "false").toLowerCase() === "true"; // On the back, reveal other clozes we didnʼt ask for?
var revealAllCustomPlaceholders = (config[4] || "false").toLowerCase() === "true";
var divOriginal = document.getElementById("cloze-original");
var divJsRendered = document.getElementById("cloze-js-rendered");
var currentCloze = +(
(document.body.className.match(/(^|\s)card(\d+)(\s|$)/) || [])[2] ||
((document.getElementById("qa_box") && document.getElementById("qa_box").className && document.getElementById("qa_box").className.match(/(^|\s)card(\d+)(\s|$)/)) || [])[2] ||
0
);
var allClozes = (function(){
var allMatches = divOriginal.innerHTML.match(/\{\{c\d+::[\s\S]*?\}\}/g);
var res = {};
for (var i = 0; i < allMatches.length; i++) {
var match = allMatches[i].match(/\{\{c(\d+)::([\s\S]*?)(::([\s\S]*?))?\}\}/);
res[+match[1]] = res[+match[1]] || {askAll: false, clozes: {}};
if (match[2] === "ask-all")
res[+match[1]].askAll = true;
res[+match[1]].clozes[allMatches[i]] = {content: match[2], placeholder: match[4] ? match[4] : "..."};
}
return res;
})();
var isBackSide = document.getElementById("cloze-is-back") ? true : false;
var question = divOriginal.innerHTML;
for (var i in allClozes) {
for (var orig in allClozes[i].clozes) {
var replacement = "";
var markBlue = false;
var needle = new RegExp(escapeRegExp(orig), "g");
if (allClozes[i].askAll)
replacement = "";
else if (i == currentCloze || allClozes[currentCloze].askAll) {
markBlue = true;
replacement = isBackSide ? allClozes[i].clozes[orig].content : "[" + allClozes[i].clozes[orig].placeholder + "]";
} else if (currentCloze - leadingClozes <= i && i <= currentCloze + followingClozes)
replacement = allClozes[i].clozes[orig].content;
else if (showAllClozes && !allClozes[i].askAll)
replacement = (isBackSide && revealAllClozes) ? allClozes[i].clozes[orig].content : "[" + (revealAllCustomPlaceholders ? allClozes[i].clozes[orig].placeholder : "...") + "]";
else {
replacement = "";
// Also get rid of following new lines, commas, dots, etc.
needle = new RegExp(escapeRegExp(orig) + "(<br>|[\\s,.])*", "g");
}
question = question.replace(needle, function () {
return (markBlue ? "<span class=\"cloze\">" : "") + replacement + (markBlue ? "</span>" : "");
});
}
}
alreadyRendered = true;
divJsRendered.innerHTML = question;
}
function delayedRender() {
if (window.requestAnimationFrame) window.requestAnimationFrame(render); // less flickering
else window.setTimeout(render, 0);
};
window.onload = delayedRender();
if (document.readyState === "complete") delayedRender();
else document.addEventListener("DOMContentLoaded", delayedRender);
// Observe document.body class changes to trigger re-rendering.
// This is useful, because Anki doesn’t always start with an up-to-date class list:
// https://forums.ankiweb.net/t/card-card-classes-only-injected-separately-now/27387.
const observer = new MutationObserver(function(mutationsList, observer) {
for (let mutation of mutationsList) {
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
delayedRender();
}
}
});
observer.observe(document.body, { attributes: true });
})();
</script>