From ac4c88afdc84de48f19ff0474b2be0a7ed4965dd Mon Sep 17 00:00:00 2001
From: Matthias Metelka <62722460+kleinerpirat@users.noreply.github.com>
Date: Thu, 18 Aug 2022 07:48:34 +0200
Subject: [PATCH] Merge branch 'main' into color-palette
---
ftl/core/editing.ftl | 1 +
ftl/core/fields.ftl | 1 +
proto/anki/notetypes.proto | 1 +
qt/aqt/data/web/css/webview.scss | 7 +-
qt/aqt/editor.py | 28 +-
qt/aqt/fields.py | 5 +
qt/aqt/forms/fields.ui | 76 +++---
rslib/src/notetype/fields.rs | 1 +
rslib/src/notetype/schema11.rs | 9 +-
sass/base.scss | 2 +-
ts/components/WithTooltip.svelte | 11 -
ts/editable/mathjax-element.ts | 7 +
ts/editor/EditorField.svelte | 1 +
ts/editor/FieldDescription.svelte | 7 +-
ts/editor/NoteEditor.svelte | 22 +-
ts/editor/editor-toolbar/LatexButton.svelte | 10 +
.../editor-toolbar/RemoveFormatButton.svelte | 93 ++++---
.../rich-text-input/RichTextInput.svelte | 13 +-
ts/editor/surround.ts | 243 +++++++++++-------
ts/lib/functional.ts | 4 +
20 files changed, 337 insertions(+), 205 deletions(-)
diff --git a/ftl/core/editing.ftl b/ftl/core/editing.ftl
index 6e4d9086a..96e5af0e5 100644
--- a/ftl/core/editing.ftl
+++ b/ftl/core/editing.ftl
@@ -58,6 +58,7 @@ editing-toggle-visual-editor = Toggle Visual Editor
editing-underline-text = Underline text
editing-unordered-list = Unordered list
editing-warning-cloze-deletions-will-not-work = Warning, cloze deletions will not work until you switch the type at the top to Cloze.
+editing-toggle-mathjax-rendering = Toggle MathJax Rendering
## You don't need to translate these strings, as they will be replaced with different ones soon.
diff --git a/ftl/core/fields.ftl b/ftl/core/fields.ftl
index 3f8b3581f..dfcb6f3f0 100644
--- a/ftl/core/fields.ftl
+++ b/ftl/core/fields.ftl
@@ -10,6 +10,7 @@ fields-font = Font:
fields-new-position-1 = New position (1...{ $val }):
fields-notes-require-at-least-one-field = Notes require at least one field.
fields-reverse-text-direction-rtl = Reverse text direction (RTL)
+fields-html-by-default = Use HTML editor by default
fields-size = Size:
fields-sort-by-this-field-in-the = Sort by this field in the browser
fields-that-field-name-is-already-used = That field name is already used.
diff --git a/proto/anki/notetypes.proto b/proto/anki/notetypes.proto
index 6bd9d37ab..ff9f0ee0c 100644
--- a/proto/anki/notetypes.proto
+++ b/proto/anki/notetypes.proto
@@ -72,6 +72,7 @@ message Notetype {
string font_name = 3;
uint32 font_size = 4;
string description = 5;
+ bool plain_text = 6;
bytes other = 255;
}
diff --git a/qt/aqt/data/web/css/webview.scss b/qt/aqt/data/web/css/webview.scss
index ee0f9cd4b..71a377303 100644
--- a/qt/aqt/data/web/css/webview.scss
+++ b/qt/aqt/data/web/css/webview.scss
@@ -14,8 +14,8 @@
body {
color: var(--text-fg);
background: var(--window-bg);
- margin: 1em;
transition: opacity 0.5s ease-out;
+ margin: 2em;
overscroll-behavior: none;
}
@@ -24,11 +24,6 @@ a {
text-decoration: none;
}
-body {
- margin: 2em;
- overscroll-behavior: none;
-}
-
h1 {
margin-bottom: 0.2em;
}
diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py
index d70acb870..034353023 100644
--- a/qt/aqt/editor.py
+++ b/qt/aqt/editor.py
@@ -125,6 +125,7 @@ class Editor:
self.card: Card | None = None
self._init_links()
self.setupOuter()
+ self.add_webview()
self.setupWeb()
self.setupShortcuts()
gui_hooks.editor_did_init(self)
@@ -139,11 +140,12 @@ class Editor:
self.widget.setLayout(l)
self.outerLayout = l
- def setupWeb(self) -> None:
+ def add_webview(self) -> None:
self.web = EditorWebView(self.widget, self)
self.web.set_bridge_command(self.onBridgeCmd, self)
self.outerLayout.addWidget(self.web, 1)
+ def setupWeb(self) -> None:
if self.editorMode == EditorMode.ADD_CARDS:
file = "note_creator"
elif self.editorMode == EditorMode.BROWSER:
@@ -499,6 +501,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
]
flds = self.note.note_type()["flds"]
+ plain_texts = [fld.get("plainText", False) for fld in flds]
descriptions = [fld.get("description", "") for fld in flds]
self.widget.show()
@@ -519,14 +522,26 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
text_color = self.mw.pm.profile.get("lastTextColor", "#00f")
highlight_color = self.mw.pm.profile.get("lastHighlightColor", "#00f")
- js = "setFields({}); setDescriptions({}); setFonts({}); focusField({}); setNoteId({}); setColorButtons({}); setTags({}); ".format(
+ js = """
+ setFields({});
+ setPlainTexts({});
+ setDescriptions({});
+ setFonts({});
+ focusField({});
+ setNoteId({});
+ setColorButtons({});
+ setTags({});
+ setMathjaxEnabled({});
+ """.format(
json.dumps(data),
+ json.dumps(plain_texts),
json.dumps(descriptions),
json.dumps(self.fonts()),
json.dumps(focusTo),
json.dumps(self.note.id),
json.dumps([text_color, highlight_color]),
json.dumps(self.note.tags),
+ json.dumps(self.mw.col.get_config("renderMathjax", True)),
)
if self.addMode:
@@ -1130,6 +1145,14 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
def insertMathjaxChemistry(self) -> None:
self.web.eval("wrap('\\\\(\\\\ce{', '}\\\\)');")
+ def toggleMathjax(self) -> None:
+ self.mw.col.set_config(
+ "renderMathjax", not self.mw.col.get_config("renderMathjax", False)
+ )
+ # hackily redraw the page
+ self.setupWeb()
+ self.loadNoteKeepingFocus()
+
# Links from HTML
######################################################################
@@ -1156,6 +1179,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
mathjaxInline=Editor.insertMathjaxInline,
mathjaxBlock=Editor.insertMathjaxBlock,
mathjaxChemistry=Editor.insertMathjaxChemistry,
+ toggleMathjax=Editor.toggleMathjax,
)
diff --git a/qt/aqt/fields.py b/qt/aqt/fields.py
index a3c25f938..7bbddfe7b 100644
--- a/qt/aqt/fields.py
+++ b/qt/aqt/fields.py
@@ -243,6 +243,7 @@ class FieldDialog(QDialog):
f.fontSize.setValue(fld["size"])
f.sortField.setChecked(self.model["sortf"] == fld["ord"])
f.rtl.setChecked(fld["rtl"])
+ f.plainTextByDefault.setChecked(fld["plainText"])
f.fieldDescription.setText(fld.get("description", ""))
def saveField(self) -> None:
@@ -264,6 +265,10 @@ class FieldDialog(QDialog):
if fld["rtl"] != rtl:
fld["rtl"] = rtl
self.change_tracker.mark_basic()
+ plain_text = f.plainTextByDefault.isChecked()
+ if fld["plainText"] != plain_text:
+ fld["plainText"] = plain_text
+ self.change_tracker.mark_basic()
desc = f.fieldDescription.text()
if fld.get("description", "") != desc:
fld["description"] = desc
diff --git a/qt/aqt/forms/fields.ui b/qt/aqt/forms/fields.ui
index 81f3ce3e0..cb2a04b1b 100644
--- a/qt/aqt/forms/fields.ui
+++ b/qt/aqt/forms/fields.ui
@@ -6,8 +6,8 @@
0
0
- 586
- 376
+ 598
+ 378
@@ -84,13 +84,6 @@
-
-
-
-
-
- fields_editing_font
-
-
-
-
@@ -98,13 +91,27 @@
- -
-
-
- 5
+
-
+
+
+
+ 0
+ 25
+
-
- 300
+
+
+ -
+
+
+ fields_editing_font
+
+
+
+ -
+
+
+ fields_description_placeholder
@@ -115,13 +122,6 @@
- -
-
-
- fields_sort_by_this_field_in_the
-
-
-
-
@@ -135,20 +135,30 @@
- -
-
-
-
- 0
- 25
-
+
-
+
+
+ 5
+
+
+ 300
- -
-
-
- fields_description_placeholder
+
-
+
+
+ fields_sort_by_this_field_in_the
+
+
+
+ -
+
+
+ true
+
+
+ fields_html_by_default
diff --git a/rslib/src/notetype/fields.rs b/rslib/src/notetype/fields.rs
index 1b126f0cf..ca1908e3d 100644
--- a/rslib/src/notetype/fields.rs
+++ b/rslib/src/notetype/fields.rs
@@ -42,6 +42,7 @@ impl NoteField {
config: NoteFieldConfig {
sticky: false,
rtl: false,
+ plain_text: false,
font_name: "Arial".into(),
font_size: 20,
description: "".into(),
diff --git a/rslib/src/notetype/schema11.rs b/rslib/src/notetype/schema11.rs
index 5db53d56b..0fab7e560 100644
--- a/rslib/src/notetype/schema11.rs
+++ b/rslib/src/notetype/schema11.rs
@@ -161,7 +161,7 @@ impl From for NotetypeSchema11 {
/// See [crate::deckconfig::schema11::clear_other_duplicates()].
fn clear_other_field_duplicates(other: &mut HashMap) {
- for key in &["description"] {
+ for key in &["description", "plainText"] {
other.remove(*key);
}
}
@@ -195,6 +195,7 @@ impl From for CardRequirementSchema11 {
}
#[derive(Serialize, Deserialize, Debug, Clone)]
+#[serde(rename_all = "camelCase")]
pub struct NoteFieldSchema11 {
pub(crate) name: String,
pub(crate) ord: Option,
@@ -211,6 +212,9 @@ pub struct NoteFieldSchema11 {
#[serde(default, deserialize_with = "default_on_invalid")]
pub(crate) description: String,
+ #[serde(default, deserialize_with = "default_on_invalid")]
+ pub(crate) plain_text: bool,
+
#[serde(flatten)]
pub(crate) other: HashMap,
}
@@ -222,6 +226,7 @@ impl Default for NoteFieldSchema11 {
ord: None,
sticky: false,
rtl: false,
+ plain_text: false,
font: "Arial".to_string(),
size: 20,
description: String::new(),
@@ -238,6 +243,7 @@ impl From for NoteField {
config: NoteFieldConfig {
sticky: f.sticky,
rtl: f.rtl,
+ plain_text: f.plain_text,
font_name: f.font,
font_size: f.size as u32,
description: f.description,
@@ -259,6 +265,7 @@ impl From for NoteFieldSchema11 {
ord: p.ord.map(|o| o as u16),
sticky: conf.sticky,
rtl: conf.rtl,
+ plain_text: conf.plain_text,
font: conf.font_name,
size: conf.font_size as u16,
description: conf.description,
diff --git a/sass/base.scss b/sass/base.scss
index fa5e21cf1..ab8054a6b 100644
--- a/sass/base.scss
+++ b/sass/base.scss
@@ -32,7 +32,7 @@ $utilities: (
flex-basis: 75%;
}
-* {
+body {
overscroll-behavior: none;
}
diff --git a/ts/components/WithTooltip.svelte b/ts/components/WithTooltip.svelte
index 6adbb7c11..6ad68a673 100644
--- a/ts/components/WithTooltip.svelte
+++ b/ts/components/WithTooltip.svelte
@@ -38,17 +38,6 @@
}
onDestroy(() => tooltipObject?.dispose());
-
- // hack to update field description tooltips
- let previousTooltip: string = tooltip;
- $: if (tooltip !== previousTooltip) {
- previousTooltip = tooltip;
- if (tooltipObject !== undefined) {
- const element: HTMLElement = tooltipObject["_element"];
- tooltipObject.dispose();
- createTooltip(element);
- }
- }
diff --git a/ts/editable/mathjax-element.ts b/ts/editable/mathjax-element.ts
index 247ccb458..1c1480e50 100644
--- a/ts/editable/mathjax-element.ts
+++ b/ts/editable/mathjax-element.ts
@@ -20,6 +20,10 @@ function trimBreaks(text: string): string {
.replace(/\n*$/, "");
}
+export const mathjaxConfig = {
+ enabled: true,
+};
+
export const Mathjax: DecoratedElementConstructor = class Mathjax
extends HTMLElement
implements DecoratedElement
@@ -41,6 +45,9 @@ export const Mathjax: DecoratedElementConstructor = class Mathjax
}
static toUndecorated(stored: string): string {
+ if (!mathjaxConfig.enabled) {
+ return stored;
+ }
return stored
.replace(mathjaxBlockDelimiterPattern, (_match: string, text: string) => {
const trimmed = trimBreaks(text);
diff --git a/ts/editor/EditorField.svelte b/ts/editor/EditorField.svelte
index 447460e10..23588ffb6 100644
--- a/ts/editor/EditorField.svelte
+++ b/ts/editor/EditorField.svelte
@@ -12,6 +12,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
fontFamily: string;
fontSize: number;
direction: "ltr" | "rtl";
+ plainText: boolean;
description: string;
}
diff --git a/ts/editor/FieldDescription.svelte b/ts/editor/FieldDescription.svelte
index af2cd4270..41f2cd105 100644
--- a/ts/editor/FieldDescription.svelte
+++ b/ts/editor/FieldDescription.svelte
@@ -32,10 +32,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html