Flash FileReference on Snow Leopard Bug

Yesterday I spent most of the day (ok, all of the day -- including sleep, total time on the bug was 24 hours) debugging an issue where parts of our app would stop responding to mouse move, over, and out events. After a lot of investigation assuming it was in the code, this article was discovered:

http://www.opencoder.co.uk/2009/09/bug-in-flash-player-filereference-browse-a...

Basically on Snow Leopard, in a 32-bit browser (most commonly, Firefox), the Flash player's FileReference upload dialog will cause the Flash Player to not respond to mouse moves or hovers until you (most commonly) switch to another application and then back to the browser.

Throwing this out there to hopefully give the above post some more Google juice and such, and for the future reference of myself and others.

OJUtils: A set of utilities for Objective-J

In developing Strophe.j and ojspec (more coming on that soon), I ran into the need for a couple of utility classes. To collect these utility classes, I've created a github repository named OJUtils. Currently the two classes in there are BlankSlate and DelegateProxy.

BlankSlate

BlankSlate is an equivalent to the BlankSlate class in Ruby: it provides the absolute minimum necessary for an Objective-J class to function correctly. This makes it ideal for use in proxying scenarios when you want as few methods interfering with proxying as possible. I use it in ojspec to set up a mocking framework. BlankSlate has 3 class methods and 5 instance methods, and nothing else. These are:

  • + alloc -- A basic alloc method that correctly sets up a bare bones object.
  • + initialize -- A blank implementation that is necessary for correct functioning in the Objective-J world.
  • + load -- Likewise a blank implementation necessary for correct functionality in Objective-J.
  • - description -- A barebones implementation that displays the class name with the hash.
  • - methodSignatureForSelector: -- An implementation that always returns null (thus never calling forwardInvocation:)
  • - forward:: -- A full implementation taken basically verbatim from CPObject. Calls forwardInvocation: when an unknown method is called but has a non-null methodSignatureForSelector:.
  • - forwardInvocation: -- Invokes doesNotRecognizeSelector: immediately.
  • - doesNotRecognizeSelector: -- Raises a CPInvalidArgumentException immediately.

No other methods are defined, so a proxy class can easily use forwardInvocation: to proxy almost all method calls successfully.

Something like BlankSlate is likely to go into Cappuccino itself soon (I'm hoping to have time to move this over there) -- possibly based on NSProxy concepts.

DelegateProxy

There is an oft-seen pattern in the Cappuccino codebase when invoking something on a delegate:

It seemed annoying to do this every time, and thus during the creation of Strophe.j was born DelegateProxy. DelegateProxy acts as a simple wrapper around your delegate on which you can invoke any method you want with the knowledge that it will only be forwarded to the delegate if the delegate can handle it. If it can't, then the method call will be silently ignored without causing any errors. This means that code like the above turns into a simple:

DelegateProxy itself is a super-simple class, and relies on BlankSlate to provide a very basic starting point. All you need to do is ensure that you keep a reference to a DelegateProxy wrapped around your delegate instead of keeping your delegate itself.

Creating a new DelegateProxy is as simple as:

And that's it, you're ready to just do method invocations without worrying about respondsToSelector checks!

Strophe.j -- An Objective-J Wrapper for strophe.js

As I evaluated Cappuccino as our potential next step to move parts of our UI from Flex (the parts that are not necessarily well-suited to Flex's strengths), I was in charge of assembling some quick prototype code to show how Cappuccino would work for us. Since a part of our app is XMPP communications and publish-subscribe, I started writing a simple wrapper to the strophe.js Javascript Jabber library. It implements Jabber using BOSH, which uses long-lived (usually 60-second) AJAX requests to maintain a Jabber connection, instead of an always-on TCP connection to a port (which browsers currently cannot do).

 Strophe.j is this wrapper, and it's available on github at http://github.com/Shadowfiend/Strophe.j/tree/master . It provides a very basic implementation of the current user, a connection, and basic MUC support. It has some stubs for handling rosters, though they aren't implemented, and it pulls in jquery (for parsing the Jabber XML when needed). It's in the early stages, and my work on it is likely to be sporadic, since our ultimate decision was to go with GWT... But I kind of fell in love with Objective-J, so I won't be going anywhere anytime soon.