diff --git a/routers/web/repo/view_file.go b/routers/web/repo/view_file.go
index d505ce982b..75ea42d333 100644
--- a/routers/web/repo/view_file.go
+++ b/routers/web/repo/view_file.go
@@ -93,7 +93,7 @@ func handleFileViewRenderMarkup(ctx *context.Context, filename string, sniffedTy
return true
}
- ctx.Data["FileTocHTML"] = renderSidebarTocHTML(rctx)
+ ctx.Data["FileSidebarHTML"] = renderSidebarTocHTML(rctx)
return true
}
diff --git a/routers/web/repo/view_readme.go b/routers/web/repo/view_readme.go
index 8999339bab..3cc35c35ec 100644
--- a/routers/web/repo/view_readme.go
+++ b/routers/web/repo/view_readme.go
@@ -207,7 +207,7 @@ func prepareToRenderReadmeFile(ctx *context.Context, subfolder string, readmeFil
delete(ctx.Data, "IsMarkup")
}
- ctx.Data["ReadmeTocHTML"] = renderSidebarTocHTML(rctx)
+ ctx.Data["FileSidebarHTML"] = renderSidebarTocHTML(rctx)
}
if ctx.Data["IsMarkup"] != true {
diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl
index f638e73f15..7010e9d690 100644
--- a/templates/repo/view_file.tmpl
+++ b/templates/repo/view_file.tmpl
@@ -35,11 +35,13 @@
{{end}}
- {{if or .ReadmeTocHTML .FileTocHTML}}
-
- {{or .ReadmeTocHTML .FileTocHTML}}
+ {{if .FileSidebarHTML}}
+
{{end}}
diff --git a/web_src/css/repo/home.css b/web_src/css/repo/home.css
index 110f8f7389..f686171375 100644
--- a/web_src/css/repo/home.css
+++ b/web_src/css/repo/home.css
@@ -79,8 +79,8 @@
transition: margin-right 0.2s ease;
}
-/* When TOC is visible, reserve space on the right (only for file view, not home page) */
-.repo-view-content.toc-visible {
+/* When sidebar is visible, reserve space on the right (only for file view, not home page) */
+.repo-view-content.sidebar-visible {
margin-right: 270px;
}
@@ -112,8 +112,8 @@
text-decoration: none;
}
-/* TOC as a fixed sidebar panel */
-.file-view-toc {
+/* File view sidebar panel (e.g., TOC for markdown files) */
+.file-view-sidebar {
position: fixed;
top: 120px; /* Will be adjusted by JS to align with file content */
right: 0.5rem;
@@ -129,21 +129,21 @@
transition: opacity 0.15s ease;
}
-/* Show TOC after JS has positioned it */
-.file-view-toc.toc-positioned {
+/* Show sidebar after JS has positioned it */
+.file-view-sidebar.sidebar-positioned {
opacity: 1;
}
/* Hidden state - using custom class to avoid Tailwind conflicts */
-.file-view-toc.toc-panel-hidden {
+.file-view-sidebar.sidebar-panel-hidden {
display: none;
}
-.file-view-toc details {
+.file-view-sidebar details {
font-size: 13px;
}
-.file-view-toc summary {
+.file-view-sidebar summary {
font-weight: var(--font-weight-semibold);
cursor: pointer;
padding: 8px 0;
@@ -152,17 +152,17 @@
margin-bottom: 8px;
}
-.file-view-toc ul {
+.file-view-sidebar ul {
margin: 0;
list-style: none;
padding: 5px 0 5px 1em;
}
-.file-view-toc ul ul {
+.file-view-sidebar ul ul {
border-left: 1px dashed var(--color-secondary);
}
-.file-view-toc a {
+.file-view-sidebar a {
display: block;
padding: 6px 10px;
color: var(--color-text);
@@ -172,28 +172,28 @@
border-radius: var(--border-radius);
}
-.file-view-toc a:hover {
+.file-view-sidebar a:hover {
color: var(--color-primary);
background: var(--color-hover);
}
-/* TOC toggle button active state - when TOC is visible */
-#toggle-toc-btn.active {
+/* Sidebar toggle button active state - when sidebar is visible */
+#toggle-sidebar-btn.active {
color: var(--color-primary);
}
-/* Hide TOC sidebar on small screens */
+/* Hide sidebar on small screens */
@media (max-width: 1400px) {
- .file-view-toc {
+ .file-view-sidebar {
display: none !important;
}
- #toggle-toc-btn {
+ #toggle-sidebar-btn {
display: none;
}
- /* Don't reserve space for TOC on small screens */
- .repo-view-content.toc-visible {
+ /* Don't reserve space for sidebar on small screens */
+ .repo-view-content.sidebar-visible {
margin-right: 0;
}
}
diff --git a/web_src/js/features/file-view.ts b/web_src/js/features/file-view.ts
index 430a6d5ef8..caa4a036db 100644
--- a/web_src/js/features/file-view.ts
+++ b/web_src/js/features/file-view.ts
@@ -59,32 +59,32 @@ async function renderRawFileToContainer(container: HTMLElement, rawFileLink: str
}
}
-function updateTocPosition(elFileView: HTMLElement, tocSidebar: HTMLElement): void {
+function updateSidebarPosition(elFileView: HTMLElement, sidebar: HTMLElement): void {
const fileHeader = elFileView.querySelector('.file-header');
if (!fileHeader) return;
const headerRect = fileHeader.getBoundingClientRect();
- // Align TOC top with the file header top, with a minimum of 12px from viewport top
+ // Align sidebar top with the file header top, with a minimum of 12px from viewport top
const topPos = Math.max(12, headerRect.top);
- tocSidebar.style.top = `${topPos}px`;
+ sidebar.style.top = `${topPos}px`;
- // Position TOC right next to the content (works for both file view and home page)
+ // Position sidebar right next to the content (works for both file view and home page)
const segment = elFileView.querySelector('.ui.segment');
if (segment) {
const segmentRect = segment.getBoundingClientRect();
const leftPos = segmentRect.right + 8; // 8px gap from content
- tocSidebar.style.left = `${leftPos}px`;
- tocSidebar.style.right = 'auto';
+ sidebar.style.left = `${leftPos}px`;
+ sidebar.style.right = 'auto';
}
- // Mark as positioned to show the TOC (prevents flicker)
- tocSidebar.classList.add('toc-positioned');
+ // Mark as positioned to show the sidebar (prevents flicker)
+ sidebar.classList.add('sidebar-positioned');
}
-function initTocToggle(elFileView: HTMLElement): void {
- const toggleBtn = elFileView.querySelector('#toggle-toc-btn');
- const tocSidebar = elFileView.querySelector('.file-view-toc');
- if (!toggleBtn || !tocSidebar) return;
+function initSidebarToggle(elFileView: HTMLElement): void {
+ const toggleBtn = elFileView.querySelector('#toggle-sidebar-btn');
+ const sidebar = elFileView.querySelector('.file-view-sidebar');
+ if (!toggleBtn || !sidebar) return;
// Check if we're in file view (not home page) - only file view needs margin adjustment
const repoViewContent = elFileView.closest('.repo-view-content');
@@ -92,26 +92,26 @@ function initTocToggle(elFileView: HTMLElement): void {
// Helper to update position
const updatePosition = () => {
- if (!tocSidebar.classList.contains('toc-panel-hidden')) {
- updateTocPosition(elFileView, tocSidebar);
+ if (!sidebar.classList.contains('sidebar-panel-hidden')) {
+ updateSidebarPosition(elFileView, sidebar);
}
};
- // Helper to show TOC with proper positioning
- const showToc = () => {
+ // Helper to show sidebar with proper positioning
+ const showSidebar = () => {
toggleBtn.classList.add('active');
- // Wait for margin to take effect before showing and positioning TOC
+ // Wait for margin to take effect before showing and positioning sidebar
const showAfterLayout = () => {
- tocSidebar.classList.remove('toc-panel-hidden');
+ sidebar.classList.remove('sidebar-panel-hidden');
requestAnimationFrame(() => {
- updateTocPosition(elFileView, tocSidebar);
+ updateSidebarPosition(elFileView, sidebar);
});
};
- // For file view, first add margin, wait for layout, then show TOC
- if (isFileView) {
- repoViewContent.classList.add('toc-visible');
+ // For file view, first add margin, wait for layout, then show sidebar
+ if (isFileView && repoViewContent) {
+ repoViewContent.classList.add('sidebar-visible');
// Wait for CSS transition to complete (200ms) before calculating position
setTimeout(showAfterLayout, 220);
} else {
@@ -120,28 +120,28 @@ function initTocToggle(elFileView: HTMLElement): void {
}
};
- // Helper to hide TOC
- const hideToc = () => {
- tocSidebar.classList.add('toc-panel-hidden');
- tocSidebar.classList.remove('toc-positioned');
+ // Helper to hide sidebar
+ const hideSidebar = () => {
+ sidebar.classList.add('sidebar-panel-hidden');
+ sidebar.classList.remove('sidebar-positioned');
toggleBtn.classList.remove('active');
- if (isFileView) {
- repoViewContent.classList.remove('toc-visible');
+ if (isFileView && repoViewContent) {
+ repoViewContent.classList.remove('sidebar-visible');
}
};
// Restore saved state from localStorage (default to hidden)
- const savedState = localStorage.getItem('file-view-toc-visible');
+ const savedState = localStorage.getItem('file-view-sidebar-visible');
const isVisible = savedState === 'true'; // default to hidden
// Apply initial state
if (isVisible) {
- showToc();
+ showSidebar();
} else {
- hideToc();
+ hideSidebar();
}
- // Update TOC position on resize/scroll to keep aligned with file content
+ // Update sidebar position on resize/scroll to keep aligned with file content
const resizeObserver = new ResizeObserver(() => {
updatePosition();
});
@@ -160,13 +160,13 @@ function initTocToggle(elFileView: HTMLElement): void {
}
toggleBtn.addEventListener('click', () => {
- const isCurrentlyVisible = !tocSidebar.classList.contains('toc-panel-hidden');
+ const isCurrentlyVisible = !sidebar.classList.contains('sidebar-panel-hidden');
if (isCurrentlyVisible) {
- hideToc();
- localStorage.setItem('file-view-toc-visible', 'false');
+ hideSidebar();
+ localStorage.setItem('file-view-sidebar-visible', 'false');
} else {
- showToc();
- localStorage.setItem('file-view-toc-visible', 'true');
+ showSidebar();
+ localStorage.setItem('file-view-sidebar-visible', 'true');
}
});
}
@@ -175,8 +175,8 @@ export function initRepoFileView(): void {
registerGlobalInitFunc('initRepoFileView', async (elFileView: HTMLElement) => {
initPluginsOnce();
- // Initialize TOC toggle functionality
- initTocToggle(elFileView);
+ // Initialize sidebar toggle functionality (e.g., TOC for markdown files)
+ initSidebarToggle(elFileView);
const rawFileLink = elFileView.getAttribute('data-raw-file-link')!;
const mimeType = elFileView.getAttribute('data-mime-type') || ''; // not used yet