policy.go RawHistoryFolder

1package download
2
3import (
4	"mime"
5	"net/url"
6	"path"
7	"strings"
8)
9
10var forcedDownloadExtensions = map[string]struct{}{
11	".7z":       {},
12	".apk":      {},
13	".appimage": {},
14	".bz2":      {},
15	".deb":      {},
16	".dmg":      {},
17	".exe":      {},
18	".gz":       {},
19	".img":      {},
20	".iso":      {},
21	".msi":      {},
22	".pdf":      {},
23	".pkg":      {},
24	".rar":      {},
25	".rpm":      {},
26	".tar":      {},
27	".tgz":      {},
28	".xz":       {},
29	".zip":      {},
30}
31
32var forcedDownloadMIMETypes = map[string]struct{}{
33	"application/pdf":               {},
34	"application/x-apple-diskimage": {},
35	"application/x-cd-image":        {},
36	"application/x-iso9660-image":   {},
37}
38
39// ShouldForceDownload returns true when the resource should be downloaded
40// instead of navigated/rendered inline.
41func ShouldForceDownload(uri, mimeType string) bool {
42	return ShouldForceDownloadForMIMEType(mimeType) || ShouldForceDownloadForURI(uri)
43}
44
45// ShouldForceDownloadForURI returns true when the URI path has a known
46// download-only extension.
47func ShouldForceDownloadForURI(uri string) bool {
48	ext := strings.ToLower(path.Ext(uriPath(uri)))
49	if ext == "" {
50		return false
51	}
52	_, ok := forcedDownloadExtensions[ext]
53	return ok
54}
55
56// ShouldForceDownloadForMIMEType returns true when the MIME type maps to a
57// known download-only artifact.
58func ShouldForceDownloadForMIMEType(mimeType string) bool {
59	if mimeType == "" {
60		return false
61	}
62
63	mediaType := strings.ToLower(strings.TrimSpace(mimeType))
64	if parsed, _, err := mime.ParseMediaType(mediaType); err == nil {
65		mediaType = parsed
66	}
67
68	_, ok := forcedDownloadMIMETypes[mediaType]
69	return ok
70}
71
72func uriPath(raw string) string {
73	if raw == "" {
74		return ""
75	}
76
77	parsed, err := url.Parse(raw)
78	if err == nil && parsed.Path != "" {
79		return parsed.Path
80	}
81
82	if cut := strings.IndexAny(raw, "?#"); cut >= 0 {
83		return raw[:cut]
84	}
85
86	return raw
87}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close