Interaktywny runtime widgetów dynamicznego XFA
TXFAWidgetRuntime dostarcza neutralny dla hosta model interakcji dla dynamicznych formularzy XFA bez konwertowania ich do pól AcroForm ani spłaszczania ich zawartości
Runtime wystawia deterministyczne granice i stan widgetów, więc aplikacja desktopowa, serwis albo własny renderer może dostarczyć własne wejście, malowanie, dostępność i pętlę zdarzeń
Tworzenie runtime
Utwórz runtime bezpośrednio z bajtów XDP albo wywołaj THotPDF.CreateLoadedXFAWidgetRuntime po wczytaniu PDF, którego AcroForm zawiera wpis /XFA jako pojedynczy strumień albo tablicę pakietów
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;
Fabryka dokumentów załadowanych jest tylko do odczytu względem grafu obiektów PDF i istniejących XFAFlattenWarnings; zapis dokumentu zachowuje jego oryginalne wpisy /XFA i /NeedsRendering
Model interakcji
FocusWidgetiClearFocusutrzymują jeden widget z fokusem, wykonują skrypty enter/exit i publikują uporządkowane callbacki po zatwierdzeniuBeginEdit,ReplaceSelection,CancelEditiCommitEditzachowują tekst Unicode, łącznie ze spacjami wiodącymi i końcowymiHitTestmapuje współrzędne strony na widoczny widget położony najwyżejOnWidgetInvalidated,OnLayoutChangediOnFocusChangedpozwalają hostowi odświeżyć tylko dotknięty stan
Interaktywne commity synchronizują istniejące natywne wartości skalarne w aliasach ukrytych i niewidzialnych, łącznie z rzeczywistymi powtórzonymi zakresami danych i rollbackiem dokładnym co do bajta
Atomowa walidacja i obliczanie
Commit rozwiązuje jawne wiązania SOM i bieżący kontekst danych powtarzanego wiersza przed uruchomieniem skryptów validate i calculate
Edytowana wartość, wartości obliczone, węzły danych, model widgetu, stan fokusa i edycji, ostrzeżenia i liczniki przejść publikują razem dopiero po ustabilizowaniu walidacji i layoutu
Odrzucone skrypty, wyczerpane budżety, niepoprawne granice zaznaczenia UTF-16 oraz wyjątki layoutu albo pomiaru hosta przywracają kompletny poprzedni stan i ustawiają LastDiagnostic
Budżety
TXFAWidgetRuntimeOptions ogranicza liczbę widgetów, długość edytowanej wartości, przejścia obliczeń, przejścia reflow, operacje layoutu, operacje skryptowe, czas wykonania skryptów i inne zasoby FormCalc albo JavaScript
Limit widgetów obowiązuje podczas dołączania elementów layoutu i fragmentów paginacji, a dekompresja wczytanego XFA i składanie pakietów zatrzymują się na limicie wejścia XFA DOM przed parsowaniem
MaxLayoutOperations domyślnie wynosi 200000 i ogranicza zarówno przejście dokumentu, jak i pracę layoutu; głębokość layoutu jest ograniczona do 128, głębokość celu zdarzenia i inicjalizacji instancji do 64, a rekurencyjna dyspozycja zdarzeń jest odrzucana
Domyślne literałowe zdarzenia dynamiczne
DispatchEvent przyjmuje literałowe operacje rozdzielone średnikami w pasujących skryptach zdarzeń pól o typach zawartości FormCalc albo JavaScript; te operacje są parsowane bezpośrednio i nie wymagają DLL JavaScript
row.instanceManager.addInstance(true);
row.instanceManager.removeInstance(0);
target.presence = "hidden";
addInstance dołącza jedną instancję i przyjmuje true, false, 1 albo 0 jako argument merge; pominięty argument oznacza true, a skrót _row.addInstance(1) też jest akceptowany
Wspierany model binduje wszystkie istniejące grupy danych o tej samej nazwie, więc nowa instancja dostaje nową grupę danych zainicjalizowaną z domyślnych wartości szablonu dla dowolnego argumentu merge; tworzenie instancji nie klonuje wprowadzonych wartości poprzedniego wiersza
removeInstance używa indeksu całkowitego od zera wśród grup danych o tej samej nazwie wybranego subformularza; subformularz musi mieć element occur z powtarzalnym maksimum, a obie operacje wymuszają jego minimum i maksimum, łącznie z max="-1"
Mutacja instancji wymaga niejawnego bindowania nazwanych zbiorów danych i ASCII nazw danych XML; jawne bindowanie data-reference i niejednoznaczne konteksty rodzica są odrzucane przed publikacją transakcji
Cele są rozwiązywane przez nazwane dzieci szablonu w otaczających zakresach zdarzenia, w tym ścieżki kropkowe i this.parent; menedżer zagnieżdżony w powtórzonym zakresie używa własnej grupy danych zdarzenia
presence przyjmuje visible, hidden i invisible na polach szablonu, rysunkach, subformularzach i grupach wykluczeń; zawartość hidden nie zajmuje miejsca w przepływie, a zawartość invisible zachowuje swoje miejsce i jest pomijana w widgetach i wyjściu flatten
Przy domyślnym parserze literałowym zmiany presence dotyczą wybranego węzła szablonu, więc też wszystkich jego powtórzonych wystąpień; presence per instancja indeksowana, inactive, dowolne wyrażenia, zmienne, warunki, pętle i inne operacje skryptów zdarzeń wymagają dodatkowego hosta zdarzeń
Batch zdarzeń publikuje zmiany danych, obliczenia, layout, fokus i stan edycji razem po ustabilizowaniu reflow; każda odrzucona operacja albo wyczerpany budżet wejścia, operacji, instancji, wartości, widgetów, layoutu albo czasu przywraca kompletny poprzedni stan dokumentu i interakcji
Usunięcie wiersza zachowuje fokus i oczekujące edycje przetrwałych grup danych, nawet gdy zmieniają się ich indeksy widgetów; usunięcie albo ukrycie widgetu z fokusem czyści fokus i publikuje odpowiadający callback fokusa po sukcesie
Ogólne wykonanie zdarzeń JavaScript i FormCalc
Ustaw TXFAWidgetRuntimeOptions.ScriptOptions.EnableJavaScript, aby włączyć dostarczany ograniczony bridge QuickJS do wykonania zdarzeń; zdarzenia JavaScript wspierają wtedy funkcje, domknięcia, tablice, warunki, pętle i wyjątki zamiast domyślnej gramatyki literałowej
Options := TXFAWidgetRuntimeOptions.Default;
Options.ScriptOptions.EnableJavaScript := True;
Runtime := TXFAWidgetRuntime.Create(XDPBytes, 595, 842, Options);
Host zdarzeń wystawia this, otaczające nazwane pola i subformularze, parent, zapisywalne rawValue, presence i access, instanceManager.count/min/max, addInstance, removeInstance, insertInstance, moveInstance i setInstances, xfa.resolveNode, xfa.resolveNodes, rozwiązywanie na poziomie węzłów oraz xfa.layout.relayout
Listy węzłów wspierają indeksowanie numeryczne, length i item; powtórzone wartości pól zachowują własne cele zbiorów danych, a ścieżki SOM przyjmują nazwane dzieci z indeksami numerycznymi albo wildcard dla żywych węzłów hosta
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";Każdy powtórzony subformularz ma własny żywy obiekt i pola potomne; index, gettery dzieci rodzica i kolejne zapytania SOM podążają natychmiast za operacjami wstawienia, przeniesienia i usunięcia wewnątrz skryptu
addInstance i insertInstance zwracają żywe poddrzewo zainicjalizowane z domyślnych wartości szablonu, więc skrypt może zapisać wartości pól przed publikacją zdarzenia; usunięte uchwyty odrzucają kolejne odczyty i zapisy
Zmiany presence i access ogólnych skryptów są trwałe w standardowym pakiecie form XFA per wystąpienie, a wartości pól i operacje powtórzeń są trwałe w datasets; wstawienie, przeniesienie i usunięcie utrzymuje odpowiadający stan form w zgodzie z grupami danych
Przy tej samej opcji opt-in skrypty zdarzeń FormCalc kompilują się do ograniczonego silnika i wspierają var, if/elseif/else, for z upto albo downto, while, foreach, func z niejawnymi wynikami, arytmetykę i porównania, konkatenację łańcuchów, agregację węzłów wildcard i niejawne przypisanie wartości pola
Biblioteka funkcji zdarzeń obejmuje Sum, Count, Avg, Min, Max, Round, typowe funkcje matematyczne, wycinanie łańcuchów, zmianę wielkości liter, przycinanie, podmianę, HasValue, Exists, Within, Oneof i Choose; nazwy wbudowane są niewrażliwe na wielkość liter, At(source, search) podąża za kolejnością argumentów XFA łącznie z zachowaniem pustego wyszukiwania, funkcje finansowe podążają za kolejnością parametrów XFA, a katalogi dat i finansów są opisane w FormCalc Functions
Mutacje skryptów są nagrywane wewnątrz silnika, walidowane i odtwarzane wewnątrz transakcji runtime; wyjątki, przerwanie, niepoprawny Unicode, niepoprawne operacje hosta i wyczerpane budżety nie publikują żadnych częściowych zmian dokumentu
Ogólne wykonanie skryptów pozostaje domyślnie wyłączone, nie używa przeglądarki ani procesu zewnętrznego i nie wystawia API systemu plików, sieci ani aplikacji; wywołujący może zamiast bridge'a dostarczyć JavaScriptEvaluator
Trwałe obiekty skryptowe
Obiekty script JavaScript wewnątrz elementu variables subformularza wystawiają swoje zmienne i funkcje przez nazwę skryptu; zmienne leksykalne, stan obiektów i zagnieżdżone domknięcia pozostają żywe przez sesję runtime, z zachowaniem normalnego cieniowania leksykalnego i dyrektyw strict
<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>
Kod zdarzeń może wywołać Helpers.next(); powtórzone wystąpienia subformularza posiadają niezależne obiekty skryptowe, a funkcje rozwiązują nazwane pola względem bieżącego żywego kontekstu formularza
Przechwycone węzły pól i menedżery podążają za stabilną tożsamością danych przez przeniesienia i publikację świeżo utworzonych instancji; dostęp do usuniętego węzła odrzuca zdarzenie i wycofuje stan jego modułu
Ogólne skrypty calculate i validate współdzielą sesję i obiekty skryptowe; JavaScript wspiera niejawne wartości ukończenia i jawne return, a FormCalc zwraca swoje ostatnie wyrażenie
Nieudane transakcje przywracają stan leksykalny i domknięć przez replay zapamiętanego wirtualnego dziennika, z nagranymi wejściami czasu i losowości; replay i bieżące wykonanie współdzielą deadline transakcji, a domyślne limity dziennika to 64 MiB skryptów/wyników i 8192 wpisów
Stan obiektów skryptowych żyje w sesji runtime i jest inicjalizowany ponownie po ponownym wczytaniu XDP; standardowe wartości dokumentu i nadpisania form nadal są trwałe przez SaveToBytes
Własne callbacki JavaScriptEvaluator zachowują istniejącą natywną powłokę calculate/validate; trwałą sesję dostarcza dostarczany silnik
Konfiguracja jawnego transportu hosta
Ustaw HostTransport i opcjonalne OnHostTransactionCompleted w TXFAWidgetRuntimeOptions, aby wykonywać dialogi hosta, drukowanie, nawigację, submission i transfer danych przez callbacki aplikacji
Jawny XFA Host Transport dostarcza xfa.host.messageBox, response, beep, print, gotoURL, submitForm, importData, exportData oraz FormCalc Get, Post i Put; aplikacja zwraca typowane wyniki i kontroluje efekty zewnętrzne
Ponowienia i replay sesji używają nagranych odpowiedzi, więc callbacki wykonują się raz na zdysponowane żądanie; zakończenie niepowodzeniem pozwala aplikacji wyrzucić wystage'owane efekty albo skompensować operacje odwracalne
Dodatnie HostTransportLimits ograniczają liczbę żądań, liczbę argumentów i zagregowane bajty żądań/odpowiedzi w otaczającej transakcji runtime
Wykonanie locale i obrazów picture
Ogólne zdarzenia FormCalc oraz skrypty calculate i validate wspierają funkcje locale i picture, w tym Format, Parse, zlokalizowane konwersje daty/czasu, jednostki, kodowanie, UUID i angielskie słowa liczbowe
Dynamiczny FormCalc Eval wykonuje dynamicznie dostarczane obliczenia z izolowanymi zmiennymi i funkcjami, względnym dostępem pól, kompilacją natywną, nagranymi odpowiedziami i transakcyjnym rollbackiem
Jawne referencje FormCalc wspierają przypisanie write-through, rebinding, odłączenie null, argumenty funkcji i stabilne uchwyty zapamiętane przez obiekty skryptowe podczas przenoszenia powtórzonych instancji
Żywe ścieżki SOM wspierają wywnioskowane, absolutne i względne indeksy wystąpień, selektory klas i potomków, przezroczyste kontenery, kandydackie predykaty i bezpośrednie indeksowane przypisanie FormCalc
Natywny Data DOM wystawia zbiory danych przez $data i $record, natychmiast synchronizuje zbindowane odczyty i zapisy form, mirruje powtórzone instancje i zachowuje zapamiętane referencje danych przez natywną publikację tożsamości
Natywny Property DOM wystawia zadeklarowane potomków wartości, fontów, UI i innych właściwości, synchronizuje typowane wartości pól i utrwala atrybuty per-instancja używane przez pomiar fontów i wspierane stylowanie flatten
Wykonywany węzeł dziedziczy swój najbliższy atrybut locale; wpisy localeSet dokumentu nadpisują systemowe symbole i wzorce, a wyliczone nazwy locale są rozwiązywane przez ograniczone wewnętrzne żądania i zachowywane w dzienniku sesji
Num2Date bez obrazu picture używa teraz otaczającego domyślnego wzorca daty; przekaż YYYY-MM-DD jawnie, gdy wymagane jest wyjście ISO
Model hosta utrzymujący stan
XFA Host Model dostarcza metadane aplikacji, rzeczywistą liczbę stron, nawigację stron, tytuł Unicode, flagi obliczania/walidacji, zakresowany reset i fokus pola z transakcyjnym cyklem życia enter/exit
TXFAWidgetRuntimeOptions.HostModel konfiguruje początkowy stan aplikacji; TXFAWidgetRuntime.HostModel zwraca bieżący stan, a nieudane zdarzenia przywracają go razem ze snapshotami dokumentu i interakcji
Przeniesienie fokusa bez skryptu enter/exit, oczekującej edycji albo zainicjalizowanego cyklu życia zmienia fokus bez uruchamiania obliczeń skryptowych ani przetwarzania deadline'ów; scriptowane przeniesienia fokusa i commity oczekujących edycji nadal używają transakcyjnych budżetów, walidacji i przeliczania
Zaawansowane klauzule picture wykonują się przez te same transakcje runtime, dziennik ponowień locale i cykl życia obliczeń, z ograniczonym parsowaniem złożonym
Inicjalizacja i utrzymanie cyklu życia
Wywołaj InitializeForm po skonfigurowaniu runtime i callbacków, aby wykonać zdarzenia initialize w kolejności szablonu, potem calculate i validate, zdarzenia form-ready i layout-ready; wywołanie jest idempotentne po sukcesie
Nowe instancje utworzone przez inicjalizację albo zdarzenia ready dostają własne zdarzenia initialize przed swoimi handlerami ready; wykonanie layout-ready powtarza się tylko przy zmianie layoutu, w budżetach reflow i transakcji
Po inicjalizacji udana dyspozycja zdarzenia i commit edycji inicjalizują świeżo utworzone instancje i wykonują calculate, validate i layout-ready; istniejące wystąpienia zachowują swój stan inicjalizacji przez przeniesienia i rollback transakcji
Niepowodzenia cyklu życia wycofują bajty dokumentu, interakcję widgetów i księgowość inicjalizacji razem, a callbacki publikują dopiero po sukcesie otaczającej transakcji
Zapis zaktualizowanego formularza
SaveToBytes zwraca kompletny zaktualizowany XDP runtime, włącznie ze zmodyfikowanymi zbiorami danych i standardowym stanem form per-instancja; zmiany presence parsera literałowego pozostają atrybutami szablonu; użyj tych bajtów z SetXFADocument przy zapisie PDF albo z HPDFXFAFlatten dla zaktualizowanego wyjścia flatten
Fabryka dokumentów załadowanych tworzy niezależny runtime, więc zdarzenia runtime nie modyfikują automatycznie grafu obiektów źródłowego PDF
Opcjonalny profil prezentacji instancji
Dynamic XFA Instance Presentation dodaje jawne powtórzone bindowania, stabilne ID per-instancja, indeksowane presence i dostęp, ograniczone zdarzenia warunkowe, malowanie host canvas i dostępność przez niezależny helper; domyślny runtime i jego ograniczona gramatyka zdarzeń pozostają zgodne
UpdateDocument dostarcza transakcyjne akcje dokumentowe; opcjonalne callbacki runtime właściwości, zakresu bindowania, tożsamości, rozpoczęcia rozwiązywania i walidacji dokumentu wspierają helper, a domyślne nil zachowuje istniejących wywołujących
Niższego poziomu API zdarzeń i formularzy
HPDFXFACompileFormCalcEvent kompiluje składnię zdarzeń; HPDFXFAExecuteJavaScriptEvent wykonuje wirtualny kontekst opisany przez TXFAEventBinding i TXFAEventBindings
TXFAJavaScriptSession dostarcza trwałe wykonanie i ograniczone checkpointy dla wywołujących niższego poziomu
Zwracane wartości TXFAEventAction używają TXFAEventActionKind; transakcyjny replay jest dostarczany przez runtime
HPDFXFAResolveFormInstanceNode i HPDFXFAResolveFormInstanceProperty dostarczają ograniczonego wyszukiwania w standardowym pakiecie form
Bieżące granice
Runtime to jednowątkowy obiekt hosta; GUI i malowanie pozostają odpowiedzialnością hosta albo opcjonalnego helpera prezentacji
Wspierany stan hosta, żywy DOM formularzy i cykl życia nie obejmują jeszcze każdej właściwości hosta Acrobat, obrazów picture z cyframi alternatywnych epok i zlokalizowanymi, synchronicznych zapytań dynamicznego reflow ani każdego operatora SOM
Zobacz Ograniczone FormCalc i JavaScript XFA, DOM pakietów XFA oraz Interaktywne przetwarzanie dokumentów