11// Copyright 2026 The Gitea Authors. All rights reserved.
22// SPDX-License-Identifier: MIT
33
4- import { initRepoShortcuts } from './repo-shortcuts.ts' ;
4+ import { initRepoCodeSearchShortcut } from './repo-shortcuts.ts' ;
55
6- describe ( 'Repository Keyboard Shortcuts' , ( ) => {
7- let fileSearchInput : HTMLInputElement ;
6+ describe ( 'Repository Code Search Shortcut Hint' , ( ) => {
87 let codeSearchInput : HTMLInputElement ;
98 let codeSearchHint : HTMLElement ;
109
1110 beforeEach ( ( ) => {
12- // Set up DOM structure
11+ // Set up DOM structure for code search
1312 document . body . innerHTML = `
14- <div class="repo-file-search-container">
15- <div class="repo-file-search-input-wrapper">
16- <input type="text" placeholder="Go to file">
17- <kbd class="repo-search-shortcut-hint">T</kbd>
18- </div>
19- </div>
2013 <div class="repo-home-sidebar-top">
2114 <div class="repo-code-search-input-wrapper">
22- <input name="q" class="code-search-input" placeholder="Search code">
15+ <input name="q" class="code-search-input" placeholder="Search code" data-global-keyboard-shortcut="s" data-global-init="initRepoCodeSearchShortcut" >
2316 <kbd class="repo-search-shortcut-hint">S</kbd>
2417 </div>
2518 </div>
2619 ` ;
2720
28- fileSearchInput = document . querySelector ( '.repo-file-search-container input' ) ! ;
2921 codeSearchInput = document . querySelector ( '.code-search-input' ) ! ;
3022 codeSearchHint = document . querySelector ( '.repo-code-search-input-wrapper .repo-search-shortcut-hint' ) ! ;
3123
32- initRepoShortcuts ( ) ;
24+ // Initialize the shortcut hint functionality directly
25+ initRepoCodeSearchShortcut ( codeSearchInput ) ;
3326 } ) ;
3427
3528 afterEach ( ( ) => {
3629 document . body . innerHTML = '' ;
3730 } ) ;
3831
39- test ( 'T key focuses file search input' , ( ) => {
40- const event = new KeyboardEvent ( 'keydown' , { key : 't' , bubbles : true } ) ;
41- document . dispatchEvent ( event ) ;
42-
43- expect ( document . activeElement ) . toBe ( fileSearchInput ) ;
44- } ) ;
45-
46- test ( 'Shift+T (uppercase T) focuses file search input' , ( ) => {
47- const event = new KeyboardEvent ( 'keydown' , { key : 'T' , bubbles : true } ) ;
48- document . dispatchEvent ( event ) ;
49-
50- expect ( document . activeElement ) . toBe ( fileSearchInput ) ;
51- } ) ;
52-
53- test ( 'S key focuses code search input' , ( ) => {
54- const event = new KeyboardEvent ( 'keydown' , { key : 's' , bubbles : true } ) ;
55- document . dispatchEvent ( event ) ;
56-
57- expect ( document . activeElement ) . toBe ( codeSearchInput ) ;
58- } ) ;
59-
60- test ( 'Shortcuts do not trigger when typing in input' , ( ) => {
61- // Focus on an input field first
62- const otherInput = document . createElement ( 'input' ) ;
63- document . body . append ( otherInput ) ;
64- otherInput . focus ( ) ;
65-
66- const event = new KeyboardEvent ( 'keydown' , { key : 't' , bubbles : true } ) ;
67- Object . defineProperty ( event , 'target' , { value : otherInput } ) ;
68- document . dispatchEvent ( event ) ;
69-
70- // File search should not be focused because we're already in an input
71- expect ( document . activeElement ) . toBe ( otherInput ) ;
72- } ) ;
73-
74- test ( 'Shortcuts do not trigger with Ctrl modifier' , ( ) => {
75- const event = new KeyboardEvent ( 'keydown' , { key : 't' , ctrlKey : true , bubbles : true } ) ;
76- document . dispatchEvent ( event ) ;
77-
78- expect ( document . activeElement ) . not . toBe ( fileSearchInput ) ;
79- } ) ;
80-
81- test ( 'Shortcuts do not trigger with Meta modifier' , ( ) => {
82- const event = new KeyboardEvent ( 'keydown' , { key : 's' , metaKey : true , bubbles : true } ) ;
83- document . dispatchEvent ( event ) ;
84-
85- expect ( document . activeElement ) . not . toBe ( codeSearchInput ) ;
86- } ) ;
87-
88- test ( 'Shortcuts do not trigger with Alt modifier' , ( ) => {
89- const event = new KeyboardEvent ( 'keydown' , { key : 't' , altKey : true , bubbles : true } ) ;
90- document . dispatchEvent ( event ) ;
91-
92- expect ( document . activeElement ) . not . toBe ( fileSearchInput ) ;
93- } ) ;
94-
9532 test ( 'Code search hint hides when input has value' , ( ) => {
9633 // Initially visible
9734 expect ( codeSearchHint . style . display ) . toBe ( '' ) ;
@@ -118,16 +55,20 @@ describe('Repository Keyboard Shortcuts', () => {
11855 expect ( codeSearchHint . style . display ) . toBe ( '' ) ;
11956 } ) ;
12057
121- test ( 'Escape key blurs code search input' , ( ) => {
122- // Focus the code search input first
58+ test ( 'Escape key clears and blurs code search input' , ( ) => {
59+ // Set a value and focus the input
60+ codeSearchInput . value = 'test' ;
61+ codeSearchInput . dispatchEvent ( new Event ( 'input' ) ) ;
12362 codeSearchInput . focus ( ) ;
12463 expect ( document . activeElement ) . toBe ( codeSearchInput ) ;
64+ expect ( codeSearchInput . value ) . toBe ( 'test' ) ;
12565
126- // Press Escape directly on the input (the input has its own keydown handler)
66+ // Press Escape directly on the input
12767 const event = new KeyboardEvent ( 'keydown' , { key : 'Escape' , bubbles : true } ) ;
12868 codeSearchInput . dispatchEvent ( event ) ;
12969
130- // Should no longer be focused
70+ // Value should be cleared and input should be blurred
71+ expect ( codeSearchInput . value ) . toBe ( '' ) ;
13172 expect ( document . activeElement ) . not . toBe ( codeSearchInput ) ;
13273 } ) ;
13374
@@ -149,4 +90,16 @@ describe('Repository Keyboard Shortcuts', () => {
14990 // Should be visible again
15091 expect ( codeSearchHint . style . display ) . toBe ( '' ) ;
15192 } ) ;
93+
94+ test ( 'Change event also updates hint visibility' , ( ) => {
95+ // Initially visible
96+ expect ( codeSearchHint . style . display ) . toBe ( '' ) ;
97+
98+ // Set value via change event (e.g., browser autofill)
99+ codeSearchInput . value = 'autofilled' ;
100+ codeSearchInput . dispatchEvent ( new Event ( 'change' ) ) ;
101+
102+ // Should be hidden
103+ expect ( codeSearchHint . style . display ) . toBe ( 'none' ) ;
104+ } ) ;
152105} ) ;
0 commit comments