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

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.d.mts CHANGED
@@ -63,6 +63,9 @@ type PageContextResponse = {
63
63
  ally_plugin_url: string;
64
64
  cookiez_plugin_active: boolean;
65
65
  cookiez_plugin_url: string;
66
+ cookiez_plugin_installed: boolean;
67
+ cookiez_plugin_action_url: string;
68
+ cookiez_scan_url: string;
66
69
  image_optimization_plugin_active: boolean;
67
70
  image_optimization_plugin_url: string;
68
71
  site_identity: {
package/dist/index.d.ts CHANGED
@@ -63,6 +63,9 @@ type PageContextResponse = {
63
63
  ally_plugin_url: string;
64
64
  cookiez_plugin_active: boolean;
65
65
  cookiez_plugin_url: string;
66
+ cookiez_plugin_installed: boolean;
67
+ cookiez_plugin_action_url: string;
68
+ cookiez_scan_url: string;
66
69
  image_optimization_plugin_active: boolean;
67
70
  image_optimization_plugin_url: string;
68
71
  site_identity: {
package/dist/index.js CHANGED
@@ -141,8 +141,8 @@ async function requestPageContext(documentId, attachmentIds, allowNonceRetry) {
141
141
 
142
142
  // src/registry.ts
143
143
  var registry = /* @__PURE__ */ new Map();
144
- function registerAudit(audit21) {
145
- registry.set(audit21.id, audit21);
144
+ function registerAudit(audit22) {
145
+ registry.set(audit22.id, audit22);
146
146
  }
147
147
  function getRegisteredAudits() {
148
148
  return Array.from(registry.values());
@@ -178,6 +178,11 @@ var CATEGORY_LABELS = {
178
178
  // src/utils/audit-status-summary.ts
179
179
  var import_i18n2 = require("@wordpress/i18n");
180
180
 
181
+ // src/utils/is-scored-audit.ts
182
+ function isScoredAudit(audit22) {
183
+ return audit22.weight > 0;
184
+ }
185
+
181
186
  // src/utils/sort-failed-audits.ts
182
187
  var SEVERITY_SORTING_RANK = {
183
188
  error: 0,
@@ -208,7 +213,9 @@ function partitionAuditResults(report, options = {}) {
208
213
  switch (run.result.status) {
209
214
  case "fail":
210
215
  failed.push({ ...run, result: run.result });
211
- totalViolations += run.result.violations.length;
216
+ if (isScoredAudit(run.audit)) {
217
+ totalViolations += run.result.violations.length;
218
+ }
212
219
  break;
213
220
  case "pass":
214
221
  passed.push({ ...run, result: run.result });
@@ -229,7 +236,10 @@ function auditStatusDisplayCounts(report) {
229
236
  let pass = 0;
230
237
  let skipped = 0;
231
238
  let totalViolations = 0;
232
- for (const { result } of report.auditResults) {
239
+ for (const { audit: audit22, result } of report.auditResults) {
240
+ if (!isScoredAudit(audit22)) {
241
+ continue;
242
+ }
233
243
  switch (result.status) {
234
244
  case "fail":
235
245
  totalViolations += result.violations.length;
@@ -277,16 +287,16 @@ function computeReport(documentId, results) {
277
287
  const accumulators = Object.fromEntries(
278
288
  ALL_CATEGORIES.map((c) => [c, { totalWeight: 0, passedWeight: 0, total: 0, failed: 0 }])
279
289
  );
280
- for (const { audit: audit21, result } of results) {
290
+ for (const { audit: audit22, result } of results) {
281
291
  if (result.status === "skipped") {
282
292
  continue;
283
293
  }
284
- for (const category of audit21.categories) {
294
+ for (const category of audit22.categories) {
285
295
  const acc = accumulators[category];
286
296
  acc.total++;
287
- acc.totalWeight += audit21.weight;
297
+ acc.totalWeight += audit22.weight;
288
298
  if (result.status === "pass") {
289
- acc.passedWeight += audit21.weight;
299
+ acc.passedWeight += audit22.weight;
290
300
  } else {
291
301
  acc.failed++;
292
302
  }
@@ -475,10 +485,10 @@ async function runPageAudit(documentId) {
475
485
  const ctx = { documentId, elements, pageContext, kit };
476
486
  const registered = getRegisteredAudits();
477
487
  const auditResults = await Promise.all(
478
- registered.map(async (audit21) => {
479
- const { evaluate: _evaluate, ...meta } = audit21;
488
+ registered.map(async (audit22) => {
489
+ const { evaluate: _evaluate, ...meta } = audit22;
480
490
  try {
481
- const result = await audit21.evaluate(ctx);
491
+ const result = await audit22.evaluate(ctx);
482
492
  return { audit: meta, result };
483
493
  } catch (error) {
484
494
  const reason = error instanceof Error ? error.message : "unknown-error";
@@ -767,7 +777,7 @@ var import_ui5 = require("@elementor/ui");
767
777
  var import_i18n7 = require("@wordpress/i18n");
768
778
  function StatusSection({ label, count, color = "default", defaultExpanded = false, children }) {
769
779
  const [expanded, setExpanded] = (0, import_react3.useState)(defaultExpanded);
770
- if (count === 0) {
780
+ if (React5.Children.count(children) === 0) {
771
781
  return null;
772
782
  }
773
783
  return /* @__PURE__ */ React5.createElement(import_ui5.Box, { sx: { paddingBlock: 1 } }, /* @__PURE__ */ React5.createElement(
@@ -966,13 +976,13 @@ function ViolationIcon({ violation, widgetIcon }) {
966
976
  function SkipReasonTooltip({ reason }) {
967
977
  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" })));
968
978
  }
969
- function StatusIndicator({ audit: audit21, violations }) {
979
+ function StatusIndicator({ audit: audit22, violations }) {
970
980
  if (violations) {
971
- return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length), /* @__PURE__ */ React11.createElement(SeverityIcon, { severity: audit21.severity }));
981
+ return /* @__PURE__ */ React11.createElement(React11.Fragment, null, isScoredAudit(audit22) && /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length), /* @__PURE__ */ React11.createElement(SeverityIcon, { severity: audit22.severity }));
972
982
  }
973
983
  return /* @__PURE__ */ React11.createElement(import_icons7.CheckIcon, { fontSize: "small", color: "success" });
974
984
  }
975
- function ViolationRow({ audit: audit21, skipReason, violations }) {
985
+ function ViolationRow({ audit: audit22, skipReason, violations }) {
976
986
  const [expanded, setExpanded] = (0, import_react4.useState)(false);
977
987
  const toggleExpanded = () => setExpanded((value) => !value);
978
988
  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(
@@ -988,8 +998,8 @@ function ViolationRow({ audit: audit21, skipReason, violations }) {
988
998
  },
989
999
  onClick: toggleExpanded
990
1000
  },
991
- /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "body2", sx: { flex: 1 } }, audit21.title),
992
- !skipReason && /* @__PURE__ */ React11.createElement(StatusIndicator, { audit: audit21, violations })
1001
+ /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "body2", sx: { flex: 1 } }, audit22.title),
1002
+ !skipReason && /* @__PURE__ */ React11.createElement(StatusIndicator, { audit: audit22, violations })
993
1003
  ), skipReason && /* @__PURE__ */ React11.createElement(SkipReasonTooltip, { reason: skipReason }), /* @__PURE__ */ React11.createElement(
994
1004
  import_ui10.IconButton,
995
1005
  {
@@ -1015,7 +1025,7 @@ function ViolationRow({ audit: audit21, skipReason, violations }) {
1015
1025
  icon: /* @__PURE__ */ React11.createElement(import_icons7.AlertCircleIcon, { fontSize: "small", color: "secondary", "aria-hidden": true })
1016
1026
  },
1017
1027
  /* @__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"))),
1018
- /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", component: "p", color: "text.secondary" }, audit21.description)
1028
+ /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", component: "p", color: "text.secondary" }, audit22.description)
1019
1029
  ), /* @__PURE__ */ React11.createElement(
1020
1030
  import_ui10.Alert,
1021
1031
  {
@@ -1024,7 +1034,7 @@ function ViolationRow({ audit: audit21, skipReason, violations }) {
1024
1034
  icon: /* @__PURE__ */ React11.createElement(import_icons7.BulbIcon, { fontSize: "small", color: "info", "aria-hidden": true })
1025
1035
  },
1026
1036
  /* @__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"))),
1027
- /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", component: "p", color: "text.secondary" }, audit21.fixHint)
1037
+ /* @__PURE__ */ React11.createElement(import_ui10.Typography, { variant: "caption", component: "p", color: "text.secondary" }, audit22.fixHint)
1028
1038
  )), violations && violations.length > 0 && /* @__PURE__ */ React11.createElement(import_ui10.Box, { role: "list", sx: { paddingBlockEnd: 1, paddingInlineStart: 2 } }, violations.map((violation, idx) => {
1029
1039
  const widgetIcon = violation.elementId ? (0, import_editor_elements4.getElementIcon)(violation.elementId) : null;
1030
1040
  const elementTitle = violation.elementId ? (0, import_editor_elements4.getElementTitle)(violation.elementId) : null;
@@ -1158,14 +1168,17 @@ var import_i18n14 = require("@wordpress/i18n");
1158
1168
  var ALL_SEVERITIES = ["error", "warning", "info"];
1159
1169
  function countSeverities(report, category) {
1160
1170
  const counts = { error: 0, warning: 0, info: 0 };
1161
- for (const { audit: audit21, result } of report.auditResults) {
1171
+ for (const { audit: audit22, result } of report.auditResults) {
1162
1172
  if (result.status !== "fail") {
1163
1173
  continue;
1164
1174
  }
1165
- if (category && !audit21.categories.includes(category)) {
1175
+ if (category && !audit22.categories.includes(category)) {
1176
+ continue;
1177
+ }
1178
+ if (!isScoredAudit(audit22)) {
1166
1179
  continue;
1167
1180
  }
1168
- counts[audit21.severity] += result.violations.length;
1181
+ counts[audit22.severity] += result.violations.length;
1169
1182
  }
1170
1183
  return counts;
1171
1184
  }
@@ -1277,6 +1290,13 @@ var PROMOTIONS = [
1277
1290
  formatSubtitle: (run) => run.result.status === "fail" ? (0, import_i18n15.__)("Generate cookie policy", "elementor") : null,
1278
1291
  getCtaUrl: firstFailExternalUrl
1279
1292
  },
1293
+ {
1294
+ auditId: "audits/scan-for-cookies",
1295
+ icon: import_icons10.ElementorCookieIcon,
1296
+ ctaLabel: (0, import_i18n15.__)("Scan", "elementor"),
1297
+ formatSubtitle: (run) => run.result.status === "fail" ? (0, import_i18n15.__)("Scan this page for cookies", "elementor") : null,
1298
+ getCtaUrl: firstFailExternalUrl
1299
+ },
1280
1300
  {
1281
1301
  auditId: "audits/images-too-large",
1282
1302
  icon: import_icons10.ShieldHalfFilledIcon,
@@ -2736,30 +2756,58 @@ var audit17 = {
2736
2756
  }
2737
2757
  };
2738
2758
 
2739
- // src/audits/sections-and-columns.ts
2759
+ // src/audits/scan-for-cookies.ts
2740
2760
  var import_i18n40 = require("@wordpress/i18n");
2741
2761
  var audit18 = {
2742
- id: "audits/sections-and-columns",
2743
- title: (0, import_i18n40.__)("Sections and columns", "elementor"),
2762
+ id: "audits/scan-for-cookies",
2763
+ title: (0, import_i18n40.__)("Scan for cookies", "elementor"),
2744
2764
  description: (0, import_i18n40.__)(
2765
+ "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.",
2766
+ "elementor"
2767
+ ),
2768
+ fixHint: (0, import_i18n40.__)("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
2769
+ categories: ["compliance"],
2770
+ severity: "info",
2771
+ weight: 0,
2772
+ evaluate: (ctx) => {
2773
+ const isReady = ctx.pageContext.cookiez_plugin_installed && ctx.pageContext.cookiez_plugin_active;
2774
+ return {
2775
+ status: "fail",
2776
+ violations: [
2777
+ {
2778
+ auditId: audit18.id,
2779
+ label: (0, import_i18n40.__)("This page has not been scanned for cookies yet.", "elementor"),
2780
+ externalUrl: isReady ? ctx.pageContext.cookiez_scan_url : ctx.pageContext.cookiez_plugin_action_url
2781
+ }
2782
+ ]
2783
+ };
2784
+ }
2785
+ };
2786
+
2787
+ // src/audits/sections-and-columns.ts
2788
+ var import_i18n41 = require("@wordpress/i18n");
2789
+ var audit19 = {
2790
+ id: "audits/sections-and-columns",
2791
+ title: (0, import_i18n41.__)("Sections and columns", "elementor"),
2792
+ description: (0, import_i18n41.__)(
2745
2793
  "Sections and columns are legacy elements. Containers render fewer DOM nodes and are more flexible.",
2746
2794
  "elementor"
2747
2795
  ),
2748
- fixHint: (0, import_i18n40.__)("Use the Container Converter to replace each section/column with a container.", "elementor"),
2796
+ fixHint: (0, import_i18n41.__)("Use the Container Converter to replace each section/column with a container.", "elementor"),
2749
2797
  categories: ["best-practices", "performance"],
2750
2798
  severity: "warning",
2751
2799
  weight: 7,
2752
2800
  evaluate: (ctx) => {
2753
2801
  if (ctx.elements.tree.length === 0) {
2754
- return { status: "skipped", reason: (0, import_i18n40.__)("No elements", "elementor") };
2802
+ return { status: "skipped", reason: (0, import_i18n41.__)("No elements", "elementor") };
2755
2803
  }
2756
2804
  const violations = [];
2757
2805
  walkElements(ctx.elements.tree, (node) => {
2758
2806
  if (node.elType === "section" || node.elType === "column") {
2759
2807
  violations.push({
2760
- auditId: audit18.id,
2808
+ auditId: audit19.id,
2761
2809
  elementId: node.id,
2762
- label: node.elType === "section" ? (0, import_i18n40.__)("Section element", "elementor") : (0, import_i18n40.__)("Column element", "elementor")
2810
+ label: node.elType === "section" ? (0, import_i18n41.__)("Section element", "elementor") : (0, import_i18n41.__)("Column element", "elementor")
2763
2811
  });
2764
2812
  }
2765
2813
  });
@@ -2768,15 +2816,15 @@ var audit18 = {
2768
2816
  };
2769
2817
 
2770
2818
  // src/audits/site-identity.ts
2771
- var import_i18n41 = require("@wordpress/i18n");
2772
- var audit19 = {
2819
+ var import_i18n42 = require("@wordpress/i18n");
2820
+ var audit20 = {
2773
2821
  id: "audits/site-identity",
2774
- title: (0, import_i18n41.__)("Site identity", "elementor"),
2775
- description: (0, import_i18n41.__)(
2822
+ title: (0, import_i18n42.__)("Site identity", "elementor"),
2823
+ description: (0, import_i18n42.__)(
2776
2824
  "Site name, description, logo, and favicon establish your brand and appear in search results and browser tabs.",
2777
2825
  "elementor"
2778
2826
  ),
2779
- fixHint: (0, import_i18n41.__)("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
2827
+ fixHint: (0, import_i18n42.__)("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
2780
2828
  categories: ["best-practices", "seo"],
2781
2829
  severity: "info",
2782
2830
  weight: 7,
@@ -2785,30 +2833,30 @@ var audit19 = {
2785
2833
  const violations = [];
2786
2834
  if (!identity.site_name_set) {
2787
2835
  violations.push({
2788
- auditId: audit19.id,
2789
- label: (0, import_i18n41.__)("Site name is missing or still uses the default.", "elementor"),
2836
+ auditId: audit20.id,
2837
+ label: (0, import_i18n42.__)("Site name is missing or still uses the default.", "elementor"),
2790
2838
  targetHint: "site-identity-settings"
2791
2839
  });
2792
2840
  }
2793
2841
  if (!identity.site_description_set) {
2794
2842
  violations.push({
2795
- auditId: audit19.id,
2796
- label: (0, import_i18n41.__)("Site description is missing or still uses the default.", "elementor"),
2843
+ auditId: audit20.id,
2844
+ label: (0, import_i18n42.__)("Site description is missing or still uses the default.", "elementor"),
2797
2845
  targetHint: "site-identity-settings",
2798
2846
  angieFix: true
2799
2847
  });
2800
2848
  }
2801
2849
  if (!identity.site_logo_set) {
2802
2850
  violations.push({
2803
- auditId: audit19.id,
2804
- label: (0, import_i18n41.__)("Site logo is not set.", "elementor"),
2851
+ auditId: audit20.id,
2852
+ label: (0, import_i18n42.__)("Site logo is not set.", "elementor"),
2805
2853
  targetHint: "site-identity-settings"
2806
2854
  });
2807
2855
  }
2808
2856
  if (!identity.site_favicon_set) {
2809
2857
  violations.push({
2810
- auditId: audit19.id,
2811
- label: (0, import_i18n41.__)("Site favicon is not set.", "elementor"),
2858
+ auditId: audit20.id,
2859
+ label: (0, import_i18n42.__)("Site favicon is not set.", "elementor"),
2812
2860
  targetHint: "site-identity-settings"
2813
2861
  });
2814
2862
  }
@@ -2823,19 +2871,19 @@ var audit19 = {
2823
2871
  };
2824
2872
 
2825
2873
  // src/audits/too-many-widgets.ts
2826
- var import_i18n42 = require("@wordpress/i18n");
2874
+ var import_i18n43 = require("@wordpress/i18n");
2827
2875
  var WIDGET_COUNT_THRESHOLD = 100;
2828
- var audit20 = {
2876
+ var audit21 = {
2829
2877
  id: "audits/too-many-widgets",
2830
- title: (0, import_i18n42.__)("Too many widgets", "elementor"),
2831
- description: (0, import_i18n42.__)("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
2832
- fixHint: (0, import_i18n42.__)("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
2878
+ title: (0, import_i18n43.__)("Too many widgets", "elementor"),
2879
+ description: (0, import_i18n43.__)("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
2880
+ fixHint: (0, import_i18n43.__)("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
2833
2881
  categories: ["best-practices", "performance"],
2834
2882
  severity: "warning",
2835
2883
  weight: 5,
2836
2884
  evaluate: (ctx) => {
2837
2885
  if (ctx.elements.tree.length === 0) {
2838
- return { status: "skipped", reason: (0, import_i18n42.__)("No elements", "elementor") };
2886
+ return { status: "skipped", reason: (0, import_i18n43.__)("No elements", "elementor") };
2839
2887
  }
2840
2888
  let widgetCount = 0;
2841
2889
  walkElements(ctx.elements.tree, (node) => {
@@ -2850,8 +2898,8 @@ var audit20 = {
2850
2898
  status: "fail",
2851
2899
  violations: [
2852
2900
  {
2853
- auditId: audit20.id,
2854
- label: (0, import_i18n42.__)("Page has too many widgets.", "elementor")
2901
+ auditId: audit21.id,
2902
+ label: (0, import_i18n43.__)("Page has too many widgets.", "elementor")
2855
2903
  }
2856
2904
  ]
2857
2905
  };
@@ -2865,12 +2913,12 @@ var AUDITS = [
2865
2913
  audit12,
2866
2914
  audit7,
2867
2915
  audit5,
2868
- audit20,
2869
- audit18,
2916
+ audit21,
2917
+ audit19,
2870
2918
  audit3,
2871
2919
  audit10,
2872
2920
  audit4,
2873
- audit19,
2921
+ audit20,
2874
2922
  audit14,
2875
2923
  audit15,
2876
2924
  audit6,
@@ -2879,11 +2927,12 @@ var AUDITS = [
2879
2927
  audit17,
2880
2928
  audit16,
2881
2929
  audit,
2882
- audit2
2930
+ audit2,
2931
+ audit18
2883
2932
  ];
2884
2933
  function registerAllAudits() {
2885
- for (const audit21 of AUDITS) {
2886
- registerAudit(audit21);
2934
+ for (const audit22 of AUDITS) {
2935
+ registerAudit(audit22);
2887
2936
  }
2888
2937
  }
2889
2938