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