@@ -76,6 +76,29 @@ window.searchState = {
7676 setTimeout ( searchState . filterLints , 50 ) ;
7777 } ,
7878 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+
79102 searchState . clearInputTimeout ( ) ;
80103
81104 let searchStr = searchState . inputElem . value . trim ( ) . toLowerCase ( ) ;
@@ -87,29 +110,19 @@ window.searchState = {
87110 }
88111 searchState . lastSearch = searchStr ;
89112 const terms = searchStr . split ( " " ) ;
113+ const cleanedSearchStr = searchStr . replaceAll ( "-" , "_" ) ;
90114
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 ;
96119 }
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 = "" ;
111124 }
112- } ) ;
125+ }
113126 if ( searchStr . length > 0 ) {
114127 window . location . hash = `/${ searchStr } ` ;
115128 } else {
@@ -151,12 +164,26 @@ function handleShortcut(ev) {
151164document . addEventListener ( "keypress" , handleShortcut ) ;
152165document . addEventListener ( "keydown" , handleShortcut ) ;
153166
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 ) ;
156172 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+ }
159182 ) ;
183+ element . querySelector ( ".badge" ) . innerText = value ? count : 0 ;
184+ if ( needsUpdate ) {
185+ filters . filterLints ( ) ;
186+ }
160187}
161188
162189function changeSetting ( elem ) {
@@ -251,23 +278,99 @@ const GROUPS_FILTER_DEFAULT = {
251278 style : true ,
252279 suspicious : true ,
253280} ;
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+ }
254346
255347function resetGroupsToDefault ( ) {
348+ let needsUpdate = false ;
349+
256350 onEachLazy ( document . querySelectorAll ( "#lint-groups-selector input" ) , el => {
257351 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+ }
259358 } ) ;
359+ if ( needsUpdate ) {
360+ filters . filterLints ( ) ;
361+ }
260362}
261363
262- function generateListOfOptions ( list , elementId ) {
364+ function generateListOfOptions ( list , elementId , filter ) {
263365 let html = '' ;
264366 let nbEnabled = 0 ;
265367 for ( const [ key , value ] of Object . entries ( list ) ) {
266368 const attr = value ? " checked" : "" ;
267369 html += `\
268370<li class="checkbox">\
269371 <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 } \
271374 </label>\
272375</li>` ;
273376 if ( value ) {
@@ -298,20 +401,10 @@ function setupDropdown(elementId) {
298401function generateSettings ( ) {
299402 setupDropdown ( "settings-dropdown" ) ;
300403
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" ) ;
315408
316409 let html = '' ;
317410 for ( const kind of [ "≥" , "≤" , "=" ] ) {
@@ -361,5 +454,5 @@ function scrollToLintByURL() {
361454}
362455
363456scrollToLintByURL ( ) ;
364-
457+ filters . filterLints ( ) ;
365458onEachLazy ( document . querySelectorAll ( "pre > code.language-rust" ) , el => hljs . highlightElement ( el ) ) ;
0 commit comments