HTMLHint icon indicating copy to clipboard operation
HTMLHint copied to clipboard

Rewrite configuration structure

Open Shinigami92 opened this issue 7 years ago • 8 comments

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"
  • [ ] 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"]
}

Shinigami92 avatar Aug 28 '18 16:08 Shinigami92

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];

Shinigami92 avatar Sep 02 '18 15:09 Shinigami92

This is such a good idea.

tom-spalding avatar May 02 '20 07:05 tom-spalding

We may later think about using cosmiconfig

Shinigami92 avatar May 16 '20 20:05 Shinigami92

@Shinigami92 seems a great idea.

thedaviddias avatar May 16 '20 20:05 thedaviddias

All unresolved tasks have been extracted into their own issues

Shinigami92 avatar Jul 14 '20 10:07 Shinigami92

It looks like #489 is marked as completed here, but it didn't merge and there isn't another open issue about it.

openjck avatar May 02 '21 20:05 openjck

What with merge configuration (#489), still unavailable?

gitrequests avatar Jan 06 '22 11:01 gitrequests