Monorepo for Tangled
tangled.org
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 pb-2 mb-3 text-base border-b border-gray-200 dark:border-gray-700">
16 <div class="flex flex-col md:flex-row md:justify-between gap-2">
17 <div id="breadcrumbs" class="overflow-x-auto whitespace-nowrap text-gray-400 dark:text-gray-500">
18 {{ range $idx, $value := .BreadCrumbs }}
19 {{ if ne $idx (sub (len $.BreadCrumbs) 1) }}
20 <a
21 href="{{ index . 1 }}"
22 class="text-bold text-gray-500 dark:text-gray-400 {{ $linkstyle }}"
23 >{{ pathUnescape (index . 0) }}</a
24 >
25 /
26 {{ else }}
27 <span class="text-bold text-black dark:text-white"
28 >{{ pathUnescape (index . 0) }}</span
29 >
30 {{ end }}
31 {{ end }}
32 </div>
33 <div id="file-info" class="text-gray-500 dark:text-gray-400 text-xs md:text-sm flex flex-wrap items-center gap-1 md:gap-0">
34 <span>at <a href="/{{ .RepoInfo.FullName }}/tree/{{ pathEscape .Ref }}">{{ .Ref }}</a></span>
35
36 {{ if (and .BlobView.ContentType.HasTextView (not .ShowRendered)) }}
37 <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span>
38 <span>{{ .BlobView.Lines }} lines</span>
39 {{ end }}
40
41 {{ if .BlobView.SizeHint }}
42 <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span>
43 <span>{{ byteFmt .BlobView.SizeHint }}</span>
44 {{ end }}
45
46 {{ if .BlobView.ContentType.HasRawView }}
47 <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span>
48 <a href="/{{ .RepoInfo.FullName }}/raw/{{ pathEscape .Ref }}/{{ .Path }}">View raw</a>
49 {{ end }}
50
51 {{ if (and .BlobView.ContentType.HasTextView .BlobView.ContentType.HasRenderedView) }}
52 <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span>
53 <a href="/{{ .RepoInfo.FullName }}/blob/{{ pathEscape .Ref }}/{{ .Path }}?code={{ .ShowRendered }}" hx-boost="true">
54 View {{ if .ShowRendered }}code{{ else }}rendered{{ end }}
55 </a>
56 {{ end }}
57
58 {{ if (and .BlobView.ContentType.HasTextView (not .ShowRendered)) }}
59 <div id="toggle-wrap-content" class="flex items-center">
60 <span class="select-none px-1 md:px-2 [&:before]:content-['·']"></span>
61 <label class="flex items-center lowercase font-normal px-1 py-0 gap-1 text-xs md:text-sm">
62 <input id="toggle-wrap-content-checkbox" type="checkbox" name="wrap"/>
63 wrap content
64 </label>
65 </div>
66 {{ end }}
67 </div>
68 </div>
69 </div>
70
71 {{ if .LastCommitInfo }}
72 {{ template "repo/fragments/lastCommitPanel" $ }}
73 {{ end }}
74
75 {{ $wrapContentClasses := "peer-has-[:checked]:*:whitespace-pre-wrap peer-has-[:checked]:*:[overflow-wrap:anywhere]" }}
76
77 {{ if .BlobView.ContentType.IsSubmodule }}
78 <p class="text-center text-gray-400 dark:text-gray-500">
79 This directory is a git submodule of <a href="{{ .BlobView.ContentSrc }}">{{ .BlobView.ContentSrc }}</a>.
80 </p>
81 {{ else if .BlobView.ContentType.IsImage }}
82 <div class="text-center">
83 <img src="{{ .BlobView.ContentSrc }}"
84 alt="{{ .Path }}"
85 class="max-w-full h-auto mx-auto border border-gray-200 dark:border-gray-700 rounded" />
86 </div>
87 {{ else if .BlobView.ContentType.IsVideo }}
88 <div class="text-center">
89 <video controls class="max-w-full h-auto mx-auto border border-gray-200 dark:border-gray-700 rounded">
90 <source src="{{ .BlobView.ContentSrc }}">
91 Your browser does not support the video tag.
92 </video>
93 </div>
94 {{ else if .BlobView.ContentType.IsSvg }}
95 <div class="overflow-auto relative {{ $wrapContentClasses }}">
96 {{ if .ShowRendered }}
97 <div class="text-center">
98 <img src="{{ .BlobView.ContentSrc }}"
99 alt="{{ .Path }}"
100 class="max-w-full h-auto mx-auto border border-gray-200 dark:border-gray-700 rounded" />
101 </div>
102 {{ else }}
103 <div id="blob-contents" class="whitespace-pre peer-target:bg-yellow-200 dark:peer-target:bg-yellow-900">{{ code .BlobView.Contents .Path | escapeHtml }}</div>
104 {{ end }}
105 </div>
106 {{ else if .BlobView.FileTooLarge }}
107 <p class="text-center text-gray-400 dark:text-gray-500">
108 This file is too large to render. <a href="/{{ .RepoInfo.FullName }}/raw/{{ pathEscape .Ref }}/{{ .Path }}">View raw.</a>.
109 </p>
110 {{ else if .BlobView.ContentType.IsMarkup }}
111 <div class="overflow-auto relative {{ $wrapContentClasses }}">
112 {{ if .ShowRendered }}
113 <div id="blob-contents" class="prose dark:prose-invert">{{ .BlobView.Contents | readme }}</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.ContentType.IsCode }}
119 <div class="overflow-auto relative {{ $wrapContentClasses }}">
120 <div id="blob-contents" class="whitespace-pre peer-target:bg-yellow-200 dark:peer-target:bg-yellow-900">{{ code .BlobView.Contents .Path | escapeHtml }}</div>
121 </div>
122 {{ else }}
123 <p class="text-center text-gray-400 dark:text-gray-500">
124 Previews are not supported for this file type.
125 </p>
126 {{ end }}
127 {{ template "fragments/multiline-select" }}
128 <script>
129 (() => {
130 const abortController = new AbortController();
131 const toggle = document.querySelector('#toggle-wrap-content');
132 const toggleCheckbox = document.querySelector('#toggle-wrap-content-checkbox');
133 const contents = document.querySelector('#blob-contents');
134
135 function showWrapContentToggleOnOverflow() {
136 if(!toggle || !toggleCheckbox || !contents) return;
137
138 const isScrollable = contents.scrollWidth > contents.clientWidth;
139 const showToggle = isScrollable || toggleCheckbox.checked;
140
141 if(showToggle) {
142 toggle.classList.remove('hidden');
143 } else {
144 toggle.classList.add('hidden');
145 }
146 }
147
148 window.addEventListener('resize', () => showWrapContentToggleOnOverflow(), {signal: abortController.signal});
149 document.body.addEventListener('htmx:afterSettle', () => showWrapContentToggleOnOverflow(), {signal: abortController.signal});
150 document.body.addEventListener('htmx:beforeCleanupElement', (e) => {
151 if(e.target === toggle) {
152 abortController.abort();
153 }
154 }, {signal: abortController.signal});
155
156 showWrapContentToggleOnOverflow();
157 })();
158 </script>
159 {{ if .LastCommitInfo }}
160 {{ template "repo/fragments/permalinkShortcutScript" (printf "/%s/tree/%s/%s" .RepoInfo.RepoIdentifier .LastCommitInfo.Hash .Path) }}
161 {{ end }}
162{{ end }}