/    Sign up×
Community /Pin to ProfileBookmark

Beta testers needed

Hi all

We have put together an unobtrusive implementation of the HTMLElement and sub interfaces for IE 6.0+. The first beta version is out and we would very much like some help testing it.

For those of you who can spare some free time please see [URL=”http://www.jslab.dk/epe.introduction.php”]http://www.jslab.dk/epe.introduction.php[/URL] for more info.

Any help is appreciated.

to post a comment
JavaScript

17 Comments(s)

Copy linkTweet thisAlerts:
@UltimaterMar 27.2008 — Neat, another http://www.browserland.org/scripts/htmlelement/

Always interesting to see how others attempt to define a HTMLElement constructor for IE.
Copy linkTweet thisAlerts:
@DokauthorMar 27.2008 — I'm aware of that attempt but the solution lacks several important features. It's simpler but imcomplete.
Copy linkTweet thisAlerts:
@UltimaterMar 28.2008 — I think it makes more sense to take this route:
<i>
</i>&lt;!--[if IE]&gt;
&lt;style type="text/css"&gt;
*{behavior:url(htmlelement.htc)}
&lt;/style&gt;
&lt;![endif]--&gt;

&lt;script type="text/javascript"&gt;
if(typeof HTMLElement=="undefined")HTMLElement=new Function();
if(typeof HTMLSelectElement=="undefined")HTMLSelectElement=new Function();

HTMLSelectElement.prototype.c=function(){
alert(this.options[this.options.selectedIndex].text)
};
&lt;/script&gt;

&lt;/head&gt;

&lt;body&gt;
&lt;select onchange="this.c()"&gt;&lt;option&gt;true&lt;option&gt;false&lt;/select&gt;
&lt;/body&gt;
&lt;/html&gt;


<i>
</i>&lt;PUBLIC:COMPONENT&gt;
&lt;script type="text/javascript"&gt;
//element is set via HTC
for(prop in HTMLElement.prototype)
element[prop]=HTMLElement.prototype[prop];

if(element.tagName=="SELECT")
for(prop in HTMLSelectElement.prototype)
element[prop]=HTMLSelectElement.prototype[prop];
&lt;/script&gt;
&lt;/PUBLIC:COMPONENT&gt;
Copy linkTweet thisAlerts:
@UltimaterMar 28.2008 — Unlike my CSS selecting approach which is unable to force inheritance until an element is appended to the page,

I give you credit for thinking to override createElement in order to force inheritance prior to the element being appended to the page.

innerHTML created elements are a bit tricky to keep up with. I'm not too sure how well your script does with that.
Copy linkTweet thisAlerts:
@DokauthorMar 28.2008 — You are Jason Karl Davis? If so I give you credit for coming up with the solution in the first place. Using behaviors (htc) is a nice and clean solution and I was inspired by the way you use an expando to create a dummy prototype. I actually tried to build upon it but abandoned the idea somewhere along the road in favor of creating a solution from scratch.

Changes to innerHTML is handled by an event handler registered on the onpropertychange event. The function makes a depth-first search of all child nodes which are inserted and extends those which should be extended.

There are several other issues as well though.

The dummy prototype is 'live'. Any changes made to the prototype is instantly reflected to all affected elements.

An element now actually have a 'class' of HTMLDivElement for instance which can be used when making comparisons.

The two issues above create the following side effect. Modifying the prototype before onload is actually a modification of the real prototype object so you need to synchronize between the real and the dummy prototype.

Nodes which are in memory but not in the DOM may need extending when applied to appendChild, insertBefore or replaceChild.
Copy linkTweet thisAlerts:
@UltimaterMar 28.2008 — Fails my test using both document.createElement("img") and new Image().

<i>
</i>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="eng"&gt;
&lt;head&gt;
&lt;meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /&gt;
&lt;title&gt;&lt;/title&gt;
&lt;script type="text/javascript" src="http://www.jslab.dk/scripts/epe.1.9.4.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
HTMLElement.prototype.getOuterHTML=function(){
return document.createElement("div").appendChild(this.cloneNode(true)).parentNode.innerHTML;
}
&lt;/script&gt;

&lt;script type="text/javascript"&gt;
img=(true)?document.createElement("img"):new Image();
img.src="http://www.webdeveloper.com/forum/image.php?u=30185&amp;dateline=1128637189";
img.alt="Ultimater's Avatar";
if(img.getOuterHTML)alert(img.getOuterHTML())
else alert("Failed to inherit!");
&lt;/script&gt;

&lt;/head&gt;
&lt;body&gt;
&lt;script type="text/javascript"&gt;
if(window.EPE){//IE
EPE.__R1=document.documentElement.childNodes[1].onload;
document.documentElement.childNodes[1].onload=EPE.init;
}
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

Sorry to disappoint you but I'm not the author of the script in my link. I wrote up the following script afterwards as a practical solution though.
Copy linkTweet thisAlerts:
@DokauthorMar 28.2008 — It works for me. The function you are creating is returning the default value of undefined.

If I replace
[CODE]HTMLElement.prototype.getOuterHTML = function() {
return document.createElement("div").appendChild(this.cloneNode(true)).parentNode.innerHTML;
}[/CODE]

with
[CODE]HTMLElement.prototype.getOuterHTML = function() {
return 'Inherit succeded';
}[/CODE]

then I get no errors. So the error is in IE handling your function as it works fine in Moz. Do you agree?
Copy linkTweet thisAlerts:
@UltimaterMar 28.2008 — No, my function is cross-browser. Your script is corrupting the DOM methods.

This works:
<i>
</i>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="eng"&gt;
&lt;head&gt;
&lt;meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /&gt;
&lt;!--&lt;script type="text/javascript" src="http://www.jslab.dk/scripts/epe.1.9.4.js"&gt;&lt;/script&gt;--&gt;
&lt;script type="text/javascript"&gt;
onerror=function(){
alert(Array.apply(null,arguments).join("n"))
}
if(typeof HTMLElement=="undefined")HTMLElement=new Function();

HTMLElement.prototype.getOuterHTML=function(){
return document.createElement("div").appendChild(this.cloneNode(true)).parentNode.innerHTML;
}
&lt;/script&gt;
&lt;title&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script type="text/javascript"&gt;
img=(true)?document.createElement("img"):new Image();
img.src="http://www.webdeveloper.com/forum/image.php?u=30185&amp;dateline=1128637189";
img.alt="Ultimater's Avatar";
alert(HTMLElement.prototype.getOuterHTML.apply(img))
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

Now uncomment your script then it corrupts the DOM methods and IE throws an error.
Copy linkTweet thisAlerts:
@DokauthorMar 28.2008 — You're right. The error has been corrected. Script have been updated to 1.9.5. You need to download the new script to verify.
Copy linkTweet thisAlerts:
@UltimaterMar 28.2008 — Well done, it handles new Image as well now and supports my HTMLElement.prototype.getOuterHTML function.

Ok 1.9.5 passes my first test.
Copy linkTweet thisAlerts:
@DokauthorMar 28.2008 — Thanks for repoting the error. I never thought of new Image but I guess some internal conversion is done so that it is treated like a common node. Would you like me to credit you in the source and on the site?

If yes you can send me a private message with the info which I should include.
Copy linkTweet thisAlerts:
@UltimaterMar 28.2008 — Fails my dynamic table creation test:
<i>
</i>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="eng"&gt;
&lt;head&gt;
&lt;meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /&gt;
&lt;title&gt;&lt;/title&gt;
&lt;script type="text/javascript" src="http://www.jslab.dk/scripts/epe.1.9.5.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
HTMLElement.prototype.getOuterHTML=function(){
return document.createElement("div").appendChild(this.cloneNode(true)).parentNode.innerHTML;
}

HTMLTableRowElement.prototype.insertCells=function(n){
for(var i=0;i&lt;n;i++)
this.insertCell(-1)
return this.getElementsByTagName("td");
}

var tbl=document.createElement("table");
var row=tbl.insertRow(-1);
if(row.insertCells){
var cells=row.insertCells(3);
cells[0].appendChild(document.createTextNode("1"))
cells[1].appendChild(document.createTextNode("2"))
cells[2].appendChild(document.createTextNode("3"))
alert(tbl.getOuterHTML())
}
else alert("Failed to inherit!");
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script type="text/javascript"&gt;
if(window.EPE){//IE
EPE.__R1=document.documentElement.childNodes[1].onload;
document.documentElement.childNodes[1].onload=EPE.init;
}
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
Copy linkTweet thisAlerts:
@DokauthorMar 28.2008 — Thanks. Keep 'em coming ? Corrected. Script updated to 1.9.6.beta.js.
Copy linkTweet thisAlerts:
@UltimaterMar 28.2008 — Firefox itself has issues extending HTMLCollection so I'm using Object:
<i>
</i>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="eng"&gt;
&lt;head&gt;
&lt;meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /&gt;
&lt;title&gt;&lt;/title&gt;
&lt;script type="text/javascript" src="http://www.jslab.dk/scripts/epe.1.9.6.beta.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
HTMLElement.prototype.getOuterHTML=function(){
return document.createElement("div").appendChild(this.cloneNode(true)).parentNode.innerHTML;
}

HTMLTableRowElement.prototype.insertCells=function(n){
for(var i=0;i&lt;n;i++)
this.insertCell(-1)
return this.getElementsByTagName("td");
}

Object.prototype.appendChildren=function(){
for(var i=0;i&lt;arguments.length;i++)
this[i].appendChild(arguments[i]);
}

var tbl=document.createElement("table");
with(document)a=[createTextNode("1"),createTextNode("2"),createTextNode("3")];

var cells=tbl.insertRow(-1).insertCells(3);
if(cells.appendChildren){
cells.appendChildren(a[0],a[1],a[2])
alert(tbl.getOuterHTML())
}
else alert("Failed to inherit");
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;&lt;/body&gt;
&lt;/html&gt;


Dunno if you want to go through the trouble of keeping Object up-to-date...
Copy linkTweet thisAlerts:
@DokauthorMar 28.2008 — HTMLCollections are not implemented and will not be right now. Can you post a W3C reference on how they should behave?
Copy linkTweet thisAlerts:
@DokauthorMar 28.2008 — Found the reference and looked at our code. It is probably possible to implement the Object -> Node -> Element -> HTMLElement inheritance heirachy but also very difficult without touching the native Object.prototype...and I'd rather not.

So for now inheritance is simply HTMLElement -> HTML[SubInterface]Element which is still very useful.
Copy linkTweet thisAlerts:
@DokauthorMar 28.2008 — Well it looks like its possible. Your test does not fail anymore.

It is only preliminary support for collections via getElementsByTagName. Other methods which returns collections will not work untill they are implemented but the principle is the same.

HTMLCollection now inherits from Object. It is not possible to extend HTMLCollection.prototype by itself yet but it shouldn't be difficult to implement that.

Thanks for reporting the errors. Script is updated and can be downloaded from http://www.jslab.dk/download.php
×

Success!

Help @Dok spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.2,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...