PageSourceSearch

https://ccb-armor.org/plugins/auto/soyezcreateurs/v6.5.7/javascrip…-accessible-modal-window-aria.js?1775563700

js ccb-armor.org collected 2026-10-04 15:18:15 UTC 10,158 bytes, 237 lines download raw bytes

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.