Adobe
Products
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
Student and Teacher Editions
More products
Solutions
Creative tools for business
Digital marketing
Digital media
Education
Financial services
Government
Web Experience Management
More solutions
Learning Help Downloads Company
Buy
Home use for personal and home office
Education for students, educators, and staff
Business for small and medium businesses
Licensing programs for businesses, schools, and government
Special offers
Search
 
Info Sign in
Welcome,
My cart
My orders My Adobe
My Adobe
My orders
My information
My preferences
My products and services
Sign out
Why sign in? Sign in to manage your account and access trial downloads, product extensions, community areas, and more.
Adobe
Products Sections Buy   Search  
Solutions Company
Help Learning
Sign in Sign out My orders My Adobe
Preorder Estimated Availability Date. Your credit card will not be charged until the product is shipped. Estimated availability date is subject to change. Preorder Estimated Availability Date. Your credit card will not be charged until the product is ready to download. Estimated availability date is subject to change.
Qty:
Purchase requires verification of academic eligibility
Subtotal
Review and Checkout
Adobe Developer Connection / Flash Developer Center /

Creating and packaging a professional JSFL command

by James O'Reilly

James O'Reilly
  • jamesor.com

Content

  • Creating a JSFL command
  • Creating an XUL dialog box to interface with your JSFL command
  • Creating an MXP installer for your JSFL command

Created

9 October 2006

Page tools

Share on Facebook
Share on Twitter
Share on LinkedIn
Bookmark
Print
extensibility Flash Professional JSFL

Requirements

Prerequisite knowledge

No prior understanding of JSFL is required. However, you should be familiar with the Flash authoring environment and how to use invisible buttons in your movies.

User Level

Intermediate

Required products

  • Flash Professional 8 (Download trial)

Sample files

  • invisible_button.zip (4 KB)

Macromedia Extension Manager

  • Free download

One of the many nice things about the Flash authoring environment is its extensibility. If there is something missing that would really make your development easier and less tedious, you can extend the authoring environment to include almost anything you imagine by creating new panels, components, tools, behaviors, and commands.

One of the simplest ways to extend Flash is by writing scripts using JavaScript Flash (JSFL). JSFL commands are similar to how you might extend other applications with macros. They are external scripts stored as a text file and interpreted by Flash at design-time when you run them.

In this tutorial, you will create a JSFL command, a user interface to the command, and a cross-platform package so that you can distribute the command for others to install.

Creating a JSFL command

All banner ads have one thing in common: When you click the ad, you go to another website. Flash banners are no exception. Some of the cooler Flash ads let you interact with them briefly before carting you off to their site. The majority of ads, however, simply accept a user click anywhere on the ad. The industry standard way of doing this is by creating an "invisible button," which is simply a button that has only a hit state and cannot be seen. This button is usually the same size of the Stage, is placed on the bottommost layer of your FLA file, and handles mouse down events not captured by buttons lying on top of it.

Having created a lot of Flash banner ads in my time, I grew tired of adding invisible buttons to each project I worked on. Then it dawned on me: Wouldn't it be cool if there was a command to do this for me?

Planning the project

Let's sum up the feature list for this new command:

  • A button is added to the Library named "invisible"
  • The button contains a rectangle shape on the Hit Area frame
  • The button is placed on the Stage in a new layer named "Button"
  • The button is resized to match the size of the Stage and is moved to 0,0
  • ActionScript is added to the button for interactivity
  • When clicked, a dialog box opens for command options
  • The new command appears in the Commands menu of the Flash authoring environment

Now that you know what you are building, you can break it down into a series of steps that you'll build upon.

Creating a working space

Create a folder on your desktop named My Commands. This folder can be anywhere, really, but it'll be easier to follow if we have it in the same place. Open Flash, select File > New, and choose Flash JavaScript File in the New Document dialog box. Save this file to your My Commands folder as Invisible Button.jsfl, but don't close it just yet because we'll be writing to it.

Note: Double-clicking a JSFL file does not open the script for editing in Flash. Instead, the Flash authoring environment tries to run the command. To edit a JSFL file, you need to open it from within Flash.

Adding DOM references to your command

After you save your document, add some test code to make sure things are running properly. Type the following code into your "Invisible Button.jsfl" document:

var flash_doc = fl.getDocumentDOM(); // Document object reference var flash_lib = flash_doc.library; // Library object reference var flash_tl = flash_doc.getTimeline(); // Timeline object reference var flash_w = flash_doc.width; // Document width var flash_h = flash_doc.height; // Document height fl.trace("flash_doc: " + flash_doc); fl.trace("flash_lib: " + flash_lib); fl.trace("flash_tl: " + flash_tl); fl.trace("flash_w: " + flash_w); fl.trace("flash_h: " + flash_h);

You'll notice that I didn't use strict typing for my variables. This is because we are coding with JavaScript. It's easy to forget this and think you are coding with ActionScript because of the similar syntax and ActionScript-like methods such as trace().

Now save your document and create a new Flash document by choosing File > New > Flash Document. If your defaults are unchanged, you should now have an empty movie that is 550 × 400 pixels in size.

Let's test our new command and see how it works. With the empty Flash document in focus, run the command by choosing Commands > Run Command. You will be presented with an Open File dialog box. Simply browse for and select the "Invisible Button.jsfl" file you just created and click Open. If the command executes properly, your Output window should open and trace five lines from the script, as follows:

flash_doc: [object Document] flash_lib: [object Library] flash_tl: [object Timeline] flash_w: 550 flash_h: 400

Creating symbols in the Library

Start adding some features from our list. Skip the dialog box for now and begin with the invisible button. Add a Button item to the Library with the name invisible:

var symbolname = "invisible"; flash_lib.addNewItem("button", symbolname);

The addNewItem(type [,namePath]) method of the Library object enables you to add any new type to the Library, such as button or movie clip, and assign it a name. The first parameter is the type—in our case, "button". The second parameter is the name for our symbol; name it "invisible".

Save the JSFL document and open the empty FLA file you have been using for testing. Run the command the same way we did earlier; you will see a new button symbol added to your Library.

Overachievers who clicked the command twice may have noticed a slight bug. Running the command a second time gives you an error message: "The name invisible is already taken. Please use a different name." There are a number of ways to solve this issue. I'm going to assume a few things:

  • I'm writing this tool for myself to use and not to resell
  • I'll likely know if I already have an invisible button before clicking the command
  • If I know I have an invisible button already and I click anyway, I likely want to replace it with a new one

Your assumptions may be different than mine so you may choose to loop through incremented names until you find one that's not already taken. For the sake of this tutorial, but mostly because I'm the one writing it, we'll go with my assumptions and choose to delete the existing version of the invisible button. Here's how:

var symbolname = "invisible"; // Check the library to see if the symbol already exists // if it does delete it while (flash_lib.itemExists(symbolname)) { flash_lib.deleteItem(symbolname); } // Add the new symbol to the library flash_lib.addNewItem("button", symbolname);

Simple enough, right? We now have the button symbol in the Library and correctly named, so we can scratch the first item off our feature list.

Editing Library symbols

We now have an empty button. What you need to do next is add a rectangle shape to its Hit Area frame. The way to do this is by entering Edit mode, draw on the Stage, and exit Editing mode.

To edit a symbol in the Library, call the editItem([ namePath ]) method of the Library object and pass it the name of the symbol you wish to edit:

flash_lib.editItem(symbolname);

Doing this has pretty much the same effect as if you were to double-click the symbol in the Library and open it for editing. The exitEditMode() method of the Library object closes the symbol and returns you to the Stage. Wait until after you draw to implement the Exit method.

Drawing in a symbol

Now you need to implement some drawing while you have the symbol in Edit mode. To do this, obtain a reference to the current Timeline. Keep in mind that the reference you already stored as flash_tl is a reference to _root's timeline. Once you enter Edit mode on a symbol, the timeline changes to that of the symbol. To establish a reference to the symbol's timeline, grab it the same way you did for _root:

button_tl = flash_doc.getTimeline();

This can become confusing because it's the exact same call. It's important that you understand and pay attention to the context of this call. Know which timeline you are viewing when you grab a reference to it. Because the previous line of code was a call to editItem, you know which timeline you are viewing.

You want to edit the Hit Area frame of the button, so you need to have a keyframe on frame 3:

button_tl.insertKeyframe(3); button_tl.currentFrame = 3;

Note: Frames are zero-based, so the frame at index 3 is actually the fourth frame. A button's four frames are labeled Up, Over, Down, and Hit—in that order.

By setting the Timeline object's currentFrame property to 3, you move the playhead to that frame. Any drawing you do will be on the Stage at this frame. However, the drawing isn't done on the Timeline's object reference; it's done on the document's object reference:

flash_doc.addNewRectangle({left:0, top:0, right:flash_w, bottom:flash_h}, 0); flash_doc.selectAll(); flash_doc.breakApart(); flash_doc.setFillColor("#000000"); flash_doc.setStroke("#00000000", 1, "solid"); flash_doc.selectNone();

You've successfully drawn a rectangle on the Hit Area frame of your invisible button symbol. Now you can exit Editing mode and scratch off feature #2 from the list:

flash_doc.exitEditMode();

Adding a symbol to the Stage

The invisible button is now complete so you can add it to the Stage on the timeline of _root (or _level0). Do this by calling the addNewLayer([name] [,layerType [,bAddAbove]]) method of your flash_tl timeline object reference. This method returns an ID which you will use to select the layer:

// Create a new layer for this symbol and rename it to button var layerNum = flash_tl.addNewLayer(); flash_tl.setSelectedLayers(layerNum, true); flash_tl.setLayerProperty("name", "button");

The setLayerProperty(property, value [,layersToChange]) method of the Timeline object enables you to set the name of the layer to button.

Now that you have the layer both named and selected, you can add symbol instances to it:

// Place the button on the stage and add the actionscript flash_lib.addItemToDocument({x:flash_w/2, y:flash_h/2}, symbolname);

Using the Library object reference, place the invisible button symbol on the Stage using the addItemToDocument(position [,namePath]) method. By adding an item to the document, it automatically becomes selected. Since you know it's the only thing selected, you can simply reference index zero of the selection array.

Next, add ActionScript to the button click. (_root.clickTag is a variable that most media placement companies like DoubleClick use for passing URLs into the SWF. Some companies use _root.clickTAG, so be sure to get the proper case from your vendor, because case matters.) These values are hard-coded for now but will be part of the Options dialog box in the Phase 2 of this tutorial:

flash_doc.selection[0].actionScript = "on (release) {\n\tgetURL(_root.clickTag, \"_blank\");\n}"; flash_doc.selectNone();

Notice the backslashes (\) in the above script. They escape the character that follows them, which tells the JSFL interpreter to treat the next character in a special way. In this example, \n tells the interpreter you want a "new line", \t means you want a tab character to indent the new line, and \" means you want a quote mark. (If you don't escape the quote, the interpreter might think you are tring to end the string!) When the command is run and the ActionScript is placed in the movie, the final output looks like this:

on (release) { getURL(_root.clickTag, "_blank"); }

You've now completed features #3, #4, and #5 on the list. Save and run your command to see it in action!

Phase 1 of the JSFL command

Here is the current state of the JSFL code in its entirety. This code reflects the items I've discussed up to this point and will change as you continue this tutorial:

/** * Invisible Button.jsfl (phase 1 of 3) * JSFL Command that adds an invisible button to the library of an open * FLA and places that button on to the current timeline at the height * and width of the stage. * * Author: James O'Reilly - JOR * www.jamesor.com * * This work is licensed under the Creative Commons attribution 2.5 * This comment block must remain intact. */ var flash_doc = fl.getDocumentDOM(); var flash_lib = flash_doc.library; var flash_tl = flash_doc.getTimeline(); var flash_w = flash_doc.width; var flash_h = flash_doc.height; var symbolname = "invisible"; // Check the library to see if the symbol already exists // if it does delete it while (flash_lib.itemExists(symbolname)) { flash_lib.deleteItem(symbolname); } // Add the new symbol to the library flash_lib.addNewItem("button", symbolname); flash_lib.editItem(symbolname); // Draw the button button_tl = flash_doc.getTimeline(); button_tl.insertKeyframe(3); button_tl.currentFrame = 3; flash_doc.addNewRectangle({left:0, top:0, right:flash_w, bottom:flash_h}, 0); flash_doc.selectAll(); flash_doc.breakApart(); flash_doc.setFillColor("#000000"); flash_doc.setStroke("#00000000", 1, "solid"); flash_doc.selectNone(); // Exit edit mode and add the symbol to the stage flash_doc.exitEditMode(); // Create a new layer for this symbol and rename it to button var layerNum = flash_tl.addNewLayer(); flash_tl.setSelectedLayers(layerNum, true); flash_tl.setLayerProperty("name", "button"); // Place the button on the stage and add the actionscript flash_lib.addItemToDocument({x:flash_w/2, y:flash_h/2}, symbolname); flash_doc.selection[0].actionScript = "on (release) {\n\tgetURL(_root.clickTag, \"_blank\");\n}"; flash_doc.selectNone();

Creating an XUL dialog box to interface with your JSFL command

In this section I discuss creating a dialog box using XML and associating it with the invisible button command.

This dialog box will show a list of options that the developer (or just you) can customize when using the new command. Here are the options to implement:

  • Enter a URL for the button
  • Choose whether the URL entered is a variable name or a string
  • Enter in the target window for the URL

Creating the XUL dialog box

In your My Commands folder, or whatever folder contains the "Invisible Button.jsfl" file, create an empty text document named Invisible Button.xml. We'll keep the name the same as the command—except for the extension—in this tutorial, but this doesn't need to be the case. You can name this file anything you want. You can even use multiple XML files per command in case you want to make a complex interface. The XML is parsed with an XML-to-UI engine that uses a subset of the XML User Interface Language (XUL) plus some additional Flash-only tags. You can see the full documentation in the Flash LiveDocs.

Open this empty XML document in the text editor of your choice so you can add the following content to it:

<?xml version="1.0"?> <dialog title="Invisible Button" buttons="accept,cancel"> </dialog>

Here we define the dialog box as having the title "Invisible Button" and adding OK and Cancel buttons to the form. Because you'll want to tweak your form and see how it looks as you build it, open it from within your command:

var flash_doc = fl.getDocumentDOM(); var flash_lib = flash_doc.library; var flash_tl = flash_doc.getTimeline(); var flash_w = flash_doc.width; var flash_h = flash_doc.height; // Be sure to set this path to match your setup var result = flash_doc.xmlPanel("file:///C:/Documents and Settings/Username/Desktop/My Commands/Invisible Button.xml"); // rest of the code follows

By using the xmlPanel(fileURI) method of the Document object, you can open the XML file you just created. The URI format for this method uses a string expressed as a file:/// URI. It must be a full path to the file; relative paths will not work. Please make sure this path is correct for your machine. In the section "Creating an MXP installer for your JSFL command," you'll learn how to reference the folder to which you install the finished command. Save your files and click your command to see the Invisible Button dialog box open (see Figure 1).

XUL dialog box with OK and Cancel buttons
Figure 1. XUL dialog box with OK and Cancel buttons

Clicking either of the two buttons returns you to your JSFL script a result object, which you store in a variable cleverly named result. This object's dismiss property is the only predefined property and have a value of either "accept" or "cancel". The other properties will be defined by you in your XML file:

... var result = flash_doc.xmlPanel("file:///C:/Documents and Settings/Username/Desktop/My Commands/Invisible Button.xml"); if (result.dismiss == "accept") { var symbolname = "invisible"; ... flash_doc.selectNone(); }

If you now run your command, you will notice that clicking OK adds the invisible button to the movie and clicking Cancel does nothing, as it should.

Adding a form to the XUL dialog box

Take a look at the XML file. Open "Invisible Button.xml" in your text editor and start adding controls to the form. Each of the controls you add will, in turn, become properties of the xmlPanel's result object (see Figure 2).

XUL dialog box with form elements neatly laid out
Figure 2. XUL dialog box with form elements neatly laid out

Let's start with the layout controls. Use the <grid> container so that you can lay out your controls in a column/row format. As you can see, we need the form to be two columns wide: one for the field names and the other for the fields themselves. Since there are three form elements, and we have one per line, we'll need three rows.

The format is different than the <table> container you might expect from HTML. The <grid> container always contains exactly two children: <columns> and <rows>.

The <columns> container has two empty <column/> tags to let the engine know that each row contains two columns. When the engine parses a <row> tag, it puts the first element in the first column and the second element in the second column. For example, the first element in each row is a <label> control to display the name of the input control. The second element in each row is the input control. Finally, after the grid there's a <separator/> tag which draws a line between the form and its buttons.

This is how the complete "Invisible Button.xml" file should look:

<?xml version="1.0"?> <dialog title="Invisible Button" buttons="accept,cancel"> <grid> <columns> <column/> <column/> </columns> <rows> <row> <label value="URL:" /> <textbox id="url" tabindex="1" value="_root.clickTag" multiline="false" maxlength="100" /> </row> <row> <label value="URL Type:" /> <radiogroup id="type" tabindex="2"> <radio label="Variable" selected="true" /> <radio label="String" /> </radiogroup> </row> <row> <label value="Target:" /> <textbox id="target" tabindex="3" value="_blank" multiline="false" maxlength="20" /> </row> </rows> </grid> <separator/> </dialog>

Each input control has an "id" attribute which becomes a property with the same name in the result object returned from xmlPanel(). This is how you will access the user-defined values in your JSFL file.

Save your updated XML file and run the command. You should now see the form, although none of the options actually has an affect on the button you are creating. You'll do that in the next step.

Updating your JSFL command

Now that you have the form laid out correctly, it's pretty simple to access its properties. Just access the property you need from the result object. To see the form work and the properties it returns, add this bit of code to our JSFL file:

... var result = flash_doc.xmlPanel("file:///C:/Documents and Settings/Username/Desktop/My Commands/Invisible Button.xml"); // Add these three lines here to see all of the available // properties of the result object for (var prop in result) { fl.trace("property " + prop + " = " + result[prop]); } if (result.dismiss == "accept") { ...

Your output window should display something similar to the following:

property url = _root.clickTag property type = Variable property target = _blank property dismiss = accept

Using these newly created properties, you can make the JSFL command respond to the options selected in the dialog box.

Phase 2 of the JSFL command

Here is the current state of the JSFL file. The code reflects the items I've discussed up to this point and will change as you continue this tutorial:

/** * Invisible Button.jsfl (phase 2 of 3) * JSFL Command that adds an invisible button to the library of an open * FLA and places that button on to the current timeline at the height * and width of the stage. * * Author: James O'Reilly - JOR * www.jamesor.com * * This work is licensed under the Creative Commons attribution 2.5 * This comment block must remain intact. */ var flash_doc = fl.getDocumentDOM(); var flash_lib = flash_doc.library; var flash_tl = flash_doc.getTimeline(); var flash_w = flash_doc.width; var flash_h = flash_doc.height; // Be sure to set this path to match your setup var result = flash_doc.xmlPanel("file:///C:/Documents and Settings/Username/Desktop/My Commands/Invisible Button.xml"); if (result.dismiss == "accept") { // Make sure the result values are valid // and use defaults if they are not var mUrl = result.url; if (mUrl == "") mUrl = "_root.clickTag"; else { // If we are setting the URL to a string instead of // using a variable name then we need to quote the url. if (result.type == "String") mUrl = "\"" + mUrl + "\""; } var mTarget = result.target; // Additional Local Variables var symbolname = "invisible"; // Check the library to see if the symbol already exists // if it does, create a new one with the next highest // number while (flash_lib.itemExists(symbolname)) { flash_lib.deleteItem(symbolname); } // Add the new symbol to the library and enter edit mode flash_lib.addNewItem("button", symbolname); flash_lib.editItem(symbolname); // Draw the button button_tl = flash_doc.getTimeline(); button_tl.insertKeyframe(3); button_tl.currentFrame = 3; flash_doc.addNewRectangle({left:0, top:0, right:flash_w, bottom:flash_h}, 0); flash_doc.selectAll(); flash_doc.breakApart(); flash_doc.setFillColor("#000000"); flash_doc.setStroke("#00000000", 1, "solid"); flash_doc.selectNone(); // Exit edit mode and add the symbol to the stage flash_doc.exitEditMode(); // Create a new layer for this symbol and rename it to button var layerNum = flash_tl.addNewLayer(); flash_tl.setSelectedLayers(layerNum, true); flash_tl.setLayerProperty("name", "button"); // Place the button on the stage and add the actionscript flash_lib.addItemToDocument({x:flash_w/2, y:flash_h/2}, symbolname); flash_doc.selection[0].actionScript = "on (release) {\n\tgetURL("+mUrl+", \""+mTarget+"\");\n}"; flash_doc.selectNone(); }

Creating an MXP installer for your JSFL command

This section explains how to update the Invisible Button command so that you can use a relative installation path to locate your XML form. I also describe how to create an installer file (MXI) and package it (MXP) using Macromedia Extension Manager so that you can distribute your commands to the Flash community.

There are three things to accomplish in this tutorial:

  1. Modify the JSFL command to use a relative installation path to find the XML UI dialog box.
  2. Create an MXI file with instructions on how to package your command.
  3. Package your extension using Extension Manager.

Update the JSFL command's XUL dialog box path

Open the "Invisible Button.jsfl" file from the My Commands folder on your desktop.

The fl object contains a property called configURI. This property contains the file URI for the location of the current user's Flash configuration. Each machine user has a unique URI which, in Windows, is typically something similar to file:///C|/Documents and Settings/Username/Local Settings/Application Data/Macromedia/Flash 8/en/Configuration/. Inside this folder, you'll find the Commands folder, which contains files for any custom commands you might have installed already.

This is the folder you'll be targeting when you create your package, so change the xmlPath() to point to this folder when looking for the "Invisible Button.xml" file. To do that, simply change the beginning of your "Invisible Button.jsfl" script to read as follows:

var flash_doc = fl.getDocumentDOM(); var flash_lib = flash_doc.library; var flash_tl = flash_doc.getTimeline(); var flash_w = flash_doc.width; var flash_h = flash_doc.height; fl.trace(fl.configURI); var result = flash_doc.xmlPanel(fl.configURI + "/Commands/Invisible Button.xml");

We added the trace() function so that you could easily find out the exact folder you are targeting on your machine. You can remove this line after you find your folder. Create a new empty Flash document so that you can test this modified command (the Commands menu is available only when a FLA is open and in focus).

If you run the command, two things should happen. First, you should get an error (see Figure 3). Second, the Output window should display and print the fl.configURI for you to examine.

XML file cannot be found at the new path location
Figure 3. XML file cannot be found at the new path location

The error is expected because you do not yet have your XML file located in this new folder. The trace() finds the correct location to copy your XML file to. Read the path printed in the Output window and then open that folder however you wish. Then look for the Commands folder and open it. Copy only the "Invisible Button.xml" file into that Commands folder and run your command again. This time you should not get an error and the command should function as expected. You can now delete the trace() command at this point; you won't be needing it any longer.

Creating a cross-platform installer (MXI)

Using your favorite text or XML editor, create a new document in your My Commands folder on your desktop called Invisible Button.mxi. Below is a basic template you can copy into this file:

<macromedia-extension type="flash command" version="1.0.0" requires-restart="false" name="Invisible Button"> <!-- children will go here --> </macromedia-extension>

This is a starting point for the MXI that you'll be building on. Notice that the root node, <macromedia-extension>, has a number of settable attributes. The first attribute, type, defines the type of extension we are adding. For a complete list of extension types and further documentation on extensions, read The Extension Installation File Format (PDF, 420KB) . The second attribute, version, defines the version number for your extension. requires-restart indicates whether Flash needs to be restarted after the installation; it doesn't, for a command. You can look up other types of extensions for their requirements. The last attribute is name, the name of the command.

Inside the <macromedia-extension> node are a few child nodes that define the information displayed inside Extension Manager after users install the extension. The first node, <author>, defines the author's name as displayed inside Extension Manager:

<author name="James O'Reilly" />

The second node, <product>, defines the product that the extension will be installed to. This is because the MXI format is used across many Macromedia (now Adobe) products. Extension Manager needs to know which one to install to. Extension manager will install to the version indicated, or later:

<products> <product name="Flash" version="8" primary="true" /> </products>

The next node defines the product's description:

<description> <![CDATA[Creates an invisible button and places it on the document in a new layer named "button" and automatically assigned a getURL call. The button is created as a symbol called "invisible".]]> </description>
The next node defines how the extention is accessed from within the product. In our example, the user would need to go to the Commands menu and select the command from there. A common notation for that is "Commands > Invisible Button", which is what we'll use here. Type anything you see fit for your situation:
<ui-access> <![CDATA[Commands > Invisible Button]]> </ui-access>

The next node defines any legal information you wish to display. It will be prompted for the user to accept before installating the extension:

<license-agreement> <![CDATA[CDATA[James O'Reilly provides this extension 'as is' without any warranty of any kind as to the suitability of the extension for the licensees intended purpose. All risk as to the performance of the extension and it's contents are the sole responsibility of you, the licensee.]]> </license-agreement>

Last comes the node that defines all the files that make up this extension. The source attribute defines the location of the file and the destination attribute defines the location of the installation. To install to the Commands folder, you can target that folder like this: $Flash\commands (case must match the actual folder name). Two files make up your installation, so you need to include both. Because this MXI file is in the same folder as the JSFL and XML files, the source doesn't need to list a path:

<files> <file source="Invisible Button.jsfl" destination="$Flash\commands" /> <file source="Invisible Button.xml" destination="$Flash\commands" /> </files>

Note: If this isn't the case, you can use relative paths as needed.

Creating a package (MXP)

After you create your MXI file, open Extension Manager. (If your Flash installation does not come with this program, you can download it for free.) From inside Extension Manager, select File > Package Extension and browse to the "Invisible Button.mxi" file you just created. When prompted, save the "Invisible Button.mxp" file to the same folder.

To install your new extension, select File > Install Extension from the Extension Manager menu. Browse to the newly created "Invisible Button.mxp" file. You will be prompted with a legal agreement. If you scroll down to the bottom, you'll see the additional legal information you added in your MXI file. Click OK to install. You're done! You'll see your new extension added to the list of currently installed Flash extensions in the Commands menu. Go ahead and create a new document and test your new command.

To distribute this extension, simply give out the MXP file. It contains all the necessary files others need to install the extension in Flash.

Where to go from here

In this tutorial you've gone down a path which started at planning a project and ended at creating a polished installer for professional distribution. From a high-level view, you divided the project into three parts: command, interface, and installer. As you delved into each part, you further divided the tasks into smaller goals while testing your progress along the way.

Here are just a few ideas to help get you started writing your own JSFL commands:

  • Sometimes it's beneficial to place symbols on the Stage at exact, whole-pixel coordinates. One command might be to move all currently selected symbols and reposition them by rounding their current x and y locations.
  • You can achieve really nice text effects by writing commands that break apart text on the Stage and distribute or transform each letter over time.
  • Simplify your ActionScript writing by automatically inserting code snippets like getters/setters or creating documentation from your comments.

A good book to read is Extending Macromedia Flash MX 2004 by Keith Peters and Todd Yard. It has comprehensive coverage of Flash extensions.

I also recommend checking out Peter Elst's article, Automating Tasks with JavaScript Flash. Peter covers JSFL basics and the new Filter object in Flash 8.

I always like to hear from people. Feel free to contact me with any questions or suggestions you might have. The best place to contact me is at my blog, www.jamesor.com. Happy coding!

More Like This

  • Introducing the JSFL File API
  • Creating the Kuler panel for Flash CS3 Professional
  • Using the External API for Flash–JavaScript Communication
  • Automating tasks with JavaScript Flash

Flash User Forum

More
04/23/2012 Auto-Save and Auto-Recovery
04/23/2012 Open hyperlinks in new window/tab/pop-up ?
04/21/2012 PNG transparencies glitched
04/01/2010 Workaround for JSFL shape selection bug?

Flash Cookbooks

More
02/13/2012 Randomize an array
02/11/2012 How to create a Facebook fan page with Flash
02/08/2012 Digital Clock
01/18/2012 Recording webcam video & audio in a flv file on local drive

Products

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • Mobile Apps
  • Photoshop
  • Touch Apps
  • Student and Teacher Editions

Solutions

  • Digital marketing
  • Digital media
  • Web Experience Management

Industries

  • Education
  • Financial services
  • Government

Help

  • Product help centers
  • Orders and returns
  • Downloading and installing
  • My Adobe

Learning

  • Adobe Developer Connection
  • Adobe TV
  • Training and certification
  • Forums
  • Design Center

Ways to buy

  • For personal and home office
  • For students, educators, and staff
  • For small and medium businesses
  • For businesses, schools, and government
  • Special offers

Downloads

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

Company

  • News room
  • Partner programs
  • Corporate social responsibility
  • Career opportunities
  • Investor Relations
  • Events
  • Legal
  • Security
  • Contact Adobe
Choose your region United States (Change)
Choose your region Close

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

Terms of Use | Privacy Policy and Cookies (Updated)

Ad Choices

Reviewed by TRUSTe: site privacy statement