M12: opening a document leaves the field highlight the one in front reads

An open set the session's field highlight to the remembered Highlight fields for the new document's scripts, and the frame only set it back to the active document's afterwards: an edit of that document handled in between read the new one's default as app.runtimeHighlight. The open now passes the remembered setting in its own context (OpenContext::with_highlight) and the session's value stays (CodeRabbit, on #4691).
This commit is contained in:
Eric Kaden committed 2026-10-27 00:39:05 -04:00
1 parent fd9a76e3ce
commit 8745623fca
3 files changed
+52 -6

No files matched your search

+8
View File
@@ -27,6 +27,14 @@ pub struct PreparedDocument {
}
impl OpenContext {
/// This context with Highlight fields `on`, which the document's scripts read as
/// `app.runtimeHighlight` while it opens. A new document opens with the remembered setting
/// while the session keeps the one of the document in front, which its scripts read.
pub fn with_highlight(mut self, on: bool) -> Self {
self.highlight = on;
self
}
/// Prepare a document without mutating the session that supplied this context.
pub fn prepare_open(
&self,
+8 -6
View File
@@ -106,9 +106,10 @@ impl PdfCraftApp {
if let Some(ctx) = &self.ctx {
worker.set_context(ctx);
}
self.session.set_field_highlight(self.view_defaults.highlight_fields);
let receiver =
worker.submit(token, self.session.open_context(), request.name.clone(), request.path.clone(), request.password, request.input)?;
// A new document opens with the remembered Highlight fields, which its scripts read; the
// session keeps the document in front's.
let context = self.session.open_context().with_highlight(self.view_defaults.highlight_fields);
let receiver = worker.submit(token, context, request.name.clone(), request.path.clone(), request.password, request.input)?;
self.next_open_token = token;
self.pending_opens.push(PendingOpen {
token,
@@ -226,9 +227,10 @@ impl PdfCraftApp {
activate: bool,
) -> Result<(), String> {
use pdfcraft_render::OpenError;
// A new document opens with the remembered Highlight fields, which its scripts read.
self.session.set_field_highlight(self.view_defaults.highlight_fields);
let prepared = match self.session.prepare_open(name, path.clone(), bytes.clone(), password) {
// A new document opens with the remembered Highlight fields, which its scripts read; the
// session keeps the document in front's.
let context = self.session.open_context().with_highlight(self.view_defaults.highlight_fields);
let prepared = match context.prepare_open(name, path.clone(), bytes.clone(), password) {
Ok(prepared) => prepared,
Err(e @ (OpenError::NeedsPassword | OpenError::WrongPassword)) => {
let error = matches!(e, OpenError::WrongPassword).then(|| "Incorrect password. Try again.".to_string());
+36
View File
@@ -231,6 +231,42 @@ fn a_secured_dynamic_xfa_form_shows_its_layout_and_its_security() {
h.get_by_label("Security settings");
}
/// Opening another document doesn't change the field highlight the document in front's scripts
/// read: the new one opens with the remembered Highlight fields in its own open context. Before,
/// the open set the session's value, so an edit of the first document handled before the next
/// frame read the new document's default as `app.runtimeHighlight`.
#[test]
fn opening_another_document_keeps_the_highlight_the_one_in_front_reads() {
let script = |js: &str| format!(r#"<event activity="click"><script contentType="application/x-javascript">{js}</script></event>"#);
let xdp = format!(
r##"<?xml version="1.0" encoding="UTF-8"?>
<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
<subform name="form" layout="tb">
<pageSet><pageArea name="front"><contentArea x="0.5in" y="0.5in" w="7.5in" h="10in"/><medium short="8.5in" long="11in"/></pageArea></pageSet>
<field name="look" w="1in" h="0.3in"><ui><button/></ui>{look}</field>
<field name="seen" w="2in" h="0.3in"><ui><textEdit/></ui></field>
</subform>
</template>
</xdp:xdp>
"##,
look = script("xfa.form.form.seen.rawValue = String(app.runtimeHighlight);"),
);
let mut h = open(pdfcraft_xfa::fixtures::shell(&xdp));
let app = h.state_mut();
// The document in front has Highlight fields on; the remembered setting is off.
app.view_defaults.highlight_fields = false;
app.views[0].highlight_fields = true;
h.run_steps(2);
let app = h.state_mut();
let first = app.views[0].id;
app.open_bytes("next.pdf", None, pdfcraft_xfa::fixtures::shell(&pdfcraft_xfa::fixtures::template(1))).unwrap();
// Before the next frame, the first document's script reads its own setting.
app.session.apply(first, pdfcraft_engine::Edit::XfaEvent { som: "form[0].look[0]".into(), activity: "click".into() }).unwrap();
let seen = app.session.get(first).unwrap().form.iter().find(|f| f.name == "seen").map(|f| f.value.clone()).unwrap_or_default();
assert_eq!(seen, vec!["true".to_string()], "the first document's script reads its own Highlight fields");
}
/// A form that turns field highlighting on (`app.runtimeHighlight = true` in a `layout:ready`
/// script) gets it, and so does the next document, as with the Highlight fields button.
#[test]