PluginProbe
Accessibility Tool Kit: WP Accessibility checker plugin for WCAG, Section 508, ADA, EAA Compliance / trunk
Accessibility Tool Kit: WP Accessibility checker plugin for WCAG, Section 508, ADA, EAA Compliance vtrunk
2.2.1 2.2.0 2.1.2 1.1.1 1.1.2 1.1.3 1.2 1.2.1 1.2.2 1.2.3 1.2.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 trunk 1.0.0 All 31 releases
accessibility-plus / legacy / loader.php

loader.php in Accessibility Tool Kit: WP Accessibility checker plugin for WCAG, Section 508, ADA, EAA Compliance trunk, at legacy/loader.php

368 lines 11.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit;
5 }
6
7 require_once 'inc/simple_html_dom.php';
8
9 // include option
10
11 require_once 'inc/options.php';
12
13 function wya11y_process_html_with_dom( $html, $callback ) {
14 $dom = lhb_str_get_html( $html, false, true, 'UTF-8', false, PHP_EOL, ' ' );
15
16 if ( empty( $dom ) ) {
17 return $html;
18 }
19
20 $callback( $dom );
21
22 $html = $dom->save();
23 return $html;
24 }
25
26 // Name: Form elements do not have associated labels
27 function easywpstuff_assesplus_check_input_labels( $html ) {
28 return wya11y_process_html_with_dom(
29 $html,
30 function( $dom ) {
31 $inputs = $dom->find( 'input' );
32
33 foreach ( $inputs as $input ) {
34 $parent = $input->parent();
35 $previousSibling = $input->previousSibling();
36 $nextSibling = $input->nextSibling();
37
38 // Check if label is a sibling and has the 'for' attribute matching input's 'id'
39 if (
40 ( $previousSibling && $previousSibling->tag === 'label' && $previousSibling->getAttribute( 'for' ) === $input->getAttribute( 'id' ) ) ||
41 ( $nextSibling && $nextSibling->tag === 'label' && $nextSibling->getAttribute( 'for' ) === $input->getAttribute( 'id' ) ) ||
42 ( $parent && $parent->tag === 'label' && $parent->getAttribute( 'for' ) === $input->getAttribute( 'id' ) )
43 ) {
44 continue; // Skip if label with 'for' attribute is found
45 }
46
47 // Check if no descriptive attributes and not in a labeled context
48 if ( ! $input->getAttribute( 'placeholder' ) || ! $input->getAttribute( 'aria-label' ) || ! $input->getAttribute( 'aria-labelledby' ) ) {
49 $inputType = $input->getAttribute( 'type' );
50
51 // Check if input type is not hidden, button, or submit
52 if ( $inputType && ! in_array( $inputType, array( 'hidden', 'button', 'submit' ) ) ) {
53 $input->setAttribute( 'aria-label', $inputType );
54 }
55 }
56 }
57 }
58 );
59 }
60 function wya11y_has_non_empty_text_content( $element ) {
61 $textContent = $element->plaintext;
62 return $textContent !== '' && trim( $textContent ) !== ''; // Check if it's not empty or consists only of whitespace
63 }
64 // Links do not have a discernible name
65 function easywpstuff_assesplus_add_aria_labels_to_links( $html ) {
66 $html = str_replace( '</img>', '', $html );
67 $html = str_replace( '</source>', '', $html );
68
69 return wya11y_process_html_with_dom(
70 $html,
71 function( $dom ) {
72 $links = $dom->find( 'a' );
73
74 foreach ( $links as $link ) {
75 $hasTextContent = false;
76 $hasImageWithNonBlankAlt = false;
77
78 // Check if link or its child elements have text content
79 if ( wya11y_has_non_empty_text_content( $link ) ) {
80 $hasTextContent = true;
81 } else {
82 foreach ( $link->find( '*' ) as $element ) {
83 if ( wya11y_has_non_empty_text_content( $element ) ) {
84 $hasTextContent = true;
85 break;
86 }
87 }
88 }
89
90 // Check if link lacks text content or child with text content, and aria-label attributes
91 if ( ! $hasTextContent && ! $link->getAttribute( 'aria-label' ) && ! $link->getAttribute( 'aria-labelledby' ) ) {
92 foreach ( $link->find( 'img' ) as $imgElement ) {
93 if ( trim( $imgElement->getAttribute( 'alt' ) ) ) {
94 $hasImageWithNonBlankAlt = true;
95 break;
96 }
97 }
98
99 // Exclude links with image children having non-blank alt attribute
100 if ( ! $hasImageWithNonBlankAlt ) {
101 $link->setAttribute( 'aria-label', 'link' );
102 }
103 }
104 }
105 }
106 );
107 }
108
109
110 //Buttons do not have an accessible name
111
112 function easywpstuff_assesplus_add_aria_labels_to_buttons( $html ) {
113
114 return wya11y_process_html_with_dom(
115 $html,
116 function( $dom ) {
117 $buttons = $dom->find( 'button' );
118 foreach ( $buttons as $button ) {
119 if ( ! trim( $button->plaintext ) && ! $button->getattribute( 'aria-label' ) ) {
120 $child_elements = $button->find( '*' );
121 if ( empty( $child_elements ) ) {
122 $button->setattribute( 'aria-label', 'button' );
123 } else {
124 $button->setattribute( 'aria-label', 'button' );
125 }
126 }
127 if ( ! $button->getattribute( 'aria-label' ) ) {
128 $svg = $button->find( 'svg', 0 );
129 $path = $button->find( 'path', 0 );
130 $span = $button->find( 'span', 0 );
131 if ( $svg && $path ) {
132 $button->setattribute( 'aria-label', 'button' );
133 } elseif ( $span ) {
134 $span_text = trim( $span->plaintext );
135 if ( $span_text ) {
136 $button->setattribute( 'aria-label', $span_text );
137 }
138 }
139 }
140 }
141 }
142 );
143 }
144
145 //[user-scalable="no"] is used in the <meta name="viewport"> element or the [maximum-scale] attribute is less than 5.
146 function easywpstuff_assesplus_modify_viewport_meta_tag( $html ) {
147
148 return wya11y_process_html_with_dom(
149 $html,
150 function( $dom ) {
151 $viewport_meta_tag = $dom->find( 'meta[name=viewport]', 0 );
152 if ( $viewport_meta_tag ) {
153 $content = $viewport_meta_tag->getAttribute( 'content' );
154
155 $content = preg_replace( '/,\s*user-scalable=(?:no|0)/', '', $content );
156
157 if ( preg_match( '/maximum-scale=([^,\s]*)/', $content, $matches ) ) {
158
159 $maximum_scale = (float) $matches[1];
160 if ( $maximum_scale < 2 ) {
161 $content = preg_replace( '/maximum-scale=[^,\s]*/', 'maximum-scale=2', $content );
162 }
163 } else {
164 $content .= ', maximum-scale=2';
165 }
166
167 $viewport_meta_tag->setAttribute( 'content', $content );
168 }
169 }
170 );
171 }
172
173
174 function easywpstuff_assesplus_add_aria_labels_to_headers( $html ) {
175 return wya11y_process_html_with_dom(
176 $html,
177 function( $dom ) {
178
179 foreach ( $dom->find( 'div' ) as $div ) {
180 // Check if the div or its children have no plain text
181 if ( empty( trim( $div->plaintext ) ) ) {
182 if ( $div->role == 'link' && ! $div->hasAttribute( 'aria-label' ) ) {
183 $div->setAttribute( 'aria-label', 'link' );
184 }
185 if ( $div->role == 'button' && ! $div->hasAttribute( 'aria-label' ) ) {
186 $div->setAttribute( 'aria-label', 'button' );
187 }
188 if ( $div->role == 'menuitem' && ! $div->hasAttribute( 'aria-label' ) ) {
189 $div->setAttribute( 'aria-label', 'menuitem' );
190 }
191 }
192 }
193 }
194 );
195 }
196
197 // <frame> or <iframe> elements do not have a title
198 function easywpstuff_assesplus_booster_add_to_iframes( $html ) {
199 return wya11y_process_html_with_dom(
200 $html,
201 function( $dom ) {
202
203 foreach ( $dom->find( 'iframe' ) as $iframe ) {
204 if ( ! $iframe->hasAttribute( 'title' ) ) {
205 $iframe->setAttribute( 'title', 'iframe' );
206 }
207 }
208 }
209 );
210 }
211
212 function easywpstuff_assesplus_modify_tabindex_to_zero( $html ) {
213 return wya11y_process_html_with_dom(
214 $html,
215 function( $dom ) {
216
217 foreach ( $dom->find( '*[tabindex]' ) as $element ) {
218 $tabindex = $element->getAttribute( 'tabindex' );
219
220 if ( $tabindex > 0 ) {
221 $element->setAttribute( 'tabindex', '0' );
222 }
223 }
224 }
225 );
226 }
227
228 //Links are not crawlable
229 function easywpstuff_assesplus_addHashToBlankLinks( $html ) {
230 return wya11y_process_html_with_dom(
231 $html,
232 function( $dom ) {
233 $blankLinks = $dom->find( 'a' );
234 foreach ( $blankLinks as $link ) {
235 if ( ! $link->href || $link->href === '' ) {
236 $link->setattribute( 'href', '#' );
237 }
238 if ( ! $link->href || $link->href === 'javascript: void(0);' ) {
239 $link->setattribute( 'href', '#' );
240 }
241 if ( ! $link->href || $link->href === 'javascript:void(0);' ) {
242 $link->setattribute( 'href', '#' );
243 }
244 if ( ! $link->href || $link->href === 'javascript:void(0)' ) {
245 $link->setattribute( 'href', '#' );
246 }
247 }
248 }
249 );
250 }
251
252 //ARIA progressbar elements do not have accessible names.
253 function easywpstuff_assesplus_add_aria_label_to_progressbar( $html ) {
254 // Use Simple HTML DOM to parse the HTML
255 return wya11y_process_html_with_dom(
256 $html,
257 function( $dom ) {
258 foreach ( $dom->find( '[role=progressbar]' ) as $element ) {
259 // Check if the element has aria-label, aria-labelledby or title attribute
260 $has_label = $element->hasAttribute( 'aria-label' ) ||
261 $element->hasAttribute( 'aria-labelledby' ) ||
262 $element->hasAttribute( 'title' );
263 // If the element doesn't have a label, add aria-label="progressbar"
264 if ( ! $has_label || ( empty( $element->getAttribute( 'aria-label' ) ) && empty( $element->getAttribute( 'aria-labelledby' ) ) && empty( $element->getAttribute( 'title' ) ) ) ) {
265 $element->setAttribute( 'aria-label', 'progressbar' );
266 }
267 }
268 }
269 );
270 }
271 //Image elements do not have [alt] attributes
272 function easywpstuff_assesplus_addAltToImg( $html ) {
273 return wya11y_process_html_with_dom(
274 $html,
275 function( $dom ) {
276 $imgs = $dom->find( 'img' );
277 foreach ( $imgs as $img ) {
278 if ( ! $img->alt ) {
279 $alt = '';
280 if ( $img->title ) {
281 $alt = $img->title;
282 } else {
283 $src = $img->src;
284 $alt = basename( $src );
285 $alt = preg_replace( '/\d+/', '', $alt );
286 $alt = preg_replace( '/\.[^.]+$/', '', $alt );
287 $alt = str_replace( '-', ' ', $alt );
288 $alt = str_replace( '_', ' ', $alt );
289 if ( empty( $alt ) || is_numeric( $alt ) ) {
290 $alt = 'image';
291 }
292 }
293 $img->setattribute( 'alt', $alt );
294 }
295 }
296 }
297 );
298 }
299
300 // buffer if option is enabled
301
302 function easywpstuff_assesplus_bstr_template_redirect( $buffer ) {
303 $options = get_option( 'easywpstuff_assesplus_booster_options' );
304
305 if ( $options['easywpstuff_assesplus_booster_field_no_labels'] == 1 ) {
306 $buffer = easywpstuff_assesplus_check_input_labels( $buffer );
307 }
308
309 if ( $options['easywpstuff_assesplus_booster_field_no_accessible_name'] == 1 ) {
310 $buffer = easywpstuff_assesplus_add_aria_labels_to_buttons( $buffer );
311 }
312
313 if ( $options['easywpstuff_assesplus_booster_field_viewport_meta_tag'] == 1 ) {
314 $buffer = easywpstuff_assesplus_modify_viewport_meta_tag( $buffer );
315 }
316
317 if ( $options['easywpstuff_assesplus_booster_field_menuitem_accessible'] == 1 ) {
318 $buffer = easywpstuff_assesplus_add_aria_labels_to_headers( $buffer );
319 }
320
321 if ( $options['easywpstuff_assesplus_booster_field_iframe_title_tag'] == 1 ) {
322 $buffer = easywpstuff_assesplus_booster_add_to_iframes( $buffer );
323 }
324
325 if ( $options['easywpstuff_assesplus_add_aria_label_to_progressbar'] == 1 ) {
326 $buffer = easywpstuff_assesplus_add_aria_label_to_progressbar( $buffer );
327 }
328
329 if ( $options['easywpstuff_assesplus_links_not_crawlable'] == 1 ) {
330 $buffer = easywpstuff_assesplus_addHashToBlankLinks( $buffer );
331 }
332 if ( $options['easywpstuff_assesplus_modify_tabindex_to_zero'] == 1 ) {
333 $buffer = easywpstuff_assesplus_modify_tabindex_to_zero( $buffer );
334 }
335
336 if ( $options['easywpstuff_assesplus_img_donot_alt'] == 1 ) {
337 $buffer = easywpstuff_assesplus_addAltToImg( $buffer );
338 }
339
340 if ( $options['easywpstuff_assesplus_booster_field_no_discernible_name'] == 1 ) {
341 $buffer = easywpstuff_assesplus_add_aria_labels_to_links( $buffer );
342 }
343
344 return $buffer;
345 }
346
347 add_action( 'template_redirect', 'easywpstuff_assesplus_loader', 99 );
348 function easywpstuff_assesplus_loader() {
349
350 ob_start( 'easywpstuff_assesplus_bstr_template_redirect' );
351 }
352
353 // added settings link
354 function easywpstuff_assesplus_bs_settings_link( $links ) {
355 $settings_link = '<a href="' . admin_url( 'options-general.php?page=accessibilityplus' ) . '">' . __( 'Settings', 'accessibility-plus' ) . '</a>';
356 array_unshift( $links, $settings_link );
357 return $links;
358 }
359 add_filter( 'plugin_action_links_' . WY_A11Y_PLUGIN_BASENAME, 'easywpstuff_assesplus_bs_settings_link' );
360
361 // enqueue admin styles on option page
362 function easywpstuff_assesplus_admin_enqueue_plugin_styles( $hook ) {
363 if ( 'settings_page_accessibilityplus' === $hook ) {
364 wp_enqueue_style( 'lhbooster-styles', plugin_dir_url( __FILE__ ) . 'assets/style.css', array(), WY_A11Y_VERSION );
365 }
366 }
367 add_action( 'admin_enqueue_scripts', 'easywpstuff_assesplus_admin_enqueue_plugin_styles' );
368