@@ -76,6 +76,29 @@ window.searchState = {
76
76
setTimeout ( searchState . filterLints , 50 ) ;
77
77
} ,
78
78
filterLints : ( ) => {
79
+ function matchesSearch ( lint , terms , searchStr ) {
80
+ // Search by id
81
+ if ( lint . elem . id . indexOf ( searchStr ) !== - 1 ) {
82
+ return true ;
83
+ }
84
+ // Search the description
85
+ // The use of `for`-loops instead of `foreach` enables us to return early
86
+ const docsLowerCase = lint . elem . textContent . toLowerCase ( ) ;
87
+ for ( const term of terms ) {
88
+ // This is more likely and will therefore be checked first
89
+ if ( docsLowerCase . indexOf ( term ) !== - 1 ) {
90
+ return true ;
91
+ }
92
+
93
+ if ( lint . elem . id . indexOf ( term ) !== - 1 ) {
94
+ return true ;
95
+ }
96
+
97
+ return false ;
98
+ }
99
+ return true ;
100
+ }
101
+
79
102
searchState . clearInputTimeout ( ) ;
80
103
81
104
let searchStr = searchState . inputElem . value . trim ( ) . toLowerCase ( ) ;
@@ -87,29 +110,19 @@ window.searchState = {
87
110
}
88
111
searchState . lastSearch = searchStr ;
89
112
const terms = searchStr . split ( " " ) ;
113
+ const cleanedSearchStr = searchStr . replaceAll ( "-" , "_" ) ;
90
114
91
- onEachLazy ( document . querySelectorAll ( "article" ) , lint => {
92
- // Search by id
93
- if ( lint . id . indexOf ( searchStr . replaceAll ( "-" , "_" ) ) !== - 1 ) {
94
- lint . style . display = "" ;
95
- return ;
115
+ for ( const lint of filters . getAllLints ( ) ) {
116
+ lint . searchFilteredOut = ! matchesSearch ( lint , terms , cleanedSearchStr ) ;
117
+ if ( lint . filteredOut ) {
118
+ continue ;
96
119
}
97
- // Search the description
98
- // The use of `for`-loops instead of `foreach` enables us to return early
99
- const docsLowerCase = lint . textContent . toLowerCase ( ) ;
100
- for ( index = 0 ; index < terms . length ; index ++ ) {
101
- // This is more likely and will therefore be checked first
102
- if ( docsLowerCase . indexOf ( terms [ index ] ) !== - 1 ) {
103
- return ;
104
- }
105
-
106
- if ( lint . id . indexOf ( terms [ index ] ) !== - 1 ) {
107
- return ;
108
- }
109
-
110
- lint . style . display = "none" ;
120
+ if ( lint . searchFilteredOut ) {
121
+ lint . elem . style . display = "none" ;
122
+ } else {
123
+ lint . elem . style . display = "" ;
111
124
}
112
- } ) ;
125
+ }
113
126
if ( searchStr . length > 0 ) {
114
127
window . location . hash = `/${ searchStr } ` ;
115
128
} else {
@@ -151,12 +164,26 @@ function handleShortcut(ev) {
151
164
document . addEventListener ( "keypress" , handleShortcut ) ;
152
165
document . addEventListener ( "keydown" , handleShortcut ) ;
153
166
154
- function toggleElements ( element , value ) {
155
- // `element` is always a button in a `li` in a `ul`. We want the `input` in the `ul`.
167
+ function toggleElements ( filter , value ) {
168
+ let needsUpdate = false ;
169
+ let count = 0 ;
170
+
171
+ const element = document . getElementById ( filters [ filter ] . id ) ;
156
172
onEachLazy (
157
- element . parentElement . parentElement . getElementsByTagName ( "input" ) ,
158
- el => el . checked = value ,
173
+ element . querySelectorAll ( "ul input" ) ,
174
+ el => {
175
+ if ( el . checked !== value ) {
176
+ el . checked = value ;
177
+ filters [ filter ] [ el . getAttribute ( "data-value" ) ] = value ;
178
+ needsUpdate = true ;
179
+ }
180
+ count += 1 ;
181
+ }
159
182
) ;
183
+ element . querySelector ( ".badge" ) . innerText = value ? count : 0 ;
184
+ if ( needsUpdate ) {
185
+ filters . filterLints ( ) ;
186
+ }
160
187
}
161
188
162
189
function changeSetting ( elem ) {
@@ -251,23 +278,99 @@ const GROUPS_FILTER_DEFAULT = {
251
278
style : true ,
252
279
suspicious : true ,
253
280
} ;
281
+ const LEVEL_FILTERS_DEFAULT = {
282
+ allow : true ,
283
+ warn : true ,
284
+ deny : true ,
285
+ none : true ,
286
+ } ;
287
+ const APPLICABILITIES_FILTER_DEFAULT = {
288
+ Unspecified : true ,
289
+ Unresolved : true ,
290
+ MachineApplicable : true ,
291
+ MaybeIncorrect : true ,
292
+ HasPlaceholders : true ,
293
+ } ;
294
+
295
+ window . filters = {
296
+ groups_filter : { id : "lint-groups" , ...GROUPS_FILTER_DEFAULT } ,
297
+ levels_filter : { id : "lint-levels" , ...LEVEL_FILTERS_DEFAULT } ,
298
+ applicabilities_filter : { id : "lint-applicabilities" , ...APPLICABILITIES_FILTER_DEFAULT } ,
299
+ version_filter : {
300
+ "≥" : null ,
301
+ "≤" : null ,
302
+ "=" : null ,
303
+ } ,
304
+ allLints : null ,
305
+ getAllLints : ( ) => {
306
+ if ( filters . allLints === null ) {
307
+ filters . allLints = Array . prototype . slice . call (
308
+ document . getElementsByTagName ( "article" ) ,
309
+ ) . map ( elem => {
310
+ return {
311
+ elem : elem ,
312
+ group : elem . querySelector ( ".label-lint-group" ) . innerText ,
313
+ level : elem . querySelector ( ".label-lint-level" ) . innerText ,
314
+ version : elem . querySelector ( ".label-version" ) . innerText ,
315
+ applicability : elem . querySelector ( ".label-applicability" ) . innerText ,
316
+ filteredOut : false ,
317
+ searchFilteredOut : false ,
318
+ } ;
319
+ } ) ;
320
+ }
321
+ return filters . allLints ;
322
+ } ,
323
+ filterLints : ( ) => {
324
+ for ( const lint of filters . getAllLints ( ) ) {
325
+ lint . filteredOut = ( ! filters . groups_filter [ lint . group ]
326
+ || ! filters . levels_filter [ lint . level ]
327
+ || ! filters . applicabilities_filter [ lint . applicability ] ) ;
328
+ if ( lint . filteredOut || lint . searchFilteredOut ) {
329
+ lint . elem . style . display = "none" ;
330
+ } else {
331
+ lint . elem . style . display = "" ;
332
+ }
333
+ }
334
+ } ,
335
+ } ;
336
+
337
+ function updateFilter ( elem , filter ) {
338
+ const value = elem . getAttribute ( "data-value" ) ;
339
+ if ( filters [ filter ] [ value ] !== elem . checked ) {
340
+ filters [ filter ] [ value ] = elem . checked ;
341
+ const counter = document . querySelector ( `#${ filters [ filter ] . id } .badge` ) ;
342
+ counter . innerText = parseInt ( counter . innerText ) + ( elem . checked ? 1 : - 1 ) ;
343
+ filters . filterLints ( ) ;
344
+ }
345
+ }
254
346
255
347
function resetGroupsToDefault ( ) {
348
+ let needsUpdate = false ;
349
+
256
350
onEachLazy ( document . querySelectorAll ( "#lint-groups-selector input" ) , el => {
257
351
const key = el . getAttribute ( "data-value" ) ;
258
- el . checked = GROUPS_FILTER_DEFAULT [ key ] ;
352
+ const value = GROUPS_FILTER_DEFAULT [ key ] ;
353
+ if ( filters . groups_filter [ key ] !== value ) {
354
+ filters . groups_filter [ key ] = value ;
355
+ el . checked = value ;
356
+ needsUpdate = true ;
357
+ }
259
358
} ) ;
359
+ if ( needsUpdate ) {
360
+ filters . filterLints ( ) ;
361
+ }
260
362
}
261
363
262
- function generateListOfOptions ( list , elementId ) {
364
+ function generateListOfOptions ( list , elementId , filter ) {
263
365
let html = '' ;
264
366
let nbEnabled = 0 ;
265
367
for ( const [ key , value ] of Object . entries ( list ) ) {
266
368
const attr = value ? " checked" : "" ;
267
369
html += `\
268
370
<li class="checkbox">\
269
371
<label class="text-capitalize">\
270
- <input type="checkbox" data-value="${ key } "${ attr } />${ key } \
372
+ <input type="checkbox" data-value="${ key } " \
373
+ onchange="updateFilter(this, '${ filter } ')"${ attr } />${ key } \
271
374
</label>\
272
375
</li>` ;
273
376
if ( value ) {
@@ -298,20 +401,10 @@ function setupDropdown(elementId) {
298
401
function generateSettings ( ) {
299
402
setupDropdown ( "settings-dropdown" ) ;
300
403
301
- const LEVEL_FILTERS_DEFAULT = { allow : true , warn : true , deny : true , none : true } ;
302
- generateListOfOptions ( LEVEL_FILTERS_DEFAULT , "lint-levels" ) ;
303
-
304
- // Generate lint groups.
305
- generateListOfOptions ( GROUPS_FILTER_DEFAULT , "lint-groups" ) ;
306
-
307
- const APPLICABILITIES_FILTER_DEFAULT = {
308
- Unspecified : true ,
309
- Unresolved : true ,
310
- MachineApplicable : true ,
311
- MaybeIncorrect : true ,
312
- HasPlaceholders : true
313
- } ;
314
- generateListOfOptions ( APPLICABILITIES_FILTER_DEFAULT , "lint-applicabilities" ) ;
404
+ generateListOfOptions ( LEVEL_FILTERS_DEFAULT , "lint-levels" , "levels_filter" ) ;
405
+ generateListOfOptions ( GROUPS_FILTER_DEFAULT , "lint-groups" , "groups_filter" ) ;
406
+ generateListOfOptions (
407
+ APPLICABILITIES_FILTER_DEFAULT , "lint-applicabilities" , "applicabilities_filter" ) ;
315
408
316
409
let html = '' ;
317
410
for ( const kind of [ "≥" , "≤" , "=" ] ) {
@@ -361,5 +454,5 @@ function scrollToLintByURL() {
361
454
}
362
455
363
456
scrollToLintByURL ( ) ;
364
-
457
+ filters . filterLints ( ) ;
365
458
onEachLazy ( document . querySelectorAll ( "pre > code.language-rust" ) , el => hljs . highlightElement ( el ) ) ;
0 commit comments