| 
									
										
										
										
											2022-01-28 13:00:11 -08:00
										 |  |  | import $ from 'jquery'; | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  | import {svg} from '../svg.js'; | 
					
						
							| 
									
										
										
										
											2022-05-07 20:28:10 +02:00
										 |  |  | import {invertFileFolding} from './file-fold.js'; | 
					
						
							| 
									
										
										
										
											2022-11-21 10:59:42 +01:00
										 |  |  | import {createTippy} from '../modules/tippy.js'; | 
					
						
							| 
									
										
										
										
											2023-04-02 11:25:36 +02:00
										 |  |  | import {clippie} from 'clippie'; | 
					
						
							| 
									
										
										
										
											2023-02-08 00:08:44 +08:00
										 |  |  | import {toAbsoluteUrl} from '../utils.js'; | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 11:22:36 +01:00
										 |  |  | export const singleAnchorRegex = /^#(L|n)([1-9][0-9]*)$/; | 
					
						
							|  |  |  | export const rangeAnchorRegex = /^#(L[1-9][0-9]*)-(L[1-9][0-9]*)$/; | 
					
						
							| 
									
										
										
										
											2022-11-04 21:33:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  | 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
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:08:44 +08:00
										 |  |  |   const $refInNewIssue = $('a.ref-in-new-issue'); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  |   const $copyPermalink = $('a.copy-line-permalink'); | 
					
						
							| 
									
										
										
										
											2022-04-26 18:54:40 +08:00
										 |  |  |   const $viewGitBlame = $('a.view_git_blame'); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-12 06:00:24 +01:00
										 |  |  |   const updateIssueHref = function (anchor) { | 
					
						
							| 
									
										
										
										
											2023-02-08 00:08:44 +08:00
										 |  |  |     if ($refInNewIssue.length === 0) { | 
					
						
							| 
									
										
										
										
											2022-02-12 06:00:24 +01:00
										 |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-02-08 00:08:44 +08:00
										 |  |  |     const urlIssueNew = $refInNewIssue.attr('data-url-issue-new'); | 
					
						
							|  |  |  |     const urlParamBodyLink = $refInNewIssue.attr('data-url-param-body-link'); | 
					
						
							|  |  |  |     const issueContent = `${toAbsoluteUrl(urlParamBodyLink)}#${anchor}`; // the default content for issue body
 | 
					
						
							|  |  |  |     $refInNewIssue.attr('href', `${urlIssueNew}?body=${encodeURIComponent(issueContent)}`); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-26 18:54:40 +08:00
										 |  |  |   const updateViewGitBlameFragment = function (anchor) { | 
					
						
							|  |  |  |     if ($viewGitBlame.length === 0) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     let href = $viewGitBlame.attr('href'); | 
					
						
							|  |  |  |     href = `${href.replace(/#L\d+$|#L\d+-L\d+$/, '')}`; | 
					
						
							|  |  |  |     if (anchor.length !== 0) { | 
					
						
							|  |  |  |       href = `${href}#${anchor}`; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     $viewGitBlame.attr('href', href); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-09 14:37:34 +02:00
										 |  |  |   const updateCopyPermalinkUrl = function(anchor) { | 
					
						
							| 
									
										
										
										
											2022-04-26 18:54:40 +08:00
										 |  |  |     if ($copyPermalink.length === 0) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-09 14:37:34 +02:00
										 |  |  |     let link = $copyPermalink.attr('data-url'); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  |     link = `${link.replace(/#L\d+$|#L\d+-L\d+$/, '')}#${anchor}`; | 
					
						
							| 
									
										
										
										
											2022-08-09 14:37:34 +02:00
										 |  |  |     $copyPermalink.attr('data-url', link); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ($from) { | 
					
						
							| 
									
										
										
										
											2022-02-18 07:50:36 +01:00
										 |  |  |     let a = parseInt($select.attr('rel').slice(1)); | 
					
						
							|  |  |  |     let b = parseInt($from.attr('rel').slice(1)); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  |     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}`); | 
					
						
							| 
									
										
										
										
											2022-04-26 18:54:40 +08:00
										 |  |  |       updateViewGitBlameFragment(`L${a}-L${b}`); | 
					
						
							| 
									
										
										
										
											2022-08-09 14:37:34 +02:00
										 |  |  |       updateCopyPermalinkUrl(`L${a}-L${b}`); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   $select.addClass('active'); | 
					
						
							|  |  |  |   changeHash(`#${$select.attr('rel')}`); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   updateIssueHref($select.attr('rel')); | 
					
						
							| 
									
										
										
										
											2022-04-26 18:54:40 +08:00
										 |  |  |   updateViewGitBlameFragment($select.attr('rel')); | 
					
						
							| 
									
										
										
										
											2022-08-09 14:37:34 +02:00
										 |  |  |   updateCopyPermalinkUrl($select.attr('rel')); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function showLineButton() { | 
					
						
							| 
									
										
										
										
											2022-08-09 14:37:34 +02:00
										 |  |  |   const menu = document.querySelector('.code-line-menu'); | 
					
						
							|  |  |  |   if (!menu) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // remove all other line buttons
 | 
					
						
							|  |  |  |   for (const el of document.querySelectorAll('.code-line-button')) { | 
					
						
							|  |  |  |     el.remove(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // find active row and add button
 | 
					
						
							|  |  |  |   const tr = document.querySelector('.code-view td.lines-code.active').closest('tr'); | 
					
						
							|  |  |  |   const td = tr.querySelector('td'); | 
					
						
							|  |  |  |   const btn = document.createElement('button'); | 
					
						
							|  |  |  |   btn.classList.add('code-line-button'); | 
					
						
							|  |  |  |   btn.innerHTML = svg('octicon-kebab-horizontal'); | 
					
						
							|  |  |  |   td.prepend(btn); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // put a copy of the menu back into DOM for the next click
 | 
					
						
							| 
									
										
										
										
											2023-05-09 04:35:49 +02:00
										 |  |  |   btn.closest('.code-view').append(menu.cloneNode(true)); | 
					
						
							| 
									
										
										
										
											2022-08-09 14:37:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   createTippy(btn, { | 
					
						
							|  |  |  |     trigger: 'click', | 
					
						
							| 
									
										
										
										
											2023-06-09 11:10:51 +02:00
										 |  |  |     hideOnClick: true, | 
					
						
							| 
									
										
										
										
											2022-08-09 14:37:34 +02:00
										 |  |  |     content: menu, | 
					
						
							|  |  |  |     placement: 'right-start', | 
					
						
							|  |  |  |     interactive: 'true', | 
					
						
							| 
									
										
										
										
											2023-06-09 11:10:51 +02:00
										 |  |  |     onShow: (tippy) => { | 
					
						
							|  |  |  |       tippy.popper.addEventListener('click', () => { | 
					
						
							|  |  |  |         tippy.hide(); | 
					
						
							|  |  |  |       }, {once: true}); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-09 14:37:34 +02:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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', () => { | 
					
						
							| 
									
										
										
										
											2022-11-11 11:22:36 +01:00
										 |  |  |       let m = window.location.hash.match(rangeAnchorRegex); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  |       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]}]`); | 
					
						
							| 
									
										
										
										
											2022-11-11 11:22:36 +01:00
										 |  |  |         if ($first.length) { | 
					
						
							|  |  |  |           selectRange($list, $first, $list.filter(`[rel=${m[2]}]`)); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 11:22:36 +01:00
										 |  |  |           // show code view menu marker (don't show in blame page)
 | 
					
						
							|  |  |  |           if ($('div.blame').length === 0) { | 
					
						
							|  |  |  |             showLineButton(); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 11:22:36 +01:00
										 |  |  |           $('html, body').scrollTop($first.offset().top - 200); | 
					
						
							|  |  |  |           return; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-11-11 11:22:36 +01:00
										 |  |  |       m = window.location.hash.match(singleAnchorRegex); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  |       if (m) { | 
					
						
							|  |  |  |         $first = $list.filter(`[rel=L${m[2]}]`); | 
					
						
							| 
									
										
										
										
											2022-11-11 11:22:36 +01:00
										 |  |  |         if ($first.length) { | 
					
						
							|  |  |  |           selectRange($list, $first); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 11:22:36 +01:00
										 |  |  |           // show code view menu marker (don't show in blame page)
 | 
					
						
							|  |  |  |           if ($('div.blame').length === 0) { | 
					
						
							|  |  |  |             showLineButton(); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 11:22:36 +01:00
										 |  |  |           $('html, body').scrollTop($first.offset().top - 200); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     }).trigger('hashchange'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   $(document).on('click', '.fold-file', ({currentTarget}) => { | 
					
						
							| 
									
										
										
										
											2022-05-07 20:28:10 +02:00
										 |  |  |     invertFileFolding(currentTarget.closest('.file-content'), currentTarget); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2023-05-21 22:47:41 +02:00
										 |  |  |   $(document).on('click', '.code-expander-button', async ({currentTarget}) => { | 
					
						
							| 
									
										
										
										
											2021-11-22 09:19:01 +01:00
										 |  |  |     const url = currentTarget.getAttribute('data-url'); | 
					
						
							|  |  |  |     const query = currentTarget.getAttribute('data-query'); | 
					
						
							|  |  |  |     const anchor = currentTarget.getAttribute('data-anchor'); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  |     if (!url) return; | 
					
						
							|  |  |  |     const blob = await $.get(`${url}?${query}&anchor=${anchor}`); | 
					
						
							|  |  |  |     currentTarget.closest('tr').outerHTML = blob; | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2022-08-09 14:37:34 +02:00
										 |  |  |   $(document).on('click', '.copy-line-permalink', async (e) => { | 
					
						
							| 
									
										
										
										
											2023-05-28 03:34:18 +02:00
										 |  |  |     await clippie(toAbsoluteUrl(e.currentTarget.getAttribute('data-url'))); | 
					
						
							| 
									
										
										
										
											2022-08-09 14:37:34 +02:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2021-10-17 01:28:04 +08:00
										 |  |  | } |