mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-03 19:58:56 +02:00
merge main
This commit is contained in:
@@ -336,8 +336,13 @@ a.label,
|
||||
border-color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.ui.dropdown .menu > .header {
|
||||
text-transform: none; /* reset fomantic's "uppercase" */
|
||||
}
|
||||
|
||||
.ui.dropdown .menu > .header:not(.ui) {
|
||||
color: var(--color-text);
|
||||
font-size: 0.95em; /* reset fomantic's small font-size */
|
||||
}
|
||||
|
||||
.ui.dropdown .menu > .item {
|
||||
@@ -691,10 +696,6 @@ input:-webkit-autofill:active,
|
||||
box-shadow: 0 6px 18px var(--color-shadow) !important;
|
||||
}
|
||||
|
||||
.ui.dropdown .menu > .header {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.ui .text.left {
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
@@ -155,6 +155,7 @@ textarea:focus,
|
||||
}
|
||||
|
||||
.ui.form.left-right-form .inline.field > .help {
|
||||
display: block;
|
||||
margin-left: calc(250px + 15px);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
.ui.fluid.container {
|
||||
width: 100%;
|
||||
}
|
||||
.ui.container.medium-width {
|
||||
width: 800px;
|
||||
}
|
||||
|
||||
.ui[class*="center aligned"].container {
|
||||
text-align: center;
|
||||
|
||||
@@ -48,7 +48,8 @@
|
||||
align-items: stretch;
|
||||
}
|
||||
/* hide all items */
|
||||
#navbar .item {
|
||||
#navbar .navbar-left > .item,
|
||||
#navbar .navbar-right > .item {
|
||||
display: none;
|
||||
}
|
||||
#navbar #navbar-logo {
|
||||
|
||||
@@ -8,6 +8,7 @@ type File = {
|
||||
NameHash: string;
|
||||
Type: number;
|
||||
IsViewed: boolean;
|
||||
IsSubmodule: boolean;
|
||||
}
|
||||
|
||||
type Item = {
|
||||
@@ -34,6 +35,13 @@ function getIconForDiffType(pType) {
|
||||
};
|
||||
return diffTypes[pType];
|
||||
}
|
||||
|
||||
function fileIcon(file) {
|
||||
if (file.IsSubmodule) {
|
||||
return 'octicon-file-submodule';
|
||||
}
|
||||
return 'octicon-file';
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -44,7 +52,7 @@ function getIconForDiffType(pType) {
|
||||
:title="item.name" :href="'#diff-' + item.file.NameHash"
|
||||
>
|
||||
<!-- file -->
|
||||
<SvgIcon name="octicon-file"/>
|
||||
<SvgIcon :name="fileIcon(item.file)"/>
|
||||
<span class="gt-ellipsis tw-flex-1">{{ item.name }}</span>
|
||||
<SvgIcon :name="getIconForDiffType(item.file.Type).name" :class="getIconForDiffType(item.file.Type).classes"/>
|
||||
</a>
|
||||
|
||||
@@ -129,7 +129,7 @@ function clearMergeMessage() {
|
||||
{{ mergeForm.textCancel }}
|
||||
</button>
|
||||
|
||||
<div class="ui checkbox tw-ml-1" v-if="mergeForm.isPullBranchDeletable && !autoMergeWhenSucceed">
|
||||
<div class="ui checkbox tw-ml-1" v-if="mergeForm.isPullBranchDeletable">
|
||||
<input name="delete_branch_after_merge" type="checkbox" v-model="deleteBranchAfterMerge" id="delete-branch-after-merge">
|
||||
<label for="delete-branch-after-merge">{{ mergeForm.textDeleteBranch }}</label>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,8 @@ export function initGlobalDeleteButton(): void {
|
||||
// Some model/form elements will be filled by `data-id` / `data-name` / `data-data-xxx` attributes.
|
||||
// If there is a form defined by `data-form`, then the form will be submitted as-is (without any modification).
|
||||
// If there is no form, then the data will be posted to `data-url`.
|
||||
// TODO: it's not encouraged to use this method. `show-modal` does far better than this.
|
||||
// TODO: do not use this method in new code. `show-modal` / `link-action(data-modal-confirm)` does far better than this.
|
||||
// FIXME: all legacy `delete-button` should be refactored to use `show-modal` or `link-action`
|
||||
for (const btn of document.querySelectorAll<HTMLElement>('.delete-button')) {
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import $ from 'jquery';
|
||||
import {GET} from '../modules/fetch.ts';
|
||||
import {toggleElem, type DOMEvent} from '../utils/dom.ts';
|
||||
import {toggleElem, type DOMEvent, createElementFromHTML} from '../utils/dom.ts';
|
||||
import {logoutFromWorker} from '../modules/worker.ts';
|
||||
|
||||
const {appSubUrl, notificationSettings, assetVersionEncoded} = window.config;
|
||||
@@ -158,7 +157,8 @@ async function updateNotificationTable() {
|
||||
}
|
||||
|
||||
const data = await response.text();
|
||||
if ($(data).data('sequence-number') === notificationSequenceNumber) {
|
||||
const el = createElementFromHTML(data);
|
||||
if (parseInt(el.getAttribute('data-sequence-number')) === notificationSequenceNumber) {
|
||||
notificationDiv.outerHTML = data;
|
||||
initNotificationsTable();
|
||||
}
|
||||
|
||||
@@ -1,35 +1,34 @@
|
||||
import $ from 'jquery';
|
||||
import {hideElem, showElem} from '../utils/dom.ts';
|
||||
import {queryElems, toggleElem} from '../utils/dom.ts';
|
||||
import {fomanticQuery} from '../modules/fomantic/base.ts';
|
||||
|
||||
const {appSubUrl} = window.config;
|
||||
|
||||
export function initOrgTeamSettings() {
|
||||
// Change team access mode
|
||||
$('.organization.new.team input[name=permission]').on('change', () => {
|
||||
const val = $('input[name=permission]:checked', '.organization.new.team').val();
|
||||
if (val === 'admin') {
|
||||
hideElem('.organization.new.team .team-units');
|
||||
} else {
|
||||
showElem('.organization.new.team .team-units');
|
||||
}
|
||||
});
|
||||
function initOrgTeamSettings() {
|
||||
// on the page "page-content organization new team"
|
||||
const pageContent = document.querySelector('.page-content.organization.new.team');
|
||||
if (!pageContent) return;
|
||||
queryElems(pageContent, 'input[name=permission]', (el) => el.addEventListener('change', () => {
|
||||
// Change team access mode
|
||||
const val = pageContent.querySelector<HTMLInputElement>('input[name=permission]:checked')?.value;
|
||||
toggleElem(pageContent.querySelectorAll('.team-units'), val !== 'admin');
|
||||
}));
|
||||
}
|
||||
|
||||
export function initOrgTeamSearchRepoBox() {
|
||||
const $searchRepoBox = $('#search-repo-box');
|
||||
function initOrgTeamSearchRepoBox() {
|
||||
// on the page "page-content organization teams"
|
||||
const $searchRepoBox = fomanticQuery('#search-repo-box');
|
||||
$searchRepoBox.search({
|
||||
minCharacters: 2,
|
||||
apiSettings: {
|
||||
url: `${appSubUrl}/repo/search?q={query}&uid=${$searchRepoBox.data('uid')}`,
|
||||
onResponse(response) {
|
||||
const items = [];
|
||||
$.each(response.data, (_i, item) => {
|
||||
for (const item of response.data) {
|
||||
items.push({
|
||||
title: item.repository.full_name.split('/')[1],
|
||||
description: item.repository.full_name,
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
return {results: items};
|
||||
},
|
||||
},
|
||||
@@ -37,3 +36,9 @@ export function initOrgTeamSearchRepoBox() {
|
||||
showNoResults: false,
|
||||
});
|
||||
}
|
||||
|
||||
export function initOrgTeam() {
|
||||
if (!document.querySelector('.page-content.organization')) return;
|
||||
initOrgTeamSettings();
|
||||
initOrgTeamSearchRepoBox();
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import {singleAnchorRegex, rangeAnchorRegex} from './repo-code.ts';
|
||||
|
||||
test('singleAnchorRegex', () => {
|
||||
expect(singleAnchorRegex.test('#L0')).toEqual(false);
|
||||
expect(singleAnchorRegex.test('#L1')).toEqual(true);
|
||||
expect(singleAnchorRegex.test('#L01')).toEqual(false);
|
||||
expect(singleAnchorRegex.test('#n0')).toEqual(false);
|
||||
expect(singleAnchorRegex.test('#n1')).toEqual(true);
|
||||
expect(singleAnchorRegex.test('#n01')).toEqual(false);
|
||||
});
|
||||
|
||||
test('rangeAnchorRegex', () => {
|
||||
expect(rangeAnchorRegex.test('#L0-L10')).toEqual(false);
|
||||
expect(rangeAnchorRegex.test('#L1-L10')).toEqual(true);
|
||||
expect(rangeAnchorRegex.test('#L01-L10')).toEqual(false);
|
||||
expect(rangeAnchorRegex.test('#L1-L01')).toEqual(false);
|
||||
});
|
||||
@@ -1,12 +1,8 @@
|
||||
import $ from 'jquery';
|
||||
import {svg} from '../svg.ts';
|
||||
import {invertFileFolding} from './file-fold.ts';
|
||||
import {createTippy} from '../modules/tippy.ts';
|
||||
import {clippie} from 'clippie';
|
||||
import {toAbsoluteUrl} from '../utils.ts';
|
||||
|
||||
export const singleAnchorRegex = /^#(L|n)([1-9][0-9]*)$/;
|
||||
export const rangeAnchorRegex = /^#(L[1-9][0-9]*)-(L[1-9][0-9]*)$/;
|
||||
import {addDelegatedEventListener} from '../utils/dom.ts';
|
||||
|
||||
function changeHash(hash: string) {
|
||||
if (window.history.pushState) {
|
||||
@@ -16,20 +12,11 @@ function changeHash(hash: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function isBlame() {
|
||||
return Boolean(document.querySelector('div.blame'));
|
||||
}
|
||||
// it selects the code lines defined by range: `L1-L3` (3 lines) or `L2` (singe line)
|
||||
function selectRange(range: string): Element {
|
||||
for (const el of document.querySelectorAll('.code-view tr.active')) el.classList.remove('active');
|
||||
const elLineNums = document.querySelectorAll(`.code-view td.lines-num span[data-line-number]`);
|
||||
|
||||
function getLineEls() {
|
||||
return document.querySelectorAll(`.code-view td.lines-code${isBlame() ? '.blame-code' : ''}`);
|
||||
}
|
||||
|
||||
function selectRange($linesEls, $selectionEndEl, $selectionStartEls?) {
|
||||
for (const el of $linesEls) {
|
||||
el.closest('tr').classList.remove('active');
|
||||
}
|
||||
|
||||
// add hashchange to permalink
|
||||
const refInNewIssue = document.querySelector('a.ref-in-new-issue');
|
||||
const copyPermalink = document.querySelector('a.copy-line-permalink');
|
||||
const viewGitBlame = document.querySelector('a.view_git_blame');
|
||||
@@ -59,37 +46,30 @@ function selectRange($linesEls, $selectionEndEl, $selectionStartEls?) {
|
||||
copyPermalink.setAttribute('data-url', link);
|
||||
};
|
||||
|
||||
if ($selectionStartEls) {
|
||||
let a = parseInt($selectionEndEl[0].getAttribute('rel').slice(1));
|
||||
let b = parseInt($selectionStartEls[0].getAttribute('rel').slice(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}]`);
|
||||
}
|
||||
$linesEls.filter(classes.join(',')).each(function () {
|
||||
this.closest('tr').classList.add('active');
|
||||
});
|
||||
changeHash(`#L${a}-L${b}`);
|
||||
const rangeFields = range ? range.split('-') : [];
|
||||
const start = rangeFields[0] ?? '';
|
||||
if (!start) return null;
|
||||
const stop = rangeFields[1] || start;
|
||||
|
||||
updateIssueHref(`L${a}-L${b}`);
|
||||
updateViewGitBlameFragment(`L${a}-L${b}`);
|
||||
updateCopyPermalinkUrl(`L${a}-L${b}`);
|
||||
return;
|
||||
}
|
||||
// format is i.e. 'L14-L26'
|
||||
let startLineNum = parseInt(start.substring(1));
|
||||
let stopLineNum = parseInt(stop.substring(1));
|
||||
if (startLineNum > stopLineNum) {
|
||||
const tmp = startLineNum;
|
||||
startLineNum = stopLineNum;
|
||||
stopLineNum = tmp;
|
||||
range = `${stop}-${start}`;
|
||||
}
|
||||
$selectionEndEl[0].closest('tr').classList.add('active');
|
||||
changeHash(`#${$selectionEndEl[0].getAttribute('rel')}`);
|
||||
|
||||
updateIssueHref($selectionEndEl[0].getAttribute('rel'));
|
||||
updateViewGitBlameFragment($selectionEndEl[0].getAttribute('rel'));
|
||||
updateCopyPermalinkUrl($selectionEndEl[0].getAttribute('rel'));
|
||||
const first = elLineNums[startLineNum - 1] ?? null;
|
||||
for (let i = startLineNum - 1; i <= stopLineNum - 1 && i < elLineNums.length; i++) {
|
||||
elLineNums[i].closest('tr').classList.add('active');
|
||||
}
|
||||
changeHash(`#${range}`);
|
||||
updateIssueHref(range);
|
||||
updateViewGitBlameFragment(range);
|
||||
updateCopyPermalinkUrl(range);
|
||||
return first;
|
||||
}
|
||||
|
||||
function showLineButton() {
|
||||
@@ -103,6 +83,8 @@ function showLineButton() {
|
||||
|
||||
// find active row and add button
|
||||
const tr = document.querySelector('.code-view tr.active');
|
||||
if (!tr) return;
|
||||
|
||||
const td = tr.querySelector('td.lines-num');
|
||||
const btn = document.createElement('button');
|
||||
btn.classList.add('code-line-button', 'ui', 'basic', 'button');
|
||||
@@ -128,62 +110,36 @@ function showLineButton() {
|
||||
}
|
||||
|
||||
export function initRepoCodeView() {
|
||||
if ($('.code-view .lines-num').length > 0) {
|
||||
$(document).on('click', '.lines-num span', function (e) {
|
||||
const linesEls = getLineEls();
|
||||
const selectedEls = Array.from(linesEls).filter((el) => {
|
||||
return el.matches(`[rel=${this.getAttribute('id')}]`);
|
||||
});
|
||||
if (!document.querySelector('.code-view .lines-num')) return;
|
||||
|
||||
let from;
|
||||
if (e.shiftKey) {
|
||||
from = Array.from(linesEls).filter((el) => {
|
||||
return el.closest('tr').classList.contains('active');
|
||||
});
|
||||
}
|
||||
selectRange($(linesEls), $(selectedEls), from ? $(from) : null);
|
||||
window.getSelection().removeAllRanges();
|
||||
showLineButton();
|
||||
});
|
||||
|
||||
$(window).on('hashchange', () => {
|
||||
let m = rangeAnchorRegex.exec(window.location.hash);
|
||||
const $linesEls = $(getLineEls());
|
||||
let $first;
|
||||
if (m) {
|
||||
$first = $linesEls.filter(`[rel=${m[1]}]`);
|
||||
if ($first.length) {
|
||||
selectRange($linesEls, $first, $linesEls.filter(`[rel=${m[2]}]`));
|
||||
|
||||
// show code view menu marker (don't show in blame page)
|
||||
if (!isBlame()) {
|
||||
showLineButton();
|
||||
}
|
||||
|
||||
$('html, body').scrollTop($first.offset().top - 200);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m = singleAnchorRegex.exec(window.location.hash);
|
||||
if (m) {
|
||||
$first = $linesEls.filter(`[rel=L${m[2]}]`);
|
||||
if ($first.length) {
|
||||
selectRange($linesEls, $first);
|
||||
|
||||
// show code view menu marker (don't show in blame page)
|
||||
if (!isBlame()) {
|
||||
showLineButton();
|
||||
}
|
||||
|
||||
$('html, body').scrollTop($first.offset().top - 200);
|
||||
}
|
||||
}
|
||||
}).trigger('hashchange');
|
||||
}
|
||||
$(document).on('click', '.fold-file', ({currentTarget}) => {
|
||||
invertFileFolding(currentTarget.closest('.file-content'), currentTarget);
|
||||
let selRangeStart: string;
|
||||
addDelegatedEventListener(document, 'click', '.lines-num span', (el: HTMLElement, e: KeyboardEvent) => {
|
||||
if (!selRangeStart || !e.shiftKey) {
|
||||
selRangeStart = el.getAttribute('id');
|
||||
selectRange(selRangeStart);
|
||||
} else {
|
||||
const selRangeStop = el.getAttribute('id');
|
||||
selectRange(`${selRangeStart}-${selRangeStop}`);
|
||||
}
|
||||
window.getSelection().removeAllRanges();
|
||||
showLineButton();
|
||||
});
|
||||
$(document).on('click', '.copy-line-permalink', async ({currentTarget}) => {
|
||||
await clippie(toAbsoluteUrl(currentTarget.getAttribute('data-url')));
|
||||
|
||||
const onHashChange = () => {
|
||||
if (!window.location.hash) return;
|
||||
const range = window.location.hash.substring(1);
|
||||
const first = selectRange(range);
|
||||
if (first) {
|
||||
// set scrollRestoration to 'manual' when there is a hash in url, so that the scroll position will not be remembered after refreshing
|
||||
if (window.history.scrollRestoration !== 'manual') window.history.scrollRestoration = 'manual';
|
||||
first.scrollIntoView({block: 'start'});
|
||||
showLineButton();
|
||||
}
|
||||
};
|
||||
onHashChange();
|
||||
window.addEventListener('hashchange', onHashChange);
|
||||
|
||||
addDelegatedEventListener(document, 'click', '.copy-line-permalink', (el) => {
|
||||
clippie(toAbsoluteUrl(el.getAttribute('data-url')));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
import {POST, GET} from '../modules/fetch.ts';
|
||||
import {fomanticQuery} from '../modules/fomantic/base.ts';
|
||||
import {createTippy} from '../modules/tippy.ts';
|
||||
import {invertFileFolding} from './file-fold.ts';
|
||||
|
||||
const {pageData, i18n} = window.config;
|
||||
|
||||
@@ -244,4 +245,8 @@ export function initRepoDiffView() {
|
||||
initRepoDiffFileViewToggle();
|
||||
initViewedCheckboxListenerFor();
|
||||
initExpandAndCollapseFilesButton();
|
||||
|
||||
addDelegatedEventListener(document, 'click', '.fold-file', (el) => {
|
||||
invertFileFolding(el.closest('.file-content'), el);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import $ from 'jquery';
|
||||
import {POST} from '../modules/fetch.ts';
|
||||
import {queryElems, toggleElem} from '../utils/dom.ts';
|
||||
import {initIssueSidebarComboList} from './repo-issue-sidebar-combolist.ts';
|
||||
@@ -9,9 +8,8 @@ function initBranchSelector() {
|
||||
if (!elSelectBranch) return;
|
||||
|
||||
const urlUpdateIssueRef = elSelectBranch.getAttribute('data-url-update-issueref');
|
||||
const $selectBranch = $(elSelectBranch);
|
||||
const $branchMenu = $selectBranch.find('.reference-list-menu');
|
||||
$branchMenu.find('.item:not(.no-select)').on('click', async function (e) {
|
||||
const elBranchMenu = elSelectBranch.querySelector('.reference-list-menu');
|
||||
queryElems(elBranchMenu, '.item:not(.no-select)', (el) => el.addEventListener('click', async function (e) {
|
||||
e.preventDefault();
|
||||
const selectedValue = this.getAttribute('data-id'); // eg: "refs/heads/my-branch"
|
||||
const selectedText = this.getAttribute('data-name'); // eg: "my-branch"
|
||||
@@ -29,7 +27,7 @@ function initBranchSelector() {
|
||||
document.querySelector<HTMLInputElement>(selectedHiddenSelector).value = selectedValue;
|
||||
elSelectBranch.querySelector('.text-branch-name').textContent = selectedText;
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function initRepoIssueDue() {
|
||||
|
||||
@@ -373,10 +373,6 @@ export async function handleReply(el) {
|
||||
|
||||
export function initRepoPullRequestReview() {
|
||||
if (window.location.hash && window.location.hash.startsWith('#issuecomment-')) {
|
||||
// set scrollRestoration to 'manual' when there is a hash in url, so that the scroll position will not be remembered after refreshing
|
||||
if (window.history.scrollRestoration !== 'manual') {
|
||||
window.history.scrollRestoration = 'manual';
|
||||
}
|
||||
const commentDiv = document.querySelector(window.location.hash);
|
||||
if (commentDiv) {
|
||||
// get the name of the parent id
|
||||
@@ -384,14 +380,6 @@ export function initRepoPullRequestReview() {
|
||||
if (groupID && groupID.startsWith('code-comments-')) {
|
||||
const id = groupID.slice(14);
|
||||
const ancestorDiffBox = commentDiv.closest('.diff-file-box');
|
||||
// on pages like conversation, there is no diff header
|
||||
const diffHeader = ancestorDiffBox?.querySelector('.diff-file-header');
|
||||
|
||||
// offset is for scrolling
|
||||
let offset = 30;
|
||||
if (diffHeader) {
|
||||
offset += $('.diff-detail-box').outerHeight() + $(diffHeader).outerHeight();
|
||||
}
|
||||
|
||||
hideElem(`#show-outdated-${id}`);
|
||||
showElem(`#code-comments-${id}, #code-preview-${id}, #hide-outdated-${id}`);
|
||||
@@ -399,12 +387,11 @@ export function initRepoPullRequestReview() {
|
||||
if (ancestorDiffBox?.getAttribute('data-folded') === 'true') {
|
||||
setFileFolding(ancestorDiffBox, ancestorDiffBox.querySelector('.fold-file'), false);
|
||||
}
|
||||
|
||||
window.scrollTo({
|
||||
top: $(commentDiv).offset().top - offset,
|
||||
behavior: 'instant',
|
||||
});
|
||||
}
|
||||
// set scrollRestoration to 'manual' when there is a hash in url, so that the scroll position will not be remembered after refreshing
|
||||
if (window.history.scrollRestoration !== 'manual') window.history.scrollRestoration = 'manual';
|
||||
// wait for a while because some elements (eg: image, editor, etc.) may change the viewport's height.
|
||||
setTimeout(() => commentDiv.scrollIntoView({block: 'start'}), 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ function initRepoSettingsBranches() {
|
||||
let matched = false;
|
||||
const statusCheck = el.getAttribute('data-status-check');
|
||||
for (const pattern of validPatterns) {
|
||||
if (minimatch(statusCheck, pattern)) {
|
||||
if (minimatch(statusCheck, pattern, {noext: true})) { // https://github.com/go-gitea/gitea/issues/33121 disable extended glob syntax
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
|
||||
+2
-3
@@ -41,7 +41,7 @@ import {initUserSettings} from './features/user-settings.ts';
|
||||
import {initRepoActivityTopAuthorsChart, initRepoArchiveLinks} from './features/repo-common.ts';
|
||||
import {initRepoMigrationStatusChecker} from './features/repo-migrate.ts';
|
||||
import {initRepoDiffView} from './features/repo-diff.ts';
|
||||
import {initOrgTeamSearchRepoBox, initOrgTeamSettings} from './features/org-team.ts';
|
||||
import {initOrgTeam} from './features/org-team.ts';
|
||||
import {initUserAuthWebAuthn, initUserAuthWebAuthnRegister} from './features/user-auth-webauthn.ts';
|
||||
import {initRepoRelease, initRepoReleaseNew} from './features/repo-release.ts';
|
||||
import {initRepoEditor} from './features/repo-editor.ts';
|
||||
@@ -167,8 +167,7 @@ onDomReady(() => {
|
||||
initNotificationCount,
|
||||
initNotificationsTable,
|
||||
|
||||
initOrgTeamSearchRepoBox,
|
||||
initOrgTeamSettings,
|
||||
initOrgTeam,
|
||||
|
||||
initRepoActivityTopAuthorsChart,
|
||||
initRepoArchiveLinks,
|
||||
|
||||
@@ -28,6 +28,7 @@ import octiconEye from '../../public/assets/img/svg/octicon-eye.svg';
|
||||
import octiconFile from '../../public/assets/img/svg/octicon-file.svg';
|
||||
import octiconFileDirectoryFill from '../../public/assets/img/svg/octicon-file-directory-fill.svg';
|
||||
import octiconFileDirectoryOpenFill from '../../public/assets/img/svg/octicon-file-directory-open-fill.svg';
|
||||
import octiconFileSubmodule from '../../public/assets/img/svg/octicon-file-submodule.svg';
|
||||
import octiconFilter from '../../public/assets/img/svg/octicon-filter.svg';
|
||||
import octiconGear from '../../public/assets/img/svg/octicon-gear.svg';
|
||||
import octiconGitBranch from '../../public/assets/img/svg/octicon-git-branch.svg';
|
||||
@@ -104,6 +105,7 @@ const svgs = {
|
||||
'octicon-file': octiconFile,
|
||||
'octicon-file-directory-fill': octiconFileDirectoryFill,
|
||||
'octicon-file-directory-open-fill': octiconFileDirectoryOpenFill,
|
||||
'octicon-file-submodule': octiconFileSubmodule,
|
||||
'octicon-filter': octiconFilter,
|
||||
'octicon-gear': octiconGear,
|
||||
'octicon-git-branch': octiconGitBranch,
|
||||
|
||||
@@ -50,6 +50,7 @@ test('parseIssueNewHref', () => {
|
||||
expect(parseIssueNewHref('/owner/repo/issues/new?query')).toEqual({ownerName: 'owner', repoName: 'repo', pathType: 'issues'});
|
||||
expect(parseIssueNewHref('/sub/owner/repo/issues/new#hash')).toEqual({ownerName: 'owner', repoName: 'repo', pathType: 'issues'});
|
||||
expect(parseIssueNewHref('/sub/owner/repo/compare/feature/branch-1...fix/branch-2')).toEqual({ownerName: 'owner', repoName: 'repo', pathType: 'pulls'});
|
||||
expect(parseIssueNewHref('/other')).toEqual({});
|
||||
});
|
||||
|
||||
test('parseUrl', () => {
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ export function parseIssueHref(href: string): IssuePathInfo {
|
||||
export function parseIssueNewHref(href: string): IssuePathInfo {
|
||||
const path = (href || '').replace(/[#?].*$/, '');
|
||||
const [_, ownerName, repoName, pathTypeField] = /([^/]+)\/([^/]+)\/(issues\/new|compare\/.+\.\.\.)/.exec(path) || [];
|
||||
const pathType = pathTypeField.startsWith('issues/new') ? 'issues' : 'pulls';
|
||||
const pathType = pathTypeField ? (pathTypeField.startsWith('issues/new') ? 'issues' : 'pulls') : undefined;
|
||||
return {ownerName, repoName, pathType};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user