(bool) $f['skip_link'],
'skipTarget' => (string) $f['skip_target'],
'labels' => (bool) $f['form_labels'],
'zoom' => (bool) $f['zoom'],
'newWindow' => (string) $f['new_window'],
'tabindex' => (bool) $f['tabindex'],
'lang' => $f['lang_dir'] ? str_replace( '_', '-', get_bloginfo( 'language' ) ) : '',
'dir' => $f['lang_dir'] ? ( is_rtl() ? 'rtl' : 'ltr' ) : '',
'emptySearch' => (bool) $f['empty_search'],
'i18n' => array(
'skip' => __( 'Skip to content', 'ariaccess' ),
'newTab' => __( '(opens in a new tab)', 'ariaccess' ),
'search' => __( 'Search', 'ariaccess' ),
'emptySearch' => __( 'Please type something to search for.', 'ariaccess' ),
),
);
}
/**
* Enqueue the fixes CSS and script.
*/
public static function enqueue() {
$f = AriAccess_Settings::get( 'fixes' );
$css = '.ariaccess-sr{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}';
if ( $f['skip_link'] ) {
$css .= '.ariaccess-skip{position:absolute;left:12px;top:-200px;z-index:2147483647;padding:12px 18px;background:#fff;color:#111;font:600 16px/1.2 system-ui,sans-serif;border:3px solid #111;border-radius:6px;text-decoration:underline}.ariaccess-skip:focus{top:12px;outline:3px solid ' . esc_attr( $f['focus_color'] ) . ';outline-offset:2px}';
}
if ( $f['focus_outline'] ) {
$css .= ':where(a,button,input,select,textarea,summary,[tabindex],[contenteditable]):focus-visible{outline:3px solid ' . esc_attr( $f['focus_color'] ) . '!important;outline-offset:2px!important;box-shadow:0 0 0 5px #fff!important}';
}
if ( $f['underline_links'] ) {
$css .= ':where(.entry-content,.wp-block-post-content,.post-content,article) p a,:where(.entry-content,.wp-block-post-content,.post-content,article) li a{text-decoration:underline!important;text-underline-offset:.15em}';
}
if ( $f['reduced_motion'] ) {
$css .= '@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}}';
}
if ( $f['empty_search'] ) {
$css .= '.ariaccess-search-error{display:block;margin:.4em 0;padding:.4em .6em;background:#fff;color:#b00020;border-left:4px solid #b00020;font-weight:600}';
}
wp_register_style( 'ariaccess-fixes', false, array(), ARIACCESS_VERSION );
wp_enqueue_style( 'ariaccess-fixes' );
wp_add_inline_style( 'ariaccess-fixes', $css );
$needs_js = $f['skip_link'] || $f['form_labels'] || $f['zoom'] || 'off' !== $f['new_window'] || $f['tabindex'] || $f['lang_dir'] || $f['empty_search'];
if ( $needs_js ) {
wp_enqueue_script( 'ariaccess-fixes', ARIACCESS_URL . 'assets/js/fixes.js', array(), ARIACCESS_VERSION, array( 'strategy' => 'defer', 'in_footer' => true ) );
wp_add_inline_script( 'ariaccess-fixes', 'window.ariaccessFixes=' . wp_json_encode( self::js_config() ) . ';', 'before' );
}
}
/**
* Print the skip link at the top of the body.
*/
public static function skip_link() {
$target = (string) AriAccess_Settings::get( 'fixes', 'skip_target' );
$href = ( '' !== $target && '#' === $target[0] && preg_match( '/^#[\w-]+$/', $target ) ) ? $target : '#main';
printf( '%s', esc_attr( $href ), esc_html__( 'Skip to content', 'ariaccess' ) );
}
/**
* Fill missing or empty alt text on library images from the Media Library.
*
* The block editor copies alt text into the post when an image is inserted, so alt text
* added to the Media Library later never reaches older posts. This fills the gap.
*
* @param string $html Content.
* @return string
*/
public static function fill_media_alt( $html ) {
if ( false === strpos( (string) $html, 'wp-image-' ) ) {
return $html;
}
return preg_replace_callback(
'/
]*>/i',
function ( $m ) {
$tag = $m[0];
if ( ! preg_match( '/\bwp-image-(\d+)\b/', $tag, $id ) ) {
return $tag;
}
if ( preg_match( '/\brole=["\'](presentation|none)["\']|\baria-hidden=["\']true["\']/i', $tag ) ) {
return $tag;
}
$has_alt = preg_match( '/\salt=(["\'])(.*?)\1/is', $tag, $alt );
if ( $has_alt && '' !== trim( $alt[2] ) ) {
return $tag;
}
$library = trim( (string) get_post_meta( (int) $id[1], '_wp_attachment_image_alt', true ) );
if ( '' === $library ) {
return $tag;
}
$attr = 'alt="' . esc_attr( $library ) . '"';
if ( $has_alt ) {
return preg_replace( '/\salt=(["\'])(.*?)\1/is', $attr, $tag, 1 );
}
return preg_replace( '/^
]*?)\s+title=(["\']).*?\2/i', '$1', (string) $html );
return preg_replace_callback(
'/]*?)\s+title=(["\'])(.*?)\2([^>]*)>(.*?)<\/a>/is',
function ( $m ) {
$title = trim( wp_strip_all_tags( html_entity_decode( $m[3], ENT_QUOTES, 'UTF-8' ) ) );
$text = trim( wp_strip_all_tags( html_entity_decode( $m[5], ENT_QUOTES, 'UTF-8' ) ) );
if ( '' !== $text && 0 === strcasecmp( $title, $text ) ) {
return '' . $m[5] . '';
}
return $m[0];
},
$html
);
}
/**
* Tag clouds: the count tooltip duplicates the aria-label.
*
* @param array $tags Tag data.
* @return array
*/
public static function tag_cloud( $tags ) {
foreach ( $tags as &$tag ) {
$tag['title'] = '';
}
return $tags;
}
/**
* Remove target="_blank" from content links.
*
* @param string $html Content.
* @return string
*/
public static function remove_targets( $html ) {
return preg_replace( '/(]*?)\s+target=(["\'])_blank\2/i', '$1', (string) $html );
}
/**
* "Read more" link with the post title for screen readers.
*
* @param string $link Link HTML.
* @return string
*/
public static function more_link( $link ) {
if ( AriAccess_Checker::$rendering || false !== strpos( $link, 'ariaccess-sr' ) || false !== strpos( $link, 'screen-reader-text' ) ) {
return $link;
}
$title = get_the_title();
if ( '' === $title ) {
return $link;
}
return preg_replace( '/<\/a>/', ': ' . esc_html( wp_strip_all_tags( $title ) ) . '', $link, 1 );
}
/**
* Excerpt "more" links with context.
*
* @param string $more More text/link.
* @return string
*/
public static function excerpt_more( $more ) {
if ( false === strpos( (string) $more, '' ) ) {
return $more;
}
return self::more_link( $more );
}
/**
* Search forms without a label get one.
*
* @param string $form Form HTML.
* @return string
*/
public static function search_form( $form ) {
if ( false !== stripos( $form, '