gbu-accessibility-package 1.1.0 → 1.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 GBU Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/QUICK_START.md CHANGED
@@ -1,19 +1,18 @@
1
1
  # 🚀 Quick Start Guide
2
2
 
3
- Hướng dẫn nhanh để sử dụng Accessibility Fixer trong 5 phút.
3
+ Hướng dẫn nhanh để sử dụng GBU Accessibility Package trong 5 phút.
4
4
 
5
5
  ## ⚡ Cài đặt nhanh
6
6
 
7
7
  ```bash
8
- # 1. Copy package vào dự án
9
- cp -r accessibility-package /path/to/your/project/
8
+ # 1. Cài đặt global (khuyến nghị)
9
+ npm install -g gbu-accessibility-package
10
10
 
11
- # 2. Cài đặt dependencies
12
- cd your-project/accessibility-package
13
- npm install
11
+ # 2. Hoặc cài đặt local
12
+ npm install gbu-accessibility-package
14
13
 
15
14
  # 3. Chạy ngay!
16
- node cli.js
15
+ gbu-a11y
17
16
  ```
18
17
 
19
18
  ## 🎯 Sử dụng cơ bản
@@ -22,16 +21,19 @@ node cli.js
22
21
 
23
22
  ```bash
24
23
  # Fix toàn bộ dự án (current directory)
25
- node accessibility-package/cli.js
24
+ gbu-a11y
26
25
 
27
26
  # Fix thư mục cụ thể
28
- node accessibility-package/cli.js ./src
27
+ gbu-a11y ./src
29
28
 
30
29
  # Preview trước khi fix
31
- node accessibility-package/cli.js --dry-run
30
+ gbu-a11y --dry-run
32
31
 
33
32
  # Fix với ngôn ngữ khác
34
- node accessibility-package/cli.js -l en ./dist
33
+ gbu-a11y -l en ./dist
34
+
35
+ # Fix comprehensive (khuyến nghị)
36
+ gbu-a11y --comprehensive
35
37
  ```
36
38
 
37
39
  ### Cách 2: Node.js Script
@@ -39,7 +41,7 @@ node accessibility-package/cli.js -l en ./dist
39
41
  Tạo file `fix.js`:
40
42
 
41
43
  ```javascript
42
- const AccessibilityFixer = require('./accessibility-package/lib/fixer.js');
44
+ const AccessibilityFixer = require('gbu-accessibility-package');
43
45
 
44
46
  const fixer = new AccessibilityFixer({
45
47
  language: 'ja', // Thay đổi theo dự án
@@ -48,9 +50,8 @@ const fixer = new AccessibilityFixer({
48
50
  });
49
51
 
50
52
  async function fix() {
51
- await fixer.fixHtmlLang('.');
52
- await fixer.fixEmptyAltAttributes('.');
53
- await fixer.fixRoleAttributes('.');
53
+ // Fix tất cả issues
54
+ await fixer.fixAllAccessibilityIssues('.');
54
55
  console.log('✅ Done!');
55
56
  }
56
57
 
@@ -61,11 +62,10 @@ Chạy: `node fix.js`
61
62
 
62
63
  ## 📋 Checklist nhanh
63
64
 
64
- - [ ] Copy package vào dự án
65
- - [ ] `npm install` trong thư mục package
65
+ - [ ] `npm install -g gbu-accessibility-package`
66
66
  - [ ] Backup code (git commit)
67
- - [ ] Chạy `--dry-run` để preview
68
- - [ ] Chạy tool để fix
67
+ - [ ] Chạy `gbu-a11y --dry-run` để preview
68
+ - [ ] Chạy `gbu-a11y --comprehensive` để fix
69
69
  - [ ] Kiểm tra kết quả
70
70
  - [ ] Commit changes
71
71
 
@@ -103,19 +103,19 @@ language: 'en' // 'ja', 'vi', 'zh', etc.
103
103
 
104
104
  ### Không tạo backup
105
105
  ```bash
106
- node cli.js --no-backup
106
+ gbu-a11y --no-backup
107
107
  ```
108
108
 
109
109
  ### Chỉ preview
110
110
  ```bash
111
- node cli.js --dry-run
111
+ gbu-a11y --dry-run
112
112
  ```
113
113
 
114
114
  ## ❓ Troubleshooting
115
115
 
116
116
  **Lỗi "Cannot find module"**
117
117
  ```bash
118
- cd accessibility-package && npm install
118
+ npm install -g gbu-accessibility-package
119
119
  ```
120
120
 
121
121
  **Duplicate attributes**
@@ -130,7 +130,7 @@ cd accessibility-package && npm install
130
130
 
131
131
  1. Đọc [README.md](./README.md) đầy đủ
132
132
  2. Xem [example.js](./example.js)
133
- 3. Chạy `node cli.js --help`
133
+ 3. Chạy `gbu-a11y --help`
134
134
 
135
135
  ---
136
136
 
package/README.md CHANGED
@@ -1,335 +1,292 @@
1
1
  # GBU Accessibility Package
2
2
 
3
- [![npm version](https://badge.fury.io/js/gbu-accessibility-package.svg)](https://badge.fury.io/js/gbu-accessibility-package)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
3
+ 🚀 **Automated accessibility fixes for HTML files** - Smart, context-aware accessibility improvements with zero configuration.
5
4
 
6
- Một công cụ tự động sửa các vấn đề accessibility phổ biến trong HTML, bao gồm alt attributes, lang attributes, và role attributes với khả năng phân tích context thông minh.
5
+ [![npm version](https://badge.fury.io/js/gbu-accessibility-package.svg)](https://www.npmjs.com/package/gbu-accessibility-package)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![Node.js Version](https://img.shields.io/badge/node-%3E%3D12.0.0-brightgreen)](https://nodejs.org/)
7
8
 
8
- ## 🚀 Tính năng
9
+ ## Features
9
10
 
10
- - **Alt Attributes**: Tự động thêm alt text thông minh cho images
11
- - **Lang Attributes**: Thêm lang attribute cho thẻ `<html>`
12
- - **Role Attributes**: Thêm role attributes cho các elements
13
- - `role="img"` cho tất cả thẻ `<img>`
14
- - `role="link"` cho thẻ `<a>`
15
- - `role="button"` cho elements onclick
16
- - `role="menubar"` `role="menuitem"` cho navigation lists
17
- - **Duplicate Cleanup**: Tự động xóa duplicate role attributes
18
- - ✅ **Context-aware**: Phân tích nội dung xung quanh để tạo alt text phù hợp
19
- - ✅ **Backup tự động**: Tạo backup files trước khi sửa
20
- - ✅ **Dry run mode**: Xem preview trước khi apply changes
21
- - ✅ **Comprehensive mode**: Chạy tất cả fixes trong một lần
11
+ - 🖼️ **Smart Alt Text Generation** - Context-aware alt attributes for images
12
+ - 🌐 **HTML Lang Attributes** - Automatic language attribute fixes
13
+ - 🎭 **Role Attributes** - WCAG-compliant role attribute management
14
+ - 🧹 **Duplicate Cleanup** - Remove duplicate role attributes
15
+ - 📁 **Batch Processing** - Process entire directories recursively
16
+ - 💾 **Automatic Backups** - Safe modifications with backup files
17
+ - 🔍 **Dry Run Mode** - Preview changes before applying
18
+ - 📊 **Detailed Reports** - Comprehensive fix summaries
22
19
 
23
- ## 📦 Cài đặt
20
+ ## 🚀 Quick Start
24
21
 
25
- ### NPM Install (Khuyến nghị)
22
+ ### Installation
26
23
 
27
24
  ```bash
28
- # Cài đặt global
25
+ # Global installation (recommended)
29
26
  npm install -g gbu-accessibility-package
30
27
 
31
- # Hoặc cài đặt local cho dự án
32
- npm install gbu-accessibility-package --save-dev
28
+ # Local installation
29
+ npm install gbu-accessibility-package
33
30
  ```
34
31
 
35
- ### Yarn Install
32
+ ### Basic Usage
36
33
 
37
34
  ```bash
38
- # Global
39
- yarn global add gbu-accessibility-package
40
-
41
- # Local
42
- yarn add gbu-accessibility-package --dev
43
- ```
35
+ # Fix current directory
36
+ gbu-a11y
44
37
 
45
- ## 🛠️ Sử dụng
38
+ # Preview changes (dry run)
39
+ gbu-a11y --dry-run
46
40
 
47
- ### Cách 1: Sử dụng CLI (Global Install)
41
+ # Fix specific directory
42
+ gbu-a11y ./src
48
43
 
49
- ```bash
50
- # Sau khi cài đặt global
51
- gbu-a11y [options] [directory]
44
+ # Comprehensive fixes (recommended)
45
+ gbu-a11y --comprehensive
52
46
 
53
- # Hoặc
54
- accessibility-fixer [options] [directory]
47
+ # Fix specific file
48
+ gbu-a11y index.html
55
49
  ```
56
50
 
57
- ### Cách 1b: CLI (Local Install)
51
+ ## 📖 Detailed Usage
58
52
 
59
- ```bash
60
- # Chạy từ node_modules
61
- npx gbu-a11y [options] [directory]
53
+ ### Command Line Options
62
54
 
63
- # Hoặc thêm vào package.json scripts
64
- {
65
- "scripts": {
66
- "fix-a11y": "gbu-a11y --comprehensive",
67
- "preview-a11y": "gbu-a11y --comprehensive --dry-run",
68
- "cleanup-roles": "gbu-a11y --cleanup-only"
69
- }
70
- }
55
+ ```bash
56
+ gbu-a11y [options] [directory/file]
57
+
58
+ Options:
59
+ -d, --directory <path> Target directory (default: current directory)
60
+ -l, --language <lang> Language for lang attribute (default: ja)
61
+ --no-backup Don't create backup files
62
+ --dry-run Preview changes without applying
63
+ --cleanup-only Only cleanup duplicate role attributes
64
+ --comprehensive, --all Run all fixes including cleanup (recommended)
65
+ -h, --help Show help message
71
66
  ```
72
67
 
73
- ### Cách 2: Sử dụng trong Node.js
68
+ ### Examples
74
69
 
75
- ```javascript
76
- const AccessibilityFixer = require('gbu-accessibility-package');
70
+ ```bash
71
+ # Basic fixes for current directory
72
+ gbu-a11y
77
73
 
78
- // Tạo instance với config
79
- const fixer = new AccessibilityFixer({
80
- language: 'ja', // Ngôn ngữ cho lang attribute
81
- backupFiles: true, // Tạo backup files
82
- dryRun: false // false = apply changes, true = preview only
83
- });
74
+ # Preview all changes
75
+ gbu-a11y --dry-run --comprehensive
84
76
 
85
- // Sử dụng các methods
86
- async function fixAccessibility() {
87
- // Fix lang attributes
88
- const langResults = await fixer.fixHtmlLang('.');
89
-
90
- // Fix alt attributes
91
- const altResults = await fixer.fixEmptyAltAttributes('.');
92
-
93
- // Fix role attributes
94
- const roleResults = await fixer.fixRoleAttributes('.');
95
-
96
- console.log('Hoàn thành!');
97
- }
77
+ # Fix with English language
78
+ gbu-a11y -l en ./public
98
79
 
99
- fixAccessibility();
100
- ```
80
+ # Only cleanup duplicates
81
+ gbu-a11y --cleanup-only
101
82
 
102
- ### Cách 3: Script nhanh
83
+ # Fix without creating backups
84
+ gbu-a11y --no-backup ./dist
85
+ ```
103
86
 
104
- Tạo file `fix-accessibility.js` trong dự án:
87
+ ## 🔧 Programmatic Usage
105
88
 
106
89
  ```javascript
107
90
  const AccessibilityFixer = require('gbu-accessibility-package');
108
91
 
109
92
  const fixer = new AccessibilityFixer({
110
- language: 'ja', // Thay đổi theo ngôn ngữ dự án
93
+ language: 'en',
111
94
  backupFiles: true,
112
95
  dryRun: false
113
96
  });
114
97
 
115
- async function fixAll() {
116
- console.log('🚀 Bắt đầu fix accessibility...');
117
-
118
- // Fix tất cả issues
119
- await fixer.fixHtmlLang('.');
120
- await fixer.fixEmptyAltAttributes('.');
121
- await fixer.fixRoleAttributes('.');
122
-
123
- console.log('✅ Hoàn thành!');
98
+ // Fix all accessibility issues
99
+ async function fixAccessibility() {
100
+ try {
101
+ const results = await fixer.fixAllAccessibilityIssues('./src');
102
+ console.log('Fixed files:', results);
103
+ } catch (error) {
104
+ console.error('Error:', error);
105
+ }
124
106
  }
125
107
 
126
- fixAll();
108
+ fixAccessibility();
127
109
  ```
128
110
 
129
- Chạy script:
130
- ```bash
131
- node fix-accessibility.js
132
- ```
111
+ ## 🎯 What Gets Fixed
133
112
 
134
- ## ⚙️ Configuration Options
113
+ ### 1. Alt Attributes
114
+ - **Missing alt attributes** → Adds contextual alt text
115
+ - **Empty alt attributes** → Generates meaningful descriptions
116
+ - **Context-aware generation** → Uses surrounding text, headings, captions
135
117
 
136
- ```javascript
137
- const config = {
138
- language: 'ja', // Lang attribute value ('ja', 'en', 'vi', etc.)
139
- backupFiles: true, // Tạo .backup files
140
- dryRun: false // true = chỉ preview, false = apply changes
141
- };
118
+ ```html
119
+ <!-- Before -->
120
+ <img src="logo.png">
121
+ <img src="chart.jpg" alt="">
142
122
 
143
- const fixer = new AccessibilityFixer(config);
123
+ <!-- After -->
124
+ <img src="logo.png" alt="ロゴ">
125
+ <img src="chart.jpg" alt="グラフ">
144
126
  ```
145
127
 
146
- ## 📋 Các Methods có sẵn
128
+ ### 2. HTML Lang Attributes
129
+ - **Missing lang attributes** → Adds specified language
130
+ - **Empty lang attributes** → Sets proper language code
147
131
 
148
- ### 1. fixHtmlLang(directory)
149
- Thêm lang attribute cho thẻ `<html>`
132
+ ```html
133
+ <!-- Before -->
134
+ <html>
135
+ <html lang="">
150
136
 
151
- ```javascript
152
- const results = await fixer.fixHtmlLang('./src');
137
+ <!-- After -->
138
+ <html lang="ja">
139
+ <html lang="ja">
153
140
  ```
154
141
 
155
- ### 2. fixEmptyAltAttributes(directory)
156
- Sửa missing/empty alt attributes cho images
142
+ ### 3. Role Attributes
143
+ - **Images** `role="img"`
144
+ - **Links** → `role="link"`
145
+ - **Clickable elements** → `role="button"`
146
+ - **Navigation lists** → `role="menubar"`
147
+ - **Menu items** → `role="menuitem"`
157
148
 
158
- ```javascript
159
- const results = await fixer.fixEmptyAltAttributes('./src');
149
+ ```html
150
+ <!-- Before -->
151
+ <img src="icon.png" alt="Icon">
152
+ <a href="/home">Home</a>
153
+ <div class="btn-click">Click me</div>
154
+
155
+ <!-- After -->
156
+ <img src="icon.png" alt="Icon" role="img">
157
+ <a href="/home" role="link">Home</a>
158
+ <div class="btn-click" role="button">Click me</div>
160
159
  ```
161
160
 
162
- ### 3. fixRoleAttributes(directory)
163
- Thêm role attributes cho các elements
161
+ ### 4. Duplicate Cleanup
162
+ - **Removes duplicate role attributes**
163
+ - **Preserves first occurrence**
164
+ - **Handles mixed quote styles**
164
165
 
165
- ```javascript
166
- const results = await fixer.fixRoleAttributes('./src');
166
+ ```html
167
+ <!-- Before -->
168
+ <img src="test.jpg" role="img" role="img" alt="Test">
169
+
170
+ <!-- After -->
171
+ <img src="test.jpg" role="img" alt="Test">
167
172
  ```
168
173
 
169
- ### 4. cleanupDuplicateRoles(directory)
170
- Xóa duplicate role attributes
174
+ ## 🌟 Smart Alt Text Generation
171
175
 
172
- ```javascript
173
- const results = await fixer.cleanupDuplicateRoles('./src');
174
- ```
176
+ The package uses intelligent context analysis to generate meaningful alt text:
175
177
 
176
- ### 5. fixAllAccessibilityIssues(directory)
177
- Chạy tất cả fixes bao gồm cleanup (khuyến nghị)
178
+ ### Context Sources
179
+ 1. **Title attributes**
180
+ 2. **Aria-label attributes**
181
+ 3. **Definition terms (dt elements)**
182
+ 4. **Parent link text**
183
+ 5. **Nearby headings**
184
+ 6. **Figure captions**
185
+ 7. **Surrounding text content**
178
186
 
179
- ```javascript
180
- const results = await fixer.fixAllAccessibilityIssues('./src');
181
- ```
187
+ ### Fallback Patterns
188
+ - `logo.png` "ロゴ" (Logo)
189
+ - `icon.svg` → "アイコン" (Icon)
190
+ - `banner.jpg` → "バナー" (Banner)
191
+ - `chart.png` → "グラフ" (Chart)
192
+ - Generic images → "画像" (Image)
182
193
 
183
- ### 6. addMainLandmarks(directory)
184
- Phát hiện và suggest main landmarks
194
+ ## 📊 Output Examples
185
195
 
186
- ```javascript
187
- const suggestions = await fixer.addMainLandmarks('./src');
196
+ ### Standard Mode
188
197
  ```
198
+ 🚀 Starting Accessibility Fixer...
199
+ 📝 Step 1: Fixing HTML lang attributes...
200
+ ✅ Fixed lang attributes in 5 files
189
201
 
190
- ## 🎯 dụ kết quả
202
+ 🖼️ Step 2: Fixing alt attributes...
203
+ ✅ Fixed alt attributes in 12 files (34 issues)
191
204
 
192
- ### Alt Attributes
193
- ```html
194
- <!-- Trước -->
195
- <img src="logo.png">
196
- <img src="icon.png" alt="">
205
+ 🎭 Step 3: Fixing role attributes...
206
+ ✅ Fixed role attributes in 8 files (67 issues)
197
207
 
198
- <!-- Sau -->
199
- <img src="logo.png" alt="ロゴ">
200
- <img src="icon.png" alt="アイコン">
201
- ```
208
+ 📊 Summary:
209
+ Total files scanned: 25
210
+ Files fixed: 15
211
+ Total issues resolved: 106
202
212
 
203
- ### Role Attributes
204
- ```html
205
- <!-- Trước -->
206
- <img src="photo.jpg" alt="Beautiful sunset">
207
- <a href="/about">About Us</a>
208
- <button onclick="submit()">Submit</button>
209
-
210
- <!-- Sau -->
211
- <img src="photo.jpg" alt="Beautiful sunset" role="img">
212
- <a href="/about" role="link">About Us</a>
213
- <button onclick="submit()" role="button">Submit</button>
213
+ 🎉 All accessibility fixes completed successfully!
214
214
  ```
215
215
 
216
- ### Duplicate Cleanup
217
- ```html
218
- <!-- Trước -->
219
- <img src="logo.png" alt="Logo" role="img" role="img" role="img">
220
- <a href="/home" role="link" role="link">Home</a>
221
- <button onclick="click()" role="button" role="button">Click</button>
222
-
223
- <!-- Sau -->
224
- <img src="logo.png" alt="Logo" role="img">
225
- <a href="/home" role="link">Home</a>
226
- <button onclick="click()" role="button">Click</button>
216
+ ### Comprehensive Mode
227
217
  ```
228
-
229
- ### Lang Attributes
230
- ```html
231
- <!-- Trước -->
232
- <html>
233
-
234
- <!-- Sau -->
235
- <html lang="ja">
218
+ 🎯 Running comprehensive accessibility fixes...
219
+ 📝 Step 1: HTML lang attributes...
220
+ 🖼️ Step 2: Alt attributes...
221
+ 🎭 Step 3: Role attributes...
222
+ 🧹 Step 4: Cleanup duplicate roles...
223
+
224
+ 🎉 All accessibility fixes completed!
225
+ 📊 Final Summary:
226
+ Total files scanned: 25
227
+ Files fixed: 15
228
+ Total issues resolved: 106
236
229
  ```
237
230
 
238
- ## 🔧 Customization
231
+ ## 🔒 Safety Features
239
232
 
240
- ### Thay đổi ngôn ngữ cho alt text
233
+ - **Automatic backups** with `.backup` extension
234
+ - **Dry run mode** for safe previewing
235
+ - **Non-destructive** - only adds missing attributes
236
+ - **Duplicate prevention** - won't add existing attributes
237
+ - **Error handling** - continues processing on individual file errors
241
238
 
242
- Sửa method `generateAltText` trong `lib/fixer.js`:
239
+ ## 🛠️ Configuration
243
240
 
244
- ```javascript
245
- generateAltText(imgTag, htmlContent = '', imgIndex = 0) {
246
- // Thay đổi các text này theo ngôn ngữ dự án
247
- if (srcValue.includes('logo')) {
248
- return 'Logo'; // Thay vì 'ロゴ'
249
- } else if (srcValue.includes('icon')) {
250
- return 'Icon'; // Thay vì 'アイコン'
241
+ ### Package.json Scripts
242
+ ```json
243
+ {
244
+ "scripts": {
245
+ "a11y:fix": "gbu-a11y",
246
+ "a11y:check": "gbu-a11y --dry-run",
247
+ "a11y:comprehensive": "gbu-a11y --comprehensive",
248
+ "a11y:cleanup": "gbu-a11y --cleanup-only"
251
249
  }
252
- // ... thêm các cases khác
253
250
  }
254
251
  ```
255
252
 
256
- ### Thêm role rules mới
257
-
258
- Sửa method `fixRoleAttributesInContent` để thêm rules:
259
-
260
- ```javascript
261
- // Ví dụ: thêm role cho form elements
262
- fixed = fixed.replace(
263
- /<form([^>]*)(?!.*role\s*=)([^>]*>)/gi,
264
- '<form$1 role="form"$2'
265
- );
266
- ```
267
-
268
- ## 🚨 Lưu ý quan trọng
269
-
270
- 1. **Backup**: Luôn tạo backup trước khi chạy tool
271
- 2. **Test**: Chạy với `dryRun: true` trước để xem preview
272
- 3. **Review**: Kiểm tra kết quả sau khi chạy
273
- 4. **Git**: Commit code trước khi chạy tool
274
-
275
- ## 📊 Monitoring Results
276
-
277
- Tool sẽ hiển thị:
278
- - Số files được xử lý
279
- - Số issues được tìm thấy và sửa
280
- - Chi tiết từng file
281
- - Thống kê tổng quan
253
+ ### CI/CD Integration
254
+ ```yaml
255
+ # GitHub Actions example
256
+ - name: Check Accessibility
257
+ run: npx gbu-accessibility-package --dry-run
282
258
 
283
- ```
284
- 📁 index.html:
285
- 🖼️ Missing role: Image 1 should have role="img"
286
- 🔗 Missing role: Anchor 1 should have role="link"
287
- 🖼️ Added role="img" to image element
288
- 🔗 Added role="link" to anchor element
289
- ✅ Fixed role attributes in: index.html
290
-
291
- 📊 Summary: Found 245 role attribute issues across 50 files
259
+ - name: Fix Accessibility Issues
260
+ run: npx gbu-accessibility-package --comprehensive
292
261
  ```
293
262
 
294
- ## 🛠️ Troubleshooting
263
+ ## 🤝 Contributing
295
264
 
296
- ### Lỗi "Cannot find module"
297
- ```bash
298
- cd accessibility-package
299
- npm install
300
- ```
265
+ 1. Fork the repository
266
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
267
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
268
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
269
+ 5. Open a Pull Request
301
270
 
302
- ### Duplicate role attributes
303
- Chạy cleanup script:
304
- ```javascript
305
- // Tạo file cleanup.js
306
- const fs = require('fs');
307
- const path = require('path');
308
-
309
- async function cleanup() {
310
- // Code cleanup duplicate roles
311
- const content = await fs.promises.readFile('file.html', 'utf8');
312
- const fixed = content.replace(/role="([^"]+)"(\s+role="\1")+/g, 'role="$1"');
313
- await fs.promises.writeFile('file.html', fixed);
314
- }
315
- ```
271
+ ## 📝 License
316
272
 
317
- ### Performance với project lớn
318
- - Chạy từng thư mục con
319
- - Sử dụng `dryRun: true` để test trước
320
- - Exclude thư mục không cần thiết
273
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
321
274
 
322
- ## 📝 License
275
+ ## 🆘 Support
323
276
 
324
- MIT License - Tự do sử dụng cho mọi dự án.
277
+ - 📧 **Issues**: [GitHub Issues](https://github.com/your-org/gbu-accessibility-package/issues)
278
+ - 📖 **Documentation**: [GitHub Wiki](https://github.com/your-org/gbu-accessibility-package/wiki)
279
+ - 💬 **Discussions**: [GitHub Discussions](https://github.com/your-org/gbu-accessibility-package/discussions)
325
280
 
326
- ## 🤝 Contributing
281
+ ## 🏆 Why Choose GBU Accessibility Package?
327
282
 
328
- 1. Fork repository
329
- 2. Tạo feature branch
330
- 3. Commit changes
331
- 4. Tạo Pull Request
283
+ - **Zero Configuration** - Works out of the box
284
+ - **Smart & Context-Aware** - Not just generic fixes
285
+ - **Safe & Reliable** - Automatic backups and dry run
286
+ - **Comprehensive** - Covers all major accessibility issues
287
+ - ✅ **Fast & Efficient** - Batch processing with detailed reports
288
+ - ✅ **WCAG Compliant** - Follows accessibility standards
332
289
 
333
290
  ---
334
291
 
335
- **Happy coding! 🚀**
292
+ Made with ❤️ by the GBU Team
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="ja">
3
3
  <head>
4
4
  <title>Test Duplicate Roles</title>
5
5
  </head>
@@ -7,29 +7,29 @@
7
7
  <h1>Test Duplicate Role Attributes</h1>
8
8
 
9
9
  <!-- Images with duplicate roles -->
10
- <img src="logo.png" alt="Logo" role="img" role="img">
11
- <img src="banner.jpg" alt="Banner" role="img" role="img" role="img">
10
+ <img src="logo.png" alt="Logo" role="img" role="img" role="img" role="img" role="img">
11
+ <img src="banner.jpg" alt="Banner" role="img" role="img" role="img" role="img" role="img" role="img">
12
12
 
13
13
  <!-- Links with duplicate roles -->
14
- <a href="/home" role="link" role="link">Home</a>
15
- <a href="/about" role="link" role="link" role="link">About</a>
14
+ <a href="/home" role="link" role="link" role="link" role="link" role="link">Home</a>
15
+ <a href="/about" role="link" role="link" role="link" role="link" role="link" role="link">About</a>
16
16
 
17
17
  <!-- Buttons with duplicate roles -->
18
- <button onclick="submit()" role="button" role="button">Submit</button>
18
+ <button onclick="submit()" role="button" role="button" role="button" role="button" role="button">Submit</button>
19
19
  <button type="button" role="button" role="button" role="button">Click Me</button>
20
20
 
21
21
  <!-- Mixed quotes -->
22
- <div onclick="toggle()" role="button" role='button'>Toggle</div>
23
- <span onclick="show()" role='button' role="button">Show</span>
22
+ <div onclick="toggle()" role="button" role='button' role="button" role="button" role="button">Toggle</div>
23
+ <span onclick="show()" role='button' role="button" role="button" role="button" role="button">Show</span>
24
24
 
25
25
  <!-- Navigation with duplicates -->
26
26
  <nav>
27
- <ul class="nav-menu" role="menubar" role="menubar">
28
- <li class="nav-item" role="menuitem" role="menuitem">
29
- <a href="/products" role="link" role="link">Products</a>
27
+ <ul class="nav-menu" role="menubar" role="menubar" role="menubar" role="menubar" role="menubar">
28
+ <li class="nav-item" role="menuitem" role="menuitem" role="menuitem" role="menuitem" role="menuitem">
29
+ <a href="/products" role="link" role="link" role="link" role="link" role="link">Products</a>
30
30
  </li>
31
- <li class="nav-item" role="menuitem" role="menuitem" role="menuitem">
32
- <a href="/services" role="link" role="link" role="link">Services</a>
31
+ <li class="nav-item" role="menuitem" role="menuitem" role="menuitem" role="menuitem" role="menuitem" role="menuitem">
32
+ <a href="/services" role="link" role="link" role="link" role="link" role="link" role="link">Services</a>
33
33
  </li>
34
34
  </ul>
35
35
  </nav>
@@ -37,9 +37,9 @@
37
37
  <!-- Complex duplicates -->
38
38
  <article>
39
39
  <h2>Article with Issues</h2>
40
- <img src="article1.jpg" alt="Article Image" role="img" role="img">
40
+ <img src="article1.jpg" alt="Article Image" role="img" role="img" role="img" role="img" role="img">
41
41
  <p>Some content...</p>
42
- <a href="/read-more" role="link" role="link" role="link" role="link">Read More</a>
42
+ <a href="/read-more" role="link" role="link" role="link" role="link" role="link" role="link" role="link">Read More</a>
43
43
  </article>
44
44
  </body>
45
45
  </html>
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="ja">
3
3
  <head>
4
4
  <title>Test Duplicate Roles</title>
5
5
  </head>
@@ -7,29 +7,29 @@
7
7
  <h1>Test Duplicate Role Attributes</h1>
8
8
 
9
9
  <!-- Images with duplicate roles -->
10
- <img src="logo.png" alt="Logo" role="img" role="img">
11
- <img src="banner.jpg" alt="Banner" role="img" role="img" role="img">
10
+ <img src="logo.png" alt="Logo" role="img" role="img" role="img" role="img">
11
+ <img src="banner.jpg" alt="Banner" role="img" role="img" role="img" role="img" role="img">
12
12
 
13
13
  <!-- Links with duplicate roles -->
14
- <a href="/home" role="link" role="link">Home</a>
15
- <a href="/about" role="link" role="link" role="link">About</a>
14
+ <a href="/home" role="link" role="link" role="link" role="link">Home</a>
15
+ <a href="/about" role="link" role="link" role="link" role="link" role="link">About</a>
16
16
 
17
17
  <!-- Buttons with duplicate roles -->
18
- <button onclick="submit()" role="button" role="button">Submit</button>
18
+ <button onclick="submit()" role="button" role="button" role="button" role="button">Submit</button>
19
19
  <button type="button" role="button" role="button" role="button">Click Me</button>
20
20
 
21
21
  <!-- Mixed quotes -->
22
- <div onclick="toggle()" role="button" role='button'>Toggle</div>
23
- <span onclick="show()" role='button' role="button">Show</span>
22
+ <div onclick="toggle()" role="button" role='button' role="button" role="button">Toggle</div>
23
+ <span onclick="show()" role='button' role="button" role="button" role="button">Show</span>
24
24
 
25
25
  <!-- Navigation with duplicates -->
26
26
  <nav>
27
- <ul class="nav-menu" role="menubar" role="menubar">
28
- <li class="nav-item" role="menuitem" role="menuitem">
29
- <a href="/products" role="link" role="link">Products</a>
27
+ <ul class="nav-menu" role="menubar" role="menubar" role="menubar" role="menubar">
28
+ <li class="nav-item" role="menuitem" role="menuitem" role="menuitem" role="menuitem">
29
+ <a href="/products" role="link" role="link" role="link" role="link">Products</a>
30
30
  </li>
31
- <li class="nav-item" role="menuitem" role="menuitem" role="menuitem">
32
- <a href="/services" role="link" role="link" role="link">Services</a>
31
+ <li class="nav-item" role="menuitem" role="menuitem" role="menuitem" role="menuitem" role="menuitem">
32
+ <a href="/services" role="link" role="link" role="link" role="link" role="link">Services</a>
33
33
  </li>
34
34
  </ul>
35
35
  </nav>
@@ -37,9 +37,9 @@
37
37
  <!-- Complex duplicates -->
38
38
  <article>
39
39
  <h2>Article with Issues</h2>
40
- <img src="article1.jpg" alt="Article Image" role="img" role="img">
40
+ <img src="article1.jpg" alt="Article Image" role="img" role="img" role="img" role="img">
41
41
  <p>Some content...</p>
42
- <a href="/read-more" role="link" role="link" role="link" role="link">Read More</a>
42
+ <a href="/read-more" role="link" role="link" role="link" role="link" role="link" role="link">Read More</a>
43
43
  </article>
44
44
  </body>
45
45
  </html>
package/demo/sample.html CHANGED
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="ja">
3
3
  <head>
4
4
  <title>Demo HTML for Accessibility Testing</title>
5
5
  </head>
@@ -7,27 +7,27 @@
7
7
  <h1>Sample Website</h1>
8
8
 
9
9
  <!-- Images without alt or role -->
10
- <img src="logo.png">
11
- <img src="banner.jpg" alt="">
12
- <img src="icon.svg" alt="Home Icon">
10
+ <img src="logo.png" alt="Sample Website" role="img" role="img" role="img">
11
+ <img src="banner.jpg" alt="Sample Website" role="img" role="img" role="img">
12
+ <img src="icon.svg" alt="Home Icon" role="img" role="img" role="img">
13
13
 
14
14
  <!-- Links without role -->
15
- <a href="/home">Home</a>
16
- <a href="/about">About Us</a>
15
+ <a href="/home" role="link" role="link" role="link">Home</a>
16
+ <a href="/about" role="link" role="link" role="link">About Us</a>
17
17
 
18
18
  <!-- Buttons without role -->
19
- <button onclick="submit()">Submit Form</button>
19
+ <button onclick="submit()" role="button" role="button" role="button">Submit Form</button>
20
20
  <button type="button">Regular Button</button>
21
21
 
22
22
  <!-- Clickable elements -->
23
- <div onclick="navigate()" class="btn">Click Me</div>
24
- <span onclick="toggle()">Toggle</span>
23
+ <div onclick="navigate()" class="btn" role="button" role="button" role="button" role="button" role="button" role="button">Click Me</div>
24
+ <span onclick="toggle()" role="button" role="button" role="button">Toggle</span>
25
25
 
26
26
  <!-- Navigation -->
27
27
  <nav>
28
- <ul class="nav-menu">
29
- <li class="nav-item"><a href="/products">Products</a></li>
30
- <li class="nav-item"><a href="/services">Services</a></li>
28
+ <ul class="nav-menu" role="menubar" role="menubar" role="menubar">
29
+ <li class="nav-item" role="menuitem"><a href="/products" role="link" role="link" role="link">Products</a></li>
30
+ <li class="nav-item" role="menuitem"><a href="/services" role="link" role="link" role="link">Services</a></li>
31
31
  </ul>
32
32
  </nav>
33
33
 
@@ -36,7 +36,7 @@
36
36
  <article>
37
37
  <h2>Article Title</h2>
38
38
  <p>Some content here...</p>
39
- <img src="article-image.jpg" alt="">
39
+ <img src="article-image.jpg" alt="Article Title" role="img" role="img" role="img">
40
40
  </article>
41
41
  </main>
42
42
 
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="ja">
3
3
  <head>
4
4
  <title>Demo HTML for Accessibility Testing</title>
5
5
  </head>
@@ -7,27 +7,27 @@
7
7
  <h1>Sample Website</h1>
8
8
 
9
9
  <!-- Images without alt or role -->
10
- <img src="logo.png">
11
- <img src="banner.jpg" alt="">
12
- <img src="icon.svg" alt="Home Icon">
10
+ <img src="logo.png" alt="Sample Website" role="img" role="img" role="img">
11
+ <img src="banner.jpg" alt="Sample Website" role="img" role="img" role="img">
12
+ <img src="icon.svg" alt="Home Icon" role="img" role="img" role="img">
13
13
 
14
14
  <!-- Links without role -->
15
- <a href="/home">Home</a>
16
- <a href="/about">About Us</a>
15
+ <a href="/home" role="link" role="link" role="link">Home</a>
16
+ <a href="/about" role="link" role="link" role="link">About Us</a>
17
17
 
18
18
  <!-- Buttons without role -->
19
- <button onclick="submit()">Submit Form</button>
19
+ <button onclick="submit()" role="button" role="button" role="button">Submit Form</button>
20
20
  <button type="button">Regular Button</button>
21
21
 
22
22
  <!-- Clickable elements -->
23
- <div onclick="navigate()" class="btn">Click Me</div>
24
- <span onclick="toggle()">Toggle</span>
23
+ <div onclick="navigate()" class="btn" role="button" role="button" role="button" role="button" role="button" role="button">Click Me</div>
24
+ <span onclick="toggle()" role="button" role="button" role="button">Toggle</span>
25
25
 
26
26
  <!-- Navigation -->
27
27
  <nav>
28
- <ul class="nav-menu">
29
- <li class="nav-item"><a href="/products">Products</a></li>
30
- <li class="nav-item"><a href="/services">Services</a></li>
28
+ <ul class="nav-menu" role="menubar" role="menubar" role="menubar">
29
+ <li class="nav-item"><a href="/products" role="link" role="link" role="link">Products</a></li>
30
+ <li class="nav-item"><a href="/services" role="link" role="link" role="link">Services</a></li>
31
31
  </ul>
32
32
  </nav>
33
33
 
@@ -36,7 +36,7 @@
36
36
  <article>
37
37
  <h2>Article Title</h2>
38
38
  <p>Some content here...</p>
39
- <img src="article-image.jpg" alt="">
39
+ <img src="article-image.jpg" alt="Article Title" role="img" role="img" role="img">
40
40
  </article>
41
41
  </main>
42
42
 
package/lib/fixer.js CHANGED
@@ -645,73 +645,105 @@ class AccessibilityFixer {
645
645
 
646
646
  // Fix all images - add role="img" (only if no role exists)
647
647
  fixed = fixed.replace(
648
- /<img([^>]*)(?!.*role\s*=)([^>]*>)/gi,
649
- (match, attrs, end) => {
648
+ /<img([^>]*>)/gi,
649
+ (match, fullTag) => {
650
+ // Check if role attribute already exists
651
+ if (/role\s*=/i.test(match)) {
652
+ return match; // Return unchanged if role already exists
653
+ }
650
654
  console.log(chalk.yellow(` 🖼️ Added role="img" to image element`));
651
- return `<img${attrs} role="img"${end}`;
655
+ return match.replace(/(<img[^>]*?)(\s*>)/i, '$1 role="img"$2');
652
656
  }
653
657
  );
654
658
 
655
659
  // Fix button elements with onclick - add role="button"
656
660
  fixed = fixed.replace(
657
- /<button([^>]*onclick[^>]*)(?!.*role\s*=)([^>]*>)/gi,
658
- (match, attrs, end) => {
661
+ /<button([^>]*onclick[^>]*>)/gi,
662
+ (match) => {
663
+ // Check if role attribute already exists
664
+ if (/role\s*=/i.test(match)) {
665
+ return match; // Return unchanged if role already exists
666
+ }
659
667
  console.log(chalk.yellow(` 🔘 Added role="button" to button with onclick`));
660
- return `<button${attrs} role="button"${end}`;
668
+ return match.replace(/(<button[^>]*?)(\s*>)/i, '$1 role="button"$2');
661
669
  }
662
670
  );
663
671
 
664
672
  // Fix anchor elements - add role="link"
665
673
  fixed = fixed.replace(
666
- /<a([^>]*href[^>]*)(?!.*role\s*=)([^>]*>)/gi,
667
- (match, attrs, end) => {
674
+ /<a([^>]*href[^>]*>)/gi,
675
+ (match) => {
676
+ // Check if role attribute already exists
677
+ if (/role\s*=/i.test(match)) {
678
+ return match; // Return unchanged if role already exists
679
+ }
668
680
  console.log(chalk.yellow(` 🔗 Added role="link" to anchor element`));
669
- return `<a${attrs} role="link"${end}`;
681
+ return match.replace(/(<a[^>]*?)(\s*>)/i, '$1 role="link"$2');
670
682
  }
671
683
  );
672
684
 
673
685
  // Fix any element with onclick (except a and button) - add role="button"
674
686
  fixed = fixed.replace(
675
- /<((?!a|button)[a-zA-Z][a-zA-Z0-9]*)([^>]*onclick[^>]*)(?!.*role\s*=)([^>]*>)/gi,
676
- (match, tag, attrs, end) => {
687
+ /<((?!a|button)[a-zA-Z][a-zA-Z0-9]*)([^>]*onclick[^>]*>)/gi,
688
+ (match, tag) => {
689
+ // Check if role attribute already exists
690
+ if (/role\s*=/i.test(match)) {
691
+ return match; // Return unchanged if role already exists
692
+ }
677
693
  console.log(chalk.yellow(` 🔘 Added role="button" to ${tag} with onclick`));
678
- return `<${tag}${attrs} role="button"${end}`;
694
+ return match.replace(/(<[^>]*?)(\s*>)/i, '$1 role="button"$2');
679
695
  }
680
696
  );
681
697
 
682
698
  // Fix clickable divs - add role="button"
683
699
  fixed = fixed.replace(
684
- /<div([^>]*class="[^"]*(?:btn|button|click)[^"]*"[^>]*)(?!.*role\s*=)([^>]*>)/gi,
685
- (match, attrs, end) => {
700
+ /<div([^>]*class="[^"]*(?:btn|button|click)[^"]*"[^>]*>)/gi,
701
+ (match) => {
702
+ // Check if role attribute already exists
703
+ if (/role\s*=/i.test(match)) {
704
+ return match; // Return unchanged if role already exists
705
+ }
686
706
  console.log(chalk.yellow(` 🔘 Added role="button" to clickable div`));
687
- return `<div${attrs} role="button"${end}`;
707
+ return match.replace(/(<div[^>]*?)(\s*>)/i, '$1 role="button"$2');
688
708
  }
689
709
  );
690
710
 
691
711
  // Fix focusable elements with tabindex
692
712
  fixed = fixed.replace(
693
- /<(div|span)([^>]*tabindex\s*=\s*[""']?[0-9-]+[""']?[^>]*)(?!.*role\s*=)([^>]*>)/gi,
694
- (match, tag, attrs, end) => {
713
+ /<(div|span)([^>]*tabindex\s*=\s*[""']?[0-9-]+[""']?[^>]*>)/gi,
714
+ (match, tag) => {
715
+ // Check if role attribute already exists
716
+ if (/role\s*=/i.test(match)) {
717
+ return match; // Return unchanged if role already exists
718
+ }
695
719
  console.log(chalk.yellow(` ⌨️ Added role="button" to focusable ${tag}`));
696
- return `<${tag}${attrs} role="button"${end}`;
720
+ return match.replace(/(<[^>]*?)(\s*>)/i, '$1 role="button"$2');
697
721
  }
698
722
  );
699
723
 
700
724
  // Fix navigation lists that should be menus
701
725
  fixed = fixed.replace(
702
- /<ul([^>]*class="[^"]*(?:nav|menu)[^"]*"[^>]*)(?!.*role\s*=)([^>]*>)/gi,
703
- (match, attrs, end) => {
726
+ /<ul([^>]*class="[^"]*(?:nav|menu)[^"]*"[^>]*>)/gi,
727
+ (match) => {
728
+ // Check if role attribute already exists
729
+ if (/role\s*=/i.test(match)) {
730
+ return match; // Return unchanged if role already exists
731
+ }
704
732
  console.log(chalk.yellow(` 📋 Added role="menubar" to navigation list`));
705
- return `<ul${attrs} role="menubar"${end}`;
733
+ return match.replace(/(<ul[^>]*?)(\s*>)/i, '$1 role="menubar"$2');
706
734
  }
707
735
  );
708
736
 
709
737
  // Fix list items in navigation menus
710
738
  fixed = fixed.replace(
711
- /<li([^>]*class="[^"]*(?:nav|menu)[^"]*"[^>]*)(?!.*role\s*=)([^>]*>)/gi,
712
- (match, attrs, end) => {
739
+ /<li([^>]*class="[^"]*(?:nav|menu)[^"]*"[^>]*>)/gi,
740
+ (match) => {
741
+ // Check if role attribute already exists
742
+ if (/role\s*=/i.test(match)) {
743
+ return match; // Return unchanged if role already exists
744
+ }
713
745
  console.log(chalk.yellow(` 📋 Added role="menuitem" to navigation list item`));
714
- return `<li${attrs} role="menuitem"${end}`;
746
+ return match.replace(/(<li[^>]*?)(\s*>)/i, '$1 role="menuitem"$2');
715
747
  }
716
748
  );
717
749
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gbu-accessibility-package",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Automated accessibility fixes for HTML files - Alt attributes, Lang attributes, Role attributes. Smart context-aware alt text generation and comprehensive role attribute management.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -11,9 +11,9 @@
11
11
  "start": "node cli.js",
12
12
  "fix": "node cli.js",
13
13
  "preview": "node cli.js --dry-run",
14
- "test": "node example.js",
14
+ "test": "node test-package.js",
15
15
  "demo": "node cli.js --dry-run demo",
16
- "prepublishOnly": "npm run demo"
16
+ "prepublishOnly": "npm run test"
17
17
  },
18
18
  "keywords": [
19
19
  "accessibility",