1"use strict"; 2 3/** 4 * Aria Plugin 5 * Author: Stephan Fischer 6 * @since 2.0.0 7 */ 8;(function ($, window, document, undefined) 9{ 10 let Aria = function(scope) 11 { 12 this._core = scope; 13 this.options = $.extend({}, Aria.Defaults, this._core.options); 14 15 if (!this.options.aria) { 16 return false; 17 } 18 19 this.setup(); 20 this.$element.on( 21 { 22 'initialized.owl.carousel': e => 23 { 24 if (e.namespace && !this._init) { 25 this.$stage = this._core.$stage; 26 this.navigation(); 27 this.bind(); 28 this.setAria(); 29 this._init = true; 30 } 31 }, 32 'changed.owl.carousel': e => this.setAria() 33 }); 34 } 35 36 Aria.Defaults = 37 { 38 aria: true 39 }; 40 41 Aria.prototype.setup = function() 42 { 43 this._init = false; 44 this.$element = this._core.$element; 45 this.$element.attr('tabindex', '0').storeTabindex(); 46 this.$element.find('*').storeTabindex(); 47 }; 48 49 Aria.prototype.navigation = function() 50 { 51 this.$nav = $('.' + 52 this.options.navContainerClass + ', .' + 53 this.options.dotsClass, this.$element); 54 const noButtonSel = ":not(button):not(input[type='submit'])"; 55 56 this.setNavAria(); 57 58 $("." + this.options.dotsClass).children().attr("aria-hidden", "true"); 59 $("." + this.options.dotsClass).children().attr("aria-label", "Navigationsanzeige"); 60 61 this.$nav.children() 62 .attr("role", "button") 63 .storeTabindex().filter(noButtonSel).each((i, e) => 64 { 65 const $el = $(e); 66 67 $el.on('keydown', e => 68 { 69 if (e.keyCode === 32 || e.keyCode === 13) { 70 $el.trigger('click'); 71 return false; 72 } 73 }); 74 }); 75 } 76 77 Aria.prototype.bind = function() 78 { 79 80 this.$element.on('to.owl.carousel', (e) => e.stopPropagation()); 81 this.$element.on('next.owl.carousel', (e) => e.stopPropagation()); 82 this.$element.on('prev.owl.carousel', (e) => e.stopPropagation()); 83 this.$element.on('destroy.owl.carousel', (e) => e.stopPropagation()); 84 this.$element 85 .on('focusin', (e) => this.focus(e)) 86 .on('focusout', (e) => this.blur(e)) 87 .on('keydown', (e) => this.keydown(e)); 88 }; 89 90 Aria.prototype.focus = function() 91 { 92 this.$element.attr({'aria-live': 'polite'}); 93 }; 94 95 Aria.prototype.blur = function() 96 { 97 this.$element.attr({'aria-live': 'off'}); 98 }; 99 100 Aria.prototype.keydown = function(e) 101 { 102 let action = null; 103 104 if (e.keyCode == 37 || e.keyCode == 38) { 105 action = 'prev.owl.carousel'; 106 } else if (e.keyCode == 39 || e.keyCode == 40) { 107 action = 'next.owl.carousel'; 108 } 109 110 if (action !== null) { 111 this.$element.trigger(action); 112 return false; 113 } 114 }; 115 116 Aria.prototype.setNavAria = function() 117 { 118 this.$nav.children().each((i, el) => 119 { 120 const $el = $(el); 121 const isDisabled = $el.hasClass('disabled') || $el.hasClass('active'); 122 123 $el.attr('aria-disabled', isDisabled ? "true": "false"); 124 125 if (isDisabled) { 126 $el.attr("tabindex", "-1"); 127 $el.attr("data-tabindex", $el.attr('tabindex')); 128 } else { 129 130 $el.attr("tabindex", "0"); 131 $el.attr("data-tabindex", $el.attr('tabindex')); 132 } 133 }); 134 }; 135 136 Aria.prototype.setAria = function() 137 { 138 if (!this.$stage || !this.$stage.length) { 139 return false; 140 } 141 142 this.setNavAria(); 143 144 setTimeout(() => 145 { 146 this.$stage.children().each((i, el) => 147 { 148 const $item = $(el); 149 const isActive = $item.hasClass('active'); 150 151 if ($item) { 152 153 } 154 155 $item.attr('aria-hidden', !isActive ? "true" : "false"); 156 $item.attr('tabindex', !isActive ? '-1' : '0').attr('data-tabindex', !isActive ? '-1' : '0'); 157 $item.find('.anchor-links').attr('tabindex', !isActive ? '-1' : '0').attr('data-tabindex', !isActive ? '-1' : '0'); 158 159 // almost works without this --> needs fix 160 $item.find('a').each((i, e) => 161 { 162 const $el = $(e); 163 164 if (isActive === false) { 165 $el.storeTabindex(); 166 $el.attr("tabindex", "-1"); 167 } else { 168 $el.restoreTabindex(); 169 } 170 }); 171 }); 172 }); 173 } 174 175 Aria.prototype.destroy = function() 176 { 177 this.$element.removeAttr('aria-live'); 178 this.$element.removeAttr('tabindex'); 179 this.$element.children().removeAttr('aria-hidden'); 180 this.$element.find('[data-tabindex]').restoreTabindex(); 181 this.$element 182 .off('focusin', (e) => this.focus(e)) 183 .off('focusout', (e) => this.blur(e)) 184 .off('keydown', (e) => this.keydown(e)); 185 }; 186 187 $.fn.extend({ 188 restoreTabindex: function() 189 { 190 return this.each(function() 191 { 192 const $el = $(this); 193 194 if (!$el.is('[data-tabindex]')) { 195 $el.removeAttr("tabindex"); 196 } else { 197 $el.attr("tabindex", $el.attr('data-tabindex')); 198 } 199 }); 200 }, 201 storeTabindex: function() { 202 return this.each(function() 203 { 204 const $el = $(this); 205
206 if ($el.is('[tabindex]') && !$el.is('[data-tabindex]')) { 207 $el.attr("data-tabindex", $el.attr('tabindex')); 208 } 209 }); 210 } 211 }); 212 213 $.fn.owlCarousel.Constructor.Plugins['Aria'] = Aria; 214})( window.Zepto || window.jQuery, window, document );
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.