1 2 3/*----------------------------------------------------------------------------------- 4 5 Theme Name: Georgia Library 6 Front-end developer: Richard Opiniano 7 Author Design: Samir Alley @samiralley 8 Author URI: http://www.revize.com/ 9 Date: 9/12/22 10 11-----------------------------------------------------------------------------------*/ 12 13(function($) { 14 15 16(function($) { 17 18 'use strict'; 19 20 var $window = $(window), 21 $body = $('body'); 22 23 /*! 24 * IE10 viewport hack for Surface/desktop Windows 8 bug 25 * Copyright 2014-2015 Twitter, Inc. 26 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 27 */ 28 29 // See the Getting Started docs for more information: 30 // http://getbootstrap.com/getting-started/#support-ie10-width 31 if (navigator.userAgent.match(/IEMobile\/10\.0/)) { 32 var msViewportStyle = document.createElement('style'); 33 msViewportStyle.appendChild( 34 document.createTextNode( 35 '@-ms-viewport{width:auto!important}' 36 ) 37 ); document.querySelector('head').appendChild(msViewportStyle); 38 } 39 40 $('.search-tabs-toggle').click(function(e){ 41 e.preventDefault(); 42 $(this).toggleClass('toggled'); 43 $('.search-tabs ul').stop().fadeToggle(); 44 }) 45 46 $('.search-option').on('click',function(e){ 47 e.preventDefault(); 48 var searchOptionIndex = $(this).parent().index(); 49 console.log('clicked on item ' + searchOptionIndex) 50 $('.search-tabs-toggle span').text($(this).text()).parent().removeClass('toggled'); 51 $('.search-tabs ul').stop().fadeOut(); 52 $('.search-tabs-content form').stop().hide(); 53 $('.search-tabs-content form').eq(searchOptionIndex).stop().show(); 54 }); 55 56 // RZ Class 57 if(typeof RZ !== "undefined"){ 58 if(RZ.login){ 59 $body.addClass("user-logged-in"); 60 } else{ 61 $body.addClass("user-not-logged-in"); 62 } 63 if(RZ.pageid === "index"){ 64 $("#video-bg").YTPlayer(); 65 } 66 } 67 68 // Keyboard Navigation: Nav, flyout 69 var isClick = false; 70 $("#nav li a, #flyout li a, a, button, .toggle, .toggle2").on('focusin', function(e) { 71 if( isClick === false ) { 72 $(".focused").removeClass("focused"); 73 $(e.currentTarget).parents("#nav li, #flyout li").addClass("focused"); 74 $(".opened:not(.focused) ul:visible,.opened2:not(.focused) ul:visible").slideUp().parent().removeClass("opened opened2"); 75 } else { 76 $(".focused").removeClass("focused"); 77 isClick = false; 78 } 79 }); 80 81 // prevent focused class changes on click - This way arrows wont pop when clicking nav links 82 $("#nav a,#flyout a").on('mousedown',function(){ 83 isClick = true; 84 }); 85 86 // Search Toggle 87 $('#search-toggle').on('click',function(e){ 88 $('.search').stop().slideToggle(200); 89 $(this).toggleClass('fa-search fa-close'); 90 }); 91 92 // Navigation Toggle 93 $("#nav-toggle").on("click", function(){ 94 $("#nav").stop().slideToggle(); 95 $(this).toggleClass("fa-bars fa-close"); 96 }); 97 98 // Menu Arrows and Toggles 99 $("#nav >li>ul,#flyout >li>ul").addClass('first-level'); 100 $("#nav li ul ul").addClass('second-level'); 101 $("#nav>li:has(ul)").each(function(){ 102 $('<a href="#" class="fa fa-angle-down toggle d-lg-none" tabindex="0" aria-haspopup="true" aria-expanded="false" id="dropdown-toggle-'+$(this).index()+'" aria-label="Show Dropdown for '+ $(this).find('a:first').text() +'"></a>').insertAfter($(this).find('a:first')); 103 $(this).find('ul:first').attr('aria-labelledby', 'dropdown-toggle-'+$(this).index()); 104 }); 105 $('#nav li ul>li:has(ul)').each(function(index) { 106 $('<a href="#" class="fa fa-angle-down toggle2 d-lg-none" tabindex="0" aria-haspopup="true" aria-expanded="false" id="sub-dropdown-toggle-'+index+'" aria-label="Show Dropdown for '+ $(this).find('a:first').text() +'"></a>').insertAfter($(this).find('a:first')); 107 $(this).find('ul:first').attr('aria-labelledby', 'sub-dropdown-toggle-'+index); 108 }); 109 $('#flyout >li:has(ul)').each(function() { 110 $('<a href="#" class="fa fa-angle-down toggle d-lg-none" tabindex="0" aria-haspopup="true" aria-expanded="false" id="flyout-dropdown-toggle-'+$(this).index()+'" aria-label="Show Flyout for '+ $(this).find('a:first').text() +'"></a>').insertAfter($(this).find('a:first')); 111 $(this).find('ul:first').attr('aria-labelledby', 'flyout-dropdown-toggle-'+$(this).index()); 112 }); 113 114 function addNavClass() { 115 if ($window.width() < 992) { 116 // Insert needed for mobile 117 } else{ 118 // Insert needed for desktop 119 $('#nav ul, #flyout ul').css('display', ''); 120 } 121 } 122 addNavClass(); 123 $window.resize(addNavClass); 124 125 $(".toggle").on("click keydown",function(e) { 126 if (e.keyCode === 13 || e.type === 'click') { 127 e.preventDefault(); 128 var $parent = $(this).parent(); 129 var $parentLi = $parent.parent(); 130 $parent.toggleClass('opened'); 131 if($parent.addClass('active') && $(this).next('.first-level').is(":visible")){ 132 $(this).next('.first-level').slideUp(); 133 $parent.removeClass('active'); 134 $(this).attr({'aria-expanded': 'false'}); 135 } else { 136 $(this).attr({'aria-expanded': 'true'}); 137 $(".first-level").slideUp("slow"); 138 $parent.addClass('active'); 139 $(this).next('.first-level').slideToggle(); 140 } 141 } 142 }); 143 $(".toggle2").on("click keydown",function(e) { 144 if (e.keyCode === 13 || e.type === 'click') { 145 e.preventDefault(); 146 var $parent = $(this).parent(); 147 var $parentLi = $parent.parent(); 148 $parent.toggleClass('opened2'); 149 if($parent.addClass('active') && $(this).next('.second-level').is(":visible")){ 150 $(this).next('.second-level').slideUp(); 151 $parent.removeClass('active'); 152 $(this).attr({'aria-expanded': 'false'}); 153 } else { 154 $(this).attr({'aria-expanded': 'true'}); 155 $(".second-level").slideUp("slow"); 156 $parent.addClass('active'); 157 $(this).next('.second-level').slideToggle(); 158 } 159 } 160 }); 161 162 // close nav if left 163 $(".desktop *").focus(function(e){
164 var $opened = $(".opened"); 165 var $opened2 = $(".opened2"); 166 if( $opened.length > 0 || $opened2.length > 0 ) { 167 if( $(".opened :focus").length < 1 ){ 168 $opened.children("ul").slideUp(); 169 $opened.removeClass("opened"); 170 $(".opened2").removeClass("opened2"); 171 } 172 if( $(".opened2 :focus").length < 1 ){ 173 $opened2.children("ul").slideUp(); 174 $opened2.removeClass("opened2"); 175 } 176 } 177 }); 178 179 // Flyout 180 var flyout = $('#flyout'), 181 flyoutwrap = $('#flyout-wrap'); 182 183 if (flyout.text().length){ 184 flyoutwrap.prepend('<div id="flyout-toggle" class="d-lg-none"><i class="fa fa-bars"></i> Sub Menu</div>'); 185 } 186 187 $("#flyout-toggle").on("click", function(){ 188 flyout.slideToggle(); 189 $(this).toggleClass("active"); 190 }); 191 192 193 function fillSide(){ 194 var whiteSpace = parseFloat($('.container').css('margin-right')) + 15; 195 $('.fillLeft').css('margin-left',-whiteSpace); 196 $('.fillLeft.withPadding').css('padding-left',whiteSpace); 197 $('.fillRight').css('margin-right',-whiteSpace); 198 $('.fillRight.withPadding').css('padding-right',whiteSpace); 199 } 200 fillSide(); 201 $window.resize(fillSide); 202 203 /* 204 * E-Notify Auto submit 205 */ 206 $.urlParam=function(n){var e=new RegExp("[?&]"+n+"=([^]*)").exec(window.location.href);return null==e?null:e[1]||0}; 207 var $enotify = $('iframe[src*="/revize/plugins/notify/notify.jsp"]'); 208 if( $enotify.length > 0 ){ 209 var emailStr = $.urlParam("email"); 210 if( emailStr != null ){ 211 $enotify.attr("src", $enotify.attr("src") + "&email=" + emailStr); 212 } 213 } 214 215 // Make sure all calendars have unique ids 216 $('iframe[name="calendar"]').each(function (index, calendar) { 217 calendar.id = 'calendar-' + index; 218 }); 219 220 // Start Frame Resizer 221 function resizeIframe(height, frameElement) { 222 if ( frameElement ) { 223 frameElement.height = ""; 224 frameElement.height = height; 225 } 226 } 227 228 var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent"; 229 var eventHandler = window[eventMethod]; 230 var messageEvent = eventMethod === "attachEvent" ? "onmessage" : "message"; 231 eventHandler(messageEvent, function (e) { 232 if ( Array.isArray(e.data) ) { 233 if( e.data[0] === "setCalHeight" || e.data[0] === "setNotifyHeight") { 234 var frames = document.querySelectorAll('iframe'); 235 for( var i = 0; i < frames.length; i++ ) { 236 if( frames[i].contentWindow === e.source ){ 237 resizeIframe(e.data[1], frames[i]); 238 } 239 } 240 } 241 } 242 }); 243 // End Frame Resizer 244 245 // Alert Close Caching 246 if ($("div.alert").length) { 247 var hide = window.sessionStorage && parseInt(window.sessionStorage.getItem("alertClosed")) > 1; 248 if (!hide || $(".user-logged-in").length != 0) { 249 $("div.alert").addClass('show'); 250 } 251 $("div.alert button.close").on('click', function(e) { 252 if (window.sessionStorage) { 253 window.sessionStorage.setItem("alertClosed",parseInt(window.sessionStorage.getItem("alertClosed")||0)+1); 254 } 255 }); 256 } 257 258 var $translateButton = $('.translate-button'); 259 $translateButton.on('click', function(e) { 260 // Check if the event is a click or Enter key press 261 $(this).next('ul').stop().fadeToggle(); 262 $(this).toggleClass('toggled'); 263 $translateButton = $(this); 264 // Update the aria-expanded attribute based on its current value 265 $(this).attr('aria-expanded', function(_, attr) { 266 return attr === 'true' ? 'false' : 'true'; 267 }); 268 }); 269 270 $('.translation-links ul').on('mouseleave',function(){ 271 $(this).fadeOut(); 272 $translateButton.attr('aria-expanded', false); 273 $('header .translate-button').removeClass('toggled'); 274 }); 275 $('.search-tabs ul').on('mouseleave',function(){ 276 $(this).fadeOut(); 277 $('.search-tabs-toggle').removeClass('toggled'); 278 }); 279 280 function removeCookieString(value, domain) { 281 domain = domain ? 'domain='+domain+'; ' : ''; 282 return value+'; expires=Thu, 01 Jan 1970 00:00:01 GMT; '+domain+'path=/'; 283 } 284 285 function unsetGoogtransCookie() { 286 for (var domains = window.location.hostname.split('.'); domains.length >= 2; domains.shift()) { 287 var cookieString = removeCookieString('googtrans=unset', domains.join('.')); 288 document.cookie=cookieString; 289 if (domains.length === 2) { 290 cookieString = removeCookieString('googtrans=unset', '.'+domains.join('.')); 291 document.cookie=cookieString; 292 } 293 }
294 document.cookie=removeCookieString('googtrans=unset'); 295 } 296 297 if (document.cookie.split(';').some(function(item) { return item.trim().startsWith('googtrans=/auto/en'); })) { 298 unsetGoogtransCookie(); 299 } 300 301 // Translate Script 302 var translateURL = "//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"; 303 $.getScript(translateURL); 304 $('.translation-links a').click(function() { 305 var lang = $(this).data('lang'); 306 var $frame = $('iframe.skiptranslate'); 307 308 var frameId = $frame.attr("id"); 309 if (lang === 'English') { 310 if (frameId) { 311 $frame.contents().find("#\\"+frameId.replace(".container", "\\.restore")).click(); 312 return false; 313 }; 314 } 315 316 if (!$frame.length) { 317 return false; 318 } 319 320 var $el = $frame.contents().find('span.text:contains(' + lang + ')').parents("a").get(0); 321 if (!$el) { 322 $el = $frame.contents().find('span.text:contains("English")').parents("a").get(0); 323 } 324 325 if (frameId) { 326 var $confirm = $frame.contents().find("#\\"+frameId.replace(".container", "\\.promptSection")); 327 if ($confirm.css("display") !== "none") { 328 $confirm.find("#\\"+frameId.replace(".container", "\\.confirm")).click(); 329 setTimeout(function() { $el.click(); }, 500); 330 return false; 331 } 332 } 333 $el.click(); 334 335 return false; 336 }); 337 338 // Tiny Slider 339 if (typeof tns !== "undefined") { 340 341 function sliderHeight(){ 342 var headerHeight = $('#main-header').outerHeight(); 343 var windowHeight = $(window).outerHeight(); 344 var totalHeight = windowHeight - headerHeight; 345 346 if($(window).width() < 992 || $(window).width() > 1920){ 347 $('#slider').css('min-height',totalHeight); 348 } else { 349 $('#slider').css('min-height','initial'); 350 } 351 } 352 sliderHeight(); 353 $window.resize(sliderHeight); 354 355 $('.tiny-slider').each(function(i, el) { 356 tns({ 357 autoplay: true, 358 autoplayTimeout: 8000, 359 container: el, 360 items: 1, 361 lazyload: true, 362 lazyloadSelector: '.tns-lazy-img', // accompanied with data src or data-style 363 mode: "gallery", 364 preventScrollOnTouch: 'force', 365 nav: false, 366 controlsText: [ 367 '<i class="fa fa-long-arrow-left" aria-hidden="true"></i>', 368 '<i class="fa fa-long-arrow-right" aria-hidden="true"></i>' 369 ], 370 autoplayButtonOutput: false, 371 touch: false 372 }); 373 }); 374 375 $('#quick-links .tiny-carousel').each(function(i, el) { 376 var qlinksCount = $('.qlink').length; 377 var $el = $(el); 378 var tinyItemCount = $el.children().length; 379 var tinyItemData = $el.data('tinyItems') ? $el.data('tinyItems') : 6; 380 tns({ 381 container: el, 382 items: Math.min(tinyItemCount, tinyItemData), 383 lazyload: true, 384 lazyloadSelector: '.tns-lazy-img', // accompanied with data src or data-style 385 preventScrollOnTouch: 'force', 386 nav: false, 387 controlsText: [ 388 '<i class="fa fa-long-arrow-left" aria-hidden="true"></i>', 389 '<i class="fa fa-long-arrow-right" aria-hidden="true"></i>' 390 ], 391 autoplayButtonOutput: false, 392 responsive: { 393 1367: { 394 items: (qlinksCount >= 5 ? 5 : qlinksCount) 395 }, 396 1199: { 397 items: (qlinksCount >= 4 ? 4 : qlinksCount) 398 }, 399 991: { 400 items: (qlinksCount >= 3 ? 3 : qlinksCount) 401 }, 402 767: { 403 items: (qlinksCount >= 2 ? 2 : qlinksCount) 404 }, 405 0: { 406 items: 1 407 } 408 }, 409 loop: false, 410 controlsContainer: '#qlinks-controls', 411 touch: true 412 }); 413 }); 414 415 $('#news .tiny-carousel').each(function(i, el) { 416 var newsCount = $('.news').length; 417 var $el = $(el); 418 var tinyItemCount = $el.children().length; 419 var tinyItemData = $el.data('tinyItems') ? $el.data('tinyItems') : 6; 420 tns({ 421 container: el, 422 items: Math.min(tinyItemCount, tinyItemData), 423 lazyload: true, 424 lazyloadSelector: '.tns-lazy-img', // accompanied with data src or data-style 425 preventScrollOnTouch: 'force', 426 nav: false, 427 controlsText: [ 428 '<i class="fa fa-long-arrow-left" aria-hidden="true"></i>', 429 '<i class="fa fa-long-arrow-right" aria-hidden="true"></i>' 430 ], 431 autoplayButtonOutput: false, 432 responsive: { 433 991: { 434 items: (newsCount >= 3 ? 3 : newsCount) 435 }, 436 767: { 437 items: (newsCount >= 2 ? 2 : newsCount) 438 }, 439 0: { 440 items: 1 441 } 442 }, 443 loop: false, 444 gutter: 30, 445 controlsContainer: '#news-controls', 446 touch: false 447 }); 448 }); 449 450 if (window.bookRiver) { 451 (async function() { 452 var didRiver = await loadBookRiver(); 453 if (didRiver) { 454 $('#books .tiny-carousel').each(function(i, el) { 455 var bookCount = $('.book').length; 456 var $el = $(el); 457 var tinyItemCount = $el.children().length; 458 var tinyItemData = $el.data('tinyItems') ? $el.data('tinyItems') : 6; 459 tns({ 460 container: el, 461 items: Math.min(tinyItemCount, tinyItemData), 462 lazyload: true, 463 lazyloadSelector: '.tns-lazy-img', // accompanied with data src or data-style 464 preventScrollOnTouch: 'force', 465 nav: false, 466 controlsText: [ 467 '<i class="fa fa-long-arrow-left" aria-hidden="true"></i>', 468 '<i class="fa fa-long-arrow-right" aria-hidden="true"></i>' 469 ], 470 autoplayButtonOutput: false, 471 responsive: { 472 1199: { 473 items: (bookCount >= 5 ? 5 : bookCount) 474 }, 475 991: { 476 items: (bookCount >= 4 ? 4 : bookCount), 477 gutter: 63 478 }, 479 480: { 480 items: (bookCount >= 3 ? 3 : bookCount), 481 gutter: 40 482 }, 483 0: { 484 items: (bookCount >= 2 ? 2 : bookCount), 485 gutter: 30 486 } 487 }, 488 loop: false, 489 controlsContainer: '#books-controls', 490 touch: false 491 });
492 }); 493 } 494 })(); 495 } 496 } 497 498 // Responsive Tables 499 $('.post table:not(.layout-table):not(.not-responsive)').wrap('<div class="table-responsive"></div>'); 500 $('.layout-table').attr('role', 'presentation'); 501 502 $window.ready(function(){ 503 504 if ($('.translation-links').parent().attr('flex-order') == '2'){ 505 $('.search').parent().css({ 506 'flex':'0', 507 'margin-left':'15px' 508 }); 509 510 } 511 512 // sets the order of each .header-col item depending on the value of it's flex-order attribute 513 $('.header-col').each(function(){ 514 $(this).css('order',$(this).attr('flex-order')); 515 $(this).css('justify-content',$(this).attr('justify-content')) 516 }); 517 518 519 // matchHeight 520 if(typeof $.fn.matchHeight !== "undefined"){ 521 $('.equal').matchHeight({ 522 //defaults 523 byRow: true, 524 property: 'height', // height or min-height 525 target: null, 526 remove: false 527 }); 528 } 529 530 // Animations http://www.oxygenna.com/tutorials/scroll-animations-using-waypoints-js-animate-css 531 function onScrollInit( items, trigger ) { 532 items.each( function() { 533 var osElement = $(this), 534 osAnimationClass = osElement.data('os-animation'), 535 osAnimationDelay = osElement.data('os-animation-delay'); 536 537 osElement.css({ 538 '-moz-animation-delay': osAnimationDelay, 539 'animation-delay': osAnimationDelay, 540 '-webkit-animation-delay': osAnimationDelay 541 }); 542 543 var osTrigger = ( trigger ) ? trigger : osElement; 544 545 if(typeof $.fn.waypoint !== "undefined"){ 546 osTrigger.waypoint(function() { 547 osElement.addClass('animated').addClass(osAnimationClass); 548 },{ 549 triggerOnce: true, 550 offset: '100%' 551 }); 552 } 553 }); 554 } 555 onScrollInit($('.os-animation')); 556 557 //#Smooth Scrolling 558 $('a[href*="#"]').not('[href="#"]').not('[href*="#collapse"]').not('[data-toggle*="collapse"]').click(function(event) { 559 if (location.pathname.replace(/^\//,'') === this.pathname.replace(/^\//,'') && location.hostname === this.hostname) { 560 var target = $(this.hash); 561 target = target.length ? target : $('[name=' + this.hash.slice(1) +']'); 562 if (target.length) { 563 event.preventDefault(); 564 $('html,body').animate({ 565 scrollTop: target.offset().top 566 }, 1000, function() { 567 var $target = $(target); 568 $target.focus(); 569 if ($target.is(":focus")) { 570 return false; 571 } else { 572 $target.attr('tabindex','-1'); 573 $target.focus(); 574 $target.removeAttr('tabindex'); 575 }; 576 }); 577 } 578 } 579 }); 580 581 /*global jQuery */ 582 /*! 583 * FlexVerticalCenter.js 1.0 584 * 585 * Copyright 2011, Paul Sprangers http://paulsprangers.com 586 * Released under the WTFPL license 587 * http://sam.zoy.org/wtfpl/ 588 * 589 * Date: Fri Oct 28 19:12:00 2011 +0100 590 */ 591 $.fn.flexVerticalCenter = function( options ) { 592 var settings = $.extend({ 593 cssAttribute: 'margin-top', // the attribute to apply the calculated value to 594 verticalOffset: 0, // the number of pixels to offset the vertical alignment by 595 parentSelector: null, // a selector representing the parent to vertically center this element within 596 debounceTimeout: 25, // a default debounce timeout in milliseconds 597 deferTilWindowLoad: false // if true, nothing will take effect until the $(window).load event 598 }, options || {}); 599 600 return this.each(function(){ 601 var $this = $(this); // store the object 602 var debounce; 603 604 // recalculate the distance to the top of the element to keep it centered 605 var resizer = function () { 606 607 var parentHeight = (settings.parentSelector && $this.parents(settings.parentSelector).length) ? 608 $this.parents(settings.parentSelector).first().height() : $this.parent().height(); 609 610 $this.css( 611 settings.cssAttribute, ( ( ( parentHeight - $this.height() ) / 2 ) + parseInt(settings.verticalOffset) ) 612 ); 613 }; 614 615 // Call on resize. Opera debounces their resize by default. 616 $(window).resize(function () { 617 clearTimeout(debounce); 618 debounce = setTimeout(resizer, settings.debounceTimeout); 619 }); 620 621 if (!settings.deferTilWindowLoad) { 622 // call it once, immediately. 623 resizer(); 624 } 625 626 // Call again to set after window (frames, images, etc) loads. 627 $(window).on('load', function () { 628 resizer(); 629 }); 630 631 }); 632 633 }; 634 $('.v-align').flexVerticalCenter(); 635 636 637 // ADA, remove #flyout title if it doesnt have text 638 if (!$.trim($('#flyout').text())) { 639 // Remove the element if it has no text 640 $('#flyout').remove(); 641 } 642 643 // ADA, remove this element if it doesnt have text 644 $('#main-footer h2').each(function() { 645 if ($(this).text().trim() === '') { 646 $(this).remove(); // Remove the <h2> element if it has no text 647 } 648 }); 649 650 // ADA, remove this element if it doesnt have text 651 $('#holiday-left h2').each(function() { 652 if ($(this).text().trim() === '') { 653 $(this).remove(); // Remove the <h2> element if it has no text 654 } 655 }); 656 657 658 // ADA, add aria-label to slider controls 659 $("#books-controls button:first-child").attr("aria-label", "Previous Book"); 660 $("#books-controls button:last-child").attr("aria-label", "Next Book"); 661 $("#qlinks-controls button:first-child").attr("aria-label", "Previous Link"); 662 $("#qlinks-controls button:last-child").attr("aria-label", "Next Link"); 663 $(".tns-controls button:first-child").attr("aria-label", "Previous Link"); 664 $(".tns-controls button:last-child").attr("aria-label", "Next Link"); 665 $("#news-controls button:first-child").attr("aria-label", "Previous News"); 666 $("#news-controls button:last-child").attr("aria-label", "Next News"); 667 668 // ADA, If translate list is open and user presses escape, close dropdown 669 $(document).on("keydown", function (event) { 670 if (event.key === "Escape" && $(".translation-links li ul li a:focus").length) { 671 const $focusedItem = $(".translation-links li ul li a:focus"); 672 const $currentMenu = $focusedItem.closest("ul"); 673 $currentMenu.css("display", "none"); 674 const $translateButton = $currentMenu.siblings("button"); 675 $translateButton.removeClass("toggled").attr("aria-expanded", "false").focus(); 676 } 677 }); 678 679 // ADA, close menu on escape key (desktop nav) 680 $(document).on("keydown", "ul.menuUL.level1", function (e) { 681 if (e.keyCode === 27 && $("ul.menuUL.level1").is(":visible") && $(window).width() > 992) {
682 $("ul.menuUL.level1").slideUp(); 683 $(this).focus(); 684 } 685 }); 686 687 // ADA, close menu on escape key (mobile nav) 688 $(document).on("keydown", "#nav", function (e) { 689 if (e.keyCode === 27 && $("#nav").is(":visible") && $(window).width() < 992) { 690 $("#nav").slideUp(); 691 $("#nav-toggle").removeClass("fa-close").addClass("fa-bars"); 692 $("#nav-toggle").focus(); 693 } 694 }); 695 696 697 // ADA, Ensure when user opens news modal, when closed it returns focus to the last focused element, instead of the first element in the page 698 var $lastFocusedElement; 699 $(document).on("keydown", ".mini-event", function (e) { 700 if (e.key === "Enter") { 701 // Store a reference to the last focused element 702 $lastFocusedElement = $(this); 703 } 704 }); 705 706 $(document).on("click", ".mini-event", function (e) { 707 // Store a reference to the last focused element 708 $lastFocusedElement = $(this); 709 }); 710 711 $(document).on("keydown", function (e) { 712 if (e.key === "Escape" && $("#event-modal").css("display") === "block") { 713 closeModalAndRefocus(); 714 } 715 }); 716 717 $("#event-modal-dialog > div > div.modal-footer > button.btn.btn-secondary").on("click", function () { 718 closeModalAndRefocus(); 719 }); 720 721 function closeModalAndRefocus() { 722 $("#event-modal").css("display", "none"); // Close the modal (if using Bootstrap modal) 723 if ($lastFocusedElement) { 724 $lastFocusedElement.focus(); 725 } 726 } 727 // ^^ADA, Ensure when user opens news modal, when closed it returns focus to the last focused element, instead of the first element in the page^^ 728 729 // ADA, User presses enter on calendar event on calendar page in list view, open modal set last clicked item 730 $(document).on("keydown", ".fc-day-number, .fc-content, .fc-list-item", function (e) { 731 if (e.which === 13) { 732 $lastFocusedElement = $(this); 733 $(this).click(); 734 } 735 736 // If navigating through list view on calendar page and user presses escape, go to end of calendar 737 if (e.key === "Escape") { 738 $("#ics-export").focus(); 739 } 740 }); 741
742 // ADA, make arrow/buttons visibile when focused (Similar to mouse hover) 743 function handleFocusOnControls() { 744 // Slider Controls 745 $(".tns-controls").on("focusin", function () { 746 $(this).find("button").css("opacity", "1"); 747 $(this).css("z-index", "1000"); 748 }); 749 $(".tns-controls").on("focusout", function () { 750 $(this).find("button").css("opacity", "0"); 751 $(this).css("z-index", "auto"); 752 }); 753 754 // Quick Link Controls 755 $("#qlinks-controls").on("focusin", function () { 756 $(this).css("z-index", "1000"); 757 }); 758 $("#qlinks-controls").on("focusout", function () { 759 $(this).css("z-index", "auto"); 760 }); 761 762 // News Link Controls 763 $("#news-controls").on("focusin", function () { 764 $(this).css("z-index", "1000"); 765 }); 766 $("#news-controls").on("focusout", function () { 767 $(this).css("z-index", "auto"); 768 }); 769 } 770 771 function observeTinyItems() { 772 // Select all elements with the class .tiny-item 773 var tinyItems = document.querySelectorAll(".tiny-item"); 774 775 // Create a MutationObserver instance 776 var tinyItemObserver = new MutationObserver(function (mutationsList) { 777 mutationsList.forEach(function (mutation) { 778 if (mutation.type === "attributes" && mutation.attributeName === "class") { 779 var $target = $(mutation.target); 780 781 if ($target.hasClass("tns-slide-active")) { 782 // tns-slide-active class is added 783 $target.find("a").attr("tabindex", "0"); 784 } else { 785 // tns-slide-active class is removed 786 $target.find("a").attr("tabindex", "-1"); 787 } 788 } 789 }); 790 }); 791 792 // Configure the observer to watch for attribute changes 793 var tinyItemConfig = { 794 attributes: true, 795 attributeFilter: ["class"], 796 subtree: false, 797 }; 798 799 // Attach the observer to each .tiny-item element 800 tinyItems.forEach(function (item) { 801 tinyItemObserver.observe(item, tinyItemConfig); 802 }); 803 804 // Initial setup: Set tabindex to -1 for elements that don't have the tns-slide-active class 805 $(".tiny-item").each(function () { 806 if (!$(this).hasClass("tns-slide-active")) { 807 $(this).find("a").attr("tabindex", "-1"); 808 } else { 809 $(this).find("a").attr("tabindex", "0"); 810 } 811 }); 812 } 813 814 function setTabindexOnCalendarRows() { 815 // Select the calendar element to observe 816 const calendar = document.querySelector("#calendar"); 817 818 // If the calendar is already in the DOM 819 if (calendar) { 820 var listItems = $("#calendar tr.fc-list-item"); 821 822 // This should probably be somewhere else. 823 $(".fc-day-number").attr("tabindex", "0"); 824 $(".fc-content").attr("tabindex", "0"); 825 $(".fc-list-item").attr("tabindex", "0"); 826 827 if (listItems.length > 0) { 828 listItems.each(function () { 829 $(this).attr("tabindex", "0"); 830 }); 831 } 832 } 833 834 // Create a mutation observer to watch for changes in the #calendar element 835 const observer = new MutationObserver(function (mutations) { 836 mutations.forEach(function (mutation) { 837 // Check if there are any .fc-list-item rows added 838 const newRows = $(mutation.target).find("tr.fc-list-item"); 839 840 // Set tabindex=0 for the newly added rows 841 newRows.each(function () { 842 const row = $(this); 843 const title = row.find(".fc-list-item-title").text().trim(); 844 const time = row.find(".fc-list-item-time").text().trim(); 845 row.attr("tabindex", "0"); 846 row.attr("aria-label", time + " " + title); 847 }); 848 849 // This should probably be somewhere else. 850 $(".fc-day-number").attr("tabindex", "0"); 851 $(".fc-content").attr("tabindex", "0"); 852 $(".fc-list-item").attr("tabindex", "0"); 853 }); 854 }); 855 856 // Start observing the #calendar for child changes (when rows are added) 857 if (calendar) { 858 observer.observe(calendar, { childList: true, subtree: true }); 859 } 860 } 861 862 observeTinyItems();
863 handleFocusOnControls(); 864 setTabindexOnCalendarRows(); 865 }); // Ready 866})(jQuery); 867 868})(jQuery);
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.