@elementor/editor-audits 4.4.0-1108 → 4.4.0-1109
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 +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +216 -147
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +213 -144
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/audits/images-inefficient-format.ts +67 -0
- package/src/register-audits.ts +2 -0
- package/src/register-promotions.ts +23 -0
- package/src/types.ts +1 -0
package/dist/index.mjs
CHANGED
|
@@ -103,8 +103,8 @@ async function requestPageContext(documentId, imageSizeRequests, allowNonceRetry
|
|
|
103
103
|
|
|
104
104
|
// src/registry.ts
|
|
105
105
|
var registry = /* @__PURE__ */ new Map();
|
|
106
|
-
function registerAudit(
|
|
107
|
-
registry.set(
|
|
106
|
+
function registerAudit(audit26) {
|
|
107
|
+
registry.set(audit26.id, audit26);
|
|
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(audit26) {
|
|
145
|
+
return audit26.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: audit26, result } of report.auditResults) {
|
|
202
|
+
if (!isScoredAudit(audit26)) {
|
|
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: audit26, result } of results) {
|
|
253
253
|
if (result.status === "skipped") {
|
|
254
254
|
continue;
|
|
255
255
|
}
|
|
256
|
-
for (const category of
|
|
256
|
+
for (const category of audit26.categories) {
|
|
257
257
|
const acc = accumulators[category];
|
|
258
258
|
acc.total++;
|
|
259
|
-
acc.totalWeight +=
|
|
259
|
+
acc.totalWeight += audit26.weight;
|
|
260
260
|
if (result.status === "pass") {
|
|
261
|
-
acc.passedWeight +=
|
|
261
|
+
acc.passedWeight += audit26.weight;
|
|
262
262
|
} else {
|
|
263
263
|
acc.failed++;
|
|
264
264
|
}
|
|
@@ -581,10 +581,10 @@ async function runPageAudit(documentId) {
|
|
|
581
581
|
const ctx = { documentId, elements, pageContext, kit, renderedHtml };
|
|
582
582
|
const registered = getRegisteredAudits();
|
|
583
583
|
const auditResults = await Promise.all(
|
|
584
|
-
registered.map(async (
|
|
585
|
-
const { evaluate: _evaluate, ...meta } =
|
|
584
|
+
registered.map(async (audit26) => {
|
|
585
|
+
const { evaluate: _evaluate, ...meta } = audit26;
|
|
586
586
|
try {
|
|
587
|
-
const result = await
|
|
587
|
+
const result = await audit26.evaluate(ctx);
|
|
588
588
|
return { audit: meta, result };
|
|
589
589
|
} catch (error) {
|
|
590
590
|
const reason = error instanceof Error ? error.message : "unknown-error";
|
|
@@ -1084,13 +1084,13 @@ function ViolationIcon({ violation, widgetIcon }) {
|
|
|
1084
1084
|
function SkipReasonTooltip({ reason }) {
|
|
1085
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" })));
|
|
1086
1086
|
}
|
|
1087
|
-
function StatusIndicator({ audit:
|
|
1087
|
+
function StatusIndicator({ audit: audit26, violations }) {
|
|
1088
1088
|
if (violations) {
|
|
1089
|
-
return /* @__PURE__ */ React11.createElement(React11.Fragment, null, isScoredAudit(
|
|
1089
|
+
return /* @__PURE__ */ React11.createElement(React11.Fragment, null, isScoredAudit(audit26) && /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length), /* @__PURE__ */ React11.createElement(SeverityIcon, { severity: audit26.severity }));
|
|
1090
1090
|
}
|
|
1091
1091
|
return /* @__PURE__ */ React11.createElement(CheckIcon, { fontSize: "small", color: "success" });
|
|
1092
1092
|
}
|
|
1093
|
-
function ViolationRow({ audit:
|
|
1093
|
+
function ViolationRow({ audit: audit26, skipReason, violations }) {
|
|
1094
1094
|
const [expanded, setExpanded] = useState3(false);
|
|
1095
1095
|
const toggleExpanded = () => setExpanded((value) => !value);
|
|
1096
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(
|
|
@@ -1106,8 +1106,8 @@ function ViolationRow({ audit: audit25, skipReason, violations }) {
|
|
|
1106
1106
|
},
|
|
1107
1107
|
onClick: toggleExpanded
|
|
1108
1108
|
},
|
|
1109
|
-
/* @__PURE__ */ React11.createElement(Typography6, { variant: "body2", sx: { flex: 1 } },
|
|
1110
|
-
!skipReason && /* @__PURE__ */ React11.createElement(StatusIndicator, { audit:
|
|
1109
|
+
/* @__PURE__ */ React11.createElement(Typography6, { variant: "body2", sx: { flex: 1 } }, audit26.title),
|
|
1110
|
+
!skipReason && /* @__PURE__ */ React11.createElement(StatusIndicator, { audit: audit26, violations })
|
|
1111
1111
|
), skipReason && /* @__PURE__ */ React11.createElement(SkipReasonTooltip, { reason: skipReason }), /* @__PURE__ */ React11.createElement(
|
|
1112
1112
|
IconButton5,
|
|
1113
1113
|
{
|
|
@@ -1133,7 +1133,7 @@ function ViolationRow({ audit: audit25, skipReason, violations }) {
|
|
|
1133
1133
|
icon: /* @__PURE__ */ React11.createElement(AlertCircleIcon2, { fontSize: "small", color: "secondary", "aria-hidden": true })
|
|
1134
1134
|
},
|
|
1135
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"))),
|
|
1136
|
-
/* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" },
|
|
1136
|
+
/* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit26.description)
|
|
1137
1137
|
), /* @__PURE__ */ React11.createElement(
|
|
1138
1138
|
Alert,
|
|
1139
1139
|
{
|
|
@@ -1142,7 +1142,7 @@ function ViolationRow({ audit: audit25, skipReason, violations }) {
|
|
|
1142
1142
|
icon: /* @__PURE__ */ React11.createElement(BulbIcon2, { fontSize: "small", color: "info", "aria-hidden": true })
|
|
1143
1143
|
},
|
|
1144
1144
|
/* @__PURE__ */ React11.createElement(AlertTitle, null, /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.primary", fontWeight: "bold" }, __11("How to resolve", "elementor"))),
|
|
1145
|
-
/* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" },
|
|
1145
|
+
/* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", component: "p", color: "text.secondary" }, audit26.fixHint)
|
|
1146
1146
|
)), violations && violations.length > 0 && /* @__PURE__ */ React11.createElement(Box7, { role: "list", sx: { paddingBlockEnd: 1, paddingInlineStart: 2 } }, violations.map((violation, idx) => {
|
|
1147
1147
|
const widgetIcon = violation.elementId ? getElementIcon(violation.elementId) : null;
|
|
1148
1148
|
const elementTitle = violation.elementId ? getElementTitle(violation.elementId) : null;
|
|
@@ -1289,17 +1289,17 @@ import { __ as __14 } from "@wordpress/i18n";
|
|
|
1289
1289
|
var ALL_SEVERITIES = ["error", "warning", "info"];
|
|
1290
1290
|
function countSeverities(report, category) {
|
|
1291
1291
|
const counts = { error: 0, warning: 0, info: 0 };
|
|
1292
|
-
for (const { audit:
|
|
1292
|
+
for (const { audit: audit26, result } of report.auditResults) {
|
|
1293
1293
|
if (result.status !== "fail") {
|
|
1294
1294
|
continue;
|
|
1295
1295
|
}
|
|
1296
|
-
if (category && !
|
|
1296
|
+
if (category && !audit26.categories.includes(category)) {
|
|
1297
1297
|
continue;
|
|
1298
1298
|
}
|
|
1299
|
-
if (!isScoredAudit(
|
|
1299
|
+
if (!isScoredAudit(audit26)) {
|
|
1300
1300
|
continue;
|
|
1301
1301
|
}
|
|
1302
|
-
counts[
|
|
1302
|
+
counts[audit26.severity] += result.violations.length;
|
|
1303
1303
|
}
|
|
1304
1304
|
return counts;
|
|
1305
1305
|
}
|
|
@@ -1602,6 +1602,26 @@ var PROMOTIONS = [
|
|
|
1602
1602
|
);
|
|
1603
1603
|
},
|
|
1604
1604
|
getCtaUrl: firstFailExternalUrl
|
|
1605
|
+
},
|
|
1606
|
+
{
|
|
1607
|
+
auditId: "audits/images-inefficient-format",
|
|
1608
|
+
icon: ShieldHalfFilledIcon,
|
|
1609
|
+
ctaLabel: __19("Optimize all", "elementor"),
|
|
1610
|
+
formatSubtitle: (run) => {
|
|
1611
|
+
if (run.result.status !== "fail") {
|
|
1612
|
+
return null;
|
|
1613
|
+
}
|
|
1614
|
+
const count = run.result.metadata?.inefficientImageFormatCount ?? 0;
|
|
1615
|
+
if (count === 0) {
|
|
1616
|
+
return null;
|
|
1617
|
+
}
|
|
1618
|
+
return sprintf3(
|
|
1619
|
+
/* translators: %d: number of images served in an inefficient format. */
|
|
1620
|
+
_n("%d image", "%d images", count, "elementor"),
|
|
1621
|
+
count
|
|
1622
|
+
);
|
|
1623
|
+
},
|
|
1624
|
+
getCtaUrl: firstFailExternalUrl
|
|
1605
1625
|
}
|
|
1606
1626
|
];
|
|
1607
1627
|
|
|
@@ -2603,15 +2623,63 @@ var audit11 = {
|
|
|
2603
2623
|
}
|
|
2604
2624
|
};
|
|
2605
2625
|
|
|
2626
|
+
// src/audits/images-inefficient-format.ts
|
|
2627
|
+
import { __ as __36 } from "@wordpress/i18n";
|
|
2628
|
+
var LEGACY_RASTER_MIME_TYPES = /* @__PURE__ */ new Set(["image/jpeg", "image/png", "image/gif", "image/bmp", "image/tiff"]);
|
|
2629
|
+
var audit12 = {
|
|
2630
|
+
id: "audits/images-inefficient-format",
|
|
2631
|
+
title: __36("Inefficient image format", "elementor"),
|
|
2632
|
+
description: __36("Image isn't served in a modern, efficient format like WebP or AVIF.", "elementor"),
|
|
2633
|
+
fixHint: __36("Convert the image to a modern format like WebP or AVIF, or enable image optimization.", "elementor"),
|
|
2634
|
+
categories: ["performance"],
|
|
2635
|
+
severity: "info",
|
|
2636
|
+
weight: 1,
|
|
2637
|
+
evaluate: (ctx) => {
|
|
2638
|
+
const offendingElementIds = /* @__PURE__ */ new Set();
|
|
2639
|
+
let hasAnyImage = false;
|
|
2640
|
+
let inefficientImageFormatCount = 0;
|
|
2641
|
+
const evaluateSource = (node, media) => {
|
|
2642
|
+
if (media.id || media.url) {
|
|
2643
|
+
hasAnyImage = true;
|
|
2644
|
+
}
|
|
2645
|
+
const id = media.id;
|
|
2646
|
+
if (!id) {
|
|
2647
|
+
return;
|
|
2648
|
+
}
|
|
2649
|
+
const mime = ctx.pageContext.image_sizes[buildImageSizeKey({ id, size: media.size })]?.mime;
|
|
2650
|
+
if (!mime || !LEGACY_RASTER_MIME_TYPES.has(mime)) {
|
|
2651
|
+
return;
|
|
2652
|
+
}
|
|
2653
|
+
inefficientImageFormatCount++;
|
|
2654
|
+
offendingElementIds.add(node.id);
|
|
2655
|
+
};
|
|
2656
|
+
walkImageLikeSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2657
|
+
walkBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2658
|
+
walkAtomicImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2659
|
+
walkAtomicBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2660
|
+
if (!hasAnyImage) {
|
|
2661
|
+
return { status: "skipped", reason: __36("No images", "elementor") };
|
|
2662
|
+
}
|
|
2663
|
+
const violations = Array.from(offendingElementIds).map((elementId) => ({
|
|
2664
|
+
auditId: audit12.id,
|
|
2665
|
+
elementId,
|
|
2666
|
+
targetHint: "element-settings",
|
|
2667
|
+
label: __36("Image isn't served in a modern format like WebP or AVIF.", "elementor"),
|
|
2668
|
+
externalUrl: ctx.pageContext.image_optimization_plugin_url
|
|
2669
|
+
}));
|
|
2670
|
+
return violations.length === 0 ? { status: "pass" } : { status: "fail", violations, metadata: { inefficientImageFormatCount } };
|
|
2671
|
+
}
|
|
2672
|
+
};
|
|
2673
|
+
|
|
2606
2674
|
// src/audits/images-too-large.ts
|
|
2607
|
-
import { __ as
|
|
2675
|
+
import { __ as __37, sprintf as sprintf4 } from "@wordpress/i18n";
|
|
2608
2676
|
var SIZE_THRESHOLD_BYTES = 500 * 1024;
|
|
2609
2677
|
var BYTES_PER_KB = 1024;
|
|
2610
|
-
var
|
|
2678
|
+
var audit13 = {
|
|
2611
2679
|
id: "audits/images-too-large",
|
|
2612
|
-
title:
|
|
2613
|
-
description:
|
|
2614
|
-
fixHint:
|
|
2680
|
+
title: __37("Oversized images", "elementor"),
|
|
2681
|
+
description: __37("Large image files slow down the page.", "elementor"),
|
|
2682
|
+
fixHint: __37("Replace the image with a smaller version or enable image optimization.", "elementor"),
|
|
2615
2683
|
categories: ["performance"],
|
|
2616
2684
|
severity: "warning",
|
|
2617
2685
|
weight: 7,
|
|
@@ -2641,15 +2709,15 @@ var audit12 = {
|
|
|
2641
2709
|
walkAtomicImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2642
2710
|
walkAtomicBackgroundImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2643
2711
|
if (!hasAnyImage) {
|
|
2644
|
-
return { status: "skipped", reason:
|
|
2712
|
+
return { status: "skipped", reason: __37("No images", "elementor") };
|
|
2645
2713
|
}
|
|
2646
2714
|
const violations = Array.from(widgetMaxKb.entries()).map(([elementId, kb]) => ({
|
|
2647
|
-
auditId:
|
|
2715
|
+
auditId: audit13.id,
|
|
2648
2716
|
elementId,
|
|
2649
2717
|
targetHint: "element-settings",
|
|
2650
2718
|
label: sprintf4(
|
|
2651
2719
|
/* translators: %d is the image file size in kilobytes. */
|
|
2652
|
-
|
|
2720
|
+
__37("Image is %d KB (over 500 KB).", "elementor"),
|
|
2653
2721
|
kb
|
|
2654
2722
|
),
|
|
2655
2723
|
externalUrl: ctx.pageContext.image_optimization_plugin_url
|
|
@@ -2659,21 +2727,21 @@ var audit12 = {
|
|
|
2659
2727
|
};
|
|
2660
2728
|
|
|
2661
2729
|
// src/audits/nested-boxed-containers.ts
|
|
2662
|
-
import { __ as
|
|
2730
|
+
import { __ as __38 } from "@wordpress/i18n";
|
|
2663
2731
|
function isBoxed(settings) {
|
|
2664
2732
|
return settings.content_width === "boxed";
|
|
2665
2733
|
}
|
|
2666
|
-
var
|
|
2734
|
+
var audit14 = {
|
|
2667
2735
|
id: "audits/nested-boxed-containers",
|
|
2668
|
-
title:
|
|
2669
|
-
description:
|
|
2670
|
-
fixHint:
|
|
2736
|
+
title: __38("Boxed container nested inside a boxed parent", "elementor"),
|
|
2737
|
+
description: __38("An inner container does not need to be boxed when its parent already is.", "elementor"),
|
|
2738
|
+
fixHint: __38("Change the inner container's content width to Full Width.", "elementor"),
|
|
2671
2739
|
categories: ["best-practices", "performance"],
|
|
2672
2740
|
severity: "info",
|
|
2673
2741
|
weight: 5,
|
|
2674
2742
|
evaluate: (ctx) => {
|
|
2675
2743
|
if (ctx.elements.tree.length === 0) {
|
|
2676
|
-
return { status: "skipped", reason:
|
|
2744
|
+
return { status: "skipped", reason: __38("No elements", "elementor") };
|
|
2677
2745
|
}
|
|
2678
2746
|
const violations = [];
|
|
2679
2747
|
walkElements(ctx.elements.tree, (node, parents) => {
|
|
@@ -2683,10 +2751,10 @@ var audit13 = {
|
|
|
2683
2751
|
const nearestContainerAncestor = [...parents].reverse().find((p) => p.elType === "container");
|
|
2684
2752
|
if (nearestContainerAncestor && isBoxed(nearestContainerAncestor.settings)) {
|
|
2685
2753
|
violations.push({
|
|
2686
|
-
auditId:
|
|
2754
|
+
auditId: audit14.id,
|
|
2687
2755
|
elementId: node.id,
|
|
2688
2756
|
targetHint: "element-settings",
|
|
2689
|
-
label:
|
|
2757
|
+
label: __38("Nested boxed container.", "elementor")
|
|
2690
2758
|
});
|
|
2691
2759
|
}
|
|
2692
2760
|
});
|
|
@@ -2695,12 +2763,12 @@ var audit13 = {
|
|
|
2695
2763
|
};
|
|
2696
2764
|
|
|
2697
2765
|
// src/audits/page-excerpt.ts
|
|
2698
|
-
import { __ as
|
|
2699
|
-
var
|
|
2766
|
+
import { __ as __39 } from "@wordpress/i18n";
|
|
2767
|
+
var audit15 = {
|
|
2700
2768
|
id: "audits/page-excerpt",
|
|
2701
|
-
title:
|
|
2702
|
-
description:
|
|
2703
|
-
fixHint:
|
|
2769
|
+
title: __39("Page excerpt", "elementor"),
|
|
2770
|
+
description: __39("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
|
|
2771
|
+
fixHint: __39("Open Page Settings and write a short excerpt.", "elementor"),
|
|
2704
2772
|
categories: ["seo"],
|
|
2705
2773
|
severity: "warning",
|
|
2706
2774
|
weight: 5,
|
|
@@ -2712,8 +2780,8 @@ var audit14 = {
|
|
|
2712
2780
|
status: "fail",
|
|
2713
2781
|
violations: [
|
|
2714
2782
|
{
|
|
2715
|
-
auditId:
|
|
2716
|
-
label:
|
|
2783
|
+
auditId: audit15.id,
|
|
2784
|
+
label: __39("Page has no excerpt.", "elementor"),
|
|
2717
2785
|
targetHint: "page-settings",
|
|
2718
2786
|
angieFix: true
|
|
2719
2787
|
}
|
|
@@ -2723,12 +2791,12 @@ var audit14 = {
|
|
|
2723
2791
|
};
|
|
2724
2792
|
|
|
2725
2793
|
// src/audits/page-featured-image.ts
|
|
2726
|
-
import { __ as
|
|
2727
|
-
var
|
|
2794
|
+
import { __ as __40 } from "@wordpress/i18n";
|
|
2795
|
+
var audit16 = {
|
|
2728
2796
|
id: "audits/page-featured-image",
|
|
2729
|
-
title:
|
|
2730
|
-
description:
|
|
2731
|
-
fixHint:
|
|
2797
|
+
title: __40("Page featured image", "elementor"),
|
|
2798
|
+
description: __40("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
|
|
2799
|
+
fixHint: __40("Open Page Settings and set a featured image.", "elementor"),
|
|
2732
2800
|
categories: ["seo"],
|
|
2733
2801
|
severity: "info",
|
|
2734
2802
|
weight: 5,
|
|
@@ -2740,8 +2808,8 @@ var audit15 = {
|
|
|
2740
2808
|
status: "fail",
|
|
2741
2809
|
violations: [
|
|
2742
2810
|
{
|
|
2743
|
-
auditId:
|
|
2744
|
-
label:
|
|
2811
|
+
auditId: audit16.id,
|
|
2812
|
+
label: __40("No featured image set.", "elementor"),
|
|
2745
2813
|
targetHint: "page-settings"
|
|
2746
2814
|
}
|
|
2747
2815
|
]
|
|
@@ -2750,13 +2818,13 @@ var audit15 = {
|
|
|
2750
2818
|
};
|
|
2751
2819
|
|
|
2752
2820
|
// src/audits/page-title.ts
|
|
2753
|
-
import { __ as
|
|
2821
|
+
import { __ as __41 } from "@wordpress/i18n";
|
|
2754
2822
|
var MAX_TITLE_LENGTH = 60;
|
|
2755
|
-
var
|
|
2823
|
+
var audit17 = {
|
|
2756
2824
|
id: "audits/page-title",
|
|
2757
|
-
title:
|
|
2758
|
-
description:
|
|
2759
|
-
fixHint:
|
|
2825
|
+
title: __41("Page title", "elementor"),
|
|
2826
|
+
description: __41("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
|
|
2827
|
+
fixHint: __41("Open Page Settings and add a title.", "elementor"),
|
|
2760
2828
|
categories: ["seo"],
|
|
2761
2829
|
severity: "error",
|
|
2762
2830
|
weight: 10,
|
|
@@ -2767,11 +2835,11 @@ var audit16 = {
|
|
|
2767
2835
|
status: "fail",
|
|
2768
2836
|
violations: [
|
|
2769
2837
|
{
|
|
2770
|
-
auditId:
|
|
2771
|
-
label:
|
|
2838
|
+
auditId: audit17.id,
|
|
2839
|
+
label: __41("Page has no title.", "elementor"),
|
|
2772
2840
|
targetHint: "page-settings",
|
|
2773
2841
|
angieFix: true,
|
|
2774
|
-
angiePrompt:
|
|
2842
|
+
angiePrompt: __41(
|
|
2775
2843
|
"Based on this page's contents, generate a title for this page.",
|
|
2776
2844
|
"elementor"
|
|
2777
2845
|
)
|
|
@@ -2784,8 +2852,8 @@ var audit16 = {
|
|
|
2784
2852
|
status: "fail",
|
|
2785
2853
|
violations: [
|
|
2786
2854
|
{
|
|
2787
|
-
auditId:
|
|
2788
|
-
label:
|
|
2855
|
+
auditId: audit17.id,
|
|
2856
|
+
label: __41("Page title is too long.", "elementor"),
|
|
2789
2857
|
targetHint: "page-settings",
|
|
2790
2858
|
angieFix: true
|
|
2791
2859
|
}
|
|
@@ -2797,7 +2865,7 @@ var audit16 = {
|
|
|
2797
2865
|
};
|
|
2798
2866
|
|
|
2799
2867
|
// src/audits/prefer-global-colors.ts
|
|
2800
|
-
import { __ as
|
|
2868
|
+
import { __ as __42, sprintf as sprintf5 } from "@wordpress/i18n";
|
|
2801
2869
|
|
|
2802
2870
|
// src/utils/collect-hardcoded-colors.ts
|
|
2803
2871
|
var RESERVED_SETTING_KEYS = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
|
|
@@ -2863,20 +2931,20 @@ function findMatchingGlobalByValue(value, globals) {
|
|
|
2863
2931
|
}
|
|
2864
2932
|
|
|
2865
2933
|
// src/audits/prefer-global-colors.ts
|
|
2866
|
-
var
|
|
2934
|
+
var audit18 = {
|
|
2867
2935
|
id: "audits/prefer-global-colors",
|
|
2868
|
-
title:
|
|
2869
|
-
description:
|
|
2870
|
-
fixHint:
|
|
2936
|
+
title: __42("Prefer global colors", "elementor"),
|
|
2937
|
+
description: __42("Global colors make the design consistent and easy to update site-wide.", "elementor"),
|
|
2938
|
+
fixHint: __42("Replace the hard-coded value with the matching global color.", "elementor"),
|
|
2871
2939
|
categories: ["best-practices"],
|
|
2872
2940
|
severity: "info",
|
|
2873
2941
|
weight: 3,
|
|
2874
2942
|
evaluate: (ctx) => {
|
|
2875
2943
|
if (ctx.elements.tree.length === 0) {
|
|
2876
|
-
return { status: "skipped", reason:
|
|
2944
|
+
return { status: "skipped", reason: __42("No elements", "elementor") };
|
|
2877
2945
|
}
|
|
2878
2946
|
if (ctx.kit.globals.colors.length === 0) {
|
|
2879
|
-
return { status: "skipped", reason:
|
|
2947
|
+
return { status: "skipped", reason: __42("No global colors", "elementor") };
|
|
2880
2948
|
}
|
|
2881
2949
|
const violations = [];
|
|
2882
2950
|
walkElements(ctx.elements.tree, (node) => {
|
|
@@ -2886,13 +2954,13 @@ var audit17 = {
|
|
|
2886
2954
|
continue;
|
|
2887
2955
|
}
|
|
2888
2956
|
violations.push({
|
|
2889
|
-
auditId:
|
|
2957
|
+
auditId: audit18.id,
|
|
2890
2958
|
elementId: node.id,
|
|
2891
2959
|
targetHint: "element-settings",
|
|
2892
2960
|
angieFix: true,
|
|
2893
2961
|
label: sprintf5(
|
|
2894
2962
|
/* translators: 1: hard-coded color value, 2: global color title. */
|
|
2895
|
-
|
|
2963
|
+
__42('replace "%1$s" with "%2$s" global color', "elementor"),
|
|
2896
2964
|
value,
|
|
2897
2965
|
global.title
|
|
2898
2966
|
)
|
|
@@ -2904,7 +2972,7 @@ var audit17 = {
|
|
|
2904
2972
|
};
|
|
2905
2973
|
|
|
2906
2974
|
// src/audits/prefer-global-fonts.ts
|
|
2907
|
-
import { __ as
|
|
2975
|
+
import { __ as __43, sprintf as sprintf6 } from "@wordpress/i18n";
|
|
2908
2976
|
|
|
2909
2977
|
// src/utils/collect-hardcoded-fonts.ts
|
|
2910
2978
|
var RESERVED_SETTING_KEYS2 = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
|
|
@@ -2962,20 +3030,20 @@ function collectHardcodedFonts(settings, pathPrefix = "") {
|
|
|
2962
3030
|
}
|
|
2963
3031
|
|
|
2964
3032
|
// src/audits/prefer-global-fonts.ts
|
|
2965
|
-
var
|
|
3033
|
+
var audit19 = {
|
|
2966
3034
|
id: "audits/prefer-global-fonts",
|
|
2967
|
-
title:
|
|
2968
|
-
description:
|
|
2969
|
-
fixHint:
|
|
3035
|
+
title: __43("Prefer global fonts", "elementor"),
|
|
3036
|
+
description: __43("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
|
|
3037
|
+
fixHint: __43("Replace the hard-coded value with the matching global font.", "elementor"),
|
|
2970
3038
|
categories: ["best-practices", "performance"],
|
|
2971
3039
|
severity: "info",
|
|
2972
3040
|
weight: 3,
|
|
2973
3041
|
evaluate: (ctx) => {
|
|
2974
3042
|
if (ctx.elements.tree.length === 0) {
|
|
2975
|
-
return { status: "skipped", reason:
|
|
3043
|
+
return { status: "skipped", reason: __43("No elements", "elementor") };
|
|
2976
3044
|
}
|
|
2977
3045
|
if (ctx.kit.globals.fonts.length === 0) {
|
|
2978
|
-
return { status: "skipped", reason:
|
|
3046
|
+
return { status: "skipped", reason: __43("No global fonts", "elementor") };
|
|
2979
3047
|
}
|
|
2980
3048
|
const violations = [];
|
|
2981
3049
|
walkElements(ctx.elements.tree, (node) => {
|
|
@@ -2985,12 +3053,12 @@ var audit18 = {
|
|
|
2985
3053
|
continue;
|
|
2986
3054
|
}
|
|
2987
3055
|
violations.push({
|
|
2988
|
-
auditId:
|
|
3056
|
+
auditId: audit19.id,
|
|
2989
3057
|
elementId: node.id,
|
|
2990
3058
|
targetHint: "element-settings",
|
|
2991
3059
|
label: sprintf6(
|
|
2992
3060
|
/* translators: %s: global font title. */
|
|
2993
|
-
|
|
3061
|
+
__43('replace hardcoded typography with "%s" global font', "elementor"),
|
|
2994
3062
|
global.title
|
|
2995
3063
|
)
|
|
2996
3064
|
});
|
|
@@ -3001,15 +3069,15 @@ var audit18 = {
|
|
|
3001
3069
|
};
|
|
3002
3070
|
|
|
3003
3071
|
// src/audits/privacy-policy.ts
|
|
3004
|
-
import { __ as
|
|
3005
|
-
var
|
|
3072
|
+
import { __ as __44 } from "@wordpress/i18n";
|
|
3073
|
+
var audit20 = {
|
|
3006
3074
|
id: "audits/privacy-policy",
|
|
3007
|
-
title:
|
|
3008
|
-
description:
|
|
3075
|
+
title: __44("Privacy policy", "elementor"),
|
|
3076
|
+
description: __44(
|
|
3009
3077
|
"A privacy policy page is required by privacy regulations such as GDPR (EU) and CCPA (US).",
|
|
3010
3078
|
"elementor"
|
|
3011
3079
|
),
|
|
3012
|
-
fixHint:
|
|
3080
|
+
fixHint: __44(
|
|
3013
3081
|
"Go to Settings > Privacy in the WordPress admin and assign a published privacy policy page.",
|
|
3014
3082
|
"elementor"
|
|
3015
3083
|
),
|
|
@@ -3024,10 +3092,10 @@ var audit19 = {
|
|
|
3024
3092
|
status: "fail",
|
|
3025
3093
|
violations: [
|
|
3026
3094
|
{
|
|
3027
|
-
auditId:
|
|
3028
|
-
label:
|
|
3095
|
+
auditId: audit20.id,
|
|
3096
|
+
label: __44("No privacy policy page is set.", "elementor"),
|
|
3029
3097
|
externalUrl: ctx.pageContext.privacy_settings_url,
|
|
3030
|
-
ctaLabel:
|
|
3098
|
+
ctaLabel: __44("Create", "elementor")
|
|
3031
3099
|
}
|
|
3032
3100
|
]
|
|
3033
3101
|
};
|
|
@@ -3035,15 +3103,15 @@ var audit19 = {
|
|
|
3035
3103
|
};
|
|
3036
3104
|
|
|
3037
3105
|
// src/audits/robots-noindex.ts
|
|
3038
|
-
import { __ as
|
|
3039
|
-
var
|
|
3106
|
+
import { __ as __45 } from "@wordpress/i18n";
|
|
3107
|
+
var audit21 = {
|
|
3040
3108
|
id: "audits/robots-noindex",
|
|
3041
|
-
title:
|
|
3042
|
-
description:
|
|
3109
|
+
title: __45("Search engine visibility", "elementor"),
|
|
3110
|
+
description: __45(
|
|
3043
3111
|
"When search engine visibility is checked in WordPress Settings -> Reading -> Search Engine Visibility, search engines are discouraged from indexing the website.",
|
|
3044
3112
|
"elementor"
|
|
3045
3113
|
),
|
|
3046
|
-
fixHint:
|
|
3114
|
+
fixHint: __45(
|
|
3047
3115
|
'Go to Settings \u2192 Reading in the WordPress admin and uncheck "Discourage search engines from indexing this site" when the website should be indexed.',
|
|
3048
3116
|
"elementor"
|
|
3049
3117
|
),
|
|
@@ -3058,8 +3126,8 @@ var audit20 = {
|
|
|
3058
3126
|
status: "fail",
|
|
3059
3127
|
violations: [
|
|
3060
3128
|
{
|
|
3061
|
-
auditId:
|
|
3062
|
-
label:
|
|
3129
|
+
auditId: audit21.id,
|
|
3130
|
+
label: __45("Search engines are discouraged from indexing this website.", "elementor"),
|
|
3063
3131
|
externalUrl: ctx.pageContext.reading_settings_url
|
|
3064
3132
|
}
|
|
3065
3133
|
]
|
|
@@ -3068,15 +3136,15 @@ var audit20 = {
|
|
|
3068
3136
|
};
|
|
3069
3137
|
|
|
3070
3138
|
// src/audits/scan-for-cookies.ts
|
|
3071
|
-
import { __ as
|
|
3072
|
-
var
|
|
3139
|
+
import { __ as __46 } from "@wordpress/i18n";
|
|
3140
|
+
var audit22 = {
|
|
3073
3141
|
id: "audits/scan-for-cookies",
|
|
3074
|
-
title:
|
|
3075
|
-
description:
|
|
3142
|
+
title: __46("Scan for cookies", "elementor"),
|
|
3143
|
+
description: __46(
|
|
3076
3144
|
"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.",
|
|
3077
3145
|
"elementor"
|
|
3078
3146
|
),
|
|
3079
|
-
fixHint:
|
|
3147
|
+
fixHint: __46("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
|
|
3080
3148
|
categories: ["compliance"],
|
|
3081
3149
|
severity: "info",
|
|
3082
3150
|
weight: 0,
|
|
@@ -3086,8 +3154,8 @@ var audit21 = {
|
|
|
3086
3154
|
status: "fail",
|
|
3087
3155
|
violations: [
|
|
3088
3156
|
{
|
|
3089
|
-
auditId:
|
|
3090
|
-
label:
|
|
3157
|
+
auditId: audit22.id,
|
|
3158
|
+
label: __46("This page has not been scanned for cookies yet.", "elementor"),
|
|
3091
3159
|
externalUrl: isReady ? ctx.pageContext.cookiez_scan_url : ctx.pageContext.cookiez_plugin_action_url
|
|
3092
3160
|
}
|
|
3093
3161
|
]
|
|
@@ -3096,29 +3164,29 @@ var audit21 = {
|
|
|
3096
3164
|
};
|
|
3097
3165
|
|
|
3098
3166
|
// src/audits/sections-and-columns.ts
|
|
3099
|
-
import { __ as
|
|
3100
|
-
var
|
|
3167
|
+
import { __ as __47 } from "@wordpress/i18n";
|
|
3168
|
+
var audit23 = {
|
|
3101
3169
|
id: "audits/sections-and-columns",
|
|
3102
|
-
title:
|
|
3103
|
-
description:
|
|
3170
|
+
title: __47("Sections and columns", "elementor"),
|
|
3171
|
+
description: __47(
|
|
3104
3172
|
"Sections and columns are legacy elements. Containers render fewer DOM nodes and are more flexible.",
|
|
3105
3173
|
"elementor"
|
|
3106
3174
|
),
|
|
3107
|
-
fixHint:
|
|
3175
|
+
fixHint: __47("Use the Container Converter to replace each section/column with a container.", "elementor"),
|
|
3108
3176
|
categories: ["best-practices", "performance"],
|
|
3109
3177
|
severity: "warning",
|
|
3110
3178
|
weight: 7,
|
|
3111
3179
|
evaluate: (ctx) => {
|
|
3112
3180
|
if (ctx.elements.tree.length === 0) {
|
|
3113
|
-
return { status: "skipped", reason:
|
|
3181
|
+
return { status: "skipped", reason: __47("No elements", "elementor") };
|
|
3114
3182
|
}
|
|
3115
3183
|
const violations = [];
|
|
3116
3184
|
walkElements(ctx.elements.tree, (node) => {
|
|
3117
3185
|
if (node.elType === "section" || node.elType === "column") {
|
|
3118
3186
|
violations.push({
|
|
3119
|
-
auditId:
|
|
3187
|
+
auditId: audit23.id,
|
|
3120
3188
|
elementId: node.id,
|
|
3121
|
-
label: node.elType === "section" ?
|
|
3189
|
+
label: node.elType === "section" ? __47("Section element", "elementor") : __47("Column element", "elementor")
|
|
3122
3190
|
});
|
|
3123
3191
|
}
|
|
3124
3192
|
});
|
|
@@ -3127,15 +3195,15 @@ var audit22 = {
|
|
|
3127
3195
|
};
|
|
3128
3196
|
|
|
3129
3197
|
// src/audits/site-identity.ts
|
|
3130
|
-
import { __ as
|
|
3131
|
-
var
|
|
3198
|
+
import { __ as __48 } from "@wordpress/i18n";
|
|
3199
|
+
var audit24 = {
|
|
3132
3200
|
id: "audits/site-identity",
|
|
3133
|
-
title:
|
|
3134
|
-
description:
|
|
3201
|
+
title: __48("Site identity", "elementor"),
|
|
3202
|
+
description: __48(
|
|
3135
3203
|
"Site name, description, logo, and favicon establish your brand and appear in search results and browser tabs.",
|
|
3136
3204
|
"elementor"
|
|
3137
3205
|
),
|
|
3138
|
-
fixHint:
|
|
3206
|
+
fixHint: __48("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
|
|
3139
3207
|
categories: ["best-practices", "seo"],
|
|
3140
3208
|
severity: "info",
|
|
3141
3209
|
weight: 7,
|
|
@@ -3144,30 +3212,30 @@ var audit23 = {
|
|
|
3144
3212
|
const violations = [];
|
|
3145
3213
|
if (!identity.site_name_set) {
|
|
3146
3214
|
violations.push({
|
|
3147
|
-
auditId:
|
|
3148
|
-
label:
|
|
3215
|
+
auditId: audit24.id,
|
|
3216
|
+
label: __48("Site name is missing or still uses the default.", "elementor"),
|
|
3149
3217
|
targetHint: "site-identity-settings"
|
|
3150
3218
|
});
|
|
3151
3219
|
}
|
|
3152
3220
|
if (!identity.site_description_set) {
|
|
3153
3221
|
violations.push({
|
|
3154
|
-
auditId:
|
|
3155
|
-
label:
|
|
3222
|
+
auditId: audit24.id,
|
|
3223
|
+
label: __48("Site description is missing or still uses the default.", "elementor"),
|
|
3156
3224
|
targetHint: "site-identity-settings",
|
|
3157
3225
|
angieFix: true
|
|
3158
3226
|
});
|
|
3159
3227
|
}
|
|
3160
3228
|
if (!identity.site_logo_set) {
|
|
3161
3229
|
violations.push({
|
|
3162
|
-
auditId:
|
|
3163
|
-
label:
|
|
3230
|
+
auditId: audit24.id,
|
|
3231
|
+
label: __48("Site logo is not set.", "elementor"),
|
|
3164
3232
|
targetHint: "site-identity-settings"
|
|
3165
3233
|
});
|
|
3166
3234
|
}
|
|
3167
3235
|
if (!identity.site_favicon_set) {
|
|
3168
3236
|
violations.push({
|
|
3169
|
-
auditId:
|
|
3170
|
-
label:
|
|
3237
|
+
auditId: audit24.id,
|
|
3238
|
+
label: __48("Site favicon is not set.", "elementor"),
|
|
3171
3239
|
targetHint: "site-identity-settings"
|
|
3172
3240
|
});
|
|
3173
3241
|
}
|
|
@@ -3183,7 +3251,7 @@ var audit23 = {
|
|
|
3183
3251
|
|
|
3184
3252
|
// src/audits/too-many-widgets.ts
|
|
3185
3253
|
import { getWidgetsCache as getWidgetsCache3 } from "@elementor/editor-elements";
|
|
3186
|
-
import { __ as
|
|
3254
|
+
import { __ as __49 } from "@wordpress/i18n";
|
|
3187
3255
|
var WIDGET_COUNT_THRESHOLD = 100;
|
|
3188
3256
|
function isCountableWidget(node, widgetsCache) {
|
|
3189
3257
|
if (node.elType === "widget") {
|
|
@@ -3191,17 +3259,17 @@ function isCountableWidget(node, widgetsCache) {
|
|
|
3191
3259
|
}
|
|
3192
3260
|
return !!widgetsCache?.[node.elType]?.meta?.is_compound;
|
|
3193
3261
|
}
|
|
3194
|
-
var
|
|
3262
|
+
var audit25 = {
|
|
3195
3263
|
id: "audits/too-many-widgets",
|
|
3196
|
-
title:
|
|
3197
|
-
description:
|
|
3198
|
-
fixHint:
|
|
3264
|
+
title: __49("Too many widgets", "elementor"),
|
|
3265
|
+
description: __49("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
|
|
3266
|
+
fixHint: __49("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
|
|
3199
3267
|
categories: ["best-practices", "performance"],
|
|
3200
3268
|
severity: "warning",
|
|
3201
3269
|
weight: 5,
|
|
3202
3270
|
evaluate: (ctx) => {
|
|
3203
3271
|
if (ctx.elements.tree.length === 0) {
|
|
3204
|
-
return { status: "skipped", reason:
|
|
3272
|
+
return { status: "skipped", reason: __49("No elements", "elementor") };
|
|
3205
3273
|
}
|
|
3206
3274
|
const widgetsCache = getWidgetsCache3();
|
|
3207
3275
|
let widgetCount = 0;
|
|
@@ -3217,8 +3285,8 @@ var audit24 = {
|
|
|
3217
3285
|
status: "fail",
|
|
3218
3286
|
violations: [
|
|
3219
3287
|
{
|
|
3220
|
-
auditId:
|
|
3221
|
-
label:
|
|
3288
|
+
auditId: audit25.id,
|
|
3289
|
+
label: __49("Page has too many widgets.", "elementor")
|
|
3222
3290
|
}
|
|
3223
3291
|
]
|
|
3224
3292
|
};
|
|
@@ -3227,34 +3295,35 @@ var audit24 = {
|
|
|
3227
3295
|
|
|
3228
3296
|
// src/register-audits.ts
|
|
3229
3297
|
var AUDITS = [
|
|
3230
|
-
|
|
3231
|
-
audit14,
|
|
3298
|
+
audit17,
|
|
3232
3299
|
audit15,
|
|
3300
|
+
audit16,
|
|
3233
3301
|
audit10,
|
|
3234
3302
|
audit7,
|
|
3235
|
-
|
|
3236
|
-
|
|
3303
|
+
audit25,
|
|
3304
|
+
audit23,
|
|
3237
3305
|
audit5,
|
|
3238
|
-
|
|
3306
|
+
audit14,
|
|
3239
3307
|
audit6,
|
|
3240
|
-
|
|
3241
|
-
audit17,
|
|
3308
|
+
audit24,
|
|
3242
3309
|
audit18,
|
|
3310
|
+
audit19,
|
|
3243
3311
|
audit9,
|
|
3244
3312
|
audit11,
|
|
3313
|
+
audit13,
|
|
3245
3314
|
audit12,
|
|
3315
|
+
audit21,
|
|
3246
3316
|
audit20,
|
|
3247
|
-
audit19,
|
|
3248
3317
|
audit,
|
|
3249
3318
|
audit2,
|
|
3250
3319
|
audit3,
|
|
3251
3320
|
audit4,
|
|
3252
|
-
|
|
3321
|
+
audit22,
|
|
3253
3322
|
audit8
|
|
3254
3323
|
];
|
|
3255
3324
|
function registerAllAudits() {
|
|
3256
|
-
for (const
|
|
3257
|
-
registerAudit(
|
|
3325
|
+
for (const audit26 of AUDITS) {
|
|
3326
|
+
registerAudit(audit26);
|
|
3258
3327
|
}
|
|
3259
3328
|
}
|
|
3260
3329
|
|