reptile7's JavaScript blog
Wednesday, July 23, 2014
The Quote Parade, Part 1
Blog Entry #327

In today's post we'll begin a tour of some or all of the five "New Array Text Pages" scripts offered by the Scripts that Display Text sector of the Java Goodies JavaScript Repository. Authored by Jenson Crawford in late 1998, the New Array Text Pages scripts are united by a common feature: each script uses a constructor function-created Object object to organize content of some sort.

No demos are provided for the New Array Text Pages scripts. An package holding the scripts may be downloaded here - "ETU" stands for "Easy to Use", BTW. The package contains the following files:
(1) CookieQuotes.html
(2) QuoteOfTheDay.html
(3) RandomLinks.html
(4) RandomQuotes.html
(5) TODGreeting.html
We accordingly kick off our tour with a detailed deconstruction of the CookieQuotes.html script.

Upon repeated visits to the CookieQuotes.html page, the CookieQuotes.html script displays a sequence of quotes, one quote per visit, via an integer index that is stored and accessed as the value of a cookie - or would do that, if the cookie were given a suitable expires date.

The script begins by arraying a set of quote strings.

function buildArray( ) { var a = buildArray.arguments; for (i = 0; i < a.length; i++) { this[i] = a[i]; } this.length = a.length; }

var quoteList = new buildArray( "Back Up My Hard Drive? How do I Put it in Reverse?", "What we have here is a failure to assimilate.<br>[Cool Hand Locutus]", "I just got lost in thought. It was unfamiliar territory.", /* ...11 other quotes... */ "A polar bear is a rectangular bear after a coordinate transform.");

Its name notwithstanding, the buildArray( ) constructor function does not create an Array object but rather an Object object, as though we had coded:

var quoteList = new Object( );
quoteList[0] = "Back Up My Hard Drive? How do I Put it in Reverse?";
quoteList[1] = "What we have here is a failure to assimilate.<br>[Cool Hand Locutus]";
quoteList[14] = "A polar bear is a rectangular bear after a coordinate transform.";
quoteList.length = 15;

functionObject.arguments references have been deprecated: for the a declaration, the arguments object should stand on its own.

var a = arguments;

Mozilla's current arguments page is here.

• For the quoteList object, the 0, 1, ... 14 property names are in fact strings (and not numbers).

Next, the script action moves to a document.write( ) command

document.write(quote( ));

that calls a quote( ) function. The quote( ) function first calls a getCookie( ) function and passes thereto an ETUQuoteCount string.

function quote( ) { i = getCookie("ETUQuoteCount"); ... }

As you might guess, the getCookie( ) function

function getCookie(name) { var search = name + "="; if (document.cookie.length > 0) { offset = document.cookie.indexOf(search); if (offset != -1) { offset += search.length; end = document.cookie.indexOf(";", offset); if (end == -1) end = document.cookie.length; return unescape(document.cookie.substring(offset, end)); } } }

trawls through the CookieQuotes.html document.cookie string in search of a cookie whose name is ETUQuoteCount. (The user's browser could have previously picked up any number of domain- and path-matching cookies at the site hosting the CookieQuotes.html page, but as long as none of those cookies is named ETUQuoteCount, we're OK.)

The getCookie( ) function gives the ETUQuoteCount string a name identifier and appends thereto an = character; the ETUQuoteCount= string is given a search identifier.

If there are any cookies associated with the CookieQuotes.html document, then the getCookie( ) function tries to find search in the document.cookie string; the return for that search is assigned to an offset variable. If the search is successful, i.e., if 0offset, then offset is increased by search.length (14) so that it indexes the first character of the ETUQuoteCount cookie's value.

Subsequently the getCookie( ) function looks for the first post-offset semicolon.
(A) If the ETUQuoteCount cookie's value is immediately followed by a semicolon, meaning that one or more cookies follow the ETUQuoteCount cookie in the document.cookie string, then the semicolon index is assigned to an end variable.
(B) If the ETUQuoteCount cookie's value is not followed by a semicolon, meaning that the ETUQuoteCount cookie is the last cookie in the document.cookie string, then end is set to document.cookie.length.

Finally, the offsetend cookie value is extracted, unescape( )d, and returned to the quote( ) function, which gives it an i identifier.

The unescape( ) and escape( ) (vide infra) functions are both deprecated; more importantly, the script's use of these functions is wholly unnecessary - more on this later.

The offset != -1 if condition returns false for a first-time visit to the CookieQuotes.html page. However, there's no else clause to handle the offset == -1 situation: in this case undefined is returned to the quote( ) function.

Getting back to the quote( ) function, an if...else statement
(a) sets i to 0 or
(b) converts i from a numeric string to a bona fide number
depending on whether i is or is not equal to null.

if (i == null) i = 0;
else i = parseInt(i);

• The if clause was meant to flag a first-time visit; fortunately, undefined == null does return true.

• Mozilla exhorts authors to always specify a radix argument when using the parseInt( ) function.

i = parseInt(i, 10);

Alternatively, the string-to-number conversion can be carried out via the Number( ) function.

The i integer is then moduloed by quoteList.length.

i = i % quoteList.length;

Geek Gumbo has written up a really good modulus operator page that notes:
What if the divisor is bigger than the dividend? Then the value of the modulo is the same as the dividend.
12 % 16 = 12
Didn't know that, I have to confess. It follows that i % quoteList.length gives 0 for a first-time visit.

The modulo remainder, which will serve as a display index for the quote we put on the page, is for the moment assigned to i. The i value is
(i) copied to a j variable and then
(ii) increased by one
via a postfix incrementation.

j = i++;

We're ready to set a cookie that will keep track of how many quotes the user has seen. Toward this end, the quote( ) function calls on a setCookie( ) function that adds an ETUQuoteCount=i cookie to the document.cookie string; i is escape( )d before it is incorporated into the cookie.

setCookie("ETUQuoteCount", i);

function setCookie(name, value) { document.cookie = name + "=" + escape(value); }

The quote( ) function concludes by mapping j onto the corresponding quoteList quote and returning quoteList[j]

return quoteList[j];

to the document.write(quote( )); command, which writes quoteList[j] to the page.

We'll briefly recap in the following entry and then see if we can improve the script a bit.

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)