/*! bootstrap-accessibility-plugin - v1.0.6 - 2020-05-07 * https://github.com/paypal/bootstrap-accessibility-plugin * Copyright (c) 2020 PayPal Accessibility Team; Licensed BSD */ !function ($) { "use strict"; var uniqueId = function (prefix) { return (prefix || "ui-id") + "-" + Math.floor(1e3 * Math.random() + 1) }, focusable = function (element, isTabIndexNotNaN) { var map, mapName, img, nodeName = element.nodeName.toLowerCase(); return "area" === nodeName ? (map = element.parentNode, mapName = map.name, element.href && mapName && "map" === map.nodeName.toLowerCase() ? (img = $("img[usemap='#" + mapName + "']")[0], !!img && visible(img)) : !1) : (/input|select|textarea|button|object/.test(nodeName) ? !element.disabled : "a" === nodeName ? element.href || isTabIndexNotNaN : isTabIndexNotNaN) && visible(element) }, visible = function (element) { return $.expr.filters.visible(element) && !$(element).parents().addBack().filter(function () { return "hidden" === $.css(this, "visibility") }).length }; $.extend($.expr[":"], { data: $.expr.createPseudo ? $.expr.createPseudo(function (dataName) { return function (elem) { return !!$.data(elem, dataName) } }) : function (elem, i, match) { return !!$.data(elem, match[3]) }, focusable: function (element) { return focusable(element, !isNaN($.attr(element, "tabindex"))) }, tabbable: function (element) { var tabIndex = $.attr(element, "tabindex"), isTabIndexNaN = isNaN(tabIndex); return (isTabIndexNaN || tabIndex >= 0) && focusable(element, !isTabIndexNaN) } }), $(".modal-dialog").attr({role: "document"}); var modalhide = $.fn.modal.Constructor.prototype.hide; $.fn.modal.Constructor.prototype.hide = function () { modalhide.apply(this, arguments), $(document).off("keydown.bs.modal") }; var modalfocus = $.fn.modal.Constructor.prototype.enforceFocus; $.fn.modal.Constructor.prototype.enforceFocus = function () { var $content = this.$element.find(".modal-content"), focEls = $content.find(":tabbable"), $lastEl = $(focEls[focEls.length - 1]), $firstEl = $(focEls[0]); $lastEl.on("keydown.bs.modal", $.proxy(function (ev) { 9 !== ev.keyCode || ev.shiftKey | ev.ctrlKey | ev.metaKey | ev.altKey || (ev.preventDefault(), $firstEl.focus()) }, this)), $firstEl.on("keydown.bs.modal", $.proxy(function (ev) { 9 === ev.keyCode && ev.shiftKey && (ev.preventDefault(), $lastEl.focus()) }, this)), modalfocus.apply(this, arguments) }; var $par, firstItem, toggle = "[data-toggle=dropdown]", focusDelay = 200, menus = $(toggle).parent().find("ul").attr("role", "menu"), lis = menus.find("li").attr("role", "presentation"); lis.find("a").attr({role: "menuitem", tabIndex: "-1"}), $(toggle).attr({ "aria-haspopup": "true", "aria-expanded": "false" }), $(toggle).parent().on("shown.bs.dropdown", function (e) { $par = $(this); var $toggle = $par.find(toggle); $toggle.attr("aria-expanded", "true"), $toggle.on("keydown.bs.dropdown", $.proxy(function (ev) { setTimeout(function () { firstItem = $(".dropdown-menu [role=menuitem]:visible", $par)[0]; try { firstItem.focus() } catch (ex) { } }, focusDelay) }, this)) }).on("hidden.bs.dropdown", function (e) { $par = $(this); var $toggle = $par.find(toggle); $toggle.attr("aria-expanded", "false") }), $(document).on("focusout.dropdown.data-api", ".dropdown-menu", function (e) { var $this = $(this), that = this; $this.parent().hasClass("open") && setTimeout(function () { $.contains(that, document.activeElement) || $this.parent().find("[data-toggle=dropdown]").dropdown("toggle") }, 150) }).on("keydown.bs.dropdown.data-api", toggle + ", [role=menu]", $.fn.dropdown.Constructor.prototype.keydown); var $tablist = $(".nav-tabs, .nav-pills"), $lis = $tablist.children("li"), $tabs = $tablist.find('[data-toggle="tab"], [data-toggle="pill"]'); $tabs && ($tablist.attr("role", "tablist"), $lis.attr("role", "presentation"), $tabs.attr("role", "tab")), $tabs.each(function (index) { var tabpanel = $($(this).attr("href")), tab = $(this), tabid = tab.attr("id") || uniqueId("ui-tab"); tab.attr("id", tabid), tab.parent().hasClass("active") ? (tab.attr({ tabIndex: "0", "aria-selected": "true", "aria-controls": tab.attr("href").substr(1) }), tabpanel.attr({ role: "tabpanel", tabIndex: "0", "aria-hidden": "false", "aria-labelledby": tabid })) : (tab.attr({ tabIndex: "-1", "aria-selected": "false", "aria-controls": tab.attr("href").substr(1) }), tabpanel.attr({role: "tabpanel", tabIndex: "-1", "aria-hidden": "true", "aria-labelledby": tabid})) }), $.fn.tab.Constructor.prototype.keydown = function (e) { var $items, index, $this = $(this), $ul = $this.closest("ul[role=tablist] "), k = e.which || e.keyCode; if ($this = $(this), /(37|38|39|40)/.test(k)) { $items = $ul.find("[role=tab]:visible"), index = $items.index($items.filter(":focus")), (38 == k || 37 == k) && index--, (39 == k || 40 == k) && index++, 0 > index && (index = $items.length - 1), index == $items.length && (index = 0); var nextTab = $items.eq(index); "tab" === nextTab.attr("role") && nextTab.tab("show").focus(), e.preventDefault(), e.stopPropagation() } }, $(document).on("keydown.tab.data-api", '[data-toggle="tab"], [data-toggle="pill"]', $.fn.tab.Constructor.prototype.keydown); var tabactivate = $.fn.tab.Constructor.prototype.activate; $.fn.tab.Constructor.prototype.activate = function (element, container, callback) { var $active = container.find("> .active"); $active.find("[data-toggle=tab], [data-toggle=pill]").attr({ tabIndex: "-1", "aria-selected": !1 }), $active.filter(".tab-pane").attr({ "aria-hidden": !0, tabIndex: "-1" }), tabactivate.apply(this, arguments), element.addClass("active"), element.find("[data-toggle=tab], [data-toggle=pill]").attr({ tabIndex: "0", "aria-selected": !0 }), element.filter(".tab-pane").attr({"aria-hidden": !1, tabIndex: "0"}) }; var $colltabs = $('[data-toggle="collapse"]'); $colltabs.each(function (index) { var colltab = $(this), collpanel = $(colltab.attr("data-target") ? colltab.attr("data-target") : colltab.attr("href")), parent = colltab.attr("data-parent"), collparent = parent && $(parent), collid = colltab.attr("id") || uniqueId("ui-collapse"), parentpanel = collpanel.parent(), parentfirstchild = collparent ? collparent.find(".panel.panel-default:first-child") : null, hasopenpanel = collparent ? collparent.find(".panel-collapse.in").length > 0 : !1; colltab.attr("id", collid), collparent && (colltab.attr({ "aria-controls": collpanel.attr("id"), role: "tab", "aria-selected": "false", "aria-expanded": "false" }), $(collparent).find("div:not(.collapse,.panel-body), h4").attr("role", "presentation"), collparent.attr({ role: "tablist", "aria-multiselectable": "true" }), collpanel.attr({ role: "tabpanel", "aria-labelledby": collid }), !hasopenpanel && parentpanel.is(parentfirstchild) ? (colltab.attr({tabindex: "0"}), collpanel.attr({tabindex: "-1"})) : collpanel.hasClass("in") ? (colltab.attr({ "aria-selected": "true", "aria-expanded": "true", tabindex: "0" }), collpanel.attr({ tabindex: "0", "aria-hidden": "false" })) : (colltab.attr({tabindex: "-1"}), collpanel.attr({tabindex: "-1", "aria-hidden": "true"}))) }); var collToggle = $.fn.collapse.Constructor.prototype.toggle; $.fn.collapse.Constructor.prototype.toggle = function () { var href, prevTab = this.$parent && this.$parent.find('[aria-expanded="true"]'); if (prevTab) { var curTab, prevPanel = prevTab.attr("data-target") || (href = prevTab.attr("href")) && href.replace(/.*(?=#[^\s]+$)/, ""), $prevPanel = $(prevPanel), $curPanel = this.$element; this.$parent; this.$parent && (curTab = this.$parent.find('[data-toggle=collapse][href="#' + this.$element.attr("id") + '"]')), collToggle.apply(this, arguments), $.support.transition && this.$element.one($.support.transition.end, function () { prevTab.attr({ "aria-selected": "false", "aria-expanded": "false", tabIndex: "-1" }), $prevPanel.attr({"aria-hidden": "true", tabIndex: "-1"}), curTab.attr({ "aria-selected": "true", "aria-expanded": "true", tabIndex: "0" }), $curPanel.hasClass("in") ? $curPanel.attr({ "aria-hidden": "false", tabIndex: "0" }) : (curTab.attr({ "aria-selected": "false", "aria-expanded": "false" }), $curPanel.attr({"aria-hidden": "true", tabIndex: "-1"})) }) } else collToggle.apply(this, arguments) }, $.fn.collapse.Constructor.prototype.keydown = function (e) { var $items, index, $this = $(this), $tablist = $this.closest("div[role=tablist] "), k = e.which || e.keyCode; $this = $(this), /(32|37|38|39|40)/.test(k) && (32 == k && $this.click(), $items = $tablist.find("[role=tab]"), index = $items.index($items.filter(":focus")), (38 == k || 37 == k) && index--, (39 == k || 40 == k) && index++, 0 > index && (index = $items.length - 1), index == $items.length && (index = 0), $items.eq(index).focus(), e.preventDefault(), e.stopPropagation()) }, $(document).on("keydown.collapse.data-api", '[data-toggle="collapse"]', $.fn.collapse.Constructor.prototype.keydown), $(".carousel").each(function (index) { function setTablistHighlightBox() { var $tab, offset, height, width, highlightBox = {}; highlightBox.top = 0, highlightBox.left = 32e3, highlightBox.height = 0, highlightBox.width = 0; for (var i = 0; i < $tabs.length; i++) { $tab = $tabs[i], offset = $($tab).offset(), height = $($tab).height(), width = $($tab).width(), highlightBox.top < offset.top && (highlightBox.top = Math.round(offset.top)), highlightBox.height < height && (highlightBox.height = Math.round(height)), highlightBox.left > offset.left && (highlightBox.left = Math.round(offset.left)); var w = offset.left - highlightBox.left + Math.round(width); highlightBox.width < w && (highlightBox.width = w) } $tablistHighlight.style.top = highlightBox.top - 2 + "px", $tablistHighlight.style.left = highlightBox.left - 2 + "px", $tablistHighlight.style.height = highlightBox.height + 7 + "px", $tablistHighlight.style.width = highlightBox.width + 8 + "px" } var $tabpanel, $tablistHighlight, $pauseCarousel, $complementaryLandmark, $tab, i, $this = $(this), $prev = $this.find('[data-slide="prev"]'), $next = $this.find('[data-slide="next"]'), $tablist = $this.find(".carousel-indicators"), $tabs = $this.find(".carousel-indicators li"), $tabpanels = $this.find(".item"), $is_paused = !1, id_title = "id_title", id_desc = "id_desc"; for ($tablist.attr("role", "tablist"), $tabs.focus(function () { $this.carousel("pause"), $is_paused = !0, $pauseCarousel.innerHTML = "Start Image Carousel", $(this).parent().addClass("active"), setTablistHighlightBox(), $($tablistHighlight).addClass("focus"), $(this).parents(".carousel").addClass("contrast") }), $tabs.blur(function (event) { $(this).parent().removeClass("active"), $($tablistHighlight).removeClass("focus"), $(this).parents(".carousel").removeClass("contrast") }), i = 0; i < $tabpanels.length; i++) $tabpanel = $tabpanels[i], $tabpanel.setAttribute("role", "tabpanel"), $tabpanel.setAttribute("id", "tabpanel-" + index + "-" + i), $tabpanel.setAttribute("aria-labelledby", "tab-" + index + "-" + i); for ("string" != typeof $this.attr("role") && ($this.attr("role", "complementary"), $this.attr("aria-labelledby", id_title), $this.attr("aria-describedby", id_desc), $this.prepend('<p id="' + id_desc + '" class="sr-only">You can control this image carousel using your keyboard or pointing device. Use the tabs or the previous and next buttons to change the image displayed.</p>'), $this.prepend('<h2 id="' + id_title + '" class="sr-only">Carousel with ' + $tabpanels.length + " images.</h2>")), i = 0; i < $tabs.length; i++) { $tab = $tabs[i], $tab.setAttribute("role", "tab"), $tab.setAttribute("id", "tab-" + index + "-" + i), $tab.setAttribute("aria-controls", "tabpanel-" + index + "-" + i); var tpId = "#tabpanel-" + index + "-" + i, caption = $this.find(tpId).find("h1").text(); ("string" != typeof caption || 0 === caption.length) && (caption = $this.find(tpId).text()), ("string" != typeof caption || 0 === caption.length) && (caption = $this.find(tpId).find("h3").text()), ("string" != typeof caption || 0 === caption.length) && (caption = $this.find(tpId).find("h4").text()), ("string" != typeof caption || 0 === caption.length) && (caption = $this.find(tpId).find("h5").text()), ("string" != typeof caption || 0 === caption.length) && (caption = $this.find(tpId).find("h6").text()), ("string" != typeof caption || 0 === caption.length) && (caption = "no title"); var tabName = document.createElement("span"); tabName.setAttribute("class", "sr-only"), tabName.innerHTML = "Slide " + (i + 1), caption && (tabName.innerHTML += ": " + caption), $tab.appendChild(tabName) } $tablistHighlight = document.createElement("div"), $tablistHighlight.className = "carousel-tablist-highlight", document.body.appendChild($tablistHighlight), $complementaryLandmark = document.createElement("aside"), $complementaryLandmark.setAttribute("class", "carousel-aside-pause"), $complementaryLandmark.setAttribute("aria-label", "Carousel pause/start control"), $this.prepend($complementaryLandmark), $pauseCarousel = document.createElement("button"), $pauseCarousel.className = "carousel-pause-button", $pauseCarousel.innerHTML = "Pause Carousel", $pauseCarousel.setAttribute("title", "Use the pause/start carousel button to stop/start carousel animations."), $($complementaryLandmark).append($pauseCarousel), $($pauseCarousel).click(function () { $is_paused ? ($pauseCarousel.innerHTML = "Pause Carousel", $this.carousel("cycle"), $is_paused = !1) : ($pauseCarousel.innerHTML = "Start Carousel", $this.carousel("pause"), $is_paused = !0) }), $($pauseCarousel).focus(function () { $(this).addClass("focus") }), $($pauseCarousel).blur(function () { $(this).removeClass("focus") }), setTablistHighlightBox(), $(window).resize(function () { setTablistHighlightBox() }), $prev.attr("aria-label", "Previous image"), $prev.keydown(function (e) { var k = e.which || e.keyCode; /(13|32)/.test(k) && (e.preventDefault(), e.stopPropagation(), $prev.trigger("click")) }), $prev.focus(function () { $(this).parents(".carousel").addClass("contrast") }), $prev.blur(function () { $(this).parents(".carousel").removeClass("contrast") }), $next.attr("aria-label", "Next Slide"), $next.keydown(function (e) { var k = e.which || e.keyCode; /(13|32)/.test(k) && (e.preventDefault(), e.stopPropagation(), $next.trigger("click")) }), $next.focus(function () { $(this).parents(".carousel").addClass("contrast") }), $next.blur(function () { $(this).parents(".carousel").removeClass("contrast") }), $(".carousel-inner a").focus(function () { $(this).parents(".carousel").addClass("contrast") }), $(".carousel-inner a").blur(function () { $(this).parents(".carousel").removeClass("contrast") }), $tabs.each(function () { var item = $(this); item.hasClass("active") ? item.attr({ "aria-selected": "true", tabindex: "0" }) : item.attr({"aria-selected": "false", tabindex: "-1"}) }) }); var slideCarousel = $.fn.carousel.Constructor.prototype.slide; $.fn.carousel.Constructor.prototype.slide = function (type, next) { var $id, $element = this.$element, $active = $element.find("[role=tabpanel].active"), $next = next || $active[type](), $tab_count = $element.find("[role=tabpanel]").length, $prev_side = $element.find('[data-slide="prev"]'), $next_side = $element.find('[data-slide="next"]'), $index = 0, $prev_index = $tab_count - 1, $next_index = 1; $next && $next.attr("id") && ($id = $next.attr("id"), $index = $id.lastIndexOf("-"), $index >= 0 && ($index = parseInt($id.substring($index + 1), 10)), $prev_index = $index - 1, 1 > $prev_index && ($prev_index = $tab_count - 1), $next_index = $index + 1, $next_index >= $tab_count && ($next_index = 0)), $prev_side.attr("aria-label", "Show image " + ($prev_index + 1) + " of " + $tab_count), $next_side.attr("aria-label", "Show image " + ($next_index + 1) + " of " + $tab_count), slideCarousel.apply(this, arguments), $active.one("bsTransitionEnd", function () { var $tab; $tab = $element.find('li[aria-controls="' + $active.attr("id") + '"]'), $tab && $tab.attr({ "aria-selected": !1, tabIndex: "-1" }), $tab = $element.find('li[aria-controls="' + $next.attr("id") + '"]'), $tab && $tab.attr({ "aria-selected": !0, tabIndex: "0" }) }) }; $.fn.collapse.Constructor.prototype.show = function () { if (!this.transitioning && !this.$element.hasClass("in")) { var t, e = this.$parent && this.$parent.children(".panel").children(".in, .collapsing"); if (!(e && e.length && (t = e.data("bs.collapse")) && t.transitioning)) { var i = $.Event("show.bs.collapse"); if (this.$element.trigger(i), !i.isDefaultPrevented()) { e && e.length && (l.call(e, "hide"), t || e.data("bs.collapse", null)); var o = this.dimension(); this.$element.removeClass("collapse").addClass("collapsing")[o](0); // don't add aria-expanded to collapsing element in side facets if (this.$element.attr('id') === undefined || !this.$element.attr('id').startsWith("side-collapse")) { this.$element.attr("aria-expanded", !0) } this.$trigger.removeClass("collapsed").attr("aria-expanded", !0), this.transitioning = 1; var n = function () { this.$element.removeClass("collapsing").addClass("collapse in")[o](""), this.transitioning = 0, this.$element.trigger("shown.bs.collapse") }; if (!$.support.transition) return n.call(this); var s = $.camelCase(["scroll", o].join("-")); this.$element.one("bsTransitionEnd", $.proxy(n, this)).emulateTransitionEnd(350)[o](this.$element[0][s]) } } } }; $.fn.collapse.Constructor.prototype.hide = function () { if (!this.transitioning && this.$element.hasClass("in")) { var t = $.Event("hide.bs.collapse"); if (this.$element.trigger(t), !t.isDefaultPrevented()) { var e = this.dimension(); this.$element[e](this.$element[e]())[0].offsetHeight, this.$element.addClass("collapsing").removeClass("collapse in"); // don't add aria-expanded to collapsing element in side facets if (this.$element.attr('id') === undefined || !this.$element.attr('id').startsWith("side-collapse")) { this.$element.attr("aria-expanded", !1) } this.$trigger.addClass("collapsed").attr("aria-expanded", !1), this.transitioning = 1; var i = function () { this.transitioning = 0, this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse") }; if (!$.support.transition) return i.call(this); this.$element[e](0).one("bsTransitionEnd", $.proxy(i, this)).emulateTransitionEnd(350) } } }; $.fn.collapse.Constructor.prototype.addAriaAndCollapsedClass = function (t, e) { // don't add aria-expanded to collapsing element in side facets if (t.attr('id') === undefined || !t.attr('id').startsWith("side-collapse")) { var i = t.hasClass("in"); t.attr("aria-expanded", i); } e.toggleClass("collapsed", !i).attr("aria-expanded", i); }; var $this; $.fn.carousel.Constructor.prototype.keydown = function (e) { function selectTab(index) { index >= $tabs.length || 0 > index || ($carousel.carousel(index), setTimeout(function () { $tabs[index].focus() }, 150)) } $this = $this || $(this), this instanceof Node && ($this = $(this)); var index, $carousel = $(e.target).closest(".carousel"), $tabs = $carousel.find("[role=tab]"), k = e.which || e.keyCode; /(37|38|39|40)/.test(k) && (index = $tabs.index($tabs.filter(".active")), (37 == k || 38 == k) && (index--, selectTab(index)), (39 == k || 40 == k) && (index++, selectTab(index)), e.preventDefault(), e.stopPropagation()) }, $(document).on("keydown.carousel.data-api", "li[role=tab]", $.fn.carousel.Constructor.prototype.keydown) }(jQuery); $(document).on('keydown', '.dropdown-abort', function(e) { if(e.which == 13) { let toggle = $(this).parent().parent().parent().find('.dropdown-toggle'); if(toggle.not(this).length){ toggle.focus(); } } }); $(document).on('keyup', '.dropdown-abort', function(e) { if(e.which == 13) { let toggle = $(this).parent().parent().parent().find('.dropdown-toggle'); if(toggle.not(this).length){ toggle.dropdown("toggle"); } } }); /* restore focus after closing of lightbox */ $(document).on('click', '.bulkActionButtons input', function(e) { VuFind.lightbox.setOrigin(e.target); });