swfObject javascript error in Internet Explorer

April 15th, 2009 markledford 3 comments

We’ve had this IE error reported 3 times this week:

Line: 130
Character: 4
Code: 0
Error Message: ‘script.parentNode’ is null or not an object

The issue:
The SWFObject library is included multiple times on a page causing the IE DOM ready check hack it uses internally to be triggered multiple times. This hack inserts and removes a test node. Since the first instance removes this node, additional tries cause the error.

Solution:
Remove multiple imports of <script src=”swfobject.js” type=”text/javascript”></script> from your page.

Categories: flex Tags:

embed parameter “menu” = false and ContextMenuEvent.MENU_SELECT

March 11th, 2009 markledford No comments

In the Adobe LiveDocs it states:

  • menu- Possible values: true, false.
    • true: isplays the full menu, allowing the user a variety of options to enhance or control playback.
    • false: displays a menu that contains only the Settings option and the About Flash option.

Naturally not wanting the clutter in my context menus I had menu set to false in its embed code. Today I noticed new Context Menu support I had added to my app was not showing up in Flash 9 Player though it was appearing in Flash 10. Apparently setting this option to false will also keep the ContextMenuEvent.MENU_SELECT option from being dispatched in Flash Player 9 :-x

Categories: flex Tags:

AS3 htmlDecode htmlEncode xml hack

February 25th, 2009 markledford 5 comments

You’d think there would be a straight forward way to htmlEncode and htmlDecode strings in flash but there doesn’t seam to be any sort of built-in utility class that supports this. Oddly enough there isn’t one in Javascript either. Like this Javascript hack, here is a handy hack to pimp AS3′s native XML object instance to do the htmlEncoding/decoding for you.

Unfortunately this doesn’t work for  many encoded characters like “&iacute;”, “&oacute;”,  “&aacute;”, and “&ntilde;”. It seams the best route to robust html html encoding/decoding is to roll your own utility function like this.

Here is an AS3 Version:

//modified from http://www.cnblogs.com/laudy/articles/1186810.html
public static function htmlDecode(s:String):String {
    var out:String = "";
    if (s==null) return "";
    //regex convert all numeric character references to regular chars
        var matches:Array = s.match(/&#\d+;?/g);
    for(var i:Number = 0; i < matches.length; i++){
        var replacement:Object = String.fromCharCode((matches[i]).replace(/\D/g,""));
        s = s.replace(/&#\d+;?/, replacement);
    }
    //convert all character entity references / HTML entities
    var l:Number = s.length;
    for (i=0; i<l; i++){
        var ch:String = s.charAt(i);
        if (ch == '&'){
            var semicolonIndex:Number = s.indexOf(';', i+1);
            if (semicolonIndex > 0) {
                var entity:String = s.substring(i + 1, semicolonIndex);
                switch (entity){
                    case 'quot': ch = String.fromCharCode(0x0022); break;
                    case 'amp': ch = String.fromCharCode(0x0026); break;
                    case 'lt': ch = String.fromCharCode(0x003c); break;
                    case 'gt': ch = String.fromCharCode(0x003e); break;
                    case 'nbsp': ch = String.fromCharCode(0x00a0); break;
                    case 'iexcl': ch = String.fromCharCode(0x00a1); break;
                    case 'cent': ch = String.fromCharCode(0x00a2); break;
                    case 'pound': ch = String.fromCharCode(0x00a3); break;
                    case 'curren': ch = String.fromCharCode(0x00a4); break;
                    case 'yen': ch = String.fromCharCode(0x00a5); break;
                    case 'brvbar': ch = String.fromCharCode(0x00a6); break;
                    case 'sect': ch = String.fromCharCode(0x00a7); break;
                    case 'uml': ch = String.fromCharCode(0x00a8); break;
                    case 'copy': ch = String.fromCharCode(0x00a9); break;
                    case 'ordf': ch = String.fromCharCode(0x00aa); break;
                    case 'laquo': ch = String.fromCharCode(0x00ab); break;
                    case 'not': ch = String.fromCharCode(0x00ac); break;
                    case 'shy': ch = String.fromCharCode(0x00ad); break;
                    case 'reg': ch = String.fromCharCode(0x00ae); break;
                    case 'macr': ch = String.fromCharCode(0x00af); break;
                    case 'deg': ch = String.fromCharCode(0x00b0); break;
                    case 'plusmn': ch = String.fromCharCode(0x00b1); break;
                    case 'sup2': ch = String.fromCharCode(0x00b2); break;
                    case 'sup3': ch = String.fromCharCode(0x00b3); break;
                    case 'acute': ch = String.fromCharCode(0x00b4); break;
                    case 'micro': ch = String.fromCharCode(0x00b5); break;
                    case 'para': ch = String.fromCharCode(0x00b6); break;
                    case 'middot': ch = String.fromCharCode(0x00b7); break;
                    case 'cedil': ch = String.fromCharCode(0x00b8); break;
                    case 'sup1': ch = String.fromCharCode(0x00b9); break;
                    case 'ordm': ch = String.fromCharCode(0x00ba); break;
                    case 'raquo': ch = String.fromCharCode(0x00bb); break;
                    case 'frac14': ch = String.fromCharCode(0x00bc); break;
                    case 'frac12': ch = String.fromCharCode(0x00bd); break;
                    case 'frac34': ch = String.fromCharCode(0x00be); break;
                    case 'iquest': ch = String.fromCharCode(0x00bf); break;
                    case 'Agrave': ch = String.fromCharCode(0x00c0); break;
                    case 'Aacute': ch = String.fromCharCode(0x00c1); break;
                    case 'Acirc': ch = String.fromCharCode(0x00c2); break;
                    case 'Atilde': ch = String.fromCharCode(0x00c3); break;
                    case 'Auml': ch = String.fromCharCode(0x00c4); break;
                    case 'Aring': ch = String.fromCharCode(0x00c5); break;
                    case 'AElig': ch = String.fromCharCode(0x00c6); break;
                    case 'Ccedil': ch = String.fromCharCode(0x00c7); break;
                    case 'Egrave': ch = String.fromCharCode(0x00c8); break;
                    case 'Eacute': ch = String.fromCharCode(0x00c9); break;
                    case 'Ecirc': ch = String.fromCharCode(0x00ca); break;
                    case 'Euml': ch = String.fromCharCode(0x00cb); break;
                    case 'Igrave': ch = String.fromCharCode(0x00cc); break;
                    case 'Iacute': ch = String.fromCharCode(0x00cd); break;
                    case 'Icirc': ch = String.fromCharCode(0x00ce ); break;
                    case 'Iuml': ch = String.fromCharCode(0x00cf); break;
                    case 'ETH': ch = String.fromCharCode(0x00d0); break;
                        case 'Ntilde': ch = String.fromCharCode(0x00d1); break;
                    case 'Ograve': ch = String.fromCharCode(0x00d2); break;
                    case 'Oacute': ch = String.fromCharCode(0x00d3); break;
                    case 'Ocirc': ch = String.fromCharCode(0x00d4); break;
                    case 'Otilde': ch = String.fromCharCode(0x00d5); break;
                    case 'Ouml': ch = String.fromCharCode(0x00d6); break;
                    case 'times': ch = String.fromCharCode(0x00d7); break;
                    case 'Oslash': ch = String.fromCharCode(0x00d8); break;
                    case 'Ugrave': ch = String.fromCharCode(0x00d9); break;
                    case 'Uacute': ch = String.fromCharCode(0x00da); break;
                    case 'Ucirc': ch = String.fromCharCode(0x00db); break;
                    case 'Uuml': ch = String.fromCharCode(0x00dc); break;
                    case 'Yacute': ch = String.fromCharCode(0x00dd); break;
                    case 'THORN': ch = String.fromCharCode(0x00de); break;
                    case 'szlig': ch = String.fromCharCode(0x00df); break;
                    case 'agrave': ch = String.fromCharCode(0x00e0); break;
                    case 'aacute': ch = String.fromCharCode(0x00e1); break;
                    case 'acirc': ch = String.fromCharCode(0x00e2); break;
                    case 'atilde': ch = String.fromCharCode(0x00e3); break;
                    case 'auml': ch = String.fromCharCode(0x00e4); break;
                    case 'aring': ch = String.fromCharCode(0x00e5); break;
                    case 'aelig': ch = String.fromCharCode(0x00e6); break;
                    case 'ccedil': ch = String.fromCharCode(0x00e7); break;
                    case 'egrave': ch = String.fromCharCode(0x00e8); break;
                    case 'eacute': ch = String.fromCharCode(0x00e9); break;
                    case 'ecirc': ch = String.fromCharCode(0x00ea); break;
                    case 'euml': ch = String.fromCharCode(0x00eb); break;
                    case 'igrave': ch = String.fromCharCode(0x00ec); break;
                    case 'iacute': ch = String.fromCharCode(0x00ed); break;
                    case 'icirc': ch = String.fromCharCode(0x00ee); break;
                    case 'iuml': ch = String.fromCharCode(0x00ef); break;
                    case 'eth': ch = String.fromCharCode(0x00f0); break;
                    case 'ntilde': ch = String.fromCharCode(0x00f1); break;
                    case 'ograve': ch = String.fromCharCode(0x00f2); break;
                    case 'oacute': ch = String.fromCharCode(0x00f3); break;
                    case 'ocirc': ch = String.fromCharCode(0x00f4); break;
                    case 'otilde': ch = String.fromCharCode(0x00f5); break;
                    case 'ouml': ch = String.fromCharCode(0x00f6); break;
                    case 'divide': ch = String.fromCharCode(0x00f7); break;
                    case 'oslash': ch = String.fromCharCode(0x00f8); break;
                    case 'ugrave': ch = String.fromCharCode(0x00f9); break;
                    case 'uacute': ch = String.fromCharCode(0x00fa); break;
                    case 'ucirc': ch = String.fromCharCode(0x00fb); break;
                    case 'uuml': ch = String.fromCharCode(0x00fc); break;
                    case 'yacute': ch = String.fromCharCode(0x00fd); break;
                    case 'thorn': ch = String.fromCharCode(0x00fe); break;
                    case 'yuml': ch = String.fromCharCode(0x00ff); break;
                    case 'OElig': ch = String.fromCharCode(0x0152); break;
                    case 'oelig': ch = String.fromCharCode(0x0153); break;
                    case 'Scaron': ch = String.fromCharCode(0x0160); break;
                    case 'scaron': ch = String.fromCharCode(0x0161); break;
                    case 'Yuml': ch = String.fromCharCode(0x0178); break;
                    case 'fnof': ch = String.fromCharCode(0x0192); break;
                    case 'circ': ch = String.fromCharCode(0x02c6); break;
                    case 'tilde': ch = String.fromCharCode(0x02dc); break;
                    case 'Alpha': ch = String.fromCharCode(0x0391); break;
                    case 'Beta': ch = String.fromCharCode(0x0392); break;
                    case 'Gamma': ch = String.fromCharCode(0x0393); break;
                    case 'Delta': ch = String.fromCharCode(0x0394); break;
                    case 'Epsilon': ch = String.fromCharCode(0x0395); break;
                    case 'Zeta': ch = String.fromCharCode(0x0396); break;
                    case 'Eta': ch = String.fromCharCode(0x0397); break;
                    case 'Theta': ch = String.fromCharCode(0x0398); break;
                    case 'Iota': ch = String.fromCharCode(0x0399); break;
                    case 'Kappa': ch = String.fromCharCode(0x039a); break;
                    case 'Lambda': ch = String.fromCharCode(0x039b); break;
                    case 'Mu': ch = String.fromCharCode(0x039c); break;
                    case 'Nu': ch = String.fromCharCode(0x039d); break;
                    case 'Xi': ch = String.fromCharCode(0x039e); break;
                    case 'Omicron': ch = String.fromCharCode(0x039f); break;
                    case 'Pi': ch = String.fromCharCode(0x03a0); break;
                    case ' Rho ': ch = String.fromCharCode(0x03a1); break;
                    case 'Sigma': ch = String.fromCharCode(0x03a3); break;
                    case 'Tau': ch = String.fromCharCode(0x03a4); break;
                    case 'Upsilon': ch = String.fromCharCode(0x03a5); break;
                    case 'Phi': ch = String.fromCharCode(0x03a6); break;
                    case 'Chi': ch = String.fromCharCode(0x03a7); break;
                    case 'Psi': ch = String.fromCharCode(0x03a8); break;
                    case 'Omega': ch = String.fromCharCode(0x03a9); break;
                    case 'alpha': ch = String.fromCharCode(0x03b1); break;
                    case 'beta': ch = String.fromCharCode(0x03b2); break;
                    case 'gamma': ch = String.fromCharCode(0x03b3); break;
                    case 'delta': ch = String.fromCharCode(0x03b4); break;
                    case 'epsilon': ch = String.fromCharCode(0x03b5); break;
                    case 'zeta': ch = String.fromCharCode(0x03b6); break;
                    case 'eta': ch = String.fromCharCode(0x03b7); break;
                    case 'theta': ch = String.fromCharCode(0x03b8); break;
                    case 'iota': ch = String.fromCharCode(0x03b9); break;
                    case 'kappa': ch = String.fromCharCode(0x03ba); break;
                    case 'lambda': ch = String.fromCharCode(0x03bb); break;
                    case 'mu': ch = String.fromCharCode(0x03bc); break;
                    case 'nu': ch = String.fromCharCode(0x03bd); break;
                    case 'xi': ch = String.fromCharCode(0x03be); break;
                    case 'omicron': ch = String.fromCharCode(0x03bf); break;
                    case 'pi': ch = String.fromCharCode(0x03c0); break;
                    case 'rho': ch = String.fromCharCode(0x03c1); break;
                    case 'sigmaf': ch = String.fromCharCode(0x03c2); break;
                    case 'sigma': ch = String.fromCharCode(0x03c3); break;
                    case 'tau': ch = String.fromCharCode(0x03c4); break;
                    case 'upsilon': ch = String.fromCharCode(0x03c5); break;
                    case 'phi': ch = String.fromCharCode(0x03c6); break;
                    case 'chi': ch = String.fromCharCode(0x03c7); break;
                    case 'psi': ch = String.fromCharCode(0x03c8); break;
                    case 'omega': ch = String.fromCharCode(0x03c9); break;
                    case 'thetasym': ch = String.fromCharCode(0x03d1); break;
                    case 'upsih': ch = String.fromCharCode(0x03d2); break;
                    case 'piv': ch = String.fromCharCode(0x03d6); break;
                    case 'ensp': ch = String.fromCharCode(0x2002); break;
                    case 'emsp': ch = String.fromCharCode(0x2003); break;
                    case 'thinsp': ch = String.fromCharCode(0x2009); break;
                    case 'zwnj': ch = String.fromCharCode(0x200c); break;
                    case 'zwj': ch = String.fromCharCode(0x200d); break;
                    case 'lrm': ch = String.fromCharCode(0x200e); break;
                    case 'rlm': ch = String.fromCharCode(0x200f); break;
                    case 'ndash': ch = String.fromCharCode(0x2013); break;
                    case 'mdash': ch = String.fromCharCode(0x2014); break;
                    case 'lsquo': ch = String.fromCharCode(0x2018); break;
                    case 'rsquo': ch = String.fromCharCode(0x2019); break;
                    case 'sbquo': ch = String.fromCharCode(0x201a); break;
                    case 'ldquo': ch = String.fromCharCode(0x201c); break;
                    case 'rdquo': ch = String.fromCharCode(0x201d); break;
                    case 'bdquo': ch = String.fromCharCode(0x201e); break;
                    case 'dagger': ch = String.fromCharCode(0x2020); break;
                    case 'Dagger': ch = String.fromCharCode(0x2021); break;
                    case 'bull': ch = String.fromCharCode(0x2022); break;
                    case 'hellip': ch = String.fromCharCode(0x2026); break;
                    case 'permil': ch = String.fromCharCode(0x2030); break;
                    case 'prime': ch = String.fromCharCode(0x2032); break;
                    case 'Prime': ch = String.fromCharCode(0x2033); break;
                    case 'lsaquo': ch = String.fromCharCode(0x2039); break;
                    case 'rsaquo': ch = String.fromCharCode(0x203a); break;
                    case 'oline': ch = String.fromCharCode(0x203e); break;
                    case 'frasl': ch = String.fromCharCode(0x2044); break;
                    case 'euro': ch = String.fromCharCode(0x20ac); break;
                    case 'image': ch = String.fromCharCode(0x2111); break;
                    case 'weierp': ch = String.fromCharCode(0x2118); break;
                        case 'real': ch = String.fromCharCode(0x211c); break;
                    case 'trade': ch = String.fromCharCode(0x2122); break;
                    case 'alefsym': ch = String.fromCharCode(0x2135); break;
                    case 'larr': ch = String.fromCharCode(0x2190); break;
                    case 'uarr': ch = String.fromCharCode(0x2191); break;
                    case 'rarr': ch = String.fromCharCode(0x2192); break;
                    case 'darr': ch = String.fromCharCode(0x2193); break;
                    case 'harr': ch = String.fromCharCode(0x2194); break;
                    case 'crarr': ch = String.fromCharCode(0x21b5); break;
                    case 'lArr': ch = String.fromCharCode(0x21d0); break;
                    case 'uArr': ch = String.fromCharCode(0x21d1); break;
                    case 'rArr': ch = String.fromCharCode(0x21d2); break;
                    case 'dArr': ch = String.fromCharCode(0x21d3); break;
                    case 'hArr': ch = String.fromCharCode(0x21d4); break;
                    case 'forall': ch = String.fromCharCode(0x2200); break;
                    case 'part': ch = String.fromCharCode(0x2202); break;
                    case 'exist': ch = String.fromCharCode(0x2203); break;
                    case 'empty': ch = String.fromCharCode(0x2205); break;
                    case 'nabla': ch = String.fromCharCode(0x2207); break;
                    case 'isin': ch = String.fromCharCode(0x2208); break;
                    case 'notin': ch = String.fromCharCode(0x2209); break;
                    case 'ni': ch = String.fromCharCode(0x220b); break;
                    case 'prod': ch = String.fromCharCode(0x220f); break;
                    case 'sum': ch = String.fromCharCode(0x2211); break;
                    case 'minus': ch = String.fromCharCode(0x2212); break;
                    case 'lowast': ch = String.fromCharCode(0x2217); break;
                    case 'radic': ch = String.fromCharCode(0x221a); break;
                    case 'prop': ch = String.fromCharCode(0x221d); break;
                    case 'infin': ch = String.fromCharCode(0x221e); break;
                    case 'ang': ch = String.fromCharCode(0x2220); break;
                    case 'and': ch = String.fromCharCode(0x2227); break;
                    case 'or': ch = String.fromCharCode(0x2228); break;
                    case 'cap': ch = String.fromCharCode(0x2229); break;
                    case 'cup': ch = String.fromCharCode(0x222a); break;
                    case 'int': ch = String.fromCharCode(0x222b); break;
                    case 'there4': ch = String.fromCharCode(0x2234); break;
                    case 'sim': ch = String.fromCharCode(0x223c); break;
                    case 'cong': ch = String.fromCharCode(0x2245); break;
                    case 'asymp': ch = String.fromCharCode(0x2248); break;
                    case 'ne': ch = String.fromCharCode(0x2260); break;
                    case 'equiv': ch = String.fromCharCode(0x2261); break;
                    case 'le': ch = String.fromCharCode(0x2264); break;
                    case 'ge': ch = String.fromCharCode(0x2265); break;
                    case 'sub': ch = String.fromCharCode(0x2282); break;
                    case 'sup': ch = String.fromCharCode(0x2283); break;
                    case 'nsub': ch = String.fromCharCode(0x2284); break;
                    case 'sube': ch = String.fromCharCode(0x2286); break;
                    case 'supe': ch = String.fromCharCode(0x2287); break;
                    case 'oplus': ch = String.fromCharCode(0x2295); break;
                    case 'otimes': ch = String.fromCharCode(0x2297); break;
                    case 'perp': ch = String.fromCharCode(0x22a5); break;
                    case 'sdot': ch = String.fromCharCode(0x22c5); break;
                    case 'lceil': ch = String.fromCharCode(0x2308); break;
                    case 'rceil': ch = String.fromCharCode(0x2309); break;
                    case 'lfloor': ch = String.fromCharCode(0x230a); break;
                    case 'rfloor': ch = String.fromCharCode(0x230b); break;
                    case 'lang': ch = String.fromCharCode(0x2329); break;
                    case 'rang': ch = String.fromCharCode(0x232a); break;
                    case 'loz': ch = String.fromCharCode(0x25ca); break;
                    case 'spades': ch = String.fromCharCode(0x2660); break;
                    case 'clubs': ch = String.fromCharCode(0x2663); break;
                    case 'hearts': ch = String.fromCharCode(0x2665); break;
                    case 'diams': ch = String.fromCharCode(0x2666); break;
                    default: ch = ''; break;
                }
                i = semicolonIndex;
            }
        }
        out += ch;
    }
    return out;
}
Categories: flex Tags:

Multipart form data in flash

February 20th, 2009 markledford No comments

Eugene has a handy MultipartURLLoader class to do the leg work of sending multipart form data from flash.

Note that because it uses:
urlRequest.requestHeaders.push( new URLRequestHeader( ‘Cache-Control’, ‘no-cache’ ) );

You may get SecurityError:
Error #2044: Unhandled securityError:. text=Error #2170: Security sandbox violation: http://domain1.com/your.swf cannot send HTTP headers to http://domain2.com/yourscript.php.

You may need to add a variation of <allow-http-request-headers-from domain=”*” headers=”*”/>  to your crossdomain.xml file or comment out that line. I chose the latter as I don’t think its neccessary in a POST call.

Categories: flex Tags:

solved: white rectangular flicker occuring when clicking on buttons in as3 project

February 13th, 2009 markledford No comments

Thanks be to Google and this blog I finally tracked down the cause of a mysterious unsightly rectangular white flicker that occurs when clicking on buttons in some of my projects as of late.  The culprit? Mac Firefox 3 + SWFAddress. Its really an ExternalInterface+Firefox 3 issue but a recent SWFAddress 2.2 release fixes it!

-Build-in fix for the Firefox 3/Mac OSX blinking effect.

Categories: actionscript, bugs Tags: , ,

show full folder paths in Finder on Mac OSX

February 2nd, 2009 markledford No comments

I’ve been using a Mackbook Pro almost exclusively  for development for the last 2+ years and really enjoy it. Adium is by far the best AIM client on any OS and QuickSilver makes interacting with the OS super quick. There are a few weird UI decisions though that irk me on a daily basis though and I finally google’d one for a quick fix. Here’s a quick Terminal command to show full folder paths in Finder folder windows. Now if I could only cut-and-paste in the file system and edit/delete/manage files in file browser dialogue boxes I’d be all set.

Categories: mac Tags:

javascript injection in AS3

January 20th, 2009 markledford No comments

Pretty useful method of storing Javascript inside of a swf for use with ExternalInterface. The novel part is maintaining the formatted Javascript inside of an xml object, check it out here. Thanks to Derek for the link.

Categories: flex Tags:

encodeURIComponent in AS3

December 17th, 2008 markledford 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.

Categories: actionscript Tags:

mysterious “Where is the debugger or host application running?” dialogue on non-debug swfs

September 1st, 2008 markledford 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%

Categories: actionscript, bugs Tags: , ,

Why some AS3 swfs work stand alone but fail to load into other swfs

August 13th, 2008 markledford 23 comments

Most developers who create standalone swfs have some standard instantiation code in their class constructor, something like this:

stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;

This works fine when the swf is embedded on a page directly as the “stage” property will be available instantaneously.
When this swf is loaded into another swf however, say like this:

var loader:Loader = new Loader();
addChild(loader);
loader.load(new URLRequest("http://widget.meebo.com/mcr.swf?id=RQYRkTseLc"));

It generates the infamous and ambiguous: TypeError: Error #1009: Cannot access a property or method of a null object reference.
I’m pretty sure this is because when a swf is loaded into another swf, it’s class constructor is called to create the object before it is even added to it’s parent (the Loader object).
Thus the stage property is undefined, which throws the error, which kills the call stack including what ever else was in the constructor after the stage reference.
I’d kind of consider this a bug in the flash architecture.

The work around to insure your swf is compatible with loading into other swfs:
If the stage references are just the above, you can throw a try/catch around them as they would probably get set by the loader anyways:

try {
   stage.align = StageAlign.TOP_LEFT;
   stage.scaleMode = StageScaleMode.NO_SCALE;
} catch(er:Error) { };

or just ensure the property is available:

if (stage){
   stage.align = StageAlign.TOP_LEFT;
   stage.scaleMode = StageScaleMode.NO_SCALE;
}

or, if there is setup that absolutely requires the stage reference, put this in your constructor:

Constructor(){
   if (stage){
      onAddedToStage();
   } else {
      addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
   }
}

private function onAddedToStage(evt:Event=null):void {
   removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
   stage.align = StageAlign.TOP_LEFT;
   stage.scaleMode = StageScaleMode.NO_SCALE;
   initApp();
}
Categories: flex Tags: