@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.js +60 -99
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +60 -99
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/audits/images-alt-text.ts +3 -3
- package/src/audits/images-inefficient-format.ts +3 -8
- package/src/audits/images-too-large.ts +3 -8
- package/src/components/severity-summary-cards.tsx +1 -1
- package/src/register-audits.ts +0 -2
- package/src/utils/all-image-sources.ts +17 -0
- package/src/utils/alt-text-image-sources.ts +24 -0
- package/src/utils/atomic-image-sources.ts +8 -4
- package/src/utils/image-like-sources.ts +0 -12
- package/src/utils/page-attachments.ts +3 -11
- package/src/audits/too-many-widgets.ts +0 -53
package/dist/index.js
CHANGED
|
@@ -246,16 +246,16 @@ async function requestPageContext(documentId, imageSizeRequests, allowNonceRetry
|
|
|
246
246
|
|
|
247
247
|
// src/registry.ts
|
|
248
248
|
var registry = /* @__PURE__ */ new Map();
|
|
249
|
-
function registerAudit(
|
|
250
|
-
registry.set(
|
|
249
|
+
function registerAudit(audit25) {
|
|
250
|
+
registry.set(audit25.id, audit25);
|
|
251
251
|
}
|
|
252
252
|
function getRegisteredAudits() {
|
|
253
253
|
return Array.from(registry.values());
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
// src/utils/is-scored-audit.ts
|
|
257
|
-
function isScoredAudit(
|
|
258
|
-
return
|
|
257
|
+
function isScoredAudit(audit25) {
|
|
258
|
+
return audit25.weight > 0;
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
// src/utils/sort-failed-audits.ts
|
|
@@ -316,16 +316,16 @@ function computeReport(documentId, results) {
|
|
|
316
316
|
const accumulators = Object.fromEntries(
|
|
317
317
|
ALL_CATEGORIES.map((c) => [c, { totalWeight: 0, passedWeight: 0, total: 0, failed: 0 }])
|
|
318
318
|
);
|
|
319
|
-
for (const { audit:
|
|
319
|
+
for (const { audit: audit25, result } of results) {
|
|
320
320
|
if (result.status === "skipped") {
|
|
321
321
|
continue;
|
|
322
322
|
}
|
|
323
|
-
for (const category of
|
|
323
|
+
for (const category of audit25.categories) {
|
|
324
324
|
const acc = accumulators[category];
|
|
325
325
|
acc.total++;
|
|
326
|
-
acc.totalWeight +=
|
|
326
|
+
acc.totalWeight += audit25.weight;
|
|
327
327
|
if (result.status === "pass") {
|
|
328
|
-
acc.passedWeight +=
|
|
328
|
+
acc.passedWeight += audit25.weight;
|
|
329
329
|
} else {
|
|
330
330
|
acc.failed++;
|
|
331
331
|
}
|
|
@@ -392,13 +392,14 @@ function recurse(nodes, parents, visit) {
|
|
|
392
392
|
}
|
|
393
393
|
|
|
394
394
|
// src/utils/atomic-image-sources.ts
|
|
395
|
-
var
|
|
396
|
-
|
|
395
|
+
var ATOMIC_CONTENT_IMAGE_PROP_KEYS = ["image"];
|
|
396
|
+
var ATOMIC_IMAGE_PROP_KEYS = [...ATOMIC_CONTENT_IMAGE_PROP_KEYS, "poster"];
|
|
397
|
+
function walkAtomicImageSources(tree, visit, propKeys = ATOMIC_IMAGE_PROP_KEYS) {
|
|
397
398
|
walkElements(tree, (node) => {
|
|
398
399
|
if (node.elType !== "widget") {
|
|
399
400
|
return;
|
|
400
401
|
}
|
|
401
|
-
for (const key of
|
|
402
|
+
for (const key of propKeys) {
|
|
402
403
|
const media = extractAtomicImageMedia(node.settings[key]);
|
|
403
404
|
if (media) {
|
|
404
405
|
visit({ node, media });
|
|
@@ -420,8 +421,9 @@ function extractAtomicImageMedia(imageProp) {
|
|
|
420
421
|
if (!id && !url) {
|
|
421
422
|
return null;
|
|
422
423
|
}
|
|
424
|
+
const alt = import_editor_props.stringPropTypeUtil.extract(src.alt) ?? void 0;
|
|
423
425
|
const size = import_editor_props.stringPropTypeUtil.extract(image.size) ?? void 0;
|
|
424
|
-
return { id, url, size };
|
|
426
|
+
return { id, url, alt, size };
|
|
425
427
|
}
|
|
426
428
|
|
|
427
429
|
// src/utils/atomic-background-image-sources.ts
|
|
@@ -476,15 +478,6 @@ function walkBackgroundImageSources(tree, visit) {
|
|
|
476
478
|
|
|
477
479
|
// src/utils/image-like-sources.ts
|
|
478
480
|
var IMAGE_LIKE_WIDGETS = /* @__PURE__ */ new Set(["image", "image-box", "image-carousel", "gallery", "image-gallery"]);
|
|
479
|
-
function hasPageImages(tree) {
|
|
480
|
-
let found = false;
|
|
481
|
-
walkImageLikeSources(tree, ({ media }) => {
|
|
482
|
-
if (media.id || media.url) {
|
|
483
|
-
found = true;
|
|
484
|
-
}
|
|
485
|
-
});
|
|
486
|
-
return found;
|
|
487
|
-
}
|
|
488
481
|
function walkImageLikeSources(tree, visit) {
|
|
489
482
|
walkElements(tree, (node) => {
|
|
490
483
|
if (node.elType !== "widget") {
|
|
@@ -516,6 +509,14 @@ function collectMediaFromNode(node) {
|
|
|
516
509
|
return sources;
|
|
517
510
|
}
|
|
518
511
|
|
|
512
|
+
// src/utils/all-image-sources.ts
|
|
513
|
+
function walkAllImageSources(tree, visit) {
|
|
514
|
+
walkImageLikeSources(tree, visit);
|
|
515
|
+
walkBackgroundImageSources(tree, visit);
|
|
516
|
+
walkAtomicImageSources(tree, visit);
|
|
517
|
+
walkAtomicBackgroundImageSources(tree, visit);
|
|
518
|
+
}
|
|
519
|
+
|
|
519
520
|
// src/utils/image-size-key.ts
|
|
520
521
|
function buildImageSizeKey({ id, size }) {
|
|
521
522
|
return `${id}:${size || "full"}`;
|
|
@@ -524,15 +525,11 @@ function buildImageSizeKey({ id, size }) {
|
|
|
524
525
|
// src/utils/page-attachments.ts
|
|
525
526
|
function extractImageSizeRequests(tree) {
|
|
526
527
|
const keys = /* @__PURE__ */ new Set();
|
|
527
|
-
|
|
528
|
+
walkAllImageSources(tree, ({ media }) => {
|
|
528
529
|
if (media.id) {
|
|
529
530
|
keys.add(buildImageSizeKey({ id: media.id, size: media.size }));
|
|
530
531
|
}
|
|
531
|
-
};
|
|
532
|
-
walkImageLikeSources(tree, ({ media }) => collect(media));
|
|
533
|
-
walkBackgroundImageSources(tree, ({ media }) => collect(media));
|
|
534
|
-
walkAtomicImageSources(tree, ({ media }) => collect(media));
|
|
535
|
-
walkAtomicBackgroundImageSources(tree, ({ media }) => collect(media));
|
|
532
|
+
});
|
|
536
533
|
return Array.from(keys).sort();
|
|
537
534
|
}
|
|
538
535
|
|
|
@@ -641,10 +638,10 @@ async function runPageAudit(documentId) {
|
|
|
641
638
|
const ctx = { documentId, elements, pageContext, kit, renderedHtml };
|
|
642
639
|
const registered = getRegisteredAudits();
|
|
643
640
|
const auditResults = await Promise.all(
|
|
644
|
-
registered.map(async (
|
|
645
|
-
const { evaluate: _evaluate, ...meta } =
|
|
641
|
+
registered.map(async (audit25) => {
|
|
642
|
+
const { evaluate: _evaluate, ...meta } = audit25;
|
|
646
643
|
try {
|
|
647
|
-
const result = await
|
|
644
|
+
const result = await audit25.evaluate(ctx);
|
|
648
645
|
return { audit: meta, result };
|
|
649
646
|
} catch (error) {
|
|
650
647
|
const reason = error instanceof Error ? error.message : "unknown-error";
|
|
@@ -1125,9 +1122,9 @@ function ViolationIcon({ violation, widgetIcon }) {
|
|
|
1125
1122
|
function SkipReasonTooltip({ reason }) {
|
|
1126
1123
|
return /* @__PURE__ */ React12.createElement(import_ui11.Tooltip, { title: reason, placement: "top" }, /* @__PURE__ */ React12.createElement(import_ui11.Box, { "aria-label": reason, component: "span", sx: { display: "inline-flex", alignItems: "center" } }, /* @__PURE__ */ React12.createElement(import_icons10.HelpIcon, { fontSize: "small", color: "action" })));
|
|
1127
1124
|
}
|
|
1128
|
-
function StatusIndicator({ audit:
|
|
1125
|
+
function StatusIndicator({ audit: audit25, violations }) {
|
|
1129
1126
|
if (violations) {
|
|
1130
|
-
return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(SeverityIcon, { severity:
|
|
1127
|
+
return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(SeverityIcon, { severity: audit25.severity }), isScoredAudit(audit25) && /* @__PURE__ */ React12.createElement(import_ui11.Typography, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length));
|
|
1131
1128
|
}
|
|
1132
1129
|
return /* @__PURE__ */ React12.createElement(import_icons10.CheckIcon, { fontSize: "small", color: "success" });
|
|
1133
1130
|
}
|
|
@@ -1169,7 +1166,7 @@ function getSharedAngiePrompt(violations) {
|
|
|
1169
1166
|
);
|
|
1170
1167
|
return allShareTheSameFix ? first.angiePrompt : void 0;
|
|
1171
1168
|
}
|
|
1172
|
-
function ViolationRow({ audit:
|
|
1169
|
+
function ViolationRow({ audit: audit25, expanded, onToggleExpand, skipReason, violations }) {
|
|
1173
1170
|
const primaryViolation = violations?.[0];
|
|
1174
1171
|
const isGuidanceFocusable = !!primaryViolation;
|
|
1175
1172
|
const panelZIndex = (0, import_editor_floating_panels2.useFloatingPanelZIndex)(AUDIT_PANEL_ID);
|
|
@@ -1192,8 +1189,8 @@ function ViolationRow({ audit: audit26, expanded, onToggleExpand, skipReason, vi
|
|
|
1192
1189
|
},
|
|
1193
1190
|
onClick: onToggleExpand
|
|
1194
1191
|
},
|
|
1195
|
-
/* @__PURE__ */ React12.createElement(import_ui11.Typography, { variant: "subtitle2", color: "text.secondary", sx: { flex: 1 } },
|
|
1196
|
-
!skipReason && /* @__PURE__ */ React12.createElement(StatusIndicator, { audit:
|
|
1192
|
+
/* @__PURE__ */ React12.createElement(import_ui11.Typography, { variant: "subtitle2", color: "text.secondary", sx: { flex: 1 } }, audit25.title),
|
|
1193
|
+
!skipReason && /* @__PURE__ */ React12.createElement(StatusIndicator, { audit: audit25, violations })
|
|
1197
1194
|
), skipReason && /* @__PURE__ */ React12.createElement(SkipReasonTooltip, { reason: skipReason }), /* @__PURE__ */ React12.createElement(
|
|
1198
1195
|
import_ui11.IconButton,
|
|
1199
1196
|
{
|
|
@@ -1211,7 +1208,7 @@ function ViolationRow({ audit: audit26, expanded, onToggleExpand, skipReason, vi
|
|
|
1211
1208
|
}
|
|
1212
1209
|
}
|
|
1213
1210
|
)
|
|
1214
|
-
)), /* @__PURE__ */ React12.createElement(import_ui11.Collapse, { in: expanded }, /* @__PURE__ */ React12.createElement(import_ui11.Box, { paddingBlock: 1 }, /* @__PURE__ */ React12.createElement(import_ui11.Tooltip, { title:
|
|
1211
|
+
)), /* @__PURE__ */ React12.createElement(import_ui11.Collapse, { in: expanded }, /* @__PURE__ */ React12.createElement(import_ui11.Box, { paddingBlock: 1 }, /* @__PURE__ */ React12.createElement(import_ui11.Tooltip, { title: audit25.fixHint, placement: "top" }, /* @__PURE__ */ React12.createElement(
|
|
1215
1212
|
import_ui11.Alert,
|
|
1216
1213
|
{
|
|
1217
1214
|
severity: "secondary",
|
|
@@ -1222,7 +1219,7 @@ function ViolationRow({ audit: audit26, expanded, onToggleExpand, skipReason, vi
|
|
|
1222
1219
|
onClick: isGuidanceFocusable ? handleGuidanceClick : void 0,
|
|
1223
1220
|
onKeyDown: isGuidanceFocusable ? onKeyboardClick(handleGuidanceClick) : void 0
|
|
1224
1221
|
},
|
|
1225
|
-
/* @__PURE__ */ React12.createElement(import_ui11.Typography, { variant: "caption", component: "p", color: "text.secondary" },
|
|
1222
|
+
/* @__PURE__ */ React12.createElement(import_ui11.Typography, { variant: "caption", component: "p", color: "text.secondary" }, audit25.description),
|
|
1226
1223
|
primaryViolation && /* @__PURE__ */ React12.createElement(
|
|
1227
1224
|
GuidanceAction,
|
|
1228
1225
|
{
|
|
@@ -1340,17 +1337,17 @@ var import_i18n12 = require("@wordpress/i18n");
|
|
|
1340
1337
|
var ALL_SEVERITIES = ["error", "warning", "info"];
|
|
1341
1338
|
function countSeverities(report, category) {
|
|
1342
1339
|
const counts = { error: 0, warning: 0, info: 0 };
|
|
1343
|
-
for (const { audit:
|
|
1340
|
+
for (const { audit: audit25, result } of report.auditResults) {
|
|
1344
1341
|
if (result.status !== "fail") {
|
|
1345
1342
|
continue;
|
|
1346
1343
|
}
|
|
1347
|
-
if (category && !
|
|
1344
|
+
if (category && !audit25.categories.includes(category)) {
|
|
1348
1345
|
continue;
|
|
1349
1346
|
}
|
|
1350
|
-
if (!isScoredAudit(
|
|
1347
|
+
if (!isScoredAudit(audit25)) {
|
|
1351
1348
|
continue;
|
|
1352
1349
|
}
|
|
1353
|
-
counts[
|
|
1350
|
+
counts[audit25.severity] += result.violations.length;
|
|
1354
1351
|
}
|
|
1355
1352
|
return counts;
|
|
1356
1353
|
}
|
|
@@ -1556,7 +1553,7 @@ function SeverityCard({ severity, count }) {
|
|
|
1556
1553
|
flex: 1,
|
|
1557
1554
|
flexDirection: "column",
|
|
1558
1555
|
gap: 1,
|
|
1559
|
-
bgcolor: "
|
|
1556
|
+
bgcolor: "action.hover",
|
|
1560
1557
|
borderRadius: 1.5,
|
|
1561
1558
|
px: 1.5,
|
|
1562
1559
|
py: 1
|
|
@@ -2293,6 +2290,21 @@ var audit10 = {
|
|
|
2293
2290
|
// src/audits/images-alt-text.ts
|
|
2294
2291
|
var import_i18n29 = require("@wordpress/i18n");
|
|
2295
2292
|
|
|
2293
|
+
// src/utils/alt-text-image-sources.ts
|
|
2294
|
+
function walkAltTextImageSources(tree, visit) {
|
|
2295
|
+
walkImageLikeSources(tree, visit);
|
|
2296
|
+
walkAtomicImageSources(tree, visit, ATOMIC_CONTENT_IMAGE_PROP_KEYS);
|
|
2297
|
+
}
|
|
2298
|
+
function hasAltTextImages(tree) {
|
|
2299
|
+
let found = false;
|
|
2300
|
+
walkAltTextImageSources(tree, ({ media }) => {
|
|
2301
|
+
if (media.id || media.url) {
|
|
2302
|
+
found = true;
|
|
2303
|
+
}
|
|
2304
|
+
});
|
|
2305
|
+
return found;
|
|
2306
|
+
}
|
|
2307
|
+
|
|
2296
2308
|
// src/utils/image-alt.ts
|
|
2297
2309
|
function hasMeaningfulAlt(media, pageContext) {
|
|
2298
2310
|
if (!media.id && !media.url) {
|
|
@@ -2319,14 +2331,14 @@ var audit11 = {
|
|
|
2319
2331
|
severity: "error",
|
|
2320
2332
|
weight: 10,
|
|
2321
2333
|
evaluate: (ctx) => {
|
|
2322
|
-
if (!
|
|
2334
|
+
if (!hasAltTextImages(ctx.elements.tree)) {
|
|
2323
2335
|
return { status: "skipped", reason: (0, import_i18n29.__)("No images", "elementor") };
|
|
2324
2336
|
}
|
|
2325
2337
|
const isReady = ctx.pageContext.ally_plugin_active;
|
|
2326
2338
|
const violations = [];
|
|
2327
2339
|
const failedWidgetIds = /* @__PURE__ */ new Set();
|
|
2328
2340
|
let missingAltImageCount = 0;
|
|
2329
|
-
|
|
2341
|
+
walkAltTextImageSources(ctx.elements.tree, ({ node, media }) => {
|
|
2330
2342
|
if (!isImageSourcePresent(media) || hasMeaningfulAlt(media, ctx.pageContext)) {
|
|
2331
2343
|
return;
|
|
2332
2344
|
}
|
|
@@ -2378,10 +2390,7 @@ var audit12 = {
|
|
|
2378
2390
|
inefficientImageFormatCount++;
|
|
2379
2391
|
offendingElementIds.add(node.id);
|
|
2380
2392
|
};
|
|
2381
|
-
|
|
2382
|
-
walkBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2383
|
-
walkAtomicImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2384
|
-
walkAtomicBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2393
|
+
walkAllImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2385
2394
|
if (!hasAnyImage) {
|
|
2386
2395
|
return { status: "skipped", reason: (0, import_i18n30.__)("No images", "elementor") };
|
|
2387
2396
|
}
|
|
@@ -2431,10 +2440,7 @@ var audit13 = {
|
|
|
2431
2440
|
const currentMax = widgetMaxKb.get(node.id) ?? 0;
|
|
2432
2441
|
widgetMaxKb.set(node.id, Math.max(currentMax, kb));
|
|
2433
2442
|
};
|
|
2434
|
-
|
|
2435
|
-
walkBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2436
|
-
walkAtomicImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2437
|
-
walkAtomicBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2443
|
+
walkAllImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2438
2444
|
if (!hasAnyImage) {
|
|
2439
2445
|
return { status: "skipped", reason: (0, import_i18n31.__)("No images", "elementor") };
|
|
2440
2446
|
}
|
|
@@ -2982,50 +2988,6 @@ var audit24 = {
|
|
|
2982
2988
|
}
|
|
2983
2989
|
};
|
|
2984
2990
|
|
|
2985
|
-
// src/audits/too-many-widgets.ts
|
|
2986
|
-
var import_editor_elements9 = require("@elementor/editor-elements");
|
|
2987
|
-
var import_i18n43 = require("@wordpress/i18n");
|
|
2988
|
-
var WIDGET_COUNT_THRESHOLD = 100;
|
|
2989
|
-
function isCountableWidget(node, widgetsCache) {
|
|
2990
|
-
if (node.elType === "widget") {
|
|
2991
|
-
return true;
|
|
2992
|
-
}
|
|
2993
|
-
return !!widgetsCache?.[node.elType]?.meta?.is_compound;
|
|
2994
|
-
}
|
|
2995
|
-
var audit25 = {
|
|
2996
|
-
id: "audits/too-many-widgets",
|
|
2997
|
-
title: (0, import_i18n43.__)("Too many widgets", "elementor"),
|
|
2998
|
-
description: (0, import_i18n43.__)("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
|
|
2999
|
-
fixHint: (0, import_i18n43.__)("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
|
|
3000
|
-
categories: ["best-practices", "performance"],
|
|
3001
|
-
severity: "warning",
|
|
3002
|
-
weight: 5,
|
|
3003
|
-
evaluate: (ctx) => {
|
|
3004
|
-
if (ctx.elements.tree.length === 0) {
|
|
3005
|
-
return { status: "skipped", reason: (0, import_i18n43.__)("No elements", "elementor") };
|
|
3006
|
-
}
|
|
3007
|
-
const widgetsCache = (0, import_editor_elements9.getWidgetsCache)();
|
|
3008
|
-
let widgetCount = 0;
|
|
3009
|
-
walkElements(ctx.elements.tree, (node) => {
|
|
3010
|
-
if (isCountableWidget(node, widgetsCache)) {
|
|
3011
|
-
widgetCount++;
|
|
3012
|
-
}
|
|
3013
|
-
});
|
|
3014
|
-
if (widgetCount <= WIDGET_COUNT_THRESHOLD) {
|
|
3015
|
-
return { status: "pass" };
|
|
3016
|
-
}
|
|
3017
|
-
return {
|
|
3018
|
-
status: "fail",
|
|
3019
|
-
violations: [
|
|
3020
|
-
{
|
|
3021
|
-
auditId: audit25.id,
|
|
3022
|
-
label: (0, import_i18n43.__)("Page has too many widgets.", "elementor")
|
|
3023
|
-
}
|
|
3024
|
-
]
|
|
3025
|
-
};
|
|
3026
|
-
}
|
|
3027
|
-
};
|
|
3028
|
-
|
|
3029
2991
|
// src/register-audits.ts
|
|
3030
2992
|
var AUDITS = [
|
|
3031
2993
|
audit17,
|
|
@@ -3033,7 +2995,6 @@ var AUDITS = [
|
|
|
3033
2995
|
audit16,
|
|
3034
2996
|
audit10,
|
|
3035
2997
|
audit7,
|
|
3036
|
-
audit25,
|
|
3037
2998
|
audit23,
|
|
3038
2999
|
audit5,
|
|
3039
3000
|
audit14,
|
|
@@ -3055,8 +3016,8 @@ var AUDITS = [
|
|
|
3055
3016
|
audit8
|
|
3056
3017
|
];
|
|
3057
3018
|
function registerAllAudits() {
|
|
3058
|
-
for (const
|
|
3059
|
-
registerAudit(
|
|
3019
|
+
for (const audit25 of AUDITS) {
|
|
3020
|
+
registerAudit(audit25);
|
|
3060
3021
|
}
|
|
3061
3022
|
}
|
|
3062
3023
|
|