@elementor/editor-audits 4.3.0-beta1 → 4.3.0-beta3
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 +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +536 -306
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +496 -266
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -13
- package/src/api/page-context-client.ts +27 -8
- package/src/audits/google-consent-mode.ts +68 -0
- package/src/audits/privacy-policy.ts +1 -0
- package/src/audits/scan-for-cookies.ts +30 -0
- package/src/components/status-section.tsx +1 -1
- package/src/components/violation-cta-button.tsx +22 -0
- package/src/components/violation-row.tsx +19 -4
- package/src/hooks/use-audit-report.ts +6 -0
- package/src/register-audits.ts +4 -0
- package/src/register-promotions.ts +8 -0
- package/src/store/slice.ts +3 -0
- package/src/types.ts +6 -0
- package/src/utils/audit-status-summary.ts +11 -2
- package/src/utils/fetch-rendered-html.ts +24 -0
- package/src/utils/is-scored-audit.ts +5 -0
- package/src/utils/scan-consent-signals.ts +19 -0
- package/src/utils/session-expiration.ts +63 -0
- package/src/utils/severity-counts.ts +5 -0
package/dist/index.mjs
CHANGED
|
@@ -13,10 +13,10 @@ import { __ as __22 } from "@wordpress/i18n";
|
|
|
13
13
|
import { createFloatingPanel } from "@elementor/editor-floating-panels";
|
|
14
14
|
|
|
15
15
|
// src/components/audit-panel.tsx
|
|
16
|
-
import * as
|
|
16
|
+
import * as React23 from "react";
|
|
17
17
|
import { getCurrentDocumentId as getCurrentDocumentId2 } from "@elementor/editor-elements";
|
|
18
18
|
import { FloatingPanelBody, FloatingPanelFooter, FloatingPanelHeader } from "@elementor/editor-floating-panels";
|
|
19
|
-
import { Box as Box19, Button as
|
|
19
|
+
import { Box as Box19, Button as Button5, Typography as Typography15 } from "@elementor/ui";
|
|
20
20
|
import { __ as __21 } from "@wordpress/i18n";
|
|
21
21
|
|
|
22
22
|
// src/hooks/use-audit-report.ts
|
|
@@ -39,24 +39,72 @@ function getWindowConfig() {
|
|
|
39
39
|
return config;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
// src/utils/session-expiration.ts
|
|
43
|
+
var NONCE_INVALID_CODE = "rest_cookie_invalid_nonce";
|
|
44
|
+
var DEFAULT_AJAX_URL = "/wp-admin/admin-ajax.php";
|
|
45
|
+
var SessionExpiredError = class extends Error {
|
|
46
|
+
};
|
|
47
|
+
var nonceRefreshPromise = null;
|
|
48
|
+
function isNonceInvalidError(error) {
|
|
49
|
+
const response = error?.response;
|
|
50
|
+
return response?.status === 403 && response?.data?.code === NONCE_INVALID_CODE;
|
|
51
|
+
}
|
|
52
|
+
async function refreshAuditsNonce() {
|
|
53
|
+
if (nonceRefreshPromise) {
|
|
54
|
+
return nonceRefreshPromise;
|
|
55
|
+
}
|
|
56
|
+
nonceRefreshPromise = requestFreshNonce();
|
|
57
|
+
try {
|
|
58
|
+
return await nonceRefreshPromise;
|
|
59
|
+
} finally {
|
|
60
|
+
nonceRefreshPromise = null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function requestFreshNonce() {
|
|
64
|
+
const ajaxUrl = window.elementorCommon?.ajax?.config?.url ?? DEFAULT_AJAX_URL;
|
|
65
|
+
const url = new URL(ajaxUrl, window.location.origin);
|
|
66
|
+
url.searchParams.set("action", "rest-nonce");
|
|
67
|
+
const response = await fetch(url.toString(), { credentials: "same-origin" });
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
throw new Error(`Failed to refresh audits nonce: HTTP ${response.status}`);
|
|
70
|
+
}
|
|
71
|
+
const nonce = await response.text();
|
|
72
|
+
if (!nonce || "0" === nonce) {
|
|
73
|
+
throw new SessionExpiredError("Session expired \u2014 received invalid nonce");
|
|
74
|
+
}
|
|
75
|
+
window.elementorAudits = { ...getWindowConfig(), nonce };
|
|
76
|
+
return nonce;
|
|
77
|
+
}
|
|
78
|
+
|
|
42
79
|
// src/api/page-context-client.ts
|
|
43
80
|
async function fetchPageContext(documentId, attachmentIds) {
|
|
81
|
+
return requestPageContext(documentId, attachmentIds, true);
|
|
82
|
+
}
|
|
83
|
+
async function requestPageContext(documentId, attachmentIds, allowNonceRetry) {
|
|
44
84
|
const { restNamespace, nonce } = getWindowConfig();
|
|
45
85
|
const url = `${restNamespace}/audits/page-context`;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
86
|
+
try {
|
|
87
|
+
const response = await httpService().get(url, {
|
|
88
|
+
params: {
|
|
89
|
+
document_id: documentId,
|
|
90
|
+
attachment_ids: attachmentIds
|
|
91
|
+
},
|
|
92
|
+
headers: { "X-WP-Nonce": nonce }
|
|
93
|
+
});
|
|
94
|
+
return response.data;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
if (!allowNonceRetry || !isNonceInvalidError(error)) {
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
await refreshAuditsNonce();
|
|
100
|
+
return requestPageContext(documentId, attachmentIds, false);
|
|
101
|
+
}
|
|
54
102
|
}
|
|
55
103
|
|
|
56
104
|
// src/registry.ts
|
|
57
105
|
var registry = /* @__PURE__ */ new Map();
|
|
58
|
-
function registerAudit(
|
|
59
|
-
registry.set(
|
|
106
|
+
function registerAudit(audit23) {
|
|
107
|
+
registry.set(audit23.id, audit23);
|
|
60
108
|
}
|
|
61
109
|
function getRegisteredAudits() {
|
|
62
110
|
return Array.from(registry.values());
|
|
@@ -92,6 +140,11 @@ var CATEGORY_LABELS = {
|
|
|
92
140
|
// src/utils/audit-status-summary.ts
|
|
93
141
|
import { __ as __2 } from "@wordpress/i18n";
|
|
94
142
|
|
|
143
|
+
// src/utils/is-scored-audit.ts
|
|
144
|
+
function isScoredAudit(audit23) {
|
|
145
|
+
return audit23.weight > 0;
|
|
146
|
+
}
|
|
147
|
+
|
|
95
148
|
// src/utils/sort-failed-audits.ts
|
|
96
149
|
var SEVERITY_SORTING_RANK = {
|
|
97
150
|
error: 0,
|
|
@@ -122,7 +175,9 @@ function partitionAuditResults(report, options = {}) {
|
|
|
122
175
|
switch (run.result.status) {
|
|
123
176
|
case "fail":
|
|
124
177
|
failed.push({ ...run, result: run.result });
|
|
125
|
-
|
|
178
|
+
if (isScoredAudit(run.audit)) {
|
|
179
|
+
totalViolations += run.result.violations.length;
|
|
180
|
+
}
|
|
126
181
|
break;
|
|
127
182
|
case "pass":
|
|
128
183
|
passed.push({ ...run, result: run.result });
|
|
@@ -143,7 +198,10 @@ function auditStatusDisplayCounts(report) {
|
|
|
143
198
|
let pass = 0;
|
|
144
199
|
let skipped = 0;
|
|
145
200
|
let totalViolations = 0;
|
|
146
|
-
for (const { result } of report.auditResults) {
|
|
201
|
+
for (const { audit: audit23, result } of report.auditResults) {
|
|
202
|
+
if (!isScoredAudit(audit23)) {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
147
205
|
switch (result.status) {
|
|
148
206
|
case "fail":
|
|
149
207
|
totalViolations += result.violations.length;
|
|
@@ -191,16 +249,16 @@ function computeReport(documentId, results) {
|
|
|
191
249
|
const accumulators = Object.fromEntries(
|
|
192
250
|
ALL_CATEGORIES.map((c) => [c, { totalWeight: 0, passedWeight: 0, total: 0, failed: 0 }])
|
|
193
251
|
);
|
|
194
|
-
for (const { audit:
|
|
252
|
+
for (const { audit: audit23, result } of results) {
|
|
195
253
|
if (result.status === "skipped") {
|
|
196
254
|
continue;
|
|
197
255
|
}
|
|
198
|
-
for (const category of
|
|
256
|
+
for (const category of audit23.categories) {
|
|
199
257
|
const acc = accumulators[category];
|
|
200
258
|
acc.total++;
|
|
201
|
-
acc.totalWeight +=
|
|
259
|
+
acc.totalWeight += audit23.weight;
|
|
202
260
|
if (result.status === "pass") {
|
|
203
|
-
acc.passedWeight +=
|
|
261
|
+
acc.passedWeight += audit23.weight;
|
|
204
262
|
} else {
|
|
205
263
|
acc.failed++;
|
|
206
264
|
}
|
|
@@ -389,10 +447,10 @@ async function runPageAudit(documentId) {
|
|
|
389
447
|
const ctx = { documentId, elements, pageContext, kit };
|
|
390
448
|
const registered = getRegisteredAudits();
|
|
391
449
|
const auditResults = await Promise.all(
|
|
392
|
-
registered.map(async (
|
|
393
|
-
const { evaluate: _evaluate, ...meta } =
|
|
450
|
+
registered.map(async (audit23) => {
|
|
451
|
+
const { evaluate: _evaluate, ...meta } = audit23;
|
|
394
452
|
try {
|
|
395
|
-
const result = await
|
|
453
|
+
const result = await audit23.evaluate(ctx);
|
|
396
454
|
return { audit: meta, result };
|
|
397
455
|
} catch (error) {
|
|
398
456
|
const reason = error instanceof Error ? error.message : "unknown-error";
|
|
@@ -422,6 +480,9 @@ var slice = __createSlice({
|
|
|
422
480
|
state.status = "error";
|
|
423
481
|
state.error = action.payload;
|
|
424
482
|
},
|
|
483
|
+
runAborted(state) {
|
|
484
|
+
state.status = state.report ? "ready" : "idle";
|
|
485
|
+
},
|
|
425
486
|
reportRestored(state, action) {
|
|
426
487
|
state.status = "ready";
|
|
427
488
|
state.report = action.payload;
|
|
@@ -483,6 +544,10 @@ function useAuditReport() {
|
|
|
483
544
|
dispatch(slice.actions.runSucceeded(nextReport));
|
|
484
545
|
persistReport(documentIdToRun, nextReport);
|
|
485
546
|
} catch (e) {
|
|
547
|
+
if (e instanceof SessionExpiredError) {
|
|
548
|
+
dispatch(slice.actions.runAborted());
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
486
551
|
dispatch(slice.actions.runFailed(e instanceof Error ? e.message : "Unknown error"));
|
|
487
552
|
}
|
|
488
553
|
};
|
|
@@ -668,13 +733,13 @@ function WelcomePage() {
|
|
|
668
733
|
}
|
|
669
734
|
|
|
670
735
|
// src/components/report-shell.tsx
|
|
671
|
-
import * as
|
|
736
|
+
import * as React22 from "react";
|
|
672
737
|
import { useState as useState4 } from "react";
|
|
673
738
|
import { Box as Box18, Divider as Divider2, Tab, Tabs } from "@elementor/ui";
|
|
674
739
|
import { __ as __20 } from "@wordpress/i18n";
|
|
675
740
|
|
|
676
741
|
// src/components/pages/all-audits-page.tsx
|
|
677
|
-
import * as
|
|
742
|
+
import * as React12 from "react";
|
|
678
743
|
import { Box as Box8 } from "@elementor/ui";
|
|
679
744
|
import { __ as __12 } from "@wordpress/i18n";
|
|
680
745
|
|
|
@@ -686,7 +751,7 @@ import { Box as Box4, Chip, Collapse, IconButton as IconButton2 } from "@element
|
|
|
686
751
|
import { __ as __7 } from "@wordpress/i18n";
|
|
687
752
|
function StatusSection({ label, count, color = "default", defaultExpanded = false, children }) {
|
|
688
753
|
const [expanded, setExpanded] = useState2(defaultExpanded);
|
|
689
|
-
if (count === 0) {
|
|
754
|
+
if (React5.Children.count(children) === 0) {
|
|
690
755
|
return null;
|
|
691
756
|
}
|
|
692
757
|
return /* @__PURE__ */ React5.createElement(Box4, { sx: { paddingBlock: 1 } }, /* @__PURE__ */ React5.createElement(
|
|
@@ -727,7 +792,7 @@ function SubpageHeader({ title, onBack, backLabel, icon }) {
|
|
|
727
792
|
}
|
|
728
793
|
|
|
729
794
|
// src/components/violation-row.tsx
|
|
730
|
-
import * as
|
|
795
|
+
import * as React11 from "react";
|
|
731
796
|
import { useState as useState3 } from "react";
|
|
732
797
|
import { getElementIcon, getElementTitle } from "@elementor/editor-elements";
|
|
733
798
|
import { AlertCircleIcon as AlertCircleIcon2, BulbIcon, CheckIcon, ChevronDownIcon as ChevronDownIcon2, EyeIcon, HelpIcon } from "@elementor/icons";
|
|
@@ -844,13 +909,25 @@ function SeverityIcon({ severity }) {
|
|
|
844
909
|
return /* @__PURE__ */ React8.createElement(Icon, { fontSize: "small", color });
|
|
845
910
|
}
|
|
846
911
|
|
|
847
|
-
// src/components/violation-
|
|
912
|
+
// src/components/violation-cta-button.tsx
|
|
848
913
|
import * as React9 from "react";
|
|
914
|
+
import { Button as Button3 } from "@elementor/ui";
|
|
915
|
+
function ViolationCtaButton({ ctaLabel, externalUrl }) {
|
|
916
|
+
const handleClick = (event) => {
|
|
917
|
+
event.stopPropagation();
|
|
918
|
+
event.preventDefault();
|
|
919
|
+
window.open(externalUrl, "_blank", "noopener");
|
|
920
|
+
};
|
|
921
|
+
return /* @__PURE__ */ React9.createElement(Button3, { variant: "outlined", color: "secondary", size: "small", onClick: handleClick }, ctaLabel);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// src/components/violation-icons.tsx
|
|
925
|
+
import * as React10 from "react";
|
|
849
926
|
import { FileSettingsIcon, SettingsIcon, ShieldCheckIcon } from "@elementor/icons";
|
|
850
927
|
import { Box as Box6 } from "@elementor/ui";
|
|
851
928
|
function ViolationIcon({ violation, widgetIcon }) {
|
|
852
929
|
if (widgetIcon) {
|
|
853
|
-
return /* @__PURE__ */
|
|
930
|
+
return /* @__PURE__ */ React10.createElement(
|
|
854
931
|
Box6,
|
|
855
932
|
{
|
|
856
933
|
component: "i",
|
|
@@ -861,28 +938,28 @@ function ViolationIcon({ violation, widgetIcon }) {
|
|
|
861
938
|
);
|
|
862
939
|
}
|
|
863
940
|
if (violation.targetHint === "page-settings") {
|
|
864
|
-
return /* @__PURE__ */
|
|
941
|
+
return /* @__PURE__ */ React10.createElement(FileSettingsIcon, { fontSize: "inherit", "aria-hidden": true });
|
|
865
942
|
}
|
|
866
943
|
if (violation.targetHint === "site-settings" || violation.targetHint === "site-identity-settings") {
|
|
867
|
-
return /* @__PURE__ */
|
|
944
|
+
return /* @__PURE__ */ React10.createElement(SettingsIcon, { fontSize: "inherit", "aria-hidden": true });
|
|
868
945
|
}
|
|
869
|
-
return /* @__PURE__ */
|
|
946
|
+
return /* @__PURE__ */ React10.createElement(ShieldCheckIcon, { fontSize: "inherit", "aria-hidden": true });
|
|
870
947
|
}
|
|
871
948
|
|
|
872
949
|
// src/components/violation-row.tsx
|
|
873
950
|
function SkipReasonTooltip({ reason }) {
|
|
874
|
-
return /* @__PURE__ */
|
|
951
|
+
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" })));
|
|
875
952
|
}
|
|
876
|
-
function StatusIndicator({ audit:
|
|
953
|
+
function StatusIndicator({ audit: audit23, violations }) {
|
|
877
954
|
if (violations) {
|
|
878
|
-
return /* @__PURE__ */
|
|
955
|
+
return /* @__PURE__ */ React11.createElement(React11.Fragment, null, isScoredAudit(audit23) && /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length), /* @__PURE__ */ React11.createElement(SeverityIcon, { severity: audit23.severity }));
|
|
879
956
|
}
|
|
880
|
-
return /* @__PURE__ */
|
|
957
|
+
return /* @__PURE__ */ React11.createElement(CheckIcon, { fontSize: "small", color: "success" });
|
|
881
958
|
}
|
|
882
|
-
function ViolationRow({ audit:
|
|
959
|
+
function ViolationRow({ audit: audit23, skipReason, violations }) {
|
|
883
960
|
const [expanded, setExpanded] = useState3(false);
|
|
884
961
|
const toggleExpanded = () => setExpanded((value) => !value);
|
|
885
|
-
return /* @__PURE__ */
|
|
962
|
+
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(
|
|
886
963
|
Box7,
|
|
887
964
|
{
|
|
888
965
|
sx: {
|
|
@@ -895,16 +972,16 @@ function ViolationRow({ audit: audit21, skipReason, violations }) {
|
|
|
895
972
|
},
|
|
896
973
|
onClick: toggleExpanded
|
|
897
974
|
},
|
|
898
|
-
/* @__PURE__ */
|
|
899
|
-
!skipReason && /* @__PURE__ */
|
|
900
|
-
), skipReason && /* @__PURE__ */
|
|
975
|
+
/* @__PURE__ */ React11.createElement(Typography6, { variant: "body2", sx: { flex: 1 } }, audit23.title),
|
|
976
|
+
!skipReason && /* @__PURE__ */ React11.createElement(StatusIndicator, { audit: audit23, violations })
|
|
977
|
+
), skipReason && /* @__PURE__ */ React11.createElement(SkipReasonTooltip, { reason: skipReason }), /* @__PURE__ */ React11.createElement(
|
|
901
978
|
IconButton5,
|
|
902
979
|
{
|
|
903
980
|
size: "small",
|
|
904
981
|
"aria-label": expanded ? __11("Collapse", "elementor") : __11("Expand", "elementor"),
|
|
905
982
|
onClick: toggleExpanded
|
|
906
983
|
},
|
|
907
|
-
/* @__PURE__ */
|
|
984
|
+
/* @__PURE__ */ React11.createElement(
|
|
908
985
|
ChevronDownIcon2,
|
|
909
986
|
{
|
|
910
987
|
fontSize: "small",
|
|
@@ -914,29 +991,29 @@ function ViolationRow({ audit: audit21, skipReason, violations }) {
|
|
|
914
991
|
}
|
|
915
992
|
}
|
|
916
993
|
)
|
|
917
|
-
)), /* @__PURE__ */
|
|
994
|
+
)), /* @__PURE__ */ React11.createElement(Collapse2, { in: expanded }, /* @__PURE__ */ React11.createElement(Box7, { sx: { display: "flex", flexDirection: "column", gap: 1, paddingBlock: 1 } }, /* @__PURE__ */ React11.createElement(
|
|
918
995
|
Alert,
|
|
919
996
|
{
|
|
920
997
|
severity: "secondary",
|
|
921
998
|
sx: { p: 1 },
|
|
922
|
-
icon: /* @__PURE__ */
|
|
999
|
+
icon: /* @__PURE__ */ React11.createElement(AlertCircleIcon2, { fontSize: "small", color: "secondary", "aria-hidden": true })
|
|
923
1000
|
},
|
|
924
|
-
/* @__PURE__ */
|
|
925
|
-
/* @__PURE__ */
|
|
926
|
-
), /* @__PURE__ */
|
|
1001
|
+
/* @__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" }, audit23.description)
|
|
1003
|
+
), /* @__PURE__ */ React11.createElement(
|
|
927
1004
|
Alert,
|
|
928
1005
|
{
|
|
929
1006
|
severity: "info",
|
|
930
1007
|
sx: { p: 1 },
|
|
931
|
-
icon: /* @__PURE__ */
|
|
1008
|
+
icon: /* @__PURE__ */ React11.createElement(BulbIcon, { fontSize: "small", color: "info", "aria-hidden": true })
|
|
932
1009
|
},
|
|
933
|
-
/* @__PURE__ */
|
|
934
|
-
/* @__PURE__ */
|
|
935
|
-
)), violations && violations.length > 0 && /* @__PURE__ */
|
|
1010
|
+
/* @__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" }, audit23.fixHint)
|
|
1012
|
+
)), violations && violations.length > 0 && /* @__PURE__ */ React11.createElement(Box7, { role: "list", sx: { paddingBlockEnd: 1, paddingInlineStart: 2 } }, violations.map((violation, idx) => {
|
|
936
1013
|
const widgetIcon = violation.elementId ? getElementIcon(violation.elementId) : null;
|
|
937
1014
|
const elementTitle = violation.elementId ? getElementTitle(violation.elementId) : null;
|
|
938
1015
|
const rowLabel = elementTitle ? `${elementTitle} - ${violation.label}` : violation.label;
|
|
939
|
-
return /* @__PURE__ */
|
|
1016
|
+
return /* @__PURE__ */ React11.createElement(
|
|
940
1017
|
Box7,
|
|
941
1018
|
{
|
|
942
1019
|
key: idx,
|
|
@@ -959,10 +1036,23 @@ function ViolationRow({ audit: audit21, skipReason, violations }) {
|
|
|
959
1036
|
}
|
|
960
1037
|
}
|
|
961
1038
|
},
|
|
962
|
-
/* @__PURE__ */
|
|
963
|
-
/* @__PURE__ */
|
|
964
|
-
violation.angieFix && /* @__PURE__ */
|
|
965
|
-
/* @__PURE__ */
|
|
1039
|
+
/* @__PURE__ */ React11.createElement(ViolationIcon, { violation, widgetIcon }),
|
|
1040
|
+
/* @__PURE__ */ React11.createElement(Box7, { sx: { flex: 1 } }, /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption" }, rowLabel), violation.detail && /* @__PURE__ */ React11.createElement(Typography6, { variant: "caption", color: "text.secondary" }, violation.detail)),
|
|
1041
|
+
violation.angieFix && /* @__PURE__ */ React11.createElement(FixViolationWithAngie, { prompt: buildAngiePrompt(rowLabel) }),
|
|
1042
|
+
violation.ctaLabel && violation.externalUrl ? /* @__PURE__ */ React11.createElement(
|
|
1043
|
+
ViolationCtaButton,
|
|
1044
|
+
{
|
|
1045
|
+
ctaLabel: violation.ctaLabel,
|
|
1046
|
+
externalUrl: violation.externalUrl
|
|
1047
|
+
}
|
|
1048
|
+
) : /* @__PURE__ */ React11.createElement(
|
|
1049
|
+
EyeIcon,
|
|
1050
|
+
{
|
|
1051
|
+
className: "violation-hover-icon",
|
|
1052
|
+
fontSize: "tiny",
|
|
1053
|
+
"aria-hidden": true
|
|
1054
|
+
}
|
|
1055
|
+
)
|
|
966
1056
|
);
|
|
967
1057
|
}))));
|
|
968
1058
|
}
|
|
@@ -973,7 +1063,7 @@ function AllAuditsPage({ initialExpandedStatus, onBack, report }) {
|
|
|
973
1063
|
const expandFail = !initialExpandedStatus || initialExpandedStatus === "fail";
|
|
974
1064
|
const expandPass = initialExpandedStatus === "pass";
|
|
975
1065
|
const expandSkipped = initialExpandedStatus === "skipped";
|
|
976
|
-
return /* @__PURE__ */
|
|
1066
|
+
return /* @__PURE__ */ React12.createElement(Box8, { key: initialExpandedStatus ?? "default" }, /* @__PURE__ */ React12.createElement(SubpageHeader, { title: __12("All audits", "elementor"), onBack }), /* @__PURE__ */ React12.createElement(Box8, { sx: { p: 1 } }, /* @__PURE__ */ React12.createElement(
|
|
977
1067
|
StatusSection,
|
|
978
1068
|
{
|
|
979
1069
|
label: auditStatusLabel("fail"),
|
|
@@ -981,8 +1071,8 @@ function AllAuditsPage({ initialExpandedStatus, onBack, report }) {
|
|
|
981
1071
|
color: auditStatusColor("fail"),
|
|
982
1072
|
defaultExpanded: expandFail
|
|
983
1073
|
},
|
|
984
|
-
failed.map((r) => /* @__PURE__ */
|
|
985
|
-
), /* @__PURE__ */
|
|
1074
|
+
failed.map((r) => /* @__PURE__ */ React12.createElement(ViolationRow, { key: r.audit.id, audit: r.audit, violations: r.result.violations }))
|
|
1075
|
+
), /* @__PURE__ */ React12.createElement(
|
|
986
1076
|
StatusSection,
|
|
987
1077
|
{
|
|
988
1078
|
label: auditStatusLabel("pass"),
|
|
@@ -990,8 +1080,8 @@ function AllAuditsPage({ initialExpandedStatus, onBack, report }) {
|
|
|
990
1080
|
color: auditStatusColor("pass"),
|
|
991
1081
|
defaultExpanded: expandPass
|
|
992
1082
|
},
|
|
993
|
-
passed.map((r) => /* @__PURE__ */
|
|
994
|
-
), /* @__PURE__ */
|
|
1083
|
+
passed.map((r) => /* @__PURE__ */ React12.createElement(ViolationRow, { key: r.audit.id, audit: r.audit }))
|
|
1084
|
+
), /* @__PURE__ */ React12.createElement(
|
|
995
1085
|
StatusSection,
|
|
996
1086
|
{
|
|
997
1087
|
label: auditStatusLabel("skipped"),
|
|
@@ -999,12 +1089,12 @@ function AllAuditsPage({ initialExpandedStatus, onBack, report }) {
|
|
|
999
1089
|
color: auditStatusColor("skipped"),
|
|
1000
1090
|
defaultExpanded: expandSkipped
|
|
1001
1091
|
},
|
|
1002
|
-
skipped.map((r) => /* @__PURE__ */
|
|
1092
|
+
skipped.map((r) => /* @__PURE__ */ React12.createElement(ViolationRow, { key: r.audit.id, audit: r.audit, skipReason: r.result.reason }))
|
|
1003
1093
|
)));
|
|
1004
1094
|
}
|
|
1005
1095
|
|
|
1006
1096
|
// src/components/pages/category-page.tsx
|
|
1007
|
-
import * as
|
|
1097
|
+
import * as React13 from "react";
|
|
1008
1098
|
import { Box as Box9 } from "@elementor/ui";
|
|
1009
1099
|
import { __ as __13 } from "@wordpress/i18n";
|
|
1010
1100
|
|
|
@@ -1028,15 +1118,15 @@ var CATEGORY_ICONS = {
|
|
|
1028
1118
|
function CategoryPage({ category, report, onBack }) {
|
|
1029
1119
|
const Icon = CATEGORY_ICONS[category];
|
|
1030
1120
|
const { failed, passed, totalViolations } = partitionAuditResults(report, { category });
|
|
1031
|
-
return /* @__PURE__ */
|
|
1121
|
+
return /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(
|
|
1032
1122
|
SubpageHeader,
|
|
1033
1123
|
{
|
|
1034
1124
|
title: CATEGORY_LABELS[category],
|
|
1035
1125
|
onBack,
|
|
1036
1126
|
backLabel: __13("Back to all issues", "elementor"),
|
|
1037
|
-
icon: /* @__PURE__ */
|
|
1127
|
+
icon: /* @__PURE__ */ React13.createElement(Icon, { fontSize: "small", color: "action" })
|
|
1038
1128
|
}
|
|
1039
|
-
), /* @__PURE__ */
|
|
1129
|
+
), /* @__PURE__ */ React13.createElement(Box9, { sx: { p: 1 } }, /* @__PURE__ */ React13.createElement(
|
|
1040
1130
|
StatusSection,
|
|
1041
1131
|
{
|
|
1042
1132
|
label: __13("Failed audits", "elementor"),
|
|
@@ -1044,12 +1134,12 @@ function CategoryPage({ category, report, onBack }) {
|
|
|
1044
1134
|
color: "error",
|
|
1045
1135
|
defaultExpanded: true
|
|
1046
1136
|
},
|
|
1047
|
-
failed.map((r) => /* @__PURE__ */
|
|
1048
|
-
), /* @__PURE__ */
|
|
1137
|
+
failed.map((r) => /* @__PURE__ */ React13.createElement(ViolationRow, { key: r.audit.id, audit: r.audit, violations: r.result.violations }))
|
|
1138
|
+
), /* @__PURE__ */ React13.createElement(StatusSection, { label: __13("Passed audits", "elementor"), count: passed.length, color: "success" }, passed.map((r) => /* @__PURE__ */ React13.createElement(ViolationRow, { key: r.audit.id, audit: r.audit })))));
|
|
1049
1139
|
}
|
|
1050
1140
|
|
|
1051
1141
|
// src/components/pages/issues-page.tsx
|
|
1052
|
-
import * as
|
|
1142
|
+
import * as React17 from "react";
|
|
1053
1143
|
import { Box as Box13, Link, Typography as Typography10 } from "@elementor/ui";
|
|
1054
1144
|
import { __ as __17 } from "@wordpress/i18n";
|
|
1055
1145
|
|
|
@@ -1058,14 +1148,17 @@ import { __ as __14, sprintf as sprintf2 } from "@wordpress/i18n";
|
|
|
1058
1148
|
var ALL_SEVERITIES = ["error", "warning", "info"];
|
|
1059
1149
|
function countSeverities(report, category) {
|
|
1060
1150
|
const counts = { error: 0, warning: 0, info: 0 };
|
|
1061
|
-
for (const { audit:
|
|
1151
|
+
for (const { audit: audit23, result } of report.auditResults) {
|
|
1062
1152
|
if (result.status !== "fail") {
|
|
1063
1153
|
continue;
|
|
1064
1154
|
}
|
|
1065
|
-
if (category && !
|
|
1155
|
+
if (category && !audit23.categories.includes(category)) {
|
|
1156
|
+
continue;
|
|
1157
|
+
}
|
|
1158
|
+
if (!isScoredAudit(audit23)) {
|
|
1066
1159
|
continue;
|
|
1067
1160
|
}
|
|
1068
|
-
counts[
|
|
1161
|
+
counts[audit23.severity] += result.violations.length;
|
|
1069
1162
|
}
|
|
1070
1163
|
return counts;
|
|
1071
1164
|
}
|
|
@@ -1103,13 +1196,13 @@ function severityRemainingCountLabel(severity, count) {
|
|
|
1103
1196
|
}
|
|
1104
1197
|
|
|
1105
1198
|
// src/components/issues-category-row.tsx
|
|
1106
|
-
import * as
|
|
1199
|
+
import * as React14 from "react";
|
|
1107
1200
|
import { ChevronRightIcon } from "@elementor/icons";
|
|
1108
1201
|
import { Box as Box10, Rotate as Rotate2, Typography as Typography7, useTheme as useTheme2 } from "@elementor/ui";
|
|
1109
1202
|
function IssuesCategoryRow({ category, label, counts, onClick }) {
|
|
1110
1203
|
const isRtl = "rtl" === useTheme2().direction;
|
|
1111
1204
|
const Icon = CATEGORY_ICONS[category];
|
|
1112
|
-
return /* @__PURE__ */
|
|
1205
|
+
return /* @__PURE__ */ React14.createElement(
|
|
1113
1206
|
Box10,
|
|
1114
1207
|
{
|
|
1115
1208
|
role: "button",
|
|
@@ -1131,15 +1224,15 @@ function IssuesCategoryRow({ category, label, counts, onClick }) {
|
|
|
1131
1224
|
"&:focus-visible": { outline: "2px solid", outlineColor: "primary.main" }
|
|
1132
1225
|
}
|
|
1133
1226
|
},
|
|
1134
|
-
/* @__PURE__ */
|
|
1135
|
-
/* @__PURE__ */
|
|
1136
|
-
/* @__PURE__ */
|
|
1137
|
-
/* @__PURE__ */
|
|
1227
|
+
/* @__PURE__ */ React14.createElement(Icon, { fontSize: "small", color: "action" }),
|
|
1228
|
+
/* @__PURE__ */ React14.createElement(Typography7, { variant: "body2", fontWeight: "bold", sx: { flex: 1 } }, label),
|
|
1229
|
+
/* @__PURE__ */ React14.createElement(Box10, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, ALL_SEVERITIES.filter((s) => counts[s] > 0).map((severity) => /* @__PURE__ */ React14.createElement(Box10, { key: severity, sx: { display: "flex", alignItems: "center", gap: 0.25 } }, /* @__PURE__ */ React14.createElement(SeverityIcon, { severity }), /* @__PURE__ */ React14.createElement(Typography7, { variant: "caption", color: "text.primary", fontWeight: "bold" }, counts[severity])))),
|
|
1230
|
+
/* @__PURE__ */ React14.createElement(Rotate2, { in: isRtl }, /* @__PURE__ */ React14.createElement(ChevronRightIcon, { fontSize: "small", color: "action" }))
|
|
1138
1231
|
);
|
|
1139
1232
|
}
|
|
1140
1233
|
|
|
1141
1234
|
// src/components/promotions.tsx
|
|
1142
|
-
import * as
|
|
1235
|
+
import * as React16 from "react";
|
|
1143
1236
|
import { Box as Box12, Typography as Typography9 } from "@elementor/ui";
|
|
1144
1237
|
import { __ as __16 } from "@wordpress/i18n";
|
|
1145
1238
|
|
|
@@ -1177,6 +1270,13 @@ var PROMOTIONS = [
|
|
|
1177
1270
|
formatSubtitle: (run) => run.result.status === "fail" ? __15("Generate cookie policy", "elementor") : null,
|
|
1178
1271
|
getCtaUrl: firstFailExternalUrl
|
|
1179
1272
|
},
|
|
1273
|
+
{
|
|
1274
|
+
auditId: "audits/scan-for-cookies",
|
|
1275
|
+
icon: ElementorCookieIcon,
|
|
1276
|
+
ctaLabel: __15("Scan", "elementor"),
|
|
1277
|
+
formatSubtitle: (run) => run.result.status === "fail" ? __15("Scan this page for cookies", "elementor") : null,
|
|
1278
|
+
getCtaUrl: firstFailExternalUrl
|
|
1279
|
+
},
|
|
1180
1280
|
{
|
|
1181
1281
|
auditId: "audits/images-too-large",
|
|
1182
1282
|
icon: ShieldHalfFilledIcon2,
|
|
@@ -1205,10 +1305,10 @@ function findAuditRun(report, auditId) {
|
|
|
1205
1305
|
}
|
|
1206
1306
|
|
|
1207
1307
|
// src/components/promotion-card.tsx
|
|
1208
|
-
import * as
|
|
1209
|
-
import { Box as Box11, Button as
|
|
1308
|
+
import * as React15 from "react";
|
|
1309
|
+
import { Box as Box11, Button as Button4, Typography as Typography8 } from "@elementor/ui";
|
|
1210
1310
|
function PromotionCard({ ctaDisabled, ctaLabel, icon: Icon, onCtaClick, subtitle, title }) {
|
|
1211
|
-
return /* @__PURE__ */
|
|
1311
|
+
return /* @__PURE__ */ React15.createElement(
|
|
1212
1312
|
Box11,
|
|
1213
1313
|
{
|
|
1214
1314
|
sx: {
|
|
@@ -1222,9 +1322,9 @@ function PromotionCard({ ctaDisabled, ctaLabel, icon: Icon, onCtaClick, subtitle
|
|
|
1222
1322
|
py: 1.5
|
|
1223
1323
|
}
|
|
1224
1324
|
},
|
|
1225
|
-
/* @__PURE__ */
|
|
1226
|
-
/* @__PURE__ */
|
|
1227
|
-
/* @__PURE__ */
|
|
1325
|
+
/* @__PURE__ */ React15.createElement(Icon, { fontSize: "small", color: "action" }),
|
|
1326
|
+
/* @__PURE__ */ React15.createElement(Box11, { sx: { display: "flex", flex: 1, flexDirection: "column", gap: 0.25, minWidth: 0 } }, /* @__PURE__ */ React15.createElement(Typography8, { variant: "body2", fontWeight: "bold" }, title), /* @__PURE__ */ React15.createElement(Typography8, { variant: "caption", color: "text.secondary" }, subtitle)),
|
|
1327
|
+
/* @__PURE__ */ React15.createElement(Button4, { variant: "outlined", color: "secondary", size: "small", disabled: ctaDisabled, onClick: onCtaClick }, ctaLabel)
|
|
1228
1328
|
);
|
|
1229
1329
|
}
|
|
1230
1330
|
|
|
@@ -1253,7 +1353,7 @@ function Promotions({ report }) {
|
|
|
1253
1353
|
if (cards.length === 0) {
|
|
1254
1354
|
return null;
|
|
1255
1355
|
}
|
|
1256
|
-
return /* @__PURE__ */
|
|
1356
|
+
return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(Typography9, { variant: "subtitle1", fontWeight: "bold" }, __16("Quick wins", "elementor")), /* @__PURE__ */ React16.createElement(Box12, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, cards.map(({ config, ctaUrl, key, run, subtitle }) => /* @__PURE__ */ React16.createElement(
|
|
1257
1357
|
PromotionCard,
|
|
1258
1358
|
{
|
|
1259
1359
|
key,
|
|
@@ -1274,7 +1374,7 @@ function Promotions({ report }) {
|
|
|
1274
1374
|
// src/components/pages/issues-page.tsx
|
|
1275
1375
|
function IssuesPage({ report, onCategoryClick, onAllAuditsClick }) {
|
|
1276
1376
|
const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
|
|
1277
|
-
return /* @__PURE__ */
|
|
1377
|
+
return /* @__PURE__ */ React17.createElement(Box13, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React17.createElement(
|
|
1278
1378
|
Link,
|
|
1279
1379
|
{
|
|
1280
1380
|
component: "button",
|
|
@@ -1283,8 +1383,8 @@ function IssuesPage({ report, onCategoryClick, onAllAuditsClick }) {
|
|
|
1283
1383
|
onClick: onAllAuditsClick,
|
|
1284
1384
|
sx: { textAlign: "start" }
|
|
1285
1385
|
},
|
|
1286
|
-
/* @__PURE__ */
|
|
1287
|
-
), /* @__PURE__ */
|
|
1386
|
+
/* @__PURE__ */ React17.createElement(Typography10, { variant: "subtitle1", component: "h2" }, __17("All issues", "elementor"))
|
|
1387
|
+
), /* @__PURE__ */ React17.createElement(Box13, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, populatedCategories.map((category) => /* @__PURE__ */ React17.createElement(
|
|
1288
1388
|
IssuesCategoryRow,
|
|
1289
1389
|
{
|
|
1290
1390
|
key: category,
|
|
@@ -1293,11 +1393,11 @@ function IssuesPage({ report, onCategoryClick, onAllAuditsClick }) {
|
|
|
1293
1393
|
counts: countSeverities(report, category),
|
|
1294
1394
|
onClick: () => onCategoryClick(category)
|
|
1295
1395
|
}
|
|
1296
|
-
))), /* @__PURE__ */
|
|
1396
|
+
))), /* @__PURE__ */ React17.createElement(Promotions, { report }));
|
|
1297
1397
|
}
|
|
1298
1398
|
|
|
1299
1399
|
// src/components/pages/overview-page.tsx
|
|
1300
|
-
import * as
|
|
1400
|
+
import * as React21 from "react";
|
|
1301
1401
|
import { Box as Box17, Chip as Chip3, Divider, Typography as Typography14 } from "@elementor/ui";
|
|
1302
1402
|
import { __ as __19, sprintf as sprintf4 } from "@wordpress/i18n";
|
|
1303
1403
|
|
|
@@ -1316,7 +1416,7 @@ function getScoreTier(score) {
|
|
|
1316
1416
|
}
|
|
1317
1417
|
|
|
1318
1418
|
// src/components/count-summary-circle.tsx
|
|
1319
|
-
import * as
|
|
1419
|
+
import * as React18 from "react";
|
|
1320
1420
|
import { Box as Box14, Chip as Chip2, Typography as Typography11 } from "@elementor/ui";
|
|
1321
1421
|
var COUNT_SUMMARY_CIRCLE_SIZE = 64;
|
|
1322
1422
|
var COUNT_SUMMARY_BORDER_WIDTH = 4;
|
|
@@ -1327,7 +1427,7 @@ function chipBorderColor(theme, color) {
|
|
|
1327
1427
|
return theme.palette[color].main;
|
|
1328
1428
|
}
|
|
1329
1429
|
function CountSummaryCircle({ ariaLabel, color, count, label, onClick }) {
|
|
1330
|
-
return /* @__PURE__ */
|
|
1430
|
+
return /* @__PURE__ */ React18.createElement(
|
|
1331
1431
|
Box14,
|
|
1332
1432
|
{
|
|
1333
1433
|
"aria-label": ariaLabel,
|
|
@@ -1346,7 +1446,7 @@ function CountSummaryCircle({ ariaLabel, color, count, label, onClick }) {
|
|
|
1346
1446
|
padding: 0
|
|
1347
1447
|
}
|
|
1348
1448
|
},
|
|
1349
|
-
/* @__PURE__ */
|
|
1449
|
+
/* @__PURE__ */ React18.createElement(
|
|
1350
1450
|
Chip2,
|
|
1351
1451
|
{
|
|
1352
1452
|
color,
|
|
@@ -1368,17 +1468,17 @@ function CountSummaryCircle({ ariaLabel, color, count, label, onClick }) {
|
|
|
1368
1468
|
})
|
|
1369
1469
|
}
|
|
1370
1470
|
),
|
|
1371
|
-
/* @__PURE__ */
|
|
1471
|
+
/* @__PURE__ */ React18.createElement(Typography11, { color: "text.secondary", sx: { textAlign: "center" }, variant: "caption" }, label)
|
|
1372
1472
|
);
|
|
1373
1473
|
}
|
|
1374
1474
|
|
|
1375
1475
|
// src/components/score-bar.tsx
|
|
1376
|
-
import * as
|
|
1476
|
+
import * as React19 from "react";
|
|
1377
1477
|
import { ChevronRightIcon as ChevronRightIcon2 } from "@elementor/icons";
|
|
1378
1478
|
import { Box as Box15, LinearProgress, Rotate as Rotate3, Typography as Typography12, useTheme as useTheme3 } from "@elementor/ui";
|
|
1379
1479
|
function ScoreBar({ label, score, onClick }) {
|
|
1380
1480
|
const isRtl = "rtl" === useTheme3().direction;
|
|
1381
|
-
return /* @__PURE__ */
|
|
1481
|
+
return /* @__PURE__ */ React19.createElement(
|
|
1382
1482
|
Box15,
|
|
1383
1483
|
{
|
|
1384
1484
|
role: onClick ? "button" : void 0,
|
|
@@ -1395,8 +1495,8 @@ function ScoreBar({ label, score, onClick }) {
|
|
|
1395
1495
|
py: 0.5
|
|
1396
1496
|
}
|
|
1397
1497
|
},
|
|
1398
|
-
/* @__PURE__ */
|
|
1399
|
-
/* @__PURE__ */
|
|
1498
|
+
/* @__PURE__ */ React19.createElement(Typography12, { variant: "body2", sx: { minWidth: 96 } }, label),
|
|
1499
|
+
/* @__PURE__ */ React19.createElement(
|
|
1400
1500
|
LinearProgress,
|
|
1401
1501
|
{
|
|
1402
1502
|
variant: "determinate",
|
|
@@ -1405,7 +1505,7 @@ function ScoreBar({ label, score, onClick }) {
|
|
|
1405
1505
|
sx: { flex: 1, height: 6, borderRadius: 4, bgcolor: "action.disabledBackground" }
|
|
1406
1506
|
}
|
|
1407
1507
|
),
|
|
1408
|
-
/* @__PURE__ */
|
|
1508
|
+
/* @__PURE__ */ React19.createElement(
|
|
1409
1509
|
Typography12,
|
|
1410
1510
|
{
|
|
1411
1511
|
variant: "body2",
|
|
@@ -1414,18 +1514,18 @@ function ScoreBar({ label, score, onClick }) {
|
|
|
1414
1514
|
},
|
|
1415
1515
|
score
|
|
1416
1516
|
),
|
|
1417
|
-
onClick && /* @__PURE__ */
|
|
1517
|
+
onClick && /* @__PURE__ */ React19.createElement(Rotate3, { in: isRtl }, /* @__PURE__ */ React19.createElement(ChevronRightIcon2, { fontSize: "small", color: "action" }))
|
|
1418
1518
|
);
|
|
1419
1519
|
}
|
|
1420
1520
|
|
|
1421
1521
|
// src/components/score-circle.tsx
|
|
1422
|
-
import * as
|
|
1522
|
+
import * as React20 from "react";
|
|
1423
1523
|
import { Box as Box16, CircularProgress as CircularProgress2, Typography as Typography13 } from "@elementor/ui";
|
|
1424
1524
|
var SCORE_CIRCLE_SIZE = 88;
|
|
1425
1525
|
var SCORE_CIRCLE_THICKNESS = 3;
|
|
1426
1526
|
function ScoreCircle({ color, score }) {
|
|
1427
1527
|
const progressColor = color ?? getScoreTier(score).color;
|
|
1428
|
-
return /* @__PURE__ */
|
|
1528
|
+
return /* @__PURE__ */ React20.createElement(
|
|
1429
1529
|
Box16,
|
|
1430
1530
|
{
|
|
1431
1531
|
role: "progressbar",
|
|
@@ -1434,7 +1534,7 @@ function ScoreCircle({ color, score }) {
|
|
|
1434
1534
|
"aria-valuemax": 100,
|
|
1435
1535
|
sx: { position: "relative", display: "inline-flex" }
|
|
1436
1536
|
},
|
|
1437
|
-
/* @__PURE__ */
|
|
1537
|
+
/* @__PURE__ */ React20.createElement(
|
|
1438
1538
|
CircularProgress2,
|
|
1439
1539
|
{
|
|
1440
1540
|
variant: "determinate",
|
|
@@ -1444,7 +1544,7 @@ function ScoreCircle({ color, score }) {
|
|
|
1444
1544
|
sx: { color: "action.disabledBackground" }
|
|
1445
1545
|
}
|
|
1446
1546
|
),
|
|
1447
|
-
/* @__PURE__ */
|
|
1547
|
+
/* @__PURE__ */ React20.createElement(
|
|
1448
1548
|
CircularProgress2,
|
|
1449
1549
|
{
|
|
1450
1550
|
variant: "determinate",
|
|
@@ -1455,7 +1555,7 @@ function ScoreCircle({ color, score }) {
|
|
|
1455
1555
|
sx: { position: "absolute", left: 0 }
|
|
1456
1556
|
}
|
|
1457
1557
|
),
|
|
1458
|
-
/* @__PURE__ */
|
|
1558
|
+
/* @__PURE__ */ React20.createElement(
|
|
1459
1559
|
Box16,
|
|
1460
1560
|
{
|
|
1461
1561
|
sx: {
|
|
@@ -1466,7 +1566,7 @@ function ScoreCircle({ color, score }) {
|
|
|
1466
1566
|
justifyContent: "center"
|
|
1467
1567
|
}
|
|
1468
1568
|
},
|
|
1469
|
-
/* @__PURE__ */
|
|
1569
|
+
/* @__PURE__ */ React20.createElement(
|
|
1470
1570
|
Typography13,
|
|
1471
1571
|
{
|
|
1472
1572
|
variant: "h4",
|
|
@@ -1504,7 +1604,7 @@ function OverviewPage({ onCategoryClick, onStatusClick, report }) {
|
|
|
1504
1604
|
const severityCounts = countSeverities(report);
|
|
1505
1605
|
const statusCounts = auditStatusDisplayCounts(report);
|
|
1506
1606
|
const overallScore = getScoreTier(report.overall);
|
|
1507
|
-
return /* @__PURE__ */
|
|
1607
|
+
return /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", alignItems: "center", gap: 2 } }, /* @__PURE__ */ React21.createElement(ScoreCircle, { color: overallScore.color, score: report.overall }), /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", flexDirection: "column", gap: 0.5 } }, /* @__PURE__ */ React21.createElement(
|
|
1508
1608
|
Chip3,
|
|
1509
1609
|
{
|
|
1510
1610
|
label: overallScore.label,
|
|
@@ -1513,7 +1613,7 @@ function OverviewPage({ onCategoryClick, onStatusClick, report }) {
|
|
|
1513
1613
|
size: "small",
|
|
1514
1614
|
sx: { fontWeight: 600, alignSelf: "flex-start" }
|
|
1515
1615
|
}
|
|
1516
|
-
), /* @__PURE__ */
|
|
1616
|
+
), /* @__PURE__ */ React21.createElement(Typography14, { variant: "body2", color: "text.secondary" }, __19("Overall score", "elementor")))), /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", flexDirection: "column", gap: 2 } }, populatedCategories.map((category) => /* @__PURE__ */ React21.createElement(
|
|
1517
1617
|
ScoreBar,
|
|
1518
1618
|
{
|
|
1519
1619
|
key: category,
|
|
@@ -1521,7 +1621,7 @@ function OverviewPage({ onCategoryClick, onStatusClick, report }) {
|
|
|
1521
1621
|
score: report.categories[category].score,
|
|
1522
1622
|
onClick: () => onCategoryClick(category)
|
|
1523
1623
|
}
|
|
1524
|
-
))), /* @__PURE__ */
|
|
1624
|
+
))), /* @__PURE__ */ React21.createElement(Divider, null), /* @__PURE__ */ React21.createElement(Typography14, { variant: "subtitle1", fontWeight: "bold" }, __19("Audit statuses", "elementor")), /* @__PURE__ */ React21.createElement(Box17, { sx: { display: "flex", justifyContent: "space-around", gap: 2 } }, STATUS_GROUPS.map((status) => /* @__PURE__ */ React21.createElement(
|
|
1525
1625
|
CountSummaryCircle,
|
|
1526
1626
|
{
|
|
1527
1627
|
key: status,
|
|
@@ -1531,7 +1631,7 @@ function OverviewPage({ onCategoryClick, onStatusClick, report }) {
|
|
|
1531
1631
|
label: auditStatusLabel(status),
|
|
1532
1632
|
onClick: () => onStatusClick(status)
|
|
1533
1633
|
}
|
|
1534
|
-
))), /* @__PURE__ */
|
|
1634
|
+
))), /* @__PURE__ */ React21.createElement(Divider, null), /* @__PURE__ */ React21.createElement(Typography14, { variant: "subtitle1", fontWeight: "bold" }, __19("Remaining issues", "elementor")), /* @__PURE__ */ React21.createElement(
|
|
1535
1635
|
Box17,
|
|
1536
1636
|
{
|
|
1537
1637
|
component: "ul",
|
|
@@ -1546,7 +1646,7 @@ function OverviewPage({ onCategoryClick, onStatusClick, report }) {
|
|
|
1546
1646
|
},
|
|
1547
1647
|
ALL_SEVERITIES.map((severity) => {
|
|
1548
1648
|
const count = severityCounts[severity];
|
|
1549
|
-
return /* @__PURE__ */
|
|
1649
|
+
return /* @__PURE__ */ React21.createElement(
|
|
1550
1650
|
Box17,
|
|
1551
1651
|
{
|
|
1552
1652
|
"aria-label": severityRemainingCountLabel(severity, count),
|
|
@@ -1554,9 +1654,9 @@ function OverviewPage({ onCategoryClick, onStatusClick, report }) {
|
|
|
1554
1654
|
key: severity,
|
|
1555
1655
|
sx: { alignItems: "center", display: "flex", gap: 0.5 }
|
|
1556
1656
|
},
|
|
1557
|
-
/* @__PURE__ */
|
|
1558
|
-
/* @__PURE__ */
|
|
1559
|
-
/* @__PURE__ */
|
|
1657
|
+
/* @__PURE__ */ React21.createElement(SeverityIcon, { severity }),
|
|
1658
|
+
/* @__PURE__ */ React21.createElement(Typography14, { variant: "body2", fontWeight: "bold" }, count),
|
|
1659
|
+
/* @__PURE__ */ React21.createElement(Typography14, { variant: "body2" }, severityPluralLabel(severity))
|
|
1560
1660
|
);
|
|
1561
1661
|
})
|
|
1562
1662
|
));
|
|
@@ -1595,7 +1695,7 @@ function ReportShell({ report }) {
|
|
|
1595
1695
|
setActivePage(activePage.backTo);
|
|
1596
1696
|
}
|
|
1597
1697
|
};
|
|
1598
|
-
return /* @__PURE__ */
|
|
1698
|
+
return /* @__PURE__ */ React22.createElement(Box18, null, /* @__PURE__ */ React22.createElement(
|
|
1599
1699
|
Tabs,
|
|
1600
1700
|
{
|
|
1601
1701
|
"aria-label": __20("Audit navigation", "elementor"),
|
|
@@ -1607,30 +1707,30 @@ function ReportShell({ report }) {
|
|
|
1607
1707
|
centered: true,
|
|
1608
1708
|
variant: "fullWidth"
|
|
1609
1709
|
},
|
|
1610
|
-
/* @__PURE__ */
|
|
1611
|
-
/* @__PURE__ */
|
|
1612
|
-
), /* @__PURE__ */
|
|
1710
|
+
/* @__PURE__ */ React22.createElement(Tab, { value: "overview", label: __20("Overview", "elementor") }),
|
|
1711
|
+
/* @__PURE__ */ React22.createElement(Tab, { value: "issues", label: __20("Issues", "elementor") })
|
|
1712
|
+
), /* @__PURE__ */ React22.createElement(Divider2, null), activePage === "overview" && /* @__PURE__ */ React22.createElement(
|
|
1613
1713
|
OverviewPage,
|
|
1614
1714
|
{
|
|
1615
1715
|
report,
|
|
1616
1716
|
onCategoryClick: (category) => openCategory(category, "overview"),
|
|
1617
1717
|
onStatusClick: (status) => openAllAudits(status, "overview")
|
|
1618
1718
|
}
|
|
1619
|
-
), activePage === "issues" && /* @__PURE__ */
|
|
1719
|
+
), activePage === "issues" && /* @__PURE__ */ React22.createElement(
|
|
1620
1720
|
IssuesPage,
|
|
1621
1721
|
{
|
|
1622
1722
|
report,
|
|
1623
1723
|
onCategoryClick: (category) => openCategory(category, "issues"),
|
|
1624
1724
|
onAllAuditsClick: () => openAllAudits()
|
|
1625
1725
|
}
|
|
1626
|
-
), isAllAuditsPage(activePage) && /* @__PURE__ */
|
|
1726
|
+
), isAllAuditsPage(activePage) && /* @__PURE__ */ React22.createElement(
|
|
1627
1727
|
AllAuditsPage,
|
|
1628
1728
|
{
|
|
1629
1729
|
report,
|
|
1630
1730
|
initialExpandedStatus: activePage.expand,
|
|
1631
1731
|
onBack: backFromSubPage
|
|
1632
1732
|
}
|
|
1633
|
-
), isCategoryPage(activePage) && /* @__PURE__ */
|
|
1733
|
+
), isCategoryPage(activePage) && /* @__PURE__ */ React22.createElement(CategoryPage, { category: activePage.category, report, onBack: backFromSubPage }));
|
|
1634
1734
|
}
|
|
1635
1735
|
|
|
1636
1736
|
// src/components/audit-panel.tsx
|
|
@@ -1639,7 +1739,7 @@ function AuditPanel() {
|
|
|
1639
1739
|
const currentDocumentId = getCurrentDocumentId2() ?? 0;
|
|
1640
1740
|
const onRun = () => run(currentDocumentId);
|
|
1641
1741
|
const lastScanLabel = report ? new Date(report.runAt).toLocaleTimeString() : null;
|
|
1642
|
-
return /* @__PURE__ */
|
|
1742
|
+
return /* @__PURE__ */ React23.createElement(React23.Fragment, null, /* @__PURE__ */ React23.createElement(
|
|
1643
1743
|
FloatingPanelHeader,
|
|
1644
1744
|
{
|
|
1645
1745
|
panelId: "audit-panel",
|
|
@@ -1647,8 +1747,8 @@ function AuditPanel() {
|
|
|
1647
1747
|
badge: __21("Beta", "elementor"),
|
|
1648
1748
|
titleVariant: "subtitle2"
|
|
1649
1749
|
}
|
|
1650
|
-
), /* @__PURE__ */
|
|
1651
|
-
|
|
1750
|
+
), /* @__PURE__ */ React23.createElement(FloatingPanelBody, null, status === "idle" && /* @__PURE__ */ React23.createElement(WelcomePage, null), status === "loading" && /* @__PURE__ */ React23.createElement(LoadingPage, null), status === "error" && /* @__PURE__ */ React23.createElement(ErrorPage, { message: error ?? "", onRetry: onRun }), status === "ready" && report && /* @__PURE__ */ React23.createElement(ReportShell, { report })), /* @__PURE__ */ React23.createElement(FloatingPanelFooter, null, lastScanLabel ? /* @__PURE__ */ React23.createElement(Typography15, { variant: "caption", sx: { flex: 1 } }, __21("Last scan:", "elementor"), " ", lastScanLabel) : /* @__PURE__ */ React23.createElement(Box19, { sx: { flex: 1 } }), lastScanLabel && /* @__PURE__ */ React23.createElement(AuditFeedback, null), /* @__PURE__ */ React23.createElement(
|
|
1751
|
+
Button5,
|
|
1652
1752
|
{
|
|
1653
1753
|
variant: "contained",
|
|
1654
1754
|
size: "small",
|
|
@@ -1869,8 +1969,107 @@ var audit5 = {
|
|
|
1869
1969
|
}
|
|
1870
1970
|
};
|
|
1871
1971
|
|
|
1872
|
-
// src/audits/
|
|
1972
|
+
// src/audits/google-consent-mode.ts
|
|
1873
1973
|
import { __ as __28 } from "@wordpress/i18n";
|
|
1974
|
+
|
|
1975
|
+
// src/utils/fetch-rendered-html.ts
|
|
1976
|
+
var FETCH_TIMEOUT_MS = 1e4;
|
|
1977
|
+
async function fetchRenderedHtml(url) {
|
|
1978
|
+
if (!url) {
|
|
1979
|
+
return null;
|
|
1980
|
+
}
|
|
1981
|
+
const timeoutController = new AbortController();
|
|
1982
|
+
const timeoutId = setTimeout(() => timeoutController.abort(), FETCH_TIMEOUT_MS);
|
|
1983
|
+
try {
|
|
1984
|
+
const response = await fetch(url, { credentials: "omit", signal: timeoutController.signal });
|
|
1985
|
+
if (!response.ok) {
|
|
1986
|
+
return null;
|
|
1987
|
+
}
|
|
1988
|
+
return await response.text();
|
|
1989
|
+
} catch {
|
|
1990
|
+
return null;
|
|
1991
|
+
} finally {
|
|
1992
|
+
clearTimeout(timeoutId);
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
// src/utils/scan-consent-signals.ts
|
|
1997
|
+
var GOOGLE_TRACKING_PATTERNS = [
|
|
1998
|
+
/googletagmanager\.com\/gtag\/js\?id=(G|AW)-/,
|
|
1999
|
+
/googletagmanager\.com\/gtm\.js/,
|
|
2000
|
+
/\bGTM-[A-Z0-9]+\b/,
|
|
2001
|
+
/gtag\(\s*['"]config['"]\s*,\s*['"](G|AW)-/
|
|
2002
|
+
];
|
|
2003
|
+
var CONSENT_DEFAULT_PATTERNS = [
|
|
2004
|
+
/gtag\(\s*['"]consent['"]\s*,\s*['"]default['"]/,
|
|
2005
|
+
/dataLayer\.push\(\s*\[\s*['"]consent['"]\s*,\s*['"]default['"]/
|
|
2006
|
+
];
|
|
2007
|
+
function hasGoogleTracking(html) {
|
|
2008
|
+
return GOOGLE_TRACKING_PATTERNS.some((pattern) => pattern.test(html));
|
|
2009
|
+
}
|
|
2010
|
+
function hasConsentDefaultCall(html) {
|
|
2011
|
+
return CONSENT_DEFAULT_PATTERNS.some((pattern) => pattern.test(html));
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
// src/audits/google-consent-mode.ts
|
|
2015
|
+
var audit6 = {
|
|
2016
|
+
id: "audits/google-consent-mode",
|
|
2017
|
+
title: __28("Google Consent Mode", "elementor"),
|
|
2018
|
+
description: __28(
|
|
2019
|
+
"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.",
|
|
2020
|
+
"elementor"
|
|
2021
|
+
),
|
|
2022
|
+
fixHint: __28(
|
|
2023
|
+
"Turn on Google Consent Mode in your cookie consent plugin so Google tags respect visitor consent choices.",
|
|
2024
|
+
"elementor"
|
|
2025
|
+
),
|
|
2026
|
+
categories: ["compliance"],
|
|
2027
|
+
severity: "warning",
|
|
2028
|
+
weight: 1,
|
|
2029
|
+
evaluate: async (ctx) => {
|
|
2030
|
+
if (!ctx.pageContext.frontend_url) {
|
|
2031
|
+
return { status: "skipped", reason: __28("Page is not published.", "elementor") };
|
|
2032
|
+
}
|
|
2033
|
+
const html = await fetchRenderedHtml(ctx.pageContext.frontend_url);
|
|
2034
|
+
if (!html) {
|
|
2035
|
+
return { status: "skipped", reason: __28("Could not fetch the published page.", "elementor") };
|
|
2036
|
+
}
|
|
2037
|
+
if (!hasGoogleTracking(html)) {
|
|
2038
|
+
return { status: "skipped", reason: __28("No Google tracking product detected.", "elementor") };
|
|
2039
|
+
}
|
|
2040
|
+
if (hasConsentDefaultCall(html)) {
|
|
2041
|
+
return { status: "pass" };
|
|
2042
|
+
}
|
|
2043
|
+
const label = __28("No Google Consent Mode signal was found on the page.", "elementor");
|
|
2044
|
+
const isCookiezReady = ctx.pageContext.cookiez_plugin_installed && ctx.pageContext.cookiez_plugin_active;
|
|
2045
|
+
if (isCookiezReady) {
|
|
2046
|
+
return {
|
|
2047
|
+
status: "fail",
|
|
2048
|
+
violations: [
|
|
2049
|
+
{
|
|
2050
|
+
auditId: audit6.id,
|
|
2051
|
+
label,
|
|
2052
|
+
ctaLabel: __28("Enable", "elementor"),
|
|
2053
|
+
externalUrl: ctx.pageContext.cookiez_consent_mode_settings_url
|
|
2054
|
+
}
|
|
2055
|
+
]
|
|
2056
|
+
};
|
|
2057
|
+
}
|
|
2058
|
+
return {
|
|
2059
|
+
status: "fail",
|
|
2060
|
+
violations: [
|
|
2061
|
+
{
|
|
2062
|
+
auditId: audit6.id,
|
|
2063
|
+
label,
|
|
2064
|
+
externalUrl: ctx.pageContext.cookiez_plugin_action_url
|
|
2065
|
+
}
|
|
2066
|
+
]
|
|
2067
|
+
};
|
|
2068
|
+
}
|
|
2069
|
+
};
|
|
2070
|
+
|
|
2071
|
+
// src/audits/heading-structure.ts
|
|
2072
|
+
import { __ as __29 } from "@wordpress/i18n";
|
|
1874
2073
|
var HEADING_LEVELS = ["h1", "h2", "h3", "h4", "h5", "h6"];
|
|
1875
2074
|
var HEADING_CONTROLS_REGISTRY = {
|
|
1876
2075
|
// Core
|
|
@@ -2046,47 +2245,47 @@ function extractPageHeadings(tree) {
|
|
|
2046
2245
|
});
|
|
2047
2246
|
return headings;
|
|
2048
2247
|
}
|
|
2049
|
-
var
|
|
2248
|
+
var audit7 = {
|
|
2050
2249
|
id: "audits/heading-structure",
|
|
2051
|
-
title:
|
|
2052
|
-
description:
|
|
2053
|
-
fixHint:
|
|
2250
|
+
title: __29("Heading structure", "elementor"),
|
|
2251
|
+
description: __29("Pages should have exactly one H1 and a non-skipping heading order.", "elementor"),
|
|
2252
|
+
fixHint: __29("Ensure your page has one H1 and that heading levels do not skip (no H2 \u2192 H4).", "elementor"),
|
|
2054
2253
|
categories: ["seo", "accessibility"],
|
|
2055
2254
|
severity: "error",
|
|
2056
2255
|
weight: 10,
|
|
2057
2256
|
evaluate: (ctx) => {
|
|
2058
2257
|
if (ctx.elements.tree.length === 0) {
|
|
2059
|
-
return { status: "skipped", reason:
|
|
2258
|
+
return { status: "skipped", reason: __29("No elements", "elementor") };
|
|
2060
2259
|
}
|
|
2061
2260
|
const headings = extractPageHeadings(ctx.elements.tree);
|
|
2062
2261
|
const violations = [];
|
|
2063
2262
|
if (headings.length === 0) {
|
|
2064
2263
|
violations.push({
|
|
2065
|
-
auditId:
|
|
2066
|
-
label:
|
|
2264
|
+
auditId: audit7.id,
|
|
2265
|
+
label: __29("No headings found on the page.", "elementor")
|
|
2067
2266
|
});
|
|
2068
2267
|
} else {
|
|
2069
2268
|
const h1Count = headings.filter((h) => h.level === 1).length;
|
|
2070
2269
|
if (h1Count === 0) {
|
|
2071
|
-
violations.push({ auditId:
|
|
2270
|
+
violations.push({ auditId: audit7.id, label: __29("No H1 on the page.", "elementor") });
|
|
2072
2271
|
}
|
|
2073
2272
|
if (h1Count > 1) {
|
|
2074
2273
|
headings.filter((h) => h.level === 1).slice(1).forEach(
|
|
2075
2274
|
(h) => violations.push({
|
|
2076
|
-
auditId:
|
|
2275
|
+
auditId: audit7.id,
|
|
2077
2276
|
elementId: h.elementId,
|
|
2078
2277
|
targetHint: "element-settings",
|
|
2079
|
-
label:
|
|
2278
|
+
label: __29("More than one H1 on the page.", "elementor")
|
|
2080
2279
|
})
|
|
2081
2280
|
);
|
|
2082
2281
|
}
|
|
2083
2282
|
for (let i = 1; i < headings.length; i++) {
|
|
2084
2283
|
if (headings[i].level - headings[i - 1].level > 1) {
|
|
2085
2284
|
violations.push({
|
|
2086
|
-
auditId:
|
|
2285
|
+
auditId: audit7.id,
|
|
2087
2286
|
elementId: headings[i].elementId,
|
|
2088
2287
|
targetHint: "element-settings",
|
|
2089
|
-
label:
|
|
2288
|
+
label: __29("Heading level skipped.", "elementor")
|
|
2090
2289
|
});
|
|
2091
2290
|
}
|
|
2092
2291
|
}
|
|
@@ -2096,33 +2295,33 @@ var audit6 = {
|
|
|
2096
2295
|
};
|
|
2097
2296
|
|
|
2098
2297
|
// src/audits/hidden-elements.ts
|
|
2099
|
-
import { __ as
|
|
2298
|
+
import { __ as __30 } from "@wordpress/i18n";
|
|
2100
2299
|
function isHiddenOnAllDevices(settings) {
|
|
2101
2300
|
return Boolean(settings.hide_desktop) && Boolean(settings.hide_tablet) && Boolean(settings.hide_mobile);
|
|
2102
2301
|
}
|
|
2103
|
-
var
|
|
2302
|
+
var audit8 = {
|
|
2104
2303
|
id: "audits/hidden-elements",
|
|
2105
|
-
title:
|
|
2106
|
-
description:
|
|
2304
|
+
title: __30("Hidden elements", "elementor"),
|
|
2305
|
+
description: __30(
|
|
2107
2306
|
"Elements hidden on all devices simultaneously are effectively dead code in the page tree.",
|
|
2108
2307
|
"elementor"
|
|
2109
2308
|
),
|
|
2110
|
-
fixHint:
|
|
2309
|
+
fixHint: __30("Remove the element or make it visible on at least one device breakpoint.", "elementor"),
|
|
2111
2310
|
categories: ["best-practices", "performance"],
|
|
2112
2311
|
severity: "info",
|
|
2113
2312
|
weight: 3,
|
|
2114
2313
|
evaluate: (ctx) => {
|
|
2115
2314
|
if (ctx.elements.tree.length === 0) {
|
|
2116
|
-
return { status: "skipped", reason:
|
|
2315
|
+
return { status: "skipped", reason: __30("No elements", "elementor") };
|
|
2117
2316
|
}
|
|
2118
2317
|
const violations = [];
|
|
2119
2318
|
walkElements(ctx.elements.tree, (node) => {
|
|
2120
2319
|
if (isHiddenOnAllDevices(node.settings)) {
|
|
2121
2320
|
violations.push({
|
|
2122
|
-
auditId:
|
|
2321
|
+
auditId: audit8.id,
|
|
2123
2322
|
elementId: node.id,
|
|
2124
2323
|
targetHint: "element-settings",
|
|
2125
|
-
label:
|
|
2324
|
+
label: __30("Element is hidden on all devices.", "elementor")
|
|
2126
2325
|
});
|
|
2127
2326
|
}
|
|
2128
2327
|
});
|
|
@@ -2131,7 +2330,7 @@ var audit7 = {
|
|
|
2131
2330
|
};
|
|
2132
2331
|
|
|
2133
2332
|
// src/audits/images-alt-text.ts
|
|
2134
|
-
import { __ as
|
|
2333
|
+
import { __ as __31 } from "@wordpress/i18n";
|
|
2135
2334
|
|
|
2136
2335
|
// src/utils/image-alt.ts
|
|
2137
2336
|
function hasMeaningfulAlt(media, pageContext) {
|
|
@@ -2149,17 +2348,17 @@ function isImageSourcePresent(media) {
|
|
|
2149
2348
|
}
|
|
2150
2349
|
|
|
2151
2350
|
// src/audits/images-alt-text.ts
|
|
2152
|
-
var
|
|
2351
|
+
var audit9 = {
|
|
2153
2352
|
id: "audits/images-alt-text",
|
|
2154
|
-
title:
|
|
2155
|
-
description:
|
|
2156
|
-
fixHint:
|
|
2353
|
+
title: __31("Images alt text", "elementor"),
|
|
2354
|
+
description: __31("Every image needs a meaningful alt attribute for screen readers and image-search.", "elementor"),
|
|
2355
|
+
fixHint: __31("Open the image's settings and add an Alt Text describing the image.", "elementor"),
|
|
2157
2356
|
categories: ["seo", "accessibility"],
|
|
2158
2357
|
severity: "error",
|
|
2159
2358
|
weight: 10,
|
|
2160
2359
|
evaluate: (ctx) => {
|
|
2161
2360
|
if (!hasPageImages(ctx.elements.tree)) {
|
|
2162
|
-
return { status: "skipped", reason:
|
|
2361
|
+
return { status: "skipped", reason: __31("No images", "elementor") };
|
|
2163
2362
|
}
|
|
2164
2363
|
const violations = [];
|
|
2165
2364
|
const failedWidgetIds = /* @__PURE__ */ new Set();
|
|
@@ -2172,10 +2371,10 @@ var audit8 = {
|
|
|
2172
2371
|
if (!failedWidgetIds.has(node.id)) {
|
|
2173
2372
|
failedWidgetIds.add(node.id);
|
|
2174
2373
|
violations.push({
|
|
2175
|
-
auditId:
|
|
2374
|
+
auditId: audit9.id,
|
|
2176
2375
|
elementId: node.id,
|
|
2177
2376
|
targetHint: "element-settings",
|
|
2178
|
-
label:
|
|
2377
|
+
label: __31("Image is missing alt text.", "elementor"),
|
|
2179
2378
|
externalUrl: ctx.pageContext.ally_plugin_url
|
|
2180
2379
|
});
|
|
2181
2380
|
}
|
|
@@ -2185,20 +2384,20 @@ var audit8 = {
|
|
|
2185
2384
|
};
|
|
2186
2385
|
|
|
2187
2386
|
// src/audits/images-too-large.ts
|
|
2188
|
-
import { __ as
|
|
2387
|
+
import { __ as __32, sprintf as sprintf5 } from "@wordpress/i18n";
|
|
2189
2388
|
var SIZE_THRESHOLD_BYTES = 500 * 1024;
|
|
2190
2389
|
var BYTES_PER_KB = 1024;
|
|
2191
|
-
var
|
|
2390
|
+
var audit10 = {
|
|
2192
2391
|
id: "audits/images-too-large",
|
|
2193
|
-
title:
|
|
2194
|
-
description:
|
|
2195
|
-
fixHint:
|
|
2392
|
+
title: __32("Oversized images", "elementor"),
|
|
2393
|
+
description: __32("Large image files slow down the page.", "elementor"),
|
|
2394
|
+
fixHint: __32("Replace the image with a smaller version or enable image optimization.", "elementor"),
|
|
2196
2395
|
categories: ["performance"],
|
|
2197
2396
|
severity: "warning",
|
|
2198
2397
|
weight: 7,
|
|
2199
2398
|
evaluate: (ctx) => {
|
|
2200
2399
|
if (!hasPageImages(ctx.elements.tree)) {
|
|
2201
|
-
return { status: "skipped", reason:
|
|
2400
|
+
return { status: "skipped", reason: __32("No images", "elementor") };
|
|
2202
2401
|
}
|
|
2203
2402
|
const widgetMaxKb = /* @__PURE__ */ new Map();
|
|
2204
2403
|
let oversizedImageCount = 0;
|
|
@@ -2217,12 +2416,12 @@ var audit9 = {
|
|
|
2217
2416
|
widgetMaxKb.set(node.id, Math.max(currentMax, kb));
|
|
2218
2417
|
});
|
|
2219
2418
|
const violations = Array.from(widgetMaxKb.entries()).map(([elementId, kb]) => ({
|
|
2220
|
-
auditId:
|
|
2419
|
+
auditId: audit10.id,
|
|
2221
2420
|
elementId,
|
|
2222
2421
|
targetHint: "element-settings",
|
|
2223
2422
|
label: sprintf5(
|
|
2224
2423
|
/* translators: %d is the image file size in kilobytes. */
|
|
2225
|
-
|
|
2424
|
+
__32("Image is %d KB (over 500 KB).", "elementor"),
|
|
2226
2425
|
kb
|
|
2227
2426
|
),
|
|
2228
2427
|
externalUrl: ctx.pageContext.image_optimization_plugin_url
|
|
@@ -2232,21 +2431,21 @@ var audit9 = {
|
|
|
2232
2431
|
};
|
|
2233
2432
|
|
|
2234
2433
|
// src/audits/nested-boxed-containers.ts
|
|
2235
|
-
import { __ as
|
|
2434
|
+
import { __ as __33 } from "@wordpress/i18n";
|
|
2236
2435
|
function isBoxed(settings) {
|
|
2237
2436
|
return settings.content_width === "boxed";
|
|
2238
2437
|
}
|
|
2239
|
-
var
|
|
2438
|
+
var audit11 = {
|
|
2240
2439
|
id: "audits/nested-boxed-containers",
|
|
2241
|
-
title:
|
|
2242
|
-
description:
|
|
2243
|
-
fixHint:
|
|
2440
|
+
title: __33("Boxed container nested inside a boxed parent", "elementor"),
|
|
2441
|
+
description: __33("An inner container does not need to be boxed when its parent already is.", "elementor"),
|
|
2442
|
+
fixHint: __33("Change the inner container's content width to Full Width.", "elementor"),
|
|
2244
2443
|
categories: ["best-practices", "performance"],
|
|
2245
2444
|
severity: "info",
|
|
2246
2445
|
weight: 5,
|
|
2247
2446
|
evaluate: (ctx) => {
|
|
2248
2447
|
if (ctx.elements.tree.length === 0) {
|
|
2249
|
-
return { status: "skipped", reason:
|
|
2448
|
+
return { status: "skipped", reason: __33("No elements", "elementor") };
|
|
2250
2449
|
}
|
|
2251
2450
|
const violations = [];
|
|
2252
2451
|
walkElements(ctx.elements.tree, (node, parents) => {
|
|
@@ -2256,10 +2455,10 @@ var audit10 = {
|
|
|
2256
2455
|
const nearestContainerAncestor = [...parents].reverse().find((p) => p.elType === "container");
|
|
2257
2456
|
if (nearestContainerAncestor && isBoxed(nearestContainerAncestor.settings)) {
|
|
2258
2457
|
violations.push({
|
|
2259
|
-
auditId:
|
|
2458
|
+
auditId: audit11.id,
|
|
2260
2459
|
elementId: node.id,
|
|
2261
2460
|
targetHint: "element-settings",
|
|
2262
|
-
label:
|
|
2461
|
+
label: __33("Nested boxed container.", "elementor")
|
|
2263
2462
|
});
|
|
2264
2463
|
}
|
|
2265
2464
|
});
|
|
@@ -2268,12 +2467,12 @@ var audit10 = {
|
|
|
2268
2467
|
};
|
|
2269
2468
|
|
|
2270
2469
|
// src/audits/page-excerpt.ts
|
|
2271
|
-
import { __ as
|
|
2272
|
-
var
|
|
2470
|
+
import { __ as __34 } from "@wordpress/i18n";
|
|
2471
|
+
var audit12 = {
|
|
2273
2472
|
id: "audits/page-excerpt",
|
|
2274
|
-
title:
|
|
2275
|
-
description:
|
|
2276
|
-
fixHint:
|
|
2473
|
+
title: __34("Page excerpt", "elementor"),
|
|
2474
|
+
description: __34("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
|
|
2475
|
+
fixHint: __34("Open Page Settings and write a short excerpt.", "elementor"),
|
|
2277
2476
|
categories: ["seo"],
|
|
2278
2477
|
severity: "warning",
|
|
2279
2478
|
weight: 5,
|
|
@@ -2285,8 +2484,8 @@ var audit11 = {
|
|
|
2285
2484
|
status: "fail",
|
|
2286
2485
|
violations: [
|
|
2287
2486
|
{
|
|
2288
|
-
auditId:
|
|
2289
|
-
label:
|
|
2487
|
+
auditId: audit12.id,
|
|
2488
|
+
label: __34("Page has no excerpt.", "elementor"),
|
|
2290
2489
|
targetHint: "page-settings",
|
|
2291
2490
|
angieFix: true
|
|
2292
2491
|
}
|
|
@@ -2296,12 +2495,12 @@ var audit11 = {
|
|
|
2296
2495
|
};
|
|
2297
2496
|
|
|
2298
2497
|
// src/audits/page-featured-image.ts
|
|
2299
|
-
import { __ as
|
|
2300
|
-
var
|
|
2498
|
+
import { __ as __35 } from "@wordpress/i18n";
|
|
2499
|
+
var audit13 = {
|
|
2301
2500
|
id: "audits/page-featured-image",
|
|
2302
|
-
title:
|
|
2303
|
-
description:
|
|
2304
|
-
fixHint:
|
|
2501
|
+
title: __35("Page featured image", "elementor"),
|
|
2502
|
+
description: __35("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
|
|
2503
|
+
fixHint: __35("Open Page Settings and set a featured image.", "elementor"),
|
|
2305
2504
|
categories: ["seo"],
|
|
2306
2505
|
severity: "info",
|
|
2307
2506
|
weight: 5,
|
|
@@ -2313,8 +2512,8 @@ var audit12 = {
|
|
|
2313
2512
|
status: "fail",
|
|
2314
2513
|
violations: [
|
|
2315
2514
|
{
|
|
2316
|
-
auditId:
|
|
2317
|
-
label:
|
|
2515
|
+
auditId: audit13.id,
|
|
2516
|
+
label: __35("No featured image set.", "elementor"),
|
|
2318
2517
|
targetHint: "page-settings"
|
|
2319
2518
|
}
|
|
2320
2519
|
]
|
|
@@ -2323,13 +2522,13 @@ var audit12 = {
|
|
|
2323
2522
|
};
|
|
2324
2523
|
|
|
2325
2524
|
// src/audits/page-title.ts
|
|
2326
|
-
import { __ as
|
|
2525
|
+
import { __ as __36 } from "@wordpress/i18n";
|
|
2327
2526
|
var MAX_TITLE_LENGTH = 60;
|
|
2328
|
-
var
|
|
2527
|
+
var audit14 = {
|
|
2329
2528
|
id: "audits/page-title",
|
|
2330
|
-
title:
|
|
2331
|
-
description:
|
|
2332
|
-
fixHint:
|
|
2529
|
+
title: __36("Page title", "elementor"),
|
|
2530
|
+
description: __36("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
|
|
2531
|
+
fixHint: __36("Open Page Settings and add a title.", "elementor"),
|
|
2333
2532
|
categories: ["seo"],
|
|
2334
2533
|
severity: "error",
|
|
2335
2534
|
weight: 10,
|
|
@@ -2340,8 +2539,8 @@ var audit13 = {
|
|
|
2340
2539
|
status: "fail",
|
|
2341
2540
|
violations: [
|
|
2342
2541
|
{
|
|
2343
|
-
auditId:
|
|
2344
|
-
label:
|
|
2542
|
+
auditId: audit14.id,
|
|
2543
|
+
label: __36("Page has no title.", "elementor"),
|
|
2345
2544
|
targetHint: "page-settings",
|
|
2346
2545
|
angieFix: true
|
|
2347
2546
|
}
|
|
@@ -2353,8 +2552,8 @@ var audit13 = {
|
|
|
2353
2552
|
status: "fail",
|
|
2354
2553
|
violations: [
|
|
2355
2554
|
{
|
|
2356
|
-
auditId:
|
|
2357
|
-
label:
|
|
2555
|
+
auditId: audit14.id,
|
|
2556
|
+
label: __36("Page title is too long.", "elementor"),
|
|
2358
2557
|
targetHint: "page-settings",
|
|
2359
2558
|
angieFix: true
|
|
2360
2559
|
}
|
|
@@ -2366,7 +2565,7 @@ var audit13 = {
|
|
|
2366
2565
|
};
|
|
2367
2566
|
|
|
2368
2567
|
// src/audits/prefer-global-colors.ts
|
|
2369
|
-
import { __ as
|
|
2568
|
+
import { __ as __37, sprintf as sprintf6 } from "@wordpress/i18n";
|
|
2370
2569
|
|
|
2371
2570
|
// src/utils/collect-hardcoded-colors.ts
|
|
2372
2571
|
var RESERVED_SETTING_KEYS = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
|
|
@@ -2432,20 +2631,20 @@ function findMatchingGlobalByValue(value, globals) {
|
|
|
2432
2631
|
}
|
|
2433
2632
|
|
|
2434
2633
|
// src/audits/prefer-global-colors.ts
|
|
2435
|
-
var
|
|
2634
|
+
var audit15 = {
|
|
2436
2635
|
id: "audits/prefer-global-colors",
|
|
2437
|
-
title:
|
|
2438
|
-
description:
|
|
2439
|
-
fixHint:
|
|
2636
|
+
title: __37("Prefer global colors", "elementor"),
|
|
2637
|
+
description: __37("Global colors make the design consistent and easy to update site-wide.", "elementor"),
|
|
2638
|
+
fixHint: __37("Replace the hard-coded value with the matching global color.", "elementor"),
|
|
2440
2639
|
categories: ["best-practices"],
|
|
2441
2640
|
severity: "info",
|
|
2442
2641
|
weight: 3,
|
|
2443
2642
|
evaluate: (ctx) => {
|
|
2444
2643
|
if (ctx.elements.tree.length === 0) {
|
|
2445
|
-
return { status: "skipped", reason:
|
|
2644
|
+
return { status: "skipped", reason: __37("No elements", "elementor") };
|
|
2446
2645
|
}
|
|
2447
2646
|
if (ctx.kit.globals.colors.length === 0) {
|
|
2448
|
-
return { status: "skipped", reason:
|
|
2647
|
+
return { status: "skipped", reason: __37("No global colors", "elementor") };
|
|
2449
2648
|
}
|
|
2450
2649
|
const violations = [];
|
|
2451
2650
|
walkElements(ctx.elements.tree, (node) => {
|
|
@@ -2455,13 +2654,13 @@ var audit14 = {
|
|
|
2455
2654
|
continue;
|
|
2456
2655
|
}
|
|
2457
2656
|
violations.push({
|
|
2458
|
-
auditId:
|
|
2657
|
+
auditId: audit15.id,
|
|
2459
2658
|
elementId: node.id,
|
|
2460
2659
|
targetHint: "element-settings",
|
|
2461
2660
|
angieFix: true,
|
|
2462
2661
|
label: sprintf6(
|
|
2463
2662
|
/* translators: 1: hard-coded color value, 2: global color title. */
|
|
2464
|
-
|
|
2663
|
+
__37('replace "%1$s" with "%2$s" global color', "elementor"),
|
|
2465
2664
|
value,
|
|
2466
2665
|
global.title
|
|
2467
2666
|
)
|
|
@@ -2473,7 +2672,7 @@ var audit14 = {
|
|
|
2473
2672
|
};
|
|
2474
2673
|
|
|
2475
2674
|
// src/audits/prefer-global-fonts.ts
|
|
2476
|
-
import { __ as
|
|
2675
|
+
import { __ as __38, sprintf as sprintf7 } from "@wordpress/i18n";
|
|
2477
2676
|
|
|
2478
2677
|
// src/utils/collect-hardcoded-fonts.ts
|
|
2479
2678
|
var RESERVED_SETTING_KEYS2 = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
|
|
@@ -2531,20 +2730,20 @@ function collectHardcodedFonts(settings, pathPrefix = "") {
|
|
|
2531
2730
|
}
|
|
2532
2731
|
|
|
2533
2732
|
// src/audits/prefer-global-fonts.ts
|
|
2534
|
-
var
|
|
2733
|
+
var audit16 = {
|
|
2535
2734
|
id: "audits/prefer-global-fonts",
|
|
2536
|
-
title:
|
|
2537
|
-
description:
|
|
2538
|
-
fixHint:
|
|
2735
|
+
title: __38("Prefer global fonts", "elementor"),
|
|
2736
|
+
description: __38("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
|
|
2737
|
+
fixHint: __38("Replace the hard-coded value with the matching global font.", "elementor"),
|
|
2539
2738
|
categories: ["best-practices", "performance"],
|
|
2540
2739
|
severity: "info",
|
|
2541
2740
|
weight: 3,
|
|
2542
2741
|
evaluate: (ctx) => {
|
|
2543
2742
|
if (ctx.elements.tree.length === 0) {
|
|
2544
|
-
return { status: "skipped", reason:
|
|
2743
|
+
return { status: "skipped", reason: __38("No elements", "elementor") };
|
|
2545
2744
|
}
|
|
2546
2745
|
if (ctx.kit.globals.fonts.length === 0) {
|
|
2547
|
-
return { status: "skipped", reason:
|
|
2746
|
+
return { status: "skipped", reason: __38("No global fonts", "elementor") };
|
|
2548
2747
|
}
|
|
2549
2748
|
const violations = [];
|
|
2550
2749
|
walkElements(ctx.elements.tree, (node) => {
|
|
@@ -2554,12 +2753,12 @@ var audit15 = {
|
|
|
2554
2753
|
continue;
|
|
2555
2754
|
}
|
|
2556
2755
|
violations.push({
|
|
2557
|
-
auditId:
|
|
2756
|
+
auditId: audit16.id,
|
|
2558
2757
|
elementId: node.id,
|
|
2559
2758
|
targetHint: "element-settings",
|
|
2560
2759
|
label: sprintf7(
|
|
2561
2760
|
/* translators: %s: global font title. */
|
|
2562
|
-
|
|
2761
|
+
__38('replace hardcoded typography with "%s" global font', "elementor"),
|
|
2563
2762
|
global.title
|
|
2564
2763
|
)
|
|
2565
2764
|
});
|
|
@@ -2570,15 +2769,15 @@ var audit15 = {
|
|
|
2570
2769
|
};
|
|
2571
2770
|
|
|
2572
2771
|
// src/audits/privacy-policy.ts
|
|
2573
|
-
import { __ as
|
|
2574
|
-
var
|
|
2772
|
+
import { __ as __39 } from "@wordpress/i18n";
|
|
2773
|
+
var audit17 = {
|
|
2575
2774
|
id: "audits/privacy-policy",
|
|
2576
|
-
title:
|
|
2577
|
-
description:
|
|
2775
|
+
title: __39("Privacy policy", "elementor"),
|
|
2776
|
+
description: __39(
|
|
2578
2777
|
"A privacy policy page is required by privacy regulations such as GDPR (EU) and CCPA (US).",
|
|
2579
2778
|
"elementor"
|
|
2580
2779
|
),
|
|
2581
|
-
fixHint:
|
|
2780
|
+
fixHint: __39(
|
|
2582
2781
|
"Go to Settings > Privacy in the WordPress admin and assign a published privacy policy page.",
|
|
2583
2782
|
"elementor"
|
|
2584
2783
|
),
|
|
@@ -2593,9 +2792,10 @@ var audit16 = {
|
|
|
2593
2792
|
status: "fail",
|
|
2594
2793
|
violations: [
|
|
2595
2794
|
{
|
|
2596
|
-
auditId:
|
|
2597
|
-
label:
|
|
2598
|
-
externalUrl: ctx.pageContext.privacy_settings_url
|
|
2795
|
+
auditId: audit17.id,
|
|
2796
|
+
label: __39("No privacy policy page is set.", "elementor"),
|
|
2797
|
+
externalUrl: ctx.pageContext.privacy_settings_url,
|
|
2798
|
+
ctaLabel: __39("Create", "elementor")
|
|
2599
2799
|
}
|
|
2600
2800
|
]
|
|
2601
2801
|
};
|
|
@@ -2603,15 +2803,15 @@ var audit16 = {
|
|
|
2603
2803
|
};
|
|
2604
2804
|
|
|
2605
2805
|
// src/audits/robots-noindex.ts
|
|
2606
|
-
import { __ as
|
|
2607
|
-
var
|
|
2806
|
+
import { __ as __40 } from "@wordpress/i18n";
|
|
2807
|
+
var audit18 = {
|
|
2608
2808
|
id: "audits/robots-noindex",
|
|
2609
|
-
title:
|
|
2610
|
-
description:
|
|
2809
|
+
title: __40("Search engine visibility", "elementor"),
|
|
2810
|
+
description: __40(
|
|
2611
2811
|
"When search engine visibility is checked in WordPress Settings -> Reading -> Search Engine Visibility, search engines are discouraged from indexing the website.",
|
|
2612
2812
|
"elementor"
|
|
2613
2813
|
),
|
|
2614
|
-
fixHint:
|
|
2814
|
+
fixHint: __40(
|
|
2615
2815
|
'Go to Settings \u2192 Reading in the WordPress admin and uncheck "Discourage search engines from indexing this site" when the website should be indexed.',
|
|
2616
2816
|
"elementor"
|
|
2617
2817
|
),
|
|
@@ -2626,8 +2826,8 @@ var audit17 = {
|
|
|
2626
2826
|
status: "fail",
|
|
2627
2827
|
violations: [
|
|
2628
2828
|
{
|
|
2629
|
-
auditId:
|
|
2630
|
-
label:
|
|
2829
|
+
auditId: audit18.id,
|
|
2830
|
+
label: __40("Search engines are discouraged from indexing this website.", "elementor"),
|
|
2631
2831
|
externalUrl: ctx.pageContext.reading_settings_url
|
|
2632
2832
|
}
|
|
2633
2833
|
]
|
|
@@ -2635,30 +2835,58 @@ var audit17 = {
|
|
|
2635
2835
|
}
|
|
2636
2836
|
};
|
|
2637
2837
|
|
|
2838
|
+
// src/audits/scan-for-cookies.ts
|
|
2839
|
+
import { __ as __41 } from "@wordpress/i18n";
|
|
2840
|
+
var audit19 = {
|
|
2841
|
+
id: "audits/scan-for-cookies",
|
|
2842
|
+
title: __41("Scan for cookies", "elementor"),
|
|
2843
|
+
description: __41(
|
|
2844
|
+
"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.",
|
|
2845
|
+
"elementor"
|
|
2846
|
+
),
|
|
2847
|
+
fixHint: __41("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
|
|
2848
|
+
categories: ["compliance"],
|
|
2849
|
+
severity: "info",
|
|
2850
|
+
weight: 0,
|
|
2851
|
+
evaluate: (ctx) => {
|
|
2852
|
+
const isReady = ctx.pageContext.cookiez_plugin_installed && ctx.pageContext.cookiez_plugin_active;
|
|
2853
|
+
return {
|
|
2854
|
+
status: "fail",
|
|
2855
|
+
violations: [
|
|
2856
|
+
{
|
|
2857
|
+
auditId: audit19.id,
|
|
2858
|
+
label: __41("This page has not been scanned for cookies yet.", "elementor"),
|
|
2859
|
+
externalUrl: isReady ? ctx.pageContext.cookiez_scan_url : ctx.pageContext.cookiez_plugin_action_url
|
|
2860
|
+
}
|
|
2861
|
+
]
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2864
|
+
};
|
|
2865
|
+
|
|
2638
2866
|
// src/audits/sections-and-columns.ts
|
|
2639
|
-
import { __ as
|
|
2640
|
-
var
|
|
2867
|
+
import { __ as __42 } from "@wordpress/i18n";
|
|
2868
|
+
var audit20 = {
|
|
2641
2869
|
id: "audits/sections-and-columns",
|
|
2642
|
-
title:
|
|
2643
|
-
description:
|
|
2870
|
+
title: __42("Sections and columns", "elementor"),
|
|
2871
|
+
description: __42(
|
|
2644
2872
|
"Sections and columns are legacy elements. Containers render fewer DOM nodes and are more flexible.",
|
|
2645
2873
|
"elementor"
|
|
2646
2874
|
),
|
|
2647
|
-
fixHint:
|
|
2875
|
+
fixHint: __42("Use the Container Converter to replace each section/column with a container.", "elementor"),
|
|
2648
2876
|
categories: ["best-practices", "performance"],
|
|
2649
2877
|
severity: "warning",
|
|
2650
2878
|
weight: 7,
|
|
2651
2879
|
evaluate: (ctx) => {
|
|
2652
2880
|
if (ctx.elements.tree.length === 0) {
|
|
2653
|
-
return { status: "skipped", reason:
|
|
2881
|
+
return { status: "skipped", reason: __42("No elements", "elementor") };
|
|
2654
2882
|
}
|
|
2655
2883
|
const violations = [];
|
|
2656
2884
|
walkElements(ctx.elements.tree, (node) => {
|
|
2657
2885
|
if (node.elType === "section" || node.elType === "column") {
|
|
2658
2886
|
violations.push({
|
|
2659
|
-
auditId:
|
|
2887
|
+
auditId: audit20.id,
|
|
2660
2888
|
elementId: node.id,
|
|
2661
|
-
label: node.elType === "section" ?
|
|
2889
|
+
label: node.elType === "section" ? __42("Section element", "elementor") : __42("Column element", "elementor")
|
|
2662
2890
|
});
|
|
2663
2891
|
}
|
|
2664
2892
|
});
|
|
@@ -2667,15 +2895,15 @@ var audit18 = {
|
|
|
2667
2895
|
};
|
|
2668
2896
|
|
|
2669
2897
|
// src/audits/site-identity.ts
|
|
2670
|
-
import { __ as
|
|
2671
|
-
var
|
|
2898
|
+
import { __ as __43 } from "@wordpress/i18n";
|
|
2899
|
+
var audit21 = {
|
|
2672
2900
|
id: "audits/site-identity",
|
|
2673
|
-
title:
|
|
2674
|
-
description:
|
|
2901
|
+
title: __43("Site identity", "elementor"),
|
|
2902
|
+
description: __43(
|
|
2675
2903
|
"Site name, description, logo, and favicon establish your brand and appear in search results and browser tabs.",
|
|
2676
2904
|
"elementor"
|
|
2677
2905
|
),
|
|
2678
|
-
fixHint:
|
|
2906
|
+
fixHint: __43("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
|
|
2679
2907
|
categories: ["best-practices", "seo"],
|
|
2680
2908
|
severity: "info",
|
|
2681
2909
|
weight: 7,
|
|
@@ -2684,30 +2912,30 @@ var audit19 = {
|
|
|
2684
2912
|
const violations = [];
|
|
2685
2913
|
if (!identity.site_name_set) {
|
|
2686
2914
|
violations.push({
|
|
2687
|
-
auditId:
|
|
2688
|
-
label:
|
|
2915
|
+
auditId: audit21.id,
|
|
2916
|
+
label: __43("Site name is missing or still uses the default.", "elementor"),
|
|
2689
2917
|
targetHint: "site-identity-settings"
|
|
2690
2918
|
});
|
|
2691
2919
|
}
|
|
2692
2920
|
if (!identity.site_description_set) {
|
|
2693
2921
|
violations.push({
|
|
2694
|
-
auditId:
|
|
2695
|
-
label:
|
|
2922
|
+
auditId: audit21.id,
|
|
2923
|
+
label: __43("Site description is missing or still uses the default.", "elementor"),
|
|
2696
2924
|
targetHint: "site-identity-settings",
|
|
2697
2925
|
angieFix: true
|
|
2698
2926
|
});
|
|
2699
2927
|
}
|
|
2700
2928
|
if (!identity.site_logo_set) {
|
|
2701
2929
|
violations.push({
|
|
2702
|
-
auditId:
|
|
2703
|
-
label:
|
|
2930
|
+
auditId: audit21.id,
|
|
2931
|
+
label: __43("Site logo is not set.", "elementor"),
|
|
2704
2932
|
targetHint: "site-identity-settings"
|
|
2705
2933
|
});
|
|
2706
2934
|
}
|
|
2707
2935
|
if (!identity.site_favicon_set) {
|
|
2708
2936
|
violations.push({
|
|
2709
|
-
auditId:
|
|
2710
|
-
label:
|
|
2937
|
+
auditId: audit21.id,
|
|
2938
|
+
label: __43("Site favicon is not set.", "elementor"),
|
|
2711
2939
|
targetHint: "site-identity-settings"
|
|
2712
2940
|
});
|
|
2713
2941
|
}
|
|
@@ -2722,19 +2950,19 @@ var audit19 = {
|
|
|
2722
2950
|
};
|
|
2723
2951
|
|
|
2724
2952
|
// src/audits/too-many-widgets.ts
|
|
2725
|
-
import { __ as
|
|
2953
|
+
import { __ as __44 } from "@wordpress/i18n";
|
|
2726
2954
|
var WIDGET_COUNT_THRESHOLD = 100;
|
|
2727
|
-
var
|
|
2955
|
+
var audit22 = {
|
|
2728
2956
|
id: "audits/too-many-widgets",
|
|
2729
|
-
title:
|
|
2730
|
-
description:
|
|
2731
|
-
fixHint:
|
|
2957
|
+
title: __44("Too many widgets", "elementor"),
|
|
2958
|
+
description: __44("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
|
|
2959
|
+
fixHint: __44("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
|
|
2732
2960
|
categories: ["best-practices", "performance"],
|
|
2733
2961
|
severity: "warning",
|
|
2734
2962
|
weight: 5,
|
|
2735
2963
|
evaluate: (ctx) => {
|
|
2736
2964
|
if (ctx.elements.tree.length === 0) {
|
|
2737
|
-
return { status: "skipped", reason:
|
|
2965
|
+
return { status: "skipped", reason: __44("No elements", "elementor") };
|
|
2738
2966
|
}
|
|
2739
2967
|
let widgetCount = 0;
|
|
2740
2968
|
walkElements(ctx.elements.tree, (node) => {
|
|
@@ -2749,8 +2977,8 @@ var audit20 = {
|
|
|
2749
2977
|
status: "fail",
|
|
2750
2978
|
violations: [
|
|
2751
2979
|
{
|
|
2752
|
-
auditId:
|
|
2753
|
-
label:
|
|
2980
|
+
auditId: audit22.id,
|
|
2981
|
+
label: __44("Page has too many widgets.", "elementor")
|
|
2754
2982
|
}
|
|
2755
2983
|
]
|
|
2756
2984
|
};
|
|
@@ -2759,30 +2987,32 @@ var audit20 = {
|
|
|
2759
2987
|
|
|
2760
2988
|
// src/register-audits.ts
|
|
2761
2989
|
var AUDITS = [
|
|
2762
|
-
|
|
2763
|
-
audit11,
|
|
2990
|
+
audit14,
|
|
2764
2991
|
audit12,
|
|
2765
|
-
|
|
2992
|
+
audit13,
|
|
2993
|
+
audit8,
|
|
2766
2994
|
audit5,
|
|
2995
|
+
audit22,
|
|
2767
2996
|
audit20,
|
|
2768
|
-
audit18,
|
|
2769
2997
|
audit3,
|
|
2770
|
-
|
|
2998
|
+
audit11,
|
|
2771
2999
|
audit4,
|
|
2772
|
-
|
|
2773
|
-
audit14,
|
|
3000
|
+
audit21,
|
|
2774
3001
|
audit15,
|
|
2775
|
-
|
|
2776
|
-
|
|
3002
|
+
audit16,
|
|
3003
|
+
audit7,
|
|
2777
3004
|
audit9,
|
|
3005
|
+
audit10,
|
|
3006
|
+
audit18,
|
|
2778
3007
|
audit17,
|
|
2779
|
-
audit16,
|
|
2780
3008
|
audit,
|
|
2781
|
-
audit2
|
|
3009
|
+
audit2,
|
|
3010
|
+
audit19,
|
|
3011
|
+
audit6
|
|
2782
3012
|
];
|
|
2783
3013
|
function registerAllAudits() {
|
|
2784
|
-
for (const
|
|
2785
|
-
registerAudit(
|
|
3014
|
+
for (const audit23 of AUDITS) {
|
|
3015
|
+
registerAudit(audit23);
|
|
2786
3016
|
}
|
|
2787
3017
|
}
|
|
2788
3018
|
|