PageSourceSearch

https://covear.top/js/local_search.js

js covear.top collected 2026-10-04 01:43:25 UTC 5,698 bytes, 155 lines download raw bytes

1// A local search script with the help of [hexo-generator-search](https://github.com/PaicHyperionDev/hexo-generator-search)
2// Copyright (C) 2017
3// Liam Huang <http://github.com/Liam0205>
4// This library is free software; you can redistribute it and/or modify
5// it under the terms of the GNU Lesser General Public License as
6// published by the Free Software Foundation; either version 2.1 of the
7// License, or (at your option) any later version.
8//
9// This library is distributed in the hope that it will be useful, but
10// WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12// Lesser General Public License for more details.
13//
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17// 02110-1301 USA
18//
19
20var searchFunc = function (path, search_id, content_id) {
21  // 0x00. environment initialization
22  "use strict";
23  var BTN =
24    "<i id='local-search-close' class='fas fa-times' aria-hidden='true'></i>";
25  var $input = document.getElementById(search_id);
26  var $resultContent = document.getElementById(content_id);
27  // $resultContent.innerHTML = BTN + "<ul><span class='local-search-empty'>首次搜索,正在载入索引文件,请稍后……<span></ul>";
28  $.ajax({
29    // 0x01. load xml file
30    url: path,
31    dataType: "xml",
32    success: function (xmlResponse) {
33      // 0x02. parse xml file
34      var datas = $("entry", xmlResponse)
35        .map(function () {
36          return {
37            title: $("title", this).text(),
38            content: $("content", this).text(),
39            url: $("url", this).text(),
40          };
41        })
42        .get();
43      $resultContent.innerHTML = "";
44
45      $input.addEventListener("input", function () {
46        // 0x03. parse query to keywords list
47        var str = '<ul class="search-result-list">';
48        var keywords = this.value
49          .trim()
50          .toLowerCase()
51          .split(/[\s\-]+/);
52        $resultContent.innerHTML = "";
53        if (this.value.trim().length <= 0) {
54          return;
55        }
56        // 0x04. perform local searching
57        datas.forEach(function (data) {
58          var isMatch = true;
59          var content_index = [];
60          if (!data.title || data.title.trim() === "") {
61            data.title = "Untitled";
62          }
63          var orig_data_title = data.title.trim();
64          var data_title = orig_data_title.toLowerCase();
65          var orig_data_content = data.content.trim().replace(/<[^>]+>/g, "");
66          var data_content = orig_data_content.toLowerCase();
67          var data_url = data.url;
68          var index_title = -1;
69          var index_content = -1;
70          var first_occur = -1;
71          // only match artiles with not empty contents
72          if (data_content !== "") {
73            keywords.forEach(function (keyword, i) {
74              index_title = data_title.indexOf(keyword);
75              index_content = data_content.indexOf(keyword);
76
77              if (index_title < 0 && index_content < 0) {
78                isMatch = false;
79              } else {
80                if (index_content < 0) {
81                  index_content = 0;
82                }
83                if (i == 0) {
84                  first_occur = index_content;
85                }
86                // content_index.push({index_content:index_content, keyword_len:keyword_len});
87              }
88            });
89          } else {
90            isMatch = false;
91          }
92          // 0x05. show search results
93          if (isMatch) {
94            str +=
95              "<li><a href='" +
96              data_url +
97              "' class='search-result-title color-primary'>" +
98              orig_data_title +
99              "</a>";
100            var content = orig_data_content;
101            if (first_occur >= 0) {
102              // cut out 100 characters
103              var start = first_occur - 20;
104              var end = first_occur + 80;
105
106              if (start < 0) {
107                start = 0;
108              }
109
110              if (start == 0) {
111                end = 100;
112              }
113
114              if (end > content.length) {
115                end = content.length;
116              }
117
118              var match_content = content.substr(start, end);
119
120              // highlight all keywords
121              keywords.forEach(function (keyword) {
122                var regS = new RegExp(keyword, "gi");
123                match_content = match_content.replace(
124                  regS,
125                  '<span class="search-keyword">' + keyword + "</span>"
126                );
127              });
128
129              str += '<p class="search-result">' + match_content + "...</p>";
130            }
131            str += "</li>";
132          }
133        });
134        str += "</ul>";
135        if (str.indexOf("<li>") === -1) {
136          return ($resultContent.innerHTML =
137            "<ul><span class='local-search-empty'>没有找到内容,请尝试更换检索词。<span></ul>");
138          // return $resultContent.innerHTML = BTN + "<ul><span class='local-search-empty'>没有找到内容,请尝试更换检索词。<span></ul>";
139        }
140        $resultContent.innerHTML = str;
141        window.pjax && window.pjax.refresh($resultContent)
142        // $resultContent.innerHTML = BTN + str;
143      });
144    },
145  });
146  $(document).on("click", "#local-search-close", function () {
147    $("#local-search-input").val("");
148    $("#local-search-result").html("");
149  });
150};
151
152var getSearchFile = function (path) {
153  // var path = "/search.xml";
154  searchFunc(path, "local-search-input", "local-search-result");
155};

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.