@@ -17,6 +17,125 @@ let annotationsOptions = new Map(); // Global options map for annotations
1717let archivedDataLoaded = false ;
1818let loadedBenchmarkRuns = [ ] ; // Loaded results from the js/json files
1919
20+ // Toggle configuration and abstraction
21+ //
22+ // HOW TO ADD A NEW TOGGLE:
23+ // 1. Add HTML checkbox to index.html:
24+ // <label><input type="checkbox" id="my-toggle">My Toggle</label>
25+ //
26+ // 2. Add configuration below:
27+ // 'my-toggle': {
28+ // defaultValue: false, // true = enabled by default, false = disabled by default
29+ // urlParam: 'myParam', // Name shown in URL (?myParam=true)
30+ // invertUrlParam: false, // false = normal behavior, true = legacy inverted logic
31+ // onChange: function(isEnabled) { // Function called when toggle state changes
32+ // // Your logic here
33+ // updateURL(); // Always call this to update the browser URL
34+ // }
35+ // }
36+ //
37+ // 3. (Optional) Add helper function for cleaner, more readable code:
38+ // function isMyToggleEnabled() { return isToggleEnabled('my-toggle'); }
39+ //
40+ // This lets you write: if (isMyToggleEnabled()) { ... }
41+ // Instead of: if (isToggleEnabled('my-toggle')) { ... }
42+ //
43+
44+ const toggleConfigs = {
45+ 'show-notes' : {
46+ defaultValue : true ,
47+ urlParam : 'notes' ,
48+ invertUrlParam : true , // Store false in URL when enabled (legacy behavior)
49+ onChange : function ( isEnabled ) {
50+ document . querySelectorAll ( '.benchmark-note' ) . forEach ( note => {
51+ note . style . display = isEnabled ? 'block' : 'none' ;
52+ } ) ;
53+ updateURL ( ) ;
54+ }
55+ } ,
56+ 'show-unstable' : {
57+ defaultValue : false ,
58+ urlParam : 'unstable' ,
59+ invertUrlParam : false ,
60+ onChange : function ( isEnabled ) {
61+ document . querySelectorAll ( '.benchmark-unstable' ) . forEach ( warning => {
62+ warning . style . display = isEnabled ? 'block' : 'none' ;
63+ } ) ;
64+ filterCharts ( ) ;
65+ }
66+ } ,
67+ 'custom-range' : {
68+ defaultValue : false ,
69+ urlParam : 'customRange' ,
70+ invertUrlParam : false ,
71+ onChange : function ( isEnabled ) {
72+ updateCharts ( ) ;
73+ }
74+ } ,
75+ 'show-archived-data' : {
76+ defaultValue : false ,
77+ urlParam : 'archived' ,
78+ invertUrlParam : false ,
79+ onChange : function ( isEnabled ) {
80+ if ( isEnabled ) {
81+ loadArchivedData ( ) ;
82+ } else {
83+ if ( archivedDataLoaded ) {
84+ location . reload ( ) ;
85+ }
86+ }
87+ updateURL ( ) ;
88+ }
89+ }
90+ } ;
91+
92+ // Generic toggle helper functions
93+ function isToggleEnabled ( toggleId ) {
94+ const toggle = document . getElementById ( toggleId ) ;
95+ return toggle ? toggle . checked : toggleConfigs [ toggleId ] ?. defaultValue || false ;
96+ }
97+
98+ function setupToggle ( toggleId , config ) {
99+ const toggle = document . getElementById ( toggleId ) ;
100+ if ( ! toggle ) return ;
101+
102+ // Set up event listener
103+ toggle . addEventListener ( 'change' , function ( ) {
104+ config . onChange ( toggle . checked ) ;
105+ } ) ;
106+
107+ // Initialize from URL params if present
108+ const urlParam = getQueryParam ( config . urlParam ) ;
109+ if ( urlParam !== null ) {
110+ const urlValue = urlParam === 'true' ;
111+ // Handle inverted URL params (like notes where false means enabled)
112+ toggle . checked = config . invertUrlParam ? ! urlValue : urlValue ;
113+ } else {
114+ // Use default value
115+ toggle . checked = config . defaultValue ;
116+ }
117+ }
118+
119+ function updateToggleURL ( toggleId , config , url ) {
120+ const isEnabled = isToggleEnabled ( toggleId ) ;
121+
122+ if ( config . invertUrlParam ) {
123+ // For inverted params, store in URL when disabled
124+ if ( isEnabled ) {
125+ url . searchParams . delete ( config . urlParam ) ;
126+ } else {
127+ url . searchParams . set ( config . urlParam , 'false' ) ;
128+ }
129+ } else {
130+ // For normal params, store in URL when enabled
131+ if ( ! isEnabled ) {
132+ url . searchParams . delete ( config . urlParam ) ;
133+ } else {
134+ url . searchParams . set ( config . urlParam , 'true' ) ;
135+ }
136+ }
137+ }
138+
20139// DOM Elements
21140let runSelect , selectedRunsDiv , suiteFiltersContainer , tagFiltersContainer ;
22141
@@ -627,30 +746,10 @@ function updateURL() {
627746 url . searchParams . delete ( 'runs' ) ;
628747 }
629748
630- // Add toggle states to URL
631- if ( isNotesEnabled ( ) ) {
632- url . searchParams . delete ( 'notes' ) ;
633- } else {
634- url . searchParams . set ( 'notes' , 'false' ) ;
635- }
636-
637- if ( ! isUnstableEnabled ( ) ) {
638- url . searchParams . delete ( 'unstable' ) ;
639- } else {
640- url . searchParams . set ( 'unstable' , 'true' ) ;
641- }
642-
643- if ( ! isCustomRangesEnabled ( ) ) {
644- url . searchParams . delete ( 'customRange' ) ;
645- } else {
646- url . searchParams . set ( 'customRange' , 'true' ) ;
647- }
648-
649- if ( ! isArchivedDataEnabled ( ) ) {
650- url . searchParams . delete ( 'archived' ) ;
651- } else {
652- url . searchParams . set ( 'archived' , 'true' ) ;
653- }
749+ // Update toggle states in URL using the generic helper
750+ Object . entries ( toggleConfigs ) . forEach ( ( [ toggleId , config ] ) => {
751+ updateToggleURL ( toggleId , config , url ) ;
752+ } ) ;
654753
655754 history . replaceState ( null , '' , url ) ;
656755}
@@ -949,94 +1048,26 @@ function setupSuiteFilters() {
9491048}
9501049
9511050function isNotesEnabled ( ) {
952- const notesToggle = document . getElementById ( 'show-notes' ) ;
953- return notesToggle . checked ;
1051+ return isToggleEnabled ( 'show-notes' ) ;
9541052}
9551053
9561054function isUnstableEnabled ( ) {
957- const unstableToggle = document . getElementById ( 'show-unstable' ) ;
958- return unstableToggle . checked ;
1055+ return isToggleEnabled ( 'show-unstable' ) ;
9591056}
9601057
9611058function isCustomRangesEnabled ( ) {
962- const rangesToggle = document . getElementById ( 'custom-range' ) ;
963- return rangesToggle . checked ;
1059+ return isToggleEnabled ( 'custom-range' ) ;
9641060}
9651061
9661062function isArchivedDataEnabled ( ) {
967- const archivedDataToggle = document . getElementById ( 'show-archived-data' ) ;
968- return archivedDataToggle . checked ;
1063+ return isToggleEnabled ( 'show-archived-data' ) ;
9691064}
9701065
9711066function setupToggles ( ) {
972- const notesToggle = document . getElementById ( 'show-notes' ) ;
973- const unstableToggle = document . getElementById ( 'show-unstable' ) ;
974- const customRangeToggle = document . getElementById ( 'custom-range' ) ;
975- const archivedDataToggle = document . getElementById ( 'show-archived-data' ) ;
976-
977- notesToggle . addEventListener ( 'change' , function ( ) {
978- // Update all note elements visibility
979- document . querySelectorAll ( '.benchmark-note' ) . forEach ( note => {
980- note . style . display = isNotesEnabled ( ) ? 'block' : 'none' ;
981- } ) ;
982- updateURL ( ) ;
983- } ) ;
984-
985- unstableToggle . addEventListener ( 'change' , function ( ) {
986- // Update all unstable warning elements visibility
987- document . querySelectorAll ( '.benchmark-unstable' ) . forEach ( warning => {
988- warning . style . display = isUnstableEnabled ( ) ? 'block' : 'none' ;
989- } ) ;
990- filterCharts ( ) ;
991- } ) ;
992-
993- customRangeToggle . addEventListener ( 'change' , function ( ) {
994- // redraw all charts
995- updateCharts ( ) ;
1067+ // Set up all toggles using the configuration
1068+ Object . entries ( toggleConfigs ) . forEach ( ( [ toggleId , config ] ) => {
1069+ setupToggle ( toggleId , config ) ;
9961070 } ) ;
997-
998- // Add event listener for archived data toggle
999- if ( archivedDataToggle ) {
1000- archivedDataToggle . addEventListener ( 'change' , function ( ) {
1001- if ( archivedDataToggle . checked ) {
1002- loadArchivedData ( ) ;
1003- } else {
1004- if ( archivedDataLoaded ) {
1005- // Reload the page to reset
1006- location . reload ( ) ;
1007- }
1008- }
1009- updateURL ( ) ;
1010- } ) ;
1011- }
1012-
1013- // Initialize from URL params if present
1014- const notesParam = getQueryParam ( 'notes' ) ;
1015- const unstableParam = getQueryParam ( 'unstable' ) ;
1016- const archivedParam = getQueryParam ( 'archived' ) ;
1017-
1018- if ( notesParam !== null ) {
1019- let showNotes = notesParam === 'true' ;
1020- notesToggle . checked = showNotes ;
1021- }
1022-
1023- if ( unstableParam !== null ) {
1024- let showUnstable = unstableParam === 'true' ;
1025- unstableToggle . checked = showUnstable ;
1026- }
1027-
1028- const customRangesParam = getQueryParam ( 'customRange' ) ;
1029- if ( customRangesParam !== null ) {
1030- customRangeToggle . checked = customRangesParam === 'true' ;
1031- }
1032-
1033- if ( archivedDataToggle && archivedParam !== null ) {
1034- archivedDataToggle . checked = archivedParam === 'true' ;
1035-
1036- if ( archivedDataToggle . checked ) {
1037- loadArchivedData ( ) ;
1038- }
1039- }
10401071}
10411072
10421073function setupTagFilters ( ) {
@@ -1154,9 +1185,10 @@ function initializeCharts() {
11541185 // Setup UI components
11551186 setupRunSelector ( ) ;
11561187 setupSuiteFilters ( ) ;
1157- setupTagFilters ( ) ;
11581188 setupToggles ( ) ;
11591189 initializePlatformTab ( ) ;
1190+ // Setup tag filters after everything else is ready
1191+ setupTagFilters ( ) ;
11601192
11611193 // Apply URL parameters
11621194 const regexParam = getQueryParam ( 'regex' ) ;
0 commit comments