Flex tip: conditions like ‘&&’ in MXML

Consider the following little MXML snippet:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
        <mx:VBox x="0" y="0" height="100%" width="100%">
                <mx:CheckBox label="Checkbox 1" id="check1"/>
                <mx:CheckBox label="Checkbox 2" id="check2"/>
                <mx:Label text="{check1.selected && check2.selected?
                        'Both checked':
                        'Not both checked'}"/>
        </mx:VBox>
</mx:Application>

We want to show the string “Both checked” in the label, if both of the checkboxes are checked, otherwise the label should show “Not both checked”. When you use the above code in Flex, it will show you the error: “The entity name must immediately follow the ‘&’ in the entity reference.”. It is complaining about the line where the “&&” appears.

MXML files are treated as XML files and as such the parser expects to see a symbol name after the “&” character. Hence the error message.

With this in mind, we can convince Flex Builder and the mxml-compiler to still use “&&” as a condition, by properly escaping them, as in:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
        <mx:VBox x="0" y="0" height="100%" width="100%">
                <mx:CheckBox label="Checkbox 1" id="check1"/>
                <mx:CheckBox label="Checkbox 2" id="check2"/>
                <mx:Label text="{check1.selected &amp;&amp; check2.selected?
                        'Both checked':
                        'Not both checked'}"/>
        </mx:VBox>
</mx:Application>

The above may look weird in the editor, but it compiles cleanly and does what one would expect.

The same applies to other operators: “< " should be written as "&lt;" and ">” should be written as “&gt;”.

AIR Link Report visualizer

The Flex compiler has a rarely used feature called “link-report”. Using this option instructs the compiler to create a report of all symbols that went into the compiled application as well as a list of all external references. The Reducing SWF file sizes livedocs-page has more information about link reports.

To enable it, you would either modify your Flex projects’ compiler settings:

link-report flex compiler settings

or you would use “-link-report output.xml” as an option on the mxmlc command line. In either case, an XML file with all definitions will be created after the compiler successfully built the SWF-file.

The contents of the link report file look like this:

link report xml

Hmmm - not very easy to digest by just reading the file in a text-editor. Theo Hultberg over at iconara.net created an XSL-script that transforms link-reports into human-readable HTML. While this is interesting, it did not give me the “big picture” for all the pieces that go into my applications.

I created an AIR application which can read, digest and visualize link-report files.

After installing the LinkReportAIR application, you can use the “Browse …” button to select a link-report XML file on your system or alternatively just drag and drop an XML-file on the AIR application itself.

link report air 1

The DataGrid on the left lists all symbols included in the report (under “id”), the modification date for the symbol (if available), the package it is included in, the size of the symbol and the optimized size (if available). You can use the DataGrid headers to sort the symbols using any of the columns.
All symbols that do not have a package associated with them are automatically assigned to a package called “global”. Any symbol that ends in “_properties” is assigned to a package called “properties”.

If you click on any of the symbols in the DataGrid, the bottom portion will show you where this symbol comes from (this can be a SWC or any of your sources) and whether is has “prerequisites” or “dependencies” associated with it (the livedocs link above has more details about these):

link report air 2

The neatest feature of LinkReportAIR is the little treemap (using ILOG Elixir) that is automatically created from the data in the link report. It tries to visualize the space consumption per package. In the screenshot below, I’m hovering over the “mx.controls” package (and all packages included in it) and LinkReportAIR tells me that the (unoptimized) size of everything contained under mx.controls.* is roughly 500 KBytes and that this equals about 25% of my applications total size.

link report air treemap

Double-clicking on a package in the tree-map will “drill down” and allows you to focus on certain portions of the package tree. While “drilled down”, the DataGrid on the left will also be filtered to only show symbols in the current drilled down subtree. To get back to the entire view, you would double-click again on the subtree-symbol that is currently in focus (sounds complicated, but you’ll get it once you use it).

And finally the “External Symbols” tab will show all symbols that are externally required (like the stuff that’s exported from the Flash Player itself). That list will grow if you decide to link the Flex Framework externally via Runtime Shared Libraries (RSLs):

link report air external

You can download and install the AIR application using the badge below. If you need a sample link-report file to play with, then use the one that I generated from the application itself: link-report.xml (use “Save Link As …” to save the report locally)

Flare - data visualization in Flex

flare logoOver at http://flare.prefuse.org/ there’s an interesting collection of ActionScript libraries for Data Visualization. Take a look at the demo to see what Flare is capable of.

Going to take a closer look at it when I have some spare time …

AirLog

Things were so simple in the old days, when we had a single server acting as web-/application-server at the same time. In order to see what was going on, one would just “tail” the servers log-file (for example Apache’s access_log and/or error_log) to get live information about the servers activity.

Things are not as easy these days. For one of my work projects only god knows how many individual servers are involved: web-server, application server, rendering server, conversion server, etc. To see activity on all systems involved, developers usually have multiple Terminal windows open, are logged in to multiple servers and “tail -f” logfiles in those windows. While this allows people to get a live view into the system, it makes it very difficult to correlate log-events on one system to log-events on another system. The logs are tailed independently and the information is not “interleaved”.

There are existing utilities out there that allow you to look at multiple files at the same time (most notably http://www.vanheusden.com/multitail/), but as far as I know, there is no platform-independent one.

airlog

(more…)

Flex uploads via http/https

I heard that quite a number of people have issues when it comes to uploading file-content from a Flex application to a server. This is especially true if the upload happens as part of a “session”, meaning a user is authenticated and each HTTP request carries a sessionid back to the server. That sessionid is usually transported in form of a cookie.

So why do things break when trying to do uploads from Flex, especially when using Firefox? The explanation is pretty simple: when you select a file for upload (using FileReference.browse() and FileReference.upload() - see here for a discussion about “Working with file upload and download”) and then send that selected file to the server, Firefox uses two different processes. The first one is the one that hosts your Flex (Flash) application and communicates with the server on one channel. The second one is the actual file-upload process that pipes multipart-mime data to the server. And, unfortunately, those two processes do not share cookies. So any sessionid-cookie that was established in the first channel is not being transported to the server in the second channel. This means that the server upload code cannot associate the posted data with an active session and rejects the data, thus failing the upload.

To fix this we need to make sure that we transport all the necessary information with the upload URL allowing the server to associate the uploaded data with an active session.

It has been suggested elsewhere, like here or here to just tackle on the sessionid to the URLs used for the upload. That will work, but moves logic from the server into the client and I don’t like that. What if the sessionid-parameter gets changed on the server? What if a different server application is receiving the upload-data? In both cases you will need to make modifications to the client as well. You have an unnecessary dependency between client and server.

For a recent project we used a different approach: our flex application communicates via remoting calls with the server (we use Flex Data Services in this case). When a user is about to upload a file to the server, the Flex-application will issue a call getUserUploadURL(...). The receiving java-servlet will construct a one-time usable URL that encodes the users sessionid and a secret into the URL. The flex-code will in turn use that URL when the FileReference.upload() is executed. Once the server has received the data-stream for the current upload, the same URL cannot be used for subsequent uploads, instead the flex code has to ask for another url via getUserUploadURL(...).

And on the server side the upload-code makes sure that no cookies are considered, but only the contents of the URL are used to figure out which session the uploaded data belongs to.

Adobe “SHARE beta”: the cat’s out of the bag …

For the past few months I’ve been working on the front-end of the Adobe SHARE (beta) service. “Front-end” here means the Flex-code that makes up the stuff you see in your browser and that connects to the back-end service that does the heavy-lifting. Almost every action in the user-interface sends a message back to the server with instructions on what to do with the user-supplied data.

The service (along with the “Virtual Ubiquity” Buzzword acquisition) was announced at this year’s Adobe MAX conference in Chicago.

“Adobe SHARE beta” is a web-service that allows you to send “documents” to a number of recipients. You can pick whether you want to have those recipients as the only recipients or whether it is allowed to re-share the documents. 1 GB of free storage should be enough to get you going. Besides pushing (email) data to your recipients, you can also upload documents to the service and embed a preview of the document on your own web-site/blog.

Adobe

The Flex-UI allows us to add some distinct value: you can preview a (growing) number of document-formats right in your browser. This allows you to figure out whether it’s worth to download a document.

There were tons of features that were cut from the application before it’s public release and we are planning to (re-)add those before we reach the 1.0-milestone of the service.

Give it a try and let me know what you think.

The simFluence : Deep Linking Flex Applications Presentation at 360Flex

There’s an interesting article/presentation over at: The simFluence : Deep Linking Flex Applications Presentation at 360Flex.

It talks about how to implement deep-linking for your Flex apps. Traditionally moving from state to state in a Flex application, does not update the associated browser URL and hitting “back” and then “forward” will not bring you to the exact same state in the Flex UI, instead the application will be reinitialized. Using the ExternalInterface API you can now update the browser’s URL to match the state of your Flex application. This means that one can “bookmark” interesting spots deep inside the Flex application and can return to that bookmarked location later on.

Flex: Stopping event propagation from itemRenderers

My application uses an mx:TileList to display some thumbnail and document information. I created a custom itemRenderer to display the individual tiles. The itemRenderer also uses MOUSE_OVER and MOUSE_OUT events to display a menu under the thumbnail. You move the mouse over the item, the menu appears - you move out and the menu disappears. Here’s a quick screen-shot where the mouse is currently over the right item:

TileList with custom itemRenderer

My problem was that whenever I clicked on one of the menu items (the four icons at the bottom of the right tile), the mouse event would not only execute the action associated with the menu-item, no, the event would propagate up the chain and would result in the current tile being selected as well. Not good - this has to stop.

Initially my menu-item event handler, which was triggered via “click=’menuItemClicked(event)’” was calling event.stopPropagation(), but that did not seem to do the trick. The menu-action was performed, but the TileList item was still receiving event, which resulted in the selection of the current Tile-item.
After some googling I finally found the solution: besides the “click” event I needed to trap the MOUSE_DOWN event as well. So inside my itemRenderer’s creationComplete handler I call:

private function onCreationComplete() : void
{
this.addEventListener(MouseEvent.MOUSE_DOWN, disablePropagation);
}

And inside the disablePropagation event handler I say:

private function disablePropagation(event : MouseEvent) : void
{
event.stopPropagation();
}

And this says: if you receive a MOUSE_DOWN event on the itemRenderer, call disablePropagation and for each such MOUSE_DOWN event, make sure that nothing else but the itemRenderer’s MOUSE_DOWN event handler(s) are called.

Works just fine!

Flex tip: make your UIComponents announce themselves

I work a lot with Adobe’s Flex these days. The more I use it, the more I like it.

Here’s a neat little trick for those of you who also use Flex: Every single UI element is styled via entries in a global CSS file and the UI elements pick the correct style via “styleName” properties. So, inside the CSS, you’ll find tons of sections like this one:

.dc2HeaderDocument
{
font-weight:bold;
color:#339933;
font-size:21;
}

And that dc2HeaderDocument is used as a styleName on some UI element. Just recently a UI designer started to work on the CSS-file to make it compliant with the design-document. But how the heck is he supposed to know which UI element uses which style? That would require looking through the *.as/*.mxml sources and identifying the correct relationship between source and presentation.

After some fiddling today I came up with a much more elegant solution to this problem.

In my main mx:Application I register an event handler for the “added” event. The docs say that this event is dispatched “when a display object is added to the display list”. Inside the event handler I check if the added object is a sub-class of UIComponent and if it is the case, then I set the UIComponent’s toolTip property to the UIComponent’s styleName property. This means that every single item that is added to the stage will get a toolTip that represents the styleName used for the UIComponent. Just hover over an item and it will identify itself.

Here’s what I had to do:

<mx:Application …. added=”displayObjectAdded(event)” ….>

public function displayObjectAdded(event : Event) : void
{
 if(event.target is UIComponent) {
  event.target.toolTip =
   event.target.styleName?event.target.styleName:”no style”;
 }
}

Now UI designer loads the Flex application, hovers over the item that needs to be fixed and immediately knows what CSS-entry to change.

Try Flex - online!

try.flex.orgOur summer intern, Sara, just told me about an online service that allows you to get your feet wet with Flex without having to download/install anything. At http://try.flex.org/ you get a form with a textarea that allows you to enter some MXML-code (or select some predefined samples). When you hit the “Try It” button, the service will compile your MXML-code (I suspect they use “mxmlc” from the free Flex SDK to do the compilation) and will display the resulting SWF-file (your application) beneath the textarea. Neat!

|
Next Page »