/* global CONFIG */ (function() { // Modified from [hexo-generator-search](https://github.com/wzpan/hexo-generator-search) function localSearchFunc(path, searchSelector, resultSelector) { 'use strict'; // 0x00. environment initialization var $input = jQuery(searchSelector); var $result = jQuery(resultSelector); if ($input.length === 0) { // eslint-disable-next-line no-console throw Error('No element selected by the searchSelector'); } if ($result.length === 0) { // eslint-disable-next-line no-console throw Error('No element selected by the resultSelector'); } if ($result.attr('class').indexOf('list-group-item') === -1) { $result.html('
Loading...

Loading...
'); } jQuery.ajax({ // 0x01. load xml file url : path, dataType: 'xml', success : function(xmlResponse) { // 0x02. parse xml file var dataList = jQuery('entry', xmlResponse).map(function() { return { title : jQuery('title', this).text(), content: jQuery('content', this).text(), url : jQuery('url', this).text() }; }).get(); if ($result.html().indexOf('list-group-item') === -1) { $result.html(''); } $input.on('input', function() { // 0x03. parse query to keywords list var content = $input.val(); var resultHTML = ''; var keywords = content.trim().toLowerCase().split(/[\s-]+/); $result.html(''); if (content.trim().length <= 0) { return $input.removeClass('invalid').removeClass('valid'); } // 0x04. perform local searching dataList.forEach(function(data) { var isMatch = true; if (!data.title || data.title.trim() === '') { data.title = 'Untitled'; } var orig_data_title = data.title.trim(); var data_title = orig_data_title.toLowerCase(); var orig_data_content = data.content.trim().replace(/<[^>]+>/g, ''); var data_content = orig_data_content.toLowerCase(); var data_url = data.url; var index_title = -1; var index_content = -1; var first_occur = -1; // Skip matching when content is included in search and content is empty if (CONFIG.include_content_in_search && data_content === '') { isMatch = false; } else { keywords.forEach(function (keyword, i) { index_title = data_title.indexOf(keyword); index_content = data_content.indexOf(keyword); if (index_title < 0 && index_content < 0) { isMatch = false; } else { if (index_content < 0) { index_content = 0; } if (i === 0) { first_occur = index_content; } } }); } // 0x05. show search results if (isMatch) { resultHTML += '' + orig_data_title + ''; var content = orig_data_content; if (first_occur >= 0) { // cut out 100 characters var start = first_occur - 20; var end = first_occur + 80; if (start < 0) { start = 0; } if (start === 0) { end = 100; } if (end > content.length) { end = content.length; } var match_content = content.substring(start, end); // highlight all keywords keywords.forEach(function(keyword) { var regS = new RegExp(keyword, 'gi'); match_content = match_content.replace(regS, '' + keyword + ''); }); resultHTML += '

' + match_content + '...

'; } } }); if (resultHTML.indexOf('list-group-item') === -1) { return $input.addClass('invalid').removeClass('valid'); } $input.addClass('valid').removeClass('invalid'); $result.html(resultHTML); }); } }); } function localSearchReset(searchSelector, resultSelector) { 'use strict'; var $input = jQuery(searchSelector); var $result = jQuery(resultSelector); if ($input.length === 0) { // eslint-disable-next-line no-console throw Error('No element selected by the searchSelector'); } if ($result.length === 0) { // eslint-disable-next-line no-console throw Error('No element selected by the resultSelector'); } $input.val('').removeClass('invalid').removeClass('valid'); $result.html(''); } var modal = jQuery('#modalSearch'); var searchSelector = '#local-search-input'; var resultSelector = '#local-search-result'; modal.on('show.bs.modal', function() { var path = CONFIG.search_path || '/local-search.xml'; localSearchFunc(path, searchSelector, resultSelector); }); modal.on('shown.bs.modal', function() { jQuery('#local-search-input').focus(); }); modal.on('hidden.bs.modal', function() { localSearchReset(searchSelector, resultSelector); }); })();