a11yfix_get_frontend_post_id(), ) ); } add_action( 'wp_enqueue_scripts', 'a11yfix_enqueue_assets' ); /** * Send current page post ID as a response header for crawler fetch requests. * * @return void */ function a11yfix_send_post_id_header() { if ( headers_sent() ) { return; } header( 'X-A11yFix-Page-Type: ' . a11yfix_get_frontend_page_type() ); header( 'X-A11yFix-Post-Id: ' . a11yfix_get_frontend_post_id() ); } add_action( 'send_headers', 'a11yfix_send_post_id_header' ); /** * Register plugin page under Tools. * * @return void */ function a11yfix_register_tools_page() { add_management_page( __( 'A11yFix for WCAG', 'a11yfix-for-wcag' ), __( 'A11yFix for WCAG', 'a11yfix-for-wcag' ), 'manage_options', 'a11yfix', 'a11yfix_render_admin_page' ); } add_action( 'admin_menu', 'a11yfix_register_tools_page' ); /** * Add quick link to open A11yFix page from the Plugins list. * * @param string[] $links Existing plugin action links. * * @return string[] */ function a11yfix_add_plugin_action_link( $links ) { if ( ! current_user_can( 'manage_options' ) ) { return $links; } $open_link = sprintf( '%2$s', esc_url( admin_url( 'tools.php?page=a11yfix' ) ), esc_html__( 'Open plugin', 'a11yfix-for-wcag' ) ); array_unshift( $links, $open_link ); return $links; } add_filter( 'plugin_action_links_' . plugin_basename( A11YFIX_FILE ), 'a11yfix_add_plugin_action_link' ); /** * Enqueue admin assets for the plugin page. * * @param string $hook_suffix Current admin page hook suffix. * * @return void */ function a11yfix_enqueue_admin_assets( $hook_suffix ) { if ( 'tools_page_a11yfix' !== $hook_suffix ) { return; } $script_path = A11YFIX_PATH . 'assets/dist/a11yfix.js'; $style_path = A11YFIX_PATH . 'assets/dist/a11yfix.css'; $script_url = A11YFIX_URL . 'assets/dist/a11yfix.js'; $style_url = A11YFIX_URL . 'assets/dist/a11yfix.css'; $script_ver = file_exists( $script_path ) ? (string) filemtime( $script_path ) : A11YFIX_VERSION; $style_ver = file_exists( $style_path ) ? (string) filemtime( $style_path ) : A11YFIX_VERSION; wp_enqueue_style( 'a11yfix-style', $style_url, array(), $style_ver ); wp_enqueue_script( 'a11yfix-script', $script_url, array( 'wp-i18n' ), $script_ver, true ); wp_localize_script( 'a11yfix-script', 'a11yfixData', array( 'homeUrl' => home_url( '/' ), 'adminUrl' => admin_url(), 'submitSampleUrl' => apply_filters( 'a11yfix_submit_sample_url', A11YFIX_SAMPLE_SUBMIT_SERVER_URL ), 'submitSampleToken' => apply_filters( 'a11yfix_submit_sample_token', A11YFIX_VERSION . '-map-data' ), 'forceShowSubmitSample' => false, // Set to true to show the "View before send" and "Send data" buttons in the rules view for testing purposes, without needing to trigger the conditions that normally show them (e.g. having test results and being in the WP editor mode ) ); wp_set_script_translations( 'a11yfix-script', A11YFIX_TEXT_DOMAIN, A11YFIX_PATH . 'languages' ); /* * Vite bundles all source files into a single JS asset. WordPress's * load_script_textdomain() hashes the *bundle* URL to find the JSON, but * wp i18n make-json generates one JSON per *source* file (different hashes). * As a result, wp_set_script_translations never finds a matching file and * no JS translations are inlined. We work around this by loading every * per-source JSON ourselves and injecting a single setLocaleData() call. */ $locale = function_exists( 'determine_locale' ) ? determine_locale() : get_locale(); $lang_dir = A11YFIX_PATH . 'languages/'; $json_files = glob( $lang_dir . A11YFIX_TEXT_DOMAIN . '-' . $locale . '-*.json' ); if ( ! empty( $json_files ) ) { $merged = array( '' => array( 'domain' => 'messages', 'lang' => $locale, 'plural-forms' => 'nplurals=2; plural=(n != 1);', ), ); foreach ( $json_files as $json_file ) { $raw = file_get_contents( $json_file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents if ( false === $raw ) { continue; } $data = json_decode( $raw, true ); if ( isset( $data['locale_data']['messages'] ) ) { foreach ( $data['locale_data']['messages'] as $msgid => $msgstr ) { if ( '' !== $msgid ) { $merged[ $msgid ] = $msgstr; } } } } if ( count( $merged ) > 1 ) { wp_add_inline_script( 'a11yfix-script', 'window.wp && window.wp.i18n && window.wp.i18n.setLocaleData(' . wp_json_encode( $merged ) . ', ' . wp_json_encode( A11YFIX_TEXT_DOMAIN ) . ');', 'before' ); } } } add_action( 'admin_enqueue_scripts', 'a11yfix_enqueue_admin_assets' ); /** * Render selected A11yFix scripts as ES modules. * * @param string $tag The script tag. * @param string $handle The script handle. * @param string $src The script source. * * @return string */ function a11yfix_mark_module_scripts( $tag, $handle, $src ) { $module_handles = array( 'a11yfix-script', ); if ( ! in_array( $handle, $module_handles, true ) ) { return $tag; } // WordPress builds $tag as: $before_inline . |', // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript -- This rewrites an already enqueued script tag. '', $tag ); } add_filter( 'script_loader_tag', 'a11yfix_mark_module_scripts', 10, 3 ); /** * Render plugin main admin page. * * @return void */ function a11yfix_render_admin_page() { ?>