Представление экземпляров динамического XFA
Модуль: HPDFXFAPresentation
TXFAInstancePresentation владеет независимым TXFAWidgetRuntime и добавляет ограниченный профиль представления экземпляров для документов XDP-пакетов с одной записью datasets
Используйте SetPresence('row[1]', 'hidden'), чтобы убрать экземпляр из потока, invisible, чтобы сохранить его место, спрятав виджеты, и visible, чтобы вернуть его; индексы — позиции с нуля среди экземпляров данных, включая скрытые
Разрешатель раскладки измеряет каждый экземпляр отдельно, уплотняет вертикальные смещения выживших и резервирует полный повторяющийся объём перед размещением последующего содержимого; в reflow участвуют строки с фиксированной высотой, высотой по содержимому и табличные
Стабильная идентичность и сохранение
ID виджетов объединяют непрозрачные идентичности шаблона и datasets и остаются стабильными при скрытии или удалении предыдущих строк, после сохранения и перезагрузки и пока выжившие поля держат фокус или неподтверждённые правки
Хелпер хранит атрибуты идентичности с пространствами имён и переопределения экземпляров в расширении чужого пространства имён внутри form-пакета, используя urn:hotpdf:xfa:instance-presentation:1; новые строки получают свежие идентичности и шаблонные умолчания, а удалённые строки не могут передать неподтверждённые правки строкам-заместителям
SaveToBytes возвращает полный XDP, включая обновлённые datasets, идентичности и состояния представления; чтобы сохранить его в PDF, используйте THotPDF.SetXFADocument и ставьте XFANeedsRendering := True при записи динамической формы
После перезагрузки PDF получите полный XDP через THotPDF.CreateLoadedXFAWidgetRuntime.SaveToBytes, затем сконструируйте TXFAInstancePresentation из этих байтов, чтобы восстановить этот профиль
Расширение пространства имён интерпретирует только этот хелпер; нативный HPDFXFAFlatten, фабрика рантайма по умолчанию для загруженных документов и внешние просмотрщики XFA не применяют его поэкземплярные переопределения автоматически, поэтому сохранение профиля не гарантирует идентичный рендеринг в других читалках
Явный биндинг и операции над экземплярами
Повторяющиеся сабформы могут привязываться к по-другому названной группе данных через <bind match="dataRef" ref="$record.lines.entry[*]"/>; абсолютные корни $record и $data и относительные пути поддерживают неиндексированные родительские группы и финальную повторяющуюся группу
Поля внутри каждого экземпляра используют нативный разрешатель привязанных значений, включая явные относительные привязки полей вроде ref="label"
AddInstance и RemoveInstance обновляют выбранную группу данных, соблюдают минимум и максимум occur, применяют лимиты создания и делают reflow до публикации; новая строка получает значения полей из шаблона, а не копирует введённые значения из предыдущей строки
Селекторы используют уникальное имя шаблона с опциональным индексом экземпляра, например row[1]; дублирующиеся имена шаблонов, отсутствующие группы, неверные индексы и мутации под неоднозначным повторяющимся родителем отвергают транзакцию
SetAccess поддерживает open, readOnly, protected и nonInteractive; ограничения экземпляра наследуются потомками и не дают редактировать через собственный рантайм
Условные события
DispatchConditionalEvent находит подходящее событие поля с типом содержимого JavaScript и разбирает ограниченный профиль напрямую; Execute исполняет явный скрипт против существующего ID виджета
if(this.rawValue=="hide"){
row[1].presence="hidden";
}else{
row[1].presence="visible";
}
row.instanceManager.addInstance();
row.instanceManager.removeInstance(0);
Условия принимают равенство или неравенство между this.rawValue и неэскейпированным кавычечным литералом; вложенные блоки if в фигурных скобках и опциональные else ограничены MaxDepth
Присваивания поддерживают presence и access; все ветки проходят синтаксическую проверку, включая не выполняемые, а неподдерживаемые операции отвергают весь батч
this.rawValue читает зафиксированное значение виджета; подтвердите неподтверждённые правки через Runtime.CommitEdit перед диспетчеризацией события, которое должно их увидеть
Исходный Runtime.DispatchEvent сохраняет ограниченное поведение с литеральными операциями и отвергает условный синтаксис и синтаксис с индексированными экземплярами; этот хелпер не даёт полноценного интерпретатора JavaScript или FormCalc, браузерных API, доступа в сеть или автоматической диспетчеризации жизненного цикла XFA
Транзакции и бюджеты
Мутации исполняются через TXFAWidgetRuntime.UpdateDocument вместе с нативными вычислениями и ограниченным стабильным reflow; при сбое восстанавливаются сериализованный XDP, фокус, неподтверждённые правки, состояние валидации, счётчики вычислений и reflow и количество предупреждений
Callback'и фокуса, раскладки и инвалидации виджетов публикуются только после успеха; разрешение отката подавляет исчерпанные работы хелпера и проверки отмены, сохраняя нативную раскладку и границы виджетов, чтобы отмена не могла помешать восстановлению
Инициализируйте TXFAPresentationOptions значением Default; умолчания: 200 000 операций, 4 096 состояний представления, 10 000 созданных экземпляров на группу, конверт ввода и документа 32 МиБ, 65 536 байт скрипта, 32 уровня вложенности условий и 5 000 миллисекунд
MaxInputBytes также ограничивает консервативный эскейпированный XML-конверт перед каждым проходом раскладки и публикации, включая атрибуты идентичности, объявления пространств имён, текст и изменения datasets; валидный XML может достичь этого консервативного лимита раньше, чем его сериализованный размер в байтах достигнет того же значения
Cancelled — опциональный callback-метод объекта, проверяемый во время ограниченной работы; опции встроенного Runtime продолжают ограничивать виджеты, значения, вычисления, раскладку, reflow и нативную работу скриптов
Отрисовка у хоста и доступность
Accessibility возвращает записи видимых виджетов со стабильным ID, ролью, подписью или именем поля, описанием tooltip, зафиксированным значением, страницей и границами, фокусом, валидностью, состояниями read-only и required и подписями вариантов; значения password опускаются
PaintPage передаёт снимок видимых виджетов и соответствующих записей доступности в TXFAHostWidgetPainter; кастомные хосты могут реализовать свои контролы или поверхность отрисовки
TXFACanvasWidgetPainter даёт настоящую отрисовку на canvas VCL и LCL для границ виджетов, текста, маскирования паролей, меток checkbox и radio, индикаторов списков, кнопок и фокуса, с положительным масштабом и опциональными смещениями; он отсекает каждый виджет и восстанавливает стили canvas
Canvas-адаптер рисует виджеты и не рисует полное статическое дерево графики XFA; хост сам предоставляет фон страницы, статическую графику, маршрутизацию событий, представление выделения и мост доступности к своей платформе
Рантайм и хелпер — однопоточные объекты; callback'и обязаны следовать потоковой принадлежности хоста и избегать рекурсивных мутаций во время активной транзакции
Вызывающий код C++Builder обязан передать все аргументы конструктора canvas-пеинтера, например new TXFACanvasWidgetPainter(canvas, 1, 0, 0); сгенерированные заголовки не сохраняют эти вещественные аргументы по умолчанию
Проверка
Приёмка покрывает 106 Delphi-кейсов на архитектуру, свежую компиляцию FPC на обеих архитектурах Windows, компиляцию публичных заголовков C++Builder на Win32 и Win64x и независимую валидацию реального вывода PDF/XDP
Tests/Fixtures/XFAInstancePresentation/explicit-invoice.xdp содержит независимые имена данных, три повторяющиеся строки счёта, условное событие, метаданные для доступности и следующий за ними футер
Run-XFAInstancePresentationTests.ps1 запускает проверки хелпера и существующие регрессионные фикстуры событий XFA, рантайма, скриптинга, SOM, DOM и разрешения раскладки без GUI и внешних просмотрщиков PDF
Независимый verify_saved_invoice.py читает сгенерированный PDF через pypdf и проверяет реальные строки данных XDP, уникальные постоянные идентичности, скрытое состояние экземпляра, инициализированные умолчания и идентичности после перезагрузки
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
Совместимый базовый рантайм и нативный контракт редактирования описаны в Interactive XFA Widget Runtime