1+ /* global Fuse, Mark */
2+
13function ready ( fn ) {
2- if ( document . readyState != 'loading' ) {
3- fn ( ) ;
4- } else {
5- document . addEventListener ( 'DOMContentLoaded' , fn ) ;
6- }
4+ if ( document . readyState != = 'loading' ) {
5+ fn ( ) ;
6+ } else {
7+ document . addEventListener ( 'DOMContentLoaded' , fn ) ;
8+ }
79}
810
911ready ( doSearch ) ;
1012
1113const summaryInclude = 60 ;
1214const fuseOptions = {
13- shouldSort : true ,
14- includeMatches : true ,
15- matchAllTokens : true ,
16- threshold : 0.0 , // for parsing diacritics
17- tokenize : true ,
18- location : 0 ,
19- distance : 100 ,
20- maxPatternLength : 32 ,
21- minMatchCharLength : 1 ,
22- keys : [ {
23- name : " title" ,
24- weight : 0.8
25- } ,
26- {
27- name : " contents" ,
28- weight : 0.5
29- } ,
30- {
31- name : " tags" ,
32- weight : 0.3
33- } ,
34- {
35- name : " categories" ,
36- weight : 0.3
37- }
38- ]
15+ shouldSort : true ,
16+ includeMatches : true ,
17+ matchAllTokens : true ,
18+ threshold : 0.0 , // for parsing diacritics
19+ tokenize : true ,
20+ location : 0 ,
21+ distance : 100 ,
22+ maxPatternLength : 32 ,
23+ minMatchCharLength : 1 ,
24+ keys : [ {
25+ name : ' title' ,
26+ weight : 0.8
27+ } ,
28+ {
29+ name : ' contents' ,
30+ weight : 0.5
31+ } ,
32+ {
33+ name : ' tags' ,
34+ weight : 0.3
35+ } ,
36+ {
37+ name : ' categories' ,
38+ weight : 0.3
39+ }
40+ ]
3941} ;
4042
4143function param ( name ) {
42- return decodeURIComponent ( ( location . search . split ( name + '=' ) [ 1 ] || '' ) . split ( '&' ) [ 0 ] ) . replace ( / \+ / g, ' ' ) ;
44+ return decodeURIComponent ( ( window . location . search . split ( ` ${ name } =` ) [ 1 ] || '' ) . split ( '&' ) [ 0 ] ) . replace ( / \+ / g, ' ' ) ;
4345}
4446
45- let searchQuery = param ( "s" ) ;
47+ const searchQuery = param ( 's' ) ;
4648
4749function doSearch ( ) {
48- if ( searchQuery ) {
49- document . getElementById ( " search-query" ) . value = searchQuery ;
50- executeSearch ( searchQuery ) ;
51- } else {
52- const para = document . createElement ( "P" ) ;
53- para . innerText = " Please enter a word or phrase above" ;
54- document . getElementById ( " search-results" ) . appendChild ( para ) ;
55- }
50+ if ( searchQuery ) {
51+ document . getElementById ( ' search-query' ) . value = searchQuery ;
52+ executeSearch ( searchQuery ) ;
53+ } else {
54+ const para = document . createElement ( 'P' ) ;
55+ para . innerText = ' Please enter a word or phrase above' ;
56+ document . getElementById ( ' search-results' ) . appendChild ( para ) ;
57+ }
5658}
5759
5860function getJSON ( url , fn ) {
59- const request = new XMLHttpRequest ( ) ;
60- request . open ( 'GET' , url , true ) ;
61- request . onload = function ( ) {
62- if ( request . status >= 200 && request . status < 400 ) {
63- const data = JSON . parse ( request . responseText ) ;
64- fn ( data ) ;
65- } else {
66- console . log ( " Target reached on " + url + " with error " + request . status ) ;
67- }
68- } ;
69- request . onerror = function ( ) {
70- console . log ( " Connection error " + request . status ) ;
71- } ;
72- request . send ( ) ;
61+ const request = new XMLHttpRequest ( ) ;
62+ request . open ( 'GET' , url , true ) ;
63+ request . onload = function ( ) {
64+ if ( request . status >= 200 && request . status < 400 ) {
65+ const data = JSON . parse ( request . responseText ) ;
66+ fn ( data ) ;
67+ } else {
68+ console . error ( ` Target reached on ${ url } with error ${ request . status } ` ) ;
69+ }
70+ } ;
71+ request . onerror = function ( ) {
72+ console . error ( ` Connection error ${ request . status } ` ) ;
73+ } ;
74+ request . send ( ) ;
7375}
7476
7577function executeSearch ( searchQuery ) {
76- getJSON ( "/" + document . LANG + "/index.json" , function ( data ) {
77- const pages = data ;
78- const fuse = new Fuse ( pages , fuseOptions ) ;
79- const result = fuse . search ( searchQuery ) ;
80- console . log ( {
81- "matches" : result
82- } ) ;
83- document . getElementById ( "search-results" ) . innerHTML = "" ;
84- if ( result . length > 0 ) {
85- populateResults ( result ) ;
86- } else {
87- const para = document . createElement ( "P" ) ;
88- para . innerText = "No matches found" ;
89- document . getElementById ( "search-results" ) . appendChild ( para ) ;
90- }
91- } ) ;
78+ getJSON ( `/${ document . LANG } /index.json` , ( data ) => {
79+ const pages = data ;
80+ const fuse = new Fuse ( pages , fuseOptions ) ;
81+ const result = fuse . search ( searchQuery ) ;
82+ document . getElementById ( 'search-results' ) . innerHTML = '' ;
83+ if ( result . length > 0 ) {
84+ populateResults ( result ) ;
85+ } else {
86+ const para = document . createElement ( 'P' ) ;
87+ para . innerText = 'No matches found' ;
88+ document . getElementById ( 'search-results' ) . appendChild ( para ) ;
89+ }
90+ } ) ;
9291}
9392
9493function populateResults ( result ) {
95- result . forEach ( function ( value , key ) {
96- const content = value . item . contents ;
97- let snippet = "" ;
98- const snippetHighlights = [ ] ;
99- if ( fuseOptions . tokenize ) {
100- snippetHighlights . push ( searchQuery ) ;
101- value . matches . forEach ( function ( mvalue ) {
102- if ( mvalue . key === "tags" || mvalue . key === "categories" ) {
103- snippetHighlights . push ( mvalue . value ) ;
104- } else if ( mvalue . key === "contents" ) {
105- const ind = content . toLowerCase ( ) . indexOf ( searchQuery . toLowerCase ( ) ) ;
106- const start = ind - summaryInclude > 0 ? ind - summaryInclude : 0 ;
107- const end = ind + searchQuery . length + summaryInclude < content . length ? ind + searchQuery . length + summaryInclude : content . length ;
108- snippet += content . substring ( start , end ) ;
109- if ( ind > - 1 ) {
110- snippetHighlights . push ( content . substring ( ind , ind + searchQuery . length ) )
111- } else {
112- snippetHighlights . push ( mvalue . value . substring ( mvalue . indices [ 0 ] [ 0 ] , mvalue . indices [ 0 ] [ 1 ] - mvalue . indices [ 0 ] [ 0 ] + 1 ) ) ;
113- }
114- }
115- } ) ;
94+ result . forEach ( ( value , key ) => {
95+ const content = value . item . contents ;
96+ let snippet = '' ;
97+ const snippetHighlights = [ ] ;
98+ if ( fuseOptions . tokenize ) {
99+ snippetHighlights . push ( searchQuery ) ;
100+ value . matches . forEach ( ( mvalue ) => {
101+ if ( mvalue . key === 'tags' || mvalue . key === 'categories' ) {
102+ snippetHighlights . push ( mvalue . value ) ;
103+ } else if ( mvalue . key === 'contents' ) {
104+ const ind = content . toLowerCase ( ) . indexOf ( searchQuery . toLowerCase ( ) ) ;
105+ const start = ind - summaryInclude > 0 ? ind - summaryInclude : 0 ;
106+ const end = ind + searchQuery . length + summaryInclude < content . length ? ind + searchQuery . length + summaryInclude : content . length ;
107+ snippet += content . substring ( start , end ) ;
108+ if ( ind > - 1 ) {
109+ snippetHighlights . push ( content . substring ( ind , ind + searchQuery . length ) ) ;
110+ } else {
111+ snippetHighlights . push ( mvalue . value . substring ( mvalue . indices [ 0 ] [ 0 ] , mvalue . indices [ 0 ] [ 1 ] - mvalue . indices [ 0 ] [ 0 ] + 1 ) ) ;
112+ }
116113 }
114+ } ) ;
115+ }
117116
118- if ( snippet . length < 1 ) {
119- snippet += content . substring ( 0 , summaryInclude * 2 ) ;
120- }
121- //pull template from hugo templarte definition
122- const templateDefinition = document . getElementById ( "search-result-template" ) . innerHTML ;
123- //replace values
124- const output = render ( templateDefinition , {
125- key : key ,
126- title : value . item . title ,
127- link : value . item . permalink ,
128- tags : value . item . tags ,
129- categories : value . item . categories ,
130- snippet : snippet
131- } ) ;
132- document . getElementById ( "search-results" ) . appendChild ( htmlToElement ( output ) ) ;
133-
134- snippetHighlights . forEach ( function ( snipvalue ) {
135- new Mark ( document . getElementById ( "summary-" + key ) ) . mark ( snipvalue ) ;
136- } ) ;
117+ if ( snippet . length < 1 ) {
118+ snippet += content . substring ( 0 , summaryInclude * 2 ) ;
119+ }
120+ // pull template from hugo template definition
121+ const templateDefinition = document . getElementById ( 'search-result-template' ) . innerHTML ;
122+ // replace values
123+ const output = render ( templateDefinition , {
124+ key,
125+ title : value . item . title ,
126+ link : value . item . permalink ,
127+ tags : value . item . tags ,
128+ categories : value . item . categories ,
129+ snippet
130+ } ) ;
131+ document . getElementById ( 'search-results' ) . appendChild ( htmlToElement ( output ) ) ;
137132
133+ snippetHighlights . forEach ( ( snipvalue ) => {
134+ new Mark ( document . getElementById ( `summary-${ key } ` ) ) . mark ( snipvalue ) ;
138135 } ) ;
136+ } ) ;
139137}
140138
141139function render ( templateString , data ) {
142- let conditionalMatches , copy ;
143- const conditionalPattern = / \$ \{ \s * i s s e t ( [ a - z A - Z ] * ) \s * \} ( .* ) \$ \{ \s * e n d \s * } / g;
144- //since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop
145- copy = templateString ;
146- while ( ( conditionalMatches = conditionalPattern . exec ( templateString ) ) !== null ) {
147- if ( data [ conditionalMatches [ 1 ] ] ) {
148- //valid key, remove conditionals, leave content.
149- copy = copy . replace ( conditionalMatches [ 0 ] , conditionalMatches [ 2 ] ) ;
150- } else {
151- //not valid, remove entire section
152- copy = copy . replace ( conditionalMatches [ 0 ] , '' ) ;
153- }
154- }
155- templateString = copy ;
156- //now any conditionals removed we can do simple substitution
157- let key , find , re ;
158- for ( key in data ) {
159- find = '\\$\\{\\s*' + key + '\\s*\\}' ;
160- re = new RegExp ( find , 'g' ) ;
161- templateString = templateString . replace ( re , data [ key ] ) ;
140+ let conditionalMatches , copy ;
141+ const conditionalPattern = / \$ \{ \s * i s s e t ( [ a - z A - Z ] * ) \s * \} ( .* ) \$ \{ \s * e n d \s * } / g;
142+ // since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop
143+ copy = templateString ;
144+ while ( ( conditionalMatches = conditionalPattern . exec ( templateString ) ) !== null ) {
145+ if ( data [ conditionalMatches [ 1 ] ] ) {
146+ // valid key, remove conditionals, leave content.
147+ copy = copy . replace ( conditionalMatches [ 0 ] , conditionalMatches [ 2 ] ) ;
148+ } else {
149+ // not valid, remove entire section
150+ copy = copy . replace ( conditionalMatches [ 0 ] , '' ) ;
162151 }
163- return templateString ;
152+ }
153+ templateString = copy ;
154+ // now any conditionals removed we can do simple substitution
155+ let key , find , re ;
156+ for ( key of Object . keys ( data ) ) {
157+ find = `\\$\\{\\s*${ key } \\s*\\}` ;
158+ re = new RegExp ( find , 'g' ) ;
159+ templateString = templateString . replace ( re , data [ key ] ) ;
160+ }
161+ return templateString ;
164162}
165163
166164/**
@@ -169,8 +167,8 @@ function render(templateString, data) {
169167 * @return {Element }
170168 */
171169function htmlToElement ( html ) {
172- const template = document . createElement ( 'template' ) ;
173- html = html . trim ( ) ; // Never return a text node of whitespace as the result
174- template . innerHTML = html ;
175- return template . content . firstChild ;
170+ const template = document . createElement ( 'template' ) ;
171+ html = html . trim ( ) ; // Never return a text node of whitespace as the result
172+ template . innerHTML = html ;
173+ return template . content . firstChild ;
176174}
0 commit comments