mirror of
https://github.com/McShelby/hugo-theme-relearn.git
synced 2024-11-27 01:33:04 +00:00
search: improve handling of multiterm search #407
This commit is contained in:
parent
8debc83a77
commit
57b73a5f47
3 changed files with 66 additions and 21 deletions
|
@ -1 +1 @@
|
|||
7.1.1+fc960aa5eaf2240ba8a6de92943ac838423e1269
|
||||
7.1.1+8debc83a770553885b78318e2651a127a82d2b0c
|
|
@ -3,6 +3,10 @@ import { init, search } from './orama-adapter.js';
|
|||
|
||||
(function(){
|
||||
|
||||
function escapeRegex( string ){
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
|
||||
window.relearn = window.relearn || {};
|
||||
|
||||
window.relearn.executeInitialSearch =
|
||||
|
@ -95,12 +99,19 @@ function executeSearch( value ) {
|
|||
a.forEach( function(item){
|
||||
var page = item.page;
|
||||
var context = [];
|
||||
if( item.matches ){
|
||||
if( item.matches && item.matches.length ){
|
||||
var numContextWords = 10;
|
||||
var contextPattern = '(?:\\S+ +){0,' + numContextWords + '}\\S*\\b(?:' +
|
||||
item.matches.map( function(match){return match.replace(/\W/g, '\\$&')} ).join('|') +
|
||||
escapeRegex( item.matches[0] ) +
|
||||
')\\b\\S*(?: +\\S+){0,' + numContextWords + '}';
|
||||
context = page.content.match(new RegExp(contextPattern, 'i'));
|
||||
if( !context ){
|
||||
item.matches.shift();
|
||||
var contextPattern = '(?:\\S+ +){0,' + numContextWords + '}\\S*\\b(?:' +
|
||||
item.matches.map( escapeRegex ).join('|') +
|
||||
')\\b\\S*(?: +\\S+){0,' + numContextWords + '}';
|
||||
context = page.content.match(new RegExp(contextPattern, 'i'));
|
||||
}
|
||||
}
|
||||
var divsuggestion = document.createElement('a');
|
||||
divsuggestion.className = 'autocomplete-suggestion';
|
||||
|
@ -169,12 +180,19 @@ function initSearchAfterLoad(){
|
|||
renderItem: function( item, term ) {
|
||||
var page = item.page;
|
||||
var context = [];
|
||||
if( item.matches ){
|
||||
if( item.matches && item.matches.length ){
|
||||
var numContextWords = 2;
|
||||
var contextPattern = '(?:\\S+ +){0,' + numContextWords + '}\\S*\\b(?:' +
|
||||
item.matches.map( function(match){return match.replace(/\W/g, '\\$&')} ).join('|') +
|
||||
escapeRegex( item.matches[0] ) +
|
||||
')\\b\\S*(?: +\\S+){0,' + numContextWords + '}';
|
||||
context = page.content.match(new RegExp(contextPattern, 'i'));
|
||||
if( !context ){
|
||||
item.matches.shift();
|
||||
var contextPattern = '(?:\\S+ +){0,' + numContextWords + '}\\S*\\b(?:' +
|
||||
item.matches.map( escapeRegex ).join('|') +
|
||||
')\\b\\S*(?: +\\S+){0,' + numContextWords + '}';
|
||||
context = page.content.match(new RegExp(contextPattern, 'i'));
|
||||
}
|
||||
}
|
||||
var divsuggestion = document.createElement('div');
|
||||
divsuggestion.className = 'autocomplete-suggestion';
|
||||
|
|
|
@ -1327,10 +1327,12 @@ function scrollToPositions() {
|
|||
return;
|
||||
}
|
||||
|
||||
var search = sessionStorage.getItem( window.relearn.absBaseUri+'/search-value' );
|
||||
if( search && search.length ){
|
||||
search = regexEscape( search );
|
||||
var found = elementContains( search, elc );
|
||||
|
||||
var value = sessionStorage.getItem( window.relearn.absBaseUri+'/search-value' );
|
||||
var words = (value ?? '') .split( ' ' ).filter( word => word.trim() != '' );
|
||||
if( words && words.length ){
|
||||
unmark();
|
||||
var found = elementContains( words, elc );
|
||||
var searchedElem = found.length && found[ 0 ];
|
||||
if( searchedElem ){
|
||||
searchedElem.scrollIntoView();
|
||||
|
@ -1339,6 +1341,8 @@ function scrollToPositions() {
|
|||
window.scroll( 0, scrolledY - 125 );
|
||||
}
|
||||
}
|
||||
sessionStorage.setItem( window.relearn.absBaseUri+'/search-value', value );
|
||||
mark();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1371,7 +1375,7 @@ function mark() {
|
|||
bodyInnerLinks[i].classList.add( 'highlight' );
|
||||
}
|
||||
|
||||
var value = sessionStorage.getItem( window.relearn.absBaseUri + '/search-value' );
|
||||
var value = (sessionStorage.getItem( window.relearn.absBaseUri + '/search-value' ) ?? '').split( ' ' ).filter( word => word.trim() != '' );
|
||||
var highlightableElements = document.querySelectorAll( '.highlightable' );
|
||||
highlight( highlightableElements, value, { element: 'mark', className: 'search' } );
|
||||
|
||||
|
@ -1411,17 +1415,10 @@ function highlight( es, words, options ){
|
|||
};
|
||||
Object.assign( settings, options );
|
||||
|
||||
if( !words ){ return; }
|
||||
if( words.constructor === String ){
|
||||
words = [ words ];
|
||||
}
|
||||
words = words.filter( function( word, i ){
|
||||
return word != '';
|
||||
});
|
||||
if( !words.length ){ return; }
|
||||
words = words.map( function( word, i ){
|
||||
return regexEscape( word );
|
||||
});
|
||||
if( words.length == 0 ){ return this; }
|
||||
|
||||
var flag = settings.caseSensitive ? '' : 'i';
|
||||
var pattern = "(" + words.join( '|' ) + ')';
|
||||
|
@ -1507,8 +1504,24 @@ function unhighlight( es, options ){
|
|||
};
|
||||
|
||||
// replace jQuery.createPseudo with https://stackoverflow.com/a/66318392
|
||||
function elementContains( txt, e ){
|
||||
var regex = RegExp( txt, 'i' );
|
||||
function elementContains( words, e ){
|
||||
var settings = {
|
||||
caseSensitive: false,
|
||||
wordsOnly: false
|
||||
};
|
||||
|
||||
if( !words.length ){ return; }
|
||||
words = words.map( function( word, i ){
|
||||
return regexEscape( word );
|
||||
});
|
||||
|
||||
var flag = settings.caseSensitive ? '' : 'i';
|
||||
var pattern = "(" + words.join( '\\s+' ) + ')';
|
||||
if( settings.wordsOnly ){
|
||||
pattern = '\\b' + pattern + '\\b';
|
||||
}
|
||||
var regex = new RegExp( pattern, flag );
|
||||
|
||||
var nodes = [];
|
||||
if( e ){
|
||||
var tree = document.createTreeWalker( e, 4 /* NodeFilter.SHOW_TEXT */, function( node ){
|
||||
|
@ -1518,6 +1531,20 @@ function elementContains( txt, e ){
|
|||
while( node = tree.nextNode() ){
|
||||
nodes.push( node.parentElement );
|
||||
}
|
||||
|
||||
var pattern = "(" + words.join( '|' ) + ')';
|
||||
if( settings.wordsOnly ){
|
||||
pattern = '\\b' + pattern + '\\b';
|
||||
}
|
||||
regex = new RegExp( pattern, flag );
|
||||
|
||||
tree = document.createTreeWalker( e, 4 /* NodeFilter.SHOW_TEXT */, function( node ){
|
||||
return regex.test( node.data );
|
||||
}, false );
|
||||
node = null;
|
||||
while( node = tree.nextNode() ){
|
||||
nodes.push( node.parentElement );
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
@ -1537,7 +1564,7 @@ function initSearch() {
|
|||
e.addEventListener( 'keydown', function( event ){
|
||||
if( event.key == 'Escape' ){
|
||||
var input = event.target;
|
||||
var search = sessionStorage.getItem( window.relearn.absBaseUri+'/search-value' );
|
||||
var search = (sessionStorage.getItem( window.relearn.absBaseUri+'/search-value' ) ?? '').split( ' ' ).filter( word => word.trim() != '' );
|
||||
if( !search || !search.length ){
|
||||
input.blur();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue