• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

equalizedigital / accessibility-checker / 28036382587

23 Jun 2026 03:17PM UTC coverage: 59.571% (+0.004%) from 59.567%
28036382587

push

github

web-flow
Merge pull request #1786 from equalizedigital/william/pro-1068-speak-announcement-in-dismiss-panel

a11y: announce dismiss/reopen result to screen readers via speak() (PRO-1068)

0 of 1 new or added line in 1 file covered. (0.0%)

1 existing line in 1 file now uncovered.

5801 of 9738 relevant lines covered (59.57%)

5.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.37
/admin/class-enqueue-admin.php
1
<?php
2
/**
3
 * Class file for Admin enqueueing styles and scripts.
4
 *
5
 * @package Accessibility_Checker
6
 */
7

8
namespace EDAC\Admin;
9

10
use EDAC\Admin\OptIn\Email_Opt_In;
11
use EqualizeDigital\AccessibilityChecker\Admin\IgnoreUI;
12

13
/**
14
 * Class that initializes and handles enqueueing styles and scripts for the admin.
15
 */
16
class Enqueue_Admin {
17

18

19
        /**
20
         * Constructor
21
         */
22
        public function __construct() {
23
        }
40✔
24

25

26
        /**
27
         * Enqueue the scripts and styles.
28
         */
29
        public static function enqueue() {
30
                self::enqueue_styles();
×
31
                self::maybe_enqueue_admin_and_editor_app_scripts();
×
32
                self::maybe_enqueue_sidebar_script();
×
33
                self::maybe_enqueue_issue_modal_script();
×
34
                self::maybe_enqueue_email_opt_in_script();
×
35
        }
36

37
        /**
38
         * Enqueue the admin styles.
39
         *
40
         * @return void
41
         */
42
        public static function enqueue_styles() {
43
                wp_enqueue_style( 'edac', plugin_dir_url( EDAC_PLUGIN_FILE ) . 'build/css/admin.css', [], EDAC_VERSION, 'all' );
×
44
        }
45

46
        /**
47
         * Enqueue the admin and editorApp scripts.
48
         *
49
         * @return void
50
         */
51
        public static function maybe_enqueue_admin_and_editor_app_scripts() {
52

53
                global $pagenow;
22✔
54
                $post_types        = Settings::get_scannable_post_types();
22✔
55
                $has_post_types    = is_array( $post_types ) && count( $post_types );
22✔
56
                $is_scannable_post = Helpers::is_current_post_type_scannable( $post_types );
22✔
57
                $page              = self::get_current_page_slug();
22✔
58
                $enabled_pages     = apply_filters(
22✔
59
                        'edac_filter_admin_scripts_slugs',
22✔
60
                        [
22✔
61
                                'accessibility_checker',
22✔
62
                                'accessibility_checker_settings',
22✔
63
                                'accessibility_checker_issues',
22✔
64
                                'accessibility_checker_ignored',
22✔
65
                        ]
22✔
66
                );
22✔
67

68
                if (
69
                        (
70
                                $has_post_types &&
22✔
71
                                (
22✔
72
                                        $is_scannable_post ||
22✔
73
                                        in_array( $page, $enabled_pages, true )
22✔
74
                                )
22✔
75
                        ) ||
76
                        'site-editor.php' !== $pagenow
22✔
77
                ) {
78

79
                        global $post;
22✔
80
                        $post_id = is_object( $post ) ? $post->ID : null;
22✔
81
                        wp_enqueue_script( 'edac', plugin_dir_url( EDAC_PLUGIN_FILE ) . 'build/admin.bundle.js', [ 'jquery' ], EDAC_VERSION, false );
22✔
82
                        wp_set_script_translations( 'edac', 'accessibility-checker', plugin_dir_path( EDAC_PLUGIN_FILE ) . 'languages' );
22✔
83

84
                        wp_localize_script(
22✔
85
                                'edac',
22✔
86
                                'edac_script_vars',
22✔
87
                                [
22✔
88
                                        'postID'                   => $post_id,
22✔
89
                                        'nonce'                    => wp_create_nonce( 'ajax-nonce' ),
22✔
90
                                        'edacApiUrl'               => esc_url_raw( rest_url( 'accessibility-checker/v1' ) ),
22✔
91
                                        'fixesRestUrl'             => esc_url_raw( rest_url( 'edac/v1' ) ),
22✔
92
                                        'restNonce'                => wp_create_nonce( 'wp_rest' ),
22✔
93
                                        'proUrl'                   => esc_url_raw( edac_generate_link_type( [ 'utm_content' => '__name__' ] ) ),
22✔
94
                                        'hasDismissEndpoint'       => method_exists( \EDAC\Inc\REST_Api::class, 'dismiss_issue' ),
22✔
95
                                        'showMetaboxInBlockEditor' => ! Helpers::is_block_editor() || (bool) get_option( 'edac_show_metabox_in_block_editor', 1 ),
22✔
96
                                ]
22✔
97
                        );
22✔
98

99
                        if ( 'post.php' === $pagenow || 'post-new.php' === $pagenow ) {
22✔
100

101
                                // Is this posttype setup to be checked?
102
                                $active = $is_scannable_post;
10✔
103

104
                                $pro = defined( 'EDACP_VERSION' ) && EDAC_KEY_VALID;
10✔
105

106
                                if ( EDAC_DEBUG || strpos( EDAC_VERSION, '-beta' ) !== false ) {
10✔
107
                                        $debug = true; // @codeCoverageIgnore
108
                                } else {
109
                                        $debug = false;
10✔
110
                                }
111

112
                                wp_enqueue_script( 'edac-editor-app', plugin_dir_url( EDAC_PLUGIN_FILE ) . 'build/editorApp.bundle.js', false, EDAC_VERSION, false );
10✔
113
                                wp_set_script_translations( 'edac-editor-app', 'accessibility-checker', plugin_dir_path( EDAC_PLUGIN_FILE ) . 'languages' );
10✔
114

115
                                // If this is the frontpage or homepage, preview URLs won't work. Use the live URL.
116
                                if ( (int) get_option( 'page_on_front' ) === $post_id || (int) get_option( 'page_for_posts' ) === $post_id ) {
10✔
117
                                        $scan_url = add_query_arg( 'edac_pageScanner', 1, get_permalink( $post_id ) );
4✔
118
                                } else {
119
                                        $post_view_link = apply_filters(
6✔
120
                                                'edac_get_origin_url_for_virtual_page',
6✔
121
                                                get_preview_post_link( $post_id ),
6✔
122
                                                $post_id
6✔
123
                                        );
6✔
124

125
                                        $scan_url = add_query_arg(
6✔
126
                                                [
6✔
127
                                                        'edac_pageScanner' => 1,
6✔
128
                                                ],
6✔
129
                                                $post_view_link
6✔
130
                                        );
6✔
131
                                }
132

133
                                wp_localize_script(
10✔
134
                                        'edac-editor-app',
10✔
135
                                        'edac_editor_app',
10✔
136
                                        [
10✔
137
                                                'postID'        => $post_id,
10✔
138
                                                'edacUrl'       => esc_url_raw( get_site_url() ),
10✔
139
                                                'edacApiUrl'    => esc_url_raw( rest_url( 'accessibility-checker/v1' ) ),
10✔
140
                                                'baseurl'       => plugin_dir_url( __DIR__ ),
10✔
141
                                                'active'        => $active,
10✔
142
                                                'pro'           => $pro,
10✔
143
                                                'debug'         => $debug,
10✔
144
                                                'scanUrl'       => $scan_url,
10✔
145
                                                'maxAltLength'  => max( 1, absint( apply_filters( 'edac_max_alt_length', 300 ) ) ),
10✔
146
                                                'landmarkTypes' => edac_get_landmark_types(),
10✔
147
                                                'version'       => EDAC_VERSION,
10✔
148
                                                'postStatus'    => get_post_status( $post_id ),
10✔
149
                                                'restNonce'     => wp_create_nonce( 'wp_rest' ),
10✔
150
                                        ]
10✔
151
                                );
10✔
152

153
                        }
154
                }
155
        }
156

157
        /**
158
         * Enqueue the Gutenberg sidebar script.
159
         *
160
         * @return void
161
         */
162
        public static function maybe_enqueue_sidebar_script() {
163
                global $pagenow;
6✔
164

165
                // Only load on post edit screens.
166
                if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
6✔
167
                        return;
×
168
                }
169

170
                if ( ! Helpers::is_block_editor() ) {
6✔
171
                        return;
2✔
172
                }
173

174
                // Check if this post type is scannable.
175
                $post_types = Settings::get_scannable_post_types();
4✔
176
                if ( ! Helpers::is_current_post_type_scannable( $post_types ) ) {
4✔
177
                        return;
2✔
178
                }
179

180
                // Enqueue the sidebar script with WordPress dependencies.
181
                wp_enqueue_script(
2✔
182
                        'edac-sidebar',
2✔
183
                        plugin_dir_url( EDAC_PLUGIN_FILE ) . 'build/sidebar.bundle.js',
2✔
184
                        [
2✔
185
                                'wp-plugins',
2✔
186
                                'wp-edit-post',
2✔
187
                                'wp-editor',
2✔
188
                                'wp-element',
2✔
189
                                'wp-data',
2✔
190
                                'wp-i18n',
2✔
191
                                'wp-api-fetch',
2✔
192
                                'wp-components',
2✔
193
                        ],
2✔
194
                        EDAC_VERSION,
2✔
195
                        false
2✔
196
                );
2✔
197

198
                // Set translations for the sidebar.
199
                wp_set_script_translations( 'edac-sidebar', 'accessibility-checker', plugin_dir_path( EDAC_PLUGIN_FILE ) . 'languages' );
2✔
200

201
                // Localize script with necessary data.
202
                wp_localize_script(
2✔
203
                        'edac-sidebar',
2✔
204
                        'edac_sidebar_app',
2✔
205
                        [
2✔
206
                                'gutenbergEnabled'        => true,
2✔
207
                                'postID'                  => get_the_ID(),
2✔
208
                                'highlightNonce'          => wp_create_nonce( 'edac_highlight' ),
2✔
209
                                'ajaxNonce'               => wp_create_nonce( 'ajax-nonce' ),
2✔
210
                                'ajaxUrl'                 => admin_url( 'admin-ajax.php' ),
2✔
211
                                'edacApiUrl'              => esc_url_raw( rest_url() . 'accessibility-checker/v1' ),
2✔
212
                                'settingsUrl'             => esc_url_raw( admin_url( 'admin.php?page=accessibility_checker_settings' ) ),
2✔
213
                                'canManageSettings'       => current_user_can( apply_filters( 'edac_filter_settings_capability', 'manage_options' ) ),
2✔
214
                                'readabilityHelpUrl'      => esc_url_raw( edac_link_wrapper( 'https://a11ychecker.com/help3265', 'wordpress-general', 'content-analysis-sidebar', false ) ),
2✔
215
                                'dismissReasons'          => IgnoreUI::get_reasons(),
2✔
216
                                'simplifiedSummaryPrompt' => get_option( 'edac_simplified_summary_prompt', 'none' ),
2✔
217
                        ]
2✔
218
                );
2✔
219

220
                // Enqueue sidebar styles.
221
                wp_enqueue_style(
2✔
222
                        'edac-sidebar',
2✔
223
                        plugin_dir_url( EDAC_PLUGIN_FILE ) . 'build/css/sidebar.css',
2✔
224
                        [],
2✔
225
                        EDAC_VERSION,
2✔
226
                        'all'
2✔
227
                );
2✔
228

229
                // Enqueue CodeMirror for HTML syntax highlighting in the issue modal.
230
                wp_enqueue_code_editor( [ 'type' => 'text/html' ] );
2✔
231
        }
232

233
        /**
234
         * Enqueue the issue modal bundle (used in sidebar and other admin areas).
235
         *
236
         * @return void
237
         */
238
        public static function maybe_enqueue_issue_modal_script() {
239
                global $pagenow;
×
240

241
                // Only load on post edit screens where the sidebar is active.
242
                if ( 'post.php' !== $pagenow && 'post-new.php' !== $pagenow ) {
×
243
                        return;
×
244
                }
245

246
                // Check if this post type is scannable.
247
                $post_types = Settings::get_scannable_post_types();
×
248
                if ( ! Helpers::is_current_post_type_scannable( $post_types ) ) {
×
249
                        return;
×
250
                }
251

252
                // Enqueue the issue modal script with WordPress dependencies.
253
                wp_enqueue_script(
×
254
                        'edac-issue-modal',
×
255
                        plugin_dir_url( EDAC_PLUGIN_FILE ) . 'build/issueModal.bundle.js',
×
256
                        [
×
257
                                'wp-element',
×
258
                                'wp-components',
×
259
                                'wp-i18n',
×
260
                                'wp-api-fetch',
×
261
                                'wp-html-entities',
×
NEW
262
                                'wp-a11y',
×
263
                        ],
×
264
                        EDAC_VERSION,
×
265
                        true
×
266
                );
×
267

268
                // Set translations for the issue modal.
269
                wp_set_script_translations( 'edac-issue-modal', 'accessibility-checker', plugin_dir_path( EDAC_PLUGIN_FILE ) . 'languages' );
×
270

271
                // Enqueue issue modal styles.
272
                wp_enqueue_style(
×
273
                        'edac-issue-modal',
×
274
                        plugin_dir_url( EDAC_PLUGIN_FILE ) . 'build/css/issueModal.css',
×
275
                        [ 'wp-components' ],
×
276
                        EDAC_VERSION,
×
277
                        'all'
×
278
                );
×
279

280
                // Enqueue CodeMirror for HTML syntax highlighting.
281
                wp_enqueue_code_editor( [ 'type' => 'text/html' ] );
×
282
        }
283

284
        /**
285
         * Enqueue the email opt-in script on the welcome page.
286
         *
287
         * @return void
288
         */
289
        public static function maybe_enqueue_email_opt_in_script() {
290

291
                $page = self::get_current_page_slug();
×
292
                if ( 'accessibility_checker' !== $page ) {
×
293
                        return;
×
294
                }
295

296
                $user_already_opted_in = (bool) get_user_meta( get_current_user_id(), Email_Opt_In::EDAC_USER_OPTIN_META_KEY, true );
×
297
                if ( $user_already_opted_in ) {
×
298
                        return;
×
299
                }
300

301
                $email_opt_in = new Email_Opt_In();
×
302
                $email_opt_in->enqueue_scripts();
×
303
        }
304

305

306
        /**
307
         * Enqueue the screen reader only format script and styles for the block editor.
308
         *
309
         * Loads on post edit screens for scannable post types, and also on the
310
         * Full Site Editor (site-editor.php) where there is no post type context.
311
         *
312
         * @return void
313
         */
314
        public static function maybe_enqueue_sr_only_format(): void {
315
                if ( ! self::should_load_sr_only_format() ) {
12✔
316
                        return;
6✔
317
                }
318

319
                global $pagenow;
6✔
320
                $is_fse = 'site-editor.php' === $pagenow;
6✔
321

322
                wp_enqueue_script(
6✔
323
                        'edac-sr-only-format',
6✔
324
                        plugin_dir_url( EDAC_PLUGIN_FILE ) . 'build/srOnlyFormat.bundle.js',
6✔
325
                        [ 'wp-rich-text', 'wp-block-editor', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-editor', 'wp-api-fetch' ],
6✔
326
                        EDAC_VERSION,
6✔
327
                        false
6✔
328
                );
6✔
329

330
                wp_set_script_translations( 'edac-sr-only-format', 'accessibility-checker', plugin_dir_path( EDAC_PLUGIN_FILE ) . 'languages' );
6✔
331

332
                wp_localize_script(
6✔
333
                        'edac-sr-only-format',
6✔
334
                        'edacSrOnlyFormat',
6✔
335
                        [
6✔
336
                                'showSrTextInEditor' => (bool) get_user_meta( get_current_user_id(), 'show_sr_text_in_editor', true ),
6✔
337
                                'isFSE'              => $is_fse,
6✔
338
                        ]
6✔
339
                );
6✔
340
        }
341

342
        /**
343
         * Inject screen reader only format styles into the block editor iframe.
344
         *
345
         * @param array $editor_settings Default editor settings.
346
         * @return array
347
         */
348
        public static function maybe_inject_sr_only_editor_styles( array $editor_settings ): array {
349
                if ( ! self::should_load_sr_only_format() ) {
×
350
                        return $editor_settings;
×
351
                }
352

353
                $css = self::get_sr_only_editor_styles();
×
354
                if ( '' === $css ) {
×
355
                        return $editor_settings;
×
356
                }
357

358
                if ( ! isset( $editor_settings['styles'] ) || ! is_array( $editor_settings['styles'] ) ) {
×
359
                        $editor_settings['styles'] = [];
×
360
                }
361

362
                if ( get_user_meta( get_current_user_id(), 'show_sr_text_in_editor', true ) ) {
×
363
                        $body_classes = trim( (string) ( $editor_settings['bodyClassName'] ?? '' ) );
×
364
                        if ( false === strpos( " {$body_classes} ", ' sr-only-show-always ' ) ) {
×
365
                                $editor_settings['bodyClassName'] = trim( $body_classes . ' sr-only-show-always' );
×
366
                        }
367
                }
368

369
                $editor_settings['styles'][] = [
×
370
                        'css' => $css,
×
371
                ];
×
372

373
                return $editor_settings;
×
374
        }
375

376
        /**
377
         * Determine whether the screen reader only format assets should load.
378
         *
379
         * Returns true for the post editor on scannable post types, and also
380
         * for the Full Site Editor where there is no post type context.
381
         *
382
         * @return bool
383
         */
384
        private static function should_load_sr_only_format(): bool {
385
                global $pagenow;
12✔
386

387
                $is_post_editor = 'post.php' === $pagenow || 'post-new.php' === $pagenow;
12✔
388
                $is_fse         = 'site-editor.php' === $pagenow;
12✔
389

390
                if ( ! $is_post_editor && ! $is_fse ) {
12✔
391
                        return false;
2✔
392
                }
393

394
                if ( ! Helpers::is_block_editor() ) {
10✔
395
                        return false;
2✔
396
                }
397

398
                // The FSE has no post type context, so always load there.
399
                if ( $is_fse ) {
8✔
400
                        return true;
2✔
401
                }
402

403
                $post_types = Settings::get_scannable_post_types();
6✔
404

405
                return Helpers::is_current_post_type_scannable( $post_types );
6✔
406
        }
407

408
        /**
409
         * Build the CSS that should be injected into the block editor iframe.
410
         *
411
         * @return string
412
         */
413
        private static function get_sr_only_editor_styles(): string {
414
                static $cached_css = null;
×
415

416
                if ( null !== $cached_css ) {
×
417
                        return $cached_css;
×
418
                }
419

420
                $css_file = plugin_dir_path( EDAC_PLUGIN_FILE ) . 'build/css/srOnlyFormat.css';
×
421
                if ( ! file_exists( $css_file ) || ! is_readable( $css_file ) ) {
×
422
                        $cached_css = '';
×
423
                        return $cached_css;
×
424
                }
425

426
                $css = file_get_contents( $css_file ); // phpcs:ignore WordPressVIPMinimum.Performance.FetchingRemoteData.FileGetContentsUnknown -- Reads a local built CSS asset from the plugin directory.
×
427
                if ( false === $css ) {
×
428
                        $cached_css = '';
×
429
                        return $cached_css;
×
430
                }
431

432
                $css .= sprintf(
×
433
                        '
×
434
                        .is-selected .text-format-sr-only:hover:after,
435
                        .is-selected .text-format-sr-only:focus:after {
436
                                content: %s;
437
                        }',
×
438
                        wp_json_encode( __( '* Screen Reader Text', 'accessibility-checker' ) )
×
439
                );
×
440

441
                $cached_css = $css;
×
442
                return $cached_css;
×
443
        }
444

445
        /**
446
         * Gets the current admin page slug.
447
         *
448
         * @since 1.31.0
449
         * @return string|null The current page slug or null if not set.
450
         */
451
        private static function get_current_page_slug(): ?string {
452
                return isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- display only.
22✔
453
        }
454
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc