IE6 Nesting Problem?

B

bweaverusenet

Hi. I am trying to get some javascript to work in IE6, from the
address line. It works in Firefox and, I believe, IE7.

It appears that with some number of nested structures, the code does
not execute. Take a level or two out and it works. The code below is
nonsense, but illustrates the problem.

This works:

javascript: for( a=1;a<=10;a++ ) { for( b=1;b<=10;b++ ) { if( q<1000 )
{ for( c=1;c<=10;c++ ) { for( d=1;d<=10;d++ ) { if( a > 0 ) { if( a <
2000 ) { x=10; q++; } } } } } } } for( a=1;a<=10;a++ )
{ for( b=1;b<=10;b++ ) { if( q<1000 ) { for( c=1;c<=10;c++ )
{ for( d=1;d<=10;d++ ) { if( a > 0 ) { x=10; q++; } } } } } }
alert( q ); void( 0 );

But this doesn't:

javascript: for( a=1;a<=10;a++ ) { for( b=1;b<=10;b++ ) { if( q<1000 )
{ for( c=1;c<=10;c++ ) { for( d=1;d<=10;d++ ) { if( a > 0 ) { if( a <
2000 ) { x=10; q++; } } } } } } } for( a=1;a<=10;a++ )
{ for( b=1;b<=10;b++ ) { if( q<1000 ) { for( c=1;c<=10;c++ )
{ for( d=1;d<=10;d++ ) { if( a > 0 ) { if( a < 2000 ) { x=10; q+
+; } } } } } } } alert( q ); void( 0 );

I've tried declaring the variables, blah blah blah. Still breaks. Is
this a memory issue? Am I missing something obvious in the code?
Thanks for any help!

Here's a prettied version:

javascript:
for( a=1;a<=10;a++ ) {
for( b=1;b<=10;b++ ) {
if( q<1000 ) {
for( c=1;c<=10;c++ ) {
for( d=1;d<=10;d++ ) {
if( a > 0 ) {
if( a < 2000 ) {
x=10;
q++;
}
}
}
}
}
}
}
for( a=1;a<=10;a++ ) {
for( b=1;b<=10;b++ ) {
if( q<1000 ) {
for( c=1;c<=10;c++ ) {
for( d=1;d<=10;d++ ) {
if( a > 0 ) {
if( a < 2000 ) {
x=10;
q++;
}
}
}
}
}
}
}
alert( q );
void( 0 );
 
R

RobG

Hi. I am trying to get some javascript to work in IE6, from the
address line. It works in Firefox and, I believe, IE7.

It appears that with some number of nested structures, the code does
not execute. Take a level or two out and it works. The code below is
nonsense, but illustrates the problem.

This works:

It doesn't.
javascript: for( a=1;a<=10;a++ ) { for( b=1;b<=10;b++ ) { if( q<1000 )

Error: q is not defined.

If you want others to consider your question, post code that is easily
read. Also:

- highlight the differences between the 'working' and 'not working'
code
- advise what result indicates 'it works'
- report any error messages you get
 
B

bweaverusenet

It doesn't.




Error: q is not defined.

If you want others to consider your question, post code that is easily
read. Also:

- highlight the differences between the 'working' and 'not working'
code
- advise what result indicates 'it works'
- report any error messages you get

Hi Rob.

I posted the working and broken code as copied into the address bar of
the browser, however I also posted a prettied version of the broken
code for readability. The first bit of code *does* work in IE6 (and
firefox etc) from the browser address field. I realize q isn't defined
but neither are a b c and d. As I also mentioned in my post, I have
tried declaring the variables, with similar results.

The difference in the two snippits is a single additional if( a <
2000 ) test in the second set of nested for loops. Removing that test
yields the working alert( q ) while leaving it in does not.

I get no error messages, unless they are buried in some console
somewhere.

Regardless, unless I have some obvious syntactical error, the point is
that some number of nesting structures (loops, tests, etc.) appears to
make javascript from the IE6 browser address bar not work. Since I am
not an IE6 javascript whiz, I thought it might ring a bell with
someone here.

Thanks.
 
V

VK

I posted the working and broken code as copied into the address bar of
the browser, however I also posted a prettied version of the broken
code for readability. The first bit of code *does* work in IE6

No, it doesn't - at least in the programming sense of the word "work".
Phylosophical interpretations of "work" as "having a unrealized
potention to work" and similar are irrelevant here I guess ;-)
Rob pointed out the problem already: because you didn't instantiate q
variable, by reaching the statement if (q < 1000) you are getting
"Undefined identifier" run-time error. After adding q = 0 before loops
the program _works_ so it executes all loops and alerts 1000.
This way the particular code your posted has no UA-dependant problems
but it has the pointed coding error to correct.

On a big run as "can a very big bookmarklet do not work on IE?" the
answer is yes, you may hit the URL length limit imposed by IE (both 6
and 7). This limit is 2,048 characters minus the number of characters
in the actual path. javascript: pseudo-protocol is affected by this
limit as well. Because the exceeding part is simply being truncated, a
proper by itself code may become broken if used for bookmarklet. This
is why while making especially complicated bookmarklet or very long
GET requests watch closely the string length.

Hope it helps.

P.S. See also http://support.microsoft.com/kb/208427
 
B

bweaverusenet

Thanks. However, turns out it's much worse than that. IE6 apparently
has a limit on bookmarklets of around 500 bytes, slightly more for
IE6, slightly less for IE6 SP2.

http://subsimple.com/bookmarklets/rules.asp

Thanks for making me think about length. At first I thought you were
smoking something since the code wasn't nearly 2K long. However, a
simple search for IE6 bookmarklet length turned up this *stupid*
limitation of IE6. Hopefully I can get it to work by loading an
external js file.

Thanks again.
 
V

VK

Thanks. However, turns out it's much worse than that. IE6 apparently
has a limit on bookmarklets of around 500 bytes, slightly more for
IE6, slightly less for IE6 SP2.

Yes, apparently Microsoft narrowed the limit way more than stated in
their KB. That must happened in one of security updates. I wonder if
only javascript: was "victimized" so badly or GET request / POST URL
part as well?
Thanks for making me think about length. At first I thought you were
smoking something since the code wasn't nearly 2K long.

You are welcome but you are again mixing two unrelated issues. The
code you posted is not affected by any of IE URL limits, the engine
tries to execute it but it leads to run-time error "Undefined
identifier" because you didn't instantiate q variable. Simply
instantiate it before using and everything will be fine. I'm referring
to the code from your original post:

<quote>
This works:

javascript: for( a=1;a<=10;a++ ) { for( b=1;b<=10;b++ )
{ if( q<1000 )
{ for( c=1;c<=10;c++ ) { for( d=1;d<=10;d++ ) { if( a > 0 ) { if( a <
2000 ) { x=10; q++; } } } } } } } for( a=1;a<=10;a++ )
{ for( b=1;b<=10;b++ ) { if( q<1000 ) { for( c=1;c<=10;c++ )
{ for( d=1;d<=10;d++ ) { if( a > 0 ) { x=10; q++; } } } } } }
alert( q ); void( 0 );
However, a simple search for IE6 bookmarklet length turned up this *stupid*
limitation of IE6.

"Unexpected" I would say. I was explaining the issue a few years in
the row already (as it is a rather frequent one) - and most of the
time I get called stupid "because it cannot be because it just never
can be" :) The reason of such "mental block" for the true reason is a
bit strange to me. Yes, very bad guys, yes, may get very inconvenient
- but the suckers are right, no one of relevant RFCs demands to accept
unlimited length URL nor some no-lesser-than value. If someone really
doesn't like it - so migrate on some normal browser instead ;-)
 
B

bweaverusenet

VK. Thanks. I'm not really worried about the undefined variable; as I
said, I've tried defining it etc. but left it out of the original code
for the sake of brevity. The real issue is not URL length (which
remains at 2K in IE6 I think), but javascript: bookmarklet length. It
appears to be the culprit.

I have another issue now that I'm solving it by loading an offsite
script, but I'll edit the subject for that one. :)

Thanks again.
 
B

bweaverusenet

Following up on my IE6 Nesting question, which turned out to be the
508 byte IE6 bookmarklet length limit...

I'm attempting to solve this now by putting my main javascript in
functions in a .js file, then loading it from the bookmarklet.
However, I am running into a problem the first time it's executed. It
appears to be a readyState issue, but I am not sure how to solve it.

Calling the method after loading and injecting the .js script works
fine (readyState is complete at that point).

Here's the bookmarklet:
javascript: var js=document.createElement('script'); js.src='http://
localhost/isie.js'; js.setAttribute('type', 'text/javascript');
document.getElementsByTagName('head')[0].appendChild(js); hi();
void(0);

And here's test.js:
function hi() {
alert("hi");
}

For those format sticklers here's the bookmarklet formatted:
javascript:
var js=document.createElement('script');
js.src='http://localhost/isie.js';
js.setAttribute('type', 'text/javascript');
document.getElementsByTagName('head')[0].appendChild(js);
hi();
void(0);


Anyway, first time through I get an error "Line: 0 Error: Object
expected".

Second time through, or if I simply enter "javascript: hi();" into the
address bar, I get the "hi" alert.

So I'm guessing that the script isn't fully set up that soon, so the
engine doesn't know what hi() is. Is there a way to make hi() execute
*after* it's all loaded and groovy?

Incidentally, replacing hi() with alert(js.readyState) as follows
yields "loading" the first time, then "complete" on any subsequent
execution during that browser session.

javascript: var js=document.createElement('script'); js.src='http://
localhost/isie.js'; js.setAttribute('type', 'text/javascript');
document.getElementsByTagName('head')[0].appendChild(js);
alert(js.readyState); void(0);


Thanks for any guidance here.
 
V

VK

Following up on my IE6 Nesting question, which turned out to be the
508 byte IE6 bookmarklet length limit...

I'm attempting to solve this now by putting my main javascript in
functions in a .js file, then loading it from the bookmarklet.
However, I am running into a problem the first time it's executed. It
appears to be a readyState issue, but I am not sure how to solve it.

Yes, it is a frequent synchronization issue: appendChild(js) doesn't
mean "now js file is loaded and parsed, use its functions". It simply
puts a request for DOM Tree update and goes to the next line. If you
always have to call the same function onload, then simply put a call
for it at the very end of your external file:

hi.js file
---------

function hi() {
window.alert('Hi!');
}

hi();

---------

<html>
<head>
<title>Test</title>
<style type="text/css">
</style>
</head>
<body>
<a href="javascript:void((function(){if(window){var
js=document.createElement('SCRIPT');js.src='hi.js';document.getElementsByTagName('HEAD')
[0].appendChild(js);}})())">link</a>
</body>
</html>

P.S. In the form above the bookmarklet implements i) an environment
checks, ii) full void wrap against occasional text garbage and iii)
local shy namespace so do not pollute Global beyond the necessity

A pretty-printed version:

<html>
<head>
<title>Test</title>
<style type="text/css">
</style>
</head>
<body>
<a href="javascript:void((function(){
if(window) {
var js=document.createElement('SCRIPT');
js.src='hi.js';
document.getElementsByTagName('HEAD')[0].appendChild(js);
}})())">link</a>
</body>
</html>

P.P.S. Please do not quote the whole message and especially the whole
previous thread in your reply: it obscures very much future search
results :-| and also it is such a waste of electrons :)
Please quote only what you are replying to.
 
B

bweaverusenet

Yes, it is a frequent synchronization issue: appendChild(js) doesn't
mean "now js file is loaded and parsed, use its functions". It simply
puts a request for DOM Tree update and goes to the next line. If you
always have to call the same function onload, then simply put a call
for it at the very end of your external file:

Actually there are several functions, so this won't really work
(couldn't make it work while testing anyhow).

Using a try/catch with a timer seems to work. Do you see any problems
with this?

javascript:
var js=document.createElement('SCRIPT');
js.src='http://localhost/hi.js';
document.getElementsByTagName('HEAD')[0].appendChild(js);
setTimeout(fn=function() {
try {
hi();
} catch(e) {
alert(e.Description);
setTimeout( 'fn()', 10 );
}
}
, 10 );
void(0);
P.S. In the form above the bookmarklet implements i) an environment
checks, ii) full void wrap against occasional text garbage and iii)
local shy namespace so do not pollute Global beyond the necessity

I would like to understand some of this better.

* environment checks - can you explain a bit more? is this the
if(window) part? Does it limit the code to IE?
* full void wrap - you mean instead of the final void(0), right?
* The anonymous wrapper function() is nice and I'll test with it some
more.
P.P.S. Please do not quote the whole message and especially the whole
previous thread in your reply: it obscures very much future search
results :-| and also it is such a waste of electrons :)
Please quote only what you are replying to.

Okay. Sorry.
 
B

bweaverusenet

javascript:
var js=document.createElement('SCRIPT');
js.src='http://localhost/hi.js';
document.getElementsByTagName('HEAD')[0].appendChild(js);
setTimeout(fn=function() {
try {
hi();
} catch(e) {
alert(e.Description);
setTimeout( 'fn()', 10 );
}
}
, 10 );
void(0);

Whoops. The alert is (a) wrong -- should be e.description, and (b)
only in there for debugging. Ignore it.
 
R

Richard Cornford

On Mar 15, 3:30 pm, "VK" <[email protected]> wrote:
Using a try/catch with a timer seems to work. Do you see
any problems with this?

javascript:
var js=document.createElement('SCRIPT');
js.src='http://localhost/hi.js';
document.getElementsByTagName('HEAD')[0].appendChild(js);
setTimeout(fn=function() {
try {
hi();
} catch(e) {
alert(e.Description);
setTimeout( 'fn()', 10 );
}
}
, 10 );
void(0);
P.S. In the form above the bookmarklet implements i) an
environment checks, ii) full void wrap against occasional
text garbage and iii) local shy namespace so do not pollute
Global beyond the necessity
<a href="javascript:void((function(){
if(window) {
var js=document.createElement('SCRIPT');
js.src='hi.js';
document.getElementsByTagName('HEAD')[0].appendChild(js);
}})())">link</a>
I would like to understand some of this better.

* environment checks - can you explain a bit more?

In order to explain anything it would be necessary to understand it, and
VK is not someone who understands javascript. What he may (and often
does) do is post a story laced with sufficient jargon (or jargon-like
statements) and sufficiently incoherently expressed that people who don't
know the subject may get the impression that he knows what he is talking
about (though will not learn anything) and (assuming he achieves his
usual level of incoherence) people who do understand the subject will not
know what he is talking about at all (else whenever he fails to achieve
sufficient incoherence his story would be subject to technical correction
(as may be observed from the archives of the group)).
is this the if(window) part?

It would make no sense to describe that as "environment checks". All web
browsers provide a property of the global object with the name 'window'
the value of which refers to the global object itself. So - if(window){
.... } - implies resolving the Identifier - window - and then
type-converting the resulting value into a boolean value and using that
boolean value to determine whether to execute the block statement that
follows the - if - test expression. The global object will type-convert
to boolean true and so the block will be executed.

However, in the event that this code was exposed to an environment where
the browser had not provided a 'window' property of the global object
(and no such environments have ever been identified in a web browser
(though non-browser environments such as ASP are not expected to provide
such a property)) the test would not result in the identifier - window -
type-converting to boolean false. Instead the attempt to type-convert the
result of resolving - window - (which would not resolve as no - window -
property of the global object would exist) would result in a runtime
error.

Thus the outcome of the "check" would be either its being passed and the
code in the block executed (the expected outcome in all browser
environments) or a runtime error. Which is effectively the same as the
expected outcome if the test was omitted entirely (the code is executed
and either errors or it does not).

The - if(window){ ... } - is a mystical incantation, and like all good
mystical incarnation structures seen in javascript code it appears
precisely because it is both useless and harmless. The only consequence
of understanding it is that it would then be seen as useless and omitted
entirely.

In general code exposed to an unknown browser environments tests might
verify the availability of the - createElement -, -
getElementsByTagName - and - appendChild - methods actually used by the
code, as they are known not ot exist in all browser environments and so
testing for them may avoid provoking runtime errors that would follow
from their use in such environments (allowing the script to fail to act,
or use fall-back strategies, under its own control). In the context of
bookmarklet/favelet type scripts that level of testing is redundant as
you know the browser environment you are using, and so can predict its
capabilities.
Does it limit the code to IE?

There are no scriptable web browser environments where a property of the
global object with the name - window - does not refer to the global
object, and so no scriptable web browser environments where the body of
the - if - statement will not be executed. And non-web browser
environments do not provide facilities for executing javascript
pseudo-protocol URLs.
* full void wrap - you mean instead of the final void(0), right?
<snip>

VK has a strong, and apparently unshakable, belief in the magical powers
of the javascript - void - operator. As an operator - void - forms part
of an expression, it evaluates its right hand side operand (forcing any
consequential side-effects to happen) and then ensures that the
expression it forms results in the undefined value.

So in your - void(0) - expression the right hand side operand is the
grouped expression - (0) - which evaluates as the number zero, but the
entire expression evaluates as the undefined value.

An expression representing a call to any function (technically, a
CallExpression) evaluates as the value returned from the function call.
If the body of a function is exited via a return statement and that
return statement specifies a value to be returned then it is that value
that becomes the value of the entire CallExpression.

In javascript all expressions must evaluate to a value or a Reference,
and so all CallExpressions must evaluate to a value or a Reference, but
not all functions include a return statement, and not all return
statements return explicit values. Javascript reconciles this requirement
for function calls to always result in value by providing a default value
whenever a a call to a function does not explicitly return a value
itself. All function calls that do not explicitly end at a return
statement that returns a value actually return the undefined value
instead.

The anonymous function called inline (- (function(){ ... })() -) does not
include a return statement and so it returns undefined. As a result the
value of the CallExpression is also the undefined value. So using the
CallExpression as the operand of the - void - operator is evaluating the
CallExpression to get the undefined vlaue and then evaluating the -
void - expression to the undefined value:-

void (function(){ ... })())

-where the anonymous function expression does not include any return
statement, has the same value as:-

(function(){ ... })())

- and so will have the same result in any context in which it is used.

Using - void - in that context is just another mystical incantation.
Useless, but again harmless enough not to be weeded out by those not
knowledgeable enough to see its uselessness.

Richard.
 
V

VK

* environment checks - can you explain a bit more? is this the
if(window) part? Does it limit the code to IE?

No - it limits the code to the environment where window host object is
presented and has expected properties.

Richard: the crossing questions from your post and OP's post will be
answered in OP's branch if you don't mind. Then I answer to your only
part in your branch. Also I'm still on St-Pet recovery :), so one
answer only today.

We have to keep in our mind that this particular coding is intended
for a bookmarklet: not a code running on a page, but a code invoked by
choosing an item from Favorites/Bookmarks menu.
That means that at the moment of invocation we have no guarantee of
any kind that user will be viewing an ol' good HTML page. It may be a
PDF file, SVG drawing and God knows what else. It means that the
window host object may be not presented or presented but pointing to
something really weird. It is also good to remember that
document.someMethod() is really a common shortcut for
window.document.someMethod()
It is _not_ a functionality crucial detail but it doesn't harm to add
if you have a few free bytes left. Say try this bookmarklet on Firefox
(so add it first to Bookmarks):
javascript:alert(window.document.body)
Try it on any HTML page. OK, now try it on say
http://www.croczilla.com/svg/samples/butterfly/butterfly.svg
 
R

RobG

No - it limits the code to the environment where window host object is
presented and has expected properties.

It limits execution only in that it will produce an error earlier, it
will not stop an error from occuring. Therefore the test (as
explained by Richard) is useless.

To prevent an error it needs something like:

if (typeof window == 'object') {...}

Perhaps the OP should not have disregarded the original 'q' error.

Richard: the crossing questions from your post and OP's post will be
answered in OP's branch if you don't mind. Then I answer to your only
part in your branch. Also I'm still on St-Pet recovery :), so one
answer only today.

We have to keep in our mind that this particular coding is intended
for a bookmarklet: not a code running on a page, but a code invoked by
choosing an item from Favorites/Bookmarks menu.
That means that at the moment of invocation we have no guarantee of
any kind that user will be viewing an ol' good HTML page.

If it might be run an a non-browser environment, it would be wise to
test all host objects and methods before use.
 
R

Richard Cornford

VK said:
No - it limits the code to the environment where window host
object is presented and has expected properties.

In what sense is provoking a runtime error in such an environment
'limiting the code'? What advantage is there is getting a "'window' is
undefined" error better than letting the code run and getting a
"'document' is undefined" error, or a "document.createElement is not a
function" error, or a "document.getElementsByTagName('HEAD')[0] is null
or not an object" error?
Richard: the crossing questions from your post and OP's post
will be answered in OP's branch if you don't mind.

You never answer any of the questions you are asked (just as you will not
be answering the question I have asked you above). All you ever do in
response to being asked questions is post a mass of irrelevant nonsense.
Then I answer to your only part in your branch. Also I'm
still on St-Pet recovery :), so one answer only today.

More hollow promises? Where is that much vaunted superior rounding
function you promised to post over a month ago? If you cannot write it
you could at least confirm that the task was, as everyone suspected from
the outset, beyond your capabilities.
We have to keep in our mind that this particular coding is
intended for a bookmarklet:

And so going to be deliberately activated by a user of more than average
sophistication (that is, not someone who would normally be passively
staring at the contents of a browser window) to achieve some specific
task.
not a code running on a page, but a code invoked by
choosing an item from Favorites/Bookmarks menu.
That means that at the moment of invocation we have no
guarantee of any kind that user will be viewing an ol'
good HTML page.

We can reasonably assume that if the subject document is not a type
amenable to the action of the bookmarklet it is unlikely that a user
sophisticated enough to be using boookmarklets in the first place will
choose to attempt to employ it.
It may be a
PDF file, SVG drawing and God knows what else.

And it will likely error out in such a context, but having it error-out
fractionally earlier is worthless, and the effort needed to prevent it
erroring at all is pointless as there are no consequences following from
its erroring out in an inappropriate environment.
It means that the window host object may be not presented or
presented but pointing to something really weird.

In your - if(window){ ... } - code, if the global object has a window
property that points to "something really weird" then the odds are very
good that the test will be passed, making it non-discriminating of the
"really weird".
It is also good to remember that
document.someMethod() is really a common shortcut for
window.document.someMethod()

Nonsense. The property accessor - window.document.someMethod() - is a
longer and slower alternative to - document.soemMethod() -, as is -
window.window.document.someMethod() -, or -
wnidow.window.window.document.someMethod() - and so on. Being able to do
something inefficiently does not make doing it efficiently a shortcut for
the inefficient alternatives.

And, of course, that is utterly irrelevant to anything that is under
discussion here (you do like to try to distract attention form your
follies by posting irrelevancies, don't you).
It is _not_ a functionality crucial detail but it doesn't harm
to add if you have a few free bytes left.

It is a pointless piece of code that may do no more than result in an
error being thrown fractionally sooner than it would otherwise, will not
discriminate between a window property of the global object referring to
global object and one that refers to "something really weird", and it
will not ensure that the body of the - if - statement is only executed in
HTML DOMs, as the W3C SVG DOM mandates that the ECMAScript global object
be given a - window - property that refers to the global object (so there
are better formal grounds for expecting a - window - property of the
global object in an SVG document than there are in an HTML document).

So that is a "test" that fails to discriminate anything useful (and
particularly the things you have proposed here as 'justification' for
that test) and acts in a way that pointless.
Say try this bookmarklet on Firefox
(so add it first to Bookmarks):
javascript:alert(window.document.body)
Try it on any HTML page. OK, now try it on say
http://www.croczilla.com/svg/samples/butterfly/butterfly.svg

And is the outcome changed by wrapping that code in - if(window){
.... } -? That test would be the better demonstration of the worthless
ness of your - if - statement.

Richard.
 
V

VK

And is the outcome changed by wrapping that code in - if(window){
... } -? That test would be the better demonstration of the worthless
ness of your - if - statement.

Yes, if (window) check is worthless here.
 
R

Richard Cornford

VK said:
Yes, if (window) check is worthless here.

Precisely. The - if - test is worthless in discriminating between HTML
documents and non-HTML documents, is worthless in discriminating between
window references to the global object and window references to
"something really weird" and pointless in general because all it will do
is provoke an exception to be thrown fractionally sooner that it may be
throws otherwise. Thus it is worthless in total. So why did you put it
there in the first place? And why did you say "it limits the code to the
environment where" when asked to explain it?

In truth you did not know why you had put it there, it was a mystical
incantation and its existence only persists because it is broadly
harmless in its context (or at least makes nothing any worse; "it doesn't
harm to add if you have a few free bytes left").
Richard.
 
V

VK

In order to explain anything it would be necessary to understand it,
and VK ...
<snip the rest of the standard preface>

<snip a very detailed but irrelevant explanation of how javascript
treats different values in boolean checks>
However, in the event that this code was exposed to an environment where
the browser had not provided a 'window' property
the attempt to type-convert the result of resolving - window -
would result in a runtime error.

Right. So if (window) check is superfluous and useless here. My
mistake.
VK has a strong, and apparently unshakable, belief in the magical powers
of the javascript - void - operator.

While Mr.Cornford has a strong, and apparently unshakable, belief in
the harmful nature of void. For him worser than void expression can be
only void(expression)
We'll stop right here.
An expression representing a call to any function (technically, a
CallExpression) evaluates as the value returned from the function call.
If the body of a function is exited via a return statement and that
return statement specifies a value to be returned then it is that value
that becomes the value of the entire CallExpression.

You missed the whole idea of (function(){})() usage here - as well as
the shy namespace concept. I don't care of the return value. Think of
HTML page with its own script. If on this page one chooses a
bookmarklet of a kind javascript:var foo='bar'; then where variable
foo goes?
 
B

bweaverusenet

I'm replying to all of you here.

Richard, please help me understand the gist of your posts. Best I can
tell, you are saying that if(window) ... is pointless, but can you
explain the void( ... ) comments maybe a little more succinctly? Best
I can understand so far is that (function(){ ... }()) is superior to
void(function(){ ... }()).

RobG, I think you missed my original point about the 'q' error, that I
understand that it should be defined, but it was not relevant to the
bookmarketlet size limit behavior that I was seeing. Declaring
variables and paying attention to scope is important; no argument
there.

VK, thanks for your help. You got me headed in the right direction and
sparked this conversation that is helping me understand some of the
finer points a bit better.

All, thanks for entertaining the questions. Here's the code at this
point. It seems to work, but do you see any problems with it?
javascript:
(function() {
var js=document.createElement("SCRIPT");
js.src="http://localhost/hi.js";
document.getElementsByTagName("HEAD")[0].appendChild(js);
setTimeout(fn=function() {
try {
hi();
} catch(e) {
setTimeout( "fn()", 10 );
}
}
, 10 );
}
())
 
R

Richard Cornford

I'm replying to all of you here.

Richard, please help me understand the gist of your posts. Best
I can tell, you are saying that if(window) ... is pointless,

Absolutely pointless.
but can you explain the void( ... ) comments maybe a little
more succinctly? Best I can understand so far is that
(function(){ ... }()) is superior to void(function(){ ... }()).

The first is not superior, in itself, it is just sufficient for the task.
When the anonymous function contains no return statement at all (or when
it contains a return statement that does not specify any other value) the
value of the expression - (function(){ .... })() - is the undefined
value. The value of the expression - void(function(){ ... }()) - is the
undefined value. It is in fact the point of the void operator that it
evaluates its operand and then results in the undefined value. However,
if you can guarantee that the expression that is the operand of void will
evaluate to the undefined value (as you can when the expression is a call
to an anonymous function expression where the function contains no return
statement) it is pointless to make it the subject of a void operation.

It is not a characteristic of programmers that they write code that
performs operations that they know to be pointless at the point of
writing them. Doing so would be irrational.
RobG, I think you missed my original point about the 'q'
error, that I understand that it should be defined, but it
was not relevant to the bookmarketlet size limit behavior
that I was seeing.

Maybe not, but the error that followed form the undeclared - q - is the
same error that must follow from the undeclared - window - in
environments that do not provide a - window - property of the global
object natively.
Declaring variables and paying attention to scope is important;
no argument there.

VK, thanks for your help. You got me headed in the right direction
and sparked this conversation that is helping me understand some
of the finer points a bit better.

VK is very good at providing examples of things that should not be done.
It is just a pity he does it so relentlessly.
All, thanks for entertaining the questions. Here's the code at this
point. It seems to work, but do you see any problems with it?
javascript:
(function() {
var js=document.createElement("SCRIPT");
js.src="http://localhost/hi.js";
document.getElementsByTagName("HEAD")[0].appendChild(js);
setTimeout(fn=function() {
try {
hi();
} catch(e) {
setTimeout( "fn()", 10 );
}
}
, 10 );
}
())

If you are not willing to put the call to your - hi - function at the end
of your - hi.js - file (which is probably the best way of guaranteeing
that the function is defined prior to the first call to it) then you
could avoid the try-catch with a typeof test (typeof dos not error if its
subject is undeclared):-

javascript:
(function() {
function f(){
if(typeof hi == 'function'){
hi();
}else{
setTiemout(f,10);
}
}
var js=document.createElement("SCRIPT");
js.src="http://localhost/hi.js";
document.getElementsByTagName("HEAD")[0].appendChild(js);
f();
}());

Though 10 milliseconds is a very short interval for a setTiemout.
Remembers that humans tend to take about 400 milliseconds to react to
anything, so a timeout of 100 milliseconds would be plenty fast enough.

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top