Why does this work?

P

Paul Lautman

Normally I ask why things DON'T work!!

However, according to what I have read at
http://subsimple.com/bookmarklets/rules.asp the bookmarklet:

javascript:q = prompt("Enter destination or leave blank for main maps
page.",
"");location='http://maps.google.co.uk/'+((q.length)?'maps?f=d&hl=en&saddr=po4+8ej&daddr='+escape(q.replace(/
/g, "+"))+'&om=1':'')

should cause a problem because the assignment of the prompt to q is not
voided and the script is not encapsulated in a function.

So why am I not getting an error? Is it because the location assignment is
taking precedent?

TIA
Regards
Paul
 
V

VK

Paul said:
Normally I ask why things DON'T work!!

However, according to what I have read at
http://subsimple.com/bookmarklets/rules.asp the bookmarklet:

javascript:q = prompt("Enter destination or leave blank for main maps
page.",
"");location='http://maps.google.co.uk/'+((q.length)?'maps?f=d&hl=en&saddr=po4+8ej&daddr='+escape(q.replace(/
/g, "+"))+'&om=1':'')

should cause a problem because the assignment of the prompt to q is not
voided and the script is not encapsulated in a function.

So why am I not getting an error? Is it because the location assignment is
taking precedent?

Well, strictly and officially javascript: pseudo-protocol has nothing
to do with bookmarklets: it is the closest relative of document.write
(used after document load). Yet Brendan Eich foresaw some possible
creative usage of this protocol including ill-fated psi-links and
bookmarklets see more at
<http://en.wikipedia.org/wiki/Bookmarklet#History>

That's an introductory blah-blah :) as a comment on that funny
statement in the page you linked:
<q>If a function or an assignment returns a value, which you do not
catch, the bookmarklet will redirect to a new page that shows the
returned value. Silly, I know, but that's what it does. You can
intercept the return value by encapsulating the relevant statements
with void(...).</q>

Indeed, "silly" to see something working in the intended way instead of
the hacked way :)

On your direct question:
As user are lasy and refusing to read any specs by their very nature
:), "extended" javascript: protocol usage is as simplified as
possible. As long as you don't return any value back explicetly (via
return), it presumes that you don't want to use it as a javascript
source for the next page.

In the posted bookmarklet you don't return anything explicetly, so you
are fine. Yet I would suggest to use void operator in your own
bookmarklets - just in case.
 
P

Paul Lautman

VK said:
Well, strictly and officially javascript: pseudo-protocol has nothing
to do with bookmarklets: it is the closest relative of document.write
(used after document load). Yet Brendan Eich foresaw some possible
creative usage of this protocol including ill-fated psi-links and
bookmarklets see more at
<http://en.wikipedia.org/wiki/Bookmarklet#History>

That's an introductory blah-blah :) as a comment on that funny
statement in the page you linked:
<q>If a function or an assignment returns a value, which you do not
catch, the bookmarklet will redirect to a new page that shows the
returned value. Silly, I know, but that's what it does. You can
intercept the return value by encapsulating the relevant statements
with void(...).</q>

Indeed, "silly" to see something working in the intended way instead
of the hacked way :)

On your direct question:
As user are lasy and refusing to read any specs by their very nature
:), "extended" javascript: protocol usage is as simplified as
possible. As long as you don't return any value back explicetly (via
return), it presumes that you don't want to use it as a javascript
source for the next page.

In the posted bookmarklet you don't return anything explicetly, so you
are fine. Yet I would suggest to use void operator in your own
bookmarklets - just in case.

Thank you VK
 
L

Lasse Reichstein Nielsen

Yes. I wouldn't depend on it working in all browsers.
As user are lasy and refusing to read any specs by their very nature
:), "extended" javascript: protocol usage is as simplified as
possible. As long as you don't return any value back explicetly (via
return), it presumes that you don't want to use it as a javascript
source for the next page.

That's not how browsers work.

Change the assignment to, e.g, "locationx" instead of "location", and
see that the page is indeed replaced by the string value of that
assignment, even without a return value.

When following a "javascript:"-link, the browser evaluates the
following statements as if it was the argument of the eval function,
i.e., the result is the value of the last evaluated expression
statement or the value returned by a return statement.

If that value is "undefined", no replacement happens. Otherwise the
result is converted to a string (as by the String function) and a new
page is created with that string value as its source code.

In this case, evaluation of the javascript code had a side effect of
loading another page. In the browsers you have tested, that
replacement was the one to take effect.
In the posted bookmarklet you don't return anything explicetly, so you
are fine. Yet I would suggest to use void operator in your own
bookmarklets - just in case.

I would suggest learning when and how the void operator is applicable
and suitabel. Don't insert it just because you think you have to.
Insert it because you know! Otherwise it's just programming by
coincidence ("it works, but I don't know why", which often means
that there are cases where it fails to work, and you don't know
where to look for them).

/L
 
V

VK

Lasse said:
I would suggest learning when and how the void operator is applicable
and suitabel. Don't insert it just because you think you have to.

Very true.
In this case (psi-links and bookmarklets) it was suggested and
illustrated by Brendan Eich, so I see it as a valid use (which is it
actually). There is always a possibility of course that Brendan Eich
doesn't know how to program in JavaScript properly - sometimes even
original inventors cannot deal with evolutionated versions of their
inventions. I don't see it as the case here though. :)
 
T

Thomas 'PointedEars' Lahn

Paul said:
However, according to what I have read at
http://subsimple.com/bookmarklets/rules.asp the bookmarklet:

javascript:q = prompt("Enter destination or leave blank for main maps
page.",
"");location='http://maps.google.co.uk/'+((q.length)?'maps?f=d&hl=en&saddr=po4+8ej&daddr='+escape(q.replace(/
/g, "+"))+'&om=1':'')

should cause a problem because the assignment of the prompt to q is not
voided and the script is not encapsulated in a function.

So why am I not getting an error? Is it because the location assignment is
taking precedent?

First of all, ignore VK's fiction.

Second, you do not get an error because the source code is syntactically
correct.

Third, the common implementation of the proprietary `javascript:'
pseudo-protocol is that only the result of the last evaluation is used to
create a HTML document with the evaluated value as content. Since the last
statement is an assignment to the host-defined `location' property of the
Global Object, as a peculiarity of HTML UA's Application Object Model
(AOM), the Global Object and the execution context the script code runs in
ceases to exist (and is recreated later). Hence no temporary document is
generated from that assigned value.

Simply remove the `location=' assignment (or change it to `locationx' or any
other property that does not affect navigation, as Lasse suggested) and
observe that the value assigned to `q' (or `locationx') is used to generate
that temporary document.


PointedEars
 
V

VK

Lasse said:
Change the assignment to, e.g, "locationx" instead of "location", and
see that the page is indeed replaced by the string value of that
assignment, even without a return value.

When following a "javascript:"-link, the browser evaluates the
following statements as if it was the argument of the eval function,
i.e., the result is the value of the last evaluated expression
statement or the value returned by a return statement.

That's a nice observation, good to know. I guess I always was just too
accurate with using javascript: protocol to notice that :)

In the original introduction of javascript: Brendan Eich just says:
<q>If the value of the expression following a javascript: URL prefix
evaluates to undefined, no new document is loaded. If the expression
evaluates to a defined type, the value is converted to a string that
specifies the source of the document to load.</a>

But the behavior you pointed to is consistent at least down to NN4.5 -
and it doesn't really anyhow contradict to the quote above (just could
be clearer in the mechanics, but this can be said about way many too
many specs :)

But now it is also crearer why Mr. Eich was suggesting to use void()
wrapper for the code: exactly for the situations when you can still get
a return value without returning anything explicetly - just because of
say script error in the code to evaluate.
 

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

Members online

No members online now.

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,238
Latest member
Top CryptoPodcasts

Latest Threads

Top