Re: John Resig has a new idea
- From: David Mark <dmark.cinsoft@xxxxxxxxx>
- Date: Sat, 28 Mar 2009 13:28:46 -0700 (PDT)
On Mar 28, 4:08 pm, Garrett Smith <dhtmlkitc...@xxxxxxxxx> wrote:
Richard Cornford wrote:
dhtml wrote:
On Mar 27, 3:12 pm, Richard Cornford wrote:
Garrett Smith wrote:
Richard Cornford wrote:
Danny wrote:
[...]
As we have already established beyond and reasonable doubt that - value
= object[0] - causes an exception to be thrown when - object - is an
empty styleSheets collection, and having observed the (conditional)
'equivalence' between property accessors and calls to the collection's -
item - method, - object.item(0) - throwing the same exception is
entirely "to be expected".
In this case, it should return null. Even by MSDN documentation,
which states:-
| Returns an object or a collection of objects if successful,
| or null otherwise.
Right, so Microsoft have a bug (in their code or their documentation),
but that is hardly unexpected.
Not uncommon. I try to hold the software vendor to the expectation that
their documentation of their software be correct, even if it is often
incorrect. So, I sort of "expect" that, even though I know it is often
not that case.
Richard noted in a later post that according to other MS
documentation, the behavior is unexpected.
[...]
The error occurs whether by property access, by calling the
item method,
The two are specified as being equivalent for some property
names/arguments, so no real surprise there.
And the item method is specified as having a very clear behavior:-
| Return Value
|
| StyleSheet
|
| The style sheet at the index position in the StyleSheetList,
| or null if that is not a valid index.
Yes, but a property accessor is only specified as being equivalent if
the property name is an "integer index", so the behaviour of property
accesses where the property name is not an "integer index" is not
specified. Thus the throwing of exceptions is allowed with the use of
some property accessors (as only ECMA 262 apples in those case), and it
becomes important to determine what an "integer index" means.
The parameter name is |index|. When they say "integer index", they
probably should have instead used just |index|. Integer could be
replaced with "dom unsigned long". That is, an unsigned integer type
that has values in the range [0, 4294967295].
This index would be provided as a string for property access. If a
string is not used, the value is converted to a string value (the
property access operator requires that). For example, styleSheets[1]
converts to styleSheets["1"], styleSheets[NaN] converts to
styleSheets["NaN"].
IE identifies identifies floating point numbers as "integers", too (see
below). But then Gecko and AppleWebKit do too, but only when using the
item method. This may be to copy IE to support poorly coded sites (guess)..
The w3c does not define a standard "collection" interface with
an item method. IE documents its item method as being something
that operates on "various collections". This is fine. What is
not fine is IE's design and testing.
Not really. IE had - item - methods on its collections long before
there were W3C DOM standards. That makes it difficult to assert
that anything they do is wrong, except where it disagrees with
Microsoft's own documentation of what they are supposed to do.
If blame is to be
That is the problem.
It is _a_ problem, or rather it is a potential problem (as it really
isn't that difficult to work with styleSheets collections in a way that
does not provoke any issues, suggesting that practical issue here was
introduced by something outside of IE and the W3C standards).
The out-of-bounds problem does not normally occur. I found the behavior
of IE's item method more interesting than the fact of a logical mistake
in jQuery.
IE's item method is designed to work on a "map" type collection, a
"list" type collection, or one of IE's Map/List hybrid collections. It
returns a node, a collection, null, or throws an error.
We can test this method on a childNodes collection (a hybrid collection
in IE). The results show that the documentation is wrong and that the
behavior is unstable.
No.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en" >
<head>
<title>childNodes.item() test</title>
</head>
<body>
<pre id="a">
<script type="text/javascript">
var childNodes = document.body.childNodes;
try{
document.write('childNodes.item(0): ');
document.writeln( childNodes.item(0));
document.write('childNodes.item("a"): ');
document.writeln( childNodes.item("a") );
document.write('childNodes.item("xxx"): ');
document.writeln(childNodes.item("xxx") );
document.write('childNodes.item("0.2"): ');
document.writeln(childNodes.item("0.2"));
document.write('childNodes.item(1): ');
document.writeln(childNodes.item(1));
document.write('childNodes.item(999): ');
document.writeln(childNodes.item(999));} catch(ex) {
document.writeln(ex.name + ": " + ex.message);}
</script>
</pre>
</body>
</html>
(Only the first and last calls to childNodes.item are per w3c standard.)
Results:
IE6:
childNodes.item(0): [object]
childNodes.item("a"): [object]
childNodes.item("xxx"): [object]
childNodes.item("0.2"): [object]
childNodes.item(1): TypeError: Invalid procedure call or argument
Explicitly allowed.
Safari 4.0 (528.16), Firefox 3.0.7, Google Chrome:
childNodes.item(0): [object Text]
childNodes.item("a"): [object Text]
childNodes.item("xxx"): [object Text]
childNodes.item("0.2"): [object Text]
childNodes.item(1): [object HTMLPreElement]
Opera 9.6:
childNodes.item(0): [object Text]
childNodes.item("a"): [object HTMLPreElement]
childNodes.item("xxx"): null
childNodes.item("0.2"): null
childNodes.item(1): [object HTMLPreElement
Well, part of the problem. The item method
doesn't do in IE what MSDN says it does.
Apparently not, and that is a bug (which Microsoft will probably fix if
it is brought to their attention, though they may just fix the
documentation).
Instead, it throws an error (sometimes). It does not check the
type of the first argument. Instead, it tries to convert it to a
number. Look:-
javascript: alert(document.body.childNodes.item( "XXX").nodeName );
javascript: alert(document.body.childNodes.item(""))
- returns the first element in the document. In IE6, anyway.
Type-converting arguments is a very javascript-like thing to be doing. I
don't think anyone would reasonable complain about that, as it should be
the responsibility of the javascript programmer to ensure they are
passing the right types of values into function/method calls (that is
one of disciplines that goes with using a loosely type language).
Type converting arguments may be javascript-like, but type converting
"XXX" is totally not javascript-like.
Taking that result of said conversion and applying it to get an item out
of a list is absurd.
What is worse is that Gecko mimics that behavior (sort of). Gecko
returns the first Node, however, not the first element. Since Gecko
recognizes text nodes, it returns the first text node. AppleWebKit
mimics this behavior also. Opera takes a more sane option of returning
null.
Now we have MSIE going and trying to change that behavior with:-
| Windows Internet Explorer 7 and later. If given a string that is not a
| numeric index, this method throws an error if no id property with that
| string value is found.
[...]
It doesn't even seem to b
callable, as:-
typeof childNodes.item
- is "string" in IE.
Mad as that may be it has been there since IE4 to my certain knowledge,
and has gone sufficiently unnoticed over that time as to suggest it
isn't really an issue.
Feature tests would not identify "item" as something that can
be called.
No feature test has ever been devised that will accurately determine the
capability of host method.
Thomas and David's "isHostMethod" (which I do not use) would return
false in that case.
It is true enough that this is the first documented case in ten years
of a host method that fails the isHostMethod test. Likely never came
up as nobody would test this method. Though perfectly allowed for
host objects, I think the "string" result should be reported to MS as
a bug.
I wouldn't throw the baby out with the bath water though. Using the -
in - operator alone fails in far more places as it tells you nothing
about the property. You have to have a central function anyway as you
never know how the rules will change from one year to the next.
Granted, it had been a decade of mind-numbing monotony on that front
until this find. The fix for isHostMethod is simple: document this
one known deviation.
[snip]
.
- Follow-Ups:
- Re: John Resig has a new idea
- From: Garrett Smith
- Re: John Resig has a new idea
- References:
- John Resig has a new idea
- From: beegee
- Re: John Resig has a new idea
- From: Richard Cornford
- Re: John Resig has a new idea
- From: Danny
- Re: John Resig has a new idea
- From: Richard Cornford
- Re: John Resig has a new idea
- From: Garrett Smith
- Re: John Resig has a new idea
- From: Richard Cornford
- Re: John Resig has a new idea
- From: dhtml
- Re: John Resig has a new idea
- From: Richard Cornford
- Re: John Resig has a new idea
- From: Garrett Smith
- John Resig has a new idea
- Prev by Date: Re: John Resig has a new idea
- Next by Date: Re: John Resig has a new idea
- Previous by thread: Re: John Resig has a new idea
- Next by thread: Re: John Resig has a new idea
- Index(es):
Relevant Pages
|