gbu-accessibility-package 3.10.0 → 3.10.2
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/CHANGELOG.md +23 -0
- package/lib/fixer.js +90 -17
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [3.10.2] - 2025-12-09
|
|
9
|
+
|
|
10
|
+
### Improved
|
|
11
|
+
- **Smarter Partial File Detection**: Enhanced detection of HTML partial/include files using 3 methods:
|
|
12
|
+
1. Files containing `<!--#include virtual="...">` or `<!--#include file="...">`
|
|
13
|
+
2. Files in `/inc/` directory (common pattern for partials)
|
|
14
|
+
3. Files without `<!DOCTYPE html>` or `<html>` tag (HTML fragments)
|
|
15
|
+
- Partial files are automatically skipped during meta tag analysis
|
|
16
|
+
- Each detection method provides a specific skip reason in the summary
|
|
17
|
+
|
|
18
|
+
## [3.10.1] - 2025-12-09
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- **SSI Include Files Ignored**: Files containing `<!--#include virtual="...">` are now skipped during meta tag analysis
|
|
22
|
+
- **Recommendations vs Warnings**: Separated optional improvements from actual warnings:
|
|
23
|
+
- `og:image:width`, `og:image:height`, `og:image:alt` → Now shown as 💎 recommendations
|
|
24
|
+
- `Canonical URL` → Now shown as 💎 recommendation
|
|
25
|
+
- These are optional best practices, not errors or warnings
|
|
26
|
+
|
|
27
|
+
### Improved
|
|
28
|
+
- **Summary Statistics**: Now shows count of skipped files and recommendations separately
|
|
29
|
+
- **Output Clarity**: Clear distinction between ❌ issues, ⚠️ warnings, and 💎 recommendations
|
|
30
|
+
|
|
8
31
|
## [3.10.0] - 2025-12-09
|
|
9
32
|
|
|
10
33
|
### Added
|
package/lib/fixer.js
CHANGED
|
@@ -7258,7 +7258,18 @@ class AccessibilityFixer {
|
|
|
7258
7258
|
const content = await fs.readFile(file, 'utf8');
|
|
7259
7259
|
const metaAnalysis = this.analyzeMetaTags(content, file);
|
|
7260
7260
|
|
|
7261
|
-
|
|
7261
|
+
// Skip SSI include files
|
|
7262
|
+
if (metaAnalysis.isIncludeFile) {
|
|
7263
|
+
results.push({
|
|
7264
|
+
file,
|
|
7265
|
+
status: 'skipped',
|
|
7266
|
+
reason: 'SSI include file',
|
|
7267
|
+
metaAnalysis
|
|
7268
|
+
});
|
|
7269
|
+
continue;
|
|
7270
|
+
}
|
|
7271
|
+
|
|
7272
|
+
if (metaAnalysis.issues.length > 0 || metaAnalysis.warnings.length > 0 || metaAnalysis.recommendations.length > 0) {
|
|
7262
7273
|
console.log(chalk.cyan(`\n📁 ${path.relative(directory, file)}:`));
|
|
7263
7274
|
|
|
7264
7275
|
// Show status for required OG tags
|
|
@@ -7282,7 +7293,7 @@ class AccessibilityFixer {
|
|
|
7282
7293
|
console.log(chalk.green(` ✅ Twitter Card: Đã cài đặt`));
|
|
7283
7294
|
}
|
|
7284
7295
|
|
|
7285
|
-
// Show issues
|
|
7296
|
+
// Show issues (errors)
|
|
7286
7297
|
metaAnalysis.issues.forEach(issue => {
|
|
7287
7298
|
console.log(chalk.red(` ❌ ${issue.type}: ${issue.description}`));
|
|
7288
7299
|
if (issue.suggestion) {
|
|
@@ -7297,6 +7308,16 @@ class AccessibilityFixer {
|
|
|
7297
7308
|
console.log(chalk.gray(` 💡 ${warning.suggestion}`));
|
|
7298
7309
|
}
|
|
7299
7310
|
});
|
|
7311
|
+
|
|
7312
|
+
// Show recommendations (optional improvements)
|
|
7313
|
+
if (metaAnalysis.recommendations.length > 0) {
|
|
7314
|
+
metaAnalysis.recommendations.forEach(rec => {
|
|
7315
|
+
console.log(chalk.blue(` 💎 ${rec.type}: ${rec.description}`));
|
|
7316
|
+
if (rec.suggestion) {
|
|
7317
|
+
console.log(chalk.gray(` ℹ️ ${rec.suggestion}`));
|
|
7318
|
+
}
|
|
7319
|
+
});
|
|
7320
|
+
}
|
|
7300
7321
|
}
|
|
7301
7322
|
|
|
7302
7323
|
results.push({
|
|
@@ -7310,16 +7331,30 @@ class AccessibilityFixer {
|
|
|
7310
7331
|
}
|
|
7311
7332
|
}
|
|
7312
7333
|
|
|
7334
|
+
const filesAnalyzed = results.filter(r => r.status === 'analyzed').length;
|
|
7335
|
+
const filesSkipped = results.filter(r => r.status === 'skipped').length;
|
|
7313
7336
|
const filesWithOG = results.filter(r => r.metaAnalysis?.hasOpenGraph).length;
|
|
7314
7337
|
const filesWithIssues = results.filter(r => r.metaAnalysis?.issues?.length > 0).length;
|
|
7315
7338
|
const filesWithWarnings = results.filter(r => r.metaAnalysis?.warnings?.length > 0).length;
|
|
7339
|
+
const filesWithRecs = results.filter(r => r.metaAnalysis?.recommendations?.length > 0).length;
|
|
7316
7340
|
const totalIssues = results.reduce((sum, r) => sum + (r.metaAnalysis?.issues?.length || 0), 0);
|
|
7317
7341
|
const totalWarnings = results.reduce((sum, r) => sum + (r.metaAnalysis?.warnings?.length || 0), 0);
|
|
7342
|
+
const totalRecs = results.reduce((sum, r) => sum + (r.metaAnalysis?.recommendations?.length || 0), 0);
|
|
7318
7343
|
|
|
7319
|
-
console.log(chalk.blue(`\n📊 Tóm tắt: Đã phân tích ${
|
|
7344
|
+
console.log(chalk.blue(`\n📊 Tóm tắt: Đã phân tích ${filesAnalyzed} file`));
|
|
7345
|
+
if (filesSkipped > 0) {
|
|
7346
|
+
console.log(chalk.gray(` ⏭️ Bỏ qua: ${filesSkipped} file (SSI include)`));
|
|
7347
|
+
}
|
|
7320
7348
|
console.log(chalk.green(` ✅ File có Open Graph: ${filesWithOG}`));
|
|
7321
|
-
|
|
7322
|
-
|
|
7349
|
+
if (totalIssues > 0) {
|
|
7350
|
+
console.log(chalk.red(` ❌ File có lỗi: ${filesWithIssues} (${totalIssues} vấn đề)`));
|
|
7351
|
+
}
|
|
7352
|
+
if (totalWarnings > 0) {
|
|
7353
|
+
console.log(chalk.yellow(` ⚠️ File có cảnh báo: ${filesWithWarnings} (${totalWarnings} cảnh báo)`));
|
|
7354
|
+
}
|
|
7355
|
+
if (totalRecs > 0) {
|
|
7356
|
+
console.log(chalk.blue(` 💎 File có khuyến nghị: ${filesWithRecs} (${totalRecs} khuyến nghị)`));
|
|
7357
|
+
}
|
|
7323
7358
|
console.log(chalk.gray('💡 Open Graph Protocol cần có 4 thẻ bắt buộc: og:title, og:type, og:image, og:url'));
|
|
7324
7359
|
|
|
7325
7360
|
return results;
|
|
@@ -7330,16 +7365,43 @@ class AccessibilityFixer {
|
|
|
7330
7365
|
hasOpenGraph: false,
|
|
7331
7366
|
hasTwitterCard: false,
|
|
7332
7367
|
hasBasicMeta: false,
|
|
7368
|
+
isIncludeFile: false, // New: track if this is an SSI include file
|
|
7333
7369
|
requiredTags: [],
|
|
7334
7370
|
optionalTags: [],
|
|
7335
7371
|
twitterTags: [],
|
|
7336
7372
|
basicTags: [],
|
|
7337
7373
|
issues: [],
|
|
7338
7374
|
warnings: [],
|
|
7375
|
+
recommendations: [], // New: optional improvements, not errors
|
|
7339
7376
|
syntaxErrors: [],
|
|
7340
7377
|
typos: [] // New: track typos for auto-fix
|
|
7341
7378
|
};
|
|
7342
7379
|
|
|
7380
|
+
// Check if this is an SSI include file or partial file (should be skipped)
|
|
7381
|
+
// Method 1: File contains SSI include directive
|
|
7382
|
+
const ssiIncludePattern = /<!--#include\s+(virtual|file)\s*=\s*["'][^"']+["']\s*-->/i;
|
|
7383
|
+
if (ssiIncludePattern.test(content)) {
|
|
7384
|
+
result.isIncludeFile = true;
|
|
7385
|
+
result.skipReason = 'Chứa SSI include directive';
|
|
7386
|
+
return result; // Skip analysis for include files
|
|
7387
|
+
}
|
|
7388
|
+
|
|
7389
|
+
// Method 2: File path contains /inc/ directory (common pattern for partials)
|
|
7390
|
+
if (filePath && /[\/\\]inc[\/\\]/i.test(filePath)) {
|
|
7391
|
+
result.isIncludeFile = true;
|
|
7392
|
+
result.skipReason = 'File partial trong thư mục /inc/';
|
|
7393
|
+
return result;
|
|
7394
|
+
}
|
|
7395
|
+
|
|
7396
|
+
// Method 3: File doesn't have DOCTYPE or <html> tag (likely a partial)
|
|
7397
|
+
const hasDoctype = /<!DOCTYPE\s+html/i.test(content);
|
|
7398
|
+
const hasHtmlTag = /<html[\s>]/i.test(content);
|
|
7399
|
+
if (!hasDoctype && !hasHtmlTag) {
|
|
7400
|
+
result.isIncludeFile = true;
|
|
7401
|
+
result.skipReason = 'File partial (không có DOCTYPE/html)';
|
|
7402
|
+
return result;
|
|
7403
|
+
}
|
|
7404
|
+
|
|
7343
7405
|
// Required OG Tags according to Open Graph Protocol
|
|
7344
7406
|
const requiredOGTags = ['og:title', 'og:type', 'og:image', 'og:url'];
|
|
7345
7407
|
const optionalOGTags = ['og:description', 'og:site_name', 'og:locale', 'og:image:width', 'og:image:height', 'og:image:alt', 'og:image:secure_url', 'og:audio', 'og:video', 'og:determiner'];
|
|
@@ -7704,7 +7766,7 @@ class AccessibilityFixer {
|
|
|
7704
7766
|
});
|
|
7705
7767
|
});
|
|
7706
7768
|
|
|
7707
|
-
// Check og:image dimensions
|
|
7769
|
+
// Check og:image dimensions - these are recommendations, not required
|
|
7708
7770
|
const ogImage = allMetaTags.find(t => t.property === 'og:image');
|
|
7709
7771
|
if (ogImage) {
|
|
7710
7772
|
const ogImageWidth = allMetaTags.find(t => t.property === 'og:image:width');
|
|
@@ -7712,17 +7774,17 @@ class AccessibilityFixer {
|
|
|
7712
7774
|
const ogImageAlt = allMetaTags.find(t => t.property === 'og:image:alt');
|
|
7713
7775
|
|
|
7714
7776
|
if (!ogImageWidth || !ogImageHeight) {
|
|
7715
|
-
result.
|
|
7716
|
-
type: '
|
|
7717
|
-
description: '
|
|
7777
|
+
result.recommendations.push({
|
|
7778
|
+
type: 'Kích thước og:image',
|
|
7779
|
+
description: 'Cân nhắc thêm kích thước hình ảnh og:image',
|
|
7718
7780
|
suggestion: 'Thêm og:image:width và og:image:height để tối ưu hiển thị. Khuyến nghị: 1200x630 pixels'
|
|
7719
7781
|
});
|
|
7720
7782
|
}
|
|
7721
7783
|
|
|
7722
7784
|
if (!ogImageAlt) {
|
|
7723
|
-
result.
|
|
7724
|
-
type: '
|
|
7725
|
-
description: '
|
|
7785
|
+
result.recommendations.push({
|
|
7786
|
+
type: 'og:image:alt',
|
|
7787
|
+
description: 'Cân nhắc thêm alt text cho og:image',
|
|
7726
7788
|
suggestion: 'Thêm <meta property="og:image:alt" content="Mô tả hình ảnh"> để cải thiện accessibility'
|
|
7727
7789
|
});
|
|
7728
7790
|
}
|
|
@@ -7760,14 +7822,14 @@ class AccessibilityFixer {
|
|
|
7760
7822
|
});
|
|
7761
7823
|
}
|
|
7762
7824
|
|
|
7763
|
-
// Check for canonical URL
|
|
7825
|
+
// Check for canonical URL - this is a recommendation, not required
|
|
7764
7826
|
const canonicalPattern = /<link\s+[^>]*rel\s*=\s*["']canonical["'][^>]*>/i;
|
|
7765
7827
|
const canonicalMatch = content.match(canonicalPattern);
|
|
7766
7828
|
if (!canonicalMatch) {
|
|
7767
|
-
result.
|
|
7768
|
-
type: '
|
|
7769
|
-
description: '
|
|
7770
|
-
suggestion: '
|
|
7829
|
+
result.recommendations.push({
|
|
7830
|
+
type: 'Canonical URL',
|
|
7831
|
+
description: 'Chưa có thẻ link rel="canonical"',
|
|
7832
|
+
suggestion: 'Cân nhắc thêm <link rel="canonical" href="..."> để tránh duplicate content'
|
|
7771
7833
|
});
|
|
7772
7834
|
}
|
|
7773
7835
|
|
|
@@ -7855,6 +7917,17 @@ class AccessibilityFixer {
|
|
|
7855
7917
|
const originalContent = content;
|
|
7856
7918
|
const metaAnalysis = this.analyzeMetaTags(content, file);
|
|
7857
7919
|
|
|
7920
|
+
// Skip SSI include files
|
|
7921
|
+
if (metaAnalysis.isIncludeFile) {
|
|
7922
|
+
results.push({
|
|
7923
|
+
file,
|
|
7924
|
+
status: 'skipped',
|
|
7925
|
+
reason: 'SSI include file',
|
|
7926
|
+
fixes: 0
|
|
7927
|
+
});
|
|
7928
|
+
continue;
|
|
7929
|
+
}
|
|
7930
|
+
|
|
7858
7931
|
let fixCount = 0;
|
|
7859
7932
|
const fixes = [];
|
|
7860
7933
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gbu-accessibility-package",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.2",
|
|
4
4
|
"description": "Comprehensive accessibility fixes and project optimization for HTML files. Smart context-aware alt text generation, form labels, button names, link names, landmarks, heading analysis, WCAG-compliant role attributes, unused files detection, dead code analysis, broken external links detection, missing local resources detection, and Meta Tags & Open Graph Protocol validation. Covers major axe DevTools issues with individual fix modes.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|