mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-27 00:23:41 +09:00 
			
		
		
		
	| @@ -4,6 +4,7 @@ | |||||||
| package markup | package markup | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"html/template" | ||||||
| 	"io" | 	"io" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| @@ -92,9 +93,9 @@ func (st *Sanitizer) createDefaultPolicy() *bluemonday.Policy { | |||||||
| 	return policy | 	return policy | ||||||
| } | } | ||||||
|  |  | ||||||
| // Sanitize takes a string that contains a HTML fragment or document and applies policy whitelist. | // Sanitize use default sanitizer policy to sanitize a string | ||||||
| func Sanitize(s string) string { | func Sanitize(s string) template.HTML { | ||||||
| 	return GetDefaultSanitizer().defaultPolicy.Sanitize(s) | 	return template.HTML(GetDefaultSanitizer().defaultPolicy.Sanitize(s)) | ||||||
| } | } | ||||||
|  |  | ||||||
| // SanitizeReader sanitizes a Reader | // SanitizeReader sanitizes a Reader | ||||||
|   | |||||||
| @@ -69,6 +69,6 @@ func TestSanitizer(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for i := 0; i < len(testCases); i += 2 { | 	for i := 0; i < len(testCases); i += 2 { | ||||||
| 		assert.Equal(t, testCases[i+1], Sanitize(testCases[i])) | 		assert.Equal(t, testCases[i+1], string(Sanitize(testCases[i]))) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -176,9 +176,9 @@ func safeHTML(s any) template.HTML { | |||||||
| 	panic(fmt.Sprintf("unexpected type %T", s)) | 	panic(fmt.Sprintf("unexpected type %T", s)) | ||||||
| } | } | ||||||
|  |  | ||||||
| // SanitizeHTML sanitizes the input by pre-defined markdown rules | // SanitizeHTML sanitizes the input by default sanitization rules. | ||||||
| func SanitizeHTML(s string) template.HTML { | func SanitizeHTML(s string) template.HTML { | ||||||
| 	return template.HTML(markup.Sanitize(s)) | 	return markup.Sanitize(s) | ||||||
| } | } | ||||||
|  |  | ||||||
| func htmlEscape(s any) template.HTML { | func htmlEscape(s any) template.HTML { | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ package repo | |||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	gocontext "context" | 	gocontext "context" | ||||||
|  | 	"html/template" | ||||||
| 	"io" | 	"io" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| @@ -61,9 +62,9 @@ func MustEnableWiki(ctx *context.Context) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	unit, err := ctx.Repo.Repository.GetUnit(ctx, unit.TypeExternalWiki) | 	repoUnit, err := ctx.Repo.Repository.GetUnit(ctx, unit.TypeExternalWiki) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		ctx.Redirect(unit.ExternalWikiConfig().ExternalWikiURL) | 		ctx.Redirect(repoUnit.ExternalWikiConfig().ExternalWikiURL) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -95,7 +96,7 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error) | |||||||
| } | } | ||||||
|  |  | ||||||
| func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) { | func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) { | ||||||
| 	wikiGitRepo, errGitRepo := gitrepo.OpenRepository(ctx, ctx.Repo.Repository.WikiStorageRepo()) | 	wikiGitRepo, errGitRepo := gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository.WikiStorageRepo()) | ||||||
| 	if errGitRepo != nil { | 	if errGitRepo != nil { | ||||||
| 		ctx.ServerError("OpenRepository", errGitRepo) | 		ctx.ServerError("OpenRepository", errGitRepo) | ||||||
| 		return nil, nil, errGitRepo | 		return nil, nil, errGitRepo | ||||||
| @@ -178,23 +179,17 @@ func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_ | |||||||
| } | } | ||||||
|  |  | ||||||
| func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { | func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { | ||||||
| 	wikiRepo, commit, err := findWikiRepoCommit(ctx) | 	wikiGitRepo, commit, err := findWikiRepoCommit(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 		if !git.IsErrNotExist(err) { | 		if !git.IsErrNotExist(err) { | ||||||
| 			ctx.ServerError("GetBranchCommit", err) | 			ctx.ServerError("GetBranchCommit", err) | ||||||
| 		} | 		} | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Get page list. | 	// get the wiki pages list. | ||||||
| 	entries, err := commit.ListEntries() | 	entries, err := commit.ListEntries() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 		ctx.ServerError("ListEntries", err) | 		ctx.ServerError("ListEntries", err) | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
| @@ -208,9 +203,6 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { | |||||||
| 			if repo_model.IsErrWikiInvalidFileName(err) { | 			if repo_model.IsErrWikiInvalidFileName(err) { | ||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
| 			if wikiRepo != nil { |  | ||||||
| 				wikiRepo.Close() |  | ||||||
| 			} |  | ||||||
| 			ctx.ServerError("WikiFilenameToName", err) | 			ctx.ServerError("WikiFilenameToName", err) | ||||||
| 			return nil, nil | 			return nil, nil | ||||||
| 		} else if wikiName == "_Sidebar" || wikiName == "_Footer" { | 		} else if wikiName == "_Sidebar" || wikiName == "_Footer" { | ||||||
| @@ -249,58 +241,26 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { | |||||||
| 		ctx.Redirect(util.URLJoin(ctx.Repo.RepoLink, "wiki/raw", string(pageName))) | 		ctx.Redirect(util.URLJoin(ctx.Repo.RepoLink, "wiki/raw", string(pageName))) | ||||||
| 	} | 	} | ||||||
| 	if entry == nil || ctx.Written() { | 	if entry == nil || ctx.Written() { | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// get filecontent | 	// get page content | ||||||
| 	data := wikiContentsByEntry(ctx, entry) | 	data := wikiContentsByEntry(ctx, entry) | ||||||
| 	if ctx.Written() { | 	if ctx.Written() { | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var sidebarContent []byte |  | ||||||
| 	if !isSideBar { |  | ||||||
| 		sidebarContent, _, _, _ = wikiContentsByName(ctx, commit, "_Sidebar") |  | ||||||
| 		if ctx.Written() { |  | ||||||
| 			if wikiRepo != nil { |  | ||||||
| 				wikiRepo.Close() |  | ||||||
| 			} |  | ||||||
| 			return nil, nil |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		sidebarContent = data |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var footerContent []byte |  | ||||||
| 	if !isFooter { |  | ||||||
| 		footerContent, _, _, _ = wikiContentsByName(ctx, commit, "_Footer") |  | ||||||
| 		if ctx.Written() { |  | ||||||
| 			if wikiRepo != nil { |  | ||||||
| 				wikiRepo.Close() |  | ||||||
| 			} |  | ||||||
| 			return nil, nil |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		footerContent = data |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	rctx := renderhelper.NewRenderContextRepoWiki(ctx, ctx.Repo.Repository) | 	rctx := renderhelper.NewRenderContextRepoWiki(ctx, ctx.Repo.Repository) | ||||||
|  |  | ||||||
| 	buf := &strings.Builder{} | 	renderFn := func(data []byte) (escaped *charset.EscapeStatus, output template.HTML, err error) { | ||||||
| 	renderFn := func(data []byte) (escaped *charset.EscapeStatus, output string, err error) { | 		buf := &strings.Builder{} | ||||||
| 		markupRd, markupWr := io.Pipe() | 		markupRd, markupWr := io.Pipe() | ||||||
| 		defer markupWr.Close() | 		defer markupWr.Close() | ||||||
| 		done := make(chan struct{}) | 		done := make(chan struct{}) | ||||||
| 		go func() { | 		go func() { | ||||||
| 			// We allow NBSP here this is rendered | 			// We allow NBSP here this is rendered | ||||||
| 			escaped, _ = charset.EscapeControlReader(markupRd, buf, ctx.Locale, charset.RuneNBSP) | 			escaped, _ = charset.EscapeControlReader(markupRd, buf, ctx.Locale, charset.RuneNBSP) | ||||||
| 			output = buf.String() | 			output = template.HTML(buf.String()) | ||||||
| 			buf.Reset() | 			buf.Reset() | ||||||
| 			close(done) | 			close(done) | ||||||
| 		}() | 		}() | ||||||
| @@ -311,75 +271,61 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { | |||||||
| 		return escaped, output, err | 		return escaped, output, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ctx.Data["EscapeStatus"], ctx.Data["content"], err = renderFn(data) | 	ctx.Data["EscapeStatus"], ctx.Data["WikiContentHTML"], err = renderFn(data) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 		ctx.ServerError("Render", err) | 		ctx.ServerError("Render", err) | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if rctx.SidebarTocNode != nil { | 	if rctx.SidebarTocNode != nil { | ||||||
| 		sb := &strings.Builder{} | 		sb := strings.Builder{} | ||||||
| 		err = markdown.SpecializedMarkdown(rctx).Renderer().Render(sb, nil, rctx.SidebarTocNode) | 		if err = markdown.SpecializedMarkdown(rctx).Renderer().Render(&sb, nil, rctx.SidebarTocNode); err != nil { | ||||||
| 		if err != nil { |  | ||||||
| 			log.Error("Failed to render wiki sidebar TOC: %v", err) | 			log.Error("Failed to render wiki sidebar TOC: %v", err) | ||||||
| 		} else { |  | ||||||
| 			ctx.Data["sidebarTocContent"] = sb.String() |  | ||||||
| 		} | 		} | ||||||
|  | 		ctx.Data["WikiSidebarTocHTML"] = templates.SanitizeHTML(sb.String()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if !isSideBar { | 	if !isSideBar { | ||||||
| 		buf.Reset() | 		sidebarContent, _, _, _ := wikiContentsByName(ctx, commit, "_Sidebar") | ||||||
| 		ctx.Data["sidebarEscapeStatus"], ctx.Data["sidebarContent"], err = renderFn(sidebarContent) | 		if ctx.Written() { | ||||||
|  | 			return nil, nil | ||||||
|  | 		} | ||||||
|  | 		ctx.Data["WikiSidebarEscapeStatus"], ctx.Data["WikiSidebarHTML"], err = renderFn(sidebarContent) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			if wikiRepo != nil { |  | ||||||
| 				wikiRepo.Close() |  | ||||||
| 			} |  | ||||||
| 			ctx.ServerError("Render", err) | 			ctx.ServerError("Render", err) | ||||||
| 			return nil, nil | 			return nil, nil | ||||||
| 		} | 		} | ||||||
| 		ctx.Data["sidebarPresent"] = sidebarContent != nil |  | ||||||
| 	} else { |  | ||||||
| 		ctx.Data["sidebarPresent"] = false |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if !isFooter { | 	if !isFooter { | ||||||
| 		buf.Reset() | 		footerContent, _, _, _ := wikiContentsByName(ctx, commit, "_Footer") | ||||||
| 		ctx.Data["footerEscapeStatus"], ctx.Data["footerContent"], err = renderFn(footerContent) | 		if ctx.Written() { | ||||||
|  | 			return nil, nil | ||||||
|  | 		} | ||||||
|  | 		ctx.Data["WikiFooterEscapeStatus"], ctx.Data["WikiFooterHTML"], err = renderFn(footerContent) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			if wikiRepo != nil { |  | ||||||
| 				wikiRepo.Close() |  | ||||||
| 			} |  | ||||||
| 			ctx.ServerError("Render", err) | 			ctx.ServerError("Render", err) | ||||||
| 			return nil, nil | 			return nil, nil | ||||||
| 		} | 		} | ||||||
| 		ctx.Data["footerPresent"] = footerContent != nil |  | ||||||
| 	} else { |  | ||||||
| 		ctx.Data["footerPresent"] = false |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// get commit count - wiki revisions | 	// get commit count - wiki revisions | ||||||
| 	commitsCount, _ := wikiRepo.FileCommitsCount(ctx.Repo.Repository.DefaultWikiBranch, pageFilename) | 	commitsCount, _ := wikiGitRepo.FileCommitsCount(ctx.Repo.Repository.DefaultWikiBranch, pageFilename) | ||||||
| 	ctx.Data["CommitCount"] = commitsCount | 	ctx.Data["CommitCount"] = commitsCount | ||||||
|  |  | ||||||
| 	return wikiRepo, entry | 	return wikiGitRepo, entry | ||||||
| } | } | ||||||
|  |  | ||||||
| func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { | func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) { | ||||||
| 	wikiRepo, commit, err := findWikiRepoCommit(ctx) | 	wikiGitRepo, commit, err := findWikiRepoCommit(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 		if !git.IsErrNotExist(err) { | 		if !git.IsErrNotExist(err) { | ||||||
| 			ctx.ServerError("GetBranchCommit", err) | 			ctx.ServerError("GetBranchCommit", err) | ||||||
| 		} | 		} | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// get requested pagename | 	// get requested page name | ||||||
| 	pageName := wiki_service.WebPathFromRequest(ctx.PathParamRaw("*")) | 	pageName := wiki_service.WebPathFromRequest(ctx.PathParamRaw("*")) | ||||||
| 	if len(pageName) == 0 { | 	if len(pageName) == 0 { | ||||||
| 		pageName = "Home" | 		pageName = "Home" | ||||||
| @@ -394,50 +340,35 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) | |||||||
| 	ctx.Data["Username"] = ctx.Repo.Owner.Name | 	ctx.Data["Username"] = ctx.Repo.Owner.Name | ||||||
| 	ctx.Data["Reponame"] = ctx.Repo.Repository.Name | 	ctx.Data["Reponame"] = ctx.Repo.Repository.Name | ||||||
|  |  | ||||||
| 	// lookup filename in wiki - get filecontent, gitTree entry , real filename | 	// lookup filename in wiki - get page content, gitTree entry , real filename | ||||||
| 	data, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName) | 	_, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName) | ||||||
| 	if noEntry { | 	if noEntry { | ||||||
| 		ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages") | 		ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages") | ||||||
| 	} | 	} | ||||||
| 	if entry == nil || ctx.Written() { | 	if entry == nil || ctx.Written() { | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ctx.Data["content"] = string(data) |  | ||||||
| 	ctx.Data["sidebarPresent"] = false |  | ||||||
| 	ctx.Data["sidebarContent"] = "" |  | ||||||
| 	ctx.Data["footerPresent"] = false |  | ||||||
| 	ctx.Data["footerContent"] = "" |  | ||||||
|  |  | ||||||
| 	// get commit count - wiki revisions | 	// get commit count - wiki revisions | ||||||
| 	commitsCount, _ := wikiRepo.FileCommitsCount(ctx.Repo.Repository.DefaultWikiBranch, pageFilename) | 	commitsCount, _ := wikiGitRepo.FileCommitsCount(ctx.Repo.Repository.DefaultWikiBranch, pageFilename) | ||||||
| 	ctx.Data["CommitCount"] = commitsCount | 	ctx.Data["CommitCount"] = commitsCount | ||||||
|  |  | ||||||
| 	// get page | 	// get page | ||||||
| 	page := max(ctx.FormInt("page"), 1) | 	page := max(ctx.FormInt("page"), 1) | ||||||
|  |  | ||||||
| 	// get Commit Count | 	// get Commit Count | ||||||
| 	commitsHistory, err := wikiRepo.CommitsByFileAndRange( | 	commitsHistory, err := wikiGitRepo.CommitsByFileAndRange( | ||||||
| 		git.CommitsByFileAndRangeOptions{ | 		git.CommitsByFileAndRangeOptions{ | ||||||
| 			Revision: ctx.Repo.Repository.DefaultWikiBranch, | 			Revision: ctx.Repo.Repository.DefaultWikiBranch, | ||||||
| 			File:     pageFilename, | 			File:     pageFilename, | ||||||
| 			Page:     page, | 			Page:     page, | ||||||
| 		}) | 		}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 		ctx.ServerError("CommitsByFileAndRange", err) | 		ctx.ServerError("CommitsByFileAndRange", err) | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
| 	ctx.Data["Commits"], err = git_service.ConvertFromGitCommit(ctx, commitsHistory, ctx.Repo.Repository) | 	ctx.Data["Commits"], err = git_service.ConvertFromGitCommit(ctx, commitsHistory, ctx.Repo.Repository) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 		ctx.ServerError("ConvertFromGitCommit", err) | 		ctx.ServerError("ConvertFromGitCommit", err) | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
| @@ -446,16 +377,11 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) | |||||||
| 	pager.AddParamFromRequest(ctx.Req) | 	pager.AddParamFromRequest(ctx.Req) | ||||||
| 	ctx.Data["Page"] = pager | 	ctx.Data["Page"] = pager | ||||||
|  |  | ||||||
| 	return wikiRepo, entry | 	return wikiGitRepo, entry | ||||||
| } | } | ||||||
|  |  | ||||||
| func renderEditPage(ctx *context.Context) { | func renderEditPage(ctx *context.Context) { | ||||||
| 	wikiRepo, commit, err := findWikiRepoCommit(ctx) | 	_, commit, err := findWikiRepoCommit(ctx) | ||||||
| 	defer func() { |  | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			_ = wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 	}() |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if !git.IsErrNotExist(err) { | 		if !git.IsErrNotExist(err) { | ||||||
| 			ctx.ServerError("GetBranchCommit", err) | 			ctx.ServerError("GetBranchCommit", err) | ||||||
| @@ -463,7 +389,7 @@ func renderEditPage(ctx *context.Context) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// get requested pagename | 	// get requested page name | ||||||
| 	pageName := wiki_service.WebPathFromRequest(ctx.PathParamRaw("*")) | 	pageName := wiki_service.WebPathFromRequest(ctx.PathParamRaw("*")) | ||||||
| 	if len(pageName) == 0 { | 	if len(pageName) == 0 { | ||||||
| 		pageName = "Home" | 		pageName = "Home" | ||||||
| @@ -487,17 +413,13 @@ func renderEditPage(ctx *context.Context) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// get filecontent | 	// get wiki page content | ||||||
| 	data := wikiContentsByEntry(ctx, entry) | 	data := wikiContentsByEntry(ctx, entry) | ||||||
| 	if ctx.Written() { | 	if ctx.Written() { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ctx.Data["content"] = string(data) | 	ctx.Data["WikiEditContent"] = string(data) | ||||||
| 	ctx.Data["sidebarPresent"] = false |  | ||||||
| 	ctx.Data["sidebarContent"] = "" |  | ||||||
| 	ctx.Data["footerPresent"] = false |  | ||||||
| 	ctx.Data["footerContent"] = "" |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // WikiPost renders post of wiki page | // WikiPost renders post of wiki page | ||||||
| @@ -559,12 +481,7 @@ func Wiki(ctx *context.Context) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	wikiRepo, entry := renderViewPage(ctx) | 	wikiGitRepo, entry := renderViewPage(ctx) | ||||||
| 	defer func() { |  | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 	}() |  | ||||||
| 	if ctx.Written() { | 	if ctx.Written() { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @@ -580,7 +497,7 @@ func Wiki(ctx *context.Context) { | |||||||
| 		ctx.Data["FormatWarning"] = ext + " rendering is not supported at the moment. Rendered as Markdown." | 		ctx.Data["FormatWarning"] = ext + " rendering is not supported at the moment. Rendered as Markdown." | ||||||
| 	} | 	} | ||||||
| 	// Get last change information. | 	// Get last change information. | ||||||
| 	lastCommit, err := wikiRepo.GetCommitByPath(wikiPath) | 	lastCommit, err := wikiGitRepo.GetCommitByPath(wikiPath) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("GetCommitByPath", err) | 		ctx.ServerError("GetCommitByPath", err) | ||||||
| 		return | 		return | ||||||
| @@ -600,13 +517,7 @@ func WikiRevision(ctx *context.Context) { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	wikiRepo, entry := renderRevisionPage(ctx) | 	wikiGitRepo, entry := renderRevisionPage(ctx) | ||||||
| 	defer func() { |  | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 	}() |  | ||||||
|  |  | ||||||
| 	if ctx.Written() { | 	if ctx.Written() { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| @@ -618,7 +529,7 @@ func WikiRevision(ctx *context.Context) { | |||||||
|  |  | ||||||
| 	// Get last change information. | 	// Get last change information. | ||||||
| 	wikiPath := entry.Name() | 	wikiPath := entry.Name() | ||||||
| 	lastCommit, err := wikiRepo.GetCommitByPath(wikiPath) | 	lastCommit, err := wikiGitRepo.GetCommitByPath(wikiPath) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("GetCommitByPath", err) | 		ctx.ServerError("GetCommitByPath", err) | ||||||
| 		return | 		return | ||||||
| @@ -638,12 +549,7 @@ func WikiPages(ctx *context.Context) { | |||||||
| 	ctx.Data["Title"] = ctx.Tr("repo.wiki.pages") | 	ctx.Data["Title"] = ctx.Tr("repo.wiki.pages") | ||||||
| 	ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(unit.TypeWiki) && !ctx.Repo.Repository.IsArchived | 	ctx.Data["CanWriteWiki"] = ctx.Repo.CanWrite(unit.TypeWiki) && !ctx.Repo.Repository.IsArchived | ||||||
|  |  | ||||||
| 	wikiRepo, commit, err := findWikiRepoCommit(ctx) | 	_, commit, err := findWikiRepoCommit(ctx) | ||||||
| 	defer func() { |  | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			_ = wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 	}() |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Redirect(ctx.Repo.RepoLink + "/wiki") | 		ctx.Redirect(ctx.Repo.RepoLink + "/wiki") | ||||||
| 		return | 		return | ||||||
| @@ -697,13 +603,7 @@ func WikiPages(ctx *context.Context) { | |||||||
|  |  | ||||||
| // WikiRaw outputs raw blob requested by user (image for example) | // WikiRaw outputs raw blob requested by user (image for example) | ||||||
| func WikiRaw(ctx *context.Context) { | func WikiRaw(ctx *context.Context) { | ||||||
| 	wikiRepo, commit, err := findWikiRepoCommit(ctx) | 	_, commit, err := findWikiRepoCommit(ctx) | ||||||
| 	defer func() { |  | ||||||
| 		if wikiRepo != nil { |  | ||||||
| 			wikiRepo.Close() |  | ||||||
| 		} |  | ||||||
| 	}() |  | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if git.IsErrNotExist(err) { | 		if git.IsErrNotExist(err) { | ||||||
| 			ctx.NotFound(nil) | 			ctx.NotFound(nil) | ||||||
|   | |||||||
| @@ -164,7 +164,7 @@ func TestEditWiki(t *testing.T) { | |||||||
| 	EditWiki(ctx) | 	EditWiki(ctx) | ||||||
| 	assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) | 	assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) | ||||||
| 	assert.EqualValues(t, "Home", ctx.Data["Title"]) | 	assert.EqualValues(t, "Home", ctx.Data["Title"]) | ||||||
| 	assert.Equal(t, wikiContent(t, ctx.Repo.Repository, "Home"), ctx.Data["content"]) | 	assert.Equal(t, wikiContent(t, ctx.Repo.Repository, "Home"), ctx.Data["WikiEditContent"]) | ||||||
|  |  | ||||||
| 	ctx, _ = contexttest.MockContext(t, "user2/repo1/wiki/jpeg.jpg?action=_edit") | 	ctx, _ = contexttest.MockContext(t, "user2/repo1/wiki/jpeg.jpg?action=_edit") | ||||||
| 	ctx.SetPathParam("*", "jpeg.jpg") | 	ctx.SetPathParam("*", "jpeg.jpg") | ||||||
|   | |||||||
| @@ -195,7 +195,7 @@ func (telegramConvertor) WorkflowJob(p *api.WorkflowJobPayload) (TelegramPayload | |||||||
| func createTelegramPayloadHTML(msgHTML string) TelegramPayload { | func createTelegramPayloadHTML(msgHTML string) TelegramPayload { | ||||||
| 	// https://core.telegram.org/bots/api#formatting-options | 	// https://core.telegram.org/bots/api#formatting-options | ||||||
| 	return TelegramPayload{ | 	return TelegramPayload{ | ||||||
| 		Message:           strings.TrimSpace(markup.Sanitize(msgHTML)), | 		Message:           strings.TrimSpace(string(markup.Sanitize(msgHTML))), | ||||||
| 		ParseMode:         "HTML", | 		ParseMode:         "HTML", | ||||||
| 		DisableWebPreview: true, | 		DisableWebPreview: true, | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -1,22 +1,22 @@ | |||||||
| {{if .EscapeStatus}} | {{if .EscapeStatus}} | ||||||
| 	{{if .EscapeStatus.HasInvisible}} | 	{{if .EscapeStatus.HasInvisible}} | ||||||
| 		<div class="ui warning message unicode-escape-prompt tw-text-left"> | 		<div class="ui warning message unicode-escape-prompt"> | ||||||
| 			<button class="btn close icon hide-panel" data-panel-closest=".message">{{svg "octicon-x" 16 "close inside"}}</button> | 			<button class="btn close icon hide-panel" data-panel-closest=".message">{{svg "octicon-x" 16 "close inside"}}</button> | ||||||
| 			<div class="header"> | 			<div class="header"> | ||||||
| 				{{ctx.Locale.Tr "repo.invisible_runes_header"}} | 				{{ctx.Locale.Tr "repo.invisible_runes_header"}} | ||||||
| 			</div> | 			</div> | ||||||
| 			<p>{{ctx.Locale.Tr "repo.invisible_runes_description"}}</p> | 			<div>{{ctx.Locale.Tr "repo.invisible_runes_description"}}</div> | ||||||
| 			{{if .EscapeStatus.HasAmbiguous}} | 			{{if .EscapeStatus.HasAmbiguous}} | ||||||
| 				<p>{{ctx.Locale.Tr "repo.ambiguous_runes_description"}}</p> | 				<div>{{ctx.Locale.Tr "repo.ambiguous_runes_description"}}</div> | ||||||
| 			{{end}} | 			{{end}} | ||||||
| 		</div> | 		</div> | ||||||
| 	{{else if .EscapeStatus.HasAmbiguous}} | 	{{else if .EscapeStatus.HasAmbiguous}} | ||||||
| 		<div class="ui warning message unicode-escape-prompt tw-text-left"> | 		<div class="ui warning message unicode-escape-prompt"> | ||||||
| 			<button class="btn close icon hide-panel" data-panel-closest=".message">{{svg "octicon-x" 16 "close inside"}}</button> | 			<button class="btn close icon hide-panel" data-panel-closest=".message">{{svg "octicon-x" 16 "close inside"}}</button> | ||||||
| 			<div class="header"> | 			<div class="header"> | ||||||
| 				{{ctx.Locale.Tr "repo.ambiguous_runes_header"}} | 				{{ctx.Locale.Tr "repo.ambiguous_runes_header"}} | ||||||
| 			</div> | 			</div> | ||||||
| 			<p>{{ctx.Locale.Tr "repo.ambiguous_runes_description"}}</p> | 			<div>{{ctx.Locale.Tr "repo.ambiguous_runes_description"}}</div> | ||||||
| 		</div> | 		</div> | ||||||
| 	{{end}} | 	{{end}} | ||||||
| {{end}} | {{end}} | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ | |||||||
| 				{{ctx.Locale.Tr "repo.wiki.page_name_desc"}} | 				{{ctx.Locale.Tr "repo.wiki.page_name_desc"}} | ||||||
| 			</div> | 			</div> | ||||||
|  |  | ||||||
| 			{{$content := .content}} | 			{{$content := .WikiEditContent}} | ||||||
| 			{{if not .PageIsWikiEdit}} | 			{{if not .PageIsWikiEdit}} | ||||||
| 				{{$content = ctx.Locale.Tr "repo.wiki.welcome"}} | 				{{$content = ctx.Locale.Tr "repo.wiki.welcome"}} | ||||||
| 			{{end}} | 			{{end}} | ||||||
|   | |||||||
| @@ -62,36 +62,34 @@ | |||||||
| 		{{end}} | 		{{end}} | ||||||
|  |  | ||||||
| 		<div class="wiki-content-parts"> | 		<div class="wiki-content-parts"> | ||||||
| 			{{if .sidebarTocContent}} | 			{{if .WikiSidebarTocHTML}} | ||||||
| 			<div class="render-content markup wiki-content-sidebar wiki-content-toc"> | 			<div class="render-content markup wiki-content-sidebar wiki-content-toc"> | ||||||
| 				{{.sidebarTocContent | SafeHTML}} | 				{{.WikiSidebarTocHTML}} | ||||||
| 			</div> | 			</div> | ||||||
| 			{{end}} | 			{{end}} | ||||||
|  |  | ||||||
| 			<div class="render-content markup wiki-content-main {{if or .sidebarTocContent .sidebarPresent}}with-sidebar{{end}}"> | 			<div class="render-content markup wiki-content-main {{if or .WikiSidebarTocHTML .WikiSidebarHTML}}with-sidebar{{end}}"> | ||||||
| 				{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus "root" $}} | 				{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .EscapeStatus}} | ||||||
| 				{{.content | SafeHTML}} | 				{{.WikiContentHTML}} | ||||||
| 			</div> | 			</div> | ||||||
|  |  | ||||||
| 			{{if .sidebarPresent}} | 			{{if .WikiSidebarHTML}} | ||||||
| 			<div class="render-content markup wiki-content-sidebar"> | 			<div class="render-content markup wiki-content-sidebar"> | ||||||
| 				{{if and .CanWriteWiki (not .Repository.IsMirror)}} | 				{{if and .CanWriteWiki (not .Repository.IsMirror)}} | ||||||
| 					<a class="tw-float-right muted" href="{{.RepoLink}}/wiki/_Sidebar?action=_edit" aria-label="{{ctx.Locale.Tr "repo.wiki.edit_page_button"}}">{{svg "octicon-pencil"}}</a> | 					<a class="tw-float-right muted" href="{{.RepoLink}}/wiki/_Sidebar?action=_edit" aria-label="{{ctx.Locale.Tr "repo.wiki.edit_page_button"}}">{{svg "octicon-pencil"}}</a> | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 				{{template "repo/unicode_escape_prompt" dict "EscapeStatus" .sidebarEscapeStatus "root" $}} | 				{{.WikiSidebarHTML}} | ||||||
| 				{{.sidebarContent | SafeHTML}} |  | ||||||
| 			</div> | 			</div> | ||||||
| 			{{end}} | 			{{end}} | ||||||
|  |  | ||||||
| 			<div class="tw-clear-both"></div> | 			<div class="tw-clear-both"></div> | ||||||
|  |  | ||||||
| 			{{if .footerPresent}} | 			{{if .WikiFooterHTML}} | ||||||
| 			<div class="render-content markup wiki-content-footer"> | 			<div class="render-content markup wiki-content-footer"> | ||||||
| 				{{if and .CanWriteWiki (not .Repository.IsMirror)}} | 				{{if and .CanWriteWiki (not .Repository.IsMirror)}} | ||||||
| 					<a class="tw-float-right muted" href="{{.RepoLink}}/wiki/_Footer?action=_edit" aria-label="{{ctx.Locale.Tr "repo.wiki.edit_page_button"}}">{{svg "octicon-pencil"}}</a> | 					<a class="tw-float-right muted" href="{{.RepoLink}}/wiki/_Footer?action=_edit" aria-label="{{ctx.Locale.Tr "repo.wiki.edit_page_button"}}">{{svg "octicon-pencil"}}</a> | ||||||
| 				{{end}} | 				{{end}} | ||||||
| 				{{template "repo/unicode_escape_prompt" dict "footerEscapeStatus" .sidebarEscapeStatus "root" $}} | 				{{.WikiFooterHTML}} | ||||||
| 				{{.footerContent | SafeHTML}} |  | ||||||
| 			</div> | 			</div> | ||||||
| 			{{end}} | 			{{end}} | ||||||
| 		</div> | 		</div> | ||||||
|   | |||||||
| @@ -134,7 +134,9 @@ | |||||||
|   margin-bottom: 16px; |   margin-bottom: 16px; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* override p:last-child from base.css */ | /* override p:last-child from base.css. | ||||||
|  | Fomantic assumes that <p>/<hX> elements only have margins between elements, but not for the first's top or last's bottom. | ||||||
|  | In markup content, we always use bottom margin for all elements */ | ||||||
| .markup p:last-child { | .markup p:last-child { | ||||||
|   margin-bottom: 16px; |   margin-bottom: 16px; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1834,6 +1834,7 @@ tbody.commit-list { | |||||||
|   border-radius: 0; |   border-radius: 0; | ||||||
|   display: flex; |   display: flex; | ||||||
|   flex-direction: column; |   flex-direction: column; | ||||||
|  |   gap: 0.5em; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* fomantic's last-child selector does not work with hidden last child */ | /* fomantic's last-child selector does not work with hidden last child */ | ||||||
|   | |||||||
| @@ -39,10 +39,6 @@ | |||||||
|   min-width: 150px; |   min-width: 150px; | ||||||
| } | } | ||||||
|  |  | ||||||
| .repository.wiki .wiki-content-sidebar .ui.message.unicode-escape-prompt p { |  | ||||||
|   display: none; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .repository.wiki .wiki-content-footer { | .repository.wiki .wiki-content-footer { | ||||||
|   margin-top: 1em; |   margin-top: 1em; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user