1jQuery(document).ready(function($) { 2 3 /* 4 * jQuery simple and accessible modal window, using ARIA 5 * @version v1.11.1 6 * Website: https://a11y.nicolas-hoffmann.net/modal/ 7 * License MIT: https://github.com/nico3333fr/jquery-accessible-modal-window-aria/blob/master/LICENSE 8 */ 9 // loading modal ------------------------------------------------------------------------------------------------------------ 10 11 // init 12 var $modals = $('.js-modal'), 13 $body = $('body'); 14 15 $modals.each(function(index_to_expand) { 16 var $this = $(this), 17 index_lisible = index_to_expand + 1; 18 19 $this.attr({ 20 'id': 'label_modal_' + index_lisible, 21 'aria-haspopup': 'dialog' 22 }); 23 24 }); 25 26 // jQuery formatted selector to search for focusable items 27 var focusableElementsString = "a[href], area[href], input:not([type='hidden']):not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]"; 28 29 if ($('#js-modal-page').length === 0) { // just to avoid missing #js-modal-page 30 $body.wrapInner('<div id="js-modal-page"></div>'); 31 } 32 33 // events ------------------ 34 $body.on('click', '.js-modal', function(event) { 35 var $this = $(this), 36 options = $this.data(), 37 $modal_starter_id = $this.attr('id'), 38 $modal_prefix_classes = typeof options.modalPrefixClass !== 'undefined' ? options.modalPrefixClass + '-' : '', 39 $modal_text = options.modalText || '', 40 modal_content_id = typeof options.modalContentId !== 'undefined' ? options.modalContentId : '', 41 $modal_content = typeof options.modalContentId !== 'undefined' ? $('#' + modal_content_id) : '', 42 $modal_title = options.modalTitle || '', 43 $modal_close_text = options.modalCloseText || 'Close', 44 $modal_close_title = options.modalCloseTitle || options.modalCloseText, 45 $modal_close_img = options.modalCloseImg || '', 46 $modal_background_click = options.modalBackgroundClick || '', 47 $modal_focus_id = options.modalFocusId || '', 48 $modal_aria = typeof options.modalAriaModal !== 'undefined' ? 'aria-modal="true"' : '', 49 $modal_role_alertdialog = typeof options.modalUseRoleAlertdialog !== 'undefined' ? 'role="alertdialog"' : '', 50 $modal_role_dialog = typeof options.modalRemoveRoleDialog !== 'undefined' || $modal_role_alertdialog === 'role="alertdialog"' ? '' : 'role="dialog"', 51 $modal_tag = typeof options.modalRemoveDialogTag !== 'undefined' ? 'div' : 'dialog', 52 $modal_code, 53 $modal_overlay, 54 $page = $('#js-modal-page'); 55 56 // insert code at the end 57 $modal_code = '<' + $modal_tag + ' ' + $modal_role_dialog + ' ' + $modal_role_alertdialog + ' id="js-modal" class="' + $modal_prefix_classes + 'modal" aria-labelledby="modal-title" open ' + $modal_aria + '><div role="document" class="' + $modal_prefix_classes + 'modal__wrapper">'; 58 $modal_code += '<button type="button" id="js-modal-close" class="' + $modal_prefix_classes + 'modal-close" data-content-back-id="back_' + modal_content_id + '" data-focus-back="' + $modal_starter_id + '" title="' + $modal_close_title + '">'; 59 if ($modal_close_img !== '') { 60 $modal_code += '<img src="' + $modal_close_img + '" alt="' + $modal_close_text + '" class="' + $modal_prefix_classes + 'modal__closeimg" />'; 61 } else { 62 $modal_code += '<span class="' + $modal_prefix_classes + 'modal-close__text">' + $modal_close_text + '</span>'; 63 } 64 $modal_code += '</button>'; 65 $modal_code += '<div class="' + $modal_prefix_classes + 'modal__content">'; 66 if ($modal_title !== '') { 67 $modal_code += '<h1 id="modal-title" class="' + $modal_prefix_classes + 'modal-title">' + $modal_title + '</h1>'; 68 } 69 70 if ($modal_text !== '') { 71 $modal_code += '<p>' + $modal_text + '</p>'; 72 } else { 73 if (modal_content_id !== '' && $modal_content.length) { 74 //var $modal_content_id = $('#' + $modal_content_id); 75 $modal_code += '<div id="js-modal-content">'; 76 //$modal_code += $modal_content.html(); 77 $modal_code += '</div>'; 78 //$modal_content.empty(); 79 } 80 } 81 $modal_code += '</div></div></' + $modal_tag + '>'; 82 83 $($modal_code).insertAfter($page); 84 if (modal_content_id !== '' && $modal_content.length) { 85 $($modal_content).wrap("<div id='back_" + modal_content_id + "'></div>"); 86 $($modal_content).appendTo('#js-modal-content'); 87 } 88 89 $body.addClass('no-scroll'); 90 91 $page.attr('aria-hidden', 'true'); 92 93 // add overlay 94 if ($modal_background_click !== 'disabled') {
95 $modal_overlay = '<span id="js-modal-overlay" class="' + $modal_prefix_classes + 'modal-overlay" title="' + $modal_close_title + '" data-background-click="enabled"><span class="invisible">' + $modal_close_text + '</span></span>'; 96 } else { 97 $modal_overlay = '<span id="js-modal-overlay" class="' + $modal_prefix_classes + 'modal-overlay" data-background-click="disabled"></span>'; 98 } 99 100 $($modal_overlay).insertAfter($('#js-modal')); 101 102 if ($modal_focus_id !== '') { 103 $('#' + $modal_focus_id).focus(); 104 } else { 105 $('#js-modal-close').focus(); 106 } 107 108 109 event.preventDefault(); 110 111 }) 112 // close button and esc key 113 $body.on('click', '#js-modal-close', function() { 114 var $this = $(this), 115 $focus_back = '#' + $this.attr('data-focus-back'), 116 $content_back_id = $this.attr('data-content-back-id'), 117 $js_modal = $('#js-modal'), 118 $js_modal_content = $('#js-modal-content'), 119 $class_element = $js_modal.attr('class'), 120 $class_element_reverse = $class_element + '--reverse', 121 $js_modal_overlay = $('#js-modal-overlay'), 122 $page = $('#js-modal-page'); 123 124 $page.removeAttr('aria-hidden'); 125 126 var delay = $js_modal.css("animation-duration"); 127 //alert(delay); 128 if (delay != '0s') { 129 var timeout = parseFloat(delay.replace('s', '')) * 1000; 130 timeout++; 131 132 $js_modal.removeClass($class_element); 133 setTimeout(function() { 134 $js_modal.addClass($class_element_reverse); 135 }, 1); 136 setTimeout(function() { 137 $body.removeClass('no-scroll'); 138 if ($content_back_id !== '') { 139 $js_modal_content.children().appendTo('#' + $content_back_id); 140 $('#' + $content_back_id).children().unwrap(); 141 } 142 $js_modal.remove(); 143 $js_modal_overlay.remove(); 144 145 $($focus_back).focus(); 146 $js_modal.removeClass($class_element_reverse); 147 $js_modal.addClass($class_element); 148 }, timeout); 149 } else { 150 $body.removeClass('no-scroll'); 151 if ($content_back_id !== '') { 152 $js_modal_content.children().appendTo('#' + $content_back_id); 153 $('#' + $content_back_id).children().unwrap(); 154 } 155 $js_modal.remove(); 156 $js_modal_overlay.remove(); 157 158 $($focus_back).focus(); 159 } 160 161 }) 162 .on('click', '#js-modal-overlay', function(event) { 163 var $close = $('#js-modal-close'); 164 165 event.preventDefault(); 166 $close.trigger('click'); 167 168 }) 169 .on('click', '.js-modal-close', function(event) { 170 var $close = $('#js-modal-close'); 171 172 $close.trigger('click'); 173 174 }) 175 .on('keydown', '#js-modal-overlay', function(event) { 176 var $close = $('#js-modal-close'); 177 178 if (event.keyCode == 13 || event.keyCode == 32) { // space or enter 179 event.preventDefault(); 180 $close.trigger('click'); 181 } 182 }) 183 .on("keydown", "#js-modal", function(event) { 184 var $this = $(this), 185 $close = $('#js-modal-close'); 186 187 if (event.keyCode == 27) { // esc 188 $close.trigger('click'); 189 } 190 if (event.keyCode == 9) { // tab or maj+tab 191 192 // get list of all children elements in given object 193 var children = $this.find('*'); 194 195 // get list of focusable items 196 var focusableItems = children.filter(focusableElementsString).filter(':visible'); 197 198 // get currently focused item 199 var focusedItem = $(document.activeElement); 200 201 // get the number of focusable items
202 var numberOfFocusableItems = focusableItems.length; 203 204 var focusedItemIndex = focusableItems.index(focusedItem); 205 206 if (!event.shiftKey && (focusedItemIndex == numberOfFocusableItems - 1)) { 207 focusableItems.get(0).focus(); 208 event.preventDefault(); 209 } 210 if (event.shiftKey && focusedItemIndex == 0) { 211 focusableItems.get(numberOfFocusableItems - 1).focus(); 212 event.preventDefault(); 213 } 214 215 216 } 217 218 }) 219 .on("keyup", ":not(#js-modal)", function(event) { 220 var $js_modal = $('#js-modal'), 221 focusedItem = $(document.activeElement), 222 in_jsmodal = focusedItem.parents('#js-modal').length ? true : false, 223 $close = $('#js-modal-close'); 224 225 if ($js_modal.length && event.keyCode == 9 && in_jsmodal === false) { // tab or maj+tab 226 $close.focus(); 227 } 228 229 }) 230 .on('focus', '#js-modal-tabindex', function() { 231 var $close = $('#js-modal-close'); 232 233 $close.focus(); 234 }); 235 236 237});
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.