{{if .EscapeStatus.Escaped}}
{{ctx.Locale.Tr "repo.unescape_control_characters"}}
{{ctx.Locale.Tr "repo.escape_control_characters"}}
diff --git a/tests/integration/api_packages_cran_test.go b/tests/integration/api_packages_cran_test.go
index d307e87d4e0f8..667ba0908ce20 100644
--- a/tests/integration/api_packages_cran_test.go
+++ b/tests/integration/api_packages_cran_test.go
@@ -115,6 +115,14 @@ func TestPackageCran(t *testing.T) {
MakeRequest(t, req, http.StatusOK)
})
+ t.Run("DownloadArchived", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", fmt.Sprintf("%s/src/contrib/Archive/%s/%s_%s.tar.gz", url, packageName, packageName, packageVersion)).
+ AddBasicAuth(user.Name)
+ MakeRequest(t, req, http.StatusOK)
+ })
+
t.Run("Enumerate", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
diff --git a/tests/integration/repo_test.go b/tests/integration/repo_test.go
index b967ccad1ec69..7889dfaf3b797 100644
--- a/tests/integration/repo_test.go
+++ b/tests/integration/repo_test.go
@@ -49,7 +49,7 @@ func testViewRepo(t *testing.T) {
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
- files := htmlDoc.doc.Find("#repo-files-table > TBODY > TR")
+ files := htmlDoc.doc.Find("#repo-files-table .repo-file-item")
type file struct {
fileName string
@@ -61,7 +61,7 @@ func testViewRepo(t *testing.T) {
var items []file
files.Each(func(i int, s *goquery.Selection) {
- tds := s.Find("td")
+ tds := s.Find(".repo-file-cell")
var f file
tds.Each(func(i int, s *goquery.Selection) {
if i == 0 {
@@ -127,10 +127,10 @@ func TestViewRepo1CloneLinkAnonymous(t *testing.T) {
resp := MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
- link, exists := htmlDoc.doc.Find("#repo-clone-https").Attr("data-link")
+ link, exists := htmlDoc.doc.Find(".repo-clone-https").Attr("data-link")
assert.True(t, exists, "The template has changed")
assert.Equal(t, setting.AppURL+"user2/repo1.git", link)
- _, exists = htmlDoc.doc.Find("#repo-clone-ssh").Attr("data-link")
+ _, exists = htmlDoc.doc.Find(".repo-clone-ssh").Attr("data-link")
assert.False(t, exists)
}
@@ -143,10 +143,10 @@ func TestViewRepo1CloneLinkAuthorized(t *testing.T) {
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
- link, exists := htmlDoc.doc.Find("#repo-clone-https").Attr("data-link")
+ link, exists := htmlDoc.doc.Find(".repo-clone-https").Attr("data-link")
assert.True(t, exists, "The template has changed")
assert.Equal(t, setting.AppURL+"user2/repo1.git", link)
- link, exists = htmlDoc.doc.Find("#repo-clone-ssh").Attr("data-link")
+ link, exists = htmlDoc.doc.Find(".repo-clone-ssh").Attr("data-link")
assert.True(t, exists, "The template has changed")
sshURL := fmt.Sprintf("ssh://%s@%s:%d/user2/repo1.git", setting.SSH.User, setting.SSH.Domain, setting.SSH.Port)
assert.Equal(t, sshURL, link)
@@ -161,7 +161,7 @@ func TestViewRepoWithSymlinks(t *testing.T) {
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
- files := htmlDoc.doc.Find("#repo-files-table > TBODY > TR > TD.name > SPAN.truncate")
+ files := htmlDoc.doc.Find("#repo-files-table .repo-file-cell.name")
items := files.Map(func(i int, s *goquery.Selection) string {
cls, _ := s.Find("SVG").Attr("class")
file := strings.Trim(s.Find("A").Text(), " \t\n")
diff --git a/tools/generate-images.js b/tools/generate-images.js
index 0bd3af29e4c3d..d28e0916f7351 100755
--- a/tools/generate-images.js
+++ b/tools/generate-images.js
@@ -1,6 +1,6 @@
#!/usr/bin/env node
-import imageminZopfli from 'imagemin-zopfli'; // eslint-disable-line i/no-unresolved
-import {loadSVGFromString, Canvas, Rect, util} from 'fabric/node'; // eslint-disable-line i/no-unresolved
+import imageminZopfli from 'imagemin-zopfli'; // eslint-disable-line import-x/no-unresolved
+import {loadSVGFromString, Canvas, Rect, util} from 'fabric/node'; // eslint-disable-line import-x/no-unresolved
import {optimize} from 'svgo';
import {readFile, writeFile} from 'node:fs/promises';
import {argv, exit} from 'node:process';
diff --git a/web_src/css/index.css b/web_src/css/index.css
index 158ae42d3e325..02513aebc1cd1 100644
--- a/web_src/css/index.css
+++ b/web_src/css/index.css
@@ -66,7 +66,10 @@
@import "./repo/wiki.css";
@import "./repo/header.css";
@import "./repo/home.css";
+@import "./repo/home-file-list.css";
@import "./repo/reactions.css";
+@import "./repo/clone.css";
+@import "./repo/commit-sign.css";
@import "./editor/fileeditor.css";
@import "./editor/combomarkdowneditor.css";
diff --git a/web_src/css/repo.css b/web_src/css/repo.css
index f5785c41a7773..9a43e10e826b7 100644
--- a/web_src/css/repo.css
+++ b/web_src/css/repo.css
@@ -101,42 +101,6 @@
margin-bottom: 12px;
}
-.repository .clone-panel {
- display: flex;
- flex: 1;
-}
-
-.repository.wiki .clone-panel {
- flex: 0;
-}
-
-.repository.wiki .clone-panel input {
- width: 20ch;
-}
-
-.repository .clone-panel #repo-clone-url {
- border-radius: 0;
- flex: 1;
-}
-
-.repository .ui.action.input.clone-panel > button + button,
-.repository .ui.action.input.clone-panel > button + input {
- margin-left: -1px; /* make the borders overlap to avoid double borders */
-}
-
-.repository .clone-panel > button:first-of-type {
- border-radius: var(--border-radius) 0 0 var(--border-radius) !important;
-}
-
-.repository .clone-panel > button:last-of-type {
- border-radius: 0 var(--border-radius) var(--border-radius) 0 !important;
-}
-
-.repository .clone-panel .dropdown .menu {
- right: 0 !important;
- left: auto !important;
-}
-
.repository .repo-description {
font-size: 16px;
margin-bottom: 5px;
@@ -177,138 +141,6 @@ td .commit-summary {
overflow-wrap: anywhere;
}
-/* this is what limits the commit table width to a value that works on all viewport sizes */
-#repo-files-table th:first-of-type {
- max-width: calc(calc(min(100vw, 1280px)) - 145px - calc(2 * var(--page-margin-x)));
-}
-
-.repository.file.list #repo-files-table thead th {
- font-weight: var(--font-weight-normal);
-}
-
-.repository.file.list #repo-files-table tbody .svg {
- margin-left: 3px;
- margin-right: 5px;
-}
-
-.repository.file.list #repo-files-table tbody .svg.octicon-reply {
- margin-right: 10px;
-}
-
-.repository.file.list #repo-files-table tbody .svg.octicon-file-directory-fill,
-.repository.file.list #repo-files-table tbody .svg.octicon-file-submodule {
- color: var(--color-primary);
-}
-
-.repository.file.list #repo-files-table tbody .svg.octicon-file,
-.repository.file.list #repo-files-table tbody .svg.octicon-file-symlink-file,
-.repository.file.list #repo-files-table tbody .svg.octicon-file-directory-symlink {
- color: var(--color-secondary-dark-7);
-}
-
-.repository.file.list #repo-files-table td {
- padding-top: 0;
- padding-bottom: 0;
- overflow: initial;
-}
-
-.repository.file.list #repo-files-table td.name {
- width: 33%;
- max-width: calc(100vw - 140px);
-}
-
-@media (min-width: 1201px) {
- .repository.file.list #repo-files-table td.name {
- max-width: 150px;
- }
-}
-
-@media (min-width: 992px) and (max-width: 1200px) {
- .repository.file.list #repo-files-table td.name {
- max-width: 200px;
- }
-}
-
-@media (min-width: 768px) and (max-width: 991.98px) {
- .repository.file.list #repo-files-table td.name {
- max-width: 300px;
- }
-}
-
-.repository.file.list #repo-files-table td.message {
- color: var(--color-text-light-1);
- width: 66%;
-}
-
-@media (min-width: 1201px) {
- .repository.file.list #repo-files-table td.message {
- max-width: 400px;
- }
-}
-
-@media (min-width: 992px) and (max-width: 1200px) {
- .repository.file.list #repo-files-table td.message {
- max-width: 350px;
- }
-}
-
-@media (min-width: 768px) and (max-width: 991.98px) {
- .repository.file.list #repo-files-table td.message {
- max-width: 250px;
- }
-}
-
-.repository.file.list #repo-files-table td.age {
- color: var(--color-text-light-1);
-}
-
-.repository.file.list #repo-files-table td .truncate {
- display: inline-block;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- width: 100%;
- padding-top: 8px;
- padding-bottom: 8px;
-}
-
-.repository.file.list #repo-files-table td a {
- padding-top: 8px;
- padding-bottom: 8px;
-}
-
-.repository.file.list #repo-files-table td .at {
- margin-left: 3px;
- margin-right: 3px;
-}
-
-.repository.file.list #repo-files-table td > * {
- vertical-align: middle;
-}
-
-.repository.file.list #repo-files-table td.message .isSigned {
- cursor: default;
-}
-
-.repository.file.list #repo-files-table tr:last-of-type td:first-child {
- border-bottom-left-radius: var(--border-radius);
-}
-
-.repository.file.list #repo-files-table tr:last-of-type td:last-child {
- border-bottom-right-radius: var(--border-radius);
-}
-
-.repository.file.list #repo-files-table tr:hover {
- background-color: var(--color-hover);
-}
-
-.repository.file.list #repo-files-table tr.has-parent a {
- display: inline-block;
- padding-top: 8px;
- padding-bottom: 8px;
- width: calc(100% - 1.25rem);
-}
-
.repository.file.list .non-diff-file-content .header .icon {
font-size: 1em;
}
@@ -787,47 +619,6 @@ td .commit-summary {
height: 30px !important;
}
-.singular-commit .shabox .sha.label {
- margin: 0;
- border: 1px solid var(--color-light-border);
-}
-
-.singular-commit .shabox .sha.label.isSigned.isWarning {
- border: 1px solid var(--color-red-badge);
- background: var(--color-red-badge-bg);
-}
-
-.singular-commit .shabox .sha.label.isSigned.isWarning:hover {
- background: var(--color-red-badge-hover-bg) !important;
-}
-
-.singular-commit .shabox .sha.label.isSigned.isVerified {
- border: 1px solid var(--color-green-badge);
- background: var(--color-green-badge-bg);
-}
-
-.singular-commit .shabox .sha.label.isSigned.isVerified:hover {
- background: var(--color-green-badge-hover-bg) !important;
-}
-
-.singular-commit .shabox .sha.label.isSigned.isVerifiedUntrusted {
- border: 1px solid var(--color-yellow-badge);
- background: var(--color-yellow-badge-bg);
-}
-
-.singular-commit .shabox .sha.label.isSigned.isVerifiedUntrusted:hover {
- background: var(--color-yellow-badge-hover-bg) !important;
-}
-
-.singular-commit .shabox .sha.label.isSigned.isVerifiedUnmatched {
- border: 1px solid var(--color-orange-badge);
- background: var(--color-orange-badge-bg);
-}
-
-.singular-commit .shabox .sha.label.isSigned.isVerifiedUnmatched:hover {
- background: var(--color-orange-badge-hover-bg) !important;
-}
-
.repository.view.issue .comment-list .timeline-item.event > .commit-status-link {
float: right;
margin-right: 8px;
@@ -1162,151 +953,6 @@ td .commit-summary {
background-color: var(--color-light) !important;
}
-.repository #commits-table td.sha .sha.label,
-.repository #repo-files-table .sha.label,
-.repository #repo-file-commit-box .sha.label,
-.repository #rev-list .sha.label,
-.repository .timeline-item.commits-list .singular-commit .sha.label {
- border: 1px solid var(--color-light-border);
-}
-
-.repository #commits-table td.sha .sha.label .detail.icon,
-.repository #repo-files-table .sha.label .detail.icon,
-.repository #repo-file-commit-box .sha.label .detail.icon,
-.repository #rev-list .sha.label .detail.icon,
-.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon {
- background: var(--color-light);
- margin: -6px -10px -4px 0;
- padding: 5px 4px 5px 6px;
- border-left: 1px solid var(--color-light-border);
- border-top: 0;
- border-right: 0;
- border-bottom: 0;
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
-}
-
-.repository #commits-table td.sha .sha.label .detail.icon .svg,
-.repository #repo-files-table .sha.label .detail.icon .svg,
-.repository #repo-file-commit-box .sha.label .detail.icon .svg,
-.repository #rev-list .sha.label .detail.icon .svg,
-.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon .svg {
- margin: 0 0.25em 0 0;
-}
-
-.repository #commits-table td.sha .sha.label .detail.icon > div,
-.repository #repo-files-table .sha.label .detail.icon > div,
-.repository #repo-file-commit-box .sha.label .detail.icon > div,
-.repository #rev-list .sha.label .detail.icon > div,
-.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon > div {
- display: flex;
- align-items: center;
-}
-
-.repository #commits-table td.sha .sha.label.isSigned.isWarning,
-.repository #repo-files-table .sha.label.isSigned.isWarning,
-.repository #repo-file-commit-box .sha.label.isSigned.isWarning,
-.repository #rev-list .sha.label.isSigned.isWarning,
-.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning {
- border: 1px solid var(--color-red-badge);
- background: var(--color-red-badge-bg);
-}
-
-.repository #commits-table td.sha .sha.label.isSigned.isWarning .detail.icon,
-.repository #repo-files-table .sha.label.isSigned.isWarning .detail.icon,
-.repository #repo-file-commit-box .sha.label.isSigned.isWarning .detail.icon,
-.repository #rev-list .sha.label.isSigned.isWarning .detail.icon,
-.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning .detail.icon {
- border-left: 1px solid var(--color-red-badge);
- color: var(--color-red-badge);
-}
-
-.repository #commits-table td.sha .sha.label.isSigned.isWarning:hover,
-.repository #repo-files-table .sha.label.isSigned.isWarning:hover,
-.repository #repo-file-commit-box .sha.label.isSigned.isWarning:hover,
-.repository #rev-list .sha.label.isSigned.isWarning:hover,
-.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning:hover {
- background: var(--color-red-badge-hover-bg) !important;
-}
-
-.repository #commits-table td.sha .sha.label.isSigned.isVerified,
-.repository #repo-files-table .sha.label.isSigned.isVerified,
-.repository #repo-file-commit-box .sha.label.isSigned.isVerified,
-.repository #rev-list .sha.label.isSigned.isVerified,
-.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified {
- border: 1px solid var(--color-green-badge);
- background: var(--color-green-badge-bg);
-}
-
-.repository #commits-table td.sha .sha.label.isSigned.isVerified .detail.icon,
-.repository #repo-files-table .sha.label.isSigned.isVerified .detail.icon,
-.repository #repo-file-commit-box .sha.label.isSigned.isVerified .detail.icon,
-.repository #rev-list .sha.label.isSigned.isVerified .detail.icon,
-.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified .detail.icon {
- border-left: 1px solid var(--color-green-badge);
- color: var(--color-green-badge);
-}
-
-.repository #commits-table td.sha .sha.label.isSigned.isVerified:hover,
-.repository #repo-files-table .sha.label.isSigned.isVerified:hover,
-.repository #repo-file-commit-box .sha.label.isSigned.isVerified:hover,
-.repository #rev-list .sha.label.isSigned.isVerified:hover,
-.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified:hover {
- background: var(--color-green-badge-hover-bg) !important;
-}
-
-.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted,
-.repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted,
-.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted,
-.repository #rev-list .sha.label.isSigned.isVerifiedUntrusted,
-.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted {
- border: 1px solid var(--color-yellow-badge);
- background: var(--color-yellow-badge-bg);
-}
-
-.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
-.repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
-.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
-.repository #rev-list .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
-.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted .detail.icon {
- border-left: 1px solid var(--color-yellow-badge);
- color: var(--color-yellow-badge);
-}
-
-.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted:hover,
-.repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted:hover,
-.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted:hover,
-.repository #rev-list .sha.label.isSigned.isVerifiedUntrusted:hover,
-.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted:hover {
- background: var(--color-yellow-badge-hover-bg) !important;
-}
-
-.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched,
-.repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched,
-.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched,
-.repository #rev-list .sha.label.isSigned.isVerifiedUnmatched,
-.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched {
- border: 1px solid var(--color-orange-badge);
- background: var(--color-orange-badge-bg);
-}
-
-.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
-.repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
-.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
-.repository #rev-list .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
-.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched .detail.icon {
- border-left: 1px solid var(--color-orange-badge);
- color: var(--color-orange-badge);
-}
-
-.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched:hover,
-.repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched:hover,
-.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched:hover,
-.repository #rev-list .sha.label.isSigned.isVerifiedUnmatched:hover,
-.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched:hover {
- background: var(--color-orange-badge-hover-bg) !important;
-}
-
.repository .data-table {
width: 100%;
}
@@ -1615,14 +1261,6 @@ td .commit-summary {
font-weight: var(--font-weight-normal);
}
-.repository.quickstart .guide #repo-clone-url {
- border-radius: 0;
- padding: 5px 10px;
- font-size: 1.2em;
- line-height: 1.4;
- flex: 1
-}
-
.empty-placeholder {
display: flex;
flex-direction: column;
@@ -1678,92 +1316,6 @@ td .commit-summary {
padding-top: 0;
}
-.repository .ui.attached.isSigned.isWarning {
- border-left: 1px solid var(--color-error-border);
- border-right: 1px solid var(--color-error-border);
-}
-
-.repository .ui.attached.isSigned.isWarning.top,
-.repository .ui.attached.isSigned.isWarning.message {
- border-top: 1px solid var(--color-error-border);
-}
-
-.repository .ui.attached.isSigned.isWarning.message {
- box-shadow: none;
- background-color: var(--color-error-bg);
- color: var(--color-error-text);
-}
-
-.repository .ui.attached.isSigned.isWarning.message .ui.text {
- color: var(--color-error-text);
-}
-
-.repository .ui.attached.isSigned.isWarning:last-child,
-.repository .ui.attached.isSigned.isWarning.bottom {
- border-bottom: 1px solid var(--color-error-border);
-}
-
-.repository .ui.attached.isSigned.isVerified {
- border-left: 1px solid var(--color-success-border);
- border-right: 1px solid var(--color-success-border);
-}
-
-.repository .ui.attached.isSigned.isVerified.top,
-.repository .ui.attached.isSigned.isVerified.message {
- border-top: 1px solid var(--color-success-border);
-}
-
-.repository .ui.attached.isSigned.isVerified.message {
- box-shadow: none;
- background-color: var(--color-success-bg);
- color: var(--color-success-text);
-}
-
-.repository .ui.attached.isSigned.isVerified.message .pull-right {
- color: var(--color-text);
-}
-
-.repository .ui.attached.isSigned.isVerified.message .ui.text {
- color: var(--color-success-text);
-}
-
-.repository .ui.attached.isSigned.isVerified:last-child,
-.repository .ui.attached.isSigned.isVerified.bottom {
- border-bottom: 1px solid var(--color-success-border);
-}
-
-.repository .ui.attached.isSigned.isVerifiedUntrusted,
-.repository .ui.attached.isSigned.isVerifiedUnmatched {
- border-left: 1px solid var(--color-warning-border);
- border-right: 1px solid var(--color-warning-border);
-}
-
-.repository .ui.attached.isSigned.isVerifiedUntrusted.top,
-.repository .ui.attached.isSigned.isVerifiedUnmatched.top,
-.repository .ui.attached.isSigned.isVerifiedUntrusted.message,
-.repository .ui.attached.isSigned.isVerifiedUnmatched.message {
- border-top: 1px solid var(--color-warning-border);
-}
-
-.repository .ui.attached.isSigned.isVerifiedUntrusted.message,
-.repository .ui.attached.isSigned.isVerifiedUnmatched.message {
- box-shadow: none;
- background-color: var(--color-warning-bg);
- color: var(--color-warning-text);
-}
-
-.repository .ui.attached.isSigned.isVerifiedUntrusted.message .ui.text,
-.repository .ui.attached.isSigned.isVerifiedUnmatched.message .ui.text {
- color: var(--color-warning-text);
-}
-
-.repository .ui.attached.isSigned.isVerifiedUntrusted:last-child,
-.repository .ui.attached.isSigned.isVerifiedUnmatched:last-child,
-.repository .ui.attached.isSigned.isVerifiedUntrusted.bottom,
-.repository .ui.attached.isSigned.isVerifiedUnmatched.bottom {
- border-bottom: 1px solid var(--color-warning-border);
-}
-
.repository .ui.fluid.action.input .ui.search.action.input {
flex: auto;
}
@@ -1782,7 +1334,7 @@ td .commit-summary {
.repository .repository-summary .sub-menu .item {
flex: 1;
- height: 30px;
+ height: 33px; /* match search bar height, need to be improved in the future to use some consistent methods */
line-height: var(--line-height-default);
display: flex;
align-items: center;
@@ -2110,26 +1662,18 @@ td .commit-summary {
display: flex;
align-items: center;
gap: 8px;
- justify-content: space-between;
+ flex-wrap: wrap;
}
.repo-button-row-left,
.repo-button-row-right {
display: flex;
- flex: 1;
align-items: center;
gap: 0.5rem;
}
-.repo-button-row-right {
- justify-content: flex-end;
-}
-
-@media (max-width: 1200px) {
- .repository:not(.wiki) .repo-button-row {
- flex-direction: column;
- align-items: stretch;
- }
+.repo-button-row-left {
+ flex: 1;
}
.repo-button-row .button {
@@ -2143,16 +1687,6 @@ td .commit-summary {
padding-right: 22px !important; /* normal buttons have !important paddings, so we need to override it for dropdown (Add File) icons */
}
-.repo-button-row input {
- height: 30px;
-}
-
-@media (max-width: 600px) {
- .repo-button-row-left {
- flex-wrap: wrap;
- }
-}
-
tbody.commit-list {
vertical-align: baseline;
}
@@ -2178,11 +1712,6 @@ tbody.commit-list {
overflow-wrap: anywhere;
}
-/* but in the repo-files-table we cannot */
-#repo-files-table .commit-list .message-wrapper {
- display: inline-block;
-}
-
@media (max-width: 767.98px) {
tr.commit-list {
width: 100%;
@@ -2578,25 +2107,6 @@ tbody.commit-list {
}
@media (max-width: 767.98px) {
- .repository.file.list #repo-files-table .entry,
- .repository.file.list #repo-files-table .commit-list {
- align-items: center;
- display: flex !important;
- padding-top: 4px;
- padding-bottom: 4px;
- }
- .repository.file.list #repo-files-table .entry td.age,
- .repository.file.list #repo-files-table .commit-list td.age,
- .repository.file.list #repo-files-table .entry th.age,
- .repository.file.list #repo-files-table .commit-list th.age {
- margin-left: auto;
- }
- .repository.file.list #repo-files-table .entry td.message,
- .repository.file.list #repo-files-table .commit-list td.message,
- .repository.file.list #repo-files-table .entry span.commit-summary,
- .repository.file.list #repo-files-table .commit-list tr span.commit-summary {
- display: none !important;
- }
.repository.view.issue .comment-list .timeline,
.repository.view.issue .comment-list .timeline-item {
margin-left: 0;
diff --git a/web_src/css/repo/clone.css b/web_src/css/repo/clone.css
new file mode 100644
index 0000000000000..15709a78f652e
--- /dev/null
+++ b/web_src/css/repo/clone.css
@@ -0,0 +1,32 @@
+/* only used by "repo/empty.tmpl" */
+.clone-buttons-combo {
+ flex: 1;
+}
+
+.clone-buttons-combo input {
+ border-left: none !important;
+ border-radius: 0 !important;
+}
+
+/* used by the clone-panel popup */
+.clone-panel-field,
+.clone-panel-list {
+ margin: 10px;
+}
+
+.clone-panel-tab .item {
+ padding: 5px 10px;
+ background: none;
+}
+
+.clone-panel-tab .item.active {
+ border-bottom: 3px solid var(--color-secondary);
+}
+
+.clone-panel-tab + .divider {
+ margin: -1px 0 0;
+}
+
+.clone-panel-list .item {
+ margin: 5px 0;
+}
diff --git a/web_src/css/repo/commit-sign.css b/web_src/css/repo/commit-sign.css
new file mode 100644
index 0000000000000..e7570304194d3
--- /dev/null
+++ b/web_src/css/repo/commit-sign.css
@@ -0,0 +1,272 @@
+
+.repository .ui.attached.isSigned.isWarning {
+ border-left: 1px solid var(--color-error-border);
+ border-right: 1px solid var(--color-error-border);
+}
+
+.repository .ui.attached.isSigned.isWarning.top,
+.repository .ui.attached.isSigned.isWarning.message {
+ border-top: 1px solid var(--color-error-border);
+}
+
+.repository .ui.attached.isSigned.isWarning.message {
+ box-shadow: none;
+ background-color: var(--color-error-bg);
+ color: var(--color-error-text);
+}
+
+.repository .ui.attached.isSigned.isWarning.message .ui.text {
+ color: var(--color-error-text);
+}
+
+.repository .ui.attached.isSigned.isWarning:last-child,
+.repository .ui.attached.isSigned.isWarning.bottom {
+ border-bottom: 1px solid var(--color-error-border);
+}
+
+.repository .ui.attached.isSigned.isVerified {
+ border-left: 1px solid var(--color-success-border);
+ border-right: 1px solid var(--color-success-border);
+}
+
+.repository .ui.attached.isSigned.isVerified.top,
+.repository .ui.attached.isSigned.isVerified.message {
+ border-top: 1px solid var(--color-success-border);
+}
+
+.repository .ui.attached.isSigned.isVerified.message {
+ box-shadow: none;
+ background-color: var(--color-success-bg);
+ color: var(--color-success-text);
+}
+
+.repository .ui.attached.isSigned.isVerified.message .pull-right {
+ color: var(--color-text);
+}
+
+.repository .ui.attached.isSigned.isVerified.message .ui.text {
+ color: var(--color-success-text);
+}
+
+.repository .ui.attached.isSigned.isVerified:last-child,
+.repository .ui.attached.isSigned.isVerified.bottom {
+ border-bottom: 1px solid var(--color-success-border);
+}
+
+.repository .ui.attached.isSigned.isVerifiedUntrusted,
+.repository .ui.attached.isSigned.isVerifiedUnmatched {
+ border-left: 1px solid var(--color-warning-border);
+ border-right: 1px solid var(--color-warning-border);
+}
+
+.repository .ui.attached.isSigned.isVerifiedUntrusted.top,
+.repository .ui.attached.isSigned.isVerifiedUnmatched.top,
+.repository .ui.attached.isSigned.isVerifiedUntrusted.message,
+.repository .ui.attached.isSigned.isVerifiedUnmatched.message {
+ border-top: 1px solid var(--color-warning-border);
+}
+
+.repository .ui.attached.isSigned.isVerifiedUntrusted.message,
+.repository .ui.attached.isSigned.isVerifiedUnmatched.message {
+ box-shadow: none;
+ background-color: var(--color-warning-bg);
+ color: var(--color-warning-text);
+}
+
+.repository .ui.attached.isSigned.isVerifiedUntrusted.message .ui.text,
+.repository .ui.attached.isSigned.isVerifiedUnmatched.message .ui.text {
+ color: var(--color-warning-text);
+}
+
+.repository .ui.attached.isSigned.isVerifiedUntrusted:last-child,
+.repository .ui.attached.isSigned.isVerifiedUnmatched:last-child,
+.repository .ui.attached.isSigned.isVerifiedUntrusted.bottom,
+.repository .ui.attached.isSigned.isVerifiedUnmatched.bottom {
+ border-bottom: 1px solid var(--color-warning-border);
+}
+
+.repository #commits-table td.sha .sha.label,
+.repository #repo-files-table .sha.label,
+.repository #repo-file-commit-box .sha.label,
+.repository #rev-list .sha.label,
+.repository .timeline-item.commits-list .singular-commit .sha.label {
+ border: 1px solid var(--color-light-border);
+}
+
+.repository #commits-table td.sha .sha.label .detail.icon,
+.repository #repo-files-table .sha.label .detail.icon,
+.repository #repo-file-commit-box .sha.label .detail.icon,
+.repository #rev-list .sha.label .detail.icon,
+.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon {
+ background: var(--color-light);
+ margin: -6px -10px -4px 0;
+ padding: 5px 4px 5px 6px;
+ border-left: 1px solid var(--color-light-border);
+ border-top: 0;
+ border-right: 0;
+ border-bottom: 0;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.repository #commits-table td.sha .sha.label .detail.icon .svg,
+.repository #repo-files-table .sha.label .detail.icon .svg,
+.repository #repo-file-commit-box .sha.label .detail.icon .svg,
+.repository #rev-list .sha.label .detail.icon .svg,
+.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon .svg {
+ margin: 0 0.25em 0 0;
+}
+
+.repository #commits-table td.sha .sha.label .detail.icon > div,
+.repository #repo-files-table .sha.label .detail.icon > div,
+.repository #repo-file-commit-box .sha.label .detail.icon > div,
+.repository #rev-list .sha.label .detail.icon > div,
+.repository .timeline-item.commits-list .singular-commit .sha.label .detail.icon > div {
+ display: flex;
+ align-items: center;
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isWarning,
+.repository #repo-files-table .sha.label.isSigned.isWarning,
+.repository #repo-file-commit-box .sha.label.isSigned.isWarning,
+.repository #rev-list .sha.label.isSigned.isWarning,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning {
+ border: 1px solid var(--color-red-badge);
+ background: var(--color-red-badge-bg);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isWarning .detail.icon,
+.repository #repo-files-table .sha.label.isSigned.isWarning .detail.icon,
+.repository #repo-file-commit-box .sha.label.isSigned.isWarning .detail.icon,
+.repository #rev-list .sha.label.isSigned.isWarning .detail.icon,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning .detail.icon {
+ border-left: 1px solid var(--color-red-badge);
+ color: var(--color-red-badge);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isWarning:hover,
+.repository #repo-files-table .sha.label.isSigned.isWarning:hover,
+.repository #repo-file-commit-box .sha.label.isSigned.isWarning:hover,
+.repository #rev-list .sha.label.isSigned.isWarning:hover,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isWarning:hover {
+ background: var(--color-red-badge-hover-bg) !important;
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerified,
+.repository #repo-files-table .sha.label.isSigned.isVerified,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerified,
+.repository #rev-list .sha.label.isSigned.isVerified,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified {
+ border: 1px solid var(--color-green-badge);
+ background: var(--color-green-badge-bg);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerified .detail.icon,
+.repository #repo-files-table .sha.label.isSigned.isVerified .detail.icon,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerified .detail.icon,
+.repository #rev-list .sha.label.isSigned.isVerified .detail.icon,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified .detail.icon {
+ border-left: 1px solid var(--color-green-badge);
+ color: var(--color-green-badge);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerified:hover,
+.repository #repo-files-table .sha.label.isSigned.isVerified:hover,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerified:hover,
+.repository #rev-list .sha.label.isSigned.isVerified:hover,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerified:hover {
+ background: var(--color-green-badge-hover-bg) !important;
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted,
+.repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted,
+.repository #rev-list .sha.label.isSigned.isVerifiedUntrusted,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted {
+ border: 1px solid var(--color-yellow-badge);
+ background: var(--color-yellow-badge-bg);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
+.repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
+.repository #rev-list .sha.label.isSigned.isVerifiedUntrusted .detail.icon,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted .detail.icon {
+ border-left: 1px solid var(--color-yellow-badge);
+ color: var(--color-yellow-badge);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUntrusted:hover,
+.repository #repo-files-table .sha.label.isSigned.isVerifiedUntrusted:hover,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUntrusted:hover,
+.repository #rev-list .sha.label.isSigned.isVerifiedUntrusted:hover,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUntrusted:hover {
+ background: var(--color-yellow-badge-hover-bg) !important;
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched,
+.repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched,
+.repository #rev-list .sha.label.isSigned.isVerifiedUnmatched,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched {
+ border: 1px solid var(--color-orange-badge);
+ background: var(--color-orange-badge-bg);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
+.repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
+.repository #rev-list .sha.label.isSigned.isVerifiedUnmatched .detail.icon,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched .detail.icon {
+ border-left: 1px solid var(--color-orange-badge);
+ color: var(--color-orange-badge);
+}
+
+.repository #commits-table td.sha .sha.label.isSigned.isVerifiedUnmatched:hover,
+.repository #repo-files-table .sha.label.isSigned.isVerifiedUnmatched:hover,
+.repository #repo-file-commit-box .sha.label.isSigned.isVerifiedUnmatched:hover,
+.repository #rev-list .sha.label.isSigned.isVerifiedUnmatched:hover,
+.repository .timeline-item.commits-list .singular-commit .sha.label.isSigned.isVerifiedUnmatched:hover {
+ background: var(--color-orange-badge-hover-bg) !important;
+}
+
+.singular-commit .shabox .sha.label {
+ margin: 0;
+ border: 1px solid var(--color-light-border);
+}
+
+.singular-commit .shabox .sha.label.isSigned.isWarning {
+ border: 1px solid var(--color-red-badge);
+ background: var(--color-red-badge-bg);
+}
+
+.singular-commit .shabox .sha.label.isSigned.isWarning:hover {
+ background: var(--color-red-badge-hover-bg) !important;
+}
+
+.singular-commit .shabox .sha.label.isSigned.isVerified {
+ border: 1px solid var(--color-green-badge);
+ background: var(--color-green-badge-bg);
+}
+
+.singular-commit .shabox .sha.label.isSigned.isVerified:hover {
+ background: var(--color-green-badge-hover-bg) !important;
+}
+
+.singular-commit .shabox .sha.label.isSigned.isVerifiedUntrusted {
+ border: 1px solid var(--color-yellow-badge);
+ background: var(--color-yellow-badge-bg);
+}
+
+.singular-commit .shabox .sha.label.isSigned.isVerifiedUntrusted:hover {
+ background: var(--color-yellow-badge-hover-bg) !important;
+}
+
+.singular-commit .shabox .sha.label.isSigned.isVerifiedUnmatched {
+ border: 1px solid var(--color-orange-badge);
+ background: var(--color-orange-badge-bg);
+}
+
+.singular-commit .shabox .sha.label.isSigned.isVerifiedUnmatched:hover {
+ background: var(--color-orange-badge-hover-bg) !important;
+}
diff --git a/web_src/css/repo/home-file-list.css b/web_src/css/repo/home-file-list.css
new file mode 100644
index 0000000000000..eab2124d6f489
--- /dev/null
+++ b/web_src/css/repo/home-file-list.css
@@ -0,0 +1,70 @@
+#repo-files-table {
+ width: 100%;
+ display: grid;
+ grid-template-columns: auto 1fr auto;
+ border: 1px solid var(--color-light-border);
+ border-radius: var(--border-radius);
+ margin: 10px 0; /* match the "clone-panel-popup" margin to avoid "visual double-border" */
+}
+
+#repo-files-table .svg.octicon-file-directory-fill,
+#repo-files-table .svg.octicon-file-submodule {
+ color: var(--color-primary);
+}
+
+#repo-files-table .svg.octicon-file,
+#repo-files-table .svg.octicon-file-symlink-file,
+#repo-files-table .svg.octicon-file-directory-symlink {
+ color: var(--color-secondary-dark-7);
+}
+
+#repo-files-table .repo-file-item {
+ display: contents;
+}
+
+#repo-files-table .repo-file-item:hover > .repo-file-cell {
+ background: var(--color-hover);
+}
+
+#repo-files-table .repo-file-line,
+#repo-files-table .repo-file-cell {
+ border-top: 1px solid var(--color-light-border);
+ padding: 6px 10px;
+}
+
+#repo-files-table .repo-file-line:first-child {
+ border-top: none;
+}
+
+#repo-files-table .repo-file-line {
+ grid-column: 1 / span 3;
+ display: flex;
+ align-items: center;
+ gap: 0.5em;
+ padding: 6px 10px;
+}
+
+#repo-files-table .repo-file-cell.name {
+ max-width: 300px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+#repo-files-table .repo-file-cell.message {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ color: var(--color-text-light-1);
+}
+
+#repo-files-table .repo-file-cell.age {
+ white-space: nowrap;
+ color: var(--color-text-light-1);
+}
+
+@media (max-width: 767.98px) {
+ #repo-files-table .repo-file-cell.name {
+ max-width: 150px;
+ }
+}
diff --git a/web_src/css/repo/wiki.css b/web_src/css/repo/wiki.css
index ba502d32161d5..ca59dadb9c806 100644
--- a/web_src/css/repo/wiki.css
+++ b/web_src/css/repo/wiki.css
@@ -59,9 +59,6 @@
}
@media (max-width: 767.98px) {
- .repository.wiki .clone-panel #repo-clone-url {
- width: 160px;
- }
.repository.wiki .wiki-content-main.with-sidebar,
.repository.wiki .wiki-content-sidebar {
float: none;
diff --git a/web_src/js/features/repo-common.ts b/web_src/js/features/repo-common.ts
index 5185a7ca43510..90860720e4fc2 100644
--- a/web_src/js/features/repo-common.ts
+++ b/web_src/js/features/repo-common.ts
@@ -1,10 +1,11 @@
-import $ from 'jquery';
-import {hideElem, queryElems, showElem} from '../utils/dom.ts';
+import {queryElems} from '../utils/dom.ts';
import {POST} from '../modules/fetch.ts';
import {showErrorToast} from '../modules/toast.ts';
import {sleep} from '../utils.ts';
import RepoActivityTopAuthors from '../components/RepoActivityTopAuthors.vue';
import {createApp} from 'vue';
+import {toOriginUrl} from '../utils/url.ts';
+import {createTippy} from '../modules/tippy.ts';
async function onDownloadArchive(e) {
e.preventDefault();
@@ -41,54 +42,69 @@ export function initRepoActivityTopAuthorsChart() {
}
}
-export function initRepoCloneLink() {
- const $repoCloneSsh = $('#repo-clone-ssh');
- const $repoCloneHttps = $('#repo-clone-https');
- const $inputLink = $('#repo-clone-url');
+function initCloneSchemeUrlSelection(parent: Element) {
+ const elCloneUrlInput = parent.querySelector
('.repo-clone-url');
- if ((!$repoCloneSsh.length && !$repoCloneHttps.length) || !$inputLink.length) {
- return;
- }
+ const tabSsh = parent.querySelector('.repo-clone-ssh');
+ const tabHttps = parent.querySelector('.repo-clone-https');
+ const updateClonePanelUi = function() {
+ const scheme = localStorage.getItem('repo-clone-protocol') || 'https';
+ const isSSH = scheme === 'ssh' && Boolean(tabSsh) || scheme !== 'ssh' && !tabHttps;
+ if (tabHttps) {
+ tabHttps.textContent = window.origin.split(':')[0].toUpperCase(); // show "HTTP" or "HTTPS"
+ tabHttps.classList.toggle('active', !isSSH);
+ }
+ if (tabSsh) {
+ tabSsh.classList.toggle('active', isSSH);
+ }
+
+ const tab = isSSH ? tabSsh : tabHttps;
+ if (!tab) return;
+ const link = toOriginUrl(tab.getAttribute('data-link'));
+
+ for (const el of document.querySelectorAll('.js-clone-url')) {
+ if (el.nodeName === 'INPUT') {
+ (el as HTMLInputElement).value = link;
+ } else {
+ el.textContent = link;
+ }
+ }
+ for (const el of parent.querySelectorAll('.js-clone-url-editor')) {
+ el.href = el.getAttribute('data-href-template').replace('{url}', encodeURIComponent(link));
+ }
+ };
- $repoCloneSsh.on('click', () => {
+ updateClonePanelUi();
+ // tabSsh or tabHttps might not both exist, eg: guest view, or one is disabled by the server
+ tabSsh?.addEventListener('click', () => {
localStorage.setItem('repo-clone-protocol', 'ssh');
- window.updateCloneStates();
+ updateClonePanelUi();
});
- $repoCloneHttps.on('click', () => {
+ tabHttps?.addEventListener('click', () => {
localStorage.setItem('repo-clone-protocol', 'https');
- window.updateCloneStates();
+ updateClonePanelUi();
});
-
- $inputLink.on('focus', () => {
- $inputLink.trigger('select');
+ elCloneUrlInput.addEventListener('focus', () => {
+ elCloneUrlInput.select();
});
}
-export function initRepoCommonBranchOrTagDropdown(selector: string) {
- $(selector).each(function () {
- const $dropdown = $(this);
- $dropdown.find('.reference.column').on('click', function () {
- hideElem($dropdown.find('.scrolling.reference-list-menu'));
- showElem($($(this).data('target')));
- return false;
- });
+function initClonePanelButton(btn: HTMLButtonElement) {
+ const elPanel = btn.nextElementSibling;
+ // "init" must be before the "createTippy" otherwise the "tippy-target" will be removed from the document
+ initCloneSchemeUrlSelection(elPanel);
+ createTippy(btn, {
+ content: elPanel,
+ trigger: 'click',
+ placement: 'bottom-end',
+ interactive: true,
+ hideOnClick: true,
});
}
-export function initRepoCommonFilterSearchDropdown(selector: string) {
- const $dropdown = $(selector);
- if (!$dropdown.length) return;
-
- $dropdown.dropdown({
- fullTextSearch: 'exact',
- selectOnKeydown: false,
- onChange(_text, _value, $choice) {
- if ($choice[0].getAttribute('data-url')) {
- window.location.href = $choice[0].getAttribute('data-url');
- }
- },
- message: {noResults: $dropdown[0].getAttribute('data-no-results')},
- });
+export function initRepoCloneButtons() {
+ queryElems(document, '.js-btn-clone-panel', initClonePanelButton);
+ queryElems(document, '.clone-buttons-combo', initCloneSchemeUrlSelection);
}
export async function updateIssuesMeta(url, action, issue_ids, id) {
diff --git a/web_src/js/features/repo-legacy.ts b/web_src/js/features/repo-legacy.ts
index dfea66c7ad811..eaa9e3742a869 100644
--- a/web_src/js/features/repo-legacy.ts
+++ b/web_src/js/features/repo-legacy.ts
@@ -8,9 +8,7 @@ import {
} from './repo-issue.ts';
import {initUnicodeEscapeButton} from './repo-unicode-escape.ts';
import {initRepoBranchTagSelector} from '../components/RepoBranchTagSelector.vue';
-import {
- initRepoCloneLink, initRepoCommonBranchOrTagDropdown, initRepoCommonFilterSearchDropdown,
-} from './repo-common.ts';
+import {initRepoCloneButtons} from './repo-common.ts';
import {initCitationFileCopyContent} from './citation.ts';
import {initCompLabelEdit} from './comp/LabelEdit.ts';
import {initRepoDiffConversationNav} from './repo-diff.ts';
@@ -36,6 +34,33 @@ export function initBranchSelectorTabs() {
});
}
+function initRepoCommonBranchOrTagDropdown(selector: string) {
+ $(selector).each(function () {
+ const $dropdown = $(this);
+ $dropdown.find('.reference.column').on('click', function () {
+ hideElem($dropdown.find('.scrolling.reference-list-menu'));
+ showElem($($(this).data('target')));
+ return false;
+ });
+ });
+}
+
+function initRepoCommonFilterSearchDropdown(selector: string) {
+ const $dropdown = $(selector);
+ if (!$dropdown.length) return;
+
+ $dropdown.dropdown({
+ fullTextSearch: 'exact',
+ selectOnKeydown: false,
+ onChange(_text, _value, $choice) {
+ if ($choice[0].getAttribute('data-url')) {
+ window.location.href = $choice[0].getAttribute('data-url');
+ }
+ },
+ message: {noResults: $dropdown[0].getAttribute('data-no-results')},
+ });
+}
+
export function initRepository() {
if (!$('.page-content.repository').length) return;
@@ -54,7 +79,7 @@ export function initRepository() {
initRepoCommonFilterSearchDropdown('.choose.branch .dropdown');
}
- initRepoCloneLink();
+ initRepoCloneButtons();
initCitationFileCopyContent();
initRepoSettings();
diff --git a/web_src/js/utils/url.test.ts b/web_src/js/utils/url.test.ts
index 25fda79b19af9..bb331a6b4901a 100644
--- a/web_src/js/utils/url.test.ts
+++ b/web_src/js/utils/url.test.ts
@@ -1,4 +1,4 @@
-import {pathEscapeSegments, isUrl} from './url.ts';
+import {pathEscapeSegments, isUrl, toOriginUrl} from './url.ts';
test('pathEscapeSegments', () => {
expect(pathEscapeSegments('a/b/c')).toEqual('a/b/c');
@@ -11,3 +11,19 @@ test('isUrl', () => {
expect(isUrl('https://example.com/index.html')).toEqual(true);
expect(isUrl('/index.html')).toEqual(false);
});
+
+test('toOriginUrl', () => {
+ const oldLocation = String(window.location);
+ for (const origin of ['https://example.com', 'https://example.com:3000']) {
+ window.location.assign(`${origin}/`);
+ expect(toOriginUrl('/')).toEqual(`${origin}/`);
+ expect(toOriginUrl('/org/repo.git')).toEqual(`${origin}/org/repo.git`);
+ expect(toOriginUrl('https://another.com')).toEqual(`${origin}/`);
+ expect(toOriginUrl('https://another.com/')).toEqual(`${origin}/`);
+ expect(toOriginUrl('https://another.com/org/repo.git')).toEqual(`${origin}/org/repo.git`);
+ expect(toOriginUrl('https://another.com:4000')).toEqual(`${origin}/`);
+ expect(toOriginUrl('https://another.com:4000/')).toEqual(`${origin}/`);
+ expect(toOriginUrl('https://another.com:4000/org/repo.git')).toEqual(`${origin}/org/repo.git`);
+ }
+ window.location.assign(oldLocation);
+});
diff --git a/web_src/js/utils/url.ts b/web_src/js/utils/url.ts
index c5a28774a9d42..a7d61c5e837b7 100644
--- a/web_src/js/utils/url.ts
+++ b/web_src/js/utils/url.ts
@@ -13,3 +13,19 @@ export function isUrl(url: string): boolean {
return false;
}
}
+
+// Convert an absolute or relative URL to an absolute URL with the current origin. It only
+// processes absolute HTTP/HTTPS URLs or relative URLs like '/xxx' or '//host/xxx'.
+export function toOriginUrl(urlStr: string) {
+ try {
+ if (urlStr.startsWith('http://') || urlStr.startsWith('https://') || urlStr.startsWith('/')) {
+ const {origin, protocol, hostname, port} = window.location;
+ const url = new URL(urlStr, origin);
+ url.protocol = protocol;
+ url.hostname = hostname;
+ url.port = port || (protocol === 'https:' ? '443' : '80');
+ return url.toString();
+ }
+ } catch {}
+ return urlStr;
+}
diff --git a/web_src/js/webcomponents/origin-url.test.ts b/web_src/js/webcomponents/origin-url.test.ts
deleted file mode 100644
index 19cc467d7dfc7..0000000000000
--- a/web_src/js/webcomponents/origin-url.test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import {toOriginUrl} from './origin-url.ts';
-
-test('toOriginUrl', () => {
- const oldLocation = String(window.location);
- for (const origin of ['https://example.com', 'https://example.com:3000']) {
- window.location.assign(`${origin}/`);
- expect(toOriginUrl('/')).toEqual(`${origin}/`);
- expect(toOriginUrl('/org/repo.git')).toEqual(`${origin}/org/repo.git`);
- expect(toOriginUrl('https://another.com')).toEqual(`${origin}/`);
- expect(toOriginUrl('https://another.com/')).toEqual(`${origin}/`);
- expect(toOriginUrl('https://another.com/org/repo.git')).toEqual(`${origin}/org/repo.git`);
- expect(toOriginUrl('https://another.com:4000')).toEqual(`${origin}/`);
- expect(toOriginUrl('https://another.com:4000/')).toEqual(`${origin}/`);
- expect(toOriginUrl('https://another.com:4000/org/repo.git')).toEqual(`${origin}/org/repo.git`);
- }
- window.location.assign(oldLocation);
-});
diff --git a/web_src/js/webcomponents/origin-url.ts b/web_src/js/webcomponents/origin-url.ts
index d407fe0dff7d1..dbb910ce6c694 100644
--- a/web_src/js/webcomponents/origin-url.ts
+++ b/web_src/js/webcomponents/origin-url.ts
@@ -1,19 +1,4 @@
-// Convert an absolute or relative URL to an absolute URL with the current origin. It only
-// processes absolute HTTP/HTTPS URLs or relative URLs like '/xxx' or '//host/xxx'.
-// NOTE: Keep this function in sync with clone_script.tmpl
-export function toOriginUrl(urlStr: string) {
- try {
- if (urlStr.startsWith('http://') || urlStr.startsWith('https://') || urlStr.startsWith('/')) {
- const {origin, protocol, hostname, port} = window.location;
- const url = new URL(urlStr, origin);
- url.protocol = protocol;
- url.hostname = hostname;
- url.port = port || (protocol === 'https:' ? '443' : '80');
- return url.toString();
- }
- } catch {}
- return urlStr;
-}
+import {toOriginUrl} from '../utils/url.ts';
window.customElements.define('origin-url', class extends HTMLElement {
connectedCallback() {