1+ document . addEventListener ( 'DOMContentLoaded' , function ( ) {
2+ // Smooth scrolling for glossary navigation
3+ document . querySelectorAll ( '.glossary-nav a' ) . forEach ( anchor => {
4+ anchor . addEventListener ( 'click' , function ( e ) {
5+ e . preventDefault ( ) ;
6+ const targetId = this . getAttribute ( 'href' ) ;
7+ const targetElement = document . querySelector ( targetId ) ;
8+
9+ if ( targetElement ) {
10+ const headerOffset = 120 ; // Adjust for fixed header and nav
11+ const elementPosition = targetElement . getBoundingClientRect ( ) . top ;
12+ const offsetPosition = elementPosition + window . pageYOffset - headerOffset ;
13+
14+ window . scrollTo ( {
15+ top : offsetPosition ,
16+ behavior : 'smooth'
17+ } ) ;
18+ }
19+ } ) ;
20+ } ) ;
21+
22+ // Check if URL has a hash
23+ if ( window . location . hash ) {
24+ const targetId = window . location . hash ;
25+ const targetElement = document . querySelector ( targetId ) ;
26+
27+ if ( targetElement ) {
28+ setTimeout ( function ( ) {
29+ const headerOffset = 120 ;
30+ const elementPosition = targetElement . getBoundingClientRect ( ) . top ;
31+ const offsetPosition = elementPosition + window . pageYOffset - headerOffset ;
32+
33+ window . scrollTo ( {
34+ top : offsetPosition ,
35+ behavior : 'smooth'
36+ } ) ;
37+
38+ // Highlight the term briefly
39+ targetElement . classList . add ( 'highlight-term' ) ;
40+ setTimeout ( function ( ) {
41+ targetElement . classList . remove ( 'highlight-term' ) ;
42+ } , 2000 ) ;
43+ } , 300 ) ; // Small delay to ensure page is loaded
44+ }
45+ }
46+
47+ const searchInput = document . getElementById ( 'glossary-search' ) ;
48+ if ( ! searchInput ) return ;
49+
50+ searchInput . addEventListener ( 'input' , function ( ) {
51+ const searchTerm = this . value . toLowerCase ( ) . trim ( ) ;
52+ const allTerms = document . querySelectorAll ( 'dt[id^="term-"]' ) ;
53+
54+ allTerms . forEach ( term => {
55+ const termText = term . textContent . toLowerCase ( ) ;
56+ const definition = term . nextElementSibling ;
57+ const definitionText = definition . textContent . toLowerCase ( ) ;
58+
59+ if ( termText . includes ( searchTerm ) || definitionText . includes ( searchTerm ) ) {
60+ term . style . display = '' ;
61+ definition . style . display = '' ;
62+ // Show parent section
63+ const section = term . closest ( 'section' ) ;
64+ if ( section ) {
65+ section . style . display = '' ;
66+ }
67+ } else {
68+ term . style . display = 'none' ;
69+ definition . style . display = 'none' ;
70+
71+ // Hide section if all terms are hidden
72+ const section = term . closest ( 'section' ) ;
73+ if ( section ) {
74+ const visibleTermsInSection = section . querySelectorAll ( 'dt[style=""]' ) . length ;
75+ if ( visibleTermsInSection === 0 ) {
76+ section . style . display = 'none' ;
77+ }
78+ }
79+ }
80+ } ) ;
81+
82+ // Show "no results" message if needed
83+ const visibleTerms = document . querySelectorAll ( 'dt[id^="term-"]:not([style="display: none;"])' ) ;
84+ const noResultsMsg = document . getElementById ( 'no-results-message' ) ;
85+
86+ if ( visibleTerms . length === 0 && searchTerm !== '' ) {
87+ if ( ! noResultsMsg ) {
88+ const msg = document . createElement ( 'div' ) ;
89+ msg . id = 'no-results-message' ;
90+ msg . className = 'alert alert-info mt-4' ;
91+ msg . innerHTML = `No terms found matching "<strong>${ searchTerm } </strong>". Try a different search term.` ;
92+ document . querySelector ( '.col-lg-8' ) . appendChild ( msg ) ;
93+ } else {
94+ noResultsMsg . innerHTML = `No terms found matching "<strong>${ searchTerm } </strong>". Try a different search term.` ;
95+ noResultsMsg . style . display = '' ;
96+ }
97+ } else if ( noResultsMsg ) {
98+ noResultsMsg . style . display = 'none' ;
99+ }
100+ } ) ;
101+
102+ // Copy citation functionality
103+ document . querySelectorAll ( '.copy-btn' ) . forEach ( button => {
104+ button . addEventListener ( 'click' , function ( ) {
105+ const citationText = this . previousElementSibling . textContent . trim ( ) ;
106+
107+ navigator . clipboard . writeText ( citationText ) . then ( ( ) => {
108+ // Change button text temporarily
109+ const originalText = this . innerHTML ;
110+ this . innerHTML = '<i class="fas fa-check"></i> Copied!' ;
111+
112+ setTimeout ( ( ) => {
113+ this . innerHTML = originalText ;
114+ } , 2000 ) ;
115+ } ) . catch ( err => {
116+ console . error ( 'Could not copy text: ' , err ) ;
117+ } ) ;
118+ } ) ;
119+ } ) ;
120+ } ) ;
0 commit comments