Tuesday, April 25, 2006

Dynamically Inserting FSCommand-Capable Flash Objects With innerHTML

Let me preface this post by saying that if you've never tried to dynamically write a bunch of FSCommand-enabled swfs into an HTML page, you'll probably be really confused by what follows. In point of fact, there's a good likelihood you'll be confused anyway, since my writing is not particulary lucid. But glean what you can. Forging ahead...

Suppose you have a series of SWF files to dynamically insert into a page (maybe, just maybe, as a result of the infernal Eolas patch) and these SWF files need to communicate via FSCommand. You must also add a script block for each swf, to capture the FSCommand calls. Typically, this would be a block of VB Script, like the one Flash puts into the HTML files it publishes with your SWF.

Now suppose we have the filenames of the swfs in an array, and we want to loop through the array and write each swf into the document. We need to dynamically create an ID for each one, create a VBScript for it, and then insert them into the document. Since you can't use innerHTML to insert VB Script, you have to use the DOM:

for(var i=0; i < swfArray.length; i++){
var mySwfId = "swf"+i;

var myVB = document.createElement("script");
myVB.language = "VBScript";
myVB.text = "Sub "+mySwfId+"_FSCommand(ByVal command, ByVal args) \n call "+mySwfId+"_DoFSCommand(command, args) \n end sub ";
// Insert the VBScript into the Head element
document.getElementsByTagName("head")[0].appendChild(myVB);

// Insert the swf into the target element
var mySwf = '< object id='+mySwfId+' ... swf code omitted ... < / object>';
targetElement.innerHTML = mySwf;
}

This method works pretty well as long as the VBScript is inserted before the swf is, and as long as you're doing this before the page load completes. For some reason, the VBScript doesn't seem to work if it is written into the page after loading completes. I fooled around with some techniques for simulating onDomReady in IE, but while some of them worked locally, none of them worked under live network conditions. This meant that I had to put my init() call before the closing body tag, which I hate to do because it makes my code less maintainable.

Happily, it turns out that you can use JavaScript instead of VBScript if you prefer, and JavaScript is much more forgiving in this matter. You can also insert the JavaScript via the innerHTML property:

for(var i=0; i < swfArray.length; i++){
var mySwfId = "swf"+i;

var myJS = '< script event=FSCommand(command,args) for='+mySwfId+'>\n '+mySwfId+'_DoFSCommand <\ /script>';

var mySwf = '< object id='+mySwfId+' ... swf code omitted ... < / object>';

// Insert the swf and the JavaScript into the target element.
targetElement.innerHTML = mySwf+myJS;
}

The order here is important: the JS must be inserted AFTER the swf for it to work if the swf is inserted after page load. If you insert the swf onDomReady, it seems to work in either order. I always add the JS after the swf just to be on the safe side.

Here's where I found out about using JavaScript instead of VBScript to catch the FSCommand calls.

I know this post is a bit confusing, since the code is pseudo-code and out of context. But I'll do my best to answer any questions you might have. At any rate, maybe this will help someone who, like me, was Googling for hours trying to find the answer to this obscure question.

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.

Monday, April 24, 2006

IE bug: background-image and :hover kills page load status

This bug relates to anchor tags with a background-image defined on the hover pseudo-class, as follows:

a:hover{
background-image:url("yourimage.gif");
}


When the user clicks this link and then moves their mouse off of the link, Internet Explorer's page load status indicators (the wavy Windows animation in the upper right corner of the browser, as well as the status-bar at the bottom of the browser) will revert to their default states, seemingly indicating that nothing is loading. However, the requested page actually IS loading, and will appear when the process is complete.

This is most noticeable when submitting a form, or with high-latency network conditions.

There is a workaround, although it is imperfect:

a:active{
background-image:none;
}

This works well, although if the user clicks anywhere on the screen, the link will revert to its default state, and the load status indicators will go to their default states as well, showing no page load activity.

See
http://www.nabu-beraterteam.de/dev/ie6-bg-img-link/ for more information. This bug may be related to the IE background-image caching flicker bug, although applying the IIS fixes did not resolve the problem for me.

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.

Wednesday, April 19, 2006

Flash Minutia: getURL("javascript:function();") fails on Mac Opera 8.0

Using the getUrl command to call a javascript function from a swf fails on Opera 8.0 for the Mac. For example, the following code:

getURL("javascript:alert('Hello World');");

should cause a dialog box to appear. However, in Opera 8.0 for the Mac, it does not.

The fix, as described by Alex at Linecraft Blog is to ensure that the AllowScriptAccess parameter of your embed or object statement is set to "always", or to simply omit the AllowScriptAccess parameter altogether, which has the same effect.

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.

Thursday, April 13, 2006

More IE Fieldset Wackiness

If you have a legend element styled position: relative; within a fieldset, the top border of the fieldset will be pushed down the page. The amount the top border of the fieldset is pushed down the page is equal to the height of the content preceding the fieldset.

This is true only for the first fieldset on the page. Subsequent fieldsets will display normally, regardless of whether their legend elements use position:relative. See the test page for a demonstration.

The good news is, there is a fix: simply applying position:relative to the fieldset element in addition to the legend element will fix the bug.

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.

Fieldset Border Bug in IE

There are many problems with the way that fieldsets are rendered across virtually all browsers. This is yet another for the IE pile, and it only happens in obscure circumstances, so I'm not too surprised I haven't seen it posted elsewhere.

If you apply a negative margin to the top or bottom of an input or select element in a fieldset that has a legend, the top border of the fieldset will be repeated at the position of each input or select element. Sound a little murky? Check out the test page.

The test page has a strict doctype, but the bug also occurs with transitional doctypes. I've confirmed the bug in IE 5, IE 5.5, and IE 6. Let me know if you have a workaround!

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.

Wednesday, April 12, 2006

Flash Quirk: ExternalInterface IE "Expected ;" Bug

This information applies to Flash Player 8,5,0,246 and may also apply to other versions.

If you use an integer for the id of your swf object element, ExternalInterface.call will fail and IE will report a script error:

Expected: ';'

The solution is to not use integers for element ids.

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.

Monday, April 10, 2006

Open Source CSS Helper Library - What features would you like to see included?

I plan on releasing a library of JS functions designed to provide functionality for CSS properties that Internet Explorer does not support. It will work in conjunction with the IE-only expression operator. This will be an open source effort, so it will be free to use, but it will adhere to the strict standards of quality I follow in my professional work.

I intend to do the usual min-width, max-width, min-height, max-height, etc. Which CSS properties would you like to see support for? Let me know, and I'll do my best to include them.

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.

Sunday, April 09, 2006

Windows XP Service Pack 1 with Apple Bootcamp - DON'T TRY IT

I wasn't able to immediately get my hands on a Win XP disc with Service Pack 2 included, so I decided I'd try a Service Pack 1 installation. Everything went normally, until the very last step when Windows reboots your computer, which it failed to do. I manually rebooted the system, and was able to bring up Windows, but the Mac drivers would not install on SP1.

Now, this is a bad thing, because that includes the ethernet drivers. They wouldn't install either. No internet, no upgrade to Service Pack 2.

I downloaded SP2 on another machine, burned it to CD, and tried to update the SP1 installation. This failed as well.

Ultimately, I had to remove the partition I had made with Bootcamp and start the whole process over again, this time with a WinXP Sp2 disc in hand. This time, everything went smoothly. The whole ordeal makes for a long and boring Saturday night, so I recommend against making the attempt with Service Pack 1.

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.

Saturday, April 08, 2006

Installing Windows on My New Mac Mini

Well, I took the leap and bought my dual-core Mac Mini today... Everything about the experience has been awesome so far, except installing Windows on it. That is to say, Bootcamp is working perfectly, and the installation is working perfectly, but I am reminded anew of just how much Windows installations suck. Tonight I will probably have "Setup will complete in approximately: 36 minutes" stamped across all my dreams.

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.

Wednesday, April 05, 2006

Windows on a Mac, or The Final Nail in the Wintel Coffin

As an art student, I was educated on Macs, but I never could understand why all my colleagues were so in love with them. Yes, the colors on the display were more natural. Theoretically, they could crunch graphics faster than Wintel machines, but the Wintel machines had faster processors, so they seemed about equal to me. When the G2s in the lab broke (which they frequently did) you couldn't really fix them. When they became outdated, you couldn't go down to Staples and snag some new hardware for them.

Fast-forward to Christmas 2005. I have 16 hours of digital footage of my son that I need to edit down to a 45-minute DVD. The import process on my 3GHZ 1GB RAM Wintel box is going poorly. Video is coming in with huge green blocky artifacts, and Windows Movie Maker (or whatever it's called) is unusably slow. Even the mighty Adobe Premiere has been brought to its knees. Hours of trying to tweak out performance bottlenecks have proven fruitless. The Mac Mini on my desk (that I only use for cross-platform compatibility checks) is giving me a shy little wink.

"This thing has firewire? Ok, let's give it a whirl", I think to myself. Within minutes, I've got iMovie importing my footage flawlessly. Editing is a breeze with no signs of sluggishness in the UI. It just works. Granted, it took 14 hours to export a disc image from iDVD (a known issue), but I was asleep for most of it, so I didn't really care.

Fast-forward again to the present. I have a workstation at home that needs to be replaced (433 MHz PII with a fan that sounds like a llama giving birth), and the dual-core Macs are looking mighty sexy. That slick OSX interface is calling to me. The comparitively garish color pallete of my Wintel machine is beginning to finally destroy my retinas. Windows Vista will likely not ship until 2007. But I have all this Windows software... I can't afford to run out and buy Mac versions of Studio MX and Creative Suite (especially since CS2 will probably never be a Universal Binary).

Enter Apple Bootcamp. This has finalized my decision to buy a Mac. With Bootcamp, Apple is releasing an officially supported means of dual-booting your Intel-based Mac with Windows and OSX. This will allow me to continue to use my legacy Windows apps, while slowly migrating over to a total Mac environment. My wallet likes slow transitions.

I wonder how many other Windows users are in the same situation? The move to Intel chipsets and dual-booting with Windows seems like a smart strategy for Apple. With the ubiquity of Apple stores in major cities, it's now easier than ever to get supplies and support for Macs. The popularity of the iPod has done awesome things for the Apple brand.

It seems like a lot of pieces are coming together in Apple's favor. I, for one, am finally convinced.

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.

Tuesday, April 04, 2006

Comma operator in ECMA script

From this page:
Enter a technique I discovered out of necessity, which I call "one-time use expression()". It relies upon the rarely used comma operator in ECMAScript. The expression expr1, expr2 evaluates both expressions, but returns only the value of the second. So we do 2 things inside expression() using this. The first being our dirty deed, secretly inserting markup into the header. The second removes the mechanism we utilized itself! We simply set the value of the property to "none", overriding the current expression() value. It goes away, but leaves the inserted markup. This hack effectively allows "CSS" (I'll use the term loosely) content-generation in IE4+ in Windows! The limitation being, of course, that one must have scripting enabled. Some have told me that expression() works with scripting disabled (that would be a serious security issue in IE, which wouldn't be surprising in the least), however my tests seem to indicate otherwise.


I had seen this done in IE expressions before, but had never seen an explanation of how/why it worked. Firing up Flash to see if the comma operator works in ActionScript...

...and it does!! Really cool! I can see the uses for the comma operator as a shortcut syntax, and perhaps as a weak-strength obfuscation technique, but aside from IE expressions, I can think of no other practical use for it. Everything you can do with it can already be done with other, more maintainable techniques. Am I missing something??

Was this post helpful to you? If so, please consider making a small donation to keep this blog going.