Interaktivní běhové prostředí dynamických widgetů XFA

TXFAWidgetRuntime poskytuje neutrální interakční model pro dynamické formuláře XFA, aniž by je převáděl na pole AcroForm nebo ploštil jejich obsah

Běhové prostředí vystavuje deterministické meze a stav widgetů, takže desktopová aplikace, služba nebo vlastní vykreslovač může dodat vlastní vstup, malování, přístupnost a smyčku událostí

Vytvoření běhového prostředí

Běhové prostředí vytvoříte přímo z bajtů XDP nebo zavoláním THotPDF.CreateLoadedXFAWidgetRuntime po načtení PDF, jehož AcroForm obsahuje záznam /XFA s jediným streamem nebo polem paketů

var
  Runtime: TXFAWidgetRuntime;
  State: TXFAWidgetState;
begin
  Runtime := PDF.CreateLoadedXFAWidgetRuntime;
  try
    if (Runtime <> nil) and (Runtime.WidgetCount > 0) then
    begin
      State := Runtime.Widgets[0];
      Runtime.FocusWidget(State.ID);
      Runtime.BeginEdit(State.ID);
      Runtime.ReplaceSelection(0, Length(State.Value), 'Updated value');
      if not Runtime.CommitEdit then
        raise Exception.Create(Runtime.LastDiagnostic);
    end;
  finally
    Runtime.Free;
  end;
end;

Továrna pro načtený dokument je jen pro čtení vůči grafu objektů PDF a stávající XFAFlattenWarnings; uložení dokumentu zachová jeho původní záznamy /XFA a /NeedsRendering

Interakční model

Interaktivní commity synchronizují stávající nativní skalární hodnoty v skrytých a neviditelných aliasech, včetně skutečných opakovaných datových scopů a rollbacku přesně po bajtech

Atomická validace a výpočet

Commit vyřeší explicitní vazby SOM a aktuální kontext dat opakovaného řádku před spuštěním skriptů validate a calculate

Editovaná hodnota, vypočtené hodnoty, datové uzly, model widgetu, stav fokusu a editace, varování a počítadla průchodů se publikují společně teprve poté, co se stabilizuje validace a rozložení

Odmítnuté skripty, vyčerpané rozpočty, neplatné hranice výběru v UTF-16 a výjimky rozložení nebo měření hostitele obnoví kompletní předchozí stav a nastaví LastDiagnostic

Rozpočty

TXFAWidgetRuntimeOptions omezuje počet widgetů, délku editované hodnoty, průchody výpočtu, průchody přerozdělení, operace rozložení, operace skriptů, uplynulý čas skriptů a další zdroje FormCalc nebo JavaScript

Limit widgetů se uplatňuje při připojování rozložení a fragmentů stránkování, zatímco načítaná dekomprese XFA a sestavení paketů končí na limitu vstupu XFA DOM ještě před parsováním

MaxLayoutOperations má výchozí hodnotu 200000 a omezuje jak průchod dokumentem, tak práci rozložení; hloubka rozložení je omezena na 128, hloubka cíle události a inicializace instancí na 64 a rekurzivní dispatch událostí se odmítne

Omezené dynamické události

DispatchEvent přijímá středníkem oddělené literální operace v odpovídajících event skriptech pole s typem obsahu FormCalc nebo JavaScript; tyto operace se parsují přímo a nevyžadují JavaScript DLL

row.instanceManager.addInstance(true);
row.instanceManager.removeInstance(0);
target.presence = "hidden";

addInstance přidá jednu instanci a jako merge argument přijímá true, false, 1 nebo 0; vynechaný argument znamená true a zkrácený zápis _row.addInstance(1) se také přijímá

Podporovaný model sváže každou existující datovou skupinu stejného jména, takže nová instance dostane novou datovou skupinu inicializovanou z defaultů šablony pro kterýkoli merge argument; vytvoření instance neklonuje zadané hodnoty předchozího řádku

removeInstance používá celočíselný index od nuly mezi datovými skupinami stejného jména vybraného subformu; subform musí mít element occur s opakovatelným maximem a obě operace vynucují jeho minimum i maximum, včetně max="-1"

Mutace instancí vyžaduje implicitní pojmenovanou vazbu datasetu a ASCII názvy XML dat; explicitní vazba přes data-reference a nejednoznačné rodičovské kontexty se odmítnou před publikováním transakce

Cíle se řeší přes pojmenované potomky šablony v obklopujících scopech události, včetně tečkových cest a this.parent; manager vnořený do opakovaného scope použije vlastní datovou skupinu události

presence přijímá visible, hidden a invisible na polích šablony, draw, subformech a exclusion grupách; skrytý obsah nezabírá místo v toku, zatímco invisible obsah si své místo nechá a vynechá se z widgetů i z flatten výstupu

Změny presence se vztahují na vybraný uzel šablony, a tedy na všechny jeho opakované výskyty; indexovaná presence na úrovni jednotlivých instancí, inactive, libovolné výrazy, proměnné, podmínky, smyčky a další operace event skriptů se odmítnou

Dávka událostí publikuje změny dat, výpočty, rozložení, fokus i stav editace společně po stabilizaci přerozdělení; jakákoli odmítnutá operace nebo vyčerpaný budget vstupu, operací, instancí, hodnot, widgetů, rozložení či času obnoví kompletní předchozí stav dokumentu i interakce

Odstranění řádku zachová fokus a rozpracované editace pro přeživší datové skupiny, i když se změní indexy jejich widgetů; odstranění nebo skrytí fokusovaného widgetu vymaže fokus a po úspěchu publikuje odpovídající fokus callback

Obecné vykonávání událostí JavaScript a FormCalc

Nastavte TXFAWidgetRuntimeOptions.ScriptOptions.EnableJavaScript, abyste povolili dodávaný ohraničený QuickJS bridge pro vykonávání událostí; JavaScriptové události pak podporují funkce, closures, pole, podmínky, smyčky a výjimky místo defaultní literální gramatiky

Options := TXFAWidgetRuntimeOptions.Default;
Options.ScriptOptions.EnableJavaScript := True;
Runtime := TXFAWidgetRuntime.Create(XDPBytes, 595, 842, Options);

Event host zpřístupňuje this, obklopující pojmenovaná pole a subformy, parent, zapisovatelné rawValue, presence a access, instanceManager.count/min/max, addInstance, removeInstance, insertInstance, moveInstance a setInstances, xfa.resolveNode, xfa.resolveNodes, resolution na úrovni uzlů a xfa.layout.relayout

Seznamy uzlů podporují číselné indexování, length a item; hodnoty opakovaných polí si zachovávají vlastní dataset cíle a SOM path přijímají pojmenované potomky s číselnými nebo wildcard indexy pro živé host uzly

const values = xfa.resolveNodes("main.row[*].amount[*]");
let total = 0;
for (const field of values) total += Number(field.rawValue);
xfa.resolveNode("main.total").rawValue = total;
if (total > 100) this.parent.warning.presence = "visible";

Každý opakovaný subform má vlastní živý objekt a potomní pole; index, parent child gettery i následné SOM dotazy následují operace insert, move a remove bezprostředně uvnitř skriptu

addInstance a insertInstance vrátí živý subtree inicializovaný z defaultů šablony, takže skript může zapsat hodnoty polí dřív, než událost publikuje; odstraněné handly odmítnou další čtení i zápisy

Změny presence a access obecných skriptů přetrvávají ve standardním paketu XFA form na výskyt, zatímco hodnoty polí a operace opakování přetrvávají v datasets; insert, move a remove udržují odpovídající form stav v souladu s datovými skupinami

Se stejným opt-in se FormCalc event skripty kompilují do ohraničeného engine a podporují var, if/elseif/else, for s upto nebo downto, while, foreach, func s implicitními výsledky, aritmetiku a porovnávání, konkatenaci řetězců, agregaci wildcard uzlů a implicitní přiřazování hodnot polí

Knihovna event funkcí zahrnuje Sum, Count, Avg, Min, Max, Round, běžné matematické funkce, krájení řetězců, konverzi velikosti písmen, trim, náhradu, HasValue, Exists, Within, Oneof a Choose; názvy vestavěných funkcí nerozlišují velikost písmen, At(source, search) dodržuje pořadí argumentů XFA včetně chování prázdného hledání, finanční funkce dodržují pořadí parametrů XFA a katalogy dat i financí popisuje Funkce FormCalc

Mutace skriptů se zaznamenávají uvnitř engine, validují a přehrávají uvnitř runtime transakce; výjimky, přerušení, neplatné Unicode, neplatné host operace a vyčerpané budgety nepublikují žádné částečné změny dokumentu

Obecné vykonávání skriptů zůstává defaultně vypnuté, nepoužívá žádný prohlížeč ani externí proces a nezpřístupňuje žádná API souborového systému, sítě ani aplikace; volající místo bridge může dodávat JavaScriptEvaluator

Perzistentní script objekty

JavaScriptové script objekty uvnitř elementu variables subformu zpřístupňují své proměnné a funkce přes název skriptu; lexikální proměnné, stav objektů a vnořené closures zůstávají živé po dobu runtime session, se zachováním běžného lexikálního stínění a direktiv strict

<variables>
  <script name="Helpers" contentType="application/x-javascript"><![CDATA[
    let count = 0;
    const nextPrivate = (() => { let value = 0; return () => ++value; })();
    function next() { return ++count + ":" + nextPrivate(); }
  ]]></script>
</variables>

Eventový kód může volat Helpers.next(); opakované výskyty subformu vlastní nezávislé script objekty a funkce řeší pojmenovaná pole proti aktuálnímu živému form kontextu

Zachycené field uzly a managery sledují stabilní datovou identitu přes přesuny i publikaci nově vytvořených instancí; přístup k odstraněnému uzlu odmítne událost a vrátí zpět stav jejího modulu

Obecné calculate a validate skripty sdílejí session i script objekty; JavaScript podporuje implicitní completion hodnoty a explicitní return, zatímco FormCalc vrací svůj finální výraz

Neúspěšné transakce obnoví lexikální stav a stav closures přehráním commitnutého virtuálního journalu, se zaznamenanými vstupy času a náhody; replay i aktuální vykonávání sdílejí deadline transakce a defaultní limity journalu jsou 64 MiB skriptů/výsledků a 8192 položek

Stav script objektů žije v runtime session a po XDP reloadu se inicializuje znovu; standardní hodnoty dokumentu a form override dál přetrvávají přes SaveToBytes

Custom callbacky JavaScriptEvaluator zachovávají stávající nativní obálku calculate/validate; perzistentní session dodává dodávaný engine

Konfigurace explicitního host transportu

Nastavte HostTransport a volitelné OnHostTransactionCompleted v TXFAWidgetRuntimeOptions, abyste vykonávali hostovské dialogy, tisk, navigaci, submission a přenos dat přes callbacky aplikace

Explicitní XFA Host Transport dodává xfa.host.messageBox, response, beep, print, gotoURL, submitForm, importData, exportData a FormCalc Get, Post a Put; aplikace vrací typované výsledky a řídí externí efekty

Retry i session replay používají zaznamenané odpovědi, takže callbacky se vykonají jednou na odeslaný požadavek; dokončení selháním dovolí aplikaci odhodlat odložené efekty nebo kompenzovat reverzibilní operace

Kladné HostTransportLimits ohraničují počet požadavků, počet argumentů a agregované bajty požadavků/odpovědí přes celou obklopující runtime transakci

Vykonávání locale a pictures

Obecné FormCalc eventy i calculate a validate skripty podporují funkce locale a pictures, včetně Format, Parse, lokalizovaných konverzí data/času, jednotek, encoding, UUID a anglických číslových slov

Dynamický FormCalc Eval provádí dynamicky dodané výpočty s izolovanými proměnnými a funkcemi, relativním přístupem k polím, nativní kompilací, zaznamenanými odpověďmi a transakčním rollbackem

Explicitní FormCalc reference podporují write-through přiřazování, rebind, odpojení null, argumenty funkcí a stabilní handly udržované script objekty přes přesuny opakovaných instancí

Živé SOM path podporují odvozené, absolutní a relativní indexy výskytů, class a descendant selektory, průhledné kontejnery, candidate predikáty a přímé FormCalc indexované přiřazování

Nativní Data DOM zpřístupňuje datasety přes $data a $record, okamžitě synchronizuje vázané čtení a zápis formuláře, zrcadlí opakované instance a zachovává udržované datové reference přes nativní publikaci identity

Nativní Property DOM zpřístupňuje deklarované potomky value, font, UI a dalších vlastností, synchronizuje typované hodnoty polí a perzistuje atributy na výskyt používané měřením písem a podporovaným flatten stylingem

Prováděný uzel dědí svůj nejbližší atribut locale; položky localeSet dokumentu přebíjejí systémové symboly a vzory, zatímco vypočtené názvy locale se řeší přes ohraničené interní požadavky a zachovávají se v session journalu

Num2Date bez picture nyní používá ambient defaultní vzor data; když je vyžadován ISO výstup, zadejte YYYY-MM-DD explicitně

Stateful host model

XFA Host Model dodává metadata aplikace, skutečný počet stránek, navigaci stránek, Unicode název, příznaky calculation/validation, scopovaný reset a fokus pole s transakčním lifecycle enter/exit

TXFAWidgetRuntimeOptions.HostModel konfiguruje počáteční stav aplikace; TXFAWidgetRuntime.HostModel vrací aktuální stav a neúspěšné eventy jej obnoví spolu se snapshoty dokumentu a interakce

Přesun fokusu bez enter/exit skriptu, rozpracované editace nebo inicializovaného lifecycle změní fokus bez zahájení skriptových výpočtů ani zpracování deadline; skriptovaný fokus a commity rozpracovaných editací i nadále používají transakční budgety, validaci a přepočet

Pokročilé picture klauzule se provádějí stejnými runtime transakcemi, journalem locale retry i calculation lifecycle, s ohraničeným compound parsingem

Inicializace a údržba lifecycle

Zavolejte InitializeForm po nakonfigurování runtime a callbacků, aby se vykonaly initialize eventy v pořadí šablony, poté calculate a validate, form-ready eventy a layout-ready eventy; po úspěchu je volání idempotentní

Nové instance vytvořené inicializací nebo ready eventy dostanou vlastní initialize eventy před svými ready handlery; vykonání layout-ready se opakuje jen při změně rozložení, v rámci budgetů přerozdělení a transakce

Po inicializaci inicializují úspěšný dispatch události i commit editace nově vytvořené instance a vykonávají calculate, validate a layout-ready; stávající výskyty zachovávají svůj inicializační stav přes přesuny i rollback transakce

Selhání lifecycle vrátí zpět bajty dokumentu, interakci widgetů i účetnictví inicializace společně a callbacky se publikují až po úspěchu obklopující transakce

Uložení aktualizovaného formuláře

SaveToBytes vrátí kompletní aktualizované XDP běhového prostředí, včetně upravených datasetů a atributů presence v šabloně; tyto bajty použijte s SetXFADocument při zápisu PDF nebo s HPDFXFAFlatten pro aktualizovaný flatten výstup

Továrna pro načtený dokument vytváří nezávislé běhové prostředí, takže události runtime automaticky nemodifikují objektový graf zdrojového PDF

Volitelný profil prezentace instancí

Dynamic XFA Instance Presentation přidává přes samostatný helper explicitní opakované vazby, stabilní ID na instanci, indexovanou presence a access, ohraničené podmíněné eventy, malování na host canvas a přístupnost; defaultní runtime i jeho omezená event gramatika zůstávají kompatibilní

UpdateDocument poskytuje transakční akce dokumentu; volitelné callbacky runtime vlastnosti, binding scope, identity, zahájení resolution a validace dokumentu podporují helper, zatímco nil defaulty zachovávají stávající volající

Nízkourovňové event a form API

HPDFXFACompileFormCalcEvent kompiluje syntax událostí; HPDFXFAExecuteJavaScriptEvent provádí virtuální kontext popsaný TXFAEventBinding a TXFAEventBindings

TXFAJavaScriptSession dodává perzistentní vykonávání a ohraničené checkpointy pro nižší úrovně volajících

Vrácené hodnoty TXFAEventAction používají TXFAEventActionKind; transakční replay dodává runtime

HPDFXFAResolveFormInstanceNode a HPDFXFAResolveFormInstanceProperty poskytují ohraničené vyhledávání ve standardním form paketu

Aktuální hranice

Běhové prostředí je jednovláknový hostitelský objekt; GUI a malování zůstávají odpovědností hostitele nebo volitelného presentation helperu

Podporovaný hostitelský stav, živý form DOM a lifecycle zatím nepokrývají každou vlastnost hosta Acrobat, alternativní éry a lokalizované digit pictures, synchronní dynamické dotazy přerozdělení ani každý SOM operátor

Viz Ohraničené FormCalc a JavaScript XFA, DOM paketů XFA a Interaktivní zpracování dokumentů