You are here

Hacking around the Eolas patch the ugly-as-sin way

The Eolas vs Internet Explorer case has been getting a lot of attention lately, since it is almost time the patch is released in the wild. To make a long story short: Internet Explorer 6 and the upcoming version 7 will display plugin content differently from the 'seamless' experience we're used to. Whereas most plugins (Flash, Windows Media) will 'only' require an additional click to enabled interactivity, some plugins such as Quicktime and Shockwave result in an ugly dialog box when they are found on a page. The official workaround has authors rewrite each HTML page containing the 'offending' tags substantially.

I think I have found the shortest, ugliest way around the patch. This workaround shows just how little sense it all makes. It works like a charm, but is ugly as sin, and I would not really recommend it. But here we go anyway.

Add this line of HTML immediately before the current object/param/embed tagsoup (any plugin should work):

<!--[if gte IE 6]><SCRIPT language="javascript" src="repairembed.js"><![endif]--></SCRIPT>

This is the content of the repairembed.js script:

document.write("<NOSCRIPT>")

window.onload = function() {
 document.body.innerHTML = document.body.innerHTML.replace(/\<noscript\>/gi,"")
}

And that's all. Note that the added line and script are generic for all (types of) content, and the script is about 140 bytes...

Here's the technique in action, displaying a panorama using Shockwave:
http://www.fieldofview.com/temp/repairembed.html

All browsers except IE will happily display the tagsoup as they did before; The (opening of) the script tag in the added line is commented out.

IE6 and newer (ruling out IE 5.5 on Mac, which I don't think will be Eolas-patched) are the only browsers that see through the comment and execute the script. The script masquerades the object/param/embed tag behind a noscript tag just in time so the activation-check is not triggered. The rest of the script removes the masquerading noscript tag after the check is done. If scripting is disabled in IE, you still need to activate the control, but there's no way around that.

The script closing tag is a bit odd, but it broke the conditional comment in IE if I put it in the comment.

So there you have it, a single generic line of HTML, that does not need to be changed if you want to embed another file, or even another plugin. But boy, is it ugly. And silly.

Update: This makes the hack a bit less ugly for other browsers than IE:

<!--[if gte IE 6]><SCRIPT language="javascript" src="repairembed.js"><![endif]--><SCRIPT></SCRIPT>

And this makes sure the script doesn't remove noscript tags that should not be removed:

document.write("<NOSCRIPT id=fix>")

window.onload = function() {
 document.body.innerHTML = document.body.innerHTML.replace(/\<noscript\sid=fix\>/gi,"")
}

Update 2: It's been brought to my attention that the one-line fix does not work with the IE7 beta; in that browser the fix scaps all content below the tagsoup. This can be fixed with a second line, just behind the object/param/embed tag soup:

<!--[if gte IE 6]></NOSCRIPT><![endif]-->

This also takes away most of the uglyness, but makes the hack far less cool as it's now two lines of code :-(

Final(?) update: It turns out that document.innerHTML doesn't always play nice. Here's a final alteration to the script that does not rewrite the whole document, but only the noscript node we adde

document.write("<NOSCRIPT class=fix>")

window.onload = function() {
  elems=document.getElementsByTagName("noscript");
  for(i=elems.length-1;elem=elems[i];i--) {
    if(elem.className=="fix")
      elem.outerHTML = elem.innerHTML
  }
}

Comments

http://geekswithblogs.net/mwatson/archive/2006/03/22/73022.aspx

The script could be a bit shorter, but it is far less ugly than my attempt, and the reasoning is as silly.

for(j=0;tagName=["object","embed","applet"][j];j ) {
  for(i=0;elem=document.getElementsByTagName(tagName)[i];i ) {
    elem.outerHTML = elem.outerHTML;
  }
}

Edit: can not really get this one to work...
Edit2: j instead of i, thanks Ingemar

Hi Aldo! Thanks for these tips! I'm in the process of updating my webpages to cope with the 906 disaster... By the way... shouldn't the first for-loop increment j? (j++ not i++) :-)

That makes sense, but its still not working terribly well for me. Oh well, my method's still (marginally) smaller ;-)

I came across your blog through the Macromedia conglomoration and figured I'd drop in links to the M$ info:

This is the Microsoft official blog that is not accepting comments (linked to from: http://blogs.msdn.com/ie/):
http://blogs.technet.com/msrc/archive/2006/03/29/423560.aspx

These are the official fix directions:
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/overview/activating_activex.asp

Not that their info is particularly good, but because the links are hard to locate. AdobeMedia has no independant information on this problem, they just point to the M$ site.

If you're a pretty good coder, it shouldn't be too big an issue to use the document.createElement example that M$ provides on the link above. You can always justify it as having the element details separate from the base webpage so that you can maintain them separately... :)

If you aren't comfortable with coding, then the document.write example, directly beneath the Loading Interactive Controls Externally heading on the link above should work for you. It's only 1 line in the html file, then pull the standard code that Flash creates out into a JS file and surround with document.write commands.

Good luck!

D

Thanks for posting those links.

The significance of my hack was that it was a single line of code that could be easily inserted with a find&replace. The second line, required for IE7 if there's content after the object/embed/applet sort of defeats that purpose.

I have not been able to make either version wotk with DevalVR . . . What could make a control incompatible?

I don't know exactly, but Fiero fixed it:
http://www.devalvr.com/forum/viewtopic.php?t=67

I've been working on various ways to approach a workaround and using the conditional tags to setup the NOSCRIPT tags is the best way I've found to far to minimize changes to the files which need fixing up (and equally importantly limit the changes to IE). However as far as I can tell IE 7 beta 2 does NOT like the open ended <NOSCRIPT> tag. It seems like the rest of the page is lost and no subsequent JavaScript code is executed.

IE 6 doesn't exactly love it either - I had to throw in a dummy tag after it <!--IEDummyTag> to prevent the closing <![endif]--> from appearing above the object. Ideally, the trailing </NOSCRIPT> tag should be written using JavaScript as well so it doesn't appear in the HTML if JavaScript is disabled (and therefore the whole workaround disabled) but that doesn't seem to work.

See update 2...

The problem seems to be that IE7 is smart enough NOT to load code that it's going to discard if script IS enabled. My tests on XP SP2 with IE 7 beta 2 show that the outer html only contains the NOSCRIPT opening tag, a bunch of blank lines (one for each line of HTML between the tags) and the NOSCRIPT closing tag. As a result this approach doesn't work because you end up replacing nothing with nothing.

Maybe I'm missing something.

Hmmm... IE7 beta 2 works for me on this url:
http://www.fieldofview.com/temp/repairembed.html

Can you post a link where it's not working for you?

I tested your page again and it worked. I went back to my code, made sure it had the same modifications and it didn't work. I modified the .js file to include a dump of the outerHTML to see what was going on with your code - and hey presto - all was revealed.

IE 7 beta 2 is throwing away the object tag, but keeping the nested embed. Check out these screenshots created using your HTML.

IE6 SP 2

IE7 beta 2

In my case, I was using APPLET tags and didn't have a secondary embedded object. So when IE 7 decided to dump the outer object (the applet tag) there was no nested object to fall back on.

What I don't get however is why your code still works on IE - given that IE is not supposed to understand the EMBED tag.

I've uploaded a few other files to my test site - which show the outerHTML when accessed. Compare IE 6 to IE 7.

Java applet using APPLET tag

Java applet using just OBJECT tag (Not much use for Firefox)

Aldo's code (won't work - but you can see script in action)

Java applet using OBJECT tag, EMBED tag and secondary nested OBJECT tag (Trying to support IE and Firefox)

I'm very curious to see if you can reproduce my findings. I guess it might be possible to rig something a little cleaner in the html than the double embed. Don't want to spend to much time on it if you cannot reproduce the basic problems though.

Hmm... I can repro what you describe. Will there be no end to this travesty?

Adam, could you try changing the first line of the script to this:

document.write("<NOSCRIPT class=fix><OBJECT style=\"display:none\">")

And change the closing line in the HTML to:

<!--[if gte IE 6]></OBJECT></NOSCRIPT><![endif]-->

The change you suggested above seems to resolve the remaining problem - although it's even 'uglier-than-sin' than before! ;)

It's not immediately clear to me why IE 6 works ok - when only IE 7 throws away the outer object tag. I would expect the secondary object to be hidden in IE 6 given the code.

Even so, seems like we have a workable solution for the moment (with fingers crossed there aren't any other intentional changes before IE 7 actually ships!).

I reported the higher level NOSCRIPT changes to the Internet Explorer 7 dev team through Microsoft Connect and for the moment Microsoft are saying that the changes to the NOSCRIPT behavior are essentially intentional.

You'll need to signup in order to see the bug report thread on this...
https://connect.microsoft.com/feedback/Comment.aspx?SiteID=136&FeedbackID=63086

Thanks

Adam

Your page does'nt show up when I point with IE 7. But does work with IE6

Your solution will not work for Flash content that communicates with the page. No idea why, but the content displays correctly and the page can communicate with Flash, but Flash cannot communicate back. Not a problem if you don't need 2-way communication. Also, you should change the code so that it doesn't replace the onload event but tacks the call onto it, such as:

window.onloadOld = window.onload;
window.onload = function() {
elems=document.getElementsByTagName("noscript");
for(i=elems.length-1;elem=elems[i];i--) {
if(elem.className=="fix")
elem.outerHTML = elem.innerHTML
}
window.onloadOld();
}

these solutions won't work if you want to pass parameters with the SWF file
extracting the "params" (getElementsByTagName('param')) and "attribute" arrays can work more or less,
but there is a synchronisation problem cause flash run weired (when you use object{display:none} to disable loading twice)

so I could not find final solution.. Could anybody?

Did you try the fix in Aldo's comment upthread (http://www.hoeben.net/node/135#comment-979)? It worked perfectly for me, using a Java applet which contains multiple PARAM tags. YMMV with Flash objects, but I can't imagine IE would treat them that differently.

I tried all the solutions on this page as of November 7, 06

Also tried Microsoft's solution.

While the javascripts presented here does fix it for IE6, the problem of "Click to Activate" remains for IE7.

Here's another PHP-based solution for anyone who's interested:

http://www.mediajolt.com/blog-2.php

It's used like so:

dispFlash("myfile.swf", "250", "50");

I have an "iframe" in one of my pages that embeds a php generated page. The php makes a page with a full screen applet (that I can confine to the iframe). When I implement the above code ("final(?) update") it works great on the full screen php page but not in the iframe. Any suggestions?

I figured out the problem. Please ignore the last post. :-)

!!!! BIG NEWS !!!!

The easiest way to do it now (in my opinion anyways) is to head over to the macromedia support center and just patch your flash. The link is here http://www.adobe.com/devnet/activecontent/#updates and wala! it does it all for you... no more slogging around trying to write out code... Even though some people like coding it out... I do most my designing at 1 am and am too brain dead to find solutions to microsofts problems... if they want help they can hire a shrink :P

Cheers,

Mike

Hi Aldo. Testing your patch. It is working to prevent the ActiveX box from displaying - but if I go back to the home page and click the link to bring up the QT movie a second time it just hangs unless the page is refreshed. Worked with the apple and MS fix too with no luck. The MS document.write fix seemed promising but a large white box appeared on the top left of the uploaded page where java script line had been inserted into the body section of the code.

My wife Laura heard you speak in Sedona and was signed up for the Lisbon summit - very disappointed it was it was cancelled so suddenly.

Thanks.

Sorry - didn't include the link to the page in question:
http://www.aspenportrait.com/maroon_bells/index.html

Thanks again.

I can't get your site to crash, yet. But that might be because I'm using IE7. What (exact) browser version are you using?

At me all is normal in IE 6.0

Does it give [if gte] for Firefox or Opera also?

<!--[if gte IE 7]> <script language="JavaScript">

<!--

document.write("I use IE 7");
//--> <![endif]--> </SCRIPT>

<!--[if gte ?]> <script language="JavaScript">

<!--

document.write("I use Firefox");
//--> <![endif]--> </SCRIPT>

Conditional comments are only conditional for Internet Explorer. Other browsers just see them as comments. A comment in HTML opens with <!-- and closes with -->. The first line opens a comment, for all browsers except IE7. This comment is not closed untill the first occurance of -->. The nesting in your code is quite wrong.