aboutsummaryrefslogtreecommitdiffstats
path: root/web_src
diff options
context:
space:
mode:
Diffstat (limited to 'web_src')
-rw-r--r--web_src/js/features/repo-code.js14
-rw-r--r--web_src/js/utils.js14
-rw-r--r--web_src/js/utils.test.js5
3 files changed, 23 insertions, 10 deletions
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');
});