@@ -122,6 +122,81 @@ html.dark .http-ver[data-ver="ws"].active { color: #22d3ee; background: rgba(8,1
122122</script >
123123</div >
124124
125+ <div id =" timeline-link-bar " style =" display :flex ; margin-top :0.5rem ; padding :0.45rem 0.9rem ; justify-content :flex-end ; align-items :center ; gap :0.5rem ; font-size :0.8rem ; color :#64748b ;" >
126+ <span id =" timeline-link-prefix " >📈 Browse historical benchmark results on</span >
127+ <a id="timeline-link"
128+ href="https://kaliumhexacyanoferrat.github.io/HttpArena-Timeline/ "
129+ target="_ blank" rel="noopener"
130+ style="color:#7c3aed; text-decoration: none ; font-weight:600;">HttpArena Timeline →</a >
131+ </div >
132+ <style >
133+ html .dark #timeline-link-bar { color :#94a3b8 ; }
134+ html .dark #timeline-link { color :#a78bfa ; }
135+ #timeline-link :hover { text-decoration :underline ; }
136+ </style >
137+ <script >
138+ (function () {
139+ var TIMELINE_BASE = ' https://kaliumhexacyanoferrat.github.io/HttpArena-Timeline/' ;
140+ /* Per-version: wrapper id and panel class. Composite has no entry here —
141+ it doesn't map onto a single test+conns pair, so the bar keeps the
142+ generic prefix + home URL for that view. */
143+ var VERSION_CFG = {
144+ h1iso: { wrapper: ' lb-h1iso-wrapper' , panel: ' lb-panel' },
145+ h1wk: { wrapper: ' lb-h1wk-wrapper' , panel: ' lb-panel' },
146+ h2: { wrapper: ' lb-h2-wrapper' , panel: ' lb-panel-h2' },
147+ gateway: { wrapper: ' lb-gateway-wrapper' , panel: ' lb-panel-gw' },
148+ h3: { wrapper: ' lb-h3-wrapper' , panel: ' lb-panel-h3' },
149+ grpc: { wrapper: ' lb-grpc-wrapper' , panel: ' lb-panel-grpc' },
150+ ws: { wrapper: ' lb-ws-wrapper' , panel: ' lb-panel-ws' }
151+ };
152+ var GENERIC_PREFIX = ' 📈 Browse historical benchmark results on' ;
153+ var SPECIFIC_PREFIX = ' 📈 Track this test over time:' ;
154+
155+ function setGeneric () {
156+ var p = document .getElementById (' timeline-link-prefix' );
157+ var l = document .getElementById (' timeline-link' );
158+ if (p) p .textContent = GENERIC_PREFIX ;
159+ if (l) l .href = TIMELINE_BASE ;
160+ }
161+
162+ function update () {
163+ var verEl = document .querySelector (' .http-ver.active' );
164+ var v = verEl ? verEl .dataset .ver : ' composite' ;
165+ var cfg = VERSION_CFG [v];
166+ if (! cfg) { setGeneric (); return ; }
167+ var wrap = document .getElementById (cfg .wrapper );
168+ if (! wrap) { setGeneric (); return ; }
169+ var panel = wrap .querySelector (' .' + cfg .panel + ' .active' );
170+ if (! panel || ! panel .dataset .panel ) { setGeneric (); return ; }
171+ var test = panel .dataset .panel ;
172+ var connTab = panel .querySelector (' .lb-conn-tab.active' );
173+ var conns = connTab ? connTab .dataset .conns : null ;
174+ if (! conns || conns === ' best' ) {
175+ /* "Best" aggregates across conn counts; pick the highest numeric
176+ value declared on the panel for the timeline deep link. */
177+ var declared = (panel .dataset .conns || ' ' ).split (' ,' )
178+ .filter (function (c ) { return / ^ \d + $ / .test (c); })
179+ .map (Number );
180+ if (! declared .length ) { setGeneric (); return ; }
181+ conns = Math .max .apply (null , declared);
182+ }
183+ var p = document .getElementById (' timeline-link-prefix' );
184+ var l = document .getElementById (' timeline-link' );
185+ if (p) p .textContent = SPECIFIC_PREFIX ;
186+ if (l) l .href = TIMELINE_BASE + ' #test=' + test + ' -' + conns;
187+ }
188+
189+ /* Poll once a frame for the first 2 seconds in case shortcode scripts
190+ mutate state asynchronously, then settle into a low-frequency check
191+ that catches any tab/filter interaction we didn't event-hook. */
192+ var ticks = 0 ;
193+ var fast = setInterval (function () {
194+ update ();
195+ if (++ ticks > 30 ) { clearInterval (fast); setInterval (update, 400 ); }
196+ }, 60 );
197+ })();
198+ </script >
199+
125200<div id =" lb-h1iso-wrapper " style =" display :none ;" >
126201{{< leaderboard-h1-isolated >}}
127202</div >
0 commit comments