search.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /* SPDX-License-Identifier: AGPL-3.0-or-later */
  2. /* global AutoComplete */
  3. (function (w, d, searxng) {
  4. 'use strict';
  5. var firstFocus = true, qinput_id = "q", qinput;
  6. function placeCursorAtEnd (element) {
  7. if (element.setSelectionRange) {
  8. var len = element.value.length;
  9. element.setSelectionRange(len, len);
  10. }
  11. }
  12. function submitIfQuery () {
  13. if (qinput.value.length > 0) {
  14. var search = document.getElementById('search');
  15. setTimeout(search.submit.bind(search), 0);
  16. }
  17. }
  18. function createClearButton (qinput) {
  19. var cs = document.getElementById('clear_search');
  20. var updateClearButton = function () {
  21. if (qinput.value.length === 0) {
  22. cs.classList.add("empty");
  23. } else {
  24. cs.classList.remove("empty");
  25. }
  26. };
  27. // update status, event listener
  28. updateClearButton();
  29. cs.addEventListener('click', function () {
  30. qinput.value = '';
  31. qinput.focus();
  32. updateClearButton();
  33. });
  34. qinput.addEventListener('keyup', updateClearButton, false);
  35. }
  36. searxng.ready(function () {
  37. qinput = d.getElementById(qinput_id);
  38. function placeCursorAtEndOnce () {
  39. if (firstFocus) {
  40. placeCursorAtEnd(qinput);
  41. firstFocus = false;
  42. } else {
  43. // e.preventDefault();
  44. }
  45. }
  46. if (qinput !== null) {
  47. // clear button
  48. createClearButton(qinput);
  49. // autocompleter
  50. if (searxng.autocompleter) {
  51. searxng.autocomplete = AutoComplete.call(w, {
  52. Url: "./autocompleter",
  53. EmptyMessage: searxng.translations.no_item_found,
  54. HttpMethod: searxng.method,
  55. HttpHeaders: {
  56. "Content-type": "application/x-www-form-urlencoded",
  57. "X-Requested-With": "XMLHttpRequest"
  58. },
  59. MinChars: 4,
  60. Delay: 300,
  61. _Position: function () {
  62. this.DOMResults.setAttribute("class", "autocomplete");
  63. this.DOMResults.style.top = (this.Input.offsetTop + this.Input.offsetHeight) + "px";
  64. this.DOMResults.style.left = this.Input.offsetLeft + "px";
  65. this.DOMResults.style.width = this.Input.clientWidth + "px";
  66. },
  67. }, "#" + qinput_id);
  68. // hack, see : https://github.com/autocompletejs/autocomplete.js/issues/37
  69. w.addEventListener('resize', function () {
  70. var event = new CustomEvent("position");
  71. qinput.dispatchEvent(event);
  72. });
  73. }
  74. qinput.addEventListener('focus', placeCursorAtEndOnce, false);
  75. qinput.focus();
  76. }
  77. // vanilla js version of search_on_category_select.js
  78. if (qinput !== null && d.querySelector('.help') != null && searxng.search_on_category_select) {
  79. d.querySelector('.help').className = 'invisible';
  80. searxng.on('#categories input', 'change', function () {
  81. var i, categories = d.querySelectorAll('#categories input[type="checkbox"]');
  82. for (i = 0; i < categories.length; i++) {
  83. if (categories[i] !== this && categories[i].checked) {
  84. categories[i].click();
  85. }
  86. }
  87. if (! this.checked) {
  88. this.click();
  89. }
  90. submitIfQuery();
  91. return false;
  92. });
  93. searxng.on(d.getElementById('safesearch'), 'change', submitIfQuery);
  94. searxng.on(d.getElementById('time_range'), 'change', submitIfQuery);
  95. searxng.on(d.getElementById('language'), 'change', submitIfQuery);
  96. }
  97. });
  98. })(window, document, window.searxng);