1window.selaxLangs = { 2 en: { 3 searchPlaceholder: "Search", 4 noResults: "No results", 5 }, 6 ar: { 7 searchPlaceholder: "Ø¥Ø¨ØØ«", 8 noResults: "ÙØ§ ØªÙØ¬Ø¯ ÙØªØ§Ø¦Ø¬", 9 }, 10 tr: { 11 searchPlaceholder: "Ara", 12 noResults: "Sonuç bulunamadı", 13 }, 14}; 15 16(function ($) { 17 function normalizeForSearch(str, langCode) { 18 if (str == null) return ""; 19 20 let s = String(str); 21 22 // Fix Turkish casing properly when lang is tr 23 if (langCode === "tr") { 24 s = s.toLocaleLowerCase("tr"); 25 } else { 26 s = s.toLowerCase(); 27 } 28 29 // Make search forgiving: remove accents/diacritics (Å->s, Ä->g, etc.) 30 // Works for TR + many other langs 31 s = s.normalize("NFD").replace(/[\u0300-\u036f]/g, ""); 32 33 // Optional: normalize special Turkish letters even after diacritics removal 34 // (normalize doesn't convert dotless ı) 35 s = s.replace(/ı/g, "i"); 36 37 return s; 38 } 39 $.fn.selaxSearch = function () { 40 function getLangSettings() { 41 const lang = 42 $("html").attr("lang") || $("body").data("lang") || "en"; 43 return window.selaxLangs?.[lang] || window.selaxLangs["en"]; 44 } 45 46 function createDropdown($select, uniqid, options, lang) { 47 const container = $( 48 '<div class="dropdown-menu custom-select-container"><div class="options_list"></div></div>', 49 ); 50 51 const searchInput = $( 52 `<input type="text" class="form-control form-control-sm border-0 border-bottom rounded-0" id="custom-select-search" placeholder="${lang.searchPlaceholder}" style="padding:10px 15px!important; border-bottom:1px solid #e6e8ea!important;">`, 53 ); 54 55 container.prepend(searchInput); 56 57 options.forEach((opt) => { 58 const btn = $( 59 `<button class="dropdown-item fs-h5 modal-select-option ${opt.isActive} ${opt.isEmpty}" data-parent-select="${uniqid}" data-value="${opt.value}">${opt.text}</button>`, 60 ); 61 container.find(".options_list").append(btn); 62 }); 63 64 return container; 65 } 66 67 function buildOptions($select) { 68 const options = []; 69 $select.find("option").each(function () { 70 const $opt = $(this); 71 if ( 72 $opt.prop("disabled") || 73 $opt.prop("hidden") || 74 $opt.hasClass("d-none") 75 ) 76 return; 77 78 options.push({ 79 value: $opt.val(), 80 text: $opt.text(), 81 isActive: $opt.is(":selected") ? "active" : "", 82 isEmpty: !$opt.val() ? "h5 text-muted" : "", 83 }); 84 }); 85 return options; 86 } 87 88 function closeDropdowns() { 89 $("select.opened") 90 .removeClass("opened") 91 .next(".custom-select-container") 92 .remove(); 93 } 94 95 $(document) 96 .off("mousedown.selax") 97 .on("mousedown.selax", "select:not(.normal-select)", function (e) { 98 e.preventDefault(); 99 }); 100 101 $(document) 102 .off("click.selax") 103 .on("click.selax", "select:not(.normal-select)", function (e) { 104 e.preventDefault(); 105 106 const $select = $(this); 107 if ($select.hasClass("opened")) return closeDropdowns(); 108 109 closeDropdowns(); 110 111 const uniqid = `selax-${Math.random() 112 .toString(36) 113 .substr(2, 9)}`; 114 $select.addClass("opened").addClass(uniqid); 115 116 const lang = getLangSettings(); 117 const options = buildOptions($select); 118 const dropdown = createDropdown($select, uniqid, options, lang); 119 120 $select.after(dropdown); 121 122 dropdown.css({ 123 width: $select.outerWidth(), 124 minWidth: $select.outerWidth() + 20, 125 // maxWidth: $select.outerWidth(), 126 maxWidth: "100%", 127 position: "absolute", 128 top: $select.position().top, 129 left: $select.position().left, 130 }); 131 132 if (options.length > 2) { 133 dropdown.find(".options_list").css({ 134 maxHeight: "200px", 135 overflowY: "auto", 136 }); 137 } 138 139 dropdown.show(); 140 dropdown.find("input").focus(); 141 }); 142 143 $(document) 144 .off("click.selax-option") 145 .on("click.selax-option", ".modal-select-option", function (e) { 146 e.preventDefault(); 147 const $btn = $(this); 148 const selectClass = $btn.data("parent-select"); 149 const $select = $("." + selectClass); 150 151 $select.val($btn.data("value")).trigger("change"); 152 closeDropdowns(); 153 }); 154 155 $(document) 156 .off("keyup.selax-search") 157 .on("keyup.selax-search", "#custom-select-search", function () { 158 const langSettings = getLangSettings(); 159 const langCode = 160 $("html").attr("lang") || $("body").data("lang") || "en"; 161 162 const text = normalizeForSearch($(this).val(), langCode); 163 164 const $options = $(this) 165 .siblings(".options_list")
166 .find(".modal-select-option"); 167 168 $options.each(function () { 169 const optText = normalizeForSearch( 170 $(this).text(), 171 langCode, 172 ); 173 const match = optText.includes(text); 174 $(this).toggle(match); 175 }); 176 177 $(this).siblings(".no-result-option").remove(); 178 179 if (!$options.filter(":visible").length) { 180 $(this) 181 .parent() 182 .append( 183 `<div class="h5 my-2 mx-auto no-result-option text-center text-muted w-100">${langSettings.noResults}</div>`, 184 ); 185 } 186 }); 187 188 $(document).on("click.selax-outside", function (e) { 189 if ( 190 !$(e.target).closest("select, .custom-select-container").length 191 ) { 192 closeDropdowns(); 193 } 194 }); 195 196 $(document).on("keyup.selax-esc", function (e) { 197 if (e.key === "Escape") { 198 closeDropdowns(); 199 } 200 }); 201 202 return this; 203 }; 204})(jQuery);
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.