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

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