1(function( $ ) { 'use strict'; 2 var html = document.querySelector( 'html' ); 3 var errors = []; 4 if ( wpa.lang ) { 5 var lang = html.getAttribute( 'lang' ); 6 if ( ! lang ) { 7 $('html').attr( 'lang', wpa.lang ); 8 if ( wpa.errors || wpa.tracking ) { 9 errors.push( 'html-lang' ); 10 console.log( 'HTML language set by WP Accessibility' ); 11 } 12 } 13 } 14 15 if ( wpa.dir ) { 16 var dir = html.getAttribute( 'dir' ); 17 if ( ! dir ) { 18 $('html').attr( 'dir', wpa.dir ); 19 if ( wpa.errors || wpa.tracking ) { 20 errors.push( 'html-lang-direction' ); 21 console.log( 'HTML language direction set by WP Accessibility' ); 22 } 23 } 24 } 25 26 var viewport = document.querySelector( 'meta[name="viewport"]' ); 27 if ( viewport ) { 28 var conditionsBefore = viewport.getAttribute( 'content' ); 29 var conditionsAfter = viewport.getAttribute( 'content' ); 30 if ( conditionsBefore.search(/user-scalable=no/g) ) { 31 conditionsAfter = conditionsBefore.replace( 'user-scalable=no', 'user-scalable=yes' ); 32 viewport.setAttribute( 'content', conditionsAfter ); 33 if ( ( wpa.errors || wpa.tracking ) && conditionsAfter != conditionsBefore ) { 34 errors.push( 'viewport-scalable' ); 35 console.log( 'Viewport made scalable by WP Accessibility' ); 36 } 37 } 38 if ( conditionsBefore.search(/maximum-scale=1/g) ) { 39 conditionsAfter = conditionsBefore.replace( 'maximum-scale=1', 'maximum-scale=5' ); 40 conditionsAfter = conditionsAfter.replace( 'maximum-scale=0', 'maximum-scale=5' ); 41 viewport.setAttribute( 'content', conditionsAfter ); 42 if ( ( wpa.errors || wpa.tracking ) && conditionsAfter != conditionsBefore ) { 43 errors.push( 'viewport-maxscale' ); 44 console.log( 'Viewport maximum scale set by WP Accessibility' ); 45 } 46 } 47 } 48 49 if ( wpa.skiplinks.enabled ) { 50 $('body').prepend( wpa.skiplinks.output ); 51 if ( wpa.errors || wpa.tracking ) { 52 errors.push( 'skiplinks' ); 53 console.log( 'Skip links added by WP Accessibility' ); 54 } 55 } 56 57 if ( wpa.current ) { 58 $(function() { 59 $( '.current-menu-item a, .current_page_item a' ).attr( 'aria-current', 'page' ); 60 }); 61 if ( wpa.errors || wpa.tracking ) { 62 errors.push( 'aria-current' ); 63 console.log( 'ARIA current added by WP Accessibility' ); 64 } 65 } 66 67 if ( wpa.labels ) { 68 var wpa_names = [ 's', 'author', 'email', 'url', 'comment' ]; 69 $.each( wpa_names, function( index, value ) { 70 if ( value == 'comment' ) { 71 var field = $( 'textarea[name=' + value + ']' ); 72 } else { 73 var field = $( 'input[name=' + value + ']' ).not( '#adminbar-search' ); 74 } 75 if ( 0 !== field.length ) { 76 var field_id = field.attr( 'id' ); 77 var implicit = $( field ).parent( 'label' ); 78 var aria = $( field ).attr( 'aria-label' ); 79 var ariaId = $( field ).attr( 'aria-labelledby' ); 80 var ariaTarget = {}; 81 if ( ariaId ) { 82 ariaTarget = $( '#' + ariaId ); 83 } 84 var hasAria = ( '' == aria || 'undefined' == typeof( aria ) ) ? false : true; 85 var hasAriaId = ( '' == ariaId || 'undefined' == typeof( ariaId ) ) ? false : true; 86 // Add label if aria label empty, aria labelledby empty, or aria reference ID does not exist. 87 if ( ( ! hasAria && ! hasAriaId ) || ( ! hasAria && ( hasAriaId && 0 === ariaTarget.length ) ) ) { 88 if ( field_id ) { 89 var label = $( 'label[for=' + field_id + ']' ); 90 if ( !label.length && !implicit.length ) { 91 field.before( "<label for='" + field_id + "' class='wpa-screen-reader-text'>" + wpa.wpalabels[value] + "</label>" ); 92 if ( wpa.errors || wpa.tracking ) { 93 errors.push( ['explicit-label', wpa.wpalabels[value]] ); 94 console.log( 'Explicit label on ' + wpa.wpalabels[value] + 'added by WP Accessibility' ); 95 } 96 } 97 } else { 98 if ( !implicit.length ) { 99 field.attr( 'id', 'wpa_label_' + value ).before( "<label for='wpa_label_" + value + "' class='wpa-screen-reader-text'>" + wpa.wpalabels[value] + "</label>" ); 100 if ( wpa.errors || wpa.tracking ) { 101 errors.push( ['implicit-label', wpa.wpalabels[value]] ); 102 console.log( 'Implicit label on ' + wpa.wpalabels[value] + 'added by WP Accessibility' ); 103 } 104 } 105 } 106 } 107 } 108 }); 109 } 110 111 if ( wpa.titles ) { 112 var images = 0; 113 var controls = 0; 114 var fields = 0; 115 const els = document.querySelectorAll( 'img, a, input, textarea, select, button' );
116 els.forEach((el) => { 117 var title = el.getAttribute( 'title' ); 118 if ( title && '' !== title ) { 119 switch ( el.tagName ) { 120 case 'IMG': 121 // If image has alt, remove title. If not, set title as alt. 122 var alt = el.getAttribute( 'alt' ); 123 if ( ! alt || '' === alt ) { 124 el.setAttribute( 'alt', title ); 125 el.removeAttribute( 'title' ); 126 } else { 127 el.removeAttribute( 'title' ); 128 } 129 images++; 130 break; 131 case 'A': 132 case 'BUTTON': 133 // If link or button has contained text or an img with alt, remove title. Otherwise, set title as aria-label unless element already has aria-label. 134 var linkText = wpaElementText(el); 135 if ( ! linkText || '' === linkText ) { 136 var ariaLabel = el.getAttribute( 'aria-label' ); 137 if ( ! ariaLabel || '' === ariaLabel ) { 138 el.setAttribute( 'aria-label', title ); 139 el.removeAttribute( 'title' ); 140 } 141 } else { 142 el.removeAttribute( 'title' ); 143 } 144 controls++; 145 break; 146 case 'INPUT': 147 case 'SELECT': 148 case 'TEXTAREA': 149 // If input field has an aria-label, aria-labelledby, associated label, or wrapping label, remove title. Else, add title as aria-label. 150 var ariaLabel = el.getAttribute( 'aria-label' ); 151 var ariaLabelled = el.getAttribute( 'aria-labelledby' ); 152 var ariaLabeller = ( ariaLabelled ) ? document.getElementById( ariaLabelled ) : false; 153 var labelId = el.getAttribute( 'id' ); 154 var label = ( labelId ) ? document.querySelector( 'label[for="' + labelId + '"]' ) : false; 155 var parentLabel = el.closest( 'label' ); 156 var hasAriaLabel = ( ariaLabel && '' !== ariaLabel ) ? true : false; 157 var hasRealLabel = ( label && '' !== wpaElementText( label ) ) ? true : false; 158 var hasImplicitLabel = ( parentLabel && '' !== wpaElementText( parentLabel ) ) ? true : false; 159 var hasAriaLabelled = ( ariaLabeller && '' !== wpaElementText( arialabeller ) ) ? true : false; 160 if ( hasAriaLabel || hasRealLabel || hasImplicitLabel || hasAriaLabelled ) { 161 // This has a label. 162 el.removeAttribute( 'title' ); 163 } else { 164 el.setAttribute( 'aria-label', title ); 165 el.removeAttribute( 'title' ); 166 } 167 fields++; 168 break; 169 } 170 } 171 }); 172 if ( wpa.errors || wpa.tracking ) { 173 if ( images > 0 ) { 174 errors.push( ['images-titles', images] ); 175 console.log( images + ' title attributes removed from images by WP Accessibility' ); 176 } 177 if ( controls > 0 ) { 178 errors.push( ['control-titles', controls] ); 179 console.log( controls + ' title attributes removed from links and buttons by WP Accessibility' ); 180 } 181 if ( fields > 0 ) { 182 errors.push( ['input-titles', fields] ); 183 console.log( fields + ' title attributes removed from input fields by WP Accessibility' ); 184 } 185 } 186 } 187 188 if ( wpa.target ) { 189 var targeted = $('a:not(.wpa-allow-target)'); 190 var targetRemoved = 0; 191 targeted.each( function() { 192 var target = $( this ).attr( 'target' ); 193 if ( target ) { 194 $( this ).removeAttr( 'target' ); 195 targetRemoved++; 196 } 197 }); 198 if ( targetRemoved > 0 && ( wpa.errors || wpa.tracking ) ) { 199 errors.push( ['link-targets', targetRemoved] ); 200 console.log( targetRemoved + ' target attributes removed from links by WP Accessibility' ); 201 } 202 } 203 204 if ( wpa.tabindex ) { 205 // Remove tabindex from elements that should be natively focusable. 206 var focusable = $('input,a,select,textarea,button').not('a:not([href])'); 207 var tabRemoved = 0; 208 focusable.each( function() { 209 var tabindex = $( this ).attr( 'tabindex' ); 210 if ( tabindex ) { 211 $( this ).removeAttr('tabindex'); 212 tabRemoved++; 213 } 214 }); 215 216 if ( tabRemoved > 0 && ( wpa.errors || wpa.tracking ) ) { 217 errors.push( ['control-tabindex', tabRemoved] ); 218 console.log( tabRemoved + ' tabindex attributes removed from links, buttons and inputs by WP Accessibility' ); 219 } 220 221 // Add tabindex to elements that appear active but are not natively focusable. 222 var fakeButtons = $('div[role="button"]').not('div[tabindex]' ); 223 var buttonLinks = $('a[role="button"]').not('a[tabindex],a[href]'); 224 fakeButtons.attr( 'tabindex', '0' ).addClass('wpa-focusable'); 225 if ( fakeButtons.length > 0 && ( wpa.errors || wpa.tracking ) ) { 226 errors.push( ['button-add-tabindex', fakeButtons.length] );
227 console.log( fakeButtons.length + ' tabindex attributes added to divs with the button role by WP Accessibility' ); 228 } 229 buttonLinks.attr( 'tabindex', '0' ).addClass('wpa-focusable'); 230 if ( buttonLinks.length > 0 && ( wpa.errors || wpa.tracking ) ) { 231 errors.push( ['link-add-tabindex', buttonLinks.length] ); 232 console.log( buttonLinks.length + ' tabindex attributes added to anchor elements with the button role and no href value by WP Accessibility' ); 233 } 234 } 235 var fingerprint = new Fingerprint().get(); 236 237 // If stats are disabled, skip this. 238 if ( 'disabled' !== wpa.url ) { 239 $('.toggle-contrast').on('click', function (e) { 240 // This fires after the contrast change happens, and the ID is already changed. 241 if ($(this).attr('id') == "is_normal_contrast") { 242 // high contrast turned on. 243 var event = {'contrast' : 'disabled'}; 244 } else { 245 // high contrast turned off. 246 var event = {'contrast' : 'enabled'}; 247 } 248 var data = { 249 'action' : wpa.action, 250 'security' : wpa.security, 251 'stats' : event, 252 'post_id' : wpa.post_id, 253 'title' : fingerprint, 254 'type' : 'event' 255 }; 256 $.post( wpa.ajaxurl, data, function () {}, "json" ); 257 }); 258 259 $('.toggle-fontsize').on('click', function (e) { 260 // This fires after the fontsize change happens, and the ID is already changed. 261 if ($(this).attr('id') == "is_normal_fontsize") { 262 // fontsizes turned on. 263 var event = {'fontsize' : 'disabled'}; 264 } else { 265 // fontsizes turned off. 266 var event = {'fontsize' : 'enabled'}; 267 } 268 var data = { 269 'action' : wpa.action, 270 'security' : wpa.security, 271 'stats' : event, 272 'post_id' : wpa.post_id, 273 'title' : fingerprint, 274 'type' : 'event' 275 }; 276 $.post( wpa.ajaxurl, data, function () {}, "json" ); 277 }); 278 279 waitForElement('.wpa-ld button').then((elm) => { 280 $('.wpa-ld button').on( 'click', function(e) { 281 // For descriptions, we aren't concerned about state changes; just usage. 282 var visible = ( 'true' === $( this ).attr( 'aria-expanded' ) ) ? true : false; 283 if ( visible ) { 284 var img = $( this ).parent( 'div' ); 285 var image_id = img.attr( 'class' ).replace( 'wpa-ld wp-image-', '' ); 286 var event = { 'longdesc' : image_id }; 287 var data = { 288 'action' : wpa.action, 289 'security' : wpa.security, 290 'stats' : event, 291 'post_id' : wpa.post_id, 292 'title' : fingerprint, 293 'type' : 'event' 294 }; 295 $.post( wpa.ajaxurl, data, function (response) { console.log( response ); }, "json" ); 296 } 297 }); 298 }); 299 300 $('.wpa-alt button').on( 'click', function(e) { 301 // For alt text, we aren't concerned about state changes; just usage. 302 var visible = ( 'true' === $( this ).attr( 'aria-expanded' ) ) ? true : false; 303 if ( visible ) { 304 var img = $( this ).parent( 'div' ); 305 console.log( img ); 306 var image_id = img.attr( 'class' ).replace( 'wpa-alt wp-image-', '' ); 307 var event = { 'alttext' : image_id }; 308 var data = { 309 'action' : wpa.action, 310 'security' : wpa.security, 311 'stats' : event, 312 'post_id' : wpa.post_id, 313 'title' : fingerprint, 314 'type' : 'event' 315 }; 316 $.post( wpa.ajaxurl, data, function (response) { console.log( response ); }, "json" ); 317 } 318 }); 319 320 if ( wpa.tracking && errors.length >= 1 ) { 321 var data = { 322 'action' : wpa.action, 323 'security' : wpa.security, 324 'stats' : errors, 325 'post_id' : wpa.post_id, 326 'title' : wpa.url, 327 'type' : 'view' 328 }; 329 $.post( wpa.ajaxurl, data, function (response) { 330 console.log( response ); 331 }, "json" ); 332 } 333 334 } 335 if ( wpa.underline.enabled ) { 336 // Underline any link not inside a `nav` region. Using JS for this avoids problems with cascade precedence. 337 var originalOutline = $( wpa.underline.target ).css( 'outline-width' ); 338 var originalOffset = $( wpa.underline.target ).css( 'outline-offset' ); 339 var textColor = $( wpa.underline.target ).css( 'color' ); 340 var originalColor = $( wpa.underline.target ).css( 'outline-color' ); 341 $( wpa.underline.target ).not( 'nav ' + wpa.underline.target ).css( 'text-decoration', 'underline' ); 342 343 $( wpa.underline.target ).on( 'mouseenter', function() { 344 $( this ).css( 'text-decoration', 'none' ); 345 }); 346 $( wpa.underline.target ).on( 'mouseleave', function() { 347 // Reset visible appearance on exit. 348 $( this ).css( 'text-decoration', 'underline' ); 349 }); 350 351 $( wpa.underline.target ).on( 'focusin', function() { 352 var newOutline = '2px'; 353 if ( originalOutline == '2px' ) { 354 newOutline = '4px'; 355 } 356 // Ensure there's a visible change of appearance on hover or focus. 357 $(this).css( 'outline-width', newOutline ); 358 $(this).css( 'outline-color', textColor ); 359 $(this).css( 'outline-offset', '2px' ); 360 }); 361 $( wpa.underline.target ).on( 'focusout', function() { 362 // Reset visible appearance on exit. 363 $(this).css( 'outline-width', originalOutline ); 364 $(this).css( 'outline-color', originalColor ); 365 $(this).css( 'outline-offset', originalOffset ); 366 }); 367 } 368}(jQuery)); 369 370/** 371 * Check whether an element contains text, including inspecting contained content for image alt attributes or aria-label attributes. 372 * 373 * 374 * @arg el DOM element to check. 375 * 376 * Based on work by Roger Johansson https://www.456bereastreet.com/archive/201105/get_element_text_including_alt_text_for_images_with_javascript/ 377 */ 378function wpaElementText(el) { 379 var text = ''; 380 // Text node (3) or CDATA node (4) - return its text
381 if ( (el.nodeType === 3) || (el.nodeType === 4) ) { 382 text = el.nodeValue; 383 // If node is an element (1) and an img, input[type=image], or area element, return its alt text 384 } else if ( (el.nodeType === 1) && ( 385 (el.tagName.toLowerCase() == 'img') || 386 (el.tagName.toLowerCase() == 'area') || 387 ((el.tagName.toLowerCase() == 'input') && el.getAttribute('type') && (el.getAttribute('type').toLowerCase() == 'image')) 388 ) ) { 389 text = el.getAttribute('alt') || ''; 390 // Traverse children unless this is a script or style element 391 } else if ( (el.nodeType === 1) && !el.tagName.match(/^(script|style)$/i) ) { 392 var children = el.childNodes; 393 for (var i = 0, l = children.length; i < l; i++) { 394 // If an element has an aria-label, that will override any other contained text. 395 var ariaLabel = el.getAttribute( 'aria-label' ); 396 text += ( ariaLabel ) ? ariaLabel : wpaElementText( children[i] ) + ' '; 397 } 398 } 399 400 return text; 401}; 402 403/** 404 * Wait to see whether an element becomes available. 405 * 406 * @param {string} selector 407 * @returns 408 */ 409function waitForElement(selector) { 410 return new Promise(resolve => { 411 if (document.querySelector(selector)) { 412 return resolve(document.querySelector(selector)); 413 } 414 415 const observer = new MutationObserver(mutations => { 416 if (document.querySelector(selector)) { 417 observer.disconnect(); 418 resolve(document.querySelector(selector)); 419 } 420 }); 421 422 observer.observe(document.body, { 423 childList: true, 424 subtree: true 425 }); 426 }); 427}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.