diff options
-rw-r--r-- | templates/repo/view_file.tmpl | 3 | ||||
-rw-r--r-- | web_src/js/features/repo-code.js | 14 | ||||
-rw-r--r-- | web_src/js/utils.js | 14 | ||||
-rw-r--r-- | web_src/js/utils.test.js | 5 |
4 files changed, 24 insertions, 12 deletions
diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index 85ff0120b2..e92aeb0702 100644 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -110,8 +110,7 @@ </table> <div class="code-line-menu ui vertical pointing menu tippy-target"> {{if $.Permission.CanRead $.UnitTypeIssues}} - {{/* FIXME: Here we use HTMLURL but not link, see https://github.com/go-gitea/gitea/pull/21986/files#r1096532186*/}} - <a class="item ref-in-new-issue" href="{{.RepoLink}}/issues/new?body={{.Repository.HTMLURL}}{{printf "/src/commit/"}}{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}" rel="nofollow noindex">{{.locale.Tr "repo.issues.context.reference_issue"}}</a> + <a class="item ref-in-new-issue" data-url-issue-new="{{.RepoLink}}/issues/new" data-url-param-body-link="{{.Repository.Link}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}" rel="nofollow noindex">{{.locale.Tr "repo.issues.context.reference_issue"}}</a> {{end}} <a class="item view_git_blame" href="{{.Repository.Link}}/blame/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}">{{.locale.Tr "repo.view_git_blame"}}</a> <a class="item copy-line-permalink" data-url="{{.Repository.Link}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}">{{.locale.Tr "repo.file_copy_permalink"}}</a> diff --git a/web_src/js/features/repo-code.js b/web_src/js/features/repo-code.js index 083a17bf21..1c59913132 100644 --- a/web_src/js/features/repo-code.js +++ b/web_src/js/features/repo-code.js @@ -3,6 +3,7 @@ import {svg} from '../svg.js'; import {invertFileFolding} from './file-fold.js'; import {createTippy} from '../modules/tippy.js'; import {copyToClipboard} from './clipboard.js'; +import {toAbsoluteUrl} from '../utils.js'; export const singleAnchorRegex = /^#(L|n)([1-9][0-9]*)$/; export const rangeAnchorRegex = /^#(L[1-9][0-9]*)-(L[1-9][0-9]*)$/; @@ -19,17 +20,18 @@ function selectRange($list, $select, $from) { $list.removeClass('active'); // add hashchange to permalink - const $issue = $('a.ref-in-new-issue'); + const $refInNewIssue = $('a.ref-in-new-issue'); const $copyPermalink = $('a.copy-line-permalink'); const $viewGitBlame = $('a.view_git_blame'); const updateIssueHref = function (anchor) { - if ($issue.length === 0) { + if ($refInNewIssue.length === 0) { return; } - let href = $issue.attr('href'); - href = `${href.replace(/%23L\d+$|%23L\d+-L\d+$/, '')}%23${anchor}`; - $issue.attr('href', href); + 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)}`); }; const updateViewGitBlameFragment = function (anchor) { @@ -188,7 +190,7 @@ export function initRepoCodeView() { currentTarget.closest('tr').outerHTML = blob; }); $(document).on('click', '.copy-line-permalink', async (e) => { - const success = await copyToClipboard(e.currentTarget.getAttribute('data-url')); + const success = await copyToClipboard(toAbsoluteUrl(e.currentTarget.getAttribute('data-url'))); if (!success) return; document.querySelector('.code-line-button')?._tippy?.hide(); }); diff --git a/web_src/js/utils.js b/web_src/js/utils.js index b9cd69e15a..c7624404c7 100644 --- a/web_src/js/utils.js +++ b/web_src/js/utils.js @@ -134,9 +134,15 @@ export function convertImage(blob, mime) { }); } -export function toAbsoluteUrl(relUrl) { - if (relUrl.startsWith('http://') || relUrl.startsWith('https://')) { - return relUrl; +export function toAbsoluteUrl(url) { + if (url.startsWith('http://') || url.startsWith('https://')) { + return url; } - return `${window.location.origin}${relUrl}`; + if (url.startsWith('//')) { + return `${window.location.protocol}${url}`; // it's also a somewhat absolute URL (with the current scheme) + } + if (url && !url.startsWith('/')) { + throw new Error('unsupported url, it should either start with / or http(s)://'); + } + return `${window.location.origin}${url}`; } diff --git a/web_src/js/utils.test.js b/web_src/js/utils.test.js index 4efe916231..306acd34af 100644 --- a/web_src/js/utils.test.js +++ b/web_src/js/utils.test.js @@ -139,6 +139,11 @@ test('blobToDataURI', async () => { }); test('toAbsoluteUrl', () => { + expect(toAbsoluteUrl('//host/dir')).toEqual('http://host/dir'); + expect(toAbsoluteUrl('https://host/dir')).toEqual('https://host/dir'); + expect(toAbsoluteUrl('')).toEqual('http://localhost:3000'); expect(toAbsoluteUrl('/user/repo')).toEqual('http://localhost:3000/user/repo'); + + expect(() => toAbsoluteUrl('path')).toThrowError('unsupported'); }); |