search.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import throttle from 'lodash/throttle';
  2. import URI from 'url-parse';
  3. import qs from 'querystringify';
  4. import history from './history';
  5. export const DEFAULTS = {
  6. uri: '',
  7. limit: 20,
  8. snippet: 300,
  9. min: 3,
  10. search_type: 'auto',
  11. in_page: false,
  12. live_update: true,
  13. };
  14. const historyPush = ({ value = false, params = false } = {}) => {
  15. const uri = new URI(global.location.href, true);
  16. if (params === false) {
  17. delete uri.query.q;
  18. } else {
  19. uri.query.q = params;
  20. }
  21. const querystring = qs.stringify(uri.query, '?');
  22. history.push(`${uri.pathname}${querystring}`, {
  23. historyValue: value, type: 'tntsearch',
  24. });
  25. };
  26. const throttling = throttle(async ({ input, results, historyValue = false } = {}) => {
  27. if (!input || !results) { return false; }
  28. const value = historyValue || input.value.trim();
  29. const clear = input.nextElementSibling;
  30. const data = Object.assign({}, DEFAULTS, JSON.parse(input.dataset.tntsearch || '{}'));
  31. if (!value) {
  32. results.style.display = 'none';
  33. if (data.in_page) {
  34. clear.style.display = 'none';
  35. if (historyValue === false && data.live_update) {
  36. historyPush({ value });
  37. }
  38. }
  39. return false;
  40. }
  41. if (value.length < data.min) {
  42. return false;
  43. }
  44. if (data.in_page) {
  45. clear.style.display = '';
  46. }
  47. const params = {
  48. q: encodeURIComponent(value),
  49. l: data.limit,
  50. sl: data.snippet,
  51. search_type: data.search_type,
  52. ajax: true,
  53. };
  54. const startEvent = new Event('tntsearch:start');
  55. const query = Object.keys(params)
  56. .map(k => `${k}=${params[k]}`)
  57. .join('&');
  58. input.dispatchEvent(startEvent);
  59. fetch(`${data.uri}?${query}`, { credentials: 'same-origin' })
  60. .then((response) => response.text())
  61. .then((response) => {
  62. if (data.in_page && data.live_update && !historyValue) {
  63. historyPush({ value, params: params.q });
  64. }
  65. return response;
  66. })
  67. .then((response) => {
  68. const doneEvent = new Event('tntsearch:done');
  69. results.style.display = '';
  70. results.innerHTML = response;
  71. input.dispatchEvent(doneEvent);
  72. return response;
  73. });
  74. return this;
  75. }, 350, { leading: false });
  76. history.listen((location) => {
  77. if (location.state && location.state.type === 'tntsearch') {
  78. location.state.input = document.querySelector('.tntsearch-field-inpage');
  79. location.state.results = document.querySelector('.tntsearch-results-inpage');
  80. if (location.state.input && location.state.results) {
  81. location.state.input.value = location.state.historyValue;
  82. throttling({ ...location.state });
  83. }
  84. }
  85. });
  86. export default throttling;