@elementor/editor-audits 4.3.3 → 4.3.5
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 +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +1103 -1146
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1075 -1108
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -15
- package/src/api/page-context-client.ts +8 -5
- package/src/audits/accessibility-statement.ts +39 -0
- package/src/audits/accessibility-widget.ts +41 -0
- package/src/audits/cookie-policy.ts +1 -0
- package/src/audits/google-consent-mode.ts +4 -7
- package/src/audits/images-alt-text.ts +6 -4
- package/src/audits/images-inefficient-format.ts +66 -0
- package/src/audits/images-too-large.ts +23 -10
- package/src/audits/nested-boxed-containers.ts +5 -0
- package/src/components/audit-feedback.tsx +4 -1
- package/src/components/audit-panel.tsx +13 -13
- package/src/components/audit-toggle-icon.tsx +22 -0
- package/src/components/fix-violation-with-angie.tsx +18 -7
- package/src/components/pages/category-page.tsx +27 -3
- package/src/components/pages/overview-page.tsx +24 -29
- package/src/components/report-shell.tsx +10 -91
- package/src/components/rescan-button.tsx +38 -0
- package/src/components/severity-icons.tsx +5 -1
- package/src/components/severity-summary-cards.tsx +52 -0
- package/src/components/violation-cta-button.tsx +11 -2
- package/src/components/violation-icons.tsx +2 -2
- package/src/components/violation-row.tsx +120 -62
- package/src/hooks/use-audit-report.ts +5 -4
- package/src/hooks/use-audit-toggle-props.ts +2 -2
- package/src/hooks/use-single-expanded-card.ts +11 -0
- package/src/init.ts +2 -0
- package/src/register-audits.ts +6 -2
- package/src/runner.ts +15 -7
- package/src/store/selectors.ts +4 -0
- package/src/store/slice.ts +10 -1
- package/src/sync-report-staleness.ts +14 -0
- package/src/types.ts +11 -1
- package/src/utils/all-image-sources.ts +17 -0
- package/src/utils/alt-text-image-sources.ts +24 -0
- package/src/utils/atomic-background-image-sources.ts +56 -0
- package/src/utils/atomic-image-sources.ts +66 -0
- package/src/utils/audit-status-summary.ts +0 -57
- package/src/utils/background-image-sources.ts +32 -0
- package/src/utils/image-alt.ts +3 -1
- package/src/utils/image-like-sources.ts +5 -14
- package/src/utils/image-size-key.ts +8 -0
- package/src/utils/page-attachments.ts +7 -6
- package/src/utils/scan-accessibility-widgets.ts +7 -0
- package/src/audits/too-many-widgets.ts +0 -53
- package/src/components/audit-statuses-section.tsx +0 -65
- package/src/components/count-summary-circle.tsx +0 -66
- package/src/components/pages/all-audits-page.tsx +0 -65
- package/src/components/pages/issues-page.tsx +0 -65
- package/src/components/score-bar.tsx +0 -56
- package/src/components/score-circle.tsx +0 -60
- package/src/components/severity-filter-chips.tsx +0 -57
- package/src/utils/score-thresholds.ts +0 -23
package/dist/index.js
CHANGED
|
@@ -37,33 +37,138 @@ __export(index_exports, {
|
|
|
37
37
|
module.exports = __toCommonJS(index_exports);
|
|
38
38
|
|
|
39
39
|
// src/init.ts
|
|
40
|
-
var
|
|
41
|
-
var
|
|
40
|
+
var import_editor_floating_panels6 = require("@elementor/editor-floating-panels");
|
|
41
|
+
var import_store7 = require("@elementor/store");
|
|
42
42
|
|
|
43
43
|
// src/editor-app-bar.tsx
|
|
44
44
|
var import_editor_app_bar = require("@elementor/editor-app-bar");
|
|
45
45
|
|
|
46
46
|
// src/hooks/use-audit-toggle-props.ts
|
|
47
|
-
var
|
|
48
|
-
|
|
47
|
+
var import_i18n18 = require("@wordpress/i18n");
|
|
48
|
+
|
|
49
|
+
// src/components/audit-toggle-icon.tsx
|
|
50
|
+
var React = __toESM(require("react"));
|
|
51
|
+
var import_icons = require("@elementor/icons");
|
|
52
|
+
var import_store2 = require("@elementor/store");
|
|
53
|
+
var import_ui = require("@elementor/ui");
|
|
54
|
+
|
|
55
|
+
// src/store/slice.ts
|
|
56
|
+
var import_store = require("@elementor/store");
|
|
57
|
+
var initialState = { status: "idle", report: null, error: null, isStale: false };
|
|
58
|
+
var slice = (0, import_store.__createSlice)({
|
|
59
|
+
name: "audits",
|
|
60
|
+
initialState,
|
|
61
|
+
reducers: {
|
|
62
|
+
runStarted(state) {
|
|
63
|
+
state.status = "loading";
|
|
64
|
+
state.error = null;
|
|
65
|
+
},
|
|
66
|
+
runSucceeded(state, action) {
|
|
67
|
+
state.status = "ready";
|
|
68
|
+
state.report = action.payload;
|
|
69
|
+
state.isStale = false;
|
|
70
|
+
},
|
|
71
|
+
runFailed(state, action) {
|
|
72
|
+
state.status = "error";
|
|
73
|
+
state.error = action.payload;
|
|
74
|
+
},
|
|
75
|
+
runAborted(state) {
|
|
76
|
+
state.status = state.report ? "ready" : "idle";
|
|
77
|
+
},
|
|
78
|
+
reportRestored(state, action) {
|
|
79
|
+
state.status = "ready";
|
|
80
|
+
state.report = action.payload;
|
|
81
|
+
state.error = null;
|
|
82
|
+
state.isStale = false;
|
|
83
|
+
},
|
|
84
|
+
reportCleared(state) {
|
|
85
|
+
state.status = "idle";
|
|
86
|
+
state.report = null;
|
|
87
|
+
state.error = null;
|
|
88
|
+
state.isStale = false;
|
|
89
|
+
},
|
|
90
|
+
reportStale(state) {
|
|
91
|
+
if (state.report) {
|
|
92
|
+
state.isStale = true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// src/store/selectors.ts
|
|
99
|
+
function selectStatus(state) {
|
|
100
|
+
return state.audits.status;
|
|
101
|
+
}
|
|
102
|
+
function selectReport(state) {
|
|
103
|
+
return state.audits.report;
|
|
104
|
+
}
|
|
105
|
+
function selectError(state) {
|
|
106
|
+
return state.audits.error;
|
|
107
|
+
}
|
|
108
|
+
function selectIsStale(state) {
|
|
109
|
+
return state.audits.isStale;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/components/audit-toggle-icon.tsx
|
|
113
|
+
function AuditToggleIcon() {
|
|
114
|
+
const isStale = (0, import_store2.__useSelector)((state) => selectIsStale(state));
|
|
115
|
+
return /* @__PURE__ */ React.createElement(
|
|
116
|
+
import_ui.Badge,
|
|
117
|
+
{
|
|
118
|
+
variant: "dot",
|
|
119
|
+
color: "warning",
|
|
120
|
+
invisible: !isStale,
|
|
121
|
+
overlap: "circular",
|
|
122
|
+
slotProps: { badge: { "data-testid": "audit-stale-indicator" } }
|
|
123
|
+
},
|
|
124
|
+
/* @__PURE__ */ React.createElement(import_icons.ShieldCheckIcon, null)
|
|
125
|
+
);
|
|
126
|
+
}
|
|
49
127
|
|
|
50
128
|
// src/editor-panel.tsx
|
|
51
|
-
var
|
|
129
|
+
var import_editor_floating_panels5 = require("@elementor/editor-floating-panels");
|
|
52
130
|
|
|
53
131
|
// src/components/audit-panel.tsx
|
|
54
|
-
var
|
|
55
|
-
var
|
|
56
|
-
var
|
|
57
|
-
var
|
|
58
|
-
var
|
|
132
|
+
var React21 = __toESM(require("react"));
|
|
133
|
+
var import_editor_elements6 = require("@elementor/editor-elements");
|
|
134
|
+
var import_editor_floating_panels4 = require("@elementor/editor-floating-panels");
|
|
135
|
+
var import_ui20 = require("@elementor/ui");
|
|
136
|
+
var import_i18n17 = require("@wordpress/i18n");
|
|
137
|
+
|
|
138
|
+
// src/constants.ts
|
|
139
|
+
var import_i18n = require("@wordpress/i18n");
|
|
140
|
+
var AUDIT_PANEL_ID = "audit-panel";
|
|
141
|
+
var REPORT_STORAGE_KEY_PREFIX = "elementor/audits/report";
|
|
142
|
+
var CREATE_WIDGET_EVENT = "elementor/editor/create-widget";
|
|
143
|
+
var ANGIE_FIX_ENTRY_POINT = "audit_violation";
|
|
144
|
+
var FEEDBACK_EXPERIMENT_NAME = "in_editor_feedback";
|
|
145
|
+
var FEEDBACK_ENTRY_POINT = "audit_panel";
|
|
146
|
+
var FEEDBACK_CLICKED_EVENT = "audit_feedback_clicked";
|
|
147
|
+
var FEEDBACK_SENT_EVENT = "audit_feedback_sent";
|
|
148
|
+
var FEEDBACK_CANCELLED_EVENT = "audit_feedback_cancelled";
|
|
149
|
+
var FEEDBACK_CLOSED_EVENT = "audit_feedback_closed";
|
|
150
|
+
var ALL_CATEGORIES = [
|
|
151
|
+
"best-practices",
|
|
152
|
+
"seo",
|
|
153
|
+
"accessibility",
|
|
154
|
+
"performance",
|
|
155
|
+
"compliance"
|
|
156
|
+
];
|
|
157
|
+
var CATEGORY_LABELS = {
|
|
158
|
+
"best-practices": (0, import_i18n.__)("Best Practices", "elementor"),
|
|
159
|
+
seo: (0, import_i18n.__)("SEO", "elementor"),
|
|
160
|
+
accessibility: (0, import_i18n.__)("Accessibility", "elementor"),
|
|
161
|
+
performance: (0, import_i18n.__)("Performance", "elementor"),
|
|
162
|
+
compliance: (0, import_i18n.__)("Site compliance", "elementor")
|
|
163
|
+
};
|
|
59
164
|
|
|
60
165
|
// src/hooks/use-audit-report.ts
|
|
61
166
|
var import_react = require("react");
|
|
62
|
-
var
|
|
63
|
-
var
|
|
167
|
+
var import_editor_elements3 = require("@elementor/editor-elements");
|
|
168
|
+
var import_store4 = require("@elementor/store");
|
|
64
169
|
|
|
65
170
|
// src/runner.ts
|
|
66
|
-
var
|
|
171
|
+
var import_editor_elements2 = require("@elementor/editor-elements");
|
|
67
172
|
|
|
68
173
|
// src/api/page-context-client.ts
|
|
69
174
|
var import_http_client = require("@elementor/http-client");
|
|
@@ -115,17 +220,17 @@ async function requestFreshNonce() {
|
|
|
115
220
|
}
|
|
116
221
|
|
|
117
222
|
// src/api/page-context-client.ts
|
|
118
|
-
async function fetchPageContext(documentId,
|
|
119
|
-
return requestPageContext(documentId,
|
|
223
|
+
async function fetchPageContext(documentId, imageSizeRequests) {
|
|
224
|
+
return requestPageContext(documentId, imageSizeRequests, true);
|
|
120
225
|
}
|
|
121
|
-
async function requestPageContext(documentId,
|
|
226
|
+
async function requestPageContext(documentId, imageSizeRequests, allowNonceRetry) {
|
|
122
227
|
const { restNamespace, nonce } = getWindowConfig();
|
|
123
228
|
const url = `${restNamespace}/audits/page-context`;
|
|
124
229
|
try {
|
|
125
230
|
const response = await (0, import_http_client.httpService)().get(url, {
|
|
126
231
|
params: {
|
|
127
232
|
document_id: documentId,
|
|
128
|
-
|
|
233
|
+
image_size_requests: imageSizeRequests
|
|
129
234
|
},
|
|
130
235
|
headers: { "X-WP-Nonce": nonce }
|
|
131
236
|
});
|
|
@@ -135,52 +240,22 @@ async function requestPageContext(documentId, attachmentIds, allowNonceRetry) {
|
|
|
135
240
|
throw error;
|
|
136
241
|
}
|
|
137
242
|
await refreshAuditsNonce();
|
|
138
|
-
return requestPageContext(documentId,
|
|
243
|
+
return requestPageContext(documentId, imageSizeRequests, false);
|
|
139
244
|
}
|
|
140
245
|
}
|
|
141
246
|
|
|
142
247
|
// src/registry.ts
|
|
143
248
|
var registry = /* @__PURE__ */ new Map();
|
|
144
|
-
function registerAudit(
|
|
145
|
-
registry.set(
|
|
249
|
+
function registerAudit(audit25) {
|
|
250
|
+
registry.set(audit25.id, audit25);
|
|
146
251
|
}
|
|
147
252
|
function getRegisteredAudits() {
|
|
148
253
|
return Array.from(registry.values());
|
|
149
254
|
}
|
|
150
255
|
|
|
151
|
-
// src/constants.ts
|
|
152
|
-
var import_i18n = require("@wordpress/i18n");
|
|
153
|
-
var AUDIT_PANEL_ID = "audit-panel";
|
|
154
|
-
var REPORT_STORAGE_KEY_PREFIX = "elementor/audits/report";
|
|
155
|
-
var CREATE_WIDGET_EVENT = "elementor/editor/create-widget";
|
|
156
|
-
var ANGIE_FIX_ENTRY_POINT = "audit_violation";
|
|
157
|
-
var FEEDBACK_EXPERIMENT_NAME = "in_editor_feedback";
|
|
158
|
-
var FEEDBACK_ENTRY_POINT = "audit_panel";
|
|
159
|
-
var FEEDBACK_CLICKED_EVENT = "audit_feedback_clicked";
|
|
160
|
-
var FEEDBACK_SENT_EVENT = "audit_feedback_sent";
|
|
161
|
-
var FEEDBACK_CANCELLED_EVENT = "audit_feedback_cancelled";
|
|
162
|
-
var FEEDBACK_CLOSED_EVENT = "audit_feedback_closed";
|
|
163
|
-
var ALL_CATEGORIES = [
|
|
164
|
-
"best-practices",
|
|
165
|
-
"seo",
|
|
166
|
-
"accessibility",
|
|
167
|
-
"performance",
|
|
168
|
-
"compliance"
|
|
169
|
-
];
|
|
170
|
-
var CATEGORY_LABELS = {
|
|
171
|
-
"best-practices": (0, import_i18n.__)("Best Practices", "elementor"),
|
|
172
|
-
seo: (0, import_i18n.__)("SEO", "elementor"),
|
|
173
|
-
accessibility: (0, import_i18n.__)("Accessibility", "elementor"),
|
|
174
|
-
performance: (0, import_i18n.__)("Performance", "elementor"),
|
|
175
|
-
compliance: (0, import_i18n.__)("Site compliance", "elementor")
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
// src/utils/audit-status-summary.ts
|
|
179
|
-
var import_i18n2 = require("@wordpress/i18n");
|
|
180
|
-
|
|
181
256
|
// src/utils/is-scored-audit.ts
|
|
182
|
-
function isScoredAudit(
|
|
183
|
-
return
|
|
257
|
+
function isScoredAudit(audit25) {
|
|
258
|
+
return audit25.weight > 0;
|
|
184
259
|
}
|
|
185
260
|
|
|
186
261
|
// src/utils/sort-failed-audits.ts
|
|
@@ -232,52 +307,6 @@ function partitionAuditResults(report, options = {}) {
|
|
|
232
307
|
totalViolations
|
|
233
308
|
};
|
|
234
309
|
}
|
|
235
|
-
function auditStatusDisplayCounts(report) {
|
|
236
|
-
let pass = 0;
|
|
237
|
-
let skipped = 0;
|
|
238
|
-
let totalViolations = 0;
|
|
239
|
-
for (const { audit: audit23, result } of report.auditResults) {
|
|
240
|
-
if (!isScoredAudit(audit23)) {
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
switch (result.status) {
|
|
244
|
-
case "fail":
|
|
245
|
-
totalViolations += result.violations.length;
|
|
246
|
-
break;
|
|
247
|
-
case "pass":
|
|
248
|
-
pass++;
|
|
249
|
-
break;
|
|
250
|
-
case "skipped":
|
|
251
|
-
skipped++;
|
|
252
|
-
break;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
return {
|
|
256
|
-
fail: totalViolations,
|
|
257
|
-
pass,
|
|
258
|
-
skipped
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
function auditStatusColor(status) {
|
|
262
|
-
switch (status) {
|
|
263
|
-
case "fail":
|
|
264
|
-
return "error";
|
|
265
|
-
case "pass":
|
|
266
|
-
return "success";
|
|
267
|
-
case "skipped":
|
|
268
|
-
return "default";
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
function auditStatusLabel(status) {
|
|
272
|
-
switch (status) {
|
|
273
|
-
case "fail":
|
|
274
|
-
return (0, import_i18n2.__)("Failed audits", "elementor");
|
|
275
|
-
case "pass":
|
|
276
|
-
return (0, import_i18n2.__)("Passed audits", "elementor");
|
|
277
|
-
case "skipped":
|
|
278
|
-
return (0, import_i18n2.__)("Skipped audits", "elementor");
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
310
|
function getPopulatedCategories(categoryTotals, categories) {
|
|
282
311
|
return categories.filter((category) => categoryTotals[category].total > 0);
|
|
283
312
|
}
|
|
@@ -287,16 +316,16 @@ function computeReport(documentId, results) {
|
|
|
287
316
|
const accumulators = Object.fromEntries(
|
|
288
317
|
ALL_CATEGORIES.map((c) => [c, { totalWeight: 0, passedWeight: 0, total: 0, failed: 0 }])
|
|
289
318
|
);
|
|
290
|
-
for (const { audit:
|
|
319
|
+
for (const { audit: audit25, result } of results) {
|
|
291
320
|
if (result.status === "skipped") {
|
|
292
321
|
continue;
|
|
293
322
|
}
|
|
294
|
-
for (const category of
|
|
323
|
+
for (const category of audit25.categories) {
|
|
295
324
|
const acc = accumulators[category];
|
|
296
325
|
acc.total++;
|
|
297
|
-
acc.totalWeight +=
|
|
326
|
+
acc.totalWeight += audit25.weight;
|
|
298
327
|
if (result.status === "pass") {
|
|
299
|
-
acc.passedWeight +=
|
|
328
|
+
acc.passedWeight += audit25.weight;
|
|
300
329
|
} else {
|
|
301
330
|
acc.failed++;
|
|
302
331
|
}
|
|
@@ -320,6 +349,34 @@ function computeReport(documentId, results) {
|
|
|
320
349
|
};
|
|
321
350
|
}
|
|
322
351
|
|
|
352
|
+
// src/utils/fetch-rendered-html.ts
|
|
353
|
+
var FETCH_TIMEOUT_MS = 1e4;
|
|
354
|
+
async function fetchRenderedHtml(url) {
|
|
355
|
+
if (!url) {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
const timeoutController = new AbortController();
|
|
359
|
+
const timeoutId = setTimeout(() => timeoutController.abort(), FETCH_TIMEOUT_MS);
|
|
360
|
+
try {
|
|
361
|
+
const response = await fetch(url, { credentials: "omit", signal: timeoutController.signal });
|
|
362
|
+
if (!response.ok) {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
return await response.text();
|
|
366
|
+
} catch {
|
|
367
|
+
return null;
|
|
368
|
+
} finally {
|
|
369
|
+
clearTimeout(timeoutId);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// src/utils/atomic-background-image-sources.ts
|
|
374
|
+
var import_editor_elements = require("@elementor/editor-elements");
|
|
375
|
+
var import_editor_props2 = require("@elementor/editor-props");
|
|
376
|
+
|
|
377
|
+
// src/utils/atomic-image-sources.ts
|
|
378
|
+
var import_editor_props = require("@elementor/editor-props");
|
|
379
|
+
|
|
323
380
|
// src/utils/walk.ts
|
|
324
381
|
function walkElements(tree, visit) {
|
|
325
382
|
const parents = [];
|
|
@@ -334,17 +391,93 @@ function recurse(nodes, parents, visit) {
|
|
|
334
391
|
}
|
|
335
392
|
}
|
|
336
393
|
|
|
337
|
-
// src/utils/image-
|
|
338
|
-
var
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
if (
|
|
343
|
-
|
|
394
|
+
// src/utils/atomic-image-sources.ts
|
|
395
|
+
var ATOMIC_CONTENT_IMAGE_PROP_KEYS = ["image"];
|
|
396
|
+
var ATOMIC_IMAGE_PROP_KEYS = [...ATOMIC_CONTENT_IMAGE_PROP_KEYS, "poster"];
|
|
397
|
+
function walkAtomicImageSources(tree, visit, propKeys = ATOMIC_IMAGE_PROP_KEYS) {
|
|
398
|
+
walkElements(tree, (node) => {
|
|
399
|
+
if (node.elType !== "widget") {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
for (const key of propKeys) {
|
|
403
|
+
const media = extractAtomicImageMedia(node.settings[key]);
|
|
404
|
+
if (media) {
|
|
405
|
+
visit({ node, media });
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
function extractAtomicImageMedia(imageProp) {
|
|
411
|
+
const image = import_editor_props.imagePropTypeUtil.extract(imageProp);
|
|
412
|
+
if (!image) {
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
const src = import_editor_props.imageSrcPropTypeUtil.extract(image.src);
|
|
416
|
+
if (!src) {
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
const id = import_editor_props.imageAttachmentIdPropType.extract(src.id) ?? void 0;
|
|
420
|
+
const url = import_editor_props.urlPropTypeUtil.extract(src.url) ?? void 0;
|
|
421
|
+
if (!id && !url) {
|
|
422
|
+
return null;
|
|
423
|
+
}
|
|
424
|
+
const alt = import_editor_props.stringPropTypeUtil.extract(src.alt) ?? void 0;
|
|
425
|
+
const size = import_editor_props.stringPropTypeUtil.extract(image.size) ?? void 0;
|
|
426
|
+
return { id, url, alt, size };
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// src/utils/atomic-background-image-sources.ts
|
|
430
|
+
function walkAtomicBackgroundImageSources(tree, visit) {
|
|
431
|
+
walkElements(tree, (node) => {
|
|
432
|
+
const styles = (0, import_editor_elements.getElementStyles)(node.id);
|
|
433
|
+
if (!styles) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
for (const media of extractBackgroundImageMedia(styles)) {
|
|
437
|
+
visit({ node, media });
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
function extractBackgroundImageMedia(styles) {
|
|
442
|
+
const sources = [];
|
|
443
|
+
for (const style of Object.values(styles)) {
|
|
444
|
+
for (const variant of style.variants) {
|
|
445
|
+
const background = import_editor_props2.backgroundPropTypeUtil.extract(variant.props.background);
|
|
446
|
+
const overlays = import_editor_props2.backgroundOverlayPropTypeUtil.extract(background?.["background-overlay"]) ?? [];
|
|
447
|
+
for (const overlay of overlays) {
|
|
448
|
+
const imageOverlay = import_editor_props2.backgroundImageOverlayPropTypeUtil.extract(overlay);
|
|
449
|
+
const media = extractAtomicImageMedia(imageOverlay?.image);
|
|
450
|
+
if (media) {
|
|
451
|
+
sources.push(media);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return sources;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// src/utils/background-image-sources.ts
|
|
460
|
+
var BACKGROUND_IMAGE_SETTING_KEYS = [
|
|
461
|
+
"background_image",
|
|
462
|
+
"background_hover_image",
|
|
463
|
+
"background_overlay_image",
|
|
464
|
+
"background_overlay_hover_image",
|
|
465
|
+
"_background_image",
|
|
466
|
+
"_background_hover_image"
|
|
467
|
+
];
|
|
468
|
+
function walkBackgroundImageSources(tree, visit) {
|
|
469
|
+
walkElements(tree, (node) => {
|
|
470
|
+
for (const key of BACKGROUND_IMAGE_SETTING_KEYS) {
|
|
471
|
+
const media = node.settings[key];
|
|
472
|
+
if (media?.id || media?.url) {
|
|
473
|
+
visit({ node, media });
|
|
474
|
+
}
|
|
344
475
|
}
|
|
345
476
|
});
|
|
346
|
-
return found;
|
|
347
477
|
}
|
|
478
|
+
|
|
479
|
+
// src/utils/image-like-sources.ts
|
|
480
|
+
var IMAGE_LIKE_WIDGETS = /* @__PURE__ */ new Set(["image", "image-box", "image-carousel", "gallery", "image-gallery"]);
|
|
348
481
|
function walkImageLikeSources(tree, visit) {
|
|
349
482
|
walkElements(tree, (node) => {
|
|
350
483
|
if (node.elType !== "widget") {
|
|
@@ -362,28 +495,42 @@ function collectMediaFromNode(node) {
|
|
|
362
495
|
const sources = [];
|
|
363
496
|
const image = node.settings.image;
|
|
364
497
|
if (image?.id || image?.url) {
|
|
365
|
-
sources.push(image);
|
|
498
|
+
sources.push({ ...image, size: node.settings.image_size });
|
|
366
499
|
}
|
|
367
500
|
const gallery = node.settings.carousel ?? node.settings.gallery ?? node.settings.wp_gallery;
|
|
368
501
|
if (Array.isArray(gallery)) {
|
|
502
|
+
const gallerySize = node.settings.thumbnail_size;
|
|
369
503
|
for (const item of gallery) {
|
|
370
504
|
if (item?.id || item?.url) {
|
|
371
|
-
sources.push(item);
|
|
505
|
+
sources.push({ ...item, size: gallerySize });
|
|
372
506
|
}
|
|
373
507
|
}
|
|
374
508
|
}
|
|
375
509
|
return sources;
|
|
376
510
|
}
|
|
377
511
|
|
|
512
|
+
// src/utils/all-image-sources.ts
|
|
513
|
+
function walkAllImageSources(tree, visit) {
|
|
514
|
+
walkImageLikeSources(tree, visit);
|
|
515
|
+
walkBackgroundImageSources(tree, visit);
|
|
516
|
+
walkAtomicImageSources(tree, visit);
|
|
517
|
+
walkAtomicBackgroundImageSources(tree, visit);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// src/utils/image-size-key.ts
|
|
521
|
+
function buildImageSizeKey({ id, size }) {
|
|
522
|
+
return `${id}:${size || "full"}`;
|
|
523
|
+
}
|
|
524
|
+
|
|
378
525
|
// src/utils/page-attachments.ts
|
|
379
|
-
function
|
|
380
|
-
const
|
|
381
|
-
|
|
526
|
+
function extractImageSizeRequests(tree) {
|
|
527
|
+
const keys = /* @__PURE__ */ new Set();
|
|
528
|
+
walkAllImageSources(tree, ({ media }) => {
|
|
382
529
|
if (media.id) {
|
|
383
|
-
|
|
530
|
+
keys.add(buildImageSizeKey({ id: media.id, size: media.size }));
|
|
384
531
|
}
|
|
385
532
|
});
|
|
386
|
-
return Array.from(
|
|
533
|
+
return Array.from(keys).sort();
|
|
387
534
|
}
|
|
388
535
|
|
|
389
536
|
// src/utils/read-kit-snapshot.ts
|
|
@@ -477,18 +624,24 @@ function toSnapshot(element) {
|
|
|
477
624
|
|
|
478
625
|
// src/runner.ts
|
|
479
626
|
async function runPageAudit(documentId) {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
627
|
+
if (documentId !== (0, import_editor_elements2.getHostDocumentId)()) {
|
|
628
|
+
throw new Error("runPageAudit: documentId must match the host document.");
|
|
629
|
+
}
|
|
630
|
+
const tree = buildSnapshotTree((0, import_editor_elements2.getHostDocumentElements)());
|
|
631
|
+
const imageSizeRequests = extractImageSizeRequests(tree);
|
|
632
|
+
const pageContext = await fetchPageContext(documentId, imageSizeRequests);
|
|
483
633
|
const elements = { documentId, tree };
|
|
484
|
-
const kit = await
|
|
485
|
-
|
|
634
|
+
const [kit, renderedHtml] = await Promise.all([
|
|
635
|
+
readKitSnapshot(pageContext.kit_id),
|
|
636
|
+
fetchRenderedHtml(pageContext.frontend_url)
|
|
637
|
+
]);
|
|
638
|
+
const ctx = { documentId, elements, pageContext, kit, renderedHtml };
|
|
486
639
|
const registered = getRegisteredAudits();
|
|
487
640
|
const auditResults = await Promise.all(
|
|
488
|
-
registered.map(async (
|
|
489
|
-
const { evaluate: _evaluate, ...meta } =
|
|
641
|
+
registered.map(async (audit25) => {
|
|
642
|
+
const { evaluate: _evaluate, ...meta } = audit25;
|
|
490
643
|
try {
|
|
491
|
-
const result = await
|
|
644
|
+
const result = await audit25.evaluate(ctx);
|
|
492
645
|
return { audit: meta, result };
|
|
493
646
|
} catch (error) {
|
|
494
647
|
const reason = error instanceof Error ? error.message : "unknown-error";
|
|
@@ -499,52 +652,6 @@ async function runPageAudit(documentId) {
|
|
|
499
652
|
return computeReport(documentId, auditResults);
|
|
500
653
|
}
|
|
501
654
|
|
|
502
|
-
// src/store/slice.ts
|
|
503
|
-
var import_store = require("@elementor/store");
|
|
504
|
-
var initialState = { status: "idle", report: null, error: null };
|
|
505
|
-
var slice = (0, import_store.__createSlice)({
|
|
506
|
-
name: "audits",
|
|
507
|
-
initialState,
|
|
508
|
-
reducers: {
|
|
509
|
-
runStarted(state) {
|
|
510
|
-
state.status = "loading";
|
|
511
|
-
state.error = null;
|
|
512
|
-
},
|
|
513
|
-
runSucceeded(state, action) {
|
|
514
|
-
state.status = "ready";
|
|
515
|
-
state.report = action.payload;
|
|
516
|
-
},
|
|
517
|
-
runFailed(state, action) {
|
|
518
|
-
state.status = "error";
|
|
519
|
-
state.error = action.payload;
|
|
520
|
-
},
|
|
521
|
-
runAborted(state) {
|
|
522
|
-
state.status = state.report ? "ready" : "idle";
|
|
523
|
-
},
|
|
524
|
-
reportRestored(state, action) {
|
|
525
|
-
state.status = "ready";
|
|
526
|
-
state.report = action.payload;
|
|
527
|
-
state.error = null;
|
|
528
|
-
},
|
|
529
|
-
reportCleared(state) {
|
|
530
|
-
state.status = "idle";
|
|
531
|
-
state.report = null;
|
|
532
|
-
state.error = null;
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
});
|
|
536
|
-
|
|
537
|
-
// src/store/selectors.ts
|
|
538
|
-
function selectStatus(state) {
|
|
539
|
-
return state.audits.status;
|
|
540
|
-
}
|
|
541
|
-
function selectReport(state) {
|
|
542
|
-
return state.audits.report;
|
|
543
|
-
}
|
|
544
|
-
function selectError(state) {
|
|
545
|
-
return state.audits.error;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
655
|
// src/utils/report-storage.ts
|
|
549
656
|
var import_session = require("@elementor/session");
|
|
550
657
|
function getStorageKey(documentId) {
|
|
@@ -559,51 +666,53 @@ function persistReport(documentId, report) {
|
|
|
559
666
|
|
|
560
667
|
// src/hooks/use-audit-report.ts
|
|
561
668
|
function useAuditReport() {
|
|
562
|
-
const status = (0,
|
|
563
|
-
const report = (0,
|
|
564
|
-
const error = (0,
|
|
565
|
-
const
|
|
566
|
-
const
|
|
669
|
+
const status = (0, import_store4.__useSelector)((state) => selectStatus(state));
|
|
670
|
+
const report = (0, import_store4.__useSelector)((state) => selectReport(state));
|
|
671
|
+
const error = (0, import_store4.__useSelector)((state) => selectError(state));
|
|
672
|
+
const isStale = (0, import_store4.__useSelector)((state) => selectIsStale(state));
|
|
673
|
+
const dispatch2 = (0, import_store4.__useDispatch)();
|
|
674
|
+
const documentId = (0, import_editor_elements3.getHostDocumentId)() ?? 0;
|
|
567
675
|
(0, import_react.useEffect)(() => {
|
|
568
676
|
if (!documentId || report?.documentId === documentId) {
|
|
569
677
|
return;
|
|
570
678
|
}
|
|
571
679
|
const persisted = getPersistedReport(documentId);
|
|
572
680
|
if (persisted) {
|
|
573
|
-
|
|
681
|
+
dispatch2(slice.actions.reportRestored(persisted));
|
|
574
682
|
} else if (report) {
|
|
575
|
-
|
|
683
|
+
dispatch2(slice.actions.reportCleared());
|
|
576
684
|
}
|
|
577
|
-
}, [documentId, report,
|
|
685
|
+
}, [documentId, report, dispatch2]);
|
|
578
686
|
const run = async (documentIdToRun) => {
|
|
579
|
-
|
|
687
|
+
dispatch2(slice.actions.runStarted());
|
|
580
688
|
try {
|
|
581
689
|
const nextReport = await runPageAudit(documentIdToRun);
|
|
582
|
-
|
|
690
|
+
dispatch2(slice.actions.runSucceeded(nextReport));
|
|
583
691
|
persistReport(documentIdToRun, nextReport);
|
|
584
692
|
} catch (e) {
|
|
585
693
|
if (e instanceof SessionExpiredError) {
|
|
586
|
-
|
|
694
|
+
dispatch2(slice.actions.runAborted());
|
|
587
695
|
return;
|
|
588
696
|
}
|
|
589
|
-
|
|
697
|
+
dispatch2(slice.actions.runFailed(e instanceof Error ? e.message : "Unknown error"));
|
|
590
698
|
}
|
|
591
699
|
};
|
|
592
|
-
return { status, report, error, run };
|
|
700
|
+
return { status, report, error, isStale, run };
|
|
593
701
|
}
|
|
594
702
|
|
|
595
703
|
// src/components/audit-feedback.tsx
|
|
596
|
-
var
|
|
704
|
+
var React2 = __toESM(require("react"));
|
|
597
705
|
var import_react2 = require("react");
|
|
706
|
+
var import_editor_floating_panels = require("@elementor/editor-floating-panels");
|
|
598
707
|
var import_editor_notifications = require("@elementor/editor-notifications");
|
|
599
708
|
var import_editor_v1_adapters = require("@elementor/editor-v1-adapters");
|
|
600
709
|
var import_events = require("@elementor/events");
|
|
601
710
|
var import_http_client2 = require("@elementor/http-client");
|
|
602
|
-
var
|
|
603
|
-
var
|
|
604
|
-
var
|
|
711
|
+
var import_icons2 = require("@elementor/icons");
|
|
712
|
+
var import_ui2 = require("@elementor/ui");
|
|
713
|
+
var import_i18n2 = require("@wordpress/i18n");
|
|
605
714
|
var FEEDBACK_SUBJECT = "Page Audit Tool";
|
|
606
|
-
var FEEDBACK_SUBJECT_LABEL = (0,
|
|
715
|
+
var FEEDBACK_SUBJECT_LABEL = (0, import_i18n2.__)("Page Audit Tool", "elementor");
|
|
607
716
|
var SUCCESS_NOTIFICATION_ID = "audit-feedback-success";
|
|
608
717
|
var ERROR_NOTIFICATION_ID = "audit-feedback-error";
|
|
609
718
|
var DIALOG_TITLE_ID = "audit-feedback-dialog-title";
|
|
@@ -612,18 +721,19 @@ var isUserConnected = () => Boolean(window.elementorCommon?.config?.library_conn
|
|
|
612
721
|
var notifySuccess = () => (0, import_editor_notifications.notify)({
|
|
613
722
|
id: SUCCESS_NOTIFICATION_ID,
|
|
614
723
|
type: "success",
|
|
615
|
-
message: (0,
|
|
724
|
+
message: (0, import_i18n2.__)("Feedback sent. Thanks for helping us out.", "elementor")
|
|
616
725
|
});
|
|
617
726
|
var notifyError = () => (0, import_editor_notifications.notify)({
|
|
618
727
|
id: ERROR_NOTIFICATION_ID,
|
|
619
728
|
type: "error",
|
|
620
|
-
message: (0,
|
|
729
|
+
message: (0, import_i18n2.__)("Something went wrong. Please try sending your feedback again.", "elementor")
|
|
621
730
|
});
|
|
622
731
|
function AuditFeedback() {
|
|
623
732
|
const [isOpen, setIsOpen] = (0, import_react2.useState)(false);
|
|
624
733
|
const [feedbackText, setFeedbackText] = (0, import_react2.useState)("");
|
|
625
734
|
const [isSubmitting, setIsSubmitting] = (0, import_react2.useState)(false);
|
|
626
735
|
const { dispatchEvent: trackEvent = (...args) => void args } = (0, import_events.useMixpanel)();
|
|
736
|
+
const panelZIndex = (0, import_editor_floating_panels.useFloatingPanelZIndex)(AUDIT_PANEL_ID);
|
|
627
737
|
if (!(0, import_editor_v1_adapters.isExperimentActive)(FEEDBACK_EXPERIMENT_NAME)) {
|
|
628
738
|
return null;
|
|
629
739
|
}
|
|
@@ -632,7 +742,7 @@ function AuditFeedback() {
|
|
|
632
742
|
if (!connected && !connectUrl) {
|
|
633
743
|
return null;
|
|
634
744
|
}
|
|
635
|
-
const triggerLabel = (0,
|
|
745
|
+
const triggerLabel = (0, import_i18n2.__)("Give feedback", "elementor");
|
|
636
746
|
const handleOpen = () => {
|
|
637
747
|
if (!connected) {
|
|
638
748
|
window.open(connectUrl, "_blank", "noopener");
|
|
@@ -665,8 +775,8 @@ function AuditFeedback() {
|
|
|
665
775
|
trackEvent(FEEDBACK_SENT_EVENT, { entry_point: FEEDBACK_ENTRY_POINT });
|
|
666
776
|
}).catch(notifyError).finally(() => setIsSubmitting(false));
|
|
667
777
|
};
|
|
668
|
-
return /* @__PURE__ */
|
|
669
|
-
|
|
778
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(import_ui2.Tooltip, { title: triggerLabel, placement: "top", PopperProps: { sx: { zIndex: panelZIndex } } }, /* @__PURE__ */ React2.createElement(import_ui2.IconButton, { size: "small", "aria-label": triggerLabel, onClick: handleOpen }, /* @__PURE__ */ React2.createElement(import_icons2.MessageLinesIcon, { fontSize: "small" }))), /* @__PURE__ */ React2.createElement(
|
|
779
|
+
import_ui2.Dialog,
|
|
670
780
|
{
|
|
671
781
|
open: isOpen,
|
|
672
782
|
onClose: handleClose,
|
|
@@ -674,11 +784,11 @@ function AuditFeedback() {
|
|
|
674
784
|
"aria-describedby": DIALOG_DESCRIPTION_ID,
|
|
675
785
|
PaperProps: { sx: { borderRadius: 1 } }
|
|
676
786
|
},
|
|
677
|
-
/* @__PURE__ */
|
|
678
|
-
/* @__PURE__ */
|
|
679
|
-
|
|
787
|
+
/* @__PURE__ */ React2.createElement(import_ui2.DialogHeader, { logo: false, onClose: handleClose }, /* @__PURE__ */ React2.createElement(import_ui2.DialogTitle, { id: DIALOG_TITLE_ID }, (0, import_i18n2.__)("Let us know what you think", "elementor"))),
|
|
788
|
+
/* @__PURE__ */ React2.createElement(import_ui2.DialogContent, { dividers: true }, /* @__PURE__ */ React2.createElement(import_ui2.Stack, { direction: "column", gap: 2 }, /* @__PURE__ */ React2.createElement(import_ui2.TextField, { value: FEEDBACK_SUBJECT_LABEL, disabled: true, fullWidth: true, size: "small" }), /* @__PURE__ */ React2.createElement(
|
|
789
|
+
import_ui2.TextField,
|
|
680
790
|
{
|
|
681
|
-
placeholder: (0,
|
|
791
|
+
placeholder: (0, import_i18n2.__)(
|
|
682
792
|
"Tell us what you had in mind, what we can improve or fix to make this feature better.",
|
|
683
793
|
"elementor"
|
|
684
794
|
),
|
|
@@ -689,48 +799,48 @@ function AuditFeedback() {
|
|
|
689
799
|
onChange: (event) => setFeedbackText(event.target.value),
|
|
690
800
|
value: feedbackText
|
|
691
801
|
}
|
|
692
|
-
), /* @__PURE__ */
|
|
802
|
+
), /* @__PURE__ */ React2.createElement(import_ui2.Typography, { id: DIALOG_DESCRIPTION_ID, variant: "caption", color: "text.secondary" }, (0, import_i18n2.__)(
|
|
693
803
|
"We appreciate your feedback! While we review all submissions, we can't guarantee that every suggestion will result in a change or update.",
|
|
694
804
|
"elementor"
|
|
695
805
|
)))),
|
|
696
|
-
/* @__PURE__ */
|
|
697
|
-
|
|
806
|
+
/* @__PURE__ */ React2.createElement(import_ui2.DialogActions, null, /* @__PURE__ */ React2.createElement(import_ui2.Button, { variant: "text", color: "secondary", onClick: handleCancel }, (0, import_i18n2.__)("Cancel", "elementor")), /* @__PURE__ */ React2.createElement(
|
|
807
|
+
import_ui2.Button,
|
|
698
808
|
{
|
|
699
809
|
variant: "contained",
|
|
700
810
|
color: "primary",
|
|
701
811
|
disabled: isSubmitting || feedbackText.trim().length === 0,
|
|
702
812
|
onClick: handleSubmit
|
|
703
813
|
},
|
|
704
|
-
(0,
|
|
814
|
+
(0, import_i18n2.__)("Send", "elementor")
|
|
705
815
|
))
|
|
706
816
|
));
|
|
707
817
|
}
|
|
708
818
|
|
|
709
819
|
// src/components/pages/error-page.tsx
|
|
710
|
-
var
|
|
711
|
-
var
|
|
712
|
-
var
|
|
820
|
+
var React3 = __toESM(require("react"));
|
|
821
|
+
var import_ui3 = require("@elementor/ui");
|
|
822
|
+
var import_i18n3 = require("@wordpress/i18n");
|
|
713
823
|
function ErrorPage({ message, onRetry }) {
|
|
714
|
-
return /* @__PURE__ */
|
|
824
|
+
return /* @__PURE__ */ React3.createElement(import_ui3.Box, { sx: { display: "flex", flexDirection: "column", alignItems: "center", gap: 1.5, p: 4 } }, /* @__PURE__ */ React3.createElement(import_ui3.Typography, { variant: "body2", color: "error", textAlign: "center" }, message), /* @__PURE__ */ React3.createElement(import_ui3.Button, { variant: "contained", size: "small", onClick: onRetry }, (0, import_i18n3.__)("Try again", "elementor")));
|
|
715
825
|
}
|
|
716
826
|
|
|
717
827
|
// src/components/pages/loading-page.tsx
|
|
718
|
-
var
|
|
719
|
-
var
|
|
720
|
-
var
|
|
828
|
+
var React4 = __toESM(require("react"));
|
|
829
|
+
var import_ui4 = require("@elementor/ui");
|
|
830
|
+
var import_i18n4 = require("@wordpress/i18n");
|
|
721
831
|
function LoadingPage() {
|
|
722
|
-
return /* @__PURE__ */
|
|
832
|
+
return /* @__PURE__ */ React4.createElement(import_ui4.Box, { sx: { display: "flex", flexDirection: "column", alignItems: "center", gap: 1.5, p: 4 } }, /* @__PURE__ */ React4.createElement(import_ui4.CircularProgress, { size: 32 }), /* @__PURE__ */ React4.createElement(import_ui4.Typography, { variant: "body2" }, (0, import_i18n4.__)("Audit in progress.", "elementor")));
|
|
723
833
|
}
|
|
724
834
|
|
|
725
835
|
// src/components/pages/welcome-page.tsx
|
|
726
|
-
var
|
|
727
|
-
var
|
|
728
|
-
var
|
|
836
|
+
var React5 = __toESM(require("react"));
|
|
837
|
+
var import_ui5 = require("@elementor/ui");
|
|
838
|
+
var import_i18n5 = require("@wordpress/i18n");
|
|
729
839
|
var INFORMATION_IMAGE_PATH = "images/information.svg";
|
|
730
840
|
function WelcomePage() {
|
|
731
841
|
const assetsUrl = window.elementorCommon?.config?.urls?.assets ?? "";
|
|
732
|
-
return /* @__PURE__ */
|
|
733
|
-
|
|
842
|
+
return /* @__PURE__ */ React5.createElement(
|
|
843
|
+
import_ui5.Box,
|
|
734
844
|
{
|
|
735
845
|
sx: {
|
|
736
846
|
display: "flex",
|
|
@@ -741,17 +851,17 @@ function WelcomePage() {
|
|
|
741
851
|
p: 3
|
|
742
852
|
}
|
|
743
853
|
},
|
|
744
|
-
/* @__PURE__ */
|
|
854
|
+
/* @__PURE__ */ React5.createElement(
|
|
745
855
|
"img",
|
|
746
856
|
{
|
|
747
857
|
className: "elementor-nerd-box-icon",
|
|
748
858
|
src: `${assetsUrl}${INFORMATION_IMAGE_PATH}`,
|
|
749
859
|
loading: "lazy",
|
|
750
|
-
alt: (0,
|
|
860
|
+
alt: (0, import_i18n5.__)("Elementor", "elementor")
|
|
751
861
|
}
|
|
752
862
|
),
|
|
753
|
-
/* @__PURE__ */
|
|
754
|
-
/* @__PURE__ */
|
|
863
|
+
/* @__PURE__ */ React5.createElement(import_ui5.Typography, { variant: "subtitle1", component: "h3", sx: { marginBlockStart: 2 } }, (0, import_i18n5.__)("Audit your page!", "elementor")),
|
|
864
|
+
/* @__PURE__ */ React5.createElement(import_ui5.Typography, { variant: "caption", textAlign: "center" }, (0, import_i18n5.__)(
|
|
755
865
|
'Check SEO, accessibility, performance, and best practices. Click "Run page audit" to begin.',
|
|
756
866
|
"elementor"
|
|
757
867
|
))
|
|
@@ -759,41 +869,60 @@ function WelcomePage() {
|
|
|
759
869
|
}
|
|
760
870
|
|
|
761
871
|
// src/components/report-shell.tsx
|
|
762
|
-
var
|
|
763
|
-
var
|
|
764
|
-
var
|
|
765
|
-
var import_i18n22 = require("@wordpress/i18n");
|
|
872
|
+
var React19 = __toESM(require("react"));
|
|
873
|
+
var import_react5 = require("react");
|
|
874
|
+
var import_ui18 = require("@elementor/ui");
|
|
766
875
|
|
|
767
|
-
// src/components/pages/
|
|
768
|
-
var
|
|
769
|
-
var
|
|
770
|
-
var
|
|
876
|
+
// src/components/pages/category-page.tsx
|
|
877
|
+
var React13 = __toESM(require("react"));
|
|
878
|
+
var import_ui12 = require("@elementor/ui");
|
|
879
|
+
var import_i18n11 = require("@wordpress/i18n");
|
|
771
880
|
|
|
772
|
-
// src/
|
|
773
|
-
var React5 = __toESM(require("react"));
|
|
881
|
+
// src/hooks/use-single-expanded-card.ts
|
|
774
882
|
var import_react3 = require("react");
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
883
|
+
function useSingleExpandedCard(initialId = null) {
|
|
884
|
+
const [expandedId, setExpandedId] = (0, import_react3.useState)(initialId);
|
|
885
|
+
const toggle = (id) => {
|
|
886
|
+
setExpandedId((current) => current === id ? null : id);
|
|
887
|
+
};
|
|
888
|
+
return { expandedId, toggle };
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
// src/components/category-icons.ts
|
|
892
|
+
var import_icons3 = require("@elementor/icons");
|
|
893
|
+
var CATEGORY_ICONS = {
|
|
894
|
+
"best-practices": import_icons3.Settings2Icon,
|
|
895
|
+
seo: import_icons3.FileSearchIcon,
|
|
896
|
+
accessibility: import_icons3.ElementorAccessibilityIcon,
|
|
897
|
+
performance: import_icons3.BoltIcon,
|
|
898
|
+
compliance: import_icons3.ShieldCheckIcon
|
|
899
|
+
};
|
|
900
|
+
|
|
901
|
+
// src/components/status-section.tsx
|
|
902
|
+
var React6 = __toESM(require("react"));
|
|
903
|
+
var import_react4 = require("react");
|
|
904
|
+
var import_icons4 = require("@elementor/icons");
|
|
905
|
+
var import_ui6 = require("@elementor/ui");
|
|
906
|
+
var import_i18n6 = require("@wordpress/i18n");
|
|
778
907
|
function StatusSection({ label, count, color = "default", defaultExpanded = false, children }) {
|
|
779
|
-
const [expanded, setExpanded] = (0,
|
|
780
|
-
if (
|
|
908
|
+
const [expanded, setExpanded] = (0, import_react4.useState)(defaultExpanded);
|
|
909
|
+
if (React6.Children.count(children) === 0) {
|
|
781
910
|
return null;
|
|
782
911
|
}
|
|
783
|
-
return /* @__PURE__ */
|
|
784
|
-
|
|
912
|
+
return /* @__PURE__ */ React6.createElement(import_ui6.Box, { sx: { paddingBlock: 1 } }, /* @__PURE__ */ React6.createElement(
|
|
913
|
+
import_ui6.Box,
|
|
785
914
|
{
|
|
786
915
|
sx: { display: "flex", alignItems: "center", gap: 0.5, cursor: "pointer" },
|
|
787
916
|
onClick: () => setExpanded((v) => !v)
|
|
788
917
|
},
|
|
789
|
-
/* @__PURE__ */
|
|
790
|
-
|
|
918
|
+
/* @__PURE__ */ React6.createElement(
|
|
919
|
+
import_ui6.IconButton,
|
|
791
920
|
{
|
|
792
921
|
size: "small",
|
|
793
|
-
"aria-label": expanded ? (0,
|
|
922
|
+
"aria-label": expanded ? (0, import_i18n6.__)("Collapse", "elementor") : (0, import_i18n6.__)("Expand", "elementor")
|
|
794
923
|
},
|
|
795
|
-
/* @__PURE__ */
|
|
796
|
-
|
|
924
|
+
/* @__PURE__ */ React6.createElement(
|
|
925
|
+
import_icons4.ChevronDownIcon,
|
|
797
926
|
{
|
|
798
927
|
fontSize: "small",
|
|
799
928
|
sx: {
|
|
@@ -803,37 +932,37 @@ function StatusSection({ label, count, color = "default", defaultExpanded = fals
|
|
|
803
932
|
}
|
|
804
933
|
)
|
|
805
934
|
),
|
|
806
|
-
/* @__PURE__ */
|
|
807
|
-
), /* @__PURE__ */
|
|
935
|
+
/* @__PURE__ */ React6.createElement(import_ui6.Chip, { label: `${label} (${count})`, size: "small", color, variant: "standard" })
|
|
936
|
+
), /* @__PURE__ */ React6.createElement(import_ui6.Collapse, { in: expanded }, /* @__PURE__ */ React6.createElement(import_ui6.Box, { sx: { paddingInlineStart: 4.25, paddingBlock: 2 } }, children)));
|
|
808
937
|
}
|
|
809
938
|
|
|
810
939
|
// src/components/subpage-header.tsx
|
|
811
|
-
var
|
|
812
|
-
var
|
|
813
|
-
var
|
|
814
|
-
var
|
|
940
|
+
var React7 = __toESM(require("react"));
|
|
941
|
+
var import_icons5 = require("@elementor/icons");
|
|
942
|
+
var import_ui7 = require("@elementor/ui");
|
|
943
|
+
var import_i18n7 = require("@wordpress/i18n");
|
|
815
944
|
function SubpageHeader({ title, onBack, backLabel, icon }) {
|
|
816
|
-
const isRtl = "rtl" === (0,
|
|
817
|
-
return /* @__PURE__ */
|
|
945
|
+
const isRtl = "rtl" === (0, import_ui7.useTheme)().direction;
|
|
946
|
+
return /* @__PURE__ */ React7.createElement(import_ui7.Box, { sx: { display: "flex", alignItems: "center", gap: 0.5, p: 1 } }, /* @__PURE__ */ React7.createElement(import_ui7.IconButton, { size: "small", onClick: onBack, "aria-label": backLabel ?? (0, import_i18n7.__)("Back", "elementor") }, /* @__PURE__ */ React7.createElement(import_ui7.Rotate, { in: isRtl }, /* @__PURE__ */ React7.createElement(import_icons5.ArrowLeftIcon, { fontSize: "small" }))), icon, /* @__PURE__ */ React7.createElement(import_ui7.Typography, { variant: "subtitle2", fontWeight: "bold" }, title));
|
|
818
947
|
}
|
|
819
948
|
|
|
820
949
|
// src/components/violation-row.tsx
|
|
821
|
-
var
|
|
822
|
-
var
|
|
823
|
-
var
|
|
824
|
-
var
|
|
825
|
-
var
|
|
826
|
-
var
|
|
950
|
+
var React12 = __toESM(require("react"));
|
|
951
|
+
var import_editor_elements5 = require("@elementor/editor-elements");
|
|
952
|
+
var import_editor_floating_panels2 = require("@elementor/editor-floating-panels");
|
|
953
|
+
var import_icons10 = require("@elementor/icons");
|
|
954
|
+
var import_ui11 = require("@elementor/ui");
|
|
955
|
+
var import_i18n10 = require("@wordpress/i18n");
|
|
827
956
|
|
|
828
957
|
// src/hooks/focus-violation.ts
|
|
829
|
-
var
|
|
958
|
+
var import_editor_elements4 = require("@elementor/editor-elements");
|
|
830
959
|
var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
|
|
831
960
|
var SCROLL_TO_VIEW_DELAY_MS = 200;
|
|
832
961
|
function focusViolation(violation) {
|
|
833
962
|
if (violation.elementId) {
|
|
834
|
-
const container = (0,
|
|
963
|
+
const container = (0, import_editor_elements4.getContainer)(violation.elementId);
|
|
835
964
|
if (container) {
|
|
836
|
-
(0,
|
|
965
|
+
(0, import_editor_elements4.selectElement)(violation.elementId);
|
|
837
966
|
const domElement = container.view?.getDomElement?.();
|
|
838
967
|
if (domElement) {
|
|
839
968
|
window.elementor?.helpers?.scrollToView?.(domElement, SCROLL_TO_VIEW_DELAY_MS);
|
|
@@ -864,11 +993,11 @@ function focusViolation(violation) {
|
|
|
864
993
|
}
|
|
865
994
|
|
|
866
995
|
// src/utils/build-angie-prompt.ts
|
|
867
|
-
var
|
|
996
|
+
var import_i18n8 = require("@wordpress/i18n");
|
|
868
997
|
function buildAngiePrompt(violationText) {
|
|
869
|
-
return (0,
|
|
998
|
+
return (0, import_i18n8.sprintf)(
|
|
870
999
|
/* translators: %s: audit violation description. */
|
|
871
|
-
(0,
|
|
1000
|
+
(0, import_i18n8.__)("Help me fix: %s", "elementor"),
|
|
872
1001
|
violationText
|
|
873
1002
|
);
|
|
874
1003
|
}
|
|
@@ -884,13 +1013,13 @@ function onKeyboardClick(callback) {
|
|
|
884
1013
|
}
|
|
885
1014
|
|
|
886
1015
|
// src/components/fix-violation-with-angie.tsx
|
|
887
|
-
var
|
|
1016
|
+
var React8 = __toESM(require("react"));
|
|
888
1017
|
var import_editor_mcp = require("@elementor/editor-mcp");
|
|
889
|
-
var
|
|
890
|
-
var
|
|
891
|
-
var
|
|
892
|
-
function FixViolationWithAngie({ prompt }) {
|
|
893
|
-
const label = (0,
|
|
1018
|
+
var import_icons6 = require("@elementor/icons");
|
|
1019
|
+
var import_ui8 = require("@elementor/ui");
|
|
1020
|
+
var import_i18n9 = require("@wordpress/i18n");
|
|
1021
|
+
function FixViolationWithAngie({ prompt, panelZIndex, variant = "icon" }) {
|
|
1022
|
+
const label = (0, import_i18n9.__)("Fix with Angie", "elementor");
|
|
894
1023
|
const href = `#angie-prompt=${encodeURIComponent(prompt)}`;
|
|
895
1024
|
const handleClick = (event) => {
|
|
896
1025
|
event.stopPropagation();
|
|
@@ -908,53 +1037,70 @@ function FixViolationWithAngie({ prompt }) {
|
|
|
908
1037
|
})
|
|
909
1038
|
);
|
|
910
1039
|
};
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
1040
|
+
if (variant === "button") {
|
|
1041
|
+
return /* @__PURE__ */ React8.createElement(
|
|
1042
|
+
import_ui8.Button,
|
|
1043
|
+
{
|
|
1044
|
+
component: "a",
|
|
1045
|
+
href,
|
|
1046
|
+
size: "small",
|
|
1047
|
+
color: "secondary",
|
|
1048
|
+
variant: "outlined",
|
|
1049
|
+
startIcon: /* @__PURE__ */ React8.createElement(import_icons6.AngieIcon, { fontSize: "tiny", "aria-hidden": true }),
|
|
1050
|
+
onClick: handleClick
|
|
1051
|
+
},
|
|
1052
|
+
label
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
1055
|
+
return /* @__PURE__ */ React8.createElement(import_ui8.Tooltip, { title: label, placement: "top", PopperProps: { sx: { zIndex: panelZIndex } } }, /* @__PURE__ */ React8.createElement(import_ui8.IconButton, { component: "a", href, size: "small", "aria-label": label, onClick: handleClick }, /* @__PURE__ */ React8.createElement(import_icons6.AngieIcon, { fontSize: "tiny" })));
|
|
923
1056
|
}
|
|
924
1057
|
|
|
925
1058
|
// src/components/severity-icons.tsx
|
|
926
|
-
var
|
|
927
|
-
var
|
|
1059
|
+
var React9 = __toESM(require("react"));
|
|
1060
|
+
var import_icons7 = require("@elementor/icons");
|
|
928
1061
|
var SEVERITY_CONFIG = {
|
|
929
|
-
error: { Icon:
|
|
930
|
-
warning: { Icon:
|
|
931
|
-
info: { Icon:
|
|
1062
|
+
error: { Icon: import_icons7.AlertTriangleFilledIcon, color: "error" },
|
|
1063
|
+
warning: { Icon: import_icons7.AlertCircleIcon, color: "warning" },
|
|
1064
|
+
info: { Icon: import_icons7.BulbIcon, color: "info" }
|
|
932
1065
|
};
|
|
1066
|
+
var INFO_ICON_VERTICAL_NUDGE = "translateY(-2px)";
|
|
933
1067
|
function SeverityIcon({ severity }) {
|
|
934
1068
|
const { Icon, color } = SEVERITY_CONFIG[severity];
|
|
935
|
-
|
|
1069
|
+
const sx = "info" === severity ? { transform: INFO_ICON_VERTICAL_NUDGE } : void 0;
|
|
1070
|
+
return /* @__PURE__ */ React9.createElement(Icon, { fontSize: "small", color, sx });
|
|
936
1071
|
}
|
|
937
1072
|
|
|
938
1073
|
// src/components/violation-cta-button.tsx
|
|
939
|
-
var
|
|
940
|
-
var
|
|
941
|
-
|
|
1074
|
+
var React10 = __toESM(require("react"));
|
|
1075
|
+
var import_icons8 = require("@elementor/icons");
|
|
1076
|
+
var import_ui9 = require("@elementor/ui");
|
|
1077
|
+
function ViolationCtaButton({ ctaLabel, externalUrl, variant = "outlined", withIcon = false }) {
|
|
942
1078
|
const handleClick = (event) => {
|
|
943
1079
|
event.stopPropagation();
|
|
944
1080
|
event.preventDefault();
|
|
945
1081
|
window.open(externalUrl, "_blank", "noopener");
|
|
946
1082
|
};
|
|
947
|
-
return /* @__PURE__ */
|
|
1083
|
+
return /* @__PURE__ */ React10.createElement(
|
|
1084
|
+
import_ui9.Button,
|
|
1085
|
+
{
|
|
1086
|
+
variant,
|
|
1087
|
+
color: "secondary",
|
|
1088
|
+
size: "small",
|
|
1089
|
+
startIcon: withIcon ? /* @__PURE__ */ React10.createElement(import_icons8.WandIcon, { fontSize: "tiny", "aria-hidden": true }) : void 0,
|
|
1090
|
+
onClick: handleClick
|
|
1091
|
+
},
|
|
1092
|
+
ctaLabel
|
|
1093
|
+
);
|
|
948
1094
|
}
|
|
949
1095
|
|
|
950
1096
|
// src/components/violation-icons.tsx
|
|
951
|
-
var
|
|
952
|
-
var
|
|
953
|
-
var
|
|
1097
|
+
var React11 = __toESM(require("react"));
|
|
1098
|
+
var import_icons9 = require("@elementor/icons");
|
|
1099
|
+
var import_ui10 = require("@elementor/ui");
|
|
954
1100
|
function ViolationIcon({ violation, widgetIcon }) {
|
|
955
1101
|
if (widgetIcon) {
|
|
956
|
-
return /* @__PURE__ */
|
|
957
|
-
|
|
1102
|
+
return /* @__PURE__ */ React11.createElement(
|
|
1103
|
+
import_ui10.Box,
|
|
958
1104
|
{
|
|
959
1105
|
component: "i",
|
|
960
1106
|
className: widgetIcon,
|
|
@@ -964,29 +1110,74 @@ function ViolationIcon({ violation, widgetIcon }) {
|
|
|
964
1110
|
);
|
|
965
1111
|
}
|
|
966
1112
|
if (violation.targetHint === "page-settings") {
|
|
967
|
-
return /* @__PURE__ */
|
|
1113
|
+
return /* @__PURE__ */ React11.createElement(import_icons9.FileSettingsIcon, { fontSize: "inherit", "aria-hidden": true });
|
|
968
1114
|
}
|
|
969
1115
|
if (violation.targetHint === "site-settings" || violation.targetHint === "site-identity-settings") {
|
|
970
|
-
return /* @__PURE__ */
|
|
1116
|
+
return /* @__PURE__ */ React11.createElement(import_icons9.SettingsIcon, { fontSize: "inherit", "aria-hidden": true });
|
|
971
1117
|
}
|
|
972
|
-
return /* @__PURE__ */
|
|
1118
|
+
return /* @__PURE__ */ React11.createElement(import_icons9.SettingsIcon, { fontSize: "inherit", "aria-hidden": true });
|
|
973
1119
|
}
|
|
974
1120
|
|
|
975
1121
|
// src/components/violation-row.tsx
|
|
976
1122
|
function SkipReasonTooltip({ reason }) {
|
|
977
|
-
return /* @__PURE__ */
|
|
1123
|
+
return /* @__PURE__ */ React12.createElement(import_ui11.Tooltip, { title: reason, placement: "top" }, /* @__PURE__ */ React12.createElement(import_ui11.Box, { "aria-label": reason, component: "span", sx: { display: "inline-flex", alignItems: "center" } }, /* @__PURE__ */ React12.createElement(import_icons10.HelpIcon, { fontSize: "small", color: "action" })));
|
|
978
1124
|
}
|
|
979
|
-
function StatusIndicator({ audit:
|
|
1125
|
+
function StatusIndicator({ audit: audit25, violations }) {
|
|
980
1126
|
if (violations) {
|
|
981
|
-
return /* @__PURE__ */
|
|
1127
|
+
return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(SeverityIcon, { severity: audit25.severity }), isScoredAudit(audit25) && /* @__PURE__ */ React12.createElement(import_ui11.Typography, { variant: "caption", color: "text.secondary", fontWeight: "bold" }, violations.length));
|
|
1128
|
+
}
|
|
1129
|
+
return /* @__PURE__ */ React12.createElement(import_icons10.CheckIcon, { fontSize: "small", color: "success" });
|
|
1130
|
+
}
|
|
1131
|
+
function GuidanceAction({
|
|
1132
|
+
violation,
|
|
1133
|
+
sharedAngiePrompt,
|
|
1134
|
+
panelZIndex
|
|
1135
|
+
}) {
|
|
1136
|
+
const hasPrimaryCta = !!(violation.ctaLabel && violation.externalUrl);
|
|
1137
|
+
if (!hasPrimaryCta && !sharedAngiePrompt) {
|
|
1138
|
+
return null;
|
|
1139
|
+
}
|
|
1140
|
+
return /* @__PURE__ */ React12.createElement(import_ui11.Box, { display: "flex", alignItems: "center", gap: 1, mt: 1 }, hasPrimaryCta && /* @__PURE__ */ React12.createElement(
|
|
1141
|
+
ViolationCtaButton,
|
|
1142
|
+
{
|
|
1143
|
+
ctaLabel: violation.ctaLabel,
|
|
1144
|
+
externalUrl: violation.externalUrl,
|
|
1145
|
+
withIcon: true
|
|
1146
|
+
}
|
|
1147
|
+
), hasPrimaryCta && violation.secondaryCtaLabel && violation.secondaryCtaUrl && /* @__PURE__ */ React12.createElement(
|
|
1148
|
+
ViolationCtaButton,
|
|
1149
|
+
{
|
|
1150
|
+
ctaLabel: violation.secondaryCtaLabel,
|
|
1151
|
+
externalUrl: violation.secondaryCtaUrl,
|
|
1152
|
+
variant: "text"
|
|
1153
|
+
}
|
|
1154
|
+
), sharedAngiePrompt && /* @__PURE__ */ React12.createElement(FixViolationWithAngie, { prompt: sharedAngiePrompt, panelZIndex, variant: "button" }));
|
|
1155
|
+
}
|
|
1156
|
+
function getSharedAngiePrompt(violations) {
|
|
1157
|
+
if (!violations || violations.length < 2) {
|
|
1158
|
+
return void 0;
|
|
1159
|
+
}
|
|
1160
|
+
const [first, ...rest] = violations;
|
|
1161
|
+
if (!first.angieFix || !first.angiePrompt) {
|
|
1162
|
+
return void 0;
|
|
982
1163
|
}
|
|
983
|
-
|
|
1164
|
+
const allShareTheSameFix = rest.every(
|
|
1165
|
+
(violation) => violation.angieFix && violation.angiePrompt === first.angiePrompt
|
|
1166
|
+
);
|
|
1167
|
+
return allShareTheSameFix ? first.angiePrompt : void 0;
|
|
984
1168
|
}
|
|
985
|
-
function ViolationRow({ audit:
|
|
986
|
-
const
|
|
987
|
-
const
|
|
988
|
-
|
|
989
|
-
|
|
1169
|
+
function ViolationRow({ audit: audit25, expanded, onToggleExpand, skipReason, violations }) {
|
|
1170
|
+
const primaryViolation = violations?.[0];
|
|
1171
|
+
const isGuidanceFocusable = !!primaryViolation;
|
|
1172
|
+
const panelZIndex = (0, import_editor_floating_panels2.useFloatingPanelZIndex)(AUDIT_PANEL_ID);
|
|
1173
|
+
const sharedAngiePrompt = getSharedAngiePrompt(violations);
|
|
1174
|
+
const handleGuidanceClick = () => {
|
|
1175
|
+
if (isGuidanceFocusable && primaryViolation) {
|
|
1176
|
+
focusViolation(primaryViolation);
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
1179
|
+
return /* @__PURE__ */ React12.createElement(import_ui11.Box, { sx: { borderBottom: 1, borderColor: "divider", paddingBlock: 0.5 } }, /* @__PURE__ */ React12.createElement(import_ui11.Box, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React12.createElement(
|
|
1180
|
+
import_ui11.Box,
|
|
990
1181
|
{
|
|
991
1182
|
sx: {
|
|
992
1183
|
alignItems: "center",
|
|
@@ -996,19 +1187,19 @@ function ViolationRow({ audit: audit23, skipReason, violations }) {
|
|
|
996
1187
|
gap: 0.5,
|
|
997
1188
|
minWidth: 0
|
|
998
1189
|
},
|
|
999
|
-
onClick:
|
|
1190
|
+
onClick: onToggleExpand
|
|
1000
1191
|
},
|
|
1001
|
-
/* @__PURE__ */
|
|
1002
|
-
!skipReason && /* @__PURE__ */
|
|
1003
|
-
), skipReason && /* @__PURE__ */
|
|
1004
|
-
|
|
1192
|
+
/* @__PURE__ */ React12.createElement(import_ui11.Typography, { variant: "subtitle2", color: "text.secondary", sx: { flex: 1 } }, audit25.title),
|
|
1193
|
+
!skipReason && /* @__PURE__ */ React12.createElement(StatusIndicator, { audit: audit25, violations })
|
|
1194
|
+
), skipReason && /* @__PURE__ */ React12.createElement(SkipReasonTooltip, { reason: skipReason }), /* @__PURE__ */ React12.createElement(
|
|
1195
|
+
import_ui11.IconButton,
|
|
1005
1196
|
{
|
|
1006
1197
|
size: "small",
|
|
1007
|
-
"aria-label": expanded ? (0,
|
|
1008
|
-
onClick:
|
|
1198
|
+
"aria-label": expanded ? (0, import_i18n10.__)("Collapse", "elementor") : (0, import_i18n10.__)("Expand", "elementor"),
|
|
1199
|
+
onClick: onToggleExpand
|
|
1009
1200
|
},
|
|
1010
|
-
/* @__PURE__ */
|
|
1011
|
-
|
|
1201
|
+
/* @__PURE__ */ React12.createElement(
|
|
1202
|
+
import_icons10.ChevronDownIcon,
|
|
1012
1203
|
{
|
|
1013
1204
|
fontSize: "small",
|
|
1014
1205
|
sx: {
|
|
@@ -1017,30 +1208,34 @@ function ViolationRow({ audit: audit23, skipReason, violations }) {
|
|
|
1017
1208
|
}
|
|
1018
1209
|
}
|
|
1019
1210
|
)
|
|
1020
|
-
)), /* @__PURE__ */
|
|
1021
|
-
|
|
1211
|
+
)), /* @__PURE__ */ React12.createElement(import_ui11.Collapse, { in: expanded }, /* @__PURE__ */ React12.createElement(import_ui11.Box, { paddingBlock: 1 }, /* @__PURE__ */ React12.createElement(import_ui11.Tooltip, { title: audit25.fixHint, placement: "top" }, /* @__PURE__ */ React12.createElement(
|
|
1212
|
+
import_ui11.Alert,
|
|
1022
1213
|
{
|
|
1023
1214
|
severity: "secondary",
|
|
1024
|
-
sx: { p: 1 },
|
|
1025
|
-
icon: /* @__PURE__ */
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
import_ui10.Alert,
|
|
1031
|
-
{
|
|
1032
|
-
severity: "info",
|
|
1033
|
-
sx: { p: 1 },
|
|
1034
|
-
icon: /* @__PURE__ */ React11.createElement(import_icons7.BulbIcon, { fontSize: "small", color: "info", "aria-hidden": true })
|
|
1215
|
+
sx: { p: 1, cursor: isGuidanceFocusable ? "pointer" : void 0 },
|
|
1216
|
+
icon: /* @__PURE__ */ React12.createElement(import_icons10.InfoCircleIcon, { fontSize: "small", "aria-hidden": true }),
|
|
1217
|
+
role: isGuidanceFocusable ? "button" : void 0,
|
|
1218
|
+
tabIndex: isGuidanceFocusable ? 0 : void 0,
|
|
1219
|
+
onClick: isGuidanceFocusable ? handleGuidanceClick : void 0,
|
|
1220
|
+
onKeyDown: isGuidanceFocusable ? onKeyboardClick(handleGuidanceClick) : void 0
|
|
1035
1221
|
},
|
|
1036
|
-
/* @__PURE__ */
|
|
1037
|
-
/* @__PURE__ */
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1222
|
+
/* @__PURE__ */ React12.createElement(import_ui11.Typography, { variant: "caption", component: "p", color: "text.secondary" }, audit25.description),
|
|
1223
|
+
primaryViolation && /* @__PURE__ */ React12.createElement(
|
|
1224
|
+
GuidanceAction,
|
|
1225
|
+
{
|
|
1226
|
+
violation: primaryViolation,
|
|
1227
|
+
sharedAngiePrompt,
|
|
1228
|
+
panelZIndex
|
|
1229
|
+
}
|
|
1230
|
+
)
|
|
1231
|
+
))), violations && violations.length > 0 && /* @__PURE__ */ React12.createElement(import_ui11.Box, { role: "list", sx: { paddingBlockEnd: 1 } }, violations.map((violation, idx) => {
|
|
1232
|
+
const widgetIcon = violation.elementId ? (0, import_editor_elements5.getElementIcon)(violation.elementId) : null;
|
|
1233
|
+
const elementTitle = violation.elementId ? (0, import_editor_elements5.getElementTitle)(violation.elementId) : null;
|
|
1234
|
+
const displayLabel = elementTitle ?? violation.label;
|
|
1235
|
+
const angiePromptContext = elementTitle ? `${elementTitle} - ${violation.label}` : violation.label;
|
|
1236
|
+
const showsOwnFixAction = !!violation.angieFix && !sharedAngiePrompt;
|
|
1237
|
+
return /* @__PURE__ */ React12.createElement(
|
|
1238
|
+
import_ui11.Box,
|
|
1044
1239
|
{
|
|
1045
1240
|
key: idx,
|
|
1046
1241
|
role: "button",
|
|
@@ -1052,258 +1247,130 @@ function ViolationRow({ audit: audit23, skipReason, violations }) {
|
|
|
1052
1247
|
alignItems: "center",
|
|
1053
1248
|
gap: 1,
|
|
1054
1249
|
paddingBlock: 0.5,
|
|
1055
|
-
paddingInline:
|
|
1250
|
+
paddingInline: 1,
|
|
1056
1251
|
borderRadius: 1,
|
|
1057
1252
|
cursor: "pointer",
|
|
1058
|
-
"& .violation-hover-icon": { opacity: 0, transition: "opacity .15s" },
|
|
1059
1253
|
"&:hover": { bgcolor: "action.hover" },
|
|
1060
|
-
"&:hover .violation-
|
|
1254
|
+
"&:hover .violation-row-fix-action, &:focus-visible .violation-row-fix-action": {
|
|
1061
1255
|
opacity: 1
|
|
1062
1256
|
}
|
|
1063
1257
|
}
|
|
1064
1258
|
},
|
|
1065
|
-
/* @__PURE__ */
|
|
1066
|
-
/* @__PURE__ */
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
{
|
|
1070
|
-
prompt: violation.angiePrompt ?? buildAngiePrompt(rowLabel)
|
|
1071
|
-
}
|
|
1072
|
-
),
|
|
1073
|
-
violation.ctaLabel && violation.externalUrl ? /* @__PURE__ */ React11.createElement(
|
|
1074
|
-
ViolationCtaButton,
|
|
1075
|
-
{
|
|
1076
|
-
ctaLabel: violation.ctaLabel,
|
|
1077
|
-
externalUrl: violation.externalUrl
|
|
1078
|
-
}
|
|
1079
|
-
) : /* @__PURE__ */ React11.createElement(
|
|
1080
|
-
import_icons7.EyeIcon,
|
|
1259
|
+
/* @__PURE__ */ React12.createElement(ViolationIcon, { violation, widgetIcon }),
|
|
1260
|
+
/* @__PURE__ */ React12.createElement(import_ui11.Box, { sx: { flex: 1 } }, /* @__PURE__ */ React12.createElement(import_ui11.Typography, { variant: "caption" }, displayLabel), violation.detail && /* @__PURE__ */ React12.createElement(import_ui11.Typography, { variant: "caption", color: "text.secondary" }, violation.detail)),
|
|
1261
|
+
showsOwnFixAction && /* @__PURE__ */ React12.createElement(
|
|
1262
|
+
import_ui11.Box,
|
|
1081
1263
|
{
|
|
1082
|
-
className: "violation-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1264
|
+
className: "violation-row-fix-action",
|
|
1265
|
+
sx: { opacity: 0, transition: "opacity .15s" }
|
|
1266
|
+
},
|
|
1267
|
+
/* @__PURE__ */ React12.createElement(
|
|
1268
|
+
FixViolationWithAngie,
|
|
1269
|
+
{
|
|
1270
|
+
prompt: violation.angiePrompt ?? buildAngiePrompt(angiePromptContext),
|
|
1271
|
+
panelZIndex
|
|
1272
|
+
}
|
|
1273
|
+
)
|
|
1086
1274
|
)
|
|
1087
1275
|
);
|
|
1088
1276
|
}))));
|
|
1089
1277
|
}
|
|
1090
1278
|
|
|
1091
|
-
// src/components/pages/all-audits-page.tsx
|
|
1092
|
-
function AllAuditsPage({ initialExpandedStatus, onBack, report }) {
|
|
1093
|
-
const { failed, passed, skipped, totalViolations } = partitionAuditResults(report);
|
|
1094
|
-
const expandFail = !initialExpandedStatus || initialExpandedStatus === "fail";
|
|
1095
|
-
const expandPass = initialExpandedStatus === "pass";
|
|
1096
|
-
const expandSkipped = initialExpandedStatus === "skipped";
|
|
1097
|
-
return /* @__PURE__ */ React12.createElement(import_ui11.Box, { key: initialExpandedStatus ?? "default" }, /* @__PURE__ */ React12.createElement(SubpageHeader, { title: (0, import_i18n12.__)("All audits", "elementor"), onBack }), /* @__PURE__ */ React12.createElement(import_ui11.Box, { sx: { p: 1 } }, /* @__PURE__ */ React12.createElement(
|
|
1098
|
-
StatusSection,
|
|
1099
|
-
{
|
|
1100
|
-
label: auditStatusLabel("fail"),
|
|
1101
|
-
count: totalViolations,
|
|
1102
|
-
color: auditStatusColor("fail"),
|
|
1103
|
-
defaultExpanded: expandFail
|
|
1104
|
-
},
|
|
1105
|
-
failed.map((r) => /* @__PURE__ */ React12.createElement(ViolationRow, { key: r.audit.id, audit: r.audit, violations: r.result.violations }))
|
|
1106
|
-
), /* @__PURE__ */ React12.createElement(
|
|
1107
|
-
StatusSection,
|
|
1108
|
-
{
|
|
1109
|
-
label: auditStatusLabel("pass"),
|
|
1110
|
-
count: passed.length,
|
|
1111
|
-
color: auditStatusColor("pass"),
|
|
1112
|
-
defaultExpanded: expandPass
|
|
1113
|
-
},
|
|
1114
|
-
passed.map((r) => /* @__PURE__ */ React12.createElement(ViolationRow, { key: r.audit.id, audit: r.audit }))
|
|
1115
|
-
), /* @__PURE__ */ React12.createElement(
|
|
1116
|
-
StatusSection,
|
|
1117
|
-
{
|
|
1118
|
-
label: auditStatusLabel("skipped"),
|
|
1119
|
-
count: skipped.length,
|
|
1120
|
-
color: auditStatusColor("skipped"),
|
|
1121
|
-
defaultExpanded: expandSkipped
|
|
1122
|
-
},
|
|
1123
|
-
skipped.map((r) => /* @__PURE__ */ React12.createElement(ViolationRow, { key: r.audit.id, audit: r.audit, skipReason: r.result.reason }))
|
|
1124
|
-
)));
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
// src/components/pages/category-page.tsx
|
|
1128
|
-
var React13 = __toESM(require("react"));
|
|
1129
|
-
var import_ui12 = require("@elementor/ui");
|
|
1130
|
-
var import_i18n13 = require("@wordpress/i18n");
|
|
1131
|
-
|
|
1132
|
-
// src/components/category-icons.ts
|
|
1133
|
-
var import_icons8 = require("@elementor/icons");
|
|
1134
|
-
var CATEGORY_ICONS = {
|
|
1135
|
-
"best-practices": import_icons8.Settings2Icon,
|
|
1136
|
-
seo: import_icons8.FileSearchIcon,
|
|
1137
|
-
accessibility: import_icons8.ElementorAccessibilityIcon,
|
|
1138
|
-
performance: import_icons8.BoltIcon,
|
|
1139
|
-
compliance: import_icons8.ShieldCheckIcon
|
|
1140
|
-
};
|
|
1141
|
-
|
|
1142
1279
|
// src/components/pages/category-page.tsx
|
|
1143
1280
|
function CategoryPage({ category, report, onBack }) {
|
|
1144
1281
|
const Icon = CATEGORY_ICONS[category];
|
|
1145
|
-
const { failed, passed, totalViolations } = partitionAuditResults(report, { category });
|
|
1282
|
+
const { failed, passed, skipped, totalViolations } = partitionAuditResults(report, { category });
|
|
1283
|
+
const { expandedId, toggle } = useSingleExpandedCard();
|
|
1146
1284
|
return /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(
|
|
1147
1285
|
SubpageHeader,
|
|
1148
1286
|
{
|
|
1149
1287
|
title: CATEGORY_LABELS[category],
|
|
1150
1288
|
onBack,
|
|
1151
|
-
backLabel: (0,
|
|
1289
|
+
backLabel: (0, import_i18n11.__)("Back to all issues", "elementor"),
|
|
1152
1290
|
icon: /* @__PURE__ */ React13.createElement(Icon, { fontSize: "small", color: "action" })
|
|
1153
1291
|
}
|
|
1154
1292
|
), /* @__PURE__ */ React13.createElement(import_ui12.Box, { sx: { p: 1 } }, /* @__PURE__ */ React13.createElement(
|
|
1155
1293
|
StatusSection,
|
|
1156
1294
|
{
|
|
1157
|
-
label: (0,
|
|
1295
|
+
label: (0, import_i18n11.__)("Failed audits", "elementor"),
|
|
1158
1296
|
count: totalViolations,
|
|
1159
1297
|
color: "error",
|
|
1160
1298
|
defaultExpanded: true
|
|
1161
1299
|
},
|
|
1162
|
-
failed.map((r) => /* @__PURE__ */ React13.createElement(
|
|
1163
|
-
|
|
1300
|
+
failed.map((r) => /* @__PURE__ */ React13.createElement(
|
|
1301
|
+
ViolationRow,
|
|
1302
|
+
{
|
|
1303
|
+
key: r.audit.id,
|
|
1304
|
+
audit: r.audit,
|
|
1305
|
+
violations: r.result.violations,
|
|
1306
|
+
expanded: expandedId === r.audit.id,
|
|
1307
|
+
onToggleExpand: () => toggle(r.audit.id)
|
|
1308
|
+
}
|
|
1309
|
+
))
|
|
1310
|
+
), /* @__PURE__ */ React13.createElement(StatusSection, { label: (0, import_i18n11.__)("Passed audits", "elementor"), count: passed.length, color: "success" }, passed.map((r) => /* @__PURE__ */ React13.createElement(
|
|
1311
|
+
ViolationRow,
|
|
1312
|
+
{
|
|
1313
|
+
key: r.audit.id,
|
|
1314
|
+
audit: r.audit,
|
|
1315
|
+
expanded: expandedId === r.audit.id,
|
|
1316
|
+
onToggleExpand: () => toggle(r.audit.id)
|
|
1317
|
+
}
|
|
1318
|
+
))), /* @__PURE__ */ React13.createElement(StatusSection, { label: (0, import_i18n11.__)("Skipped audits", "elementor"), count: skipped.length, color: "default" }, skipped.map((r) => /* @__PURE__ */ React13.createElement(
|
|
1319
|
+
ViolationRow,
|
|
1320
|
+
{
|
|
1321
|
+
key: r.audit.id,
|
|
1322
|
+
audit: r.audit,
|
|
1323
|
+
skipReason: r.result.reason,
|
|
1324
|
+
expanded: expandedId === r.audit.id,
|
|
1325
|
+
onToggleExpand: () => toggle(r.audit.id)
|
|
1326
|
+
}
|
|
1327
|
+
)))));
|
|
1164
1328
|
}
|
|
1165
1329
|
|
|
1166
|
-
// src/components/pages/
|
|
1330
|
+
// src/components/pages/overview-page.tsx
|
|
1167
1331
|
var React18 = __toESM(require("react"));
|
|
1168
|
-
var import_react5 = require("react");
|
|
1169
1332
|
var import_ui17 = require("@elementor/ui");
|
|
1170
|
-
var
|
|
1333
|
+
var import_i18n15 = require("@wordpress/i18n");
|
|
1171
1334
|
|
|
1172
1335
|
// src/utils/severity-counts.ts
|
|
1173
|
-
var
|
|
1336
|
+
var import_i18n12 = require("@wordpress/i18n");
|
|
1174
1337
|
var ALL_SEVERITIES = ["error", "warning", "info"];
|
|
1175
1338
|
function countSeverities(report, category) {
|
|
1176
1339
|
const counts = { error: 0, warning: 0, info: 0 };
|
|
1177
|
-
for (const { audit:
|
|
1340
|
+
for (const { audit: audit25, result } of report.auditResults) {
|
|
1178
1341
|
if (result.status !== "fail") {
|
|
1179
1342
|
continue;
|
|
1180
1343
|
}
|
|
1181
|
-
if (category && !
|
|
1344
|
+
if (category && !audit25.categories.includes(category)) {
|
|
1182
1345
|
continue;
|
|
1183
1346
|
}
|
|
1184
|
-
if (!isScoredAudit(
|
|
1347
|
+
if (!isScoredAudit(audit25)) {
|
|
1185
1348
|
continue;
|
|
1186
1349
|
}
|
|
1187
|
-
counts[
|
|
1350
|
+
counts[audit25.severity] += result.violations.length;
|
|
1188
1351
|
}
|
|
1189
1352
|
return counts;
|
|
1190
1353
|
}
|
|
1191
1354
|
function severityPluralLabel(severity) {
|
|
1192
1355
|
switch (severity) {
|
|
1193
1356
|
case "error":
|
|
1194
|
-
return (0,
|
|
1357
|
+
return (0, import_i18n12.__)("Errors", "elementor");
|
|
1195
1358
|
case "warning":
|
|
1196
|
-
return (0,
|
|
1359
|
+
return (0, import_i18n12.__)("Warnings", "elementor");
|
|
1197
1360
|
case "info":
|
|
1198
|
-
return (0,
|
|
1361
|
+
return (0, import_i18n12.__)("Suggestions", "elementor");
|
|
1199
1362
|
}
|
|
1200
1363
|
}
|
|
1201
1364
|
|
|
1202
|
-
// src/components/
|
|
1203
|
-
var React15 = __toESM(require("react"));
|
|
1204
|
-
var import_ui14 = require("@elementor/ui");
|
|
1205
|
-
var import_i18n15 = require("@wordpress/i18n");
|
|
1206
|
-
|
|
1207
|
-
// src/components/count-summary-circle.tsx
|
|
1365
|
+
// src/components/issues-category-row.tsx
|
|
1208
1366
|
var React14 = __toESM(require("react"));
|
|
1367
|
+
var import_icons11 = require("@elementor/icons");
|
|
1209
1368
|
var import_ui13 = require("@elementor/ui");
|
|
1210
|
-
var COUNT_SUMMARY_CIRCLE_SIZE = 64;
|
|
1211
|
-
var COUNT_SUMMARY_BORDER_WIDTH = 4;
|
|
1212
|
-
function chipBorderColor(theme, color) {
|
|
1213
|
-
if (color === "default" || !color) {
|
|
1214
|
-
return theme.palette.text.secondary;
|
|
1215
|
-
}
|
|
1216
|
-
return theme.palette[color].main;
|
|
1217
|
-
}
|
|
1218
|
-
function CountSummaryCircle({ ariaLabel, color, count, label, onClick }) {
|
|
1219
|
-
return /* @__PURE__ */ React14.createElement(
|
|
1220
|
-
import_ui13.Box,
|
|
1221
|
-
{
|
|
1222
|
-
"aria-label": ariaLabel,
|
|
1223
|
-
component: "button",
|
|
1224
|
-
onClick,
|
|
1225
|
-
type: "button",
|
|
1226
|
-
sx: {
|
|
1227
|
-
alignItems: "center",
|
|
1228
|
-
background: "none",
|
|
1229
|
-
border: "none",
|
|
1230
|
-
cursor: "pointer",
|
|
1231
|
-
display: "flex",
|
|
1232
|
-
flex: 1,
|
|
1233
|
-
flexDirection: "column",
|
|
1234
|
-
gap: 0.5,
|
|
1235
|
-
padding: 0
|
|
1236
|
-
}
|
|
1237
|
-
},
|
|
1238
|
-
/* @__PURE__ */ React14.createElement(
|
|
1239
|
-
import_ui13.Chip,
|
|
1240
|
-
{
|
|
1241
|
-
color,
|
|
1242
|
-
label: count,
|
|
1243
|
-
size: "small",
|
|
1244
|
-
variant: "standard",
|
|
1245
|
-
sx: (theme) => ({
|
|
1246
|
-
border: `${COUNT_SUMMARY_BORDER_WIDTH}px solid ${chipBorderColor(theme, color)}`,
|
|
1247
|
-
borderRadius: "50%",
|
|
1248
|
-
height: COUNT_SUMMARY_CIRCLE_SIZE,
|
|
1249
|
-
maxWidth: COUNT_SUMMARY_CIRCLE_SIZE,
|
|
1250
|
-
width: COUNT_SUMMARY_CIRCLE_SIZE,
|
|
1251
|
-
"& .MuiChip-label": {
|
|
1252
|
-
fontSize: theme.typography.body2.fontSize,
|
|
1253
|
-
fontWeight: 700,
|
|
1254
|
-
lineHeight: 1,
|
|
1255
|
-
padding: 0
|
|
1256
|
-
}
|
|
1257
|
-
})
|
|
1258
|
-
}
|
|
1259
|
-
),
|
|
1260
|
-
/* @__PURE__ */ React14.createElement(import_ui13.Typography, { color: "text.secondary", sx: { textAlign: "center" }, variant: "caption" }, label)
|
|
1261
|
-
);
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
|
-
// src/components/audit-statuses-section.tsx
|
|
1265
|
-
var STATUS_ARIA_LABELS = {
|
|
1266
|
-
pass: (count) => (0, import_i18n15.sprintf)(
|
|
1267
|
-
/* translators: %d: number of passed audits. */
|
|
1268
|
-
(0, import_i18n15.__)("%d passed audits, view all", "elementor"),
|
|
1269
|
-
count
|
|
1270
|
-
),
|
|
1271
|
-
fail: (count) => (0, import_i18n15.sprintf)(
|
|
1272
|
-
/* translators: %d: number of failed audit violations. */
|
|
1273
|
-
(0, import_i18n15.__)("%d failed audits, view all", "elementor"),
|
|
1274
|
-
count
|
|
1275
|
-
),
|
|
1276
|
-
skipped: (count) => (0, import_i18n15.sprintf)(
|
|
1277
|
-
/* translators: %d: number of skipped audits. */
|
|
1278
|
-
(0, import_i18n15.__)("%d skipped audits, view all", "elementor"),
|
|
1279
|
-
count
|
|
1280
|
-
)
|
|
1281
|
-
};
|
|
1282
|
-
var STATUS_GROUPS = ["fail", "pass", "skipped"];
|
|
1283
|
-
function AuditStatusesSection({ report, onStatusClick }) {
|
|
1284
|
-
const statusCounts = auditStatusDisplayCounts(report);
|
|
1285
|
-
return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(import_ui14.Typography, { variant: "subtitle1", fontWeight: "bold" }, (0, import_i18n15.__)("Audit statuses", "elementor")), /* @__PURE__ */ React15.createElement(import_ui14.Box, { sx: { display: "flex", justifyContent: "space-around", gap: 2 } }, STATUS_GROUPS.map((status) => /* @__PURE__ */ React15.createElement(
|
|
1286
|
-
CountSummaryCircle,
|
|
1287
|
-
{
|
|
1288
|
-
key: status,
|
|
1289
|
-
ariaLabel: STATUS_ARIA_LABELS[status](statusCounts[status]),
|
|
1290
|
-
color: auditStatusColor(status),
|
|
1291
|
-
count: statusCounts[status],
|
|
1292
|
-
label: auditStatusLabel(status),
|
|
1293
|
-
onClick: () => onStatusClick(status)
|
|
1294
|
-
}
|
|
1295
|
-
))), /* @__PURE__ */ React15.createElement(import_ui14.Divider, null));
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
|
-
// src/components/issues-category-row.tsx
|
|
1299
|
-
var React16 = __toESM(require("react"));
|
|
1300
|
-
var import_icons9 = require("@elementor/icons");
|
|
1301
|
-
var import_ui15 = require("@elementor/ui");
|
|
1302
1369
|
function IssuesCategoryRow({ category, label, counts, onClick }) {
|
|
1303
|
-
const isRtl = "rtl" === (0,
|
|
1370
|
+
const isRtl = "rtl" === (0, import_ui13.useTheme)().direction;
|
|
1304
1371
|
const Icon = CATEGORY_ICONS[category];
|
|
1305
|
-
return /* @__PURE__ */
|
|
1306
|
-
|
|
1372
|
+
return /* @__PURE__ */ React14.createElement(
|
|
1373
|
+
import_ui13.Box,
|
|
1307
1374
|
{
|
|
1308
1375
|
role: "button",
|
|
1309
1376
|
tabIndex: 0,
|
|
@@ -1324,120 +1391,29 @@ function IssuesCategoryRow({ category, label, counts, onClick }) {
|
|
|
1324
1391
|
"&:focus-visible": { outline: "2px solid", outlineColor: "primary.main" }
|
|
1325
1392
|
}
|
|
1326
1393
|
},
|
|
1327
|
-
/* @__PURE__ */
|
|
1328
|
-
/* @__PURE__ */
|
|
1329
|
-
/* @__PURE__ */
|
|
1330
|
-
/* @__PURE__ */
|
|
1394
|
+
/* @__PURE__ */ React14.createElement(Icon, { fontSize: "small", color: "action" }),
|
|
1395
|
+
/* @__PURE__ */ React14.createElement(import_ui13.Typography, { variant: "body2", fontWeight: "bold", sx: { flex: 1 } }, label),
|
|
1396
|
+
/* @__PURE__ */ React14.createElement(import_ui13.Box, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, ALL_SEVERITIES.filter((s) => counts[s] > 0).map((severity) => /* @__PURE__ */ React14.createElement(import_ui13.Box, { key: severity, sx: { display: "flex", alignItems: "center", gap: 0.25 } }, /* @__PURE__ */ React14.createElement(SeverityIcon, { severity }), /* @__PURE__ */ React14.createElement(import_ui13.Typography, { variant: "caption", color: "text.primary", fontWeight: "bold" }, counts[severity])))),
|
|
1397
|
+
/* @__PURE__ */ React14.createElement(import_ui13.Rotate, { in: isRtl }, /* @__PURE__ */ React14.createElement(import_icons11.ChevronRightIcon, { fontSize: "small", color: "action" }))
|
|
1331
1398
|
);
|
|
1332
1399
|
}
|
|
1333
1400
|
|
|
1334
|
-
// src/components/severity-filter-chips.tsx
|
|
1335
|
-
var React17 = __toESM(require("react"));
|
|
1336
|
-
var import_ui16 = require("@elementor/ui");
|
|
1337
|
-
var import_i18n16 = require("@wordpress/i18n");
|
|
1338
|
-
function SeverityFilterChips({ selected, onChange }) {
|
|
1339
|
-
return /* @__PURE__ */ React17.createElement(import_ui16.Box, { sx: { display: "flex", alignItems: "center", gap: 1 } }, /* @__PURE__ */ React17.createElement(
|
|
1340
|
-
FilterChip,
|
|
1341
|
-
{
|
|
1342
|
-
label: (0, import_i18n16.__)("All", "elementor"),
|
|
1343
|
-
isSelected: selected === "all",
|
|
1344
|
-
onClick: () => onChange("all")
|
|
1345
|
-
}
|
|
1346
|
-
), ALL_SEVERITIES.map((severity) => /* @__PURE__ */ React17.createElement(
|
|
1347
|
-
FilterChip,
|
|
1348
|
-
{
|
|
1349
|
-
key: severity,
|
|
1350
|
-
label: severityPluralLabel(severity),
|
|
1351
|
-
icon: /* @__PURE__ */ React17.createElement(SeverityIcon, { severity }),
|
|
1352
|
-
isSelected: selected === severity,
|
|
1353
|
-
onClick: () => onChange(severity)
|
|
1354
|
-
}
|
|
1355
|
-
)));
|
|
1356
|
-
}
|
|
1357
|
-
function FilterChip({ label, icon, isSelected, onClick }) {
|
|
1358
|
-
return /* @__PURE__ */ React17.createElement(
|
|
1359
|
-
import_ui16.Chip,
|
|
1360
|
-
{
|
|
1361
|
-
label,
|
|
1362
|
-
icon,
|
|
1363
|
-
size: "small",
|
|
1364
|
-
variant: "filled",
|
|
1365
|
-
color: "default",
|
|
1366
|
-
onClick,
|
|
1367
|
-
"aria-pressed": isSelected,
|
|
1368
|
-
sx: { bgcolor: isSelected ? "action.selected" : "transparent" }
|
|
1369
|
-
}
|
|
1370
|
-
);
|
|
1371
|
-
}
|
|
1372
|
-
|
|
1373
|
-
// src/components/pages/issues-page.tsx
|
|
1374
|
-
function filterCounts(counts, filter) {
|
|
1375
|
-
if (filter === "all") {
|
|
1376
|
-
return counts;
|
|
1377
|
-
}
|
|
1378
|
-
return { error: 0, warning: 0, info: 0, [filter]: counts[filter] };
|
|
1379
|
-
}
|
|
1380
|
-
function IssuesPage({ report, onCategoryClick, onAllAuditsClick, onStatusClick }) {
|
|
1381
|
-
const [filter, setFilter] = (0, import_react5.useState)("all");
|
|
1382
|
-
const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
|
|
1383
|
-
const categoryRows = populatedCategories.map((category) => ({ category, counts: filterCounts(countSeverities(report, category), filter) })).filter(({ counts }) => Object.values(counts).some((count) => count > 0));
|
|
1384
|
-
return /* @__PURE__ */ React18.createElement(import_ui17.Box, { sx: { display: "flex", flexDirection: "column", gap: 4, p: 2 } }, /* @__PURE__ */ React18.createElement(AuditStatusesSection, { report, onStatusClick }), /* @__PURE__ */ React18.createElement(
|
|
1385
|
-
import_ui17.Link,
|
|
1386
|
-
{
|
|
1387
|
-
component: "button",
|
|
1388
|
-
underline: "none",
|
|
1389
|
-
color: "inherit",
|
|
1390
|
-
onClick: onAllAuditsClick,
|
|
1391
|
-
sx: { textAlign: "start" }
|
|
1392
|
-
},
|
|
1393
|
-
/* @__PURE__ */ React18.createElement(import_ui17.Typography, { variant: "subtitle1", component: "h2" }, (0, import_i18n17.__)("All issues", "elementor"))
|
|
1394
|
-
), /* @__PURE__ */ React18.createElement(SeverityFilterChips, { selected: filter, onChange: setFilter }), /* @__PURE__ */ React18.createElement(import_ui17.Box, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, categoryRows.map(({ category, counts }) => /* @__PURE__ */ React18.createElement(
|
|
1395
|
-
IssuesCategoryRow,
|
|
1396
|
-
{
|
|
1397
|
-
key: category,
|
|
1398
|
-
category,
|
|
1399
|
-
label: CATEGORY_LABELS[category],
|
|
1400
|
-
counts,
|
|
1401
|
-
onClick: () => onCategoryClick(category)
|
|
1402
|
-
}
|
|
1403
|
-
))));
|
|
1404
|
-
}
|
|
1405
|
-
|
|
1406
|
-
// src/components/pages/overview-page.tsx
|
|
1407
|
-
var React23 = __toESM(require("react"));
|
|
1408
|
-
var import_ui22 = require("@elementor/ui");
|
|
1409
|
-
var import_i18n21 = require("@wordpress/i18n");
|
|
1410
|
-
|
|
1411
|
-
// src/utils/score-thresholds.ts
|
|
1412
|
-
var import_i18n18 = require("@wordpress/i18n");
|
|
1413
|
-
var GOOD_THRESHOLD = 90;
|
|
1414
|
-
var OK_THRESHOLD = 50;
|
|
1415
|
-
function getScoreTier(score) {
|
|
1416
|
-
if (score >= GOOD_THRESHOLD) {
|
|
1417
|
-
return { color: "success", label: (0, import_i18n18.__)("Good", "elementor") };
|
|
1418
|
-
}
|
|
1419
|
-
if (score >= OK_THRESHOLD) {
|
|
1420
|
-
return { color: "warning", label: (0, import_i18n18.__)("Needs work", "elementor") };
|
|
1421
|
-
}
|
|
1422
|
-
return { color: "error", label: (0, import_i18n18.__)("At risk", "elementor") };
|
|
1423
|
-
}
|
|
1424
|
-
|
|
1425
1401
|
// src/components/promotions.tsx
|
|
1426
|
-
var
|
|
1427
|
-
var
|
|
1428
|
-
var
|
|
1402
|
+
var React16 = __toESM(require("react"));
|
|
1403
|
+
var import_ui15 = require("@elementor/ui");
|
|
1404
|
+
var import_i18n14 = require("@wordpress/i18n");
|
|
1429
1405
|
|
|
1430
1406
|
// src/register-promotions.ts
|
|
1431
|
-
var
|
|
1432
|
-
var
|
|
1407
|
+
var import_icons12 = require("@elementor/icons");
|
|
1408
|
+
var import_i18n13 = require("@wordpress/i18n");
|
|
1433
1409
|
function firstFailExternalUrl(run) {
|
|
1434
1410
|
return run.result.status === "fail" ? run.result.violations[0]?.externalUrl : void 0;
|
|
1435
1411
|
}
|
|
1436
1412
|
var PROMOTIONS = [
|
|
1437
1413
|
{
|
|
1438
1414
|
auditId: "audits/images-alt-text",
|
|
1439
|
-
icon:
|
|
1440
|
-
ctaLabel: (0,
|
|
1415
|
+
icon: import_icons12.PhotoIcon,
|
|
1416
|
+
ctaLabel: (0, import_i18n13.__)("Fix with Ally", "elementor"),
|
|
1441
1417
|
formatSubtitle: (run) => {
|
|
1442
1418
|
if (run.result.status !== "fail") {
|
|
1443
1419
|
return null;
|
|
@@ -1446,9 +1422,9 @@ var PROMOTIONS = [
|
|
|
1446
1422
|
if (count === 0) {
|
|
1447
1423
|
return null;
|
|
1448
1424
|
}
|
|
1449
|
-
return (0,
|
|
1425
|
+
return (0, import_i18n13.sprintf)(
|
|
1450
1426
|
/* translators: %d: number of images missing alt text. */
|
|
1451
|
-
(0,
|
|
1427
|
+
(0, import_i18n13._n)("%d image", "%d images", count, "elementor"),
|
|
1452
1428
|
count
|
|
1453
1429
|
);
|
|
1454
1430
|
},
|
|
@@ -1456,22 +1432,22 @@ var PROMOTIONS = [
|
|
|
1456
1432
|
},
|
|
1457
1433
|
{
|
|
1458
1434
|
auditId: "audits/cookie-policy",
|
|
1459
|
-
icon:
|
|
1460
|
-
ctaLabel: (0,
|
|
1461
|
-
formatSubtitle: (run) => run.result.status === "fail" ? (0,
|
|
1435
|
+
icon: import_icons12.ElementorCookieIcon,
|
|
1436
|
+
ctaLabel: (0, import_i18n13.__)("Fix with Cookiez", "elementor"),
|
|
1437
|
+
formatSubtitle: (run) => run.result.status === "fail" ? (0, import_i18n13.__)("Generate cookie policy", "elementor") : null,
|
|
1462
1438
|
getCtaUrl: firstFailExternalUrl
|
|
1463
1439
|
},
|
|
1464
1440
|
{
|
|
1465
1441
|
auditId: "audits/scan-for-cookies",
|
|
1466
|
-
icon:
|
|
1467
|
-
ctaLabel: (0,
|
|
1468
|
-
formatSubtitle: (run) => run.result.status === "fail" ? (0,
|
|
1442
|
+
icon: import_icons12.ElementorCookieIcon,
|
|
1443
|
+
ctaLabel: (0, import_i18n13.__)("Scan", "elementor"),
|
|
1444
|
+
formatSubtitle: (run) => run.result.status === "fail" ? (0, import_i18n13.__)("Scan this page for cookies", "elementor") : null,
|
|
1469
1445
|
getCtaUrl: firstFailExternalUrl
|
|
1470
1446
|
},
|
|
1471
1447
|
{
|
|
1472
1448
|
auditId: "audits/images-too-large",
|
|
1473
|
-
icon:
|
|
1474
|
-
ctaLabel: (0,
|
|
1449
|
+
icon: import_icons12.ShieldHalfFilledIcon,
|
|
1450
|
+
ctaLabel: (0, import_i18n13.__)("Optimize all", "elementor"),
|
|
1475
1451
|
formatSubtitle: (run) => {
|
|
1476
1452
|
if (run.result.status !== "fail") {
|
|
1477
1453
|
return null;
|
|
@@ -1480,9 +1456,9 @@ var PROMOTIONS = [
|
|
|
1480
1456
|
if (count === 0) {
|
|
1481
1457
|
return null;
|
|
1482
1458
|
}
|
|
1483
|
-
return (0,
|
|
1459
|
+
return (0, import_i18n13.sprintf)(
|
|
1484
1460
|
/* translators: %d: number of oversized images. */
|
|
1485
|
-
(0,
|
|
1461
|
+
(0, import_i18n13._n)("%d image", "%d images", count, "elementor"),
|
|
1486
1462
|
count
|
|
1487
1463
|
);
|
|
1488
1464
|
},
|
|
@@ -1496,11 +1472,11 @@ function findAuditRun(report, auditId) {
|
|
|
1496
1472
|
}
|
|
1497
1473
|
|
|
1498
1474
|
// src/components/promotion-card.tsx
|
|
1499
|
-
var
|
|
1500
|
-
var
|
|
1475
|
+
var React15 = __toESM(require("react"));
|
|
1476
|
+
var import_ui14 = require("@elementor/ui");
|
|
1501
1477
|
function PromotionCard({ ctaDisabled, ctaLabel, icon: Icon, onCtaClick, subtitle, title }) {
|
|
1502
|
-
return /* @__PURE__ */
|
|
1503
|
-
|
|
1478
|
+
return /* @__PURE__ */ React15.createElement(
|
|
1479
|
+
import_ui14.Box,
|
|
1504
1480
|
{
|
|
1505
1481
|
sx: {
|
|
1506
1482
|
alignItems: "center",
|
|
@@ -1513,9 +1489,9 @@ function PromotionCard({ ctaDisabled, ctaLabel, icon: Icon, onCtaClick, subtitle
|
|
|
1513
1489
|
py: 1.5
|
|
1514
1490
|
}
|
|
1515
1491
|
},
|
|
1516
|
-
/* @__PURE__ */
|
|
1517
|
-
/* @__PURE__ */
|
|
1518
|
-
/* @__PURE__ */
|
|
1492
|
+
/* @__PURE__ */ React15.createElement(Icon, { fontSize: "small", color: "action" }),
|
|
1493
|
+
/* @__PURE__ */ React15.createElement(import_ui14.Box, { sx: { display: "flex", flex: 1, flexDirection: "column", gap: 0.25, minWidth: 0 } }, /* @__PURE__ */ React15.createElement(import_ui14.Typography, { variant: "body2", fontWeight: "bold" }, title), /* @__PURE__ */ React15.createElement(import_ui14.Typography, { variant: "caption", color: "text.secondary" }, subtitle)),
|
|
1494
|
+
/* @__PURE__ */ React15.createElement(import_ui14.Button, { variant: "outlined", color: "secondary", size: "small", disabled: ctaDisabled, onClick: onCtaClick }, ctaLabel)
|
|
1519
1495
|
);
|
|
1520
1496
|
}
|
|
1521
1497
|
|
|
@@ -1544,7 +1520,7 @@ function Promotions({ report }) {
|
|
|
1544
1520
|
if (cards.length === 0) {
|
|
1545
1521
|
return null;
|
|
1546
1522
|
}
|
|
1547
|
-
return /* @__PURE__ */
|
|
1523
|
+
return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(import_ui15.Divider, null), /* @__PURE__ */ React16.createElement(import_ui15.Typography, { variant: "subtitle1", fontWeight: "bold" }, (0, import_i18n14.__)("Quick actions", "elementor")), /* @__PURE__ */ React16.createElement(import_ui15.Box, { sx: { display: "flex", flexDirection: "column", gap: 1 } }, cards.map(({ config, ctaUrl, key, run, subtitle }) => /* @__PURE__ */ React16.createElement(
|
|
1548
1524
|
PromotionCard,
|
|
1549
1525
|
{
|
|
1550
1526
|
key,
|
|
@@ -1562,246 +1538,123 @@ function Promotions({ report }) {
|
|
|
1562
1538
|
))));
|
|
1563
1539
|
}
|
|
1564
1540
|
|
|
1565
|
-
// src/components/
|
|
1566
|
-
var
|
|
1567
|
-
var
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
return /* @__PURE__ */ React21.createElement(
|
|
1572
|
-
import_ui20.Box,
|
|
1573
|
-
{
|
|
1574
|
-
role: onClick ? "button" : void 0,
|
|
1575
|
-
tabIndex: onClick ? 0 : void 0,
|
|
1576
|
-
onClick,
|
|
1577
|
-
onKeyDown: onClick ? onKeyboardClick(onClick) : void 0,
|
|
1578
|
-
sx: {
|
|
1579
|
-
display: "flex",
|
|
1580
|
-
alignItems: "center",
|
|
1581
|
-
gap: 1,
|
|
1582
|
-
cursor: onClick ? "pointer" : "default",
|
|
1583
|
-
outline: "none",
|
|
1584
|
-
"&:focus-visible": { outline: "2px solid", outlineColor: "primary.main", borderRadius: 1 },
|
|
1585
|
-
py: 0.5
|
|
1586
|
-
}
|
|
1587
|
-
},
|
|
1588
|
-
/* @__PURE__ */ React21.createElement(import_ui20.Typography, { variant: "body2", sx: { minWidth: 96 } }, label),
|
|
1589
|
-
/* @__PURE__ */ React21.createElement(
|
|
1590
|
-
import_ui20.LinearProgress,
|
|
1591
|
-
{
|
|
1592
|
-
variant: "determinate",
|
|
1593
|
-
value: score,
|
|
1594
|
-
color: getScoreTier(score).color,
|
|
1595
|
-
sx: { flex: 1, height: 6, borderRadius: 4, bgcolor: "action.disabledBackground" }
|
|
1596
|
-
}
|
|
1597
|
-
),
|
|
1598
|
-
/* @__PURE__ */ React21.createElement(
|
|
1599
|
-
import_ui20.Typography,
|
|
1600
|
-
{
|
|
1601
|
-
variant: "body2",
|
|
1602
|
-
color: "text.primary",
|
|
1603
|
-
sx: { minWidth: 24, textAlign: "right", fontWeight: 900 }
|
|
1604
|
-
},
|
|
1605
|
-
score
|
|
1606
|
-
),
|
|
1607
|
-
onClick && /* @__PURE__ */ React21.createElement(import_ui20.Rotate, { in: isRtl }, /* @__PURE__ */ React21.createElement(import_icons11.ChevronRightIcon, { fontSize: "small", color: "action" }))
|
|
1608
|
-
);
|
|
1541
|
+
// src/components/severity-summary-cards.tsx
|
|
1542
|
+
var React17 = __toESM(require("react"));
|
|
1543
|
+
var import_ui16 = require("@elementor/ui");
|
|
1544
|
+
function SeveritySummaryCards({ report }) {
|
|
1545
|
+
const counts = countSeverities(report);
|
|
1546
|
+
return /* @__PURE__ */ React17.createElement(import_ui16.Box, { display: "flex", gap: 1.5 }, ALL_SEVERITIES.map((severity) => /* @__PURE__ */ React17.createElement(SeverityCard, { key: severity, severity, count: counts[severity] })));
|
|
1609
1547
|
}
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
var import_ui21 = require("@elementor/ui");
|
|
1614
|
-
var SCORE_CIRCLE_SIZE = 88;
|
|
1615
|
-
var SCORE_CIRCLE_THICKNESS = 3;
|
|
1616
|
-
function ScoreCircle({ color, score }) {
|
|
1617
|
-
const progressColor = color ?? getScoreTier(score).color;
|
|
1618
|
-
return /* @__PURE__ */ React22.createElement(
|
|
1619
|
-
import_ui21.Box,
|
|
1548
|
+
function SeverityCard({ severity, count }) {
|
|
1549
|
+
return /* @__PURE__ */ React17.createElement(
|
|
1550
|
+
import_ui16.Box,
|
|
1620
1551
|
{
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
"
|
|
1624
|
-
|
|
1625
|
-
|
|
1552
|
+
display: "flex",
|
|
1553
|
+
flex: 1,
|
|
1554
|
+
flexDirection: "column",
|
|
1555
|
+
gap: 1,
|
|
1556
|
+
bgcolor: "action.hover",
|
|
1557
|
+
borderRadius: 1.5,
|
|
1558
|
+
px: 1.5,
|
|
1559
|
+
py: 1
|
|
1626
1560
|
},
|
|
1627
|
-
/* @__PURE__ */
|
|
1628
|
-
|
|
1629
|
-
{
|
|
1630
|
-
variant: "determinate",
|
|
1631
|
-
value: 100,
|
|
1632
|
-
size: SCORE_CIRCLE_SIZE,
|
|
1633
|
-
thickness: SCORE_CIRCLE_THICKNESS,
|
|
1634
|
-
sx: { color: "action.disabledBackground" }
|
|
1635
|
-
}
|
|
1636
|
-
),
|
|
1637
|
-
/* @__PURE__ */ React22.createElement(
|
|
1638
|
-
import_ui21.CircularProgress,
|
|
1639
|
-
{
|
|
1640
|
-
variant: "determinate",
|
|
1641
|
-
value: score,
|
|
1642
|
-
size: SCORE_CIRCLE_SIZE,
|
|
1643
|
-
thickness: SCORE_CIRCLE_THICKNESS,
|
|
1644
|
-
color: progressColor,
|
|
1645
|
-
sx: { position: "absolute", left: 0 }
|
|
1646
|
-
}
|
|
1647
|
-
),
|
|
1648
|
-
/* @__PURE__ */ React22.createElement(
|
|
1649
|
-
import_ui21.Box,
|
|
1650
|
-
{
|
|
1651
|
-
sx: {
|
|
1652
|
-
position: "absolute",
|
|
1653
|
-
inset: 0,
|
|
1654
|
-
display: "flex",
|
|
1655
|
-
alignItems: "center",
|
|
1656
|
-
justifyContent: "center"
|
|
1657
|
-
}
|
|
1658
|
-
},
|
|
1659
|
-
/* @__PURE__ */ React22.createElement(
|
|
1660
|
-
import_ui21.Typography,
|
|
1661
|
-
{
|
|
1662
|
-
variant: "h4",
|
|
1663
|
-
component: "span",
|
|
1664
|
-
color: "text.primary",
|
|
1665
|
-
sx: { fontWeight: 700, lineHeight: 1 }
|
|
1666
|
-
},
|
|
1667
|
-
score
|
|
1668
|
-
)
|
|
1669
|
-
)
|
|
1561
|
+
/* @__PURE__ */ React17.createElement(SeverityIcon, { severity }),
|
|
1562
|
+
/* @__PURE__ */ React17.createElement(import_ui16.Box, { display: "flex", flexDirection: "column" }, /* @__PURE__ */ React17.createElement(import_ui16.Typography, { variant: "h5", fontWeight: 700, component: "span" }, count), /* @__PURE__ */ React17.createElement(import_ui16.Typography, { variant: "caption", color: "text.secondary" }, severityPluralLabel(severity)))
|
|
1670
1563
|
);
|
|
1671
1564
|
}
|
|
1672
1565
|
|
|
1673
1566
|
// src/components/pages/overview-page.tsx
|
|
1674
1567
|
function OverviewPage({ onCategoryClick, report }) {
|
|
1675
1568
|
const populatedCategories = getPopulatedCategories(report.categories, ALL_CATEGORIES);
|
|
1676
|
-
const
|
|
1677
|
-
return /* @__PURE__ */
|
|
1678
|
-
|
|
1679
|
-
{
|
|
1680
|
-
label: overallScore.label,
|
|
1681
|
-
color: overallScore.color,
|
|
1682
|
-
variant: "standard",
|
|
1683
|
-
size: "small",
|
|
1684
|
-
sx: { fontWeight: 600, alignSelf: "flex-start" }
|
|
1685
|
-
}
|
|
1686
|
-
), /* @__PURE__ */ React23.createElement(import_ui22.Typography, { variant: "body2", color: "text.secondary" }, (0, import_i18n21.__)("Overall score", "elementor")))), /* @__PURE__ */ React23.createElement(import_ui22.Box, { sx: { display: "flex", flexDirection: "column", gap: 2 } }, populatedCategories.map((category) => /* @__PURE__ */ React23.createElement(
|
|
1687
|
-
ScoreBar,
|
|
1569
|
+
const categoryRows = populatedCategories.map((category) => ({ category, counts: countSeverities(report, category) })).filter(({ counts }) => Object.values(counts).some((count) => count > 0));
|
|
1570
|
+
return /* @__PURE__ */ React18.createElement(import_ui17.Box, { display: "flex", flexDirection: "column", gap: 3, p: 2 }, /* @__PURE__ */ React18.createElement(SeveritySummaryCards, { report }), /* @__PURE__ */ React18.createElement(import_ui17.Box, { display: "flex", flexDirection: "column", gap: 1 }, /* @__PURE__ */ React18.createElement(import_ui17.Typography, { variant: "subtitle1", component: "h2" }, (0, import_i18n15.__)("All issues", "elementor")), /* @__PURE__ */ React18.createElement(import_ui17.Box, { display: "flex", flexDirection: "column", gap: 1 }, categoryRows.map(({ category, counts }) => /* @__PURE__ */ React18.createElement(
|
|
1571
|
+
IssuesCategoryRow,
|
|
1688
1572
|
{
|
|
1689
1573
|
key: category,
|
|
1574
|
+
category,
|
|
1690
1575
|
label: CATEGORY_LABELS[category],
|
|
1691
|
-
|
|
1576
|
+
counts,
|
|
1692
1577
|
onClick: () => onCategoryClick(category)
|
|
1693
1578
|
}
|
|
1694
|
-
))), /* @__PURE__ */
|
|
1579
|
+
)))), /* @__PURE__ */ React18.createElement(Promotions, { report }));
|
|
1695
1580
|
}
|
|
1696
1581
|
|
|
1697
1582
|
// src/components/report-shell.tsx
|
|
1698
|
-
function activeTab(page) {
|
|
1699
|
-
if (page === "overview") {
|
|
1700
|
-
return "overview";
|
|
1701
|
-
}
|
|
1702
|
-
if (page === "issues") {
|
|
1703
|
-
return "issues";
|
|
1704
|
-
}
|
|
1705
|
-
return page.backTo;
|
|
1706
|
-
}
|
|
1707
|
-
function isAllAuditsPage(page) {
|
|
1708
|
-
return typeof page === "object" && "page" in page && page.page === "all-audits";
|
|
1709
|
-
}
|
|
1710
1583
|
function isCategoryPage(page) {
|
|
1711
1584
|
return typeof page === "object" && "category" in page;
|
|
1712
1585
|
}
|
|
1713
1586
|
function ReportShell({ report }) {
|
|
1714
|
-
const [activePage, setActivePage] = (0,
|
|
1715
|
-
const
|
|
1716
|
-
const
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
return /* @__PURE__ */ React24.createElement(import_ui23.Box, { sx: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0 } }, /* @__PURE__ */ React24.createElement(import_ui23.Box, { sx: { flexShrink: 0 } }, /* @__PURE__ */ React24.createElement(
|
|
1731
|
-
import_ui23.Tabs,
|
|
1587
|
+
const [activePage, setActivePage] = (0, import_react5.useState)("overview");
|
|
1588
|
+
const openCategory = (category) => setActivePage({ category });
|
|
1589
|
+
const backToOverview = () => setActivePage("overview");
|
|
1590
|
+
return /* @__PURE__ */ React19.createElement(import_ui18.Box, { sx: { flex: 1, minHeight: 0, overflowY: "auto" } }, activePage === "overview" && /* @__PURE__ */ React19.createElement(OverviewPage, { report, onCategoryClick: openCategory }), isCategoryPage(activePage) && /* @__PURE__ */ React19.createElement(CategoryPage, { category: activePage.category, report, onBack: backToOverview }));
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
// src/components/rescan-button.tsx
|
|
1594
|
+
var React20 = __toESM(require("react"));
|
|
1595
|
+
var import_editor_floating_panels3 = require("@elementor/editor-floating-panels");
|
|
1596
|
+
var import_icons13 = require("@elementor/icons");
|
|
1597
|
+
var import_ui19 = require("@elementor/ui");
|
|
1598
|
+
var import_i18n16 = require("@wordpress/i18n");
|
|
1599
|
+
function RescanButton({ hasScanned, isStale, disabled, onClick }) {
|
|
1600
|
+
const panelZIndex = (0, import_editor_floating_panels3.useFloatingPanelZIndex)(AUDIT_PANEL_ID);
|
|
1601
|
+
return /* @__PURE__ */ React20.createElement(
|
|
1602
|
+
import_ui19.Tooltip,
|
|
1732
1603
|
{
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
textColor: "secondary",
|
|
1737
|
-
indicatorColor: "secondary",
|
|
1738
|
-
size: "small",
|
|
1739
|
-
centered: true,
|
|
1740
|
-
variant: "fullWidth"
|
|
1604
|
+
title: (0, import_i18n16.__)("Page content changed - rescan advised", "elementor"),
|
|
1605
|
+
disableHoverListener: !isStale,
|
|
1606
|
+
PopperProps: { sx: { zIndex: panelZIndex } }
|
|
1741
1607
|
},
|
|
1742
|
-
/* @__PURE__ */
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
onCategoryClick: (category) => openCategory(category, "issues"),
|
|
1755
|
-
onAllAuditsClick: () => openAllAudits(),
|
|
1756
|
-
onStatusClick: (status) => openAllAudits(status)
|
|
1757
|
-
}
|
|
1758
|
-
), isAllAuditsPage(activePage) && /* @__PURE__ */ React24.createElement(
|
|
1759
|
-
AllAuditsPage,
|
|
1760
|
-
{
|
|
1761
|
-
report,
|
|
1762
|
-
initialExpandedStatus: activePage.expand,
|
|
1763
|
-
onBack: backFromSubPage
|
|
1764
|
-
}
|
|
1765
|
-
), isCategoryPage(activePage) && /* @__PURE__ */ React24.createElement(CategoryPage, { category: activePage.category, report, onBack: backFromSubPage })));
|
|
1608
|
+
/* @__PURE__ */ React20.createElement(import_ui19.Badge, { variant: "dot", color: "warning", invisible: !isStale, overlap: "rectangular" }, /* @__PURE__ */ React20.createElement(
|
|
1609
|
+
import_ui19.Button,
|
|
1610
|
+
{
|
|
1611
|
+
variant: "contained",
|
|
1612
|
+
size: "small",
|
|
1613
|
+
startIcon: hasScanned ? /* @__PURE__ */ React20.createElement(import_icons13.ReloadIcon, { fontSize: "small" }) : void 0,
|
|
1614
|
+
onClick,
|
|
1615
|
+
disabled
|
|
1616
|
+
},
|
|
1617
|
+
hasScanned ? (0, import_i18n16.__)("Rescan", "elementor") : (0, import_i18n16.__)("Run page audit", "elementor")
|
|
1618
|
+
))
|
|
1619
|
+
);
|
|
1766
1620
|
}
|
|
1767
1621
|
|
|
1768
1622
|
// src/components/audit-panel.tsx
|
|
1769
1623
|
function AuditPanel() {
|
|
1770
|
-
const { status, report, error, run } = useAuditReport();
|
|
1771
|
-
const
|
|
1772
|
-
const onRun = () => run(
|
|
1624
|
+
const { status, report, error, isStale, run } = useAuditReport();
|
|
1625
|
+
const hostDocumentId = (0, import_editor_elements6.getHostDocumentId)() ?? 0;
|
|
1626
|
+
const onRun = () => run(hostDocumentId);
|
|
1773
1627
|
const lastScanLabel = report ? new Date(report.runAt).toLocaleTimeString() : null;
|
|
1774
|
-
return /* @__PURE__ */
|
|
1775
|
-
|
|
1628
|
+
return /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(
|
|
1629
|
+
import_editor_floating_panels4.FloatingPanelHeader,
|
|
1776
1630
|
{
|
|
1777
|
-
panelId:
|
|
1778
|
-
title: (0,
|
|
1779
|
-
badge: (0,
|
|
1631
|
+
panelId: AUDIT_PANEL_ID,
|
|
1632
|
+
title: (0, import_i18n17.__)("Page Audit", "elementor"),
|
|
1633
|
+
badge: (0, import_i18n17.__)("Beta", "elementor"),
|
|
1780
1634
|
titleVariant: "subtitle2"
|
|
1781
1635
|
}
|
|
1782
|
-
), /* @__PURE__ */
|
|
1783
|
-
|
|
1636
|
+
), /* @__PURE__ */ React21.createElement(
|
|
1637
|
+
import_editor_floating_panels4.FloatingPanelBody,
|
|
1784
1638
|
{
|
|
1785
1639
|
sx: status === "ready" ? { display: "flex", flexDirection: "column", overflow: "hidden", minHeight: 0 } : void 0
|
|
1786
1640
|
},
|
|
1787
|
-
status === "idle" && /* @__PURE__ */
|
|
1788
|
-
status === "loading" && /* @__PURE__ */
|
|
1789
|
-
status === "error" && /* @__PURE__ */
|
|
1790
|
-
status === "ready" && report && /* @__PURE__ */
|
|
1791
|
-
), /* @__PURE__ */
|
|
1792
|
-
|
|
1641
|
+
status === "idle" && /* @__PURE__ */ React21.createElement(WelcomePage, null),
|
|
1642
|
+
status === "loading" && /* @__PURE__ */ React21.createElement(LoadingPage, null),
|
|
1643
|
+
status === "error" && /* @__PURE__ */ React21.createElement(ErrorPage, { message: error ?? "", onRetry: onRun }),
|
|
1644
|
+
status === "ready" && report && /* @__PURE__ */ React21.createElement(ReportShell, { report })
|
|
1645
|
+
), /* @__PURE__ */ React21.createElement(import_editor_floating_panels4.FloatingPanelFooter, null, lastScanLabel ? /* @__PURE__ */ React21.createElement(import_ui20.Typography, { variant: "caption", sx: { flex: 1 } }, (0, import_i18n17.__)("Last scan:", "elementor"), " ", lastScanLabel) : /* @__PURE__ */ React21.createElement(import_ui20.Box, { sx: { flex: 1 } }), lastScanLabel && /* @__PURE__ */ React21.createElement(AuditFeedback, null), /* @__PURE__ */ React21.createElement(
|
|
1646
|
+
RescanButton,
|
|
1793
1647
|
{
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
}
|
|
1799
|
-
lastScanLabel ? (0, import_i18n23.__)("Re-scan", "elementor") : (0, import_i18n23.__)("Run page audit", "elementor")
|
|
1648
|
+
hasScanned: Boolean(lastScanLabel),
|
|
1649
|
+
isStale,
|
|
1650
|
+
disabled: status === "loading" || hostDocumentId === 0,
|
|
1651
|
+
onClick: onRun
|
|
1652
|
+
}
|
|
1800
1653
|
)));
|
|
1801
1654
|
}
|
|
1802
1655
|
|
|
1803
1656
|
// src/editor-panel.tsx
|
|
1804
|
-
var auditPanel = (0,
|
|
1657
|
+
var auditPanel = (0, import_editor_floating_panels5.createFloatingPanel)({
|
|
1805
1658
|
id: AUDIT_PANEL_ID,
|
|
1806
1659
|
title: "Audit",
|
|
1807
1660
|
icon: () => null,
|
|
@@ -1821,8 +1674,8 @@ function useAuditToggleProps() {
|
|
|
1821
1674
|
const { isOpen } = auditPanel.useFloatingPanelStatus();
|
|
1822
1675
|
const { toggle } = auditPanel.useFloatingPanelActions();
|
|
1823
1676
|
return {
|
|
1824
|
-
title: (0,
|
|
1825
|
-
icon:
|
|
1677
|
+
title: (0, import_i18n18.__)("Audit Page", "elementor"),
|
|
1678
|
+
icon: AuditToggleIcon,
|
|
1826
1679
|
selected: isOpen,
|
|
1827
1680
|
onClick: () => toggle()
|
|
1828
1681
|
};
|
|
@@ -1838,30 +1691,107 @@ function registerAppBarAuditsToggle() {
|
|
|
1838
1691
|
});
|
|
1839
1692
|
}
|
|
1840
1693
|
|
|
1841
|
-
// src/audits/accessibility-policy.ts
|
|
1842
|
-
var
|
|
1843
|
-
var audit = {
|
|
1844
|
-
id: "audits/accessibility-policy",
|
|
1845
|
-
title: (0,
|
|
1846
|
-
description: (0,
|
|
1847
|
-
"An accessibility policy demonstrates your commitment to digital inclusion and may be legally required in some regions.",
|
|
1848
|
-
"elementor"
|
|
1849
|
-
),
|
|
1850
|
-
fixHint: (0,
|
|
1851
|
-
categories: ["compliance"],
|
|
1694
|
+
// src/audits/accessibility-policy.ts
|
|
1695
|
+
var import_i18n19 = require("@wordpress/i18n");
|
|
1696
|
+
var audit = {
|
|
1697
|
+
id: "audits/accessibility-policy",
|
|
1698
|
+
title: (0, import_i18n19.__)("Accessibility policy", "elementor"),
|
|
1699
|
+
description: (0, import_i18n19.__)(
|
|
1700
|
+
"An accessibility policy demonstrates your commitment to digital inclusion and may be legally required in some regions.",
|
|
1701
|
+
"elementor"
|
|
1702
|
+
),
|
|
1703
|
+
fixHint: (0, import_i18n19.__)("Install the Ally plugin to add an accessibility policy to your website.", "elementor"),
|
|
1704
|
+
categories: ["compliance"],
|
|
1705
|
+
severity: "info",
|
|
1706
|
+
weight: 1,
|
|
1707
|
+
evaluate: (ctx) => {
|
|
1708
|
+
if (ctx.pageContext.ally_plugin_active) {
|
|
1709
|
+
return { status: "pass" };
|
|
1710
|
+
}
|
|
1711
|
+
return {
|
|
1712
|
+
status: "fail",
|
|
1713
|
+
violations: [
|
|
1714
|
+
{
|
|
1715
|
+
auditId: audit.id,
|
|
1716
|
+
label: (0, import_i18n19.__)("Ally plugin is not installed or active.", "elementor"),
|
|
1717
|
+
externalUrl: ctx.pageContext.ally_plugin_url
|
|
1718
|
+
}
|
|
1719
|
+
]
|
|
1720
|
+
};
|
|
1721
|
+
}
|
|
1722
|
+
};
|
|
1723
|
+
|
|
1724
|
+
// src/audits/accessibility-statement.ts
|
|
1725
|
+
var import_i18n20 = require("@wordpress/i18n");
|
|
1726
|
+
var audit2 = {
|
|
1727
|
+
id: "audits/accessibility-statement",
|
|
1728
|
+
title: (0, import_i18n20.__)("Create an accessibility statement", "elementor"),
|
|
1729
|
+
description: (0, import_i18n20.__)(
|
|
1730
|
+
"An accessibility statement showcases your efforts to create an inclusive online space, highlighting helpful features and a commitment to accessibility.",
|
|
1731
|
+
"elementor"
|
|
1732
|
+
),
|
|
1733
|
+
fixHint: (0, import_i18n20.__)("Use Ally to create and publish an accessibility statement for your site.", "elementor"),
|
|
1734
|
+
categories: ["accessibility"],
|
|
1735
|
+
severity: "info",
|
|
1736
|
+
weight: 1,
|
|
1737
|
+
evaluate: (ctx) => {
|
|
1738
|
+
const isReady = ctx.pageContext.ally_plugin_active;
|
|
1739
|
+
if (isReady && ctx.pageContext.ally_accessibility_statement_created) {
|
|
1740
|
+
return { status: "pass" };
|
|
1741
|
+
}
|
|
1742
|
+
return {
|
|
1743
|
+
status: "fail",
|
|
1744
|
+
violations: [
|
|
1745
|
+
{
|
|
1746
|
+
auditId: audit2.id,
|
|
1747
|
+
label: (0, import_i18n20.__)("No accessibility statement has been created for this site.", "elementor"),
|
|
1748
|
+
externalUrl: isReady ? ctx.pageContext.ally_accessibility_statement_url : ctx.pageContext.ally_plugin_url,
|
|
1749
|
+
ctaLabel: (0, import_i18n20.__)("Create", "elementor"),
|
|
1750
|
+
secondaryCtaLabel: (0, import_i18n20.__)("Learn more", "elementor"),
|
|
1751
|
+
secondaryCtaUrl: "https://elementor.com/help/start-using-ally/#statement"
|
|
1752
|
+
}
|
|
1753
|
+
]
|
|
1754
|
+
};
|
|
1755
|
+
}
|
|
1756
|
+
};
|
|
1757
|
+
|
|
1758
|
+
// src/audits/accessibility-widget.ts
|
|
1759
|
+
var import_i18n21 = require("@wordpress/i18n");
|
|
1760
|
+
|
|
1761
|
+
// src/utils/scan-accessibility-widgets.ts
|
|
1762
|
+
var ACCESSIBILITY_WIDGET_SCRIPT_SOURCES = ["cdn.elementor.com/a11y/widget.js"];
|
|
1763
|
+
function hasAccessibilityWidgetScript(html) {
|
|
1764
|
+
return ACCESSIBILITY_WIDGET_SCRIPT_SOURCES.some((src) => html.includes(src));
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
// src/audits/accessibility-widget.ts
|
|
1768
|
+
var audit3 = {
|
|
1769
|
+
id: "audits/accessibility-widget",
|
|
1770
|
+
title: (0, import_i18n21.__)("Add an accessibility widget", "elementor"),
|
|
1771
|
+
description: (0, import_i18n21.__)("Make your site more inclusive by adding an accessibility widget.", "elementor"),
|
|
1772
|
+
fixHint: (0, import_i18n21.__)("Activate Ally\u2019s accessibility widget to give visitors on-page accessibility tools.", "elementor"),
|
|
1773
|
+
categories: ["accessibility"],
|
|
1852
1774
|
severity: "info",
|
|
1853
1775
|
weight: 1,
|
|
1854
1776
|
evaluate: (ctx) => {
|
|
1855
|
-
if (ctx.pageContext.
|
|
1777
|
+
if (!ctx.pageContext.frontend_url) {
|
|
1778
|
+
return { status: "skipped", reason: (0, import_i18n21.__)("Page is not published.", "elementor") };
|
|
1779
|
+
}
|
|
1780
|
+
if (!ctx.renderedHtml) {
|
|
1781
|
+
return { status: "skipped", reason: (0, import_i18n21.__)("Could not fetch the published page.", "elementor") };
|
|
1782
|
+
}
|
|
1783
|
+
if (hasAccessibilityWidgetScript(ctx.renderedHtml)) {
|
|
1856
1784
|
return { status: "pass" };
|
|
1857
1785
|
}
|
|
1786
|
+
const isReady = ctx.pageContext.ally_plugin_active;
|
|
1858
1787
|
return {
|
|
1859
1788
|
status: "fail",
|
|
1860
1789
|
violations: [
|
|
1861
1790
|
{
|
|
1862
|
-
auditId:
|
|
1863
|
-
label: (0,
|
|
1864
|
-
externalUrl: ctx.pageContext.ally_plugin_url
|
|
1791
|
+
auditId: audit3.id,
|
|
1792
|
+
label: (0, import_i18n21.__)("No accessibility widget is active on this site.", "elementor"),
|
|
1793
|
+
externalUrl: isReady ? ctx.pageContext.ally_widget_settings_url : ctx.pageContext.ally_plugin_url,
|
|
1794
|
+
ctaLabel: (0, import_i18n21.__)("Activate", "elementor")
|
|
1865
1795
|
}
|
|
1866
1796
|
]
|
|
1867
1797
|
};
|
|
@@ -1869,15 +1799,15 @@ var audit = {
|
|
|
1869
1799
|
};
|
|
1870
1800
|
|
|
1871
1801
|
// src/audits/cookie-policy.ts
|
|
1872
|
-
var
|
|
1873
|
-
var
|
|
1802
|
+
var import_i18n22 = require("@wordpress/i18n");
|
|
1803
|
+
var audit4 = {
|
|
1874
1804
|
id: "audits/cookie-policy",
|
|
1875
|
-
title: (0,
|
|
1876
|
-
description: (0,
|
|
1805
|
+
title: (0, import_i18n22.__)("Cookie policy", "elementor"),
|
|
1806
|
+
description: (0, import_i18n22.__)(
|
|
1877
1807
|
"A cookie policy is required by privacy regulations such as GDPR (EU) or CCPA (US) to inform visitors about tracking and data collection.",
|
|
1878
1808
|
"elementor"
|
|
1879
1809
|
),
|
|
1880
|
-
fixHint: (0,
|
|
1810
|
+
fixHint: (0, import_i18n22.__)("Install the Cookiez plugin to add a cookie policy to your website.", "elementor"),
|
|
1881
1811
|
categories: ["compliance"],
|
|
1882
1812
|
severity: "info",
|
|
1883
1813
|
weight: 1,
|
|
@@ -1889,9 +1819,10 @@ var audit2 = {
|
|
|
1889
1819
|
status: "fail",
|
|
1890
1820
|
violations: [
|
|
1891
1821
|
{
|
|
1892
|
-
auditId:
|
|
1893
|
-
label: (0,
|
|
1894
|
-
externalUrl: ctx.pageContext.cookiez_plugin_url
|
|
1822
|
+
auditId: audit4.id,
|
|
1823
|
+
label: (0, import_i18n22.__)("Cookiez plugin is not installed or active.", "elementor"),
|
|
1824
|
+
externalUrl: ctx.pageContext.cookiez_plugin_url,
|
|
1825
|
+
ctaLabel: (0, import_i18n22.__)("Set up cookie consent", "elementor")
|
|
1895
1826
|
}
|
|
1896
1827
|
]
|
|
1897
1828
|
};
|
|
@@ -1899,8 +1830,8 @@ var audit2 = {
|
|
|
1899
1830
|
};
|
|
1900
1831
|
|
|
1901
1832
|
// src/audits/deep-nesting.ts
|
|
1902
|
-
var
|
|
1903
|
-
var
|
|
1833
|
+
var import_editor_elements7 = require("@elementor/editor-elements");
|
|
1834
|
+
var import_i18n23 = require("@wordpress/i18n");
|
|
1904
1835
|
var MAX_NESTING_DEPTH = 6;
|
|
1905
1836
|
function isNestingElement(node, widgetsCache) {
|
|
1906
1837
|
if (node.elType === "container") {
|
|
@@ -1908,22 +1839,22 @@ function isNestingElement(node, widgetsCache) {
|
|
|
1908
1839
|
}
|
|
1909
1840
|
return !!widgetsCache?.[node.elType]?.meta?.is_container;
|
|
1910
1841
|
}
|
|
1911
|
-
var
|
|
1842
|
+
var audit5 = {
|
|
1912
1843
|
id: "audits/deep-nesting",
|
|
1913
|
-
title: (0,
|
|
1914
|
-
description: (0,
|
|
1844
|
+
title: (0, import_i18n23.__)("Deep container nesting", "elementor"),
|
|
1845
|
+
description: (0, import_i18n23.__)(
|
|
1915
1846
|
"Container nesting exceeds the recommended depth. Deep DOM trees hurt rendering performance and readability.",
|
|
1916
1847
|
"elementor"
|
|
1917
1848
|
),
|
|
1918
|
-
fixHint: (0,
|
|
1849
|
+
fixHint: (0, import_i18n23.__)("Flatten the layout by removing unnecessary wrapper containers.", "elementor"),
|
|
1919
1850
|
categories: ["performance", "best-practices"],
|
|
1920
1851
|
severity: "warning",
|
|
1921
1852
|
weight: 5,
|
|
1922
1853
|
evaluate: (ctx) => {
|
|
1923
1854
|
if (ctx.elements.tree.length === 0) {
|
|
1924
|
-
return { status: "skipped", reason: (0,
|
|
1855
|
+
return { status: "skipped", reason: (0, import_i18n23.__)("No elements", "elementor") };
|
|
1925
1856
|
}
|
|
1926
|
-
const widgetsCache = (0,
|
|
1857
|
+
const widgetsCache = (0, import_editor_elements7.getWidgetsCache)();
|
|
1927
1858
|
const violations = [];
|
|
1928
1859
|
walkElements(ctx.elements.tree, (node, parents) => {
|
|
1929
1860
|
if (!isNestingElement(node, widgetsCache)) {
|
|
@@ -1932,10 +1863,10 @@ var audit3 = {
|
|
|
1932
1863
|
const depth = parents.filter((parent) => isNestingElement(parent, widgetsCache)).length + 1;
|
|
1933
1864
|
if (depth > MAX_NESTING_DEPTH) {
|
|
1934
1865
|
violations.push({
|
|
1935
|
-
auditId:
|
|
1866
|
+
auditId: audit5.id,
|
|
1936
1867
|
elementId: node.id,
|
|
1937
1868
|
targetHint: "element-settings",
|
|
1938
|
-
label: (0,
|
|
1869
|
+
label: (0, import_i18n23.__)("Container nesting is too deep.", "elementor")
|
|
1939
1870
|
});
|
|
1940
1871
|
}
|
|
1941
1872
|
});
|
|
@@ -1944,15 +1875,15 @@ var audit3 = {
|
|
|
1944
1875
|
};
|
|
1945
1876
|
|
|
1946
1877
|
// src/audits/default-design-system.ts
|
|
1947
|
-
var
|
|
1948
|
-
var
|
|
1878
|
+
var import_i18n24 = require("@wordpress/i18n");
|
|
1879
|
+
var audit6 = {
|
|
1949
1880
|
id: "audits/default-design-system",
|
|
1950
|
-
title: (0,
|
|
1951
|
-
description: (0,
|
|
1881
|
+
title: (0, import_i18n24.__)("Default website kit", "elementor"),
|
|
1882
|
+
description: (0, import_i18n24.__)(
|
|
1952
1883
|
"Your website is using the default design system colors and fonts. Custom branding makes the website feel uniquely yours.",
|
|
1953
1884
|
"elementor"
|
|
1954
1885
|
),
|
|
1955
|
-
fixHint: (0,
|
|
1886
|
+
fixHint: (0, import_i18n24.__)("Open Site Settings and customize your kit (colors, fonts, layout).", "elementor"),
|
|
1956
1887
|
categories: ["best-practices"],
|
|
1957
1888
|
severity: "info",
|
|
1958
1889
|
weight: 1,
|
|
@@ -1964,8 +1895,8 @@ var audit4 = {
|
|
|
1964
1895
|
status: "fail",
|
|
1965
1896
|
violations: [
|
|
1966
1897
|
{
|
|
1967
|
-
auditId:
|
|
1968
|
-
label: (0,
|
|
1898
|
+
auditId: audit6.id,
|
|
1899
|
+
label: (0, import_i18n24.__)("Kit appears unchanged from default.", "elementor"),
|
|
1969
1900
|
targetHint: "site-settings"
|
|
1970
1901
|
}
|
|
1971
1902
|
]
|
|
@@ -1974,22 +1905,22 @@ var audit4 = {
|
|
|
1974
1905
|
};
|
|
1975
1906
|
|
|
1976
1907
|
// src/audits/deprecated-widgets.ts
|
|
1977
|
-
var
|
|
1978
|
-
var
|
|
1908
|
+
var import_editor_elements8 = require("@elementor/editor-elements");
|
|
1909
|
+
var import_i18n25 = require("@wordpress/i18n");
|
|
1979
1910
|
var DEPRECATION_CONTROL_NAME = "deprecation_message";
|
|
1980
|
-
var
|
|
1911
|
+
var audit7 = {
|
|
1981
1912
|
id: "audits/deprecated-widgets",
|
|
1982
|
-
title: (0,
|
|
1983
|
-
description: (0,
|
|
1913
|
+
title: (0, import_i18n25.__)("Deprecated widgets", "elementor"),
|
|
1914
|
+
description: (0, import_i18n25.__)(
|
|
1984
1915
|
"Deprecated widgets should not be used. For better capabilities use the recommended replacement.",
|
|
1985
1916
|
"elementor"
|
|
1986
1917
|
),
|
|
1987
|
-
fixHint: (0,
|
|
1918
|
+
fixHint: (0, import_i18n25.__)("Replace each deprecated widget with the recommended new widget shown in its panel.", "elementor"),
|
|
1988
1919
|
categories: ["best-practices", "performance"],
|
|
1989
1920
|
severity: "warning",
|
|
1990
1921
|
weight: 7,
|
|
1991
1922
|
evaluate: (ctx) => {
|
|
1992
|
-
const widgetsCache = (0,
|
|
1923
|
+
const widgetsCache = (0, import_editor_elements8.getWidgetsCache)();
|
|
1993
1924
|
if (!widgetsCache) {
|
|
1994
1925
|
return { status: "skipped", reason: "widgets-cache-unavailable" };
|
|
1995
1926
|
}
|
|
@@ -2008,10 +1939,10 @@ var audit5 = {
|
|
|
2008
1939
|
return;
|
|
2009
1940
|
}
|
|
2010
1941
|
violations.push({
|
|
2011
|
-
auditId:
|
|
1942
|
+
auditId: audit7.id,
|
|
2012
1943
|
elementId: node.id,
|
|
2013
1944
|
targetHint: "element-settings",
|
|
2014
|
-
label: (0,
|
|
1945
|
+
label: (0, import_i18n25.__)("Using deprecated widget.", "elementor")
|
|
2015
1946
|
});
|
|
2016
1947
|
});
|
|
2017
1948
|
return violations.length === 0 ? { status: "pass" } : { status: "fail", violations };
|
|
@@ -2019,28 +1950,7 @@ var audit5 = {
|
|
|
2019
1950
|
};
|
|
2020
1951
|
|
|
2021
1952
|
// src/audits/google-consent-mode.ts
|
|
2022
|
-
var
|
|
2023
|
-
|
|
2024
|
-
// src/utils/fetch-rendered-html.ts
|
|
2025
|
-
var FETCH_TIMEOUT_MS = 1e4;
|
|
2026
|
-
async function fetchRenderedHtml(url) {
|
|
2027
|
-
if (!url) {
|
|
2028
|
-
return null;
|
|
2029
|
-
}
|
|
2030
|
-
const timeoutController = new AbortController();
|
|
2031
|
-
const timeoutId = setTimeout(() => timeoutController.abort(), FETCH_TIMEOUT_MS);
|
|
2032
|
-
try {
|
|
2033
|
-
const response = await fetch(url, { credentials: "omit", signal: timeoutController.signal });
|
|
2034
|
-
if (!response.ok) {
|
|
2035
|
-
return null;
|
|
2036
|
-
}
|
|
2037
|
-
return await response.text();
|
|
2038
|
-
} catch {
|
|
2039
|
-
return null;
|
|
2040
|
-
} finally {
|
|
2041
|
-
clearTimeout(timeoutId);
|
|
2042
|
-
}
|
|
2043
|
-
}
|
|
1953
|
+
var import_i18n26 = require("@wordpress/i18n");
|
|
2044
1954
|
|
|
2045
1955
|
// src/utils/scan-consent-signals.ts
|
|
2046
1956
|
var GOOGLE_TRACKING_PATTERNS = [
|
|
@@ -2061,44 +1971,43 @@ function hasConsentDefaultCall(html) {
|
|
|
2061
1971
|
}
|
|
2062
1972
|
|
|
2063
1973
|
// src/audits/google-consent-mode.ts
|
|
2064
|
-
var
|
|
1974
|
+
var audit8 = {
|
|
2065
1975
|
id: "audits/google-consent-mode",
|
|
2066
|
-
title: (0,
|
|
2067
|
-
description: (0,
|
|
1976
|
+
title: (0, import_i18n26.__)("Google Consent Mode", "elementor"),
|
|
1977
|
+
description: (0, import_i18n26.__)(
|
|
2068
1978
|
"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.",
|
|
2069
1979
|
"elementor"
|
|
2070
1980
|
),
|
|
2071
|
-
fixHint: (0,
|
|
1981
|
+
fixHint: (0, import_i18n26.__)(
|
|
2072
1982
|
"Turn on Google Consent Mode in your cookie consent plugin so Google tags respect visitor consent choices.",
|
|
2073
1983
|
"elementor"
|
|
2074
1984
|
),
|
|
2075
1985
|
categories: ["compliance"],
|
|
2076
1986
|
severity: "warning",
|
|
2077
1987
|
weight: 1,
|
|
2078
|
-
evaluate:
|
|
1988
|
+
evaluate: (ctx) => {
|
|
2079
1989
|
if (!ctx.pageContext.frontend_url) {
|
|
2080
|
-
return { status: "skipped", reason: (0,
|
|
1990
|
+
return { status: "skipped", reason: (0, import_i18n26.__)("Page is not published.", "elementor") };
|
|
2081
1991
|
}
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
return { status: "skipped", reason: (0, import_i18n30.__)("Could not fetch the published page.", "elementor") };
|
|
1992
|
+
if (!ctx.renderedHtml) {
|
|
1993
|
+
return { status: "skipped", reason: (0, import_i18n26.__)("Could not fetch the published page.", "elementor") };
|
|
2085
1994
|
}
|
|
2086
|
-
if (!hasGoogleTracking(
|
|
2087
|
-
return { status: "skipped", reason: (0,
|
|
1995
|
+
if (!hasGoogleTracking(ctx.renderedHtml)) {
|
|
1996
|
+
return { status: "skipped", reason: (0, import_i18n26.__)("No Google tracking product detected.", "elementor") };
|
|
2088
1997
|
}
|
|
2089
|
-
if (hasConsentDefaultCall(
|
|
1998
|
+
if (hasConsentDefaultCall(ctx.renderedHtml)) {
|
|
2090
1999
|
return { status: "pass" };
|
|
2091
2000
|
}
|
|
2092
|
-
const label = (0,
|
|
2001
|
+
const label = (0, import_i18n26.__)("No Google Consent Mode signal was found on the page.", "elementor");
|
|
2093
2002
|
const isCookiezReady = ctx.pageContext.cookiez_plugin_installed && ctx.pageContext.cookiez_plugin_active;
|
|
2094
2003
|
if (isCookiezReady) {
|
|
2095
2004
|
return {
|
|
2096
2005
|
status: "fail",
|
|
2097
2006
|
violations: [
|
|
2098
2007
|
{
|
|
2099
|
-
auditId:
|
|
2008
|
+
auditId: audit8.id,
|
|
2100
2009
|
label,
|
|
2101
|
-
ctaLabel: (0,
|
|
2010
|
+
ctaLabel: (0, import_i18n26.__)("Enable", "elementor"),
|
|
2102
2011
|
externalUrl: ctx.pageContext.cookiez_consent_mode_settings_url
|
|
2103
2012
|
}
|
|
2104
2013
|
]
|
|
@@ -2108,7 +2017,7 @@ var audit6 = {
|
|
|
2108
2017
|
status: "fail",
|
|
2109
2018
|
violations: [
|
|
2110
2019
|
{
|
|
2111
|
-
auditId:
|
|
2020
|
+
auditId: audit8.id,
|
|
2112
2021
|
label,
|
|
2113
2022
|
externalUrl: ctx.pageContext.cookiez_plugin_action_url
|
|
2114
2023
|
}
|
|
@@ -2118,7 +2027,7 @@ var audit6 = {
|
|
|
2118
2027
|
};
|
|
2119
2028
|
|
|
2120
2029
|
// src/audits/heading-structure.ts
|
|
2121
|
-
var
|
|
2030
|
+
var import_i18n27 = require("@wordpress/i18n");
|
|
2122
2031
|
var HEADING_LEVELS = ["h1", "h2", "h3", "h4", "h5", "h6"];
|
|
2123
2032
|
var HEADING_CONTROLS_REGISTRY = {
|
|
2124
2033
|
// Core
|
|
@@ -2294,47 +2203,47 @@ function extractPageHeadings(tree) {
|
|
|
2294
2203
|
});
|
|
2295
2204
|
return headings;
|
|
2296
2205
|
}
|
|
2297
|
-
var
|
|
2206
|
+
var audit9 = {
|
|
2298
2207
|
id: "audits/heading-structure",
|
|
2299
|
-
title: (0,
|
|
2300
|
-
description: (0,
|
|
2301
|
-
fixHint: (0,
|
|
2208
|
+
title: (0, import_i18n27.__)("Heading structure", "elementor"),
|
|
2209
|
+
description: (0, import_i18n27.__)("Pages should have exactly one H1 and a non-skipping heading order.", "elementor"),
|
|
2210
|
+
fixHint: (0, import_i18n27.__)("Ensure your page has one H1 and that heading levels do not skip (no H2 \u2192 H4).", "elementor"),
|
|
2302
2211
|
categories: ["seo", "accessibility"],
|
|
2303
2212
|
severity: "error",
|
|
2304
2213
|
weight: 10,
|
|
2305
2214
|
evaluate: (ctx) => {
|
|
2306
2215
|
if (ctx.elements.tree.length === 0) {
|
|
2307
|
-
return { status: "skipped", reason: (0,
|
|
2216
|
+
return { status: "skipped", reason: (0, import_i18n27.__)("No elements", "elementor") };
|
|
2308
2217
|
}
|
|
2309
2218
|
const headings = extractPageHeadings(ctx.elements.tree);
|
|
2310
2219
|
const violations = [];
|
|
2311
2220
|
if (headings.length === 0) {
|
|
2312
2221
|
violations.push({
|
|
2313
|
-
auditId:
|
|
2314
|
-
label: (0,
|
|
2222
|
+
auditId: audit9.id,
|
|
2223
|
+
label: (0, import_i18n27.__)("No headings found on the page.", "elementor")
|
|
2315
2224
|
});
|
|
2316
2225
|
} else {
|
|
2317
2226
|
const h1Count = headings.filter((h) => h.level === 1).length;
|
|
2318
2227
|
if (h1Count === 0) {
|
|
2319
|
-
violations.push({ auditId:
|
|
2228
|
+
violations.push({ auditId: audit9.id, label: (0, import_i18n27.__)("No H1 on the page.", "elementor") });
|
|
2320
2229
|
}
|
|
2321
2230
|
if (h1Count > 1) {
|
|
2322
2231
|
headings.filter((h) => h.level === 1).slice(1).forEach(
|
|
2323
2232
|
(h) => violations.push({
|
|
2324
|
-
auditId:
|
|
2233
|
+
auditId: audit9.id,
|
|
2325
2234
|
elementId: h.elementId,
|
|
2326
2235
|
targetHint: "element-settings",
|
|
2327
|
-
label: (0,
|
|
2236
|
+
label: (0, import_i18n27.__)("More than one H1 on the page.", "elementor")
|
|
2328
2237
|
})
|
|
2329
2238
|
);
|
|
2330
2239
|
}
|
|
2331
2240
|
for (let i = 1; i < headings.length; i++) {
|
|
2332
2241
|
if (headings[i].level - headings[i - 1].level > 1) {
|
|
2333
2242
|
violations.push({
|
|
2334
|
-
auditId:
|
|
2243
|
+
auditId: audit9.id,
|
|
2335
2244
|
elementId: headings[i].elementId,
|
|
2336
2245
|
targetHint: "element-settings",
|
|
2337
|
-
label: (0,
|
|
2246
|
+
label: (0, import_i18n27.__)("Heading level skipped.", "elementor")
|
|
2338
2247
|
});
|
|
2339
2248
|
}
|
|
2340
2249
|
}
|
|
@@ -2344,33 +2253,33 @@ var audit7 = {
|
|
|
2344
2253
|
};
|
|
2345
2254
|
|
|
2346
2255
|
// src/audits/hidden-elements.ts
|
|
2347
|
-
var
|
|
2256
|
+
var import_i18n28 = require("@wordpress/i18n");
|
|
2348
2257
|
function isHiddenOnAllDevices(settings) {
|
|
2349
2258
|
return Boolean(settings.hide_desktop) && Boolean(settings.hide_tablet) && Boolean(settings.hide_mobile);
|
|
2350
2259
|
}
|
|
2351
|
-
var
|
|
2260
|
+
var audit10 = {
|
|
2352
2261
|
id: "audits/hidden-elements",
|
|
2353
|
-
title: (0,
|
|
2354
|
-
description: (0,
|
|
2262
|
+
title: (0, import_i18n28.__)("Hidden elements", "elementor"),
|
|
2263
|
+
description: (0, import_i18n28.__)(
|
|
2355
2264
|
"Elements hidden on all devices simultaneously are effectively dead code in the page tree.",
|
|
2356
2265
|
"elementor"
|
|
2357
2266
|
),
|
|
2358
|
-
fixHint: (0,
|
|
2267
|
+
fixHint: (0, import_i18n28.__)("Remove the element or make it visible on at least one device breakpoint.", "elementor"),
|
|
2359
2268
|
categories: ["best-practices", "performance"],
|
|
2360
2269
|
severity: "info",
|
|
2361
2270
|
weight: 3,
|
|
2362
2271
|
evaluate: (ctx) => {
|
|
2363
2272
|
if (ctx.elements.tree.length === 0) {
|
|
2364
|
-
return { status: "skipped", reason: (0,
|
|
2273
|
+
return { status: "skipped", reason: (0, import_i18n28.__)("No elements", "elementor") };
|
|
2365
2274
|
}
|
|
2366
2275
|
const violations = [];
|
|
2367
2276
|
walkElements(ctx.elements.tree, (node) => {
|
|
2368
2277
|
if (isHiddenOnAllDevices(node.settings)) {
|
|
2369
2278
|
violations.push({
|
|
2370
|
-
auditId:
|
|
2279
|
+
auditId: audit10.id,
|
|
2371
2280
|
elementId: node.id,
|
|
2372
2281
|
targetHint: "element-settings",
|
|
2373
|
-
label: (0,
|
|
2282
|
+
label: (0, import_i18n28.__)("Element is hidden on all devices.", "elementor")
|
|
2374
2283
|
});
|
|
2375
2284
|
}
|
|
2376
2285
|
});
|
|
@@ -2379,7 +2288,22 @@ var audit8 = {
|
|
|
2379
2288
|
};
|
|
2380
2289
|
|
|
2381
2290
|
// src/audits/images-alt-text.ts
|
|
2382
|
-
var
|
|
2291
|
+
var import_i18n29 = require("@wordpress/i18n");
|
|
2292
|
+
|
|
2293
|
+
// src/utils/alt-text-image-sources.ts
|
|
2294
|
+
function walkAltTextImageSources(tree, visit) {
|
|
2295
|
+
walkImageLikeSources(tree, visit);
|
|
2296
|
+
walkAtomicImageSources(tree, visit, ATOMIC_CONTENT_IMAGE_PROP_KEYS);
|
|
2297
|
+
}
|
|
2298
|
+
function hasAltTextImages(tree) {
|
|
2299
|
+
let found = false;
|
|
2300
|
+
walkAltTextImageSources(tree, ({ media }) => {
|
|
2301
|
+
if (media.id || media.url) {
|
|
2302
|
+
found = true;
|
|
2303
|
+
}
|
|
2304
|
+
});
|
|
2305
|
+
return found;
|
|
2306
|
+
}
|
|
2383
2307
|
|
|
2384
2308
|
// src/utils/image-alt.ts
|
|
2385
2309
|
function hasMeaningfulAlt(media, pageContext) {
|
|
@@ -2387,7 +2311,8 @@ function hasMeaningfulAlt(media, pageContext) {
|
|
|
2387
2311
|
return true;
|
|
2388
2312
|
}
|
|
2389
2313
|
if (media.id) {
|
|
2390
|
-
const
|
|
2314
|
+
const key = buildImageSizeKey({ id: media.id, size: media.size });
|
|
2315
|
+
const alt = pageContext.image_sizes[key]?.alt ?? "";
|
|
2391
2316
|
return alt.trim().length > 0;
|
|
2392
2317
|
}
|
|
2393
2318
|
return (media.alt ?? "").trim().length > 0;
|
|
@@ -2397,22 +2322,23 @@ function isImageSourcePresent(media) {
|
|
|
2397
2322
|
}
|
|
2398
2323
|
|
|
2399
2324
|
// src/audits/images-alt-text.ts
|
|
2400
|
-
var
|
|
2325
|
+
var audit11 = {
|
|
2401
2326
|
id: "audits/images-alt-text",
|
|
2402
|
-
title: (0,
|
|
2403
|
-
description: (0,
|
|
2404
|
-
fixHint: (0,
|
|
2327
|
+
title: (0, import_i18n29.__)("Images alt text", "elementor"),
|
|
2328
|
+
description: (0, import_i18n29.__)("Every image needs a meaningful alt attribute for screen readers and image-search.", "elementor"),
|
|
2329
|
+
fixHint: (0, import_i18n29.__)("Open the image's settings and add an Alt Text describing the image.", "elementor"),
|
|
2405
2330
|
categories: ["seo", "accessibility"],
|
|
2406
2331
|
severity: "error",
|
|
2407
2332
|
weight: 10,
|
|
2408
2333
|
evaluate: (ctx) => {
|
|
2409
|
-
if (!
|
|
2410
|
-
return { status: "skipped", reason: (0,
|
|
2334
|
+
if (!hasAltTextImages(ctx.elements.tree)) {
|
|
2335
|
+
return { status: "skipped", reason: (0, import_i18n29.__)("No images", "elementor") };
|
|
2411
2336
|
}
|
|
2337
|
+
const isReady = ctx.pageContext.ally_plugin_active;
|
|
2412
2338
|
const violations = [];
|
|
2413
2339
|
const failedWidgetIds = /* @__PURE__ */ new Set();
|
|
2414
2340
|
let missingAltImageCount = 0;
|
|
2415
|
-
|
|
2341
|
+
walkAltTextImageSources(ctx.elements.tree, ({ node, media }) => {
|
|
2416
2342
|
if (!isImageSourcePresent(media) || hasMeaningfulAlt(media, ctx.pageContext)) {
|
|
2417
2343
|
return;
|
|
2418
2344
|
}
|
|
@@ -2420,11 +2346,12 @@ var audit9 = {
|
|
|
2420
2346
|
if (!failedWidgetIds.has(node.id)) {
|
|
2421
2347
|
failedWidgetIds.add(node.id);
|
|
2422
2348
|
violations.push({
|
|
2423
|
-
auditId:
|
|
2349
|
+
auditId: audit11.id,
|
|
2424
2350
|
elementId: node.id,
|
|
2425
2351
|
targetHint: "element-settings",
|
|
2426
|
-
label: (0,
|
|
2427
|
-
externalUrl: ctx.pageContext.ally_plugin_url
|
|
2352
|
+
label: (0, import_i18n29.__)("Image is missing alt text.", "elementor"),
|
|
2353
|
+
externalUrl: isReady ? ctx.pageContext.ally_scan_url : ctx.pageContext.ally_plugin_url,
|
|
2354
|
+
ctaLabel: (0, import_i18n29.__)("Fix with Ally", "elementor")
|
|
2428
2355
|
});
|
|
2429
2356
|
}
|
|
2430
2357
|
});
|
|
@@ -2432,30 +2359,79 @@ var audit9 = {
|
|
|
2432
2359
|
}
|
|
2433
2360
|
};
|
|
2434
2361
|
|
|
2362
|
+
// src/audits/images-inefficient-format.ts
|
|
2363
|
+
var import_i18n30 = require("@wordpress/i18n");
|
|
2364
|
+
var LEGACY_RASTER_MIME_TYPES = /* @__PURE__ */ new Set(["image/jpeg", "image/png", "image/gif", "image/bmp", "image/tiff"]);
|
|
2365
|
+
var audit12 = {
|
|
2366
|
+
id: "audits/images-inefficient-format",
|
|
2367
|
+
title: (0, import_i18n30.__)("Inefficient image format", "elementor"),
|
|
2368
|
+
description: (0, import_i18n30.__)("Image isn't served in a modern, efficient format like WebP or AVIF.", "elementor"),
|
|
2369
|
+
fixHint: (0, import_i18n30.__)("Convert the image to a modern format like WebP or AVIF, or enable image optimization.", "elementor"),
|
|
2370
|
+
categories: ["performance"],
|
|
2371
|
+
severity: "info",
|
|
2372
|
+
weight: 1,
|
|
2373
|
+
evaluate: (ctx) => {
|
|
2374
|
+
const isReady = ctx.pageContext.image_optimization_plugin_active;
|
|
2375
|
+
const offendingElementIds = /* @__PURE__ */ new Set();
|
|
2376
|
+
let hasAnyImage = false;
|
|
2377
|
+
let inefficientImageFormatCount = 0;
|
|
2378
|
+
const evaluateSource = (node, media) => {
|
|
2379
|
+
if (media.id || media.url) {
|
|
2380
|
+
hasAnyImage = true;
|
|
2381
|
+
}
|
|
2382
|
+
const id = media.id;
|
|
2383
|
+
if (!id) {
|
|
2384
|
+
return;
|
|
2385
|
+
}
|
|
2386
|
+
const mime = ctx.pageContext.image_sizes[buildImageSizeKey({ id, size: media.size })]?.mime;
|
|
2387
|
+
if (!mime || !LEGACY_RASTER_MIME_TYPES.has(mime)) {
|
|
2388
|
+
return;
|
|
2389
|
+
}
|
|
2390
|
+
inefficientImageFormatCount++;
|
|
2391
|
+
offendingElementIds.add(node.id);
|
|
2392
|
+
};
|
|
2393
|
+
walkAllImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2394
|
+
if (!hasAnyImage) {
|
|
2395
|
+
return { status: "skipped", reason: (0, import_i18n30.__)("No images", "elementor") };
|
|
2396
|
+
}
|
|
2397
|
+
const violations = Array.from(offendingElementIds).map((elementId) => ({
|
|
2398
|
+
auditId: audit12.id,
|
|
2399
|
+
elementId,
|
|
2400
|
+
targetHint: "element-settings",
|
|
2401
|
+
label: (0, import_i18n30.__)("Image isn't served in a modern format like WebP or AVIF.", "elementor"),
|
|
2402
|
+
externalUrl: isReady ? ctx.pageContext.image_optimization_settings_url : ctx.pageContext.image_optimization_plugin_url,
|
|
2403
|
+
ctaLabel: (0, import_i18n30.__)("Optimize all", "elementor")
|
|
2404
|
+
}));
|
|
2405
|
+
return violations.length === 0 ? { status: "pass" } : { status: "fail", violations, metadata: { inefficientImageFormatCount } };
|
|
2406
|
+
}
|
|
2407
|
+
};
|
|
2408
|
+
|
|
2435
2409
|
// src/audits/images-too-large.ts
|
|
2436
|
-
var
|
|
2410
|
+
var import_i18n31 = require("@wordpress/i18n");
|
|
2437
2411
|
var SIZE_THRESHOLD_BYTES = 500 * 1024;
|
|
2438
2412
|
var BYTES_PER_KB = 1024;
|
|
2439
|
-
var
|
|
2413
|
+
var audit13 = {
|
|
2440
2414
|
id: "audits/images-too-large",
|
|
2441
|
-
title: (0,
|
|
2442
|
-
description: (0,
|
|
2443
|
-
fixHint: (0,
|
|
2415
|
+
title: (0, import_i18n31.__)("Oversized images", "elementor"),
|
|
2416
|
+
description: (0, import_i18n31.__)("Large image files slow down the page.", "elementor"),
|
|
2417
|
+
fixHint: (0, import_i18n31.__)("Replace the image with a smaller version or enable image optimization.", "elementor"),
|
|
2444
2418
|
categories: ["performance"],
|
|
2445
2419
|
severity: "warning",
|
|
2446
2420
|
weight: 7,
|
|
2447
2421
|
evaluate: (ctx) => {
|
|
2448
|
-
|
|
2449
|
-
return { status: "skipped", reason: (0, import_i18n34.__)("No images", "elementor") };
|
|
2450
|
-
}
|
|
2422
|
+
const isReady = ctx.pageContext.image_optimization_plugin_active;
|
|
2451
2423
|
const widgetMaxKb = /* @__PURE__ */ new Map();
|
|
2452
2424
|
let oversizedImageCount = 0;
|
|
2453
|
-
|
|
2425
|
+
let hasAnyImage = false;
|
|
2426
|
+
const evaluateSource = (node, media) => {
|
|
2427
|
+
if (media.id || media.url) {
|
|
2428
|
+
hasAnyImage = true;
|
|
2429
|
+
}
|
|
2454
2430
|
const id = media.id;
|
|
2455
2431
|
if (!id) {
|
|
2456
2432
|
return;
|
|
2457
2433
|
}
|
|
2458
|
-
const size = ctx.pageContext.image_sizes[id];
|
|
2434
|
+
const size = ctx.pageContext.image_sizes[buildImageSizeKey({ id, size: media.size })];
|
|
2459
2435
|
if (!size || size.filesize_bytes <= SIZE_THRESHOLD_BYTES) {
|
|
2460
2436
|
return;
|
|
2461
2437
|
}
|
|
@@ -2463,38 +2439,43 @@ var audit10 = {
|
|
|
2463
2439
|
const kb = Math.round(size.filesize_bytes / BYTES_PER_KB);
|
|
2464
2440
|
const currentMax = widgetMaxKb.get(node.id) ?? 0;
|
|
2465
2441
|
widgetMaxKb.set(node.id, Math.max(currentMax, kb));
|
|
2466
|
-
}
|
|
2442
|
+
};
|
|
2443
|
+
walkAllImageSources(ctx.elements.tree, ({ node, media }) => evaluateSource(node, media));
|
|
2444
|
+
if (!hasAnyImage) {
|
|
2445
|
+
return { status: "skipped", reason: (0, import_i18n31.__)("No images", "elementor") };
|
|
2446
|
+
}
|
|
2467
2447
|
const violations = Array.from(widgetMaxKb.entries()).map(([elementId, kb]) => ({
|
|
2468
|
-
auditId:
|
|
2448
|
+
auditId: audit13.id,
|
|
2469
2449
|
elementId,
|
|
2470
2450
|
targetHint: "element-settings",
|
|
2471
|
-
label: (0,
|
|
2451
|
+
label: (0, import_i18n31.sprintf)(
|
|
2472
2452
|
/* translators: %d is the image file size in kilobytes. */
|
|
2473
|
-
(0,
|
|
2453
|
+
(0, import_i18n31.__)("Image is %d KB (over 500 KB).", "elementor"),
|
|
2474
2454
|
kb
|
|
2475
2455
|
),
|
|
2476
|
-
externalUrl: ctx.pageContext.image_optimization_plugin_url
|
|
2456
|
+
externalUrl: isReady ? ctx.pageContext.image_optimization_settings_url : ctx.pageContext.image_optimization_plugin_url,
|
|
2457
|
+
ctaLabel: (0, import_i18n31.__)("Optimize all", "elementor")
|
|
2477
2458
|
}));
|
|
2478
2459
|
return violations.length === 0 ? { status: "pass" } : { status: "fail", violations, metadata: { oversizedImageCount } };
|
|
2479
2460
|
}
|
|
2480
2461
|
};
|
|
2481
2462
|
|
|
2482
2463
|
// src/audits/nested-boxed-containers.ts
|
|
2483
|
-
var
|
|
2464
|
+
var import_i18n32 = require("@wordpress/i18n");
|
|
2484
2465
|
function isBoxed(settings) {
|
|
2485
2466
|
return settings.content_width === "boxed";
|
|
2486
2467
|
}
|
|
2487
|
-
var
|
|
2468
|
+
var audit14 = {
|
|
2488
2469
|
id: "audits/nested-boxed-containers",
|
|
2489
|
-
title: (0,
|
|
2490
|
-
description: (0,
|
|
2491
|
-
fixHint: (0,
|
|
2470
|
+
title: (0, import_i18n32.__)("Boxed container nested inside a boxed parent", "elementor"),
|
|
2471
|
+
description: (0, import_i18n32.__)("An inner container does not need to be boxed when its parent already is.", "elementor"),
|
|
2472
|
+
fixHint: (0, import_i18n32.__)("Change the inner container's content width to Full Width.", "elementor"),
|
|
2492
2473
|
categories: ["best-practices", "performance"],
|
|
2493
2474
|
severity: "info",
|
|
2494
2475
|
weight: 5,
|
|
2495
2476
|
evaluate: (ctx) => {
|
|
2496
2477
|
if (ctx.elements.tree.length === 0) {
|
|
2497
|
-
return { status: "skipped", reason: (0,
|
|
2478
|
+
return { status: "skipped", reason: (0, import_i18n32.__)("No elements", "elementor") };
|
|
2498
2479
|
}
|
|
2499
2480
|
const violations = [];
|
|
2500
2481
|
walkElements(ctx.elements.tree, (node, parents) => {
|
|
@@ -2504,10 +2485,15 @@ var audit11 = {
|
|
|
2504
2485
|
const nearestContainerAncestor = [...parents].reverse().find((p) => p.elType === "container");
|
|
2505
2486
|
if (nearestContainerAncestor && isBoxed(nearestContainerAncestor.settings)) {
|
|
2506
2487
|
violations.push({
|
|
2507
|
-
auditId:
|
|
2488
|
+
auditId: audit14.id,
|
|
2508
2489
|
elementId: node.id,
|
|
2509
2490
|
targetHint: "element-settings",
|
|
2510
|
-
label: (0,
|
|
2491
|
+
label: (0, import_i18n32.__)("Nested boxed container.", "elementor"),
|
|
2492
|
+
angieFix: true,
|
|
2493
|
+
angiePrompt: (0, import_i18n32.__)(
|
|
2494
|
+
"Find containers that have nested containers. Containers can be deep-nested. Update the nested container styling so that when a parent container already uses a boxed setting, any inner container inside it is set to Full Width. Keep the first parent container boxed, remove all boxed styling from the nested inner containers, and preserve the inner container\u2019s content, spacing, alignment, and hierarchy.",
|
|
2495
|
+
"elementor"
|
|
2496
|
+
)
|
|
2511
2497
|
});
|
|
2512
2498
|
}
|
|
2513
2499
|
});
|
|
@@ -2516,12 +2502,12 @@ var audit11 = {
|
|
|
2516
2502
|
};
|
|
2517
2503
|
|
|
2518
2504
|
// src/audits/page-excerpt.ts
|
|
2519
|
-
var
|
|
2520
|
-
var
|
|
2505
|
+
var import_i18n33 = require("@wordpress/i18n");
|
|
2506
|
+
var audit15 = {
|
|
2521
2507
|
id: "audits/page-excerpt",
|
|
2522
|
-
title: (0,
|
|
2523
|
-
description: (0,
|
|
2524
|
-
fixHint: (0,
|
|
2508
|
+
title: (0, import_i18n33.__)("Page excerpt", "elementor"),
|
|
2509
|
+
description: (0, import_i18n33.__)("A descriptive excerpt helps search engines and previews summarize the page.", "elementor"),
|
|
2510
|
+
fixHint: (0, import_i18n33.__)("Open Page Settings and write a short excerpt.", "elementor"),
|
|
2525
2511
|
categories: ["seo"],
|
|
2526
2512
|
severity: "warning",
|
|
2527
2513
|
weight: 5,
|
|
@@ -2533,8 +2519,8 @@ var audit12 = {
|
|
|
2533
2519
|
status: "fail",
|
|
2534
2520
|
violations: [
|
|
2535
2521
|
{
|
|
2536
|
-
auditId:
|
|
2537
|
-
label: (0,
|
|
2522
|
+
auditId: audit15.id,
|
|
2523
|
+
label: (0, import_i18n33.__)("Page has no excerpt.", "elementor"),
|
|
2538
2524
|
targetHint: "page-settings",
|
|
2539
2525
|
angieFix: true
|
|
2540
2526
|
}
|
|
@@ -2544,12 +2530,12 @@ var audit12 = {
|
|
|
2544
2530
|
};
|
|
2545
2531
|
|
|
2546
2532
|
// src/audits/page-featured-image.ts
|
|
2547
|
-
var
|
|
2548
|
-
var
|
|
2533
|
+
var import_i18n34 = require("@wordpress/i18n");
|
|
2534
|
+
var audit16 = {
|
|
2549
2535
|
id: "audits/page-featured-image",
|
|
2550
|
-
title: (0,
|
|
2551
|
-
description: (0,
|
|
2552
|
-
fixHint: (0,
|
|
2536
|
+
title: (0, import_i18n34.__)("Page featured image", "elementor"),
|
|
2537
|
+
description: (0, import_i18n34.__)("Featured images are used by social shares and many themes for hero visuals.", "elementor"),
|
|
2538
|
+
fixHint: (0, import_i18n34.__)("Open Page Settings and set a featured image.", "elementor"),
|
|
2553
2539
|
categories: ["seo"],
|
|
2554
2540
|
severity: "info",
|
|
2555
2541
|
weight: 5,
|
|
@@ -2561,8 +2547,8 @@ var audit13 = {
|
|
|
2561
2547
|
status: "fail",
|
|
2562
2548
|
violations: [
|
|
2563
2549
|
{
|
|
2564
|
-
auditId:
|
|
2565
|
-
label: (0,
|
|
2550
|
+
auditId: audit16.id,
|
|
2551
|
+
label: (0, import_i18n34.__)("No featured image set.", "elementor"),
|
|
2566
2552
|
targetHint: "page-settings"
|
|
2567
2553
|
}
|
|
2568
2554
|
]
|
|
@@ -2571,13 +2557,13 @@ var audit13 = {
|
|
|
2571
2557
|
};
|
|
2572
2558
|
|
|
2573
2559
|
// src/audits/page-title.ts
|
|
2574
|
-
var
|
|
2560
|
+
var import_i18n35 = require("@wordpress/i18n");
|
|
2575
2561
|
var MAX_TITLE_LENGTH = 60;
|
|
2576
|
-
var
|
|
2562
|
+
var audit17 = {
|
|
2577
2563
|
id: "audits/page-title",
|
|
2578
|
-
title: (0,
|
|
2579
|
-
description: (0,
|
|
2580
|
-
fixHint: (0,
|
|
2564
|
+
title: (0, import_i18n35.__)("Page title", "elementor"),
|
|
2565
|
+
description: (0, import_i18n35.__)("Pages need a clear title for SEO and screen-reader navigation.", "elementor"),
|
|
2566
|
+
fixHint: (0, import_i18n35.__)("Open Page Settings and add a title.", "elementor"),
|
|
2581
2567
|
categories: ["seo"],
|
|
2582
2568
|
severity: "error",
|
|
2583
2569
|
weight: 10,
|
|
@@ -2588,11 +2574,11 @@ var audit14 = {
|
|
|
2588
2574
|
status: "fail",
|
|
2589
2575
|
violations: [
|
|
2590
2576
|
{
|
|
2591
|
-
auditId:
|
|
2592
|
-
label: (0,
|
|
2577
|
+
auditId: audit17.id,
|
|
2578
|
+
label: (0, import_i18n35.__)("Page has no title.", "elementor"),
|
|
2593
2579
|
targetHint: "page-settings",
|
|
2594
2580
|
angieFix: true,
|
|
2595
|
-
angiePrompt: (0,
|
|
2581
|
+
angiePrompt: (0, import_i18n35.__)(
|
|
2596
2582
|
"Based on this page's contents, generate a title for this page.",
|
|
2597
2583
|
"elementor"
|
|
2598
2584
|
)
|
|
@@ -2605,8 +2591,8 @@ var audit14 = {
|
|
|
2605
2591
|
status: "fail",
|
|
2606
2592
|
violations: [
|
|
2607
2593
|
{
|
|
2608
|
-
auditId:
|
|
2609
|
-
label: (0,
|
|
2594
|
+
auditId: audit17.id,
|
|
2595
|
+
label: (0, import_i18n35.__)("Page title is too long.", "elementor"),
|
|
2610
2596
|
targetHint: "page-settings",
|
|
2611
2597
|
angieFix: true
|
|
2612
2598
|
}
|
|
@@ -2618,7 +2604,7 @@ var audit14 = {
|
|
|
2618
2604
|
};
|
|
2619
2605
|
|
|
2620
2606
|
// src/audits/prefer-global-colors.ts
|
|
2621
|
-
var
|
|
2607
|
+
var import_i18n36 = require("@wordpress/i18n");
|
|
2622
2608
|
|
|
2623
2609
|
// src/utils/collect-hardcoded-colors.ts
|
|
2624
2610
|
var RESERVED_SETTING_KEYS = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
|
|
@@ -2684,20 +2670,20 @@ function findMatchingGlobalByValue(value, globals) {
|
|
|
2684
2670
|
}
|
|
2685
2671
|
|
|
2686
2672
|
// src/audits/prefer-global-colors.ts
|
|
2687
|
-
var
|
|
2673
|
+
var audit18 = {
|
|
2688
2674
|
id: "audits/prefer-global-colors",
|
|
2689
|
-
title: (0,
|
|
2690
|
-
description: (0,
|
|
2691
|
-
fixHint: (0,
|
|
2675
|
+
title: (0, import_i18n36.__)("Prefer global colors", "elementor"),
|
|
2676
|
+
description: (0, import_i18n36.__)("Global colors make the design consistent and easy to update site-wide.", "elementor"),
|
|
2677
|
+
fixHint: (0, import_i18n36.__)("Replace the hard-coded value with the matching global color.", "elementor"),
|
|
2692
2678
|
categories: ["best-practices"],
|
|
2693
2679
|
severity: "info",
|
|
2694
2680
|
weight: 3,
|
|
2695
2681
|
evaluate: (ctx) => {
|
|
2696
2682
|
if (ctx.elements.tree.length === 0) {
|
|
2697
|
-
return { status: "skipped", reason: (0,
|
|
2683
|
+
return { status: "skipped", reason: (0, import_i18n36.__)("No elements", "elementor") };
|
|
2698
2684
|
}
|
|
2699
2685
|
if (ctx.kit.globals.colors.length === 0) {
|
|
2700
|
-
return { status: "skipped", reason: (0,
|
|
2686
|
+
return { status: "skipped", reason: (0, import_i18n36.__)("No global colors", "elementor") };
|
|
2701
2687
|
}
|
|
2702
2688
|
const violations = [];
|
|
2703
2689
|
walkElements(ctx.elements.tree, (node) => {
|
|
@@ -2707,13 +2693,13 @@ var audit15 = {
|
|
|
2707
2693
|
continue;
|
|
2708
2694
|
}
|
|
2709
2695
|
violations.push({
|
|
2710
|
-
auditId:
|
|
2696
|
+
auditId: audit18.id,
|
|
2711
2697
|
elementId: node.id,
|
|
2712
2698
|
targetHint: "element-settings",
|
|
2713
2699
|
angieFix: true,
|
|
2714
|
-
label: (0,
|
|
2700
|
+
label: (0, import_i18n36.sprintf)(
|
|
2715
2701
|
/* translators: 1: hard-coded color value, 2: global color title. */
|
|
2716
|
-
(0,
|
|
2702
|
+
(0, import_i18n36.__)('replace "%1$s" with "%2$s" global color', "elementor"),
|
|
2717
2703
|
value,
|
|
2718
2704
|
global.title
|
|
2719
2705
|
)
|
|
@@ -2725,7 +2711,7 @@ var audit15 = {
|
|
|
2725
2711
|
};
|
|
2726
2712
|
|
|
2727
2713
|
// src/audits/prefer-global-fonts.ts
|
|
2728
|
-
var
|
|
2714
|
+
var import_i18n37 = require("@wordpress/i18n");
|
|
2729
2715
|
|
|
2730
2716
|
// src/utils/collect-hardcoded-fonts.ts
|
|
2731
2717
|
var RESERVED_SETTING_KEYS2 = /* @__PURE__ */ new Set(["__globals__", "__dynamic__"]);
|
|
@@ -2783,20 +2769,20 @@ function collectHardcodedFonts(settings, pathPrefix = "") {
|
|
|
2783
2769
|
}
|
|
2784
2770
|
|
|
2785
2771
|
// src/audits/prefer-global-fonts.ts
|
|
2786
|
-
var
|
|
2772
|
+
var audit19 = {
|
|
2787
2773
|
id: "audits/prefer-global-fonts",
|
|
2788
|
-
title: (0,
|
|
2789
|
-
description: (0,
|
|
2790
|
-
fixHint: (0,
|
|
2774
|
+
title: (0, import_i18n37.__)("Prefer global fonts", "elementor"),
|
|
2775
|
+
description: (0, import_i18n37.__)("Global fonts make the design consistent and easy to update site-wide.", "elementor"),
|
|
2776
|
+
fixHint: (0, import_i18n37.__)("Replace the hard-coded value with the matching global font.", "elementor"),
|
|
2791
2777
|
categories: ["best-practices", "performance"],
|
|
2792
2778
|
severity: "info",
|
|
2793
2779
|
weight: 3,
|
|
2794
2780
|
evaluate: (ctx) => {
|
|
2795
2781
|
if (ctx.elements.tree.length === 0) {
|
|
2796
|
-
return { status: "skipped", reason: (0,
|
|
2782
|
+
return { status: "skipped", reason: (0, import_i18n37.__)("No elements", "elementor") };
|
|
2797
2783
|
}
|
|
2798
2784
|
if (ctx.kit.globals.fonts.length === 0) {
|
|
2799
|
-
return { status: "skipped", reason: (0,
|
|
2785
|
+
return { status: "skipped", reason: (0, import_i18n37.__)("No global fonts", "elementor") };
|
|
2800
2786
|
}
|
|
2801
2787
|
const violations = [];
|
|
2802
2788
|
walkElements(ctx.elements.tree, (node) => {
|
|
@@ -2806,12 +2792,12 @@ var audit16 = {
|
|
|
2806
2792
|
continue;
|
|
2807
2793
|
}
|
|
2808
2794
|
violations.push({
|
|
2809
|
-
auditId:
|
|
2795
|
+
auditId: audit19.id,
|
|
2810
2796
|
elementId: node.id,
|
|
2811
2797
|
targetHint: "element-settings",
|
|
2812
|
-
label: (0,
|
|
2798
|
+
label: (0, import_i18n37.sprintf)(
|
|
2813
2799
|
/* translators: %s: global font title. */
|
|
2814
|
-
(0,
|
|
2800
|
+
(0, import_i18n37.__)('replace hardcoded typography with "%s" global font', "elementor"),
|
|
2815
2801
|
global.title
|
|
2816
2802
|
)
|
|
2817
2803
|
});
|
|
@@ -2822,15 +2808,15 @@ var audit16 = {
|
|
|
2822
2808
|
};
|
|
2823
2809
|
|
|
2824
2810
|
// src/audits/privacy-policy.ts
|
|
2825
|
-
var
|
|
2826
|
-
var
|
|
2811
|
+
var import_i18n38 = require("@wordpress/i18n");
|
|
2812
|
+
var audit20 = {
|
|
2827
2813
|
id: "audits/privacy-policy",
|
|
2828
|
-
title: (0,
|
|
2829
|
-
description: (0,
|
|
2814
|
+
title: (0, import_i18n38.__)("Privacy policy", "elementor"),
|
|
2815
|
+
description: (0, import_i18n38.__)(
|
|
2830
2816
|
"A privacy policy page is required by privacy regulations such as GDPR (EU) and CCPA (US).",
|
|
2831
2817
|
"elementor"
|
|
2832
2818
|
),
|
|
2833
|
-
fixHint: (0,
|
|
2819
|
+
fixHint: (0, import_i18n38.__)(
|
|
2834
2820
|
"Go to Settings > Privacy in the WordPress admin and assign a published privacy policy page.",
|
|
2835
2821
|
"elementor"
|
|
2836
2822
|
),
|
|
@@ -2845,10 +2831,10 @@ var audit17 = {
|
|
|
2845
2831
|
status: "fail",
|
|
2846
2832
|
violations: [
|
|
2847
2833
|
{
|
|
2848
|
-
auditId:
|
|
2849
|
-
label: (0,
|
|
2834
|
+
auditId: audit20.id,
|
|
2835
|
+
label: (0, import_i18n38.__)("No privacy policy page is set.", "elementor"),
|
|
2850
2836
|
externalUrl: ctx.pageContext.privacy_settings_url,
|
|
2851
|
-
ctaLabel: (0,
|
|
2837
|
+
ctaLabel: (0, import_i18n38.__)("Create", "elementor")
|
|
2852
2838
|
}
|
|
2853
2839
|
]
|
|
2854
2840
|
};
|
|
@@ -2856,15 +2842,15 @@ var audit17 = {
|
|
|
2856
2842
|
};
|
|
2857
2843
|
|
|
2858
2844
|
// src/audits/robots-noindex.ts
|
|
2859
|
-
var
|
|
2860
|
-
var
|
|
2845
|
+
var import_i18n39 = require("@wordpress/i18n");
|
|
2846
|
+
var audit21 = {
|
|
2861
2847
|
id: "audits/robots-noindex",
|
|
2862
|
-
title: (0,
|
|
2863
|
-
description: (0,
|
|
2848
|
+
title: (0, import_i18n39.__)("Search engine visibility", "elementor"),
|
|
2849
|
+
description: (0, import_i18n39.__)(
|
|
2864
2850
|
"When search engine visibility is checked in WordPress Settings -> Reading -> Search Engine Visibility, search engines are discouraged from indexing the website.",
|
|
2865
2851
|
"elementor"
|
|
2866
2852
|
),
|
|
2867
|
-
fixHint: (0,
|
|
2853
|
+
fixHint: (0, import_i18n39.__)(
|
|
2868
2854
|
'Go to Settings \u2192 Reading in the WordPress admin and uncheck "Discourage search engines from indexing this site" when the website should be indexed.',
|
|
2869
2855
|
"elementor"
|
|
2870
2856
|
),
|
|
@@ -2879,8 +2865,8 @@ var audit18 = {
|
|
|
2879
2865
|
status: "fail",
|
|
2880
2866
|
violations: [
|
|
2881
2867
|
{
|
|
2882
|
-
auditId:
|
|
2883
|
-
label: (0,
|
|
2868
|
+
auditId: audit21.id,
|
|
2869
|
+
label: (0, import_i18n39.__)("Search engines are discouraged from indexing this website.", "elementor"),
|
|
2884
2870
|
externalUrl: ctx.pageContext.reading_settings_url
|
|
2885
2871
|
}
|
|
2886
2872
|
]
|
|
@@ -2889,15 +2875,15 @@ var audit18 = {
|
|
|
2889
2875
|
};
|
|
2890
2876
|
|
|
2891
2877
|
// src/audits/scan-for-cookies.ts
|
|
2892
|
-
var
|
|
2893
|
-
var
|
|
2878
|
+
var import_i18n40 = require("@wordpress/i18n");
|
|
2879
|
+
var audit22 = {
|
|
2894
2880
|
id: "audits/scan-for-cookies",
|
|
2895
|
-
title: (0,
|
|
2896
|
-
description: (0,
|
|
2881
|
+
title: (0, import_i18n40.__)("Scan for cookies", "elementor"),
|
|
2882
|
+
description: (0, import_i18n40.__)(
|
|
2897
2883
|
"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.",
|
|
2898
2884
|
"elementor"
|
|
2899
2885
|
),
|
|
2900
|
-
fixHint: (0,
|
|
2886
|
+
fixHint: (0, import_i18n40.__)("Run a Cookiez scan on this page to see which cookies need disclosure.", "elementor"),
|
|
2901
2887
|
categories: ["compliance"],
|
|
2902
2888
|
severity: "info",
|
|
2903
2889
|
weight: 0,
|
|
@@ -2907,8 +2893,8 @@ var audit19 = {
|
|
|
2907
2893
|
status: "fail",
|
|
2908
2894
|
violations: [
|
|
2909
2895
|
{
|
|
2910
|
-
auditId:
|
|
2911
|
-
label: (0,
|
|
2896
|
+
auditId: audit22.id,
|
|
2897
|
+
label: (0, import_i18n40.__)("This page has not been scanned for cookies yet.", "elementor"),
|
|
2912
2898
|
externalUrl: isReady ? ctx.pageContext.cookiez_scan_url : ctx.pageContext.cookiez_plugin_action_url
|
|
2913
2899
|
}
|
|
2914
2900
|
]
|
|
@@ -2917,29 +2903,29 @@ var audit19 = {
|
|
|
2917
2903
|
};
|
|
2918
2904
|
|
|
2919
2905
|
// src/audits/sections-and-columns.ts
|
|
2920
|
-
var
|
|
2921
|
-
var
|
|
2906
|
+
var import_i18n41 = require("@wordpress/i18n");
|
|
2907
|
+
var audit23 = {
|
|
2922
2908
|
id: "audits/sections-and-columns",
|
|
2923
|
-
title: (0,
|
|
2924
|
-
description: (0,
|
|
2909
|
+
title: (0, import_i18n41.__)("Sections and columns", "elementor"),
|
|
2910
|
+
description: (0, import_i18n41.__)(
|
|
2925
2911
|
"Sections and columns are legacy elements. Containers render fewer DOM nodes and are more flexible.",
|
|
2926
2912
|
"elementor"
|
|
2927
2913
|
),
|
|
2928
|
-
fixHint: (0,
|
|
2914
|
+
fixHint: (0, import_i18n41.__)("Use the Container Converter to replace each section/column with a container.", "elementor"),
|
|
2929
2915
|
categories: ["best-practices", "performance"],
|
|
2930
2916
|
severity: "warning",
|
|
2931
2917
|
weight: 7,
|
|
2932
2918
|
evaluate: (ctx) => {
|
|
2933
2919
|
if (ctx.elements.tree.length === 0) {
|
|
2934
|
-
return { status: "skipped", reason: (0,
|
|
2920
|
+
return { status: "skipped", reason: (0, import_i18n41.__)("No elements", "elementor") };
|
|
2935
2921
|
}
|
|
2936
2922
|
const violations = [];
|
|
2937
2923
|
walkElements(ctx.elements.tree, (node) => {
|
|
2938
2924
|
if (node.elType === "section" || node.elType === "column") {
|
|
2939
2925
|
violations.push({
|
|
2940
|
-
auditId:
|
|
2926
|
+
auditId: audit23.id,
|
|
2941
2927
|
elementId: node.id,
|
|
2942
|
-
label: node.elType === "section" ? (0,
|
|
2928
|
+
label: node.elType === "section" ? (0, import_i18n41.__)("Section element", "elementor") : (0, import_i18n41.__)("Column element", "elementor")
|
|
2943
2929
|
});
|
|
2944
2930
|
}
|
|
2945
2931
|
});
|
|
@@ -2948,15 +2934,15 @@ var audit20 = {
|
|
|
2948
2934
|
};
|
|
2949
2935
|
|
|
2950
2936
|
// src/audits/site-identity.ts
|
|
2951
|
-
var
|
|
2952
|
-
var
|
|
2937
|
+
var import_i18n42 = require("@wordpress/i18n");
|
|
2938
|
+
var audit24 = {
|
|
2953
2939
|
id: "audits/site-identity",
|
|
2954
|
-
title: (0,
|
|
2955
|
-
description: (0,
|
|
2940
|
+
title: (0, import_i18n42.__)("Site identity", "elementor"),
|
|
2941
|
+
description: (0, import_i18n42.__)(
|
|
2956
2942
|
"Site name, description, logo, and favicon establish your brand and appear in search results and browser tabs.",
|
|
2957
2943
|
"elementor"
|
|
2958
2944
|
),
|
|
2959
|
-
fixHint: (0,
|
|
2945
|
+
fixHint: (0, import_i18n42.__)("Open Site Settings \u2192 Site Identity and complete all the missing fields.", "elementor"),
|
|
2960
2946
|
categories: ["best-practices", "seo"],
|
|
2961
2947
|
severity: "info",
|
|
2962
2948
|
weight: 7,
|
|
@@ -2965,30 +2951,30 @@ var audit21 = {
|
|
|
2965
2951
|
const violations = [];
|
|
2966
2952
|
if (!identity.site_name_set) {
|
|
2967
2953
|
violations.push({
|
|
2968
|
-
auditId:
|
|
2969
|
-
label: (0,
|
|
2954
|
+
auditId: audit24.id,
|
|
2955
|
+
label: (0, import_i18n42.__)("Site name is missing or still uses the default.", "elementor"),
|
|
2970
2956
|
targetHint: "site-identity-settings"
|
|
2971
2957
|
});
|
|
2972
2958
|
}
|
|
2973
2959
|
if (!identity.site_description_set) {
|
|
2974
2960
|
violations.push({
|
|
2975
|
-
auditId:
|
|
2976
|
-
label: (0,
|
|
2961
|
+
auditId: audit24.id,
|
|
2962
|
+
label: (0, import_i18n42.__)("Site description is missing or still uses the default.", "elementor"),
|
|
2977
2963
|
targetHint: "site-identity-settings",
|
|
2978
2964
|
angieFix: true
|
|
2979
2965
|
});
|
|
2980
2966
|
}
|
|
2981
2967
|
if (!identity.site_logo_set) {
|
|
2982
2968
|
violations.push({
|
|
2983
|
-
auditId:
|
|
2984
|
-
label: (0,
|
|
2969
|
+
auditId: audit24.id,
|
|
2970
|
+
label: (0, import_i18n42.__)("Site logo is not set.", "elementor"),
|
|
2985
2971
|
targetHint: "site-identity-settings"
|
|
2986
2972
|
});
|
|
2987
2973
|
}
|
|
2988
2974
|
if (!identity.site_favicon_set) {
|
|
2989
2975
|
violations.push({
|
|
2990
|
-
auditId:
|
|
2991
|
-
label: (0,
|
|
2976
|
+
auditId: audit24.id,
|
|
2977
|
+
label: (0, import_i18n42.__)("Site favicon is not set.", "elementor"),
|
|
2992
2978
|
targetHint: "site-identity-settings"
|
|
2993
2979
|
});
|
|
2994
2980
|
}
|
|
@@ -3002,87 +2988,58 @@ var audit21 = {
|
|
|
3002
2988
|
}
|
|
3003
2989
|
};
|
|
3004
2990
|
|
|
3005
|
-
// src/audits/too-many-widgets.ts
|
|
3006
|
-
var import_editor_elements8 = require("@elementor/editor-elements");
|
|
3007
|
-
var import_i18n46 = require("@wordpress/i18n");
|
|
3008
|
-
var WIDGET_COUNT_THRESHOLD = 100;
|
|
3009
|
-
function isCountableWidget(node, widgetsCache) {
|
|
3010
|
-
if (node.elType === "widget") {
|
|
3011
|
-
return true;
|
|
3012
|
-
}
|
|
3013
|
-
return !!widgetsCache?.[node.elType]?.meta?.is_compound;
|
|
3014
|
-
}
|
|
3015
|
-
var audit22 = {
|
|
3016
|
-
id: "audits/too-many-widgets",
|
|
3017
|
-
title: (0, import_i18n46.__)("Too many widgets", "elementor"),
|
|
3018
|
-
description: (0, import_i18n46.__)("Excessive DOM size caused by too many widgets degrades rendering performance.", "elementor"),
|
|
3019
|
-
fixHint: (0, import_i18n46.__)("Reduce the number of widgets on the page by removing or combining elements.", "elementor"),
|
|
3020
|
-
categories: ["best-practices", "performance"],
|
|
3021
|
-
severity: "warning",
|
|
3022
|
-
weight: 5,
|
|
3023
|
-
evaluate: (ctx) => {
|
|
3024
|
-
if (ctx.elements.tree.length === 0) {
|
|
3025
|
-
return { status: "skipped", reason: (0, import_i18n46.__)("No elements", "elementor") };
|
|
3026
|
-
}
|
|
3027
|
-
const widgetsCache = (0, import_editor_elements8.getWidgetsCache)();
|
|
3028
|
-
let widgetCount = 0;
|
|
3029
|
-
walkElements(ctx.elements.tree, (node) => {
|
|
3030
|
-
if (isCountableWidget(node, widgetsCache)) {
|
|
3031
|
-
widgetCount++;
|
|
3032
|
-
}
|
|
3033
|
-
});
|
|
3034
|
-
if (widgetCount <= WIDGET_COUNT_THRESHOLD) {
|
|
3035
|
-
return { status: "pass" };
|
|
3036
|
-
}
|
|
3037
|
-
return {
|
|
3038
|
-
status: "fail",
|
|
3039
|
-
violations: [
|
|
3040
|
-
{
|
|
3041
|
-
auditId: audit22.id,
|
|
3042
|
-
label: (0, import_i18n46.__)("Page has too many widgets.", "elementor")
|
|
3043
|
-
}
|
|
3044
|
-
]
|
|
3045
|
-
};
|
|
3046
|
-
}
|
|
3047
|
-
};
|
|
3048
|
-
|
|
3049
2991
|
// src/register-audits.ts
|
|
3050
2992
|
var AUDITS = [
|
|
3051
|
-
|
|
3052
|
-
audit12,
|
|
3053
|
-
audit13,
|
|
3054
|
-
audit8,
|
|
3055
|
-
audit5,
|
|
3056
|
-
audit22,
|
|
3057
|
-
audit20,
|
|
3058
|
-
audit3,
|
|
3059
|
-
audit11,
|
|
3060
|
-
audit4,
|
|
3061
|
-
audit21,
|
|
2993
|
+
audit17,
|
|
3062
2994
|
audit15,
|
|
3063
2995
|
audit16,
|
|
3064
|
-
audit7,
|
|
3065
|
-
audit9,
|
|
3066
2996
|
audit10,
|
|
2997
|
+
audit7,
|
|
2998
|
+
audit23,
|
|
2999
|
+
audit5,
|
|
3000
|
+
audit14,
|
|
3001
|
+
audit6,
|
|
3002
|
+
audit24,
|
|
3067
3003
|
audit18,
|
|
3068
|
-
|
|
3004
|
+
audit19,
|
|
3005
|
+
audit9,
|
|
3006
|
+
audit11,
|
|
3007
|
+
audit13,
|
|
3008
|
+
audit12,
|
|
3009
|
+
audit21,
|
|
3010
|
+
audit20,
|
|
3069
3011
|
audit,
|
|
3070
3012
|
audit2,
|
|
3071
|
-
|
|
3072
|
-
|
|
3013
|
+
audit3,
|
|
3014
|
+
audit4,
|
|
3015
|
+
audit22,
|
|
3016
|
+
audit8
|
|
3073
3017
|
];
|
|
3074
3018
|
function registerAllAudits() {
|
|
3075
|
-
for (const
|
|
3076
|
-
registerAudit(
|
|
3019
|
+
for (const audit25 of AUDITS) {
|
|
3020
|
+
registerAudit(audit25);
|
|
3077
3021
|
}
|
|
3078
3022
|
}
|
|
3079
3023
|
|
|
3024
|
+
// src/sync-report-staleness.ts
|
|
3025
|
+
var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
|
|
3026
|
+
var import_store6 = require("@elementor/store");
|
|
3027
|
+
function syncReportStaleness() {
|
|
3028
|
+
(0, import_editor_v1_adapters3.__privateListenTo)((0, import_editor_v1_adapters3.commandEndEvent)("document/save/set-is-modified"), (e) => {
|
|
3029
|
+
const event = e;
|
|
3030
|
+
if (event.args?.status) {
|
|
3031
|
+
(0, import_store6.__dispatch)(slice.actions.reportStale());
|
|
3032
|
+
}
|
|
3033
|
+
});
|
|
3034
|
+
}
|
|
3035
|
+
|
|
3080
3036
|
// src/init.ts
|
|
3081
3037
|
function init() {
|
|
3082
|
-
(0,
|
|
3038
|
+
(0, import_store7.__registerSlice)(slice);
|
|
3083
3039
|
registerAllAudits();
|
|
3084
|
-
(0,
|
|
3040
|
+
(0, import_editor_floating_panels6.registerFloatingPanel)(auditPanel.panel);
|
|
3085
3041
|
registerAppBarAuditsToggle();
|
|
3042
|
+
syncReportStaleness();
|
|
3086
3043
|
}
|
|
3087
3044
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3088
3045
|
0 && (module.exports = {
|