Rewrite configuration structure
Is your feature request related to a problem? Please describe.
Today's tools are characterized by a much better style of configuration file
It's much more extensible and supports things like defaultSeverity and presets that load before its own configuration
Describe the solution you'd like
We will rewrite the configuration in eslint-style, see https://github.com/htmlhint/HTMLHint/issues/279#issuecomment-417939741
TODOs
- [X] rewrite rules (#445 merged)
- [x] update docu (#447 merged)
- [x] move rules into attribute
"rules": { /* ... */ }(#476 merged) - [ ] parse inline rules with options (extracted to #503)
- [x] add attribute
"extends"(#489 in review)- [x] define value
"htmlhint:recommended"
- [x] define value
- [ ] add attribute
"defaultSeverity"(is this still needed? 🤔)
this could be done after release 1.0.0 - [ ] add attribute
"exclude"(extracted to #502)
this could be done after release 1.0.0
Old proposal
We should rewrite the configuration file into something like this:
{
"extends": ["htmlhint:recommended"],
"defaultSeverity": "error",
"htmlVersion": "html5",
"rules": {
"attr-no-duplication": true,
"attr-unsafe-chars": true,
"attr-value-double-quotes": true,
"doctype-first": false,
"doctype-html5": true,
"id-class-ad-disabled": true,
"id-class-value": ["dash", { "severity": "warning" }],
"id-unique": true,
"inline-style-disabled": false,
"space-tab-mixed-disabled": ["tab", { "severity": "warning" }],
"spec-char-escape": true,
"src-not-empty": true,
"style-disabled": [true, { "severity": "warning" }],
"tag-pair": true,
"tag-self-close": false,
"tagname-lowercase": [
true,
{
"exceptions": ["linearGradient"]
}
],
"title-require": true,
"stylelint": [
true,
{
"extends": "stylelint-config-standard",
"rules": {
"block-no-empty": null,
"color-no-invalid-hex": true
}
}
],
"eslint": [
true,
{
"configFile": "./.eslintrc.json"
}
]
},
"exclude": ["test/**/*.html"]
}
We will rewrite the configuration structure in eslint-style
{
"extends": ["htmlhint:recommended"],
"defaultSeverity": "error",
"htmlVersion": "html5",
"rules": {},
"exclude": ["test/**/*.html"]
}
Rules
alt-require
The alt attribute of an <img> element must be present and alt attribute of area[href] and input[type=image] must have a value.
{ "alt-require": "off" }
{ "alt-require": "error" }
{ "alt-require": "warn" }
{ "alt-require": ["off"] }
{ "alt-require": ["error"] }
{ "alt-require": ["warn"] }
attr-lowercase
All attribute names must be in lowercase.
{ "attr-lowercase": "off" }
{ "attr-lowercase": "error" }
{ "attr-lowercase": "warn" }
{ "attr-lowercase": ["off"] }
{ "attr-lowercase": ["error", { "exceptions": ["viewBox"] }] }
{ "attr-lowercase": ["warn", { "exceptions": ["viewBox"] }] }
htmlhint:recommended
attr-no-duplication
Elements cannot have duplicate attributes.
{ "attr-no-duplication": "off" }
{ "attr-no-duplication": "error" }
{ "attr-no-duplication": "warn" }
{ "attr-no-duplication": ["off"] }
{ "attr-no-duplication": ["error"] }
{ "attr-no-duplication": ["warn"] }
htmlhint:recommended
attr-unsafe-chars
Attribute values cannot contain unsafe chars.
{ "attr-unsafe-chars": "off" }
{ "attr-unsafe-chars": "error" }
{ "attr-unsafe-chars": "warn" }
{ "attr-unsafe-chars": ["off"] }
{ "attr-unsafe-chars": ["error"] }
{ "attr-unsafe-chars": ["warn"] }
attr-value-double-quotes
Attribute values must be in double quotes.
{ "attr-value-double-quotes": "off" }
{ "attr-value-double-quotes": "error" }
{ "attr-value-double-quotes": "warn" }
{ "attr-value-double-quotes": ["off"] }
{ "attr-value-double-quotes": ["error"] }
{ "attr-value-double-quotes": ["warn"] }
htmlhint:recommended
- option to use single or double quotes
attr-value-not-empty
All attributes must have values.
{ "attr-value-not-empty": "off" }
{ "attr-value-not-empty": "error" }
{ "attr-value-not-empty": "warn" }
{ "attr-value-not-empty": ["off"] }
{ "attr-value-not-empty": ["error"] }
{ "attr-value-not-empty": ["warn"] }
csslint
Scan css with csslint.
// check for .csslintrc
{ "csslint": "off" }
{ "csslint": "error" }
{ "csslint": "warn" }
{ "csslint": ["off"] }
// pass csslint config
{ "csslint": ["error", { "vendor-prefix": true }] }
{ "csslint": ["warn", { "vendor-prefix": true }] }
- needs rewrite to support reading .csslintrc
doctype-first
Doctype must be declared first.
{ "doctype-first": "off" }
{ "doctype-first": "error" }
{ "doctype-first": "warn" }
{ "doctype-first": ["off"] }
{ "doctype-first": ["error"] }
{ "doctype-first": ["warn"] }
htmlhint:recommended
- option to check only root index.html
doctype-html5
Invalid doctype. Use: "<!DOCTYPE html>"
{ "doctype-html5": "off" }
{ "doctype-html5": "error" }
{ "doctype-html5": "warn" }
{ "doctype-html5": ["off"] }
{ "doctype-html5": ["error"] }
{ "doctype-html5": ["warn"] }
- needs to be more generic (html4, html5 xhtml)
head-script-disabled
The <script> tag cannot be used in a <head> tag.
{ "head-script-disabled": "off" }
{ "head-script-disabled": "error" }
{ "head-script-disabled": "warn" }
{ "head-script-disabled": ["off"] }
{ "head-script-disabled": ["error"] }
{ "head-script-disabled": ["warn"] }
href-abs-or-rel
An href attribute must be either absolute or relative.
{ "href-abs-or-rel": "off" }
{ "href-abs-or-rel": ["off"] }
{ "href-abs-or-rel": ["error", { "mode": "absolute" }] }
{ "href-abs-or-rel": ["warn", { "mode": "relative" }] }
- needs rewrite
id-class-ad-disabled
The id and class attributes cannot use the ad keyword, it will be blocked by adblock software.
{ "id-class-ad-disabled": "off" }
{ "id-class-ad-disabled": "error" }
{ "id-class-ad-disabled": "warn" }
{ "id-class-ad-disabled": ["off"] }
{ "id-class-ad-disabled": ["error"] }
{ "id-class-ad-disabled": ["warn"] }
id-class-value
The id and class attribute values must meet the specified rules.
{ "id-class-value": "off" }
{ "id-class-value": ["off"] }
{ "id-class-value": ["error", { "mode": "underline" }] }
{ "id-class-value": ["warn", { "mode": "dash" }] }
{ "id-class-value": ["warn", { "mode": "hump" }] }
- needs rewrite
id-unique
The value of id attributes must be unique.
{ "id-unique": "off" }
{ "id-unique": "error" }
{ "id-unique": "warn" }
{ "id-unique": ["off"] }
{ "id-unique": ["error"] }
{ "id-unique": ["warn"] }
htmlhint:recommended
inline-script-disabled
Inline script cannot be used.
{ "inline-script-disabled": "off" }
{ "inline-script-disabled": "error" }
{ "inline-script-disabled": "warn" }
{ "inline-script-disabled": ["off"] }
{ "inline-script-disabled": ["error"] }
{ "inline-script-disabled": ["warn"] }
inline-style-disabled
Inline style cannot be used.
{ "inline-style-disabled": "off" }
{ "inline-style-disabled": "error" }
{ "inline-style-disabled": "warn" }
{ "inline-style-disabled": ["off"] }
{ "inline-style-disabled": ["error"] }
{ "inline-style-disabled": ["warn"] }
jshint
Scan script with jshint.
// check for .jshintrc
{ "jshint": "off" }
{ "jshint": "error" }
{ "jshint": "warn" }
{ "jshint": ["off"] }
// pass jshint config
{ "jshint": ["error", { "curly": true }] }
{ "jshint": ["warn", { "curly": true }] }
- needs rewrite to support reading .jshintrc
space-tab-mixed-disabled
Do not mix tabs and spaces for indentation.
{ "space-tab-mixed-disabled": "off" }
{ "space-tab-mixed-disabled": ["off"] }
{ "space-tab-mixed-disabled": ["error", { "mode": "tab" }] }
{ "space-tab-mixed-disabled": ["warn", { "mode": "space" }] }
{ "space-tab-mixed-disabled": ["warn", { "mode": "space4" }] }
- needs rewrite
- option to pass number for spaces
spec-char-escape
Special characters must be escaped.
{ "spec-char-escape": "off" }
{ "spec-char-escape": "error" }
{ "spec-char-escape": "warn" }
{ "spec-char-escape": ["off"] }
{ "spec-char-escape": ["error"] }
{ "spec-char-escape": ["warn"] }
htmlhint:recommended
src-not-empty
The src attribute of an img(script,link) must have a value.
{ "src-not-empty": "off" }
{ "src-not-empty": "error" }
{ "src-not-empty": "warn" }
{ "src-not-empty": ["off"] }
{ "src-not-empty": ["error"] }
{ "src-not-empty": ["warn"] }
htmlhint:recommended
style-disabled
<style> tags cannot be used.
{ "style-disabled": "off" }
{ "style-disabled": "error" }
{ "style-disabled": "warn" }
{ "style-disabled": ["off"] }
{ "style-disabled": ["error"] }
{ "style-disabled": ["warn"] }
tag-pair
Tag must be paired.
{ "tag-pair": "off" }
{ "tag-pair": "error" }
{ "tag-pair": "warn" }
{ "tag-pair": ["off"] }
{ "tag-pair": ["error"] }
{ "tag-pair": ["warn"] }
htmlhint:recommended
tag-self-close
Empty tags must be self closed.
{ "tag-self-close": "off" }
{ "tag-self-close": "error" }
{ "tag-self-close": "warn" }
{ "tag-self-close": ["off"] }
{ "tag-self-close": ["error"] }
{ "tag-self-close": ["warn"] }
tagname-lowercase
All html element names must be in lowercase.
{ "tagname-lowercase": "off" }
{ "tagname-lowercase": "error" }
{ "tagname-lowercase": "warn" }
{ "tagname-lowercase": ["off"] }
{ "tagname-lowercase": ["error"] }
{ "tagname-lowercase": ["warn"] }
htmlhint:recommended
title-require
<title> must be present in <head> tag.
{ "title-require": "off" }
{ "title-require": "error" }
{ "title-require": "warn" }
{ "title-require": ["off"] }
{ "title-require": ["error"] }
{ "title-require": ["warn"] }
htmlhint:recommended
Type Definition
export type RuleSeverity = 'off' | 'error' | 'warn';
export type RuleConfig = RuleSeverity | [RuleSeverity, { [key: string]: any } | undefined];
This is such a good idea.
We may later think about using cosmiconfig
@Shinigami92 seems a great idea.
All unresolved tasks have been extracted into their own issues
It looks like #489 is marked as completed here, but it didn't merge and there isn't another open issue about it.
What with merge configuration (#489), still unavailable?