The navigator object contains strings which
specify the browser and version; however, this is in general not
very genuine. Mozilla (and therefore Netscape 6+) allows this to
be freely set, and Opera and IE allow it to be modified. There
are also at least 25 other javascript capable browsers with
their own strings here.
Generally though, you don't need to identify which browser is
being used. There are alternative techniques, but which one you
choose depends on why you want to redirect browsers. If it's to
offer different CSS stylesheets, then <URL:
http://w3development.de/css/hide_css_from_browsers/ >
shows many techniques. For Scripting, _object_ detection
is a better method to use.
<URL: http://www.quirksmode.org/js/support.html >
It is also known as feature detection.
Object/feature detection means checking that the object you wish
to use is supported by the browser before using it. This means
that you don't need to know what browsers support what methods,
and your code will automatically be usable on any browser that
can execute it.
if (document.getElementById &&
document.getElementById('el') &&
document.getElementById('el').style ) {
// We know that this browser supports getElementById and has
// a style object, so we can set a style property.
document.getElementById('el').style.color = "red";
}
Browser bugs can often be detected and overcome in similar ways.
<URL:
http://developer.mozilla.org/en/docs/Using_Web_Standards_in_your_Web_Pages:Developing_Cross_Browser/Cross_Platform_Pages
>
<URL: http://jibbering.com/faq/faq_notes/not_browser_detect.html >
<URL: http://dev.opera.com/articles/view/using-capability-detection/ >
<URL:
http://developer.apple.com/internet/webcontent/objectdetection.html >
==========================================
Commentary:
The entry links to the quirksmode.org article:
http://www.quirksmode.org/js/support.html
While well intentioned, this article has some information that is
factually false and would likely mislead someone learning javascript. I
found in that article:
| if (window.focus)
| means: "If the focus method is supported", while this code
| if (window.focus())
| means:
| "If you can put the focus on the window" and assumes that focus
| is supported.
Both statements are wrong.
Regarding the first statement, I am concerned with the possibility of a
browser to be configured to disallow scripts to focus windows, yet have
a focus property.
Regarding the second statement, that is just dead wrong. The
window.focus method call should return undefined where supported and the
|if| statement would be false.
He also calls document.images and "array". It is not. It is an
HTMLCollection in standards-compliant browsers.
I have added a link to Hallvord R.M. Steen's "Object Detection". The
article does not mention ToBoolean errors on ActiveX objects. I sent an
email to Hallvord and asked him to add something about that.
Rearding the the FAQ, it is not to the point enough.
| Generally though, you don't need to identify which browser is being
| used. There are alternative techniques, but which one you choose
| depends on why you want to redirect browsers.
Not to the point. Redirect browsers? No, that is not usually why browser
detection is used. "Alternative" techniques? I'd rather think of
capability detection as a "mroe sensible technique"
I think the whole thing needs a rewrite.
The points should be that browser detection is:
1) unreliable (can't trust navigator.userAgent)
2) uses an unrelated inference (it is unrelated to the problem it is
trying to solve), which:
a. causes forwards-compatibility problems
b. hides the reasoning behind the workaround, which makes
understanding the thinking behind the code more difficult to understand.
Though I haven't drafted anything. Still working on the notes index page.
Garrett
Although understandable, that looks inefficient. The following, after
checking, can be presented for actual use.
if (document.getElementById &&
(T=document.getElementById('Divn')) && (T=T.style) ) {
// ...
// ...
T.color = "red";
}
In IE, but not Firefox, one can start with
if ((T=document.getElementById) && (T=T('Divn'))
--
(c) John Stockton, nr London, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 7.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
I find MiniTrue useful for viewing/searching/altering files, at a DOS prompt;
free, DOS/Win/UNIX, <URL:http://www.idiotsdelight.net/minitrue/> unsupported.
What is with the uppercase identifiers? They only serve to confuse
the casual reader. I don't like assignments in conditionals either.
And you *never* test host methods by type conversion. Use the typeof
operator or search the archive for isHostMethod (or areHostMethods.)
>
> In IE, but not Firefox, one can start with
>
> if ((T=document.getElementById) && (T=T('Divn'))
That's a worthless aside, but somebody is bound to copy it without the
disclaimer.
> In comp.lang.javascript message <gvvtr2$4nd$1...@news.eternal-
> september.org>, Sun, 31 May 2009 23:52:07, Garrett Smith
> <dhtmlk...@gmail.com> posted:
>>
>> if (document.getElementById &&
>> document.getElementById('el') &&
>> document.getElementById('el').style ) {
>> // We know that this browser supports getElementById and has
>> // a style object, so we can set a style property.
>> document.getElementById('el').style.color = "red";
>> }
>
> Although understandable, that looks inefficient.
Being understandable is more important than being efficient 90% of the
time (or more). That said, repeated subexpressions like in the above make
give me twitches.
> The following, after
> checking, can be presented for actual use.
>
> if (document.getElementById &&
> (T=document.getElementById('Divn')) && (T=T.style) ) {
> // ...
> // ...
> T.color = "red";
> }
Remember to declare T as a variable, i.e., preceed the above by
"var T".
Personally I would prefer to check for document.getElementById only
once, but if this code is executed only once, that wouldn't be
relevant.
And assignments (any side effect, really) inside conditional expressions
is not very readable. It should be avoided where possible.
For one-shot code I would write it as:
if (document.getElemenetById) { // or use typeof for extra safety
var elem = document.getElementById('el');
if (elem && elem.style) { // why test for style if getElementById
// exists. I don't believe there is any
// browser that has getElementById and
// not element.style.
elem.style.color = "red";
}
}
/L
--
Lasse Reichstein Holst Nielsen
'Javascript frameworks is a disruptive technology'
[mental image of LRN twitching...]
Oh no, lets chagne that right away!
Kidding, of course :-)
[...]
>
> For one-shot code I would write it as:
>
> if (document.getElemenetById) { // or use typeof for extra safety
> var elem = document.getElementById('el');
> if (elem && elem.style) { // why test for style if getElementById
> // exists. I don't believe there is any
> // browser that has getElementById and
> // not element.style.
> elem.style.color = "red";
> }
> }
>
Cumbersome to have that inline, though. I would not want to have that
much code every time I wanted to set a style.
Regarding the code comment, I don't know. Browsers that have a
scriptable document but do not have document.getElementById?
Is there a browser that does not have a userAgent string?
A draft with a totally different example below. I threw in "host
object", which is not in the glossary (glossary does not exist).
Anyone want to write a glossary? Start out with a list terms. They'll
get defined by members here. That can be added to the FAQ, or can be an
"appendix".
======================================================================
8.6 _How do I detect Opera/Netscape/IE_?
Short answer: Don't do that.
The navigator host object contains properties that may identify
the browser and version. These properties are historically inaccurate.
Some browsers allow the user to set navigator.userAgent to any value.
For example, Firefox, (type about:config and search useragent
or Safari, Develop > User Agent > Other..., IE, via Registry.
Other browsers, such as Opera, provide a list of user agents
for the user to select from. There are also at least 25 other
javascript capable browsers, with multiple versions, each
with their own string.
Browser detection is unreliable, at best. It usually causes
forwards-compatibility and maintenance problems. It is unrelated
to the problem or incompatiblity it is trying to solve, and tends
obscures the thinking behind the code.
Object detection is checking that the object in question exists.
Capability detection goes one step further to actually test the
objects, methods, or properties, to see if it behaves in the
desired manner.
/**
* Returns the element/object the user targeted.
* If neither DOM nor IE event model is supported, returns undefined.
* @throws TypeError if the event is not an object.
*/
function getEventTarget(e) {
e = e || window.event;
// First check for the existence of standard "target" property.
if("target" in e) {
return e.target;
}
return e.srcElement;
}
See also:
<URL: http://jibbering.com/faq/faq_notes/not_browser_detect.html >
<URL: http://dev.opera.com/articles/view/using-capability-detection/ >
<URL: http://developer.apple.com/internet/webcontent/objectdetection.html >
<URL: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43 >
======================================================================
Garrett
--
The official comp.lang.javascript FAQ:
http://jibbering.com/faq/
And lose one `e' :)
>> var elem = document.getElementById('el');
>> if (elem && elem.style) { // why test for style if getElementById
>> // exists. I don't believe there is any
>> // browser that has getElementById and
>> // not element.style.
>> elem.style.color = "red";
>> }
>> }
>>
>
> Cumbersome to have that inline, though. I would not want to have that
> much code every time I wanted to set a style.
See dhtml.setStyleProperty(). That's one call in source code (of course, it
spawns a few more). The efficient software developer writes (or at least
attempts to write) efficient wrappers for everyday tasks.
> Regarding the code comment, I don't know. Browsers that have a
> scriptable document but do not have document.getElementById?
Entirely possible, see IE < 5.
> Is there a browser that does not have a userAgent string?
Depends on what you are asking. There is probably no *browser* that does
not have navigator.userAgent, as object and property originate from
JavaScript 1.0, Netscape 2.0. However, a) there are UAs that are not
browsers which support ECMAScript scripting, and b) the property value is
implementation-dependent, of course.
Why are you asking?
> Anyone want to write a glossary?
A glossary of what?
> /**
> * Returns the element/object the user targeted.
> * If neither DOM nor IE event model is supported, returns undefined.
> * @throws TypeError if the event is not an object.
> */
> function getEventTarget(e) {
> e = e || window.event;
> // First check for the existence of standard "target" property.
> if("target" in e) {
It is quite pointless to use a feature that is not supported in previous
versions of a programming language or API to determine if features
introduced in previous versions of a programming language or API are
supported. Besides, the `in' operation should not be used with host objects
in particular.
> return e.target;
> }
> return e.srcElement;
What for? var t = e.target || e.srcElement; Couldn't be simpler.
PointedEars
Obviously.
>
> > Is there a browser that does not have a userAgent string?
>
> Depends on what you are asking. There is probably no *browser* that does
> not have navigator.userAgent, as object and property originate from
> JavaScript 1.0, Netscape 2.0. However, a) there are UAs that are not
> browsers which support ECMAScript scripting, and b) the property value is
> implementation-dependent, of course.
>
> Why are you asking?
>
> > Anyone want to write a glossary?
>
> A glossary of what?
>
> > /**
> > * Returns the element/object the user targeted.
> > * If neither DOM nor IE event model is supported, returns undefined.
> > * @throws TypeError if the event is not an object.
> > */
> > function getEventTarget(e) {
> > e = e || window.event;
> > // First check for the existence of standard "target" property.
> > if("target" in e) {
>
> It is quite pointless to use a feature that is not supported in previous
> versions of a programming language or API to determine if features
> introduced in previous versions of a programming language or API are
> supported. Besides, the `in' operation should not be used with host objects
> in particular.
Exactly. I'm a bit tired of this revisionist approach to feature
testing. We've settled these issues and nothing like this is going in
the FAQ if I have anything to say about it (and you know I will.)
>
> > return e.target;
> > }
> > return e.srcElement;
>
> What for? var t = e.target || e.srcElement; Couldn't be simpler.
Exactly.
...of terms which are frequently used in this group but may be new to
beginners. "Host object", "DontEnum", "[[term-from-the-specs]]", and
abbreviations like UA come to mind, for example.
>> Besides, the `in' operation should not be
>> used with host objects in particular.
>
> Exactly. I'm a bit tired of this revisionist approach to feature
> testing. We've settled these issues [..]
Hm. The in operator doesn't give a lot of information in this context
(ok, so "foo" is in document, but is it what we were looking for?), but
apart from that it should be relatively safe - ie, should not cause a
crash. There was one specific exception to this, but I can't remember
what exactly. Some problem in Safari, I think.
>>> return e.target;
>>> }
>>> return e.srcElement;
>>
>> What for? var t = e.target || e.srcElement; Couldn't be simpler.
>
> Exactly.
Except that this won't always evaluate to an element. IIRC, there was an
issue with Safari where it would let events fire on text nodes. In that
case you'd have to check the nodeType of 't' and use its parentNode if
necessary.
- Conrad
[...]
>>> return e.target;
>>> }
>>> return e.srcElement;
>> What for? var t = e.target || e.srcElement; Couldn't be simpler.
>
> Exactly.
Agreed.
Correct. It tells you virtually nothing.
> (ok, so "foo" is in document, but is it what we were looking for?), but
> apart from that it should be relatively safe - ie, should not cause a
No, it is perfectly ridiculous to use the - in - operator for feature
detection as there are agents that do not support it. Think about
what feature detection is used for.
> crash. There was one specific exception to this, but I can't remember
> what exactly. Some problem in Safari, I think.
Not that I know of. Of course, I virtually never use the - in -
operator.
>
> >>> return e.target;
> >>> }
> >>> return e.srcElement;
>
> >> What for? var t = e.target || e.srcElement; Couldn't be simpler.
>
> > Exactly.
>
> Except that this won't always evaluate to an element.
That's allowable and must be dealt with accordingly after the target
has been determined.
> IIRC, there was an
> issue with Safari where it would let events fire on text nodes. In that
> case you'd have to check the nodeType of 't' and use its parentNode if
> necessary.
It is neither an issue, nor Safari-specific. This is one of the first
things I fixed (by proxy) in jQuery way back when. And what is a
nodeType of 't' supposed to be?
[...]
>> Is there a browser that does not have a userAgent string?
>
> Depends on what you are asking. There is probably no *browser* that does
> not have navigator.userAgent, as object and property originate from
> JavaScript 1.0, Netscape 2.0. However, a) there are UAs that are not
> browsers which support ECMAScript scripting, and b) the property value is
> implementation-dependent, of course.
>
> Why are you asking?
>
It would be a novel find.
>> Anyone want to write a glossary?
>
> A glossary of what?
>
The glossary would contain terms that get used and sometimes need
clarification or reiteration.
Terms like:
"Host Object"
"Script Engine"
"Layout Engine"
"Quirks Mode"
"Primitive value"
"Object inference"
"Scope"
Ideally they would have short definitions, too.
>> return e.target;
>> }
>> return e.srcElement;
>
> What for? var t = e.target || e.srcElement; Couldn't be simpler.
>
It could lose the identifier |t|.
return e.target || e.srcElement;
As always, it depends on the requirements. If it's important that any
and all UAs are able to execute the scripts without syntax errors, then
'in' is not an option (and neither are try..catch).
>> crash. There was one specific exception to this, but I can't remember
>> what exactly. Some problem in Safari, I think.
>
> Not that I know of. Of course, I virtually never use the - in -
> operator.
Ah, I got that mixed up: I found the thread again, and the crash only
happened with 'typeof', but could be avoided with 'in'. Possibly just an
interesting anomaly, but it demonstrates that not even 'typeof' is
always safe.
http://preview.tinyurl.com/p7aocu (starting with message #126)
>> >> What for? var t = e.target || e.srcElement; Couldn't be simpler.
>>
>> > Exactly.
>>
>> Except that this won't always evaluate to an element.
>
> That's allowable and must be dealt with accordingly after the target
> has been determined.
>
>> IIRC, there was an
>> issue with Safari where it would let events fire on text nodes. In that
>> case you'd have to check the nodeType of 't' and use its parentNode if
>> necessary.
>
> It is neither an issue, nor Safari-specific. This is one of the first
> things I fixed (by proxy) in jQuery way back when. And what is a
> nodeType of 't' supposed to be?
Usually element (1), or text (3) if the browser decides it wants to fire
events on text nodes, too. What else?
- Conrad
Any of Safari 2.x., to be precise.
I posted a testcase which exhibits the crash
<http://groups.google.com/group/comp.lang.javascript/msg/7a7ddde62e65b80b>
and I think Garrett confirmed that bug on his machine.
Nevertheless, as David pointed out, you wouldn't really fiddle with `in`
or `typeof`. Those should really be abstracted in
`isHostMethod`/`areHostMethods` (used to determine client capabilities
*before* initializing certain app behavior) instead of cluttering the code.
--
kangax
Or 9 if document.
Or undefined if the object is not a Node, such as window.
I did. Here:
http://groups.google.com/group/comp.lang.javascript/msg/1e34a215461e10da
and here:
http://groups.google.com/group/comp.lang.javascript/msg/7127bbeac65dd8c2
> Nevertheless, as David pointed out, you wouldn't really fiddle with `in`
> or `typeof`. Those should really be abstracted in
> `isHostMethod`/`areHostMethods` (used to determine client capabilities
> *before* initializing certain app behavior) instead of cluttering the code.
>
An extra method call.
As for "clutter":-
isHostMethod(obj, prop)
vs.
(prop in obj)
The former is more and would be slower. isHostMethod is a bad name. It
would seem to indicate that the property is host method. That is not
what it does.
isPossibleHostMethod()
would be a more accurate name. Still though, AISB, isHostMethod doesn't
really tell you much about the value of an arbitrary host object.
--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Proper <= 4-line sig. separator as above, a line exactly "-- " (SonOfRFC1036)
Do not Mail News to me. Before a reply, quote with ">" or "> " (SonOfRFC1036)
[...]
>>>>> return e.target;
>>>>> }
>>>>> return e.srcElement;
>>>> What for? var t = e.target || e.srcElement; Couldn't be simpler.
>>> Exactly.
>> Except that this won't always evaluate to an element.
>
> That's allowable and must be dealt with accordingly after the target
> has been determined.
>
The beauty of it is that you don't even have to deal with it in most cases.
Most times, you just want to know if the target matches certain
criteria, like:-
hasClass(target, "scroll-actuator").
A text node or the document should not have a className property. Even
if it did, the return value of that |hasClass| call above would still be
false (unless the odd program intentionally set a className property on
that object, but that would be a fault of the program).
>> IIRC, there was an
>> issue with Safari where it would let events fire on text nodes. In that
>> case you'd have to check the nodeType of 't' and use its parentNode if
>> necessary.
>
> It is neither an issue, nor Safari-specific. This is one of the first
> things I fixed (by proxy) in jQuery way back when. And what is a
> nodeType of 't' supposed to be?
Which recent browsers still include text nodes? Gecko did that for a
long while but stopped at some point.
I find extra method call to be irrelevant if it happens during load
time; 99% of the time it is runtime performance that matters. That is
unless we are talking about testing host objects at runtime of course.
>
> As for "clutter":-
>
> isHostMethod(obj, prop)
> vs.
> (prop in obj)
I was recently rereading that huge thread where you had a conversation
with D. Mark (and PointedEars) about `in` vs `typeof` for testing host
objects. It seemed like there were quite few examples of `in` catching
oddball properties - "filter", `document.all` and others. Properties
that `typeof` *rightfully ignored*. Another solid argument in favor of
`typeof` was that there was no (or little) practical evidence of it
being safe, comparing to `typeof`; `typeof` was used for 10 years
without any problems, contrary to `in` which no one has really tested
"well enough".
It is then that I found `typeof` glitch in Safari 2.x as the only one
example (so far) of its failure.
There were also compatibility concerns - such as `in` being not
implemented in IE <5 - but I find them somewhat moot these days.
>
> The former is more and would be slower. isHostMethod is a bad name. It
> would seem to indicate that the property is host method. That is not
> what it does.
That would depend on your definition of "host method". Is it something
that returns "object", "function" or "unknown" for `typeof`? Is it
something that is callable? How do we then determine its callability? Is
host method something that's callable and doesn't throw error when
called? Is it something that has "[native method]" in its string
representation (j/k, of course)? And what if method is callable, doesn't
throw error but does nothing (e.g. NOOP)? And what if it returns typeof
"undefined" but `in` detects it as being present? Can we consider it a
host method in that case?
>
> isPossibleHostMethod()
>
> would be a more accurate name. Still though, AISB, isHostMethod doesn't
> really tell you much about the value of an arbitrary host object.
I know.
I had similar concerns some time ago
<http://groups.google.com/group/comp.lang.javascript/msg/aef3e9b0765fb047>
Eventually, you still have to stop somewhere. Draw an inference and
assume something to be true (or at least very close to true). How else
otherwise? : )
--
kangax
Doesn't matter for these. And what happens when some new version of
IE comes out and starts throwing exceptions on using the - in -
operator with - for example - element nodes (similar things have
happened before.) You've got to go back and change every one of
them. So I don't see a wrapper-less solution as workable.
>
> As for "clutter":-
>
> isHostMethod(obj, prop)
> vs.
> (prop in obj)
I think he's alluding to the fact that these are called once in a
gateway (usually during or on load), not sprinkled throughout the
code. You can also use areHostMethods. Much easier on the eyes. No
compatibility issues at all. I can't see a better solution. I've
been sold ever since 2001 (approx.) when it fixed the most mysterious
Mac IE bug I'd ever seen. Sure enough, it was an "unknown" type.
Then I heard a few years back that nobody could detect the bookmark
methods in IE. Once again, an "unknown" type. Gecko's document.all
is an "undefined" type, despite its availability (clearly a cue from
the Gecko developers to stay away from it.) If you listen, the
browser developers are giving hints and the - typeof - operator is
what reveals them to your script.
>
> The former is more and would be slower. isHostMethod is a bad name. It
> would seem to indicate that the property is host method. That is not
> what it does.
>
> isPossibleHostMethod()
Rubbish. It's the perfect name. It should always be documented to
remind the author to pass names of known methods, not any random
property name. If it passes - for example - gEBI, you can be quite
sure it is a host method. Other scripts overwriting (or adding) gEBI
don't count (throw those away.)
>
> would be a more accurate name. Still though, AISB, isHostMethod doesn't
> really tell you much about the value of an arbitrary host object.
Certainly it does. Over a decade of history confirms it and that is
all you have to go on in this case. It is the - in - operator that
tells you nothing. You are focusing on semantics, not reality and
your interpretation is wrong anyway. You are not supposed to pass an
*arbitrary* anything. The rules for these methods (there are three or
four) have been very clearly defined and each serves a very specific
purpose.
Sounds like FUD.
A wrapperless solution involves using |in| where |in| works and typeof
where it doesn't.
A wrapper could do that, too, or could use combinations of the two
operators (using |in| as a guard clause to prevent the Safari 2 crash
kangax mentioned).
>> As for "clutter":-
>>
>> isHostMethod(obj, prop)
>> vs.
>> (prop in obj)
>
> I think he's alluding to the fact that these are called once in a
> gateway (usually during or on load), not sprinkled throughout the
> code. You can also use areHostMethods. Much easier on the eyes. No
> compatibility issues at all. I can't see a better solution. I've
> been sold ever since 2001 (approx.) when it fixed the most mysterious
> Mac IE bug I'd ever seen. Sure enough, it was an "unknown" type.
I'm can't prove it was not, but I bet you are wrong on that.
> Then I heard a few years back that nobody could detect the bookmark
> methods in IE. Once again, an "unknown" type. Gecko's document.all
> is an "undefined" type, despite its availability (clearly a cue from
> the Gecko developers to stay away from it.) If you listen, the
> browser developers are giving hints and the - typeof - operator is
> what reveals them to your script.
The reason |typeof document.all| is "undefined" is not because Gecko's
developers are saying to stay away from it. The reason is so that
existing scripts that check document.all can continue to function the same.
Do you really need |typeof| to tell you not to use document.all?
>
>> The former is more and would be slower. isHostMethod is a bad name. It
>> would seem to indicate that the property is host method. That is not
>> what it does.
>>
>> isPossibleHostMethod()
>
> Rubbish.
Huh.
It's the perfect name. It should always be documented to
> remind the author to pass names of known methods, not any random
> property name. If it passes - for example - gEBI, you can be quite
> sure it is a host method. Other scripts overwriting (or adding) gEBI
> don't count (throw those away.)
>
isHostMethod(document, "getElementById");
>> would be a more accurate name. Still though, AISB, isHostMethod doesn't
>> really tell you much about the value of an arbitrary host object.
>
> Certainly it does. Over a decade of history confirms it and that is
> all you have to go on in this case. It is the - in - operator that
> tells you nothing. You are focusing on semantics, not reality and
> your interpretation is wrong anyway. You are not supposed to pass an
> *arbitrary* anything. The rules for these methods (there are three or
> four) have been very clearly defined and each serves a very specific
> purpose.
What you've stated in the above paragraph (the one I am directly
replying to) is that isHostMethod requires the developer to have a
presupposition about what the presence of an object property means about it.
So, IIUC, isHostMethod detects the presence of a property, and that it
is not a primitive value (it even has to call [[Get]] to do that). Did I
get that right?
Does isHostMethod tell you if the object is a host object? Nope. It does
not tell you if the property is a callable object (method), either.
I will wait another day before I upload the FAQ, to allow for more
feedback. One thing at a time. The "format a date" question needs
attention now, so that is waiting for this.
These don't have exactly the same meaning, of course.
I don't know that the condition actually exists in reality, but if
e.target is ever null, your alternative will return undefined instead
of null.
Matt Kruse
Yes, they have. In addition, the W3C DOM has e.relatedTarget, and the
MSHTML DOM has e.fromElement and e.toElement.
> I don't know that the condition actually exists in reality, but if
> e.target is ever null,
It can't be.
> your alternative will return undefined instead of null.
Correct, but irrelevant because
if (t)
covers both.
PointedEars
Are you kidding? It was an "unknown" type. That's a fact. And it
behaved just as the "unknown" types do in Windows (blows up on type
conversion, among other things.)
>
> > Then I heard a few years back that nobody could detect the bookmark
> > methods in IE. Once again, an "unknown" type. Gecko's document.all
> > is an "undefined" type, despite its availability (clearly a cue from
> > the Gecko developers to stay away from it.) If you listen, the
> > browser developers are giving hints and the - typeof - operator is
> > what reveals them to your script.
>
> The reason |typeof document.all| is "undefined" is not because Gecko's
> developers are saying to stay away from it. The reason is so that
> existing scripts that check document.all can continue to function the same.
That is exactly what I said. I didn't say a thing about Gecko's
developers trying to stay away from it.
>
> Do you really need |typeof| to tell you not to use document.all?
I don't know what that means.
>
>
>
> >> The former is more and would be slower. isHostMethod is a bad name. It
> >> would seem to indicate that the property is host method. That is not
> >> what it does.
>
> >> isPossibleHostMethod()
>
> > Rubbish.
>
> Huh.
As in refuse.
>
> It's the perfect name. It should always be documented to
>
> > remind the author to pass names of known methods, not any random
> > property name. If it passes - for example - gEBI, you can be quite
> > sure it is a host method. Other scripts overwriting (or adding) gEBI
> > don't count (throw those away.)
>
> isHostMethod(document, "getElementById");
And?
>
> >> would be a more accurate name. Still though, AISB, isHostMethod doesn't
> >> really tell you much about the value of an arbitrary host object.
>
> > Certainly it does. Over a decade of history confirms it and that is
> > all you have to go on in this case. It is the - in - operator that
> > tells you nothing. You are focusing on semantics, not reality and
> > your interpretation is wrong anyway. You are not supposed to pass an
> > *arbitrary* anything. The rules for these methods (there are three or
> > four) have been very clearly defined and each serves a very specific
> > purpose.
>
> What you've stated in the above paragraph (the one I am directly
> replying to) is that isHostMethod requires the developer to have a
> presupposition about what the presence of an object property means about it.
YES. We've discussed this to death. The first argument is a host
object. Not an Object object or a string or whatever. The second is
the name of a method. Not a name of any other type of property. I
think it is quite clear. The name kind of says it all.
>
> So, IIUC, isHostMethod detects the presence of a property, and that it
> is not a primitive value (it even has to call [[Get]] to do that). Did I
> get that right?
Not even in the ballpark. And I don't think you are really trying.
>
> Does isHostMethod tell you if the object is a host object? Nope.
That is not what it does. In fact, such a method would be completely
idiotic (see jQuery.) And see above.
> It does
> not tell you if the property is a callable object (method), either.
Oh, but it does. Perhaps not in the way you would like, but it is the
only way in reality.
>
> I will wait another day before I upload the FAQ, to allow for more
> feedback. One thing at a time. The "format a date" question needs
> attention now, so that is waiting for this.
I don't care what you do with that thing.
[...]
>>> compatibility issues at all. I can't see a better solution. I've
>>> been sold ever since 2001 (approx.) when it fixed the most mysterious
>>> Mac IE bug I'd ever seen. Sure enough, it was an "unknown" type.
>> I'm can't prove it was not, but I bet you are wrong on that.
>
> Are you kidding?
Not kidding.
It was an "unknown" type. That's a fact. And it
> behaved just as the "unknown" types do in Windows (blows up on type
> conversion, among other things.)
>
So you had an object where:-
typeof obj == "unknown"
was true in Mac IE. I have not seen that and I'm calling you on that. I
think you are mistaken. Please post an example.
>>> Then I heard a few years back that nobody could detect the bookmark
>>> methods in IE. Once again, an "unknown" type. Gecko's document.all
>>> is an "undefined" type, despite its availability (clearly a cue from
>>> the Gecko developers to stay away from it.) If you listen, the
>>> browser developers are giving hints and the - typeof - operator is
>>> what reveals them to your script.
>> The reason |typeof document.all| is "undefined" is not because Gecko's
>> developers are saying to stay away from it. The reason is so that
>> existing scripts that check document.all can continue to function the same.
>
> That is exactly what I said. I didn't say a thing about Gecko's
> developers trying to stay away from it.
>
>> Do you really need |typeof| to tell you not to use document.all?
>
> I don't know what that means.
>
Ah, you said:
| Gecko's document.all is an "undefined" type, despite its availability
| (clearly a cue from the Gecko developers to stay away from it.)
My reply is in response to that. Gecko developers were not cuing. They
were trying to make IE-only sites work.
>>
>>
>>>> The former is more and would be slower. isHostMethod is a bad name. It
>>>> would seem to indicate that the property is host method. That is not
>>>> what it does.
>>>> isPossibleHostMethod()
>>> Rubbish.
>> Huh.
>
> As in refuse.
>
Are you British?
>> It's the perfect name. It should always be documented to
>>
>>> remind the author to pass names of known methods, not any random
>>> property name. If it passes - for example - gEBI, you can be quite
>>> sure it is a host method. Other scripts overwriting (or adding) gEBI
>>> don't count (throw those away.)
>> isHostMethod(document, "getElementById");
>
> And?
>
I wanted to ask: Is what I wrote what you meant? Did you mean: If
isHostMethod(document, "getElementById"); returns true, then you can be
sure that isHostMethod is a host method.
?
That is a true statement and I think that is what you meant but it is
not what you wrote. You wrote:
| If it passes - for example - gEBI, you can be quite sure it is a host
| method.
- not true, if taken literally. Does not make much sense to me.
>>>> would be a more accurate name. Still though, AISB, isHostMethod doesn't
>>>> really tell you much about the value of an arbitrary host object.
>>> Certainly it does. Over a decade of history confirms it and that is
>>> all you have to go on in this case. It is the - in - operator that
>>> tells you nothing. You are focusing on semantics, not reality and
>>> your interpretation is wrong anyway. You are not supposed to pass an
>>> *arbitrary* anything. The rules for these methods (there are three or
>>> four) have been very clearly defined and each serves a very specific
>>> purpose.
>> What you've stated in the above paragraph (the one I am directly
>> replying to) is that isHostMethod requires the developer to have a
>> presupposition about what the presence of an object property means about it.
>
> YES.
That is what isHostMethod does. It does nothing more.
That is *also* the approach for using the |in| operator.
Both are valid approaches. Neither is infallible.
We've discussed this to death.
No argument there.
The first argument is a host
> object. Not an Object object or a string or whatever. The second is
> the name of a method. Not a name of any other type of property. I
> think it is quite clear. The name kind of says it all.
>
The method requires the developer to know that the second argument is
the name of a method.
Do you see a parallel to the approach using |in| ?
The benefit to |in| is that is inline and does not require stepping into
another line of code in another file.
>> So, IIUC, isHostMethod detects the presence of a property, and that it
>> is not a primitive value (it even has to call [[Get]] to do that). Did I
>> get that right?
>
> Not even in the ballpark. And I don't think you are really trying.
>
How did you come to that, or why do you say that? Can you respond more
specifically to what I wrote?
>> Does isHostMethod tell you if the object is a host object? Nope.
>
> That is not what it does. In fact, such a method would be completely
> idiotic (see jQuery.) And see above.
>
It would be well-intentioned, but could not work.
>> It does
>> not tell you if the property is a callable object (method), either.
>
> Oh, but it does. Perhaps not in the way you would like, but it is the
> only way in reality.
>
isHostMethod(document, "images");
returns true in all browsers.
But document.images is *not* callable in all browsers.
>> I will wait another day before I upload the FAQ, to allow for more
>> feedback. One thing at a time. The "format a date" question needs
>> attention now, so that is waiting for this.
>
> I don't care what you do with that thing.
I am disappointed to hear that. Yesterday you seemed interested with
what should and should not go into the FAQ.
| We've settled these issues and nothing like this is going in
| the FAQ if I have anything to say about it (and you know I will.)
You said your bit, the proposed change that you agreed to was agreed on
by me, making three of us.
The FAQ is a document for learning and reference.
The FAQ is an accurate collection of knowledge that is critically
reviewed. It is corrected and republished at 0 marginal cost with little
environmental impact. It is a more accurate reference than the books and
videos and other sources of inaccuracies.
The rampant misconception that javascript development requires using a
preconceived library like Dojo can be recognized for what it is by more
people learning.
The FAQ has to get better.
Theoretically, the result would be whatever e.srcElement is and that
might not necessarily be undefined. Opera has both.
[...]
>>>> compatibility issues at all. I can't see a better solution. I've
>>>> been sold ever since 2001 (approx.) when it fixed the most mysterious
>>>> Mac IE bug I'd ever seen. Sure enough, it was an "unknown" type.
>>> I'm can't prove it was not, but I bet you are wrong on that.
>>
>> Are you kidding?
>
> Not kidding.
>
> It was an "unknown" type. That's a fact. And it
>> behaved just as the "unknown" types do in Windows (blows up on type
>> conversion, among other things.)
>>
>
> So you had an object where:-
>
> typeof obj == "unknown"
>
> was true in Mac IE. I have not seen that and I'm calling you on that. I
> think you are mistaken. Please post an example.
>
You've been called out on that and no reply.
No "unknown" type in Mac IE.
[...]
>
> Ah, you said:
>
> | Gecko's document.all is an "undefined" type, despite its availability
> | (clearly a cue from the Gecko developers to stay away from it.)
>
> My reply is in response to that. Gecko developers were not cuing. They
> were trying to make IE-only sites work.
>
And again, wrong on that one.
[...]
> The FAQ has to get better.
>
Updated:
Version 16, Updated June 04, 2009 by Garrett Smith
http://jibbering.com/faq/#detectBrowser
Also added a rule to faq.css so that the hover effect does not affect
named anchor in h3 and the h3 has a little more margin-top (1.5em), as
requested. It seems less squished and provides a little space between an
answer and the following question.
Garrett -> To gym.
> Garrett Smith wrote:
>>>> David Mark wrote:
>>>>> […] the most mysterious
>>>>> Mac IE bug I'd ever seen. Sure enough, it was an "unknown" type.
> You've been called out on that and no reply.
I remember reading stuff like that in Heavy Metal magazines
when I was 14 :-)
> No "unknown" type in Mac IE.
typeof window.location.replace
IE:mac 5.1 -> 'unknown'
IE:mac 5.2 -> 'unknown'
Pfft. I'm a little busy. Replies to your posts are on the back
burner these days.
>
> No "unknown" type in Mac IE.
You don't have a clue.
>
> [...]
>
>
>
> > Ah, you said:
>
> > | Gecko's document.all is an "undefined" type, despite its availability
> > | (clearly a cue from the Gecko developers to stay away from it.)
>
> > My reply is in response to that. Gecko developers were not cuing. They
> > were trying to make IE-only sites work.
Do you understand what a cue is?
>
> And again, wrong on that one.
How can one guy keep saying I'm wrong on the same points over and over
and be wrong about it every time. Told about it every time, etc.
It's getting old. It is you that goes MIA every time you can't
answer. Keep your shit real, my brother. :)
[snip]
[...]
> typeof window.location.replace
> IE:mac 5.1 -> 'unknown'
> IE:mac 5.2 -> 'unknown'
>
Thanks, Eric.
I am so fucking tired of hearing what you haven't seen. Have you seen
it now? Good!
>
>
>
> >>> Then I heard a few years back that nobody could detect the bookmark
> >>> methods in IE. Once again, an "unknown" type. Gecko's document.all
> >>> is an "undefined" type, despite its availability (clearly a cue from
> >>> the Gecko developers to stay away from it.) If you listen, the
> >>> browser developers are giving hints and the - typeof - operator is
> >>> what reveals them to your script.
> >> The reason |typeof document.all| is "undefined" is not because Gecko's
> >> developers are saying to stay away from it. The reason is so that
> >> existing scripts that check document.all can continue to function the same.
>
> > That is exactly what I said. I didn't say a thing about Gecko's
> > developers trying to stay away from it.
>
> >> Do you really need |typeof| to tell you not to use document.all?
>
> > I don't know what that means.
>
> Ah, you said:
>
> | Gecko's document.all is an "undefined" type, despite its availability
> | (clearly a cue from the Gecko developers to stay away from it.)
>
> My reply is in response to that. Gecko developers were not cuing. They
> were trying to make IE-only sites work.
And do you understand that is a cue? Also, your interpretation of
their motivations is irrelevant. The fact is, the typeof operator
wins again.
>
>
>
> >>>> The former is more and would be slower. isHostMethod is a bad name. It
> >>>> would seem to indicate that the property is host method. That is not
> >>>> what it does.
> >>>> isPossibleHostMethod()
> >>> Rubbish.
> >> Huh.
>
> > As in refuse.
>
> Are you British?
No. What if I was?
>
> >> It's the perfect name. It should always be documented to
>
> >>> remind the author to pass names of known methods, not any random
> >>> property name. If it passes - for example - gEBI, you can be quite
> >>> sure it is a host method. Other scripts overwriting (or adding) gEBI
> >>> don't count (throw those away.)
> >> isHostMethod(document, "getElementById");
>
> > And?
>
> I wanted to ask: Is what I wrote what you meant? Did you mean: If
> isHostMethod(document, "getElementById"); returns true, then you can be
> sure that isHostMethod is a host method.
>
> ?
I'll echo that. I know isHostMethod is not a host method.
>
> That is a true statement and I think that is what you meant but it is
> not what you wrote. You wrote:
>
> | If it passes - for example - gEBI, you can be quite sure it is a host
> | method.
>
> - not true, if taken literally. Does not make much sense to me.
We've had this discussion a hundred times now. You pass a *method*
name (e.g. gEBI), not any arbitrary string (e.g. offsetParent.) Go
back and read.
>
> >>>> would be a more accurate name. Still though, AISB, isHostMethod doesn't
> >>>> really tell you much about the value of an arbitrary host object.
> >>> Certainly it does. Over a decade of history confirms it and that is
> >>> all you have to go on in this case. It is the - in - operator that
> >>> tells you nothing. You are focusing on semantics, not reality and
> >>> your interpretation is wrong anyway. You are not supposed to pass an
> >>> *arbitrary* anything. The rules for these methods (there are three or
> >>> four) have been very clearly defined and each serves a very specific
> >>> purpose.
> >> What you've stated in the above paragraph (the one I am directly
> >> replying to) is that isHostMethod requires the developer to have a
> >> presupposition about what the presence of an object property means about it.
>
> > YES.
>
> That is what isHostMethod does. It does nothing more.
Who are you talking to?
>
> That is *also* the approach for using the |in| operator.
Not at all. The - in - operator tells you nothing and may be unsafe.
>
> Both are valid approaches. Neither is infallible.
>
> We've discussed this to death.
>
> No argument there.
Then, for the love of God, drop it.
You are such a fucking loser. See isHostObjectProperty. RTFM. STFW
and if you still can't figure it out, FOAD. Does that sum it up? I'm
tired of you wasting time and confusing issues.
[snip]
You could have just taken my word for it. Of course, I wasn't even
talking about Mac IE 5, but a much older variety that you've likely
never seen. How many times are you going to put your foot in your
mouth like this? We aren't looking to fill the position vacated by
Matt Kruse.
Next time take a deep breath, do some research and *then* fly off the
handle (assuming you still think you are right.)
[...]
>>>> What you've stated in the above paragraph (the one I am directly
>>>> replying to) is that isHostMethod requires the developer to have a
>>>> presupposition about what the presence of an object property means about it.
>>> YES.
>> That is what isHostMethod does. It does nothing more.
>
> Who are you talking to?
>
>> That is *also* the approach for using the |in| operator.
>
> Not at all. The - in - operator tells you nothing and may be unsafe.
>
>> Both are valid approaches. Neither is infallible.
>>
>> We've discussed this to death.
>>
>> No argument there.
>
> Then, for the love of God, drop it.
>
The problem is that you seem to be advocating isHostMethod as having
superior method-checking skills. Method isHostMethod does not
deductively check to see if a property is a method. It requires
presupposition, *just like in does*.
Method isHostMethod has a drawback. It is an extra method call. It is
marginally slower than a function call and takes up more space. The in
operator is the simpler choice and is a valid choice in many circumstances.
>>
>> Do you see a parallel to the approach using |in| ?
>>
Not surprised you ignored that one.
>> The benefit to |in| is that is inline and does not require stepping into
>> another line of code in another file.
>>
Yep, still a benefit.
>> isHostMethod(document, "images");
>>
>> returns true in all browsers.
>>
>> But document.images is *not* callable in all browsers.
>
> You are such a fucking loser. See isHostObjectProperty. RTFM. STFW
> and if you still can't figure it out, FOAD. Does that sum it up? I'm
> tired of you wasting time and confusing issues.
It does not sum it up. It shows us what an asshole you are, but you do
that all the time. Real professional.
It also shows that you missed the point of that example. In case it
wasn't clear to others: The point of document.images being reported as a
Host Method by isHostMethod shows that that method returns true for a
property that is not a method in Firefox, but is a method in other
browsers. Yes, document.images *is* callable in several browsers
including IE, Opera, Safari. This is nonstandard, but legal, and is a fact:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>callable images</title>
</head>
<body>
<img src="">
<script type="text/javascript">
function isHostMethod(object, property) {
var t = typeof object[property];
return t=='function' ||
(!!(t=='object' && object[property])) ||
t=='unknown';
}
document.write("isHostMethod(document, 'images'): ");
document.write(isHostMethod(document, "images"));
document.write("<br>typeof document.images(0): ");
try {
document.write(typeof document.images(0));
} catch(ex) {
document.write("<b>not callable<\/b>");
}
</script>
</body>
</html>
Opera, Safari, IE:
isHostMethod(document, 'images'): true
typeof document.images(0): object
Firefox:
isHostMethod(document, 'images'): true
typeof document.images(0): not callable
Nobody should try calling document.images. It is a non-standard API
decision by microsoft that has resulted in confusion and compatibility
among developers and other vendors.
In short, the method isHostMethod does not do what the method name
implies; does not return true iff 1) the base object is a host object
and 2) the property is callable). That was the point of the
document.images example
Such long explanations are time consuming.
A better summary would be:-
The typeof operator is widely implemented. When used on host objects the
result is implementation-dependent. For callable host objects, the
resutl is usually "object", "function", or "unknown", depending on the
implementation. The wrapper |isHostMethod| checks to see if the return
value is one of those.
The |in| operator detects presence of a property in an object. It mostly
works on host objects by returning true of the object contains the
property.
Both appraoches, |in| or |typeof| require the developer to make a
presupposition of an property being callable-if-present.
Neither approach will determine if the object is callable.
The |in| operator is a more recent addition to the language and is not
implemented in Mac IE, which also has "unknown" type.
The typeof operator has varied results, depending on the implementation
and the property. This is makes a typeof strategy more complicated, so
if this approach is used, it is generally better to wrap it in a
function that clearly describes the intent of the code. The name
isHostMethod fails on that count.
FOAD, huh. You seem to want everyone who you disagree with to die.
STOP. That's where you are wrong. You haven't read my numerous
comments (or the documentation), so you don't understand the logic of
it and therefore your "arguments" are skewed. An argument is point-
counterpoint and requires understanding. When I say point A, you
should not respond with an unrelated point B. It only serves to waste
time and confuse issues.
[snip]
Sounds like a contradiction to what you wrote earlier:
I wrote:
| What you've stated in the above paragraph (the one I am directly
| replying to) is that isHostMethod requires the developer to have a
| presupposition about what the presence of an object property means
| about it.
And you replied:
| YES.
And, as I just stated, (the part where you said I am wrong):
| isHostMethod does not deductively check to see if a property is a
|method. It requires presupposition, *just like in does*.
Neither approach determines callability and both are faulty in some way.
Either (or both) can be used in valid strategies. Both have benefits and
drawbacks.
The |in| operator is a good and useful operator that made it into
EMCA-262r3 (1999).
A strategy using |in| on host objects can mostly work (though not in Mac
IE). It is shorter, simpler, and faster than using an isHostMethod.
Of course it does. Do you not see how that is a problem? Get your
hearing checked.
[snip\
That's not even a possibility. You are far too uncouth.
If you are British, you are giving the country a bad name. Well, two
names. :)
As you see it. And, of course, there's the logic you don't seem to
understand. Read those one-liners (two maybe) again. They are not
the same as testing for the existence of a property.
> Either (or both) can be used in valid strategies. Both have benefits and
> drawbacks.
>
> The |in| operator is a good and useful operator that made it into
> EMCA-262r3 (1999).
Thanks for that.
>
> A strategy using |in| on host objects can mostly work (though not in Mac
> IE). It is shorter, simpler, and faster than using an isHostMethod.
You left out "far less effective."
Shorter and simpler don't enter into it. Again, are you kidding? And
faster sure, but not enough to matter. Basically, you just want to
argue, despite the fact that you have no argument.
>>
>> Neither approach determines callability and both are faulty in some way.
>
> As you see it.
You can't seem to see anything other than the solution you have married
yourself to.
And, of course, there's the logic you don't seem to
> understand. Read those one-liners (two maybe) again. They are not
> the same as testing for the existence of a property.
>
They accomplish analagous results. The document.images collection is
*not* callable in Firefox, yet isHostMethod says it is.
> You left out "far less effective."
Less effective at *what*?
Determining callability? Not that. Less effective at determining if the
base object is actually an object? Certainly not that, in fact the
opposite is true!
>
> Shorter and simpler don't enter into it. Again, are you kidding? And
> faster sure, but not enough to matter. Basically, you just want to
> argue, despite the fact that you have no argument.
No, I provided a summary that |in| is a viable alternative to the
|isHostMethod|, that it is shorter and faster.
typeof checks fails fail to detect the item() method in IE. Not a
problem, if item is not used. It crashes under Safari 2 with NodeList.
that is a more serious problem.
|in| fails with false positive on document.styleSheets collection and
positive for things that are "hidden", which should never be a problem
(no reason to want to do that).
|in| works.
So there is a false positive, but it is a false positive that is caused by a
wrong premise of the caller. `document.images' is not supposed to be
subject to this feature test as it does not need to be called, and so its
callability is not an issue.
In contrast, the `in' operation makes exactly *no* statement about the
callability of the subject, in the best case it can only state its existence
(that is, either the object has this property or it is inherited through the
prototype chain). And it does that in a more error-prone and less
compatible way (cf. ES3F, sections 11.4.3 and 11.8.7, and the ECMAScript
Support Matrix).
PointedEars
No one of posters raised the real problem of practical DOM
programming. It is not enough to know if a property is presented. Even
checking if the property is callable (acts as a method) doesn't do
much good. The most important is to know what and how this property/
method does in this particular UA (User Agent). A bit outdated yet
still actual for some intranet environments example:
document.createElement in IE6
window.alert('createElement' in document); // true
window.alert(typeof document.createElement); // 'object'
// but
window.alert(''.concat(document.createElement).indexOf('function')!
=-1); // true
// so a method
And what good of it unless I know that it is IE6? Because in IE6 it
will lead to a runtime error as soon as will try to create an INPUT
element. For IE6 I need to use
document.createElement('<INPUT TYPE="TEXT">') syntax which obviously
is not acceptable for say Firefox.
This is why we need to know the exact UA type and version our script
is running and there is no alternatives to that. The alternatives
appears for how do we detect the type and the version: either by
studying UserAgent string or by checking some properties of the host
object which are known in advance to be specific in their presence or
absence for a specific UA. The common modern trend is to use property
sniffing rather then UserAgent sniffing.
The method is supposed to do what its name indicates.
> A bit outdated yet still actual for some intranet environments example:
> document.createElement in IE6
>
> window.alert('createElement' in document); // true
> window.alert(typeof document.createElement); // 'object'
> // but
> window.alert(''.concat(document.createElement).indexOf('function')!
> =-1); // true
> // so a method
Yes, we know that. Which is why methods determining the likelihood of
callability also test for "object" (and "unknown").
> And what good of it unless I know that it is IE6? Because in IE6 it
> will lead to a runtime error as soon as will try to create an INPUT
> element. For IE6 I need to use
> document.createElement('<INPUT TYPE="TEXT">') syntax which obviously
> is not acceptable for say Firefox.
And not necessary for IE 6 at all.
> This is why we need to know the exact UA type and version our script
> is running and there is no alternatives to that. [...]
It is the same in all MSHTML 4+ based UAs, though, which renders your
argumentation utter nonsense if there was not sufficient evidence already
that you don't know what you are talking about.
Do not feed this troll. (Search the archives about it instead.)
PointedEars
One of isHostMethod's goals is to prevent bumping into oddball host
objects like those that report "unknown" type in IE. An assumption is
that if isHostMethod returns true for `document.createElement`, it's
likely that this method is safe to call.
> much good. The most important is to know what and how this property/
> method does in this particular UA (User Agent). A bit outdated yet
> still actual for some intranet environments example:
> document.createElement in IE6
>
> window.alert('createElement' in document); // true
> window.alert(typeof document.createElement); // 'object'
> // but
> window.alert(''.concat(document.createElement).indexOf('function')!
> =-1); // true
> // so a method
What host object's `toString` returns hardly means anything. Don't rely
on it:
<http://thinkweb2.com/projects/prototype/those-tricky-functions/>
<http://thinkweb2.com/projects/prototype/detecting-built-in-host-methods/>
>
> And what good of it unless I know that it is IE6? Because in IE6 it
> will lead to a runtime error as soon as will try to create an INPUT
> element. For IE6 I need to use
> document.createElement('<INPUT TYPE="TEXT">') syntax which obviously
> is not acceptable for say Firefox.
So make a test. Use try/catch to determine if createElement accepts
"extended" syntax and act accordingly. This is a very simple feature
detection. No need to sniff userAgent string or use object inference.
>
> This is why we need to know the exact UA type and version our script
> is running and there is no alternatives to that. The alternatives
> appears for how do we detect the type and the version: either by
> studying UserAgent string or by checking some properties of the host
> object which are known in advance to be specific in their presence or
> absence for a specific UA. The common modern trend is to use property
> sniffing rather then UserAgent sniffing.
Sniffing has its uses, but they are rare and can be often avoided. Your
example is definitely not one of them.
--
kangax
I do repeat my question: IF a host property is found AND it is checked
that it can be used as a method (is callable) THEN it must be the
method safe to call in the way and with the results exactly as
described by ? at ? (not sure what place to suggest but obviously it
has to be a single one).
Is this the story you are trying to sell or did I miss something?
Try it again in a coherent and, thusly, understandable way.
PointedEars
> And what good of it unless I know that it is IE6? Because in IE6 it
[document.createElement, ed.]
> will lead to a runtime error as soon as will try to create an INPUT
> element.
Nonsense. Taking a wild guess, you are trying to set the ‘type’ property
after the INPUT element has been created and added to the document.
> This is why we need to know the exact UA type and version our script
> is running and there is no alternatives to that.
If you are unable to locate the source of trivial problems like the
above within a decade, there may be no alternatives left, right.
I gave you just a sample, moreover one of the most primitive ones,
where using detected method in some situations simply leads to a
runtime error. The main problem is with methods perfectly callable in
all allowed situations but leading to slightly or hugely different
visual results.
As Thomas pretending that he didn't understand my last question, I am
putting it in more simple form:
---
A really reliable method call looks like this:
IF the needed host property detected
AND this property is callable (acts as method)
THEN call this property to get necessary results no matter what UA
your script is running on
---
The question: is this a correct explanation of isHostMethod-like
approach and thinking discussed in this thread?
Correct. Seems the "unknown" types indicate properties of an ActiveX
object, but nobody knows for sure. It has been demonstrated
repeatedly that type converting these properties throws an exception.
Take that bit away and it is just checking for a "function" type or
truthy object (e.g. not null.)
The most important thing is that you must give isHostMethod a valid
proposition per the documentation (i.e. host object + the name of a
property that is expected to be a method and therefore inherently
callable.) I think we all know what that means (except for one
apparently.)
>
> > much good. The most important is to know what and how this property/
> > method does in this particular UA (User Agent). A bit outdated yet
> > still actual for some intranet environments example:
> > document.createElement in IE6
>
> > window.alert('createElement' in document); // true
> > window.alert(typeof document.createElement); // 'object'
> > // but
> > window.alert(''.concat(document.createElement).indexOf('function')!
> > =-1); // true
> > // so a method
>
> What host object's `toString` returns hardly means anything. Don't rely
> on it:
> <http://thinkweb2.com/projects/prototype/those-tricky-functions/>
> <http://thinkweb2.com/projects/prototype/detecting-built-in-host-methods/>
Don't bother arguing with VK. Give him a minute and he'll try to
monopolize your whole week.
>
>
>
> > And what good of it unless I know that it is IE6? Because in IE6 it
> > will lead to a runtime error as soon as will try to create an INPUT
> > element. For IE6 I need to use
> > document.createElement('<INPUT TYPE="TEXT">') syntax which obviously
> > is not acceptable for say Firefox.
>
> So make a test. Use try/catch to determine if createElement accepts
> "extended" syntax and act accordingly. This is a very simple feature
> detection. No need to sniff userAgent string or use object inference.
He's fantasizing (as usual.) Just ignore him.
>
>
>
> > This is why we need to know the exact UA type and version our script
> > is running and there is no alternatives to that. The alternatives
> > appears for how do we detect the type and the version: either by
> > studying UserAgent string or by checking some properties of the host
> > object which are known in advance to be specific in their presence or
> > absence for a specific UA. The common modern trend is to use property
> > sniffing rather then UserAgent sniffing.
>
> Sniffing has its uses, but they are rare and can be often avoided. Your
> example is definitely not one of them.
US sniffing has no use other than to echo an arbitrary string
property. Multiple object inferences come up once in a blue moon,
usually because of an inflexible design (e.g. a monolithic library
that tries to do too much.)
You gave a perfect example of your ongoing cluelessness; one simply does not
and need not to call document.createElement('<INPUT TYPE="TEXT">') anywhere.
Go away.
PointedEars
You are correct. VK is nuts.
>
> > This is why we need to know the exact UA type and version our script
> > is running and there is no alternatives to that.
>
> If you are unable to locate the source of trivial problems like the
> above within a decade, there may be no alternatives left, right.
That's how we ended up with something like jQuery in 2009. Ten years
of futility. Last I read in their group, they were wondering whether
they could finally stop "supporting" IE6. LOL. As if they ever
understood the first thing about it. They, as well as VK, can't say
they haven't been told (repeatedly.)
Please be merciful on my so weak brains and answer in most simple
words is the statement below considered to be correct one:
That is a red herring, and you know it. Nobody ever stated that if a
property passes the isHostMethod() test it
1. MUST be callable without error
and
2. MUST return the expected result.
That is why one, if necessary, takes necessary precautions should the call
fail, and one definitely checks the return value of calling the tested
property before one uses it.
I, in particular, was talking about "*likelihoods* of callability" in this
very thread, which you could have noticed were it your intention to learn
anything here and not just trolling. In the unlikely case I am wrong making
this assessment, you should start learning to *read*; otherwise go away.
PointedEars
Brains?
>
> ---
> A really reliable method call looks like this:
>
> IF the needed host property detected
Yes.
> AND this property is callable (acts as method)
By passing a property name to isHostMethod, you are asserting that the
property will be callable in all implementations if it is one of three
expected types (and truthy in the case of "object" types.) You don't
ask about properties that are never callable (e.g. offsetParent) or
properties that might be callable but aren't normally called (e.g.
images, all.) That's it.
> THEN call this property to get necessary results no matter what UA
> your script is running on
Yes, one normally calls methods. No, the UA doesn't enter into it.
This is a cross-browser technique and a good opportunity for you to
finally gain some understanding about cross-browser scripting (please
don't squander it with meaningless techno-babble.)
Oh come'on... Don't get boring.
> > ---
> > A really reliable method call looks like this:
>
> > IF the needed host property detected
>
> Yes.
OK
> > AND this property is callable (acts as method)
>
> By passing a property name to isHostMethod, you are asserting that the
> property will be callable in all implementations if it is one of three
> expected types (and truthy in the case of "object" types.) You don't
> ask about properties that are never callable (e.g. offsetParent) or
> properties that might be callable but aren't normally called (e.g.
> images, all.) That's it.
So you don't consider expando cases, like a property presented but it
is a runtime user-defined property just happened to have the name in
question? It is not a criticism because if one decides to break the
script - she will do it no matter what. Just knowing your paranoid
coding style I am a bit surprised you are disregarding this
opportunity for another check. The chances of such situation are
somewhere near 0.001% so at least 100,000 higher then getting UA
without in-operator support and 1,000,000 higher than getting UA
without document.getElementById support.
> > THEN call this property to get necessary results no matter what UA
> > your script is running on
>
> Yes, one normally calls methods. No, the UA doesn't enter into it.
OK, so the updated version of your approach is:
IF the needed method is found in host object
THEN call it to get the needed results no matter what UA your script
is running on
Is it correct now?
> This is a cross-browser technique and a good opportunity for you to
> finally gain some understanding about cross-browser scripting
If the algorithm description above is correct then it is hardly I can
learn anything valuable from people supporting this algorithm.
btw about document.createElement in other posters comments: no, it is
not for INPUT only, try for instance
document.createElement('BUTTON') for IE6
It has to be real IE6 though because X-UA-Compatible switch doesn't
restore all former bugs.
And again you are missing the main point of the problem in the real
world (not in "clj-world"):
Even if we wrap "just for hell of it" each and every host method call
into try-catch block and start checking all return values for type
correctness, it doesn't make the script commercially usable. It is
because a number of host methods are callable, giving right return
value but producing different visual outcome on different browsers.
I don't know if you are capable or willing to learn, but you may take
a look at my TransModal project to get your feet wet in cross-browser
Javascript programming. The code is well documented:
http://transmodal.sourceforge.net/TransModal_0_0_4_full/scripts/TransModal.js
the test pages are
http://transmodal.sourceforge.net/TransModal_0_0_4_full/0_0_4_Strict.html
http://transmodal.sourceforge.net/TransModal_0_0_4_full/0_0_4_Compat.html
You also may contribute to the project so finally produce in your life
something more useful than 100% bulletproof gEBI detectors.
If this library is too complex for the first time, you may also take a
look at my JSONet cross-domain data exchange library:
http://jsnet.sourceforge.net/
It is much more compact and simpler to follow yet still illustrates
the topic.
Now you're back : I've seen that you once posted something on the
history of CLJ FAQs. It has been suggested that something about that
might be added to the FAQ Notes.
--
(c) John Stockton, nr London UK. ???@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Check boilerplate spelling -- error is a public sign of incompetence.
Never fully trust an article from a poster who gives no full real name.
Yes, back in 2006 I made the full story of CLJ FAQ, see
http://groups.google.com/group/comp.lang.javascript/msg/8954de60cffe6dab
I did some corrections later at the same year, see
http://groups.google.com/group/comp.lang.javascript/msg/7b2a3100608da41e
and I got a copy of the very first FAQ page from WayBack Machine. This
copy is still available at the same address:
http://jsnet.sourceforge.net/tmp/clj_1996.htm
If the consensus to add it to FAQ is still here, I can start new
thread for FAQ article preparation.
I'm not quite sure what the "right premise" is, but in this case, it
seems like it's "the property needs to be called".
>
> In contrast, the `in' operation makes exactly *no* statement about the
> callability of the subject, in the best case it can only state its existence
> (that is, either the object has this property or it is inherited through the
> prototype chain). And it does that in a more error-prone and less
> compatible way (cf. ES3F, sections 11.4.3 and 11.8.7, and the ECMAScript
> Support Matrix).
>
>
You said the 'in' operation makes exactly *no* statement about the
callability of the subject. Right you are.
Neither |in| nor isHostMethod method determine callability. isHostMethod
rules out the possibility that the property value is primitive but that
is irrelevant in most contexts.
TheisHostMethod logic is as presumputous as an inference made after
checking presence with |in|; kist because the browser reports "unknown"
or "object" (as I showed in my document.images example) the property is
assumed to be callable. And the name "isHostMethod" is presumptuously
misleading.
The typeof a host object property can be *anything*. Method isHostMethod
is based on the result of typeof, and therefore is based on nothing more
than informed assumptions.
Both require presupposition.
Both |in| and |typeof| check the property in the prototype chain, so
that cancels out, as far as comparisons go.
Regarding the comment on |in| being more error-prone: |in| throws a
TypeError if the right hand operand is not an object[ex1], while typeof
throws when the property is null or undefined[ex2]. That makes typeof
less error prone when the operand is number, string, or boolean but that
is irrelevant in most cases. That is some of thinking that went into it.
Reducing the number of things that will pass isHostMethod does not
remove the need to make a reasonable inference about the property.
Making a reasonable inference is what is important. Code that uses |in|
clearly shows that the code makes an inference, isHostMethod is
presumptuous.
Most situations in context of dealing with host objects could get away
with: - if(!obj) - and be confident that the obj would never be a
number, string, or boolean[ex3]. So, in context, a strategy using |in|
would not be more error-prone.
A reasonable strategy for determining if a property is a method, while
ensuring that the would-be object is not a primitive is to first do
that: Make sure the base object is not a primitive. Inferences and
simple checks can be made in cases when dealing with host objects[ex3].
The strategy for determining callability is to make reasonable
assumptions about an object property. I do this *all the time*. For
example, code such as:-
window.alert("test").
- I make the assumptions that |window| is A) a browser window object
with B) an alert property that is C) callable.
Three assumptions.
==
Examples and Commentary:
ex1, TypeError on |in| and |typeof|:
// produces an error.
var aPrimitive = 2;
"toString" in aPrimitive
// no error with typeof
typeof aPrimitive.toString
I see no reason to use |in| on a number. The only plausible situation of
using prop in aPrimitive *by mistake* would be where aPrimitive ===
undefined or aPrimitive === null . IN that case, TypeError occurs with
typeof:-
ex2:
var aPrimitive;
typeof aPrimitive.toString; // => Error.
aPrimitive = null;
typeof aPrimitive.toString; // => Error.
// Error is avoided by a simple check of aPrimitive
if(aPrimitive && "toString" in aPrimitive) {
}
[ex3]
// throws error if el is null/undefined.
function removeNode(el) {
var p = el.parentNode;
// p might be null or undefined, or an object,
// but should never be number string, or boolean.
if(p != null) {
if("removeChild" in p) {
p.removeChild(el);
}
}
}
Downsides to in:
|in| is a more recent addition to ECMAScript. It is less compatible. It
doesn't work in Mac IE or Netscape 4. For compatibility with these
browsers, use typeof and test accordingly.
Downsides to isHostMethod:
The typeof operator used on a host object returns an
implementation-dependent string. To account for the various results in
implementations, the user-defined wrapper isHostMethod was created.
A reasonable expectation of a method with the name "isHostMethod" would
be that if it returns true, the property is a method of a Host object.
That is not what isHostMethod does. The name is misleading.
isPossibleHostMethod is more apt.
Calling a user-defined method contributes to the size of a codebase.
Calling said method is slower than a native |in| operation. Should the
program require debugging, that is one more method to step into. Less is
more.
Neither approach determines callability. Both require presupposition
that can and that should be based on reasonable inferences. For example,
a reasonable inference would be knowing that if an "addEventListener" is
present on the object, that it is callable, as no known implementations
have an addEventListener property that behaves otherwise.
Using direct type conversion is error prone, as some host objects throw
errors upon type conversion.
Both the |in| operator and the typeof operator provides the programmer
with a way to check for the existence of a property while avoiding type
conversion.
The typeof operator mostly works.
The |in| operator mostly works, too.
Both have edge cases that do not work.
In most cases, |in| is the simplest thing that could possibly work.
To determine callability, ES5 provides new behavior for typeof:
| ES5 (11.4.3) requires that both native (ie, pure actual ECMAScript
| objects) and host objects that implement [[Call]] produce "function"
| when typeof is applied to them.
- Allen Wirfs-Brock.
Until ES5 rolls out, the best known approach is to make reasonable
inferences about an object's interface, specifically, what the presence
of property |p| on object |o| in a given context.
And again we're back to browser sniffing. Please, understand that this
is far from an optimal solution.
...
with (wndDialogTitleBar.style) {
...
else if (TransModal.isSafari) {
WebkitBorderTopLeftRadius = '8px';
WebkitBorderTopRightRadius = '8px';
}
...
TransModal.isSafari = (navigator.userAgent.indexOf('Safari') != -1);
...
So unless `userAgent` string has "Safari" in it, clients which actually
*do support* "WebkitBorderTopLeftRadius", such as *Chrome or numerous
Linux and mobile clients that are all based on WebKit*, are left in a
cold all alone?
Why would you do that?
--
kangax
[...]
> ---
> A really reliable method call looks like this:
>
> IF the needed host property detected
> AND this property is callable (acts as method)
> THEN call this property to get necessary results no matter what UA
> your script is running on
> ---
>
Sounds like a capability test is in order. That is mentioned in the FAQ,
but there is an example of a feature presence test following the mention
of capability test.
| Object detection is checking that the object in question exists.
| Capability detection goes one step further to actually test the oject,
| method, or property, to see if behaves in the desired manner.
|
| For example:
|
[feature presence test example]
The text "For example:" should change to "Feature test example:"
The article on capability detection is in the "see also". It should be
linked within the entry itself.
| Capability detection goes one step further to actually test the
| object, method, or property, to see if behaves in the desired manner
| see also: "Using capability detection"
|<URL: http://dev.opera.com/articles/view/using-capability-detection/ >.
That Opera article on capability detection could also include some
mention of ActiveX. I plan on adding some comments there, though I would
rather see that text directly in the article itself, as not all will
read all the article commments.
It would also be worth considering adding a link to the CFT project,
though I think the code in there might want to get some scrutiny from
this group first. Provided kangax is not too busy for that.
Did you actually test it in Chrome? ;-) The borders are rounded.
Overall please follow the logic of the whole script, not a separate
chunk of it. It is called TransModal, not TransRoundedCorners. If the
only purpose of the script was to set CSS-based rounded corners
wherever however it might be supported then the approach would be
rather different.
But the script has to
1) cover 100% width x 100% height of document content including out of
view areas both in BackCompat and Strict mode
2) center the dialog pseudo-window in the current view
3) generate and insert form elements
and many additional stuff (see comments)
Within the scope of these tasks it is irrelevant that some browser X
may support WebkitBorderTopLeftRadius because without actual testing
you have absolutely no idea how the rest of code will behave.
Remember the main rule of the actual web development: unless you saw
it is working in browser X under OS Y, it does not work for browser X
under OS Y. Never state otherwise, never think otherwise, never do
otherwise.
I think an entire CFT could be replaced with one tutorial and a set of
examples. The goal of the project was to show some of the common
patterns in feature testing. Surprisingly, it's not as easy as it seems
to write a good feature test. At least it wasn't very obvious to me.
Cornford's article (linked to from FAQ) was a great start. It explained
why and how feature detection is superior to other alternatives, but it
didn't give enough examples. Then there were Michaux's articles as
continuation on the subject. Those were very insightful but I still had
questions: How do you test something that's only available after body is
loaded? How do you test event object properties when there's no event
available at the time script is being executed? How do you test event
support? CSS property support? how do you test a specific bug? what if
that bug "relies" on `document.body` being available and you need to fix
it for a method that could be invoked before `document.body` is available?
I suppose CFT did come out to be useful after all. I recently noticed
that jQuery's support() docs link to it
<http://docs.jquery.com/Utilities/jQuery.support>
--
kangax
No problem. I see strange constructs in other parts as well:
...
if (document.body == null) {
if (TransModal.isIE) {
window.attachEvent('onload', TransModal);
}
else {
window.addEventListener('load', TransModal, false);
}
return null;
}
...
Why are you limiting IE to `attachEvent`? What if they implement
compliant `addEventLisener` in the next iteration?
...
/* Prototype.js compatibility.
* If global $() function is already defined
* then do not override it. Otherwise making
* a lightweight replacement of it.
*
* We don't want a parasite closure in here,
* so we are using Function constructor.
*/
// ! BUG bug 0.0.4#1
// Possible jQuery namespace slash as per
// http://docs.jquery.com/Using_jQuery_with_Other_Libraries
if (typeof $ != 'function') {
$ = new Function('id', 'return document.getElementById(id)');
}
...
What is this "parasite closure" you're talking about? What does it
parasite and why are you avoiding it?
...
with (wndDialogIcon.style) {
margin = '4px 4px';
padding = '0px 0px';
(TransModal.isIE) ? (styleFloat = 'left') : (cssFloat = 'left');
}
...
Why nonsense inference again? It's *really not hard* to test for a
presence of "styleFloat" in `style` object ;) And, by the way,
`margin = "4px 4px"` could be shortened to "4px" (ditto for padding)
...
if (TransModal.isIE) {
button = document.createElement('<BUTTON TYPE="BUTTON">');
// - otherwise runtime error on attempt to set control type;
// thank you, IE, for bringing so much fun into our life...
}
else if (TransModal.isOpera) {
// Yet Opera bits IE with the fun so far: it has
// the same "no controls type change security lock"
// plus it doesn't provide IE's-like workaround.
// As the result we have to use rather crazy code to
// get type="button" instead of the default "submit":
tmp = document.createElement('SPAN');
tmp.innerHTML = '<BUTTON TYPE="BUTTON"></BUTTON>';
button = tmp.firstChild;
}
else {
// Sic! Safari here is on the side of adequately acting
// browsers so doesn't require a personal workaround.
// Worth a mention as a rare situation...
button = document.createElement('BUTTON');
button.type = 'button';
}
...
Again, this is all very brittle. It needs a test; a test that is not
very hard to employ. See <http://yura.thinkweb2.com/cft/> for some of
the examples.
[...]
--
kangax
Till 2015 it is out of practical concerns, as long as Windows 2000 +
IE6 commitment is in action between the US government and Microsoft.
It is very slightly possible that some year 2016 or 2020 there will be
IE with addEventLisener but without attachEvent. It is also possible
that there will be neither Microsoft nor IE any more 6 years from now
so all this branching will get mute. It is possible that 6, 10, 100
years from now just like at this very moment there will be a few dorks
and web-punks browsing the Web with Netscape 3-4 or IE 4-5 or a toilet
made UA without neither option. The options are endless, but who the
hell cares? There are too many really interesting, really challenging
and really demanded things to do in the modern web programming to keep
sitting and masturbating on these if's ;-) So far we know that it is
IE so it has attachEvent, otherwise it has addEventListener, otherwise
screw it - look at calendar on the wall and try to believe that it is
perfectly OK at the current epoch ;-)
> ...
> /* Prototype.js compatibility.
> * If global $() function is already defined
> * then do not override it. Otherwise making
> * a lightweight replacement of it.
> *
> * We don't want a parasite closure in here,
> * so we are using Function constructor.
> */
>
> // ! BUG bug 0.0.4#1
> // Possible jQuery namespace slash as per
> //http://docs.jquery.com/Using_jQuery_with_Other_Libraries
>
> if (typeof $ != 'function') {
> $ = new Function('id', 'return document.getElementById(id)');
> }
> ...
>
> What is this "parasite closure" you're talking about? What does it
> parasite and why are you avoiding it?
The parasite closure is the closure created not for some practical
purposes by the programmer - say for encapsulation emulation - but
appeared as a side effect of careless anonymous function assignments.
We want to avoid it because we don't want to be leaking memory unless
we have no other options. Search "memory leak closure" in this group
first, I will be glad to explain the details in a separate thread.
> ...
> with (wndDialogIcon.style) {
> margin = '4px 4px';
> padding = '0px 0px';
> (TransModal.isIE) ? (styleFloat = 'left') : (cssFloat = 'left');
> }
> ...
>
> Why nonsense inference again? It's *really not hard* to test for a
> presence of "styleFloat" in `style` object ;)
It is not :-) But why to do it if we know already that it is IE or not
IE at the compilation stage so we know if we need to use styleFloat or
cssFloat? Why to introduce yet another check: just in case if UA gets
changed at runtime? It is not a principal question really but I just
hate any coding for coding itself.
> And, by the way,
> `margin = "4px 4px"` could be shortened to "4px" (ditto for padding)
And at ciwas (a.k.a. comp.infosystems.www.authoring.stylesheets) some
regulars would get berserk for "margin:0px" because "margin:0" is
enough so must be used. Admittedly I am having some anankastic
disorders, this is professional for any long time programmer, a
consequence of being forced to do things in strictly defined way and
in strictly defined order :-) There is no logic behind using "margin:
4px 4px" instead of just "margin: 4px" but the latter makes me feel
uncomfortable. Just like curly brackets is not on the same line.
Trying to control myself.
> ...
> if (TransModal.isIE) {
> button = document.createElement('<BUTTON TYPE="BUTTON">');
> // - otherwise runtime error on attempt to set control type;
> // thank you, IE, for bringing so much fun into our life...
> }
> else if (TransModal.isOpera) {
> // Yet Opera bits IE with the fun so far: it has
> // the same "no controls type change security lock"
> // plus it doesn't provide IE's-like workaround.
> // As the result we have to use rather crazy code to
> // get type="button" instead of the default "submit":
> tmp = document.createElement('SPAN');
> tmp.innerHTML = '<BUTTON TYPE="BUTTON"></BUTTON>';
> button = tmp.firstChild;
> }
> else {
> // Sic! Safari here is on the side of adequately acting
> // browsers so doesn't require a personal workaround.
> // Worth a mention as a rare situation...
> button = document.createElement('BUTTON');
> button.type = 'button';
> }
> ...
>
> Again, this is all very brittle. It needs a test; a test that is not
> very hard to employ. See <http://yura.thinkweb2.com/cft/> for some of
> the examples.
This comment is not understood? Of course it was tasted before the
claim.
As you wish.
>
>> ...
>> /* Prototype.js compatibility.
>> * If global $() function is already defined
>> * then do not override it. Otherwise making
>> * a lightweight replacement of it.
>> *
>> * We don't want a parasite closure in here,
>> * so we are using Function constructor.
>> */
>>
>> // ! BUG bug 0.0.4#1
>> // Possible jQuery namespace slash as per
>> //http://docs.jquery.com/Using_jQuery_with_Other_Libraries
>>
>> if (typeof $ != 'function') {
>> $ = new Function('id', 'return document.getElementById(id)');
>> }
>> ...
>>
>> What is this "parasite closure" you're talking about? What does it
>> parasite and why are you avoiding it?
>
> The parasite closure is the closure created not for some practical
> purposes by the programmer - say for encapsulation emulation - but
> appeared as a side effect of careless anonymous function assignments.
> We want to avoid it because we don't want to be leaking memory unless
> we have no other options. Search "memory leak closure" in this group
> first, I will be glad to explain the details in a separate thread.
Then why are there dozens of other functions (and so closures) created
after that `$` assignment? At least few of them that I looked at do not
"take advantage" of closures that they are forming. Why is it only `$`
that you create with Function constructor?
I also don't see how a memory leak could occur there. How exactly would
a circular reference be formed if `$` was defined as either function
expression, or function declaration? Would you please explain?
>
>> ...
>> with (wndDialogIcon.style) {
>> margin = '4px 4px';
>> padding = '0px 0px';
>> (TransModal.isIE) ? (styleFloat = 'left') : (cssFloat = 'left');
>> }
>> ...
>>
>> Why nonsense inference again? It's *really not hard* to test for a
>> presence of "styleFloat" in `style` object ;)
>
> It is not :-) But why to do it if we know already that it is IE or not
> IE at the compilation stage so we know if we need to use styleFloat or
> cssFloat? Why to introduce yet another check: just in case if UA gets
> changed at runtime? It is not a principal question really but I just
> hate any coding for coding itself.
I don't see how checking for a certain property before using that
property can be called "another check". Isn't the the most
straight-forward way?
>
>> And, by the way,
>> `margin = "4px 4px"` could be shortened to "4px" (ditto for padding)
>
> And at ciwas (a.k.a. comp.infosystems.www.authoring.stylesheets) some
> regulars would get berserk for "margin:0px" because "margin:0" is
> enough so must be used. Admittedly I am having some anankastic
> disorders, this is professional for any long time programmer, a
> consequence of being forced to do things in strictly defined way and
> in strictly defined order :-) There is no logic behind using "margin:
> 4px 4px" instead of just "margin: 4px" but the latter makes me feel
> uncomfortable. Just like curly brackets is not on the same line.
> Trying to control myself.
As you wish.
I'm sure it tasted bitter :)
Which version of Opera exhibit this bug? There's a very big chance that
it is already fixed in later versions. If that's the case, you're doing
an unnecessary workaround. And again, if next version of IE (or another
client, `navigator.userAgent` of which looks like IE) disallows extended
syntax, the whole thing will fail.
--
kangax
It is like something *I personally* wish - it is what it is.
> >> if (typeof $ != 'function') {
> >> $ = new Function('id', 'return document.getElementById(id)');
> >> }
> >> ...
>
> >> What is this "parasite closure" you're talking about? What does it
> >> parasite and why are you avoiding it?
>
> > The parasite closure is the closure created not for some practical
> > purposes by the programmer - say for encapsulation emulation - but
> > appeared as a side effect of careless anonymous function assignments.
> > We want to avoid it because we don't want to be leaking memory unless
> > we have no other options. Search "memory leak closure" in this group
> > first, I will be glad to explain the details in a separate thread.
>
> Then why are there dozens of other functions (and so closures) created
> after that `$` assignment? At least few of them that I looked at do not
> "take advantage" of closures that they are forming. Why is it only `$`
> that you create with Function constructor?
>
> I also don't see how a memory leak could occur there. How exactly would
> a circular reference be formed if `$` was defined as either function
> expression, or function declaration? Would you please explain?
Sure. But let's us not doing it in "FAQ Question: How do I detect
Opera/Netscape/IE" thread as being way too far from the declared
topic. Of course by simply declaring a new function we are not always
and necessarily creating a memory leak. What you may overlooked here
is that in this particular case we are creating a new function within
another function what contains the entire code. You still may want to
search for "closure memory leak" in this group, it was discussed and
tested in depth, at least 1-2 years ago. Maybe I'll start a topic on
it, just today-tomorrow are looking very busy for me so far.
> >> ...
> >> with (wndDialogIcon.style) {
> >> margin = '4px 4px';
> >> padding = '0px 0px';
> >> (TransModal.isIE) ? (styleFloat = 'left') : (cssFloat = 'left');
> >> }
> >> ...
>
> >> Why nonsense inference again? It's *really not hard* to test for a
> >> presence of "styleFloat" in `style` object ;)
>
> > It is not :-) But why to do it if we know already that it is IE or not
> > IE at the compilation stage so we know if we need to use styleFloat or
> > cssFloat? Why to introduce yet another check: just in case if UA gets
> > changed at runtime? It is not a principal question really but I just
> > hate any coding for coding itself.
>
> I don't see how checking for a certain property before using that
> property can be called "another check". Isn't the the most
> straight-forward way?
The underground logic behind is the terrible behavior of Safari and
especially Opera till very recently. They placed bogus property and
methods left and right to emulate both IE and Gecko w/o any equal
functionality behind of them (samples on request). The trust was
completely broken so using a bulletproof check from the conditional
compilation was - not sure if still is - the most straight-forward
way. Truly Opera is a dead horse by its market share for a couple of
years already, but in my project I am still trying to do something for
it out of nostalgic reasons.
> >> And, by the way,
> >> `margin = "4px 4px"` could be shortened to "4px" (ditto for padding)
>
> > And at ciwas (a.k.a. comp.infosystems.www.authoring.stylesheets) some
> > regulars would get berserk for "margin:0px" because "margin:0" is
> > enough so must be used. Admittedly I am having some anankastic
> > disorders, this is professional for any long time programmer, a
> > consequence of being forced to do things in strictly defined way and
> > in strictly defined order :-) There is no logic behind using "margin:
> > 4px 4px" instead of just "margin: 4px" but the latter makes me feel
> > uncomfortable. Just like curly brackets is not on the same line.
> > Trying to control myself.
>
> As you wish.
Thanks :-)
> >> else {
> >> // Sic! Safari here is on the side of adequately acting
> >> // browsers so doesn't require a personal workaround.
> >> // Worth a mention as a rare situation...
> >> button = document.createElement('BUTTON');
> >> button.type = 'button';
> >> }
> >> ...
>
> >> Again, this is all very brittle. It needs a test; a test that is not
> >> very hard to employ. See <http://yura.thinkweb2.com/cft/> for some of
> >> the examples.
>
> > This comment is not understood? Of course it was tasted before the
> > claim.
>
> I'm sure it tasted bitter :)
Sure it was :-) Silly regular typo of mine...
> Which version of Opera exhibit this bug?
Minor.Major are indicated in comments. 9.something, SourceForge is
down for this minute.
[...]
I assume you are much too busy for that.
I merged a good number of changes in your fork of APE back into the
main, but not all of them. I replied to your emails and sent one other,
but did not hear back.
If you're not too busy, such an addendum to the notes could be useful,
eventually. Since I am not yet done with the index page, I would not be
able to link to that just yet. I am doing a little at a time. There is a
good deal of rearrangement in order to make the Notes correspond to the
ordering of the FAQ sections (e.g. "DOM and Forms".
Garrett -> gym.
Choosing attachEvent is backwards.
addEventListener is the w3c standard approach. The code should that one
first. Otherwise, A) Opera gets the attachEvent code and B) it requires
anything that looks like IE to have attachEvent.
Suppose IE9 creates yet another "new standards mode" and that mode does
not have attachEvent, a script expects attachEvent will fail by poor
inference.
As stated in the FAQ on browser detection:-
| It is unrelated to the problem or incompatiblity it is trying to
| solve and tends obscures the thinking behind the code.
Taking that into consideration leaves us with something like:-
if(typeof el.addEventListener != "undefined") {
// code here.
} else {
// Fallback to attachEvent or screw it.
}
[...]
>> ...
>> with (wndDialogIcon.style) {
>> margin = '4px 4px';
>> padding = '0px 0px';
>> (TransModal.isIE) ? (styleFloat = 'left') : (cssFloat = 'left');
>> }
>> ...
>>
>> Why nonsense inference again? It's *really not hard* to test for a
>> presence of "styleFloat" in `style` object ;)
>
> It is not :-) But why to do it if we know already that it is IE or not
> IE at the compilation stage so we know if we need to use styleFloat or
> cssFloat? Why to introduce yet another check: just in case if UA gets
> changed at runtime? It is not a principal question really but I just
> hate any coding for coding itself.
>
Again, you would go with the standard approach first. A related
inference that would provide superior runtime performance:-
var floatProp = "cssFloat" in document.documentElement.style ?
"cssFloat" : "styleFloat";
and let the code use the square-bracket notation.
el.style[floatProp] = "none";
>> And, by the way,
>> `margin = "4px 4px"` could be shortened to "4px" (ditto for padding)
>
> And at ciwas (a.k.a. comp.infosystems.www.authoring.stylesheets) some
> regulars would get berserk for "margin:0px" because "margin:0" is
style.margin = "4" would be invalid. The shortest is style.margin = "4px";
There is no need to repeat "4px" any number of times more than one.
[...]
Garrett
Gotta love deadlines :/
>
> I merged a good number of changes in your fork of APE back into the
> main, but not all of them. I replied to your emails and sent one other,
> but did not hear back.
Sorry for being unresponsive. I'll reply to your emails whenever I get a
chance. I have already answered to your comments on github commits. Not
sure if you've seen those.
>
> If you're not too busy, such an addendum to the notes could be useful,
> eventually. Since I am not yet done with the index page, I would not be
> able to link to that just yet. I am doing a little at a time. There is a
> good deal of rearrangement in order to make the Notes correspond to the
> ordering of the FAQ sections (e.g. "DOM and Forms".
It would make sense for feature detection section in FAQ to include
Peter's articles (one on isHost* family and types of inferences; another
- on cross-browser widgets, which gives some insights on how to test
environment before initializing a widget).
Would there be any objections to that?
[...]
--
kangax