1'use strict'; 2 3class HuskyText { 4 constructor(input, data = {}) { 5 this.searched_value = ''; 6 this.current_page = 0; 7 this.data = Object.assign({}, data); 8 this.input = input; 9 this.init_input(); 10 this.container = document.createElement('div'); 11 this.container.className = 'woof_husky_txt'; 12 this.input.insertAdjacentElement('afterend', this.container); 13 14 this.fetch_timer = null; 15 this.fetch_controller = null; 16 17 18 19 20 document.addEventListener('click', ev => { 21 if (ev.target !== this.input) { 22 this._show(false); 23 } 24 }); 25 26 if (typeof woof_current_values['woof_text'] != 'undefined') { 27 let txt = woof_current_values['woof_text']; 28 txt = txt.replace(/&/,"%26"); 29 txt = txt.replace(/&/,"%26"); 30 woof_current_values['woof_text'] = txt; 31 } 32 } 33 34 init_input() { 35 36 Object.keys(this.data).forEach((marker) => { 37 if (this.input.hasAttribute(`data-${marker}`)) { 38 this.data[marker] = this.input.getAttribute(`data-${marker}`); 39 } 40 }); 41 42 this.input.value = this.data.s; 43 if (!this.input.classList.contains('woof_husky_txt-input')) { 44 this.input.classList.add('woof_husky_txt-input'); 45 } 46 47 this.input.setAttribute('autocomplete', 'off'); 48 49 //+++ 50 51 let _this = this; 52 53 if (this.input.closest('div').querySelector('.woof_text_search_go')) { 54 this.input.closest('div').querySelector('.woof_text_search_go').addEventListener('click', function (e) { 55 e.stopPropagation(); 56 e.preventDefault(); 57 let search_text = _this.input.value; 58 woof_current_values['woof_text'] = search_text.replace(/&/,"%26"); 59 woof_ajax_page_num = 1; 60 woof_submit_link(woof_get_submit_link(), 0); 61 62 return false; 63 }); 64 } 65 if (this.input.closest('form[role=search]')) { 66 this.input.closest('form[role=search]').addEventListener('submit', function (e) { 67 e.stopPropagation(); 68 e.preventDefault(); 69 70 let search_text = _this.input.value; 71 let min_symbols = (typeof _this.data.min_symbols) ? _this.data.min_symbols : 3; 72 if (search_text.length >= min_symbols) { 73 woof_current_values['woof_text'] = search_text.replace(/&/,"%26"); 74 woof_ajax_page_num = 1; 75 // woof_text_do_submit = false; 76 woof_submit_link(woof_get_submit_link(), 0); 77 78 } 79 80 return false; 81 }); 82 } 83 84 this.input.addEventListener('keyup', function (e) { 85 e.stopPropagation(); 86 e.preventDefault(); 87 _this.searched_value = this.value; 88 _this._search(1, e.key); 89 90 return false; 91 }); 92 93 this.input.addEventListener('focus', (e) => { 94 if (this._get_options_container()) { 95 this._get_options_container().style.display = 'block'; 96 } 97 }); 98 } 99 100 _search(current_page = 1, ekey = null) { 101 102 let _this = this; 103 104 let search_text = encodeURIComponent(this.searched_value); 105 106 107 let min_symbols = (typeof this.data.min_symbols) ? this.data.min_symbols : 3; 108 this._loader(false); 109 if (this.fetch_timer) { 110 clearTimeout(this.fetch_timer); 111 } 112 113 if (search_text.length === 0) { 114 this._cross(false); 115 } 116 if (search_text.length >= min_symbols) { 117 jQuery('.woof_text_search_go').show(222); 118 } else { 119 jQuery('.woof_text_search_go').hide(); 120 } 121 122 woof_current_values['woof_text'] = search_text; 123 if (ekey === 'Enter') { 124 this._loader(); 125 woof_current_values['woof_text'] = this.searched_value.replace(/&/,"%26"); 126 woof_ajax_page_num = 1; 127 woof_submit_link(woof_get_submit_link(), 0); 128 this._loader(false); 129 return true; 130 } 131 132 if (!parseInt(this.input.dataset.autocomplete)) { 133 return false; 134 } 135 136 if (this.searched_value === search_text && current_page === this.current_page) { 137 //return true; - TODO for pagination clicking 138 } 139 140 this.current_page = current_page; 141 142 //+++ 143 144 let delay_time = 777; 145 if (ekey === 'Enter' || ekey === 'Paged') { 146 delay_time = 1; 147 } 148 149 this.fetch_timer = setTimeout(() => { 150 151 let do_fetch = true; 152 153 if (search_text.length < min_symbols) { 154 do_fetch = false; 155 156 this._reset(); 157 } 158 this._loader(); 159 160 if (do_fetch) { 161 //check current tax 162 let cur_tax = false; 163 if (Object.keys(woof_really_curr_tax).length > 0) { 164 cur_tax = woof_really_curr_tax.term_id + '-' + woof_really_curr_tax.taxonomy; 165 } 166 search_text = decodeURIComponent(this.searched_value); 167 168 var nonce = jQuery('.woof_text_search_nonce').val(); 169 let request_data = { 170 action: 'woof_text_search', 171 value: search_text, 172 link: woof_get_submit_link(), 173 cur_tax: cur_tax, 174 page: current_page - 1, 175 woof_text_search_nonce: nonce, 176 ...this.data 177 }; 178 179 this._cross(); 180 181 if (this.fetch_controller) { 182 //cancel ajax request if user is too quick 183 this.fetch_controller.abort(); 184 } 185 186 this.fetch_controller = new AbortController(); 187 const signal = this.fetch_controller.signal; 188 189 fetch(woof_husky_txt.ajax_url, {...{ 190 method: 'POST', 191 credentials: 'same-origin', 192 body: (function (data) { 193 const formData = new FormData(); 194
195 Object.keys(data).forEach(function (k) { 196 formData.append(k, data[k]); 197 }); 198 199 return formData; 200 })(request_data) 201 }, signal}).then(response => response.json()).then(response => { 202 203 this._reset(); 204 this.searched_value = encodeURIComponent(search_text); 205 this._loader(false); 206 let answer = document.createElement('div'); 207 this.answer = answer; 208 this.answer.className = 'woof_husky_txt-container'; 209 this.container.appendChild(answer); 210 if (response.options.length > 0) { 211 response.options.forEach(function (row) { 212 let option = document.createElement('div'); 213 option.className = 'woof_husky_txt-option'; 214 option.innerHTML = row; 215 216 //+++ 217 218 let title = option.querySelector('.woof_husky_txt-option-title'); 219 let title_link = title.querySelector('a'); 220 221 222 if (parseInt(_this.data.title_light)) { 223 let pattern = new RegExp('(' + search_text + ')', 'ig'); 224 title_link.innerHTML = title.innerText.replace(pattern, `<span class='woof_husky_txt-highlight'>$1</span>`); 225 } 226 227 228 // if (parseInt(_this.data.how_to_open_links)) { 229// option.classList.add('husky-option-clickable'); 230// option.addEventListener('click', (e) => { 231// e.stopPropagation();
232// window.open(title_link.href, _this.data.click_target); 233// return false; 234// }); 235 // } 236 237 answer.appendChild(option); 238 }); 239 240 if (response.pagination.pages > 1) { 241 this._draw_pagination(answer, response); 242 } 243 } else { 244 let option = document.createElement('div'); 245 option.className = 'woof_husky_txt-option'; 246 247 let content_container = document.createElement('div'); 248 249 let title = document.createElement('div'); 250 title.className = 'woof_husky_txt-option-title'; 251 title.textContent = woof_husky_txt.not_found; 252 content_container.appendChild(title); 253 option.appendChild(content_container); 254 answer.appendChild(option); 255 } 256 257 this._show(); 258 259 }).catch((err) => { 260 console.log(err); 261 }); 262 263 } else { 264 this._loader(false); 265 } 266 }, delay_time); 267 268 return true; 269 } 270 271 _show(is = true) { 272 if (is) { 273 //animation 274 let counter = 1; 275 let container = this._get_options_container(); 276 let timer = setInterval(() => { 277 let max_height = 0; 278 279 if (typeof this.data.max_open_height !== 'undefined') { 280 max_height = parseInt(this.data.max_open_height); 281 } else { 282 container.querySelectorAll('.woof_husky_txt-option').forEach(function (item) { 283 max_height += item.offsetHeight; 284 }); 285 } 286 287 //growing 288 container.style.maxHeight = parseFloat(0.05 * counter) * max_height + 'px'; 289 290 if (parseInt(container.style.maxHeight) >= max_height) { 291 clearInterval(timer); 292 if (typeof this.data.max_open_height !== 'undefined') { 293 container.style.maxHeight = max_height + 'px'; 294 container.style.overflow = 'auto'; 295 } else { 296 container.style.maxHeight = '100vh'; 297 } 298 } 299 counter++; 300 }, 10); 301 } else { 302 303 if (this._get_options_container()) { 304 let container = this._get_options_container(); 305 container.style.display = 'none'; 306 307 if (typeof container.style.overflow !== 'undefined') { 308 //container.scrollTop = 0;//!! 309 //container.style.overflow = null; 310 } 311 } 312 313 } 314 } 315 316 _loader(show = true) { 317 if (show) { 318 this.loader = document.createElement('div'); 319 this.loader.className = 'woof_husky_txt-loader'; 320 this.loader.style.width = this.loader.style.height = this.input.offsetHeight + 'px'; 321 this.loader.style.top = '-' + (this.input.offsetHeight - 1) + 'px'; 322 this.container.appendChild(this.loader); 323 } else { 324 if (this.loader) { 325 this.loader.remove(); 326 } 327 } 328 } 329 330 _cross(show = true) { 331 332 if (!this.cross) { 333 this.cross = document.createElement('span'); 334 this.cross.className = 'woof_husky_txt-cross'; 335 this.cross.innerText = 'x'; 336 this.cross.style.width = this.cross.style.height = (this.input.offsetHeight / 2) + 'px'; 337 this.cross.style.top = '-' + (this.input.offsetHeight / 2) + 'px'; 338 this.cross.style.right = '-23px'; 339 340 this.container.appendChild(this.cross); 341 342 let _this = this; 343 this.cross.addEventListener('click', function (e) { 344 e.stopPropagation(); 345 _this.input.value = ''; 346 _this._cross(false); 347 if (_this.answer) { 348 _this.answer.remove(); 349 } 350 if (_this.fetch_controller) { 351 //cancel ajax request if user is too quick 352 _this.fetch_controller.abort(); 353 } 354 if (_this.fetch_timer) { 355 clearTimeout(_this.fetch_timer); 356 } 357 358 return true; 359 }); 360 } 361 362 363 if (show) { 364 this.cross.style.display = 'inline'; 365 } else { 366 this.cross.style.display = 'none'; 367 } 368 } 369 370 _reset() { 371 if (this._get_options_container()) { 372 this._get_options_container().remove(); 373 } 374 } 375 376 _get_options_container() { 377 return this.container.querySelector('.woof_husky_txt-container'); 378 } 379 380 _draw_pagination(answer, response) { 381 let _this = this; 382 let option = document.createElement('div'); 383 option.className = 'woof_husky_txt-option woof_husky_txt-option-pagination'; 384 let p_container = document.createElement('div'); 385 p_container.className = 'husky-pagination'; 386 option.appendChild(p_container); 387 answer.appendChild(option); 388 389 //+++ 390 let a = null; 391 392 //algo 393 //1 2 !3! 4 5 394 for (let p = 1; p <= response.pagination.pages; p++) { 395 396 if (response.pagination.pages > 12) { 397 398 if (p === 1 || p === response.pagination.pages) { 399 this._draw_pagination_btn(response.pagination.page, p, p_container); 400 continue; 401 } 402 403 if (p === response.pagination.page || 404 p === response.pagination.page - 1 || 405 p === response.pagination.page - 2 || 406 p === response.pagination.page - 3 || 407 p === response.pagination.page + 1 || 408 p === response.pagination.page + 2 || 409 p === response.pagination.page + 3) { 410 this._draw_pagination_btn(response.pagination.page, p, p_container); 411 } 412 413 if (p === response.pagination.page - 4 || p === response.pagination.page + 4) { 414 a = document.createElement('i'); 415 a.innerText = ' ... '; 416 p_container.appendChild(a); 417 } 418 419 } else { 420 this._draw_pagination_btn(response.pagination.page, p, p_container); 421 } 422 423 } 424 425 //+++ 426 427 if (response.pagination.page > 1) { 428 a = document.createElement('a'); 429 a.href = '#'; 430 a.innerText = woof_husky_txt.prev; 431 432 a.addEventListener('click', function (e) { 433 e.preventDefault(); 434 e.stopPropagation(); 435 436 _this._search(response.pagination.page - 1, 'Paged'); 437 return false; 438 }); 439 440 p_container.prepend(a); 441 } 442 443 if (response.pagination.page < response.pagination.pages) { 444 a = document.createElement('a'); 445 a.href = '#'; 446 a.innerText = woof_husky_txt.next; 447 448 a.addEventListener('click', function (e) { 449 e.preventDefault(); 450 e.stopPropagation(); 451 452 _this._search(response.pagination.page + 1, 'Paged'); 453 return false; 454 }); 455 456 p_container.appendChild(a); 457 } 458 } 459 460 _draw_pagination_btn(page, p, p_container) { 461 let a = null; 462 let _this = this; 463 464 if (parseInt(page) === p) { 465 a = document.createElement('b'); 466 a.innerText = p; 467 } else { 468 469 a = document.createElement('a'); 470 a.href = '#'; 471 a.innerText = a.dataset.page = p; 472 473 a.addEventListener('click', function (e) { 474 e.preventDefault(); 475 e.stopPropagation(); 476 477 _this._search(this.dataset.page, 'Paged'); 478 479 return false; 480 }); 481 482 } 483 484 p_container.appendChild(a); 485 } 486} 487
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.