@@ -107,6 +107,33 @@ function getPinnedItemIndexFromEvent(event) {
107107 return - 1 ;
108108}
109109
110+ /**
111+ * Resolve a visible Run Code item button from Alt+Q/W/E/R/T/Y/U/I/O/P.
112+ * @param {KeyboardEvent } event
113+ * @returns {HTMLButtonElement | null }
114+ */
115+ function getRunCodeButtonFromEvent ( event ) {
116+ if (
117+ ! event . altKey ||
118+ event . metaKey ||
119+ event . ctrlKey ||
120+ event . shiftKey ||
121+ event . isComposing
122+ ) {
123+ return null ;
124+ }
125+
126+ const key = getShortcutKeyFromEvent ( event ) ;
127+ if ( ! RUN_CODE_SHORTCUT_KEYS . includes ( key ) ) {
128+ return null ;
129+ }
130+
131+ const button = runCodeList ?. querySelector (
132+ `[data-run-code-shortcut="${ key } "]` ,
133+ ) ;
134+ return button instanceof HTMLButtonElement ? button : null ;
135+ }
136+
110137/**
111138 * Determine whether the popup search field is currently the active element.
112139 * @returns {boolean }
@@ -141,6 +168,10 @@ function shouldSuppressSearchInputAltShortcut(event) {
141168 return true ;
142169 }
143170
171+ if ( getRunCodeButtonFromEvent ( event ) ) {
172+ return true ;
173+ }
174+
144175 return Object . values ( SHORTCUT_CONFIG ) . some ( ( config ) => config . key === key ) ;
145176}
146177
@@ -278,6 +309,19 @@ const PINNED_SEARCH_RESULTS_STORAGE_KEY = 'pinnedSearchResults';
278309const SEARCH_RESULT_WEIGHTS_KEY = 'searchResultWeights' ;
279310const RUN_CODE_IN_PAGE_RULES_STORAGE_KEY = 'runCodeInPageRules' ;
280311const RUN_CODE_IN_PAGE_EXECUTE_MESSAGE = 'runCodeInPage:execute' ;
312+ /** @type {string[] } */
313+ const RUN_CODE_SHORTCUT_KEYS = [
314+ 'q' ,
315+ 'w' ,
316+ 'e' ,
317+ 'r' ,
318+ 't' ,
319+ 'y' ,
320+ 'u' ,
321+ 'i' ,
322+ 'o' ,
323+ 'p' ,
324+ ] ;
281325
282326/** @type {string[] } Default pinned shortcuts */
283327const DEFAULT_PINNED_SHORTCUTS = [
@@ -1060,24 +1104,36 @@ async function refreshMatchingRunCodeSection() {
10601104 }
10611105
10621106 runCodeList . textContent = '' ;
1107+ let renderedRunCodeItemCount = 0 ;
10631108 matchingRules . forEach ( ( rule ) => {
10641109 if ( ! rule . id ) {
10651110 return ;
10661111 }
10671112 const title = getRunCodeRuleTitle ( rule ) ;
1113+ const shortcutKey =
1114+ RUN_CODE_SHORTCUT_KEYS [ renderedRunCodeItemCount ] || '' ;
10681115 const button = document . createElement ( 'button' ) ;
10691116 button . type = 'button' ;
10701117 button . className =
10711118 'badge cursor-pointer hover:opacity-80 border-none transition-all duration-200 run-code-item' ;
10721119 button . setAttribute ( 'role' , 'listitem' ) ;
10731120 button . title = title ;
1121+ if ( shortcutKey ) {
1122+ button . dataset . runCodeShortcut = shortcutKey ;
1123+ }
10741124 button . innerHTML = `
1125+ ${
1126+ shortcutKey
1127+ ? `<span class="run-code-shortcut-key pointer-events-none">${ shortcutKey } </span>`
1128+ : ''
1129+ }
10751130 <span class="truncate pointer-events-none">${ escapeHtml ( title ) } </span>
10761131 ` ;
10771132 button . addEventListener ( 'click' , ( ) => {
10781133 void runCodeInPage ( rule , button , tabId ) ;
10791134 } ) ;
10801135 runCodeList . appendChild ( button ) ;
1136+ renderedRunCodeItemCount += 1 ;
10811137 } ) ;
10821138
10831139 setRunCodeSectionHidden ( runCodeList . children . length === 0 ) ;
@@ -3958,6 +4014,14 @@ async function initializeBookmarksSearch(
39584014 return ;
39594015 }
39604016
4017+ const runCodeButton = getRunCodeButtonFromEvent ( event ) ;
4018+ if ( runCodeButton ) {
4019+ event . preventDefault ( ) ;
4020+ event . stopPropagation ( ) ;
4021+ runCodeButton . click ( ) ;
4022+ return ;
4023+ }
4024+
39614025 const matchedShortcut = getPinnedShortcutActionFromEvent ( event ) ;
39624026 if ( ! matchedShortcut ) {
39634027 return ;
0 commit comments