mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-10 14:41:51 +00:00
M6: a script's field-highlight change reaches the next edit of a batch, and is kept only when its request is
This commit is contained in:
@@ -2687,6 +2687,8 @@ fn run_edit(doc: &mut pdfcraft_cos::Document, edit: &Edit, cx: &mut EditCtx) ->
|
||||
let ran = xfa::on_event(doc, &tpl, som, activity, &mut run);
|
||||
cx.xfa_datasets = run.datasets;
|
||||
cx.xfa_ran_away |= run.ran_away;
|
||||
// The next edit of a batch reads the highlight this one's scripts set.
|
||||
cx.highlight = run.highlight;
|
||||
ran.map_err(EditError::Invalid)?;
|
||||
}
|
||||
Edit::SetFieldImage { name, image } => {
|
||||
@@ -3484,6 +3486,8 @@ fn xfa_after_data_change(doc: &mut pdfcraft_cos::Document, cx: &mut EditCtx, cal
|
||||
.unwrap_or_else(|m| Err(format!("laying the form out again failed unexpectedly ({m})")));
|
||||
cx.xfa_datasets = run.datasets;
|
||||
cx.xfa_ran_away |= run.ran_away;
|
||||
// The next edit of a batch reads the highlight this one's scripts set.
|
||||
cx.highlight = run.highlight;
|
||||
if let Err(e) = r {
|
||||
cx.xfa_out.errors.push(e);
|
||||
}
|
||||
@@ -4071,6 +4075,8 @@ impl Session {
|
||||
.unwrap_or_else(|m| Err(format!("the form's scripts failed unexpectedly ({m})")));
|
||||
cx.xfa_datasets = run.datasets;
|
||||
cx.xfa_ran_away |= run.ran_away;
|
||||
// The next edit of a batch reads the highlight this one's scripts set.
|
||||
cx.highlight = run.highlight;
|
||||
if let Err(e) = ran {
|
||||
cx.xfa_out.errors.push(e);
|
||||
}
|
||||
|
||||
@@ -8102,6 +8102,35 @@ fn a_forms_layout_ready_scripts_run_once_it_is_laid_out() {
|
||||
assert!(s.take_js_output(id).requests.is_empty());
|
||||
}
|
||||
|
||||
/// In a batch of XFA events, a later event's scripts read the field highlight an earlier one's set:
|
||||
/// `on`'s click turns it on, and `look`'s click, in the same batch, records what it reads.
|
||||
#[test]
|
||||
fn a_later_xfa_event_in_a_batch_reads_the_highlight_an_earlier_one_set() {
|
||||
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="on" w="1in" h="0.3in"><ui><button/></ui>{on}</field>
|
||||
<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>
|
||||
"##,
|
||||
on = script("app.runtimeHighlight = true;"),
|
||||
look = script("xfa.form.form.seen.rawValue = String(app.runtimeHighlight);"),
|
||||
);
|
||||
let mut s = Session::new();
|
||||
let id = s.open("batch.pdf", None, Arc::new(pdfcraft_xfa::fixtures::shell(&xdp)), None).expect("opens");
|
||||
let click = |som: &str| Edit::XfaEvent { som: som.into(), activity: "click".into() };
|
||||
s.apply(id, Edit::Batch { edits: vec![click("form[0].on[0]"), click("form[0].look[0]")], label: "Click".into() }).expect("clicks");
|
||||
let seen = s.get(id).unwrap().form.iter().find(|f| f.name == "seen").map(|f| f.value.clone()).unwrap_or_default();
|
||||
assert_eq!(seen, vec!["true".to_string()]);
|
||||
}
|
||||
|
||||
/// Field scripts of one edit read the field highlight an earlier one set: `on`'s calculation turns
|
||||
/// it on, and `seen`'s, which runs after it, records what it reads.
|
||||
#[test]
|
||||
|
||||
@@ -1579,6 +1579,16 @@ mod runtime_highlight {
|
||||
assert_eq!(o.effects, vec![XfaEffect::Highlight(true)]);
|
||||
let o = run_xfa(script, &ev, &XfaDoc { highlight: true, ..Default::default() }, &root, Limits::default());
|
||||
assert_eq!((o.result.as_deref(), o.effects.len()), (Some("true,true"), 0), "already on: nothing to ask for");
|
||||
// Past the effect cap the request is dropped, and the script still reads the setting the
|
||||
// viewer has.
|
||||
let full = format!(
|
||||
"for (var i = 0; i < {}; i++) {{ xfa.host.beep(); }} app.runtimeHighlight = true; String(app.runtimeHighlight)",
|
||||
crate::xfa::MAX_EFFECTS
|
||||
);
|
||||
let o = run_xfa(&full, &ev, &XfaDoc::default(), &root, Limits::default());
|
||||
assert_eq!(o.error, None, "{o:?}");
|
||||
assert_eq!(o.result.as_deref(), Some("false"));
|
||||
assert!(!o.effects.contains(&XfaEffect::Highlight(true)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1159,9 +1159,12 @@ fn runtime_highlight(_: &JsValue, _: &[JsValue], ctx: &mut Context) -> JsResult<
|
||||
fn set_runtime_highlight(_: &JsValue, args: &[JsValue], ctx: &mut Context) -> JsResult<JsValue> {
|
||||
let on = arg(args, 0).to_boolean();
|
||||
let mut h = host(ctx)?.borrow_mut();
|
||||
if h.doc.highlight != on {
|
||||
let e = XfaEffect::Highlight(on);
|
||||
// Changed only when the request is kept: past the effect cap the script goes on reading the
|
||||
// setting the viewer has.
|
||||
if h.doc.highlight != on && h.reserve(&e, payload(&e)) {
|
||||
h.doc.highlight = on;
|
||||
h.push(XfaEffect::Highlight(on));
|
||||
h.record(e);
|
||||
}
|
||||
Ok(JsValue::undefined())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user