jenkins-bot has submitted this change and it was merged.

Change subject: Update domino to 1.0.17
......................................................................


Update domino to 1.0.17

Change-Id: Ic8b011fa4b3b13918977b6fceaeb7f3d58b3df07
---
M node_modules/domino/.travis.yml
A node_modules/domino/CHANGELOG.md
M node_modules/domino/README.md
M node_modules/domino/lib/DOMTokenList.js
M node_modules/domino/lib/Element.js
M node_modules/domino/lib/HTMLParser.js
M node_modules/domino/lib/Node.js
M node_modules/domino/lib/htmlelts.js
M node_modules/domino/lib/select.js
M node_modules/domino/package.json
M node_modules/domino/test/domino.js
M node_modules/domino/test/w3c/harness/index.js
12 files changed, 316 insertions(+), 111 deletions(-)

Approvals:
  Subramanya Sastry: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/node_modules/domino/.travis.yml b/node_modules/domino/.travis.yml
index 2cde307..f238dc5 100644
--- a/node_modules/domino/.travis.yml
+++ b/node_modules/domino/.travis.yml
@@ -1,9 +1,6 @@
 language: node_js
 node_js:
-  - 0.4
-  - 0.6
-  - 0.7
   - 0.8
-  - 0.9
   - 0.10
   - 0.11
+script: npm run test-spec
diff --git a/node_modules/domino/CHANGELOG.md b/node_modules/domino/CHANGELOG.md
new file mode 100644
index 0000000..82bff5b
--- /dev/null
+++ b/node_modules/domino/CHANGELOG.md
@@ -0,0 +1,67 @@
+# domino 1.0.17 (14 May 2014)
+* Brown paper bag bug fix for an HTML parsing regression introduced in
+  domino 1.0.16. (#45)
+* Update `mocha` dependency to 1.18.x and `should` to 3.3.x.
+
+# domino 1.0.16 (13 May 2014)
+**DO NOT USE:** contains parser regression, fixed in 1.0.17.
+* Various performance improvements to the HTML5 parser. (#43, #44)
+* Fix `Element#isHTML` for non-HTML elements. (#41)
+
+# domino 1.0.15 (21 Jan 2014)
+* Implement `Element#matches()`.
+* Fix CSS `[lang]`, `[dir]`, etc selectors.
+* Update `mocha` dependency to 1.17.x.
+
+# domino 1.0.14 (21 Dec 2013)
+* `Element#classList.length` should be 0 if there's no `class`
+  attribute.
+* Add `height`/`width` attributes to `HTMLImageElement`.
+* Fix node 0.11 incompatibility in the w3c test harness.
+* Update `mocha` dependency to 1.16.x; update `should` dependency to 2.1.x.
+
+# domino 1.0.13 (8 Oct 2013)
+* Include `<th>` elements in `HTMLTableRowElement#cells`. (#38, #39)
+* Fix old call to `toLowerCase()` function. (#37)
+* Update `mocha` and `should` dependencies.
+
+# domino 1.0.12 (9 Jul 2013)
+* Fix bug in formatting element adoption agency algorithm. (#36)
+* Coerce `document.createTextNode` argument to a string. (#34, #35)
+* Work around performance regression in node <= 0.6.
+
+# domino 1.0.11 (1 May 2013)
+* Fix rooted element traversal (`Element#nextElement`,
+  `Element#getElementsByTagName`).  (#31, #32)
+* Update zest to fix bugs in `+` and `>` combinators.
+* Don't overflow the stack if attribute values are very large (>64k).
+
+# domino 1.0.10 (12 Apr 2013)
+* Document issues with `Element#attributes`. (#27)
+* Fix `Document#title` to match DOM spec. (#29)
+* Add missing `require('utils')` for `handleErrors`. (#28)
+* Implement `DocumentFragment#querySelector` and
+  `DocumentFragment#querySelectorAll`. (#20, #26)
+* Fix `querySelectorAll` on unparented `Element`s. (#23)
+* Move `outerHTML`/`innerHTML` properties from `HTMLElement` to
+  `Element` to match dom parsing spec. (#21)
+* Update zest selector library to 0.0.4. (#25)
+* Fix regression in node 0.10. (#22, #24)
+* Update `mocha` and `should` dependencies.
+
+# domino 1.0.9 (11 Mar 2013)
+* Support jQuery 1.9.x by allowing `Element#attributes[qname]`.
+* Implement `HTMLElement#outerHTML`. (#18)
+* Only add newlines after `<pre>`/`<textarea>`/`<listing>` if
+  necessary, to match HTML5 serialization spec. (#16, #17)
+* Mirror node type properties (`ELEMENT_NODE`, etc) into
+  `Node.prototype`. (#14, #15)
+
+# domino 1.0.8
+
+**DO NOT USE:** was inadvertently published identical to domino 1.0.7.
+
+# domino 1.0.7 (16 Jan 2013)
+* Throw `SyntaxError` upon invocation rather than build-time. (#10)
+* Return nodes in document order. (#11)
+* Added a TreeWalker implementation.
diff --git a/node_modules/domino/README.md b/node_modules/domino/README.md
index a3bc604..c3c2d3e 100644
--- a/node_modules/domino/README.md
+++ b/node_modules/domino/README.md
@@ -24,7 +24,7 @@
 
 ## CSS Selector Support
 
-Domino provides support for `querySelector()` and `querySelectorAll()` backed 
by the [Zest](https://github.com/chjj/zest) selector engine.
+Domino provides support for `querySelector()`, `querySelectorAll()`, and 
`matches()` backed by the [Zest](https://github.com/chjj/zest) selector engine.
 
 ## Usage
 
diff --git a/node_modules/domino/lib/DOMTokenList.js 
b/node_modules/domino/lib/DOMTokenList.js
index c91e935..d946627 100644
--- a/node_modules/domino/lib/DOMTokenList.js
+++ b/node_modules/domino/lib/DOMTokenList.js
@@ -6,7 +6,7 @@
 function DOMTokenList(getter, setter) {
   this._getString = getter;
   this._setString = setter;
-  fixIndex(this, getter().split(" "));
+  fixIndex(this, getList(this));
 }
 
 DOMTokenList.prototype = {
diff --git a/node_modules/domino/lib/Element.js 
b/node_modules/domino/lib/Element.js
index c034208..35e7e3a 100644
--- a/node_modules/domino/lib/Element.js
+++ b/node_modules/domino/lib/Element.js
@@ -218,7 +218,7 @@
   }},
 
   // Overwritten in the constructor if not in the HTML namespace
-  isHTML: { value: true },
+  isHTML: { value: true, writable: true },
 
   // Utility methods used by the public API methods above
   clone: { value: function clone() {
@@ -680,6 +680,10 @@
     return dtlist;
   }},
 
+  matches: { value: function(selector) {
+    return select.matches(this, selector);
+  }},
+
   querySelector: { value: function(selector) {
     return select(selector, this)[0];
   }},
diff --git a/node_modules/domino/lib/HTMLParser.js 
b/node_modules/domino/lib/HTMLParser.js
index 7a213cd..03f3f06 100644
--- a/node_modules/domino/lib/HTMLParser.js
+++ b/node_modules/domino/lib/HTMLParser.js
@@ -1438,11 +1438,24 @@
 // Like the above, but for named char refs, the last char can't be =
 var ATTRCHARREF = 
/^#[0-9]+[^0-9]|^#[xX][0-9a-fA-F]+[^0-9a-fA-F]|^[a-zA-Z][a-zA-Z0-9]*[^=a-zA-Z0-9]/;
 
+// note that \r is included in all of these regexps because it will need
+// to be converted to LF by the scanChars() function.
+var DBLQUOTEATTRVAL = /[^\r"&\u0000]+/g;
+var SINGLEQUOTEATTRVAL = /[^\r'&\u0000]+/g;
+var UNQUOTEDATTRVAL = /[^\r\t\n\f &>\u0000]+/g;
+var TAGNAME = /[^\r\t\n\f \/>A-Z\u0000]+/g;
+var ATTRNAME = /[^\r\t\n\f \/=>A-Z\u0000]+/g;
+
 var DATATEXT = /[^&<\r\u0000\uffff]*/g;
 var RAWTEXT = /[^<\r\u0000\uffff]*/g;
 var PLAINTEXT = /[^\r\u0000\uffff]*/g;
-var SIMPLETAG = /^(\/)?([a-z]+)>/g;
-var SIMPLEATTR = /^([a-z]+) *= *('[^'&\r\u0000]*'|"[^"&\r\u0000]*"|[^&> 
\t\n\r\f\u0000][ \t\n\f])/g;
+// Since we don't have the 'sticky tag', add '|.' to the end of SIMPLETAG
+// and SIMPLEATTR so that we are guaranteed to always match.  This prevents
+// us from scanning past the lastIndex set. (Note that the desired matches
+// are always greater than 1 char long, so longest-match will ensure that .
+// is not matched unless the desired match fails.)
+var SIMPLETAG = /(?:(\/)?([a-z]+)>)|[\s\S]/g;
+var SIMPLEATTR = /(?:([-a-z]+)[ \t\n\f]*=[ 
\t\n\f]*('[^'&\r\u0000]*'|"[^"&\r\u0000]*"|[^\t\n\r\f "&'\u0000>][^&> 
\t\n\r\f\u0000]*[ \t\n\f]))|[\s\S]/g;
 
 var NONWS = /[^\x09\x0A\x0C\x0D\x20]/;
 var ALLNONWS = /[^\x09\x0A\x0C\x0D\x20]/g; // like above, with g flag
@@ -1853,11 +1866,11 @@
   // Tokenizer state
   var tokenizer = data_state; // Current tokenizer state
   var savedTokenizerStates = []; // Stack of saved states
-  var tagnamebuf = [];
+  var tagnamebuf = "";
   var lasttagname = ""; // holds the target end tag for text states
   var tempbuf = [];
-  var attrnamebuf = [];
-  var attrvaluebuf = [];
+  var attrnamebuf = "";
+  var attrvaluebuf = "";
   var commentbuf = [];
   var doctypenamebuf = [];
   var doctypepublicbuf = [];
@@ -2234,18 +2247,15 @@
   /***
    * Tokenizer utility functions
    */
-  function addAttribute(namebuf,valuebuf) {
-    var name = buf2str(namebuf);
-    var value;
-
+  function addAttribute(name,value) {
     // Make sure there isn't already an attribute with this name
     // If there is, ignore this one.
     for(var i = 0; i < attributes.length; i++) {
       if (attributes[i][0] === name) return;
     }
 
-    if (valuebuf) {
-      attributes.push([name, buf2str(valuebuf)]);
+    if (value !== undefined) {
+      attributes.push([name, value]);
     }
     else {
       attributes.push([name]);
@@ -2256,8 +2266,9 @@
   function handleSimpleAttribute() {
     SIMPLEATTR.lastIndex = nextchar-1;
     var matched = SIMPLEATTR.exec(chars);
-    if (!matched) return false;
+    if (!matched) throw new Error("should never happen");
     var name = matched[1];
+    if (!name) return false;
     var value = matched[2];
     var len = value.length;
     switch(value[0]) {
@@ -2289,18 +2300,18 @@
   function popState() { tokenizer = savedTokenizerStates.pop(); }
   function beginTagName() {
     is_end_tag = false;
-    tagnamebuf.length = 0;
+    tagnamebuf = "";
     attributes.length = 0;
   }
   function beginEndTagName() {
     is_end_tag = true;
-    tagnamebuf.length = 0;
+    tagnamebuf = "";
     attributes.length = 0;
   }
 
   function beginTempBuf() { tempbuf.length = 0; }
-  function beginAttrName() { attrnamebuf.length = 0; }
-  function beginAttrValue() { attrvaluebuf.length = 0; }
+  function beginAttrName() { attrnamebuf = ""; }
+  function beginAttrValue() { attrvaluebuf = ""; }
   function beginComment() { commentbuf.length = 0; }
   function beginDoctype() {
     doctypenamebuf.length = 0;
@@ -2318,11 +2329,7 @@
   // Return true if the codepoints in the specified buffer match the
   // characters of lasttagname
   function appropriateEndTag(buf) {
-    if (buf.length !== lasttagname.length) return false;
-    for(var i = 0, n = buf.length; i < n; i++) {
-      if (buf[i] !== lasttagname.charCodeAt(i)) return false;
-    }
-    return true;
+    return lasttagname === buf;
   }
 
   function flushText() {
@@ -2340,6 +2347,21 @@
       textIncludesNUL = false;
     }
     ignore_linefeed = false;
+  }
+
+  // Consume chars matched by the pattern and return them as a string. Starts
+  // matching at the current position, so users should drop the current char
+  // otherwise.
+  function getMatchingChars(pattern) {
+      pattern.lastIndex = nextchar - 1;
+      var match = pattern.exec(chars);
+      if (match && match.index === nextchar - 1) {
+          match = match[0];
+          nextchar += match.length - 1;
+          return match;
+      } else {
+          throw new Error("should never happen");
+      }
   }
 
   // emit a string of chars that match a regexp
@@ -2367,11 +2389,11 @@
   }
 
   function emitTag() {
-    if (is_end_tag) insertToken(ENDTAG, buf2str(tagnamebuf));
+    if (is_end_tag) insertToken(ENDTAG, tagnamebuf);
     else {
       // Remember the last open tag we emitted
-      var tagname = buf2str(tagnamebuf);
-      tagnamebuf.length = 0;
+      var tagname = tagnamebuf;
+      tagnamebuf = "";
       lasttagname = tagname;
       insertToken(TAG, tagname, attributes);
     }
@@ -2383,8 +2405,9 @@
   function emitSimpleTag() {
     SIMPLETAG.lastIndex = nextchar;
     var matched = SIMPLETAG.exec(chars);
-    if (!matched) return false;
+    if (!matched) throw new Error("should never happen");
     var tagname = matched[2];
+    if (!tagname) return false;
     var endtag = matched[1];
     if (endtag) {
       nextchar += (tagname.length+2);
@@ -2399,9 +2422,9 @@
   }
 
   function emitSelfClosingTag() {
-    if (is_end_tag) insertToken(ENDTAG, buf2str(tagnamebuf), null, true);
+    if (is_end_tag) insertToken(ENDTAG, tagnamebuf, null, true);
     else {
-      insertToken(TAG, buf2str(tagnamebuf), attributes, true);
+      insertToken(TAG, tagnamebuf, attributes, true);
     }
   }
 
@@ -2418,7 +2441,7 @@
     doc.modclock = 1; // Start tracking modifications
   }
 
-  // Insert a token, either using the current parser insertio mode
+  // Insert a token, either using the current parser insertion mode
   // (for HTML stuff) or using the insertForeignToken() method.
   function insertToken(t, value, arg3, arg4) {
     flushText();
@@ -3187,9 +3210,10 @@
     case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-      c += 0x20; // to lowercase
-      /* falls through */
-
+      beginTagName();
+      tagnamebuf += String.fromCharCode(c + 0x0020 /* to lowercase */);
+      tokenizer = tag_name_state;
+      break;
     case 0x0061:  // [a-z]
     case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
     case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
@@ -3197,7 +3221,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
       beginTagName();
-      tagnamebuf.push(c);
+      tagnamebuf += getMatchingChars(TAGNAME);
       tokenizer = tag_name_state;
       break;
     case 0x003F: // QUESTION MARK
@@ -3220,9 +3244,10 @@
     case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-      c += 0x20; // to lowercase
-      /* falls through */
-
+      beginEndTagName();
+      tagnamebuf += String.fromCharCode(c + 0x0020 /* to lowercase */);
+      tokenizer = tag_name_state;
+      break;
     case 0x0061:  // [a-z]
     case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
     case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
@@ -3230,7 +3255,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
       beginEndTagName();
-      tagnamebuf.push(c);
+      tagnamebuf += getMatchingChars(TAGNAME);
       tokenizer = tag_name_state;
       break;
     case 0x003E: // GREATER-THAN SIGN
@@ -3270,18 +3295,17 @@
     case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       break;
     case 0x0000: // NULL
-      tagnamebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
+      tagnamebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
       break;
     case -1: // EOF
       nextchar--; // pushback
       tokenizer = data_state;
       break;
     default:
-      tagnamebuf.push(c);
-      // appendCharsWhile(tagnamebuf, TAGNAMECHARS) || tagnamebuf.push(c);
+      tagnamebuf += getMatchingChars(TAGNAME);
       break;
     }
   }
@@ -3309,7 +3333,7 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
       beginEndTagName();
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       tokenizer = rcdata_end_tag_name_state;
       break;
@@ -3320,7 +3344,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
       beginEndTagName();
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       tokenizer = rcdata_end_tag_name_state;
       break;
@@ -3365,7 +3389,7 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
 
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       return;
     case 0x0061:  // [a-z]
@@ -3375,7 +3399,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
 
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       return;
     default:
@@ -3416,7 +3440,7 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
       beginEndTagName();
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       tokenizer = rawtext_end_tag_name_state;
       break;
@@ -3427,7 +3451,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
       beginEndTagName();
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       tokenizer = rawtext_end_tag_name_state;
       break;
@@ -3471,7 +3495,7 @@
     case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       return;
     case 0x0061:  // [a-z]
@@ -3480,7 +3504,7 @@
     case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       return;
     default:
@@ -3526,7 +3550,7 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
       beginEndTagName();
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       tokenizer = script_data_end_tag_name_state;
       break;
@@ -3537,7 +3561,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
       beginEndTagName();
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       tokenizer = script_data_end_tag_name_state;
       break;
@@ -3582,7 +3606,7 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
 
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       return;
     case 0x0061:  // [a-z]
@@ -3592,7 +3616,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
 
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       return;
     default:
@@ -3751,7 +3775,7 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
       beginEndTagName();
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       tokenizer = script_data_escaped_end_tag_name_state;
       break;
@@ -3762,7 +3786,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
       beginEndTagName();
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       tokenizer = script_data_escaped_end_tag_name_state;
       break;
@@ -3805,7 +3829,7 @@
     case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       return;
     case 0x0061:  // [a-z]
@@ -3814,7 +3838,7 @@
     case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       return;
     default:
@@ -4022,12 +4046,12 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
       beginAttrName();
-      attrnamebuf.push(c + 0x0020);
+      attrnamebuf += String.fromCharCode(c + 0x0020);
       tokenizer = attribute_name_state;
       break;
     case 0x0000: // NULL
       beginAttrName();
-      attrnamebuf.push(0xFFFD);
+      attrnamebuf += String.fromCharCode(0xFFFD);
       tokenizer = attribute_name_state;
       break;
     case -1: // EOF
@@ -4042,7 +4066,11 @@
     default:
       if (handleSimpleAttribute()) break;
       beginAttrName();
-      attrnamebuf.push(c);
+      if (c === 0x003D) {
+        attrnamebuf += '='; // not valid elsewhere in attribute_name_state!
+      } else {
+        attrnamebuf += getMatchingChars(ATTRNAME);
+      }
       tokenizer = attribute_name_state;
       break;
     }
@@ -4075,10 +4103,10 @@
     case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-      attrnamebuf.push(c + 0x0020);
+      attrnamebuf += String.fromCharCode(c + 0x0020);
       break;
     case 0x0000: // NULL
-      attrnamebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
+      attrnamebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
       break;
     case -1: // EOF
       nextchar--; // pushback
@@ -4089,7 +4117,7 @@
     case 0x003C: // LESS-THAN SIGN
       /* falls through */
     default:
-      attrnamebuf.push(c);
+      attrnamebuf += getMatchingChars(ATTRNAME);
       break;
     }
   }
@@ -4123,13 +4151,13 @@
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
       addAttribute(attrnamebuf);
       beginAttrName();
-      attrnamebuf.push(c + 0x0020);
+      attrnamebuf += String.fromCharCode(c + 0x0020);
       tokenizer = attribute_name_state;
       break;
     case 0x0000: // NULL
       addAttribute(attrnamebuf);
       beginAttrName();
-      attrnamebuf.push(0xFFFD);
+      attrnamebuf += String.fromCharCode(0xFFFD);
       tokenizer = attribute_name_state;
       break;
     case -1: // EOF
@@ -4143,7 +4171,7 @@
     default:
       addAttribute(attrnamebuf);
       beginAttrName();
-      attrnamebuf.push(c);
+      attrnamebuf += getMatchingChars(ATTRNAME);
       tokenizer = attribute_name_state;
       break;
     }
@@ -4168,7 +4196,7 @@
       tokenizer = attribute_value_single_quoted_state;
       break;
     case 0x0000: // NULL
-      attrvaluebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
+      attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
       tokenizer = attribute_value_unquoted_state;
       break;
     case 0x003E: // GREATER-THAN SIGN
@@ -4185,7 +4213,7 @@
     case 0x0060: // GRAVE ACCENT
       /* falls through */
     default:
-      attrvaluebuf.push(c);
+      attrvaluebuf += getMatchingChars(UNQUOTEDATTRVAL);
       tokenizer = attribute_value_unquoted_state;
       break;
     }
@@ -4202,15 +4230,18 @@
       tokenizer = character_reference_in_attribute_value_state;
       break;
     case 0x0000: // NULL
-      attrvaluebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
+      attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
       break;
     case -1: // EOF
       nextchar--; // pushback
       tokenizer = data_state;
       break;
+    case 0x000A: // LF
+      // this could be a converted \r, so don't use getMatchingChars
+      attrvaluebuf += String.fromCharCode(c);
+      break;
     default:
-      attrvaluebuf.push(c);
-      // appendCharsWhile(attrvaluebuf, DBLQUOTEATTRVAL);
+      attrvaluebuf += getMatchingChars(DBLQUOTEATTRVAL);
       break;
     }
   }
@@ -4226,15 +4257,18 @@
       tokenizer = character_reference_in_attribute_value_state;
       break;
     case 0x0000: // NULL
-      attrvaluebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
+      attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
       break;
     case -1: // EOF
       nextchar--; // pushback
       tokenizer = data_state;
       break;
+    case 0x000A: // LF
+      // this could be a converted \r, so don't use getMatchingChars
+      attrvaluebuf += String.fromCharCode(c);
+      break;
     default:
-      attrvaluebuf.push(c);
-      // appendCharsWhile(attrvaluebuf, SINGLEQUOTEATTRVAL);
+      attrvaluebuf += getMatchingChars(SINGLEQUOTEATTRVAL);
       break;
     }
   }
@@ -4258,7 +4292,7 @@
       emitTag();
       break;
     case 0x0000: // NULL
-      attrvaluebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
+      attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
       break;
     case -1: // EOF
       nextchar--; // pushback
@@ -4271,8 +4305,7 @@
     case 0x0060: // GRAVE ACCENT
       /* falls through */
     default:
-      attrvaluebuf.push(c);
-      // appendCharsWhile(attrvaluebuf, UNQUOTEDATTRVAL);
+      attrvaluebuf += getMatchingChars(UNQUOTEDATTRVAL);
       break;
     }
   }
@@ -4281,16 +4314,14 @@
     var char = parseCharRef(lookahead, true);
     if (char !== null) {
       if (typeof char === "number")
-        attrvaluebuf.push(char);
+        attrvaluebuf += String.fromCharCode(char);
       else {
         // An array of numbers
-        for(var i = 0; i < char.length; i++) {
-          attrvaluebuf.push(char[i]);
-        }
+        attrvaluebuf += String.fromCharCode.apply(String, char);
       }
     }
     else {
-      attrvaluebuf.push(0x0026); // AMPERSAND;
+      attrvaluebuf += '&'; // AMPERSAND;
     }
 
     popState();
diff --git a/node_modules/domino/lib/Node.js b/node_modules/domino/lib/Node.js
index 5cc083d..6b13422 100644
--- a/node_modules/domino/lib/Node.js
+++ b/node_modules/domino/lib/Node.js
@@ -614,13 +614,19 @@
 }
 
 function escapeAttr(s) {
-  return s.replace(/[&"\u00A0]/g, function(c) {
-    switch(c) {
-    case '&': return '&amp;';
-    case '"': return '&quot;';
-    case '\u00A0': return '&nbsp;';
-    }
-  });
+  var toEscape = /[&"\u00A0]/g;
+  if (!toEscape.test(s)) {
+         // nothing to do, fast path
+         return s;
+  } else {
+         return s.replace(toEscape, function(c) {
+               switch(c) {
+               case '&': return '&amp;';
+               case '"': return '&quot;';
+               case '\u00A0': return '&nbsp;';
+               }
+         });
+  }
 }
 
 function attrname(a) {
diff --git a/node_modules/domino/lib/htmlelts.js 
b/node_modules/domino/lib/htmlelts.js
index ab380d2..58d6f15 100644
--- a/node_modules/domino/lib/htmlelts.js
+++ b/node_modules/domino/lib/htmlelts.js
@@ -497,7 +497,9 @@
     alt: String,
     crossOrigin: String,
     useMap: String,
-    isMap: Boolean
+    isMap: Boolean,
+    height: { type: Number, default: 0 },
+    width: { type: Number, default: 0 }
   }
 });
 
diff --git a/node_modules/domino/lib/select.js 
b/node_modules/domino/lib/select.js
index 63576bd..6059cea 100644
--- a/node_modules/domino/lib/select.js
+++ b/node_modules/domino/lib/select.js
@@ -189,12 +189,21 @@
           // getAttribute('title') can be '' when non-existent sometimes?
           attr = el.getAttribute('title') || null;
           break;
+        // careful with attributes with special getter functions
         case 'id':
+        case 'lang':
+        case 'dir':
+        case 'accessKey':
+        case 'hidden':
+        case 'tabIndex':
           if (el.getAttribute) {
-            attr = el.getAttribute('id');
+            attr = el.getAttribute(key);
             break;
           }
         default:
+          if (el.hasAttribute && !el.hasAttribute(key)) {
+            break;
+          }
           attr = el[key] != null
             ? el[key]
             : el.getAttribute && el.getAttribute(key);
@@ -824,7 +833,10 @@
 exports.combinators = combinators;
 
 exports.matches = function(el, sel) {
-  return !!compile(sel)(el);
+  var test = { sel: sel };
+  do {
+    test = compile(test.sel);
+    if (test(el)) { return true; }
+  } while (test.sel);
+  return false;
 };
-
-
diff --git a/node_modules/domino/package.json b/node_modules/domino/package.json
index 7252e64..364568c 100644
--- a/node_modules/domino/package.json
+++ b/node_modules/domino/package.json
@@ -1,6 +1,6 @@
 {
   "name": "domino",
-  "version": "1.0.13",
+  "version": "1.0.17",
   "author": {
     "name": "Felix Gnass",
     "email": "fgn...@gmail.com"
@@ -13,17 +13,18 @@
     "url": "https://github.com/fgnass/domino.git";
   },
   "scripts": {
-    "test": "./node_modules/.bin/mocha"
+    "test": "./node_modules/.bin/mocha",
+    "test-spec": "./node_modules/.bin/mocha -R spec"
   },
   "devDependencies": {
-    "mocha": "~1.13.0",
-    "should": "~1.3.0"
+    "mocha": "~1.18.2",
+    "should": "~3.3.1"
   },
-  "readme": "# Server-side DOM implementation based on Mozilla's 
dom.js\n\n[![Build Status][1]][2] [![dependency status][3]][4] [![dev 
dependency status][5]][6]\n\nAs the name might suggest, domino's goal is to 
provide a <b>DOM in No</b>de.\n\nIn contrast to the original 
[dom.js](https://github.com/andreasgal/dom.js) project, domino was not designed 
to run untrusted code. Hence it doesn't have to hide its internals behind a 
proxy facade which makes the code not only simpler, but also [more 
performant](https://github.com/fgnass/dombench).\n\nDomino currently doesn't 
use any harmony features like proxies or WeakMaps and therefore also runs in 
older Node versions.\n\n## Speed over Compliance\n\nDomino is intended for 
_building_ pages rather than scraping them. Hence Domino doesn't execute 
scripts nor does it download external resources.\n\nAlso Domino doesn't 
implement any properties which have been deprecated in HTML5.\n\nDomino sticks 
to the [DOM level 
4](http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-attr) 
working draft, which means that Attributes do not inherit the Node interface. 
Also 
[Element.attributes](http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-element-attributes)
 returns a read-only array instead of a NamedNodeMap.\n\n<b>Note that</b> 
because domino does not use proxies,\n`Element.attributes` is not a true 
JavaScript array; it is an object\nwith a `length` property and an `item(n)` 
accessor method.  See\n[github issue 
#27](https://github.com/fgnass/domino/issues/27) for\nfurther discussion.\n\n## 
CSS Selector Support\n\nDomino provides support for `querySelector()` and 
`querySelectorAll()` backed by the [Zest](https://github.com/chjj/zest) 
selector engine.\n\n## Usage\n\n```javascript\nvar domino = 
require('domino');\n\nvar window = domino.createWindow('<h1>Hello 
world</h1>');\nvar document = window.document;\n\nvar h1 = 
document.querySelector('h1');\nconsole.log(h1.innerHTML);\n```\n\n## 
Tests\n\nDomino includes test from the [W3C DOM Conformance 
Suites](http://www.w3.org/DOM/Test/)\nas well as tests from [HTML Working 
Group](http://www.w3.org/html/wg/wiki/Testing).\n\nThe tests can be run via 
`npm test` or directly though the [Mocha](http://visionmedia.github.com/mocha/) 
command 
line:\n\n![Screenshot](http://fgnass.github.com/images/domino.png)\n\n## 
License and Credits\n\nThe majority of the code was written by [Andreas 
Gal](https://github.com/andreasgal/) and [David 
Flanagan](https://github.com/davidflanagan) as part of the 
[dom.js](https://github.com/andreasgal/dom.js) project. Please refer to the 
included LICENSE file for the original copyright notice and disclaimer.\n\n[1]: 
https://travis-ci.org/fgnass/domino.png\n[2]: 
https://travis-ci.org/fgnass/domino\n[3]: 
https://david-dm.org/fgnass/domino.png\n[4]: 
https://david-dm.org/fgnass/domino\n[5]: 
https://david-dm.org/fgnass/domino/dev-status.png\n[6]: 
https://david-dm.org/fgnass/domino#info=devDependencies\n";,
+  "readme": "# Server-side DOM implementation based on Mozilla's 
dom.js\n\n[![Build Status][1]][2] [![dependency status][3]][4] [![dev 
dependency status][5]][6]\n\nAs the name might suggest, domino's goal is to 
provide a <b>DOM in No</b>de.\n\nIn contrast to the original 
[dom.js](https://github.com/andreasgal/dom.js) project, domino was not designed 
to run untrusted code. Hence it doesn't have to hide its internals behind a 
proxy facade which makes the code not only simpler, but also [more 
performant](https://github.com/fgnass/dombench).\n\nDomino currently doesn't 
use any harmony features like proxies or WeakMaps and therefore also runs in 
older Node versions.\n\n## Speed over Compliance\n\nDomino is intended for 
_building_ pages rather than scraping them. Hence Domino doesn't execute 
scripts nor does it download external resources.\n\nAlso Domino doesn't 
implement any properties which have been deprecated in HTML5.\n\nDomino sticks 
to the [DOM level 
4](http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-attr) 
working draft, which means that Attributes do not inherit the Node interface. 
Also 
[Element.attributes](http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-element-attributes)
 returns a read-only array instead of a NamedNodeMap.\n\n<b>Note that</b> 
because domino does not use proxies,\n`Element.attributes` is not a true 
JavaScript array; it is an object\nwith a `length` property and an `item(n)` 
accessor method.  See\n[github issue 
#27](https://github.com/fgnass/domino/issues/27) for\nfurther discussion.\n\n## 
CSS Selector Support\n\nDomino provides support for `querySelector()`, 
`querySelectorAll()`, and `matches()` backed by the 
[Zest](https://github.com/chjj/zest) selector engine.\n\n## 
Usage\n\n```javascript\nvar domino = require('domino');\n\nvar window = 
domino.createWindow('<h1>Hello world</h1>');\nvar document = 
window.document;\n\nvar h1 = 
document.querySelector('h1');\nconsole.log(h1.innerHTML);\n```\n\n## 
Tests\n\nDomino includes test from the [W3C DOM Conformance 
Suites](http://www.w3.org/DOM/Test/)\nas well as tests from [HTML Working 
Group](http://www.w3.org/html/wg/wiki/Testing).\n\nThe tests can be run via 
`npm test` or directly though the [Mocha](http://visionmedia.github.com/mocha/) 
command 
line:\n\n![Screenshot](http://fgnass.github.com/images/domino.png)\n\n## 
License and Credits\n\nThe majority of the code was written by [Andreas 
Gal](https://github.com/andreasgal/) and [David 
Flanagan](https://github.com/davidflanagan) as part of the 
[dom.js](https://github.com/andreasgal/dom.js) project. Please refer to the 
included LICENSE file for the original copyright notice and disclaimer.\n\n[1]: 
https://travis-ci.org/fgnass/domino.png\n[2]: 
https://travis-ci.org/fgnass/domino\n[3]: 
https://david-dm.org/fgnass/domino.png\n[4]: 
https://david-dm.org/fgnass/domino\n[5]: 
https://david-dm.org/fgnass/domino/dev-status.png\n[6]: 
https://david-dm.org/fgnass/domino#info=devDependencies\n";,
   "readmeFilename": "README.md",
   "bugs": {
     "url": "https://github.com/fgnass/domino/issues";
   },
-  "_id": "domino@1.0.13",
+  "_id": "domino@1.0.17",
   "_from": "domino@~1.0.13"
 }
diff --git a/node_modules/domino/test/domino.js 
b/node_modules/domino/test/domino.js
index a0df99a..ebf203a 100644
--- a/node_modules/domino/test/domino.js
+++ b/node_modules/domino/test/domino.js
@@ -2,6 +2,19 @@
 var fs = require('fs');
 var html = fs.readFileSync(__dirname + '/fixture/doc.html', 'utf8');
 
+exports = exports.domino = {};
+
+exports.matches = function() {
+  // see https://developer.mozilla.org/en-US/docs/Web/API/Element.matches
+  var d = domino.createWindow(html).document;
+  var h1 = d.getElementById('lorem');
+  h1.matches('h1').should.equal(true);
+  h1.matches('body > h1').should.equal(true); // not rooted
+  h1.matches('h1 > p').should.equal(false);
+  h1.matches('h1,h2').should.equal(true);
+  h1.matches('h2,h1').should.equal(true);
+};
+
 exports.querySelectorAll = function() {
   var window = domino.createWindow(html);
   var d = window.document;
@@ -113,7 +126,7 @@
   var d = domino.createDocument(html);
   var c = d.body.children;
   c.should.have.length(4);
-  c.should.have.property(0);
+  c.should.have.property('0');
   var a = Array.prototype.slice.call(c);
   a.should.be.an.instanceof(Array);
   a.should.have.length(4);
@@ -123,7 +136,7 @@
 }
 
 
-exports.attributes = function() {
+exports.attributes1 = function() {
   var d = domino.createDocument();
   var el = d.createElement('div');
   el.setAttribute('foo', 'foo');
@@ -158,14 +171,14 @@
   cl[0].should.not.equal('foo');
 }
 
-exports.attributes = function() {
+exports.attributes2 = function() {
   var d = domino.createDocument();
   var div = d.createElement('div');
   div.setAttribute('onclick', 't');
   div.attributes.should.have.property('onclick');
   div.attributes.onclick.should.have.property('value', 't');
   div.removeAttribute('onclick');
-  div.attributes.should.not.have.property('onclick');
+  (div.attributes.onclick === undefined).should.be.true;
 }
 
 exports.jquery = function() {
@@ -264,3 +277,72 @@
   var doc = domino.createDocument(html);
   doc.body.innerHTML.should.equal(html);
 };
+
+exports.attributeSelector = function() {
+  var html = '<h1>foo</h1><h2 id="x" title="y" lang="en" dir="ltr" ' +
+    'accessKey="z" hidden tabIndex="2">bar</h2>';
+  var doc = domino.createDocument(html);
+  var h1 = doc.querySelector('h1');
+  h1.matches('*[id]').should.equal(false);
+  h1.matches('*[title]').should.equal(false);
+  h1.matches('*[lang]').should.equal(false);
+  h1.matches('*[dir]').should.equal(false);
+  h1.matches('*[accessKey]').should.equal(false);
+  h1.matches('*[hidden]').should.equal(false);
+  h1.matches('*[tabIndex]').should.equal(false);
+
+  var h2 = doc.querySelector('h2');
+  h2.matches('*[id]').should.equal(true);
+  h2.matches('*[title]').should.equal(true);
+  h2.matches('*[lang]').should.equal(true);
+  h2.matches('*[dir]').should.equal(true);
+  h2.matches('*[accessKey]').should.equal(true);
+  h2.matches('*[hidden]').should.equal(true);
+  h2.matches('*[tabIndex]').should.equal(true);
+
+  h1.matches('*[matches]').should.equal(false);
+  h1.matches('*[querySelector]').should.equal(false);
+
+  h1.matches('*[isHTML]').should.equal(false);
+};
+
+exports.crHandling = function() {
+  var html = '<div\rid=a data-test=1\rfoo="\r"\rbar=\'\r\'\rbat=\r>\r</div\r>';
+  var doc = domino.createDocument(html);
+  var div = doc.querySelector('#a');
+  (div != null).should.be.true;
+  // all \r should be converted to \n
+  div.outerHTML.should.equal('<div id="a" data-test="1" foo="\n" bar="\n" 
bat="">\n</div>');
+};
+
+exports.eqAttr = function() {
+  var html = "<div id=a ==x><a=B></A=b></div>";
+  var doc = domino.createDocument(html);
+  var div = doc.querySelector('#a');
+  (div != null).should.be.true;
+  div.attributes.length.should.equal(2);
+  div.attributes.item(1).name.should.equal('=');
+  div.children.length.should.equal(1);
+  div.children[0].tagName.should.equal('A=B');
+};
+
+exports.tagNameCase = function() {
+  // See https://github.com/fgnass/domino/pull/41
+  var impl = domino.createDOMImplementation();
+  var namespace = 'http://schemas.xmlsoap.org/soap/envelope/';
+  var qualifiedName = 'Envelope';
+  var doc = impl.createDocument(namespace, qualifiedName, null);
+  doc.documentElement.tagName.should.equal(qualifiedName);
+};
+
+exports.fastAttributes = function() {
+  // test the SIMPLETAG/SIMPLEATTR path in HTMLParser
+  var html = "<div id=a b=\"x &quot;y\" c='a \rb'><\np></div>";
+  var doc = domino.createDocument(html);
+  var div = doc.querySelector('#a');
+  (div != null).should.be.true;
+  div.attributes.length.should.equal(3);
+  div.attributes.item(1).value.should.equal('x "y');
+  div.attributes.item(2).value.should.equal('a \nb');
+  div.children.length.should.equal(0);
+};
diff --git a/node_modules/domino/test/w3c/harness/index.js 
b/node_modules/domino/test/w3c/harness/index.js
index 36359af..2b99432 100644
--- a/node_modules/domino/test/w3c/harness/index.js
+++ b/node_modules/domino/test/w3c/harness/index.js
@@ -44,7 +44,10 @@
     return ctx;
   }
 
-  var ctx = vm.createContext(globals);
+  var ctx = vm.createContext(); // create new independent context
+  Object.keys(globals).forEach(function(k) {
+    ctx[k] = globals[k]; // shallow clone
+  });
 
   ctx.createConfiguredBuilder = function() {
     return {

-- 
To view, visit https://gerrit.wikimedia.org/r/135034
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ic8b011fa4b3b13918977b6fceaeb7f3d58b3df07
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/services/parsoid/deploy
Gerrit-Branch: master
Gerrit-Owner: GWicke <gwi...@wikimedia.org>
Gerrit-Reviewer: Arlolra <abrea...@wikimedia.org>
Gerrit-Reviewer: Cscott <canan...@wikimedia.org>
Gerrit-Reviewer: Marcoil <marc...@wikimedia.org>
Gerrit-Reviewer: Subramanya Sastry <ssas...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to