From f0be697b558c39388bb25f20140c113261973d9d Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sun, 17 Sep 2023 14:22:25 +1000 Subject: [PATCH] Protect image occlusion fields and cloze field --- proto/anki/notetypes.proto | 15 ++++++++++++++- rslib/src/image_occlusion/notetype.rs | 26 +++++++++++++++++++++----- rslib/src/notetype/mod.rs | 3 ++- rslib/src/notetype/stock.rs | 9 +++++++-- 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/proto/anki/notetypes.proto b/proto/anki/notetypes.proto index 6163229bd..c58fcea83 100644 --- a/proto/anki/notetypes.proto +++ b/proto/anki/notetypes.proto @@ -220,4 +220,17 @@ message RestoreNotetypeToStockRequest { // Older notetypes did not store their original stock kind, so we allow the UI // to pass in an override to use when missing, or for tests. optional StockNotetype.Kind force_kind = 2; -} \ No newline at end of file +} + +enum ImageOcclusionField { + IMAGE_OCCLUSION_FIELD_OCCLUSIONS = 0; + IMAGE_OCCLUSION_FIELD_IMAGE = 1; + IMAGE_OCCLUSION_FIELD_HEADER = 2; + IMAGE_OCCLUSION_FIELD_BACK_EXTRA = 3; + IMAGE_OCCLUSION_FIELD_COMMENTS = 4; +} + +enum ClozeField { + CLOZE_FIELD_TEXT = 0; + CLOZE_FIELD_BACK_EXTRA = 1; +} diff --git a/rslib/src/image_occlusion/notetype.rs b/rslib/src/image_occlusion/notetype.rs index 2ed763088..b889eb7f8 100644 --- a/rslib/src/image_occlusion/notetype.rs +++ b/rslib/src/image_occlusion/notetype.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use anki_proto::notetypes::stock_notetype::OriginalStockKind; +use anki_proto::notetypes::ImageOcclusionField; use crate::notetype::stock::empty_stock; use crate::notetype::Notetype; @@ -61,16 +62,31 @@ pub(crate) fn image_occlusion_notetype(tr: &I18n) -> Notetype { tr.notetypes_image_occlusion_name(), ); nt.config.css = IMAGE_CLOZE_CSS.to_string(); + let occlusion = tr.notetypes_occlusion(); - nt.add_field(occlusion.as_ref()); + let mut config = nt.add_field(occlusion.as_ref()); + config.tag = Some(ImageOcclusionField::Occlusions as u32); + config.prevent_deletion = true; + let image = tr.notetypes_image(); - nt.add_field(image.as_ref()); + config = nt.add_field(image.as_ref()); + config.tag = Some(ImageOcclusionField::Image as u32); + config.prevent_deletion = true; + let header = tr.notetypes_header(); - nt.add_field(header.as_ref()); + config = nt.add_field(header.as_ref()); + config.tag = Some(ImageOcclusionField::Header as u32); + config.prevent_deletion = true; + let back_extra = tr.notetypes_back_extra_field(); - nt.add_field(back_extra.as_ref()); + config = nt.add_field(back_extra.as_ref()); + config.tag = Some(ImageOcclusionField::BackExtra as u32); + config.prevent_deletion = true; + let comments = tr.notetypes_comments_field(); - nt.add_field(comments.as_ref()); + config = nt.add_field(comments.as_ref()); + config.tag = Some(ImageOcclusionField::Comments as u32); + config.prevent_deletion = true; let err_loading = tr.notetypes_error_loading_image_occlusion(); let qfmt = format!( diff --git a/rslib/src/notetype/mod.rs b/rslib/src/notetype/mod.rs index 547999972..1e0151897 100644 --- a/rslib/src/notetype/mod.rs +++ b/rslib/src/notetype/mod.rs @@ -456,8 +456,9 @@ impl Notetype { } } - pub(crate) fn add_field>(&mut self, name: S) { + pub(crate) fn add_field>(&mut self, name: S) -> &mut NoteFieldConfig { self.fields.push(NoteField::new(name)); + self.fields.last_mut().map(|f| &mut f.config).unwrap() } pub(crate) fn add_template(&mut self, name: S1, qfmt: S2, afmt: S3) diff --git a/rslib/src/notetype/stock.rs b/rslib/src/notetype/stock.rs index ba62735cc..71f1308f8 100644 --- a/rslib/src/notetype/stock.rs +++ b/rslib/src/notetype/stock.rs @@ -2,6 +2,7 @@ // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html use anki_i18n::I18n; +use anki_proto::notetypes::ClozeField; use anki_proto::notetypes::notetype::config::Kind as NotetypeKind; use anki_proto::notetypes::stock_notetype::Kind; pub(crate) use anki_proto::notetypes::stock_notetype::Kind as StockKind; @@ -169,9 +170,13 @@ pub(crate) fn cloze(tr: &I18n) -> Notetype { tr.notetypes_cloze_name(), ); let text = tr.notetypes_text_field(); - nt.add_field(text.as_ref()); + let mut config = nt.add_field(text.as_ref()); + config.tag = Some(ClozeField::Text as u32); + config.prevent_deletion = true; + let back_extra = tr.notetypes_back_extra_field(); - nt.add_field(back_extra.as_ref()); + config = nt.add_field(back_extra.as_ref()); + config.tag = Some(ClozeField::BackExtra as u32); let qfmt = format!("{{{{cloze:{}}}}}", text); let afmt = format!("{}
\n{{{{{}}}}}", qfmt, back_extra); nt.add_template(nt.name.clone(), qfmt, afmt);