https://www.austrianwine.jp/_assets/283016a5deb98031c60d7504e8f170…/suggest_controller.js?1790768776
1function SuggestController() { 2 var instanceCounter = 0; 3 var self = this; 4 var reinitializing = false; 5 6 function getInputId($input) { 7 if (!$input.attr('id')) { 8 instanceCounter += 1; 9 $input.attr('id', 'tx-solr-suggest-' + instanceCounter); 10 } 11 12 return $input.attr('id'); 13 } 14 15 function getLiveRegion($searchBox) { 16 var liveRegionId = getInputId($searchBox) + '-status'; 17 var $liveRegion = jQuery('#' + liveRegionId); 18 19 if ($liveRegion.length === 0) { 20 $liveRegion = jQuery('<div></div>').attr({ 21 'id': liveRegionId, 22 'class': 'sr-only', 23 'aria-live': 'polite', 24 'aria-atomic': 'true' 25 }); 26 $searchBox.after($liveRegion); 27 } 28 29 return $liveRegion; 30 } 31 32 function updateActiveDescendant($searchBox) { 33 var listboxId = $searchBox.attr('aria-controls'); 34 var $listbox = listboxId ? jQuery('#' + listboxId) : jQuery(); 35 var $selected = $listbox.find('.autocomplete-selected').first(); 36 var $liveRegion = getLiveRegion($searchBox); 37 38 if ($selected.length) { 39 var optionLabel = $selected.attr('aria-label') || $selected.find('.sr-only').first().text().trim() || $selected.text().trim(); 40 41 $searchBox.attr('aria-activedescendant', $selected.attr('id')); 42 $listbox.find('.autocomplete-suggestion').attr('aria-selected', 'false'); 43 $selected.attr('aria-selected', 'true'); 44 $liveRegion.text(''); 45 setTimeout(function () { 46 $liveRegion.text(optionLabel); 47 }, 0); 48 } else { 49 $searchBox.removeAttr('aria-activedescendant'); 50 $liveRegion.text(''); 51 } 52 } 53 54 function syncSuggestionsWidth($searchBox, $container) { 55 var searchBoxWidth = $searchBox[0].getBoundingClientRect().width, 56 $inputGroup = $searchBox.closest('.input-group'), 57 addonWidth = $inputGroup.find('.input-group-addon').first().outerWidth() || 0, 58 isBodyContainer = $container.parent()[0] === document.body; 59 60 if (searchBoxWidth > 0) { 61 $container.css({ 62 width: isBodyContainer 63 ? Math.ceil(searchBoxWidth + addonWidth) + 'px' 64 : Math.ceil(searchBoxWidth) + 'px', 65 'margin-left': isBodyContainer ? -addonWidth + 'px' : '0' 66 }); 67 } 68 } 69 70 function isSmallMobileViewport() { 71 return window.matchMedia('only screen and (max-width: 767px)').matches; 72 } 73 74 this.init = function () { 75 76 jQuery('form[data-suggest]').each(function () { 77 var $form = jQuery(this), $searchBox = $form.find('.tx-solr-suggest'); 78 var $formAutoComplete; 79 80 if ($form.find('.tx-solr-autocomplete').length > 0){ 81 $formAutoComplete = $form.find('.tx-solr-autocomplete'); 82 } else if (isSmallMobileViewport()) { 83 $formAutoComplete = $searchBox.closest('.input-group'); 84 if ($formAutoComplete.length === 0) { 85 $formAutoComplete = jQuery('body'); 86 } 87 } else { 88 $formAutoComplete = jQuery('body'); 89 } 90 91 $form.find('.tx-solr-suggest-focus').focus(); 92 93 // when no specific container found, use the form as container 94 if ($searchBox.length === 0) { 95 $searchBox = $form; 96 } 97 $searchBox.css('position', 'relative'); 98 var inputId = getInputId($searchBox); 99 var listboxId = inputId + '-listbox'; 100 $searchBox.attr({ 101 'role': 'combobox', 102 'aria-autocomplete': 'list', 103 'aria-expanded': 'false', 104 'aria-haspopup': 'listbox', 105 'aria-controls': listboxId 106 }); 107 108 $searchBox.off('keyup.autocompleteA11y').on('keyup.autocompleteA11y', function (e) { 109 if (e.which === 38 || e.which === 40) {
110 updateActiveDescendant($searchBox); 111 } 112 }); 113 114 // Prevent submit of empty search form 115 $form.off('submit.solrSuggest').on('submit.solrSuggest', function (e) { 116 if ($form.find('.tx-solr-suggest').val() === '') { 117 e.preventDefault(); 118 $form.find('.tx-solr-suggest').focus(); 119 } 120 }); 121 122 123 124 var $input = $form.find('.tx-solr-suggest'); 125 126 $input.devbridgeAutocomplete({ 127 serviceUrl: $form.data('suggest'), 128 dataType: 'json', 129 paramName: 'tx_solr[queryString]', 130 groupBy: 'category', 131 maxHeight: 1000, 132 appendTo: $formAutoComplete, 133 forceFixPosition: true, 134 autoSelectFirst: false, 135 triggerSelectOnValidInput: false, 136 // Keep the width set in beforeRender; the library overwrites 137 // the width during fixPosition when this is set to 'auto'. 138 width: 'flex', 139 zIndex: 20, 140 onHide: function () { 141 $searchBox.attr('aria-expanded', 'false').removeAttr('aria-activedescendant'); 142 getLiveRegion($searchBox).text(''); 143 }, 144 onSelect: function (suggestion) { 145 // go to link when selecting found result 146 if (suggestion.data.link) { 147 // Open youtube in overlay 148 if (suggestion.data.link.indexOf('https://www.youtube.com') === 0) { 149 openVideoOverlay(suggestion.data.link); 150 } else { 151 location.href = suggestion.data.link; 152 } 153 // else trigger form submit (do search) 154 } else { 155 $form.trigger('submit'); 156 } 157 }, 158 transformResult: function (response) { 159 if (!response.suggestions) return {suggestions: []}; 160 var firstSuggestion, result = { 161 suggestions: $.map(response.suggestions, function (count, suggestion) { 162 if (!firstSuggestion) firstSuggestion = suggestion; 163 return {value: suggestion, data: {category: 'suggestion', count: count}}; 164 }) 165 }; 166 167 $.each(response.documents, function (key, value) { 168 var dataObject = value; 169 170 var defaultGroup = $form.data('suggest-header') ? $form.data('suggest-header') : 'Top results'; 171 dataObject.category = defaultGroup; 172 173 // if a group is set we try to get a label 174 if(dataObject.group) { 175 dataObject.category = $form.data('suggest-header-' + dataObject.group) ? $form.data('suggest-header-' + dataObject.group) : dataObject.group; 176 } 177 178 result.suggestions.push( 179 { 180 value: firstSuggestion, 181 data: dataObject 182 } 183 ); 184 }); 185 186 return result; 187 }, 188 beforeRender: function (container) { 189 syncSuggestionsWidth($searchBox, container); 190 191 // remove first group header 192 container.find('.autocomplete-group:first').remove(); 193 container.addClass('tx-solr-autosuggest').attr({ 194 'id': listboxId, 195 'role': 'listbox', 196 'aria-label': $searchBox.data('suggestionsLabel') || 'Search suggestions' 197 }); 198 199 container.find('.autocomplete-suggestion').each(function (index) { 200 var $option = jQuery(this); 201 var optionLabel = $option.find('.sr-only').first().text().trim() || $option.text().trim(); 202 203 $option.attr({ 204 'role': 'option', 205 'id': listboxId + '-option-' + index, 206 'aria-selected': 'false', 207 'aria-label': optionLabel 208 }); 209 }); 210 211 container.find('.autocomplete-group').attr('role', 'presentation'); 212 213 // add active class to container 214 $searchBox.parent().addClass('autocomplete-active').fadeIn(); 215 $searchBox.attr('aria-expanded', 'true');
216 updateActiveDescendant($searchBox); 217 }, 218 formatResult: function (suggestion, currentValue) { 219 // Do not replace anything if there current value is empty 220 if (!currentValue) { 221 return suggestion.value; 222 } 223 var pattern = '(' + $.Autocomplete.utils.escapeRegExChars(currentValue.trim()) + ')'; 224 // normal suggestion 225 if (suggestion.data.category === 'suggestion') { 226 var visualText = suggestion.value 227 .replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>') 228 .replace(/&/g, '&') 229 .replace(/</g, '<') 230 .replace(/>/g, '>') 231 .replace(/"/g, '"') 232 .replace(/<(\/?strong)>/g, '<$1>'); 233 234 var cleanText = suggestion.value 235 .replace(/&/g, '&') 236 .replace(/</g, '<') 237 .replace(/>/g, '>') 238 .replace(/"/g, '"'); 239 240 return '<span aria-hidden="true">' + visualText + '</span>' + 241 '<span class="sr-only">' + cleanText + '</span>'; 242 243 // results 244 } else { 245 var title = suggestion.data.title 246 .replace(new RegExp(pattern, 'gi'), '<em>$1<\/em>') 247 .replace(/&/g, '&') 248 .replace(/</g, '<') 249 .replace(/>/g, '>') 250 .replace(/"/g, '"') 251 .replace(/<(\/?em)>/g, '<$1>'); 252 253 return '<div class="' + suggestion.data.type + '">' + 254 (!!suggestion.data.previewImage ? '<figure ' + (!!suggestion.data.hasVideo ? 'class="hasVideo"' : '') + '>
254<img src="' + suggestion.data.previewImage + '" alt="" /></figure>' : '') + 255 '<span class="sr-only">' + suggestion.data.category + ': ' + suggestion.data.title + '</span>' + 256 '<a href="' + suggestion.data.link + '" class="internal-link" tabindex="-1"><span aria-hidden="true">' + title + '</span></a>' + 257 '</div>'; 258 } 259 260 } 261 }).off('blur.solrSuggest').on('blur.solrSuggest', function () { 262 $searchBox.parent().removeClass('autocomplete-active'); 263 $searchBox.attr('aria-expanded', 'false'); 264 var $box = jQuery(this); 265 setTimeout(function () { 266 $box.devbridgeAutocomplete('hide'); 267 }, 200); 268 }); 269 270 var mobileViewport = isSmallMobileViewport(); 271 $searchBox.data('solrSuggestionsMobileViewport', mobileViewport); 272 jQuery(window) 273 .off('resize.solrSuggestions-' + inputId) 274 .on('resize.solrSuggestions-' + inputId, function () { 275 var currentMobileViewport = isSmallMobileViewport(); 276 277 if (currentMobileViewport !== $searchBox.data('solrSuggestionsMobileViewport')) { 278 if (!reinitializing) { 279 reinitializing = true; 280 self.init(); 281 if (window.solrSearchController && typeof window.solrSearchController.clearSearch === 'function') { 282 window.solrSearchController.clearSearch(); 283 } 284 reinitializing = false; 285 } 286 } 287 }); 288 289 }); 290 }; 291} 292 293jQuery(document).ready(function() { 294 /** solr search autocomplete **/ 295 var solrSuggestController = new SuggestController(); 296 solrSuggestController.init(); 297 jQuery("body").on("tx_solr_updated", function() { 298 solrSuggestController.init(); 299 }); 300 301});
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.