@@ -262,6 +262,11 @@ function toggleExpansion(expand) {
262
262
) ;
263
263
}
264
264
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
+
265
270
const GROUPS_FILTER_DEFAULT = {
266
271
cargo : true ,
267
272
complexity : true ,
@@ -287,6 +292,17 @@ const APPLICABILITIES_FILTER_DEFAULT = {
287
292
MaybeIncorrect : true ,
288
293
HasPlaceholders : true ,
289
294
} ;
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
+ } ;
290
306
291
307
window . filters = {
292
308
groups_filter : { id : "lint-groups" , ...GROUPS_FILTER_DEFAULT } ,
@@ -321,7 +337,65 @@ window.filters = {
321
337
}
322
338
return filters . allLints ;
323
339
} ,
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
+ } ,
324
396
filterLints : ( ) => {
397
+ // First we regenerate the URL parameters.
398
+ filters . regenerateURLparams ( ) ;
325
399
for ( const lint of filters . getAllLints ( ) ) {
326
400
lint . filteredOut = ( ! filters . groups_filter [ lint . group ]
327
401
|| ! filters . levels_filter [ lint . level ]
@@ -339,17 +413,19 @@ window.filters = {
339
413
} ,
340
414
} ;
341
415
342
- function updateFilter ( elem , filter ) {
416
+ function updateFilter ( elem , filter , skipLintsFiltering ) {
343
417
const value = elem . getAttribute ( "data-value" ) ;
344
418
if ( filters [ filter ] [ value ] !== elem . checked ) {
345
419
filters [ filter ] [ value ] = elem . checked ;
346
420
const counter = document . querySelector ( `#${ filters [ filter ] . id } .badge` ) ;
347
421
counter . innerText = parseInt ( counter . innerText ) + ( elem . checked ? 1 : - 1 ) ;
348
- filters . filterLints ( ) ;
422
+ if ( ! skipLintsFiltering ) {
423
+ filters . filterLints ( ) ;
424
+ }
349
425
}
350
426
}
351
427
352
- function updateVersionFilters ( elem , comparisonKind ) {
428
+ function updateVersionFilters ( elem , skipLintsFiltering ) {
353
429
let value = elem . value . trim ( ) ;
354
430
if ( value . length === 0 ) {
355
431
value = null ;
@@ -359,9 +435,12 @@ function updateVersionFilters(elem, comparisonKind) {
359
435
console . error ( `Failed to get version number from "${ value } "` ) ;
360
436
return ;
361
437
}
438
+ const comparisonKind = elem . getAttribute ( "data-value" ) ;
362
439
if ( filters . version_filter [ comparisonKind ] !== value ) {
363
440
filters . version_filter [ comparisonKind ] = value ;
364
- filters . filterLints ( ) ;
441
+ if ( ! skipLintsFiltering ) {
442
+ filters . filterLints ( ) ;
443
+ }
365
444
}
366
445
}
367
446
@@ -454,11 +533,11 @@ function generateSettings() {
454
533
class="version-filter-input form-control filter-input" \
455
534
maxlength="2" \
456
535
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)" \
462
541
/>
463
542
<span>.0</span>\
464
543
</li>` ;
@@ -495,6 +574,33 @@ function scrollToLintByURL() {
495
574
}
496
575
}
497
576
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 ( ) ;
498
604
scrollToLintByURL ( ) ;
499
605
filters . filterLints ( ) ;
500
606
onEachLazy ( document . querySelectorAll ( "pre > code.language-rust" ) , el => hljs . highlightElement ( el ) ) ;
0 commit comments