JavaScript Contexts in Acrobat¶
JavaScript for Acrobat can be placed in a variety of locations, both external to the document, and within the document. This chapter discusses how to determine the appropriate location for a script, and how to create and access the scripts.
The concept of a JavaScript event¶
All scripts are executed in response to a particular event. There are several types of events:
App: When the Viewer is started, the Application Initialization Event occurs. Script files, called Folder Level JavaScripts, are read in from the application and user JavaScript folders. See Folder level for additional details.
Batch: A batch event occurs during the processing of each document of a batch sequence.
Bookmark: This event occurs whenever a user clicks on a bookmark that executes a script.
Console: A console event occurs whenever a user evaluates a script in the console. See Executing JavaScript.
Doc: This event is triggered whenever a document level event occurs. For more information, see Document level.
External: This event is the result of an external access, for example, through OLE, AppleScript, or loading an FDF
field: This event is triggered when the user interacts with an Acrobat form, see Field level for more information.
Link: This event is triggered when a link containing a JavaScript action is activated by the user.
Menu: A menu event occurs whenever JavaScript that has been attached to a menu item is executed. In Acrobat 5.0 and later, the user can add a menu item and associate JavaScript actions with it.
Page: This event is triggered when the user changes pages in the document. See Page level for more information.
Screen: This event is triggered when the user interacts with a multimedia screen annotation.
These types of events may be initiated, or triggered, in a number of different ways, for example, in response to a mouse up, a mouse down, a keystroke, on focus, or on blur. These are referred to by the Acrobat JavaScript API Reference as the event names. Event types and names appear in pairs. For example, if an action is initiated by clicking a button, this would generate a Field type event, triggered by a mouse up event; consequently, we refer to such an event as a field/mouse up event.
The table that follows lists all event type/name combinations.
Event type/name combinations
Event type |
Event names |
---|---|
App |
Init |
Batch |
Exec |
Bookmark |
Mouse Up |
Console |
Exec |
Doc |
DidPrint, DidSave, Open, WillClose, WillPrint, WillSave |
External |
Exec |
Field |
Blur, Calculate, Focus, Format, Keystroke, Mouse Down, Mouse Enter, Mouse Exit, Mouse Up, Validate |
Link |
Mouse Up |
Menu |
Exec |
Page |
Open, Close |
Screen |
InView, OutView, Open, Close, Focus, Blur, Mouse Up, Mouse Down, Mouse Enter, Mouse Exit |
An event manifests itself in JavaScript as an Event object. Complete documentation for the different event types of events and the ways in which they can be triggered can be found in the description of the Event object in the Acrobat JavaScript API Reference.
About contexts¶
JavaScript for Acrobat can be placed at a variety of levels:
Folder level: Scripts placed here respond to App type events.
Document level: Scripts placed here respond to Doc type events.
Page level: Scripts placed here respond to Page type events.
Field level: Scripts placed here respond to Field type events.
Batch level: Scripts are placed here respond to Batch type events.
Each of these levels represents a context, or location, in which processing occurs. The list above is by no means a complete list of locations at which scripts can be placed.
The placement of a script at a given level determines its reusability. Folder level scripts are available within all documents, document level scripts are available to all form fields within a given document, field level scripts are visible to the form fields with which they are associated.
Note
For instructions on how to disallow changes to scripts or hide scripts, see Disallowing changes in scripts and Hiding scripts.
Folder level¶
Folder level scripts contain variable declarations and function definitions that may be generally useful to Acrobat, and are visible from all documents. Top level scripts, ones that are not contained in a function definition, are executed when the application is initialized.
There are two kinds of folder level scripts: App and User. For example, if you would like to add specialized menus and menu items to be available to all documents opened in Acrobat, you can store the code at the folder level.
Folder level scripts are placed in separate files that have the .js
extension. App folder level scripts are stored in the Acrobat application’s JavaScripts
folder, and user folder level scripts are stored in the user’s JavaScripts
folder. These scripts are loaded when Acrobat starts execution, and are associated with the event object’s Application Initialization.``App/Init``) event.
Note
The locations of these folders can be found by executing the following lines in the JavaScript Debugger Console:
// for App folder scripts
app.getPath("app", "javascript");
// for User folder scripts
app.getPath("user", "javascript");
When Acrobat is installed on your machine, it provides you with several standard folder level JavaScript files, including JSByteCodeWin.bin
(this file is a pre-compiled script that supports the forms and annotation plug-ins) and debugger.js
; these are in the App folder. Other JavaScript files in the App folder may be installed by third-party Acrobat plug-in developers.
The user folder may contain the files glob.js
and config.js
. The glob.js
file is programmatically generated and contains cross-session global variables set using the global
object’s setPersistent
method. The config.js
file is used to set user preferences or to customize the viewer UI by adding toolbar buttons or menu items. (See Adding toolbar buttons and menu items for more information on this topic.) Any file with an extension of .js
found in the user folder is also loaded by Acrobat during initialization, after it has loaded the files found in the App folder, and after it has loaded the config.js
and global.js
files.
To create folder level scripts, use an external editor running in parallel to Acrobat. Note that the external editor cannot be invoked from Acrobat for folder level scripts.
Document level¶
Document level scripts are variable and function definitions that are generally useful to a given document, but are not applicable outside the document.
Variable definitions: Define variables at the document level to make them visible to any executing script. For example,
var defaultUserColor = "red";
The variable defined above, which has an initial value of "red"
, may be changed as the user interacts with the document.
Function definitions: Define functions at the document level that support the user interaction with the document. These functions may be utility functions for handling common tasks for string or number manipulation, or functions that execute lengthy scripts called by actions initiated by a user interacting with Acrobat form fields, bookmarks, page changes, and so on.
To create or access document level scripts in Acrobat, select Tools pane > JavaScript > Document JavaScript, which enables you to add, modify, or delete document level scripts. Document level scripts are executed after the document has opened, but before the first Page Open event (See Page level). They are stored within the PDF document.
You can also create Doc level scripts programmatically using the addScript
method of the Doc object.
In addition to document level scripts, there are document action scripts that execute when certain document events occur. Such document events are
Document Will Close: This event is triggered before the document is closed.
Document Will Save: This event is triggered before the document is saved.
Document Did Save: This event is triggered after the document is saved.
Document Will Print: This event is triggered, before the document is printed.
Document Did Print: This event is triggered after the document is closed.
To access the JavaScript Editor for each of these document actions, select Tools pane > JavaScript > Set Document Action.
You can also create the document actions just described programmatically using the setAction
method of the Doc object.
Page level¶
Page level scripts are scripts that are executed when a particular page is either closed or opened.
Page Open: This event is triggered whenever a new page is viewed and after the drawing of the page has occurred.
Page Close: This event is triggered whenever the page being viewed is no longer the current page; that is, the user switched to a new page or closed the document. Page Close will occur before the Document Will Close event.
To create a page level script:
Click the Pages tab.
Right-click a thumbnail and select Page Properties.
Select the Actions tab from the Page Properties dialog box.
In the Select Trigger list, choose either Page Open or Page Close.
In the Select Action list, choose Run a JavaScript.
Click Add to open the JavaScript editor.
To access or delete a page level script:
Click the Pages tab.
Select the page by clicking the page thumbnail.
Right-click a thumbnail and select Page Properties.
Select the Actions tab from the Page Properties dialog box.
Select any of the actions listed in the Actions list.
Click Edit or Delete.
Other actions, as listed in the Select Action Menu of the Page Properties dialog box, can be created, accessed and deleted in the same way.
Page level scripts can also be created programmatically using the setPageAction
method of the Doc object.
Field level¶
Field level scripts are associated or attached to an Acrobat form field. Field events occur as the user interacts with the field, either directly or indirectly. Field scripts are typically executed to validate, format, or calculate form field values. Like document level scripts, field level scripts are stored within the PDF document.
There are several ways to create or edit field level scripts. The most straightforward manner is to right-click the form field, select the Properties context menu item and choose the Actions tab. Choose Run a JavaScript for Select Action and choose how to trigger the script from the Select Trigger Menu.
Field level scripts can also be created programmatically using the setAction
method of the Field object.
Privileged versus non-privileged context¶
Some JavaScript methods have security restrictions. These methods can be executed only in a privileged context which includes console, batch, and application initialization events. All other events (for example, page open and mouse-up events) are considered non-privileged. In the Acrobat JavaScript API Reference, methods with security restrictions are marked by an S in the third column of the quick bar.
The description of each security-restricted method indicates the events during which the method can be executed.
Beginning with Acrobat 6.0, security-restricted methods can execute in a non-privileged context if the document is certified by the document author for embedded JavaScript.
Security-restricted methods can also execute in a non-privileged context through the use of a trusted function introduced in Acrobat 7.0).
In Acrobat versions earlier than 7.0, menu events were considered privileged contexts. Beginning with Acrobat 7.0, execution of JavaScript through a menu event is no longer privileged. You can execute security-restricted methods through menu events in one of the following ways:
By enabling the preferences item named Enable Menu Items JavaScript Execution Privileges.
By executing a specific method through a trusted function introduced in Acrobat 7.0). Trusted functions allow privileged code—code that normally requires a privileged context to execute—to execute in a non-privileged context. For details and examples, see documentation of the
app.trustedFunction
method in the Acrobat JavaScript API Reference.
Executing privileged methods in a non-privileged context¶
To illustrate the techniques required, let’s work with a specific method, app.browseForFile
. According to the Acrobat JavaScript API Reference, this method can only be executed during batch or console events. This means that we are free to executed this method in the console, or to use it as a part of a batch sequence.
What happens when we execute this method in a non-privileged context? Create an Acrobat form button, and attach the following script as a mouse up JavaScript action.
var oRetn = app.browseForDoc({bSave: true});
After clicking the button, an exception is thrown; the console displays the following message:
NotAllowedError: Security settings prevent access to this property or method.
app.browseForDoc:1:Field Button1:Mouse Up
This shows that we have violated the documented security restriction.
If we really want this method in our workflow what do we need to do? We need to move this method to folder JavaScript and declare it as a trusted function. Why move it to the folder context? Because you can only declare a function trusted from a folder (console or batch) context.
Navigate to the user JavaScript folder and open the file config.js
in your text editor. Paste the following script into config.js
:
myTrustedBrowseForDoc = app.trustedFunction( function ( oArgs )
{
app.beginPriv();
var myTrustedRetn = app.browseForDoc( oArgs );
app.endPriv();
return myTrustedRetn;
});
For the syntax details of app.trustedFunction
, see the JavaScript for Acrobat API Reference. Note that the privileged script must be enclosed by the app.beginPriv
and app.endPriv
pair.
Save the file and restart Acrobat (folder JavaScript is read only at startup).
Now create a PDF with a single button on it. The script for that button is
try {
var oRetn = myTrustedBrowseForDoc({bSave: true});
console.println(oRetn.toSource());
} catch(e) {
console.println("User cancelled Save As dialog box");
}
Clicking the button now executes the app.browseForDoc
method without throwing the security exception.
In this example, we use the app.browseForDoc
and the Doc.saveAs
methods, both of which have security restrictions.
In config.js
, paste both the myTrustedBrowseForDoc
script listed above, and paste this script:
myTrustedSaveAs = app.trustedFunction( function ( doc, oArgs )
{
app.beginPriv();
var myTrustedRetn = doc.saveAs( oArgs );
app.endPriv();
return myTrustedRetn;
});
Note that the Doc object is passed to this trusted function. Now, revise the button described above to read as follows:
try {
var oRetn = myTrustedBrowseForDoc({bSave: true});
try {
myTrustedSaveAs(this, { cPath: oRetn.cPath, cFS:oRetn.cFS });
} catch(e) { console.println("Save not allowed, perhaps readonly."); }
} catch(e) { console.println("User cancelled Save As dialog box");}
Now, the PDF document, through a mouse up button action, can open a Save As dialog box and save the current document.
Executing privileged methods in a certified document¶
Many of the JavaScript methods in Acrobat are restricted for security reasons, and their execution is only allowed during batch, console or menu events. This restriction is a limitation when enterprise customers try to develop solutions that require these methods and know that their environment is secure.
Three requirements must be met to make restricted JavaScript methods available to users.
You must obtain a digital ID.
You must sign the PDF document containing the restricted JavaScript methods using the digital ID.
For details on where you can obtain digital IDs and the procedures for using them to sign documents, see Acrobat Help.
The recipient should trust the signer for certified documents and JavaScript.
For details, see Acrobat Help.
All trusted certificates can be accessed by selecting Certificates from Preferences > Signatures > Identities & Trusted Certificates > more in the Acrobat main menu.