@elementor/editor-audits 4.4.0-1129 → 4.4.0-1131

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
@@ -208,16 +208,16 @@ async function requestPageContext(documentId, imageSizeRequests, allowNonceRetry
208
208
 
209
209
  // src/registry.ts
210
210
  var registry = /* @__PURE__ */ new Map();
211
- function registerAudit(audit26) {
212
- registry.set(audit26.id, audit26);
211
+ function registerAudit(audit25) {
212
+ registry.set(audit25.id, audit25);
213
213
  }
214
214
  function getRegisteredAudits() {
215
215
  return Array.from(registry.values());
216
216
  }
217
217
 
218
218
  // src/utils/is-scored-audit.ts
219
- function isScoredAudit(audit26) {
220
- return audit26.weight > 0;
219
+ function isScoredAudit(audit25) {
220
+ return audit25.weight > 0;
221
221
  }
222
222
 
223
223
  // src/utils/sort-failed-audits.ts
@@ -278,16 +278,16 @@ function computeReport(documentId, results) {
278
278
  const accumulators = Object.fromEntries(
279
279
  ALL_CATEGORIES.map((c) => [c, { totalWeight: 0, passedWeight: 0, total: 0, failed: 0 }])
280
280
  );
281
- for (const { audit: audit26, result } of results) {
281
+ for (const { audit: audit25, result } of results) {
282
282
  if (result.status === "skipped") {
283
283
  continue;
284
284
  }
285
- for (const category of audit26.categories) {
285
+ for (const category of audit25.categories) {
286
286
  const acc = accumulators[category];
287
287
  acc.total++;
288
- acc.totalWeight += audit26.weight;
288
+ acc.totalWeight += audit25.weight;
289
289
  if (result.status === "pass") {
290
- acc.passedWeight += audit26.weight;
290
+ acc.passedWeight += audit25.weight;
291
291
  } else {
292
292
  acc.failed++;
293
293
  }
@@ -364,13 +364,14 @@ function recurse(nodes, parents, visit) {
364
364
  }
365
365
 
366
366
  // src/utils/atomic-image-sources.ts
367
- var ATOMIC_IMAGE_PROP_KEYS = ["image", "poster"];
368
- function walkAtomicImageSources(tree, visit) {
367
+ var ATOMIC_CONTENT_IMAGE_PROP_KEYS = ["image"];
368
+ var ATOMIC_IMAGE_PROP_KEYS = [...ATOMIC_CONTENT_IMAGE_PROP_KEYS, "poster"];
369
+ function walkAtomicImageSources(tree, visit, propKeys = ATOMIC_IMAGE_PROP_KEYS) {
369
370
  walkElements(tree, (node) => {
370
371
  if (node.elType !== "widget") {
371
372
  return;
372
373
  }
373
- for (const key of ATOMIC_IMAGE_PROP_KEYS) {
374
+ for (const key of propKeys) {
374
375
  const media = extractAtomicImageMedia(node.settings[key]);
375
376
  if (media) {
376
377
  visit({ node, media });
@@ -392,8 +393,9 @@ function extractAtomicImageMedia(imageProp) {
392
393
  if (!id && !url) {
393
394
  return null;
394
395
  }
396
+ const alt = stringPropTypeUtil.extract(src.alt) ?? void 0;
395
397
  const size = stringPropTypeUtil.extract(image.size) ?? void 0;
396
- return { id, url, size };
398
+ return { id, url, alt, size };
397
399
  }
398
400
 
399
401
  // src/utils/atomic-background-image-sources.ts
@@ -448,15 +450,6 @@ function walkBackgroundImageSources(tree, visit) {
448
450
 
449
451
  // src/utils/image-like-sources.ts
450
452
  var IMAGE_LIKE_WIDGETS = /* @__PURE__ */ new Set(["image", "image-box", "image-carousel", "gallery", "image-gallery"]);
451
- function hasPageImages(tree) {
452
- let found = false;
453
- walkImageLikeSources(tree, ({ media }) => {
454
- if (media.id || media.url) {
455
- found = true;
456
- }
457
- });
458
- return found;
459
- }
460
453
  function walkImageLikeSources(tree, visit) {
461
454
  walkElements(tree, (node) => {
462
455
  if (node.elType !== "widget") {
@@ -488,6 +481,14 @@ function collectMediaFromNode(node) {
488
481
  return sources;
489
482
  }
490
483
 
484
+ // src/utils/all-image-sources.ts
485
+ function walkAllImageSources(tree, visit) {
486
+ walkImageLikeSources(tree, visit);
487
+ walkBackgroundImageSources(tree, visit);
488
+ walkAtomicImageSources(tree, visit);
489
+ walkAtomicBackgroundImageSources(tree, visit);
490
+ }
491
+
491
492
  // src/utils/image-size-key.ts
492
493
  function buildImageSizeKey({ id, size }) {
493
494
  return `${id}:${size || "full"}`;
@@ -496,15 +497,11 @@ function buildImageSizeKey({ id, size }) {
496
497
  // src/utils/page-attachments.ts
497
498
  function extractImageSizeRequests(tree) {
498
499
  const keys = /* @__PURE__ */ new Set();
499
- const collect = (media) => {
500
+ walkAllImageSources(tree, ({ media }) => {
500
501
  if (media.id) {
501
502
  keys.add(buildImageSizeKey({ id: media.id, size: media.size }));
502
503
  }
503
- };
504
- walkImageLikeSources(tree, ({ media }) => collect(media));
505
- walkBackgroundImageSources(tree, ({ media }) => collect(media));
506
- walkAtomicImageSources(tree, ({ media }) => collect(media));
507
- walkAtomicBackgroundImageSources(tree, ({ media }) => collect(media));
504
+ });
508
505
  return Array.from(keys).sort();
509
506
  }
510
507
 
@@ -613,10 +610,10 @@ async function runPageAudit(documentId) {
613
610
  const ctx = { documentId, elements, pageContext, kit, renderedHtml };
614
611
  const registered = getRegisteredAudits();
615
612
  const auditResults = await Promise.all(
616
- registered.map(async (audit26) => {
617
- const { evaluate: _evaluate, ...meta } = audit26;
613
+ registered.map(async (audit25) => {
614
+ const { evaluate: _evaluate, ...meta } = audit25;
618
615
  try {
619
- const result = await audit26.evaluate(ctx);
616
+ const result = await audit25.evaluate(ctx);
620
617
  return { audit: meta, result };
621
618
  } catch (error) {
622
619
  const reason = error instanceof Error ? error.message : "unknown-error";
@@ -1109,9 +1106,9 @@ function ViolationIcon({ violation, widgetIcon }) {
1109
1106
  function SkipReasonTooltip({ reason }) {
1110
1107
  return /* @__PURE__ */ React12.createElement(Tooltip3, { title: reason, placement: "top" }, /* @__PURE__ */ React12.createElement(Box7, { "aria-label": reason, component: "span", sx: { display: "inline-flex", alignItems: "center" } }, /* @__PURE__ */ React12.createElement(HelpIcon, { fontSize: "small", color: "action" })));
1111
1108
  }
1112
- function StatusIndicator({ audit: audit26, violations }) {
1109
+ function StatusIndicator({ audit: audit25, violations }) {
1113
1110
  if (violations) {
1114
- return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(SeverityIcon, { severity: audit26.severity }), isScoredAudit(audit26) && /* @__PURE__ */ React12.createElement(Typography6, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length));
1111
+ return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(SeverityIcon, { severity: audit25.severity }), isScoredAudit(audit25) && /* @__PURE__ */ React12.createElement(Typography6, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length));
1115
1112
  }
1116
1113
  return /* @__PURE__ */ React12.createElement(CheckIcon, { fontSize: "small", color: "success" });
1117
1114
  }
@@ -1153,7 +1150,7 @@ function getSharedAngiePrompt(violations) {
1153
1150
  );
1154
1151
  return allShareTheSameFix ? first.angiePrompt : void 0;
1155
1152
  }
1156
- function ViolationRow({ audit: audit26, expanded, onToggleExpand, skipReason, violations }) {
1153
+ function ViolationRow({ audit: audit25, expanded, onToggleExpand, skipReason, violations }) {
1157
1154
  const primaryViolation = violations?.[0];
1158
1155
  const isGuidanceFocusable = !!primaryViolation;
1159
1156
  const panelZIndex = useFloatingPanelZIndex2(AUDIT_PANEL_ID);
@@ -1176,8 +1173,8 @@ function ViolationRow({ audit: audit26, expanded, onToggleExpand, skipReason, vi
1176
1173
  },
1177
1174
  onClick: onToggleExpand
1178
1175
  },
1179
- /* @__PURE__ */ React12.createElement(Typography6, { variant: "subtitle2", color: "text.secondary", sx: { flex: 1 } }, audit26.title),
1180
- !skipReason && /* @__PURE__ */ React12.createElement(StatusIndicator, { audit: audit26, violations })
1176
+ /* @__PURE__ */ React12.createElement(Typography6, { variant: "subtitle2", color: "text.secondary", sx: { flex: 1 } }, audit25.title),
1177
+ !skipReason && /* @__PURE__ */ React12.createElement(StatusIndicator, { audit: audit25, violations })
1181
1178
  ), skipReason && /* @__PURE__ */ React12.createElement(SkipReasonTooltip, { reason: skipReason }), /* @__PURE__ */ React12.createElement(
1182
1179
  IconButton5,
1183
1180
  {
@@ -1195,7 +1192,7 @@ function ViolationRow({ audit: audit26, expanded, onToggleExpand, skipReason, vi
1195
1192
  }
1196
1193
  }
1197
1194
  )
1198
- )), /* @__PURE__ */ React12.createElement(Collapse2, { in: expanded }, /* @__PURE__ */ React12.createElement(Box7, { paddingBlock: 1 }, /* @__PURE__ */ React12.createElement(Tooltip3, { title: audit26.fixHint, placement: "top" }, /* @__PURE__ */ React12.createElement(
1195
+ )), /* @__PURE__ */ React12.createElement(Collapse2, { in: expanded }, /* @__PURE__ */ React12.createElement(Box7, { paddingBlock: 1 }, /* @__PURE__ */ React12.createElement(Tooltip3, { title: audit25.fixHint, placement: "top" }, /* @__PURE__ */ React12.createElement(
1199
1196
  Alert,
1200
1197
  {
1201
1198
  severity: "secondary",
@@ -1206,7 +1203,7 @@ function ViolationRow({ audit: audit26, expanded, onToggleExpand, skipReason, vi
1206
1203
  onClick: isGuidanceFocusable ? handleGuidanceClick : void 0,
1207
1204
  onKeyDown: isGuidanceFocusable ? onKeyboardClick(handleGuidanceClick) : void 0
1208
1205
  },
1209
- /* @__PURE__ */ React12.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit26.description),
1206
+ /* @__PURE__ */ React12.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit25.description),
1210
1207
  primaryViolation && /* @__PURE__ */ React12.createElement(
1211
1208
  GuidanceAction,
1212
1209
  {
@@ -1324,17 +1321,17 @@ import { __ as __12 } from "@wordpress/i18n";
1324
1321
  var ALL_SEVERITIES = ["error", "warning", "info"];
1325
1322
  function countSeverities(report, category) {
1326
1323
  const counts = { error: 0, warning: 0, info: 0 };
1327
- for (const { audit: audit26, result } of report.auditResults) {
1324
+ for (const { audit: audit25, result } of report.auditResults) {
1328
1325
  if (result.status !== "fail") {
1329
1326
  continue;
1330
1327
  }
1331
- if (category && !audit26.categories.includes(category)) {
1328
+ if (category && !audit25.categories.includes(category)) {
1332
1329
  continue;
1333
1330
  }
1334
- if (!isScoredAudit(audit26)) {
1331
+ if (!isScoredAudit(audit25)) {
1335
1332
  continue;
1336
1333
  }
1337
- counts[audit26.severity] += result.violations.length;
1334
+ counts[audit25.severity] += result.violations.length;
1338
1335
  }
1339
1336
  return counts;
1340
1337
  }
@@ -1540,7 +1537,7 @@ function SeverityCard({ severity, count }) {
1540
1537
  flex: 1,
1541
1538
  flexDirection: "column",
1542
1539
  gap: 1,
1543
- bgcolor: "grey.50",
1540
+ bgcolor: "action.hover",
1544
1541
  borderRadius: 1.5,
1545
1542
  px: 1.5,
1546
1543
  py: 1
@@ -2277,6 +2274,21 @@ var audit10 = {
2277
2274
  // src/audits/images-alt-text.ts
2278
2275
  import { __ as __29 } from "@wordpress/i18n";
2279
2276
 
2277
+ // src/utils/alt-text-image-sources.ts
2278
+ function walkAltTextImageSources(tree, visit) {
2279
+ walkImageLikeSources(tree, visit);
2280
+ walkAtomicImageSources(tree, visit, ATOMIC_CONTENT_IMAGE_PROP_KEYS);
2281
+ }
2282
+ function hasAltTextImages(tree) {
2283
+ let found = false;
2284
+ walkAltTextImageSources(tree, ({ media }) => {
2285
+ if (media.id || media.url) {
2286
+ found = true;
2287
+ }
2288
+ });
2289
+ return found;
2290
+ }
2291
+
2280
2292
  // src/utils/image-alt.ts
2281
2293
  function hasMeaningfulAlt(media, pageContext) {
2282
2294
  if (!media.id && !media.url) {
@@ -2303,14 +2315,14 @@ var audit11 = {
2303
2315
  severity: "error",
2304
2316
  weight: 10,
2305
2317
  evaluate: (ctx) => {
2306
- if (!hasPageImages(ctx.elements.tree)) {
2318
+ if (!hasAltTextImages(ctx.elements.tree)) {
2307
2319
  return { status: "skipped", reason: __29("No images", "elementor") };
2308
2320
  }
2309
2321
  const isReady = ctx.pageContext.ally_plugin_active;
2310
2322
  const violations = [];
2311
2323
  const failedWidgetIds = /* @__PURE__ */ new Set();
2312
2324
  let missingAltImageCount = 0;
2313
- walkImageLikeSources(ctx.elements.tree, ({ node, media }) => {
2325
+ walkAltTextImageSources(ctx.elements.tree, ({ node, media }) => {
2314
2326
  if (!isImageSourcePresent(media) || hasMeaningfulAlt(media, ctx.pageContext)) {
2315
2327
  return;
2316
2328
  }
@@ -2362,10 +2374,7 @@ var audit12 = {
2362
2374
  inefficientImageFormatCount++;
2363
2375
  offendingElementIds.add(node.id);
2364
2376
  };
2365
- walkImageLikeSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2366
- walkBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2367
- walkAtomicImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2368
- walkAtomicBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2377
+ walkAllImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2369
2378
  if (!hasAnyImage) {
2370
2379
  return { status: "skipped", reason: __30("No images", "elementor") };
2371
2380
  }
@@ -2415,10 +2424,7 @@ var audit13 = {
2415
2424
  const currentMax = widgetMaxKb.get(node.id) ?? 0;
2416
2425
  widgetMaxKb.set(node.id, Math.max(currentMax, kb));
2417
2426
  };
2418
- walkImageLikeSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2419
- walkBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2420
- walkAtomicImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2421
- walkAtomicBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2427
+ walkAllImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
2422
2428
  if (!hasAnyImage) {
2423
2429
  return { status: "skipped", reason: __31("No images", "elementor") };
2424
2430
  }
@@ -2966,50 +2972,6 @@ var audit24 = {
2966
2972
  }
2967
2973
  };
2968
2974
 
2969
- // src/audits/too-many-widgets.ts
2970
- import { getWidgetsCache as getWidgetsCache3 } from "@elementor/editor-elements";
2971
- import { __ as __43 } from "@wordpress/i18n";
2972
- var WIDGET_COUNT_THRESHOLD = 100;
2973
- function isCountableWidget(node, widgetsCache) {
2974
- if (node.elType === "widget") {
2975
- return true;
2976
- }
2977
- return !!widgetsCache?.[node.elType]?.meta?.is_compound;
2978
- }
2979
- var audit25 = {
2980
- id: "audits/too-many-widgets",
2981
- title: __43("Too many widgets", "elementor"),
2982
- description: __43("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
2983
- fixHint: __43("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
2984
- categories: ["best-practices", "performance"],
2985
- severity: "warning",
2986
- weight: 5,
2987
- evaluate: (ctx) => {
2988
- if (ctx.elements.tree.length === 0) {
2989
- return { status: "skipped", reason: __43("No elements", "elementor") };
2990
- }
2991
- const widgetsCache = getWidgetsCache3();
2992
- let widgetCount = 0;
2993
- walkElements(ctx.elements.tree, (node) => {
2994
- if (isCountableWidget(node, widgetsCache)) {
2995
- widgetCount++;
2996
- }
2997
- });
2998
- if (widgetCount <= WIDGET_COUNT_THRESHOLD) {
2999
- return { status: "pass" };
3000
- }
3001
- return {
3002
- status: "fail",
3003
- violations: [
3004
- {
3005
- auditId: audit25.id,
3006
- label: __43("Page has too many widgets.", "elementor")
3007
- }
3008
- ]
3009
- };
3010
- }
3011
- };
3012
-
3013
2975
  // src/register-audits.ts
3014
2976
  var AUDITS = [
3015
2977
  audit17,
@@ -3017,7 +2979,6 @@ var AUDITS = [
3017
2979
  audit16,
3018
2980
  audit10,
3019
2981
  audit7,
3020
- audit25,
3021
2982
  audit23,
3022
2983
  audit5,
3023
2984
  audit14,
@@ -3039,8 +3000,8 @@ var AUDITS = [
3039
3000
  audit8
3040
3001
  ];
3041
3002
  function registerAllAudits() {
3042
- for (const audit26 of AUDITS) {
3043
- registerAudit(audit26);
3003
+ for (const audit25 of AUDITS) {
3004
+ registerAudit(audit25);
3044
3005
  }
3045
3006
  }
3046
3007