local-search.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. 'use strict';
  2. function _toConsumableArray(e) {
  3. if (Array.isArray(e)) {
  4. for (var t = 0, n = Array(e.length); t < e.length; t++)
  5. n[t] = e[t];
  6. return n;
  7. }
  8. return Array.from(e);
  9. }
  10. window.addEventListener('DOMContentLoaded', function () {
  11. var t = !1, n = void 0, r = !0, e = CONFIG.path;
  12. 0 === e.length ? e = 'search.xml' : e.endsWith('json') && (r = !1);
  13. function T(e, t, n) {
  14. if (CONFIG.localsearch.unescape) {
  15. var r = document.createElement('div');
  16. r.innerText = e, e = r.innerHTML;
  17. }
  18. var o = e.length;
  19. if (0 === o)
  20. return [];
  21. var i = 0, a = [], c = [];
  22. for (n || (t = t.toLowerCase(), e = e.toLowerCase()); -1 < (a = t.indexOf(e, i));)
  23. c.push({
  24. position: a,
  25. word: e
  26. }), i = a + o;
  27. return c;
  28. }
  29. function S(e, t, n, r) {
  30. for (var o = n[n.length - 1], i = o.position, a = o.word, c = [], s = 0; i + a.length <= t && 0 !== n.length;) {
  31. a === r && s++, c.push({
  32. position: i,
  33. length: a.length
  34. });
  35. var l = i + a.length;
  36. for (n.pop(); 0 !== n.length && (i = (o = n[n.length - 1]).position, a = o.word, i < l);)
  37. n.pop();
  38. }
  39. return {
  40. hits: c,
  41. start: e,
  42. end: t,
  43. searchTextCount: s
  44. };
  45. }
  46. function q(n, e) {
  47. var r = '', o = e.start;
  48. return e.hits.forEach(function (e) {
  49. r += n.substring(o, e.position);
  50. var t = e.position + e.length;
  51. r += '<b class="search-keyword">' + n.substring(e.position, t) + '</b>', o = t;
  52. }), r += n.substring(o, e.end);
  53. }
  54. function o() {
  55. if (t) {
  56. var w = a.value.trim().toLowerCase(), L = w.split(/[-\s]+/);
  57. 1 < L.length && L.push(w);
  58. var E = [];
  59. 0 < w.length && n.forEach(function (e) {
  60. var t = e.title, n = e.content, r = e.url, o = t.toLowerCase(), i = n.toLowerCase(), a = [], c = [], s = 0;
  61. if (L.forEach(function (e) {
  62. a = a.concat(T(e, o, !1)), c = c.concat(T(e, i, !1));
  63. }), 0 < a.length || 0 < c.length) {
  64. var l = a.length + c.length;
  65. [a,c].forEach(function (e) {
  66. e.sort(function (e, t) {
  67. return t.position !== e.position ? t.position - e.position : e.word.length - t.word.length;
  68. });
  69. });
  70. var u = [];
  71. if (0 !== a.length) {
  72. var h = S(0, t.length, a, w);
  73. s += h.searchTextCountInSlice, u.push(h);
  74. }
  75. for (var d = []; 0 !== c.length;) {
  76. var f = c[c.length - 1], p = f.position, g = f.word, v = p - 20, C = p + 80;
  77. v < 0 && (v = 0), C < p + g.length && (C = p + g.length), C > n.length && (C = n.length);
  78. var y = S(v, C, c, w);
  79. s += y.searchTextCountInSlice, d.push(y);
  80. }
  81. d.sort(function (e, t) {
  82. return e.searchTextCount !== t.searchTextCount ? t.searchTextCount - e.searchTextCount : e.hits.length !== t.hits.length ? t.hits.length - e.hits.length : e.start - t.start;
  83. });
  84. var m = parseInt(CONFIG.localsearch.top_n_per_article, 10);
  85. 0 <= m && (d = d.slice(0, m));
  86. var x = '';
  87. 0 !== u.length ? x += '<li><a href="' + r + '" class="search-result-title">' + q(t, u[0]) + '</a>' : x += '<li><a href="' + r + '" class="search-result-title">' + t + '</a>', d.forEach(function (e) {
  88. x += '<a href="' + r + '"><p class="search-result">' + q(n, e) + '...</p></a>';
  89. }), x += '</li>', E.push({
  90. item: x,
  91. id: E.length,
  92. hitCount: l,
  93. searchTextCount: s
  94. });
  95. }
  96. }), 1 === L.length && '' === L[0] ? c.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x"></i></div>' : 0 === E.length ? c.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x"></i></div>' : (E.sort(function (e, t) {
  97. return e.searchTextCount !== t.searchTextCount ? t.searchTextCount - e.searchTextCount : e.hitCount !== t.hitCount ? t.hitCount - e.hitCount : t.id - e.id;
  98. }), c.innerHTML = '<ul class="search-result-list">' + E.map(function (e) {
  99. return e.item;
  100. }).join('') + '</ul>', window.pjax && window.pjax.refresh(c));
  101. }
  102. }
  103. function i() {
  104. fetch(CONFIG.root + e).then(function (e) {
  105. return e.text();
  106. }).then(function (e) {
  107. t = !0, n = (n = r ? [].concat(_toConsumableArray(new DOMParser().parseFromString(e, 'text/xml').querySelectorAll('entry'))).map(function (e) {
  108. return {
  109. title: e.querySelector('title').textContent,
  110. content: e.querySelector('content').textContent,
  111. url: e.querySelector('url').textContent
  112. };
  113. }) : JSON.parse(e)).filter(function (e) {
  114. return e.title;
  115. }).map(function (e) {
  116. return e.title = e.title.trim(), e.content = e.content ? e.content.trim().replace(/<[^>]+>/g, '') : '', e.url = decodeURIComponent(e.url).replace(/\/{2,}/g, '/'), e;
  117. }), document.getElementById('no-result').innerHTML = '<i class="fa fa-search fa-5x"></i>', o();
  118. });
  119. }
  120. var a = document.querySelector('.search-input'), c = document.getElementById('search-result');
  121. CONFIG.localsearch.preload && i(), 'auto' === CONFIG.localsearch.trigger ? a.addEventListener('input', o) : (document.querySelector('.search-icon').addEventListener('click', o), a.addEventListener('keypress', function (e) {
  122. 'Enter' === e.key && o();
  123. })), document.querySelectorAll('.popup-trigger').forEach(function (e) {
  124. e.addEventListener('click', function () {
  125. document.body.style.overflow = 'hidden', document.querySelector('.search-pop-overlay').classList.add('search-active'), a.focus(), t || i();
  126. });
  127. });
  128. function s() {
  129. document.body.style.overflow = '', document.querySelector('.search-pop-overlay').classList.remove('search-active');
  130. }
  131. document.querySelector('.search-pop-overlay').addEventListener('click', function (e) {
  132. e.target === document.querySelector('.search-pop-overlay') && s();
  133. }), document.querySelector('.popup-btn-close').addEventListener('click', s), window.addEventListener('pjax:success', s), window.addEventListener('keyup', function (e) {
  134. 'Escape' === e.key && s();
  135. });
  136. });