1+ var reducedMotion = window . matchMedia ( "(prefers-reduced-motion: reduce)" ) ;
2+
13function getScrollBehavior ( ) {
2- return window . matchMedia ( "(prefers-reduced-motion: reduce)" ) . matches
3- ? "auto"
4- : "smooth" ;
4+ return reducedMotion . matches ? "auto" : "smooth" ;
55}
66
7- // State
8- let activeFilter = null ; // string value or null
7+ let activeFilter = null ;
98let activeSort = { col : "stars" , order : "desc" } ;
109const searchInput = document . querySelector ( ".search" ) ;
1110const filterBar = document . querySelector ( ".filter-bar" ) ;
@@ -70,7 +69,6 @@ document.querySelectorAll("[data-scroll-to]").forEach(function (link) {
7069 observer . observe ( hero ) ;
7170} ) ( ) ;
7271
73- // Relative time formatting
7472function relativeTime ( isoStr ) {
7573 const date = new Date ( isoStr ) ;
7674 const now = new Date ( ) ;
@@ -89,7 +87,6 @@ function relativeTime(isoStr) {
8987 return diffYears === 1 ? "1 year ago" : diffYears + " years ago" ;
9088}
9189
92- // Format all commit date cells
9390document . querySelectorAll ( ".col-commit[data-commit]" ) . forEach ( function ( td ) {
9491 const time = td . querySelector ( "time" ) ;
9592 if ( time ) time . textContent = relativeTime ( td . dataset . commit ) ;
@@ -101,14 +98,14 @@ document
10198 time . textContent = relativeTime ( time . getAttribute ( "datetime" ) ) ;
10299 } ) ;
103100
104- // Store original row order for sort reset
105101rows . forEach ( function ( row , i ) {
106102 row . _origIndex = i ;
107103 row . _expandRow = row . nextElementSibling ;
108104} ) ;
109105
110106function collapseAll ( ) {
111- const openRows = document . querySelectorAll ( ".table tbody tr.row.open" ) ;
107+ if ( ! tbody ) return ;
108+ var openRows = tbody . querySelectorAll ( "tr.row.open" ) ;
112109 openRows . forEach ( function ( row ) {
113110 row . classList . remove ( "open" ) ;
114111 row . setAttribute ( "aria-expanded" , "false" ) ;
@@ -119,18 +116,16 @@ function applyFilters() {
119116 const query = searchInput ? searchInput . value . toLowerCase ( ) . trim ( ) : "" ;
120117 let visibleCount = 0 ;
121118
122- // Collapse all expanded rows on filter/search change
123119 collapseAll ( ) ;
124120
125121 rows . forEach ( function ( row ) {
126122 let show = true ;
127123
128124 if ( activeFilter ) {
129- const tags = row . dataset . tags ;
130- show = tags ? tags . split ( "||" ) . indexOf ( activeFilter ) !== - 1 : false ;
125+ var rowTags = row . dataset . tags ;
126+ show = rowTags ? rowTags . split ( "||" ) . includes ( activeFilter ) : false ;
131127 }
132128
133- // Text search
134129 if ( show && query ) {
135130 if ( ! row . _searchText ) {
136131 let text = row . textContent . toLowerCase ( ) ;
@@ -156,12 +151,10 @@ function applyFilters() {
156151
157152 if ( noResults ) noResults . hidden = visibleCount > 0 ;
158153
159- // Update tag highlights
160154 tags . forEach ( function ( tag ) {
161155 tag . classList . toggle ( "active" , activeFilter === tag . dataset . value ) ;
162156 } ) ;
163157
164- // Filter bar
165158 if ( filterBar ) {
166159 if ( activeFilter ) {
167160 filterBar . classList . add ( "visible" ) ;
@@ -243,10 +236,12 @@ function sortRows() {
243236 applyFilters ( ) ;
244237}
245238
239+ var sortHeaders = document . querySelectorAll ( "th[data-sort]" ) ;
240+
246241function updateSortIndicators ( ) {
247- document . querySelectorAll ( "th[data-sort]" ) . forEach ( function ( th ) {
242+ sortHeaders . forEach ( function ( th ) {
248243 th . classList . remove ( "sort-asc" , "sort-desc" ) ;
249- if ( activeSort && th . dataset . sort === activeSort . col ) {
244+ if ( th . dataset . sort === activeSort . col ) {
250245 th . classList . add ( "sort-" + activeSort . order ) ;
251246 th . setAttribute (
252247 "aria-sort" ,
@@ -287,7 +282,6 @@ if (tbody) {
287282 } ) ;
288283}
289284
290- // Tag click: filter
291285tags . forEach ( function ( tag ) {
292286 tag . addEventListener ( "click" , function ( e ) {
293287 e . preventDefault ( ) ;
@@ -297,15 +291,13 @@ tags.forEach(function (tag) {
297291 } ) ;
298292} ) ;
299293
300- // Clear filter
301294if ( filterClear ) {
302295 filterClear . addEventListener ( "click" , function ( ) {
303296 activeFilter = null ;
304297 applyFilters ( ) ;
305298 } ) ;
306299}
307300
308- // No-results clear
309301const noResultsClear = document . querySelector ( ".no-results-clear" ) ;
310302if ( noResultsClear ) {
311303 noResultsClear . addEventListener ( "click" , function ( ) {
@@ -315,13 +307,12 @@ if (noResultsClear) {
315307 } ) ;
316308}
317309
318- // Column sorting
319- document . querySelectorAll ( "th[data-sort]" ) . forEach ( function ( th ) {
310+ sortHeaders . forEach ( function ( th ) {
320311 th . addEventListener ( "click" , function ( ) {
321312 const col = th . dataset . sort ;
322313 const defaultOrder = col === "name" ? "asc" : "desc" ;
323314 const altOrder = defaultOrder === "asc" ? "desc" : "asc" ;
324- if ( activeSort && activeSort . col === col ) {
315+ if ( activeSort . col === col ) {
325316 if ( activeSort . order === defaultOrder )
326317 activeSort = { col : col , order : altOrder } ;
327318 else activeSort = { col : "stars" , order : "desc" } ;
@@ -333,15 +324,13 @@ document.querySelectorAll("th[data-sort]").forEach(function (th) {
333324 } ) ;
334325} ) ;
335326
336- // Search input
337327if ( searchInput ) {
338328 let searchTimer ;
339329 searchInput . addEventListener ( "input" , function ( ) {
340330 clearTimeout ( searchTimer ) ;
341331 searchTimer = setTimeout ( applyFilters , 150 ) ;
342332 } ) ;
343333
344- // Keyboard shortcuts
345334 document . addEventListener ( "keydown" , function ( e ) {
346335 if (
347336 e . key === "/" &&
@@ -363,7 +352,6 @@ if (searchInput) {
363352 } ) ;
364353}
365354
366- // Back to top
367355const backToTop = document . querySelector ( ".back-to-top" ) ;
368356const resultsSection = document . querySelector ( "#library-index" ) ;
369357const tableWrap = document . querySelector ( ".table-wrap" ) ;
@@ -403,7 +391,6 @@ if (backToTop) {
403391 updateBackToTopVisibility ( ) ;
404392}
405393
406- // Restore state from URL
407394( function ( ) {
408395 const params = new URLSearchParams ( location . search ) ;
409396 const q = params . get ( "q" ) ;
0 commit comments