1/** 2 * Component accessibility 3 * makes content more accessible to people with disabilities. 4 * @module Accessibility 5 * @param {jQuery} $ Instance of jQuery 6 */ 7XA.component.accessibility = (function ($) { 8 /** 9 * This object stores all public api methods 10 * @type {Object.<Methods>} 11 * @memberOf module:Accessibility 12 * */ 13 var api = {}; 14 /** 15 * getAllIndexedElement - returns elements that have tab index attribute 16 * @returns {jQuery<DOMElement>} elements that have tab index attribute 17 */ 18 var getAllIndexedElement = function () { 19 return $("body").find("[tabindex]"); 20 }; 21 22 /** 23 * activateFirstElement - activate first element on a page that have tab index attribute 24 * active element 25 * @returns {String} component name 26 */ 27 api.activateFirstElement = function () { 28 api.indexedElements.eq(0).attr("tabindex", "0"); 29 }; 30 /** 31 * getComponentName - helper that provides component name based on 32 * active element 33 * @returns {String} component name 34 */ 35 var getComponentName = function () { 36 var $activeElement = $(document.activeElement), 37 currComponent = $activeElement.closest(".initialized"), 38 componentName = currComponent.length 39 ? currComponent.attr("class").split(" ")[1] 40 : ""; 41 return componentName; 42 }; 43 /** 44 * getWrapper - helper that provides wrapper element for 45 * active element 46 * @param {String} selector selector of parent wrapper 47 * @returns {jQuery<DOMElement>} 48 */ 49 var getWrapper = function (selector) { 50 var $activeElement = $(document.activeElement); 51 return $activeElement.closest(selector); 52 }; 53 54 /** 55 * activateTab - helper for Tabs component 56 */ 57 var activateTab = function (direction, currTab) { 58 var activatedTab = currTab; 59 if (direction == "left" && currTab.prev()) { 60 currTab.attr("tabindex", "-1"); 61 activatedTab = currTab.prev(); 62 } else if (direction == "right" && currTab.next()) { 63 currTab.attr("tabindex", "-1"); 64 activatedTab = currTab.next(); 65 } 66 activatedTab 67 .attr("tabindex", "0") 68 .trigger("click") 69 .focus(); 70 }; 71 72 /** 73 * activateItem - helper for Accordion component 74 */ 75 var activateItem = function (direction, currItem, event) { 76 var itemWrapper = currItem.closest("li.item"), 77 activatedTab = currItem, 78 nextItem = itemWrapper.next(), 79 prevItem = itemWrapper.prev(); 80 if (direction == "down" && nextItem.length) { 81 event.preventDefault(); 82 currItem.attr("tabindex", "-1"); 83 activatedTab = nextItem; 84 85 } else if (direction == "up" && prevItem.length) { 86 event.preventDefault(); 87 currItem.attr("tabindex", "-1"); 88 activatedTab = prevItem; 89 } 90 activatedTab 91 .find(".toggle-header") 92 .attr("tabindex", "0") 93 .focus(); 94 }; 95 96 /** 97 * toggleFlip - helper for Flip component 98 */ 99 var toggleFlip = function (currItem) { 100 var nextItem = currItem.next().length ? currItem.next() : currItem.prev(); 101 currItem.attr("tabindex", "-1"); 102 nextItem 103 .trigger("click") 104 .attr("tabindex", "0") 105 .focus(); 106 }; 107 108 /** 109 * componentLogic - object that contains list of components as a object key 110 * and function with logic that make this component WCAG friendly 111 * @type {Object} 112 */ 113 var componentLogic = { 114 tabs: function (keyCode) { 115 var currTab = getWrapper("li.active"); 116 if (currTab) { 117 if (keyCode == api.keys.right) { 118 activateTab("right", currTab); 119 } else if (keyCode == api.keys.left) { 120 activateTab("left", currTab); 121 } 122 } 123 }, 124 accordion: function (keyCode, isShiftPressed, event) { 125 var currItem = getWrapper("div.toggle-header"); 126 if (currItem) { 127 if (keyCode == api.keys.down) { 128 activateItem("down", currItem, event); 129 } else if (keyCode == api.keys.up) { 130 activateItem("up", currItem, event); 131 } else if (!isShiftPressed && keyCode == api.keys.tab) { 132 activateItem("down", currItem, event); 133 } else if (isShiftPressed && keyCode == api.keys.tab){ 134 activateItem("up", currItem, event); 135 } 136 } 137 }, 138 flip: function (keyCode) { 139 var currItem = getWrapper("[class*='Side']"); 140 if (currItem) {
141 if (keyCode == api.keys.right || keyCode == api.keys.left) { 142 toggleFlip(currItem); 143 } 144 } 145 } 146 }; 147 /** 148 * bindEvents method get component name by calling 149 * ["getComponentName"]{@link module:Accessibility.getComponentName} method and running apropriate to 150 * component logic 151 * @memberOf module:Accessibility 152 * @param {number} keycode keycode of pressed button on keyboard 153 * @alias module:Accessibility.bindEvents 154 * @private 155 * */ 156 var bindEvents = function (keyCode, isShiftPressed, event) { 157 var component = getComponentName(); 158 if (componentLogic[component]) { 159 componentLogic[component](keyCode, isShiftPressed, event); 160 } 161 }; 162 163 /** 164 * This object stores keycode of keyboard buttons 165 * @type {Object} 166 * @memberOf module:Accessibility 167 * @alias module:Accessibility.keys 168 * */ 169 api.keys = { 170 end: 35, 171 home: 36, 172 left: 37, 173 up: 38, 174 right: 39, 175 down: 40, 176 delete: 46, 177 enter: 13, 178 space: 32, 179 tab: 9 180 }; 181 /** 182 * indexedElements variable take list of all Indexed Element on a page by calling 183 * ["getAllIndexedElement"]{@link module:Accessibility.getAllIndexedElement} method 184 * @memberOf module:Accessibility 185 * @param {Object} properties list of properties for accordion component 186 * @alias module:Accessibility.indexedElements 187 */ 188 api.indexedElements = getAllIndexedElement(); 189 /** 190 * watchEvents method bind keyup event on document and on each trigger calls 191 * ["bindEvents"]{@link module:Accessibility.bindEvents} 192 * @memberOf module:Accessibility 193 * @alias module:Accessibility.watchEvents 194 */ 195 api.watchEvents = function () { 196 $(document).on("keydown", function (event) { 197 var keyCode = event.keyCode,
198 isShiftPressed = event.shiftKey; 199 bindEvents(keyCode, isShiftPressed, event); 200 }); 201 }; 202 /** 203 * registerLogic method register accessability logic to 204 * ["componentLogic"]{@link module:Accessibility.componentLogic} list 205 * @memberOf module:Accessibility 206 * @param {string} componentName name of component which logic should be registered 207 * @param {Function} componentFunc function for component that will be triggered for accessability support 208 * @alias module:Accessibility.registerLogic 209 */ 210 api.registerLogic = function (componentName, componentFunc) { 211 componentLogic[componentName] = componentFunc; 212 } 213 /** 214 * unregisterLogic method delete accessability logic from 215 * ["unregisterLogic"]{@link module:Accessibility.unregisterLogic} list 216 * @memberOf module:Accessibility 217 * @param {string} componentName name of component which logic should be deleted 218 * @alias module:Accessibility.unregisterLogic 219 */ 220 api.unregisterLogic = function (componentName) { 221 delete componentLogic[componentName] 222 } 223 /** 224 * getRegisteredLogic method return list of accessability logic 225 * ["unregisterLogic"]{@link module:Accessibility.unregisterLogic} list 226 * @memberOf module:Accessibility 227 * @returns {Object} list of registered components and their logic 228 * @alias module:Accessibility.getRegisteredLogic 229 */ 230 api.getRegisteredLogic = function () { 231 return componentLogic 232 } 233 /** 234 * initInstance method call 235 * ["watchEvents"]{@link module:Accessibility.watchEvents} method 236 * and call 237 * ["activateFirstElement"]{@link module:Accessibility.activateFirstElement} 238 * @memberOf module:Accessibility 239 * @method 240 * @alias module:Accessibility.initInstance 241 */ 242 api.initInstance = function () { 243 api.watchEvents(); 244 api.activateFirstElement(); 245 }; 246 /** 247 * init method calls 248 * [".initInstance"]{@link module:Accessibility.initInstance} method. 249 * @memberOf module:Accessibility 250 * @alias module:Accessibility.init 251 */ 252 api.init = function () { 253 api.initInstance(); 254 }; 255 256 return api; 257})(jQuery, document); 258 259XA.register("accessibility", XA.component.accessibility);
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.