Introduction To Developing Fireworks Extensions (They’re Just JavaScript!)
One of the most powerful features of Adobe Fireworks is that you can extend its functionality. Almost anything you can do through Fireworks’ interface — and even some things that you can’t — can also be achieved by writing a simple JavaScript extension.
Fireworks extensions are of two main types: commands and command panels. If you find yourself repeatedly performing a tedious task, you could write a command to automate the process and save yourself a lot of time. Alternatively, if you are missing a particular feature that would improve your workflow, you could write a more complex extension — a command panel — to implement it.
I learned to develop Fireworks extensions by writing the Specctr plugin. While working on Specctr, I’ve witnessed Fireworks’ passionate community actively support the app — an app that has been widely overlooked by Adobe. (Sadly, Fireworks CS6 is the last major release from Adobe, but it is still available as a standalone application and through Creative Cloud. Adobe plans to support Fireworks at least through the next major releases of Mac OS X and Windows OS and to release bug fixes and patches for it.)
Although Fireworks is an excellent screen design tool out of the box, it has benefited greatly from contributions from the Fireworks community — namely, developers such as John Dunning, Aaron Beall and Matt Stow, among others, who have written many indispensable extensions, such as SVG Import and SVG Export (which add full-featured SVG support to Fireworks), Generate Web Assets, CSS Professionalzr (which extends the features of the CSS Properties panel to Fireworks CS6) and many more.
Now that we can’t expect Adobe to add any more features to Fireworks, the ability to extend the app becomes even more important, because many designers still rely on it (while looking for alternatives, of course, such as Sketch 3.0), and through extensions, new features and panels can be added. This article is aimed at those interested in developing extensions for Fireworks. We’ll introduce the JavaScript underpinnings of Fireworks and, in the process, write a few JavaScript examples to get you started.
Do You Speak JavaScript? Fireworks Does!
Fireworks speaks JavaScript. It exposes a JavaScript application programming interface (API) via Fireworks’ document object model (DOM), which represents its constituent parts and functions. That’s a long way of saying that you can write JavaScript to tell Fireworks what to do.
Fireworks lets you run the JavaScript in two basic ways: commands and command panels.
Commands
The first option is to execute JavaScript as commands. Commands are simple text files that contain JavaScript and that are saved with a .jsf
extension. To make them available from the “Commands” menu in Fireworks, you must save them in the <Fireworks>/Configuration/Commands/
directory (where <Fireworks>
is a stand-in for the installation directory of Adobe Fireworks on your computer — see “A Note on Locations” below).
Command Panels
The second option is to build a command panel. Command panels are Flash panels powered by ActionScript, which in turn can call JavaScript code to boss Fireworks around. Fireworks has an embedded Flash player and can run these panels. The panels are in SWF format and should be saved in the <Fireworks>/Configuration/Command Panels/
directory so that they can be accessed from the “Window” menu in Fireworks.
A Note On Locations
Below are the exact locations of the Commands
and Command Panels
folders on both Mac and Windows.
Mac OS X
/Applications/Adobe Fireworks CS6/Configuration/Commands/
- `/Users/
/Library/Application Support/Adobe/Fireworks CS6/Commands/` /Applications/Adobe Fireworks CS6/Configuration/Command Panels/
- `/Users/
/Library/Application Support/Adobe/Fireworks CS6/Command Panels/`
Windows
Windows 8.1, 8, 7, Vista and 64-bit (for 32-bit, simply remove the (x86)
):
C:\Program Files (x86)\Adobe\Adobe Fireworks CS6\Configuration\Commands\
- `C:\Users\
\AppData\Roaming\Adobe\Fireworks CS6\Commands\` C:\Program Files (x86)\Adobe\Adobe Fireworks CS6\Configuration\Command Panels\
- `C:\Users\
\AppData\Roaming\Adobe\Fireworks CS6\Command Panels\`
C:\Program Files\Adobe\Adobe Fireworks CS6\Configuration\Commands\
- `C:\Documents and Settings\
\Application Data\Adobe\Fireworks CS6\Commands\` C:\Program Files\Adobe\Adobe Fireworks CS6\Configuration\Command Panels\
- `C:\Documents and Settings\
\Application Data\Adobe\Fireworks CS6\Command Panels\`
How To Choose Between Commands And Command Panels
When should you write a command, and when should you write a command panel?
Generally, a command is useful for automating some action that requires no or very little user input, such as pasting elements into an existing group or quickly collapsing all layers. A command is also easier to build and test.
Regardless of whether you write a command or build a command panel, you will be interacting with Fireworks via JavaScript. Now let’s peek inside Fireworks’ JavaScript heart!
Note: How to build a command panel is beyond the scope of this article. We’ll focus instead on the basics of developing a Fireworks extension and how to write your first extension.
History Panel
The History panel in Fireworks provides an easy way to examine the JavaScript running behind the scenes.
As a quick example, open the History panel (Window → History
), select a text element and then move it anywhere on the canvas.
A “Move” item will be added to the list of actions in the History panel.
Next, click the “Copy steps to clipboard” button in the bottom-right corner of the History panel, and paste it in the text element that you’ve just moved (i.e. replacing the “Move Me!” text).
If you moved an object 2 pixels to the right (along the x-axis) and 46 pixels down (along the y-axis), this is how the JavaScript code would look:
fw.getDocumentDOM().moveSelectionBy({x:2, y:46}, false, false);
We can save this code to Fireworks’ “Commands” menu by clicking on the “Save steps as a command” button in the bottom-right corner of the History panel.
Once this simple command has been saved to the Commands
folder, you’ll be able to run it from the “Commands” menu, use it in more complex Fireworks batch-processing scripts and more. Whenever run, the command will move any selected object on the canvas 2 pixels to the right along the x-axis and 46 pixels down along the y-axis. You can also easily customize this command by editing the x
and y
values in the .jsf
file that Fireworks saved at the location described earlier in this article.
This was a very simple example, but it shows that developing a Fireworks extension is not that hard — at least not in the beginning!
Fireworks Console
Let’s dig a bit deeper. When you’re developing an extension, being able to execute a one-off JavaScript command without having to save it to the “Commands” menu every time would be useful. To execute the “Move” command without having to first add it to the “Commands” menu, let’s install John Dunning’s Fireworks Console extension. This command panel has a text input that lets you type arbitrary JavaScript code and run it by clicking the “Eval” button.
Make sure to select the text element (the method is called moveSelectionBy
, after all) and paste the “Move” code into the Console. Then, hit “Eval” to run it.
This is a great way to quickly test different commands and to make sure that the code you are working on actually does what it is supposed to do.
Console Debugging
While building the Specctr panel, I used the JavaScript alert
function to check the output of my code at various places in its execution.
myCode.jsf
…
// Check the value of myVariable:
alert("my variable:", myVariable);
…
As in Web development, JavaScript alerts in Fireworks pause the code’s execution until you click to proceed. This means that if you had multiple values that you wanted to alert in the code, you would have to repeatedly press the “OK” button in the alert pop-up to continue executing the code.
Instead, we can use the panel to log our extension’s output to the console!
When the Console panel first launches, it introduces an object named console
into Fireworks’ global namespace. This means that we can use the console
object’s log
function to log messages out to the Console panel’s output pane, as we’ll see now.
myCode.jsf
…
console.log("myProgramVariable", myVariable);
…
This doesn’t interrupt the code from executing. Because Fireworks does not provide any way for you to set breakpoints in the code, logging to the console is the method that I would recommend when debugging extensions.
Fireworks DOM
Just as the console
object is a JavaScript representation of Fireworks’ Console panel, the different concepts and functionality that make up Fireworks have JavaScript representations. This organization of JavaScript objects that models Fireworks’ behavior is called the Fireworks DOM.
fw Object
We can see the DOM being accessed by our “Move” JavaScript code from earlier:
fw.getDocumentDOM().moveSelectionBy({x:2, y:46}, false, false);
The fw
object is a JavaScript object that models or represents Fireworks itself. It contains properties that describe Fireworks’ current state. For example fw.selection
is an array that represents all of the currently selected elements on the canvas.
We can see this by selecting the text element that we’ve been working with and, in the Console panel, typing fw.selection
, then clicking the “Eval” button. Here is the Console panel’s output:
[{
…
alignment: "justify",
face: "GillSans",
fontsize: "34pt",
…
}]
In the output window, you should see a JSON representation of the fw.selection
array containing objects that symbolize each of the selected design elements on the canvas. (JSON is just a human-readable representation of JavaScript objects — in our case, the text element that we selected.)
Viewing The DOM
When the formatting of the Console’s output gets too long, it leaves something to be desired. So, to see the properties and values of objects (object methods are not shown) in the Fireworks DOM, I use Aaron Beall’s DOM Inspector panel, another indispensable companion in my journey of developing extensions.
fw.selection
. You should see an expanded [object Text]
in the Inspector, along with all of its properties and values.
From the drop-down menu, I can select between viewing the contents of four objects:
fw.selection
An array of currently selected elements on the canvasfw
The Fireworks objectdom
The DOM of the currently active document (which we will discuss next)dom.pngText
A property of the currently active document (available for us to write to so that we can save data to the current document and retrieve it even after restarting Fireworks)
Document DOM
In the DOM Inspector panel, we can switch to the documentDOM
and explore its state. We can also access the documentDOM
via JavaScript with the getDocumentDOM()
method, as we did with the “Move” command:
fw.getDocumentDOM().moveSelectionBy({x:10, y:10}, false, false);
The getDocumentDOM()
method invocation returns only the DOM object of the currently active document, rather than the entire Fireworks DOM, and allows us to manipulate that document via its properties and methods. For example, the moveSelectionBy()
method (which the History panel taught us about) does the work of moving elements around the document’s canvas.
Selection Bias
Acting on the current selection is a common pattern when developing Fireworks extensions. It mirrors the way that the user selects elements on the canvas with the mouse, before performing some action on that selection.
fw.getDocumentDOM().moveSelectionBy({x:10, y:10}, false, false);
The document DOM’s moveSelectionBy() function takes a JavaScript object as a parameter:
{x:10, y:10}
Given an origin in the top-left corner, this tells Fireworks to move the selected object by x
pixels to the right and by y
pixels down.
The other two boolean parameters (false
, false
) indicate to move
(as opposed to copy
) the selection and to move the entire element
(as opposed to a sub-selection
, if any exists).
Like the moveSelectionBy()
method, many other Document DOM methods act on the current selection (cloneSelection()
and flattenSelection()
, to name two).
Expand Your Horizons (And The Canvas)
Using what we have learned so far, let’s write a simple command that will expand the size of our canvas.
Canvas Size
To increase the size of the canvas, we need to know the current size. Our panel can call the JavaScript below to access the canvas’ current dimensions:
var = canvasWidth = fw.getDocumentDOM().width;
var = canvasHeight = fw.getDocumentDOM().height;
Now, let’s see how to change these dimensions.
Setting The Canvas’ Size
To set the canvas’ size, we call the setDocumentCanvasSize()
method of the Document DOM.
fw.getDocumentDOM().setDocumentCanvasSize({left:0, top:0, right:200, bottom:200});
The method takes a “bounding rectangle” as a parameter:
{left:0, top:0, right:200, bottom:200}
The size of the rectangle will determine the new size of the canvas:
right - left = 200
bottom - top = 200
Here, the rectangle is bounded by the object; therefore, the canvas is 200 × 200 pixels.
Increasing The Canvas’ Size: A Simple Command
Let’s create a simple command that will double the canvas’ size automatically.
Instead of going through the Modify → Canvas → Canvas Size
menu and then figuring out a width and height to input and then pressing “OK” whenever we want to increase the canvas’ size, we can combine the two code samples from above to create a quick shortcut to double the canvas’ size.
The code might look something like this:
// Double Canvas Size command, v.0.1 :)
var newWidth = fw.getDocumentDOM().width * 2;
var newHeight = fw.getDocumentDOM().height * 2;
fw.getDocumentDOM().setDocumentCanvasSize({left:0, top:0, right: newWidth, bottom: newHeight});
I’m working on a Mac, so to make this command available from the “Commands” menu in Fireworks, I could save the code above as double_size.jsf
in the following location:
/Users/<MYUSERNAME>/Library/Application Support/Adobe/Fireworks CS6/Commands/double_size.jsf
(Check the beginning of the article to see where to save your .jsf
commands if you are on a different OS.)
I leave it as an exercise for you to write and save a simple command that cuts the canvas’ size in half.
Conclusion
We’ve covered quite a few things in this article:
- With the help of the History panel, we’ve seen the JavaScript that makes Fireworks run.
- We’ve broken down the JavaScript code needed to move a text element on the canvas, learned about the Fireworks DOM and seen how to manipulate it.
- We’ve gone over how the Console panel executes and tests our JavaScript code. We’ve learned how to debug an extension by logging to the JavaScript
console
object that the panel introduces into Fireworks’ global namespace. - We’ve covered the DOM Inspector panel and how to use it to check the properties and values of various parts of the Fireworks DOM.
- We’ve written a simple command to change the canvas’ size automatically.
Another great way to learn more about Fireworks extensions is by deconstructing other extensions. Because Fireworks commands are simple JavaScript files, you could learn a lot by studying the code of other developers. I’d especially recommend the extensions created by the following people:
(The Project Phoenix extensions, recently rebooted by Linus Lim, are also worth mentioning. They include Font List, Super Nudge, Auto Save, Rename, Transform, Alignment Guides, Perspective Mockups, Retina Scaler, Layer Commands, Used Fonts and many others.)
Finally, below you’ll find an incomplete list of resources to help you along the way. If you think I’ve missed something important (or if you have any questions), let me know in the comments. I’d be happy to help.
Other Resources
- “Extending Fireworks,” Adobe. This is the official guide to developing extensions for Fireworks CS5 and CS6 (including the “Fireworks Object Model” documentation).
- “Adobe Fireworks JavaScript Engine Errata,” John Dunning. Dunning breaks down the quirks of the JavaScript interpreter that ships with Fireworks. Something not working as it should? Check it here. The list is pretty extensive!
- Fireworks Console, John Dunning. This is a must-have if you write Fireworks extensions!
- DOM Inspector (panel), Aaron Beall.
Further Reading
- Developing A Design Workflow In Adobe Fireworks
- Switching From Adobe Fireworks To Sketch: Ten Tips And Tricks
- The Present And Future Of Adobe Fireworks
- The Power of Adobe Fireworks: What Can You Achieve With It?