From e3a4ef896e64d983cc6f28d61de6c7a687256076 Mon Sep 17 00:00:00 2001 From: Eric Kaden <608341+EricKaden@users.noreply.github.com> Date: Fri, 23 Oct 2026 23:56:17 -0400 Subject: [PATCH] M12: docstrings for the functions next to the focus-script change --- crates/automation/src/a11y.rs | 4 ++++ crates/automation/tests/it/automation.rs | 4 ++++ crates/engine/src/tests.rs | 4 ++++ crates/ui-egui/src/forms_ui.rs | 1 + crates/ui-egui/tests/it/xfa.rs | 4 ++++ crates/xfa/src/script.rs | 2 ++ 6 files changed, 19 insertions(+) diff --git a/crates/automation/src/a11y.rs b/crates/automation/src/a11y.rs index a0598262ad..276010c612 100644 --- a/crates/automation/src/a11y.rs +++ b/crates/automation/src/a11y.rs @@ -677,6 +677,8 @@ impl Automation { Ok(json!({ "scripts": list })) } + /// `js_set_document_script`: set the document-level script `name` to `script`, or remove it + /// when `script` is left out, as one undoable edit; returns the document's scripts. pub(crate) fn js_set_document_script(&mut self, a: &Args) -> Result { let edit = pdfcraft_engine::Edit::SetDocumentScript { name: a.str("name")?.into(), script: a.opt_str("script")?.map(str::to_string) }; let id = self.doc(a)?.id; @@ -724,6 +726,8 @@ impl Automation { Ok(json!({ "changed": changed, "alerts": out.alerts, "console": out.console, "requests": reqs, "errors": out.errors })) } + /// `form_merge_data`: merge the form data files at `paths` into one CSV at `path`, a row per + /// file; returns the path and the row and column counts. pub(crate) fn form_merge_data(&mut self, a: &Args) -> Result { let mut files = Vec::new(); for p in a.strs("paths")? { diff --git a/crates/automation/tests/it/automation.rs b/crates/automation/tests/it/automation.rs index a2c0c216c5..ef8ff612a7 100644 --- a/crates/automation/tests/it/automation.rs +++ b/crates/automation/tests/it/automation.rs @@ -6777,6 +6777,8 @@ fn growable_xfa_text_paginates_after_fill_save_and_print() { let _ = std::fs::remove_dir_all(dir); } +/// A print button repeated on every page of an XFA form runs its own XFA click script (a print +/// request) through js_run, from each copy, before and after saving and reopening. #[test] fn repeated_xfa_print_buttons_work_through_tools_and_after_reopen() { let dir = workdir("xfa-print-buttons"); @@ -6846,6 +6848,8 @@ fn xfa_focus_scripts_run_through_form_focus() { } } +/// XFA scripts run through the tools: initialize and calculate on opening, calculations after +/// form_fill, and a button's click script through js_run, adding a row that undo takes away. #[test] fn xfa_scripts_run_for_buttons_and_field_changes_through_tools() { let dir = workdir("xfa-scripts"); diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index 6a9574ed5b..5aff0fe936 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -4640,6 +4640,8 @@ fn guard_turns_a_panic_into_an_error() { assert_eq!(guard(|| -> u8 { panic!("page {n} is bad") }), Err("page 3 is bad".to_string())); } +/// Measurement edits are single undoable steps that leave the file unchanged when they fail, and +/// respect the document's annotation permissions. #[test] fn measurement_edits_are_transactional_and_honour_annotation_permissions() { let mut session = Session::default(); @@ -4823,6 +4825,8 @@ fn a_radio_buttons_own_focus_scripts_run() { assert_eq!(field_text(&s, id, "drops"), "1"); } +/// A dynamic XFA form is laid out from its template on opening (an appended revision, not an +/// edit), takes values from the datasets, and saves its filled values incrementally. #[test] fn dynamic_xfa_forms_are_laid_out_on_open_filled_and_saved_incrementally() { let original = Arc::new(pdfcraft_xfa::fixtures::shell(&pdfcraft_xfa::fixtures::template(3))); diff --git a/crates/ui-egui/src/forms_ui.rs b/crates/ui-egui/src/forms_ui.rs index 1e171431cc..68fb8b7876 100644 --- a/crates/ui-egui/src/forms_ui.rs +++ b/crates/ui-egui/src/forms_ui.rs @@ -93,6 +93,7 @@ fn fillable(f: &FormField) -> bool { !f.read_only() && !matches!(f.kind, FormFieldKind::PushButton | FormFieldKind::Signature) } +/// The editor's draft for widget `widget` of field `f`, opened on the field's value. fn open_focus(f: &FormField, widget: usize) -> Focus { Focus { name: f.name.clone(), diff --git a/crates/ui-egui/tests/it/xfa.rs b/crates/ui-egui/tests/it/xfa.rs index 120fe2cc2e..98dce60cd8 100644 --- a/crates/ui-egui/tests/it/xfa.rs +++ b/crates/ui-egui/tests/it/xfa.rs @@ -130,6 +130,8 @@ fn click_field(h: &mut Harness<'static, PdfCraftApp>, name: &str) { h.run_steps(4); } +/// Clicking an XFA button in the app runs its click script: one adds a row, another shows its +/// message as a notice. #[test] fn xfa_buttons_run_their_scripts_in_the_app() { let mut h = open(pdfcraft_xfa::fixtures::shell(&pdfcraft_xfa::fixtures::scripted_template())); @@ -225,6 +227,8 @@ fn an_enter_script_that_changes_its_field_shows_in_the_editor() { assert_eq!(value(&h), ""); } +/// A message an initialize script shows on opening appears at once, and a print request from it +/// is refused (only a click may print). #[test] fn messages_from_scripts_run_on_open_show_right_away() { let tpl = pdfcraft_xfa::fixtures::scripted_template() diff --git a/crates/xfa/src/script.rs b/crates/xfa/src/script.rs index 3ae38e4d6e..74ec8652fd 100644 --- a/crates/xfa/src/script.rs +++ b/crates/xfa/src/script.rs @@ -440,9 +440,11 @@ pub fn form_tree(tpl: &Template, data: Option<&DataNode>, ov: &Overrides) -> Liv /// Does the template declare any script (an event, calculation or validation)? Forms without /// one need no live form and run nothing. pub fn has_scripts(tpl: &Template) -> bool { + /// Is any of `s` a non-blank script? fn any(s: &[Script]) -> bool { s.iter().any(|s| !s.text.trim().is_empty()) } + /// Has field `f` an event, calculate or validate script? fn field(f: &Field) -> bool { any(&f.scripts) || [&f.calculate, &f.validate].into_iter().flatten().any(|s| !s.text.trim().is_empty()) }