1(async function (doc, win, hotRankList, keyword) { 2 // è·å layer 模åï¼å ¼å®¹ layui åç´æ¥å¼å ¥ç layerï¼ 3 const layer = win.layer || (win.layui && win.layui.layer) || { 4 msg: function(msg) { console.log(msg); }, 5 load: function() { return 0; }, 6 closeAll: function() {} 7 }; 8 9 // ç«å æç´¢å ¥å£ - 使ç¨å½åååè¿è¡æç´¢ 10 const buildSearchUrl = (q) => { 11 // 使ç¨å½åååçæ ¹è·¯å¾è¿è¡æç´¢ï¼ä¸ä½¿ç¨åå°é ç½®çå°å 12 const base = window.location.origin + '/'; 13 return `${base}?s=${encodeURIComponent(q)}`; 14 }; 15 16 // å表(æç´¢ç»æ) 17 class SortList { 18 constructor(selector, url) { 19 const _this = this; 20 this.$archive = () => $(selector); 21 this.keyword = keyword; 22 this.url = url; 23 this.sort = ''; 24 this.page = 1; 25 26 // åé 27 $(document).on('change', '.xqbj-search-sort input[name="searchsort"][type="radio"]', function() { 28 _this.sort = $(this).val(); 29 _this.page = 1; 30 _this.load(); 31 }); 32 } 33 34 // å ¥å£æ¹æ³ 35 load() { 36 this.showLoading(); 37 this.fetchData() 38 .done((html) => { 39 this.renderList(html); 40 this.bindEvents(); 41 }) 42 .fail(() => { 43 layer.msg('æ°æ®è¯·æ±å¤±è´¥'); 44 }) 45 .always(() => { 46 this.goTop(); 47 setTimeout(() => { 48 layer.closeAll('loading') 49 }, 500); 50 }); 51 } 52 53 // è¯·æ± 54 fetchData() { 55 const data = { 56 q: this.keyword, 57 sort: this.sort, 58 page: this.page, 59 }; 60 61 console.log("@data", data); 62 63 return $.ajax({ 64 url: this.url, 65 method: 'GET', 66 data: { s: data.q, sort: data.sort, page: data.page } 67 }); 68 } 69 70 // 渲æ[å端å¤ç] 71 renderList(html) { 72 this.$archive().fadeOut('fast', () => { 73 this.$archive().replaceWith(html).fadeIn(300); 74 }); 75 } 76 77 // äºä»¶ 78 bindEvents() { 79 const _this = this; 80 $(doc).off('click.pageNav') 81 82 // ä¸ä¸é¡µ 83 .on('click.pageNav', '.page-nav-ajax .prev a', function (e) { 84 e.preventDefault(); 85 _this.page = $(this)?.data('page') || 1; 86 _this.load(); 87 }) 88 89 // ä¸ä¸é¡µ 90 .on('click.pageNav', '.page-nav-ajax .next a', function (e) { 91 e.preventDefault(); 92 _this.page = $(this)?.data('page') || 1; 93 console.log('next clicked'); 94 _this.load(); 95 }) 96 97 // 跳转æé® 98 .on('click.pageNav', '.page-nav-ajax #submitBtn', function (e) { 99 e.preventDefault(); 100 const input = $(this).closest('.page-nav-ajax').find('input').val(); 101 console.log('goto clicked', input); 102 103 _this.page = (1 * input || 1); 104 _this.load(); 105 }); 106 } 107 108 // æ¾ç¤ºå è½½å¨ç» 109 showLoading() { 110 layer.load(0); 111 } 112 113 // æ¾ç¤ºå è½½å¨ç» 114 goTop() { 115 window.scrollTo({ 116 top: 0, 117 behavior: 'smooth' 118 }); 119 } 120 } 121 122 // 导èª(头é¨å¯¼èª) 123 class NavSearch { 124 constructor(hoturl, url, throttleInterval, keyLength) { 125 const _this = this; 126 this.hoturl = hoturl; 127 this.url = url; 128 this.throttleInterval = throttleInterval; 129 this.keyLength = keyLength; 130 this.domparser = new DOMParser(); 131 132 // 模æ¿å®ä¹(åå²) 133 this.hotTemplate = (c = []) => { 134 const list = Array.isArray(c) ? c.slice(0, 10) : []; 135 const hasData = list.length > 0; 136 return ` 137 <div class="container-search-context"> 138 <div class="search-container"> 139 <div class="search-title">
140 <span>åå²è®°å½</span> 141 <div class="r-text on-history-clear"> 142 <div class="xqbj-icon-delete icon"></div> 143 å é¤è®°å½ 144 </div> 145 </div> 146 <div class="container-search-tags"> 147 <div class="list history-record"> 148 <div class="no-data">ææ æ°æ®</div> 149 </div> 150 </div> 151 <div class="search-title search-border"> 152 <span>çé¨æç´¢</span> 153 </div> 154 <div class="container-search-hots"> 155 ${ 156 hasData 157 ? ` 158 <div class="rank-list"> 159 ${list.map((e, index) => ` 160 <a href="${e.permalink}" class="rank-card"> 161 ${index <= 2 ? `<div class="xqbj-icon-rank-${index + 1}"></div>` : `<div class="rank-card-icon">${index + 1}</div>`} 162 <div class="rank-card-title text-line-ellipsis-1">${e.title}</div> 163 <div class="mobile-rank-hot"><span>${e.hot_formatted} ç度</span></div> 164 </a> 165 `).join("")} 166 </div> 167 ` 168 : `<div class="no-data">ææ æ°æ®</div>` 169 } 170 </div> 171 </div> 172 </div> 173 `; 174 }; 175 176 // 模æ¿å®ä¹(æç´¢å»ºè®®) 177 // æå¤æ¾ç¤º 20 æ¡æç´¢å»ºè®®ï¼å ³é®è¯é«äº®ä½¿ç¨ <span class="keyword"> å 裹 178 // Requirements: 6.2 179 this.seaTemplate = (c) => { 180 const list = Array.isArray(c?.list) ? c.list.slice(0, 20) : []; 181 const hasData = list.length > 0; 182 return hasData ? ` 183 <div class="container-search-context"> 184 <div class="search-container"> 185 <div class="container-search-hots"> 186 <div class="rank-list"> 187 ${list.map((e) => ` 188 <a href="${e.url}" class="rank-card"> 189 <div class="xqbj-icon-search1"></div> 190 <div class="rank-card-title text-line-ellipsis-1">${e.title}</div> 191 </a> 192 `).join("")} 193 </div> 194 </div> 195 </div> 196 </div> 197 ` : ``; 198 }; 199 200 this.renderHotList = (list = []) => { 201 const tpl = _this.hotTemplate(list); 202 // åæ¶æ¸²ææ¡é¢ä¸ç§»å¨ç«¯çæç´¢å®¹å¨ 203 $('.nav-search-container .container-hot-search').each(function () { 204 $(this).html(tpl); 205 $(this).addClass('show'); 206 }); 207 }; 208 209 // åå§(mobile) - è·³è½¬å°æç´¢é¡µé¢ 210 $(doc).on('click', 'form#search-form', function (e) { 211 e.preventDefault(); 212 top.location.href = '/usr/plugins/Search/search-page.php'; 213 }); 214 215 // è¾å ¥(mobile) 216 $(doc).on('input', '#input-mobile-control-key', _this.debounce(function() { 217 const navSearchContainer = $(this).closest('.nav-search-container'); 218 const hotSearchContainer = navSearchContainer.find('.container-hot-search').get(0); 219 const listSearchContainer = navSearchContainer.find('.container-list-search').get(0);
220 const keyword = $(this).val().trim(); 221 222 if (keyword) { 223 _this.fetchSearchData(keyword) 224 .done((d) => { 225 const data = { 226 list: d.map(e => ({ 227 title: e, 228 url: buildSearchUrl(e) 229 })) 230 }; 231 232 // 渲è²å¤ç 233 data.list = data.list.map(item => { 234 const safeKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); 235 const regex = new RegExp(safeKeyword, 'g'); 236 237 return { 238 ...item, 239 title: item.title.replace(regex, `<span class="keyword">${keyword}</span>`) 240 }; 241 }); 242 243 // æ¨¡æ¿æå»º 244 const tpl = _this.seaTemplate(data); 245 246 // æ¨¡æ¿æ¸²æ 247 $(listSearchContainer).html(tpl); 248 }) 249 .fail(() => { 250 layer.msg('æ°æ®è¯·æ±å¤±è´¥'); 251 console.log('æ°æ®è¯·æ±å¤±è´¥'); 252 }) 253 .always(() => { 254 $(listSearchContainer).addClass('show'); 255 $(hotSearchContainer).removeClass('show'); 256 }); 257 } else { 258 $(listSearchContainer).removeClass('show'); 259 $(hotSearchContainer).removeClass('show'); 260 } 261 }, _this.throttleInterval)); 262 263 // æç´¢(mobile) 264 $(doc).on('click', '.input-mobile-search-btn', function () { 265 const navSearchContainer = $(this).closest('.van-nav-bar'); 266 const keywordval = navSearchContainer.find('#input-mobile-control-key').val().trim(); 267 const keywordhtml = _this.domparser.parseFromString(keywordval, 'text/html'); 268 const keyword = keywordhtml.body.textContent; 269 try { 270 top.location.href = buildSearchUrl(keyword); 271 } finally { 272 $HistoryRecord.add(keyword); 273 } 274 }); 275 276 // æç´¢-é®ç(mobile) 277 $('#input-mobile-control-key').on('keydown', function (event) { 278 if (event.key === 'Enter') { 279 event.preventDefault(); 280 const navSearchContainer = $(this).closest('.van-nav-bar'); 281 const keywordval = navSearchContainer.find('#input-mobile-control-key').val().trim(); 282 const keywordhtml = _this.domparser.parseFromString(keywordval, 'text/html'); 283 const keyword = keywordhtml.body.textContent; 284 try { 285 top.location.href = buildSearchUrl(keyword); 286 } finally { 287 $HistoryRecord.add(keyword); 288 } 289 } 290 }); 291 292 // ########################### 293 294 // åå§(desktop) 295 $(doc).on('click', '.nav-search-container', function () { 296 $(this).addClass('expand').find('#input-desktop-control-key').focus(); 297 }); 298 299 // è¾å ¥(desktop) 300 $(doc).on('input', '#input-desktop-control-key', _this.debounce(function() { 301 const navSearchContainer = $(this).closest('.nav-search-container'); 302 const hotSearchContainer = navSearchContainer.find('.container-hot-search').get(0); 303 const listSearchContainer = navSearchContainer.find('.container-list-search').get(0); 304 const keywordhtml = _this.domparser.parseFromString($(this).val(), 'text/html'); 305 const keyword = keywordhtml.body.textContent; 306 307 if (keyword) { 308 _this.fetchSearchData(keyword) 309 .done((d) => { 310 const data = { 311 list: d.map(e => ({ 312 title: e, 313 url: buildSearchUrl(e) 314 })) 315 }; 316 317 // 渲è²å¤ç 318 data.list = data.list.map(item => { 319 const safeKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); 320 const regex = new RegExp(safeKeyword, 'g'); 321 322 return { 323 ...item, 324 title: item.title.replace(regex, `<sp
324an class="keyword">${keyword}</span>`) 325 }; 326 }); 327 328 // æ¨¡æ¿æå»º 329 const tpl = _this.seaTemplate(data); 330 331 // æ¨¡æ¿æ¸²æ 332 $(listSearchContainer).html(tpl); 333 }) 334 .fail(() => { 335 layer.msg('æ°æ®è¯·æ±å¤±è´¥'); 336 console.log('æ°æ®è¯·æ±å¤±è´¥'); 337 }) 338 .always(() => { 339 $(listSearchContainer).addClass('show'); 340 $(hotSearchContainer).removeClass('show'); 341 }); 342 } else { 343 $(listSearchContainer).removeClass('show'); 344 $(hotSearchContainer).addClass('show'); 345 } 346 }, _this.throttleInterval)); 347 348 // åºå失ç¦(desktop) 349 $(doc).on('mouseleave', '#navbarCollapse', function () { 350 const navSearchContainer = $(this).find('.nav-search-container'); 351 const navSearchinput = $(this).find('#input-desktop-control-key'); 352 353 if(navSearchinput.val() === '') { 354 $(navSearchContainer).removeClass('expand'); 355 $(navSearchinput).val('').blur(); 356 } 357 }); 358 359 // ç¹å»å¤±ç¦(desktop) 360 $(doc).on('click', function (event) { 361 const navSearchContainer = $('#navbarCollapse .nav-search-container'); 362 if($(event.target).closest('#navbarCollapse').length) { 363 // ç¹å»å¨å¯¼èªæ å ï¼ä¸å¤ç 364 } else if($(event.target).closest('.on-history-delete').length) { 365 // ç¹å»å 餿é®ï¼ä¸å¤ç 366 } else { 367 $(navSearchContainer).removeClass('expand'); 368 $(this).val(''); 369 } 370 }); 371 372 // 确认(desktop) 373 $(doc).on('keydown', '#input-desktop-control-key', function (e) { 374 if (e.key === 'Enter') { 375 const keywordhtml = _this.domparser.parseFromString($(this).val().trim(), 'text/html'); 376 const keyword = keywordhtml.body.textContent; 377 if (keyword) { 378 try { 379 top.location.href = buildSearchUrl(keyword); 380 } finally { 381 $HistoryRecord.add(keyword); 382 } 383 } 384 } 385 }); 386 387 // ########################### 388 389 // è¿å 390 $(doc).on('click', '.backbtn', function () { 391 if (window.location.protocol === 'file:' || (!document.referrer && document.referrer.startsWith('file://'))) { 392 top.location.href = `../index.html`; 393 } else if (!document.referrer) { 394 top.location.href = `./`; 395 } else { 396 history.back(); 397 } 398 }); 399 400 // æç´¢å岿¶é(mobile and desktop) 401 $(doc).on('click', '.container-search-tags a, .container-search-lists a, .xqbj-search-tags-list a, .xqbj-search-none a', function (event) { 402 const keywordhtml = _this.domparser.parseFromString($(event.target)?.text()?.replace(/(^\s*)|(\s*$)/g, ""), 'text/html'); 403 const keyword = keywordhtml.body.textContent; 404 try { 405 $HistoryRecord.add(keyword); 406 } catch (error) { 407 console.log("åå²ä¿¡æ¯æ¶é失败", error); 408 } 409 }); 410 411 // 412 this.init(); 413 } 414 415 // åå§å 416 init() { 417 const _this = this; 418 console.log('Search Plugin Init - hotRankList:', hotRankList); 419 _this.renderHotList(hotRankList); 420 421 // è¥é ç½®äºæ¥å£ï¼ååæåææ°æ°æ®è¦ç 422 _this.fetchHotData() 423 .done((list = []) => { 424 if (Array.isArray(list)) { 425 _this.renderHotList(list); 426 } 427 }) 428 .fail(() => { 429 console.log('çé¨æç´¢å 载失败'); 430 }); 431 432 // 433 win?.$HistoryRecord && win?.$HistoryRecord.init(); 434 } 435 436 // æç´¢è¯·æ± - å ³é®è¯é¿åº¦å¿ 须大äº2å符 437 fetchSearchData(keyword) { 438 const _this = this; 439 if(keyword.length <= _this.keyLength) throw new Error('å ³é®è¯é¿åº¦å¿ 须大äº2'); 440 441 const data = { 442 q: keyword 443 }; 444 445 console.log("@data", data, this.url); 446 447 return $.ajax({ 448 url: `${this.url}`, 449 method: 'GET', 450 data 451 }); 452 } 453 454 // çé¨è¯·æ± 455 fetchHotData() { 456 const _this = this; 457 if (!_this.hoturl || typeof _this.hoturl !== 'string') { 458 return $.Deferred().reject(); 459 } 460 return $.ajax({ 461 url: _this.hoturl, 462 method: 'POST' 463 }); 464 } 465 466 // èæµ 467 debounce(func, delay) { 468 let timer = null; 469 return function(...args) { 470 if (timer) clearTimeout(timer); 471 timer = setTimeout(() => { 472 func.apply(this, args); 473 timer = null; 474 }, delay); 475 }; 476 } 477 } 478 479 // åå²(æç´¢åå²) 480 class HistoryRecord { 481 constructor() { 482 this.key = '__GLOBAL_SEARCH_HISTORY__'; // localStorage ç key 483 this.max = 8; // æå¤ä¿å 8 æ¡è®°å½ 484 this.listcontainer = 'div.history-record'; // å表容å¨å ç´ 485 this.init(); // åå§å è½½è®°å½ 486 } 487 488 // å è½½ 489 init() { 490 const _this = this; 491 const history = JSON.parse(localStorage.getItem(this.key)) || []; 492 this.show(history); 493 494 // äºä»¶ 495 _this.event(); 496 } 497 498 // äºä»¶ 499 event() { 500 const _this = this; 501 $(doc).on('click', '.on-history-clear', function () { 502 _this.clear(); 503 }); 504 505 $(doc).on('click', '.on-history-delete', function (e) { 506 e.preventDefault();
507 const keyword = $(this).closest('a').text(); 508 _this.del(keyword); 509 }); 510 } 511 512 // æ¾ç¤º(æä½) 513 show(historys) { 514 const $container = $(this.listcontainer); 515 $container && $container.each((index, c) => { 516 const hasData = Array.isArray(historys) && historys.length > 0; 517 if (hasData) { 518 c.innerHTML = historys.map(item => `<a href="${buildSearchUrl(item)}"><span class="text-line-ellipsis-1">${item}</span></a>`).join(''); 519 } else { 520 c.innerHTML = '<div class="no-data">ææ æ°æ®</div>'; 521 } 522 }); 523 } 524 525 // æ·»å 526 add(keyword) { 527 if (!keyword) return; 528 529 let history = JSON.parse(localStorage.getItem(this.key)) || []; 530 531 // å»é + æ·»å å°å¼å¤´ + éå¶æ°é 532 history = [keyword, ...history.filter(item => item !== keyword)].slice(0, this.max); 533 534 localStorage.setItem(this.key, JSON.stringify(history)); 535 this.show(history); 536 } 537 538 // å é¤ 539 del(keyword) { 540 if (!keyword) return; 541 542 let history = JSON.parse(localStorage.getItem(this.key)) || []; 543 544 // å é¤ 545 history = history.filter(k => k !== keyword); 546 547 localStorage.setItem(this.key, JSON.stringify(history)); 548 this.show(history); 549 } 550 551 // æ¸ ç©º 552 clear() { 553 localStorage.removeItem(this.key); 554 this.show([]); 555 } 556 } 557 558 // åå§å 559 document.addEventListener('DOMContentLoaded', function () { 560 // 使ç¨å½åååä½ä¸ºæç´¢åºç¡URL 561 const currentBaseUrl = window.location.origin + '/'; 562 563 // å¯¼èª 564 win['$NavSearch'] = new NavSearch( 565 '', // æ åç¬ç鍿¥å£ï¼ä¿æç©º 566 currentBaseUrl, // 使ç¨å½åååè¿è¡æç´¢ 567 300, 568 2 // å ³é®è¯é¿åº¦ä¸éï¼å¿ 须大äº2åç¬¦ï¼ 569 ); 570 571 // æç´¢ 572 win['$SortList'] = new SortList( 573 "div#archive", 574 currentBaseUrl 575 ); 576 577 // åå² 578 win['$HistoryRecord'] = new HistoryRecord(); 579 }, false); 580 581})(document, window, window.hotRankList || [], window.keyword || '');
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.