pub trait XfaJsRuntime {
// Required methods
fn init(&mut self) -> Result<(), SandboxError>;
fn reset_for_new_document(&mut self) -> Result<(), SandboxError>;
fn execute_script(
&mut self,
activity: Option<&str>,
body: &str,
) -> Result<RuntimeOutcome, SandboxError>;
fn take_metadata(&mut self) -> RuntimeMetadata;
// Provided methods
fn set_form_handle(
&mut self,
_form: *mut FormTree,
_root_id: FormNodeId,
) -> Result<(), SandboxError> { ... }
fn set_data_handle(&mut self, _dom: *const DataDom) { ... }
fn set_declared_subform_names(&mut self, _names: HashSet<String>) { ... }
fn reset_per_script(
&mut self,
_current_id: FormNodeId,
_activity: Option<&str>,
) -> Result<(), SandboxError> { ... }
fn set_static_page_count(
&mut self,
_page_count: u32,
) -> Result<(), SandboxError> { ... }
fn set_presave_gate(&mut self, _enabled: bool) { ... }
fn take_occur_mutations(&mut self) -> Vec<(usize, String, i64)> { ... }
fn take_diag_logs(&mut self) -> RuntimeDiagLogs { ... }
}Expand description
The host-side adapter the dispatch path calls. A minimal contract chosen so that swapping backends (rquickjs ↔ boa ↔ external sandbox) is one Cargo feature flag away.
Required Methods§
Sourcefn init(&mut self) -> Result<(), SandboxError>
fn init(&mut self) -> Result<(), SandboxError>
One-time initialisation. Idempotent.
Sourcefn reset_for_new_document(&mut self) -> Result<(), SandboxError>
fn reset_for_new_document(&mut self) -> Result<(), SandboxError>
Reset per-document state (memory budget, instruction counter, any cached compiled scripts). Called once per flatten.
Sourcefn execute_script(
&mut self,
activity: Option<&str>,
body: &str,
) -> Result<RuntimeOutcome, SandboxError>
fn execute_script( &mut self, activity: Option<&str>, body: &str, ) -> Result<RuntimeOutcome, SandboxError>
Execute one script body inside the sandbox.
activity is the enclosing <event activity="..."> value if
any. The dispatch site has already filtered against
activity_allowed_for_sandbox; backends may treat unknown
activities as PhaseDenied for defence-in-depth.
Sourcefn take_metadata(&mut self) -> RuntimeMetadata
fn take_metadata(&mut self) -> RuntimeMetadata
Take the cumulative metadata since the last take_metadata
call (or since reset_for_new_document, whichever was later).
Provided Methods§
Sourcefn set_form_handle(
&mut self,
_form: *mut FormTree,
_root_id: FormNodeId,
) -> Result<(), SandboxError>
fn set_form_handle( &mut self, _form: *mut FormTree, _root_id: FormNodeId, ) -> Result<(), SandboxError>
Phase C: install the FormTree the runtime should resolve paths
against and mutate. The dispatch path owns the mutable borrow and clears
the handle before returning.
Sourcefn set_data_handle(&mut self, _dom: *const DataDom)
fn set_data_handle(&mut self, _dom: *const DataDom)
Phase D-γ: install a read-only view of the DataDom for the current
document. Called once per document after set_form_handle, before any
scripts run. Default: no-op (backends without DataDom support ignore it).
§Safety
Callers must guarantee that dom outlives all script execution for
this document (i.e. it must remain alive until set_form_handle(null)
is called). The runtime stores the pointer read-only and never writes
through it.
Sourcefn set_declared_subform_names(&mut self, _names: HashSet<String>)
fn set_declared_subform_names(&mut self, _names: HashSet<String>)
BE-1 tranche #1 (benign zero-instance SOM): install the set of
template-declared container names (subform/subformSet/exclGroup/
area) for the current document. Backends that resolve implicit SOM
identifiers use it to return a benign empty-node façade for a
declared-but-absent reference instead of undefined (Adobe semantics),
so guarded scripts (if (!Sub.Child.isNull) {...} else {...}) run their
else branch instead of throwing. Like set_data_handle, the caller
installs this before script execution. Default: no-op (the static
NullRuntime ignores it, so the default/non-sandboxed path is
unaffected and stays byte-identical).
Sourcefn reset_per_script(
&mut self,
_current_id: FormNodeId,
_activity: Option<&str>,
) -> Result<(), SandboxError>
fn reset_per_script( &mut self, _current_id: FormNodeId, _activity: Option<&str>, ) -> Result<(), SandboxError>
Phase C: reset per-script host counters and install the current script context node / activity. Backends without host bindings ignore it.
Sourcefn set_static_page_count(
&mut self,
_page_count: u32,
) -> Result<(), SandboxError>
fn set_static_page_count( &mut self, _page_count: u32, ) -> Result<(), SandboxError>
Phase C page-count foundation. The current flatten order runs scripts before layout, so callers normally leave this at 0.
Sourcefn set_presave_gate(&mut self, _enabled: bool)
fn set_presave_gate(&mut self, _enabled: bool)
D1.B gated allow. Inform the runtime whether the
XFA_PRESAVE_DURING_FLATTEN=1 opt-in is active for the current
flatten. The dispatch path computes this once per document via
presave_during_flatten_enabled and forwards it here so the host
binding layer can mirror the dispatch decision (defence-in-depth).
Default: no-op. Backends without a host-binding gate ignore it. The contract for backends that DO mirror the gate:
- Default OFF: every call to
HostBindings::write_activity_allowedwithcurrent_activity = Some("preSave")MUST return false. - Gate ON: the same call MUST return true ONLY for
Some("preSave"). Every other denylist activity (preSubmit,click, …) MUST continue to return false.
Cross-ref: docs/INST_MGR_ACTIVITY_POLICY.md v5 §6.1 (D1.B).
Sourcefn take_occur_mutations(&mut self) -> Vec<(usize, String, i64)>
fn take_occur_mutations(&mut self) -> Vec<(usize, String, i64)>
D6: drain captured occur.min/occur.max write intents
(node_index, prop, value) recorded during the script pass. The
dispatch path applies them (only when XFA_OCCUR_APPLY=1) after the
rollback decision. Default: none (non-sandboxed runtimes capture nothing).
Sourcefn take_diag_logs(&mut self) -> RuntimeDiagLogs
fn take_diag_logs(&mut self) -> RuntimeDiagLogs
Epic A E-2/E-3: drain verbose per-entry diagnostic logs. Only
populated when XFA_RUNTIME_DIAG=1 is set at the host call sites.
Default impl returns empty logs (NullRuntime, non-sandboxed paths).
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".