]> source.dussan.org Git - gwtquery.git/commitdiff
added a pure javascript selector engine based in Sizzle, replaced EngineJS by EngineS...
authorManolo Carrasco <manolo@apache.org>
Thu, 27 May 2010 22:53:34 +0000 (22:53 +0000)
committerManolo Carrasco <manolo@apache.org>
Thu, 27 May 2010 22:53:34 +0000 (22:53 +0000)
gwtquery-core/src/main/java/com/google/gwt/query/Query.gwt.xml
gwtquery-core/src/main/java/com/google/gwt/query/client/Function.java
gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineJS.java
gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineSizzle.java [new file with mode: 0644]
gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineXPath.java
gwtquery-core/src/test/java/com/google/gwt/query/client/GQuerySelectorsTest.java

index bf41a26d3e6be438a9c1e764e3b45daeb54bfd30..bd9a76c3a5c7def9baad6d72eb1dd937649215a4 100644 (file)
     </replace-with>\r
 \r
 \r
-    <replace-with class="com.google.gwt.query.client.impl.SelectorEngineJS">\r
+    <replace-with class="com.google.gwt.query.client.impl.SelectorEngineSizzle">\r
         <when-type-assignable\r
                 class="com.google.gwt.query.client.impl.SelectorEngineImpl"/>\r
     </replace-with>\r
 \r
-    <replace-with class="com.google.gwt.query.client.impl.SelectorEngineJS">\r
-        <when-type-assignable\r
-                class="com.google.gwt.query.client.impl.SelectorEngineImpl"/>\r
-        <when-property-is name="user.agent" value="gecko"/>\r
-    </replace-with>\r
-\r
-    <replace-with class="com.google.gwt.query.client.impl.SelectorEngineJSIE">\r
-        <when-type-assignable\r
-                class="com.google.gwt.query.client.impl.SelectorEngineImpl"/>\r
-        <when-property-is name="user.agent" value="ie6"/>\r
-        <when-property-is name="user.agent" value="ie8"/>\r
-    </replace-with>\r
-\r
     <replace-with class="com.google.gwt.query.client.impl.SelectorEngineXPath">\r
         <when-type-assignable\r
                 class="com.google.gwt.query.client.impl.SelectorEngineImpl"/>\r
index 333e537bb4406197daeb1ebd4fa3b7e3ec9ea5de..005b9d2a0d3c3ccd68e5eb521e130f88d53dc546 100644 (file)
@@ -52,7 +52,7 @@ public abstract class Function {
    * Override this method for bound event handlers.
    */
   public boolean f(Event e) {
-    f(e.getCurrentTarget());
+    f((Element)e.getCurrentEventTarget().cast());
     return true;
   }
 }
index b18c275977a8cf2ce2e5916165181b7cbb0f4096..a0788fbaf3c50eae5c87e78d03b47100c5b03b15 100644 (file)
@@ -323,14 +323,14 @@ public class SelectorEngineJS extends SelectorEngineImpl {
             for (int r = 0, rlen = matchingElms.size(); r < rlen; r++) {\r
               Element current = matchingElms.getElement(r);\r
               boolean addElm = false;\r
-              for (int s = 0, sl = regExpAttributes.length, attributeRegExp;\r
+              for (int s = 0, sl = regExpAttributes.length;\r
                   s < sl; s++) {\r
                 addElm = false;\r
-                Regexp attributeRegExp2 = regExpAttributes[s];\r
+                Regexp attributeRegexp = regExpAttributes[s];\r
                 String currentAttr = getAttr(current, regExpAttributesStr[s]);\r
                 if (SelectorEngine.truth(currentAttr)\r
                     && currentAttr.length() != 0) {\r
-                  if (attributeRegExp2 == null || attributeRegExp2\r
+                  if (attributeRegexp == null || attributeRegexp\r
                       .test(currentAttr)) {\r
                     addElm = true;\r
                   }\r
@@ -427,7 +427,6 @@ public class SelectorEngineJS extends SelectorEngineImpl {
     JSArray prevParents = JSArray.create();\r
     boolean previousDir = pseudoClass.startsWith("first") ? true : false;\r
     JSArray matchingElms = JSArray.create();\r
-    Node prev, next, previous;\r
     if (SelectorEngine.eq("first-child", pseudoClass) || SelectorEngine\r
         .eq("last-child", pseudoClass)) {\r
       getFirstChildPseudo(previousMatch, previousDir, matchingElms);\r
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineSizzle.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/impl/SelectorEngineSizzle.java
new file mode 100644 (file)
index 0000000..3149f3b
--- /dev/null
@@ -0,0 +1,748 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.query.client.impl;
+
+import java.util.HashSet;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.JsArray;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Node;
+import com.google.gwt.dom.client.NodeList;
+
+/**
+ * Pure Javascript Selector Engine Implementation based on
+ * Sizzle CSS Selector Engine v1.0.
+ */
+public class SelectorEngineSizzle extends SelectorEngineImpl {
+  
+  public static native boolean contains(Object a, Object b) /*-{
+    var ret =  
+      document.compareDocumentPosition ?
+        (a.compareDocumentPosition(b) & 16): 
+        a !== b && (a.contains ? a.contains(b) : true);
+    return ret ? true : false;
+  }-*/;
+
+  public static native JavaScriptObject createExpr() /*-{
+    var done = 0;
+    $wnd.Expr = {
+      order: [ "ID", "NAME", "TAG" ],
+      match: {
+        ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+        CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+        NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
+        ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+        TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
+        CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+        POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+        PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/,
+        CHUNKER: /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g  
+      },
+      leftMatch: {},
+      attrMap: {
+        "class": "className",
+        "for": "htmlFor"
+      },
+      attrHandle: {
+        href: function(elem){
+          return elem.getAttribute("href");
+        }
+      },
+      relative: {
+        "+": function(checkSet, part){
+          var isPartStr = typeof part === "string",
+            isTag = isPartStr && !/\W/.test(part),
+            isPartStrNotTag = isPartStr && !isTag;
+          if ( isTag ) {
+            part = part.toLowerCase();
+          }
+          for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+            if ( (elem = checkSet[i]) ) {
+              while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+              checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+                elem || false :
+                elem === part;
+            }
+          }
+          if ( isPartStrNotTag ) {
+            @com.google.gwt.query.client.impl.SelectorEngineSizzle::filter(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;ZLjava/lang/Object;)( part, checkSet, true );
+          }
+        },
+        ">": function(checkSet, part){
+          var isPartStr = typeof part === "string";
+          if ( isPartStr && !/\W/.test(part) ) {
+            part = part.toLowerCase();
+
+            for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+              var elem = checkSet[i];
+              if ( elem ) {
+                var parent = elem.parentNode;
+                checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+              }
+            }
+          } else {
+            for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+              var elem = checkSet[i];
+              if ( elem ) {
+                checkSet[i] = isPartStr ?
+                  elem.parentNode :
+                  elem.parentNode === part;
+              }
+            }
+            if ( isPartStr ) {
+              @com.google.gwt.query.client.impl.SelectorEngineSizzle::filter(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;ZLjava/lang/Object;)( part, checkSet, true );
+            }
+          }
+        },
+        "": function(checkSet, part){
+          var doneName = done++;
+          if ( typeof part === "string" && !/\W/.test(part) ) {
+            checkFn = $wnd.dirNodeCheck;
+            @com.google.gwt.query.client.impl.SelectorEngineSizzle::dirNodeCheck(Ljava/lang/String;Ljava/lang/Object;ILjava/lang/Object;)("parentNode", part, doneName, checkSet);
+          } else {
+            @com.google.gwt.query.client.impl.SelectorEngineSizzle::dirCheck(Ljava/lang/String;Ljava/lang/Object;ILjava/lang/Object;)("parentNode", part, doneName, checkSet);
+          }
+        },
+        "~": function(checkSet, part){
+          var doneName = done++;
+          if ( typeof part === "string" && !/\W/.test(part) ) {
+            @com.google.gwt.query.client.impl.SelectorEngineSizzle::dirNodeCheck(Ljava/lang/String;Ljava/lang/Object;ILjava/lang/Object;)("previousSibling", part, doneName, checkSet);
+          } else {
+            @com.google.gwt.query.client.impl.SelectorEngineSizzle::dirCheck(Ljava/lang/String;Ljava/lang/Object;ILjava/lang/Object;)("previousSibling", part, doneName, checkSet);
+          }
+        }
+      },
+      find: {
+        ID: function(match, context){
+          if ( typeof context.getElementById !== "undefined") {
+            var m = context.getElementById(match[1]);
+            return m ? [m] : [];
+          }
+        },
+        NAME: function(match, context){
+          if ( typeof context.getElementsByName !== "undefined" ) {
+            var ret = [], results = context.getElementsByName(match[1]);
+
+            for ( var i = 0, l = results.length; i < l; i++ ) {
+              if ( results[i].getAttribute("name") === match[1] ) {
+                ret.push( results[i] );
+              }
+            }
+            return ret.length === 0 ? null : ret;
+          }
+        },
+        TAG: function(match, context){
+          return context.getElementsByTagName(match[1]);
+        }
+      },
+      preFilter: {
+        CLASS: function(match, curLoop, inplace, result, not){
+          match = " " + match[1].replace(/\\/g, "") + " ";
+          for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+            if ( elem ) {
+              if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
+                if ( !inplace ) {
+                  result.push( elem );
+                }
+              } else if ( inplace ) {
+                curLoop[i] = false;
+              }
+            }
+          }
+          return false;
+        },
+        ID: function(match){
+          return match[1].replace(/\\/g, "");
+        },
+        TAG: function(match, curLoop){
+          return match[1].toLowerCase();
+        },
+        CHILD: function(match){
+          if ( match[1] === "nth" ) {
+            // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+            var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+              match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+              !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+            // calculate the numbers (first)n+(last) including if they are negative
+            match[2] = (test[1] + (test[2] || 1)) - 0;
+            match[3] = test[3] - 0;
+          }
+          match[0] = done++;
+          return match;
+        },
+        ATTR: function(match, curLoop, inplace, result, not){
+          var name = match[1].replace(/\\/g, "");
+          if ($wnd.Expr.attrMap[name] ) {
+            match[1] = $wnd.Expr.attrMap[name];
+          }
+          if ( match[2] === "~=" ) {
+            match[4] = " " + match[4] + " ";
+          }
+          return match;
+        },
+        PSEUDO: function(match, curLoop, inplace, result, not){
+          if ( match[1] === "not" ) {
+            // If we're dealing with a complex expression, or a simple one
+            if ( ( $wnd.Expr.match.CHUNKER.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+              match[3] = @com.google.gwt.query.client.impl.SelectorEngineSizzle::select(Ljava/lang/String;Lcom/google/gwt/dom/client/Node;Lcom/google/gwt/core/client/JsArray;Lcom/google/gwt/core/client/JsArray;)(match[3], null, null, curLoop);
+            } else {
+              var ret = @com.google.gwt.query.client.impl.SelectorEngineSizzle::filter(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;ZLjava/lang/Object;)(match[3], curLoop, inplace, true ^ not);
+              if ( !inplace ) {
+                result.push.apply( result, ret );
+              }
+              return false;
+            }
+          } else if ( $wnd.Expr.match.POS.test( match[0] ) || $wnd.Expr.match.CHILD.test( match[0] ) ) {
+            return true;
+          }
+          return match;
+        },
+        POS: function(match){
+          match.unshift( true );
+          return match;
+        }
+      },
+      filters: {
+        enabled: function(elem){
+          return elem.disabled === false && elem.type !== "hidden";
+        },
+        disabled: function(elem){
+          return elem.disabled === true;
+        },
+        checked: function(elem){
+          return elem.checked === true;
+        },
+        selected: function(elem){
+          // Accessing this property makes selected-by-default
+          // options in Safari work properly
+          elem.parentNode.selectedIndex;
+          return elem.selected === true;
+        },
+        parent: function(elem){
+          return !!elem.firstChild;
+        },
+        empty: function(elem){
+          return !elem.firstChild;
+        },
+        has: function(elem, i, match){
+          return !!@com.google.gwt.query.client.impl.SelectorEngineSizzle::select(Ljava/lang/String;Lcom/google/gwt/dom/client/Node;Lcom/google/gwt/core/client/JsArray;Lcom/google/gwt/core/client/JsArray;)(match[3], elem, null, null).length;
+        },
+        header: function(elem){
+          return /h\d/i.test( elem.nodeName );
+        },
+        text: function(elem){
+          return "text" === elem.type;
+        },
+        radio: function(elem){
+          return "radio" === elem.type;
+        },
+        checkbox: function(elem){
+          return "checkbox" === elem.type;
+        },
+        file: function(elem){
+          return "file" === elem.type;
+        },
+        password: function(elem){
+          return "password" === elem.type;
+        },
+        submit: function(elem){
+          return "submit" === elem.type;
+        },
+        image: function(elem){
+          return "image" === elem.type;
+        },
+        reset: function(elem){
+          return "reset" === elem.type;
+        },
+        button: function(elem){
+          return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
+        },
+        input: function(elem){
+          return /input|select|textarea|button/i.test(elem.nodeName);
+        }
+      },
+      setFilters: {
+        first: function(elem, i){
+          return i === 0;
+        },
+        last: function(elem, i, match, array){
+          return i === array.length - 1;
+        },
+        even: function(elem, i){
+          return i % 2 === 0;
+        },
+        odd: function(elem, i){
+          return i % 2 === 1;
+        },
+        lt: function(elem, i, match){
+          return i < match[3] - 0;
+        },
+        gt: function(elem, i, match){
+          return i > match[3] - 0;
+        },
+        nth: function(elem, i, match){
+          return match[3] - 0 === i;
+        },
+        eq: function(elem, i, match){
+          return match[3] - 0 === i;
+        }
+      },
+      filter: {
+        PSEUDO: function(elem, match, i, array){
+          var name = match[1], filter = $wnd.Expr.filters[ name ];
+          if ( filter ) {
+            return filter( elem, i, match, array );
+          } else if ( name === "contains" ) {
+            return (elem.textContent || elem.innerText || @com.google.gwt.query.client.impl.SelectorEngineSizzle::getText(Ljava/lang/Object;)([ elem ]) || "").indexOf(match[3]) >= 0;
+          } else if ( name === "not" ) {
+            var not = match[3];
+
+            for ( var i = 0, l = not.length; i < l; i++ ) {
+              if ( not[i] === elem ) {
+                return false;
+              }
+            }
+            return true;
+          } else {
+            @com.google.gwt.query.client.impl.SelectorEngineSizzle::error(Ljava/lang/String;)("Syntax error, unrecognized expression: " + name);
+          }
+        },
+        CHILD: function(elem, match){
+          var type = match[1], node = elem;
+          switch (type) {
+            case 'only':
+            case 'first':
+              while ( (node = node.previousSibling) )   {
+                if ( node.nodeType === 1 ) { 
+                  return false; 
+                }
+              }
+              if ( type === "first" ) { 
+                return true; 
+              }
+              node = elem;
+            case 'last':
+              while ( (node = node.nextSibling) )   {
+                if ( node.nodeType === 1 ) { 
+                  return false; 
+                }
+              }
+              return true;
+            case 'nth':
+              var first = match[2], last = match[3];
+              if ( first === 1 && last === 0 ) {
+                return true;
+              }
+              var doneName = match[0],
+              parent = elem.parentNode;
+              if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+                var count = 0;
+                for ( node = parent.firstChild; node; node = node.nextSibling ) {
+                  if ( node.nodeType === 1 ) {
+                    node.nodeIndex = ++count;
+                  }
+                } 
+                parent.sizcache = doneName;
+              }
+              var diff = elem.nodeIndex - last;
+              if ( first === 0 ) {
+                return diff === 0;
+              } else {
+                return ( diff % first === 0 && diff / first >= 0 );
+              }
+          }
+        },
+        ID: function(elem, match){
+          return elem.nodeType === 1 && elem.getAttribute("id") === match;
+        },
+        TAG: function(elem, match){
+          return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+        },
+        CLASS: function(elem, match){
+          return (" " + (elem.className || elem.getAttribute("class")) + " ")
+            .indexOf( match ) > -1;
+        },
+        ATTR: function(elem, match){
+          var name = match[1],
+            result = $wnd.Expr.attrHandle[ name ] ?
+              $wnd.Expr.attrHandle[ name ]( elem ) :
+              elem[ name ] != null ?
+                elem[ name ] :
+                elem.getAttribute( name ),
+            value = result + "",
+            type = match[2],
+            check = match[4];
+          return result == null ?
+            type === "!=" :
+            type === "=" ?
+            value === check :
+            type === "*=" ?
+            value.indexOf(check) >= 0 :
+            type === "~=" ?
+            (" " + value + " ").indexOf(check) >= 0 :
+            !check ?
+            value && result !== false :
+            type === "!=" ?
+            value !== check :
+            type === "^=" ?
+            value.indexOf(check) === 0 :
+            type === "$=" ?
+            value.substr(value.length - check.length) === check :
+            type === "|=" ?
+            value === check || value.substr(0, check.length + 1) === check + "-" :
+            false;
+        },
+        POS: function(elem, match, i, array){
+          var name = match[2], filter = $wnd.Expr.setFilters[ name ];
+          if ( filter ) {
+            return filter( elem, i, match, array );
+          }
+        }
+      }
+    };
+
+    for ( var type in $wnd.Expr.match ) {
+      $wnd.Expr.match[ type ] = new RegExp( $wnd.Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+      $wnd.Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + $wnd.Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
+        return "\\" + (num - 0 + 1);
+      }));
+    }
+    
+    return $wnd.Expr;
+  }-*/;
+
+  public static native void dirCheck(String dir, Object cur, int doneName, Object checkSet) /*-{
+     for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+       var elem = checkSet[i];
+       if ( elem ) {
+         elem = elem[dir];
+         var match = false;
+         while ( elem ) {
+           if ( elem.sizcache === doneName ) {
+             match = checkSet[elem.sizset];
+             break;
+           }
+           if ( elem.nodeType === 1 ) {
+             elem.sizcache = doneName;
+             elem.sizset = i;
+             if ( typeof cur !== "string" ) {
+               if ( elem === cur ) {
+                 match = true;
+                 break;
+               }
+             } else if ( @com.google.gwt.query.client.impl.SelectorEngineSizzle::filter(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;ZLjava/lang/Object;)( cur, [elem], false ).length > 0 ) {
+               match = elem;
+               break;
+             }
+           }
+           elem = elem[dir];
+         }
+         checkSet[i] = match;
+       }
+     }
+   }-*/;
+    
+   public static native void dirNodeCheck(String dir, Object cur, int doneName, Object checkSet) /*-{
+    for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+      var elem = checkSet[i];
+      if ( elem ) {
+        elem = elem[dir];
+        var match = false;
+        while ( elem ) {
+          if ( elem.sizcache === doneName ) {
+            match = checkSet[elem.sizset];
+            break;
+          }
+          if ( elem.nodeType === 1){
+            elem.sizcache = doneName;
+            elem.sizset = i;
+          }
+          if ( elem.nodeName.toLowerCase() === cur ) {
+            match = elem;
+            break;
+          }
+          elem = elem[dir];
+        }
+        checkSet[i] = match;
+      }
+    }
+  }-*/;
+  
+  public static void error(String msg) {
+    throw new IllegalArgumentException("Syntax error, unrecognized expression: " + msg);
+  }
+   
+  public static native JsArray<Node> filter(String expr, JsArray<Node> set, boolean inplace, Object not) /*-{
+    var old = expr, result = [], curLoop = set, match, anyFound;
+    while ( expr && set.length ) {
+      for ( var type in $wnd.Expr.filter ) {
+        if ( (match = $wnd.Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+          var filter = $wnd.Expr.filter[ type ], found, item, left = match[1];
+          anyFound = false;
+          match.splice(1,1);
+          if ( left.substr( left.length - 1 ) === "\\" ) {
+            continue;
+          }
+          if ( curLoop === result ) {
+            result = [];
+          }
+          if ( $wnd.Expr.preFilter[ type ] ) {
+            match = $wnd.Expr.preFilter[ type ]( match, curLoop, inplace, result, not);
+            if ( !match ) {
+              anyFound = found = true;
+            } else if ( match === true ) {
+              continue;
+            }
+          }
+          if ( match ) {
+            for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+              if ( item ) {
+                found = filter( item, match, i, curLoop );
+                var pass = not ^ !!found;
+  
+                if ( inplace && found != null ) {
+                  if ( pass ) {
+                    anyFound = true;
+                  } else {
+                    curLoop[i] = false;
+                  }
+                } else if ( pass ) {
+                  result.push( item );
+                  anyFound = true;
+                }
+              }
+            }
+          }
+          if ( found !== undefined ) {
+            if ( !inplace ) {
+              curLoop = result;
+            }
+            expr = expr.replace( $wnd.Expr.match[ type ], "" );
+            if ( !anyFound ) {
+              return [];
+            }
+            break;
+          }
+        }
+      }
+      // Improper expression
+      if ( expr === old ) {
+        if ( anyFound == null ) {
+          @com.google.gwt.query.client.impl.SelectorEngineSizzle::error(Ljava/lang/String;)(expr);
+        } else {
+          break;
+        }
+      }
+      old = expr;
+    }
+    return curLoop;    
+  }-*/;
+
+  public static native JavaScriptObject find(String expr, Node context) /*-{
+    var set, match;
+    if ( !expr ) {
+      return [];
+    }
+    for ( var i = 0, l = $wnd.Expr.order.length; i < l; i++ ) {
+      var type = $wnd.Expr.order[i], match;
+      
+      if ( (match = $wnd.Expr.leftMatch[ type ].exec( expr )) ) {
+        var left = match[1];
+        match.splice(1,1);
+  
+        if ( left.substr( left.length - 1 ) !== "\\" ) {
+          match[1] = (match[1] || "").replace(/\\/g, "");
+          set = $wnd.Expr.find[ type ]( match, context);
+          if ( set != null ) {
+            expr = expr.replace( $wnd.Expr.match[ type ], "" );
+            break;
+          }
+        }
+      }
+    }
+    if ( !set ) {
+      set = context.getElementsByTagName("*");
+    }
+    return {set: set, expr: expr};    
+  }-*/;
+   
+  public static native String getText(Object elems) /*-{
+    var ret = "", elem;
+    for ( var i = 0; elems[i]; i++ ) {
+      elem = elems[i];
+      // Get the text from text nodes and CDATA nodes
+      if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+        ret += elem.nodeValue;
+      // Traverse everything else, except comment nodes
+      } else if ( elem.nodeType !== 8 ) {
+        ret += @com.google.gwt.query.client.impl.SelectorEngineSizzle::getText(Ljava/lang/Object;)(elem.childNodes);
+      }
+    }
+    return ret;
+  }-*/;
+   
+  public static native JsArray<Node> makeArray(NodeList<Node> array, JsArray<Node> results) /*-{
+    var ret = results || [];
+    if ( Object.prototype.toString.call(array) === "[object Array]" ) {
+      Array.prototype.push.apply( ret, array );
+    } else {
+      if ( typeof array.length === "number" ) {
+        for ( var i = 0, l = array.length; i < l; i++ ) {
+          ret.push( array[i] );
+        }
+      } else {
+        for ( var i = 0; array[i]; i++ ) {
+          ret.push( array[i] );
+        }
+      }
+    }
+    return ret;   
+  }-*/;
+  
+  public static native JsArray<Element> posProcess(String selector, Node context) /*-{
+    var tmpSet = [], later = "", match, root = context.nodeType ? [context] : context;
+    // Position selectors must be done after the filter
+    // And so must :not(positional) so we move all PSEUDOs to the end
+    while ( (match = $wnd.Expr.match.PSEUDO.exec( selector )) ) {
+      later += match[0];
+      selector = selector.replace($wnd.Expr.match.PSEUDO, "" );
+    }
+    selector = $wnd.Expr.relative[selector] ? selector + "*" : selector;
+    for ( var i = 0, l = root.length; i < l; i++ ) {
+      @com.google.gwt.query.client.impl.SelectorEngineSizzle::select(Ljava/lang/String;Lcom/google/gwt/dom/client/Node;Lcom/google/gwt/core/client/JsArray;Lcom/google/gwt/core/client/JsArray;)(selector, root[i], tmpSet, null);
+    }
+    return @com.google.gwt.query.client.impl.SelectorEngineSizzle::filter(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;ZLjava/lang/Object;)( later, tmpSet, false );
+  }-*/;   
+   
+  public static JsArray<Element> unique(JsArray<Element> a) {
+    JsArray<Element> ret = JavaScriptObject.createArray().cast();
+    HashSet<Integer> f = new HashSet<Integer>();
+    for (int i = 0; i < a.length(); i++) {
+      Element e = a.get(i);
+      if (!f.contains(e.hashCode())) {
+        f.add(e.hashCode());
+        ret.push(e);
+      }
+    }    
+    return ret;
+  }
+  
+  private static native JsArray<Element> select(String selector, Node context, JsArray<Element> results, JsArray<Element> seed) /*-{
+    results = results || [];
+    var origContext = context = context || document;
+    var parts = [], m, set, checkSet, extra, prune = true, soFar = selector;
+    // Reset the position of the chunker regexp (start from head)
+    while ( ($wnd.Expr.match.CHUNKER.exec(""), m = $wnd.Expr.match.CHUNKER.exec(soFar)) !== null ) {
+      soFar = m[3];
+      parts.push( m[1] );
+      if ( m[2] ) {
+        extra = m[3];
+        break;
+      }
+    }
+    if ( parts.length > 1 && $wnd.Expr.match.POS.exec( selector ) ) {
+      if ( parts.length === 2 && $wnd.Expr.relative[ parts[0] ] ) {
+        set = @com.google.gwt.query.client.impl.SelectorEngineSizzle::posProcess(Ljava/lang/String;Lcom/google/gwt/dom/client/Node;)(parts[0] + parts[1], context);
+      } else {
+        set = $wnd.Expr.relative[ parts[0] ] ?
+          [ context ] :
+          @com.google.gwt.query.client.impl.SelectorEngineSizzle::select(Ljava/lang/String;Lcom/google/gwt/dom/client/Node;Lcom/google/gwt/core/client/JsArray;Lcom/google/gwt/core/client/JsArray;)(parts.shift(), context, null, null);
+        while ( parts.length ) {
+          selector = parts.shift();
+          if ( $wnd.Expr.relative[ selector ] ) {
+            selector += parts.shift();
+          }
+          set = @com.google.gwt.query.client.impl.SelectorEngineSizzle::posProcess(Ljava/lang/String;Lcom/google/gwt/dom/client/Node;)(selector, set);
+        }
+      }
+    } else {
+      // Take a shortcut and set the context if the root selector is an ID
+      // (but not if it'll be faster if the inner selector is an ID)
+      if ( !seed && parts.length > 1 && context.nodeType === 9 &&
+          $wnd.Expr.match.ID.test(parts[0]) && !$wnd.Expr.match.ID.test(parts[parts.length - 1]) ) {
+        var ret = @com.google.gwt.query.client.impl.SelectorEngineSizzle::find(Ljava/lang/String;Lcom/google/gwt/dom/client/Node;)( parts.shift(), context);
+        context = ret.expr ? @com.google.gwt.query.client.impl.SelectorEngineSizzle::filter(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;ZLjava/lang/Object;)( ret.expr, ret.set, false )[0] : ret.set[0];
+      }
+      if ( context ) {
+        var ret = seed ?
+          { expr: parts.pop(), set: @com.google.gwt.query.client.impl.SelectorEngineSizzle::makeArray(Lcom/google/gwt/dom/client/NodeList;Lcom/google/gwt/core/client/JsArray;)(seed, null) } :
+          @com.google.gwt.query.client.impl.SelectorEngineSizzle::find(Ljava/lang/String;Lcom/google/gwt/dom/client/Node;)( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context);
+        set = ret.expr ? @com.google.gwt.query.client.impl.SelectorEngineSizzle::filter(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;ZLjava/lang/Object;)( ret.expr, ret.set, false ) : ret.set;
+        if ( parts.length > 0 ) {
+          checkSet = @com.google.gwt.query.client.impl.SelectorEngineSizzle::makeArray(Lcom/google/gwt/dom/client/NodeList;Lcom/google/gwt/core/client/JsArray;)(set, null);
+        } else {
+          prune = false;
+        }
+        while ( parts.length ) {
+          var cur = parts.pop(), pop = cur;
+          if ( !$wnd.Expr.relative[ cur ] ) {
+            cur = "";
+          } else {
+            pop = parts.pop();
+          }
+          if ( pop == null ) {
+            pop = context;
+          }
+          $wnd.Expr.relative[ cur ]( checkSet, pop);
+        }
+      } else {
+        checkSet = parts = [];
+      }
+    }
+    if ( !checkSet ) {
+      checkSet = set;
+    }
+    if ( !checkSet ) {
+      @com.google.gwt.query.client.impl.SelectorEngineSizzle::error(Ljava/lang/String;)(cur || selector);
+    }
+    if ( Object.prototype.toString.call(checkSet) === "[object Array]" ) {
+      if ( !prune ) {
+        results.push.apply( results, checkSet );
+      } else if ( context && context.nodeType === 1 ) {
+        for ( var i = 0; checkSet[i] != null; i++ ) {
+          if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && @com.google.gwt.query.client.impl.SelectorEngineSizzle::contains(Ljava/lang/Object;Ljava/lang/Object;)(context, checkSet[i])) ) {
+            results.push( set[i] );
+          }
+        }
+      } else {
+        for ( var i = 0; checkSet[i] != null; i++ ) {
+          if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+            results.push( set[i] );
+          }
+        }
+      }
+    } else {
+      @com.google.gwt.query.client.impl.SelectorEngineSizzle::makeArray(Lcom/google/gwt/dom/client/NodeList;Lcom/google/gwt/core/client/JsArray;)(checkSet, results);
+    }
+    if ( extra ) {
+      @com.google.gwt.query.client.impl.SelectorEngineSizzle::select(Ljava/lang/String;Lcom/google/gwt/dom/client/Node;Lcom/google/gwt/core/client/JsArray;Lcom/google/gwt/core/client/JsArray;)(extra, origContext, results, seed);
+      @com.google.gwt.query.client.impl.SelectorEngineSizzle::unique(Lcom/google/gwt/core/client/JsArray;)(results);
+    }
+    return results;     
+   }-*/;
+  
+  public SelectorEngineSizzle() {
+    createExpr();
+  }
+  
+  public NodeList<Element> select(String selector, Node context) {
+    JsArray<Element> results = JavaScriptObject.createArray().cast();
+    return select(selector, context, results, null).cast();
+  }
+}
index 0c2e9cc054508890049a93c11cc7d5768401c6ee..99cf50ef44de11d8c89959c70789a74013eec2d1 100644 (file)
  */\r
 package com.google.gwt.query.client.impl;\r
 \r
-import com.google.gwt.core.client.GWT;\r
+import static com.google.gwt.query.client.SelectorEngine.eq;\r
+import static com.google.gwt.query.client.SelectorEngine.truth;\r
+\r
 import com.google.gwt.dom.client.Element;\r
 import com.google.gwt.dom.client.Node;\r
 import com.google.gwt.dom.client.NodeList;\r
 import com.google.gwt.query.client.JSArray;\r
 import com.google.gwt.query.client.Regexp;\r
 import com.google.gwt.query.client.SelectorEngine;\r
-import static com.google.gwt.query.client.SelectorEngine.eq;\r
-import static com.google.gwt.query.client.SelectorEngine.truth;\r
 \r
 /**\r
  * Runtime selector engine implementation which translates selectors to XPath\r
@@ -58,6 +58,8 @@ public class SelectorEngineXPath extends SelectorEngineImpl {
   private Regexp selectorSplitRegExp;\r
 \r
   private Regexp combinator;\r
+  \r
+  private SelectorEngineImpl jsEngine = null;\r
 \r
   public SelectorEngineXPath() {\r
   }\r
@@ -115,7 +117,6 @@ public class SelectorEngineXPath extends SelectorEngineImpl {
                   "[contains(concat(' ', @class, ' '), ' $1 ')]");\r
         }\r
         if (truth(splitRule.allAttr)) {\r
-          GWT.log("AllAttr is " + splitRule.allAttr, null);\r
           xPathExpression += replaceAttr(\r
               SelectorEngine.or(splitRule.allAttr, ""));\r
         }\r
@@ -139,7 +140,14 @@ public class SelectorEngineXPath extends SelectorEngineImpl {
           }\r
         }\r
       }\r
-      SelectorEngine.xpathEvaluate(xPathExpression, ctx, elm);\r
+      try {\r
+        SelectorEngine.xpathEvaluate(xPathExpression, ctx, elm).cast();  \r
+      } catch (Exception e) {\r
+        if (jsEngine == null) {\r
+          jsEngine = new SelectorEngineSizzle();\r
+        }\r
+        return jsEngine.select(sel, ctx).cast();\r
+      }\r
     }\r
     return elm;\r
   }\r
index 1d1f3c457404052a5f8c7cef464e6effc083f885..aabd8902dfc5cfb4528f2d14c11b189d893d7e50 100644 (file)
@@ -18,21 +18,131 @@ package com.google.gwt.query.client;
 import static com.google.gwt.query.client.GQuery.$;
 
 import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.Node;
+import com.google.gwt.dom.client.NodeList;
 import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.query.client.impl.SelectorEngineImpl;
+import com.google.gwt.query.client.impl.SelectorEngineSizzle;
+import com.google.gwt.query.client.impl.SelectorEngineXPath;
 import com.google.gwt.user.client.ui.HTML;
 import com.google.gwt.user.client.ui.RootPanel;
 
+/**
+ * Test for selectors
+ */
 public class GQuerySelectorsTest extends GWTTestCase {
 
-  public String getModuleName() {
-    return "com.google.gwt.query.Query";
+  public interface AllSelectors extends Selectors {
+    // @Selector("h1[id]:contains(Selectors)")
+    // NodeList<Element> h1IdContainsSelectors();
+    // @Selector("*:first")
+    // NodeList<Element> allFirst();
+    // @Selector("div[class!=madeup]")
+    // NodeList<Element> divWithClassNotContainsMadeup();
+    // @Selector("div, p a")
+    // NodeList<Element> divCommaPA();
+    // @Selector("p:contains(selectors)")
+    // NodeList<Element> pContainsSelectors();
+    @Selector("a[href][lang][class]")
+    NodeList<Element> aHrefLangClass();
+    @Selector("*:checked")
+    NodeList<Element> allChecked();
+    @Selector("body")
+    NodeList<Element> body();
+    @Selector("body div")
+    NodeList<Element> bodyDiv();
+    @Selector("div .example")
+    NodeList<Element> divExample();
+    @Selector("div > div")
+    NodeList<Element> divGtP();
+    @Selector("div:not(.example)")
+    NodeList<Element> divNotExample();
+    @Selector("div p")
+    NodeList<Element> divP();
+    @Selector("div p a")
+    NodeList<Element> divPA();
+    @Selector("div + p")
+    NodeList<Element> divPlusP();
+    @Selector("div[class^=exa][class$=mple]")
+    NodeList<Element> divPrefixExaSuffixMple();
+    @Selector("div #title")
+    NodeList<Element> divSpaceTitle();
+    @Selector("div ~ p")
+    NodeList<Element> divTildeP();
+    @Selector("div[class]")
+    NodeList<Element> divWithClass();
+    @Selector("div[class~=dialog]")
+    NodeList<Element> divWithClassContainsDialog();
+    @Selector("div[class*=e]")
+    NodeList<Element> divWithClassContainsE();
+    @Selector("div[class=example]")
+    NodeList<Element> divWithClassExample();
+    @Selector("div[class~=dialog]")
+    NodeList<Element> divWithClassListContainsDialog();
+    @Selector("div[class^=exa]")
+    NodeList<Element> divWithClassPrefixExa();
+    @Selector("div[class$=mple]")
+    NodeList<Element> divWithClassSuffixMple();
+    @Selector("p:first-child")
+    NodeList<Element> firstChild();
+    @Selector("h1#title")
+    NodeList<Element> h1Title();
+    @Selector("h1#title + em > span")
+    NodeList<Element> h1TitlePlusEmGtSpan();
+    @Selector("p:last-child")
+    NodeList<Element> lastChild();
+    @Selector(".note")
+    NodeList<Element> note();
+    @Selector("p:nth-child(n)")
+    NodeList<Element> nthChild();
+    @Selector("p:nth-child(2n)")
+    NodeList<Element> nThChild2n();
+    @Selector("p:nth-child(2n+1)")
+    NodeList<Element> nThChild2nPlus1();
+    @Selector("p:nth-child(even)")
+    NodeList<Element> nThChildEven();
+    @Selector("p:nth-child(odd)")
+    NodeList<Element> nThChildOdd();
+    @Selector("p:only-child")
+    NodeList<Element> onlyChild();
+    @Selector("#title")
+    NodeList<Element> title();
+    @Selector("#title,h1#title")
+    NodeList<Element> titleAndh1Title();
+    @Selector("ul .tocline2")
+    NodeList<Element> ulTocline2();
+    @Selector("ul.toc li.tocline2")
+    NodeList<Element> ulTocLiTocLine2();
+  }
+
+  public interface TestSelectors extends Selectors {
+    @Selector("*:checked")
+    public GQuery allChecked();
+    @Selector("*:checked")
+    public GQuery allChecked(Node n);
+    @Selector(".branchA")
+    public GQuery branchA();
+    @Selector(".branchA")
+    public GQuery branchA(Node n);
+    @Selector(".branchB")
+    public GQuery branchB();
+    @Selector(".branchB")
+    public GQuery branchB(Node n);
+    @Selector(".target")
+    public GQuery target();
+    @Selector(".target")
+    public GQuery target(Node n);
   }
 
   static Element e = null;
   static HTML testPanel = null;
 
+  public String getModuleName() {
+    return "com.google.gwt.query.Query";
+  }
+
   public void gwtSetUp() {
     if (e == null) {
       testPanel = new HTML();
@@ -44,52 +154,96 @@ public class GQuerySelectorsTest extends GWTTestCase {
     }
   }
 
-  public interface TestSelectors extends Selectors {
-    @Selector(".target")
-    public GQuery target();
+  public void testAllSelectors() {
+    final AllSelectors sel = GWT.create(AllSelectors.class);
+    $(e).html(getTestContent());
 
-    @Selector(".branchA")
-    public GQuery branchA();
+    // TODO: fix these selectors
+    // sel.h1IdContainsSelectors().getLength()
+    // sel.allFirst().getLength()
+    // sel.divWithClassNotContainsMadeup().getLength()
+    // sel.divCommaPA().getLength()
+    // sel.pContainsSelectors().getLength()
+    // assertArrayContains(sel.title().getLength(), 1);
 
-    @Selector(".branchB")
-    public GQuery branchB();
-    
-    @Selector(".target")
-    public GQuery target(Node n);
+    assertEquals(1, sel.body().getLength());
+    assertEquals(53, sel.bodyDiv().getLength());
+    sel.setRoot(e);
+    assertArrayContains(sel.aHrefLangClass().getLength(), 0, 1);
+    assertArrayContains(sel.allChecked().getLength(), 1);
+    assertArrayContains(sel.divExample().getLength(), 43);
+    assertArrayContains(sel.divGtP().getLength(), 51, 52);
+    assertArrayContains(sel.divNotExample().getLength(), 9, 10);
+    assertArrayContains(sel.divP().getLength(), 324);
+    assertArrayContains(sel.divPA().getLength(), 84);
+    assertArrayContains(sel.divPlusP().getLength(), 22);
+    assertArrayContains(sel.divPrefixExaSuffixMple().getLength(), 43);
+    assertArrayContains(sel.divSpaceTitle().getLength(), 1);
+    assertArrayContains(sel.divTildeP().getLength(), 183);
+    assertArrayContains(sel.divWithClass().getLength(), 51, 52);
+    assertArrayContains(sel.divWithClassContainsDialog().getLength(), 1);
+    assertArrayContains(sel.divWithClassContainsE().getLength(), 50);
+    assertArrayContains(sel.divWithClassExample().getLength(), 43);
+    assertArrayContains(sel.divWithClassListContainsDialog().getLength(), 1);
+    assertArrayContains(sel.divWithClassPrefixExa().getLength(), 43);
+    assertArrayContains(sel.divWithClassSuffixMple().getLength(), 43);
+    assertArrayContains(sel.firstChild().getLength(), 54);
+    assertArrayContains(sel.h1Title().getLength(), 1);
+    assertArrayContains(sel.h1TitlePlusEmGtSpan().getLength(), 1);
+    assertArrayContains(sel.lastChild().getLength(), 19);
+    assertArrayContains(sel.note().getLength(), 14);
+    assertArrayContains(sel.nthChild().getLength(), 324);
+    assertArrayContains(sel.nThChild2n().getLength(), 159);
+    assertArrayContains(sel.nThChild2nPlus1().getLength(), 165);
+    assertArrayContains(sel.nThChildEven().getLength(), 159);
+    assertArrayContains(sel.nThChildOdd().getLength(), 165);
+    assertArrayContains(sel.onlyChild().getLength(), 3);
+    assertArrayContains(sel.titleAndh1Title().getLength(), 0, 1);
+    assertArrayContains(sel.ulTocline2().getLength(), 12);
+    assertArrayContains(sel.ulTocLiTocLine2().getLength(), 12);
+  }
 
-    @Selector(".branchA")
-    public GQuery branchA(Node n);
+  public void testSelectorEngineDomAssistant() {
+    // This test runs very slow in chrome
+    // SelectorEngineImpl selEng = new SelectorEngineJS();
+    // executeSelectorEngineTests(selEng);
+  }
 
-    @Selector(".branchB")
-    public GQuery branchB(Node n);    
-    
-    @Selector("*:checked")
-    public GQuery allChecked();
-    
-    @Selector("*:checked")
-    public GQuery allChecked(Node n);
+  public void testSelectorEngineSizzle() {
+    SelectorEngineImpl selEng = new SelectorEngineSizzle();
+    executeSelectorEngineTests(selEng);
   }
-  
+
+  public void testSelectorEngineXpath() {
+    SelectorEngineImpl selEng = new SelectorEngineXPath();
+    executeSelectorEngineTests(selEng);
+  }
+
   public void testSelectorsGeneratorNative() {
-    $(e).html( "<input type='radio' name='n' value='v1'>1</input>"
-             + "<input type='radio' name='n' value='v2' checked='checked'>2</input>");
-    
+    $(e)
+        .html(
+            "<input type='radio' name='n' value='v1'>1</input>"
+                + "<input type='radio' name='n' value='v2' checked='checked'>2</input>");
+
     TestSelectors selectors = GWT.create(TestSelectors.class);
     assertEquals(1, selectors.allChecked().size());
   }
+  
 
   public void testSelectorsWithContext() {
-    $(e).append("<div class='branchA'><div class='target'>branchA target</div></div>"
-        + "<div class='branchB'><div class='target'>branchB target</div></div>");
+    $(e)
+        .append(
+            "<div class='branchA'><div class='target'>branchA target</div></div>"
+                + "<div class='branchB'><div class='target'>branchB target</div></div>");
 
     TestSelectors selectors = GWT.create(TestSelectors.class);
-    
+
     assertEquals(2, selectors.target().length());
     Element branchA = selectors.branchA().get(0);
     Element branchB = selectors.branchB().get(0);
     assertNotNull(selectors.branchA().get(0));
     assertNotNull(selectors.branchB().get(0));
-    
+
     assertEquals(2, selectors.target(RootPanel.getBodyElement()).length());
     branchA = selectors.branchA(RootPanel.getBodyElement()).get(0);
     branchB = selectors.branchB(RootPanel.getBodyElement()).get(0);
@@ -107,4 +261,1951 @@ public class GQuerySelectorsTest extends GWTTestCase {
     assertEquals("branchB target", selectors.target().text());
   }
   
+  private void assertArrayContains(Object result, Object... array) {
+    assertArrayContains("", result, array);
+  }
+  private void assertArrayContains(String message, Object result, Object... array) {
+    String values = "";
+    boolean done = false;
+    for (Object o : array) {
+      values += o.toString() + " ";
+      if (result.equals(o)){
+        done = true;
+      }
+    }
+    message = message + ", value (" + result + ") not found in: " + values;
+    assertTrue(message, done);
+  }
+
+  private void executeSelectorEngineTests(SelectorEngineImpl selEng) {
+    $(e).html(getTestContent());
+
+    assertArrayContains(selEng.select("body", Document.get()).getLength(), 1);
+    assertArrayContains(selEng.select("body div", Document.get()).getLength(), 53);
+
+    assertArrayContains(selEng.select("h1[id]:contains(Selectors)", e).getLength(), 1);
+    assertArrayContains(selEng.select("*:first", e).getLength(), 1, 0);
+    assertArrayContains(selEng.select("div[class!=madeup]", e).getLength(), 52, 53);
+    assertArrayContains(selEng.select("div, p a", e).getLength(), 136, 137, 138);
+    assertArrayContains(selEng.select("p:contains(selectors)", e).getLength(), 54, 55);
+    assertArrayContains(selEng.select("a[href][lang][class]", e).getLength(), 1);
+    assertArrayContains(selEng.select("*:checked", e).getLength(), 1);
+    assertArrayContains(selEng.select("div .example", e).getLength(), 43);
+    assertArrayContains(selEng.select("div > div", e).getLength(), 51);
+    assertArrayContains(selEng.select("div:not(.example)", e).getLength(), 9, 10);
+    assertArrayContains(selEng.select("div p", e).getLength(), 324);
+    assertArrayContains(selEng.select("div p a", e).getLength(), 85, 84);
+    assertArrayContains(selEng.select("div + p", e).getLength(), 22);
+    assertArrayContains(selEng.select("div[class^=exa][class$=mple]", e).getLength(), 43);
+    assertArrayContains(selEng.select("div #title", e).getLength(), 1);
+    assertArrayContains(selEng.select("div ~ p", e).getLength(), 183);
+    assertArrayContains(selEng.select("div[class]", e).getLength(), 51, 52);
+    assertArrayContains(selEng.select("div[class~=dialog]", e).getLength(), 1);
+    assertArrayContains(selEng.select("div[class*=e]", e).getLength(), 50);
+    assertArrayContains(selEng.select("div[class=example]", e).getLength(), 43);
+    assertArrayContains(selEng.select("div[class~=dialog]", e).getLength(), 1);
+    assertArrayContains(selEng.select("div[class^=exa]", e).getLength(), 43);
+    assertArrayContains(selEng.select("div[class$=mple]", e).getLength(), 43);
+    assertArrayContains(selEng.select("p:first-child", e).getLength(), 54);
+    assertArrayContains(selEng.select("h1#title", e).getLength(), 1);
+    assertArrayContains(selEng.select("h1#title + em > span", e).getLength(), 1);
+    assertArrayContains(selEng.select("p:last-child", e).getLength(), 19, 22);
+    assertArrayContains(selEng.select(".note", e).getLength(), 14);
+    assertArrayContains(selEng.select("p:nth-child(n)", e).getLength(), 324);
+    assertArrayContains(selEng.select("p:nth-child(2n)", e).getLength(), 159);
+    assertArrayContains(selEng.select("p:nth-child(2n+1)", e).getLength(), 165);
+    assertArrayContains(selEng.select("p:nth-child(even)", e).getLength(), 159);
+    assertArrayContains(selEng.select("p:nth-child(odd)", e).getLength(), 165);
+    assertArrayContains(selEng.select("p:only-child", e).getLength(), 3);
+    assertArrayContains(selEng.select("#title", e).getLength(), 1);
+    assertArrayContains(selEng.select("#title, h1#title", e).getLength(), 2);
+    assertArrayContains(selEng.select("ul.toc li.tocline2", e).getLength(), 12);    
+    assertArrayContains(selEng.select("h1[id]:contains(Selectors)", e).getLength(),  1);
+  }
+
+  // This method is used to initialize a huge html String, because
+  // java 1.5 has a limitation in the size of static strings.
+  private String getTestContent() {
+    String test_content = "";
+    test_content += "<html><head>      </head><body><div>";
+    test_content += "      <div class='head dialog'>";
+    test_content += "          <p><a href='http://www.w3.org/'><img alt='W3C' src='' height='48' width='72'></a></p>";
+    test_content += "          <h1 id='title'>Selectors</h1>";
+    test_content += "          <em><span>.</span></em>";
+    test_content += "          <h2>W3C Working Draft 15 December 2005</h2>";
+    test_content += "          <dl>";
+    test_content += "              <dt>This version:</dt>";
+    test_content += "              <dd><a href='http://www.w3.org/TR/2005/WD-css3-selectors-20051215'>";
+    test_content += "                  http://www.w3.org/TR/2005/WD-css3-selectors-20051215</a></dd>";
+    test_content += "              <dt>Latest version:";
+    test_content += "              </dt><dd><a href='http://www.w3.org/TR/css3-selectors'>";
+    test_content += "                  http://www.w3.org/TR/css3-selectors</a>";
+    test_content += "              </dd><dt>Previous version:";
+    test_content += "              </dt><dd><a href='http://www.w3.org/TR/2001/CR-css3-selectors-20011113'>";
+    test_content += "                  http://www.w3.org/TR/2001/CR-css3-selectors-20011113</a>";
+    test_content += "              </dd><dt><a name='editors-list'></a>Editors:";
+    test_content += "              </dt><dd class='vcard'><span class='fn'>Daniel Glazman</span> (Invited";
+    test_content += "              </dd>";
+    test_content += "              <dd class='vcard'><a class='url fn' href='http://www.tantek.com/' lang='tr'>Tantek Çelik</a>";
+    test_content += "              </dd><dd class='vcard'><a href='mailto:ian@hixie.ch' class='url fn'>Ian";
+    test_content += "                  Hickson</a> (<span class='company'><a href='http://www.google.com/'>Google</a></span>)";
+    test_content += "              </dd><dd class='vcard'><span class='fn'>Peter Linss</span> (former";
+    test_content += "                  editor, <span class='company'><a href='http://www.netscape.com/'>Netscape/AOL</a></span>)";
+    test_content += "              </dd><dd class='vcard'><span class='fn'>John Williams</span> (former editor, <span class='company'><a href='http://www.quark.com/'>Quark, Inc.</a></span>)";
+    test_content += "          </dd></dl>";
+    test_content += "          <p class='copyright'><a href='http://www.w3.org/Consortium/Legal/ipr-notice#Copyright'>";
+    test_content += "              Copyright</a> © 2005 <a href='http://www.w3.org/'><abbr title='World Wide Web Consortium'>W3C</abbr></a><sup>®</sup>";
+    test_content += "              (<a href='http://www.csail.mit.edu/'><abbr title='Massachusetts";
+    test_content += "         Institute of Technology'>MIT</abbr></a>, <a href='http://www.ercim.org/'><acronym title='European Research";
+    test_content += "         Consortium for Informatics and Mathematics'>ERCIM</acronym></a>, <a href='http://www.keio.ac.jp/'>Keio</a>), All Rights Reserved.";
+    test_content += "              <a href='http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer'>liability</a>,";
+    test_content += "              <a href='http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks'>trademark</a>,";
+    test_content += "              <a href='http://www.w3.org/Consortium/Legal/copyright-documents'>document";
+    test_content += "                  use</a> rules apply.";
+    test_content += "          </p><hr title='Separator for header'>";
+    test_content += "      </div>";
+    test_content += "      <h2><a name='abstract'></a>Abstract</h2>";
+    test_content += "      <p><em>Selectors</em> are patterns that match against elements in a";
+    test_content += "          tree. Selectors have been optimized for use with HTML and XML, and";
+    test_content += "          are designed to be usable in performance-critical code.</p>";
+    test_content += "      <p><acronym title='Cascading Style Sheets'>CSS</acronym> (Cascading";
+    test_content += "          Style Sheets) is a language for describing the rendering of <acronym title='Hypertext Markup Language'>HTML</acronym> and <acronym title='Extensible Markup Language'>XML</acronym> documents on";
+    test_content += "          screen, on paper, in speech, etc. CSS uses Selectors for binding";
+    test_content += "          describes extensions to the selectors defined in CSS level 2. These";
+    test_content += "          extended selectors will be used by CSS level 3.";
+    test_content += "      </p><p>Selectors define the following function:</p>";
+    test_content += "      <pre>expression ∗ element → boolean</pre>";
+    test_content += "      <p>That is, given an element and a selector, this specification";
+    test_content += "          defines whether that element matches the selector.</p>";
+    test_content += "      <p>These expressions can also be used, for instance, to select a set";
+    test_content += "          subtree. <acronym title='Simple Tree Transformation";
+    test_content += "        Sheets'>STTS</acronym> (Simple Tree Transformation Sheets), a";
+    test_content += "          language for transforming XML trees, uses this mechanism. <a href='#refsSTTS'>[STTS]</a></p>";
+    test_content += "      <h2><a name='status'></a>Status of this document</h2>";
+    test_content += "      <p><em>This section describes the status of this document at the";
+    test_content += "          of this technical report can be found in the <a href='http://www.w3.org/TR/'>W3C technical reports index at";
+    test_content += "              http://www.w3.org/TR/.</a></em></p>";
+    test_content += "      <p>This document describes the selectors that already exist in <a href='#refsCSS1'><abbr title='CSS level 1'>CSS1</abbr></a> and <a href='#refsCSS21'><abbr title='CSS level 2'>CSS2</abbr></a>, and";
+    test_content += "          also proposes new selectors for <abbr title='CSS level";
+    test_content += "        3'>CSS3</abbr> and other languages that may need them.</p>";
+    test_content += "      <p>The CSS Working Group doesn't expect that all implementations of";
+    test_content += "          CSS3 will have to implement all selectors. Instead, there will";
+    test_content += "          will include all of the selectors.</p>";
+    test_content += "      <p>This specification is a last call working draft for the the <a href='http://www.w3.org/Style/CSS/members'>CSS Working Group</a>";
+    test_content += "          (<a href='/Style/'>Style Activity</a>). This";
+    test_content += "          document is a revision of the <a href='http://www.w3.org/TR/2001/CR-css3-selectors-20011113/'>Candidate";
+    test_content += "              Recommendation dated 2001 November 13</a>, and has incorporated";
+    test_content += "          be demonstrable.</p>";
+    test_content += "      <p>All persons are encouraged to review and implement this";
+    test_content += "          specification and return comments to the (<a href='http://lists.w3.org/Archives/Public/www-style/'>archived</a>)";
+    test_content += "          public mailing list <a href='http://www.w3.org/Mail/Lists.html#www-style'>www-style</a>";
+    test_content += "          (see <a href='http://www.w3.org/Mail/Request'>instructions</a>). W3C";
+    test_content += "          The deadline for comments is 14 January 2006.</p>";
+    test_content += "      <p>This is still a draft document and may be updated, replaced, or";
+    test_content += "      </p><p>This document may be available in <a href='http://www.w3.org/Style/css3-selectors-updates/translations'>translation</a>.";
+    test_content += "      </p><div class='subtoc'>";
+    test_content += "          <h2><a name='contents'>Table of contents</a></h2>";
+    test_content += "          <ul class='toc'>";
+    test_content += "              <li class='tocline2'><a href='#context'>1. Introduction</a>";
+    test_content += "                  <ul>";
+    test_content += "                      <li><a href='#dependencies'>1.1. Dependencies</a></li>";
+    test_content += "                      <li><a href='#terminology'>1.2. Terminology</a></li>";
+    test_content += "                      <li><a href='#changesFromCSS2'>1.3. Changes from CSS2</a></li>";
+    test_content += "                  </ul>";
+    test_content += "              </li><li class='tocline2'><a href='#selectors'>2. Selectors</a>";
+    test_content += "              </li><li class='tocline2'><a href='#casesens'>3. Case sensitivity</a>";
+    test_content += "              </li><li class='tocline2'><a href='#selector-syntax'>4. Selector syntax</a>";
+    test_content += "              </li><li class='tocline2'><a href='#grouping'>5. Groups of selectors</a>";
+    test_content += "              </li><li class='tocline2'><a href='#simple-selectors'>6. Simple selectors</a>";
+    test_content += "                  <ul class='toc'>";
+    test_content += "                      <li class='tocline3'><a href='#type-selectors'>6.1. Type";
+    test_content += "                          selectors</a>";
+    test_content += "                          <ul class='toc'>";
+    test_content += "                              <li class='tocline4'><a href='#typenmsp'>6.1.1. Type";
+    test_content += "                                  selectors and namespaces</a></li>";
+    test_content += "                          </ul>";
+    test_content += "                      </li><li class='tocline3'><a href='#universal-selector'>6.2.";
+    test_content += "                          Universal selector</a>";
+    test_content += "                          <ul>";
+    test_content += "                              <li><a href='#univnmsp'>6.2.1. Universal selector and";
+    test_content += "                                  namespaces</a></li>";
+    test_content += "                          </ul>";
+    test_content += "                      </li><li class='tocline3'><a href='#attribute-selectors'>6.3.";
+    test_content += "                          Attribute selectors</a>";
+    test_content += "                          <ul class='toc'>";
+    test_content += "                              <li class='tocline4'><a href='#attribute-representation'>6.3.1.";
+    test_content += "                                  values</a>";
+    test_content += "                              </li><li><a href='#attribute-substrings'>6.3.2. Substring";
+    test_content += "                                  matching attribute selectors</a>";
+    test_content += "                              </li><li class='tocline4'><a href='#attrnmsp'>6.3.3.";
+    test_content += "                                  Attribute selectors and namespaces</a>";
+    test_content += "                              </li><li class='tocline4'><a href='#def-values'>6.3.4.";
+    test_content += "                                  Default attribute values in DTDs</a></li>";
+    test_content += "                          </ul>";
+    test_content += "                      </li><li class='tocline3'><a href='#class-html'>6.4. Class";
+    test_content += "                          selectors</a>";
+    test_content += "                      </li><li class='tocline3'><a href='#id-selectors'>6.5. ID";
+    test_content += "                          selectors</a>";
+    test_content += "                      </li><li class='tocline3'><a href='#pseudo-classes'>6.6.";
+    test_content += "                          Pseudo-classes</a>";
+    test_content += "                          <ul class='toc'>";
+    test_content += "                              <li class='tocline4'><a href='#dynamic-pseudos'>6.6.1.";
+    test_content += "                                  Dynamic pseudo-classes</a>";
+    test_content += "                              </li><li class='tocline4'><a href='#target-pseudo'>6.6.2. The";
+    test_content += "                                  :target pseudo-class</a>";
+    test_content += "                              </li><li class='tocline4'><a href='#lang-pseudo'>6.6.3. The";
+    test_content += "                                  :lang() pseudo-class</a>";
+    test_content += "                              </li><li class='tocline4'><a href='#UIstates'>6.6.4. UI";
+    test_content += "                                  element states pseudo-classes</a>";
+    test_content += "                              </li><li class='tocline4'><a href='#structural-pseudos'>6.6.5.";
+    test_content += "                                  Structural pseudo-classes</a>";
+    test_content += "                                  <ul>";
+    test_content += "                                      <li><a href='#root-pseudo'>:root";
+    test_content += "                                          pseudo-class</a>";
+    test_content += "                                      </li><li><a href='#nth-child-pseudo'>:nth-child()";
+    test_content += "                                          pseudo-class</a>";
+    test_content += "                                      </li><li><a href='#nth-last-child-pseudo'>:nth-last-child()</a>";
+    test_content += "                                      </li><li><a href='#nth-of-type-pseudo'>:nth-of-type()";
+    test_content += "                                          pseudo-class</a>";
+    test_content += "                                      </li><li><a href='#nth-last-of-type-pseudo'>:nth-last-of-type()</a>";
+    test_content += "                                      </li><li><a href='#first-child-pseudo'>:first-child";
+    test_content += "                                          pseudo-class</a>";
+    test_content += "                                      </li><li><a href='#last-child-pseudo'>:last-child";
+    test_content += "                                          pseudo-class</a>";
+    test_content += "                                      </li><li><a href='#first-of-type-pseudo'>:first-of-type";
+    test_content += "                                          pseudo-class</a>";
+    test_content += "                                      </li><li><a href='#last-of-type-pseudo'>:last-of-type";
+    test_content += "                                          pseudo-class</a>";
+    test_content += "                                      </li><li><a href='#only-child-pseudo'>:only-child";
+    test_content += "                                          pseudo-class</a>";
+    test_content += "                                      </li><li><a href='#only-of-type-pseudo'>:only-of-type";
+    test_content += "                                          pseudo-class</a>";
+    test_content += "                                      </li><li><a href='#empty-pseudo'>:empty";
+    test_content += "                                          pseudo-class</a></li>";
+    test_content += "                                  </ul>";
+    test_content += "                              </li><li class='tocline4'><a href='#negation'>6.6.7. The";
+    test_content += "                                  negation pseudo-class</a></li>";
+    test_content += "                          </ul>";
+    test_content += "                      </li>";
+    test_content += "                  </ul>";
+    test_content += "              </li><li><a href='#pseudo-elements'>7. Pseudo-elements</a>";
+    test_content += "                  <ul>";
+    test_content += "                      <li><a href='#first-line'>7.1. The ::first-line";
+    test_content += "                          pseudo-element</a>";
+    test_content += "                      </li><li><a href='#first-letter'>7.2. The ::first-letter";
+    test_content += "                          pseudo-element</a>";
+    test_content += "                      </li><li><a href='#UIfragments'>7.3. The ::selection";
+    test_content += "                          pseudo-element</a>";
+    test_content += "                      </li><li><a href='#gen-content'>7.4. The ::before and ::after";
+    test_content += "                          pseudo-elements</a></li>";
+    test_content += "                  </ul>";
+    test_content += "              </li><li class='tocline2'><a href='#combinators'>8. Combinators</a>";
+    test_content += "                  <ul class='toc'>";
+    test_content += "                      <li class='tocline3'><a href='#descendant-combinators'>8.1.";
+    test_content += "                          Descendant combinators</a>";
+    test_content += "                      </li><li class='tocline3'><a href='#child-combinators'>8.2. Child";
+    test_content += "                          combinators</a>";
+    test_content += "                      </li><li class='tocline3'><a href='#sibling-combinators'>8.3. Sibling";
+    test_content += "                          combinators</a>";
+    test_content += "                          <ul class='toc'>";
+    test_content += "                              <li class='tocline4'><a href='#adjacent-sibling-combinators'>8.3.1.";
+    test_content += "                                  Adjacent sibling combinator</a>";
+    test_content += "                              </li><li class='tocline4'><a href='#general-sibling-combinators'>8.3.2.";
+    test_content += "                                  General sibling combinator</a></li>";
+    test_content += "                          </ul>";
+    test_content += "                      </li>";
+    test_content += "                  </ul>";
+    test_content += "              </li><li class='tocline2'><a href='#specificity'>9. Calculating a selector's";
+    test_content += "                  specificity</a>";
+    test_content += "              </li><li class='tocline2'><a href='#w3cselgrammar'>10. The grammar of";
+    test_content += "                  Selectors</a>";
+    test_content += "                  <ul class='toc'>";
+    test_content += "                      <li class='tocline3'><a href='#grammar'>10.1. Grammar</a>";
+    test_content += "                      </li><li class='tocline3'><a href='#lex'>10.2. Lexical scanner</a>";
+    test_content += "                      </li>";
+    test_content += "                  </ul>";
+    test_content += "              </li><li class='tocline2'><a href='#downlevel'>11. Namespaces and down-level";
+    test_content += "                  clients</a>";
+    test_content += "              </li><li class='tocline2'><a href='#profiling'>12. Profiles</a>";
+    test_content += "              </li><li><a href='#Conformance'>13. Conformance and requirements</a>";
+    test_content += "              </li><li><a href='#Tests'>14. Tests</a>";
+    test_content += "              </li><li><a href='#ACKS'>15. Acknowledgements</a>";
+    test_content += "              </li><li class='tocline2'><a href='#references'>16. References</a>";
+    test_content += "          </li></ul>";
+    test_content += "      </div>";
+    test_content += "      <h2><a name='context'>1. Introduction</a></h2>";
+    test_content += "      <h3><a name='dependencies'></a>1.1. Dependencies</h3>";
+    test_content += "      <p>Some features of this specification are specific to CSS, or have";
+    test_content += "          specification, these have been described in terms of CSS2.1. <a href='#refsCSS21'>[CSS21]</a></p>";
+    test_content += "      <h3><a name='terminology'></a>1.2. Terminology</h3>";
+    test_content += "      <p>All of the text of this specification is normative except";
+    test_content += "          non-normative.</p>";
+    test_content += "      <h3><a name='changesFromCSS2'></a>1.3. Changes from CSS2</h3>";
+    test_content += "      <p><em>This section is non-normative.</em></p>";
+    test_content += "      <p>The main differences between the selectors in CSS2 and those in";
+    test_content += "          Selectors are:";
+    test_content += "      </p><ul>";
+    test_content += "          <li>the list of basic definitions (selector, group of selectors,";
+    test_content += "              of simple selectors, and the term 'simple selector' is now used for";
+    test_content += "          </li>";
+    test_content += "          <li>an optional namespace component is now allowed in type element";
+    test_content += "              selectors, the universal selector and attribute selectors";
+    test_content += "          </li>";
+    test_content += "          <li>a <a href='#general-sibling-combinators'>new combinator</a> has been";
+    test_content += "          </li>";
+    test_content += "          <li>new simple selectors including substring matching attribute";
+    test_content += "              selectors, and new pseudo-classes";
+    test_content += "          </li>";
+    test_content += "          <li>new pseudo-elements, and introduction of the '::' convention";
+    test_content += "          </li>";
+    test_content += "          <li>the grammar has been rewritten</li>";
+    test_content += "          <li>profiles to be added to specifications integrating Selectors";
+    test_content += "              and defining the set of selectors which is actually supported by";
+    test_content += "          </li>";
+    test_content += "          <li>Selectors are now a CSS3 Module and an independent";
+    test_content += "          </li>";
+    test_content += "          <li>the specification now has its own test suite</li>";
+    test_content += "      </ul>";
+    test_content += "      <h2><a name='selectors'></a>2. Selectors</h2>";
+    test_content += "      <p><em>This section is non-normative, as it merely summarizes the";
+    test_content += "          following sections.</em></p>";
+    test_content += "      <p>A Selector represents a structure. This structure can be used as a";
+    test_content += "          HTML or XML fragment corresponding to that structure.</p>";
+    test_content += "      <p>Selectors may range from simple element names to rich contextual";
+    test_content += "          representations.</p>";
+    test_content += "      <p>The following table summarizes the Selector syntax:</p>";
+    test_content += "      <table class='selectorsReview'>";
+    test_content += "      <thead>";
+    test_content += "      <tr>";
+    test_content += "          <th class='pattern'>Pattern</th>";
+    test_content += "          <th class='meaning'>Meaning</th>";
+    test_content += "          <th class='described'>Described in section</th>";
+    test_content += "          <th class='origin'>First defined in CSS level</th>";
+    test_content += "      </tr>";
+    test_content += "      </thead><tbody>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>*</td>";
+    test_content += "          <td class='meaning'>any element</td>";
+    test_content += "          <td class='described'><a href='#universal-selector'>Universal";
+    test_content += "              selector</a></td>";
+    test_content += "          <td class='origin'>2</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E</td>";
+    test_content += "          <td class='meaning'>an element of type E</td>";
+    test_content += "          <td class='described'><a href='#type-selectors'>Type selector</a></td>";
+    test_content += "          <td class='origin'>1</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E[foo]</td>";
+    test_content += "          <td class='meaning'>an E element with a 'foo' attribute</td>";
+    test_content += "          <td class='described'><a href='#attribute-selectors'>Attribute";
+    test_content += "              selectors</a></td>";
+    test_content += "          <td class='origin'>2</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E[foo='bar']</td>";
+    test_content += "          <td class='meaning'>an E element whose 'foo' attribute value is exactly";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#attribute-selectors'>Attribute";
+    test_content += "              selectors</a></td>";
+    test_content += "          <td class='origin'>2</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E[foo~='bar']</td>";
+    test_content += "          <td class='meaning'>an E element whose 'foo' attribute value is a list of";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#attribute-selectors'>Attribute";
+    test_content += "              selectors</a></td>";
+    test_content += "          <td class='origin'>2</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E[foo^='bar']</td>";
+    test_content += "          <td class='meaning'>an E element whose 'foo' attribute value begins exactly";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#attribute-selectors'>Attribute";
+    test_content += "              selectors</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E[foo$='bar']</td>";
+    test_content += "          <td class='meaning'>an E element whose 'foo' attribute value ends exactly";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#attribute-selectors'>Attribute";
+    test_content += "              selectors</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E[foo*='bar']</td>";
+    test_content += "          <td class='meaning'>an E element whose 'foo' attribute value contains the";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#attribute-selectors'>Attribute";
+    test_content += "              selectors</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E[hreflang|='en']</td>";
+    test_content += "          <td class='meaning'>an E element whose 'hreflang' attribute has a";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#attribute-selectors'>Attribute";
+    test_content += "              selectors</a></td>";
+    test_content += "          <td class='origin'>2</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:root</td>";
+    test_content += "          <td class='meaning'>an E element, root of the document</td>";
+    test_content += "          <td class='described'><a href='#structural-pseudos'>Structural";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:nth-child(n)</td>";
+    test_content += "          <td class='meaning'>an E element, the n-th child of its parent</td>";
+    test_content += "          <td class='described'><a href='#structural-pseudos'>Structural";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:nth-last-child(n)</td>";
+    test_content += "          <td class='meaning'>an E element, the n-th child of its parent, counting";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#structural-pseudos'>Structural";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:nth-of-type(n)</td>";
+    test_content += "          <td class='meaning'>an E element, the n-th sibling of its type</td>";
+    test_content += "          <td class='described'><a href='#structural-pseudos'>Structural";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:nth-last-of-type(n)</td>";
+    test_content += "          <td class='meaning'>an E element, the n-th sibling of its type, counting";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#structural-pseudos'>Structural";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:first-child</td>";
+    test_content += "          <td class='meaning'>an E element, first child of its parent</td>";
+    test_content += "          <td class='described'><a href='#structural-pseudos'>Structural";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>2</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:last-child</td>";
+    test_content += "          <td class='meaning'>an E element, last child of its parent</td>";
+    test_content += "          <td class='described'><a href='#structural-pseudos'>Structural";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:first-of-type</td>";
+    test_content += "          <td class='meaning'>an E element, first sibling of its type</td>";
+    test_content += "          <td class='described'><a href='#structural-pseudos'>Structural";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:last-of-type</td>";
+    test_content += "          <td class='meaning'>an E element, last sibling of its type</td>";
+    test_content += "          <td class='described'><a href='#structural-pseudos'>Structural";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:only-child</td>";
+    test_content += "          <td class='meaning'>an E element, only child of its parent</td>";
+    test_content += "          <td class='described'><a href='#structural-pseudos'>Structural";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:only-of-type</td>";
+    test_content += "          <td class='meaning'>an E element, only sibling of its type</td>";
+    test_content += "          <td class='described'><a href='#structural-pseudos'>Structural";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:empty</td>";
+    test_content += "          <td class='meaning'>an E element that has no children (including text";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#structural-pseudos'>Structural";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:link<br>E:visited</td>";
+    test_content += "          <td class='meaning'>an E element being the source anchor of a hyperlink of";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#link'>The link";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>1</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:active<br>E:hover<br>E:focus</td>";
+    test_content += "          <td class='meaning'>an E element during certain user actions</td>";
+    test_content += "          <td class='described'><a href='#useraction-pseudos'>The user";
+    test_content += "              action pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>1 and 2</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:target</td>";
+    test_content += "          <td class='meaning'>an E element being the target of the referring URI</td>";
+    test_content += "          <td class='described'><a href='#target-pseudo'>The target";
+    test_content += "              pseudo-class</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:lang(fr)</td>";
+    test_content += "          <td class='meaning'>an element of type E in language 'fr' (the document";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#lang-pseudo'>The :lang()";
+    test_content += "              pseudo-class</a></td>";
+    test_content += "          <td class='origin'>2</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:enabled<br>E:disabled</td>";
+    test_content += "          <td class='meaning'>a user interface element E which is enabled or";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#UIstates'>The UI element states";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:checked<!--<br>E:indeterminate--></td>";
+    test_content += "          <td class='meaning'>a user interface element E which is checked<!-- or in an";
+    test_content += "            indeterminate state--> (for instance a radio-button or checkbox)";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#UIstates'>The UI element states";
+    test_content += "              pseudo-classes</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E::first-line</td>";
+    test_content += "          <td class='meaning'>the first formatted line of an E element</td>";
+    test_content += "          <td class='described'><a href='#first-line'>The ::first-line";
+    test_content += "              pseudo-element</a></td>";
+    test_content += "          <td class='origin'>1</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E::first-letter</td>";
+    test_content += "          <td class='meaning'>the first formatted letter of an E element</td>";
+    test_content += "          <td class='described'><a href='#first-letter'>The ::first-letter";
+    test_content += "              pseudo-element</a></td>";
+    test_content += "          <td class='origin'>1</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E::selection</td>";
+    test_content += "          <td class='meaning'>the portion of an E element that is currently";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#UIfragments'>The UI element";
+    test_content += "              fragments pseudo-elements</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E::before</td>";
+    test_content += "          <td class='meaning'>generated content before an E element</td>";
+    test_content += "          <td class='described'><a href='#gen-content'>The ::before";
+    test_content += "              pseudo-element</a></td>";
+    test_content += "          <td class='origin'>2</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E::after</td>";
+    test_content += "          <td class='meaning'>generated content after an E element</td>";
+    test_content += "          <td class='described'><a href='#gen-content'>The ::after";
+    test_content += "              pseudo-element</a></td>";
+    test_content += "          <td class='origin'>2</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E.warning</td>";
+    test_content += "          <td class='meaning'>an E element whose class is";
+    test_content += "          </td>";
+    test_content += "          <td class='described'><a href='#class-html'>Class";
+    test_content += "              selectors</a></td>";
+    test_content += "          <td class='origin'>1</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E#myid</td>";
+    test_content += "          <td class='meaning'>an E element with ID equal to 'myid'.</td>";
+    test_content += "          <td class='described'><a href='#id-selectors'>ID";
+    test_content += "              selectors</a></td>";
+    test_content += "          <td class='origin'>1</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E:not(s)</td>";
+    test_content += "          <td class='meaning'>an E element that does not match simple selector s</td>";
+    test_content += "          <td class='described'><a href='#negation'>Negation";
+    test_content += "              pseudo-class</a></td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E F</td>";
+    test_content += "          <td class='meaning'>an F element descendant of an E element</td>";
+    test_content += "          <td class='described'><a href='#descendant-combinators'>Descendant";
+    test_content += "              combinator</a></td>";
+    test_content += "          <td class='origin'>1</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E &gt; F</td>";
+    test_content += "          <td class='meaning'>an F element child of an E element</td>";
+    test_content += "          <td class='described'><a href='#child-combinators'>Child";
+    test_content += "              combinator</a></td>";
+    test_content += "          <td class='origin'>2</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E + F</td>";
+    test_content += "          <td class='meaning'>an F element immediately preceded by an E element</td>";
+    test_content += "          <td class='described'><a href='#adjacent-sibling-combinators'>Adjacent sibling combinator</a>";
+    test_content += "          </td>";
+    test_content += "          <td class='origin'>2</td>";
+    test_content += "      </tr>";
+    test_content += "      <tr>";
+    test_content += "          <td class='pattern'>E ~ F</td>";
+    test_content += "          <td class='meaning'>an F element preceded by an E element</td>";
+    test_content += "          <td class='described'><a href='#general-sibling-combinators'>General sibling combinator</a>";
+    test_content += "          </td>";
+    test_content += "          <td class='origin'>3</td>";
+    test_content += "      </tr>";
+    test_content += "      </tbody>";
+    test_content += "      </table>";
+    test_content += "      <p>The meaning of each selector is derived from the table above by";
+    test_content += "          column.</p>";
+    test_content += "      <h2><a name='casesens'>3. Case sensitivity</a></h2>";
+    test_content += "      <p>The case sensitivity of document language element names, attribute";
+    test_content += "          names, and attribute values in selectors depends on the document";
+    test_content += "          but in XML, they are case-sensitive.</p>";
+    test_content += "      <h2><a name='selector-syntax'>4. Selector syntax</a></h2>";
+    test_content += "      <p>A <dfn><a name='selector'>selector</a></dfn> is a chain of one";
+    test_content += "          or more <a href='#sequence'>sequences of simple selectors</a>";
+    test_content += "          separated by <a href='#combinators'>combinators</a>.</p>";
+    test_content += "      <p>A <dfn><a name='sequence'>sequence of simple selectors</a></dfn>";
+    test_content += "          is a chain of <a href='#simple-selectors-dfn'>simple selectors</a>";
+    test_content += "          that are not separated by a <a href='#combinators'>combinator</a>. It";
+    test_content += "          always begins with a <a href='#type-selectors'>type selector</a> or a";
+    test_content += "          <a href='#universal-selector'>universal selector</a>. No other type";
+    test_content += "          selector or universal selector is allowed in the sequence.</p>";
+    test_content += "      <p>A <dfn><a name='simple-selectors-dfn'></a><a href='#simple-selectors'>simple selector</a></dfn> is either a <a href='#type-selectors'>type selector</a>, <a href='#universal-selector'>universal selector</a>, <a href='#attribute-selectors'>attribute selector</a>, <a href='#class-html'>class selector</a>, <a href='#id-selectors'>ID selector</a>, <a href='#content-selectors'>content selector</a>, or <a href='#pseudo-classes'>pseudo-class</a>. One <a href='#pseudo-elements'>pseudo-element</a> may be appended to the last";
+    test_content += "          sequence of simple selectors.</p>";
+    test_content += "      <p><dfn>Combinators</dfn> are: white space, 'greater-than";
+    test_content += "          sign' (U+003E, <code>&gt;</code>), 'plus sign' (U+002B,";
+    test_content += "          <code>+</code>) and 'tilde' (U+007E, <code>~</code>). White";
+    test_content += "          space may appear between a combinator and the simple selectors around";
+    test_content += "          it. <a name='whitespace'></a>Only the characters 'space' (U+0020), 'tab'";
+    test_content += "          never part of white space.</p>";
+    test_content += "      <p>The elements of a document tree that are represented by a selector";
+    test_content += "          are the <dfn><a name='subject'></a>subjects of the selector</dfn>. A";
+    test_content += "          selector consisting of a single sequence of simple selectors";
+    test_content += "          sequence of simple selectors and a combinator to a sequence imposes";
+    test_content += "          simple selectors.</p>";
+    test_content += "      <p>An empty selector, containing no sequence of simple selectors and";
+    test_content += "          no pseudo-element, is an <a href='#Conformance'>invalid";
+    test_content += "              selector</a>.</p>";
+    test_content += "      <h2><a name='grouping'>5. Groups of selectors</a></h2>";
+    test_content += "      <p>When several selectors share the same declarations, they may be";
+    test_content += "          grouped into a comma-separated list. (A comma is U+002C.)</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>CSS examples:</p>";
+    test_content += "          <p>In this example, we condense three rules with identical";
+    test_content += "              declarations into one. Thus,</p>";
+    test_content += "      <pre>h1 { font-family: sans-serif }";
+    test_content += "      h3 { font-family: sans-serif }</pre>";
+    test_content += "          <p>is equivalent to:</p>";
+    test_content += "          <pre>h1, h2, h3 { font-family: sans-serif }</pre>";
+    test_content += "      </div>";
+    test_content += "      <p><strong>Warning</strong>: the equivalence is true in this example";
+    test_content += "          because all the selectors are valid selectors. If just one of these";
+    test_content += "          selectors were invalid, the entire group of selectors would be";
+    test_content += "          heading rules would be invalidated.</p>";
+    test_content += "      <h2><a name='simple-selectors'>6. Simple selectors</a></h2>";
+    test_content += "      <h3><a name='type-selectors'>6.1. Type selector</a></h3>";
+    test_content += "      <p>A <dfn>type selector</dfn> is the name of a document language";
+    test_content += "          type in the document tree.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <p>The following selector represents an <code>h1</code> element in the";
+    test_content += "              document tree:</p>";
+    test_content += "          <pre>h1</pre>";
+    test_content += "      </div>";
+    test_content += "      <h4><a name='typenmsp'>6.1.1. Type selectors and namespaces</a></h4>";
+    test_content += "      <p>Type selectors allow an optional namespace (<a href='#refsXMLNAMES'>[XMLNAMES]</a>) component. A namespace prefix";
+    test_content += "          (U+007C, <code>|</code>).</p>";
+    test_content += "      <p>The namespace component may be left empty to indicate that the";
+    test_content += "          selector is only to represent elements with no declared namespace.</p>";
+    test_content += "      <p>An asterisk may be used for the namespace prefix, indicating that";
+    test_content += "          with no namespace).</p>";
+    test_content += "      <p>Element type selectors that have no namespace component (no";
+    test_content += "          element's namespace (equivalent to '<code>*|</code>') unless a default";
+    test_content += "          namespace.</p>";
+    test_content += "      <p>A type selector containing a namespace prefix that has not been";
+    test_content += "          previously declared is an <a href='#Conformance'>invalid</a> selector.";
+    test_content += "          language implementing Selectors. In CSS, such a mechanism is defined";
+    test_content += "          in the General Syntax module.</p>";
+    test_content += "      <p>In a namespace-aware client, element type selectors will only match";
+    test_content += "          against the <a href='http://www.w3.org/TR/REC-xml-names/#NT-LocalPart'>local";
+    test_content += "              part</a>";
+    test_content += "          of the element's <a href='http://www.w3.org/TR/REC-xml-names/#ns-qualnames'>qualified";
+    test_content += "              name</a>. See <a href='#downlevel'>below</a> for notes about matching";
+    test_content += "          behaviors in down-level clients.</p>";
+    test_content += "      <p>In summary:</p>";
+    test_content += "      <dl>";
+    test_content += "          <dt><code>ns|E</code></dt>";
+    test_content += "          <dd>elements with name E in namespace ns</dd>";
+    test_content += "          <dt><code>*|E</code></dt>";
+    test_content += "          <dd>elements with name E in any namespace, including those without any";
+    test_content += "          </dd>";
+    test_content += "          <dt><code>|E</code></dt>";
+    test_content += "          <dd>elements with name E without any declared namespace</dd>";
+    test_content += "          <dt><code>E</code></dt>";
+    test_content += "          <dd>if no default namespace has been specified, this is equivalent to *|E.";
+    test_content += "          </dd>";
+    test_content += "      </dl>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>CSS examples:</p>";
+    test_content += "       <pre>@namespace foo url(http://www.example.com);";
+    test_content += "       h1 { color: green }</pre>";
+    test_content += "          <p>The first rule will match only <code>h1</code> elements in the";
+    test_content += "              'http://www.example.com' namespace.</p>";
+    test_content += "          <p>The second rule will match all elements in the";
+    test_content += "              'http://www.example.com' namespace.</p>";
+    test_content += "          <p>The third rule will match only <code>h1</code> elements without";
+    test_content += "              any declared namespace.</p>";
+    test_content += "          <p>The fourth rule will match <code>h1</code> elements in any";
+    test_content += "              namespace (including those without any declared namespace).</p>";
+    test_content += "          <p>The last rule is equivalent to the fourth rule because no default";
+    test_content += "              namespace has been defined.</p>";
+    test_content += "      </div>";
+    test_content += "      <h3><a name='universal-selector'>6.2. Universal selector</a></h3>";
+    test_content += "      <p>The <dfn>universal selector</dfn>, written 'asterisk'";
+    test_content += "          (<code>*</code>), represents the qualified name of any element";
+    test_content += "          specified, see <a href='#univnmsp'>Universal selector and";
+    test_content += "              Namespaces</a> below.</p>";
+    test_content += "      <p>If the universal selector is not the only component of a sequence";
+    test_content += "          of simple selectors, the <code>*</code> may be omitted.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <ul>";
+    test_content += "              <li><code>*[hreflang|=en]</code> and <code>[hreflang|=en]</code> are";
+    test_content += "              </li>";
+    test_content += "              <li><code>*.warning</code> and <code>.warning</code> are equivalent,";
+    test_content += "              </li>";
+    test_content += "              <li><code>*#myid</code> and <code>#myid</code> are equivalent.</li>";
+    test_content += "          </ul>";
+    test_content += "      </div>";
+    test_content += "      <p class='note'><strong>Note:</strong> it is recommended that the";
+    test_content += "          <code>*</code>, representing the universal selector, not be";
+    test_content += "          omitted.</p>";
+    test_content += "      <h4><a name='univnmsp'>6.2.1. Universal selector and namespaces</a></h4>";
+    test_content += "      <p>The universal selector allows an optional namespace component. It";
+    test_content += "          is used as follows:</p>";
+    test_content += "      <dl>";
+    test_content += "          <dt><code>ns|*</code></dt>";
+    test_content += "          <dd>all elements in namespace ns</dd>";
+    test_content += "          <dt><code>*|*</code></dt>";
+    test_content += "          <dd>all elements</dd>";
+    test_content += "          <dt><code>|*</code></dt>";
+    test_content += "          <dd>all elements without any declared namespace</dd>";
+    test_content += "          <dt><code>*</code></dt>";
+    test_content += "          <dd>if no default namespace has been specified, this is equivalent to *|*.";
+    test_content += "          </dd>";
+    test_content += "      </dl>";
+    test_content += "      <p>A universal selector containing a namespace prefix that has not";
+    test_content += "          been previously declared is an <a href='#Conformance'>invalid</a>";
+    test_content += "          to the language implementing Selectors. In CSS, such a mechanism is";
+    test_content += "          defined in the General Syntax module.</p>";
+    test_content += "      <h3><a name='attribute-selectors'>6.3. Attribute selectors</a></h3>";
+    test_content += "      <p>Selectors allow the representation of an element's attributes. When";
+    test_content += "          attribute selectors must be considered to match an element if that";
+    test_content += "          attribute selector.</p>";
+    test_content += "      <h4><a name='attribute-representation'>6.3.1. Attribute presence and values";
+    test_content += "          selectors</a></h4>";
+    test_content += "      <p>CSS2 introduced four attribute selectors:</p>";
+    test_content += "      <dl>";
+    test_content += "          <dt><code>[att]</code>";
+    test_content += "          </dt><dd>Represents an element with the <code>att</code> attribute, whatever the";
+    test_content += "          </dd>";
+    test_content += "          <dt><code>[att=val]</code></dt>";
+    test_content += "          <dd>Represents an element with the <code>att</code> attribute whose value is";
+    test_content += "          </dd>";
+    test_content += "          <dt><code>[att~=val]</code></dt>";
+    test_content += "          <dd>Represents an element with the <code>att</code> attribute whose value is";
+    test_content += "              a <a href='#whitespace'>whitespace</a>-separated list of words, one";
+    test_content += "              represent anything (since the words are <em>separated</em> by";
+    test_content += "          </dd>";
+    test_content += "          <dt><code>[att|=val]</code>";
+    test_content += "          </dt><dd>Represents an element with the <code>att</code> attribute, its value";
+    test_content += "              matches (e.g., the <code>hreflang</code> attribute on the";
+    test_content += "              <code>link</code> element in HTML) as described in RFC 3066 (<a href='#refsRFC3066'>[RFC3066]</a>). For <code>lang</code> (or";
+    test_content += "              <code>xml:lang</code>) language subcode matching, please see <a href='#lang-pseudo'>the <code>:lang</code> pseudo-class</a>.";
+    test_content += "          </dd>";
+    test_content += "      </dl>";
+    test_content += "      <p>Attribute values must be identifiers or strings. The";
+    test_content += "          case-sensitivity of attribute names and values in selectors depends on";
+    test_content += "          the document language.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <p>The following attribute selector represents an <code>h1</code>";
+    test_content += "              element that carries the <code>title</code> attribute, whatever its";
+    test_content += "              value:</p>";
+    test_content += "          <pre>h1[title]</pre>";
+    test_content += "          <p>In the following example, the selector represents a";
+    test_content += "              <code>span</code> element whose <code>class</code> attribute has";
+    test_content += "              exactly the value 'example':</p>";
+    test_content += "          <pre>span[class='example']</pre>";
+    test_content += "          <p>Multiple attribute selectors can be used to represent several";
+    test_content += "              attribute. Here, the selector represents a <code>span</code> element";
+    test_content += "              whose <code>hello</code> attribute has exactly the value 'Cleveland'";
+    test_content += "              and whose <code>goodbye</code> attribute has exactly the value";
+    test_content += "              'Columbus':</p>";
+    test_content += "          <pre>span[hello='Cleveland'][goodbye='Columbus']</pre>";
+    test_content += "          <p>The following selectors illustrate the differences between '='";
+    test_content += "              'copyright copyleft copyeditor' on a <code>rel</code> attribute. The";
+    test_content += "              second selector will only represent an <code>a</code> element with";
+    test_content += "              an <code>href</code> attribute having the exact value";
+    test_content += "              'http://www.w3.org/'.</p>";
+    test_content += "        <pre>a[rel~='copyright']";
+    test_content += "      a[href='http://www.w3.org/']</pre>";
+    test_content += "          <p>The following selector represents a <code>link</code> element";
+    test_content += "              whose <code>hreflang</code> attribute is exactly 'fr'.</p>";
+    test_content += "          <pre>link[hreflang=fr]</pre>";
+    test_content += "          <p>The following selector represents a <code>link</code> element for";
+    test_content += "              which the values of the <code>hreflang</code> attribute begins with";
+    test_content += "              'en', including 'en', 'en-US', and 'en-cockney':</p>";
+    test_content += "          <pre>link[hreflang|='en']</pre>";
+    test_content += "          <p>Similarly, the following selectors represents a";
+    test_content += "              <code>DIALOGUE</code> element whenever it has one of two different";
+    test_content += "              values for an attribute <code>character</code>:</p>";
+    test_content += "        <pre>DIALOGUE[character=romeo]";
+    test_content += "      DIALOGUE[character=juliet]</pre>";
+    test_content += "      </div>";
+    test_content += "      <h4><a name='attribute-substrings'></a>6.3.2. Substring matching attribute";
+    test_content += "          selectors</h4>";
+    test_content += "      <p>Three additional attribute selectors are provided for matching";
+    test_content += "          substrings in the value of an attribute:</p>";
+    test_content += "      <dl>";
+    test_content += "          <dt><code>[att^=val]</code></dt>";
+    test_content += "          <dd>Represents an element with the <code>att</code> attribute whose value";
+    test_content += "          </dd>";
+    test_content += "          <dt><code>[att$=val]</code>";
+    test_content += "          </dt><dd>Represents an element with the <code>att</code> attribute whose value";
+    test_content += "          </dd>";
+    test_content += "          <dt><code>[att*=val]</code>";
+    test_content += "          </dt><dd>Represents an element with the <code>att</code> attribute whose value";
+    test_content += "          </dd>";
+    test_content += "      </dl>";
+    test_content += "      <p>Attribute values must be identifiers or strings. The";
+    test_content += "          case-sensitivity of attribute names in selectors depends on the";
+    test_content += "          document language.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <p>The following selector represents an HTML <code>object</code>,";
+    test_content += "              image:</p>";
+    test_content += "          <pre>object[type^='image/']</pre>";
+    test_content += "          <p>The following selector represents an HTML anchor <code>a</code> with an";
+    test_content += "              <code>href</code> attribute whose value ends with '.html'.</p>";
+    test_content += "          <pre>a[href$='.html']</pre>";
+    test_content += "          <p>The following selector represents an HTML paragraph with a";
+    test_content += "              <code>title</code>";
+    test_content += "              attribute whose value contains the substring 'hello'</p>";
+    test_content += "          <pre>p[title*='hello']</pre>";
+    test_content += "      </div>";
+    test_content += "      <h4><a name='attrnmsp'>6.3.3. Attribute selectors and namespaces</a></h4>";
+    test_content += "      <p>Attribute selectors allow an optional namespace component to the";
+    test_content += "          separator 'vertical bar' (<code>|</code>). In keeping with";
+    test_content += "          apply to attributes, therefore attribute selectors without a namespace";
+    test_content += "          (equivalent to '<code>|attr</code>'). An asterisk may be used for the";
+    test_content += "      </p><p>An attribute selector with an attribute name containing a namespace";
+    test_content += "          prefix that has not been previously declared is an <a href='#Conformance'>invalid</a> selector. The mechanism for";
+    test_content += "          a namespace prefix is left up to the language implementing Selectors.";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>CSS examples:</p>";
+    test_content += "        <pre>@namespace foo 'http://www.example.com';";
+    test_content += "      [att] { color: green }</pre>";
+    test_content += "          <p>The first rule will match only elements with the attribute";
+    test_content += "              <code>att</code> in the 'http://www.example.com' namespace with the";
+    test_content += "              value 'val'.</p>";
+    test_content += "          <p>The second rule will match only elements with the attribute";
+    test_content += "              <code>att</code> regardless of the namespace of the attribute";
+    test_content += "              (including no declared namespace).</p>";
+    test_content += "          <p>The last two rules are equivalent and will match only elements";
+    test_content += "              with the attribute <code>att</code> where the attribute is not";
+    test_content += "              declared to be in a namespace.</p>";
+    test_content += "      </div>";
+    test_content += "      <h4><a name='def-values'>6.3.4. Default attribute values in DTDs</a></h4>";
+    test_content += "      <p>Attribute selectors represent explicitly set attribute values in";
+    test_content += "          selectors. Selectors should be designed so that they work even if the";
+    test_content += "          default values are not included in the document tree.</p>";
+    test_content += "      <p>More precisely, a UA is <em>not</em> required to read an 'external";
+    test_content += "          subset' of the DTD but <em>is</em> required to look for default";
+    test_content += "          attribute values in the document's 'internal subset.' (See <a href='#refsXML10'>[XML10]</a> for definitions of these subsets.)</p>";
+    test_content += "      <p>A UA that recognizes an XML namespace <a href='#refsXMLNAMES'>[XMLNAMES]</a> is not required to use its";
+    test_content += "          required to use its built-in knowledge of the XHTML DTD.)</p>";
+    test_content += "      <p class='note'><strong>Note:</strong> Typically, implementations";
+    test_content += "          choose to ignore external subsets.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <p>Consider an element EXAMPLE with an attribute 'notation' that has a";
+    test_content += "              default value of 'decimal'. The DTD fragment might be</p>";
+    test_content += "          <pre class='dtd-example'>&lt;!ATTLIST EXAMPLE notation (decimal,octal) 'decimal'&gt;</pre>";
+    test_content += "          <p>If the style sheet contains the rules</p>";
+    test_content += "      <pre>EXAMPLE[notation=decimal] { /*... default property settings ...*/ }";
+    test_content += "      EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>";
+    test_content += "          <p>the first rule will not match elements whose 'notation' attribute";
+    test_content += "              attribute selector for the default value must be dropped:</p>";
+    test_content += "      <pre>EXAMPLE                   { /*... default property settings ...*/ }";
+    test_content += "      EXAMPLE[notation=octal]   { /*... other settings...*/ }</pre>";
+    test_content += "          <p>Here, because the selector <code>EXAMPLE[notation=octal]</code> is";
+    test_content += "              cases' style rules.</p>";
+    test_content += "      </div>";
+    test_content += "      <h3><a name='class-html'>6.4. Class selectors</a></h3>";
+    test_content += "      <p>Working with HTML, authors may use the period (U+002E,";
+    test_content += "          <code>.</code>) notation as an alternative to the <code>~=</code>";
+    test_content += "          notation when representing the <code>class</code> attribute. Thus, for";
+    test_content += "          HTML, <code>div.value</code> and <code>div[class~=value]</code> have";
+    test_content += "          'period' (<code>.</code>).</p>";
+    test_content += "      <p>UAs may apply selectors using the period (.) notation in XML";
+    test_content += "          1.0 <a href='#refsSVG'>[SVG]</a> describes the <a href='http://www.w3.org/TR/2001/PR-SVG-20010719/styling.html#ClassAttribute'>SVG";
+    test_content += "              'class' attribute</a> and how a UA should interpret it, and";
+    test_content += "          similarly MathML 1.01 <a href='#refsMATH'>[MATH]</a> describes the <a href='http://www.w3.org/1999/07/REC-MathML-19990707/chapter2.html#sec2.3.4'>MathML";
+    test_content += "              'class' attribute</a>.)</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>CSS examples:</p>";
+    test_content += "          <p>We can assign style information to all elements with";
+    test_content += "              <code>class~='pastoral'</code> as follows:</p>";
+    test_content += "          <pre>*.pastoral { color: green }  /* all elements with class~=pastoral */</pre>";
+    test_content += "          <p>or just</p>";
+    test_content += "          <pre>.pastoral { color: green }  /* all elements with class~=pastoral */</pre>";
+    test_content += "          <p>The following assigns style only to H1 elements with";
+    test_content += "              <code>class~='pastoral'</code>:</p>";
+    test_content += "          <pre>H1.pastoral { color: green }  /* H1 elements with class~=pastoral */</pre>";
+    test_content += "          <p>Given these rules, the first H1 instance below would not have";
+    test_content += "              green text, while the second would:</p>";
+    test_content += "        <pre>&lt;H1&gt;Not green&lt;/H1&gt;";
+    test_content += "      &lt;H1 class='pastoral'&gt;Very green&lt;/H1&gt;</pre>";
+    test_content += "      </div>";
+    test_content += "      <p>To represent a subset of 'class' values, each value must be preceded";
+    test_content += "          by a '.', in any order.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>CSS example:</p>";
+    test_content += "          <p>The following rule matches any P element whose 'class' attribute";
+    test_content += "              has been assigned a list of <a href='#whitespace'>whitespace</a>-separated values that includes";
+    test_content += "              'pastoral' and 'marine':</p>";
+    test_content += "          <pre>p.pastoral.marine { color: green }</pre>";
+    test_content += "          <p>This rule matches when <code>class='pastoral blue aqua";
+    test_content += "              marine'</code> but does not match for <code>class='pastoral";
+    test_content += "              blue'</code>.</p>";
+    test_content += "      </div>";
+    test_content += "      <p class='note'><strong>Note:</strong> Because CSS gives considerable";
+    test_content += "          not.</p>";
+    test_content += "      <p class='note'><strong>Note:</strong> If an element has multiple";
+    test_content += "          this specification.</p>";
+    test_content += "      <h3><a name='id-selectors'>6.5. ID selectors</a></h3>";
+    test_content += "      <p>Document languages may contain attributes that are declared to be";
+    test_content += "          applies.</p>";
+    test_content += "      <p>An ID-typed attribute of a document language allows authors to";
+    test_content += "          ID selectors represent an element instance based on its identifier. An";
+    test_content += "          <code>#</code>) immediately followed by the ID value, which must be an";
+    test_content += "          identifier.</p>";
+    test_content += "      <p>Selectors does not specify how a UA knows the ID-typed attribute of";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <p>The following ID selector represents an <code>h1</code> element";
+    test_content += "              whose ID-typed attribute has the value 'chapter1':</p>";
+    test_content += "          <pre>h1#chapter1</pre>";
+    test_content += "          <p>The following ID selector represents any element whose ID-typed";
+    test_content += "              attribute has the value 'chapter1':</p>";
+    test_content += "          <pre>#chapter1</pre>";
+    test_content += "          <p>The following selector represents any element whose ID-typed";
+    test_content += "              attribute has the value 'z98y'.</p>";
+    test_content += "          <pre>*#z98y</pre>";
+    test_content += "      </div>";
+    test_content += "      <p class='note'><strong>Note.</strong> In XML 1.0 <a href='#refsXML10'>[XML10]</a>, the information about which attribute";
+    test_content += "          should use normal attribute selectors instead:";
+    test_content += "          <code>[name=p371]</code> instead of <code>#p371</code>. Elements in";
+    test_content += "          XML 1.0 documents without a DTD do not have IDs at all.</p>";
+    test_content += "      <p>If an element has multiple ID attributes, all of them must be";
+    test_content += "          DOM3 Core, XML DTDs, and namespace-specific knowledge.</p>";
+    test_content += "      <h3><a name='pseudo-classes'>6.6. Pseudo-classes</a></h3>";
+    test_content += "      <p>The pseudo-class concept is introduced to permit selection based on";
+    test_content += "          expressed using the other simple selectors.</p>";
+    test_content += "      <p>A pseudo-class always consists of a 'colon'";
+    test_content += "          (<code>:</code>) followed by the name of the pseudo-class and";
+    test_content += "          optionally by a value between parentheses.</p>";
+    test_content += "      <p>Pseudo-classes are allowed in all sequences of simple selectors";
+    test_content += "          sequences of simple selectors, after the leading type selector or";
+    test_content += "          document.</p>";
+    test_content += "      <h4><a name='dynamic-pseudos'>6.6.1. Dynamic pseudo-classes</a></h4>";
+    test_content += "      <p>Dynamic pseudo-classes classify elements on characteristics other";
+    test_content += "          that cannot be deduced from the document tree.</p>";
+    test_content += "      <p>Dynamic pseudo-classes do not appear in the document source or";
+    test_content += "          document tree.</p>";
+    test_content += "      <h5>The <a name='link'>link pseudo-classes: :link and :visited</a></h5>";
+    test_content += "      <p>User agents commonly display unvisited links differently from";
+    test_content += "          previously visited ones. Selectors";
+    test_content += "          provides the pseudo-classes <code>:link</code> and";
+    test_content += "          <code>:visited</code> to distinguish them:</p>";
+    test_content += "      <ul>";
+    test_content += "          <li>The <code>:link</code> pseudo-class applies to links that have";
+    test_content += "          </li>";
+    test_content += "          <li>The <code>:visited</code> pseudo-class applies once the link has";
+    test_content += "          </li>";
+    test_content += "      </ul>";
+    test_content += "      <p>After some amount of time, user agents may choose to return a";
+    test_content += "          visited link to the (unvisited) ':link' state.</p>";
+    test_content += "      <p>The two states are mutually exclusive.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <p>The following selector represents links carrying class";
+    test_content += "              <code>external</code> and already visited:</p>";
+    test_content += "          <pre>a.external:visited</pre>";
+    test_content += "      </div>";
+    test_content += "      <p class='note'><strong>Note:</strong> It is possible for style sheet";
+    test_content += "      </p><p>UAs may therefore treat all links as unvisited links, or implement";
+    test_content += "          and unvisited links differently.</p>";
+    test_content += "      <h5>The <a name='useraction-pseudos'>user action pseudo-classes";
+    test_content += "          :hover, :active, and :focus</a></h5>";
+    test_content += "      <p>Interactive user agents sometimes change the rendering in response";
+    test_content += "          to user actions. Selectors provides";
+    test_content += "          acting on.</p>";
+    test_content += "      <ul>";
+    test_content += "          <li>The <code>:hover</code> pseudo-class applies while the user";
+    test_content += "              element. User agents not that do not support <a href='http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group'>interactive";
+    test_content += "                  media</a> do not have to support this pseudo-class. Some conforming";
+    test_content += "              user agents that support <a href='http://www.w3.org/TR/REC-CSS2/media.html#interactive-media-group'>interactive";
+    test_content += "                  media</a> may not be able to support this pseudo-class (e.g., a pen";
+    test_content += "          </li>";
+    test_content += "          <li>The <code>:active</code> pseudo-class applies while an element";
+    test_content += "          </li>";
+    test_content += "          <li>The <code>:focus</code> pseudo-class applies while an element";
+    test_content += "          </li>";
+    test_content += "      </ul>";
+    test_content += "      <p>There may be document language or implementation specific limits on";
+    test_content += "          which elements can become <code>:active</code> or acquire";
+    test_content += "          <code>:focus</code>.</p>";
+    test_content += "      <p>These pseudo-classes are not mutually exclusive. An element may";
+    test_content += "          match several pseudo-classes at the same time.</p>";
+    test_content += "      <p>Selectors doesn't define if the parent of an element that is";
+    test_content += "          ':active' or ':hover' is also in that state.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "        <pre>a:link    /* unvisited links */";
+    test_content += "      a:active  /* active links */</pre>";
+    test_content += "          <p>An example of combining dynamic pseudo-classes:</p>";
+    test_content += "        <pre>a:focus";
+    test_content += "      a:focus:hover</pre>";
+    test_content += "          <p>The last selector matches <code>a</code> elements that are in";
+    test_content += "              the pseudo-class :focus and in the pseudo-class :hover.</p>";
+    test_content += "      </div>";
+    test_content += "      <p class='note'><strong>Note:</strong> An element can be both ':visited'";
+    test_content += "          and ':active' (or ':link' and ':active').</p>";
+    test_content += "      <h4><a name='target-pseudo'>6.6.2. The target pseudo-class :target</a></h4>";
+    test_content += "      <p>Some URIs refer to a location within a resource. This kind of URI";
+    test_content += "          identifier (called the fragment identifier).</p>";
+    test_content += "      <p>URIs with fragment identifiers link to a certain element within the";
+    test_content += "          pointing to an anchor named <code>section_2</code> in an HTML";
+    test_content += "          document:</p>";
+    test_content += "      <pre>http://example.com/html/top.html#section_2</pre>";
+    test_content += "      <p>A target element can be represented by the <code>:target</code>";
+    test_content += "          the document has no target element.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <pre>p.note:target</pre>";
+    test_content += "          <p>This selector represents a <code>p</code> element of class";
+    test_content += "              <code>note</code> that is the target element of the referring";
+    test_content += "              URI.</p>";
+    test_content += "      </div>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>CSS example:</p>";
+    test_content += "          <p>Here, the <code>:target</code> pseudo-class is used to make the";
+    test_content += "              target element red and place an image before it, if there is one:</p>";
+    test_content += "       <pre>*:target { color : red }";
+    test_content += "      *:target::before { content : url(target.png) }</pre>";
+    test_content += "      </div>";
+    test_content += "      <h4><a name='lang-pseudo'>6.6.3. The language pseudo-class :lang</a></h4>";
+    test_content += "      <p>If the document language specifies how the human language of an";
+    test_content += "          element is determined, it is possible to write selectors that";
+    test_content += "          represent an element based on its language. For example, in HTML <a href='#refsHTML4'>[HTML4]</a>, the language is determined by a";
+    test_content += "          combination of the <code>lang</code> attribute, the <code>meta</code>";
+    test_content += "          headers). XML uses an attribute called <code>xml:lang</code>, and";
+    test_content += "          the language.</p>";
+    test_content += "      <p>The pseudo-class <code>:lang(C)</code> represents an element that";
+    test_content += "          <code>:lang()</code> selector is based solely on the identifier C";
+    test_content += "          element's language value, in the same way as if performed by the <a href='#attribute-representation'>'|='</a> operator in attribute";
+    test_content += "          selectors. The identifier C does not have to be a valid language";
+    test_content += "          name.</p>";
+    test_content += "      <p>C must not be empty. (If it is, the selector is invalid.)</p>";
+    test_content += "      <p class='note'><strong>Note:</strong> It is recommended that";
+    test_content += "          documents and protocols indicate language using codes from RFC 3066 <a href='#refsRFC3066'>[RFC3066]</a> or its successor, and by means of";
+    test_content += "          'xml:lang' attributes in the case of XML-based documents <a href='#refsXML10'>[XML10]</a>. See <a href='http://www.w3.org/International/questions/qa-lang-2or3.html'>";
+    test_content += "              'FAQ: Two-letter or three-letter language codes.'</a></p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <p>The two following selectors represent an HTML document that is in";
+    test_content += "              Belgian, French, or German. The two next selectors represent";
+    test_content += "              <code>q</code> quotations in an arbitrary element in Belgian, French,";
+    test_content += "              or German.</p>";
+    test_content += "        <pre>html:lang(fr-be)";
+    test_content += "      :lang(de) &gt; q</pre>";
+    test_content += "      </div>";
+    test_content += "      <h4><a name='UIstates'>6.6.4. The UI element states pseudo-classes</a></h4>";
+    test_content += "      <h5><a name='enableddisabled'>The :enabled and :disabled pseudo-classes</a></h5>";
+    test_content += "      <p>The <code>:enabled</code> pseudo-class allows authors to customize";
+    test_content += "          an enabled <code>input</code> element without also specifying what it";
+    test_content += "          would look like when it was disabled.</p>";
+    test_content += "      <p>Similar to <code>:enabled</code>, <code>:disabled</code> allows the";
+    test_content += "          element should look.</p>";
+    test_content += "      <p>Most elements will be neither enabled nor disabled. An element is";
+    test_content += "          presently activate it or transfer focus to it.</p>";
+    test_content += "      <h5><a name='checked'>The :checked pseudo-class</a></h5>";
+    test_content += "      <p>Radio and checkbox elements can be toggled by the user. Some menu";
+    test_content += "          toggled 'on' the <code>:checked</code> pseudo-class applies. The";
+    test_content += "          <code>:checked</code> pseudo-class initially applies to such elements";
+    test_content += "          that have the HTML4 <code>selected</code> and <code>checked</code>";
+    test_content += "          attributes as described in <a href='http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.2.1'>Section";
+    test_content += "              17.2.1 of HTML4</a>, but of course the user can toggle 'off' such";
+    test_content += "          elements in which case the <code>:checked</code> pseudo-class would no";
+    test_content += "          longer apply. While the <code>:checked</code> pseudo-class is dynamic";
+    test_content += "          on the presence of the semantic HTML4 <code>selected</code> and";
+    test_content += "          <code>checked</code> attributes, it applies to all media.";
+    test_content += "      </p><h5><a name='indeterminate'>The :indeterminate pseudo-class</a></h5>";
+    test_content += "      <div class='note'>";
+    test_content += "          <p>Radio and checkbox elements can be toggled by the user, but are";
+    test_content += "              This can be due to an element attribute, or DOM manipulation.</p>";
+    test_content += "          <p>A future version of this specification may introduce an";
+    test_content += "              <code>:indeterminate</code> pseudo-class that applies to such elements.";
+    test_content += "              <!--While the <code>:indeterminate</code> pseudo-class is dynamic in";
+    test_content += "         the presence of an element attribute, it applies to all media.</p>";
+    test_content += "         <p>Components of a radio-group initialized with no pre-selected choice";
+    test_content += "         are an example of :indeterminate state.--></p>";
+    test_content += "      </div>";
+    test_content += "      <h4><a name='structural-pseudos'>6.6.5. Structural pseudo-classes</a></h4>";
+    test_content += "      <p>Selectors introduces the concept of <dfn>structural";
+    test_content += "          pseudo-classes</dfn> to permit selection based on extra information that";
+    test_content += "          the document tree but cannot be represented by other simple selectors or";
+    test_content += "      </p><p>Note that standalone pieces of PCDATA (text nodes in the DOM) are";
+    test_content += "      </p><h5><a name='root-pseudo'>:root pseudo-class</a></h5>";
+    test_content += "      <p>The <code>:root</code> pseudo-class represents an element that is";
+    test_content += "          <code>HTML</code> element.";
+    test_content += "      </p><h5><a name='nth-child-pseudo'>:nth-child() pseudo-class</a></h5>";
+    test_content += "      <p>The";
+    test_content += "          <code>:nth-child(<var>a</var><code>n</code>+<var>b</var>)</code>";
+    test_content += "          <var>a</var><code>n</code>+<var>b</var>-1 siblings";
+    test_content += "          <strong>before</strong> it in the document tree, for a given positive";
+    test_content += "          integer or zero value of <code>n</code>, and has a parent element. In";
+    test_content += "          other words, this matches the <var>b</var>th child of an element after";
+    test_content += "          all the children have been split into groups of <var>a</var> elements";
+    test_content += "          each. For example, this allows the selectors to address every other";
+    test_content += "          of paragraph text in a cycle of four. The <var>a</var> and";
+    test_content += "          <var>b</var> values must be zero, negative integers or positive";
+    test_content += "      </p><p>In addition to this, <code>:nth-child()</code> can take";
+    test_content += "          '<code>odd</code>' and '<code>even</code>' as arguments instead.";
+    test_content += "          '<code>odd</code>' has the same signification as <code>2n+1</code>,";
+    test_content += "          and '<code>even</code>' has the same signification as <code>2n</code>.";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "      <pre>tr:nth-child(2n+1) /* represents every odd row of an HTML table */";
+    test_content += "      p:nth-child(4n+4) { color: purple; }</pre>";
+    test_content += "      </div>";
+    test_content += "      <p>When <var>a</var>=0, no repeating is used, so for example";
+    test_content += "          <code>:nth-child(0n+5)</code> matches only the fifth child. When";
+    test_content += "          <var>a</var>=0, the <var>a</var><code>n</code> part need not be";
+    test_content += "          <code>:nth-child(<var>b</var>)</code> and the last example simplifies";
+    test_content += "          to <code>:nth-child(5)</code>.";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "      <pre>foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */";
+    test_content += "      foo:nth-child(1)      /* same */</pre>";
+    test_content += "      </div>";
+    test_content += "      <p>When <var>a</var>=1, the number may be omitted from the rule.";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <p>The following selectors are therefore equivalent:</p>";
+    test_content += "      <pre>bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */";
+    test_content += "      bar                   /* same but lower specificity (0,0,1) */</pre>";
+    test_content += "      </div>";
+    test_content += "      <p>If <var>b</var>=0, then every <var>a</var>th element is picked. In";
+    test_content += "          such a case, the <var>b</var> part may be omitted.";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "      <pre>tr:nth-child(2n+0) /* represents every even row of an HTML table */";
+    test_content += "      tr:nth-child(2n) /* same */</pre>";
+    test_content += "      </div>";
+    test_content += "      <p>If both <var>a</var> and <var>b</var> are equal to zero, the";
+    test_content += "          pseudo-class represents no element in the document tree.</p>";
+    test_content += "      <p>The value <var>a</var> can be negative, but only the positive";
+    test_content += "          values of <var>a</var><code>n</code>+<var>b</var>, for";
+    test_content += "          <code>n</code>≥0, may represent an element in the document";
+    test_content += "          tree.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <pre>html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */</pre>";
+    test_content += "      </div>";
+    test_content += "      <p>When the value <var>b</var> is negative, the '+' character in the";
+    test_content += "          character indicating the negative value of <var>b</var>).</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "      <pre>:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */";
+    test_content += "      :nth-child(10n+-1) /* Syntactically invalid, and would be ignored */</pre>";
+    test_content += "      </div>";
+    test_content += "      <h5><a name='nth-last-child-pseudo'>:nth-last-child() pseudo-class</a></h5>";
+    test_content += "      <p>The <code>:nth-last-child(<var>a</var>n+<var>b</var>)</code>";
+    test_content += "          <var>a</var><code>n</code>+<var>b</var>-1 siblings";
+    test_content += "          <strong>after</strong> it in the document tree, for a given positive";
+    test_content += "          integer or zero value of <code>n</code>, and has a parent element. See";
+    test_content += "          <code>:nth-child()</code> pseudo-class for the syntax of its argument.";
+    test_content += "          It also accepts the '<code>even</code>' and '<code>odd</code>' values";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "      <pre>tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */";
+    test_content += "                                    counting from the last one */</pre>";
+    test_content += "      </div>";
+    test_content += "      <h5><a name='nth-of-type-pseudo'>:nth-of-type() pseudo-class</a></h5>";
+    test_content += "      <p>The <code>:nth-of-type(<var>a</var>n+<var>b</var>)</code>";
+    test_content += "          <var>a</var><code>n</code>+<var>b</var>-1 siblings with the same";
+    test_content += "          element name <strong>before</strong> it in the document tree, for a";
+    test_content += "          given zero or positive integer value of <code>n</code>, and has a";
+    test_content += "          parent element. In other words, this matches the <var>b</var>th child";
+    test_content += "          groups of a elements each. See <code>:nth-child()</code> pseudo-class";
+    test_content += "          '<code>even</code>' and '<code>odd</code>' values.";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>CSS example:</p>";
+    test_content += "          <p>This allows an author to alternate the position of floated images:</p>";
+    test_content += "      <pre>img:nth-of-type(2n+1) { float: right; }";
+    test_content += "      img:nth-of-type(2n) { float: left; }</pre>";
+    test_content += "      </div>";
+    test_content += "      <h5><a name='nth-last-of-type-pseudo'>:nth-last-of-type() pseudo-class</a></h5>";
+    test_content += "      <p>The <code>:nth-last-of-type(<var>a</var>n+<var>b</var>)</code>";
+    test_content += "          <var>a</var><code>n</code>+<var>b</var>-1 siblings with the same";
+    test_content += "          element name <strong>after</strong> it in the document tree, for a";
+    test_content += "          given zero or positive integer value of <code>n</code>, and has a";
+    test_content += "          parent element. See <code>:nth-child()</code> pseudo-class for the";
+    test_content += "          syntax of its argument. It also accepts the '<code>even</code>' and '<code>odd</code>'";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <p>To represent all <code>h2</code> children of an XHTML";
+    test_content += "              <code>body</code> except the first and last, one could use the";
+    test_content += "              following selector:</p>";
+    test_content += "          <pre>body &gt; h2:nth-of-type(n+2):nth-last-of-type(n+2)</pre>";
+    test_content += "          <p>In this case, one could also use <code>:not()</code>, although the";
+    test_content += "              selector ends up being just as long:</p>";
+    test_content += "          <pre>body &gt; h2:not(:first-of-type):not(:last-of-type)</pre>";
+    test_content += "      </div>";
+    test_content += "      <h5><a name='first-child-pseudo'>:first-child pseudo-class</a></h5>";
+    test_content += "      <p>Same as <code>:nth-child(1)</code>. The <code>:first-child</code>";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <p>The following selector represents a <code>p</code> element that is";
+    test_content += "              the first child of a <code>div</code> element:</p>";
+    test_content += "          <pre>div &gt; p:first-child</pre>";
+    test_content += "          <p>This selector can represent the <code>p</code> inside the";
+    test_content += "              <code>div</code> of the following fragment:</p>";
+    test_content += "        <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;";
+    test_content += "      &lt;/div&gt;</pre>";
+    test_content += "          but cannot represent the second <code>p</code> in the following";
+    test_content += "        <pre>&lt;p&gt; The last P before the note.&lt;/p&gt;";
+    test_content += "      &lt;/div&gt;</pre>";
+    test_content += "          <p>The following two selectors are usually equivalent:</p>";
+    test_content += "        <pre>* &gt; a:first-child /* a is first child of any element */";
+    test_content += "      a:first-child /* Same (assuming a is not the root element) */</pre>";
+    test_content += "      </div>";
+    test_content += "      <h5><a name='last-child-pseudo'>:last-child pseudo-class</a></h5>";
+    test_content += "      <p>Same as <code>:nth-last-child(1)</code>. The <code>:last-child</code>";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <p>The following selector represents a list item <code>li</code> that";
+    test_content += "              is the last child of an ordered list <code>ol</code>.";
+    test_content += "          </p><pre>ol &gt; li:last-child</pre>";
+    test_content += "      </div>";
+    test_content += "      <h5><a name='first-of-type-pseudo'>:first-of-type pseudo-class</a></h5>";
+    test_content += "      <p>Same as <code>:nth-of-type(1)</code>. The <code>:first-of-type</code>";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <p>The following selector represents a definition title";
+    test_content += "              <code>dt</code> inside a definition list <code>dl</code>, this";
+    test_content += "              <code>dt</code> being the first of its type in the list of children of";
+    test_content += "              its parent element.</p>";
+    test_content += "          <pre>dl dt:first-of-type</pre>";
+    test_content += "          <p>It is a valid description for the first two <code>dt</code>";
+    test_content += "              elements in the following example but not for the third one:</p>";
+    test_content += "      <pre>&lt;dl&gt;";
+    test_content += "      &lt;/dl&gt;</pre>";
+    test_content += "      </div>";
+    test_content += "      <h5><a name='last-of-type-pseudo'>:last-of-type pseudo-class</a></h5>";
+    test_content += "      <p>Same as <code>:nth-last-of-type(1)</code>. The";
+    test_content += "          <code>:last-of-type</code> pseudo-class represents an element that is";
+    test_content += "          element.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <p>The following selector represents the last data cell";
+    test_content += "              <code>td</code> of a table row.</p>";
+    test_content += "          <pre>tr &gt; td:last-of-type</pre>";
+    test_content += "      </div>";
+    test_content += "      <h5><a name='only-child-pseudo'>:only-child pseudo-class</a></h5>";
+    test_content += "      <p>Represents an element that has a parent element and whose parent";
+    test_content += "          <code>:first-child:last-child</code> or";
+    test_content += "          <code>:nth-child(1):nth-last-child(1)</code>, but with a lower";
+    test_content += "          specificity.</p>";
+    test_content += "      <h5><a name='only-of-type-pseudo'>:only-of-type pseudo-class</a></h5>";
+    test_content += "      <p>Represents an element that has a parent element and whose parent";
+    test_content += "          as <code>:first-of-type:last-of-type</code> or";
+    test_content += "          <code>:nth-of-type(1):nth-last-of-type(1)</code>, but with a lower";
+    test_content += "          specificity.</p>";
+    test_content += "      <h5><a name='empty-pseudo'></a>:empty pseudo-class</h5>";
+    test_content += "      <p>The <code>:empty</code> pseudo-class represents an element that has";
+    test_content += "          empty or not.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <p><code>p:empty</code> is a valid representation of the following fragment:";
+    test_content += "          </p>";
+    test_content += "          <pre>&lt;p&gt;&lt;/p&gt;</pre>";
+    test_content += "          <p><code>foo:empty</code> is not a valid representation for the";
+    test_content += "              following fragments:</p>";
+    test_content += "          <pre>&lt;foo&gt;bar&lt;/foo&gt;</pre>";
+    test_content += "          <pre>&lt;foo&gt;&lt;bar&gt;bla&lt;/bar&gt;&lt;/foo&gt;</pre>";
+    test_content += "          <pre>&lt;foo&gt;this is not &lt;bar&gt;:empty&lt;/bar&gt;&lt;/foo&gt;</pre>";
+    test_content += "      </div>";
+    test_content += "      <h4><a name='content-selectors'>6.6.6. Blank</a></h4>";
+    test_content += "      <!-- It's the Return of Appendix H!!! Run away! -->";
+    test_content += "      <p>This section intentionally left blank.</p>";
+    test_content += "      <!-- (used to be :contains()) -->";
+    test_content += "      <h4><a name='negation'></a>6.6.7. The negation pseudo-class</h4>";
+    test_content += "      <p>The negation pseudo-class, <code>:not(<var>X</var>)</code>, is a";
+    test_content += "          functional notation taking a <a href='#simple-selectors-dfn'>simple";
+    test_content += "              selector</a> (excluding the negation pseudo-class itself and";
+    test_content += "          <!-- pseudo-elements are not simple selectors, so the above paragraph";
+    test_content += "      may be a bit confusing -->";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <p>The following CSS selector matches all <code>button</code>";
+    test_content += "              elements in an HTML document that are not disabled.</p>";
+    test_content += "          <pre>button:not([DISABLED])</pre>";
+    test_content += "          <p>The following selector represents all but <code>FOO</code>";
+    test_content += "              elements.</p>";
+    test_content += "          <pre>*:not(FOO)</pre>";
+    test_content += "          <p>The following group of selectors represents all HTML elements";
+    test_content += "              except links.</p>";
+    test_content += "          <pre>html|*:not(:link):not(:visited)</pre>";
+    test_content += "      </div>";
+    test_content += "      <p>Default namespace declarations do not affect the argument of the";
+    test_content += "          type selector.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <p>Assuming that the default namespace is bound to";
+    test_content += "              elements that are not in that namespace:</p>";
+    test_content += "          <pre>*|*:not(*)</pre>";
+    test_content += "          <p>The following CSS selector matches any element being hovered,";
+    test_content += "              rule when they <em>are</em> being hovered.</p>";
+    test_content += "          <pre>*|*:not(:hover)</pre>";
+    test_content += "      </div>";
+    test_content += "      <p class='note'><strong>Note</strong>: the :not() pseudo allows";
+    test_content += "          useless selectors to be written. For instance <code>:not(*|*)</code>,";
+    test_content += "          which represents no element at all, or <code>foo:not(bar)</code>,";
+    test_content += "          which is equivalent to <code>foo</code> but with a higher";
+    test_content += "          specificity.</p>";
+    test_content += "      <h3><a name='pseudo-elements'>7. Pseudo-elements</a></h3>";
+    test_content += "      <p>Pseudo-elements create abstractions about the document tree beyond";
+    test_content += "          source document (e.g., the <code>::before</code> and";
+    test_content += "          <code>::after</code> pseudo-elements give access to generated";
+    test_content += "          content).</p>";
+    test_content += "      <p>A pseudo-element is made of two colons (<code>::</code>) followed";
+    test_content += "          by the name of the pseudo-element.</p>";
+    test_content += "      <p>This <code>::</code> notation is introduced by the current document";
+    test_content += "          <code>:first-line</code>, <code>:first-letter</code>,";
+    test_content += "          <code>:before</code> and <code>:after</code>). This compatibility is";
+    test_content += "          not allowed for the new pseudo-elements introduced in CSS level 3.</p>";
+    test_content += "      <p>Only one pseudo-element may appear per selector, and if present it";
+    test_content += "          must appear after the sequence of simple selectors that represents the";
+    test_content += "          <a href='#subject'>subjects</a> of the selector. <span class='note'>A";
+    test_content += "      pesudo-elements per selector.</span></p>";
+    test_content += "      <h4><a name='first-line'>7.1. The ::first-line pseudo-element</a></h4>";
+    test_content += "      <p>The <code>::first-line</code> pseudo-element describes the contents";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>CSS example:</p>";
+    test_content += "          <pre>p::first-line { text-transform: uppercase }</pre>";
+    test_content += "          <p>The above rule means 'change the letters of the first line of every";
+    test_content += "              paragraph to uppercase'.</p>";
+    test_content += "      </div>";
+    test_content += "      <p>The selector <code>p::first-line</code> does not match any real";
+    test_content += "          agents will insert at the beginning of every paragraph.</p>";
+    test_content += "      <p>Note that the length of the first line depends on a number of";
+    test_content += "          an ordinary HTML paragraph such as:</p>";
+    test_content += "      <pre>      &lt;P&gt;This is a somewhat long HTML ";
+    test_content += "      </pre>";
+    test_content += "      <p>the lines of which happen to be broken as follows:";
+    test_content += "      </p><pre>      THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT";
+    test_content += "      </pre>";
+    test_content += "      <p>This paragraph might be 'rewritten' by user agents to include the";
+    test_content += "          <em>fictional tag sequence</em> for <code>::first-line</code>. This";
+    test_content += "          fictional tag sequence helps to show how properties are inherited.</p>";
+    test_content += "      <pre>      &lt;P&gt;<b>&lt;P::first-line&gt;</b> This is a somewhat long HTML ";
+    test_content += "      paragraph that <b>&lt;/P::first-line&gt;</b> will be broken into several";
+    test_content += "      </pre>";
+    test_content += "      <p>If a pseudo-element breaks up a real element, the desired effect";
+    test_content += "          with a <code>span</code> element:</p>";
+    test_content += "      <pre>      &lt;P&gt;<b>&lt;SPAN class='test'&gt;</b> This is a somewhat long HTML";
+    test_content += "      lines.<b>&lt;/SPAN&gt;</b> The first line will be identified";
+    test_content += "      </pre>";
+    test_content += "      <p>the user agent could simulate start and end tags for";
+    test_content += "          <code>span</code> when inserting the fictional tag sequence for";
+    test_content += "          <code>::first-line</code>.";
+    test_content += "      </p><pre>      &lt;P&gt;&lt;P::first-line&gt;<b>&lt;SPAN class='test'&gt;</b> This is a";
+    test_content += "      paragraph that will <b>&lt;/SPAN&gt;</b>&lt;/P::first-line&gt;<b>&lt;SPAN";
+    test_content += "          class='test'&gt;</b> be";
+    test_content += "      lines.<b>&lt;/SPAN&gt;</b> The first line will be identified";
+    test_content += "      </pre>";
+    test_content += "      <p>In CSS, the <code>::first-line</code> pseudo-element can only be";
+    test_content += "          or a table-cell.</p>";
+    test_content += "      <p><a name='first-formatted-line'></a>The 'first formatted line' of an";
+    test_content += "          line of the <code>div</code> in <code>&lt;DIV&gt;&lt;P&gt;This";
+    test_content += "              line...&lt;/P&gt;&lt;/DIV&gt;</code> is the first line of the <code>p</code>";
+    test_content += "          that both <code>p</code> and <code>div</code> are block-level).";
+    test_content += "      </p><p>The first line of a table-cell or inline-block cannot be the first";
+    test_content += "          formatted line of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P";
+    test_content += "              etcetera&lt;/DIV&gt;</code> the first formatted line of the";
+    test_content += "          <code>div</code> is not the line 'Hello'.";
+    test_content += "      </p><p class='note'>Note that the first line of the <code>p</code> in this";
+    test_content += "          fragment: <code>&lt;p&gt;&lt;br&gt;First...</code> doesn't contain any";
+    test_content += "          letters (assuming the default style for <code>br</code> in HTML";
+    test_content += "      </p><p>A UA should act as if the fictional start tags of the";
+    test_content += "          <code>::first-line</code> pseudo-elements were nested just inside the";
+    test_content += "          is an example. The fictional tag sequence for</p>";
+    test_content += "      <pre>      &lt;DIV&gt;";
+    test_content += "      </pre>";
+    test_content += "      <p>is</p>";
+    test_content += "      <pre>      &lt;DIV&gt;";
+    test_content += "      </pre>";
+    test_content += "      <p>The <code>::first-line</code> pseudo-element is similar to an";
+    test_content += "          following properties apply to a <code>::first-line</code>";
+    test_content += "          properties as well.</p>";
+    test_content += "      <h4><a name='first-letter'>7.2. The ::first-letter pseudo-element</a></h4>";
+    test_content += "      <p>The <code>::first-letter</code> pseudo-element represents the first";
+    test_content += "          is 'none'; otherwise, it is similar to a floated element.</p>";
+    test_content += "      <p>In CSS, these are the properties that apply to <code>::first-letter</code>";
+    test_content += "          of the letter, unlike for normal elements.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <p>This example shows a possible rendering of an initial cap. Note";
+    test_content += "              <code>::first-letter</code>";
+    test_content += "              fictional start tag of the first letter is inside the <span>span</span>,";
+    test_content += "              the font weight of the first letter is normal, not bold as the <span>span</span>:";
+    test_content += "      </p><pre>      p { line-height: 1.1 }";
+    test_content += "      </pre>";
+    test_content += "          <div class='figure'>";
+    test_content += "              <p><img src='' alt='Image illustrating the ::first-letter pseudo-element'>";
+    test_content += "          </p></div>";
+    test_content += "      </div>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>The following CSS will make a drop cap initial letter span about two";
+    test_content += "              lines:</p>";
+    test_content += "      <pre>      &lt;!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'&gt;";
+    test_content += "      </pre>";
+    test_content += "          <p>This example might be formatted as follows:</p>";
+    test_content += "          <div class='figure'>";
+    test_content += "              <p><img src='' alt='Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements'>";
+    test_content += "              </p>";
+    test_content += "          </div>";
+    test_content += "          <p>The <span class='index-inst' title='fictional tag";
+    test_content += "      sequence'>fictional tag sequence</span> is:</p>";
+    test_content += "      <pre>      &lt;P&gt;";
+    test_content += "      </pre>";
+    test_content += "          <p>Note that the <code>::first-letter</code> pseudo-element tags abut";
+    test_content += "              block element.</p></div>";
+    test_content += "      <p>In order to achieve traditional drop caps formatting, user agents";
+    test_content += "          glyph outline may be taken into account when formatting.</p>";
+    test_content += "      <p>Punctuation (i.e, characters defined in Unicode in the 'open' (Ps),";
+    test_content += "          be included. <a href='#refsUNICODE'>[UNICODE]</a></p>";
+    test_content += "      <div class='figure'>";
+    test_content += "          <p><img src='' alt='Quotes that precede the";
+    test_content += "      first letter should be included.'></p>";
+    test_content += "      </div>";
+    test_content += "      <p>The <code>::first-letter</code> also applies if the first letter is";
+    test_content += "          money.'</p>";
+    test_content += "      <p>In CSS, the <code>::first-letter</code> pseudo-element applies to";
+    test_content += "          elements. <span class='note'>A future version of this specification";
+    test_content += "      types.</span></p>";
+    test_content += "      <p>The <code>::first-letter</code> pseudo-element can be used with all";
+    test_content += "          the element, even if that first text is in a descendant.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <p>The fictional tag sequence for this HTMLfragment:";
+    test_content += "      </p><pre>&lt;div&gt;";
+    test_content += "      &lt;p&gt;The first text.</pre>";
+    test_content += "          <p>is:";
+    test_content += "      </p><pre>&lt;div&gt;";
+    test_content += "      &lt;p&gt;&lt;div::first-letter&gt;&lt;p::first-letter&gt;T&lt;/...&gt;&lt;/...&gt;he first text.</pre>";
+    test_content += "      </div>";
+    test_content += "      <p>The first letter of a table-cell or inline-block cannot be the";
+    test_content += "          first letter of an ancestor element. Thus, in <code>&lt;DIV&gt;&lt;P";
+    test_content += "              etcetera&lt;/DIV&gt;</code> the first letter of the <code>div</code> is";
+    test_content += "          letter 'H'. In fact, the <code>div</code> doesn't have a first letter.";
+    test_content += "      </p><p>The first letter must occur on the <a href='#first-formatted-line'>first formatted line.</a> For example, in";
+    test_content += "          this fragment: <code>&lt;p&gt;&lt;br&gt;First...</code> the first line";
+    test_content += "          doesn't contain any letters and <code>::first-letter</code> doesn't";
+    test_content += "          match anything (assuming the default style for <code>br</code> in HTML";
+    test_content += "      </p><p>In CSS, if an element is a list item ('display: list-item'), the";
+    test_content += "          <code>::first-letter</code> applies to the first letter in the";
+    test_content += "          <code>::first-letter</code> on list items with 'list-style-position:";
+    test_content += "          inside'. If an element has <code>::before</code> or";
+    test_content += "          <code>::after</code> content, the <code>::first-letter</code> applies";
+    test_content += "          to the first letter of the element <em>including</em> that content.";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <p>After the rule 'p::before {content: 'Note: '}', the selector";
+    test_content += "              'p::first-letter' matches the 'N' of 'Note'.</p>";
+    test_content += "      </div>";
+    test_content += "      <p>Some languages may have specific rules about how to treat certain";
+    test_content += "          considered within the <code>::first-letter</code> pseudo-element.";
+    test_content += "      </p><p>If the letters that would form the ::first-letter are not in the";
+    test_content += "          same element, such as ''T' in <code>&lt;p&gt;'&lt;em&gt;T...</code>, the UA";
+    test_content += "          both elements, or simply not create a pseudo-element.</p>";
+    test_content += "      <p>Similarly, if the first letter(s) of the block are not at the start";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <p><a name='overlapping-example'>The following example</a> illustrates";
+    test_content += "              paragraph will be 'red'.</p>";
+    test_content += "      <pre>p { color: red; font-size: 12pt }";
+    test_content += "      &lt;P&gt;Some text that ends up on two lines&lt;/P&gt;</pre>";
+    test_content += "          <p>Assuming that a line break will occur before the word 'ends', the";
+    test_content += "      <span class='index-inst' title='fictional tag sequence'>fictional tag";
+    test_content += "      sequence</span> for this fragment might be:</p>";
+    test_content += "      <pre>&lt;P&gt;";
+    test_content += "      &lt;/P&gt;</pre>";
+    test_content += "          <p>Note that the <code>::first-letter</code> element is inside the <code>::first-line</code>";
+    test_content += "              element. Properties set on <code>::first-line</code> are inherited by";
+    test_content += "              <code>::first-letter</code>, but are overridden if the same property is";
+    test_content += "              <code>::first-letter</code>.</p>";
+    test_content += "      </div>";
+    test_content += "      <h4><a name='UIfragments'>7.3.</a> <a name='selection'>The ::selection";
+    test_content += "          pseudo-element</a></h4>";
+    test_content += "      <p>The <code>::selection</code> pseudo-element applies to the portion";
+    test_content += "          field. This pseudo-element should not be confused with the <code><a href='#checked'>:checked</a></code> pseudo-class (which used to be";
+    test_content += "          named <code>:selected</code>)";
+    test_content += "      </p><p>Although the <code>::selection</code> pseudo-element is dynamic in";
+    test_content += "          <a href='#refsCSS21'>[CSS21]</a>) which was originally rendered to a";
+    test_content += "          <code>::selection</code> state to that other medium, and have all the";
+    test_content += "          required — UAs may omit the <code>::selection</code>";
+    test_content += "      </p><p>These are the CSS properties that apply to <code>::selection</code>";
+    test_content += "          <code>::selection</code> may be ignored.";
+    test_content += "      </p><h4><a name='gen-content'>7.4. The ::before and ::after pseudo-elements</a></h4>";
+    test_content += "      <p>The <code>::before</code> and <code>::after</code> pseudo-elements";
+    test_content += "          content. They are explained in CSS 2.1 <a href='#refsCSS21'>[CSS21]</a>.</p>";
+    test_content += "      <p>When the <code>::first-letter</code> and <code>::first-line</code>";
+    test_content += "          pseudo-elements are combined with <code>::before</code> and";
+    test_content += "          <code>::after</code>, they apply to the first letter or line of the";
+    test_content += "          element including the inserted text.</p>";
+    test_content += "      <h2><a name='combinators'>8. Combinators</a></h2>";
+    test_content += "      <h3><a name='descendant-combinators'>8.1. Descendant combinator</a></h3>";
+    test_content += "      <p>At times, authors may want selectors to describe an element that is";
+    test_content += "          <code>EM</code> element that is contained within an <code>H1</code>";
+    test_content += "          descendant combinator is <a href='#whitespace'>white space</a> that";
+    test_content += "          separates two sequences of simple selectors. A selector of the form";
+    test_content += "          '<code>A B</code>' represents an element <code>B</code> that is an";
+    test_content += "          arbitrary descendant of some ancestor element <code>A</code>.";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <p>For example, consider the following selector:</p>";
+    test_content += "          <pre>h1 em</pre>";
+    test_content += "          <p>It represents an <code>em</code> element being the descendant of";
+    test_content += "              an <code>h1</code> element. It is a correct and valid, but partial,";
+    test_content += "              description of the following fragment:</p>";
+    test_content += "       <pre>&lt;h1&gt;This &lt;span class='myclass'&gt;headline";
+    test_content += "      is &lt;em&gt;very&lt;/em&gt; important&lt;/span&gt;&lt;/h1&gt;</pre>";
+    test_content += "          <p>The following selector:</p>";
+    test_content += "          <pre>div * p</pre>";
+    test_content += "          <p>represents a <code>p</code> element that is a grandchild or later";
+    test_content += "              descendant of a <code>div</code> element. Note the whitespace on";
+    test_content += "              of the P.</p>";
+    test_content += "          <p>The following selector, which combines descendant combinators and";
+    test_content += "              <a href='#attribute-selectors'>attribute selectors</a>, represents an";
+    test_content += "              element that (1) has the <code>href</code> attribute set and (2) is";
+    test_content += "              inside a <code>p</code> that is itself inside a <code>div</code>:</p>";
+    test_content += "          <pre>div p *[href]</pre>";
+    test_content += "      </div>";
+    test_content += "      <h3><a name='child-combinators'>8.2. Child combinators</a></h3>";
+    test_content += "      <p>A <dfn>child combinator</dfn> describes a childhood relationship";
+    test_content += "          'greater-than sign' (<code>&gt;</code>) character and";
+    test_content += "          separates two sequences of simple selectors.";
+    test_content += "      </p><div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <p>The following selector represents a <code>p</code> element that is";
+    test_content += "              child of <code>body</code>:</p>";
+    test_content += "          <pre>body &gt; p</pre>";
+    test_content += "          <p>The following example combines descendant combinators and child";
+    test_content += "              combinators.</p>";
+    test_content += "          <pre>div ol&gt;li p</pre>";
+    test_content += "          <!-- LEAVE THOSE SPACES OUT! see below -->";
+    test_content += "          <p>It represents a <code>p</code> element that is a descendant of an";
+    test_content += "              <code>li</code> element; the <code>li</code> element must be the";
+    test_content += "              child of an <code>ol</code> element; the <code>ol</code> element must";
+    test_content += "              be a descendant of a <code>div</code>. Notice that the optional white";
+    test_content += "              space around the '&gt;' combinator has been left out.</p>";
+    test_content += "      </div>";
+    test_content += "      <p>For information on selecting the first child of an element, please";
+    test_content += "          see the section on the <code><a href='#structural-pseudos'>:first-child</a></code> pseudo-class";
+    test_content += "          above.</p>";
+    test_content += "      <h3><a name='sibling-combinators'>8.3. Sibling combinators</a></h3>";
+    test_content += "      <p>There are two different sibling combinators: the adjacent sibling";
+    test_content += "          considering adjacency of elements.</p>";
+    test_content += "      <h4><a name='adjacent-sibling-combinators'>8.3.1. Adjacent sibling combinator</a>";
+    test_content += "      </h4>";
+    test_content += "      <p>The adjacent sibling combinator is made of the 'plus";
+    test_content += "          sign' (U+002B, <code>+</code>) character that separates two";
+    test_content += "          sequences of simple selectors. The elements represented by the two";
+    test_content += "          represented by the second one.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "          <p>The following selector represents a <code>p</code> element";
+    test_content += "              immediately following a <code>math</code> element:</p>";
+    test_content += "          <pre>math + p</pre>";
+    test_content += "          <p>The following selector is conceptually similar to the one in the";
+    test_content += "              adds a constraint to the <code>h1</code> element, that it must have";
+    test_content += "              <code>class='opener'</code>:</p>";
+    test_content += "          <pre>h1.opener + h2</pre>";
+    test_content += "      </div>";
+    test_content += "      <h4><a name='general-sibling-combinators'>8.3.2. General sibling combinator</a>";
+    test_content += "      </h4>";
+    test_content += "      <p>The general sibling combinator is made of the 'tilde'";
+    test_content += "          (U+007E, <code>~</code>) character that separates two sequences of";
+    test_content += "          simple selectors. The elements represented by the two sequences share";
+    test_content += "          represented by the second one.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Example:</p>";
+    test_content += "          <pre>h1 ~ pre</pre>";
+    test_content += "          <p>represents a <code>pre</code> element following an <code>h1</code>. It";
+    test_content += "              is a correct and valid, but partial, description of:</p>";
+    test_content += "       <pre>&lt;h1&gt;Definition of the function a&lt;/h1&gt;";
+    test_content += "      &lt;pre&gt;function a(x) = 12x/13.5&lt;/pre&gt;</pre>";
+    test_content += "      </div>";
+    test_content += "      <h2><a name='specificity'>9. Calculating a selector's specificity</a></h2>";
+    test_content += "      <p>A selector's specificity is calculated as follows:</p>";
+    test_content += "      <ul>";
+    test_content += "          <li>count the number of ID selectors in the selector (= a)</li>";
+    test_content += "          <li>count the number of class selectors, attributes selectors, and";
+    test_content += "          </li>";
+    test_content += "          <li>count the number of element names in the selector (= c)</li>";
+    test_content += "          <li>ignore pseudo-elements</li>";
+    test_content += "      </ul>";
+    test_content += "      <p>Selectors inside <a href='#negation'>the negation pseudo-class</a>";
+    test_content += "          a pseudo-class.</p>";
+    test_content += "      <p>Concatenating the three numbers a-b-c (in a number system with a";
+    test_content += "          large base) gives the specificity.</p>";
+    test_content += "      <div class='example'>";
+    test_content += "          <p>Examples:</p>";
+    test_content += "      <pre>*               /* a=0 b=0 c=0 -&gt; specificity =   0 */";
+    test_content += "      </pre>";
+    test_content += "      </div>";
+    test_content += "      <p class='note'><strong>Note:</strong> the specificity of the styles";
+    test_content += "          specified in an HTML <code>style</code> attribute is described in CSS";
+    test_content += "          2.1. <a href='#refsCSS21'>[CSS21]</a>.</p>";
+    test_content += "      <h2><a name='w3cselgrammar'>10. The grammar of Selectors</a></h2>";
+    test_content += "      <h3><a name='grammar'>10.1. Grammar</a></h3>";
+    test_content += "      <p>The grammar below defines the syntax of Selectors. It is globally";
+    test_content += "          shorthand notations beyond Yacc (see <a href='#refsYACC'>[YACC]</a>)";
+    test_content += "          are used:</p>";
+    test_content += "      <ul>";
+    test_content += "          <li><b>*</b>: 0 or more";
+    test_content += "          </li><li><b>+</b>: 1 or more";
+    test_content += "          </li><li><b>?</b>: 0 or 1";
+    test_content += "          </li><li><b>|</b>: separates alternatives";
+    test_content += "          </li><li><b>[ ]</b>: grouping</li>";
+    test_content += "      </ul>";
+    test_content += "      <p>The productions are:</p>";
+    test_content += "      <pre>selectors_group";
+    test_content += "        ;</pre>";
+    test_content += "      <h3><a name='lex'>10.2. Lexical scanner</a></h3>";
+    test_content += "      <p>The following is the <a name='x3'>tokenizer</a>, written in Flex (see";
+    test_content += "          <a href='#refsFLEX'>[FLEX]</a>) notation. The tokenizer is";
+    test_content += "          case-insensitive.</p>";
+    test_content += "      <p>The two occurrences of '\377' represent the highest character";
+    test_content += "          possible code point in Unicode/ISO-10646. <a href='#refsUNICODE'>[UNICODE]</a></p>";
+    test_content += "      <pre>%option case-insensitive";
+    test_content += "      .                return *yytext;</pre>";
+    test_content += "      <h2><a name='downlevel'>11. Namespaces and down-level clients</a></h2>";
+    test_content += "      <p>An important issue is the interaction of CSS selectors with XML";
+    test_content += "          to construct a CSS style sheet which will properly match selectors in";
+    test_content += "          is possible to construct a style sheet in which selectors would match";
+    test_content += "          elements and attributes correctly.</p>";
+    test_content += "      <p>It should be noted that a down-level CSS client will (if it";
+    test_content += "          <code>@namespace</code> at-rules, as well as all style rules that make";
+    test_content += "          use of namespace qualified element type or attribute selectors. The";
+    test_content += "          than possibly match them incorrectly.</p>";
+    test_content += "      <p>The use of default namespaces in CSS makes it possible to write";
+    test_content += "          element type selectors that will function in both namespace aware CSS";
+    test_content += "          down-level clients may incorrectly match selectors against XML";
+    test_content += "          elements in other namespaces.</p>";
+    test_content += "      <p>The following are scenarios and examples in which it is possible to";
+    test_content += "          that do not implement this proposal.</p>";
+    test_content += "      <ol>";
+    test_content += "          <li>";
+    test_content += "              <p>The XML document does not use namespaces.</p>";
+    test_content += "              <ul>";
+    test_content += "                  <li>In this case, it is obviously not necessary to declare or use";
+    test_content += "                      attribute selectors will function adequately in a down-level";
+    test_content += "                  </li>";
+    test_content += "                  <li>In a CSS namespace aware client, the default behavior of";
+    test_content += "                      element selectors matching without regard to namespace will";
+    test_content += "                      present. However, the use of specific element type selectors";
+    test_content += "                      match only elements that have no namespace ('<code>|name</code>')";
+    test_content += "                      will guarantee that selectors will match only XML elements that";
+    test_content += "                  </li>";
+    test_content += "              </ul>";
+    test_content += "          </li>";
+    test_content += "          <li>";
+    test_content += "              <p>The XML document defines a single, default namespace used";
+    test_content += "                  names.</p>";
+    test_content += "              <ul>";
+    test_content += "                  <li>In this case, a down-level client will function as if";
+    test_content += "                      element type and attribute selectors will match against all";
+    test_content += "                  </li>";
+    test_content += "              </ul>";
+    test_content += "          </li>";
+    test_content += "          <li>";
+    test_content += "              <p>The XML document does <b>not</b> use a default namespace, all";
+    test_content += "                  to the same URI).</p>";
+    test_content += "              <ul>";
+    test_content += "                  <li>In this case, the down-level client will view and match";
+    test_content += "                      element type and attribute selectors based on their fully";
+    test_content += "                      qualified name, not the local part as outlined in the <a href='#typenmsp'>Type selectors and Namespaces</a>";
+    test_content += "                      selectors may be declared using an escaped colon";
+    test_content += "                      '<code>\\:</code>'";
+    test_content += "                      '<code>html\\:h1</code>' will match";
+    test_content += "                      <code>&lt;html:h1&gt;</code>. Selectors using the qualified name";
+    test_content += "                  </li>";
+    test_content += "                  <li>Note that selectors declared in this fashion will";
+    test_content += "                      <em>only</em> match in down-level clients. A CSS namespace aware";
+    test_content += "                      client will match element type and attribute selectors based on";
+    test_content += "                      the name's local part. Selectors declared with the fully";
+    test_content += "                  </li>";
+    test_content += "              </ul>";
+    test_content += "          </li>";
+    test_content += "      </ol>";
+    test_content += "      <p>In other scenarios: when the namespace prefixes used in the XML are";
+    test_content += "          <em>different</em> namespace URIs within the same document, or in";
+    test_content += "          a CSS and XML namespace aware client.</p>";
+    test_content += "      <h2><a name='profiling'>12. Profiles</a></h2>";
+    test_content += "      <p>Each specification using Selectors must define the subset of W3C";
+    test_content += "          Selectors it allows and excludes, and describe the local meaning of";
+    test_content += "          all the components of that subset.</p>";
+    test_content += "      <p>Non normative examples:";
+    test_content += "      </p><div class='profile'>";
+    test_content += "          <table class='tprofile'>";
+    test_content += "              <tbody>";
+    test_content += "              <tr>";
+    test_content += "                  <th class='title' colspan='2'>Selectors profile</th>";
+    test_content += "              </tr>";
+    test_content += "              <tr>";
+    test_content += "                  <th>Specification</th>";
+    test_content += "                  <td>CSS level 1</td>";
+    test_content += "              </tr>";
+    test_content += "              <tr>";
+    test_content += "                  <th>Accepts</th>";
+    test_content += "                  <td>type selectors<br>class selectors<br>ID selectors<br>:link,";
+    test_content += "                      :visited and :active pseudo-classes<br>descendant combinator";
+    test_content += "                      <br>::first-line and ::first-letter pseudo-elements";
+    test_content += "                  </td>";
+    test_content += "              </tr>";
+    test_content += "              <tr>";
+    test_content += "                  <th>Excludes</th>";
+    test_content += "                  <td>";
+    test_content += "                      <p>universal selector<br>attribute selectors<br>:hover and";
+    test_content += "                          pseudo-classes<br>:target pseudo-class<br>:lang()";
+    test_content += "                          pseudo-class<br>all UI";
+    test_content += "                          element states pseudo-classes<br>all structural";
+    test_content += "                          pseudo-classes<br>negation pseudo-class<br>all";
+    test_content += "                          UI element fragments pseudo-elements<br>::before and ::after";
+    test_content += "                          pseudo-elements<br>child combinators<br>sibling combinators";
+    test_content += "                      </p><p>namespaces</p></td>";
+    test_content += "              </tr>";
+    test_content += "              <tr>";
+    test_content += "                  <th>Extra constraints</th>";
+    test_content += "                  <td>only one class selector allowed per sequence of simple";
+    test_content += "                      selectors";
+    test_content += "                  </td>";
+    test_content += "              </tr>";
+    test_content += "              </tbody>";
+    test_content += "          </table>";
+    test_content += "          <br><br>";
+    test_content += "          <table class='tprofile'>";
+    test_content += "              <tbody>";
+    test_content += "              <tr>";
+    test_content += "                  <th class='title' colspan='2'>Selectors profile</th>";
+    test_content += "              </tr>";
+    test_content += "              <tr>";
+    test_content += "                  <th>Specification</th>";
+    test_content += "                  <td>CSS level 2</td>";
+    test_content += "              </tr>";
+    test_content += "              <tr>";
+    test_content += "                  <th>Accepts</th>";
+    test_content += "                  <td>type selectors<br>universal selector<br>attribute presence and";
+    test_content += "                      values selectors<br>class selectors<br>ID selectors<br>:link,";
+    test_content += "                      <br>descendant combinator<br>child combinator<br>adjacent";
+    test_content += "                      combinator<br>::first-line and ::first-letter";
+    test_content += "                      pseudo-elements<br>::before";
+    test_content += "                  </td>";
+    test_content += "              </tr>";
+    test_content += "              <tr>";
+    test_content += "                  <th>Excludes</th>";
+    test_content += "                  <td>";
+    test_content += "                      <p>content selectors<br>substring matching attribute";
+    test_content += "                          selectors<br>:target pseudo-classes<br>all UI element";
+    test_content += "                          states pseudo-classes<br>all structural pseudo-classes other";
+    test_content += "                          than :first-child<br>negation pseudo-class<br>all UI element";
+    test_content += "                          fragments pseudo-elements<br>general sibling combinators";
+    test_content += "                      </p><p>namespaces</p></td>";
+    test_content += "              </tr>";
+    test_content += "              <tr>";
+    test_content += "                  <th>Extra constraints</th>";
+    test_content += "                  <td>more than one class selector per sequence of simple selectors";
+    test_content += "                  </td>";
+    test_content += "              </tr>";
+    test_content += "              </tbody>";
+    test_content += "          </table>";
+    test_content += "          <p>In CSS, selectors express pattern matching rules that determine which";
+    test_content += "          </p><p>The following selector (CSS level 2) will <b>match</b> all anchors <code>a</code>";
+    test_content += "              with attribute <code>name</code> set inside a section 1 header";
+    test_content += "              <code>h1</code>:";
+    test_content += "          </p><pre>h1 a[name]</pre>";
+    test_content += "          <p>All CSS declarations attached to such a selector are applied to elements";
+    test_content += "              matching it.</p></div>";
+    test_content += "      <div class='profile'>";
+    test_content += "          <table class='tprofile'>";
+    test_content += "              <tbody>";
+    test_content += "              <tr>";
+    test_content += "                  <th class='title' colspan='2'>Selectors profile</th>";
+    test_content += "              </tr>";
+    test_content += "              <tr>";
+    test_content += "                  <th>Specification</th>";
+    test_content += "                  <td>STTS 3</td>";
+    test_content += "              </tr>";
+    test_content += "              <tr>";
+    test_content += "                  <th>Accepts</th>";
+    test_content += "                  <td>";
+    test_content += "                      <p>type selectors<br>universal selectors<br>attribute";
+    test_content += "                          selectors<br>class";
+    test_content += "                          selectors<br>ID selectors<br>all structural";
+    test_content += "                          pseudo-classes<br>";
+    test_content += "                      </p><p>namespaces</p></td>";
+    test_content += "              </tr>";
+    test_content += "              <tr>";
+    test_content += "                  <th>Excludes</th>";
+    test_content += "                  <td>non-accepted pseudo-classes<br>pseudo-elements<br></td>";
+    test_content += "              </tr>";
+    test_content += "              <tr>";
+    test_content += "                  <th>Extra constraints</th>";
+    test_content += "                  <td>some selectors and combinators are not allowed in fragment";
+    test_content += "                  </td>";
+    test_content += "              </tr>";
+    test_content += "              </tbody>";
+    test_content += "          </table>";
+    test_content += "          <p>Selectors can be used in STTS 3 in two different";
+    test_content += "          </p><ol>";
+    test_content += "              <li>a selection mechanism equivalent to CSS selection mechanism:";
+    test_content += "              </li><li>fragment descriptions that appear on the right side of declarations.";
+    test_content += "              </li>";
+    test_content += "          </ol>";
+    test_content += "      </div>";
+    test_content += "      <h2><a name='Conformance'></a>13. Conformance and requirements</h2>";
+    test_content += "      <p>This section defines conformance with the present specification only.";
+    test_content += "      </p><p>The inability of a user agent to implement part of this specification due to";
+    test_content += "      </p><p>All specifications reusing Selectors must contain a <a href='#profiling'>Profile</a> listing the";
+    test_content += "          subset of Selectors it accepts or excludes, and describing the constraints";
+    test_content += "      </p><p>Invalidity is caused by a parsing error, e.g. an unrecognized token or a";
+    test_content += "      </p><p>User agents must observe the rules for handling parsing errors:";
+    test_content += "      </p><ul>";
+    test_content += "          <li>a simple selector containing an undeclared namespace prefix is invalid";
+    test_content += "          </li>";
+    test_content += "          <li>a selector containing an invalid simple selector, an invalid combinator";
+    test_content += "          </li>";
+    test_content += "          <li>a group of selectors containing an invalid selector is invalid.</li>";
+    test_content += "      </ul>";
+    test_content += "      <p>Specifications reusing Selectors must define how to handle parsing";
+    test_content += "          used is dropped.)</p>";
+    test_content += "      <!-- Apparently all these references are out of date:";
+    test_content += "      <p>Implementations of this specification must behave as";
+    test_content += "      'recipients of text data' as defined by <a href='#refsCWWW'>[CWWW]</a>";
+    test_content += "      when parsing selectors and attempting matches. (In particular,";
+    test_content += "      <a href='#refsCWWW'>[CWWW]</a> and <a";
+    test_content += "      href='#refsUNICODE'>[UNICODE]</a> and apply to implementations of this";
+    test_content += "      specification.</p>-->";
+    test_content += "      <h2><a name='Tests'></a>14. Tests</h2>";
+    test_content += "      <p>This specification has <a href='http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/'>a test";
+    test_content += "          suite</a> allowing user agents to verify their basic conformance to";
+    test_content += "          and does not cover all possible combined cases of Selectors.</p>";
+    test_content += "      <h2><a name='ACKS'></a>15. Acknowledgements</h2>";
+    test_content += "      <p>The CSS working group would like to thank everyone who has sent";
+    test_content += "          comments on this specification over the years.</p>";
+    test_content += "      <p>The working group would like to extend special thanks to Donna";
+    test_content += "          the final editorial review.</p>";
+    test_content += "      <h2><a name='references'>16. References</a></h2>";
+    test_content += "      <dl class='refs'>";
+    test_content += "          <dt>[CSS1]";
+    test_content += "          </dt><dd><a name='refsCSS1'></a> Bert Bos, Håkon Wium Lie; '<cite>Cascading";
+    test_content += "              Style Sheets, level 1</cite>', W3C Recommendation, 17 Dec 1996, revised";
+    test_content += "          </dd><dd>(<code><a href='http://www.w3.org/TR/REC-CSS1'>http://www.w3.org/TR/REC-CSS1</a></code>)";
+    test_content += "          </dd><dt>[CSS21]";
+    test_content += "          </dt><dd><a name='refsCSS21'></a> Bert Bos, Tantek Çelik, Ian Hickson, Håkon";
+    test_content += "              Wium Lie, editors; '<cite>Cascading Style Sheets, level 2 revision";
+    test_content += "                  1</cite>', W3C Working Draft, 13 June 2005";
+    test_content += "          </dd><dd>(<code><a href='http://www.w3.org/TR/CSS21'>http://www.w3.org/TR/CSS21</a></code>)";
+    test_content += "          </dd><dt>[CWWW]";
+    test_content += "          </dt><dd><a name='refsCWWW'></a> Martin J. Dürst, François Yergeau,";
+    test_content += "              Misha Wolf, Asmus Freytag, Tex Texin, editors; '<cite>Character Model";
+    test_content += "                  for the World Wide Web</cite>', W3C Recommendation, 15 February 2005";
+    test_content += "          </dd><dd>(<code><a href='http://www.w3.org/TR/charmod/'>http://www.w3.org/TR/charmod/</a></code>)";
+    test_content += "          </dd><dt>[FLEX]";
+    test_content += "          </dt><dd><a name='refsFLEX'></a> '<cite>Flex: The Lexical Scanner";
+    test_content += "              Generator</cite>', Version 2.3.7, ISBN 1882114213";
+    test_content += "          </dd><dt>[HTML4]";
+    test_content += "          </dt><dd><a name='refsHTML4'></a> Dave Ragget, Arnaud Le Hors, Ian Jacobs,";
+    test_content += "              editors; '<cite>HTML 4.01 Specification</cite>', W3C Recommendation, 24";
+    test_content += "          </dd><dd>";
+    test_content += "              (<a href='http://www.w3.org/TR/html4/'><code>http://www.w3.org/TR/html4/</code></a>)";
+    test_content += "          </dd><dt>[MATH]";
+    test_content += "          </dt><dd><a name='refsMATH'></a> Patrick Ion, Robert Miner, editors; '<cite>Mathematical";
+    test_content += "              Markup Language (MathML) 1.01</cite>', W3C Recommendation, revision of 7";
+    test_content += "          </dd><dd>(<code><a href='http://www.w3.org/TR/REC-MathML/'>http://www.w3.org/TR/REC-MathML/</a></code>)";
+    test_content += "          </dd><dt>[RFC3066]";
+    test_content += "          </dt><dd><a name='refsRFC3066'></a> H. Alvestrand; '<cite>Tags for the";
+    test_content += "              Identification of Languages</cite>', Request for Comments 3066, January";
+    test_content += "          </dd><dd>(<a href='http://www.ietf.org/rfc/rfc3066.txt'><code>http://www.ietf.org/rfc/rfc3066.txt</code></a>)";
+    test_content += "          </dd><dt>[STTS]";
+    test_content += "          </dt><dd><a name='refsSTTS'></a> Daniel Glazman; '<cite>Simple Tree Transformation";
+    test_content += "              Sheets 3</cite>', Electricité de France, submission to the W3C,";
+    test_content += "          </dd><dd>(<code><a href='http://www.w3.org/TR/NOTE-STTS3'>http://www.w3.org/TR/NOTE-STTS3</a></code>)";
+    test_content += "          </dd><dt>[SVG]";
+    test_content += "          </dt><dd><a name='refsSVG'></a> Jon Ferraiolo, 藤沢 淳, Dean";
+    test_content += "              Jackson, editors; '<cite>Scalable Vector Graphics (SVG) 1.1";
+    test_content += "                  Specification</cite>', W3C Recommendation, 14 January 2003";
+    test_content += "          </dd><dd>(<code><a href='http://www.w3.org/TR/SVG/'>http://www.w3.org/TR/SVG/</a></code>)";
+    test_content += "          </dd><dt>[UNICODE]</dt>";
+    test_content += "          <dd><a name='refsUNICODE'></a> <cite><a href='http://www.unicode.org/versions/Unicode4.1.0/'>The Unicode";
+    test_content += "              Standard, Version 4.1</a></cite>, The Unicode Consortium. Boston, MA,";
+    test_content += "              Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by <a href='http://www.unicode.org/versions/Unicode4.0.1/'>Unicode";
+    test_content += "                  4.0.1</a> and <a href='http://www.unicode.org/versions/Unicode4.1.0/'>Unicode";
+    test_content += "                  4.1.0</a>.";
+    test_content += "          </dd><dd>(<code><a href='http://www.unicode.org/versions/'>http://www.unicode.org/versions/</a></code>)";
+    test_content += "          </dd>";
+    test_content += "          <dt>[XML10]";
+    test_content += "          </dt><dd><a name='refsXML10'></a> Tim Bray, Jean Paoli, C. M. Sperberg-McQueen,";
+    test_content += "              Eve Maler, François Yergeau, editors; '<cite>Extensible Markup";
+    test_content += "                  Language (XML) 1.0 (Third Edition)</cite>', W3C Recommendation, 4";
+    test_content += "          </dd><dd>(<a href='http://www.w3.org/TR/REC-xml/'><code>http://www.w3.org/TR/REC-xml/</code></a>)";
+    test_content += "          </dd><dt>[XMLNAMES]";
+    test_content += "          </dt><dd><a name='refsXMLNAMES'></a> Tim Bray, Dave Hollander, Andrew Layman,";
+    test_content += "              editors; '<cite>Namespaces in XML</cite>', W3C Recommendation, 14";
+    test_content += "          </dd><dd>(<a href='http://www.w3.org/TR/REC-xml-names/'><code>http://www.w3.org/TR/REC-xml-names/</code></a>)";
+    test_content += "          </dd><dt>[YACC]";
+    test_content += "          </dt><dd><a name='refsYACC'></a> S. C. Johnson; '<cite>YACC — Yet another";
+    test_content += "              compiler compiler</cite>', Technical Report, Murray Hill, 1975";
+    test_content += "      </dd></dl>'; </div>";
+    test_content += "      <input name='n' value='v1' type='radio'>1";
+    test_content += "      <input name='n' value='v2' checked='checked' type='radio'>2";
+    test_content += "</body></html>";
+    return test_content;
+  }
+
 }