EOLAS, Microsoft & “Frankenstein”

A simple search for Eolas and Internet Explorer will reveal mo’ betta’ detail about this, but here’s the Jonathan’s Notes version:
Here’s a good description of the Eolas issue, with links.

  • The 1-man company, Eolas, sued Microsoft a few years ago, claiming MS owed them half a beeellion dollars because IE can show multimedia content on a webpage. Eolas owns one of those vague patents that covers any variation of this they can think of. Jerk.
  • Microsoft lost the court case, but to avoid paying out 1/80th of Bill Gates’ net worth to the Eolas peon, they decided to alter how Internet Explorer shows multimedia instead (Why pay out to 1 guy when you can screw doz-thousands of developers who’ve been using your technology for years? It just wouldn’t be the Microsoft way!)
  • After April 11, 2006 Internet Explorer’s new behavior will require visitors to a webpage that contains Flash, PDFs, Windows Media or Real Player (any ActiveX plugin) to first enable that media before they can view it. If they leave the page and come back, they have to enable it again. Annoying as hell.

I’ve seen three solutions for this.

  1. Do nothing. Accept the ugly popup prompts to enable multimedia before it appears.
  2. Add a new attribute into the <object> tag called “NOEXTERNALDATA”. This tells the prompting system to buzz off, but also tells your multimedia that it cannot load external data. Handy if your flash movie is self contained. Not so much if it has to call an external data file to get a list of images to display. But there’s problems:
    • It violates XHTML validation rules (and valid pages are smaller faster better nicer bla bla bla)
    • It involves modifying every instance of every <object> tag you’ve got. Tedious
    • It really might stop your multimedia from reading other sources for the data to display.
  3. Concoct javascript code that will write the exact same <object> tag that’s now “illegal” in a web page, to your web page. What!? That’s the legal system for you. Have javascript write the code and you’re fine.

Personally, the sites I’m working with don’t have a lot of <object>s on them, but I hate the concept of changing every instance, so I set off looking for a good Javascript solution that I can apply in a header include and avoid changing every page.

Found it. Here’s my Frankenstein version of widespread goodies:

function rewriteContent() {
	// Found via: http://codingforums.com/showthread.php?s=7332402ac03df0099a4793deddaa07c2&p=427364
	// Intended to rewrite tags to avoid IE/Eolas problems
	var v=document.getElementsByTagName("embed");
	for(i=0;i<v .length;i++){
		var el=v[i];
		el.outerHTML=el.outerHTML
	}
}
function init() {
	// Found via: http://dean.edwards.name/weblog/2005/09/busted/
	// Used to call rewriteContent as soon as the DOM has loaded.
	// quit if this function has already been called
	if (arguments.callee.done) return;

	// flag this function so we don't do the same thing twice
	arguments.callee.done = true;

	// call rewriteContent
	rewriteContent();
};
// Part of: http://dean.edwards.name/weblog/2005/09/busted/
/* for Mozilla */
if (document.addEventListener) {
   document.addEventListener("DOMContentLoaded", init, null);
}

/* for Internet Explorer - IE's conditional compiling is used: */
/*@cc_on @*/
/*@if (@_win32)
   document.write("<script defer src=/js/ie_init.js>< "+"/script>");
/*@end @*/

/* for other browsers */
window.onload = init;

What it does:
rewriteContent() is a simple: find every <embed> tag on the page, and rewrite it via script. After all, that’s legal.

init() is a gift to everyone who’s upset with the idea of waiting for window.onload to fire before altering the content of a page via javascript. It looks for the page’s Document Object Model (DOM) to be finished (read: created) and can start working right away – before images download. Excellent. It contains a flag to indicate that it’s already run, so if it gets called multiple times (and it will), it only has an effect once. Tidy.

The script after the functions is the multi-browser method of firing init. Mozilla has an event for it. IE uses conditional compiling to call an external script (an unchanged, external copy of the init function) using the “defer” option. “Defer” tells IE to wait until after the DOM is loaded. Nifty. The last section is for any other browser and just falls back on window.onload (it also guarantees init will be called more than once on Mozilla or IE, but that’s already been handled in the init function).

In testing this, I found IE had more success replacing the <embed> tag than the <object> tag, so I changed the one instance on my site that used <object>.

Now, <embed> supposedly isn’t valid XHTML, but it does work in every browser I’ve tested… so I’ve decided to withhold giving a damn about validation. The XHTML nazi’s are going to persecute me for that, I know.

So now, I inserted this new code into my existing javascript header include, and I don’t have to worry about the <embed>s all over my site – they’re automatically, nicely displayed without the annoying popup, and without having to modify individual pages.

If someone without javascript enabled visited my site, they’d get the default <embed> tag behavior – the flash/pdf would display and run, but any interaction with the visitor would require that initial activiation click or keystroke. So I’m satisfying as many people as possible, as easily as possible, and denying no-one. Not bad.