有界 XFA FormCalc 與 JavaScript

HotPDF 在扁平化表單時會評估 XFA calculate 腳本:始終可用的有界 FormCalc 路徑,加上一條更完整的 QuickJS 路徑——後者在應用程式明確啟用之前保持停用

擴充 FormCalc

FormCalc 運算式支援算術、字串、布林、比較運算子、短路求值的 And、Or、Not,以及惰性求值的 If(condition, whenTrue, whenFalse) 分支

Sum、Avg、Min、Max 與 Count 接受純量與 SOM 節點集混用的參數,路徑可用根路徑、直接、索引、萬用字元或後代形式,例如 $record.rows[*].amount;只有 If 被選中的分支會求值,所以未用到的無效分支不會讓整個計算被拒

巢狀呼叫可以組合數值、字串與節點集結果,並確定性地支援 At、Choose、Concat、LTrim、RTrim、Str、Stuff、Null、Sign、Exp、Log、Sin、Cos、Tan、Deg2Rad、Rad2Deg、Within 與 Oneof

使用者自訂函式、迴圈、指派、地區設定 picture clause 與網路函式仍在原生子集之外,一律以失敗收場

InstanceAdd(name, count) 與 InstanceRemove(name, index) 會在通過參數與操作預算驗證後,才經由 OnXFAInstanceAction 分派

選用的 JavaScript

在 ApplyXFAAsAcroForm 或 FlattenLoadedXFA 之前把 THotPDF.XFAJavaScriptEnabled 設為 True,即可執行 contentType 指定 JavaScript 的腳本

這個執行環境支援一般的 JavaScript 控制流程與 Float64Array 之類的原生具型別陣列,但不會拿到任何檔案、行程、網路、瀏覽器或應用程式物件;fetch、XMLHttpRequest、WebSocket、require、process 與 Deno 一概不存在

var
  Budgets: THPDFXFAFormScriptBudgets;
begin
  Budgets := THPDFXFAFormScriptBudgets.Default;
  Budgets.MaxElapsedMilliseconds := 100;
  Budgets.JavaScriptMemoryBytes := 8 * 1024 * 1024;
  PDF.XFAFormScriptBudgets := Budgets;
  PDF.XFAJavaScriptEnabled := True;
  PDF.OnXFAInstanceAction := HandleXFAInstanceAction;
  PDF.ApplyXFAAsAcroForm(XDPBytes, False);
end;

腳本環境

JavaScript 會拿到可變的 this.rawValue、一個 event.value,以及凍結的 xfa facade

預算與遙測

THPDFXFAFormScriptBudgets 約束腳本位元組、FormCalc 操作數、經過時間、運算式深度、重複陣列項目、值位元組、執行個體操作、JavaScript 記憶體、JavaScript 堆疊用量與中斷檢查

堆疊預算構成遞迴邊界,時間與中斷預算則攔住不終止的迴圈;越過任何邊界的腳本一律以失敗收場,並把診斷訊息附加到 XFAFlattenWarnings

XFAFlattenScriptsEvaluated、XFAFlattenScriptsRejected 與 XFAFlattenInstanceOperations 回報最近一次扁平化流程

直接執行環境整合

擴充的 HPDFXFAFlatten 多載直接接受 TXFAFormScriptOptions 與 TXFAFormInstanceAction;指派 TXFAFormScriptOptions.JavaScriptEvaluator 即可轉接靜態 QuickJS 綁定或應用程式自有的其他評估器,同時保留同樣的包裹層與預算

另見 TXFAFormScriptOptions、TXFAFormScriptLimits、THPDFXFAFormScriptBudgets 與 THPDFXFAInstanceAction