build: add HTML linting

This commit is contained in:
Ben Goldsworthy 2021-04-25 22:37:25 +01:00
parent 4591c1f3ca
commit e6a6691338
5 changed files with 283 additions and 9 deletions

7
.gitignore vendored
View file

@ -79,13 +79,8 @@ tmp/
!.editorconfig !.editorconfig
!.phpcs.xml.dist !.phpcs.xml.dist
!.eslintrc.json
!.eslintignore
!.php-commitizen.php
!.prettierignore !.prettierignore
!.prettierrc !.htmlhintrc
!.stylelintignore
!.stylelintrc.json
# Track favicon files, if they exist. # Track favicon files, if they exist.
!android-chrome-*.png !android-chrome-*.png

22
.htmlhintrc Normal file
View file

@ -0,0 +1,22 @@
{
"style-disabled": true,
"head-script-disabled": true,
"attr-lowercase": true,
"attr-no-duplication": true,
"attr-no-unnecessary-whitespace": true,
"attr-unsafe-chars": true,
"attr-value-double-quotes": true,
"attr-value-not-empty": false,
"alt-require": true,
"input-requires-label": true,
"href-abs-or-rel": "rel",
"tagname-lowercase": true,
"empty-tag-not-self-closed": true,
"src-not-empty": true,
"id-class-ad-disabled": true,
"id_class_value": "underline",
"id-unique": true,
"inline-script-disabled": true,
"inline-style-disabled": true,
"space-tab-mixed-disabled": true
}

View file

@ -21,6 +21,7 @@
"format:js:fix": "npm run format:js:fix", "format:js:fix": "npm run format:js:fix",
"lint:md": "npm run lint:md", "lint:md": "npm run lint:md",
"lint:md:fix": "npm run lint:md:fix", "lint:md:fix": "npm run lint:md:fix",
"lint:html": "npm run lint:html",
"docs": "./vendor/bin/phpdoc", "docs": "./vendor/bin/phpdoc",
"post-install-cmd": "npm install", "post-install-cmd": "npm install",
"minify": "npm run minify", "minify": "npm run minify",

251
package-lock.json generated
View file

@ -14,6 +14,7 @@
"eslint": "^7.24.0", "eslint": "^7.24.0",
"eslint-config-prettier": "^8.2.0", "eslint-config-prettier": "^8.2.0",
"eslint-plugin-prettier": "^3.4.0", "eslint-plugin-prettier": "^3.4.0",
"htmlhint": "^0.14.2",
"husky": "^4.3.8", "husky": "^4.3.8",
"lint-staged": "^10.5.4", "lint-staged": "^10.5.4",
"markdownlint-cli": "^0.27.1", "markdownlint-cli": "^0.27.1",
@ -1254,6 +1255,12 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/async": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
"integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==",
"dev": true
},
"node_modules/async-foreach": { "node_modules/async-foreach": {
"version": "0.1.3", "version": "0.1.3",
"resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
@ -4332,6 +4339,49 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/glob-base": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
"integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
"dev": true,
"dependencies": {
"glob-parent": "^2.0.0",
"is-glob": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/glob-base/node_modules/glob-parent": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
"integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
"dev": true,
"dependencies": {
"is-glob": "^2.0.0"
}
},
"node_modules/glob-base/node_modules/is-extglob": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
"integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/glob-base/node_modules/is-glob": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
"integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
"dev": true,
"dependencies": {
"is-extglob": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/glob-parent": { "node_modules/glob-parent": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@ -4758,6 +4808,43 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/htmlhint": {
"version": "0.14.2",
"resolved": "https://registry.npmjs.org/htmlhint/-/htmlhint-0.14.2.tgz",
"integrity": "sha512-lUCgGVZ/oyCkpgDkIa5IfClwX8Ppy11Dk7XdeVboAGSmKjIuOKx6yy86WS0W08KFtCRuxftzNy+KdQjM4UjqCA==",
"dev": true,
"dependencies": {
"async": "3.2.0",
"chalk": "4.1.0",
"commander": "5.1.0",
"glob": "7.1.6",
"parse-glob": "3.0.4",
"request": "2.88.2",
"strip-json-comments": "3.1.0",
"xml": "1.0.1"
},
"bin": {
"htmlhint": "bin/htmlhint"
}
},
"node_modules/htmlhint/node_modules/commander": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
"dev": true,
"engines": {
"node": ">= 6"
}
},
"node_modules/htmlhint/node_modules/strip-json-comments": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz",
"integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/htmlparser2": { "node_modules/htmlparser2": {
"version": "3.10.1", "version": "3.10.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
@ -5312,6 +5399,15 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/is-dotfile": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
"integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-extendable": { "node_modules/is-extendable": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
@ -7366,6 +7462,42 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/parse-glob": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
"integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
"dev": true,
"dependencies": {
"glob-base": "^0.3.0",
"is-dotfile": "^1.0.0",
"is-extglob": "^1.0.0",
"is-glob": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/parse-glob/node_modules/is-extglob": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
"integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/parse-glob/node_modules/is-glob": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
"integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
"dev": true,
"dependencies": {
"is-extglob": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/parse-json": { "node_modules/parse-json": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
@ -11565,6 +11697,12 @@
"integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=",
"dev": true "dev": true
}, },
"node_modules/xml": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
"integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=",
"dev": true
},
"node_modules/xtend": { "node_modules/xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@ -12701,6 +12839,12 @@
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="
}, },
"async": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
"integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==",
"dev": true
},
"async-foreach": { "async-foreach": {
"version": "0.1.3", "version": "0.1.3",
"resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
@ -15120,6 +15264,42 @@
"path-is-absolute": "^1.0.0" "path-is-absolute": "^1.0.0"
} }
}, },
"glob-base": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
"integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
"dev": true,
"requires": {
"glob-parent": "^2.0.0",
"is-glob": "^2.0.0"
},
"dependencies": {
"glob-parent": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
"integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
"dev": true,
"requires": {
"is-glob": "^2.0.0"
}
},
"is-extglob": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
"integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
"dev": true
},
"is-glob": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
"integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
"dev": true,
"requires": {
"is-extglob": "^1.0.0"
}
}
}
},
"glob-parent": { "glob-parent": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@ -15442,6 +15622,36 @@
"resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz",
"integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==" "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg=="
}, },
"htmlhint": {
"version": "0.14.2",
"resolved": "https://registry.npmjs.org/htmlhint/-/htmlhint-0.14.2.tgz",
"integrity": "sha512-lUCgGVZ/oyCkpgDkIa5IfClwX8Ppy11Dk7XdeVboAGSmKjIuOKx6yy86WS0W08KFtCRuxftzNy+KdQjM4UjqCA==",
"dev": true,
"requires": {
"async": "3.2.0",
"chalk": "4.1.0",
"commander": "5.1.0",
"glob": "7.1.6",
"parse-glob": "3.0.4",
"request": "2.88.2",
"strip-json-comments": "3.1.0",
"xml": "1.0.1"
},
"dependencies": {
"commander": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
"dev": true
},
"strip-json-comments": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz",
"integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==",
"dev": true
}
}
},
"htmlparser2": { "htmlparser2": {
"version": "3.10.1", "version": "3.10.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
@ -15838,6 +16048,12 @@
"integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
"dev": true "dev": true
}, },
"is-dotfile": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
"integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
"dev": true
},
"is-extendable": { "is-extendable": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
@ -17397,6 +17613,35 @@
"is-hexadecimal": "^1.0.0" "is-hexadecimal": "^1.0.0"
} }
}, },
"parse-glob": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
"integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
"dev": true,
"requires": {
"glob-base": "^0.3.0",
"is-dotfile": "^1.0.0",
"is-extglob": "^1.0.0",
"is-glob": "^2.0.0"
},
"dependencies": {
"is-extglob": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
"integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
"dev": true
},
"is-glob": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
"integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
"dev": true,
"requires": {
"is-extglob": "^1.0.0"
}
}
}
},
"parse-json": { "parse-json": {
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
@ -20707,6 +20952,12 @@
"integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=",
"dev": true "dev": true
}, },
"xml": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
"integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=",
"dev": true
},
"xtend": { "xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

View file

@ -6,7 +6,7 @@
"format:fix": "npm run format:js:fix", "format:fix": "npm run format:js:fix",
"format:js": "prettier './src/**/*.js'", "format:js": "prettier './src/**/*.js'",
"format:js:fix": "npm run format:js -- --write", "format:js:fix": "npm run format:js -- --write",
"lint": "npm run lint:js && npm run lint:css && npm run lint:md", "lint": "npm run lint:js && npm run lint:css && npm run lint:md && npm run lint:html",
"lint:fix": "npm run lint:js:fix && npm run lint:css:fix && npm run lint:md:fix", "lint:fix": "npm run lint:js:fix && npm run lint:css:fix && npm run lint:md:fix",
"lint:php": "composer run lint:php", "lint:php": "composer run lint:php",
"lint:php:fix": "composer run lint:php:fix", "lint:php:fix": "composer run lint:php:fix",
@ -16,6 +16,7 @@
"lint:css:fix": "npm run lint:css -- --fix", "lint:css:fix": "npm run lint:css -- --fix",
"lint:md": "markdownlint '*.md'", "lint:md": "markdownlint '*.md'",
"lint:md:fix": "npm run lint:md -- --fix", "lint:md:fix": "npm run lint:md -- --fix",
"lint:html": "htmlhint ./src/**/*.html",
"minify": "npm run minify:css && npm run minify:js", "minify": "npm run minify:css && npm run minify:js",
"minify:css": "for f in ./tmp/css/*.css; do npx minify $f > ./dist/css/$(basename $f .css).min.css; done", "minify:css": "for f in ./tmp/css/*.css; do npx minify $f > ./dist/css/$(basename $f .css).min.css; done",
"minify:js": "for f in ./src/js/*.js; do npx minify $f > ./dist/js/$(basename $f .js).min.js; done" "minify:js": "for f in ./src/js/*.js; do npx minify $f > ./dist/js/$(basename $f .js).min.js; done"
@ -39,6 +40,9 @@
], ],
"*.md": [ "*.md": [
"npm run lint:md" "npm run lint:md"
],
"*.html": [
"npm run lint:html"
] ]
}, },
"devDependencies": { "devDependencies": {
@ -47,6 +51,7 @@
"eslint": "^7.24.0", "eslint": "^7.24.0",
"eslint-config-prettier": "^8.2.0", "eslint-config-prettier": "^8.2.0",
"eslint-plugin-prettier": "^3.4.0", "eslint-plugin-prettier": "^3.4.0",
"htmlhint": "^0.14.2",
"husky": "^4.3.8", "husky": "^4.3.8",
"lint-staged": "^10.5.4", "lint-staged": "^10.5.4",
"markdownlint-cli": "^0.27.1", "markdownlint-cli": "^0.27.1",