forked from gdkraus/web-evaluation-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
code.js
717 lines (604 loc) · 34.2 KB
/
code.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
var errThrown = false;
// Pass a function to be applied to all frames within a given context
function recurseFrames(fr, f) {
f(fr);
fr.find('iframe').each(function(index) {
try {
recurseFrames(jQuery(this).contents(), f);
}
catch (err) {
if (!errThrown) {
//Some content is loaded from another domain and cannot be analyzed becasue of cross-scripting permissions.
}
errThrown = true;
}
})
}
// CSS Strings for Tests
var ncsuA11yToolHighContrastCSSString = "*,body,html{color:#ff0!important;background-color:#000!important;font-family:sans-serif!important;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)!important}html{background:#eee!important}:focus{outline:2px solid #0FF!important}body{font-size:1.4em!important;line-height:1.6em!important;text-align:left!important;margin-left:1em!important;margin-right:auto!important}a{color:#fff!important;text-decoration:underline!important;border-color:#0F0!important}a:focus,a:hover{color:#000!important;background:#ffc!important}a:visited{color:#090!important}button,input,select,textarea{border-color:#FFF!important;border-style:solid!important;background-image:none!important}";
var ncsuA11yToolVisibleFocusString = ":focus{outline:#afff00;outline: solid 3px red !important}";
var ncsuA11yToolHeadingCSSString = ".heading-highlight{background:#afff00;outline: 3px #0f0 solid;border: 3px #0f0 solid;position:relative;width:auto;left:auto;top:auto;} p.heading-highlight-note{background:#0f0;font-weight:bold;margin:3px;padding:3px;font-size:1em;}";
var ncsuA11yToolARIALandmarksCSSString = ".aria-landmark-highlight{background:#fcc;outline: 3px #f00 solid;border: 3px #f00 solid;clear:both;} p.aria-landmark-highlight-note{background:#f99;font-weight:bold;margin:0;padding:0;font-size:1em;padding-top:1.2em;}";
var ncsuA11yToolARIARolesCSSString = ".aria-role-highlight{background:#cfc;outline: 3px #0f0 solid;border: 3px #0f0 solid;clear:both;} p.aria-role-highlight-note{background:#9f9;font-weight:bold;margin:0;padding:0;font-size:1em;padding-top:1.2em;}";
var ncsuA11yToolARIAAttributesCSSString = ".aria-attribute-highlight{background:#ccf;outline: 3px #00f solid;border: 3px #00f solid;clear:both;} p.aria-attribute-highlight-note{background:#99f;font-weight:bold;margin:0;padding:0;font-size:1em;padding-top:1.2em;}";
var ncsuA11yToolTabindexCSSString = ".tabindex-highlight{background:#fe0;outline: 3px #ffd700 solid;border: 3px #ffd700 solid;} p.tabindex-highlight-note{background:#ffee00;font-weight:bold;margin:3px;padding:3px;font-size:1em;}";
var ncsuA11yToolInternalLinksCSSString = ".internal-link-highlight{background:#ccf;outline: 3px #ffd700 solid;border: 3px #00f solid;position:relative;width:auto;left:auto;top:auto;} p.internal-link-highlight-note{background:#ccf;font-weight:bold;margin:3px;padding:3px;font-size:1em;position:relative;width:auto;left:auto;top:auto;}";
var ncsuA11yToolCrossSiteContentCSSString = ".cross-site-content-highlight{border: 3px orange solid !important;} p.cross-site-content-highlight-note{background:orange;color:#000;font-weight:bold;margin:3px;padding:3px;font-size:1em;}";
var ncsuA11yToolLanguageAttributesCSSString = ".language-attribute-highlight{background:#ccf;outline: 3px #00f solid;border: 3px #00f solid;clear:both;} p.language-attribute-highlight-note{background:#99f;font-weight:bold;margin:0;padding:0;font-size:1em;padding-top:1.2em;}";
// Track the number of instances for each test
var ncsuA11yToolHeadingsCount = 0;
var ncsuA11yToolARIALandmarksCount = 0;
var ncsuA11yToolARIARolesCount = 0;
var ncsuA11yToolARIAAttributesCount = 0;
var ncsuA11yToolTabindexCount = 0;
var ncsuA11yToolInternalLinksCount = 0;
var ncsuA11yToolInternalLinksMissingTabindex = false;
var ncsuA11yToolCrossSiteContentCount = 0;
var ncsuA11yToolLanguageAttributesCount = 0;
var languageAttributesFirstPass = true;
var languageAttributesFirstPassAdd = true;
/****** HEADINGS ******/
// count the number of headings in a given frame
function ncsuA11yToolCountHeadings(fr) {
ncsuA11yToolHeadingsCount += fr.find('h1,h2,h3,h4,h5,h6').length;
}
// count the number of headings, recursing through all the frames
function ncsuA11yToolGetNumberOfHeadings() {
recurseFrames(jQuery('html'), ncsuA11yToolCountHeadings);
return ncsuA11yToolHeadingsCount;
}
// add the style for highlighting headings for a given frame
function ncsuA11yToolAddHeadingStyle(fr) {
fr.find('head').append("<style type='text/css'>" + ncsuA11yToolHeadingCSSString + "</style>");
}
// remove the style for highlighting headings for a given frame
function ncsuA11yToolRemoveHeadingStyle(fr) {
fr.find('style:contains(' + ncsuA11yToolHeadingCSSString + ')').remove();
}
// add the contextual notes for each heading for a given frame
function ncsuA11yToolAddHeadingNotes(fr) {
fr.find('h1,h2,h3,h4,h5,h6').each(function() {
jQuery(this).addClass('heading-highlight')
jQuery(this).prepend("<p class='heading-highlight-note'>" + jQuery(this).prop("tagName") + ':' + jQuery(this).text() + "</p>")
});
}
// remove the contextual notes for each heading for a given frame
function ncsuA11yToolRemoveHeadingNotes(fr) {
fr.find('.heading-highlight-note').remove();
fr.find('h1,h2,h3,h4,h5,h6').each(function() {
jQuery(this).removeClass('heading-highlight')
});
}
// add/remove the headings tool
function ncsuA11yToolHeadings() {
if (jQuery('style:contains(' + ncsuA11yToolHeadingCSSString + ')').length) { // need to remove from the DOM
recurseFrames(jQuery('html'), ncsuA11yToolRemoveHeadingStyle); //remove the CSS style from the head
recurseFrames(jQuery('html'), ncsuA11yToolRemoveHeadingNotes); //remove all elements with this style (which should just be the elements we inserted)
} else { // need to insert into the DOM
recurseFrames(jQuery('html'), ncsuA11yToolAddHeadingStyle);
recurseFrames(jQuery('html'), ncsuA11yToolAddHeadingNotes);
if (ncsuA11yToolGetNumberOfHeadings() == 0) {
alert('No headings were found.');
}
}
}
/************ ARIA LANDMARKS ************/
// count the number of ARIA landmarks in a given frame
function ncsuA11yToolCountARIALandmarks(fr) {
ncsuA11yToolARIALandmarksCount += fr.find('[role="navigation"],[role="main"],[role="form"],[role="search"],[role="banner"],[role="complementary"],[role="contentinfo"]').length;
}
// count the number of ARIA landmarks, recursing through all the frames
function ncsuA11yToolGetNumberOfARIALandmarks() {
recurseFrames(jQuery('html'), ncsuA11yToolCountARIALandmarks);
return ncsuA11yToolARIALandmarksCount;
}
// add the style for highlighting ARIA landmarks for a given frame
function ncsuA11yToolAddARIALandmarkStyle(fr) {
fr.find('head').append("<style type='text/css'>" + ncsuA11yToolARIALandmarksCSSString + "</style>");
}
// remove the style for highlighting ARIA landmarks for a given frame
function ncsuA11yToolRemoveARIALandmarkStyle(fr) {
fr.find('style:contains(' + ncsuA11yToolARIALandmarksCSSString + ')').remove();
}
// add the contextual notes for each ARIA landmark for a given frame
function ncsuA11yToolAddARIALandmarkNotes(fr) {
fr.find('.aria-landmark-highlight-note').remove()
fr.find('[role="navigation"],[role="main"],[role="form"],[role="search"],[role="banner"],[role="complementary"],[role="contentinfo"]').each(function() {
jQuery(this).addClass('aria-landmark-highlight')
if (jQuery(this).attr('aria-label') !== undefined) {
// attribute exists
jQuery(this).prepend("<p class='aria-landmark-highlight-note'>Label: "" + jQuery(this).attr("aria-label") + ""</p>")
} else {
// attribute does not exist
}
if (jQuery(this).attr('aria-labelledby') !== undefined) {
// attribute exists
jQuery(this).prepend("<p class='aria-landmark-highlight-note'>Labelled By: "" + jQuery('[id="' + jQuery(this).attr("aria-labelledby") + '"]').html() + ""</p>")
} else {
// attribute does not exist
}
jQuery(this).prepend("<p class='aria-landmark-highlight-note'>Role: " + jQuery(this).attr("role") + "</p>")
});
}
// remove the contextual notes for each ARIA landmark for a given frame
function ncsuA11yToolRemoveARIALandmarkNotes(fr) {
fr.find('.aria-landmark-highlight-note').remove();
fr.find('[role="navigation"],[role="main"],[role="form"],[role="search"],[role="banner"],[role="complementary"],[role="contentinfo"]').each(function() {
jQuery(this).removeClass('aria-landmark-highlight')
});
}
// add/remove the ARIA landmarks tool
function ncsuA11yToolAriaLandmarks() {
if (jQuery('style:contains(' + ncsuA11yToolARIALandmarksCSSString + ')').length) {// need to remove from the DOM
recurseFrames(jQuery('html'), ncsuA11yToolRemoveARIALandmarkStyle); //remove the CSS style from the head
recurseFrames(jQuery('html'), ncsuA11yToolRemoveARIALandmarkNotes);
} else { // need to insert into the DOM
recurseFrames(jQuery('html'), ncsuA11yToolAddARIALandmarkStyle);
recurseFrames(jQuery('html'), ncsuA11yToolAddARIALandmarkNotes);
if (ncsuA11yToolGetNumberOfARIALandmarks() == 0) {
alert('No ARIA Landmarks were found');
}
}
}
/************ ARIA ROLES THAT ARE NOT LANDMARKS ************/
// count the number of ARIA roles that are not landmarks in a given frame
function ncsuA11yToolCountARIARoles(fr) {
ncsuA11yToolARIARolesCount += fr.find('[role]:not([role="navigation"],[role="main"],[role="form"],[role="search"],[role="banner"],[role="complementary"],[role="contentinfo"])').length;
}
// count the number of ARIA roles that are not landmarks, recursing through all the frames
function ncsuA11yToolGetNumberOfARIARoles() {
recurseFrames(jQuery('html'), ncsuA11yToolCountARIARoles);
return ncsuA11yToolARIARolesCount;
}
// add the style for highlighting ARIA roles that are not landmarks for a given frame
function ncsuA11yToolAddARIARolesStyle(fr) {
fr.find('head').append("<style type='text/css'>" + ncsuA11yToolARIARolesCSSString + "</style>");
}
// remove the style for highlighting ARIA roles that are not landmarks for a given frame
function ncsuA11yToolRemoveARIARolesStyle(fr) {
fr.find('style:contains(' + ncsuA11yToolARIARolesCSSString + ')').remove();
}
// add the contextual notes for each ARIA roles that are not landmarks for a given frame
function ncsuA11yToolAddARIARolesNotes(fr) {
fr.find('.aria-role-highlight-note').remove()
fr.find('[role]:not([role="navigation"],[role="main"],[role="form"],[role="search"],[role="banner"],[role="complementary"],[role="contentinfo"])').each(function() {
jQuery(this).addClass('aria-role-highlight')
jQuery(this).prepend("<p class='aria-role-highlight-note'>Role: " + jQuery(this).attr("role") + "</p>")
});
}
// remove the contextual notes for each ARIA roles that are not landmarks for a given frame
function ncsuA11yToolRemoveARIARolesNotes(fr) {
fr.find('.aria-role-highlight-note').remove();
fr.find('[role]:not([role="navigation"],[role="main"],[role="form"],[role="search"],[role="banner"],[role="complementary"],[role="contentinfo"])').each(function() {
jQuery(this).removeClass('aria-role-highlight')
});
}
// add/remove the ARIA roles that are not landmarks tool
function ncsuA11yToolAriaRoles() {
if (jQuery('style:contains(' + ncsuA11yToolARIARolesCSSString + ')').length) {// need to remove from the DOM
recurseFrames(jQuery('html'), ncsuA11yToolRemoveARIARolesStyle); //remove the CSS style from the head
recurseFrames(jQuery('html'), ncsuA11yToolRemoveARIARolesNotes);
} else { // need to insert into the DOM
recurseFrames(jQuery('html'), ncsuA11yToolAddARIARolesStyle);
recurseFrames(jQuery('html'), ncsuA11yToolAddARIARolesNotes);
if (ncsuA11yToolGetNumberOfARIARoles() == 0) {
alert('No ARIA Roles were found');
}
}
}
/************ ARIA ATTRIBUTES (NOT ROLE) ************/
// count the number of ARIA attributes (not role) in a given frame
function ncsuA11yToolCountARIAAttributes(fr) {
//console.log(fr);
var ARIAAttributeCount = 0;
$('*', fr).each(function() {
$.each(this.attributes, function() {
if (this.specified) {
if (this.name.substring(0, 5).toLowerCase() == 'aria-') {
ARIAAttributeCount = ARIAAttributeCount + 1;
}
}
});
});
ncsuA11yToolARIAAttributesCount += ARIAAttributeCount;
}
// count the number of ARIA attributes (not role), recursing through all the frames
function ncsuA11yToolGetNumberOfARIAAttributes() {
recurseFrames(jQuery('html'), ncsuA11yToolCountARIAAttributes);
return ncsuA11yToolARIAAttributesCount;
}
// add the style for highlighting ARIA attributes (not role) for a given frame
function ncsuA11yToolAddARIAAttributesStyle(fr) {
fr.find('head').append("<style type='text/css'>" + ncsuA11yToolARIAAttributesCSSString + "</style>");
}
// remove the style for highlighting ARIA attributes (not role) for a given frame
function ncsuA11yToolRemoveARIAAttributesStyle(fr) {
fr.find('style:contains(' + ncsuA11yToolARIAAttributesCSSString + ')').remove();
}
// add the contextual notes for each ARIA attributes (not role) for a given frame
function ncsuA11yToolAddARIAAttributesNotes(fr) {
var currentElement;
//fr.find('.aria-attribute-highlight-note').remove()
$('*', fr).each(function() {
currentElement = this;
$.each(this.attributes, function() {
if (this.specified) {
if (this.name.substring(0, 5).toLowerCase() == 'aria-') {
jQuery(currentElement).addClass('aria-attribute-highlight');
jQuery(currentElement).prepend("<p class='aria-attribute-highlight-note'>ARIA Attribute: " + this.name + "=" + this.value + "</p>");
}
}
});
});
}
// remove the contextual notes for each ARIA attributes (not role) for a given frame
function ncsuA11yToolRemoveARIAAttributesNotes(fr) {
fr.find('.aria-attribute-highlight-note').remove();
jQuery('*', fr).removeClass('aria-attribute-highlight');
// fr.find('[role]:not([role="navigation"],[role="main"],[role="form"],[role="search"],[role="banner"],[role="complementary"],[role="contentinfo"])').each(function() {
// jQuery(this).removeClass('aria-attribute-highlight')
// });
}
// add/remove the ARIA attributes (not role) tool
function ncsuA11yToolAriaAttributes() {
if (jQuery('style:contains(' + ncsuA11yToolARIAAttributesCSSString + ')').length) {// need to remove from the DOM
recurseFrames(jQuery('html'), ncsuA11yToolRemoveARIAAttributesStyle); //remove the CSS style from the head
recurseFrames(jQuery('html'), ncsuA11yToolRemoveARIAAttributesNotes);
} else { // need to insert into the DOM
recurseFrames(jQuery('html'), ncsuA11yToolAddARIAAttributesStyle);
recurseFrames(jQuery('html'), ncsuA11yToolAddARIAAttributesNotes);
if (ncsuA11yToolGetNumberOfARIAAttributes() == 0) {
alert('No ARIA Attributes were found');
}
}
}
/************ TABINDEX ************/
// count the number of tabindex attributes in a given frame
function ncsuA11yToolCountTabindex(fr) {
ncsuA11yToolTabindexCount += fr.find('[tabindex]').length;
}
// count the number of tabindex attributes, recursing through all the frames
function ncsuA11yToolGetNumberOfTabindex() {
recurseFrames(jQuery('html'), ncsuA11yToolCountTabindex);
return ncsuA11yToolTabindexCount;
}
// add the style for highlighting tabindex attributes for a given frame
function ncsuA11yToolAddTabindexStyle(fr) {
fr.find('head').append("<style type='text/css'>" + ncsuA11yToolTabindexCSSString + "</style>");
}
// remove the style for highlighting tabindex attributes for a given frame
function ncsuA11yToolRemoveTabindexStyle(fr) {
fr.find('style:contains(' + ncsuA11yToolTabindexCSSString + ')').remove();
}
// add the contextual notes for each tabindex attributes for a given frame
function ncsuA11yToolAddTabindexNotes(fr) {
fr.find('[tabindex]').each(function() {
jQuery(this).addClass('tabindex-highlight')
jQuery(this).parent().prepend("<p class='tabindex-highlight-note'>tabindex: " + jQuery(this).attr("tabindex") + "</p>")
});
}
// remove the contextual notes for each tabindex attributes for a given frame
function ncsuA11yToolRemoveTabindexNotes(fr) {
fr.find('.tabindex-highlight-note').remove();
fr.find('[tabindex]').each(function() {
jQuery(this).removeClass('tabindex-highlight')
});
}
// add/remove the tabindex attributes tool
function ncsuA11yToolTabIndex() {
if (jQuery('style:contains(' + ncsuA11yToolTabindexCSSString + ')').length) {
// need to remove from the DOM
recurseFrames(jQuery('html'), ncsuA11yToolRemoveTabindexStyle); //remove the CSS style from the head
recurseFrames(jQuery('html'), ncsuA11yToolRemoveTabindexNotes); //remove all elements with this style (which should just be the elements we inserted)
} else {
// need to insert into the DOM
recurseFrames(jQuery('html'), ncsuA11yToolAddTabindexStyle);
recurseFrames(jQuery('html'), ncsuA11yToolAddTabindexNotes);
if (ncsuA11yToolGetNumberOfTabindex() == 0) {
alert('No tabindex attributes were found.');
}
}
}
/************ INTERNAL LINK ************/
// count the number of internal links in a given frame
function ncsuA11yToolCountInternalLinks(fr) {
ncsuA11yToolInternalLinksCount += fr.find('[href^="#"][href!="#"]').length;
fr.find('[href^="#"][href!="#"]').each(function() {
var missingTabIndex = false;
if (jQuery(jQuery(this).attr("href") + ',[name="' + jQuery(this).attr('href').substring(1, jQuery('[href^="#"][href!="#"]').attr('href').length) + '"]').attr('tabindex') === undefined) {
missingTabIndex = true;
} else {
missingTabIndex = false;
}
if (missingTabIndex) {
ncsuA11yToolInternalLinksMissingTabindex = true
} else {
}
});
}
// count the number of internal links, recursing through all the frames
function ncsuA11yToolGetNumberOfInternalLinks() {
recurseFrames(jQuery('html'), ncsuA11yToolCountInternalLinks);
return ncsuA11yToolInternalLinksCount + (ncsuA11yToolInternalLinksMissingTabindex == true ? '*' : '');
}
// add the style for highlighting internal links for a given frame
function ncsuA11yToolAddInternalLinksStyle(fr) {
fr.find('head').append("<style type='text/css'>" + ncsuA11yToolInternalLinksCSSString + "</style>");
}
// remove the style for highlighting internal links for a given frame
function ncsuA11yToolRemoveInternalLinksStyle(fr) {
fr.find('style:contains(' + ncsuA11yToolInternalLinksCSSString + ')').remove();
}
// add the contextual notes for each internal link for a given frame
function ncsuA11yToolAddInternalLinksNotes(fr) {
fr.find('[href^="#"][href!="#"]').each(function() {
jQuery(this).addClass('internal-link-highlight')
jQuery(this).parent().prepend("<p class='internal-link-highlight-note'>Internal Link Source: " + jQuery(this).text() + "</p>")
var missingTabIndex = false;
if (jQuery(jQuery(this).attr("href") + ',[name="' + jQuery(this).attr('href').substring(1, jQuery('[href^="#"][href!="#"]').attr('href').length) + '"]').attr('tabindex') === undefined) {
missingTabIndex = true;
} else {
missingTabIndex = false;
}
jQuery(jQuery(this).attr("href") + ',[name="' + jQuery(this).attr('href').substring(1, jQuery('[href^="#"][href!="#"]').attr('href').length) + '"]').prepend("<p class='internal-link-highlight-note'>Internal Link Target" + (missingTabIndex ? ' (missing tabindex)' : '') + ": " + jQuery(this).text() + "</p>")
//jQuery(jQuery(this).attr("href")).prepend("<p class='internal-link-highlight-note'>Internal Link Target: " + jQuery(this).text() + "</p>")
});
}
// remove the contextual notes for each internal link for a given frame
function ncsuA11yToolRemoveInternalLinksNotes(fr) {
fr.find('.internal-link-highlight-note').remove();
fr.find('[href^="#"][href!="#"]').each(function() {
jQuery(this).removeClass('internal-link-highlight')
});
}
// add/remove the internal links tool
function ncsuA11yToolInternalLink() {
if (jQuery('style:contains(' + ncsuA11yToolInternalLinksCSSString + ')').length) {
// need to remove from the DOM
recurseFrames(jQuery('html'), ncsuA11yToolRemoveInternalLinksStyle); //remove the CSS style from the head
recurseFrames(jQuery('html'), ncsuA11yToolRemoveInternalLinksNotes); //remove all elements with this style (which should just be the elements we inserted)
} else {
// need to insert into the DOM
recurseFrames(jQuery('html'), ncsuA11yToolAddInternalLinksStyle);
recurseFrames(jQuery('html'), ncsuA11yToolAddInternalLinksNotes);
if (ncsuA11yToolGetNumberOfInternalLinks() == 0) {
alert('No internal links were found.');
}
}
}
/************ VISUAL FOCUS ************/
// add a focus ring for all focusable items for a given frame
function ncsuA11yToolAddVisibleFocusStyle(fr) {
fr.find('head').append("<style type='text/css'>" + ncsuA11yToolVisibleFocusString + "</style>");
}
// remove the focus ring for all focusble items for a given frame
function ncsuA11yToolRemoveVisibleFocusStyle(fr) {
fr.find('style:contains(' + ncsuA11yToolVisibleFocusString + ')').remove();
}
// add/remove the visual focus tool
function ncsuA11yToolVisualFocus() {
if (jQuery('style:contains(' + ncsuA11yToolVisibleFocusString + ')').length) {
// need to remove from the DOM
recurseFrames(jQuery('html'), ncsuA11yToolRemoveVisibleFocusStyle); //remove the CSS style from the head
} else {
// need to insert into the DOM
recurseFrames(jQuery('html'), ncsuA11yToolAddVisibleFocusStyle);
}
}
/************ HIGH CONTRAST CSS ************/
// add the high contrast CSS for a given frame
function ncsuA11yToolAddHighContrastCSSStyle(fr) {
fr.find('head').append("<style type='text/css' data-id='ncsuA11yToolHighContrastCSS'>" + ncsuA11yToolHighContrastCSSString + "</style>");
}
// remove the high contrast CSS for a given frame
function ncsuA11yToolRemoveHighContrastCSSStyle(fr) {
fr.find('[data-id="ncsuA11yToolHighContrastCSS"]').remove();
}
// add/remove the high contrast CSS
function ncsuA11yToolHighContrastCSS() {
if (jQuery('[data-id="ncsuA11yToolHighContrastCSS"]').length) {
// need to remove from the DOM
recurseFrames(jQuery('html'), ncsuA11yToolRemoveHighContrastCSSStyle); //remove the CSS style from the head
} else {
// need to insert into the DOM
recurseFrames(jQuery('html'), ncsuA11yToolAddHighContrastCSSStyle);
}
}
/************ CROSS-SITE CONTENT ************/
// count the number of cross-site content areas in a given frame
function ncsuA11yToolCountCrossSiteContent(fr) {
ncsuA11yToolCrossSiteContentCount += fr.find('iframe').length;
}
// count the number of cross-site content areas, recursing through all the frames
function ncsuA11yToolGetNumberOfCrossSiteContent() {
recurseFrames(jQuery('html'), ncsuA11yToolCountCrossSiteContent);
return ncsuA11yToolCrossSiteContentCount;
}
// add the style for highlighting cross-site content areas for a given frame
function ncsuA11yToolAddCrossSiteContentStyle(fr) {
fr.find('head').append("<style type='text/css'>" + ncsuA11yToolCrossSiteContentCSSString + "</style>");
}
// remove the style for highlighting cross-site content areas for a given frame
function ncsuA11yToolRemoveCrossSiteContentStyle(fr) {
fr.find('style:contains(' + ncsuA11yToolCrossSiteContentCSSString + ')').remove();
}
// add the contextual notes for each cross-site content area for a given frame
function ncsuA11yToolAddCrossSiteContentNotes(fr) {
fr.find('iframe').each(function() {
jQuery(this).addClass('cross-site-content-highlight')
jQuery(this).parent().prepend("<p class='cross-site-content-highlight-note'>Cross Site Content</p>")
});
}
// remove the contextual notes for each cross-site content area for a given frame
function ncsuA11yToolRemoveCrossSiteContentNotes(fr) {
fr.find('.cross-site-content-highlight-note').remove();
fr.find('iframe').each(function() {
jQuery(this).removeClass('cross-site-content-highlight')
});
}
// add/remove the cross-site content areas tool
function ncsuA11yToolCrossSiteContent() {
if (jQuery('style:contains(' + ncsuA11yToolCrossSiteContentCSSString + ')').length) {
// need to remove from the DOM
recurseFrames(jQuery('html'), ncsuA11yToolRemoveCrossSiteContentStyle); //remove the CSS style from the head
recurseFrames(jQuery('html'), ncsuA11yToolRemoveCrossSiteContentNotes); //remove all elements with this style (which should just be the elements we inserted)
} else {
// need to insert into the DOM
recurseFrames(jQuery('html'), ncsuA11yToolAddCrossSiteContentStyle);
recurseFrames(jQuery('html'), ncsuA11yToolAddCrossSiteContentNotes);
if (ncsuA11yToolGetNumberOfCrossSiteContent() == 0) {
alert('No internal links were found.');
}
}
}
/************ LANGUAGE ATTRIBUTES ************/
// count the number of language attributes in a given frame
function ncsuA11yToolCountLanguageAttributes(fr) {
var languageAttributeCount = 0;
if (languageAttributesFirstPass) { // need to do this check to accurately determine lang attributes on the outer most html element of page. html elements in iframes do not need this check
languageAttributesFirstPass = false;
$('*').each(function() {
$.each(this.attributes, function() {
if (this.specified) {
if (this.name.toLowerCase() == 'lang') {
languageAttributeCount = languageAttributeCount + 1;
}
}
});
});
} else {
$('*', fr).each(function() {
$.each(this.attributes, function() {
if (this.specified) {
if (this.name.toLowerCase() == 'lang') {
languageAttributeCount = languageAttributeCount + 1;
}
}
});
});
}
ncsuA11yToolLanguageAttributesCount += languageAttributeCount;
}
// count the number of language attributes, recursing through all the frames
function ncsuA11yToolGetNumberOfLanguageAttributes() {
languageAttributesFirstPass = true;
recurseFrames(jQuery('html'), ncsuA11yToolCountLanguageAttributes);
return ncsuA11yToolLanguageAttributesCount;
}
// add the style for highlighting language attributes for a given frame
function ncsuA11yToolAddLanguageAttributesStyle(fr) {
fr.find('head').append("<style type='text/css'>" + ncsuA11yToolLanguageAttributesCSSString + "</style>");
}
// remove the style for highlighting language attributes for a given frame
function ncsuA11yToolRemoveLanguageAttributesStyle(fr) {
fr.find('style:contains(' + ncsuA11yToolLanguageAttributesCSSString + ')').remove();
}
// add the contextual notes for each language attributes for a given frame
function ncsuA11yToolAddLanguageAttributesNotes(fr) {
var currentElement;
//fr.find('.language-attribute-highlight-note').remove()
if (languageAttributesFirstPassAdd) { // need to do this check to accurately determine lang attributes on the outer most html element of page. html elements in iframes do not need this check
$('*').each(function() {
currentElement = this;
$.each(this.attributes, function() {
if (this.specified) {
if (this.name.toLowerCase() == 'lang') {
if (languageAttributesFirstPassAdd) {
jQuery('body').addClass('language-attribute-highlight');
jQuery('body').prepend("<p class='language-attribute-highlight-note'>Language=\"" + this.value + "\"</p>");
languageAttributesFirstPassAdd = false;
} else {
jQuery(currentElement).addClass('language-attribute-highlight');
jQuery(currentElement).prepend("<p class='language-attribute-highlight-note'>Language=\"" + this.value + "\"</p>");
}
}
}
});
});
} else {
$('*', fr).each(function() {
currentElement = this;
$.each(this.attributes, function() {
if (this.specified) {
if (this.name.toLowerCase() == 'lang') {
jQuery(currentElement).addClass('language-attribute-highlight');
jQuery(currentElement).prepend("<p class='language-attribute-highlight-note'>Language=\"" + this.value + "\"</p>");
}
}
});
});
}
}
// remove the contextual notes for each language attributes for a given frame
function ncsuA11yToolRemoveLanguageAttributesNotes(fr) {
languageAttributesFirstPassAdd = true;
fr.find('.language-attribute-highlight-note').remove();
jQuery('*', fr).removeClass('language-attribute-highlight');
}
// add/remove the language attributes tool
function ncsuA11yToolLanguageAttributes() {
if (jQuery('style:contains(' + ncsuA11yToolLanguageAttributesCSSString + ')').length) {// need to remove from the DOM
recurseFrames(jQuery('html'), ncsuA11yToolRemoveLanguageAttributesStyle); //remove the CSS style from the head
recurseFrames(jQuery('html'), ncsuA11yToolRemoveLanguageAttributesNotes);
} else { // need to insert into the DOM
recurseFrames(jQuery('html'), ncsuA11yToolAddLanguageAttributesStyle);
recurseFrames(jQuery('html'), ncsuA11yToolAddLanguageAttributesNotes);
if (ncsuA11yToolGetNumberOfLanguageAttributes() == 0) {
alert('No language attributes were found');
}
}
}
/************ INSERT/REMOVE THE TOOL BAR ************/
if (jQuery('#ncsuA11yTools').length == 0) { // insert the toolbar
// add space to the top of the page
var bodyCssString = "body {margin-top:3em !important;}";
jQuery("<style type='text/css'>" + bodyCssString + "</style>").appendTo("head");
// css for the toolbar
var toolsCSSString = "#ncsuA11yTools {line-height: 1.2em;border: 1px solid #000;text-align:center !important;font-size:12pt !important;background:#eee !important;margin:0 !important;padding:3px !important;top:0 !important;left:0 !important;position:fixed !important;width:100% !important;z-index:9999999 !important} #ncsuA11yTools input, #ncsuA11yTools span{background-color:#eee !important} #ncsuA11yTools label{background-color:#eee !important;margin-right:1em; display:inline !important; color:#000 !important;font-size:1em !important; font-weight:normal !important; font-family: arial, sans-serif important;}.ncsua11ytoolitem{white-space:nowrap;}";
jQuery("<style type='text/css'>" + toolsCSSString + "</style>").appendTo("head");
// add the toolbar
jQuery('body').prepend('<div id="ncsuA11yTools">\n\
<span class="ncsua11ytoolitem"><input id="ncsua11ytoolheadings" name="headings" type="checkbox" onChange="ncsuA11yToolHeadings();">\n\
<label for="ncsua11ytoolheadings">Headings: </label></span>\n\
\n\
<span class="ncsua11ytoolitem"><input id="ncsua11ytoolarialandmarks" name="arialandmarks" type="checkbox" onChange="ncsuA11yToolAriaLandmarks();">\n\
<label for="ncsua11ytoolarialandmarks">ARIA Landmarks: </label></span>\n\
\n\
<span class="ncsua11ytoolitem"><input id="ncsua11ytoolariaroles" name="ariaroles" type="checkbox" onChange="ncsuA11yToolAriaRoles();">\n\
<label for="ncsua11ytoolariaroles">ARIA Roles: </label></span>\n\
\n\
<span class="ncsua11ytoolitem"><input id="ncsua11ytoolariaattributes" name="ariaattributes" type="checkbox" onChange="ncsuA11yToolAriaAttributes();">\n\
<label for="ncsua11ytoolariaattributes">ARIA Attributes: </label></span>\n\
\n\
<span class="ncsua11ytoolitem"><input id="ncsua11ytooltabindex" name="tabindex" type="checkbox" onChange="ncsuA11yToolTabIndex();">\n\
<label for="ncsua11ytooltabindex">tabindex: </label></span>\n\
\n\
<span class="ncsua11ytoolitem"><input id="ncsua11ytoolinternallink" name="internallink" type="checkbox" onChange="ncsuA11yToolInternalLink();">\n\
<label for="ncsua11ytoolinternallink">Internal Link: </label></span>\n\
\n\
<span class="ncsua11ytoolitem"><input id="ncsua11ycrosssitecontent" name="crosssitecontent" type="checkbox" onChange="ncsuA11yToolCrossSiteContent();">\n\
<label for="ncsua11ycrosssitecontent">Cross Site Content: </label></span>\n\
\n\
<span class="ncsua11ytoolitem"><input id="ncsua11ytoolvisualfocus" name="visualfocus" type="checkbox" onChange="ncsuA11yToolVisualFocus();">\n\
<label for="ncsua11ytoolvisualfocus">Force Show Visual Focus</label></span>\n\
\n\
<span class="ncsua11ytoolitem"><input id="ncsua11ytoolhighcontrastcss" name="highcntrast" type="checkbox" onChange="ncsuA11yToolHighContrastCSS();">\n\
<label for="ncsua11ytoolhighcontrastcss">High Contrast CSS</label></span>\n\
\n\
<span class="ncsua11ytoolitem"><input id="ncsua11ytoollanguageattributes" name="languageattributes" type="checkbox" onChange="ncsuA11yToolLanguageAttributes();">\n\
<label for="ncsu a11ytoollanguageattributes">Language Attributes: </label></span>\n\
</div>')
// append the number of instances to each appropriate tool
jQuery('label[for="ncsua11ytoolheadings"]').append(ncsuA11yToolGetNumberOfHeadings())
jQuery('label[for="ncsua11ytoolarialandmarks"]').append(ncsuA11yToolGetNumberOfARIALandmarks())
jQuery('label[for="ncsua11ytoolariaroles"]').append(ncsuA11yToolGetNumberOfARIARoles())
jQuery('label[for="ncsua11ytoolariaattributes"]').append(ncsuA11yToolGetNumberOfARIAAttributes())
jQuery('label[for="ncsua11ytooltabindex"]').append(ncsuA11yToolGetNumberOfTabindex())
jQuery('label[for="ncsua11ytoolinternallink"]').append(ncsuA11yToolGetNumberOfInternalLinks())
jQuery('label[for="ncsua11ycrosssitecontent"]').append(ncsuA11yToolGetNumberOfCrossSiteContent())
jQuery('label[for="ncsua11ytoollanguageattributes"]').append(ncsuA11yToolGetNumberOfLanguageAttributes())
} else { // remove the toolbar
jQuery('#ncsuA11yTools').remove()
jQuery('style:contains(' + bodyCssString + ')').remove();
jQuery('style:contains(' + toolsCSSString + ')').remove();
}