actionscript
encodeURIComponent in AS3
Wednesday, December 17th, 2008 | actionscript | No Comments
Haven’t posted in awhile. Been Keeping busy here at KickApps and took a 2 week vacation to South Korea. It was awesome :)
I was looking into interfacing with some Facebook APIs today via actionscript and was having some issues passing some nested querystring vars. Turned out using escape() wasn’t enough and encodeURIComponent() did the trick. I didn’t realize it was even available in actionscript until i did some googling. encodeURI() and encodeURIComponent() are available along with escape() as top level functions in AS3.
Here’s a useful link explaining the difference between them.
mysterious “Where is the debugger or host application running?” dialogue on non-debug swfs
Monday, September 1st, 2008 | actionscript, bugs | 3 Comments
Remember awhile back when you’d go to a flash site and randomly get accosted by a “Where is the debugger or host application running?” modal prompt? Haven’t seen one in a while have you? Happily these days debug swfs normally don’t pop open this dialogue unless you explicitly right click a debug swf and click on “Debugger” from its context menu. Unfortunely there are still some tricky situations where this prompt will still rear its ugly head.
My Google-foo (or Adobe?) has let me down on getting solid information on this but in my tests it appears this functionality changed with Flash Player Debugger 9,0,115,0 (Yeah, I thought it was earlier too). This is the debugger version that installs with Flex so even tho you may no longer get the prompt its keen to note that any viewer with a <9,0,115,0 Flash 9 debugger (like the 9,0,45,0 debugger that installs with Adobe CS3) will still receive it. In most cases this isn’t anything to worry about though as its second nature to turn off debugging on your production swf. However did you know you have to take into account all embedded and run-time loaded swfs as well?
After receiving reports of said infamous debugger on our production swfs and a lot of time spent investigating with Flash Switcher I found a couple insignificant embedded icon swfs and a few run-time loaded font swfs were the debug swf culprits. Duplicating the issue in the Flash 9.0.45.0 Debugger, what made matters worse is that each debug swf that loaded was getting its own modal popup and, atleast in Mac FF3, each consecutive modal popup was showing up blank but still needed to be clicked or the user was locked out of the site.
After another extensive google search the only thing I could find regarding this child swf debugger policy is a brief mention in Tinc Uro’s Blog regarding Flash Player 9 Update 3 (again Player 9,0,115,0). The one line from his release notes was: “210746 When a release swf loads a debug swf, flash player doesn’t look for the debugger”. I’m assuming that this was the “fix” as this player version does indeed keep the issue from happening. So to prevent your viewers from ever getting spammed with “Where is the debugger” modal windows, ensure all your swfs (embedded and run-time loaded) are non-debug or force your viewers to update to the most recent flash player if they don’t have atleast 9,0,115,0.
With the proliferation of “dot” releases of the Flash Player its now really important to know which sub version of the player you are targeting. Looking at the Flash Player 9 version penetration rates at KickApps I was surprised to find around 80% of our audience had atleast 115. I’m not sure of the remaining 20% how many are debug players though.
Version Penetration
9,0,124,0: ~56%
9,0,115,0: ~24%
9,0,47,0: ~10%
9,0,28,0: ~7%
9,0,45,0: ~4%
handy way of removing event listeners via arguments.callee
Saturday, August 9th, 2008 | actionscript | No Comments
Theo’s entry reminded me how useful this can be especially when using an anonymous function as a one time callback. Try it out:
stage.addEventListener(MouseEvent.MOUSE_DOWN, function(event:Event):void { event.currentTarget.removeEventListener(event.type, arguments.callee); trace(’ran once’); });
FYI you should always use event.currentTarget and not event.target when removing a mouse event listener because event.currentTarget will always reference the object that the listener was explicitly attached to. event.target can easily reference a different object like a child displayObject inside the displayObject you were listening for a bubbling event on.
Event.INIT and Event.COMPLETE don’t fire when loading an unpacked swc
Thursday, July 24th, 2008 | Uncategorized | No Comments
Cleaning out the wordpress there were a few posts I hadn’t finished. This one is mainly a for-future-reference for myself.
I’ve been doing some run-time class loading involving loading SWF files into the same ApplicationDomain as the container via Loader then using getDefinitionByName to access new instances of the loaded classes. I was perplexed that the INIT and COMPLETE events weren’t being dispatched and found some info here.
SecurityError: Error #2000: No active security context.
Thursday, July 24th, 2008 | Uncategorized | 2 Comments
Always interesting to throw an error that has only 4 obscure results in google.
Using setTimeout with navigateToURL:
var urlRequest:URLRequest = new URLRequest(”http://google.com”);
setTimeout(navigateToURL, 1000, urlRequest, “_blank”);
Generates:
SecurityError: Error #2000: No active security context.
at global/flash.net::navigateToURL()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at <anonymous>()
at SetIntervalTimer/onTimer()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
A work around is to wrap the call in an anonymous function:
setTimeout(function():void { navigateToURL(urlRequest, “_blank”); }, 1000);
How to make an efficient image proxy
Thursday, February 21st, 2008 | actionscript, bugs, help | 6 Comments
So the work I’m currently doing is centered around loading data from different domains. I’ve got a proxy setup to get around pesky crossdomain issues but I’ve been trying to make it a bit dynamic for efficiency’s sake. I only want to proxy if I know for sure that the data isn’t coming from our servers or a server with a crossdomain file in place.
Creating a “smart” proxy with the URLLoader for text content is a piece of cake. Simply listen for the SecurityErrorEvent then run the url through the proxy. Beautifully simple.
For the Loader class its a different story. The Loader class’s contentLoaderInfo doesn’t have a security error event, just an ioError event. Your supposed to use the childAllowsParent property of the contentLoaderInfo to figure out whether you have bitmapData level access. The only problem is you can’t access that property until the Event.COMPLETE event is dispatched despite the livedocs LoaderContext page stating this property is available on ProgressEvent.PROGRESS which will throw a Error #2099: The loading object is not sufficiently loaded to provide this information. at flash.display::LoaderInfo/get childAllowsParent()
I can finagle with the LoaderContext and try/catches all I want but there doesn’t seam to be a creative solution to this problem. The result: I have to load every image that doesn’t have a policy file TWICE. Once to check childAllowsParent, the next to proxy the image. This doesn’t make any sense considering on the same livedocs LoaderContext page it states:
When you call the Loader.load() method with LoaderContext.checkPolicyFile set to true, Flash Player does not begin downloading the specified object in URLRequest.url until it has either successfully downloaded a relevant cross-domain policy file or discovered that no such policy file exists.
I can see the “Error: Request for resource at http://… by requestor from http://… is denied due to lack of policy file permissions.” errors being outputted to the trace window but I don’t seam to have a way to catch it in code. Is something as significant as this, really a bug? Can anyone give me a hand?
Using the “include” directive to update multiple classes
Wednesday, February 6th, 2008 | actionscript, flex | No Comments
I recently subclassed Flex’s Canvas to utilize my own custom scrollbars (what a pain!) and soon found I needed to do the same with the Box container (VBox, HBox). Due to the clean OOP nature of these components my overrides and implementation turned out exactly the same for my CustomScrollBarCanvas and CustomScrollBarBox. After a few refactoring sessions copying and pasting my changes to both subclasses I ended up moving all my code to a separate include file and its worked out beautifully with Flex still checking the code during incremental compile:
public class CustomScrollBarCanvas extends Canvas {
public function CustomScrollBarCanvas(){
super();
}
include “CustomScrollBarImplementation.as”
}
public class CustomScrollBarCanvas extends Box {
public function CustomScrollBarCanvas(){
super();
}
include “CustomScrollBarImplementation.as”
}
The Actionscript “include” directive is useful when you have a variable or several lines of code that are mirrored in several classes and you want to maintain that code in a central file. Flex and other frameworks use it commonly to write out framework version numbers on all their classes explicitly during compile time. Flex also uses it to write out groups of meta style tags by type (TextStyles.as, BorderStyles.as, etc) into the components that use them. Its really quite ingenious for upkeep but really simple to implement. (FYI in AS3 you no longer prepend the include statement with a “#”)
Using the class path resolution to your advantage
Sunday, January 13th, 2008 | actionscript, flex | No Comments
Heres a interesting, albeit questionable hack when extending flex classes that cockblock you with a private property or require you to extend several classes when you just want to tweak 1 line of insignificant code in the component.
You can grab the class you want to tweak and copy it to your project folder, mirroring its package with the appropriate folders. When classes get resolved your project folder gets checked before default system paths so your edited version will get compiled in.
I don’t recommend doing this, probably ever, but its been my best friend when I just wanted to tweak that dark 1 pixel line that the Panel component’s title bar receives via TitleBackground without making it a long and convoluted proccess. I don’t know how well this will work with Flex 3’s framework caching but its nice to know this quick and dirty method is there.