Forms: a background form's highlight request applies at once

This commit is contained in:
Eric Kaden committed 2026-10-19 23:20:41 -04:00
1 parent 98d9310309
commit 1ef0c1b948
4 files changed
+45 -8

No files matched your search

+15
View File
@@ -194,6 +194,21 @@ impl Session {
self.docs.iter_mut().find(|d| d.id == id).map(|d| std::mem::take(&mut d.js_output)).unwrap_or_default()
}
/// The last field-highlight change (`app.runtimeHighlight`) scripts asked for in document
/// `id`, taken out of its waiting output; the rest stays for [`Session::take_js_output`].
pub fn take_js_highlight(&mut self, id: DocId) -> Option<bool> {
let doc = self.docs.iter_mut().find(|d| d.id == id)?;
let mut last = None;
doc.js_output.requests.retain(|r| match r {
Request::Highlight(on) => {
last = Some(*on);
false
}
_ => true,
});
last
}
/// Run `script` in document `id`, for a button (`target`: the field, event "Mouse Up") or
/// the console (no target). Field changes and `resetForm` are applied as one undoable step;
/// everything else the script asked for is returned.
+11 -8
View File
@@ -67,14 +67,7 @@ impl PdfCraftApp {
&[("u", &u)],
),
Request::SaveAs => self.run_command("file.save_as"),
// As the Highlight fields button does: this document and the next ones.
Request::Highlight(on) => {
if let Some(i) = view {
self.views[i].highlight_fields = on;
}
self.view_defaults.highlight_fields = on;
self.session.set_field_highlight(on);
}
Request::Highlight(on) => self.script_highlight(id, on),
Request::Focus(_) | Request::Beep | Request::Reset(_) => {}
}
}
@@ -83,6 +76,16 @@ impl PdfCraftApp {
}
}
/// A form's script turned field highlighting on or off (`app.runtimeHighlight`): as the
/// Highlight fields button does, for document `id` and the next ones.
pub(crate) fn script_highlight(&mut self, id: DocId, on: bool) {
if let Some(v) = self.views.iter_mut().find(|v| v.id == id) {
v.highlight_fields = on;
}
self.view_defaults.highlight_fields = on;
self.session.set_field_highlight(on);
}
/// Run a push button's JavaScript (its Mouse Up action).
pub fn run_button_script(&mut self, id: DocId, field: &str, script: &str) {
// A script reads the fields: include what's still being typed in one (#166).
+3
View File
@@ -1380,6 +1380,9 @@ impl PdfCraftApp {
if activate {
let out = self.session.take_js_output(id);
self.handle_js(id, out);
} else if let Some(on) = self.session.take_js_highlight(id) {
// The field highlight a form asks for isn't about the current document: now.
self.script_highlight(id, on);
}
Ok(id)
}
+16
View File
@@ -746,6 +746,22 @@ fn a_background_startup_forms_script_notice_waits_until_its_tab_is_selected() {
assert!(h.state().toast.is_none(), "the notice is delivered once");
}
/// A form opened behind the current document that turns field highlighting on gets it at
/// once, and so does the next document: only requests that act on the current document (a
/// print, a save, a message) wait for its tab.
#[test]
fn a_background_forms_highlight_request_applies_at_once() {
let h = harness(&[3]);
assert!(!h.state().view_defaults.highlight_fields);
deliver_startup(&h, "late-form.pdf", pdfcraft_xfa::fixtures::shell(&pdfcraft_xfa::fixtures::layout_ready_template()));
let mut h = h;
h.run_steps(2);
assert_eq!(h.state().active, Some(0), "it opened behind the current document");
assert!(h.state().views[1].highlight_fields, "the background form is highlighted");
assert!(!h.state().views[0].highlight_fields, "the current document is left as it was");
assert!(h.state().view_defaults.highlight_fields, "the next document opens highlighted");
}
/// Embedded bytes and the PDF's original /UF name stay independent of the Save suggestion.
fn attachment_fixture() -> Vec<u8> {
attachment_pdf("invoice\u{202e}fdp.exe", b"hello notes")