@elementor/editor-audits 4.4.0-1076 → 4.4.0-1077

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.mjs CHANGED
@@ -103,8 +103,8 @@ async function requestPageContext(documentId, attachmentIds, allowNonceRetry) {
103
103
 
104
104
  // src/registry.ts
105
105
  var registry = /* @__PURE__ */ new Map();
106
- function registerAudit(audit21) {
107
- registry.set(audit21.id, audit21);
106
+ function registerAudit(audit22) {
107
+ registry.set(audit22.id, audit22);
108
108
  }
109
109
  function getRegisteredAudits() {
110
110
  return Array.from(registry.values());
@@ -140,6 +140,11 @@ var CATEGORY_LABELS = {
140
140
  // src/utils/audit-status-summary.ts
141
141
  import { __ as __2 } from "@wordpress/i18n";
142
142
 
143
+ // src/utils/is-scored-audit.ts
144
+ function isScoredAudit(audit22) {
145
+ return audit22.weight > 0;
146
+ }
147
+
143
148
  // src/utils/sort-failed-audits.ts
144
149
  var SEVERITY_SORTING_RANK = {
145
150
  error: 0,
@@ -170,7 +175,9 @@ function partitionAuditResults(report, options = {}) {
170
175
  switch (run.result.status) {
171
176
  case "fail":
172
177
  failed.push({ ...run, result: run.result });
173
- totalViolations += run.result.violations.length;
178
+ if (isScoredAudit(run.audit)) {
179
+ totalViolations += run.result.violations.length;
180
+ }
174
181
  break;
175
182
  case "pass":
176
183
  passed.push({ ...run, result: run.result });
@@ -191,7 +198,10 @@ function auditStatusDisplayCounts(report) {
191
198
  let pass = 0;
192
199
  let skipped = 0;
193
200
  let totalViolations = 0;
194
- for (const { result } of report.auditResults) {
201
+ for (const { audit: audit22, result } of report.auditResults) {
202
+ if (!isScoredAudit(audit22)) {
203
+ continue;
204
+ }
195
205
  switch (result.status) {
196
206
  case "fail":
197
207
  totalViolations += result.violations.length;
@@ -239,16 +249,16 @@ function computeReport(documentId, results) {
239
249
  const accumulators = Object.fromEntries(
240
250
  ALL_CATEGORIES.map((c) => [c, { totalWeight: 0, passedWeight: 0, total: 0, failed: 0 }])
241
251
  );
242
- for (const { audit: audit21, result } of results) {
252
+ for (const { audit: audit22, result } of results) {
243
253
  if (result.status === "skipped") {
244
254
  continue;
245
255
  }
246
- for (const category of audit21.categories) {
256
+ for (const category of audit22.categories) {
247
257
  const acc = accumulators[category];
248
258
  acc.total++;
249
- acc.totalWeight += audit21.weight;
259
+ acc.totalWeight += audit22.weight;
250
260
  if (result.status === "pass") {
251
- acc.passedWeight += audit21.weight;
261
+ acc.passedWeight += audit22.weight;
252
262
  } else {
253
263
  acc.failed++;
254
264
  }
@@ -437,10 +447,10 @@ async function runPageAudit(documentId) {
437
447
  const ctx = { documentId, elements, pageContext, kit };
438
448
  const registered = getRegisteredAudits();
439
449
  const auditResults = await Promise.all(
440
- registered.map(async (audit21) => {
441
- const { evaluate: _evaluate, ...meta } = audit21;
450
+ registered.map(async (audit22) => {
451
+ const { evaluate: _evaluate, ...meta } = audit22;
442
452
  try {
443
- const result = await audit21.evaluate(ctx);
453
+ const result = await audit22.evaluate(ctx);
444
454
  return { audit: meta, result };
445
455
  } catch (error) {
446
456
  const reason = error instanceof Error ? error.message : "unknown-error";
@@ -741,7 +751,7 @@ import { Box as Box4, Chip, Collapse, IconButton as IconButton2 } from "@element
741
751
  import { __ as __7 } from "@wordpress/i18n";
742
752
  function StatusSection({ label, count, color = "default", defaultExpanded = false, children }) {
743
753
  const [expanded, setExpanded] = useState2(defaultExpanded);
744
- if (count === 0) {
754
+ if (React5.Children.count(children) === 0) {
745
755
  return null;
746
756
  }
747
757
  return /* @__PURE__ */ React5.createElement(Box4, { sx: { paddingBlock: 1 } }, /* @__PURE__ */ React5.createElement(
@@ -940,13 +950,13 @@ function ViolationIcon({ violation, widgetIcon }) {
940
950
  function SkipReasonTooltip({ reason }) {
941
951
  return /* @__PURE__ */ React11.createElement(Tooltip3, { title: reason, placement: "top" }, /* @__PURE__ */ React11.createElement(Box7, { "aria-label": reason, component: "span", sx: { display: "inline-flex", alignItems: "center" } }, /* @__PURE__ */ React11.createElement(HelpIcon, { fontSize: "small", color: "action" })));
942
952
  }
943
- function StatusIndicator({ audit: audit21, violations }) {
953
+ function StatusIndicator({ audit: audit22, violations }) {
944
954
  if (violations) {
945
- return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length), /* @__PURE__ */ React11.createElement(SeverityIcon, { severity: audit21.severity }));
955
+ return /* @__PURE__ */ React11.createElement(React11.Fragment, null, isScoredAudit(audit22) && /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length), /* @__PURE__ */ React11.createElement(SeverityIcon, { severity: audit22.severity }));
946
956
  }
947
957
  return /* @__PURE__ */ React11.createElement(CheckIcon, { fontSize: "small", color: "success" });
948
958
  }
949
- function ViolationRow({ audit: audit21, skipReason, violations }) {
959
+ function ViolationRow({ audit: audit22, skipReason, violations }) {
950
960
  const [expanded, setExpanded] = useState3(false);
951
961
  const toggleExpanded = () => setExpanded((value) => !value);
952
962
  return /* @__PURE__ */ React11.createElement(Box7, { sx: { borderBottom: 1, borderColor: "divider", paddingBlock: 0.5 } }, /* @__PURE__ */ React11.createElement(Box7, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React11.createElement(
@@ -962,8 +972,8 @@ function ViolationRow({ audit: audit21, skipReason, violations }) {
962
972
  },
963
973
  onClick: toggleExpanded
964
974
  },
965
- /* @__PURE__ */ React11.createElement(Typography6, { variant: "body2", sx: { flex: 1 } }, audit21.title),
966
- !skipReason && /* @__PURE__ */ React11.createElement(StatusIndicator, { audit: audit21, violations })
975
+ /* @__PURE__ */ React11.createElement(Typography6, { variant: "body2", sx: { flex: 1 } }, audit22.title),
976
+ !skipReason && /* @__PURE__ */ React11.createElement(StatusIndicator, { audit: audit22, violations })
967
977
  ), skipReason && /* @__PURE__ */ React11.createElement(SkipReasonTooltip, { reason: skipReason }), /* @__PURE__ */ React11.createElement(
968
978
  IconButton5,
969
979
  {
@@ -989,7 +999,7 @@ function ViolationRow({ audit: audit21, skipReason, violations }) {
989
999
  icon: /* @__PURE__ */ React11.createElement(AlertCircleIcon2, { fontSize: "small", color: "secondary", "aria-hidden": true })
990
1000
  },
991
1001
  /* @__PURE__ */ React11.createElement(AlertTitle, null, /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.primary", fontWeight: "bold" }, __11("What's the issue", "elementor"))),
992
- /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit21.description)
1002
+ /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit22.description)
993
1003
  ), /* @__PURE__ */ React11.createElement(
994
1004
  Alert,
995
1005
  {
@@ -998,7 +1008,7 @@ function ViolationRow({ audit: audit21, skipReason, violations }) {
998
1008
  icon: /* @__PURE__ */ React11.createElement(BulbIcon, { fontSize: "small", color: "info", "aria-hidden": true })
999
1009
  },
1000
1010
  /* @__PURE__ */ React11.createElement(AlertTitle, null, /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.primary", fontWeight: "bold" }, __11("How to resolve", "elementor"))),
1001
- /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit21.fixHint)
1011
+ /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit22.fixHint)
1002
1012
  )), violations && violations.length > 0 && /* @__PURE__ */ React11.createElement(Box7, { role: "list", sx: { paddingBlockEnd: 1, paddingInlineStart: 2 } }, violations.map((violation, idx) => {
1003
1013
  const widgetIcon = violation.elementId ? getElementIcon(violation.elementId) : null;
1004
1014
  const elementTitle = violation.elementId ? getElementTitle(violation.elementId) : null;
@@ -1138,14 +1148,17 @@ import { __ as __14, sprintf as sprintf2 } from "@wordpress/i18n";
1138
1148
  var ALL_SEVERITIES = ["error", "warning", "info"];
1139
1149
  function countSeverities(report, category) {
1140
1150
  const counts = { error: 0, warning: 0, info: 0 };
1141
- for (const { audit: audit21, result } of report.auditResults) {
1151
+ for (const { audit: audit22, result } of report.auditResults) {
1142
1152
  if (result.status !== "fail") {
1143
1153
  continue;
1144
1154
  }
1145
- if (category && !audit21.categories.includes(category)) {
1155
+ if (category && !audit22.categories.includes(category)) {
1156
+ continue;
1157
+ }
1158
+ if (!isScoredAudit(audit22)) {
1146
1159
  continue;
1147
1160
  }
1148
- counts[audit21.severity] += result.violations.length;
1161
+ counts[audit22.severity] += result.violations.length;
1149
1162
  }
1150
1163
  return counts;
1151
1164
  }
@@ -1257,6 +1270,13 @@ var PROMOTIONS = [
1257
1270
  formatSubtitle: (run) => run.result.status === "fail" ? __15("Generate cookie policy", "elementor") : null,
1258
1271
  getCtaUrl: firstFailExternalUrl
1259
1272
  },
1273
+ {
1274
+ auditId: "audits/scan-for-cookies",
1275
+ icon: ElementorCookieIcon,
1276
+ ctaLabel: __15("Scan", "elementor"),
1277
+ formatSubtitle: (run) => run.result.status === "fail" ? __15("Scan this page for cookies", "elementor") : null,
1278
+ getCtaUrl: firstFailExternalUrl
1279
+ },
1260
1280
  {
1261
1281
  auditId: "audits/images-too-large",
1262
1282
  icon: ShieldHalfFilledIcon2,
@@ -2716,30 +2736,58 @@ var audit17 = {
2716
2736
  }
2717
2737
  };
2718
2738
 
2719
- // src/audits/sections-and-columns.ts
2739
+ // src/audits/scan-for-cookies.ts
2720
2740
  import { __ as __40 } from "@wordpress/i18n";
2721
2741
  var audit18 = {
2722
- id: "audits/sections-and-columns",
2723
- title: __40("Sections and columns", "elementor"),
2742
+ id: "audits/scan-for-cookies",
2743
+ title: __40("Scan for cookies", "elementor"),
2724
2744
  description: __40(
2745
+ "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.",
2746
+ "elementor"
2747
+ ),
2748
+ fixHint: __40("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
2749
+ categories: ["compliance"],
2750
+ severity: "info",
2751
+ weight: 0,
2752
+ evaluate: (ctx) => {
2753
+ const isReady = ctx.pageContext.cookiez_plugin_installed && ctx.pageContext.cookiez_plugin_active;
2754
+ return {
2755
+ status: "fail",
2756
+ violations: [
2757
+ {
2758
+ auditId: audit18.id,
2759
+ label: __40("This page has not been scanned for cookies yet.", "elementor"),
2760
+ externalUrl: isReady ? ctx.pageContext.cookiez_scan_url : ctx.pageContext.cookiez_plugin_action_url
2761
+ }
2762
+ ]
2763
+ };
2764
+ }
2765
+ };
2766
+
2767
+ // src/audits/sections-and-columns.ts
2768
+ import { __ as __41 } from "@wordpress/i18n";
2769
+ var audit19 = {
2770
+ id: "audits/sections-and-columns",
2771
+ title: __41("Sections and columns", "elementor"),
2772
+ description: __41(
2725
2773
  "Sections and columns are legacy elements. Containers render fewer DOM nodes and are more flexible.",
2726
2774
  "elementor"
2727
2775
  ),
2728
- fixHint: __40("Use the Container Converter to replace each section/column with a container.", "elementor"),
2776
+ fixHint: __41("Use the Container Converter to replace each section/column with a container.", "elementor"),
2729
2777
  categories: ["best-practices", "performance"],
2730
2778
  severity: "warning",
2731
2779
  weight: 7,
2732
2780
  evaluate: (ctx) => {
2733
2781
  if (ctx.elements.tree.length === 0) {
2734
- return { status: "skipped", reason: __40("No elements", "elementor") };
2782
+ return { status: "skipped", reason: __41("No elements", "elementor") };
2735
2783
  }
2736
2784
  const violations = [];
2737
2785
  walkElements(ctx.elements.tree, (node) => {
2738
2786
  if (node.elType === "section" || node.elType === "column") {
2739
2787
  violations.push({
2740
- auditId: audit18.id,
2788
+ auditId: audit19.id,
2741
2789
  elementId: node.id,
2742
- label: node.elType === "section" ? __40("Section element", "elementor") : __40("Column element", "elementor")
2790
+ label: node.elType === "section" ? __41("Section element", "elementor") : __41("Column element", "elementor")
2743
2791
  });
2744
2792
  }
2745
2793
  });
@@ -2748,15 +2796,15 @@ var audit18 = {
2748
2796
  };
2749
2797
 
2750
2798
  // src/audits/site-identity.ts
2751
- import { __ as __41 } from "@wordpress/i18n";
2752
- var audit19 = {
2799
+ import { __ as __42 } from "@wordpress/i18n";
2800
+ var audit20 = {
2753
2801
  id: "audits/site-identity",
2754
- title: __41("Site identity", "elementor"),
2755
- description: __41(
2802
+ title: __42("Site identity", "elementor"),
2803
+ description: __42(
2756
2804
  "Site name, description, logo, and favicon establish your brand and appear in search results and browser tabs.",
2757
2805
  "elementor"
2758
2806
  ),
2759
- fixHint: __41("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
2807
+ fixHint: __42("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
2760
2808
  categories: ["best-practices", "seo"],
2761
2809
  severity: "info",
2762
2810
  weight: 7,
@@ -2765,30 +2813,30 @@ var audit19 = {
2765
2813
  const violations = [];
2766
2814
  if (!identity.site_name_set) {
2767
2815
  violations.push({
2768
- auditId: audit19.id,
2769
- label: __41("Site name is missing or still uses the default.", "elementor"),
2816
+ auditId: audit20.id,
2817
+ label: __42("Site name is missing or still uses the default.", "elementor"),
2770
2818
  targetHint: "site-identity-settings"
2771
2819
  });
2772
2820
  }
2773
2821
  if (!identity.site_description_set) {
2774
2822
  violations.push({
2775
- auditId: audit19.id,
2776
- label: __41("Site description is missing or still uses the default.", "elementor"),
2823
+ auditId: audit20.id,
2824
+ label: __42("Site description is missing or still uses the default.", "elementor"),
2777
2825
  targetHint: "site-identity-settings",
2778
2826
  angieFix: true
2779
2827
  });
2780
2828
  }
2781
2829
  if (!identity.site_logo_set) {
2782
2830
  violations.push({
2783
- auditId: audit19.id,
2784
- label: __41("Site logo is not set.", "elementor"),
2831
+ auditId: audit20.id,
2832
+ label: __42("Site logo is not set.", "elementor"),
2785
2833
  targetHint: "site-identity-settings"
2786
2834
  });
2787
2835
  }
2788
2836
  if (!identity.site_favicon_set) {
2789
2837
  violations.push({
2790
- auditId: audit19.id,
2791
- label: __41("Site favicon is not set.", "elementor"),
2838
+ auditId: audit20.id,
2839
+ label: __42("Site favicon is not set.", "elementor"),
2792
2840
  targetHint: "site-identity-settings"
2793
2841
  });
2794
2842
  }
@@ -2803,19 +2851,19 @@ var audit19 = {
2803
2851
  };
2804
2852
 
2805
2853
  // src/audits/too-many-widgets.ts
2806
- import { __ as __42 } from "@wordpress/i18n";
2854
+ import { __ as __43 } from "@wordpress/i18n";
2807
2855
  var WIDGET_COUNT_THRESHOLD = 100;
2808
- var audit20 = {
2856
+ var audit21 = {
2809
2857
  id: "audits/too-many-widgets",
2810
- title: __42("Too many widgets", "elementor"),
2811
- description: __42("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
2812
- fixHint: __42("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
2858
+ title: __43("Too many widgets", "elementor"),
2859
+ description: __43("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
2860
+ fixHint: __43("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
2813
2861
  categories: ["best-practices", "performance"],
2814
2862
  severity: "warning",
2815
2863
  weight: 5,
2816
2864
  evaluate: (ctx) => {
2817
2865
  if (ctx.elements.tree.length === 0) {
2818
- return { status: "skipped", reason: __42("No elements", "elementor") };
2866
+ return { status: "skipped", reason: __43("No elements", "elementor") };
2819
2867
  }
2820
2868
  let widgetCount = 0;
2821
2869
  walkElements(ctx.elements.tree, (node) => {
@@ -2830,8 +2878,8 @@ var audit20 = {
2830
2878
  status: "fail",
2831
2879
  violations: [
2832
2880
  {
2833
- auditId: audit20.id,
2834
- label: __42("Page has too many widgets.", "elementor")
2881
+ auditId: audit21.id,
2882
+ label: __43("Page has too many widgets.", "elementor")
2835
2883
  }
2836
2884
  ]
2837
2885
  };
@@ -2845,12 +2893,12 @@ var AUDITS = [
2845
2893
  audit12,
2846
2894
  audit7,
2847
2895
  audit5,
2848
- audit20,
2849
- audit18,
2896
+ audit21,
2897
+ audit19,
2850
2898
  audit3,
2851
2899
  audit10,
2852
2900
  audit4,
2853
- audit19,
2901
+ audit20,
2854
2902
  audit14,
2855
2903
  audit15,
2856
2904
  audit6,
@@ -2859,11 +2907,12 @@ var AUDITS = [
2859
2907
  audit17,
2860
2908
  audit16,
2861
2909
  audit,
2862
- audit2
2910
+ audit2,
2911
+ audit18
2863
2912
  ];
2864
2913
  function registerAllAudits() {
2865
- for (const audit21 of AUDITS) {
2866
- registerAudit(audit21);
2914
+ for (const audit22 of AUDITS) {
2915
+ registerAudit(audit22);
2867
2916
  }
2868
2917
  }
2869
2918