ObjectSwap: Bypassing the ActiveX Activation Issue in IE

Share this article

Microsoft’s recent decision to change the way ActiveX objects are handled in Internet Explorer, following the patent law suit by EOLAS, has created a serious problem for the developer community.

All ActiveX controls in Internet Explorer — including Flash and Shockwave — will need to be activated by a mouse click (or by hitting Tab and the Enter key) before the user can interact with the control. This is bound to impair the user experience of any web site that embeds Flash, and it’s up to the Flash and HTML developers to clean up the mess.

Available Solutions

You can bypass the activation requirement by using an externally linked script, such as JavaScript, to embed the ActiveX content. Solutions are currently available for Flash, such as FlashObject and UFO.

These work well for embedding new Flash content using JavaScript. But what about existing object tags, which will need to be rewritten, or browsers with JavaScript disabled? These situations require an alternative solution.

ObjectSwap

The ObjectSwap solution presented in this article takes all these issues into account. It captures all existing object tags and replaces them with … themselves. This forces an automatic activation in Internet Explorer, while leaving other browsers alone. Similar solutions have been developed in parallel, but this article will concern itself only with ObjectSwap.

Although this solution was developed primarily with Flash in mind, it should also work with other ActiveX controls, such as Shockwave. The script affects all the object tags in the page, but the developer can choose to exclude a specific object by setting its class name to “noswap”.

Implementation

ObjectSwap was written with a view to make implementation as easy as possible, with minimum disruption to existing code. The only change you need to make to your HTML page is to link the script in the <head> tag for every page that includes ActiveX objects, like this:

<script type="text/javascript" src="objectSwap.js"> </script>

Once you’ve done that, you can keep on using your favourite technique for embedding ActiveX content. For Flash, that means either the Adobe/Macromedia default setting using object/embed tags, or the standards-compliant technique that uses only the object tag (better known as Flash Satay).

Flash Detection

So far, so good. But since we’re already using JavaScript, why not avail ourselves of the opportunity to add some Flash Detection to the mix? We can achieve this by adding a new param definition to the Flash object, for example:

<param name="flashVersion" value="7" /> 

The script looks for this param and, if it exists, will transform the object into a div that displays the alternative content. This content is not generated by the script, but instead must already reside inside the object tag, and display alternative text, images, links to the Flash installer, and so forth. Internet Explorer normally ignores this content if Flash is present. This is also true for other browsers when you use the Flash Satay method, so you can simply add the content anywhere in the body of the object.

On the other hand, if the object/embed method is used, gecko-based browsers like Firefox and Netscape will display the alternative content alongside the embedded movie. The solution is to enclose the content within HTML comments, which will be stripped by the script when the content is displayed. There should be a space or a line-break between the comment tags and content, to avoid conflicts with any IE conditional comments that happen to be inside the object tag:

<!--   
<p>You need <a href= "http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash">Flash</a> to view this content.</p>
-->

Of course, you can also choose to ignore the Flash detection option, or use Adobe’s express installation for Flash 8 instead.

Browser Support

The activation issue of ActiveX objects affects only Internet Explorer, so most of the code will also affect only IE. However, the Flash detection code needs to work with other browsers as well. This means that the objectSwap function will be called for all browsers to perform the Flash detection service, if required, but will only execute the object swap on IE, leaving other browsers unaffected.
This is all you need to know to start using the script. You can download the script and examples here.

However, if you’d like to know more about how ObjectSwap works, the following sections will reveal the inner workings of the script.

How It Works

First, the script cycles through all the object tags in the HTML source code and retrieves their outerHTML values:

var objects = document.getElementsByTagName('object'); 
for (var i=0; i<objects.length; i++) {
 var o = objects[i];
 var h = o.outerHTML;

Since Internet Explorer does not include any of the object’s param tags in its outerHTML (or innerHTML), they need to be extracted separately into a string:

var params = ""; 
for (var j = 0; j<o.childNodes.length; j++) {
 var p = o.childNodes[j];
 if (p.tagName == "PARAM"){

    ....

   params += p.outerHTML;
 }
}

The generated "params" string is spliced into the outerHTML code:

var tag = h.split(">")[0] + ">"; 
var newObject = tag + params + o.innerHTML + " </OBJECT>";

And, finally, the new generated HTML replaces the original:

o.outerHTML = newObject; 

Hiding the Objects

There are still a few things to be done. First of all, we want to prevent the objects from loading twice — once when they’re initiated in the HTML code, and again after they’re swapped. We achieve this by writing a new style sheet to the document before the page loads. The style uses display: none to take the objects out of the document flow, delaying their loading until the swap is complete:

document.write ("<style id='hideObject'> object {display: none;} </style>");

After the swap, the style is disabled and the objects are allowed to load:

document.getElementById("hideObject").disabled = true;

Detecting Flash

As it cycles through the parameter list for each object, the objectSwap function checks for the existence of the flashVersion param and, if it’s found, executes a Flash detection method:

if (p.name == "flashVersion") { 
 hasFlash = detectFlash(p.value);

The method looks for Flash in two types of browsers. First, it checks whether the plugin is present in the navigator.plugins array, which applies to gecko-based browsers:

detectFlash = function(version) { 
 if(navigator.plugins && navigator.plugins.length){
   var plugin = navigator.plugins["Shockwave Flash"];
   if (plugin == undefined){
     return false;
   }

If a plugin is found, the code still needs to check for the installed version. This is achieved by retrieving the third item in the plugin’s description property and checking it against the passed version parameter:

var ver = navigator.plugins["Shockwave Flash"].description.split(" ")[2]; 
 return (Number(ver) >= Number(version))

Next, the script checks for the plugin in Internet Explorer. In JavaScript, it achieves this by trying to create a new Flash ActiveX object with the passed version. If JavaScript is unable to create the object, it will throw an exception, which is why the entire expression must be enclosed inside a try-catch block:

} else if (ie && typeof (ActiveXObject) == "function") {    
 try {
   var flash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + version);
   return true;
 }
 catch(e) {
   return false;
 }
}

Just in case some other browser has a different way of handling Flash, the method returns true at its end, as a safety net. If the browser doesn’t have the navigator.plugins array, and is not Internet Explorer, it will still try to display the Flash movie.

Back at the objectSwap method, if the script doesn’t find the correct version, the object’s id is retrieved (or a new one is assigned) and added to a queue:

if (!hasFlash){ 
o.id = (o.id == "") ? ("stripFlash"+i) : o.id;
stripQueue.push(o.id);
Later on, the queue is passed to the stripFlash method:
if (stripQueue.length) {
 stripFlash(stripQueue)
}

Stripping Flash

This method cycles through the ids in the queue and retrieves each object’s innerHTML:

for (var i=0; i<stripQueue.length; i++){ 
 var o = document.getElementById(stripQueue[i]);
 var newHTML = o.innerHTML;

For the object/embed method, where the alternative content has been hidden from Firefox and Netscape with comments, regular expressions are needed to strip the comments from the innerHTML, so that the new content can be displayed in the browser:

newHTML = newHTML.replace(/<!--s/g, ""); 
newHTML = newHTML.replace(/s-->/g, "");

Another regular expression is used to neutralise the embed tag by replacing it with a span:

newHTML = newHTML.replace(/<embed/gi, "span");

In order to transform the object into a div, the easiest thing would have been to change the object’s outerHTML. However, that doesn’t work in Firefox; instead, a new div element is created and assigned the same innerHTML, id, and className as the object:

var d = document.createElement("div"); 
d.innerHTML = newHTML;
d.className = o.className;
d.id = o.id;

Finally, the object is swapped for the new div:

o.parentNode.replaceChild(d, o);

Initiating the ObjectSwap

ObjectSwap must be executed after all the objects have loaded, by binding the objectSwap function to the window.onload event. The catch is that other linked scripts in your page might have their functions bound to the same event; the last script to do so will override all the earlier bindings, causing the other scripts to fail. This is resolved by catching existing functions bound to the event, and calling them as well: 

var tempFunc = window.onload; 
window.onload = function(){
 if (typeof (tempFunc) == "function"){
   try{
     tempFunc();
   } catch(e){}
 }
 objectSwap();
}

Naturally, this will fail if following scripts use window.onload, so you must ensure that either this script comes last, or that the following scripts use a similar technique.

Conclusion
ObjectSwap offers a complete, one-step solution to the problem resulting from the decision by Microsoft as a result of the EOLAS law suit. A single JavaScript file linked from the <head> tag of your page is all you need to avoid Internet Explorer's activation requirement. What's more, you can take advantage of the situation and enhance the user experience by adding some simple Flash detection to your page.

Frequently Asked Questions about ActiveX Activation Issue in Internet Explorer

What is ActiveX and why is it important for Internet Explorer?

ActiveX is a set of object-oriented programming technologies and tools that Microsoft developed for Internet Explorer to facilitate rich media playback. It’s important because it allows interactive content to be embedded within web pages, enhancing the overall user experience. ActiveX controls can be used for tasks such as displaying animation, gathering data, and viewing files.

Why am I experiencing ActiveX activation issues in Internet Explorer?

ActiveX activation issues in Internet Explorer can occur due to several reasons. The most common reason is that the ActiveX controls are not enabled in your browser settings. Other reasons could be outdated ActiveX controls, conflicts with other software, or security settings that block ActiveX controls.

How can I enable ActiveX controls in Internet Explorer?

To enable ActiveX controls in Internet Explorer, go to the ‘Tools’ menu, then ‘Internet Options’, and then the ‘Security’ tab. Click on ‘Custom Level’, scroll down to ‘ActiveX controls and plug-ins’, and enable the options under it. Click ‘OK’ to save the changes.

How can I update my ActiveX controls?

To update your ActiveX controls, you need to visit the official website of the software that requires the control. Download the latest version of the control and install it. Remember to restart your browser after the installation.

What should I do if my security settings are blocking ActiveX controls?

If your security settings are blocking ActiveX controls, you can adjust the settings by going to ‘Tools’, then ‘Internet Options’, and then the ‘Security’ tab. Click on ‘Custom Level’ and enable the options under ‘ActiveX controls and plug-ins’. If this doesn’t work, you may need to lower your overall security level.

Are there any risks associated with enabling ActiveX controls?

While ActiveX controls can enhance your browsing experience, they can also pose security risks as they have the potential to access your computer’s resources. Therefore, it’s important to only enable ActiveX controls from trusted sources.

Can I use ActiveX controls in other browsers?

ActiveX is a technology specific to Internet Explorer. Other browsers, such as Chrome or Firefox, do not support ActiveX controls natively. However, there are third-party extensions available that can enable ActiveX controls in these browsers.

What is the role of ActiveX controls in viewing files?

ActiveX controls can be used to view files directly in your browser. For example, an ActiveX control could be used to view a PDF file within Internet Explorer, rather than having to download the file and open it in a separate application.

How can I troubleshoot ActiveX activation issues?

Troubleshooting ActiveX activation issues can involve several steps. First, ensure that ActiveX controls are enabled in your browser settings. If they are, try updating the controls. If the issue persists, check your security settings to ensure they’re not blocking ActiveX controls.

Can I disable ActiveX controls if I no longer need them?

Yes, you can disable ActiveX controls if you no longer need them. Go to ‘Tools’, then ‘Internet Options’, and then the ‘Security’ tab. Click on ‘Custom Level’ and disable the options under ‘ActiveX controls and plug-ins’. Remember to restart your browser after making these changes.

Karina SteffensKarina Steffens
View Author

Karina is a freelance multimedia and web developer and designer. She specializes in both Flash and web standards xhtml development, as can be seen on her web site www.neo-archaic.net, where she attempts to bring the two together.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week