Forms: doc comments for the functions this change touches

This commit is contained in:
Eric Kaden
2026-10-19 23:39:31 -04:00
parent 9da056e00e
commit 257c843eed
8 changed files with 30 additions and 0 deletions
+1
View File
@@ -646,6 +646,7 @@ impl Automation {
}
}
/// A script's request as `js_run` reports it: one small object per kind of request.
fn request_json(r: &pdfcraft_engine::js::Request) -> Value {
use pdfcraft_engine::js::Request as R;
match r {
+4
View File
@@ -2265,6 +2265,8 @@ struct EditCtx {
}
impl EditCtx {
/// The context for one edit: `now` (the session's clock) dates it, and with `salt` seeds the
/// ids it makes.
fn new(now: Option<i64>, salt: u64) -> Self {
let mut seed = 0x9E37_79B9_7F4A_7C15u64 ^ salt;
if let Some(t) = now {
@@ -3375,6 +3377,8 @@ impl Session {
Ok(self.commit_open(prepared))
}
/// What [`OpenContext::prepare_open`] runs inside its panic guard: read, decrypt and lay out
/// the document, and run an XFA form's opening scripts.
fn prepare_open_unguarded(
context: &OpenContext,
name: String,
+3
View File
@@ -6107,6 +6107,9 @@ fn undo_never_makes_an_unsaved_document_clean() {
assert!(!s.get(new).unwrap().dirty, "once saved, undo back to the saved state is clean");
}
/// layout:ready scripts run once on opening: the root's turns field highlighting on (only when it
/// is off), a field's sets a value and a later script reads the new highlight, while page
/// numbering is left to the layout and form:ready is another event.
#[test]
fn a_forms_layout_ready_scripts_run_once_it_is_laid_out() {
let bytes = Arc::new(pdfcraft_xfa::fixtures::shell(&pdfcraft_xfa::fixtures::layout_ready_template()));
+2
View File
@@ -911,6 +911,8 @@ fn color_object(ctx: &mut Context) -> JsObject {
o.build()
}
/// The AcroForm object model as globals: the document's methods and properties (`getField`,
/// `numPages`, `info`, …), `app`, `util`, `console`, `display` and `color`.
fn install(ctx: &mut Context) -> JsResult<()> {
let globals: [(&str, usize, NativeFunction); 9] = [
("getField", 1, NativeFunction::from_fn_ptr(get_field)),
+9
View File
@@ -15,6 +15,7 @@ fn fields() -> Vec<FieldState> {
]
}
/// The document these tests' scripts run in.
fn doc() -> DocInfo {
DocInfo { file_name: "order.pdf".into(), num_pages: 3, page: 0, info: vec![("title".into(), "Order".into())], highlight: false }
}
@@ -380,6 +381,7 @@ mod xfa_model {
}
}
/// Run JavaScript `script` as `target`'s `activity` script on [`form`].
fn go(script: &str, target: &str, activity: &str) -> XfaOutcome {
let ev = XfaEvent { activity: activity.into(), target: target.into(), ..Default::default() };
let doc = XfaDoc { file_name: "f.pdf".into(), page: 1, page_count: 3, ..Default::default() };
@@ -594,6 +596,7 @@ mod formcalc {
use crate::formcalc::run_formcalc;
use crate::xfa::*;
/// Run FormCalc `script` as `target`'s `activity` script on [`form`].
fn go(script: &str, target: &str, activity: &str) -> XfaOutcome {
let ev = XfaEvent { activity: activity.into(), target: target.into(), ..Default::default() };
let doc = XfaDoc { file_name: "f.pdf".into(), page: 1, page_count: 3, ..Default::default() };
@@ -1110,6 +1113,8 @@ mod session {
assert_eq!(s.dead(), None);
}
/// A JavaScript script past its time is abandoned within the deadline, and the session runs
/// nothing after it; a FormCalc one stops itself or is abandoned too.
#[test]
fn a_script_past_its_time_is_abandoned_and_the_session_is_dead_after_it() {
let mut s = XfaSession::new(XfaDoc::default());
@@ -1137,6 +1142,8 @@ mod runtime_highlight {
use super::*;
use crate::xfa::{XfaDoc, XfaEffect, XfaEvent, XfaNode, run_xfa};
/// `app.runtimeHighlight` in AcroForm scripts reads the viewer's setting, and setting it asks
/// for the change once and reads back the new value.
#[test]
fn app_runtime_highlight_reads_the_viewers_setting_and_asks_to_change_it() {
let ev = Event::field("Calculate", "total", "");
@@ -1149,6 +1156,8 @@ mod runtime_highlight {
assert_eq!(o.requests, vec![Request::Highlight(true)]);
}
/// The same in XFA scripts, where the change is an effect; nothing is asked for when the
/// setting is already what the script wants.
#[test]
fn xfa_app_runtime_highlight_reads_the_setting_and_records_a_change() {
let ev = XfaEvent { activity: "layoutReady".into(), target: "form1[0]".into(), ..Default::default() };
+2
View File
@@ -1118,6 +1118,8 @@ fn xfa_resolve(ctx: &mut Context, many: bool) -> JsResult<JsValue> {
resolver(ctx, current, many)
}
/// The XFA object model as globals for one script: `xfa` (form, host, layout, event), `event`
/// (the same object as `xfa.event`), `this` as node `current`, `app`, `console` and `util`.
fn install(ctx: &mut Context, event: &XfaEvent, doc: &XfaDoc, current: usize) -> JsResult<()> {
let rw = Attribute::CONFIGURABLE;
let form = node_object(ctx, 0)?;
+7
View File
@@ -1150,6 +1150,8 @@ impl PdfCraftApp {
self.try_open(name, path, std::sync::Arc::new(bytes), None, activate)
}
/// Hand `request` to the background open worker (started on first use); the result arrives
/// later as a pending open, under the returned token.
#[cfg(not(target_arch = "wasm32"))]
fn schedule_open(&mut self, request: OpenRequest) -> Result<u64, String> {
if self.open_worker.is_none() {
@@ -1275,6 +1277,8 @@ impl PdfCraftApp {
}
}
/// Open `bytes` on this thread: ask for a password if the document needs one, else add it
/// as a tab (in front when `activate`).
fn try_open(
&mut self,
name: &str,
@@ -1312,6 +1316,8 @@ impl PdfCraftApp {
self.finish_open(name, path, bytes.len(), prepared, activate).map(|_| ())
}
/// Add a prepared document as a tab: its view, the recent-files entry, and what its scripts
/// said while it opened (at once in front, or when a background tab is first selected).
fn finish_open(
&mut self,
name: &str,
@@ -3123,6 +3129,7 @@ impl eframe::App for PdfCraftApp {
self.process_picked();
}
/// One frame of the whole window.
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
let ctx = ui.ctx().clone();
i18n::set_current(i18n::Lang::from_pref(&self.language));
+2
View File
@@ -2068,6 +2068,8 @@ fn som_indices_count_earlier_same_named_siblings() {
assert_eq!((0..=children.len()).map(|i| sibs.at(i)).collect::<Vec<_>>(), [0, 0, 1, 0, 2, 1, 0]);
}
/// `ready` is two events: `ref="$layout"` is layout:ready (`layoutReady`), anything else stays
/// form:ready (`ready`), in the template and in the live form; page numbering is recognized.
#[test]
fn a_layout_ready_event_is_told_apart_from_form_ready() {
let (tpl, _) = parse(&crate::fixtures::layout_ready_template()).unwrap();