I have the following code which works in FF / Chrome
var stack = [Array.prototype.slice.call(document.getElementsByTagName("body")[0].childNodes)], nodes, node, parent, text, offset;
while (stack.length) {
nodes = stack.pop();
for (var i=0, n=nodes.length; i<n; ++i) {
node = nodes[i];
switch (node.nodeType) {
case Node.ELEMENT_NODE:
if (node.nodeName.toUpperCase() !== "SCRIPT") {
stack.push(Array.prototype.slice.call(node.childNodes));
}
break;
case Node.TEXT_NODE:
text = node.nodeValue;
offset = text.indexOf("[test=");
if (offset >= 0 && text.substr(offset).match(/^(\[test=(\d+)\])/)) {
parent = node.parentNode;
var before = document.createTextNode(text.substr(0, offset));
link = document.createElement("a"),
after = document.createTextNode(text.substr(offset + RegExp.$1.length));
link.appendChild(document.createTextNode(text.substr(offset, RegExp.$1.length)));
link.setAttribute("href", "http://example.com/" + RegExp.$2);
parent.insertBefore(after, node);
parent.insertBefore(link, after);
parent.insertBefore(before, link);
parent.removeChild(node);
stack.push([after]);
}
}
}
}
Basically what it does is if it finds [test=25] in the page it converts it to a link which points to example.com/25
In IE I get the following error: JScript Object Expected on first line:
var stack = [Array.prototype.slice.call(document.getElementsByTagName("body")[0].childNodes)], nodes, node, parent, text, offset;
This error occurs in both IE7 and IE8.
Any help would be appreciated.
Thanks.
It’s not legal to call
Array.prototype.sliceon aNodeListobject as returned by thechildNodesproperty (or various other DOM methods).Normally it wouldn’t be legal to call
Thing.prototype.methodon anything but an instance ofThing, however browsers have traditionally allowed — and the ECMAScript Third Edition standard requires — a special case for manyArray.prototypemethods so that they can be called on any native-JavaScript object which is sufficiently like anArray. This means, notably, that they can be used on theargumentsobject, which looks like anArraybut actually isn’t.However,
NodeListand the other collection objects in the DOM are not defined to be native JavaScript objects; they are allowed to be ‘host objects’, which are implemented completely by the browser and not the language. All bets are off for host objects…So
Array.prototype.slicemay not work for NodeList, and in IE before version 8, indeed, it won’t.If you want to make a plain-Array copy of a NodeList, you’ll have to do it the long but safe way:
Incidentally, you can make that linkifier a bit simpler by using
textnode.splitText, and I’d be very wary about using the globalRegExpproperties, as if any unexpected regex work occurs in one of the intervening calls they’ll be lost. Looking at the match object is usually better. See this question for another attack at basically the same problem.