Subversion Repositories FAQs

Compare Revisions

Last modification

Ignore whitespace Rev 1 → Rev HEAD

/trunk/cljs/auto-poster.pl
0,0 → 1,354
#!/usr/bin/perl
 
####################################################################
# comp.lang.javascript FAQ - Daily sendout to Usenet based upon #
# XML feed in defined format. #
#------------------------------------------------------------------#
# Message headers can only contain 7bit ASCII chars (RFC2822). #
# I'm using ISO-8859-1 in the message bodies for maximum #
# compatibility with all kinds of newsreaders. #
#------------------------------------------------------------------#
# Code by Bart Van der Donck - www.dotinternet.be - Aug 2006. #
#------------------------------------------------------------------#
# This program is free software released under the GNU/GPL; you #
# can redistribute it and/or modify it under the GNU/GPL terms. #
####################################################################
 
####################################################################
# Load modules & locale for English formatted date. #
# These modules should be present in default Perl 5.6+ installs. #
####################################################################
 
use strict;
use warnings;
use POSIX;
use Net::NNTP;
use LWP::UserAgent;
use HTML::Parser;
use HTML::Entities;
use XML::Parser;
use XML::Simple;
 
setlocale(LC_ALL, 'English (UK)');
 
 
####################################################################
# Configuration area. #
####################################################################
 
# account on news server (leave both blanco if no authentication
# is needed)
my $account = 'javas...@dotinternet.be';
my $password = 'secret';
 
# server and newsgroup
my $server = 'news.sunsite.dk';
my $ng = 'comp.lang.javascript';
 
# sender data
my $sendername = 'FAQ server';
my $senderaddress = 'javas...@dotinternet.be';
 
# where is the XML file to load ?
my $xml_file = 'http://www.jibbering.com/faq/index.xml';
 
# footer of the message
my $footer = <<FOOT
--
Postings as these are automatically sent once a day. Their goal
is to answer repeated questions, and to offer the content to the
community for continuous evaluation/improvement. The complete
comp.lang.javascript FAQ is at http://www.jibbering.com/faq/.
The FAQ workers are a group of volunteers.
FOOT
;
 
# where is writable file that keeps track of the counter
# (path must be absolute or relative to this script)
my $writablefile = 'entry2post.cnt';
my $fc;
 
# misc. header settings, these should be left untouched
my $mime_version = '1.0';
my $charset = 'iso-8859-1';
my $content_type = 'text/plain';
my $trans_enc = '8bit';
my $organization = 'comp.lang.javascript FAQ workers';
my $date = strftime "%a, %d %b %Y %H:%M:%S +0000", gmtime;
 
# which regexes for nice Usenet layout
my %regexes = (
"p" => "\n",
"/p" => "\n",
"em" => "_",
"/em" => "_",
"url" => "\n\n",
"/url" => "\n\n",
"ul" => "\n",
"/ul" => "\n",
"li" => "* ",
"/li" => "",
"moreinfo" => "\n\n",
"/moreinfo" => "\n\n",
"resource" => "\n\n",
"/resource" => "\n\n",
"icode" => "`` ",
"/icode" => " ''",
"code" => "\n\n",
"/code" => "\n\n",
);
 
# run options
my $sendout = 1; # 1 = send to Usenet, 0 = print to screen.
my $printnrs = 0; # 1 = include FAQ chapter & entry nr,
# 0 = exclude. CAUTION! as it takes this
# data not from XML feed but from this
# porgram's internal counting.
 
####################################################################
# Get XML file. #
####################################################################
 
# fetch XML file
my $ua = new LWP::UserAgent;
$ua->agent("AgentName/0.1 " . $ua->agent);
my $req = new HTTP::Request GET => $xml_file;
$req->content_type('text/xml');
my $res = $ua->request($req);
unless ($res->is_success) {
die "Error: couldn't get $xml_file: $!\n";
}
 
# is XML file well-formed ?
my $xml = $res->content;
eval { XML::Parser->new(ErrorContext=>1)->parse($xml) };
if ($@) {
die "Error: $xml_file is not well-formed XML\n";
}
 
####################################################################
# Regexes on XML feed. #
####################################################################
 
# regex the mentionned tags to Usenet layout format
while ( my ($key, $val) = each %regexes ) {
$xml =~ s/<\Q$key\E(?:[^>'"]*|(['"]).*?\1)*>/$val/gsi;
}
 
# regex out all other tags except CONTENTS, CONTENT, FAQ, TITLE
my $result_xml = '';
my @report_tags = qw(content contents faq title);
HTML::Parser->new(api_version => 3,
start_h => [\&tag, 'tokenpos, text'],
process_h => ['', ''],
comment_h => ['', ''],
declaration_h => [\&decl, 'tagname, text'],
default_h => [\&text, 'text'],
report_tags => \@report_tags,
)
->parse( $xml );
 
# check for well-formedness
eval { XML::Parser->new(ErrorContext=>1)->parse($result_xml) };
if ($@) {
die "Error: XML file not well-formed after Usenet format regexes";
}
 
####################################################################
# Decide which subject/body part we need. #
####################################################################
 
# tie xml to vars
my $xml_ref = XMLin($result_xml, ForceArray => 1);
 
# load counter file
open my $F, '<', $writablefile
|| die "Error: can't open $writablefile: $!";
flock($F, 1) || die "Error: can't get LOCK_SH on $writablefile: $!";
$fc = $_ while <$F>;
close $F || die "Error: can't close $writablefile: $!";
my ($chap, $cnt) = split /\|/, $fc;
 
# lookup subject/body in hashed structure
unless ($xml_ref->{CONTENTS}->[0]
->{CONTENT}->[$chap]
->{CONTENT}->[$cnt]) {
save4next ( $chap, $cnt );
die "Error: FAQ entry ".($chap+1).".".($cnt+1).". doesn't exist";
}
 
my $part = $xml_ref->{CONTENTS}->[0]
->{CONTENT}->[$chap]
->{CONTENT}->[$cnt];
my %hash_deref = %$part;
my $subject = $hash_deref{TITLE};
my $body = $hash_deref{content};
 
 
####################################################################
# Regexes on $body and $subject and compile final $message #
####################################################################
 
# decode num/char HTML entities in subject and in message
$subject = HTML::Entities::decode($subject);
$body = HTML::Entities::decode($body);
 
# take care of Euro sign towards ISO-8859-1, just in case
s/€/Euro/ig for ($body, $subject);
 
# don't allow EOLs and successive blancs in subject lines
$subject =~ s/\n/ /g;
$subject =~ s/\s+/ /g;
 
# remove 1-6 initial blanks from begin + all from end
my @splitbody = split /\n/, $body;
for (@splitbody) {
s/\s+$//;
s/^\s{1,6}//;
s/^\s+http:/http:/g; # issue with leading http on line
}
$body = join "\n", @splitbody;
 
# remove more than three EOLs
$body =~ s/\n{3,}/\n\n/gs;
 
# remove all EOLs from begin and end of $body
for ($body) {
s/^\n+//;
s/\n+$//;
}
 
# should we add the FAQ entry chapter/number ? (own counting)
if ($printnrs==1) {
$subject = 'FAQ ' . $chap . '.' . $cnt . '. - ' . $subject ;
}
else {
$subject = 'FAQ - ' . $subject;
}
 
# format full body
$body = "\x2D" x 71 . "\n" . $subject . "\n" . "\x2D" x 71
. "\n" x 2 . $body . "\n" x 3 . $footer;
 
# remove lines that consist only of 1 dot
$body =~ s/\n\.\n/\n/g;
 
# compute & store which entry is to send next time
save4next ( $chap, $cnt );
 
# compile complete message
my $message = <<EOM;
Reply-To: "$sendername" <$senderaddress>
From: "$sendername" <$senderaddress>
Date: $date
Newsgroups: $ng
Subject: $subject
Organization: $organization
Mime-Version: $mime_version
Content-Type: $content_type; charset="$charset"
Content-Transfer-Encoding: $trans_enc\n
$body
EOM
 
# should we send the message to Usenet or print to screen ?
if ($sendout != 1) {
print $message;
exit;
}
 
 
####################################################################
# Fire off the message. #
####################################################################
 
# do some final checks
if ( !$message || $message eq '' || !$body || $body eq ''
|| !$subject || $subject eq '') {
die "Error: didn't send message due to malformed data";
}
 
# send action (heavy error checking)
my $nntp = Net::NNTP->new( $server )
|| die "Error: can't connect to $server: $!\n";
 
$nntp->authinfo( $account, $password )
|| die "Error: Net::NNTP->authinfo() failed: $!\n"
if ( defined $account && defined $password
&& $account ne '' && $password ne '');
 
$nntp->postok() || die "Error: $server said: not allowed to post\n";
 
$nntp->post( $message )
|| die "Error: can't send message: $!\n";
$nntp->quit;
 
 
####################################################################
# HTML::Parser and $chap/$cnt counting routines. #
####################################################################
 
sub tag {
my ($pos, $text) = @_;
if (@$pos >= 4) {
my ($k_offset, $k_len, $v_offset, $v_len) = @{$pos}[-4 .. -1];
my $next_attr = $v_offset?$v_offset+$v_len:$k_offset+$k_len;
my $edited;
while (@$pos >= 4) {
($k_offset, $k_len, $v_offset, $v_len) = splice @$pos, -4;
$next_attr = $k_offset;
}
$text =~ s/^(<\w+)\s+>$/$1>/ if $edited;
}
$result_xml.=$text;
}
 
sub decl {
my $type = shift;
$result_xml.=shift if $type eq 'doctype';
}
 
sub text {
$result_xml.= shift;
}
 
sub save4next {
my ($ch, $cn) = @_;
 
# next entry in same chapter exists ?
if ($xml_ref->{CONTENTS}->[0]
->{CONTENT}->[$ch]
->{CONTENT}->[$cn+1]) {
writefile( $ch . '|' . ($cn+1) );
return
}
 
# first entry in next chapter exists ?
if ($xml_ref->{CONTENTS}->[0]
->{CONTENT}->[$ch+1]
->{CONTENT}->[0]) {
writefile( ($ch+1).'|0' );
return
}
 
# reset entries if we're at the last entry of the last chapter
if ($xml_ref->{CONTENTS}->[0]
->{CONTENT}->[1]
->{CONTENT}->[0]) {
writefile( '1|0' );
return
}
 
# last resort: no entry found => reset counter and die
writefile( '1|0' );
die "Error: couldn't find next entry for FAQ ".($ch+1).".".($cn+1)
."; next time I'll take the first entry again";
}
 
sub writefile {
open WR, '>', $writablefile
|| die "Error: can't open $writablefile: $!";
print WR shift;
close WR || die "Error: can't close $writablefile: $!";
}
 
__END__
/trunk/cljs/faq_notes/cookies.html
0,0 → 1,120
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en"><head><title>Cookies</title>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<link href="../faq.css" rel="stylesheet" type="text/css">
<link href="faq_notes.css" rel="stylesheet" type="text/css">
</head>
<body>
 
<h1><a name="cookies" id="cookies">Cookies</a></h1>
 
<ul>
<li><a href="#proxIs">Privacy filters on proxies</a></li>
</ul>
 
<h2><a name="proxIs" id="proxIs">Privacy filters on proxies</a></h2>
 
<p id="proxIs_1">
<a href="http://www.w3schools.com/js/js_cookies.asp">The page
referenced</a> from <a href="http://jibbering.com/faq/#FAQ4_4">section 4.4 of
the FAQ</a> describes a generally sound strategy for using cookies but suffers from
an additional issue relating to &quot;privacy&quot; filters employed by content
inserting/re-writing proxies.
</p>
 
<p id="proxIs_2">
The problem is that some of these filters identify the character sequence
&quot;cookie&quot; within Javascript source code and replace it with an
alternative string. <a href="http://groups.google.com/groups?threadm=41ebaba2.0306240406.1fdff5ef%40posting.google.com">
A c.l.j. thread describing an occurrence of this problem</a> had
&quot;cookie&quot; replaced by &quot;ignore&quot; by ZoneAlarm, and
Proximatron has a similar filter available (but not active) by default.
</p>
 
<p id="proxIs_3">
The effect of changing occurrences of <code>document.cookie</code>
into <code>document.ignore</code> within source code is that attempts
to write to the property just result in a new string property being
assigned to the document object, but no cookie is created. And reading
from the property returns the same string, or an undefined value
if nothing has yet been written to the property.
</p>
 
<p id="proxIs_4">
The problem with the irt.org code is that the <code>Get_Cookie</code>
and <code>Set_Cookie</code> functions are
not written with a consideration that <code>document.cookie</code> may
not refer to a string.
</p>
 
<p id="proxIs_5">
<code>Get_Cookie</code> will error if &quot;cookie&quot; has been replaced with
&quot;ignore&quot; because it treats the <code>document.cookie</code>
value as if it was a string. But changing that one function so that it
does not attempt to read <code>document.cookie</code> if the value is
not a string may prevent the error but would still undermine that strategy used.
</p>
 
<p id="proxIs_6">
However, the problem can be completely avoided by wrapping the content
of the <code>Get_Cookie</code> and <code>Set_Cookie</code> functions
in <code>typeof</code> tests and only executing the rest of the
function if <code>typeof</code> returns <code>&quot;string&quot;</code>.
</p>
 
 
<pre id="proxIs_ex1">
function Get_Cookie(name) {
if(typeof document.cookie == &quot;string&quot;){
var start = document.cookie.indexOf(name+&quot;=&quot;);
var len = start+name.length+1;
if ((!start)&amp;&amp;
(name != document.cookie.substring(0,name.length))){
return null;
}
if (start == -1) return null;
var end = document.cookie.indexOf(&quot;;&quot;,len);
if (end == -1) end = document.cookie.length;
return unescape(document.cookie.substring(len,end));
}else{
<span class="commentJS">/* document.cookie is not a string so return an
empty string. When tested this will type-convert to
boolean false (accurately) giving the impression that
client-side cookies are not available on this system:-
*/</span>
return &quot;&quot;;
}
}
 
function Set_Cookie(name,value,expires,path,domain,secure) {
if(typeof document.cookie == &quot;string&quot;){
document.cookie = name + &quot;=&quot; +escape(value) +
( (expires) ? &quot;;expires=&quot; + expires.toGMTString() : &quot;&quot;) +
( (path) ? &quot;;path=&quot; + path : &quot;&quot;) +
( (domain) ? &quot;;domain=&quot; + domain : &quot;&quot;) +
( (secure) ? &quot;;secure&quot; : &quot;&quot;);
}<span class="commentJS">//else document.cookie is not a string so do not write to it.</span>
}
 
function Delete_Cookie(name,path,domain) {
if (Get_Cookie(name)) document.cookie = name + &quot;=&quot; +
( (path) ? &quot;;path=&quot; + path : &quot;&quot;) +
( (domain) ? &quot;;domain=&quot; + domain : &quot;&quot;) +
&quot;;expires=Thu, 01-Jan-70 00:00:01 GMT&quot;;
}
}
</pre>
 
<p id="proxIs_7">
Cookie reading and writing is unlikely to be done sufficiently often that
the extra overhead of the tests will impact on the performance of
the resulting script.
</p>
 
<p id="rToc">
<a href="faq_notes.html#toc">comp.lang.javascript FAQ notes T.O.C.</a>
</p>
 
 
</body>
</html>
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/faq_notes/contributors.html
===================================================================
--- trunk/cljs/faq_notes/contributors.html (nonexistent)
+++ trunk/cljs/faq_notes/contributors.html (revision 45)
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en"><head><title>Notes on the comp.lang.javascript FAQ</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<link href="../faq.css" rel="stylesheet" type="text/css">
+<link href="faq_notes.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+.nameList, .nameList UL {
+ list-style-type:none;
+}
+</style>
+</head>
+<body>
+
+<h1>Contributors</h1>
+<!-- listed by Date -->
+<h2>Editors:</h2>
+<ul class="nameList">
+ <li><span class="person">Jim Ley</span>. - Jan 2004</li>
+ <li><span class="person">Richard Cornford</span>. Jan 2004 - </li>
+</ul>
+<!-- Alphabetical list by surname or username if not an individual's name -->
+<h2>Contributors:</h2>
+<ul class="nameList">
+ <li><span class="person">Richard Cornford</span>:
+ <ul>
+ <li>2 Author - Posting Questions and replies to comp.lang.javascript</li>
+ <li>4.4.1 Author - Privacy filters on proxies</li>
+ <li>4.13.1 Author - Referencing Forms and Form Controls</li>
+ <li>4.15.1 Author - An Alternative DynWrite function</li>
+ <li>4.21.1 Author - Javascript Type-Conversion</li>
+ <li>4.26.1 Author - Browser Detecting (and what to do Instead)</li>
+ <li>4.39.1 Author - Javascript Square Bracket Notation</li>
+ <li>Misc 2 Author - Javascript Closures</li>
+ <li>Misc 3 Author - How to Include Scripts in HTML Documents</li>
+ </ul>
+ </li>
+ <li><span class="person">Martin Honnen</span>:
+ <ul>
+ <li>Misc 2 Suggestions and corrections</li>
+ </ul>
+ </li>
+ <li><span class="person">Jim Ley</span>:
+ <ul>
+ <li>Author - The comp.lang.javascript FAQ version 7.9</li>
+ </ul>
+ </li>
+ <li><span class="person">Lasse Reichstein Nielsen</span>:
+ <ul>
+ <li>4.13.1 Suggestions of content</li>
+ <li>4.39.1 Technical corrections</li>
+ <li>Misc 2 Definition of Closure</li>
+ </ul>
+ </li>
+ <li><span class="person">Michael Winter</span>:
+ <ul>
+ <li>FAQ General suggestions and corrections</li>
+ </ul>
+ </li>
+ <li><span class="person">Yann-Erwan Perio (Yep)</span>:
+ <ul>
+ <li>4.39.1 Code testing and suggestions</li>
+ <li>Misc 2 Suggestions and corrections</li>
+ </ul>
+ </li>
+ <li><span class="person">Mike Scirocco</span>:
+ <ul>
+ <li>Misc 2 Corrections</li>
+ </ul>
+ </li>
+ <li><span class="person">Dr John Stockton</span>:
+ <ul>
+ <li>2 Additional material, suggestions and corrections</li>
+ <li>4.15.1 Code testing and suggestions</li>
+ <li>4.21.1 Regular expression examples and additional suggestions</li>
+ <li>4.26.1 Suggestions and corrections</li>
+ <li>4.39.1 Suggestions and corrections</li>
+ <li>Misc 2 Suggestions and corrections</li>
+ </ul>
+ </li>
+ <li><span class="person">Randy Webb (HikksNotAtHome)</span>:
+ <ul>
+ <li>4.13.1 Suggestions of content and technical corrections</li>
+ <li>4.15.1 The first getElementById emulation for IE 4 listed</li>
+ </ul>
+ </li>
+</ul>
+
+<p>
+<a href="faq_notes.html#toc">comp.lang.javascript FAQ notes T.O.C.</a>
+</p>
+
+</body>
+</html>
\ No newline at end of file
/trunk/cljs/faq_notes/contributors.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/faq_notes/faqNotes.zip
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/cljs/faq_notes/faqNotes.zip
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/cljs/faq_notes/square_brackets.html
===================================================================
--- trunk/cljs/faq_notes/square_brackets.html (nonexistent)
+++ trunk/cljs/faq_notes/square_brackets.html (revision 45)
@@ -0,0 +1,369 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en"><head><title>Square Bracket Notation</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<link href="../faq.css" rel="stylesheet" type="text/css">
+<link href="faq_notes.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+<h1>Javascript Square Bracket Notation</h1>
+<ul>
+ <li><a href="#intro">Introduction</a></li>
+ <li><a href="#sBs">Square Bracket Syntax</a></li>
+ <li><a href="#vId">String Variables as Identifiers</a></li>
+ <li><a href="#eId">String Expressions as Identifiers</a></li>
+ <li><a href="#aVa">Global Variable access with the Square Bracket Notation</a></li>
+ <li><a href="#illc">Illegal characters in Identifier-strings</a></li>
+</ul>
+<h2><a name="intro" id="intro">Introduction</a></h2>
+
+<p id="intro_1">To be useful javascript needs to be able to access the properties of
+objects. It is impossible to learn javascript without understanding the
+dot notation that is normally used to access the properties of objects.
+</p>
+
+<p id="intro_2">Javascript also offers an alternative property accessor notation
+using square brackets in a way that is similar to the way in which the
+indexed members of an Array are accessed, except that a string is used
+between the square brackets. This alternative notation is extremely
+powerful and useful but gets very little coverage in most books on
+javascript and that seems to leave novice javascript programmers
+unaware that they even have this option.</p>
+
+<p id="intro_3">The coverage in javascript books can be very poor. Looking back at
+some of the books that I first used to learn javascript, one devotes
+exactly one paragraph to property accessors and another actually states
+that the square bracket notation can only be used with integer indexes
+to access Arrays and array-like structures.</p>
+
+<p id="intro_4">With an understanding of dot notation and few clues that an
+alternative exists, novice (and a few surprisingly experienced)
+javascript programmers often turn to the <code>eval</code> function,
+constructing a string that represents a dot notation accessor
+(frequently retrieving the property names from javascript variables)
+and then passing it to the <code>eval</code> function in order to
+access the object property that it refers to. The <code>eval</code>
+function is just not needed to perform this type of property access
+and it is a relatively inefficient way of doing so (plus, some embedded
+browsers lack the resources to implement an <code>eval</code> function).
+</p>
+
+<h2><a name="sBs" id="sBs">Square Bracket Syntax</a></h2>
+<p id="sBs_1">If you can access the property of an object using dot
+notation, such as:-</p>
+
+<pre id="sBs_ex1">document.body</pre>
+
+<p id="sBs_2">- you can also use the square bracket notation:-</p>
+
+<pre id="sBs_ex2">document['body']</pre>
+
+<p id="sBs_3">- in which the dot and the identifier to the right of the dot are
+replaced with a set of square brackets containing a string that
+represents the identifier that was to the right of the dot.</p>
+
+<p id="sBs_4">The Property Accessors section of javascript language specification
+(ECMA 262) makes it clear that the dot notation and the square bracket
+notation are parallel ways of accessing the properties of objects.</p>
+
+<blockquote cite="http://www.ecma-international.org/publications/files/ecma-st/Ecma-262.pdf">
+<dl>
+ <dt>ECMA 262 3rd Edition. Section 11.2.1 Property Accessors</dt>
+ <dd>
+ Properties are accessed by name, using either the dot notation:
+<pre >
+MemberExpression.Identifier
+CallExpression.Identifier
+</pre>
+ or the bracket notation:
+<pre>
+MemberExpression[ Expression ]
+CallExpression[ Expression ]
+</pre>
+ The dot notation is explained by the following syntactic conversion:
+ <pre>MemberExpression.Identifier</pre>
+ is identical in its behaviour to
+ <pre>MemberExpression[ &lt;identifier-string&gt; ]</pre>
+ and similarly
+ <pre>CallExpression.Identifier</pre>
+ is identical in its behaviour to
+ <pre >CallExpression[ &lt;identifier-string&gt; ]</pre>
+ where <code>&lt;identifier-string&gt;</code> is a string literal
+ containing the same sequence of characters as the Identifier.
+ <dd>
+</dl>
+</blockquote>
+
+<p id="sBs_5">In the following simple <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page:-</p>
+
+<pre id="sBs_ex3">
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;title&gt;&lt;/title&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+ &lt;form name=&quot;formName&quot; action=&quot;#&quot;&gt;
+ &lt;input type=&quot;text&quot; name=&quot;inpName&quot; value=&quot;Example value text&quot;&gt;
+ &lt;/form&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<p id="sBs_6">- which contains a form named <code>&quot;formName&quot;</code> with
+one input element named <code>&quot;inpName&quot;</code>. Various forms
+of dot notation property accessor can be used to reference the
+<code>&quot;value&quot;</code> property of the input element. One of
+the simplest is:-</p>
+
+<pre id="sBs_ex4">
+var stringOfValue = document.formName.inpName.value;
+</pre>
+
+<p id="sBs_7">This dot notation has three dots, so there are three points at which
+the square bracket notation could be used in place of the dot notation
+(these are all equivalent).</p>
+
+<pre id="sBs_ex5">
+var stringOfValue = document[&quot;formName&quot;].inpName.value;
+
+var stringOfValue = document.formName[&quot;inpName&quot;].value;
+
+var stringOfValue = document.formName.inpName[&quot;value&quot;];
+</pre>
+
+<p id="sBs_8">The following combinations are also all equivalent to the original
+dot notation:-</p>
+
+<pre id="sBs_ex6">
+var stringOfValue = document[&quot;formName&quot;].inpName[&quot;value&quot;];
+
+var stringOfValue = document[&quot;formName&quot;][&quot;inpName&quot;].value;
+
+var stringOfValue = document[&quot;formName&quot;][&quot;inpName&quot;][&quot;value&quot;];
+
+var stringOfValue = window[&quot;document&quot;][&quot;formName&quot;][&quot;inpName&quot;][&quot;value&quot;];
+</pre>
+
+<p id="sBs_9">Where the dot notation follows the dot with the identifier for the
+property that is to be accessed, the square bracket notation replaces
+the dot and identifier with square brackets that contain a string that
+represents the identifier for the property (the property name).</p>
+
+<h2><a name="vId" id="vId">String Variables as Identifiers</a></h2>
+
+<p id="vId_1">The string used within the square brackets does not need to be a
+string literal. It can be any expression that results in a string.
+This is where the square bracket notation becomes most useful as the
+expression could be a reference to a string variable that holds the
+property name as its value, or a function call that returns a string,
+or an expression that concatenates two strings, or any combination of
+these.</p>
+
+<p id="vId_2">This means that the identifier needed to access a property does not
+need to be coded into a javascript. Consider the following simple
+function:-</p>
+
+<pre id="vId_ex1">
+function setPropertyToValue(oObj, sPropName, value){
+ oObj[sPropName] = value;
+}
+</pre>
+
+<p id="vId_3">- provided with a reference to an object (<code>oObj</code>), the
+name of a property (<code>sPropName</code>) and a value for that
+property (<code>value</code>), it will set the value of the property
+without needing to know what the name of the property that it is
+setting is. Called as
+<code>setPropertyToValue(document.formName.inpName, &quot;value&quot;, &quot;new value&quot;)</code>
+it will set the value of the field in the example form above to the
+string <code>&quot;new value&quot;</code>. However, called as
+<code>setPropertyToValue(window, &quot;location&quot;, &quot;http://www.google.com&quot;)</code>
+and the same function will navigate a web browser to the URL provided
+as the final parameter. Although this is a forced example you should be
+able to see that the square bracket notation offers considerable power
+and flexibility.</p>
+
+<p id="vId_4">Any variable that holds a string value can be used between the
+square brackets to form a property accessor. Variables that hold
+non-strings will have their value internally type converted into a
+string and that string will be used as the property name. This is not very
+useful, especially if the variables contain references to objects or
+functions, as the returned string is likely to be implementation
+dependent.</p>
+
+<h2><a name="eId" id="eId">String Expressions as Identifiers</a></h2>
+
+<p id="eId_1">The ability to build the string used as the property name can be
+very useful in loops and with dynamically generating web pages (server
+side) that have variable length content. The strings can be the result
+of expressions that concatenate string literals with variables
+(particularly loop counters).</p>
+
+<p id="eId_2">Given the form:-</p>
+
+<pre id="eId_ex1">
+&lt;form name=&quot;formName&quot; action=&quot;#&quot;&gt;
+ &lt;input type=&quot;text&quot; name=&quot;field_1&quot;&gt;
+ &lt;input type=&quot;text&quot; name=&quot;field_2&quot;&gt;
+ &lt;input type=&quot;text&quot; name=&quot;field_3&quot;&gt;
+&lt;/form&gt;
+</pre>
+
+<p id="eId_3">- the following loop will clear the value property of each element
+it turn:-</p>
+
+<pre id="eId_ex2">
+for(var c = 1;c &lt; 4;c++){
+ document.forms[&quot;formName&quot;].elements[&quot;field_&quot;+c].value = &quot;&quot;;
+}
+</pre>
+
+<p id="eId_4">If a server side process had created the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> form with
+<code>n</code> elements, named <code>field_1, field_2 ... field_n</code>
+, then all the server side process would have to do to have the loop
+clear each and every input element would be to change the <code>4</code>
+in the example to the value of <code>n+1</code>.</p>
+
+<p id="eId_5">Concatenation is the most common type of expression used with the
+square bracket notation but any javascript expression could be used.
+A function that returned a string could be used.</p>
+
+<p id="eId_6">In the following (rather contrived) example :-</p>
+
+<pre id="eId_ex3">
+function getRootElName(){
+ if(document.compatMode &amp;&amp; (document.compatMode == &quot;CSS1Compat&quot;)){
+ return &quot;documentElement&quot;;
+ }else{
+ return &quot;body&quot;;
+ }
+}
+
+var verticalScroll = document[getRootElName()].scrollTop;
+</pre>
+<p id="eId_7">- the <code>scrollTop</code> value is read from either the
+<code>document.body</code> or <code>document.documentElement</code>
+depending on the value of <code>document.compatMode</code>. Passing
+strings about is far from the best way of achieving what the code
+above does but there will be circumstances when returning a string
+from a function call for use in a property accessor is potentially
+useful.</p>
+
+<h2><a name="aVa" id="aVa">Global Variable access with the Square Bracket Notation</a></h2>
+
+<p id="aVa_1">The square bracket notation requires that there be some sort of
+object reference to the left of the brackets.</p>
+
+<pre id="aVa_ex1">[&quot;document&quot;] <span class="commentJS">//Array literal, not a Property Accessor!</span></pre>
+
+<p id="aVa_2">-will produce an error if an attempt is made to assign a value to it,
+as it will be treated as an Array literal, if an attempt to read from
+it is made the one element array containing the string within the
+brackets is returned. Global variables are normally referenced by their
+one identifier alone. This would seem to exclude global variables from
+the possibility of being referenced using a string that held their
+identifier name or an expression that built, or returned, their name.
+However, javascript global variables (and global function names for
+that matter) are properties of a global object. Any identifier that
+holds a reference to the global object can be used to the left of the
+square brackets to form a property accessor that refers to a global
+variable.</p>
+
+<p id="aVa_3">In a web browser the global object is the window (or frame) in which
+the script is running. Each window (or frame) object contains a number
+of properties, at least two of which are references to the window
+(global object) itself. These properties are 'window' and 'self'.
+These property names can be used as the identifier to the left of the
+square brackets when referring to global variables. So given a global
+variable defined as:-</p>
+
+<pre id="aVa_ex2">
+var anyName = 0;
+</pre>
+
+<p id="aVa_4">- that global variable can be referenced as:-</p>
+
+<pre id="aVa_ex3">
+window[&quot;anyName&quot;]
+</pre>
+
+<p id="aVa_5">As with any other use of the square bracket notation, the string
+within the brackets can be held in a variable or constructed/returned
+by an expression.</p>
+
+<p id="aVa_6">Code that is executing in the global context, the code within global
+functions (except Object constructors invoked with the <code>new</code>
+keyword) and inline code outside of any functions, could also use the
+<code>this</code> keyword to refer to the global object. The
+<code>this</code> keyword refers to an object depending on the
+execution context. For code executing in the global context
+<code>this</code> is the global object (on a web browser, the window
+object). As a result, the above variable could be referred to as
+<code>this[&quot;anyName&quot;]</code>, but only in code that is
+executing in the global context.</p>
+
+<p id="aVa_7">However, using the <code>this</code> keyword is very likely to be
+confusing, especially in scripts that include custom javascript objects
+where the methods (and constructors) of those objects would be using
+<code>this</code> to refer to their own object instances.</p>
+
+<p id="aVa_8">Some javascript implementations do not have a property of the global
+object that refers to the global object. Rather than trying to use the
+<code>this</code> keyword to access global variables it is possible to
+create your own global variable that refers to the global object.</p>
+
+<pre id="aVa_ex4">
+var myGlobal = this;
+</pre>
+
+<p id="aVa_9">- executed as inline code at the start of a script will assign a
+reference to the global object (<code>this</code> in that context).
+From then on all global variables can be referenced with square bracket
+notation as:-</p>
+
+<pre id="aVa_ex5">
+myGlobal[&quot;anyName&quot;];
+</pre>
+
+<p id="aVa_10">- and expect <code>myGlobal</code> to refer to the global object
+from any execution context.</p>
+
+<h2><a name="illc" id="illc">Illegal characters in Identifier-strings</a></h2>
+
+<p id="illc_1">One advantage of the square bracket notation over dot notation is
+the ability to use characters in identifier-strings that are not legal
+identifier characters. It is generally best to avoid giving javascript
+properties names and <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> elements names/IDs that are not made up
+entirely of characters that are legal in the relevant context. However,
+it is not always possible to avoid referencing elements with names that
+include characters that would be illegal in a javascript identifier.
+PHP offers an example of this, multiple form elements given the same
+name followed with empty square brackets, such as
+<code>name=&quot;inpEl[]&quot;</code>, are made available on the server
+as an array.</p>
+
+<p id="illc_2">The square bracket notation would allow an element with such a name
+to be referenced as <code> document&#46;forms[&quot;formName&quot;]&#46;elements[&quot;inpEl[]&quot;][0]</code>
+for example (the final <code>[0]</code> reflects the fact that
+multiple elements with the same name, when accessed by name, generate
+collections of elements and individual elements within that collection
+need to be referenced by index).</p>
+
+<p id="illc_3">
+<a href="faq_notes.html#toc">comp.lang.javascript FAQ notes T.O.C.</a>
+</p>
+
+<ul style="list-style-type:none;margin-top:2.5em;">
+ <li>Written by <span class="person">Richard Cornford</span>. March 2003.</li>
+ <li>With technical corrections and suggestions by:-<br>
+ <ul style="list-style-type:none;">
+ <li><span class="person">Yann-Erwan Perio (Yep)</span>. (Also, thanks for testing the use
+ of <code>this</code> to reference the global object in WSH
+ and ASP2.)
+ </li>
+ <li><span class="person">Lasse Reichstein Nielsen</span>.</li>
+ <li><span class="person">Dr John Stockton</span>.</li>
+ </ul>
+ </li>
+</ul>
+</body>
+</html>
\ No newline at end of file
/trunk/cljs/faq_notes/square_brackets.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/faq_notes/faq_notes.html
===================================================================
--- trunk/cljs/faq_notes/faq_notes.html (nonexistent)
+++ trunk/cljs/faq_notes/faq_notes.html (revision 45)
@@ -0,0 +1,196 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en"><head><title>Notes on the comp.lang.javascript FAQ</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<meta name="ROBOTS" content="NOINDEX NOFOLLOW">
+<link href="../faq.css" rel="stylesheet" type="text/css">
+<link href="faq_notes.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+.tocEn {
+ margin-bottom:0.5em;
+}
+</style>
+</head>
+<body>
+<div id="pageWarning">
+ The documents under <kbd>faq_notes/</kbd> are unmaintained. An up-to-date version
+ of this document may be available at
+ <a href="/faq/notes/">/faq/notes/</a>.
+</div>
+
+<h1>Notes on the comp.lang.javascript FAQ</h1>
+<h2><a name="toc" id="toc">Table of Contents</a></h2>
+
+<ul id="contTable">
+ <li class="tocEn"><a href="#fnIntro">Introduction to the Notes</a>
+ <li class="tocEn">
+ <a name="FAQN2" id="FAQN2">2 comp.lang.javascript tips</a>
+ <ol>
+ <li><a href="clj_posts.html">Posting Questions and Replies to comp.lang.javascript</a></li>
+ </ol>
+ </li>
+ <li class="tocEn">
+ <a name="FAQN4_4" id="FAQN4_4">4.4 How can I see in javascript if a web browser accepts cookies?</a>
+ <ol>
+ <li><a href="cookies.html">Privacy filters on proxies</a></li>
+ </ol>
+ </li>
+ <li class="tocEn">
+ <a name="FAQN4_12" id="FAQN4_12">4.12 Why does parseInt('09') give an error?</a>
+ <ol>
+ <li>See: <a href="type_convert.html#tcPrIntRx">4.21.1 Javascript Type-Conversion - parseInt with a radix argument</a>
+ </li>
+ </ol>
+ </li>
+ <li class="tocEn">
+ <a name="FAQN4_13" id="FAQN4_13">4.13 How do I get the value of a form control?</a>
+ <ol>
+ <li><a href="form_access.html#faHead">Referencing Forms and Form Controls.</a>
+ <ul>
+ <li><a href="form_access.html#faInt">Introduction</a>
+ <ul>
+ <li><a href="form_access.html#faInF">Forms</a></li>
+ <li><a href="form_access.html#faInC">Form Controls</a></li>
+ </ul>
+ </li>
+ <li><a href="form_access.html#faShrt">Shortcut Accessors</a></li>
+ <li><a href="form_access.html#faComMis">The Most Common Mistake</a></li>
+ <li><a href="form_access.html#faAnon">Anonymous Form References</a></li>
+ <li><a href="form_access.html#faBut">Radio Button and Other Control Collections</a></li>
+ <li><a href="form_access.html#faEff">Efficient use of Form Accessors</a></li>
+ </ul>
+ </li>
+ </ol>
+ </li>
+ <li class="tocEn">
+ <a name="FAQN4_15" id="FAQN4_15">4.15 How do I modify the current page in a browser?</a>
+ <ol>
+ <li><a href="alt_dynwrite.html#alDynWr">An Alternative DynWrite function</a>
+ <ul>
+ <li><a href="alt_dynwrite.html#DynWr">The DynWrite function.</a></li>
+ <li><a href="alt_dynwrite.html#getEl">Element retrieval given the element ID as a string.</a></li>
+ <li><a href="alt_dynwrite.html#innHTest">innerHTML Testing Strategy.</a></li>
+ <li><a href="alt_dynwrite.html#AltDynWr">Alternative DynWrite function.</a></li>
+ </ul>
+ </li>
+ </ol>
+ </li>
+ <li class="tocEn">
+ <a name="FAQN4_21" id="FAQN4_21">4.21 Why does 1+1 equal 11? or How do I convert a string to a number?</a>
+ <ol>
+ <li><a href="type_convert.html">Javascript Type-Conversion</a>
+ <ul>
+ <li><a href="type_convert.html#tcInt">Introduction.</a></li>
+ <li><a href="type_convert.html#tcBool">Converting to Boolean.</a></li>
+ <li><a href="type_convert.html#tcString">Converting to String.</a></li>
+ <li><a href="type_convert.html#tcNumber">Converting to Number.</a></li>
+ <li><a href="type_convert.html#tcParse">Parsing to Number.</a>
+ <ul>
+ <li><a href="type_convert.html#tcParseFl">parseFloat</a></li>
+ <li><a href="type_convert.html#tcParseIn">parseInt</a></li>
+ <li><a href="type_convert.html#tcPrIntRx">parseInt with a radix argument</a></li>
+ </ul>
+ </li>
+ <li><a href="type_convert.html#tcToInt32">ToInt32.</a></li>
+ <li><a href="type_convert.html#tcUserIn">Converting User Input.</a>
+ <ul>
+ <li><a href="type_convert.html#tcRegEx">Regular expression examples.</a></li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ol>
+ </li>
+ <li class="tocEn">
+ <a name="FAQN4_25" id="FAQN4_25">4.25 My element is named myselect[] , how do I access it?</a>
+ <ol>
+ <li>See: <a href="square_brackets.html#illc">4.39.1 Javascript Square Bracket Notation - Illegal characters in Identifier-strings</a>
+ </li>
+ </ol>
+ </li>
+ <li class="tocEn">
+ <a name="FAQN4_26" id="FAQN4_26">4.26 How do I detect Opera/Netscape/IE?</a>
+ <ol>
+ <li><a href="not_browser_detect.html#bdTop">Browser Detecting (and what to do Instead)</a>
+
+ <ul>
+ <li><a href="not_browser_detect.html#bdIntro">Introduction</a></li>
+ <li><a href="not_browser_detect.html#bdValid">Avoiding structural differences in the browser DOMs</a></li>
+ <li><a href="not_browser_detect.html#bdDif">Browsers Differences</a></li>
+ <li><a href="not_browser_detect.html#bdFailS">Failed Strategies: Browser Detecting</a>
+ <ul>
+ <li><a href="not_browser_detect.html#bdUAS">Assumptions Based on navigator.userAgent</a></li>
+ <li><a href="not_browser_detect.html#bdOI">Assumptions Based on DOM Objects: Object inference</a></li>
+ </ul>
+ </li>
+ <li><a href="not_browser_detect.html#bdFD">A Strategy That Works: Object/Feature Detecting.</a>
+ <ul>
+ <li><a href="not_browser_detect.html#bdGEID">Example 1: IDed Element Retrieval</a></li>
+ <li><a href="not_browser_detect.html#bdScroll">Example 2: Scroll Values</a></li>
+ <li><a href="not_browser_detect.html#bdReplace">Example 3: String.prototype.replace</a></li>
+ </ul>
+ </li>
+ <li><a href="not_browser_detect.html#bdDesPb">The Javascript Design Problem</a></li>
+ </ul>
+
+
+ </li>
+ </ol>
+ </li>
+ <li class="tocEn">
+ <a name="FAQN4_39" id="FAQN4_39">4.39 How do I access the property of an object using a string?</a>
+ <ol>
+ <li><a href="square_brackets.html">Javascript Square Bracket Notation</a>
+ <ul>
+ <li><a href="square_brackets.html#intro">Introduction</a></li>
+ <li><a href="square_brackets.html#sBs">Square Bracket Syntax</a></li>
+ <li><a href="square_brackets.html#vId">String Variables as Identifiers</a></li>
+ <li><a href="square_brackets.html#eId">String Expressions as Identifiers</a></li>
+ <li><a href="square_brackets.html#aVa">Global Variable access with the Square Bracket Notation</a></li>
+ <li><a href="square_brackets.html#illc">Illegal characters in Identifier-strings</a></li>
+ </ul>
+ </li>
+ </ol>
+ </li>
+ <li class="tocEn">
+ <a name="FAQN4_41" id="FAQN4_41">4.41 Why doesn't the global variable &quot;divId&quot; always refer to the element with id=&quot;divId&quot;?</a>
+ <ol>
+ <li>See: <a href="alt_dynwrite.html#getEl">4.15.1 An Alternative DynWrite function - Element retrieval given the element ID as a string</a></li>
+ <li>See: <a href="not_browser_detect.html#bdGEID">4.26.1 Browser Detecting (and what to do Instead) - Example 1: IDed Element Retrieval</a></li>
+ </ol>
+ </li>
+ <li>Miscellaneous
+ <ol>
+ <li class="tocEn"><a href="cljs_charter.html">The comp.lang.javascript Charter</a></li>
+ <li class="tocEn"><a href="closures.html">Javascript Closures</a></li>
+ <li class="tocEn"><a href="script_tags.html">How to Include Scripts in <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> Documents</a></li>
+ <li class="tocEn"><a href="misc.html">Tricks and Tips</a></li>
+ </ol>
+ </li>
+ <li class="tocEn"><a href="contributors.html">Contributors</a></li>
+ <li class="tocEn"><a href="faqNotes.zip">The complete FAQ and Notes in ZIP format (174KB)</a></li>
+</ul>
+
+<h2><a name="fnIntro" id="fnIntro">Introduction to the Notes</a></h2>
+
+<p>
+Because the <a href="http://jibbering.com/faq/">comp.lang.javascript
+FAQ</a> is posted to the group regularly
+there are practical constraints on how much can be included in it. At
+the same time it is often felt that it should contain more (or more
+in-depth) information on some of its topics. The FAQ is largely
+designed to provide URLs of other resources that provide that
+additional information, but where no additional resource is available
+or it is felt that those resources omit important information. These
+notes are intended to provide an opportunity for those additional
+resources to be created.
+</p>
+
+<p>
+It is intended that anyone who wishes to contribute notes should be
+able to do so (under editorial control) and that some of the more
+in-depth postings to the group should become notes, or be
+incorporated within them.
+</p>
+
+</body>
+</html>
/trunk/cljs/faq_notes/faq_notes.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/faq_notes/script_tags.html
===================================================================
--- trunk/cljs/faq_notes/script_tags.html (nonexistent)
+++ trunk/cljs/faq_notes/script_tags.html (revision 45)
@@ -0,0 +1,949 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en"><head><title>How to Include Scripts in HTML Documents</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<link href="../faq.css" rel="stylesheet" type="text/css">
+<link href="faq_notes.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+BLOCKQUOTE PRE {
+ background-color:#EEEEFF;
+ color:#000000;
+ border:#EEEEFF 0px none;
+ margin:0;
+ padding:0;
+}
+BLOCKQUOTE H5 {
+ margin-left:0;
+}
+CODE { white-space:nowrap; }
+.elContent {
+ background-color:#EEEEFF;
+ color:#900000;
+}
+</style>
+</head>
+<body>
+
+<h1><a name="hsHead" id="hsHead">How to Include Scripts in <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> Documents</a></h1>
+
+<ul>
+ <li><a href="#hsIntro">Introduction</a></li>
+ <li><a href="#hsSE">SCRIPT Elements</a>
+ <ul>
+ <li><a href="#hsAt">Attributes</a>
+ <ol>
+ <li><a href="#hsAtch">charset</a></li>
+ <li><a href="#hsAtty">type</a></li>
+ <li><a href="#hsAtln">language</a></li>
+ <li><a href="#hsAtsc">src</a></li>
+ <li><a href="#hsAtdf">defer</a></li>
+ </ol>
+ </li>
+ </ul>
+ </li>
+ <li><a href="#hsStFm">The Standard Formulations</a></li>
+ <li><a href="#hsPrCn">Permissible Contexts for Script Elements</a></li>
+ <li><a href="#hsCt">The Content of Script Elements</a>
+ <ul>
+ <li><a href="#hsOld">Hiding Scripts from Older Browsers</a></li>
+ <li><a href="#hsETO">Closing Script Tags and &quot;&lt;/&quot; (end-tag open delimiter)</a></li>
+ </ul>
+ </li>
+ <li><a href="#hsExF">External Javascript Files</a>
+ <ul>
+ <li><a href="#hsExC">The content of External Javascript Files.</a></li>
+ </ul>
+ </li>
+ <li>
+ <a href="#hsMix">Script Elements that Import Javascript Files and Have Contents</a>
+ </li>
+ <li><a href="#hsEh">Event Handling Attributes: Intrinsic Events</a>
+ <ul>
+ <li><a href="#hsEhD">The Default Language for Intrinsic Events</a></li>
+ </ul>
+ </li>
+ <li><a href="#hsNs">NOSCRIPT Elements</a></li>
+</ul>
+
+<h2><a name="hsIntro" id="hsIntro">Introduction</a></h2>
+
+
+<p>
+There are three ways of including scripts in <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> documents:-
+</p>
+
+<ol>
+ <li>As the string value provided for an event handling attribute such as onclick (intrinsic events).</li>
+ <li>As the contents of a SCRIPT element (between opening and closing script tags in certain permissible locations within <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> source code.</li>
+ <li>As a separate script file imported into an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page by having the URL of the file assigned to the SRC attribute of a SCRIPT element, again at certain permissible locations within the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> source.</li>
+</ol>
+
+<h2><a name="hsSE" id="hsSE">SCRIPT Elements</a></h2>
+
+<p>
+The current <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> version is 4.01. The <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> 4.01 transitional DTD
+defines a script element with:-
+</p>
+
+<blockquote cite="http://www.w3.org/TR/html4/loose.dtd" style="font-family:Courier, monospace;">
+&lt;!ELEMENT SCRIPT <span class="elContent">- -</span> %Script; -- script statements --&gt;<br>
+&lt;!ATTLIST SCRIPT<br>
+<pre>
+ charset %Charset; #IMPLIED - char encoding of linked resource -
+ type %ContentType; #REQUIRED - content type of script language -
+ language CDATA #IMPLIED - predefined script language name -
+ src %URI; #IMPLIED - URI for an external script -
+ defer (defer) #IMPLIED - UA may defer execution of script -
+ event CDATA #IMPLIED - reserved for possible future use -
+ for %URI; #IMPLIED - reserved for possible future use -
+ </pre>
+ &gt;
+</blockquote>
+
+<p>
+(The <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> 4.01 strict DTD omits the <code>language</code> attribute
+as it is deprecated in the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> 4.01 standard.)
+</p>
+
+<p>
+Script elements are defined with opening and closing script tags. The
+two dashes after the element name in the DTD means that neither opening nor
+closing tag may be omitted, even when the element is importing a
+javascript file and has no contents.
+</p>
+
+<h3><a name="hsAt" id="hsAt">Attributes</a></h3>
+
+<h4><a name="hsAtch" id="hsAtch">charset</a></h4>
+
+<p>
+The <code>charset</code> attribute can declare the character encoding of an external
+javascript file that is being imported using the <code>src</code> attribute. In all
+cases it is preferable that the server sending the file provide
+character encoding information in Content-Type
+<span class="initialism" title="HyperText Transfer Protocol ">
+<abbr title=" Transfer Protocol ">HTTP</abbr></span> headers (with the
+slight problem that there was no official content-type for use with
+scripts; see the <code>type</code> attribute below).
+</p>
+
+<p>
+Javascript itself uses a very limited repertoire of characters but the
+content of string literals in non-Latin languages may necessitate an
+interest in character encodings with script files. That is not a
+problem that I have faced to date so I don't know how it should best
+be handled. I am yet to see a <code>charset</code> attribute used in
+a script tag.
+</p>
+
+<h4><a name="hsAtty" id="hsAtty">type</a></h4>
+
+<p>
+The <code>type</code> attribute is required in <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> 4 but the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> 4
+specification is not very helpful on the subject. It says:-
+</p>
+
+<blockquote cite="http://www.w3.org/TR/html4/interact/scripts.html#h-18.2.1">
+<h5>type = content-type [CI]</h5>
+This attribute specifies the scripting language of the element's
+contents and overrides the default scripting language. The scripting
+language is specified as a content type (e.g.,
+&quot;text/javascript&quot;). Authors must supply a value for this
+attribute. There is no default value for this attribute.
+</blockquote>
+
+<p>
+(The [CI] means that the attribute's value is case insensitive.)
+</p>
+
+<p>
+Pursuing the permissible values of content-type through the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>
+specification leads to a list of currently recognised content types
+(MIME or Media types). Up until mid 2005 that list did not include
+anything related to ECMAScript or javascript. So although the attribute
+is required, and so must have a value, there was no standardised
+content-type for that value. However, the HTML 4 specification did give
+text/javascript as an example (even though it was not a recognised
+standard content type) so it was that value that has traditionally been
+used with the <code>type</code> attribute when including or importing
+ECMAScript/javascript into an HTML page.
+</p>
+
+<p>
+The MIME types introduced in 2005 are application/ecmascript,
+application/javascript and text/javascript. The last of these, and the
+value that has traditionally been used; text/javascript, was official
+deprecated and so should be phased-out over time. However, at the point
+of officially recognising these new MIME types no browsers exist that
+will recognise either of application/ecmascript and application/javascript.
+This means that if either are actually used for the value of the <code>type</code>
+attribute the likelihood is that the script in question will never be
+executed.
+</p>
+
+<p>
+So for the present, and probably many years to come, text/javascript is
+the only viable value for use with the <code>type</code> attribute when using javascript.
+</p>
+
+<pre>
+type=&quot;text/javascript&quot;
+</pre>
+
+<h4><a name="hsAtln" id="hsAtln">language</a></h4>
+
+<p>
+The <code>language</code> attribute is deprecated (and not allowed under
+the strict DTD) and it is unnecessary when the <code>type</code> attribute
+is required, as that attribute will determine the language used.
+</p>
+
+<p>
+The <code>language</code> attribute can be more specific than the
+<code>type</code> attribute because it can also specify the language
+version. In almost all respects specifying a language version is not
+helpful and even potentially dangerous.
+</p>
+
+<p>
+By default a web browser will execute a script using the latest version
+of the language that it supports. Generally all current (March 2004)
+browsers support all of the language features specified in ECMA 262 2nd
+edition (approximately JavaScript 1.3) and most fully support the 3rd
+edition. Restricting the language features used to those defined in
+ECMA 262 2nd edition (with additional care in some less used areas)
+should result in scripts that will happily execute on all current
+browsers without a need to specify a language version.
+</p>
+
+<p>
+Netscape initially attempted to tie the DOM features of their browser
+to the language version, which would have allowed a specified language
+version to imply the DOM features supported. That idea was abandoned
+because other browsers produced by their competitors introduced
+scripting with near identical languages but significantly different
+DOMs. DOM support should be determined independently of language
+version using object/feature detecting.
+</p>
+
+<p>
+The potential danger with specifying a language version comes with
+specifying version 1.2. Version 1.2 was an aberration. It deviated
+significantly from earlier versions of the language in anticipation
+of changes to the ECMA specification, but those changes were never
+made. Netscape had to reverse the changes it had made to version
+1.2 in version 1.3 in order to conform with what was eventually
+published as ECMA 262 2nd edition. The only browsers released for
+which version 1.2 was the default JavaScript version were Netscape
+4.00 to 4.05 (and you won't find many of those left in the wild).
+</p>
+
+<p>
+The problem is that if you specify version 1.2 in a <code>language</code> attribute
+you may actually get it, with all of its deviant characteristics, but
+at the same time most browsers will not exhibit those characteristics.
+It is always a bad idea to encourage the same code to be interpreted in
+two different ways, and certainly never without fully understanding how
+the language versions differ. The specific problem can be avoided by
+never specifying the language version as 1.2. The issue can be avoided
+by never providing the deprecated <code>language</code> attribute at all.
+</p>
+
+<h4><a name="hsAtsc" id="hsAtsc">src</a></h4>
+
+<p>
+The SRC attribute specifies the URL of an external javascript file that
+is to be imported by the script element. If no file is being imported
+by the element (the script is the element's contents) then the
+<code>src</code> attribute is omitted.
+</p>
+
+<h4><a name="hsAtdf" id="hsAtdf">defer</a></h4>
+
+<p>
+The <code>defer</code> attribute is specified as providing a
+&quot;hint&quot; to the browser as to whether it needs to process
+the script immediately (as it usually would), or whether it can carry
+on parsing the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> following the script element and leave the
+javascript interpreter to process the script in its own time.
+</p>
+
+<p>
+If a script uses the <code>document.write</code> method to insert
+content into the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> being processed then the script element
+containing that script must not be deferred as the inserted <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>
+could end up at any point in the document (or even be inserted after
+the current document has closed, replacing it). If a script is
+deferred additional care must be taken before any part of it, such
+as a function it defines, is interacted with by other scripts (such
+as intrinsic events).
+</p>
+
+<p>
+It is unusual for a script element to have a <code>defer</code>
+attribute. And many browsers will not recognise/act upon a
+<code>defer</code> attribute even if one is present.
+</p>
+
+<h2><a name="hsStFm" id="hsStFm">The Standard Formulations</a></h2>
+
+<p>
+Leaving the <code>defer</code> and <code>charset</code> attributes
+aside, the normal formulation for a valid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> 4 script element that
+imports a javascript file is:-
+</p>
+
+<pre>
+&lt;script type=&quot;text/javascript&quot;
+ src=&quot;http://example.com/scriptFile.js&quot;&gt;&lt;/script&gt;
+
+<span class="commentJS">&lt;!-- or using an example relative URL --&gt;</span>
+
+&lt;script type=&quot;text/javascript&quot; src=&quot;../scripts/scriptFile.js&quot;&gt;&lt;/script&gt;
+</pre>
+
+<p>
+<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> is case insensitive so the tag name and attribute names can be
+in upper or lower (or mixed) case (current practice tends to prefer
+lower case).
+</p>
+
+<p>
+The attribute values must be quoted because in both cases they include
+characters that are forbidden in unquoted attribute values (forbidden
+characters would be any character that is not: letters (a-z and A-Z),
+digits (0-9), hyphens (ASCII decimal 45), periods (ASCII decimal 46),
+underscores (ASCII decimal 95), and colons (ASCII decimal 58)). The
+quote characters used may be double quotes (<code>&quot;</code>) or single quotes
+(<code>'</code>). Common practice prefers double quotes for <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> attributes.
+</p>
+
+<p>
+Traditionally javascript files are given a two-letter extension of <code>.js</code>.
+That extension is not required, any valid URL to a resource that
+returns content that can be interpreted as valid javascript source
+code will work. In addition, browsers do not appear to be interested
+in any Content Type headers sent with the javascript source, which is
+probably a good thing as officially recognised content types have only
+just (mid 2005) been introduced.
+</p>
+
+<p>
+Script that is to be included in an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page is placed as the content
+of a script element. Appearing between the opening and closing script
+tags:-
+</p>
+
+<pre>
+&lt;script type=&quot;text/javascript&quot;&gt;
+function exampleFunctionDeclaration(n){
+ return (n * 4);
+}
+&lt;/sciprt&gt;
+</pre>
+
+<p>
+The same case sensitivity and attribute value quoting considerations
+apply to this application of the script tags as applied to their use
+when importing external script files.
+</p>
+
+
+<h2><a name="hsPrCn" id="hsPrCn">Permissible Contexts for Script Elements</a></h2>
+
+<p>
+Script elements may not appear in all contexts in an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> document.
+They may be children of the <code>HEAD</code> element because the DTD
+defines the content of the <code>HEAD</code> element as including
+<code>%head_misc;</code> content which includes <code>SCRIPT</code> in
+its definition. Script elements may also appear within the
+<code>BODY</code> element in any context that is specified as
+<code>%flow;</code>, <code>%inline;</code>, <code>%special;</code> or
+specifically <code>SCRIPT</code> by the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> DTDs. This is because
+<code>%flow;</code> includes all elements defined as
+<code>%inline;</code>, which includes all elements defined as
+<code>%special;</code>, which includes <code>SCRIP</code> in its
+definition (among others).
+</p>
+
+<p>
+Reading the DTDs and looking out for these categories will indicate
+where script elements are allowed to appear. For example, the (<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>
+4.01 transitional) DTD definition for the paragraph element reads:-
+</p>
+
+<blockquote cite="http://www.w3.org/TR/html4/loose.dtd">
+<pre>
+&lt;!ELEMENT P - O (<span class="elContent">%inline;</span>)* -- paragraph --&gt;
+</pre>
+</blockquote>
+
+<p>
+The content for the <code>P</code> element is <code>%inline;</code> and
+<code>%inline;</code> encompasses <code>SCRIPT</code>. Similarly:-
+</p>
+
+<blockquote cite="http://www.w3.org/TR/html4/loose.dtd">
+<pre>
+&lt;!ELEMENT DD - O (<span class="elContent">%flow;</span>)* -- definition description --&gt;
+</pre>
+</blockquote>
+
+<p>
+The <code>DD</code> element has <code>%flow;</code> defining its content so it is
+allowed <code>SCRIPT</code> as its content (or part of it). Whereas:-
+</p>
+
+<blockquote cite="http://www.w3.org/TR/html4/loose.dtd">
+<pre>
+&lt;!ELEMENT DL - - (<span class="elContent">DT|DD</span>)+ -- definition list --&gt;
+</pre>
+</blockquote>
+
+<p>
+The <code>DL</code> element is only allowed <code>DT</code> and
+<code>DD</code> elements as its children. So a script element
+cannot appear as a child of a <code>DL</code> element in valid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> 4.
+</p>
+
+<p>
+The DTD for the particular flavour of <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> being authored is the best
+guide as the where in a document script elements may appear, but note
+that the different versions of the DTD differ slightly in terms of the
+content defined for some elements.
+</p>
+
+<h2><a name="hsCt" id="hsCt">The Content of Script Elements</a></h2>
+
+<p>
+Script elements that have source code as their contents and appear on
+an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page need some special consideration.
+</p>
+
+<h3><a name="hsOld" id="hsOld">Hiding Scripts from Older Browsers</a></h3>
+
+<p>
+When scripting was first introduced the preceding generations of
+browsers had no concept of what a script element was, and would treat
+the content of the unrecognised script tags in the way unrecognised
+tags are normally handled in <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>. The content is treated as <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>
+source, which, for a scripts, meant including it as text in a page.
+The results did not look good and a mechanism was provided to hide the
+script element contents from browsers that did not know how to handle
+script elements.
+</p>
+
+<p>
+Javascript has an end of line comment symbol consisting of two slashes
+(<code>//</code>). All characters between that symbol and the end of
+the line are treated as a comment and ignored. <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> also provides a
+means of commenting out parts of its source, an opening comment
+tag <code>&lt;!--</code> and a closing comment tag
+<code>--&gt;</code> (strictly these are not opening and closing tags
+in HTML, it is the pairs of dashes that start and end a comment. The
+surrounding <code>&lt;!</code> and <code>&gt;</code> represent a
+processing instruction, which is the only context in which a comment
+is recognised in HTML.).
+</p>
+
+<p>
+The trick to hiding javascript source code from
+browsers that did not recognise the script element, so it would not
+be shown on the page, was to allow script included in an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page to
+use an additional end of line comment symbol that corresponded with
+the <code>&lt;!--</code> opening comment tag used by <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>. The script
+author would then place this tag/comment symbol at the start of the
+script source code (on a line of its own, so as not to comment out
+any javascript code) and then use the normal javascript end of line
+comment symbol to comment out (from the javascript interpreter) an
+<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> end of comment tag.
+</p>
+
+<pre>
+&lt;script type=&quot;text/javascript&quot;&gt;
+<span class="commentJS">&lt;!--</span>
+function exampleFunctionDeclaration(n){
+ return (n * 4);
+}
+<span class="commentJS">// --&gt;</span>
+&lt;/sciprt&gt;
+</pre>
+
+<p>
+A browser incapable of recognising the script element would treat its
+content as <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>
+source and so it would interpret the script within the script element
+as effectively commented out, thus not displaying it on the page.
+</p>
+
+<p>
+When scripting was introduced the practice was necessary and highly
+recommended, but that was some time ago and browsers and <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> versions
+have moved on two or three generations. We are now at a point where
+the oldest browsers in current use are already two generations into
+<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> versions that formalised script elements. They all know what a
+script element is and how its contents should be handled. Even
+browsers that cannot execute scripts know that they are supposed to
+ignore the content of script elements.
+</p>
+
+<p>
+The practice of hiding scripts from &quot;older&quot; browsers has
+become an anachronism, no longer needed and no longer used by informed
+javascript authors. It is still often seen because it is recommended
+in out of date books and in out of date javascript tutorials on the
+web. And the readers of those books and tutorials continue to use and
+promote it, not realising that it no longer serves any real purpose.
+</p>
+
+<p>
+The existence of this additional comment syntax in javascript included
+in <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> pages also lead to <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> style comments being used extensively
+in on-page javascript. This was, and is, a very bad idea. Javascript
+has end of line and multi-line comment syntaxes and they should be used
+exclusively to comment javascript source code.
+</p>
+
+<h3><a name="hsETO" id="hsETO">Closing Script Tags and &quot;&lt;/&quot; (end-tag open delimiter)</a></h3>
+
+<p>
+When a script is included on an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser needs to
+decide how much of the page's source text to pass on to the javascript
+interpreter and where it should start processing other <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> again.
+Officially an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser is required to take the first occurrence of
+the character sequence &quot;<code>&lt;/</code>&quot; it finds after
+the opening script tag as marking the end of the script element. In
+practice browsers seem to be a lot more lax and only terminate the
+script section when they encounter the character sequence
+&quot;<code>&lt;/script&gt;</code>&quot;.
+</p>
+
+<p>
+That seems reasonable (if lax) but it does not eliminate all problems.
+Suppose that a script includes <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> source in the form of a string
+literal, and that source includes a closing script tag, as might be
+the case when using <code>document.write</code> to write a new script
+element to the page:-
+</p>
+
+<pre>
+&lt;script type=&quot;text/javascript&quot;&gt;
+document.write(
+ '&lt;script type=&quot;text/javascript&quot; src=&quot;scriptFile.js&quot;&gt;&lt;/script&gt;');
+&lt;/script&gt;
+</pre>
+
+<p>
+That is an example simplified to the point of being futile but it
+should be obvious that if the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser considers the first
+occurrence of &quot;<code>&lt;/script&gt;</code>&quot; as terminating
+the script element the results will be undesirable.
+</p>
+
+<p>
+The solution is to do something to make the character sequence within
+the javascript string of <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> different from the sequence that will be
+recognised as the closing script tag. This is often done by splitting
+the string and using a concatenation operation to let the script
+produce the same output:-
+</p>
+
+<pre>
+&lt;script type=&quot;text/javascript&quot;&gt;
+document.write(
+ '&lt;script type=&quot;text/javascript&quot; src=&quot;scriptFile.js&quot;&gt;&lt;/scr'+'ipt&gt;');
+&lt;/script&gt;
+</pre>
+
+<p>
+This conceals the closing script tag from the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser but it is not
+a good idea because string concatenation is a surprisingly heavyweight
+operation and the same goal of disrupting the character sequence that
+the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser will mistake for a closing tag can be achieved by using
+the javascript escape character to escape any character in the closing
+script tag:-
+</p>
+
+<pre>
+&lt;script type=&quot;text/javascript&quot;&gt;
+document.write(
+ '&lt;script type=&quot;text/javascript&quot; src=&quot;scriptFile.js&quot;&gt;&lt;/script\&gt;');
+&lt;/script&gt;
+</pre>
+
+<p>
+The <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser will now not find the character sequence
+&quot;<code>&lt;/script&gt;</code>&quot; until it encounters the real
+closing script tag, but the internal representation of the string is not
+affected by the use of the escape character in the javascript source
+and no additional operations are needed.
+</p>
+
+<p>
+However, as I said, it is the character sequence
+&quot;<code>&lt;/</code>&quot; that is officially to be taken as
+terminating a script element's contents. While no current browsers are
+known to be that strict it is entirely realistic that some browsers may
+exist (or be introduced) that takes the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> specifications to hart and
+treat &quot;<code>&lt;/</code>&quot; as the end of the script content.
+But <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> validaters already tend to take the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> specification
+seriously and will report many mark-up errors as a result of getting
+the impression that a script element has terminated sooner than a
+browser would think it had.
+</p>
+
+<p>
+The above use of the escape character may placate all known browsers
+but it will not address the requirements of the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> specification.
+But they can both be addressed by escaping a different character,
+specifically the forward slash:-
+</p>
+
+<pre>
+&lt;script type=&quot;text/javascript&quot;&gt;
+document.write(
+ '&lt;script type=&quot;text/javascript&quot; src=&quot;scriptFile.js&quot;&gt;&lt;\/script&gt;');
+&lt;/script&gt;
+</pre>
+
+<p>
+Of course now it is not just the closing script tag that needs to be
+escaped but all occurrences of closing tags appearing in string
+literals. All occurrences of &quot;<code>&lt;/</code>&quot; would need
+to be escaped to &quot;<code>&lt;\/</code>&quot; to completely avoid
+<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser and validation problems. Alternatively the javascript
+source could be moved to an external file as then it is never
+examined by an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser or considered in <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> validation.
+</p>
+
+<h2><a name="hsExF" id="hsExF">External Javascript Files</a></h2>
+
+<p>
+Placing javascript source code in external files has several
+advantages. For those who are required to use a browser that is
+javascript incapable/disabled it can significantly reduce download
+time as those browsers just will not bother getting the external file
+as they have no use for it, scripts on an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page must be downloaded
+with the page if the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> is to be used.
+</p>
+
+<p>
+External javascript files can also be cached separately from <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> pages
+so they may need to be downloaded less often even for the users of
+javascript capable/enabled browsers.
+</p>
+
+<p>
+They entirely remove the need to worry about script hiding (no longer
+needed anyway), escaping <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> closing tags in strings or any other
+factors relating to the parsing of mark-up languages.
+</p>
+
+<p>
+Javascript imported by using the <code>src</code> attribute of a script element is
+used in place of the content for the script element that imported it.
+The position of that element in the page defines the
+&quot;location&quot; of the script in the document. If the file
+executes <code>document.write</code> then any content written will be
+inserted following the script element that imported the file, and any
+other elements on the page referenced by that script as it loads will
+need to have already been parsed by the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser at that point or
+they will not be found in the DOM.
+</p>
+
+<h3><a name="hsExC" id="hsExC">The Content of External Javascript Files.</a></h3>
+
+<p>
+Javascript files imported using the <code>src</code> attribute of script elements
+must contain <em>only</em> javascript source code. They must not contain any
+<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>. It is a surprisingly common error for opening and closing script
+tags and/or the &quot;hide from older browsers&quot; <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> comment
+tags to be included in external script files, in that context they are
+javascript syntax errors and nothing else.
+</p>
+
+<h2><a name="hsMix" id="hsMix">Script Elements that Import Javascript Files and Have Contents</a></h2>
+
+<p>
+Script elements may attempt to both import a file and contain script
+contents. The idea here is to provide some scripted action in the event
+that the external file cannot be loaded for some reason. Such a script
+element may look like:-
+</p>
+
+<pre>
+&lt;script type=&quot;text/javascript&quot; src=&quot;../scripts/scriptFile.js&quot;&gt;
+ var externalScriptLoaded = false;
+&lt;/script&gt;
+</pre>
+
+<p>
+The browser should handle this formulation of the script element by
+attempting to load the external file, but in the even of that attempt
+failing instead the contents of the script element are executed. So, in
+the example above, if the external file is loaded and executed the
+contents of the element would not be executed. That external file
+would itself define the <code>externalScriptLoaded</code> global
+variable and assign it a value of boolean <code>true</code>. If the
+file did not load the contents would be executed, again creating
+the <code>externalScriptLoaded</code> variable, but this time
+assigning it a <code>false</code> value. Another script on the page
+can then read the <code>externalScriptLoaded</code> variable as a
+means of determining whether the external script loaded successfully.
+</p>
+
+<p>
+The definition of failing to load an external script is centred
+around <span class="initialism" title="HyperText Transfer Protocol ">
+<abbr title=" Transfer Protocol ">HTTP</abbr></span>. If no connection
+to the server can be made, or an
+<span class="initialism" title="HyperText Transfer Protocol ">
+<abbr title=" Transfer Protocol ">HTTP</abbr></span> error response,
+such as <code>404</code>, is returned, then the external script has
+failed to load and the browser can execute the contents of the
+element. However, many servers are set up in such a way that they
+do not actually return the expected
+<span class="initialism" title="HyperText Transfer Protocol ">
+<abbr title=" Transfer Protocol ">HTTP</abbr></span> error responses,
+but instead return an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page that is intended to inform the user
+of the error. This is fine for humans but from the point of view of
+the browser such a response is indistinguishable from a returned
+(but erroneous) javascript source file (This is in part because
+the browser disregards content-type headers sent with external
+javascript files so even if the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> error reporting page is sent
+with a text/html content type the browser will still assume that
+it contains javascript source). The browser attempts to
+execute the returned <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> source as javascript and fails at the
+first inevitable syntax error. But erroring while executing what
+the browser thought was an external javascript file does not
+result in the execution of the code within the script element.
+</p>
+
+<p>
+In practice script elements are rarely used where an external
+file is imported and script contents are provided for the element.
+If a separate script wanted to verify that an externally imported
+script was available it would not need the mechanism demonstrated
+in the example above as javascript provides many ways of verifying
+the existence of javascript defined entities. So, for example, if
+the external script defined a function called <code>functionName</code>, the
+availability of that function could be verified as:-
+</p>
+
+<pre>
+if(typeof functionName == &quot;function&quot;){
+ functionName();
+}
+</pre>
+
+<p>
+- and if a function defined in an external file is available then
+that external file must have been successfully loaded.
+</p>
+
+<h2><a name="hsEh" id="hsEh">Event Handling Attributes: Intrinsic Events</a></h2>
+
+<p>
+The final place where javascript can be included in an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> document is
+as the value strings provided for event handling attributes.
+</p>
+
+<p>
+The values of event handling attributes will almost certainly need to
+be quoted because it is nearly impossible to write a javascript
+statement that only uses the characters allowed in an unquoted
+attribute value. And quoting can get quite involved in attribute values
+because they need to be quoted in the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> source so whatever type of
+quote marks are used in the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> cannot be used within the javascript
+code provided as the value because the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser would take them as
+ending the string for the attribute value. While javascript string
+literals allow the use of double quotes or single quotes as delimiters
+and allow the type of quote not used as the delimiter to appear within
+the string literal unescaped.
+</p>
+
+<p>
+So, given a desire to assign the string <code>&quot;don't do
+that&quot;</code> to an element's value property in an onclick event,
+because of the single quote appearing in the string itself the attribute
+value <code>onclick='this.value = &quot;don't do that&quot;;'</code>
+will not work because the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser will take the second single quote
+as ending the attribute value. It will not work to simply escape the
+single quote as <code>onclick='this.value = &quot;don\'t do
+that&quot;;'</code> because the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser doesn't know anything about
+javascript escapes and still sees the second single quote in the middle
+of the javascript string.
+</p>
+
+<p>
+In this case escaping the single quote and reversing the quoting
+between the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> and the javascript
+<code>onclick=&quot;this.value = 'don\'t do that';&quot;</code> or
+using a javascript hex escape (which the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> parser will not see as a
+quote) <code>onclick='this.value = &quot;don\x27t do that&quot;;'</code>
+would solve the problem. But quotes in event handling attribute strings
+that define code that uses string literals often needs to be thought
+about.
+</p>
+
+<h3><a name="hsEhD" id="hsEhD">The Default Language for Intrinsic Events</a></h3>
+
+<p>
+All else being equal, web browsers seem to all default the scripting
+language used with intrinsic events to javascript (ECMAScript, in
+whichever implementation is provided) and there is no formal mechanism
+for associating a scripting language with individual event handling
+attributes (unlike script elements which must be provided with a
+<code>type</code> attribute).
+</p>
+
+<p>
+The <span class="initialism" title="HyperText Mark-up Language">
+<abbr title="HyperText Mark-up Language">HTML</abbr></span>
+specification calls for a page wide default scripting language
+to be set, and that is the only specified way to set the scripting
+language for intrinsic events.
+</p>
+
+<p>
+To this end The <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> specification proposes the inclusion in the
+<code>HEAD</code> section of a page of a <code>META</code> tag:-
+</p>
+
+<blockquote cite="http://www.w3.org/TR/html4/interact/scripts.html#h-18.2.2.1">
+<pre>
+&lt;meta http-equiv=&quot;Content-Script-Type&quot; content=&quot;text/javascript&quot;&gt;
+</pre>
+</blockquote>
+
+<p>
+This is supposed to assert the default type of script language on a
+page (possibly overridden by the (required) <code>type</code>
+attributes provided for individual script elements). As a result it
+is <em>formally correct</em> to include this tag in <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> 4.01 documents
+(or provide a corresponding <span class="initialism" title="HyperText Transfer Protocol "><abbr title=" Transfer Protocol ">HTTP</abbr></span> header when the page is served).
+</p>
+
+<p>
+However, there is no evidence that any current browsers pay any attention to
+this <code>META</code> element at all (or would have any interest in a corresponding
+<span class="initialism" title="HyperText Transfer Protocol "><abbr title=" Transfer Protocol ">HTTP</abbr></span>
+header), but then there are not many browsers that can execute any
+scripting language but javascript. This entire proposed mechanism
+has also been subject to criticism, and many recommend disregarding
+it entirely in favour of relying on the tendency of browsers to
+default to interpreting intrinsic event code as javascript.
+</p>
+
+<h2><a name="hsNs" id="hsNs">NOSCRIPT Elements</a></h2>
+
+<p>
+The general idea of a <code>NOSCRIPT</code> element is to provide a
+holder for <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> marked-up content
+that will only be displayed when scripting is not enabled/available on
+a web browsers. At first sight this seems to be a useful idea, and a
+contribution towards providing clean degradation in circumstances where
+scripts cannot be executed. Showing content that would be a substitute
+for any content that would otherwise have been provided by a script.
+</p>
+
+<p>
+However, <code>SCRIPT</code> and <code>NOSCRIPT</code> elements are not
+actually directly substitutable in
+<span class="initialism" title="HyperText Mark-up Language">
+<abbr title="HyperText Mark-up Language">HTML</abbr></span>. That is, you
+cannot use a <code>NOSCRIPT</code> element in all of the contexts in
+which you can use a <code>SCRIPT</code> element and produce valid
+<span class="initialism" title="HyperText Mark-up Language">
+<abbr title="HyperText Mark-up Language">HTML</abbr></span> as a result.
+</p>
+
+<p>
+The <span class="initialism" title="HyperText Mark-up Language">
+<abbr title="HyperText Mark-up Language">HTML</abbr></span> DTDs
+categories <code>SCRIPT</code> and <code>NOSCRIPT</code> differently:
+<code>SCRIPT</code> is an <code>%inline</code>, <code>%special</code> or <code>%head.misc</code> element,
+it may appear in the <code>HEAD</code> of a document (as a child of
+a <code>HEAD</code> element (<code>%head.misc</code>)), or in any context that
+allows inline or <code>%special</code> content (descendants of the <code>BODY</code>
+element, but not in all contexts). The <code>NOSCRIPT</code> element
+is categorised as <code>%block</code>, and as a result it cannot appear in the
+<code>HEAD</code> at all, and may only appear in the body in a context
+that allows <code>%block</code> content (<code>%flow</code> or <code>%block</code> but not <code>%inline</code>). This
+means that the one cannot always stand as a direct substitute for the
+other in a valid <span class="initialism" title="HyperText Mark-up Language">
+<abbr title="HyperText Mark-up Language">HTML</abbr></span> document.
+</p>
+
+<p>
+<span class="initialism" title="HyperText Mark-up Language">
+<abbr title="HyperText Mark-up Language">HTML</abbr></span> <code>NOSCRIPT</code>
+elements probably seemed like a good idea when they were first introduced.
+They were probably even viable at the time because so few browsers were
+able to execute javascript that a division between <code>SCRIPT</code>
+and <code>NOSCRIPT</code> could encompass all of the possibilities. The
+problem with them now is the diversity of javascript capable web
+browsers, with their differing object models and language implementations.
+</p>
+
+<p>
+While it remains the case that any browser on which scripting is disabled
+or unavailable will use any <code>NOSCRIPT</code> elements provided in
+an <span class="initialism" title="HyperText Mark-up Language">
+<abbr title="HyperText Mark-up Language">HTML</abbr></span> page, it is not the
+case that all javascript supporting and enabled browsers will be able
+to successfully execute any script specified within (or imported by) a
+<code>SCRIPT</code> element. The browser may lack the features needed
+by the script, or just not be sufficiently dynamic to present any
+content that the script intends to insert into the document.
+</p>
+
+<p>
+Even browser features as seemingly universal as the
+<code>document.write</code> function are not universally supported
+(even on modern browsers), and anything even remotely dynamic is bound
+to fail somewhere. So instead of having to cope with two certain
+outcomes, successful execution and no script execution at all, it is
+actually necessary to cope with 3 possible outcomes, adding the
+possibility that scripting is supported by the browser but the features
+required by any individual script are not available. In that third
+case the script fails to provide what it was intended to provide, but
+the contents of the <code>NOSCRIPT</code> elements are not presented
+either.
+</p>
+
+<p>
+This effectively renders <code>NOSCRIPT</code> elements next to
+useless when it comes to providing clean degradation. They leave
+an unbridgeable gap between browsers unwilling or unable to execute
+scripts at all and browsers that will fully support any given script.
+And whatever content seemed to make sense within those
+<code>NOSCRIPT</code> elements must also make sense in the context
+of a javascript capable browser that does not support the features
+required by a script.
+</p>
+
+<p>
+Recognising a requirement for clean degradation in script design,
+and the inability of <code>NOSCRIPT</code> elements to contribute
+towards facilitating it, many recommend never using
+<code>NOSCRIPT</code> elements. Instead providing content that
+works in place of active script support within the
+<span class="initialism" title="HyperText Mark-up Language">
+<abbr title="HyperText Mark-up Language">HTML</abbr></span> and then
+having their scripts remove, or transform by manipulation, that
+content only when the browser proves sufficiently supportive for
+the script to be viable. This technique allows the design to only
+consider two conditions; the browser fully supports the script
+and will execute it, or the browser does not support the scripts
+so whatever was originally included in the
+<span class="initialism" title="HyperText Mark-up Language">
+<abbr title="HyperText Mark-up Language">HTML</abbr></span> will be
+what the user is exposed to.
+</p>
+
+<p id="rToc">
+<a href="faq_notes.html#toc">comp.lang.javascript FAQ notes T.O.C.</a>
+</p>
+
+</body>
+</html>
\ No newline at end of file
/trunk/cljs/faq_notes/script_tags.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/faq_notes/cljs_charter.html
===================================================================
--- trunk/cljs/faq_notes/cljs_charter.html (nonexistent)
+++ trunk/cljs/faq_notes/cljs_charter.html (revision 45)
@@ -0,0 +1,146 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en"><head><title>CALL FOR VOTES -- comp.lang.javascript</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<link href="../faq.css" rel="stylesheet" type="text/css">
+<link href="faq_notes.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+
+<h1><a name="chT" id="chT">The comp.lang.javascript Charter</a></h1>
+
+<p>
+The following is the text of the last Call For Votes (CFV) that
+resulted in the creation of the comp.lang.javascript newsgroup
+(as extracted from the archives at google groups). It defines
+the Charter for the proposed group, and as the vote was successful
+the charter as stated below is the charter currently in force for
+the comp.lang.javascript.
+</p>
+
+<pre>
+LAST CALL FOR VOTES (of 2)
+ unmoderated group comp.lang.javascript
+
+Newsgroups line:
+comp.lang.javascript Netscape Communications Corp.'s JavaScript language.
+
+Votes must be received by 23:59:59 UTC, 26 Jan 1996.
+
+This vote is being conducted by a neutral third party. Questions
+about the proposed group should be directed to the proponent.
+
+Proponent: Thomas Winzig &lt;thomas.winzig@webcom.com&gt;
+Votetaker: Steve Bonine &lt;spb@ntrs.com&gt;
+
+RATIONALE: comp.lang.javascript
+
+Since Netscape Communication Corp.'s release of the Java-complementary
+scripting language, JavaScript, there has been a steady increase in
+the amount of JavaScript related questions and discussion in the
+comp.lang.java usenet newsgroup. Since these two languages are
+distinctly different, and might draw discussion from two generally
+different 'crowds' (professional programmers and casual programmers),
+I formally propose the creation of comp.lang.javascript for discussion
+of everything related to the JavaScript scripting language.
+
+At this point in time, with JavaScript still in Beta test, the amount
+of JavaScript related postings to comp.lang.java is &quot;acceptable&quot; by
+most. However, as JavaScript reaches completion, there will need to be
+a place for it's separate discussion.
+
+Truthfully, the JavaScript newsgroup could fit into a number of UseNet
+heirarchies, but I think the moderator of comp.infosystems.www.announce
+(M. L. Grant) explained it best when he said:
+
+&quot;...since javascript is different from java itself, it should be
+in its own hierarchy. A sixteenth comp.infosystems.www.* newsgroup
+is not needed; and putting it in the java groups will encourage the
+same confusion that comp.windows endures (HINT: the group is *not*
+about Microsoft operating systems).&quot;
+
+CHARTER: comp.lang.javascript
+
+The proposed comp.lang.javascript will be open to discussion on all
+aspects of JavaScript, as it relates to HTML, Java, Perl, the World
+Wide Web in general, and other related languages. The scope of
+discussion will specifically exclude matters which are *solely*
+related to Sun Microsystems, Inc.'s Java language, which should be
+discussed in comp.lang.java.
+
+END CHARTER.
+
+HOW TO VOTE:
+
+Send E-MAIL (posts to a newsgroup are not votes) to:
+
+ voting@ntrs.com
+
+Replying to this article should work, but check the address before you mail
+your vote. Your mail message must contain one and only one of the following
+vote statements for each group:
+
+ I vote YES on comp.lang.javascript
+ I vote NO on comp.lang.javascript
+
+Names are required for this vote. The counting software will extract your name
+from the mail message if your mailer is properly configured; if your mail
+software does not indicate your name, you must include the following statement:
+
+ Voter name: Your name here
+
+You can also vote ABSTAIN or CANCEL. These votes are not counted in the
+results, and CANCEL removes your name from the vote listing in the result.
+
+Vote counting is automated. Failure to follow these directions may mean that
+your vote does not get counted. If you do not receive an acknowledgment of
+your vote within three days contact the votetaker about the problem. IT'S YOUR
+RESPONSIBILITY TO MAKE SURE YOUR VOTE IS REGISTERED CORRECTLY.
+
+If you wish to change your vote, simply vote again from the same account;
+duplicate votes are resolved in favor of the most recent vote.
+
+THIS IS NOT A SECRET VOTE. Names, addresses, and votes will be published in
+a RESULTS article in the same newsgroups in which this CFV appears.
+
+The purpose of a Usenet vote is to determine if there is sufficient interest in
+the Usenet community to create a new newsgroup. Soliciting votes from
+disinterested parties defeats this purpose. Please do not distribute this CFV;
+direct people to the CFV in news.announce.newgroups. Distributing pre-marked
+or edited copies of this CFV is prohibited, and votes from such sources will be
+removed from the final vote total.
+
+Standard Guidelines for voting apply. One person, one vote. Votes must be
+mailed directly from the voter to the votetaker. Anonymous, forwarded or proxy
+votes are not valid. Votes mailed by WWW servers are considered to be
+anonymous votes.
+</pre>
+
+<p>
+In my opinion the charter says little that isn't obvious, but it
+also exhibits symptoms of its historic origin; an attempt to avoid
+javascript questions being asked in comp.lang.java groups. 50% of
+the charter's text being devoted to excluding the discussion of the
+Java language
+</p>
+
+<p>
+In a modern context the subject of the group is interpreted as being
+all ECMAScript implementations as that is the standard that
+JavaScript (TM) now implements, and it is the implementation of that
+standard that allows other languages to be categorised as javascript.
+</p>
+
+<p>
+No applications of javascript/ECMAScript are excluded from discussion
+on the group, and the group's apparent bias towards web browser
+scripting for the Internet is a consequence of the historical origin
+of the language, and the fact that browser scripting remains its most
+common application.
+</p>
+
+<p id="rToc">
+<a href="faq_notes.html#toc">comp.lang.javascript FAQ notes T.O.C.</a>
+</p>
+
+</body>
+</html>
\ No newline at end of file
/trunk/cljs/faq_notes/cljs_charter.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/faq_notes/faq_notes.css
===================================================================
--- trunk/cljs/faq_notes/faq_notes.css (nonexistent)
+++ trunk/cljs/faq_notes/faq_notes.css (revision 45)
@@ -0,0 +1,51 @@
+P CODE, LI CODE {
+ background-color:#FFFFDD;
+ color:#000000;
+ padding:0;
+ margin:0;
+}
+BLOCKQUOTE {
+ background-color:#EEEEFF;
+ color:#000000;
+ padding:0.5em;
+}
+BLOCKQUOTE DD PRE, BLOCKQUOTE DD CODE {
+ background-color:#EEEEFF;
+ color:#000000;
+ border:#EEEEFF 0px none;
+ margin:0.5em;
+ padding:0;
+}
+BLOCKQUOTE DT {
+ font-weight:bold;
+ margin-bottom:0.5em;
+}
+.commentJS {
+ background-color:#FFFFCC;
+ color:#004800;
+}
+.person {
+ font-weight:bold;
+}
+.fn {
+ text-align:left;
+ color:#B00000;
+ }
+.ob {
+ color:#AA6500;
+}
+.st {
+ color:#0000DD;
+}
+.nm {
+ color:#006000;
+ }
+.bl{
+ color:#003444;
+}
+.un {
+ color:#666666;
+}
+DL {
+ MARGIN-TOP: 0.5em; FONT-SIZE: 100%; MARGIN-BOTTOM: 0.5em; MARGIN-LEFT: 2.5em
+}
\ No newline at end of file
/trunk/cljs/faq_notes/faq_notes.css
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/faq_notes/alt_dynwrite.html
===================================================================
--- trunk/cljs/faq_notes/alt_dynwrite.html (nonexistent)
+++ trunk/cljs/faq_notes/alt_dynwrite.html (revision 45)
@@ -0,0 +1,569 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en"><head><title>An Alternative DynWrite function</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<link href="../faq.css" rel="stylesheet" type="text/css">
+<link href="faq_notes.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+
+<h1><a name="alDynWr" id="alDynWr">An Alternative DynWrite function</a></h1>
+
+<ul>
+ <li><a href="#DynWr">The DynWrite function.</a></li>
+ <li><a href="#getEl">Element retrieval given the element ID as a string.</a></li>
+ <li><a href="#innHTest">innerHTML Testing Strategy.</a></li>
+ <li><a href="#AltDynWr">Alternative DynWrite function.</a></li>
+</ul>
+
+
+<h2><a name="DynWr" id="DynWr">The Original DynWrite function.</a></h2>
+
+<p id="DynWr_1">
+<a href="http://jibbering.com/faq/#FAQ4_15">The quick answer in section
+4.15 of the FAQ</a> defines a function called <code>DynWrite</code> that will insert <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>
+content into an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page by writing a string of <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> to the <code>innerHTML</code>
+property of an IDed element, but only on browsers that fully support
+the (Microsoft IE originated) <code>innerHTML</code> extension.
+</p>
+
+<p id="DynWr_2">
+On browsers that do not provide a suitable mechanism for accessing the
+element, do not implement the <code>innerHTML</code> extension and browsers that
+implement <code>innerHTML</code> as a read-only property (along with Javascript
+incapable/disabled browsers) no content will be inserted with this
+function.
+</p>
+
+<p id="DynWr_3">
+On browsers that lack the element retrieval mechanism the <code>DynWrite</code>
+function is created as a simple function that just returns false. That
+would allow code that called <code>DynWrite</code> to check the value returned from
+a call to <code>DynWrite</code> and, if it was false, know that there would be no
+point in continuing to use the function as content will never be
+inserted into the document.
+</p>
+
+<p id="DynWr_4">
+Unfortunately the other branch, when an element retrieval mechanism is
+available, produces a function that will retrieve the element and write
+to its <code>innerHTML</code> property, returning true. On the browsers that do not
+implement, or fully implement, <code>innerHTML</code> this action should have no
+harmful side effects, merely creating a new <code>innerHTML</code> property on the
+element in browsers that do not implement the extension at all and
+leaving read-only <code>innerHTML</code> properties unchanged. But the true return
+value cannot be taken as an indicator of the success of the action.
+</p>
+
+<p id="DynWr_5">
+Ideally the return value from <code>DynWrite</code> should be a reasonable
+indicator of the success of the attempt to insert contents into the
+<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> as that would facilitate controlled degradation on un-supporting
+browsers.
+</p>
+
+<p id="DynWr_6">
+However, it is necessary to have a reference to an element in order
+to examine it to see if it does support <code>innerHTML</code> and the testing
+would alter the contents of that element (though possibly only
+temporarily). As a page loads elements usually become available
+(or, at least, referencable) after their opening <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> tag has been
+parsed, so code defined (or imported) in the HEAD section of a page
+could access the <code><span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span></code> element and the <code>HEAD</code> element along with,
+possibly, the <code>TITLE</code> and any other preceding elements.
+</p>
+
+<p id="DynWr_7">
+It would be theoretically possible acquire a reference to one of
+these elements and determine whether it has an <code>innerHTML</code> property
+and maybe then attempt to write to it to see if that had the desired
+effect. In reality there is at least one <code>innerHTML</code> supporting
+browser that will allow the dynamic modification of the content of
+any element within the BODY but generates run-time errors if an
+attempt is made to test, read or modify the <code>innerHTML</code> property of
+elements within the HEAD. That rules out examining the elements
+within the HEAD for <code>innerHTML</code> support and means that when <code>DynWrite</code>
+is initially configured it cannot know whether it is going to be
+effective or not.
+</p>
+
+<p id="DynWr_8">
+It would, in principle, be possible to write the <code>DynWrite</code> functions
+so that it tests the element that it is asked to insert <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> into
+prior to making the attempt so that it could act (or not) and then
+return true/false based on the result of those tests. But that would
+be inefficient as it would require that the test be carried out on
+every invocation of <code>DynWrite</code>. Iit may also be visually undesirable as
+the testing strategy (described below) involves setting the <code>innerHTML</code>
+to a test value resulting in two <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> modification per write operation
+(which may become visually apparent).
+</p>
+
+<p id="DynWr_9">
+An alternative is to exploit the flexibility of Javascript by
+initially assigning a function to <code>DynWrite</code> that could carry out
+the required tests and then re-assign <code>DynWrite</code> to a function that
+returned a true/false value that more accurately reflected the
+browser's support for the <code>innerHTML</code> extension. Allowing the tests
+to be performed on an element that should be available at the time
+of the test and the content of which is intended that it be replaced
+so it will not matter if it is replaced with the test value because
+if it was successfully replaced for the test it would then be
+re-replaced with the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> that was intended to be inserted. It also
+allows the test to only be performed once as success or failure on
+the first attempt should indicate the same outcome on subsequent
+attempts.
+</p>
+
+<p id="DynWr_10">
+<code>DynWrite</code> is initially configured based on the browser's apparent
+ability to retrieve a reference to a DOM element given its ID in
+the form of a string. On modern browsers the document.getElementById
+function can be used to return a reference to an element given the
+ID as a string. Older browsers may not implement the getElementById
+function, but some may provide an alternative mechanism such as
+document.all.
+</p>
+
+<h2><a name="getEl" id="getEl">Element retrieval given the element ID as a string.</a></h2>
+
+<p id="getEl_1">
+Several approaches can be taken towards maximising the ability
+to retrieve references to DOM elements.
+</p>
+
+<p id="getEl_2">
+1. Writing a general element retrieval function such as:-
+</p>
+
+<pre id="getEl_ex1">
+function getElementWithId(id){
+ var obj = null;
+ if(document.getElementById){
+ <span class="commentJS">/* Prefer the widely supported W3C DOM method, if
+ available:-
+ */</span>
+ obj = document.getElementById(id);
+ }else if(document.all){
+ <span class="commentJS">/* Branch to use document.all on document.all only
+ browsers. Requires that IDs are unique to the page
+ and do not coincide with NAME attributes on other
+ elements:-
+ */</span>
+ obj = document.all[id];
+ }
+ <span class="commentJS">/* If no appropriate element retrieval mechanism exists on
+ this browser this function always returns null:-
+ */</span>
+ return obj;
+}
+</pre>
+
+<p id="getEl_3">
+2. Assigning one of many functions tailored to element retrieval on
+the current browser to a global variable that can then be used to
+call the element retrieval function.
+</p>
+
+<pre id="getEl_ex2">
+var getElementWithId;
+if(document.getElementById){
+ <span class="commentJS">/* Prefer the widely supported W3C DOM method, if
+ available:-
+ */</span>
+ getElementWithId = function(id){
+ return document.getElementById(id);
+ }
+}else if(document.all){
+ <span class="commentJS">/* Branch to use document.all on document.all only
+ browsers. Requires that IDs are unique to the page
+ and do not coincide with NAME attributes on other
+ elements:-
+ */</span>
+ getElementWithId = function(id){
+ return document.all[id];
+ }
+}else{
+ <span class="commentJS">/* No appropriate element retrieval mechanism exists on
+ this browser. So assign this function as a safe dummy.
+ Values returned form calls to getElementWithId probably
+ should be tested to ensure that they are non-null prior
+ to use anyway so this branch always returns null:-
+ */</span>
+ getElementWithId = function(id){
+ return null;
+ }
+}
+</pre>
+
+<p id="getEl_4">
+3. Using a feature of a browser to emulate getElementById on a browser
+that does not implement it. So that getElementById can be used as a
+general element reference retrieval method.
+</p>
+
+<pre id="getEl_ex3">
+<span class="commentJS">/* Emulate getElementById on document.all only browsers. Requires
+ that IDs are unique to the page and do not coincide with NAME
+ attributes on other elements:-
+*/</span>
+if((!document.getElementById) &amp;&amp; document.all){
+ document.getElementById = function(id){return document.all[id];};
+}
+</pre>
+
+<p id="getEl_5">
+The reason for the comment about the use of ID and NAME attributes is
+that the <code>document.all</code> collection does not have exactly
+analogous behaviour with the <code>document.getElementById</code> method.
+If multiple elements have the same ID (or share an ID with the NAME of
+other elements) then <code>document.all</code> returns a collection
+instead of an individual element, while <code>document.getElementById</code>
+only ever returns an individual element or <code>null</code>. However,
+ID attributes are supposed to be unique to an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page if that page
+is valid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> 4 so multiple identical IDs should not be a problem.
+The issue with IDs coinciding with NAMEs remains, though it would not
+be good <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> design to provoke that problem.
+</p>
+
+<p id="getEl_6">
+Also, when a string used to refer to a property of the <code>document.all</code>
+collection does not refer to an element or a collection of elements
+<code>undefined</code> is returned by the above function. In most
+type-converting tests <code>undefined</code> and <code>null</code>
+behave the same (they both convert to boolean <code>false</code>)
+so the distinction is not necessarily important.
+</p>
+
+<p id="getEl_7">
+However, a more cautious but slower getElementById emulation could be
+used. Including tests that ensure that its behaviour exactly matched
+the W3C getElementById method.
+</p>
+
+<pre id="getEl_ex4">
+<span class="commentJS">/* Emulate getElementById on document.all only browsers. */</span>
+if((!document.getElementById) &amp;&amp; document.all){
+ document.getElementById = function(id){
+ var tempEl = null, el = document.all[id];
+ if(el){ <span class="commentJS">//document.all returned something.</span>
+ if((!el.id)||(el.id != id)){
+ <span class="commentJS">/* Either this is a collection or the only element
+ available under the property name provided as the
+ - id - parameter is a named element:
+ */</span>
+ if(el.length){ <span class="commentJS">//assume it is a collection.</span>
+ <span class="commentJS">/* But it might be an element with a NAME
+ corresponding with the id parameter that has
+ collection-like behaviour such as a form or a
+ select element so proceed with caution:
+ */</span>
+ for(var c = 0;c &lt; el.length;c++){
+ if((el[c].id)&amp;&amp;(el[c].id == id)){
+ <span class="commentJS">/* Set tempEl to the first match and
+ break out of the - for - loop:
+ */</span>
+ tempEl = el[c];
+ break;
+ }
+ }
+ <span class="commentJS">/* el will be set to null if the loop did not
+ find an element with the corresponding ID
+ because the default null value of tempEl
+ will not have changed:
+ */</span>
+ el = tempEl;
+ }else{ <span class="commentJS">//only a named element is available for id.</span>
+ <span class="commentJS">/* getElementById should not return named elements
+ only an IDed element so set el to null:
+ */</span>
+ el = null;
+ }
+ } <span class="commentJS">//else we have our element (the ID matches).</span>
+ }else{ <span class="commentJS">//el is undefined so make it null;</span>
+ el = null;
+ }
+ <span class="commentJS">/* The returned value will be the first element confirmed as
+ having the corresponding ID or it will be null:
+ */</span>
+ return el;
+ };
+}
+</pre>
+
+<p id="getEl_8">
+One of the consequences of creating a function to emulate
+<code>getElementById</code> is that other scripts that use the
+existence of <code>document.getElementById</code> to infer the
+existence of features of the browser beyond the getElementById method
+may wrongly infer that a browser that is provided with the emulation
+may have features that it does not have (unless they have also been
+emulated). This should not be a problem as using a test on one feature
+to infer the existence of other features is a <strong>fatally flawed
+technique</strong>, the use of which <strong>is discouraged</strong>.
+</p>
+
+<p id="getEl_9">
+I will be using the third approach, emulating the
+<code>document.getElementById</code> method, in the modified
+<code>DynWrite</code> function (with notes on what would differ
+with either of the first two).
+</p>
+
+<h2><a name="innHTest" id="innHTest">innerHTML Testing Strategy.</a></h2>
+
+<p id="innHTest_1">
+Initially testing an element to see if <code>innerHTML</code> is supported simply
+involves using the <code>typeof</code> operator to see if it returns
+<code>&quot;string&quot;</code>. That test will identify browsers such as Opera 6,
+where the <code>innerHTML</code> property is undefined.
+</p>
+
+<p id="innHTest_2">
+The second test is based on the fact that when the <code>innerHTML</code> property
+of an element is read on a supporting browser the value returned is
+normalised <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> and not the literal <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> source code. However, all
+browsers seem to take a different attitude when generating that
+normalised source. So given the original <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> source:-<br><code>&lt;td
+CLASS=&quot;obj&quot;&gt;&lt;U&gt;firstChild&lt;/U&gt;&lt;/td&gt;</code><br>
+the corresponding <code>innerHTML</code> of the parent element reads <br><code>&lt;TD
+CLASS='obj'&gt;&lt;U&gt;firstChild&lt;/U&gt;&lt;/TD&gt;</code><br> on
+Opera 7.11, <br><code>&lt;TD class=obj&gt;&lt;U&gt;firstChild&lt;/U&gt;&lt;/TD&gt;
+</code><br> on IE 5.0 and <br><code>&lt;td
+class=&quot;obj&quot;&gt;&lt;u&gt;firstChild&lt;/u&gt;&lt;/td&gt;
+</code><br> on Mozilla 1.2.
+</p>
+
+<p id="innHTest_3">
+None of these correspond with the original <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> but they are also
+different from each other. What is needed for the test is <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>
+source that all supporting browsers will return as different text
+from the source assigned. For that task a mixed case <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> string with additional
+unnecessary whitespace characters is used. That test <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> is appended
+to the original <code>innerHTML</code> value to ensure that the test string will
+never be equivalent to either the original <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> or the normalised
+result of reading the innnerHTML property after the assignment, even
+by accident. The fact that the browser has normalised the source is
+taken as indicating that the browser supports the <code>innerHTML</code> extension.
+</p>
+
+<p id="innHTest_4">
+After writing the test <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> to the <code>innerHTML</code> property it is possible
+to determine whether the property is read only by comparing a stored
+copy of the original value against the retrieved value. This is also
+necessary because otherwise the fact that the returned <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> does not
+correspond with the testHTML would be taken as indicating that
+it had been normalised.
+</p>
+
+<p id="innHTest_5">
+Finally, it is necessary to determine whether inserting the test
+<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> has added the element that it defines to the DOM for the page.
+</p>
+
+<p id="innHTest_6">
+When those tests are passed correctly the <code>DynWrite</code> function can be
+replaced with a new function that does not bother repeating the tests
+for subsequent assignments to <code>innerHTML</code>. If the tests are failed
+then the <code>DynWrite</code> function replaces itself with one that does no
+more than return false to indicate its failure.
+</p>
+
+<h2><a name="AltDynWr" id="AltDynWr">Alternative DynWrite function.</a></h2>
+
+<p id="AltDynWr_1">
+The modified, and commented, alternative <code>DynWrite</code> function
+incorporating these tests is as follows:-
+</p>
+
+<pre id="AltDynWr_ex1">
+<span class="commentJS">/* As written here, to support older browsers like IE 4, the emulation
+ of getElementById MUST HAVE BEEN EXECUTED _PRIOR_ TO THE FIRST CALL
+ TO THIS FUNCTION. If either of the alternative element retrieval
+ methods are to be used the noted changes also need to be made to
+ this function and the alternative method MUST have been set-up
+ prior to the first use of this function.
+*/</span>
+function DynWrite(id, S){<span class="commentJS"> //Generates a successor when first called!</span>
+ <span class="commentJS">/* Define local variables:-
+ */</span>
+ var testH, newH, inH, testID;
+ <span class="commentJS">/* Set the default value for the body text of the function that
+ will be created to replace this function as the DynWrite
+ function:-
+ */</span>
+ var funcBody = &quot;return false;&quot;
+ <span class="commentJS">/* This ensures that getElementById is available (or emulated)
+ on this browser prior to calling it:-
+ */</span>
+ var el = (document.getElementById)?document.getElementById(id):null;
+ <span class="commentJS">/* If one of the other element retrieval strategies was used,
+ creating a getElementWithId function, then because that function
+ will return null when an element cannot be found, it is
+ practical to just call that function as -
+ var el = getElementWithId(id);
+ - as subsequent tests result in an appropriate response.
+ */</span>
+ <span class="commentJS">/* This ensures that the referenced element has been successfully
+ retrieved and tests to verify that its innerHTML property is
+ a string (as opposed to being undefined):-
+ */</span>
+ if((el)&amp;&amp;(typeof el.innerHTML == 'string')){
+ <span class="commentJS">/* Arbitrary string to use as an ID for an element that
+ should be created as a result of writing to the innerHTML
+ value (The string itself and the result of concatenating it
+ to itself (repeatedly) should follow the rules for valid
+ <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> ID attributes):-
+ */</span>
+ testID = &quot;tSt&quot;;
+ <span class="commentJS">/* This ensures that the test ID is not in use on the page by
+ modifying it until an element cannot be retrieved using it:-
+ */</span>
+ while(document.getElementById(testID)){
+ <span class="commentJS">/* If the getElementWithId function is being used instead
+ of the getElementById emulation then the preceding test
+ must also use that function.
+ */</span>
+ testID += testID;
+ }
+ inH = el.innerHTML; <span class="commentJS">//Read the original innerHTML value.</span>
+ <span class="commentJS">/* The following mixed case <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> string is _not_ an error.
+ */
+ /* Note also that the STRONG element inserted in the page
+ contains the text "test", which may momentarily be
+ visible to the user. It would probably not be a good
+ idea to have no contents in the STRONG at all but &amp;nbsp;
+ could be used to reduce the potential visual impact:-
+ */</span>
+ newH = inH+&quot;&lt;sTrOnG Id='&quot;+testID+&quot;' &gt;test&lt;\/StRoNg &gt;&quot;;
+ el.innerHTML = newH; <span class="commentJS">//Assumes synchronous update of DOM.</span>
+ testH = el.innerHTML; <span class="commentJS">//Read innerHTML back for examination.</span>
+ if((testH != newH)&amp;&amp; <span class="commentJS">//Apparently normalised or unchanged.</span>
+ (testH != inH)&amp;&amp; <span class="commentJS">//Not unchanged (Not read-only).</span>
+ (document.getElementById(testID))){ <span class="commentJS">//Element found in DOM.</span>
+ <span class="commentJS">/* If the getElementWithId function is being used instead
+ of the getElementById emulation then the preceding test
+ must also use that function.
+ */</span>
+ <span class="commentJS">/* TESTS PASSED! Replace the default function body string
+ with code that will set the innerHTML property of the
+ element and return true, based on the assumption that
+ the assignment will be successful because this test was
+ sucessful:-
+ */</span>
+ funcBody =
+ &quot;document.getElementById(id).innerHTML=S; return true&quot;;
+ <span class="commentJS">/* See additional notes[1] on the function body to use at
+ this point.
+ */</span>
+ }
+ }
+ <span class="commentJS">/* Replace the DynWrite function with one determined by the results
+ of the tests:-
+ */</span>
+ DynWrite = new Function(&quot;id&quot;, &quot;S&quot;, funcBody);
+ <span class="commentJS">/* Call the newly created DynWrite function and return its return
+ value as the return value for this function call:-
+ */</span>
+ return DynWrite(id, S);
+}
+<span class="commentJS">/* [1] Notes on the body string to use if the tests are passed:-
+ The existing function body string relies on the use of
+ the getElementById emulation approach to retrieving DOM element
+ with an ID. If the getElementWithId function was used the
+ appropriate equivalent body string would be:-
+
+&quot;getElementWithId(id).innerHTML = S;return true;&quot;
+
+ However, if the ID passed as a parameter to DynWrite does not
+ correspond with an existing IDed element then either of these two
+ options would result in a function that would generate run-time
+ errors. For development that is probably a good thing as the
+ resulting error should be corrected in either the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> or the
+ script code by ensuring that the ID string provided does refer to a
+ uniquely identified DOM element. On the other hand, having fully
+ tested the code, the body string might be best swapped in deployed
+ code to a more cautious version that checked the result of the
+ element retrieval call to ensure that it is a non-null object:-
+
+&quot;var el=document.getElementById(id);if(el){el.innerHTML=S;}return true;&quot;
+
+ - with the getElementById emulation or:-
+
+&quot;var el=getElementWithId(id);if(el){el.innerHTML=S;}return true;&quot;
+
+ - with the getElementWithId function.
+
+ These function body strings are still returning true. How
+ suited that is to the situation would depend on how the code
+ intended to respond to the return value. The inability to resolve
+ one ID does not indicate that innerHTML would not available on
+ others if they could be resolved so code that decides to stop
+ attempting to write to innerHTML upon the first false return
+ value might be better off using the previous strings. Code that
+ wanted to fall-back based on each attempt to write to innerHTML
+ would be better using a function body string that returned
+ true/false based on the success of each individual attempt. For
+ the body string that tests to ensure that the element reference
+ is recovered a boolean return value based on the success of the
+ element retrieval would be best suited. That is simplest achieved
+ with a double NOT operator - return !!el; - . A null value of
+ - el - would return boolean false and an element reference would
+ return true due to type-converting forced by the NOT operator:-
+
+&quot;var el=document.getElementById(id);if(el){el.innerHTML=S;}return !!el;&quot;
+
+ - with the getElementById emulation or:-
+
+&quot;var el=getElementWithId(id);if(el){el.innerHTML=S;}return !!el;&quot;
+
+ - with the getElementWithId function.
+
+*/</span>
+</pre>
+
+<p id="AltDynWr_2">
+This design of the function does not involve any configuration tests
+as the page loads. It is one simple function definition. In principle
+calling the function with appropriate parameters will always return
+false if the content inserting is not possible and true otherwise.
+With the tests being performed only on the first invocation of the
+function.
+</p>
+
+<p id="AltDynWr_3">
+Given the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>: <code>&lt;div ID=&quot;anID&quot;&gt;old
+&lt;code&gt;HTML&lt;/code&gt;&lt;/div&gt;</code> examples of usage might be:-
+</p>
+
+<pre id="AltDynWr_ex2">
+if(!DynWrite(&quot;anID&quot;, &quot;new &lt;code&gt;HTML&lt;\/code&gt;&quot;)){
+ ... <span class="commentJS">// Handle the failure of the call to DynWrite.</span>
+}
+</pre>
+
+<p id="AltDynWr_4">
+- or -
+</p>
+
+<pre id="AltDynWr_ex3">
+if(DynWrite(&quot;anID&quot;, &quot;new &lt;code&gt;HTML&lt;\/code&gt;&quot;)){
+ ... <span class="commentJS">// Action following the success of the DynWrite call.</span>
+}else{
+ ... <span class="commentJS">// Handle the failure of the call to DynWrite.</span>
+}
+</pre>
+
+<p id="AltDynWr_5">
+It has been observed that IE 4 errors if DynWrite is called before the
+onload event is triggered by the browser. So to maximise cross-browser
+support for this function it would be better not to use it prior to that
+point.
+</p>
+
+<p id="rToc">
+<a href="faq_notes.html#toc">comp.lang.javascript FAQ notes T.O.C.</a>
+</p>
+
+
+</body>
+</html>
\ No newline at end of file
/trunk/cljs/faq_notes/alt_dynwrite.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/faq_notes/misc.html
===================================================================
--- trunk/cljs/faq_notes/misc.html (nonexistent)
+++ trunk/cljs/faq_notes/misc.html (revision 45)
@@ -0,0 +1,287 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en"><head><title>Miscellaneous Tricks and Tips</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<link href="../faq.css" rel="stylesheet" type="text/css">
+<link href="faq_notes.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+
+<h1><a name="mtHead" id="mtHead">Miscellaneous Tricks and Tips.</a></h1>
+
+<ol>
+ <!-- <li><a href="#mtSort">Sorting Arrays of objects by one of properties of those objects.</a></li> -->
+ <li><a href="#mtCSSUn">Setting the top and left values of positioned elements with <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> units, when needed</a></li>
+ <li><a href="#mtSetTI">Using function references with setTimeout and setInterval</a></li>
+</ol>
+<!--
+<h2><a name="mtSort" id="mtSort">Sorting Arrays of objects by one of properties of those objects.</a></h2>
+
+<p id="mtSort_1">
+Given an <code>Array</code> of like objects it may be necessary to sort
+that <code>Array</code> based on the value of one of the properties of
+those objects. The following functions are based on the results of a
+discussion between Evertjan and Lasse Reichstein Nielsen and are
+probably the shortest possible formulations of <code>&quot;comparefn&quot;</code>
+functions (as per ECMA 262 page 94) for use with the
+<code>Array.prototype.sort</code> method when sorting Arrays of objects
+by values held in one of their properties.
+</p>
+
+<pre id="mtSort_ex1">
+<span class="commentJS">/* These example function use the value of a property of the objects
+ called &quot;x&quot;. That property name would have to be changed if the
+ sorting was to be done by the value held under any other named. If
+ the object to be sorted are other Arrays then the dot notation
+ accessors - a.x - and - b.x - would have to be exchanged for Array
+ accessors - a[n] - and - b[n] - where - n - is the integer index of
+ the element being accessed.
+*/</span>
+<span class="commentJS">/* The object who's property holds the smallest value is placed first
+ in the Array returned by the Array.prototype.sort method:
+ a.x &lt; b.x returns +1
+ b.x &lt; a.x retains -1
+ a.x == b.x returns 0
+*/</span>
+function sortSmallFirst(a, b){
+ <span class="commentJS">/* If a.x == b.x then (a.x &lt; b.x) is false and (a.x &gt; b.x) is
+ false, the subtraction type converts false to zero and the
+ return value is (0 - 0) which is zero. If a.x &lt; b.x then
+ (a.x &lt; b.x) is true, and (a.x &gt; b.x) is false, the
+ subtraction type-converts them into the numbers one and zero
+ respectively and the return value is (1 - 0) which is plus
+ one. Finally, if a.x &gt; b.x then (a.x &lt; b.x) is false, and
+ (a.x &gt; b.x) is true, the subtraction type converts them to
+ the numbers zero and one respectively and the return value
+ is (0 - 1) which is minus one.
+ */</span>
+ return (a.x &lt; b.x) - (a.x &gt; b.x);
+}
+
+<span class="commentJS">/* The object who's property holds the largest value is placed first
+ in the Array returned by the Array.prototype.sort method:
+ a.x &lt; b.x returns -1
+ b.x &lt; a.x retains +1
+ a.x == b.x returns 0
+*/</span>
+function sortLargeFirst(a, b){
+ return (a.x &gt; b.x) - (a.x &lt; b.x);
+}
+
+<span class="commentJS">/* usage:-
+ var unsortedObjectArray = [
+ {x:2, y:'apple', z:5},
+ {x:3, y:'orange', z:7},
+ {x:89, y:'strawberry', z:9},
+ {x:45, y:'peach', z:3},
+ {x:8, y:'banana', z:9},
+ {x:1, y:'lemon', z:34}
+ ];
+
+ var sortedObjectArray = unsortedObjectArray.sort(sortLargeFirst);
+*/</span>
+</pre>
+ -->
+
+
+<h2><a name="mtCSSUn" id="mtCSSUn">Setting the top and left values of positioned
+ elements with <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> units, when needed</a></h2>
+
+<p id="mtCSSUn_1">
+When setting the position of a positioned element by assigning values
+to the <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> <code>top</code> and <code>left</code> properties of the
+element's <code>style</code> object it is necessary to provide the
+value as a string with the units of the length (usually &quot;px&quot;)
+following the value. Modern standards compliant browsers require this,
+older and more tolerant browsers may assume that values without units
+represent &quot;px&quot; units but they can handle string values which
+include the <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> units. Unfortunately some browsers want the
+<code>top</code> and <code>left</code> values provided as numbers and
+complain (or don't react) if they are provided as strings with units.
+</p>
+
+<p id="mtCSSUn_2">
+A technique for handling this requirement is based on the observation
+that when a browser expects the <code>top</code> and <code>left</code>
+values to be set as a number of pixels a <code>typeof</code> test of
+either the <code>top</code> or <code>left</code> properties will return
+&quot;number&quot; while if that same test returns &quot;string&quot;
+the browser either will require the <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> units to be appended to the
+values set as a string or it will successfully handle a value in that
+format.
+</p>
+
+<p id="mtCSSUn_3">
+Once the object on which the <code>top</code> and <code>left</code>
+values are to be set is available one of its <code>top</code> or
+<code>left</code> properties can be tested with <code>tyoeof</code>
+and an appropriately scoped variable set to either the string
+<code>&quot;px&quot;</code> or the number zero.
+</p>
+
+<pre id="mtCSSUn_ex1">
+var cssUnitsOrZero = (typeof styleObjectRef.top == 'string')?'px':0;
+</pre>
+
+<p id="mtCSSUn_4">
+Then when the position has been calculated (as a number) it can be
+assigned to the appropriate property with the value derived as the
+result of the test applied to it using the <code>+</code> operator.
+Because the <code>+</code> operator is a duel role addition and
+string concatenation operator, and decides which action it will take
+based on its operands, the application of the <code>+</code> operator
+to a position value as a number will depend on the type of the value
+derived from the preceding <code>typeof</code> test on the
+<code>top</code> or <code>left</code> properties.
+</p>
+
+<pre id="mtCSSUn_ex2">
+styleObjectRef.top = numericPosition + cssUnitsOrZero;
+
+<span class="commentJS">/* If the - numericPosition - value was 125, for example, and -
+ cssUnitsOrZero - was zero, the value assigned would be:-
+
+ styleObjectRef.top = (125 + 0);
+
+ - which is the number 125. If - cssUnitsOrZero - was &quot;px&quot; then
+ the assignment would be:-
+
+ styleObjectRef.top = (125 + &quot;px&quot;);
+
+ - which is the string &quot;125px&quot;.
+*/</span>
+</pre>
+
+<p id="mtCSSUn_5">
+If the tested top property was not a string <code>cssUnitsOrZero</code>
+will be the number zero and the <code>+</code> operator will have two
+numeric operands and will perform numeric addition, assigning a numeric
+value to the property, unmodified by the addition of zero. But if the
+tested property was a string, so <code>cssUnitsOrZero</code> was
+assigned the string value <code>&quot;px&quot;</code>, the
+<code>+</code> operator will recognise that one of its operands is a
+string and type-convert the other (the calculated position value) into
+a string and perform concatenation, appending the
+<code>&quot;px&quot;</code> <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> units string to the string
+representation of the calculated position and then assign that value to
+the property.
+</p>
+
+<p id="mtCSSUn_6">
+This fulfils the requirement to provide <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> units where needed while
+providing the vlaues in numeric form whenever that is the type of value
+expected. It is inefficient to perform the <code>typeof</code> test on
+a relevant property whenever a value is to be assigned, it is better to
+perform the test once and then re-use the same
+<code>cssUnitsOrZero</code> variable for all subsequent assignments.
+</p>
+
+
+
+<h2><a name="mtSetTI" id="mtSetTI">Using function references with setTimeout and setInterval</a></h2>
+
+<p id="mtSetTI_1">
+The <code>setTimeout</code> and <code>setInterval</code> functions
+provided by web browsers are commonly used with a string of javascript
+source code as their first argument, frequently a string that does no
+more than call a separately defined function:-
+</p>
+
+<pre id="mtSetTI_ex1">
+function invokedWithSetTimeout(){
+ ... <span class="commentJS">// do something.</span>
+}
+...
+var timer = setTimeout(&quot;invokedWithSetTimeout()&quot;, 100);
+</pre>
+
+<p id="mtSetTI_2">
+The string argument is interpreted and executed after the interval
+specified as the second argument (in milliseconds). In the preceding
+code the <code>invokeWithSetTimout</code> function would be called.
+</p>
+
+<p id="mtSetTI_3">
+On more recent browsers (easily the majority these days) the first
+argument to the<code> setTimeout</code> and <code>setInterval</code>
+functions can be a reference to a function. Instead of having to
+interpret and execute a string of javascript source code the function
+referred to is just executed after the interval. That will be more
+efficient as considerably smaller overhead would be involved in the
+execution of the function.
+</p>
+
+<pre id="mtSetTI_ex2">
+var timer = setTimeout(invokedWithSetTimeout, 100);
+</pre>
+
+<p id="mtSetTI_4">
+Unfortunately a number of older browsers such as IE 4 and Opera 5 do
+not understand the function reference versions of
+<code>setTimeout</code> and <code>setInterval</code>, leaving the use
+of string arguments as apparently the best method for cross-browser
+support. However, it is in the nature of loosely typed javascript that
+when a native code function such as <code>setTimeout/Interval</code> is
+expecting a string argument but is instead passed a value of another
+type that value will be type-converted into a string. That doesn't help
+much when the process of type-converting a function into a string
+results in an implementation dependent representation of the function,
+as is normally the case.
+</p>
+
+<p id="mtSetTI_5">
+Type-converting of a function to a string is done with the
+function's <code>toString</code> method, usually
+<code>Function.prototype.toString</code>. Methods of a
+<code>prototype</code> can be overridden by methods of the function
+object itself and an overriding <code>toString</code> method can return
+any value its creator desires. That fact provides a means of using the
+more efficient function reference arguments with
+<code>setTimeout/Interval</code> and still supporting browsers that can
+only handle string arguments, by assigning a custom
+<code>toString</code> method to the function that is referred to in the
+argument to <code>setTimeout/Interval</code>. That custom method would
+return the string that would have been used in the
+<code>setTimeout/Interval</code> function call. If the function
+reference is type-converted to a string that string represents the
+javascript source code that would be needed to invoke the function. If
+it is not type-converted then <code>setTimeout/Interval</code> can
+invoke the function directly (and without the overhead involved in
+interpreting and executing the string of source code).
+</p>
+
+<pre id="mtSetTI_ex3">
+function invokedWithSetTimeout(){
+ ... <span class="commentJS">// do something.</span>
+}
+<span class="commentJS">/* Assign a function expression to a toString property of the function
+ object referred to by the identifier - invokeWithSetTimeout -,
+ overriding - Funciton.prototype.toString -. The new toString
+ function returns the javascript source code needed to invoke a call
+ to the function.
+*/</span>
+invokedWithSetTimeout.toString = function(){
+ return &quot;invokedWithSetTimeout();&quot;;
+}
+...
+var timer = setTimeout(invokedWithSetTimeout, 100);
+<span class="commentJS">/* If the browser will only recognise string values as the first
+ argument to - setTimeout - then the function referred to by the
+ identifier - invokeWithSetTimeout - will be type-converted to a
+ string by calling its - toString - method, which will return the
+ string &quot; invokedWithSetTimeout();&quot; and that string will
+ be employed by the setTimeout function. Efectivly the same as
+ calling the setTimeout function as:-
+
+var timer = setTimeout(&quot;invokedWithSetTimeout()&quot;, 100);
+*/</span>
+</pre>
+
+
+
+
+<p id="rToc">
+<a href="faq_notes.html#toc">comp.lang.javascript FAQ notes T.O.C.</a>
+</p>
+
+</body>
+</html>
\ No newline at end of file
/trunk/cljs/faq_notes/misc.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/meta.xml
===================================================================
--- trunk/cljs/sections/meta.xml (nonexistent)
+++ trunk/cljs/sections/meta.xml (revision 45)
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Meta-FAQ meta-questions" ID="meta" NUMID="1">
+ <P>
+ This is the meta-FAQ for comp.lang.javascript. The latest
+ version is available at <URL>http://PointedEars.de/faq/</URL> in HTML form.
+ </P>
+<!--
+ <P>
+ Each day, one section of the <em>original</em> comp.lang.javascript FAQ, <VER/>,
+ is posted for review and questions, and as a reminder that the FAQ
+ is available.
+ </P>
+ -->
+ <P>
+ For additional explanation and detail relating to some aspects
+ of the FAQ, please see the
+ <URL LINKTEXT="FAQ Notes">notes/</URL>.
+ It has been provided separately to avoid increasing the size of
+ the FAQ to a point where it would be unreasonable to post it to
+ the group.
+ </P>
+ <P>
+ Code examples in this FAQ use <URL LINKTEXT="JSDoc Toolkit"
+ >https://code.google.com/p/jsdoc-toolkit/</URL> comments.
+ </P>
+
+ <CONTENT TITLE="Why this FAQ?" ID="why" NUMID="2_0">
+ <P>
+ This document is work in progress, intended to replace
+ the comp.lang.javascript FAQ that has gone unmaintained
+ since 2010-10-08 CE.
+ </P>
+ </CONTENT>
+
+ <CONTENT TITLE="Which newsgroups deal with javascript?" ID="newsgroups" NUMID="2_1">
+ <P>
+ The official Big 8 Usenet newsgroup dealing with javascript is
+ <NEWSGROUP>comp.lang.javascript</NEWSGROUP>.
+ Some "language" hierarchies also have *.comp.lang.javascript groups.
+ </P>
+ <P>
+ c.l.js is an unmoderated newsgroup.
+ </P>
+ </CONTENT>
+
+ <CONTENT TITLE="What questions are on-topic for comp.lang.javascript?" ID="appropriateQuestions" NUMID="2_2">
+ <P>
+ The comp.lang.javascript newsgroup deals with ECMAScript
+ languages, so any questions about JavaScript or JScript are
+ welcome. However, the majority of questions sent to this group
+ relates to javascript in a web browser. If you are experiencing
+ issues with a particular browser, or the host is not a browser
+ at all, please make this information clear.
+ </P>
+ <P>
+ Javascript and Java are two completely different languages.
+ Java questions should be asked in one of the comp.lang.java.*
+ newsgroups; they are not appropriate for c.l.js (as Java and
+ javascript are distinct programming languages with only
+ superficial similarities due to sharing a C-like syntax and
+ some of the characters in their names).
+ </P>
+ <P>
+ Questions dealing with other scripting languages, such as
+ VBScript, PerlScript or CGI scripting are also off-topic,
+ as are HTML-only or CSS-only questions.
+ </P>
+ <!--
+ <P>
+ Questions about the design of various javascript libraries are
+ appropriate; questions on how to <EM>use</EM> such libraries
+ are not. Check <URL LINKTEXT="c.l.js FAQ Resources"
+ >http://jibbering.comindex.html#libraryResources</URL> or search the web.
+ </P>
+ -->
+ <P>
+ Questions that are specific to Microsoft's JScript may also
+ be appropriately asked at:
+ <NEWSGROUP>microsoft.public.scripting.jscript</NEWSGROUP>
+ </P>
+ <P>
+ The comp.lang.javascript newsgroup charter is included in
+ <URL>faq_notes/cljs_charter.html</URL>.
+ </P>
+ </CONTENT>
+
+ <CONTENT TITLE="What should I do before posting to comp.lang.javascript?" ID="posting" NUMID="2_3">
+ <P>
+ Before posting to c.l.js, you should read this document.
+ You should also check the <URL LINKTEXT="Resources section">#onlineResources</URL>.
+ </P>
+ <LIST TYPE="UL" TITLE="How to Ask a Question" ID="ask">
+ <LI>State your question clearly and concisely.</LI>
+ <LI>Use the Subject: line to show the type of problem you have but
+ include the question in the body as well.</LI>
+ <LI>For a more detailed explanation of formatting, see
+ &quot;<URL LINKTEXT="Posting Questions and Replies to comp.lang.javascript">notes/posting/</URL>&quot;.</LI>
+ </LIST>
+
+ <LIST TYPE="UL" TITLE="Replying" ID="reply">
+ <LI>Quote only relevant parts of earlier messages, and add your
+ comments below each quoted section
+ (<URL LINKTEXT="FYI28/RFC1855">http://www.ietf.org/rfc/rfc1855.txt</URL>).</LI>
+ <LI>Link to specific sections of the FAQ that are relevant.</LI>
+ <LI>Avoid being unnecessarily rude, but do not complain about other rude posts.</LI>
+ <LI>Don't quote signatures.</LI>
+ </LIST>
+
+ <LIST TYPE="UL" TITLE="Posting Code" ID="postCode">
+ <LI>
+ Remove everything that does not contribute to the problem (images,
+ markup, other scripts, etc).
+ </LI>
+ <LI>Validate the HTML and CSS <URL>http://validator.w3.org/</URL>,
+ <URL>http://jigsaw.w3.org/css-validator/</URL>.</LI>
+ <LI>Make sure the code is executable as transmitted.</LI>
+ <LI>Format lines to 72 characters; indent with 2-4 spaces (not tabs).</LI>
+ <LI>State what you expect the code to do.</LI>
+ <LI>Mention the platforms, browsers, and versions.</LI>
+ <LI>See also the <URL LINKTEXT="FAQ section on debugging">#debugging</URL>.</LI>
+ <LI>Post in plain-text only. Do not encode it. Do not attach files.</LI>
+ <LI>If the code is more than about 100 lines, provide a URL in addition.</LI>
+ <LI>Do not multi-post; cross-post if necessary
+ (<URL LINKTEXT="Wikipedia description">http://en.wikipedia.org/wiki/Cross-post</URL>).</LI>
+ </LIST>
+ <LIST TYPE="UL" TITLE="What Not to Post" ID="doNotPost">
+ <LI>Do not post job postings. Job postings should go to
+ an appropriate regional jobs group.</LI>
+ <LI>Do not post copyright material without permission
+ from the copyright holder.</LI>
+ </LIST>
+ <P>
+ Relevant announcements are welcome, but no more often than once
+ per major release, as a short link to the product's webpage.
+ </P>
+ </CONTENT>
+
+ <CONTENT TITLE="Why was my post not answered?" ID="noAnswer" NUMID="2_4">
+ <P>This could be for several reasons:</P>
+ <UL>
+ <LI>It was a variation of a frequently asked question and was
+ therefore ignored by everyone.</LI>
+ <LI>Nobody knows the answer.</LI>
+ <LI>The person with the answer has not seen the post.</LI>
+ <LI>It might not be possible to do what you want to do but perhaps
+ readers of c.l.js are reluctant to answer your post in the negative
+ when they are not convinced that it cannot be done.</LI>
+ <LI>The question was not asked clearly enough, or did not included
+ enough information to be answered.</LI>
+ <LI>The questioner did not realise the need to read the group, for a
+ few days, to see the answers posted there.</LI>
+ <LI>You ignored the <URL LINKTEXT="section on posting">#posting</URL></LI>
+ </UL>
+
+ <p>If it is not one of these, then after a few days consider
+ reposting after checking
+ <URL>http://groups.google.com/group/comp.lang.javascript/topics</URL>
+ for replies. Make sure the post is phrased well, and everything
+ needed to answer is correct, and the subject is appropriate.</p>
+ </CONTENT>
+</CONTENT>
\ No newline at end of file
/trunk/cljs/sections/meta.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/suggestions.xml
===================================================================
--- trunk/cljs/sections/suggestions.xml (nonexistent)
+++ trunk/cljs/sections/suggestions.xml (revision 45)
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Comments and Suggestions" ID="comments" NUMID="14">
+ <P HTMLONLY="true">
+ This FAQ uses the CSS stylesheet <URL>faq.css</URL> and is generated
+ from the XML source <URL>index.xml</URL> using the XSLT stylesheet
+ <URL>index.xsl</URL><!-- which also checks the links -->.
+ </P>
+ <CONTENT TITLE="Why do some posts have &lt;FAQENTRY&gt; in them?" ID="FAQENTRY" NUMID="5_1">
+ <P>
+ If a poster feels that the question they are answering should be
+ covered in the FAQ, placing &lt;FAQENTRY&gt; in the post lets the FAQ
+ robot collect the messages for easy review and inclusion. A Draft Proposal
+ for the FAQ is requested and appreciated.
+ </P>
+ <P>
+The &lt;FAQENTRY&gt; should not be used in posts except in
+conjunction with a suggestion/proposal for this FAQ. It should
+also not be literally quoted in replies, instead it should be
+partly obscured as, e.g. &lt;FAQ**TRY&gt; or similar.
+ </P>
+ </CONTENT>
+ <CONTENT TITLE="How do I make a suggestion?" NUMID="5_2" ID="makeSuggestion">
+ <P>
+To make a suggestion to this FAQ, use either the FAQENTRY method
+above, or send e-mail to Thomas 'PointedEars' Lahn
+&lt;&#99;l&#106;s&#64;P&#111;i&#110;&#116;&#101;&#100;Ea&#114;&#115;&#46;&#100;&#101;&gt;
+(editor).
+All comments, suggestions, and especially corrections are welcome, and will be credited, where it is due, below.
+ </P>
+ </CONTENT>
+
+ <CONTENT TITLE="Contributors" ID="contributors">
+ <p>(non-exhaustive, in alphabetical order; see <a
+ href="http://PointedEars.de/wsvn/FAQs/trunk/cljs/?op=log&amp;isdir=1&amp;showchanges=1"
+ >changelog</a> for details)</p>
+ <ul>
+ <li>Andrew Poulos &lt;<a href="mailto:&#97;p&#95;pr&#111;g&#64;&#104;&#111;&#116;m&#97;i&#108;.com">ap&#95;pro&#103;&#64;h&#111;t&#109;&#97;il&#46;&#99;&#111;m</a>&gt;</li>
+ <li><a href="http://3-magi.net/">Christoph Michael Becker</a> &lt;<a href="mailto:&#99;m&#98;&#101;cke&#114;69@&#97;rco&#114;&#46;&#100;&#101;">&#99;&#109;be&#99;&#107;er&#54;9&#64;arco&#114;&#46;d&#101;</a>&gt;</li>
+ <li><a href="http://weppipakki.com/">Osmo Saarikumpu</a> &lt;<a href="mailto:o&#115;m&#111;@&#119;&#101;&#112;&#112;ipak&#107;&#105;&#46;c&#111;&#109;">osmo&#64;we&#112;&#112;i&#112;&#97;k&#107;i.c&#111;m</a>&gt;</li>
+ <li><a href="http://personx.tumblr.com/">Garrett Smith</a> &lt;<a href="mailto:&#100;h&#116;&#109;&#108;k&#105;&#116;&#99;h&#101;n&#64;g&#109;a&#105;&#108;&#46;com">d&#104;&#116;&#109;&#108;k&#105;t&#99;h&#101;n&#64;gma&#105;&#108;&#46;&#99;o&#109;</a>&gt;</li>
+ </ul>
+ </CONTENT>
+
+ <!-- FIXME -->
+ <!--
+ <P>
+ This FAQ is (C) Copyright Contributors on behalf of the
+ newsgroup comp.lang.javascript. Upon change of the FAQ maintainer,
+ the copyright will automatically pass over to the new maintainer.
+ </P>
+ -->
+ </CONTENT>
\ No newline at end of file
/trunk/cljs/sections/suggestions.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/windows.xml
===================================================================
--- trunk/cljs/sections/windows.xml (nonexistent)
+++ trunk/cljs/sections/windows.xml (revision 45)
@@ -0,0 +1,483 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Windows and Frames" ID="windows">
+ <P>
+ The <ICODE>window</ICODE> object (also referred to by <ICODE>self</ICODE>) is "DOM Level 0".
+ No formal standard for it exists.
+ </P>
+ <CONTENT TITLE="How can I disable the back button in a web browser?" ID="disableBackButton" NUMID="4_2">
+ <P>
+ You can't. The browser's history cannot be modified. However, you
+ can use <ICODE>self.location.replace(url);</ICODE> in some browsers to replace
+ the current page in the history.
+ </P>
+ <MOREINFO>
+ <URL>http://msdn.microsoft.com/en-us/library/ms536712%28VS.85%29.aspx</URL>
+ <URL>http://docs.sun.com/source/816-6408-10/location.htm#1194240</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I access a frame's content?"
+ ID="frameRef" NUMID="4_8">
+ <P>
+ To reference another frame on the <EM>same domain</EM>:
+ </P>
+ <P>
+ The <DFN>content window</DFN> of a <ICODE>FRAME</ICODE> or <ICODE>IFRAME</ICODE> can be
+ accessed by the <ICODE>frames</ICODE> collection.
+ </P>
+ <P>
+ Example:
+ </P>
+ <CODE>
+var fwin;
+fwin = self.frames[0]; // or:
+fwin = self.frames["iframeName"];
+ </CODE>
+ <P>or, from the <ICODE>IFRAME</ICODE> or <ICODE>FRAME</ICODE> element:</P>
+ <CODE>
+var iframeEl = document.getElementById("myFrame");
+var fwin = iframeEl.contentWindow; // Nonstandard, but widely supported.
+var fdoc = iframeEl.contentDocument; // DOM2 HTML Standard.
+ </CODE>
+ <P>
+ A global identifier <ICODE>moomin</ICODE> in the the iframe's <DFN>content window</DFN>
+ is accessed as <ICODE>fwin.moomin</ICODE>.
+ </P>
+ <P>
+ To communicate between frames on <EM>different</EM> domains:
+ </P>
+ <P>
+ Where supported, (IE8, Firefox 3, Opera 9, Safari 4), use
+ <ICODE>window.postMessage( message[, port], otherDomain);</ICODE>.
+ </P>
+ <P>
+ Example:
+ <URL>http://jibbering.com/faq/example/postMessage.html</URL>
+ </P>
+ <P>
+ Where <ICODE>window.postMessage</ICODE> is not supported, the <ICODE>window.name</ICODE> property
+ can be set on the other window, which can poll for updates to that
+ property using <ICODE>setInterval(checkWinName, 100);</ICODE> where <ICODE>checkWinName</ICODE>
+ is a function that polls to check the value of
+ <ICODE>self.name</ICODE>.
+ </P>
+ <MOREINFO>
+ <URL>http://en.wikipedia.org/wiki/Same_origin_policy</URL>
+ <URL>http://www-archive.mozilla.org/docs/dom/domref/dom_frame_ref5.html</URL>
+ <URL>https://developer.mozilla.org/en/DOM/window.postMessage</URL>
+ <URL>http://msdn.microsoft.com/en-us/library/cc197015(VS.85).aspx</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I find the size of the window?" ID="getWindowSize"
+ NUMID="4_9">
+ <P>
+ Here is a detailed explanation of a cross-browser strategy to
+ find the dimensions of the viewport, excepting all chrome
+ (excludes scrollbars, etc).
+ </P>
+ <P>
+ We can consider various properties:
+ </P>
+ <CODE>
+window.innerWidth
+document.clientWidth
+document.documentElement.clientWidth
+document.body.clientWidth
+ </CODE>
+ <P>
+ Of the browsers that have an <ICODE>innerWidth</ICODE> property, most
+ include scrollbar dimensions. Some versions of KHTML browsers
+ (including Safari 2) do <EM>not</EM> include scrollbar width.
+ </P>
+
+ <P>
+ The <ICODE>window.inner*</ICODE> properties are unreliable and not
+ useful here. We don't want scrollbar dimensions included.
+ </P>
+<CODE> document.clientWidth</CODE>
+ <P>
+ Certain versions of KHTML, including Safari 2, have
+ <ICODE>document.clientHeight</ICODE> and <ICODE>document.clientWidth</ICODE>
+ properties. Where supported, these rare properties accurately
+ return the height and width of the viewport, without including
+ scrollbar dimensions.
+ </P>
+ <CODE>
+document.documentElement.clientWidth
+document.body.clientWidth
+ </CODE>
+ <P>
+ MSHTML (Trident), Firefox (Gecko), Opera (Presto), and Safari
+ (Webkit) all support <ICODE>clientHeight</ICODE> on <ICODE>document.body</ICODE>
+ and <ICODE>document.documentElement</ICODE>. The difficulty is figuring out
+ which one is reliable. In other words which object to get the
+ <ICODE>clientHeight</ICODE> property from:<ICODE>documentElement</ICODE> or <ICODE>body</ICODE>?
+ </P>
+
+ <P>
+ What the number returned from either of these properties
+ represents depends on the environment. The environment includes
+ the browser, its version, and the rendering mode of the document.
+ In quirks mode, we'll mostly want to use <ICODE>body.clientHeight</ICODE>
+ (except for in Safari 2).
+ </P>
+ <CODE>document.body.clientHeight</CODE>
+ <P>
+ Some environments will return the viewport height. Others will
+ return <ICODE>0</ICODE>. Yet others will return the <ICODE>clientHeight</ICODE> of
+ the <ICODE>BODY</ICODE> element.
+ </P>
+ <CODE> document.documentElement.clientHeight</CODE>
+ <P>
+ This is the more "standard" property for getting the height of
+ the viewport. It usually "works" in modern browsers in
+ <DFN>standards mode</DFN>. Notable exceptions include Safari 2 and
+ Opera &lt;= 9.25, both of which return the <ICODE>clientHeight</ICODE>
+ of the <ICODE>html</ICODE> <EM>element</EM>. (Oddly, Opera &lt;= 9.25
+ in standards mode returns the width of the viewport for
+ <ICODE>documentElement.clientWidth</ICODE>).
+ </P>
+ <P>
+ With the exception of Safari 2, <ICODE>body.clientHeight</ICODE> is reliable
+ where <ICODE>documentElement.clientHeight</ICODE> is found to be unreliable.
+ For example, in Safari 3+, Opera, and Mozilla, all in quirks mode,
+ <ICODE>document.documentElement.clientHeight</ICODE> returns the <ICODE>clientHeight</ICODE>
+ of the <ICODE>html</ICODE> element (this may seem unsurprising but
+ it is not what we want).
+ </P>
+ <P>
+ Conversely, <ICODE>document.body.clientHeight</ICODE> will return
+ the height of the viewport in most cases where
+ <ICODE>document.documentElement.clientHeight</ICODE> does not. An exception
+ to that is Safari 2, where <ICODE>documentElement.clientHeight</ICODE>
+ and <ICODE>body.clientHeight</ICODE> both return the height of their
+ corresponding element (not what we want).
+ </P>
+ <P>
+ By using a combination of <DFN>Feature Testing</DFN> and <DFN>Capability Testing</DFN>,
+ the dimensions of the viewport can be strategically retrieved
+ from the property that works in the environment the script is
+ running in. The trick is determining which property will give us
+ the value we want.
+ </P>
+ <P>
+ Since <ICODE>document.clientHeight</ICODE> is reliable where
+ (rarely) supported, and since browsers that support this property
+ don't return the viewport dimensions from
+ <ICODE>document.body.clientHeight</ICODE> or
+ <ICODE>document.documentElement.clientHeight</ICODE>, this should be the
+ very first condition:
+ </P>
+ <CODE>
+// Safari 2 uses document.clientWidth (default).
+if(typeof document.clientWidth == "number") {
+ // use document.clientWidth.
+}
+ </CODE>
+ <P>
+ The next strategy is to determine if
+ <ICODE>document.documentElement.clientHeight</ICODE> property is unreliable.
+ It is deemed "unreliable" when it is either <ICODE>0</ICODE> or taller
+ than the viewport.
+ </P>
+ <P>
+ Determining if <ICODE>documentElement.clientHeight</ICODE> is <ICODE>0</ICODE> is easy.
+ The result is stored in a variable <ICODE>IS_BODY_ACTING_ROOT</ICODE>.
+ </P>
+ <CODE>
+var docEl = document.documentElement,
+ IS_BODY_ACTING_ROOT = docEl &amp;&amp; docEl.clientHeight === 0;
+docEl = null;
+ </CODE>
+ <P>
+ To determine if <ICODE>documentElement.clientHeight</ICODE> returns
+ a value taller than the viewport, we need a <DFN>Capability Test.</DFN>
+ </P>
+ <P>
+ If we can force <ICODE>documentElement</ICODE> to be very tall
+ (taller than a normal viewport) we can then check to see if
+ <ICODE>documentElement.clientHeight</ICODE> returns that "very tall" number.
+ If it does, then it is unreliable.
+ </P>
+ <P>
+ We can force <ICODE>documentElement</ICODE> to be taller than the viewport
+ (or any "normal" viewport) by adding a <ICODE>div</ICODE> to the <ICODE>body</ICODE>,
+ give that <ICODE>div</ICODE> a height larger than any normal monitor,
+ and then check to see if <ICODE>documentElement.clientHeight</ICODE> is
+ that high (or "almost" that high, to account for <ICODE>documentElement</ICODE>
+ having a border).
+ </P>
+ <CODE>
+// Used to feature test Opera returning wrong values
+// for documentElement.clientHeight.
+// The results of this function should be cached,
+// so it does not need to be called more than once.
+function isDocumentElementHeightOff(){
+ var d = document,
+ div = d.createElement('div');
+ div.style.height = "2500px";
+ d.body.insertBefore(div, d.body.firstChild);
+ var r = d.documentElement.clientHeight &gt; 2400;
+ d.body.removeChild(div);
+ return r;
+}
+ </CODE>
+ <P>
+ We can use this function to see if we should use
+ <ICODE>body.clientHeight</ICODE>, instead. (but only after checking if
+ <ICODE>document.clientHeight</ICODE> is supported).
+ </P>
+ <CODE>
+// Safari 2 uses document.clientWidth (default).
+if(typeof document.clientWidth == "number") {
+ // use document.clientHeight/Width.
+}
+else if(IS_BODY_ACTING_ROOT || isDocumentElementHeightOff()) {
+ // use document.body.clientHeight/Width.
+} else {
+ // use document.documentElement.clientHeight/Width.
+}
+ </CODE>
+ <P>
+ The preceding strategy was developed by Garrett Smith with input
+ from John David Dalton. A complete and tested example can be found
+ in APE Library under <ICODE>APE.dom.getViewportDimensions</ICODE>.
+ Source code:
+ <URL>http://wayback.archive.org/web/20110814142717/http://dhtmlkitchen.com/ape/build/dom/viewport-f.js</URL>.
+ APE is publicly released under Academic Free License.
+ APE home: <URL>http://wayback.archive.org/web/20110628160010/http://www.dhtmlkitchen.com/ape/</URL>.
+ </P>
+ <P>
+ Note: The dimensions cannot be determined accurately until after
+ the document has finished loading.
+ </P>
+ <MOREINFO>
+ <URL>http://msdn.microsoft.com/en-us/library/ms533566%28VS.85%29.aspx</URL>
+ <URL>http://developer.mozilla.org/en/DOM/window.innerWidth</URL>
+ <URL>http://dev.opera.com/articles/view/using-capability-detection/</URL>
+ </MOREINFO>
+ </CONTENT>
+
+ <CONTENT TITLE="How do I check to see if a child window is open, before opening another?"
+ ID="isWindowOpen" NUMID="4_10">
+ <CODE>
+var myWin;
+function openWin(aURL) {
+ if (!myWin || myWin.closed ) {
+ myWin = window.open(aURL,'myWin');
+ } else {
+ myWin.location.href = aURL;
+ myWin.focus();
+ }
+}
+ </CODE>
+ <P>
+ Popup windows cause usability problems and are generally best avoided.
+ </P>
+ <MOREINFO>
+ <URL>https://developer.mozilla.org/en/DOM:window.open</URL>
+ <URL>http://msdn.microsoft.com/en-us/library/ms533574%28VS.85%29.aspx</URL>
+ <URL>http://docs.sun.com/source/816-6408-10/window.htm#1201877</URL>
+ <URL>http://www.useit.com/alertbox/990530.html</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="Why does framename.print() not print the correct frame in IE?"
+ ID="printFrame" NUMID="4_11">
+ <P>
+ IE prints the frame that has focus when you call the print
+ method <ICODE>frameref.focus();frameref.print();</ICODE>
+ </P>
+ <MOREINFO>
+ <URL>http://msdn.microsoft.com/en-us/library/ms976105.aspx</URL>
+ </MOREINFO>
+ </CONTENT>
+
+ <CONTENT TITLE="How do I close a window and why does it not work on the first one?"
+ ID="windowClose" NUMID="4_14">
+ <P>
+ If a window was opened by javascript, then it can be closed
+ without confirmation by using <ICODE>windowRef.close()</ICODE>.
+ </P>
+ <P>
+ Before calling <ICODE>windowRef.close()</ICODE> (or other <ICODE>window</ICODE> methods), make
+ sure the window reference is not null and its <ICODE>closed</ICODE> property is <ICODE>false</ICODE>.
+ </P>
+ <P>
+ Popup windows cause usability problems and are generally best avoided.
+ </P>
+ <MOREINFO>
+ <URL>http://www.useit.com/alertbox/990530.html</URL>
+ <URL>#isWindowOpen</URL>
+ <URL>http://msdn.microsoft.com/en-us/library/ms536367%28VS.85%29.aspx</URL>
+ <URL>https://developer.mozilla.org/en/DOM/window.close#Description</URL>
+ <URL>http://docs.sun.com/source/816-6408-10/window.htm#1201822</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="Why do I get permission denied when accessing a frame/window?"
+ ID="permissionDenied" NUMID="4_19">
+ <P>
+ In the normal browser security model, a script may only access the
+ properties of documents served from the same domain or IP address,
+ protocol, and port.
+ </P>
+ <P>
+ Any attempt to access a property in such cases will result in a &quot;Permission
+ Denied&quot; error. Signed scripts or trusted ActiveX objects can
+ overcome this in limited situations.
+ </P>
+ <MOREINFO>
+ <URL>http://msdn.microsoft.com/en-us/library/ms533028%28VS.85%29.aspx</URL>
+ <URL>https://developer.mozilla.org/En/Same_origin_policy_for_JavaScript</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I make a 10 second delay?" ID="setTimeout" NUMID="4_20">
+ <P>
+ There is no built-in way to pause execution in javascript such
+ as a sleep function, but hosts usually provide a method of some
+ form. Web browsers are designed for event driven programming and
+ only provide the <ICODE>setTimeout</ICODE> and <ICODE>setInterval</ICODE> functions
+ to facilitate timed delays. The delay before calling <ICODE>getSnork</ICODE> may
+ exceed the second parameter to <ICODE>setTimeout</ICODE> and <ICODE>setInterval</ICODE>
+ due to implementation differences among browsers.
+ </P>
+ <P>
+ To call the function <ICODE>getSnork</ICODE>, approximately 10 seconds
+ after the function <ICODE>getMoomin()</ICODE> completes, you would do this:
+ </P>
+ <CODE>
+getMoomin();
+setTimeout(getSnork, 10000);
+ </CODE>
+ <P>
+ Script execution is not stopped, and adding <ICODE>getSnufkin()</ICODE> after the
+ <ICODE>setTimeout</ICODE> line would immediately execute the function <ICODE>getSnufkin</ICODE>
+ before <ICODE>getSnork</ICODE>.
+ </P>
+ <P>
+ Achieving delays through running a loop of some sort for a pre-defined
+ period is a bad strategy, as that will inhibit whatever was supposed to
+ be happening during the delay, including blocking user interation.
+ </P>
+ <P>
+ Other (less event driven) hosts have different wait functions,
+ such as <ICODE>WScript.Sleep()</ICODE> in the Windows Script Host.
+ </P>
+ <MOREINFO>
+ <URL>http://msdn.microsoft.com/en-us/library/ms536753%28VS.85%29.aspx</URL>
+ <URL>http://docs.sun.com/source/816-6408-10/window.htm#1203758</URL>
+ <URL>http://en.wikipedia.org/wiki/Event-driven_programming</URL>
+ <URL>faq_notes/misc.html#mtSetTI</URL>
+ </MOREINFO>
+ </CONTENT>
+
+ <CONTENT TITLE="How do I change print settings for window.print()?"
+ ID="printSettings" NUMID="4_23">
+ <P>
+ In a normal security environment, you can't change anything.
+ </P>
+ <P>
+ Print Stylesheet rules provide options.
+ </P>
+ <P>
+ For IE, <ICODE>ActiveX</ICODE> or Plugin ScriptX and
+ Neptune from Meadroid to give you more control for Windows
+ versions of Internet Explorer, Netscape, and Opera.
+ </P>
+ <MOREINFO>
+ <URL>http://www.meadroid.com/scriptx/</URL>
+ <URL>http://msdn.microsoft.com/en-us/library/ms976105.aspx</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I change the confirm box to say yes/no or default to cancel?"
+ ID="changeBrowserDialog" NUMID="4_28">
+ <P>
+ The buttons on a confirm box cannot be changed, nor can a default
+ button be specified.
+ </P>
+ <P>
+ Change the question to a statement so that "OK" is suitable as the
+ default response.
+ </P>
+ <P>
+ Example:
+ "Would you like us to charge your credit card?" (wrong)
+ "We will now charge your credit card." (right).
+ </P>
+ </CONTENT>
+ <CONTENT TITLE="How do I prompt a &quot;Save As&quot; dialog for an accepted mime type?"
+ ID="fileDownload" NUMID="4_33">
+ <P>
+ It is not possible with client-side javascript.
+ </P>
+ <P>
+ Some browsers accept the Content-Disposition header, but this
+ must be added by the server. Taking the form:-
+ <ICODE>Content-Disposition: attachment; filename=filename.ext</ICODE>
+ </P>
+ <MOREINFO>
+ <URL>http://classicasp.aspfaq.com/general/how-do-i-prompt-a-save-as-dialog-for-an-accepted-mime-type.html</URL>
+ <URL>http://support.microsoft.com/kb/q260519/</URL>
+ </MOREINFO>
+ </CONTENT>
+ <!-- Can we remove this entry?
+ http://groups.google.com/group/comp.lang.javascript/msg/c70b57d86300fa91
+
+ CONTENT TITLE="I have window.status=&quot;Moomin&quot;; why doesn't the statusbar change?"
+ ID="returnValue" NUMID="4_35">
+ <P>
+When changing the status in an event (e.g. <ICODE>onmouseover</ICODE>) you
+should return true from the event. Also a number of browsers
+require a short delay before setting the status to overcome their
+default behaviour with the statusbar.
+<ICODE>onevent=&quot;setTimeout('window.status=\'Moomin\'',15);&quot;</ICODE>
+ </P>
+ <P>
+Many browsers are configured, by default, to disallow scripts from setting
+the status bar text. Some browsers don't have such a bar, or don't have it by default.
+ </P>
+ </CONTENT-->
+
+ <CONTENT TITLE="How do I modify the current browser window?" ID="modifyChrome" NUMID="4_36">
+ <P>
+ In a default security environment you are very limited in how much
+ you can modify the current browser window. You can use
+ <ICODE>window.resizeTo</ICODE> or <ICODE>window.moveTo</ICODE> to resize or move a
+ window respectively, but that is it. Normally you can only
+ suggest chrome changes in a <ICODE>window.open</ICODE>.
+ </P>
+ <MOREINFO>
+ <URL>http://msdn.microsoft.com/en-us/library/ms536651%28VS.85%29.aspx</URL>
+ <URL>https://developer.mozilla.org/en/DOM:window.open</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I POST a form to a new window?" ID="target" NUMID="4_37">
+ <P>
+ Use the target attribute on the form, opening a window with
+ that name and your feature string in the onsubmit handler of the
+ FORM.
+ </P>
+ <CODE>
+&lt;form action=&quot;&quot; method="post"
+ target=&quot;wndname&quot; onsubmit=&quot;window.open('',this.target);return true;&quot;&gt;
+ </CODE>
+ <MOREINFO>
+ <URL>http://www.htmlhelp.com/reference/html40/forms/form.html</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I open a new window with javascript?" ID="openWindow" NUMID="4_42">
+ <P>
+ New windows can be opened on browsers that support the
+ <ICODE>window.open</ICODE> function and are not subject to the action of any
+ pop-up blocking mechanism with code such as:-
+ </P>
+ <CODE>
+var wRef;
+if(window.open){
+ wRef = window.open("http://example.com/page.html","windowName");
+}
+ </CODE>
+ <MOREINFO>
+ <URL>https://developer.mozilla.org/en/DOM:window.open</URL>
+ <URL>http://www.infimum.dk/HTML/JSwindows.html</URL>
+ </MOREINFO>
+ </CONTENT>
+</CONTENT>
\ No newline at end of file
/trunk/cljs/sections/windows.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/dom.xml
===================================================================
--- trunk/cljs/sections/dom.xml (nonexistent)
+++ trunk/cljs/sections/dom.xml (revision 45)
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="DOM and Forms" ID="domRef">
+ <CONTENT TITLE="How do I get the value of a form control?"
+ ID="formControlAccess" NUMID="4_13">
+ <P>
+ In HTML documents, a form may be referred to as a property of the
+ <ICODE>document.forms</ICODE> collection, either by its ordinal index or by name
+ (if the <ICODE>form</ICODE> has a name). A <ICODE>form</ICODE>'s controls may be similarly referenced
+ from its <ICODE>elements</ICODE> collection:
+ </P>
+ <CODE>
+var frm = document.forms[0];
+var control = frm.elements[&quot;elementname&quot;];
+ </CODE>
+ <P>
+ Once a reference to a control is obtained, its (string) <ICODE>value</ICODE>
+ property can be read:-
+ </P>
+ <CODE>
+var value = control.value;
+value = +control.value; //string to number.
+ </CODE>
+ Some exceptions would be:
+ <P>
+ First Exception: Where the control is a <ICODE>SELECT</ICODE> element, and
+ support for older browsers, such as NN4, is required:
+ </P>
+ <CODE>
+var value = control.options[control.selectedIndex].value;
+ </CODE>
+ <P>
+ Second Exception: Where several controls share the same name,
+ such as radio buttons. These are made available as collections
+ and require additional handling. For more information, see:-
+ </P>
+ <MOREINFO>
+ <URL>notes/form-access/</URL>
+ <URL LINKTEXT="Unsafe Names for HTML Form Controls">names/</URL>
+ </MOREINFO>
+ <P>
+ Third Exception: File inputs. Most current browsers do not allow
+ reading of <ICODE>type="file"</ICODE> input elements in a way that is useful.
+ </P>
+ </CONTENT>
+ <CONTENT TITLE="My element is named myselect[], how do I access it?" ID="propertyAccess" NUMID="4_25">
+ <P>
+Form controls with any &quot;illegal&quot; characters can be accessed with
+<ICODE>formref.elements[&quot;myselect[]&quot;]</ICODE> - The bracket characters,
+amongst others, are illegal in ID attributes and javascript
+identifiers, so you should try to avoid them as browsers may
+handle them incorrectly.
+ </P>
+ <MOREINFO>
+ <URL>http://msdn.microsoft.com/en-us/library/ms537449%28VS.85%29.aspx</URL>
+ <URL>https://developer.mozilla.org/en/DOM/form</URL>
+ <URL>notes/form-access/</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="Why doesn't the global variable &quot;divId&quot; always refer to the element with id=&quot;divId&quot;?"
+ ID="globalPollution" NUMID="4_41">
+ <P>
+ Microsoft introduced a shortcut that can be used to reference
+ elements which include an <ICODE>id</ICODE> attribute where the
+ <ICODE>id</ICODE> becomes a globally-accessible property. Some browsers reproduce
+ this behavior. Some, most notably Gecko-based browsers (Netscape and Mozilla),
+ do so only in "quirks" mode. The best approach is the <ICODE>document.getElementById</ICODE>
+ method, which is part of the W3C DOM standard and implemented
+ in modern browsers (including IE from version 5.0). So an
+ element with <ICODE>id=&quot;foo&quot;</ICODE> can be referenced
+ with:-
+ </P>
+ <CODE>
+var el = document.getElementById(&quot;foo&quot;);
+ </CODE>
+ <P>
+ Note: make sure not to use the same <ICODE>id</ICODE> twice in the same document
+ and do not give an element a <ICODE>name</ICODE> that matches an <ICODE>id</ICODE>
+ of another in the same document or it will trigger bugs in MSIE &lt;= 7 with
+ <ICODE>document.getElementsByName</ICODE> and <ICODE>document.getElementById</ICODE>.
+ </P>
+ <MOREINFO>
+ <URL>https://developer.mozilla.org/en/Using_Web_Standards_in_your_Web_Pages/Using_the_W3C_DOM#Accessing_Elements_with_the_W3C_DOM</URL>
+ <URL>faq_notes/faq_notes.html#FAQN4_41</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I modify the content of the current page?"
+ ID="updateContent" NUMID="4_15">
+ <P>
+ Using the non-standard but widely implemented
+ <ICODE>innerHTML</ICODE> property:
+ <ICODE>&lt;div id=&quot;anID&quot;&gt;Some Content&lt;/div&gt;</ICODE> with script:
+ </P>
+ <CODE>
+document.getElementById(&quot;anID&quot;).innerHTML =
+ &quot;Some &lt;em&gt;new&lt;/em&gt; Content&quot;;
+ </CODE>
+ <P>
+ Where <ICODE>&quot;anID&quot;</ICODE> is the (unique on the HTML page)
+ <ICODE>id</ICODE> attribute value of the element to modify.
+ </P>
+ <P>
+ All versions of Internet Explorer exhibit problems with innerHTML, including:
+ </P>
+ <LIST TYPE="UL">
+ <LI>Fails with FRAMESET, HEAD, HTML, STYLE, SELECT,
+ OBJECT, and all TABLE-related elements.</LI>
+ <LI>Replaces consecutive whitespace characters with a single space.</LI>
+ <LI>Changes attribute values and order of appearance.</LI>
+ <LI>Removes quotations around attribute values.</LI>
+ </LIST>
+ <P>
+ If the new content is only text and does not need to replace existing HTML,
+ it is more efficient to modify the <ICODE>data</ICODE> property of a text node.
+ </P>
+ <CODE>
+document.getElementById(&quot;anID&quot;).firstChild.data = &quot;Some new Text&quot;;
+ </CODE>
+ <P>
+ Compatibility Note: Implementations have been known to split long text
+ content among several adjacent text nodes, so replacing the data of the
+ first text node may not replace all the element's text. The <ICODE>normalize</ICODE>
+ method, where supported, will combine adjacent text nodes.
+ </P>
+ <P>
+ Note: Make sure the element exists in the document (has been parsed) before trying to
+ reference it.
+ </P>
+ <MOREINFO>
+ <URL>http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-FF21A306</URL>
+ <URL>http://msdn.microsoft.com/en-us/library/cc304097%28VS.85%29.aspx</URL>
+ <URL>http://msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx</URL>
+ <URL>http://developer.mozilla.org/en/Whitespace_in_the_DOM</URL>
+ <URL>http://developer.mozilla.org/en/docs/DOM:element.innerHTML</URL>
+ <URL>http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#html-fragment-serialization-algorithm</URL> (draft)
+ </MOREINFO>
+ </CONTENT>
+
+ <CONTENT TITLE="Why does my code fail to access an element?" ID="accessElementBeforeDefined">
+ <P>
+ An element can only be accessed after it exists in the document.
+ </P>
+ <P>
+ Either:
+ A) include your script after the HTML element it refers to, or
+ B) use the <ICODE>"load"</ICODE> event to trigger your script.
+ </P>
+ <P>
+ Example A:
+ </P>
+ <CODE>
+&lt;div id="snurgle"&gt;here&lt;/div&gt;
+&lt;script type="text/javascript"&gt;
+// Don't forget var.
+var snurgleEl = document.getElementById("snurgle");
+window.alert(snurgleEl.parentNode);
+&lt;/script&gt;
+ </CODE>
+ <P>
+ Example B:
+ </P>
+ <CODE>
+// In the HEAD.
+&lt;script type="text/javascript"&gt;
+window.onload = function(){
+ var snurgleEl = document.getElementById("snurgle");
+};
+&lt;/script&gt;
+ </CODE>
+
+ <LIST TYPE="UL" TITLE="Other problems can include:">
+ <LI>invalid HTML</LI>
+ <LI>two elements with the same <ICODE>name</ICODE> or <ICODE>id</ICODE></LI>
+ <LI><URL LINKTEXT="use of an unsafe name">names</URL></LI>.
+ </LIST>
+ </CONTENT>
+ <CONTENT TITLE="How can I see in javascript if a web browser accepts cookies?"
+ ID="testCookie" NUMID="4_4">
+ <P>
+ Write a cookie and read it back and check if it's the same.
+ </P>
+ <MOREINFO>
+ Additional Notes:
+ <URL>http://www.ietf.org/rfc/rfc2965.txt</URL>
+ <URL>http://www.galasoft-lb.ch/myjavascript/consulting/2001012701/</URL>
+ <URL>http://www.cookiecentral.com/</URL>
+ </MOREINFO>
+ </CONTENT>
+</CONTENT>
\ No newline at end of file
/trunk/cljs/sections/dom.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/debugging.xml
===================================================================
--- trunk/cljs/sections/debugging.xml (nonexistent)
+++ trunk/cljs/sections/debugging.xml (revision 45)
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Debugging" ID="debugging">
+ <CONTENT TITLE="How do I get my browser to report script errors?"
+ ID="javascriptErrors" NUMID="4_43">
+ <P>
+There are debugging tools for many browsers. Learn to use them all.
+ </P>
+ <LIST TYPE="DL">
+ <DT>General</DT>
+ <DD><URL LINKTEXT="Secrets of the Browser Developer Tools">http://devtoolsecrets.com/</URL></DD>
+ <DT>Windows</DT>
+ <DD>
+<URL LINKTEXT="Fiddler">http://www.fiddlertool.com/fiddler/</URL>.
+Fiddler is an HTTP Debugging proxy (it won't find script
+errors). Fiddler logs HTTP activity, like Firebug's Net
+tab, but can be attached to any browser running on Windows.
+ </DD>
+ <DT>Windows IE</DT>
+ <DD>Microsoft Script Editor. Included with Visual Studio or Microsoft
+Word 2003 (discontinued in Office 2007).
+To enable,
+<ICODE>Tools</ICODE>, <ICODE>Internet Options</ICODE>, <ICODE>Advanced</ICODE>, and uncheck
+<ICODE>Disable Script Debugging</ICODE>. After enabling Script Debugging,
+a <ICODE>Script Debugger</ICODE> option will appear in the <ICODE>View</ICODE> menu.</DD>
+
+<DD><URL LINKTEXT="IETester">http://www.my-debugbar.com/wiki/IETester/HomePage</URL> for testing IE 5.5- IE8.</DD>
+<DD><URL LINKTEXT="CompanionJS">http://www.my-debugbar.com/wiki/CompanionJS/HomePage</URL> <ICODE>console</ICODE> for IE.</DD>
+ <DD>
+<EM>Note:</EM> For debugging scripts in IE, the Microsoft Script <EM>Editor</EM>
+is recommended. However, if not available, the <URL LINKTEXT="Microsoft Script Debugger"
+>http://www.microsoft.com/downloads/details.aspx?FamilyId=2F465BE0-94FD-4569-B3C4-DFFDF19CCD99&amp;displaylang=en</URL> may be somewhat helpful.
+ </DD>
+ <DD>
+<URL LINKTEXT="Internet Explorer Developer Toolbar"
+ >http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e-2d5e1db91038&amp;displaylang=en</URL>
+ </DD>
+ <DD>
+To report errors: Wait until a little yellow
+triangle appears at the left end of the status bar, double click
+on it and, when the error dialog box appears, check the &quot;Always
+show errors&quot; checkbox it contains.
+
+Or, <ICODE>Internet Options</ICODE>, <ICODE>Advanced</ICODE>, deselect <ICODE>"Disable Script Debugging"</ICODE>,
+select <ICODE>"Display a notification ..."</ICODE>.
+ </DD>
+ <DT>Firefox</DT>
+ <DD>
+ <ICODE>Tools &gt; Error console</ICODE> (<ICODE>Ctrl</ICODE> + <ICODE>Shift</ICODE> + <ICODE>j</ICODE>).
+ </DD>
+ <DD>
+<URL LINKTEXT="Firebug">http://getfirebug.com/</URL>
+ </DD>
+ <DD>
+<URL LINKTEXT="YSlow">https://addons.mozilla.org/en-US/firefox/addon/5369</URL>.
+YSlow analyzes web pages and tells you why they're slow
+based on Yahoo's rules for high performance web sites.
+ </DD>
+ <DD>
+<URL LINKTEXT="Lori">https://addons.mozilla.org/en-US/firefox/addon/1743</URL>
+<DFN>Lori</DFN> or Life-of-request info, is useful for troubleshooting
+server response and page load time.
+ </DD>
+ <DD>
+<URL LINKTEXT="Web Developer Toolbar">https://addons.mozilla.org/en-US/firefox/addon/60</URL>.
+ </DD>
+ <DD>
+<URL LINKTEXT="Cookie Watcher">https://addons.mozilla.org/en-US/firefox/addon/1201</URL>.
+ </DD>
+ <DD>
+<URL LINKTEXT="XPather">https://addons.mozilla.org/en-US/firefox/addon/1192</URL>.
+XPath generator, editor and inspector.
+ </DD>
+ <DT>Opera</DT>
+ <DD>
+Tools &gt; Advanced &gt; Error console
+ </DD>
+ <DD>
+<URL LINKTEXT="Introduction to Opera Dragonfly"
+ >http://dev.opera.com/articles/view/introduction-to-opera-dragonfly/</URL>
+ </DD>
+ <DT>Safari</DT>
+ <DD>
+To display the <ICODE>Develop</ICODE> menu in Safari 3.1 or higher, select
+the checkbox labeled "Show Develop menu in menu bar" in
+Safari's <ICODE>Advanced</ICODE> Preferences panel.
+ </DD>
+ <DD>
+<URL LINKTEXT="Safari Web Inspector">http://trac.webkit.org/wiki/Web%20Inspector </URL>
+ </DD>
+ <DT>Chrome</DT>
+ <DD>
+JavaScript Console: click the <ICODE>Page</ICODE> menu icon and select
+<ICODE>Developer &gt; JavaScript Console</ICODE>. From here, you'll be
+able to view errors in the JavaScript execution, and enter
+additional javascript commands to execute.
+ </DD>
+ <DD>
+JavaScript Debugger: available as <ICODE>Page</ICODE> menu icon &gt; <ICODE>Developer</ICODE>
+&gt; Debug JavaScript, the debugger provides a command prompt from which you
+can set breakpoints, backtrace, and more. Type <ICODE>help</ICODE> at the debugger
+command line to get started.
+ </DD>
+ <DD>
+ <UL>
+ <LI><URL LINKTEXT="Google Chrome Script Debugging"
+ >http://www.google.com/chrome/intl/en/webmasters-faq.html#jsexec</URL></LI>
+ <LI><URL LINKTEXT="Developer Tools for Google Chrome"
+ >http://blog.chromium.org/2009/06/developer-tools-for-google-chrome.html</URL></LI>
+ <LI><URL LINKTEXT="Tools for Eclipse Users">http://blog.chromium.org/2009/08/google-chrome-developer-tools-for.html</URL></LI>
+ </UL>
+ </DD>
+ <DT>Mac IE</DT>
+ <DD>
+Use the Preferences dialog.
+ </DD>
+ </LIST>
+ </CONTENT>
+ </CONTENT>
\ No newline at end of file
/trunk/cljs/sections/debugging.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/overview.xml
===================================================================
--- trunk/cljs/sections/overview.xml (nonexistent)
+++ trunk/cljs/sections/overview.xml (revision 45)
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Language Overview" ID="tips" NUMID="2">
+ <CONTENT TITLE="What is ECMAScript?" ID="ecma" NUMID="2_6">
+ <P>
+ <URL LINKTEXT="ECMA-262">http://www.ecma-international.org/publications/standards/Ecma-262.htm</URL>
+ is the international standard that current language implementations
+ (JavaScript&trade;, JScript etc.) are based on.
+ </P>
+ <P>
+ <URL LINKTEXT="ECMA-262">http://www.ecma-international.org/publications/standards/Ecma-262.htm</URL>
+ defines the language Syntax, Types, Keywords, Operators, and built-in
+ objects. The ECMAScript specification is the reference to determine the
+ expected behavior of a program. ECMAScript does not define any host
+ objects, such as <ICODE>document</ICODE>, <ICODE>window</ICODE>, or
+ <ICODE>ActiveXObject</ICODE>.
+ </P>
+ <P>
+ ECMA-327 defines the Compact Profile of ECMAScript by
+ describing the features from ECMA 262 that may be omitted in some
+ resource-constrained environments.
+ <URL>http://www.ecma-international.org/publications/standards/Ecma-327.htm</URL>
+ </P>
+ <P>
+ The most widely supported edition of ECMA-262 is the 3rd edition (1999).
+ There is fair support for this edition in JScript 5.5+ (buggy) and good
+ support JavaScript 1.5.
+ </P>
+ <P>
+ <em>For historical reasons, the term “javascript” is used herein
+ as a shorthand for “ECMAScript-based programming languages”.
+ Note that not all uses of that term here are correct. For example,
+ there are instances where using “DOM” instead would have been correct.
+ This will be fixed in a later revision.</em>
+ </P>
+ </CONTENT>
+ <CONTENT TITLE="What is JScript?" ID="jScript" NUMID="2_7">
+ <P>
+ JScript is Microsoft's implementation of ECMAScript.
+ </P>
+ <P>
+ Questions that are specific to Microsoft's JScript may also
+ be appropriately asked at:
+ <NEWSGROUP>microsoft.public.scripting.jscript</NEWSGROUP>.
+ </P>
+ </CONTENT>
+ <CONTENT TITLE="What is the Document Object Model (DOM)?" ID="dom" NUMID="2_9">
+ <P>
+ The <DFN>Document Object Model</DFN> (DOM) is a interface-based model for <ICODE>Document</ICODE>
+ objects. The DOM allows scripts to dynamically access and update a
+ document's content, style, and event handlers.
+ </P>
+ <P>
+ The DOM is <EM>not</EM> part of the ECMAScript programming language.
+ </P>
+ <P>
+ Official DOM standards are defined by the World Wide Web Consortium.
+ Scriptable browsers also have <DFN>proprietary</DFN> DOM features (<URL
+ LINKTEXT="MSDN">http://msdn.microsoft.com/en-us/library/ms533050(VS.85).aspx</URL>, <URL
+ LINKTEXT="MDC">https://developer.mozilla.org/en/DOM_Client_Object_Cross-Reference</URL>),
+ such as <ICODE>document.writeln()</ICODE>.
+ </P>
+ <P>
+ Also see the section on <URL LINKTEXT="DOM and Forms">#domRef</URL>.
+ </P>
+ <MOREINFO>
+ <URL LINKTEXT="c.l.js DOM Resources">#onlineResources</URL>
+ <URL LINKTEXT="W3C DOM FAQ">http://www.w3.org/DOM/faq.html</URL>
+ <URL LINKTEXT="W3C DOM ">http://www.w3.org/DOM/</URL>
+ <URL LINKTEXT="MDC: What is the DOM?">https://developer.mozilla.org/en/Gecko_DOM_Reference/Introduction#What_is_the_DOM.3F</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="Internationalisation and Localisation in javascript" ID="localization" NUMID="2_10">
+ <P>
+ <DFN>Internationalisation</DFN> means using one form which is everywhere both
+ acceptable and understood. Any international standard not supported by
+ default can be coded for.
+ </P>
+ <P>
+ For example, there is an International Standard for numeric Gregorian
+ date format; but none for decimal and thousands separators.
+ </P>
+ <P>
+ <DFN>Localisation</DFN> is the process of adapting software for a specific region
+ or language by adding locale-specific components and translating text. It
+ cannot work well in general, because it requires a knowledge of all
+ preferences and the ability to choose the right one, in an environment
+ where many systems are inappropriately set anyway.
+ </P>
+ <P>
+ ECMAScript has a few <DFN>localisation</DFN> features. The various
+ <ICODE>toString()</ICODE> methods are all implementation dependent,
+ but tend to use either UK or US settings (not necessarily correctly).
+ ECMAScript Ed. 3 introduced some capabilities, including the
+ <ICODE>toLocaleString()</ICODE>method which should create a string
+ based on the host's locale.
+ </P>
+ <P>
+ ECMAScript 5th Edition introduces limited ISO 8601 capabilities with
+ <ICODE>Date.prototype.toISOString()</ICODE> and new behavior for <ICODE>Date.parse()</ICODE>.
+ </P>
+ </CONTENT>
+ <CONTENT TITLE="What does the future hold for ECMAScript?" ID="futureEcmaScript" NUMID="2_12">
+ <P>
+ The 5th edition of ECMAScript was approved on 2009-12-04. There is some
+ support in implementations released before approval date (JScript 5.8,
+ JavaScript 1.8, JavaScriptCore).
+ http://www.ecma-international.org/publications/standards/Ecma-262.htm
+ </P>
+ <MOREINFO>
+ <URL>http://www.ecma-international.org/publications/standards/Ecma-262.htm</URL>
+ </MOREINFO>
+ </CONTENT>
+</CONTENT>
\ No newline at end of file
/trunk/cljs/sections/overview.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/numbers.xml
===================================================================
--- trunk/cljs/sections/numbers.xml (nonexistent)
+++ trunk/cljs/sections/numbers.xml (revision 45)
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Numbers" ID="numbers">
+ <CONTENT TITLE="How do I format a Number as a String with exactly 2 decimal places?" ID="formatNumber" NUMID="4_6">
+ <P>
+ (For example: When formatting currency, how to format
+ <code>6.57634</code> as <code>"6.58"</code>,
+ <code>6.5</code> as <code>"6.50"</code>, and <code>6</code>
+ as <code>"6.00"</code>?)
+ </P>
+ <P>
+ Rounding of x.xx5 is unreliable, as most numbers are not
+ represented exactly. See also:
+ <URL LINKTEXT="Why does simple decimal arithmetic give strange results?"
+ >#binaryNumbers</URL>
+ </P>
+ <P>
+ The statement <code>n = Math.round(n * 100) / 100</code>
+ converts <code>n</code> to a <code>Number</code> value close
+ to a multiple of <code>0.01</code>. However, there are
+ problems. Converting the <code>Number</code> value
+ <code>n</code> to a <code>String</code> value
+ (<code>n.toString()</code>), does not give trailing zeroes.
+ Rounding numbers that are very close to <code>x.5</code>,
+ for example, <code>Math.round(0.49999999999999992)</code>
+ returns <code>1</code>.
+ </P>
+ <P>
+ ECMA-262 Edition 3 introduced <code>Number.prototype.toFixed()</code>.
+ However, there are bugs in JScript 5.8 and below with certain
+ values; for example, <code>0.007.toFixed(2)</code> incorrectly
+ returns <code>"0.00"</code>.
+ </P>
+ <CODE><![CDATA[
+var numberToFixed = (function () {
+ /**
+ * @param {string} input
+ * Input value to be converted to string.
+ * @param {number} size
+ * Desired length of output.
+ * @param {string} ch
+ * Single character to prefix to <var>s</var>.
+ * @return {string}
+ */
+ function padLeft (input, size, ch)
+ {
+ var s = input.toString();
+
+ while (s.length < size)
+ {
+ s = ch + s;
+ }
+
+ return s;
+ }
+
+ function toUnsignedString (m, digits)
+ {
+ var t,
+ s = Math.round(m * Math.pow(10, digits)).toString(),
+ start, end;
+
+ if (/\D/.test(s))
+ {
+ return m.toString();
+ }
+
+ s = padLeft(s, 1 + digits, "0");
+ start = s.substring(0, t = (s.length - digits));
+ end = s.substring(t);
+
+ if (end)
+ {
+ end = "." + end;
+ }
+
+ /* avoid "0." */
+ return start + end;
+ }
+
+ /**
+ * @param {number} n
+ * Number to be formatted
+ * @param {number} digits
+ * Number of decimal digits
+ * @return {string}
+ * The formatted string
+ */
+ return function (n, digits) {
+ var unsigned = toUnsignedString(Math.abs(n), digits);
+ return (n < 0 ? "-" : "") + unsigned;
+ };
+})();
+
+// Test results
+document.writeln([
+ "numberToFixed(9e-3, 12) => " + numberToFixed(9e-3, 12),
+ "numberToFixed(1.255, 2) => " + numberToFixed(1.255, 2),
+ "numberToFixed(1.355, 2) => " + numberToFixed(1.355, 2),
+ "numberToFixed(0.1255, 3) => " + numberToFixed(0.1255, 3),
+ "numberToFixed(0.07, 2) => " + numberToFixed(0.07, 2),
+ "numberToFixed(0.0000000006, 1) => " + numberToFixed(0.0000000006, 1),
+ "numberToFixed(0.0000000006, 0) => " + numberToFixed(0.0000000006, 0)
+].join("\n"));
+ ]]></CODE>
+ <MOREINFO>
+ <URL>http://www.merlyn.demon.co.uk/js-round.htm</URL>
+ <URL>http://msdn.microsoft.com/en-us/library/sstyff0z%28VS.85%29.aspx</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="Why does simple decimal arithmetic give strange results?" ID="binaryNumbers" NUMID="4_7">
+ <P>
+ For example, <ICODE>5 * 1.015</ICODE> does not give exactly
+ <ICODE>5.075</ICODE> and <ICODE>0.06+0.01</ICODE> does
+ not give exactly <ICODE>0.07</ICODE> in javascript.
+ </P>
+ <P>
+ ECMAScript numbers are represented in binary as IEEE-754 (IEC 559)
+ Doubles, with a resolution of 53 bits, giving an accuracy of
+ 15-16 decimal digits; integers up to just over <ICODE>9e15</ICODE> are
+ precise, but few decimal fractions are. Given this, arithmetic
+ is as exact as possible, but no more. Operations on integers
+ are exact if the true result and all intermediates are integers
+ within that range.
+ </P>
+ <P>
+ In particular, non-integer results should not normally be
+ compared for equality; and non-integer computed results
+ commonly need rounding; see <URL
+ LINKTEXT="How do I format a Number as a String with exactly 2 decimal places?"
+ >#formatNumber</URL>
+ </P>
+ <MOREINFO>
+ <URL>http://msdn.microsoft.com/en-us/library/7wkd9z69%28VS.85%29.aspx</URL>
+ <URL>http://www.merlyn.demon.co.uk/js-misc0.htm#DW4</URL>
+ </MOREINFO>
+ <P>
+ Otherwise, use <ICODE>Math.round</ICODE> on the results of expressions which
+ should be of integer value.
+ </P>
+ </CONTENT>
+ <CONTENT TITLE="Why does K = parseInt('09') set K to 0?" ID="parseIntBase" NUMID="4_12">
+ <P>
+ Method <ICODE>parseInt</ICODE> generally needs a second parameter, <ICODE>radix</ICODE>,
+ for the base (from 2 to 36).
+ </P>
+ <P>
+ If <ICODE>radix</ICODE> is omitted, the base is determined by the contents of
+ the string. Any string beginning with <ICODE>'0x'</ICODE> or <ICODE>'0X'</ICODE> represents a
+ hexadecimal number. A string beginning with a leading 0 may be parsed as
+ octal (as if <ICODE>raxix</ICODE> were 8), in ECMA-262 Ed 3 (octal digits are <ICODE>0-7</ICODE>).
+ If string <ICODE>'09'</ICODE> is converted to <ICODE>0</ICODE>.
+ </P>
+ <P>
+ To force use of a particular base, use the <ICODE>radix</ICODE>
+ parameter: <ICODE>parseInt("09", base)</ICODE>.
+
+ <!-- [omit]
+ If base 10 is desired,
+ the unary <ICODE>+</ICODE> operator can be an option. Example:
+ <ICODE>
+var s = '-09.1'; // Input string.
+var j = +s; // Convert to number. Result: -9.1
+var n = j|0; // Chop off decimal (convert ToInt32). Result: -9
+</ICODE>
+ [/omit] -->
+ </P>
+ <MOREINFO>
+ <URL>http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/parseInt</URL>
+ <URL>http://msdn.microsoft.com/en-us/library/x53yedee%28VS.85%29.aspx</URL>
+ <URL>http://docs.sun.com/source/816-6408-10/toplev.htm#1064173</URL>
+ <URL>notes/type-conversion/#tcPrIntRx</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="Why does 1+1 equal 11? or How do I convert a string to a number?" ID="typeConvert">
+ <P>
+ Variables are not typed; their values are. The conversion between a
+ string and a number happens automatically.
+ </P>
+ <P>
+ The addition operator (<ICODE>+</ICODE>) performs concatenation if either operand is a
+ string, thus <ICODE>"1" + 1</ICODE> results <ICODE>"11"</ICODE>. To perform addition, you might need
+ to first convert the string to a number. For example <ICODE>+varname</ICODE> or
+ <ICODE>Number(varname)</ICODE> or <ICODE>parseInt(varname, 10)</ICODE> or
+ <ICODE>parseFloat(varname)</ICODE>. Form control values are strings, as is the result
+ from a <ICODE>prompt</ICODE> dialog. Convert these to numbers before performing
+ addition: <ICODE>+'1' + 1</ICODE> results <ICODE>2</ICODE>.
+ </P>
+ <MOREINFO>
+ <URL LINKTEXT="Additional Notes">notes/type-conversion/</URL>
+ <URL>http://msdn.microsoft.com/en-us/library/67defydd%28VS.85%29.aspx</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I generate a random integer from 1 to n?" ID="randomNumber" NUMID="4_22">
+ <P>
+ <ICODE>Math.random()</ICODE> returns a value <ICODE>R</ICODE> such that <ICODE>0 &lt;= R &lt; 1.0</ICODE>; therefore:
+ </P>
+ <CODE>
+// positive integer expected
+function getRandomNumber(n) {
+ return Math.floor(n * Math.random());
+}
+ </CODE>
+ - gives an evenly distributed random integer in the range from
+ <ICODE>0</ICODE> to <ICODE>n - 1</ICODE> inclusive; use <ICODE>getRandomNumber(n)+1</ICODE> for <ICODE>1</ICODE> to <ICODE>n</ICODE>.
+ <MOREINFO>
+ <URL>http://msdn.microsoft.com/en-us/library/41336409%28VS.85%29.aspx</URL>
+ <URL>http://docs.sun.com/source/816-6408-10/math.htm</URL>
+ How to Deal and Shuffle, see in: <URL>http://www.merlyn.demon.co.uk/js-randm.htm</URL>
+ </MOREINFO>
+ </CONTENT>
+</CONTENT>
\ No newline at end of file
/trunk/cljs/sections/numbers.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/dates.xml
===================================================================
--- trunk/cljs/sections/dates.xml (nonexistent)
+++ trunk/cljs/sections/dates.xml (revision 45)
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Dates" ID="dates">
+ <P>
+ ISO 8601 defines date and time formats. Some benefits include:
+ </P>
+ <LIST TYPE="UL">
+ <LI>language-independent and unambiguous world-wide</LI>
+ <LI>sortable with a trivial string comparison</LI>
+ <LI>easily readable and writable by software</LI>
+ <LI>compatible with standards ISO 9075 and <URL LINKTEXT="rfc 3339">http://www.ietf.org/rfc/rfc3339.txt</URL></LI>
+ </LIST>
+ <P>
+ The ISO Extended format for common date is <ICODE>YYYY-MM-DD</ICODE>, and for time is
+ <ICODE>hh:mm:ss</ICODE>.
+ </P>
+ <P>
+ For an event with an offset from UTC, use <ICODE>YYYY-MM-DDThh:mm:ss&#177;hh:mm</ICODE>.
+ </P>
+ <P>
+ Never use a local date/time format for a non-local event. Instead, use
+ UTC, as in <ICODE>YYYY-MM-DDThh:mm:ssZ</ICODE> (<ICODE>Z</ICODE> is the only letter suffix).
+ </P>
+ <P>
+ The <ICODE>T</ICODE> can be omitted where that would not cause ambiguity. For
+ rfc 3339 compliance, it may be replaced by a space and for SQL,
+ it <EM>must</EM> be replaced by a single space.
+ </P>
+ <P>
+ Year <ICODE>0000</ICODE> is unrecognized by some formats (XML Schema, <ICODE>xs:date</ICODE>).
+ </P>
+ <MOREINFO>
+ <URL LINKTEXT="ECMA-262 Date.prototype, s. 15.9">#onlineResources</URL>
+ <URL LINKTEXT="A summary of the international standard date and time notation, by Markus Kuhn"
+ >http://www.cl.cam.ac.uk/~mgk25/iso-time.html</URL>
+ <URL>http://en.wikipedia.org/wiki/ISO_8601</URL>
+ <URL LINKTEXT="ISO 8601:2004(E)">res/ISO_8601-2004_E.pdf</URL>
+ <URL LINKTEXT="W3C QA Tip: Use international date format (ISO)">http://www.w3.org/QA/Tips/iso-date</URL>
+ <URL LINKTEXT="RFC 3339, Date and Time on the Internet: Timestamps"
+ >http://www.ietf.org/rfc/rfc3339.txt</URL>
+ <URL>http://www.w3.org/TR/xmlschema-2/#dateTime</URL>
+ </MOREINFO>
+
+ <CONTENT TITLE="How do I format a Date object with javascript?" ID="formatDate" NUMID="4_30">
+ <P>
+ A local <ICODE>Date</ICODE> object where <ICODE>0 &lt;= year &lt;= 9999</ICODE> can be
+ formatted to a common ISO 8601 format <ICODE>YYYY-MM-DD</ICODE> with:-
+ </P>
+ <CODE>
+/** Formats a Date to YYYY-MM-DD (local time), compatible with both
+ * ISO 8601 and ISO/IEC 9075-2:2003 (E) (SQL 'date' type).
+ * @param {Date} dateInRange year 0000 to 9999.
+ * @throws {RangeError} if the year is not in range
+ */
+function formatDate(dateInRange) {
+ var year = dateInRange.getFullYear(),
+ isInRange = year &gt;= 0 &amp;&amp; year &lt;= 9999, yyyy, mm, dd;
+ if(!isInRange) {
+ throw RangeError("formatDate: year must be 0000-9999");
+ }
+ yyyy = ("000" + year).slice(-4);
+ mm = ("0" + (dateInRange.getMonth() + 1)).slice(-2);
+ dd = ("0" + (dateInRange.getDate())).slice(-2);
+ return yyyy + "-" + mm + "-" + dd;
+}
+ </CODE>
+ <MOREINFO>
+ <URL>http://www.merlyn.demon.co.uk/js-date9.htm</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How can I create a Date object from a String?" ID="parseDate">
+ <P>
+ An Extended ISO 8601 local Date format <ICODE>YYYY-MM-DD</ICODE> can be parsed to a
+ Date with the following:
+ </P>
+ <CODE>
+/**Parses string formatted as YYYY-MM-DD to a Date object.
+ * If the supplied string does not match the format, an
+ * invalid Date (value NaN) is returned.
+ * @param {string} dateStringInRange format YYYY-MM-DD, with year in
+ * range of 0000-9999, inclusive.
+ * @return {Date} Date object representing the string.
+ */
+function parseISO8601(dateStringInRange) {
+ var isoExp = /^\s*(\d{4})-(\d\d)-(\d\d)\s*$/,
+ date = new Date(NaN), month,
+ parts = isoExp.exec(dateStringInRange);
+
+ if(parts) {
+ month = +parts[2];
+ date.setFullYear(parts[1], month - 1, parts[3]);
+ if(month != date.getMonth() + 1) {
+ date.setTime(NaN);
+ }
+ }
+ return date;
+}
+ </CODE>
+ </CONTENT>
+</CONTENT>
\ No newline at end of file
/trunk/cljs/sections/dates.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/server.xml
===================================================================
--- trunk/cljs/sections/server.xml (nonexistent)
+++ trunk/cljs/sections/server.xml (revision 45)
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Ajax and Server Communication" ID="ajaxRef">
+ <CONTENT TITLE="What is Ajax?" ID="ajax" NUMID="4_44">
+ <P>
+<DFN TITLE="Asynchronous JavaScript and XML">Ajax</DFN>
+is shorthand for Asynchronous JavaScript and XML. The technology is
+based on the <ICODE>XMLHttpRequest</ICODE> Object. At its simplest,
+it is the sending/retrieving of new data from the server without
+changing or reloading the window location.
+ </P>
+<MOREINFO>
+Mozilla Documentation:
+<URL>http://developer.mozilla.org/en/docs/XMLHttpRequest</URL>
+MSDN Documention:
+<URL>http://msdn.microsoft.com/en-us/library/ms535874%28VS.85%29.aspx</URL>
+<URL>http://msdn.microsoft.com/en-us/library/ms759148%28VS.85%29.aspx</URL>
+
+<DFN TITLE="Asynchronous JavaScript and XML">Ajax</DFN>
+Libraries and Tutorial Sites:
+<URL>http://jibbering.com/2002/4/httprequest.html</URL>
+<URL>http://www.ajaxtoolbox.com/</URL>
+</MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I download a page to a variable?" ID="downloadPage" NUMID="4_38">
+ <P>
+Although <ICODE>XMLHttpRequest</ICODE> can be used to download
+entire pages, it is often used for downloading small pieces
+of data that can be used to update the current page.
+ </P>
+ <MOREINFO>
+ <URL>http://jibbering.com/2002/4/httprequest.html</URL>
+ <URL>http://www.ajaxtoolbox.com/</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I get a jsp/php variable into client-side javascript?"
+ ID="getServerVariable" NUMID="4_18">
+ <P>
+Use a server-side language to generate the javascript.
+</P>
+<P>
+Certain characters of ECMAScript strings must be escaped by backslash.
+These include quote marks, backslash, and line terminators.
+</P>
+<P>JSP Example, using Apache Commons: <ICODE>org.apache.commons.lang.StringEscapeUtils</ICODE>:
+</P>
+ <CODE>
+var jsVar = "&lt;%= StringEscapeUtils.escapeJavaScript(str) %&gt;";
+</CODE>
+<P>PHP example using <ICODE>addcslashes</ICODE>: </P>
+<CODE>
+var jsVar = "&lt;?php echo addcslashes($str,"\\\'\"\n\r"); ?&gt;";
+</CODE>
+ <MOREINFO>
+ <URL>example/addcslashes.php</URL>
+ <URL>http://php.net/manual/en/function.addcslashes.php</URL>
+ <URL>http://commons.apache.org/lang/</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I log-out a user when they leave my site?"
+ ID="sessionExpired" NUMID="4_29">
+ <P>
+This cannot be done reliably. Here's why:
+ </P>
+ <UL>
+ <LI>
+The user may disable javascript so the log-out script will
+never execute.
+ </LI>
+ <LI>
+The user may not be on-line when they close your web page.
+ </LI>
+ <LI>
+Javascript errors elsewhere in the page may prevent the script
+executing.
+ </LI>
+ <LI>
+The browser may not support the onunload event, or may not fire
+it under certain circumstances, so the log-out function will
+not execute.
+ </LI>
+ </UL>
+The URL below has more information.
+<MOREINFO>
+<URL>http://groups.google.com/groups?selm=BlmZ7.55691%244x4.7344316%40news2-win.server.ntlworld.com</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I run a server side script?" ID="runServerScript" NUMID="4_34">
+ <P>
+You trigger a server-side script by sending an HTTP request.
+This can be achieved by setting the <ICODE>src</ICODE> of an <ICODE>img</ICODE>,
+<ICODE>Image</ICODE>, <ICODE>frame</ICODE>, or <ICODE>iframe</ICODE>, or by using <DFN
+TITLE="XMLHttpRequest or XMLHTTP">XHR</DFN>, where supported.
+ </P>
+ <P>
+An image will also
+&quot;swallow&quot; the data sent back by the server, so that they will
+not be visible anywhere.
+</P>
+ <CODE>
+ var dummyImage = new Image();
+ dummyImage.src = &quot;scriptURL.asp?param=&quot; + varName;
+</CODE>
+ <P>
+Mozilla, Opera 7.6+, Safari 1.2+, and Windows IE 7
+provide the <ICODE>XMLHttpRequest</ICODE> object
+(Windows IE versions 5+, provides ActiveX to acheive an analagous
+effect). <ICODE>XMLHttpRequest</ICODE> can send HTTP requests to
+the server, and provides access the <ICODE>responseText</ICODE> or <ICODE>responseXML</ICODE>
+(when the response is XML), and HTTP header information.
+</P>
+<MOREINFO>
+<URL>http://jibbering.com/2002/4/httprequest.html</URL>
+<URL>http://www.w3.org/TR/XMLHttpRequest/</URL>
+<URL>http://developer.mozilla.org/en/XMLHttpRequest</URL>
+<URL>http://msdn.microsoft.com/en-us/library/ms537505(VS.85).aspx</URL>
+</MOREINFO>
+ <CONTENT TITLE="Why are my rollovers so slow?" ID="imageCache" NUMID="4_31">
+ <P>
+Images are cached by the browser depending on the headers sent by
+the server. If the server does not send sufficient information
+for the browser to decide the image is cacheable, the browser
+will check if the image has been updated every time you change the
+src of an image (in some user settings). To overcome this you
+must send suitable headers.
+ </P>
+<MOREINFO>
+<URL>http://www.mnot.net/cache_docs/</URL>
+</MOREINFO>
+ </CONTENT>
+ </CONTENT>
+ <CONTENT TITLE="How do I force a reload from the server/prevent caching?"
+ ID="noCache" NUMID="4_17">
+ <P>
+To reload a page, use <ICODE>location.reload()</ICODE>. However, this depends
+upon the cache headers that your server sends. To change this,
+you need to alter the server configuration. A quick fix on the
+client is to change the page URI so that it contains a unique
+element, such as the current time. For example:
+<ICODE>location.replace(location.href+'?d='+new Date().valueOf())</ICODE>
+If the <ICODE>location.href</ICODE> already contains a query String, use:
+<ICODE>location.replace(location.href+'&amp;d='+new Date().valueOf())</ICODE>
+ </P>
+ <MOREINFO>
+ <URL>http://www.mnot.net/cache_docs/</URL>
+ <URL>http://docs.sun.com/source/816-6408-10/date.htm</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT
+ TITLE="Why is my Ajax page not updated properly when using an HTTP GET request in Internet Explorer?"
+ ID="ajaxCache" NUMID="4_45">
+ <P>
+ Browsers cache the results of HTTP requests to reduce network traffic.
+ To force the browser to request the document from the server, either
+ set the <ICODE>EXPIRES</ICODE> and/or <ICODE>CACHE-CONTROL</ICODE> response header(s)
+ with a past date or use a unique query string.
+</P>
+ <CODE>
+ req.open("GET", "/example.jsp?date=" + (+new Date), true);
+</CODE>
+
+Always use the appropriate HTTP method. Do not use <ICODE>POST</ICODE>
+to prevent caching. See <URL LINKTEXT="RFC 2616"
+>http://www.faqs.org/rfcs/rfc2616.html</URL>.
+
+<MOREINFO>
+<URL>http://www.mnot.net/cache_docs/#EXPIRES</URL>
+<URL>http://www.mnot.net/javascript/xmlhttprequest/cache.html </URL>
+</MOREINFO>
+ </CONTENT>
+ </CONTENT>
\ No newline at end of file
/trunk/cljs/sections/server.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/donts.xml
===================================================================
--- trunk/cljs/sections/donts.xml (nonexistent)
+++ trunk/cljs/sections/donts.xml (revision 45)
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Things not to attempt in a browser" ID="doNotTry">
+ <CONTENT TITLE="How do I detect Opera/Safari/IE?" ID="detectBrowser" NUMID="4_26">
+ <P>
+The short answer: <EM>Don't do that</EM>.
+ </P>
+ <P>
+The <ICODE>navigator</ICODE> <DFN>host object</DFN> contains properties which
+may identify the browser and version. These properties are historically
+inaccurate. Some browsers allow the user to set <ICODE>navigator.userAgent</ICODE> to any value. For
+example, Firefox, (type <ICODE>about:config</ICODE> and search <ICODE>useragent</ICODE>
+or Safari, <ICODE>Develop &gt; User Agent &gt; Other...</ICODE>, IE, via Registry.
+ </P>
+ <P>
+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.
+ </P>
+ <P>
+Browser detection is unreliable, at best. It usually causes
+forward-compatibility and maintenance problems. It is unrelated to the
+problem or incompatiblity it is trying to solve and obscures the
+problems it is used for, where it is used.
+ </P>
+ <P>
+Object detection is checking that the object in question exists.
+<URL LINKTEXT="Capability detection"
+>http://dev.opera.com/articles/view/using-capability-detection/</URL
+ > goes one step further to actually test the object,
+method, or property, to see if behaves in the desired manner.
+ </P>
+ <P>
+Feature Test Example:
+ </P>
+ <CODE>
+/**
+ * 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.
+ return e.target || e.srcElement;
+}</CODE>
+<MOREINFO>
+<URL>notes/detect-browser/</URL>
+<URL>http://dev.opera.com/articles/view/using-capability-detection/</URL>
+<URL>http://developer.apple.com/internet/webcontent/objectdetection.html</URL>
+<URL>http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43</URL>
+</MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How can I prevent access to a web page by using javascript?"
+ ID="preventAccess" NUMID="4_5">
+ <P>
+In practice you can't. While you could create a suitable
+encryption system with a password in the page, the level of
+support you need to do this means it's always simpler to do it
+server-side. Anything that &quot;protects&quot; a page
+other than the current one is definitely flawed.
+ </P>
+ </CONTENT>
+ <CONTENT TITLE="How do I protect my javascript code?" ID="hideSource" NUMID="4_1">
+ <P>
+With clientside javascript you can't as your code is distributed
+in source form and is easily readable. With JScript, there is the
+Script Encoder (see MSDN), but this is nothing more than obfuscation.
+Attempting to disable the context menu does nothing to
+protect your script in a Web browser.
+ </P>
+ <MOREINFO>
+ Your code is likely protected under copyright laws. See:
+ <URL>http://www.wipo.int/about-ip/en/copyright.html</URL>
+ <URL>http://webdesign.about.com/od/copyright/Copyright_Issues_on_the_Web_Intellectual_Property.htm</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I suppress a context menu (right-click menu)?"
+ ID="disableRightClick" NUMID="4_27">
+ <P>
+A context menu, often triggered by right-click, can be requested by the
+user in a few ways. For example, on windows, shift + F10 and on macs,
+click-and-hold. Other input devices exist and mouse buttons can be
+configured, making the term "right click" a misnomer, in context.
+</P>
+<P>
+In browsers that allow it, a script can suppress the context menu by
+returning false from an object's <ICODE>oncontextmenu</ICODE> event handler.
+</P>
+<CODE>
+document.oncontextmenu = function() {
+ return false;
+};
+</CODE>
+<P>
+Some browsers lack context menus (e.g. iphone). Browsers that have
+context menus do not always have a scriptable event for them. Some
+browsers can be configured to disallow scripts from detecting context
+menu events (IE, Opera); others may fire the event but be configured to
+disallow scripts from suppressing the context menu (Firefox,Seamonkey).
+</P>
+<P>
+Even when the context menu has been suppressed, it will still be
+possible to view/save the source code and to save images.
+</P>
+<MOREINFO>
+<URL>http://en.wikipedia.org/wiki/Context_menu</URL>
+<URL>http://kb.mozillazine.org/Ui.click_hold_context_menus</URL>
+<URL>http://support.microsoft.com/kb/823057</URL>
+<URL>http://stackoverflow.com/questions/1870880/opera-custom-context-menu-picking-up-the-right-click/1902730#1902730</URL>
+<URL>http://support.mozilla.com/en-US/kb/Javascript#Advanced_JavaScript_settings</URL>
+<URL>http://msdn.microsoft.com/en-us/library/ms536914%28VS.85%29.aspx</URL>
+</MOREINFO>
+</CONTENT>
+ <CONTENT TITLE="How can I access the client-side filesystem?" ID="readFile" NUMID="4_3">
+ <P>
+Security means that by default you can't. In a more restricted
+environment, there are options. For example, using LiveConnect to
+connect to Java with Netscape, and using the FileSystemObject in
+IE. Check <URL LINKTEXT="Google Groups archives">http://groups.google.com/group/comp.lang.javascript/topics</URL>
+for previous posts on the subject.
+ </P>
+ <MOREINFO>
+ <URL>http://msdn.microsoft.com/en-us/library/z9ty6h50%28VS.85%29.aspx</URL>
+ <URL>http://www.javaworld.com/javaworld/jw-10-1998/jw-10-apptowin32.html</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="I have &lt;a href=&quot;javascript:somefunction()&quot;&gt; what ... ?"
+ ID="javascriptURI" NUMID="4_24">
+ <P>
+Whatever the rest of your question, this is generally a very bad idea.
+The <ICODE>javascript:</ICODE> pseudo protocol was designed to replace the
+current document with the value that is returned from the expression.
+For example:
+ </P>
+ <CODE>
+ &lt;a href=&quot;javascript:'&lt;h1&gt;' + document.lastModified + '&lt;/h1&gt;'&quot;&gt;lastModified&lt;/a&gt;
+</CODE>
+ <P>
+will result in replacing the current document with the value
+returned from <ICODE>document.lastModified</ICODE>, wrapped in an <ICODE>&lt;h1&gt;</ICODE>
+tag.
+ </P>
+ <P>
+When the expression used evaluates to an <ICODE>undefined</ICODE> value
+(as some function calls do), the contents of the current page are not
+replaced. Regardless, some browsers (notably IE6) interpret this as
+navigation and will enter into a 'navigation' state where GIF
+animations and plugins (such as movies) will stop and navigational
+features such as <ICODE>META</ICODE> refresh, assignment to <ICODE>location.href</ICODE>, and image
+swaps fail.
+ </P>
+ <P>
+It is also possible for IE to be configured such that it supports
+javascript but not the <ICODE>javascript:</ICODE> protocol. This results
+in the user seeing a protocol error for <ICODE>javascript:</ICODE> URIs.
+ </P>
+ <P>
+The <ICODE>javascript:</ICODE> pseudo protocol creates accessibility and
+usability problems. It provides no fallback for when the script is not
+supported.
+ </P>
+ <P>
+Instead, use
+<ICODE>&lt;a href=&quot;something.html&quot; onclick=&quot;somefunction();return false&quot;&gt;</ICODE>
+where <ICODE>something.html</ICODE> is a meaningful alternative. Alternatively,
+attach the <ICODE>click</ICODE> callback using an event registry.
+ </P>
+ <MOREINFO>
+ <URL>example/jsuri/</URL>
+ <URL LINKTEXT="Set/Navigate to a Location">http://groups.google.com/group/comp.lang.javascript/msg/f665cfca3b619692</URL>
+ <URL LINKTEXT="Top Ten Web-Design Mistakes of 2002">http://www.useit.com/alertbox/20021223.html</URL>
+ </MOREINFO>
+ </CONTENT>
+ </CONTENT>
\ No newline at end of file
/trunk/cljs/sections/donts.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/functions.xml
===================================================================
--- trunk/cljs/sections/functions.xml (nonexistent)
+++ trunk/cljs/sections/functions.xml (revision 45)
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Functions" ID="functions">
+ <CONTENT TITLE="What is (function(){ /*...*/ })() ?" ID="scope">
+ <P>
+ This is an anonymous <DFN>FunctionExpression</DFN> that is called
+ immediately after creation.
+ </P>
+ <P>
+ Variables declared inside a function are not accessible from
+ outside the function. This can be useful, for example, to hide
+ implementation details or to avoid polluting the global scope.
+ </P>
+ <MOREINFO>
+ <URL>http://yura.thinkweb2.com/named-function-expressions/</URL>
+ <URL>notes/closures/</URL>
+ <URL>http://dmitrysoshnikov.com/ecmascript/chapter-5-functions/#question-about-surrounding-parentheses</URL>
+ </MOREINFO>
+ </CONTENT>
+
+ <CONTENT TITLE="What is a function statement?" ID="functionStatement">
+ <P>
+ The term <DFN>function statement</DFN> has been widely and wrongly used to
+ describe a <ICODE>FunctionDeclaration</ICODE>. This is misleading because in ECMAScript,
+ a <ICODE>FunctionDeclaration</ICODE> is not a <DFN>Statement</DFN>; there are places in a program
+ where a <DFN>Statement</DFN> is permitted but a <ICODE>FunctionDeclaration</ICODE> is not. To add
+ to this confusion, some implementations, notably Mozillas', provide a
+ syntax extension called <DFN>function statement</DFN>. This is allowed under
+ section 16 of ECMA-262, Editions 3 and 5.
+ </P>
+ <P>
+ Example of nonstandard <DFN>function statement</DFN>:
+ </P>
+ <CODE>
+// Nonstandard syntax, found in GMail source code. DO NOT USE.
+try {
+ // FunctionDeclaration not allowed in Block.
+ function Fze(b,a){return b.unselectable=a}
+ /*...*/
+} catch(e) { _DumpException(e) }
+ </CODE>
+ <P>
+ Code that uses <DFN>function statement</DFN> has three known interpretations. Some
+ implementations process <ICODE>Fze</ICODE> as a <DFN>Statement</DFN>, in order. Others, including
+ JScript, evaluate <ICODE>Fze</ICODE> upon entering the execution context that it
+ appears in. Yet others, notably DMDScript and default configuration of BESEN,
+ throw a <ICODE>SyntaxError</ICODE>.
+ </P>
+ <P>
+ For consistent behavior across implementations, <EM>do not use function
+ statement</EM>; use either <ICODE>FunctionExpression</ICODE> or <ICODE>FunctionDeclaration</ICODE> instead.
+ </P>
+ <P>
+ Example of <ICODE>FunctionExpression</ICODE> (valid):
+ </P>
+ <CODE>
+var Fze;
+try {
+ Fze = function(b,a){return b.unselectable=a};
+ /*...*/
+} catch(e) { _DumpException(e) }
+ </CODE>
+ Example of <ICODE>FunctionDeclaration</ICODE> (valid):
+ <CODE>
+// Program code
+function aa(b,a){return b.unselectable=a}
+ </CODE>
+<!--
+Notable examples of the misuse of the term "function statement"
+can be seen in David Flanagan's "JavaScript: The Definitive Guide",
+Douglas Crockford's "JavaScript: The Good Parts", MDC documentation,
+JSLint error messages.
+-->
+ <MOREINFO>
+ <URL>example/functionStatement.html</URL>
+ <URL>https://mail.mozilla.org/pipermail/es-discuss/2008-February/005314.html</URL>
+ <URL>http://groups.google.com/group/comp.lang.javascript/msg/aa9a32d0c6ae0342</URL>
+ <URL>http://groups.google.com/group/comp.lang.javascript/msg/3987eac87ad27966</URL>
+ <URL>http://nanto.asablo.jp/blog/2005/12/10/172622</URL> (Article in Japanese)
+ </MOREINFO>
+ </CONTENT>
+</CONTENT>
\ No newline at end of file
/trunk/cljs/sections/functions.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/objects.xml
===================================================================
--- trunk/cljs/sections/objects.xml (nonexistent)
+++ trunk/cljs/sections/objects.xml (revision 45)
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Objects" ID="objects">
+ <CONTENT TITLE="What is a native object?" ID="nativeObject">
+ <P>
+ A <DFN>native object</DFN> is any object whose semantics are fully defined by
+ ECMA-262.
+ </P>
+ <P>
+ Some <DFN>native objects</DFN> are <DFN>built-in</DFN>; others, such as <DFN>user-defined</DFN> objects,
+ may be constructed during the execution of an ECMAScript program.
+ </P>
+ <P>
+ Example:
+ </P>
+ <CODE>
+// Native built-in objects:
+var m = Math, // Built-in Math object.
+ slice = Array.prototype.slice, // Built-in native method.
+ o = {}, // Native user-defined object.
+ f = function(){}, // Native user-defined function.
+ d = new Date(),
+ a = [],
+ e = new Error("My Message.");
+ </CODE>
+ See also:
+ <MOREINFO>
+ <URL>http://dmitrysoshnikov.com/ecmascript/chapter-7-2-oop-ecmascript-implementation/</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="What is a built-in object?" ID="builtInObject">
+ <P>
+ A <DFN>built-in</DFN> object is any object supplied by an ECMAScript
+ implementation, independent of the host environment, that is present
+ at the start of the execution of an ECMAScript program.
+ </P>
+ <P>
+ ECMA-262 3rd Edition defines the following <DFN>built-in</DFN> objects:
+ </P>
+ <LIST TYPE="DL" ID="builtInsList">
+ <DT>Objects</DT>
+ <DD><EM>global</EM>, Math</DD>
+
+ <DT>Constructors</DT>
+ <DD>Object, Function, Array, String, Boolean, Number, Date, RegExp</DD>
+
+ <DT>Errors</DT>
+ <DD>Error, Date, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError</DD>
+
+ <DT>Functions</DT>
+ <DD>eval, parseInt, parseFloat, isNaN, isFinite, decodeURI,
+ decodeURIComponent, encodeURI, encodeURIComponent</DD>
+ </LIST>
+ <P>
+ ECMA-262 Edition 5 defines also the built-in object <ICODE>JSON</ICODE>.
+ </P>
+ <P>
+ Nonstandard <DFN>built-in</DFN> objects may include <ICODE>RuntimeObject</ICODE>,
+ <ICODE>String.prototype.link</ICODE>, <ICODE>CollectGarbage</ICODE>, and more.
+ </P>
+ </CONTENT>
+
+ <CONTENT TITLE="What is a host object?" ID="hostObject" NUMID="2_8">
+ <P>
+ A <DFN>host object</DFN> is any object supplied by the host environment to
+ complete the execution environment of ECMAScript.
+ </P>
+ <P>
+ A <DFN>host object</DFN> is not part of the ECMAScript implementation, but is
+ exposed to the ECMAScript implementation.
+ </P>
+ <P>
+ A <DFN>host object</DFN> may be implemented as a native ECMAScript object, however
+ this is not required. For example, Internet Explorer implements many
+ scriptable DOM objects as ActiveX Objects, often resulting in unexpected errors.
+ </P>
+ <P>
+ Availability and behavior of a host object depends on the host environment.
+ </P>
+ <P>
+ For example, in a browser, <ICODE>XMLHttpRequest</ICODE> might be available, with or
+ without standard or proprietary features or events. Windows Script Host object model
+ has the <ICODE>WScript</ICODE> object available.
+ </P>
+ <P>
+ For information on a particular host object, consult the pertinent
+ documentation available for the implementation(s). For web browsers,
+ this usually includes the w3c specifications as well as documentation
+ for that browser.
+ See also:
+ </P>
+
+ <MOREINFO>
+ <URL>notes/code-guidelines/#hostObjects</URL>
+ <URL>http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="When should I use eval?" ID="eval" NUMID="4_40">
+ <P>
+The <ICODE>eval</ICODE> function should <EM>only</EM> be used when it is necessary to
+evaluate a string supplied or composed at run-time; the string
+can be anything from a simple (but unpredictable) expression such
+as <ICODE>"12 * 2.54"</ICODE> to a substantial piece of javascript code.
+</P>
+<P>
+When <ICODE>eval( '{"key" : 42}' )</ICODE> is called, <ICODE>{</ICODE> is interpreted as a block of
+code instead of an object literal. Hence, the Grouping Operator (parentheses)
+is used to force <ICODE>eval</ICODE> to interpret the JSON as an object literal:
+<ICODE>eval( '({"key" : 42})' );</ICODE>.
+ </P>
+ <MOREINFO>
+ <URL>http://json.org/</URL>
+ <URL LINKTEXT="How do I access a property of an object using a string?"
+ >#propertyAccessAgain</URL>
+ <URL>notes/square-brackets/</URL>
+ </MOREINFO>
+ </CONTENT>
+ <CONTENT TITLE="How do I access a property of an object using a string?" ID="propertyAccessAgain" NUMID="4_39">
+ <P>
+ There are two ways to access properties: dot notation and square bracket
+ notation. What you are looking for is the square bracket notation in
+ which the dot, and the identifier to its right, are replaced with a set
+ of square brackets containing a string. The value of the string matches
+ the identifier. For example:-
+ </P>
+ <CODE>
+//dot notation
+var bodyElement = document.body;
+
+//square bracket notation, using an expression
+var bodyElement = document[&quot;bo&quot;+&quot;dy&quot;];
+ </CODE>
+ <MOREINFO>
+ <URL>notes/square-brackets/</URL>
+ </MOREINFO>
+ </CONTENT>
+</CONTENT>
\ No newline at end of file
/trunk/cljs/sections/objects.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/strings.xml
===================================================================
--- trunk/cljs/sections/strings.xml (nonexistent)
+++ trunk/cljs/sections/strings.xml (revision 45)
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Strings and RegExp" ID="strings">
+ <CONTENT TITLE="How do I trim whitespace?" ID="trimString" NUMID="4_16">
+ <P>
+ ECMAScript 5 defines <ICODE>String.prototype.trim</ICODE>. Where not supported,
+ it can be added as a function that uses a <DFN>regular expression</DFN>:
+ </P>
+ <CODE>
+if(!String.prototype.trim) {
+ String.prototype.trim = function() {
+ return String(this).replace(/^\s+|\s+$/g, "");
+ };
+}
+ </CODE>
+ <P>
+ Implementations are inconsistent with <ICODE>\s</ICODE>. For example,
+ some implementations, notably JScript 5.8 and Safari 2, do not match <ICODE>\xA0</ICODE>
+ (no-break space), among others.</P>
+ <P>
+ A more consistent approach would be to create a character class
+ that defines the characters to trim.
+ </P>
+ <MOREINFO>
+ <URL>https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp</URL>
+ <URL>http://thinkweb2.com/projects/prototype/whitespace-deviations/</URL>
+ <URL>https://developer.mozilla.org/en/Firefox_3.1_for_developers</URL>
+ <URL>http://docs.sun.com/source/816-6408-10/regexp.htm</URL>
+ <URL>http://msdn.microsoft.com/en-us/library/6wzad2b2%28VS.85%29.aspx</URL>
+ <URL>http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/c7010139217600c3/31092c5eb99625d0?#31092c5eb99625d0</URL>
+ <URL>http://unicode.org/Public/UNIDATA/PropList.txt</URL>
+ </MOREINFO>
+ </CONTENT>
+</CONTENT>
\ No newline at end of file
/trunk/cljs/sections/strings.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/sections/resources.xml
===================================================================
--- trunk/cljs/sections/resources.xml (nonexistent)
+++ trunk/cljs/sections/resources.xml (revision 45)
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONTENT TITLE="Javascript Resources" ID="ecmascriptResources" NUMID="3">
+ <CONTENT TITLE="What books are recommended for javascript?" ID="books" NUMID="3_1">
+ <P>
+ Most javascript books have been found to contain so many technical
+ errors that consensus recommendations have not emerged from the group.
+ </P>
+ <P>
+ The following books have been considered to have value by some
+ individuals on c.l.js. The reviews of these books are provided:
+ </P>
+ <LIST TYPE="UL">
+ <LI><EM>&quot;JavaScript: The Definitive Guide,&quot;</EM> 5th Edition, by David Flanagan
+ <UL>
+ <LI>Published: 2006-08</LI>
+ <LI>Pages: 1018</LI>
+ <LI>Errata: <URL>http://oreilly.com/catalog/9780596101992/errata/</URL></LI>
+ <LI>Discussed in:
+ <UL>
+ <LI>
+ <URL LINKTEXT="FAQ Update 9.85 Dated 2007-08-31"
+ >http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/7283898f77fd2a66/9252aa024e058dea#c5f145ae807c918e</URL>
+ </LI>
+ </UL>
+ </LI>
+ </UL>
+ </LI>
+ <LI>
+ <EM>"JavaScript, The Good Parts,"</EM> 1st Edition, by Douglas Crockford
+ <UL>
+ <LI>Published: 2008-05</LI>
+ <LI>Pages: 170</LI>
+ <LI>Errata: <URL>http://oreilly.com/catalog/9780596517748/errata/</URL></LI>
+ <LI>Discussed in:
+ <UL>
+ <LI>
+ <URL LINKTEXT="Crockford's 'The Good Parts': a short review"
+ >http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/d084d2109f7b4ec7#</URL>
+ </LI>
+ <LI>
+ <URL LINKTEXT="FunctionExpression's and memory consumptions"
+ >http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/db1e49ab113aa05c/3987eac87ad27966#3987eac87ad27966</URL>
+ </LI>
+ <LI>
+ <URL LINKTEXT="FAQ Topic - What books are recommended for javascript? (2008-12-02)"
+ >http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/6a41f7835ee728de/da5ccfc65e2df64a#da5ccfc65e2df64a</URL>
+ </LI>
+ <LI>
+ <URL LINKTEXT="Augmenting functions"
+ >http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/3a08fb741525ab6d/</URL>
+ </LI>
+
+ <LI>
+ <URL LINKTEXT="Crockford's JavaScript, The Good Parts (a book review)."
+ >http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/bf26be6e63494ee2/acb733a1c35f6ce5#ee9e4ee29e658d5d</URL>
+ </LI>
+ <LI>
+ <URL LINKTEXT="Closures Explained"
+ >http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/df602506ee48b400/e65e00f5cad07676#e65e00f5cad07676</URL>
+ </LI>
+ <LI>
+ <URL LINKTEXT="Javascript library development"
+ >http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/acadf1b22b219433/4f69a95607d0b3ae#4f69a95607d0b3ae</URL>
+ </LI>
+ </UL></LI>
+ </UL>
+ </LI>
+ </LIST>
+ </CONTENT>
+
+ <CONTENT TITLE="What online resources are available?" ID="onlineResources" NUMID="3_2">
+ <LIST TITLE="ECMAScript" TYPE="DL" ID="ecmaResources">
+ <DT>The Official ECMAScript Specification</DT>
+ <DD><URL>[ECMA-262] http://www.ecma-international.org/publications/standards/Ecma-262-arch.htm</URL></DD>
+
+ <DT>[ISO16262] ISO/IEC 16262, Second Edition 2002-06-01 : ISO Standard matching
+ ECMA-262 3rd Edition, with corrections.</DT>
+ <DD><URL>http://standards.iso.org/ittf/PubliclyAvailableStandards/c033835_ISO_IEC_16262_2002(E).zip</URL></DD>
+
+ <DT>[MS-ES3]: Internet Explorer ECMA-262 ECMAScript Language Specification Standards Support</DT>
+ <DD><URL>http://msdn.microsoft.com/en-us/library/ff520996%28VS.85%29.aspx</URL></DD>
+ <DD><URL>res/%5BMS-ES3%5D.pdf</URL> (local alias)</DD>
+
+ <DT>[MS-ES3EX]: Microsoft JScript Extensions to the ECMAScript Language Specification Third Edition</DT>
+ <DD><URL>http://msdn.microsoft.com/en-us/library/ff521046%28VS.85%29.aspx</URL></DD>
+ <DD><URL>res/%5BMS-ES3EX%5D.pdf</URL> (local alias)</DD>
+
+ <DT>ECMAScript on Wikipedia</DT>
+ <DD><URL>http://en.wikipedia.org/wiki/ECMAScript</URL></DD>
+ </LIST>
+
+ <LIST TITLE="W3C DOM" TYPE="DL" ID="domResources">
+ <DT>DOM Level 1 ECMAScript Binding</DT>
+ <DD><URL>http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html</URL></DD>
+
+ <DT>DOM Level 2 ECMAScript Binding</DT>
+ <DD><URL>http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html</URL></DD>
+
+ <DT>DOM Level 2 Events</DT>
+ <DD><URL>http://www.w3.org/TR/DOM-Level-2-Events/events.html</URL></DD>
+
+ <DT>DOM Level 2 Style</DT>
+ <DD><URL>http://www.w3.org/TR/DOM-Level-2-Style/</URL></DD>
+
+ <DT>DOM Level 3 ECMAScript Binding</DT>
+ <DD><URL>http://www.w3.org/TR/DOM-Level-3-Core/ecma-script-binding.html</URL></DD>
+ </LIST>
+
+ <LIST TITLE="Browser Documentation" TYPE="DL" ID="browserResources">
+ <DT>Mozilla</DT>
+ <DD>JavaScript: <URL>http://developer.mozilla.org/en/docs/JavaScript</URL></DD>
+ <DD>Gecko DOM Reference: <URL>http://developer.mozilla.org/en/docs/Gecko_DOM_Reference</URL></DD>
+
+ <DT>Microsoft</DT>
+ <DD>HTML and DHTML Reference: <URL>http://msdn.microsoft.com/en-us/library/ms533050.aspx</URL></DD>
+ <DD>JScript Language Reference:<URL>http://msdn.microsoft.com/en-us/library/hbxc2t98%28VS.85%29.aspx</URL></DD>
+ <DD>Scripting: <URL>http://msdn.microsoft.com/en-us/library/ms950396.aspx</URL></DD>
+
+ <DT>Opera</DT>
+ <DD>Web Specifications Support: <URL>http://www.opera.com/docs/specs/#ecmascript</URL></DD>
+
+ <DD>JavaScript Support: <URL>http://www.opera.com/docs/specs/js/</URL></DD>
+ <DD>ECMAScript Support: <URL>http://www.opera.com/docs/specs/js/ecma</URL></DD>
+
+ <DT>BlackBerry JavaScript Reference</DT>
+ <DD><URL>http://docs.blackberry.com/en/developers/deliverables/11849/</URL></DD>
+
+ <DT>ICab InScript</DT>
+ <DD><URL>http://www.muchsoft.com/inscript/</URL></DD>
+
+ <DT>Apple Safari</DT>
+ <DD>Web Content Guide: <URL>http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariWebContent/Introduction/Introduction.html</URL></DD>
+
+ <DT>Webkit</DT>
+ <DD>Project Site: <URL>http://webkit.org/</URL></DD>
+ <DD>Wiki: <URL>http://trac.webkit.org/wiki</URL></DD>
+ <DD>DOM Reference: <URL>http://developer.apple.com/Mac/library/documentation/AppleApplications/Reference/WebKitDOMRef/index.html#//apple_ref/doc/uid/TP40006089</URL></DD>
+
+ <DT>Netscape 4 Client-Side JavaScript Reference</DT>
+ <DD><URL>http://docs.sun.com/source/816-6408-10/</URL></DD>
+
+ <DT>Archived documentation for MSIE 3.x</DT>
+ <DD><URL>http://members.tripod.com/%7Ehousten/download/</URL></DD>
+ </LIST>
+
+ <LIST TITLE="Standalone ECMAScript Implementations" TYPE="DL" ID="standaloneImplementations">
+ <DT>Rhino: An open-source implementation of JavaScript written in Java</DT>
+ <DD><URL>http://www.mozilla.org/rhino/</URL></DD>
+
+ <DT>Besen IDE: ECMAScript Edition 5 with IDE</DT>
+ <DD><URL>http://besen.sourceforge.net/</URL></DD>
+
+ <DT>V8: Google's open source JavaScript engine</DT>
+ <DD><URL>http://code.google.com/p/v8/</URL></DD>
+
+ <DT>SpiderMonkey: Mozilla's C implementation of JavaScript</DT>
+ <DD><URL>http://www.mozilla.org/js/spidermonkey/</URL></DD>
+
+ <DT>Digital Mars DMD Script, console and MS Active Script implementation of ECMAScript</DT>
+ <DD><URL>http://www.digitalmars.com/dscript/</URL></DD>
+ </LIST>
+
+ <LIST TITLE="Other ECMAScript Implementations" TYPE="DL" ID="nonBrowserResources">
+ <DT>Developing Dashboard Widgets: Apple Developer Connection</DT>
+ <DD><URL>http://developer.apple.com/macosx/dashboard.html</URL></DD>
+
+ <DT>Whitebeam Apache Module: Server Side JavaScript in Apache</DT>
+ <DD><URL>http://www.whitebeam.org/</URL></DD>
+ </LIST>
+ </CONTENT>
+
+ <CONTENT TITLE="Javascript Libraries" ID="libraryResources">
+ <P>
+ No javascript libraries are endorsed by this group. If you want help
+ with using a library, visit that library's discussion group instead.
+ </P>
+ </CONTENT>
+</CONTENT>
\ No newline at end of file
/trunk/cljs/sections/resources.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/index.xsl
===================================================================
--- trunk/cljs/index.xsl (nonexistent)
+++ trunk/cljs/index.xsl (revision 45)
@@ -0,0 +1,293 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE xsl:stylesheet [
+ <!ENTITY nbsp "&#160;"><!-- no-break space = non-breaking space,
+ U+00A0 ISOnum -->
+]>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+ <xsl:output method="html"
+ doctype-public="-//W3C//DTD HTML 4.01//EN"
+ doctype-system="http://www.w3.org/TR/html4/strict.dtd"/>
+
+ <xsl:variable name="checkURLs" select="false"/>
+ <xsl:variable name="previous_url">http://jibbering.com/faq/</xsl:variable>
+ <xsl:variable name="previous_maintainer">Garrett Smith</xsl:variable>
+ <xsl:variable name="previous_maintainer_website">http://personx.tumblr.com/</xsl:variable>
+
+ <xsl:variable name="maintainer">Thomas 'PointedEars' Lahn</xsl:variable>
+ <xsl:variable name="maintainer_email"><![CDATA[cl&#106;&#115;&#64;&#80;o&#105;n&#116;&#101;d&#69;a&#114;s.&#100;&#101;]]></xsl:variable>
+ <xsl:variable name="maintainer_website">http://PointedEars.de/</xsl:variable>
+
+ <xsl:variable name="version" select="/FAQ/@VERSION"/>
+ <xsl:template match="/FAQ">
+ <xsl:variable name="revision_length" select="string-length('$Revision: ')"/>
+ <xsl:variable name="revision" select="substring(@revision, $revision_length, string-length(@revision) - $revision_length - 1)"/>
+ <xsl:variable name="updated" select="@DATE"/>
+
+ <html lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; UTF-8"/>
+ <title><xsl:value-of select="TITLE"/></title>
+ <meta name="DCTERMS.language" scheme="RFC1766" content="en"/>
+ <meta name="DC.title" content="FAQ for comp.lang.javascript"/>
+ <meta name="DCTERMS.subject"
+ content="Frequently asked questions in the Usenet newsgroup comp.lang.javascript"/>
+ <meta name="DC.format" content="text/html"/>
+ <meta name="DC.type" content="Text"/>
+ <meta name="DC.creator" content="Jim Ley"/>
+ <meta name="DC.publisher" content="{$maintainer}"/>
+ <meta name="DC.Publisher.Address"
+ content="{$maintainer_email}"/>
+ <meta name="DCTERMS.modified" content="{$updated}"/>
+ <meta name="DCTERMS.audience" content="Programmers, web developers"/>
+ <meta name="DC.description" content="Frequently Asked Questions about JavaScript and other ECMAScript implementations"/>
+ <meta name="DC.identifier" content="http://PointedEars.de/scripts/faq/cljs/"/>
+ <meta name="DC.source"
+ content="http://www.ecma-international.org/publications/standards/Ecma-262.htm"/>
+ <meta name="DC.source" content="news:comp.lang.javascript"/>
+ <meta name="DC.source" content="https://developer.mozilla.org/en/JavaScript"/>
+ <meta name="DC.source" content="http://msdn.microsoft.com/en-us/library/hbxc2t98%28VS.85%29.aspx"/>
+ <meta name="DC.source" content="http://msdn.microsoft.com/en-us/library/ms533050%28VS.85%29.aspx"/>
+ <meta name="DC.rights" content="copyright contributors, comp.lang.javascript"/>
+ <link rel="StyleSheet" href="faq.css" type="text/css" media="screen"/>
+ </head>
+ <body>
+ <h1><xsl:value-of select="TITLE"/></h1>
+
+ <p><!-- Revision <xsl:value-of select="$revision"/>
+ -->by <a href="{$maintainer_website}"><xsl:value-of select="$maintainer"/></a>
+ and <a href="#contributors">contributors</a><br/>
+ Based on the <a href="{$previous_url}">comp.lang.javascript FAQ</a>,
+ version <xsl:value-of select="$version"/>
+ of <xsl:value-of select="$updated"/>,
+ by <a href="{$previous_maintainer_website}"><xsl:value-of select="$previous_maintainer"/></a>
+ and contributors.</p>
+
+ <ul style="list-style: none; margin-left: 0; padding-left: 0">
+ <li><tt><xsl:value-of select="@id" /></tt></li>
+ <li><tt>$Id$</tt></li>
+ </ul>
+
+ <div>
+ <ul class="horizontal">
+ <li><a
+ href="http://PointedEars.de/wsvn/FAQs/trunk/cljs/?op=log&amp;isdir=1&amp;showchanges=1"
+ >Changelog</a></li>
+ <li><a
+ href="http://PointedEars.de/wsvn/FAQs/trunk/cljs/"
+ title="Subversion repository browser"
+ >SVN</a></li>
+ </ul>
+ </div>
+
+ <xsl:variable name="faq_uri">http://PointedEars.de/scripts/faq/cljs/</xsl:variable>
+ <p style="clear: left; text-align: left">
+ Available online at <a
+ href="{$faq_uri}"
+ ><xsl:value-of select="$faq_uri"/></a>
+ </p>
+
+ <hr/>
+
+ <h2 id="toc">Table of contents</h2>
+
+ <div id="nav"><a href="notes/">FAQ Notes</a></div>
+
+ <xsl:apply-templates select="CONTENTS" mode="toc"/>
+
+ <hr/>
+
+ <xsl:apply-templates select="CONTENTS"/>
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="CONTENTS" mode="toc">
+ <ul id="faqList">
+ <xsl:apply-templates select="CONTENT" mode="toc"/>
+ </ul>
+ </xsl:template>
+
+ <xsl:template match="CONTENTS">
+ <xsl:apply-templates select="CONTENT"/>
+ </xsl:template>
+
+ <xsl:template match="CONTENT" mode="toc">
+ <li><xsl:value-of select="position()"/>
+ <xsl:text> </xsl:text>
+ <a href="#{@ID}"><xsl:value-of select="@TITLE"/></a>
+
+ <xsl:if test="CONTENT">
+ <ul>
+ <xsl:apply-templates select="CONTENT" mode="subtoc">
+ <xsl:with-param name="section" select="position()" />
+ </xsl:apply-templates>
+ </ul>
+ </xsl:if></li>
+ </xsl:template>
+
+ <xsl:template match="CONTENT" mode="subtoc">
+ <xsl:param name="section"/>
+
+ <li><xsl:value-of select="$section"/>.<xsl:value-of select="position()"/>
+ <xsl:text> </xsl:text><a href="#{@ID}"><xsl:value-of select="@TITLE"/></a></li>
+ </xsl:template>
+
+ <xsl:template match="CONTENT">
+ <div id="{@ID}" class="section">
+ <xsl:element name="h2">
+ <xsl:call-template name="getOldId">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+
+ <xsl:value-of select="position()"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@TITLE"/>
+ </xsl:element>
+
+ <!-- introduction; TODO: use separate element -->
+ <xsl:for-each select="*">
+ <xsl:if test="local-name(.) != 'CONTENT'">
+ <xsl:apply-templates select="."/>
+ </xsl:if>
+ </xsl:for-each>
+
+ <xsl:variable name="section" select="position()"/>
+ <xsl:for-each select="CONTENT">
+ <xsl:apply-templates select="." mode="subsection">
+ <xsl:with-param name="section" select="concat($section, '.', position())"/>
+ </xsl:apply-templates>
+ </xsl:for-each>
+ </div>
+ </xsl:template>
+
+ <xsl:template name="getOldId">
+ <xsl:param name="node"/>
+ <xsl:if test="$node/@NUMID">
+ <xsl:attribute name="id">FAQ<xsl:value-of select="$node/@NUMID"/></xsl:attribute>
+ </xsl:if>
+ </xsl:template>
+
+ <xsl:template match="CONTENT" mode="subsection">
+ <xsl:param name="section"/>
+
+ <div id="{@ID}" class="section">
+ <xsl:element name="h3">
+ <xsl:call-template name="getOldId">
+ <xsl:with-param name="node" select="."/>
+ </xsl:call-template>
+ <xsl:value-of select="$section"/><xsl:text> </xsl:text>
+ <xsl:value-of select="@TITLE"/>
+ </xsl:element>
+
+ <xsl:apply-templates />
+ </div>
+ </xsl:template>
+
+ <xsl:template match="VER">
+ <xsl:value-of select="$version"/>
+ </xsl:template>
+
+ <xsl:template match="UPDATED">
+ <xsl:value-of select="$updated"/>
+ </xsl:template>
+
+ <xsl:template match="URL">
+ <!-- TODO: Link check, see process.wsf -->
+ <xsl:element name="a">
+ <xsl:variable name="uri" select="text()"/>
+ <xsl:attribute name="href"><xsl:value-of select="$uri"/></xsl:attribute>
+ <xsl:if test="$checkURLs">
+ <xsl:choose>
+ <xsl:when test="starts-with($uri, 'http://')">
+ <xsl:variable name="response" select="document($url)"/>
+ <xsl:if test="not($response) or contains($url, 'microsoft') and contains($response, 'Page Cannot')">
+ <xsl:attribute name="class">nolink</xsl:attribute>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="response" select="document(concat('http://www.google.com/search?q=cache:', $url), '/')"/>
+ <xsl:choose>
+ <xsl:when test="$response">
+ <xsl:attribute name="class">cached</xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="class">nolink</xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:attribute name="class">nolink</xsl:attribute>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+
+ <xsl:value-of select="@LINKTEXT|text()"/>
+ </xsl:element>
+ </xsl:template>
+
+ <xsl:template match="NEWSGROUP">
+ <a href="news:{.}'"><xsl:value-of select="."/></a>
+ </xsl:template>
+
+ <xsl:template match="MAILTO">
+ <a href="mailto:{.}'"><xsl:value-of select="."/></a>
+ </xsl:template>
+
+ <xsl:template match="MOREINFO">
+ <ul class="linkList">
+ <xsl:for-each select="*">
+ <li><xsl:apply-templates select="."/></li>
+ </xsl:for-each>
+ </ul>
+ </xsl:template>
+
+ <xsl:template match="CODE">
+ <pre><code><xsl:apply-templates/></code></pre>
+ </xsl:template>
+
+ <xsl:template match="ICODE">
+ <code><xsl:apply-templates /></code>
+ </xsl:template>
+
+ <xsl:template match="LIST">
+ <xsl:if test="@TITLE">
+ <xsl:element name="h4">
+ <xsl:if test="@ID">
+ <xsl:attribute name="id"><xsl:value-of select="@ID"/></xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="@TITLE"/>
+ </xsl:element>
+ </xsl:if>
+
+ <xsl:variable name="type">
+ <xsl:choose>
+ <xsl:when test="@TYPE"><xsl:value-of select="@TYPE"/></xsl:when>
+ <xsl:otherwise>ul</xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:element name="{$type}">
+ <xsl:if test="not(@TITLE) and @ID">
+ <xsl:attribute name="id"><xsl:value-of select="@ID"/></xsl:attribute>
+ </xsl:if>
+
+ <xsl:for-each select="*">
+ <xsl:apply-templates select="."/>
+ </xsl:for-each>
+ </xsl:element>
+ </xsl:template>
+
+ <xsl:template match="P">
+ <xsl:copy>
+ <!-- NOTE: do not copy invalid attributes -->
+ <xsl:apply-templates select="@*[local-name() != 'HTMLONLY']"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:template>
+
+ <!-- standard copy template -->
+ <xsl:template match="@*|node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@*"/>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:template>
+</xsl:stylesheet>
\ No newline at end of file
/trunk/cljs/index.xsl
Property changes:
Added: svn:keywords
## -0,0 +1 ##
+Id
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/notes/code-guidelines/index.html
===================================================================
--- trunk/cljs/notes/code-guidelines/index.html (nonexistent)
+++ trunk/cljs/notes/code-guidelines/index.html (revision 45)
@@ -0,0 +1,615 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
+<title>Code Guidelines for Rich Internet Application Development</title>
+
+<link rel="schema.DC" href="http://www.purl.org/dc/elements/1.1/">
+<meta name="DC.title" lang="en" content="Code Guidlines for Rich Internet Applications">
+<meta name="DC.date" scheme="W3CDTF" content="2010-05-29">
+<meta name="DC.source" content="http://www.ecma-international.org/publications/standards/Ecma-262.htm">
+<meta name="DC.publisher" content="Garrett Smith">
+<meta name="DC.Publisher.Address" content="dhtmlkitchen&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">
+<meta name="DCTERMS.audience" content="Programmers, web developers">
+<meta name="DC.description" content="Guidlines and Best Practices for javascript (ECMAScript) in web applications.">
+<meta name="DC.source" content="http://www.ecma-international.org/publications/standards/Ecma-262.htm">
+<meta name="DC.source" content="http://www.w3.org/TR/html4/">
+
+<meta name="DCTERMS.language" scheme="RFC1766" content="en">
+<link rel="DCTERMS.isReferencedBy" href="/faq/notes/" >
+
+<meta name="DC.source" content="news:comp.lang.javascript">
+
+
+<link href="../../faq.css" rel="stylesheet" type="text/css">
+<link href="../notes.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+li {
+ font-weight: bold;
+}
+li p, li div, ul ul ul li {
+ font-weight: normal;
+}
+h4 {
+ margin: .5ex;
+ font-size: 1em;
+}
+</style>
+
+</head>
+<body>
+<h1>Code Guidelines for Rich Internet Application Development</h1>
+<div id="faqNav">
+ <a href="../../">FAQ</a> &gt; <a href="../">FAQ Notes</a>
+</div>
+<p>
+By Garrett Smith, with contributions from Asen Bozhilov, RobG, John G Harris, David Mark, and Dmitry Soshnikov.
+</p>
+<h2>Abstract</h2>
+<p>
+ This document points to the causes of errors and problems related to javascript
+ for web applications and provides explanation of what to do instead.
+</p>
+<p>
+ When followed, these guidelines can improve the code
+ stability and maintainability of a Rich Internet Application deployed
+ across a wide range of web browsers.
+</p>
+<p>
+ For code reviews, this document and the
+ <a href="../review/">Code Review Guidelines</a> should be read by the code author and code reviewer.
+</p>
+<h2>Guidelines</h2>
+<ul>
+ <li>Markup
+ <ul>
+ <li>
+ <p>Use valid html <a href="http://validator.w3.org">validator.w3.org</a>.</p>
+ <p>
+ Code that uses malformed, nonconforming HTML is expecting nonstandard behavior.
+ When a web browser encounters a problem in HTML, it must perform error correction.
+ Since there are no error correction mechanisms defined in HTML 4, browsers
+ handle the problem in proprietary ways.
+ </p>
+ <p>
+ When the browser parses a document, it creates a DOM representation of it.
+ If the browser performed error correction when parsing, the outcome is a
+ different DOM. For an example with a detailed explanation, see:
+ <a href="http://ln.hixie.ch/?start=1037910467&amp;count=1"
+ >Tag Soup: How UAs handle &lt;x&gt; &lt;y&gt; &lt;/x&gt; &lt;/y&gt;</a>
+ and also <a href="http://jibbering.com/faq/notes/detect-browser/#bdValid"
+ >Avoiding Structural Differences in the Browser DOMs</a>.
+ </p>
+ <p>
+ The W3C validator results either with green <code>PASS</code> or with one or more errors
+ at which point it is clear that the code is not completed to
+ standard.
+ </p>
+ </li>
+ <li>
+ <p>Use standards mode, with HTML <code>DOCTYPE</code> first (neither comments nor xml declaration preceeding it).</p>
+ </li>
+ <li>
+ <p>Reduce the markup to simplest semantic markup necessary.</p>
+ <p>Simpler code is easier to read.</p>
+ <p>
+ More markup means more bytes transferred over the wire,
+ more parsing for the browser, and a larger DOM for scripts
+ to traverse.
+ </p>
+ </li>
+ <li><p>Set the HTTP content-type text/html.</p></li>
+ <li>
+ <p>Set charset in HTTP or, if using a <code>META</code> tag, as
+ <a href="http://www.w3.org/TR/html4/charset.html#spec-char-encoding">early as possible</a>
+ in the <code>HEAD</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Escape ETAGO delimiter with backwards solidus (backslash).
+ See also : <a href="http://www.cs.tut.fi/~jkorpela/www/revsol.html"
+ >The reverse solidus (backslash, <code>\</code>) in Web authoring</a>.
+ </p>
+ <p>
+ A reverse solidus (backslash) should appear before the solidus
+ symbol in the sequence "&lt;/", resulting in "&lt;\/", and not "&lt;" + "/".
+ <a href="http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.2.1"
+ >ETAGO in SCRIPT and STYLE</a>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Do not use <code>javascript:</code> pseudo protocol.
+ <a href="../../#javascriptURI">FAQ: I have &lt;a href=&quot;javascript:somefunction()&quot;&gt; what ... ?</a>
+ </p>
+ </li>
+ </ul>
+ <h3>Validation Note</h3>
+ <p>
+ The <a href="http://validator.w3.org/docs/help.html#validandconform">W3C
+ validator does not validate conformance</a>. Conformance errors can
+ cause problems and must be recognized and corrected. See also:
+ <a href="http://www.w3.org/TR/html4/appendix/notes.html#notes-invalid-docs"
+ >Appendix B: Performance, Implementation, and Design Notes: Invalid Documents</a>,
+ which states <cite>This specification does not define how conforming
+ user agents handle general error conditions...</cite>
+ </p>
+
+ <p>
+ When the code does not do what is wanted of it, it is important to understand
+ why. The HTML validator can help because it can report HTML errors (and much more quickly
+ than a tired human eye could).
+ </p>
+
+ <p>
+ Poring over a long list of validation errors to find the validation error(s)
+ that could be related to the code not doing what is wanted of it is error-prone,
+ time-consuming guesswork. When an HTML error is found, the next task is finding
+ when that error crept in, why it is there, what other code is relying
+ on the problematic area, who wrote that other code, where is he now, so a
+ possible fix can be discussed, etc. Using invalid HTML is a waste of time.
+ Instead, by always using valid HTML, clear expectations can be made of what
+ the code should be doing.
+ </p>
+
+ <p>
+ Running the W3C validator is a little extra effort that saves a lot of time.
+ See also: <a href="http://validator.w3.org/docs/why.html">W3C: Why Validate?</a>
+ </p>
+ </li>
+
+ <li>
+ CSS
+ <ul>
+ <li>
+ <p>
+ Use valid css. (Excepting vendor extensions and css 3 features).
+ <a href="http://jigsaw.w3.org/css-validator/">http://jigsaw.w3.org/css-validator/</a>
+ </p>
+ </li>
+ <li>
+ <p>
+ Class and id selectors should have semantic meaning. See also:
+ <a href="http://www.w3.org/QA/Tips/goodclassnames">Use class with semantics in mind</a>.
+ Selectors such as <code>.redButton</code>, <code>#ItalicStatement</code> are meaningless.
+ Instead, use class and id that represent an object or state.
+ </p>
+ Example:
+ <pre>.errorButton, #warningMessage, .active-panel</pre>
+ <p>
+ This makes the code meaningful even when the styles change.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ Script:
+ <ul>
+ <li>Variables
+ <ul>
+ <li>
+ <p>
+ Declare variables in the narrowest possible scope, never global.
+ </p>
+ </li>
+ <li>
+ <p>
+ Do not assign to undeclared identifiers (do not forget <code>var</code>).
+ </p>
+ </li>
+ <li>
+ <p>
+ Give each identifier a meaningful name.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li id="methods">Methods
+ <ul>
+ <li>
+ Avoid initialization routines that loop through the DOM.
+ Instead, use event delegation and inspect the target (see design
+ section).
+ </li>
+ <li>Avoid methods that do too much or have side effects. Methods should be simple and do one thing.</li>
+ <li>Avoid long parameter lists. The fewer the better.</li>
+ <li>Do not include non-localized strings in scripts (excepting developer error messages).</li>
+ <li>Be clear and consistent with their return type.</li>
+ <li>Test not only that it succeeds correctly (happy path),
+ but also that it fails correctly (sad path). </li>
+ </ul>
+ </li>
+ <li id="design">Design
+ <ul>
+ <li>Avoid creating and using useless methods, e.g.
+ <pre>goog.isDef = function(val) {
+ return val !== undefined;
+};
+</pre>
+ </li>
+ <li>
+ Do not use non-standard or inconsistent ECMAScript methods (<code>substr</code>,
+ <code>escape</code>, <code>getYear</code>, <code>parseInt</code> with no radix). Instead, use
+ <code>substring</code>, <code>encodeURIComponent</code>, <code>getFullYear</code>,
+ and <code>parseInt(<var>s</var>, 10)</code> with a radix, respectively.
+ </li>
+ <li>
+ Do not use non-standard syntax such as "function statement"
+ (see also: <a href="/faq/#functionStatement">FAQ: What is a function statement?</a> and
+ <a href="http://kangax.github.io/nfe/"
+ >Named Function Expressions</a>).
+ </li>
+ <li>
+ Consider refactoring a function with conditionals to dynamic dispatch or
+ function redefinition.
+ </li>
+ <li>
+ Avoid modifying objects you don't own.
+ <p>
+ A piece of code that modifies any object it does not own is not
+ clear to the client of the API where those changes are coming from.
+ </p>
+
+ <p>
+ Modifying built-ins has been known to cause forwards-compatibility problems
+ and conflict with other code. Modifying host objects can result in
+ javascript errors.
+ </p>
+
+ <p>
+ Instead, use another approach. For example, define your own object, possibly hidden
+ in a closure.
+ </p>
+
+ <p>
+ Modifying host objects or host objects' constructors' prototypes with new properties
+ is unspecified. The practice has been known to be the source of cross-browser problems.
+ </p>
+
+ <p>
+ Where DOM host objects are implemented with prototypes, the prototype chain
+ is implementation-dependent (not specified). The interface-based API design of the
+ <a href="http://www.w3.org/TR/DOM-Level-2-HTML/">W3C DOM</a> does not forbid a
+ sub-interface from providing a more specific implementation that could shadow
+ the a user-defined method of the same name further up in the prototype chain.
+ </p>
+ <p>
+ The W3C DOM does not prevent implementations from creating their own
+ interfaces. Quite often implementations do create interfaces that are
+ interwoven through the interface hierarchy. Such interfaces may or may
+ not be accessible to code.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ Strings:
+ <ul>
+ <li>
+ Use efficient string concatenation techniques. Do not repeatedly create
+ and discard temporary strings.
+ </li>
+ <li>
+ Instead use <code>String.prototype.concat(a, b, c)</code> or
+ <code>htmlArray.push(a, b, c);</code>
+ </li>
+ </ul>
+ </li>
+ <li>
+ Loops:
+ <ul>
+ <li>
+ Avoid chains of identifiers in loop.
+ Replace a long chain of identifiers with a variable.
+ </li>
+ <li>
+ Do not traverse over elements to modify the style or add an event
+ callback to each element.
+ <div>
+
+ <p>
+ For Styles, replace a loop that applies styles to descendants by
+ adding a class token to the nearest common ancestor (<a
+ href="descendant-sel.html">example</a>).
+ </p>
+ <ol>
+ <li>
+ Add a style rule to the stylesheet with selector text
+ <code>.special-state .special-descendant-class</code>.
+ </li>
+ <li>
+ In the HTML, for each element to be to dynamically updated, add
+ the class attribute <code>"special-descendant-class"</code>.
+ </li>
+ <li>
+ In the script, add the class "special-state" to the ancestor
+ and.
+ The style rule defined in the stylesheet will be applied to
+ the descendants with <code>"special-descendant-class"</code>.
+ </li>
+ </ol>
+ <p>
+ For events, use event delegation. That is, replace a loop that adds a
+ callback to each element in a collection with a callback on a common ancestor.
+ </p>
+ </div>
+ </li>
+ </ul>
+ </li>
+ <li>Statements:
+ <ul>
+ <li>
+ <p>
+ Do not use <code>==</code> where strict equality is required.
+ Where strict equality is required, the strict equality operator <code>===</code> must be used.
+ The strict equality operator should always be used to compare objects.
+ </p>
+ </li>
+ <li>
+ <p>
+ Do not use Boolean conversion of value that may be acceptably falsish,
+ e.g. <code>if(e.pageX)</code>.
+ </p>
+ <p>
+ Instead check the property using <code>typeof</code>. For example:
+ <code>if(typeof e.pageX == "number")</code>.
+ </p>
+ </li>
+ <li>
+ <p>
+ Do not use useless statements (e.g. <code>typeof it == "array"</code>). In addition to
+ contributing to code size and runtime performance, useless statements make the
+ code harder to understand.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li id="regex">
+ Regular Expressions
+ <ul>
+ <li>
+ Be simple, but do not match the wrong thing.
+ A complex regular expression is harder to understand than a simple one.
+
+ <p>
+ The context of a Regular Expression is as important as what it can match.
+ A complex regular expression is harder to understand than a simple one.
+ Simple regular expressions are preferred. It is sometimes acceptable for the
+ expression to match the wrong thing, just so long as the context in which it
+ is used precludes or handles that.
+ </p>
+ <pre>
+// Wrong: Matches 137, 138...
+ARROW_KEY_EXP : /37|38|39|40/;
+
+// Right: matches only arrow keys.
+ARROW_KEY_EXP : /^(?:37|38|39|40)$/;
+
+// Simple: Can match the wrong thing, but that can be handled.
+var iso8601Exp = /^\s*([\d]{4})-(\d\d)-(\d\d)\s*$/;
+</pre>
+ <p>
+ Trying to match leap years would be excessively complex.
+ Instead, the date validation can be addressed where the expression is used.
+ </p>
+ <p>
+ As with functions, test not only that it succeeds correctly,
+ but also that it fails correctly.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li id="formatting">
+ Formatting:
+ <ul>
+ <li>
+ Code should not be formatted with tabs.
+ Space indentation should be used consistently.
+ </li>
+ <li>
+ Code should be formatted to a maximal line length. For newsgroup code,
+ it should not exceed 72 chars.
+ </li>
+ <li id="asi">Semicolons:
+ <h4>Semicolons, Newlines, and ASI (Automatic Semicolon Insertion)</h4>
+ <p>
+ Avoid mistakes caused by <dfn title="Automatic Semicolon Insertion">ASI</dfn>.
+ </p>
+
+ <p>
+ In ECMAScript, line terminators affect how a program is interpreted. This is a design
+ mistake of the language of which the details are complicated. The following guidelines
+ can help avoid ASI problems with both <dfn>restricted productions</dfn> and productions that
+ are not restricted.
+ </p>
+ <h5>Line Terminators: Restricted Productions</h5>
+
+ <p>
+ <dfn>Restricted productions</dfn> include only the postfix operators and the control
+ statements <code>return</code>, <code>throw</code>, <code>continue</code>, and
+ <code>break</code>. ASI affects a <dfn>restricted productions</dfn>
+ when a line terminator is introduced. The following guidelines help avoid that mistake:
+ </p>
+ <h5>ASI Guidelines for <dfn>restricted productions</dfn>:</h5>
+ <ul>
+ <li>
+ A postfix <code>++</code> or <code>--</code> operator must appear
+ on the same line as its operand.
+ </li>
+ <li>An Expression in a <code>return</code> or <code>throw</code> statement must
+ start on the same line as the <code>return</code> or <code>throw</code> token.
+ </li>
+ <li>
+ An Identifier in a <code>break</code> or <code>continue</code> statement
+ must be on the same line as the <code>break</code> or <code>continue</code> token.
+ </li>
+ </ul>
+
+ <h5>Guidelines for Semicolons in Source Code:</h5>
+ <ul>
+ <li>
+ <p>
+ Don't rely on ASI. Use semicolons explicitly.
+ </p>
+ <p>
+ A program that uses semicolons explicitly is less
+ susceptible to different interpretation caused by
+ changes in line terminators and expressions.
+ </p>
+ <p>
+ For more details, please see: <a href="asi.html"
+ >Automatic Semicolon Insertion : Unrestricted Productions</a>
+ </p>
+ </li>
+ </ul>
+ <h5>Extraneous Semicolons and The Empty Statement, ;</h5>
+ <p>
+ While it is important use semicolons explicitly, where required,
+ there are cases where a semicolon should not be added.
+ </p>
+ <p>
+ The <dfn>Statement</dfn>s that do not end in semicolon all end in close
+ curly braces instead. They are :
+ </p>
+<pre>
+Block:
+ { ... }
+
+SwitchStatement:
+ switch ( ... ) { ... }
+
+TryStatement:
+ try ... catch ( ... ) { ... }
+ try ... finally { ... }
+</pre>
+
+ <p>
+ Something that isn't a statement but looks like one:
+ </p>
+<pre>
+Function Declaration:
+ function x{ ... }
+</pre>
+ <p>
+ A semicolon that immediately follows a FunctionDeclaration
+ is interpreted as an <dfn>EmptyStatement</dfn>. Useless
+ statements should be avoided.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li id="dom">
+ DOM:
+ <ul>
+ <li id="unrelatedInference">
+ Do not use poor or unrelated inferences such as <a href="../detect-browser/">browser detection</a>
+ (see also <a href="../../#detectBrowser">FAQ: How do I detect Opera/Safari/IE?</a>).
+ <pre>// Unrelated inference:
+if(typeof window.innerHeight == "number") // it isn't IE
+// Good inference:
+if(typeof window.innerHeight == "number") // innerHeight available.
+
+// Unrelated inference based on proprietary XUL feature (Borrowed from MooTools).
+// See also: Bug 340571 - getBoxObjectFor leaking-onto-the-Web disaster
+// https://bugzilla.mozilla.org/show_bug.cgi?id=340571
+gecko: function(){
+ return (document.getBoxObjectFor == undefined) ? false : ((document.getElementsByClassName) ? 19 : 18);
+}
+</pre>
+ </li>
+ <li>
+ Use standards W3C DOM approach preferentially and proprietary DOMs as a fallback.
+ </li>
+ <li>
+ If an approach requires several branches for handling browser variance,
+ look for a different approach that works in all tested browsers.
+ </li>
+ <li>
+ Do not traverse the DOM on page load; do not traverse the DOM
+ using user-defined css query selector.
+ </li>
+ <li>
+ Instead of traversing the DOM, use Event delegation.
+ </li>
+ </ul>
+ </li>
+ <li id="hostObjects">
+ Host Objects:
+ <ul>
+ <li>Operators:
+ <ul>
+ <li>
+ Do not use <code>delete</code> operator with host object This will cause errors in IE, and others:
+ <pre>delete window.location; //Security error" code: "1000"</pre>
+ </li>
+ <li>
+ Do not add any expando properties (<code>unselectable</code> is safe).
+ See also: <a href="http://msdn.microsoft.com/en-us/library/ms533747(v=VS.85).aspx"
+ >msdn expando</a>.
+ </li>
+ <li>
+ Host objects that error upon <code>[[Get]]</code> access are often
+ <code>ActiveX</code> objects. These include, but are not limited to:
+ <ul>
+ <li>
+ Disconnected nodes whose <code>parentNode</code> is not an element (<code>node.offsetParent</code>).
+ </li>
+ <li>
+ <code>XMLHttpRequest</code> methods (<code>open</code>, <code>send</code>, etc).
+ </li>
+ <li>
+ filters: <code>elem.filters.alpha</code>, <code>elem.style.filters.alpha</code>, etc.
+ </li>
+ <li>
+ <code>document.styleSheets[99999] </code>- Error from <code>[[Get]]</code> for a
+ nonexistent numeric property of a <code>styleSheets</code> collection.
+ </li>
+ <li>
+ <code>link.href</code> for <code>nntp:</code> links in IE.
+ </li>
+ <li>
+ <code>NodeList</code> in Safari 2 - do not attempt access a
+ nonexistent property
+ (e.g. <code>document.childNodes.slice</code>).
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>Type conversion
+ <dl>
+ <dt><code>[[ToString]]</code></dt>
+ <dd>Perform string conversion by starting concatenation with a string value.
+ See <a href="http://groups.google.bg/group/comp.lang.javascript/msg/1528f612e31f09fe"
+ >Newsgroup message explanation</a>.
+ </dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ Comments:
+ <ul>
+ <li>
+ Avoid too many comments; let the code speak for itself.
+ </li>
+ <li>
+ Avoid comments that are likely to become obsolete or are redundant.
+ </li>
+ <li>
+ Explain <em>why</em>, not <em>what</em>.
+ Comments should help explain things that are not obvious.
+ </li>
+ <li>
+ Comments should never contain inaccurate statements or terminology,
+ should never be misleading, and should be well-written.
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+</ul>
+</body>
+</html>
/trunk/cljs/notes/code-guidelines/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/notes/code-guidelines/asi.html
===================================================================
--- trunk/cljs/notes/code-guidelines/asi.html (nonexistent)
+++ trunk/cljs/notes/code-guidelines/asi.html (revision 45)
@@ -0,0 +1,152 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
+
+<link rel="schema.DC" href="http://www.purl.org/dc/elements/1.1/">
+
+<meta name="DC.title" lang="en" content="Automatic Semicolon Insertion - Unrestricted Productions">
+<meta name="DC.date" scheme="W3CDTF" content="2010-05-29">
+
+<meta name="DC.source" content="http://www.ecma-international.org/publications/standards/Ecma-262.htm">
+<meta name="DC.publisher" content="Garrett Smith">
+<meta name="DC.Publisher.Address" content="dhtmlkitchen&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">
+<meta name="DCTERMS.audience" content="Programmers, web developers">
+<meta name="DC.description" content="How Automatic Semicolon Insertion affects an ECMAScript program.">
+<meta name="DC.source" content="http://www.ecma-international.org/publications/standards/Ecma-262.htm">
+<meta name="DCTERMS.language" scheme="RFC1766" content="en">
+<link rel="DCTERMS.isReferencedBy" href="./#asi" >
+
+<meta name="DC.source" content="news:comp.lang.javascript">
+
+<link href="../../faq.css" rel="stylesheet" type="text/css">
+<link href="../notes.css" rel="stylesheet" type="text/css">
+<title>Automatic Semicolon Insertion - Unrestricted Productions</title>
+</head>
+<body>
+<h1>Automatic Semicolon Insertion</h1>
+<p>
+ Article by Garrett Smith
+</p>
+<p>
+ This document is an addendum to <a href="./#asi"
+ >Code Guidelines for Rich Internet Application Development</a>.
+</p>
+<h2>Unrestricted Productions</h2>
+<p>
+ Productions that are not <dfn>restricted</dfn> can be created accidentally where
+ <abbr title="automatic semicolon insertion">ASI</abbr> has been used. This is often
+ the result of where the developer forgot to use a
+ semicolon. Regardless, the problems it creates can occur when the order of <dfn>Statements</dfn>
+ changes or when line terminators are added or removed, including those that appear in comments.
+ Where semicolons are needed, it is recommended that they appear explicitly.
+</p>
+<ul>
+ <li>
+ <dfn>Arguments</dfn> and property access operations can be created accidentally when the
+ program relies on <abbr title="automatic semicolon insertion">ASI</abbr>.
+ </li>
+ <li>
+ Line terminators in comments affect <abbr title="automatic semicolon insertion">ASI</abbr> but behavior in implementations,
+ notably JScript, vary.
+ </li>
+ </ul>
+ <h3>Grouping Operator or Arguments?</h3>
+ <p>
+ The parentheses following an <dfn>Expression</dfn>
+ interpreted as <dfn>Arguments</dfn>, implicating the <dfn>Expression</dfn> in
+ a <dfn>CallExpression</dfn>:
+ </p>
+<pre>var MyWidget = function(){
+ this.name = "mike";
+}
+/**
+ * Initialize Widget
+ */
+(function() {
+ /*...*/
+});</pre>
+ <p>
+
+ The <dfn>FunctionExpression</dfn> that appears on the right hand side of the assignment
+ to the identifier <code>MyWidget</code> would be called because the parentheses,
+ which were intended to be a <dfn>Grouping Operator</dfn>, are interpreted as <dfn>Arguments</dfn>
+ in a <dfn>CallExpression</dfn>, resulting in <code>MyWidget</code> having the value
+ <code>undefined</code> and <code>window.name</code> getting the value <code>"mike"</code>.
+ </p>
+
+ <p>
+ This can be explained by the fact that a program is scanned from left to right,
+ repeatedly taking the longest possible sequence of characters as the next input element.
+ Since a <dfn>CallExpression</dfn> is not a <dfn>restricted production</dfn>, the program
+ would be interpreted as:
+ </p>
+ <pre>
+var MyWidget = function(){
+ this.name = "mike";
+}(function() {});
+</pre>
+<h3>ArrayLiteral or Property Accessor?</h3>
+<p>
+An <dfn>ArrayLiteral</dfn> can be interpreted as property accessor after the
+removal of a <dfn>restricted production</dfn>. In this case, <dfn>Expression</dfn> <code>g--</code>.
+</p>
+<pre>
+var g = 12
+g--
+[].slice.call([1,2,3])</pre>
+<p>
+The program is interpreted as:
+</p>
+<pre>
+var g = 12<kbd>;</kbd>
+g--<kbd>;</kbd>
+[].slice.call([1,2,3])
+</pre>
+<p>
+When the postfix operator is removed, a <dfn>SyntaxError</dfn> results. Given the input:
+</p>
+<pre>
+var g = 12
+--g
+[].slice.call([1,2,3])
+</pre>
+<p>The program is interpreted as:-</p>
+<pre>
+var g = 12;
+--g[].slice.call([1,2,3])
+</pre>
+<p>
+- and that program is not valid syntax so it results in a <dfn>SyntaxError</dfn>.
+</p>
+<h3>Line Terminators in Comments</h3>
+<p>
+ A LineTerminator in any <dfn>MultilineComment</dfn> affects
+ <abbr title="automatic semicolon insertion">ASI</abbr>. From ECMAScript Edition 5 specification, 5.1.2:
+</p>
+<blockquote>
+<p>
+ A <dfn>MultiLineComment</dfn> (that is, a comment of the form /*...*/
+ regardless of whether it spans more than one line) is likewise simply
+ discarded if it contains no line terminator; but if a <dfn>MultiLineComment</dfn>
+ contains one or more line terminators, then it is replaced by a single
+ line terminator, which becomes part of the stream of input elements
+ for the syntactic grammar.
+</p>
+</blockquote>
+
+<p>
+ Not all implementations follow rules of whitespace in MultiLineComment. JScript is one
+ such implementation that does not process a <dfn>MultiLineComment</dfn> that contains
+ a <dfn>LineTerminator</dfn> as a <dfn>LineTerminator</dfn>.
+</p>
+<p>
+ A program that uses semicolons explicitly avoids such problems and is less
+ susceptible to behavior changes (including script errors) caused by inadvertent changes in
+ line terminators and expressions, including those introduced
+ by build tools (e.g. minficication).
+</p>
+
+</body>
+</html>
/trunk/cljs/notes/code-guidelines/asi.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/notes/code-guidelines/descendant-sel.html
===================================================================
--- trunk/cljs/notes/code-guidelines/descendant-sel.html (nonexistent)
+++ trunk/cljs/notes/code-guidelines/descendant-sel.html (revision 45)
@@ -0,0 +1,102 @@
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+
+<html lang="en">
+<head>
+<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
+<link rel="Index" href="../">
+<title>Toggle Class To Trigger Descendant Selector Rules</title>
+
+<style type="text/css">
+/* Make table pretty */
+table {
+ border: 1px solid #8893af;
+ background: #dfe3ff;
+ width: 33em;
+ font-family: verdana, sans-serif;
+ margin: 12px;
+}
+tr {
+ background: #eef6ff;
+}
+
+td {
+ padding: 4px;
+}
+
+/* The descendant selector trick */
+.even .odd-row, .odd tr {
+ display: none;
+}
+
+.odd .odd-row {
+ display: block;
+ display: table-row;
+}
+
+.odd-row {
+ background: #fdfeff;
+}
+</style>
+
+<script type="text/javascript">
+function showEven() {
+ var testTable = document.getElementById("testTable");
+ testTable.className = "even";
+}
+
+function showOdd() {
+ var testTable = document.getElementById("testTable");
+ testTable.className = "odd";
+}
+
+function showAll() {
+ var testTable = document.getElementById("testTable");
+ testTable.className = "";
+}
+</script>
+</head>
+
+<body>
+<h1>Toggle Class To Trigger Descendant Selector Rules</h1>
+<h2>Description</h2>
+<p>
+ By toggling a class name on the table, the descendant selector is applied and certain rows are shown
+ and hidden.
+</p>
+<h2>Demonstration</h2>
+<div>
+ <button onclick="showEven()">showEven()</button>
+ <button onclick="showOdd()">showOdd()</button>
+ <button onclick="showAll()">showAll()</button>
+</div>
+
+<table id="testTable">
+ <tr>
+ <td>even row, even row, even row, even row, even row, even row</td>
+ </tr>
+ <tr class="odd-row">
+ <td>odd row, odd row, odd row, odd row, odd row, odd row</td>
+ </tr>
+ <tr>
+ <td>even row, even row, even row, even row, even row, even row</td>
+ </tr>
+ <tr class="odd-row">
+ <td>odd row, odd row, odd row, odd row, odd row, odd row</td>
+ </tr>
+ <tr>
+ <td>even row, even row, even row, even row, even row, even row</td>
+ </tr>
+ <tr class="odd-row">
+ <td>odd row, odd row, odd row, odd row, odd row, odd row</td>
+ </tr>
+ <tr>
+ <td>even row, even row, even row, even row, even row, even row</td>
+ </tr>
+ <tr class="odd-row">
+ <td>odd row, odd row, odd row, odd row, odd row, odd row</td>
+ </tr>
+</table>
+</body>
+
+</html>
/trunk/cljs/notes/code-guidelines/descendant-sel.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/notes/index.html
===================================================================
--- trunk/cljs/notes/index.html (nonexistent)
+++ trunk/cljs/notes/index.html (revision 45)
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+<title>Notes on the comp.lang.javascript FAQ</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<link href="../faq.css" rel="stylesheet" type="text/css">
+<link href="notes.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+
+<h1>Notes on the comp.lang.javascript FAQ</h1>
+
+<div id="faqNav">
+ <a href="../">FAQ</a> &gt; FAQ Notes
+</div>
+
+<h2 id="toc">Table of Contents</h2>
+<ul id="contTable">
+ <li>Posting tips
+ <ul>
+ <li>
+ <a href="posting/">Questions and Replies</a>
+ </li>
+ <li>
+ <a href="code-guidelines/">Code Guidelines</a>
+ </li>
+ <li>
+ <a href="review/">Code Review Guidelines</a>
+ </li>
+ </ul>
+ </li>
+ <li>Numbers
+ <dl>
+ <dt>Why does K = parseInt('09') set K to 0?</dt>
+ <dd><a href="type-conversion/#tcPrIntRx"
+ >Javascript Type-Conversion - parseInt with a radix argument</a>
+ </dd>
+ </dl>
+ </li>
+ <li>DOM and Forms
+ <dl>
+ <!--dt>How can I see in javascript if a web browser accepts cookies?</dt>
+ <dd>
+ <a href="cookies/">Privacy filters on proxies</a>
+ </dd-->
+ <dt>
+ How do I get the value of a form control?
+ </dt>
+ <dd>
+ <a href="form-access/">Referencing Forms and Form Controls</a>
+ </dd>
+ <dd>
+ <a href="/faq/names/">Unsafe Names for Form Controls</a>
+ </dd>
+ <dt>How do I detect Opera/Netscape/IE?</dt>
+ <dd>
+ <a href="detect-browser/">Browser Detection (and What to Do Instead)</a>
+ </dd>
+ <!--
+ <dt>My element is named myselect[], how do I access it?</dt>
+ <dd>
+ <a href="square_brackets/">Javascript Square Bracket Notation - Illegal characters in Identifier-strings</a>
+ </dd>
+ <dt>How do I access the property of an object using a string?
+ <dd><a href="square_brackets">Javascript Square Bracket Notation</a>
+ </dd>
+ -->
+ </dl>
+ </li>
+ <li>Functions
+ <ul>
+ <li><a href="closures/">Javascript Closures</a></li>
+ <li><a href="http://kangax.github.io/nfe/">Named Function Expressions</a></li>
+ </ul>
+ </li>
+
+ <!--li>Miscellaneous
+ <ol>
+ <li><a href="charter/">The comp.lang.javascript Charter</a></li>
+ <li><a href="script_tags/">How to Include Scripts in
+ <abbr class="initialism" title="HyperText Mark-up Language">HTML</abbr> Documents</a></li>
+ <li><a href="misc/">Tricks and Tips</a></li>
+ </ol>
+ </li-->
+ <!--li><a href="contributors/">Contributors</a></li-->
+</ul>
+
+</body>
+</html>
/trunk/cljs/notes/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/notes/closures/index.html
===================================================================
--- trunk/cljs/notes/closures/index.html (nonexistent)
+++ trunk/cljs/notes/closures/index.html (revision 45)
@@ -0,0 +1,1574 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+<title>Javascript Closures</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="../../faq.css" rel="stylesheet" type="text/css">
+<link href="../notes.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+CODE { white-space:nowrap; }
+.scopeCh {
+ white-space:nowrap;
+ font-family:Courier, monospace;
+}
+</style>
+</head>
+<body>
+
+<h1>Javascript Closures</h1>
+<div id="faqNav">
+ <a href="../../">FAQ</a> &gt; <a href="../">FAQ Notes</a>
+</div>
+
+<ul>
+ <li><a href="#clIntro">Introduction</a></li>
+ <li><a href="#clResO">The Resolution of Property Names on Objects</a>
+ <ul>
+ <li><a href="#clResA">Assignment of Values</a></li>
+ <li><a href="#clResR">Reading of Values</a></li>
+ </ul>
+ </li>
+ <li><a href="#clIRExSc">Identifier Resolution, Execution Contexts and scope chains</a>
+ <ul>
+ <li><a href="#clExCon">The Execution Context</a></li>
+ <li><a href="#clScCh">scope chains and [[scope]]</a></li>
+ <li><a href="#clIdRes">Identifier Resolution</a></li>
+ </ul>
+ </li>
+ <li><a href="#clClose">Closures</a>
+ <ul>
+ <li><a href="#clAtGb">Automatic Garbage Collection</a></li>
+ <li><a href="#clFrmC">Forming Closures</a></li>
+ </ul>
+ </li>
+ <li><a href="#clClDo">What can be done with Closures?</a>
+ <ul>
+ <li><a href="#clSto">Example 1: setTimeout with Function References</a></li>
+ <li><a href="#clObjI">Example 2: Associating Functions with Object Instance Methods</a></li>
+ <li><a href="#clEncap">Example 3: Encapsulating Related Functionality</a></li>
+ <li><a href="#clOtE">Other Examples</a></li>
+ </ul>
+ </li>
+ <li><a href="#clAc">Accidental Closures</a></li>
+ <li><a href="#clMem">The Internet Explorer Memory Leak Problem</a></li>
+</ul>
+
+<h2 id="clIntro">Introduction</h2>
+
+<blockquote cite="http://groups.google.com/groups?selm=wu535hos.fsf@hotpop.com">
+ <dl>
+ <dt id="clDefN">Closure</dt>
+ <dd>A &quot;closure&quot; is an expression (typically a function) that
+ can have free variables together with an environment that binds
+ those variables (that &quot;closes&quot; the expression).
+ <dd>
+ </dl>
+</blockquote>
+
+<p>
+Closures are one of the most powerful features of ECMAScript
+(javascript) but they cannot be property exploited without
+understanding them. They are, however, relatively easy to create,
+even accidentally, and their creation has potentially harmful
+consequences, particularly in some relatively common web browser
+environments. To avoid accidentally encountering the drawbacks and
+to take advantage of the benefits they offer it is necessary to
+understand their mechanism. This depends heavily on the role of
+scope chains in identifier resolution and so on the resolution of
+property names on objects.
+</p>
+
+<p>
+The simple explanation of a Closure is that ECMAScript allows inner
+functions; function definitions and function expressions that are
+inside the function bodes of other functions. And that those inner
+functions are allowed access to all of the local variables, parameters
+and declared inner functions within their outer function(s). A closure
+is formed when one of those inner functions is made accessible outside
+of the function in which it was contained, so that it may be executed
+after the outer function has returned. At which point it still has
+access to the local variables, parameters and inner function
+declarations of its outer function. Those local variables, parameter
+and function declarations (initially) have the values that they had
+when the outer function returned and may be interacted with by the
+inner function.
+</p>
+
+<p>
+Unfortunately, properly understanding closures requires an
+understanding of the mechanism behind them, and quite a bit of
+technical detail. While some of the ECMA 262 specified algorithms have
+been brushed over in the early part of the following explanation, much
+cannot be omitted or easily simplified. Individuals familiar with
+object property name resolution may skip that section but only people
+already familiar with closures can afford to skip the following
+sections, and they can stop reading now and get back to exploiting
+them.
+</p>
+
+<h2 id="clResO">The Resolution of Property Names on Objects</h2>
+
+<p>
+ECMAScript recognises two categories of object, &quot;Native Object&quot;
+and &quot;Host Object&quot; with a sub-category of native objects called
+&quot;Built-in Object&quot; (ECMA 262 3rd Ed Section 4.3). Native objects
+belong to the language and host objects are provided by the environment,
+and may be, for example, document objects, DOM nodes and the like.
+</p>
+
+<p>
+Native objects are loose and dynamic bags of named properties (some
+implementations are not that dynamic when it comes to the built in
+object sub-category, though usually that doesn't matter). The defined
+named properties of an object will hold a value, which may be a
+reference to another Object (functions are also Objects in this sense)
+or a primitive value: String, Number, Boolean, Null or Undefined. The
+Undefined primitive type is a bit odd in that it is possible to assign
+a value of Undefined to a property of an object but doing so does not
+remove that property from the object; it remains a defined named
+property, it just holds the value <code>undefined</code>.
+</p>
+
+<p>
+The following is a simplified description of how property values are
+read and set on objects with the internal details brushed over to the
+greatest extent possible.
+</p>
+
+<h3><a name="clResA" id="clResA">Assignment of Values</a></h3>
+
+<p>
+Named properties of objects can be created, or values set on existing
+named properties, by assigning a value to that named property. So
+given:-
+</p>
+
+<pre>
+var objectRef = new Object(); <span class="commentJS">//create a generic javascript object.</span>
+</pre>
+
+<p>
+A property with the name &quot;testNumber&quot; can be created as:-
+</p>
+
+<pre>
+objectRef.testNumber = 5;
+<span class="commentJS">/* - or:- */</span>
+objectRef[&quot;testNumber&quot;] = 5;
+</pre>
+
+<p>
+The object had no &quot;testNumber&quot; property prior to the
+assignment but one is created when the assignment is made. Any
+subsequent assignment does not need to create the property, it just
+re-sets its value:-
+</p>
+
+<pre>
+objectRef.testNumber = 8;
+<span class="commentJS">/* - or:- */</span>
+objectRef[&quot;testNumber&quot;] = 8;
+</pre>
+
+<p>
+Javascript objects have prototypes that can themselves be objects, as
+will be described shortly, and that prototype may have named
+properties. But this has no role in assignment. If a value is assigned
+and the actual object does not have a property with the corresponding
+name a property of that name is created and the value is assigned to
+it. If it has the property then its value is re-set.
+</p>
+
+<h3><a name="clResR" id="clResR">Reading of Values</a></h3>
+
+<p>
+It is in reading values from object properties that prototypes come
+into play. If an object has a property with the property name used in
+the property accessor then the value of that property is returned:-
+</p>
+
+<pre>
+<span class="commentJS">/* Assign a value to a named property. If the object does not have a
+ property with the corresponding name prior to the assignment it
+ will have one after it:-
+*/</span>
+objectRef.testNumber = 8;
+
+<span class="commentJS">/* Read the value back from the property:- */</span>
+
+var val = objectRef.testNumber;
+<span class="commentJS">/* and - val - now holds the value 8 that was just assigned to the
+ named property of the object. */</span>
+ </pre>
+
+<p>
+But all objects may have prototypes, and prototypes are objects so they, in
+turn, may have prototypes, which may have prototypes, and so on forming
+what is called the prototype chain. The prototype chain ends when one
+of the objects in the chain has a null prototype. The default prototype for the
+<code>Object</code> constructor has a null prototype so:-
+</p>
+
+<pre>
+var objectRef = new Object(); <span class="commentJS">//create a generic javascript object.</span>
+</pre>
+
+<p>
+Creates an object with the prototype <code>Object.prototype</code> that itself has a
+null prototype. So the prototype chain for <code>objectRef</code> contains only one
+object: <code>Object.prototype</code>. However:-
+</p>
+
+<pre>
+<span class="commentJS">/* A &quot;constructor&quot; function for creating objects of a -
+ MyObject1 - type.
+*/</span>
+function MyObject1(formalParameter){
+ <span class="commentJS">/* Give the constructed object a property called - testNumber - and
+ assign it the value passed to the constructor as its first
+ argument:-
+ */</span>
+ this.testNumber = formalParameter;
+}
+
+<span class="commentJS">/* A &quot;constructor&quot; function for creating objects of a -
+ MyObject2 - type:-
+*/</span>
+function MyObject2(formalParameter){
+ <span class="commentJS">/* Give the constructed object a property called - testString -
+ and assign it the value passed to the constructor as its first
+ argument:-
+ */</span>
+ this.testString = formalParameter;
+}
+
+<span class="commentJS">/* The next operation replaces the default prototype associated with
+ all MyObject2 instances with an instance of MyObject1, passing the
+ argument - 8 - to the MyObject1 constructor so that its -
+ testNumber - property will be set to that value:-
+*/</span>
+MyObject2.prototype = new MyObject1( 8 );
+
+<span class="commentJS">/* Finally, create an instance of - MyObject2 - and assign a reference
+ to that object to the variable - objectRef - passing a string as the
+ first argument for the constructor:-
+*/</span>
+
+var objectRef = new MyObject2( &quot;String_Value&quot; );
+</pre>
+
+<p>
+The instance of <code>MyObject2</code> referred to by the <code>objectRef</code> variable has a
+prototype chain. The first object in that chain is the instance of
+<code>MyObject1</code> that was created and assigned to the prototype
+property of the <code>MyObject2</code> constructor. The instance of
+<code>MyObject1</code> has a prototype, the object that was assigned to the function
+<code>MyObject1</code>'s prototype property by the implementation. That object has
+a prototype, the default <code>Object</code> prototype that corresponds with the
+object referred to by <code>Object.prototype</code>. <code>Object.prototype</code> has a null
+prototype so the prototype chain comes to an end at this point.
+</p>
+<p>
+When a property accessor attempts to read a named property form the
+object referred to by the variable <code>objectRef</code> the whole
+prototype chain can enter into the process. In the simple case:-
+</p>
+
+<pre>
+var val = objectRef.testString;
+</pre>
+
+<p>
+- the instance of <code>MyObject2</code> referred to by <code>objectRef</code> has
+a property with the name &quot;testString&quot; so it is the value of
+that property, set to &quot;String_Value&quot;, that is assigned to the
+variable <code>val</code>. However:-
+</p>
+
+<pre>
+var val = objectRef.testNumber;
+</pre>
+
+<p>
+- cannot read a named property form the instance of
+<code>MyObject2</code> itself as it has no such property but the
+variable <code>val</code> is set to the value of <code>8</code> rather
+than undefined because having failed to find a corresponding named
+property on the object itself the interpreter then examines the object
+that is its prototype. Its prototype is the instance of
+<code>MyObject1</code> and it was created with a property named
+&quot;testNumber&quot; with the value <code>8</code> assigned to that property, so
+the property accessor evaluates as the value <code>8</code>. Neither
+<code>MyObject1</code> or <code>MyObject2</code> have defined a
+<code>toString</code> method, but if a property accessor attempts to
+read the value of a <code>toString</code> property from
+<code>objectRef</code>:-
+</p>
+
+<pre>
+var val = objectRef.toString;
+</pre>
+
+<p>
+- the <code>val</code> variable is assigned a reference to a function.
+That function is the <code>toString</code> property of
+<code>Object.prototype</code> and is returned because the process of
+examining the prototype of <code>objectRef</code>, when
+<code>objectRef</code> turns out not to have a &quot;toString&quot;
+property, is acting on an object, so when that prototype is found to
+lack the property its prototype is examined in turn. Its prototype
+is <code>Object.prototype</code>, which does have a
+<code>toString</code> method so it is a reference to that function
+object that is returned.
+</p>
+
+<p>
+Finally:-
+</p>
+
+<pre>
+var val = objectRef.madeUpProperty;
+</pre>
+
+<p>
+- returns <code>undefined</code>, because as the process of working up the prototype
+chain finds no properties on any of the object with the name
+&quot;madeUpPeoperty&quot; it eventually gets to the prototype of
+<code>Object.prototype</code>, which is null, and the process ends
+returning <code>undefined</code>.
+</p>
+
+<p>
+The reading of named properties returns the first value found, on the
+object or then from its prototype chain. The assigning of a value to a
+named property on an object will create a property on the object itself
+if no corresponding property already exists.
+</p>
+
+<p>
+This means that if a value was assigned as
+<code>objectRef.testNumber = 3</code> a &quot;testNumber&quot; property
+will be created on the instance of <code>MyObject2</code> itself, and
+any subsequent attempts to read that value will retrieve that value as
+set on the object. The prototype chain no longer needs to be examined
+to resolve the property accessor, but the instance of
+<code>MyObject1</code> with the value of <code>8</code> assigned to its
+&quot;testNumber&quot; property is unaltered. The assignment to the
+<code>objectRef</code> object masks the corresponding property in its
+prototype chain.
+</p>
+
+<p>
+Note: ECMAScript defines an internal <code>[[prototype]]</code>
+property of the internal Object type. This property is not directly accessible with
+scripts, but it is the chain of objects referred to with the
+internal <code>[[prototype]]</code> property that is used in property
+accessor resolution; the object's prototype chain. A public
+<code>prototype</code> property exists to allow the assignment,
+definition and manipulation of prototypes in association with the
+internal <code>[[prototype]]</code> property. The details of the
+relationship between to two are described in ECMA 262 (3rd edition)
+and are beyond the <dfn>scope</dfn> of this discussion.
+</p>
+
+<h2 id="clIRExSc">Identifier Resolution, Execution Contexts and scope chains</h2>
+
+<h3 id="clExCon">The Execution Context</h3>
+
+<p>
+An <dfn>execution context</dfn> is an abstract concept used by the ECMSScript
+specification (ECMA 262 3rd edition) to define the behaviour required
+of ECMAScript implementations. The specification does not say anything
+about how <dfn>execution contexts</dfn> should be implemented but execution
+contexts have associated attributes that refer to specification defined
+structures so they might be conceived (and even implemented) as objects
+with properties, though not public properties.
+</p>
+
+<p>
+All javascript code is executed in an <dfn>execution context</dfn>. Global code
+(code executed inline, normally as a JS file, or <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page, loads) gets
+executed in <dfn>global</dfn> <dfn>execution context</dfn>, and each invocation of a function (possibly as a constructor) has an associated
+<dfn>execution context</dfn>. Code executed with the <code>eval</code> function
+also gets a distinct execution context but as <code>eval</code> is
+never normally used by javascript programmers it will not be discussed
+here. The specified details of <dfn>execution contexts</dfn> are to be found in
+section 10.2 of ECMA 262 (3rd edition).
+</p>
+
+<p>
+When a javascript function is called it enters an <dfn>execution context</dfn>,
+if another function is called (or the same function recursively) a new
+<dfn>execution context</dfn> is created and execution enters that context for the
+duration of the function call. Returning to the original execution
+context when that called function returns. Thus running javascript code
+forms a stack of <dfn>execution contexts</dfn>.
+</p>
+
+<p>
+When an <dfn>execution context</dfn> is created a number of things happen in a
+defined order. First, in the <dfn>execution context</dfn> of a function, an
+&quot;Activation&quot; object is created. The activation object is
+another specification mechanism. It can be considered as an object
+because it ends up having accessible named properties, but it is not a
+normal object as it has no prototype (at least not a defined prototype)
+and it cannot be directly referenced by javascript code.
+</p>
+
+<p>
+The next step in the creation of the <dfn>execution context</dfn> for a function
+call is the creation of an <code>arguments</code> object, which is an
+array-like object with integer indexed members corresponding with the
+arguments passed to the function call, in order. It also has
+<code>length</code> and <code>callee</code> properties (which are not
+relevant to this discussion, see the spec for details). A property of
+the Activation object is created with the name &quot;arguments&quot;
+and a reference to the <code>arguments</code> object is assigned to
+that property.
+</p>
+
+<p>
+Next the <dfn>execution context</dfn> is assigned a <dfn>scope</dfn>. A <dfn>scope</dfn> consists of a
+list (or chain) of objects. Each function object has an internal
+<code>[[scope]]</code> property (which we will go into more detail
+about shortly) that also consists of a list (or chain) of objects.
+The <dfn>scope</dfn> that is assigned to the <dfn>execution context</dfn> of a function call
+consists of the list referred to by the <code>[[scope]]</code> property
+of the corresponding function object with the Activation object added
+at the front of the chain (or the top of the list).
+</p>
+
+<p>
+Then the process of &quot;variable instantiation&quot; takes place using an object
+that ECMA 262 refers to as the &quot;Variable&quot; object. However,
+the Activation object is used as the Variable object (note this, it is
+important: they are the same object). Named properties of the Variable
+object are created for each of the function's formal parameters, and if
+arguments to the function call correspond with those parameters the
+values of those arguments are assigned to the properties (otherwise the
+assigned value is <code>undefined</code>). Inner function definitions
+are used to create function objects which are assigned to properties of
+the Variable object with names that correspond to the function name
+used in the function declaration. The last stage of variable
+instantiation is to create named properties of the Variable object
+that correspond with all the local variables declared within the
+function.
+</p>
+
+<p>
+The properties created on the Variable object that correspond with
+declared local variables are initially assigned <code>undefined</code>
+values during variable instantiation, the actual initialisation of
+local variables does not happen until the evaluation of the
+corresponding assignment expressions during the execution of the
+function body code.
+</p>
+
+<p>
+It is the fact that the Activation object, with its
+<code>arguments</code> property, and the Variable object, with named
+properties corresponding with function local variables, are the same
+object, that allows the identifier <code>arguments</code> to be treated
+as if it was a function local variable.
+</p>
+
+<p>
+Finally a value is assigned for use with the <code>this</code> keyword.
+If the value assigned refers to an object then property accessors
+prefixed with the <code>this</code> keyword reference properties of
+that object. If the value assigned (internally) is null then the
+<code>this</code> keyword will refer to the global object.
+</p>
+
+<p>
+The global execution context gets some slightly different handling as
+it does not have arguments so it does not need a defined Activation
+object to refer to them. The global execution context does need a <dfn>scope</dfn>
+and its <dfn>scope chain</dfn> consists of exactly one object, the global object.
+The global execution context does go through variable instantiation,
+its inner functions are the normal top level function declarations that
+make up the bulk of javascript code. The global object is used as the
+Variable object, which is why globally declared functions become
+properties of the global object. As do globally declared variables.
+</p>
+
+<p>
+The global execution context also uses a reference to the global object
+for the <code>this</code> object.
+</p>
+
+<h3 id="clScCh">scope chains and [[scope]]</h3>
+
+<p>
+The <dfn>scope chain</dfn> of the execution context for a function call is
+constructed by adding the execution context's Activation/Variable
+object to the front of the <dfn>scope chain</dfn> held in the function
+object's <code>[[scope]]</code> property, so it is important to
+understand how the internal <code>[[scope]]</code> property is
+defined.
+</p>
+
+<p>
+In ECMAScript functions are objects, they are created during variable
+instantiation from function declarations, during the evaluation of
+function expressions or by invoking the <code>Function</code>
+constructor.
+</p>
+
+<p>
+Function objects created with the <code>Function</code> constructor
+always have a <code>[[scope]]</code> property referring to a <dfn>scope
+chain</dfn> that only contains the global object.
+</p>
+
+<p>
+Function objects created with function declarations or function
+expressions have the <dfn>scope chain</dfn> of the execution context in which
+they are created assigned to their internal <code>[[scope]]</code>
+property.
+</p>
+
+<p>
+In the simplest case of a global function declaration such as:-
+</p>
+
+<pre>
+function exampleFunction(formalParameter){
+ ... <span class="commentJS">// function body code</span>
+}
+</pre>
+
+<p>
+- the corresponding function object is created during the variable
+instantiation for the global execution context. The global execution
+context has a <dfn>scope chain</dfn> consisting of only the global object. Thus
+the function object that is created and referred to by the property of
+the global object with the name &quot;exampleFunction&quot; is
+assigned an internal <code>[[scope]]</code> property referring to a
+<dfn>scope chain</dfn> containing only the global object.
+</p>
+
+<p>
+A similar <dfn>scope chain</dfn> is assigned when a function expression is
+executed in the global context:-
+</p>
+
+<pre>
+var exampleFuncRef = function(){
+ ... <span class="commentJS">// function body code</span>
+}
+</pre>
+
+<p>
+- except in this case a named property of the global object is created
+during variable instantiation for the global execution context but the
+function object is not created, and a reference to it assigned to the
+named property of the global object, until the assignment expression is
+evaluated. But the creation of the function object still happens in the
+global execution context so the <code>[[scope]]</code> property of the
+created function object still only contains the global object in the
+assigned scope chain.
+</p>
+
+<p>
+Inner function declarations and expressions result in function objects
+being created within the execution context of a function so they get
+more elaborate scope chains. Consider the following code, which defines
+a function with an inner function declaration and then executes the
+outer function:-
+</p>
+
+<pre>
+function exampleOuterFunction(formalParameter){
+ function exampleInnerFuncitonDec(){
+ ... <span class="commentJS">// inner function body</span>
+ }
+ ... <span class="commentJS">// the rest of the outer function body.</span>
+}
+
+exampleOuterFunction( 5 );
+</pre>
+
+<p>
+The function object corresponding with the outer function declaration
+is created during variable instantiation in the global execution context
+so its <code>[[scope]]</code> property contains the one item scope
+chain with only the global object in it.
+</p>
+
+<p>
+When the global code executes the call to the
+<code>exampleOuterFunction</code> a new execution context is created for
+that function call and an Activation/Variable object along with it.
+The <dfn>scope</dfn> of that new execution context becomes the chain consisting of
+the new Activation object followed by the chain refereed to by the
+outer function object's <code>[[scope]]</code> property (just the
+global object). Variable instantiation for that new execution context
+results in the creation of a function object that corresponds with the
+inner function definition and the <code>[[scope]]</code> property of
+that function object is assigned the value of the <dfn>scope</dfn> from the
+execution context in which it was created. A <dfn>scope chain</dfn> that contains
+the Activation object followed by the global object.
+</p>
+
+<p>
+So far this is all automatic and controlled by the structure and
+execution of the source code. The <dfn>scope chain</dfn> of the execution context
+defines the <code>[[scope]]</code> properties of the function objects
+created and the <code>[[scope]]</code> properties of the function
+objects define the <dfn>scope</dfn> for their execution contexts (along with the
+corresponding Activation object). But ECMAScript provides the
+<code>with</code> statement as a means of modifying the scope chain.
+</p>
+
+<p>
+The <code>with</code> statement evaluates an expression and if that
+expression is an object it is added to the <dfn>scope chain</dfn> of the current
+execution context (in front of the Activation/Variable object). The
+<code>with</code> statement then executes another statement (that may
+itself be a block statement) and then restores the execution context's
+<dfn>scope chain</dfn>to what it was before.
+</p>
+
+<p>
+A function declaration could not be affected by a <code>with</code>
+statement as they result in the creation of function objects during
+variable instantiation, but a function expression can be evaluated
+inside a <code>with</code> statement:-
+</p>
+
+<pre>
+<span class="commentJS">/* create a global variable - y - that refers to an object:- */</span>
+var y = {x:5}; <span class="commentJS">// object literal with an - x - property</span>
+function exampleFuncWith(){
+ var z;
+ <span class="commentJS">/* Add the object referred to by the global variable - y - to the
+ front of he scope chain:-
+ */</span>
+ with(y){
+ <span class="commentJS">/* evaluate a function expression to create a function object
+ and assign a reference to that function object to the local
+ variable - z - :-
+ */</span>
+ z = function(){
+ ... <span class="commentJS">// inner function expression body;</span>
+ }
+ }
+ ...
+}
+
+<span class="commentJS">/* execute the - exampleFuncWith - function:- */</span>
+exampleFuncWith();
+</pre>
+
+<p>
+When the <code>exampleFuncWith</code> function is called the resulting
+execution context has a <dfn>scope chain</dfn> consisting of its Activation object
+followed by the global object. The execution of the <code>with</code>
+statement adds the object referred to by the global variable
+<code>y</code> to the front of that <dfn>scope chain</dfn> during the evaluation
+of the function expression. The function object created by the
+evaluation of the function expression is assigned a
+<code>[[scope]]</code> property that corresponds with the <dfn>scope</dfn> of the
+execution context in which it is created. A <dfn>scope chain</dfn> consisting of
+object <code>y</code> followed by the Activation object from the
+execution context of the outer function call, followed by the global
+object.
+</p>
+
+<p>
+When the block statement associated with the <code>with</code>
+statement terminates the <dfn>scope</dfn> of the execution context is restored
+(the <code>y</code> object is removed), but the function object has
+been created at that point and its <code>[[scope]]</code> property
+assigned a reference to a <dfn>scope chain</dfn> with the <code>y</code> object
+at its head.
+</p>
+
+<h3><a name="clIdRes" id="clIdRes">Identifier Resolution</a></h3>
+
+<p>
+Identifiers are resolved against the scope chain. ECMA 262 categorises
+<code>this</code> as a keyword rather than an identifier, which is not
+unreasonable as it is always resolved dependent on the
+<code>this</code> value in the execution context in which it is used,
+without reference to the scope chain.
+</p>
+
+<p>
+Identifier resolution starts with the first object in the scope chain.
+It is checked to see if it has a property with a name that corresponds
+with the identifier. Because the <dfn>scope chain</dfn> is a chain of objects
+this checking encompasses the prototype chain of that object (if it
+has one). If no corresponding value can be found on the first object
+in the <dfn>scope chain</dfn> the search progresses to the next object. And so on until
+one of the objects in the chain (or one of its prototypes) has a
+property with a name that corresponds with the identifier or the scope
+chain is exhausted.
+</p>
+
+<p>
+The operation on the identifier happens in the same way as the use of
+property accessors on objects described above. The object identified
+in the <dfn>scope chain</dfn> as having the corresponding property takes the
+place of the object in the property accessor and the identifier acts
+as a property name for that object. The global object is always at the
+end of the scope chain.
+</p>
+
+<p>
+As execution contexts associated with function calls will have the
+Activation/Variable object at the front of the chain, identifiers used
+in function bodies are effectively first checked to see whether they
+correspond with formal parameters, inner function declaration names or
+local variables. Those would be resolved as named properties of the
+Activation/Variable object.
+</p>
+
+<h2><a name="clClose" id="clClose">Closures</a></h2>
+
+<h3><a name="clAtGb" id="clAtGb">Automatic Garbage Collection</a></h3>
+
+<p>
+ECMAScript uses automatic garbage collection. The specification
+does not define the details, leaving that to the implementers to sort
+out, and some implementations are known to give a very low priority to
+their garbage collection operations. But the general idea is that if an
+object becomes un-referable (by having no remaining references to it
+left accessible to executing code) it becomes available for garbage
+collection and will at some future point be destroyed and any resources
+it is consuming freed and returned to the system for re-use.
+</p>
+
+<p>
+This would normally be the case upon exiting an execution context. The
+<dfn>scope chain</dfn> structure, the Activation/Variable object and any objects
+created within the execution context, including function objects, would
+no longer be accessible and so would become available for garbage
+collection.
+</p>
+
+<h3><a name="clFrmC" id="clFrmC">Forming Closures</a></h3>
+
+<p>
+A closure is formed by returning a function object that was created
+within an execution context of a function call from that function call
+and assigning a reference to that inner function to a property of another
+object. Or by directly assigning a reference to such a function object
+to, for example, a global variable, a property of a globally accessible
+object or an object passed by reference as an argument to the outer
+function call. e.g:-
+</p>
+
+<pre>
+function exampleClosureForm(arg1, arg2){
+ var localVar = 8;
+ function exampleReturned(innerArg){
+ return ((arg1 + arg2)/(innerArg + localVar));
+ }
+ <span class="commentJS">/* return a reference to the inner function defined as -
+ exampleReturned -:-
+ */</span>
+ return exampleReturned;
+}
+
+var globalVar = exampleClosureForm(2, 4);
+</pre>
+
+<p>
+Now the function object created within the execution context of the
+call to <code>exampleClosureForm</code> cannot be garbage collected
+because it is referred to by a global variable and is still accessible,
+it can even be executed with <code>globalVar(n)</code>.
+</p>
+
+<p>
+But something a little more complicated has happened because the
+function object now referred to by <code>globalVar</code> was created
+with a <code>[[scope]]</code> property referring to a scope chain
+containing the Activation/Variable object belonging to the execution
+context in which it was created (and the global object). Now the
+Activation/Variable object cannot be garbage collected either as the
+execution of the function object referred to by <code>globalVar</code>
+will need to add the whole <dfn>scope chain</dfn> from its <code>[[scope]]</code>
+property to the <dfn>scope</dfn> of the execution context created for each call to
+it.
+</p>
+
+<p>
+A closure is formed. The inner function object has the free variables
+and the Activation/Variable object on the function's <dfn>scope chain</dfn> is
+the environment that binds them.
+</p>
+
+<p>
+The Activation/Variable object is trapped by being
+referred to in the <dfn>scope chain</dfn> assigned to the internal
+<code>[[scope]]</code> property of the function object now referred to
+by the <code>globalVar</code> variable. The Activation/Variable object
+is preserved along with its state; the values of its properties. Scope
+resolution in the execution context of calls to the inner function will
+resolve identifiers that correspond with named properties of that
+Activation/Variable object as properties of that object. The value of
+those properties can still be read and set even though the execution
+context for which it was created has exited.
+</p>
+
+<p>
+In the example above that Activation/Variable object has a state that
+represents the values of formal parameters, inner function definitions
+and local variables, at the time when the outer function returned
+(exited its execution context). The <code>arg1</code> property has the
+value <code>2</code>,the <code>arg2</code> property the value
+<code>4</code>, <code>localVar</code> the value <code>8</code> and an
+<code>exampleReturned</code> property that is a reference to the inner
+function object that was returned form the outer function. (We will be
+referring to this Activation/Variable object as "ActOuter1" in later
+discussion, for convenience.)
+</p>
+
+<p>
+If the <code>exampleClosureForm</code> function was called again as:-
+</p>
+
+<pre>
+var secondGlobalVar = exampleClosureForm(12, 3);
+</pre>
+
+<p>
+- a new execution context would be created, along with a new Activation
+object. And a new function object would be returned, with its own
+distinct <code>[[scope]]</code> property referring to a scope chain
+containing the Activation object form this second execution context,
+with <code>arg1</code> being <code>12</code> and <code>arg2</code>
+being <code>3</code>. (We will be referring to this Activation/Variable
+object as &quot;ActOuter2&quot; in later discussion, for convenience.)
+</p>
+
+<p>
+A second and distinct closure has been formed by the second execution
+of <code>exampleClosureForm</code>.
+</p>
+
+<p>
+The two function objects created by the execution of
+<code>exampleClosureForm</code> to which references have been assigned
+to the global variable <code>globalVar</code> and
+<code>secondGlobalVar</code> respectively, return the expression
+<code>((arg1 + arg2)/(innerArg + localVar))</code>. Which applies
+various operators to four identifiers. How these identifiers are
+resolved is critical to the use and value of closures.
+</p>
+
+<p>
+Consider the execution of the function object referred to by
+<code>globalVar</code>, as <code>globalVar(2)</code>. A new execution
+context is created and an Activation object (we will call it
+&quot;ActInner1&quot;), which is added to the head of the scope chain
+referred to the <code>[[scope]]</code> property of the executed
+function object. ActInner1 is given a property named
+<code>innerArg</code>, after its formal parameter and the argument
+value <code>2</code> assigned to it. The <dfn>scope chain</dfn> for this new
+execution context is: <span class="scopeCh">ActInner1-&gt;</span>
+<span class="scopeCh">ActOuter1-&gt;</span>
+<span class="scopeCh">global object</span>.
+</p>
+
+<p>
+Identifier resolution is done against the <dfn>scope chain</dfn> so in order
+to return the value of the expression
+<code>((arg1 + arg2)/(innerArg + localVar))</code> the values of the
+identifiers will be determined by looking for properties, with names
+corresponding with the identifiers, on each object in the scope chain
+in turn.
+</p>
+
+<p>
+The first object in the chain is ActInner1 and it has a property named
+<code>innerArg</code> with the value <code>2</code>. All of the other
+3 identifiers correspond with named properties of ActOuter1;
+<code>arg1</code> is <code>2</code>, <code>arg2</code> is
+<code>4</code> and <code>localVar</code> is <code>8</code>. The
+function call returns <code>((2 + 4)/(2 + 8))</code>.
+</p>
+
+<p>
+Compare that with the execution of the otherwise identical function
+object referred to by <code>secondGlobalVar</code>, as
+<code>secondGlobalVar(5)</code>. Calling the Activation object for
+this new execution context &quot;ActInner2&quot;, the scope chain
+becomes: <span class="scopeCh">ActInner2-&gt;</span>
+<span class="scopeCh">ActOuter2-&gt;</span>
+<span class="scopeCh">global object</span>. ActInner2 returns
+<code>innerArg</code> as <code>5</code> and ActOuter2 returns
+<code>arg1</code>, <code>arg2</code> and <code>localVar</code> as
+<code>12</code>, <code>3</code> and <code>8</code> respectively. The
+value returned is <code>((12 + 3)/(5 + 8))</code>.
+</p>
+
+<p>
+Execute <code>secondGlobalVar</code> again and a new Activation object
+will appear at the front of the <dfn>scope chain</dfn> but ActOuter2 will still
+be next object in the chain and the value of its named properties will
+again be used in the resolution of the identifiers <code>arg1</code>,
+<code>arg2</code> and <code>localVar</code>.
+</p>
+
+<p>
+This is how ECMAScript inner functions gain, and maintain, access to the formal
+parameters, declared inner functions and local variables of the
+execution context in which they were created. And it is how the
+forming of a closure allows such a function object to keep referring
+to those values, reading and writing to them, for as long as it
+continues to exist. The Activation/Variable object from the execution
+context in which the inner function was created remains on the scope
+chain referred to by the function object's <code>[[scope]]</code>
+property, until all references to the inner function are freed and
+the function object is made available for garbage collection (along
+with any now unneeded objects on its scope chain).
+</p>
+
+<p>
+Inner function may themselves have inner functions, and the inner
+functions returned from the execution of functions to form closures
+may themselves return inner functions and form closures of their own.
+With each nesting the <dfn>scope chain</dfn> gains extra Activation objects
+originating with the execution contexts in which the inner function
+objects were created. The ECMAScript specification requires a scope
+chain to be finite, but imposes no limits on their length.
+Implementations probably do impose some practical limitation but no
+specific magnitude has yet been reported. The potential for nesting
+inner functions seems so far to have exceeded anyone's desire to
+code them.
+</p>
+
+<h2><a name="clClDo" id="clClDo">What can be done with Closures?</a></h2>
+
+<p>
+Strangely the answer to that appears to be anything and everything.
+I am told that closures enable ECMAScript to emulate anything, so the
+limitation is the ability to conceive and implement the emulation. That
+is a bit esoteric and it is probably better to start with something a
+little more practical.
+</p>
+
+
+<h3><a name="clSto" id="clSto">Example 1: setTimeout with Function References</a></h3>
+
+
+<p>
+A common use for a closure is to provide parameters for the execution
+of a function prior to the execution of that function. For example,
+when a function is to be provided as the first argument to the
+<code>setTimout</code> function that is common in web browser
+environments.
+</p>
+
+<p>
+<code>setTimeout</code> schedules the execution of a function (or a
+string of javascript source code, but not in this context), provided as
+its first argument, after an interval expressed in milliseconds (as its
+second argument). If a piece of code wants to use
+<code>setTimeout</code> it calls the <code>setTimeout</code> function
+and passes a reference to a function object as the first argument and
+the millisecond interval as the second, but a reference to a function
+object cannot provide parameters for the scheduled execution of that
+function.
+</p>
+
+<p>
+However, code could call another function that returned a reference to
+an inner function object, with that inner function object being passed
+by reference to the <code>setTimeout</code> function. The parameters to
+be used for the execution of the inner function are passed with the
+call to the function that returns it. <code>setTimout</code> executes
+the inner function without passing arguments but that inner function
+can still access the parameters provided by the call to the outer
+function that returned it:-
+</p>
+
+<pre>
+function callLater(paramA, paramB, paramC){
+ <span class="commentJS">/* Return a reference to an anonymous inner function created
+ with a function expression:-
+ */</span>
+ return (function(){
+ <span class="commentJS">/* This inner function is to be executed with - setTimeout
+ - and when it is executed it can read, and act upon, the
+ parameters passed to the outer function:-
+ */</span>
+ paramA[paramB] = paramC;
+ });
+}
+
+...
+
+<span class="commentJS">/* Call the function that will return a reference to the inner function
+ object created in its execution context. Passing the parameters that
+ the inner function will use when it is eventually executed as
+ arguments to the outer function. The returned reference to the inner
+ function object is assigned to a local variable:-
+*/</span>
+var functRef = callLater(elStyle, "display", "none");
+<span class="commentJS">/* Call the setTimeout function, passing the reference to the inner
+ function assigned to the - functRef - variable as the first argument:-
+*/</span>
+hideMenu=setTimeout(functRef, 500);
+</pre>
+
+<h3><a name="clObjI" id="clObjI">Example 2: Associating Functions with Object Instance Methods</a></h3>
+
+<p>
+There are many other circumstances when a reference to a function
+object is assigned so that it would be executed at some future time
+where it is useful to provide parameters for the execution of that
+function that would not be easily available at the time of execution
+but cannot be known until the moment of assignment.
+</p>
+
+<p>
+One example might be a javascript object that is designed to
+encapsulate the interactions with a particular DOM element. It has
+<code>doOnClick</code>, <code>doMouseOver</code> and
+<code>doMouseOut</code> methods and wants to execute those methods
+when the corresponding events are triggered on the DOM element, but
+there may be any number of instances of the javascript object created
+associated with different DOM elements and the individual object
+instances do not know how they will be employed by the code that
+instantiated them. The object instances do not know how to reference
+themselves globally because they do not know which global variables
+(if any) will be assigned references to their instances.
+</p>
+
+<p>
+So the problem is to execute an event handling function that has an
+association with a particular instance of the javascript object, and
+knows which method of that object to call.
+</p>
+
+<p>
+The following example uses a small generalised closure based function
+that associates object instances with element event handlers.
+Arranging that the execution of the event handler calls the specified
+method of the object instance, passing the event object and a reference
+to the associated element on to the object method and returning the
+method's return value.
+</p>
+
+<pre>
+<span class="commentJS">/* A general function that associates an object instance with an event
+ handler. The returned inner function is used as the event handler.
+ The object instance is passed as the - obj - parameter and the name
+ of the method that is to be called on that object is passed as the -
+ methodName - (string) parameter.
+*/</span>
+function associateObjWithEvent(obj, methodName){
+ <span class="commentJS">/* The returned inner function is intended to act as an event
+ handler for a DOM element:-
+ */</span>
+ return (function(e){
+ <span class="commentJS">/* The event object that will have been parsed as the - e -
+ parameter on DOM standard browsers is normalised to the IE
+ event object if it has not been passed as an argument to the
+ event handling inner function:-
+ */</span>
+ e = e||window.event;
+ <span class="commentJS">/* The event handler calls a method of the object - obj - with
+ the name held in the string - methodName - passing the now
+ normalised event object and a reference to the element to
+ which the event handler has been assigned using the - this -
+ (which works because the inner function is executed as a
+ method of that element because it has been assigned as an
+ event handler):-
+ */</span>
+ return obj[methodName](e, this);
+ });
+}
+
+<span class="commentJS">/* This constructor function creates objects that associates themselves
+ with DOM elements whose IDs are passed to the constructor as a
+ string. The object instances want to arrange than when the
+ corresponding element triggers onclick, onmouseover and onmouseout
+ events corresponding methods are called on their object instance.
+*/</span>
+function DhtmlObject(elementId){
+ <span class="commentJS">/* A function is called that retrieves a reference to the DOM
+ element (or null if it cannot be found) with the ID of the
+ required element passed as its argument. The returned value
+ is assigned to the local variable - el -:-
+ */</span>
+ var el = getElementWithId(elementId);
+ <span class="commentJS">/* The value of - el - is internally type-converted to boolean for
+ the - if - statement so that if it refers to an object the
+ result will be true, and if it is null the result false. So that
+ the following block is only executed if the - el - variable
+ refers to a DOM element:-
+ */</span>
+ if(el){
+ <span class="commentJS">/* To assign a function as the element's event handler this
+ object calls the - associateObjWithEvent - function
+ specifying itself (with the - this - keyword) as the object
+ on which a method is to be called and providing the name of
+ the method that is to be called. The - associateObjWithEvent
+ - function will return a reference to an inner function that
+ is assigned to the event handler of the DOM element. That
+ inner function will call the required method on the
+ javascript object when it is executed in response to
+ events:-
+ */</span>
+ el.onclick = associateObjWithEvent(this, "doOnClick");
+ el.onmouseover = associateObjWithEvent(this, "doMouseOver");
+ el.onmouseout = associateObjWithEvent(this, "doMouseOut");
+ ...
+ }
+}
+DhtmlObject.prototype.doOnClick = function(event, element){
+ ... <span class="commentJS">// doOnClick method body</span>.
+}
+DhtmlObject.prototype.doMouseOver = function(event, element){
+ ... <span class="commentJS">// doMouseOver method body.</span>
+}
+DhtmlObject.prototype.doMouseOut = function(event, element){
+ ... <span class="commentJS">// doMouseOut method body.</span>
+}
+</pre>
+
+<p>
+And so any instances of the <code>DhtmlObject</code> can associate themselves
+with the DOM element that they are interested in without any need
+to know anything about how they are being employed by other code,
+impacting on the global namespace or risking clashes with other
+instances of the <code>DhtmlObject</code>.
+</p>
+
+<h3><a name="clEncap" id="clEncap">Example 3: Encapsulating Related Functionality</a></h3>
+
+<p>
+Closures can be used to create additional scopes that can be used to
+group interrelated and dependent code in a way that minimises the risk
+of accidental interaction. Suppose a function is to build a string and
+to avoid the repeated concatenation operations (and the creation of
+numerous intermediate strings) the desire is to use an array to store
+the parts of the string in sequence and then output the results using
+the <code>Array.prototype.join</code> method (with an empty string as its argument).
+The array is going to act as a buffer for the output, but defining it
+locally to the function will result in its re-creation on each
+execution of the function, which may not be necessary if the only
+variable content of that array will be re-assigned on each function
+call.
+</p>
+
+<p>
+One approach might make the array a global variable so that it can be
+re-used without being re-created. But the consequences of that will be
+that, in addition to the global variable that refers to the function
+that will use the buffer array, there will be a second global property
+that refers to the array itself. The effect is to render the code less
+manageable, as, if it is to be used elsewhere, its author has to remember
+to include both the function definition and the array definition. It
+also makes the code less easy to integrate with other code because
+instead of just ensuring that the function name is unique within the
+global namespace it is necessary to ensure that the Array on which it
+is dependent is using a name that is unique within the global
+namespace.
+</p>
+
+<p>
+A Closure allows the buffer array to be associated (and neatly
+packaged) with the function that is dependent upon it and
+simultaneously keep the property name to which the buffer array as
+assigned out of the global namespace and free of the risk of name
+conflicts and accidental interactions.
+</p>
+
+<p>
+The trick here is to create one additional execution context by
+executing a function expression in-line and have that function
+expression return an inner function that will be the function that is
+used by external code. The buffer array is then defined as a local
+variable of the function expression that is executed in-line. That only
+happens once so the Array is only created once, but is available to
+the function that depends on it for repeated use.
+</p>
+
+<p>
+The following code creates a function that will return a string of
+<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>, much of which is constant, but those constant character
+sequences need to be interspersed with variable information provided
+as parameter to the function call.
+</p>
+
+<p>
+A reference to an inner function object is returned from the in-line
+execution of a function expression and assigned to a global variable
+so that it can be called as a global function. The buffer array is
+defined as a local variable in the outer function expression. It is
+not exposed in the global namespace and does not need to be re-created
+whenever the function that uses it is called.
+</p>
+
+<pre>
+<span class="commentJS">/* A global variable - getImgInPositionedDivHtml - is declared and
+ assigned the value of an inner function expression returned from
+ a one-time call to an outer function expression.
+
+ That inner function returns a string of <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> that represents an
+ absolutely positioned DIV wrapped round an IMG element, such that
+ all of the variable attribute values are provided as parameters
+ to the function call:-
+*/</span>
+var getImgInPositionedDivHtml = (function(){
+ <span class="commentJS">/* The - buffAr - Array is assigned to a local variable of the
+ outer function expression. It is only created once and that one
+ instance of the array is available to the inner function so that
+ it can be used on each execution of that inner function.
+
+ Empty strings are used as placeholders for the date that is to
+ be inserted into the Array by the inner function:-
+ */</span>
+ var buffAr = [
+ '&lt;div id="',
+ '', <span class="commentJS">//index 1, DIV ID attribute</span>
+ '" style="position:absolute;top:',
+ '', <span class="commentJS">//index 3, DIV top position</span>
+ 'px;left:',
+ '', <span class="commentJS">//index 5, DIV left position</span>
+ 'px;width:',
+ '', <span class="commentJS">//index 7, DIV width</span>
+ 'px;height:',
+ '', <span class="commentJS">//index 9, DIV height</span>
+ 'px;overflow:hidden;\"&gt;&lt;img src=\"',
+ '', <span class="commentJS">//index 11, IMG URL</span>
+ '\" width=\"',
+ '', <span class="commentJS">//index 13, IMG width</span>
+ '\" height=\"',
+ '', <span class="commentJS">//index 15, IMG height</span>
+ '\" alt=\"',
+ '', <span class="commentJS">//index 17, IMG alt text</span>
+ '\"&gt;&lt;\/div&gt;'
+ ];
+ <span class="commentJS">/* Return the inner function object that is the result of the
+ evaluation of a function expression. It is this inner function
+ object that will be executed on each call to -
+ getImgInPositionedDivHtml( ... ) -:-
+ */</span>
+ return (function(url, id, width, height, top, left, altText){
+ <span class="commentJS">/* Assign the various parameters to the corresponding
+ locations in the buffer array:-
+ */</span>
+ buffAr[1] = id;
+ buffAr[3] = top;
+ buffAr[5] = left;
+ buffAr[13] = (buffAr[7] = width);
+ buffAr[15] = (buffAr[9] = height);
+ buffAr[11] = url;
+ buffAr[17] = altText;
+ <span class="commentJS">/* Return the string created by joining each element in the
+ array using an empty string (which is the same as just
+ joining the elements together):-
+ */</span>
+ return buffAr.join('');
+ }); <span class="commentJS">//:End of inner function expression.</span>
+})();
+<span class="commentJS">/*^^- :The inline execution of the outer function expression. */</span>
+</pre>
+
+<p>
+If one function was dependent on one (or several) other functions, but
+those other functions were not expected to be directly employed by any
+other code, then the same technique could be used to group those
+functions with the one that was to be publicly exposed. Making a
+complex multi-function process into an easily portable and encapsulated
+unit of code.
+</p>
+
+<h3><a name="clOtE" id="clOtE">Other Examples</a></h3>
+
+<p>
+Probably one of the best known applications of closures is
+<a href="http://www.crockford.com/javascript/private.html">Douglas
+Crockford's technique for the emulation of private instance variables
+in ECMAScript objects</a>. Which can be extended to all sorts of
+structures of <dfn>scope</dfn> contained nested accessibility/visibility, including
+<a href="http://myweb.tiscali.co.uk/cornford/js_info/private_static.html">
+the emulation of private static members for ECMAScript objects</a>.
+</p>
+
+<p>
+The possible application of closures are endless, understanding how
+they work is probably the best guide to realising how they can be
+used.
+</p>
+
+<h2 id="clAc">Accidental Closures</h2>
+
+<p>
+Rendering any inner function accessible outside of the body of the
+function in which it was created will form a closure. That makes
+closures very easy to create and one of the consequences is that
+javascript authors who do not appreciate closures as a language feature
+can observe the use of inner functions for various tasks and employ
+inner functions, with no apparent consequences, not realising that
+closures are being created or what the implications of doing that are.
+</p>
+
+<p>
+Accidentally creating closures can have harmful side effects as the
+following section on the IE memory leak problem describes, but they can
+also impact of the efficiency of code. It is not the closures
+themselves, indeed carefully used they can contribute significantly
+towards the creation of efficient code. It is the use of inner
+functions that can impact on efficiency.
+</p>
+
+<p>
+A common situation is where inner functions are used is as event
+handlers for DOM elements. For example the following code might be used
+to add an onclick handler to a link element:-
+</p>
+
+<pre>
+<span class="commentJS">/* Define the global variable that is to have its value added to the
+ - href - of a link as a query string by the following function:-
+*/</span>
+var quantaty = 5;
+<span class="commentJS">/* When a link passed to this function (as the argument to the function
+ call - linkRef -) an onclick event handler is added to the link that
+ will add the value of a global variable - quantaty - to the - href -
+ of that link as a query string, then return true so that the link
+ will navigate to the resource specified by the - href - which will
+ by then include the assigned query string:-
+*/</span>
+function addGlobalQueryOnClick(linkRef){
+ <span class="commentJS">/* If the - linkRef - parameter can be type converted to true
+ (which it will if it refers to an object):-
+ */</span>
+ if(linkRef){
+ <span class="commentJS">/* Evaluate a function expression and assign a reference to the
+ function object that is created by the evaluation of the
+ function expression to the onclick handler of the link
+ element:-
+ */</span>
+ linkRef.onclick = function(){
+ <span class="commentJS">/* This inner function expression adds the query string to
+ the - href - of the element to which it is attached as
+ an event handler:-
+ */</span>
+ this.href += ('?quantaty='+escape(quantaty));
+ return true;
+ };
+ }
+}
+</pre>
+
+<p>
+Whenever the <code>addGlobalQueryOnClick</code> function is called a
+new inner function is created (and a closure formed by its assignment).
+From the efficiency point of view that would not be significant if the
+<code>addGlobalQueryOnClick</code> function was only called once or
+twice, but if the function was heavily employed many distinct function
+objects would be created (one for each evaluation of the inner function
+expression).
+</p>
+
+<p>
+The above code is not taking advantage of the fact that inner functions
+are becoming accessible outside of the function in which they are being
+created (or the resulting closures). As a result exactly the same effect
+could be achieved by defining the function that is to be used as the
+event handler separately and then assigning a reference to that
+function to the event handling property. Only one function object would
+be created and all of the elements that use that event handler would
+share a reference to that one function:-
+</p>
+
+<pre>
+<span class="commentJS">/* Define the global variable that is to have its value added to the
+ - href - of a link as a query string by the following function:-
+*/</span>
+var quantaty = 5;
+
+<span class="commentJS">/* When a link passed to this function (as the argument to the function
+ call - linkRef -) an onclick event handler is added to the link that
+ will add the value of a global variable - quantaty - to the - href -
+ of that link as a query string, then return true so that the link
+ will navigate to the resource specified by the - href - which will
+ by then include the assigned query string:-
+*/</span>
+function addGlobalQueryOnClick(linkRef){
+ <span class="commentJS">/* If the - linkRef - parameter can be type converted to true
+ (which it will if it refers to an object):-
+ */</span>
+ if(linkRef){
+ <span class="commentJS">/* Assign a reference to a global function to the event
+ handling property of the link so that it becomes the
+ element's event handler:-
+ */</span>
+ linkRef.onclick = forAddQueryOnClick;
+ }
+}
+<span class="commentJS">/* A global function declaration for a function that is intended to act
+ as an event handler for a link element, adding the value of a global
+ variable to the - href - of an element as an event handler:-
+*/</span>
+function forAddQueryOnClick(){
+ this.href += ('?quantaty='+escape(quantaty));
+ return true;
+}
+</pre>
+
+<p>
+As the inner function in the first version is not being used to exploit
+the closures produced by its use, it would be more efficient not to use
+an inner function, and thus not repeat the process of creating many
+essentially identical function objects.
+</p>
+
+<p>
+A similar consideration applies to object constructor functions. It is
+not uncommon to see code similar to the following skeleton constructor:-
+</p>
+
+
+<pre>
+function ExampleConst(param){
+ <span class="commentJS">/* Create methods of the object by evaluating function expressions
+ and assigning references to the resulting function objects
+ to the properties of the object being created:-
+ */</span>
+ this.method1 = function(){
+ ... <span class="commentJS">// method body.</span>
+ };
+ this.method2 = function(){
+ ... <span class="commentJS">// method body.</span>
+ };
+ this.method3 = function(){
+ ... <span class="commentJS">// method body.</span>
+ };
+ <span class="commentJS">/* Assign the constructor's parameter to a property of the object:-
+ */</span>
+ this.publicProp = param;
+}
+</pre>
+
+<p>
+Each time the constructor is used to create an object, with
+<code>new ExampleConst(n)</code>, a new set of function objects are
+created to act as its methods. So the more object instances that are
+created the more function objects are created to go with them.
+</p>
+
+<p>
+Douglas Crockford's technique for emulating private members on
+javascript objects exploits the closure resulting form assigning
+references to inner function objects to the public properties of a
+constructed object from within its constructor. But if the methods of
+an object are not taking advantage of the closure that they will form
+within the constructor the creation of multiple function objects for
+each object instantiation will make the instantiation process slower
+and more resources will be consumed to accommodate the extra function
+objects created.
+</p>
+
+<p>
+In that case it would be more efficient to create the function object
+once and assign references to them to the corresponding properties of
+the constructor's <code>prototype</code> so they may be shared by all
+of the objects created with that constructor:-
+</p>
+
+<pre>
+function ExampleConst(param){
+ <span class="commentJS">/* Assign the constructor's parameter to a property of the object:-
+ */</span>
+ this.publicProp = param;
+}
+<span class="commentJS">/* Create methods for the objects by evaluating function expressions
+ and assigning references to the resulting function objects to the
+ properties of the constructor's prototype:-
+*/</span>
+ExampleConst.prototype.method1 = function(){
+ ... <span class="commentJS">// method body.</span>
+};
+ExampleConst.prototype.method2 = function(){
+ ... <span class="commentJS">// method body.</span>
+};
+ExampleConst.prototype.method3 = function(){
+ ... <span class="commentJS">// method body.</span>
+};
+
+</pre>
+<h2><a name="clMem" id="clMem">The Internet Explorer Memory Leak Problem</a></h2>
+
+<p>
+The Internet Explorer web browser (verified on versions 4 to 6 (6 is
+current at the time of writing)) has a fault in its garbage collection
+system that prevents it from garbage collecting ECMAScript and some
+host objects if those host objects form part of a &quot;circular&quot;
+reference. The host objects in question are any DOM Nodes (including
+the document object and its descendants) and ActiveX objects. If a
+circular reference is formed including one or more of them, then
+none of the objects involved will be freed until the browser is closed
+down, and the memory that they consume will be unavailable to the
+system until that happens.
+</p>
+
+<p>
+A circular reference is when two or more objects refer to each other in
+a way that can be followed and lead back to the starting point. Such
+as object 1 has a property that refers to object 2, object 2 has a
+property that refers to object 3 and object 3 has a property that
+refers back to object 1. With pure ECMAScript objects as soon as no
+other objects refer to any of objects 1, 2 or 3 the fact that they only
+refer to each other is recognised and they are made available for
+garbage collection. But on Internet Explorer, if any of those objects
+happen to be a DOM Node or ActiveX object, the garbage collection
+cannot see that the circular relationship between them is isolated
+from the rest of the system and free them. Instead they all stay in
+memory until the browser is closed.
+</p>
+
+<p>
+Closures are extremely good at forming circular references. If a
+function object that forms a closure is assigned as, for example, and
+event handler on a DOM Node, and a reference to that Node is assigned
+to one of the Activation/Variable objects in its <dfn>scope chain</dfn> then a
+circular reference exists.
+<span class="scopeCh">DOM_Node.onevent -&gt;</span>
+<span class="scopeCh">function_object.[[scope]] -&gt;</span>
+<span class="scopeCh">scope_chain -&gt;</span>
+<span class="scopeCh">Activation_object.nodeRef -&gt;</span>
+<span class="scopeCh">DOM_Node</span>.
+It is very easy to do, and a bit of browsing around a site that forms
+such a reference in a piece of code common to each page can consume
+most of the systems memory (possibly all).
+</p>
+
+<p>
+Care can be taken to avoid forming circular references and remedial
+action can be taken when they cannot otherwise be avoided, such as
+using IE's onunload event to null event handling function
+references. Recognising the problem and understanding closures
+(and their mechanism) is the key to avoiding this problem with IE.
+</p>
+
+<p id="rToc">
+<a href="faq_notes.html#toc">comp.lang.javascript FAQ notes T.O.C.</a>
+</p>
+
+<ul style="list-style-type:none;margin-top:2.5em;">
+ <li>Written by <span class="person">Richard Cornford</span>. March 2004.</li>
+ <li>With corrections and suggestions by:-<br>
+ <ul style="list-style-type:none;">
+ <li><span class="person">Martin Honnen</span>.</li>
+ <li><span class="person">Yann-Erwan Perio (Yep)</span>.</li>
+ <li><span class="person">Lasse Reichstein Nielsen</span>. (<a href="#clDefN">definition of closure</a>)</li>
+ <li><span class="person">Mike Scirocco</span>.</li>
+ <li><span class="person">Dr John Stockton</span>.</li>
+ <li><span class="person">Garrett Smith</span>.</li>
+ </ul>
+ </li>
+</ul>
+</body>
+</html>
/trunk/cljs/notes/closures/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/notes/notes.css
===================================================================
--- trunk/cljs/notes/notes.css (nonexistent)
+++ trunk/cljs/notes/notes.css (revision 45)
@@ -0,0 +1,34 @@
+#contTable {
+ font-size: 120%;
+}
+#contTable, #contTable li dt {
+ font-weight: bold;
+}
+
+#contTable dl {
+ margin-left: 1.1em;
+ font-size: 86%;
+}
+
+#contTable dl * {
+ margin-left: 0;
+ padding-left: 0;
+}
+
+#contTable dl dd {
+ margin-left: 2.2em;
+}
+
+#contTable li * {
+ font-weight: normal;
+}
+
+div {
+ background: transparent;
+ border: 0;
+ padding: 0;
+}
+
+#faqNav a {
+ font-weight: 700;
+}
/trunk/cljs/notes/notes.css
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/notes/review/index.html
===================================================================
--- trunk/cljs/notes/review/index.html (nonexistent)
+++ trunk/cljs/notes/review/index.html (revision 45)
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title>Code Review Guidelines - comp.lang.javascript</title>
+<link href="../../faq.css" rel="stylesheet" type="text/css">
+<link href="../notes.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+<h1>Code Review Guidelines</h1>
+<div id="faqNav">
+ <a href="../../">FAQ</a> &gt; <a href="../">FAQ Notes</a>
+</div>
+<p>
+ Article by Garrett Smith
+</p>
+<p>
+Peer code review is where software developers review each others'
+development code.
+</p>
+
+<h2>Benefits</h2>
+<p>
+The number one benefit to code reviews is code quality. Code reviews make the code
+better. Here are some other benefits:
+</p>
+
+<ul>
+ <li>
+ Spreads understanding about the code being reviewed.
+ </li>
+ <li>
+ Helps find bugs before they get to QA and avoids QA churn.
+ </li>
+ <li>
+ Helps identify potential problems, bad practices, or maldesign.
+ </li>
+ <li>
+ Preparation for review will require the code author to check his
+ code against the <a href="../code-guidelines/">code guidelines</a> and
+ clean it up (bugs fixed prior to review).
+ </li>
+
+ <li>
+ Encourages collaboration.
+ </li>
+
+ <li>
+ Keeps code cleaner and more maintainable.
+ </li>
+</ul>
+<h2>How to perform the Review</h2>
+<p>
+Take your time understand the problem and how it is addressed in the solution.
+</p>
+
+<p>
+Focus on a small piece at a time.
+</p>
+
+<p>
+A code review should be objective and should state actual problems.
+Saying "the code is bad" is not a helpful review. Instead, explain
+the problem clearly. If the problem is severe, then say why.
+</p>
+
+<h2>Preparation of Reviewed Code</h2>
+<p>
+This section is for the the reviewee (the person whose code is being reviewed).
+</p>
+
+<p>
+The reviewee should prepare for a code review by following the
+the <a href="../code-guidelines/">code guidelines</a>.
+</p>
+
+<h3>Posting Code for Review and Code Reviews</h3>
+<p>
+When posting code to the newsgroup, it is important to make sure
+to transmit it such that it can be easily read and understood.
+</p>
+
+<ul>
+ <li>Format the code to 72 char width. </li>
+
+ <li>Replace any spaces in the source code with tabs.</li>
+
+ <li>Post small sections at a time.
+ <p>By focusing carefully on small
+ sections, the code review can find more bugs. The reviewer may want to
+ spend an hour reviewing the code, then come back to re-review his notes
+ and comments for another hour.
+ </p>
+ </li>
+</ul>
+
+<h3>Rebuttals</h3>
+<p>
+The reveiwee may challenge a criticism and, if the challenge cannot be
+rebutted, the criticism shall be withdrawn.
+</p>
+
+</body>
+</html>
/trunk/cljs/notes/review/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/notes/form-access/index.html
===================================================================
--- trunk/cljs/notes/form-access/index.html (nonexistent)
+++ trunk/cljs/notes/form-access/index.html (revision 45)
@@ -0,0 +1,729 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head><title>Referencing Forms and Form Controls</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="../../faq.css" rel="stylesheet" type="text/css">
+<link href="../notes.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+.commentJS {
+ background-color: #FFFFCC;
+ color: #004800;
+}
+P CODE {
+ background-color: #FFFFDD;
+ color: #000000;
+ padding: 0ex;
+ margin: 0ex;
+}
+</style>
+</head>
+<body>
+
+<h1 id="faHead">Referencing Forms and Form Controls</h1>
+<div id="faqNav">
+ <a href="../../">FAQ</a> &gt; <a href="../">FAQ Notes</a>
+</div>
+
+<ul>
+ <li><a href="#faInt">Introduction</a>
+ <ul>
+ <li><a href="#faInF">Forms</a></li>
+ <li><a href="#faInC">Form Controls</a></li>
+ </ul>
+ </li>
+ <li><a href="#faShrt">Shortcut Accessors</a></li>
+ <li><a href="#faComMis">The Most Common Mistake</a></li>
+ <li><a href="#faAnon">Anonymous Form References</a></li>
+ <li><a href="#faBut">Radio Button and Other Control Collections</a></li>
+ <li><a href="#faEff">Efficient use of Form Accessors</a></li>
+</ul>
+
+<h2 id="faInt">Introduction</h2>
+<h3 id="faInF">Forms</h3>
+<p id="faInF_1">
+When the W3C defined the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> DOM specification much of what they included
+represented a formalisation of existing browser behaviour. In particular they
+defined &quot;convenience&quot; properties on the <code>HTMLDocument</code>
+interface that reproduce document level collections common in preceding
+browsers. Of specific interest here is the <code>document.forms</code>
+collection, which makes all of the <code>FORM</code> elements on a page
+available as (zero based) indexed members of the collection. Allowing,
+for example, the second <code>FORM</code> element on a page to be
+referenced as:-
+</p>
+
+<pre id="faInF_ex1">
+var formElement = document.forms[1];
+</pre>
+
+<p id="faInF_2">
+<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> (but not necessarily XHTML) <code>FORM</code> elements are allowed
+<code>NAME</code> attributes and the <code>document.forms</code> collection
+also makes <code>FORM</code> elements with <code>NAME</code> attributes
+available as named members, under a property name that corresponds with
+value of the <code>NAME</code> attribute. So given a form with the
+attribute <code>name=&quot;myForm&quot;</code> the form can be referenced
+as:-
+</p>
+
+<pre id="faInF_ex2">
+var formElement = document.forms.myForm;
+
+<span class="commentJS">/* - or - */</span>
+
+var formElement = document.forms[&quot;myForm&quot;];
+
+<span class="commentJS">/* The latter, bracket notation, does not impose the same restrictions
+ on the character sequence used for the name as is imposed by the
+ preceding dot notation, which is restricted to only using character
+ sequences that would fulfill the ECMAScript definition of an
+ identifier.
+
+ Bracket notation is often preferred when accessing form elements as
+ it helps to document itself by making it clear in the source code
+ which property names originate in the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> rather than the DOM.
+*/</span>
+</pre>
+
+<p id="faInF_3">
+The <code>document.forms</code> collection had exhibited this behaviour
+in all of the preceding browsers that implemented it (which included
+all the browsers that understood what a form was) and as a result
+represents the most cross-browser method of accessing <code>FORM</code>
+elements. It is both W3C <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> DOM standard compliant and
+back-compatible with pre-existing browsers.
+</p>
+
+<p id="faInF_4">
+The W3C went on to require <code>FORM</code> elements with
+<code>ID</code> attributes to also be made available as named properties
+of the <code>document.forms</code> collection. That represented a
+formalisation of behaviour already exhibited in IE 4 but not by
+Netscape 4 (and earlier). Referencing <code>ID</code>ed <code>FORM</code>
+elements as named properties of the <code>document.forms</code> collection
+should work reliably in all W3C <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> DOM compliant browsers but some
+back-compatibility will be sacrificed if <code>ID</code>s are used instead
+of <code>NAME</code>s (though not nearly as much as would be lost if
+<code>ID</code>ed form elements were referenced using the
+<code>document.getElementById</code> method).
+</p>
+
+<p id="faInF_5">
+When writing <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> that conforms to a DTD that allows <code>FORM</code>
+elements to have <code>NAME</code> attributes it is possible to also give
+the <code>FORM</code> element an <code>ID</code> attribute that corresponds
+with its <code>NAME</code> attribute (so long as the <code>ID</code> is
+unique on the page). The form will appear as a member of the
+<code>document.forms</code> collection under a property name that
+corresponds with the value of the <code>NAME</code> and <code>ID</code>
+attributes (as they are identical).
+</p>
+
+<h3 id="faInC">Form Controls</h3>
+
+<p id="faInC_1">
+Traditionally browsers that implemented the <code>document.forms</code>
+collection also made the controls within a form available as a
+collection accessible as a property of the <code>FORM</code> element
+under the name <code>elements</code>. The W3C <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> DOM also formalised
+this collection in the <code>HTMLFormElement</code> interface.
+Controls within a form can be referenced as integer indexed members of
+that collection:-
+</p>
+
+<pre id="faInC_ex1">
+var formElement = document.forms[&quot;myForm&quot;];
+var controlElement = formElement.elements[2]; <span class="commentJS">//Third control in the form.</span>
+</pre>
+
+<p id="faInC_2">
+Controlls with <code>NAME</code> attributes are again made available as
+named properties of the collection. So a control with
+<code>name=&quot;myControl&quot;</code> can be referenced as:-
+</p>
+
+<pre id="faInC_ex2">
+var controlElement = formElement.elements[&quot;myControl&quot;];
+</pre>
+
+<p id="faInC_3">
+Again the W3C also specified that controls with <code>ID</code>
+attributes should be made available as named members of the
+elements collection under their <code>ID</code>s (with the same
+implications for back-compatibility with really ancient browsers).
+All official (x)<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> DTDs allow form controls to have
+<code>NAME</code> attributes because without a <code>NAME</code>
+attribute the value of the control cannot be sent as a
+name/value pair when the form is submitted.
+</p>
+
+<h2 id="faShrt">Shortcut Accessors</h2>
+
+<p id="faShrt_1">
+In addition to making named <code>FORM</code> elements available
+as named properties of the <code>document.forms</code> collection
+web browsers also make them available as named properties of the
+<code>document</code> object. So:-
+</p>
+
+<pre id="faShrt_ex1">
+var formElement = document.myForm;
+</pre>
+
+<p id="faShrt_2">
+-will reference the same FORM element as:-
+</p>
+
+<pre id="faShrt_ex2">
+var formElement = document.forms.myForm;
+</pre>
+
+<p id="faShrt_3">
+And the same is true using bracket notation:-
+</p>
+
+<pre id="faShrt_ex3">
+var formElement = document[&quot;myForm&quot;];
+
+<span class="commentJS">/* instead of:- */ </span>
+
+var formElement = document.forms[&quot;myForm&quot;];
+</pre>
+
+<p id="faShrt_4">
+The W3C did not include this shortcut in the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> DOM specifications
+so code that uses it cannot be described as standards compliant and,
+while nobody has been able to name an <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> browser where the shortcut
+accessors do not work when referencing named <code>FORM</code>
+elements, it would still be possible for a future standards compliant
+browser not to support the shortcut accessors.
+</p>
+
+<p id="faShrt_5">
+<code>FORM</code> elements that only have <code>ID</code> attributes
+cannot be accessed as properties of the <code>document</code> object
+under a property name that corresponds with their <code>ID</code>
+attributes. While by W3C <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> DOM specification (but not necessarily
+on older browsers) <code>ID</code>ed forms are made available as named
+properties of the <code>document.forms</code> collections under a
+property name that corresponds with the <code>ID</code>.
+</p>
+
+<p id="faShrt_6">
+Form controls can be referenced as named properties of the
+<code>FORM</code> element that contains them with a shortcut accessor:-
+</p>
+
+<pre id="faShrt_ex4">
+var formControl = formElement.myControl;
+
+<span class="commentJS">/* instead of :- */</span>
+
+var formControl = fromElement.elements.myControl;
+</pre>
+
+<p id="faShrt_7">
+But in the case of form controls, elements with <code>ID</code>
+attributes may be available as properties of the <code>FORM</code>
+element under a property name that corresponds with their
+<code>ID</code> (at least on more recent browsers).
+</p>
+
+<p id="faShrt_8">
+The main argument in favour of using shortcut accessors (apart from the
+reduced amount of typing) is that they are resolved fractionally quicker
+than accessors that employ the <code>forms</code> and
+<code>elements</code> collections. That follows from the fact that fewer
+object references need to be resolved before the reference to the element
+of interest is returned.
+</p>
+
+<p id="faShrt_9">
+While arguments against the shortcut accessors point out that named image,
+embed and other elements are also made available as named properties of
+the <code>document</code> object, making it ambiguous when reading the
+source code whether the shortcut accessor is referring to a form or some
+other named property of the <code>document</code> object. When a
+<code>FORM</code> element is referenced as a member of the
+<code>document.forms</code> collection, or a control as a member of the
+<code>elements</code> collection, there can be no doubt while reading
+the source code as to the type of element that is the subject of the
+reference.
+</p>
+
+<h2 id="faComMis">The Most Common Mistake</h2>
+
+<p id="faComMis_1">
+The most common mistake made when defining the form <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> that a script
+will interact with follows from the existence of the shortcut accessors
+for form controls. It is to give the control a <code>NAME</code> (or
+possibly <code>ID</code>) that corresponds with an existing property of
+<code>FORM</code> elements. And the most common example of that is an
+<code>INPUT</code> element of <code>type=&quot;submit&quot;</code> with
+the <code>NAME</code> &quot;submit&quot;. Because the named controls are
+made available as named properties of the <code>FORM</code> element this
+<code>INPUT</code> element is made available under the property name
+<code>&quot;submit&quot;</code>. Unfortunately <code>FORM</code> elements
+already have a property with the name <code>&quot;submit&quot;</code>, it
+is the <code>submit</code> method that can be used to submit the form
+with a script. The misguided choice of name for the <code>INPUT</code>
+element effectively renders the form's <code>submit</code> method
+unscriptable. And the same is true for all controls with names that
+correspond any with existing <code>FORM</code> element properties.
+</p>
+
+<p id="faComMis_2">
+Because ECMAScript is case sensitive it may only be necessary to
+capitalise the name of the <code>INPUT</code> element to avoid the
+conflict. However, it would probably be safest to adopt a naming
+convention for form controls that ensured that they do not
+correspond with existing properties of the <code>FORM</code> elements
+regardless of case. Especially as theW3C <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> specification implies
+that referring to named properties of collections can be case
+insensitive in <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> DOMs. In reality I don't know of any
+implementations in which it is but it would be better to err on the side
+of caution.
+</p>
+
+<p id="faComMis_3">
+Another naming conflict that should be avoided would arise if named form
+controls had names that correspond with the string representations of
+integers, such as <code>name=&quot;1&quot;</code> as they will almost
+certainly result in inconsistent results (across browsers) when being
+referenced because the controls are already available by integer index
+and it would become unclear which control was being referenced by
+accessors such as <code>formElement.elements[1]</code> or
+<code>formElement.elements[&quot;1&quot;]</code> (by the ECMAScript
+specification the preceding two property accessors are equivalent).
+Unless the control with the name <code>&quot;1&quot;</code> also
+happened to be the control with the index 1. This problem would also
+apply to <code>FORM</code> elements within the <code>document.forms</code>
+collection.
+</p>
+
+<p id="faComMis_4">
+Generally it is best to only give form controls names that cannot
+conflict with existing properties of <code>FORM</code> elements
+and <code>FORM</code> elements names that cannot conflict with
+existing properties of the <code>document.forms</code> collection
+or the <code>document</code> object.
+</p>
+
+<h2 id="faAnon">Anonymous Form References</h2>
+
+<p id="faAnon_1">
+Because <code>FORM</code> elements are available as integer indexed
+member of the <code>document.forms</code> collection it is not
+necessary to know the name of a form (or for the form to have a
+name) to acquire a reference to it. While being able to refer to a
+form anonymously with its index might seem like a good approach
+towards making more general/flexible functions for form validation
+and the like, in practice referring to forms by their index actually
+makes code less flexible and harder to maintain. As soon as the
+number or layout of forms on a page is changed their indexes also
+change, requiring that all of the references by index be located
+and altered.
+</p>
+
+<p id="faAnon_2">
+One method of avoiding having to know the name of a <code>FORM</code>
+element within a function that is to act upon a form is to pass a
+reference to the form object as an argument in the function call.
+This is easiest achieved from the code provided as the value for
+an event handling attribute because that code is used by the browser
+to create an event handling function that is assigned as a method of
+the element to which it is attached. And in any function executed as
+a method of an object the <code>this</code> keyword is a reference to
+the object with which the execution of the method is associated. The
+most common need to anonymously pass a reference to a <code>FORM</code>
+element is as an argument to a form validation function in the
+onsubmit handler of the form. In that case the event handling function
+is a method of the <code>FORM</code> element so the <code>this</code>
+keyword refers to the form directly:-
+</p>
+
+<pre id="faAnon_ex1">
+function validateForm(formRef){
+ <span class="commentJS">/* Use the reference to the form passed as the formal
+ parameter - formRef - to acquire a reference to the form
+ control with the name &quot;textField&quot;:
+ */</span>
+ var el = formRef &amp;&amp; formRef.elements[&quot;textField&quot;];
+ <span class="commentJS">/* If the control reference exists return its value property
+ converted to a boolean value (false if empty, true otherwise)
+ else return true so the form is submitted and the server can
+ do the validation:
+ */</span>
+ return !el || Boolean(el.value);
+}
+...
+&lt;form action=&quot;http://example.com/somePage.asp&quot;
+ onsubmit=&quot;return validateForm(this);&quot;&gt;
+ &lt;input type=&quot;text&quot; name=&quot;textField&quot; value=&quot;&quot;&gt;
+ &lt;input type=&quot;submit&quot; name=&quot;Submit_Button&quot; value=&quot;Submit&quot;&gt;
+&lt;/form&gt;
+</pre>
+
+<p id="faAnon_3">
+Because the above function receives the reference to the form that it
+is to validate as an argument when it is called it can also be used
+with any number of other forms. Although in the case of the above
+function each of those forms would need to contain a field called
+<code>&quot;textField&quot;</code>, but that string name could also be
+passed as an argument, making the function more general.
+</p>
+
+<p id="faAnon_4">
+Form control objects all have a property named
+<code>&quot;form&quot;</code> that holds a reference to the
+<code>FORM</code> element that contains them. As a result the event
+handling functions attached to form controls can pass an anonymous
+reference to the form that contains them as <code>this.form</code>.
+Obviously a function called from an event handler on a control can
+be passes an anonymous reference to the control itself as
+<code>this</code>.
+</p>
+
+<h2 id="faBut">Radio Button and Other Control Collections</h2>
+
+<p id="faBut_1">
+Radio button controls work to provide a selection of one item of many
+when each of the radio button alternatives has the same
+<code>NAME</code> attribute. But it is also possible to give other types
+of control the same <code>NAME</code> attribute.
+</p>
+
+<p id="faBut_2">
+When controls that share the same <code>NAME</code> attribute they can
+still be accessed as integer indexed members of the <code>FORM</code>
+element's <code>elements</code> collection but when the member of the
+<code>elements</code> collection is accessed using the <code>NAME</code>
+attribute value as a property name browsers return a collection all of
+the elements with the corresponding NAME attributes. So given the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>:-
+</p>
+
+<pre id="faBut_ex1">
+&lt;form name=&quot;testForm&quot; action=&quot;http://example.com/somePage.jsp&quot;&gt;
+ &lt;ul style=&quot;list-style-type:none;&quot;&gt;
+ &lt;li&gt;&lt;input type=&quot;radio&quot; name=&quot;radioSet&quot; value=&quot;R1&quot;&gt;option 1&lt;/li&gt;
+ &lt;li&gt;&lt;input type=&quot;radio&quot; name=&quot;radioSet&quot; value=&quot;R2&quot;&gt;option 2&lt;/li&gt;
+ &lt;li&gt;&lt;input type=&quot;radio&quot; name=&quot;radioSet&quot; value=&quot;R3&quot;&gt;option 3&lt;/li&gt;
+ &lt;li&gt;&lt;input type=&quot;radio&quot; name=&quot;radioSet&quot; value=&quot;R4&quot;&gt;option 4&lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;input type=&quot;submit&quot name=&quot;Submit_Button&quot; value=&quot;Send&quot;&gt;
+&lt;/form&gt;
+</pre>
+
+<p id="faBut_3">
+A property accessor referring to the member of the <code>FORM</code>'s
+<code>elements</code> collection by the property name
+<code>&quot;radioSet&quot;</code> will not return a reference to any one
+of the named radio buttons but instead returns a collection of all of the
+like-named radio controls.
+</p>
+
+<p id="faBut_4">
+The individual radio buttons within that collection are referred to as
+integer indexed members of that collection. So to find the button that
+is checked one might loop through all of the members of the collection
+of like-named radio buttons and copy a reference to the button with its
+<code>checked</code> property set to boolean <code>true</code>.
+</p>
+
+
+<pre id="faBut_ex2">
+var radioCollection, checkedButton;
+var frm = document.forms[&quot;testForm&quot;];
+if(frm){
+ radioCollection = frm.elements[&quot;radioSet&quot;];
+ if(radioCollection){
+ <span class="commentJS">/* The collection of like-named radio buttons has a length
+ property and that is used to limit a for loop:-
+ */</span>
+ for(var c = 0;c &lt; radioCollection.length;c++){
+ <span class="commentJS">/* The individual radio buttons are accessed as indexed
+ members of the collection using the loop counter - c
+ - from the for loop:
+ */</span>
+ if(radioCollection[c].checked){
+ <span class="commentJS">/* When a radio button element is found with its
+ checked property set to boolean true a reference
+ to that element is assigned to the local variable
+ - checkedButton - and the loop is terminated with
+ the - break - statement as only one button in a set
+ of like-named radio buttons will be checked at a
+ time, so any remaining buttons in the collection
+ must have checked properties set to false:
+ */</span>
+ checkedButton = radioCollection[c];
+ break;
+ }
+ }
+ if(checkedButton){
+ <span class="commentJS">/* Do something with the reference to the checked radio
+ button (if any).
+ */</span>
+ ...
+ }
+ }
+}
+</pre>
+
+<p id="faBut_5">
+It is not unusual when a form is generated by a server-side script that
+some forms may have one or more like-named controls. If there is only
+one control inserted in the form then accessing a member of the
+<code>elements</code> collection with its name will return a reference
+to that one control, but if there are multiple elements the returned
+reference will be to a collection of such controls. While it may be
+possible to branch client-side code that wants to interact with those
+controls to handle the two alternatives it adds an unnecessary
+maintenance burden to do so.
+</p>
+
+<p id="faBut_6">
+As handling a returned collection usually involves looping through that
+collection the simplest way of implementing the client-side code to
+deal with both collections and individual controls being returned by
+named properties of the <code>elements</code> collection is to
+normalise the references to individual controls so that they can be
+handled as if they were a collection. Looping through a collection
+involves using the <code>length</code> property of the collection to
+limit the loop statement and accessing the controls within the
+collection by integer index. This is exactly the way in which code
+would loop through the elements of an <code>Array</code>. To allow a
+script to handle both possibilities with the same code the return of
+a reference to an individual control could be detected and then that
+reference used to create a one-element <code>Array</code>. Subsequent
+code would then treat the <code>Array</code> as if it was a collection and
+loop through it, but as there is only one element the loop body would
+only be executed once.
+</p>
+
+<pre id="faBut_ex3">
+var radioCollection, checkedButton;
+var frm = document.forms[&quot;testForm&quot;];
+if(frm){
+ radioCollection = frm.elements[&quot;radioSet&quot;];
+ if(radioCollection){
+ <span class="commentJS">/* But the returned reference might not be a collection in this
+ case. Instead it may be a reference to just one control if
+ there is only one in this form with the name &quot;radioSet&quot;.
+ If it is a reference to an individual control it is going to
+ be necessary to normalise it. Because radio button controls
+ do not have - length - properties and collections do that is
+ the property that is going to be tested:
+ */</span>
+ if(typeof radioCollection.length != &quot;number&quot;){
+ <span class="commentJS">/* The length property is not a number so this cannot be a
+ collection and must be normalised so that the following
+ loop statement can handle it correctly. Normalisation is
+ done by making a reference to the control currently
+ referred to by the - radioCollection - local variable
+ into the first (and only) element of a new Array object
+ and then assigning a reference to that array to the -
+ radioCollection - local variable:
+ */</span>
+ radioCollection = [radioCollection];
+ }
+ <span class="commentJS">/* The execution of the body of the - for - loop is limited by
+ the - length - property of the collection/Array.
+ */</span>
+ for(var c = 0;c &lt; radioCollection.length;c++){
+ <span class="commentJS">/* The individual radio buttons are accessed as indexed
+ members of the collection/Array using the loop counter
+ - c - from the for loop:
+ */</span>
+ if(radioCollection[c].cheked){
+ checkedButton = radioCollection[c];
+ break;
+ }
+ }
+ if(checkedButton){
+ <span class="commentJS">/* do something with the reference to the checked radio
+ button (if any).
+ */</span>
+ ...
+ }
+ }
+}
+</pre>
+
+<p id="faBut_7">
+While it is normal for radio button controls to be like-named it is
+also possible for all other controls to be included in a form with
+multiple controls of the same type and like names. The same
+referencing techniques can be used with any type of control (even
+mixed types with like-names, though that is almost never done). But
+deciding whether a reference needs to be normalised by making it into
+the only element of an <code>Array</code> by testing the
+<code>length</code> property of that reference to see if it doesn't
+exist will not work with <code>SELECT</code> elements as they have
+a <code>length</code> property of their own. It also would not help
+to be testing some other characteristic of a collection, such as their
+<code>item</code> method, as <code>SELECT</code> elements usually have
+all of the methods and properties of a collection as they are
+implemented as collections of <code>OPTION</code> elements.
+</p>
+
+<p id="faBut_8">
+Turning the problem around and testing a returned reference to see if
+it has the characteristics of a <code>SELECT</code> element (such as
+an <code>options</code> property) would be better but some collection
+implementations have all of the properties and methods of the first
+element within that collection as well as the properties and methods
+of a collection (e.g. on IceBrowser 5). That means that it would not be
+easy to distinguish a collection of <code>SELECT</code> controls
+from an individual <code>SELECT</code> control. However, a more
+elaborate test might go:-
+</p>
+
+<pre id="faBut_ex4">
+<span class="commentJS">/* Normalise a reference that may be an individual from control
+ (including SELECT elements) or may be a collection of controls
+ into a form that can be handled in a - for - loop controlled with
+ its - length - property and accessed by integer index.
+*/</span>
+if((typeof contrlCollection.length != &quot;number&quot;)|| <span class="commentJS">//no length propety:</span>
+ <span class="commentJS">/* or:- */</span>
+ ((contrlCollection.options)&amp;&amp; <span class="commentJS">//it has an options colleciton and:</span>
+ ((!contrlCollection[0])|| <span class="commentJS">//no object at index 0 - not a collection</span>
+ <span class="commentJS">/* or:- */</span>
+ (contrlCollection[0] == contrlCollection.options[0])))){
+ <span class="commentJS">/* The object at index 0 in contrlCollection is the same object
+ as is at index 0 in contrlCollection.options so this must be
+ an individual SELECT element not a collection of them because a
+ collection of SELECT elements would not have an OPTION element
+ at index zero.
+ */</span>
+ contrlCollection = [contrlCollection];
+}
+</pre>
+
+<h2 id="faEff">Efficient use of Form Accessors</h2>
+
+<p id="faEff_1">
+Code that interacts with <code>FORM</code> elements and controls
+through the <code>document.forms</code> collection and the form's
+<code>elements</code> collection usually does not do enough work to
+make the efficiency of the code significant. But with large forms with
+many controls an inefficiently coded validation function (or some other
+interaction, like keeping running totals) can negatively impact on the
+user's experience. It can also be argued that considering the
+efficiency of implementation is a worthwhile habit even when it would
+make no perceivable difference.
+</p>
+
+<p id="faEff_2">
+A significant aspect of the efficient coding of form interacting code
+is the re-resolving of references to various objects. This trivial
+example code copies the values of 5 <code>INPUT</code> elements to
+local variables:-
+</p>
+
+<pre id="faEff_ex1">
+var txt1 = document.forms[&quot;formName&quot;].elements[&quot;field1&quot;].value;
+var txt2 = document.forms[&quot;formName&quot;].elements[&quot;field2&quot;].value;
+var txt3 = document.forms[&quot;formName&quot;].elements[&quot;field3&quot;].value;
+var txt4 = document.forms[&quot;formName&quot;].elements[&quot;field4&quot;].value;
+var txt5 = document.forms[&quot;formName&quot;].elements[&quot;field5&quot;].value;
+</pre>
+
+<p id="faEff_3">
+The shortcut accessors require the resolution of fewer object
+references:-
+</p>
+
+<pre id="faEff_ex2">
+var txt1 = document[&quot;formName&quot;][&quot;field1&quot;].value;
+var txt2 = document[&quot;formName&quot;][&quot;field2&quot;].value;
+var txt3 = document[&quot;formName&quot;][&quot;field3&quot;].value;
+var txt4 = document[&quot;formName&quot;][&quot;field4&quot;].value;
+var txt5 = document[&quot;formName&quot;][&quot;field5&quot;].value;
+</pre>
+
+<p id="faEff_4">
+But their use still involves re-resolving the form object each time a
+form control is accessed. It would be unnecessary to re-resolve this
+reference if a reference to the form was assigned to a local variable:-
+</p>
+
+<pre id="faEff_ex3">
+<span class="commentJS">/* Assign a reference to the form object to the local variable - frm -
+ and then make subsequent control references relative to that local
+ variable:
+*/</span>
+var frm = document.forms[&quot;formName&quot;];
+var txt1 = frm.elements[&quot;field1&quot;].value;
+var txt2 = frm.elements[&quot;field2&quot;].value;
+var txt3 = frm.elements[&quot;field3&quot;].value;
+var txt4 = frm.elements[&quot;field4&quot;].value;
+var txt5 = frm.elements[&quot;field5&quot;].value;
+</pre>
+
+<p id="faEff_5">
+The effect would be much the same as when a reference to the form
+object has been passed to a function and control references are
+accessed relative to the parameter holding the form reference.
+</p>
+
+<p id="faEff_6">
+It is still not optimum to be re-resolving the <code>elements</code>
+collection, and it is practical to assign a reference to that object
+to a local variable instead of a reference to the form object:-
+</p>
+
+<pre id="faEff_ex4">
+<span class="commentJS">/* Assign a reference to the form's elements collection to the local
+ variable - frmEls - and then make subsequent control references
+ relative to that local variable:
+*/</span>
+var frmEls = document.forms[&quot;formName&quot;].elements;
+var txt1 = frmEls[&quot;field1&quot;].value;
+var txt2 = frmEls[&quot;field2&quot;].value;
+var txt3 = frmEls[&quot;field3&quot;].value;
+var txt4 = frmEls[&quot;field4&quot;].value;
+var txt5 = frmEls[&quot;field5&quot;].value;
+</pre>
+
+<p id="faEff_7">
+With the original long form accessor the resolution starts with
+resolving the <code>&quot;document&quot;</code> identifier. The
+identifier is first looked for among the local variables of the
+function (as a named property of the internal
+&quot;Variable&quot; object, by ECMA specification),
+when it is not found the scope chain is searched, object by object
+down the chain, for a property with the corresponding name. When the
+scope resolution for <code>&quot;document&quot;</code> gets to the
+global object (at the end of the scope chain) it will find a property
+called <code>&quot;document&quot;</code>, a reference to the
+<code>document</code> object, and the first identifier in the accessor
+will have been resolved. The next identifier is
+<code>&quot;forms&quot;</code> and that is located as a property of the
+<code>document</code>. Then the <code>&quot;formName&quot;</code>
+property is identified in the <code>forms</code> collection. Next the
+<code>&quot;elements&quot;</code> property of the form is located,
+followed by the control name in that object and finally the
+<code>&quot;value&quot;</code> property of the control is returned.
+</p>
+
+<p id="faEff_8">
+When a reference to the <code>elements</code> collection is assigned to
+a local variable the first identifier in the property accessor is
+identified as that local variable, the control name is identified as a
+property of the <code>elements</code> collection referenced and the
+<code>&quot;value&quot;</code> property of the control is returned.
+</p>
+
+<p id="faEff_9">
+Obviously there is a big difference in the amount of work involved in
+acquiring the <code>value</code> of the control in each case. That
+difference will not be that significant if only a couple of values are
+accessed, but even with as few as half a dozen control property
+accesses the second approach will obviously be much more efficient,
+and with increasing numbers of controls the difference could easily
+become apparent to the user.
+</p>
+</body>
+</html>
/trunk/cljs/notes/form-access/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/notes/posting/index.html
===================================================================
--- trunk/cljs/notes/posting/index.html (nonexistent)
+++ trunk/cljs/notes/posting/index.html (revision 45)
@@ -0,0 +1,1209 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+<title>Notes on the comp.lang.javascript FAQ</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<link href="../../faq.css" rel="stylesheet" type="text/css">
+<link href="../notes.css" rel="stylesheet" type="text/css">
+<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
+<style type="text/css">
+.resourceList LI {
+ margin-bottom: 0.8em;
+}
+</style>
+</head>
+<body>
+
+<h1>Posting Questions and Replies to comp.lang.javascript</h1>
+<div id="faqNav">
+ <a href="../../">FAQ</a> &gt; <a href="../">FAQ Notes</a>
+
+</div>
+<ul>
+ <li><a href="#ps1Intro">Introduction</a></li>
+ <li><a href="#ps1Lang">Posting Language</a></li>
+ <li><a href="#ps1OToc">On and Off Topic Posting</a></li>
+ <li><a href="#ps1Txt">Plain-Text Only</a></li>
+ <li><a href="#ps1Post">Interleaved Posting, Bottom Posting and Not Top Posting.</a>
+ <ul>
+ <li><a href="#ps1InBPost">Interleaved Posting, Bottom Posting</a></li>
+ <li><a href="#ps1TopPs">Top Posting (don't)</a></li>
+ </ul>
+ </li>
+ <li><a href="#ps1Trim">What to Trim</a></li>
+ <li><a href="#ps1Marg">Margins and Line Wrapping</a>
+ <ul>
+ <li><a href="#ps1Mar">Margins</a></li>
+ <li><a href="#ps1Lw">Line Wrapping</a></li>
+ <li><a href="#ps1LwQu">Line Wrapping in Quoted Material</a></li>
+ </ul>
+ </li>
+ <li><a href="#ps1Code">General Code Postings, and when to use a URL</a></li>
+ <!-- <li><a href="#ps1Proof">Proof-read your message</a></li> -->
+ <li><a href="#ps1Quest">Well Asked Questions Get the Best Answers</a>
+ <ul>
+ <li><a href="#ps1QSub">Appropriate Use of the Subject Header</a></li>
+ <li><a href="#ps1QRes">Doing Your Own Research</a></li>
+ <li><a href="#ps1DontWork">&quot;It doesn't work&quot;</a></li>
+ <li><a href="#ps1CntX">Explain the Whole Context</a></li>
+ <li><a href="#ps1PR">Proof-Read your Questions</a></li>
+ </ul>
+ </li>
+ <!-- <li><a href="#ps1notHD">comp.lang.javascript is Not a Helpdesk</a></li> -->
+ <li><a href="#ps1AddR">Additional Reading</a></li>
+</ul>
+
+<h2 id="ps1Intro">Introduction</h2>
+<h3>Social Behavior</h3>
+
+<p>
+There may be several reasons for making posts to comp.lang.javascirpt
+but all valid reasons would be intended to elicit responses, preferably
+including responses form the many experienced and knowledgeable
+regular contributors to the group. The direction of communication is
+always one-to-many, which places the onus on the composer of a message
+to consider the many in their audience above any personal preferences.
+It is always in the best interest
+of someone posting to the group to recognise that the people whose
+responses will be of most value to them may have an attitude toward
+their behaviour on the group, and to try to ensure that it will not be
+a bad attitude.
+</p>
+
+<p>
+It is also always in the best interest of any poster to the group to do
+everything within their power to behave in a way that makes it quick
+and easy for the people they expect to answer their questions to read and follow
+their posts, understand their questions and problems and comprehend and
+test posted code. The people with the best answers are the most likely
+to be busy; too busy to be interested in unraveling a badly expressed
+problem from a mass of incomprehensibly formatted code amid a
+conversation that is hard to follow.
+</p>
+
+<p id="ps1Into_3">
+Usenet has been around for a long time now and has developed various
+conventions of its own. Conventions that have evolved to make
+communicating in the medium as easy and efficient as possible. They
+are not necessarily adhered to on all groups but where they are
+recognised they are definitely preferred. And comp.lang.javascript is
+a group where most of the regulars recognise many Usenet conventions
+and so the FAQ outlines them. This document is intended to provide
+additional detail on the subject.
+</p>
+
+<p id="ps1Into_4">
+Following those conventions and additionally posting with a
+consideration of the other points made on this page related more
+specifically to posting in comp.lang.javascript, will maximise the
+potential for any questions asked and posts made to elicit a useful
+response. At least in part because they make it quicker and easier for
+those interested in offering help to do so.
+</p>
+
+<h2 id="ps1Lang">Posting Language</h2>
+
+<p id="ps1Lang_1">
+comp.lang.javascript is the international javascript group. There are
+language specific javascript groups that could be expected to be
+carried by news servers within the countries concerned. There is,
+however, no English language specific javascript group so
+comp.lang.javascript serves that audience. As a result the vast
+majority of the conversation within the group is in English, and
+anyone with a javascript interest but incapable of reading/writing any
+language but English would choose comp.lang.javascript to read and post
+in. But there are no rules that say that English is the only language
+that is to be used.
+</p>
+
+<p id="ps1Lang_2">
+As an international group, comp.lang.javascript has contributors form
+around the world, many of whom speak/read/write English as a second or
+third (+) language. So a post made in any other language will stand a
+chance of falling within the linguistic capabilities of someone. But
+posts in English should be understandable to everyone, including those
+for whom English is their only language, and thus receive the most
+attention.
+</p>
+
+<p id="ps1Lang_3">
+Machine translation into English (and sometimes less skilled human
+translation) sometimes does not produce results that can be
+understood/followed by English speakers. When a bad translation into
+English is the only option it might be better for a poster to precede
+it with a version in their native language. (Faced with a post in a
+language that is not understood it is natural to scroll down to see
+if there is any accompanying javascript code that might explain the
+problem; a following English translation would be discovered along
+the way). A reader of the group who understands the language used
+may be able to contribute improvements to the English translation even
+if they cannot directly address the question raised.
+</p>
+
+<p id="ps1Lang_4">
+However, even though the most common language used in postings to
+comp.lang.javascript is English, the fact that the group is
+international and that English should not be expected to be the first
+language of contributors to the group means that the English used
+should be formally correct (to the best of the posters ability).
+Normal English sentence structure should be observed, particularly in
+terms of capitalisation (which serves to aid reading for everyone). But
+above all, shorthand abbreviations should not be used, no matter how
+common they may be in English speaking cultures, as they would not
+normally be part of the teaching of English as a foreign language. This
+applies especially to text-message shorthand as they are very much a
+product of local culture and circumstances in a way that is not
+relevant to Usenet as a medium or appropriate to an international
+newsgroup.
+</p>
+
+<p id="ps1Lang_5">
+In the context of an international forum it is also probably best to
+avoid references that may be ambiguous outside of a national context.
+Date formats are an obvious example, with the ISO 8601 <code>YYYY-MM-DD</code> format
+being more appropriate than any preferred local form. Also, references
+to national bodies by acronym alone will not necessarily convey
+sufficient meaning to an international audience.
+</p>
+
+<h2 id="ps1OToc">On and Off Topic Posting</h2>
+
+<p id="ps1OToc_1">
+ECMA 262 is the formal specification for ECMAScript, the
+standard adopted by javascript implementations and thus the
+specification for javascript.
+</p>
+
+<h3>ECMAScript and Browsers</h3>
+<p id="ps1OToc_2">
+As comp.lang.javascript deals with ECMAScript and ECMAScript was
+designed as a general scripting language for scripting any object
+model, questions relating to any application of ECMAScript are
+appropriate. The group has a general bias towards the use of
+ECMAScript in web browsers in an Internet context, and questions
+asked without additional qualification will tend to be assumed to
+be related to that environment and context. As a result it is a
+very good idea for questions asked that are not related to that
+default context; Intranet, other hosts, OS automation, etc., to
+include details of that context.
+</p>
+
+<h3 id="ps1OToc_3">Javascript (not Java)</h3>
+<p>
+Because of the name &quot;JavaScript&quot; being applied to the
+language early in its existence there is often confusion between
+javascript and the Java programming language. The two are distinct
+and very different languages. Questions relating to Java programming,
+Java Applets, Java Server Pages (JSP), etc., would be better asked in
+comp.lang.java.* groups. Only the use of ECMAScript to interact with,
+say, Java Applets would be on topic, and then the questions should
+relate to the ECMAScript aspect of the problem.
+</p>
+
+<h3 id="ps1OToc_4">Other Languages</h3>
+<p>
+Questions relating exclusively to other scripting languages,
+ mark-up languages ((x)<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>) and style sheets
+(<span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span>, XSL) are off topic and should be addressed to more
+appropriate newsgroups.
+</p>
+
+<h3 id="ps1OToc_5">The FAQ</h3>
+<p>
+The comp.lang.javascript newsgroup may also validly become its own
+subject, particularly the content and maintenance of the FAQ resources.
+But as a subject that is most appropriately raised and discussed by
+the individuals who invest their time in the group rather than
+passers-by.
+</p>
+
+<h3 id="ps1OToc_6">Usenet Behavior (don't)</h3>
+<p>
+Usenet, and particularly appropriate behaviour on and for Usenet, is
+also often raised. This is largely unwelcome but inevitable. Hopefully
+this document should contribute to a reduction in that noise by stating
+the group's attitude towards Usenet postings in greater detail than can
+be accommodated in the FAQ proper.
+</p>
+
+<h3 id="ps1OToc_7">Spam (don't)</h3>
+<p>
+Other things that are off topic for the group include obvious things
+like pyramid and get rich quick schemes, commercial advertising (with
+some rare exceptions mentioned below), job adverts, spurious
+invitations to visit web sites and anything else that might be
+reasonably regarded as spam.
+</p>
+
+<h3>Announcements</h3>
+<p id="ps1OToc_8">
+Announcements of product releases and events of particular relevance
+to javascript are welcome but, for products no more often than once
+pre major release, and for events preferably only once and certainly
+not more often than at two month intervals leading up to the event.
+Be aware that product announcements (particularly commercial
+javascript) are likely to attract reviews, which should not be
+expected to be uncritical.
+</p>
+
+<h2 id="ps1Txt">Plain-Text Only</h2>
+
+<p id="ps1Txt_1">
+Messages are posted in plain-text. There is no requirement for Usenet
+newsreader software to recognise, support or display any other
+content type, such as <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>, and it is felt that messages posted to
+comp.lang.javascript should be available to any and all newsreader
+software. Any form of attachments are also ruled out.
+</p>
+
+<p id="ps1Txt_2">
+It has also been observed that while most of the world may be happy
+to use the newsreader bundled with their operating system, experts in
+various aspects of computing will often go out and acquire software
+that they believe superior for the task they have for it. Meaning that
+the people best equipped to offer help in the group are also the people
+least likely to be using the newsreader that you are familiar with.
+The expectation should be that others are using software that conforms
+to the applicable standards and not that they are using software with
+any particular set of additional or &quot;enhanced&quot; features, no
+matter how common they may seem. Plain-text posts will be readable by
+everyone, other content types may be subject to more comment on the
+inappropriateness of the content type than answers intended to address
+the question raised.
+</p>
+
+<h2 id="ps1Post">Interleaved Posting, Bottom Posting and Not Top Posting</h2>
+
+<h3 id="ps1InBPost">Interleaved Posting, Bottom Posting</h3>
+
+<p id="ps1InBPost_1">
+The posting style in messages intended as responses to other messages
+is an area where a long established pattern of behaviour has been
+recognised as most appropriate for the medium and become an established
+convention.
+</p>
+
+<p id="ps1InBPost_2">
+Material quoted from the previous message is attributed to its author
+and indented with a marker character (usually &gt;). It is trimmed down
+to just sufficient to provide the context in which the response is made
+(marking the fact that an edit has been made with one of several
+common notations, such as: &lt;snip&gt;, [snip], [ ... ], etc.) and
+the responding text is placed <em>below</em> the quoted material
+to which it is responding, separated from it by a blank line.
+</p>
+
+<p id="ps1InBPost_3">
+If the response addresses several points from the previous message
+then the parts of the quoted text providing the context for each
+point are separated by the responses to each point. Producing an
+interleaved post. If the quoted material is in one block then the
+response text goes after it at the bottom. Producing a bottom post.
+</p>
+
+<p id="ps1InBPost_4">
+It is not possible to distinguish between bottom posting and an
+interleaved post that is only responding to one point in the previous
+message. Personally, I prefer interleaved responses but neither will
+result in an adverse reaction. The important points are that quoted
+material should be trimmed to the minimum that provides sufficient
+context and that responses should follow that quoted material.
+The conversation, and its chronological sequence, flows in the normal
+direction of reading; top to bottom.
+</p>
+
+<p id="ps1InBPost_5">
+Failing to quote any of the preceding message is not necessarily
+wrong, so long as the text posted makes sense without the preceding
+message, for example, by summarising the points being responded to.
+But generally it is easier to provide the context for a response with
+a quoted snippet. But responses need to have a context.
+</p>
+
+<h3 id="ps1TopPs">Top Posting (don't)</h3>
+
+<p id="ps1TopPs_1">
+Top posting is placing the response above the quoted material that is
+being responded to. The chronological sequence of conversation becomes
+the reverse of the normal top to bottom reading sequence and, without
+additional text summarising the points being responded to, it is
+difficult to determine exactly which points such a reply relates to.
+</p>
+
+<p id="ps1TopPs_2">
+The worst possible style of response posting is top posting over a full
+verbatim quote of the previous message, but even placing a response
+above a trimmed quote is wrong. It renders the conversational aspects
+of a response backwards, requiring people to scroll up and down to
+reconstruct the context of the response and generally making it hard
+work to understand the message. The answers come before the questions
+and the comments precede their subjects.
+</p>
+
+<p id="ps1TopPs_3">
+People do attempt to justify top posting. A common excuse made by top
+posters is that their newsreader places the cursor at the top of the
+message so that is the natural place to write the reply. That excuse
+is worthless as newsreader software does not dictate the style of
+posting and a cursor that starts at the top of a post does not have
+to stay there. Indeed it should not be expected to stay there, as the
+first responsibility of the respondent is to trim the quoted material
+down to just what is necessary to provide context for their response.
+A process that may reasonably be achieved by moving down through the
+quoted material deleting whatever is unneeded and marking those edits.
+And having done that the cursor will be at or near the bottom.
+</p>
+
+<p id="ps1TopPs_4">
+The other common excuse for top posting is that avoids excessive
+scrolling in order to find the response. The need for excessive
+scrolling in an interleaved or bottom posted message is most likely
+an indicator that the quoted material has not been suitably, or
+sufficiently, trimmed. But a top posters apparent desire to avoid
+scrolling is of no value to the regular users of Usenet who are
+accustomed to interleaved/bottom posting. They may take the top
+post as a preamble and still scroll down to see if any specific
+points have been responded to, not discovering that hey have wasted
+their time until they get to the bottom. A very short top post,
+without a blank line separating it from the following attribution
+line, may easily be missed by someone expecting the quoted material
+to come first, meaning that they do not discover where to look until
+they have scrolled to the bottom, and then they need to back scroll
+to the top. The perception is wrong, top posting results in much more
+unnecessary scrolling than it avoids, and that misperception impacts on
+regular user of Usenet; the very people whose help and co-operation is
+being sought.
+</p>
+
+<p id="ps1TopPs_5">
+<strong>Never top post to comp.lang.javascript</strong>. There is an
+established convention in posting styles on Usenet, and
+comp.lang.javascript. It is most efficient for everyone if newcomers
+follow that convention even if it seems strange to do so at first. In
+the long run it makes life easier for everyone, and the sooner that is
+recognised the less likelihood there is of being taken for a fool.
+</p>
+
+<h2 id="ps1Trim">What to Trim</h2>
+
+<p id="ps1Trim_1">
+As a general guide, quoted material should almost never exceed the
+text posted in response. Exceptions might occur when both consist
+of exactly one line or sentence, or maybe a short code block that
+only needs a one line comment.
+</p>
+
+<p id="ps1Trim_2">
+Deciding what to trim is a matter of judgment and takes a bit of
+practice to get right. There are few hard and fast rules and the best
+general advice has got to be to observe the behaviour of others
+positing to the group.
+</p>
+
+<p id="ps1Trim_3">
+It is necessary to preserve the context in
+which a response is made but some things can be trimmed automatically:
+Signatures (if present); the section at the end of a post (and they
+should always, and only, be at the end, no matter where any individual
+newsreader may try to insert them) which starts with a separator
+consisting of &quot;dash dash space newline(aka return)&quot; on a
+line of its own, followed by material that is not directly
+related to the post but may be of more general interest or related
+to the individual who makes the post, should <strong>always</strong>
+be trimmed from quoted material. It is never normally relevant to a
+posted response, but even if a signature is being directly commented
+upon it is vital to remove the signature separator at least, and best
+to trim anything it contains that is not being commented upon.
+</p>
+
+<p id="ps1Trim_4">
+In comp.lang.javascript there is rarely much point in quoting
+javascript code that is not being directly commented upon or
+corrected. The indenting character (and possible line wrapping)
+renders any quoted code syntactically invalid so anyone wanting
+to use the code will have to go back to the message in which it
+originally appeared anyway. That would certainly apply to a post
+wishing to thank someone who had provided a complete scripted
+demonstration for their efforts.
+</p>
+
+<p id="ps1Trim_5">
+No matter what gets trimmed the material that stays should not be
+altered in terms of spelling, words used and their order, etc. A
+quote should be a quote not an interpretation.
+</p>
+
+<h2 id="ps1Marg">Margins and Line Wrapping</h2>
+<h3 id="ps1Mar">Margins</h3>
+
+<p id="ps1Mar_1">
+A line in a plane text Usenet post could be quite long, and some
+newsreaders would automatically wrap that line to the window in
+which it was being displayed. Others would provide horizontal scroll
+bars (usually undesirable) and yet others may not be able to access
+characters beyond the 80<sup>th</sup> (unlikely these days). There
+are no rules for handling excessively long lines but Usenet is old
+and has lived through the time when 80 character wide displays were
+commonplace. Along the way it became the convention that Usenet posts
+should have lines no longer than between 70 and 80 characters. And
+that avoids the need for any specified requirement in the handling of
+long lines by newsreader software. Lines in that range are unlikely to
+need to be wrapped for display and will not normally generate
+horizontal scroll bars. It is also the case that humans generally
+(and sometimes strongly) prefer to read text that is no more than about
+80 character per line.
+</p>
+
+<p id="ps1Mar_2">
+It is widely recommended that newsreader software should be configured
+to automatically wrap at about 72 characters when posting, which works
+well for posted text but can be problematic for posting long URLs and
+particularly in our context, posted source code. Others suggest that
+software should not be allowed to wrap posted code at all and that the
+poster should always do it manually. In either case it is the
+individual composing the post that is responsible for, and should be in
+control of, the wrapping of the content to ensure that it is suitable
+for posting to the group.
+</p>
+
+<h3 id="ps1Lw">Line Wrapping</h3>
+
+<p id="ps1Lw_1">
+Most URLs are less than 72 character long anyway but some, such as
+references to Usenet articles in the archives at groups.google.com,
+are longer. Some newsreader software is smart enough to recognise a
+URL and not apply its default margin settings to them but in any event
+delimiting them with &quot;&lt;URL:&quot at the beginning and
+&quot;&gt;&quot; at the end (preferably with the URL separated from
+the delimiters with spaces) should be sufficient to indicate to a
+reader that a line wrapped URL will need some remedial action.
+</p>
+
+<p id="ps1Lw_2">
+Restricting margins to 72 characters usually does not need to affect
+the functionality of posted code either. Allowing a newsreader to
+line wrap posted code as it sees fit will usually render that code
+faulty (and difficult to read) and that will make it difficult for
+a reader to differentiate between problems within the original code
+and problems arising form line wrapping.
+</p>
+
+<h3 id="ps1Lw_3">Code Reformatting</h3>
+<p>
+Javascript (ECMAScript) is extremely tolerant of white space (including
+line breaks) within its source code. There are in fact only a couple of
+places where white space characters are not allowed. For example, a
+line break may not be placed between the <code>return</code> keyword
+and any expression that is to be returned. As a result it is almost
+always possible to spread a line of javascript that would exceed the
+newsreaders wrapping margin across two or more lines without affecting
+its functionality or syntactic correctness.
+</p>
+
+<p id="ps1Lw_4">
+One of the main reasons that Javascript is so tolerant of white space
+is to allow the structure of the source code (how the code is laid out
+in a text editor/post) to convey additional meaning (usually related to
+structure of the code/function/program) and maximise clarity for human
+readers. The breaking of long lines of source code across several lines
+should be done in a way that does not detract from the clarity of the
+code.
+</p>
+
+<h4 id="ps1Lw_5">Blocks</h4>
+<p>
+The main source code structuring consideration that adds clarity is
+block indenting. A block is defined with curly brackets <code>{</code>
+and <code>}</code> and represents a block statement (which may contain
+zero or more other statements). It is normal to indent the statements
+within a block by one tab character, though that tab is usually set to
+4 or fewer spaces (two spaces is frequently recommended) width as the
+normal default 8 spaces width is a bit
+too deep for most practical uses. However, <em>tab character should not be
+used for indention in Usenet posts at all</em> as newsreader default tab
+settings may often be 8 characters but may also be zero characters,
+defeating the purpose indentation in posted code entirely. Good text
+editors will usually offer a facility to convert tabs to any number of
+spaces, which can be used to prepare code for posting. Indenting in
+code posted to Usenet should be done with space characters. 4 or fewer
+(two is often recommended) per level of indentation.
+</p>
+
+<p id="ps1Lw_6">
+There are various common styles of block indenting, of which I prefer
+to leave the opening <code>{</code> at the end of the control statement
+(on the same line) and list the block contents as one statement per
+line, indented by 4 <em>or fewer</em> spaces, with the closing
+<code>}</code> on a new line indented so that it lines up vertically
+with the start of the control statement, e.g.:-
+</p>
+
+<pre id="ps1Lw_ex1">
+function doSomething(oArea){
+ var nArea = oArea.nWidth * oArea.nHeight;
+ var result = true;
+ if(!nArea){
+ removeRegion(oArea);
+ result = false;
+ }else if(oArea.nWidth &lt; oArea.nHeight){
+ result = oArea.reShape(nArea);
+ }
+ return result;
+}
+
+<span class="commentJS">/* The same function may also be commonly formatted:- */</span>
+
+function doSomething(oArea)
+{
+ var nArea = oArea.nWidth * oArea.nHeight;
+ var result = true;
+ if(!nArea)
+ {
+ removeRegion(oArea);
+ result = false;
+ }
+ else if(oArea.nWidth &lt; oArea.nHeight)
+ {
+ result = oArea.reShape(nArea);
+ }
+ return result;
+}
+
+<span class="commentJS">/* -or:- */</span>
+
+function doSomething(oArea)
+ {
+ var nArea = oArea.nWidth * oArea.nHeight;
+ var result = true;
+ if(!nArea)
+ {
+ removeRegion(oArea);
+ result = false;
+ }
+ else if(oArea.nWidth &lt; oArea.nHeight)
+ {
+ result = oArea.reShape(nArea);
+ }
+ return result;
+ }
+</pre>
+
+<p id="ps1Lw_7">
+It is not that important which style of block indenting is used,
+everyone has their own preferred style, but it is important that
+<em>a</em> style of block indenting is used in code posted to the
+group. In all cases the indenting serves to make the structure of
+the function apparent in the structure of the source code. It is
+an aid to human readers of the code and saves a great deal of time
+for anyone attempting to offer help and so needing to understand
+the code.
+</p>
+
+<p id="ps1Lw_8">
+Sometimes the line wrapping problem can be avoided by reducing the
+number of space characters by which the blocks are indented. However,
+if a statement must be broken across several lines
+it could be indented to a different level than it's own start, and it
+could also be indented at a different level to its block contents (if
+any). If block indenting is at, say, 4 space intervals then indenting a
+broken line at 1 to 3 characters should serve to make it clear that
+it is indenting separate from the general block structure of the
+code, e.g.:-
+</p>
+
+<pre id="ps1Lw_ex2">
+function getRootElement_OrDefault(deflt){
+ if((typeof document.compatMode == "string")&&
+ (document.compatMode.indexOf("CSS") != -1)&&
+ (document.documentElement)){ <span class="commentJS">//<< broken statement</span>
+ return document.documentElement;
+ }else if(document.body){
+ return document.body;
+ }else{
+ return deflt;
+ }
+}
+
+</pre>
+
+<p id="ps1Lw_9">
+Another alternative for formatting statements broken across lines
+might be to disregard the indenting on the left and line the code
+that belongs to the broken statement up on the right hand side.
+e.g.:-
+</p>
+
+<pre id="ps1Lw_ex3">
+this.position = function(){
+ var twiceSize;
+ if(--delay <= 0){
+ step();
+ if(((z+=fv) >= planeDepth)||
+ ((dy+dm) > windowCenterY)||
+ ((dx+dm) > windowCenterX)||
+ (v < 0)){ <span class="commentJS">//right aligned broken statement</span>
+ this.reset();
+ step();
+ }
+ div.top = (sy+(py*dy)-dm)+cssUnitsOrZero;
+ div.left = (sx+(px*dx)-dm)+cssUnitsOrZero;
+ divClip.height = (twiceSize = (dm << 1)+cssUnitsOrZero);
+ divClip.width = twiceSize;
+ }
+ next.position();
+};
+</pre>
+
+<p id="ps1Lw_10">
+Thus the ability to insert line breaks liberally throughout javascript
+source code allows almost all code to be formatted in a fully
+functional, well structured and clear way within the restricted
+margins appropriate in posts to comp.lang.javascript. Efforts put into
+preparing posted code to be clear and comprehensible to its Usenet
+audience will be rewarded. But it is important to start any formatting
+required with the actual code in use, rather than attempting to
+re-type it, in order not to introduce errors that are not present in
+the original and so have nothing to do with the original problem.
+Having prepared the formatting of the code to suite Usenet it is
+important to re-test it to ensure that it is still as functional, that
+no errors have been introduced and that it still exhibits whatever
+behaviour it was that motivated the post in the first place.
+</p>
+
+<h3 id="ps1LwQu">Line Wrapping in Quoted Material</h3>
+
+<p id="ps1LwQu_1">
+If a news post has been wrapped at, say, 72 characters and it is
+responded to then the indenting character used to mark quoted material
+will add to the length of that line. Maybe pushing it over the length
+at which the reply will be wrapped. The result, if posted without
+adjustment, may look something like this:-
+</p>
+
+<pre id="ps1LwQu_ex1">
+An example OP wrote:
+> A long line of text quoted from the previous post, that was wrapped
+at
+> 72 characters in that post but has been extended to 74 characters
+long
+> lines because of the addition of the indenting characters that mark
+it
+> as a quotation, but has been re-wrapped to 72 characters in the
+posted
+> follow-up that is quoting it.
+
+The comment posted in response to the material quoted above. Originally
+wrapped in the response at 72 characters.
+</pre>
+
+<p id="ps1LwQu_2">
+The effect is that the words &quot;at&quot;, &quot;long&quot;,
+&quot;it&quot; and &quot;posted&quot; are no
+longer marked as part of the quotation but instead appear to be badly
+formatted and meaningless comments on that quoted material. Which has
+itself gained the appearance of being incompetently trimmed. The effect
+escalates with additional responses, loosing more meaning and becoming
+less and less clear as to whom any particular part of the text is
+attributable.
+</p>
+
+<pre id="ps1LwQu_ex2">
+The First Responder wrote:
+> An example OP wrote:
+>> The First Responder wrote:
+>>> An example OP wrote:
+>>>> A long line of text quoted from the previous post, that was
+wrapped
+>>> at
+>>>> 72 characters in that post but has been extended to 74 characters
+>>> long
+>>>> lines because of the addition of the indenting characters that
+mark
+>>> it
+>>>> as a quotation, but has been re-wrapped to 72 characters in the
+>>> posted
+>>>> follow-up that is quoting it.
+>>>
+>>> The comment posted in response to the material quoted above.
+>> Originally
+>>> wrapped in the response at 72 characters.
+>
+>> This response is the OP's reply to the comments on the original
+>> post. It quoted the previous posts in full and was wrapped at 72
+>> characters.
+>
+>And the original responder added this.
+
+The conversation ended with the OP thanking the responder for their
+comments. (but who said what?)
+</pre>
+
+<p id="ps1LwQu_3">
+The solution is to be aware that this may happen and re-wrap that
+quoted material so that it is not effected by the automatic line
+wrapping when a post is sent, or to increase the wrapping margins by
+the number of characters inserted to mark a quotation (so long as the
+result does not exceed 80 characters). Some newsreader software can
+handle this automatically, and add on software exists for other
+products (such as OE), but ultimately the responsibility for properly
+marking and attributing quoted material belongs with the individual
+making the post.
+</p>
+
+<p id="ps1LwQu_4">
+If the two had taken the effect of the progressive lengthening of lines
+in quoted material into account the result would have looked like
+this:-
+</p>
+
+<pre id="ps1LwQu_ex3">
+The First Responder wrote:
+> An example OP wrote:
+>> The First Responder wrote:
+>>> An example OP wrote:
+>>>> A long line of text quoted from the previous post, that was
+>>>> wrapped at 72 characters in that post but has been extended to 74
+>>>> characters long lines because of the addition of the indenting
+>>>> characters that mark it as a quotation, but has been re-wrapped to
+>>>> 72 characters in the posted follow-up that is quoting it.
+>>>
+>>> The comment posted in response to the material quoted above.
+>>> Originally wrapped in the response at 72 characters.
+>
+>> This response is the OP's reply to the comments on the original
+>> post. It quoted the previous posts in full and was wrapped at 72
+>> characters.
+>
+>And the original responder added this.
+
+The conversation ended with the OP thanking the responder for their
+comments.
+</pre>
+
+<p id="ps1LwQu_5">
+It would have been clear form the number of quote indicating characters
+who exactly had said what and the quoted material would have been
+easier to read and understand. Though in practice there probably should
+have been much more trimming along the way as the whole conversation
+would probably not have been needed to show the context of each
+response.
+</p>
+
+
+<h2 id="ps1Code">General Code Postings, and when to use a URL</h2>
+
+<p id="ps1Code_1">
+Often a question cannot usefully be answered without being accompanied
+with javascript source code. Even a very detailed explanation of a
+process will not tend to narrow the possibilities down to just one
+method, and deciding whether a reported effect is due to a
+characteristic of an execution environment or code that is taking the
+wrong approach cannot be done without seeing the source code.
+</p>
+
+<p id="ps1Code_2">
+In some cases small snippets of code, say an individual function's
+definition, might be sufficient. Though it is usually necessary to know
+how such a function is being called and what arguments it is using. But
+ideally questions should be accompanied by an easily testable example
+that demonstrates the characteristics that provoked the question.
+</p>
+
+<p id="ps1Code_3">
+Easily testable because there is no better aid to debugging than being
+able to reproduce a problem. Time spent turning a snippet of code into
+testable web page (or whatever) is not rewarded if the results do not
+exhibit the problem described. And asking many people to repeat that
+process when it could have been done by the questioner once, in a way
+that guaranteed a demonstration of the problem, is not a good use of
+the group or the time of its participants.
+</p>
+
+<p id="ps1Code_4">
+However, posting the entire source code of a web page that happens to
+include the problematic script is rarely the answer. For one thing web
+pages often import <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span>, other script files and graphics (the latter
+simply could not be posted to the group). But web pages also often
+consist of large amounts of <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>, which would require careful
+re-wrapping to fit within the posting margins and be left correct, and
+much of the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> would be irrelevant to the post.
+</p>
+
+<p id="ps1Code_5">
+There is also the question of bandwidth in transmission and capacity in
+storage. Every post is stored, at least for a time, on every news server
+carrying the group world wide and usually also on the hard disk of
+everyone who reads the group. And to get from server to server, and
+eventually to the many readers, it must be transmitted, consuming
+bandwidth related to the size of the post. The more irrelevant
+information that any post contains the more those resources are wasted
+(this is also a reason for appropriate trimming of quoted material).
+</p>
+
+<p id="ps1Code_6">
+The comp.lang.javascript FAQ makes the injunction that posting code of
+more than 500 lines is unacceptable. That is the theoretical upper
+limit that should never be exceeded, but a post of even half that
+length would have to be exceptional.
+</p>
+
+<p id="ps1Code_7">
+The easiest way of demonstrating a problem in context without posting
+excessive amounts of code and <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> is to make a page that exhibits the
+problem available online and post the URL of that page along with the
+question. Possibly accompanied by a snippet of the code highlighting
+the suspected cause.
+</p>
+
+<p id="ps1Code_8">
+The circumstances under which making a page that demonstrates the
+problem available online is advisable are, whenever that page is
+interacting within a frameset, or whenever images play a significant
+part in a problem. As those circumstances are time consuming to
+reproduce from posted code and cannot always be recreated for testing.
+But any request to have people examine excessive amounts of code
+and/or <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> should also be made available on line instead of in a post.
+</p>
+
+<p id="ps1Code_9">
+Unfortunately not all participants in the group are viewing Usenet in a
+way that makes easily following a URL to an example page viable. Often
+downloading new Usenet posts as a batch and then viewing them off line.
+Re-connecting to view an example page is not always desirable (due to
+local conditions, slow modem connections and potential associated
+expense) and can be unrewarding if the page viewed is a mush of <abbr title="What You See Is What You Get">WYSIWYG</abbr>
+generated bloated <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>-like noise. Where it takes a considerable time
+to even locate the cause of what may still turn out to be a trivial
+problem.
+</p>
+
+<p id="ps1Code_10">
+Then again there are people using the group who much prefer examples to
+be available online. Either way what is not wanted is for questions to
+be asked without making the corresponding code available in some way,
+or the posting of excessive amounts of code.
+</p>
+
+<p id="ps1Code_11">
+A good compromise, and a valuable debugging technique, is the creation
+of a demonstration test-case page. A page containing no more than
+sufficient <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> and javascript to allow others to reproduce the problem
+and see the relevant code without anything extraneous. Such a test-case
+page would almost always be short enough to post with the question
+(properly formatted) and could additionally be made available online for
+the convenience of those that would prefer to use a URL to load it
+directly into a browser for testing.
+</p>
+
+<p id="ps1Code_12">
+Creating such a test-case page can be valuable in itself as attempting
+to reduce a problem from a larger context to an isolated demonstration
+will often reveal the cause of that problem along the way. The act of
+cutting out what initially seems irrelevant often reveals that the
+problem in fact results form an unexpected interaction with something
+that was assumed to be unconnected. And if the problem can be
+demonstrated in isolation then it is relatively easy for readers of the
+question to reproduce the problem and identify its cause, resulting in
+less discussion of superfluous issues and usually a quicker resolution
+of the question.
+</p>
+
+<p id="ps1Code_13">
+It is very important to test test-case pages prior to posting them to
+ensure that they do indeed exhibit the characteristic that motivated
+the question. At least if you want to be taken seriously in future. And
+when such a test-case is posted to the group it should be formatted and
+indented to facilitate the essayist reading of the code and testing by
+no more than copying the page into a text editor and saving it locally
+as a <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> file.
+</p>
+
+
+<h2 id="ps1Quest">Well Asked Questions Get the Best Answers</h2>
+
+<p id="ps1Quest_1">
+Beyond any considerations of posting style and formatting, the quality
+of questions asked has a considerable impact upon the number and
+quality of answers given, and the time taken to elicit a useful
+response. Vague questions are likely to be answered with requests for
+clarification. Terse general questions are likely to elicit yes or no
+answers (often both). And questions that have been asked, and well
+answered, before (especially frequently or in the recent past) are as
+likely as not to be ignored.
+</p>
+
+<p id="ps1Quest_2">
+When asking a question it would almost always be a good idea to put
+yourself in the position of the reader of the question, read it back to
+yourself and ask yourself; Does this question actually ask what I
+want to know, and is it sufficiently clear and detailed to elicit that
+answer?
+</p>
+
+<p id="ps1Quest_3">
+The following is a short list of recurring features of badly asked
+questions:-
+</p>
+
+
+<h3 id="ps1QSub">Appropriate Use of the Subject Header</h3>
+
+<p id="ps1QSub_1">
+Another Usenet convention holds that the Subject header should not be
+expected to be available to a reader of any message. While it is
+unlikely that there are any newsreaders currently in use in which the
+user is not presented with the Subject header, it remains
+inappropriate to ask a question in the subject header (or to assume
+that its contents will provide supplementary information about a
+question) and doing so is as likely to invoke a lesson in Usenet
+etiquette as an answer to the question. But a question is not really
+a subject anyway. The subject should describe what the question is
+in relation to, and is useful for archive searching and
+categorisation rather than as a means of communication.
+</p>
+
+<p id="ps1QSub_2">
+Any question asked should always appear in the body of the post, and in
+a form that does not assume the availability of the Subject header to
+the reader.
+</p>
+
+<p id="ps1QSub_3">
+The Subject header should also not be wasted. Placing &quot;please
+help&quot; and the like in the subject header is unwelcome and
+counterproductive. Take the opportunity to construct a Subject
+header that states the type of the problem, what it relates to.
+Subject headers that state the real subject will attract the
+attention of people with a special interest in that subject,
+exactly those people best able to offer help.
+</p>
+
+<h3 id="ps1QRes">Doing Your Own Research</h3>
+
+<p id="ps1QRes_1">
+Many questions, at least the questions literally asked, could quickly
+be answered with a little research, and the chances are that regulars
+on the group know how easily those answers could have been found with
+a little effort. The group is not intended to be a vending machine for
+trivial information about javascript, that wouldn't be an interesting
+group to participate in.
+</p>
+
+<p id="ps1QRes_2">
+On the other hand, evidence that some effort has been put into
+researching a problem before asking a question tends to be looked upon
+kindly (though claiming to have exhausted all lines of research when that
+is obviously not the case would have the opposite effect).
+</p>
+
+<p id="ps1QRes_3">
+The obvious first place to look for answers is in
+<a href="../clj_faq.html">the group's FAQ</a>. That will
+mean reading all of the FAQ because the answers to some problems (or
+sufficient clues to those answers) will be found within the answers to
+seemingly unrelated questions, or the resources linked to from the FAQ.
+That in itself is a fairly big task, but if not undertaken will just
+result in questions being answered with references back to the FAQ.
+There is also a Usenet convention that whenever a newsgroup
+(particularly technical groups) provides a FAQ resource, that FQA should
+be read by anyone wishing to post to the group <em>prior</em> to making
+their first post. So reading the FAQ is <em>not optional</em> anyway.
+</p>
+
+<p id="ps1QRes_4">
+The Internet provides a massive resource for researching virtually any
+question, and particularly questions relating to computing. Search
+engines are the primary research tool and among those Google search is
+extremely useful. But when a question relates to javascript in a way
+that indicates that it may be suitable to be asked on
+comp.lang.javascript the best place to research the question is
+<a href="http://groups.google.com/groups?q=comp.lang.javascript">
+groups.google.com</a>, as that resource holds a searchable archive of
+almost all postings ever made to the group. There is an
+<a href="http://groups.google.com/advanced_group_search?group=comp.lang.javascript">
+&quot;Advanced Search&quot; page</a>, where entering
+&quot;comp.lang.javascript&quot; in the Newsgroup field and suitable keywords
+in the other fields provided will return all messages posted to the group
+that match the search criteria. As most questions will have been asked
+before many answers can be obtained from the groups.google.com archives.
+But be aware of the date of posts found as the archive goes back to
+1996 and some things have changed over the intervening years.
+</p>
+
+<p id="ps1QRes_5">
+Reading back over recent posts to the group, for a minimum of a week
+and preferably more than a month will avoid the need to re-ask a
+question that has been asked and answered in recent memory. Not all
+news servers will hold all messages over that period so
+<a href="http://groups.google.com/groups?q=comp.lang.javascript">
+the group archives at groups.google.com</a> can be useful in this
+respect also.
+</p>
+
+<h3 id="ps1DontWork">&quot;It doesn't work&quot;</h3>
+
+<p id="ps1DontWork_1">
+People don't tend to question code that
+does exactly what they want it to do. Sometimes they may ask how it
+does exactly what they want but generally it is superfluous to state
+that code that does not address a situation doesn't work.
+</p>
+
+<p id="ps1DontWork_2">
+To start with computer code always does exactly what is asked of it,
+that is the nature of computers. So it does &quot;work&quot;, it is
+just that it doesn't do what is wanted of it. And that is a problem
+because code that does not do something that is wanted of it cannot
+itself explain what that something was.
+</p>
+
+<p id="ps1DontWork_3">
+It is the task of a human designer to decide what is wanted form code,
+to specify the task. The reader of a question can do no more than
+guess as to the task unless the questioner explains the specification
+for the code, and that specification needs to be specific. That
+information is needed when assessing what would qualify as
+&quot;works&quot; in the context of the question.
+</p>
+
+<p id="ps1DontWork_4">
+But in addition to knowing what would qualify as working it is also
+necessary to know in what way code is failing to work. There is a big
+difference between code that appears to do nothing when executed, code
+that does something undesirable in addition to what is expected of it
+and code that does something else entirely.
+</p>
+
+<p id="ps1DontWork_5">
+Instead of stating the self-evident &quot;It doesn't work&quot;, the
+posters of questions should attempt to provide answers to:-
+</p>
+
+<dl id="ps1DontWork_df">
+ <dt id="ps1DontWork_p1">1. What you have done?</dt>
+
+ <dd id="ps1DontWork_d1">Providing access the code (possibly in the form of a test
+ case), explaining the steps required to initiate the
+ undesirable effect and the environments (usually web
+ browsers) where the problem has been observed, so that it
+ can be reproduced and tested.
+ <dd>
+
+ <dt id="ps1DontWork_p2">2. What you expected to happen?</dt>
+
+ <dd id="ps1DontWork_d2">Both specifically in the case of the code under discussion and
+ generally with regard to the design specification.
+ <dd>
+
+ <dt id="ps1DontWork_p3">3. What really happened?</dt>
+
+ <dd id="ps1DontWork_d3">What was observed to happen and any error messaged generated.
+ So that when (and if) the problem is reproduced in testing it
+ is possible to identify it as the effect under discussion.
+ <dd>
+</dl>
+
+<h3 id="ps1CntX">Explain the Whole Context</h3>
+
+<p id="ps1CntX_1">
+The context in which a question is asked or a problem exists is very
+important to the type of answers given or solutions proposed. Beyond
+the obvious required details such as the execution host(s), scripts
+used and how they are used, There are details like whether a project
+is for the Internet or an Intranet. Because on comp.lang.javascript
+the default assumption is that the context will be browser scripting
+for the Internet, many approaches/solutions are ruled out, but some may
+be completely reasonable and practical in the more restricted context
+of a company Intranet (or on more controlled hosts such as the windows
+scripting host or server-side javascript).
+</p>
+
+<p id="ps1CntX_2">
+There have been many occasions where many answers to questions have
+stressed the unsuitability of particular approaches to use on the
+Internet only for the original questioner to respond by explaining
+that they don't apply because their context is an Intranet. That
+wastes the time of everyone who composed a response to the original
+question; if they had been in possession of the real context from the
+outset they could have got on with proposing/discussing solutions that
+were appropriate, or moved on to something more interesting.
+</p>
+
+<p id="ps1CntX_3">
+But the full context of a question goes beyond such details and answers
+the question: why? Often a question will be asking about a particular
+approach that, to the questioner, is a perceived solution to a problem.
+The answer to the question why would explain what that problem is, and
+knowing what that problem is will allow respondents to assess the
+suitability of the approach at addressing the problem and possibly
+suggest other, and superior, solutions. There is very little that is
+genuinely new and unique, whatever the wider problem is the chances are
+that someone will be familiar with it and be in a position to identify
+the best solution (even if that is just confirming that the proposed
+solution is the best available). Questions raised on the group should
+always include the answer to the question: why?
+</p>
+
+<h3 id="ps1PR">Proof-Read your Questions</h3>
+
+<p id="ps1PR_1">
+Proof-read your message two or three times before posting. Ensure that
+it is as error free as possible and does convey the question and
+provide all of the necessary information in a way that will not be
+subject to misinterpretation.
+</p>
+
+<!-- <h2><a name="ps1notHD" id="ps1notHD">comp.lang.javascript is Not a Helpdesk</a></h2>
+
+<p id="ps1notHD_1">
+The comp.lang.javascript newsgroup is a discussion forum on the subject
+of ECMAScript (javascript). It is not a helpdesk and its participants
+make their contributions voluntarily in their own time and with their
+own resources for whatever reasons they see fit. Just because the
+majority of the discussion starts with someone posting a question,
+often asking for help with some aspect of javascript, does not mean
+that anyone should have any expectation of receiving any help or
+assistance from any ensuing discussion. So, although help and
+assistance is often (if not usually) offered during the following
+discussion, that is just a positive side effect of the group and not
+its reason for existing.
+</p>
+
+<p id="ps1notHD_2">
+The real benefit of the group goes to its regular participants, who,
+in participating in the discussion, attempting to address the diverse
+situations and problems raised and exposing their code to critical
+public scrutiny, get to hone their code authoring and script design
+skills and knowledge with the active assistance and critical feed-back
+of their peers.
+</p>
+
+<p id="ps1notHD_3">
+The whole process would not work as well if people did not post
+questions relating to a diversity of problem situations to the group
+in the hope of getting some assistance, and people would never do that
+if there were not a good chance of actually getting assistance. But the
+people posting such questions need to remember that they have no right
+to assistance, and cannot demand, or even expect it. Instead, wanting
+to take advantage of the potentially beneficial side effect of the
+existence of the group, they should encourage the group to give them
+assistance, by making doing so as easy and convenient as possible. The
+preceding document is intended to make it as clear as possible how to
+go about achieving that aim.
+</p> -->
+
+<h2 id="ps1AddR">Additional Reading</h2>
+
+<ul class="resourceList" id="ps1AddR_l">
+ <li><a href="http://www.cs.tut.fi/~jkorpela/usenet/dont.html">The seven don'ts of Usenet<br>http://www.cs.tut.fi/~jkorpela/usenet/dont.html</a></li>
+ <li><a href="http://oakroadsystems.com/genl/unice.htm">Playing Nice on Usenet<br>http://oakroadsystems.com/genl/unice.htm</a></li>
+ <li><a href="http://www.netmeister.org/news/learn2quote2.html">How do I quote correctly in Usenet? - Quoting and Answering<br>http://www.netmeister.org/news/learn2quote2.html</a></li>
+ <li><a href="http://www.xs4all.nl/%7ewijnands/nnq/nquote.html">Quoting Style in Newsgroup Postings<br>http://www.xs4all.nl/%7ewijnands/nnq/nquote.html </a></li>
+ <li><a href="http://www.cs.tut.fi/~jkorpela/usenet/xpost.html">Why and how to crosspost<br>http://www.cs.tut.fi/~jkorpela/usenet/xpost.html</a></li>
+ <li><a href="http://kb.indiana.edu/data/affn.html?cust=12244">How can I post a message to more than one Usenet newsgroup?<br>http://kb.indiana.edu/data/affn.html?cust=12244</a></li>
+ <li><a href="http://catb.org/%7Eesr/faqs/smart-questions.html">How To Ask Questions The Smart Way<br>http://catb.org/%7Eesr/faqs/smart-questions.html</a></li>
+ <li><a href="http://www.chiark.greenend.org.uk/~sgtatham/bugs.html">How to Report Bugs Effectively<br>http://www.chiark.greenend.org.uk/~sgtatham/bugs.html</a></li>
+</ul>
+</body>
+</html>
/trunk/cljs/notes/posting/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/notes/type-conversion/index.html
===================================================================
--- trunk/cljs/notes/type-conversion/index.html (nonexistent)
+++ trunk/cljs/notes/type-conversion/index.html (revision 45)
@@ -0,0 +1,1319 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+ <title>Javascript Type-Conversion</title>
+ <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<link href="../../faq.css" rel="stylesheet" type="text/css">
+<link href="../notes.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+td {
+ text-align:center;
+}
+pre.st {
+ background-color:#EEEEFF;
+ margin:0px;
+ padding:0px;
+ text-align:left;
+ border:0px none #EEEEFF;
+}
+caption {
+ font-weight:bold;
+}
+th, td {
+ vertical-align:baseline;
+ background-color:#EEEEFF;
+ color:#000000;
+ white-space:nowrap;
+ padding:2px
+}
+.true {
+ color:#003444;
+ background-color:#E0FFE0;
+}
+.false {
+ color:#003444;
+ background-color:#FFE0E0;
+}
+table {
+ margin:1em 2.5em;
+}
+ </style>
+ </head>
+ <body>
+
+<h1>Javascript Type-Conversion</h1>
+<div id="faqNav">
+ <a href="/faq/">FAQ</a> &gt; <a href="/faq/notes/">FAQ Notes</a>
+</div>
+
+<ul>
+ <li><a href="#tcInt">Introduction</a></li>
+ <li><a href="#tcBool">Converting to Boolean</a></li>
+ <li><a href="#tcString">Converting to String</a></li>
+ <li><a href="#tcNumber">Converting to Number</a></li>
+ <li><a href="#tcParse">Parsing to Number</a>
+ <ul>
+ <li><a href="#tcParseFl">parseFloat</a></li>
+ <li><a href="#tcParseIn">parseInt</a></li>
+ <li><a href="#tcPrIntRx">parseInt with a radix argument</a></li>
+ </ul>
+ </li>
+ <li><a href="#tcToInt32">ToInt32</a></li>
+ <li><a href="#tcUserIn">Converting User Input</a>
+ <ul>
+ <li><a href="#tcRegEx">Regular expression examples</a></li>
+ </ul>
+ </li>
+</ul>
+
+<h2 id="tcInt">Introduction</h2>
+
+<p id="tcInt_1">
+Javascript (ECMAScript) is a loosely typed language. That does not mean
+that it has no data types just that the value of a variable or a Javascript
+object property does not need to have a particular type of value assigned
+to it, or that it should always hold the same type of value. Javascript
+also freely type-converts values into a type suitable for (or required by)
+the context of their use.
+</p>
+
+<p id="tcInt_2">
+Javascript being loosely typed and willing to type-convert still does not
+save the programmer from needing to think about the actual type of values
+that they are dealing with. A very common error in browser scripting, for
+example, is to read the value property of a form control into which the
+user is expected to type a number and then add that value to another
+number. Because the value properties of form controls are strings (even if
+the character sequence they contain represents a number) the attempt to
+add that string to a value, even if that value happens to be a number,
+results in the second value being type-converted into a string and
+concatenated to the end of the first string value from the from control.
+</p>
+
+<p id="tcInt_3">
+That problem arises from the dual nature of the <code>+</code> operator
+used for both numeric addition and string concatenation. With which the
+nature of the operation performed is determined by the context, where
+only if both operands are numbers to start with will the <code>+</code>
+operator perform addition. Otherwise it converts all of its operands to
+strings and does concatenation.
+</p>
+
+<p id="tcInt_4">
+The following discussion is illustrated with Javascript generated tables
+of values resulting from the conversion operations. The headers of those
+tables display the values as represented in the Javascript source code
+used rather than their internal representation. So, for example
+<code>123e-2</code> as a number was the character sequence typed into
+the source code, the interpreter reads that and generates the
+number value 1.23 from it for internal use. The various values used for
+the tests have been chosen to illustrate aspects of type
+converting, those aspects may not apply to all of the tables presented.
+However, all of the test values are included in all of the tables (except
+where no type converting occurs) for full comparison. The bodies of the
+tables list the results of the various type conversion operations.
+</p>
+
+<p id="tcInt_5">
+If you are accepting/using this page's <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> style suggestions the type
+of the values at various stages is illustrated by the colour of the text
+used. The following key shows those type/colour relationships, they are
+derived from the string values returned by the <code>typeof</code>
+operator (which returns <code>&quot;object&quot;</code>
+for the <code>null</code> type when in reality <code>null</code> is
+distinct from objects).
+</p>
+
+<table id="tcInt_key">
+ <tbody>
+ <tr><th>Key</th></tr>
+ <tr><td class="st">string</td></tr>
+ <tr><td class="nm">number</td></tr>
+ <tr><td class="bl">boolean</td></tr>
+ <tr><td class="ob">object</td></tr>
+ <tr><td class="fn" style="text-align:center;">function</td></tr>
+ <tr><td class="ob">null</td></tr>
+ <tr><td class="un">undefined</td></tr>
+ </tbody>
+</table>
+
+<p id="tcInt_6">
+The boolean values of results also have a coloured background to highlight
+ <code>true</code> or <code>false</code>.
+</p>
+
+<h2 id="tcBool">Converting to Boolean</h2>
+
+<p id="tcBool_1">
+When evaluating the expression of an <code>if</code> statement the Javascript
+interpreter will type-convert the result of that expression to boolean
+in order to make its decision. Also various operators internally
+type-convert their operands to boolean in order to determine what
+action to take. These include the logical operators like AND
+(<code>&&</code>), OR (<code>||</code>) and NOT (<code>!</code>). The NOT
+operator type-converts its operand to boolean and if that value is
+boolean true it returns false and if false it returns true. As the
+result of a NOT operation is a boolean value that is the inverse of
+the type-converted true-ness of its operand, two NOT operations
+together will return a boolean value that is equivalent to the result
+of type-converting the operand to boolean:-
+</p>
+
+<pre id="tcBool_ex1">
+var boolValue = !!x;
+</pre>
+
+<p id="tcBool_2">
+That technique has been used to generate the following tables.
+</p>
+
+<p id="tcBool_3">
+An alternative method of generating a boolean value that represents
+the type-converted true-ness of a value is to pass that value to
+the <code>Boolean</code> constructor called as a function:-
+</p>
+
+<pre id="tcBool_ex2">
+var boolValue = Boolean(x);
+</pre>
+
+<table>
+ <caption>Double NOT (!!col) : Numeric Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="nm">-1.6</th>
+ <th class="nm">-0</th>
+ <th class="nm">+0</th>
+ <th class="nm">1</th>
+ <th class="nm">1.6</th>
+ <th class="nm">8</th>
+ <th class="nm">16</th>
+ <th class="nm">16.8</th>
+ <th class="nm">123e-2</th>
+ <th class="nm">-Infinity</th>
+ <th class="nm">+Infinity</th>
+ <th class="nm">NaN</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>!!col</th>
+ <td class="true">true</td>
+ <td class="false">false</td>
+ <td class="false">false</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="false">false</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcBool_4">
+When numbers are converted to boolean, zero becomes false and all other
+numbers are true. With the excepting of the special numeric value
+<code>NaN</code> (Not a Number) which is used when another type is
+converted to a number but that conversion does not result in a
+meaningful number. <code>NaN</code> is always false. The values of
+positive and negative infinity, while not finite numbers, are non-zero
+numeric values and always type-convert to boolean <code>true</code>.
+</p>
+
+<table>
+ <caption>Double NOT (!!col) : String Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="st">&quot;&quot;<br>(empty<br>string)</th>
+ <th class="st">&quot;-1.6&quot;</th>
+ <th class="st">&quot;0&quot;</th>
+ <th class="st">&quot;1&quot;</th>
+ <th class="st">&quot;1.6&quot;</th>
+ <th class="st">&quot;8&quot;</th>
+ <th class="st">&quot;16&quot;</th>
+ <th class="st">&quot;16.8&quot;</th>
+ <th class="st">&quot;123e-2&quot;</th>
+ <th class="st">&quot;010&quot;<br>(Octal)</th>
+ <th class="st">&quot;0x10&quot;<br>(Hex)</th>
+ <th class="st">&quot;0xFF&quot;<br>(Hex)</th>
+ <th class="st">&quot;-010&quot;</th>
+ <th class="st">&quot;-0x10&quot;</th>
+ <th class="st">&quot;xx&quot;</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>!!col</th>
+ <td class="false">false</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcBool_5">
+Type conversion rules are even simpler for string to boolean conversion
+as all non-empty strings always become true and empty strings become
+false.
+</p>
+
+<table>
+ <caption>Double NOT (!!col) : Other Values</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="un">undefined</th>
+ <th class="ob">null</th>
+ <th class="bl">true</th>
+ <th class="bl">false</th>
+ <th class="ob">new Object()</th>
+ <th class="fn">function(){<br> return;<br>}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>!!col</th>
+ <td class="false">false</td>
+ <td class="false">false</td>
+ <td class="true">true</td>
+ <td class="false">false</td>
+ <td class="true">true</td>
+ <td class="true">true</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcBool_6">
+For the other types, <code>undefined</code> and <code>null</code> are
+converted to false, boolean values are not converted and objects and
+functions are always true.
+</p>
+
+<p id="tcBool_7">
+This is the most valuable aspect of type-converting to boolean as it
+allows a script to distinguish between properties in an environment
+that may be undefined or may refer to an object. Treating an undefined
+(or null) value as if it was an object will produce errors. So when
+there is a doubt (as there usually is where web browsers are concerned)
+then code can avoid generating errors by wrapping the code that wants
+to access an object in an <code>if</code> test. Supplying the suspect
+reference to the object as the expression. The expression will be type
+converted to boolean and result in <code>false</code> if the object
+does not exist and <code>true</code> if it does.
+</p>
+
+<pre id="tcBool_ex3">
+if(document.documentElement){
+ scrollX = document.documentElement.scrollLeft;
+}
+</pre>
+
+<p id="tcBool_8">
+The double NOT operation also allows the setting of boolean flags that
+can be used to indicate the presence of various objects:-
+</p>
+
+<pre id="tcBool_ex4">
+var hasDocEl = !!document.documentElement;
+...
+if(hasDocEl){
+ scrollX = document.documentElement.scrollLeft;
+}
+</pre>
+
+<h2 id="tcString">Converting to String</h2>
+
+<p id="tcString_1">
+As mentioned above, type conversion to a string most often results
+from the action of the + operator whenever one of its operators in
+not a number. The easiest way of getting the string that results
+from type-conversion is to concatenate a value to an empty string.
+That technique has been used to generate the following tables.
+</p>
+
+<p id="tcString_2">
+An alternative method of converting a value into a string is to
+pass it as an argument to the <code>String</code> constructor
+called as a function:-
+</p>
+
+<pre id="tcString_ex1">
+var stringValue = String(x);
+</pre>
+
+<table>
+ <caption>type-convert to string (&quot;&quot; + col) : Numeric Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="nm">-1.6</th>
+ <th class="nm">-0</th>
+ <th class="nm">+0</th>
+ <th class="nm">1</th>
+ <th class="nm">1.6</th>
+ <th class="nm">8</th>
+ <th class="nm">16</th>
+ <th class="nm">16.8</th>
+ <th class="nm">123e-2</th>
+ <th class="nm">-Infinity</th>
+ <th class="nm">+Infinity</th>
+ <th class="nm">NaN</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>&quot;&quot; + col</th>
+ <td class="st">-1.6</td>
+ <td class="st">0</td>
+ <td class="st">0</td>
+ <td class="st">1</td>
+ <td class="st">1.6</td>
+ <td class="st">8</td>
+ <td class="st">16</td>
+ <td class="st">16.8</td>
+ <td class="st">1.23</td>
+ <td class="st">-Infinity</td>
+ <td class="st">Infinity</td>
+ <td class="st">NaN</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcString_3">
+Notice that the number generated from the source code <code>123e-2</code>
+has resulted in the string <code>&quot;1.23&quot;</code> because that is
+the string representation of the internal number created from the source
+code. However, Javascript's internal number representations take the form
+of IEEE double precision floating point numbers and that means that they
+cannot represent all numbers with precision. The results of mathematical
+operations may only produce close approximations and when they are
+converted to strings the string represents the approximation and may be
+unexpected and undesirable. It is often necessary to use custom functions
+to generate string representations of numbers in an acceptable format,
+the type-conversion mechanism is rarely suited to generating numeric output
+intended for presentation.
+</p>
+
+<table>
+ <caption>type-convert to string (&quot;&quot; + col) : Other Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="un">undefined</th>
+ <th class="ob">null</th>
+ <th class="bl">true</th>
+ <th class="bl">false</th>
+ <th class="ob">new Object()</th>
+ <th class="fn">function(){<br> return;<br>}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>&quot;&quot; + col</th>
+ <td class="st">undefined</td>
+ <td class="st">null</td>
+ <td class="st">true</td>
+ <td class="st">false</td>
+ <td class="st">[object Object]</td>
+ <td><pre class="st">function(){
+ return;
+}</pre></td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcString_4">
+When objects or functions are type-converted to strings their
+<code>toString</code> method is called. These default to
+<code>Object.prototype.toString</code> and
+<code>Function.prototype.toString</code> but may be overloaded
+with a function assigned to a &quot;toString&quot; property of
+the object/function. Type-converting a function to a string does
+not necessarily result in the function's source code. The behaviour
+of <code>Function.prototype.toString</code> is implementation
+depended and varies quite a lot, as do the results from
+&quot;host objects&quot; and methods (the objects and methods
+provided by the environment, such as DOM elements).
+</p>
+
+<h2 id="tcNumber">Converting to Number</h2>
+
+<p id="tcNumber_1">
+Converting values to numbers, especially strings to numbers, is an
+extremely common requirement and many methods can be used. Any
+mathematical operator except the concatenation/addition operator
+will force type-conversion. So conversion of a string to a number
+might entail performing a mathematical operation on the string
+representation of the number that would not affect the resulting
+number, such as subtracting zero or multiplying by one.
+</p>
+
+<pre id="tcNumber_ex1">
+var numValue = stringValue - 0;
+<span class="commentJS">/* or */</span>
+var numValue = stringValue * 1;
+<span class="commentJS">/* or */</span>
+var numValue = stringValue / 1;
+</pre>
+
+<p id="tcNumber_2">
+However, the unary <code>+</code> operator also type-converts its
+operand to a number and because it does not do any additional
+mathematical operations it is the fastest method for type-converting
+a string into a number.
+</p>
+
+<p id="tcNumber_2b">
+Incidentally, the unary <code>-</code> (minus) operator also
+type-converts its operand (if necessary) in addition to
+subsequently negating its value.
+</p>
+
+<pre id="tcNumber_ex2">
+var numValue = (+stringValue);
+
+<span class="commentJS">/* The preceding unary + expression has been parenthesised. That is
+ unnecessary but is often felt to make the code easier to comprehend
+ and make it clear which operations are being applied. Especially
+ avoiding confusion with pre and post increment and addition
+ operations. Compare:-
+
+var n = anyNumVar++ + +stringVar + ++anotherNumVar;
+
+ - with -
+
+var n = (anyNumVar++) + (+stringVar) + (++anotherNumVar);
+ ^^ ^ ^^
+ (post increment) + (unary plus) + (pre increment)
+*/</span>
+</pre>
+
+<p id="tcNumber_3">
+While unary <code>+</code> is the fastest method for converting a
+string to a number a final method is available that uses the
+Javascript type-conversion algorithms. The <code>Number</code>
+constructor can be called with the string value as its argument
+and its return value is a number representing the result of the
+type-conversion.
+</p>
+
+<pre id="tcNumber_ex3">
+var numValue = Number(stringValue);
+</pre>
+
+<p id="tcNumber_4">
+The Number constructor is the slowest of the type-converting
+methods but when speed is not an overriding consideration its
+use does produce the clearest source code.
+</p>
+
+<p id="tcNumber_5">
+The following tables show the results of type-conversion to a number using
+the unary <code>+</code> operator. Though all of the preceding
+alternative method produce the same results as they all use exactly the
+same algorithm to do the conversion.
+</p>
+
+<table>
+ <caption>type-convert to number (+col) : String Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="st">&quot;&quot;<br>(empty<br>string)</th>
+ <th class="st">&quot;-1.6&quot;</th>
+ <th class="st">&quot;0&quot;</th>
+ <th class="st">&quot;1&quot;</th>
+ <th class="st">&quot;1.6&quot;</th>
+ <th class="st">&quot;8&quot;</th>
+ <th class="st">&quot;16&quot;</th>
+ <th class="st">&quot;16.8&quot;</th>
+ <th class="st">&quot;123e-2&quot;</th>
+ <th class="st">&quot;010&quot;<br>(Octal)</th>
+ <th class="st">&quot;0x10&quot;<br>(Hex)</th>
+ <th class="st">&quot;0xFF&quot;<br>(Hex)</th>
+ <th class="st">&quot;-010&quot;</th>
+ <th class="st">&quot;-0x10&quot;</th>
+ <th class="st">&quot;xx&quot;</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>+col</th>
+ <td class="nm">0</td>
+ <td class="nm">-1.6</td>
+ <td class="nm">0</td>
+ <td class="nm">1</td>
+ <td class="nm">1.6</td>
+ <td class="nm">8</td>
+ <td class="nm">16</td>
+ <td class="nm">16.8</td>
+ <td class="nm">1.23</td>
+ <td class="nm">10</td>
+ <td class="nm">16</td>
+ <td class="nm">255</td>
+ <td class="nm">-10</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcNumber_6">
+The important considerations when converting strings to numbers with
+the type-converting methods is the results from strings that do not
+represent numbers. The empty string is converted into the number zero,
+depending on the application this can be harmless or disastrous, but
+it is important to be aware that it is going to happen. In other
+contexts strings that follow the Javascript format for octal number
+(leading zero) can be problematic but type conversion treats them
+as base 10 anyway. However, strings that follow the format for
+hexadecimal numbers (leading <code>0x</code> or <code>0X</code>)
+are read as hexadecimal. Strings that cannot be read as a number
+type-convert to <code>NaN</code>, which can be tested for with
+the <code>isNaN</code> function. Strings representing numbers in an
+exponential format (<code>&quot;123e-2&quot;</code>) are understood
+along with leading minus signs.
+</p>
+
+<table>
+ <caption>type-convert to number (+col) : Other Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="un">undefined</th>
+ <th class="ob">null</th>
+ <th class="bl">true</th>
+ <th class="bl">false</th>
+ <th class="ob">new Object()</th>
+ <th class="fn">function(){<br> return;<br>}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>+col</th>
+ <td class="nm">NaN</td>
+ <td class="nm">0</td>
+ <td class="nm">1</td>
+ <td class="nm">0</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcNumber_7">
+Objects and functions always type-convert to <code>NaN</code> numbers, as do
+<code>undefined</code> values but it is worth noting that <code>null</code>
+type-converts to zero. Probably because it is being type-converted to boolean
+first and then to number and, as is clear from the boolean results
+above, <code>null</code> would become boolean <code>false</code> which
+would then become numeric zero. There is almost no need to type convert
+these types of values into numbers. How they convert is only really
+relevant to a consideration of the accidental result of converting a
+value that is expected to be a string but actually turns out to be one
+of these (and/or performing an mathematical operation with one of these as an operand).
+</p>
+
+<h2 id="tcParse">Parsing to Number</h2>
+
+<p id="tcParse_1">
+An alternative method of converting a string into a number is to use
+one of the global functions designed to parse a string and return a
+number. The <code>parseFloat</code> function accepts a string argument
+and returns a floating point number resulting from parsing that string.
+Non-string arguments are first type-converted to a string as described
+above.
+</p>
+
+<p id="tcParse_2">
+The string parsing functions read the string character by character until
+they encounter a character that cannot be part of the number, at which
+point they stop and return a number based on the characters that they
+have seen that can be part of the number. This feature of their action
+can be usefully exploited, for example, given a string representing a
+<span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> length value such as <code>&quot;34.5em&quot;</code>
+<code>parseFloat</code> would be able to ignore the <code>&quot;em&quot;</code>
+because those characters cannot be combined with the preceding set to
+produce a valid number. The returned number would be 34.5, the numeric
+part of the <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> string stripped of its units.
+</p>
+
+<h3 id="tcParseFl">parseFloat</h3>
+
+<table>
+ <caption>parseFloat(col) : String Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="st">&quot;&quot;<br>(empty<br>string)</th>
+ <th class="st">&quot;-1.6&quot;</th>
+ <th class="st">&quot;0&quot;</th>
+ <th class="st">&quot;1&quot;</th>
+ <th class="st">&quot;1.6&quot;</th>
+ <th class="st">&quot;8&quot;</th>
+ <th class="st">&quot;16&quot;</th>
+ <th class="st">&quot;16.8&quot;</th>
+ <th class="st">&quot;123e-2&quot;</th>
+ <th class="st">&quot;010&quot;<br>(Octal)</th>
+ <th class="st">&quot;0x10&quot;<br>(Hex)</th>
+ <th class="st">&quot;0xFF&quot;<br>(Hex)</th>
+ <th class="st">&quot;-010&quot;</th>
+ <th class="st">&quot;-0x10&quot;</th>
+ <th class="st">&quot;xx&quot;</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>parseFloat(col)</th>
+ <td class="nm">NaN</td>
+ <td class="nm">-1.6</td>
+ <td class="nm">0</td>
+ <td class="nm">1</td>
+ <td class="nm">1.6</td>
+ <td class="nm">8</td>
+ <td class="nm">16</td>
+ <td class="nm">16.8</td>
+ <td class="nm">1.23</td>
+ <td class="nm">10</td>
+ <td class="nm">0</td>
+ <td class="nm">0</td>
+ <td class="nm">-10</td>
+ <td class="nm">0</td>
+ <td class="nm">NaN</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcParseFl_1">
+With <code>parseFloat</code> empty strings return <code>NaN </code>
+along with strings that cannot be subject to numeric interpretation.
+The exponential format is understood and the leading zero in the
+octal format does not hinder the string's interpretation as a
+decimal number. Hexadecimal strings are interpreted as the number
+zero because the following <code>&quot;x&quot;</code> cannot be
+interpreted as part of a number so parsing stops after the leading zero.
+</p>
+
+<table>
+ <caption>parseFloat(col) : Other Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="un">undefined</th>
+ <th class="ob">null</th>
+ <th class="bl">true</th>
+ <th class="bl">false</th>
+ <th class="ob">new Object()</th>
+ <th class="fn">function(){<br> return;<br>}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>parseFloat(col)</th>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcParseFl_2">
+Non-string values are first converted into a string that is employed
+by <code>parseFloat</code>. As that type-conversion to a string would
+not normally result in a string that could be interpreted as a number
+the result is <code>NaN</code>. Objects and functions may have custom
+<code>toString</code> methods that may return strings that could be
+interpreted as numbers but that would be an unusual requirement.
+</p>
+
+<h3 id="tcParseIn">parseInt</h3>
+
+<p id="tcParseIn_1">
+The <code>parseInt</code> function works in a similar way to
+<code>parseFloat</code> except that it is trying to interpret its
+string argument into an integer and as a result recognises fewer
+character as possible candidates to be part of that number.
+</p>
+
+<p id="tcParseIn_2">
+<code>parseInt</code> is occasionally used as a means of turning a
+floating point number into an integer. It is very ill suited to that
+task because if its argument is of numeric type it will first be
+converted into a string and then parsed as a number, very inefficient.
+This can produce very wrong results with numbers such as
+<code>2e-200</code>, for which the next smaller integer is zero, but
+with which <code>parseInt</code> returns <code>2</code>. Also, because
+of the number format used by javascript, numbers are often represented
+by near approximations. So, for example, 1/2 + 1/3 + 1/6 =
+0.9999999999999999, which isn't quite one and parseInt would return
+zero if asked to act on the result of the operation.
+</p>
+
+<p id="tcParseIn_3">
+For rounding
+numbers to integers one of <code>Math.round</code>, <code>Math.ceil</code>
+and <code>Math.floor</code> are preferable, and for a desired result
+that can be expressed as a 32 bit signed integer the bitwise operation
+described below might also suit.
+</p>
+
+<table>
+ <caption>parseInt(col) : Numeric Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="nm">-1.6</th>
+ <th class="nm">-0</th>
+ <th class="nm">+0</th>
+ <th class="nm">1</th>
+ <th class="nm">1.6</th>
+ <th class="nm">8</th>
+ <th class="nm">16</th>
+ <th class="nm">16.8</th>
+ <th class="nm">123e-2</th>
+ <th class="nm">-Infinity</th>
+ <th class="nm">+Infinity</th>
+ <th class="nm">NaN</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>parseInt(col)</th>
+ <td class="nm">-1</td>
+ <td class="nm">0</td>
+ <td class="nm">0</td>
+ <td class="nm">1</td>
+ <td class="nm">1</td>
+ <td class="nm">8</td>
+ <td class="nm">16</td>
+ <td class="nm">16</td>
+ <td class="nm">1</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcParseIn_4">
+When it is acting on number the effect of the initial type-conversion
+of the argument to a string is evident in the results. Note that the
+value <code>123e-2</code> is internally the number <code>1.23</code>
+and that type converts into the string <code>&quot;1.23&quot;</code>,
+so that entry in the table above might look odd but it is correct.
+</p>
+
+<table>
+ <caption>parseInt(col) : String Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="st">&quot;&quot;<br>(empty<br>string)</th>
+ <th class="st">&quot;-1.6&quot;</th>
+ <th class="st">&quot;0&quot;</th>
+ <th class="st">&quot;1&quot;</th>
+ <th class="st">&quot;1.6&quot;</th>
+ <th class="st">&quot;8&quot;</th>
+ <th class="st">&quot;16&quot;</th>
+ <th class="st">&quot;16.8&quot;</th>
+ <th class="st">&quot;123e-2&quot;</th>
+ <th class="st">&quot;010&quot;<br>(Octal)</th>
+ <th class="st">&quot;0x10&quot;<br>(Hex)</th>
+ <th class="st">&quot;0xFF&quot;<br>(Hex)</th>
+ <th class="st">&quot;-010&quot;</th>
+ <th class="st">&quot;-0x10&quot;</th>
+ <th class="st">&quot;xx&quot;</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>parseInt(col)</th>
+ <td class="nm">NaN</td>
+ <td class="nm">-1</td>
+ <td class="nm">0</td>
+ <td class="nm">1</td>
+ <td class="nm">1</td>
+ <td class="nm">8</td>
+ <td class="nm">16</td>
+ <td class="nm">16</td>
+ <td class="nm">123</td>
+ <td class="nm">8</td>
+ <td class="nm">16</td>
+ <td class="nm">255</td>
+ <td class="nm">-8</td>
+ <td class="nm">-16</td>
+ <td class="nm">NaN</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcParseIn_5">
+Strings in octal and hexadecimal number formats do represent integers
+and <code>parseInt</code> is capable of interpreting them in accordance
+with the rules for Javascript source code, even when they have leading
+minus signs.
+</p>
+
+<table>
+ <caption>parseInt(col) : Other Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="un">undefined</th>
+ <th class="ob">null</th>
+ <th class="bl">true</th>
+ <th class="bl">false</th>
+ <th class="ob">new Object()</th>
+ <th class="fn">function(){<br> return;<br>}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>parseInt(col)</th>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcParseIn_6">
+As <code>parseInt</code> type-converts its non-string arguments to
+strings it always produces the same results for <code>boolean</code>,
+<code>null</code>, <code>undefined</code>, object and function
+arguments as <code>parseFloat</code> (assuming objects and functions
+do not have custom <code>toString</code> methods).
+</p>
+
+<h3 id="tcPrIntRx">parseInt with a radix argument</h3>
+
+<p id="tcPrIntRx_1">
+It is rarely desirable to allow <code>parseInt</code> to deduce the
+base in which the number is represented from the string as leading zeros are
+rarely intended to indicate data in octal format (particularly with
+user input). To deal with this problem <code>parseInt</code> recognises
+a second, radix, argument that can be used to specify the base in which the
+string is to be interpreted. Specifying a second argument of 10 causes
+<code>parseInt</code> to interpret the strings as only base 10.
+</p>
+
+<table>
+ <caption>parseInt(col, 10) : String Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="st">&quot;&quot;<br>(empty<br>string)</th>
+ <th class="st">&quot;-1.6&quot;</th>
+ <th class="st">&quot;0&quot;</th>
+ <th class="st">&quot;1&quot;</th>
+ <th class="st">&quot;1.6&quot;</th>
+ <th class="st">&quot;8&quot;</th>
+ <th class="st">&quot;16&quot;</th>
+ <th class="st">&quot;16.8&quot;</th>
+ <th class="st">&quot;123e-2&quot;</th>
+ <th class="st">&quot;010&quot;<br>(Octal)</th>
+ <th class="st">&quot;0x10&quot;<br>(Hex)</th>
+ <th class="st">&quot;0xFF&quot;<br>(Hex)</th>
+ <th class="st">&quot;-010&quot;</th>
+ <th class="st">&quot;-0x10&quot;</th>
+ <th class="st">&quot;xx&quot;</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>parseInt(col, 10)</th>
+ <td class="nm">NaN</td>
+ <td class="nm">-1</td>
+ <td class="nm">0</td>
+ <td class="nm">1</td>
+ <td class="nm">1</td>
+ <td class="nm">8</td>
+ <td class="nm">16</td>
+ <td class="nm">16</td>
+ <td class="nm">123</td>
+ <td class="nm">10</td>
+ <td class="nm">0</td>
+ <td class="nm">0</td>
+ <td class="nm">-10</td>
+ <td class="nm">0</td>
+ <td class="nm">NaN</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcPrIntRx_2">
+The string in octal format is now interpreted as base 10 and the
+hexadecimal strings can now only be zero as parsing has to stop
+when the <code>&quot;x&quot;</code> is encountered.
+</p>
+
+<p id="tcPrIntRx_3">
+Number bases 2 to 36 can be used with <code>parseInt</code>. The
+following is base 16.
+</p>
+
+<table>
+ <caption>parseInt(col, 16) : String Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="st">&quot;&quot;<br>(empty<br>string)</th>
+ <th class="st">&quot;-1.6&quot;</th>
+ <th class="st">&quot;0&quot;</th>
+ <th class="st">&quot;1&quot;</th>
+ <th class="st">&quot;1.6&quot;</th>
+ <th class="st">&quot;8&quot;</th>
+ <th class="st">&quot;16&quot;</th>
+ <th class="st">&quot;16.8&quot;</th>
+ <th class="st">&quot;123e-2&quot;</th>
+ <th class="st">&quot;010&quot;<br>(Octal)</th>
+ <th class="st">&quot;0x10&quot;<br>(Hex)</th>
+ <th class="st">&quot;0xFF&quot;<br>(Hex)</th>
+ <th class="st">&quot;-010&quot;</th>
+ <th class="st">&quot;-0x10&quot;</th>
+ <th class="st">&quot;xx&quot;</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>parseInt(col, 16)</th>
+ <td class="nm">NaN</td>
+ <td class="nm">-1</td>
+ <td class="nm">0</td>
+ <td class="nm">1</td>
+ <td class="nm">1</td>
+ <td class="nm">8</td>
+ <td class="nm">22</td>
+ <td class="nm">22</td>
+ <td class="nm">4670</td>
+ <td class="nm">16</td>
+ <td class="nm">16</td>
+ <td class="nm">255</td>
+ <td class="nm">-16</td>
+ <td class="nm">-16</td>
+ <td class="nm">NaN</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcPrIntRx_4">
+The hexadecimal <code>0x</code> format is recognised again with the
+base 16 interpretation.
+</p>
+
+<p id="tcPrIntRx_5">
+Finally base 3:-
+</p>
+
+<table>
+ <caption>parseInt(col, 3) : Numeric Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="nm">-1.6</th>
+ <th class="nm">-0</th>
+ <th class="nm">+0</th>
+ <th class="nm">1</th>
+ <th class="nm">1.6</th>
+ <th class="nm">8</th>
+ <th class="nm">16</th>
+ <th class="nm">16.8</th>
+ <th class="nm">123e-2</th>
+ <th class="nm">-Infinity</th>
+ <th class="nm">+Infinity</th>
+ <th class="nm">NaN</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>parseInt(col, 3)</th>
+ <td class="nm">-1</td>
+ <td class="nm">0</td>
+ <td class="nm">0</td>
+ <td class="nm">1</td>
+ <td class="nm">1</td>
+ <td class="nm">NaN</td>
+ <td class="nm">1</td>
+ <td class="nm">1</td>
+ <td class="nm">1</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ <td class="nm">NaN</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcPrIntRx_6">
+The consequences of the type-converting of numeric arguments to
+strings is evident again. The number <code>8</code> is coming out
+as <code>NaN</code> because the <code>&quot;8&quot;</code> character
+cannot be interpreted as base 3, leaving an empty sequence of
+acceptable characters and producing the same result as an empty string.
+</p>
+
+<table>
+ <caption>parseInt(col, 3) : String Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="st">&quot;&quot;<br>(empty<br>string)</th>
+ <th class="st">&quot;-1.6&quot;</th>
+ <th class="st">&quot;0&quot;</th>
+ <th class="st">&quot;1&quot;</th>
+ <th class="st">&quot;1.6&quot;</th>
+ <th class="st">&quot;8&quot;</th>
+ <th class="st">&quot;16&quot;</th>
+ <th class="st">&quot;16.8&quot;</th>
+ <th class="st">&quot;123e-2&quot;</th>
+ <th class="st">&quot;010&quot;<br>(Octal)</th>
+ <th class="st">&quot;0x10&quot;<br>(Hex)</th>
+ <th class="st">&quot;0xFF&quot;<br>(Hex)</th>
+ <th class="st">&quot;-010&quot;</th>
+ <th class="st">&quot;-0x10&quot;</th>
+ <th class="st">&quot;xx&quot;</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>parseInt(col, 3)</th>
+ <td class="nm">NaN</td>
+ <td class="nm">-1</td>
+ <td class="nm">0</td>
+ <td class="nm">1</td>
+ <td class="nm">1</td>
+ <td class="nm">NaN</td>
+ <td class="nm">1</td>
+ <td class="nm">1</td>
+ <td class="nm">5</td>
+ <td class="nm">3</td>
+ <td class="nm">0</td>
+ <td class="nm">0</td>
+ <td class="nm">-3</td>
+ <td class="nm">0</td>
+ <td class="nm">NaN</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="tcToInt32">ToInt32</h2>
+
+<p id="tcToInt32_1">
+<code>ToInt32</code> is an <em>internal</em> function only available to the
+Javascript implementation and cannot be called directly from scripts
+in the way that <code>parseInt</code> can. It is a bit unusual to mention it in
+connection with converting Javascript values to numbers but it can
+be used in a limited set of circumstances. The bitwise operators such
+as bitwise OR (<code>|</code>) and bitwise AND (<code>&</code>) operate on
+numbers so they type-convert their operands to numbers. However, they
+also only operate on 32 bit signed integers so given the (possibly
+type-converted) numeric value they call the <em>internal</em>
+<code>ToInt32</code> function with that number as its argument and
+use the returned value as their operand. That returned value is always
+a 32 bit signed integer.
+</p>
+
+<p id="tcToInt32_2">
+The effect can be like <code>parseInt</code> combined with type-converting
+to numbers. While the result is limited in range to 32 bits, it is
+<em>always</em> numeric and never <code>NaN</code>, or &plusmn;
+<code>Infinity</code>.
+</p>
+
+<p id="tcToInt32_3">
+As with using mathematical operators in operations that have no effect on
+the value of any resulting number it is possible to perform a bitwise
+operation that will not affect the value returned from the call to
+<code>ToInt32</code>. The tables below were generated using a bitwise
+OR zero operation.
+</p>
+
+<table>
+ <caption> ToInt32 (col|0) : Numeric Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="nm">-1.6</th>
+ <th class="nm">-0</th>
+ <th class="nm">+0</th>
+ <th class="nm">1</th>
+ <th class="nm">1.6</th>
+ <th class="nm">8</th>
+ <th class="nm">16</th>
+ <th class="nm">16.8</th>
+ <th class="nm">123e-2</th>
+ <th class="nm">-Infinity</th>
+ <th class="nm">+Infinity</th>
+ <th class="nm">NaN</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>col|0</th>
+ <td class="nm">-1</td>
+ <td class="nm">0</td>
+ <td class="nm">0</td>
+ <td class="nm">1</td>
+ <td class="nm">1</td>
+ <td class="nm">8</td>
+ <td class="nm">16</td>
+ <td class="nm">16</td>
+ <td class="nm">1</td>
+ <td class="nm">0</td>
+ <td class="nm">0</td>
+ <td class="nm">0</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcToInt32_4">
+<code>NaN</code> and &plusmn;<code>Infinity</code> become zero and
+floating point values are <em>truncated</em> to integers.
+</p>
+
+<table>
+ <caption> ToInt32 (col|0) : String Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="st">&quot;&quot;<br>(empty<br>string)</th>
+ <th class="st">&quot;-1.6&quot;</th>
+ <th class="st">&quot;0&quot;</th>
+ <th class="st">&quot;1&quot;</th>
+ <th class="st">&quot;1.6&quot;</th>
+ <th class="st">&quot;8&quot;</th>
+ <th class="st">&quot;16&quot;</th>
+ <th class="st">&quot;16.8&quot;</th>
+ <th class="st">&quot;123e-2&quot;</th>
+ <th class="st">&quot;010&quot;<br>(Octal)</th>
+ <th class="st">&quot;0x10&quot;<br>(Hex)</th>
+ <th class="st">&quot;0xFF&quot;<br>(Hex)</th>
+ <th class="st">&quot;-010&quot;</th>
+ <th class="st">&quot;-0x10&quot;</th>
+ <th class="st">&quot;xx&quot;</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>col|0</th>
+ <td class="nm">0</td>
+ <td class="nm">-1</td>
+ <td class="nm">0</td>
+ <td class="nm">1</td>
+ <td class="nm">1</td>
+ <td class="nm">8</td>
+ <td class="nm">16</td>
+ <td class="nm">16</td>
+ <td class="nm">1</td>
+ <td class="nm">10</td>
+ <td class="nm">16</td>
+ <td class="nm">255</td>
+ <td class="nm">-10</td>
+ <td class="nm">0</td>
+ <td class="nm">0</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcToInt32_5">
+String values that would type-convert to <code>NaN</code> are returned
+as zero from <code>ToInt32</code>.
+</p>
+
+<table>
+ <caption> ToInt32 (col|0) : Other Values.</caption>
+ <thead>
+ <tr>
+ <th></th>
+ <th class="un">undefined</th>
+ <th class="ob">null</th>
+ <th class="bl">true</th>
+ <th class="bl">false</th>
+ <th class="ob">new Object()</th>
+ <th class="fn">function(){<br> return;<br>}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>col|0</th>
+ <td class="nm">0</td>
+ <td class="nm">0</td>
+ <td class="nm">1</td>
+ <td class="nm">0</td>
+ <td class="nm">0</td>
+ <td class="nm">0</td>
+ </tr>
+ </tbody>
+</table>
+
+<p id="tcToInt32_6">
+Even <code>undefined</code>, objects and functions are converted to zero value
+numbers by this operation. Note though that boolean <code>true</code> is
+converted to the number 1.
+</p>
+
+
+<h2 id="tcUserIn">Converting User Input</h2>
+
+<p id="tcUserIn_1">
+Most of the mechanisms for getting input from the user,
+<code>&lt;input type=&quot;text&quot;&gt;</code> and
+<code>prompt</code> for example, provide their results in the form
+of strings. If the user is expected to input a number they still
+might enter anything (at the least they may just make a typo). If
+the string needs to be converted into a number for later operations
+one of the methods mentioned above can be chosen based on what best
+suits the nature of the input expected but some of the results
+generated with erroneous input may be difficult to detect and handle.
+</p>
+
+<p id="tcUserIn_2">
+Prior to converting a string to a number it may be advantageous
+to use a Regular Expression to test the contents of the string
+to ensure that they conform to an acceptable format. That would
+serve to eliminate some of the string values that may otherwise
+suffer from the quirks of the string to number converting
+processes when applied to unexpected string values.
+</p>
+
+
+<h3 id="tcRegEx">Regular expression examples</h3>
+
+<pre id="tcRegExEm">
+/^\d+$/ <span class="commentJS">//All-digit</span>
+/^\s*[-+]?\d+\s*$/ <span class="commentJS">//Unbroken Signed integer &amp; spaces</span>
+/^\d{1,5}$/ <span class="commentJS">//1 to 5 digits</span>
+/^\d+\.\d\d$/ <span class="commentJS">//Money</span>
+/^\d+(\.\d{2})$/ <span class="commentJS">//Money</span>
+/^\d{1,3}(,\d\d\d)*\.\d\d$/ <span class="commentJS">//comma-separated money - 12,432.57</span>
+
+ <span class="commentJS">// optional comma-separated money - 12,432.57 or 12432.57</span>
+/^\d{1,3}(,\d\d\d)*\.\d\d$|^\d+\.\d\d$/
+
+</pre>
+</body>
+</html>
/trunk/cljs/notes/type-conversion/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/notes/detect-browser/index.html
===================================================================
--- trunk/cljs/notes/detect-browser/index.html (nonexistent)
+++ trunk/cljs/notes/detect-browser/index.html (revision 45)
@@ -0,0 +1,1413 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+<title>Browser Detection (and What to Do Instead)</title>
+<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<link href="../../faq.css" rel="stylesheet" type="text/css">
+<link href="../notes.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+.tip {
+ border: 1px solid #ccc;
+ padding: 1ex;
+ background: #fcfcfc;
+ font-size: 90%;
+}
+</style>
+</head>
+<body>
+<h1 id="bdTop">Browser Detection (and What to Do Instead)</h1>
+<div id="faqNav">
+ <a href="../../">FAQ</a> &gt; <a href="../">FAQ Notes</a>
+</div>
+<p>
+By Richard Cornford, edited by Garrett Smith
+</p>
+<ul>
+ <li><a href="#bdIntro">Introduction</a></li>
+ <li><a href="#bdValid">Avoiding Structural Differences in the Browser DOMs</a></li>
+ <li><a href="#bdDif">Browsers Differences</a></li>
+ <li><a href="#bdFailS">Failed Strategies: Browser Detecting</a>
+ <ul>
+ <li><a href="#bdUAS">Assumptions Based on navigator.userAgent</a></li>
+ <li><a href="#bdOI">Assumptions Based on DOM Objects: Object inference</a></li>
+ </ul>
+ </li>
+ <li><a href="#bdFD">A Strategy That Works: Object/Feature Detecting.</a>
+ <ul>
+ <li><a href="#bdGEID">Example 1: IDed Element Retrieval</a></li>
+ <li><a href="#bdScroll">Example 2: Scroll Values</a></li>
+ <li><a href="#bdReplace">Example 3: String.prototype.replace</a></li>
+ </ul>
+ </li>
+ <li><a href="#bdDesPb">The Javascript Design Problem</a></li>
+
+</ul>
+
+<h2 id="bdIntro">Introduction</h2>
+
+<p id="bdIntro_1">
+Under normal circumstances computer programs are written for a known
+environment. The programmer knows what to expect; which APIs will be
+available, how they will behave and so on. Java is an ideal example
+of this, providing a theoretically consistent set of APIs and language
+features across all Java Virtual Machine (JVM) implementations. But
+this is also true in most other circumstances. The programmer of C++
+for the Windows operating system will know what MFC classes are
+available and how to program them. Their expectations will be
+rewarded, if they posses the required knowledge.
+</p>
+
+<p id="bdIntro_2">
+Client side javascript for the Internet, on the other hand, has the
+possibly unique problem of having to be authored with no specific
+knowledge of the environment in which it will be executed. The
+client side environment will usually be a web browser and web
+browsers do tend to have many common features (and increasingly
+standardised features) but the author cannot know which version of
+which browser will be making any HTTP request (or
+whether it is a browser at all). It is not even possible to tell in
+advance whether the User Agent will be capable of executing
+javascript; all of those that can include a user configurable option
+to disable it anyway.
+</p>
+
+<p id="bdIntro_3">
+Javascript authors for the Internet must realise that they are dealing
+with the unknown and that any, and all, scripts will fail to execute
+somewhere. The challenge is to get the most from your javascript when
+it is available but to cope with their failure in a meaningful way.
+</p>
+
+<p id="bdIntro_4">
+I once read a description of a variant on the game of chess, played
+at military academies. Two players sit at separate boards set up with
+only their own pieces, out of sight of each other, and a referee
+supervises the game. Each player makes their move in turn and the
+referee is responsible for informing them how the other's move impacts
+on their own pieces and how the other's disposition of pieces impact
+on their intended move. The player is informed only when one of their
+own pieces is taken, when one of their moves is affected by
+interacting with one of their opponents pieces (i.e. a player may want
+to move a bishop across the board but the referee may inform them that
+their move was stopped four squares early when the bishop took a pawn
+from the other side) and when one of their opponents pieces is
+sitting on a square adjacent to one of their own.
+</p>
+
+<p id="bdIntro_5">
+The game is used to teach battlefield strategy. To win a player must
+probe and test to deduce his opponent's disposition, while planing and
+executing a response that will achieve the desired checkmate. It is
+this sort of strategy that needs to be added to the normal programming
+problems in order that javascript may cope with its unknown execution
+environment, with the significant difference that the strategy, its
+tests and all of the paths of execution must be fully planed out before
+the code can even starts executing.
+</p>
+
+<h2 id="bdValid">Avoiding Structural Differences in the Browser DOMs</h2>
+
+<p id="bdValid_1">
+While the point of this article is to introduce techniques for handling
+the differences between web browsers and their DOM implementations it
+is also possible to avoid some types of differences especially related
+to the structure of the DOM that is being scripted.
+</p>
+
+<p id="bdValid_2">
+If I was asked to recommend one action most likely to promote the
+authoring of cross-browser scripts it would be: <strong><em>Start
+from a basis of valid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language"
+>HTML</abbr></span></em></strong>.</p>
+
+<p id="bdValid_3">
+Browsers presented with invalid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> will usually attempt to error
+correct it in order to do the best possible job of displaying it.
+Some browsers, particularly IE, are tolerant of all sorts of strange
+formulations of mark-up. Valid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> has a tree-like structure, elements
+may completely contain others but they cannot overlap, and there are
+rules about which elements may appear in which contexts. The DOM that
+is to be scripted also has a tree-like structure and there is a very
+simple relationship between the tree-like structure of valid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> and
+the DOM constructed from it. So any browser presented with valid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>
+will be able to directly translate that <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> into a corresponding DOM
+using well specified rules, resulting in a DOM that is of predictable
+and consistent structure on all of the browsers that can build a DOM.
+</p>
+
+<p id="bdValid_4">
+Invalid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> will not translate as naturally into a DOM, or even a
+tree-like structure. If the browser is going to build a DOM with the
+source provided it is going to have to apply error correcting rules
+and attempt to build the best DOM it can. But the error correcting
+rules are not standardised, not even published. So different browsers
+have no choice but apply different rules and that directly results in
+the building of DOMs with different (and in extremes, radically
+different) structures.
+</p>
+
+<p id="bdValid_5">
+As a result, using invalid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> directly produces differences in the
+DOMs produced by different browsers. No matter how good the application
+of techniques for dealing with the differences between browsers, it
+does not make sense to do anything that will provoke more differences
+than are unavoidable.
+</p>
+
+<p id="bdValid_6">
+The authoring of invalid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>, justified because &quot;It works in
+browser XYZ&quot;, gives the authors of accompanying scripts the
+impression that cross-browser scripting is harder than it is. If they
+had started with valid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> they would never have encountered any of
+the structural inconsistencies that invalid <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> can provoke.
+</p>
+
+<h2 id="bdDif">Browsers Differences</h2>
+
+<p id="bdDif_1">
+As browsers have evolved they have offered more features to javascript.
+Different manufactures have adopted the features of other browsers,
+while adding new features, that may in turn have been adopted by (or
+will be adopted by) their competitors. Various sets of common features
+have emerged and some have been formalised by the W3C into a sequence
+of standard DOM specifications. Along the way an increasing number of
+javascript capable browsers have emerged. In addition to desktop PC
+browsers, javascript capable browsers exist for a whole range of
+devices; PDAs, mobile telephones (Microwave ovens, refrigerators).
+</p>
+
+<p id="bdDif_2">
+Unfortunately it is the case that the browsers on the smaller devices
+cannot offer the range of features available to a desktop PC and even
+as the technology improves and features are added to the smaller
+browsers the problem will not improve as browsers will become available
+on a wider range of devices while the desktop PC browsers will continue
+to march ahead of them.
+</p>
+
+<p id="bdDif_3">
+Over the years various strategies have been attempted to tackle this
+problem and some have failed miserably.
+</p>
+
+<h2 id="bdFailS">Failed Strategies: Browser Detecting</h2>
+
+<h3 id="bdUAS">Assumptions Based on navigator.userAgent</h3>
+
+<p id="bdUAS_1">
+One of the most popular strategies for handling the differences between
+web browsers was browser detecting based on the User Agent string.
+Browsers possessing a <code>navigator</code> object also provide a
+property of that object: <code>navigator.userAgent</code> containing a
+string that (in theory) identifies the browser. Its application went
+something like:-
+</p>
+
+<pre id="bdUAS_ex1">
+<span class="commentJS">/* Warning: never use this script, or any script based on, or resembling, it.
+*/</span>
+var userAgent = self.navigator.userAgent;
+var appName = self.navigator.appName;
+var isOpera = false;
+var isOpera5 = false;
+var isOpera6p = false;
+var isIE = false;
+var isIE4 = false;
+var isIE5p = false;
+var isMozilla1p = false;
+var isNet4 = false;
+var isNet5p = false;
+var operaVersion = 0;
+var ieVersion = 0;
+var appVersion = self.navigator.appVersion;
+var brSet = false;
+
+function brSetup(){
+ for(var c = 3;c &lt; appVersion.length;c++){
+ var chr = appVersion.charAt(c);
+ if(isNaN(chr)){
+ appVersion = appVersion.substring(0, c);
+ break;
+ }
+ }
+ if((userAgent.indexOf('webtv') &lt; 0) &amp;&amp;
+ (userAgent.indexOf('hotjava') &lt; 0)){
+ if(userAgent.indexOf('Opera') &gt;= 0){
+ var ind = (userAgent.indexOf('Opera')+6);
+ if(((ind+1) &lt; userAgent.length)&amp;&amp;(ind &gt;= 6)){
+ isOpera = true;
+ var bsVersion = parseInt(userAgent.substring(ind, ind+1));
+ if(!isNaN(bsVersion)){
+ operaVersion = bsVersion;
+ if(operaVersion &gt;= 6){
+ isOpera6p = true;
+ }else if(operaVersion &gt;= 5){
+ isOpera5 = true;
+ }
+ }
+ }
+ }else if(appName.indexOf('Microsoft Internet Explorer') &gt;= 0){
+ var ind = (userAgent.indexOf('MSIE')+5);
+ if(((ind+1) &lt; userAgent.length)&amp;&amp;(ind &gt;= 5)){
+ isIE = true;
+ var bsVersion = parseInt(userAgent.substring(ind, ind+1));
+ if(!isNaN(bsVersion)){
+ ieVersion = bsVersion;
+ if(ieVersion &gt;= 5){
+ isIE5p = true;
+ }else if(ieVersion &gt;= 4){
+ isIE4 = true;
+ }
+ }
+ }
+ }else if(appName.indexOf('Netscape') &gt;= 0){
+ if((self.navigator.vendor)&amp;&amp;
+ (self.navigator.vendor.indexOf('Netscape') &gt;= 0)&amp;&amp;
+ (userAgent.indexOf('Gecko') &gt;= 0)){
+ isNet5p = true;
+ }else if((userAgent.indexOf('Netscape') &lt; 0)&amp;&amp;
+ (userAgent.indexOf('Gecko') &gt;= 0)&amp;&amp;
+ (appVersion &gt;= 5)){
+ isMozilla1p = true;
+ }else if((appVersion &lt; 5)&amp;&amp;
+ (userAgent.indexOf('compatible') &lt; 0)){
+ isNet4 = true;
+ }
+ }
+ }
+ brSet = true;
+}
+</pre>
+
+<p id="bdUAS_2">
+This version also uses some other properties of the
+<code>navigator</code> object; <code>appName</code> and
+<code>appVersion</code>.
+</p>
+
+<p id="bdUAS_3">
+Superficially this type of script seems to be saying quite a lot about
+what browser is executing the script. Knowing that the
+<code>isIE5p</code> variable is boolean <code>true</code> seems to be
+a reasonable indicator that the browser in question is Internet
+Explorer Version 5 or above and from that all of the available features
+on the IE 5+ DOM could be assumed to exist.
+</p>
+
+<p id="bdUAS_4">
+Unfortunately, if this type of script ever was an effective determiner
+of the browser type, it is not now. The first problem is that you cannot
+write this type of script to take into account all web browsers. The
+script above is only interested in Internet Explorer, Netscape and
+(some) Mozilla derived browsers and Opera. Any other browser will not
+be identified, and that will include a number of W3C DOM conforming
+fully dynamic visual browsers quite capable of delivering on even quite
+demanding code.
+</p>
+
+<p id="bdUAS_5">
+The second problem is that scripts like this one, and server-side
+counter-parts (reading the HTTP User Agent header) were used to
+<em>exclude</em> browsers that did not fall into a set of browsers
+known to the author, regardless of whether those browsers were
+capable of displaying the offending site or not.
+</p>
+
+<p id="bdUAS_6">
+As more browsers were written, their authors discovered that if they
+honestly reported their type and version in their User Agent string
+they would likely be excluded from sites that they would
+otherwise be quite capable of displaying. To get around this problem
+browsers began spoofing the more popular versions, sending HTTP User
+Agent headers, and reporting <code>navigator.userAgent</code> strings,
+that were indistinguishable from, say, IE.
+</p>
+
+<p id="bdUAS_7">
+As a result, when the above script reports <code>isIE5p</code> as true, it is
+possible that the browser that is executing the script is one of
+numerous current browsers. Many of those browsers support sufficient
+features found on IE5+ to allow most scripts to execute but the
+trueness of <code>isIE5p</code> is not a valid indicator that the
+browser will support <em>all</em> of the IE 5+ DOM.
+</p>
+
+<p id="bdUAS_8">
+Now you might decide that a browser that lies about its identity
+deserves what it gets (though they started lying in order to make
+themselves usable in the face of near-sighted <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> and script authors)
+but is worth bearing in mind that the IE 5
+<code>navigator.userAgent</code> string is:
+<code>&quot;Mozilla/4.0 (compatible; MSIE 5.01; Windows NT)&quot;</code>.
+IE 5 is in fact spoofing Netscape 4, and Microsoft started to do that
+for precisely the same reasons that motivate many current browsers to
+send User Agent headers, and report <code>navigator.userAgent</code>
+strings that are indistinguishable form those of Microsoft browsers.
+</p>
+
+<p id="bdUAS_9">
+No browser manufacture wants (or ever has wanted) their browser to be
+needlessly excluded from displaying a web site that it is perfectly
+capable of handling just because the author of that site does not
+know it by name. And to prevent that they have followed Microsoft and
+taken action that has rendered the <code>userAgent</code> string (and
+the HTTP User Agent header) meaningless.
+</p>
+
+<p id="bdUAS_10">
+We are now at a point where the contents of the User Agent strings
+bear no relationship at all to the capabilities and features of the
+browser that is reporting it. The situation has gone so far that a
+number of javascript experts have stated that a standard quality test
+for an unknown script would include searching the source code of the
+script for the string <code>&quot;userAgent&quot;</code> and dismissing
+the script out of hand if that string is found.
+</p>
+
+<h3 id="bdOI">Assumptions Based on DOM Objects: Object inference</h3>
+
+<p id="bdOI_1">
+A second browser detecting strategy uses the objects present in various
+browser DOMs and make the assumption that the presence (or absence) of
+one or more objects indicates that a browser is a particular type or
+version. I quickly found this example of typical code of this type:-
+</p>
+
+<pre id="bdOI_ex1">
+<span class="commentJS">/* Warning: never use this script, or any script based on, or resembling, it.
+*/</span>
+var isDOM=(document.getElementById)?true:false;
+var isIE4=(document.all&amp;&amp;!isDOM)?true:false;
+var isIE5p=(document.all&amp;&amp;isDOM)?true:false;
+var isIE=(document.all)?true:false;
+var isOP=(window.opera)?true:false;
+var isNS4=(document.layers)?true:false;
+</pre>
+
+<p id="bdOI_2">
+Javascript performs automatic type conversion so when a boolean result
+is expected from an expression that evaluates to a non-boolean value
+that non-boolean value is (internally) converted to a boolean value
+(using the rules defined in the ECMAScript specification) and that
+boolean is used as the result.
+</p>
+
+<p id="bdOI_3">
+Take the first line:-
+</p>
+
+<pre id="bdOI_ex2">
+var isDOM=(document.getElementById)?true:false;
+</pre>
+
+<p id="bdOI_4">
+The conditional expression requires that the expression preceding the <code>?</code>
+have a boolean result. The <code>document.getElementById</code>
+property accessor can resolve as one of two values depending on whether
+the <code>getElementById</code> function is supported in the browser in
+question. If it is supported then the accessor resolves as a function
+object, and is type converted to boolean <code>true</code>. If
+<code>getElementById</code> is not supported the accessor resolves as
+undefined, and undefined type converts to boolean
+<code>false</code>. Thus the expression preceding the question mark
+resolves as <code>true</code> or <code>false</code> and based on that
+result <code>true</code> or <code>false</code> are assigned to the
+variable <code>isDOM</code>.
+</p>
+
+<div class="tip">
+ <h4>Boolean Conversion Tip: !!</h4>
+ <p id="bdOI_5">
+ Incidentally, this code is not the optimum method of assigning a boolean
+ value based on the type converted to boolean result of a property accessor.
+ It is better to use the javascript NOT operator ( <code>!</code> ) twice
+ or to pass the object reference as the argument to the <code>Boolean</code>
+ constructor called as a function. The not operator will type convert its
+ operand to boolean and then invert it so <code>false</code> becomes
+ <code>true</code> and <code>true</code> becomes <code>false</code>.
+ Passing that result as the operand for a second not operator inverts
+ the boolean again so a reference to a function object results in boolean
+ <code>true</code> and an undefined reference results in boolean
+ <code>false</code>. The <code>Boolean</code> constructor called as a
+ function converts its argument to boolean and returns that value. The
+ statement would become:-
+ </p>
+
+ <pre id="bdOI_ex3">
+ var isDOM = !!document.getElementById;
+
+ <span class="commentJS">/* - or - */</span>
+
+ var isDOM = Boolean(document.getElementById);
+ </pre>
+
+ <p id="bdOI_6">
+ Which is shorter and faster than the original version and certainly
+ more direct.
+ </p>
+</div>
+
+<h4>Inductive Generalization Fallacy</h4>
+<p id="bdOI_7">
+The problem with this type of browser detecting script is that it is
+used to make assumptions about the browser's capabilities that are
+rarely valid. For example, this <code>isDOM</code> result, based on
+the browser's support for <code>document.getElementById</code>, is
+often used as the basis for the assumption that the browser has a
+fully dynamic DOM with methods such as
+<code>document.createElement</code>, <code>replaceChild</code> and
+<code>appendChild</code>. Browsers do not live up to that expectation,
+some are not that dynamic and while they may implement some of the Core
+DOM level 1 methods such as <code>getElementById</code> They do not
+necessarily implement large parts of the various DOM standards,
+including all of the dynamic <code>Node</code> manipulation methods.
+</p>
+
+<p id="bdOI_8">
+The result of the <code>isIE5p</code> test is intended to indicate that
+the browser is Internet Explorer 5.0 or above. However, Opera 7,
+IceBrowser 5.4, Web Browser 2.0 (palm OS), Konquerer, Safari, NetFront,
+iCab and others will all produce a <code>true</code> value in
+<code>isIE5p</code> because they implement <code>getElementById</code>
+and the <code>document.all</code> collection. As a result, code that
+assumes that it will have <em>all</em> of the capabilities of IE 5.0+
+available to it when <code>isIE5p</code> is <code>true</code> will as
+often as not be mistaken.
+</p>
+
+<p id="bdOI_9">
+This problem applies to all of the tests above with the possible
+exception of the <code>window.opera</code> test. I am unaware of a
+second browser type that has implemented an <code>opera</code> object
+on the window object. But then Opera 7 is a radically different, and
+much more dynamic browser that its preceding versions, though they all
+possess a <code>window.opera</code> object.
+</p>
+
+<p id="bdOI_10">
+To get around the problem that multiple browsers implement the same
+features (even if they start off unique to one browser) script authors
+have attempted to find more discriminating features to test. For
+example, the following script extract is intended to work only on IE
+5.0+ browsers:-
+</p>
+
+<pre id="bdOI_ex4">
+var isIE5p = !!window.ActiveXObject;
+...
+function copyToClip(myString){
+ if(!isIE5p) return;
+ window.clipboardData.setData(&quot;text&quot;,myString);
+}
+</pre>
+
+<p id="bdOI_11">
+The <code>ActiveXObject</code> constructor is intended to be
+discriminating of an IE browser. However, this type if script still
+does not work. It has placed the competing browser manufacturers in
+exactly the same position as they were in when scripts tested the
+<code>navigator.userAgent</code> string and excluded them from
+accessing a site because they honestly reported that they where not
+IE. As a result I already know of one browser that has implemented
+a <code>window.ActiveXObject</code> function, it probably is a dummy
+and exists in the browsers DOM specifically to defeat the exclusion
+of that browser based on tests like the one above.
+</p>
+
+<p id="bdOI_12">
+The assumptions that the existence of one (or two) feature(s) in a
+javascript environment infers the existence of any feature beyond
+the ones tested is invalid. It is only used by those ignorant of the
+potential for diversity, imitation and the patterns of evolution in
+browser DOMs.
+</p>
+
+<p id="bdOI_13">
+No matter how specifically the objects from which the inferences are
+derived are chosen, the technique itself sows the seeds of its own
+invalidity, an object that may actually validly be used to infer that
+a browser is of a particular type/version today probably will not still
+be valid next year. Adding a maintenance burden to a task that already
+presupposes an omniscient knowledge of <em>all</em> browser DOMs just
+in order to be effectively implemented at present.
+</p>
+
+
+<h2 id="bdFD">A Strategy That Works: Object/Feature Detecting</h2>
+
+<p id="bdFD_1">
+The main point of the previous discussion is to convey the idea that it
+is impossible to detect exactly which type of browser (or version of
+that browser) a script is being executed on. The use that such scripts
+have been put to in the past (to exclude browsers from sites that
+they probably could have successfully handled) has motivated the
+manufactures of browsers to render browser detecting nonviable
+as a strategy for dealing with the variations in browser DOMs.
+</p>
+
+<p id="bdFD_2">
+Fortunately, not being able to identify a web browser type or version
+with more accuracy than could be achieved by generating a random number
+and then biasing the result by your favourite (meaningless, because
+they too are based on browser detecting and suffer exactly the same
+unreliability) browser usage statistics, does not need to impact upon
+your ability to script web browsers at all. A viable alternative
+strategy has been identified and developed to the point where it is
+possible to author javascript to be used on web pages without any
+interest in the type or version of the browser at all.
+</p>
+
+<p id="bdFD_3">
+That alternative strategy is known as object or feature detecting. I
+prefer to use the term &quot;feature detecting&quot;, partly because the
+resulting code often needs to test and probe a wider range of
+features than just those that could be described as objects, but
+mostly because &quot;object detecting&quot; is occasionally
+erroneously applied to the object inference style of script described
+above.
+</p>
+
+<p id="bdFD_4">
+Feature detecting seeks to match an attempt to execute as script (or a
+part of a script) with the execution environment by seeking to test
+features of that environment where the results of the test have a
+direct one-to-one relationship with the features that need to be
+supported in the environment for the code to successfully execute. It
+is the direct one-to-one relationship in the implemented tests that
+avoids the need to identify the specific browser because whatever
+browser it is it either will support all of the required features or
+it will not. That would mean testing the feature itself (to ensure
+that it exists on the browser) and possibly aspects of the behaviour
+of that feature.
+</p>
+
+<p id="bdFD_5">
+Taking the previous example that illustrated how the
+<code>ActiveXObject</code> constructor might be used as the basis for
+a script that inferred the existence of, and ability to use, the
+<code>clipboardData</code> feature implemented on window IE. Rather
+than inferring the browser's support for the <code>clipboardData</code>
+feature from some other unrelated feature it should be fairly obvious
+that the feature that should be tested for prior to attempting to write
+to the clipboard <em>is</em> the <code>clipboardData</code> object, and
+further, that calling the <code>setData</code> method of that object
+should necessitate checking that it too is implemented:-
+</p>
+
+<pre id="bdFD_ex1">
+function copyToClip(myString){
+ if((typeof clipboardData != 'undefined')&amp;&amp;
+ (clipboardData.setData)){
+ clipboardData.setData(&quot;text&quot;,myString);
+ }
+}
+</pre>
+
+<p id="bdFD_6">
+In this way the tests that determine whether the
+<code>clipboardData.setData</code> method is called have a direct
+one-to-one relationship with the browser's support for the feature. It
+is not necessary to be interested in whether the browser is the
+expected windows IE that is known to implement the feature, or whether
+it is some other browser that has decided to copy IE's implementation
+and provide the feature itself. If the feature is there (at least to
+the required extent) it is used and if it is not there no attempt is
+made to use it.
+</p>
+
+<p id="bdFD_7">
+The above feature detecting tests are done using two operations. The
+first employs the <code>typeof</code> operator, which returns a string
+depending on the type of its operand. That string is one of
+<code>&quot;undefined&quot;</code>, <code>&quot;object&quot;</code>,
+<code>&quot;function&quot;</code>, <code>&quot;boolean&quot;</code>
+<code>&quot;string&quot;</code> and <code>&quot;number&quot;</code>
+and the test compares the returned string with the string
+<code>&quot;undefined&quot;</code>. The <code>clipboardData</code>
+object is not used unless typeof does not return
+<code>&quot;undefined&quot;</code>.
+</p>
+
+
+<p id="bdFD_8">
+The second test is a type-converting test. The logical AND
+(<code>&amp;&amp;</code>) operator internally converts its operands to
+boolean in order to make its decision about what value it will return.
+If <code>clipboardData.setData</code> is undefined it will type-convert
+to boolean <code>false</code>, while if it is an object or a function
+the result of the conversion will be boolean <code>true</code>.
+</p>
+
+<p id="bdFD_9">
+However, that function is not a particularly clever application of
+feature detecting because, while it avoids the function throwing errors
+in an attempt to execute <code>clipboardData.setData</code> on a browser
+thatdoes not support it, it will do nothing on a browser that does not
+support it. That is a problem when the user has been presented with a
+GUI component that gives them the impression that their interaction
+will result in something being written to the clipboard but when they
+use it nothing happens. And of course nothing was going to happen if
+the browser in use did not support javascript or it had been disabled.
+</p>
+
+<p id="bdFD_10">
+Ensuring that a script will not attempt to use a feature that is not
+supported is not sufficient to address the design challenge of crating
+scripts for the Internet. Testing the browser for the features that it
+does support makes it practical to handle a spectrum of browser DOMs
+but the script design task also involves planning how to handle the
+range of possibilities. A range that goes from guaranteed failure to
+execute at all on browser that do not support javascript, to full
+support for all of the required features.
+</p>
+
+<p id="bdFD_11">
+You can tell when the browser does not support the
+<code>clipboardData</code> feature from the script prior to using it
+but the user has no way of knowing why a button that promised them
+some action has failed to do anything. So in addition to matching the
+script to the browser's ability to execute it, it is also necessary to
+match the GUI, and the user's resulting expectations, to what the
+script is going to be able to deliver.
+</p>
+
+<p id="bdFD_12">
+Suppose the <code>copyToClip</code> function was called from an
+<code>INPUT</code> element of <code>type=&quot;button&quot;</code>
+and was intended to copy a company e-mail address into the clipboard,
+the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> code for the button might look like:-
+</p>
+
+<pre id="bdFD_ex2">
+&lt;input type=&quot;button&quot;
+ value=&quot;copy our contact e-mail address to your clipboard&quot;
+ onclick=&quot;copyToClip('info@example.com')&quot;&gt;
+</pre>
+
+<p id="bdFD_13">
+We know that that <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> will do nothing if javascript is
+disabled/unavailable and we know that it will do nothing if the browser
+does not support the required features, so one option would be to use a
+script to write the button <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> into the document in the position in
+which the button was wanted when the browser provided the facility:-
+</p>
+
+<pre id="bdFD_ex3">
+&lt;script type=&quot;text/javascript&quot;&gt;
+ if((typeof clipboardData != 'undefined')&amp;&amp;
+ (clipboardData.setData)&amp;&amp;
+ (document.write)){
+ document.write('&lt;input type=&quot;button&quot;',
+ 'value=&quot;copy our contact e-mail address',
+ ' to your clipboard&quot; onclick=&quot;',
+ 'copyToClip(\'info@example.com\')&quot;&gt;');
+ }
+&lt;/script&gt;
+</pre>
+
+<p id="bdFD_14">
+Now the user will never see the button unless the browser supports the
+required features <em>and</em> javascript is enabled. The user never
+gets an expectation that the script will not be able to deliver (at
+least that is the theory, it is still possible for the user's browser
+configuration to prevent scripts from writing to the clipboard, but
+the user might be expected to know how their browser is configured and
+understand that the button is not in a position to override it).
+</p>
+
+<p id="bdFD_15">
+If the <code>copyToClip</code> function is only ever called from
+buttons that are written only following the required feature detection
+then it can be simplified by the removal of the test from its body as
+it would be shielded from generating errors on nonsupporting browsers by
+the fact that there would be no way for it to be executed.
+</p>
+
+<p id="bdFD_16">
+The <code>document.write</code> method is not the only way of adding
+GUI components to a web page in a way that can be subject to the
+verification of the features that render those components meaningful.
+Alternatives include writing to a parent element's
+<code>innerHTML</code> property (where supported, see
+<a href="/faq/#updateContent">FAQ: How do I modify the content of the current page?</a>), or using the W3C DOM
+<code>document.crateElement</code> (or <code>createElementNS</code>)
+methods and appending the created element at a suitable location within
+the DOM. Either of these two approaches are suited to adding the
+components after the page has finished loading, but that can be useful
+as some feature testing is not practical before that point. The
+approach used can be chosen based on the requirements of the script.
+If the script is going to be using the
+<code>document.createElement</code> method itself then it is a good
+candidate as a method for inserting any required GUI components,
+similarly with <code>innerHTML</code>. The <code>document.write</code>
+method is universally supported in <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> DOMs but is not necessarily
+available at all in XHTML DOMs.
+</p>
+
+<p id="bdFD_17">
+Other ways of handling the possibility that the browser will not
+support either javascript or the features required by the script used
+is to design the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>/<span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> parts of the page so that the script, upon
+verifying support for the features it requires, can modify, manipulate
+and transform the resulting elements in the DOM. But in the absence of
+sufficient script support the unmodified <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> presents all of the
+required content, navigation, etc.
+</p>
+
+<p id="bdFD_18">
+This can be particularly significant with things like navigation menus.
+One style of design would place the content of the navigation menus,
+the URLs and text, in javascript structures such as Arrays. But either
+of javascript being disabled/unavailable on the client or the absence
+of the features required to support a functional javascript menu would
+leave the page without any navigation at all. Generally that would not
+be a viable web page, and not that good for search engine placement as
+search engine robots do not tend to execute javascript either so they
+would be left unable to navigate a site featuring such a menu and so
+unable to rank its content for listing.
+</p>
+
+<p id="bdFD_19">
+A better approach to menu design would have the navigation menu content
+defined in the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span>, possibly as nested list elements of some sort, and
+once the script has ascertained that the browser is capable of executing
+it and providing the menu in an interactive form it can modify the <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span>
+<code>position</code>, <code>display</code> and <code>visibility</code>
+properties, move the elements to their desired location, attach event
+handlers and generally get on with the task of providing a javascript
+menu. And the worst that happens when the browser does not support
+scripting or the required features is that the user (and any search
+engine robots) finds the navigation in the page as a series of nested
+lists containing links. Fully functional, if not quite as impressive as
+it could have been had the script been supported. This is termed
+&quot;clean degradation&quot; and goes hand in hand with feature
+detecting during the process of planing and implementing a browser
+script for the Internet.
+</p>
+
+<h3 id="bdGEID">Example 1: IDed Element Retrieval</h3>
+
+<p id="bdGEID_1">
+An important aspect of feature detecting is that it allows a script to
+take advantage of possible fall-back options. Having deduced that a
+browser lacks the preferred feature it still may be possible to
+achieve the desired goal by using an alternative feature that is know
+to exist on some browsers. A common example of this is retrieving an
+element reference from the DOM given a string representing the
+<code>ID</code> attribute of that element. The preferred method would
+be the W3C Core DOM standard <code>document.getElementById</code>
+method which is supported on the widest number of browsers. If that
+method was not available but the browser happened to support the
+<code>document.all</code> collection then it could be used for the
+element retrieval as a fall-back option. And for some types of
+elements, such as <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> positioned elements on Netscape 4 (where the
+<code>document.layers</code> collection may be used to retrieve such
+a reference), additional options may be available.
+</p>
+
+<pre id="bdGEID_ex1">
+function getElementWithId(id){
+ var obj;
+ if(document.getElementById){
+ <span class="commentJS">/* Prefer the widely supported W3C DOM method, if
+ available:-
+ */</span>
+ obj = document.getElementById(id);
+ }else if(document.all){
+ <span class="commentJS">/* Branch to use document.all on document.all only
+ browsers. Requires that IDs are unique to the page
+ and do not coincide with NAME attributes on other
+ elements:-
+ */</span>
+ obj = document.all[id];
+ }else if(document.layers){
+ <span class="commentJS">/* Branch to use document.layers, but that will only work for
+ <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> positioned elements and LAYERs that are not nested. A
+ recursive method might be used instead to find positioned
+ elements within positioned elements but most DOM nodes on
+ document.layers browsers cannot be referenced at all.
+ */</span>
+ obj = document.layers[id];
+ }
+ <span class="commentJS">/* If no appropriate/functional element retrieval mechanism
+ exists on this browser this function returns null:-
+ */</span>
+ return obj||null;
+}
+</pre>
+
+<p id="bdGEID_2">
+Although that function is not very long or complex (without its
+comments) it does demonstrate a consequence of one style of
+implementation of feature detecting, it repeats the test each time
+it is necessary to retrieve an element using its ID. If not too many
+elements need retrieving that may not be significant, but if many
+elements needed retrieving in rapid succession and performance was
+significant then the overhead of performing the feature detection on
+each retrieval may add up and impact on the resulting
+script.
+</p>
+
+<p id="bdGEID_3">
+An alternative is to assign one of many functions to a global
+<code>getElementWithId</code> variable based on the results of the
+feature detecting tests, as the script loads.
+</p>
+
+<pre id="bdGEID_ex2">
+var getElementWithId;
+if(document.getElementById){
+ <span class="commentJS">/* Prefer the widely supported W3C DOM method, if
+ available:-
+ */</span>
+ getElementWithId = function(id){
+ return document.getElementById(id);
+ }
+}else if(document.all){
+ <span class="commentJS">/* Branch to use document.all on document.all only
+ browsers. Requires that IDs are unique to the page
+ and do not coincide with NAME attributes on other
+ elements:-
+ */</span>
+ getElementWithId = function(id){
+ return document.all[id];
+ }
+}else if(document.layers){
+ <span class="commentJS">/* Branch to use document.layers, but that will only work for <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span>
+ positioned elements. This function uses a recursive method
+ to find positioned elements within positioned elements but most
+ DOM nodes on document.layers browsers cannot be referenced at
+ all. This function is expected to be called with only one
+ argument, exactly like the over versions.
+ */</span>
+ getElementWithId = function(id, baseLayers){
+ <span class="commentJS">/* If the - baseLayers - parameter is not provided default
+ its value to the document.layers collection of the main
+ document:
+ */</span>
+ baseLayers = baseLayers||document.layers;
+ <span class="commentJS">/* Assign the value of the property of the - baseLayers -
+ object (possibly defaulted to the document.layers
+ collection) with the property name corresponding to the
+ - id - parameter to the local variable - obj:
+ */</span>
+ var obj = baseLayers[id];
+ <span class="commentJS">/* If - obj - remains undefined (no element existed with the
+ given - id -) try searching the indexed members of
+ - baseLayers - to see if any of their layers collections
+ contain the element with the corresponding - id:
+ */</span>
+ if(!obj){ <span class="commentJS">//Element not found</span>
+ <span class="commentJS">/* Loop through the indexed members of - baseLayers: */</span>
+ for(var c = 0;c &lt; baseLayers.length;c++){
+ if((baseLayers[c])&amp;&amp; <span class="commentJS">//Object at index - c.</span>
+ (baseLayers[c].document)&amp;&amp; <span class="commentJS">//It has a - document.</span>
+ <span class="commentJS">/* And a layers collection on that document: */</span>
+ (baseLayers[c].document.layers)){
+ <span class="commentJS">/* Recursively call this function passing the - id - as
+ the first parameter and the layers collection from
+ within the document found on the layer at index - c
+ - in - baseLayers - as the second parameter and
+ assign the result to the local variable - obj:
+ */</span>
+ obj=getElementWithId(id,baseLayers[c].document.layers);
+ <span class="commentJS">/* If - obj - is now not null then we have found the
+ required element and can break out of the - for -
+ loop:
+ */</span>
+ if(obj)break;
+ }
+ }
+ }
+ <span class="commentJS">/* If - obj - will type-convert to boolean true (it is not null
+ or undefined) return it, else return null:
+ */</span>
+ return obj||null;
+ }
+}else{
+ <span class="commentJS">/* No appropriate element retrieval mechanism exists on
+ this browser. So assign this function as a safe dummy.
+ Values returned form calls to getElementWithId probably
+ should be tested to ensure that they are non-null prior
+ to use anyway so this branch always returns null:-
+ */</span>
+ getElementWithId = function(id){
+ return null;
+ }
+}
+
+<span class="commentJS">/*
+Usage:-
+
+var elRef = getElementWithId(&quot;ID_string&quot;);
+if(elRef){
+ ... //element was found
+}else{
+ ... //element could not be found.
+}
+*/</span>
+</pre>
+
+<p id="bdGEID_4">
+The feature detecting tests are performed once as the page loads and
+one of many function expressions assigned to the
+<code>getElementWithId</code> global variable as a result. The
+assigned function is the one most capable of retrieving the required
+element on the browser in use but it is still necessary to check that
+the returned value in not <code>null</code> and plan for the
+possibility of failure in the element retrieval process. It is
+guaranteed to fail on any browser that does not implement at least one
+of the element retrieval mechanisms used as the default function just
+returns <code>null</code>.
+</p>
+
+<p id="bdGEID_5">
+It may not be sufficient to provide a function that does the best job
+of element retrieval that can be done on the browser in use. Other
+scripts, or parts of the script, may need to know how successful their
+attempts to retrieve elements are likely to be. The
+<code>getElementWithId</code> version that uses
+<code>document.layers</code> cannot retrieve elements that are not <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span>
+positioned and that may not be good enough for some scripts, while it
+may not matter to others. The <code>document.getElementById</code> and
+<code>document.all</code> versions should be able to retrieve any
+element given its <code>ID</code>. An opting would be to set a couple
+of boolean flags to indicate how successful element retrieval can be
+expected to be. Defaulting the flags to <code>false</code> and setting
+them to <code>true</code> in the branches that assign the various
+function expressions. Then if other code is interested in what can be
+expected from the <code>getElementWithId</code> function, say in order
+to decide how to configure, or default itself, it can check the
+pertinent flag.
+</p>
+
+<pre id="bdGEID_ex3">
+var getElementWithId;
+var canGetAnyElement = false; <span class="commentJS">//default any element flag</span>
+var canGetCSSPositionedElements = false; <span class="commentJS">//default <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> positioned flag</span>
+if(document.getElementById){
+ canGetAnyElement = true; <span class="commentJS">//set any element flag to true</span>
+ canGetCSSPositionedElements = true; <span class="commentJS">//set <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> positioned flag true</span>
+ getElementWithId = ...
+}else if(document.all){
+ canGetAnyElement = true; <span class="commentJS">//set any element flag to true</span>
+ canGetCSSPositionedElements = true; <span class="commentJS">//set <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> positioned flag true</span>
+ getElementWithId = ...
+}else if(document.layers){
+ canGetCSSPositionedElements = true; <span class="commentJS">//set <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> positioned flag true</span>
+ <span class="commentJS">/* The - canGetAnyElement - flag is not set in this branch because
+ the document.layers collection does not make *all* elements
+ available.
+ */</span>
+ getElementWithId = ...
+}else{
+ <span class="commentJS">/* Neither flag is set when the dummy function is assigned because
+ it is guaranteed not to be able to retrieve any elements:
+ */</span>
+ getElementWithId = function(id){
+ return null;
+ }
+}
+...
+if(canGetCSSPositionedElements){
+ <span class="commentJS">/* Expect to be able to retrieve <span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span> positioned elements.
+ */</span>
+ ...
+ if(canGetAnyElement){
+ <span class="commentJS">/* Expect to also be able to retrieve any other elements that
+ have an ID attribute.
+ */</span>
+ ...
+ }
+}
+</pre>
+
+<p id="bdGEID_6">
+The flags do not directly reflect which feature is going to be used
+for element retrieval, instead they reflect what can be expected from
+the <code>getElementWithId</code> function on the current browser.
+Allowing a script that requires a particular level of performance
+(say the retrieval of any element) to determine whether it will have
+that facility but without denying the facility from a script with a
+less demanding requirement.
+</p>
+
+<h3 id="bdScroll">Example 2: Scroll Values</h3>
+
+<p id="bdScroll_1">
+Another common task that needs to be approached differently on
+different browsers is the retrieval of the extent to which the user
+has scrolled a web page. The majority of browsers provide properties
+of the global object called <code>pageXOffset</code> and
+<code>pageYOffset</code>, which hold the relevant values. Some make the
+equivalent browsers available as scrollLeft and scrollTop properties on
+the &quot;root&quot; element (either in addition to the
+<code>pageX/YOffset</code> properties or instead of them). The task is
+complicated further by the fact that which element is the
+&quot;root&quot; element depends on various factors, it was always the
+<code>document.body</code> element in the past but newer (<span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span>)
+standards compliant browsers (and browsers that can operate in various
+modes, including standards compliant mode) make the
+<code>document.documentElement</code> the root element. Then there may
+be browsers that do not make the scrolling values available at all.
+</p>
+
+<p id="bdScroll_2">
+Because the <code>pageXOffset</code> and <code>pageYOffset</code>
+properties are implemented on the largest number of browsers, and their
+use avoids the need to worry about the &quot;root&quot; element, they
+are the preferred values to use. In there absence the problem moves on
+to identifying the &quot;root&quot; element, which is made easier by
+the browsers that understand standards compliant mode and provide a
+<code>document.compatMode</code> string property to announce which mode
+they are in. If the string property is missing or the value of that
+string is other than <code>&quot;CSS1Compat&quot;</code> then it is the
+<code>document.body</code> object that needs to be read for the
+scrolling values, else the <code>document.documentElement</code> should
+be read. Testing for the presence of any of the scroll values
+themselves needs to done with a <code>typeof</code> test because they
+are numeric values and if implemented but set to zero a type-converting
+test would return <code>false</code> but that would not be an indicator
+of their absence.
+</p>
+
+<p id="bdScroll_3">
+The following is an example that employs feature detection to decide
+which scroll values to read:-
+</p>
+
+<pre id="bdScroll_ex1">
+<span class="commentJS">/* The - getPageScroll - global variable is assigned a reference to a
+ function and when that function is called initially it configures
+ the script to read the correct values, if available, and then
+ returns a reference to the object - interface - which provides
+ methods that retrieve the scroll values. Subsequent invocations of
+ the getPageScroll function do not repeat the configuration, they
+ just return a reference to the same interface object. Because the
+ configuration stage may need to check whether the document.body
+ element exists the function cannot be called until the browser has
+ parsed the opening body tag as prior to that point there is no
+ document.body element.
+
+ Usage:-
+ var scrollInterface = getPageScroll();
+ var scrollX = scrollInterface.getScrollX();
+ var scrollY = scrollInterface.getScrollY();
+
+ The interface methods return NaN if the browser provides no method
+ of reading the scroll values. A returned NaN value can be tested for
+ with the - isNaN - global function, but it should not be necessary
+ to perform the isNaN test on more than the first retrieval because
+ if the returned value is NaN it will always be NaN and if it is not
+ it should never be.
+
+ if(isNaN(scrollX)){
+ //No scroll value retrieval mechanism was available on this browser
+ }
+
+ (* The script performs an inline execution of a function expression
+ which returns the function object that is assigned to the -
+ getPageScroll - global variable. This produces a closure that
+ preserves the local variables of the executed function expression,
+ allowing the execution context of the function expression to provide
+ a repository for the configuration results, keeping them out of the
+ global namespace. The format is:-
+
+ v--- Anonymous function expression --v
+ var variable = (function(){ ...; return returnValue; })();
+ Inline execution of the function expression ----^^
+
+ The value returned by the inline execution of the anonymous function
+ expression is assigned to the variable. If that returned value is a
+ reference to an inner function object then the assignment will form
+ a closure.)
+*/</span>
+var getPageScroll = (function(){
+ <span class="commentJS">/* The local variable &quot;global&quot; is assigned the value - this -
+ because the function expression is executing in the global
+ context and - this - refers to the global object in that
+ context. The global object is usually the - window - object on
+ web browsers but this local variable is going to be used in the
+ configuration tests for convenience:
+ */</span>
+ var global = this;
+ <span class="commentJS">/* notSetUp - Is a flag to indicate when the script has done the
+ setup configuration:
+ */</span>
+ var notSetUp = true;
+ <span class="commentJS">/* readScroll - Is initially a dummy object that is used to return
+ the NaN values whenever no functional scroll value retrieval
+ mechanism is available on the browser. It is assigned a
+ reference to the object from which the scroll values can be read
+ if the feature detection determines that to be possible:
+ */</span>
+ var readScroll = {scrollLeft:NaN,scrollTop:NaN};
+ <span class="commentJS">/* Using the local variables - readScrollX - and readScrollY - to
+ hold the property names allows the same functions to read both
+ the pageX/YOffset properties of the global object and the
+ scrollTop/Left properties of the &quot;root&quot; element by assigning
+ different values to the variables. These are the defaults:
+ */</span>
+ var readScrollX = 'scrollLeft';
+ var readScrollY = 'scrollTop';
+ <span class="commentJS">/* The - itrface - local variable is assigned a reference to an
+ object and it is this object that is returned whenever
+ getPageScroll() is called. The object has two properties,
+ getScrollX and getScrollY, which are assigned the values of two
+ anonymous function expressions. These functions are inner
+ functions and as a result have access to the local variables of
+ the function that contains them (the anonymous function
+ expression that is executed inline in order to assign value to
+ the getPageScroll global variable). The use a square bracket
+ property accessor to read a value of whatever object has been
+ assigned to the variable - readScroll - with a property name
+ that corresponds to the value assigned to whichever of the
+ variables - readScrollX - or - readScrollY - are employed,
+ allows the functions to use the simplest code poible to provide
+ values for all of the possible permutations resting from the
+ feature detection derived configuration:
+ */</span>
+ var itrface = {
+ getScrollX:function(){
+ return readScroll[readScrollX];
+ },
+ getScrollY:function(){
+ return readScroll[readScrollY];
+ }
+ };
+ <span class="commentJS">/* The - setUp - inner function is called to perform the feature
+ detection and configure the variables that will be employed in
+ reading the correct scroll values. It sets the - notSetUp - flag
+ to false once it has been executed so that configuration only
+ happens the first time that a request for the interface object
+ is made:
+ */</span>
+ function setUp(){
+ <span class="commentJS">/* As the paeX/YOffset properties are the preferred values to
+ use they are tested for first. They are not both tested
+ because if one exists the other can be assumed to exist for
+ symmetry. The testing method is a - typeof - test to see if
+ the value is a number. A type-converting test cannot be used
+ because the number zero would result in boolean false and a
+ pageXOffset value will be zero if the page has not been
+ scrolled:
+ */</span>
+ if(typeof global.pageXOffset == 'number'){
+ <span class="commentJS">/* If pageXOffset is a number then the value of the -
+ global - variable (assigned a reference to the global
+ object earlier) is assigned to the - readScroll -
+ variable and the strings &quot;pageXOffset&quot; and &quot;pageYOffset&quot;
+ are assigned to the - readScrollX - and - readScrollY -
+ variables so they will be the property names used to
+ access the - readScroll- (now the global) object.
+ */</span>
+ readScroll = global;
+ readScrollY = 'pageYOffset';
+ readScrollX = 'pageXOffset';
+ }else{
+ <span class="commentJS">/* If pageXOffset is undefined it is time to find out which
+ object is the &quot;root&quot; element. First, does the browser
+ have a - document.compatMode - string, if it does then
+ is its value &quot;BackCompat&quot;, &quot;QuirksMode&quot; or &quot;CSS1Compat&quot;.
+ Instead of comparing the string directly it is searched
+ for the substring &quot;<span class="initialism" title="Cascading Style Sheet"><abbr title="Cascading Style Sheet">CSS</abbr></span>&quot; which might make the script more
+ robust in the face of possible future &quot;CSSnCompat&quot;
+ modes, which are unlikely to demand that the &quot;root&quot;
+ element is moved again.
+
+ The tests also verifies that there is a -
+ document.documentElement - to read and that its
+ - scrollLeft - property is a number:
+ */</span>
+ if((typeof document.compatMode == 'string')&amp;&amp;
+ (document.compatMode.indexOf('CSS') &gt;= 0)&amp;&amp;
+ (document.documentElement)&amp;&amp;
+ (typeof document.documentElement.scrollLeft=='number')){
+ <span class="commentJS">/* The - readScrollX - and - readScrollY - variables
+ are already defaulted to the required strings so it
+ is only necessary to assign a reference to the -
+ document.documentElement - to the - readScroll -
+ variable:
+ */</span>
+ readScroll = document.documentElement;
+ <span class="commentJS">/* If the browser is not in the appropriate mode the scroll
+ values should be read from the document.body - element,
+ assuming it exists on this browser and that the
+ - scrollLeft - property is a number:
+ */</span>
+ }else if((document.body)&amp;&amp;
+ (typeof document.body.scrollLeft == 'number')){
+ <span class="commentJS">/* The - readScrollX - and - readScrollY - variables
+ are already defaulted to the required strings so it
+ is only necessary to assign a reference to the -
+ document.body - to the - readScroll - variable:
+ */</span>
+ readScroll = document.body;
+ }
+ <span class="commentJS">/* No other scroll value reading options exist so if -
+ readScroll - has not been assigned a new value by this
+ point it will remain a reference to the object with the
+ NaN value properties.
+ */</span>
+ }
+ notSetUp = false; <span class="commentJS">//No need to repeat configuration.</span>
+ }
+ <span class="commentJS">/* The inline execution of the anonymous function expression
+ returns with the following statement. It returns an inner
+ function expression and it is that function that will be called
+ when getPageScroll() is executed. Doing this forms a closure,
+ preserving all of the local variables and functions defined
+ within the executed anonymous function expression. Calling that
+ returned function as - getPageScroll() - executes the setUp
+ function, but only if it has not already been called, and
+ returns a reference to the - itrface - object.
+ */</span>
+ return (function(){
+ if(notSetUp){ <span class="commentJS">//If the - notSetUp - variable is still true.</span>
+ setUp(); <span class="commentJS">//Execute the - setUp - function.</span>
+ }
+ return itrface; <span class="commentJS">//returns a reference to - itrface</span>
+ });
+})(); <span class="commentJS">//inline-execution of anonymous function expression, one-off!</span>
+</pre>
+
+<p id="bdScroll_4">
+The effect of this code is to match the browser's ability to provide
+the scrolling information with a script's desire to read it through a
+simple and efficient interface that acts based on the results of
+featured detecting tests that it applies only once, and if the browser
+does not support any methods of reading the scroll values the return
+values form the interface method indicate that fact by being NaN. It
+does not matter that Netscape 4 will be reading the global
+<code>pageX/YOffset</code> properties, that IE 4 will read the
+<code>scrollTop/Left</code> properties from <code>document.body</code>
+or that IE 6 will read those values from one of two possible objects
+based on the <code>document.compatMode</code> value. What is important
+is that if unknown browser XYZ provides any of those mechanisms for
+reporting the scroll values the script is going to be able to use them,
+without ever knowing (or caring) that it is browser XYZ that it is
+executing on.
+</p>
+
+<h3 id="bdReplace">Example 3: String.prototype.replace</h3>
+
+<p id="bdReplace_1">
+Feature detecting is not restricted to features of the DOM, it can be
+extended to include features of the javascript language implementation.
+For example the <code>String.prototype.replace</code> function in later
+language versions will accept a function reference as its second
+argument, while earlier versions only accept a string in that context.
+Code that wants to use the function argument facility of the
+<code>replace</code> method will fail badly if it is not supported on
+the browser.
+</p>
+
+<p id="bdReplace_2">
+As usual, a feature-detecting test for the implementation's ability to
+support function arguments with the <code>replace</code> method has to
+be a direct test on that feature. The following example test takes
+advantage of the fact that a browser that only supports the string
+argument version of <code>replace</code> will type-convert a function
+reference used in that context into a string. The <code>replace</code>
+method uses a Regular Expression (its first argument) to
+identify parts of a string and then replaces them with a string that is
+provided as its second argument. If the second argument is a function,
+and the browser supports the function argument, that function is called
+and its return value replaces the identified parts of the string.
+</p>
+
+<p id="bdReplace_3">
+By providing a function expression that returns an empty string as its
+second argument and a Regular Expression that identifies the entire
+original string as the first argument, the operation of the
+<code>replace</code> method will result in an empty string if the
+function argument is supported. But if only string arguments are
+supported then the function will be type-converted into a string and
+that string will not be an empty string so the result of the
+evaluation of the <code>replace</code> method will not be an empty
+string. Applying a NOT (<code>!</code>) operation to the resulting
+string type-converts the empty string into a boolean value, inverts
+it and returns <code>true</code>, the non-empty string would result
+in <code>false</code>.
+</p>
+
+<pre id="bdReplace_ex1">
+<span class="commentJS">/* The original string is the one letter string literal &quot;a&quot;. The
+ Regular Expression /a/ identifies that entire string, so it is the
+ entire original string that will be replaced. The second argument is
+ the function expression - function(){return '';} -, so the entire
+ original string will be replaced with an empty string if the
+ function expression is executed. If it is instead type-converted
+ into a string that string will not be an empty string. The NOT (!)
+ operation type-converts its operand to boolean and then inverts it
+ so the results of the test is boolean true if function references
+ are supported in the second argument for the - replace - method, and
+ false when not supported:
+*/</span>
+if(!('a'.replace(/a/, (function(){return '';})))){
+ ... <span class="commentJS">//function references OK.</span>
+}else{
+ ... <span class="commentJS">//no function references with replace.</span>
+}
+</pre>
+
+<p id="bdReplace_4">
+The common thread with feature detecting is that it is the code that is
+going to use the features, and the nature of those features, that
+defines how support for the required feature needs to be tested. Once
+you get used to the idea it starts to become obvious which tests need
+to be applied to verify a browser's support for a feature, and then it
+is time to work on the efficient application of feature detection.
+</p>
+
+<h2 id="bdDesPb">The Javascript Design Problem</h2>
+
+<p id="bdDesPb_1">
+Javascript as a language is not that complex, it may have its quirks
+but it can be defined entirely in the 173 pages of the ECMA
+specification (3rd edition). The challenge of authoring javascript
+comes form the diversity of execution environments. When authoring for
+the Internet nothing is known about the receiving software in advance,
+and even when that software is a web browser that will execute
+javascript, there is still a spectrum of possible DOM implementations
+to contend with.
+</p>
+
+<p id="bdDesPb_2">
+The combination of the facts that it is impossible to determine which
+browser is executing the script, and that it is impossible to be
+familiar with all browser DOMs can be rendered insignificant by using
+feature detection to match code execution with any browser's ability to
+support it. But there is still going to be a diversity of
+outcomes, ranging from total failure to execute any scripts (on
+browsers that do not support javascript, or have it disabled) to full
+successful execution on the most capable javascript enabled browsers.
+</p>
+
+<p id="bdDesPb_3">
+The challenge when designing scripts is to cope with all of the
+possibilities in a way that makes sense for everyone. As those
+possibilities will always include browsers incapable of executing
+javascript at all, the starting point must be pages based on (valid)
+<span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> that contain all of the required content, allow the necessary
+navigation and are as functional as they purport to be (possibly with
+the backing of server-side scripting, which does not have any of the
+problems of client side scripting). On top of that reliable foundation
+it is possible to layer the scripts. Feature detecting and adding
+scripted enhancements when the browser is capable of supporting them,
+cleanly degrading to the underlying and reliable <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> when it is not.
+</p>
+
+<p id="bdDesPb_4">
+A well designed script, implementing a suitable strategy, can enhance
+the underlying <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page, exploiting the browser's capabilities to the
+maximum extent possible and still exhibit planed behaviour in the
+absence of any (or all) desired features and degrade cleanly where
+necessary. Nobody should either consider themselves a skilled Internet
+javascript author, or deprecate javascript as a language and/or browser
+scripting as a task, until they have demonstrated an ability to write
+a non-trivial script that achieves that goal.
+</p>
+</body>
+</html>
/trunk/cljs/notes/detect-browser/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/notes/square-brackets/index.html
===================================================================
--- trunk/cljs/notes/square-brackets/index.html (nonexistent)
+++ trunk/cljs/notes/square-brackets/index.html (revision 45)
@@ -0,0 +1,373 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+<title>Square Bracket Notation</title>
+<meta http-equiv="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+<link href="../../faq.css" rel="stylesheet" type="text/css">
+<link href="../notes.css" rel="stylesheet" type="text/css">
+<meta name="ROBOTS" content="NOINDEX NOFOLLOW">
+</head>
+<body>
+<h1>Javascript Square Bracket Notation</h1>
+<div id="faqNav">
+ <a href="../../">FAQ</a> &gt; <a href="../">FAQ Notes</a>
+
+</div>
+<ul>
+ <li><a href="#intro">Introduction</a></li>
+ <li><a href="#sBs">Square Bracket Syntax</a></li>
+ <li><a href="#vId">String Variables as Identifiers</a></li>
+ <li><a href="#eId">String Expressions as Identifiers</a></li>
+ <li><a href="#aVa">Global Variable access with the Square Bracket Notation</a></li>
+ <li><a href="#illc">Illegal characters in Identifier-strings</a></li>
+</ul>
+<h2 id="intro">Introduction</h2>
+
+<p id="intro_1">To be useful javascript needs to be able to access the properties of
+objects. It is impossible to learn javascript without understanding the
+dot notation that is normally used to access the properties of objects.
+</p>
+
+<p id="intro_2">Javascript also offers an alternative property accessor notation
+using square brackets in a way that is similar to the way in which the
+indexed members of an Array are accessed, except that a string is used
+between the square brackets. This alternative notation is extremely
+powerful and useful but gets very little coverage in most books on
+javascript and that seems to leave novice javascript programmers
+unaware that they even have this option.</p>
+
+<p id="intro_3">The coverage in javascript books can be very poor. Looking back at
+some of the books that I first used to learn javascript, one devotes
+exactly one paragraph to property accessors and another actually states
+that the square bracket notation can only be used with integer indexes
+to access Arrays and array-like structures.</p>
+
+<p id="intro_4">With an understanding of dot notation and few clues that an
+alternative exists, novice (and a few surprisingly experienced)
+javascript programmers often turn to the <code>eval</code> function,
+constructing a string that represents a dot notation accessor
+(frequently retrieving the property names from javascript variables)
+and then passing it to the <code>eval</code> function in order to
+access the object property that it refers to. The <code>eval</code>
+function is just not needed to perform this type of property access
+and it is a relatively inefficient way of doing so (plus, some embedded
+browsers lack the resources to implement an <code>eval</code> function).
+</p>
+
+<h2 id="sBs">Square Bracket Syntax</h2>
+<p id="sBs_1">If you can access the property of an object using dot
+notation, such as:-</p>
+
+<pre id="sBs_ex1">document.body</pre>
+
+<p id="sBs_2">- you can also use the square bracket notation:-</p>
+
+<pre id="sBs_ex2">document['body']</pre>
+
+<p id="sBs_3">- in which the dot and the identifier to the right of the dot are
+replaced with a set of square brackets containing a string that
+represents the identifier that was to the right of the dot.</p>
+
+<p id="sBs_4">The Property Accessors section of javascript language specification
+(ECMA 262) makes it clear that the dot notation and the square bracket
+notation are parallel ways of accessing the properties of objects.</p>
+
+<blockquote cite="http://www.ecma-international.org/publications/files/ecma-st/Ecma-262.pdf">
+<dl>
+ <dt>ECMA 262 3rd Edition. Section 11.2.1 Property Accessors</dt>
+ <dd>
+ Properties are accessed by name, using either the dot notation:
+<pre >
+MemberExpression.Identifier
+CallExpression.Identifier
+</pre>
+ or the bracket notation:
+<pre>
+MemberExpression[ Expression ]
+CallExpression[ Expression ]
+</pre>
+ The dot notation is explained by the following syntactic conversion:
+ <pre>MemberExpression.Identifier</pre>
+ is identical in its behaviour to
+ <pre>MemberExpression[ &lt;identifier-string&gt; ]</pre>
+ and similarly
+ <pre>CallExpression.Identifier</pre>
+ is identical in its behaviour to
+ <pre >CallExpression[ &lt;identifier-string&gt; ]</pre>
+ where <code>&lt;identifier-string&gt;</code> is a string literal
+ containing the same sequence of characters as the Identifier.
+ <dd>
+</dl>
+</blockquote>
+
+<p id="sBs_5">In the following simple <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> page:-</p>
+
+<pre id="sBs_ex3">
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;title&gt;&lt;/title&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+ &lt;form name=&quot;formName&quot; action=&quot;#&quot;&gt;
+ &lt;input type=&quot;text&quot; name=&quot;inpName&quot; value=&quot;Example value text&quot;&gt;
+ &lt;/form&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<p id="sBs_6">- which contains a form named <code>&quot;formName&quot;</code> with
+one input element named <code>&quot;inpName&quot;</code>. Various forms
+of dot notation property accessor can be used to reference the
+<code>&quot;value&quot;</code> property of the input element. One of
+the simplest is:-</p>
+
+<pre id="sBs_ex4">
+var stringOfValue = document.formName.inpName.value;
+</pre>
+
+<p id="sBs_7">This dot notation has three dots, so there are three points at which
+the square bracket notation could be used in place of the dot notation
+(these are all equivalent).</p>
+
+<pre id="sBs_ex5">
+var stringOfValue = document[&quot;formName&quot;].inpName.value;
+
+var stringOfValue = document.formName[&quot;inpName&quot;].value;
+
+var stringOfValue = document.formName.inpName[&quot;value&quot;];
+</pre>
+
+<p id="sBs_8">The following combinations are also all equivalent to the original
+dot notation:-</p>
+
+<pre id="sBs_ex6">
+var stringOfValue = document[&quot;formName&quot;].inpName[&quot;value&quot;];
+
+var stringOfValue = document[&quot;formName&quot;][&quot;inpName&quot;].value;
+
+var stringOfValue = document[&quot;formName&quot;][&quot;inpName&quot;][&quot;value&quot;];
+
+var stringOfValue = window[&quot;document&quot;][&quot;formName&quot;][&quot;inpName&quot;][&quot;value&quot;];
+</pre>
+
+<p id="sBs_9">Where the dot notation follows the dot with the identifier for the
+property that is to be accessed, the square bracket notation replaces
+the dot and identifier with square brackets that contain a string that
+represents the identifier for the property (the property name).</p>
+
+<h2 id="vId">String Variables as Identifiers</h2>
+
+<p id="vId_1">The string used within the square brackets does not need to be a
+string literal. It can be any expression that results in a string.
+This is where the square bracket notation becomes most useful as the
+expression could be a reference to a string variable that holds the
+property name as its value, or a function call that returns a string,
+or an expression that concatenates two strings, or any combination of
+these.</p>
+
+<p id="vId_2">This means that the identifier needed to access a property does not
+need to be coded into a javascript. Consider the following simple
+function:-</p>
+
+<pre id="vId_ex1">
+function setPropertyToValue(oObj, sPropName, value){
+ oObj[sPropName] = value;
+}
+</pre>
+
+<p id="vId_3">- provided with a reference to an object (<code>oObj</code>), the
+name of a property (<code>sPropName</code>) and a value for that
+property (<code>value</code>), it will set the value of the property
+without needing to know what the name of the property that it is
+setting is. Called as
+<code>setPropertyToValue(document.formName.inpName, &quot;value&quot;, &quot;new value&quot;)</code>
+it will set the value of the field in the example form above to the
+string <code>&quot;new value&quot;</code>. However, called as
+<code>setPropertyToValue(window, &quot;location&quot;, &quot;http://www.google.com&quot;)</code>
+and the same function will navigate a web browser to the URL provided
+as the final parameter. Although this is a forced example you should be
+able to see that the square bracket notation offers considerable power
+and flexibility.</p>
+
+<p id="vId_4">Any variable that holds a string value can be used between the
+square brackets to form a property accessor. Variables that hold
+non-strings will have their value internally type converted into a
+string and that string will be used as the property name. This is not very
+useful, especially if the variables contain references to objects or
+functions, as the returned string is likely to be implementation
+dependent.</p>
+
+<h2 id="eId">String Expressions as Identifiers</h2>
+
+<p id="eId_1">The ability to build the string used as the property name can be
+very useful in loops and with dynamically generating web pages (server
+side) that have variable length content. The strings can be the result
+of expressions that concatenate string literals with variables
+(particularly loop counters).</p>
+
+<p id="eId_2">Given the form:-</p>
+
+<pre id="eId_ex1">
+&lt;form name=&quot;formName&quot; action=&quot;#&quot;&gt;
+ &lt;input type=&quot;text&quot; name=&quot;field_1&quot;&gt;
+ &lt;input type=&quot;text&quot; name=&quot;field_2&quot;&gt;
+ &lt;input type=&quot;text&quot; name=&quot;field_3&quot;&gt;
+&lt;/form&gt;
+</pre>
+
+<p id="eId_3">- the following loop will clear the value property of each element
+it turn:-</p>
+
+<pre id="eId_ex2">
+for(var c = 1;c &lt; 4;c++){
+ document.forms[&quot;formName&quot;].elements[&quot;field_&quot;+c].value = &quot;&quot;;
+}
+</pre>
+
+<p id="eId_4">If a server side process had created the <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> form with
+<code>n</code> elements, named <code>field_1, field_2 ... field_n</code>
+, then all the server side process would have to do to have the loop
+clear each and every input element would be to change the <code>4</code>
+in the example to the value of <code>n+1</code>.</p>
+
+<p id="eId_5">Concatenation is the most common type of expression used with the
+square bracket notation but any javascript expression could be used.
+A function that returned a string could be used.</p>
+
+<p id="eId_6">In the following (rather contrived) example :-</p>
+
+<pre id="eId_ex3">
+function getRootElName(){
+ if(document.compatMode &amp;&amp; (document.compatMode == &quot;CSS1Compat&quot;)){
+ return &quot;documentElement&quot;;
+ }else{
+ return &quot;body&quot;;
+ }
+}
+
+var verticalScroll = document[getRootElName()].scrollTop;
+</pre>
+<p id="eId_7">- the <code>scrollTop</code> value is read from either the
+<code>document.body</code> or <code>document.documentElement</code>
+depending on the value of <code>document.compatMode</code>. Passing
+strings about is far from the best way of achieving what the code
+above does but there will be circumstances when returning a string
+from a function call for use in a property accessor is potentially
+useful.</p>
+
+<h2 id="aVa">Global Variable access with the Square Bracket Notation</h2>
+
+<p id="aVa_1">The square bracket notation requires that there be some sort of
+object reference to the left of the brackets.</p>
+
+<pre id="aVa_ex1">[&quot;document&quot;] <span class="commentJS">//Array literal, not a Property Accessor!</span></pre>
+
+<p id="aVa_2">-will produce an error if an attempt is made to assign a value to it,
+as it will be treated as an Array literal, if an attempt to read from
+it is made the one element array containing the string within the
+brackets is returned. Global variables are normally referenced by their
+one identifier alone. This would seem to exclude global variables from
+the possibility of being referenced using a string that held their
+identifier name or an expression that built, or returned, their name.
+However, javascript global variables (and global function names for
+that matter) are properties of a global object. Any identifier that
+holds a reference to the global object can be used to the left of the
+square brackets to form a property accessor that refers to a global
+variable.</p>
+
+<p id="aVa_3">In a web browser the global object is the window (or frame) in which
+the script is running. Each window (or frame) object contains a number
+of properties, at least two of which are references to the window
+(global object) itself. These properties are 'window' and 'self'.
+These property names can be used as the identifier to the left of the
+square brackets when referring to global variables. So given a global
+variable defined as:-</p>
+
+<pre id="aVa_ex2">
+var anyName = 0;
+</pre>
+
+<p id="aVa_4">- that global variable can be referenced as:-</p>
+
+<pre id="aVa_ex3">
+window[&quot;anyName&quot;]
+</pre>
+
+<p id="aVa_5">As with any other use of the square bracket notation, the string
+within the brackets can be held in a variable or constructed/returned
+by an expression.</p>
+
+<p id="aVa_6">Code that is executing in the global context, the code within global
+functions (except Object constructors invoked with the <code>new</code>
+keyword) and inline code outside of any functions, could also use the
+<code>this</code> keyword to refer to the global object. The
+<code>this</code> keyword refers to an object depending on the
+execution context. For code executing in the global context
+<code>this</code> is the global object (on a web browser, the window
+object). As a result, the above variable could be referred to as
+<code>this[&quot;anyName&quot;]</code>, but only in code that is
+executing in the global context.</p>
+
+<p id="aVa_7">However, using the <code>this</code> keyword is very likely to be
+confusing, especially in scripts that include custom javascript objects
+where the methods (and constructors) of those objects would be using
+<code>this</code> to refer to their own object instances.</p>
+
+<p id="aVa_8">Some javascript implementations do not have a property of the global
+object that refers to the global object. Rather than trying to use the
+<code>this</code> keyword to access global variables it is possible to
+create your own global variable that refers to the global object.</p>
+
+<pre id="aVa_ex4">
+var myGlobal = this;
+</pre>
+
+<p id="aVa_9">- executed as inline code at the start of a script will assign a
+reference to the global object (<code>this</code> in that context).
+From then on all global variables can be referenced with square bracket
+notation as:-</p>
+
+<pre id="aVa_ex5">
+myGlobal[&quot;anyName&quot;];
+</pre>
+
+<p id="aVa_10">- and expect <code>myGlobal</code> to refer to the global object
+from any execution context.</p>
+
+<h2 id="illc">Illegal characters in Identifier-strings</h2>
+
+<p id="illc_1">One advantage of the square bracket notation over dot notation is
+the ability to use characters in identifier-strings that are not legal
+identifier characters. It is generally best to avoid giving javascript
+properties names and <span class="initialism" title="HyperText Mark-up Language"><abbr title="HyperText Mark-up Language">HTML</abbr></span> elements names/IDs that are not made up
+entirely of characters that are legal in the relevant context. However,
+it is not always possible to avoid referencing elements with names that
+include characters that would be illegal in a javascript identifier.
+PHP offers an example of this, multiple form elements given the same
+name followed with empty square brackets, such as
+<code>name=&quot;inpEl[]&quot;</code>, are made available on the server
+as an array.</p>
+
+<p id="illc_2">The square bracket notation would allow an element with such a name
+to be referenced as <code> document&#46;forms[&quot;formName&quot;]&#46;elements[&quot;inpEl[]&quot;][0]</code>
+for example (the final <code>[0]</code> reflects the fact that
+multiple elements with the same name, when accessed by name, generate
+collections of elements and individual elements within that collection
+need to be referenced by index).</p>
+
+<ul style="list-style-type:none;margin-top:2.5em;">
+ <li>Written by <span class="person">Richard Cornford</span>. March 2003.</li>
+ <li>With technical corrections and suggestions by:-<br>
+ <ul style="list-style-type:none;">
+ <li><span class="person">Yann-Erwan Perio (Yep)</span>. (Also, thanks for testing the use
+ of <code>this</code> to reference the global object in WSH
+ and ASP2.)
+ </li>
+ <li><span class="person">Lasse Reichstein Nielsen</span>.</li>
+ <li><span class="person">Dr John Stockton</span>.</li>
+ </ul>
+ </li>
+</ul>
+</body>
+</html>
/trunk/cljs/notes/square-brackets/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/index.php
===================================================================
--- trunk/cljs/index.php (nonexistent)
+++ trunk/cljs/index.php (revision 45)
@@ -0,0 +1,39 @@
+<?php
+
+$encoding = 'UTF-8';
+header("Content-Type: text/html" . ($encoding ? "; charset=$encoding" : ""));
+
+$modi = max(
+ array_map('filemtime',
+ array_diff(
+ array_merge(
+ scandir(__DIR__),
+ array_map(
+ function ($e) {
+ return 'sections' . DIRECTORY_SEPARATOR . $e;
+ },
+ scandir('sections')
+ )
+ ),
+ array('.', '..')
+ )
+ )
+);
+
+header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $modi) . ' GMT');
+
+/* Cached resource expires in HTTP/1.1 caches 0 (-24-) h after last retrieval */
+header('Cache-Control: max-age=0, s-maxage=0, must-revalidate, proxy-revalidate');
+
+/* Cached resource expires in HTTP/1.0 caches 0 (-24-) h after last retrieval */
+header('Expires: ' . gmdate('D, d M Y H:i:s', time() /*+ 86400*/) . ' GMT');
+
+$doc = new DOMDocument();
+$doc->substituteEntities = true;
+$xsl = new XSLTProcessor();
+
+$doc->load('index.xsl');
+$xsl->importStyleSheet($doc);
+
+$doc->load('index.xml');
+echo $xsl->transformToXML($doc);
\ No newline at end of file
/trunk/cljs/index.php
Property changes:
Added: svn:keywords
## -0,0 +1 ##
+LastChangedDate LastChangedRevision LastChangedBy Id
\ No newline at end of property
Index: trunk/cljs/index.xml
===================================================================
--- trunk/cljs/index.xml (nonexistent)
+++ trunk/cljs/index.xml (revision 45)
@@ -0,0 +1,37 @@
+<!DOCTYPE FAQ [
+ <!ENTITY trade "&#8482;"><!-- trade mark sign, U+2122 ISOnum -->
+
+ <!ENTITY meta SYSTEM "sections/meta.xml">
+ <!ENTITY overview SYSTEM "sections/overview.xml">
+ <!ENTITY resources SYSTEM "sections/resources.xml">
+ <!ENTITY functions SYSTEM "sections/functions.xml">
+ <!ENTITY dates SYSTEM "sections/dates.xml">
+ <!ENTITY numbers SYSTEM "sections/numbers.xml">
+ <!ENTITY objects SYSTEM "sections/objects.xml">
+ <!ENTITY strings SYSTEM "sections/strings.xml">
+ <!ENTITY dom SYSTEM "sections/dom.xml">
+ <!ENTITY windows SYSTEM "sections/windows.xml">
+ <!ENTITY server SYSTEM "sections/server.xml">
+ <!ENTITY debugging SYSTEM "sections/debugging.xml">
+ <!ENTITY donts SYSTEM "sections/donts.xml">
+ <!ENTITY suggestions SYSTEM "sections/suggestions.xml">
+]>
+<FAQ VERSION="32.2" DATE="2010-10-08" revision="$Revision$" id="$Id$">
+ <TITLE>FAQ for comp.lang.javascript</TITLE>
+ <CONTENTS>
+ &meta;
+ &overview;
+ &resources;
+ &functions;
+ &dates;
+ &numbers;
+ &objects;
+ &strings;
+ &dom;
+ &windows;
+ &server;
+ &debugging;
+ &donts;
+ &suggestions;
+ </CONTENTS>
+</FAQ>
\ No newline at end of file
/trunk/cljs/index.xml
Property changes:
Added: svn:keywords
## -0,0 +1 ##
+LastChangedDate LastChangedRevision LastChangedBy Id
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/faq.css
===================================================================
--- trunk/cljs/faq.css (nonexistent)
+++ trunk/cljs/faq.css (revision 45)
@@ -0,0 +1,229 @@
+/*
+Updated 2009-06-14 Garrett Smith
+*/
+
+
+a {
+ text-decoration: none;
+ color: #002288;
+ background: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+a[href^="http:"],
+a[href^="https:"],
+a[href^="news:"]
+{
+ padding-right: 13px;
+ background: transparent url(/media/video/img/external.png) no-repeat right center;
+}
+
+a[href^="http://PointedEars.de/"],
+a[href^="https://PointedEars.de/"]
+{
+ padding-right: 0;
+ background: none;
+}
+
+html {
+ font-family: sans-serif;
+ font-size: 90%;
+ background: #F6f6f6;
+ color : #000;
+}
+
+body {
+ margin: 1em;
+ border-bottom: 1px solid #ccc;
+}
+
+.preSample {
+ background-color : #f9eff0;
+ line-height : 200%;
+ border : #bb7799 1px solid;
+}
+
+pre {
+ font-family : monospace;
+ background-color : #fFF9f9;
+ border : #bb7799 1px solid;
+ color : #440011;
+ font-size : 100%;
+ padding : 5px 5px 5px 10px;
+}
+
+h1 {
+ font-size : 160%;
+}
+
+h2 {
+ font-size : 140%;
+}
+
+h3 {
+ font-size : 113%;
+}
+
+h2 a, h3 a, h2 a:hover, h3 a:hover {
+ color: inherit;
+ text-decoration: none;
+}
+
+.section h3 {
+ margin-top: 0;
+}
+
+h4 {
+ font-size : 110%;
+}
+
+h5 {
+ font-size : 100%;
+}
+
+code {
+ color : #550011;
+ font-family : monospace;
+ margin: 0em 0.1em;
+}
+
+/** EcmaScript Code Examples */
+/* keywords, if, with, var, et c */
+.keyword {
+ color: #00f;
+ font-weight: 800;
+}
+
+/* string literals */
+.q {
+ color: #900;
+}
+
+ul.linkList {
+ background-color : #eeeeee;
+ border : #999999 1px solid;
+ color : #000000;
+ font-size : 100%;
+ padding : 0.2em;
+ list-style: none;
+}
+
+ul.linkList li {
+ margin: .2em;
+}
+
+ul.horizontal {
+ float: left;
+ margin: 0 0 1em 0;
+ padding-left: 0;
+ list-style: none;
+}
+
+ul.horizontal li {
+ float: left;
+ margin-left: 0;
+ margin-right: 0.5em;
+}
+
+#faqList {
+ font-size: 120%;
+ list-style: none;
+ padding-left: 0;
+ margin-left: 0;
+}
+
+#faqList li {
+ margin-top: .3em;
+ margin-bottom: .3em;
+}
+
+#faqList ul {
+ font-size: 83%;
+ list-style: none;
+ padding-left: 0;
+ padding-top: 0;
+ margin-left: 1em;
+ color: #333;
+}
+
+.linkListSample {
+ background-color : #eeeeff;
+ line-height : 200%;
+ border : #9999bb 1px solid;
+}
+
+dd {
+ margin: 3px 2em;
+ padding: 0;
+}
+
+#nav {
+ clear: both;
+}
+
+#readerViewToggle {
+ margin-left: 34%;
+ text-align: center;
+ position: absolute;
+ margin-top: -3em;
+ background: #fff;
+ border: 1px solid #CCC;
+ padding: 0.1em 0.2em;
+}
+
+#readerViewToggle * {
+ cursor: pointer;
+ display: block;
+ white-space: nowrap;
+}
+
+#readerViewToggle img {
+ font-size: 24px;
+ height: 33px;
+ width: 27px;
+ margin: auto;
+}
+
+.readerView #faqList {
+ width: 40%;
+ background: #fcfcfc;
+ border: 1px solid #eee;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ padding: 8px;
+ float: left;
+ margin-right: 22px;
+}
+
+.section {
+ padding-top: 1.2em;
+}
+
+.readerView .section {
+ display: none;
+ float: left;
+ width:56%;
+}
+
+#builtInsList dd {
+ margin-right: 0;
+ margin-left: 1em;
+ display: inline;
+}
+
+#builtInsList dt {
+ font-weight: 700;
+}
+
+#pageWarning {
+ background-color: #fff3dd;
+ color: #321;
+ border: 1ex solid #fc9;
+ font-size: larger;
+ font-weight: bold;
+ padding: 1em;
+ margin: 1em 3em;
+}
/trunk/cljs/faq.css
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/backup/index.html
===================================================================
--- trunk/cljs/backup/index.html (nonexistent)
+++ trunk/cljs/backup/index.html (revision 45)
@@ -0,0 +1,2110 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="DCTERMS.language" scheme="RFC1766" content="en">
+<meta name="DC.title" content="comp.lang.javascript Frequently Asked Questions">
+<meta name="DCTERMS.subject" content="Frequently asked questions in the Usenet newsgroup comp.lang.javascript">
+<meta name="DC.format" content="text/html">
+<meta name="DC.type" content="Text">
+<meta name="DC.creator" content="Jim Ley">
+<meta name="DC.publisher" content="Garrett Smith">
+<META name="DC.Publisher.Address" content="dhtmlkitchen&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">
+<meta name="DCTERMS.modified" content="2010-10-08">
+<meta name="DCTERMS.audience" content="Programmers, web developers">
+<meta name="DC.description" content="Javascript Frequently Asked Questions">
+<meta name="DC.identifier" content="http://jibbering.com/faq">
+<meta name="DC.source" content="http://www.ecma-international.org/publications/standards/Ecma-262.htm">
+<meta name="DC.source" content="news:comp.lang.javascript">
+<meta name="DC.source" content="https://developer.mozilla.org/en/JavaScript">
+<meta name="DC.source" content="http://msdn.microsoft.com/en-us/library/hbxc2t98%28VS.85%29.aspx">
+<meta name="DC.source" content="http://msdn.microsoft.com/en-us/library/ms533050%28VS.85%29.aspx">
+<meta name="DC.rights" content="copyright contributors, comp.lang.javascript">
+<link rel="StyleSheet" href="faq.css" type="text/css" media="screen">
+<title> comp.lang.javascript FAQ</title>
+</head>
+ <body>
+<h1> comp.lang.javascript FAQ</h1>
+<p>Version 32.2, Updated 2010-10-08, by Garrett Smith</p><div id="nav"><a href="notes/">FAQ Notes</a></div>
+<ul id='faqList'>
+<li>1 <a href='#meta'>Meta-FAQ meta-questions</a>
+
+<ul>
+<li>1.1 <a href='#newsgroups'>Which newsgroups deal with javascript?</a></li>
+<li>1.2 <a href='#appropriateQuestions'>What questions are on-topic for comp.lang.javascript?</a></li>
+<li>1.3 <a href='#posting'>What should I do before posting to comp.lang.javascript?</a></li>
+<li>1.4 <a href='#noAnswer'>Why was my post not answered?</a></li>
+</ul></li><li>2 <a href='#tips'>Language Overview</a>
+
+<ul>
+<li>2.1 <a href='#ecma'>What is ECMAScript?</a></li>
+<li>2.2 <a href='#jScript'>What is JScript?</a></li>
+<li>2.3 <a href='#dom'>What is the Document Object Model (DOM)?</a></li>
+<li>2.4 <a href='#localization'>Internationalisation and Localisation in javascript</a></li>
+<li>2.5 <a href='#futureEcmaScript'>What does the future hold for ECMAScript?</a></li>
+</ul></li><li>3 <a href='#ecmascriptResources'>Javascript Resources</a>
+
+<ul>
+<li>3.1 <a href='#books'>What books are recommended for javascript?</a></li>
+<li>3.2 <a href='#onlineResources'>What online resources are available?</a></li>
+<li>3.3 <a href='#libraryResources'>Javascript Libraries</a></li>
+</ul></li><li>4 <a href='#functions'>Functions</a>
+
+<ul>
+<li>4.1 <a href='#scope'>What is (function(){ /*...*/ })() ?</a></li>
+<li>4.2 <a href='#functionStatement'>What is a function statement?</a></li>
+</ul></li><li>5 <a href='#dates'>Dates</a>
+
+<ul>
+<li>5.1 <a href='#formatDate'>How do I format a Date object with javascript?</a></li>
+<li>5.2 <a href='#parseDate'>How can I create a Date object from a String?</a></li>
+</ul></li><li>6 <a href='#numbers'>Numbers</a>
+
+<ul>
+<li>6.1 <a href='#formatNumber'>How do I format a Number as a String with exactly 2 decimal places?</a></li>
+<li>6.2 <a href='#binaryNumbers'>Why does simple decimal arithmetic give strange results?</a></li>
+<li>6.3 <a href='#parseIntBase'>Why does K = parseInt('09') set K to 0?</a></li>
+<li>6.4 <a href='#typeConvert'>Why does 1+1 equal 11? or How do I convert a string to a number?</a></li>
+<li>6.5 <a href='#randomNumber'>How do I generate a random integer from 1 to n?</a></li>
+</ul></li><li>7 <a href='#objects'>Objects</a>
+
+<ul>
+<li>7.1 <a href='#nativeObject'>What is a native object?</a></li>
+<li>7.2 <a href='#builtInObject'>What is a built-in object?</a></li>
+<li>7.3 <a href='#hostObject'>What is a host object?</a></li>
+<li>7.4 <a href='#eval'>When should I use eval?</a></li>
+<li>7.5 <a href='#propertyAccessAgain'>How do I access a property of an object using a string?</a></li>
+</ul></li><li>8 <a href='#strings'>Strings and RegExp</a>
+
+<ul>
+<li>8.1 <a href='#trimString'>How do I trim whitespace?</a></li>
+</ul></li><li>9 <a href='#domRef'>DOM and Forms</a>
+
+<ul>
+<li>9.1 <a href='#formControlAccess'>How do I get the value of a form control?</a></li>
+<li>9.2 <a href='#propertyAccess'>My element is named myselect[], how do I access it?</a></li>
+<li>9.3 <a href='#globalPollution'>Why doesn't the global variable &quot;divId&quot; always refer to the element with id=&quot;divId&quot;?</a></li>
+<li>9.4 <a href='#updateContent'>How do I modify the content of the current page?</a></li>
+<li>9.5 <a href='#accessElementBeforeDefined'>Why does my code fail to access an element?</a></li>
+<li>9.6 <a href='#testCookie'>How can I see in javascript if a web browser accepts cookies?</a></li>
+</ul></li><li>10 <a href='#windows'>Windows and Frames</a>
+
+<ul>
+<li>10.1 <a href='#disableBackButton'>How can I disable the back button in a web browser?</a></li>
+<li>10.2 <a href='#frameRef'>How do I access a frame's content?</a></li>
+<li>10.3 <a href='#getWindowSize'>How do I find the size of the window?</a></li>
+<li>10.4 <a href='#isWindowOpen'>How do I check to see if a child window is open, before opening another?</a></li>
+<li>10.5 <a href='#printFrame'>Why does framename.print() not print the correct frame in IE?</a></li>
+<li>10.6 <a href='#windowClose'>How do I close a window and why does it not work on the first one?</a></li>
+<li>10.7 <a href='#permissionDenied'>Why do I get permission denied when accessing a frame/window?</a></li>
+<li>10.8 <a href='#setTimeout'>How do I make a 10 second delay?</a></li>
+<li>10.9 <a href='#printSettings'>How do I change print settings for window.print()?</a></li>
+<li>10.10 <a href='#changeBrowserDialog'>How do I change the confirm box to say yes/no or default to cancel?</a></li>
+<li>10.11 <a href='#fileDownload'>How do I prompt a &quot;Save As&quot; dialog for an accepted mime type?</a></li>
+<li>10.12 <a href='#modifyChrome'>How do I modify the current browser window?</a></li>
+<li>10.13 <a href='#target'>How do I POST a form to a new window?</a></li>
+<li>10.14 <a href='#openWindow'>How do I open a new window with javascript?</a></li>
+</ul></li><li>11 <a href='#ajaxRef'>Ajax and Server Communication</a>
+
+<ul>
+<li>11.1 <a href='#ajax'>What is Ajax?</a></li>
+<li>11.2 <a href='#downloadPage'>How do I download a page to a variable?</a></li>
+<li>11.3 <a href='#getServerVariable'>How do I get a jsp/php variable into client-side javascript?</a></li>
+<li>11.4 <a href='#sessionExpired'>How do I log-out a user when they leave my site?</a></li>
+<li>11.5 <a href='#runServerScript'>How do I run a server side script?</a></li>
+<li>11.6 <a href='#noCache'>How do I force a reload from the server/prevent caching?</a></li>
+<li>11.7 <a href='#ajaxCache'>Why is my Ajax page not updated properly when using an HTTP GET request in Internet Explorer?</a></li>
+</ul></li><li>12 <a href='#debugging'>Debugging</a>
+
+<ul>
+<li>12.1 <a href='#javascriptErrors'>How do I get my browser to report javascript errors?</a></li>
+</ul></li><li>13 <a href='#doNotTry'>Things not to attempt in a browser</a>
+
+<ul>
+<li>13.1 <a href='#detectBrowser'>How do I detect Opera/Safari/IE?</a></li>
+<li>13.2 <a href='#preventAccess'>How can I prevent access to a web page by using javascript?</a></li>
+<li>13.3 <a href='#hideSource'>How do I protect my javascript code?</a></li>
+<li>13.4 <a href='#disableRightClick'>How do I suppress a context menu (right-click menu)?</a></li>
+<li>13.5 <a href='#readFile'>How can I access the client-side filesystem?</a></li>
+<li>13.6 <a href='#javascriptURI'>I have &lt;a href=&quot;javascript:somefunction()&quot;&gt; what ... ?</a></li>
+</ul></li><li>14 <a href='#comments'>Comments and Suggestions</a>
+
+<ul>
+<li>14.1 <a href='#FAQENTRY'>Why do some posts have &lt;FAQENTRY&gt; in them?</a></li>
+<li>14.2 <a href='#makeSuggestion'>How do I make a suggestion?</a></li>
+</ul></li></ul><div id='meta' class='section'><h2 id='FAQ1'>1 Meta-FAQ meta-questions</h2>
+<p>
+
+This is the <em>comp.lang.javascript</em> meta-FAQ, 32.2. The latest
+version is available at <a href="http://jibbering.com/faq/" >http://jibbering.com/faq/</a> in HTML form.
+</p> <p>
+
+Each day, one section of the FAQ is posted for review and questions,
+and as a reminder that the FAQ is available.
+</p> <p>
+
+For additional explanation and detail relating to some aspects
+of the FAQ, please see the
+<a href="notes/" >FAQ Notes</a>.
+It has been provided separately to avoid increasing the size of
+the FAQ to a point where it would be unreasonable to post it to
+the group.
+</p> <p>
+
+Code examples in this FAQ use <a href="http://jsdoctoolkit.org/" >JSDoc Toolkit</a> comments.
+</p> </div><div id='newsgroups' class='section'><h3 id='FAQ2_1'>1.1 Which newsgroups deal with javascript?</h3><p>
+
+The official Big 8 Usenet newsgroup dealing with javascript is
+ <a href="news:comp.lang.javascript">comp.lang.javascript</a>.
+Some "language" hierarchies also have *.comp.lang.javascript groups.
+ </p> <p>
+
+c.l.js is an unmoderated newsgroup.
+ </p> </div>
+<div id='appropriateQuestions' class='section'><h3 id='FAQ2_2'>1.2 What questions are on-topic for comp.lang.javascript?</h3><p>
+
+The comp.lang.javascript newsgroup deals with ECMAScript
+languages, so any questions about JavaScript or JScript are
+welcome. However, the majority of questions sent to this group
+relates to javascript in a web browser. If you are experiencing
+issues with a particular browser, or the host is not a browser
+at all, please make this information clear.
+ </p> <p>
+
+Javascript and Java are two completely different languages.
+Java questions should be asked in one of the comp.lang.java.*
+newsgroups; they are not appropriate for c.l.js (as Java and
+javascript are distinct programming languages with only
+superficial similarities due to sharing a C-like syntax and
+some of the characters in their names).
+ </p> <p>
+
+Questions dealing with other scripting languages, such as
+VBScript, PerlScript or CGI scripting are also off-topic,
+as are HTML-only or CSS-only questions.
+ </p> <p>
+
+Questions that are specific to Microsoft's JScript may also
+be appropriately asked at:
+ <a href="news:microsoft.public.scripting.jscript">microsoft.public.scripting.jscript</a></p> <p>
+
+The comp.lang.javascript newsgroup charter is included in
+<a href="faq_notes/cljs_charter.html" >faq_notes/cljs_charter.html</a>.
+ </p> </div>
+<div id='posting' class='section'><h3 id='FAQ2_3'>1.3 What should I do before posting to comp.lang.javascript?</h3><p>
+
+Before posting to c.l.js, you should read this document.
+You should also check the <a href="#onlineResources" >Resources section</a>.
+ </p>
+<h4 id='ask'>How to Ask a Question</h4>
+
+<ul>
+ <li>
+State your question clearly and concisely.
+ </li>
+ <li>
+Use the Subject: line to show the type of problem you have but
+include the question in the body as well.
+ </li>
+ <li>
+For a more detailed explanation of formatting, see
+ <a href="notes/posting/" >&quot;Posting Questions and Replies to comp.lang.javascript&quot;</a>.
+ </li></ul>
+<h4 id='reply'>Replying</h4>
+
+<ul>
+ <li>
+Quote only relevant parts of earlier messages, and add your
+comments below each quoted section
+(<a href="http://www.ietf.org/rfc/rfc1855.txt" >FYI28/RFC1855</a>).
+ </li>
+ <li>
+Link to specific sections of the FAQ that are relevant.
+ </li>
+ <li>
+Avoid being unnecessarily rude, but do not complain about other rude posts.
+ </li>
+ <li>
+Don't quote signatures.
+ </li></ul>
+<h4 id='postCode'>Posting Code</h4>
+
+<ul>
+ <li>
+Remove everything that does not contribute to the problem (images,
+markup, other scripts, etc).
+ </li>
+ <li>
+Validate the HTML and CSS <a href="http://validator.w3.org/" >http://validator.w3.org/</a>, <a href="http://jigsaw.w3.org/css-validator/" >http://jigsaw.w3.org/css-validator/</a>.
+ </li>
+ <li>
+Make sure the code is executable as transmitted.
+ </li>
+ <li>
+Format lines to 72 characters; indent with 2-4 spaces (not tabs).
+ </li>
+ <li>
+State what you expect the code to do.
+ </li>
+ <li>
+Mention the platforms, browsers, and versions.
+ </li>
+ <li>
+See also the <a href="#debugging" >FAQ section on debugging</a>.
+ </li>
+ <li>
+Post in plain-text only. Do not encode it. Do not attach files.
+ </li>
+ <li>
+If the code is more than about 100 lines, provide a URL in addition.
+ </li>
+ <li>
+Do not multi-post; cross-post if necessary
+(<a href="http://en.wikipedia.org/wiki/Cross-post" >Wikipedia description</a>).
+ </li></ul>
+<h4 id='doNotPost'>What Not to Post</h4>
+
+<ul>
+ <li>
+Do not post job postings. Job postings should go to
+an appropriate regional jobs group.
+ </li>
+ <li>
+Do not post copyright material without permission
+from the copyright holder.
+ </li></ul><p>
+
+Relevant announcements are welcome, but no more often than once
+per major release, as a short link to the product's webpage.
+ </p> </div>
+<div id='noAnswer' class='section'><h3 id='FAQ2_4'>1.4 Why was my post not answered?</h3><p>
+
+This could be for several reasons:
+ </p>
+<ul> <li>
+It was a variation of a frequently asked question and was
+therefore ignored by everyone.
+ </li>
+<li>
+Nobody knows the answer.
+ </li>
+<li>
+The person with the answer has not seen the post.
+ </li>
+<li>
+It might not be possible to do what you want to do but perhaps
+readers of c.l.js are reluctant to answer your post in the negative
+when they are not convinced that it cannot be done.
+ </li>
+<li>
+The question was not asked clearly enough, or did not included
+enough information to be answered.
+ </li>
+<li>
+The questioner did not realise the need to read the group, for a
+few days, to see the answers posted there.
+ </li>
+<li> You ignored the <a href="#posting" >section on posting</a> </li>
+</ul>
+<p>
+If it is not one of these, then after a few days consider
+reposting after checking <a href="http://groups.google.com/group/comp.lang.javascript/topics" >http://groups.google.com/group/comp.lang.javascript/topics</a>
+for replies. Make sure the post is phrased well, and everything
+needed to answer is correct, and the subject is appropriate.
+ </p> </div>
+<div id='tips' class='section'><h2 id='FAQ2'>2 Language Overview</h2>
+</div><div id='ecma' class='section'><h3 id='FAQ2_6'>2.1 What is ECMAScript?</h3><p>
+ <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm" >ECMA-262</a>
+is the international standard that current language implementations
+(JavaScript&trade;, JScript etc.) are based on.
+
+ </p> <p>
+ <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm" >ECMA-262</a>
+defines the language Syntax, Types, Keywords, Operators, and built-in
+objects. The ECMAScript specification is the reference to determine the
+expected behavior of a program. ECMAScript does not define any host
+objects, such as <code>document</code>, <code>window</code>, or <code>ActiveXObject</code>.
+ </p> <p>
+
+ECMA-327 defines the Compact Profile of ECMAScript by
+describing the features from ECMA 262 that may be omitted in some
+resource-constrained environments.
+<a href="http://www.ecma-international.org/publications/standards/Ecma-327.htm" >http://www.ecma-international.org/publications/standards/Ecma-327.htm</a></p> <p>
+
+The most widely supported edition of ECMA-262 is the 3rd edition (1999).
+There is fair support for this edition in JScript 5.5+ (buggy) and good
+support JavaScript 1.5.
+</p> <p>
+
+The term "javascript" is used as a common name for all dialects of ECMAScript.
+ </p> </div>
+<div id='jScript' class='section'><h3 id='FAQ2_7'>2.2 What is JScript?</h3><p>
+
+JScript is Microsoft's implementation of ECMAScript.
+ </p> <p>
+
+Questions that are specific to Microsoft's JScript may also
+be appropriately asked at:
+ <a href="news:microsoft.public.scripting.jscript">microsoft.public.scripting.jscript</a>.
+ </p> </div>
+<div id='dom' class='section'><h3 id='FAQ2_9'>2.3 What is the Document Object Model (DOM)?</h3><p>
+
+The
+<dfn>Document Object Model</dfn> (DOM) is a interface-based model for <code>Document</code>
+objects. The DOM allows scripts to dynamically access and update a
+document's content, style, and event handlers.
+</p> <p>
+
+The DOM is <em>not</em> part of the ECMAScript programming language.
+</p> <p>
+
+Official DOM standards are defined by the World Wide Web Consortium.
+Scriptable browsers also have
+<dfn>proprietary</dfn> DOM features (<a href="http://msdn.microsoft.com/en-us/library/ms533050(VS.85).aspx" >MSDN</a>, <a href="https://developer.mozilla.org/en/DOM_Client_Object_Cross-Reference" >MDC</a>),
+such as <code>document.writeln()</code>.
+ </p> <p>
+
+Also see the section on <a href="#domRef" >DOM and Forms</a>.
+</p><ul class='linkList'><li><a href="#onlineResources" >c.l.js DOM Resources</a></li>
+<li><a href="http://www.w3.org/DOM/faq.html" >W3C DOM FAQ</a></li>
+<li><a href="http://www.w3.org/DOM/" >W3C DOM </a></li>
+<li><a href="https://developer.mozilla.org/en/Gecko_DOM_Reference/Introduction#What_is_the_DOM.3F" >MDC: What is the DOM?</a></li>
+</ul> </div>
+<div id='localization' class='section'><h3 id='FAQ2_10'>2.4 Internationalisation and Localisation in javascript</h3><p>
+
+<dfn>Internationalisation</dfn> means using one form which is everywhere both
+acceptable and understood. Any international standard not supported by
+default can be coded for.
+ </p> <p>
+
+For example, there is an International Standard for numeric Gregorian
+date format; but none for decimal and thousands separators.
+ </p> <p>
+
+<dfn>Localisation</dfn> is the process of adapting software for a specific region
+or language by adding locale-specific components and translating text. It
+cannot work well in general, because it requires a knowledge of all
+preferences and the ability to choose the right one, in an environment
+where many systems are inappropriately set anyway.
+ </p> <p>
+
+ECMAScript has a few
+<dfn>localisation</dfn> features. The various
+<code>toString()</code> methods are all implementation dependent,
+but tend to use either UK or US settings (not necessarily correctly).
+ECMAScript Ed. 3 introduced some capabilities, including the
+<code>toLocaleString()</code>method which should create a string
+based on the host's locale.
+ </p> <p>
+
+ECMAScript 5th Edition introduces limited ISO 8601 capabilities with
+<code>Date.prototype.toISOString()</code> and new behavior for <code>Date.parse()</code>.
+</p> </div>
+<div id='futureEcmaScript' class='section'><h3 id='FAQ2_12'>2.5 What does the future hold for ECMAScript?</h3><p>
+
+The 5th edition of ECMAScript was approved on 2009-12-04. There is some
+support in implementations released before approval date (JScript 5.8,
+JavaScript 1.8, JavaScriptCore).
+http://www.ecma-international.org/publications/standards/Ecma-262.htm
+</p><ul class='linkList'><li><a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm" >http://www.ecma-international.org/publications/standards/Ecma-262.htm</a></li>
+</ul> </div>
+<div id='ecmascriptResources' class='section'><h2 id='FAQ3'>3 Javascript Resources</h2>
+</div><div id='books' class='section'><h3 id='FAQ3_1'>3.1 What books are recommended for javascript?</h3><p>
+
+Most javascript books have been found to contain so many technical
+errors that consensus recommendations have not emerged from the group.
+ </p> <p>
+
+The following books have been considered to have value by some
+individuals on c.l.js. The reviews of these books are provided:
+ </p>
+<ul>
+ <li> <em>&quot;JavaScript: The Definitive Guide,&quot;</em> 5th Edition, by David Flanagan
+
+<ul> <li> Published: 2006-08 </li>
+<li> Pages: 1018 </li>
+<li> Errata: <a href="http://oreilly.com/catalog/9780596101992/errata/" >http://oreilly.com/catalog/9780596101992/errata/</a> </li>
+<li> Discussed in:
+
+<ul> <li> <a href="http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/7283898f77fd2a66/9252aa024e058dea#c5f145ae807c918e" >FAQ Update 9.85 Dated 2007-08-31</a> </li>
+</ul>
+ </li>
+</ul>
+ </li>
+ <li> <em>"JavaScript, The Good Parts,"</em> 1st Edition, by Douglas Crockford
+
+<ul> <li> Published: 2008-05 </li>
+<li> Pages: 170 </li>
+<li> Errata: <a href="http://oreilly.com/catalog/9780596517748/errata/" >http://oreilly.com/catalog/9780596517748/errata/</a> </li>
+<li> Discussed in:
+
+<ul> <li> <a href="http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/d084d2109f7b4ec7#" >Crockford's 'The Good Parts': a short review</a> </li>
+<li> <a href="http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/db1e49ab113aa05c/3987eac87ad27966#3987eac87ad27966" >FunctionExpression's and memory consumptions</a> </li>
+<li> <a href="http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/6a41f7835ee728de/da5ccfc65e2df64a#da5ccfc65e2df64a" >FAQ Topic - What books are recommended for javascript? (2008-12-02)</a> </li>
+<li> <a href="http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/3a08fb741525ab6d/" >Augmenting functions</a> </li>
+<li> <a href="http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/bf26be6e63494ee2/acb733a1c35f6ce5#ee9e4ee29e658d5d" >Crockford's JavaScript, The Good Parts (a book review).</a> </li>
+<li> <a href="http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/df602506ee48b400/e65e00f5cad07676#e65e00f5cad07676" >Closures Explained</a> </li>
+<li> <a href="http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/acadf1b22b219433/4f69a95607d0b3ae#4f69a95607d0b3ae" >Javascript library development</a> </li>
+</ul>
+ </li>
+</ul>
+ </li></ul></div>
+<div id='onlineResources' class='section'><h3 id='FAQ3_2'>3.2 What online resources are available?</h3>
+<h4 id='ecmaResources'>ECMAScript</h4>
+
+<dl>
+ <dt>
+The Official ECMAScript Specification
+ </dt>
+ <dd> <a href="[ECMA-262] http://www.ecma-international.org/publications/standards/Ecma-262-arch.htm" >[ECMA-262] http://www.ecma-international.org/publications/standards/Ecma-262-arch.htm</a> </dd>
+ <dt>
+[ISO16262] ISO/IEC 16262, Second Edition 2002-06-01 : ISO Standard matching
+ECMA-262 3rd Edition, with corrections.
+ </dt>
+ <dd> <a href="http://standards.iso.org/ittf/PubliclyAvailableStandards/c033835_ISO_IEC_16262_2002(E).zip" >http://standards.iso.org/ittf/PubliclyAvailableStandards/c033835_ISO_IEC_16262_2002(E).zip</a> </dd>
+ <dt>
+ [MS-ES3]: Internet Explorer ECMA-262 ECMAScript Language Specification Standards Support
+ </dt>
+ <dd> <a href="http://msdn.microsoft.com/en-us/library/ff520996%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ff520996%28VS.85%29.aspx</a> </dd>
+ <dd> <a href="res/%5BMS-ES3%5D.pdf" >res/%5BMS-ES3%5D.pdf</a> (local alias) </dd>
+ <dt>
+ [MS-ES3EX]: Microsoft JScript Extensions to the ECMAScript Language Specification Third Edition
+ </dt>
+ <dd> <a href="http://msdn.microsoft.com/en-us/library/ff521046%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ff521046%28VS.85%29.aspx</a> </dd>
+ <dd> <a href="res/%5BMS-ES3EX%5D.pdf" >res/%5BMS-ES3EX%5D.pdf</a> (local alias) </dd>
+ <dt> ECMAScript on Wikipedia
+ </dt>
+ <dd> <a href="http://en.wikipedia.org/wiki/ECMAScript" >http://en.wikipedia.org/wiki/ECMAScript</a> </dd></dl>
+<h4 id='domResources'>W3C DOM</h4>
+
+<dl>
+ <dt>
+DOM Level 1 ECMAScript Binding
+ </dt>
+ <dd> <a href="http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html" >http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html</a> </dd>
+ <dt>
+DOM Level 2 ECMAScript Binding
+ </dt>
+ <dd> <a href="http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html" >http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html</a> </dd>
+ <dt>
+DOM Level 2 Events
+ </dt>
+ <dd> <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html" >http://www.w3.org/TR/DOM-Level-2-Events/events.html</a> </dd>
+ <dt>
+DOM Level 2 Style
+ </dt>
+ <dd> <a href="http://www.w3.org/TR/DOM-Level-2-Style/" >http://www.w3.org/TR/DOM-Level-2-Style/</a> </dd>
+ <dt>
+DOM Level 3 ECMAScript Binding
+ </dt>
+ <dd> <a href="http://www.w3.org/TR/DOM-Level-3-Core/ecma-script-binding.html" >http://www.w3.org/TR/DOM-Level-3-Core/ecma-script-binding.html</a> </dd></dl>
+<h4 id='browserResources'>Browser Documentation</h4>
+
+<dl>
+ <dt>
+Mozilla
+ </dt>
+ <dd> JavaScript:
+<a href="http://developer.mozilla.org/en/docs/JavaScript" >http://developer.mozilla.org/en/docs/JavaScript</a> </dd>
+ <dd> Gecko DOM Reference:
+<a href="http://developer.mozilla.org/en/docs/Gecko_DOM_Reference" >http://developer.mozilla.org/en/docs/Gecko_DOM_Reference</a> </dd>
+ <dt>
+Microsoft
+ </dt>
+ <dd> HTML and DHTML Reference:
+<a href="http://msdn.microsoft.com/en-us/library/ms533050.aspx" >http://msdn.microsoft.com/en-us/library/ms533050.aspx</a> </dd>
+ <dd> JScript Language Reference:
+<a href="http://msdn.microsoft.com/en-us/library/hbxc2t98%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/hbxc2t98%28VS.85%29.aspx</a> </dd>
+ <dd> Scripting:
+<a href="http://msdn.microsoft.com/en-us/library/ms950396.aspx" >http://msdn.microsoft.com/en-us/library/ms950396.aspx</a> </dd>
+ <dt>
+Opera
+ </dt>
+ <dd> Web Specifications Support:
+<a href="http://www.opera.com/docs/specs/#ecmascript" >http://www.opera.com/docs/specs/#ecmascript</a> </dd>
+ <dd> JavaScript Support:
+<a href="http://www.opera.com/docs/specs/js/" >http://www.opera.com/docs/specs/js/</a> </dd>
+ <dd> ECMAScript Support:
+<a href="http://www.opera.com/docs/specs/js/ecma" >http://www.opera.com/docs/specs/js/ecma</a> </dd>
+ <dt>
+BlackBerry JavaScript Reference
+ </dt>
+ <dd> <a href="http://docs.blackberry.com/en/developers/deliverables/11849/" >http://docs.blackberry.com/en/developers/deliverables/11849/</a> </dd>
+ <dt>
+ICab InScript
+ </dt>
+ <dd> <a href="http://www.muchsoft.com/inscript/" >http://www.muchsoft.com/inscript/</a> </dd>
+ <dt> Apple Safari </dt>
+ <dd> Web Content Guide:
+<a href="http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariWebContent/Introduction/Introduction.html" >http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariWebContent/Introduction/Introduction.html</a> </dd>
+ <dt>
+Webkit
+ </dt>
+ <dd> Project Site: <a href="http://webkit.org/" >http://webkit.org/</a> </dd>
+ <dd>
+ Wiki: <a href="http://trac.webkit.org/wiki" >http://trac.webkit.org/wiki</a> </dd>
+ <dd> DOM Reference:
+<a href="http://developer.apple.com/Mac/library/documentation/AppleApplications/Reference/WebKitDOMRef/index.html#//apple_ref/doc/uid/TP40006089" >http://developer.apple.com/Mac/library/documentation/AppleApplications/Reference/WebKitDOMRef/index.html#//apple_ref/doc/uid/TP40006089</a> </dd>
+ <dt>
+Netscape 4 Client-Side JavaScript Reference
+ </dt>
+ <dd> <a href="http://docs.sun.com/source/816-6408-10/" >http://docs.sun.com/source/816-6408-10/</a> </dd>
+ <dt>
+Archived documentation for MSIE 3.x
+ </dt>
+ <dd> <a href="http://members.tripod.com/%7Ehousten/download/" >http://members.tripod.com/%7Ehousten/download/</a> </dd></dl>
+<h4 id='standaloneImplementations'>Standalone ECMAScript Implementations</h4>
+
+<dl>
+ <dt>
+Rhino: An open-source implementation of JavaScript written in Java
+ </dt>
+ <dd> <a href="http://www.mozilla.org/rhino/" >http://www.mozilla.org/rhino/</a> </dd>
+ <dt>
+Besen IDE: ECMAScript Edition 5 with IDE
+ </dt>
+ <dd> <a href="http://besen.sourceforge.net/" >http://besen.sourceforge.net/</a> </dd>
+ <dt>
+V8: Google's open source JavaScript engine
+ </dt>
+ <dd> <a href="http://code.google.com/p/v8/" >http://code.google.com/p/v8/</a> </dd>
+ <dt>
+SpiderMonkey: Mozilla's C implementation of JavaScript
+ </dt>
+ <dd> <a href="http://www.mozilla.org/js/spidermonkey/" >http://www.mozilla.org/js/spidermonkey/</a> </dd>
+ <dt>
+Digital Mars DMD Script, console and MS Active Script implementation of ECMAScript
+ </dt>
+ <dd> <a href="http://www.digitalmars.com/dscript/" >http://www.digitalmars.com/dscript/</a> </dd></dl>
+<h4 id='nonBrowserResources'>Other ECMAScript Implementations</h4>
+
+<dl>
+ <dt>
+Developing Dashboard Widgets: Apple Developer Connection
+ </dt>
+ <dd> <a href="http://developer.apple.com/macosx/dashboard.html" >http://developer.apple.com/macosx/dashboard.html</a> </dd>
+ <dt>
+Whitebeam Apache Module: Server Side JavaScript in Apache
+ </dt>
+ <dd> <a href="http://www.whitebeam.org/" >http://www.whitebeam.org/</a> </dd></dl></div>
+<div id='libraryResources' class='section'><h3>3.3 Javascript Libraries</h3><p>
+
+No javascript libraries are endorsed by this group. If you want help
+with using a library, visit that library's discussion group instead.
+ </p> </div>
+<div id='functions' class='section'><h2>4 Functions</h2>
+</div><div id='scope' class='section'><h3>4.1 What is (function(){ /*...*/ })() ?</h3><p>
+
+This is an anonymous
+<dfn>FunctionExpression</dfn> that is called
+immediately after creation.
+</p> <p>
+
+Variables declared inside a function are not accessible from
+outside the function. This can be useful, for example, to hide
+implementation details or to avoid polluting the global scope.
+</p><ul class='linkList'><li><a href="http://yura.thinkweb2.com/named-function-expressions/" >http://yura.thinkweb2.com/named-function-expressions/</a></li>
+<li><a href="notes/closures/" >notes/closures/</a></li>
+<li><a href="http://dmitrysoshnikov.com/ecmascript/chapter-5-functions/#question-about-surrounding-parentheses" >http://dmitrysoshnikov.com/ecmascript/chapter-5-functions/#question-about-surrounding-parentheses</a></li>
+</ul> </div>
+<div id='functionStatement' class='section'><h3>4.2 What is a function statement?</h3><p>
+
+The term
+<dfn>function statement</dfn> has been widely and wrongly used to
+describe a <code>FunctionDeclaration</code>. This is misleading because in ECMAScript,
+a <code>FunctionDeclaration</code> is not a
+<dfn>Statement</dfn>; there are places in a program
+where a
+<dfn>Statement</dfn> is permitted but a <code>FunctionDeclaration</code> is not. To add
+to this confusion, some implementations, notably Mozillas', provide a
+syntax extension called
+<dfn>function statement</dfn>. This is allowed under
+section 16 of ECMA-262, Editions 3 and 5.
+</p> <p>
+
+Example of nonstandard
+<dfn>function statement</dfn>:
+</p>
+<pre>
+// Nonstandard syntax, found in GMail source code. DO NOT USE.
+try {
+ // FunctionDeclaration not allowed in Block.
+ function Fze(b,a){return b.unselectable=a}
+ /*...*/
+} catch(e) { _DumpException(e) }
+</pre>
+ <p>
+
+Code that uses
+<dfn>function statement</dfn> has three known interpretations. Some
+implementations process <code>Fze</code> as a
+<dfn>Statement</dfn>, in order. Others, including
+JScript, evaluate <code>Fze</code> upon entering the execution context that it
+appears in. Yet others, notably DMDScript and default configuration of BESEN,
+throw a <code>SyntaxError</code>.
+</p> <p>
+
+For consistent behavior across implementations, <em>do not use function
+statement</em>; use either <code>FunctionExpression</code> or <code>FunctionDeclaration</code> instead.
+</p> <p>
+
+Example of <code>FunctionExpression</code> (valid):
+</p>
+<pre>
+var Fze;
+try {
+ Fze = function(b,a){return b.unselectable=a};
+ /*...*/
+} catch(e) { _DumpException(e) }
+</pre>
+<p>
+Example of <code>FunctionDeclaration</code> (valid):
+</p>
+<pre>
+// Program code
+function aa(b,a){return b.unselectable=a}
+</pre>
+ <p>
+ <!--
+Notable examples of the misuse of the term "function statement"
+can be seen in David Flanagan's "JavaScript: The Definitive Guide",
+Douglas Crockford's "JavaScript: The Good Parts", MDC documentation,
+JSLint error messages.
+--></p><ul class='linkList'><li><a href="example/functionStatement.html" >example/functionStatement.html</a></li>
+<li><a href="https://mail.mozilla.org/pipermail/es-discuss/2008-February/005314.html" >https://mail.mozilla.org/pipermail/es-discuss/2008-February/005314.html</a></li>
+<li><a href="http://groups.google.com/group/comp.lang.javascript/msg/aa9a32d0c6ae0342" >http://groups.google.com/group/comp.lang.javascript/msg/aa9a32d0c6ae0342</a></li>
+<li><a href="http://groups.google.com/group/comp.lang.javascript/msg/3987eac87ad27966" >http://groups.google.com/group/comp.lang.javascript/msg/3987eac87ad27966</a></li>
+<li><a href="http://nanto.asablo.jp/blog/2005/12/10/172622" >http://nanto.asablo.jp/blog/2005/12/10/172622</a></li>
+<li> (Article in Japanese)
+</li>
+</ul> </div>
+<div id='dates' class='section'><h2>5 Dates</h2>
+<p>
+
+ISO 8601 defines date and time formats. Some benefits include:
+</p>
+<ul>
+ <li> language-independent and unambiguous world-wide </li>
+ <li> sortable with a trivial string comparison </li>
+ <li> easily readable and writable by software </li>
+ <li> compatible with standards ISO 9075 and <a href="http://www.ietf.org/rfc/rfc3339.txt" >rfc 3339</a> </li></ul><p>
+
+The ISO Extended format for common date is <code>YYYY-MM-DD</code>, and for time is
+<code>hh:mm:ss</code>.
+</p> <p>
+
+For an event with an offset from UTC, use <code>YYYY-MM-DDThh:mm:ss&#177;hh:mm</code>.
+</p> <p>
+
+Never use a local date/time format for a non-local event. Instead, use
+UTC, as in <code>YYYY-MM-DDThh:mm:ssZ</code> (<code>Z</code> is the only letter suffix).
+</p> <p>
+
+The <code>T</code> can be omitted where that would not cause ambiguity. For
+rfc 3339 compliance, it may be replaced by a space and for SQL,
+it <em>must</em> be replaced by a single space.
+</p> <p>
+
+Year <code>0000</code> is unrecognized by some formats (XML Schema, <code>xs:date</code>).
+ </p><ul class='linkList'><li><a href="#onlineResources" >ECMA-262 Date.prototype, s. 15.9</a></li>
+<li><a href="http://www.cl.cam.ac.uk/~mgk25/iso-time.html" >A summary of the international standard date and time notation, by Markus Kuhn</a></li>
+<li><a href="http://en.wikipedia.org/wiki/ISO_8601" >http://en.wikipedia.org/wiki/ISO_8601</a></li>
+<li><a href="res/ISO_8601-2004_E.pdf" >ISO 8601:2004(E)</a></li>
+<li><a href="http://www.w3.org/QA/Tips/iso-date" >W3C QA Tip: Use international date format (ISO)</a></li>
+<li><a href="http://www.ietf.org/rfc/rfc3339.txt" >RFC 3339, Date and Time on the Internet: Timestamps
+</a></li>
+<li><a href="http://www.w3.org/TR/xmlschema-2/#dateTime" >http://www.w3.org/TR/xmlschema-2/#dateTime</a></li>
+</ul> </div><div id='formatDate' class='section'><h3 id='FAQ4_30'>5.1 How do I format a Date object with javascript?</h3><p>
+
+A local <code>Date</code> object where <code>0 &lt;= year &lt;= 9999</code> can be
+formatted to a common ISO 8601 format <code>YYYY-MM-DD</code> with:-
+ </p>
+<pre>
+ /** Formats a Date to YYYY-MM-DD (local time), compatible with both
+ * ISO 8601 and ISO/IEC 9075-2:2003 (E) (SQL 'date' type).
+ * @param {Date} dateInRange year 0000 to 9999.
+ * @throws {RangeError} if the year is not in range
+ */
+ function formatDate(dateInRange) {
+ var year = dateInRange.getFullYear(),
+ isInRange = year &gt;= 0 &amp;&amp; year &lt;= 9999, yyyy, mm, dd;
+ if(!isInRange) {
+ throw RangeError("formatDate: year must be 0000-9999");
+ }
+ yyyy = ("000" + year).slice(-4);
+ mm = ("0" + (dateInRange.getMonth() + 1)).slice(-2);
+ dd = ("0" + (dateInRange.getDate())).slice(-2);
+ return yyyy + "-" + mm + "-" + dd;
+ }
+ </pre>
+<ul class='linkList'><li><a href="http://www.merlyn.demon.co.uk/js-date9.htm" >http://www.merlyn.demon.co.uk/js-date9.htm</a></li>
+</ul> </div>
+<div id='parseDate' class='section'><h3>5.2 How can I create a Date object from a String?</h3><p>
+
+An Extended ISO 8601 local Date format <code>YYYY-MM-DD</code> can be parsed to a
+Date with the following:-
+</p>
+<pre>
+ /**Parses string formatted as YYYY-MM-DD to a Date object.
+ * If the supplied string does not match the format, an
+ * invalid Date (value NaN) is returned.
+ * @param {string} dateStringInRange format YYYY-MM-DD, with year in
+ * range of 0000-9999, inclusive.
+ * @return {Date} Date object representing the string.
+ */
+ function parseISO8601(dateStringInRange) {
+ var isoExp = /^\s*(\d{4})-(\d\d)-(\d\d)\s*$/,
+ date = new Date(NaN), month,
+ parts = isoExp.exec(dateStringInRange);
+
+ if(parts) {
+ month = +parts[2];
+ date.setFullYear(parts[1], month - 1, parts[3]);
+ if(month != date.getMonth() + 1) {
+ date.setTime(NaN);
+ }
+ }
+ return date;
+ }</pre>
+ </div>
+<div id='numbers' class='section'><h2>6 Numbers</h2>
+</div><div id='formatNumber' class='section'><h3 id='FAQ4_6'>6.1 How do I format a Number as a String with exactly 2 decimal places?</h3><p>
+
+When formatting money for example, to format 6.57634 to 6.58, 6.7 to
+6.50, and 6 to 6.00?
+ </p> <p>
+
+Rounding of x.xx5 is unreliable, as most numbers are not represented
+exactly. See also:
+<a href="#binaryNumbers" >Why does simple decimal arithmetic give strange results?</a></p> <p>
+
+The statement <code>n = Math.round(n * 100)/100</code> converts <code>n</code> to a <code>Number</code> value
+close to a multiple of <code>0.01</code>. However, there are some problems.
+Converting the number to a string <code>(n + "")</code>, does not give
+trailing zeroes. Rounding numbers that are very close to <code>x.5</code>, for example,
+<code>Math.round(0.49999999999999992)</code> results <code>1</code>.
+ </p> <p>
+
+ECMA-262 3rd Edition introduced <code>Number.prototype.toFixed</code>.
+There are bugs in JScript 5.8 and below with certain numbers, for example
+<code>0.007.toFixed(2)</code> incorrectly results <code>0.00</code>.
+ </p> <p>
+ </p>
+<pre>
+var numberToFixed =
+(function() {
+ return toFixedString;
+
+ function toFixedString(n, digits) {
+ var unsigned = toUnsignedString(Math.abs(n), digits);
+ return (n &lt; 0 ? "-" : "") + unsigned;
+ }
+
+ function toUnsignedString(m, digits) {
+ var t, s = Math.round(m * Math.pow(10, digits)) + "",
+ start, end;
+ if (/\D/.test(s)) {
+ return "" + m;
+ }
+ s = padLeft(s, 1 + digits, "0");
+ start = s.substring(0, t = (s.length - digits));
+ end = s.substring(t);
+ if(end) {
+ end = "." + end;
+ }
+ return start + end; // avoid "0."
+ }
+ /**
+ * @param {string} input: input value converted to string.
+ * @param {number} size: desired length of output.
+ * @param {string} ch: single character to prefix to s.
+ */
+ function padLeft(input, size, ch) {
+ var s = input + "";
+ while(s.length &lt; size) {
+ s = ch + s;
+ }
+ return s;
+ }
+})();
+
+// Test results
+document.writeln([
+ "numberToFixed(9e-3, 12) =&gt; " + numberToFixed(9e-3, 12),
+ "numberToFixed(1.255, 2) =&gt; " + numberToFixed(1.255, 2),
+ "numberToFixed(1.355, 2) =&gt; " + numberToFixed(1.355, 2),
+ "numberToFixed(0.1255, 3) =&gt; " + numberToFixed(0.1255, 3),
+ "numberToFixed(0.07, 2) =&gt; " + numberToFixed(0.07, 2),
+ "numberToFixed(0.0000000006, 1) =&gt; " + numberToFixed(0.0000000006, 1),
+ "numberToFixed(0.0000000006, 0) =&gt; " + numberToFixed(0.0000000006, 0)
+].join("\n"));
+</pre>
+<ul class='linkList'><li><a href="http://www.merlyn.demon.co.uk/js-round.htm" >http://www.merlyn.demon.co.uk/js-round.htm</a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/sstyff0z%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/sstyff0z%28VS.85%29.aspx</a></li>
+</ul> </div>
+<div id='binaryNumbers' class='section'><h3 id='FAQ4_7'>6.2 Why does simple decimal arithmetic give strange results?</h3><p>
+
+For example, <code>5 * 1.015</code> does not give exactly
+<code>5.075</code> and <code>0.06+0.01</code> does
+not give exactly <code>0.07</code> in javascript.
+ </p> <p>
+
+ECMAScript numbers are represented in binary as IEEE-754 (IEC 559)
+Doubles, with a resolution of 53 bits, giving an accuracy of
+15-16 decimal digits; integers up to just over <code>9e15</code> are
+precise, but few decimal fractions are. Given this, arithmetic
+is as exact as possible, but no more. Operations on integers
+are exact if the true result and all intermediates are integers
+within that range.
+ </p> <p>
+
+In particular, non-integer results should not normally be
+compared for equality; and non-integer computed results
+commonly need rounding; see <a href="#formatNumber" >How do I format a Number as a String with exactly 2 decimal places?</a></p><ul class='linkList'><li><a href="http://msdn.microsoft.com/en-us/library/7wkd9z69%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/7wkd9z69%28VS.85%29.aspx</a></li>
+<li><a href="http://www.merlyn.demon.co.uk/js-misc0.htm#DW4" >http://www.merlyn.demon.co.uk/js-misc0.htm#DW4</a></li>
+</ul> <p>
+
+Otherwise, use <code>Math.round</code> on the results of expressions which
+should be of integer value.
+ </p> </div>
+<div id='parseIntBase' class='section'><h3 id='FAQ4_12'>6.3 Why does K = parseInt('09') set K to 0?</h3><p>
+
+Method <code>parseInt</code> generally needs a second parameter, <code>radix</code>,
+for the base (from 2 to 36).
+ </p> <p>
+
+If <code>radix</code> is omitted, the base is determined by the contents of
+the string. Any string beginning with <code>'0x'</code> or <code>'0X'</code> represents a
+hexadecimal number. A string beginning with a leading 0 may be parsed as
+octal (as if <code>raxix</code> were 8), in ECMA-262 Ed 3 (octal digits are <code>0-7</code>).
+If string <code>'09'</code> is converted to <code>0</code>.
+ </p> <p>
+
+To force use of a particular base, use the <code>radix</code>
+parameter: <code>parseInt("09", base)</code>.
+
+ <!-- [omit]
+ If base 10 is desired,
+ the unary <ICODE>+</ICODE> operator can be an option. Example:
+ <ICODE>
+var s = '-09.1'; // Input string.
+var j = +s; // Convert to number. Result: -9.1
+var n = j|0; // Chop off decimal (convert ToInt32). Result: -9
+</ICODE>
+ [/omit] --></p> <p>
+ </p><ul class='linkList'><li><a href="http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/parseInt" >http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Functions/parseInt</a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/x53yedee%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/x53yedee%28VS.85%29.aspx</a></li>
+<li><a href="http://docs.sun.com/source/816-6408-10/toplev.htm#1064173" >http://docs.sun.com/source/816-6408-10/toplev.htm#1064173</a></li>
+<li><a href="notes/type-conversion/#tcPrIntRx" >notes/type-conversion/#tcPrIntRx</a></li>
+</ul> </div>
+<div id='typeConvert' class='section'><h3>6.4 Why does 1+1 equal 11? or How do I convert a string to a number?</h3><p>
+
+Variables are not typed; their values are. The conversion between a
+string and a number happens automatically.
+</p> <p>
+
+The addition operator (<code>+</code>) performs concatenation if either operand is a
+string, thus <code>"1" + 1</code> results <code>"11"</code>. To perform addition, you might need
+to first convert the string to a number. For example <code>+varname</code> or
+<code>Number(varname)</code> or <code>parseInt(varname, 10)</code> or
+<code>parseFloat(varname)</code>. Form control values are strings, as is the result
+from a <code>prompt</code> dialog. Convert these to numbers before performing
+addition: <code>+'1' + 1</code> results <code>2</code>.
+ </p><ul class='linkList'><li>
+Additional Notes: </li>
+<li><a href="notes/type-conversion/" >notes/type-conversion/</a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/67defydd%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/67defydd%28VS.85%29.aspx</a></li>
+</ul> </div>
+<div id='randomNumber' class='section'><h3 id='FAQ4_22'>6.5 How do I generate a random integer from 1 to n?</h3><p>
+ <code>Math.random()</code> returns a value <code>R</code> such that <code>0 &lt;= R &lt; 1.0</code>; therefore:
+ </p>
+<pre>
+ // positive integer expected
+ function getRandomNumber(n) {
+ return Math.floor(n * Math.random());
+ }
+</pre>
+<p>
+- gives an evenly distributed random integer in the range from
+ <code>0</code> to <code>n - 1</code> inclusive; use <code>getRandomNumber(n)+1</code> for <code>1</code> to <code>n</code>.
+ </p><ul class='linkList'><li><a href="http://msdn.microsoft.com/en-us/library/41336409%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/41336409%28VS.85%29.aspx</a></li>
+<li><a href="http://docs.sun.com/source/816-6408-10/math.htm" >http://docs.sun.com/source/816-6408-10/math.htm</a></li>
+<li>
+How to Deal and Shuffle, see in: </li>
+<li><a href="http://www.merlyn.demon.co.uk/js-randm.htm" >http://www.merlyn.demon.co.uk/js-randm.htm</a></li>
+</ul> </div>
+<div id='objects' class='section'><h2>7 Objects</h2>
+</div><div id='nativeObject' class='section'><h3>7.1 What is a native object?</h3><p>
+
+A
+<dfn>native object</dfn> is any object whose semantics are fully defined by
+ECMA-262.
+</p> <p>
+
+Some
+<dfn>native objects</dfn> are
+<dfn>built-in</dfn>; others, such as
+<dfn>user-defined</dfn> objects,
+may be constructed during the execution of an ECMAScript program.
+</p> <p>
+
+Example:
+</p>
+<pre>
+// Native built-in objects:
+var m = Math, // Built-in Math object.
+ slice = Array.prototype.slice, // Built-in native method.
+ o = {}, // Native user-defined object.
+ f = function(){}, // Native user-defined function.
+ d = new Date(),
+ a = [],
+ e = new Error("My Message.");
+ </pre>
+<p>
+See also:
+</p><ul class='linkList'><li><a href="http://dmitrysoshnikov.com/ecmascript/chapter-7-2-oop-ecmascript-implementation/" >http://dmitrysoshnikov.com/ecmascript/chapter-7-2-oop-ecmascript-implementation/</a></li>
+</ul> </div>
+<div id='builtInObject' class='section'><h3>7.2 What is a built-in object?</h3><p>
+
+ A
+<dfn>built-in</dfn> object is any object supplied by an ECMAScript
+ implementation, independent of the host environment, that is present
+ at the start of the execution of an ECMAScript program.
+ </p> <p>
+
+ECMA-262 3rd Edition defines the following
+<dfn>built-in</dfn> objects:
+</p>
+<dl id='builtInsList'>
+ <dt> Objects </dt>
+ <dd> <em>global</em>, Math </dd>
+ <dt> Constructors </dt>
+ <dd> Object, Function, Array, String, Boolean, Number, Date, RegExp </dd>
+ <dt> Errors </dt>
+ <dd> Error, Date, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError </dd>
+ <dt> Functions </dt>
+ <dd> eval, parseInt, parseFloat, isNaN, isFinite, decodeURI,
+ decodeURIComponent, encodeURI, encodeURIComponent </dd></dl><p>
+
+ECMA-262 Edition 5 defines also the built-in object <code>JSON</code>.
+</p> <p>
+
+Nonstandard
+<dfn>built-in</dfn> objects may include <code>RuntimeObject</code>,
+<code>String.prototype.link</code>, <code>CollectGarbage</code>, and more.
+</p> </div>
+<div id='hostObject' class='section'><h3 id='FAQ2_8'>7.3 What is a host object?</h3><p>
+
+A
+<dfn>host object</dfn> is any object supplied by the host environment to
+complete the execution environment of ECMAScript.
+</p> <p>
+
+A
+<dfn>host object</dfn> is not part of the ECMAScript implementation, but is
+exposed to the ECMAScript implementation.
+</p> <p>
+
+A
+<dfn>host object</dfn> may be implemented as a native ECMAScript object, however
+this is not required. For example, Internet Explorer implements many
+scriptable DOM objects as ActiveX Objects, often resulting in unexpected errors.
+</p> <p>
+
+Availability and behavior of a host object depends on the host environment.
+</p> <p>
+
+For example, in a browser, <code>XMLHttpRequest</code> might be available, with or
+without standard or proprietary features or events. Windows Script Host object model
+has the <code>WScript</code> object available.
+</p> <p>
+
+ For information on a particular host object, consult the pertinent
+ documentation available for the implementation(s). For web browsers,
+ this usually includes the w3c specifications as well as documentation
+ for that browser.
+ See also:
+
+</p><ul class='linkList'><li><a href="notes/code-guidelines/#hostObjects" >notes/code-guidelines/#hostObjects</a></li>
+<li><a href="http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting" >http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting</a></li>
+</ul> </div>
+<div id='eval' class='section'><h3 id='FAQ4_40'>7.4 When should I use eval?</h3><p>
+
+The <code>eval</code> function should <em>only</em> be used when it is necessary to
+evaluate a string supplied or composed at run-time; the string
+can be anything from a simple (but unpredictable) expression such
+as <code>"12 * 2.54"</code> to a substantial piece of javascript code.
+</p> <p>
+
+When <code>eval( '{"key" : 42}' )</code> is called, <code>{</code> is interpreted as a block of
+code instead of an object literal. Hence, the Grouping Operator (parentheses)
+is used to force <code>eval</code> to interpret the JSON as an object literal:
+<code>eval( '({"key" : 42})' );</code>.
+ </p><ul class='linkList'><li><a href="http://json.org/" >http://json.org/</a></li>
+<li><a href="#propertyAccessAgain" >How do I access a property of an object using a string?</a></li>
+<li><a href="notes/square-brackets/" >notes/square-brackets/</a></li>
+</ul> </div>
+<div id='propertyAccessAgain' class='section'><h3 id='FAQ4_39'>7.5 How do I access a property of an object using a string?</h3><p>
+
+There are two ways to access properties: dot notation and square bracket
+notation. What you are looking for is the square bracket notation in
+which the dot, and the identifier to its right, are replaced with a set
+of square brackets containing a string. The value of the string matches
+the identifier. For example:-
+</p>
+<pre>
+ //dot notation
+ var bodyElement = document.body;
+
+ //square bracket notation, using an expression
+ var bodyElement = document[&quot;bo&quot;+&quot;dy&quot;];</pre>
+<ul class='linkList'><li><a href="notes/square-brackets/" >notes/square-brackets/</a></li>
+</ul> </div>
+<div id='strings' class='section'><h2>8 Strings and RegExp</h2>
+</div><div id='trimString' class='section'><h3 id='FAQ4_16'>8.1 How do I trim whitespace?</h3><p>
+
+ECMAScript 5 defines <code>String.prototype.trim</code>. Where not supported,
+it can be added as a function that uses a
+<dfn>regular expression</dfn>:
+</p>
+<pre>
+if(!String.prototype.trim) {
+ String.prototype.trim = function() {
+ return String(this).replace(/^\s+|\s+$/g, "");
+ };
+}
+</pre>
+<p>
+Implementations are inconsistent with <code>\s</code>. For example,
+some implementations, notably JScript 5.8 and Safari 2, do not match <code>\xA0</code>
+(no-break space), among others.
+ </p> <p>
+
+A more consistent approach would be to create a character class
+that defines the characters to trim.
+ </p> <p>
+ </p><ul class='linkList'><li><a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp" >https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp</a></li>
+<li><a href="http://thinkweb2.com/projects/prototype/whitespace-deviations/" >http://thinkweb2.com/projects/prototype/whitespace-deviations/</a></li>
+<li><a href="https://developer.mozilla.org/en/Firefox_3.1_for_developers" >https://developer.mozilla.org/en/Firefox_3.1_for_developers</a></li>
+<li><a href="http://docs.sun.com/source/816-6408-10/regexp.htm" >http://docs.sun.com/source/816-6408-10/regexp.htm</a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/6wzad2b2%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/6wzad2b2%28VS.85%29.aspx</a></li>
+<li><a href="http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/c7010139217600c3/31092c5eb99625d0?#31092c5eb99625d0" >http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/c7010139217600c3/31092c5eb99625d0?#31092c5eb99625d0</a></li>
+<li><a href="http://unicode.org/Public/UNIDATA/PropList.txt" >http://unicode.org/Public/UNIDATA/PropList.txt</a></li>
+</ul> </div>
+<div id='domRef' class='section'><h2>9 DOM and Forms</h2>
+</div><div id='formControlAccess' class='section'><h3 id='FAQ4_13'>9.1 How do I get the value of a form control?</h3><p>
+
+In HTML documents, a form may be referred to as a property of the
+<code>document.forms</code> collection, either by its ordinal index or by name
+(if the <code>form</code> has a name). A <code>form</code>'s controls may be similarly referenced
+from its <code>elements</code> collection:
+</p>
+<pre>
+ var frm = document.forms[0];
+ var control = frm.elements[&quot;elementname&quot;];
+</pre>
+<p>
+Once a reference to a control is obtained, its (string) <code>value</code>
+property can be read:-
+</p>
+<pre>
+ var value = control.value;
+ value = +control.value; //string to number.
+</pre>
+<p>
+Some exceptions would be:
+</p> <p>
+
+First Exception: Where the control is a <code>SELECT</code> element, and
+support for older browsers, such as NN4, is required:
+</p>
+<pre>
+ var value = control.options[control.selectedIndex].value;
+</pre>
+<p>
+Second Exception: Where several controls share the same name,
+such as radio buttons. These are made available as collections
+and require additional handling. For more information, see:-
+</p><ul class='linkList'><li><a href="notes/form-access/" >notes/form-access/</a></li>
+<li><a href="names/" >Unsafe Names for HTML Form Controls</a></li>
+</ul> <p>
+
+Third Exception: File inputs. Most current browsers do not allow
+reading of <code>type="file"</code> input elements in a way that is useful.
+ </p> </div>
+<div id='propertyAccess' class='section'><h3 id='FAQ4_25'>9.2 My element is named myselect[], how do I access it?</h3><p>
+
+Form controls with any &quot;illegal&quot; characters can be accessed with
+<code>formref.elements[&quot;myselect[]&quot;]</code> - The bracket characters,
+amongst others, are illegal in ID attributes and javascript
+identifiers, so you should try to avoid them as browsers may
+handle them incorrectly.
+</p><ul class='linkList'><li><a href="http://msdn.microsoft.com/en-us/library/ms537449%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ms537449%28VS.85%29.aspx</a></li>
+<li><a href="https://developer.mozilla.org/en/DOM/form" >https://developer.mozilla.org/en/DOM/form</a></li>
+<li><a href="notes/form-access/" >notes/form-access/</a></li>
+</ul> </div>
+<div id='globalPollution' class='section'><h3 id='FAQ4_41'>9.3 Why doesn't the global variable &quot;divId&quot; always refer to the element with id=&quot;divId&quot;?</h3><p>
+
+Microsoft introduced a shortcut that can be used to reference
+elements which include an <code>id</code> attribute where the
+<code>id</code> becomes a globally-accessible property. Some browsers reproduce
+this behavior. Some, most notably Gecko-based browsers (Netscape and Mozilla),
+do so only in "quirks" mode. The best approach is the <code>document.getElementById</code>
+method, which is part of the W3C DOM standard and implemented
+in modern browsers (including IE from version 5.0). So an
+element with <code>id=&quot;foo&quot;</code> can be referenced
+with:-
+ </p>
+<pre>
+ var el = document.getElementById(&quot;foo&quot;);
+</pre>
+<p>
+Note: make sure not to use the same <code>id</code> twice in the same document
+and do not give an element a <code>name</code> that matches an <code>id</code>
+of another in the same document or it will trigger bugs in MSIE &lt;= 7 with
+<code>document.getElementsByName</code> and <code>document.getElementById</code>.
+</p><ul class='linkList'><li><a href="https://developer.mozilla.org/en/Using_Web_Standards_in_your_Web_Pages/Using_the_W3C_DOM#Accessing_Elements_with_the_W3C_DOM
+" >https://developer.mozilla.org/en/Using_Web_Standards_in_your_Web_Pages/Using_the_W3C_DOM#Accessing_Elements_with_the_W3C_DOM
+</a></li>
+<li><a href="faq_notes/faq_notes.html#FAQN4_41" >faq_notes/faq_notes.html#FAQN4_41</a></li>
+</ul> </div>
+<div id='updateContent' class='section'><h3 id='FAQ4_15'>9.4 How do I modify the content of the current page?</h3><p>
+
+Using the non-standard but widely implemented
+<code>innerHTML</code> property:
+<code>&lt;div id=&quot;anID&quot;&gt;Some Content&lt;/div&gt;</code> with script:
+ </p>
+<pre>
+ document.getElementById(&quot;anID&quot;).innerHTML =
+ &quot;Some &lt;em&gt;new&lt;/em&gt; Content&quot;;
+</pre>
+<p>
+Where <code>&quot;anID&quot;</code> is the (unique on the HTML page)
+<code>id</code> attribute value of the element to modify.
+ </p> <p>
+
+All versions of Internet Explorer exhibit problems with innerHTML, including:
+ </p>
+<ul>
+ <li> Fails with FRAMESET, HEAD, HTML, STYLE, SELECT,
+OBJECT, and all TABLE-related elements.
+ </li>
+ <li> Replaces consecutive whitespace characters with a single space. </li>
+ <li> Changes attribute values and order of appearance. </li>
+ <li> Removes quotations around attribute values. </li></ul><p>
+
+If the new content is only text and does not need to replace existing HTML,
+it is more efficient to modify the <code>data</code> property of a text node.
+ </p>
+<pre>
+ document.getElementById(&quot;anID&quot;).firstChild.data = &quot;Some new Text&quot;;
+</pre>
+ <p>
+
+Compatibility Note: Implementations have been known to split long text
+content among several adjacent text nodes, so replacing the data of the
+first text node may not replace all the element's text. The <code>normalize</code>
+method, where supported, will combine adjacent text nodes.
+</p> <p>
+
+Note: Make sure the element exists in the document (has been parsed) before trying to
+reference it.
+ </p><ul class='linkList'><li><a href="http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-FF21A306" >http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-FF21A306</a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/cc304097%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/cc304097%28VS.85%29.aspx</a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx</a></li>
+<li><a href="http://developer.mozilla.org/en/Whitespace_in_the_DOM" >http://developer.mozilla.org/en/Whitespace_in_the_DOM</a></li>
+<li><a href="http://developer.mozilla.org/en/docs/DOM:element.innerHTML" >http://developer.mozilla.org/en/docs/DOM:element.innerHTML</a></li>
+<li><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#html-fragment-serialization-algorithm" >http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#html-fragment-serialization-algorithm</a></li>
+<li> (draft)
+ </li>
+</ul> </div>
+<div id='accessElementBeforeDefined' class='section'><h3>9.5 Why does my code fail to access an element?</h3><p>
+
+An element can only be accessed after it exists in the document.
+ </p> <p>
+
+Either:
+A) include your script after the HTML element it refers to, or
+B) use the <code>"load"</code> event to trigger your script.
+ </p> <p>
+
+Example A:
+</p>
+<pre>
+&lt;div id="snurgle"&gt;here&lt;/div&gt;
+&lt;script type="text/javascript"&gt;
+// Don't forget var.
+var snurgleEl = document.getElementById("snurgle");
+window.alert(snurgleEl.parentNode);
+&lt;/script&gt;
+</pre>
+ <p>
+
+Example B:
+</p>
+<pre>
+// In the HEAD.
+&lt;script type="text/javascript"&gt;
+window.onload = function(){
+ var snurgleEl = document.getElementById("snurgle");
+};
+&lt;/script&gt;
+</pre>
+
+<h4>Other problems can include:</h4>
+
+<ul>
+ <li> invalid HTML </li>
+ <li> two elements with the same <code>name</code> or <code>id</code> </li>
+ <li> use of an unsafe name: http://jibbering.com/names/ </li></ul></div>
+<div id='testCookie' class='section'><h3 id='FAQ4_4'>9.6 How can I see in javascript if a web browser accepts cookies?</h3><p>
+
+Write a cookie and read it back and check if it's the same.
+ </p><ul class='linkList'><li>
+Additional Notes:
+</li>
+<li><a href="http://www.ietf.org/rfc/rfc2965.txt" >http://www.ietf.org/rfc/rfc2965.txt</a></li>
+<li><a href="http://www.galasoft-lb.ch/myjavascript/consulting/2001012701/" >http://www.galasoft-lb.ch/myjavascript/consulting/2001012701/</a></li>
+<li><a href="http://www.cookiecentral.com/" >http://www.cookiecentral.com/</a></li>
+</ul> </div>
+<div id='windows' class='section'><h2>10 Windows and Frames</h2>
+<p>
+
+The <code>window</code> object (also referred to by <code>self</code>) is "DOM Level 0".
+No formal standard for it exists.
+</p> </div><div id='disableBackButton' class='section'><h3 id='FAQ4_2'>10.1 How can I disable the back button in a web browser?</h3><p>
+
+You can't. The browser's history cannot be modified. However, you
+can use <code>self.location.replace(url);</code> in some browsers to replace
+the current page in the history.
+ </p><ul class='linkList'><li><a href="http://msdn.microsoft.com/en-us/library/ms536712%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ms536712%28VS.85%29.aspx</a></li>
+<li><a href="http://docs.sun.com/source/816-6408-10/location.htm#1194240" >http://docs.sun.com/source/816-6408-10/location.htm#1194240</a></li>
+</ul> </div>
+<div id='frameRef' class='section'><h3 id='FAQ4_8'>10.2 How do I access a frame's content?</h3><p>
+
+To reference another frame on the <em>same domain</em>:
+</p> <p>
+
+The
+<dfn>content window</dfn> of a <code>FRAME</code> or <code>IFRAME</code> can be
+accessed by the <code>frames</code> collection.
+</p> <p>
+
+Example:
+</p>
+<pre>
+var fwin;
+fwin = self.frames[0]; // or:
+fwin = self.frames["iframeName"];
+</pre>
+ <p>
+ or, from the <code>IFRAME</code> or <code>FRAME</code> element:
+</p>
+<pre>
+var iframeEl = document.getElementById("myFrame");
+var fwin = iframeEl.contentWindow; // Nonstandard, but widely supported.
+var fdoc = iframeEl.contentDocument; // DOM2 HTML Standard.
+</pre>
+ <p>
+
+A global identifier <code>moomin</code> in the the iframe's
+<dfn>content window</dfn>
+is accessed as <code>fwin.moomin</code>.
+ </p> <p>
+
+To communicate between frames on <em>different</em> domains:
+</p> <p>
+
+Where supported, (IE8, Firefox 3, Opera 9, Safari 4), use
+<code>window.postMessage( message[, port], otherDomain);</code>.
+</p> <p>
+
+Example:
+<a href="http://jibbering.com/faq/example/postMessage.html" >http://jibbering.com/faq/example/postMessage.html</a></p> <p>
+
+Where <code>window.postMessage</code> is not supported, the <code>window.name</code> property
+can be set on the other window, which can poll for updates to that
+property using <code>setInterval(checkWinName, 100);</code> where <code>checkWinName</code>
+is a function that polls to check the value of
+<code>self.name</code>.
+</p><ul class='linkList'><li><a href="http://en.wikipedia.org/wiki/Same_origin_policy" >http://en.wikipedia.org/wiki/Same_origin_policy</a></li>
+<li><a href="http://www-archive.mozilla.org/docs/dom/domref/dom_frame_ref5.html" >http://www-archive.mozilla.org/docs/dom/domref/dom_frame_ref5.html</a></li>
+<li><a href="https://developer.mozilla.org/en/DOM/window.postMessage" >https://developer.mozilla.org/en/DOM/window.postMessage</a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/cc197015(VS.85).aspx" >http://msdn.microsoft.com/en-us/library/cc197015(VS.85).aspx</a></li>
+</ul> </div>
+<div id='getWindowSize' class='section'><h3 id='FAQ4_9'>10.3 How do I find the size of the window?</h3><p>
+
+Here is a detailed explanation of a cross-browser strategy to
+find the dimensions of the viewport, excepting all chrome
+(excludes scrollbars, etc).
+ </p> <p>
+
+We can consider various properties:
+ </p>
+<pre>
+ window.innerWidth
+ document.clientWidth
+ document.documentElement.clientWidth
+ document.body.clientWidth
+</pre>
+<p>
+
+Of the browsers that have an <code>innerWidth</code> property, most
+include scrollbar dimensions. Some versions of KHTML browsers
+(including Safari 2) do <em>not</em> include scrollbar width.
+ </p> <p>
+
+The <code>window.inner*</code> properties are unreliable and not
+useful here. We don't want scrollbar dimensions included.
+</p>
+<pre> document.clientWidth</pre>
+ <p>
+
+Certain versions of KHTML, including Safari 2, have
+<code>document.clientHeight</code> and <code>document.clientWidth</code>
+properties. Where supported, these rare properties accurately
+return the height and width of the viewport, without including
+scrollbar dimensions.
+ </p>
+<pre>
+ document.documentElement.clientWidth
+ document.body.clientWidth
+</pre>
+<p>
+MSHTML (Trident), Firefox (Gecko), Opera (Presto), and Safari
+(Webkit) all support <code>clientHeight</code> on <code>document.body</code>
+and <code>document.documentElement</code>. The difficulty is figuring out
+which one is reliable. In other words which object to get the
+<code>clientHeight</code> property from:<code>documentElement</code> or <code>body</code>?
+ </p> <p>
+
+What the number returned from either of these properties
+represents depends on the environment. The environment includes
+the browser, its version, and the rendering mode of the document.
+In quirks mode, we'll mostly want to use <code>body.clientHeight</code>
+(except for in Safari 2).
+
+ </p>
+<pre> document.body.clientHeight</pre>
+<p>
+
+Some environments will return the viewport height. Others will
+return <code>0</code>. Yet others will return the <code>clientHeight</code> of
+the <code>BODY</code> element.
+
+ </p>
+<pre> document.documentElement.clientHeight</pre>
+<p>
+
+This is the more "standard" property for getting the height of
+the viewport. It usually "works" in modern browsers in
+
+<dfn>standards mode</dfn>. Notable exceptions include Safari 2 and
+Opera &lt;= 9.25, both of which return the <code>clientHeight</code>
+of the <code>html</code> <em>element</em>. (Oddly, Opera &lt;= 9.25
+in standards mode returns the width of the viewport for
+<code>documentElement.clientWidth</code>).
+ </p> <p>
+
+With the exception of Safari 2, <code>body.clientHeight</code> is reliable
+where <code>documentElement.clientHeight</code> is found to be unreliable.
+For example, in Safari 3+, Opera, and Mozilla, all in quirks mode,
+<code>document.documentElement.clientHeight</code> returns the <code>clientHeight</code>
+of the <code>html</code> element (this may seem unsurprising but
+it is not what we want).
+ </p> <p>
+
+Conversely, <code>document.body.clientHeight</code> will return
+the height of the viewport in most cases where
+<code>document.documentElement.clientHeight</code> does not. An exception
+to that is Safari 2, where <code>documentElement.clientHeight</code>
+and <code>body.clientHeight</code> both return the height of their
+corresponding element (not what we want).
+ </p> <p>
+
+By using a combination of
+<dfn>Feature Testing</dfn> and
+<dfn>Capability Testing</dfn>,
+the dimensions of the viewport can be strategically retrieved
+from the property that works in the environment the script is
+running in. The trick is determining which property will give us
+the value we want.
+ </p> <p>
+
+Since <code>document.clientHeight</code> is reliable where
+(rarely) supported, and since browsers that support this property
+don't return the viewport dimensions from
+<code>document.body.clientHeight</code> or
+<code>document.documentElement.clientHeight</code>, this should be the
+very first condition:
+
+ </p>
+<pre>
+ // Safari 2 uses document.clientWidth (default).
+ if(typeof document.clientWidth == "number") {
+ // use document.clientWidth.
+ }
+</pre>
+<p>
+
+The next strategy is to determine if
+<code>document.documentElement.clientHeight</code> property is unreliable.
+It is deemed "unreliable" when it is either <code>0</code> or taller
+than the viewport.
+ </p> <p>
+
+ Determining if <code>documentElement.clientHeight</code> is <code>0</code> is easy.
+ The result is stored in a variable <code>IS_BODY_ACTING_ROOT</code>.
+
+ </p>
+<pre>
+ var docEl = document.documentElement,
+ IS_BODY_ACTING_ROOT = docEl &amp;&amp; docEl.clientHeight === 0;
+ docEl = null;
+</pre>
+<p>
+
+To determine if <code>documentElement.clientHeight</code> returns
+a value taller than the viewport, we need a
+<dfn>Capability Test.</dfn></p> <p>
+
+If we can force <code>documentElement</code> to be very tall
+(taller than a normal viewport) we can then check to see if
+<code>documentElement.clientHeight</code> returns that "very tall" number.
+If it does, then it is unreliable.
+ </p> <p>
+
+We can force <code>documentElement</code> to be taller than the viewport
+(or any "normal" viewport) by adding a <code>div</code> to the <code>body</code>,
+give that <code>div</code> a height larger than any normal monitor,
+and then check to see if <code>documentElement.clientHeight</code> is
+that high (or "almost" that high, to account for <code>documentElement</code>
+having a border).
+
+ </p>
+<pre>
+ // Used to feature test Opera returning wrong values
+ // for documentElement.clientHeight.
+ // The results of this function should be cached,
+ // so it does not need to be called more than once.
+ function isDocumentElementHeightOff(){
+ var d = document,
+ div = d.createElement('div');
+ div.style.height = "2500px";
+ d.body.insertBefore(div, d.body.firstChild);
+ var r = d.documentElement.clientHeight &gt; 2400;
+ d.body.removeChild(div);
+ return r;
+ }
+</pre>
+<p>
+
+We can use this function to see if we should use
+<code>body.clientHeight</code>, instead. (but only after checking if
+<code>document.clientHeight</code> is supported).
+
+ </p>
+<pre>
+ // Safari 2 uses document.clientWidth (default).
+ if(typeof document.clientWidth == "number") {
+ // use document.clientHeight/Width.
+ }
+ else if(IS_BODY_ACTING_ROOT || isDocumentElementHeightOff()) {
+ // use document.body.clientHeight/Width.
+ } else {
+ // use document.documentElement.clientHeight/Width.
+ }
+</pre>
+<p>
+The preceding strategy was developed by Garrett Smith with input
+from John David Dalton. A complete and tested example can be found
+in APE Library under <code>APE.dom.getViewportDimensions</code>.
+Source code:
+<a href="http://dhtmlkitchen.com/ape/build/dom/viewport-f.js" >http://dhtmlkitchen.com/ape/build/dom/viewport-f.js</a>.
+APE is publicly released under Academic Free License.
+APE home: <a href="http://dhtmlkitchen.com/ape/" >http://dhtmlkitchen.com/ape/</a>.
+ </p> <p>
+
+Note: The dimensions cannot be determined accurately until after
+the document has finished loading.
+</p><ul class='linkList'><li><a href="http://msdn.microsoft.com/en-us/library/ms533566%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ms533566%28VS.85%29.aspx</a></li>
+<li><a href="http://developer.mozilla.org/en/DOM/window.innerWidth" >http://developer.mozilla.org/en/DOM/window.innerWidth</a></li>
+<li><a href="http://dev.opera.com/articles/view/using-capability-detection/" >http://dev.opera.com/articles/view/using-capability-detection/</a></li>
+</ul> </div>
+<div id='isWindowOpen' class='section'><h3 id='FAQ4_10'>10.4 How do I check to see if a child window is open, before opening another?</h3><p>
+ </p>
+<pre>
+ var myWin;
+ function openWin(aURL) {
+ if (!myWin || myWin.closed ) {
+ myWin = window.open(aURL,'myWin');
+ } else {
+ myWin.location.href = aURL;
+ myWin.focus();
+ }
+ }</pre>
+<p>
+Popup windows cause usability problems and are generally best avoided.
+</p><ul class='linkList'><li><a href="https://developer.mozilla.org/en/DOM:window.open" >https://developer.mozilla.org/en/DOM:window.open</a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/ms533574%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ms533574%28VS.85%29.aspx</a></li>
+<li><a href="http://docs.sun.com/source/816-6408-10/window.htm#1201877" >http://docs.sun.com/source/816-6408-10/window.htm#1201877</a></li>
+<li><a href="http://www.useit.com/alertbox/990530.html" >http://www.useit.com/alertbox/990530.html</a></li>
+</ul> </div>
+<div id='printFrame' class='section'><h3 id='FAQ4_11'>10.5 Why does framename.print() not print the correct frame in IE?</h3><p>
+
+IE prints the frame that has focus when you call the print
+method <code>frameref.focus();frameref.print();</code></p><ul class='linkList'><li><a href="http://msdn.microsoft.com/en-us/library/ms976105.aspx" >http://msdn.microsoft.com/en-us/library/ms976105.aspx</a></li>
+</ul> </div>
+<div id='windowClose' class='section'><h3 id='FAQ4_14'>10.6 How do I close a window and why does it not work on the first one?</h3><p>
+
+If a window was opened by javascript, then it can be closed
+without confirmation by using <code>windowRef.close()</code>.
+</p> <p>
+
+Before calling <code>windowRef.close()</code> (or other <code>window</code> methods), make
+sure the window reference is not null and its <code>closed</code> property is <code>false</code>.
+</p> <p>
+
+Popup windows cause usability problems and are generally best avoided.
+</p> <p>
+ </p><ul class='linkList'><li><a href="http://www.useit.com/alertbox/990530.html" >http://www.useit.com/alertbox/990530.html</a></li>
+<li><a href="#isWindowOpen " >#isWindowOpen </a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/ms536367%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ms536367%28VS.85%29.aspx</a></li>
+<li><a href="https://developer.mozilla.org/en/DOM/window.close#Description" >https://developer.mozilla.org/en/DOM/window.close#Description</a></li>
+<li><a href="http://docs.sun.com/source/816-6408-10/window.htm#1201822" >http://docs.sun.com/source/816-6408-10/window.htm#1201822</a></li>
+</ul> </div>
+<div id='permissionDenied' class='section'><h3 id='FAQ4_19'>10.7 Why do I get permission denied when accessing a frame/window?</h3><p>
+
+In the normal browser security model, a script may only access the
+properties of documents served from the same domain or IP address,
+protocol, and port.
+ </p> <p>
+
+Any attempt to access a property in such cases will result in a &quot;Permission
+Denied&quot; error. Signed scripts or trusted ActiveX objects can
+overcome this in limited situations.
+</p><ul class='linkList'><li><a href="http://msdn.microsoft.com/en-us/library/ms533028%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ms533028%28VS.85%29.aspx</a></li>
+<li><a href="https://developer.mozilla.org/En/Same_origin_policy_for_JavaScript" >https://developer.mozilla.org/En/Same_origin_policy_for_JavaScript</a></li>
+</ul> </div>
+<div id='setTimeout' class='section'><h3 id='FAQ4_20'>10.8 How do I make a 10 second delay?</h3><p>
+
+There is no built-in way to pause execution in javascript such
+as a sleep function, but hosts usually provide a method of some
+form. Web browsers are designed for event driven programming and
+only provide the <code>setTimeout</code> and <code>setInterval</code> functions
+to facilitate timed delays. The delay before calling <code>getSnork</code> may
+exceed the second parameter to <code>setTimeout</code> and <code>setInterval</code>
+due to implementation differences among browsers.
+ </p> <p>
+
+ To call the function <code>getSnork</code>, approximately 10 seconds
+ after the function <code>getMoomin()</code> completes, you would do this:
+ </p>
+<pre>
+ getMoomin();
+ setTimeout(getSnork, 10000);
+</pre>
+<p>
+Script execution is not stopped, and adding <code>getSnufkin()</code> after the
+<code>setTimeout</code> line would immediately execute the function <code>getSnufkin</code>
+before <code>getSnork</code>.
+ </p> <p>
+
+Achieving delays through running a loop of some sort for a pre-defined
+period is a bad strategy, as that will inhibit whatever was supposed to
+be happening during the delay, including blocking user interation.
+ </p> <p>
+
+Other (less event driven) hosts have different wait functions,
+such as <code>WScript.Sleep()</code> in the Windows Script Host.
+</p><ul class='linkList'><li><a href="http://msdn.microsoft.com/en-us/library/ms536753%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ms536753%28VS.85%29.aspx</a></li>
+<li><a href="http://docs.sun.com/source/816-6408-10/window.htm#1203758" >http://docs.sun.com/source/816-6408-10/window.htm#1203758</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Event-driven_programming" >http://en.wikipedia.org/wiki/Event-driven_programming</a></li>
+<li><a href="faq_notes/misc.html#mtSetTI" >faq_notes/misc.html#mtSetTI</a></li>
+</ul> </div>
+<div id='printSettings' class='section'><h3 id='FAQ4_23'>10.9 How do I change print settings for window.print()?</h3><p>
+
+In a normal security environment, you can't change anything.
+</p> <p>
+
+Print Stylesheet rules provide options.
+</p> <p>
+ For IE, <code>ActiveX</code> or Plugin ScriptX and
+Neptune from Meadroid to give you more control for Windows
+versions of Internet Explorer, Netscape, and Opera.
+</p><ul class='linkList'><li><a href="http://www.meadroid.com/scriptx/" >http://www.meadroid.com/scriptx/</a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/ms976105.aspx" >http://msdn.microsoft.com/en-us/library/ms976105.aspx</a></li>
+</ul> </div>
+<div id='changeBrowserDialog' class='section'><h3 id='FAQ4_28'>10.10 How do I change the confirm box to say yes/no or default to cancel?</h3><p>
+
+The buttons on a confirm box cannot be changed, nor can a default
+button be specified.
+ </p> <p>
+
+Change the question to a statement so that "OK" is suitable as the
+default response.
+</p> <p>
+
+ Example:
+ "Would you like us to charge your credit card?" (wrong)
+ "We will now charge your credit card." (right).
+</p> </div>
+<div id='fileDownload' class='section'><h3 id='FAQ4_33'>10.11 How do I prompt a &quot;Save As&quot; dialog for an accepted mime type?</h3><p>
+
+It is not possible with client-side javascript.
+ </p> <p>
+
+Some browsers accept the Content-Disposition header, but this
+must be added by the server. Taking the form:-
+<code>Content-Disposition: attachment; filename=filename.ext</code></p><ul class='linkList'><li><a href="http://classicasp.aspfaq.com/general/how-do-i-prompt-a-save-as-dialog-for-an-accepted-mime-type.html" >http://classicasp.aspfaq.com/general/how-do-i-prompt-a-save-as-dialog-for-an-accepted-mime-type.html</a></li>
+<li><a href="http://support.microsoft.com/kb/q260519/" >http://support.microsoft.com/kb/q260519/</a></li>
+</ul> </div>
+<div id='modifyChrome' class='section'><h3 id='FAQ4_36'>10.12 How do I modify the current browser window?</h3><p>
+
+In a default security environment you are very limited in how much
+you can modify the current browser window. You can use
+<code>window.resizeTo</code> or <code>window.moveTo</code> to resize or move a
+window respectively, but that is it. Normally you can only
+suggest chrome changes in a <code>window.open</code>.
+</p><ul class='linkList'><li><a href="http://msdn.microsoft.com/en-us/library/ms536651%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ms536651%28VS.85%29.aspx</a></li>
+<li><a href="https://developer.mozilla.org/en/DOM:window.open" >https://developer.mozilla.org/en/DOM:window.open</a></li>
+</ul> </div>
+<div id='target' class='section'><h3 id='FAQ4_37'>10.13 How do I POST a form to a new window?</h3><p>
+
+Use the target attribute on the form, opening a window with
+that name and your feature string in the onsubmit handler of the
+FORM.
+ </p>
+<pre>
+ &lt;form action=&quot;&quot; method="post"
+ target=&quot;wndname&quot; onsubmit=&quot;window.open('',this.target);return true;&quot;&gt;</pre>
+<ul class='linkList'><li><a href="http://www.htmlhelp.com/reference/html40/forms/form.html" >http://www.htmlhelp.com/reference/html40/forms/form.html</a></li>
+</ul> </div>
+<div id='openWindow' class='section'><h3 id='FAQ4_42'>10.14 How do I open a new window with javascript?</h3><p>
+
+New windows can be opened on browsers that support the
+<code>window.open</code> function and are not subject to the action of any
+pop-up blocking mechanism with code such as:-
+ </p>
+<pre>
+ var wRef;
+ if(window.open){
+ wRef = window.open("http://example.com/page.html","windowName");
+ }</pre>
+<ul class='linkList'><li><a href="https://developer.mozilla.org/en/DOM:window.open" >https://developer.mozilla.org/en/DOM:window.open</a></li>
+<li><a href="http://www.infimum.dk/HTML/JSwindows.html" >http://www.infimum.dk/HTML/JSwindows.html</a></li>
+</ul> </div>
+<div id='ajaxRef' class='section'><h2>11 Ajax and Server Communication</h2>
+</div><div id='ajax' class='section'><h3 id='FAQ4_44'>11.1 What is Ajax?</h3><p>
+
+<dfn title = 'Asynchronous JavaScript and XML'>Ajax</dfn>
+is shorthand for Asynchronous JavaScript and XML. The technology is
+based on the <code>XMLHttpRequest</code> Object. At its simplest,
+it is the sending/retrieving of new data from the server without
+changing or reloading the window location.
+</p><ul class='linkList'><li>
+Mozilla Documentation:
+</li>
+<li><a href="http://developer.mozilla.org/en/docs/XMLHttpRequest" >http://developer.mozilla.org/en/docs/XMLHttpRequest</a></li>
+<li>
+MSDN Documention:
+</li>
+<li><a href="http://msdn.microsoft.com/en-us/library/ms535874%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ms535874%28VS.85%29.aspx</a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/ms759148%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ms759148%28VS.85%29.aspx</a></li>
+<li>
+Libraries and Tutorial Sites:
+</li>
+<li><a href="http://jibbering.com/2002/4/httprequest.html" >http://jibbering.com/2002/4/httprequest.html</a></li>
+<li><a href="http://www.ajaxtoolbox.com/" >http://www.ajaxtoolbox.com/</a></li>
+</ul> </div>
+<div id='downloadPage' class='section'><h3 id='FAQ4_38'>11.2 How do I download a page to a variable?</h3><p>
+
+Although <code>XMLHttpRequest</code> can be used to download
+entire pages, it is often used for downloading small pieces
+of data that can be used to update the current page.
+ </p><ul class='linkList'><li><a href="http://jibbering.com/2002/4/httprequest.html" >http://jibbering.com/2002/4/httprequest.html</a></li>
+<li><a href="http://www.ajaxtoolbox.com/" >http://www.ajaxtoolbox.com/</a></li>
+</ul> </div>
+<div id='getServerVariable' class='section'><h3 id='FAQ4_18'>11.3 How do I get a jsp/php variable into client-side javascript?</h3><p>
+
+Use a server-side language to generate the javascript.
+</p> <p>
+
+Certain characters of ECMAScript strings must be escaped by backslash.
+These include quote marks, backslash, and line terminators.
+</p> <p>
+ JSP Example, using Apache Commons: <code>org.apache.commons.lang.StringEscapeUtils</code>:
+ </p>
+<pre>
+var jsVar = "&lt;%= StringEscapeUtils.escapeJavaScript(str) %&gt;";
+</pre>
+ <p>
+ PHP example using <code>addcslashes</code>:
+</p>
+<pre>
+var jsVar = "&lt;?php echo addcslashes($str,"\\\'\"\n\r"); ?&gt;";
+</pre>
+<ul class='linkList'><li><a href="example/addcslashes.php" >example/addcslashes.php</a></li>
+<li><a href="http://php.net/manual/en/function.addcslashes.php" >http://php.net/manual/en/function.addcslashes.php</a></li>
+<li><a href="http://commons.apache.org/lang/" >http://commons.apache.org/lang/</a></li>
+</ul> </div>
+<div id='sessionExpired' class='section'><h3 id='FAQ4_29'>11.4 How do I log-out a user when they leave my site?</h3><p>
+
+This cannot be done reliably. Here's why:
+ </p>
+<ul> <li>
+The user may disable javascript so the log-out script will
+never execute.
+ </li>
+<li>
+The user may not be on-line when they close your web page.
+ </li>
+<li>
+Javascript errors elsewhere in the page may prevent the script
+executing.
+ </li>
+<li>
+The browser may not support the onunload event, or may not fire
+it under certain circumstances, so the log-out function will
+not execute.
+ </li>
+</ul>
+<p>
+The URL below has more information.
+</p><ul class='linkList'><li><a href="http://groups.google.com/groups?selm=BlmZ7.55691%244x4.7344316%40news2-win.server.ntlworld.com" >http://groups.google.com/groups?selm=BlmZ7.55691%244x4.7344316%40news2-win.server.ntlworld.com</a></li>
+</ul> </div>
+<div id='runServerScript' class='section'><h3 id='FAQ4_34'>11.5 How do I run a server side script?</h3><p>
+
+You trigger a server-side script by sending an HTTP request.
+This can be achieved by setting the <code>src</code> of an <code>img</code>,
+<code>Image</code>, <code>frame</code>, or <code>iframe</code>, or by using
+<dfn title = 'XMLHttpRequest or XMLHTTP'>XHR</dfn>, where supported.
+ </p> <p>
+
+An image will also
+&quot;swallow&quot; the data sent back by the server, so that they will
+not be visible anywhere.
+</p> <p>
+ </p>
+<pre>
+ var dummyImage = new Image();
+ dummyImage.src = &quot;scriptURL.asp?param=&quot; + varName;
+</pre>
+ <p>
+
+Mozilla, Opera 7.6+, Safari 1.2+, and Windows IE 7
+provide the <code>XMLHttpRequest</code> object
+(Windows IE versions 5+, provides ActiveX to acheive an analagous
+effect). <code>XMLHttpRequest</code> can send HTTP requests to
+the server, and provides access the <code>responseText</code> or <code>responseXML</code>
+(when the response is XML), and HTTP header information.
+</p><ul class='linkList'><li><a href="http://jibbering.com/2002/4/httprequest.html" >http://jibbering.com/2002/4/httprequest.html</a></li>
+<li><a href="http://www.w3.org/TR/XMLHttpRequest/" >http://www.w3.org/TR/XMLHttpRequest/</a></li>
+<li><a href="http://developer.mozilla.org/en/XMLHttpRequest" >http://developer.mozilla.org/en/XMLHttpRequest</a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/ms537505(VS.85).aspx" >http://msdn.microsoft.com/en-us/library/ms537505(VS.85).aspx</a></li>
+</ul> </div>
+<div id='noCache' class='section'><h3 id='FAQ4_17'>11.6 How do I force a reload from the server/prevent caching?</h3><p>
+
+To reload a page, use <code>location.reload()</code>. However, this depends
+upon the cache headers that your server sends. To change this,
+you need to alter the server configuration. A quick fix on the
+client is to change the page URI so that it contains a unique
+element, such as the current time. For example:
+<code>location.replace(location.href+'?d='+new Date().valueOf())</code>
+If the <code>location.href</code> already contains a query String, use:
+<code>location.replace(location.href+'&amp;d='+new Date().valueOf())</code></p><ul class='linkList'><li><a href="http://www.mnot.net/cache_docs/" >http://www.mnot.net/cache_docs/</a></li>
+<li><a href="http://docs.sun.com/source/816-6408-10/date.htm" >http://docs.sun.com/source/816-6408-10/date.htm</a></li>
+</ul> </div>
+<div id='ajaxCache' class='section'><h3 id='FAQ4_45'>11.7 Why is my Ajax page not updated properly when using an HTTP GET request in Internet Explorer?</h3><p>
+
+ Browsers cache the results of HTTP requests to reduce network traffic.
+ To force the browser to request the document from the server, either
+ set the <code>EXPIRES</code> and/or <code>CACHE-CONTROL</code> response header(s)
+ with a past date or use a unique query string.
+ </p>
+<pre>
+ req.open("GET", "/example.jsp?date=" + (+new Date), true);
+</pre>
+<p>
+
+Always use the appropriate HTTP method. Do not use <code>POST</code>
+to prevent caching. See <a href="http://www.faqs.org/rfcs/rfc2616.html" >RFC 2616</a>.
+
+</p><ul class='linkList'><li><a href="http://www.mnot.net/cache_docs/#EXPIRES" >http://www.mnot.net/cache_docs/#EXPIRES</a></li>
+<li><a href="http://www.mnot.net/javascript/xmlhttprequest/cache.html " >http://www.mnot.net/javascript/xmlhttprequest/cache.html </a></li>
+</ul> </div>
+<div id='debugging' class='section'><h2>12 Debugging</h2>
+</div><div id='javascriptErrors' class='section'><h3 id='FAQ4_43'>12.1 How do I get my browser to report javascript errors?</h3><p>
+
+There are debugging tools for many browsers. Learn to use them all.
+ </p>
+<dl>
+ <dt> Windows </dt>
+ <dd> <a href="http://www.fiddlertool.com/fiddler/" >Fiddler</a>.
+Fiddler is an HTTP Debugging proxy (it won't find script
+errors). Fiddler logs HTTP activity, like Firebug's Net
+tab, but can be attached to any browser running on Windows.
+ </dd>
+ <dt> Windows IE </dt>
+ <dd> Microsoft Script Editor. Included with Visual Studio or Microsoft
+Word 2003 (discontinued in Office 2007).
+To enable,
+<code>Tools</code>, <code>Internet Options</code>, <code>Advanced</code>, and uncheck
+<code>Disable Script Debugging</code>. After enabling Script Debugging,
+a <code>Script Debugger</code> option will appear in the <code>View</code> menu. </dd>
+ <dd> <a href="http://www.my-debugbar.com/wiki/IETester/HomePage" >IETester</a> for testing IE 5.5- IE8. </dd>
+ <dd> <a href="http://www.my-debugbar.com/wiki/CompanionJS/HomePage" >CompanionJS</a><code>console</code> for IE. </dd>
+ <dd> <em>Note:</em> For debugging scripts in IE, the Microsoft Script <em>Editor</em>
+is recommended. However, if not available, the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=2F465BE0-94FD-4569-B3C4-DFFDF19CCD99&amp;displaylang=en" >Microsoft Script Debugger</a> may be somewhat helpful.
+ </dd>
+ <dd> <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e-2d5e1db91038&amp;displaylang=en" >Internet Explorer Developer Toolbar</a> </dd>
+ <dd>
+To report errors: Wait until a little yellow
+triangle appears at the left end of the status bar, double click
+on it and, when the error dialog box appears, check the &quot;Always
+show errors&quot; checkbox it contains.
+
+Or, <code>Internet Options</code>, <code>Advanced</code>, deselect <code>"Disable Script Debugging"</code>,
+select <code>"Display a notification ..."</code>.
+ </dd>
+ <dt> Firefox </dt>
+ <dd> <code>Tools &gt; Error console</code> (<code>Ctrl</code> + <code>Shift</code> + <code>j</code>).
+ </dd>
+ <dd> <a href="http://getfirebug.com/" >Firebug</a> </dd>
+ <dd> <a href="https://addons.mozilla.org/en-US/firefox/addon/5369" >YSlow</a>.
+YSlow analyzes web pages and tells you why they're slow
+based on Yahoo's rules for high performance web sites.
+ </dd>
+ <dd> <a href="https://addons.mozilla.org/en-US/firefox/addon/1743" >Lori</a>
+<dfn>Lori</dfn> or Life-of-request info, is useful for troubleshooting
+server response and page load time.
+ </dd>
+ <dd> <a href="https://addons.mozilla.org/en-US/firefox/addon/60" >Web Developer Toolbar</a>.
+ </dd>
+ <dd> <a href="https://addons.mozilla.org/en-US/firefox/addon/1201" >Cookie Watcher</a>.
+ </dd>
+ <dd> <a href="https://addons.mozilla.org/en-US/firefox/addon/1192" >XPather</a>.
+XPath generator, editor and inspector.
+ </dd>
+ <dt> Opera </dt>
+ <dd>
+Tools &gt; Advanced &gt; Error console
+ </dd>
+ <dd> <a href="http://dev.opera.com/articles/view/introduction-to-opera-dragonfly/" >Introduction to Opera Dragonfly</a> </dd>
+ <dt> Safari </dt>
+ <dd>
+To display the <code>Develop</code> menu in Safari 3.1 or higher, select
+the checkbox labeled "Show Develop menu in menu bar" in
+Safari's <code>Advanced</code> Preferences panel.
+ </dd>
+ <dd> <a href="http://trac.webkit.org/wiki/Web%20Inspector " >Safari Web Inspector</a> </dd>
+ <dt> Chrome </dt>
+ <dd>
+JavaScript Console: click the <code>Page</code> menu icon and select
+<code>Developer &gt; JavaScript Console</code>. From here, you'll be
+able to view errors in the JavaScript execution, and enter
+additional javascript commands to execute.
+ </dd>
+ <dd>
+JavaScript Debugger: available as <code>Page</code> menu icon &gt; <code>Developer</code>
+&gt; Debug JavaScript, the debugger provides a command prompt from which you
+can set breakpoints, backtrace, and more. Type <code>help</code> at the debugger
+command line to get started.
+ </dd>
+ <dd>
+<ul> <li> <a href="http://www.google.com/chrome/intl/en/webmasters-faq.html#jsexec" >Google Chrome Script Debugging</a> </li>
+<li> <a href="http://blog.chromium.org/2009/06/developer-tools-for-google-chrome.html" >Developer Tools for Google Chrome</a> </li>
+<li> <a href="http://blog.chromium.org/2009/08/google-chrome-developer-tools-for.html" >Tools for Eclipse Users</a> </li>
+</ul>
+ </dd>
+ <dt> Mac IE </dt>
+ <dd>
+Use the Preferences dialog.
+ </dd></dl></div>
+<div id='doNotTry' class='section'><h2>13 Things not to attempt in a browser</h2>
+</div><div id='detectBrowser' class='section'><h3 id='FAQ4_26'>13.1 How do I detect Opera/Safari/IE?</h3><p>
+
+The short answer: <em>Don't do that</em>.
+ </p> <p>
+
+The <code>navigator</code>
+<dfn>host object</dfn> contains properties which
+may identify the browser and version. These properties are historically
+inaccurate. Some browsers allow the user to set <code>navigator.userAgent</code> to any value. For
+example, Firefox, (type <code>about:config</code> and search <code>useragent</code>
+or Safari, <code>Develop &gt; User Agent &gt; Other...</code>, IE, via Registry.
+ </p> <p>
+
+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.
+ </p> <p>
+
+Browser detection is unreliable, at best. It usually causes
+forward-compatibility and maintenance problems. It is unrelated to the
+problem or incompatiblity it is trying to solve and obscures the
+problems it is used for, where it is used.
+ </p> <p>
+
+Object detection is checking that the object in question exists.
+<a href="http://dev.opera.com/articles/view/using-capability-detection/" >Capability detection</a> goes one step further to actually test the object,
+method, or property, to see if behaves in the desired manner.
+ </p> <p>
+
+Feature Test Example:
+ </p>
+<pre>
+/**
+ * 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.
+ return e.target || e.srcElement;
+}</pre>
+<ul class='linkList'><li><a href="notes/detect-browser/" >notes/detect-browser/</a></li>
+<li><a href="http://dev.opera.com/articles/view/using-capability-detection/" >http://dev.opera.com/articles/view/using-capability-detection/</a></li>
+<li><a href="http://developer.apple.com/internet/webcontent/objectdetection.html" >http://developer.apple.com/internet/webcontent/objectdetection.html</a></li>
+<li><a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43" >http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43</a></li>
+</ul> </div>
+<div id='preventAccess' class='section'><h3 id='FAQ4_5'>13.2 How can I prevent access to a web page by using javascript?</h3><p>
+
+In practice you can't. While you could create a suitable
+encryption system with a password in the page, the level of
+support you need to do this means it's always simpler to do it
+server-side. Anything that &quot;protects&quot; a page
+other than the current one is definitely flawed.
+ </p> </div>
+<div id='hideSource' class='section'><h3 id='FAQ4_1'>13.3 How do I protect my javascript code?</h3><p>
+
+With clientside javascript you can't as your code is distributed
+in source form and is easily readable. With JScript, there is the
+Script Encoder (see MSDN), but this is nothing more than obfuscation.
+Attempting to disable the context menu does nothing to
+protect your script in a Web browser.
+ </p><ul class='linkList'><li>
+ Your code is likely protected under copyright laws. See:
+ </li>
+<li><a href="http://www.wipo.int/about-ip/en/copyright.html" >http://www.wipo.int/about-ip/en/copyright.html</a></li>
+<li><a href="http://webdesign.about.com/od/copyright/Copyright_Issues_on_the_Web_Intellectual_Property.htm" >http://webdesign.about.com/od/copyright/Copyright_Issues_on_the_Web_Intellectual_Property.htm</a></li>
+</ul> </div>
+<div id='disableRightClick' class='section'><h3 id='FAQ4_27'>13.4 How do I suppress a context menu (right-click menu)?</h3><p>
+
+A context menu, often triggered by right-click, can be requested by the
+user in a few ways. For example, on windows, shift + F10 and on macs,
+click-and-hold. Other input devices exist and mouse buttons can be
+configured, making the term "right click" a misnomer, in context.
+</p> <p>
+
+In browsers that allow it, a script can suppress the context menu by
+returning false from an object's <code>oncontextmenu</code> event handler.
+</p>
+<pre>
+document.oncontextmenu = function() {
+ return false;
+};
+</pre>
+<p>
+Some browsers lack context menus (e.g. iphone). Browsers that have
+context menus do not always have a scriptable event for them. Some
+browsers can be configured to disallow scripts from detecting context
+menu events (IE, Opera); others may fire the event but be configured to
+disallow scripts from suppressing the context menu (Firefox,Seamonkey).
+</p> <p>
+
+Even when the context menu has been suppressed, it will still be
+possible to view/save the source code and to save images.
+</p><ul class='linkList'><li><a href="http://en.wikipedia.org/wiki/Context_menu" >http://en.wikipedia.org/wiki/Context_menu</a></li>
+<li><a href="http://kb.mozillazine.org/Ui.click_hold_context_menus" >http://kb.mozillazine.org/Ui.click_hold_context_menus</a></li>
+<li><a href="http://support.microsoft.com/kb/823057" >http://support.microsoft.com/kb/823057</a></li>
+<li><a href="http://stackoverflow.com/questions/1870880/opera-custom-context-menu-picking-up-the-right-click/1902730#1902730" >http://stackoverflow.com/questions/1870880/opera-custom-context-menu-picking-up-the-right-click/1902730#1902730</a></li>
+<li><a href="http://support.mozilla.com/en-US/kb/Javascript#Advanced_JavaScript_settings" >http://support.mozilla.com/en-US/kb/Javascript#Advanced_JavaScript_settings</a></li>
+<li><a href="http://msdn.microsoft.com/en-us/library/ms536914%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/ms536914%28VS.85%29.aspx</a></li>
+</ul> </div>
+<div id='readFile' class='section'><h3 id='FAQ4_3'>13.5 How can I access the client-side filesystem?</h3><p>
+
+Security means that by default you can't. In a more restricted
+environment, there are options. For example, using LiveConnect to
+connect to Java with Netscape, and using the FileSystemObject in
+IE. Check <a href="http://groups.google.com/group/comp.lang.javascript/topics" >Google Groups archives</a>
+for previous posts on the subject.
+ </p><ul class='linkList'><li><a href="http://msdn.microsoft.com/en-us/library/z9ty6h50%28VS.85%29.aspx" >http://msdn.microsoft.com/en-us/library/z9ty6h50%28VS.85%29.aspx</a></li>
+<li><a href="http://www.javaworld.com/javaworld/jw-10-1998/jw-10-apptowin32.html" >http://www.javaworld.com/javaworld/jw-10-1998/jw-10-apptowin32.html</a></li>
+</ul> </div>
+<div id='javascriptURI' class='section'><h3 id='FAQ4_24'>13.6 I have &lt;a href=&quot;javascript:somefunction()&quot;&gt; what ... ?</h3><p>
+
+Whatever the rest of your question, this is generally a very bad idea.
+The <code>javascript:</code> pseudo protocol was designed to replace the
+current document with the value that is returned from the expression.
+For example:
+ </p>
+<pre>
+ &lt;a href=&quot;javascript:'&amp;lt;h1&amp;gt;' + document.lastModified + '&amp;lt;/h1&amp;gt;'&quot;&gt;lastModified&lt;/a&gt;
+</pre>
+<p>
+will result in replacing the current document with the value
+returned from <code>document.lastModified</code>, wrapped in an <code>&lt;h1&gt;</code>
+tag.
+ </p> <p>
+
+When the expression used evaluates to an <code>undefined</code> value
+(as some function calls do), the contents of the current page are not
+replaced. Regardless, some browsers (notably IE6) interpret this as
+navigation and will enter into a 'navigation' state where GIF
+animations and plugins (such as movies) will stop and navigational
+features such as <code>META</code> refresh, assignment to <code>location.href</code>, and image
+swaps fail.
+ </p> <p>
+
+It is also possible for IE to be configured such that it supports
+javascript but not the <code>javascript:</code> protocol. This results
+in the user seeing a protocol error for <code>javascript:</code> URIs.
+ </p> <p>
+
+The <code>javascript:</code> pseudo protocol creates accessibility and
+usability problems. It provides no fallback for when the script is not
+supported.
+ </p> <p>
+
+Instead, use
+<code>&lt;a href=&quot;something.html&quot; onclick=&quot;somefunction();return false&quot;&gt;</code>
+where <code>something.html</code> is a meaningful alternative. Alternatively,
+attach the <code>click</code> callback using an event registry.
+ </p><ul class='linkList'><li><a href="example/jsuri/" >example/jsuri/</a></li>
+<li><a href="http://groups.google.com/group/comp.lang.javascript/msg/f665cfca3b619692" >Set/Navigate to a Location</a></li>
+<li><a href="http://www.useit.com/alertbox/20021223.html" >Top Ten Web-Design Mistakes of 2002</a></li>
+</ul> </div>
+<div id='comments' class='section'><h2 id='FAQ5'>14 Comments and Suggestions</h2>
+<p>
+
+The FAQ uses the stylesheet <a href="faq.css" >faq.css</a> and is generated
+from the xml source <a href="index.xml" >index.xml</a> by the windows script
+host script <a href="process.wsf" >process.wsf</a> which also checks the links.
+ </p> </div><div id='FAQENTRY' class='section'><h3 id='FAQ5_1'>14.1 Why do some posts have &lt;FAQENTRY&gt; in them?</h3><p>
+
+If a poster feels that the question they are answering should be
+covered in the FAQ, placing &lt;FAQENTRY&gt; in the post lets the FAQ
+robot collect the messages for easy review and inclusion. A Draft Proposal
+for the FAQ is requested and appreciated.
+ </p> <p>
+
+The &lt;FAQENTRY&gt; should not be used in posts except in
+conjunction with a suggestion/proposal for the FAQ. It should
+also not be literally quoted in replies, instead it should be
+partly obscured as, e.g. &lt;FAQ**TRY&gt; or similar.
+ </p> </div>
+<div id='makeSuggestion' class='section'><h3 id='FAQ5_2'>14.2 How do I make a suggestion?</h3><p>
+
+The FAQ is currently lacking a maintainer, please contact Jim Ley
+(jim.ley&#64;gmail.com) if you wish to take it over, you will need to
+be in good standing in the group and trustworthy to have access to the
+server. All comments, suggestions, and especially corrections are
+welcome.
+ </p> </div>
+<!--<script src='FAQReader.js' type='text/javascript'></script>--></body>
+</html>
+
/trunk/cljs/backup/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/backup/process.wsf
===================================================================
--- trunk/cljs/backup/process.wsf (nonexistent)
+++ trunk/cljs/backup/process.wsf (revision 45)
@@ -0,0 +1,387 @@
+<job id="process">
+<!--
+This file generates the FAQ index.html
+-->
+<SCRIPT>
+/**
+ * Formatting - Still messy.
+ * Needed corrections:
+ * statements terminated with semicolon.
+ * use |var| for variables.
+ * use whitespace.
+ * 2 spaces for indentation (not one).
+ */
+var CheckUrls=false,
+ xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
+
+// moomin.utilities can be got from http://www.e-media.co.uk/earl/
+// var mu=new ActiveXObject("Moomin.Utilities")
+
+var xml = new ActiveXObject("Microsoft.XMLDOM");
+xml.async = false;
+xml.validateOnParse = false;
+xml.resolveExternals = false;
+xml.load("index.xml");
+xml.save("indexold.xml");
+
+var faqNode = xml.selectSingleNode("/FAQ"),
+ Version = faqNode.attributes.getNamedItem("VERSION").nodeValue,
+ maintainer = "Garrett Smith",
+ Updated = faqNode.attributes.getNamedItem("DATE").nodeValue;
+
+var str = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" \n'
+ + '"http://www.w3.org/TR/html4/strict.dtd">\n<html lang="en">\n'
+ + '<head>\n'
+ + '<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\n'
+ + '<meta name="DCTERMS.language" scheme="RFC1766" content="en">\n'
+ + '<meta name="DC.title" content="comp.lang.javascript Frequently Asked Questions">\n'
+ + '<meta name="DCTERMS.subject" '
+ + 'content="Frequently asked questions in the Usenet newsgroup comp.lang.javascript">\n'
+ + '<meta name="DC.format" content="text/html">\n'
+ + '<meta name="DC.type" content="Text">\n'
+ + '<meta name="DC.creator" content="Jim Ley">\n'
+ + '<meta name="DC.publisher" content="' + maintainer + '">\n'
+ + '<META name="DC.Publisher.Address" '
+ + 'content="dhtmlkitchen&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">\n'
+ + '<meta name="DCTERMS.modified" content="' + Updated +'">\n'
+ + '<meta name="DCTERMS.audience" content="Programmers, web developers">\n'
+ + '<meta name="DC.description" content="Javascript Frequently Asked Questions">\n'
+ + '<meta name="DC.identifier" content="http://jibbering.com/faq">\n'
+ + '<meta name="DC.source" '
+ + 'content="http://www.ecma-international.org/publications/standards/Ecma-262.htm">\n'
+ + '<meta name="DC.source" content="news:comp.lang.javascript">\n'
+ + '<meta name="DC.source" content="https://developer.mozilla.org/en/JavaScript">\n'
+ + '<meta name="DC.source" content="http://msdn.microsoft.com/en-us/library/hbxc2t98%28VS.85%29.aspx">\n'
+ + '<meta name="DC.source" content="http://msdn.microsoft.com/en-us/library/ms533050%28VS.85%29.aspx">\n'
+ + '<meta name="DC.rights" content="copyright contributors, comp.lang.javascript">\n'
+ + '<link rel="StyleSheet" href="faq.css" type="text/css" media="screen">\n';
+
+TitleStr = xml.selectSingleNode("/FAQ/TITLE").firstChild.nodeValue;
+
+str += "<title> "+TitleStr+"</title>\n"
+ + '</head>\n <body>\n'
+ + "<h1> "+TitleStr+"</h1>\n"
+ + "<p>Version "+Version+", Updated "+Updated +", by " + maintainer + "</p>"
+ + '<div id="nav"><a href="notes/">FAQ Notes</a></div>';
+
+var contentstr = "";
+Contents = xml.selectSingleNode("/FAQ/CONTENTS").selectNodes("CONTENT");
+
+str += "\n<ul id='faqList'>\n";
+
+for (var i = 0; i < Contents.length; i++) {
+ CNode = Contents[i];
+ var sectionId = CNode.getAttribute("ID") || "",
+ title = CNode.getAttribute("TITLE");
+
+ str += "<li>" + (i+1) + " <a href='#" + sectionId +"'>" + title + "</a>\n";
+
+ contentstr += "<div id='" + sectionId +"' class='section'>"
+ + "<h2"+getOldId(CNode)+">"
+ + (i+1) + " " + title
+ + "</h2>\n"
+ + processContentChildren(CNode)
+ + "</div>";
+
+ var SubContents = CNode.selectNodes("CONTENT");
+ processContentChildren(CNode);
+ if(SubContents.length > 0) {
+ str += "\n<ul>\n";
+
+ // Build a link to a subsection.
+ // a subsection looks like:
+ // <h3 id=[FAQ5_7 | getWindowSize]><a name=FAQ5_7></a> ... </h3>
+ // This allows for items to be moved around in various
+ // order (index should not matter).
+
+ for (var j = 0; j < SubContents.length; j++) {
+ var SubCNode = SubContents[j],
+ subSectionId = SubCNode.getAttribute("ID"),
+ title = SubCNode.getAttribute("TITLE"),
+ entryNumber = ""+(i+1)+"."+ (j+1);
+
+ str += "<li>" + entryNumber +" <a href='#"+ subSectionId +"'>" + title + "</a></li>\n";
+
+ contentstr += "<div id='" + subSectionId + "' class='section'>"
+ + "<h3" + getOldId(SubCNode) + ">"
+ + entryNumber + " " + title
+ + '</h3>'
+ + processContentChildren(SubCNode )
+ + '</div>'
+ + '\n';
+ }
+ str += "</ul>";
+ }
+ str += "</li>";
+}
+
+/**
+ * If the node contains a "NUMID",
+ * the content is wrapped in an anchor, e.g. "<a name='" + NUMID.
+ * Otherwise, returns the content.
+ */
+function getOldId(node) {
+ var faqSectionIndexString = node.getAttribute("NUMID") || "";
+ return (faqSectionIndexString ?
+ " id='FAQ" + faqSectionIndexString +"'" : "");
+}
+
+str += "</ul>"
+ + contentstr
+ + "<!--<script src='FAQReader.js' type='text/javascript'><\/script>-->"
+ + "</body> \n</html> \n";
+str = str.replace(/<p><\/p>/gm,"").replace(/<p> <\/p>/gm,"");
+
+// Create the files.
+var FSO = new ActiveXObject("Scripting.FileSystemObject");
+FIL = FSO.CreateTextFile("index"+Version+".html",true);
+FIL.WriteLine(str);
+FIL.close();
+FIL=FSO.CreateTextFile("index.html",true);
+FIL.WriteLine(str);
+FIL.close();
+if (CheckUrls) {
+ xml.save("index.xml");
+ xml.save("index"+Version+".xml");
+}
+
+function processContentChildren(cNode) {
+ var allNodes = cNode.selectNodes("*"),
+ contentstr = "";;
+ for(var k = 0; k < allNodes.length; k++) {
+ var node = allNodes[k];
+ if(node.tagName == "P")
+ contentstr += ProcessNode(node);
+
+ // List nodes, for UL, OL, DL.
+ else if(node.tagName == "LIST")
+ contentstr += processList(allNodes[k]);
+ }
+ return contentstr;
+}
+
+function ProcessNode(nde) {
+ var str = " ", p = "", closeP = "", child;
+ if(nde.tagName == "P") {
+ str = "<p>\n ";
+ p = "<p>";
+ closeP = "</p>";
+ }
+ for (var i = 0;i < nde.childNodes.length; i++) {
+ child = nde.childNodes[i];
+ switch (child.nodeName) {
+ case "#comment" :
+ str += "<!--" + child.data + "-->";
+ break;
+ case "#text" :
+ // If a text node is empty, do not generate an empty <p> tag.
+ if(child.nodeValue.replace(/\s+/,'') == "") return " ";
+ str += child.nodeValue;
+ break;
+ case "VER" :
+ str += Version;
+ break;
+ case "UPDATED" :
+ str += Updated;
+ break;
+ case "URL" :
+ str += makeLink(child);
+ break;
+ case "EM" :
+ var url= child.firstChild.nodeValue;
+ str+=' <em>'+url+'</em>';
+ break;
+ case "NEWSGROUP" :
+ var url= child.firstChild.nodeValue;
+ str+=' <a href="news:'+url+'">'+url+'</a>';
+ break;
+ case "MAILTO" :
+ var url= child.firstChild.nodeValue;
+ str+=' <a href="mailto:'+url+'">'+url+'</a>';
+ break;
+ case "MOREINFO" :
+ str += closeP + ProcessResource(child) + p;
+ break;
+ case "UL" :
+ str+= closeP + " \n<ul> "+ProcessUL(nde.childNodes[i])+"</ul> \n" + p;
+ break;
+ case "LI" :
+ str+="<li> "+ ProcessNode( child ) + "</li>";
+ break;
+ case "CODE" :
+ str+= closeP + "\n<pre>"+ child.firstChild.nodeValue +"</pre>\n"+p;
+ break;
+ case "ICODE" :
+ str += "<code>"+ child.firstChild.nodeValue+"</code>";
+ break;
+ case "DFN" :
+ var title = child.attributes.getNamedItem("TITLE");
+ title = title && (" title = '" + title.nodeValue +"'") || "";
+ str +="\n<dfn" + title + ">"
+ + child.firstChild.nodeValue + "</dfn>";
+ break;
+ default:
+ str += child.nodeValue;
+ break;
+ }
+ }
+ return str+= closeP + " ";
+}
+
+function makeLink(child) {
+ var url = child.firstChild.nodeValue,
+ linkText = child.attributes.getNamedItem("LINKTEXT"),
+ addstr = checkUrl(url, child);
+ linkText = linkText && linkText.nodeValue;
+ return '<a href="'+url+'" '+addstr+'>'+(linkText||url)+'</a>';
+}
+
+/** Processing for OL, UL, DL.
+ * calls processNode.
+ */
+function processList(list) {
+ var str = "",
+ header = "",
+ title = list.getAttribute("TITLE"),
+ id = list.getAttribute("ID"),
+ idStr = (id && " id='" + id + "'") || "";
+
+ if(title) {
+ header = "\n<h4" + idStr +">" + title + "</h4>\n";
+ idStr = ""; // Output id only once.
+ }
+
+ var type = list.getAttribute("TYPE");
+ type = (type || "ul").toLowerCase();
+
+ str += "\n<" + type + idStr +">";
+
+ for (var i = 0; i < list.childNodes.length; i++) {
+ var child = list.childNodes[i],
+ tagName = child.nodeName;
+
+ // If not a list-type element,
+ // add it to the header (will appear first).
+ if(!/(?:LI)|(?:DT)|(?:DD)/.test(tagName)) {
+ header += ProcessNode(child);
+ }
+ else if(tagName !== "#text") {
+ tagName = tagName.toLowerCase();
+ str += "\n <" +tagName +">" + ProcessNode(child) + "</" +tagName +">";
+ }
+ }
+ return header + str + "</" + type + ">";
+}
+
+ function ProcessUL(nde) {
+ var str=""
+ for (var i=0;i<nde.childNodes.length;i++) {
+
+ var child = nde.childNodes[i];
+
+ switch (nde.childNodes[i].nodeName) {
+ case "#text" :
+ str+=nde.childNodes[i].nodeValue;
+ break;
+ case "VER" :
+ str+=Version
+ break;
+ case "URL" :
+ str += makeLink(child);
+ break;
+ case "NEWSGROUP" :
+ var url = child.firstChild.nodeValue
+ str+=' <a href="news:'+url+'">'+url+'</a> \n'
+ break;
+ case "MAILTO" :
+ var url= child.firstChild.nodeValue;
+ str+=' <a href="mailto:'+url+'">'+url+'</a> \n'
+ break;
+ case "UL" :
+ str+="<ul>\n" + ProcessNode(child) + "\n</ul>\n"
+ break;
+ case "LI" :
+ str+="<li> " + ProcessNode(child) + "</li> \n"
+ break;
+ case "CODE" :
+ str+="</p>\n<pre>"+nde.childNodes[i].firstChild.nodeValue.replace('\r',"<BR> ")+"</pre> \n<p> \n"
+ break;
+ case "ICODE" :
+ str+="<code>"+nde.childNodes[i].firstChild.nodeValue+"</code>\n"
+ break;
+ default:
+ document.write(nde.childNodes[i].nodeName+'<br> \n')
+ str+=nde.childNodes[i].nodeValue;
+ break;
+ }
+ }
+ return str += "";
+ }
+
+
+function ProcessResource(nde) {
+ var str="<ul class='linkList'>", child;
+ for (var i = 0; i < nde.childNodes.length; i++) {
+ child = nde.childNodes[i];
+ switch (child.nodeName) {
+ case "#text" :
+ if(/[a-zA-Z]/.test(child.nodeValue))
+ str += '<li>' + child.nodeValue + '</li>\n';
+ break;
+ case "URL" :
+ str+='<li>' + makeLink(child) + '</li>\n';
+ break;
+ case "NEWSGROUP" :
+ var url = child.firstChild.nodeValue;
+ str += '<li><a href="news:'+url+'">' + url + '</a></li> \n';
+ break;
+
+ }
+ }
+ return str + "</ul>";
+}
+
+ function checkUrl(url,node) {
+ url=url.split('#')[0]
+ if (CheckUrls) {
+ if (url.indexOf('http://')==0) {
+ xmlhttp.Open("get",url,false)
+ try {
+ xmlhttp.Send()
+ } catch (e) { WScript.Echo(url);return ""; }
+ stat=xmlhttp.status
+ node.attributes.getNamedItem("status").nodeValue=stat
+ if (stat==200) {
+ source=xmlhttp.responseText
+ if (url.indexOf('microsoft')!=-1 && source.indexOf('Page Cannot')!=-1) {
+ //Ugly hack 'cos MSDN don't understand HTTP.
+ stat=404
+ node.attributes.getNamedItem("status").nodeValue=stat
+ return ' class="nolink" '
+ }
+ contentlength=source.length
+// oldhash=node.attributes.getNamedItem("hash").nodeValue
+// hash=mu.MD5(source,"faq")
+// node.attributes.getNamedItem("hash").nodeValue=hash
+ classstr=""
+// if (oldhash!=hash) classstr=' class="updated"'
+ lm=xmlhttp.getResponseHeader("Last-Modified")
+ return classstr+' title="'+lm+'" '
+ } else {
+ xmlhttp.Open("get","http://www.google.com/search?q=cache:"+url,false)
+ xmlhttp.Send()
+ if (xmlhttp.responseText.indexOf('did not match any documents')==-1) {
+ return ' class="nolink"> \n<small> \n<a href="http://www.google.com/search?q=cache:'+url+'>(Googles cached copy)</a> \n<small'
+ }
+ return ' class="nolink" '
+ }
+ } else {
+ return ""
+ }
+ } else {
+ return ""
+ }
+
+ }
+</SCRIPT>
+</job>
Index: trunk/cljs/names/conclusion.html
===================================================================
--- trunk/cljs/names/conclusion.html (nonexistent)
+++ trunk/cljs/names/conclusion.html (revision 45)
@@ -0,0 +1,120 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+<head>
+ <title>Unsafe Names for HTML Form Controls - Conclusion</title>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <meta name="author" content="Garrett Smith">
+ <link rel="Start" href="./">
+ <link rel="stylesheet" href="../faq.css" type="text/css" media="all" charset="iso-8859-1">
+ <link rel="stylesheet" href="names.css" type="text/css" media="all" charset="iso-8859-1">
+</head>
+<body>
+
+ <h1>Unsafe Names for HTML Form Controls</h1>
+ <h2>Conclusion</h2>
+
+ <h3>Problem</h3>
+ <p>
+ Browser APIs and Web Standards are designed in such a way that
+ element <code>id</code>s and <code>name</code>s, if not
+ carefully chosen, may inadvertently pollute other objects
+ with extra properties. This can cause problems.
+ </p>
+
+ <h3>Solution</h3>
+ <p>
+ There are several steps that you, as a page author, can take
+ to avoid these problems.
+ </p>
+
+ <ul>
+ <li>
+ Be aware of the problem.
+ </li>
+ <li>
+ Don't rely on the augmented scope chain to find properties of the <code>FORM</code>,
+ <code>body</code>, or <code>document</code>. Instead, use fully qualified property lookups,
+ e.g. <code>document.body</code>, <code>this.form.elements</code>.
+ </li>
+ <li>
+ Avoid Event Handler Content Attributes.
+ Events can be registered in the script (not in HTML).
+ </li>
+ <li>
+ Use prefixed or "namespaced" names for
+ <code>id</code> and <code>name</code> attribute values.
+ </li>
+ </ul>
+
+ <h3>Do Web Standards Suck?</h3>
+ <p>
+ They are not without their problems.
+ Most of the problems and <a href="extra_props.html#StandardWrong">misconceptions</a>
+ would become self-evident if the standards bodies were to use a
+ test-driven approach. The current approach is Big Up Front Design
+ with the traditional analysis-documentation-implementation phases.
+ The APIs are designed with a waterfall approach.
+ </p>
+
+ <p>
+ Testing is informal and not part of the official process. This is something
+ that needs to change in order to avoid unforseen pitfalls. Unfortunately, there has
+ not been enough change in this direction and we can witness current problems
+ with HTML 5 that build upon the mistakes of prior specifications and poor
+ design of experimental implementations.
+ </p>
+
+ <p>
+ A test-based process could have revealed the design problem
+ with form-as-a-collection, as specified in HTML 5, or the issues
+ with <code>body</code> event handler content attributes (e.g.
+ <code>hashchange</code>). Multiple contributors
+ to a test suite would make it hard for the author to ignore API design mistakes.
+ </p>
+
+ <h4>Normative References</h4>
+ <ul id="controls-normref">
+ <li> [DOM1]
+ <a href="http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-40002357"
+ >Document Object Model (HTML) Level 1</a>, Mike Champion, others.
+ </li>
+ <li> [DOM2]
+ <a href="http://www.w3.org/TR/DOM-Level-2-HTML/ecma-script-binding.html"
+ >Document Object Model (HTML) Level 2</a>, Johnny Stenback, others.
+ </li>
+ <li>
+ [DOMEvents]
+ <a href="http://www.w3.org/TR/DOM-Level-3-Events/events.html"
+ >Document Object Model Events</a>, Philippe Le H&eacute;garet, Tom Pixley
+ </li>
+ <li>
+ [HTML 5]
+ <a href="http://www.whatwg.org/specs/">HTML 5</a>,
+ Ian Hickson
+ </li>
+ <li>[WebIDL]
+ <a href="http://www.w3.org/TR/WebIDL/">Web IDL</a>,
+ Cameron McCormack
+ </li>
+ </ul>
+
+ <div id="toc">
+ <h4>Table of Contents</h4>
+ <ul class="pagination linkList">
+ <li><a href="./index.html">Introduction</a></li>
+ <li><a href="extra_props.html">Extra Properties: <code>FORM</code> Elements</a></li>
+ <li><a href="extra_props_document.html">Extra Properties: <code>document</code></a></li>
+ <li><a href="extra_props_global.html">Extra Properties: <code>global</code></a></li>
+ <li><a href="event_handler.html">Event Handler Scope</a></li>
+ <li><a href="api_design.html">API Design?</a></li>
+ <li><a href="unsafe_names.html">Unsafe Names</a></li>
+ <li>Conclusion</li>
+ </ul>
+ </div>
+ <ul id="nextLink" class="linkList">
+ <li>
+ <span class="prev">Previous:</span> <a href="unsafe_names.html">Unsafe Names</a>
+ </li>
+ </ul>
+</body>
+</html>
/trunk/cljs/names/conclusion.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/event_handler.html
===================================================================
--- trunk/cljs/names/event_handler.html (nonexistent)
+++ trunk/cljs/names/event_handler.html (revision 45)
@@ -0,0 +1,305 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Unsafe Names for HTML Form Controls - Unsafe Names</title>
+ <meta name="author" content="Garrett Smith">
+ <link rel="Start" href="./">
+ <link rel="stylesheet" href="../faq.css" type="text/css" media="all" charset="iso-8859-1">
+ <link rel="stylesheet" href="names.css" type="text/css" media="all" charset="iso-8859-1">
+</head>
+<body>
+
+ <h1>Unsafe Names for HTML Form Controls</h1>
+ <h2>Event Handler Scope</h2>
+ <h3>Event Handler Content Attributes and Augmented Scope Chain</h3>
+ <p>
+ Event Handler Content Attributes are event handler attributes that appear in the HTML source.
+ </p>
+
+ <p>
+ When an element has an event handler content attribute, the value
+ of that attribute becomes the <code>FunctionBody</code> of a function that the browser calls when it fires that event.
+ </p>
+ <p>
+ Modern browsers augment the <code>FunctionBody</code>'s scope chain with the element, the element's <code>FORM</code>
+ (if it is a form control), and <code>document</code>. There is no official standard for this augmented scope chain.
+ </p>
+ <p>
+ Older browsers, such as Safari 2, Mozilla 1.x, Opera 7, differ. Scope augmentation occurs for all
+ event handler content attributes with the notable exception of the <code>body</code> element, for
+ which event handler scope is not consistently augmented across event types and implementations.
+ </p>
+
+ <p>
+ The context (<code>thisArg</code>) is (with the exception of <code>body</code>), the element
+ itself. In the browsers that implement DOM Events [<a href="conclusion.html#controls-normref">DOMEvents</a>],
+ the event handler function has a single parameter named <code>event</code>.
+ </p>
+
+ <p>
+ Given the following markup:
+ </p>
+<pre>&lt;p onclick="self.alert(event);"&gt;&lt;/p&gt;</pre>
+ <p>
+ The augmented scope chain, if written in ECMAScript, would look like:
+ </p>
+
+ <pre>
+<span class='keyword'>function</span> onclick(<var>event</var>) {
+ <span class='keyword'>with</span>(document) {
+ <span class='keyword'>with</span>(<span class='keyword'>this</span>.form) {
+ <span class='keyword'>with</span>(<span class='keyword'>this</span>) {
+ self.alert(<var>event</var>);
+ }
+ }
+ }
+}</pre>
+ <p>
+ Note that some browsers will not supply an <code><var>event</var></code> parameter.
+ </p>
+
+ <h4>Example 3: Augmented Scope Chain</h4>
+ <p>
+ This example shows how <code>window</code> and <code>document</code>
+ are shadowed:
+ </p>
+ <form action="">
+ <input type="hidden" name="document">
+ <button type="button" name="window"
+ onclick="self.alert([window.tagName, document.tagName])"
+ >self.alert([window.tagName, document.tagName])</button>
+ </form>
+ <strong>Source:</strong>
+ <pre>
+&lt;form action=""&gt;
+ &lt;input type="hidden" name="document"&gt;
+ &lt;button type="button" name="window"
+ onclick="self.alert([window.tagName, document.tagName])"&gt;self.alert([window.tagName, document.tagName])&lt;/button&gt;
+&lt;/form&gt;
+</pre>
+ <p>
+ The augmented scope chain, if written in ECMAScript, would look like:
+ </p>
+
+ <pre>
+<span class='keyword'>function</span> onclick(<var>event</var>) {
+ <span class='keyword'>with</span>(document) {
+ <span class='keyword'>with</span>(<span class='keyword'>this</span>.form) {
+ <span class='keyword'>with</span>(<span class='keyword'>this</span>) {
+ self.alert([title, files, focus == window.focus]);
+ <span class='keyword'>var</span> e = <var>event</var>||window.event;
+ <span class='keyword'>if</span>(e && e.preventDefault) e.preventDefault();
+ e.returnValue = <span class='keyword'>false</span>;
+ }
+ }
+ }
+}</pre>
+
+ <p>
+ For all intents and purposes, the browser's
+ <code>window</code> property of the <code>global</code> object is
+ an alias to the the <code>global</code> object itself.
+ </p>
+
+ <p>
+ Relying on an augmented scope chain to resolve properties may
+ have unexpected results in different environments (i.e. browsers). The following example
+ shows how in at least two browsers, <code>files</code> is resolved as a property
+ of an <code>input</code> element.
+ </p>
+
+ <script type="text/javascript">
+ var files = [1,2,3];
+ </script>
+
+ <form action="">
+ <input onclick="self.alert([title, files, focus == window.focus]);
+ var e = event||window.event;
+ if(e && e.preventDefault) e.preventDefault();e.returnValue = false;" type="file">
+ </form>
+ <pre>
+&lt;script type="text/javascript"&gt;
+<span class='keyword'>var</span> files = [1,2,3];
+&lt;/script&gt;
+
+&lt;form action=""&gt;
+ &lt;input onclick="self.alert([title, files, focus == window.focus]);
+ var e = event||window.event;
+ if(e && e.preventDefault) e.preventDefault();
+ e.returnValue = false;" type="file"&gt;
+&lt;/form&gt;
+</pre>
+ <h3>Result</h3>
+ Firefox 3, Safari 3:
+ <pre>",[object FileList],false"</pre>
+ Opera 9.5, IE7, IE8:
+ <pre>",1,2,3,false"</pre>
+
+ <p>
+ The identifier <code>files</code> is resolved on the input element
+ in Firefox 3 and Safari 3. In IE8 or Opera 9.5, <code>files</code> is
+ resolved on the window object.
+ </p>
+ <p>
+ A <a href="scope_aug_example.html">modified example</a> from c.l.js thread <a
+ href="http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/2d1bd03a4bc47add"
+ >"Works in ie and opera not mozilla"</a>, by Richard Cornford.
+ </p>
+ <h4>Browsers Tested:</h4>
+<ul>
+ <li>Opera 9.27, 9.63, 10a;</li>
+ <li>Safari 3.2.1;</li>
+ <li>Chrome 1.0.154.46;</li>
+ <li>Firefox 2.0.0.18, 3.0.5;</li>
+ <li>IE 7, 8.0RC1;</li>
+ <li>IE 5.2 (Mac)</li>
+ <li>Konqueror 4.1;</li>
+ <li>Blackberry 4.7 (9500 model)</li>
+ <li>MSIEMobile 6.0 (WinCE)</li>
+</ul>
+ <h4>Results:</h4>
+<pre>
+ex0 = global
+ex1 = document #document
+ex2 = document #document
+ex3 = document #document
+ex4 = 4 FORM
+ex5 = 4 FORM
+ex6 = 4 FORM
+ex7 = 7 INPUT
+ex8 = 7 INPUT
+ex9 = 7 INPUT
+
+// First link
+
+ex0 = global
+ex1 = document #document
+ex2 = document #document
+ex3 = document #document
+ex4 = document #document
+ex5 = document #document
+ex6 = document #document
+ex7 = document #document
+ex8 = 8 A
+ex9 = 8 A
+
+// Second link
+
+ex0 = global
+ex1 = document #document
+ex2 = document #document
+ex3 = document #document
+ex4 = document #document
+ex5 = document #document
+ex6 = document #document
+ex7 = document #document
+ex8 = document #document
+ex9 = 9 A
+</pre>
+ <p>Most of the above results were provided by Juriy Zaytsev on thread
+ <a
+ href="http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/8e48b8520d359395/61b45f35fb76694f"
+ >Cross-Browser Mouse Event Handling</a>.
+ </p>
+<h4>Older Browsers</h4>
+ <p>
+ Less recent browsers, including Safari 2.0.4, Mozilla 1.x,
+ and Opera 7, featured different scope chains.
+ </p>
+
+ <h4>Exception: The <code>BODY</code> Tag.</h4>
+ <p>
+ The <code>body</code> tag's event handler attributes are either mapped to
+ <code>window</code> (which has no tag) or to the <code>BODY</code> element.
+ Results vary based on the event and the browser. Do not use event handler
+ attributes for the <code>body</code> element.
+ </p>
+
+ <h3>Problem</h3>
+
+ <p>
+ An augmented scope chain, combined with event handler content attributes, means that
+ properties of the element itself, the element's form (if it is a form control),
+ and document, may shadow properties of the window object.
+ As explained in: <a href="http://groups.google.com/group/comp.lang.javascript/msg/3f5495216b3e9b67"
+ >select?</a>, and
+ <a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2008-September/016184.html"
+ >hashchange only dispatched in history traversal</a>, comments by Garrett Smith. Shortened code excerpt:
+ </p>
+ <pre>
+&lt;img name='alert' alt="Alert!" src="alert.jpg"&gt;
+&lt;button onclick="self.alert(alert);"&gt;self.alert(alert);&lt;/button&gt;
+</pre>
+
+<img name='alert' alt="Alert!" src="" style="z-index:-1;position:absolute">
+<button onclick="self.alert(alert);">self.alert(alert);</button>
+
+ <h4>Result</h4>
+ <p>
+ Alerts <samp>[object HTMLImageElement]</samp> (or similar implementation-dependent string).
+ </p>
+
+ <p>
+ By using an unsafe name of <samp>"alert"</samp> for an <code>IMG</code>,
+ The <code>window</code>'s <code>alert</code> property
+ identifier is shadowed by <code>document</code>'s <code>alert</code>
+ property identifier because
+ <code>document</code> is in the event handler's augmented scope
+ before <code>window</code>.
+ </p>
+
+ <p>
+ By using event handler content attributes and unsafe names,
+ <code>document</code> and <code>window</code>, the respective identifiers
+ are resolved on the augmented scope chain.
+ </p>
+
+ <p>
+ The augmented scope chain
+ creates more ambiguity and increases the number of unsafe names.
+ </p>
+ <h3>Solution</h3>
+ <ul>
+ <li>
+ Don't rely on the augmented scope chain to find properties of the <code>FORM</code>,
+ <code>body</code>, or <code>document</code>. Instead, use fully qualified property lookups,
+ e.g. <code>document.body</code>, <code>this.form.elements</code>.
+ </li>
+ <li>
+ Avoid Event Handler Content Attributes.
+ Registering event callbacks in the script (not in HTML) avoids
+ the possibility of a property such as unqualified <code>alert</code>
+ being resolved on an object other than <code>window</code>.
+ </li>
+ <li>
+ Do not use Event Handler Content Attributes for <code>body</code>.
+ </li>
+ <li>
+ Use prefixed names for all <code>id</code> or <code>name</code> attribute values.
+ </li>
+ </ul>
+
+ <div id="toc">
+ <h4>Table of Contents</h4>
+ <ul class="pagination linkList">
+ <li><a href="./index.html">Introduction</a></li>
+ <li><a href="extra_props.html">Extra Properties: <code>FORM</code> Elements</a></li>
+ <li><a href="extra_props_document.html">Extra Properties: <code>document</code></a></li>
+ <li><a href="extra_props_global.html">Extra Properties: <code>global</code></a></li>
+ <li>Event Handler Scope</li>
+ <li><a href="api_design.html">API Design?</a></li>
+ <li><a href="unsafe_names.html">Unsafe Names</a></li>
+ <li><a href="conclusion.html">Conclusion</a></li>
+ </ul>
+ </div>
+ <ul id="nextLink" class="linkList">
+ <li>
+ <span class="prev">Previous:</span> <a href="extra_props_global.html">Extra Properties: global</a>
+ </li>
+ <li>
+ <span class="next">Next:</span> <a href="api_design.html">API Design?</a>
+ </li>
+ </ul>
+</body>
+</html>
/trunk/cljs/names/event_handler.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/map-like-nodelist.html
===================================================================
--- trunk/cljs/names/map-like-nodelist.html (nonexistent)
+++ trunk/cljs/names/map-like-nodelist.html (revision 45)
@@ -0,0 +1,34 @@
+<!doctype html>
+<html>
+<head>
+<title>Map-like NodeList Example</title>
+</head>
+<body>
+<h1>Map-like NodeList Example</h1>
+<div id="item"></div>
+<div id="length"></div>
+<pre>
+<script type="text/javascript">
+var divs = document.getElementsByTagName('div');
+document.writeln("divs.item.tagName = " + divs.item.tagName);
+document.writeln("divs.length.tagName = " + divs.length.tagName);
+</script>
+</pre>
+<hr>
+<h2>Opera, IE</h2>
+<pre>
+DIV DIV
+</pre>
+
+<h2>Safari 3</h2>
+<pre>
+DIV undefined
+</pre>
+
+<h2>Firefox</h2>
+<pre>
+undefined undefined
+</pre>
+
+</body>
+</html>
/trunk/cljs/names/map-like-nodelist.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/scope_aug_example.html
===================================================================
--- trunk/cljs/names/scope_aug_example.html (nonexistent)
+++ trunk/cljs/names/scope_aug_example.html (revision 45)
@@ -0,0 +1,83 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+ <head>
+ <title>Augmented Scope Chain in Event Handlers</title>
+<script type="text/javascript">
+
+function setExpandos(){
+ setExs(window,0, 'global');
+ setExs(document,1, 'document');
+ setExOn(document.body,2, 'body');
+}
+
+function setExOn(obj, depth, data){
+ if(obj.nodeType == 1){
+ setExs(obj,depth, data);
+ var o = obj.children||obj.childNodes;
+ for(var c = 0;c < o.length;c++){
+ setExOn(o[c], (depth+1), (depth+1));
+ }
+ }
+}
+
+function setExs(obj,start, data){
+ for(var c = start;c < 10;c++){
+ obj['ex'+c] = data+((obj.nodeName)?(' '+obj.nodeName):'');
+ }
+}
+
+var res = [
+'chain results > ',
+'\nex0 = ','', //2
+'\nex1 = ','', //4
+'\nex2 = ','', //6
+'\nex3 = ','', //8
+'\nex4 = ','', //10
+'\nex5 = ','', //12
+'\nex6 = ','', //14
+'\nex7 = ','', //16
+'\nex8 = ','', //18
+'\nex9 = ','' //20
+];
+
+</script>
+</head>
+<body onload="setExpandos();">
+<div>
+<form action="">
+ <div>
+ <p>
+ <input type="button" value="Form Button"
+ onclick="var a = res;a[2] = ex0;a[4] = ex1;
+ a[6] = ex2;a[8] = ex3;a[10] = ex4;
+ a[12] = ex5;a[14] = ex6;a[16] = ex7;
+ a[18] = ex8;a[20] = ex9;
+ alert(a.join(''));return false;">
+ </p>
+ </div>
+</form>
+<table>
+ <thead>
+ <tr><th><a href="#"
+ onclick="var a = res;a[2] = ex0;a[4] = ex1;
+ a[6] = ex2;a[8] = ex3;a[10] = ex4;
+ a[12] = ex5;a[14] = ex6;a[16] = ex7;
+ a[18] = ex8;a[20] = ex9;
+ alert(a.join(''));return false;">
+ thead</a></th></tr>
+ </thead>
+ <tbody>
+ <tr><td><span>
+ <a href="#"
+ onclick="var a = res;a[2] = ex0;a[4] = ex1;
+ a[6] = ex2;a[8] = ex3;a[10] = ex4;
+ a[12] = ex5;a[14] = ex6;a[16] = ex7;
+ a[18] = ex8;a[20] = ex9;
+ alert(a.join(''));return false;">
+ tbody</a></span></td></tr>
+ </tbody>
+</table>
+</div>
+</body>
+</html>
\ No newline at end of file
/trunk/cljs/names/scope_aug_example.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/extra_props_global.html
===================================================================
--- trunk/cljs/names/extra_props_global.html (nonexistent)
+++ trunk/cljs/names/extra_props_global.html (revision 45)
@@ -0,0 +1,200 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+<head>
+ <title>Unsafe Names for HTML Form Controls - Extra Properties: Global</title>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <meta name="author" content="Garrett Smith">
+ <link rel="Start" href="./">
+ <link rel="stylesheet" href="../faq.css" type="text/css" media="all" charset="iso-8859-1">
+ <link rel="stylesheet" href="names.css" type="text/css" media="all" charset="iso-8859-1">
+</head>
+<body>
+
+ <h1>Unsafe Names for HTML Form Controls</h1>
+ <h2>Extra Properties: <code>global</code></h2>
+
+ <h3>Extra Properties: The Element Id Resolver Object</h3>
+ <p>
+ IE, Opera, Firefox, and Webkit
+ seem to implement a non-standard <dfn>element id resolver</dfn>
+ object. This object is used to retrieve the element.
+ See comp.lang.javscript thread:
+ <a href="http://groups.google.com/group/comp.lang.javascript/msg/aed8ecf1660e1dd1"
+ >Why "window.alert()" over "alert()"?</a>, comment by Lasse Reichstein Nielsen.
+ </p>
+
+ <p>
+ In some browsers, this behavior depends on the DOCTYPE used.
+ </p>
+
+ <p>
+ This is a non-standard behavior of browsers that applies to <em>any</em> element with
+ an <code>id</code>, not only form controls.
+ </p>
+
+ <p>
+ Assigning to an undeclared identifier should result in a new global
+ property being created, or, if the global/window object has a property with
+ that name, its value should be replaced. However in some
+ browsers, the assigment can result in an error.
+ </p>
+
+ <p>
+ The properties of the "element resolver" may appear to be shadowed by
+ properties of the global object, or vice-versa.
+ </p>
+
+<h4>Property Assignment to Element</h4>
+ <script type="text/javascript">
+var globalVal;
+function addScript(id) {
+ var script = document.createElement('script'),
+ src = document.getElementById(id);
+ script.text = src.firstChild.data;
+
+ document.body.appendChild(script);
+ document.getElementById(id+"Result").firstChild.data = globalVal;
+}
+ </script>
+ <p>
+ The following example should result: <samp>undefined, 11</samp>.
+ </p>
+
+ <button id='b1' onclick="addScript('g1')">addScript('g1')</button>
+ <code id='g1Result'>&nbsp;</code>
+ <pre id="g1">
+try {
+ var b1;
+ globalVal = [String(b1)]; // Should be "undefined".
+ b1 = 11;
+ globalVal = globalVal.concat(b1); // Should be ["undefined", 11]
+} catch(ex) {
+ globalVal = ex.message;
+}
+</pre>
+ <p>
+ The following example does not declare a variable. The browser may optionally
+ resolve the identifier <code>b2</code> on the <dfn>element id resolver</dfn> object.
+ </p>
+ <button id='b2' onclick="addScript('g2')">addScript('g2')</button>
+<code id='g2Result'>&nbsp;</code>
+<pre id="g2">
+try {
+ globalVal = [typeof b2];
+ b2 = 11; // undeclared assignment.
+ globalVal = globalVal.concat(b2);
+} catch(ex) {
+ globalVal = ex.message;
+}
+</pre>
+ <p>
+ The following example should result: <samp>undefined, 11</samp>.
+ </p>
+ <button id='b3' onclick="addScript('g3')">addScript('g3')</button>
+<code id='g3Result'>&nbsp;</code>
+<pre id="g3">
+// remove element id.
+document.getElementById('b3').id = '';
+
+try {
+ globalVal = [typeof b3]; // should be "undefined".
+ b3 = 11; // undeclared assignment.
+ globalVal = globalVal.concat(b3);
+} catch(ex) {
+ globalVal = ex.message;
+}
+</pre>
+ <p>
+ Declared variables that have not yet been assigned a value create a property
+ on the Variable object with the value <code>undefined</code>.
+ </p>
+ <p>
+ If the <dfn>element id resolver</dfn> object exists above the scope of
+ the global object, the identifier will be shadowed by the global variable object.
+ </p>
+<h3>Results</h3>
+<p>Firefox:</p>
+<ul>
+ <li>
+ <samp class="expected">undefined, 11</samp>
+ </li>
+ <li>
+ <samp>object, 11</samp>
+ </li>
+ <li>
+ <samp class="expected">undefined, 11</samp>
+ </li>
+</ul>
+<p>Opera 9.5:</p>
+<ul>
+ <li>
+ <samp class="error">undefined, 11</samp>
+ </li>
+ <li>
+ <samp>object, 11</samp>
+ </li>
+ <li>
+ <samp class="expected">undefined, 11</samp>
+ </li>
+</ul>
+<p>Safari 2.0.2, 3.1:</p>
+<ul>
+ <li>
+ <samp class="error">[object HTMLButtonElement], 11</samp>
+ </li>
+ <li>
+ <samp>object, 11</samp>
+ </li>
+ <li>
+ <samp class="expected">undefined, 11</samp>
+ </li>
+</ul>
+<p>MSIE 7</p>
+<ul>
+ <li>
+ <samp>undefined, 11</samp>
+ </li>
+ <li>
+ <samp>Object doesn't support this property or method</samp>
+ </li>
+ <li>
+ <samp>undefined, 11</samp>
+ </li>
+</ul>
+<p>MSIE 6</p>
+<ul>
+ <li>
+ <samp>undefined, 11</samp>
+ </li>
+ <li>
+ <samp>Object doesn't support this property or method</samp>
+ </li>
+ <li>
+ <samp>undefined, 11</samp>
+ </li>
+</ul>
+
+<div id="toc">
+ <h4>Table of Contents</h4>
+ <ul class="pagination linkList">
+ <li><a href="./index.html">Introduction</a></li>
+ <li><a href="extra_props.html">Extra Properties: <code>FORM</code> Elements</a></li>
+ <li><a href="extra_props_document.html">Extra Properties: <code>document</code></a></li>
+ <li>Extra Properties: <code>global</code></li>
+ <li><a href="event_handler.html">Event Handler Scope</a></li>
+ <li><a href="api_design.html">API Design?</a></li>
+ <li><a href="unsafe_names.html">Unsafe Names</a></li>
+ <li><a href="conclusion.html">Conclusion</a></li>
+ </ul>
+</div>
+<ul id="nextLink" class="linkList">
+ <li>
+ <span class="prev">Previous:</span> <a href="extra_props_document.html">Extra Properties: <code>document</code></a>
+ </li>
+ <li>
+ <span class="next">Next:</span> <a href="event_handler.html">Event Handler Scope</a>
+ </li>
+</ul>
+
+</body>
+</html>
\ No newline at end of file
/trunk/cljs/names/extra_props_global.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/form_dom_removal.html
===================================================================
--- trunk/cljs/names/form_dom_removal.html (nonexistent)
+++ trunk/cljs/names/form_dom_removal.html (revision 45)
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>Test element Removal</title>
+<style type='text/css'>
+ .fail { background: #F33; }
+ .pass { background: #0f0; }
+ b { display: none; padding: 1px 3px;
+ font-family: monospace; white-space: pre;}
+</style>
+</head>
+<body>
+<form action="">
+<input type="text" name="test">
+</form>
+
+<b id="failElements" class="fail">FAIL</b>
+<b id="passElements" class="pass">PASS</b>
+<strong>form.elements.test is null?</strong>
+
+<div>
+<b id="passForm" class="pass">PASS</b>
+<b id="failForm" class="fail">FAIL</b>
+<strong>form.test is null?</strong>
+</div>
+
+<script type="text/javascript">
+var d = document,
+ form = d.forms[0],
+ display = "inline-block",
+ failElements = d.getElementById('failElements'),
+ passElements = d.getElementById('passElements'),
+ failForm = d.getElementById('failForm'),
+ passForm = d.getElementById('passForm');
+
+// comment the following line to hide bug:
+form.test;
+
+while(form.lastChild){
+ form.removeChild(form.lastChild);
+}
+if(document.forms[0].elements.test )
+ failElements.style.display = display;
+else
+ passElements.style.display = display;
+
+if(document.forms[0].test )
+ failForm.style.display = display;
+else
+ passForm.style.display = display;
+</script>
+</body>
+</html>
\ No newline at end of file
/trunk/cljs/names/form_dom_removal.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/names.css
===================================================================
--- trunk/cljs/names/names.css (nonexistent)
+++ trunk/cljs/names/names.css (revision 45)
@@ -0,0 +1,104 @@
+#toc ul.linkList {
+ /* 160% * 62.5% = 100% */
+ font-size : 62.5%;
+ margin: 0;
+}
+
+body {
+ position: relative;
+}
+
+ul {
+ margin : 1em 2.0em 1.5em 2.5em;
+}
+ul.linkList li {
+ line-height: 120%;
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+
+#toc{
+ background: transparent;
+ border: 0;
+}
+
+ul.linkList li {
+ display: inline;
+ margin: .4em;
+ color: #334;
+ white-space: nowrap;
+}
+
+ul.linkList li a code {
+ color: inherit;
+ padding: 0;
+ font-size: 105%;
+ font-weight: normal;
+}
+
+#toc {
+ position: absolute;
+ top: 2em;
+ *top: 3em;
+ font-size : 160%;
+ padding: 0;
+ width: 97.5%;
+}
+
+#toc h4 {
+ font-size : 62.5%;
+ margin-bottom: 0;
+ display: none;
+ }
+
+h1 {
+ /* space for toc */
+ margin-bottom: 3em;
+}
+
+ul.linkList {
+ margin-left: 0;
+ margin-top: 0;
+ font-weight: 800;
+}
+
+.next, .prev {
+ font-style: italic;
+ color: #334;
+ margin-right: .1em;
+ font-weight: 400;
+}
+
+div {
+ padding: 0;
+ margin: 0;
+}
+
+button.evaluator {
+ margin-right: .4em;
+}
+
+ins {
+ background: #ffc;
+ border-bottom: 1px dotted #ec9;
+ margin: 1px;
+ text-decoration: none;
+ padding: 1px;
+}
+
+ins[title]:before, del[title]:before {
+ content: attr(title);
+ display: block;
+ background: #666;
+ color: #fff;
+ padding: 2px;
+ font-style: italic;
+}
+
+body > ins, body > del {
+ display: block;
+}
+del {
+ background: #fdc;
+ color: #333;
+}
/trunk/cljs/names/names.css
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/simple-leak-form-input.html
===================================================================
--- trunk/cljs/names/simple-leak-form-input.html (nonexistent)
+++ trunk/cljs/names/simple-leak-form-input.html (revision 45)
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head><title></title></head>
+<body>
+<form action=""><input name="foo"><input name="bar"></form>
+<pre>
+<script type="text/javascript">
+document.forms[0].foo;
+document.forms[0].elements.foo;
+
+// Clear out form's HTML.
+document.forms[0].innerHTML = "";
+document.write('foo: ' + document.forms[0].foo+'<br>');
+document.write('bar: '+document.forms[0].bar+'<br>');
+document.write('elements.foo: '+document.forms[0].elements.foo);
+</script>
+</pre>
+</body>
+</html>
\ No newline at end of file
/trunk/cljs/names/simple-leak-form-input.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/form_override_dom.html
===================================================================
--- trunk/cljs/names/form_override_dom.html (nonexistent)
+++ trunk/cljs/names/form_override_dom.html (revision 45)
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+ <title>FormElementCollection.html</title>
+ <style type="text/css">
+ input { font-size: 8px; font-family: courier new, monospace; padding: 0 }
+ #pass { display: none; background : #0f0; }
+ #fail { display: none; background : #F33; }
+ </style>
+</head>
+<body>
+<h1>Test: 290 Names not to give a FORM Control</h1>
+<form name="length" action="fail" title="fail">
+<input type="submit" />
+</form>
+<form name="title"></form>
+
+<pre id="pass">PASS - All Form Properties Replaced by an Element</pre>
+<pre id="fail">FAIL</pre>
+<pre>
+<script type='text/javascript' src="names.js"></script>
+<script type="text/javascript">
+
+(function(){
+var form = document.forms[0];
+var input = document.createElement('input'),
+ clone;
+var bugs = [];
+
+input.type = "text";
+
+for(var i = names.length -1; i >= 0; i--) {
+ try {
+ if(names[i] == names[i-1]) {
+ alert("found duplicate: " + names[i]);
+ break;
+ }
+ else {
+ clone = input.cloneNode(false);
+ clone.name = clone.id = names[i];
+ clone.value = names[i];
+ form.appendChild(clone);
+ }
+ } catch(ex) {
+ //("could not create input named: " + names[i]);
+ }
+}
+// can't use form.elements, form.getElementsByTagName, et c
+// because they were replaced by an input.
+
+var actual, expected, msg, actualString;
+for(i = 0; i < names.length; i++) {
+
+ actual = form[names[i]];
+ expected = document.getElementById(names[i]);
+ if(actual != expected) {
+ msg = names[i];
+ if(actual.toString && actual.toString.tagName)
+ actualString = actual.toString.tagName;
+ else
+ actualString = String(actual);
+ msg += " found: " + (((actualString + " ("+typeof actual+")")) || "(missing)");
+ bugs[bugs.length] = msg;
+ }
+}
+
+if(bugs.length > 0)
+ fail(bugs);
+else pass();
+
+function fail(bugs) {
+ var fail = document.getElementById('fail');
+ fail.firstChild.data += ': The following ' + bugs.length +
+ ' form properties should have been an INPUT element:\n * ' + bugs.join('\n * ');
+ fail.style.display = "inline-block";
+}
+
+function pass() {
+ var pass = document.getElementById('pass');
+ pass.style.display = "inline-block";
+}
+
+//document.write(names.join("\n &lt;/li&gt;\n &lt;li&gt;\n "));
+})();
+</script>
+</body>
+</html>
/trunk/cljs/names/form_override_dom.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/api_design.html
===================================================================
--- trunk/cljs/names/api_design.html (nonexistent)
+++ trunk/cljs/names/api_design.html (revision 45)
@@ -0,0 +1,169 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+<head>
+ <title>Unsafe Names for HTML Form Controls - API Design?</title>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <meta name="author" content="Garrett Smith">
+ <link rel="Start" href="./">
+ <link rel="stylesheet" href="../faq.css" type="text/css" media="all" charset="iso-8859-1">
+ <link rel="stylesheet" href="names.css" type="text/css" media="all" charset="iso-8859-1">
+</head>
+<body>
+
+ <h1>Unsafe Names for HTML Form Controls</h1>
+ <h2>API Design?</h2>
+ <h3>Form-as-a-collection Design Decision</h3>
+
+ <p>
+ Form-as-a-collection is problematic for implementors and should be a
+ concern for developers (because bugs can occur when unsafe names are used).
+ </p>
+
+ <p>
+ The idea of creating properties on a form creates
+ a conflict. In Opera, the same key may appear twice in a for in loop.
+ <a href="http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/a27c626bd71f1f0/"
+ >Opera, For In Loop, Same Key Appears Twice</a>.
+ </p>
+
+ <p>
+ The elements collection is a safe alternative.
+ By deprecating the non-standard mystery <code>"similar to a collection"</code>
+ behavior of a form, authors would be discouraged from using it.
+ </p>
+
+ <p>
+ Developers can still safely access the properties directly from the <code>elements</code> collection.
+ There is no need to standardize this.
+ </p>
+ <h4>HTML 5</h4>
+ <p>
+ The HTML 5 draft has merged in much of the Web Forms 2.0 specification,
+ which attempted to standardize some of the browser inconsistencies, strange behavior,
+ and bugs.
+ </p>
+
+ <h4 id="controls-example-2">toString Example</h4>
+ <p>
+ This example contains a <code>FORM</code> element with two form controls,
+ one named "length", the other "toString". A click callback is added to the
+ <code>FORM</code>'s <code>length</code> property. The body of the function calls
+ the <code>alert</code> function with the <code>FORM</code>.
+ </p>
+ <form action=";" id="form1" style="display:inline">
+ <input name="toString" type="hidden">
+ <input name="length" value="submit" type="submit">
+ </form>
+ (Click the submit button to see what happens.)
+
+ <script type="text/javascript">
+ (function (){
+ var form = document.getElementById('form1');
+ form.length.onclick = function(e) {
+ try{
+ alert(form);
+ } catch(ex) {
+ alert("Error:\n" +ex.message);
+ } finally {
+ return false;
+ }
+ };
+ })();
+ </script>
+
+ <p>
+ <a onclick="toggleDisplay('controls-example-2-source', 'block', 'none'); return false;"
+ href="">source...</a>
+ </p>
+
+ <pre id='controls-example-2-source' style="display:none">
+&lt;form action="" id="form1"&gt;
+&lt;input name="toString" type="hidden"/&gt;
+&lt;input name="length" value="submit" type="submit"/&gt;
+&lt;/form&gt;
+&lt;script type="text/javascript"&gt;
+(<span class='keyword'>function</span> (){
+ <span class='keyword'>var</span> form = document.getElementById(<span class='q'>'form1'</span>);
+ form.length.onclick = <span class='keyword'>function</span>(e) {
+ <span class='keyword'>try</span>{
+ alert(form);
+ } <span class='keyword'>catch</span>(ex) {
+ alert(<span class='q'>"Error:\n"</span> +ex.message);
+ } <span class='keyword'>finally</span> {
+ <span class='keyword'>return</span> <span class='keyword'>false</span>;
+ }
+ };
+})();&lt;/script&gt;
+ </pre>
+
+ <strong>Result</strong>
+ <p>
+ The callback tries to <code>alert</code>
+ the <code>FORM</code> but throws an error when the <code>alert</code> function
+ attempts to call the form's <code>toString</code>
+ property, which was shadowed by a form control.
+ </p>
+
+ <h3>Callable Collections</h3>
+ <p>
+ Many browsers make <code>HTMLCollection</code> collection a callable object.
+ When called, <code>document.forms(<var>x</var>)</code> returns a form element whose <code>name</code>,
+ <code>id</code>, or <code>index</code> matches the supplied argument <code><var>x</var></code>.
+ </p>
+ <p>
+ <a href="callable_example.html">Callable HTMLCollection Example</a>
+ </p>
+ <p>
+ The DOM does not standardize collections to be callable. There isn't a good reason to call
+ a collection. The property access operators provide a standard, cross-browser alternative.
+ Callable collections are not implented in Mozilla. This feature does not appear to be considered for
+ inclusion in HTML 5 or Web IDL.
+ </p>
+
+ <h3>Map-like NodeList Collections</h3>
+ <p>
+ Many browsers implement Map-like quality on <code>NodeList</code>.
+ In these browsers, elements are accessible off the <code>NodeList</code> by their ID.
+ </p>
+ <p>
+ <a href="map-like-nodelist.html">Map-like NodeList Example</a>
+ </p>
+ <p>
+ This behavior is nonstandard and may be present, but should not be used.
+ It is one innovation of Internet Explorer,
+ copied in Safari, Opera, and perhaps elsewhere.
+ </p>
+
+ <p>
+ Implementation developers and specifications authors must be aware of the permanence of
+ API Design. We should all be cognizant of the impact that an API has on the future.
+ </p>
+ <div id="toc">
+ <h4>Table of Contents</h4>
+ <ul class="pagination linkList">
+ <li><a href="./index.html">Introduction</a></li>
+ <li><a href="extra_props.html">Extra Properties: <code>FORM</code> Elements</a></li>
+ <li><a href="extra_props_document.html">Extra Properties: <code>document</code></a></li>
+ <li><a href="extra_props_global.html">Extra Properties: <code>global</code></a></li>
+ <li><a href="event_handler.html">Event Handler Scope</a></li>
+ <li>API Design?</li>
+ <li><a href="unsafe_names.html">Unsafe Names</a></li>
+ <li><a href="conclusion.html">Conclusion</a></li>
+ </ul>
+ </div>
+ <ul id="nextLink" class="linkList">
+ <li>
+ <span class="prev">Previous:</span> <a href="event_handler.html">Event Handler Scope</a>
+ </li>
+ <li>
+ <span class="next">Next:</span> <a href="unsafe_names.html">Unsafe Names</a>
+ </li>
+ </ul>
+ <script type="text/javascript">
+ function toggleDisplay(id, d1, d2) {
+ var s = document.getElementById(id).style;
+ s.display = s.display === d2 ? d1 : d2;
+ }
+ </script>
+</body>
+</html>
/trunk/cljs/names/api_design.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/unsafe_names.html
===================================================================
--- trunk/cljs/names/unsafe_names.html (nonexistent)
+++ trunk/cljs/names/unsafe_names.html (revision 45)
@@ -0,0 +1,997 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <title>Unsafe Names for HTML Form Controls - Unsafe Names</title>
+ <meta name="author" content="Garrett Smith">
+ <link rel="Start" href="./">
+ <link rel="stylesheet" href="../faq.css" type="text/css" media="all" charset="iso-8859-1">
+ <link rel="stylesheet" href="names.css" type="text/css" media="all" charset="iso-8859-1">
+</head>
+<body>
+
+ <h1>Unsafe Names for HTML Form Controls</h1>
+ <h2>Unsafe Names</h2>
+ <p>
+ There are roughly three-hundred (300) names which a form control
+ must not have.
+ </p>
+
+ <p>
+ Unsafely named elements can be added to a <code>FORM</code> object after
+ the form has been created, or can be included in the HTML source
+ code.
+ </p>
+
+<h3>
+Examples of Unsafe Form Control Names
+</h3>
+ <p>
+ Unsafe <code>FORM</code>
+ control names can appear in three ways:
+ </p>
+ <ol>
+ <li>In the <a href="form_override_html_source.html">HTML Source</a></li>
+ <li><a href="form_override_dom.html">Added via the DOM</a></li>
+ <li>From <a href="form_override_change_name.html">changing the <code>name</code> property</a></li>
+ </ol>
+
+ <p>
+ Not all browsers behave the same when using unsafe
+ <code>FORM</code> control names and a changing DOM.
+ </p>
+
+ <h3>Solution: Namespaced Form Controls</h3>
+ <p>
+ A naming system can help avoid unsafe names.
+ </p>
+ <p>
+ Name the form controls starting with a special prefix. The prefix should be
+ unique and represent the application.
+ </p>
+
+ <p>
+ For example, an application named "VortexMail" could use the prefix <code>vtxmail_</code>.
+ </p>
+
+ <pre>
+&lt;input name="vtxmail_fname" type="text"&gt;
+&lt;input name="vtxmail_data" type="file"&gt;
+&lt;input name="vtxmail_submit" type="submit"&gt;
+</pre>
+ <p>
+ A prefix can also act as an identifying characteristic of your program or company,
+ like a namespace.
+ </p>
+
+ <h4>Unsafe Names - Partial List</h4>
+ <p>
+ This list contains all the names that a form control should never have. It assumes
+ that event handler attributes are never used and excludes some
+ proposed properties from HTML 5
+ [<a href="conclusion.html#controls-normref">References</a>]. (e.g.
+ <code>autofocus</code>, <code>min</code>, <code>max</code>,
+ <code>height</code>, <code>labels</code>, <code>required</code>, <code>valid</code>, etc.).
+ </p>
+
+ <p>
+ If event handler attributes are used, the list of unsafe names also includes
+ every possible property name that exists on <code>document</code>, <code>window</code>,
+ and the object of the tag that the event handler is declared on (could be any tag).
+ This would bring the list to well over five-hundred (500) unsafe names, including
+ <code>atob</code>, <code>bgColor</code>, <code>clear</code>, <code>close</code>, <code>opener</code>,
+ <code>status</code>, <code>write</code>, etc.
+ </p>
+
+ <ol style="-moz-column-count: 2;
+ -webkit-column-count: 2;
+ column-count: 2;
+ -moz-column-gap: 20px;
+ -webkit-column-gap: 20px;
+ column-gap: 20px;
+ list-style-position:inside;">
+ <li>
+ ATTRIBUTE_NODE
+ </li>
+ <li>
+ CDATA_SECTION_NODE
+ </li>
+ <li>
+ COMMENT_NODE
+ </li>
+ <li>
+ DOCUMENT_FRAGMENT_NODE
+ </li>
+ <li>
+ DOCUMENT_NODE
+ </li>
+ <li>
+ DOCUMENT_POSITION_CONTAINED_BY
+ </li>
+ <li>
+ DOCUMENT_POSITION_CONTAINS
+ </li>
+ <li>
+ DOCUMENT_POSITION_DISCONNECTED
+ </li>
+ <li>
+ DOCUMENT_POSITION_FOLLOWING
+ </li>
+ <li>
+ DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+ </li>
+ <li>
+ DOCUMENT_POSITION_PRECEDING
+ </li>
+ <li>
+ DOCUMENT_TYPE_NODE
+ </li>
+ <li>
+ ELEMENT_NODE
+ </li>
+ <li>
+ ENTITY_NODE
+ </li>
+ <li>
+ ENTITY_REFERENCE_NODE
+ </li>
+ <li>
+ NOTATION_NODE
+ </li>
+ <li>
+ PROCESSING_INSTRUCTION_NODE
+ </li>
+ <li>
+ TEXT_NODE
+ </li>
+ <li>
+ accept
+ </li>
+ <li>
+ acceptCharset
+ </li>
+ <li>
+ action
+ </li>
+ <li>
+ addBehavior
+ </li>
+ <li>
+ addEventListener
+ </li>
+ <li>
+ addEventSource
+ </li>
+ <li>
+ addRepetitionBlock
+ </li>
+ <li>
+ addRepetitionBlockByIndex
+ </li>
+ <li>
+ all
+ </li>
+ <li>
+ appendChild
+ </li>
+ <li>
+ applyElement
+ </li>
+ <li>
+ ariaBusy
+ </li>
+ <li>
+ ariaChecked
+ </li>
+ <li>
+ ariaControls
+ </li>
+ <li>
+ ariaDescribability
+ </li>
+ <li>
+ ariaDisabled
+ </li>
+ <li>
+ ariaExpanded
+ </li>
+ <li>
+ ariaFlowto
+ </li>
+ <li>
+ ariaHaspopup
+ </li>
+ <li>
+ ariaHidden
+ </li>
+ <li>
+ ariaInvalid
+ </li>
+ <li>
+ ariaLabelledby
+ </li>
+ <li>
+ ariaLevel
+ </li>
+ <li>
+ ariaMultiselect
+ </li>
+ <li>
+ ariaOwns
+ </li>
+ <li>
+ ariaPosinset
+ </li>
+ <li>
+ ariaPressed
+ </li>
+ <li>
+ ariaReadonly
+ </li>
+ <li>
+ ariaRequired
+ </li>
+ <li>
+ ariaSecret
+ </li>
+ <li>
+ ariaSelected
+ </li>
+ <li>
+ ariaSetsize
+ </li>
+ <li>
+ ariaValuemax
+ </li>
+ <li>
+ ariaValuemin
+ </li>
+ <li>
+ ariaValuenow
+ </li>
+ <li>
+ attachEvent
+ </li>
+ <li>
+ attributes
+ </li>
+ <li>
+ autocomplete
+ </li>
+ <li>
+ baseURI
+ </li>
+ <li>
+ behaviorUrns
+ </li>
+ <li>
+ blockDiraction
+ </li>
+ <li>
+ blur
+ </li>
+ <li>
+ canHaveChildren
+ </li>
+ <li>
+ canHaveHTML
+ </li>
+ <li>
+ checkValidity
+ </li>
+ <li>
+ childElementCount
+ </li>
+ <li>
+ childNodes
+ </li>
+ <li>
+ children
+ </li>
+ <li>
+ className
+ </li>
+ <li>
+ clearAttributes
+ </li>
+ <li>
+ click
+ </li>
+ <li>
+ clientHeight
+ </li>
+ <li>
+ clientLeft
+ </li>
+ <li>
+ clientTop
+ </li>
+ <li>
+ clientWidth
+ </li>
+ <li>
+ cloneNode
+ </li>
+ <li>
+ compareDocumentPosition
+ </li>
+ <li>
+ componentFromPoint
+ </li>
+ <li>
+ constructor
+ </li>
+ <li>
+ contains
+ </li>
+ <li>
+ contentEditable
+ </li>
+ <li>
+ currentStyle
+ </li>
+ <li>
+ data
+ </li>
+ <li>
+ detachEvent
+ </li>
+ <li>
+ dir
+ </li>
+ <li>
+ dispatchEvent
+ </li>
+ <li>
+ dispatchFormChange
+ </li>
+ <li>
+ dispatchFormInput
+ </li>
+ <li>
+ document
+ </li>
+ <li>
+ dragDrop
+ </li>
+ <li>
+ elements
+ </li>
+ <li>
+ encoding
+ </li>
+ <li>
+ enctype
+ </li>
+ <li>
+ fireEvent
+ </li>
+ <li>
+ firstChild
+ </li>
+ <li>
+ firstElementChild
+ </li>
+ <li>
+ focus
+ </li>
+ <li>
+ getAdjacentText
+ </li>
+ <li>
+ getAttribute
+ </li>
+ <li>
+ getAttributeNS
+ </li>
+ <li>
+ getAttributeNode
+ </li>
+ <li>
+ getAttributeNodeNS
+ </li>
+ <li>
+ getBoundingClientRect
+ </li>
+ <li>
+ getClientRects
+ </li>
+ <li>
+ getElementsByClassName
+ </li>
+ <li>
+ getElementsByTagName
+ </li>
+ <li>
+ getElementsByTagNameNS
+ </li>
+ <li>
+ getExpression
+ </li>
+ <li>
+ getFeature
+ </li>
+ <li>
+ getUserData
+ </li>
+ <li>
+ hasAttribute
+ </li>
+ <li>
+ hasAttributeNS
+ </li>
+ <li>
+ hasAttributes
+ </li>
+ <li>
+ hasChildNodes
+ </li>
+ <li>
+ hasOwnProperty
+ </li>
+ <li>
+ hideFocus
+ </li>
+ <li>
+ id
+ </li>
+ <li>
+ innerHTML
+ </li>
+ <li>
+ innerText
+ </li>
+ <li>
+ insertAdjacentElement
+ </li>
+ <li>
+ insertAdjacentHTML
+ </li>
+ <li>
+ insertAdjacentText
+ </li>
+ <li>
+ insertBefore
+ </li>
+ <li>
+ isContentEditable
+ </li>
+ <li>
+ isDefaultNamespace
+ </li>
+ <li>
+ isDefaultNamespaceURI
+ </li>
+ <li>
+ isDisabled
+ </li>
+ <li>
+ isEqualNode
+ </li>
+ <li>
+ isMultiLine
+ </li>
+ <li>
+ isPrototypeOf
+ </li>
+ <li>
+ isSameNode
+ </li>
+ <li>
+ isSupported
+ </li>
+ <li>
+ isTextEdit
+ </li>
+ <li>
+ item
+ </li>
+ <li>
+ lang
+ </li>
+ <li>
+ language
+ </li>
+ <li>
+ lastChild
+ </li>
+ <li>
+ lastElementChild
+ </li>
+ <li>
+ length
+ </li>
+ <li>
+ localName
+ </li>
+ <li>
+ lookupPrefix
+ </li>
+ <li>
+ mergeAttributes
+ </li>
+ <li>
+ method
+ </li>
+ <li>
+ moveRepetitionBlock
+ </li>
+ <li>
+ msBlockProgression
+ </li>
+ <li>
+ msBoxSizing
+ </li>
+ <li>
+ name
+ </li>
+ <li>
+ namedItem
+ </li>
+ <li>
+ namespaceURI
+ </li>
+ <li>
+ nextSibling
+ </li>
+ <li>
+ nodeName
+ </li>
+ <li>
+ nodeType
+ </li>
+ <li>
+ nodeValue
+ </li>
+ <li>
+ normalize
+ </li>
+ <li>
+ offsetHeight
+ </li>
+ <li>
+ offsetWidth
+ </li>
+ <li>
+ onOffBehavior
+ </li>
+ <li>
+ onabort
+ </li>
+ <li>
+ onactivate
+ </li>
+ <li>
+ onbeforeactivate
+ </li>
+ <li>
+ onbeforecopy
+ </li>
+ <li>
+ onbeforecut
+ </li>
+ <li>
+ onbeforedeactivate
+ </li>
+ <li>
+ onbeforeeditfocus
+ </li>
+ <li>
+ onbeforepaste
+ </li>
+ <li>
+ onblur
+ </li>
+ <li>
+ onchage
+ </li>
+ <li>
+ onclick
+ </li>
+ <li>
+ onclosecapture
+ </li>
+ <li>
+ oncontextmenu
+ </li>
+ <li>
+ oncopy
+ </li>
+ <li>
+ oncut
+ </li>
+ <li>
+ ondblclick
+ </li>
+ <li>
+ ondeactivate
+ </li>
+ <li>
+ ondrag
+ </li>
+ <li>
+ ondragend
+ </li>
+ <li>
+ ondragenter
+ </li>
+ <li>
+ ondragleave
+ </li>
+ <li>
+ ondragover
+ </li>
+ <li>
+ onerror
+ </li>
+ <li>
+ onfocus
+ </li>
+ <li>
+ onfocusin
+ </li>
+ <li>
+ onfocusout
+ </li>
+ <li>
+ onhelp
+ </li>
+ <li>
+ oninput
+ </li>
+ <li>
+ onkeydown
+ </li>
+ <li>
+ onkeypress
+ </li>
+ <li>
+ onkeyup
+ </li>
+ <li>
+ onmousedown
+ </li>
+ <li>
+ onmouseenter
+ </li>
+ <li>
+ onmouseleave
+ </li>
+ <li>
+ onmousemove
+ </li>
+ <li>
+ onmousemultiwheel
+ </li>
+ <li>
+ onmouseout
+ </li>
+ <li>
+ onmouseover
+ </li>
+ <li>
+ onmouseup
+ </li>
+ <li>
+ onmousewheel
+ </li>
+ <li>
+ onmove
+ </li>
+ <li>
+ onmoveend
+ </li>
+ <li>
+ onmovestart
+ </li>
+ <li>
+ onpaste
+ </li>
+ <li>
+ onpropertychange
+ </li>
+ <li>
+ onreadystatechange
+ </li>
+ <li>
+ onresize
+ </li>
+ <li>
+ onresizeend
+ </li>
+ <li>
+ onresizestart
+ </li>
+ <li>
+ onscroll
+ </li>
+ <li>
+ onsearch
+ </li>
+ <li>
+ onselect
+ </li>
+ <li>
+ onselectstart
+ </li>
+ <li>
+ ontimeerror
+ </li>
+ <li>
+ onunload
+ </li>
+ <li>
+ outerHTML
+ </li>
+ <li>
+ outerText
+ </li>
+ <li>
+ ownerDocument
+ </li>
+ <li>
+ parentNode
+ </li>
+ <li>
+ parentTextEdit
+ </li>
+ <li>
+ prefix
+ </li>
+ <li>
+ previousElementSibling
+ </li>
+ <li>
+ previousSibling
+ </li>
+ <li>
+ propertyIsEnumerable
+ </li>
+ <li>
+ querySelector
+ </li>
+ <li>
+ querySelectorAll
+ </li>
+ <li>
+ quotes
+ </li>
+ <li>
+ releaseCapture
+ </li>
+ <li>
+ removeAttribute
+ </li>
+ <li>
+ removeAttributeNS
+ </li>
+ <li>
+ removeAttributeNode
+ </li>
+ <li>
+ removeBehavior
+ </li>
+ <li>
+ removeChild
+ </li>
+ <li>
+ removeEventListener
+ </li>
+ <li>
+ removeEventSource
+ </li>
+ <li>
+ removeExpression
+ </li>
+ <li>
+ removeNode
+ </li>
+ <li>
+ removeRepetitionBlock
+ </li>
+ <li>
+ repeatMax
+ </li>
+ <li>
+ repeatMin
+ </li>
+ <li>
+ repeatStart
+ </li>
+ <li>
+ repetitionBlocks
+ </li>
+ <li>
+ repetitionIndex
+ </li>
+ <li>
+ repetitionTemplate
+ </li>
+ <li>
+ repetitionType
+ </li>
+ <li>
+ replace
+ </li>
+ <li>
+ replaceAdjacentText
+ </li>
+ <li>
+ replaceChild
+ </li>
+ <li>
+ replaceNode
+ </li>
+ <li>
+ reset
+ </li>
+ <li>
+ resetFromData
+ </li>
+ <li>
+ role
+ </li>
+ <li>
+ runtimeStyle
+ </li>
+ <li>
+ schemaTypeInfo
+ </li>
+ <li>
+ scopeName
+ </li>
+ <li>
+ scrollByLines
+ </li>
+ <li>
+ scrollByPages
+ </li>
+ <li>
+ scrollHeight
+ </li>
+ <li>
+ scrollIntoView
+ </li>
+ <li>
+ scrollLeft
+ </li>
+ <li>
+ scrollTop
+ </li>
+ <li>
+ scrollWidth
+ </li>
+ <li>
+ selectNodes
+ </li>
+ <li>
+ selectSingleNode
+ </li>
+ <li>
+ setActive
+ </li>
+ <li>
+ setAttributeNS
+ </li>
+ <li>
+ setAttributeNode
+ </li>
+ <li>
+ setAttributeNodeNS
+ </li>
+ <li>
+ setCapture
+ </li>
+ <li>
+ setExpression
+ </li>
+ <li>
+ setIdAttribute
+ </li>
+ <li>
+ setIdAttributeNS
+ </li>
+ <li>
+ setIdAttributeNode
+ </li>
+ <li>
+ setUserData
+ </li>
+ <li>
+ sourceIndex
+ </li>
+ <li>
+ spellcheck
+ </li>
+ <li>
+ style
+ </li>
+ <li>
+ submit
+ </li>
+ <li>
+ swapNode
+ </li>
+ <li>
+ tabIndex
+ </li>
+ <li>
+ tagName
+ </li>
+ <li>
+ tagUrn
+ </li>
+ <li>
+ target
+ </li>
+ <li>
+ templateElements
+ </li>
+ <li>
+ text
+ </li>
+ <li>
+ textContent
+ </li>
+ <li>
+ title
+ </li>
+ <li>
+ toLocaleString
+ </li>
+ <li>
+ toString
+ </li>
+ <li>
+ uniqueID
+ </li>
+ <li>
+ unselectable
+ </li>
+ <li>
+ unwatch
+ </li>
+ <li>
+ urns
+ </li>
+ <li>
+ valueOf
+ </li>
+ <li>
+ watch
+ </li>
+ <li>
+ window
+ </li>
+ </ol>
+
+ <h4 style="clear:both">Early Adopter</h4>
+ <p>
+ Safari 3 has implemented the behavior specified in more closely than
+ Safari 2. Safari 3 replaces more pre-existing properties of a
+ <code>FORM</code> when an element with the same name is added.
+ </p>
+
+ <div id="toc">
+ <h4>Table of Contents</h4>
+ <ul class="pagination linkList">
+ <li><a href="./index.html">Introduction</a></li>
+ <li><a href="extra_props.html">Extra Properties: <code>FORM</code> Elements</a></li>
+ <li><a href="extra_props_document.html">Extra Properties: <code>document</code></a></li>
+ <li><a href="extra_props_global.html">Extra Properties: <code>global</code></a></li>
+ <li><a href="event_handler.html">Event Handler Scope</a></li>
+ <li><a href="api_design.html">API Design?</a></li>
+ <li>Unsafe Names</li>
+ <li><a href="conclusion.html">Conclusion</a></li>
+ </ul>
+ </div>
+ <ul id="nextLink" class="linkList">
+ <li>
+ <span class="prev">Previous:</span> <a href="api_design.html">API Design?</a>
+ </li>
+ <li>
+ <span class="next">Next:</span> <a href="conclusion.html">Conclusion</a>
+ </li>
+ </ul>
+</body>
+</html>
/trunk/cljs/names/unsafe_names.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/extra_props_document.html
===================================================================
--- trunk/cljs/names/extra_props_document.html (nonexistent)
+++ trunk/cljs/names/extra_props_document.html (revision 45)
@@ -0,0 +1,86 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+<head>
+ <title>Unsafe Names for HTML Form Controls - Extra Properties: Document</title>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <meta name="author" content="Garrett Smith">
+ <link rel="Start" href="./">
+ <link rel="stylesheet" href="../faq.css" type="text/css" media="all" charset="iso-8859-1">
+ <link rel="stylesheet" href="names.css" type="text/css" media="all" charset="iso-8859-1">
+</head>
+<body>
+
+ <h1>Unsafe Names for HTML Form Controls</h1>
+ <h2>Extra Properties: <code>document</code></h2>
+
+ <h3>Non-Standard Named Properties</h3>
+ <p>
+ A browser may add a property to the <code>document</code> for each named
+ (or <code>id</code>'d) FORM element, IMG, or possibly any other element.
+ Alternatively, the same
+ browser may implement a specialized <code>[[Get]]</code> method to find the property.
+ </p>
+
+ <form action="" id="testFormID" name="testFormName">
+ <pre>
+&lt;form action="" id="testFormID" name="testFormName"&gt;
+&lt;/form&gt;
+</pre>
+ <button class="evaluator" onclick="this.nextSibling.firstChild.data = eval(this.firstChild.data);return false"
+ >'testFormID' in document</button
+ ><span>&nbsp;</span>
+ <button class="evaluator" onclick="this.nextSibling.firstChild.data = eval(this.firstChild.data);return false"
+ >'testFormName' in document</button
+ ><span>&nbsp;</span>
+ <img name="testImgNAME" src="" alt="404" style="z-index: -1;position:relative;">
+<pre>
+&lt;img name="testImgNAME" src=""&gt;
+</pre>
+
+ <button class="evaluator" onclick="this.nextSibling.firstChild.data = eval(this.firstChild.data);return false"
+ >'testImgNAME' in document</button
+ ><span>&nbsp;</span>
+
+ <a name='testLinkNAME' style="z-index: -1;position:relative;">link</a>
+<pre>
+&lt;a name='testLinkNAME'&gt;link&lt;/a&gt;
+</pre>
+ <button class="evaluator" onclick="this.nextSibling.firstChild.data = eval(this.firstChild.data);return false"
+ >'testLinkNAME' in document</button
+ ><span>&nbsp;</span>
+ </form>
+
+ <h3>Non Standard</h3>
+
+ <p>
+ Accessing objects from the <code>document</code> collection is not standard and unsafe.
+ </p>
+
+ <p>
+ The extra properties added to <code>document</code>
+ can cause problems with Event Handler Content Attributes as we will see later on.
+ </p>
+
+ <div id="toc">
+ <h4>Table of Contents</h4>
+ <ul class="pagination linkList">
+ <li><a href="./index.html">Introduction</a></li>
+ <li><a href="extra_props.html">Extra Properties: <code>FORM</code> Elements</a></li>
+ <li>Extra Properties: <code>document</code></li>
+ <li><a href="extra_props_global.html">Extra Properties: <code>global</code></a></li>
+ <li><a href="event_handler.html">Event Handler Scope</a></li>
+ <li><a href="api_design.html">API Design?</a></li>
+ <li><a href="unsafe_names.html">Unsafe Names</a></li>
+ <li><a href="conclusion.html">Conclusion</a></li>
+ </ul>
+ </div>
+ <ul id="nextLink" class="linkList">
+ <li>
+ <span class="prev">Previous:</span> <a href="extra_props.html">Extra Properties: <code>FORM</code> Elements</a>
+ </li>
+ <li>
+ <span class="next">Next:</span> <a href="extra_props_global.html">Extra Properties: <code>global</code></a>
+ </li>
+ </ul>
+</body>
+</html>
/trunk/cljs/names/extra_props_document.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/extra_props.html
===================================================================
--- trunk/cljs/names/extra_props.html (nonexistent)
+++ trunk/cljs/names/extra_props.html (revision 45)
@@ -0,0 +1,182 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+<head>
+ <title>Unsafe Names for HTML Form Controls - Extra Properties: Form Elements</title>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <meta name="author" content="Garrett Smith">
+ <link rel="Start" href="./">
+ <link rel="stylesheet" href="../faq.css" type="text/css" media="all" charset="iso-8859-1">
+ <link rel="stylesheet" href="names.css" type="text/css" media="all" charset="iso-8859-1">
+</head>
+<body>
+
+ <h1>Unsafe Names for HTML Form Controls</h1>
+ <h2>Extra Properties: <code>FORM</code> Elements</h2>
+
+ <h3>Named Properties</h3>
+ <p>
+ A browser may add a property to the either the <code>FORM</code> or
+ <code>elements</code> collection for each named (or <code>id</code>'d) element.
+ Alternatively, the same
+ browser may implement a specialized <code>[[Get]]</code> method to find the property.
+ </p>
+ <p>The way to tell if an object has a property is to use the <code>in</code> operator.</p>
+
+ <form action="">
+ <button name='test' onclick="this.nextSibling.firstChild.data = eval(this.firstChild.data);return false"
+ >'test' in this.form</button
+ ><span>&nbsp;</span>
+ <button name='test' onclick="this.nextSibling.firstChild.data = eval(this.firstChild.data);return false"
+ >'test' in this.form.elements</button
+ ><span>&nbsp;</span>
+ </form>
+
+ <p>
+ Behavior varies between browsers,
+ and between <code>FORM</code> and <code>elements</code>. When named properties
+ exist, they usually appear to have the attributes <code>ReadOnly</code>, <code>DontDelete</code>.
+ </p>
+
+ <h3>Indexed Properties</h3>
+ <p>
+ Browsers also either add indexed properties to the collection or form or implement
+ a specialized <code>[[Get]]</code> method to find the property. As with named properties, most browsers
+ will actually add the property to the collection.
+ </p>
+
+ <form action="">
+ <button name='test' onclick="this.nextSibling.firstChild.data = eval(this.firstChild.data);return false"
+ >'0' in this.form</button
+ ><span>&nbsp;</span>
+ <button name='test' onclick="this.nextSibling.firstChild.data = eval(this.firstChild.data);return false"
+ >'0' in this.form.elements</button
+ ><span>&nbsp;</span>
+ </form>
+
+ <p>
+ Mozilla seems to be the only browser that implements a specialized [[Get]].
+ </p>
+
+ <h3 id="StandardWrong">Standard</h3>
+ <p>
+ The <code>elements</code> collection is an <code>HTMLCollection</code> that provides a
+ standard way to access form controls.
+ </p>
+
+ <p>
+ Web IDL [<a href="conclusion.html#controls-normref">WebIDL</a>] lumps these behaviors into
+ the terms: <code>[[NameGetter]]</code> and <code>[[IndexGetter]]</code>.
+ Not all browsers have a specialized <code>[[Get]]</code> to retrieve named elements;
+ the ones that do (Mozilla) don't always use it for every collection, so the term is a bit
+ of a misnomer.
+ </p>
+ <p>
+ We can see the influence Java programmers had in the DOM 2 ECMAScript bindings
+ [<a href="conclusion.html#controls-normref">DOM2</a>],
+ which falsely states:
+ </p>
+
+ <blockquote cite="http://www.w3.org/TR/DOM-Level-2-HTML/ECMA-script-binding.html">
+ <strong>Objects that implement the <code>HTMLCollection</code> interface:</strong>
+ ...
+ <p>
+ <strong>Note:</strong> This object can also be dereferenced using square
+ bracket notation (e.g. <code>obj[1]</code>). Dereferencing with an integer
+ <strong>index</strong> is equivalent to invoking the <strong><code>item</code></strong> function
+ with that index.
+ </p>
+ ...
+ <p>
+ <strong>Note:</strong> This object can also be dereferenced using square
+ bracket notation (e.g. <code>obj["foo"]</code>). Dereferencing using a string
+ index is equivalent to invoking the <strong><code>namedItem</code></strong> function with
+ that index.
+ </p>
+ </blockquote>
+
+ <h3>Property Access Operators</h3>
+ <p>
+ Contrary to what the [<a href="conclusion.html#controls-normref">DOM 1</a>]
+ specification states, the <code>[ ]</code> property access operator does not perform
+ a typecheck. In ECMAScript, property access
+ is performed with <code>obj[ <var>Expression</var> ]</code> or
+ <code>obj . <var>Identifier</var></code>.
+ </p>
+
+ <h4>Property Access on a Form</h4>
+ <p>
+ When the named or indexed property is added to the form,
+ there is no call to <code>item</code> or <code>namedItem</code>. The specification
+ is wrong.
+ </p>
+
+ <p>
+ When the property access operator is used, the <code><var>Expression</var></code> is
+ converted to a string with the internal <code>ToString</code>.
+ The internal <code>ToString</code> method calls the object's <code>toString</code>
+ property if it is an object or, if <code>toString</code> is not an object, the <code>valueOf</code>
+ property is to be called (though results vary).
+ </p>
+
+ <h4>Property Access on a Form Example</h4>
+ <p>
+ The following example
+ shows that with <code>form[ <var>Expression</var> ]</code>,
+ the <code><var>Expression</var></code>, an <code>ObjectLiteral</code>,
+ results in an Object. This object's <code>toString</code> method
+ is called by the internal [[ToString]].
+ </p>
+
+ <form action="">
+ <button name='test' onclick="this.nextSibling.data += eval(this.firstChild.data);return false"
+ >this.form["0"] === this.form[ { toString : function(){ return 0; } } ]</button
+ >&nbsp;
+ </form>
+
+ <p>
+ The property access operator results in a call to the object's <code>toString</code>
+ property and the resulting primitive value is converted to the string value <samp>"0"</samp>.
+ </p>
+
+ <p>
+ Had the authors of the DOM specification ECMAScript bindings written some tests,
+ they could have learned how this basic feature of property access works in ECMAScript.
+ </p>
+
+ <p>
+ Accessing form controls from the <code>elements</code> collection reduces ambiguity
+ in the code. Control names that may conflict with the collection's properties are limited to:
+ <code>length</code>, <code>item</code>, <code>namedItem</code>, <code>tags</code>.
+ The names <code>document</code>, and <code>window</code> are still unsafe.
+ </p>
+
+ <p>
+ Accessing form controls from the <code>elements</code> collection is safe. There
+ are fewer conflicting names and, unlike form-as-a-collection, <code>elements</code>
+ is a live representation.
+ </p>
+
+
+ <div id="toc">
+ <h4>Table of Contents</h4>
+ <ul class="pagination linkList">
+ <li><a href="./index.html">Introduction</a></li>
+ <li>Extra Properties: <code>FORM</code> Elements</li>
+ <li><a href="extra_props_document.html">Extra Properties: <code>document</code></a></li>
+ <li><a href="extra_props_global.html">Extra Properties: <code>global</code></a></li>
+ <li><a href="event_handler.html">Event Handler Scope</a></li>
+ <li><a href="api_design.html">API Design?</a></li>
+ <li><a href="unsafe_names.html">Unsafe Names</a></li>
+ <li><a href="conclusion.html">Conclusion</a></li>
+ </ul>
+ </div>
+ <ul id="nextLink" class="linkList">
+ <li>
+ <span class="prev">Previous:</span> <a href="index.html">Introduction</a>
+ </li>
+ <li>
+ <span class="next">Next:</span> <a href="extra_props_document.html">Extra Properties: <code>document</code></a>
+ </li>
+ </ul>
+</body>
+</html>
/trunk/cljs/names/extra_props.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/form_override_html_source.html
===================================================================
--- trunk/cljs/names/form_override_html_source.html (nonexistent)
+++ trunk/cljs/names/form_override_html_source.html (revision 45)
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+ <title>FormElementCollection.html</title>
+ <style type="text/css">
+ #pass { display: none; background : #0f0; }
+ #fail { display: none; background : #F33; }
+ </style>
+</head>
+<body>
+<h1>Test: 290 Names not to give a FORM Control</h1>
+<form action="">
+<input name="window" id="window" type="text"><input name="watch" id="watch" type="text"><input name="valueOf" id="valueOf" type="text"><input name="urns" id="urns" type="text"><input name="unwatch" id="unwatch" type="text"><input name="unselectable" id="unselectable" type="text"><input name="uniqueID" id="uniqueID" type="text"><input name="toString" id="toString" type="text"><input name="toLocaleString" id="toLocaleString" type="text"><input name="title" id="title" type="text"><input name="textContent" id="textContent" type="text"><input name="text" id="text" type="text"><input name="templateElements" id="templateElements" type="text"><input name="target" id="target" type="text"><input name="tagUrn" id="tagUrn" type="text"><input name="tagName" id="tagName" type="text"><input name="tabIndex" id="tabIndex" type="text"><input name="swapNode" id="swapNode" type="text"><input name="submit" id="submit" type="text"><input name="style" id="style" type="text"><input name="spellcheck" id="spellcheck" type="text"><input name="sourceIndex" id="sourceIndex" type="text"><input name="setUserData" id="setUserData" type="text"><input name="setIdAttributeNode" id="setIdAttributeNode" type="text"><input name="setIdAttributeNS" id="setIdAttributeNS" type="text"><input name="setIdAttribute" id="setIdAttribute" type="text"><input name="setExpression" id="setExpression" type="text"><input name="setCapture" id="setCapture" type="text"><input name="setAttributeNodeNS" id="setAttributeNodeNS" type="text"><input name="setAttributeNode" id="setAttributeNode" type="text"><input name="setAttributeNS" id="setAttributeNS" type="text"><input name="setActive" id="setActive" type="text"><input name="selectSingleNode" id="selectSingleNode" type="text"><input name="selectNodes" id="selectNodes" type="text"><input name="scrollWidth" id="scrollWidth" type="text"><input name="scrollTop" id="scrollTop" type="text"><input name="scrollLeft" id="scrollLeft" type="text"><input name="scrollIntoView" id="scrollIntoView" type="text"><input name="scrollHeight" id="scrollHeight" type="text"><input name="scrollByPages" id="scrollByPages" type="text"><input name="scrollByLines" id="scrollByLines" type="text"><input name="scopeName" id="scopeName" type="text"><input name="schemaTypeInfo" id="schemaTypeInfo" type="text"><input name="runtimeStyle" id="runtimeStyle" type="text"><input name="role" id="role" type="text"><input name="resetFromData" id="resetFromData" type="text"><input name="reset" id="reset" type="text"><input name="replaceNode" id="replaceNode" type="text"><input name="replaceChild" id="replaceChild" type="text"><input name="replaceAdjacentText" id="replaceAdjacentText" type="text"><input name="replace" id="replace" type="text"><input name="repetitionType" id="repetitionType" type="text"><input name="repetitionTemplate" id="repetitionTemplate" type="text"><input name="repetitionIndex" id="repetitionIndex" type="text"><input name="repetitionBlocks" id="repetitionBlocks" type="text"><input name="repeatStart" id="repeatStart" type="text"><input name="repeatMin" id="repeatMin" type="text"><input name="repeatMax" id="repeatMax" type="text"><input name="removeRepetitionBlock" id="removeRepetitionBlock" type="text"><input name="removeNode" id="removeNode" type="text"><input name="removeExpression" id="removeExpression" type="text"><input name="removeEventSource" id="removeEventSource" type="text"><input name="removeEventListener" id="removeEventListener" type="text"><input name="removeChild" id="removeChild" type="text"><input name="removeBehavior" id="removeBehavior" type="text"><input name="removeAttributeNode" id="removeAttributeNode" type="text"><input name="removeAttributeNS" id="removeAttributeNS" type="text"><input name="removeAttribute" id="removeAttribute" type="text"><input name="releaseCapture" id="releaseCapture" type="text"><input name="quotes" id="quotes" type="text"><input name="querySelectorAll" id="querySelectorAll" type="text"><input name="querySelector" id="querySelector" type="text"><input name="propertyIsEnumerable" id="propertyIsEnumerable" type="text"><input name="previousSibling" id="previousSibling" type="text"><input name="previousElementSibling" id="previousElementSibling" type="text"><input name="prefix" id="prefix" type="text"><input name="parentTextEdit" id="parentTextEdit" type="text"><input name="parentNode" id="parentNode" type="text"><input name="ownerDocument" id="ownerDocument" type="text"><input name="outerText" id="outerText" type="text"><input name="outerHTML" id="outerHTML" type="text"><input name="onunload" id="onunload" type="text"><input name="ontimeerror" id="ontimeerror" type="text"><input name="onselectstart" id="onselectstart" type="text"><input name="onselect" id="onselect" type="text"><input name="onsearch" id="onsearch" type="text"><input name="onscroll" id="onscroll" type="text"><input name="onresizestart" id="onresizestart" type="text"><input name="onresizeend" id="onresizeend" type="text"><input name="onresize" id="onresize" type="text"><input name="onreadystatechange" id="onreadystatechange" type="text"><input name="onpropertychange" id="onpropertychange" type="text"><input name="onpaste" id="onpaste" type="text"><input name="onmovestart" id="onmovestart" type="text"><input name="onmoveend" id="onmoveend" type="text"><input name="onmove" id="onmove" type="text"><input name="onmousewheel" id="onmousewheel" type="text"><input name="onmouseup" id="onmouseup" type="text"><input name="onmouseover" id="onmouseover" type="text"><input name="onmouseout" id="onmouseout" type="text"><input name="onmousemultiwheel" id="onmousemultiwheel" type="text"><input name="onmousemove" id="onmousemove" type="text"><input name="onmouseleave" id="onmouseleave" type="text"><input name="onmouseenter" id="onmouseenter" type="text"><input name="onmousedown" id="onmousedown" type="text"><input name="onkeyup" id="onkeyup" type="text"><input name="onkeypress" id="onkeypress" type="text"><input name="onkeydown" id="onkeydown" type="text"><input name="oninput" id="oninput" type="text"><input name="onhelp" id="onhelp" type="text"><input name="onfocusout" id="onfocusout" type="text"><input name="onfocusin" id="onfocusin" type="text"><input name="onfocus" id="onfocus" type="text"><input name="onerror" id="onerror" type="text"><input name="ondragover" id="ondragover" type="text"><input name="ondragleave" id="ondragleave" type="text"><input name="ondragenter" id="ondragenter" type="text"><input name="ondragend" id="ondragend" type="text"><input name="ondrag" id="ondrag" type="text"><input name="ondeactivate" id="ondeactivate" type="text"><input name="ondblclick" id="ondblclick" type="text"><input name="oncut" id="oncut" type="text"><input name="oncopy" id="oncopy" type="text"><input name="oncontextmenu" id="oncontextmenu" type="text"><input name="onclosecapture" id="onclosecapture" type="text"><input name="onclick" id="onclick" type="text"><input name="onchage" id="onchage" type="text"><input name="onblur" id="onblur" type="text"><input name="onbeforepaste" id="onbeforepaste" type="text"><input name="onbeforeeditfocus" id="onbeforeeditfocus" type="text"><input name="onbeforedeactivate" id="onbeforedeactivate" type="text"><input name="onbeforecut" id="onbeforecut" type="text"><input name="onbeforecopy" id="onbeforecopy" type="text"><input name="onbeforeactivate" id="onbeforeactivate" type="text"><input name="onactivate" id="onactivate" type="text"><input name="onabort" id="onabort" type="text"><input name="onOffBehavior" id="onOffBehavior" type="text"><input name="offsetWidth" id="offsetWidth" type="text"><input name="offsetHeight" id="offsetHeight" type="text"><input name="normalize" id="normalize" type="text"><input name="nodeValue" id="nodeValue" type="text"><input name="nodeType" id="nodeType" type="text"><input name="nodeName" id="nodeName" type="text"><input name="nextSibling" id="nextSibling" type="text"><input name="namespaceURI" id="namespaceURI" type="text"><input name="namedItem" id="namedItem" type="text"><input name="name" id="name" type="text"><input name="msBoxSizing" id="msBoxSizing" type="text"><input name="msBlockProgression" id="msBlockProgression" type="text"><input name="moveRepetitionBlock" id="moveRepetitionBlock" type="text"><input name="method" id="method" type="text"><input name="mergeAttributes" id="mergeAttributes" type="text"><input name="lookupPrefix" id="lookupPrefix" type="text"><input name="localName" id="localName" type="text"><input name="length" id="length" type="text"><input name="lastElementChild" id="lastElementChild" type="text"><input name="lastChild" id="lastChild" type="text"><input name="language" id="language" type="text"><input name="lang" id="lang" type="text"><input name="item" id="item" type="text"><input name="isTextEdit" id="isTextEdit" type="text"><input name="isSupported" id="isSupported" type="text"><input name="isSameNode" id="isSameNode" type="text"><input name="isPrototypeOf" id="isPrototypeOf" type="text"><input name="isMultiLine" id="isMultiLine" type="text"><input name="isEqualNode" id="isEqualNode" type="text"><input name="isDisabled" id="isDisabled" type="text"><input name="isDefaultNamespaceURI" id="isDefaultNamespaceURI" type="text"><input name="isDefaultNamespace" id="isDefaultNamespace" type="text"><input name="isContentEditable" id="isContentEditable" type="text"><input name="insertBefore" id="insertBefore" type="text"><input name="insertAdjacentText" id="insertAdjacentText" type="text"><input name="insertAdjacentHTML" id="insertAdjacentHTML" type="text"><input name="insertAdjacentElement" id="insertAdjacentElement" type="text"><input name="innerText" id="innerText" type="text"><input name="innerHTML" id="innerHTML" type="text"><input name="id" id="id" type="text"><input name="hideFocus" id="hideFocus" type="text"><input name="hasOwnProperty" id="hasOwnProperty" type="text"><input name="hasChildNodes" id="hasChildNodes" type="text"><input name="hasAttributes" id="hasAttributes" type="text"><input name="hasAttributeNS" id="hasAttributeNS" type="text"><input name="hasAttribute" id="hasAttribute" type="text"><input name="getUserData" id="getUserData" type="text"><input name="getFeature" id="getFeature" type="text"><input name="getExpression" id="getExpression" type="text"><input name="getElementsByTagNameNS" id="getElementsByTagNameNS" type="text"><input name="getElementsByTagName" id="getElementsByTagName" type="text"><input name="getElementsByClassName" id="getElementsByClassName" type="text"><input name="getClientRects" id="getClientRects" type="text"><input name="getBoundingClientRect" id="getBoundingClientRect" type="text"><input name="getAttributeNodeNS" id="getAttributeNodeNS" type="text"><input name="getAttributeNode" id="getAttributeNode" type="text"><input name="getAttributeNS" id="getAttributeNS" type="text"><input name="getAttribute" id="getAttribute" type="text"><input name="getAdjacentText" id="getAdjacentText" type="text"><input name="focus" id="focus" type="text"><input name="firstElementChild" id="firstElementChild" type="text"><input name="firstChild" id="firstChild" type="text"><input name="fireEvent" id="fireEvent" type="text"><input name="enctype" id="enctype" type="text"><input name="encoding" id="encoding" type="text"><input name="elements" id="elements" type="text"><input name="dragDrop" id="dragDrop" type="text"><input name="document" id="document" type="text"><input name="dispatchFormInput" id="dispatchFormInput" type="text"><input name="dispatchFormChange" id="dispatchFormChange" type="text"><input name="dispatchEvent" id="dispatchEvent" type="text"><input name="dir" id="dir" type="text"><input name="detachEvent" id="detachEvent" type="text"><input name="data" id="data" type="text"><input name="currentStyle" id="currentStyle" type="text"><input name="contentEditable" id="contentEditable" type="text"><input name="contains" id="contains" type="text"><input name="constructor" id="constructor" type="text"><input name="componentFromPoint" id="componentFromPoint" type="text"><input name="compareDocumentPosition" id="compareDocumentPosition" type="text"><input name="cloneNode" id="cloneNode" type="text"><input name="clientWidth" id="clientWidth" type="text"><input name="clientTop" id="clientTop" type="text"><input name="clientLeft" id="clientLeft" type="text"><input name="clientHeight" id="clientHeight" type="text"><input name="click" id="click" type="text"><input name="clearAttributes" id="clearAttributes" type="text"><input name="className" id="className" type="text"><input name="children" id="children" type="text"><input name="childNodes" id="childNodes" type="text"><input name="childElementCount" id="childElementCount" type="text"><input name="checkValidity" id="checkValidity" type="text"><input name="canHaveHTML" id="canHaveHTML" type="text"><input name="canHaveChildren" id="canHaveChildren" type="text"><input name="blur" id="blur" type="text"><input name="blockDiraction" id="blockDiraction" type="text"><input name="behaviorUrns" id="behaviorUrns" type="text"><input name="baseURI" id="baseURI" type="text"><input name="autocomplete" id="autocomplete" type="text"><input name="attributes" id="attributes" type="text"><input name="attachEvent" id="attachEvent" type="text"><input name="ariaValuenow" id="ariaValuenow" type="text"><input name="ariaValuemin" id="ariaValuemin" type="text"><input name="ariaValuemax" id="ariaValuemax" type="text"><input name="ariaSetsize" id="ariaSetsize" type="text"><input name="ariaSelected" id="ariaSelected" type="text"><input name="ariaSecret" id="ariaSecret" type="text"><input name="ariaRequired" id="ariaRequired" type="text"><input name="ariaReadonly" id="ariaReadonly" type="text"><input name="ariaPressed" id="ariaPressed" type="text"><input name="ariaPosinset" id="ariaPosinset" type="text"><input name="ariaOwns" id="ariaOwns" type="text"><input name="ariaMultiselect" id="ariaMultiselect" type="text"><input name="ariaLevel" id="ariaLevel" type="text"><input name="ariaLabelledby" id="ariaLabelledby" type="text"><input name="ariaInvalid" id="ariaInvalid" type="text"><input name="ariaHidden" id="ariaHidden" type="text"><input name="ariaHaspopup" id="ariaHaspopup" type="text"><input name="ariaFlowto" id="ariaFlowto" type="text"><input name="ariaExpanded" id="ariaExpanded" type="text"><input name="ariaDisabled" id="ariaDisabled" type="text"><input name="ariaDescribability" id="ariaDescribability" type="text"><input name="ariaControls" id="ariaControls" type="text"><input name="ariaChecked" id="ariaChecked" type="text"><input name="ariaBusy" id="ariaBusy" type="text"><input name="applyElement" id="applyElement" type="text"><input name="appendChild" id="appendChild" type="text"><input name="all" id="all" type="text"><input name="addRepetitionBlockByIndex" id="addRepetitionBlockByIndex" type="text"><input name="addRepetitionBlock" id="addRepetitionBlock" type="text"><input name="addEventSource" id="addEventSource" type="text"><input name="addEventListener" id="addEventListener" type="text"><input name="addBehavior" id="addBehavior" type="text"><input name="action" id="action" type="text"><input name="acceptCharset" id="acceptCharset" type="text"><input name="accept" id="accept" type="text"><input name="TEXT_NODE" id="TEXT_NODE" type="text"><input name="PROCESSING_INSTRUCTION_NODE" id="PROCESSING_INSTRUCTION_NODE" type="text"><input name="NOTATION_NODE" id="NOTATION_NODE" type="text"><input name="ENTITY_REFERENCE_NODE" id="ENTITY_REFERENCE_NODE" type="text"><input name="ENTITY_NODE" id="ENTITY_NODE" type="text"><input name="ELEMENT_NODE" id="ELEMENT_NODE" type="text"><input name="DOCUMENT_TYPE_NODE" id="DOCUMENT_TYPE_NODE" type="text"><input name="DOCUMENT_POSITION_PRECEDING" id="DOCUMENT_POSITION_PRECEDING" type="text"><input name="DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC" id="DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC" type="text"><input name="DOCUMENT_POSITION_FOLLOWING" id="DOCUMENT_POSITION_FOLLOWING" type="text"><input name="DOCUMENT_POSITION_DISCONNECTED" id="DOCUMENT_POSITION_DISCONNECTED" type="text"><input name="DOCUMENT_POSITION_CONTAINS" id="DOCUMENT_POSITION_CONTAINS" type="text"><input name="DOCUMENT_POSITION_CONTAINED_BY" id="DOCUMENT_POSITION_CONTAINED_BY" type="text"><input name="DOCUMENT_NODE" id="DOCUMENT_NODE" type="text"><input name="DOCUMENT_FRAGMENT_NODE" id="DOCUMENT_FRAGMENT_NODE" type="text"><input name="COMMENT_NODE" id="COMMENT_NODE" type="text"><input name="CDATA_SECTION_NODE" id="CDATA_SECTION_NODE" type="text"><input name="ATTRIBUTE_NODE" id="ATTRIBUTE_NODE" type="text">
+</form>
+<form name="title"/>
+
+<pre id="pass">PASS - All Form Properties Replaced by an Element</pre>
+<pre id="fail">FAIL</pre>
+<pre>
+<script type='text/javascript' src="names.js"></script>
+<script type="text/javascript">
+(function(){
+var form = document.forms[0];
+var actual, expected, msg, actualString;
+var bugs = [];
+
+for(var i = names.length -1; i > 0; i--) {
+ try{
+ actual = form[names[i]];
+ if(actual != input) {
+ msg = names[i];
+ if(actual.toString && actual.toString.tagName)
+ actualString = actual.toString.tagName;
+ else
+ actualString = String(actual);
+ msg += " found: " + (((actualString + " ("+typeof actual+")")) || "(missing)");
+ bugs[bugs.length] = msg;
+ }
+ } catch(x){
+ msg = "Error: " + x.message;
+ }
+}
+// can't use form.elements, form.getElementsByTagName, et c
+// because they were replaced by an input.
+
+if(bugs.length > 0)
+ fail(bugs);
+else pass();
+
+function fail(bugs) {
+ var fail = document.getElementById('fail');
+ fail.firstChild.data += ': The following ' + bugs.length +
+ ' form properties should have been an INPUT element:\n * ' + bugs.join('\n * ');
+ fail.style.display = "inline-block";
+}
+
+function pass() {
+ var pass = document.getElementById('pass');
+ pass.style.display = "inline-block";
+}
+
+})();
+</script>
+</body>
+</html>
/trunk/cljs/names/form_override_html_source.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/form_override_change_name.html
===================================================================
--- trunk/cljs/names/form_override_change_name.html (nonexistent)
+++ trunk/cljs/names/form_override_change_name.html (revision 45)
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+ <title>Safe Form Controls</title>
+ <style type="text/css">
+ input { font-size: 8px; font-family: courier new, monospace; padding: 0 }
+ #pass { display: none; background : #0f0; }
+ #fail { display: none; background : #F33; }
+ </style>
+</head>
+<body>
+<h1>Test: 290 Names not to give a FORM Control</h1>
+<form name="length" action="fail" title="fail">
+<input type="submit" />
+</form>
+<pre id="pass">PASS - All Form Properties Replaced by an Element</pre>
+<pre id="fail">FAIL</pre>
+<pre>
+<script type='text/javascript' src="names.js"></script>
+<script type="text/javascript">
+(function(){
+var form = document.forms[0];
+var input = form.elements[0];
+var bugs = [];
+
+var actual, expected, msg, actualString;
+
+for(var i = names.length -1; i > 0; i--) {
+ if(names[i] == names[i-1]) {
+ alert("found duplicate: " + names[i]);
+ break;
+ }
+ else {
+ try{
+ input.name = names[i];
+ actual = form[names[i]];
+ if(actual != input) {
+ msg = names[i];
+ if(actual.toString && actual.toString.tagName)
+ actualString = actual.toString.tagName;
+ else
+ actualString = String(actual);
+ msg += " found: " + (((actualString + " ("+typeof actual+")")) || "(missing)");
+ bugs[bugs.length] = msg;
+ }
+ } catch(x){
+ msg = "Error: " + x.message;
+ }
+ }
+}
+// can't use form.elements, form.getElementsByTagName, et c
+// because they were replaced by an input.
+
+if(bugs.length > 0)
+ fail(bugs);
+else pass();
+
+function fail(bugs) {
+ var fail = document.getElementById('fail');
+ fail.firstChild.data += ': The following ' + bugs.length +
+ ' form properties should have been an INPUT element:\n * ' + bugs.join('\n * ');
+ fail.style.display = "inline-block";
+}
+
+function pass() {
+ var pass = document.getElementById('pass');
+ pass.style.display = "inline-block";
+}
+
+//document.write(names.join("\n &lt;/li&gt;\n&lt;li&gt;\n"));
+})();
+</script>
+</pre>
+</body>
+</html>
/trunk/cljs/names/form_override_change_name.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/index.html
===================================================================
--- trunk/cljs/names/index.html (nonexistent)
+++ trunk/cljs/names/index.html (revision 45)
@@ -0,0 +1,235 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+<head>
+ <title>Unsafe Names for HTML Form Controls</title>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
+ <meta name="author" content="Garrett Smith">
+ <meta name="author-email" content="dhtmkitchen@gmail.com">
+ <link rel="stylesheet" href="../faq.css" type="text/css" media="all" charset="iso-8859-1">
+ <link rel="stylesheet" href="names.css" type="text/css" media="all" charset="iso-8859-1">
+ <link rel="Start" href="./">
+</head>
+<body>
+ <h1>Unsafe Names for HTML Form Controls</h1>
+
+ <p>
+ by Garrett Smith (<a href="http://www.dhtmlkitchen.com/">dhtmlkitchen.com</a>),
+ edited by Frank Manno (<a href="http://www.frankmanno.com/">frankmanno.com</a>)
+ with comments from David Mark, Richard Cornford, RobG, and Juriy Zaytsev.
+ </p>
+ <h2>Rich, Featureful Forms</h2>
+
+ <p>
+ An HTML <code>FORM</code> element, in most modern browsers,
+ implements many interfaces and has a rich set of features.
+ These features are exposed as properties of the form, such as
+ <code>addEventListener</code>, <code>parentNode</code>, and
+ <code>submit</code>. Browsers also add their own non-standard features
+ such as <code>all</code>, <code>contentEditable</code>, or <code>spellcheck</code>.
+ </p>
+
+ <h3>Problem</h3>
+ <p>
+ Browsers add <code>name</code>s and <code>id</code>s of form
+ controls as properties to the <code>FORM</code>. This results in
+ the properties of the form being replaced.
+ </p>
+ <p>
+ Browsers also may add <code>name</code>s
+ and <code>id</code>'s of other elements as properties to
+ <code>document</code>, and sometimes to the <code>global</code>
+ object (or an object above the <code>global</code> object in scope).
+ This non-standard behavior can result in replacement of
+ properties on other objects. The problems it causes are discussed in detail.
+ </p>
+
+ <p>
+ A problem occurs when a form control's <code>name</code> conflicts
+ with the a property name of the <code>FORM</code> object. For example:
+ </p>
+
+ <h4>Simple Unsafe Name Example</h4>
+ <pre>
+&lt;form action=""&gt;
+ &lt;input type="text" name="name"&gt;
+ &lt;input type="submit" name="submit"&gt;
+&lt;/form&gt;
+</pre>
+
+ <h5>Result</h5>
+ <p>
+ The element with <code>name="name"</code> replaces
+ the value of the <code>FORM</code>'s <code>name</code> property.
+ A similar type of conflict happens with the
+ <code>FORM</code>'s <code>submit</code> method and the
+ element with <code>name="submit'</code>. Which will win?
+ </p>
+ <p>
+ In most cases, the form control wins and the <code>FORM</code>'s property is
+ replaced to have the value of the form control, or, if more than
+ one form control has that name, the <code>FORM</code>'s property is
+ replaced with a <code>NodeList</code> containing those form controls.
+ </p>
+ <p>
+ However, in some cases, the <code>FORM</code>'s property is <em>not</em> replaced
+ to have the value of the form control with the same name. The examples in this page show that
+ the result depends on the browser, the property, and how the control is added.
+ </p>
+
+ <h4>How is a Form Like a Collection?</h4>
+ <p>
+ The DOM 1 specification states:
+ </p>
+ <blockquote cite="http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-40002357">
+ <p>
+ The <code>FORM</code> element encompasses behavior similar to a collection and an element.
+ It provides direct access to the contained <code>input</code> elements as well as the
+ attributes of the <code>FORM</code> element. [<a href="conclusion.html#controls-normref">DOM1</a>]
+ </p>
+ </blockquote>
+
+ <p>
+ <cite>"Similar to a collection?"</cite>
+ <em>What</em> collection? Similar in what way?
+ The only standardized feature that is <cite>"similar to a collection"</cite> is
+ the <code>length</code> property.
+ </p>
+
+ <p>
+ In most browsers, a form has direct access to all named form controls,
+ (except for <code>input type="image"</code>), not just <code>input</code> elements.
+ </p>
+ <p>
+ Accessing controls as named or indexed properties is not standardized by the w3c DOM specification.
+ It is a holdover feature from Netscape Navigator that was copied by Internet Explorer
+ and since copied by every other major browser vendor.
+ </p>
+
+ <h4>How the Nonstandard Form-as-a-Collection <em>Really</em> Works</h4>
+ <p>
+ Controls may be accessed directly off the form.
+ </p>
+
+ <p>Given the following form:</p>
+
+ <pre>
+&lt;form action=""&gt;
+ &lt;input type="text" name="a"&gt;
+&lt;/form&gt;
+</pre>
+ <p>
+ The <code>input name="a"</code> may be retrieved in one of two ways, from the form
+ or from the <code>elements</code> collection.
+ </p>
+ <h5>The elements Collection (standard)</h5>
+
+ <pre>
+ // Standard.
+ document.forms[0].elements[0];
+ document.forms[0].elements.a;
+</pre>
+ <p>
+ The control may be accessed directly off the form:
+ </p>
+ <h5>Directly from the Form (nonstandard)</h5>
+ <pre>
+ // non-standard.
+ document.forms[0][0];
+ document.forms[0].a;
+</pre>
+
+ <h4>Side Effects</h4>
+ <p>
+ Accessing a named control directly off the form can have undesirable results.
+ </p>
+ <p>
+ In a few browsers, removing a named control from the form will leave the named
+ control as a property of the form.
+ </p>
+ <h5>Form-as-a-Collection Leak Example</h5>
+ <p>
+ This <a href="simple-leak-form-input.html">Simple leak</a> example shows
+ that accessing a named element property directly from the <code>form</code>
+ may cause the property to remain on the form, even after the element
+ has been removed from the DOM.
+ </p>
+ <h5>Results</h5>
+ <strong>Firefox 3, Safari 3</strong>
+ <pre>
+foo: [object HTMLInputElement]
+bar: undefined
+elements.foo: undefined
+</pre>
+ <strong>Opera 9.5, IE 6, Safari 2</strong>
+ <pre>
+foo: undefined
+bar: undefined
+elements.foo: undefined
+</pre>
+
+ <p>
+ Similarly, when a named <code>FORM</code> element is removed from the <code>document</code>
+ some browsers will keep that form name as a property of the <code>document</code>.
+ Accessing named <code>FORM</code> controls as properties of the document is also nonstandard.
+ </p>
+
+ <h5>Standard</h5>
+ <pre>document.forms.myform;</pre>
+ <h5>Nonstandard</h5>
+ <pre>document.myform;</pre>
+
+ <p>
+ A <code>form</code>'s indexed form control properties may also appear out of order.
+ This behavior would not be compliant for the <code>elements</code> collection,
+ it does not violate any standard for the form-as-a-collection (because
+ there is no standard).
+ </p>
+
+ <p>
+ Form-as-a-collection is unreliable and therefore should never be used.
+ </p>
+
+ <h3>The <code>elements</code> Collection</h3>
+ <p>
+ The <code>form.elements</code> collection
+ provides programmers a safe place to access form controls.
+ </p>
+
+ <p>
+ The <code>elements</code> collection contains the following properties:
+ <code>length</code>, <code>item</code>, <code>namedItem</code>, plus an ordinal
+ index property for each form control (excepting <code>input type="image"</code> controls).
+ Some browsers also have a <code>tags</code> property on the <code>elements</code> collection.
+ </p>
+
+ <h4>The elements Collection is Live</h4>
+ <p>
+ When a form control is removed from the DOM, the <code>elements</code> collection
+ is updated; however, the property will still remain on the form in some browsers
+ (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=307415">Mozilla bug 307415</a>).
+ </p>
+ <h5>Element Removal Example</h5>
+ <p>
+ <a href="form_dom_removal.html">element removal example</a>
+ </p>
+
+ <div id="toc">
+ <h4>Table of Contents</h4>
+ <ul class="pagination linkList">
+ <li>Introduction</li>
+ <li><a href="extra_props.html">Extra Properties: <code>FORM</code> Elements</a></li>
+ <li><a href="extra_props_document.html">Extra Properties: <code>document</code></a></li>
+ <li><a href="extra_props_global.html">Extra Properties: <code>global</code></a></li>
+ <li><a href="event_handler.html">Event Handler Scope</a></li>
+ <li><a href="api_design.html">API Design?</a></li>
+ <li><a href="unsafe_names.html">Unsafe Names</a></li>
+ <li><a href="conclusion.html">Conclusion</a></li>
+ </ul>
+ </div>
+ <ul id="nextLink" class="linkList">
+ <li>
+ <span class="next">Next:</span> <a href="extra_props.html">Extra Properties: <code>FORM</code> Elements</a>
+ </li>
+ </ul>
+</body>
+</html>
/trunk/cljs/names/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/callable_example.html
===================================================================
--- trunk/cljs/names/callable_example.html (nonexistent)
+++ trunk/cljs/names/callable_example.html (revision 45)
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+ <title>Callable HTMLCollection</title>
+ <link rel="Start" href="./">
+ <link rev="Section" href="api_design.html">
+</head>
+<body>
+<form action="" id="a" name="d"><input type="text"></form>
+<h3>Your Browser's Result:</h3>
+<pre id="callableResult">-</pre>
+<pre>
+<script type="text/javascript">(function(){
+var f = document.forms, isCallable = true,
+ callableResult = document.getElementById('callableResult');
+try {
+ f(0);
+} catch(ex) {
+ isCallable = false;
+}
+if(!isCallable) {
+ callableResult.firstChild.data = "form is not callable";
+} else {
+ callableResult.firstChild.data =
+ ["typeof f " + "\""+ (typeof f) + "\"",
+ "f('0') " + f('0'),
+ "f('a') " + f('a'),
+ "f('d') " + f('d')].join('\n');
+}
+})();</script>
+</pre>
+<hr>
+<h3>Browser Results:</h3>
+Firefox
+<pre>form is not callable</pre>
+Opera 9
+<pre>
+typeof f "object"
+f('0') [object HTMLFormElement]
+f('a') [object HTMLFormElement]
+f('d') [object HTMLFormElement]
+</pre>
+IE6, IE7, IE8
+<pre>
+typeof f "object"
+f('0') [object]
+f('a') [object]
+f('d') [object]
+</pre>
+Safari
+<pre>
+typeof f "function"
+f('0') [object HTMLFormElement]
+f('a') [object HTMLFormElement]
+f('d') [object HTMLFormElement]
+</pre>
+</body>
+</html>
/trunk/cljs/names/callable_example.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/names.js
===================================================================
--- trunk/cljs/names/names.js (nonexistent)
+++ trunk/cljs/names/names.js (revision 45)
@@ -0,0 +1,316 @@
+var names = [
+ // HTMLFormElement
+ "elements","length", //readonly.
+ "name", "acceptCharset", "action", "enctype", "method", "target", "submit", "reset",
+
+ // HTMLElement
+ "id", "title", "lang", "dir", "className",
+
+ // Element.
+ "tagName", "schemaTypeInfo", // readonly.
+ "getAttribute", "removeAttribute", "getAttributeNode",
+ "setAttributeNode", "removeAttributeNode", "getElementsByTagName",
+ "getAttributeNS", "setAttributeNS", "removeAttributeNS",
+ "getAttributeNodeNS", "setAttributeNodeNS", "getElementsByTagNameNS",
+ "hasAttribute", "hasAttributeNS", "setIdAttribute", "setIdAttributeNS",
+ "setIdAttributeNode",
+
+ // Node.
+ // Node constants.
+ "ELEMENT_NODE",
+ "ATTRIBUTE_NODE",
+ "TEXT_NODE",
+ "CDATA_SECTION_NODE",
+ "ENTITY_REFERENCE_NODE",
+ "ENTITY_NODE",
+ "PROCESSING_INSTRUCTION_NODE",
+ "COMMENT_NODE",
+ "DOCUMENT_NODE",
+ "DOCUMENT_TYPE_NODE",
+ "DOCUMENT_FRAGMENT_NODE",
+ "NOTATION_NODE",
+ "DOCUMENT_POSITION_DISCONNECTED",
+ "DOCUMENT_POSITION_PRECEDING",
+ "DOCUMENT_POSITION_FOLLOWING",
+ "DOCUMENT_POSITION_CONTAINS",
+ "DOCUMENT_POSITION_CONTAINED_BY",
+ "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC",
+
+ // Readonly.
+ "nodeName",
+ "nodeType",
+ "parentNode",
+ "childNodes",
+ "firstChild",
+ "lastChild",
+ "previousSibling",
+ "nextSibling",
+ "attributes",
+ "ownerDocument",
+ "namespaceURI",
+ "localName",
+ "baseURI",
+
+ "nodeValue",
+ "insertBefore",
+ "replaceChild",
+ "removeChild",
+ "appendChild",
+ "hasChildNodes",
+ "cloneNode",
+ "normalize",
+ "isSupported",
+ "prefix",
+ "hasAttributes",
+ "compareDocumentPosition",
+ "textContent",
+ "isSameNode",
+ "lookupPrefix",
+ "isDefaultNamespaceURI",
+ "isEqualNode",
+ "getFeature",
+ "setUserData",
+ "getUserData",
+
+ // ElementCSSInlineStyle.
+ "style", // readonly.
+
+ // EventTarget.
+ "addEventListener",
+ "removeEventListener",
+ "dispatchEvent",
+
+ // Mouse Events
+ "onclick",
+ "onmousedown",
+ "onmouseup",
+ "onmouseover",
+ "onmousemove",
+ "onmouseout",
+ "ondblclick",
+
+ // MouseWheelEvent.
+ "onmousewheel",
+ "onmousemultiwheel",
+
+ // Key Events.
+ "onkeydown",
+ "onkeyup",
+ "onkeypress",
+
+ // bubbled events?
+ "onchage",
+ "onabort",
+ "onerror",
+ "onselect",
+ "onresize",
+ "onscroll",
+
+ // New Events for Element:
+ "onfocus",
+ "onblur",
+
+ // Proprietary MSIE (also HTML 5/FF).
+ "clientHeight",
+ "clientWidth",
+ "offsetHeight",
+ "offsetWidth",
+ "clientLeft",
+ "clientTop",
+ "contentEditable",
+ "getBoundingClientRect",
+ "getClientRects",
+ "getElementsByClassName",
+ "scrollIntoView",
+ "scrollLeft",
+ "scrollTop",
+ "scrollWidth",
+ "scrollHeight",
+ "tabIndex",
+ "encoding",
+ "spellcheck",
+ "innerHTML",
+ "innerText",
+ "children",
+
+ "ariaBusy",
+ "ariaChecked",
+ "ariaControls",
+ "ariaDescribability",
+ "ariaDisabled",
+ "ariaExpanded",
+ "ariaFlowto",
+ "ariaHaspopup",
+ "ariaHidden",
+ "ariaInvalid",
+ "ariaLabelledby",
+ "ariaLevel",
+ "ariaMultiselect",
+ "ariaOwns",
+ "ariaPosinset",
+ "ariaPressed",
+ "ariaReadonly",
+ "ariaRequired",
+ "ariaSecret",
+ "ariaSelected",
+ "ariaSetsize",
+ "ariaValuemax",
+ "ariaValuemin",
+ "ariaValuenow",
+
+ "autocomplete",
+ "blockDiraction",
+ "canHaveChildren",
+ "canHaveHTML",
+ "hideFocus",
+ "isContentEditable",
+ "isDisabled",
+ "isMultiLine",
+ "isTextEdit",
+ "language",
+ "msBlockProgression",
+ "msBoxSizing",
+ "onOffBehavior",
+ "outerHTML",
+ "outerText",
+ "parentTextEdit",
+ "quotes",
+ "role",
+ "scopeName",
+ "sourceIndex",
+ "tagUrn",
+ "uniqueID",
+
+ "all",
+ "behaviorUrns",
+
+ "onactivate",
+ "onbeforeactivate",
+ "onbeforecopy",
+ "onbeforecut",
+ "onbeforedeactivate",
+ "onbeforeeditfocus",
+ "onbeforepaste",
+ "oncontextmenu",
+ "oncopy",
+ "oncut",
+ "ondeactivate",
+ "ondrag",
+ "ondragend",
+ "ondragenter",
+ "ondragleave",
+ "ondragover",
+ "onfocusin",
+ "onfocusout",
+ "onhelp",
+ "onclosecapture",
+ "onmouseenter",
+ "onmouseleave",
+ "onmove",
+ "onmoveend",
+ "onmovestart",
+ "onpaste",
+ "onpropertychange",
+ "onreadystatechange",
+ "onresizeend",
+ "onresizestart",
+ "onselectstart",
+ "ontimeerror",
+
+ // methods.
+ "addBehavior",
+ "applyElement",
+ "attachEvent",
+ "blur",
+ "clearAttributes",
+ "click",
+ "componentFromPoint",
+ "contains",
+ "detachEvent",
+ "dragDrop",
+ "fireEvent",
+ "focus",
+ "getAdjacentText",
+ "getExpression",
+ "insertAdjacentElement",
+ "insertAdjacentHTML",
+ "insertAdjacentText",
+ "item",
+ "mergeAttributes",
+ "namedItem",
+ "querySelector",
+ "querySelectorAll",
+ "releaseCapture",
+ "removeBehavior",
+ "removeExpression",
+ "removeNode",
+ "replaceAdjacentText",
+ "replaceNode",
+ "setActive",
+ "setCapture",
+ "setExpression",
+ "swapNode",
+ "urns",
+
+ // objects.
+ "currentStyle",
+ "runtimeStyle",
+
+ // WF2.0
+ "accept",
+ "checkValidity",
+ "replace",
+ "data",
+ "resetFromData",
+ "dispatchFormInput",
+ "dispatchFormChange",
+ "templateElements",
+
+ // Proprietary Moz/HTML 5
+ "isDefaultNamespace",
+
+ // Opera
+ "childElementCount",
+ "firstElementChild",
+ "lastElementChild",
+ "previousElementSibling",
+ "repeatMin",
+ "repeatStart",
+ "repetitionBlocks",
+ "repetitionIndex",
+ "repetitionTemplate",
+ "repetitionType",
+ "repeatMax",
+ "text",
+ "unselectable",
+ "addRepetitionBlock",
+ "addRepetitionBlockByIndex",
+ "moveRepetitionBlock",
+ "removeRepetitionBlock",
+ "selectNodes",
+ "selectSingleNode",
+ "addEventSource",
+ "removeEventSource",
+
+ // Webkit
+ "oninput",
+ "scrollByLines",
+ "scrollByPages",
+ "document",
+ "onsearch",
+ "onunload",
+
+ // Scope chain for event handler attributes.
+ "window",
+
+ // Object.prototype
+ "constructor",
+ "toString",
+ "toLocaleString",
+ "valueOf",
+ "hasOwnProperty",
+ "isPrototypeOf",
+ "propertyIsEnumerable",
+ "watch",
+ "unwatch"
+].sort();
\ No newline at end of file
/trunk/cljs/names/names.js
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/res/[MS-ES3EX].pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/cljs/res/[MS-ES3EX].pdf
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/cljs/res/ISO_8601-2004_E.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/cljs/res/ISO_8601-2004_E.pdf
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/cljs/res/[MS-ES3].pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/cljs/res/[MS-ES3].pdf
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/cljs/example/addcslashes.php
===================================================================
--- trunk/cljs/example/addcslashes.php (nonexistent)
+++ trunk/cljs/example/addcslashes.php (revision 45)
@@ -0,0 +1,10 @@
+
+<pre>
+$str: " ' \
+ +</pre>
+
+<pre>
+addcslashes($str,"\\\'\"\n\r"):
+\" \' \\ \n\r
+</pre>
\ No newline at end of file
Index: trunk/cljs/example/jsuri/index.html
===================================================================
--- trunk/cljs/example/jsuri/index.html (nonexistent)
+++ trunk/cljs/example/jsuri/index.html (revision 45)
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+"http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+<title>javascript pseudo-protocol errors</title>
+<meta http-equiv="refresh" content="10; url=pseudoGifTest.html">
+<link rel="index" href="http://jibbering.com/faq/">
+<script type="text/javascript">
+var loadTime;
+function init(){
+ loadTime = +new Date
+ showTime();
+ setInterval(showTime, 100);
+
+}
+window.onbeforeunload = function() {
+ document.getElementById("bNotifier").value = "beforeonload handler called";
+};
+
+function showTime(){
+ document.forms['f'].elements['t'].value = (((new Date()).getTime() - loadTime)/1000)
+}
+</script>
+</head>
+<body onload="init()">
+<h1>javascript: uri problems demo</h1>
+<p>
+ <img src="waveAnim.gif" alt="animated wave">
+</p>
+
+<form action="" onsubmit="return false;" name="f">
+ <input type="text" value="" name="t" size="20">
+ <input type="text" value="" id="bNotifier" size="30">
+</form>
+
+<h3>javascript: uri as href</h3>
+<p>
+<a href="javascript:void 0;">javascript:void 0;</a>
+</p>
+
+<h3>Actual link to invalid URL</h3>
+ <a href="http://bogus.example.com/v.html">http://bogus.example.com/</a>
+
+<h3>javascript: uri with syntactially invalid code</h3>
+<p>
+ <a href="javascript:void();">javascript:void();</a>
+</p>
+</body>
+</html>
/trunk/cljs/example/jsuri/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/example/jsuri/waveAnim.gif
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/cljs/example/jsuri/waveAnim.gif
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: trunk/cljs/example/functionStatement.html
===================================================================
--- trunk/cljs/example/functionStatement.html (nonexistent)
+++ trunk/cljs/example/functionStatement.html (revision 45)
@@ -0,0 +1,54 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="iso-8859-15">
+<link rel="DCTERMS.isReferencedBy" href="http://jibbering.com/faq/#functionStatement">
+
+<title>Function Statement Example - FAQ - comp.lang.javascript</title>
+
+<style type="text/css">
+pre {
+ background: #fefefe;
+ padding: 1ex;
+ border: 1px dashed #eee;
+}
+</style>
+</head>
+
+<body style="background: #f9f9f9">
+<h1>Function Statement Example - FAQ : "What is a function statement?"</h1>
+<h2>Example Code</h2>
+<pre>
+try {
+ x; // ReferenceError: x is not defined.
+ function Fze(a, b) {a.unselectable = b}
+} catch(e) { }
+
+document.write("typeof Fze: ", typeof Fze, "\ntypeof e: ", typeof e);
+</pre>
+
+<h2>Result</h2>
+<pre>
+<script type="text/javascript">
+try {
+ x; // ReferenceError: x is not defined.
+ function Fze(a, b) {a.unselectable = b}
+} catch(e) { }
+
+document.write("typeof Fze: ", typeof Fze, "\ntypeof e: ", typeof e);
+</script>
+</pre>
+
+<p>
+Expected outcome for <code>typeof Fze</code> is not specified by ECMA-262.
+</p>
+If <code>typeof Fze</code> results <code>"function"</code>, then <code>Fze</code> was interpreted
+as a FunctionDeclaration. Otherwise if <code>typeof Fze</code> resulted <code>"undefined"</code>,
+then <code>Fze</code> was not reached as a Statement; the preceeding statement - <code>x;</code> -
+would trigger a ReferenceError, making it unreachable.
+</p>
+<p>
+Expected outcome for <code>typeof e</code> is <code>"undefined"</code>.
+</p>
+</body>
+</html>
/trunk/cljs/example/functionStatement.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/example/postMessage.html
===================================================================
--- trunk/cljs/example/postMessage.html (nonexistent)
+++ trunk/cljs/example/postMessage.html (revision 45)
@@ -0,0 +1,60 @@
+<!doctype html>
+<html>
+<head>
+<title>window postMessage</title>
+
+<body>
+<h1>Ask the 8-Ball</h1>
+<iframe src="http://dhtmlkitchen.com/jstest/postMessage/receiver.html" id="iframe"
+ style="width: 90%; height: 10em;"></iframe>
+<form id="posterForm">
+ <textarea id="msg" placeholder="Ask the 8 ball" cols="30" rows="5"></textarea>
+ <input type="submit">
+ <pre id="responseMessage">-</pre>
+</form>
+<script type="text/javascript">
+window.onload = function() {
+
+ var DOMAIN_RECEIVER = "http://dhtmlkitchen.com",
+ win = document.getElementById("iframe").contentWindow,
+ responseMessage = document.getElementById("responseMessage"),
+ form = document.getElementById("posterForm").onsubmit = postDataToWin;
+
+
+
+ function postDataToWin(ev){
+ win.postMessage(
+ document.getElementById("msg").value,
+ DOMAIN_RECEIVER
+ );
+ return false;
+ }
+
+ // Listen for message back from dhtmlkitchen.
+ addCallback(self, "message", messageReceivedBackHandler);
+
+ function messageReceivedBackHandler(ev) {
+ ev = ev || self.event;
+ var ACCEPT_DOMAIN = "http://dhtmlkitchen.com",
+ origin = ev.origin,
+ messageEl = document.getElementById("m");
+
+ // Allow only accepted domain.
+ if(origin !== ACCEPT_DOMAIN) {
+ return;
+ }
+
+ responseMessage.firstChild.data = ev.data;
+ }
+
+ function addCallback(o, type, cb){
+ if(o.addEventListener) {
+ o.addEventListener(type, cb, false);
+ } else {
+ o.attachEvent("on" + type, cb);
+ }
+ }
+};
+</script>
+</body>
+</html>
/trunk/cljs/example/postMessage.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/.project
===================================================================
--- trunk/.project (nonexistent)
+++ trunk/.project (revision 45)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>FAQs</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.dltk.core.scriptbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.php.core.PHPNature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ </natures>
+</projectDescription>
/trunk/.project
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/selfhtml.de/index.html
===================================================================
--- trunk/selfhtml.de/index.html (nonexistent)
+++ trunk/selfhtml.de/index.html (revision 45)
@@ -0,0 +1,258 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<meta name="generator" content="HTML Tidy, see www.w3.org">
+
+<title>JavaScript- und Java-Linkliste</title>
+
+<style type="text/css">
+a[href ^="http:"]:before {
+ content: "\2192";
+ text-decoration: none;
+ color: inherit;
+ background-color: inherit;
+}
+
+ul a[href ^="http:"]:before {
+ content: "";
+}
+</style>
+</head>
+
+<body>
+<h1>JavaScript- und Java-Linkliste</h1>
+
+<h2>Vorwort</h2>
+
+<p>Dies ist ein informativer Text, der (technische) Fakten
+vermittelt, <strong>keine</strong> Meinungen!</p>
+
+<p>Bei FAQs (<b>F</b>requently <b>A</b>sked <b>Q</b>uestions =
+häufig gestellte Fragen) und bei Fragen, die darauf hindeuten, dass dem
+Teilnehmer der Unterschied zwischen Java und JavaScript nicht klar ist,
+sollte hierauf verwiesen werden.</p>
+
+<p>Hilfreiche Kommentare und Verbesserungsvorschläge bitte <strong>nur</strong>
+per E-Mail an faq@PointedEars.de <strong>direkt</strong> an mich. Alles
+andere bitte nach /dev/tonne, danke.</p>
+
+<p>Vielen Dank für die Idee zu diesem Posting an <a
+ href="http://homepage.boku.ac.at/partl/">Dr. Hubert Partl</a>, der
+einen ähnlichen Text regelmässig in den <a
+ href="http://einklich.net/usenet/usenet1.htm">Usenet</a>-Newsgroups
+<a href="news:de.comp.lang.javascript">de.comp.lang.javascript</a>
+und <a href="news:de.comp.lang.java">de.comp.lang.java</a> (hier
+mit einem Klick zum Abo) postet.</p>
+
+<hr>
+
+<h2>Worum geht es?</h2>
+
+<p>Viele Fragen, die gestellt werden, wurden vorher bereits
+diskutiert und beantwortet. Das erneute Stellen dieser Fragen <strong>nervt</strong>
+die Teilnehmer, die hier schon länger mitlesen und -posten (kurz:
+Regulars, von engl. "regular" = regelmässig), denn niemand möchte die
+gleiche Frage immer wieder beantworten.</p>
+
+<p>Das hat dann oft gereizte Reaktionen zur Folge und der Fragende
+wundert sich darüber, denn er stellt ja die Frage aus seiner Perspektive
+das erste Mal.</p>
+
+<p>Um Auseinandersetzungen zu vermeiden, mögen bitte die Regulars
+einfach auf dieses Dokument verweisen und die Frager versuchen, Probleme
+<strong>vor</strong> dem Posten über die Links in dieser FAQ sowie
+einschlägige Literatur und <strong>Selbst</strong>studium (einfach mal
+was ausprobieren!) zu lösen.</p>
+
+<p>Weitere Information zum Auffinden von früheren Antworten findet
+man(n) auf der <a href="http://dcljs.de/">Website der Gruppe</a>.
+<p>Ausserdem gibt es regelmässig Verwechslungen zwischen den beiden
+<strong>Programmiersprachen</strong> <a href="#java">Java</a> und <a
+ href="#js">JavaScript</a>. Java ist <strong>nicht</strong> JavaScript
+(kurz: Java&nbsp;<strong>!=</strong>&nbsp;JavaScript), und umgekehrt.</p>
+
+<hr>
+
+<h2><a name="js">JavaScript</a></h2>
+
+<p>Script-Sprache z.B. innerhalb von HTML-Dokumenten.</p>
+
+<p><a href="#ecmascript">ECMAScript</a>-Implementation von <a
+ href="#netscape">Netscape</a> (siehe Microsoft <a href="#jscript">JScript</a>).</p>
+
+<p>Wird von Netscape Navigator bis 4.x (Mozilla/4.0) und Netscape <a
+ href="#gecko">Gecko</a> (Rendering-Engine von Mozilla/5.0 -- d.h.
+Mozilla SeaMonkey, Mozilla Firefox/Thunderbird, Netscape 6+, Camino,
+...) verwendet.</p>
+
+<p>(X)HTML-Element: <code>script</code></p>
+<ul>
+ <li><a href="http://www.w3.org/TR/html4/interact/scripts.html">Normative
+ Version</a> (englisch)</li>
+ <li><a
+ href="http://edition-w3.de/TR/1999/REC-html401-19991224/interact/scripts.html">Vorveröffentlichung
+ der Deutschen Übersetzung</a></li>
+</ul>
+
+<p>.js-Dateien (üblich), wenn als externe Scripte eingebunden</p>
+
+<h2>Referenzen</h2>
+
+<ul>
+ <li><a name="ecmascript" id="ecmascript"
+ href="http://www.mozilla.org/js/language/">ECMAScript (ECMA-262)</a>
+ (englisch)</li>
+
+ <li><a name="netscape">Mozilla Developer Center (MDC)</a>
+ (englisch):<br>
+ <ul>
+ <li><a href="http://developer.mozilla.org/en/docs/JavaScript">JavaScript</a></li>
+
+ <li><a href="http://developer.mozilla.org/en/docs/DOM">DOM</a></li>
+
+ <li><a name="gecko" id="gecko"
+ href="http://developer.mozilla.org/en/docs/Gecko_DOM_Reference">Gecko
+ DOM Reference</a> (englisch)</li>
+ </ul>
+ </li>
+
+ <li>W3C-DOM Level 2 (englisch):
+ <ul>
+ <li><a href="http://www.w3.org/TR/DOM-Level-2/">Core</a></li>
+ <li><a href="http://www.w3.org/TR/DOM-Level-2-Events/">Events</a></li>
+ <li><a href="http://www.w3.org/TR/DOM-Level-2-HTML/">HTML</a></li>
+ <li><a href="http://www.w3.org/TR/DOM-Level-2-Style/">Style</a></li>
+ </ul>
+ </li>
+
+ <li>Microsoft Developer Network (MSDN) Library (englisch):
+ <ul>
+ <li><a name="jscript" id="jscript"
+ href="http://msdn.microsoft.com/library/en-us/script56/html/js56jsoriJScript.asp">JScript</a>:
+ <a href="#ecmascript">ECMAScript</a>-Implementation von Microsoft,
+ wird u.a. von der IE-Browserkomponente, <a href="http://asp.net/">Active
+ Server Pages (ASP)</a> und dem Windows Script Host verwendet.</li>
+
+ <li><a
+ href="http://msdn.microsoft.com/nhp/Default.asp?contentid=28001169">Windows
+ Script Documentation</a></li>
+
+ <li><a
+ href="http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp">HTML
+ and DHTML Reference</a> (DOM-Referenz zur IE-Browserkomponente)</li>
+ </ul>
+ </li>
+</ul>
+
+<h3>FAQs, FFQs</h3>
+
+<ul>
+ <li><a href="http://dcljs.de/faq/">FAQ --
+ Frequently Asked Questions -- Häufig gestellte Fragen</a></li>
+
+ <li><a name="ffq" id="ffq" href="http://praast.de/ffq/">FFQ
+ -- Frequently Forbidden Questions -- "Verbotene" Fragen</a></li>
+
+ <li><a href="http://dcljs.de/">Website der Newsgroup
+ de.comp.lang.javascript</a></li>
+</ul>
+
+<h3>Testcases, Tools</h3>
+
+<ul>
+ <li><a href="http://www.brain4.de/programmierecke/js/">JavaScript-Ecke
+ von Ralf Beutler, u.a. zur Abfrage von Maus und Tastatur-Ereignissen</a></li>
+
+ <li><a href="http://PointedEars.de/scripts/test/whatami">Was
+ bin ich? -- Wie "gut" Browsererkennung ist</a> von Thomas 'PointedEars'
+ Lahn</li>
+
+ <li><a href="http://PointedEars.de/scripts/test/hoverMe/">hoverMe
+ -- Vorladen von Bildern und Realisierung des Hover-Effekts</a> von Thomas
+ 'PointedEars' Lahn (unter Beachtung der Lizenzbestimmungen frei
+ verwendbar)</li>
+
+ <li><a
+ href="http://PointedEars.de/scripts/test/ObjectInspector/nightly/latest/index">ObjectInspector</a>
+ von Thomas 'PointedEars' Lahn (unter Beachtung der Lizenzbestimmungen
+ frei verwendbar)</li>
+
+ <li><a href="http://PointedEars.de/scripts/js-version-info">JS/ECMAScript-Versionsinformation</a></li>
+
+ <li><a href="http://PointedEars.de/scripts/test/mime-types/">Support
+ von für JS/ECMAScript registrierten MIME-Typen</a></li>
+</ul>
+
+<h3>Tutorials, Fertigscripte (siehe <a href="#ffq">FFQ</a>)</h3>
+
+<ul>
+ <li>"SELFHTML -- HTML-Dateien selbst erstellen" von Stefan Münz:
+ <ul>
+ <li><a href="http://selfhtml.teamone.de/javascript/">JavaScript</a></li>
+ <li><a href="http://selfhtml.teamone.de/dhtml/">Dynamisches
+ HTML (DHTML)</a></li>
+ </ul>
+ </li>
+
+ <li><a href="http://javascript.seite.net/">Kakao
+ &amp; Kekse -- Die deutsche JavaScript-Seite</a></li>
+
+ <li><a href="http://dhtml.seite.net/">Milch &amp; Zucker --
+ Die deutsche DHTML-Seite</a></li>
+</ul>
+
+<hr>
+
+<h2><a name="java">Java</a></h2>
+
+<p>Programmiersprache für Applets und Applikationen</p>
+
+<p>(X)HTML-Elemente: <code>applet</code>, <code>object</code></p>
+<ul>
+ <li><a href="http://www.w3.org/TR/html4/struct/objects.html">Normative
+ Version</a> (englisch)</li>
+ <li><a
+ href="http://edition-w3.de/TR/1999/REC-html401-19991224/struct/objects.html">Vorveröffentlichung
+ der Deutschen Übersetzung</a></li>
+</ul>
+
+<ul>
+ <li>Quelltext: .java-Dateien (üblich)</li>
+ <li>Compiliert:
+ <ul>
+ <li>.class-Dateien (zwingend, plattformunabhängig),</li>
+ <li>.exe-Dateien (plattformabhängig)</li>
+ </ul>
+ </li>
+</ul>
+
+<h3>Referenzen</h3>
+
+<p><a href="http://developer.java.sun.com/developer/infodocs/">Sun
+Java Documentation &amp; Training (englisch)</a></p>
+
+<h3>FAQs, weiterführende Information</h3>
+
+<ul>
+ <li><a href="http://www.dclj.de/faq.html">FAQ --
+ Frequently Asked Questions -- Häufig gestellte Fragen</a></li>
+
+ <li><a href="http://dclj.de/">Website der Newsgroup
+ de.comp.lang.java</a></li>
+</ul>
+
+<h3>Tutorials, fertiger Code (siehe <a href="#ffq">FFQ</a>)</h3>
+
+<ul>
+ <li>"SELFHTML -- HTML-Dateien selbst erstellen" von Stefan Münz:<br>
+ <a
+ href="http://selfhtml.teamone.de/html/multimedia/java_applets.htm#einbinden">Java-Applets
+ einbinden</a></li>
+
+ <li><a href="http://java.seite.net/">Kaffee &amp;
+ Kuchen -- Die deutsche Java-Seite</a></li>
+</ul>
+</body>
+</html>
\ No newline at end of file
/trunk/selfhtml.de/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/.buildpath
===================================================================
--- trunk/.buildpath (nonexistent)
+++ trunk/.buildpath (revision 45)
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<buildpath>
+ <buildpathentry kind="src" path=""/>
+ <buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/>
+</buildpath>
Index: trunk/.settings/org.eclipse.php.core.prefs
===================================================================
--- trunk/.settings/org.eclipse.php.core.prefs (nonexistent)
+++ trunk/.settings/org.eclipse.php.core.prefs (revision 45)
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+include_path=0;/FAQs
/trunk/.settings/org.eclipse.php.core.prefs
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/.settings/org.eclipse.wst.common.project.facet.core.xml
===================================================================
--- trunk/.settings/org.eclipse.wst.common.project.facet.core.xml (nonexistent)
+++ trunk/.settings/org.eclipse.wst.common.project.facet.core.xml (revision 45)
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <fixed facet="php.component"/>
+ <fixed facet="php.core.component"/>
+ <installed facet="php.core.component" version="1"/>
+ <installed facet="php.component" version="5.3"/>
+</faceted-project>
/trunk/.settings/org.eclipse.wst.common.project.facet.core.xml
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property