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.