mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Improve wiki sidebar and TOC (#25460)
Close #20976 Close #20975 1. Fix the bug: the TOC in footer was incorrectly rendered as main content's TOC 2. Fix the layout: on mobile, the TOC is put above the main content, while the sidebar is put below the main content 3. Auto collapse the TOC on mobile ps: many styles of "wiki.css" are moved from old css files, so leave nits to following PRs.
This commit is contained in:
		| @@ -273,6 +273,16 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { | ||||
| 		return nil, nil | ||||
| 	} | ||||
|  | ||||
| 	if rctx.SidebarTocNode != nil { | ||||
| 		sb := &strings.Builder{} | ||||
| 		err = markdown.SpecializedMarkdown().Renderer().Render(sb, nil, rctx.SidebarTocNode) | ||||
| 		if err != nil { | ||||
| 			log.Error("Failed to render wiki sidebar TOC: %v", err) | ||||
| 		} else { | ||||
| 			ctx.Data["sidebarTocContent"] = sb.String() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if !isSideBar { | ||||
| 		buf.Reset() | ||||
| 		ctx.Data["sidebarEscapeStatus"], ctx.Data["sidebarContent"], err = renderFn(sidebarContent) | ||||
| @@ -303,16 +313,6 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { | ||||
| 		ctx.Data["footerPresent"] = false | ||||
| 	} | ||||
|  | ||||
| 	if rctx.SidebarTocNode != nil { | ||||
| 		sb := &strings.Builder{} | ||||
| 		err = markdown.SpecializedMarkdown().Renderer().Render(sb, nil, rctx.SidebarTocNode) | ||||
| 		if err != nil { | ||||
| 			log.Error("Failed to render wiki sidebar TOC: %v", err) | ||||
| 		} else { | ||||
| 			ctx.Data["sidebarTocContent"] = sb.String() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// get commit count - wiki revisions | ||||
| 	commitsCount, _ := wikiRepo.FileCommitsCount(wiki_service.DefaultBranch, pageFilename) | ||||
| 	ctx.Data["CommitCount"] = commitsCount | ||||
|   | ||||
| @@ -4,13 +4,8 @@ | ||||
| 	{{$title := .title}} | ||||
| 	<div class="ui container"> | ||||
| 		<div class="ui stackable grid"> | ||||
| 			<div class="ui eight wide column text right gt-df gt-ac gt-je"> | ||||
| 				<div class="ui action small input" id="clone-panel"> | ||||
| 					{{template "repo/clone_buttons" .}} | ||||
| 					{{template "repo/clone_script" .}} | ||||
| 				</div> | ||||
| 			</div> | ||||
| 			<div class="ui header eight wide column"> | ||||
| 			<div class="ui eight wide column"> | ||||
| 				<div class="ui header"> | ||||
| 					<a class="file-revisions-btn ui basic button" title="{{.locale.Tr "repo.wiki.back_to_wiki"}}" href="{{.RepoLink}}/wiki/{{.PageURL}}"><span>{{.revision}}</span> {{svg "octicon-home"}}</a> | ||||
| 					{{$title}} | ||||
| 					<div class="ui sub header gt-word-break"> | ||||
| @@ -19,6 +14,13 @@ | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 			<div class="ui eight wide column text right"> | ||||
| 				<div class="ui action small input" id="clone-panel"> | ||||
| 					{{template "repo/clone_buttons" .}} | ||||
| 					{{template "repo/clone_script" .}} | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 		<h2 class="ui top header">{{.locale.Tr "repo.wiki.wiki_page_revisions"}}</h2> | ||||
| 		<div class="gt-mt-4"> | ||||
| 			<h4 class="ui top attached header"> | ||||
|   | ||||
| @@ -2,8 +2,8 @@ | ||||
| <div role="main" aria-label="{{.Title}}" class="page-content repository wiki start"> | ||||
| 	{{template "repo/header" .}} | ||||
| 	<div class="ui container"> | ||||
| 		<div class="ui center segment"> | ||||
| 			{{svg "octicon-book" 32}} | ||||
| 		<div class="ui center segment gt-py-5"> | ||||
| 			{{svg "octicon-book" 48}} | ||||
| 			<h2>{{.locale.Tr "repo.wiki.welcome"}}</h2> | ||||
| 			<p>{{.locale.Tr "repo.wiki.welcome_desc"}}</p> | ||||
| 			{{if and .CanWriteWiki (not .Repository.IsMirror)}} | ||||
|   | ||||
| @@ -63,20 +63,21 @@ | ||||
| 				<p>{{.FormatWarning}}</p> | ||||
| 			</div> | ||||
| 		{{end}} | ||||
| 		<div class="ui gt-mt-0 {{if or .sidebarPresent .sidebarTocContent}}grid equal width{{end}}"> | ||||
| 			<div class="ui {{if or .sidebarPresent .sidebarTocContent}}eleven wide column{{else}}gt-ml-0{{end}} segment markup wiki-content-main"> | ||||
| 				{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}} | ||||
| 				{{.content | Safe}} | ||||
| 			</div> | ||||
| 			{{if or .sidebarPresent .sidebarTocContent}} | ||||
| 			<div class="column gt-pt-0"> | ||||
|  | ||||
| 		<div class="wiki-content-parts"> | ||||
| 			{{if .sidebarTocContent}} | ||||
| 					<div class="ui segment wiki-content-toc"> | ||||
| 			<div class="markup wiki-content-sidebar wiki-content-toc"> | ||||
| 				{{.sidebarTocContent | Safe}} | ||||
| 			</div> | ||||
| 			{{end}} | ||||
|  | ||||
| 			<div class="markup wiki-content-main {{if or .sidebarTocContent .sidebarPresent}}with-sidebar{{end}}"> | ||||
| 				{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}} | ||||
| 				{{.content | Safe}} | ||||
| 			</div> | ||||
|  | ||||
| 			{{if .sidebarPresent}} | ||||
| 					<div class="ui segment wiki-content-sidebar"> | ||||
| 			<div class="markup wiki-content-sidebar"> | ||||
| 				{{if and .CanWriteWiki (not .Repository.IsMirror)}} | ||||
| 					<a class="ui right floated muted" href="{{.RepoLink}}/wiki/_Sidebar?action=_edit" aria-label="{{.locale.Tr "repo.wiki.edit_page_button"}}">{{svg "octicon-pencil"}}</a> | ||||
| 				{{end}} | ||||
| @@ -84,11 +85,11 @@ | ||||
| 				{{.sidebarContent | Safe}} | ||||
| 			</div> | ||||
| 			{{end}} | ||||
| 			</div> | ||||
| 			{{end}} | ||||
| 		</div> | ||||
|  | ||||
| 			<div class="gt-clear-both"></div> | ||||
|  | ||||
| 			{{if .footerPresent}} | ||||
| 		<div class="ui segment wiki-content-footer"> | ||||
| 			<div class="markup wiki-content-footer"> | ||||
| 				{{if and .CanWriteWiki (not .Repository.IsMirror)}} | ||||
| 					<a class="ui right floated muted" href="{{.RepoLink}}/wiki/_Footer?action=_edit" aria-label="{{.locale.Tr "repo.wiki.edit_page_button"}}">{{svg "octicon-pencil"}}</a> | ||||
| 				{{end}} | ||||
| @@ -98,6 +99,7 @@ | ||||
| 			{{end}} | ||||
| 		</div> | ||||
| 	</div> | ||||
| </div> | ||||
|  | ||||
| <div class="ui g-modal-confirm delete modal"> | ||||
| 	<div class="header"> | ||||
|   | ||||
| @@ -85,6 +85,7 @@ Gitea's private styles use `g-` prefix. | ||||
|  | ||||
| .gt-float-left { float: left !important; } | ||||
| .gt-float-right { float: right !important; } | ||||
| .gt-clear-both { clear: both !important; } | ||||
|  | ||||
| .gt-font-light { font-weight: var(--font-weight-light) !important; } | ||||
| .gt-font-normal { font-weight: var(--font-weight-normal) !important; } | ||||
|   | ||||
| @@ -45,6 +45,7 @@ | ||||
| @import "./repo/issue-list.css"; | ||||
| @import "./repo/list-header.css"; | ||||
| @import "./repo/linebutton.css"; | ||||
| @import "./repo/wiki.css"; | ||||
|  | ||||
| @import "./editor/fileeditor.css"; | ||||
| @import "./editor/combomarkdowneditor.css"; | ||||
|   | ||||
| @@ -514,20 +514,6 @@ | ||||
|   padding-left: 2em; | ||||
| } | ||||
|  | ||||
| .repository.wiki.revisions .ui.container > .ui.stackable.grid { | ||||
|   -ms-flex-direction: row-reverse; | ||||
|   flex-direction: row-reverse; | ||||
| } | ||||
|  | ||||
| .repository.wiki.revisions .ui.container > .ui.stackable.grid > .header { | ||||
|   margin-top: 0; | ||||
| } | ||||
|  | ||||
| .repository.wiki.revisions .ui.container > .ui.stackable.grid > .header .sub.header { | ||||
|   padding-left: 52px; | ||||
|   word-break: break-word; | ||||
| } | ||||
|  | ||||
| .file-revisions-btn { | ||||
|   display: block; | ||||
|   float: left; | ||||
|   | ||||
| @@ -1887,50 +1887,9 @@ | ||||
|   white-space: nowrap; | ||||
| } | ||||
|  | ||||
| .repository.wiki.start .ui.segment { | ||||
|   padding-top: 70px; | ||||
|   padding-bottom: 100px; | ||||
| } | ||||
|  | ||||
| .repository.wiki.start .ui.segment .svg { | ||||
|   height: 48px; | ||||
| } | ||||
|  | ||||
| .repository.wiki.new .ui.attached.tabular.menu.previewtabs { | ||||
|   margin-bottom: 15px; | ||||
| } | ||||
|  | ||||
| .file-view.markup { | ||||
|   padding: 1em 2em; | ||||
| } | ||||
|  | ||||
| .wiki-content-main { | ||||
|   padding: 1em 2em !important; | ||||
|   margin-left: 1em !important; | ||||
| } | ||||
|  | ||||
| .wiki-pages-list .wiki-git-entry { | ||||
|   margin-left: 10px; | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| .wiki-pages-list td:hover .wiki-git-entry { | ||||
|   display: inline-block; | ||||
| } | ||||
|  | ||||
| @media (max-width: 767.98px) { | ||||
|   .repository.wiki .dividing.header .stackable.grid .button { | ||||
|     margin-top: 2px; | ||||
|     margin-bottom: 2px; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @media (max-width: 767.98px) { | ||||
|   .repository.wiki #clone-panel #repo-clone-url { | ||||
|     width: 160px; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .repository .activity-header { | ||||
|   display: flex; | ||||
|   justify-content: space-between; | ||||
| @@ -2988,22 +2947,6 @@ tbody.commit-list { | ||||
|   flex-direction: column; | ||||
| } | ||||
|  | ||||
| .wiki-content-sidebar .ui.message.unicode-escape-prompt p, | ||||
| .wiki-content-footer .ui.message.unicode-escape-prompt p { | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| .wiki-content-toc ul { | ||||
|   margin: 0; | ||||
|   list-style: none; | ||||
|   padding: 5px 0 5px 1em; | ||||
| } | ||||
|  | ||||
| .wiki-content-toc ul ul { | ||||
|   border-left:  1px var(--color-secondary); | ||||
|   border-left-style: dashed; | ||||
| } | ||||
|  | ||||
| /* fomantic's last-child selector does not work with hidden last child */ | ||||
| .ui.buttons .unescape-button { | ||||
|   border-top-right-radius: 0.28571429rem; | ||||
|   | ||||
							
								
								
									
										63
									
								
								web_src/css/repo/wiki.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								web_src/css/repo/wiki.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| .repository.wiki .wiki-pages-list .wiki-git-entry { | ||||
|   margin-left: 10px; | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| .repository.wiki .wiki-pages-list td:hover .wiki-git-entry { | ||||
|   display: inline-block; | ||||
| } | ||||
|  | ||||
| .repository.wiki .markup { | ||||
|   overflow: visible; | ||||
| } | ||||
|  | ||||
| .repository.wiki .wiki-content-parts .markup { | ||||
|   border: 1px solid var(--color-secondary); | ||||
|   padding: 1em; | ||||
|   margin-top: 1em; | ||||
|   font-size: 1em; | ||||
| } | ||||
|  | ||||
| .repository.wiki .wiki-content-main.with-sidebar { | ||||
|   float: left; | ||||
|   width: 80%; | ||||
|   max-width: calc(100% - 150px - 1em); /* match the min-width of .wiki-content-sidebar */ | ||||
| } | ||||
|  | ||||
| .repository.wiki .wiki-content-sidebar { | ||||
|   float: right; | ||||
|   width: calc(20% - 1em); | ||||
|   min-width: 150px; | ||||
| } | ||||
|  | ||||
| .repository.wiki .wiki-content-sidebar .ui.message.unicode-escape-prompt p { | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| .repository.wiki .wiki-content-footer { | ||||
|   margin-top: 1em; | ||||
| } | ||||
|  | ||||
| .repository.wiki .wiki-content-toc ul { | ||||
|   margin: 0; | ||||
|   list-style: none; | ||||
|   padding: 5px 0 5px 1em; | ||||
| } | ||||
|  | ||||
| .repository.wiki .wiki-content-toc ul ul { | ||||
|   border-left:  1px var(--color-secondary); | ||||
|   border-left-style: dashed; | ||||
| } | ||||
|  | ||||
| @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; | ||||
|     width: 100%; | ||||
|     min-width: unset; | ||||
|     max-width: unset; | ||||
|   } | ||||
| } | ||||
| @@ -1,6 +1,7 @@ | ||||
| import $ from 'jquery'; | ||||
| import {initMarkupContent} from '../markup/content.js'; | ||||
| import {validateTextareaNonEmpty, initComboMarkdownEditor} from './comp/ComboMarkdownEditor.js'; | ||||
| import {fomanticMobileScreen} from '../modules/fomantic.js'; | ||||
|  | ||||
| const {csrfToken} = window.config; | ||||
|  | ||||
| @@ -70,6 +71,17 @@ async function initRepoWikiFormEditor() { | ||||
|   }); | ||||
| } | ||||
|  | ||||
| function collapseWikiTocForMobile(collapse) { | ||||
|   if (collapse) { | ||||
|     document.querySelector('.wiki-content-toc details')?.removeAttribute('open'); | ||||
|   } | ||||
| } | ||||
|  | ||||
| export function initRepoWikiForm() { | ||||
|   if (!document.querySelector('.page-content.repository.wiki')) return; | ||||
|  | ||||
|   fomanticMobileScreen.addEventListener('change', (e) => collapseWikiTocForMobile(e.matches)); | ||||
|   collapseWikiTocForMobile(fomanticMobileScreen.matches); | ||||
|  | ||||
|   initRepoWikiFormEditor(); | ||||
| } | ||||
|   | ||||
| @@ -3,6 +3,8 @@ import {initAriaCheckboxPatch} from './aria/checkbox.js'; | ||||
| import {initAriaDropdownPatch} from './aria/dropdown.js'; | ||||
| import {svg} from '../svg.js'; | ||||
|  | ||||
| export const fomanticMobileScreen = window.matchMedia('only screen and (max-width: 767.98px)'); | ||||
|  | ||||
| export function initGiteaFomantic() { | ||||
|   // Silence fomantic's error logging when tabs are used without a target content element | ||||
|   $.fn.tab.settings.silent = true; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user