<?xml version="1.0" encoding="UTF-8"?>
<!-- name="generator" content="blojsom v3.2" -->
<rss version="2.0" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
    <channel>
        <title>DHTML Kitchen News</title>
        <link>http://dhtmlkitchen.com/news/default</link>
        <description>Front End Web Development</description>
        <language>en</language>
        <image>
            <url>http://dhtmlkitchen.com/favicon.ico</url>
            <title>DHTML Kitchen News</title>
            <link>http://dhtmlkitchen.com/news/default</link>
        </image>
        <docs>http://blogs.law.harvard.edu/tech/rss</docs>
		<generator>blojsom v3.2</generator>
		<managingEditor>dhtmkitchen@gmail.com</managingEditor>
		<webMaster>dhtmkitchen@gmail.com</webMaster>
		<pubDate>Thu, 9 Sep 2010 00:15:52 -0500</pubDate>

                        <item>
            <title>JavaScript Query Engines</title>
            <link>http://dhtmlkitchen.com/news/default/2010/09/09/JavaScript-Query-Engines</link>
            <description>&lt;p&gt;
   By Garrett Smith, with input from John David Dalton, Scott Sauyet, and a ton of feedback Diego Perini.
&lt;/p&gt;

&lt;p&gt;
Most popular javascript libraries these days have a CSS Selector query engine. The concept originated from 
&lt;a href=&quot;http://dean.edwards.name/my/cssQuery/&quot;&gt;CSSQuery&lt;/a&gt; and was 
popularized by jQuery. The idea is to match elements in the DOM based on a CSS selector string.
&lt;/p&gt;

&lt;p&gt;
   The &lt;a href=&quot;#sel-normative&quot;&gt;W3C Selectors API Level 1&lt;/a&gt;, a Candidate Recommendation since 2009, 
was started in 2006, based on CSS selectors.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;#sel-normative&quot;&gt;CSS2&lt;/a&gt; selectors have been around for over 12 years. 
The syntax and concepts are easy to grasp and are well known &amp;mdash; or are they? 
&lt;/p&gt;

&lt;p&gt;
What&#39;s the difference between the &lt;a href=&quot;#sel-normative&quot;&gt;W3C Selectors API&lt;/a&gt; and 
those found in javascript libraries? They&#39;re both based on CSS Selectors, 
right? Aren&#39;t they all about the same? 
&lt;/p&gt;

&lt;p&gt;
It turns out they&#39;re not. There are many significant differences between 
CSS Selectors[&lt;a href=&quot;#sel-normative&quot;&gt;CSS2&lt;/a&gt;] and the 
CSS Selector query engines defined in javascript libraries. 
&lt;/p&gt;

&lt;p&gt;
The differences are explained and demostrated by the library examples. 
&lt;/p&gt;

&lt;p&gt;
  When considering a Javascript library, it is important to examine the source 
  code by code review to in order to make an informed decision about its quality. 
&lt;/p&gt;

&lt;h2&gt;Library Examples&lt;/h2&gt;
&lt;p&gt;
The examples demonstrate problems primarily in &lt;a href=&quot;http://jquery.com&quot;&gt;jQuery&lt;/a&gt;, 
but also in &lt;a href=&quot;developer.yahoo.com/yui/2/&quot;&gt;YUI 2&lt;/a&gt;, 
 &lt;a href=&quot;developer.yahoo.com/yui/3/&quot;&gt;YUI 3&lt;/a&gt;, 
 &lt;a href=&quot;http://extjs.com/&quot;&gt;Ext-JS&lt;/a&gt;, 
and &lt;a href=&quot;http://sencha.com/&quot;&gt;Sencha&lt;/a&gt;. Listing every bug in each major library would 
have been too much cover in the already lengthy article.
&lt;/p&gt;

&lt;h2&gt;CSS3 Compliance&lt;/h2&gt;
&lt;p&gt;
   To be CSS2 compliant, a CSS Selector Engine must follow the lexical grammar defined in the 
   CSS2 specification to parse selector strings and perform correct matching on elements.
&lt;/p&gt;

&lt;p&gt;
  None of the libraries reviewed are compliant with any edition of CSS.  
  The conformance violations are pretty obvious: Broken parsing, incorrect matching, errors 
  thrown on CSS1 selectors and proprietary syntax extensions. These and other problems 
  are explained below. 
&lt;/p&gt;

&lt;p&gt;
Although any library author is free to make any design decision he chooses, if the design decisions violate the CSS 
specifications and drafts (and these do), then the code cannot honestly be said to be CSS3 compliant. 
&lt;/p&gt;

&lt;p&gt;
For example, &lt;a href=&quot;http://jquery.com&quot;&gt;jQuery.com&lt;/a&gt; claims CSS3 Compliance and Ext-JS claims 
&quot;DomQuery supports most of the CSS3 selectors spec, along with some custom selectors and basic XPath&quot;. 
Whether Ext supports more than half of CSS3 selectors depends on the browser; 
the claim of &quot;basic XPath&quot; support is false (possibly outdated documentation from previous editions 
which borrower from jQuery). 
&lt;/p&gt;

&lt;h2&gt;What do the Libraries Do?&lt;/h2&gt;
&lt;p&gt;
The current javascript library APIs do not adhere CSS2 selectors[&lt;a href=&quot;#sel-normative&quot;&gt;CSS2&lt;/a&gt;]. 
Most implement nonstandard extensions and different behavior for standard selectors. All of them fail to 
implement many pseudo-classes of CSS1-CSS3. Some match properties instead of attributes for attribute selectors.  
They all tend to copy each other and the respective documentation of each doesn&#39;t always reflect reality. 
They tend to change substantially between each release, removing support for XPath, redesign with 
&lt;code&gt;document.querySelectorAll&lt;/code&gt;, removing some selectors and adding others. 
They tend to work differently in &lt;abbr title=&quot;Internet Explorer&quot;&gt;IE&lt;/abbr&gt;, depending on the mode. The article will elaborate on cases of 
these things happening in javascript libraries.
&lt;/p&gt;

&lt;h2&gt;Cross Browser Consistency?&lt;/h2&gt;
&lt;p&gt;
A few superficial tests in this article demonstrate significant problems in the cross browser behavior 
of these libraries. More inconsistencies are revealed in Diego Perini&#39;s 
&lt;a href=&quot;http://javascript.nwbox.com/NWMatcher/release/test/css3-compat/&quot;&gt;Index of CSS selector tests&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
The supported browser list in jQuery includes 
&lt;abbr title=&quot;Internet Explorer&quot;&gt;IE&lt;/abbr&gt; 6.0+, FF 2+, Safari 3.0+, Opera 9.0+, and Chrome. 
However all libraries tested have results within that set of browsers that are 
inconsistent with the spec, inconsistent between browsers, and in the case of selectors extensions, 
inconsistent with other libraries.
&lt;/p&gt;

&lt;h2&gt;Problems Overview&lt;/h2&gt;
&lt;p&gt;
Problems in jQuery, YUI2, YUI 3, Ext, and Sencha include:
&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;#broken-by-design&quot;&gt;Broken by Design&lt;/a&gt;
	    &lt;ul&gt;
          &lt;li&gt;Fundamentally broken abstractions and browser inconsistency.
          &lt;li&gt;
              Native First Dual Approach, or &lt;abbr title=&quot;Native-First, Dual&quot;&gt;NFD&lt;/abbr&gt; - Inconsistent. 
              Variance based on NodeSelector presence/absence or errors thrown and handled with the library&#39;s fallback.
          &lt;li&gt;
      	      Syntax Extensions - nonstandard and inconsistent.
	      &lt;/li&gt;
		  &lt;li&gt;
             Incorrect Documentation.
    &lt;/ul&gt;
	
    &lt;li&gt;
    &lt;a href=&quot;#broken-parsing&quot;&gt;Broken Parsing&lt;/a&gt;
	&lt;ul&gt;
      &lt;li&gt; Fails to ignore various whitespace in attribute values, as &lt;code&gt;a[name= bar\n\t]&lt;/code&gt; (YUI2, Ext);
      &lt;li&gt; Not throwing errors on invalid, unhandled input.
      either returning a result that is either empty or contains elements (All: YUI2, YUI3, Ext, Sencha, jQuery).
      &lt;li&gt; Parse multiple adjacent whitespace as multiple descendant selector.
        (Ext)
      &lt;li&gt; Fail to parse certain whitespace in descendant selector (YUI 2).
      &lt;li&gt; Splitting input on &lt;code&gt;&quot;,&quot;&lt;/code&gt; &amp;mdash; this breaks attribute selectors where the attribute value contains a comma
       (e.g. &lt;code&gt;&quot;[title=&#39;Hey, Joe&#39;]&quot;&lt;/code&gt;); (Ext, Sencha).
    &lt;/ul&gt;

	&lt;li&gt;&lt;a href=&quot;#broken-matching&quot;&gt;Broken Matching&lt;/a&gt;
	  &lt;ul&gt;
        &lt;li&gt;Universal selector mismatches
        &lt;li&gt;Attributes vs properties mistakes
    &lt;li&gt;Pseudo-class selectors returning every element or throwing errors
    &lt;li&gt;Case sensitivity applied to case-insensitive attributes 
	  &lt;/ul&gt;
&lt;/ol&gt;

&lt;h2&gt;Problems Details&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;
  &lt;h3&gt;
  	  &lt;a id=&quot;broken-by-design&quot; href=&quot;#broken-by-design&quot;&gt;Broken by Design&lt;/a&gt;
  &lt;/h3&gt;
  &lt;p&gt;
  The biggest problems are the design issues, this includes &lt;abbr title=&quot;Native-First, Dual&quot;&gt;NFD&lt;/abbr&gt; 
  approach and reliance on fundamentally broken abstractions. Some problems such 
  as psuedo-class related bugs are seen in parsing and matching. These bugs cannot be as neatly fixed. 
  &lt;/p&gt;
  
  &lt;ul&gt;
  &lt;li&gt;
    &lt;h4&gt;Fundamentally Broken Abstractions&lt;/h4&gt;
    &lt;p&gt;
       A fundamentally broken abstraction is an abstraction that &lt;dfn&gt;cannot&lt;/dfn&gt; 
       function consistently across browsers.
    &lt;/p&gt;
    
    &lt;p&gt;
       The reviewed libraries&#39; query selector engines are an example of a fundamentally 
       broken abstraction. (Though the problems in the libraries reviewed go beyond the bugs that 
       are seen in the query engines).
    &lt;/p&gt;
    
    &lt;p&gt;
       You might say something like:-
       &quot;Hey, nothings&#39; perfect, right?&quot;, or &quot;The libraries have a large user base;
       they can&#39;t be &lt;em&gt;that&lt;/em&gt; broken, can they?&quot; or &quot;Can&#39;t the bugs be fixed?&quot;
       Those things have all been said and although fixing the bugs might seem like 
       the right thing to do, in reality it can get complicated. 
    &lt;/p&gt;
    
    &lt;h5&gt;Dependencies, Consistency, and Change&lt;/h5&gt;
    &lt;p&gt;
       Any change to a low-level abstraction propagates to its dependencies.  
    &lt;/p&gt;
    
    &lt;p&gt;
       Fixing bugs in a low level module creates instability which can break things (like jQuery plugins or widgets). 
       Before attempting to fix any bug, the author must first get an understanding 
       of the problem(s) caused by his code. In the case of a fundamentally broken abstraction,
       one choice may be to not attempt to fix the bug but to leave it and deprecate the method.
       If the bug is a core part of the library, it may be possible to refactor the library to not 
       use that method. If that cannot be done (as is the case for the reviewed libraries) then not 
       using not use the library is probably the best option.
    &lt;/p&gt;
    
    &lt;p&gt;
       Most libraries that use a selector engines do so at a lower level. Each bug in 
       library&#39;s selector engine propagates to a higher level. If the selector engine&#39;s 
       behavior is changed, as by fixing a bug, that change is propagated to all of the 
       higher level dependencies. Such behavioral changes cause instfability. The alternative 
       to making such changes (and causing instability) is to not fix the bugs. 
    &lt;/p&gt;
    
    &lt;p&gt;
       The infamous &lt;code&gt;dojo.isArray&lt;/code&gt; is one example of a bug in a 
       low-level abstraction that was not fixed and despite having been pointed out over 
       many discussions over many years on comp.lang.javascript, es-discuss mailing list,
       and most recently on Ajaxian.com. The problems with the method are that it doesn&#39;t work 
       cross-frame, it can return falsish values (&lt;code&gt;0&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt;, 
       &lt;code&gt;undefined&lt;/code&gt;), and has a useless statement (&lt;code&gt;typeof it == &quot;array&quot;&lt;/code&gt;). 
       The method will, however, have consistent results across browsers.
    &lt;/p&gt;
    
    &lt;p&gt;
       However, sometimes an abstraction fails to work consistently across browsers. 
       This is often due to a limitation in a browser. 
    &lt;/p&gt;
    
    &lt;p&gt;   
       The author who initially failed to recognize such problem is faced with the decision to either
       attempt to get the abstraction working correctly across browsers, 
       leave it alone, or fix it to work correctly in some cases, while attempting 
       to minimize change.
    &lt;/p&gt;
    
    &lt;p&gt;
       Due to the generalized nature of the 
       function, every case cannot be addressed. The result of attempting to make it work is 
       bloat and complexity. The code becomes difficult for the author to understand 
       and clients of the API are confused by inconsistent results, both with various inputs 
       to the function and with versions of the API. The paradox is that if the author does not 
       fix the bugs, then some instability can be avoided, but at a cost of inconsistency between 
       browsers.  
    &lt;/p&gt;
    
    &lt;p&gt;   
       One example of this is the attributes problem in Internet Explorer 7 and below 
       (IE8 fixed most of the issues). Generalized functions that attempt to make &lt;abbr title=&quot;Internet Explorer&quot;&gt;IE&lt;/abbr&gt; 
       correctly read attributes are more trouble and effort than it is worth. Instead, the 
       problems of reading attributes can be recognized as a limitation and the design of the 
       system can avoid doing that. By avoiding doing that, the problems 
       associated with doing that are avoided.
    &lt;/p&gt;
    
    &lt;p&gt;
       The best solution for such abstractions is to know what you are doing. Do not 
       create them in the first place. 
    &lt;/p&gt;
    
    &lt;p&gt;
       Any library that relies a broken query selector at the core is just as broken 
       as its query engine. Fixing the query engine bugs causes instability and the 
       browser inconsistencies are unacceptable. 
    &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;h4&gt;Native-First Dual Approach&lt;/h4&gt;
    &lt;p&gt;
    The most significant query selector problem is the design approach that I am calling a &lt;dfn&gt;native-first dual&lt;/dfn&gt;
    (&lt;abbr title=&quot;Native-First, Dual&quot;&gt;NFD&lt;/abbr&gt;) approach. &lt;abbr title=&quot;Native-First, Dual&quot;&gt;NFD&lt;/abbr&gt; is 
    creates great inconsistencies between different browsers running the same code. The approach is to first try 
    to use &lt;code&gt;document.querySelectorAll&lt;/code&gt; where it supported and where that is either unsupported or where 
    calling it throws an error, a fallback selector matching engine is used.  
    &lt;/p&gt;
    
    &lt;p&gt;
       Because an error will happen when any proprietary selector is used, the code path taken varies, 
       depending not just on the browser, but on the selector supplied. The library addresses these 
       errors by wrapping every call to &lt;code&gt;document.querySelectorAll&lt;/code&gt; in a 
	   &lt;code&gt;try&lt;/code&gt; / &lt;code&gt;catch&lt;/code&gt;. For jQuery, in the catch block, the query selector engine 
	   is called &lt;code&gt;oldSizzle&lt;/code&gt;. In some cases, &lt;code&gt;oldSizzle&lt;/code&gt; will throw an error where 
	   &lt;code&gt;document.querySelector&lt;/code&gt; all would have 
       returned a result, such as with &lt;code&gt;:focus&lt;/code&gt;. 
    &lt;/p&gt;
    
    &lt;p&gt;
       jQuery&#39;s &lt;code&gt;oldSizzle&lt;/code&gt; does not support the same input and standard selectors as 
       &lt;code&gt;querySelectorAll&lt;/code&gt;. The differences noticeable in the results of simple queries 
       can vary widely across browsers, as seen in the examples further on. Any library that uses 
       &lt;abbr title=&quot;Native-First, Dual&quot;&gt;NFD&lt;/abbr&gt; (Ext and YUI, among those) will exhibit the same problems.
    &lt;/p&gt;
    
    &lt;p&gt;
    Libraries that use &lt;abbr title=&quot;Native-First, Dual&quot;&gt;NFD&lt;/abbr&gt; include jQuery, YUI 3, and Ext-js, among others.
    Sencha, which is related to Ext-js, uses a different approach. YUI 2 does not use 
	&lt;code&gt;document.querySelectorAll&lt;/code&gt;.
    &lt;/p&gt;

	&lt;div class=&quot;text-diagram&quot;&gt;
    &lt;h5&gt;Native-first Dual Approach Diagram&lt;/h5&gt; 
&lt;pre&gt;
&amp;lt;Native QSA Support?&amp;gt;
 Y              N
 |              |
 |              |
[Try Use QSA]   +--[Use oldSizzle]
  |                /   |  
 &amp;lt;error thrown?&amp;gt;  /  &amp;lt;oldSizzle Supports Input?&amp;gt;
  Y             N/        Y          N
  |             /        |     [Throw error]
  |            /|        |              |           
[Use oldSizzle] |   [perform match      |
                |    and return result] |
                |          |            |
           [return result] |            |
                |          |            |
               &lt;b&gt;END&lt;/b&gt;        &lt;b&gt;END&lt;/b&gt;          &lt;b&gt;END&lt;/b&gt;
  &lt;/pre&gt;
    &lt;p&gt;
    Diagram of native-first dual approach. Notice the three different possible endings.
    &lt;/p&gt;
&lt;/div&gt;    
    &lt;p&gt;
    In addition to the code path variations, native support is buggy. For example, in Internet Explorer 8, 
    &lt;code&gt;&amp;lt;option selected&amp;gt;text&amp;lt;/option&amp;gt;&lt;/code&gt; isn&#39;t matched by &lt;code&gt;[selected]&lt;/code&gt; 
    but is matched by &lt;code&gt;[selected=selected]&lt;/code&gt;.
    &lt;/p&gt;
    
	&lt;/li&gt;
	&lt;li&gt;
    &lt;p&gt;
    The &lt;abbr title=&quot;Native-First, Dual&quot;&gt;NFD&lt;/abbr&gt; approach is the most 
	significant and fundamental mistake that a selectors library can make. It is 
	&lt;dfn&gt;broken by design&lt;/dfn&gt;.
    &lt;/p&gt;
    
    &lt;h3&gt;Syntax Extensions&lt;/h3&gt;
    &lt;p&gt;
    Some examples of syntax extensions include variations on what jQuery calls bare words attribute selectors, 
	&lt;code&gt;[att!=val]&lt;/code&gt;, CSS Style value selectors (in Ext), and even user-defined selectors. 
    &lt;/p&gt;
    &lt;p&gt;
    A W3C-compliant Selectors engine is required to throw errors on any invalid syntax in the selector, 
	such as those extensions defined by jQuery.
    &lt;/p&gt;
    &lt;p&gt;
    Instead of throwing an error, jQuery interprets &lt;code&gt;[att!=val]&lt;/code&gt; as a property selector (described below).  
	How a library interprets the syntax extension is nonstandard, proprietary, and may vary between libraries.
    &lt;/p&gt;
    &lt;p&gt;
    Ext provides additional syntax extensions to match style values. For example, to match 
	all the elements whose visibility is &lt;code&gt;&quot;inherit&quot;&lt;/code&gt;, one would use:
    &lt;/p&gt;
    &lt;pre&gt;
  [
    Ext.query(&quot;{visibility=inherit}&quot;).length,
    Ext.query(&quot;{visibility=visible}&quot;).length
  ]
&lt;/pre&gt;
    &lt;p&gt;
        That code running on the &lt;a href=&quot;ext.html&quot;&gt;Ext test page&lt;/a&gt; results:
    &lt;/p&gt;
	&lt;dl&gt;
		&lt;dt&gt;Internet Explorer (all versions)&lt;/dt&gt;
		&lt;dd&gt;18, 0&lt;/dd&gt;
		&lt;dt&gt;Safari 4, Opera 10.6, Firefox 3.6*, Firefox 2&lt;/dt&gt;
		&lt;dd&gt;0, 18&lt;/dd&gt;
	&lt;/dl&gt;
	&lt;p&gt;
    The &lt;code&gt;&quot;visibility=inherit&quot;&lt;/code&gt; result in Internet Explorer is an array of 18 elements,
	and &lt;code&gt;0&lt;/code&gt; in other browsers. This is due to the fact that Ext.query 
    relies on &lt;code&gt;Ext.Dom.getStyle&lt;/code&gt;, which checks &lt;code&gt;currentStyle&lt;/code&gt; in 
    &lt;abbr title=&quot;Internet Explorer&quot;&gt;IE&lt;/abbr&gt; and calls &lt;code&gt;getComputedStyle&lt;/code&gt; 
	in other browsers. 
    &lt;/p&gt;
	
	&lt;p&gt;
	   The result is only acheived when there is no trailing whitespace, as 
	   &lt;code&gt;&quot;{visibility=visible}&quot;&lt;/code&gt;, and not &lt;code&gt;&quot;{visibility=visible }&quot;&lt;/code&gt;.
	&lt;/p&gt;
	
	&lt;p class=&quot;footnote&quot;&gt;
	   *Firefox results with plugins disabled. 
	   Some plugins such as Firebug add nodes to the document which will affect
	   the result you see in your browser.
	&lt;/p&gt;
    &lt;/li&gt;
	&lt;li&gt;
	&lt;h4&gt;Incorrect Documentation&lt;/h4&gt;
	&lt;p&gt;
	   The documentation for most of the libraries tends to be out of sync with what 
	   the code actually does. The most egregious offenders are Sencha and Ext-js.
	&lt;/p&gt;
	&lt;p&gt;
	   This is yet another compelling reason for anyone who evaluating a library 
	   to carefully review the source code. The code explains exactly what it does. 
       Does the code clearly reflect what is stated in the documentation?
    &lt;/p&gt;
    &lt;p&gt;
       If, when examining the source code, it is realized that the 
	   code is written obscurely, such as using long methods with high degree of complexity,
	   then it may be best to avoid using the library on that basis because 
       at some point, a part of the application will inevitably need to be debugged and  
       long, complicated methods such as those found in jQuery can be painfully time consuming
       to step through.
	&lt;/p&gt;
	&lt;/li&gt;
  &lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
  &lt;h3&gt;
  	  &lt;a id=&quot;broken-parsing&quot; href=&quot;#broken-parsing&quot;&gt;Broken Parsing&lt;/a&gt;
  &lt;/h3&gt;
  &lt;p&gt;
     CSS2.1 defines the grammar by which tokens are matched. 
     None of the libraries tested are compliant with that grammar. 
     Most fail in very obvious ways. Some of the problems include:
  &lt;/p&gt;
  &lt;ul&gt;
        &lt;li&gt; Fails to ignore various whitespace in attribute values, as &lt;code&gt;a[name= bar\n\t]&lt;/code&gt; (YUI2, Ext);
        &lt;li&gt;Not throwing errors on invalid, unhandled input.
     &lt;p&gt;
     Matches invalid selectors &lt;code&gt;&quot;&gt;&gt;&gt;&quot;&lt;/code&gt;, &lt;code&gt;&quot;[name=]&quot;&lt;/code&gt;, &lt;code&gt;&quot;[a &gt;= 2]&quot;&lt;/code&gt;, &lt;code&gt;&quot;#---&quot;&lt;/code&gt;, 
         either returning a result that is either empty or contains elements (All: YUI2, YUI3, Ext, Sencha, jQuery).
     &lt;/p&gt;
        &lt;li&gt; Parse multiple adjacent whitespace as multiple descendant selector.
          (Ext)
        &lt;li&gt; Fail to parse certain whitespace in descendant selector (YUI 2).
        &lt;li&gt; Splitting input on &quot;,&quot; -- this breaks attribute selectors where the attribute value contains a comma
         (e.g. &lt;code&gt;&quot;[title=&#39;Hey, Joe&#39;]&quot;&lt;/code&gt;); (Ext, Sencha).
  &lt;/ul&gt;
    
  &lt;h4&gt;Fails to ignore various whitespace in attribute values&lt;/h4&gt;
  &lt;p&gt;
    Of the tested libraries, jQuery seems to be the only that is able parse (though not according to standard) 
    and ignore extraneous whitespace in attribute selectors (though it fails to match them properly). 
  &lt;/p&gt;
  &lt;p&gt;Given the HTML&lt;/p&gt;
  &lt;pre&gt;
  &amp;lt;a name=&quot;bar&quot;&amp;gt;
&lt;/pre&gt;
  And selector string:
  &lt;pre&gt;
  &quot;a[name= bar\n\t]&quot;;
&lt;/pre&gt; 
  &lt;p&gt;YUI2 and Ext will not match the &lt;code&gt;a&lt;/code&gt; element.&lt;/p&gt;
  
  &lt;h4&gt;Not throwing errors on Invalid, Unhandled Input&lt;/h4&gt;
  &lt;p&gt;
  All of the tested libraries allow invalid selectors such as &quot;#---&quot;.
  &lt;/p&gt;
  
  &lt;p&gt;
  YUI and Ext both fail on the descendant selector, as explained below.
  &lt;/p&gt;
  
  &lt;p&gt;
    Ext and Sencha split the input on &quot;,&quot;, and so will fail with the basic selector &#39;[title=&quot;Hello, user&quot;]&#39;. 
    Of course, it will also fail for any valid Identifier that contains an escaped , as in &quot;#x\\,&quot;, 
    which is a perfectly valid selector and works perfectly find when supplied as an 
    argument to document.querySelector. 
  &lt;/p&gt;
  
  &lt;p&gt;
    The fallback query selector engines in javascript libraries do not follow the lexical grammar defined in CSS2. 
    A library that accepts invalid selectors suffers more problems when it uses an 
    &lt;abbr title=&quot;Native-First, Dual&quot;&gt;NFD&lt;/abbr&gt; approach, no invalid syntax must be allowed because 
    allowing them creates more possibility for variance (depending on browser, version, selector string, etc, 
    see &lt;abbr title=&quot;Native-First, Dual&quot;&gt;NFD&lt;/abbr&gt; above).
  &lt;/p&gt;
  
  &lt;h3&gt;Descendant Selector&lt;/h3&gt;
  &lt;p&gt;
  A &lt;a href=&quot;#sel-normative&quot;&gt;Descendant Selector&lt;/a&gt; is two or more selectors separated by whitespace. 
  Whitespace is defined in CSS as: Only the characters &quot;space&quot; (&lt;code&gt;U+0020&lt;/code&gt;), &quot;tab&quot; 
  (&lt;code&gt;U+0009&lt;/code&gt;), &quot;line feed&quot; (&lt;code&gt;U+000A&lt;/code&gt;), &quot;carriage return&quot; (&lt;code&gt;U+000D&lt;/code&gt;), 
	 and &quot;form feed&quot; (&lt;code&gt;U+000C&lt;/code&gt;) can occur in white space. Other space-like characters, such as 
	 &quot;em-space&quot; (&lt;code&gt;U+2003&lt;/code&gt;) and &quot;ideographic space&quot; (&lt;code&gt;U+3000&lt;/code&gt;), are never part 
     of white space. 
  &lt;/p&gt;
  &lt;p&gt;
  YUI 2 and Ext 3.2.1 both fail on the descendant selector. 
  &lt;/p&gt;

  &lt;h4&gt;Fail to parse certain whitespace in descendant selector&lt;/h4&gt;
  &lt;p&gt;
  YUI 2 fails by inconsistently throwing errors with anything other than &lt;code&gt;U+0020&lt;/code&gt; (space). 
  For example, using a tab character, as in &lt;code&gt;&quot;html\u0009body&quot;&lt;/code&gt; will, depending on the 
  browser, throw an error with YUI2.
  &lt;/p&gt;

  &lt;h4&gt;Parsing multiple adjacent whitespace as multiple descendant selector&lt;/h4&gt;
  &lt;p&gt;
  Ext 3.2.1 fails by treating multiple adjacent whitespace as multiple selectors, thus:
  &lt;/p&gt;
&lt;pre&gt;
Ext.query(&quot;html  body&quot;); // two spaces 
&lt;/pre&gt;
  &lt;p&gt;
  - matches 0 elements, depending on the browser.
  &lt;/p&gt;  
&lt;/li&gt;

&lt;li&gt;
  &lt;h3&gt;
  	  &lt;a id=&quot;broken-matching&quot; href=&quot;#broken-matching&quot;&gt;Broken Matching&lt;/a&gt;
  &lt;/h3&gt;
	  &lt;ul&gt;
        &lt;li&gt;Universal selector mismatches
        &lt;li&gt;Attributes vs properties mistakes
        &lt;li&gt;Pseudo-class selectors returning every element or throwing errors
        &lt;li&gt;Case sensitivity applied to case-insensitive attributes 
	  &lt;/ul&gt;
  &lt;h4&gt;Universal selector mismatches&lt;/h4&gt;
  &lt;p&gt;
  The universal selector, written &lt;code&gt;&quot;*&quot;&lt;/code&gt;, matches any single element in the document tree 
  (&lt;a href=&quot;#sel-normative&quot;&gt;CSS 2.1&lt;/a&gt;). The selector is broken in jQuery.
  &lt;/p&gt;
  
  &lt;h4&gt;Attributes vs properties mistakes&lt;/h4&gt;
&lt;p&gt;
   Attributes are string values that the browser parses from the HTML source code.
   Properties reflect an object&#39;s state with any value type (number, boolean, function, etc).
&lt;/p&gt;
&lt;p&gt;
   Most libraries have significant problems with attribute matching, beginning with 
   library progenitor of the confusion: jQuery.
   These problems are shown below in the &lt;a href=&quot;#attributes-vs-properties&quot;
   &gt;jQuery Attributes vs Properties examples&lt;/a&gt;
&lt;/p&gt;

  &lt;h4&gt;Psuedo-class problems&lt;/h4&gt;
  &lt;p&gt;
  Pseudo-class problems include returning every element or throwing errors inconsistently.
  &lt;/p&gt;
  &lt;p&gt;
  In an &lt;abbr title=&quot;Native-First, Dual&quot;&gt;NFD&lt;/abbr&gt;-based library, when the fallback is used, 
  Pseudo-class such as &lt;code&gt;:focus&lt;/code&gt; and &lt;code&gt;:active&lt;/code&gt; 
  will either return every element or throw errors. For example:
  &lt;/p&gt;
&lt;pre&gt;
:link[rel!=nofollow]; // force fallback with custom != selector.
&lt;/pre&gt;
&lt;dl&gt;
&lt;dt&gt;  Ext&lt;/dt&gt;
&lt;dd&gt;
&lt;code class=&quot;error&quot;&gt;
TypeError: Ext.DomQuery.pseudos[name] is not a function
&lt;/code&gt;
&lt;/dd&gt;
&lt;dt&gt;
jQuery:
&lt;/dt&gt;
&lt;dd&gt;
&lt;code class=&quot;error&quot;&gt;
Syntax error, unrecognized expression: Syntax error, unrecognized expression: link
&lt;/code&gt;
&lt;/dd&gt;
&lt;dt&gt;
YUI 2:
&lt;/dt&gt;
&lt;dd&gt;
&lt;code&gt;[] // (empty result)
&lt;/code&gt;
&lt;/dd&gt;
&lt;dt&gt;
YUI 3:
&lt;/dt&gt;
&lt;dd&gt;
&lt;code class=&quot;error&quot;&gt;
Error thrown and not caught: name: TypeError, message: methodName is undefined
&lt;/code&gt;
&lt;/dd&gt;
&lt;/dl&gt;
  &lt;p&gt;
     These same libraries will all return a match for valid selector syntax &lt;code&gt;:link&lt;/code&gt; 
     in a browser that supports &lt;code&gt;document.querySelectorAll&lt;/code&gt; because they use the 
	 &lt;abbr title=&quot;Native-First, Dual&quot;&gt;NFD&lt;/abbr&gt; approach. 
  &lt;/p&gt;
  &lt;p&gt;
  	 The &lt;code&gt;:link&lt;/code&gt; pseudoclass is specified in CSS to match all unvisited 
	 links. Most browsers that implement &lt;code&gt;NodeSelector&lt;/code&gt; for &lt;code&gt;:link&lt;/code&gt; 
	 match &lt;em&gt;all&lt;/em&gt; links, regardless of whether or not they have been visited.
	 This is allowed by &lt;a href=&quot;http://www.w3.org/TR/2009/WD-css3-selectors-20090310/#dynamic-pseudos&quot;
	 &gt;Selectors Level 3 Working Draft&lt;/a&gt; and is done to prevent scripts from examining 
	 a user&#39;s history.
  &lt;/p&gt;
  &lt;p&gt;
  	 Throwing errors in one browser while returning a match in another is not interoperable. 	 
	 It would be better to either throw an error for &lt;code&gt;:link&lt;/code&gt; everywhere 
	 or to support &lt;code&gt;:link&lt;/code&gt; everywhere by matching on all links.
  &lt;/p&gt;
  
  &lt;h3&gt;Case Insensitive Attribute Values Treated Case-sensitively&lt;/h3&gt;
  &lt;p&gt;
  Are attribute values case sensitive or case insensitive? 
  &lt;/p&gt;
  
  &lt;p&gt;
  The CSS2 specification states:
  &lt;/p&gt;
  &lt;blockquote&gt;
    &lt;p&gt;
    The case-sensitivity of attribute names and values in selectors depends on the document language. 
    &lt;/p&gt;
  &lt;/blockquote&gt;
  &lt;p&gt;
  In &lt;a href=&quot;#sel-normative&quot;&gt;HTML 4&lt;/a&gt;, each attribute definition includes information about the 
  case-sensitivity of its value. Examples of case-insensitive (CI) attribute values 
  include &lt;code&gt;INPUT&lt;/code&gt; element&#39;s &lt;code&gt;type&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; attributes 
  and the &lt;code&gt;FORM&lt;/code&gt; element&#39;s &lt;code&gt;action&lt;/code&gt; and &lt;code&gt;method&lt;/code&gt; attributes, 
  among many others. Some case sensitive (CS) attribute values include the global &lt;code&gt;id&lt;/code&gt; 
  attribute, and, for the &lt;code&gt;A&lt;/code&gt; element, the &lt;code&gt;name&lt;/code&gt; attribute.
  &lt;/p&gt;
  
  &lt;p&gt;
  Thus, &lt;code&gt;[method=GeT]&lt;/code&gt; must match &lt;code&gt;&amp;lt;form method=&#39;get&#39;&amp;gt;&lt;/code&gt; while &lt;code&gt;[name=Q]&lt;/code&gt; 
  would match &lt;code&gt;&amp;lt;input name=&quot;q&quot; type=&quot;text&quot;&amp;gt;&lt;/code&gt; and not &lt;code&gt;&amp;lt;a name=&quot;q&quot;&amp;gt;&lt;/code&gt;. 
  &lt;/p&gt;
  
  &lt;p&gt;
  To add to the confusion, &lt;a href=&quot;#sel-normative&quot;&gt;HTML5&lt;/a&gt; defines a &lt;em&gt;global&lt;/em&gt; 
  case sensitivity map that conflicts with what is defined by HTML 4 for some specific element attributes. 
  &lt;/p&gt;
  
  &lt;p&gt;
  Browser implementations vary.
  &lt;/p&gt;
  
  &lt;p&gt;
     Internet Explorer 8 and below will correctly match the &lt;code&gt;INPUT&lt;/code&gt; element&#39;s 
     &lt;abbr title=&quot;Case Insensitive&quot;&gt;CI&lt;/abbr&gt; &lt;code&gt;NAME&lt;/code&gt; 
     attribute values in a case-insensitive manner while many other browsers will not.
  &lt;/p&gt;
  
  &lt;p&gt;
    For the most consistent and interoperable behavior, authors are advised to not rely on 
    case-insensitive attribute matching for &lt;code&gt;NodeSelector&lt;/code&gt; but to instead supply 
    the case in the selector string as it appears in the source markup.
  &lt;/p&gt;
    
  &lt;p&gt;
     Although most libraries account for case insensitivity in element and attribute names, 
     they do not account for case insensitive attribute values. 
  &lt;/p&gt;
  
  &lt;p&gt;
     While implementations vary, the javascript library query engines pass the variance 
     right on to their callers, providing inconsistent results.
  &lt;/p&gt;
  
  &lt;p&gt;
     A javascript library could provide consistent cross-browser results by either
  &lt;/p&gt;
  
  &lt;ul&gt;
   &lt;li&gt; supporting no attribute selectors
   &lt;li&gt; providing a case-sensitivity map. 
  &lt;/ul&gt;
  
  &lt;p&gt;
    &lt;a href=&quot;javascript.nwbox.com/NWMatcher/&quot;&gt;NWMatcher&lt;/a&gt; provides a case-sensitivity map. 
    However it does not do so on a per element basis, but instead element-agnostically. 
    NWMatcher follows the &lt;a 
    href=&quot;http://www.whatwg.org/specs/web-apps/current-work/#selectors&quot;&gt;recommendation from HTML5&lt;/a&gt;.
  &lt;/p&gt;
  
  &lt;p&gt;
  Not all browsers will follow that case sensitivity map, which is a part of a draft. 
  &lt;/p&gt;
  
  &lt;p&gt;
  Attribute selectors involve conflicts and interdependencies between working drafts HTML5, and CSS2.1 (PR) the 
  official standard HTML 4.01, and conflicting implementations.
  &lt;/p&gt;
  
  &lt;p&gt;
  A program using lower case attribute values except in cases for &lt;code&gt;ID&lt;/code&gt;, &lt;code&gt;CLASS&lt;/code&gt;, and 
  &lt;code&gt;NAME&lt;/code&gt;, can avoid many of the differences, however that doesn&#39;t change the problem of a 
  javascript library that runs on a page with form &lt;code&gt;name=&quot;F1&quot;&lt;/code&gt; and uses a query selector 
  &lt;code&gt;[name=&quot;f1&quot;]&lt;/code&gt;.
  &lt;/p&gt;
  
  &lt;p&gt;
  A javascript query library can avoid these problems by disallowing attribute selectors altogether. It can do this by 
  throwing an error on any unsupported syntax. The strategy is explained below.
  &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;jQuery Selectors Quiz&lt;/h3&gt;
&lt;p&gt;
   Not long before writing this article, I published a &lt;a href=&quot;http://dhtmlkitchen.com/jstest/jquery/quiz.jsp&quot;&gt;quiz&lt;/a&gt; 
   of 10 multiple-choice questions of simple, common selectors being applied to 9 lines of HTML. I did this after 
   the jQuery team had &lt;a href=&quot;https://twitter.com/jquery/status/13674858690&quot;&gt;tweeted&lt;/a&gt; about an 
   &lt;a href=&quot;http://www.tuttoaster.com/some-good-and-advanced-jquery-techniques&quot;&gt;article&lt;/a&gt; demonstrating 
   invalid selector syntax using jQuery&#39;s &quot;bare words&quot; attribute/property selector to match property values instead 
   of attributes. The confusion that jQuery has helped propagate was to blur the distinction between properties and 
   attributes. That confusion was shown in the article, which had espoused such invalid techniques and which jQuery had endorsed.
&lt;/p&gt;
&lt;h4&gt;Tweet&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;
Some Good and Advanced jQuery Techniques - &lt;a href=&quot;http://bit.ly/dli5EN&quot;&gt;http://bit.ly/dli5EN&lt;/a&gt;  
9:01 AM May 9th
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
   It seems surprising that the jQuery team would espouse that, especially light of all the attention 
   that has been paid to the broken &lt;code&gt;ATTR&lt;/code&gt; function (explained below).
   My response to that was to question the reader of what that code actually does. 
&lt;/p&gt;

&lt;p&gt;
   For each correct answer submitted, the quiz-taker is presented with the explanation of why the 
   answer is correct. At the bottom of the quiz are two example documents that display the results of each question. 
&lt;/p&gt;

&lt;h4&gt;Example HTML from Quiz&lt;/h4&gt;
&lt;pre id=&quot;example&quot;&gt;
1.   &amp;lt;img width=&quot;600&quot; src=&quot;logo.gif&quot; id=&quot;imageOne&quot; style=&quot;display: none&quot; alt=&quot;Write less&quot;&amp;gt;
2.   &amp;lt;img src=&quot;logo.gif&quot; id=&quot;imageTwo&quot; alt=&quot;Do More!&quot;&amp;gt;
3.   &amp;lt;img width=&quot;100&quot; src=&quot;logo.gif&quot; id=&quot;imageThree&quot;  alt=&quot;Write less&quot;&amp;gt;
4.   &amp;lt;img width=&quot;0&quot; src=&quot;logo.gif&quot; id=&quot;imageFour&quot;  alt=&quot;Write less&quot;&amp;gt;
5.   &amp;lt;input type=&quot;image&quot; width=&quot;600&quot; src=&quot;logo.gif&quot; id=&quot;inputOne&quot; alt=&quot;Write less&quot;&amp;gt;
6.   &amp;lt;input type=&quot;image&quot; width=&quot;100&quot; src=&quot;logo.gif&quot; id=&quot;inputTwo&quot; alt=&quot;Do More!&quot;&amp;gt;
7.   &amp;lt;input type=&quot;image&quot; src=&quot;logo.gif&quot; id=&quot;inputThree&quot; alt=&quot;Write less&quot;&amp;gt;
8.   &amp;lt;input type=&quot;image&quot; src=&quot;logo.gif&quot; width=&quot;0&quot; id=&quot;inputFour&quot; alt=&quot;Write less&quot;&amp;gt;

9.   &amp;lt;pre&amp;gt;-&amp;lt;/pre&amp;gt;
&lt;/pre&gt;

&lt;p&gt;
Test results (&lt;a href=&quot;http://dhtmlkitchen.com/jstest/jquery/ex.html&quot;&gt;standards&lt;/a&gt;, 
&lt;a href=&quot;http://dhtmlkitchen.com/jstest/jquery/exq.html&quot;&gt;quirks&lt;/a&gt;).
&lt;/p&gt;

&lt;p&gt;
No tricky edge cases, however as shown in the test, the answers vary between browsers, with surprising results.
&lt;/p&gt;

&lt;p&gt;
The &lt;a 
href=&quot;http://www.tuttoaster.com/some-good-and-advanced-jquery-techniques&quot;&gt;jQuery-tweeted article&lt;/a&gt; 
espouses the use of &lt;code&gt;$(&#39;img[width=600]&#39;)&lt;/code&gt; to get &lt;cite&gt;&quot;All the images whose width is 600px&quot;&lt;/cite&gt;.  
That&#39;s different from the W3C Selectors API (draft)[&lt;a href=&quot;#sel-normative&quot;&gt;SELECT&lt;/a&gt;] specifies. 
&lt;/p&gt;

&lt;p&gt;
If the attribute&#39;s value were quoted, as &lt;code&gt;img[width=&quot;600&quot;]&lt;/code&gt;, then standard behavior for that 
query should match img elements whose width attribute is exactly the value &quot;600&quot;, never mind if has been rendered at 600px.
&lt;/p&gt;

&lt;p&gt;
In contrast, the Selectors API[&lt;a href=&quot;#sel-normative&quot;&gt;SELECT&lt;/a&gt;] specifies that an error should be thrown when 
invalid syntax is supplied. Since &lt;code&gt;600&lt;/code&gt; is neither a string nor an identifier, the entire selector is invalid. 
A compliant Selectors implementation must throw an error with that.
&lt;/p&gt;
The Selectors API Level 1[&lt;a href=&quot;#sel-normative&quot;&gt;SELECT&lt;/a&gt;] states:
&lt;blockquote&gt;
&lt;p&gt;If the given group of selectors is invalid ([&lt;a href=&quot;http://www.w3.org/selectors-api/#SELECT&quot;&gt;SELECT&lt;/a&gt;], section 13),
the implementation must &lt;a 
href=&quot;http://www.w3.org/DOM-Level-3-Core/core.html#DOMException-SYNTAX_ERR&quot;
&gt;raise a SYNTAX_ERR exception&lt;/a&gt;.
&lt;/p&gt;
&lt;/blockquote&gt;

CSS 2.1[&lt;a href=&quot;#sel-normative&quot;&gt;CSS2&lt;/a&gt;] states:
&lt;blockquote&gt;
&lt;p&gt;
Attribute values must be identifiers or strings. 
&lt;/p&gt;
&lt;/blockquote&gt;
And also:
&lt;blockquote&gt;
&lt;p&gt;
When a user agent cannot parse the selector (i.e., it is not valid CSS2.1), it must 
&lt;a href=&quot;http://www.w3.org/TR/CSS2/syndata.html#ignore&quot;&gt;ignore&lt;/a&gt; the selector and 
the following declaration block (if any) as well. 
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;Selector Extensions and CSS3 Compliance&lt;/h3&gt;
&lt;p&gt;
Many selector libraries do not throw an error when given invalid selector syntax. 
Instead, the library interprets the invalid selector as a property selector (described below). 
&lt;/p&gt;

&lt;p&gt;
 In the case of jQuery being passed an attribute selector, 
 the &lt;code&gt;ATTR&lt;/code&gt; function is used to match a property value. 
&lt;/p&gt;

&lt;p&gt;
   Other libraries will do different things. Some may match attribute values while others do not. 
   None of the javascript libraries are CSS3 compliant.
&lt;/p&gt;

&lt;p&gt;
Before looking at the results of how jQuery handles attribute selectors, some definition of terms is in order.
&lt;/p&gt;

&lt;h4&gt;Attribute Selectors&lt;/h4&gt; 
&lt;p&gt;
Standard CSS 2.1 attribute selectors match attributes defined in the source document. Any attribute value must be 
either a string or an identifier. In CSS2.1, a string is delimited either by single or double quote marks 
and an identifier is defined:
&lt;/p&gt;

&lt;h4&gt;CSS Identifier&lt;/h4&gt;
&lt;p&gt;
In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the 
characters [a-zA-Z0-9] and ISO 10646 characters U+00A1 and higher, plus the hyphen (&lt;code&gt;-&lt;/code&gt;) and the 
underscore (&lt;code&gt;_&lt;/code&gt;); they cannot start with a digit, or a hyphen followed by a digit. Identifiers can 
also contain escaped characters and any ISO 10646 character as a numeric code (see next item). For 
instance, the identifier &quot;&lt;code&gt;B&amp;amp;W?&lt;/code&gt;&quot; may be written as &quot;&lt;code&gt;B\&amp;amp;W\?&lt;/code&gt;&quot; or &quot;&lt;code&gt;B\26 W\3F&lt;/code&gt;&quot;. 
&lt;/p&gt;

&lt;p&gt;
The definition is unfortunately looser than what is defined by the lexical grammar of CSS, which disallows identifier beginning 
with a hyphen followed by a hyphen, however the libraries don&#39;t match either definition 
(see also CSS WG &lt;a href=&quot;http://wiki.csswg.org/spec/css2.1#issue-174&quot;&gt;bug #174&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;
CSS identifier is also used in class and ID selectors.
&lt;/p&gt;
&lt;p&gt;
CSS 2.1 defines four attribute selectors:
&lt;/p&gt;

&lt;pre&gt;[att]&lt;/pre&gt;
    &lt;p&gt;
	   Match when the element sets the &quot;att&quot; attribute, whatever the value of the attribute.
	&lt;/p&gt; 
&lt;pre&gt;[att=val]&lt;/pre&gt;
    &lt;p&gt;
	   Match when the element&#39;s &quot;att&quot; attribute value is exactly &quot;val&quot;.
	&lt;/p&gt; 
&lt;pre&gt;[att~=val]&lt;/pre&gt;
    &lt;p&gt;    
   	  Represents an element with the att attribute whose value is a white space-separated list of words, 
      one of which is exactly &quot;val&quot;. If &quot;val&quot; contains white space, it will never represent anything 
      (since the words are separated by spaces). If &quot;val&quot; is the empty string, it will never represent anything either. 
    &lt;/p&gt;
&lt;pre&gt;[att|=val]&lt;/pre&gt;
    &lt;p&gt;
        Represents an element with the &lt;code&gt;att&lt;/code&gt; attribute, its value either being exactly &lt;code&gt;&quot;val&quot;&lt;/code&gt; or 
		beginning with &lt;code&gt;&quot;val&quot;&lt;/code&gt; immediately followed by &lt;code&gt;&quot;-&quot;&lt;/code&gt; (&lt;code&gt;U+002D&lt;/code&gt;). This is primarily 
		intended to allow language subcode matches (e.g., the &lt;code&gt;hreflang&lt;/code&gt; attribute on the &lt;code&gt;a&lt;/code&gt; 
		element in HTML) as described in RFC 3066 ([&lt;a href=&quot;http://www.ietf.org/rfc/rfc3066.txt&quot;&gt;RFC3066&lt;/a&gt;]) or its 
		successor. For &lt;code&gt;lang&lt;/code&gt; (or &lt;code&gt;xml:lang&lt;/code&gt;) language subcode matching, please see the 
		&lt;code&gt;:lang&lt;/code&gt; pseudo-class. 
    &lt;/p&gt;

&lt;h4&gt;CSS3 Attribute Selectors&lt;/h4&gt;

&lt;pre&gt;[att*=val]&lt;/pre&gt;
&lt;p&gt;
  Match element whose &quot;att&quot; attribute value contains the substring &quot;val&quot;.
&lt;/p&gt;
&lt;pre&gt;E[foo^=&quot;bar&quot;]&lt;/pre&gt; 
&lt;p&gt;
  Match element whose &quot;att&quot; attribute value begins  with the string &quot;val&quot;.
&lt;/p&gt;
&lt;pre&gt;E[att$=&quot;val&quot;]&lt;/pre&gt; 
&lt;p&gt;
  Match element whose &quot;att&quot; attribute value ends  with the string &quot;val&quot; .
&lt;/p&gt;

&lt;h4&gt;Property Matching&lt;/h4&gt;

&lt;p&gt;
   Dynamic object properties can be of any value and reflect the object&#39;s state. Matching 
   attribute selectors against properties is nonstandard. This is what jQuery does most of the time.
&lt;/p&gt;
&lt;h3&gt;
jQuery Attribute (Property) Selector Syntax Extensions
&lt;/h3&gt;

jQuery defines additional nonstandard extensions, for example, an incomplete list of just two:
&lt;dl&gt;
&lt;dt&gt;&lt;code&gt;[att!=val] &lt;/code&gt;
&lt;/dt&gt;
&lt;dd&gt;
  Represents an element whose property att is either undefined or is not val.
&lt;/dd&gt;
&lt;dt&gt;
&lt;code&gt;:animated&lt;/code&gt;
&lt;/dt&gt;
&lt;dd&gt;
  Select all elements that are in the progress of an animation at the time the selector is run.
&lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;
   The &lt;code&gt;:animated&lt;/code&gt; selector is inherently coupled to jQuery.  
&lt;/p&gt;   

&lt;p&gt;
   Other javascript libraries copy some of the jQuery selectors but implement them differently. 
   Rather than trying to match against property values, the other libraries match against 
   attribute values in more cases, though still often matching properties in MSIE.
&lt;/p&gt;

&lt;h4&gt;What Does jQuery Do?&lt;/h4&gt;
&lt;p&gt;
    jQuery does what the &lt;a href=&quot;http://www.tuttoaster.com/some-good-and-advanced-jquery-techniques/&quot;
  	&gt;blog article&lt;/a&gt; says it does. Well, in a few browsers, and depending on the rendering mode and 
  	the CSS that has been applied to the elements. What jQuery does varies widely across browsers. 
&lt;/p&gt;

&lt;h4&gt;
Bare Words Attribute Values Test
&lt;/h4&gt;

&lt;p&gt;
   jQuery &lt;dfn&gt;bare words&lt;/dfn&gt; attribute selector performs property matching in 
   the examples in the &lt;a href=&quot;http://www.tuttoaster.com/some-good-and-advanced-jquery-techniques/&quot;
  &gt;article&lt;/a&gt;. 
&lt;/p&gt;
&lt;pre&gt;
&#39;img[width=600]&#39;
&lt;/pre&gt;
&lt;dl&gt;
&lt;dt&gt;Opera 10.5&lt;/dt&gt;
&lt;dd&gt;&lt;pre&gt;
    imageOne
    imageTwo
&lt;/pre&gt;
&lt;/dd&gt;
&lt;dt&gt;
Firefox 3.6, Firefox 2, Safari 4, Chrome 4:
&lt;/dt&gt;
&lt;dd&gt;
&lt;pre&gt;
    imageOne
    imageTwo
    imageThree
    imageFour
&lt;/pre&gt;
&lt;/dd&gt;
&lt;dt&gt;
IE6 and IE7 (standards mode), IE8 (EmulateIE7)
&lt;/dt&gt;
&lt;dd&gt;
    (empty result)
&lt;/dd&gt;
&lt;dt&gt;
IE6 and IE7 (quirks mode), IE8 and IE9 (either mode)
&lt;/dt&gt;
&lt;dd&gt;
&lt;pre&gt;
    imageTwo
    imageThree
    imageFour
&lt;/pre&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;h4&gt;Cross Browser Results Analysis&lt;/h4&gt;
&lt;p&gt;
   The results above show inconsistent results from recent 
   versions of browsers that jQuery supports.
&lt;/p&gt;
&lt;p&gt;
	In fact, in IE8 alone, jQuery can result in three possible different results. 
	This is because in IE8, NodeSelector is unavailable in both quirks mode and IE7 mode. 
	Property values can vary between those modes. This leaves the possibility for jQuery 
	attribute selectors to match attributes, or one of two different property values, 
	depending on if the document is in quirks mode.
&lt;/p&gt;
&lt;p&gt;
	Had the selector&#39;s attribute value been a string (surrounded by quotation marks), as 
	&lt;code&gt;img[width=&#39;600&#39;]&lt;/code&gt;, then following the Selectors API, it must match all &lt;code&gt;img&lt;/code&gt; 
	elements whose width content attribute is exactly the value &lt;code&gt;&quot;600&quot;&lt;/code&gt;. 
&lt;/p&gt;	 
&lt;p&gt;
   However, because jQuery uses &lt;code&gt;querySelectorAll&lt;/code&gt; first (NFD), 
   &lt;code&gt;img[width=&#39;600&#39;]&lt;/code&gt; would match &lt;code&gt;img&lt;/code&gt; with attribute 
   &quot;600&quot; and for browsers that lack &lt;code&gt;querySelectorAll&lt;/code&gt;, will match 
   &lt;code&gt;img&lt;/code&gt; elements whose &lt;code&gt;width&lt;/code&gt; &lt;em&gt;property&lt;/em&gt; is &lt;code&gt;600&lt;/code&gt;.
&lt;/p&gt;

&lt;h4&gt;
	jQuery Property Matching Example
&lt;/h4&gt;
&lt;pre&gt;
$(&quot;body[ownerDocument]&quot;, &quot;html&quot;).length
&lt;/pre&gt;
&lt;p&gt;
All tested browsers:
&lt;/p&gt;
&lt;pre&gt;
    1
&lt;/pre&gt;
&lt;pre&gt;
$(&quot;html body[ownerDocument]&quot;).length
&lt;/pre&gt;
&lt;dl&gt;
&lt;dt&gt;
Safari 4, Firefox 3.6, IE8, 9, Chrome 4, Opera 10
&lt;/dt&gt;
&lt;dd&gt;&lt;code&gt;0&lt;/code&gt;&lt;/dd&gt;
&lt;dt&gt;
Firefox 2, IE6 and 7 (either mode), IE8 and 9 (quirks mode)
&lt;/dt&gt;
&lt;dd&gt;&lt;code&gt;
1
&lt;/code&gt;
&lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;
The example shows:
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt; jQuery performs property matching of ownerDocument in some browsers
 &lt;li&gt; when a context parameter is passed,  the property matching occurs in all tested browsers
&lt;/ol&gt;

&lt;p&gt;
   It is a bad idea to try to read &lt;code&gt;ownerDocument&lt;/code&gt; this way, however 
   some might actually think it is a good idea to try to read an input&#39;s &lt;code&gt;checked&lt;/code&gt; property. 
   &amp;mdash; a classic mistake, and one which unfortunately made it into the core of jQuery.
&lt;/p&gt;

&lt;h4 id=&quot;attributes-vs-properties&quot;&gt;
Attributes vs Properties
&lt;/h4&gt;
&lt;p&gt;
   The basic difference between attributes and properties are that attributes are 
   string values that the browser parses from the HTML source code and properties 
   reflect an object&#39;s state with any value type (number, boolean, function, etc).
&lt;/p&gt;

&lt;p&gt;
   jQuery has never handled attributes properly&lt;a href=&quot;#references-jquery&quot;&gt;[1][2][3][4][5][6]&lt;/a&gt;. 
   jQuery is designed in such a way that does not clearly distinguish attributes from properties. 
   The most common versions of Internet Explorer have this same problem. 
&lt;/p&gt;

&lt;h4&gt;
jQuery/Sizzle &lt;code&gt;ATTR&lt;/code&gt; Matcher
&lt;/h4&gt;
&lt;p&gt;
   The source code for Sizzle shows how object properties, before attributes, are matched.
&lt;/p&gt;

&lt;pre&gt;
ATTR: function(elem, match){
    var name = match[1],
    result = Expr.attrHandle[ name ] ?
        Expr.attrHandle[ name ]( elem ) :
        elem[ name ] != null ?
         elem[ name ] :
         elem.getAttribute( name ),
        value = result + &quot;&quot;,
        type = match[2],
        check = match[4];
&lt;/pre&gt;
&lt;p&gt;
The line:
&lt;/p&gt;
&lt;pre&gt;
elem[ name ] != null ? elem[ name ]
&lt;/pre&gt;
&lt;p&gt;
   - checks to see if the element&#39;s property is either &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;. 
   If that is the case, getAttribute is used as a fallback.
&lt;/p&gt;

&lt;p&gt;
   It would seem to make more sense to use &lt;code&gt;elem.getAttribute&lt;/code&gt; instead, 
   however, that would still leave behind problems with MSIE&#39;s completely broken 
   implementation of attributes, prior to IE8. 
&lt;/p&gt;

&lt;p&gt;
   Using &lt;code&gt;getAttribute(att, 2)&lt;/code&gt; for IE cannot be used safely because IE throws 
   errors in some cases with that and returns wrong values, such as strange numbers for 
   values of boolean attributes (&lt;a title=&quot;MSDN: getAttribute()&quot;
   href=&quot;http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx#ctl00_WikiViewer1_wikiItems&quot;&gt;MSDN&lt;/a&gt;).
&lt;/p&gt;
&lt;pre&gt;
input.getAttribute(&quot;disabled&quot;, 2); // Result number 0 in IE.
&lt;/pre&gt;

&lt;p&gt;
   Properties as attributes appears to have been a fundamental design oversight in 
   early jQuery. Changing the method to use a strategy to resolve attribute values 
   would change behavior with programs that use of jQuery, jQuery UI and any and all 
   plugin dependencies.  
&lt;/p&gt;

&lt;p&gt;
   So while changing ATTR to match attributes would make sense, it would not be practically 
   possible in IE (due to bugs in IE). IE bugs aside, changes to &lt;code&gt;ATTR&lt;/code&gt; would result in a 
   substantial change propagation to any and all dependencies. The problem cannot easily be fixed, 
   as jQuery is a public API and public APIs are forever. 
&lt;/p&gt;

&lt;p&gt;
   jQuery applies attribute selectors to match object properties, but where &lt;code&gt;querySelectorAll&lt;/code&gt; 
   is implemented, and an error is not thrown, jQuery resolves attributes.
&lt;/p&gt;

&lt;p&gt;
	Attribute values and properties are completely different things. Performing attribute selector 
	matching by testing elements&#39; property values, as jQuery does, is a significant deviation 
	from the way standard attribute selectors work.
&lt;/p&gt;

&lt;h3&gt;
CSS 2.1 Identifier: ID and Class Selectors
&lt;/h3&gt;

The CSS production for Identifier is also for &lt;code&gt;ID&lt;/code&gt; and &lt;code&gt;class&lt;/code&gt; Selector.
ID Selector
&lt;p&gt;
The ID selector is &quot;#&quot; followed by an identifier; B&amp;amp;W? is not an 
identifier and so #B&amp;amp;W? is not a valid ID selector. However in jQuery, the production for 
identifier is not matched; jQuery will use its native-first dual approach, which throws an error 
catches that, falling back to &lt;code&gt;oldSizzle&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;
document.querySelectorAll(&quot;#B&amp;amp;W?&quot;); // Error.
jQuery(&quot;#B&amp;amp;W?&quot;); // Result of 0 objects matched.
&lt;/pre&gt;

&lt;h4&gt;Class Selector&lt;/h4&gt;
&lt;p&gt;
The Class selector is &quot;#&quot; followed by an identifier.
&lt;/p&gt;
&lt;pre&gt;
document.querySelectorAll(&quot;.B&amp;amp;W?&quot;); // Error.
jQuery(&quot;.B&amp;amp;W?&quot;); // Result of 0 objects matched.
&lt;/pre&gt;
&lt;p&gt;
Not only jQuery, libraries have problems with these selectors.
&lt;/p&gt;
&lt;p&gt;
Ext-JS documentation uses invalid syntax and misleads the reader by falsely stating:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
The use of &lt;code&gt;@&lt;/code&gt; and quotes are optional. For example, &lt;code&gt;div[@foo=&#39;bar&#39;]&lt;/code&gt; 
is also a valid attribute selector.
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
   No! The &lt;code&gt;@&lt;/code&gt; in an attribute selector is &lt;em&gt;not a valid CSS Selector&lt;/em&gt; 
   Quotes are &lt;em&gt;not&lt;/em&gt; optional for CSS selectors. Omitting quotes in Ext (the big one) 
   may result in an error being thrown, depening on if the attribute value is an 
   &lt;dfn&gt;Identifier&lt;/dfn&gt; and when an error is thrown, the fallback is used. 
&lt;/p&gt;
&lt;p&gt;
   The same documentation is used for Sencha, and when and invalid query is passed in Sencha,
   the result is a javascript error. An XPath attribute selector using &lt;code&gt;[@foo=&#39;bar&#39;]&lt;/code&gt;
   would cause an error to be thrown in any browser. The difference with Sencha is that error 
   is not caught; no fallback is provided.
&lt;/p&gt;

&lt;h4&gt;
Other Libraries: A Peek at YUI, Ext-JS, and &quot;My Library&quot;
&lt;/h4&gt;
&lt;h5&gt;YUI 2&lt;/h5&gt;
  &lt;p&gt;
    YUI 2 supports some jQuery extensions, but for other extensions, and even for some standard 
    CSS selectors, it returns wrong results. For example, &lt;code&gt;&quot;:link&quot;&lt;/code&gt; and &lt;code&gt;&quot;:disabled&quot;&lt;/code&gt;, 
	return every element in the document.
  &lt;/p&gt;
  &lt;p&gt;
    YUI 2 supports only &lt;code&gt;U+0020&lt;/code&gt; white space in selectors and throws errors on anything 
	else. Mootools 1.2 has the same problem, throwing an error if the selector contains whitespace it 
    can&#39;t recognize (such as tab). Contrast to what is specified for whitespace in CSS2.
  &lt;/p&gt;	

&lt;h3&gt;What&#39;s Next?&lt;/h3&gt; 
&lt;p&gt;
   Upon learning that the library creates more cross browser problems than it solves, the 
   next logical step for the library user should be to stop using it, to remove it, and not 
   to jump blindly to another library. 
&lt;/p&gt;
&lt;p&gt;
   The most logical next step for developers realizing that their query library is failing 
   to live up to what was promised is to learn how to create reusable, forwards-compatible 
   abstractions that follow standards and work consistently across browsers. 
&lt;/p&gt;

&lt;h4&gt;For Library Users and Management&lt;/h4&gt;
&lt;p&gt;
   There is no substitute for knowledge (Deming). One who wants to build RIAs must read all 
   of the pertinent specifications and all of the pertinent browser documentation. 
   He should have a good foundation of OO principles and methodologies.
&lt;/p&gt;

&lt;p&gt;The following advice is offered to the reader:
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt; RTM - (ECMA, CSS2.1, Selectors, DOM 2 HTML, HTML4, HTML5, also MDC and MSDN).
    &lt;li&gt; Test across many browsers, including older browsers, to test degradation paths.
    &lt;li&gt; Get code reviews 
    &lt;li&gt; Ask smart questions
&lt;/ul&gt;
&lt;p&gt;
Everyone in the company should be focused on the successful production of a quality product. 
&lt;/p&gt;
&lt;p&gt;
   If management is making decisions about javascript (libraries or otherwise) and they are 
   not technically qualified to make technical assessments of quality, then they are effectively 
   hurting the company and they need to stop doing that.
&lt;/p&gt;

&lt;h4&gt;For Library Authors&lt;/h4&gt;
&lt;p&gt;
   Reusable abstractions are useful to fulfill software requirements quickly. The concept of 
   javascript library must evolve beyond the current state.
&lt;/p&gt;

&lt;h5&gt;Independent, Cohesive parts&lt;/h5&gt;
&lt;p&gt;
The libararies reviewed are highly interdependent. 
&lt;/p&gt;
&lt;p&gt;
The javascript programming language allows interface-based design without 
having to create an actual interface. For example, a method `elementHasClass` is needed, 
then that method could easily exist independently, and such methods do exist in YUI, for example.
There should be no need to depend on the concretion of &lt;em&gt;entire&lt;/em&gt; YUI core, just that method and 
whatever it depends upon. 
&lt;/p&gt;

&lt;p&gt;
   An interface does not need to &quot;change the way you write javascript. That would be the task of an
   IoC-type framework.
&lt;/p&gt;

&lt;p&gt;
   An interface does not promote dependence on one
   Big Thing. An interface should do &lt;em&gt;one&lt;/em&gt; thing. 
&lt;/p&gt;

&lt;h5&gt;Fundamentally Broken Abstractions&lt;/h5&gt;
&lt;p&gt;
   A fundamentally broken abstraction cannot function consistently across browsers
   in all contexts. What can be done about such problems?
&lt;/p&gt; 

&lt;p&gt;
   One approach is to try to make the abstraction work in all contexts. 
   A few extreme examples of that are in the &quot;APE.dom.getOffsetCoords&quot; function I wrote 
   several years back. Another is David Mark&#39;s attribute reading function 
   &lt;a href=&quot;http://www.cinsoft.net/scripts/prop.js&quot;&gt;&lt;code&gt;attr&lt;/code&gt;&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;   
   As seen in these examples, modules that have more browser-differences workarounds become 
   increasingly complex, have more edge cases, and are and much harder for humans to digest. 
&lt;/p&gt;

&lt;p&gt;   
   To avoid having a linear dependence on any abstraction the object 
   that is using the abstraction can be &lt;em&gt;configured&lt;/em&gt; so that the abstraction that it is 
   using can be switched to another abstraction with the same interface. 
&lt;/p&gt;

&lt;h4&gt;Speculative Generality&lt;/h4&gt;
&lt;p&gt;
   An interface that is built for &quot;users&quot; tends to lead to too much 
   generality, as seen in the popular libraries, burgeoning with fetures, complexity, and bugs.  
&lt;/p&gt;

&lt;p&gt;
   An interface that addresses differences in browsers should follow standards and use feature testing to derive 
   strong inferences about the client environment and should limit what it does to the least capable environments.
&lt;/p&gt;

&lt;h4&gt;Code Review&lt;/h4&gt;
&lt;p&gt;
   Blind acceptance of library code caused the Ajax library problem. Too many awful APIs, too 
   much misinformation and the result is a catastrophe. 
&lt;/p&gt;

&lt;p&gt;   
   To avoid the mistakes, libraries will need more peer review, and that starts with you, 
   reader. The next time you want to evaluate a library, look carefully at the source code. 
&lt;/p&gt;

&lt;p&gt;
   Technical management (at least in America) thinks that they can get away with 
   copying what everybody else is doing but they don&#39;t realize that this is hurting quality. 
   Ajax development has become an extreme case of the blind leading the blind.
&lt;/p&gt;

&lt;h3&gt;Focus on Quality&lt;/h3&gt;
&lt;p&gt;
   Teams that focus on short term costs and &quot;getting things done&quot; sacrifice quality. Sacrificing 
   quality creates technical debt. Technical debt hurts quality and increases the effort 
   (and cost) of maintaining the code. 
&lt;/p&gt;
&lt;p&gt;
   The most important step that a company can take is to focus on fulfilling its goals with quality 
   solutions. A company that focuses on quality will, in the long run, reduce the costs of production.
&lt;/p&gt;
&lt;p&gt;
   You can &lt;em&gt;not&lt;/em&gt; afford to do things wrongly. 
&lt;/p&gt;

&lt;h3&gt;Cross Browser Abstractions - Wrapper with a Fallback&lt;/h3&gt;
&lt;p&gt;
  What follows is a strategy for developing a consistent interface, 
  limited by the least common denominator. 
&lt;/p&gt;
&lt;p&gt;
   The strategy uses a mixture of standard features, where those are available, and compatible 
   fallbacks where they are missing or found buggy (by capability tests). 
&lt;/p&gt;
&lt;p&gt;
   Although the example of the concept is about Selector queries, the conceptual pattern and 
   strategy itself is applicable to many situations. 
&lt;/p&gt;

&lt;h4&gt;Filter the Input&lt;/h4&gt;
&lt;p&gt;
   A query selector that behaves consistently across browsers must verify that all inputs behave 
   consistently across all known implementations.  
&lt;/p&gt;
&lt;p&gt;
   The library can decide which selectors will be unsupported and filter them out.  Some selectors, 
   such as &lt;code&gt;:visited&lt;/code&gt;, are not possible to implement and not very useful anyway. Supporting 
   attribute selectors for IE is more trouble than it is worth. 
&lt;/p&gt;

&lt;h4&gt;Using NodeSelector&lt;/h4&gt;

&lt;p&gt;
   If the library chooses to use &lt;code&gt;NodeSelector&lt;/code&gt;, then it must follow the specification to the letter. 
   It must not allow any invalid selectors. It must not extend the CSS2 selectors syntax.
&lt;/p&gt;

&lt;h4&gt;Capability Tests&lt;/h4&gt;

&lt;p&gt;
   To determine if the browser provides a sufficient implementation of 
   &lt;code&gt;document.querySelectorAll&lt;/code&gt;, perform capability tests to check for not only 
   existence of &lt;code&gt;document.querySelectorAll&lt;/code&gt;, but known problems with the 
   supported selectors[12]
&lt;/p&gt;
&lt;p&gt;
   For example, a a CSS1-compliant query selector engine could employ a strategy where if the 
   selector did not match a validity constraint, then an error would be thrown. 
&lt;/p&gt;
&lt;pre&gt;
function makeQuery(selector, doc) {
    if(!isValidSelector(selector)) {
        throw new InvalidSelectorError(selector);
    }
    doc = doc || document;
    if(IS_QSA_SUPPORTED) { 
        return doc.querySelectorAll(selector);
    } else {
        return makeQueryFallback(selector, doc);
    }
}
&lt;/pre&gt;

&lt;p&gt;
Consistently throwing an error for unsupported selectors avoids the inconsistencies seen with the native-first dual approach.
&lt;/p&gt;
&lt;p&gt;
The library function could safely use &lt;code&gt;doc.querySelectorAll&lt;/code&gt; as a fallback, so long as the known implementations 
consistently support all of the selectors that the library supports[11]. And, in case you didn&#39;t notice, 
this strategy will work cross-frame, unlike every other selector engine.  
&lt;/p&gt;
&lt;pre&gt;
  &amp;lt;Is input Supported?&amp;gt;
   |           |
   Y           N- [Throw Error] -END| 
   |              
  &amp;lt;Native QSA Support?&amp;gt;
   |               |
   Y -[Use QSA]    N - [Use falback]
&lt;/pre&gt;
&lt;p&gt;
This is somewhat similar to the strategy used by Dojo, which documents that some selectors are unsupported.
&lt;/p&gt;

&lt;h4&gt;The Value of Queries&lt;/h4&gt;
&lt;p&gt;
The selector APIs in the several prominent javascript libraries reviewed are so broken 
that they obviously cannot be relied on. 
&lt;/p&gt;
&lt;p&gt;
The value of selectors that work as specified by the specifications has not been established. 
&lt;/p&gt;
&lt;p&gt;
There are several alternatives to using selectors. Anyone, though especially those who areusing a broken selectors API, 
should question how much value the abstraction provides. He should compare that value, positive or negative, to the alternatives.
&lt;/p&gt;

&lt;h4&gt;Drawbacks to Queries&lt;/h4&gt;
&lt;p&gt;
The program design approach of using DOM traversal to select nodes and then 
performing an action on one or more of them is usually much less efficient than 
standard alternatives. 
&lt;/p&gt;
&lt;p&gt;
DOM traversal is performed on page load, it can cause the page load to seem slower, especially if the 
action inside the loop triggers a recalc (also commonly called &quot;reflow&quot;). For a large document, 
thus can can cause the page to become unresponsive, as seen on the WHATWG HTML5 draft specification 
&quot;full version&quot; [&lt;a href=&quot;#ref-bugs&quot;&gt;13&lt;/a&gt;]. Such performance 
issues are more likely to affect slower systems, not fast developer systems. 
&lt;/p&gt;

&lt;h4&gt;Query Matching Strategy&lt;/h4&gt;
&lt;p&gt;
Most usage of queries don&#39;t allow for common traversal patterns of finding an ancestor. Such traversal pattern is often 
needed when using event delegation strategies, where the callback needs to know find an ancestor matching a particular 
criteria, usually either &lt;code&gt;ID&lt;/code&gt;, &lt;code&gt;className&lt;/code&gt; or &lt;code&gt;tagName&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;
var sel = new Selector(&quot;ul.panel&quot;);

function clickCallback(ev) {
  var target = DomUtils.getTarget(ev);
  if(sel.test(target)) {
    panelListClickHandler(ev);
  }
}
&lt;/pre&gt;
&lt;p&gt;
To handle this functionality, the &lt;code&gt;Selector.test&lt;/code&gt; method could use 
&lt;code&gt;Element.matchesSelector(txt)&lt;/code&gt; (after capability testing, of course). This is implemented 
in Gecko as &lt;code&gt;Element.mozMatchesSelector&lt;/code&gt; and in webkit as &lt;code&gt;Element.webkitMatchesSelector&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
   Since selector traversal and parsing is slower, another alternative would be to support only 
   simple selectors but without attributes, so limiting to type (element), class, and ID. 
&lt;/p&gt;

&lt;h4&gt;Alternatives&lt;/h4&gt;
&lt;p&gt;
The &quot;find something, do something&quot; approach has efficient alternatives alternatives. 
&lt;/p&gt;
&lt;p&gt;
If the &quot;do something&quot; action is adding an event handler to various nodes, then that can action be replaced by using event delegation. 
This is done by adding an event listener to a common ancestor.
&lt;/p&gt;
&lt;p&gt;
   If the &quot;do something&quot; action is modifying styles, then the script can add a &lt;code&gt;className&lt;/code&gt; 
   token to a common ancestor of 
   the matched nodes, allowing the browser to apply the cascade to descendant nodes. An example of this is linked from 
   the design section of the &lt;a href=&quot;http://jibbering.com/faq/notes/code-guidelines/#design&quot;
   &gt;code guidelines&lt;/a&gt; for &lt;a href=&quot;news://comp.lang.javascript&quot;&gt;comp.lang.javascript&lt;/a&gt;.
&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;
The current javascript library APIs do not adhere the CSS2 specification for selectors.
&lt;/p&gt;
&lt;p&gt;
Library documentation for selectors often does not differentiate between standard selectors or nonstandard extensions. 
For libraries that use the &lt;abbr title=&quot;native-first dual&quot;&gt;NFD&lt;/abbr&gt; approach, query results vary 
widely not only between browsers, but even in the same browser, depending on something as trivial as 
an unquoted attribute value.
&lt;/p&gt;
&lt;p&gt;
The native-first dual approach does not normalize browser behavior. 
Instead, amplifies the differences between browsers that have native support and those that don&#39;t. 
&lt;/p&gt;

&lt;p&gt;
Design problems are not limited to the query engines, but include other parts of the library and extend to their dependencies. 
Other such design problems seen in libraries include browser detection, fake method overloading, and useless methods 
that don&#39;t do what their name indicates. All at a cost of increased bytes and instability.
&lt;/p&gt;

&lt;p&gt;
   Any javascript developer who uses jQuery, YUI, Ext-JS, or Sencha either has not read the 
   source code enough, is not capable of understanding the problems, or has read and understood 
   the problems but has not appreciated the consequences deeply. The use one any of these libraries 
   is substantially irresponsible and uninformed decision that puts quality and long-term success of his project at risk.
&lt;/p&gt;

&lt;p&gt;
   Today&#39;s Ajax libraries are interdependent monoliths that promise what is not practically 
   possible. The problems with javascript libraries can be avoided by favoring simple interface-based 
   design that avoids browser issues. 
&lt;/p&gt;

&lt;h2&gt;References&lt;/h2&gt; 
&lt;h3 id=&quot;sel-normative&quot;&gt;Specifications and Drafts&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;CSS 2
    &lt;ul&gt;  
      &lt;li&gt;&lt;a href=&quot;http://www.w3.org/TR/2008/REC-CSS2-20080411/&quot;&gt;overview&lt;/a&gt;
      &lt;li&gt; &lt;a href=&quot;http://www.w3.org/TR/CSS2/selector.html&quot;&gt;selectors&lt;/a&gt;
      &lt;li&gt; &lt;a href=&quot;http://www.w3.org/TR/CSS21/grammar.html#scanner&quot;&gt;lexical grammar&lt;/a&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
  &lt;a href=&quot;http://www.w3.org/TR/REC-html40/&quot;&gt;HTML 4&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://whatwg.org/&quot;&gt;HTML5&lt;/a&gt;
  &lt;a href=&quot;&quot;&gt;Selectors Recommendations&lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
  &lt;a href=&quot;http://www.w3.org/TR/DOM-Level-2-HTML/html.html&quot;&gt;DOMHTML&lt;/a&gt; 
  &lt;/li&gt;
  &lt;li&gt;
[&lt;a href=&quot;http://www.w3.org/TR/selectors-api/#processing-selectors&quot;&gt;SELECT&lt;/a&gt;] 
  &lt;/li&gt;
  &lt;li&gt;
  [&lt;a href=&quot;http://dev.w3.org/2006/webapi/selectors-api-testsuite/002.html&quot;&gt;SELTEST&lt;/a&gt;]
  &lt;/li&gt;
  &lt;li&gt;
  &lt;a href=&quot;http://www.w3.org/TR/2009/WD-css3-selectors-20090310/#dynamic-pseudos&quot;&gt;SELECTORS 3&lt;/a&gt;]  
  &lt;/li&gt;
&lt;/ul&gt;
  &lt;h3&gt;Other References&lt;/h3&gt;
  &lt;ul&gt;
  &lt;li&gt;
  [&lt;a href=&quot;http://api.jquery.com/all-selector/&quot;&gt;jQuery documentation: The all selector&lt;/a&gt;] 
  &lt;/li&gt;
  &lt;li&gt;
	&lt;a href=&quot;http://api.jquery.com/category/selectors/attribute-selectors/&quot;&gt;jQuery documentation: attribute selectors&lt;/a&gt; 
  &lt;/li&gt;
  &lt;li&gt;
JQuery Issues and Discussions
&lt;ul id=&quot;references-jquery&quot;&gt;
  &lt;li&gt;[1]&lt;a href=&quot;http://forum.jquery.com/topic/attr-is-still-very-broken-in-1-4a1&quot;
         &gt;http://forum.jquery.com/topic/attr-is-still-very-broken-in-1-4a1&lt;/a&gt;
  &lt;li&gt;[2]&lt;a href=&quot;http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/d9dcd1584dddbf04/257d12eea69a1a37#msg_5c408465d003bae6&quot;
  &gt;http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/d9dcd1584dddbf04/257d12eea69a1a37#msg_5c408465d003bae6&lt;/a&gt;
  &lt;li&gt;[3]&lt;a href=&quot;http://dev.jquery.com/ticket/6139&quot;&gt;http://dev.jquery.com/ticket/6139&lt;/a&gt;
  &lt;li&gt;[4]&lt;a href=&quot;http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/c4cc46106a2ba203&quot;
  &gt;jQuery Attribute Summit--Latest Coverage&lt;/a&gt;
  &lt;li&gt;
[5] &lt;a href=&quot;http://forum.jquery.com/topic/ticket-1591-ie-table-attr-non-existent-invalid-argument-error&quot;
&gt;http://forum.jquery.com/topic/ticket-1591-ie-table-attr-non-existent-invalid-argument-error&lt;/a&gt;
&lt;li&gt;
[6] &lt;a href=&quot;http://video.google.com/videoplay?docid=-474821803269194441&quot;
&gt;http://video.google.com/videoplay?docid=-474821803269194441&lt;/a&gt;
&lt;li&gt; 
[7] &quot;&lt;a href=&quot;http://newsgroups.derkeiler.com/Archive/Comp/comp.lang.javascript/2007-11/msg00004.html&quot;
&gt;Javascript Library&lt;/a&gt;&quot;, comp.lang.javascript.
&lt;li&gt;[8]
 &quot;&lt;a href=&quot;http://groups.google.com/group/sizzlejs/browse_thread/thread/6790c8c6741453dd&quot;
&gt;Sizzle JS - Standards Edition&lt;/a&gt;&quot;, sizzlejs Google Group.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Other javascript libraries&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
[8]&lt;a href=&quot;http://developer.yahoo.com/yui/selector/&quot;&gt;http://developer.yahoo.com/yui/selector/&lt;/a&gt;
&lt;li&gt;
[9] &lt;a href=&quot;http://developer.yahoo.com/yui/examples/selector/query.htmlf&quot;
&gt;http://developer.yahoo.com/yui/examples/selector/query.html&lt;/a&gt;
&lt;li&gt;
[10] &lt;a href=&quot;http://yui.yahooapis.com/combo?3.1.1/build/dom/dom.js&quot;
&gt;http://yui.yahooapis.com/combo?3.1.1/build/dom/dom.js&lt;/a&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;ref-bugs&quot;&gt;NodeSelector Bugs&lt;/h3&gt; 
&lt;li&gt;
[11] &lt;a href=&quot;http://groups.google.vu/group/comp.lang.javascript/browse_thread/thread/7ee2e996c3fe952b/d47aaa56327b8c23&quot;
&gt;QSA - Buggy in a lot of Browsers?&lt;/a&gt;
&lt;li&gt;
[12] &lt;a href=&quot;https://bugzilla.mozilla.org/show_bug.cgi?id=495217&quot;
&gt;https://bugzilla.mozilla.org/show_bug.cgi?id=495217&lt;/a&gt;
&lt;li&gt; 
[13] &lt;a href=&quot;http://lists.w3.org/Archives/Public/public-html-bugzilla/2010May/0049.html&quot;
&gt;http://lists.w3.org/Archives/Public/public-html-bugzilla/2010May/0049.html&lt;/a&gt;
&lt;li&gt;
[14] &lt;a href=&quot;http://www.w3.org/Bugs/Public/show_bug.cgi?id=9650&quot;
&gt;http://www.w3.org/Bugs/Public/show_bug.cgi?id=9650&lt;/a&gt;
&lt;/ul&gt;
</description>
            <guid>http://dhtmlkitchen.com/news/default/2010/09/09/JavaScript-Query-Engines</guid>
			<pubDate>Thu, 9 Sep 2010 00:15:52 -0500</pubDate>
            <category>/JavaScript/</category>
                                        <wfw:comment>http://dhtmlkitchen.com/commentapi/default/JavaScript/2010/09/09/JavaScript-Query-Engines</wfw:comment>
            <wfw:commentRss>http://dhtmlkitchen.com/news/default/2010/09/09/JavaScript-Query-Engines?page=comments&amp;flavor=rss2</wfw:commentRss>
                                </item>
                        <item>
            <title>Detecting Global Pollution with the JScript RuntimeObject</title>
            <link>http://dhtmlkitchen.com/news/default/2010/04/11/Detecting-Global-Pollution-with-the-JScript-RuntimeObject</link>
            <description>&lt;p&gt;
This article is about debugging with JScript&#39;s &lt;code&gt;RuntimeObject&lt;/code&gt; 
(&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ff521039%28VS.85%29.aspx&quot; 
title=&quot;RuntimeObject: MSDN&quot;&gt;msdn&lt;/a&gt;). All of the examples work in IE 5.5+, though most do not work in any other browser. 
&lt;/p&gt;

&lt;h4&gt;Leaked Global Identifiers&lt;/h4&gt;
&lt;p&gt;
Say you accidentally created a global property, as in the following:
&lt;/p&gt;
&lt;pre&gt;
function playRugby(players) {
  var items,
      i;
      len = items.length; // Global.
}

function kick() {
  var x = 10
      y = 11; // ASI makes y global.
}
&lt;/pre&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
var runJscriptExample = function(id) {
     var pre = document.getElementById(id),
        script = document.createElement(&quot;script&quot;);
     script.text = pre.innerHTML;
     script.defer = true;
     pre.parentNode.appendChild(script);
   };
&lt;/script&gt;

When &lt;code&gt;playRugby&lt;/code&gt; is called, a global property &lt;code&gt;len&lt;/code&gt; is created, if it does not already exist,
and then assigned the value of &lt;code&gt;items.length&lt;/code&gt;. Likewise, when &lt;code&gt;kick&lt;/code&gt; is called, a global 
property &lt;code&gt;y&lt;/code&gt; is created. 
&lt;p&gt;
These globals are unintentional. They break encapsulation and leak implementation details.
This can result in conflict and awkward dependency issues.
&lt;/p&gt;

&lt;p&gt;
To detect accidentally created global identifiers, we can loop over the global object using 
&lt;code&gt;for in&lt;/code&gt;. &lt;a href=&quot;http://getfirebug.com/&quot;&gt;Firebug&lt;/a&gt; provides this convenient global inspection under the &quot;DOM&quot; tab.
&lt;/p&gt;

&lt;h4&gt;Everybody&#39;s Favorite Browser&lt;/h4&gt;
&lt;p&gt;
Unfortunately, in IE, the &lt;code&gt;for in&lt;/code&gt; won&#39;t enumerate any global variables or function declarations, 
as seen in the example below.
&lt;/p&gt;

&lt;h4&gt;Example Enumerating the Global Object&lt;/h4&gt;
&lt;pre id=&quot;runtimeObject1&quot;&gt;
// Property of global variable object.
var EX1_GLOBAL_VARIABLE = 10;

// Property of global object.
this.EX1_GLOBAL_PROPERTY = 11;

// Property of global variable object.
function EX1_GLOBAL_FUNCTION(){}

(function(){
  var results = [];
  for(var p in this) {
    results.push(p);
  }
  alert(&quot;Leaked:\n&quot; + results.join(&quot;\n&quot;));
})();
&lt;/pre&gt;&lt;button onclick=&quot;runJscriptExample(&#39;runtimeObject1&#39;)&quot;&gt;run code&lt;/button&gt;

&lt;p&gt;
The result in IE contains a mix of window properties and one the four user-defined properties:
&lt;code&gt;EX1_GLOBAL_PROPERTY&lt;/code&gt;. 
&lt;/p&gt;

&lt;p&gt;
So what happened to the other three user-defined properties? Why didn&#39;t they show up in the &lt;code&gt;for in&lt;/code&gt; loop?
&lt;/p&gt;

&lt;p&gt;
It turns out that enumerating over 
the global object will enumerate properties 
assigned to the global object and will not enumerate global variables. 
&lt;/p&gt;
&lt;p&gt;
An educated guess as to why global properties are enumerated but global variables are not might be that JScript gives global variables (declared with &lt;code&gt;var&lt;/code&gt;), the &lt;code&gt;DontEnum&lt;/code&gt; flag. Since the global object is specified as being the global Variable object, this seems like a likely explanation. It would be nonstandard, but it would explain the behavior in IE. &lt;del&gt; Eric Lippert, however, provided a different explanation: The global object and the global variable object are 
&lt;a href=&quot;http://blogs.msdn.com/ericlippert/archive/2005/05/04/414684.aspx&quot;
&gt;two different objects in IE&lt;/a&gt;.
&lt;/del&gt;
&lt;/p&gt;
&lt;p&gt;According to MS-ES3:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
JScript 5.x variable instantiations creates properties of the global object that have the
DontEnum attribute.
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;Enumeration Solution: The JScript RuntimeObject&lt;/h4&gt;
&lt;p&gt;
To enumerate over global properties, use the JScript &lt;code&gt;RuntimeObject&lt;/code&gt; method.
Instead of enumerating over the global object, as you would use in a normal implementation, 
enumerate over an object returned by the global &lt;code&gt;RuntimeObject&lt;/code&gt; method.
&lt;/p&gt;

&lt;pre id=&quot;runtimeObject3&quot;&gt;
var GLOBAL_VAR1, 
    GLOBAL_VAR2, 
    GLOBAL_VAR3 = 1; 
    GLOBAL_PROP1 = 12;

function GLOBAL_FUNCTION(){}

if(this.RuntimeObject){
    void function() {
        var ro = RuntimeObject(),
            results = [],
            prop;
        for(prop in ro) {
            results.push(prop);
        }
        alert(&quot;leaked:\n&quot; + results.join(&quot;\n&quot;));
    }();
}
&lt;/pre
&gt;&lt;button onclick=&quot;runJscriptExample(&#39;runtimeObject3&#39;)&quot;&gt;run code&lt;/button&gt;

&lt;h5&gt;IE Result&lt;/h5&gt;
&lt;p&gt;
The result in IE 8 and below includes (among other things, including &lt;code&gt;window&lt;/code&gt;) &lt;code&gt;GLOBAL_FUNCTION&lt;/code&gt;, &lt;code&gt;GLOBAL_VAR3&lt;/code&gt;, 
and &lt;code&gt;GLOBAL_PROP1&lt;/code&gt;, in that order, as they were evaluated in. 
Notice that neither &lt;code&gt;GLOBAL_VAR1&lt;/code&gt; nor &lt;code&gt;GLOBAL_VAR2&lt;/code&gt; were included. 
It appears that &lt;code&gt;RuntimeObject&lt;/code&gt; does not accumulate any variables that were 
unassigned to. According to Microsoft&#39;s documentation, this is not the specified behavior  
(more on this below).
&lt;/p&gt;

&lt;h4&gt;Microsoft RuntimeObject Documentation&lt;/h4&gt;

&lt;p&gt;
The JScript &lt;code&gt;RuntimeObject&lt;/code&gt; is a built-in extension to JScript. JScript 
defines seven additional built-in global methods: &lt;code&gt;ScriptEngine&lt;/code&gt;, 
&lt;code&gt;ScriptEngineBuildVersion&lt;/code&gt;, &lt;code&gt;ScriptEngineMajorVersion&lt;/code&gt;, 
&lt;code&gt;ScriptEngineMinorVersion&lt;/code&gt;, &lt;code&gt;CollectGarbage&lt;/code&gt;, 
&lt;code&gt;RuntimeObject&lt;/code&gt;, and &lt;code&gt;GetObject&lt;/code&gt;. These objects are 
all native JScript objects, not to be confused with 
&lt;a href=&quot;http://jibbering.com/faq/#hostObject&quot;&gt;host objects&lt;/a&gt;. 
&lt;/p&gt;

&lt;p&gt;
    For &lt;code&gt;RuntimeObject&lt;/code&gt;, Microsoft JScript Extensions [&lt;a href=&quot;#RuntimeObject-references&quot;&gt;MS-ES3EX&lt;/a&gt;] states:
&lt;/p&gt;

&lt;blockquote cite=&quot;http://msdn.microsoft.com/en-us/library/ff521046%28VS.85%29.aspx&quot;&gt;
 The &lt;code&gt;RuntimeObject&lt;/code&gt; function is used to search a global object for 
 properties with names that match a specified pattern. The function 
 only locates properties of the global object that were explicitly 
 created by &lt;code&gt;VariableStatement&lt;/code&gt; or &lt;code&gt;FunctionDeclaration&lt;/code&gt; 
 functions, or that were implicitly created by appearing as an identifier 
 on the left side of an assignment operator. The function does not locate 
 properties that were created by means of explicit property access on the global 
 object.
&lt;/blockquote&gt;

&lt;p&gt;
Superficial testing indicates that Microsoft&#39;s documentation is wrong. 
&lt;/p&gt;

&lt;p&gt;
The returned object does &lt;em&gt;not&lt;/em&gt; includes all identifiers that were added to the Variable object;
only those identifiers that have been assigned a value. Whether or not they were created from 
&lt;code&gt;VariableDeclaration&lt;/code&gt;, &lt;code&gt;FunctionDeclaration&lt;/code&gt;, or assignment as global properties 
does not matter. 
&lt;/p&gt;

&lt;h5&gt;Example of Finding Identifiers Created By FunctionBindingList&lt;/h5&gt;
&lt;p&gt;
All identifiers in a &lt;code&gt;FunctionBindingList&lt;/code&gt; of a &lt;code&gt;JScriptFunction&lt;/code&gt; 
will become properties of the containing Variable object, so, for example:
&lt;/p&gt;

&lt;pre id=&#39;runtimeObject2&#39;&gt;
var foo = {}, undef, ro;
(function(){ function foo.bar, baz(){} })();
ro = RuntimeObject();
alert([ro.foo.bar, &quot;undef&quot; in ro].join(&quot;\n&quot;));
&lt;/pre
&gt;&lt;button id=&quot;example2&quot; onclick=&quot;runJscriptExample(&#39;runtimeObject2&#39;)&quot;&gt;run code&lt;/button&gt;

IE elerts 
&lt;pre&gt;
function foo.bar(){}
false
&lt;/pre&gt;

&lt;p&gt;
Browsers other than IE running JScript can be expected to throw 
&lt;code&gt;SyntaxError&lt;/code&gt; upon parsing the &lt;code&gt;FunctionBindingList&lt;/code&gt; of 
&lt;code&gt;JScriptFunction&lt;/code&gt; production. This is to be expected, as 
it is a syntax extension.
&lt;/p&gt;

&lt;h4&gt;Bookmarklet&lt;/h4&gt;
As a bookmarklet:
&lt;pre&gt;
javascript:(function() {var ro=RuntimeObject(),r=[],i=0,p;for(p in ro){r[i++]=p;}alert(&#39;leaked:\n&#39;+r.join(&#39;\n&#39;));})();
&lt;/pre&gt; 

&lt;h5&gt;JScript Syntax Extension&lt;/h5&gt;
&lt;p&gt;
The earlier example &quot;Finding Identifiers Created By FunctionBindingList&quot; mentioned 
the JScript Extension &lt;code&gt;JScriptFunction&lt;/code&gt;. In case the name is not a dead 
giveaway, this is a JScript language extension. The production for &lt;code&gt;JScriptFunction&lt;/code&gt; is:
&lt;/p&gt;
&lt;pre&gt;
JScriptFunction : 
function FunctionBindingList ( FormalParameterListopt ) { FunctionBody }
&lt;/pre&gt;

&lt;h5&gt;RuntimeObject(filterString): The filterString Parameter&lt;/h5&gt;
&lt;p&gt;
  The &lt;code&gt;RuntimeObject&lt;/code&gt; method accepts an optional filter string to match 
  identifiers. Unfortunately, &lt;var&gt;filterString&lt;/var&gt; is &lt;em&gt;not&lt;/em&gt; converted to a regular expression
  but is used for substring matching with optional &lt;var&gt;leftWild&lt;/var&gt; and &lt;var&gt;rightWild&lt;/var&gt;, defaulting to &lt;code&gt;*&lt;/code&gt;. 
&lt;/p&gt;

&lt;p&gt;
This means that, for example: &lt;code&gt;filterString = &quot;a*&quot;&lt;/code&gt; would match 
identifiers &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;a1&lt;/code&gt; but not &lt;code&gt;ba&lt;/code&gt;. 
&lt;/p&gt;

&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;
Documentation bugs and shortcomings aside, the &lt;code&gt;RuntimeObject&lt;/code&gt; 
provides a useful alternative to the problem 
of enumerating global properties in JScript. An advantage with 
&lt;code&gt;RuntimeObject&lt;/code&gt; is that it only includes user-defined 
properties, with the exception of the global &lt;code&gt;window&lt;/code&gt; property.
&lt;/p&gt;

&lt;p&gt;
The aforementioned &lt;a title=&quot;RuntimeObject Bookmarklet&quot;
href=&quot;javascript:(function() {var ro=RuntimeObject(),r=[],i=0,p;for(p in ro){r[i++]=p;}alert(&#39;leaked:\n&#39;+r.join(&#39;\n&#39;));})();&quot;
&gt;bookmarklet&lt;/a&gt; provides a convenient way to check a page 
to see the globals that have been accidentally created (it also shows that this 
site is not a shining example of keeping the global object clean).
&lt;/p&gt;

&lt;h4&gt;Other Applications for RuntimeObject&lt;/h4&gt;
&lt;h5&gt;Cross Browser Identifier Leak Bookmarklet&lt;/h5&gt;
&lt;p&gt;
    Writing a cross-browser 
    &lt;a href=&quot;http://perfectionkills.com/detecting-global-variable-leaks/&quot;&gt;identifier leak detector&lt;/a&gt; 
    is the next logical step to an IE-only identifier leak detector. 
&lt;/p&gt;

&lt;h5&gt;Automated Identifier Leak Detection&lt;/h5&gt;
&lt;p&gt;
  Checking for accidental global identifiers should be automated. 
&lt;/p&gt;
&lt;p&gt;
  The &lt;a href=&quot;http://developer.yahoo.com/yui/yuitest/&quot;
  &gt;YUI Test&lt;/a&gt; unit test framework provides hooks for &lt;code&gt;TEST_CASE_BEGIN_EVENT&lt;/code&gt; 
  and &lt;code&gt;TEST_CASE_COMPLETE_EVENT&lt;/code&gt; . These events can be used to 
  inspect the &lt;code&gt;RuntimeObject&lt;/code&gt; and catch global identifier leaks
  that occur througout the runtime execution of program code.
&lt;/p&gt;

&lt;p&gt;  
  In &lt;code&gt;TEST_CASE_BEGIN_EVENT&lt;/code&gt;, inspect the &lt;code&gt;RuntimeObject&lt;/code&gt; and save the result. 
  In &lt;code&gt;TEST_CASE_COMPLETE_EVENT&lt;/code&gt;, inspect the &lt;code&gt;RuntimeObject&lt;/code&gt; again and compare 
  the results with results saved during &lt;code&gt;TEST_CASE_BEGIN_EVENT&lt;/code&gt;. 
  Next, for each property that appeared in &lt;code&gt;TEST_CASE_COMPLETE_EVENT&lt;/code&gt; but was not present 
  in the result saved from &lt;code&gt;TEST_CASE_BEGIN_EVENT&lt;/code&gt; , a global identifier has been 
  leaked and a test case warning can be logged.
&lt;/p&gt;

&lt;h4 id=&quot;RuntimeObject-references&quot;&gt;References&lt;/h4&gt;
&lt;ul&gt;
    &lt;li&gt;
        [&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ff521046%28VS.85%29.aspx&quot;
        &gt;MS-ES3EX&lt;/a&gt;]: Microsoft JScript Extensions to the ECMAScript Language Specification Third Edition.
    &lt;/li&gt;
&lt;/ul&gt;
</description>
            <guid>http://dhtmlkitchen.com/news/default/2010/04/11/Detecting-Global-Pollution-with-the-JScript-RuntimeObject</guid>
			<pubDate>Sun, 11 Apr 2010 16:23:36 -0500</pubDate>
            <category>/Browsers/</category>
                                </item>
                        <item>
            <title>Ebay Facilitates Fraud</title>
            <link>http://dhtmlkitchen.com/news/default/2010/03/18/Ebay-Facilitates-Fraud</link>
            <description>&lt;p&gt;
Won an auction of eBay for:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
&lt;strong&gt;
&quot;You Won eBay Item:DELL E1705 INTEL DUO 2 GHZ, WINDOWS VISTA ULTIMATE (290295125189)&quot;
&lt;/strong&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
I got that laptop nearly two weeks after I paid for it. 
&lt;/p&gt;

&lt;p&gt;
Shortly thereafter, I got it in to a local tech who, after about four days, informed me that the copy of windows that was installed was unlicensed. 
&lt;/p&gt;

&lt;p&gt;
It turns out MS Office, which was also advertised as being included in the auction, is also pirated.
&lt;/p&gt;

&lt;h3&gt;Paypal Claim&lt;/h3&gt;
&lt;p&gt;
I immediately filed a complaint with the payment system, &lt;a href=&quot;http://paypal.com/?paypal-enables-fraud&quot;&gt;Paypal&lt;/a&gt; &quot;Item significantly not as described&quot;. 
The claim was requesting the seller to provide a license key for Windows. 
&lt;/p&gt;

&lt;p&gt;
The seller could not provide a license key for windows because he does not have one. He decided to make the 
irrelevant excuse &quot;I lost the CD&quot; to paypal, and somehow, that worked.
&lt;/p&gt;
&lt;p&gt;
On March 20, 2009, I receieved the email from paypal stating:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
We will notify you if further action is required.
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
  I called paypal and the representative said I would receive contact from paypal by April 17 (IIRC), 
 however that never happened and Payapl closed the claim on May 24, 2009, notifying me with the following:
&lt;/p&gt;
&lt;h4&gt;Paypal Case Details&lt;/h4&gt;
&lt;blockquote&gt;
&lt;pre&gt;
We have concluded our investigation into this case. Unfortunately, 
at this time we are unable to decide this claim in your favor.

-----------------------------------
Case Details
-----------------------------------


&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;
As you can see, there are no &quot;case details&quot; there; the entire section is completely blank. 
&lt;/p&gt;

&lt;p&gt;
As soon as I received this, I called Paypal to ask why the case had been closed. The Paypal representative could not provide a reason, 
nor could he state what, if anything, paypal had done. He reopened the case and stated that a Paypal representative would contact me. 
&lt;/p&gt;

&lt;p&gt;
Paypal did not contact me, but instead closed the case again. 
&lt;/p&gt;

&lt;p&gt;
I went through the process of calling Paypal again, waiting on hold for a long time, and again talking to a rep. 
The case was reopened, and then once again re-closed, 
without any evidence that paypal 
had actually done anything to investigate the claim.
&lt;/p&gt;

&lt;p&gt;
I have saved all of the email communications with Paypal. The responses from Paypal indicate that the paypal representatives 
failed to read my messages and failed to read the auction title which was included in the message. 
&lt;/p&gt;

&lt;p&gt;
Paypal has provided no evidence to having done anything to investigate my claim. 
&lt;/p&gt;

&lt;h3&gt;Back to Ebay&lt;/h3&gt;
&lt;p&gt;
After Paypal failed, I called ebay. I made many calls to ebay, each time having to restate everything from the beginning. 
I received follow-up email from &lt;a href=&quot;mailto:rswebhelp@ebay.com&quot;&gt;rswebhelp@ebay.com&lt;/a&gt; stating that I should contact the police, file a complaint with 
&lt;a href=&quot;http://www.ic3.gov&quot;&gt;IC3&lt;/a&gt;, and file a &lt;a href=&quot;https://postalinspectors.uspis.gov/forms/MailFraudComplaint.aspx&quot;
&gt;mail fraud complaint with USPS&lt;/a&gt;.
&lt;/p&gt;

&lt;h4&gt;Ebay Action&lt;/h4&gt;
&lt;p&gt;
Like paypal, Ebay ignored many, if not most of my emails. Of the emails that I received a reply to, the responses do not include answers to the 
questions. They are a top-reply of mostly irrelevant parroting of what appears to be copy&#39;n&#39;pasted information on how to call the police, 
file a claim with the post office, or contact IC3. I have done all of those things. 
&lt;/p&gt;

&lt;p&gt;
Ebay stated that they work closely with the police. I provided rswebhelp with the police report number and requested for them to call the 
police but the request was ignored. What ebay says and what ebay does do not match.
&lt;/p&gt;

&lt;p&gt;
The San Francisco Police officer I reported to told me that the case would be only paperwork for them. He would not even look at the URL. I
cannot force them to change how they operate. 
&lt;/p&gt;

&lt;h4&gt;The Seller&lt;/h4&gt;
&lt;p&gt;
I followed up with Dave Kaercher by sending email and by calling. The phone message I left was not replied to and the email (all emails I have sent him) was ignored. I did get through a week later and told Dave the problem and that I was seeking a refund of money I paid. Dave said &quot;we don&#39;t have a deal&quot; and that was the end of the conversation.
&lt;/p&gt;

&lt;p&gt;
The computer has not provided me with the use that could be expected out of a computer with legal, licensed versions of Windows Office. 
&lt;/p&gt;

&lt;p&gt;
Instead of using Windows, I have been hobbling with a cracked OS for 1 year. The OS frequently restarts (in failed attempts to run important security updates).
&lt;/p&gt;

&lt;p&gt;
Instead of the expected use of Microsoft Office, Launching Office errs with: &quot;
&lt;/p&gt;
&lt;div&gt;
&lt;blockquote&gt;
&lt;p&gt;
  Microsoft Office Genuine Advantage
&lt;/p&gt;

&lt;pre&gt;
  [logo] This copy of Microsoft Office is not genuine.
  Please excuse this interruption. This copy of Office did not 
  pass validation. Click Learn More for online details and help 
  identifying the best way to get genuine Microsoft Office.
              [&lt;a 
  href=&quot;http://www.microsoft.com/genuine/office/nonGenuine.aspx?displaylang=en&amp;amp;Nav=hta&amp;amp;cCode=USA&amp;amp;Error=103&amp;amp;PartnerID=400&amp;amp;sGuid=56531d66-099d-4d9b-b03c-815051efe7e9&quot;
  &gt;Learn More&lt;/a&gt;] [Remind Me Later]
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;
Clicking &quot;Learn More&quot; leads the web page:
&lt;a href=&quot;http://www.microsoft.com/genuine/office/nonGenuine.aspx?displaylang=en&amp;amp;Nav=hta&amp;amp;cCode=USA&amp;amp;Error=103&amp;amp;PartnerID=400&amp;amp;sGuid=56531d66-099d-4d9b-b03c-815051efe7e9&quot;&gt;Genuine Microsoft Software&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
I have actively pursued this for over a year, with several emails and calls to ebay, paypal, and Dave Kaercher. I am posting the seller&#39;s personal information on my site.
&lt;/p&gt;

&lt;h3&gt;Dave Kaercher&lt;/h3&gt;
&lt;p&gt;
Dave Kaercher: I told you I would do this. I clearly requested licensed copies of what I paid for. I stated this in emails to you and in the paypal claim. You made excuses and ignored those. 
&lt;/p&gt;

&lt;p&gt;
I told you two weeks ago by email (which you ignored) and by phone call two weeks ago that I would post your information on my site.
&lt;/p&gt;
&lt;h4&gt;Dave Kaercher&#39;s Personal Info&lt;/h4&gt;
&lt;address style=&quot;white-space:pre&quot;&gt;
Dave Kaercher GRI, QSC
User ID:               redbirds04
Name:                  Dave Kaercher
website:               &lt;a href=&quot;http://wesellmore.com/&quot;&gt;wesellmore.com&lt;/a&gt;
City:                  Colorado Springs
State:                 CO
Country:               United States
Phone:                 (719) 282-1681
&lt;/address&gt;
&lt;h3&gt;Lesson Learned&lt;/h3&gt;
&lt;p&gt;
Don&#39;t buy things off eBay!
&lt;/p&gt;

&lt;p&gt;
EBay knowingly facilitates fraud. EBay makes money by helping criminals defraud consumers and as such, is guilty of fraud. 
&lt;/p&gt;
&lt;p&gt;
Dave Kaercher is in good standing with ebay, probably defrauding other victims. He continues to promote auctions for various things including fake steroids over the past year. It is clear that eBay does not care to take this seriously.
&lt;/p&gt;

&lt;p&gt;
Anyone shopping for items should consider that what is sold on ebay 
might be illegitimate (pirated, counterfeit, etc). In the case that the item is illegitimate, 
ebay probably won&#39;t do anything about it.
&lt;/p&gt;
</description>
            <guid>http://dhtmlkitchen.com/news/default/2010/03/18/Ebay-Facilitates-Fraud</guid>
			<pubDate>Thu, 18 Mar 2010 11:00:14 -0500</pubDate>
            <category>/uncategorized/</category>
                                </item>
                        <item>
            <title>Myopia and the Opera 10 User Agent String</title>
            <link>http://dhtmlkitchen.com/news/default/2009/05/29/Myopia-and-the-Opera-10-User-Agent-String</link>
            <description>&lt;p&gt;
Opera has conceived a &lt;a href=&quot;http://dev.opera.com/articles/view/opera-ua-string-changes/&quot;&gt;silly tactic&lt;/a&gt; planned for Opera 10 user-agent string.          
&lt;/p&gt;

&lt;p&gt;The problem is that there are scripts that expect the browser major version to single-digit and will fail if it is not.
&lt;/p&gt;

&lt;p&gt;
 Since &quot;10&quot; not a single digit, these scripts fail.
&lt;/p&gt;

&lt;p&gt;Opera has mitigated that problem by changing the user-agent to 9.80 and publishing the following warning:
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;
Browser sniffing — unless you’re writing a web stats application — is 
 always a bad idea. It’s a misguided attempt to send different content  
 to different user agents. This is never scalable — you can’t change 
 every website you’ve ever made every time a new browser version comes 
 out. It is also not future-proof, as highlighted by this article.
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
Ineffectual and meaningless little blurb there. Those badly written sites that used (poor) browser detection will not break from Opera. Opera spoofing their own user-agent string helps reaffirm the misconception that the authors&#39; browser detection worked. Posting up a little warning that not everyone will read does not make an example. 
&lt;/p&gt;

&lt;p&gt;
The blurb states that Browser detection is used &quot;to send different content to different user agents&quot;. Not always true. In fact, browser detection is more often used on the client to work around an perceived incompatibility. Since Opera is wrong on that count, it makes the blurb seem even less relevant, as an author who read it might still try to justify or rationalize his approach by saying &quot;but that&#39;s not why I used browser detection.&quot;
&lt;/p&gt;

&lt;p&gt;
Browser detection scripts cause forwards-compatibility and maintenance problems. However, to not be able to parse out a number is not only not smart, it shows very poor coding skill. 
&lt;/p&gt;
&lt;p&gt;
Opera states that version 11 will have &quot;11&quot; in the user-agent string.
&lt;/p&gt;

&lt;p&gt;
My opinion is somewhat in line with &lt;a href=&quot;http://blog.360.yahoo.com/blog-TBPekxc1dLNy5DOloPfzVvFIVOWMB0li?p=1008
&quot;&gt;Doug&#39;s&lt;/a&gt; on this one (&lt;small&gt;that Yahoo 360 URL is an awful URL&lt;/small&gt;). 
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
 If you are a developer, check your code. It really isn&#39;t 
  hard to do this stuff correctly. It really isn&#39;t. 
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
 Where I disagree with Doug is &lt;cite&gt;&quot;Opera has been forced to lie.&quot;&lt;/cite&gt;
&lt;/p&gt;
&lt;p&gt;
 Opera developers made a &lt;em&gt;decision&lt;/em&gt; to lie, as explained by Opera. They were not forced. 
&lt;/p&gt;
&lt;p&gt;
 An alternative to that choice is for Opera to not cater to badly authored pages and simply let them break.
&lt;/p&gt;
&lt;p&gt;
Breaking sites is bad in the short term because it renders pages unusable. However, it is good in the larger scheme of the web in the long run. By driving home a hard lesson, Opera could teach developers to not use browser detection by providing an historical lesson.
&lt;/p&gt;

&lt;p&gt;
  The first sensible opinion on the matter was &lt;a href=&quot;http://my.opera.com/hallvors/blog/2008/12/19/10-is-the-one&quot;&gt;Hallvord&#39;s post from December, 2008.&lt;/a&gt;, where he pointed out that Bank of America and Live.com failed in Opera 10. The entry describes the reason: Faulty parsing of the &lt;code&gt;User-Agent&lt;/code&gt; string, and redirecting to the &quot;not supported page&quot;. 
&lt;/p&gt;
&lt;blockquote cite=&quot;http://my.opera.com/hallvors/blog/2008/12/19/10-is-the-one&quot;&gt;
&lt;p&gt;
You&#39;d think that with the intense development Microsoft has been lavishing on live.com they would have found somebody capable of writing a usable browser sniffer (or ideally a person clever enough to say &quot;wait, we don&#39;t really need one - what if we just use feature detection instead?&quot;). Think again..
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
 Of course, Microsoft has been advocating detection &quot;best practices&quot; for years, despite well reasoned arguments to stop doing that (&lt;a href=&quot;http://blogs.msdn.com/ie/archive/2009/01/09/the-internet-explorer-8-user-agent-string-updated-edition.aspx#9305124&quot;&gt;G. Talbot&lt;/a&gt;, &lt;a href=&quot;http://blogs.msdn.com/ie/archive/2009/01/09/the-internet-explorer-8-user-agent-string-updated-edition.aspx#9305799&quot;&gt;T. Zijdel&lt;/a&gt;).
&lt;/p&gt;

&lt;p&gt;
 Opera should be less myopic and stop worrying about breaking badly authored sites. Web developers should be less myopic, and build maintainable, forwards-compatible solutions. 
&lt;/p&gt;
</description>
            <guid>http://dhtmlkitchen.com/news/default/2009/05/29/Myopia-and-the-Opera-10-User-Agent-String</guid>
			<pubDate>Fri, 29 May 2009 00:06:00 -0500</pubDate>
            <category>/Browsers/</category>
                                </item>
                        <item>
            <title>Function.prototype.bind</title>
            <link>http://dhtmlkitchen.com/news/default/2008/09/11/Function-prototype-bind</link>
            <description>&lt;h3&gt;Function Binding&lt;/h3&gt;
&lt;p&gt;
	A &lt;dfn&gt;bind&lt;/dfn&gt; function wraps a function in a closure, 
	storing a reference 
	to the &lt;dfn&gt;context&lt;/dfn&gt; argument in the containing scope.
&lt;/p&gt;
&lt;p&gt;
    This allows the &lt;dfn&gt;bound&lt;/dfn&gt; function to run
    with a predetermined &lt;dfn&gt;context&lt;/dfn&gt;.
&lt;/p&gt;

&lt;h3&gt;Variable &lt;code&gt;this&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;
  When a function is passed as a reference, it loses its 
  base object. When the &lt;dfn&gt;unbound&lt;/dfn&gt; function is called, 
  the &lt;code&gt;this&lt;/code&gt; value is the global object.
&lt;/p&gt;

&lt;h3&gt;How Binding Works&lt;/h3&gt;
&lt;p&gt;
  By storing a reference to the desired object in a closure, 
  &lt;code&gt;this&lt;/code&gt; argument can be &lt;dfn&gt;bound&lt;/dfn&gt;. 
&lt;/p&gt;

&lt;p&gt;
	In it&#39;s simplest form, &lt;code&gt;bind&lt;/code&gt; looks like:-
&lt;/p&gt;

&lt;pre&gt;
Function.prototype.bind = &lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt;(&lt;var&gt;context&lt;/var&gt;) {
  &lt;span class=&#39;keyword&#39;&gt;var&lt;/span&gt; &lt;var&gt;fun&lt;/var&gt; = this;
  &lt;span class=&#39;keyword&#39;&gt;return&lt;/span&gt; &lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt;(){
    &lt;span class=&#39;keyword&#39;&gt;return&lt;/span&gt; &lt;var&gt;fun&lt;/var&gt;.apply(&lt;var&gt;context&lt;/var&gt;, arguments);
  };
};
&lt;/pre&gt;

&lt;h3&gt;Why Binding is Useful&lt;/h3&gt;
&lt;p&gt;
	Binding is often necessary when passing function references.
    For example:-
&lt;/p&gt;


&lt;pre&gt;
&lt;span class=&#39;keyword&#39;&gt;var&lt;/span&gt; &lt;var&gt;updater&lt;/var&gt; = {
  fetch : &lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt;() {
    alert(this.time++);
  },
  time : 0
};
&lt;span class=&#39;comment&#39;&gt;// setTimeout(&lt;var&gt;updater&lt;/var&gt;.fetch, 500);&lt;/span&gt;
setTimeout(&lt;var&gt;updater&lt;/var&gt;.fetch.bind(&lt;var&gt;updater&lt;/var&gt;), 500);
&lt;/pre&gt;

&lt;p&gt;
  The commented-out call to &lt;code&gt;setTimeout&lt;/code&gt; would result in a 
  call to 
  &lt;code&gt;updater.fetch&lt;/code&gt; with the &lt;code&gt;global&lt;/code&gt; object 
  for the &lt;code&gt;this&lt;/code&gt; argument. &lt;code&gt;this.time&lt;/code&gt; would 
  be undefined, and &lt;code&gt;this.time++&lt;/code&gt; would result in 
  &lt;code&gt;NaN&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
  A &lt;dfn&gt;bind&lt;/dfn&gt; function that does &lt;em&gt;only&lt;/em&gt; binding
  accomplishes a trivial task.
  In most cases, a closure can just be used where binding is needed. 
&lt;/p&gt;

&lt;h3&gt;Binding in the Wild&lt;/h3&gt;
&lt;p&gt;
  Most JavaScript libraries handle binding internally. 
  These libraries also include a &lt;dfn&gt;partial apply&lt;/dfn&gt; for 
  their &lt;dfn&gt;bind&lt;/dfn&gt; function. 
&lt;/p&gt;

&lt;h3&gt;Partial Apply&lt;/h3&gt;
&lt;p&gt;
  &lt;dfn&gt;Partial application&lt;/dfn&gt; is setting parameter values of 
  a function call before it is called. 
  A &lt;dfn&gt;partial apply&lt;/dfn&gt; function usually looks like:-
&lt;/p&gt;

&lt;pre&gt;
&lt;span class=&quot;comment&quot;&gt;/** 
 * Return a function that prepends the 
 * arguments to partial to this call and 
 * appends any additional arguments.
 */&lt;/span&gt;
Function.prototype.partial = &lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt;() {
  &lt;span class=&#39;keyword&#39;&gt;var&lt;/span&gt; &lt;var&gt;fun&lt;/var&gt; = &lt;span class=&#39;keyword&#39;&gt;this&lt;/span&gt;,
      &lt;var&gt;preArgs&lt;/var&gt; = Array.prototype.slice.call(arguments);
  &lt;span class=&#39;keyword&#39;&gt;return&lt;/span&gt; &lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt;() {
    &lt;var&gt;fun&lt;/var&gt;.apply(&lt;span class=&#39;keyword&#39;&gt;null&lt;/span&gt;, &lt;var&gt;preArgs&lt;/var&gt;.concat.apply(&lt;var&gt;preArgs&lt;/var&gt;, arguments));
  };
};
&lt;/pre&gt;
&lt;p&gt;
  This allows us to program in a dynamic, functional, 
  less OO way. For example:
&lt;/p&gt;

&lt;pre&gt;
&lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt; setStyle(&lt;var&gt;style&lt;/var&gt;, &lt;var&gt;prop&lt;/var&gt;, &lt;var&gt;value&lt;/var&gt;) {
  &lt;span class=&#39;keyword&#39;&gt;return&lt;/span&gt; &lt;var&gt;style&lt;/var&gt;[&lt;var&gt;prop&lt;/var&gt;] = &lt;var&gt;value&lt;/var&gt;;
}

&lt;span class=&quot;comment&quot;&gt;// Create a setBgColor function from 
// partial application of setStyle.&lt;/span&gt;
&lt;span class=&#39;keyword&#39;&gt;var&lt;/span&gt; &lt;var&gt;setBgColor&lt;/var&gt; = setStyle.partial(document.body.style, &quot;background&quot;);

&lt;span class=&quot;comment&quot;&gt;// Change the body&#39;s background color.&lt;/span&gt;
&lt;var&gt;setBgColor&lt;/var&gt;(&lt;span class=&#39;q&#39;&gt;&quot;red&quot;&lt;/span&gt;);
&lt;var&gt;setBgColor&lt;/var&gt;(&lt;span class=&#39;q&#39;&gt;&quot;#0f0&quot;&lt;/span&gt;);
&lt;/pre&gt;

&lt;h4&gt;Disadvantage&lt;/h4&gt;
&lt;p&gt;
  &lt;dfn&gt;Partial application&lt;/dfn&gt; requires an extra function call, 
  plus a call to &lt;em&gt;&lt;code&gt;concat&lt;/code&gt;&lt;/em&gt;
  for the extra arguments.
&lt;/p&gt;
&lt;p&gt;
  Partial application can make debugging trickier, since there is an 
  extra layer of indirection to the real method. 
&lt;/p&gt;
&lt;p&gt;
  &lt;dfn&gt;Bind&lt;/dfn&gt; + &lt;dfn&gt;partial apply&lt;/dfn&gt; can be used to force the 
  &lt;code&gt;this&lt;/code&gt; argument of a prototype method to 
  always be the of the instance. 
  This is inefficient and often leads to messy, 
  tangled function decomposition. Libraries that bind every method 
  do so out of ignorance of the language, and are best avoided.
&lt;/p&gt;

&lt;h3&gt;EcmaScript New Language Feature&lt;/h3&gt;
&lt;p&gt;
  The forthcoming version of EcmaScript (now called EcmaScript Harmony) 
  will include 
  &lt;code&gt;Function.prototype.bind(&lt;var&gt;context&lt;/var&gt;)&lt;/code&gt;. A native
  &lt;dfn&gt;bind&lt;/dfn&gt; should outperform any other &lt;dfn&gt;bind&lt;/dfn&gt; function.
&lt;/p&gt;
&lt;p&gt;
  This was something &lt;a href=&quot;http://peter.michaux.ca/&quot;&gt;Peter&lt;/a&gt; brought 
  up for EcmaScript 4, but appears to be making way into the revised 
  EcmaScript Harmony.
&lt;/p&gt;
&lt;p&gt;
  &lt;a href=&quot;http://www.erights.org/&quot;&gt;Mark Miller&lt;/a&gt; wrote out a &quot;self-hosted&quot; version of 
  EcmaScript&#39;s proposed &lt;code&gt;Function.prototype.bind&lt;/code&gt;.
  It is:-
&lt;/p&gt;

&lt;pre&gt;
Function.prototype.bind = &lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt;(&lt;var&gt;self&lt;/var&gt;, &lt;var&gt;var_args&lt;/var&gt;) {
   &lt;span class=&#39;keyword&#39;&gt;var&lt;/span&gt; &lt;var&gt;thisFunc&lt;/var&gt; = &lt;span class=&#39;keyword&#39;&gt;this&lt;/span&gt;;
   &lt;span class=&#39;keyword&#39;&gt;var&lt;/span&gt; &lt;var&gt;leftArgs&lt;/var&gt; = Array.slice(arguments, 1);
  &lt;span class=&#39;keyword&#39;&gt;return&lt;/span&gt; &lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt;(&lt;var&gt;var_args&lt;/var&gt;) {
    &lt;span class=&#39;keyword&#39;&gt;var &lt;/span&gt;args = &lt;var&gt;leftArgs&lt;/var&gt;.concat(Array.slice(arguments, 0));
    &lt;span class=&#39;keyword&#39;&gt;return&lt;/span&gt; &lt;var&gt;thisFunc&lt;/var&gt;.apply(&lt;var&gt;self&lt;/var&gt;, &lt;var&gt;args&lt;/var&gt;);
  };
};  
&lt;/pre&gt;
&lt;p&gt;
  After looking at the ES Harmony proposal, and looking at a 
  few versions of bind functions, I decided to write a better one 
  that does exactly what the ES Harmony&#39;s bind does, but with 
  greater efficiency than the current libraries offer, and whose,
  &lt;code&gt;length&lt;/code&gt; property was &lt;code&gt;1&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
  Although unnecessary, this is a welcome addition to the language.
  A native bind will outperform any user-defined bind function 
  and will result in fewer closures.
&lt;/p&gt;

&lt;h3&gt;The Rundown&lt;/h3&gt;
&lt;p&gt;
  Before I give a critique and rundown, I have a test.
&lt;/p&gt;
&lt;h4&gt;&lt;a href=&quot;/test/blog/bind/BindFunction.html&quot;&gt;Library Comparison Test&lt;/a&gt;&lt;/h4&gt;


&lt;ol&gt;
	&lt;li&gt;Garrett&#39;s Bind
		&lt;p&gt;
		 This bind was, by far, the most efficient in 
		 tests #1, and #4, and nearly ties Base 2 in test #2 
		 (Base 2 was about .5 ms faster) . 
		 This function requires no additional code or functions. 
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/base2/&quot;&gt;Base2&lt;/a&gt; 
	&lt;code&gt;bind&lt;/code&gt;
		&lt;p&gt;
		  Second performance-wise. 
		&lt;/p&gt;
		&lt;p&gt;
		  Requires only a 
		  top level &lt;code&gt;_slice&lt;/code&gt; function (trivial), and performs 
		  a strategy for extra arguments.  
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://dojotoolkit.org/&quot;&gt;Dojo&lt;/a&gt;&#39;s hitch
		&lt;p&gt;
		  Dojo was fast with pure bind, but slower with partial apply. 
		&lt;/p&gt;
		&lt;p&gt;
		  This function requires many other functions and has an additional 
		  complication of accepting strings and arguments of different order.
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt; &lt;a href=&quot;http://extjs.com/&quot;&gt;Ext-js&lt;/a&gt; 
	  &lt;code&gt;Function.prototype.createDelegate&lt;/code&gt; 
		&lt;p&gt;
		  Performance was slow.  
		  This function requires no importing of external functions.
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;Mark Miller&#39;s &lt;code&gt;bind&lt;/code&gt;
		&lt;p&gt;
		  Requires no external dependencies. While it gets a 10 for simplicity
		  and aesthetics, this function was not as fast, and for pure bind 
		  (no &lt;dfn&gt;partial apply&lt;/dfn&gt;) was not nearly as fast as it 
		  should be.
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;
		  &lt;a href=&quot;http://prototypejs.org/&quot;&gt;Prototype&lt;/a&gt;&#39;s 
		  &lt;code&gt;Function.prototype.bind&lt;/code&gt;
		&lt;p&gt;
		  Performance was fair.
		  Requires several extra functions + browser detection. The function 
		  is used very heavily internally.
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://mootools.net/&quot;&gt;Mootools&lt;/a&gt; 
	    &lt;code&gt;Function.prototype.bind&lt;/code&gt;
		&lt;p&gt;
		  Performance times were poor and
		  the results for two tests were wrong. &lt;del&gt;were wrong&lt;/del&gt;. 
		&lt;/p&gt;
		&lt;p&gt;&lt;ins&gt;
		  The entire mootools.js is required for the bind function. 
		  The library adds a &lt;code&gt;$family&lt;/code&gt; property, and makes 
		  other changes to &lt;code&gt;Array.prototype&lt;/code&gt;. 
		  &lt;/ins&gt;
		&lt;/p&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://developer.yahoo.com/yui/3/&quot;&gt;YUI 3 &lt;/a&gt; 
	  &lt;code&gt;bind&lt;/code&gt;
	  &lt;p&gt;
	    Performance time was fair.
	    The results for test#2 are wrong because the 
	    call&#39;s arguments are prepended, not appended. This is by design.
	  &lt;/p&gt;
	  &lt;p&gt;
	    Having the call&#39;s arguments &lt;em&gt;prepended&lt;/em&gt; 
	    is an unusual design decision. It might seem
	    unintuitive, and confuse developers who are used 
	    to the more common version, as seen in Prototype, Base2, 
	    and the official EcmaScript proposal.
	  &lt;/p&gt;
	  &lt;p&gt;
	    The amount of code YUI&#39;s bind depends on is staggering. 
	  &lt;/p&gt;
	&lt;/li&gt;
	
&lt;/ol&gt;

&lt;h3&gt;Pass the Parme&amp;#378;an&lt;/h3&gt;
&lt;p&gt;
  Many of the libraries have long chains of function calls. 
  A bind function does not need and should not require the 
  inclusion of several other functions.
&lt;/p&gt;

&lt;p&gt;
  Prototype JS requires the &lt;code&gt;$A&lt;/code&gt; function, which requires 
  &lt;code&gt;Prototype.Browser&lt;/code&gt; to determine 
  which &lt;code&gt;$A&lt;/code&gt; function. Browser detection has absolutely 
  no place in Function binding. (&lt;code&gt;$A&lt;/code&gt; also calls 
  &lt;code&gt;toArray&lt;/code&gt; conditionally, but that will not happen in this case.)
&lt;/p&gt;

&lt;p&gt;
  Dojo is almost as bad. 
  Dojo&#39;s &lt;code&gt;hitch&lt;/code&gt; function has the arguments in reverse order and 
  requires &lt;code&gt;dojo.global&lt;/code&gt;, 
  &lt;code&gt;dojo._hitchArgs&lt;/code&gt;, &lt;code&gt;dojo._toArray&lt;/code&gt;, 
  and &lt;code&gt;dojo.isString&lt;/code&gt;. 
&lt;/p&gt;

&lt;p&gt;
  Mootools has very strewn code. The broken bind 
  function required an additional 108 lines of Mootools. 
&lt;/p&gt;
&lt;p&gt;
  YUI is the most grandiose.
  Function &lt;code&gt;YUI.bind(f, o)&lt;/code&gt; is found in 
  &quot;&lt;samp&gt;oop.js&lt;/samp&gt;&quot;. File &lt;samp&gt;oop.js&lt;/samp&gt;
  requires over 120k of &quot;prerequisite&quot; files in 
  &lt;samp&gt;yui.js&lt;/samp&gt; and &lt;samp&gt;yui-base.js&lt;/samp&gt;, 
  coming to a total of over 160k. Just for bind. YUI 3 seems to suffer 
  from over-engineering and &lt;abbr title=&quot;Big Up Front Design&quot;
  &gt;BUFD&lt;/abbr&gt;, which is typical in waterfall shops.
  &lt;/p&gt;
&lt;p&gt;
  YUI&#39;s &#39;array&#39; module did not seem to load or evaluate properly, so 
  code from the yui-base file was copy-pasted.
&lt;/p&gt;

&lt;h3&gt;Worth Using?&lt;/h3&gt;
&lt;p&gt;
  The best bind functions are fast, do not require 
  other library functions, and are fairly simple. 
&lt;/p&gt;
&lt;h4&gt;But is a Bind Function Necessary?&lt;/h4&gt;
&lt;p&gt;
  No. Binding can be achieved with an inline closure 
  where it is needed
  and partial application is not necessary.  
&lt;/p&gt;

&lt;p&gt;
  Here is example 1, without using bind.
&lt;/p&gt;
&lt;pre&gt;
&lt;span class=&#39;keyword&#39;&gt;var&lt;/span&gt; &lt;var&gt;updater&lt;/var&gt; = {
  fetch : &lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt;() {
    alert(&lt;span class=&#39;keyword&#39;&gt;this&lt;/span&gt;.time++);
  },
  time : 0
};
setTimeout(&lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt;() { &lt;var&gt;updater&lt;/var&gt;.fetch(); }, 500);
&lt;/pre&gt;
&lt;p&gt;
  A native &lt;code&gt;Function.prototype.bind&lt;/code&gt; will allow 
  for cleaner binding, without the need for creating 
  a closure. As native code, it will be faster and more reliable.
  &lt;code&gt;Function.prototype.bind&lt;/code&gt; is not necessary, 
  but is a welcome addition to the language.
&lt;/p&gt;

&lt;h4&gt;Why All the Fuss?&lt;/h4&gt;
&lt;p&gt;
  Being aware of what libraries do and identifying and learning 
  from the mistakes of libraries helps developers avoid such 
  mistakes by learning what the library does. Developers
  do not need the burden of large, tangled, and often 
  buggy library dependencies.
&lt;/p&gt;

&lt;h4&gt;Look at The Code&lt;/h4&gt;
&lt;p&gt;
  &lt;em&gt;What&lt;/em&gt; the library&#39;s bind function does and &lt;em&gt;how&lt;/em&gt; the library uses 
  that function internally is a step to take in assessing 
  the library&#39;s quality.  
&lt;/p&gt;

&lt;p&gt;
  A developer can make a more responsible and 
  professional choice by avoiding a library that makes 
  heavy use of a slow-spaghetti bind function.
&lt;/p&gt;

&lt;h3&gt;My Version&lt;/h3&gt;

&lt;p&gt;
  The following function is
  the fastest bind function for pure bind (no partial apply). 
  It is more than three times as fast as Base2, the second fastest bind 
  function tested here. 
&lt;/p&gt;
&lt;p&gt;
  Here is my version of the bind function.
&lt;/p&gt;

&lt;pre&gt;
&lt;span class=&quot;comment&quot;&gt;/**
 * @param {Object} context the &#39;this&#39; value to be used.
 * @param {arguments} [1..n] optional arguments that are
 * prepended to returned function&#39;s call.
 * @return {Function} a function that applies the original
 * function with &#39;context&#39; as the thisArg.
 */&lt;/span&gt;
Function.prototype.bind = &lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt;(&lt;var&gt;context&lt;/var&gt;){
  &lt;span class=&#39;keyword&#39;&gt;var&lt;/span&gt; &lt;var&gt;fn&lt;/var&gt; = &lt;span class=&#39;keyword&#39;&gt;this&lt;/span&gt;, 
      &lt;var&gt;ap&lt;/var&gt;, &lt;var&gt;concat&lt;/var&gt;, &lt;var&gt;args&lt;/var&gt;,
      &lt;var&gt;isPartial&lt;/var&gt; = arguments.length &gt; 1;
  &lt;span class=&quot;comment&quot;&gt;// Strategy 1: just bind, not a partialApply&lt;/span&gt;
  &lt;span class=&#39;keyword&#39;&gt;if&lt;/span&gt;(!&lt;var&gt;isPartial&lt;/var&gt;) {
    &lt;span class=&#39;keyword&#39;&gt;return&lt;/span&gt; &lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt;() {
        &lt;span class=&#39;keyword&#39;&gt;if&lt;/span&gt;(arguments.length !== 0) {
          &lt;span class=&#39;keyword&#39;&gt;return&lt;/span&gt; &lt;var&gt;fn&lt;/var&gt;.apply(context, arguments);
        } &lt;span class=&#39;keyword&#39;&gt;else&lt;/span&gt; {
          &lt;span class=&#39;keyword&#39;&gt;return&lt;/span&gt; &lt;var&gt;fn&lt;/var&gt;.call(&lt;var&gt;context&lt;/var&gt;); &lt;span class=&#39;comment&#39;&gt;// faster in Firefox.&lt;/span&gt;
        }
      };
    } &lt;span class=&#39;keyword&#39;&gt;else&lt;/span&gt; {
    &lt;span class=&quot;comment&quot;&gt;// Strategy 2: partialApply&lt;/span&gt;
    &lt;var&gt;ap&lt;/var&gt; = Array.prototype,
    &lt;var&gt;args&lt;/var&gt; = &lt;var&gt;ap&lt;/var&gt;.&lt;var&gt;slice&lt;/var&gt;.call(arguments, 1);
    &lt;var&gt;concat&lt;/var&gt; = &lt;var&gt;ap&lt;/var&gt;.concat;
    &lt;span class=&#39;keyword&#39;&gt;return&lt;/span&gt; &lt;span class=&#39;keyword&#39;&gt;function&lt;/span&gt;() {
      &lt;span class=&#39;keyword&#39;&gt;return&lt;/span&gt; &lt;var&gt;fn&lt;/var&gt;.apply(context, 
        arguments.length === 0 ? &lt;var&gt;args&lt;/var&gt; : 
        &lt;var&gt;concat&lt;/var&gt;.apply(&lt;var&gt;args&lt;/var&gt;, arguments));
    };
  }
};
&lt;/pre&gt;
&lt;p&gt;
  This function was not included in 
  &lt;a href=&quot;http://dhtmlkithcen.com/ape/&quot;&gt;APE&lt;/a&gt; 
  because it was not needed. This function may be used by libraries who wish to 
  continue using a bind function with the benefit of faster performance. 
&lt;/p&gt;
</description>
            <guid>http://dhtmlkitchen.com/news/default/2008/09/11/Function-prototype-bind</guid>
			<pubDate>Thu, 11 Sep 2008 17:20:00 -0500</pubDate>
            <category>/JavaScript/</category>
                                        <wfw:comment>http://dhtmlkitchen.com/commentapi/default/JavaScript/2008/09/11/Function-prototype-bind</wfw:comment>
            <wfw:commentRss>http://dhtmlkitchen.com/news/default/2008/09/11/Function-prototype-bind?page=comments&amp;flavor=rss2</wfw:commentRss>
                                </item>
            </channel>
</rss>
