gbu-accessibility-package 1.6.0 โ†’ 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.js CHANGED
@@ -18,10 +18,15 @@ const options = {
18
18
  dryRun: false,
19
19
  help: false,
20
20
  cleanupOnly: false,
21
- comprehensive: false,
21
+ comprehensive: false, // Keep for backward compatibility
22
22
  altOnly: false,
23
23
  langOnly: false,
24
- roleOnly: false
24
+ roleOnly: false,
25
+ formsOnly: false,
26
+ buttonsOnly: false,
27
+ linksOnly: false,
28
+ landmarksOnly: false,
29
+ headingsOnly: false
25
30
  };
26
31
 
27
32
  // Parse arguments
@@ -55,7 +60,7 @@ for (let i = 0; i < args.length; i++) {
55
60
  break;
56
61
  case '--comprehensive':
57
62
  case '--all':
58
- options.comprehensive = true;
63
+ options.comprehensive = true; // Keep for backward compatibility
59
64
  break;
60
65
  case '--alt-only':
61
66
  options.altOnly = true;
@@ -66,6 +71,21 @@ for (let i = 0; i < args.length; i++) {
66
71
  case '--role-only':
67
72
  options.roleOnly = true;
68
73
  break;
74
+ case '--forms-only':
75
+ options.formsOnly = true;
76
+ break;
77
+ case '--buttons-only':
78
+ options.buttonsOnly = true;
79
+ break;
80
+ case '--links-only':
81
+ options.linksOnly = true;
82
+ break;
83
+ case '--landmarks-only':
84
+ options.landmarksOnly = true;
85
+ break;
86
+ case '--headings-only':
87
+ options.headingsOnly = true;
88
+ break;
69
89
  default:
70
90
  if (!arg.startsWith('-')) {
71
91
  options.directory = arg;
@@ -86,24 +106,31 @@ Options:
86
106
  --backup Create backup files (default: enabled)
87
107
  --no-backup Don't create backup files
88
108
  --dry-run Preview changes without applying
89
- --comprehensive, --all Run all fixes including cleanup (recommended)
109
+ --comprehensive, --all Run comprehensive fixes (same as default)
90
110
  --cleanup-only Only cleanup duplicate role attributes
91
- --alt-only Only fix alt attributes for images
92
- --lang-only Only fix HTML lang attributes
93
- --role-only Only fix role attributes
111
+ --alt-only Fix alt attributes + cleanup
112
+ --lang-only Fix HTML lang attributes + cleanup
113
+ --role-only Fix role attributes + cleanup
114
+ --forms-only Fix form labels + cleanup
115
+ --buttons-only Fix button names + cleanup
116
+ --links-only Fix link names + cleanup
117
+ --landmarks-only Fix landmarks + cleanup
118
+ --headings-only Analyze heading structure (no auto-fix)
94
119
  -h, --help Show this help message
95
120
 
96
121
  Examples:
97
- node cli.js # Fix current directory (with backups)
98
- node cli.js --comprehensive # Run all fixes including cleanup
99
- node cli.js --alt-only # Only fix alt attributes
100
- node cli.js --lang-only # Only fix lang attributes
101
- node cli.js --role-only # Only fix role attributes
122
+ node cli.js # Comprehensive fixes (default mode)
123
+ node cli.js --comprehensive # Comprehensive fixes (same as default)
124
+ node cli.js --alt-only # Fix alt attributes + cleanup
125
+ node cli.js --forms-only # Fix form labels + cleanup
126
+ node cli.js --buttons-only # Fix button names + cleanup
127
+ node cli.js --links-only # Fix link names + cleanup
128
+ node cli.js --landmarks-only # Fix landmarks + cleanup
129
+ node cli.js --headings-only # Analyze heading structure only
102
130
  node cli.js --cleanup-only # Only cleanup duplicate roles
103
- node cli.js ./src # Fix src directory
104
- node cli.js -l en --dry-run ./dist # Preview fixes for dist directory in English
105
- node cli.js --no-backup ./public # Fix without creating backups
106
- node cli.js --backup --comprehensive # Explicitly enable backups with all fixes
131
+ node cli.js ./src # Fix src directory (comprehensive)
132
+ node cli.js -l en --dry-run ./dist # Preview comprehensive fixes in English
133
+ node cli.js --no-backup ./public # Comprehensive fixes without backups
107
134
 
108
135
  Features:
109
136
  โœ… Alt attributes for images
@@ -115,6 +142,7 @@ Features:
115
142
  process.exit(0);
116
143
  }
117
144
 
145
+
118
146
  // Helper function to show completion message with backup info
119
147
  function showCompletionMessage(options, mode = 'fixes') {
120
148
  if (options.dryRun) {
@@ -147,14 +175,30 @@ async function main() {
147
175
  });
148
176
 
149
177
  try {
150
- // Handle different modes
151
- if (options.comprehensive) {
152
- // Run comprehensive fix (all fixes including cleanup)
178
+ // Handle different modes - All modes now include cleanup
179
+ if (options.cleanupOnly || options.altOnly || options.langOnly || options.roleOnly ||
180
+ options.formsOnly || options.buttonsOnly || options.linksOnly || options.landmarksOnly || options.headingsOnly) {
181
+ // Individual modes - handle each separately, then run cleanup
182
+ } else {
183
+ // Default mode: Run comprehensive fix (all fixes including cleanup)
153
184
  console.log(chalk.blue('๐ŸŽฏ Running comprehensive accessibility fixes...'));
154
185
  const results = await fixer.fixAllAccessibilityIssues(options.directory);
155
186
 
156
187
  // Results already logged in the method
157
188
  return;
189
+ }
190
+
191
+ // Individual modes
192
+ if (options.cleanupOnly) {
193
+ // Only cleanup duplicate roles
194
+ console.log(chalk.blue('๐Ÿงน Running cleanup for duplicate role attributes...'));
195
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
196
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
197
+
198
+ console.log(chalk.green(`\nโœ… Cleaned duplicate roles in ${cleanupFixed} files`));
199
+
200
+ showCompletionMessage(options, 'Cleanup');
201
+ return;
158
202
 
159
203
  } else if (options.cleanupOnly) {
160
204
  // Only cleanup duplicate roles
@@ -168,90 +212,143 @@ async function main() {
168
212
  return;
169
213
 
170
214
  } else if (options.altOnly) {
171
- // Only fix alt attributes
172
- console.log(chalk.blue('๐Ÿ–ผ๏ธ Running alt attribute fixes only...'));
215
+ // Fix alt attributes + cleanup
216
+ console.log(chalk.blue('๐Ÿ–ผ๏ธ Running alt attribute fixes + cleanup...'));
173
217
  const altResults = await fixer.fixEmptyAltAttributes(options.directory);
174
218
  const altFixed = altResults.filter(r => r.status === 'fixed').length;
175
219
  const totalAltIssues = altResults.reduce((sum, r) => sum + (r.issues || 0), 0);
176
220
 
177
221
  console.log(chalk.green(`\nโœ… Fixed alt attributes in ${altFixed} files (${totalAltIssues} issues)`));
178
222
 
179
- showCompletionMessage(options, 'Alt attribute fixes');
223
+ // Run cleanup
224
+ console.log(chalk.blue('\n๐Ÿงน Running cleanup for duplicate role attributes...'));
225
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
226
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
227
+ console.log(chalk.green(`โœ… Cleaned duplicate roles in ${cleanupFixed} files`));
228
+
229
+ showCompletionMessage(options, 'Alt attribute fixes + cleanup');
180
230
  return;
181
231
 
182
232
  } else if (options.langOnly) {
183
- // Only fix lang attributes
184
- console.log(chalk.blue('๐Ÿ“ Running HTML lang attribute fixes only...'));
233
+ // Fix lang attributes + cleanup
234
+ console.log(chalk.blue('๐Ÿ“ Running HTML lang attribute fixes + cleanup...'));
185
235
  const langResults = await fixer.fixHtmlLang(options.directory);
186
236
  const langFixed = langResults.filter(r => r.status === 'fixed').length;
187
237
 
188
238
  console.log(chalk.green(`\nโœ… Fixed lang attributes in ${langFixed} files`));
189
239
 
190
- showCompletionMessage(options, 'Lang attribute fixes');
240
+ // Run cleanup
241
+ console.log(chalk.blue('\n๐Ÿงน Running cleanup for duplicate role attributes...'));
242
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
243
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
244
+ console.log(chalk.green(`โœ… Cleaned duplicate roles in ${cleanupFixed} files`));
245
+
246
+ showCompletionMessage(options, 'Lang attribute fixes + cleanup');
191
247
  return;
192
248
 
193
249
  } else if (options.roleOnly) {
194
- // Only fix role attributes
195
- console.log(chalk.blue('๐ŸŽญ Running role attribute fixes only...'));
250
+ // Fix role attributes + cleanup
251
+ console.log(chalk.blue('๐ŸŽญ Running role attribute fixes + cleanup...'));
196
252
  const roleResults = await fixer.fixRoleAttributes(options.directory);
197
253
  const roleFixed = roleResults.filter(r => r.status === 'fixed').length;
198
254
  const totalRoleIssues = roleResults.reduce((sum, r) => sum + (r.issues || 0), 0);
199
255
 
200
256
  console.log(chalk.green(`\nโœ… Fixed role attributes in ${roleFixed} files (${totalRoleIssues} issues)`));
201
257
 
202
- showCompletionMessage(options, 'Role attribute fixes');
258
+ // Run cleanup
259
+ console.log(chalk.blue('\n๐Ÿงน Running cleanup for duplicate role attributes...'));
260
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
261
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
262
+ console.log(chalk.green(`โœ… Cleaned duplicate roles in ${cleanupFixed} files`));
263
+
264
+ showCompletionMessage(options, 'Role attribute fixes + cleanup');
265
+ return;
266
+
267
+ } else if (options.formsOnly) {
268
+ // Fix form labels + cleanup
269
+ console.log(chalk.blue('๐Ÿ“‹ Running form label fixes + cleanup...'));
270
+ const formResults = await fixer.fixFormLabels(options.directory);
271
+ const formFixed = formResults.filter(r => r.status === 'fixed').length;
272
+ const totalFormIssues = formResults.reduce((sum, r) => sum + (r.issues || 0), 0);
273
+
274
+ console.log(chalk.green(`\nโœ… Fixed form labels in ${formFixed} files (${totalFormIssues} issues)`));
275
+
276
+ // Run cleanup
277
+ console.log(chalk.blue('\n๐Ÿงน Running cleanup for duplicate role attributes...'));
278
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
279
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
280
+ console.log(chalk.green(`โœ… Cleaned duplicate roles in ${cleanupFixed} files`));
281
+
282
+ showCompletionMessage(options, 'Form label fixes + cleanup');
283
+ return;
284
+
285
+ } else if (options.buttonsOnly) {
286
+ // Fix button names + cleanup
287
+ console.log(chalk.blue('๐Ÿ”˜ Running button name fixes + cleanup...'));
288
+ const buttonResults = await fixer.fixButtonNames(options.directory);
289
+ const buttonFixed = buttonResults.filter(r => r.status === 'fixed').length;
290
+ const totalButtonIssues = buttonResults.reduce((sum, r) => sum + (r.issues || 0), 0);
291
+
292
+ console.log(chalk.green(`\nโœ… Fixed button names in ${buttonFixed} files (${totalButtonIssues} issues)`));
293
+
294
+ // Run cleanup
295
+ console.log(chalk.blue('\n๐Ÿงน Running cleanup for duplicate role attributes...'));
296
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
297
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
298
+ console.log(chalk.green(`โœ… Cleaned duplicate roles in ${cleanupFixed} files`));
299
+
300
+ showCompletionMessage(options, 'Button name fixes + cleanup');
301
+ return;
302
+
303
+ } else if (options.linksOnly) {
304
+ // Fix link names + cleanup
305
+ console.log(chalk.blue('๐Ÿ”— Running link name fixes + cleanup...'));
306
+ const linkResults = await fixer.fixLinkNames(options.directory);
307
+ const linkFixed = linkResults.filter(r => r.status === 'fixed').length;
308
+ const totalLinkIssues = linkResults.reduce((sum, r) => sum + (r.issues || 0), 0);
309
+
310
+ console.log(chalk.green(`\nโœ… Fixed link names in ${linkFixed} files (${totalLinkIssues} issues)`));
311
+
312
+ // Run cleanup
313
+ console.log(chalk.blue('\n๐Ÿงน Running cleanup for duplicate role attributes...'));
314
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
315
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
316
+ console.log(chalk.green(`โœ… Cleaned duplicate roles in ${cleanupFixed} files`));
317
+
318
+ showCompletionMessage(options, 'Link name fixes + cleanup');
319
+ return;
320
+
321
+ } else if (options.landmarksOnly) {
322
+ // Fix landmarks + cleanup
323
+ console.log(chalk.blue('๐Ÿ›๏ธ Running landmark fixes + cleanup...'));
324
+ const landmarkResults = await fixer.fixLandmarks(options.directory);
325
+ const landmarkFixed = landmarkResults.filter(r => r.status === 'fixed').length;
326
+ const totalLandmarkIssues = landmarkResults.reduce((sum, r) => sum + (r.issues || 0), 0);
327
+
328
+ console.log(chalk.green(`\nโœ… Fixed landmarks in ${landmarkFixed} files (${totalLandmarkIssues} issues)`));
329
+
330
+ // Run cleanup
331
+ console.log(chalk.blue('\n๐Ÿงน Running cleanup for duplicate role attributes...'));
332
+ const cleanupResults = await fixer.cleanupDuplicateRoles(options.directory);
333
+ const cleanupFixed = cleanupResults.filter(r => r.status === 'fixed').length;
334
+ console.log(chalk.green(`โœ… Cleaned duplicate roles in ${cleanupFixed} files`));
335
+
336
+ showCompletionMessage(options, 'Landmark fixes + cleanup');
337
+ return;
338
+
339
+ } else if (options.headingsOnly) {
340
+ // Analyze headings only (no fixes, no cleanup)
341
+ console.log(chalk.blue('๐Ÿ“‘ Running heading analysis only...'));
342
+ const headingResults = await fixer.analyzeHeadings(options.directory);
343
+ const totalSuggestions = headingResults.reduce((sum, r) => sum + (r.issues || 0), 0);
344
+
345
+ console.log(chalk.green(`\nโœ… Analyzed headings in ${headingResults.length} files (${totalSuggestions} suggestions)`));
346
+ console.log(chalk.gray('๐Ÿ’ก Heading issues require manual review and cannot be auto-fixed'));
347
+
348
+ showCompletionMessage(options, 'Heading analysis');
203
349
  return;
204
350
  }
205
351
 
206
- // Standard mode - run individual fixes
207
- // Fix HTML lang attributes
208
- console.log(chalk.yellow('๐Ÿ“ Step 1: Fixing HTML lang attributes...'));
209
- const langResults = await fixer.fixHtmlLang(options.directory);
210
- const langFixed = langResults.filter(r => r.status === 'fixed').length;
211
- console.log(chalk.green(`โœ… Fixed lang attributes in ${langFixed} files`));
212
- console.log('');
213
-
214
- // Fix alt attributes
215
- console.log(chalk.yellow('๐Ÿ–ผ๏ธ Step 2: Fixing alt attributes...'));
216
- const altResults = await fixer.fixEmptyAltAttributes(options.directory);
217
- const altFixed = altResults.filter(r => r.status === 'fixed').length;
218
- const totalAltIssues = altResults.reduce((sum, r) => sum + (r.issues || 0), 0);
219
- console.log(chalk.green(`โœ… Fixed alt attributes in ${altFixed} files (${totalAltIssues} issues)`));
220
- console.log('');
221
-
222
- // Fix role attributes
223
- console.log(chalk.yellow('๐ŸŽญ Step 3: Fixing role attributes...'));
224
- const roleResults = await fixer.fixRoleAttributes(options.directory);
225
- const roleFixed = roleResults.filter(r => r.status === 'fixed').length;
226
- const totalRoleIssues = roleResults.reduce((sum, r) => sum + (r.issues || 0), 0);
227
- console.log(chalk.green(`โœ… Fixed role attributes in ${roleFixed} files (${totalRoleIssues} issues)`));
228
- console.log('');
229
-
230
- // Summary
231
- const totalFiles = new Set([
232
- ...langResults.map(r => r.file),
233
- ...altResults.map(r => r.file),
234
- ...roleResults.map(r => r.file)
235
- ]).size;
236
-
237
- const totalFixed = new Set([
238
- ...langResults.filter(r => r.status === 'fixed').map(r => r.file),
239
- ...altResults.filter(r => r.status === 'fixed').map(r => r.file),
240
- ...roleResults.filter(r => r.status === 'fixed').map(r => r.file)
241
- ]).size;
242
-
243
- const totalIssues = totalAltIssues + totalRoleIssues + langFixed;
244
-
245
- console.log(chalk.blue('๐Ÿ“Š Summary:'));
246
- console.log(chalk.white(` Total files scanned: ${totalFiles}`));
247
- console.log(chalk.green(` Files fixed: ${totalFixed}`));
248
- console.log(chalk.yellow(` Total issues resolved: ${totalIssues}`));
249
-
250
- showCompletionMessage(options, 'All accessibility fixes');
251
-
252
- // Suggest cleanup if not comprehensive mode
253
- console.log(chalk.blue('\n๐Ÿ’ก Pro tip: Use --comprehensive to include duplicate role cleanup!'));
254
-
255
352
  } catch (error) {
256
353
  console.error(chalk.red('โŒ Error occurred:'), error.message);
257
354
  process.exit(1);
@@ -0,0 +1,44 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Advanced Accessibility Test</title>
6
+ </head>
7
+ <body>
8
+ <h1>Advanced Accessibility Test</h1>
9
+
10
+ <!-- Form issues -->
11
+ <form>
12
+ <input type="text" placeholder="Name">
13
+ <input type="email" id="email">
14
+ <input type="password">
15
+ <input type="submit">
16
+ </form>
17
+
18
+ <!-- Button issues -->
19
+ <button></button>
20
+ <button onclick="alert('test')"></button>
21
+ <input type="button">
22
+
23
+ <!-- Link issues -->
24
+ <a href="/home"></a>
25
+ <a href="/more">Click here</a>
26
+ <a href="/read">Read more</a>
27
+ <a href="/image"><img src="icon.png"></a>
28
+
29
+ <!-- Heading issues -->
30
+ <h3>Skipped h2</h3>
31
+ <h1>Second h1</h1>
32
+ <h4></h4>
33
+
34
+ <!-- Landmark issues -->
35
+ <div class="content">
36
+ <p>Main content without landmark</p>
37
+ </div>
38
+
39
+ <ul class="navigation">
40
+ <li><a href="/home">Home</a></li>
41
+ <li><a href="/about">About</a></li>
42
+ </ul>
43
+ </body>
44
+ </html>
@@ -0,0 +1,44 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Advanced Accessibility Test</title>
6
+ </head>
7
+ <body>
8
+ <h1>Advanced Accessibility Test</h1>
9
+
10
+ <!-- Form issues -->
11
+ <form>
12
+ <input type="text" placeholder="Name">
13
+ <input type="email" id="email">
14
+ <input type="password">
15
+ <input type="submit">
16
+ </form>
17
+
18
+ <!-- Button issues -->
19
+ <button></button>
20
+ <button onclick="alert('test')"></button>
21
+ <input type="button">
22
+
23
+ <!-- Link issues -->
24
+ <a href="/home"></a>
25
+ <a href="/more">Click here</a>
26
+ <a href="/read">Read more</a>
27
+ <a href="/image"><img src="icon.png"></a>
28
+
29
+ <!-- Heading issues -->
30
+ <h3>Skipped h2</h3>
31
+ <h1>Second h1</h1>
32
+ <h4></h4>
33
+
34
+ <!-- Landmark issues -->
35
+ <div class="content">
36
+ <p>Main content without landmark</p>
37
+ </div>
38
+
39
+ <ul class="navigation">
40
+ <li><a href="/home">Home</a></li>
41
+ <li><a href="/about">About</a></li>
42
+ </ul>
43
+ </body>
44
+ </html>
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Comprehensive Test</title>
6
+ </head>
7
+ <body>
8
+ <h1>Comprehensive Test File</h1>
9
+
10
+ <!-- Missing alt -->
11
+ <img src="test.jpg">
12
+
13
+ <!-- Missing role -->
14
+ <a href="/home">Home</a>
15
+
16
+ <!-- Duplicate roles -->
17
+ <img src="dup.jpg" alt="Duplicate" role="img" role="img">
18
+
19
+ <p>This tests comprehensive mode as default.</p>
20
+ </body>
21
+ </html>
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Comprehensive Test</title>
6
+ </head>
7
+ <body>
8
+ <h1>Comprehensive Test File</h1>
9
+
10
+ <!-- Missing alt -->
11
+ <img src="test.jpg">
12
+
13
+ <!-- Missing role -->
14
+ <a href="/home">Home</a>
15
+
16
+ <!-- Duplicate roles -->
17
+ <img src="dup.jpg" alt="Duplicate" role="img" role="img">
18
+
19
+ <p>This tests comprehensive mode as default.</p>
20
+ </body>
21
+ </html>