|
4 | 4 | (function() { |
5 | 5 | 'use strict'; |
6 | 6 |
|
7 | | - // Feature 1: Add "Copy PR Link" button next to PR title |
| 7 | + // Feature 1: Add "Copy PR Link" button next to the copy branch button |
8 | 8 | function addCopyPRLinkButton() { |
9 | | - // Find the PR title element |
10 | | - const titleElement = document.querySelector('.js-issue-title'); |
11 | | - if (!titleElement) { |
12 | | - return false; |
13 | | - } |
14 | | - |
15 | 9 | // Check if button already exists |
16 | 10 | if (document.getElementById('copy-pr-link-btn')) { |
17 | 11 | return true; |
18 | 12 | } |
19 | 13 |
|
20 | | - // Create the button |
| 14 | + // Find the copy branch button (clipboard icon next to branch name) |
| 15 | + const copyBranchBtn = document.querySelector('.gh-header-meta clipboard-copy'); |
| 16 | + if (!copyBranchBtn) { |
| 17 | + return false; |
| 18 | + } |
| 19 | + |
| 20 | + // Get PR title for copying |
| 21 | + const titleElement = document.querySelector('.js-issue-title'); |
| 22 | + if (!titleElement) { |
| 23 | + return false; |
| 24 | + } |
| 25 | + |
| 26 | + // Create the button - match the style of the existing clipboard-copy button |
21 | 27 | const button = document.createElement('button'); |
22 | 28 | button.id = 'copy-pr-link-btn'; |
23 | | - button.className = 'btn btn-sm'; |
24 | | - button.style.cssText = 'margin-left: 8px; vertical-align: middle; display: inline-flex; align-items: center; gap: 4px;'; |
| 29 | + button.className = 'Button Button--iconOnly Button--secondary Button--small'; |
| 30 | + button.type = 'button'; |
| 31 | + button.title = 'Copy PR link'; |
25 | 32 | button.innerHTML = ` |
26 | | - <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16"> |
27 | | - <path fill="currentColor" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Zm5.22-1.72a.75.75 0 0 1 1.06 0l3.97 3.97V4.25a.75.75 0 0 1 1.5 0v6.5a.75.75 0 0 1-.75.75h-6.5a.75.75 0 0 1 0-1.5H9.44L5.47 5.53a.75.75 0 0 1 0-1.06Z"></path> |
| 33 | + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" class="octicon octicon-link"> |
| 34 | + <path fill="currentColor" d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path> |
28 | 35 | </svg> |
29 | | - <span>Copy PR Link</span> |
30 | 36 | `; |
31 | | - button.title = 'Copy PR title and link to clipboard'; |
32 | 37 |
|
33 | 38 | // Add click handler |
34 | 39 | button.addEventListener('click', async function(e) { |
35 | 40 | e.preventDefault(); |
36 | 41 |
|
37 | | - // Get PR title and URL |
38 | 42 | const prTitle = titleElement.textContent.trim(); |
39 | 43 | const prUrl = window.location.href; |
40 | 44 | const textToCopy = `${prTitle}: ${prUrl}`; |
41 | 45 |
|
42 | | - // Copy to clipboard |
43 | | - // Save original button content before try/catch |
44 | | - const originalText = button.innerHTML; |
45 | 46 | try { |
46 | 47 | await navigator.clipboard.writeText(textToCopy); |
47 | | - |
48 | | - // Visual feedback |
| 48 | + // Visual feedback - change to checkmark |
49 | 49 | button.innerHTML = ` |
50 | | - <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" style="display:inline-block;vertical-align:text-bottom;"> |
| 50 | + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" class="octicon octicon-check" style="color: #1a7f37;"> |
51 | 51 | <path fill="currentColor" d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path> |
52 | 52 | </svg> |
53 | | - Copied! |
54 | 53 | `; |
55 | | - button.style.color = '#1a7f37'; |
56 | | - |
57 | 54 | setTimeout(() => { |
58 | | - button.innerHTML = originalText; |
59 | | - button.style.color = ''; |
| 55 | + button.innerHTML = ` |
| 56 | + <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" class="octicon octicon-link"> |
| 57 | + <path fill="currentColor" d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path> |
| 58 | + </svg> |
| 59 | + `; |
60 | 60 | }, 2000); |
61 | 61 | } catch (err) { |
62 | 62 | console.error('Failed to copy:', err); |
63 | | - button.innerHTML = ` |
64 | | - <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" style="display:inline-block;vertical-align:text-bottom;"> |
65 | | - <path fill="currentColor" d="M9.036 7.976a.75.75 0 0 0-1.06 1.06L10.939 12l-2.963 2.963a.75.75 0 1 0 1.06 1.06L12 13.06l2.963 2.964a.75.75 0 0 0 1.061-1.06L13.061 12l2.963-2.964a.75.75 0 0 0-1.06-1.06L12 10.939 9.036 7.976Z"></path> |
66 | | - <path fill="currentColor" d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Z"></path> |
67 | | - </svg> |
68 | | - Failed |
69 | | - `; |
70 | | - button.style.color = '#f85149'; |
71 | | - setTimeout(() => { |
72 | | - button.innerHTML = originalText; |
73 | | - button.style.color = ''; |
74 | | - }, 2000); |
75 | 63 | } |
76 | 64 | }); |
77 | 65 |
|
78 | | - // Insert button after the PR number |
79 | | - const prNumberElement = document.querySelector('.gh-header-number'); |
80 | | - if (prNumberElement) { |
81 | | - prNumberElement.after(button); |
82 | | - return true; |
83 | | - } |
84 | | - |
85 | | - return false; |
86 | | - |
87 | | - return false; |
| 66 | + // Insert button after the copy branch button |
| 67 | + copyBranchBtn.after(button); |
| 68 | + return true; |
88 | 69 | } |
89 | 70 |
|
90 | 71 | // Feature 2: Add "Request Review" button next to Copilot reviewer for draft PRs |
|
0 commit comments