This repository has no description
1{{ define "title" }}{{ .Path }} at {{ .Ref }} · {{ .RepoInfo.FullName }} · Tangled{{ end }}
2
3{{ define "extrameta" }}
4 {{ template "repo/fragments/meta" . }}
5
6 {{ $title := printf "%s at %s · %s" .Path .Ref .RepoInfo.FullName }}
7 {{ $url := printf "https://tangled.org/%s/blob/%s/%s" .RepoInfo.FullName .Ref .Path }}
8
9 {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo "Title" $title "Url" $url) }}
10
11{{ end }}
12
13{{ define "repoContent" }}
14 {{ $linkstyle := "no-underline hover:underline" }}
15 <div class="peer mb-3 text-sm flex justify-between gap-2 items-center">
16 <div class="flex gap-3 items-center">
17 <div class="bg-gray-100 dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded p-2 flex items-center gap-1 overflow-x-auto whitespace-nowrap w-fit">
18 {{ $last := sub (len .BreadCrumbs) 1 }}
19 {{ range $i, $b := .BreadCrumbs }}
20 {{ if eq $i $last }}
21 <span class="text-black dark:text-white">{{ pathUnescape (index $b 0) }}</span>
22 {{ else }}
23 <a href="{{ index $b 1 }}" class="text-gray-500 dark:text-gray-400 {{ $linkstyle }}">{{ pathUnescape (index $b 0) }}</a>
24 <span class="text-gray-500 dark:text-gray-400">/</span>
25 {{ end }}
26 {{ end }}
27 </div>
28 <div class="text-gray-500 dark:text-gray-400 flex items-center gap-2">
29 {{ if .BlobView.SizeHint }}
30 <span>{{ byteFmt .BlobView.SizeHint }}</span>
31 {{ end }}
32 {{ if (and .BlobView.ContentType.HasTextView (or (not .BlobView.ContentType.HasRenderedView) (not .ShowRendered))) }}
33 <span class="select-none [&:before]:content-['·']"></span>
34 <span>{{ .BlobView.Lines }} lines</span>
35 {{ end }}
36 </div>
37 </div>
38 <div class="hidden md:flex items-center gap-2 whitespace-nowrap text-sm">
39 {{ if (and .BlobView.ContentType.HasTextView (or (not .BlobView.ContentType.HasRenderedView) (not .ShowRendered))) }}
40 <div id="toggle-wrap-content" class="px-2">
41 <label class="flex items-center font-normal gap-2">
42 <input id="toggle-wrap-content-checkbox" type="checkbox" name="Wrap"/>
43 Wrap
44 </label>
45 </div>
46 {{ end }}
47 <div class="bg-gray-100 dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded p-2 flex items-center gap-2 justify-center">
48 <span class="text-gray-500 dark:text-gray-400">at</span>
49 <a href="/{{ .RepoInfo.FullName }}/tree/{{ pathEscape .Ref }}" class="{{ $linkstyle }}">{{ .Ref }}</a>
50 </div>
51 {{ if .Language }}
52 <div class="bg-gray-100 dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded p-2 flex items-center gap-2">
53 {{ template "repo/fragments/colorBall" (dict "color" (langColor .Language)) }}
54 {{ .Language }}
55 </div>
56 {{ end }}
57 <div class="btn-group">
58 {{ if (and .BlobView.ContentType.HasTextView .BlobView.ContentType.HasRenderedView) }}
59 <a href="/{{ .RepoInfo.FullName }}/blob/{{ pathEscape .Ref }}/{{ .Path }}?code={{ .ShowRendered }}" hx-boost="true" class="btn-group-item px-3 no-underline hover:no-underline">
60 View {{ if .ShowRendered }}code{{ else }}rendered{{ end }}
61 </a>
62 {{ end }}
63 {{ if .BlobView.ContentType.HasRawView }}
64 {{ $rawUrl := printf "/%s/raw/%s/%s" .RepoInfo.FullName (pathEscape .Ref) .Path }}
65 {{ $filename := pathUnescape (index (index .BreadCrumbs (sub (len .BreadCrumbs) 1)) 0) }}
66 <a href="{{ $rawUrl }}" class="btn-group-item px-3 no-underline hover:no-underline">View raw</a>
67 {{ if .BlobView.ContentType.HasTextView }}
68 <button
69 class="btn-group-item px-3"
70 title="Copy contents"
71 onclick="const btn=this,c=document.querySelector('#blob-contents');if(c){const cls=c.querySelectorAll('.cl');const text=cls.length>0?Array.from(cls).map(e=>e.textContent).join(''):c.textContent;navigator.clipboard.writeText(text);const h=btn.innerHTML;btn.innerHTML=`{{ i "copy-check" "size-4" }}`;setTimeout(()=>btn.innerHTML=h,1500)}">
72 {{ i "copy" "size-4" }}
73 </button>
74 {{ end }}
75 <a href="{{ $rawUrl }}?download=1" class="btn-group-item px-3 no-underline hover:no-underline" title="Download">
76 {{ i "download" "size-4" }}
77 </a>
78 {{ end }}
79 </div>
80 </div>
81 </div>
82
83 {{ if .LastCommitInfo }}
84 {{ template "repo/fragments/lastCommitPanel" $ }}
85 {{ end }}
86
87 {{ $wrapContentClasses := "peer-has-[:checked]:*:whitespace-pre-wrap peer-has-[:checked]:*:[overflow-wrap:anywhere]" }}
88
89 {{ if .BlobView.ContentType.IsSubmodule }}
90 <p class="text-center text-gray-400 dark:text-gray-500">
91 This directory is a git submodule of <a href="{{ .BlobView.ContentSrc }}">{{ .BlobView.ContentSrc }}</a>.
92 </p>
93 {{ else if .BlobView.ContentType.IsImage }}
94 <div class="text-center">
95 <img src="{{ .BlobView.ContentSrc }}"
96 alt="{{ .Path }}"
97 class="max-w-full h-auto mx-auto border border-gray-200 dark:border-gray-700 rounded" />
98 </div>
99 {{ else if .BlobView.ContentType.IsVideo }}
100 <div class="text-center">
101 <video controls class="max-w-full h-auto mx-auto border border-gray-200 dark:border-gray-700 rounded">
102 <source src="{{ .BlobView.ContentSrc }}">
103 Your browser does not support the video tag.
104 </video>
105 </div>
106 {{ else if .BlobView.ContentType.IsSvg }}
107 <div class="overflow-auto relative {{ $wrapContentClasses }}">
108 {{ if .ShowRendered }}
109 <div class="text-center">
110 <img src="{{ .BlobView.ContentSrc }}"
111 alt="{{ .Path }}"
112 class="max-w-full h-auto mx-auto border border-gray-200 dark:border-gray-700 rounded" />
113 </div>
114 {{ else }}
115 <div id="blob-contents" class="whitespace-pre peer-target:bg-yellow-200 dark:peer-target:bg-yellow-900">{{ code .BlobView.Contents .Path | escapeHtml }}</div>
116 {{ end }}
117 </div>
118 {{ else if .BlobView.FileTooLarge }}
119 <p class="text-center text-gray-400 dark:text-gray-500">
120 This file is too large to render. <a href="/{{ .RepoInfo.FullName }}/raw/{{ pathEscape .Ref }}/{{ .Path }}">View raw.</a>.
121 </p>
122 {{ else if .BlobView.ContentType.IsMarkup }}
123 <div class="overflow-auto relative {{ $wrapContentClasses }}">
124 {{ if .ShowRendered }}
125 <div id="blob-contents" class="prose dark:prose-invert">{{ .BlobView.Contents | readme }}</div>
126 {{ else }}
127 <div id="blob-contents" class="whitespace-pre peer-target:bg-yellow-200 dark:peer-target:bg-yellow-900">{{ code .BlobView.Contents .Path | escapeHtml }}</div>
128 {{ end }}
129 </div>
130 {{ else if .BlobView.ContentType.IsCode }}
131 <div class="overflow-auto relative {{ $wrapContentClasses }}">
132 <div id="blob-contents" class="whitespace-pre peer-target:bg-yellow-200 dark:peer-target:bg-yellow-900">{{ code .BlobView.Contents .Path | escapeHtml }}</div>
133 </div>
134 {{ else }}
135 <p class="text-center text-gray-400 dark:text-gray-500">
136 Previews are not supported for this file type.
137 </p>
138 {{ end }}
139 {{ template "fragments/multiline-select" }}
140 <script>
141 (() => {
142 const abortController = new AbortController();
143 const toggle = document.querySelector('#toggle-wrap-content');
144 const toggleCheckbox = document.querySelector('#toggle-wrap-content-checkbox');
145 const contents = document.querySelector('#blob-contents');
146
147 function showWrapContentToggleOnOverflow() {
148 if(!toggle || !toggleCheckbox || !contents) return;
149
150 const isScrollable = contents.scrollWidth > contents.clientWidth;
151 const showToggle = isScrollable || toggleCheckbox.checked;
152
153 if(showToggle) {
154 toggle.classList.remove('hidden');
155 } else {
156 toggle.classList.add('hidden');
157 }
158 }
159
160 window.addEventListener('resize', () => showWrapContentToggleOnOverflow(), {signal: abortController.signal});
161 document.body.addEventListener('htmx:afterSettle', () => showWrapContentToggleOnOverflow(), {signal: abortController.signal});
162 document.body.addEventListener('htmx:beforeCleanupElement', (e) => {
163 if(e.target === toggle) {
164 abortController.abort();
165 }
166 }, {signal: abortController.signal});
167
168 showWrapContentToggleOnOverflow();
169 })();
170 </script>
171 {{ if .LastCommitInfo }}
172 {{ template "repo/fragments/permalinkShortcutScript" (printf "/%s/blob/%s/%s" .RepoInfo.RepoIdentifier .LastCommitInfo.Hash .Path) }}
173 {{ end }}
174{{ end }}