Commit c93c63b1 authored by David Sveningsson's avatar David Sveningsson

feat(rules): new rule `void-content`

refs #58
parent 9ede2907
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`docs/rules/void-content.md inline validation: correct 1`] = `Array []`;
exports[`docs/rules/void-content.md inline validation: incorrect 1`] = `
Array [
Object {
"errorCount": 1,
"filePath": "inline",
"messages": Array [
Object {
"column": 7,
"context": "img",
"line": 1,
"message": "End tag for <img> must be omitted",
"offset": 6,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 4,
},
],
"source": "<img></img>",
"warningCount": 0,
},
]
`;
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`docs/rules/void-content.md inline validation: correct 1`] = `Array []`;
exports[`docs/rules/void-content.md inline validation: incorrect 1`] = `
Array [
Object {
"errorCount": 1,
"filePath": "inline",
"messages": Array [
Object {
"column": 7,
"context": "img",
"line": 1,
"message": "End tag for <img> must be omitted",
"offset": 6,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 4,
},
],
"source": "<img></img>
<div/>",
"warningCount": 0,
},
]
`;
import HtmlValidate from "../../../src/htmlvalidate";
const markup: { [key: string]: string } = {};
markup["incorrect"] = `<img></img>`;
markup["correct"] = `<img>
<img/>`;
describe("docs/rules/void-content.md", () => {
it("inline validation: incorrect", () => {
const htmlvalidate = new HtmlValidate({"rules":{"void-content":"error"}});
const report = htmlvalidate.validateString(markup["incorrect"]);
expect(report.results).toMatchSnapshot();
});
it("inline validation: correct", () => {
const htmlvalidate = new HtmlValidate({"rules":{"void-content":"error"}});
const report = htmlvalidate.validateString(markup["correct"]);
expect(report.results).toMatchSnapshot();
});
});
import HtmlValidate from "../../../src/htmlvalidate";
const markup: { [key: string]: string } = {};
markup["incorrect"] = `<img></img>
<div/>`;
markup["correct"] = `<img>
<div></div>`;
describe("docs/rules/void-content.md", () => {
it("inline validation: incorrect", () => {
const htmlvalidate = new HtmlValidate({"rules":{"void-content":"error"}});
const report = htmlvalidate.validateString(markup["incorrect"]);
expect(report.results).toMatchSnapshot();
});
it("inline validation: correct", () => {
const htmlvalidate = new HtmlValidate({"rules":{"void-content":"error"}});
const report = htmlvalidate.validateString(markup["correct"]);
expect(report.results).toMatchSnapshot();
});
});
---
docType: rule
name: void-content
category: content-model
summary: Disallow void element with content
---
# Disallows void element with content (`void-content`)
HTML [void elements](https://www.w3.org/TR/html5/syntax.html#void-contents)
cannot have any content and must not have an end tag.
## Rule details
Examples of **incorrect** code for this rule:
<validate name="incorrect" rules="void-content">
<img></img>
</validate>
Examples of **correct** code for this rule:
<validate name="correct" rules="void-content">
<img>
<img/>
</validate>
......@@ -237,7 +237,7 @@ exports[`HTML elements <applet> valid markup 1`] = `Array []`;
exports[`HTML elements <area> invalid markup 1`] = `
Array [
Object {
"errorCount": 4,
"errorCount": 6,
"filePath": "test-files/elements/area-invalid.html",
"messages": Array [
Object {
......@@ -251,6 +251,17 @@ Array [
"severity": 2,
"size": 5,
},
Object {
"column": 9,
"context": "area",
"line": 6,
"message": "End tag for <area> must be omitted",
"offset": 96,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 5,
},
Object {
"column": 3,
"context": undefined,
......@@ -262,6 +273,17 @@ Array [
"severity": 2,
"size": 5,
},
Object {
"column": 3,
"context": "area",
"line": 11,
"message": "End tag for <area> must be omitted",
"offset": 168,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 5,
},
Object {
"column": 3,
"context": Object {
......@@ -552,7 +574,7 @@ exports[`HTML elements <b> valid markup 1`] = `Array []`;
exports[`HTML elements <base> invalid markup 1`] = `
Array [
Object {
"errorCount": 2,
"errorCount": 3,
"filePath": "test-files/elements/base-invalid.html",
"messages": Array [
Object {
......@@ -577,6 +599,17 @@ Array [
"severity": 2,
"size": 5,
},
Object {
"column": 8,
"context": "base",
"line": 7,
"message": "End tag for <base> must be omitted",
"offset": 109,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 5,
},
],
"source": "<!-- should not be allowed outside <head> -->
<div>
......@@ -822,7 +855,7 @@ exports[`HTML elements <body> valid markup 1`] = `Array []`;
exports[`HTML elements <br> invalid markup 1`] = `
Array [
Object {
"errorCount": 1,
"errorCount": 2,
"filePath": "test-files/elements/br-invalid.html",
"messages": Array [
Object {
......@@ -836,6 +869,17 @@ Array [
"severity": 2,
"size": 3,
},
Object {
"column": 6,
"context": "br",
"line": 2,
"message": "End tag for <br> must be omitted",
"offset": 39,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 3,
},
],
"source": "<!-- should not allow end tag -->
<br></br>
......@@ -1118,7 +1162,7 @@ exports[`HTML elements <code> valid markup 1`] = `Array []`;
exports[`HTML elements <col> invalid markup 1`] = `
Array [
Object {
"errorCount": 2,
"errorCount": 3,
"filePath": "test-files/elements/col-invalid.html",
"messages": Array [
Object {
......@@ -1143,6 +1187,17 @@ Array [
"severity": 2,
"size": 4,
},
Object {
"column": 9,
"context": "col",
"line": 9,
"message": "End tag for <col> must be omitted",
"offset": 134,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 4,
},
],
"source": "<!-- should not be allowed under other content -->
<div>
......@@ -1630,7 +1685,7 @@ exports[`HTML elements <em> valid markup 1`] = `Array []`;
exports[`HTML elements <embed> invalid markup 1`] = `
Array [
Object {
"errorCount": 4,
"errorCount": 5,
"filePath": "test-files/elements/embed-invalid.html",
"messages": Array [
Object {
......@@ -1644,6 +1699,17 @@ Array [
"severity": 2,
"size": 6,
},
Object {
"column": 45,
"context": "embed",
"line": 2,
"message": "End tag for <embed> must be omitted",
"offset": 91,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 6,
},
Object {
"column": 2,
"context": Object {
......@@ -2561,7 +2627,7 @@ exports[`HTML elements <hgroup> valid markup 1`] = `Array []`;
exports[`HTML elements <hr> invalid markup 1`] = `
Array [
Object {
"errorCount": 2,
"errorCount": 3,
"filePath": "test-files/elements/hr-invalid.html",
"messages": Array [
Object {
......@@ -2575,6 +2641,17 @@ Array [
"severity": 2,
"size": 3,
},
Object {
"column": 6,
"context": "hr",
"line": 2,
"message": "End tag for <hr> must be omitted",
"offset": 39,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 3,
},
Object {
"column": 8,
"context": undefined,
......@@ -2812,7 +2889,7 @@ exports[`HTML elements <iframe> valid markup 1`] = `Array []`;
exports[`HTML elements <img> invalid markup 1`] = `
Array [
Object {
"errorCount": 4,
"errorCount": 5,
"filePath": "test-files/elements/img-invalid.html",
"messages": Array [
Object {
......@@ -2858,6 +2935,17 @@ Array [
"severity": 2,
"size": 4,
},
Object {
"column": 21,
"context": "img",
"line": 8,
"message": "End tag for <img> must be omitted",
"offset": 139,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 4,
},
Object {
"column": 3,
"context": undefined,
......@@ -2894,7 +2982,7 @@ exports[`HTML elements <img> valid markup 1`] = `Array []`;
exports[`HTML elements <input> invalid markup 1`] = `
Array [
Object {
"errorCount": 14,
"errorCount": 15,
"filePath": "test-files/elements/input-invalid.html",
"messages": Array [
Object {
......@@ -2908,6 +2996,17 @@ Array [
"severity": 2,
"size": 6,
},
Object {
"column": 21,
"context": "input",
"line": 2,
"message": "End tag for <input> must be omitted",
"offset": 54,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 6,
},
Object {
"column": 31,
"context": Object {
......@@ -3261,7 +3360,7 @@ exports[`HTML elements <kbd> valid markup 1`] = `Array []`;
exports[`HTML elements <keygen> invalid markup 1`] = `
Array [
Object {
"errorCount": 1,
"errorCount": 2,
"filePath": "test-files/elements/keygen-invalid.html",
"messages": Array [
Object {
......@@ -3275,6 +3374,17 @@ Array [
"severity": 2,
"size": 7,
},
Object {
"column": 10,
"context": "keygen",
"line": 2,
"message": "End tag for <keygen> must be omitted",
"offset": 38,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 7,
},
],
"source": "<!-- should omit end tag -->
<keygen></keygen>
......@@ -3413,7 +3523,7 @@ exports[`HTML elements <li> valid markup 1`] = `Array []`;
exports[`HTML elements <link> invalid markup 1`] = `
Array [
Object {
"errorCount": 5,
"errorCount": 6,
"filePath": "test-files/elements/link-invalid.html",
"messages": Array [
Object {
......@@ -3427,6 +3537,17 @@ Array [
"severity": 2,
"size": 5,
},
Object {
"column": 23,
"context": "link",
"line": 2,
"message": "End tag for <link> must be omitted",
"offset": 56,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 5,
},
Object {
"column": 2,
"context": Object {
......@@ -3757,7 +3878,7 @@ exports[`HTML elements <math> valid markup 1`] = `Array []`;
exports[`HTML elements <meta> invalid markup 1`] = `
Array [
Object {
"errorCount": 1,
"errorCount": 2,
"filePath": "test-files/elements/meta-invalid.html",
"messages": Array [
Object {
......@@ -3771,6 +3892,17 @@ Array [
"severity": 2,
"size": 5,
},
Object {
"column": 8,
"context": "meta",
"line": 2,
"message": "End tag for <meta> must be omitted",
"offset": 36,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 5,
},
],
"source": "<!-- should omit end tag -->
<meta></meta>
......@@ -4339,7 +4471,7 @@ exports[`HTML elements <p> valid markup 1`] = `Array []`;
exports[`HTML elements <param> invalid markup 1`] = `
Array [
Object {
"errorCount": 2,
"errorCount": 3,
"filePath": "test-files/elements/param-invalid.html",
"messages": Array [
Object {
......@@ -4353,6 +4485,17 @@ Array [
"severity": 2,
"size": 6,
},
Object {
"column": 9,
"context": "param",
"line": 2,
"message": "End tag for <param> must be omitted",
"offset": 37,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 6,
},
Object {
"column": 3,
"context": undefined,
......@@ -5007,7 +5150,7 @@ exports[`HTML elements <small> valid markup 1`] = `Array []`;
exports[`HTML elements <source> invalid markup 1`] = `
Array [
Object {
"errorCount": 2,
"errorCount": 3,
"filePath": "test-files/elements/source-invalid.html",
"messages": Array [
Object {
......@@ -5021,6 +5164,17 @@ Array [
"severity": 2,
"size": 7,
},
Object {
"column": 11,
"context": "source",
"line": 3,
"message": "End tag for <source> must be omitted",
"offset": 47,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 7,
},
Object {
"column": 3,
"context": undefined,
......@@ -5952,7 +6106,7 @@ exports[`HTML elements <tr> valid markup 1`] = `Array []`;
exports[`HTML elements <track> invalid markup 1`] = `
Array [
Object {
"errorCount": 1,
"errorCount": 2,
"filePath": "test-files/elements/track-invalid.html",
"messages": Array [
Object {
......@@ -5966,6 +6120,17 @@ Array [
"severity": 2,
"size": 6,
},
Object {
"column": 10,
"context": "track",
"line": 3,
"message": "End tag for <track> must be omitted",
"offset": 46,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 6,
},
],
"source": "<!-- should omit end tag -->
<audio>
......@@ -6224,7 +6389,7 @@ exports[`HTML elements <video> valid markup 1`] = `Array []`;
exports[`HTML elements <wbr> invalid markup 1`] = `
Array [
Object {
"errorCount": 1,
"errorCount": 2,
"filePath": "test-files/elements/wbr-invalid.html",
"messages": Array [
Object {
......@@ -6238,6 +6403,17 @@ Array [
"severity": 2,
"size": 4,
},
Object {
"column": 7,
"context": "wbr",
"line": 2,
"message": "End tag for <wbr> must be omitted",
"offset": 35,
"ruleId": "void-content",
"selector": null,
"severity": 2,
"size": 4,
},
],
"source": "<!-- should omit end tag -->
<wbr></wbr>
......
......@@ -6,6 +6,7 @@ Object {
"html-validate:recommended",
],
"plugins": Array [],
"root": true,
"rules": Object {
"deprecated": "error",
"element-permitted-content": "off",
......@@ -64,6 +65,7 @@ Object {
"html-validate:recommended",
],
"plugins": Array [],
"root": true,
"rules": Object {
"deprecated": "error",
"element-permitted-content": "off",
......@@ -155,6 +157,7 @@ Object {
"html-validate:recommended",
],
"plugins": Array [],
"root": true,
"rules": Object {
"deprecated": "error",
"element-permitted-content": "off",
......@@ -210,6 +213,7 @@ Object {
"html-validate:recommended",
],
"plugins": Array [],
"root": true,
"rules": Object {
"deprecated": "error",
"element-permitted-content": "off",
......@@ -269,6 +273,7 @@ Object {
"html-validate:recommended",
],
"plugins": Array [],
"root": true,
"rules": Object {
"deprecated": "error",
"element-permitted-content": "error",
......@@ -327,6 +332,7 @@ Object {
"html-validate:recommended",
],
"plugins": Array [],
"root": true,
"rules": Object {
"deprecated": "error",
"element-permitted-content": "error",
......@@ -368,6 +374,7 @@ Object {
"html-validate:recommended",
],
"plugins": Array [],
"root": true,
"rules": Object {
"deprecated": "error",
"element-permitted-content": "error",
......@@ -409,6 +416,7 @@ Object {
"html-validate:recommended",
],
"plugins": Array [],
"root": true,
"rules": Object {
"deprecated": "error",
"element-permitted-content": "error",
......@@ -426,6 +434,7 @@ Object {
"html-validate:recommended",
],
"plugins": Array [],
"root": true,
"rules": Object {
"deprecated": "error",
"element-permitted-content": "error",
......
......@@ -36,6 +36,7 @@ module.exports = {
"svg-focusable": "error",
"unrecognized-char-ref": "error",
void: "error",
"void-content": "error",
"wcag/h30": "error",
"wcag/h32": "error",
"wcag/h36": "error",
......
......@@ -77,6 +77,7 @@ describe("Engine", () => {
extends: ["html-validate:recommended"],
rules: {
deprecated: "off",
"void-content": "off",
},
});
config.init();
......