Interaktive dynamische XFA-Widget-Laufzeit

TXFAWidgetRuntime bietet ein hostneutrales Interaktionsmodell für dynamische XFA-Formulare, ohne sie in AcroForm-Felder umzuwandeln oder ihren Inhalt zu flachen

Die Laufzeit legt deterministische Widget-Grenzen und -Zustände offen, sodass ein Desktop-, Dienst- oder benutzerdefinierter Renderer seine eigene Eingabe, sein eigenes Zeichnen, seine Barrierefreiheit und seine Ereignisschleife bereitstellen kann

Eine Laufzeit erstellen

Erstellen Sie die Laufzeit direkt aus XDP-Bytes oder rufen Sie THotPDF.CreateLoadedXFAWidgetRuntime nach dem Laden eines PDF auf, dessen AcroForm einen Einzelstrom- oder Paket-Array-/XFA-Eintrag enthält

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;

Die Factory für geladene Dokumente ist hinsichtlich des PDF-Objektgraphen und vorhandener XFAFlattenWarnings schreibgeschützt; das Speichern des Dokuments behält seine ursprünglichen Einträge /XFA und /NeedsRendering bei

Interaktionsmodell

Interaktive Commits synchronisieren vorhandene native Scalar-Werte in versteckten und unsichtbaren Aliases, einschließlich tatsächlicher wiederholter Daten-Scopes und byte-exakten Rollbacks

Atomare Validierung und Berechnung

Ein Commit löst explizite SOM-Bindungen und den aktuellen Datenkontext der wiederholten Zeile auf, bevor Validierungs- und Berechnungsskripte ausgeführt werden

Der bearbeitete Wert, berechnete Werte, Datenknoten, das Widgetmodell, Fokus- und Bearbeitungszustand, Warnungen und Durchlaufzähler werden gemeinsam veröffentlicht, sobald sich Validierung und Layout stabilisieren

Abgelehnte Skripte, erschöpfte Budgets, ungültige UTF-16-Auswahlgrenzen und Layout- oder Host-Mess-Ausnahmen stellen den vollständigen vorherigen Zustand wieder her und setzen LastDiagnostic

Budgets

TXFAWidgetRuntimeOptions begrenzt die Widget-Anzahl, die Länge des bearbeiteten Werts, die Anzahl der Berechnungsläufe, die Reflow-Läufe, die Layoutoperationen, die Skriptoperationen, die verstrichene Skriptzeit und andere FormCalc- oder JavaScript-Ressourcen

Das Widget-Limit gilt, während Layout-Elemente und Paginierungsfragmente angehängt werden, während geladene XFA-Dekompression und Paketassemblierung am Eingabelimit des XFA-DOM vor dem Parsen stoppen

MaxLayoutOperations steht standardmäßig auf 200000 und begrenzt sowohl den Dokumentdurchlauf als auch die Layoutarbeit; die Layouttiefe ist auf 128 begrenzt, die Tiefe von Ereignisziel und Instanzinitialisierung auf 64, und rekursives Ereignisdispatching wird abgelehnt

Default-literale dynamische Ereignisse

DispatchEvent akzeptiert semikolongetrennte literale Operationen in passenden Feld-Ereignisskripten mit FormCalc- oder JavaScript-Content-Types; diese Operationen werden direkt geparst und brauchen keine JavaScript-DLL

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

addInstance hängt eine Instanz an und akzeptiert true, false, 1 oder 0 als Merge-Argument; ein weggelassenes Argument verwendet true, und die Kurzform _row.addInstance(1) wird ebenfalls akzeptiert

Das unterstützte Modell bindet jede vorhandene Datengruppe desselben Namens, sodass eine neue Instanz eine neue Datengruppe erhält, die aus den Template-Standards initialisiert wird, egal welches Merge-Argument; das Erzeugen einer Instanz klont nicht die eingegebenen Werte der vorherigen Zeile

removeInstance verwendet einen nullbasierten Integer-Index unter den gleichnamigen Datengruppen des gewählten Subforms; das Subform muss ein occur-Element mit wiederholbarem Maximum haben, und beide Operationen erzwingen dessen Minimum und Maximum, einschließlich max="-1"

Instanzmutationen verlangen implizite benannte Dataset-Bindung und ASCII-XML-Datennamen; explizite Data-Reference-Bindung und mehrdeutige Elternkontexte werden abgelehnt, bevor die Transaktion veröffentlicht wird

Ziele werden über benannte Template-Kinder in den umschließenden Scopes des Ereignisses aufgelöst, einschließlich gepunkteter Pfade und this.parent; ein Manager, der in einem wiederholten Scope verschachtelt ist, verwendet die eigene Datengruppe des Ereignisses

presence akzeptiert visible, hidden und invisible an Template-Feldern, Draws, Subforms und Exclusion-Groups; versteckter Inhalt belegt keinen Flussplatz, während unsichtbarer Inhalt seinen Platz behält und aus Widgets und Flatten-Ausgabe weggelassen wird

Beim Default-Literalparser greifen Presence-Änderungen am gewählten Template-Knoten und damit an allen seinen wiederholten Vorkommen; indizierte Presence je Instanz, inactive, beliebige Ausdrücke, Variablen, Conditionals, Schleifen und andere Ereignisskript-Operationen brauchen einen zusätzlichen Event-Host

Ein Ereignis-Batch veröffentlicht Datenänderungen, Berechnungen, Layout, Fokus und Bearbeitungszustand gemeinsam, nachdem sich der Reflow stabilisiert hat; jede abgelehnte Operation oder jedes erschöpfte Input-, Operations-, Instanz-, Wert-, Widget-, Layout- oder Zeitbudget stellt den vollständigen vorherigen Dokument- und Interaktionszustand wieder her

Beim Entfernen einer Zeile bleiben Fokus und ausstehende Bearbeitungen für überlebende Datengruppen erhalten, selbst wenn sich ihre Widget-Indizes ändern; das Entfernen oder Verbergen des fokussierten Widgets räumt den Fokus und veröffentlicht nach Erfolg den entsprechenden Fokus-Callback

Allgemeine JavaScript- und FormCalc-Ereignisausführung

Setzen Sie TXFAWidgetRuntimeOptions.ScriptOptions.EnableJavaScript, um die mitgelieferte begrenzte QuickJS-Brücke für die Ereignisausführung zu aktivieren; JavaScript-Ereignisse unterstützen dann Funktionen, Closures, Arrays, Conditions, Schleifen und Exceptions statt der Default-Literalgrammatik

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

Der Event-Host legt this, umschließende benannte Felder und Subforms, parent, schreibbares rawValue, presence und access, instanceManager.count/min/max, addInstance, removeInstance, insertInstance, moveInstance und setInstances, xfa.resolveNode, xfa.resolveNodes, Knotenauflösung und xfa.layout.relayout offen

Knotenlisten unterstützen numerische Indizierung, length und item; wiederholte Feldwerte behalten ihre eigenen Dataset-Ziele, und SOM-Pfade akzeptieren benannte Kinder mit numerischen oder Wildcard-Indizes für live Host-Knoten

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";

Jedes wiederholte Subform hat sein eigenes Live-Objekt und seine Kinderfelder; index, Eltern-Child-Getter und nachfolgende SOM-Abfragen folgen Insert-, Move- und Remove-Operationen unmittelbar innerhalb des Skripts

addInstance und insertInstance geben einen Live-Teilbaum zurück, der aus Template-Defaults initialisiert ist, sodass das Skript seine Feldwerte schreiben kann, bevor das Ereignis veröffentlicht; entfernte Handles weisen weitere Lese- oder Schreibzugriffe zurück

Allgemeine Skript-Presence- und Access-Änderungen halten im Standard-form-Paket je Vorkommen, während Feldwerte und Repeat-Operationen in datasets halten; Insert, Move und Remove halten den zugehörigen Form-Zustand mit den Datengruppen synchron

Mit demselben Opt-in kompilieren FormCalc-Ereignisskripte zur begrenzten Engine und unterstützen var, if/elseif/else, for mit upto oder downto, while, foreach, func mit impliziten Ergebnissen, Arithmetik und Vergleiche, String-Verkettung, Wildcard-Knotenaggregation und implizite Feldwertzuweisung

Die Ereignisfunktionsbibliothek umfasst Sum, Count, Avg, Min, Max, Round, gängige Mathematikfunktionen, String-Slicing, Groß-/Kleinwandlung, Trimmen, Ersetzung, HasValue, Exists, Within, Oneof und Choose; eingebaute Namen sind case-insensitiv, At(source, search) folgt der XFA-Argumentordnung einschließlich des Verhaltens bei leerer Suche, Finanzfunktionen folgen der XFA-Parameterordnung, und der Datums- und Finanzkatalog ist in FormCalc Functions beschrieben

Skriptmutationen werden innerhalb der Engine aufgezeichnet, validiert und innerhalb der Laufzeit-Transaktion wiedergegeben; Exceptions, Unterbrechung, ungültiges Unicode, ungültige Host-Operationen und erschöpfte Budgets veröffentlichen keine partiellen Dokumentänderungen

Die allgemeine Skriptausführung bleibt standardmäßig aus, nutzt keinen Browser oder externen Prozess und legt keine Dateisystem-, Netz- oder Anwendungs-APIs offen; der Aufrufer kann stattdessen JavaScriptEvaluator liefern

Persistente Skriptobjekte

JavaScript-script-Objekte innerhalb des variables-Elements eines Subforms legen ihre Variablen und Funktionen über den Skriptnamen offen; lexikalische Variablen, Objektzustand und verschachtelte Closures bleiben für die Laufzeitsitzung am Leben, mit normaler lexikalischer Verschattung und erhaltenen Strict-Direktiven

<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>

Ereigniscode kann Helpers.next() aufrufen; wiederholte Subform-Vorkommen besitzen unabhängige Skriptobjekte, und Funktionen lösen benannte Felder gegen den aktuellen Live-Form-Kontext auf

Erfasste Feldknoten und Manager folgen der stabilen Datenidentität über Moves und die Veröffentlichung neu erzeugter Instanzen hinweg; der Zugriff auf einen entfernten Knoten weist das Ereignis zurück und rollt seinen Modulzustand zurück

Allgemeine Calculate- und Validate-Skripte teilen sich Sitzung und Skriptobjekte; JavaScript unterstützt implizite Completion-Werte und explizites return, während FormCalc seinen letzten Ausdruck zurückgibt

Fehlgeschlagene Transaktionen stellen den lexikalischen und Closure-Zustand wieder her, indem sie das committete virtuelle Journal mit aufgezeichneter Zeit und Zufallseingaben wiedergeben; Replay und aktuelle Ausführung teilen sich die Transaktionsfrist, und die Default-Journal-Limits liegen bei 64 MiB Skripten/Ergebnissen und 8192 Einträgen

Skriptobjektzustand lebt in der Laufzeitsitzung und wird nach dem Neuladen des XDP erneut initialisiert; Standard-Dokumentwerte und Form-Overrides halten über SaveToBytes weiterhin persistent

Eigene JavaScriptEvaluator-Callbacks behalten die vorhandene native Calculate/Validate-Hülle; die persistente Sitzung liefert die mitgelieferte Engine

Expliziten Host-Transport konfigurieren

Setzen Sie HostTransport und optional OnHostTransactionCompleted in TXFAWidgetRuntimeOptions, um Host-Dialoge, Drucken, Navigation, Submission und Datenübertragung über Anwendungs-Callbacks auszuführen

Expliziter XFA-Host-Transport stellt xfa.host.messageBox, response, beep, print, gotoURL, submitForm, importData, exportData sowie FormCalc Get, Post und Put bereit; die Anwendung liefert typisierte Ergebnisse und steuert externe Effekte

Wiederholungen und Session-Replay verwenden aufgezeichnete Antworten, sodass Callbacks je ausgelieferte Anfrage genau einmal laufen; das Fehler-Abschluss lässt die Anwendung gestagete Effekte verwerfen oder reversible Operationen kompensieren

Positive HostTransportLimits begrenzen Anfrageanzahl, Argumentanzahl und aggregierte Anfrage-/Antwort-Bytes über die umschließende Laufzeit-Transaktion

Locale- und Picture-Ausführung

Allgemeine FormCalc-Ereignisse sowie Calculate- und Validate-Skripte unterstützen Locale- und Picture-Funktionen, einschließlich Format, Parse, lokalisierter Datum/Zeit-Konvertierungen, Einheiten, Encoding, UUIDs und englischer Zahlenwörter

Dynamisches FormCalc Eval führt dynamisch gelieferte Berechnungen mit isolierten Variablen und Funktionen, relativem Feldzugriff, nativer Kompilierung, aufgezeichneten Antworten und transaktionalem Rollback aus

Explizite FormCalc-Referenzen unterstützen Write-Through-Zuweisung, Rebind, Null-Ablösung, Funktionsargumente und stabile Handles, die Skriptobjekte über Instanzbewegungen hinweg halten

Live-SOM-Pfade unterstützen abgeleitete, absolute und relative Vorkommensindizes, Klassen- und Nachfahren-Selektoren, transparente Container, Kandidaten-Prädikate und direkte FormCalc-Indexzuweisung

Das native Data-DOM legt Datasets über $data und $record offen, synchronisiert gebundene Form-Lese- und Schreibzugriffe sofort, spiegelt wiederholte Instanzen und bewahrt gehaltene Datenreferenzen über native Identitätsveröffentlichung

Das native Property-DOM legt deklarierte Value-, Font-, UI- und weitere Property-Kinder offen, synchronisiert typisierte Feldwerte und hält Per-Instanz-Attribute persistent, die Font-Messung und unterstütztes Flatten-Styling nutzen

Der ausführende Knoten erbt sein nächstgelegenes Locale-Attribut; LocaleSet-Einträge des Dokuments überschreiben System-Symbole und -Patterns, während berechnete Locale-Namen über begrenzte interne Anfragen aufgelöst und im Session-Journal bewahrt werden

Num2Date ohne Picture verwendet jetzt das umgebende Default-Datums-Pattern; liefern Sie YYYY-MM-DD explizit, wenn ISO-Ausgabe gebraucht wird

Zustandsbehaftetes Host-Modell

XFA-Host-Modell stellt Anwendungsmetadaten, tatsächliche Seitenzahl, Seitennavigation, Unicode-Titel, Berechnungs-/Validierungs-Flags, bereichsbezogenes Zurücksetzen und Feldfokus mit transaktionalem Enter/Exit-Lebenszyklus bereit

TXFAWidgetRuntimeOptions.HostModel konfiguriert den initialen Anwendungszustand; TXFAWidgetRuntime.HostModel liefert den aktuellen Zustand, und fehlgeschlagene Ereignisse stellen ihn zusammen mit Dokument- und Interaktions-Snapshots wieder her

Ein Fokuswechsel ohne Enter/Exit-Skript, ausstehende Bearbeitung oder initialisierten Lebenszyklus ändert den Fokus, ohne Skriptberechnung oder Fristverarbeitung zu starten; Skript-Fokus und Commits ausstehender Bearbeitungen nutzen weiterhin transaktionale Budgets, Validierung und Neuberechnung

Erweiterte Picture-Klauseln laufen über dieselben Laufzeit-Transaktionen, das Locale-Retry-Journal und den Berechnungslebenszyklus, mit begrenztem Compound-Parsing

Lebenszyklus initialisieren und pflegen

Rufen Sie InitializeForm nach dem Konfigurieren von Laufzeit und Callbacks auf, um Initialize-Ereignisse in Template-Reihenfolge auszuführen, dann Calculate und Validate, Form-Ready-Ereignisse und Layout-Ready-Ereignisse; der Aufruf ist nach Erfolg idempotent

Neue Instanzen aus Initialisierung oder Ready-Ereignissen erhalten ihre eigenen Initialize-Ereignisse vor ihren Ready-Handlern; die Layout-Ready-Ausführung wiederholt sich nur bei Layoutänderungen, innerhalb der Reflow- und Transaktionsbudgets

Nach der Initialisierung initialisieren erfolgreicher Ereignisdispatch und Edit-Commit neu erzeugte Instanzen und führen Calculate, Validate und Layout-Ready aus; vorhandene Vorkommen behalten ihren Initialisierungszustand über Moves und Transaktions-Rollback hinweg

Lebenszyklusfehler rollen Dokument-Bytes, Widget-Interaktion und Initialisierungs-Buchhaltung gemeinsam zurück, und Callbacks veröffentlichen erst nach Erfolg der umschließenden Transaktion

Aktualisiertes Formular speichern

SaveToBytes liefert das vollständige aktualisierte XDP der Laufzeit, einschließlich geänderter Datasets und Standard-Form-Zustand je Instanz; Presence-Änderungen des Literalparsers bleiben Template-Attribute; verwenden Sie diese Bytes mit SetXFADocument beim Schreiben eines PDF oder mit HPDFXFAFlatten für die aktualisierte Flatten-Ausgabe

Die Factory für geladene Dokumente erzeugt eine unabhängige Laufzeit, daher verändern Laufzeitereignisse nicht automatisch den Objektgraphen des Quell-PDF

Optionales Instanz-Präsentationsprofil

Dynamische XFA-Instanzpräsentation ergänzt über einen unabhängigen Helfer explizite wiederholte Bindungen, stabile Per-Instanz-IDs, indizierte Presence und Access, begrenzte konditionale Ereignisse, Host-Canvas-Zeichnung und Barrierefreiheit; die Default-Laufzeit und ihre eingeschränkte Ereignisgrammatik bleiben kompatibel

UpdateDocument stellt transaktionale Dokumentaktionen bereit; optionale Runtime-Property-, Binding-Scope-, Identity-, Resolution-Started- und Dokumentvalidierungs-Callbacks unterstützen den Helfer, während nil-Defaults bestehende Aufrufer unverändert lassen

Tieferliegende Ereignis- und Form-APIs

HPDFXFACompileFormCalcEvent kompiliert Ereignissyntax; HPDFXFAExecuteJavaScriptEvent führt den virtuellen Kontext aus, den TXFAEventBinding und TXFAEventBindings beschreiben

TXFAJavaScriptSession stellt tieferliegenden Aufrufern persistente Ausführung und begrenzte Checkpoints bereit

Zurückgegebene TXFAEventAction-Werte verwenden TXFAEventActionKind; das transaktionale Replay liefert die Laufzeit

HPDFXFAResolveFormInstanceNode und HPDFXFAResolveFormInstanceProperty bieten begrenzte Standard-Form-Paket-Suche

Aktuelle Grenzen

Die Laufzeit ist ein einthreadiges Hostobjekt; GUI und Zeichnen bleiben Aufgabe des Hosts oder des optionalen Präsentationshelfers

Der unterstützte Host-Zustand, das Live-Form-DOM und der Lebenszyklus decken noch nicht jede Acrobat-Host-Property, Picture-Klauseln anderer Ären und lokalisierter Ziffern, synchrone dynamische Reflow-Abfragen oder jeden SOM-Operator ab

Siehe Begrenztes XFA FormCalc und JavaScript, XFA-Paket-DOM und Interaktive Dokumentverarbeitung