fireworks
FWXHR
Since Fireworks is used so heavily for web graphics production, it's quite likely that there'll be times when you developers out there would like your JSF commands to interact with a web service. Unlike a browser's JS environment, unfortunately, Fireworks doesn't offer any XmlHttpRequest functionality. Flash panels can make HTTP calls, but there hasn't been easy way to integrate Flash with JSF commands. Until now.
Installation
After installing the extension, you should have a FWXHR
directory in your commands folder, which will look like:
/Adobe Fireworks CS4
/Configuration
/Commands
/FWXHR
Example - Insert Stock Price.jsf
Example - Translate Text.jsf
/lib
lib.js
/dojo
...
/fwlib
FWXHR.swf
io.js
The lib
sub-folder contains all the files necessary to make XHR-style calls from your JavaScript commands. The io.js
file implements an API for making requests, and the FWXHR.swf
Flash file provides the XHR functionality.
To use the library in your .jsf commands, copy the entire lib
sub-folder to the folder that contains your .jsf. Your folder hierarchy should look something like:
/Adobe Fireworks CS4
/Configuration
/Commands
/My XHR Commands
XHR Command 1.jsf
XHR Command 2.jsf
/lib
...
Loading the fwlib.io library
From within XHR Command 1.jsf
in the example above, you can load the API by including this code:
try { dojo.require; } catch (e)
{ fw.runScript(fw.currentScriptDir + "/lib/lib.js"); }
dojo.require("fwlib.io");
This first loads the dojo
API, if it's not already loaded, and then loads the fwlib.io
library, which is what you'll use to make the XHR calls.
A simple GET
To make a simple HTTP GET request, call fwlib.io.request()
with a URL. The following example looks up the current price of Adobe stock using Yahoo!'s Finance API:
var response = fwlib.io.request(
"http://download.finance.yahoo.com/d/quotes.csv?f=snl1c1p2d1t5&s=ADBE"
);
The call to request()
is always synchronous, so by the time the next line in your script executes, the request has either succeeded or failed and will have returned the response as an object.
When your script calls request()
, a Flash dialog is opened. It's a pretty simple dialog, consisting of a Cancel button, a progress bar and a few text fields showing the current request method and the URL. The dialog will remain open until the HTTP request succeeds, fails, times out, or is canceled by the user. If you're making a GET
request, the loaded and total bytes will be shown next to the progress bar. For a POST
request, an indeterminate progress bar is shown, as Flex doesn't provide any information about the progress of the request. Either way, if the request works, the dialog usually opens and closes too fast to interact with.
The response object
When the HTTP transaction is complete, the response is returned from request()
as an object with the following fields:
- status
- The HTTP status code as a number, such as
200
for a successful transaction. - statusText
- The HTTP status code as a string, such as
OK
for a successful transaction. - responseText
- The data returned from the web service endpoint as a string. If the HTTP request failed for some reason, this will contain the resulting error message. If the response is in some structured format like XML or JSON, it's up to you to convert it from text to that format.
If the user cancels the dialog before the transaction can complete, then request()
returns null
, so your code should check for that.
The response from the previous example can be handled like this:
var response = fwlib.io.request(
"http://download.finance.yahoo.com/d/quotes.csv?f=snl1c1p2d1t5&s=ADBE"
);
if (!response) {
alert("The request was canceled.");
} else if (response.status != 200) {
alert("The request failed: " + response.responseText);
} else {
var dom = fw.getDocumentDOM();
// the stock data fields are comma-separated
var data = response.responseText.split(",");
var currentStock = data[0] + " is at $" + data[2];
// insert the stock price as a text element centered in the document
dom.addNewText({ left: 0, top: 0, right: 150, bottom: 10 }, true);
dom.align("center vertical", true);
dom.align("center horizontal", true);
dom.setTextRuns({ initialAttrs: { alignment: "center" },
textRuns: [{ changedAttrs: {}, characters: currentStock }] });
}
This script extracts the comma-separated stock price data from the response and then uses that data to create a text element.
The request configuration object
Similar to the io()
method of YUI3, the second parameter to request()
can be an object that defines the parameters of the transaction. This parameter and all of its fields are optional:
- method
- Specifies the HTTP method of the transaction, either
GET
(the default) orPOST
. - headers
- An object containing key-value pairs of headers to supply with the transaction, e.g.,
{ "Content-Type": "application/xml; charset=utf-8" }
. Due to a limitation in Flex, custom headers work only withPOST
requests. They will be ignored byGET
requests. - data
-
Data to be sent with the transaction, defined as either a string of key-value pairs (e.g.,
"foo=bar&baz=42"
) or an object (e.g.,{ foo: "bar", baz: 42 }
), which will be serialized into a URI-encoded string.If the method is
GET
, thendata
will be appended to the URL after a?
(the question mark is added automatically if the URL doesn't end with one). If the method isPOST
, then the data will be sent as the body of the request. - fileData
- An object containing key-value pairs of form field names and local file paths. If specified, the local files are loaded into memory and then posted as a multi-part form submission. The files are combined with the key-value pairs in the
data
parameter, if any, and the method is set toPOST
. See below for more information on posting local files.
The data
parameter can make it more convenient to build up a complicated set of query parameters. Here's another way to look up stock price data in the previous example:
var symbol = prompt("Enter the stock symbol to look up.");
var response = fwlib.io.request(
"http://download.finance.yahoo.com/d/quotes.csv",
{
data: {
f: "snl1c1p2d1t5",
s: symbol
}
}
);
Posting local files
Normally, a web page can't upload arbitrary files from the local computer without the user's interaction. But since Fireworks and its commands already have access to the local filesystem, it's possible to upload files directly from a JSF command.
A typical scenario might be to POST
the current document to a file server. How exactly this request should be constructed will depend on the web service you are posting to, but an example might look something like this:
var tempPath = Files.getTempFilePath(null) + ".png";
var dom = fw.getDocumentDOM();
dom.exportTo(tempPath, null);
var response = fwlib.io.request(
"http://your.domain.com/upload.php",
{
method: "POST",
data: {
username: "myuser",
password: "mypass",
pageName: dom.pageName
},
fileData: {
pageImage: tempPath
}
}
);
In this example, the current document is exported to a temp file, and the path to that temp file is passed to request()
in the fileData
parameter of the request configuration object. This causes the file to be loaded into memory and then combined with the data
parameter to form the body of the POST
. To the server page receiving this post, it will look like a regular form submission.
The Content-Type
of each file is determined by its extension. An image type of PNG
, for instance, is given a content type of image/png
. All other file types default to application/octet-stream
.
Example scripts
There are two example .jsf scripts in the installation folder, one that demonstrates using a GET
request to access Yahoo's stock price API, and another that uses a POST
request to access Google's translation API. (The latter is a simplified version of the Translate Text extension.) The scripts are well-commented and should help you get started making your own HTTP requests from Fireworks.
Future directions
The FWXHR extension is still pretty basic, so let me know if you run into any problems and how you'd like to see it extended.
Credits
The FWXHR extension uses a slightly modified version of the URLRequestBuilder AS3 library (Copyright (c) Mike Stead 2009) to create the multi-part form requests when posting file data.
Release history
- 0.1.2
- Added an example that uses Google's translation API.
- 0.1.1
- Added progress bar for
GET
requests, and an indeterminate bar forPOST
requests. Enlarged area showing requested URL. Added support for multiple dojo installations. - 0.1.0
- Initial release.
Package contents
- Example - Insert Stock Price
- Example - Translate Text
- FWXHR