Skip to content

Commit 6b8a1bb

Browse files
committed
New validator (#41775)
* New validator * update * remove * update
1 parent f94bcbe commit 6b8a1bb

File tree

5 files changed

+412
-115
lines changed

5 files changed

+412
-115
lines changed

.github/workflows/docs.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,14 @@ jobs:
3030
node-version: "${{ env.NODE }}"
3131
cache: npm
3232

33-
- run: java -version
34-
3533
- name: Install npm dependencies
3634
run: npm ci
3735

3836
- name: Build docs
3937
run: npm run docs-build
4038

4139
- name: Validate HTML
42-
run: npm run docs-vnu
40+
run: npm run docs-html-validate
4341

4442
- name: Run linkinator
4543
uses: JustinBeckwith/linkinator-action@3d5ba091319fa7b0ac14703761eebb7d100e6f6d # v1.11.0

build/html-validate.mjs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/usr/bin/env node
2+
3+
/*!
4+
* Script to run html-validate for HTML validation.
5+
*
6+
* This replaces the Java-based vnu-jar validator with a faster, Node.js-only solution.
7+
* Benefits:
8+
* - No Java dependency required
9+
* - Faster execution (no JVM startup time)
10+
* - Easy to configure with rule-based system
11+
* - Better integration with Node.js build tools
12+
*
13+
* Copyright 2017-2025 The Bootstrap Authors
14+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
15+
*/
16+
17+
import { HtmlValidate } from 'html-validate'
18+
import { globby } from 'globby'
19+
20+
const htmlValidate = new HtmlValidate({
21+
rules: {
22+
// Allow autocomplete on buttons (Bootstrap specific)
23+
'attribute-allowed-values': 'off',
24+
// Allow aria-disabled on links (Bootstrap specific)
25+
'aria-label-misuse': 'off',
26+
// Allow modern CSS syntax
27+
'valid-id': 'off',
28+
// Allow void elements with trailing slashes (Astro)
29+
'void-style': 'off',
30+
// Allow custom attributes
31+
'no-unknown-elements': 'off',
32+
'attribute-boolean-style': 'off',
33+
'no-inline-style': 'off',
34+
// KEEP duplicate ID checking enabled (this is important for HTML validity)
35+
'no-dup-id': 'error'
36+
},
37+
elements: [
38+
'html5',
39+
{
40+
// Allow custom attributes for Astro/framework compatibility
41+
'*': {
42+
attributes: {
43+
'is:raw': { boolean: true },
44+
switch: { boolean: true },
45+
autocomplete: { enum: ['on', 'off', 'new-password', 'current-password'] }
46+
}
47+
}
48+
}
49+
]
50+
})
51+
52+
async function validateHTML() {
53+
try {
54+
console.log('Running html-validate validation...')
55+
56+
// Find all HTML files
57+
const files = await globby([
58+
'_site/**/*.html',
59+
'js/tests/**/*.html'
60+
], {
61+
ignore: ['**/node_modules/**']
62+
})
63+
64+
console.log(`Validating ${files.length} HTML files...`)
65+
66+
let hasErrors = false
67+
68+
// Validate all files in parallel to avoid await-in-loop
69+
const validationPromises = files.map(file =>
70+
htmlValidate.validateFile(file).then(report => ({ file, report }))
71+
)
72+
73+
const validationResults = await Promise.all(validationPromises)
74+
75+
// Process results and check for errors
76+
for (const { file, report } of validationResults) {
77+
if (!report.valid) {
78+
hasErrors = true
79+
console.error(`\nErrors in ${file}:`)
80+
81+
// Extract error messages with reduced nesting
82+
const errorMessages = report.results.flatMap(result =>
83+
result.messages.filter(message => message.severity === 2)
84+
)
85+
86+
for (const message of errorMessages) {
87+
console.error(` Line ${message.line}:${message.column} - ${message.message} (${message.ruleId})`)
88+
}
89+
}
90+
}
91+
92+
if (hasErrors) {
93+
console.error('\nHTML validation failed!')
94+
process.exit(1)
95+
} else {
96+
console.log('✓ All HTML files are valid!')
97+
}
98+
} catch (error) {
99+
console.error('HTML validation error:', error)
100+
process.exit(1)
101+
}
102+
}
103+
104+
validateHTML()

build/vnu-jar.mjs

Lines changed: 0 additions & 66 deletions
This file was deleted.

0 commit comments

Comments
 (0)