Accessibility

Adobe AIR Quick Start

 

Cross-scripting PDF content in an Adobe AIR application


Jeff Swartz

Jeff Swartz

Sr. Technical Writer
Adobe

Created:
25 February 2008
User Level:
Intermediate, Advanced
Products:
Adobe AIR

This Flex based PDF Control sample application loads a PDF file. You navigate through the file using user interface provided by HTML (not by the embedded PDF renderer). The zoom and navigation buttons are at the top of the application (see Figure 1).

The PDF Control sample application demonstrates the following features of working with PDF content in Adobe AIR:

  • Adding PDF content to an AIR application
  • Using Acrobat 8 to add JavaScript to a PDF file
  • Using ActionScript in an AIR application to communicate with document-level JavaScript in a PDF file

PDF Control application

Figure 1. This sample application enables you to load PDF files.

Note: This is a sample application provided, as is, for instructional purposes.

Requirements

To make the most of this article, you need the following software and files:

Adobe AIR

Adobe Flex Builder 3

Sample files:

This sample application includes the following files:

  • PDFControlFlex.mxml: The main application file in MXML for Flex; includes the code discussed in this article
  • PDFControlFlex-app.xml: The AIR application descriptor file
  • test.pdf: A sample PDF file loaded by the application
  • index.html: An HTML file loaded into the application
  • Sample AIR icon files

Prerequisite knowledge

General experience of building applications with Flex Builder or the Flex SDK is suggested. For more details on getting started with this Quick Start, refer to Building the Quick Start sample applications with Flex.

Understanding the code

Note: This article does not describe all of the Flex components used in the MXML code for the file. For more information, see the Flex 3 Language Reference.

The message handler JavaScript function in the PDF file

In document-level JavaScript in a PDF file, you can assign functions to the onMessage , onError, and onDisclose properties of the msgHandler property of the hostContainer object. These functions define how the PDF file handles messages sent to it from the host container.

The test.pdf file, included with the sample files, includes the following document-level JavaScript:

function myOnMessage(aMessage)
{
    if (aMessage.length==1) {
        switch(aMessage[0])
        {
            case "ZoomIn":
                zoom *= 2;
                break;
            case "ZoomOut":
                zoom /= 2;
                break;
            case "PageUp":
                pageNum--;
                break;
            case "PageDn":
                pageNum++;
                break;
            default:
                app.alert("Unknown message: " + aMessage[0]);
        }
    }
    else
    {
        app.alert("Message from hostContainer: \n" + aMessage);
    }
}
             
function myOnDisclose(cURL,cDocumentURL)
{
    return true;
}
             
function myOnError(error, aMessage)
{
    app.alert(error);
}
             
var msgHandlerObject = new Object();
msgHandlerObject.onMessage = myOnMessage;
msgHandlerObject.onError = myOnError;
msgHandlerObject.onDisclose = myOnDisclose;
             
this.hostContainer.messageHandler = msgHandlerObject;

This code defines functions for handling incoming messages. It sets these functions as the onMessage , onError , and onDisclose properties of an object, msgHandlerObject . The code assigns the msgHandlerObject object to the msgHandler property of the hostContainer object. The myOnDisclose() function checks the first string in the incoming message array, and takes the appropriate action. For example, if the string is "ZoomIn" , the code sets a PDF JavaScript property to zoom the page in: zoom *= 2.

This example application shows basic page navigation and display scale factor. Full details on other JavaScript extensions for Adobe Acrobat are provided at the Adobe Acrobat Developer Center.

Adding document-level JavaScript to a PDF file

Follow these steps:

  1. Create a PDF document named test.pdf and save it to the project directory for your application.
  2. Open the PDF in Acrobat 8.
  3. On the Advanced menu, select Document Processing > Document JavaScripts.
  4. In the JavaScript Functions dialog box, type myOnMessage as the Script Name, and then click the Add button.
  5. In the JavaScript Editor window, edit the text to match the following, and then click the OK button.

    function myOnMessage(aMessage)
    {
        if (aMessage.length==1) {
            switch(aMessage[0])
            {
                case "ZoomIn":
                    zoom *= 2;
                    break;
                case "ZoomOut":
                    zoom /= 2;
                    break;
                case "PageUp":
                    pageNum--;
                    break;
                case "PageDn":
                    pageNum++;
                    break;
                default:
                    app.alert("Unknown message: " + aMessage[0]);
            }
        }
        else
        {
            app.alert("Message from hostContainer: \n" + aMessage);
        }
    }
     
    function myOnDisclose(cURL,cDocumentURL)
    {
        return true;
    }
     
    function myOnError(error, aMessage)
    {
        app.alert(error);
    }
     
    var msgHandlerObject = new Object();
    msgHandlerObject.onMessage = myOnMessage;
    msgHandlerObject.onError = myOnError;
    msgHandlerObject.onDisclose = myOnDisclose;
     
    this.hostContainer.messageHandler = msgHandlerObject;

    For a description of this code, see the previous section.

  6. Close the JavaScript Functions dialog box.
  7. Select the File > Document Properties command.
  8. In the Document Properties dialog box, select the following options:

    • Navigation tab: Page Only
    • Page layout: Single Page
    • Maginfication: Default
    • Open to Page: 1
    • Hide menu bar: selected
    • Hide tool bars: selected
    • Hide window controls: selected
  9. Save the PDF document to your project directory, and name it test.pdf.

Loading the PDF content into the AIR application

AIR applications can render PDF content inside an HTMLLoader object. The Flex HTML component is a wrapper for an HTMLLoader object. The second-to-last line of the MXML code for the sample application is the following:

<mx:HTML id="pdfHtml" location="test.html" width="100%" height="100%" />

It loads an HTML page included with the application: test.html. In turn, the test.html page loads the PDF content, which is also included with the application: test.pdf. The following is the code of the HTML page:

<html>
    <body>
        <object id="PDFObj"
            data="test.pdf"
            type="application/pdf"
            width="100%"
            height="100%"/>
    </body>
</html>

Communicating with the JavaScript in the PDF file

The MXML code for the sample application defines four Button components:

<mx:Label text="Zoom:" width="75"/>
<mx:Button id="btn1" label="+" click="sendMessage('ZoomIn')" width="35" enabled="false"/>
<mx:Button id="btn2" label="-" click="sendMessage('ZoomOut')" width="35" enabled="false"/>
 
<mx:Label text="Navigate:" width="75"/>
<mx:Button id="btn3" label="&lt;" click="sendMessage('PageUp')" width="35"enabled="false"/>
<mx:Button id="btn4" label=">" click="sendMessage('PageDn')" width="35" enabled="false"/>

These buttons are disabled until the DOM the HTML component has initialized. The application calls the init() function (defined in the MXML code) is called when the applicationComplete event is dispatched:

private function init():void
{
    pdfHtml.htmlLoader.addEventListener(Event.HTML_DOM_INITIALIZE, htmlLoaded);
}
private function htmlLoaded(event:Event):void
{
    btn1.enabled=true;
    btn2.enabled=true;
    btn3.enabled=true;
    btn4.enabled=true;
}

When the user clicks any one of the Button components, the click event handler calls the sendMessage() method. For example, clicking the first button causes the following code to execute:

sendMessage('ZoomIn')

The sendMessage() method sets an object, pdfObj, to the PDFObj element in the HTML page. This is the object in the HTML DOM containing the embedded PDF content. You can send a message to the embedded PDF object by calling its postMessage() method. The postMessage() method takes an array of message strings as a parameter:

private function sendMessage(message:String):void
{
    try
    {
        var pdfObj:Object = pdfHtml.htmlLoader.window.document.getElementById("PDFObj");
        pdfObj.postMessage([message]);
    }
    catch (error:Error)
    {
        trace( "Error: " + error.name + "\nError message: " + error.message);
    }
}

The document-level JavaScript in the PDF file has a hostContainer.messageHandler object defined. This object determines how to processes the incoming message. (For details, see the section "The message handler JavaScript function in the PDF file" above.) In this application, the PDF content navigates or magnifies.

About the author

Jeff Swartz first worked at Macromedia (now Adobe Systems) in 1992. He is currently a technical writer for Adobe AIR. Jeff received a bachelor’s degree in Computer Science and Mathematics from the University of Illinois at Urbana-Champaign and studied at the Edinburgh University Department of Artificial Intelligence. Audiences around the San Francisco Bay Area have tolerated Jeff’s artistry on the trombone. He has served as Big Frank, a dancing hot dog, for Vienna Beef Ltd.