@elementor/editor-audits 4.4.0-1106 → 4.4.0-1107
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +343 -255
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +340 -252
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/audits/accessibility-statement.ts +39 -0
- package/src/audits/accessibility-widget.ts +41 -0
- package/src/audits/google-consent-mode.ts +4 -7
- package/src/components/violation-cta-button.tsx +3 -2
- package/src/components/violation-row.tsx +13 -4
- package/src/register-audits.ts +4 -0
- package/src/runner.ts +6 -2
- package/src/types.ts +6 -0
- package/src/utils/scan-accessibility-widgets.ts +7 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-audits",
|
|
3
|
-
"version": "4.4.0-
|
|
3
|
+
"version": "4.4.0-1107",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Elementor Team",
|
|
6
6
|
"homepage": "https://elementor.com/",
|
|
@@ -39,21 +39,21 @@
|
|
|
39
39
|
"dev": "tsup --config=../../tsup.dev.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@elementor/editor": "4.4.0-
|
|
43
|
-
"@elementor/editor-mcp": "4.4.0-
|
|
44
|
-
"@elementor/editor-app-bar": "4.4.0-
|
|
45
|
-
"@elementor/editor-elements": "4.4.0-
|
|
46
|
-
"@elementor/editor-floating-panels": "4.4.0-
|
|
47
|
-
"@elementor/editor-notifications": "4.4.0-
|
|
48
|
-
"@elementor/editor-props": "4.4.0-
|
|
49
|
-
"@elementor/editor-styles": "4.4.0-
|
|
50
|
-
"@elementor/editor-v1-adapters": "4.4.0-
|
|
51
|
-
"@elementor/events": "4.4.0-
|
|
52
|
-
"@elementor/http-client": "4.4.0-
|
|
42
|
+
"@elementor/editor": "4.4.0-1107",
|
|
43
|
+
"@elementor/editor-mcp": "4.4.0-1107",
|
|
44
|
+
"@elementor/editor-app-bar": "4.4.0-1107",
|
|
45
|
+
"@elementor/editor-elements": "4.4.0-1107",
|
|
46
|
+
"@elementor/editor-floating-panels": "4.4.0-1107",
|
|
47
|
+
"@elementor/editor-notifications": "4.4.0-1107",
|
|
48
|
+
"@elementor/editor-props": "4.4.0-1107",
|
|
49
|
+
"@elementor/editor-styles": "4.4.0-1107",
|
|
50
|
+
"@elementor/editor-v1-adapters": "4.4.0-1107",
|
|
51
|
+
"@elementor/events": "4.4.0-1107",
|
|
52
|
+
"@elementor/http-client": "4.4.0-1107",
|
|
53
53
|
"@elementor/icons": "~1.77.0",
|
|
54
|
-
"@elementor/locations": "4.4.0-
|
|
55
|
-
"@elementor/session": "4.4.0-
|
|
56
|
-
"@elementor/store": "4.4.0-
|
|
54
|
+
"@elementor/locations": "4.4.0-1107",
|
|
55
|
+
"@elementor/session": "4.4.0-1107",
|
|
56
|
+
"@elementor/store": "4.4.0-1107",
|
|
57
57
|
"@elementor/ui": "1.37.5"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { __ } from '@wordpress/i18n';
|
|
2
|
+
|
|
3
|
+
import { type Audit } from '../types';
|
|
4
|
+
|
|
5
|
+
export const audit: Audit = {
|
|
6
|
+
id: 'audits/accessibility-statement',
|
|
7
|
+
title: __( 'Create an accessibility statement', 'elementor' ),
|
|
8
|
+
description: __(
|
|
9
|
+
'An accessibility statement showcases your efforts to create an inclusive online space, highlighting helpful features and a commitment to accessibility.',
|
|
10
|
+
'elementor'
|
|
11
|
+
),
|
|
12
|
+
fixHint: __( 'Use Ally to create and publish an accessibility statement for your site.', 'elementor' ),
|
|
13
|
+
categories: [ 'accessibility' ],
|
|
14
|
+
severity: 'info',
|
|
15
|
+
weight: 1,
|
|
16
|
+
evaluate: ( ctx ) => {
|
|
17
|
+
const isReady = ctx.pageContext.ally_plugin_active;
|
|
18
|
+
|
|
19
|
+
if ( isReady && ctx.pageContext.ally_accessibility_statement_created ) {
|
|
20
|
+
return { status: 'pass' };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
status: 'fail',
|
|
25
|
+
violations: [
|
|
26
|
+
{
|
|
27
|
+
auditId: audit.id,
|
|
28
|
+
label: __( 'No accessibility statement has been created for this site.', 'elementor' ),
|
|
29
|
+
externalUrl: isReady
|
|
30
|
+
? ctx.pageContext.ally_accessibility_statement_url
|
|
31
|
+
: ctx.pageContext.ally_plugin_url,
|
|
32
|
+
ctaLabel: isReady ? __( 'Create', 'elementor' ) : undefined,
|
|
33
|
+
secondaryCtaLabel: __( 'Learn more', 'elementor' ),
|
|
34
|
+
secondaryCtaUrl: 'https://go.elementor.com/acc-plg-learn-more',
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { __ } from '@wordpress/i18n';
|
|
2
|
+
|
|
3
|
+
import { type Audit } from '../types';
|
|
4
|
+
import { hasAccessibilityWidgetScript } from '../utils/scan-accessibility-widgets';
|
|
5
|
+
|
|
6
|
+
export const audit: Audit = {
|
|
7
|
+
id: 'audits/accessibility-widget',
|
|
8
|
+
title: __( 'Add an accessibility widget', 'elementor' ),
|
|
9
|
+
description: __( 'Make your site more inclusive by adding an accessibility widget.', 'elementor' ),
|
|
10
|
+
fixHint: __( 'Activate Ally’s accessibility widget to give visitors on-page accessibility tools.', 'elementor' ),
|
|
11
|
+
categories: [ 'accessibility' ],
|
|
12
|
+
severity: 'info',
|
|
13
|
+
weight: 1,
|
|
14
|
+
evaluate: ( ctx ) => {
|
|
15
|
+
if ( ! ctx.pageContext.frontend_url ) {
|
|
16
|
+
return { status: 'skipped', reason: __( 'Page is not published.', 'elementor' ) };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if ( ! ctx.renderedHtml ) {
|
|
20
|
+
return { status: 'skipped', reason: __( 'Could not fetch the published page.', 'elementor' ) };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if ( hasAccessibilityWidgetScript( ctx.renderedHtml ) ) {
|
|
24
|
+
return { status: 'pass' };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const isReady = ctx.pageContext.ally_plugin_active;
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
status: 'fail',
|
|
31
|
+
violations: [
|
|
32
|
+
{
|
|
33
|
+
auditId: audit.id,
|
|
34
|
+
label: __( 'No accessibility widget is active on this site.', 'elementor' ),
|
|
35
|
+
externalUrl: isReady ? ctx.pageContext.ally_widget_settings_url : ctx.pageContext.ally_plugin_url,
|
|
36
|
+
ctaLabel: __( 'Activate', 'elementor' ),
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
2
|
|
|
3
3
|
import { type Audit } from '../types';
|
|
4
|
-
import { fetchRenderedHtml } from '../utils/fetch-rendered-html';
|
|
5
4
|
import { hasConsentDefaultCall, hasGoogleTracking } from '../utils/scan-consent-signals';
|
|
6
5
|
|
|
7
6
|
export const audit: Audit = {
|
|
@@ -18,22 +17,20 @@ export const audit: Audit = {
|
|
|
18
17
|
categories: [ 'compliance' ],
|
|
19
18
|
severity: 'warning',
|
|
20
19
|
weight: 1,
|
|
21
|
-
evaluate:
|
|
20
|
+
evaluate: ( ctx ) => {
|
|
22
21
|
if ( ! ctx.pageContext.frontend_url ) {
|
|
23
22
|
return { status: 'skipped', reason: __( 'Page is not published.', 'elementor' ) };
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if ( ! html ) {
|
|
25
|
+
if ( ! ctx.renderedHtml ) {
|
|
29
26
|
return { status: 'skipped', reason: __( 'Could not fetch the published page.', 'elementor' ) };
|
|
30
27
|
}
|
|
31
28
|
|
|
32
|
-
if ( ! hasGoogleTracking(
|
|
29
|
+
if ( ! hasGoogleTracking( ctx.renderedHtml ) ) {
|
|
33
30
|
return { status: 'skipped', reason: __( 'No Google tracking product detected.', 'elementor' ) };
|
|
34
31
|
}
|
|
35
32
|
|
|
36
|
-
if ( hasConsentDefaultCall(
|
|
33
|
+
if ( hasConsentDefaultCall( ctx.renderedHtml ) ) {
|
|
37
34
|
return { status: 'pass' };
|
|
38
35
|
}
|
|
39
36
|
|
|
@@ -4,9 +4,10 @@ import { Button } from '@elementor/ui';
|
|
|
4
4
|
type Props = {
|
|
5
5
|
ctaLabel: string;
|
|
6
6
|
externalUrl: string;
|
|
7
|
+
variant?: 'outlined' | 'text';
|
|
7
8
|
};
|
|
8
9
|
|
|
9
|
-
export default function ViolationCtaButton( { ctaLabel, externalUrl }: Props ) {
|
|
10
|
+
export default function ViolationCtaButton( { ctaLabel, externalUrl, variant = 'outlined' }: Props ) {
|
|
10
11
|
const handleClick = ( event: React.MouseEvent< HTMLButtonElement > ) => {
|
|
11
12
|
event.stopPropagation();
|
|
12
13
|
event.preventDefault();
|
|
@@ -15,7 +16,7 @@ export default function ViolationCtaButton( { ctaLabel, externalUrl }: Props ) {
|
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
return (
|
|
18
|
-
<Button variant=
|
|
19
|
+
<Button variant={ variant } color="secondary" size="small" onClick={ handleClick }>
|
|
19
20
|
{ ctaLabel }
|
|
20
21
|
</Button>
|
|
21
22
|
);
|
|
@@ -164,10 +164,19 @@ export default function ViolationRow( { audit, skipReason, violations }: Props )
|
|
|
164
164
|
/>
|
|
165
165
|
) }
|
|
166
166
|
{ violation.ctaLabel && violation.externalUrl ? (
|
|
167
|
-
<
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
167
|
+
<Box sx={ { display: 'flex', alignItems: 'center', gap: 0.5 } }>
|
|
168
|
+
<ViolationCtaButton
|
|
169
|
+
ctaLabel={ violation.ctaLabel }
|
|
170
|
+
externalUrl={ violation.externalUrl }
|
|
171
|
+
/>
|
|
172
|
+
{ violation.secondaryCtaLabel && violation.secondaryCtaUrl && (
|
|
173
|
+
<ViolationCtaButton
|
|
174
|
+
ctaLabel={ violation.secondaryCtaLabel }
|
|
175
|
+
externalUrl={ violation.secondaryCtaUrl }
|
|
176
|
+
variant="text"
|
|
177
|
+
/>
|
|
178
|
+
) }
|
|
179
|
+
</Box>
|
|
171
180
|
) : (
|
|
172
181
|
<EyeIcon
|
|
173
182
|
className="violation-hover-icon"
|
package/src/register-audits.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as accessibilityPolicy from './audits/accessibility-policy';
|
|
2
|
+
import * as accessibilityStatement from './audits/accessibility-statement';
|
|
3
|
+
import * as accessibilityWidget from './audits/accessibility-widget';
|
|
2
4
|
import * as cookiePolicy from './audits/cookie-policy';
|
|
3
5
|
import * as deepNesting from './audits/deep-nesting';
|
|
4
6
|
import * as defaultDesignSystem from './audits/default-design-system';
|
|
@@ -48,6 +50,8 @@ const AUDITS: Audit[] = [
|
|
|
48
50
|
|
|
49
51
|
privacyPolicy.audit,
|
|
50
52
|
accessibilityPolicy.audit,
|
|
53
|
+
accessibilityStatement.audit,
|
|
54
|
+
accessibilityWidget.audit,
|
|
51
55
|
cookiePolicy.audit,
|
|
52
56
|
scanForCookies.audit,
|
|
53
57
|
googleConsentMode.audit,
|
package/src/runner.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
type PageAuditReport,
|
|
13
13
|
} from './types';
|
|
14
14
|
import { computeReport } from './utils/compute-report';
|
|
15
|
+
import { fetchRenderedHtml } from './utils/fetch-rendered-html';
|
|
15
16
|
import { extractImageSizeRequests } from './utils/page-attachments';
|
|
16
17
|
import { readKitSnapshot } from './utils/read-kit-snapshot';
|
|
17
18
|
import { buildSnapshotTree } from './utils/v1-snapshot';
|
|
@@ -22,9 +23,12 @@ export async function runPageAudit( documentId: number ): Promise< PageAuditRepo
|
|
|
22
23
|
const pageContext = await fetchPageContext( documentId, imageSizeRequests );
|
|
23
24
|
|
|
24
25
|
const elements: ElementsModelSnapshot = { documentId, tree };
|
|
25
|
-
const kit: KitSnapshot = await
|
|
26
|
+
const [ kit, renderedHtml ]: [ KitSnapshot, string | null ] = await Promise.all( [
|
|
27
|
+
readKitSnapshot( pageContext.kit_id ),
|
|
28
|
+
fetchRenderedHtml( pageContext.frontend_url ),
|
|
29
|
+
] );
|
|
26
30
|
|
|
27
|
-
const ctx: AuditContext = { documentId, elements, pageContext, kit };
|
|
31
|
+
const ctx: AuditContext = { documentId, elements, pageContext, kit, renderedHtml };
|
|
28
32
|
const registered = getRegisteredAudits();
|
|
29
33
|
|
|
30
34
|
const auditResults: AuditRun[] = await Promise.all(
|
package/src/types.ts
CHANGED
|
@@ -40,6 +40,8 @@ export type AuditViolation = {
|
|
|
40
40
|
angieFix?: boolean;
|
|
41
41
|
angiePrompt?: string;
|
|
42
42
|
ctaLabel?: string;
|
|
43
|
+
secondaryCtaLabel?: string;
|
|
44
|
+
secondaryCtaUrl?: string;
|
|
43
45
|
};
|
|
44
46
|
|
|
45
47
|
export type PageContextResponse = {
|
|
@@ -66,6 +68,9 @@ export type PageContextResponse = {
|
|
|
66
68
|
privacy_settings_url: string;
|
|
67
69
|
ally_plugin_active: boolean;
|
|
68
70
|
ally_plugin_url: string;
|
|
71
|
+
ally_accessibility_statement_created: boolean;
|
|
72
|
+
ally_accessibility_statement_url: string;
|
|
73
|
+
ally_widget_settings_url: string;
|
|
69
74
|
cookiez_plugin_active: boolean;
|
|
70
75
|
cookiez_plugin_url: string;
|
|
71
76
|
cookiez_plugin_installed: boolean;
|
|
@@ -109,6 +114,7 @@ export type AuditContext = {
|
|
|
109
114
|
elements: ElementsModelSnapshot;
|
|
110
115
|
pageContext: PageContextResponse;
|
|
111
116
|
kit: KitSnapshot;
|
|
117
|
+
renderedHtml: string | null;
|
|
112
118
|
};
|
|
113
119
|
|
|
114
120
|
export type PageAuditReport = {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Script sources of known accessibility widgets. Ally is listed first; append third-party
|
|
2
|
+
// widget script sources here (UserWay, AccessiBe, EqualWeb, etc.) once confirmed.
|
|
3
|
+
const ACCESSIBILITY_WIDGET_SCRIPT_SOURCES = [ 'cdn.elementor.com/a11y/widget.js' ];
|
|
4
|
+
|
|
5
|
+
export function hasAccessibilityWidgetScript( html: string ): boolean {
|
|
6
|
+
return ACCESSIBILITY_WIDGET_SCRIPT_SOURCES.some( ( src ) => html.includes( src ) );
|
|
7
|
+
}
|