@elementor/editor-audits 4.4.0-1105 → 4.4.0-1107
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 +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +491 -294
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +480 -273
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -13
- package/src/api/page-context-client.ts +8 -5
- package/src/audits/accessibility-statement.ts +39 -0
- package/src/audits/accessibility-widget.ts +41 -0
- package/src/audits/google-consent-mode.ts +4 -7
- package/src/audits/images-too-large.ts +23 -9
- package/src/components/violation-cta-button.tsx +3 -2
- package/src/components/violation-row.tsx +13 -4
- package/src/register-audits.ts +4 -0
- package/src/runner.ts +9 -5
- package/src/types.ts +8 -1
- package/src/utils/atomic-background-image-sources.ts +56 -0
- package/src/utils/atomic-image-sources.ts +62 -0
- package/src/utils/background-image-sources.ts +32 -0
- package/src/utils/image-alt.ts +3 -1
- package/src/utils/image-like-sources.ts +5 -2
- package/src/utils/image-size-key.ts +8 -0
- package/src/utils/page-attachments.ts +16 -7
- package/src/utils/scan-accessibility-widgets.ts +7 -0
package/dist/index.mjs
CHANGED
|
@@ -77,17 +77,17 @@ async function requestFreshNonce() {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// src/api/page-context-client.ts
|
|
80
|
-
async function fetchPageContext(documentId,
|
|
81
|
-
return requestPageContext(documentId,
|
|
80
|
+
async function fetchPageContext(documentId, imageSizeRequests) {
|
|
81
|
+
return requestPageContext(documentId, imageSizeRequests, true);
|
|
82
82
|
}
|
|
83
|
-
async function requestPageContext(documentId,
|
|
83
|
+
async function requestPageContext(documentId, imageSizeRequests, allowNonceRetry) {
|
|
84
84
|
const { restNamespace, nonce } = getWindowConfig();
|
|
85
85
|
const url = `${restNamespace}/audits/page-context`;
|
|
86
86
|
try {
|
|
87
87
|
const response = await httpService().get(url, {
|
|
88
88
|
params: {
|
|
89
89
|
document_id: documentId,
|
|
90
|
-
|
|
90
|
+
image_size_requests: imageSizeRequests
|
|
91
91
|
},
|
|
92
92
|
headers: { "X-WP-Nonce": nonce }
|
|
93
93
|
});
|
|
@@ -97,14 +97,14 @@ async function requestPageContext(documentId, attachmentIds, allowNonceRetry) {
|
|
|
97
97
|
throw error;
|
|
98
98
|
}
|
|
99
99
|
await refreshAuditsNonce();
|
|
100
|
-
return requestPageContext(documentId,
|
|
100
|
+
return requestPageContext(documentId, imageSizeRequests, false);
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
// src/registry.ts
|
|
105
105
|
var registry = /* @__PURE__ */ new Map();
|
|
106
|
-
function registerAudit(
|
|
107
|
-
registry.set(
|
|
106
|
+
function registerAudit(audit25) {
|
|
107
|
+
registry.set(audit25.id, audit25);
|
|
108
108
|
}
|
|
109
109
|
function getRegisteredAudits() {
|
|
110
110
|
return Array.from(registry.values());
|
|
@@ -141,8 +141,8 @@ var CATEGORY_LABELS = {
|
|
|
141
141
|
import { __ as __2 } from "@wordpress/i18n";
|
|
142
142
|
|
|
143
143
|
// src/utils/is-scored-audit.ts
|
|
144
|
-
function isScoredAudit(
|
|
145
|
-
return
|
|
144
|
+
function isScoredAudit(audit25) {
|
|
145
|
+
return audit25.weight > 0;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
// src/utils/sort-failed-audits.ts
|
|
@@ -198,8 +198,8 @@ function auditStatusDisplayCounts(report) {
|
|
|
198
198
|
let pass = 0;
|
|
199
199
|
let skipped = 0;
|
|
200
200
|
let totalViolations = 0;
|
|
201
|
-
for (const { audit:
|
|
202
|
-
if (!isScoredAudit(
|
|
201
|
+
for (const { audit: audit25, result } of report.auditResults) {
|
|
202
|
+
if (!isScoredAudit(audit25)) {
|
|
203
203
|
continue;
|
|
204
204
|
}
|
|
205
205
|
switch (result.status) {
|
|
@@ -249,16 +249,16 @@ function computeReport(documentId, results) {
|
|
|
249
249
|
const accumulators = Object.fromEntries(
|
|
250
250
|
ALL_CATEGORIES.map((c) => [c, { totalWeight: 0, passedWeight: 0, total: 0, failed: 0 }])
|
|
251
251
|
);
|
|
252
|
-
for (const { audit:
|
|
252
|
+
for (const { audit: audit25, result } of results) {
|
|
253
253
|
if (result.status === "skipped") {
|
|
254
254
|
continue;
|
|
255
255
|
}
|
|
256
|
-
for (const category of
|
|
256
|
+
for (const category of audit25.categories) {
|
|
257
257
|
const acc = accumulators[category];
|
|
258
258
|
acc.total++;
|
|
259
|
-
acc.totalWeight +=
|
|
259
|
+
acc.totalWeight += audit25.weight;
|
|
260
260
|
if (result.status === "pass") {
|
|
261
|
-
acc.passedWeight +=
|
|
261
|
+
acc.passedWeight += audit25.weight;
|
|
262
262
|
} else {
|
|
263
263
|
acc.failed++;
|
|
264
264
|
}
|
|
@@ -282,6 +282,44 @@ function computeReport(documentId, results) {
|
|
|
282
282
|
};
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
+
// src/utils/fetch-rendered-html.ts
|
|
286
|
+
var FETCH_TIMEOUT_MS = 1e4;
|
|
287
|
+
async function fetchRenderedHtml(url) {
|
|
288
|
+
if (!url) {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
const timeoutController = new AbortController();
|
|
292
|
+
const timeoutId = setTimeout(() => timeoutController.abort(), FETCH_TIMEOUT_MS);
|
|
293
|
+
try {
|
|
294
|
+
const response = await fetch(url, { credentials: "omit", signal: timeoutController.signal });
|
|
295
|
+
if (!response.ok) {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
return await response.text();
|
|
299
|
+
} catch {
|
|
300
|
+
return null;
|
|
301
|
+
} finally {
|
|
302
|
+
clearTimeout(timeoutId);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// src/utils/atomic-background-image-sources.ts
|
|
307
|
+
import { getElementStyles } from "@elementor/editor-elements";
|
|
308
|
+
import {
|
|
309
|
+
backgroundImageOverlayPropTypeUtil,
|
|
310
|
+
backgroundOverlayPropTypeUtil,
|
|
311
|
+
backgroundPropTypeUtil
|
|
312
|
+
} from "@elementor/editor-props";
|
|
313
|
+
|
|
314
|
+
// src/utils/atomic-image-sources.ts
|
|
315
|
+
import {
|
|
316
|
+
imageAttachmentIdPropType,
|
|
317
|
+
imagePropTypeUtil,
|
|
318
|
+
imageSrcPropTypeUtil,
|
|
319
|
+
stringPropTypeUtil,
|
|
320
|
+
urlPropTypeUtil
|
|
321
|
+
} from "@elementor/editor-props";
|
|
322
|
+
|
|
285
323
|
// src/utils/walk.ts
|
|
286
324
|
function walkElements(tree, visit) {
|
|
287
325
|
const parents = [];
|
|
@@ -296,6 +334,89 @@ function recurse(nodes, parents, visit) {
|
|
|
296
334
|
}
|
|
297
335
|
}
|
|
298
336
|
|
|
337
|
+
// src/utils/atomic-image-sources.ts
|
|
338
|
+
var ATOMIC_IMAGE_PROP_KEYS = ["image", "poster"];
|
|
339
|
+
function walkAtomicImageSources(tree, visit) {
|
|
340
|
+
walkElements(tree, (node) => {
|
|
341
|
+
if (node.elType !== "widget") {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
for (const key of ATOMIC_IMAGE_PROP_KEYS) {
|
|
345
|
+
const media = extractAtomicImageMedia(node.settings[key]);
|
|
346
|
+
if (media) {
|
|
347
|
+
visit({ node, media });
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
function extractAtomicImageMedia(imageProp) {
|
|
353
|
+
const image = imagePropTypeUtil.extract(imageProp);
|
|
354
|
+
if (!image) {
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
const src = imageSrcPropTypeUtil.extract(image.src);
|
|
358
|
+
if (!src) {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
const id = imageAttachmentIdPropType.extract(src.id) ?? void 0;
|
|
362
|
+
const url = urlPropTypeUtil.extract(src.url) ?? void 0;
|
|
363
|
+
if (!id && !url) {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
const size = stringPropTypeUtil.extract(image.size) ?? void 0;
|
|
367
|
+
return { id, url, size };
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// src/utils/atomic-background-image-sources.ts
|
|
371
|
+
function walkAtomicBackgroundImageSources(tree, visit) {
|
|
372
|
+
walkElements(tree, (node) => {
|
|
373
|
+
const styles = getElementStyles(node.id);
|
|
374
|
+
if (!styles) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
for (const media of extractBackgroundImageMedia(styles)) {
|
|
378
|
+
visit({ node, media });
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
function extractBackgroundImageMedia(styles) {
|
|
383
|
+
const sources = [];
|
|
384
|
+
for (const style of Object.values(styles)) {
|
|
385
|
+
for (const variant of style.variants) {
|
|
386
|
+
const background = backgroundPropTypeUtil.extract(variant.props.background);
|
|
387
|
+
const overlays = backgroundOverlayPropTypeUtil.extract(background?.["background-overlay"]) ?? [];
|
|
388
|
+
for (const overlay of overlays) {
|
|
389
|
+
const imageOverlay = backgroundImageOverlayPropTypeUtil.extract(overlay);
|
|
390
|
+
const media = extractAtomicImageMedia(imageOverlay?.image);
|
|
391
|
+
if (media) {
|
|
392
|
+
sources.push(media);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return sources;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// src/utils/background-image-sources.ts
|
|
401
|
+
var BACKGROUND_IMAGE_SETTING_KEYS = [
|
|
402
|
+
"background_image",
|
|
403
|
+
"background_hover_image",
|
|
404
|
+
"background_overlay_image",
|
|
405
|
+
"background_overlay_hover_image",
|
|
406
|
+
"_background_image",
|
|
407
|
+
"_background_hover_image"
|
|
408
|
+
];
|
|
409
|
+
function walkBackgroundImageSources(tree, visit) {
|
|
410
|
+
walkElements(tree, (node) => {
|
|
411
|
+
for (const key of BACKGROUND_IMAGE_SETTING_KEYS) {
|
|
412
|
+
const media = node.settings[key];
|
|
413
|
+
if (media?.id || media?.url) {
|
|
414
|
+
visit({ node, media });
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
|
|
299
420
|
// src/utils/image-like-sources.ts
|
|
300
421
|
var IMAGE_LIKE_WIDGETS = /* @__PURE__ */ new Set(["image", "image-box", "image-carousel", "gallery", "image-gallery"]);
|
|
301
422
|
function hasPageImages(tree) {
|
|
@@ -324,28 +445,38 @@ function collectMediaFromNode(node) {
|
|
|
324
445
|
const sources = [];
|
|
325
446
|
const image = node.settings.image;
|
|
326
447
|
if (image?.id || image?.url) {
|
|
327
|
-
sources.push(image);
|
|
448
|
+
sources.push({ ...image, size: node.settings.image_size });
|
|
328
449
|
}
|
|
329
450
|
const gallery = node.settings.carousel ?? node.settings.gallery ?? node.settings.wp_gallery;
|
|
330
451
|
if (Array.isArray(gallery)) {
|
|
452
|
+
const gallerySize = node.settings.thumbnail_size;
|
|
331
453
|
for (const item of gallery) {
|
|
332
454
|
if (item?.id || item?.url) {
|
|
333
|
-
sources.push(item);
|
|
455
|
+
sources.push({ ...item, size: gallerySize });
|
|
334
456
|
}
|
|
335
457
|
}
|
|
336
458
|
}
|
|
337
459
|
return sources;
|
|
338
460
|
}
|
|
339
461
|
|
|
462
|
+
// src/utils/image-size-key.ts
|
|
463
|
+
function buildImageSizeKey({ id, size }) {
|
|
464
|
+
return `${id}:${size || "full"}`;
|
|
465
|
+
}
|
|
466
|
+
|
|
340
467
|
// src/utils/page-attachments.ts
|
|
341
|
-
function
|
|
342
|
-
const
|
|
343
|
-
|
|
468
|
+
function extractImageSizeRequests(tree) {
|
|
469
|
+
const keys = /* @__PURE__ */ new Set();
|
|
470
|
+
const collect = (media) => {
|
|
344
471
|
if (media.id) {
|
|
345
|
-
|
|
472
|
+
keys.add(buildImageSizeKey({ id: media.id, size: media.size }));
|
|
346
473
|
}
|
|
347
|
-
}
|
|
348
|
-
|
|
474
|
+
};
|
|
475
|
+
walkImageLikeSources(tree, ({ media }) => collect(media));
|
|
476
|
+
walkBackgroundImageSources(tree, ({ media }) => collect(media));
|
|
477
|
+
walkAtomicImageSources(tree, ({ media }) => collect(media));
|
|
478
|
+
walkAtomicBackgroundImageSources(tree, ({ media }) => collect(media));
|
|
479
|
+
return Array.from(keys).sort();
|
|
349
480
|
}
|
|
350
481
|
|
|
351
482
|
// src/utils/read-kit-snapshot.ts
|
|
@@ -440,17 +571,20 @@ function toSnapshot(element) {
|
|
|
440
571
|
// src/runner.ts
|
|
441
572
|
async function runPageAudit(documentId) {
|
|
442
573
|
const tree = buildSnapshotTree(getElements());
|
|
443
|
-
const
|
|
444
|
-
const pageContext = await fetchPageContext(documentId,
|
|
574
|
+
const imageSizeRequests = extractImageSizeRequests(tree);
|
|
575
|
+
const pageContext = await fetchPageContext(documentId, imageSizeRequests);
|
|
445
576
|
const elements = { documentId, tree };
|
|
446
|
-
const kit = await
|
|
447
|
-
|
|
577
|
+
const [kit, renderedHtml] = await Promise.all([
|
|
578
|
+
readKitSnapshot(pageContext.kit_id),
|
|
579
|
+
fetchRenderedHtml(pageContext.frontend_url)
|
|
580
|
+
]);
|
|
581
|
+
const ctx = { documentId, elements, pageContext, kit, renderedHtml };
|
|
448
582
|
const registered = getRegisteredAudits();
|
|
449
583
|
const auditResults = await Promise.all(
|
|
450
|
-
registered.map(async (
|
|
451
|
-
const { evaluate: _evaluate, ...meta } =
|
|
584
|
+
registered.map(async (audit25) => {
|
|
585
|
+
const { evaluate: _evaluate, ...meta } = audit25;
|
|
452
586
|
try {
|
|
453
|
-
const result = await
|
|
587
|
+
const result = await audit25.evaluate(ctx);
|
|
454
588
|
return { audit: meta, result };
|
|
455
589
|
} catch (error) {
|
|
456
590
|
const reason = error instanceof Error ? error.message : "unknown-error";
|
|
@@ -912,13 +1046,13 @@ function SeverityIcon({ severity }) {
|
|
|
912
1046
|
// src/components/violation-cta-button.tsx
|
|
913
1047
|
import * as React9 from "react";
|
|
914
1048
|
import { Button as Button3 } from "@elementor/ui";
|
|
915
|
-
function ViolationCtaButton({ ctaLabel, externalUrl }) {
|
|
1049
|
+
function ViolationCtaButton({ ctaLabel, externalUrl, variant = "outlined" }) {
|
|
916
1050
|
const handleClick = (event) => {
|
|
917
1051
|
event.stopPropagation();
|
|
918
1052
|
event.preventDefault();
|
|
919
1053
|
window.open(externalUrl, "_blank", "noopener");
|
|
920
1054
|
};
|
|
921
|
-
return /* @__PURE__ */ React9.createElement(Button3, { variant
|
|
1055
|
+
return /* @__PURE__ */ React9.createElement(Button3, { variant, color: "secondary", size: "small", onClick: handleClick }, ctaLabel);
|
|
922
1056
|
}
|
|
923
1057
|
|
|
924
1058
|
// src/components/violation-icons.tsx
|
|
@@ -950,13 +1084,13 @@ function ViolationIcon({ violation, widgetIcon }) {
|
|
|
950
1084
|
function SkipReasonTooltip({ reason }) {
|
|
951
1085
|
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" })));
|
|
952
1086
|
}
|
|
953
|
-
function StatusIndicator({ audit:
|
|
1087
|
+
function StatusIndicator({ audit: audit25, violations }) {
|
|
954
1088
|
if (violations) {
|
|
955
|
-
return /* @__PURE__ */ React11.createElement(React11.Fragment, null, isScoredAudit(
|
|
1089
|
+
return /* @__PURE__ */ React11.createElement(React11.Fragment, null, isScoredAudit(audit25) && /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length), /* @__PURE__ */ React11.createElement(SeverityIcon, { severity: audit25.severity }));
|
|
956
1090
|
}
|
|
957
1091
|
return /* @__PURE__ */ React11.createElement(CheckIcon, { fontSize: "small", color: "success" });
|
|
958
1092
|
}
|
|
959
|
-
function ViolationRow({ audit:
|
|
1093
|
+
function ViolationRow({ audit: audit25, skipReason, violations }) {
|
|
960
1094
|
const [expanded, setExpanded] = useState3(false);
|
|
961
1095
|
const toggleExpanded = () => setExpanded((value) => !value);
|
|
962
1096
|
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(
|
|
@@ -972,8 +1106,8 @@ function ViolationRow({ audit: audit23, skipReason, violations }) {
|
|
|
972
1106
|
},
|
|
973
1107
|
onClick: toggleExpanded
|
|
974
1108
|
},
|
|
975
|
-
/* @__PURE__ */ React11.createElement(Typography6, { variant: "body2", sx: { flex: 1 } },
|
|
976
|
-
!skipReason && /* @__PURE__ */ React11.createElement(StatusIndicator, { audit:
|
|
1109
|
+
/* @__PURE__ */ React11.createElement(Typography6, { variant: "body2", sx: { flex: 1 } }, audit25.title),
|
|
1110
|
+
!skipReason && /* @__PURE__ */ React11.createElement(StatusIndicator, { audit: audit25, violations })
|
|
977
1111
|
), skipReason && /* @__PURE__ */ React11.createElement(SkipReasonTooltip, { reason: skipReason }), /* @__PURE__ */ React11.createElement(
|
|
978
1112
|
IconButton5,
|
|
979
1113
|
{
|
|
@@ -999,7 +1133,7 @@ function ViolationRow({ audit: audit23, skipReason, violations }) {
|
|
|
999
1133
|
icon: /* @__PURE__ */ React11.createElement(AlertCircleIcon2, { fontSize: "small", color: "secondary", "aria-hidden": true })
|
|
1000
1134
|
},
|
|
1001
1135
|
/* @__PURE__ */ React11.createElement(AlertTitle, null, /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.primary", fontWeight: "bold" }, __11("What's the issue", "elementor"))),
|
|
1002
|
-
/* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" },
|
|
1136
|
+
/* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit25.description)
|
|
1003
1137
|
), /* @__PURE__ */ React11.createElement(
|
|
1004
1138
|
Alert,
|
|
1005
1139
|
{
|
|
@@ -1008,7 +1142,7 @@ function ViolationRow({ audit: audit23, skipReason, violations }) {
|
|
|
1008
1142
|
icon: /* @__PURE__ */ React11.createElement(BulbIcon2, { fontSize: "small", color: "info", "aria-hidden": true })
|
|
1009
1143
|
},
|
|
1010
1144
|
/* @__PURE__ */ React11.createElement(AlertTitle, null, /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.primary", fontWeight: "bold" }, __11("How to resolve", "elementor"))),
|
|
1011
|
-
/* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" },
|
|
1145
|
+
/* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit25.fixHint)
|
|
1012
1146
|
)), violations && violations.length > 0 && /* @__PURE__ */ React11.createElement(Box7, { role: "list", sx: { paddingBlockEnd: 1, paddingInlineStart: 2 } }, violations.map((violation, idx) => {
|
|
1013
1147
|
const widgetIcon = violation.elementId ? getElementIcon(violation.elementId) : null;
|
|
1014
1148
|
const elementTitle = violation.elementId ? getElementTitle(violation.elementId) : null;
|
|
@@ -1044,13 +1178,20 @@ function ViolationRow({ audit: audit23, skipReason, violations }) {
|
|
|
1044
1178
|
prompt: violation.angiePrompt ?? buildAngiePrompt(rowLabel)
|
|
1045
1179
|
}
|
|
1046
1180
|
),
|
|
1047
|
-
violation.ctaLabel && violation.externalUrl ? /* @__PURE__ */ React11.createElement(
|
|
1181
|
+
violation.ctaLabel && violation.externalUrl ? /* @__PURE__ */ React11.createElement(Box7, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React11.createElement(
|
|
1048
1182
|
ViolationCtaButton,
|
|
1049
1183
|
{
|
|
1050
1184
|
ctaLabel: violation.ctaLabel,
|
|
1051
1185
|
externalUrl: violation.externalUrl
|
|
1052
1186
|
}
|
|
1053
|
-
)
|
|
1187
|
+
), violation.secondaryCtaLabel && violation.secondaryCtaUrl && /* @__PURE__ */ React11.createElement(
|
|
1188
|
+
ViolationCtaButton,
|
|
1189
|
+
{
|
|
1190
|
+
ctaLabel: violation.secondaryCtaLabel,
|
|
1191
|
+
externalUrl: violation.secondaryCtaUrl,
|
|
1192
|
+
variant: "text"
|
|
1193
|
+
}
|
|
1194
|
+
)) : /* @__PURE__ */ React11.createElement(
|
|
1054
1195
|
EyeIcon,
|
|
1055
1196
|
{
|
|
1056
1197
|
className: "violation-hover-icon",
|
|
@@ -1148,17 +1289,17 @@ import { __ as __14 } from "@wordpress/i18n";
|
|
|
1148
1289
|
var ALL_SEVERITIES = ["error", "warning", "info"];
|
|
1149
1290
|
function countSeverities(report, category) {
|
|
1150
1291
|
const counts = { error: 0, warning: 0, info: 0 };
|
|
1151
|
-
for (const { audit:
|
|
1292
|
+
for (const { audit: audit25, result } of report.auditResults) {
|
|
1152
1293
|
if (result.status !== "fail") {
|
|
1153
1294
|
continue;
|
|
1154
1295
|
}
|
|
1155
|
-
if (category && !
|
|
1296
|
+
if (category && !audit25.categories.includes(category)) {
|
|
1156
1297
|
continue;
|
|
1157
1298
|
}
|
|
1158
|
-
if (!isScoredAudit(
|
|
1299
|
+
if (!isScoredAudit(audit25)) {
|
|
1159
1300
|
continue;
|
|
1160
1301
|
}
|
|
1161
|
-
counts[
|
|
1302
|
+
counts[audit25.severity] += result.violations.length;
|
|
1162
1303
|
}
|
|
1163
1304
|
return counts;
|
|
1164
1305
|
}
|
|
@@ -1842,16 +1983,93 @@ var audit = {
|
|
|
1842
1983
|
}
|
|
1843
1984
|
};
|
|
1844
1985
|
|
|
1845
|
-
// src/audits/
|
|
1986
|
+
// src/audits/accessibility-statement.ts
|
|
1846
1987
|
import { __ as __26 } from "@wordpress/i18n";
|
|
1847
1988
|
var audit2 = {
|
|
1848
|
-
id: "audits/
|
|
1849
|
-
title: __26("
|
|
1989
|
+
id: "audits/accessibility-statement",
|
|
1990
|
+
title: __26("Create an accessibility statement", "elementor"),
|
|
1850
1991
|
description: __26(
|
|
1992
|
+
"An accessibility statement showcases your efforts to create an inclusive online space, highlighting helpful features and a commitment to accessibility.",
|
|
1993
|
+
"elementor"
|
|
1994
|
+
),
|
|
1995
|
+
fixHint: __26("Use Ally to create and publish an accessibility statement for your site.", "elementor"),
|
|
1996
|
+
categories: ["accessibility"],
|
|
1997
|
+
severity: "info",
|
|
1998
|
+
weight: 1,
|
|
1999
|
+
evaluate: (ctx) => {
|
|
2000
|
+
const isReady = ctx.pageContext.ally_plugin_active;
|
|
2001
|
+
if (isReady && ctx.pageContext.ally_accessibility_statement_created) {
|
|
2002
|
+
return { status: "pass" };
|
|
2003
|
+
}
|
|
2004
|
+
return {
|
|
2005
|
+
status: "fail",
|
|
2006
|
+
violations: [
|
|
2007
|
+
{
|
|
2008
|
+
auditId: audit2.id,
|
|
2009
|
+
label: __26("No accessibility statement has been created for this site.", "elementor"),
|
|
2010
|
+
externalUrl: isReady ? ctx.pageContext.ally_accessibility_statement_url : ctx.pageContext.ally_plugin_url,
|
|
2011
|
+
ctaLabel: isReady ? __26("Create", "elementor") : void 0,
|
|
2012
|
+
secondaryCtaLabel: __26("Learn more", "elementor"),
|
|
2013
|
+
secondaryCtaUrl: "https://go.elementor.com/acc-plg-learn-more"
|
|
2014
|
+
}
|
|
2015
|
+
]
|
|
2016
|
+
};
|
|
2017
|
+
}
|
|
2018
|
+
};
|
|
2019
|
+
|
|
2020
|
+
// src/audits/accessibility-widget.ts
|
|
2021
|
+
import { __ as __27 } from "@wordpress/i18n";
|
|
2022
|
+
|
|
2023
|
+
// src/utils/scan-accessibility-widgets.ts
|
|
2024
|
+
var ACCESSIBILITY_WIDGET_SCRIPT_SOURCES = ["cdn.elementor.com/a11y/widget.js"];
|
|
2025
|
+
function hasAccessibilityWidgetScript(html) {
|
|
2026
|
+
return ACCESSIBILITY_WIDGET_SCRIPT_SOURCES.some((src) => html.includes(src));
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
// src/audits/accessibility-widget.ts
|
|
2030
|
+
var audit3 = {
|
|
2031
|
+
id: "audits/accessibility-widget",
|
|
2032
|
+
title: __27("Add an accessibility widget", "elementor"),
|
|
2033
|
+
description: __27("Make your site more inclusive by adding an accessibility widget.", "elementor"),
|
|
2034
|
+
fixHint: __27("Activate Ally\u2019s accessibility widget to give visitors on-page accessibility tools.", "elementor"),
|
|
2035
|
+
categories: ["accessibility"],
|
|
2036
|
+
severity: "info",
|
|
2037
|
+
weight: 1,
|
|
2038
|
+
evaluate: (ctx) => {
|
|
2039
|
+
if (!ctx.pageContext.frontend_url) {
|
|
2040
|
+
return { status: "skipped", reason: __27("Page is not published.", "elementor") };
|
|
2041
|
+
}
|
|
2042
|
+
if (!ctx.renderedHtml) {
|
|
2043
|
+
return { status: "skipped", reason: __27("Could not fetch the published page.", "elementor") };
|
|
2044
|
+
}
|
|
2045
|
+
if (hasAccessibilityWidgetScript(ctx.renderedHtml)) {
|
|
2046
|
+
return { status: "pass" };
|
|
2047
|
+
}
|
|
2048
|
+
const isReady = ctx.pageContext.ally_plugin_active;
|
|
2049
|
+
return {
|
|
2050
|
+
status: "fail",
|
|
2051
|
+
violations: [
|
|
2052
|
+
{
|
|
2053
|
+
auditId: audit3.id,
|
|
2054
|
+
label: __27("No accessibility widget is active on this site.", "elementor"),
|
|
2055
|
+
externalUrl: isReady ? ctx.pageContext.ally_widget_settings_url : ctx.pageContext.ally_plugin_url,
|
|
2056
|
+
ctaLabel: __27("Activate", "elementor")
|
|
2057
|
+
}
|
|
2058
|
+
]
|
|
2059
|
+
};
|
|
2060
|
+
}
|
|
2061
|
+
};
|
|
2062
|
+
|
|
2063
|
+
// src/audits/cookie-policy.ts
|
|
2064
|
+
import { __ as __28 } from "@wordpress/i18n";
|
|
2065
|
+
var audit4 = {
|
|
2066
|
+
id: "audits/cookie-policy",
|
|
2067
|
+
title: __28("Cookie policy", "elementor"),
|
|
2068
|
+
description: __28(
|
|
1851
2069
|
"A cookie policy is required by privacy regulations such as GDPR (EU) or CCPA (US) to inform visitors about tracking and data collection.",
|
|
1852
2070
|
"elementor"
|
|
1853
2071
|
),
|
|
1854
|
-
fixHint:
|
|
2072
|
+
fixHint: __28("Install the Cookiez plugin to add a cookie policy to your website.", "elementor"),
|
|
1855
2073
|
categories: ["compliance"],
|
|
1856
2074
|
severity: "info",
|
|
1857
2075
|
weight: 1,
|
|
@@ -1863,8 +2081,8 @@ var audit2 = {
|
|
|
1863
2081
|
status: "fail",
|
|
1864
2082
|
violations: [
|
|
1865
2083
|
{
|
|
1866
|
-
auditId:
|
|
1867
|
-
label:
|
|
2084
|
+
auditId: audit4.id,
|
|
2085
|
+
label: __28("Cookiez plugin is not installed or active.", "elementor"),
|
|
1868
2086
|
externalUrl: ctx.pageContext.cookiez_plugin_url
|
|
1869
2087
|
}
|
|
1870
2088
|
]
|
|
@@ -1874,7 +2092,7 @@ var audit2 = {
|
|
|
1874
2092
|
|
|
1875
2093
|
// src/audits/deep-nesting.ts
|
|
1876
2094
|
import { getWidgetsCache } from "@elementor/editor-elements";
|
|
1877
|
-
import { __ as
|
|
2095
|
+
import { __ as __29 } from "@wordpress/i18n";
|
|
1878
2096
|
var MAX_NESTING_DEPTH = 6;
|
|
1879
2097
|
function isNestingElement(node, widgetsCache) {
|
|
1880
2098
|
if (node.elType === "container") {
|
|
@@ -1882,20 +2100,20 @@ function isNestingElement(node, widgetsCache) {
|
|
|
1882
2100
|
}
|
|
1883
2101
|
return !!widgetsCache?.[node.elType]?.meta?.is_container;
|
|
1884
2102
|
}
|
|
1885
|
-
var
|
|
2103
|
+
var audit5 = {
|
|
1886
2104
|
id: "audits/deep-nesting",
|
|
1887
|
-
title:
|
|
1888
|
-
description:
|
|
2105
|
+
title: __29("Deep container nesting", "elementor"),
|
|
2106
|
+
description: __29(
|
|
1889
2107
|
"Container nesting exceeds the recommended depth. Deep DOM trees hurt rendering performance and readability.",
|
|
1890
2108
|
"elementor"
|
|
1891
2109
|
),
|
|
1892
|
-
fixHint:
|
|
2110
|
+
fixHint: __29("Flatten the layout by removing unnecessary wrapper containers.", "elementor"),
|
|
1893
2111
|
categories: ["performance", "best-practices"],
|
|
1894
2112
|
severity: "warning",
|
|
1895
2113
|
weight: 5,
|
|
1896
2114
|
evaluate: (ctx) => {
|
|
1897
2115
|
if (ctx.elements.tree.length === 0) {
|
|
1898
|
-
return { status: "skipped", reason:
|
|
2116
|
+
return { status: "skipped", reason: __29("No elements", "elementor") };
|
|
1899
2117
|
}
|
|
1900
2118
|
const widgetsCache = getWidgetsCache();
|
|
1901
2119
|
const violations = [];
|
|
@@ -1906,10 +2124,10 @@ var audit3 = {
|
|
|
1906
2124
|
const depth = parents.filter((parent) => isNestingElement(parent, widgetsCache)).length + 1;
|
|
1907
2125
|
if (depth > MAX_NESTING_DEPTH) {
|
|
1908
2126
|
violations.push({
|
|
1909
|
-
auditId:
|
|
2127
|
+
auditId: audit5.id,
|
|
1910
2128
|
elementId: node.id,
|
|
1911
2129
|
targetHint: "element-settings",
|
|
1912
|
-
label:
|
|
2130
|
+
label: __29("Container nesting is too deep.", "elementor")
|
|
1913
2131
|
});
|
|
1914
2132
|
}
|
|
1915
2133
|
});
|
|
@@ -1918,15 +2136,15 @@ var audit3 = {
|
|
|
1918
2136
|
};
|
|
1919
2137
|
|
|
1920
2138
|
// src/audits/default-design-system.ts
|
|
1921
|
-
import { __ as
|
|
1922
|
-
var
|
|
2139
|
+
import { __ as __30 } from "@wordpress/i18n";
|
|
2140
|
+
var audit6 = {
|
|
1923
2141
|
id: "audits/default-design-system",
|
|
1924
|
-
title:
|
|
1925
|
-
description:
|
|
2142
|
+
title: __30("Default website kit", "elementor"),
|
|
2143
|
+
description: __30(
|
|
1926
2144
|
"Your website is using the default design system colors and fonts. Custom branding makes the website feel uniquely yours.",
|
|
1927
2145
|
"elementor"
|
|
1928
2146
|
),
|
|
1929
|
-
fixHint:
|
|
2147
|
+
fixHint: __30("Open Site Settings and customize your kit (colors, fonts, layout).", "elementor"),
|
|
1930
2148
|
categories: ["best-practices"],
|
|
1931
2149
|
severity: "info",
|
|
1932
2150
|
weight: 1,
|
|
@@ -1938,8 +2156,8 @@ var audit4 = {
|
|
|
1938
2156
|
status: "fail",
|
|
1939
2157
|
violations: [
|
|
1940
2158
|
{
|
|
1941
|
-
auditId:
|
|
1942
|
-
label:
|
|
2159
|
+
auditId: audit6.id,
|
|
2160
|
+
label: __30("Kit appears unchanged from default.", "elementor"),
|
|
1943
2161
|
targetHint: "site-settings"
|
|
1944
2162
|
}
|
|
1945
2163
|
]
|
|
@@ -1949,16 +2167,16 @@ var audit4 = {
|
|
|
1949
2167
|
|
|
1950
2168
|
// src/audits/deprecated-widgets.ts
|
|
1951
2169
|
import { getWidgetsCache as getWidgetsCache2 } from "@elementor/editor-elements";
|
|
1952
|
-
import { __ as
|
|
2170
|
+
import { __ as __31 } from "@wordpress/i18n";
|
|
1953
2171
|
var DEPRECATION_CONTROL_NAME = "deprecation_message";
|
|
1954
|
-
var
|
|
2172
|
+
var audit7 = {
|
|
1955
2173
|
id: "audits/deprecated-widgets",
|
|
1956
|
-
title:
|
|
1957
|
-
description:
|
|
2174
|
+
title: __31("Deprecated widgets", "elementor"),
|
|
2175
|
+
description: __31(
|
|
1958
2176
|
"Deprecated widgets should not be used. For better capabilities use the recommended replacement.",
|
|
1959
2177
|
"elementor"
|
|
1960
2178
|
),
|
|
1961
|
-
fixHint:
|
|
2179
|
+
fixHint: __31("Replace each deprecated widget with the recommended new widget shown in its panel.", "elementor"),
|
|
1962
2180
|
categories: ["best-practices", "performance"],
|
|
1963
2181
|
severity: "warning",
|
|
1964
2182
|
weight: 7,
|
|
@@ -1982,10 +2200,10 @@ var audit5 = {
|
|
|
1982
2200
|
return;
|
|
1983
2201
|
}
|
|
1984
2202
|
violations.push({
|
|
1985
|
-
auditId:
|
|
2203
|
+
auditId: audit7.id,
|
|
1986
2204
|
elementId: node.id,
|
|
1987
2205
|
targetHint: "element-settings",
|
|
1988
|
-
label:
|
|
2206
|
+
label: __31("Using deprecated widget.", "elementor")
|
|
1989
2207
|
});
|
|
1990
2208
|
});
|
|
1991
2209
|
return violations.length === 0 ? { status: "pass" } : { status: "fail", violations };
|
|
@@ -1993,28 +2211,7 @@ var audit5 = {
|
|
|
1993
2211
|
};
|
|
1994
2212
|
|
|
1995
2213
|
// src/audits/google-consent-mode.ts
|
|
1996
|
-
import { __ as
|
|
1997
|
-
|
|
1998
|
-
// src/utils/fetch-rendered-html.ts
|
|
1999
|
-
var FETCH_TIMEOUT_MS = 1e4;
|
|
2000
|
-
async function fetchRenderedHtml(url) {
|
|
2001
|
-
if (!url) {
|
|
2002
|
-
return null;
|
|
2003
|
-
}
|
|
2004
|
-
const timeoutController = new AbortController();
|
|
2005
|
-
const timeoutId = setTimeout(() => timeoutController.abort(), FETCH_TIMEOUT_MS);
|
|
2006
|
-
try {
|
|
2007
|
-
const response = await fetch(url, { credentials: "omit", signal: timeoutController.signal });
|
|
2008
|
-
if (!response.ok) {
|
|
2009
|
-
return null;
|
|
2010
|
-
}
|
|
2011
|
-
return await response.text();
|
|
2012
|
-
} catch {
|
|
2013
|
-
return null;
|
|
2014
|
-
} finally {
|
|
2015
|
-
clearTimeout(timeoutId);
|
|
2016
|
-
}
|
|
2017
|
-
}
|
|
2214
|
+
import { __ as __32 } from "@wordpress/i18n";
|
|
2018
2215
|
|
|
2019
2216
|
// src/utils/scan-consent-signals.ts
|
|
2020
2217
|
var GOOGLE_TRACKING_PATTERNS = [
|
|
@@ -2035,44 +2232,43 @@ function hasConsentDefaultCall(html) {
|
|
|
2035
2232
|
}
|
|
2036
2233
|
|
|
2037
2234
|
// src/audits/google-consent-mode.ts
|
|
2038
|
-
var
|
|
2235
|
+
var audit8 = {
|
|
2039
2236
|
id: "audits/google-consent-mode",
|
|
2040
|
-
title:
|
|
2041
|
-
description:
|
|
2237
|
+
title: __32("Google Consent Mode", "elementor"),
|
|
2238
|
+
description: __32(
|
|
2042
2239
|
"Google Analytics, Ads, or Tag Manager are running on this site and may not receive a consent signal, which risks losing conversion/analytics data and compliance exposure.",
|
|
2043
2240
|
"elementor"
|
|
2044
2241
|
),
|
|
2045
|
-
fixHint:
|
|
2242
|
+
fixHint: __32(
|
|
2046
2243
|
"Turn on Google Consent Mode in your cookie consent plugin so Google tags respect visitor consent choices.",
|
|
2047
2244
|
"elementor"
|
|
2048
2245
|
),
|
|
2049
2246
|
categories: ["compliance"],
|
|
2050
2247
|
severity: "warning",
|
|
2051
2248
|
weight: 1,
|
|
2052
|
-
evaluate:
|
|
2249
|
+
evaluate: (ctx) => {
|
|
2053
2250
|
if (!ctx.pageContext.frontend_url) {
|
|
2054
|
-
return { status: "skipped", reason:
|
|
2251
|
+
return { status: "skipped", reason: __32("Page is not published.", "elementor") };
|
|
2055
2252
|
}
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
return { status: "skipped", reason: __30("Could not fetch the published page.", "elementor") };
|
|
2253
|
+
if (!ctx.renderedHtml) {
|
|
2254
|
+
return { status: "skipped", reason: __32("Could not fetch the published page.", "elementor") };
|
|
2059
2255
|
}
|
|
2060
|
-
if (!hasGoogleTracking(
|
|
2061
|
-
return { status: "skipped", reason:
|
|
2256
|
+
if (!hasGoogleTracking(ctx.renderedHtml)) {
|
|
2257
|
+
return { status: "skipped", reason: __32("No Google tracking product detected.", "elementor") };
|
|
2062
2258
|
}
|
|
2063
|
-
if (hasConsentDefaultCall(
|
|
2259
|
+
if (hasConsentDefaultCall(ctx.renderedHtml)) {
|
|
2064
2260
|
return { status: "pass" };
|
|
2065
2261
|
}
|
|
2066
|
-
const label =
|
|
2262
|
+
const label = __32("No Google Consent Mode signal was found on the page.", "elementor");
|
|
2067
2263
|
const isCookiezReady = ctx.pageContext.cookiez_plugin_installed && ctx.pageContext.cookiez_plugin_active;
|
|
2068
2264
|
if (isCookiezReady) {
|
|
2069
2265
|
return {
|
|
2070
2266
|
status: "fail",
|
|
2071
2267
|
violations: [
|
|
2072
2268
|
{
|
|
2073
|
-
auditId:
|
|
2269
|
+
auditId: audit8.id,
|
|
2074
2270
|
label,
|
|
2075
|
-
ctaLabel:
|
|
2271
|
+
ctaLabel: __32("Enable", "elementor"),
|
|
2076
2272
|
externalUrl: ctx.pageContext.cookiez_consent_mode_settings_url
|
|
2077
2273
|
}
|
|
2078
2274
|
]
|
|
@@ -2082,7 +2278,7 @@ var audit6 = {
|
|
|
2082
2278
|
status: "fail",
|
|
2083
2279
|
violations: [
|
|
2084
2280
|
{
|
|
2085
|
-
auditId:
|
|
2281
|
+
auditId: audit8.id,
|
|
2086
2282
|
label,
|
|
2087
2283
|
externalUrl: ctx.pageContext.cookiez_plugin_action_url
|
|
2088
2284
|
}
|
|
@@ -2092,7 +2288,7 @@ var audit6 = {
|
|
|
2092
2288
|
};
|
|
2093
2289
|
|
|
2094
2290
|
// src/audits/heading-structure.ts
|
|
2095
|
-
import { __ as
|
|
2291
|
+
import { __ as __33 } from "@wordpress/i18n";
|
|
2096
2292
|
var HEADING_LEVELS = ["h1", "h2", "h3", "h4", "h5", "h6"];
|
|
2097
2293
|
var HEADING_CONTROLS_REGISTRY = {
|
|
2098
2294
|
// Core
|
|
@@ -2268,47 +2464,47 @@ function extractPageHeadings(tree) {
|
|
|
2268
2464
|
});
|
|
2269
2465
|
return headings;
|
|
2270
2466
|
}
|
|
2271
|
-
var
|
|
2467
|
+
var audit9 = {
|
|
2272
2468
|
id: "audits/heading-structure",
|
|
2273
|
-
title:
|
|
2274
|
-
description:
|
|
2275
|
-
fixHint:
|
|
2469
|
+
title: __33("Heading structure", "elementor"),
|
|
2470
|
+
description: __33("Pages should have exactly one H1 and a non-skipping heading order.", "elementor"),
|
|
2471
|
+
fixHint: __33("Ensure your page has one H1 and that heading levels do not skip (no H2 \u2192 H4).", "elementor"),
|
|
2276
2472
|
categories: ["seo", "accessibility"],
|
|
2277
2473
|
severity: "error",
|
|
2278
2474
|
weight: 10,
|
|
2279
2475
|
evaluate: (ctx) => {
|
|
2280
2476
|
if (ctx.elements.tree.length === 0) {
|
|
2281
|
-
return { status: "skipped", reason:
|
|
2477
|
+
return { status: "skipped", reason: __33("No elements", "elementor") };
|
|
2282
2478
|
}
|
|
2283
2479
|
const headings = extractPageHeadings(ctx.elements.tree);
|
|
2284
2480
|
const violations = [];
|
|
2285
2481
|
if (headings.length === 0) {
|
|
2286
2482
|
violations.push({
|
|
2287
|
-
auditId:
|
|
2288
|
-
label:
|
|
2483
|
+
auditId: audit9.id,
|
|
2484
|
+
label: __33("No headings found on the page.", "elementor")
|
|
2289
2485
|
});
|
|
2290
2486
|
} else {
|
|
2291
2487
|
const h1Count = headings.filter((h) => h.level === 1).length;
|
|
2292
2488
|
if (h1Count === 0) {
|
|
2293
|
-
violations.push({ auditId:
|
|
2489
|
+
violations.push({ auditId: audit9.id, label: __33("No H1 on the page.", "elementor") });
|
|
2294
2490
|
}
|
|
2295
2491
|
if (h1Count > 1) {
|
|
2296
2492
|
headings.filter((h) => h.level === 1).slice(1).forEach(
|
|
2297
2493
|
(h) => violations.push({
|
|
2298
|
-
auditId:
|
|
2494
|
+
auditId: audit9.id,
|
|
2299
2495
|
elementId: h.elementId,
|
|
2300
2496
|
targetHint: "element-settings",
|
|
2301
|
-
label:
|
|
2497
|
+
label: __33("More than one H1 on the page.", "elementor")
|
|
2302
2498
|
})
|
|
2303
2499
|
);
|
|
2304
2500
|
}
|
|
2305
2501
|
for (let i = 1; i < headings.length; i++) {
|
|
2306
2502
|
if (headings[i].level - headings[i - 1].level > 1) {
|
|
2307
2503
|
violations.push({
|
|
2308
|
-
auditId:
|
|
2504
|
+
auditId: audit9.id,
|
|
2309
2505
|
elementId: headings[i].elementId,
|
|
2310
2506
|
targetHint: "element-settings",
|
|
2311
|
-
label:
|
|
2507
|
+
label: __33("Heading level skipped.", "elementor")
|
|
2312
2508
|
});
|
|
2313
2509
|
}
|
|
2314
2510
|
}
|
|
@@ -2318,33 +2514,33 @@ var audit7 = {
|
|
|
2318
2514
|
};
|
|
2319
2515
|
|
|
2320
2516
|
// src/audits/hidden-elements.ts
|
|
2321
|
-
import { __ as
|
|
2517
|
+
import { __ as __34 } from "@wordpress/i18n";
|
|
2322
2518
|
function isHiddenOnAllDevices(settings) {
|
|
2323
2519
|
return Boolean(settings.hide_desktop) && Boolean(settings.hide_tablet) && Boolean(settings.hide_mobile);
|
|
2324
2520
|
}
|
|
2325
|
-
var
|
|
2521
|
+
var audit10 = {
|
|
2326
2522
|
id: "audits/hidden-elements",
|
|
2327
|
-
title:
|
|
2328
|
-
description:
|
|
2523
|
+
title: __34("Hidden elements", "elementor"),
|
|
2524
|
+
description: __34(
|
|
2329
2525
|
"Elements hidden on all devices simultaneously are effectively dead code in the page tree.",
|
|
2330
2526
|
"elementor"
|
|
2331
2527
|
),
|
|
2332
|
-
fixHint:
|
|
2528
|
+
fixHint: __34("Remove the element or make it visible on at least one device breakpoint.", "elementor"),
|
|
2333
2529
|
categories: ["best-practices", "performance"],
|
|
2334
2530
|
severity: "info",
|
|
2335
2531
|
weight: 3,
|
|
2336
2532
|
evaluate: (ctx) => {
|
|
2337
2533
|
if (ctx.elements.tree.length === 0) {
|
|
2338
|
-
return { status: "skipped", reason:
|
|
2534
|
+
return { status: "skipped", reason: __34("No elements", "elementor") };
|
|
2339
2535
|
}
|
|
2340
2536
|
const violations = [];
|
|
2341
2537
|
walkElements(ctx.elements.tree, (node) => {
|
|
2342
2538
|
if (isHiddenOnAllDevices(node.settings)) {
|
|
2343
2539
|
violations.push({
|
|
2344
|
-
auditId:
|
|
2540
|
+
auditId: audit10.id,
|
|
2345
2541
|
elementId: node.id,
|
|
2346
2542
|
targetHint: "element-settings",
|
|
2347
|
-
label:
|
|
2543
|
+
label: __34("Element is hidden on all devices.", "elementor")
|
|
2348
2544
|
});
|
|
2349
2545
|
}
|
|
2350
2546
|
});
|
|
@@ -2353,7 +2549,7 @@ var audit8 = {
|
|
|
2353
2549
|
};
|
|
2354
2550
|
|
|
2355
2551
|
// src/audits/images-alt-text.ts
|
|
2356
|
-
import { __ as
|
|
2552
|
+
import { __ as __35 } from "@wordpress/i18n";
|
|
2357
2553
|
|
|
2358
2554
|
// src/utils/image-alt.ts
|
|
2359
2555
|
function hasMeaningfulAlt(media, pageContext) {
|
|
@@ -2361,7 +2557,8 @@ function hasMeaningfulAlt(media, pageContext) {
|
|
|
2361
2557
|
return true;
|
|
2362
2558
|
}
|
|
2363
2559
|
if (media.id) {
|
|
2364
|
-
const
|
|
2560
|
+
const key = buildImageSizeKey({ id: media.id, size: media.size });
|
|
2561
|
+
const alt = pageContext.image_sizes[key]?.alt ?? "";
|
|
2365
2562
|
return alt.trim().length > 0;
|
|
2366
2563
|
}
|
|
2367
2564
|
return (media.alt ?? "").trim().length > 0;
|
|
@@ -2371,17 +2568,17 @@ function isImageSourcePresent(media) {
|
|
|
2371
2568
|
}
|
|
2372
2569
|
|
|
2373
2570
|
// src/audits/images-alt-text.ts
|
|
2374
|
-
var
|
|
2571
|
+
var audit11 = {
|
|
2375
2572
|
id: "audits/images-alt-text",
|
|
2376
|
-
title:
|
|
2377
|
-
description:
|
|
2378
|
-
fixHint:
|
|
2573
|
+
title: __35("Images alt text", "elementor"),
|
|
2574
|
+
description: __35("Every image needs a meaningful alt attribute for screen readers and image-search.", "elementor"),
|
|
2575
|
+
fixHint: __35("Open the image's settings and add an Alt Text describing the image.", "elementor"),
|
|
2379
2576
|
categories: ["seo", "accessibility"],
|
|
2380
2577
|
severity: "error",
|
|
2381
2578
|
weight: 10,
|
|
2382
2579
|
evaluate: (ctx) => {
|
|
2383
2580
|
if (!hasPageImages(ctx.elements.tree)) {
|
|
2384
|
-
return { status: "skipped", reason:
|
|
2581
|
+
return { status: "skipped", reason: __35("No images", "elementor") };
|
|
2385
2582
|
}
|
|
2386
2583
|
const violations = [];
|
|
2387
2584
|
const failedWidgetIds = /* @__PURE__ */ new Set();
|
|
@@ -2394,10 +2591,10 @@ var audit9 = {
|
|
|
2394
2591
|
if (!failedWidgetIds.has(node.id)) {
|
|
2395
2592
|
failedWidgetIds.add(node.id);
|
|
2396
2593
|
violations.push({
|
|
2397
|
-
auditId:
|
|
2594
|
+
auditId: audit11.id,
|
|
2398
2595
|
elementId: node.id,
|
|
2399
2596
|
targetHint: "element-settings",
|
|
2400
|
-
label:
|
|
2597
|
+
label: __35("Image is missing alt text.", "elementor"),
|
|
2401
2598
|
externalUrl: ctx.pageContext.ally_plugin_url
|
|
2402
2599
|
});
|
|
2403
2600
|
}
|
|
@@ -2407,29 +2604,30 @@ var audit9 = {
|
|
|
2407
2604
|
};
|
|
2408
2605
|
|
|
2409
2606
|
// src/audits/images-too-large.ts
|
|
2410
|
-
import { __ as
|
|
2607
|
+
import { __ as __36, sprintf as sprintf4 } from "@wordpress/i18n";
|
|
2411
2608
|
var SIZE_THRESHOLD_BYTES = 500 * 1024;
|
|
2412
2609
|
var BYTES_PER_KB = 1024;
|
|
2413
|
-
var
|
|
2610
|
+
var audit12 = {
|
|
2414
2611
|
id: "audits/images-too-large",
|
|
2415
|
-
title:
|
|
2416
|
-
description:
|
|
2417
|
-
fixHint:
|
|
2612
|
+
title: __36("Oversized images", "elementor"),
|
|
2613
|
+
description: __36("Large image files slow down the page.", "elementor"),
|
|
2614
|
+
fixHint: __36("Replace the image with a smaller version or enable image optimization.", "elementor"),
|
|
2418
2615
|
categories: ["performance"],
|
|
2419
2616
|
severity: "warning",
|
|
2420
2617
|
weight: 7,
|
|
2421
2618
|
evaluate: (ctx) => {
|
|
2422
|
-
if (!hasPageImages(ctx.elements.tree)) {
|
|
2423
|
-
return { status: "skipped", reason: __34("No images", "elementor") };
|
|
2424
|
-
}
|
|
2425
2619
|
const widgetMaxKb = /* @__PURE__ */ new Map();
|
|
2426
2620
|
let oversizedImageCount = 0;
|
|
2427
|
-
|
|
2621
|
+
let hasAnyImage = false;
|
|
2622
|
+
const evaluateSource = (node, media) => {
|
|
2623
|
+
if (media.id || media.url) {
|
|
2624
|
+
hasAnyImage = true;
|
|
2625
|
+
}
|
|
2428
2626
|
const id = media.id;
|
|
2429
2627
|
if (!id) {
|
|
2430
2628
|
return;
|
|
2431
2629
|
}
|
|
2432
|
-
const size = ctx.pageContext.image_sizes[id];
|
|
2630
|
+
const size = ctx.pageContext.image_sizes[buildImageSizeKey({ id, size: media.size })];
|
|
2433
2631
|
if (!size || size.filesize_bytes <= SIZE_THRESHOLD_BYTES) {
|
|
2434
2632
|
return;
|
|
2435
2633
|
}
|
|
@@ -2437,14 +2635,21 @@ var audit10 = {
|
|
|
2437
2635
|
const kb = Math.round(size.filesize_bytes / BYTES_PER_KB);
|
|
2438
2636
|
const currentMax = widgetMaxKb.get(node.id) ?? 0;
|
|
2439
2637
|
widgetMaxKb.set(node.id, Math.max(currentMax, kb));
|
|
2440
|
-
}
|
|
2638
|
+
};
|
|
2639
|
+
walkImageLikeSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2640
|
+
walkBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2641
|
+
walkAtomicImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2642
|
+
walkAtomicBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2643
|
+
if (!hasAnyImage) {
|
|
2644
|
+
return { status: "skipped", reason: __36("No images", "elementor") };
|
|
2645
|
+
}
|
|
2441
2646
|
const violations = Array.from(widgetMaxKb.entries()).map(([elementId, kb]) => ({
|
|
2442
|
-
auditId:
|
|
2647
|
+
auditId: audit12.id,
|
|
2443
2648
|
elementId,
|
|
2444
2649
|
targetHint: "element-settings",
|
|
2445
2650
|
label: sprintf4(
|
|
2446
2651
|
/* translators: %d is the image file size in kilobytes. */
|
|
2447
|
-
|
|
2652
|
+
__36("Image is %d KB (over 500 KB).", "elementor"),
|
|
2448
2653
|
kb
|
|
2449
2654
|
),
|
|
2450
2655
|
externalUrl: ctx.pageContext.image_optimization_plugin_url
|
|
@@ -2454,21 +2659,21 @@ var audit10 = {
|
|
|
2454
2659
|
};
|
|
2455
2660
|
|
|
2456
2661
|
// src/audits/nested-boxed-containers.ts
|
|
2457
|
-
import { __ as
|
|
2662
|
+
import { __ as __37 } from "@wordpress/i18n";
|
|
2458
2663
|
function isBoxed(settings) {
|
|
2459
2664
|
return settings.content_width === "boxed";
|
|
2460
2665
|
}
|
|
2461
|
-
var
|
|
2666
|
+
var audit13 = {
|
|
2462
2667
|
id: "audits/nested-boxed-containers",
|
|
2463
|
-
title:
|
|
2464
|
-
description:
|
|
2465
|
-
fixHint:
|
|
2668
|
+
title: __37("Boxed container nested inside a boxed parent", "elementor"),
|
|
2669
|
+
description: __37("An inner container does not need to be boxed when its parent already is.", "elementor"),
|
|
2670
|
+
fixHint: __37("Change the inner container's content width to Full Width.", "elementor"),
|
|
2466
2671
|
categories: ["best-practices", "performance"],
|
|
2467
2672
|
severity: "info",
|
|
2468
2673
|
weight: 5,
|
|
2469
2674
|
evaluate: (ctx) => {
|
|
2470
2675
|
if (ctx.elements.tree.length === 0) {
|
|
2471
|
-
return { status: "skipped", reason:
|
|
2676
|
+
return { status: "skipped", reason: __37("No elements", "elementor") };
|
|
2472
2677
|
}
|
|
2473
2678
|
const violations = [];
|
|
2474
2679
|
walkElements(ctx.elements.tree, (node, parents) => {
|
|
@@ -2478,10 +2683,10 @@ var audit11 = {
|
|
|
2478
2683
|
const nearestContainerAncestor = [...parents].reverse().find((p) => p.elType === "container");
|
|
2479
2684
|
if (nearestContainerAncestor && isBoxed(nearestContainerAncestor.settings)) {
|
|
2480
2685
|
violations.push({
|
|
2481
|
-
auditId:
|
|
2686
|
+
auditId: audit13.id,
|
|
2482
2687
|
elementId: node.id,
|
|
2483
2688
|
targetHint: "element-settings",
|
|
2484
|
-
label:
|
|
2689
|
+
label: __37("Nested boxed container.", "elementor")
|
|
2485
2690
|
});
|
|
2486
2691
|
}
|
|
2487
2692
|
});
|
|
@@ -2490,12 +2695,12 @@ var audit11 = {
|
|
|
2490
2695
|
};
|
|
2491
2696
|
|
|
2492
2697
|
// src/audits/page-excerpt.ts
|
|
2493
|
-
import { __ as
|
|
2494
|
-
var
|
|
2698
|
+
import { __ as __38 } from "@wordpress/i18n";
|
|
2699
|
+
var audit14 = {
|
|
2495
2700
|
id: "audits/page-excerpt",
|
|
2496
|
-
title:
|
|
2497
|
-
description:
|
|
2498
|
-
fixHint:
|
|
2701
|
+
title: __38("Page excerpt", "elementor"),
|
|
2702
|
+
description: __38("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
|
|
2703
|
+
fixHint: __38("Open Page Settings and write a short excerpt.", "elementor"),
|
|
2499
2704
|
categories: ["seo"],
|
|
2500
2705
|
severity: "warning",
|
|
2501
2706
|
weight: 5,
|
|
@@ -2507,8 +2712,8 @@ var audit12 = {
|
|
|
2507
2712
|
status: "fail",
|
|
2508
2713
|
violations: [
|
|
2509
2714
|
{
|
|
2510
|
-
auditId:
|
|
2511
|
-
label:
|
|
2715
|
+
auditId: audit14.id,
|
|
2716
|
+
label: __38("Page has no excerpt.", "elementor"),
|
|
2512
2717
|
targetHint: "page-settings",
|
|
2513
2718
|
angieFix: true
|
|
2514
2719
|
}
|
|
@@ -2518,12 +2723,12 @@ var audit12 = {
|
|
|
2518
2723
|
};
|
|
2519
2724
|
|
|
2520
2725
|
// src/audits/page-featured-image.ts
|
|
2521
|
-
import { __ as
|
|
2522
|
-
var
|
|
2726
|
+
import { __ as __39 } from "@wordpress/i18n";
|
|
2727
|
+
var audit15 = {
|
|
2523
2728
|
id: "audits/page-featured-image",
|
|
2524
|
-
title:
|
|
2525
|
-
description:
|
|
2526
|
-
fixHint:
|
|
2729
|
+
title: __39("Page featured image", "elementor"),
|
|
2730
|
+
description: __39("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
|
|
2731
|
+
fixHint: __39("Open Page Settings and set a featured image.", "elementor"),
|
|
2527
2732
|
categories: ["seo"],
|
|
2528
2733
|
severity: "info",
|
|
2529
2734
|
weight: 5,
|
|
@@ -2535,8 +2740,8 @@ var audit13 = {
|
|
|
2535
2740
|
status: "fail",
|
|
2536
2741
|
violations: [
|
|
2537
2742
|
{
|
|
2538
|
-
auditId:
|
|
2539
|
-
label:
|
|
2743
|
+
auditId: audit15.id,
|
|
2744
|
+
label: __39("No featured image set.", "elementor"),
|
|
2540
2745
|
targetHint: "page-settings"
|
|
2541
2746
|
}
|
|
2542
2747
|
]
|
|
@@ -2545,13 +2750,13 @@ var audit13 = {
|
|
|
2545
2750
|
};
|
|
2546
2751
|
|
|
2547
2752
|
// src/audits/page-title.ts
|
|
2548
|
-
import { __ as
|
|
2753
|
+
import { __ as __40 } from "@wordpress/i18n";
|
|
2549
2754
|
var MAX_TITLE_LENGTH = 60;
|
|
2550
|
-
var
|
|
2755
|
+
var audit16 = {
|
|
2551
2756
|
id: "audits/page-title",
|
|
2552
|
-
title:
|
|
2553
|
-
description:
|
|
2554
|
-
fixHint:
|
|
2757
|
+
title: __40("Page title", "elementor"),
|
|
2758
|
+
description: __40("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
|
|
2759
|
+
fixHint: __40("Open Page Settings and add a title.", "elementor"),
|
|
2555
2760
|
categories: ["seo"],
|
|
2556
2761
|
severity: "error",
|
|
2557
2762
|
weight: 10,
|
|
@@ -2562,11 +2767,11 @@ var audit14 = {
|
|
|
2562
2767
|
status: "fail",
|
|
2563
2768
|
violations: [
|
|
2564
2769
|
{
|
|
2565
|
-
auditId:
|
|
2566
|
-
label:
|
|
2770
|
+
auditId: audit16.id,
|
|
2771
|
+
label: __40("Page has no title.", "elementor"),
|
|
2567
2772
|
targetHint: "page-settings",
|
|
2568
2773
|
angieFix: true,
|
|
2569
|
-
angiePrompt:
|
|
2774
|
+
angiePrompt: __40(
|
|
2570
2775
|
"Based on this page's contents, generate a title for this page.",
|
|
2571
2776
|
"elementor"
|
|
2572
2777
|
)
|
|
@@ -2579,8 +2784,8 @@ var audit14 = {
|
|
|
2579
2784
|
status: "fail",
|
|
2580
2785
|
violations: [
|
|
2581
2786
|
{
|
|
2582
|
-
auditId:
|
|
2583
|
-
label:
|
|
2787
|
+
auditId: audit16.id,
|
|
2788
|
+
label: __40("Page title is too long.", "elementor"),
|
|
2584
2789
|
targetHint: "page-settings",
|
|
2585
2790
|
angieFix: true
|
|
2586
2791
|
}
|
|
@@ -2592,7 +2797,7 @@ var audit14 = {
|
|
|
2592
2797
|
};
|
|
2593
2798
|
|
|
2594
2799
|
// src/audits/prefer-global-colors.ts
|
|
2595
|
-
import { __ as
|
|
2800
|
+
import { __ as __41, sprintf as sprintf5 } from "@wordpress/i18n";
|
|
2596
2801
|
|
|
2597
2802
|
// src/utils/collect-hardcoded-colors.ts
|
|
2598
2803
|
var RESERVED_SETTING_KEYS = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
|
|
@@ -2658,20 +2863,20 @@ function findMatchingGlobalByValue(value, globals) {
|
|
|
2658
2863
|
}
|
|
2659
2864
|
|
|
2660
2865
|
// src/audits/prefer-global-colors.ts
|
|
2661
|
-
var
|
|
2866
|
+
var audit17 = {
|
|
2662
2867
|
id: "audits/prefer-global-colors",
|
|
2663
|
-
title:
|
|
2664
|
-
description:
|
|
2665
|
-
fixHint:
|
|
2868
|
+
title: __41("Prefer global colors", "elementor"),
|
|
2869
|
+
description: __41("Global colors make the design consistent and easy to update site-wide.", "elementor"),
|
|
2870
|
+
fixHint: __41("Replace the hard-coded value with the matching global color.", "elementor"),
|
|
2666
2871
|
categories: ["best-practices"],
|
|
2667
2872
|
severity: "info",
|
|
2668
2873
|
weight: 3,
|
|
2669
2874
|
evaluate: (ctx) => {
|
|
2670
2875
|
if (ctx.elements.tree.length === 0) {
|
|
2671
|
-
return { status: "skipped", reason:
|
|
2876
|
+
return { status: "skipped", reason: __41("No elements", "elementor") };
|
|
2672
2877
|
}
|
|
2673
2878
|
if (ctx.kit.globals.colors.length === 0) {
|
|
2674
|
-
return { status: "skipped", reason:
|
|
2879
|
+
return { status: "skipped", reason: __41("No global colors", "elementor") };
|
|
2675
2880
|
}
|
|
2676
2881
|
const violations = [];
|
|
2677
2882
|
walkElements(ctx.elements.tree, (node) => {
|
|
@@ -2681,13 +2886,13 @@ var audit15 = {
|
|
|
2681
2886
|
continue;
|
|
2682
2887
|
}
|
|
2683
2888
|
violations.push({
|
|
2684
|
-
auditId:
|
|
2889
|
+
auditId: audit17.id,
|
|
2685
2890
|
elementId: node.id,
|
|
2686
2891
|
targetHint: "element-settings",
|
|
2687
2892
|
angieFix: true,
|
|
2688
2893
|
label: sprintf5(
|
|
2689
2894
|
/* translators: 1: hard-coded color value, 2: global color title. */
|
|
2690
|
-
|
|
2895
|
+
__41('replace "%1$s" with "%2$s" global color', "elementor"),
|
|
2691
2896
|
value,
|
|
2692
2897
|
global.title
|
|
2693
2898
|
)
|
|
@@ -2699,7 +2904,7 @@ var audit15 = {
|
|
|
2699
2904
|
};
|
|
2700
2905
|
|
|
2701
2906
|
// src/audits/prefer-global-fonts.ts
|
|
2702
|
-
import { __ as
|
|
2907
|
+
import { __ as __42, sprintf as sprintf6 } from "@wordpress/i18n";
|
|
2703
2908
|
|
|
2704
2909
|
// src/utils/collect-hardcoded-fonts.ts
|
|
2705
2910
|
var RESERVED_SETTING_KEYS2 = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
|
|
@@ -2757,20 +2962,20 @@ function collectHardcodedFonts(settings, pathPrefix = "") {
|
|
|
2757
2962
|
}
|
|
2758
2963
|
|
|
2759
2964
|
// src/audits/prefer-global-fonts.ts
|
|
2760
|
-
var
|
|
2965
|
+
var audit18 = {
|
|
2761
2966
|
id: "audits/prefer-global-fonts",
|
|
2762
|
-
title:
|
|
2763
|
-
description:
|
|
2764
|
-
fixHint:
|
|
2967
|
+
title: __42("Prefer global fonts", "elementor"),
|
|
2968
|
+
description: __42("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
|
|
2969
|
+
fixHint: __42("Replace the hard-coded value with the matching global font.", "elementor"),
|
|
2765
2970
|
categories: ["best-practices", "performance"],
|
|
2766
2971
|
severity: "info",
|
|
2767
2972
|
weight: 3,
|
|
2768
2973
|
evaluate: (ctx) => {
|
|
2769
2974
|
if (ctx.elements.tree.length === 0) {
|
|
2770
|
-
return { status: "skipped", reason:
|
|
2975
|
+
return { status: "skipped", reason: __42("No elements", "elementor") };
|
|
2771
2976
|
}
|
|
2772
2977
|
if (ctx.kit.globals.fonts.length === 0) {
|
|
2773
|
-
return { status: "skipped", reason:
|
|
2978
|
+
return { status: "skipped", reason: __42("No global fonts", "elementor") };
|
|
2774
2979
|
}
|
|
2775
2980
|
const violations = [];
|
|
2776
2981
|
walkElements(ctx.elements.tree, (node) => {
|
|
@@ -2780,12 +2985,12 @@ var audit16 = {
|
|
|
2780
2985
|
continue;
|
|
2781
2986
|
}
|
|
2782
2987
|
violations.push({
|
|
2783
|
-
auditId:
|
|
2988
|
+
auditId: audit18.id,
|
|
2784
2989
|
elementId: node.id,
|
|
2785
2990
|
targetHint: "element-settings",
|
|
2786
2991
|
label: sprintf6(
|
|
2787
2992
|
/* translators: %s: global font title. */
|
|
2788
|
-
|
|
2993
|
+
__42('replace hardcoded typography with "%s" global font', "elementor"),
|
|
2789
2994
|
global.title
|
|
2790
2995
|
)
|
|
2791
2996
|
});
|
|
@@ -2796,15 +3001,15 @@ var audit16 = {
|
|
|
2796
3001
|
};
|
|
2797
3002
|
|
|
2798
3003
|
// src/audits/privacy-policy.ts
|
|
2799
|
-
import { __ as
|
|
2800
|
-
var
|
|
3004
|
+
import { __ as __43 } from "@wordpress/i18n";
|
|
3005
|
+
var audit19 = {
|
|
2801
3006
|
id: "audits/privacy-policy",
|
|
2802
|
-
title:
|
|
2803
|
-
description:
|
|
3007
|
+
title: __43("Privacy policy", "elementor"),
|
|
3008
|
+
description: __43(
|
|
2804
3009
|
"A privacy policy page is required by privacy regulations such as GDPR (EU) and CCPA (US).",
|
|
2805
3010
|
"elementor"
|
|
2806
3011
|
),
|
|
2807
|
-
fixHint:
|
|
3012
|
+
fixHint: __43(
|
|
2808
3013
|
"Go to Settings > Privacy in the WordPress admin and assign a published privacy policy page.",
|
|
2809
3014
|
"elementor"
|
|
2810
3015
|
),
|
|
@@ -2819,10 +3024,10 @@ var audit17 = {
|
|
|
2819
3024
|
status: "fail",
|
|
2820
3025
|
violations: [
|
|
2821
3026
|
{
|
|
2822
|
-
auditId:
|
|
2823
|
-
label:
|
|
3027
|
+
auditId: audit19.id,
|
|
3028
|
+
label: __43("No privacy policy page is set.", "elementor"),
|
|
2824
3029
|
externalUrl: ctx.pageContext.privacy_settings_url,
|
|
2825
|
-
ctaLabel:
|
|
3030
|
+
ctaLabel: __43("Create", "elementor")
|
|
2826
3031
|
}
|
|
2827
3032
|
]
|
|
2828
3033
|
};
|
|
@@ -2830,15 +3035,15 @@ var audit17 = {
|
|
|
2830
3035
|
};
|
|
2831
3036
|
|
|
2832
3037
|
// src/audits/robots-noindex.ts
|
|
2833
|
-
import { __ as
|
|
2834
|
-
var
|
|
3038
|
+
import { __ as __44 } from "@wordpress/i18n";
|
|
3039
|
+
var audit20 = {
|
|
2835
3040
|
id: "audits/robots-noindex",
|
|
2836
|
-
title:
|
|
2837
|
-
description:
|
|
3041
|
+
title: __44("Search engine visibility", "elementor"),
|
|
3042
|
+
description: __44(
|
|
2838
3043
|
"When search engine visibility is checked in WordPress Settings -> Reading -> Search Engine Visibility, search engines are discouraged from indexing the website.",
|
|
2839
3044
|
"elementor"
|
|
2840
3045
|
),
|
|
2841
|
-
fixHint:
|
|
3046
|
+
fixHint: __44(
|
|
2842
3047
|
'Go to Settings \u2192 Reading in the WordPress admin and uncheck "Discourage search engines from indexing this site" when the website should be indexed.',
|
|
2843
3048
|
"elementor"
|
|
2844
3049
|
),
|
|
@@ -2853,8 +3058,8 @@ var audit18 = {
|
|
|
2853
3058
|
status: "fail",
|
|
2854
3059
|
violations: [
|
|
2855
3060
|
{
|
|
2856
|
-
auditId:
|
|
2857
|
-
label:
|
|
3061
|
+
auditId: audit20.id,
|
|
3062
|
+
label: __44("Search engines are discouraged from indexing this website.", "elementor"),
|
|
2858
3063
|
externalUrl: ctx.pageContext.reading_settings_url
|
|
2859
3064
|
}
|
|
2860
3065
|
]
|
|
@@ -2863,15 +3068,15 @@ var audit18 = {
|
|
|
2863
3068
|
};
|
|
2864
3069
|
|
|
2865
3070
|
// src/audits/scan-for-cookies.ts
|
|
2866
|
-
import { __ as
|
|
2867
|
-
var
|
|
3071
|
+
import { __ as __45 } from "@wordpress/i18n";
|
|
3072
|
+
var audit21 = {
|
|
2868
3073
|
id: "audits/scan-for-cookies",
|
|
2869
|
-
title:
|
|
2870
|
-
description:
|
|
3074
|
+
title: __45("Scan for cookies", "elementor"),
|
|
3075
|
+
description: __45(
|
|
2871
3076
|
"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.",
|
|
2872
3077
|
"elementor"
|
|
2873
3078
|
),
|
|
2874
|
-
fixHint:
|
|
3079
|
+
fixHint: __45("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
|
|
2875
3080
|
categories: ["compliance"],
|
|
2876
3081
|
severity: "info",
|
|
2877
3082
|
weight: 0,
|
|
@@ -2881,8 +3086,8 @@ var audit19 = {
|
|
|
2881
3086
|
status: "fail",
|
|
2882
3087
|
violations: [
|
|
2883
3088
|
{
|
|
2884
|
-
auditId:
|
|
2885
|
-
label:
|
|
3089
|
+
auditId: audit21.id,
|
|
3090
|
+
label: __45("This page has not been scanned for cookies yet.", "elementor"),
|
|
2886
3091
|
externalUrl: isReady ? ctx.pageContext.cookiez_scan_url : ctx.pageContext.cookiez_plugin_action_url
|
|
2887
3092
|
}
|
|
2888
3093
|
]
|
|
@@ -2891,29 +3096,29 @@ var audit19 = {
|
|
|
2891
3096
|
};
|
|
2892
3097
|
|
|
2893
3098
|
// src/audits/sections-and-columns.ts
|
|
2894
|
-
import { __ as
|
|
2895
|
-
var
|
|
3099
|
+
import { __ as __46 } from "@wordpress/i18n";
|
|
3100
|
+
var audit22 = {
|
|
2896
3101
|
id: "audits/sections-and-columns",
|
|
2897
|
-
title:
|
|
2898
|
-
description:
|
|
3102
|
+
title: __46("Sections and columns", "elementor"),
|
|
3103
|
+
description: __46(
|
|
2899
3104
|
"Sections and columns are legacy elements. Containers render fewer DOM nodes and are more flexible.",
|
|
2900
3105
|
"elementor"
|
|
2901
3106
|
),
|
|
2902
|
-
fixHint:
|
|
3107
|
+
fixHint: __46("Use the Container Converter to replace each section/column with a container.", "elementor"),
|
|
2903
3108
|
categories: ["best-practices", "performance"],
|
|
2904
3109
|
severity: "warning",
|
|
2905
3110
|
weight: 7,
|
|
2906
3111
|
evaluate: (ctx) => {
|
|
2907
3112
|
if (ctx.elements.tree.length === 0) {
|
|
2908
|
-
return { status: "skipped", reason:
|
|
3113
|
+
return { status: "skipped", reason: __46("No elements", "elementor") };
|
|
2909
3114
|
}
|
|
2910
3115
|
const violations = [];
|
|
2911
3116
|
walkElements(ctx.elements.tree, (node) => {
|
|
2912
3117
|
if (node.elType === "section" || node.elType === "column") {
|
|
2913
3118
|
violations.push({
|
|
2914
|
-
auditId:
|
|
3119
|
+
auditId: audit22.id,
|
|
2915
3120
|
elementId: node.id,
|
|
2916
|
-
label: node.elType === "section" ?
|
|
3121
|
+
label: node.elType === "section" ? __46("Section element", "elementor") : __46("Column element", "elementor")
|
|
2917
3122
|
});
|
|
2918
3123
|
}
|
|
2919
3124
|
});
|
|
@@ -2922,15 +3127,15 @@ var audit20 = {
|
|
|
2922
3127
|
};
|
|
2923
3128
|
|
|
2924
3129
|
// src/audits/site-identity.ts
|
|
2925
|
-
import { __ as
|
|
2926
|
-
var
|
|
3130
|
+
import { __ as __47 } from "@wordpress/i18n";
|
|
3131
|
+
var audit23 = {
|
|
2927
3132
|
id: "audits/site-identity",
|
|
2928
|
-
title:
|
|
2929
|
-
description:
|
|
3133
|
+
title: __47("Site identity", "elementor"),
|
|
3134
|
+
description: __47(
|
|
2930
3135
|
"Site name, description, logo, and favicon establish your brand and appear in search results and browser tabs.",
|
|
2931
3136
|
"elementor"
|
|
2932
3137
|
),
|
|
2933
|
-
fixHint:
|
|
3138
|
+
fixHint: __47("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
|
|
2934
3139
|
categories: ["best-practices", "seo"],
|
|
2935
3140
|
severity: "info",
|
|
2936
3141
|
weight: 7,
|
|
@@ -2939,30 +3144,30 @@ var audit21 = {
|
|
|
2939
3144
|
const violations = [];
|
|
2940
3145
|
if (!identity.site_name_set) {
|
|
2941
3146
|
violations.push({
|
|
2942
|
-
auditId:
|
|
2943
|
-
label:
|
|
3147
|
+
auditId: audit23.id,
|
|
3148
|
+
label: __47("Site name is missing or still uses the default.", "elementor"),
|
|
2944
3149
|
targetHint: "site-identity-settings"
|
|
2945
3150
|
});
|
|
2946
3151
|
}
|
|
2947
3152
|
if (!identity.site_description_set) {
|
|
2948
3153
|
violations.push({
|
|
2949
|
-
auditId:
|
|
2950
|
-
label:
|
|
3154
|
+
auditId: audit23.id,
|
|
3155
|
+
label: __47("Site description is missing or still uses the default.", "elementor"),
|
|
2951
3156
|
targetHint: "site-identity-settings",
|
|
2952
3157
|
angieFix: true
|
|
2953
3158
|
});
|
|
2954
3159
|
}
|
|
2955
3160
|
if (!identity.site_logo_set) {
|
|
2956
3161
|
violations.push({
|
|
2957
|
-
auditId:
|
|
2958
|
-
label:
|
|
3162
|
+
auditId: audit23.id,
|
|
3163
|
+
label: __47("Site logo is not set.", "elementor"),
|
|
2959
3164
|
targetHint: "site-identity-settings"
|
|
2960
3165
|
});
|
|
2961
3166
|
}
|
|
2962
3167
|
if (!identity.site_favicon_set) {
|
|
2963
3168
|
violations.push({
|
|
2964
|
-
auditId:
|
|
2965
|
-
label:
|
|
3169
|
+
auditId: audit23.id,
|
|
3170
|
+
label: __47("Site favicon is not set.", "elementor"),
|
|
2966
3171
|
targetHint: "site-identity-settings"
|
|
2967
3172
|
});
|
|
2968
3173
|
}
|
|
@@ -2978,7 +3183,7 @@ var audit21 = {
|
|
|
2978
3183
|
|
|
2979
3184
|
// src/audits/too-many-widgets.ts
|
|
2980
3185
|
import { getWidgetsCache as getWidgetsCache3 } from "@elementor/editor-elements";
|
|
2981
|
-
import { __ as
|
|
3186
|
+
import { __ as __48 } from "@wordpress/i18n";
|
|
2982
3187
|
var WIDGET_COUNT_THRESHOLD = 100;
|
|
2983
3188
|
function isCountableWidget(node, widgetsCache) {
|
|
2984
3189
|
if (node.elType === "widget") {
|
|
@@ -2986,17 +3191,17 @@ function isCountableWidget(node, widgetsCache) {
|
|
|
2986
3191
|
}
|
|
2987
3192
|
return !!widgetsCache?.[node.elType]?.meta?.is_compound;
|
|
2988
3193
|
}
|
|
2989
|
-
var
|
|
3194
|
+
var audit24 = {
|
|
2990
3195
|
id: "audits/too-many-widgets",
|
|
2991
|
-
title:
|
|
2992
|
-
description:
|
|
2993
|
-
fixHint:
|
|
3196
|
+
title: __48("Too many widgets", "elementor"),
|
|
3197
|
+
description: __48("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
|
|
3198
|
+
fixHint: __48("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
|
|
2994
3199
|
categories: ["best-practices", "performance"],
|
|
2995
3200
|
severity: "warning",
|
|
2996
3201
|
weight: 5,
|
|
2997
3202
|
evaluate: (ctx) => {
|
|
2998
3203
|
if (ctx.elements.tree.length === 0) {
|
|
2999
|
-
return { status: "skipped", reason:
|
|
3204
|
+
return { status: "skipped", reason: __48("No elements", "elementor") };
|
|
3000
3205
|
}
|
|
3001
3206
|
const widgetsCache = getWidgetsCache3();
|
|
3002
3207
|
let widgetCount = 0;
|
|
@@ -3012,8 +3217,8 @@ var audit22 = {
|
|
|
3012
3217
|
status: "fail",
|
|
3013
3218
|
violations: [
|
|
3014
3219
|
{
|
|
3015
|
-
auditId:
|
|
3016
|
-
label:
|
|
3220
|
+
auditId: audit24.id,
|
|
3221
|
+
label: __48("Page has too many widgets.", "elementor")
|
|
3017
3222
|
}
|
|
3018
3223
|
]
|
|
3019
3224
|
};
|
|
@@ -3022,32 +3227,34 @@ var audit22 = {
|
|
|
3022
3227
|
|
|
3023
3228
|
// src/register-audits.ts
|
|
3024
3229
|
var AUDITS = [
|
|
3230
|
+
audit16,
|
|
3025
3231
|
audit14,
|
|
3026
|
-
audit12,
|
|
3027
|
-
audit13,
|
|
3028
|
-
audit8,
|
|
3029
|
-
audit5,
|
|
3030
|
-
audit22,
|
|
3031
|
-
audit20,
|
|
3032
|
-
audit3,
|
|
3033
|
-
audit11,
|
|
3034
|
-
audit4,
|
|
3035
|
-
audit21,
|
|
3036
3232
|
audit15,
|
|
3037
|
-
audit16,
|
|
3038
|
-
audit7,
|
|
3039
|
-
audit9,
|
|
3040
3233
|
audit10,
|
|
3041
|
-
|
|
3234
|
+
audit7,
|
|
3235
|
+
audit24,
|
|
3236
|
+
audit22,
|
|
3237
|
+
audit5,
|
|
3238
|
+
audit13,
|
|
3239
|
+
audit6,
|
|
3240
|
+
audit23,
|
|
3042
3241
|
audit17,
|
|
3242
|
+
audit18,
|
|
3243
|
+
audit9,
|
|
3244
|
+
audit11,
|
|
3245
|
+
audit12,
|
|
3246
|
+
audit20,
|
|
3247
|
+
audit19,
|
|
3043
3248
|
audit,
|
|
3044
3249
|
audit2,
|
|
3045
|
-
|
|
3046
|
-
|
|
3250
|
+
audit3,
|
|
3251
|
+
audit4,
|
|
3252
|
+
audit21,
|
|
3253
|
+
audit8
|
|
3047
3254
|
];
|
|
3048
3255
|
function registerAllAudits() {
|
|
3049
|
-
for (const
|
|
3050
|
-
registerAudit(
|
|
3256
|
+
for (const audit25 of AUDITS) {
|
|
3257
|
+
registerAudit(audit25);
|
|
3051
3258
|
}
|
|
3052
3259
|
}
|
|
3053
3260
|
|