Interactieve dynamische XFA-widgetruntime
TXFAWidgetRuntime biedt een hostneutraal interactiemodel voor dynamische XFA-formulieren zonder ze om te zetten in AcroForm-velden of hun inhoud te flatten
De runtime stelt deterministische widgetgrenzen en -toestand bloot zodat een desktop-, service- of aangepaste renderer zijn eigen invoer, tekening, toegankelijkheid en eventloop kan leveren
Een runtime maken
Maak de runtime rechtstreeks uit XDP-bytes of roep THotPDF.CreateLoadedXFAWidgetRuntime aan na het laden van een PDF waarvan het AcroForm een entry voor een enkele stream of packet-array /XFA bevat
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;
De fabriek voor geladen documenten is alleen-lezen met betrekking tot het PDF-objectdiagram en bestaande XFAFlattenWarnings; het opslaan van het document behoudt de oorspronkelijke /XFA- en /NeedsRendering-entries
Interactiemodel
FocusWidgetenClearFocusonderhouden één gefocuste widget en publiceren geordende focuscallbacksBeginEdit,ReplaceSelection,CancelEditenCommitEditbehouden Unicode-tekst inclusief kop- en staartspatiesHitTestwijst paginacoördinaten toe aan de bovenste zichtbare widgetOnWidgetInvalidated,OnLayoutChangedenOnFocusChangedlaten de host alleen de beïnvloede toestand verversen
Interactieve commits synchroniseren bestaande native scalairwaarden in verborgen en onzichtbare aliassen, inclusief echte herhaalde data-scopes en byte-exacte rollback
Atomaire validatie en berekening
Een commit lost expliciete SOM-bindingen en de gegevenscontext van de huidige herhaalde rij op vóór het uitvoeren van validate- en calculate-scripts
De bewerkte waarde, berekende waarden, gegevensknooppunten, widgetmodel, focus- en bewerkingstoestand, waarschuwingen en pas-tellers worden samen gepubliceerd, maar alleen nadat validatie en opmaak stabiliseren
Afgewezen scripts, uitgeputte budgetten, ongeldige UTF-16-selectiegrenzen en uitzonderingen op het gebied van opmaak of hostmeting herstellen de volledige eerdere toestand en stellen LastDiagnostic in
Budgetten
TXFAWidgetRuntimeOptions beperkt de widgetteller, bewerkte waarde lengte, berekeningspassen, herschikkingspassen, opmaakbewerkingen, scriptbewerkingen, verstreken scripttijd en andere FormCalc- of JavaScript-bronnen
De widgetlimiet geldt terwijl opmaakitems en pagineringfragmenten worden toegevoegd, terwijl geladen XFA-decompressie en packetassemblage stoppen bij de invoerlimiet van het XFA-DOM vóór het parseren
MaxLayoutOperations staat standaard op 200000 en begrenst zowel de documentdoorloop als het opmaakwerk; de opmaakdiepte is beperkt tot 128, eventdoel- en instantie-initialisatiediepte tot 64, en recursieve eventdispatch wordt geweigerd
Beperkte dynamische events
DispatchEvent accepteert puntkomma-gescheiden letterlijke operaties in overeenkomende veld-eventscripts met FormCalc- of JavaScript-inhoudstypen; deze operaties worden direct geparseerd en vereisen geen JavaScript-DLL
row.instanceManager.addInstance(true);
row.instanceManager.removeInstance(0);
target.presence = "hidden";
addInstance voegt één instantie toe en accepteert true, false, 1 of 0 als merge-argument; een weggelaten argument gebruikt true, en de verkorte notatie _row.addInstance(1) wordt ook geaccepteerd
Het ondersteunde model bindt elke bestaande gegevensgroep met dezelfde naam, dus een nieuwe instantie krijgt een nieuwe gegevensgroep die vanuit de template-defaults wordt geïnitialiseerd, bij elk merge-argument; het aanmaken van een instantie kloont de ingevoerde waarden van de vorige rij niet
removeInstance gebruikt een op nul gebaseerde integer-index binnen de gelijknamige gegevensgroepen van de geselecteerde subform; de subform moet een occur-element met een herhaalbaar maximum hebben, en beide operaties handhaven dat minimum en maximum, inclusief max="-1"
Instantiemutatie vereist impliciete named dataset-binding en ASCII-XML-datanamen; expliciete data-reference-binding en dubbelzinnige bovenliggende contexten worden geweigerd vóór het publiceren van de transactie
Doelen worden opgelost via benoemde template-kinderen in de omhullende scopes van het event, inclusief puntpaden en this.parent; een manager die binnen een herhaalde scope is genest, gebruikt de eigen gegevensgroep van het event
presence accepteert visible, hidden en invisible op templatevelden, draws, subforms en exclusiegroepen; verborgen inhoud neemt geen flowruimte in, terwijl onzichtbare inhoud zijn ruimte behoudt en wordt weggelaten uit widgets en flatten-uitvoer
Aanwezigheidswijzigingen gelden voor de geselecteerde template-node en dus voor alle herhaalde voorkomens ervan; geïndexeerde aanwezigheid per instantie, inactive, willekeurige expressies, variabelen, conditionals, loops en andere eventscript-operaties worden geweigerd
Een eventbatch publiceert gegevenswijzigingen, berekeningen, opmaak, focus en bewerkingstoestand samen nadat de herschikking stabiliseert; elke geweigerde operatie of een uitgeput budget voor invoer, bewerkingen, instanties, waarden, widgets, opmaak of verstreken tijd herstelt de volledige eerdere document- en interactietoestand
Het verwijderen van een rij behoudt focus en lopende bewerkingen voor overlevende gegevensgroepen, zelfs wanneer hun widgetindices veranderen; het verwijderen of verbergen van de gefocuste widget wist de focus en publiceert na succes de bijbehorende focuscallback
Algemene JavaScript- en FormCalc-eventuitvoering
Zet TXFAWidgetRuntimeOptions.ScriptOptions.EnableJavaScript aan om de meegeleverde begrensde QuickJS-bridge voor eventuitvoering te gebruiken; JavaScript-events ondersteunen dan functies, closures, arrays, conditionals, lussen en exceptions in plaats van de default letterlijke grammatica
Options := TXFAWidgetRuntimeOptions.Default;
Options.ScriptOptions.EnableJavaScript := True;
Runtime := TXFAWidgetRuntime.Create(XDPBytes, 595, 842, Options);
De eventhost stelt this, omsluitende benoemde velden en subforms, parent, beschrijfbare rawValue, presence en access, instanceManager.count/min/max, addInstance, removeInstance, insertInstance, moveInstance en setInstances, xfa.resolveNode, xfa.resolveNodes, resolutie op node-niveau en xfa.layout.relayout bloot
Nodelijsten ondersteunen numerieke indexering, length en item; herhaalde veldwaarden behouden hun eigen datasetdoelen en SOM-paden accepteren benoemde kinderen met numerieke of wildcard-indices voor levende host-nodes
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";
Elke herhaalde subform heeft zijn eigen levende object en kindvelden; index, ouder-kindgetters en daaropvolgende SOM-queries volgen insert-, move- en remove-operaties direct binnen het script
addInstance en insertInstance geven een levende subboom terug die vanuit template-defaults wordt geïnitialiseerd, zodat het script zijn veldwaarden kan schrijven voordat het event publiceert; verwijderde handles wijzen daaropvolgende reads en writes af
Algemene script-wijzigingen van presence en access blijven per occurrence in het standaard XFA form-packet bewaard, terwijl veldwaarden en herhaaloperaties in datasets blijven; insert, move en remove houden de bijbehorende formulierstate uitgelijnd met de datagroepen
Met dezelfde opt-in compileren FormCalc-event-scripts naar de begrensde engine en ondersteunen var, if/elseif/else, for met upto of downto, while, foreach, func met impliciete resultaten, rekenkunde en vergelijkingen, samenvoeging van strings, aggregatie van wildcard-nodes en impliciete toewijzing van veldwaarden
De eventfunctiebibliotheek omvat Sum, Count, Avg, Min, Max, Round, gebruikelijke wiskundige functies, het snijden van strings, casusconversie, trimmen, vervanging, HasValue, Exists, Within, Oneof en Choose; ingebouwde namen zijn case-insensitive, At(source, search) volgt de XFA-argumentvolgorde inclusief leeg-zoekgedrag, financiële functies volgen de XFA-parametervolgorde en de datum- en financiecatalogi worden beschreven in FormCalc Functions
Scriptmutaties worden in de engine vastgelegd, gevalideerd en binnen de runtime-transactie gereplayerd; exceptions, onderbreking, ongeldige Unicode, ongeldige hostoperaties en uitgeputte budgetten publiceren geen partiële documentwijzigingen
Algemene scriptuitvoering staat default uit, gebruikt geen browser of extern proces en stelt geen bestandssysteem-, netwerk- of applicatie-API's bloot; de aanroeper kan in plaats van de bridge een JavaScriptEvaluator aanleveren
Persistente scriptobjecten
JavaScript script-objecten binnen het variables-element van een subform stellen hun variabelen en functies via de scriptnaam beschikbaar; lexicale variabelen, objectstate en geneste closures blijven gedurende de runtime-sessie in leven, met normale lexicale shadowing en behouden strict-directives
<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>
Eventcode kan Helpers.next() aanroepen; herhaalde subform-occurrences zijn eigenaar van onafhankelijke scriptobjecten en functies lossen benoemde velden op tegen de huidige levende formuliercontext
Vastgelegde veldnodes en managers volgen stabiele data-identiteit over verplaatsingen en de publicatie van nieuw aangemaakte instanties heen; toegang tot een verwijderde node wijst het event af en rollt de modulestate terug
Algemene calculate- en validate-scripts delen de sessie en de scriptobjecten; JavaScript ondersteunt impliciete completion-waarden en expliciete return, terwijl FormCalc zijn laatste expressie teruggeeft
Mislukte transacties herstellen lexicale en closure-state door het vastgelegde virtuele journaal te replayen, met opgenomen tijd- en randominvoer; replay en huidige uitvoering delen de transactiedeadline en de default journaallimieten zijn 64 MiB aan scripts/resultaten en 8192 entries
Script-object-state leeft in de runtime-sessie en wordt na het herladen van de XDP opnieuw geïnitialiseerd; standaard documentwaarden en formulier-overrides blijven via SaveToBytes persisteren
Eigen JavaScriptEvaluator-callbacks behouden de bestaande native calculate/validate-envelop; de persistente sessie wordt door de meegeleverde engine geleverd
Expliciet host-transport configureren
Zet HostTransport en de optionele OnHostTransactionCompleted in TXFAWidgetRuntimeOptions om hostdialogen, printing, navigatie, submission en gegevensoverdracht via applicatie-callbacks uit te voeren
Explicit XFA Host Transport levert xfa.host.messageBox, response, beep, print, gotoURL, submitForm, importData, exportData en FormCalc Get, Post en Put; de applicatie geeft getypeerde resultaten terug en stuurt externe effecten
Retries en sessie-replay gebruiken opgenomen responses, dus callbacks voeren één keer per verstuurde request uit; bij het afronden van een faling kan de applicatie gestage effecten verwijderen of omkeerbare operaties compenseren
Positieve HostTransportLimits begrenzen het aantal requests, het aantal argumenten en de totale request/response-bytes binnen de omsluitende runtime-transactie
Locale- en picture-uitvoering
Algemene FormCalc-events en calculate- en validate-scripts ondersteunen locale- en picture-functies, waaronder Format, Parse, gelokaliseerde datum-/tijdconversies, eenheden, encoding, UUID's en Engelse getalswoorden
Dynamische FormCalc Eval voert dynamisch aangeleverde berekeningen uit met geïsoleerde variabelen en functies, relatieve veldtoegang, native compilatie, opgenomen responses en transactionele rollback
Expliciete FormCalc-verwijzingen ondersteunen write-through-toewijzing, rebind, null-loskoppeling, functieargumenten en stabiele handles die scriptobjecten vasthouden bij verplaatsing van herhaalde instanties
Levende SOM-paden ondersteunen afgeleide, absolute en relatieve occurrence-indices, class- en descendant-selectors, transparante containers, kandidaatpredikaten en directe FormCalc-geïndexeerde toewijzing
De native Data DOM stelt datasets via $data en $record bloot, synchroniseert gekoppelde formulier- reads en writes direct, spiegelt herhaalde instanties en behoudt vastgehouden datareferenties via native identiteitspublicatie
De native Property DOM stelt gedeclareerde value-, font-, UI- en andere property-kinderen bloot, synchroniseert getypeerde veldwaarden en persisteert per-instance attributen die worden gebruikt door fontmeting en ondersteunde flatten-styling
De uitvoerende node erft zijn dichtstbijzijnde locale-attribuut; document-localeSet-entries overrulen systeemsymbolen en -patronen, terwijl berekende locatenamen via begrensde interne verzoeken worden opgelost en in het sessiejournaal worden bewaard
Num2Date zonder picture gebruikt tegenwoordig het omgevingsdefault-datumpatroon; geef YYYY-MM-DD expliciet door wanneer ISO-uitvoer wordt vereist
Stateful hostmodel
XFA Host Model levert applicatiemetadata, werkelijke pagina-aantallen, paginanavigatie, Unicode-titel, calculation-/validatievlaggen, gescopedde reset en veldfocus met transactionele enter/exit-levenscyclus
TXFAWidgetRuntimeOptions.HostModel configureert de begin-applicatiestatus; TXFAWidgetRuntime.HostModel geeft de huidige status terug en mislukte events herstellen die samen met document- en interactie-snapshots
Een focuswissel zonder enter/exit-script, openstaande edit of geïnitialiseerde levenscyclus verandert de focus zonder scriptberekening of deadlineverwerking te starten; scriptgedreven focus- en openstaande edit-commits gebruiken nog steeds transactionele budgetten, validatie en herberekening
Geavanceerde picture-clausules worden uitgevoerd via dezelfde runtime-transacties, het locale-retry-journaal en de berekeningslevenscyclus, met begrensde samengestelde parsing
De levenscyclus initialiseren en onderhouden
Roep InitializeForm aan nadat je de runtime en de callbacks hebt geconfigureerd om initialize-events in templatevolgorde uit te voeren, daarna calculate en validate, form-ready-events en layout-ready-events; de aanroep is idempotent na succes
Nieuwe instanties die door initialisatie of ready-events ontstaan, ontvangen hun eigen initialize-events vóór hun ready-handlers; layout-ready-uitvoering herhaalt alleen wanneer de layout verandert, binnen de reflow- en transactiebudgetten
Na initialisatie initialiseren geslaagde eventdispatches en edit-commits nieuw aangemaakte instanties en voeren calculate, validate en layout-ready uit; bestaande occurrences behouden hun initialisatiestatus over verplaatsingen en transactionele rollback heen
Mislukkingen in de levenscyclus rollen documentbytes, widgetinteractie en initialisatieboekhouding samen terug, en callbacks publiceren pas nadat de omsluitende transactie is geslaagd
Het bijgewerkte formulier opslaan
SaveToBytes geeft de volledige bijgewerkte XDP van de runtime terug, inclusief gewijzigde datasets en template-aanwezigheidsattributen; gebruik deze bytes met SetXFADocument bij het schrijven van een PDF of met HPDFXFAFlatten voor de bijgewerkte flatten-uitvoer
De fabriek voor geladen documenten maakt een onafhankelijke runtime aan, dus runtime-events wijzigen niet automatisch de objectgrafiek van de bron-PDF
Optioneel instance-presentation-profiel
Dynamic XFA Instance Presentation voegt expliciete herhaalde bindingen, stabiele per-instance ID's, geïndexeerde presence en toegang, begrensde conditionele events, host-canvas-painting en accessibility toe via een onafhankelijke helper; de default-runtime en zijn beperkte eventgrammatica blijven compatibel
UpdateDocument levert transactionele documentacties; optionele callbacks voor runtime-properties, binding-scope, identiteit, resolutiestart en documentvalidatie ondersteunen de helper, terwijl nil-defaults bestaande aanroepers behouden
API's voor events en formulieren op lager niveau
HPDFXFACompileFormCalcEvent compileert eventsyntax; HPDFXFAExecuteJavaScriptEvent voert de virtuele context uit die TXFAEventBinding en TXFAEventBindings beschrijven
TXFAJavaScriptSession levert persistente uitvoering en begrensde checkpoints voor aanroepers op lager niveau
Teruggegeven TXFAEventAction-waarden gebruiken TXFAEventActionKind; transactionele replay wordt door de runtime geleverd
HPDFXFAResolveFormInstanceNode en HPDFXFAResolveFormInstanceProperty bieden begrensde opzoeking in het standaard form-packet
Huidige grenzen
De runtime is een single-thread-hostobject en biedt geen GUI, schilder of algemene XFA-eventscript-engine
Focusinvoer en -uitgang worden rechtstreeks ondersteund wanneer er geen overeenkomend eventscript bestaat; de beperkte eventoperaties impliceren geen ondersteuning voor volledige JavaScript, FormCalc, XFA-lifecycle-events of een aparte form-DOM met presentatie-overrides per instantie
Zie Bounded XFA FormCalc and JavaScript, XFA Packet DOM en Interactive Document Processing