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 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
- if (metaAnalysis.issues.length > 0 || metaAnalysis.warnings.length > 0) {
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 ${results.length} file`));
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
- console.log(chalk.red(` ❌ File có lỗi: ${filesWithIssues} (${totalIssues} vấn đề)`));
7322
- console.log(chalk.yellow(` ⚠️ File có cảnh báo: ${filesWithWarnings} (${totalWarnings} cảnh báo)`));
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.warnings.push({
7716
- type: 'Thiếu kích thước og:image',
7717
- description: 'Chưa khai báo kích thước hình ảnh og:image',
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.warnings.push({
7724
- type: 'Thiếu og:image:alt',
7725
- description: 'Chưa tả alt text cho og:image',
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.warnings.push({
7768
- type: 'Thiếu Canonical URL',
7769
- description: 'Không tìm thấy thẻ link rel="canonical"',
7770
- suggestion: 'Thêm <link rel="canonical" href="https://example.com/your-page"> để tránh duplicate content'
7829
+ result.recommendations.push({
7830
+ type: 'Canonical URL',
7831
+ description: 'Chưa 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.0",
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": {