Subversion Repositories FAQs

Compare Revisions

Last modification

Ignore whitespace Rev 1 → Rev 2

/trunk/.project
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>
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 2)
@@ -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 2)
@@ -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/cljs/faq_notes/cookies.html
===================================================================
--- trunk/cljs/faq_notes/cookies.html (nonexistent)
+++ trunk/cljs/faq_notes/cookies.html (revision 2)
@@ -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>
\ No newline at end of file
/trunk/cljs/faq_notes/cookies.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 2)
@@ -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 2)
@@ -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/closures.html
===================================================================
--- trunk/cljs/faq_notes/closures.html (nonexistent)
+++ trunk/cljs/faq_notes/closures.html (revision 2)
@@ -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/faq_notes/closures.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 2)
@@ -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/clj_posts.html
===================================================================
--- trunk/cljs/faq_notes/clj_posts.html (nonexistent)
+++ trunk/cljs/faq_notes/clj_posts.html (revision 2)
@@ -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/faq_notes/clj_posts.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/faq_notes/type_convert.html
===================================================================
--- trunk/cljs/faq_notes/type_convert.html (nonexistent)
+++ trunk/cljs/faq_notes/type_convert.html (revision 2)
@@ -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/faq_notes/type_convert.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 2)
@@ -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 2)
@@ -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 2)
@@ -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/form_access.html
===================================================================
--- trunk/cljs/faq_notes/form_access.html (nonexistent)
+++ trunk/cljs/faq_notes/form_access.html (revision 2)
@@ -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/faq_notes/form_access.html
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 2)
@@ -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 2)
@@ -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/faq_notes/not_browser_detect.html
===================================================================
--- trunk/cljs/faq_notes/not_browser_detect.html (nonexistent)
+++ trunk/cljs/faq_notes/not_browser_detect.html (revision 2)
@@ -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/faq_notes/not_browser_detect.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/names/conclusion.html
===================================================================
--- trunk/cljs/names/conclusion.html (nonexistent)
+++ trunk/cljs/names/conclusion.html (revision 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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/index.xml
===================================================================
--- trunk/cljs/index.xml (nonexistent)
+++ trunk/cljs/index.xml (revision 2)
@@ -0,0 +1,2300 @@
+<FAQ VERSION="32.2" DATE="2010-10-08">
+ <TITLE>comp.lang.javascript FAQ</TITLE>
+ <CONTENTS>
+ <CONTENT TITLE="Meta-FAQ meta-questions" ID="meta" NUMID="1">
+ <P>
+This is the <EM>comp.lang.javascript</EM> meta-FAQ, <VER/>. The latest
+version is available at <URL>http://jibbering.com/faq/</URL> 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
+<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"
+>http://jsdoctoolkit.org/</URL> comments.
+</P>
+ <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
+ <URL
+LINKTEXT='&amp;quot;Posting Questions and Replies to comp.lang.javascript&amp;quot;'>notes/posting/</URL>.
+ </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:
+ <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>
+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>
+ <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&amp;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>
+The term "javascript" is used as a common name for all dialects of ECMAScript.
+ </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>.
+<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>
+ </P>
+ </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
+<MOREINFO>
+<URL>http://www.ecma-international.org/publications/standards/Ecma-262.htm</URL>
+</MOREINFO>
+</P>
+ </CONTENT>
+ </CONTENT>
+ <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>&amp;quot;JavaScript: The Definitive Guide,&amp;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>
+ <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.
+<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>
+</P>
+</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>:
+<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>
+
+<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):
+<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>
+
+</P>
+
+<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.
+-->
+<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>
+</P>
+</CONTENT>
+</CONTENT>
+ <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&amp;#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>).
+ <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>
+</P>
+
+ <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 &amp;lt;= year &amp;lt;= 9999</ICODE> can be
+formatted to a common ISO 8601 format <ICODE>YYYY-MM-DD</ICODE> with:-
+ <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 &amp;gt;= 0 &amp;amp;&amp;amp; year &amp;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>
+ </P>
+</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:-
+<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>
+</P>
+ </CONTENT>
+ </CONTENT>
+
+ <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>
+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:
+<URL LINKTEXT="Why does simple decimal arithmetic give strange results?">#binaryNumbers</URL>
+ </P>
+ <P>
+The statement <ICODE>n = Math.round(n * 100)/100</ICODE> converts <ICODE>n</ICODE> to a <ICODE>Number</ICODE> value
+close to a multiple of <ICODE>0.01</ICODE>. However, there are some problems.
+Converting the number to a string <ICODE>(n + "")</ICODE>, does not give
+trailing zeroes. Rounding numbers that are very close to <ICODE>x.5</ICODE>, for example,
+<ICODE>Math.round(0.49999999999999992)</ICODE> results <ICODE>1</ICODE>.
+ </P>
+ <P>
+ECMA-262 3rd Edition introduced <ICODE>Number.prototype.toFixed</ICODE>.
+There are bugs in JScript 5.8 and below with certain numbers, for example
+<ICODE>0.007.toFixed(2)</ICODE> incorrectly results <ICODE>0.00</ICODE>.
+ </P>
+ <P>
+ <CODE>
+var numberToFixed =
+(function() {
+ return toFixedString;
+
+ function toFixedString(n, digits) {
+ var unsigned = toUnsignedString(Math.abs(n), digits);
+ return (n &amp;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 &amp;lt; size) {
+ s = ch + s;
+ }
+ return s;
+ }
+})();
+
+// Test results
+document.writeln([
+ "numberToFixed(9e-3, 12) =&amp;gt; " + numberToFixed(9e-3, 12),
+ "numberToFixed(1.255, 2) =&amp;gt; " + numberToFixed(1.255, 2),
+ "numberToFixed(1.355, 2) =&amp;gt; " + numberToFixed(1.355, 2),
+ "numberToFixed(0.1255, 3) =&amp;gt; " + numberToFixed(0.1255, 3),
+ "numberToFixed(0.07, 2) =&amp;gt; " + numberToFixed(0.07, 2),
+ "numberToFixed(0.0000000006, 1) =&amp;gt; " + numberToFixed(0.0000000006, 1),
+ "numberToFixed(0.0000000006, 0) =&amp;gt; " + 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>
+ </P>
+ </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>
+ <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>
+ <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>
+ <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>
+ </P>
+ </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>.
+ <MOREINFO>
+Additional Notes: <URL>notes/type-conversion/</URL>
+ <URL>http://msdn.microsoft.com/en-us/library/67defydd%28VS.85%29.aspx</URL>
+ </MOREINFO>
+ </P>
+ </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 &amp;lt;= R &amp;lt; 1.0</ICODE>; therefore:
+ <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>
+ </P>
+ </CONTENT>
+ </CONTENT>
+
+ <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:
+<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>
+</P>
+ </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:
+
+<MOREINFO>
+<URL>notes/code-guidelines/#hostObjects</URL>
+<URL>http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting</URL>
+</MOREINFO>
+</P>
+ </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>.
+ <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>
+ </P>
+ </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:-
+<CODE>
+ //dot notation
+ var bodyElement = document.body;
+
+ //square bracket notation, using an expression
+ var bodyElement = document[&amp;quot;bo&amp;quot;+&amp;quot;dy&amp;quot;];</CODE>
+ <MOREINFO>
+ <URL>notes/square-brackets/</URL>
+ </MOREINFO>
+ </P>
+ </CONTENT>
+ </CONTENT>
+ <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>:
+<CODE>
+if(!String.prototype.trim) {
+ String.prototype.trim = function() {
+ return String(this).replace(/^\s+|\s+$/g, "");
+ };
+}
+</CODE>
+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>
+ <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>
+</P>
+ </CONTENT>
+ </CONTENT>
+
+ <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:
+<CODE>
+ var frm = document.forms[0];
+ var control = frm.elements[&amp;quot;elementname&amp;quot;];
+</CODE>
+Once a reference to a control is obtained, its (string) <ICODE>value</ICODE>
+property can be read:-
+<CODE>
+ var value = control.value;
+ value = +control.value; //string to number.
+</CODE>
+Some exceptions would be:
+</P>
+<P>
+First Exception: Where the control is a <ICODE>SELECT</ICODE> element, and
+support for older browsers, such as NN4, is required:
+<CODE>
+ var value = control.options[control.selectedIndex].value;
+</CODE>
+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:-
+<MOREINFO>
+<URL>notes/form-access/</URL>
+<URL LINKTEXT="Unsafe Names for HTML Form Controls">names/</URL>
+</MOREINFO>
+ </P>
+ <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 &amp;quot;illegal&amp;quot; characters can be accessed with
+<ICODE>formref.elements[&amp;quot;myselect[]&amp;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.
+<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>
+ </P>
+ </CONTENT>
+ <CONTENT TITLE="Why doesn't the global variable &amp;quot;divId&amp;quot; always refer to the element with id=&amp;quot;divId&amp;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=&amp;quot;foo&amp;quot;</ICODE> can be referenced
+with:-
+ <CODE>
+ var el = document.getElementById(&amp;quot;foo&amp;quot;);
+</CODE>
+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 &amp;lt;= 7 with
+<ICODE>document.getElementsByName</ICODE> and <ICODE>document.getElementById</ICODE>.
+<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>
+</P>
+ </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>&amp;lt;div id=&amp;quot;anID&amp;quot;&amp;gt;Some Content&amp;lt;/div&amp;gt;</ICODE> with script:
+ <CODE>
+ document.getElementById(&amp;quot;anID&amp;quot;).innerHTML =
+ &amp;quot;Some &amp;lt;em&amp;gt;new&amp;lt;/em&amp;gt; Content&amp;quot;;
+</CODE>
+Where <ICODE>&amp;quot;anID&amp;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.
+ <CODE>
+ document.getElementById(&amp;quot;anID&amp;quot;).firstChild.data = &amp;quot;Some new Text&amp;quot;;
+</CODE>
+</P>
+<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.
+ <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>
+ </P>
+ </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:
+<CODE>
+&amp;lt;div id="snurgle"&amp;gt;here&amp;lt;/div&amp;gt;
+&amp;lt;script type="text/javascript"&amp;gt;
+// Don't forget var.
+var snurgleEl = document.getElementById("snurgle");
+window.alert(snurgleEl.parentNode);
+&amp;lt;/script&amp;gt;
+</CODE>
+ </P>
+
+ <P>
+Example B:
+<CODE>
+// In the HEAD.
+&amp;lt;script type="text/javascript"&amp;gt;
+window.onload = function(){
+ var snurgleEl = document.getElementById("snurgle");
+};
+&amp;lt;/script&amp;gt;
+</CODE>
+</P>
+<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>use of an unsafe name: http://jibbering.com/names/</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.
+ <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>
+ </P>
+ </CONTENT>
+ </CONTENT>
+
+ <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.
+ <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>
+ </P>
+ </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:
+<CODE>
+var fwin;
+fwin = self.frames[0]; // or:
+fwin = self.frames["iframeName"];
+</CODE>
+</P>
+<P>or, from the <ICODE>IFRAME</ICODE> or <ICODE>FRAME</ICODE> element:
+<CODE>
+var iframeEl = document.getElementById("myFrame");
+var fwin = iframeEl.contentWindow; // Nonstandard, but widely supported.
+var fdoc = iframeEl.contentDocument; // DOM2 HTML Standard.
+</CODE>
+</P>
+<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>.
+<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>
+</P>
+
+ </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:
+ <CODE>
+ window.innerWidth
+ document.clientWidth
+ document.documentElement.clientWidth
+ document.body.clientWidth
+</CODE>
+
+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.
+<CODE> document.clientWidth</CODE>
+ </P>
+ <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.
+ <CODE>
+ document.documentElement.clientWidth
+ document.body.clientWidth
+</CODE>
+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).
+
+ <CODE> document.body.clientHeight</CODE>
+
+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.
+
+ <CODE> document.documentElement.clientHeight</CODE>
+
+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 &amp;lt;= 9.25, both of which return the <ICODE>clientHeight</ICODE>
+of the <ICODE>html</ICODE> <EM>element</EM>. (Oddly, Opera &amp;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:
+
+ <CODE>
+ // Safari 2 uses document.clientWidth (default).
+ if(typeof document.clientWidth == "number") {
+ // use document.clientWidth.
+ }
+</CODE>
+
+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>.
+
+ <CODE>
+ var docEl = document.documentElement,
+ IS_BODY_ACTING_ROOT = docEl &amp;amp;&amp;amp; docEl.clientHeight === 0;
+ docEl = null;
+</CODE>
+
+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).
+
+ <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 &amp;gt; 2400;
+ d.body.removeChild(div);
+ return r;
+ }
+</CODE>
+
+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).
+
+ <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>
+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://dhtmlkitchen.com/ape/build/dom/viewport-f.js</URL>.
+APE is publicly released under Academic Free License.
+APE home: <URL>http://dhtmlkitchen.com/ape/</URL>.
+ </P>
+
+ <P>
+Note: The dimensions cannot be determined accurately until after
+the document has finished loading.
+<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>
+ </P>
+ </CONTENT>
+
+ <CONTENT TITLE="How do I check to see if a child window is open, before opening another?"
+ ID="isWindowOpen" NUMID="4_10">
+ <P>
+ <CODE>
+ var myWin;
+ function openWin(aURL) {
+ if (!myWin || myWin.closed ) {
+ myWin = window.open(aURL,'myWin');
+ } else {
+ myWin.location.href = aURL;
+ myWin.focus();
+ }
+ }</CODE>
+Popup windows cause usability problems and are generally best avoided.
+<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>
+ </P>
+ </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>
+<MOREINFO>
+<URL>http://msdn.microsoft.com/en-us/library/ms976105.aspx</URL>
+</MOREINFO>
+ </P>
+ </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>
+<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>
+ </P>
+ </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 &amp;quot;Permission
+Denied&amp;quot; error. Signed scripts or trusted ActiveX objects can
+overcome this in limited situations.
+<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>
+ </P>
+ </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:
+ <CODE>
+ getMoomin();
+ setTimeout(getSnork, 10000);
+</CODE>
+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.
+<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>
+ </P>
+ </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.
+<MOREINFO>
+<URL>http://www.meadroid.com/scriptx/</URL>
+<URL>http://msdn.microsoft.com/en-us/library/ms976105.aspx</URL>
+</MOREINFO>
+ </P>
+ </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 &amp;quot;Save As&amp;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>
+<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>
+ </P>
+ </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=&amp;quot;setTimeout('window.status=\'Moomin\'',15);&amp;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>.
+<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>
+ </P>
+ </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.
+ <CODE>
+ &amp;lt;form action=&amp;quot;&amp;quot; method="post"
+ target=&amp;quot;wndname&amp;quot; onsubmit=&amp;quot;window.open('',this.target);return true;&amp;quot;&amp;gt;</CODE>
+ <MOREINFO>
+<URL>http://www.htmlhelp.com/reference/html40/forms/form.html</URL>
+ </MOREINFO>
+ </P>
+ </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:-
+ <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>
+ </P>
+ </CONTENT>
+ </CONTENT>
+ <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.
+<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>
+ </P>
+ </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.
+ <MOREINFO>
+ <URL>http://jibbering.com/2002/4/httprequest.html</URL>
+ <URL>http://www.ajaxtoolbox.com/</URL>
+ </MOREINFO>
+ </P>
+ </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>:
+ <CODE>
+var jsVar = "&amp;lt;%= StringEscapeUtils.escapeJavaScript(str) %&amp;gt;";
+</CODE>
+</P>
+<P>PHP example using <ICODE>addcslashes</ICODE>:
+<CODE>
+var jsVar = "&amp;lt;?php echo addcslashes($str,"\\\'\"\n\r"); ?&amp;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>
+ </P>
+ </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:
+ <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>
+ </P>
+ </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
+&amp;quot;swallow&amp;quot; the data sent back by the server, so that they will
+not be visible anywhere.
+</P>
+ <P>
+ <CODE>
+ var dummyImage = new Image();
+ dummyImage.src = &amp;quot;scriptURL.asp?param=&amp;quot; + varName;
+</CODE>
+ </P>
+ <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.
+<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>
+</P>
+ <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.
+<MOREINFO>
+<URL>http://www.mnot.net/cache_docs/</URL>
+</MOREINFO>
+ </P>
+ </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;amp;d='+new Date().valueOf())</ICODE>
+ <MOREINFO>
+ <URL>http://www.mnot.net/cache_docs/</URL>
+ <URL>http://docs.sun.com/source/816-6408-10/date.htm</URL>
+ </MOREINFO>
+ </P>
+ </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.
+ <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>
+</P>
+ </CONTENT>
+ </CONTENT>
+
+ <CONTENT TITLE="Debugging" ID="debugging">
+ <CONTENT TITLE="How do I get my browser to report javascript errors?"
+ ID="javascriptErrors" NUMID="4_43">
+ <P>
+There are debugging tools for many browsers. Learn to use them all.
+ </P>
+ <LIST TYPE="DL">
+ <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;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;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 &amp;quot;Always
+show errors&amp;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 &amp;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 &amp;gt; Advanced &amp;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 &amp;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 &amp;gt; <ICODE>Developer</ICODE>
+&amp;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>
+ <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 &amp;gt; User Agent &amp;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:
+ <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>
+ </P>
+ </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 &amp;quot;protects&amp;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.
+ <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>
+ </P>
+ </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.
+<CODE>
+document.oncontextmenu = function() {
+ return false;
+};
+</CODE>
+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.
+<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>
+</P>
+</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.
+ <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>
+ </P>
+ </CONTENT>
+ <CONTENT TITLE="I have &amp;lt;a href=&amp;quot;javascript:somefunction()&amp;quot;&amp;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:
+ <CODE>
+ &amp;lt;a href=&amp;quot;javascript:'&amp;amp;lt;h1&amp;amp;gt;' + document.lastModified + '&amp;amp;lt;/h1&amp;amp;gt;'&amp;quot;&amp;gt;lastModified&amp;lt;/a&amp;gt;
+</CODE>
+will result in replacing the current document with the value
+returned from <ICODE>document.lastModified</ICODE>, wrapped in an <ICODE>&amp;lt;h1&amp;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>&amp;lt;a href=&amp;quot;something.html&amp;quot; onclick=&amp;quot;somefunction();return false&amp;quot;&amp;gt;</ICODE>
+where <ICODE>something.html</ICODE> is a meaningful alternative. Alternatively,
+attach the <ICODE>click</ICODE> callback using an event registry.
+ <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>
+ </P>
+ </CONTENT>
+ </CONTENT>
+
+ <CONTENT TITLE="Comments and Suggestions" ID="comments" NUMID="5">
+ <P HTMLONLY="true">
+The FAQ uses the stylesheet <URL>faq.css</URL> and is generated
+from the xml source <URL>index.xml</URL> by the windows script
+host script <URL>process.wsf</URL> which also checks the links.
+ </P>
+ <CONTENT TITLE="Why do some posts have &amp;lt;FAQENTRY&amp;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 &amp;lt;FAQENTRY&amp;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 &amp;lt;FAQENTRY&amp;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. &amp;lt;FAQ**TRY&amp;gt; or similar.
+ </P>
+ </CONTENT>
+ <CONTENT TITLE="How do I make a suggestion?" NUMID="5_2" ID="makeSuggestion">
+ <P>
+To make a suggestion to the FAQ, use either the FAQENTRY method
+above, or email Garrett Smith dhtmlkitchen&amp;#64;gmail.com (current FAQ editor)
+or Jim Ley (jim.ley&amp;#64;gmail.com). All comments, suggestions, and
+especially corrections are welcome.
+ </P>
+ </CONTENT>
+ <!--
+ <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>
+ </CONTENTS>
+</FAQ>
/trunk/cljs/index.xml
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 2)
@@ -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 2)
@@ -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/code-guidelines/asi.html
===================================================================
--- trunk/cljs/notes/code-guidelines/asi.html (nonexistent)
+++ trunk/cljs/notes/code-guidelines/asi.html (revision 2)
@@ -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/index.html
===================================================================
--- trunk/cljs/notes/code-guidelines/index.html (nonexistent)
+++ trunk/cljs/notes/code-guidelines/index.html (revision 2)
@@ -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://yura.thinkweb2.com/named-function-expressions/"
+ >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/descendant-sel.html
===================================================================
--- trunk/cljs/notes/code-guidelines/descendant-sel.html (nonexistent)
+++ trunk/cljs/notes/code-guidelines/descendant-sel.html (revision 2)
@@ -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/review/index.html
===================================================================
--- trunk/cljs/notes/review/index.html (nonexistent)
+++ trunk/cljs/notes/review/index.html (revision 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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/index.html
===================================================================
--- trunk/cljs/notes/index.html (nonexistent)
+++ trunk/cljs/notes/index.html (revision 2)
@@ -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://yura.thinkweb2.com/named-function-expressions/">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/square-brackets/index.html
===================================================================
--- trunk/cljs/notes/square-brackets/index.html (nonexistent)
+++ trunk/cljs/notes/square-brackets/index.html (revision 2)
@@ -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/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/index.html
===================================================================
--- trunk/cljs/index.html (nonexistent)
+++ trunk/cljs/index.html (revision 2)
@@ -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/index.html
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Index: trunk/cljs/example/addcslashes.php
===================================================================
--- trunk/cljs/example/addcslashes.php (nonexistent)
+++ trunk/cljs/example/addcslashes.php (revision 2)
@@ -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 2)
@@ -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 2)
@@ -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 2)
@@ -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/cljs/process.wsf
===================================================================
--- trunk/cljs/process.wsf (nonexistent)
+++ trunk/cljs/process.wsf (revision 2)
@@ -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/faq.css
===================================================================
--- trunk/cljs/faq.css (nonexistent)
+++ trunk/cljs/faq.css (revision 2)
@@ -0,0 +1,201 @@
+/*
+Updated 2009-06-14 Garrett Smith
+*/
+
+
+a {
+ text-decoration: none;
+ color: #002288;
+ background: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+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;
+}
+
+#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/.settings/org.eclipse.php.core.prefs
===================================================================
--- trunk/.settings/org.eclipse.php.core.prefs (nonexistent)
+++ trunk/.settings/org.eclipse.php.core.prefs (revision 2)
@@ -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 2)
@@ -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