mirror of
https://github.com/ankitects/anki.git
synced 2025-09-25 09:16:38 -04:00
Merge remote-tracking branch 'upstream/HEAD' into text-import-export
This commit is contained in:
commit
93a90db7d4
14 changed files with 76 additions and 18 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -1,5 +1,8 @@
|
|||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": true
|
||||
},
|
||||
"files.watcherExclude": {
|
||||
"**/.git/objects/**": true,
|
||||
"**/.git/subtree-cache/**": true,
|
||||
|
|
|
@ -141,6 +141,13 @@ that's causing the problem, and then run
|
|||
bazel run //ts:format
|
||||
```
|
||||
|
||||
If you get complaints from eslint about unordered imports, run the following
|
||||
line first, then run ts:format:
|
||||
|
||||
```
|
||||
bazel run eslint -- --fix
|
||||
```
|
||||
|
||||
For other packages, change to the folder and run
|
||||
|
||||
```
|
||||
|
|
|
@ -158,6 +158,7 @@ class TemplateRenderContext:
|
|||
self._fill_empty = fill_empty
|
||||
self._fields: dict | None = None
|
||||
self._latex_svg = False
|
||||
self._question_side: bool = True
|
||||
if not notetype:
|
||||
self._note_type = note.note_type()
|
||||
else:
|
||||
|
@ -167,6 +168,10 @@ class TemplateRenderContext:
|
|||
# hooks, you can insert it into this dictionary
|
||||
self.extra_state: dict[str, Any] = {}
|
||||
|
||||
@property
|
||||
def question_side(self) -> bool:
|
||||
return self._question_side
|
||||
|
||||
def col(self) -> anki.collection.Collection:
|
||||
return self._col
|
||||
|
||||
|
@ -226,9 +231,11 @@ class TemplateRenderContext:
|
|||
answer_av_tags=[],
|
||||
)
|
||||
|
||||
self._question_side = True
|
||||
qtext = apply_custom_filters(partial.qnodes, self, front_side=None)
|
||||
qout = self.col()._backend.extract_av_tags(text=qtext, question_side=True)
|
||||
|
||||
self._question_side = False
|
||||
atext = apply_custom_filters(partial.anodes, self, front_side=qout.text)
|
||||
aout = self.col()._backend.extract_av_tags(text=atext, question_side=False)
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ if __name__ == "__main__":
|
|||
"anki",
|
||||
"tests",
|
||||
"tools",
|
||||
"--exclude=_pb2|buildinfo|_gen",
|
||||
"--exclude=_pb2|buildinfo|_gen|_backend/generated|fluent",
|
||||
]
|
||||
+ args,
|
||||
check=False,
|
||||
|
|
|
@ -115,12 +115,12 @@ def register_repos():
|
|||
################
|
||||
|
||||
core_i18n_repo = "anki-core-i18n"
|
||||
core_i18n_commit = "0d97543af78a11c7cc4f2af34f4eaef18e86cae9"
|
||||
core_i18n_zip_csum = "ca722979b1c6ff4098d5fc3b91a723e51ac760e1a723ac46983c05248e4e79e2"
|
||||
core_i18n_commit = "f404191d521051946b824d7974b14aff35932016"
|
||||
core_i18n_zip_csum = "da823e153ff55ca1bb46d8e1eb5b74ca723f596abf85fb530f2457d17d0ffa05"
|
||||
|
||||
qtftl_i18n_repo = "anki-desktop-ftl"
|
||||
qtftl_i18n_commit = "9eda7432ff61768e867376bf7e4cf9a450056c9b"
|
||||
qtftl_i18n_zip_csum = "6544d7d02cf605559f8d1ac1103d9375b2a2ecad499734dff748cf2675d59deb"
|
||||
qtftl_i18n_commit = "51724fbb327815358d6f896a4f79cf9cb2303562"
|
||||
qtftl_i18n_zip_csum = "e8f4723eb6d20432754b08c19164fbaafd43ff8222779e2a7cd1fb835f41c7b5"
|
||||
|
||||
i18n_build_content = """
|
||||
filegroup(
|
||||
|
|
|
@ -122,7 +122,9 @@ impl LimitTreeMap {
|
|||
.unwrap();
|
||||
|
||||
let mut map = HashMap::new();
|
||||
if root_limits.limits.review > 0 {
|
||||
map.insert(root_deck.id, root_id.clone());
|
||||
}
|
||||
|
||||
let mut limits = Self { tree, map };
|
||||
let mut remaining_decks = child_decks.into_iter().peekable();
|
||||
|
|
|
@ -287,6 +287,13 @@ mod test {
|
|||
self.add_or_update_deck(deck).unwrap();
|
||||
}
|
||||
|
||||
fn set_deck_review_limit(&mut self, deck: DeckId, limit: u32) {
|
||||
let dcid = self.get_deck(deck).unwrap().unwrap().config_id().unwrap();
|
||||
let mut conf = self.get_deck_config(dcid, false).unwrap().unwrap();
|
||||
conf.inner.reviews_per_day = limit;
|
||||
self.add_or_update_deck_config(&mut conf).unwrap();
|
||||
}
|
||||
|
||||
fn queue_as_deck_and_template(&mut self, deck_id: DeckId) -> Vec<(DeckId, u16)> {
|
||||
self.build_queues(deck_id)
|
||||
.unwrap()
|
||||
|
@ -318,6 +325,18 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_build_empty_queue_if_limit_is_reached() {
|
||||
let mut col = open_test_collection();
|
||||
col.set_config_bool(BoolKey::Sched2021, true, false)
|
||||
.unwrap();
|
||||
let note_id = col.add_new_note("Basic").id;
|
||||
let cids = col.storage.card_ids_of_notes(&[note_id]).unwrap();
|
||||
col.set_due_date(&cids, "0", None).unwrap();
|
||||
col.set_deck_review_limit(DeckId(1), 0);
|
||||
assert_eq!(col.queue_as_deck_and_template(DeckId(1)), vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_queue_building() -> Result<()> {
|
||||
let mut col = open_test_collection();
|
||||
|
|
|
@ -43,10 +43,12 @@
|
|||
let previousTooltip: string = tooltip;
|
||||
$: if (tooltip !== previousTooltip) {
|
||||
previousTooltip = tooltip;
|
||||
if (tooltipObject !== undefined) {
|
||||
const element: HTMLElement = tooltipObject["_element"];
|
||||
tooltipObject.dispose();
|
||||
createTooltip(element);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<slot {createTooltip} {tooltipObject} />
|
||||
|
|
|
@ -66,7 +66,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
tooltip={getPlatformString(saveKeyCombination)}
|
||||
--border-left-radius="5px">{tr.deckConfigSaveButton()}</LabelButton
|
||||
>
|
||||
<Shortcut keyCombination={saveKeyCombination} on:click={() => save(false)} />
|
||||
<Shortcut keyCombination={saveKeyCombination} on:action={() => save(false)} />
|
||||
|
||||
<WithDropdown let:createDropdown --border-right-radius="5px">
|
||||
<LabelButton
|
||||
|
|
|
@ -70,7 +70,7 @@ export function convertMathjax(
|
|||
* Escape characters which are technically legal in Mathjax, but confuse HTML.
|
||||
*/
|
||||
export function escapeSomeEntities(value: string): string {
|
||||
return value.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&");
|
||||
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||||
}
|
||||
|
||||
export function unescapeSomeEntities(value: string): string {
|
||||
|
|
|
@ -40,7 +40,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
import Absolute from "../components/Absolute.svelte";
|
||||
import Badge from "../components/Badge.svelte";
|
||||
import { bridgeCommand } from "../lib/bridgecommand";
|
||||
import { isApplePlatform } from "../lib/platform";
|
||||
import { ChangeTimer } from "./change-timer";
|
||||
import DecoratedElements from "./DecoratedElements.svelte";
|
||||
import { clearableArray } from "./destroyable";
|
||||
|
@ -70,7 +69,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
return fontFamily;
|
||||
}
|
||||
|
||||
const size = isApplePlatform() ? 1.6 : 1.8;
|
||||
const size = 1.6;
|
||||
const wrap = true;
|
||||
|
||||
const fieldStores: Writable<string>[] = [];
|
||||
|
|
|
@ -152,12 +152,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
}
|
||||
|
||||
/**
|
||||
* Image resizing add-ons previously used image.style.width to set the
|
||||
* preferred width of an image. In these cases, if we'd only set
|
||||
* image.width, there would be no visible effect on the image.
|
||||
* To avoid confusion with users we'll clear image.style.width (for now).
|
||||
* Image resizing add-ons previously used image.style.width/height to set the
|
||||
* preferred dimension of an image. In these cases, if we'd only set
|
||||
* image.[dimension], there would be no visible effect on the image.
|
||||
* To avoid confusion with users we'll clear image.style.[dimension] (for now).
|
||||
*/
|
||||
activeImage!.style.removeProperty("width");
|
||||
activeImage!.style.removeProperty("height");
|
||||
if (activeImage!.getAttribute("style")?.length === 0) {
|
||||
activeImage!.removeAttribute("style");
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
function appendEmptyTag(): void {
|
||||
// used by tag badge and tag spacer
|
||||
deselect();
|
||||
const lastTag = tagTypes[tagTypes.length - 1];
|
||||
|
||||
if (!lastTag || lastTag.name.length > 0) {
|
||||
|
@ -219,6 +220,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
activeAfterBlur = index - 1;
|
||||
active = null;
|
||||
activeInput.blur();
|
||||
}
|
||||
|
||||
async function moveToNextTag(index: number): Promise<void> {
|
||||
|
@ -232,6 +234,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
activeAfterBlur = index + 1;
|
||||
active = null;
|
||||
activeInput.blur();
|
||||
|
||||
await tick();
|
||||
activeInput.setSelectionRange(0, 0);
|
||||
|
@ -448,6 +451,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
splitTag(index, detail.start, detail.end)}
|
||||
on:tagadd={() => insertTagKeepFocus(index)}
|
||||
on:tagdelete={() => deleteTagAt(index)}
|
||||
on:tagselectall={selectAllTags}
|
||||
on:tagjoinprevious={() => joinWithPreviousTag(index)}
|
||||
on:tagjoinnext={() => joinWithNextTag(index)}
|
||||
on:tagmoveprevious={() => moveToPreviousTag(index)}
|
||||
|
|
|
@ -5,6 +5,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount, tick } from "svelte";
|
||||
|
||||
import { registerShortcut } from "../../lib/shortcuts";
|
||||
import {
|
||||
delimChar,
|
||||
normalizeTagname,
|
||||
|
@ -230,7 +231,20 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
name = last;
|
||||
}
|
||||
|
||||
onMount(() => input.focus());
|
||||
async function onSelectAll(event: KeyboardEvent) {
|
||||
if (name.length === 0) {
|
||||
input.blur();
|
||||
await tick(); // ensure blur events are processed before tagselectall
|
||||
dispatch("tagselectall");
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
registerShortcut(onSelectAll, "Control+A", { target: input });
|
||||
input.focus();
|
||||
});
|
||||
</script>
|
||||
|
||||
<input
|
||||
|
|
Loading…
Reference in a new issue