plugin_name = $plugin_name; $this->version = $version; add_action('wp_enqueue_scripts', [$this, 'enqueue_scripts']); add_action('wp_head', [$this, 'output_inline_css']); add_action('wp_head', [$this, 'add_structured_data'], 20); add_action('wp_footer', [$this, 'render_widget']); add_action('wp_footer', [$this, 'render_skip_links'], 5); add_filter('body_class', [$this, 'filter_body_class']); add_filter('theme_page_templates', [$this, 'add_plugin_page_template']); add_filter('template_include', [$this, 'load_plugin_page_template']); } private function legacy_enabled() { $adv = get_option('ability_a11y_settings', []); return !empty($adv['enable_legacy_toolbar']); } private function presentation_mode(): string { $adv = get_option('ability_a11y_settings', []); $mode = isset($adv['presentation_mode']) ? sanitize_key($adv['presentation_mode']) : 'classic'; return in_array($mode, ['classic', 'modern'], true) ? $mode : 'classic'; } public function filter_body_class(array $classes): array { $mode = $this->presentation_mode(); $classes[] = 'ability-presentation-mode-' . $mode; $classes[] = 'ability-' . ($mode === 'modern' ? 'modern-contrast' : 'classic-mode'); return array_values(array_unique($classes)); } public function enqueue_scripts() { if (is_admin()) return; if ($this->legacy_enabled()) return; $settings = class_exists('ABILITY\\Config') ? \ABILITY\Config::get_settings() : []; $enabled = !empty($settings['widget_enabled']) || !empty($settings['frontend_widget_enabled']); if (!$enabled) return; wp_enqueue_style('ability-widget', ABILITY_URL . 'assets/css/frontend.css', [], $this->version); wp_enqueue_script('ability-widget', ABILITY_URL . 'assets/js/frontend.js', ['jquery'], $this->version, true); $adv = get_option('ability_a11y_settings', []); $widget_position = isset($adv['widget_position']) ? $adv['widget_position'] : 'top_right'; $mobile_position = isset($adv['widget_position_mobile']) ? $adv['widget_position_mobile'] : 'bottom_right'; $presentation_mode = $this->presentation_mode(); // Prefer local Comic Sans font file if present; no external CDN is used by the plugin. // Check for multiple formats in order of preference (woff2 > woff > ttf > otf). $dyslexia_font_url = ''; $font_formats = ['woff2', 'woff', 'ttf', 'otf']; $font_name = 'ComicSansMS-Regular'; foreach ($font_formats as $format) { $local_font_path = ABILITY_PATH . 'assets/fonts/' . $font_name . '.' . $format; if (file_exists($local_font_path)) { $dyslexia_font_url = ABILITY_URL . 'assets/fonts/' . $font_name . '.' . $format; break; } } $l10n = [ 'toggleOff' => __('Off', 'ability'), 'toggleOn' => __('On', 'ability'), 'reportAlert' => __('Accessibility heuristic report generated. A JSON file download should begin.', 'ability'), 'reportFileName' => 'accessibility-report.json', 'dialogLabel' => __('Accessibility Options', 'ability'), 'closePanel' => __('Close accessibility panel', 'ability'), 'escToClose' => __('Press Escape to close the accessibility panel', 'ability'), 'announcePageLoad' => __('Page loaded successfully', 'ability'), 'keyboardNotice' => __('Keyboard navigation enabled', 'ability'), 'reportGeneration' => __('Generating accessibility heuristic report', 'ability'), 'dyslexiaFontUrl' => $dyslexia_font_url, 'toolVersion' => $this->version, 'presentationMode' => $presentation_mode, 'widgetPosition' => $widget_position, 'widgetPositionMobile' => $mobile_position, ]; wp_localize_script('ability-widget', 'DWSAccessibilityL10n', $l10n); wp_localize_script('ability-widget', 'AbilityA11yL10n', $l10n); $this->inject_visibility_and_initial_state_scripts(); } private function inject_visibility_and_initial_state_scripts() { if ($this->legacy_enabled()) return; $adv = get_option('ability_a11y_settings', []); $hidden = []; if (!empty($adv['show_controls'])) { foreach ($adv['show_controls'] as $id => $show) { if (!$show) $hidden[] = $id; } } $hideScript = ''; if ($hidden) { $hideScript .= 'document.addEventListener("DOMContentLoaded",function(){'; foreach ($hidden as $hid) { if ('font-size-controls' === $hid) { $hideScript .= 'var g=document.getElementById("increase-font");if(g){var p=g.closest(".control-group");if(p)p.style.display="none";}'; } else { $hideScript .= 'var b=document.getElementById("'.esc_js($hid).'");if(b){var p=b.closest(".control-group");if(p)p.style.display="none";}'; } } $hideScript .= '});'; } $states_json = wp_json_encode($adv['default_states'] ?? []); $scale = isset($adv['initial_font_scale']) ? esc_js($adv['initial_font_scale']) : '1.0'; $initScript = <<legacy_enabled()) return; $settings = class_exists('ABILITY\\Config') ? \ABILITY\Config::get_settings() : []; $enabled = !empty($settings['widget_enabled']) || !empty($settings['frontend_widget_enabled']); if (!$enabled) return; $adv = get_option('ability_a11y_settings', []); ?> legacy_enabled()) return; $adv = get_option('ability_a11y_settings', []); if (empty($adv['enable_structured_data'])) return; if (!is_front_page()) return; // Keep default metadata factual and site-neutral. Accessibility/conformance // properties can be added by a site owner only after they have verified // those claims for the actual site. $data = [ '@context' => 'https://schema.org', '@type' => 'WebSite', 'name' => get_bloginfo('name'), 'description' => get_bloginfo('description'), 'url' => home_url(), ]; $data = apply_filters('ability_accessibility_structured_data', $data); if (!is_array($data) || empty($data)) return; echo '' . "\n"; } public function render_skip_links() { if (is_admin()) return; if ($this->legacy_enabled()) return; $adv = get_option('ability_a11y_settings', []); if ('footer' !== ($adv['skip_links_position'] ?? 'body_open')) return; $main_id = !empty($adv['skip_link_main_id']) ? esc_attr($adv['skip_link_main_id']) : 'main-content'; $nav_id = !empty($adv['skip_link_nav_id']) ? esc_attr($adv['skip_link_nav_id']) : 'navigation'; $footer_id = !empty($adv['skip_link_footer_id']) ? esc_attr($adv['skip_link_footer_id']) : 'footer'; if (apply_filters('ability_accessibility_render_skip_links', true)) : ?> legacy_enabled()) return; static $rendered = false; if ($rendered) return; $rendered = true; $settings = class_exists('ABILITY\\Config') ? \ABILITY\Config::get_settings() : []; $enabled = !empty($settings['widget_enabled']) || !empty($settings['frontend_widget_enabled']); if (!$enabled) return; $adv = get_option('ability_a11y_settings', []); $widget_position = isset($adv['widget_position']) ? $adv['widget_position'] : 'top_right'; $mobile_position = isset($adv['widget_position_mobile']) ? $adv['widget_position_mobile'] : 'bottom_right'; $show_branding = isset($adv['panel_show_branding']) ? (bool) $adv['panel_show_branding'] : true; $custom_brand_text = isset($adv['panel_brand_text']) ? $adv['panel_brand_text'] : ''; $statement_url = ''; $page_id = (int) get_option('ability_a11y_statement_page_id', 0); if ($page_id && 'publish' === get_post_status($page_id)) { $permalink = get_permalink($page_id); if ($permalink) $statement_url = $permalink; } ?>