[WIP] feat: html support (#4753)

* feat: html support

* fix: support empty lines between children

* refactor: isScriptTagNode util

* refactor: rename `glimmer` and `handlebars` tests

* fix don't add newline after `directive` node

* fix: support `pre` tag

* fix: don't trim comments content

* fix: `script` and `style` tags output

* feat: indent `head` and `body` inside `html`

* fix: better handle quotes around attribute value

* feat: better handle embed

* tests: svg into html

* fix: better handle boolean and empty attributes

* chore(deps): update `parse5` to latest version

* fix: better handle empty attribute

* tests: fix

* fix: extra newline in multiline node

* fix: print `pre` and `textarea` in right way

* tests: xhtml doctype

* fix: use `>` instead `/>`

* tests: case

* refactor: remove `toLowerCase()`

* feat: support `prettier-ignore`

* tests: empty `script` and `style` tags

* fix: clean

* tests: refactor and more
master
Evilebot Tnawi 2018-09-13 16:06:49 +03:00 committed by Suchipi
parent 59720392c3
commit 8b0bdf52be
88 changed files with 2846 additions and 191 deletions

View File

@ -47,7 +47,8 @@
"minimatch": "3.0.4",
"minimist": "1.2.0",
"normalize-path": "3.0.0",
"parse5": "3.0.3",
"parse5": "5.0.0",
"parse5-htmlparser2-tree-adapter": "5.0.0",
"postcss-less": "1.1.5",
"postcss-media-query-parser": "0.2.3",
"postcss-scss": "1.0.6",

View File

@ -1,7 +1,7 @@
"use strict";
module.exports = function(ast, newNode) {
delete newNode.__location;
delete newNode.sourceCodeLocation;
if (ast.type === "text") {
return null;

View File

@ -21,7 +21,7 @@ function embed(path, print, textToDoc, options) {
) {
const parser = options.parser === "flow" ? "flow" : "babylon";
const doc = textToDoc(getText(options, node), { parser });
return concat([hardline, doc]);
return concat([hardline, stripTrailingHardline(doc)]);
}
// Inline TypeScript
@ -35,7 +35,7 @@ function embed(path, print, textToDoc, options) {
{ parser: "typescript" },
options
);
return concat([hardline, doc]);
return concat([hardline, stripTrailingHardline(doc)]);
}
// Inline Styles
@ -49,7 +49,7 @@ function embed(path, print, textToDoc, options) {
case "attribute": {
/*
* Vue binding sytax: JS expressions
* Vue binding syntax: JS expressions
* :class="{ 'some-key': value }"
* v-bind:id="'list-' + id"
* v-if="foo && !bar"

View File

@ -3,12 +3,15 @@
function parse(text /*, parsers, opts*/) {
// Inline the require to avoid loading all the JS if we don't use it
const parse5 = require("parse5");
const htmlparser2TreeAdapter = require("parse5-htmlparser2-tree-adapter");
try {
const isFragment = !/^\s*<(!doctype|html|head|body|!--)/i.test(text);
const ast = (isFragment ? parse5.parseFragment : parse5.parse)(text, {
treeAdapter: parse5.treeAdapters.htmlparser2,
locationInfo: true
treeAdapter: htmlparser2TreeAdapter,
sourceCodeLocationInfo: true
});
return normalize(extendAst(ast));
} catch (error) {
throw error;
@ -64,10 +67,10 @@ module.exports = {
parse,
astFormat: "htmlparser2",
locStart(node) {
return node.__location && node.__location.startOffset;
return node.sourceCodeLocation && node.sourceCodeLocation.startOffset;
},
locEnd(node) {
return node.__location && node.__location.endOffset;
return node.sourceCodeLocation && node.sourceCodeLocation.endOffset;
}
}
}

View File

@ -2,34 +2,21 @@
const embed = require("./embed");
const clean = require("./clean");
const { hasNewlineInRange, hasIgnoreComment } = require("../common/util");
const { getLast, hasIgnoreComment } = require("../common/util");
const { isNextLineEmpty } = require("../common/util-shared");
const {
concat,
join,
hardline,
line,
softline,
group,
indent
} = require("../doc").builders;
// http://w3c.github.io/html/single-page.html#void-elements
const voidTags = {
area: true,
base: true,
br: true,
col: true,
embed: true,
hr: true,
img: true,
input: true,
link: true,
meta: true,
param: true,
source: true,
track: true,
wbr: true
};
builders: {
concat,
line,
hardline,
softline,
group,
indent,
conditionalGroup,
dedentToRoot
},
utils: { willBreak, isLineNext, isEmpty }
} = require("../doc");
function genericPrint(path, options, print) {
const n = path.getValue();
@ -43,50 +30,170 @@ function genericPrint(path, options, print) {
switch (n.type) {
case "root": {
return printChildren(path, print);
return concat(printChildren(path, print, options));
}
case "directive": {
return concat(["<", n.data, ">", hardline]);
return concat([
"<",
n.data.replace('!DOCTYPE html ""', "!DOCTYPE html"),
">",
hardline
]);
}
case "text": {
const parentNode = path.getParentNode();
if (
parentNode &&
(isPreTagNode(parentNode) || isTextAreaTagNode(parentNode))
) {
return n.data;
}
return n.data.replace(/\s+/g, " ").trim();
}
case "script":
case "style":
case "tag": {
const selfClose = voidTags[n.name] ? ">" : " />";
const children = printChildren(path, print);
const isVoid = isVoidTagNode(n);
const openingPrinted = printOpeningPart(path, print);
const hasNewline = hasNewlineInRange(
options.originalText,
options.locStart(n),
options.locEnd(n)
);
// Print self closing tag
if (isVoid) {
return concat([openingPrinted]);
}
return group(
const closingPrinted = printClosingPart(path, print);
const hasChildren = n.children.length > 0;
// Print tags without children
if (!hasChildren) {
return concat([openingPrinted, closingPrinted]);
}
const children = printChildren(path, print, options);
// NOTE: If the next token is a U+000A LINE FEED (LF) character token, then ignore that token and move
// on to the next one. (Newlines at the start of textarea elements are ignored as an authoring convenience.)
if (isPreTagNode(n) || isTextAreaTagNode(n)) {
const originalTagContent = options.originalText.slice(
n.sourceCodeLocation.startTag.endOffset,
n.sourceCodeLocation.endTag.startOffset
);
const hasNewlineAfterTag = /^(\r\n|\r|\n)/.test(originalTagContent);
return dedentToRoot(
group(
concat([
openingPrinted,
hasNewlineAfterTag ? hardline : "",
concat(children),
closingPrinted
])
)
);
}
const isScriptTag = isScriptTagNode(n);
if (isScriptTag) {
return group(
concat([openingPrinted, concat(children), closingPrinted])
);
}
const containsTag =
n.children.filter(
node => ["script", "style", "tag"].indexOf(node.type) !== -1
).length > 0;
const containsMultipleAttributes = n.attributes.length > 1;
let forcedBreak =
willBreak(openingPrinted) || containsTag || containsMultipleAttributes;
// Trim trailing lines (or empty strings)
while (
children.length &&
(isLineNext(getLast(children)) || isEmpty(getLast(children)))
) {
children.pop();
}
// Trim leading lines (or empty strings)
while (
children.length &&
(isLineNext(children[0]) || isEmpty(children[0])) &&
(isLineNext(children[1]) || isEmpty(children[1]))
) {
children.shift();
children.shift();
}
// Detect whether we will force this element to output over multiple lines.
const multilineChildren = [];
children.forEach(child => {
multilineChildren.push(child);
if (willBreak(child)) {
forcedBreak = true;
}
});
const containsOnlyEmptyTextNodes = n.children.every(node => {
return node.type === "text" && /^\s+$/.test(node.data);
});
const printedMultilineChildren = concat([
!isScriptTag && !containsOnlyEmptyTextNodes ? hardline : "",
group(concat(multilineChildren), { shouldBreak: true })
]);
const multiLineElem = group(
concat([
hasNewline ? hardline : "",
"<",
n.name,
printAttributes(path, print),
n.children.length ? ">" : selfClose,
n.name.toLowerCase() === "html"
? concat([hardline, children])
: indent(children),
n.children.length ? concat([softline, "</", n.name, ">"]) : hardline
openingPrinted,
indent(printedMultilineChildren),
hardline,
closingPrinted
])
);
if (forcedBreak) {
return multiLineElem;
}
return conditionalGroup([
group(concat([openingPrinted, concat(children), closingPrinted])),
multiLineElem
]);
}
case "comment": {
return concat(["<!-- ", n.data.trim(), " -->"]);
return concat(["<!--", n.data, "-->"]);
}
case "attribute": {
if (!n.value) {
return n.key;
if (isBooleanAttributeNode(n)) {
return n.key;
}
const parentNode = path.getParentNode();
if (!parentNode || !parentNode.sourceCodeLocation) {
return n.key;
}
const attributeSourceCodeLocation =
parentNode.sourceCodeLocation.attrs[n.key];
const originalAttributeSourceCode = options.originalText.slice(
attributeSourceCodeLocation.startOffset,
attributeSourceCodeLocation.endOffset
);
const hasEqualSign = originalAttributeSourceCode.indexOf("=") !== -1;
return hasEqualSign ? concat([n.key, '=""']) : n.key;
}
return concat([n.key, '="', n.value, '"']);
return concat([n.key, '="', n.value.replace(/"/g, "&quot;"), '"']);
}
default:
@ -95,25 +202,152 @@ function genericPrint(path, options, print) {
}
}
function printAttributes(path, print) {
const node = path.getValue();
return concat([
node.attributes.length ? " " : "",
indent(join(line, path.map(print, "attributes")))
]);
function isBooleanAttributeNode(node) {
return (
node.type === "attribute" &&
[
"allowfullscreen",
"allowpaymentrequest",
"async",
"autofocus",
"autoplay",
"checked",
"controls",
"default",
"defer",
"disabled",
"formnovalidate",
"hidden",
"ismap",
"itemscope",
"loop",
"multiple",
"muted",
"nomodule",
"novalidate",
"open",
"readonly",
"required",
"reversed",
"selected",
"typemustmatch"
].indexOf(node.key) !== -1
);
}
function printChildren(path, print) {
const children = [];
path.each(childPath => {
// http://w3c.github.io/html/single-page.html#void-elements
function isVoidTagNode(node) {
return (
node.type === "tag" &&
[
"area",
"base",
"br",
"col",
"embed",
"hr",
"img",
"input",
"link",
"meta",
"param",
"source",
"track",
"wbr"
].indexOf(node.name) !== -1
);
}
function isPreTagNode(node) {
return node.type === "tag" && node.name === "pre";
}
function isTextAreaTagNode(node) {
return node.type === "tag" && node.name === "textarea";
}
function isScriptTagNode(node) {
return (
(node.type === "script" || node.type === "style") &&
["script", "style"].indexOf(node.name) !== -1
);
}
function printOpeningPart(path, print) {
const n = path.getValue();
const isVoid = isVoidTagNode(n);
// Don't break self-closing elements with no attributes
if (isVoid && !n.attributes.length) {
return concat(["<", n.name, ">"]);
}
// Don't break up opening elements with a single long text attribute
if (n.attributes && n.attributes.length === 1 && n.attributes[0].value) {
return group(
concat([
"<",
path.call(print, "name"),
" ",
concat(path.map(print, "attributes")),
">"
])
);
}
return group(
concat([
"<",
n.name,
concat([
indent(
concat(path.map(attr => concat([line, print(attr)]), "attributes"))
),
softline
]),
">"
])
);
}
function printClosingPart(path, print) {
return concat(["</", path.call(print, "name"), ">"]);
}
function printChildren(path, print, options) {
const parts = [];
path.map((childPath, i) => {
const parentNode = childPath.getParentNode();
const child = childPath.getValue();
if (child.type !== "text") {
children.push(hardline);
const printedChild = print(childPath);
if (
parentNode &&
parentNode.children[i - 2] &&
parentNode.children[i - 2].type === "comment" &&
parentNode.children[i - 2].data.trim() === "prettier-ignore"
) {
parts.push(
options.originalText.slice(
options.locStart(child),
options.locEnd(child)
)
);
} else {
parts.push(printedChild);
}
if (child.type !== "text" && child.type !== "directive") {
parts.push(hardline);
}
if (isNextLineEmpty(options.originalText, childPath.getValue(), options)) {
parts.push(hardline);
}
children.push(childPath.call(print));
}, "children");
return concat(children);
return parts;
}
module.exports = {

View File

@ -0,0 +1,216 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`attributes.html - parse5-verify 1`] = `
<input name=address maxlength=200>
<input name='address' maxlength='200'>
<input name="address" maxlength="200">
<div class="foo"></div>
<div class="foo" ></div>
<div class="foo bar"></div>
<div class="foo bar" id="header"></div>
<div class="foo bar" id="header" ></div>
<div data-prettier></div>
<div data-prettier="true"></div>
<meta property="og:description" content="The Mozilla Developer Network (MDN) provides
information about Open Web technologies including HTML, CSS, and APIs for both Web sites
and HTML5 Apps. It also documents Mozilla products, like Firefox OS.">
<div attribute>String</div>
<div attribute="">String</div>
<div attribute=''>String</div>
<div attribute >String</div>
<div attribute = "" >String</div>
<div attribute = '' >String</div>
<div attribute >String</div>
<div attribute = "" >String</div>
<div attribute = '' >String</div>
<div attribute="attribute = attribute"></div>
<div ATTRIBUTE>String</div>
<div ATTRIBUTE="">String</div>
<div ATTRIBUTE=''>String</div>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">
</article>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">...</article>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">
...
</article>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">
</article>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">
</article>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<input name="address" maxlength="200">
<input name="address" maxlength="200">
<input name="address" maxlength="200">
<div class="foo"></div>
<div class="foo"></div>
<div class="foo bar"></div>
<div class="foo bar" id="header"></div>
<div class="foo bar" id="header"></div>
<div data-prettier></div>
<div data-prettier="true"></div>
<meta
property="og:description"
content="The Mozilla Developer Network (MDN) provides
information about Open Web technologies including HTML, CSS, and APIs for both Web sites
and HTML5 Apps. It also documents Mozilla products, like Firefox OS."
>
<div attribute>String</div>
<div attribute="">String</div>
<div attribute="">String</div>
<div attribute>String</div>
<div attribute="">String</div>
<div attribute="">String</div>
<div attribute>String</div>
<div attribute="">String</div>
<div attribute="">String</div>
<div attribute="attribute = attribute"></div>
<div attribute>String</div>
<div attribute="">String</div>
<div attribute="">String</div>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars"
>
</article>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars"
>
...
</article>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars"
>
...
</article>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars"
>
</article>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars"
>
</article>
`;
exports[`boolean.html - parse5-verify 1`] = `
<button type="submit">This is valid.</button>
<button type="submit" disabled>This is valid.</button>
<button type="submit" disabled="">This is valid.</button>
<button type="submit" disabled="disabled">This is valid.</button>
<button type="submit" disabled=true>This is valid. This will be disabled.</button>
<button type="submit" disabled='true'>This is valid. This will be disabled.</button>
<button type="submit" disabled="true">This is valid. This will be disabled.</button>
<button type="submit" disabled=false>This is valid. This will be disabled.</button>
<button type="submit" disabled="false">This is valid. This will be disabled.</button>
<button type="submit" disabled='false'>This is valid. This will be disabled.</button>
<button type="submit" disabled=hahah>This is valid. This will be disabled.</button>
<button type="submit" disabled='hahah'>This is valid. This will be disabled.</button>
<button type="submit" disabled="hahah">This is valid. This will be disabled.</button>
<input type="checkbox" checked disabled name="cheese">
<input type="checkbox" checked="checked" disabled="disabled" name="cheese">
<input type='checkbox' checked="" disabled="" name=cheese >
<div lang=""></div>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<button type="submit">This is valid.</button>
<button type="submit" disabled>
This is valid.
</button>
<button type="submit" disabled>
This is valid.
</button>
<button type="submit" disabled="disabled">
This is valid.
</button>
<button type="submit" disabled="true">
This is valid. This will be disabled.
</button>
<button type="submit" disabled="true">
This is valid. This will be disabled.
</button>
<button type="submit" disabled="true">
This is valid. This will be disabled.
</button>
<button type="submit" disabled="false">
This is valid. This will be disabled.
</button>
<button type="submit" disabled="false">
This is valid. This will be disabled.
</button>
<button type="submit" disabled="false">
This is valid. This will be disabled.
</button>
<button type="submit" disabled="hahah">
This is valid. This will be disabled.
</button>
<button type="submit" disabled="hahah">
This is valid. This will be disabled.
</button>
<button type="submit" disabled="hahah">
This is valid. This will be disabled.
</button>
<input type="checkbox" checked disabled name="cheese">
<input type="checkbox" checked="checked" disabled="disabled" name="cheese">
<input type="checkbox" checked disabled name="cheese">
<div lang=""></div>
`;
exports[`dobule-quotes.html - parse5-verify 1`] = `
<img src="test.png" alt="John 'ShotGun' Nelson">
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<img src="test.png" alt="John 'ShotGun' Nelson">
`;
exports[`single-quotes.html - parse5-verify 1`] = `
<img src="test.png" alt='John "ShotGun" Nelson'>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<img src="test.png" alt="John &quot;ShotGun&quot; Nelson">
`;
exports[`without-quotes.html - parse5-verify 1`] = `
<p title=Title>String</p>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<p title="Title">String</p>
`;

View File

@ -0,0 +1,60 @@
<input name=address maxlength=200>
<input name='address' maxlength='200'>
<input name="address" maxlength="200">
<div class="foo"></div>
<div class="foo" ></div>
<div class="foo bar"></div>
<div class="foo bar" id="header"></div>
<div class="foo bar" id="header" ></div>
<div data-prettier></div>
<div data-prettier="true"></div>
<meta property="og:description" content="The Mozilla Developer Network (MDN) provides
information about Open Web technologies including HTML, CSS, and APIs for both Web sites
and HTML5 Apps. It also documents Mozilla products, like Firefox OS.">
<div attribute>String</div>
<div attribute="">String</div>
<div attribute=''>String</div>
<div attribute >String</div>
<div attribute = "" >String</div>
<div attribute = '' >String</div>
<div attribute >String</div>
<div attribute = "" >String</div>
<div attribute = '' >String</div>
<div attribute="attribute = attribute"></div>
<div ATTRIBUTE>String</div>
<div ATTRIBUTE="">String</div>
<div ATTRIBUTE=''>String</div>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">
</article>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">...</article>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">
...
</article>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">
</article>
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">
</article>

View File

@ -0,0 +1,17 @@
<button type="submit">This is valid.</button>
<button type="submit" disabled>This is valid.</button>
<button type="submit" disabled="">This is valid.</button>
<button type="submit" disabled="disabled">This is valid.</button>
<button type="submit" disabled=true>This is valid. This will be disabled.</button>
<button type="submit" disabled='true'>This is valid. This will be disabled.</button>
<button type="submit" disabled="true">This is valid. This will be disabled.</button>
<button type="submit" disabled=false>This is valid. This will be disabled.</button>
<button type="submit" disabled="false">This is valid. This will be disabled.</button>
<button type="submit" disabled='false'>This is valid. This will be disabled.</button>
<button type="submit" disabled=hahah>This is valid. This will be disabled.</button>
<button type="submit" disabled='hahah'>This is valid. This will be disabled.</button>
<button type="submit" disabled="hahah">This is valid. This will be disabled.</button>
<input type="checkbox" checked disabled name="cheese">
<input type="checkbox" checked="checked" disabled="disabled" name="cheese">
<input type='checkbox' checked="" disabled="" name=cheese >
<div lang=""></div>

View File

@ -0,0 +1 @@
<img src="test.png" alt="John 'ShotGun' Nelson">

View File

@ -0,0 +1 @@
run_spec(__dirname, ["parse5"]);

View File

@ -0,0 +1 @@
<img src="test.png" alt='John "ShotGun" Nelson'>

View File

@ -0,0 +1 @@
<p title=Title>String</p>

View File

@ -5,11 +5,9 @@ exports[`basic.html - parse5-verify 1`] = `
<i class.bind="icon"></i>
</template>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<template>
<i class.bind="icon" />
<i class.bind="icon"></i>
</template>
`;

View File

@ -1,5 +1,208 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`empty.html - parse5-verify 1`] = `
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`;
exports[`empty-doc.html - parse5-verify 1`] = `
<!doctype html>
<html>
<head></head>
<body></body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html>
<head></head>
<body></body>
</html>
`;
exports[`form.html - parse5-verify 1`] = `
<form>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<div class="form-group">
<label for="exampleSelect1">Example select</label>
<select class="form-control" id="exampleSelect1">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
<div class="form-group">
<label for="exampleSelect2">Example multiple select</label>
<select multiple class="form-control" id="exampleSelect2">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
<div class="form-group">
<label for="exampleTextarea">Example textarea</label>
<textarea class="form-control" id="exampleTextarea" rows="3"></textarea>
</div>
<div class="form-group">
<label for="exampleInputFile">File input</label>
<input type="file" class="form-control-file" id="exampleInputFile" aria-describedby="fileHelp">
<small id="fileHelp" class="form-text text-muted">This is some placeholder block-level help text for the above input. It's a bit lighter and easily wraps to a new line.</small>
</div>
<fieldset class="form-group">
<legend>Radio buttons</legend>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios1" value="option1" checked>
Option one is this and that&mdash;be sure to include why it's great
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios2" value="option2">
Option two can be something else and selecting it will deselect option one
</label>
</div>
<div class="form-check disabled">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios3" value="option3" disabled>
Option three is disabled
</label>
</div>
</fieldset>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" class="form-check-input">
Check me out
</label>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<form>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input
type="email"
class="form-control"
id="exampleInputEmail1"
aria-describedby="emailHelp"
placeholder="Enter email"
>
<small id="emailHelp" class="form-text text-muted">
We'll never share your email with anyone else.
</small>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input
type="password"
class="form-control"
id="exampleInputPassword1"
placeholder="Password"
>
</div>
<div class="form-group">
<label for="exampleSelect1">Example select</label>
<select class="form-control" id="exampleSelect1">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
<div class="form-group">
<label for="exampleSelect2">Example multiple select</label>
<select multiple class="form-control" id="exampleSelect2">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
<div class="form-group">
<label for="exampleTextarea">Example textarea</label>
<textarea class="form-control" id="exampleTextarea" rows="3"></textarea>
</div>
<div class="form-group">
<label for="exampleInputFile">File input</label>
<input
type="file"
class="form-control-file"
id="exampleInputFile"
aria-describedby="fileHelp"
>
<small id="fileHelp" class="form-text text-muted">
This is some placeholder block-level help text for the above input. It's a bit lighter and easily wraps to a new line.
</small>
</div>
<fieldset class="form-group">
<legend>Radio buttons</legend>
<div class="form-check">
<label class="form-check-label">
<input
type="radio"
class="form-check-input"
name="optionsRadios"
id="optionsRadios1"
value="option1"
checked
>
Option one is this and that—be sure to include why it's great
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input
type="radio"
class="form-check-input"
name="optionsRadios"
id="optionsRadios2"
value="option2"
>
Option two can be something else and selecting it will deselect option one
</label>
</div>
<div class="form-check disabled">
<label class="form-check-label">
<input
type="radio"
class="form-check-input"
name="optionsRadios"
id="optionsRadios3"
value="option3"
disabled
>
Option three is disabled
</label>
</div>
</fieldset>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" class="form-check-input">
Check me out
</label>
</div>
<button type="submit" class="btn btn-primary">
Submit
</button>
</form>
`;
exports[`hello-world.html - parse5-verify 1`] = `
<!DOCTYPE html>
<html lang="en">
@ -16,30 +219,20 @@ exports[`hello-world.html - parse5-verify 1`] = `
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible"
content="ie=edge">
<title>Document</title>
</head>
<body>
<!-- A comment -->
<h1>Hello World</h1>
</body>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!-- A comment -->
<h1>Hello World</h1>
</body>
</html>
`;
exports[`html-comments.html - parse5-verify 1`] = `
@ -51,22 +244,15 @@ exports[`html-comments.html - parse5-verify 1`] = `
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!-- htmlhint attr-lowercase: false -->
<html>
<head />
<body>
<a href="#">Anchor</a>
<div hidden
class="foo"
id="bar" />
</body>
<head></head>
<body>
<a href="#">Anchor</a>
<div hidden class="foo" id="bar"></div>
</body>
</html>
`;
exports[`html-fragment.html - parse5-verify 1`] = `
@ -74,35 +260,131 @@ exports[`html-fragment.html - parse5-verify 1`] = `
<textarea>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<a href="#">Link</a>
<textarea />
<textarea></textarea>
`;
exports[`html5-boilerplate.html - parse5-verify 1`] = `
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="manifest" href="site.webmanifest">
<link rel="apple-touch-icon" href="icon.png">
<!-- Place favicon.ico in the root directory -->
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<!--[if lte IE 9]>
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="https://browsehappy.com/">upgrade your browser</a> to improve your experience and security.</p>
<![endif]-->
<!-- Add your site or application content here -->
<p>Hello world! This is HTML5 Boilerplate.</p>
<script src="js/vendor/modernizr-3.6.0.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-3.3.1.min.js"><\\/script>')</script>
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>
<!-- Google Analytics: change UA-XXXXX-Y to be your site's ID. -->
<script>
window.ga = function () { ga.q.push(arguments) }; ga.q = []; ga.l = +new Date;
ga('create', 'UA-XXXXX-Y', 'auto'); ga('send', 'pageview')
</script>
<script src="https://www.google-analytics.com/analytics.js" async defer></script>
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title></title>
<meta name="description" content="">
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
>
<link rel="manifest" href="site.webmanifest">
<link rel="apple-touch-icon" href="icon.png">
<!-- Place favicon.ico in the root directory -->
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<!--[if lte IE 9]>
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="https://browsehappy.com/">upgrade your browser</a> to improve your experience and security.</p>
<![endif]-->
<!-- Add your site or application content here -->
<p>Hello world! This is HTML5 Boilerplate.</p>
<script src="js/vendor/modernizr-3.6.0.min.js"></script>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"
></script>
<script>
window.jQuery ||
document.write('<script src="js/vendor/jquery-3.3.1.min.js"></script>');
</script>
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>
<!-- Google Analytics: change UA-XXXXX-Y to be your site's ID. -->
<script>
window.ga = function() {
ga.q.push(arguments);
};
ga.q = [];
ga.l = +new Date();
ga("create", "UA-XXXXX-Y", "auto");
ga("send", "pageview");
</script>
<script
src="https://www.google-analytics.com/analytics.js"
async
defer
></script>
</body>
</html>
`;
exports[`more-html.html - parse5-verify 1`] = `
<html>
<head></head>
<body>
<a href="#">Anchor</a>
<div hidden class="foo" id=bar></div>
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<html>
<head />
<body>
<a href="#">Anchor</a>
<div hidden
class="foo"
id="bar" />
</body>
<head></head>
<body>
<a href="#">Anchor</a>
<div hidden class="foo" id="bar"></div>
</body>
</html>
`;
exports[`void-elements.html - parse5-verify 1`] = `
@ -114,20 +396,12 @@ exports[`void-elements.html - parse5-verify 1`] = `
<body></body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet"
href="code-guide.css">
</head>
<body>
</body>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="code-guide.css">
</head>
<body></body>
</html>
`;

View File

@ -0,0 +1,5 @@
<!doctype html>
<html>
<head></head>
<body></body>
</html>

View File

View File

@ -0,0 +1,68 @@
<form>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<div class="form-group">
<label for="exampleSelect1">Example select</label>
<select class="form-control" id="exampleSelect1">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
<div class="form-group">
<label for="exampleSelect2">Example multiple select</label>
<select multiple class="form-control" id="exampleSelect2">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
<div class="form-group">
<label for="exampleTextarea">Example textarea</label>
<textarea class="form-control" id="exampleTextarea" rows="3"></textarea>
</div>
<div class="form-group">
<label for="exampleInputFile">File input</label>
<input type="file" class="form-control-file" id="exampleInputFile" aria-describedby="fileHelp">
<small id="fileHelp" class="form-text text-muted">This is some placeholder block-level help text for the above input. It's a bit lighter and easily wraps to a new line.</small>
</div>
<fieldset class="form-group">
<legend>Radio buttons</legend>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios1" value="option1" checked>
Option one is this and that&mdash;be sure to include why it's great
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios2" value="option2">
Option two can be something else and selecting it will deselect option one
</label>
</div>
<div class="form-check disabled">
<label class="form-check-label">
<input type="radio" class="form-check-input" name="optionsRadios" id="optionsRadios3" value="option3" disabled>
Option three is disabled
</label>
</div>
</fieldset>
<div class="form-check">
<label class="form-check-label">
<input type="checkbox" class="form-check-input">
Check me out
</label>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>

View File

@ -0,0 +1,40 @@
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="manifest" href="site.webmanifest">
<link rel="apple-touch-icon" href="icon.png">
<!-- Place favicon.ico in the root directory -->
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<!--[if lte IE 9]>
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="https://browsehappy.com/">upgrade your browser</a> to improve your experience and security.</p>
<![endif]-->
<!-- Add your site or application content here -->
<p>Hello world! This is HTML5 Boilerplate.</p>
<script src="js/vendor/modernizr-3.6.0.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-3.3.1.min.js"><\/script>')</script>
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>
<!-- Google Analytics: change UA-XXXXX-Y to be your site's ID. -->
<script>
window.ga = function () { ga.q.push(arguments) }; ga.q = []; ga.l = +new Date;
ga('create', 'UA-XXXXX-Y', 'auto'); ga('send', 'pageview')
</script>
<script src="https://www.google-analytics.com/analytics.js" async defer></script>
</body>
</html>

View File

@ -1,4 +1,5 @@
<html>
<head></head>
<body>
<a href="#">Anchor</a>
<div hidden class="foo" id=bar></div>

View File

@ -0,0 +1,50 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`case.html - parse5-verify 1`] = `
<!DOCTYPE html>
<HTML CLASS="no-js mY-ClAsS">
<HEAD>
<META CHARSET="utf-8">
<TITLE>My tITlE</TITLE>
<META NAME="description" content="My CoNtEnT">
</HEAD>
<body>
<P>Hello world!<BR> This is HTML5 Boilerplate.</P>
<SCRIPT>
window.ga = function () { ga.q.push(arguments) }; ga.q = []; ga.l = +new Date;
ga('create', 'UA-XXXXX-Y', 'auto'); ga('send', 'pageview')
</SCRIPT>
<SCRIPT src="https://www.google-analytics.com/analytics.js" ASYNC DEFER></SCRIPT>
</body>
</HTML>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html class="no-js mY-ClAsS">
<head>
<meta charset="utf-8">
<title>My tITlE</title>
<meta name="description" content="My CoNtEnT">
</head>
<body>
<p>
Hello world!<br>
This is HTML5 Boilerplate.
</p>
<script>
window.ga = function() {
ga.q.push(arguments);
};
ga.q = [];
ga.l = +new Date();
ga("create", "UA-XXXXX-Y", "auto");
ga("send", "pageview");
</script>
<script
src="https://www.google-analytics.com/analytics.js"
async
defer
></script>
</body>
</html>
`;

16
tests/html_case/case.html Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<HTML CLASS="no-js mY-ClAsS">
<HEAD>
<META CHARSET="utf-8">
<TITLE>My tITlE</TITLE>
<META NAME="description" content="My CoNtEnT">
</HEAD>
<body>
<P>Hello world!<BR> This is HTML5 Boilerplate.</P>
<SCRIPT>
window.ga = function () { ga.q.push(arguments) }; ga.q = []; ga.l = +new Date;
ga('create', 'UA-XXXXX-Y', 'auto'); ga('send', 'pageview')
</SCRIPT>
<SCRIPT src="https://www.google-analytics.com/analytics.js" ASYNC DEFER></SCRIPT>
</body>
</HTML>

View File

@ -0,0 +1 @@
run_spec(__dirname, ["parse5"]);

View File

@ -0,0 +1,99 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`conditional.html - parse5-verify 1`] = `
<!DOCTYPE html>
<html>
<body>
<!--[if IE 5]>This is IE 5<br><![endif]-->
<!--[if IE 6]>This is IE 6<br><![endif]-->
<!--[if IE 7]>This is IE 7<br><![endif]-->
<!--[if IE 8]>This is IE 8<br><![endif]-->
<!--[if IE 9]>This is IE 9<br><![endif]-->
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html>
<head></head>
<body>
<!--[if IE 5]>This is IE 5<br><![endif]-->
<!--[if IE 6]>This is IE 6<br><![endif]-->
<!--[if IE 7]>This is IE 7<br><![endif]-->
<!--[if IE 8]>This is IE 8<br><![endif]-->
<!--[if IE 9]>This is IE 9<br><![endif]-->
</body>
</html>
`;
exports[`for_debugging.html - parse5-verify 1`] = `
<!DOCTYPE html>
<html>
<body>
<!-- Do not display this at the moment
<img border="0" src="pic_trulli.jpg" alt="Trulli">
-->
<!-- Do not display this at the moment
<img border="0" src="pic_trulli.jpg" alt="Trulli">
-->
<!-- Do not display this at the moment
<img border="0" src="pic_trulli.jpg" alt="Trulli">
-->
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html>
<head></head>
<body>
<!-- Do not display this at the moment
<img border="0" src="pic_trulli.jpg" alt="Trulli">
-->
<!-- Do not display this at the moment
<img border="0" src="pic_trulli.jpg" alt="Trulli">
-->
<!-- Do not display this at the moment
<img border="0" src="pic_trulli.jpg" alt="Trulli">
-->
</body>
</html>
`;
exports[`hidden.html - parse5-verify 1`] = `
<!DOCTYPE html>
<html>
<body>
<!--This is a comment-->
<!-- This is a comment -->
<!-- This is a comment -->
<!-- This is a comment -->
<p>This is a paragraph.</p>
<!-- Comments are not displayed in the browser -->
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html>
<head></head>
<body>
<!--This is a comment-->
<!-- This is a comment -->
<!-- This is a comment -->
<!-- This is a comment -->
<p>This is a paragraph.</p>
<!-- Comments are not displayed in the browser -->
</body>
</html>
`;

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<body>
<!--[if IE 5]>This is IE 5<br><![endif]-->
<!--[if IE 6]>This is IE 6<br><![endif]-->
<!--[if IE 7]>This is IE 7<br><![endif]-->
<!--[if IE 8]>This is IE 8<br><![endif]-->
<!--[if IE 9]>This is IE 9<br><![endif]-->
</body>
</html>

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<body>
<!-- Do not display this at the moment
<img border="0" src="pic_trulli.jpg" alt="Trulli">
-->
<!-- Do not display this at the moment
<img border="0" src="pic_trulli.jpg" alt="Trulli">
-->
<!-- Do not display this at the moment
<img border="0" src="pic_trulli.jpg" alt="Trulli">
-->
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<body>
<!--This is a comment-->
<!-- This is a comment -->
<!-- This is a comment -->
<!-- This is a comment -->
<p>This is a paragraph.</p>
<!-- Comments are not displayed in the browser -->
</body>
</html>

View File

@ -0,0 +1 @@
run_spec(__dirname, ["parse5"]);

View File

@ -0,0 +1,170 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`empty.html - parse5-verify 1`] = `
<style></style>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<style></style>
`;
exports[`less.html - parse5-verify 1`] = `
<style type="text/less">
@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;
#header {
color: @light-blue;
}
</style>
<style lang="less">
@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;
#header {
color: @light-blue;
}
</style>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<style type="text/less">
@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;
#header {
color: @light-blue;
}</style>
<style lang="less">
@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;
#header {
color: @light-blue;
}</style>
`;
exports[`postcss.html - parse5-verify 1`] = `
<style type="text/css">
body { background: navy; color: yellow; }
</style>
<style lang="postcss">
body { background: navy; color: yellow; }
</style>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<style type="text/css">
body {
background: navy;
color: yellow;
}</style>
<style lang="postcss">
body {
background: navy;
color: yellow;
}</style>
`;
exports[`scss.html - parse5-verify 1`] = `
<style type="text/x-scss">
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
</style>
<style lang="scss">
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
</style>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<style type="text/x-scss">
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}</style>
<style lang="scss">
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}</style>
`;
exports[`simple.html - parse5-verify 1`] = `
<!DOCTYPE html>
<html>
<head>
<title>Sample styled page</title>
<style>a { color: red; }</style>
<style>
body { background: navy; color: yellow; }
</style>
</head>
<body>
<h1>Sample styled page</h1>
<p>This page is just a demo.</p>
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html>
<head>
<title>Sample styled page</title>
<style>
a {
color: red;
}</style>
<style>
body {
background: navy;
color: yellow;
}</style>
</head>
<body>
<h1>Sample styled page</h1>
<p>This page is just a demo.</p>
</body>
</html>
`;
exports[`single-style.html - parse5-verify 1`] = `
<style>a { color: red; }</style>
<style>
h1 {
font-size: 120%;
font-family: Verdana, Arial, Helvetica, sans-serif;
color: #333366;
}
</style>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<style>
a {
color: red;
}</style>
<style>
h1 {
font-size: 120%;
font-family: Verdana, Arial, Helvetica, sans-serif;
color: #333366;
}</style>
`;

View File

@ -0,0 +1 @@
<style></style>

View File

@ -0,0 +1 @@
run_spec(__dirname, ["parse5"]);

17
tests/html_css/less.html Normal file
View File

@ -0,0 +1,17 @@
<style type="text/less">
@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;
#header {
color: @light-blue;
}
</style>
<style lang="less">
@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;
#header {
color: @light-blue;
}
</style>

View File

@ -0,0 +1,7 @@
<style type="text/css">
body { background: navy; color: yellow; }
</style>
<style lang="postcss">
body { background: navy; color: yellow; }
</style>

19
tests/html_css/scss.html Normal file
View File

@ -0,0 +1,19 @@
<style type="text/x-scss">
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
</style>
<style lang="scss">
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
</style>

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Sample styled page</title>
<style>a { color: red; }</style>
<style>
body { background: navy; color: yellow; }
</style>
</head>
<body>
<h1>Sample styled page</h1>
<p>This page is just a demo.</p>
</body>
</html>

View File

@ -0,0 +1,8 @@
<style>a { color: red; }</style>
<style>
h1 {
font-size: 120%;
font-family: Verdana, Arial, Helvetica, sans-serif;
color: #333366;
}
</style>

View File

@ -0,0 +1,163 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`html4.01_frameset.html - parse5-verify 1`] = `
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
<title>An HTML standard template</title>
<meta charset="utf-8" />
</head>
<body>
<p>… Your HTML content here …</p>
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
<title>An HTML standard template</title>
<meta charset="utf-8">
</head>
<body>
<p>… Your HTML content here …</p>
</body>
</html>
`;
exports[`html4.01_strict.html - parse5-verify 1`] = `
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>An HTML standard template</title>
<meta charset="utf-8" />
</head>
<body>
<p>… Your HTML content here …</p>
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>An HTML standard template</title>
<meta charset="utf-8">
</head>
<body>
<p>… Your HTML content here …</p>
</body>
</html>
`;
exports[`html4.01_transitional.html - parse5-verify 1`] = `
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>An HTML standard template</title>
<meta charset="utf-8" />
</head>
<body>
<p>… Your HTML content here …</p>
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>An HTML standard template</title>
<meta charset="utf-8">
</head>
<body>
<p>… Your HTML content here …</p>
</body>
</html>
`;
exports[`html5.html - parse5-verify 1`] = `
<!DOCTYPE html>
<html>
<head>
<title>An HTML standard template</title>
<meta charset="utf-8" />
</head>
<body>
<p>… Your HTML content here …</p>
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html>
<head>
<title>An HTML standard template</title>
<meta charset="utf-8">
</head>
<body>
<p>… Your HTML content here …</p>
</body>
</html>
`;
exports[`xhtml1.1.html - parse5-verify 1`] = `
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<title>XHTML markup</title>
</head>
<body style="background-color:#ffffcc; color:#008800">
<br />
<h2 align="center">Sample XHTML page</h2>
<br />
<div align="center">
<img src="../images/bee3.jpg" width="400" height="250" alt="Beep" vspace="20" />
</div>
<p align="center" style="font-size:17px">Bar Foo,<br />
Foo,<br />
Bar<br />
Foo</p>
<p align="center"><em>String</em></p>
<br />
<hr />
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>XHTML markup</title>
</head>
<body style="background-color:#ffffcc; color:#008800">
<br>
<h2 align="center">Sample XHTML page</h2>
<br>
<div align="center">
<img
src="../images/bee3.jpg"
width="400"
height="250"
alt="Beep"
vspace="20"
>
</div>
<p align="center" style="font-size:17px">
Bar Foo,<br>
Foo,<br>
Bar<br>
Foo
</p>
<p align="center">
<em>String</em>
</p>
<br>
<hr>
</body>
</html>
`;

View File

@ -0,0 +1,11 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head>
<title>An HTML standard template</title>
<meta charset="utf-8" />
</head>
<body>
<p>… Your HTML content here …</p>
</body>
</html>

View File

@ -0,0 +1,11 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>An HTML standard template</title>
<meta charset="utf-8" />
</head>
<body>
<p>… Your HTML content here …</p>
</body>
</html>

View File

@ -0,0 +1,11 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>An HTML standard template</title>
<meta charset="utf-8" />
</head>
<body>
<p>… Your HTML content here …</p>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>An HTML standard template</title>
<meta charset="utf-8" />
</head>
<body>
<p>… Your HTML content here …</p>
</body>
</html>

View File

@ -0,0 +1 @@
run_spec(__dirname, ["parse5"]);

View File

@ -0,0 +1,22 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<title>XHTML markup</title>
</head>
<body style="background-color:#ffffcc; color:#008800">
<br />
<h2 align="center">Sample XHTML page</h2>
<br />
<div align="center">
<img src="../images/bee3.jpg" width="400" height="250" alt="Beep" vspace="20" />
</div>
<p align="center" style="font-size:17px">Bar Foo,<br />
Foo,<br />
Bar<br />
Foo</p>
<p align="center"><em>String</em></p>
<br />
<hr />
</body>
</html>

View File

@ -0,0 +1,207 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`empty.html - parse5-verify 1`] = `
<script></script>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<script></script>
`;
exports[`js.html - parse5-verify 1`] = `
<script type="text/javascript">
var message = "Alert!";
alert(message);
</script>
<script type="application/javascript">
var message = "Alert!";
alert(message);
</script>
<script>
var message = "Alert!";
alert(message);
</script>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<script type="text/javascript">
var message = "Alert!";
alert(message);
</script>
<script type="application/javascript">
var message = "Alert!";
alert(message);
</script>
<script>
var message = "Alert!";
alert(message);
</script>
`;
exports[`simple.html - parse5-verify 1`] = `
<!DOCTYPE html>
<html>
<head>
<title>Sample styled page</title>
<script>alert('test');</script>
<script>
var message = "Alert!";
alert(message);
</script>
</head>
<body>
<h1>Sample styled page</h1>
<p>This page is just a demo.</p>
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html>
<head>
<title>Sample styled page</title>
<script>
alert("test");
</script>
<script>
var message = "Alert!";
alert(message);
</script>
</head>
<body>
<h1>Sample styled page</h1>
<p>This page is just a demo.</p>
</body>
</html>
`;
exports[`single-script.html - parse5-verify 1`] = `
<script>alert('test');</script>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<script>
alert("test");
</script>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
`;
exports[`typescript.html - parse5-verify 1`] = `
<script type="application/x-typescript">
class Student {
fullName: string;
constructor(public firstName: string, public middleInitial: string, public lastName: string) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}
interface Person {
firstName: string;
lastName: string;
}
function greeter(person : Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
let user = new Student("Jane", "M.", "User");
document.body.innerHTML = greeter(user);
</script>
<script lang="ts">
class Student {
fullName: string;
constructor(public firstName: string, public middleInitial: string, public lastName: string) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}
interface Person {
firstName: string;
lastName: string;
}
function greeter(person : Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
let user = new Student("Jane", "M.", "User");
document.body.innerHTML = greeter(user);
</script>
<script lang="tsx">
class CommentBox extends React.Component<{ url: string, pollInterval: number}, CommentData> {
constructor(){
super()
this.state = { data: [] };
}
fetchComments() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: (data) => this.setState({ data: data }),
error: (xhr, status, err) => console.error(status, err)
})
}
componentDidMount() {
this.fetchComments();
setInterval(this.fetchComments.bind(this), this.props.pollInterval);
}
render() {
let handleCommentSubmit = (comment: { author: string, text: string }) => {
console.warn('comment submitted!', comment);
const updated = this.state.data.slice(0);
updated.push(comment);
this.setState({ data: updated });
}
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data}/>
<CommentForm onCommentSubmit={handleCommentSubmit} />
</div>
);
}
}
</script>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<script type="application/x-typescript">class Student { fullName: string; constructor(public firstName: string, public middleInitial: string, public lastName: string) { this.fullName = firstName + " " + middleInitial + " " + lastName; } } interface Person { firstName: string; lastName: string; } function greeter(person : Person) { return "Hello, " + person.firstName + " " + person.lastName; } let user = new Student("Jane", "M.", "User"); document.body.innerHTML = greeter(user);</script>
<script lang="ts">
class Student {
fullName: string;
constructor(
public firstName: string,
public middleInitial: string,
public lastName: string
) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}
interface Person {
firstName: string;
lastName: string;
}
function greeter(person: Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
let user = new Student("Jane", "M.", "User");
document.body.innerHTML = greeter(user);
</script>
<script lang="tsx">class CommentBox extends React.Component<{ url: string, pollInterval: number}, CommentData> { constructor(){ super() this.state = { data: [] }; } fetchComments() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: (data) => this.setState({ data: data }), error: (xhr, status, err) => console.error(status, err) }) } componentDidMount() { this.fetchComments(); setInterval(this.fetchComments.bind(this), this.props.pollInterval); } render() { let handleCommentSubmit = (comment: { author: string, text: string }) => { console.warn('comment submitted!', comment); const updated = this.state.data.slice(0); updated.push(comment); this.setState({ data: updated }); } return ( <div className="commentBox"> <h1>Comments</h1> <CommentList data={this.state.data}/> <CommentForm onCommentSubmit={handleCommentSubmit} /> </div> ); } }</script>
`;

1
tests/html_js/empty.html Normal file
View File

@ -0,0 +1 @@
<script></script>

15
tests/html_js/js.html Normal file
View File

@ -0,0 +1,15 @@
<script type="text/javascript">
var message = "Alert!";
alert(message);
</script>
<script type="application/javascript">
var message = "Alert!";
alert(message);
</script>
<script>
var message = "Alert!";
alert(message);
</script>

View File

@ -0,0 +1 @@
run_spec(__dirname, ["parse5"]);

16
tests/html_js/simple.html Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<title>Sample styled page</title>
<script>alert('test');</script>
<script>
var message = "Alert!";
alert(message);
</script>
</head>
<body>
<h1>Sample styled page</h1>
<p>This page is just a demo.</p>
</body>
</html>

View File

@ -0,0 +1,4 @@
<script>alert('test');</script>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>

View File

@ -0,0 +1,78 @@
<script type="application/x-typescript">
class Student {
fullName: string;
constructor(public firstName: string, public middleInitial: string, public lastName: string) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}
interface Person {
firstName: string;
lastName: string;
}
function greeter(person : Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
let user = new Student("Jane", "M.", "User");
document.body.innerHTML = greeter(user);
</script>
<script lang="ts">
class Student {
fullName: string;
constructor(public firstName: string, public middleInitial: string, public lastName: string) {
this.fullName = firstName + " " + middleInitial + " " + lastName;
}
}
interface Person {
firstName: string;
lastName: string;
}
function greeter(person : Person) {
return "Hello, " + person.firstName + " " + person.lastName;
}
let user = new Student("Jane", "M.", "User");
document.body.innerHTML = greeter(user);
</script>
<script lang="tsx">
class CommentBox extends React.Component<{ url: string, pollInterval: number}, CommentData> {
constructor(){
super()
this.state = { data: [] };
}
fetchComments() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: (data) => this.setState({ data: data }),
error: (xhr, status, err) => console.error(status, err)
})
}
componentDidMount() {
this.fetchComments();
setInterval(this.fetchComments.bind(this), this.props.pollInterval);
}
render() {
let handleCommentSubmit = (comment: { author: string, text: string }) => {
console.warn('comment submitted!', comment);
const updated = this.state.data.slice(0);
updated.push(comment);
this.setState({ data: updated });
}
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data}/>
<CommentForm onCommentSubmit={handleCommentSubmit} />
</div>
);
}
}
</script>

View File

@ -0,0 +1,92 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`document.html - parse5-verify 1`] = `
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Title</title>
</head>
<body>
<!-- prettier-ignore -->
<p>
Test Test Test
</p>
<!-- prettier-ignore -->
<p attribute = "value">
Test Test Test
</p>
<!-- prettier-ignore -->
<ul
><li> First </li
><li>Second<i>1</i><div><div>String</div></div></li
></ul>
<!-- prettier-ignore -->
<div>
</div>
<!-- prettier-ignore -->
<ul><!--
--><li> First </li><!--
--><li> Second </li><!--
--></ul>
<!-- prettier-ignore -->
<br />
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Title</title>
</head>
<body>
<!-- prettier-ignore -->
<p>
Test Test Test
</p>
<!-- prettier-ignore -->
<p attribute = "value">
Test Test Test
</p>
<!-- prettier-ignore -->
<ul
><li> First </li
><li>Second<i>1</i><div><div>String</div></div></li
></ul>
<!-- prettier-ignore -->
<div>
</div>
<!-- prettier-ignore -->
<ul><!--
--><li> First </li><!--
--><li> Second </li><!--
--></ul>
<!-- prettier-ignore -->
<br />
</body>
</html>
`;

View File

@ -0,0 +1,43 @@
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Title</title>
</head>
<body>
<!-- prettier-ignore -->
<p>
Test Test Test
</p>
<!-- prettier-ignore -->
<p attribute = "value">
Test Test Test
</p>
<!-- prettier-ignore -->
<ul
><li> First </li
><li>Second<i>1</i><div><div>String</div></div></li
></ul>
<!-- prettier-ignore -->
<div>
</div>
<!-- prettier-ignore -->
<ul><!--
--><li> First </li><!--
--><li> Second </li><!--
--></ul>
<!-- prettier-ignore -->
<br />
</body>
</html>

View File

@ -0,0 +1 @@
run_spec(__dirname, ["parse5"]);

View File

@ -0,0 +1,35 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`svg.html - parse5-verify 1`] = `
<!DOCTYPE html>
<html>
<head>
<title>SVG</title>
</head>
<body>
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>
</body>
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html>
<head>
<title>SVG</title>
</head>
<body>
<svg width="100" height="100">
<circle
cx="50"
cy="50"
r="40"
stroke="green"
stroke-width="4"
fill="yellow"
></circle>
</svg>
</body>
</html>
`;

View File

@ -0,0 +1 @@
run_spec(__dirname, ["parse5"]);

11
tests/html_svg/svg.html Normal file
View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>SVG</title>
</head>
<body>
<svg width="100" height="100">
<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>
</body>
</html>

View File

@ -0,0 +1,12 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`symbol_entitites.html - parse5-verify 1`] = `
<p>I will display &euro;</p>
<p>I will display &#8364;</p>
<p>I will display &#x20AC;</p>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<p>I will display €</p>
<p>I will display €</p>
<p>I will display €</p>
`;

View File

@ -0,0 +1 @@
run_spec(__dirname, ["parse5"]);

View File

@ -0,0 +1,3 @@
<p>I will display &euro;</p>
<p>I will display &#8364;</p>
<p>I will display &#x20AC;</p>

View File

@ -0,0 +1,404 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`pre.html - parse5-verify 1`] = `
<pre>
--------------------------------------------------------------------------------
* * *
** ** ***
** ** *
**** *** **** ******** ******** *** ****
* *** * **** **** * *** ******** ******** *** *** **** **** *
* **** ** **** * *** ** ** *** * *** ** ****
** ** ** * *** ** ** ** * *** **
** ** ** ** *** ** ** ** ** *** **
** ** ** ******** ** ** ** ******** **
** ** ** ******* ** ** ** ******* **
** ** ** ** ** ** ** ** **
******* *** **** * ** ** ** **** * ***
****** *** ******* ** ** *** * ******* ***
** ***** *** *****
**
**
**
--------------------------------------------------------------------------------
</pre>
<pre>
Text in a pre element
is displayed in a fixed-width
font, and it preserves
both spaces and
line breaks
</pre>
<pre> Foo Bar </pre>
<pre>
Foo Bar
</pre>
<pre>Foo Bar
</pre>
<pre>
Foo Bar</pre>
<figure role="img" aria-labelledby="cow-caption">
<pre>
___________________________
< I'm an expert in my field. >
---------------------------
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||
___________________________
</pre>
<figcaption id="cow-caption">
A cow saying, "I'm an expert in my field." The cow is illustrated using preformatted text characters.
</figcaption>
</figure>
<pre data-attr-1="foo" data-attr-2="foo" data-attr-3="foo" data-attr-4="foo" data-attr-5="foo" data-attr-6="foo">
Foo Bar
</pre>
<div>
<div>
<div>
<div>
<pre>
______
STRING
______
</pre>
</div>
</div>
</div>
</div>
<pre></pre>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<pre>
--------------------------------------------------------------------------------
* * *
** ** ***
** ** *
**** *** **** ******** ******** *** ****
* *** * **** **** * *** ******** ******** *** *** **** **** *
* **** ** **** * *** ** ** *** * *** ** ****
** ** ** * *** ** ** ** * *** **
** ** ** ** *** ** ** ** ** *** **
** ** ** ******** ** ** ** ******** **
** ** ** ******* ** ** ** ******* **
** ** ** ** ** ** ** ** **
******* *** **** * ** ** ** **** * ***
****** *** ******* ** ** *** * ******* ***
** ***** *** *****
**
**
**
--------------------------------------------------------------------------------
</pre>
<pre>
Text in a pre element
is displayed in a fixed-width
font, and it preserves
both spaces and
line breaks
</pre>
<pre> Foo Bar </pre>
<pre>
Foo Bar
</pre>
<pre>Foo Bar
</pre>
<pre>
Foo Bar</pre>
<figure role="img" aria-labelledby="cow-caption">
<pre>
___________________________
< I'm an expert in my field. >
---------------------------
\\ ^__^
\\ (oo)\\_______
(__)\\ )\\/\\
||----w |
|| ||
___________________________
</pre>
<figcaption id="cow-caption">
A cow saying, "I'm an expert in my field." The cow is illustrated using preformatted text characters.
</figcaption>
</figure>
<pre
data-attr-1="foo"
data-attr-2="foo"
data-attr-3="foo"
data-attr-4="foo"
data-attr-5="foo"
data-attr-6="foo"
>
Foo Bar
</pre>
<div>
<div>
<div>
<div>
<pre>
______
STRING
______
</pre>
</div>
</div>
</div>
</div>
<pre></pre>
`;
exports[`tags.html - parse5-verify 1`] = `
<br/>
<br />
<br />
<br
/>
<br attribute-a />
<br very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute />
<br attribute-a="value" />
<br
attribute-a="value"
/>
<br very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute="value" />
<br very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute="very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-value" />
<br attribute-a="value" attribute-b="value" attribute-c="value" attribute-d="value" attribute-e="value" attribute-f="value" />
<div>string</div>
<div>very very very very very very very very very very very very very very very very long string</div>
<div very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute>string</div>
<div very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute="value">string</div>
<div attribute="very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-value">string</div>
<div attribute="value">very very very very very very very very very very very very very very very very long string</div>
<div attribute="value" attributea="value" attributeb="value" attributec="value" attributed="value" attributef="value">string</div>
<div attribute="value" attributea="value" attributeb="value" attributec="value" attributed="value" attributef="value">very very very very very very very very very very very very very very very very long string</div>
<video width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.ogg" type="video/ogg">
Your browser does not support the video tag.
</video>
<div><div>string</div></div>
<div><div>string</div><div>string</div></div>
<div><div><div>string</div></div><div>string</div></div>
<div><div>string</div><div><div>string</div></div></div>
<div><div></div></div>
<div><div></div><div></div></div>
<div><div><div><div><div><div><div>string</div></div></div></div></div></div></div>
<div>
<div>string</div>
</div>
<div>
<div>string</div>
</div>
<div>
<div>string</div>
<div>string</div>
</div>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<br>
<br>
<br>
<br>
<br attribute-a>
<br
very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute
>
<br attribute-a="value">
<br attribute-a="value">
<br very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute="value">
<br very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute="very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-value">
<br
attribute-a="value"
attribute-b="value"
attribute-c="value"
attribute-d="value"
attribute-e="value"
attribute-f="value"
>
<div>string</div>
<div>
very very very very very very very very very very very very very very very very long string
</div>
<div
very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute
>
string
</div>
<div very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute="value">
string
</div>
<div attribute="very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-value">
string
</div>
<div attribute="value">
very very very very very very very very very very very very very very very very long string
</div>
<div
attribute="value"
attributea="value"
attributeb="value"
attributec="value"
attributed="value"
attributef="value"
>
string
</div>
<div
attribute="value"
attributea="value"
attributeb="value"
attributec="value"
attributed="value"
attributef="value"
>
very very very very very very very very very very very very very very very very long string
</div>
<video width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.ogg" type="video/ogg">
Your browser does not support the video tag.
</video>
<div>
<div>string</div>
</div>
<div>
<div>string</div>
<div>string</div>
</div>
<div>
<div>
<div>string</div>
</div>
<div>string</div>
</div>
<div>
<div>string</div>
<div>
<div>string</div>
</div>
</div>
<div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>string</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>string</div>
</div>
<div>
<div>string</div>
</div>
<div>
<div>string</div>
<div>string</div>
</div>
`;
exports[`textarea.html - parse5-verify 1`] = `
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<textarea rows="10" cols="45" name="text">
String
</textarea>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<textarea></textarea>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<textarea rows="10" cols="45" name="text">
String
</textarea>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<textarea></textarea>
`;
exports[`unsupported.html - parse5-verify 1`] = `
<center></center>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<center></center>
`;

View File

@ -0,0 +1 @@
run_spec(__dirname, ["parse5"]);

78
tests/html_tags/pre.html Normal file
View File

@ -0,0 +1,78 @@
<pre>
--------------------------------------------------------------------------------
* * *
** ** ***
** ** *
**** *** **** ******** ******** *** ****
* *** * **** **** * *** ******** ******** *** *** **** **** *
* **** ** **** * *** ** ** *** * *** ** ****
** ** ** * *** ** ** ** * *** **
** ** ** ** *** ** ** ** ** *** **
** ** ** ******** ** ** ** ******** **
** ** ** ******* ** ** ** ******* **
** ** ** ** ** ** ** ** **
******* *** **** * ** ** ** **** * ***
****** *** ******* ** ** *** * ******* ***
** ***** *** *****
**
**
**
--------------------------------------------------------------------------------
</pre>
<pre>
Text in a pre element
is displayed in a fixed-width
font, and it preserves
both spaces and
line breaks
</pre>
<pre> Foo Bar </pre>
<pre>
Foo Bar
</pre>
<pre>Foo Bar
</pre>
<pre>
Foo Bar</pre>
<figure role="img" aria-labelledby="cow-caption">
<pre>
___________________________
< I'm an expert in my field. >
---------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
___________________________
</pre>
<figcaption id="cow-caption">
A cow saying, "I'm an expert in my field." The cow is illustrated using preformatted text characters.
</figcaption>
</figure>
<pre data-attr-1="foo" data-attr-2="foo" data-attr-3="foo" data-attr-4="foo" data-attr-5="foo" data-attr-6="foo">
Foo Bar
</pre>
<div>
<div>
<div>
<div>
<pre>
______
STRING
______
</pre>
</div>
</div>
</div>
</div>
<pre></pre>

49
tests/html_tags/tags.html Normal file
View File

@ -0,0 +1,49 @@
<br/>
<br />
<br />
<br
/>
<br attribute-a />
<br very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute />
<br attribute-a="value" />
<br
attribute-a="value"
/>
<br very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute="value" />
<br very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute="very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-value" />
<br attribute-a="value" attribute-b="value" attribute-c="value" attribute-d="value" attribute-e="value" attribute-f="value" />
<div>string</div>
<div>very very very very very very very very very very very very very very very very long string</div>
<div very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute>string</div>
<div very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-attribute="value">string</div>
<div attribute="very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-very-long-value">string</div>
<div attribute="value">very very very very very very very very very very very very very very very very long string</div>
<div attribute="value" attributea="value" attributeb="value" attributec="value" attributed="value" attributef="value">string</div>
<div attribute="value" attributea="value" attributeb="value" attributec="value" attributed="value" attributef="value">very very very very very very very very very very very very very very very very long string</div>
<video width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.ogg" type="video/ogg">
Your browser does not support the video tag.
</video>
<div><div>string</div></div>
<div><div>string</div><div>string</div></div>
<div><div><div>string</div></div><div>string</div></div>
<div><div>string</div><div><div>string</div></div></div>
<div><div></div></div>
<div><div></div><div></div></div>
<div><div><div><div><div><div><div>string</div></div></div></div></div></div></div>
<div>
<div>string</div>
</div>
<div>
<div>string</div>
</div>
<div>
<div>string</div>
<div>string</div>
</div>

View File

@ -0,0 +1,28 @@
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<textarea rows="10" cols="45" name="text">
String
</textarea>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<textarea></textarea>

View File

@ -0,0 +1 @@
<center></center>

View File

@ -14,23 +14,15 @@ exports[`html-with-css-style.html - parse5-verify 1`] = `
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html lang="en">
<head>
<style>
<head>
<style>
blink {
display: none;
}
</style>
</head>
<body>
</body>
}</style>
</head>
<body></body>
</html>
`;

View File

@ -13,22 +13,14 @@ exports[`html-with-js-script.html - parse5-verify 1`] = `
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript">
<head>
<script type="text/javascript">
hello("world");
</script>
</head>
<body>
</body>
</script>
</head>
<body></body>
</html>
`;

View File

@ -22,26 +22,18 @@ exports[`html-with-ts-script.html - parse5-verify 1`] = `
</html>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<!DOCTYPE html>
<html lang="en">
<head>
<script lang="ts">
<head>
<script lang="ts">
type X = { [K in keyof Y]: Partial<K> };
class Foo<T> {
constructor(private foo: keyof Apple) {}
}
</script>
</head>
<body>
</body>
</script>
</head>
<body></body>
</html>
`;

View File

@ -573,10 +573,6 @@
dependencies:
commander "*"
"@types/node@*":
version "8.0.47"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.47.tgz#968e596f91acd59069054558a00708c445ca30c2"
"@types/semver@^5.4.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-5.5.0.tgz#146c2a29ee7d3bae4bf2fcb274636e264c813c45"
@ -4384,11 +4380,15 @@ parse-json@^4.0.0:
error-ex "^1.3.1"
json-parse-better-errors "^1.0.1"
parse5@3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
parse5-htmlparser2-tree-adapter@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-5.0.0.tgz#f941eced8061ecb1bc2db744c416a037abfe64d1"
dependencies:
"@types/node" "*"
parse5 "^5.0.0"
parse5@5.0.0, parse5@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.0.0.tgz#4d02710d44f3c3846197a11e205d4ef17842b81a"
parse5@4.0.0:
version "4.0.0"