@@ -23,6 +23,9 @@ const emojis = ['🚀', '🐿️', '⚡️', '🤌', '🥳', '🥰', '🤩', '
2323// Be careful not to select the "Submit review" button in the dialog
2424const reviewMenuButtonSelector = 'button[class*="ReviewMenuButton-module__ReviewMenuButton"]' ;
2525
26+ const openReviewMenuDeepLink = 'review-changes-modal' ;
27+ const openReviewMenuDeepLinkSelector = `#${ openReviewMenuDeepLink } ` ;
28+
2629async function quickApprove ( event : DelegateEvent < MouseEvent > ) : Promise < void > {
2730 const approval = event . altKey ? '' : prompt ( 'Approve instantly? You can add a custom message or leave empty' ) ;
2831 if ( approval === null ) {
@@ -47,7 +50,7 @@ async function quickApprove(event: DelegateEvent<MouseEvent>): Promise<void> {
4750async function addSidebarReviewButton ( reviewersSection : Element ) : Promise < void > {
4851 const reviewFormUrl = new URL ( location . href ) ;
4952 reviewFormUrl . pathname += '/files' ;
50- reviewFormUrl . hash = 'review-changes-modal' ;
53+ reviewFormUrl . hash = openReviewMenuDeepLink ;
5154
5255 // Occasionally this button appears before "Reviewers", so let's wait a bit longer
5356 await delay ( 300 ) ;
@@ -86,14 +89,25 @@ async function initSidebarReviewButton(signal: AbortSignal): Promise<void> {
8689 delegate ( '.rgh-quick-approve' , 'click' , quickApprove , { signal} ) ;
8790}
8891
92+ function initNativeReviewButton ( signal : AbortSignal ) : void {
93+ observe ( 'section[aria-label="Review Request Banner"] a[type="button"]' , enhanceNativeReviewButton , { signal} ) ;
94+ }
95+
96+ function enhanceNativeReviewButton ( button : HTMLAnchorElement ) : void {
97+ // Clone button to remove GitHub's event listeners, which interfere with ours
98+ const clonedButton = button . cloneNode ( true ) ;
99+ clonedButton . hash = openReviewMenuDeepLink ;
100+ button . replaceWith ( clonedButton ) ;
101+ }
102+
89103function focusReviewTextarea ( event : DelegateEvent < Event , HTMLElement > ) : void {
90104 if ( 'newState' in event && event . newState === 'open' ) {
91105 $ ( 'textarea' , event . delegateTarget ) . focus ( ) ;
92106 }
93107}
94108
95109async function initReviewButtonEnhancements ( signal : AbortSignal ) : Promise < void > {
96- delegate ( '#review-changes-modal' , 'toggle' , focusReviewTextarea , { capture : true , signal} ) ;
110+ delegate ( openReviewMenuDeepLinkSelector , 'toggle' , focusReviewTextarea , { capture : true , signal} ) ;
97111
98112 const reviewDropdownButton = await elementReady ( [
99113 reviewMenuButtonSelector ,
@@ -117,14 +131,19 @@ function initNativeDeepLinking(signal: AbortSignal): void {
117131 observe ( reviewMenuButtonSelector , openReviewDialog , { signal} ) ;
118132 // Old view -- TODO: Drop in the fall of 2026
119133 // Cannot target the [popover] itself because observe() can't see hidden elements
120- observe ( ' [popovertarget="review-changes-modal"]' , openReviewPopup , { signal} ) ;
134+ observe ( ` [popovertarget="${ openReviewMenuDeepLink } "]` , openReviewPopup , { signal} ) ;
121135}
122136
123137void features . add ( import . meta. url , {
124138 include : [
125139 pageDetect . isPRConversation ,
126140 ] ,
127141 init : initSidebarReviewButton ,
142+ } , {
143+ include : [
144+ pageDetect . isPRConversation ,
145+ ] ,
146+ init : initNativeReviewButton ,
128147} , {
129148 shortcuts : {
130149 v : 'Open PR review popup' ,
@@ -135,7 +154,7 @@ void features.add(import.meta.url, {
135154 init : initReviewButtonEnhancements ,
136155} , {
137156 asLongAs : [
138- ( ) => location . hash === '#review-changes-modal' ,
157+ ( ) => location . hash === openReviewMenuDeepLinkSelector ,
139158 pageDetect . isPRFiles ,
140159 ] ,
141160 init : initNativeDeepLinking ,
@@ -147,5 +166,6 @@ Test URLs:
147166
148167- Open PR (review, approve) https://github.com/refined-github/sandbox/pull/10
149168- Closed PR (only review) https://github.com/refined-github/sandbox/pull/26
169+ - PRs with your review requested: https://github.com/pulls/review-requested
150170
151171*/
0 commit comments