Become a fan of Slashdot on Facebook

 



Forgot your password?
typodupeerror
×
Programming

Journal Quantum Jim's Journal: Reading Files in Internet Explorer with JScript

Internet Explorer is a strange beast. I happened to be writing a DHTML Behavior to fix up some browser incompatibilities. One thing it had to do was download a CSS file and store it as a string for interpretation later. If ActiveX was enabled, then it is simply a matter of using the (relatively cross browser) XMLHTTP object:

function readFile(url) {
var httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
httpRequest.open("get", url, false);
httpRequest.send();
return httpRequest.responseText;
};

In a perfect world, I'd use this one. On the other hand, in a perfect work everyone would be using Mozilla to browse the web. ;-) My script must work even if ActiveX is disabled, which complicates things. There is also a built-in download behavior, but it still doesn't work if ActiveX is turned off. Custom DHTML Behaviors fortunately still work as long as active scripting is enabled, so not all hope is lost.

Microsoft jumped on the XML bandwagon early while developing Internet Explorer 5.0. Their first attempt used something called xml data islands. Instead of loading an XML document directly into the browser, they used an extension to the common SGML version of HTML - an <xml> element. It's sort of like <script> for XML: it can be wrapped around the XML or just link to an external document.

It also exposes a limited interface to an XmlDocument class. Since the object is represented as a SGML element, we can create one with the document.createElement("xml") factory method. There's also a nice side effect, where its interface still works even before being added to the DOM tree. (Some elements, like <iframe>, must be added before being used with penalty of an Unknown Error from IE.) Thus we could load any XML data - using the parts of the XmlDocument interface that work - with the following function:

function readFile(url) {
var newFrame = document.createElement("xml");
newFrame.async = false;
if (newFrame.load(url)) return newFrame.xml;
else return "";
};

Loading the CSS file now would result in an error since it isn't an XML file. (This strict parsing rule - unlike HTML - is actually the correct behavior according to the spec). Unfortunately, it can't be fixed without the ability to resolve external entities, which isn't available for security reasons. The solution is a compromise by adding a few lines to the files so IE thinks they are valid XML documents. This doesn't mean that the CSS files have to be invalid. Thank the W3C deities for adding comment declarations to the core CSS grammar for compatibility with SGML HTML. Internet Explorer's xml processor returns the comments (even though it doesn't half to), so the style sheet data can be inferred from the following:

Beginnning:
<!--
Ending:
/* --> <style/> <!-- */ -->

The SGML-style comments hide the CSS-style comments and the rest of the code. Retrieving the valid CSS is as simple as reading the value of each XML node:

function loadFile(url) {
var nodeText = "", cssText = "";
var newFrame = document.createElement("xml");
newFrame.async = false;
if (newFrame.load(url)) {
var children = newFrame.childNodes;
var numOfChildren = children.length;
for (var ii = 0; numOfChildren > ii; ii++) {
nodeText = children[ii].nodeValue;
if (nodeText) cssText += nodeText;
}
}
return cssText;
};

That's easy from the developer's point of view; however, it's an ugly ugly ugly hack for the user (CSS author). Depending on your requirements and taste, the following hider may be easier to stomach:

Beginnning:
<!-- /* --> <style> */
Ending:
/* </style> <!-- */ -->

Either case doesn't matter to the function above. Just be careful if you're having lunch. ;-)

P.S. I plan on adding this article to my program's documentation. Help editing it and constructive criticism would be much appreciated.

Note: A bug with /. puts a typo in the first code block. That should be "open" not "o pen". Cowboy Neil must hate me!

**IMPORTANT** THE ABOVE NO LONGER SEEMS TO WORK WITH INTERNET EXPLORER 6 SP 2. USE THIS PATTERN INSTEAD

This discussion has been archived. No new comments can be posted.

Reading Files in Internet Explorer with JScript

Comments Filter:

"More software projects have gone awry for lack of calendar time than for all other causes combined." -- Fred Brooks, Jr., _The Mythical Man Month_

Working...