Présentation d’instances XFA dynamiques

Unité : HPDFXFAPresentation

TXFAInstancePresentation possède un TXFAWidgetRuntime indépendant et ajoute un profil borné de présentation d’instances pour les documents de packets XDP avec un seul record datasets

Utilisez SetPresence('row[1]', 'hidden') pour retirer une occurrence du flux, invisible pour conserver son espace tout en masquant ses widgets, et visible pour la restaurer ; les indices sont des positions à base zéro parmi les occurrences de données, occurrences masquées comprises

Le résolveur de layout mesure chaque occurrence séparément, compacte les offsets verticaux survivants et réserve l’étendue répétée complète avant de placer le contenu suivant ; les hauteurs fixes, hauteurs dérivées du contenu et rangées de tables participent au reflow

Identité stable et persistance

Les IDs de widgets combinent des identités opaques de template et de datasets et restent stables quand des rangées précédentes sont masquées ou retirées, après sauvegarde et rechargement, et tant que les champs survivants conservent le focus ou des éditions en attente

Le helper stocke les attributs d’identité qualifiés par namespace et les overrides d’instances dans une extension de namespace étranger à l’intérieur du packet de formulaire, en utilisant urn:hotpdf:xfa:instance-presentation:1 ; les rangées nouvellement ajoutées reçoivent des identités fraîches et les défauts du template, et les rangées retirées ne peuvent transférer leurs éditions en attente à des rangées de remplacement

SaveToBytes renvoie le XDP complet, y compris datasets, identités et états de présentation mis à jour ; utilisez THotPDF.SetXFADocument pour le persister dans un PDF et définissez XFANeedsRendering := True quand vous écrivez un formulaire dynamique

Après rechargement du PDF, obtenez le XDP complet avec THotPDF.CreateLoadedXFAWidgetRuntime.SaveToBytes, puis construisez TXFAInstancePresentation depuis ces octets pour restaurer ce profil

L’extension de namespace est interprétée par ce helper ; le HPDFXFAFlatten natif, la fabrique de runtime chargé par défaut et les viewers XFA externes n’appliquent pas automatiquement ses overrides par instance, si bien que persister le profil n’affirme pas un rendu identique dans d’autres lecteurs

Binding explicite et opérations d’instances

Les subforms répétés peuvent se lier à un groupe de données nommé différemment avec <bind match="dataRef" ref="$record.lines.entry[*]"/> ; les racines absolues $record et $data et les chemins relatifs prennent en charge des groupes parents non indexés et un groupe répété final

Les champs à l’intérieur de chaque occurrence utilisent le résolveur natif de valeurs liées, y compris les bindings relatifs explicites de champs tels que ref="label"

AddInstance et RemoveInstance mettent à jour le groupe de données sélectionné, appliquent le minimum et le maximum de occur, respectent des limites de création et déclenchent un reflow avant publication ; la nouvelle rangée reçoit les valeurs de champs du template au lieu de copier les valeurs saisies de la rangée précédente

Les sélecteurs utilisent un nom de template unique avec un index d’occurrence optionnel, tel que row[1] ; noms de templates dupliqués, groupes manquants, indices invalides et mutations sous un parent répété ambigu rejettent la transaction

SetAccess prend en charge open, readOnly, protected et nonInteractive ; les restrictions d’instances sont héritées par les descendants et empêchent l’édition via le runtime possédé

Événements conditionnels

DispatchConditionalEvent localise un événement de champ correspondant avec type de contenu JavaScript et analyse directement le profil borné ; Execute exécute un script explicite contre un ID de widget existant

if(this.rawValue=="hide"){
  row[1].presence="hidden";
}else{
  row[1].presence="visible";
}
row.instanceManager.addInstance();
row.instanceManager.removeInstance(0);

Les conditions acceptent l’égalité ou l’inégalité entre this.rawValue et un literal quoté non échappé ; les blocs if imbriqués par accolades et blocs else optionnels sont bornés par MaxDepth

Les affectations prennent en charge presence et access ; toutes les branches sont vérifiées syntaxiquement, y compris celles non empruntées, et les opérations non prises en charge rejettent le lot entier

this.rawValue lit la valeur committée du widget ; commitez les éditions en attente via Runtime.CommitEdit avant de dispatcher un événement censé les observer

Le Runtime.DispatchEvent original conserve son comportement restreint d’opérations literal et rejette la syntaxe conditionnelle et d’instances indexées ; ce helper ne fournit pas d’interpréteur général JavaScript ou FormCalc, d’API navigateur, d’accès réseau ni de dispatch automatique du cycle de vie XFA

Transactions et budgets

Les mutations s’exécutent via TXFAWidgetRuntime.UpdateDocument, avec les calculs natifs et un reflow stable borné ; l’échec restaure le XDP sérialisé, le focus, les éditions en attente, l’état de validation, les compteurs de calculs et de reflow et le nombre d’avertissements

Les callbacks de focus, de layout et d’invalidation de widgets ne publient qu’après succès ; la résolution de rollback supprime le travail épuisé du helper et les vérifications d’annulation tout en conservant le layout natif et les bornes de widgets, afin que l’annulation ne puisse empêcher la restauration

Initialisez TXFAPresentationOptions avec Default ; les défauts sont 200 000 opérations, 4 096 états de présentation, 10 000 instances créées par groupe, une enveloppe d’entrée et de document de 32 Mio, 65 536 octets de script, 32 niveaux d’imbrication conditionnelle et 5 000 millisecondes

MaxInputBytes borne aussi une enveloppe XML échappée conservative avant chaque passe de layout et de publication, attributs d’identité, déclarations de namespace, texte et changements de datasets compris ; un XML valide peut atteindre cette limite conservative avant que son nombre d’octets sérialisés n’atteigne la même valeur

Cancelled est un callback de méthode d’objet optionnel sondé pendant le travail borné ; les options du Runtime embarqué continuent de borner widgets, valeurs, calculs, layout, reflow et travail de scripts natif

Peinture hôte et accessibilité

Accessibility renvoie des records de widgets visibles avec ID stable, rôle, caption ou nom de champ, description tooltip, valeur committée, page et bornes, focus, validité, états lecture seule et requis, et libellés de choice ; les valeurs de mots de passe sont omises

PaintPage livre un instantané des widgets visibles et des records d’accessibilité correspondants à un TXFAHostWidgetPainter ; les hôtes personnalisés peuvent implémenter leurs propres contrôles ou surface de rendu

TXFACanvasWidgetPainter fournit une vraie peinture canvas VCL et LCL pour les bordures de widgets, le texte, le masquage des mots de passe, les marques checkbox et radio, les indicateurs de choice, les boutons et le focus, avec échelle positive et offsets optionnels ; il clippe chaque widget et restaure les styles du canvas

L’adaptateur canvas peint les widgets et ne peint pas l’arbre graphique XFA statique complet ; l’hôte fournit son propre arrière-plan de page, graphiques statiques, routage d’événements, présentation de sélection et pont d’accessibilité vers sa plateforme

Le runtime et le helper sont des objets mono-thread ; les callbacks doivent respecter la propriété de threads de l’hôte et éviter les mutations récursives pendant une transaction active

Les appelants C++Builder doivent fournir tous les arguments du constructeur du painter canvas, tels que new TXFACanvasWidgetPainter(canvas, 1, 0, 0) ; les en-têtes générés ne conservent pas ces arguments par défaut en virgule flottante

Vérification

L’acceptation couvre 106 cas Delphi par architecture, une compilation FPC fraîche sur les deux architectures Windows, la compilation des en-têtes publics C++Builder sur Win32 et Win64x, et une validation indépendante de la sortie PDF/XDP réelle

Tests/Fixtures/XFAInstancePresentation/explicit-invoice.xdp contient des noms de données indépendants, trois lignes de facture répétées, un événement conditionnel, des métadonnées d’accessibilité et un pied de page suivant

Run-XFAInstancePresentationTests.ps1 exécute les vérifications du helper et les fixtures de régression existantes d’événements XFA, de runtime, de scripting, SOM, DOM et de résolution sans GUI ni lecteurs PDF externes

Le verify_saved_invoice.py indépendant lit le PDF généré avec pypdf et vérifie de vraies rangées de données XDP, des identités persistantes uniques, l’état des occurrences masquées, les défauts initialisés et les identités après rechargement

powershell -File Tests/Delphi/Run-XFAInstancePresentationTests.ps1 -Platform Win32 -CheckCppHeaders
powershell -File Tests/Delphi/Run-XFAInstancePresentationTests.ps1 -Platform Win64 -CheckCppHeaders
python Tests/Fixtures/XFAInstancePresentation/verify_saved_invoice.py

Voir Interactive XFA Widget Runtime pour le runtime de base compatible et le contrat d’édition natif