@elementor/editor-audits 4.4.0-1108 → 4.4.0-1109

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/dist/index.js CHANGED
@@ -141,8 +141,8 @@ async function requestPageContext(documentId, imageSizeRequests, allowNonceRetry
141
141
 
142
142
  // src/registry.ts
143
143
  var registry = /* @__PURE__ */ new Map();
144
- function registerAudit(audit25) {
145
- registry.set(audit25.id, audit25);
144
+ function registerAudit(audit26) {
145
+ registry.set(audit26.id, audit26);
146
146
  }
147
147
  function getRegisteredAudits() {
148
148
  return Array.from(registry.values());
@@ -179,8 +179,8 @@ var CATEGORY_LABELS = {
179
179
  var import_i18n2 = require("@wordpress/i18n");
180
180
 
181
181
  // src/utils/is-scored-audit.ts
182
- function isScoredAudit(audit25) {
183
- return audit25.weight > 0;
182
+ function isScoredAudit(audit26) {
183
+ return audit26.weight > 0;
184
184
  }
185
185
 
186
186
  // src/utils/sort-failed-audits.ts
@@ -236,8 +236,8 @@ function auditStatusDisplayCounts(report) {
236
236
  let pass = 0;
237
237
  let skipped = 0;
238
238
  let totalViolations = 0;
239
- for (const { audit: audit25, result } of report.auditResults) {
240
- if (!isScoredAudit(audit25)) {
239
+ for (const { audit: audit26, result } of report.auditResults) {
240
+ if (!isScoredAudit(audit26)) {
241
241
  continue;
242
242
  }
243
243
  switch (result.status) {
@@ -287,16 +287,16 @@ function computeReport(documentId, results) {
287
287
  const accumulators = Object.fromEntries(
288
288
  ALL_CATEGORIES.map((c) => [c, { totalWeight: 0, passedWeight: 0, total: 0, failed: 0 }])
289
289
  );
290
- for (const { audit: audit25, result } of results) {
290
+ for (const { audit: audit26, result } of results) {
291
291
  if (result.status === "skipped") {
292
292
  continue;
293
293
  }
294
- for (const category of audit25.categories) {
294
+ for (const category of audit26.categories) {
295
295
  const acc = accumulators[category];
296
296
  acc.total++;
297
- acc.totalWeight += audit25.weight;
297
+ acc.totalWeight += audit26.weight;
298
298
  if (result.status === "pass") {
299
- acc.passedWeight += audit25.weight;
299
+ acc.passedWeight += audit26.weight;
300
300
  } else {
301
301
  acc.failed++;
302
302
  }
@@ -609,10 +609,10 @@ async function runPageAudit(documentId) {
609
609
  const ctx = { documentId, elements, pageContext, kit, renderedHtml };
610
610
  const registered = getRegisteredAudits();
611
611
  const auditResults = await Promise.all(
612
- registered.map(async (audit25) => {
613
- const { evaluate: _evaluate, ...meta } = audit25;
612
+ registered.map(async (audit26) => {
613
+ const { evaluate: _evaluate, ...meta } = audit26;
614
614
  try {
615
- const result = await audit25.evaluate(ctx);
615
+ const result = await audit26.evaluate(ctx);
616
616
  return { audit: meta, result };
617
617
  } catch (error) {
618
618
  const reason = error instanceof Error ? error.message : "unknown-error";
@@ -1100,13 +1100,13 @@ function ViolationIcon({ violation, widgetIcon }) {
1100
1100
  function SkipReasonTooltip({ reason }) {
1101
1101
  return /* @__PURE__ */ React11.createElement(import_ui10.Tooltip, { title: reason, placement: "top" }, /* @__PURE__ */ React11.createElement(import_ui10.Box, { "aria-label": reason, component: "span", sx: { display: "inline-flex", alignItems: "center" } }, /* @__PURE__ */ React11.createElement(import_icons7.HelpIcon, { fontSize: "small", color: "action" })));
1102
1102
  }
1103
- function StatusIndicator({ audit: audit25, violations }) {
1103
+ function StatusIndicator({ audit: audit26, violations }) {
1104
1104
  if (violations) {
1105
- return /* @__PURE__ */ React11.createElement(React11.Fragment, null, isScoredAudit(audit25) && /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length), /* @__PURE__ */ React11.createElement(SeverityIcon, { severity: audit25.severity }));
1105
+ return /* @__PURE__ */ React11.createElement(React11.Fragment, null, isScoredAudit(audit26) && /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length), /* @__PURE__ */ React11.createElement(SeverityIcon, { severity: audit26.severity }));
1106
1106
  }
1107
1107
  return /* @__PURE__ */ React11.createElement(import_icons7.CheckIcon, { fontSize: "small", color: "success" });
1108
1108
  }
1109
- function ViolationRow({ audit: audit25, skipReason, violations }) {
1109
+ function ViolationRow({ audit: audit26, skipReason, violations }) {
1110
1110
  const [expanded, setExpanded] = (0, import_react4.useState)(false);
1111
1111
  const toggleExpanded = () => setExpanded((value) => !value);
1112
1112
  return /* @__PURE__ */ React11.createElement(import_ui10.Box, { sx: { borderBottom: 1, borderColor: "divider", paddingBlock: 0.5 } }, /* @__PURE__ */ React11.createElement(import_ui10.Box, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React11.createElement(
@@ -1122,8 +1122,8 @@ function ViolationRow({ audit: audit25, skipReason, violations }) {
1122
1122
  },
1123
1123
  onClick: toggleExpanded
1124
1124
  },
1125
- /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "body2", sx: { flex: 1 } }, audit25.title),
1126
- !skipReason && /* @__PURE__ */ React11.createElement(StatusIndicator, { audit: audit25, violations })
1125
+ /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "body2", sx: { flex: 1 } }, audit26.title),
1126
+ !skipReason && /* @__PURE__ */ React11.createElement(StatusIndicator, { audit: audit26, violations })
1127
1127
  ), skipReason && /* @__PURE__ */ React11.createElement(SkipReasonTooltip, { reason: skipReason }), /* @__PURE__ */ React11.createElement(
1128
1128
  import_ui10.IconButton,
1129
1129
  {
@@ -1149,7 +1149,7 @@ function ViolationRow({ audit: audit25, skipReason, violations }) {
1149
1149
  icon: /* @__PURE__ */ React11.createElement(import_icons7.AlertCircleIcon, { fontSize: "small", color: "secondary", "aria-hidden": true })
1150
1150
  },
1151
1151
  /* @__PURE__ */ React11.createElement(import_ui10.AlertTitle, null, /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", component: "p", color: "text.primary", fontWeight: "bold" }, (0, import_i18n11.__)("What's the issue", "elementor"))),
1152
- /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", component: "p", color: "text.secondary" }, audit25.description)
1152
+ /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", component: "p", color: "text.secondary" }, audit26.description)
1153
1153
  ), /* @__PURE__ */ React11.createElement(
1154
1154
  import_ui10.Alert,
1155
1155
  {
@@ -1158,7 +1158,7 @@ function ViolationRow({ audit: audit25, skipReason, violations }) {
1158
1158
  icon: /* @__PURE__ */ React11.createElement(import_icons7.BulbIcon, { fontSize: "small", color: "info", "aria-hidden": true })
1159
1159
  },
1160
1160
  /* @__PURE__ */ React11.createElement(import_ui10.AlertTitle, null, /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", component: "p", color: "text.primary", fontWeight: "bold" }, (0, import_i18n11.__)("How to resolve", "elementor"))),
1161
- /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", component: "p", color: "text.secondary" }, audit25.fixHint)
1161
+ /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", component: "p", color: "text.secondary" }, audit26.fixHint)
1162
1162
  )), violations && violations.length > 0 && /* @__PURE__ */ React11.createElement(import_ui10.Box, { role: "list", sx: { paddingBlockEnd: 1, paddingInlineStart: 2 } }, violations.map((violation, idx) => {
1163
1163
  const widgetIcon = violation.elementId ? (0, import_editor_elements5.getElementIcon)(violation.elementId) : null;
1164
1164
  const elementTitle = violation.elementId ? (0, import_editor_elements5.getElementTitle)(violation.elementId) : null;
@@ -1305,17 +1305,17 @@ var import_i18n14 = require("@wordpress/i18n");
1305
1305
  var ALL_SEVERITIES = ["error", "warning", "info"];
1306
1306
  function countSeverities(report, category) {
1307
1307
  const counts = { error: 0, warning: 0, info: 0 };
1308
- for (const { audit: audit25, result } of report.auditResults) {
1308
+ for (const { audit: audit26, result } of report.auditResults) {
1309
1309
  if (result.status !== "fail") {
1310
1310
  continue;
1311
1311
  }
1312
- if (category && !audit25.categories.includes(category)) {
1312
+ if (category && !audit26.categories.includes(category)) {
1313
1313
  continue;
1314
1314
  }
1315
- if (!isScoredAudit(audit25)) {
1315
+ if (!isScoredAudit(audit26)) {
1316
1316
  continue;
1317
1317
  }
1318
- counts[audit25.severity] += result.violations.length;
1318
+ counts[audit26.severity] += result.violations.length;
1319
1319
  }
1320
1320
  return counts;
1321
1321
  }
@@ -1618,6 +1618,26 @@ var PROMOTIONS = [
1618
1618
  );
1619
1619
  },
1620
1620
  getCtaUrl: firstFailExternalUrl
1621
+ },
1622
+ {
1623
+ auditId: "audits/images-inefficient-format",
1624
+ icon: import_icons10.ShieldHalfFilledIcon,
1625
+ ctaLabel: (0, import_i18n19.__)("Optimize all", "elementor"),
1626
+ formatSubtitle: (run) => {
1627
+ if (run.result.status !== "fail") {
1628
+ return null;
1629
+ }
1630
+ const count = run.result.metadata?.inefficientImageFormatCount ?? 0;
1631
+ if (count === 0) {
1632
+ return null;
1633
+ }
1634
+ return (0, import_i18n19.sprintf)(
1635
+ /* translators: %d: number of images served in an inefficient format. */
1636
+ (0, import_i18n19._n)("%d image", "%d images", count, "elementor"),
1637
+ count
1638
+ );
1639
+ },
1640
+ getCtaUrl: firstFailExternalUrl
1621
1641
  }
1622
1642
  ];
1623
1643
 
@@ -2619,15 +2639,63 @@ var audit11 = {
2619
2639
  }
2620
2640
  };
2621
2641
 
2622
- // src/audits/images-too-large.ts
2642
+ // src/audits/images-inefficient-format.ts
2623
2643
  var import_i18n36 = require("@wordpress/i18n");
2644
+ var LEGACY_RASTER_MIME_TYPES = /* @__PURE__ */ new Set(["image/jpeg", "image/png", "image/gif", "image/bmp", "image/tiff"]);
2645
+ var audit12 = {
2646
+ id: "audits/images-inefficient-format",
2647
+ title: (0, import_i18n36.__)("Inefficient image format", "elementor"),
2648
+ description: (0, import_i18n36.__)("Image isn't served in a modern, efficient format like WebP or AVIF.", "elementor"),
2649
+ fixHint: (0, import_i18n36.__)("Convert the image to a modern format like WebP or AVIF, or enable image optimization.", "elementor"),
2650
+ categories: ["performance"],
2651
+ severity: "info",
2652
+ weight: 1,
2653
+ evaluate: (ctx) => {
2654
+ const offendingElementIds = /* @__PURE__ */ new Set();
2655
+ let hasAnyImage = false;
2656
+ let inefficientImageFormatCount = 0;
2657
+ const evaluateSource = (node, media) => {
2658
+ if (media.id || media.url) {
2659
+ hasAnyImage = true;
2660
+ }
2661
+ const id = media.id;
2662
+ if (!id) {
2663
+ return;
2664
+ }
2665
+ const mime = ctx.pageContext.image_sizes[buildImageSizeKey({ id, size: media.size })]?.mime;
2666
+ if (!mime || !LEGACY_RASTER_MIME_TYPES.has(mime)) {
2667
+ return;
2668
+ }
2669
+ inefficientImageFormatCount++;
2670
+ offendingElementIds.add(node.id);
2671
+ };
2672
+ walkImageLikeSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2673
+ walkBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2674
+ walkAtomicImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2675
+ walkAtomicBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2676
+ if (!hasAnyImage) {
2677
+ return { status: "skipped", reason: (0, import_i18n36.__)("No images", "elementor") };
2678
+ }
2679
+ const violations = Array.from(offendingElementIds).map((elementId) => ({
2680
+ auditId: audit12.id,
2681
+ elementId,
2682
+ targetHint: "element-settings",
2683
+ label: (0, import_i18n36.__)("Image isn't served in a modern format like WebP or AVIF.", "elementor"),
2684
+ externalUrl: ctx.pageContext.image_optimization_plugin_url
2685
+ }));
2686
+ return violations.length === 0 ? { status: "pass" } : { status: "fail", violations, metadata: { inefficientImageFormatCount } };
2687
+ }
2688
+ };
2689
+
2690
+ // src/audits/images-too-large.ts
2691
+ var import_i18n37 = require("@wordpress/i18n");
2624
2692
  var SIZE_THRESHOLD_BYTES = 500 * 1024;
2625
2693
  var BYTES_PER_KB = 1024;
2626
- var audit12 = {
2694
+ var audit13 = {
2627
2695
  id: "audits/images-too-large",
2628
- title: (0, import_i18n36.__)("Oversized images", "elementor"),
2629
- description: (0, import_i18n36.__)("Large image files slow down the page.", "elementor"),
2630
- fixHint: (0, import_i18n36.__)("Replace the image with a smaller version or enable image optimization.", "elementor"),
2696
+ title: (0, import_i18n37.__)("Oversized images", "elementor"),
2697
+ description: (0, import_i18n37.__)("Large image files slow down the page.", "elementor"),
2698
+ fixHint: (0, import_i18n37.__)("Replace the image with a smaller version or enable image optimization.", "elementor"),
2631
2699
  categories: ["performance"],
2632
2700
  severity: "warning",
2633
2701
  weight: 7,
@@ -2657,15 +2725,15 @@ var audit12 = {
2657
2725
  walkAtomicImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2658
2726
  walkAtomicBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2659
2727
  if (!hasAnyImage) {
2660
- return { status: "skipped", reason: (0, import_i18n36.__)("No images", "elementor") };
2728
+ return { status: "skipped", reason: (0, import_i18n37.__)("No images", "elementor") };
2661
2729
  }
2662
2730
  const violations = Array.from(widgetMaxKb.entries()).map(([elementId, kb]) => ({
2663
- auditId: audit12.id,
2731
+ auditId: audit13.id,
2664
2732
  elementId,
2665
2733
  targetHint: "element-settings",
2666
- label: (0, import_i18n36.sprintf)(
2734
+ label: (0, import_i18n37.sprintf)(
2667
2735
  /* translators: %d is the image file size in kilobytes. */
2668
- (0, import_i18n36.__)("Image is %d KB (over 500 KB).", "elementor"),
2736
+ (0, import_i18n37.__)("Image is %d KB (over 500 KB).", "elementor"),
2669
2737
  kb
2670
2738
  ),
2671
2739
  externalUrl: ctx.pageContext.image_optimization_plugin_url
@@ -2675,21 +2743,21 @@ var audit12 = {
2675
2743
  };
2676
2744
 
2677
2745
  // src/audits/nested-boxed-containers.ts
2678
- var import_i18n37 = require("@wordpress/i18n");
2746
+ var import_i18n38 = require("@wordpress/i18n");
2679
2747
  function isBoxed(settings) {
2680
2748
  return settings.content_width === "boxed";
2681
2749
  }
2682
- var audit13 = {
2750
+ var audit14 = {
2683
2751
  id: "audits/nested-boxed-containers",
2684
- title: (0, import_i18n37.__)("Boxed container nested inside a boxed parent", "elementor"),
2685
- description: (0, import_i18n37.__)("An inner container does not need to be boxed when its parent already is.", "elementor"),
2686
- fixHint: (0, import_i18n37.__)("Change the inner container's content width to Full Width.", "elementor"),
2752
+ title: (0, import_i18n38.__)("Boxed container nested inside a boxed parent", "elementor"),
2753
+ description: (0, import_i18n38.__)("An inner container does not need to be boxed when its parent already is.", "elementor"),
2754
+ fixHint: (0, import_i18n38.__)("Change the inner container's content width to Full Width.", "elementor"),
2687
2755
  categories: ["best-practices", "performance"],
2688
2756
  severity: "info",
2689
2757
  weight: 5,
2690
2758
  evaluate: (ctx) => {
2691
2759
  if (ctx.elements.tree.length === 0) {
2692
- return { status: "skipped", reason: (0, import_i18n37.__)("No elements", "elementor") };
2760
+ return { status: "skipped", reason: (0, import_i18n38.__)("No elements", "elementor") };
2693
2761
  }
2694
2762
  const violations = [];
2695
2763
  walkElements(ctx.elements.tree, (node, parents) => {
@@ -2699,10 +2767,10 @@ var audit13 = {
2699
2767
  const nearestContainerAncestor = [...parents].reverse().find((p) => p.elType === "container");
2700
2768
  if (nearestContainerAncestor && isBoxed(nearestContainerAncestor.settings)) {
2701
2769
  violations.push({
2702
- auditId: audit13.id,
2770
+ auditId: audit14.id,
2703
2771
  elementId: node.id,
2704
2772
  targetHint: "element-settings",
2705
- label: (0, import_i18n37.__)("Nested boxed container.", "elementor")
2773
+ label: (0, import_i18n38.__)("Nested boxed container.", "elementor")
2706
2774
  });
2707
2775
  }
2708
2776
  });
@@ -2711,12 +2779,12 @@ var audit13 = {
2711
2779
  };
2712
2780
 
2713
2781
  // src/audits/page-excerpt.ts
2714
- var import_i18n38 = require("@wordpress/i18n");
2715
- var audit14 = {
2782
+ var import_i18n39 = require("@wordpress/i18n");
2783
+ var audit15 = {
2716
2784
  id: "audits/page-excerpt",
2717
- title: (0, import_i18n38.__)("Page excerpt", "elementor"),
2718
- description: (0, import_i18n38.__)("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
2719
- fixHint: (0, import_i18n38.__)("Open Page Settings and write a short excerpt.", "elementor"),
2785
+ title: (0, import_i18n39.__)("Page excerpt", "elementor"),
2786
+ description: (0, import_i18n39.__)("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
2787
+ fixHint: (0, import_i18n39.__)("Open Page Settings and write a short excerpt.", "elementor"),
2720
2788
  categories: ["seo"],
2721
2789
  severity: "warning",
2722
2790
  weight: 5,
@@ -2728,8 +2796,8 @@ var audit14 = {
2728
2796
  status: "fail",
2729
2797
  violations: [
2730
2798
  {
2731
- auditId: audit14.id,
2732
- label: (0, import_i18n38.__)("Page has no excerpt.", "elementor"),
2799
+ auditId: audit15.id,
2800
+ label: (0, import_i18n39.__)("Page has no excerpt.", "elementor"),
2733
2801
  targetHint: "page-settings",
2734
2802
  angieFix: true
2735
2803
  }
@@ -2739,12 +2807,12 @@ var audit14 = {
2739
2807
  };
2740
2808
 
2741
2809
  // src/audits/page-featured-image.ts
2742
- var import_i18n39 = require("@wordpress/i18n");
2743
- var audit15 = {
2810
+ var import_i18n40 = require("@wordpress/i18n");
2811
+ var audit16 = {
2744
2812
  id: "audits/page-featured-image",
2745
- title: (0, import_i18n39.__)("Page featured image", "elementor"),
2746
- description: (0, import_i18n39.__)("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
2747
- fixHint: (0, import_i18n39.__)("Open Page Settings and set a featured image.", "elementor"),
2813
+ title: (0, import_i18n40.__)("Page featured image", "elementor"),
2814
+ description: (0, import_i18n40.__)("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
2815
+ fixHint: (0, import_i18n40.__)("Open Page Settings and set a featured image.", "elementor"),
2748
2816
  categories: ["seo"],
2749
2817
  severity: "info",
2750
2818
  weight: 5,
@@ -2756,8 +2824,8 @@ var audit15 = {
2756
2824
  status: "fail",
2757
2825
  violations: [
2758
2826
  {
2759
- auditId: audit15.id,
2760
- label: (0, import_i18n39.__)("No featured image set.", "elementor"),
2827
+ auditId: audit16.id,
2828
+ label: (0, import_i18n40.__)("No featured image set.", "elementor"),
2761
2829
  targetHint: "page-settings"
2762
2830
  }
2763
2831
  ]
@@ -2766,13 +2834,13 @@ var audit15 = {
2766
2834
  };
2767
2835
 
2768
2836
  // src/audits/page-title.ts
2769
- var import_i18n40 = require("@wordpress/i18n");
2837
+ var import_i18n41 = require("@wordpress/i18n");
2770
2838
  var MAX_TITLE_LENGTH = 60;
2771
- var audit16 = {
2839
+ var audit17 = {
2772
2840
  id: "audits/page-title",
2773
- title: (0, import_i18n40.__)("Page title", "elementor"),
2774
- description: (0, import_i18n40.__)("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
2775
- fixHint: (0, import_i18n40.__)("Open Page Settings and add a title.", "elementor"),
2841
+ title: (0, import_i18n41.__)("Page title", "elementor"),
2842
+ description: (0, import_i18n41.__)("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
2843
+ fixHint: (0, import_i18n41.__)("Open Page Settings and add a title.", "elementor"),
2776
2844
  categories: ["seo"],
2777
2845
  severity: "error",
2778
2846
  weight: 10,
@@ -2783,11 +2851,11 @@ var audit16 = {
2783
2851
  status: "fail",
2784
2852
  violations: [
2785
2853
  {
2786
- auditId: audit16.id,
2787
- label: (0, import_i18n40.__)("Page has no title.", "elementor"),
2854
+ auditId: audit17.id,
2855
+ label: (0, import_i18n41.__)("Page has no title.", "elementor"),
2788
2856
  targetHint: "page-settings",
2789
2857
  angieFix: true,
2790
- angiePrompt: (0, import_i18n40.__)(
2858
+ angiePrompt: (0, import_i18n41.__)(
2791
2859
  "Based on this page's contents, generate a title for this page.",
2792
2860
  "elementor"
2793
2861
  )
@@ -2800,8 +2868,8 @@ var audit16 = {
2800
2868
  status: "fail",
2801
2869
  violations: [
2802
2870
  {
2803
- auditId: audit16.id,
2804
- label: (0, import_i18n40.__)("Page title is too long.", "elementor"),
2871
+ auditId: audit17.id,
2872
+ label: (0, import_i18n41.__)("Page title is too long.", "elementor"),
2805
2873
  targetHint: "page-settings",
2806
2874
  angieFix: true
2807
2875
  }
@@ -2813,7 +2881,7 @@ var audit16 = {
2813
2881
  };
2814
2882
 
2815
2883
  // src/audits/prefer-global-colors.ts
2816
- var import_i18n41 = require("@wordpress/i18n");
2884
+ var import_i18n42 = require("@wordpress/i18n");
2817
2885
 
2818
2886
  // src/utils/collect-hardcoded-colors.ts
2819
2887
  var RESERVED_SETTING_KEYS = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
@@ -2879,20 +2947,20 @@ function findMatchingGlobalByValue(value, globals) {
2879
2947
  }
2880
2948
 
2881
2949
  // src/audits/prefer-global-colors.ts
2882
- var audit17 = {
2950
+ var audit18 = {
2883
2951
  id: "audits/prefer-global-colors",
2884
- title: (0, import_i18n41.__)("Prefer global colors", "elementor"),
2885
- description: (0, import_i18n41.__)("Global colors make the design consistent and easy to update site-wide.", "elementor"),
2886
- fixHint: (0, import_i18n41.__)("Replace the hard-coded value with the matching global color.", "elementor"),
2952
+ title: (0, import_i18n42.__)("Prefer global colors", "elementor"),
2953
+ description: (0, import_i18n42.__)("Global colors make the design consistent and easy to update site-wide.", "elementor"),
2954
+ fixHint: (0, import_i18n42.__)("Replace the hard-coded value with the matching global color.", "elementor"),
2887
2955
  categories: ["best-practices"],
2888
2956
  severity: "info",
2889
2957
  weight: 3,
2890
2958
  evaluate: (ctx) => {
2891
2959
  if (ctx.elements.tree.length === 0) {
2892
- return { status: "skipped", reason: (0, import_i18n41.__)("No elements", "elementor") };
2960
+ return { status: "skipped", reason: (0, import_i18n42.__)("No elements", "elementor") };
2893
2961
  }
2894
2962
  if (ctx.kit.globals.colors.length === 0) {
2895
- return { status: "skipped", reason: (0, import_i18n41.__)("No global colors", "elementor") };
2963
+ return { status: "skipped", reason: (0, import_i18n42.__)("No global colors", "elementor") };
2896
2964
  }
2897
2965
  const violations = [];
2898
2966
  walkElements(ctx.elements.tree, (node) => {
@@ -2902,13 +2970,13 @@ var audit17 = {
2902
2970
  continue;
2903
2971
  }
2904
2972
  violations.push({
2905
- auditId: audit17.id,
2973
+ auditId: audit18.id,
2906
2974
  elementId: node.id,
2907
2975
  targetHint: "element-settings",
2908
2976
  angieFix: true,
2909
- label: (0, import_i18n41.sprintf)(
2977
+ label: (0, import_i18n42.sprintf)(
2910
2978
  /* translators: 1: hard-coded color value, 2: global color title. */
2911
- (0, import_i18n41.__)('replace "%1$s" with "%2$s" global color', "elementor"),
2979
+ (0, import_i18n42.__)('replace "%1$s" with "%2$s" global color', "elementor"),
2912
2980
  value,
2913
2981
  global.title
2914
2982
  )
@@ -2920,7 +2988,7 @@ var audit17 = {
2920
2988
  };
2921
2989
 
2922
2990
  // src/audits/prefer-global-fonts.ts
2923
- var import_i18n42 = require("@wordpress/i18n");
2991
+ var import_i18n43 = require("@wordpress/i18n");
2924
2992
 
2925
2993
  // src/utils/collect-hardcoded-fonts.ts
2926
2994
  var RESERVED_SETTING_KEYS2 = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
@@ -2978,20 +3046,20 @@ function collectHardcodedFonts(settings, pathPrefix = "") {
2978
3046
  }
2979
3047
 
2980
3048
  // src/audits/prefer-global-fonts.ts
2981
- var audit18 = {
3049
+ var audit19 = {
2982
3050
  id: "audits/prefer-global-fonts",
2983
- title: (0, import_i18n42.__)("Prefer global fonts", "elementor"),
2984
- description: (0, import_i18n42.__)("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
2985
- fixHint: (0, import_i18n42.__)("Replace the hard-coded value with the matching global font.", "elementor"),
3051
+ title: (0, import_i18n43.__)("Prefer global fonts", "elementor"),
3052
+ description: (0, import_i18n43.__)("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
3053
+ fixHint: (0, import_i18n43.__)("Replace the hard-coded value with the matching global font.", "elementor"),
2986
3054
  categories: ["best-practices", "performance"],
2987
3055
  severity: "info",
2988
3056
  weight: 3,
2989
3057
  evaluate: (ctx) => {
2990
3058
  if (ctx.elements.tree.length === 0) {
2991
- return { status: "skipped", reason: (0, import_i18n42.__)("No elements", "elementor") };
3059
+ return { status: "skipped", reason: (0, import_i18n43.__)("No elements", "elementor") };
2992
3060
  }
2993
3061
  if (ctx.kit.globals.fonts.length === 0) {
2994
- return { status: "skipped", reason: (0, import_i18n42.__)("No global fonts", "elementor") };
3062
+ return { status: "skipped", reason: (0, import_i18n43.__)("No global fonts", "elementor") };
2995
3063
  }
2996
3064
  const violations = [];
2997
3065
  walkElements(ctx.elements.tree, (node) => {
@@ -3001,12 +3069,12 @@ var audit18 = {
3001
3069
  continue;
3002
3070
  }
3003
3071
  violations.push({
3004
- auditId: audit18.id,
3072
+ auditId: audit19.id,
3005
3073
  elementId: node.id,
3006
3074
  targetHint: "element-settings",
3007
- label: (0, import_i18n42.sprintf)(
3075
+ label: (0, import_i18n43.sprintf)(
3008
3076
  /* translators: %s: global font title. */
3009
- (0, import_i18n42.__)('replace hardcoded typography with "%s" global font', "elementor"),
3077
+ (0, import_i18n43.__)('replace hardcoded typography with "%s" global font', "elementor"),
3010
3078
  global.title
3011
3079
  )
3012
3080
  });
@@ -3017,15 +3085,15 @@ var audit18 = {
3017
3085
  };
3018
3086
 
3019
3087
  // src/audits/privacy-policy.ts
3020
- var import_i18n43 = require("@wordpress/i18n");
3021
- var audit19 = {
3088
+ var import_i18n44 = require("@wordpress/i18n");
3089
+ var audit20 = {
3022
3090
  id: "audits/privacy-policy",
3023
- title: (0, import_i18n43.__)("Privacy policy", "elementor"),
3024
- description: (0, import_i18n43.__)(
3091
+ title: (0, import_i18n44.__)("Privacy policy", "elementor"),
3092
+ description: (0, import_i18n44.__)(
3025
3093
  "A privacy policy page is required by privacy regulations such as GDPR (EU) and CCPA (US).",
3026
3094
  "elementor"
3027
3095
  ),
3028
- fixHint: (0, import_i18n43.__)(
3096
+ fixHint: (0, import_i18n44.__)(
3029
3097
  "Go to Settings > Privacy in the WordPress admin and assign a published privacy policy page.",
3030
3098
  "elementor"
3031
3099
  ),
@@ -3040,10 +3108,10 @@ var audit19 = {
3040
3108
  status: "fail",
3041
3109
  violations: [
3042
3110
  {
3043
- auditId: audit19.id,
3044
- label: (0, import_i18n43.__)("No privacy policy page is set.", "elementor"),
3111
+ auditId: audit20.id,
3112
+ label: (0, import_i18n44.__)("No privacy policy page is set.", "elementor"),
3045
3113
  externalUrl: ctx.pageContext.privacy_settings_url,
3046
- ctaLabel: (0, import_i18n43.__)("Create", "elementor")
3114
+ ctaLabel: (0, import_i18n44.__)("Create", "elementor")
3047
3115
  }
3048
3116
  ]
3049
3117
  };
@@ -3051,15 +3119,15 @@ var audit19 = {
3051
3119
  };
3052
3120
 
3053
3121
  // src/audits/robots-noindex.ts
3054
- var import_i18n44 = require("@wordpress/i18n");
3055
- var audit20 = {
3122
+ var import_i18n45 = require("@wordpress/i18n");
3123
+ var audit21 = {
3056
3124
  id: "audits/robots-noindex",
3057
- title: (0, import_i18n44.__)("Search engine visibility", "elementor"),
3058
- description: (0, import_i18n44.__)(
3125
+ title: (0, import_i18n45.__)("Search engine visibility", "elementor"),
3126
+ description: (0, import_i18n45.__)(
3059
3127
  "When search engine visibility is checked in WordPress Settings -> Reading -> Search Engine Visibility, search engines are discouraged from indexing the website.",
3060
3128
  "elementor"
3061
3129
  ),
3062
- fixHint: (0, import_i18n44.__)(
3130
+ fixHint: (0, import_i18n45.__)(
3063
3131
  'Go to Settings \u2192 Reading in the WordPress admin and uncheck "Discourage search engines from indexing this site" when the website should be indexed.',
3064
3132
  "elementor"
3065
3133
  ),
@@ -3074,8 +3142,8 @@ var audit20 = {
3074
3142
  status: "fail",
3075
3143
  violations: [
3076
3144
  {
3077
- auditId: audit20.id,
3078
- label: (0, import_i18n44.__)("Search engines are discouraged from indexing this website.", "elementor"),
3145
+ auditId: audit21.id,
3146
+ label: (0, import_i18n45.__)("Search engines are discouraged from indexing this website.", "elementor"),
3079
3147
  externalUrl: ctx.pageContext.reading_settings_url
3080
3148
  }
3081
3149
  ]
@@ -3084,15 +3152,15 @@ var audit20 = {
3084
3152
  };
3085
3153
 
3086
3154
  // src/audits/scan-for-cookies.ts
3087
- var import_i18n45 = require("@wordpress/i18n");
3088
- var audit21 = {
3155
+ var import_i18n46 = require("@wordpress/i18n");
3156
+ var audit22 = {
3089
3157
  id: "audits/scan-for-cookies",
3090
- title: (0, import_i18n45.__)("Scan for cookies", "elementor"),
3091
- description: (0, import_i18n45.__)(
3158
+ title: (0, import_i18n46.__)("Scan for cookies", "elementor"),
3159
+ description: (0, import_i18n46.__)(
3092
3160
  "Your site may be setting cookies you haven't disclosed. Some countries require a banner even without a full consent policy. Scan to see what needs disclosure.",
3093
3161
  "elementor"
3094
3162
  ),
3095
- fixHint: (0, import_i18n45.__)("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
3163
+ fixHint: (0, import_i18n46.__)("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
3096
3164
  categories: ["compliance"],
3097
3165
  severity: "info",
3098
3166
  weight: 0,
@@ -3102,8 +3170,8 @@ var audit21 = {
3102
3170
  status: "fail",
3103
3171
  violations: [
3104
3172
  {
3105
- auditId: audit21.id,
3106
- label: (0, import_i18n45.__)("This page has not been scanned for cookies yet.", "elementor"),
3173
+ auditId: audit22.id,
3174
+ label: (0, import_i18n46.__)("This page has not been scanned for cookies yet.", "elementor"),
3107
3175
  externalUrl: isReady ? ctx.pageContext.cookiez_scan_url : ctx.pageContext.cookiez_plugin_action_url
3108
3176
  }
3109
3177
  ]
@@ -3112,29 +3180,29 @@ var audit21 = {
3112
3180
  };
3113
3181
 
3114
3182
  // src/audits/sections-and-columns.ts
3115
- var import_i18n46 = require("@wordpress/i18n");
3116
- var audit22 = {
3183
+ var import_i18n47 = require("@wordpress/i18n");
3184
+ var audit23 = {
3117
3185
  id: "audits/sections-and-columns",
3118
- title: (0, import_i18n46.__)("Sections and columns", "elementor"),
3119
- description: (0, import_i18n46.__)(
3186
+ title: (0, import_i18n47.__)("Sections and columns", "elementor"),
3187
+ description: (0, import_i18n47.__)(
3120
3188
  "Sections and columns are legacy elements. Containers render fewer DOM nodes and are more flexible.",
3121
3189
  "elementor"
3122
3190
  ),
3123
- fixHint: (0, import_i18n46.__)("Use the Container Converter to replace each section/column with a container.", "elementor"),
3191
+ fixHint: (0, import_i18n47.__)("Use the Container Converter to replace each section/column with a container.", "elementor"),
3124
3192
  categories: ["best-practices", "performance"],
3125
3193
  severity: "warning",
3126
3194
  weight: 7,
3127
3195
  evaluate: (ctx) => {
3128
3196
  if (ctx.elements.tree.length === 0) {
3129
- return { status: "skipped", reason: (0, import_i18n46.__)("No elements", "elementor") };
3197
+ return { status: "skipped", reason: (0, import_i18n47.__)("No elements", "elementor") };
3130
3198
  }
3131
3199
  const violations = [];
3132
3200
  walkElements(ctx.elements.tree, (node) => {
3133
3201
  if (node.elType === "section" || node.elType === "column") {
3134
3202
  violations.push({
3135
- auditId: audit22.id,
3203
+ auditId: audit23.id,
3136
3204
  elementId: node.id,
3137
- label: node.elType === "section" ? (0, import_i18n46.__)("Section element", "elementor") : (0, import_i18n46.__)("Column element", "elementor")
3205
+ label: node.elType === "section" ? (0, import_i18n47.__)("Section element", "elementor") : (0, import_i18n47.__)("Column element", "elementor")
3138
3206
  });
3139
3207
  }
3140
3208
  });
@@ -3143,15 +3211,15 @@ var audit22 = {
3143
3211
  };
3144
3212
 
3145
3213
  // src/audits/site-identity.ts
3146
- var import_i18n47 = require("@wordpress/i18n");
3147
- var audit23 = {
3214
+ var import_i18n48 = require("@wordpress/i18n");
3215
+ var audit24 = {
3148
3216
  id: "audits/site-identity",
3149
- title: (0, import_i18n47.__)("Site identity", "elementor"),
3150
- description: (0, import_i18n47.__)(
3217
+ title: (0, import_i18n48.__)("Site identity", "elementor"),
3218
+ description: (0, import_i18n48.__)(
3151
3219
  "Site name, description, logo, and favicon establish your brand and appear in search results and browser tabs.",
3152
3220
  "elementor"
3153
3221
  ),
3154
- fixHint: (0, import_i18n47.__)("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
3222
+ fixHint: (0, import_i18n48.__)("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
3155
3223
  categories: ["best-practices", "seo"],
3156
3224
  severity: "info",
3157
3225
  weight: 7,
@@ -3160,30 +3228,30 @@ var audit23 = {
3160
3228
  const violations = [];
3161
3229
  if (!identity.site_name_set) {
3162
3230
  violations.push({
3163
- auditId: audit23.id,
3164
- label: (0, import_i18n47.__)("Site name is missing or still uses the default.", "elementor"),
3231
+ auditId: audit24.id,
3232
+ label: (0, import_i18n48.__)("Site name is missing or still uses the default.", "elementor"),
3165
3233
  targetHint: "site-identity-settings"
3166
3234
  });
3167
3235
  }
3168
3236
  if (!identity.site_description_set) {
3169
3237
  violations.push({
3170
- auditId: audit23.id,
3171
- label: (0, import_i18n47.__)("Site description is missing or still uses the default.", "elementor"),
3238
+ auditId: audit24.id,
3239
+ label: (0, import_i18n48.__)("Site description is missing or still uses the default.", "elementor"),
3172
3240
  targetHint: "site-identity-settings",
3173
3241
  angieFix: true
3174
3242
  });
3175
3243
  }
3176
3244
  if (!identity.site_logo_set) {
3177
3245
  violations.push({
3178
- auditId: audit23.id,
3179
- label: (0, import_i18n47.__)("Site logo is not set.", "elementor"),
3246
+ auditId: audit24.id,
3247
+ label: (0, import_i18n48.__)("Site logo is not set.", "elementor"),
3180
3248
  targetHint: "site-identity-settings"
3181
3249
  });
3182
3250
  }
3183
3251
  if (!identity.site_favicon_set) {
3184
3252
  violations.push({
3185
- auditId: audit23.id,
3186
- label: (0, import_i18n47.__)("Site favicon is not set.", "elementor"),
3253
+ auditId: audit24.id,
3254
+ label: (0, import_i18n48.__)("Site favicon is not set.", "elementor"),
3187
3255
  targetHint: "site-identity-settings"
3188
3256
  });
3189
3257
  }
@@ -3199,7 +3267,7 @@ var audit23 = {
3199
3267
 
3200
3268
  // src/audits/too-many-widgets.ts
3201
3269
  var import_editor_elements9 = require("@elementor/editor-elements");
3202
- var import_i18n48 = require("@wordpress/i18n");
3270
+ var import_i18n49 = require("@wordpress/i18n");
3203
3271
  var WIDGET_COUNT_THRESHOLD = 100;
3204
3272
  function isCountableWidget(node, widgetsCache) {
3205
3273
  if (node.elType === "widget") {
@@ -3207,17 +3275,17 @@ function isCountableWidget(node, widgetsCache) {
3207
3275
  }
3208
3276
  return !!widgetsCache?.[node.elType]?.meta?.is_compound;
3209
3277
  }
3210
- var audit24 = {
3278
+ var audit25 = {
3211
3279
  id: "audits/too-many-widgets",
3212
- title: (0, import_i18n48.__)("Too many widgets", "elementor"),
3213
- description: (0, import_i18n48.__)("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
3214
- fixHint: (0, import_i18n48.__)("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
3280
+ title: (0, import_i18n49.__)("Too many widgets", "elementor"),
3281
+ description: (0, import_i18n49.__)("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
3282
+ fixHint: (0, import_i18n49.__)("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
3215
3283
  categories: ["best-practices", "performance"],
3216
3284
  severity: "warning",
3217
3285
  weight: 5,
3218
3286
  evaluate: (ctx) => {
3219
3287
  if (ctx.elements.tree.length === 0) {
3220
- return { status: "skipped", reason: (0, import_i18n48.__)("No elements", "elementor") };
3288
+ return { status: "skipped", reason: (0, import_i18n49.__)("No elements", "elementor") };
3221
3289
  }
3222
3290
  const widgetsCache = (0, import_editor_elements9.getWidgetsCache)();
3223
3291
  let widgetCount = 0;
@@ -3233,8 +3301,8 @@ var audit24 = {
3233
3301
  status: "fail",
3234
3302
  violations: [
3235
3303
  {
3236
- auditId: audit24.id,
3237
- label: (0, import_i18n48.__)("Page has too many widgets.", "elementor")
3304
+ auditId: audit25.id,
3305
+ label: (0, import_i18n49.__)("Page has too many widgets.", "elementor")
3238
3306
  }
3239
3307
  ]
3240
3308
  };
@@ -3243,34 +3311,35 @@ var audit24 = {
3243
3311
 
3244
3312
  // src/register-audits.ts
3245
3313
  var AUDITS = [
3246
- audit16,
3247
- audit14,
3314
+ audit17,
3248
3315
  audit15,
3316
+ audit16,
3249
3317
  audit10,
3250
3318
  audit7,
3251
- audit24,
3252
- audit22,
3319
+ audit25,
3320
+ audit23,
3253
3321
  audit5,
3254
- audit13,
3322
+ audit14,
3255
3323
  audit6,
3256
- audit23,
3257
- audit17,
3324
+ audit24,
3258
3325
  audit18,
3326
+ audit19,
3259
3327
  audit9,
3260
3328
  audit11,
3329
+ audit13,
3261
3330
  audit12,
3331
+ audit21,
3262
3332
  audit20,
3263
- audit19,
3264
3333
  audit,
3265
3334
  audit2,
3266
3335
  audit3,
3267
3336
  audit4,
3268
- audit21,
3337
+ audit22,
3269
3338
  audit8
3270
3339
  ];
3271
3340
  function registerAllAudits() {
3272
- for (const audit25 of AUDITS) {
3273
- registerAudit(audit25);
3341
+ for (const audit26 of AUDITS) {
3342
+ registerAudit(audit26);
3274
3343
  }
3275
3344
  }
3276
3345