~bouncepaw/mycorrhiza

40dbbf53763b84c84ec85055dc660bf51bd31168 — Umar Getagazov 1 year, 27 days ago 4e6adec
Highlight primitive diff additions and deletions
M history/histweb/histview.go => history/histweb/histview.go +38 -2
@@ 11,6 11,7 @@ import (
	"github.com/bouncepaw/mycorrhiza/util"
	"github.com/bouncepaw/mycorrhiza/viewutil"
	"github.com/gorilla/mux"
	"html/template"
	"log"
	"net/http"
	"path/filepath"


@@ 125,6 126,7 @@ var (

{{define "diff for at title"}}Разница для {{beautifulName .HyphaName}} для {{.Hash}}{{end}}
{{define "diff for at heading"}}Разница для <a href="/hypha/{{.HyphaName}}">{{beautifulName .HyphaName}}</a> для {{.Hash}}{{end}}
{{define "no text diff available"}}Нет текстовой разницы.{{end}}

{{define "count pre"}}Отобразить{{end}}
{{define "count post"}}свежих правок.{{end}}


@@ 158,15 160,49 @@ type primitiveDiffData struct {
	*viewutil.BaseData
	HyphaName string
	Hash      string
	Text      string
	Text      template.HTML
}

func primitiveDiff(meta viewutil.Meta, h hyphae.Hypha, hash, text string) {
	hunks := history.SplitPrimitiveDiff(text)
	if len(hunks) > 0 {
		var buf strings.Builder
		for _, hunk := range hunks {
			lines := strings.Split(hunk, "\n")
			buf.WriteString(`<pre class="codeblock">`)
			for i, line := range lines {
				line = strings.Trim(line, "\r")
				var class string
				if len(line) > 0 {
					switch line[0] {
					case '+':
						class = "primitive-diff__addition"
					case '-':
						class = "primitive-diff__deletion"
					case '@':
						class = "primitive-diff__context"
					}
				}
				if i > 0 {
					buf.WriteString("\n")
				}
				line = template.HTMLEscapeString(line)
				fmt.Fprintf(&buf, `<code class="%s">%s</code>`,
					class, line)
			}
			buf.WriteString(`</pre>`)
		}
		text = buf.String()
	} else if text != "" {
		text = template.HTMLEscapeString(text)
		text = fmt.Sprintf(
			`<pre class="codeblock"><code>%s</code></pre>`, text)
	}
	viewutil.ExecutePage(meta, chainPrimitiveDiff, primitiveDiffData{
		BaseData:  &viewutil.BaseData{},
		HyphaName: h.CanonicalName(),
		Hash:      hash,
		Text:      text,
		Text:      template.HTML(text),
	})
}


M history/histweb/view_primitive_diff.html => history/histweb/view_primitive_diff.html +3 -2
@@ 1,11 1,12 @@
{{define "diff for at title"}}Diff of {{beautifulName .HyphaName}} at {{.Hash}}{{end}}
{{define "diff for at heading"}}Diff of <a href="/hypha/{{.HyphaName}}">{{beautifulName .HyphaName}}</a> at {{.Hash}}{{end}}
{{define "no text diff available"}}No text diff available.{{end}}
{{define "title"}}{{template "diff for at title" .}}{{end}}
{{define "body"}}
<main class="main-width">
	<article>
		<h1>{{template "diff for at heading" .}}</h1>
		<pre class="codeblock"><code>{{.Text}}</code></pre>
		{{if .Text}}{{.Text}}{{else}}{{template "no text diff available" .}}{{end}}
	</article>
</main>
{{end}}
\ No newline at end of file
{{end}}

M history/revision.go => history/revision.go +18 -0
@@ 252,3 252,21 @@ func PrimitiveDiffAtRevision(filepath, hash string) (string, error) {
	}
	return out.String(), err
}

// SplitPrimitiveDiff splits a primitive diff of a single file into hunks.
func SplitPrimitiveDiff(text string) (result []string) {
	idx := strings.Index(text, "@@ -")
	if idx < 0 {
		return
	}
	text = text[idx:]
	for {
		idx = strings.Index(text, "\n@@ -")
		if idx < 0 {
			result = append(result, text)
			return
		}
		result = append(result, text[:idx+1])
		text = text[idx+1:]
	}
}

M static/default.css => static/default.css +18 -0
@@ 911,3 911,21 @@ body[data-rrh-addr^="/interwiki"] main form + form {
.img-gallery img { max-width: 100%; max-height: 50vh; }
figure { margin: 0; }
figcaption { padding-bottom: .5rem; }

/*
 * Primitive diff
 */
.primitive-diff__addition {
	color: green;
}
.primitive-diff__deletion {
	color: red;
}
.primitive-diff__context {
	opacity: .5;
}
@media (prefers-color-scheme: dark) {
	.primitive-diff__addition {
		color: #4cd74c;
	}
}