Johnvh.com - home of Dallas, Texas based Flash Developer and web enthusiast John Van Horn

Online home of John Van Horn

E4x and as3 gotcha

I love E4X in AS3. It's powerful and fairly simple. If you haven't worked with it yet, check out Roger Braunstein's excellent tutorial. But I was recently annoyed by this gotcha when doing some xml combining. Let's say you have this:

XML:
  1. <xml>
  2.     <people>
  3.         <person id="123">
  4.             <name>John</name>
  5.         </person>
  6.         <person>
  7.             <name>David</name>
  8.         </person>
  9.     </people>
  10. </xml>

Let's parse with E4X:

Actionscript:
  1. // #1
  2. trace( xml.people.person.length() );
  3. // 2
  4.  
  5. // #2
  6. // no animals, but e4x still returns an XMLList
  7. trace( xml.people.animal.length() );
  8. // 0
  9.  
  10. // #3
  11. // no animals, so no further children, but still returns XMList
  12. trace( xml.people.animal.fur.color.length() );
  13. // 0
  14.  
  15. // #4
  16. // gotcha
  17. trace( xml.people.person.( "123" == @id ) );
  18. // thows: ReferenceError: Error #1065: Variable @id is not defined.

The first 3 examples work great. Even though there are no <animal> nodes, E4X still returns an XMLList. Even looking for more siblings under nodes that don't exist works great - it always returns an empty (but valid) XMLList. Always returning an XMLList makes it easy to work with because you can always for-each over the result.

What I don't understand is the 4th example. It fails because not every <person> node has an id attribute. But so what? If you look at the 2nd and 3rd examples, not every <people> node has an <animal> node. So why don't we get the same result - an empty XMLList?

Turns out that there is an easy solution/work-around, that Roger mentions in his tutorial:

Actionscript:
  1. // will error if every person node does not have an id attribute
  2. trace( xml.people.person.( "123" == @id ) );
  3.  
  4. // use this
  5. trace( xml.people.person.( attribute( "id" ) == "123" ).length() );
  6. // 1

A bit wtf, but at least it works like the other examples.

Flash’s secret Javascript API

Yahoo! invasion

Yahoo! invasion

Is that a Yahoo! ad in a Youtube player? No. It's a Yahoo! logo in a Youtube player. How did it get there? Via Flash's secret javascript api!

Ok, so it's not really secret. More like old, surely deprecated, and forgotten. I've been working with flash for a good while now, and I had no idea this existed until my friend Robert Ames stumbled upon it.

What's cool (or not cool) about this api, is that it's part of the Flash plugin itself and has nothing to do with Actionscript. All you have to do to enable this api is... well... embed a swf. Try going to a youtube video page like this one, and then entering this in the address bar:

JavaScript:
  1. javascript: document.getElementById( "movie_player" ).LoadMovie( 98, "http://l.yimg.com/a/i/ww/beta/y3.gif" );

I want to play around with this a bit more... I wouldn't be surprised if some of these API methods bypassed some of the Flash Player's security restrictions.

Master bathroom progress

It's almost done. I just have to cut the trim and do some caulking and touch up painting. A couple more photos are in the full set.

My new vanity.

My new vanity.

Ignoring files in Flex Builder Navigator

I don't like seeing .svn or CVS files in my Flex Builder/Eclipse workspace. I'll never need to edit those files directly, and if I do, I won't use Flex Builder to do it. But if they're in your project, they'll show up in the Navigator panel. Everywhere.

Every directory in your project will have a .svn folder.

Every directory in your project will have a .svn folder.

Fortunately, Eclipse provides a way to filter files in the Navigator, but a) it's rather hidden, and b) it's not obvious how to add filters. In the Navigator panel, hit the down arrow in the top right corner and select "Filters...".

Navigator panel options.

Navigator panel options.

Here's the list of filters you get by default:

Default Filters

Default Filters

What? No "add filter" option? No "edit"? I guess you could use the ".*" filter, but that would hide every file or directory whose name starts with ".". That may or may not be acceptable, depending on the type of project or files your working with. What if you had a .htaccess file in your project?

Fortunately again, there is a mechanism for adding additional filters, but it's not obvious. It involves editing the plugins.xml file for the Flex Builder editor plugin. You can find this plugin in the eclipse plugins folder (located in same place as Flex Builder.app) in your Flex Builder install. It's called com.adobe.flexbuilder.standalone_3.0.194161, and it's located for me at:

CODE:
  1. /Applications/Adobe Flex Builder 3/plugins/com.adobe.flexbuilder.standalone_3.0.194161

So navigate there, and edit plugins.xml. You're looking for the extension node whose attribute point is "org.eclipse.ui.ide.resourceFilters". Under that node is where the default filters are defined. All you have to do is add another one and save the file:

Flex Builder editor plugin.xml, with svn filter added.

Flex Builder editor plugin.xml, with svn filter added.

The remaining step is to restart Flex Builder, using the -clean option. Since the plugin.xml file is either cached or compiled in somewhere, using the -clean option tells the Eclipse executable to reload all plugins and configs. This requires use of the Terminal:

CODE:
  1. $ cd /Applications/Adobe\ Flex\ Builder\ 3/Flex\ Builder.app/Contents/MacOS
  2. $ ./FlexBuilder -clean

When Flex Builder launches, you should now see the filter you just added in the filters window. Thanks to Robert Ames for telling me how to launch Flex Builder with arguments.

New filter added.

New filter added.

Del.icio.us links
» My delicious bookmarks