9494 @media (min-width : 992px ) {
9595 .search-control {
9696 margin-top : 0 ;
97+ float : right;
98+ }
99+ }
100+
101+ @media (min-width : 400px ) {
102+ # upper-filters {
103+ display : flex;
104+ }
105+ }
106+
107+ @media (max-width : 412px ) {
108+ # version-filter-selector {
109+ right : 0 ;
110+ left : auto;
97111 }
98112 }
99113
244258 cursor : pointer;
245259 }
246260
247- .theme-choice > li : hover {
261+ .theme-choice > li : hover {
248262 background : var (--theme-hover );
249263 }
250264
273287 border : 1px solid var (--theme-popup-border );
274288 }
275289
276- # filter-label , # filter-clear {
290+ # version-filter-selector .checkbox {
291+ display : flex;
292+ }
293+
294+ # version-filter {
295+ min-width : available;
296+ }
297+
298+ # version-filter li label {
299+ padding-right : 0 ;
300+ width : 80% ;
301+ }
302+
303+ .version-filter-input {
304+ height : 75% ;
305+ }
306+
307+ # filter-label , .filter-clear {
277308 background : var (--searchbar-bg );
278309 color : var (--searchbar-fg );
279310 border-color : var (--theme-popup-border );
280311 filter : brightness (95% );
281312 }
282- # filter-label : hover , # filter-clear : hover {
313+ # filter-label : hover , . filter-clear : hover {
283314 filter : brightness (90% );
284315 }
285- # filter-input {
316+ . filter-input {
286317 background : var (--searchbar-bg );
287318 color : var (--searchbar-fg );
288319 border-color : var (--theme-popup-border );
289320 }
290321
291- # filter-input ::-webkit-input-placeholder ,
292- # filter-input ::-moz-placeholder {
322+ . filter-input ::-webkit-input-placeholder ,
323+ . filter-input ::-moz-placeholder {
293324 color : var (--searchbar-fg );
294325 opacity : 30% ;
295326 }
@@ -338,7 +369,7 @@ <h1>Clippy Lints</h1>
338369
339370 < div class ="panel panel-default " ng-show ="data ">
340371 < div class ="panel-body row ">
341- < div class ="col-12 col-md-4 ">
372+ < div id =" upper-filters " class ="col-12 col-md-4 ">
342373 < div class ="btn-group " filter-dropdown >
343374 < button type ="button " class ="btn btn-default dropdown-toggle ">
344375 Lint levels < span class ="badge "> {{selectedValuesCount(levels)}}</ span > < span class ="caret "> </ span >
@@ -391,13 +422,36 @@ <h1>Clippy Lints</h1>
391422 </ li >
392423 </ ul >
393424 </ div >
425+ < div id ="version-filter ">
426+ < div class ="btn-group " filter-dropdown >
427+ < button type ="button " class ="btn btn-default dropdown-toggle ">
428+ Version < span class ="caret "> </ span >
429+ </ button >
430+ < ul id ="version-filter-selector " class ="dropdown-menu ">
431+ < li class ="checkbox ">
432+ < label ng-click ="clearVersionFilters() ">
433+ < input type ="checkbox " class ="invisible " />
434+ Clear filters
435+ </ label >
436+ </ li >
437+ < li role ="separator " class ="divider "> </ li >
438+ < li class ="checkbox " ng-repeat ="(filter, vars) in version_filters ">
439+ < label >
440+ < input type ="checkbox " ng-model ="version_filters[filter].enabled " />
441+ {{filter}}
442+ </ label >
443+ < input type ="text " class ="version-filter-input form-control filter-input " maxlength ="6 " placeholder ="1.62.0 " ng-model ="version_filters[filter].version_str " ng-model-options ="{debounce: 50} "/>
444+ </ li >
445+ </ ul >
446+ </ div >
447+ </ div >
394448 </ div >
395- < div class ="col-12 col-md-8 search-control ">
449+ < div class ="col-12 col-md-7 search-control ">
396450 < div class ="input-group ">
397- < label class ="input-group-addon " id ="filter-label " for ="filter -input "> Filter:</ label >
398- < input type ="text " class ="form-control " placeholder ="Keywords or search string " id ="filter -input " ng-model ="search " ng-model-options ="{debounce: 50} "/>
451+ < label class ="input-group-addon " id ="filter-label " for ="search -input "> Filter:</ label >
452+ < input type ="text " class ="form-control filter-input " placeholder ="Keywords or search string " id ="search -input " ng-model ="search " ng-model-options ="{debounce: 50} "/>
399453 < span class ="input-group-btn ">
400- < button id ="filter-clear " class =" btn " type ="button " ng-click ="search = '' ">
454+ < button class ="filter-clear btn " type ="button " ng-click ="search = '' ">
401455 Clear
402456 </ button >
403457 </ span >
@@ -406,7 +460,7 @@ <h1>Clippy Lints</h1>
406460 </ div >
407461 </ div >
408462 <!-- The order of the filters should be from most likely to remove a lint to least likely to improve performance. -->
409- < article class ="panel panel-default " id ="{{lint.id}} " ng-repeat ="lint in data | filter:bySearch | filter:byGroups | filter:byLevels ">
463+ < article class ="panel panel-default " id ="{{lint.id}} " ng-repeat ="lint in data | filter:bySearch | filter:byGroups | filter:byLevels | filter:byVersion ">
410464 < header class ="panel-heading " ng-click ="open[lint.id] = !open[lint.id] ">
411465 < h2 class ="panel-title ">
412466 < div class ="panel-title-name ">
@@ -601,6 +655,15 @@ <h2 class="panel-title">
601655 } ;
602656 $scope . themes = THEMES_DEFAULT ;
603657
658+ const DEFAULT_VERSION_FILTERS = {
659+ ">=" : { enabled : false , version_str : "" } ,
660+ "<=" : { enabled : false , version_str : "" } ,
661+ "==" : { enabled : false , version_str : "" } ,
662+ } ;
663+ // Weird workaround to get a copy of the object
664+ $scope . version_filters = JSON . parse ( JSON . stringify ( DEFAULT_VERSION_FILTERS ) ) ;
665+ $scope . version_regex = new RegExp ( '\\d\.\\d{2}\.\\d' ) ;
666+
604667 $scope . selectTheme = function ( theme ) {
605668 setTheme ( theme , true ) ;
606669 }
@@ -613,6 +676,7 @@ <h2 class="panel-title">
613676 }
614677 }
615678 } ;
679+
616680 $scope . toggleGroups = function ( value ) {
617681 const groups = $scope . groups ;
618682 for ( const key in groups ) {
@@ -621,9 +685,83 @@ <h2 class="panel-title">
621685 }
622686 }
623687 } ;
688+
624689 $scope . selectedValuesCount = function ( obj ) {
625690 return Object . values ( obj ) . filter ( x => x ) . length ;
626691 }
692+
693+ $scope . clearVersionFilters = function ( ) {
694+ $scope . version_filters = JSON . parse ( JSON . stringify ( DEFAULT_VERSION_FILTERS ) ) ;
695+ }
696+
697+ $scope . versionSymbol = function ( ) {
698+ const version_filters = $scope . version_filters ;
699+ let filter = ">=" ;
700+ for ( const key in version_filters ) {
701+ if ( version_filters [ key ] ) {
702+ filter = key ;
703+ }
704+ }
705+
706+ return filter ;
707+ }
708+
709+ $scope . byVersion = function ( lint ) {
710+ function validate_version_str ( ver ) {
711+ return ver . length === 6 && $scope . version_regex . test ( ver ) ;
712+ }
713+
714+ function cmp_version ( ver1 , ver2 , filter ) {
715+ // < 0: lint_version < version
716+ // 0: equal
717+ // > 0: lint_version > version
718+ let result = ver1 . localeCompare ( ver2 , undefined , {
719+ numeric : true ,
720+ sensitivity : "base"
721+ } ) ;
722+
723+ // "==" gets the highest priority, since all filters are inclusive
724+ return ( result === 0 ) || ( filter === ">=" && result > 0 ) || ( filter === "<=" && result < 0 ) ;
725+ }
726+
727+ let filters = $scope . version_filters ;
728+
729+ // Strip the "pre " prefix for pre 1.29.0 lints
730+ let lint_version = lint . version . startsWith ( "pre " ) ? lint . version . substring ( 4 , lint . version . length ) : lint . version ;
731+
732+ for ( const filter in filters ) {
733+ let version_str = filters [ filter ] . version_str ;
734+
735+ // Skip the work for version strings with invalid lengths or characters
736+ if ( ! filters [ filter ] . enabled || ! validate_version_str ( version_str ) ) {
737+ continue ;
738+ }
739+
740+ let result = cmp_version ( lint_version , version_str , filter ) ;
741+ if ( result && filter === "==" ) {
742+ return true ;
743+ } else if ( ! result ) {
744+ return false ;
745+ }
746+
747+ let cmp_filter ;
748+ if ( filter === ">=" ) {
749+ cmp_filter = "<=" ;
750+ } else {
751+ cmp_filter = ">=" ;
752+ }
753+
754+ let cmp_version_str = filters [ cmp_filter ] . version_str ;
755+ if ( ! filters [ cmp_filter ] . enabled || ! validate_version_str ( cmp_version_str ) ) {
756+ return true ;
757+ }
758+
759+ return cmp_version ( lint_version , cmp_version_str , cmp_filter ) ;
760+ }
761+
762+ return true ;
763+ }
764+
627765 $scope . byGroups = function ( lint ) {
628766 return $scope . groups [ lint . group ] ;
629767 } ;
@@ -753,4 +891,4 @@ <h2 class="panel-title">
753891 setTheme ( localStorage . getItem ( 'clippy-lint-list-theme' ) , false ) ;
754892 </ script >
755893</ body >
756- </ html >
894+ </ html >
0 commit comments