1window.addEventListener("load", () => { 2 const $searchMask = document.getElementById("search-mask"); 3 const $searchDialog = document.querySelector("#algolia-search .search-dialog"); 4 5 const openSearch = () => { 6 anzhiyu.animateIn($searchMask, "to_show 0.5s"); 7 $searchDialog.style.display = "block"; 8 setTimeout(() => { 9 document.querySelector("#algolia-search .ais-SearchBox-input").focus(); 10 }, 100); 11 12 // shortcut: ESC 13 document.addEventListener("keydown", function f(event) { 14 if (event.code === "Escape") { 15 closeSearch(); 16 document.removeEventListener("keydown", f); 17 } 18 }); 19 20 fixSafariHeight(); 21 window.addEventListener("resize", fixSafariHeight); 22 }; 23 24 // shortcut: shift+S 25 if (anzhiyu_keyboard) { 26 window.addEventListener("keydown", function (event) { 27 if (event.keyCode == 83 && event.shiftKey) { 28 console.info(selectTextNow); 29 if (selectTextNow) { 30 openSearch(); 31 const t = document.querySelector("#algolia-search-input > div > form > input"); 32 t.value = selectTextNow; 33 t.dispatchEvent(new Event("input")); 34 setTimeout(() => { 35 document.querySelector("#algolia-search-input > div > form > button.ais-SearchBox-submit").click(); 36 }, 64); 37 } else { 38 openSearch(); 39 } 40 41 return false; 42 } 43 }); 44 } 45 46 const closeSearch = () => { 47 anzhiyu.animateOut($searchDialog, "search_close .5s"); 48 anzhiyu.animateOut($searchMask, "to_hide 0.5s"); 49 window.removeEventListener("resize", fixSafariHeight); 50 }; 51 52 // fix safari 53 const fixSafariHeight = () => { 54 if (window.innerWidth < 768) { 55 $searchDialog.style.setProperty("--search-height", window.innerHeight + "px"); 56 } 57 }; 58 59 const searchClickFn = () => { 60 anzhiyu.addEventListenerPjax(document.querySelector("#search-button > .search"), "click", openSearch); 61 }; 62 63 const searchFnOnce = () => { 64 $searchMask.addEventListener("click", closeSearch); 65 document.querySelector("#algolia-search .search-close-button").addEventListener("click", closeSearch); 66 }; 67 68 const algolia = GLOBAL_CONFIG.algolia; 69 const isAlgoliaValid = algolia.appId && algolia.apiKey && algolia.indexName; 70 if (!isAlgoliaValid) { 71 return console.error("Algolia setting is invalid!"); 72 } 73 74 const search = instantsearch({ 75 indexName: algolia.indexName, 76 /* global algoliasearch */ 77 searchClient: algoliasearch(algolia.appId, algolia.apiKey), 78 searchFunction(helper) { 79 if (helper.state.query) { 80 let innerLoading = '<i class="anzhiyufont anzhiyu-icon-spinner anzhiyu-spin"></i>'; 81 document.getElementById("algolia-hits").innerHTML = innerLoading; 82 helper.search(); 83 } 84 }, 85 }); 86 87 const configure = instantsearch.widgets.configure({ 88 hitsPerPage: algolia.hits.per_page ?? 5, 89 }); 90 91 const searchBox = instantsearch.widgets.searchBox({ 92 container: "#algolia-search-input", 93 showReset: false, 94 showSubmit: false, 95 placeholder: algolia.languages.input_placeholder, 96 showLoadingIndicator: true, 97 searchOnEnterKeyPressOnly: true, 98 searchAsYouType: false, 99 }); 100 101 const hits = instantsearch.widgets.hits({ 102 container: "#algolia-hits", 103 templates: { 104 item(data) { 105 const link = data.permalink ? data.permalink : GLOBAL_CONFIG.root + data.path; 106 const result = data._highlightResult; 107 const loadingLogo = document.querySelector("#algolia-hits .anzhiyu-spin"); 108 if (loadingLogo) { 109 loadingLogo.style.display = "none"; 110 } 111 setTimeout(() => { 112 document.querySelector("#algolia-search .ais-SearchBox-input").focus(); 113 }, 200); 114 return ` 115 <a href="${link}" class="algolia-hit-item-link"> 116 <span class="algolia-hits-item-title">${result.title.value || "no-title"}</span> 117 </a>`; 118 }, 119 empty: function (data) { 120 const loadingLogo = document.querySelector("#algolia-hits .anzhiyu-spin"); 121 console.info(loadingLogo); 122 if (loadingLogo) { 123 loadingLogo.style.display = "none"; 124 } 125 setTimeout(() => { 126 document.querySelector("#algolia-search .ais-SearchBox-input").focus(); 127 }, 200); 128 return ( 129 '<div id="algolia-hits-empty">' + 130 GLOBAL_CONFIG.algolia.languages.hits_empty.replace(/\$\{query}/, data.query) + 131 "</div>" 132 ); 133 }, 134 },
135 cssClasses: { 136 item: "algolia-hit-item", 137 }, 138 }); 139 140 const stats = instantsearch.widgets.stats({ 141 container: "#algolia-info > .algolia-stats", 142 templates: { 143 text: function (data) { 144 const stats = GLOBAL_CONFIG.algolia.languages.hits_stats 145 .replace(/\$\{hits}/, data.nbHits) 146 .replace(/\$\{time}/, data.processingTimeMS); 147 return `<hr>${stats}`; 148 }, 149 }, 150 }); 151 152 const powerBy = instantsearch.widgets.poweredBy({ 153 container: "#algolia-info > .algolia-poweredBy", 154 }); 155 156 const pagination = instantsearch.widgets.pagination({ 157 container: "#algolia-pagination", 158 totalPages: algolia.hits.per_page ?? 5, 159 templates: { 160 first: '<i class="anzhiyufont anzhiyu-icon-angle-double-left"></i>', 161 last: '<i class="anzhiyufont anzhiyu-icon-angle-double-right"></i>', 162 previous: '<i class="anzhiyufont anzhiyu-icon-angle-left"></i>', 163 next: '<i class="anzhiyufont anzhiyu-icon-angle-right"></i>', 164 }, 165 scrollTo: false, 166 showFirstLast: false, 167 cssClasses: { 168 root: "pagination", 169 item: "pagination-item", 170 link: "page-number", 171 active: "current", 172 disabled: "disabled-item", 173 }, 174 }); 175 176 search.addWidgets([configure, searchBox, hits, stats, powerBy, pagination]); // add the widgets to the instantsearch instance 177 178 search.start(); 179 180 searchClickFn(); 181 searchFnOnce(); 182 183 window.addEventListener("pjax:complete", () => { 184 !anzhiyu.isHidden($searchMask) && closeSearch(); 185 searchClickFn(); 186 }); 187 188 window.pjax && 189 search.on("render", () => { 190 window.pjax.refresh(document.getElementById("algolia-hits")); 191 }); 192});
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.