1
1
import $ from 'jquery' ;
2
2
import { svg } from '../svg.js' ;
3
3
import { invertFileFolding } from './file-fold.js' ;
4
+ import { createTippy } from '../modules/tippy.js' ;
5
+ import { copyToClipboard } from './clipboard.js' ;
4
6
5
7
function changeHash ( hash ) {
6
8
if ( window . history . pushState ) {
@@ -39,13 +41,13 @@ function selectRange($list, $select, $from) {
39
41
$viewGitBlame . attr ( 'href' , href ) ;
40
42
} ;
41
43
42
- const updateCopyPermalinkHref = function ( anchor ) {
44
+ const updateCopyPermalinkUrl = function ( anchor ) {
43
45
if ( $copyPermalink . length === 0 ) {
44
46
return ;
45
47
}
46
- let link = $copyPermalink . attr ( 'data-clipboard-text ' ) ;
48
+ let link = $copyPermalink . attr ( 'data-url ' ) ;
47
49
link = `${ link . replace ( / # L \d + $ | # L \d + - L \d + $ / , '' ) } #${ anchor } ` ;
48
- $copyPermalink . attr ( 'data-clipboard-text ' , link ) ;
50
+ $copyPermalink . attr ( 'data-url ' , link ) ;
49
51
} ;
50
52
51
53
if ( $from ) {
@@ -67,7 +69,7 @@ function selectRange($list, $select, $from) {
67
69
68
70
updateIssueHref ( `L${ a } -L${ b } ` ) ;
69
71
updateViewGitBlameFragment ( `L${ a } -L${ b } ` ) ;
70
- updateCopyPermalinkHref ( `L${ a } -L${ b } ` ) ;
72
+ updateCopyPermalinkUrl ( `L${ a } -L${ b } ` ) ;
71
73
return ;
72
74
}
73
75
}
@@ -76,17 +78,36 @@ function selectRange($list, $select, $from) {
76
78
77
79
updateIssueHref ( $select . attr ( 'rel' ) ) ;
78
80
updateViewGitBlameFragment ( $select . attr ( 'rel' ) ) ;
79
- updateCopyPermalinkHref ( $select . attr ( 'rel' ) ) ;
81
+ updateCopyPermalinkUrl ( $select . attr ( 'rel' ) ) ;
80
82
}
81
83
82
84
function showLineButton ( ) {
83
- if ( $ ( '.code-line-menu' ) . length === 0 ) return ;
84
- $ ( '.code-line-button' ) . remove ( ) ;
85
- $ ( '.code-view td.lines-code.active' ) . closest ( 'tr' ) . find ( 'td:eq(0)' ) . first ( ) . prepend (
86
- $ ( `<button class="code-line-button">${ svg ( 'octicon-kebab-horizontal' ) } </button>` )
87
- ) ;
88
- $ ( '.code-line-menu' ) . appendTo ( $ ( '.code-view' ) ) ;
89
- $ ( '.code-line-button' ) . popup ( { popup : $ ( '.code-line-menu' ) , on : 'click' } ) ;
85
+ const menu = document . querySelector ( '.code-line-menu' ) ;
86
+ if ( ! menu ) return ;
87
+
88
+ // remove all other line buttons
89
+ for ( const el of document . querySelectorAll ( '.code-line-button' ) ) {
90
+ el . remove ( ) ;
91
+ }
92
+
93
+ // find active row and add button
94
+ const tr = document . querySelector ( '.code-view td.lines-code.active' ) . closest ( 'tr' ) ;
95
+ const td = tr . querySelector ( 'td' ) ;
96
+ const btn = document . createElement ( 'button' ) ;
97
+ btn . classList . add ( 'code-line-button' ) ;
98
+ btn . innerHTML = svg ( 'octicon-kebab-horizontal' ) ;
99
+ td . prepend ( btn ) ;
100
+
101
+ // put a copy of the menu back into DOM for the next click
102
+ btn . closest ( '.code-view' ) . appendChild ( menu . cloneNode ( true ) ) ;
103
+
104
+ createTippy ( btn , {
105
+ trigger : 'click' ,
106
+ content : menu ,
107
+ placement : 'right-start' ,
108
+ role : 'menu' ,
109
+ interactive : 'true' ,
110
+ } ) ;
90
111
}
91
112
92
113
export function initRepoCodeView ( ) {
@@ -159,4 +180,9 @@ export function initRepoCodeView() {
159
180
const blob = await $ . get ( `${ url } ?${ query } &anchor=${ anchor } ` ) ;
160
181
currentTarget . closest ( 'tr' ) . outerHTML = blob ;
161
182
} ) ;
183
+ $ ( document ) . on ( 'click' , '.copy-line-permalink' , async ( e ) => {
184
+ const success = await copyToClipboard ( e . currentTarget . getAttribute ( 'data-url' ) ) ;
185
+ if ( ! success ) return ;
186
+ document . querySelector ( '.code-line-button' ) ?. _tippy ?. hide ( ) ;
187
+ } ) ;
162
188
}
0 commit comments