PdfScriptHandler

What a viewer needs from a document's scripts, without knowing how they run.

kitepdf-javascript implements this over KiteJS, and a host may implement it over any other engine. The viewer talks to this interface only, so an app that shows PDFs does not carry a JavaScript engine unless it asks for one.

Every method is allowed to do nothing: a handler that runs no scripts is a valid handler, and a viewer with no handler behaves as it always did.

A viewer calls these methods off its drawing thread, one at a time and in the order the events happen, but not always from the same thread. A handler whose engine belongs to one thread moves each call there itself, as PdfScriptRunner does. hasTimers is the exception: a viewer reads it on its drawing thread every frame, so it must answer at once.

The calls that run scripts suspend. On the web a handler may pause a long script in them and let the page draw before it goes on (#489), so a viewer waits for each call before it makes the next. Everywhere else they run to the end before they return.

Properties

Link copied to clipboard
abstract val formState: PdfFormState

Where the form's live values are, which the viewer draws and the scripts write.

Link copied to clipboard
open val hasTimers: Boolean

True when a script is waiting on a timer.

Link copied to clipboard

True when commitChoice accepts an entire multiple selection as one transaction. An old string-only handler returns false, so a viewer can explain why it cannot edit a multiple selection instead of silently dropping its other values (ISO 32000-1, 12.7.4.4).

Functions

Link copied to clipboard
open suspend fun blur(fieldName: String)

A field lost the caret.

open suspend fun blur(fieldName: String, widgetIndex: Int)

One widget of a field lost the caret. See mouseDown with a widget.

Link copied to clipboard
open suspend fun choiceKeystroke(fieldName: String, selection: PdfChoiceSelection): PdfChoiceSelection?

Runs the selection-change keystroke without storing it. A viewer calls this for each proposed row, including deferred lists, then calls commitChoice when the reader commits (Adobe Acrobat JavaScript reference, Field/Keystroke and commitOnSelChange). Returns the accepted, possibly rewritten choice, or null when it was refused.

open suspend fun choiceKeystroke(fieldName: String, selection: PdfChoiceSelection, previous: PdfChoiceSelection): PdfChoiceSelection?

Runs a choice keystroke with the previous accepted draft as its event value. A deferred selection has not reached formState, so a viewer supplies it here for consecutive row changes. The default retains the two-argument custom-handler compatibility path.

Link copied to clipboard
open suspend fun commit(fieldName: String, value: String): Boolean

The reader finished with a field, so its value is committed: validate, store, recalculate and format. Returns false when a script refused the value.

Link copied to clipboard
open suspend fun commitChoice(fieldName: String, selection: PdfChoiceSelection): Boolean

Finishes a choice transaction after choiceKeystroke: commit keystroke, validate, store, calculate and format. This does not repeat the selection-change keystroke. Typed text in an editable combo instead runs ordinary keystroke calls before this commit.

Link copied to clipboard
open suspend fun documentOpened()

The document opened: run its own scripts and its open action.

Link copied to clipboard
open suspend fun focus(fieldName: String)

A field took the caret.

open suspend fun focus(fieldName: String, widgetIndex: Int)

One widget of a field took the caret. See mouseDown with a widget.

Link copied to clipboard
open suspend fun keystroke(fieldName: String, change: String, selectionStart: Int, selectionEnd: Int): String?

The reader typed into a field. change is what is being inserted, replacing the text between selectionStart and selectionEnd.

Link copied to clipboard
open suspend fun mouseDown(fieldName: String)

A pointer went down on a widget.

open suspend fun mouseDown(fieldName: String, widgetIndex: Int)

A pointer went down on one widget of a field: widgetIndex is its place in PdfFormField.widgets. Each button of a radio group, and each copy of a field on another page, has scripts of its own, so a handler that runs scripts runs that widget's (#359). The default passes the call on without the widget.

Link copied to clipboard
open suspend fun mouseUp(fieldName: String)

A pointer came up on a widget.

open suspend fun mouseUp(fieldName: String, widgetIndex: Int)

A pointer came up on one widget of a field. See the other mouseDown.

Link copied to clipboard
open fun onTimersChanged(listener: () -> Unit): () -> Unit

Calls listener when a script sets or clears a timer, from the thread the script runs on, and returns a function that stops the listening. A viewer pumps the timers only while one waits, so it learns here of a timer that a script set outside the viewer's own calls. The default reports nothing, and a viewer then checks hasTimers after each call it makes.

Link copied to clipboard
open suspend fun pageClosed(pageIndex: Int)

The reader left this page, for another page or because the view closed: run its close script. A viewer calls this before it opens the next page.

Link copied to clipboard
open suspend fun pageOpened(pageIndex: Int)

The reader landed on this page: run its open script. A viewer calls this when a scroll or a page turn settles on the page, with the page's index in the document.

Link copied to clipboard
open suspend fun prepare()

Gets the script engine ready. A viewer calls it once, before any other call: an engine that compiles itself on the web does so here, as a browser compiles only asynchronously. Until it returns, a call that needs the engine runs no script.

Link copied to clipboard
open suspend fun pumpTimers(nowMillis: Long): Long?

Runs the timers a script set that are due, and answers how long to wait before the next one, or null when none is waiting. nowMillis is the viewer's frame time. A handler may measure its timers on a clock of its own, as PdfScriptRunner does.

Link copied to clipboard
open suspend fun runAction(action: PdfAction.JavaScript)

The reader tapped something whose action is a script, such as a link.

Link copied to clipboard
open suspend fun runWidgetAction(fieldName: String, action: PdfAction): Boolean

The reader released a widget of fieldName whose /A entry holds action, or chains it through /Next (ISO 32000-1, 12.5.6.19). A viewer calls this once for each action of the chain, in order, and the chain takes the place of the widget's mouse up script (Table 194).