feat(html): whitespace-sensitive formatting (#5168)
- whitespace-sensitive formatting - respect css `display: block`/`white-space: pre` (data from [`html-styles`](https://github.com/marionebl/html-styles)) - support magic comment (`<!-- display: block -->`) - add an option to specify whitespace sensitivity (`--html-whitespace-sensitivity <css|strict|ignore>`) - magic comments take precedence - (default) `css`: respect default css style (safe in the most cases) - `strict`: every node is considered whitespace sensitive (the safest) - `ignore`: every node is considered whitespace insensitive (dangerous, the original behavior) - inline inline-tags - support ie conditional comment (`<!--[if IE]><![endif]-->`) - indent the script/style content - no inconsistent output for 2+ attributes - force break tag if there're multiline attributesmaster
parent
3369be0ca2
commit
dd4687e7ef
|
@ -38,12 +38,14 @@
|
|||
"globby": "6.1.0",
|
||||
"graphql": "0.13.2",
|
||||
"html-element-attributes": "2.0.0",
|
||||
"html-styles": "1.0.0",
|
||||
"html-tag-names": "1.1.2",
|
||||
"htmlparser2": "3.9.2",
|
||||
"ignore": "3.3.7",
|
||||
"jest-docblock": "23.2.0",
|
||||
"json-stable-stringify": "1.0.1",
|
||||
"leven": "2.1.0",
|
||||
"lines-and-columns": "1.1.6",
|
||||
"linguist-languages": "6.2.1-dev.20180706",
|
||||
"lodash.uniqby": "4.7.0",
|
||||
"mem": "1.1.0",
|
||||
|
|
|
@ -5,12 +5,12 @@ module.exports = function(ast, newNode) {
|
|||
delete newNode.endIndex;
|
||||
delete newNode.attribs;
|
||||
|
||||
if (ast.type === "text") {
|
||||
if (ast.type === "text" || ast.type === "comment") {
|
||||
return null;
|
||||
}
|
||||
|
||||
// may be formatted by multiparser
|
||||
if (ast.type === "yaml") {
|
||||
if (ast.type === "yaml" || ast.type === "toml") {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
"use strict";
|
||||
|
||||
const htmlStyles = require("html-styles");
|
||||
|
||||
const getCssStyleTags = property =>
|
||||
htmlStyles
|
||||
.filter(htmlStyle => htmlStyle.style[property])
|
||||
.map(htmlStyle =>
|
||||
htmlStyle.selectorText
|
||||
.split(",")
|
||||
.map(selector => selector.trim())
|
||||
.filter(selector => /^[a-zA-Z0-9]+$/.test(selector))
|
||||
.reduce((reduced, tagName) => {
|
||||
reduced[tagName] = htmlStyle.style[property];
|
||||
return reduced;
|
||||
}, {})
|
||||
)
|
||||
.reduce((reduced, value) => Object.assign(reduced, value), {});
|
||||
|
||||
const CSS_DISPLAY_TAGS = getCssStyleTags("display");
|
||||
const CSS_DISPLAY_DEFAULT = "inline";
|
||||
const CSS_WHITE_SPACE_TAGS = getCssStyleTags("white-space");
|
||||
const CSS_WHITE_SPACE_DEFAULT = "normal";
|
||||
|
||||
module.exports = {
|
||||
CSS_DISPLAY_TAGS,
|
||||
CSS_DISPLAY_DEFAULT,
|
||||
CSS_WHITE_SPACE_TAGS,
|
||||
CSS_WHITE_SPACE_DEFAULT
|
||||
};
|
|
@ -1,106 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
const { hasNewlineInRange } = require("../common/util");
|
||||
const {
|
||||
builders: { hardline, concat, markAsRoot, literalline },
|
||||
utils: { removeLines, mapDoc }
|
||||
} = require("../doc");
|
||||
|
||||
function embed(path, print, textToDoc, options) {
|
||||
const node = path.getValue();
|
||||
|
||||
switch (node.type) {
|
||||
case "text": {
|
||||
const parent = path.getParentNode();
|
||||
// Inline JavaScript
|
||||
if (
|
||||
parent.type === "script" &&
|
||||
((!parent.attribs.lang && !parent.attribs.type) ||
|
||||
parent.attribs.type === "text/javascript" ||
|
||||
parent.attribs.type === "text/babel" ||
|
||||
parent.attribs.type === "application/javascript")
|
||||
) {
|
||||
const parser = options.parser === "flow" ? "flow" : "babylon";
|
||||
const doc = textToDoc(node.data, { parser });
|
||||
return concat([hardline, doc]);
|
||||
}
|
||||
|
||||
// Inline TypeScript
|
||||
if (
|
||||
parent.type === "script" &&
|
||||
(parent.attribs.type === "application/x-typescript" ||
|
||||
parent.attribs.lang === "ts")
|
||||
) {
|
||||
const doc = textToDoc(node.data, { parser: "typescript" }, options);
|
||||
return concat([hardline, doc]);
|
||||
}
|
||||
|
||||
// Inline Styles
|
||||
if (parent.type === "style") {
|
||||
const doc = textToDoc(node.data, { parser: "css" });
|
||||
return concat([hardline, doc]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "attribute": {
|
||||
/*
|
||||
* Vue binding syntax: JS expressions
|
||||
* :class="{ 'some-key': value }"
|
||||
* v-bind:id="'list-' + id"
|
||||
* v-if="foo && !bar"
|
||||
* @click="someFunction()"
|
||||
*/
|
||||
if (/(^@)|(^v-)|:/.test(node.key) && !/^\w+$/.test(node.value)) {
|
||||
const doc = textToDoc(node.value, {
|
||||
parser: "__js_expression",
|
||||
// Use singleQuote since HTML attributes use double-quotes.
|
||||
// TODO(azz): We still need to do an entity escape on the attribute.
|
||||
singleQuote: true
|
||||
});
|
||||
return concat([
|
||||
node.key,
|
||||
'="',
|
||||
hasNewlineInRange(node.value, 0, node.value.length)
|
||||
? doc
|
||||
: removeLines(doc),
|
||||
'"'
|
||||
]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "yaml":
|
||||
return markAsRoot(
|
||||
concat([
|
||||
"---",
|
||||
hardline,
|
||||
node.value.trim()
|
||||
? replaceNewlinesWithLiterallines(
|
||||
textToDoc(node.value, { parser: "yaml" })
|
||||
)
|
||||
: "",
|
||||
"---",
|
||||
hardline
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function replaceNewlinesWithLiterallines(doc) {
|
||||
return mapDoc(
|
||||
doc,
|
||||
currentDoc =>
|
||||
typeof currentDoc === "string" && currentDoc.includes("\n")
|
||||
? concat(
|
||||
currentDoc
|
||||
.split(/(\n)/g)
|
||||
.map((v, i) => (i % 2 === 0 ? v : literalline))
|
||||
)
|
||||
: currentDoc
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = embed;
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
const printer = require("./printer-htmlparser2");
|
||||
const createLanguage = require("../utils/create-language");
|
||||
const options = require("./options");
|
||||
|
||||
const languages = [
|
||||
createLanguage(require("linguist-languages/data/html"), {
|
||||
|
@ -19,5 +20,6 @@ const printers = {
|
|||
|
||||
module.exports = {
|
||||
languages,
|
||||
printers
|
||||
printers,
|
||||
options
|
||||
};
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
"use strict";
|
||||
|
||||
const CATEGORY_HTML = "HTML";
|
||||
|
||||
// format based on https://github.com/prettier/prettier/blob/master/src/main/core-options.js
|
||||
module.exports = {
|
||||
htmlWhitespaceSensitivity: {
|
||||
since: "1.15.0",
|
||||
category: CATEGORY_HTML,
|
||||
type: "choice",
|
||||
default: "css",
|
||||
description: "How to handle whitespaces in HTML.",
|
||||
choices: [
|
||||
{
|
||||
value: "css",
|
||||
description: "Respect the default value of CSS display property."
|
||||
},
|
||||
{
|
||||
value: "strict",
|
||||
description: "Whitespaces are considered sensitive."
|
||||
},
|
||||
{
|
||||
value: "ignore",
|
||||
description: "Whitespaces are considered insensitive."
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
|
@ -1,10 +1,12 @@
|
|||
"use strict";
|
||||
|
||||
const parseFrontMatter = require("../utils/front-matter");
|
||||
const { HTML_TAGS, HTML_ELEMENT_ATTRIBUTES } = require("./utils");
|
||||
const { HTML_ELEMENT_ATTRIBUTES, HTML_TAGS, mapNode } = require("./utils");
|
||||
|
||||
function parse(text /*, parsers, opts*/) {
|
||||
const { frontMatter, content } = parseFrontMatter(text);
|
||||
function parse(text, parsers, options, { shouldParseFrontMatter = true } = {}) {
|
||||
const { frontMatter, content } = shouldParseFrontMatter
|
||||
? parseFrontMatter(text)
|
||||
: { frontMatter: null, content: text };
|
||||
|
||||
// Inline the require to avoid loading all the JS if we don't use it
|
||||
const Parser = require("htmlparser2/lib/Parser");
|
||||
|
@ -27,7 +29,13 @@ function parse(text /*, parsers, opts*/) {
|
|||
super.onattribdata(value);
|
||||
}
|
||||
onattribend() {
|
||||
super.onattribend();
|
||||
if (this._cbs.onattribute) {
|
||||
this._cbs.onattribute(this._attribname, this._attribvalue);
|
||||
}
|
||||
if (this._attribs) {
|
||||
this._attribs.push([this._attribname, this._attribvalue]);
|
||||
}
|
||||
this._attribname = "";
|
||||
this._attribvalue = null;
|
||||
}
|
||||
onselfclosingtag() {
|
||||
|
@ -43,15 +51,36 @@ function parse(text /*, parsers, opts*/) {
|
|||
this.onopentagend();
|
||||
}
|
||||
}
|
||||
onopentagname(name) {
|
||||
super.onopentagname(name);
|
||||
if (this._cbs.onopentag) {
|
||||
this._attribs = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* modifications:
|
||||
* - add `selfClosing` field
|
||||
* - add `isSelfClosing` field
|
||||
* - correct `endIndex` for whitespaces before closing tag end marker (e.g., `<x></x\n>`)
|
||||
*/
|
||||
class CustomDomHandler extends DomHandler {
|
||||
onselfclosingtag() {
|
||||
this._tagStack[this._tagStack.length - 1].selfClosing = true;
|
||||
this._tagStack[this._tagStack.length - 1].isSelfClosing = true;
|
||||
}
|
||||
onclosetag() {
|
||||
const elem = this._tagStack.pop();
|
||||
if (this._options.withEndIndices && elem) {
|
||||
const buffer = this._parser._tokenizer._buffer;
|
||||
let endIndex = this._parser.endIndex;
|
||||
while (buffer[endIndex] && buffer[endIndex] !== ">") {
|
||||
endIndex++;
|
||||
}
|
||||
elem.endIndex = buffer[endIndex] ? endIndex : this._parser.endIndex;
|
||||
}
|
||||
if (this._elementCB) {
|
||||
this._elementCB(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,13 +95,59 @@ function parse(text /*, parsers, opts*/) {
|
|||
recognizeSelfClosing: true
|
||||
}).end(content);
|
||||
|
||||
const ast = normalize({ type: "root", children: handler.dom }, text);
|
||||
const ast = normalize(
|
||||
{
|
||||
type: "root",
|
||||
children: handler.dom,
|
||||
startIndex: 0,
|
||||
endIndex: text.length
|
||||
},
|
||||
text
|
||||
);
|
||||
|
||||
if (frontMatter) {
|
||||
ast.children.unshift(frontMatter);
|
||||
}
|
||||
|
||||
return ast;
|
||||
const parseHtml = data =>
|
||||
parse(data, parsers, options, {
|
||||
shouldParseFrontMatter: false
|
||||
});
|
||||
|
||||
return mapNode(ast, node => {
|
||||
const ieConditionalComment = parseIeConditionalComment(node, parseHtml);
|
||||
return ieConditionalComment ? ieConditionalComment : node;
|
||||
});
|
||||
}
|
||||
|
||||
function parseIeConditionalComment(node, parseHtml) {
|
||||
if (node.type !== "comment") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const match = node.data.match(/^(\[if([^\]]*?)\]>)([\s\S]*?)<!\s*\[endif\]$/);
|
||||
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [, openingTagSuffix, condition, data] = match;
|
||||
const subTree = parseHtml(data);
|
||||
const baseIndex = node.startIndex + "<!--".length + openingTagSuffix.length;
|
||||
|
||||
return Object.assign(
|
||||
{},
|
||||
mapNode(subTree, currentNode =>
|
||||
Object.assign({}, currentNode, {
|
||||
startIndex: baseIndex + currentNode.startIndex,
|
||||
endIndex: baseIndex + currentNode.endIndex
|
||||
})
|
||||
),
|
||||
{
|
||||
type: "ieConditionalComment",
|
||||
condition: condition.trim().replace(/\s+/g, " ")
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function normalize(node, text) {
|
||||
|
@ -90,7 +165,7 @@ function normalize(node, text) {
|
|||
if (node.attribs) {
|
||||
const CURRENT_HTML_ELEMENT_ATTRIBUTES =
|
||||
HTML_ELEMENT_ATTRIBUTES[node.name] || Object.create(null);
|
||||
const attributes = Object.keys(node.attribs).map(attributeKey => {
|
||||
const attributes = node.attribs.map(([attributeKey, attributeValue]) => {
|
||||
const lowerCaseAttributeKey = attributeKey.toLowerCase();
|
||||
return {
|
||||
type: "attribute",
|
||||
|
@ -99,7 +174,7 @@ function normalize(node, text) {
|
|||
lowerCaseAttributeKey in CURRENT_HTML_ELEMENT_ATTRIBUTES
|
||||
? lowerCaseAttributeKey
|
||||
: attributeKey,
|
||||
value: node.attribs[attributeKey]
|
||||
value: attributeValue
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,285 @@
|
|||
"use strict";
|
||||
|
||||
const {
|
||||
VOID_TAGS,
|
||||
getNodeCssStyleDisplay,
|
||||
getNodeCssStyleWhiteSpace,
|
||||
getPrevNode,
|
||||
isDanglingSpaceSensitiveNode,
|
||||
isLeadingSpaceSensitiveNode,
|
||||
isScriptLikeTag,
|
||||
isTrailingSpaceSensitiveNode,
|
||||
mapNode
|
||||
} = require("./utils");
|
||||
const LineAndColumn = (m => m.default || m)(require("lines-and-columns"));
|
||||
|
||||
const PREPROCESS_PIPELINE = [
|
||||
renameScriptAndStyleWithTag,
|
||||
processDirectives,
|
||||
addIsSelfClosing,
|
||||
extractWhitespaces,
|
||||
addCssDisplay,
|
||||
addIsSpaceSensitive,
|
||||
addStartAndEndLocation,
|
||||
addShortcuts
|
||||
];
|
||||
|
||||
function preprocess(ast, options) {
|
||||
for (const fn of PREPROCESS_PIPELINE) {
|
||||
ast = fn(ast, options);
|
||||
}
|
||||
return ast;
|
||||
}
|
||||
|
||||
/** add `startLocation` and `endLocation` field */
|
||||
function addStartAndEndLocation(ast, options) {
|
||||
const locator = new LineAndColumn(options.originalText);
|
||||
return mapNode(ast, node => {
|
||||
const startLocation = locator.locationForIndex(options.locStart(node));
|
||||
const endLocation = locator.locationForIndex(options.locEnd(node) - 1);
|
||||
return Object.assign({}, node, { startLocation, endLocation });
|
||||
});
|
||||
}
|
||||
|
||||
/** rename `script` and `style` with `tag` */
|
||||
function renameScriptAndStyleWithTag(ast /*, options */) {
|
||||
return mapNode(ast, node => {
|
||||
return node.type === "script" || node.type === "style"
|
||||
? Object.assign({}, node, { type: "tag" })
|
||||
: node;
|
||||
});
|
||||
}
|
||||
|
||||
/** add `isSelfClosing` for void tags, directives, and comments */
|
||||
function addIsSelfClosing(ast /*, options */) {
|
||||
return mapNode(ast, node => {
|
||||
if (
|
||||
(node.type === "tag" && node.name in VOID_TAGS) ||
|
||||
node.type === "directive" ||
|
||||
node.type === "comment"
|
||||
) {
|
||||
return Object.assign({}, node, { isSelfClosing: true });
|
||||
}
|
||||
return node;
|
||||
});
|
||||
}
|
||||
|
||||
function processDirectives(ast /*, options */) {
|
||||
return mapNode(ast, node => {
|
||||
if (node.type !== "directive") {
|
||||
return node;
|
||||
}
|
||||
|
||||
const isDoctype = /^!doctype$/i.test(node.name);
|
||||
const data = node.data.slice(node.name.length).replace(/\s+/g, " ");
|
||||
|
||||
return Object.assign({}, node, {
|
||||
name: isDoctype ? "!DOCTYPE" : node.name,
|
||||
data: isDoctype ? data.replace(/^\s+html/i, " html") : data,
|
||||
// workaround for htmlparser2 bug
|
||||
endIndex:
|
||||
node.startIndex +
|
||||
"<".length +
|
||||
node.name.length +
|
||||
node.data.length +
|
||||
">".length
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* - add `hasLeadingSpaces` field
|
||||
* - add `hasTrailingSpaces` field
|
||||
* - add `hasDanglingSpaces` field for parent nodes
|
||||
* - add `isWhiteSpaceSensitive`, `isIndentationSensitive` field for text nodes
|
||||
* - remove insensitive whitespaces
|
||||
*/
|
||||
function extractWhitespaces(ast /*, options*/) {
|
||||
const TYPE_WHITESPACE = "whitespace";
|
||||
return mapNode(ast, node => {
|
||||
if (!node.children) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (
|
||||
node.children.length === 0 ||
|
||||
(node.children.length === 1 &&
|
||||
node.children[0].type === "text" &&
|
||||
node.children[0].data.trim().length === 0)
|
||||
) {
|
||||
return Object.assign({}, node, {
|
||||
children: [],
|
||||
hasDanglingSpaces: node.children.length !== 0
|
||||
});
|
||||
}
|
||||
|
||||
const cssStyleWhiteSpace = getNodeCssStyleWhiteSpace(node);
|
||||
const isCssStyleWhiteSpacePre = cssStyleWhiteSpace.startsWith("pre");
|
||||
const isScriptLike = isScriptLikeTag(node);
|
||||
|
||||
return Object.assign({}, node, {
|
||||
children: node.children
|
||||
// extract whitespace nodes
|
||||
.reduce((newChildren, child) => {
|
||||
if (child.type !== "text") {
|
||||
return newChildren.concat(child);
|
||||
}
|
||||
|
||||
if (isCssStyleWhiteSpacePre || isScriptLike) {
|
||||
return newChildren.concat(
|
||||
Object.assign({}, child, {
|
||||
isWhiteSpaceSensitive: true,
|
||||
isIndentationSensitive: isCssStyleWhiteSpacePre
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const localChildren = [];
|
||||
|
||||
const [, leadingSpaces, text, trailingSpaces] = child.data.match(
|
||||
/^(\s*)([\s\S]*?)(\s*)$/
|
||||
);
|
||||
|
||||
if (leadingSpaces) {
|
||||
localChildren.push({ type: TYPE_WHITESPACE });
|
||||
}
|
||||
|
||||
if (text) {
|
||||
localChildren.push({
|
||||
type: "text",
|
||||
data: text,
|
||||
startIndex: child.startIndex + leadingSpaces.length,
|
||||
endIndex: child.endIndex - trailingSpaces.length
|
||||
});
|
||||
}
|
||||
|
||||
if (trailingSpaces) {
|
||||
localChildren.push({ type: TYPE_WHITESPACE });
|
||||
}
|
||||
|
||||
return newChildren.concat(localChildren);
|
||||
}, [])
|
||||
// set hasLeadingSpaces/hasTrailingSpaces and filter whitespace nodes
|
||||
.reduce((newChildren, child, i, children) => {
|
||||
if (child.type === TYPE_WHITESPACE) {
|
||||
return newChildren;
|
||||
}
|
||||
|
||||
const hasLeadingSpaces =
|
||||
i !== 0 && children[i - 1].type === TYPE_WHITESPACE;
|
||||
const hasTrailingSpaces =
|
||||
i !== children.length - 1 &&
|
||||
children[i + 1].type === TYPE_WHITESPACE;
|
||||
|
||||
return newChildren.concat(
|
||||
Object.assign({}, child, {
|
||||
hasLeadingSpaces,
|
||||
hasTrailingSpaces
|
||||
})
|
||||
);
|
||||
}, [])
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function addCssDisplay(ast, options) {
|
||||
return mapNode(ast, (node, stack) => {
|
||||
const prevNode = getPrevNode(stack);
|
||||
return Object.assign({}, node, {
|
||||
cssDisplay: getNodeCssStyleDisplay(node, prevNode, options)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* - add `isLeadingSpaceSensitive` field
|
||||
* - add `isTrailingSpaceSensitive` field
|
||||
* - add `isDanglingSpaceSensitive` field for parent nodes
|
||||
*/
|
||||
function addIsSpaceSensitive(ast /*, options */) {
|
||||
return mapNode(ast, node => {
|
||||
if (!node.children) {
|
||||
return node;
|
||||
}
|
||||
|
||||
if (node.children.length === 0) {
|
||||
return Object.assign({}, node, {
|
||||
isDanglingSpaceSensitive: isDanglingSpaceSensitiveNode(node)
|
||||
});
|
||||
}
|
||||
|
||||
return Object.assign({}, node, {
|
||||
children: node.children
|
||||
// set isLeadingSpaceSensitive
|
||||
.map((child, i, children) => {
|
||||
const prevChild = i === 0 ? null : children[i - 1];
|
||||
const nextChild = i === children.length - 1 ? null : children[i + 1];
|
||||
return Object.assign({}, child, {
|
||||
isLeadingSpaceSensitive: isLeadingSpaceSensitiveNode(child, {
|
||||
parent: node,
|
||||
prev: prevChild,
|
||||
next: nextChild
|
||||
})
|
||||
});
|
||||
})
|
||||
// set isTrailingSpaceSensitive and update isLeadingSpaceSensitive if necessary
|
||||
.reduce((newChildren, child, i, children) => {
|
||||
const prevChild = i === 0 ? null : newChildren[i - 1];
|
||||
const nextChild = i === children.length - 1 ? null : children[i + 1];
|
||||
const isTrailingSpaceSensitive =
|
||||
nextChild && !nextChild.isLeadingSpaceSensitive
|
||||
? false
|
||||
: isTrailingSpaceSensitiveNode(child, {
|
||||
parent: node,
|
||||
prev: prevChild,
|
||||
next: nextChild
|
||||
});
|
||||
return newChildren.concat(
|
||||
Object.assign(
|
||||
{},
|
||||
child,
|
||||
{ isTrailingSpaceSensitive },
|
||||
prevChild &&
|
||||
!prevChild.isTrailingSpaceSensitive &&
|
||||
child.isLeadingSpaceSensitive
|
||||
? { isLeadingSpaceSensitive: false }
|
||||
: null
|
||||
)
|
||||
);
|
||||
}, [])
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function addShortcuts(ast /*, options */) {
|
||||
function _addShortcuts(node, parent, index) {
|
||||
const prev = index === -1 ? null : parent.children[index - 1];
|
||||
const next = index === -1 ? null : parent.children[index + 1];
|
||||
|
||||
const hasChildren = node.children && node.children.length !== 0;
|
||||
|
||||
const firstChild = !hasChildren ? null : node.children[0];
|
||||
const lastChild = !hasChildren
|
||||
? null
|
||||
: node.children[node.children.length - 1];
|
||||
|
||||
Object.defineProperties(node, {
|
||||
parent: { value: parent, enumerable: false },
|
||||
prev: { value: prev, enumerable: false },
|
||||
next: { value: next, enumerable: false },
|
||||
firstChild: { value: firstChild, enumerable: false },
|
||||
lastChild: { value: lastChild, enumerable: false }
|
||||
});
|
||||
|
||||
if (node.children) {
|
||||
node.children.forEach((child, childIndex) =>
|
||||
_addShortcuts(child, node, childIndex)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_addShortcuts(ast, null, -1);
|
||||
return ast;
|
||||
}
|
||||
|
||||
module.exports = preprocess;
|
|
@ -1,236 +1,582 @@
|
|||
"use strict";
|
||||
|
||||
const embed = require("./embed");
|
||||
const clean = require("./clean");
|
||||
const { getLast } = require("../common/util");
|
||||
const { isNextLineEmpty } = require("../common/util-shared");
|
||||
const {
|
||||
builders: {
|
||||
concat,
|
||||
line,
|
||||
hardline,
|
||||
softline,
|
||||
group,
|
||||
indent,
|
||||
conditionalGroup,
|
||||
dedentToRoot
|
||||
},
|
||||
utils: { willBreak, isLineNext, isEmpty }
|
||||
builders,
|
||||
utils: { removeLines, stripTrailingHardline }
|
||||
} = require("../doc");
|
||||
const {
|
||||
VOID_TAGS,
|
||||
breakParent,
|
||||
group,
|
||||
hardline,
|
||||
indent,
|
||||
join,
|
||||
line,
|
||||
literalline,
|
||||
markAsRoot,
|
||||
softline
|
||||
} = builders;
|
||||
const { hasNewlineInRange } = require("../common/util");
|
||||
const {
|
||||
normalizeParts,
|
||||
dedentString,
|
||||
forceBreakChildren,
|
||||
forceBreakContent,
|
||||
forceNextEmptyLine,
|
||||
getCommentData,
|
||||
getLastDescendant,
|
||||
hasPrettierIgnore,
|
||||
isPreTagNode,
|
||||
isScriptTagNode,
|
||||
isTextAreaTagNode,
|
||||
isWhitespaceOnlyText
|
||||
inferScriptParser,
|
||||
isScriptLikeTag,
|
||||
preferHardlineAsLeadingSpaces,
|
||||
replaceDocNewlines,
|
||||
replaceNewlines
|
||||
} = require("./utils");
|
||||
const preprocess = require("./preprocess");
|
||||
const assert = require("assert");
|
||||
|
||||
function genericPrint(path, options, print) {
|
||||
const n = path.getValue();
|
||||
function concat(parts) {
|
||||
const newParts = normalizeParts(parts);
|
||||
return newParts.length === 0
|
||||
? ""
|
||||
: newParts.length === 1
|
||||
? newParts[0]
|
||||
: builders.concat(newParts);
|
||||
}
|
||||
|
||||
switch (n.type) {
|
||||
case "root": {
|
||||
return concat(printChildren(path, print, options));
|
||||
}
|
||||
case "directive": {
|
||||
return concat([
|
||||
"<",
|
||||
n.name === "!doctype"
|
||||
? n.data
|
||||
.replace(/\s+/g, " ")
|
||||
.replace(
|
||||
/^(!doctype)(( html)?)/i,
|
||||
(_, doctype, doctypeHtml) =>
|
||||
doctype.toUpperCase() + doctypeHtml.toLowerCase()
|
||||
)
|
||||
: n.data,
|
||||
">",
|
||||
hardline
|
||||
]);
|
||||
function fill(parts) {
|
||||
const newParts = [];
|
||||
|
||||
let hasSeparator = true;
|
||||
for (const part of normalizeParts(parts)) {
|
||||
switch (part) {
|
||||
case line:
|
||||
case hardline:
|
||||
case literalline:
|
||||
case softline:
|
||||
newParts.push(part);
|
||||
hasSeparator = true;
|
||||
break;
|
||||
default:
|
||||
if (!hasSeparator) {
|
||||
// `fill` needs a separator between each two parts
|
||||
newParts.push("");
|
||||
}
|
||||
newParts.push(part);
|
||||
hasSeparator = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return builders.fill(newParts);
|
||||
}
|
||||
|
||||
function embed(path, print, textToDoc /*, options */) {
|
||||
const node = path.getValue();
|
||||
switch (node.type) {
|
||||
case "text": {
|
||||
const parentNode = path.getParentNode();
|
||||
|
||||
if (
|
||||
isPreTagNode(parentNode) ||
|
||||
isTextAreaTagNode(parentNode) ||
|
||||
isScriptTagNode(parentNode)
|
||||
) {
|
||||
return concat(
|
||||
n.data.split(/(\n)/g).map((x, i) => (i % 2 === 1 ? hardline : x))
|
||||
);
|
||||
if (isScriptLikeTag(node.parent)) {
|
||||
const parser = inferScriptParser(node.parent);
|
||||
if (parser) {
|
||||
return builders.concat([
|
||||
concat([
|
||||
breakParent,
|
||||
printOpeningTagPrefix(node),
|
||||
markAsRoot(
|
||||
stripTrailingHardline(textToDoc(node.data, { parser }))
|
||||
),
|
||||
printClosingTagSuffix(node)
|
||||
])
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return n.data.replace(/\s+/g, " ").trim();
|
||||
}
|
||||
case "script":
|
||||
case "style":
|
||||
case "tag": {
|
||||
const isVoid = n.name in VOID_TAGS;
|
||||
const openingPrinted = printOpeningTag(path, print, isVoid);
|
||||
|
||||
// Print self closing tag
|
||||
if (isVoid || n.selfClosing) {
|
||||
return openingPrinted;
|
||||
}
|
||||
|
||||
const closingPrinted = printClosingTag(n);
|
||||
|
||||
// Print tags without children
|
||||
if (n.children.length === 0) {
|
||||
return concat([openingPrinted, closingPrinted]);
|
||||
}
|
||||
|
||||
const children = printChildren(path, print, options);
|
||||
|
||||
if (isPreTagNode(n) || isTextAreaTagNode(n)) {
|
||||
return dedentToRoot(
|
||||
group(concat([openingPrinted, concat(children), closingPrinted]))
|
||||
);
|
||||
}
|
||||
|
||||
const isScriptTag = isScriptTagNode(n);
|
||||
|
||||
if (isScriptTag) {
|
||||
return group(
|
||||
concat([openingPrinted, concat(children), closingPrinted])
|
||||
);
|
||||
}
|
||||
|
||||
const containsTag = n.children.some(
|
||||
child => ["script", "style", "tag"].indexOf(child.type) !== -1
|
||||
);
|
||||
|
||||
let forcedBreak =
|
||||
willBreak(openingPrinted) || containsTag || n.attributes.length > 1;
|
||||
|
||||
// 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]))
|
||||
) {
|
||||
children.shift();
|
||||
}
|
||||
|
||||
// Detect whether we will force this element to output over multiple lines.
|
||||
if (children.some(doc => willBreak(doc))) {
|
||||
forcedBreak = true;
|
||||
}
|
||||
|
||||
const containsOnlyEmptyTextNodes = n.children.every(isWhitespaceOnlyText);
|
||||
|
||||
const printedMultilineChildren = concat([
|
||||
!isScriptTag && !containsOnlyEmptyTextNodes ? hardline : "",
|
||||
group(concat(children), { shouldBreak: true })
|
||||
]);
|
||||
|
||||
const multiLineElem = group(
|
||||
concat([
|
||||
openingPrinted,
|
||||
indent(printedMultilineChildren),
|
||||
hardline,
|
||||
closingPrinted
|
||||
])
|
||||
);
|
||||
|
||||
if (forcedBreak) {
|
||||
return multiLineElem;
|
||||
}
|
||||
|
||||
return conditionalGroup([
|
||||
group(concat([openingPrinted, concat(children), closingPrinted])),
|
||||
multiLineElem
|
||||
]);
|
||||
}
|
||||
case "comment": {
|
||||
return concat(["<!--", n.data, "-->"]);
|
||||
break;
|
||||
}
|
||||
case "attribute": {
|
||||
if (n.value === null) {
|
||||
return n.key;
|
||||
/*
|
||||
* Vue binding syntax: JS expressions
|
||||
* :class="{ 'some-key': value }"
|
||||
* v-bind:id="'list-' + id"
|
||||
* v-if="foo && !bar"
|
||||
* @click="someFunction()"
|
||||
*/
|
||||
if (/(^@)|(^v-)|:/.test(node.key) && !/^\w+$/.test(node.value)) {
|
||||
const doc = textToDoc(node.value, {
|
||||
parser: "__js_expression",
|
||||
// Use singleQuote since HTML attributes use double-quotes.
|
||||
// TODO(azz): We still need to do an entity escape on the attribute.
|
||||
singleQuote: true
|
||||
});
|
||||
return concat([
|
||||
node.key,
|
||||
'="',
|
||||
hasNewlineInRange(node.value, 0, node.value.length)
|
||||
? doc
|
||||
: removeLines(doc),
|
||||
'"'
|
||||
]);
|
||||
}
|
||||
|
||||
return concat([n.key, '="', n.value.replace(/"/g, """), '"']);
|
||||
break;
|
||||
}
|
||||
// front matter
|
||||
case "yaml":
|
||||
case "toml":
|
||||
return concat([n.raw, hardline]);
|
||||
default:
|
||||
/* istanbul ignore next */
|
||||
throw new Error("unknown htmlparser2 type: " + n.type);
|
||||
return markAsRoot(
|
||||
concat([
|
||||
"---",
|
||||
hardline,
|
||||
node.value.trim().length === 0
|
||||
? ""
|
||||
: replaceDocNewlines(
|
||||
textToDoc(node.value, { parser: "yaml" }),
|
||||
literalline
|
||||
),
|
||||
"---"
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function printOpeningTag(path, print, isVoid) {
|
||||
const n = path.getValue();
|
||||
function genericPrint(path, options, print) {
|
||||
const node = path.getValue();
|
||||
switch (node.type) {
|
||||
case "root":
|
||||
return concat([group(printChildren(path, options, print)), hardline]);
|
||||
case "tag":
|
||||
case "ieConditionalComment":
|
||||
return concat([
|
||||
group(
|
||||
concat([
|
||||
printOpeningTag(path, options, print),
|
||||
node.children.length === 0
|
||||
? node.hasDanglingSpaces && node.isDanglingSpaceSensitive
|
||||
? line
|
||||
: ""
|
||||
: concat([
|
||||
forceBreakContent(node) ? breakParent : "",
|
||||
indent(
|
||||
concat([
|
||||
node.firstChild.type === "text" &&
|
||||
node.firstChild.isWhiteSpaceSensitive &&
|
||||
node.firstChild.isIndentationSensitive
|
||||
? literalline
|
||||
: node.firstChild.hasLeadingSpaces &&
|
||||
node.firstChild.isLeadingSpaceSensitive
|
||||
? line
|
||||
: softline,
|
||||
printChildren(path, options, print)
|
||||
])
|
||||
),
|
||||
(node.next
|
||||
? needsToBorrowPrevClosingTagEndMarker(node.next)
|
||||
: needsToBorrowLastChildClosingTagEndMarker(node.parent))
|
||||
? ""
|
||||
: node.lastChild.hasTrailingSpaces &&
|
||||
node.lastChild.isTrailingSpaceSensitive
|
||||
? line
|
||||
: softline
|
||||
])
|
||||
])
|
||||
),
|
||||
printClosingTag(node)
|
||||
]);
|
||||
case "text":
|
||||
return fill(
|
||||
[].concat(
|
||||
printOpeningTagPrefix(node),
|
||||
node.isWhiteSpaceSensitive
|
||||
? node.isIndentationSensitive
|
||||
? replaceNewlines(
|
||||
node.data.replace(/^\s*?\n|\n\s*?$/g, ""),
|
||||
literalline
|
||||
)
|
||||
: replaceNewlines(
|
||||
dedentString(node.data.replace(/^\s*?\n|\n\s*?$/g, "")),
|
||||
hardline
|
||||
)
|
||||
: join(line, node.data.split(/\s+/)).parts,
|
||||
printClosingTagSuffix(node)
|
||||
)
|
||||
);
|
||||
case "comment":
|
||||
case "directive": {
|
||||
const data = getCommentData(node);
|
||||
return concat([
|
||||
group(
|
||||
concat([
|
||||
printOpeningTagStart(node),
|
||||
data.trim().length === 0
|
||||
? ""
|
||||
: concat([
|
||||
indent(
|
||||
concat([
|
||||
node.prev &&
|
||||
needsToBorrowNextOpeningTagStartMarker(node.prev)
|
||||
? breakParent
|
||||
: "",
|
||||
node.type === "directive" ? " " : line,
|
||||
concat(replaceNewlines(data, hardline))
|
||||
])
|
||||
),
|
||||
node.type === "directive"
|
||||
? ""
|
||||
: (node.next
|
||||
? needsToBorrowPrevClosingTagEndMarker(node.next)
|
||||
: needsToBorrowLastChildClosingTagEndMarker(node.parent))
|
||||
? " "
|
||||
: line
|
||||
])
|
||||
])
|
||||
),
|
||||
printClosingTagEnd(node)
|
||||
]);
|
||||
}
|
||||
case "attribute":
|
||||
return concat([
|
||||
node.key,
|
||||
node.value === null
|
||||
? ""
|
||||
: concat([
|
||||
'="',
|
||||
concat(
|
||||
replaceNewlines(node.value.replace(/"/g, """), literalline)
|
||||
),
|
||||
'"'
|
||||
])
|
||||
]);
|
||||
case "yaml":
|
||||
case "toml":
|
||||
return node.raw;
|
||||
default:
|
||||
throw new Error(`Unexpected node type ${node.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
const selfClosing = isVoid || n.selfClosing;
|
||||
function printChildren(path, options, print) {
|
||||
const node = path.getValue();
|
||||
|
||||
// Don't break self-closing elements with no attributes
|
||||
if (selfClosing && !n.attributes.length) {
|
||||
return concat(["<", n.name, " />"]);
|
||||
if (forceBreakChildren(node)) {
|
||||
return concat([
|
||||
breakParent,
|
||||
concat(
|
||||
path.map(childPath => {
|
||||
const childNode = childPath.getValue();
|
||||
const prevBetweenLine = !childNode.prev
|
||||
? ""
|
||||
: printBetweenLine(childNode.prev, childNode);
|
||||
return concat([
|
||||
!prevBetweenLine
|
||||
? ""
|
||||
: concat([
|
||||
prevBetweenLine,
|
||||
forceNextEmptyLine(childNode.prev) ||
|
||||
childNode.prev.endLocation.line + 1 <
|
||||
childNode.startLocation.line
|
||||
? hardline
|
||||
: ""
|
||||
]),
|
||||
print(childPath)
|
||||
]);
|
||||
}, "children")
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
// 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([
|
||||
"<",
|
||||
n.name,
|
||||
" ",
|
||||
concat(path.map(print, "attributes")),
|
||||
selfClosing ? " />" : ">"
|
||||
])
|
||||
const parts = [];
|
||||
|
||||
path.map((childPath, childIndex) => {
|
||||
const childNode = childPath.getValue();
|
||||
|
||||
if (childIndex !== 0) {
|
||||
const prevBetweenLine = printBetweenLine(childNode.prev, childNode);
|
||||
if (prevBetweenLine) {
|
||||
if (
|
||||
forceNextEmptyLine(childNode.prev) ||
|
||||
childNode.prev.endLocation.line + 1 < childNode.startLocation.line
|
||||
) {
|
||||
parts.push(hardline, hardline);
|
||||
} else {
|
||||
parts.push(prevBetweenLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Array.prototype.push.apply(
|
||||
parts,
|
||||
childNode.type === "text" ? print(childPath).parts : [print(childPath)]
|
||||
);
|
||||
}
|
||||
}, "children");
|
||||
|
||||
return group(
|
||||
concat([
|
||||
"<",
|
||||
n.name,
|
||||
indent(
|
||||
concat(path.map(attr => concat([line, print(attr)]), "attributes"))
|
||||
),
|
||||
selfClosing ? concat([line, "/>"]) : concat([softline, ">"])
|
||||
])
|
||||
);
|
||||
return fill(parts);
|
||||
|
||||
function printBetweenLine(prevNode, nextNode) {
|
||||
return (needsToBorrowNextOpeningTagStartMarker(prevNode) &&
|
||||
/**
|
||||
* 123<a
|
||||
* ~
|
||||
* ><b>
|
||||
*/
|
||||
(nextNode.firstChild ||
|
||||
/**
|
||||
* 123<br />
|
||||
* ~
|
||||
*/
|
||||
(nextNode.type === "tag" &&
|
||||
nextNode.isSelfClosing &&
|
||||
nextNode.attributes.length === 0))) ||
|
||||
/**
|
||||
* <img
|
||||
* src="long"
|
||||
* ~
|
||||
* />123
|
||||
*/
|
||||
(prevNode.type === "tag" &&
|
||||
prevNode.isSelfClosing &&
|
||||
needsToBorrowPrevClosingTagEndMarker(nextNode))
|
||||
? ""
|
||||
: !nextNode.isLeadingSpaceSensitive ||
|
||||
preferHardlineAsLeadingSpaces(nextNode) ||
|
||||
/**
|
||||
* Want to write us a letter? Use our<a
|
||||
* ><b><a>mailing address</a></b></a
|
||||
* ~
|
||||
* >.
|
||||
*/
|
||||
(needsToBorrowPrevClosingTagEndMarker(nextNode) &&
|
||||
prevNode.lastChild &&
|
||||
needsToBorrowParentClosingTagStartMarker(prevNode.lastChild) &&
|
||||
prevNode.lastChild.lastChild &&
|
||||
needsToBorrowParentClosingTagStartMarker(
|
||||
prevNode.lastChild.lastChild
|
||||
))
|
||||
? hardline
|
||||
: nextNode.hasLeadingSpaces
|
||||
? line
|
||||
: softline;
|
||||
}
|
||||
}
|
||||
|
||||
function printOpeningTag(path, options, print) {
|
||||
const node = path.getValue();
|
||||
return concat([
|
||||
printOpeningTagStart(node),
|
||||
!node.attributes || node.attributes.length === 0
|
||||
? node.isSelfClosing
|
||||
? /**
|
||||
* <br />
|
||||
* ^
|
||||
*/
|
||||
" "
|
||||
: ""
|
||||
: group(
|
||||
concat([
|
||||
node.prev && needsToBorrowNextOpeningTagStartMarker(node.prev)
|
||||
? /**
|
||||
* 123<a
|
||||
* attr
|
||||
* >
|
||||
*/
|
||||
breakParent
|
||||
: "",
|
||||
indent(concat([line, join(line, path.map(print, "attributes"))])),
|
||||
node.firstChild &&
|
||||
needsToBorrowParentOpeningTagEndMarker(node.firstChild)
|
||||
? /**
|
||||
* 123<a
|
||||
* attr
|
||||
* ~
|
||||
* >456
|
||||
*/
|
||||
""
|
||||
: node.isSelfClosing
|
||||
? line
|
||||
: softline
|
||||
])
|
||||
),
|
||||
node.isSelfClosing ? "" : printOpeningTagEnd(node)
|
||||
]);
|
||||
}
|
||||
|
||||
function printOpeningTagStart(node) {
|
||||
return node.prev && needsToBorrowNextOpeningTagStartMarker(node.prev)
|
||||
? ""
|
||||
: concat([printOpeningTagPrefix(node), printOpeningTagStartMarker(node)]);
|
||||
}
|
||||
|
||||
function printOpeningTagEnd(node) {
|
||||
return node.firstChild &&
|
||||
needsToBorrowParentOpeningTagEndMarker(node.firstChild)
|
||||
? ""
|
||||
: printOpeningTagEndMarker(node);
|
||||
}
|
||||
|
||||
function printClosingTag(node) {
|
||||
return concat(["</", node.name, ">"]);
|
||||
return concat([
|
||||
node.isSelfClosing ? "" : printClosingTagStart(node),
|
||||
printClosingTagEnd(node)
|
||||
]);
|
||||
}
|
||||
|
||||
function printChildren(path, print, options) {
|
||||
const parts = [];
|
||||
function printClosingTagStart(node) {
|
||||
return node.lastChild &&
|
||||
needsToBorrowParentClosingTagStartMarker(node.lastChild)
|
||||
? ""
|
||||
: concat([printClosingTagPrefix(node), printClosingTagStartMarker(node)]);
|
||||
}
|
||||
|
||||
path.map(childPath => {
|
||||
const child = childPath.getValue();
|
||||
function printClosingTagEnd(node) {
|
||||
return (node.next
|
||||
? needsToBorrowPrevClosingTagEndMarker(node.next)
|
||||
: needsToBorrowLastChildClosingTagEndMarker(node.parent))
|
||||
? ""
|
||||
: concat([printClosingTagEndMarker(node), printClosingTagSuffix(node)]);
|
||||
}
|
||||
|
||||
parts.push(print(childPath));
|
||||
function needsToBorrowNextOpeningTagStartMarker(node) {
|
||||
/**
|
||||
* 123<p
|
||||
* ^^
|
||||
* >
|
||||
*/
|
||||
return (
|
||||
node.next &&
|
||||
node.type === "text" &&
|
||||
node.isTrailingSpaceSensitive &&
|
||||
!node.hasTrailingSpaces
|
||||
);
|
||||
}
|
||||
|
||||
if (child.type !== "text" && child.type !== "directive") {
|
||||
parts.push(hardline);
|
||||
}
|
||||
function needsToBorrowParentOpeningTagEndMarker(node) {
|
||||
/**
|
||||
* <p
|
||||
* >123
|
||||
* ^
|
||||
*
|
||||
* <p
|
||||
* ><a
|
||||
* ^
|
||||
*/
|
||||
return !node.prev && node.isLeadingSpaceSensitive && !node.hasLeadingSpaces;
|
||||
}
|
||||
|
||||
if (isNextLineEmpty(options.originalText, childPath.getValue(), options)) {
|
||||
parts.push(hardline);
|
||||
}
|
||||
}, "children");
|
||||
function needsToBorrowPrevClosingTagEndMarker(node) {
|
||||
/**
|
||||
* <p></p
|
||||
* >123
|
||||
* ^
|
||||
*
|
||||
* <p></p
|
||||
* ><a
|
||||
* ^
|
||||
*/
|
||||
return node.prev && node.isLeadingSpaceSensitive && !node.hasLeadingSpaces;
|
||||
}
|
||||
|
||||
return parts;
|
||||
function needsToBorrowLastChildClosingTagEndMarker(node) {
|
||||
/**
|
||||
* <p
|
||||
* ><a></a
|
||||
* ></p
|
||||
* ^
|
||||
* >
|
||||
*/
|
||||
return (
|
||||
node.lastChild &&
|
||||
node.lastChild.isTrailingSpaceSensitive &&
|
||||
!node.lastChild.hasTrailingSpaces &&
|
||||
getLastDescendant(node.lastChild).type !== "text"
|
||||
);
|
||||
}
|
||||
|
||||
function needsToBorrowParentClosingTagStartMarker(node) {
|
||||
/**
|
||||
* <p>
|
||||
* 123</p
|
||||
* ^^^
|
||||
* >
|
||||
*
|
||||
* 123</b
|
||||
* ></a
|
||||
* ^^^
|
||||
* >
|
||||
*/
|
||||
return (
|
||||
!node.next &&
|
||||
!node.hasTrailingSpaces &&
|
||||
node.isTrailingSpaceSensitive &&
|
||||
getLastDescendant(node).type === "text"
|
||||
);
|
||||
}
|
||||
|
||||
function printOpeningTagPrefix(node) {
|
||||
return needsToBorrowParentOpeningTagEndMarker(node)
|
||||
? printOpeningTagEndMarker(node.parent)
|
||||
: needsToBorrowPrevClosingTagEndMarker(node)
|
||||
? printClosingTagEndMarker(node.prev)
|
||||
: "";
|
||||
}
|
||||
|
||||
function printClosingTagPrefix(node) {
|
||||
return needsToBorrowLastChildClosingTagEndMarker(node)
|
||||
? printClosingTagEndMarker(node.lastChild)
|
||||
: "";
|
||||
}
|
||||
|
||||
function printClosingTagSuffix(node) {
|
||||
return needsToBorrowParentClosingTagStartMarker(node)
|
||||
? printClosingTagStartMarker(node.parent)
|
||||
: needsToBorrowNextOpeningTagStartMarker(node)
|
||||
? printOpeningTagStartMarker(node.next)
|
||||
: "";
|
||||
}
|
||||
|
||||
function printOpeningTagStartMarker(node) {
|
||||
switch (node.type) {
|
||||
case "comment":
|
||||
return "<!--";
|
||||
case "ieConditionalComment":
|
||||
return `<!--[if ${node.condition}`;
|
||||
default:
|
||||
return `<${node.name}`;
|
||||
}
|
||||
}
|
||||
|
||||
function printOpeningTagEndMarker(node) {
|
||||
assert(!node.isSelfClosing);
|
||||
switch (node.type) {
|
||||
case "ieConditionalComment":
|
||||
return "]>";
|
||||
default:
|
||||
return `>`;
|
||||
}
|
||||
}
|
||||
|
||||
function printClosingTagStartMarker(node) {
|
||||
assert(!node.isSelfClosing);
|
||||
switch (node.type) {
|
||||
case "ieConditionalComment":
|
||||
return "<!";
|
||||
default:
|
||||
return `</${node.name}`;
|
||||
}
|
||||
}
|
||||
|
||||
function printClosingTagEndMarker(node) {
|
||||
switch (node.type) {
|
||||
case "comment":
|
||||
return "-->";
|
||||
case "ieConditionalComment":
|
||||
return `[endif]-->`;
|
||||
case "tag":
|
||||
if (node.isSelfClosing) {
|
||||
return "/>";
|
||||
}
|
||||
// fall through
|
||||
default:
|
||||
return ">";
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
preprocess,
|
||||
print: genericPrint,
|
||||
massageAstNode: clean,
|
||||
embed,
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
"use strict";
|
||||
|
||||
const {
|
||||
builders: { concat },
|
||||
utils: { mapDoc }
|
||||
} = require("../doc");
|
||||
|
||||
const {
|
||||
CSS_DISPLAY_TAGS,
|
||||
CSS_DISPLAY_DEFAULT,
|
||||
CSS_WHITE_SPACE_TAGS,
|
||||
CSS_WHITE_SPACE_DEFAULT
|
||||
} = require("./constants.evaluate");
|
||||
|
||||
const htmlTagNames = require("html-tag-names");
|
||||
const htmlElementAttributes = require("html-element-attributes");
|
||||
|
||||
|
@ -58,64 +70,402 @@ function mapObject(object, fn) {
|
|||
|
||||
function hasPrettierIgnore(path) {
|
||||
const node = path.getValue();
|
||||
|
||||
if (isWhitespaceOnlyText(node) || node.type === "attribute") {
|
||||
if (node.type === "attribute") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const parentNode = path.getParentNode();
|
||||
|
||||
if (!parentNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const index = path.getName();
|
||||
|
||||
if (typeof index !== "number" || index === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const prevNode = parentNode.children[index - 1];
|
||||
|
||||
if (isPrettierIgnore(prevNode)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isWhitespaceOnlyText(prevNode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const prevPrevNode = parentNode.children[index - 2];
|
||||
return prevPrevNode && isPrettierIgnore(prevPrevNode);
|
||||
return isPrettierIgnore(prevNode);
|
||||
}
|
||||
|
||||
function isPrettierIgnore(node) {
|
||||
return node.type === "comment" && node.data.trim() === "prettier-ignore";
|
||||
}
|
||||
|
||||
function isWhitespaceOnlyText(node) {
|
||||
return node.type === "text" && node.data.trim().length === 0;
|
||||
function isTag(node) {
|
||||
return node.type === "tag";
|
||||
}
|
||||
|
||||
function isPreTagNode(node) {
|
||||
return node.type === "tag" && node.name === "pre";
|
||||
function isScriptLikeTag(node) {
|
||||
return isTag(node) && (node.name === "script" || node.name === "style");
|
||||
}
|
||||
|
||||
function isTextAreaTagNode(node) {
|
||||
return node.type === "tag" && node.name === "textarea";
|
||||
function isFrontMatterNode(node) {
|
||||
return node.type === "yaml" || node.type === "toml";
|
||||
}
|
||||
|
||||
function isScriptTagNode(node) {
|
||||
return node.type === "script" || node.type === "style";
|
||||
function isLeadingSpaceSensitiveNode(node, { prev, parent }) {
|
||||
if (isFrontMatterNode(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parent || parent.cssDisplay === "none") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!prev &&
|
||||
(parent.type === "root" ||
|
||||
isScriptLikeTag(parent) ||
|
||||
isBlockLikeCssDisplay(parent.cssDisplay))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prev && isBlockLikeCssDisplay(prev.cssDisplay)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function isTrailingSpaceSensitiveNode(node, { next, parent }) {
|
||||
if (isFrontMatterNode(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parent || parent.cssDisplay === "none") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!next &&
|
||||
(parent.type === "root" ||
|
||||
isScriptLikeTag(parent) ||
|
||||
isBlockLikeCssDisplay(parent.cssDisplay))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (next && isBlockLikeCssDisplay(next.cssDisplay)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function isDanglingSpaceSensitiveNode(node) {
|
||||
return !isBlockLikeCssDisplay(node.cssDisplay);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {unknown} node
|
||||
* @param {(node: unknown, stack: Array<string | object>)} fn
|
||||
* @param {unknown=} parent
|
||||
*/
|
||||
function mapNode(node, fn, stack = []) {
|
||||
const newNode = Object.assign({}, node);
|
||||
|
||||
if (newNode.children) {
|
||||
newNode.children = newNode.children.map((child, childIndex) =>
|
||||
mapNode(child, fn, [childIndex, node].concat(stack))
|
||||
);
|
||||
}
|
||||
|
||||
return fn(newNode, stack);
|
||||
}
|
||||
|
||||
function getPrevNode(stack) {
|
||||
const [index, parent] = stack;
|
||||
|
||||
if (typeof index !== "number" || index === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return parent.children[index - 1];
|
||||
}
|
||||
|
||||
function replaceNewlines(text, replacement) {
|
||||
return text
|
||||
.split(/(\n)/g)
|
||||
.map((data, index) => (index % 2 === 1 ? replacement : data));
|
||||
}
|
||||
|
||||
function replaceDocNewlines(doc, replacement) {
|
||||
return mapDoc(
|
||||
doc,
|
||||
currentDoc =>
|
||||
typeof currentDoc === "string" && currentDoc.includes("\n")
|
||||
? concat(replaceNewlines(currentDoc, replacement))
|
||||
: currentDoc
|
||||
);
|
||||
}
|
||||
|
||||
function forceNextEmptyLine(node) {
|
||||
return isFrontMatterNode(node);
|
||||
}
|
||||
|
||||
/** firstChild leadingSpaces and lastChild trailingSpaces */
|
||||
function forceBreakContent(node) {
|
||||
return (
|
||||
forceBreakChildren(node) ||
|
||||
(isTag(node) &&
|
||||
node.children.length !== 0 &&
|
||||
(["body", "template"].indexOf(node.name) !== -1 ||
|
||||
node.children.some(child => hasNonTextChild(child))))
|
||||
);
|
||||
}
|
||||
|
||||
/** spaces between children */
|
||||
function forceBreakChildren(node) {
|
||||
return (
|
||||
isTag(node) &&
|
||||
node.children.length !== 0 &&
|
||||
(["html", "head", "ul", "ol", "select"].indexOf(node.name) !== -1 ||
|
||||
(node.cssDisplay.startsWith("table") && node.cssDisplay !== "table-cell"))
|
||||
);
|
||||
}
|
||||
|
||||
function preferHardlineAsLeadingSpaces(node) {
|
||||
return (
|
||||
preferHardlineAsSurroundingSpaces(node) ||
|
||||
(node.prev && preferHardlineAsTrailingSpaces(node.prev))
|
||||
);
|
||||
}
|
||||
|
||||
function preferHardlineAsTrailingSpaces(node) {
|
||||
return (
|
||||
preferHardlineAsSurroundingSpaces(node) ||
|
||||
(isTag(node) && node.name === "br")
|
||||
);
|
||||
}
|
||||
|
||||
function preferHardlineAsSurroundingSpaces(node) {
|
||||
switch (node.type) {
|
||||
case "ieConditionalComment":
|
||||
case "comment":
|
||||
case "directive":
|
||||
return true;
|
||||
case "tag":
|
||||
return ["script", "select"].indexOf(node.name) !== -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getLastDescendant(node) {
|
||||
return node.lastChild ? getLastDescendant(node.lastChild) : node;
|
||||
}
|
||||
|
||||
function hasNonTextChild(node) {
|
||||
return node.children && node.children.some(child => child.type !== "text");
|
||||
}
|
||||
|
||||
function inferScriptParser(node) {
|
||||
if (
|
||||
node.name === "script" &&
|
||||
((!node.attribs.lang && !node.attribs.type) ||
|
||||
node.attribs.type === "text/javascript" ||
|
||||
node.attribs.type === "text/babel" ||
|
||||
node.attribs.type === "application/javascript")
|
||||
) {
|
||||
return "babylon";
|
||||
}
|
||||
|
||||
if (
|
||||
node.name === "script" &&
|
||||
(node.attribs.type === "application/x-typescript" ||
|
||||
node.attribs.lang === "ts")
|
||||
) {
|
||||
return "typescript";
|
||||
}
|
||||
|
||||
if (node.name === "style") {
|
||||
return "css";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* firstChild leadingSpaces, lastChild trailingSpaces, and danglingSpaces are insensitive
|
||||
*/
|
||||
function isBlockLikeCssDisplay(cssDisplay) {
|
||||
return cssDisplay === "block" || cssDisplay.startsWith("table");
|
||||
}
|
||||
|
||||
function getNodeCssStyleDisplay(node, prevNode, options) {
|
||||
switch (getNodeCssStyleWhiteSpace(node)) {
|
||||
case "pre":
|
||||
case "pre-wrap":
|
||||
// textarea-like
|
||||
return "block";
|
||||
}
|
||||
|
||||
if (prevNode && prevNode.type === "comment") {
|
||||
// <!-- display: block -->
|
||||
const match = prevNode.data.match(/^\s*display:\s*([a-z]+)\s*$/);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
}
|
||||
|
||||
switch (options.htmlWhitespaceSensitivity) {
|
||||
case "strict":
|
||||
return "inline";
|
||||
case "ignore":
|
||||
return "block";
|
||||
default:
|
||||
return (
|
||||
(isTag(node) && CSS_DISPLAY_TAGS[node.name]) || CSS_DISPLAY_DEFAULT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getNodeCssStyleWhiteSpace(node) {
|
||||
return (
|
||||
(isTag(node) && CSS_WHITE_SPACE_TAGS[node.name]) || CSS_WHITE_SPACE_DEFAULT
|
||||
);
|
||||
}
|
||||
|
||||
function getCommentData(node) {
|
||||
const rightTrimmedData = node.data.trimRight();
|
||||
|
||||
const hasLeadingEmptyLine = /^[^\S\n]*?\n/.test(node.data);
|
||||
if (hasLeadingEmptyLine) {
|
||||
/**
|
||||
* <!--
|
||||
* 123
|
||||
* 456
|
||||
* -->
|
||||
*/
|
||||
return dedentString(rightTrimmedData.replace(/^\s*\n/, ""));
|
||||
}
|
||||
|
||||
/**
|
||||
* <!-- 123 -->
|
||||
*
|
||||
* <!-- 123
|
||||
* -->
|
||||
*
|
||||
* <!-- 123
|
||||
*
|
||||
* -->
|
||||
*/
|
||||
if (!rightTrimmedData.includes("\n")) {
|
||||
return rightTrimmedData.trimLeft();
|
||||
}
|
||||
|
||||
const firstNewlineIndex = rightTrimmedData.indexOf("\n");
|
||||
const dataWithoutLeadingLine = rightTrimmedData.slice(firstNewlineIndex + 1);
|
||||
const minIndentationForDataWithoutLeadingLine = getMinIndentation(
|
||||
dataWithoutLeadingLine
|
||||
);
|
||||
|
||||
const commentDataStartColumn = node.startLocation.column + "<!--".length;
|
||||
|
||||
/**
|
||||
* <!-- 123
|
||||
* 456 -->
|
||||
*/
|
||||
if (minIndentationForDataWithoutLeadingLine >= commentDataStartColumn) {
|
||||
return dedentString(
|
||||
" ".repeat(commentDataStartColumn) + "\n" + rightTrimmedData
|
||||
);
|
||||
}
|
||||
|
||||
const leadingLineData = rightTrimmedData.slice(0, firstNewlineIndex);
|
||||
/**
|
||||
* <!-- 123
|
||||
* 456 -->
|
||||
*/
|
||||
return (
|
||||
leadingLineData.trim() +
|
||||
"\n" +
|
||||
dedentString(
|
||||
dataWithoutLeadingLine,
|
||||
minIndentationForDataWithoutLeadingLine
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getMinIndentation(text) {
|
||||
let minIndentation = Infinity;
|
||||
|
||||
for (const lineText of text.split("\n")) {
|
||||
if (/\S/.test(lineText[0])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const indentation = lineText.match(/^\s*/)[0].length;
|
||||
|
||||
if (lineText.length === indentation) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (indentation < minIndentation) {
|
||||
minIndentation = indentation;
|
||||
}
|
||||
}
|
||||
|
||||
return minIndentation === Infinity ? 0 : minIndentation;
|
||||
}
|
||||
|
||||
function dedentString(text, minIndent = getMinIndentation(text)) {
|
||||
return minIndent === 0
|
||||
? text
|
||||
: text
|
||||
.split("\n")
|
||||
.map(lineText => lineText.slice(minIndent))
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
function normalizeParts(parts) {
|
||||
const newParts = [];
|
||||
|
||||
for (const part of parts) {
|
||||
if (!part) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
newParts.length !== 0 &&
|
||||
typeof newParts[newParts.length - 1] === "string" &&
|
||||
typeof part === "string"
|
||||
) {
|
||||
newParts.push(newParts.pop() + part);
|
||||
continue;
|
||||
}
|
||||
|
||||
newParts.push(part);
|
||||
}
|
||||
|
||||
return newParts;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
HTML_ELEMENT_ATTRIBUTES,
|
||||
HTML_TAGS,
|
||||
VOID_TAGS,
|
||||
dedentString,
|
||||
forceBreakChildren,
|
||||
forceBreakContent,
|
||||
forceNextEmptyLine,
|
||||
getCommentData,
|
||||
getLastDescendant,
|
||||
getNodeCssStyleDisplay,
|
||||
getNodeCssStyleWhiteSpace,
|
||||
getPrevNode,
|
||||
hasPrettierIgnore,
|
||||
isPreTagNode,
|
||||
isScriptTagNode,
|
||||
isTextAreaTagNode,
|
||||
isWhitespaceOnlyText
|
||||
inferScriptParser,
|
||||
isDanglingSpaceSensitiveNode,
|
||||
isFrontMatterNode,
|
||||
isLeadingSpaceSensitiveNode,
|
||||
isScriptLikeTag,
|
||||
isTrailingSpaceSensitiveNode,
|
||||
mapNode,
|
||||
normalizeParts,
|
||||
preferHardlineAsLeadingSpaces,
|
||||
preferHardlineAsTrailingSpaces,
|
||||
replaceDocNewlines,
|
||||
replaceNewlines
|
||||
};
|
||||
|
|
|
@ -61,6 +61,22 @@ and HTML5 Apps. It also documents Mozilla products, like Firefox OS.">
|
|||
|
||||
|
||||
</article>
|
||||
<X>
|
||||
</X>
|
||||
<X a="1">
|
||||
</X>
|
||||
<X a="1" b="2">
|
||||
</X>
|
||||
<X a="1" b="2" c="3">
|
||||
</X>
|
||||
<p
|
||||
class="
|
||||
foo
|
||||
bar
|
||||
baz
|
||||
"
|
||||
>
|
||||
</p>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<input name="address" maxlength="200" />
|
||||
<input name="address" maxlength="200" />
|
||||
|
@ -96,8 +112,7 @@ and HTML5 Apps. It also documents Mozilla products, like Firefox OS."
|
|||
data-columns="3"
|
||||
data-index-number="12314"
|
||||
data-parent="cars"
|
||||
>
|
||||
</article>
|
||||
></article>
|
||||
<article
|
||||
id="electriccars"
|
||||
data-columns="3"
|
||||
|
@ -119,15 +134,21 @@ and HTML5 Apps. It also documents Mozilla products, like Firefox OS."
|
|||
data-columns="3"
|
||||
data-index-number="12314"
|
||||
data-parent="cars"
|
||||
>
|
||||
</article>
|
||||
></article>
|
||||
<article
|
||||
id="electriccars"
|
||||
data-columns="3"
|
||||
data-index-number="12314"
|
||||
data-parent="cars"
|
||||
>
|
||||
</article>
|
||||
></article>
|
||||
<X> </X> <X a="1"> </X> <X a="1" b="2"> </X> <X a="1" b="2" c="3"> </X>
|
||||
<p
|
||||
class="
|
||||
foo
|
||||
bar
|
||||
baz
|
||||
"
|
||||
></p>
|
||||
|
||||
`;
|
||||
|
||||
|
@ -151,42 +172,36 @@ exports[`boolean.html - html-verify 1`] = `
|
|||
<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>
|
||||
<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" />
|
||||
|
@ -208,6 +223,13 @@ exports[`dobule-quotes.html - html-verify 1`] = `
|
|||
|
||||
`;
|
||||
|
||||
exports[`duplicate.html - html-verify 1`] = `
|
||||
<a href="1" href="2">123</a>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<a href="1" href="2">123</a>
|
||||
|
||||
`;
|
||||
|
||||
exports[`single-quotes.html - html-verify 1`] = `
|
||||
<img src="test.png" alt='John "ShotGun" Nelson'>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -58,3 +58,19 @@ and HTML5 Apps. It also documents Mozilla products, like Firefox OS.">
|
|||
|
||||
|
||||
</article>
|
||||
<X>
|
||||
</X>
|
||||
<X a="1">
|
||||
</X>
|
||||
<X a="1" b="2">
|
||||
</X>
|
||||
<X a="1" b="2" c="3">
|
||||
</X>
|
||||
<p
|
||||
class="
|
||||
foo
|
||||
bar
|
||||
baz
|
||||
"
|
||||
>
|
||||
</p>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<a href="1" href="2">123</a>
|
|
@ -3,7 +3,7 @@
|
|||
exports[`comment.html - html-verify 1`] = `
|
||||
<!--hello world-->
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<!--hello world-->
|
||||
<!-- hello world -->
|
||||
|
||||
`;
|
||||
|
||||
|
@ -107,9 +107,9 @@ exports[`form.html - html-verify 1`] = `
|
|||
aria-describedby="emailHelp"
|
||||
placeholder="Enter email"
|
||||
/>
|
||||
<small id="emailHelp" class="form-text text-muted">
|
||||
We'll never share your email with anyone else.
|
||||
</small>
|
||||
<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>
|
||||
|
@ -152,9 +152,10 @@ exports[`form.html - html-verify 1`] = `
|
|||
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>
|
||||
<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>
|
||||
|
@ -180,7 +181,8 @@ exports[`form.html - html-verify 1`] = `
|
|||
id="optionsRadios2"
|
||||
value="option2"
|
||||
/>
|
||||
Option two can be something else and selecting it will deselect option one
|
||||
Option two can be something else and selecting it will deselect option
|
||||
one
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check disabled">
|
||||
|
@ -199,13 +201,10 @@ exports[`form.html - html-verify 1`] = `
|
|||
</fieldset>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input type="checkbox" class="form-check-input" />
|
||||
Check me out
|
||||
<input type="checkbox" class="form-check-input" /> Check me out
|
||||
</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Submit
|
||||
</button>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</form>
|
||||
|
||||
`;
|
||||
|
@ -336,7 +335,11 @@ exports[`html5-boilerplate.html - html-verify 1`] = `
|
|||
|
||||
<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>
|
||||
<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 -->
|
||||
|
@ -348,21 +351,21 @@ exports[`html5-boilerplate.html - html-verify 1`] = `
|
|||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script>
|
||||
window.jQuery ||
|
||||
document.write('<script src="js/vendor/jquery-3.3.1.min.js"></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");
|
||||
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"
|
||||
|
|
|
@ -31,13 +31,13 @@ exports[`case.html - html-verify 1`] = `
|
|||
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");
|
||||
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"
|
||||
|
|
|
@ -1,5 +1,40 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`before-text.html - html-verify 1`] = `
|
||||
<!-- hello -->
|
||||
|
||||
123
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<!-- hello -->
|
||||
|
||||
123
|
||||
|
||||
`;
|
||||
|
||||
exports[`before-text.html - html-verify 2`] = `
|
||||
<!-- hello -->
|
||||
|
||||
123
|
||||
~
|
||||
<!--
|
||||
hello
|
||||
-->
|
||||
|
||||
123
|
||||
|
||||
`;
|
||||
|
||||
exports[`before-text.html - html-verify 3`] = `
|
||||
<!-- hello -->
|
||||
|
||||
123
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<!-- hello -->
|
||||
|
||||
123
|
||||
|
||||
`;
|
||||
|
||||
exports[`conditional.html - html-verify 1`] = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
@ -17,11 +52,90 @@ exports[`conditional.html - html-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>
|
||||
|
||||
`;
|
||||
|
||||
exports[`conditional.html - html-verify 2`] = `
|
||||
<!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>
|
||||
<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[`conditional.html - html-verify 3`] = `
|
||||
<!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>
|
||||
<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>
|
||||
|
||||
|
@ -50,17 +164,104 @@ exports[`for_debugging.html - html-verify 1`] = `
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<!-- Do not display this at the moment
|
||||
<!--
|
||||
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[`for_debugging.html - html-verify 2`] = `
|
||||
<!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
|
||||
<!-- 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>
|
||||
<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[`for_debugging.html - html-verify 3`] = `
|
||||
<!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>
|
||||
<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>
|
||||
|
||||
|
@ -84,13 +285,348 @@ exports[`hidden.html - html-verify 1`] = `
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<!--This is a comment-->
|
||||
<!-- This is a comment -->
|
||||
<!-- This is a comment -->
|
||||
<!-- 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>
|
||||
|
||||
`;
|
||||
|
||||
exports[`hidden.html - html-verify 2`] = `
|
||||
<!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>
|
||||
<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>
|
||||
|
||||
`;
|
||||
|
||||
exports[`hidden.html - html-verify 3`] = `
|
||||
<!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>
|
||||
<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>
|
||||
|
||||
`;
|
||||
|
||||
exports[`surrounding-empty-line.html - html-verify 1`] = `
|
||||
<ul><!-- 123
|
||||
--><li>First</li><!-- 123
|
||||
456
|
||||
789
|
||||
--><li>Second</li><!--
|
||||
|
||||
|
||||
123
|
||||
456
|
||||
789
|
||||
|
||||
|
||||
--><li>Second</li><!--
|
||||
|
||||
|
||||
123
|
||||
456
|
||||
789
|
||||
|
||||
|
||||
--></ul>
|
||||
<span><!--
|
||||
--><span>a</span><!--
|
||||
--><span>b</span><!--
|
||||
--></span>
|
||||
|
||||
<span><!-- 1
|
||||
--><span>a</span><!-- 2
|
||||
--><span>b</span><!-- 3
|
||||
--></span>
|
||||
|
||||
<span><!--
|
||||
1 --><span>a</span><!--
|
||||
2 --><span>b</span><!--
|
||||
3 --></span>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<ul>
|
||||
<!-- 123
|
||||
--><li>First</li
|
||||
><!--
|
||||
123
|
||||
456
|
||||
789
|
||||
--><li>Second</li
|
||||
><!--
|
||||
123
|
||||
456
|
||||
789
|
||||
--><li>Second</li
|
||||
><!--
|
||||
123
|
||||
456
|
||||
789
|
||||
-->
|
||||
</ul>
|
||||
<span
|
||||
><!--
|
||||
--><span>a</span
|
||||
><!--
|
||||
--><span>b</span
|
||||
><!--
|
||||
--></span>
|
||||
|
||||
<span
|
||||
><!-- 1
|
||||
--><span>a</span
|
||||
><!-- 2
|
||||
--><span>b</span
|
||||
><!-- 3
|
||||
--></span>
|
||||
|
||||
<span
|
||||
><!-- 1
|
||||
--><span>a</span
|
||||
><!-- 2
|
||||
--><span>b</span
|
||||
><!-- 3
|
||||
--></span>
|
||||
|
||||
`;
|
||||
|
||||
exports[`surrounding-empty-line.html - html-verify 2`] = `
|
||||
<ul><!-- 123
|
||||
--><li>First</li><!-- 123
|
||||
456
|
||||
789
|
||||
--><li>Second</li><!--
|
||||
|
||||
|
||||
123
|
||||
456
|
||||
789
|
||||
|
||||
|
||||
--><li>Second</li><!--
|
||||
|
||||
|
||||
123
|
||||
456
|
||||
789
|
||||
|
||||
|
||||
--></ul>
|
||||
<span><!--
|
||||
--><span>a</span><!--
|
||||
--><span>b</span><!--
|
||||
--></span>
|
||||
|
||||
<span><!-- 1
|
||||
--><span>a</span><!-- 2
|
||||
--><span>b</span><!-- 3
|
||||
--></span>
|
||||
|
||||
<span><!--
|
||||
1 --><span>a</span><!--
|
||||
2 --><span>b</span><!--
|
||||
3 --></span>
|
||||
~
|
||||
<ul>
|
||||
<!--
|
||||
123
|
||||
--><li
|
||||
>First</li
|
||||
><!--
|
||||
123
|
||||
456
|
||||
789
|
||||
--><li
|
||||
>Second</li
|
||||
><!--
|
||||
123
|
||||
456
|
||||
789
|
||||
--><li
|
||||
>Second</li
|
||||
><!--
|
||||
123
|
||||
456
|
||||
789
|
||||
-->
|
||||
</ul>
|
||||
<span
|
||||
><!--
|
||||
--><span
|
||||
>a</span
|
||||
><!--
|
||||
--><span
|
||||
>b</span
|
||||
><!--
|
||||
--></span>
|
||||
|
||||
<span
|
||||
><!--
|
||||
1
|
||||
--><span
|
||||
>a</span
|
||||
><!--
|
||||
2
|
||||
--><span
|
||||
>b</span
|
||||
><!--
|
||||
3
|
||||
--></span>
|
||||
|
||||
<span
|
||||
><!--
|
||||
1
|
||||
--><span
|
||||
>a</span
|
||||
><!--
|
||||
2
|
||||
--><span
|
||||
>b</span
|
||||
><!--
|
||||
3
|
||||
--></span>
|
||||
|
||||
`;
|
||||
|
||||
exports[`surrounding-empty-line.html - html-verify 3`] = `
|
||||
<ul><!-- 123
|
||||
--><li>First</li><!-- 123
|
||||
456
|
||||
789
|
||||
--><li>Second</li><!--
|
||||
|
||||
|
||||
123
|
||||
456
|
||||
789
|
||||
|
||||
|
||||
--><li>Second</li><!--
|
||||
|
||||
|
||||
123
|
||||
456
|
||||
789
|
||||
|
||||
|
||||
--></ul>
|
||||
<span><!--
|
||||
--><span>a</span><!--
|
||||
--><span>b</span><!--
|
||||
--></span>
|
||||
|
||||
<span><!-- 1
|
||||
--><span>a</span><!-- 2
|
||||
--><span>b</span><!-- 3
|
||||
--></span>
|
||||
|
||||
<span><!--
|
||||
1 --><span>a</span><!--
|
||||
2 --><span>b</span><!--
|
||||
3 --></span>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<ul>
|
||||
<!-- 123
|
||||
--><li>First</li
|
||||
><!--
|
||||
123
|
||||
456
|
||||
789
|
||||
--><li>Second</li
|
||||
><!--
|
||||
123
|
||||
456
|
||||
789
|
||||
--><li>Second</li
|
||||
><!--
|
||||
123
|
||||
456
|
||||
789
|
||||
-->
|
||||
</ul>
|
||||
<span
|
||||
><!--
|
||||
--><span>a</span
|
||||
><!--
|
||||
--><span>b</span
|
||||
><!--
|
||||
--></span>
|
||||
|
||||
<span
|
||||
><!-- 1
|
||||
--><span>a</span
|
||||
><!-- 2
|
||||
--><span>b</span
|
||||
><!-- 3
|
||||
--></span>
|
||||
|
||||
<span
|
||||
><!-- 1
|
||||
--><span>a</span
|
||||
><!-- 2
|
||||
--><span>b</span
|
||||
><!-- 3
|
||||
--></span>
|
||||
|
||||
`;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<!-- hello -->
|
||||
|
||||
123
|
|
@ -1 +1,3 @@
|
|||
run_spec(__dirname, ["html"]);
|
||||
run_spec(__dirname, ["html"], { printWidth: 1 });
|
||||
run_spec(__dirname, ["html"], { printWidth: 999 });
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<ul><!-- 123
|
||||
--><li>First</li><!-- 123
|
||||
456
|
||||
789
|
||||
--><li>Second</li><!--
|
||||
|
||||
|
||||
123
|
||||
456
|
||||
789
|
||||
|
||||
|
||||
--><li>Second</li><!--
|
||||
|
||||
|
||||
123
|
||||
456
|
||||
789
|
||||
|
||||
|
||||
--></ul>
|
||||
<span><!--
|
||||
--><span>a</span><!--
|
||||
--><span>b</span><!--
|
||||
--></span>
|
||||
|
||||
<span><!-- 1
|
||||
--><span>a</span><!-- 2
|
||||
--><span>b</span><!-- 3
|
||||
--></span>
|
||||
|
||||
<span><!--
|
||||
1 --><span>a</span><!--
|
||||
2 --><span>b</span><!--
|
||||
3 --></span>
|
|
@ -27,21 +27,21 @@ exports[`less.html - html-verify 1`] = `
|
|||
</style>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<style type="text/less">
|
||||
@nice-blue: #5B83AD;
|
||||
@light-blue: @nice-blue + #111;
|
||||
@nice-blue: #5B83AD;
|
||||
@light-blue: @nice-blue + #111;
|
||||
|
||||
#header {
|
||||
color: @light-blue;
|
||||
}
|
||||
#header {
|
||||
color: @light-blue;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
@nice-blue: #5B83AD;
|
||||
@light-blue: @nice-blue + #111;
|
||||
@nice-blue: #5B83AD;
|
||||
@light-blue: @nice-blue + #111;
|
||||
|
||||
#header {
|
||||
color: @light-blue;
|
||||
}
|
||||
#header {
|
||||
color: @light-blue;
|
||||
}
|
||||
</style>
|
||||
|
||||
`;
|
||||
|
@ -56,17 +56,17 @@ exports[`postcss.html - html-verify 1`] = `
|
|||
</style>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: navy;
|
||||
color: yellow;
|
||||
}
|
||||
body {
|
||||
background: navy;
|
||||
color: yellow;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="postcss">
|
||||
body {
|
||||
background: navy;
|
||||
color: yellow;
|
||||
}
|
||||
body {
|
||||
background: navy;
|
||||
color: yellow;
|
||||
}
|
||||
</style>
|
||||
|
||||
`;
|
||||
|
@ -93,23 +93,23 @@ exports[`scss.html - html-verify 1`] = `
|
|||
</style>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<style type="text/x-scss">
|
||||
$font-stack: Helvetica, sans-serif;
|
||||
$primary-color: #333;
|
||||
$font-stack: Helvetica, sans-serif;
|
||||
$primary-color: #333;
|
||||
|
||||
body {
|
||||
font: 100% $font-stack;
|
||||
color: $primary-color;
|
||||
}
|
||||
body {
|
||||
font: 100% $font-stack;
|
||||
color: $primary-color;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
$font-stack: Helvetica, sans-serif;
|
||||
$primary-color: #333;
|
||||
$font-stack: Helvetica, sans-serif;
|
||||
$primary-color: #333;
|
||||
|
||||
body {
|
||||
font: 100% $font-stack;
|
||||
color: $primary-color;
|
||||
}
|
||||
body {
|
||||
font: 100% $font-stack;
|
||||
color: $primary-color;
|
||||
}
|
||||
</style>
|
||||
|
||||
`;
|
||||
|
@ -135,15 +135,15 @@ exports[`simple.html - html-verify 1`] = `
|
|||
<head>
|
||||
<title>Sample styled page</title>
|
||||
<style>
|
||||
a {
|
||||
color: red;
|
||||
}
|
||||
a {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
background: navy;
|
||||
color: yellow;
|
||||
}
|
||||
body {
|
||||
background: navy;
|
||||
color: yellow;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -165,16 +165,16 @@ exports[`single-style.html - html-verify 1`] = `
|
|||
</style>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<style>
|
||||
a {
|
||||
color: red;
|
||||
}
|
||||
a {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
h1 {
|
||||
font-size: 120%;
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
color: #333366;
|
||||
}
|
||||
h1 {
|
||||
font-size: 120%;
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
color: #333366;
|
||||
}
|
||||
</style>
|
||||
|
||||
`;
|
||||
|
|
|
@ -152,9 +152,7 @@ exports[`xhtml1.1.html - html-verify 1`] = `
|
|||
Bar<br />
|
||||
Foo
|
||||
</p>
|
||||
<p align="center">
|
||||
<em>String</em>
|
||||
</p>
|
||||
<p align="center"><em>String</em></p>
|
||||
<br />
|
||||
<hr />
|
||||
</body>
|
||||
|
|
|
@ -28,22 +28,22 @@ exports[`js.html - html-verify 1`] = `
|
|||
</script>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<script type="text/javascript">
|
||||
var message = "Alert!";
|
||||
var message = "Alert!";
|
||||
|
||||
alert(message);
|
||||
alert(message);
|
||||
</script>
|
||||
<script type="application/javascript">
|
||||
var message = "Alert!";
|
||||
var message = "Alert!";
|
||||
|
||||
alert(message);
|
||||
alert(message);
|
||||
</script>
|
||||
<script>
|
||||
var message = "Alert!";
|
||||
var message = "Alert!";
|
||||
|
||||
alert(message);
|
||||
alert(message);
|
||||
</script>
|
||||
<script type="text/babel">
|
||||
const someJS = "this should be formatted";
|
||||
const someJS = "this should be formatted";
|
||||
</script>
|
||||
|
||||
`;
|
||||
|
@ -71,12 +71,12 @@ exports[`simple.html - html-verify 1`] = `
|
|||
<head>
|
||||
<title>Sample styled page</title>
|
||||
<script>
|
||||
alert("test");
|
||||
alert("test");
|
||||
</script>
|
||||
<script>
|
||||
var message = "Alert!";
|
||||
var message = "Alert!";
|
||||
|
||||
alert(message);
|
||||
alert(message);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -94,10 +94,10 @@ exports[`single-script.html - html-verify 1`] = `
|
|||
</script>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<script>
|
||||
alert("test");
|
||||
alert("test");
|
||||
</script>
|
||||
<script>
|
||||
document.getElementById("demo").innerHTML = "Hello JavaScript!";
|
||||
document.getElementById("demo").innerHTML = "Hello JavaScript!";
|
||||
</script>
|
||||
|
||||
`;
|
||||
|
@ -109,8 +109,8 @@ exports[`something-else.html - html-verify 1`] = `
|
|||
</script>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<script type="text/template">
|
||||
<div>
|
||||
</div>
|
||||
<div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
`;
|
||||
|
@ -196,54 +196,54 @@ exports[`typescript.html - html-verify 1`] = `
|
|||
</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;
|
||||
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;
|
||||
}
|
||||
interface Person {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
}
|
||||
|
||||
function greeter(person: Person) {
|
||||
return "Hello, " + person.firstName + " " + person.lastName;
|
||||
}
|
||||
function greeter(person: Person) {
|
||||
return "Hello, " + person.firstName + " " + person.lastName;
|
||||
}
|
||||
|
||||
let user = new Student("Jane", "M.", "User");
|
||||
let user = new Student("Jane", "M.", "User");
|
||||
|
||||
document.body.innerHTML = greeter(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;
|
||||
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;
|
||||
}
|
||||
interface Person {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
}
|
||||
|
||||
function greeter(person: Person) {
|
||||
return "Hello, " + person.firstName + " " + person.lastName;
|
||||
}
|
||||
function greeter(person: Person) {
|
||||
return "Hello, " + person.firstName + " " + person.lastName;
|
||||
}
|
||||
|
||||
let user = new Student("Jane", "M.", "User");
|
||||
let user = new Student("Jane", "M.", "User");
|
||||
|
||||
document.body.innerHTML = greeter(user);
|
||||
document.body.innerHTML = greeter(user);
|
||||
</script>
|
||||
<script lang="tsx">
|
||||
class CommentBox extends React.Component<{ url: string, pollInterval: number}, CommentData> {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`display.html - html-verify 1`] = `
|
||||
<div>
|
||||
<!-- display: inline -->
|
||||
<p>Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long</p>
|
||||
</div>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<div>
|
||||
<!-- display: inline -->
|
||||
<p
|
||||
>Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long
|
||||
Long Long Long</p
|
||||
>
|
||||
</div>
|
||||
|
||||
`;
|
|
@ -0,0 +1,4 @@
|
|||
<div>
|
||||
<!-- display: inline -->
|
||||
<p>Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long</p>
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
run_spec(__dirname, ["html"]);
|
|
@ -0,0 +1,25 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`standalone-end-marker.html - html-verify 1`] = `
|
||||
<div></div
|
||||
>
|
||||
<span></span>
|
||||
<div></div
|
||||
|
||||
|
||||
>
|
||||
<span></span>
|
||||
<div></div
|
||||
>
|
||||
|
||||
<span></span>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<div></div>
|
||||
<span></span>
|
||||
<div></div>
|
||||
<span></span>
|
||||
<div></div>
|
||||
|
||||
<span></span>
|
||||
|
||||
`;
|
|
@ -0,0 +1 @@
|
|||
run_spec(__dirname, ["html"]);
|
|
@ -0,0 +1,12 @@
|
|||
<div></div
|
||||
>
|
||||
<span></span>
|
||||
<div></div
|
||||
|
||||
|
||||
>
|
||||
<span></span>
|
||||
<div></div
|
||||
>
|
||||
|
||||
<span></span>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,15 @@
|
|||
<div>
|
||||
aaaaaaaaaa
|
||||
<a
|
||||
href="longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong"
|
||||
>bbbbbbbbbb</a
|
||||
>
|
||||
cccccccccc
|
||||
</div>
|
||||
<div>
|
||||
aaaaaaaaaa
|
||||
<a
|
||||
href="longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong"
|
||||
>bbbbbbbbbb</a
|
||||
>cccccccccc
|
||||
</div>
|
|
@ -1 +1,5 @@
|
|||
run_spec(__dirname, ["html"]);
|
||||
run_spec(__dirname, ["html"], { printWidth: 1 });
|
||||
run_spec(__dirname, ["html"], { printWidth: 999 });
|
||||
run_spec(__dirname, ["html"], { htmlWhitespaceSensitivity: "strict" });
|
||||
run_spec(__dirname, ["html"], { htmlWhitespaceSensitivity: "ignore" });
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<p
|
||||
>Want to write us a letter? Use our<a
|
||||
><b
|
||||
><a>mailing address</a></b
|
||||
></a
|
||||
>.</p
|
||||
>
|
||||
|
||||
<p
|
||||
>Want to write us a letter? Use our<a
|
||||
href="contacts.html#Mailing_address"
|
||||
><b
|
||||
><a>mailing address</a></b
|
||||
></a
|
||||
>.</p
|
||||
>
|
||||
|
||||
<p
|
||||
>Want to write us a letter? Use our<a
|
||||
href="contacts.html#Mailing_address"
|
||||
href1="contacts.html#Mailing_address"
|
||||
href2="contacts.html#Mailing_address"
|
||||
href3="contacts.html#Mailing_address"
|
||||
href4="contacts.html#Mailing_address"
|
||||
><b
|
||||
><a>mailing address</a></b
|
||||
></a
|
||||
>.</p
|
||||
>
|
|
@ -47,3 +47,15 @@
|
|||
<div>string</div>
|
||||
|
||||
</div>
|
||||
<ul
|
||||
>123<li
|
||||
class="foo"
|
||||
id="bar"
|
||||
>First</li
|
||||
>456<li
|
||||
class="baz"
|
||||
>Second</li
|
||||
>789</ul
|
||||
>
|
||||
<span>*<b>200</b></span>
|
||||
<img src="longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong" />123
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`break-tags.html - html-verify 1`] = `
|
||||
<a>Lorem</a>, ispum dolor sit <strong>amet</strong>.
|
||||
<div><a>Lorem</a>, ispum dolor sit <strong>amet</strong>.</div>
|
||||
<div><div><a>Lorem</a>, ispum dolor sit <strong>amet</strong>.</div></div>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<a>Lorem</a>, ispum dolor sit <strong>amet</strong>.
|
||||
<div><a>Lorem</a>, ispum dolor sit <strong>amet</strong>.</div>
|
||||
<div>
|
||||
<div><a>Lorem</a>, ispum dolor sit <strong>amet</strong>.</div>
|
||||
</div>
|
||||
|
||||
`;
|
||||
|
||||
exports[`display-none.html - html-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></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>
|
||||
</html>
|
||||
|
||||
`;
|
||||
|
||||
exports[`fill.html - html-verify 1`] = `
|
||||
<p>
|
||||
<img
|
||||
src="/images/pansies.jpg"
|
||||
alt="about fedco bottom image"
|
||||
style="float: left;"
|
||||
/><strong>We are a cooperative</strong>, one of the few seed companies so organized
|
||||
in the United States. Because we do not have an individual owner or beneficiary,
|
||||
profit is not our primary goal. Consumers own 60% of the cooperative and worker
|
||||
members 40%. Consumer and worker members share proportionately in the cooperative’s
|
||||
profits through our annual patronage dividends.
|
||||
</p>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<p>
|
||||
<img
|
||||
src="/images/pansies.jpg"
|
||||
alt="about fedco bottom image"
|
||||
style="float: left;"
|
||||
/><strong>We are a cooperative</strong>, one of the few seed companies so
|
||||
organized in the United States. Because we do not have an individual owner or
|
||||
beneficiary, profit is not our primary goal. Consumers own 60% of the
|
||||
cooperative and worker members 40%. Consumer and worker members share
|
||||
proportionately in the cooperative’s profits through our annual
|
||||
patronage dividends.
|
||||
</p>
|
||||
|
||||
`;
|
||||
|
||||
exports[`inline-leading-trailing-spaces.html - html-verify 1`] = `
|
||||
<span> 321 </span>
|
||||
|
||||
<span> <a>321</a> </span>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<span> 321 </span>
|
||||
|
||||
<span> <a>321</a> </span>
|
||||
|
||||
`;
|
||||
|
||||
exports[`inline-nodes.html - html-verify 1`] = `
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce cursus massa vel augue
|
||||
vestibulum facilisis in porta turpis. Ut faucibus lectus sit amet urna consectetur dignissim.
|
||||
Sam vitae neque quis ex dapibus faucibus at sed ligula. Nulla sit amet aliquet nibh.
|
||||
Vestibulum at congue mi. Suspendisse vitae odio vitae massa hendrerit mattis sed eget dui.
|
||||
Sed eu scelerisque neque. Donec <b>maximus</b> rhoncus pellentesque. Aenean purus turpis, vehicula
|
||||
euismod ante vel, ultricies eleifend dui. Class aptent taciti sociosqu ad litora torquent per
|
||||
conubia nostra, per inceptos himenaeos. Donec in ornare velit.</p>
|
||||
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce cursus massa vel augue
|
||||
vestibulum facilisis in porta turpis. Ut faucibus lectus sit amet urna consectetur dignissim.
|
||||
Sam vitae neque quis ex dapibus faucibus at sed ligula. Nulla sit amet aliquet nibh.
|
||||
Vestibulum at congue mi. Suspendisse vitae odio vitae massa hendrerit mattis sed eget dui.
|
||||
Sed eu scelerisque neque. Donec <a href="#"><b>maximus</b></a> rhoncus pellentesque. Aenean purus turpis, vehicula
|
||||
euismod ante vel, ultricies eleifend dui. Class aptent taciti sociosqu ad litora torquent per
|
||||
conubia nostra, per inceptos himenaeos. Donec in ornare velit.</p>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce cursus massa
|
||||
vel augue vestibulum facilisis in porta turpis. Ut faucibus lectus sit amet
|
||||
urna consectetur dignissim. Sam vitae neque quis ex dapibus faucibus at sed
|
||||
ligula. Nulla sit amet aliquet nibh. Vestibulum at congue mi. Suspendisse
|
||||
vitae odio vitae massa hendrerit mattis sed eget dui. Sed eu scelerisque
|
||||
neque. Donec <b>maximus</b> rhoncus pellentesque. Aenean purus turpis,
|
||||
vehicula euismod ante vel, ultricies eleifend dui. Class aptent taciti
|
||||
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec
|
||||
in ornare velit.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce cursus massa
|
||||
vel augue vestibulum facilisis in porta turpis. Ut faucibus lectus sit amet
|
||||
urna consectetur dignissim. Sam vitae neque quis ex dapibus faucibus at sed
|
||||
ligula. Nulla sit amet aliquet nibh. Vestibulum at congue mi. Suspendisse
|
||||
vitae odio vitae massa hendrerit mattis sed eget dui. Sed eu scelerisque
|
||||
neque. Donec <a href="#"><b>maximus</b></a> rhoncus pellentesque. Aenean purus
|
||||
turpis, vehicula euismod ante vel, ultricies eleifend dui. Class aptent taciti
|
||||
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec
|
||||
in ornare velit.
|
||||
</p>
|
||||
|
||||
`;
|
||||
|
||||
exports[`table.html - html-verify 1`] = `
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>A</th>
|
||||
<th>B</th>
|
||||
<th>C</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
||||
<table><thead><tr><th>A</th><th>B</th><th>C</th></tr></thead></table>
|
||||
|
||||
<table> <thead> <tr> <th> A </th> <th> B </th> <th> C </th> </tr> </thead> </table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>A</th>
|
||||
<th>B</th>
|
||||
<th>C</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>A</th>
|
||||
<th>B</th>
|
||||
<th>C</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>A</th>
|
||||
<th>B</th>
|
||||
<th>C</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr></tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
||||
`;
|
|
@ -0,0 +1,3 @@
|
|||
<a>Lorem</a>, ispum dolor sit <strong>amet</strong>.
|
||||
<div><a>Lorem</a>, ispum dolor sit <strong>amet</strong>.</div>
|
||||
<div><div><a>Lorem</a>, ispum dolor sit <strong>amet</strong>.</div></div>
|
|
@ -0,0 +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></HTML>
|
|
@ -0,0 +1,11 @@
|
|||
<p>
|
||||
<img
|
||||
src="/images/pansies.jpg"
|
||||
alt="about fedco bottom image"
|
||||
style="float: left;"
|
||||
/><strong>We are a cooperative</strong>, one of the few seed companies so organized
|
||||
in the United States. Because we do not have an individual owner or beneficiary,
|
||||
profit is not our primary goal. Consumers own 60% of the cooperative and worker
|
||||
members 40%. Consumer and worker members share proportionately in the cooperative’s
|
||||
profits through our annual patronage dividends.
|
||||
</p>
|
|
@ -0,0 +1,3 @@
|
|||
<span> 321 </span>
|
||||
|
||||
<span> <a>321</a> </span>
|
|
@ -0,0 +1,15 @@
|
|||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce cursus massa vel augue
|
||||
vestibulum facilisis in porta turpis. Ut faucibus lectus sit amet urna consectetur dignissim.
|
||||
Sam vitae neque quis ex dapibus faucibus at sed ligula. Nulla sit amet aliquet nibh.
|
||||
Vestibulum at congue mi. Suspendisse vitae odio vitae massa hendrerit mattis sed eget dui.
|
||||
Sed eu scelerisque neque. Donec <b>maximus</b> rhoncus pellentesque. Aenean purus turpis, vehicula
|
||||
euismod ante vel, ultricies eleifend dui. Class aptent taciti sociosqu ad litora torquent per
|
||||
conubia nostra, per inceptos himenaeos. Donec in ornare velit.</p>
|
||||
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce cursus massa vel augue
|
||||
vestibulum facilisis in porta turpis. Ut faucibus lectus sit amet urna consectetur dignissim.
|
||||
Sam vitae neque quis ex dapibus faucibus at sed ligula. Nulla sit amet aliquet nibh.
|
||||
Vestibulum at congue mi. Suspendisse vitae odio vitae massa hendrerit mattis sed eget dui.
|
||||
Sed eu scelerisque neque. Donec <a href="#"><b>maximus</b></a> rhoncus pellentesque. Aenean purus turpis, vehicula
|
||||
euismod ante vel, ultricies eleifend dui. Class aptent taciti sociosqu ad litora torquent per
|
||||
conubia nostra, per inceptos himenaeos. Donec in ornare velit.</p>
|
|
@ -0,0 +1 @@
|
|||
run_spec(__dirname, ["html"]);
|
|
@ -0,0 +1,20 @@
|
|||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>A</th>
|
||||
<th>B</th>
|
||||
<th>C</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
||||
<table><thead><tr><th>A</th><th>B</th><th>C</th></tr></thead></table>
|
||||
|
||||
<table> <thead> <tr> <th> A </th> <th> B </th> <th> C </th> </tr> </thead> </table>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
|
@ -18,9 +18,9 @@ exports[`html-with-css-style.html - html-verify 1`] = `
|
|||
<html lang="en">
|
||||
<head>
|
||||
<style>
|
||||
blink {
|
||||
display: none;
|
||||
}
|
||||
blink {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body></body>
|
||||
|
|
|
@ -17,7 +17,7 @@ exports[`html-with-js-script.html - html-verify 1`] = `
|
|||
<html lang="en">
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
hello("world");
|
||||
hello("world");
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
|
|
|
@ -26,11 +26,11 @@ exports[`html-with-ts-script.html - html-verify 1`] = `
|
|||
<html lang="en">
|
||||
<head>
|
||||
<script lang="ts">
|
||||
type X = { [K in keyof Y]: Partial<K> };
|
||||
type X = { [K in keyof Y]: Partial<K> };
|
||||
|
||||
class Foo<T> {
|
||||
constructor(private foo: keyof Apple) {}
|
||||
}
|
||||
class Foo<T> {
|
||||
constructor(private foo: keyof Apple) {}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
|
|
|
@ -60,6 +60,9 @@ Format options:
|
|||
Include parentheses around a sole arrow function parameter.
|
||||
Defaults to avoid.
|
||||
--no-bracket-spacing Do not print spaces between brackets.
|
||||
--html-whitespace-sensitivity <css|strict|ignore>
|
||||
How to handle whitespaces in HTML.
|
||||
Defaults to css.
|
||||
--jsx-bracket-same-line Put > on the last line instead of at a new line.
|
||||
Defaults to false.
|
||||
--parser <flow|babylon|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html>
|
||||
|
@ -197,6 +200,9 @@ Format options:
|
|||
Include parentheses around a sole arrow function parameter.
|
||||
Defaults to avoid.
|
||||
--no-bracket-spacing Do not print spaces between brackets.
|
||||
--html-whitespace-sensitivity <css|strict|ignore>
|
||||
How to handle whitespaces in HTML.
|
||||
Defaults to css.
|
||||
--jsx-bracket-same-line Put > on the last line instead of at a new line.
|
||||
Defaults to false.
|
||||
--parser <flow|babylon|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html>
|
||||
|
|
|
@ -138,6 +138,25 @@ exports[`show detailed usage with --help help (stdout) 1`] = `
|
|||
|
||||
exports[`show detailed usage with --help help (write) 1`] = `Array []`;
|
||||
|
||||
exports[`show detailed usage with --help html-whitespace-sensitivity (stderr) 1`] = `""`;
|
||||
|
||||
exports[`show detailed usage with --help html-whitespace-sensitivity (stdout) 1`] = `
|
||||
"--html-whitespace-sensitivity <css|strict|ignore>
|
||||
|
||||
How to handle whitespaces in HTML.
|
||||
|
||||
Valid options:
|
||||
|
||||
css Respect the default value of CSS display property.
|
||||
strict Whitespaces are considered sensitive.
|
||||
ignore Whitespaces are considered insensitive.
|
||||
|
||||
Default: css
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`show detailed usage with --help html-whitespace-sensitivity (write) 1`] = `Array []`;
|
||||
|
||||
exports[`show detailed usage with --help ignore-path (stderr) 1`] = `""`;
|
||||
|
||||
exports[`show detailed usage with --help ignore-path (stdout) 1`] = `
|
||||
|
|
|
@ -13,11 +13,11 @@ exports[` 1`] = `
|
|||
--no-bracket-spacing Do not print spaces between brackets.
|
||||
+ --foo-option <bar|baz> foo description
|
||||
+ Defaults to bar.
|
||||
--html-whitespace-sensitivity <css|strict|ignore>
|
||||
How to handle whitespaces in HTML.
|
||||
Defaults to css.
|
||||
--jsx-bracket-same-line Put > on the last line instead of at a new line.
|
||||
Defaults to false.
|
||||
--parser <flow|babylon|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html>
|
||||
Which parser to use.
|
||||
--print-width <int> The line length where Prettier will try wrap."
|
||||
Defaults to false."
|
||||
`;
|
||||
|
||||
exports[`show detailed external option with \`--help foo-option\` (stderr) 1`] = `""`;
|
||||
|
|
|
@ -48,6 +48,30 @@ This option cannot be used with --range-start and --range-end.",
|
|||
"description": "Specify the input filepath. This will be used to do parser inference.",
|
||||
"type": "string",
|
||||
},
|
||||
"htmlWhitespaceSensitivity": Object {
|
||||
"default": "css",
|
||||
"description": "How to handle whitespaces in HTML.",
|
||||
"oneOf": Array [
|
||||
Object {
|
||||
"description": "Respect the default value of CSS display property.",
|
||||
"enum": Array [
|
||||
"css",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"description": "Whitespaces are considered sensitive.",
|
||||
"enum": Array [
|
||||
"strict",
|
||||
],
|
||||
},
|
||||
Object {
|
||||
"description": "Whitespaces are considered insensitive.",
|
||||
"enum": Array [
|
||||
"ignore",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
"insertPragma": Object {
|
||||
"default": false,
|
||||
"description": "Insert @format pragma into file's first docblock comment.",
|
||||
|
|
|
@ -479,7 +479,27 @@ exports[`API getSupportInfo() with version 1.8.2 -> undefined 1`] = `
|
|||
\\"type\\": \\"boolean\\",
|
||||
},
|
||||
\\"cursorOffset\\": Object {
|
||||
@@ -73,16 +99,30 @@
|
||||
@@ -56,10 +82,19 @@
|
||||
},
|
||||
\\"filepath\\": Object {
|
||||
\\"default\\": undefined,
|
||||
\\"type\\": \\"path\\",
|
||||
},
|
||||
+ \\"htmlWhitespaceSensitivity\\": Object {
|
||||
+ \\"choices\\": Array [
|
||||
+ \\"css\\",
|
||||
+ \\"strict\\",
|
||||
+ \\"ignore\\",
|
||||
+ ],
|
||||
+ \\"default\\": \\"css\\",
|
||||
+ \\"type\\": \\"choice\\",
|
||||
+ },
|
||||
\\"insertPragma\\": Object {
|
||||
\\"default\\": false,
|
||||
\\"type\\": \\"boolean\\",
|
||||
},
|
||||
\\"jsxBracketSameLine\\": Object {
|
||||
@@ -73,16 +108,30 @@
|
||||
\\"typescript\\",
|
||||
\\"css\\",
|
||||
\\"less\\",
|
||||
|
@ -511,7 +531,7 @@ exports[`API getSupportInfo() with version 1.8.2 -> undefined 1`] = `
|
|||
\\"range\\": Object {
|
||||
\\"end\\": Infinity,
|
||||
\\"start\\": 0,
|
||||
@@ -90,14 +130,15 @@
|
||||
@@ -90,14 +139,15 @@
|
||||
},
|
||||
\\"type\\": \\"int\\",
|
||||
},
|
||||
|
@ -931,6 +951,29 @@ exports[`CLI --support-info (stdout) 1`] = `
|
|||
\\"since\\": \\"1.4.0\\",
|
||||
\\"type\\": \\"path\\"
|
||||
},
|
||||
{
|
||||
\\"category\\": \\"HTML\\",
|
||||
\\"choices\\": [
|
||||
{
|
||||
\\"description\\": \\"Respect the default value of CSS display property.\\",
|
||||
\\"value\\": \\"css\\"
|
||||
},
|
||||
{
|
||||
\\"description\\": \\"Whitespaces are considered sensitive.\\",
|
||||
\\"value\\": \\"strict\\"
|
||||
},
|
||||
{
|
||||
\\"description\\": \\"Whitespaces are considered insensitive.\\",
|
||||
\\"value\\": \\"ignore\\"
|
||||
}
|
||||
],
|
||||
\\"default\\": \\"css\\",
|
||||
\\"description\\": \\"How to handle whitespaces in HTML.\\",
|
||||
\\"name\\": \\"htmlWhitespaceSensitivity\\",
|
||||
\\"pluginDefaults\\": {},
|
||||
\\"since\\": \\"1.15.0\\",
|
||||
\\"type\\": \\"choice\\"
|
||||
},
|
||||
{
|
||||
\\"category\\": \\"Special\\",
|
||||
\\"default\\": false,
|
||||
|
|
|
@ -20,6 +20,7 @@ const CATEGORIES_ORDER = [
|
|||
"Common",
|
||||
"JavaScript",
|
||||
"Markdown",
|
||||
"HTML",
|
||||
"Special"
|
||||
];
|
||||
const ENABLED_OPTIONS = [
|
||||
|
@ -34,6 +35,7 @@ const ENABLED_OPTIONS = [
|
|||
"arrowParens",
|
||||
"trailingComma",
|
||||
"proseWrap",
|
||||
"htmlWhitespaceSensitivity",
|
||||
"insertPragma",
|
||||
"requirePragma"
|
||||
];
|
||||
|
|
|
@ -3184,6 +3184,10 @@ html-encoding-sniffer@^1.0.2:
|
|||
dependencies:
|
||||
whatwg-encoding "^1.0.1"
|
||||
|
||||
html-styles@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/html-styles/-/html-styles-1.0.0.tgz#a18061fd651f99c6b75c45c8e0549a3bc3e01a75"
|
||||
|
||||
html-tag-names@1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/html-tag-names/-/html-tag-names-1.1.2.tgz#f65168964c5a9c82675efda882875dcb2a875c22"
|
||||
|
@ -4392,7 +4396,7 @@ levn@^0.3.0, levn@~0.3.0:
|
|||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
|
||||
lines-and-columns@^1.1.6:
|
||||
lines-and-columns@1.1.6, lines-and-columns@^1.1.6:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
|
||||
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
|
||||
|
|
Loading…
Reference in New Issue