2021-10-17 01:28:04 +08:00
import { svg } from '../svg.js' ;
function changeHash ( hash ) {
if ( window . history . pushState ) {
window . history . pushState ( null , null , hash ) ;
} else {
window . location . hash = hash ;
}
}
function selectRange ( $list , $select , $from ) {
$list . removeClass ( 'active' ) ;
// add hashchange to permalink
const $issue = $ ( 'a.ref-in-new-issue' ) ;
const $copyPermalink = $ ( 'a.copy-line-permalink' ) ;
if ( $issue . length === 0 || $copyPermalink . length === 0 ) {
return ;
}
const updateIssueHref = function ( anchor ) {
let href = $issue . attr ( 'href' ) ;
href = ` ${ href . replace ( /%23L\d+$|%23L\d+-L\d+$/ , '' ) } %23 ${ anchor } ` ;
$issue . attr ( 'href' , href ) ;
} ;
const updateCopyPermalinkHref = function ( anchor ) {
let link = $copyPermalink . attr ( 'data-clipboard-text' ) ;
link = ` ${ link . replace ( /#L\d+$|#L\d+-L\d+$/ , '' ) } # ${ anchor } ` ;
$copyPermalink . attr ( 'data-clipboard-text' , link ) ;
} ;
if ( $from ) {
let a = parseInt ( $select . attr ( 'rel' ) . substr ( 1 ) ) ;
let b = parseInt ( $from . attr ( 'rel' ) . substr ( 1 ) ) ;
let c ;
if ( a !== b ) {
if ( a > b ) {
c = a ;
a = b ;
b = c ;
}
const classes = [ ] ;
for ( let i = a ; i <= b ; i ++ ) {
classes . push ( ` [rel=L ${ i } ] ` ) ;
}
$list . filter ( classes . join ( ',' ) ) . addClass ( 'active' ) ;
changeHash ( ` #L ${ a } -L ${ b } ` ) ;
updateIssueHref ( ` L ${ a } -L ${ b } ` ) ;
updateCopyPermalinkHref ( ` L ${ a } -L ${ b } ` ) ;
return ;
}
}
$select . addClass ( 'active' ) ;
changeHash ( ` # ${ $select . attr ( 'rel' ) } ` ) ;
updateIssueHref ( $select . attr ( 'rel' ) ) ;
updateCopyPermalinkHref ( $select . attr ( 'rel' ) ) ;
}
function showLineButton ( ) {
if ( $ ( '.code-line-menu' ) . length === 0 ) return ;
$ ( '.code-line-button' ) . remove ( ) ;
$ ( '.code-view td.lines-code.active' ) . closest ( 'tr' ) . find ( 'td:eq(0)' ) . first ( ) . prepend (
$ ( ` <button class="code-line-button"> ${ svg ( 'octicon-kebab-horizontal' ) } </button> ` )
) ;
$ ( '.code-line-menu' ) . appendTo ( $ ( '.code-view' ) ) ;
$ ( '.code-line-button' ) . popup ( { popup : $ ( '.code-line-menu' ) , on : 'click' } ) ;
}
export function initRepoCodeView ( ) {
if ( $ ( '.code-view .lines-num' ) . length > 0 ) {
$ ( document ) . on ( 'click' , '.lines-num span' , function ( e ) {
const $select = $ ( this ) ;
let $list ;
if ( $ ( 'div.blame' ) . length ) {
$list = $ ( '.code-view td.lines-code.blame-code' ) ;
} else {
$list = $ ( '.code-view td.lines-code' ) ;
}
selectRange ( $list , $list . filter ( ` [rel= ${ $select . attr ( 'id' ) } ] ` ) , ( e . shiftKey ? $list . filter ( '.active' ) . eq ( 0 ) : null ) ) ;
if ( window . getSelection ) {
window . getSelection ( ) . removeAllRanges ( ) ;
} else {
document . selection . empty ( ) ;
}
// show code view menu marker (don't show in blame page)
if ( $ ( 'div.blame' ) . length === 0 ) {
showLineButton ( ) ;
}
} ) ;
$ ( window ) . on ( 'hashchange' , ( ) => {
let m = window . location . hash . match ( /^#(L\d+)-(L\d+)$/ ) ;
let $list ;
if ( $ ( 'div.blame' ) . length ) {
$list = $ ( '.code-view td.lines-code.blame-code' ) ;
} else {
$list = $ ( '.code-view td.lines-code' ) ;
}
let $first ;
if ( m ) {
$first = $list . filter ( ` [rel= ${ m [ 1 ] } ] ` ) ;
selectRange ( $list , $first , $list . filter ( ` [rel= ${ m [ 2 ] } ] ` ) ) ;
// show code view menu marker (don't show in blame page)
if ( $ ( 'div.blame' ) . length === 0 ) {
showLineButton ( ) ;
}
$ ( 'html, body' ) . scrollTop ( $first . offset ( ) . top - 200 ) ;
return ;
}
m = window . location . hash . match ( /^#(L|n)(\d+)$/ ) ;
if ( m ) {
$first = $list . filter ( ` [rel=L ${ m [ 2 ] } ] ` ) ;
selectRange ( $list , $first ) ;
// show code view menu marker (don't show in blame page)
if ( $ ( 'div.blame' ) . length === 0 ) {
showLineButton ( ) ;
}
$ ( 'html, body' ) . scrollTop ( $first . offset ( ) . top - 200 ) ;
}
} ) . trigger ( 'hashchange' ) ;
}
$ ( document ) . on ( 'click' , '.fold-file' , ( { currentTarget } ) => {
const box = currentTarget . closest ( '.file-content' ) ;
const folded = box . dataset . folded !== 'true' ;
2021-10-27 19:11:56 +08:00
currentTarget . innerHTML = svg ( ` octicon-chevron- ${ folded ? 'right' : 'down' } ` , 18 ) ;
2021-10-17 01:28:04 +08:00
box . dataset . folded = String ( folded ) ;
} ) ;
$ ( document ) . on ( 'click' , '.blob-excerpt' , async ( { currentTarget } ) => {
const { url , query , anchor } = currentTarget . dataset ;
if ( ! url ) return ;
const blob = await $ . get ( ` ${ url } ? ${ query } &anchor= ${ anchor } ` ) ;
currentTarget . closest ( 'tr' ) . outerHTML = blob ;
} ) ;
}