@@ -262,6 +262,11 @@ function toggleExpansion(expand) {
262262 ) ;
263263}
264264
265+ // Returns the current URL without any query parameter or hash.
266+ function getNakedUrl ( ) {
267+ return window . location . href . split ( "?" ) [ 0 ] . split ( "#" ) [ 0 ] ;
268+ }
269+
265270const GROUPS_FILTER_DEFAULT = {
266271 cargo : true ,
267272 complexity : true ,
@@ -287,6 +292,17 @@ const APPLICABILITIES_FILTER_DEFAULT = {
287292 MaybeIncorrect : true ,
288293 HasPlaceholders : true ,
289294} ;
295+ const URL_PARAMS_CORRESPONDANCE = {
296+ "groups_filter" : "groups" ,
297+ "levels_filter" : "levels" ,
298+ "applicabilities_filter" : "applicabilities" ,
299+ "version_filter" : "versions" ,
300+ } ;
301+ const VERSIONS_CORRESPONDANCE = {
302+ "lte" : "≤" ,
303+ "gte" : "≥" ,
304+ "eq" : "=" ,
305+ } ;
290306
291307window . filters = {
292308 groups_filter : { id : "lint-groups" , ...GROUPS_FILTER_DEFAULT } ,
@@ -321,7 +337,65 @@ window.filters = {
321337 }
322338 return filters . allLints ;
323339 } ,
340+ regenerateURLparams : ( ) => {
341+ const urlParams = new URLSearchParams ( window . location . search ) ;
342+
343+ function compareObjects ( obj1 , obj2 ) {
344+ return ( JSON . stringify ( obj1 ) === JSON . stringify ( { id : obj1 . id , ...obj2 } ) ) ;
345+ }
346+ function updateIfNeeded ( filterName , obj2 ) {
347+ const obj1 = filters [ filterName ] ;
348+ const name = URL_PARAMS_CORRESPONDANCE [ filterName ] ;
349+ if ( ! compareObjects ( obj1 , obj2 ) ) {
350+ urlParams . set (
351+ name ,
352+ Object . entries ( obj1 ) . filter (
353+ ( [ key , value ] ) => value && key !== "id"
354+ ) . map (
355+ ( [ key , _ ] ) => key
356+ ) . join ( "," ) ,
357+ ) ;
358+ } else {
359+ urlParams . delete ( name ) ;
360+ }
361+ }
362+
363+ updateIfNeeded ( "groups_filter" , GROUPS_FILTER_DEFAULT ) ;
364+ updateIfNeeded ( "levels_filter" , LEVEL_FILTERS_DEFAULT ) ;
365+ updateIfNeeded (
366+ "applicabilities_filter" , APPLICABILITIES_FILTER_DEFAULT ) ;
367+
368+ const versions = [ ] ;
369+ if ( filters . version_filter [ "=" ] !== null ) {
370+ versions . push ( `eq:${ filters . version_filter [ "=" ] } ` ) ;
371+ }
372+ if ( filters . version_filter [ "≥" ] !== null ) {
373+ versions . push ( `gte:${ filters . version_filter [ "≥" ] } ` ) ;
374+ }
375+ if ( filters . version_filter [ "≤" ] !== null ) {
376+ versions . push ( `lte:${ filters . version_filter [ "≤" ] } ` ) ;
377+ }
378+ if ( versions . length !== 0 ) {
379+ urlParams . set ( URL_PARAMS_CORRESPONDANCE [ "version_filter" ] , versions . join ( "," ) ) ;
380+ } else {
381+ urlParams . delete ( URL_PARAMS_CORRESPONDANCE [ "version_filter" ] ) ;
382+ }
383+
384+ let params = urlParams . toString ( ) ;
385+ if ( params . length !== 0 ) {
386+ params = `?${ params } ` ;
387+ }
388+
389+ const url = getNakedUrl ( ) + params + window . location . hash
390+ if ( ! history . state ) {
391+ history . pushState ( null , "" , url ) ;
392+ } else {
393+ history . replaceState ( null , "" , url ) ;
394+ }
395+ } ,
324396 filterLints : ( ) => {
397+ // First we regenerate the URL parameters.
398+ filters . regenerateURLparams ( ) ;
325399 for ( const lint of filters . getAllLints ( ) ) {
326400 lint . filteredOut = ( ! filters . groups_filter [ lint . group ]
327401 || ! filters . levels_filter [ lint . level ]
@@ -339,17 +413,19 @@ window.filters = {
339413 } ,
340414} ;
341415
342- function updateFilter ( elem , filter ) {
416+ function updateFilter ( elem , filter , skipLintsFiltering ) {
343417 const value = elem . getAttribute ( "data-value" ) ;
344418 if ( filters [ filter ] [ value ] !== elem . checked ) {
345419 filters [ filter ] [ value ] = elem . checked ;
346420 const counter = document . querySelector ( `#${ filters [ filter ] . id } .badge` ) ;
347421 counter . innerText = parseInt ( counter . innerText ) + ( elem . checked ? 1 : - 1 ) ;
348- filters . filterLints ( ) ;
422+ if ( ! skipLintsFiltering ) {
423+ filters . filterLints ( ) ;
424+ }
349425 }
350426}
351427
352- function updateVersionFilters ( elem , comparisonKind ) {
428+ function updateVersionFilters ( elem , skipLintsFiltering ) {
353429 let value = elem . value . trim ( ) ;
354430 if ( value . length === 0 ) {
355431 value = null ;
@@ -359,9 +435,12 @@ function updateVersionFilters(elem, comparisonKind) {
359435 console . error ( `Failed to get version number from "${ value } "` ) ;
360436 return ;
361437 }
438+ const comparisonKind = elem . getAttribute ( "data-value" ) ;
362439 if ( filters . version_filter [ comparisonKind ] !== value ) {
363440 filters . version_filter [ comparisonKind ] = value ;
364- filters . filterLints ( ) ;
441+ if ( ! skipLintsFiltering ) {
442+ filters . filterLints ( ) ;
443+ }
365444 }
366445}
367446
@@ -454,11 +533,11 @@ function generateSettings() {
454533 class="version-filter-input form-control filter-input" \
455534 maxlength="2" \
456535 data-value="${ kind } " \
457- onchange="updateVersionFilters(this, ' ${ kind } ' )" \
458- oninput="updateVersionFilters(this, ' ${ kind } ' )" \
459- onkeydown="updateVersionFilters(this, ' ${ kind } ' )" \
460- onkeyup="updateVersionFilters(this, ' ${ kind } ' )" \
461- onpaste="updateVersionFilters(this, ' ${ kind } ' )" \
536+ onchange="updateVersionFilters(this)" \
537+ oninput="updateVersionFilters(this)" \
538+ onkeydown="updateVersionFilters(this)" \
539+ onkeyup="updateVersionFilters(this)" \
540+ onpaste="updateVersionFilters(this)" \
462541 />
463542 <span>.0</span>\
464543</li>` ;
@@ -495,6 +574,33 @@ function scrollToLintByURL() {
495574 }
496575}
497576
577+ function parseURLFilters ( ) {
578+ const urlParams = new URLSearchParams ( window . location . search ) ;
579+
580+ for ( const [ key , value ] of urlParams . entries ( ) ) {
581+ for ( const [ corres_key , corres_value ] of Object . entries ( URL_PARAMS_CORRESPONDANCE ) ) {
582+ if ( corres_value === key ) {
583+ if ( key !== "versions" ) {
584+ const settings = new Set ( value . split ( "," ) ) ;
585+ onEachLazy ( document . querySelectorAll ( `#lint-${ key } ul input` ) , elem => {
586+ elem . checked = settings . has ( elem . getAttribute ( "data-value" ) ) ;
587+ updateFilter ( elem , corres_key , true ) ;
588+ } ) ;
589+ } else {
590+ const settings = value . split ( "," ) . map ( elem => elem . split ( ":" ) ) ;
591+
592+ for ( const [ kind , value ] of settings ) {
593+ const elem = document . querySelector (
594+ `#version-filter input[data-value="${ VERSIONS_CORRESPONDANCE [ kind ] } "]` ) ;
595+ updateVersionFilters ( elem , true ) ;
596+ }
597+ }
598+ }
599+ }
600+ }
601+ }
602+
603+ parseURLFilters ( ) ;
498604scrollToLintByURL ( ) ;
499605filters . filterLints ( ) ;
500606onEachLazy ( document . querySelectorAll ( "pre > code.language-rust" ) , el => hljs . highlightElement ( el ) ) ;
0 commit comments