>} table
+ * @param {Object?} options
+ * @param {boolean?} [options.rule=true]
+ * @param {string?} [options.delimiter=" | "]
+ * @param {string?} [options.start="| "]
+ * @param {string?} [options.end=" |"]
+ * @param {Array.?} options.align
+ * @param {function(string)?} options.stringLength
+ * @return {string} Pretty table
+ */
+function markdownTable(table, options) {
+ var settings = options || {};
+ var delimiter = settings.delimiter;
+ var start = settings.start;
+ var end = settings.end;
+ var alignment = settings.align;
+ var calculateStringLength = settings.stringLength || lengthNoop;
+ var cellCount = 0;
+ var rowIndex = -1;
+ var rowLength = table.length;
+ var sizes = [];
+ var align;
+ var rule;
+ var rows;
+ var row;
+ var cells;
+ var index;
+ var position;
+ var size;
+ var value;
+ var spacing;
+ var before;
+ var after;
+
+ alignment = alignment ? alignment.concat() : [];
+
+ if (delimiter === null || delimiter === undefined) {
+ delimiter = SPACE + PIPE + SPACE;
+ }
+
+ if (start === null || start === undefined) {
+ start = PIPE + SPACE;
+ }
+
+ if (end === null || end === undefined) {
+ end = SPACE + PIPE;
+ }
+
+ while (++rowIndex < rowLength) {
+ row = table[rowIndex];
+
+ index = -1;
+
+ if (row.length > cellCount) {
+ cellCount = row.length;
+ }
+
+ while (++index < cellCount) {
+ position = row[index] ? dotindex(row[index]) : null;
+
+ if (!sizes[index]) {
+ sizes[index] = 3;
+ }
+
+ if (position > sizes[index]) {
+ sizes[index] = position;
+ }
+ }
+ }
+
+ if (typeof alignment === 'string') {
+ alignment = pad(cellCount, alignment).split('');
+ }
+
+ /*
+ * Make sure only valid alignments are used.
+ */
+
+ index = -1;
+
+ while (++index < cellCount) {
+ align = alignment[index];
+
+ if (typeof align === 'string') {
+ align = align.charAt(0).toLowerCase();
+ }
+
+ if (ALLIGNMENT.indexOf(align) === -1) {
+ align = NULL;
+ }
+
+ alignment[index] = align;
+ }
+
+ rowIndex = -1;
+ rows = [];
+
+ while (++rowIndex < rowLength) {
+ row = table[rowIndex];
+
+ index = -1;
+ cells = [];
+
+ while (++index < cellCount) {
+ value = row[index];
+
+ if (value === null || value === undefined) {
+ value = '';
+ } else {
+ value = String(value);
+ }
+
+ if (alignment[index] !== DOT) {
+ cells[index] = value;
+ } else {
+ position = dotindex(value);
+
+ size = sizes[index] +
+ (EXPRESSION_DOT.test(value) ? 0 : 1) -
+ (calculateStringLength(value) - position);
+
+ cells[index] = value + pad(size - 1);
+ }
+ }
+
+ rows[rowIndex] = cells;
+ }
+
+ sizes = [];
+ rowIndex = -1;
+
+ while (++rowIndex < rowLength) {
+ cells = rows[rowIndex];
+
+ index = -1;
+
+ while (++index < cellCount) {
+ value = cells[index];
+
+ if (!sizes[index]) {
+ sizes[index] = 3;
+ }
+
+ size = calculateStringLength(value);
+
+ if (size > sizes[index]) {
+ sizes[index] = size;
+ }
+ }
+ }
+
+ rowIndex = -1;
+
+ while (++rowIndex < rowLength) {
+ cells = rows[rowIndex];
+
+ index = -1;
+
+ while (++index < cellCount) {
+ value = cells[index];
+
+ position = sizes[index] - (calculateStringLength(value) || 0);
+ spacing = pad(position);
+
+ if (alignment[index] === RIGHT || alignment[index] === DOT) {
+ value = spacing + value;
+ } else if (alignment[index] !== CENTER) {
+ value = value + spacing;
+ } else {
+ position = position / 2;
+
+ if (position % 1 === 0) {
+ before = position;
+ after = position;
+ } else {
+ before = position + 0.5;
+ after = position - 0.5;
+ }
+
+ value = pad(before) + value + pad(after);
+ }
+
+ cells[index] = value;
+ }
+
+ rows[rowIndex] = cells.join(delimiter);
+ }
+
+ if (settings.rule !== false) {
+ index = -1;
+ rule = [];
+
+ while (++index < cellCount) {
+ align = alignment[index];
+
+ /*
+ * When `align` is left, don't add colons.
+ */
+
+ value = align === RIGHT || align === NULL ? DASH : COLON;
+ value += pad(sizes[index] - 2, DASH);
+ value += align !== LEFT && align !== NULL ? COLON : DASH;
+
+ rule[index] = value;
+ }
+
+ rows.splice(1, 0, rule.join(delimiter));
+ }
+
+ return start + rows.join(end + NEW_LINE + start) + end;
+}
+
+/*
+ * Expose `markdownTable`.
+ */
+
+module.exports = markdownTable;
diff --git a/tools/eslint/node_modules/markdown-table/package.json b/tools/eslint/node_modules/markdown-table/package.json
new file mode 100644
index 00000000000000..3121a74d4fc1be
--- /dev/null
+++ b/tools/eslint/node_modules/markdown-table/package.json
@@ -0,0 +1,104 @@
+{
+ "_args": [
+ [
+ {
+ "raw": "markdown-table@^0.4.0",
+ "scope": null,
+ "escapedName": "markdown-table",
+ "name": "markdown-table",
+ "rawSpec": "^0.4.0",
+ "spec": ">=0.4.0 <0.5.0",
+ "type": "range"
+ },
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/remark-stringify"
+ ]
+ ],
+ "_from": "markdown-table@>=0.4.0 <0.5.0",
+ "_id": "markdown-table@0.4.0",
+ "_inCache": true,
+ "_location": "/markdown-table",
+ "_nodeVersion": "1.6.3",
+ "_npmUser": {
+ "name": "wooorm",
+ "email": "tituswormer@gmail.com"
+ },
+ "_npmVersion": "2.7.4",
+ "_phantomChildren": {},
+ "_requested": {
+ "raw": "markdown-table@^0.4.0",
+ "scope": null,
+ "escapedName": "markdown-table",
+ "name": "markdown-table",
+ "rawSpec": "^0.4.0",
+ "spec": ">=0.4.0 <0.5.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/remark-stringify"
+ ],
+ "_resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-0.4.0.tgz",
+ "_shasum": "890c2c1b3bfe83fb00e4129b8e4cfe645270f9d1",
+ "_shrinkwrap": null,
+ "_spec": "markdown-table@^0.4.0",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/remark-stringify",
+ "author": {
+ "name": "Titus Wormer",
+ "email": "tituswormer@gmail.com"
+ },
+ "bugs": {
+ "url": "https://github.com/wooorm/markdown-table/issues"
+ },
+ "dependencies": {},
+ "description": "Markdown/ASCII tables",
+ "devDependencies": {
+ "chalk": "^1.0.0",
+ "eslint": "^0.18.0",
+ "istanbul": "^0.3.0",
+ "jscs": "^1.0.0",
+ "jscs-jsdoc": "^0.4.0",
+ "mocha": "^2.0.0"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "890c2c1b3bfe83fb00e4129b8e4cfe645270f9d1",
+ "tarball": "https://registry.npmjs.org/markdown-table/-/markdown-table-0.4.0.tgz"
+ },
+ "gitHead": "500964b100c0261c8f731bbb9c3617a624b5b255",
+ "homepage": "https://github.com/wooorm/markdown-table",
+ "keywords": [
+ "text",
+ "markdown",
+ "table",
+ "align",
+ "ascii",
+ "rows",
+ "tabular"
+ ],
+ "license": "MIT",
+ "maintainers": [
+ {
+ "name": "wooorm",
+ "email": "tituswormer@gmail.com"
+ }
+ ],
+ "name": "markdown-table",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/wooorm/markdown-table.git"
+ },
+ "scripts": {
+ "lint": "npm run lint-api && npm run lint-test && npm run lint-style",
+ "lint-api": "eslint index.js",
+ "lint-style": "jscs --reporter inline index.js test.js",
+ "lint-test": "eslint --env mocha test.js",
+ "make": "npm run lint && npm run test-coverage",
+ "test": "npm run test-api",
+ "test-api": "_mocha --check-leaks test.js",
+ "test-coverage": "istanbul cover _mocha -- -- test.js",
+ "test-coveralls": "istanbul cover _mocha --report lcovonly -- --check-leaks test.js",
+ "test-travis": "npm run test-coveralls"
+ },
+ "version": "0.4.0"
+}
diff --git a/tools/eslint/node_modules/mimic-fn/package.json b/tools/eslint/node_modules/mimic-fn/package.json
index eafefa5c2c4bdd..226dac572175d2 100644
--- a/tools/eslint/node_modules/mimic-fn/package.json
+++ b/tools/eslint/node_modules/mimic-fn/package.json
@@ -10,13 +10,13 @@
"spec": ">=1.0.0 <2.0.0",
"type": "range"
},
- "/Users/trott/io.js/tools/node_modules/onetime"
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/onetime"
]
],
"_from": "mimic-fn@>=1.0.0 <2.0.0",
"_id": "mimic-fn@1.1.0",
"_inCache": true,
- "_location": "/mimic-fn",
+ "_location": "/eslint/mimic-fn",
"_nodeVersion": "4.6.1",
"_npmOperationalInternal": {
"host": "packages-18-east.internal.npmjs.com",
@@ -38,13 +38,13 @@
"type": "range"
},
"_requiredBy": [
- "/onetime"
+ "/eslint/onetime"
],
"_resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
"_shasum": "e667783d92e89dbd342818b5230b9d62a672ad18",
"_shrinkwrap": null,
"_spec": "mimic-fn@^1.0.0",
- "_where": "/Users/trott/io.js/tools/node_modules/onetime",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/onetime",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
diff --git a/tools/eslint/node_modules/minimatch/package.json b/tools/eslint/node_modules/minimatch/package.json
index 212ab718b30cb3..dcaa77be3987c5 100644
--- a/tools/eslint/node_modules/minimatch/package.json
+++ b/tools/eslint/node_modules/minimatch/package.json
@@ -2,21 +2,21 @@
"_args": [
[
{
- "raw": "minimatch@^3.0.4",
+ "raw": "minimatch@^3.0.2",
"scope": null,
"escapedName": "minimatch",
"name": "minimatch",
- "rawSpec": "^3.0.4",
- "spec": ">=3.0.4 <4.0.0",
+ "rawSpec": "^3.0.2",
+ "spec": ">=3.0.2 <4.0.0",
"type": "range"
},
- "/Users/trott/io.js/tools/node_modules/glob"
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint"
]
],
- "_from": "minimatch@>=3.0.4 <4.0.0",
+ "_from": "minimatch@>=3.0.2 <4.0.0",
"_id": "minimatch@3.0.4",
"_inCache": true,
- "_location": "/minimatch",
+ "_location": "/eslint/minimatch",
"_nodeVersion": "8.0.0-pre",
"_npmOperationalInternal": {
"host": "packages-18-east.internal.npmjs.com",
@@ -29,22 +29,23 @@
"_npmVersion": "5.0.0-beta.43",
"_phantomChildren": {},
"_requested": {
- "raw": "minimatch@^3.0.4",
+ "raw": "minimatch@^3.0.2",
"scope": null,
"escapedName": "minimatch",
"name": "minimatch",
- "rawSpec": "^3.0.4",
- "spec": ">=3.0.4 <4.0.0",
+ "rawSpec": "^3.0.2",
+ "spec": ">=3.0.2 <4.0.0",
"type": "range"
},
"_requiredBy": [
- "/glob"
+ "/eslint",
+ "/eslint/glob"
],
"_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"_shasum": "5166e286457f03306064be5497e8dbb0c3d32083",
"_shrinkwrap": null,
- "_spec": "minimatch@^3.0.4",
- "_where": "/Users/trott/io.js/tools/node_modules/glob",
+ "_spec": "minimatch@^3.0.2",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
diff --git a/tools/eslint/node_modules/minimist/package.json b/tools/eslint/node_modules/minimist/package.json
index 964da644173817..243478d277d32e 100644
--- a/tools/eslint/node_modules/minimist/package.json
+++ b/tools/eslint/node_modules/minimist/package.json
@@ -10,13 +10,13 @@
"spec": "0.0.8",
"type": "version"
},
- "/Users/trott/io.js/tools/node_modules/mkdirp"
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/mkdirp"
]
],
"_from": "minimist@0.0.8",
"_id": "minimist@0.0.8",
"_inCache": true,
- "_location": "/minimist",
+ "_location": "/eslint/minimist",
"_npmUser": {
"name": "substack",
"email": "mail@substack.net"
@@ -33,13 +33,13 @@
"type": "version"
},
"_requiredBy": [
- "/mkdirp"
+ "/eslint/mkdirp"
],
"_resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"_shasum": "857fcabfc3397d2625b8228262e86aa7a011b05d",
"_shrinkwrap": null,
"_spec": "minimist@0.0.8",
- "_where": "/Users/trott/io.js/tools/node_modules/mkdirp",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/mkdirp",
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
diff --git a/tools/eslint/node_modules/mkdirp/package.json b/tools/eslint/node_modules/mkdirp/package.json
index dacb224baf1330..f32a2eebb755d5 100644
--- a/tools/eslint/node_modules/mkdirp/package.json
+++ b/tools/eslint/node_modules/mkdirp/package.json
@@ -10,13 +10,13 @@
"spec": ">=0.5.1 <0.6.0",
"type": "range"
},
- "/Users/trott/io.js/tools/node_modules/eslint"
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint"
]
],
"_from": "mkdirp@>=0.5.1 <0.6.0",
"_id": "mkdirp@0.5.1",
"_inCache": true,
- "_location": "/mkdirp",
+ "_location": "/eslint/mkdirp",
"_nodeVersion": "2.0.0",
"_npmUser": {
"name": "substack",
@@ -35,13 +35,13 @@
},
"_requiredBy": [
"/eslint",
- "/write"
+ "/eslint/write"
],
"_resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"_shasum": "30057438eac6cf7f8c4767f38648d6697d75c903",
"_shrinkwrap": null,
"_spec": "mkdirp@^0.5.1",
- "_where": "/Users/trott/io.js/tools/node_modules/eslint",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint",
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
diff --git a/tools/eslint/node_modules/ms/package.json b/tools/eslint/node_modules/ms/package.json
index a4ab935302c33e..c86223543eb5dc 100644
--- a/tools/eslint/node_modules/ms/package.json
+++ b/tools/eslint/node_modules/ms/package.json
@@ -10,13 +10,13 @@
"spec": "2.0.0",
"type": "version"
},
- "/Users/trott/io.js/tools/node_modules/debug"
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/debug"
]
],
"_from": "ms@2.0.0",
"_id": "ms@2.0.0",
"_inCache": true,
- "_location": "/ms",
+ "_location": "/eslint/ms",
"_nodeVersion": "7.8.0",
"_npmOperationalInternal": {
"host": "packages-18-east.internal.npmjs.com",
@@ -38,13 +38,13 @@
"type": "version"
},
"_requiredBy": [
- "/debug"
+ "/eslint/debug"
],
"_resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"_shasum": "5608aeadfc00be6c2901df5f9861788de0d597c8",
"_shrinkwrap": null,
"_spec": "ms@2.0.0",
- "_where": "/Users/trott/io.js/tools/node_modules/debug",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/debug",
"bugs": {
"url": "https://github.com/zeit/ms/issues"
},
diff --git a/tools/eslint/node_modules/mute-stream/package.json b/tools/eslint/node_modules/mute-stream/package.json
index 271b47bb2e78c9..c0b8e7ee755a5d 100644
--- a/tools/eslint/node_modules/mute-stream/package.json
+++ b/tools/eslint/node_modules/mute-stream/package.json
@@ -10,13 +10,13 @@
"spec": "0.0.7",
"type": "version"
},
- "/Users/trott/io.js/tools/node_modules/inquirer"
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/inquirer"
]
],
"_from": "mute-stream@0.0.7",
"_id": "mute-stream@0.0.7",
"_inCache": true,
- "_location": "/mute-stream",
+ "_location": "/eslint/mute-stream",
"_nodeVersion": "8.0.0-pre",
"_npmOperationalInternal": {
"host": "packages-18-east.internal.npmjs.com",
@@ -38,13 +38,13 @@
"type": "version"
},
"_requiredBy": [
- "/inquirer"
+ "/eslint/inquirer"
],
"_resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
"_shasum": "3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab",
"_shrinkwrap": null,
"_spec": "mute-stream@0.0.7",
- "_where": "/Users/trott/io.js/tools/node_modules/inquirer",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/inquirer",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
diff --git a/tools/eslint/node_modules/natural-compare/package.json b/tools/eslint/node_modules/natural-compare/package.json
index 8b81500a83f054..122e3802c24436 100644
--- a/tools/eslint/node_modules/natural-compare/package.json
+++ b/tools/eslint/node_modules/natural-compare/package.json
@@ -10,13 +10,13 @@
"spec": ">=1.4.0 <2.0.0",
"type": "range"
},
- "/Users/trott/io.js/tools/node_modules/eslint"
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint"
]
],
"_from": "natural-compare@>=1.4.0 <2.0.0",
"_id": "natural-compare@1.4.0",
"_inCache": true,
- "_location": "/natural-compare",
+ "_location": "/eslint/natural-compare",
"_nodeVersion": "6.2.2",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
@@ -44,7 +44,7 @@
"_shasum": "4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7",
"_shrinkwrap": null,
"_spec": "natural-compare@^1.4.0",
- "_where": "/Users/trott/io.js/tools/node_modules/eslint",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint",
"author": {
"name": "Lauri Rooden",
"url": "https://github.com/litejs/natural-compare-lite"
diff --git a/tools/eslint/node_modules/object-assign/package.json b/tools/eslint/node_modules/object-assign/package.json
index 0887c3c7b032ec..517a301f6bd691 100644
--- a/tools/eslint/node_modules/object-assign/package.json
+++ b/tools/eslint/node_modules/object-assign/package.json
@@ -10,13 +10,13 @@
"spec": ">=4.0.1 <5.0.0",
"type": "range"
},
- "/Users/trott/io.js/tools/node_modules/esrecurse"
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/esrecurse"
]
],
"_from": "object-assign@>=4.0.1 <5.0.0",
"_id": "object-assign@4.1.1",
"_inCache": true,
- "_location": "/object-assign",
+ "_location": "/eslint/object-assign",
"_nodeVersion": "4.6.2",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
@@ -38,16 +38,16 @@
"type": "range"
},
"_requiredBy": [
- "/del",
- "/esrecurse",
- "/file-entry-cache",
- "/globby"
+ "/eslint/del",
+ "/eslint/esrecurse",
+ "/eslint/file-entry-cache",
+ "/eslint/globby"
],
"_resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"_shasum": "2109adc7965887cfc05cbbd442cac8bfbb360863",
"_shrinkwrap": null,
"_spec": "object-assign@^4.0.1",
- "_where": "/Users/trott/io.js/tools/node_modules/esrecurse",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/esrecurse",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
diff --git a/tools/eslint/node_modules/once/package.json b/tools/eslint/node_modules/once/package.json
index 56c18c24346574..4322ce41b75829 100644
--- a/tools/eslint/node_modules/once/package.json
+++ b/tools/eslint/node_modules/once/package.json
@@ -10,13 +10,13 @@
"spec": ">=1.3.0 <2.0.0",
"type": "range"
},
- "/Users/trott/io.js/tools/node_modules/glob"
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/glob"
]
],
"_from": "once@>=1.3.0 <2.0.0",
"_id": "once@1.4.0",
"_inCache": true,
- "_location": "/once",
+ "_location": "/eslint/once",
"_nodeVersion": "6.5.0",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
@@ -38,14 +38,14 @@
"type": "range"
},
"_requiredBy": [
- "/glob",
- "/inflight"
+ "/eslint/glob",
+ "/eslint/inflight"
],
"_resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"_shasum": "583b1aa775961d4b113ac17d9c50baef9dd76bd1",
"_shrinkwrap": null,
"_spec": "once@^1.3.0",
- "_where": "/Users/trott/io.js/tools/node_modules/glob",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/glob",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
diff --git a/tools/eslint/node_modules/onetime/package.json b/tools/eslint/node_modules/onetime/package.json
index 915d55e18698cc..5dad91525ee260 100644
--- a/tools/eslint/node_modules/onetime/package.json
+++ b/tools/eslint/node_modules/onetime/package.json
@@ -10,13 +10,13 @@
"spec": ">=2.0.0 <3.0.0",
"type": "range"
},
- "/Users/trott/io.js/tools/node_modules/restore-cursor"
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/restore-cursor"
]
],
"_from": "onetime@>=2.0.0 <3.0.0",
"_id": "onetime@2.0.1",
"_inCache": true,
- "_location": "/onetime",
+ "_location": "/eslint/onetime",
"_nodeVersion": "4.7.3",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
@@ -38,13 +38,13 @@
"type": "range"
},
"_requiredBy": [
- "/restore-cursor"
+ "/eslint/restore-cursor"
],
"_resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
"_shasum": "067428230fd67443b2794b22bba528b6867962d4",
"_shrinkwrap": null,
"_spec": "onetime@^2.0.0",
- "_where": "/Users/trott/io.js/tools/node_modules/restore-cursor",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/restore-cursor",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
diff --git a/tools/eslint/node_modules/optionator/package.json b/tools/eslint/node_modules/optionator/package.json
index da848b2852ee14..c176beb15579f3 100644
--- a/tools/eslint/node_modules/optionator/package.json
+++ b/tools/eslint/node_modules/optionator/package.json
@@ -10,13 +10,13 @@
"spec": ">=0.8.2 <0.9.0",
"type": "range"
},
- "/Users/trott/io.js/tools/node_modules/eslint"
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint"
]
],
"_from": "optionator@>=0.8.2 <0.9.0",
"_id": "optionator@0.8.2",
"_inCache": true,
- "_location": "/optionator",
+ "_location": "/eslint/optionator",
"_nodeVersion": "6.6.0",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
@@ -44,7 +44,7 @@
"_shasum": "364c5e409d3f4d6301d6c0b4c05bba50180aeb64",
"_shrinkwrap": null,
"_spec": "optionator@^0.8.2",
- "_where": "/Users/trott/io.js/tools/node_modules/eslint",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint",
"author": {
"name": "George Zahariev",
"email": "z@georgezahariev.com"
diff --git a/tools/eslint/node_modules/os-tmpdir/package.json b/tools/eslint/node_modules/os-tmpdir/package.json
index bc524c47eea39f..085e662732ec33 100644
--- a/tools/eslint/node_modules/os-tmpdir/package.json
+++ b/tools/eslint/node_modules/os-tmpdir/package.json
@@ -10,13 +10,13 @@
"spec": ">=1.0.1 <1.1.0",
"type": "range"
},
- "/Users/trott/io.js/tools/node_modules/tmp"
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/tmp"
]
],
"_from": "os-tmpdir@>=1.0.1 <1.1.0",
"_id": "os-tmpdir@1.0.2",
"_inCache": true,
- "_location": "/os-tmpdir",
+ "_location": "/eslint/os-tmpdir",
"_nodeVersion": "6.6.0",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
@@ -38,13 +38,13 @@
"type": "range"
},
"_requiredBy": [
- "/tmp"
+ "/eslint/tmp"
],
"_resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"_shasum": "bbe67406c79aa85c5cfec766fe5734555dfa1274",
"_shrinkwrap": null,
"_spec": "os-tmpdir@~1.0.1",
- "_where": "/Users/trott/io.js/tools/node_modules/tmp",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/tmp",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
diff --git a/tools/eslint/node_modules/parse-entities/package.json b/tools/eslint/node_modules/parse-entities/package.json
index bff817d457d45b..e56f828155d450 100644
--- a/tools/eslint/node_modules/parse-entities/package.json
+++ b/tools/eslint/node_modules/parse-entities/package.json
@@ -1,27 +1,51 @@
{
- "_from": "parse-entities@^1.0.2",
+ "_args": [
+ [
+ {
+ "raw": "parse-entities@^1.0.2",
+ "scope": null,
+ "escapedName": "parse-entities",
+ "name": "parse-entities",
+ "rawSpec": "^1.0.2",
+ "spec": ">=1.0.2 <2.0.0",
+ "type": "range"
+ },
+ "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/remark-parse"
+ ]
+ ],
+ "_from": "parse-entities@>=1.0.2 <2.0.0",
"_id": "parse-entities@1.1.1",
- "_inBundle": false,
- "_integrity": "sha1-gRLYhHExnyerrk1klksSL+ThuJA=",
+ "_inCache": true,
"_location": "/parse-entities",
+ "_nodeVersion": "4.0.0",
+ "_npmOperationalInternal": {
+ "host": "s3://npm-registry-packages",
+ "tmp": "tmp/parse-entities-1.1.1.tgz_1497637037808_0.8155671106651425"
+ },
+ "_npmUser": {
+ "name": "wooorm",
+ "email": "tituswormer@gmail.com"
+ },
+ "_npmVersion": "2.14.2",
"_phantomChildren": {},
"_requested": {
- "type": "range",
- "registry": true,
"raw": "parse-entities@^1.0.2",
- "name": "parse-entities",
+ "scope": null,
"escapedName": "parse-entities",
+ "name": "parse-entities",
"rawSpec": "^1.0.2",
- "saveSpec": null,
- "fetchSpec": "^1.0.2"
+ "spec": ">=1.0.2 <2.0.0",
+ "type": "range"
},
"_requiredBy": [
- "/remark-parse"
+ "/remark-parse",
+ "/remark-stringify"
],
"_resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.1.1.tgz",
"_shasum": "8112d88471319f27abae4d64964b122fe4e1b890",
+ "_shrinkwrap": null,
"_spec": "parse-entities@^1.0.2",
- "_where": "j:\\temp\\_git\\node-fork\\tools\\eslint\\node_modules\\remark-parse",
+ "_where": "/Users/mborins/code/node/v6.x/tools/eslint-tmp/node_modules/eslint/node_modules/remark-parse",
"author": {
"name": "Titus Wormer",
"email": "tituswormer@gmail.com",
@@ -30,7 +54,6 @@
"bugs": {
"url": "https://github.com/wooorm/parse-entities/issues"
},
- "bundleDependencies": false,
"contributors": [
{
"name": "Titus Wormer",
@@ -46,7 +69,6 @@
"is-decimal": "^1.0.0",
"is-hexadecimal": "^1.0.0"
},
- "deprecated": false,
"description": "Parse HTML character references: fast, spec-compliant, positional information",
"devDependencies": {
"browserify": "^14.0.0",
@@ -57,9 +79,15 @@
"tape": "^4.2.0",
"xo": "^0.18.0"
},
+ "directories": {},
+ "dist": {
+ "shasum": "8112d88471319f27abae4d64964b122fe4e1b890",
+ "tarball": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.1.1.tgz"
+ },
"files": [
"index.js"
],
+ "gitHead": "97b0395ac443ba8f49d34cb0de07da186f654108",
"homepage": "https://github.com/wooorm/parse-entities#readme",
"keywords": [
"parse",
@@ -70,6 +98,12 @@
"entities"
],
"license": "MIT",
+ "maintainers": [
+ {
+ "name": "wooorm",
+ "email": "tituswormer@gmail.com"
+ }
+ ],
"name": "parse-entities",
"nyc": {
"check-coverage": true,
@@ -77,6 +111,8 @@
"functions": 100,
"branches": 100
},
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
"remarkConfig": {
"plugins": [
"preset-wooorm"
diff --git a/tools/eslint/node_modules/x-is-string/LICENCE b/tools/eslint/node_modules/parse5/LICENSE
similarity index 90%
rename from tools/eslint/node_modules/x-is-string/LICENCE
rename to tools/eslint/node_modules/parse5/LICENSE
index 0d0834052f3c54..7d4b9c5b478cab 100644
--- a/tools/eslint/node_modules/x-is-string/LICENCE
+++ b/tools/eslint/node_modules/parse5/LICENSE
@@ -1,19 +1,19 @@
-Copyright (c) 2014 Matt-Esch.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
+Copyright (c) 2013-2016 Ivan Nikulin (ifaaan@gmail.com, https://github.com/inikulin)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/tools/eslint/node_modules/parse5/README.md b/tools/eslint/node_modules/parse5/README.md
new file mode 100644
index 00000000000000..606c03073f269f
--- /dev/null
+++ b/tools/eslint/node_modules/parse5/README.md
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+WHATWG HTML5 specification-compliant, fast and ready for production HTML parsing/serialization toolset for Node.js
+
+
+
+
+
+
+
+
+
+
+parse5 provides nearly everything you may need when dealing with HTML. It's the fastest spec-compliant HTML parser
+for Node to date. It parses HTML the way the latest version of your browser does. It has proven itself reliable in such projects
+as jsdom, Angular2, Polymer and many more.
+
+
+----
+
+
+ Documentation
+
+
+
+ Version history
+
+
+
+ Online playground
+
+
+
+ Issue tracker
+
diff --git a/tools/eslint/node_modules/parse5/lib/common/doctype.js b/tools/eslint/node_modules/parse5/lib/common/doctype.js
new file mode 100644
index 00000000000000..5e14e64b3aa1f4
--- /dev/null
+++ b/tools/eslint/node_modules/parse5/lib/common/doctype.js
@@ -0,0 +1,137 @@
+'use strict';
+
+//Const
+var VALID_DOCTYPE_NAME = 'html',
+ QUIRKS_MODE_SYSTEM_ID = 'http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd',
+ QUIRKS_MODE_PUBLIC_ID_PREFIXES = [
+ '+//silmaril//dtd html pro v0r11 19970101//en',
+ '-//advasoft ltd//dtd html 3.0 aswedit + extensions//en',
+ '-//as//dtd html 3.0 aswedit + extensions//en',
+ '-//ietf//dtd html 2.0 level 1//en',
+ '-//ietf//dtd html 2.0 level 2//en',
+ '-//ietf//dtd html 2.0 strict level 1//en',
+ '-//ietf//dtd html 2.0 strict level 2//en',
+ '-//ietf//dtd html 2.0 strict//en',
+ '-//ietf//dtd html 2.0//en',
+ '-//ietf//dtd html 2.1e//en',
+ '-//ietf//dtd html 3.0//en',
+ '-//ietf//dtd html 3.0//en//',
+ '-//ietf//dtd html 3.2 final//en',
+ '-//ietf//dtd html 3.2//en',
+ '-//ietf//dtd html 3//en',
+ '-//ietf//dtd html level 0//en',
+ '-//ietf//dtd html level 0//en//2.0',
+ '-//ietf//dtd html level 1//en',
+ '-//ietf//dtd html level 1//en//2.0',
+ '-//ietf//dtd html level 2//en',
+ '-//ietf//dtd html level 2//en//2.0',
+ '-//ietf//dtd html level 3//en',
+ '-//ietf//dtd html level 3//en//3.0',
+ '-//ietf//dtd html strict level 0//en',
+ '-//ietf//dtd html strict level 0//en//2.0',
+ '-//ietf//dtd html strict level 1//en',
+ '-//ietf//dtd html strict level 1//en//2.0',
+ '-//ietf//dtd html strict level 2//en',
+ '-//ietf//dtd html strict level 2//en//2.0',
+ '-//ietf//dtd html strict level 3//en',
+ '-//ietf//dtd html strict level 3//en//3.0',
+ '-//ietf//dtd html strict//en',
+ '-//ietf//dtd html strict//en//2.0',
+ '-//ietf//dtd html strict//en//3.0',
+ '-//ietf//dtd html//en',
+ '-//ietf//dtd html//en//2.0',
+ '-//ietf//dtd html//en//3.0',
+ '-//metrius//dtd metrius presentational//en',
+ '-//microsoft//dtd internet explorer 2.0 html strict//en',
+ '-//microsoft//dtd internet explorer 2.0 html//en',
+ '-//microsoft//dtd internet explorer 2.0 tables//en',
+ '-//microsoft//dtd internet explorer 3.0 html strict//en',
+ '-//microsoft//dtd internet explorer 3.0 html//en',
+ '-//microsoft//dtd internet explorer 3.0 tables//en',
+ '-//netscape comm. corp.//dtd html//en',
+ '-//netscape comm. corp.//dtd strict html//en',
+ '-//o\'reilly and associates//dtd html 2.0//en',
+ '-//o\'reilly and associates//dtd html extended 1.0//en',
+ '-//spyglass//dtd html 2.0 extended//en',
+ '-//sq//dtd html 2.0 hotmetal + extensions//en',
+ '-//sun microsystems corp.//dtd hotjava html//en',
+ '-//sun microsystems corp.//dtd hotjava strict html//en',
+ '-//w3c//dtd html 3 1995-03-24//en',
+ '-//w3c//dtd html 3.2 draft//en',
+ '-//w3c//dtd html 3.2 final//en',
+ '-//w3c//dtd html 3.2//en',
+ '-//w3c//dtd html 3.2s draft//en',
+ '-//w3c//dtd html 4.0 frameset//en',
+ '-//w3c//dtd html 4.0 transitional//en',
+ '-//w3c//dtd html experimental 19960712//en',
+ '-//w3c//dtd html experimental 970421//en',
+ '-//w3c//dtd w3 html//en',
+ '-//w3o//dtd w3 html 3.0//en',
+ '-//w3o//dtd w3 html 3.0//en//',
+ '-//webtechs//dtd mozilla html 2.0//en',
+ '-//webtechs//dtd mozilla html//en'
+ ],
+ QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES = [
+ '-//w3c//dtd html 4.01 frameset//',
+ '-//w3c//dtd html 4.01 transitional//'
+ ],
+ QUIRKS_MODE_PUBLIC_IDS = [
+ '-//w3o//dtd w3 html strict 3.0//en//',
+ '-/w3c/dtd html 4.0 transitional/en',
+ 'html'
+ ];
+
+
+//Utils
+function enquoteDoctypeId(id) {
+ var quote = id.indexOf('"') !== -1 ? '\'' : '"';
+
+ return quote + id + quote;
+}
+
+
+//API
+exports.isQuirks = function (name, publicId, systemId) {
+ if (name !== VALID_DOCTYPE_NAME)
+ return true;
+
+ if (systemId && systemId.toLowerCase() === QUIRKS_MODE_SYSTEM_ID)
+ return true;
+
+ if (publicId !== null) {
+ publicId = publicId.toLowerCase();
+
+ if (QUIRKS_MODE_PUBLIC_IDS.indexOf(publicId) > -1)
+ return true;
+
+ var prefixes = QUIRKS_MODE_PUBLIC_ID_PREFIXES;
+
+ if (systemId === null)
+ prefixes = prefixes.concat(QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES);
+
+ for (var i = 0; i < prefixes.length; i++) {
+ if (publicId.indexOf(prefixes[i]) === 0)
+ return true;
+ }
+ }
+
+ return false;
+};
+
+exports.serializeContent = function (name, publicId, systemId) {
+ var str = '!DOCTYPE ';
+
+ if (name)
+ str += name;
+
+ if (publicId !== null)
+ str += ' PUBLIC ' + enquoteDoctypeId(publicId);
+
+ else if (systemId !== null)
+ str += ' SYSTEM';
+
+ if (systemId !== null)
+ str += ' ' + enquoteDoctypeId(systemId);
+
+ return str;
+};
diff --git a/tools/eslint/node_modules/parse5/lib/common/foreign_content.js b/tools/eslint/node_modules/parse5/lib/common/foreign_content.js
new file mode 100644
index 00000000000000..4dedbbffce6f04
--- /dev/null
+++ b/tools/eslint/node_modules/parse5/lib/common/foreign_content.js
@@ -0,0 +1,260 @@
+'use strict';
+
+var Tokenizer = require('../tokenizer'),
+ HTML = require('./html');
+
+//Aliases
+var $ = HTML.TAG_NAMES,
+ NS = HTML.NAMESPACES,
+ ATTRS = HTML.ATTRS;
+
+
+//MIME types
+var MIME_TYPES = {
+ TEXT_HTML: 'text/html',
+ APPLICATION_XML: 'application/xhtml+xml'
+};
+
+//Attributes
+var DEFINITION_URL_ATTR = 'definitionurl',
+ ADJUSTED_DEFINITION_URL_ATTR = 'definitionURL',
+ SVG_ATTRS_ADJUSTMENT_MAP = {
+ 'attributename': 'attributeName',
+ 'attributetype': 'attributeType',
+ 'basefrequency': 'baseFrequency',
+ 'baseprofile': 'baseProfile',
+ 'calcmode': 'calcMode',
+ 'clippathunits': 'clipPathUnits',
+ 'diffuseconstant': 'diffuseConstant',
+ 'edgemode': 'edgeMode',
+ 'filterunits': 'filterUnits',
+ 'glyphref': 'glyphRef',
+ 'gradienttransform': 'gradientTransform',
+ 'gradientunits': 'gradientUnits',
+ 'kernelmatrix': 'kernelMatrix',
+ 'kernelunitlength': 'kernelUnitLength',
+ 'keypoints': 'keyPoints',
+ 'keysplines': 'keySplines',
+ 'keytimes': 'keyTimes',
+ 'lengthadjust': 'lengthAdjust',
+ 'limitingconeangle': 'limitingConeAngle',
+ 'markerheight': 'markerHeight',
+ 'markerunits': 'markerUnits',
+ 'markerwidth': 'markerWidth',
+ 'maskcontentunits': 'maskContentUnits',
+ 'maskunits': 'maskUnits',
+ 'numoctaves': 'numOctaves',
+ 'pathlength': 'pathLength',
+ 'patterncontentunits': 'patternContentUnits',
+ 'patterntransform': 'patternTransform',
+ 'patternunits': 'patternUnits',
+ 'pointsatx': 'pointsAtX',
+ 'pointsaty': 'pointsAtY',
+ 'pointsatz': 'pointsAtZ',
+ 'preservealpha': 'preserveAlpha',
+ 'preserveaspectratio': 'preserveAspectRatio',
+ 'primitiveunits': 'primitiveUnits',
+ 'refx': 'refX',
+ 'refy': 'refY',
+ 'repeatcount': 'repeatCount',
+ 'repeatdur': 'repeatDur',
+ 'requiredextensions': 'requiredExtensions',
+ 'requiredfeatures': 'requiredFeatures',
+ 'specularconstant': 'specularConstant',
+ 'specularexponent': 'specularExponent',
+ 'spreadmethod': 'spreadMethod',
+ 'startoffset': 'startOffset',
+ 'stddeviation': 'stdDeviation',
+ 'stitchtiles': 'stitchTiles',
+ 'surfacescale': 'surfaceScale',
+ 'systemlanguage': 'systemLanguage',
+ 'tablevalues': 'tableValues',
+ 'targetx': 'targetX',
+ 'targety': 'targetY',
+ 'textlength': 'textLength',
+ 'viewbox': 'viewBox',
+ 'viewtarget': 'viewTarget',
+ 'xchannelselector': 'xChannelSelector',
+ 'ychannelselector': 'yChannelSelector',
+ 'zoomandpan': 'zoomAndPan'
+ },
+ XML_ATTRS_ADJUSTMENT_MAP = {
+ 'xlink:actuate': {prefix: 'xlink', name: 'actuate', namespace: NS.XLINK},
+ 'xlink:arcrole': {prefix: 'xlink', name: 'arcrole', namespace: NS.XLINK},
+ 'xlink:href': {prefix: 'xlink', name: 'href', namespace: NS.XLINK},
+ 'xlink:role': {prefix: 'xlink', name: 'role', namespace: NS.XLINK},
+ 'xlink:show': {prefix: 'xlink', name: 'show', namespace: NS.XLINK},
+ 'xlink:title': {prefix: 'xlink', name: 'title', namespace: NS.XLINK},
+ 'xlink:type': {prefix: 'xlink', name: 'type', namespace: NS.XLINK},
+ 'xml:base': {prefix: 'xml', name: 'base', namespace: NS.XML},
+ 'xml:lang': {prefix: 'xml', name: 'lang', namespace: NS.XML},
+ 'xml:space': {prefix: 'xml', name: 'space', namespace: NS.XML},
+ 'xmlns': {prefix: '', name: 'xmlns', namespace: NS.XMLNS},
+ 'xmlns:xlink': {prefix: 'xmlns', name: 'xlink', namespace: NS.XMLNS}
+
+ };
+
+//SVG tag names adjustment map
+var SVG_TAG_NAMES_ADJUSTMENT_MAP = exports.SVG_TAG_NAMES_ADJUSTMENT_MAP = {
+ 'altglyph': 'altGlyph',
+ 'altglyphdef': 'altGlyphDef',
+ 'altglyphitem': 'altGlyphItem',
+ 'animatecolor': 'animateColor',
+ 'animatemotion': 'animateMotion',
+ 'animatetransform': 'animateTransform',
+ 'clippath': 'clipPath',
+ 'feblend': 'feBlend',
+ 'fecolormatrix': 'feColorMatrix',
+ 'fecomponenttransfer': 'feComponentTransfer',
+ 'fecomposite': 'feComposite',
+ 'feconvolvematrix': 'feConvolveMatrix',
+ 'fediffuselighting': 'feDiffuseLighting',
+ 'fedisplacementmap': 'feDisplacementMap',
+ 'fedistantlight': 'feDistantLight',
+ 'feflood': 'feFlood',
+ 'fefunca': 'feFuncA',
+ 'fefuncb': 'feFuncB',
+ 'fefuncg': 'feFuncG',
+ 'fefuncr': 'feFuncR',
+ 'fegaussianblur': 'feGaussianBlur',
+ 'feimage': 'feImage',
+ 'femerge': 'feMerge',
+ 'femergenode': 'feMergeNode',
+ 'femorphology': 'feMorphology',
+ 'feoffset': 'feOffset',
+ 'fepointlight': 'fePointLight',
+ 'fespecularlighting': 'feSpecularLighting',
+ 'fespotlight': 'feSpotLight',
+ 'fetile': 'feTile',
+ 'feturbulence': 'feTurbulence',
+ 'foreignobject': 'foreignObject',
+ 'glyphref': 'glyphRef',
+ 'lineargradient': 'linearGradient',
+ 'radialgradient': 'radialGradient',
+ 'textpath': 'textPath'
+};
+
+//Tags that causes exit from foreign content
+var EXITS_FOREIGN_CONTENT = {};
+
+EXITS_FOREIGN_CONTENT[$.B] = true;
+EXITS_FOREIGN_CONTENT[$.BIG] = true;
+EXITS_FOREIGN_CONTENT[$.BLOCKQUOTE] = true;
+EXITS_FOREIGN_CONTENT[$.BODY] = true;
+EXITS_FOREIGN_CONTENT[$.BR] = true;
+EXITS_FOREIGN_CONTENT[$.CENTER] = true;
+EXITS_FOREIGN_CONTENT[$.CODE] = true;
+EXITS_FOREIGN_CONTENT[$.DD] = true;
+EXITS_FOREIGN_CONTENT[$.DIV] = true;
+EXITS_FOREIGN_CONTENT[$.DL] = true;
+EXITS_FOREIGN_CONTENT[$.DT] = true;
+EXITS_FOREIGN_CONTENT[$.EM] = true;
+EXITS_FOREIGN_CONTENT[$.EMBED] = true;
+EXITS_FOREIGN_CONTENT[$.H1] = true;
+EXITS_FOREIGN_CONTENT[$.H2] = true;
+EXITS_FOREIGN_CONTENT[$.H3] = true;
+EXITS_FOREIGN_CONTENT[$.H4] = true;
+EXITS_FOREIGN_CONTENT[$.H5] = true;
+EXITS_FOREIGN_CONTENT[$.H6] = true;
+EXITS_FOREIGN_CONTENT[$.HEAD] = true;
+EXITS_FOREIGN_CONTENT[$.HR] = true;
+EXITS_FOREIGN_CONTENT[$.I] = true;
+EXITS_FOREIGN_CONTENT[$.IMG] = true;
+EXITS_FOREIGN_CONTENT[$.LI] = true;
+EXITS_FOREIGN_CONTENT[$.LISTING] = true;
+EXITS_FOREIGN_CONTENT[$.MENU] = true;
+EXITS_FOREIGN_CONTENT[$.META] = true;
+EXITS_FOREIGN_CONTENT[$.NOBR] = true;
+EXITS_FOREIGN_CONTENT[$.OL] = true;
+EXITS_FOREIGN_CONTENT[$.P] = true;
+EXITS_FOREIGN_CONTENT[$.PRE] = true;
+EXITS_FOREIGN_CONTENT[$.RUBY] = true;
+EXITS_FOREIGN_CONTENT[$.S] = true;
+EXITS_FOREIGN_CONTENT[$.SMALL] = true;
+EXITS_FOREIGN_CONTENT[$.SPAN] = true;
+EXITS_FOREIGN_CONTENT[$.STRONG] = true;
+EXITS_FOREIGN_CONTENT[$.STRIKE] = true;
+EXITS_FOREIGN_CONTENT[$.SUB] = true;
+EXITS_FOREIGN_CONTENT[$.SUP] = true;
+EXITS_FOREIGN_CONTENT[$.TABLE] = true;
+EXITS_FOREIGN_CONTENT[$.TT] = true;
+EXITS_FOREIGN_CONTENT[$.U] = true;
+EXITS_FOREIGN_CONTENT[$.UL] = true;
+EXITS_FOREIGN_CONTENT[$.VAR] = true;
+
+//Check exit from foreign content
+exports.causesExit = function (startTagToken) {
+ var tn = startTagToken.tagName;
+ var isFontWithAttrs = tn === $.FONT && (Tokenizer.getTokenAttr(startTagToken, ATTRS.COLOR) !== null ||
+ Tokenizer.getTokenAttr(startTagToken, ATTRS.SIZE) !== null ||
+ Tokenizer.getTokenAttr(startTagToken, ATTRS.FACE) !== null);
+
+ return isFontWithAttrs ? true : EXITS_FOREIGN_CONTENT[tn];
+};
+
+//Token adjustments
+exports.adjustTokenMathMLAttrs = function (token) {
+ for (var i = 0; i < token.attrs.length; i++) {
+ if (token.attrs[i].name === DEFINITION_URL_ATTR) {
+ token.attrs[i].name = ADJUSTED_DEFINITION_URL_ATTR;
+ break;
+ }
+ }
+};
+
+exports.adjustTokenSVGAttrs = function (token) {
+ for (var i = 0; i < token.attrs.length; i++) {
+ var adjustedAttrName = SVG_ATTRS_ADJUSTMENT_MAP[token.attrs[i].name];
+
+ if (adjustedAttrName)
+ token.attrs[i].name = adjustedAttrName;
+ }
+};
+
+exports.adjustTokenXMLAttrs = function (token) {
+ for (var i = 0; i < token.attrs.length; i++) {
+ var adjustedAttrEntry = XML_ATTRS_ADJUSTMENT_MAP[token.attrs[i].name];
+
+ if (adjustedAttrEntry) {
+ token.attrs[i].prefix = adjustedAttrEntry.prefix;
+ token.attrs[i].name = adjustedAttrEntry.name;
+ token.attrs[i].namespace = adjustedAttrEntry.namespace;
+ }
+ }
+};
+
+exports.adjustTokenSVGTagName = function (token) {
+ var adjustedTagName = SVG_TAG_NAMES_ADJUSTMENT_MAP[token.tagName];
+
+ if (adjustedTagName)
+ token.tagName = adjustedTagName;
+};
+
+//Integration points
+function isMathMLTextIntegrationPoint(tn, ns) {
+ return ns === NS.MATHML && (tn === $.MI || tn === $.MO || tn === $.MN || tn === $.MS || tn === $.MTEXT);
+}
+
+function isHtmlIntegrationPoint(tn, ns, attrs) {
+ if (ns === NS.MATHML && tn === $.ANNOTATION_XML) {
+ for (var i = 0; i < attrs.length; i++) {
+ if (attrs[i].name === ATTRS.ENCODING) {
+ var value = attrs[i].value.toLowerCase();
+
+ return value === MIME_TYPES.TEXT_HTML || value === MIME_TYPES.APPLICATION_XML;
+ }
+ }
+ }
+
+ return ns === NS.SVG && (tn === $.FOREIGN_OBJECT || tn === $.DESC || tn === $.TITLE);
+}
+
+exports.isIntegrationPoint = function (tn, ns, attrs, foreignNS) {
+ if ((!foreignNS || foreignNS === NS.HTML) && isHtmlIntegrationPoint(tn, ns, attrs))
+ return true;
+
+ if ((!foreignNS || foreignNS === NS.MATHML) && isMathMLTextIntegrationPoint(tn, ns))
+ return true;
+
+ return false;
+};
diff --git a/tools/eslint/node_modules/parse5/lib/common/html.js b/tools/eslint/node_modules/parse5/lib/common/html.js
new file mode 100644
index 00000000000000..c1eec338ce1b58
--- /dev/null
+++ b/tools/eslint/node_modules/parse5/lib/common/html.js
@@ -0,0 +1,266 @@
+'use strict';
+
+var NS = exports.NAMESPACES = {
+ HTML: 'http://www.w3.org/1999/xhtml',
+ MATHML: 'http://www.w3.org/1998/Math/MathML',
+ SVG: 'http://www.w3.org/2000/svg',
+ XLINK: 'http://www.w3.org/1999/xlink',
+ XML: 'http://www.w3.org/XML/1998/namespace',
+ XMLNS: 'http://www.w3.org/2000/xmlns/'
+};
+
+exports.ATTRS = {
+ TYPE: 'type',
+ ACTION: 'action',
+ ENCODING: 'encoding',
+ PROMPT: 'prompt',
+ NAME: 'name',
+ COLOR: 'color',
+ FACE: 'face',
+ SIZE: 'size'
+};
+
+var $ = exports.TAG_NAMES = {
+ A: 'a',
+ ADDRESS: 'address',
+ ANNOTATION_XML: 'annotation-xml',
+ APPLET: 'applet',
+ AREA: 'area',
+ ARTICLE: 'article',
+ ASIDE: 'aside',
+
+ B: 'b',
+ BASE: 'base',
+ BASEFONT: 'basefont',
+ BGSOUND: 'bgsound',
+ BIG: 'big',
+ BLOCKQUOTE: 'blockquote',
+ BODY: 'body',
+ BR: 'br',
+ BUTTON: 'button',
+
+ CAPTION: 'caption',
+ CENTER: 'center',
+ CODE: 'code',
+ COL: 'col',
+ COLGROUP: 'colgroup',
+
+ DD: 'dd',
+ DESC: 'desc',
+ DETAILS: 'details',
+ DIALOG: 'dialog',
+ DIR: 'dir',
+ DIV: 'div',
+ DL: 'dl',
+ DT: 'dt',
+
+ EM: 'em',
+ EMBED: 'embed',
+
+ FIELDSET: 'fieldset',
+ FIGCAPTION: 'figcaption',
+ FIGURE: 'figure',
+ FONT: 'font',
+ FOOTER: 'footer',
+ FOREIGN_OBJECT: 'foreignObject',
+ FORM: 'form',
+ FRAME: 'frame',
+ FRAMESET: 'frameset',
+
+ H1: 'h1',
+ H2: 'h2',
+ H3: 'h3',
+ H4: 'h4',
+ H5: 'h5',
+ H6: 'h6',
+ HEAD: 'head',
+ HEADER: 'header',
+ HGROUP: 'hgroup',
+ HR: 'hr',
+ HTML: 'html',
+
+ I: 'i',
+ IMG: 'img',
+ IMAGE: 'image',
+ INPUT: 'input',
+ IFRAME: 'iframe',
+
+ KEYGEN: 'keygen',
+
+ LABEL: 'label',
+ LI: 'li',
+ LINK: 'link',
+ LISTING: 'listing',
+
+ MAIN: 'main',
+ MALIGNMARK: 'malignmark',
+ MARQUEE: 'marquee',
+ MATH: 'math',
+ MENU: 'menu',
+ MENUITEM: 'menuitem',
+ META: 'meta',
+ MGLYPH: 'mglyph',
+ MI: 'mi',
+ MO: 'mo',
+ MN: 'mn',
+ MS: 'ms',
+ MTEXT: 'mtext',
+
+ NAV: 'nav',
+ NOBR: 'nobr',
+ NOFRAMES: 'noframes',
+ NOEMBED: 'noembed',
+ NOSCRIPT: 'noscript',
+
+ OBJECT: 'object',
+ OL: 'ol',
+ OPTGROUP: 'optgroup',
+ OPTION: 'option',
+
+ P: 'p',
+ PARAM: 'param',
+ PLAINTEXT: 'plaintext',
+ PRE: 'pre',
+
+ RB: 'rb',
+ RP: 'rp',
+ RT: 'rt',
+ RTC: 'rtc',
+ RUBY: 'ruby',
+
+ S: 's',
+ SCRIPT: 'script',
+ SECTION: 'section',
+ SELECT: 'select',
+ SOURCE: 'source',
+ SMALL: 'small',
+ SPAN: 'span',
+ STRIKE: 'strike',
+ STRONG: 'strong',
+ STYLE: 'style',
+ SUB: 'sub',
+ SUMMARY: 'summary',
+ SUP: 'sup',
+
+ TABLE: 'table',
+ TBODY: 'tbody',
+ TEMPLATE: 'template',
+ TEXTAREA: 'textarea',
+ TFOOT: 'tfoot',
+ TD: 'td',
+ TH: 'th',
+ THEAD: 'thead',
+ TITLE: 'title',
+ TR: 'tr',
+ TRACK: 'track',
+ TT: 'tt',
+
+ U: 'u',
+ UL: 'ul',
+
+ SVG: 'svg',
+
+ VAR: 'var',
+
+ WBR: 'wbr',
+
+ XMP: 'xmp'
+};
+
+var SPECIAL_ELEMENTS = exports.SPECIAL_ELEMENTS = {};
+
+SPECIAL_ELEMENTS[NS.HTML] = {};
+SPECIAL_ELEMENTS[NS.HTML][$.ADDRESS] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.APPLET] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.AREA] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.ARTICLE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.ASIDE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BASE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BASEFONT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BGSOUND] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BLOCKQUOTE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BODY] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BR] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.BUTTON] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.CAPTION] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.CENTER] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.COL] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.COLGROUP] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.DD] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.DETAILS] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.DIR] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.DIV] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.DL] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.DT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.EMBED] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FIELDSET] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FIGCAPTION] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FIGURE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FOOTER] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FORM] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FRAME] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.FRAMESET] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.H1] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.H2] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.H3] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.H4] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.H5] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.H6] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.HEAD] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.HEADER] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.HGROUP] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.HR] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.HTML] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.IFRAME] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.IMG] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.INPUT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.LI] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.LINK] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.LISTING] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.MAIN] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.MARQUEE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.MENU] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.META] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.NAV] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.NOEMBED] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.NOFRAMES] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.NOSCRIPT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.OBJECT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.OL] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.P] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.PARAM] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.PLAINTEXT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.PRE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.SCRIPT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.SECTION] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.SELECT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.SOURCE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.STYLE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.SUMMARY] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TABLE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TBODY] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TD] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TEMPLATE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TEXTAREA] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TFOOT] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TH] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.THEAD] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TITLE] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TR] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.TRACK] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.UL] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.WBR] = true;
+SPECIAL_ELEMENTS[NS.HTML][$.XMP] = true;
+
+SPECIAL_ELEMENTS[NS.MATHML] = {};
+SPECIAL_ELEMENTS[NS.MATHML][$.MI] = true;
+SPECIAL_ELEMENTS[NS.MATHML][$.MO] = true;
+SPECIAL_ELEMENTS[NS.MATHML][$.MN] = true;
+SPECIAL_ELEMENTS[NS.MATHML][$.MS] = true;
+SPECIAL_ELEMENTS[NS.MATHML][$.MTEXT] = true;
+SPECIAL_ELEMENTS[NS.MATHML][$.ANNOTATION_XML] = true;
+
+SPECIAL_ELEMENTS[NS.SVG] = {};
+SPECIAL_ELEMENTS[NS.SVG][$.TITLE] = true;
+SPECIAL_ELEMENTS[NS.SVG][$.FOREIGN_OBJECT] = true;
+SPECIAL_ELEMENTS[NS.SVG][$.DESC] = true;
diff --git a/tools/eslint/node_modules/parse5/lib/common/merge_options.js b/tools/eslint/node_modules/parse5/lib/common/merge_options.js
new file mode 100644
index 00000000000000..fd26fafceadf90
--- /dev/null
+++ b/tools/eslint/node_modules/parse5/lib/common/merge_options.js
@@ -0,0 +1,13 @@
+'use strict';
+
+module.exports = function mergeOptions(defaults, options) {
+ options = options || {};
+
+ return [defaults, options].reduce(function (merged, optObj) {
+ Object.keys(optObj).forEach(function (key) {
+ merged[key] = optObj[key];
+ });
+
+ return merged;
+ }, {});
+};
diff --git a/tools/eslint/node_modules/parse5/lib/common/unicode.js b/tools/eslint/node_modules/parse5/lib/common/unicode.js
new file mode 100644
index 00000000000000..d7ee04a0dba982
--- /dev/null
+++ b/tools/eslint/node_modules/parse5/lib/common/unicode.js
@@ -0,0 +1,47 @@
+'use strict';
+
+exports.REPLACEMENT_CHARACTER = '\uFFFD';
+
+exports.CODE_POINTS = {
+ EOF: -1,
+ NULL: 0x00,
+ TABULATION: 0x09,
+ CARRIAGE_RETURN: 0x0D,
+ LINE_FEED: 0x0A,
+ FORM_FEED: 0x0C,
+ SPACE: 0x20,
+ EXCLAMATION_MARK: 0x21,
+ QUOTATION_MARK: 0x22,
+ NUMBER_SIGN: 0x23,
+ AMPERSAND: 0x26,
+ APOSTROPHE: 0x27,
+ HYPHEN_MINUS: 0x2D,
+ SOLIDUS: 0x2F,
+ DIGIT_0: 0x30,
+ DIGIT_9: 0x39,
+ SEMICOLON: 0x3B,
+ LESS_THAN_SIGN: 0x3C,
+ EQUALS_SIGN: 0x3D,
+ GREATER_THAN_SIGN: 0x3E,
+ QUESTION_MARK: 0x3F,
+ LATIN_CAPITAL_A: 0x41,
+ LATIN_CAPITAL_F: 0x46,
+ LATIN_CAPITAL_X: 0x58,
+ LATIN_CAPITAL_Z: 0x5A,
+ GRAVE_ACCENT: 0x60,
+ LATIN_SMALL_A: 0x61,
+ LATIN_SMALL_F: 0x66,
+ LATIN_SMALL_X: 0x78,
+ LATIN_SMALL_Z: 0x7A,
+ REPLACEMENT_CHARACTER: 0xFFFD
+};
+
+exports.CODE_POINT_SEQUENCES = {
+ DASH_DASH_STRING: [0x2D, 0x2D], //--
+ DOCTYPE_STRING: [0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45], //DOCTYPE
+ CDATA_START_STRING: [0x5B, 0x43, 0x44, 0x41, 0x54, 0x41, 0x5B], //[CDATA[
+ CDATA_END_STRING: [0x5D, 0x5D, 0x3E], //]]>
+ SCRIPT_STRING: [0x73, 0x63, 0x72, 0x69, 0x70, 0x74], //script
+ PUBLIC_STRING: [0x50, 0x55, 0x42, 0x4C, 0x49, 0x43], //PUBLIC
+ SYSTEM_STRING: [0x53, 0x59, 0x53, 0x54, 0x45, 0x4D] //SYSTEM
+};
diff --git a/tools/eslint/node_modules/parse5/lib/index.js b/tools/eslint/node_modules/parse5/lib/index.js
new file mode 100644
index 00000000000000..1702182e5a534a
--- /dev/null
+++ b/tools/eslint/node_modules/parse5/lib/index.js
@@ -0,0 +1,108 @@
+'use strict';
+
+var Parser = require('./parser'),
+ Serializer = require('./serializer');
+
+/** @namespace parse5 */
+
+/**
+ * Parses an HTML string.
+ * @function parse
+ * @memberof parse5
+ * @instance
+ * @param {string} html - Input HTML string.
+ * @param {ParserOptions} [options] - Parsing options.
+ * @returns {ASTNode} document
+ * @example
+ * var parse5 = require('parse5');
+ *
+ * var document = parse5.parse('Hi there!');
+ */
+exports.parse = function parse(html, options) {
+ var parser = new Parser(options);
+
+ return parser.parse(html);
+};
+
+/**
+ * Parses an HTML fragment.
+ * @function parseFragment
+ * @memberof parse5
+ * @instance
+ * @param {ASTNode} [fragmentContext] - Parsing context element. If specified, given fragment
+ * will be parsed as if it was set to the context element's `innerHTML` property.
+ * @param {string} html - Input HTML fragment string.
+ * @param {ParserOptions} [options] - Parsing options.
+ * @returns {ASTNode} documentFragment
+ * @example
+ * var parse5 = require('parse5');
+ *
+ * var documentFragment = parse5.parseFragment('');
+ *
+ * // Parses the html fragment in the context of the parsed element.
+ * var trFragment = parser.parseFragment(documentFragment.childNodes[0], 'Shake it, baby |
');
+ */
+exports.parseFragment = function parseFragment(fragmentContext, html, options) {
+ if (typeof fragmentContext === 'string') {
+ options = html;
+ html = fragmentContext;
+ fragmentContext = null;
+ }
+
+ var parser = new Parser(options);
+
+ return parser.parseFragment(html, fragmentContext);
+};
+
+/**
+ * Serializes an AST node to an HTML string.
+ * @function serialize
+ * @memberof parse5
+ * @instance
+ * @param {ASTNode} node - Node to serialize.
+ * @param {SerializerOptions} [options] - Serialization options.
+ * @returns {String} html
+ * @example
+ * var parse5 = require('parse5');
+ *
+ * var document = parse5.parse('Hi there!');
+ *
+ * // Serializes a document.
+ * var html = parse5.serialize(document);
+ *
+ * // Serializes the element content.
+ * var bodyInnerHtml = parse5.serialize(document.childNodes[0].childNodes[1]);
+ */
+exports.serialize = function (node, options) {
+ var serializer = new Serializer(node, options);
+
+ return serializer.serialize();
+};
+
+/**
+ * Provides built-in tree adapters that can be used for parsing and serialization.
+ * @var treeAdapters
+ * @memberof parse5
+ * @instance
+ * @property {TreeAdapter} default - Default tree format for parse5.
+ * @property {TreeAdapter} htmlparser2 - Quite popular [htmlparser2](https://github.com/fb55/htmlparser2) tree format
+ * (e.g. used by [cheerio](https://github.com/MatthewMueller/cheerio) and [jsdom](https://github.com/tmpvar/jsdom)).
+ * @example
+ * var parse5 = require('parse5');
+ *
+ * // Uses the default tree adapter for parsing.
+ * var document = parse5.parse('', { treeAdapter: parse5.treeAdapters.default });
+ *
+ * // Uses the htmlparser2 tree adapter with the SerializerStream.
+ * var serializer = new parse5.SerializerStream(node, { treeAdapter: parse5.treeAdapters.htmlparser2 });
+ */
+exports.treeAdapters = {
+ default: require('./tree_adapters/default'),
+ htmlparser2: require('./tree_adapters/htmlparser2')
+};
+
+
+// Streaming
+exports.ParserStream = require('./parser/stream');
+exports.SerializerStream = require('./serializer/stream');
+exports.SAXParser = require('./sax');
diff --git a/tools/eslint/node_modules/parse5/lib/location_info/parser_mixin.js b/tools/eslint/node_modules/parse5/lib/location_info/parser_mixin.js
new file mode 100644
index 00000000000000..c92baf5606ec7d
--- /dev/null
+++ b/tools/eslint/node_modules/parse5/lib/location_info/parser_mixin.js
@@ -0,0 +1,217 @@
+'use strict';
+
+var OpenElementStack = require('../parser/open_element_stack'),
+ Tokenizer = require('../tokenizer'),
+ HTML = require('../common/html');
+
+
+//Aliases
+var $ = HTML.TAG_NAMES;
+
+
+function setEndLocation(element, closingToken, treeAdapter) {
+ var loc = element.__location;
+
+ if (!loc)
+ return;
+
+ /**
+ * @typedef {Object} ElementLocationInfo
+ * @extends StartTagLocationInfo
+ *
+ * @property {StartTagLocationInfo} startTag - Element's start tag location info.
+ * @property {LocationInfo} endTag - Element's end tag location info.
+ */
+ if (!loc.startTag) {
+ loc.startTag = {
+ line: loc.line,
+ col: loc.col,
+ startOffset: loc.startOffset,
+ endOffset: loc.endOffset
+ };
+ if (loc.attrs)
+ loc.startTag.attrs = loc.attrs;
+ }
+
+ if (closingToken.location) {
+ var ctLocation = closingToken.location,
+ tn = treeAdapter.getTagName(element),
+ // NOTE: For cases like
- First 'p' closes without a closing tag and
+ // for cases like | - 'p' closes without a closing tag
+ isClosingEndTag = closingToken.type === Tokenizer.END_TAG_TOKEN &&
+ tn === closingToken.tagName;
+
+ if (isClosingEndTag) {
+ loc.endTag = {
+ line: ctLocation.line,
+ col: ctLocation.col,
+ startOffset: ctLocation.startOffset,
+ endOffset: ctLocation.endOffset
+ };
+ }
+
+ if (isClosingEndTag)
+ loc.endOffset = ctLocation.endOffset;
+ else
+ loc.endOffset = ctLocation.startOffset;
+ }
+}
+
+
+exports.assign = function (parser) {
+ //NOTE: obtain Parser proto this way to avoid module circular references
+ var parserProto = Object.getPrototypeOf(parser),
+ treeAdapter = parser.treeAdapter,
+ attachableElementLocation = null,
+ lastFosterParentingLocation = null,
+ currentToken = null;
+
+
+ //NOTE: patch _bootstrap method
+ parser._bootstrap = function (document, fragmentContext) {
+ parserProto._bootstrap.call(this, document, fragmentContext);
+
+ attachableElementLocation = null;
+ lastFosterParentingLocation = null;
+ currentToken = null;
+
+ //OpenElementStack
+ parser.openElements.pop = function () {
+ setEndLocation(this.current, currentToken, treeAdapter);
+ OpenElementStack.prototype.pop.call(this);
+ };
+
+ parser.openElements.popAllUpToHtmlElement = function () {
+ for (var i = this.stackTop; i > 0; i--)
+ setEndLocation(this.items[i], currentToken, treeAdapter);
+
+ OpenElementStack.prototype.popAllUpToHtmlElement.call(this);
+ };
+
+ parser.openElements.remove = function (element) {
+ setEndLocation(element, currentToken, treeAdapter);
+ OpenElementStack.prototype.remove.call(this, element);
+ };
+ };
+
+
+ //Token processing
+ parser._processTokenInForeignContent = function (token) {
+ currentToken = token;
+ parserProto._processTokenInForeignContent.call(this, token);
+ };
+
+ parser._processToken = function (token) {
+ currentToken = token;
+ parserProto._processToken.call(this, token);
+
+ //NOTE: and are never popped from the stack, so we need to updated
+ //their end location explicitly.
+ if (token.type === Tokenizer.END_TAG_TOKEN &&
+ (token.tagName === $.HTML ||
+ token.tagName === $.BODY && this.openElements.hasInScope($.BODY))) {
+ for (var i = this.openElements.stackTop; i >= 0; i--) {
+ var element = this.openElements.items[i];
+
+ if (this.treeAdapter.getTagName(element) === token.tagName) {
+ setEndLocation(element, token, treeAdapter);
+ break;
+ }
+ }
+ }
+ };
+
+
+ //Doctype
+ parser._setDocumentType = function (token) {
+ parserProto._setDocumentType.call(this, token);
+
+ var documentChildren = this.treeAdapter.getChildNodes(this.document),
+ cnLength = documentChildren.length;
+
+ for (var i = 0; i < cnLength; i++) {
+ var node = documentChildren[i];
+
+ if (this.treeAdapter.isDocumentTypeNode(node)) {
+ node.__location = token.location;
+ break;
+ }
+ }
+ };
+
+
+ //Elements
+ parser._attachElementToTree = function (element) {
+ //NOTE: _attachElementToTree is called from _appendElement, _insertElement and _insertTemplate methods.
+ //So we will use token location stored in this methods for the element.
+ element.__location = attachableElementLocation || null;
+ attachableElementLocation = null;
+ parserProto._attachElementToTree.call(this, element);
+ };
+
+ parser._appendElement = function (token, namespaceURI) {
+ attachableElementLocation = token.location;
+ parserProto._appendElement.call(this, token, namespaceURI);
+ };
+
+ parser._insertElement = function (token, namespaceURI) {
+ attachableElementLocation = token.location;
+ parserProto._insertElement.call(this, token, namespaceURI);
+ };
+
+ parser._insertTemplate = function (token) {
+ attachableElementLocation = token.location;
+ parserProto._insertTemplate.call(this, token);
+
+ var tmplContent = this.treeAdapter.getTemplateContent(this.openElements.current);
+
+ tmplContent.__location = null;
+ };
+
+ parser._insertFakeRootElement = function () {
+ parserProto._insertFakeRootElement.call(this);
+ this.openElements.current.__location = null;
+ };
+
+
+ //Comments
+ parser._appendCommentNode = function (token, parent) {
+ parserProto._appendCommentNode.call(this, token, parent);
+
+ var children = this.treeAdapter.getChildNodes(parent),
+ commentNode = children[children.length - 1];
+
+ commentNode.__location = token.location;
+ };
+
+
+ //Text
+ parser._findFosterParentingLocation = function () {
+ //NOTE: store last foster parenting location, so we will be able to find inserted text
+ //in case of foster parenting
+ lastFosterParentingLocation = parserProto._findFosterParentingLocation.call(this);
+ return lastFosterParentingLocation;
+ };
+
+ parser._insertCharacters = function (token) {
+ parserProto._insertCharacters.call(this, token);
+
+ var hasFosterParent = this._shouldFosterParentOnInsertion(),
+ parent = hasFosterParent && lastFosterParentingLocation.parent ||
+ this.openElements.currentTmplContent ||
+ this.openElements.current,
+ siblings = this.treeAdapter.getChildNodes(parent),
+ textNodeIdx = hasFosterParent && lastFosterParentingLocation.beforeElement ?
+ siblings.indexOf(lastFosterParentingLocation.beforeElement) - 1 :
+ siblings.length - 1,
+ textNode = siblings[textNodeIdx];
+
+ //NOTE: if we have location assigned by another token, then just update end position
+ if (textNode.__location)
+ textNode.__location.endOffset = token.location.endOffset;
+
+ else
+ textNode.__location = token.location;
+ };
+};
+
diff --git a/tools/eslint/node_modules/parse5/lib/location_info/tokenizer_mixin.js b/tools/eslint/node_modules/parse5/lib/location_info/tokenizer_mixin.js
new file mode 100644
index 00000000000000..bbdebd7cfc5a94
--- /dev/null
+++ b/tools/eslint/node_modules/parse5/lib/location_info/tokenizer_mixin.js
@@ -0,0 +1,169 @@
+'use strict';
+
+var UNICODE = require('../common/unicode');
+
+//Aliases
+var $ = UNICODE.CODE_POINTS;
+
+
+exports.assign = function (tokenizer) {
+ //NOTE: obtain Tokenizer proto this way to avoid module circular references
+ var tokenizerProto = Object.getPrototypeOf(tokenizer),
+ tokenStartOffset = -1,
+ tokenCol = -1,
+ tokenLine = 1,
+ isEol = false,
+ lineStartPosStack = [0],
+ lineStartPos = 0,
+ col = -1,
+ line = 1;
+
+ function attachLocationInfo(token) {
+ /**
+ * @typedef {Object} LocationInfo
+ *
+ * @property {Number} line - One-based line index
+ * @property {Number} col - One-based column index
+ * @property {Number} startOffset - Zero-based first character index
+ * @property {Number} endOffset - Zero-based last character index
+ */
+ token.location = {
+ line: tokenLine,
+ col: tokenCol,
+ startOffset: tokenStartOffset,
+ endOffset: -1
+ };
+ }
+
+ //NOTE: patch consumption method to track line/col information
+ tokenizer._consume = function () {
+ var cp = tokenizerProto._consume.call(this);
+
+ //NOTE: LF should be in the last column of the line
+ if (isEol) {
+ isEol = false;
+ line++;
+ lineStartPosStack.push(this.preprocessor.sourcePos);
+ lineStartPos = this.preprocessor.sourcePos;
+ }
+
+ if (cp === $.LINE_FEED)
+ isEol = true;
+
+ col = this.preprocessor.sourcePos - lineStartPos + 1;
+
+ return cp;
+ };
+
+ tokenizer._unconsume = function () {
+ tokenizerProto._unconsume.call(this);
+ isEol = false;
+
+ while (lineStartPos > this.preprocessor.sourcePos && lineStartPosStack.length > 1) {
+ lineStartPos = lineStartPosStack.pop();
+ line--;
+ }
+
+ col = this.preprocessor.sourcePos - lineStartPos + 1;
+ };
+
+ //NOTE: patch token creation methods and attach location objects
+ tokenizer._createStartTagToken = function () {
+ tokenizerProto._createStartTagToken.call(this);
+ attachLocationInfo(this.currentToken);
+ };
+
+ tokenizer._createEndTagToken = function () {
+ tokenizerProto._createEndTagToken.call(this);
+ attachLocationInfo(this.currentToken);
+ };
+
+ tokenizer._createCommentToken = function () {
+ tokenizerProto._createCommentToken.call(this);
+ attachLocationInfo(this.currentToken);
+ };
+
+ tokenizer._createDoctypeToken = function (initialName) {
+ tokenizerProto._createDoctypeToken.call(this, initialName);
+ attachLocationInfo(this.currentToken);
+ };
+
+ tokenizer._createCharacterToken = function (type, ch) {
+ tokenizerProto._createCharacterToken.call(this, type, ch);
+ attachLocationInfo(this.currentCharacterToken);
+ };
+
+ tokenizer._createAttr = function (attrNameFirstCh) {
+ tokenizerProto._createAttr.call(this, attrNameFirstCh);
+ this.currentAttrLocation = {
+ line: line,
+ col: col,
+ startOffset: this.preprocessor.sourcePos,
+ endOffset: -1
+ };
+ };
+
+ tokenizer._leaveAttrName = function (toState) {
+ tokenizerProto._leaveAttrName.call(this, toState);
+ this._attachCurrentAttrLocationInfo();
+ };
+
+ tokenizer._leaveAttrValue = function (toState) {
+ tokenizerProto._leaveAttrValue.call(this, toState);
+ this._attachCurrentAttrLocationInfo();
+ };
+
+ tokenizer._attachCurrentAttrLocationInfo = function () {
+ this.currentAttrLocation.endOffset = this.preprocessor.sourcePos;
+
+ if (!this.currentToken.location.attrs)
+ this.currentToken.location.attrs = {};
+
+ /**
+ * @typedef {Object} StartTagLocationInfo
+ * @extends LocationInfo
+ *
+ * @property {Dictionary} attrs - Start tag attributes' location info.
+ */
+ this.currentToken.location.attrs[this.currentAttr.name] = this.currentAttrLocation;
+ };
+
+ //NOTE: patch token emission methods to determine end location
+ tokenizer._emitCurrentToken = function () {
+ //NOTE: if we have pending character token make it's end location equal to the
+ //current token's start location.
+ if (this.currentCharacterToken)
+ this.currentCharacterToken.location.endOffset = this.currentToken.location.startOffset;
+
+ this.currentToken.location.endOffset = this.preprocessor.sourcePos + 1;
+ tokenizerProto._emitCurrentToken.call(this);
+ };
+
+ tokenizer._emitCurrentCharacterToken = function () {
+ //NOTE: if we have character token and it's location wasn't set in the _emitCurrentToken(),
+ //then set it's location at the current preprocessor position.
+ //We don't need to increment preprocessor position, since character token
+ //emission is always forced by the start of the next character token here.
+ //So, we already have advanced position.
+ if (this.currentCharacterToken && this.currentCharacterToken.location.endOffset === -1)
+ this.currentCharacterToken.location.endOffset = this.preprocessor.sourcePos;
+
+ tokenizerProto._emitCurrentCharacterToken.call(this);
+ };
+
+ //NOTE: patch initial states for each mode to obtain token start position
+ Object.keys(tokenizerProto.MODE)
+
+ .map(function (modeName) {
+ return tokenizerProto.MODE[modeName];
+ })
+
+ .forEach(function (state) {
+ tokenizer[state] = function (cp) {
+ tokenStartOffset = this.preprocessor.sourcePos;
+ tokenLine = line;
+ tokenCol = col;
+ tokenizerProto[state].call(this, cp);
+ };
+ });
+};
diff --git a/tools/eslint/node_modules/parse5/lib/parser/formatting_element_list.js b/tools/eslint/node_modules/parse5/lib/parser/formatting_element_list.js
new file mode 100644
index 00000000000000..8aa2859b300e06
--- /dev/null
+++ b/tools/eslint/node_modules/parse5/lib/parser/formatting_element_list.js
@@ -0,0 +1,167 @@
+'use strict';
+
+//Const
+var NOAH_ARK_CAPACITY = 3;
+
+//List of formatting elements
+var FormattingElementList = module.exports = function (treeAdapter) {
+ this.length = 0;
+ this.entries = [];
+ this.treeAdapter = treeAdapter;
+ this.bookmark = null;
+};
+
+//Entry types
+FormattingElementList.MARKER_ENTRY = 'MARKER_ENTRY';
+FormattingElementList.ELEMENT_ENTRY = 'ELEMENT_ENTRY';
+
+//Noah Ark's condition
+//OPTIMIZATION: at first we try to find possible candidates for exclusion using
+//lightweight heuristics without thorough attributes check.
+FormattingElementList.prototype._getNoahArkConditionCandidates = function (newElement) {
+ var candidates = [];
+
+ if (this.length >= NOAH_ARK_CAPACITY) {
+ var neAttrsLength = this.treeAdapter.getAttrList(newElement).length,
+ neTagName = this.treeAdapter.getTagName(newElement),
+ neNamespaceURI = this.treeAdapter.getNamespaceURI(newElement);
+
+ for (var i = this.length - 1; i >= 0; i--) {
+ var entry = this.entries[i];
+
+ if (entry.type === FormattingElementList.MARKER_ENTRY)
+ break;
+
+ var element = entry.element,
+ elementAttrs = this.treeAdapter.getAttrList(element),
+ isCandidate = this.treeAdapter.getTagName(element) === neTagName &&
+ this.treeAdapter.getNamespaceURI(element) === neNamespaceURI &&
+ elementAttrs.length === neAttrsLength;
+
+ if (isCandidate)
+ candidates.push({idx: i, attrs: elementAttrs});
+ }
+ }
+
+ return candidates.length < NOAH_ARK_CAPACITY ? [] : candidates;
+};
+
+FormattingElementList.prototype._ensureNoahArkCondition = function (newElement) {
+ var candidates = this._getNoahArkConditionCandidates(newElement),
+ cLength = candidates.length;
+
+ if (cLength) {
+ var neAttrs = this.treeAdapter.getAttrList(newElement),
+ neAttrsLength = neAttrs.length,
+ neAttrsMap = {};
+
+ //NOTE: build attrs map for the new element so we can perform fast lookups
+ for (var i = 0; i < neAttrsLength; i++) {
+ var neAttr = neAttrs[i];
+
+ neAttrsMap[neAttr.name] = neAttr.value;
+ }
+
+ for (i = 0; i < neAttrsLength; i++) {
+ for (var j = 0; j < cLength; j++) {
+ var cAttr = candidates[j].attrs[i];
+
+ if (neAttrsMap[cAttr.name] !== cAttr.value) {
+ candidates.splice(j, 1);
+ cLength--;
+ }
+
+ if (candidates.length < NOAH_ARK_CAPACITY)
+ return;
+ }
+ }
+
+ //NOTE: remove bottommost candidates until Noah's Ark condition will not be met
+ for (i = cLength - 1; i >= NOAH_ARK_CAPACITY - 1; i--) {
+ this.entries.splice(candidates[i].idx, 1);
+ this.length--;
+ }
+ }
+};
+
+//Mutations
+FormattingElementList.prototype.insertMarker = function () {
+ this.entries.push({type: FormattingElementList.MARKER_ENTRY});
+ this.length++;
+};
+
+FormattingElementList.prototype.pushElement = function (element, token) {
+ this._ensureNoahArkCondition(element);
+
+ this.entries.push({
+ type: FormattingElementList.ELEMENT_ENTRY,
+ element: element,
+ token: token
+ });
+
+ this.length++;
+};
+
+FormattingElementList.prototype.insertElementAfterBookmark = function (element, token) {
+ var bookmarkIdx = this.length - 1;
+
+ for (; bookmarkIdx >= 0; bookmarkIdx--) {
+ if (this.entries[bookmarkIdx] === this.bookmark)
+ break;
+ }
+
+ this.entries.splice(bookmarkIdx + 1, 0, {
+ type: FormattingElementList.ELEMENT_ENTRY,
+ element: element,
+ token: token
+ });
+
+ this.length++;
+};
+
+FormattingElementList.prototype.removeEntry = function (entry) {
+ for (var i = this.length - 1; i >= 0; i--) {
+ if (this.entries[i] === entry) {
+ this.entries.splice(i, 1);
+ this.length--;
+ break;
+ }
+ }
+};
+
+FormattingElementList.prototype.clearToLastMarker = function () {
+ while (this.length) {
+ var entry = this.entries.pop();
+
+ this.length--;
+
+ if (entry.type === FormattingElementList.MARKER_ENTRY)
+ break;
+ }
+};
+
+//Search
+FormattingElementList.prototype.getElementEntryInScopeWithTagName = function (tagName) {
+ for (var i = this.length - 1; i >= 0; i--) {
+ var entry = this.entries[i];
+
+ if (entry.type === FormattingElementList.MARKER_ENTRY)
+ return null;
+
+ if (this.treeAdapter.getTagName(entry.element) === tagName)
+ return entry;
+ }
+
+ return null;
+};
+
+FormattingElementList.prototype.getElementEntry = function (element) {
+ for (var i = this.length - 1; i >= 0; i--) {
+ var entry = this.entries[i];
+
+ if (entry.type === FormattingElementList.ELEMENT_ENTRY && entry.element === element)
+ return entry;
+ }
+
+ return null;
+};
diff --git a/tools/eslint/node_modules/parse5/lib/parser/index.js b/tools/eslint/node_modules/parse5/lib/parser/index.js
new file mode 100644
index 00000000000000..71cbd639eb224c
--- /dev/null
+++ b/tools/eslint/node_modules/parse5/lib/parser/index.js
@@ -0,0 +1,2817 @@
+'use strict';
+
+var Tokenizer = require('../tokenizer'),
+ OpenElementStack = require('./open_element_stack'),
+ FormattingElementList = require('./formatting_element_list'),
+ locationInfoMixin = require('../location_info/parser_mixin'),
+ defaultTreeAdapter = require('../tree_adapters/default'),
+ doctype = require('../common/doctype'),
+ foreignContent = require('../common/foreign_content'),
+ mergeOptions = require('../common/merge_options'),
+ UNICODE = require('../common/unicode'),
+ HTML = require('../common/html');
+
+//Aliases
+var $ = HTML.TAG_NAMES,
+ NS = HTML.NAMESPACES,
+ ATTRS = HTML.ATTRS;
+
+/**
+ * @typedef {Object} ParserOptions
+ *
+ * @property {Boolean} [locationInfo=false] - Enables source code location information for the nodes.
+ * When enabled, each node (except root node) has the `__location` property. In case the node is not an empty element,
+ * `__location` will be {@link ElementLocationInfo} object, otherwise it's {@link LocationInfo}.
+ * If the element was implicitly created by the parser it's `__location` property will be `null`.
+ *
+ * @property {TreeAdapter} [treeAdapter=parse5.treeAdapters.default] - Specifies the resulting tree format.
+ */
+var DEFAULT_OPTIONS = {
+ locationInfo: false,
+ treeAdapter: defaultTreeAdapter
+};
+
+//Misc constants
+var HIDDEN_INPUT_TYPE = 'hidden';
+
+//Adoption agency loops iteration count
+var AA_OUTER_LOOP_ITER = 8,
+ AA_INNER_LOOP_ITER = 3;
+
+//Insertion modes
+var INITIAL_MODE = 'INITIAL_MODE',
+ BEFORE_HTML_MODE = 'BEFORE_HTML_MODE',
+ BEFORE_HEAD_MODE = 'BEFORE_HEAD_MODE',
+ IN_HEAD_MODE = 'IN_HEAD_MODE',
+ AFTER_HEAD_MODE = 'AFTER_HEAD_MODE',
+ IN_BODY_MODE = 'IN_BODY_MODE',
+ TEXT_MODE = 'TEXT_MODE',
+ IN_TABLE_MODE = 'IN_TABLE_MODE',
+ IN_TABLE_TEXT_MODE = 'IN_TABLE_TEXT_MODE',
+ IN_CAPTION_MODE = 'IN_CAPTION_MODE',
+ IN_COLUMN_GROUP_MODE = 'IN_COLUMN_GROUP_MODE',
+ IN_TABLE_BODY_MODE = 'IN_TABLE_BODY_MODE',
+ IN_ROW_MODE = 'IN_ROW_MODE',
+ IN_CELL_MODE = 'IN_CELL_MODE',
+ IN_SELECT_MODE = 'IN_SELECT_MODE',
+ IN_SELECT_IN_TABLE_MODE = 'IN_SELECT_IN_TABLE_MODE',
+ IN_TEMPLATE_MODE = 'IN_TEMPLATE_MODE',
+ AFTER_BODY_MODE = 'AFTER_BODY_MODE',
+ IN_FRAMESET_MODE = 'IN_FRAMESET_MODE',
+ AFTER_FRAMESET_MODE = 'AFTER_FRAMESET_MODE',
+ AFTER_AFTER_BODY_MODE = 'AFTER_AFTER_BODY_MODE',
+ AFTER_AFTER_FRAMESET_MODE = 'AFTER_AFTER_FRAMESET_MODE';
+
+//Insertion mode reset map
+var INSERTION_MODE_RESET_MAP = {};
+
+INSERTION_MODE_RESET_MAP[$.TR] = IN_ROW_MODE;
+INSERTION_MODE_RESET_MAP[$.TBODY] =
+INSERTION_MODE_RESET_MAP[$.THEAD] =
+INSERTION_MODE_RESET_MAP[$.TFOOT] = IN_TABLE_BODY_MODE;
+INSERTION_MODE_RESET_MAP[$.CAPTION] = IN_CAPTION_MODE;
+INSERTION_MODE_RESET_MAP[$.COLGROUP] = IN_COLUMN_GROUP_MODE;
+INSERTION_MODE_RESET_MAP[$.TABLE] = IN_TABLE_MODE;
+INSERTION_MODE_RESET_MAP[$.BODY] = IN_BODY_MODE;
+INSERTION_MODE_RESET_MAP[$.FRAMESET] = IN_FRAMESET_MODE;
+
+//Template insertion mode switch map
+var TEMPLATE_INSERTION_MODE_SWITCH_MAP = {};
+
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.CAPTION] =
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.COLGROUP] =
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TBODY] =
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TFOOT] =
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.THEAD] = IN_TABLE_MODE;
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.COL] = IN_COLUMN_GROUP_MODE;
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TR] = IN_TABLE_BODY_MODE;
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TD] =
+TEMPLATE_INSERTION_MODE_SWITCH_MAP[$.TH] = IN_ROW_MODE;
+
+//Token handlers map for insertion modes
+var _ = {};
+
+_[INITIAL_MODE] = {};
+_[INITIAL_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[INITIAL_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenInInitialMode;
+_[INITIAL_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = ignoreToken;
+_[INITIAL_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[INITIAL_MODE][Tokenizer.DOCTYPE_TOKEN] = doctypeInInitialMode;
+_[INITIAL_MODE][Tokenizer.START_TAG_TOKEN] =
+_[INITIAL_MODE][Tokenizer.END_TAG_TOKEN] =
+_[INITIAL_MODE][Tokenizer.EOF_TOKEN] = tokenInInitialMode;
+
+_[BEFORE_HTML_MODE] = {};
+_[BEFORE_HTML_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[BEFORE_HTML_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenBeforeHtml;
+_[BEFORE_HTML_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = ignoreToken;
+_[BEFORE_HTML_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[BEFORE_HTML_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[BEFORE_HTML_MODE][Tokenizer.START_TAG_TOKEN] = startTagBeforeHtml;
+_[BEFORE_HTML_MODE][Tokenizer.END_TAG_TOKEN] = endTagBeforeHtml;
+_[BEFORE_HTML_MODE][Tokenizer.EOF_TOKEN] = tokenBeforeHtml;
+
+_[BEFORE_HEAD_MODE] = {};
+_[BEFORE_HEAD_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[BEFORE_HEAD_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenBeforeHead;
+_[BEFORE_HEAD_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = ignoreToken;
+_[BEFORE_HEAD_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[BEFORE_HEAD_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[BEFORE_HEAD_MODE][Tokenizer.START_TAG_TOKEN] = startTagBeforeHead;
+_[BEFORE_HEAD_MODE][Tokenizer.END_TAG_TOKEN] = endTagBeforeHead;
+_[BEFORE_HEAD_MODE][Tokenizer.EOF_TOKEN] = tokenBeforeHead;
+
+_[IN_HEAD_MODE] = {};
+_[IN_HEAD_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[IN_HEAD_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenInHead;
+_[IN_HEAD_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[IN_HEAD_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_HEAD_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_HEAD_MODE][Tokenizer.START_TAG_TOKEN] = startTagInHead;
+_[IN_HEAD_MODE][Tokenizer.END_TAG_TOKEN] = endTagInHead;
+_[IN_HEAD_MODE][Tokenizer.EOF_TOKEN] = tokenInHead;
+
+_[AFTER_HEAD_MODE] = {};
+_[AFTER_HEAD_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[AFTER_HEAD_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenAfterHead;
+_[AFTER_HEAD_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[AFTER_HEAD_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[AFTER_HEAD_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[AFTER_HEAD_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterHead;
+_[AFTER_HEAD_MODE][Tokenizer.END_TAG_TOKEN] = endTagAfterHead;
+_[AFTER_HEAD_MODE][Tokenizer.EOF_TOKEN] = tokenAfterHead;
+
+_[IN_BODY_MODE] = {};
+_[IN_BODY_MODE][Tokenizer.CHARACTER_TOKEN] = characterInBody;
+_[IN_BODY_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_BODY_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[IN_BODY_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_BODY_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_BODY_MODE][Tokenizer.START_TAG_TOKEN] = startTagInBody;
+_[IN_BODY_MODE][Tokenizer.END_TAG_TOKEN] = endTagInBody;
+_[IN_BODY_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[TEXT_MODE] = {};
+_[TEXT_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[TEXT_MODE][Tokenizer.NULL_CHARACTER_TOKEN] =
+_[TEXT_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[TEXT_MODE][Tokenizer.COMMENT_TOKEN] =
+_[TEXT_MODE][Tokenizer.DOCTYPE_TOKEN] =
+_[TEXT_MODE][Tokenizer.START_TAG_TOKEN] = ignoreToken;
+_[TEXT_MODE][Tokenizer.END_TAG_TOKEN] = endTagInText;
+_[TEXT_MODE][Tokenizer.EOF_TOKEN] = eofInText;
+
+_[IN_TABLE_MODE] = {};
+_[IN_TABLE_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[IN_TABLE_MODE][Tokenizer.NULL_CHARACTER_TOKEN] =
+_[IN_TABLE_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = characterInTable;
+_[IN_TABLE_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_TABLE_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_TABLE_MODE][Tokenizer.START_TAG_TOKEN] = startTagInTable;
+_[IN_TABLE_MODE][Tokenizer.END_TAG_TOKEN] = endTagInTable;
+_[IN_TABLE_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_TABLE_TEXT_MODE] = {};
+_[IN_TABLE_TEXT_MODE][Tokenizer.CHARACTER_TOKEN] = characterInTableText;
+_[IN_TABLE_TEXT_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_TABLE_TEXT_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInTableText;
+_[IN_TABLE_TEXT_MODE][Tokenizer.COMMENT_TOKEN] =
+_[IN_TABLE_TEXT_MODE][Tokenizer.DOCTYPE_TOKEN] =
+_[IN_TABLE_TEXT_MODE][Tokenizer.START_TAG_TOKEN] =
+_[IN_TABLE_TEXT_MODE][Tokenizer.END_TAG_TOKEN] =
+_[IN_TABLE_TEXT_MODE][Tokenizer.EOF_TOKEN] = tokenInTableText;
+
+_[IN_CAPTION_MODE] = {};
+_[IN_CAPTION_MODE][Tokenizer.CHARACTER_TOKEN] = characterInBody;
+_[IN_CAPTION_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_CAPTION_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[IN_CAPTION_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_CAPTION_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_CAPTION_MODE][Tokenizer.START_TAG_TOKEN] = startTagInCaption;
+_[IN_CAPTION_MODE][Tokenizer.END_TAG_TOKEN] = endTagInCaption;
+_[IN_CAPTION_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_COLUMN_GROUP_MODE] = {};
+_[IN_COLUMN_GROUP_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[IN_COLUMN_GROUP_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenInColumnGroup;
+_[IN_COLUMN_GROUP_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[IN_COLUMN_GROUP_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_COLUMN_GROUP_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_COLUMN_GROUP_MODE][Tokenizer.START_TAG_TOKEN] = startTagInColumnGroup;
+_[IN_COLUMN_GROUP_MODE][Tokenizer.END_TAG_TOKEN] = endTagInColumnGroup;
+_[IN_COLUMN_GROUP_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_TABLE_BODY_MODE] = {};
+_[IN_TABLE_BODY_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[IN_TABLE_BODY_MODE][Tokenizer.NULL_CHARACTER_TOKEN] =
+_[IN_TABLE_BODY_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = characterInTable;
+_[IN_TABLE_BODY_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_TABLE_BODY_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_TABLE_BODY_MODE][Tokenizer.START_TAG_TOKEN] = startTagInTableBody;
+_[IN_TABLE_BODY_MODE][Tokenizer.END_TAG_TOKEN] = endTagInTableBody;
+_[IN_TABLE_BODY_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_ROW_MODE] = {};
+_[IN_ROW_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[IN_ROW_MODE][Tokenizer.NULL_CHARACTER_TOKEN] =
+_[IN_ROW_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = characterInTable;
+_[IN_ROW_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_ROW_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_ROW_MODE][Tokenizer.START_TAG_TOKEN] = startTagInRow;
+_[IN_ROW_MODE][Tokenizer.END_TAG_TOKEN] = endTagInRow;
+_[IN_ROW_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_CELL_MODE] = {};
+_[IN_CELL_MODE][Tokenizer.CHARACTER_TOKEN] = characterInBody;
+_[IN_CELL_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_CELL_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[IN_CELL_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_CELL_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_CELL_MODE][Tokenizer.START_TAG_TOKEN] = startTagInCell;
+_[IN_CELL_MODE][Tokenizer.END_TAG_TOKEN] = endTagInCell;
+_[IN_CELL_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_SELECT_MODE] = {};
+_[IN_SELECT_MODE][Tokenizer.CHARACTER_TOKEN] = insertCharacters;
+_[IN_SELECT_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_SELECT_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[IN_SELECT_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_SELECT_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_SELECT_MODE][Tokenizer.START_TAG_TOKEN] = startTagInSelect;
+_[IN_SELECT_MODE][Tokenizer.END_TAG_TOKEN] = endTagInSelect;
+_[IN_SELECT_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_SELECT_IN_TABLE_MODE] = {};
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.CHARACTER_TOKEN] = insertCharacters;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.START_TAG_TOKEN] = startTagInSelectInTable;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.END_TAG_TOKEN] = endTagInSelectInTable;
+_[IN_SELECT_IN_TABLE_MODE][Tokenizer.EOF_TOKEN] = eofInBody;
+
+_[IN_TEMPLATE_MODE] = {};
+_[IN_TEMPLATE_MODE][Tokenizer.CHARACTER_TOKEN] = characterInBody;
+_[IN_TEMPLATE_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_TEMPLATE_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[IN_TEMPLATE_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_TEMPLATE_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_TEMPLATE_MODE][Tokenizer.START_TAG_TOKEN] = startTagInTemplate;
+_[IN_TEMPLATE_MODE][Tokenizer.END_TAG_TOKEN] = endTagInTemplate;
+_[IN_TEMPLATE_MODE][Tokenizer.EOF_TOKEN] = eofInTemplate;
+
+_[AFTER_BODY_MODE] = {};
+_[AFTER_BODY_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[AFTER_BODY_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenAfterBody;
+_[AFTER_BODY_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[AFTER_BODY_MODE][Tokenizer.COMMENT_TOKEN] = appendCommentToRootHtmlElement;
+_[AFTER_BODY_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[AFTER_BODY_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterBody;
+_[AFTER_BODY_MODE][Tokenizer.END_TAG_TOKEN] = endTagAfterBody;
+_[AFTER_BODY_MODE][Tokenizer.EOF_TOKEN] = stopParsing;
+
+_[IN_FRAMESET_MODE] = {};
+_[IN_FRAMESET_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[IN_FRAMESET_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[IN_FRAMESET_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[IN_FRAMESET_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[IN_FRAMESET_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[IN_FRAMESET_MODE][Tokenizer.START_TAG_TOKEN] = startTagInFrameset;
+_[IN_FRAMESET_MODE][Tokenizer.END_TAG_TOKEN] = endTagInFrameset;
+_[IN_FRAMESET_MODE][Tokenizer.EOF_TOKEN] = stopParsing;
+
+_[AFTER_FRAMESET_MODE] = {};
+_[AFTER_FRAMESET_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[AFTER_FRAMESET_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[AFTER_FRAMESET_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = insertCharacters;
+_[AFTER_FRAMESET_MODE][Tokenizer.COMMENT_TOKEN] = appendComment;
+_[AFTER_FRAMESET_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[AFTER_FRAMESET_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterFrameset;
+_[AFTER_FRAMESET_MODE][Tokenizer.END_TAG_TOKEN] = endTagAfterFrameset;
+_[AFTER_FRAMESET_MODE][Tokenizer.EOF_TOKEN] = stopParsing;
+
+_[AFTER_AFTER_BODY_MODE] = {};
+_[AFTER_AFTER_BODY_MODE][Tokenizer.CHARACTER_TOKEN] = tokenAfterAfterBody;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = tokenAfterAfterBody;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.COMMENT_TOKEN] = appendCommentToDocument;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterAfterBody;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.END_TAG_TOKEN] = tokenAfterAfterBody;
+_[AFTER_AFTER_BODY_MODE][Tokenizer.EOF_TOKEN] = stopParsing;
+
+_[AFTER_AFTER_FRAMESET_MODE] = {};
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.CHARACTER_TOKEN] =
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.NULL_CHARACTER_TOKEN] = ignoreToken;
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.WHITESPACE_CHARACTER_TOKEN] = whitespaceCharacterInBody;
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.COMMENT_TOKEN] = appendCommentToDocument;
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.DOCTYPE_TOKEN] = ignoreToken;
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.START_TAG_TOKEN] = startTagAfterAfterFrameset;
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.END_TAG_TOKEN] = ignoreToken;
+_[AFTER_AFTER_FRAMESET_MODE][Tokenizer.EOF_TOKEN] = stopParsing;
+
+
+//Parser
+var Parser = module.exports = function (options) {
+ this.options = mergeOptions(DEFAULT_OPTIONS, options);
+
+ this.treeAdapter = this.options.treeAdapter;
+ this.pendingScript = null;
+
+ if (this.options.locationInfo)
+ locationInfoMixin.assign(this);
+};
+
+// API
+Parser.prototype.parse = function (html) {
+ var document = this.treeAdapter.createDocument();
+
+ this._bootstrap(document, null);
+ this.tokenizer.write(html, true);
+ this._runParsingLoop(null, null);
+
+ return document;
+};
+
+Parser.prototype.parseFragment = function (html, fragmentContext) {
+ //NOTE: use element as a fragment context if context element was not provided,
+ //so we will parse in "forgiving" manner
+ if (!fragmentContext)
+ fragmentContext = this.treeAdapter.createElement($.TEMPLATE, NS.HTML, []);
+
+ //NOTE: create fake element which will be used as 'document' for fragment parsing.
+ //This is important for jsdom there 'document' can't be recreated, therefore
+ //fragment parsing causes messing of the main `document`.
+ var documentMock = this.treeAdapter.createElement('documentmock', NS.HTML, []);
+
+ this._bootstrap(documentMock, fragmentContext);
+
+ if (this.treeAdapter.getTagName(fragmentContext) === $.TEMPLATE)
+ this._pushTmplInsertionMode(IN_TEMPLATE_MODE);
+
+ this._initTokenizerForFragmentParsing();
+ this._insertFakeRootElement();
+ this._resetInsertionMode();
+ this._findFormInFragmentContext();
+ this.tokenizer.write(html, true);
+ this._runParsingLoop(null, null);
+
+ var rootElement = this.treeAdapter.getFirstChild(documentMock),
+ fragment = this.treeAdapter.createDocumentFragment();
+
+ this._adoptNodes(rootElement, fragment);
+
+ return fragment;
+};
+
+//Bootstrap parser
+Parser.prototype._bootstrap = function (document, fragmentContext) {
+ this.tokenizer = new Tokenizer(this.options);
+
+ this.stopped = false;
+
+ this.insertionMode = INITIAL_MODE;
+ this.originalInsertionMode = '';
+
+ this.document = document;
+ this.fragmentContext = fragmentContext;
+
+ this.headElement = null;
+ this.formElement = null;
+
+ this.openElements = new OpenElementStack(this.document, this.treeAdapter);
+ this.activeFormattingElements = new FormattingElementList(this.treeAdapter);
+
+ this.tmplInsertionModeStack = [];
+ this.tmplInsertionModeStackTop = -1;
+ this.currentTmplInsertionMode = null;
+
+ this.pendingCharacterTokens = [];
+ this.hasNonWhitespacePendingCharacterToken = false;
+
+ this.framesetOk = true;
+ this.skipNextNewLine = false;
+ this.fosterParentingEnabled = false;
+};
+
+//Parsing loop
+Parser.prototype._runParsingLoop = function (writeCallback, scriptHandler) {
+ while (!this.stopped) {
+ this._setupTokenizerCDATAMode();
+
+ var token = this.tokenizer.getNextToken();
+
+ if (token.type === Tokenizer.HIBERNATION_TOKEN)
+ break;
+
+ if (this.skipNextNewLine) {
+ this.skipNextNewLine = false;
+
+ if (token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN && token.chars[0] === '\n') {
+ if (token.chars.length === 1)
+ continue;
+
+ token.chars = token.chars.substr(1);
+ }
+ }
+
+ this._processInputToken(token);
+
+ if (scriptHandler && this.pendingScript)
+ break;
+ }
+
+ if (scriptHandler && this.pendingScript) {
+ var script = this.pendingScript;
+
+ this.pendingScript = null;
+
+ scriptHandler(script);
+
+ return;
+ }
+
+ if (writeCallback)
+ writeCallback();
+};
+
+//Text parsing
+Parser.prototype._setupTokenizerCDATAMode = function () {
+ var current = this._getAdjustedCurrentElement();
+
+ this.tokenizer.allowCDATA = current && current !== this.document &&
+ this.treeAdapter.getNamespaceURI(current) !== NS.HTML &&
+ !this._isIntegrationPoint(current);
+};
+
+Parser.prototype._switchToTextParsing = function (currentToken, nextTokenizerState) {
+ this._insertElement(currentToken, NS.HTML);
+ this.tokenizer.state = nextTokenizerState;
+ this.originalInsertionMode = this.insertionMode;
+ this.insertionMode = TEXT_MODE;
+};
+
+//Fragment parsing
+Parser.prototype._getAdjustedCurrentElement = function () {
+ return this.openElements.stackTop === 0 && this.fragmentContext ?
+ this.fragmentContext :
+ this.openElements.current;
+};
+
+Parser.prototype._findFormInFragmentContext = function () {
+ var node = this.fragmentContext;
+
+ do {
+ if (this.treeAdapter.getTagName(node) === $.FORM) {
+ this.formElement = node;
+ break;
+ }
+
+ node = this.treeAdapter.getParentNode(node);
+ } while (node);
+};
+
+Parser.prototype._initTokenizerForFragmentParsing = function () {
+ if (this.treeAdapter.getNamespaceURI(this.fragmentContext) === NS.HTML) {
+ var tn = this.treeAdapter.getTagName(this.fragmentContext);
+
+ if (tn === $.TITLE || tn === $.TEXTAREA)
+ this.tokenizer.state = Tokenizer.MODE.RCDATA;
+
+ else if (tn === $.STYLE || tn === $.XMP || tn === $.IFRAME ||
+ tn === $.NOEMBED || tn === $.NOFRAMES || tn === $.NOSCRIPT)
+ this.tokenizer.state = Tokenizer.MODE.RAWTEXT;
+
+ else if (tn === $.SCRIPT)
+ this.tokenizer.state = Tokenizer.MODE.SCRIPT_DATA;
+
+ else if (tn === $.PLAINTEXT)
+ this.tokenizer.state = Tokenizer.MODE.PLAINTEXT;
+ }
+};
+
+//Tree mutation
+Parser.prototype._setDocumentType = function (token) {
+ this.treeAdapter.setDocumentType(this.document, token.name, token.publicId, token.systemId);
+};
+
+Parser.prototype._attachElementToTree = function (element) {
+ if (this._shouldFosterParentOnInsertion())
+ this._fosterParentElement(element);
+
+ else {
+ var parent = this.openElements.currentTmplContent || this.openElements.current;
+
+ this.treeAdapter.appendChild(parent, element);
+ }
+};
+
+Parser.prototype._appendElement = function (token, namespaceURI) {
+ var element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
+
+ this._attachElementToTree(element);
+};
+
+Parser.prototype._insertElement = function (token, namespaceURI) {
+ var element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
+
+ this._attachElementToTree(element);
+ this.openElements.push(element);
+};
+
+Parser.prototype._insertFakeElement = function (tagName) {
+ var element = this.treeAdapter.createElement(tagName, NS.HTML, []);
+
+ this._attachElementToTree(element);
+ this.openElements.push(element);
+};
+
+Parser.prototype._insertTemplate = function (token) {
+ var tmpl = this.treeAdapter.createElement(token.tagName, NS.HTML, token.attrs),
+ content = this.treeAdapter.createDocumentFragment();
+
+ this.treeAdapter.setTemplateContent(tmpl, content);
+ this._attachElementToTree(tmpl);
+ this.openElements.push(tmpl);
+};
+
+Parser.prototype._insertFakeRootElement = function () {
+ var element = this.treeAdapter.createElement($.HTML, NS.HTML, []);
+
+ this.treeAdapter.appendChild(this.openElements.current, element);
+ this.openElements.push(element);
+};
+
+Parser.prototype._appendCommentNode = function (token, parent) {
+ var commentNode = this.treeAdapter.createCommentNode(token.data);
+
+ this.treeAdapter.appendChild(parent, commentNode);
+};
+
+Parser.prototype._insertCharacters = function (token) {
+ if (this._shouldFosterParentOnInsertion())
+ this._fosterParentText(token.chars);
+
+ else {
+ var parent = this.openElements.currentTmplContent || this.openElements.current;
+
+ this.treeAdapter.insertText(parent, token.chars);
+ }
+};
+
+Parser.prototype._adoptNodes = function (donor, recipient) {
+ while (true) {
+ var child = this.treeAdapter.getFirstChild(donor);
+
+ if (!child)
+ break;
+
+ this.treeAdapter.detachNode(child);
+ this.treeAdapter.appendChild(recipient, child);
+ }
+};
+
+//Token processing
+Parser.prototype._shouldProcessTokenInForeignContent = function (token) {
+ var current = this._getAdjustedCurrentElement();
+
+ if (!current || current === this.document)
+ return false;
+
+ var ns = this.treeAdapter.getNamespaceURI(current);
+
+ if (ns === NS.HTML)
+ return false;
+
+ if (this.treeAdapter.getTagName(current) === $.ANNOTATION_XML && ns === NS.MATHML &&
+ token.type === Tokenizer.START_TAG_TOKEN && token.tagName === $.SVG)
+ return false;
+
+ var isCharacterToken = token.type === Tokenizer.CHARACTER_TOKEN ||
+ token.type === Tokenizer.NULL_CHARACTER_TOKEN ||
+ token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN,
+ isMathMLTextStartTag = token.type === Tokenizer.START_TAG_TOKEN &&
+ token.tagName !== $.MGLYPH &&
+ token.tagName !== $.MALIGNMARK;
+
+ if ((isMathMLTextStartTag || isCharacterToken) && this._isIntegrationPoint(current, NS.MATHML))
+ return false;
+
+ if ((token.type === Tokenizer.START_TAG_TOKEN || isCharacterToken) && this._isIntegrationPoint(current, NS.HTML))
+ return false;
+
+ return token.type !== Tokenizer.EOF_TOKEN;
+};
+
+Parser.prototype._processToken = function (token) {
+ _[this.insertionMode][token.type](this, token);
+};
+
+Parser.prototype._processTokenInBodyMode = function (token) {
+ _[IN_BODY_MODE][token.type](this, token);
+};
+
+Parser.prototype._processTokenInForeignContent = function (token) {
+ if (token.type === Tokenizer.CHARACTER_TOKEN)
+ characterInForeignContent(this, token);
+
+ else if (token.type === Tokenizer.NULL_CHARACTER_TOKEN)
+ nullCharacterInForeignContent(this, token);
+
+ else if (token.type === Tokenizer.WHITESPACE_CHARACTER_TOKEN)
+ insertCharacters(this, token);
+
+ else if (token.type === Tokenizer.COMMENT_TOKEN)
+ appendComment(this, token);
+
+ else if (token.type === Tokenizer.START_TAG_TOKEN)
+ startTagInForeignContent(this, token);
+
+ else if (token.type === Tokenizer.END_TAG_TOKEN)
+ endTagInForeignContent(this, token);
+};
+
+Parser.prototype._processInputToken = function (token) {
+ if (this._shouldProcessTokenInForeignContent(token))
+ this._processTokenInForeignContent(token);
+
+ else
+ this._processToken(token);
+};
+
+//Integration points
+Parser.prototype._isIntegrationPoint = function (element, foreignNS) {
+ var tn = this.treeAdapter.getTagName(element),
+ ns = this.treeAdapter.getNamespaceURI(element),
+ attrs = this.treeAdapter.getAttrList(element);
+
+ return foreignContent.isIntegrationPoint(tn, ns, attrs, foreignNS);
+};
+
+//Active formatting elements reconstruction
+Parser.prototype._reconstructActiveFormattingElements = function () {
+ var listLength = this.activeFormattingElements.length;
+
+ if (listLength) {
+ var unopenIdx = listLength,
+ entry = null;
+
+ do {
+ unopenIdx--;
+ entry = this.activeFormattingElements.entries[unopenIdx];
+
+ if (entry.type === FormattingElementList.MARKER_ENTRY || this.openElements.contains(entry.element)) {
+ unopenIdx++;
+ break;
+ }
+ } while (unopenIdx > 0);
+
+ for (var i = unopenIdx; i < listLength; i++) {
+ entry = this.activeFormattingElements.entries[i];
+ this._insertElement(entry.token, this.treeAdapter.getNamespaceURI(entry.element));
+ entry.element = this.openElements.current;
+ }
+ }
+};
+
+//Close elements
+Parser.prototype._closeTableCell = function () {
+ this.openElements.generateImpliedEndTags();
+ this.openElements.popUntilTableCellPopped();
+ this.activeFormattingElements.clearToLastMarker();
+ this.insertionMode = IN_ROW_MODE;
+};
+
+Parser.prototype._closePElement = function () {
+ this.openElements.generateImpliedEndTagsWithExclusion($.P);
+ this.openElements.popUntilTagNamePopped($.P);
+};
+
+//Insertion modes
+Parser.prototype._resetInsertionMode = function () {
+ for (var i = this.openElements.stackTop, last = false; i >= 0; i--) {
+ var element = this.openElements.items[i];
+
+ if (i === 0) {
+ last = true;
+
+ if (this.fragmentContext)
+ element = this.fragmentContext;
+ }
+
+ var tn = this.treeAdapter.getTagName(element),
+ newInsertionMode = INSERTION_MODE_RESET_MAP[tn];
+
+ if (newInsertionMode) {
+ this.insertionMode = newInsertionMode;
+ break;
+ }
+
+ else if (!last && (tn === $.TD || tn === $.TH)) {
+ this.insertionMode = IN_CELL_MODE;
+ break;
+ }
+
+ else if (!last && tn === $.HEAD) {
+ this.insertionMode = IN_HEAD_MODE;
+ break;
+ }
+
+ else if (tn === $.SELECT) {
+ this._resetInsertionModeForSelect(i);
+ break;
+ }
+
+ else if (tn === $.TEMPLATE) {
+ this.insertionMode = this.currentTmplInsertionMode;
+ break;
+ }
+
+ else if (tn === $.HTML) {
+ this.insertionMode = this.headElement ? AFTER_HEAD_MODE : BEFORE_HEAD_MODE;
+ break;
+ }
+
+ else if (last) {
+ this.insertionMode = IN_BODY_MODE;
+ break;
+ }
+ }
+};
+
+Parser.prototype._resetInsertionModeForSelect = function (selectIdx) {
+ if (selectIdx > 0) {
+ for (var i = selectIdx - 1; i > 0; i--) {
+ var ancestor = this.openElements.items[i],
+ tn = this.treeAdapter.getTagName(ancestor);
+
+ if (tn === $.TEMPLATE)
+ break;
+
+ else if (tn === $.TABLE) {
+ this.insertionMode = IN_SELECT_IN_TABLE_MODE;
+ return;
+ }
+ }
+ }
+
+ this.insertionMode = IN_SELECT_MODE;
+};
+
+Parser.prototype._pushTmplInsertionMode = function (mode) {
+ this.tmplInsertionModeStack.push(mode);
+ this.tmplInsertionModeStackTop++;
+ this.currentTmplInsertionMode = mode;
+};
+
+Parser.prototype._popTmplInsertionMode = function () {
+ this.tmplInsertionModeStack.pop();
+ this.tmplInsertionModeStackTop--;
+ this.currentTmplInsertionMode = this.tmplInsertionModeStack[this.tmplInsertionModeStackTop];
+};
+
+//Foster parenting
+Parser.prototype._isElementCausesFosterParenting = function (element) {
+ var tn = this.treeAdapter.getTagName(element);
+
+ return tn === $.TABLE || tn === $.TBODY || tn === $.TFOOT || tn === $.THEAD || tn === $.TR;
+};
+
+Parser.prototype._shouldFosterParentOnInsertion = function () {
+ return this.fosterParentingEnabled && this._isElementCausesFosterParenting(this.openElements.current);
+};
+
+Parser.prototype._findFosterParentingLocation = function () {
+ var location = {
+ parent: null,
+ beforeElement: null
+ };
+
+ for (var i = this.openElements.stackTop; i >= 0; i--) {
+ var openElement = this.openElements.items[i],
+ tn = this.treeAdapter.getTagName(openElement),
+ ns = this.treeAdapter.getNamespaceURI(openElement);
+
+ if (tn === $.TEMPLATE && ns === NS.HTML) {
+ location.parent = this.treeAdapter.getTemplateContent(openElement);
+ break;
+ }
+
+ else if (tn === $.TABLE) {
+ location.parent = this.treeAdapter.getParentNode(openElement);
+
+ if (location.parent)
+ location.beforeElement = openElement;
+ else
+ location.parent = this.openElements.items[i - 1];
+
+ break;
+ }
+ }
+
+ if (!location.parent)
+ location.parent = this.openElements.items[0];
+
+ return location;
+};
+
+Parser.prototype._fosterParentElement = function (element) {
+ var location = this._findFosterParentingLocation();
+
+ if (location.beforeElement)
+ this.treeAdapter.insertBefore(location.parent, element, location.beforeElement);
+ else
+ this.treeAdapter.appendChild(location.parent, element);
+};
+
+Parser.prototype._fosterParentText = function (chars) {
+ var location = this._findFosterParentingLocation();
+
+ if (location.beforeElement)
+ this.treeAdapter.insertTextBefore(location.parent, chars, location.beforeElement);
+ else
+ this.treeAdapter.insertText(location.parent, chars);
+};
+
+//Special elements
+Parser.prototype._isSpecialElement = function (element) {
+ var tn = this.treeAdapter.getTagName(element),
+ ns = this.treeAdapter.getNamespaceURI(element);
+
+ return HTML.SPECIAL_ELEMENTS[ns][tn];
+};
+
+//Adoption agency algorithm
+//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#adoptionAgency)
+//------------------------------------------------------------------
+
+//Steps 5-8 of the algorithm
+function aaObtainFormattingElementEntry(p, token) {
+ var formattingElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName(token.tagName);
+
+ if (formattingElementEntry) {
+ if (!p.openElements.contains(formattingElementEntry.element)) {
+ p.activeFormattingElements.removeEntry(formattingElementEntry);
+ formattingElementEntry = null;
+ }
+
+ else if (!p.openElements.hasInScope(token.tagName))
+ formattingElementEntry = null;
+ }
+
+ else
+ genericEndTagInBody(p, token);
+
+ return formattingElementEntry;
+}
+
+//Steps 9 and 10 of the algorithm
+function aaObtainFurthestBlock(p, formattingElementEntry) {
+ var furthestBlock = null;
+
+ for (var i = p.openElements.stackTop; i >= 0; i--) {
+ var element = p.openElements.items[i];
+
+ if (element === formattingElementEntry.element)
+ break;
+
+ if (p._isSpecialElement(element))
+ furthestBlock = element;
+ }
+
+ if (!furthestBlock) {
+ p.openElements.popUntilElementPopped(formattingElementEntry.element);
+ p.activeFormattingElements.removeEntry(formattingElementEntry);
+ }
+
+ return furthestBlock;
+}
+
+//Step 13 of the algorithm
+function aaInnerLoop(p, furthestBlock, formattingElement) {
+ var lastElement = furthestBlock,
+ nextElement = p.openElements.getCommonAncestor(furthestBlock);
+
+ for (var i = 0, element = nextElement; element !== formattingElement; i++, element = nextElement) {
+ //NOTE: store next element for the next loop iteration (it may be deleted from the stack by step 9.5)
+ nextElement = p.openElements.getCommonAncestor(element);
+
+ var elementEntry = p.activeFormattingElements.getElementEntry(element),
+ counterOverflow = elementEntry && i >= AA_INNER_LOOP_ITER,
+ shouldRemoveFromOpenElements = !elementEntry || counterOverflow;
+
+ if (shouldRemoveFromOpenElements) {
+ if (counterOverflow)
+ p.activeFormattingElements.removeEntry(elementEntry);
+
+ p.openElements.remove(element);
+ }
+
+ else {
+ element = aaRecreateElementFromEntry(p, elementEntry);
+
+ if (lastElement === furthestBlock)
+ p.activeFormattingElements.bookmark = elementEntry;
+
+ p.treeAdapter.detachNode(lastElement);
+ p.treeAdapter.appendChild(element, lastElement);
+ lastElement = element;
+ }
+ }
+
+ return lastElement;
+}
+
+//Step 13.7 of the algorithm
+function aaRecreateElementFromEntry(p, elementEntry) {
+ var ns = p.treeAdapter.getNamespaceURI(elementEntry.element),
+ newElement = p.treeAdapter.createElement(elementEntry.token.tagName, ns, elementEntry.token.attrs);
+
+ p.openElements.replace(elementEntry.element, newElement);
+ elementEntry.element = newElement;
+
+ return newElement;
+}
+
+//Step 14 of the algorithm
+function aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement) {
+ if (p._isElementCausesFosterParenting(commonAncestor))
+ p._fosterParentElement(lastElement);
+
+ else {
+ var tn = p.treeAdapter.getTagName(commonAncestor),
+ ns = p.treeAdapter.getNamespaceURI(commonAncestor);
+
+ if (tn === $.TEMPLATE && ns === NS.HTML)
+ commonAncestor = p.treeAdapter.getTemplateContent(commonAncestor);
+
+ p.treeAdapter.appendChild(commonAncestor, lastElement);
+ }
+}
+
+//Steps 15-19 of the algorithm
+function aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry) {
+ var ns = p.treeAdapter.getNamespaceURI(formattingElementEntry.element),
+ token = formattingElementEntry.token,
+ newElement = p.treeAdapter.createElement(token.tagName, ns, token.attrs);
+
+ p._adoptNodes(furthestBlock, newElement);
+ p.treeAdapter.appendChild(furthestBlock, newElement);
+
+ p.activeFormattingElements.insertElementAfterBookmark(newElement, formattingElementEntry.token);
+ p.activeFormattingElements.removeEntry(formattingElementEntry);
+
+ p.openElements.remove(formattingElementEntry.element);
+ p.openElements.insertAfter(furthestBlock, newElement);
+}
+
+//Algorithm entry point
+function callAdoptionAgency(p, token) {
+ var formattingElementEntry;
+
+ for (var i = 0; i < AA_OUTER_LOOP_ITER; i++) {
+ formattingElementEntry = aaObtainFormattingElementEntry(p, token, formattingElementEntry);
+
+ if (!formattingElementEntry)
+ break;
+
+ var furthestBlock = aaObtainFurthestBlock(p, formattingElementEntry);
+
+ if (!furthestBlock)
+ break;
+
+ p.activeFormattingElements.bookmark = formattingElementEntry;
+
+ var lastElement = aaInnerLoop(p, furthestBlock, formattingElementEntry.element),
+ commonAncestor = p.openElements.getCommonAncestor(formattingElementEntry.element);
+
+ p.treeAdapter.detachNode(lastElement);
+ aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement);
+ aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry);
+ }
+}
+
+
+//Generic token handlers
+//------------------------------------------------------------------
+function ignoreToken() {
+ //NOTE: do nothing =)
+}
+
+function appendComment(p, token) {
+ p._appendCommentNode(token, p.openElements.currentTmplContent || p.openElements.current);
+}
+
+function appendCommentToRootHtmlElement(p, token) {
+ p._appendCommentNode(token, p.openElements.items[0]);
+}
+
+function appendCommentToDocument(p, token) {
+ p._appendCommentNode(token, p.document);
+}
+
+function insertCharacters(p, token) {
+ p._insertCharacters(token);
+}
+
+function stopParsing(p) {
+ p.stopped = true;
+}
+
+//12.2.5.4.1 The "initial" insertion mode
+//------------------------------------------------------------------
+function doctypeInInitialMode(p, token) {
+ p._setDocumentType(token);
+
+ if (token.forceQuirks || doctype.isQuirks(token.name, token.publicId, token.systemId))
+ p.treeAdapter.setQuirksMode(p.document);
+
+ p.insertionMode = BEFORE_HTML_MODE;
+}
+
+function tokenInInitialMode(p, token) {
+ p.treeAdapter.setQuirksMode(p.document);
+ p.insertionMode = BEFORE_HTML_MODE;
+ p._processToken(token);
+}
+
+
+//12.2.5.4.2 The "before html" insertion mode
+//------------------------------------------------------------------
+function startTagBeforeHtml(p, token) {
+ if (token.tagName === $.HTML) {
+ p._insertElement(token, NS.HTML);
+ p.insertionMode = BEFORE_HEAD_MODE;
+ }
+
+ else
+ tokenBeforeHtml(p, token);
+}
+
+function endTagBeforeHtml(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HTML || tn === $.HEAD || tn === $.BODY || tn === $.BR)
+ tokenBeforeHtml(p, token);
+}
+
+function tokenBeforeHtml(p, token) {
+ p._insertFakeRootElement();
+ p.insertionMode = BEFORE_HEAD_MODE;
+ p._processToken(token);
+}
+
+
+//12.2.5.4.3 The "before head" insertion mode
+//------------------------------------------------------------------
+function startTagBeforeHead(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HTML)
+ startTagInBody(p, token);
+
+ else if (tn === $.HEAD) {
+ p._insertElement(token, NS.HTML);
+ p.headElement = p.openElements.current;
+ p.insertionMode = IN_HEAD_MODE;
+ }
+
+ else
+ tokenBeforeHead(p, token);
+}
+
+function endTagBeforeHead(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HEAD || tn === $.BODY || tn === $.HTML || tn === $.BR)
+ tokenBeforeHead(p, token);
+}
+
+function tokenBeforeHead(p, token) {
+ p._insertFakeElement($.HEAD);
+ p.headElement = p.openElements.current;
+ p.insertionMode = IN_HEAD_MODE;
+ p._processToken(token);
+}
+
+
+//12.2.5.4.4 The "in head" insertion mode
+//------------------------------------------------------------------
+function startTagInHead(p, token) {
+ var tn = token.tagName;
+
+ if (tn === $.HTML)
+ startTagInBody(p, token);
+
+ else if (tn === $.BASE || tn === $.BASEFONT || tn === $.BGSOUND || tn === $.LINK || tn === $.META)
+ p._appendElement(token, NS.HTML);
+
+ else if (tn === $.TITLE)
+ p._switchToTextParsing(token, Tokenizer.MODE.RCDATA);
+
+ //NOTE: here we assume that we always act as an interactive user agent with enabled scripting, so we parse
+ //