1'use strict'; 2 3(function ($, Drupal, drupalSettings, cookies) { 4 5 Drupal.behaviors.isere_core = { 6 attach: function (context, settings) { 7 $(window).on('load', function () { 8 $('ul[id*="ui-id-"]').each(function () { 9 10 $(this).on('click', function () { 11 // LinkIt / CKEditor Entity Link 12 $('.form-linkit-autocomplete.form-text.ui-autocomplete-input,.form-autocomplete.form-text.ui-autocomplete-input').each(function () { 13 var input_id = $(this).attr('id'); 14 var user_link = $(this).val(); 15 const found = user_link.match(/^\//); 16 if (found) { 17 $.ajax({ 18 method: "GET", 19 url: drupalSettings.path.baseUrl + 'url/alias', 20 data: { link: user_link } 21 }) 22 .done(function (data) { 23 if (data.alias) { 24 $('#' + input_id).val(data.alias) 25 } 26 }); 27 } 28 }); 29 }); 30 }); 31 32 }); 33 $('.ui-autocomplete-input').each(function () { 34 35 var inputElement = $(this); 36 37 inputElement.attr('role', 'combobox'); 38 inputElement.attr('aria-autocomplete', 'both'); 39 inputElement.attr('aria-expanded', 'false'); 40 41 // Check if the input has the attribute data-search-api-autocomplete-search or has the id 'searchString' 42 if (inputElement.attr('data-search-api-autocomplete-search') || inputElement.attr('id') === 'searchString') { 43 44 // Try to find the associated <ul> element with the class ui-autocomplete and search-api-autocomplete-search 45 var associatedMenu = $('.ui-autocomplete.search-api-autocomplete-search'); 46 47 if (associatedMenu.length > 0) { 48 // If the specific menu is found, use its ID for aria-controls 49 var menuId = associatedMenu.attr('id'); 50 inputElement.attr('aria-controls', menuId); 51 } else { 52 // Fallback: If the specific menu is not found, try finding another ui-autocomplete menu 53 var fallbackMenu = $('ul.ui-menu.ui-autocomplete'); 54 55 if (fallbackMenu.length > 0) { 56 // If a fallback menu is found, use its ID for aria-controls 57 var fallbackMenuId = fallbackMenu.attr('id'); 58 inputElement.attr('aria-controls', fallbackMenuId); 59 } 60 } 61 } 62 63 $(this).autocomplete({ 64 messages: { 65 noResults: Drupal.t('Aucun résultat de recherche.'), 66 results: function (amount) { 67 return amount + 68 (amount > 1 69 ? Drupal.t(" résultats sont disponibles.") 70 : Drupal.t(" résultat est disponible.")) + 71 Drupal.t(" Utilisez les flèches HAUT / BAS pour naviguer au sein de la liste de suggestions. ") + 72 Drupal.t("Appuyez sur Entrée pour sélectionner une option. ") + 73 Drupal.t("Sur des terminaux tactiles, utilisez le balayage pour naviguer et double tapez pour sélectionner une option."); 74 } 75 }, 76 focus: function(event, ui) { 77 var value = $.parseHTML(ui.item.value); 78 // Prevent the default behavior of updating the input value 79 event.preventDefault(); 80 81 // Dynamically update the input value with the focused item's value 82 $(this).val(value[0].data); 83 84 // Prevent the listbox from closing by stopping propagation 85 event.stopPropagation(); 86 // Highlight the corresponding <li> in the listbox and update aria-selected 87 var autoUl = $(this).autocomplete("widget"); 88 autoUl.find('[role="option"]').removeAttr('aria-selected').removeClass('ui-state-focus'); // Remove aria-selected from all options 89 90 var focusedLi = autoUl.find("li").filter(function() { 91 return $(this).text().trim() === ui.item.value.trim(); // Match the item's text 92 }); 93 94 focusedLi.attr('aria-selected', 'true'); // Set aria-selected on the focused item 95 focusedLi.addClass('ui-state-focus'); // Optional: Add a CSS class for styling 96 }, 97 select: function(event, ui) { 98 // On selection, update the input value and optionally navigate 99 $(this).val(ui.item.value); 100 101 if (ui.item.url) { 102 window.location.href = ui.item.url; // Navigate to the selected URL 103 } 104 105 return false; // Prevent further propagation 106 }, 107 open: function() { 108 // Add ARIA roles and attributes when the listbox opens 109 var autoUl = $(this).autocomplete("widget"); 110 autoUl.attr('role', 'listbox'); 111 autoUl.attr('tabindex', '0'); 112 inputElement.attr('aria-expanded', 'true'); 113 114 // Ensure all <li> elements have proper roles 115 var autoLi = autoUl.find("li"); 116 autoLi.attr("role", "option"); 117 autoLi.attr("tabindex", "-1"); 118 119 // Add events listener to the window 120 if ($(window).width() > 792) { 121 $(window).on('scroll', () => { 122 setTimeout(function () { 123 resizeAutocomplete(inputElement, autoUl); 124 }, 200); 125 }); 126 127 } 128 }, 129 close: function() { 130 // Reset ARIA attributes when the listbox is closed 131 inputElement.attr("aria-expanded", "false"); 132 133 // Remove aria-selected from all options 134 var autoUl = $(this).autocomplete("widget"); 135 autoUl.find('[role="option"]').removeAttr('aria-selected').removeClass('ui-state-focus'); 136 137 // Ensure input field regains focus 138 $(this).focus(); 139 } 140 }); 141 }); 142 143 $('#searchString').autocomplete({ 144 source: function(request, response) { 145 $.get('/search_api_autocomplete/recherche', { q: request.term }, function(data) { 146 var results = []; 147 $.each(data, function(index, value) { 148 var decoded = $("<div/>").html(value.value).text(); 149 results.push({url: value.url, value: decoded, label: decoded}); 150 }); 151 response(results); 152 }); 153 }, 154 minLength: 3, 155 focus: function(event, ui) { 156 var value = $.parseHTML(ui.item.value); 157 // Prevent the default behavior of updating the input value 158 event.preventDefault(); 159 160 // Dynamically update the input value with the focused item's value 161 $(this).val(value[0].data); 162 163 // Prevent the listbox from closing by stopping propagation 164 event.stopPropagation(); 165 // Highlight the corresponding <li> in the listbox and update aria-selected 166 var autoUl = $(this).autocomplete("widget"); 167 autoUl.find('[role="option"]').removeAttr('aria-selected').removeClass('ui-state-focus'); // Remove aria-selected from all options 168
169 var focusedLi = autoUl.find("li").filter(function() { 170 return $(this).text().trim() === ui.item.value.trim(); // Match the item's text 171 }); 172 173 focusedLi.attr('aria-selected', 'true'); // Set aria-selected on the focused item 174 focusedLi.addClass('ui-state-focus'); // Optional: Add a CSS class for styling 175 }, 176 select: function(event, ui) { 177 if (ui.item.url == null) { 178 location.href= '/recherche?recherche=' + ui.item.value; 179 } 180 else { 181 location.href= ui.item.url; 182 } 183 }, 184 messages: { 185 noResults: Drupal.t('Aucun résultat de recherche.'), 186 results: function (amount) { 187 return amount + 188 (amount > 1 189 ? Drupal.t(" résultats sont disponibles.") 190 : Drupal.t(" résultat est disponible.")) + 191 Drupal.t(" Utilisez les flèches HAUT / BAS pour naviguer au sein de la liste de suggestions. ") + 192 Drupal.t("Appuyez sur Entrée pour sélectionner une option. ") + 193 Drupal.t("Sur des terminaux tactiles, utilisez le balayage pour naviguer et double tapez pour sélectionner une option."); 194 } 195 }, 196 open: function () { 197 // Add role="option" to each <li> element in the dropdown 198 var autoUl = $(this).autocomplete("widget"); 199 var searchHeader = $('#searchString'); 200 autoUl.attr('role', 'listbox'); 201 autoUl.attr('tabindex', '0'); 202 autoUl.attr('aria-expanded', 'true'); 203 204 // Add aria-controls to the input element 205 var listboxId = autoUl.attr('id'); 206 searchHeader.attr('aria-controls', listboxId); 207 208 // Ensure all <li> elements have proper roles 209 var autoLi = autoUl.find("li"); 210 autoLi.attr("role", "option"); 211 autoLi.attr("tabindex", "-1"); 212 213 const header = $('.c-main-header'); 214 header.on('animationstart', () => { 215 autoUl.css('opacity', 0); 216 }); 217 218 header.on('animationend', () => { 219 resizeAutocomplete(searchHeader, autoUl, true); 220 autoUl.css('opacity', 1); // Restore opacity immediately 221 }); 222 223 /// Add events listener to the window 224 let scrollTimer; 225 autoUl.addClass('widget-search'); 226 227 $(window).on('scroll', () => { 228 clearTimeout(scrollTimer); 229 autoUl.addClass('scrolling'); // Add class when scrolling starts 230 231 scrollTimer = setTimeout(() => { 232 resizeAutocomplete(searchHeader, autoUl, true); 233 autoUl.removeClass('scrolling'); 234 }, 200); 235 }); 236 }, 237 close: function() { 238 // Reset ARIA attributes when the listbox is closed 239 $(this).attr("aria-expanded", "false"); 240 241 // Remove aria-selected from all options 242 var autoUl = $(this).autocomplete("widget"); 243 autoUl.find('[role="option"]').removeAttr('aria-selected').removeClass('ui-state-focus'); 244 autoUl.removeClass('widget-search'); 245 246 // Ensure input field regains focus 247 $(this).focus(); 248 } 249 }); 250 251 function resizeAutocomplete(inputElement, autocompleteMenu, searchHeader = false) { 252 // Get the input element's position relative to the document 253 const inputRect = $(inputElement)[0].getBoundingClientRect(); 254 let scrollTop = $(window).scrollTop(); 255 let menuPosition = scrollTop + inputRect.bottom; // Default position below input 256 257 // Set the new position of the menu 258 $(autocompleteMenu).css({ 259 top: `${menuPosition}px`, 260 }); 261 } 262 263 $(once('js-flash-info-close', '.js-flash-info-close', context)).on('click', function (e) { 264 $(".c-flash-info").hide(); 265 cookies.set('flash-info', 'closed'); 266 }); 267 268 // TODO : Trouver l'origine de ce message d'erreur en PROD (sur vidéo Youtube distante) afin de pouvoir retirer ce fix 269 $('.c-alert--fail:contains("Could not retrieve the oEmbed resource")').hide(); 270 271 $('#form-reset').on('keydown', function (e) { 272 if (e.key === 'Enter') { 273 $(this).trigger('click'); 274 } 275 else if (e.key === ' ') { // Spacebar check 276 e.preventDefault(); // Prevent default scrolling or activation 277 } 278 }); 279 280 if ($('.aides-demarches-form').length) { 281 setTimeout(function() { 282 var profil_attribute = $('.aides-demarches-form .form-item-profils- .select2-selection').attr('aria-controls'); 283 var thematique_attribute = $('.aides-demarches-form .form-item-thematique- .select2-selection').attr('aria-controls'); 284 $('.aides-demarches-form .form-item-profils- label').attr('id', 'profils-label'); 285 $('.aides-demarches-form .form-item-profils- .select2-selection').attr('aria-labelledby', profil_attribute + ' profils-label'); 286 $('.aides-demarches-form .form-item-profils- .select2-selection__rendered').removeAttr('title'); 287 $('.aides-demarches-form .form-item-thematique- label').attr('id', 'thematique-label'); 288 $('.aides-demarches-form .form-item-thematique- .select2-selection').attr('aria-labelledby', thematique_attribute + ' thematique-label'); 289 $('.aides-demarches-form .form-item-thematique- .select2-selection__rendered').removeAttr('title'); 290 }, 5); 291 } 292 293 if ($('.offres-emploi-form').length) { 294 setTimeout(function() { 295 var commune_attribute = $('.offres-emploi-form .form-item-commune .select2-selection').attr('aria-controls'); 296 $('.offres-emploi-form .form-item-commune label').attr('id', 'commune-label'); 297 $('.offres-emploi-form .form-item-commune .select2-selection').attr('aria-labelledby', commune_attribute + ' commune-label'); 298 $('.offres-emploi-form .form-item-commune .select2-selection__rendered').removeAttr('title'); 299 }, 5); 300 } 301 302 if ($('#views-exposed-form-offres-emploi-page-offres-emploi').length) { 303 setTimeout(function() { 304 var filieres_attribute = $('#views-exposed-form-offres-emploi-page-offres-emploi .form-item-filieres .select2-selection').attr('aria-controls'); 305 var commune_attribute = $('#views-exposed-form-offres-emploi-page-offres-emploi .form-item-commune .select2-selection').attr('aria-controls'); 306 $('#views-exposed-form-offres-emploi-page-offres-emploi .form-item-filieres label').attr('id', 'filieres-label'); 307 $('#views-exposed-form-offres-emploi-page-offres-emploi .form-item-filieres .select2-selection').attr('aria-labelledby', filieres_attribute + ' filieres-label'); 308 $('#views-exposed-form-offres-emploi-page-offres-emploi .form-item-filieres .select2-selection__rendered').removeAttr('title'); 309 $('#views-exposed-form-offres-emploi-page-offres-emploi .form-item-commune label').attr('id', 'commune-label'); 310 $('#views-exposed-form-offres-emploi-page-offres-emploi .form-item-commune .select2-selection').attr('aria-labelledby', commune_attribute + ' commune-label'); 311 $('#views-exposed-form-offres-emploi-page-offres-emploi .form-item-commune .select2-selection__rendered').removeAttr('title'); 312 }, 5); 313 } 314 } 315 } 316})(jQuery, Drupal, drupalSettings, window.Cookies);
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.