1
+ /* global Fuse, Mark */
2
+
1
3
function 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
+ }
7
9
}
8
10
9
11
ready ( doSearch ) ;
10
12
11
13
const summaryInclude = 60 ;
12
14
const 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
+ ]
39
41
} ;
40
42
41
43
function 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, ' ' ) ;
43
45
}
44
46
45
- let searchQuery = param ( "s" ) ;
47
+ const searchQuery = param ( 's' ) ;
46
48
47
49
function 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
+ }
56
58
}
57
59
58
60
function 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 ( ) ;
73
75
}
74
76
75
77
function 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
+ } ) ;
92
91
}
93
92
94
93
function 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
+ }
116
113
}
114
+ } ) ;
115
+ }
117
116
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 ) ) ;
137
132
133
+ snippetHighlights . forEach ( ( snipvalue ) => {
134
+ new Mark ( document . getElementById ( `summary-${ key } ` ) ) . mark ( snipvalue ) ;
138
135
} ) ;
136
+ } ) ;
139
137
}
140
138
141
139
function 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 ] , '' ) ;
162
151
}
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 ;
164
162
}
165
163
166
164
/**
@@ -169,8 +167,8 @@ function render(templateString, data) {
169
167
* @return {Element }
170
168
*/
171
169
function 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 ;
176
174
}
0 commit comments