@@ -100,6 +100,42 @@ function showInfoModal(title, steps) {
100100 overlay . addEventListener ( "click" , overlayClick ) ;
101101}
102102
103+ // Themed confirmation modal (in-page) helper
104+ function showConfirm ( message , onConfirm , onCancel ) {
105+ var overlay = document . getElementById ( 'confirmModalOverlay' ) ;
106+ var msg = document . getElementById ( 'confirmModalMessage' ) ;
107+ var okBtn = document . getElementById ( 'confirmOkBtn' ) ;
108+ var cancelBtn = document . getElementById ( 'confirmCancelBtn' ) ;
109+ if ( ! overlay || ! msg || ! okBtn || ! cancelBtn ) {
110+ // fallback to window.confirm
111+ var ok = window . confirm ( message ) ;
112+ if ( ok && typeof onConfirm === 'function' ) onConfirm ( ) ;
113+ else if ( ! ok && typeof onCancel === 'function' ) onCancel ( ) ;
114+ return ;
115+ }
116+
117+ msg . textContent = message ;
118+ overlay . classList . add ( 'active' ) ;
119+
120+ function cleanup ( ) {
121+ overlay . classList . remove ( 'active' ) ;
122+ okBtn . removeEventListener ( 'click' , okHandler ) ;
123+ cancelBtn . removeEventListener ( 'click' , cancelHandler ) ;
124+ overlay . removeEventListener ( 'click' , overlayClick ) ;
125+ document . removeEventListener ( 'keydown' , keyHandler ) ;
126+ }
127+
128+ function okHandler ( e ) { e . stopPropagation ( ) ; cleanup ( ) ; if ( typeof onConfirm === 'function' ) onConfirm ( ) ; }
129+ function cancelHandler ( e ) { e . stopPropagation ( ) ; cleanup ( ) ; if ( typeof onCancel === 'function' ) onCancel ( ) ; }
130+ function overlayClick ( e ) { if ( e . target === overlay ) { cancelHandler ( e ) ; } }
131+ function keyHandler ( e ) { if ( e . key === 'Escape' ) cancelHandler ( e ) ; }
132+
133+ okBtn . addEventListener ( 'click' , okHandler ) ;
134+ cancelBtn . addEventListener ( 'click' , cancelHandler ) ;
135+ overlay . addEventListener ( 'click' , overlayClick ) ;
136+ document . addEventListener ( 'keydown' , keyHandler ) ;
137+ }
138+
103139var currentProjectName = "" ;
104140
105141function setupModalInfoButton ( projectName ) {
@@ -797,7 +833,7 @@ document.addEventListener("DOMContentLoaded", function () {
797833 label . addEventListener ( "click" , function ( ) {
798834 syncSearchInputs ( search , searchInput ) ;
799835 currentSearchQuery = search ;
800- performSearch ( ) ;
836+ performSearch ( true ) ;
801837 closeDropdown ( ) ;
802838 } ) ;
803839
@@ -813,9 +849,27 @@ document.addEventListener("DOMContentLoaded", function () {
813849 renderRecentSearches ( ) ;
814850 } ) ;
815851
816- recentSearchesList . appendChild ( item ) ;
817- } ) ;
818- }
852+ recentSearchesList . appendChild ( item ) ;
853+ } ) ;
854+
855+ // Wire up header Clear All button (if present)
856+ var headerClearBtn = document . getElementById ( 'clearRecentBtn' ) ;
857+ if ( headerClearBtn ) {
858+ headerClearBtn . style . display = recentSearches . length ? 'inline-flex' : 'none' ;
859+ headerClearBtn . onclick = function ( e ) {
860+ e . stopPropagation ( ) ;
861+ if ( ! recentSearches || recentSearches . length === 0 ) return ;
862+ showConfirm ( 'Clear all recent searches? This cannot be undone.' , function ( ) {
863+ recentSearches = [ ] ;
864+ localStorage . setItem ( 'recentSearches' , JSON . stringify ( recentSearches ) ) ;
865+ renderRecentSearches ( ) ;
866+ closeDropdown ( ) ;
867+ } , function ( ) {
868+ // cancelled
869+ } ) ;
870+ } ;
871+ }
872+ }
819873
820874 recentSearchesSection . style . display = "block" ;
821875 if ( resultsSection ) resultsSection . style . display = "none" ;
@@ -897,7 +951,7 @@ document.addEventListener("DOMContentLoaded", function () {
897951 if ( ! searchInput ) return ;
898952 searchInput . value = title ;
899953 currentSearchQuery = title . toLowerCase ( ) ;
900- performSearch ( ) ;
954+ performSearch ( true ) ;
901955 closeDropdown ( ) ;
902956 if ( projectsSection ) {
903957 projectsSection . scrollIntoView ( {
@@ -907,7 +961,8 @@ document.addEventListener("DOMContentLoaded", function () {
907961 }
908962 }
909963
910- function performSearch ( ) {
964+ function performSearch ( commit ) {
965+ if ( commit === undefined ) commit = true ;
911966 var query = currentSearchQuery ;
912967 if ( ! query ) {
913968 applyCategoryFilter ( currentCategory ) ;
@@ -923,12 +978,14 @@ document.addEventListener("DOMContentLoaded", function () {
923978 syncStickyTabs ( "all" ) ;
924979 }
925980
926- recentSearches = recentSearches . filter ( function ( s ) {
927- return s !== query ;
928- } ) ;
929- recentSearches . unshift ( query ) ;
930- recentSearches = recentSearches . slice ( 0 , 10 ) ;
931- localStorage . setItem ( "recentSearches" , JSON . stringify ( recentSearches ) ) ;
981+ if ( commit ) {
982+ recentSearches = recentSearches . filter ( function ( s ) {
983+ return s !== query ;
984+ } ) ;
985+ recentSearches . unshift ( query ) ;
986+ recentSearches = recentSearches . slice ( 0 , 10 ) ;
987+ localStorage . setItem ( "recentSearches" , JSON . stringify ( recentSearches ) ) ;
988+ }
932989
933990 var visibleCount = 0 ;
934991 var favorites = JSON . parse ( localStorage . getItem ( "favorites" ) || "[]" ) ;
@@ -982,7 +1039,7 @@ document.addEventListener("DOMContentLoaded", function () {
9821039 currentSearchQuery = query ;
9831040 if ( searchLoader ) searchLoader . style . display = query ? "block" : "none" ;
9841041 debouncedSearch ( query ) ;
985- performSearch ( ) ;
1042+ performSearch ( false ) ;
9861043 } ) ;
9871044
9881045 input . addEventListener ( "focus" , function ( ) {
@@ -992,11 +1049,22 @@ document.addEventListener("DOMContentLoaded", function () {
9921049 renderRecentSearches ( ) ;
9931050 } ) ;
9941051
1052+ input . addEventListener ( "blur" , function ( ) {
1053+ if ( currentSearchQuery && currentSearchQuery . trim ( ) ) {
1054+ performSearch ( true ) ;
1055+ }
1056+ } ) ;
1057+
9951058 input . addEventListener ( "keydown" , function ( e ) {
9961059 if ( e . key === "Escape" ) {
9971060 closeDropdown ( ) ;
9981061 input . blur ( ) ;
9991062 }
1063+ if ( e . key === "Enter" ) {
1064+ e . preventDefault ( ) ;
1065+ performSearch ( true ) ;
1066+ closeDropdown ( ) ;
1067+ }
10001068 } ) ;
10011069 } ) ;
10021070 }
0 commit comments