mirror of
https://github.com/osmarks/mycorrhiza.git
synced 2025-08-27 16:12:26 +00:00
Make the relative hyphae block look nicer a little
This commit is contained in:
parent
86aa82bc50
commit
671f7a05a6
@ -39,7 +39,6 @@ header { width: 100%; margin-bottom: 1rem; }
|
|||||||
.hypha-tabs__selection { display: inline-block; padding: .25rem; font-weight: bold; }
|
.hypha-tabs__selection { display: inline-block; padding: .25rem; font-weight: bold; }
|
||||||
|
|
||||||
.relative-hyphae { margin-top: .5rem; }
|
.relative-hyphae { margin-top: .5rem; }
|
||||||
.relative-hyphae > ul { margin: 0; padding: .5rem 1rem; }
|
|
||||||
.relative-hyphae li { list-style-type: none; }
|
.relative-hyphae li { list-style-type: none; }
|
||||||
|
|
||||||
@media screen and (max-width: 800px) {
|
@media screen and (max-width: 800px) {
|
||||||
@ -164,6 +163,19 @@ table { border: #ddd 1px solid; border-radius: .25rem; min-width: 4rem; }
|
|||||||
td { padding: .25rem; }
|
td { padding: .25rem; }
|
||||||
caption { caption-side: top; font-size: small; }
|
caption { caption-side: top; font-size: small; }
|
||||||
|
|
||||||
|
.navitree { padding: 0; margin: 0; }
|
||||||
|
.navitree__trunk ul { padding-left: 1rem; }
|
||||||
|
.navitree > .navitree__trunk > ul { padding-left: 2rem; }
|
||||||
|
.navitree__entry { }
|
||||||
|
.navitree > .navitree__entry > a::before { display: inline-block; width: .5rem; color: #999; margin: 0 .25rem; }
|
||||||
|
.navitree > .navitree__entry_infertile > a::before { content: " "} /* nbsp, careful */
|
||||||
|
.navitree > .navitree__entry_fertile > a::before { content: "▸"}
|
||||||
|
.navitree__trunk { border-left: 1px #999 solid; }
|
||||||
|
.navitree > .navitree__trunk { border-left: none; }
|
||||||
|
.navitree > .navitree__trunk > a { font-weight: bold; }
|
||||||
|
.navitree__link { text-decoration: none; display: block; padding: .25rem; }
|
||||||
|
.navitree__link:hover { background-color: #eee; }
|
||||||
|
|
||||||
/* Color stuff */
|
/* Color stuff */
|
||||||
/* Lighter stuff #eee */
|
/* Lighter stuff #eee */
|
||||||
article code,
|
article code,
|
||||||
@ -210,10 +222,6 @@ blockquote { border-left: 4px black solid; }
|
|||||||
.upload-amnt { border: #eee 1px solid; }
|
.upload-amnt { border: #eee 1px solid; }
|
||||||
td { border: #ddd 1px solid; }
|
td { border: #ddd 1px solid; }
|
||||||
|
|
||||||
.navitree__node { padding-left: 1rem; }
|
|
||||||
.navitree__link { text-decoration: none; display: block; }
|
|
||||||
.navitree__link:hover { background-color: #eee; }
|
|
||||||
|
|
||||||
/* Dark theme! */
|
/* Dark theme! */
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
html { background: #222; color: #ddd; }
|
html { background: #222; color: #ddd; }
|
||||||
|
@ -14,7 +14,6 @@ header { width: 100%; margin-bottom: 1rem; }
|
|||||||
.hypha-tabs__selection { display: inline-block; padding: .25rem; font-weight: bold; }
|
.hypha-tabs__selection { display: inline-block; padding: .25rem; font-weight: bold; }
|
||||||
|
|
||||||
.relative-hyphae { margin-top: .5rem; }
|
.relative-hyphae { margin-top: .5rem; }
|
||||||
.relative-hyphae > ul { margin: 0; padding: .5rem 1rem; }
|
|
||||||
.relative-hyphae li { list-style-type: none; }
|
.relative-hyphae li { list-style-type: none; }
|
||||||
|
|
||||||
@media screen and (max-width: 800px) {
|
@media screen and (max-width: 800px) {
|
||||||
@ -139,6 +138,19 @@ table { border: #ddd 1px solid; border-radius: .25rem; min-width: 4rem; }
|
|||||||
td { padding: .25rem; }
|
td { padding: .25rem; }
|
||||||
caption { caption-side: top; font-size: small; }
|
caption { caption-side: top; font-size: small; }
|
||||||
|
|
||||||
|
.navitree { padding: 0; margin: 0; }
|
||||||
|
.navitree__trunk ul { padding-left: 1rem; }
|
||||||
|
.navitree > .navitree__trunk > ul { padding-left: 2rem; }
|
||||||
|
.navitree__entry { }
|
||||||
|
.navitree > .navitree__entry > a::before { display: inline-block; width: .5rem; color: #999; margin: 0 .25rem; }
|
||||||
|
.navitree > .navitree__entry_infertile > a::before { content: " "} /* nbsp, careful */
|
||||||
|
.navitree > .navitree__entry_fertile > a::before { content: "▸"}
|
||||||
|
.navitree__trunk { border-left: 1px #999 solid; }
|
||||||
|
.navitree > .navitree__trunk { border-left: none; }
|
||||||
|
.navitree > .navitree__trunk > a { font-weight: bold; }
|
||||||
|
.navitree__link { text-decoration: none; display: block; padding: .25rem; }
|
||||||
|
.navitree__link:hover { background-color: #eee; }
|
||||||
|
|
||||||
/* Color stuff */
|
/* Color stuff */
|
||||||
/* Lighter stuff #eee */
|
/* Lighter stuff #eee */
|
||||||
article code,
|
article code,
|
||||||
@ -185,10 +197,6 @@ blockquote { border-left: 4px black solid; }
|
|||||||
.upload-amnt { border: #eee 1px solid; }
|
.upload-amnt { border: #eee 1px solid; }
|
||||||
td { border: #ddd 1px solid; }
|
td { border: #ddd 1px solid; }
|
||||||
|
|
||||||
.navitree__node { padding-left: 1rem; }
|
|
||||||
.navitree__link { text-decoration: none; display: block; }
|
|
||||||
.navitree__link:hover { background-color: #eee; }
|
|
||||||
|
|
||||||
/* Dark theme! */
|
/* Dark theme! */
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
html { background: #222; color: #ddd; }
|
html { background: #222; color: #ddd; }
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{% import "net/http" %}
|
{% import "net/http" %}
|
||||||
{% import "path" %}
|
{% import "path" %}
|
||||||
{% import "github.com/bouncepaw/mycorrhiza/user" %}
|
{% import "github.com/bouncepaw/mycorrhiza/user" %}
|
||||||
|
{% import "github.com/bouncepaw/mycorrhiza/util" %}
|
||||||
|
|
||||||
{% func HistoryHTML(rq *http.Request, hyphaName, list string) %}
|
{% func HistoryHTML(rq *http.Request, hyphaName, list string) %}
|
||||||
{%= navHTML(rq, hyphaName, "history") %}
|
{%= navHTML(rq, hyphaName, "history") %}
|
||||||
@ -43,10 +44,10 @@ If `contents` == "", a helpful message is shown instead.
|
|||||||
</article>
|
</article>
|
||||||
<section class="prevnext">
|
<section class="prevnext">
|
||||||
{% if prevHyphaName != "" %}
|
{% if prevHyphaName != "" %}
|
||||||
<a class="prevnext__el prevnext__prev" href="/page/{%s prevHyphaName %}" rel="prev">← {%s path.Base(prevHyphaName) %}</a>
|
<a class="prevnext__el prevnext__prev" href="/hypha/{%s prevHyphaName %}" rel="prev">← {%s util.BeautifulName(path.Base(prevHyphaName)) %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if nextHyphaName != "" %}
|
{% if nextHyphaName != "" %}
|
||||||
<a class="prevnext__el prevnext__next" href="/page/{%s nextHyphaName %}" rel="next">{%s path.Base(nextHyphaName) %} →</a>
|
<a class="prevnext__el prevnext__next" href="/hypha/{%s nextHyphaName %}" rel="next">{%s util.BeautifulName(path.Base(nextHyphaName)) %} →</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</section>
|
</section>
|
||||||
{% if u := user.FromRequest(rq); !user.AuthUsed || u.Group != "anon" %}
|
{% if u := user.FromRequest(rq); !user.AuthUsed || u.Group != "anon" %}
|
||||||
|
@ -13,246 +13,249 @@ import "path"
|
|||||||
//line templates/readers.qtpl:3
|
//line templates/readers.qtpl:3
|
||||||
import "github.com/bouncepaw/mycorrhiza/user"
|
import "github.com/bouncepaw/mycorrhiza/user"
|
||||||
|
|
||||||
//line templates/readers.qtpl:5
|
//line templates/readers.qtpl:4
|
||||||
|
import "github.com/bouncepaw/mycorrhiza/util"
|
||||||
|
|
||||||
|
//line templates/readers.qtpl:6
|
||||||
import (
|
import (
|
||||||
qtio422016 "io"
|
qtio422016 "io"
|
||||||
|
|
||||||
qt422016 "github.com/valyala/quicktemplate"
|
qt422016 "github.com/valyala/quicktemplate"
|
||||||
)
|
)
|
||||||
|
|
||||||
//line templates/readers.qtpl:5
|
//line templates/readers.qtpl:6
|
||||||
var (
|
var (
|
||||||
_ = qtio422016.Copy
|
_ = qtio422016.Copy
|
||||||
_ = qt422016.AcquireByteBuffer
|
_ = qt422016.AcquireByteBuffer
|
||||||
)
|
)
|
||||||
|
|
||||||
//line templates/readers.qtpl:5
|
//line templates/readers.qtpl:6
|
||||||
func StreamHistoryHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, list string) {
|
func StreamHistoryHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, list string) {
|
||||||
//line templates/readers.qtpl:5
|
//line templates/readers.qtpl:6
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:6
|
//line templates/readers.qtpl:7
|
||||||
streamnavHTML(qw422016, rq, hyphaName, "history")
|
streamnavHTML(qw422016, rq, hyphaName, "history")
|
||||||
//line templates/readers.qtpl:6
|
//line templates/readers.qtpl:7
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
<main class="main-width">
|
<main class="main-width">
|
||||||
<article class="history">
|
<article class="history">
|
||||||
<h1>History of `)
|
<h1>History of `)
|
||||||
//line templates/readers.qtpl:10
|
//line templates/readers.qtpl:11
|
||||||
qw422016.E().S(hyphaName)
|
qw422016.E().S(hyphaName)
|
||||||
//line templates/readers.qtpl:10
|
//line templates/readers.qtpl:11
|
||||||
qw422016.N().S(`</h1>
|
qw422016.N().S(`</h1>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:11
|
//line templates/readers.qtpl:12
|
||||||
qw422016.N().S(list)
|
qw422016.N().S(list)
|
||||||
//line templates/readers.qtpl:11
|
//line templates/readers.qtpl:12
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
</article>
|
</article>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
}
|
}
|
||||||
|
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
func WriteHistoryHTML(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, list string) {
|
func WriteHistoryHTML(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, list string) {
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
StreamHistoryHTML(qw422016, rq, hyphaName, list)
|
StreamHistoryHTML(qw422016, rq, hyphaName, list)
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
qt422016.ReleaseWriter(qw422016)
|
qt422016.ReleaseWriter(qw422016)
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
}
|
}
|
||||||
|
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
func HistoryHTML(rq *http.Request, hyphaName, list string) string {
|
func HistoryHTML(rq *http.Request, hyphaName, list string) string {
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
qb422016 := qt422016.AcquireByteBuffer()
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
WriteHistoryHTML(qb422016, rq, hyphaName, list)
|
WriteHistoryHTML(qb422016, rq, hyphaName, list)
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
qs422016 := string(qb422016.B)
|
qs422016 := string(qb422016.B)
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
qt422016.ReleaseByteBuffer(qb422016)
|
qt422016.ReleaseByteBuffer(qb422016)
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
return qs422016
|
return qs422016
|
||||||
//line templates/readers.qtpl:15
|
//line templates/readers.qtpl:16
|
||||||
}
|
}
|
||||||
|
|
||||||
//line templates/readers.qtpl:17
|
//line templates/readers.qtpl:18
|
||||||
func StreamRevisionHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, relatives, revHash string) {
|
func StreamRevisionHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, relatives, revHash string) {
|
||||||
//line templates/readers.qtpl:17
|
//line templates/readers.qtpl:18
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:18
|
//line templates/readers.qtpl:19
|
||||||
streamnavHTML(qw422016, rq, hyphaName, "revision", revHash)
|
streamnavHTML(qw422016, rq, hyphaName, "revision", revHash)
|
||||||
//line templates/readers.qtpl:18
|
//line templates/readers.qtpl:19
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
<main class="main-width">
|
<main class="main-width">
|
||||||
<article>
|
<article>
|
||||||
<p>Please note that viewing binary parts of hyphae is not supported in history for now.</p>
|
<p>Please note that viewing binary parts of hyphae is not supported in history for now.</p>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:23
|
//line templates/readers.qtpl:24
|
||||||
qw422016.N().S(naviTitle)
|
qw422016.N().S(naviTitle)
|
||||||
//line templates/readers.qtpl:23
|
//line templates/readers.qtpl:24
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:24
|
//line templates/readers.qtpl:25
|
||||||
qw422016.N().S(contents)
|
qw422016.N().S(contents)
|
||||||
//line templates/readers.qtpl:24
|
//line templates/readers.qtpl:25
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
</article>
|
</article>
|
||||||
</main>
|
</main>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:27
|
//line templates/readers.qtpl:28
|
||||||
streamrelativeHyphae(qw422016, relatives)
|
streamrelativeHyphae(qw422016, relatives)
|
||||||
//line templates/readers.qtpl:27
|
//line templates/readers.qtpl:28
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
</div>
|
</div>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
}
|
}
|
||||||
|
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
func WriteRevisionHTML(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, relatives, revHash string) {
|
func WriteRevisionHTML(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, relatives, revHash string) {
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
StreamRevisionHTML(qw422016, rq, hyphaName, naviTitle, contents, relatives, revHash)
|
StreamRevisionHTML(qw422016, rq, hyphaName, naviTitle, contents, relatives, revHash)
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
qt422016.ReleaseWriter(qw422016)
|
qt422016.ReleaseWriter(qw422016)
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
}
|
}
|
||||||
|
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
func RevisionHTML(rq *http.Request, hyphaName, naviTitle, contents, relatives, revHash string) string {
|
func RevisionHTML(rq *http.Request, hyphaName, naviTitle, contents, relatives, revHash string) string {
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
qb422016 := qt422016.AcquireByteBuffer()
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
WriteRevisionHTML(qb422016, rq, hyphaName, naviTitle, contents, relatives, revHash)
|
WriteRevisionHTML(qb422016, rq, hyphaName, naviTitle, contents, relatives, revHash)
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
qs422016 := string(qb422016.B)
|
qs422016 := string(qb422016.B)
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
qt422016.ReleaseByteBuffer(qb422016)
|
qt422016.ReleaseByteBuffer(qb422016)
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
return qs422016
|
return qs422016
|
||||||
//line templates/readers.qtpl:29
|
//line templates/readers.qtpl:30
|
||||||
}
|
}
|
||||||
|
|
||||||
// If `contents` == "", a helpful message is shown instead.
|
// If `contents` == "", a helpful message is shown instead.
|
||||||
|
|
||||||
//line templates/readers.qtpl:32
|
//line templates/readers.qtpl:33
|
||||||
func StreamPageHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, relatives, prevHyphaName, nextHyphaName string, hasAmnt bool) {
|
func StreamPageHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, relatives, prevHyphaName, nextHyphaName string, hasAmnt bool) {
|
||||||
//line templates/readers.qtpl:32
|
//line templates/readers.qtpl:33
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:33
|
//line templates/readers.qtpl:34
|
||||||
streamnavHTML(qw422016, rq, hyphaName, "page")
|
streamnavHTML(qw422016, rq, hyphaName, "page")
|
||||||
//line templates/readers.qtpl:33
|
//line templates/readers.qtpl:34
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
<main class="main-width">
|
<main class="main-width">
|
||||||
<article>
|
<article>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:37
|
//line templates/readers.qtpl:38
|
||||||
qw422016.N().S(naviTitle)
|
qw422016.N().S(naviTitle)
|
||||||
//line templates/readers.qtpl:37
|
//line templates/readers.qtpl:38
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:38
|
//line templates/readers.qtpl:39
|
||||||
if contents == "" {
|
if contents == "" {
|
||||||
//line templates/readers.qtpl:38
|
//line templates/readers.qtpl:39
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<p>This hypha has no text. Why not <a href="/edit/`)
|
<p>This hypha has no text. Why not <a href="/edit/`)
|
||||||
//line templates/readers.qtpl:39
|
//line templates/readers.qtpl:40
|
||||||
qw422016.E().S(hyphaName)
|
qw422016.E().S(hyphaName)
|
||||||
//line templates/readers.qtpl:39
|
//line templates/readers.qtpl:40
|
||||||
qw422016.N().S(`">create it</a>?</p>
|
qw422016.N().S(`">create it</a>?</p>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:40
|
//line templates/readers.qtpl:41
|
||||||
} else {
|
} else {
|
||||||
//line templates/readers.qtpl:40
|
//line templates/readers.qtpl:41
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:41
|
//line templates/readers.qtpl:42
|
||||||
qw422016.N().S(contents)
|
qw422016.N().S(contents)
|
||||||
//line templates/readers.qtpl:41
|
//line templates/readers.qtpl:42
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:42
|
//line templates/readers.qtpl:43
|
||||||
}
|
}
|
||||||
//line templates/readers.qtpl:42
|
//line templates/readers.qtpl:43
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
</article>
|
</article>
|
||||||
<section class="prevnext">
|
<section class="prevnext">
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:45
|
//line templates/readers.qtpl:46
|
||||||
if prevHyphaName != "" {
|
if prevHyphaName != "" {
|
||||||
//line templates/readers.qtpl:45
|
//line templates/readers.qtpl:46
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<a class="prevnext__el prevnext__prev" href="/page/`)
|
<a class="prevnext__el prevnext__prev" href="/hypha/`)
|
||||||
//line templates/readers.qtpl:46
|
//line templates/readers.qtpl:47
|
||||||
qw422016.E().S(prevHyphaName)
|
qw422016.E().S(prevHyphaName)
|
||||||
//line templates/readers.qtpl:46
|
//line templates/readers.qtpl:47
|
||||||
qw422016.N().S(`" rel="prev">← `)
|
qw422016.N().S(`" rel="prev">← `)
|
||||||
//line templates/readers.qtpl:46
|
//line templates/readers.qtpl:47
|
||||||
qw422016.E().S(path.Base(prevHyphaName))
|
qw422016.E().S(util.BeautifulName(path.Base(prevHyphaName)))
|
||||||
//line templates/readers.qtpl:46
|
//line templates/readers.qtpl:47
|
||||||
qw422016.N().S(`</a>
|
qw422016.N().S(`</a>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:47
|
//line templates/readers.qtpl:48
|
||||||
}
|
}
|
||||||
//line templates/readers.qtpl:47
|
//line templates/readers.qtpl:48
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:48
|
//line templates/readers.qtpl:49
|
||||||
if nextHyphaName != "" {
|
if nextHyphaName != "" {
|
||||||
//line templates/readers.qtpl:48
|
//line templates/readers.qtpl:49
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<a class="prevnext__el prevnext__next" href="/page/`)
|
<a class="prevnext__el prevnext__next" href="/hypha/`)
|
||||||
//line templates/readers.qtpl:49
|
//line templates/readers.qtpl:50
|
||||||
qw422016.E().S(nextHyphaName)
|
qw422016.E().S(nextHyphaName)
|
||||||
//line templates/readers.qtpl:49
|
//line templates/readers.qtpl:50
|
||||||
qw422016.N().S(`" rel="next">`)
|
qw422016.N().S(`" rel="next">`)
|
||||||
//line templates/readers.qtpl:49
|
//line templates/readers.qtpl:50
|
||||||
qw422016.E().S(path.Base(nextHyphaName))
|
qw422016.E().S(util.BeautifulName(path.Base(nextHyphaName)))
|
||||||
//line templates/readers.qtpl:49
|
//line templates/readers.qtpl:50
|
||||||
qw422016.N().S(` →</a>
|
qw422016.N().S(` →</a>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:50
|
//line templates/readers.qtpl:51
|
||||||
}
|
}
|
||||||
//line templates/readers.qtpl:50
|
//line templates/readers.qtpl:51
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
</section>
|
</section>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:52
|
//line templates/readers.qtpl:53
|
||||||
if u := user.FromRequest(rq); !user.AuthUsed || u.Group != "anon" {
|
if u := user.FromRequest(rq); !user.AuthUsed || u.Group != "anon" {
|
||||||
//line templates/readers.qtpl:52
|
//line templates/readers.qtpl:53
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<form action="/upload-binary/`)
|
<form action="/upload-binary/`)
|
||||||
//line templates/readers.qtpl:53
|
//line templates/readers.qtpl:54
|
||||||
qw422016.E().S(hyphaName)
|
qw422016.E().S(hyphaName)
|
||||||
//line templates/readers.qtpl:53
|
//line templates/readers.qtpl:54
|
||||||
qw422016.N().S(`"
|
qw422016.N().S(`"
|
||||||
method="post" enctype="multipart/form-data"
|
method="post" enctype="multipart/form-data"
|
||||||
class="upload-amnt">
|
class="upload-amnt">
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:56
|
//line templates/readers.qtpl:57
|
||||||
if hasAmnt {
|
if hasAmnt {
|
||||||
//line templates/readers.qtpl:56
|
//line templates/readers.qtpl:57
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<a class="upload-amnt__unattach" href="/unattach-ask/`)
|
<a class="upload-amnt__unattach" href="/unattach-ask/`)
|
||||||
//line templates/readers.qtpl:57
|
//line templates/readers.qtpl:58
|
||||||
qw422016.E().S(hyphaName)
|
qw422016.E().S(hyphaName)
|
||||||
//line templates/readers.qtpl:57
|
//line templates/readers.qtpl:58
|
||||||
qw422016.N().S(`">Unattach current attachment?</a>
|
qw422016.N().S(`">Unattach current attachment?</a>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:58
|
//line templates/readers.qtpl:59
|
||||||
}
|
}
|
||||||
//line templates/readers.qtpl:58
|
//line templates/readers.qtpl:59
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
<label for="upload-binary__input">Upload a new attachment</label>
|
<label for="upload-binary__input">Upload a new attachment</label>
|
||||||
<br>
|
<br>
|
||||||
@ -260,43 +263,43 @@ func StreamPageHTML(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, navi
|
|||||||
<input type="submit"/>
|
<input type="submit"/>
|
||||||
</form>
|
</form>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:64
|
//line templates/readers.qtpl:65
|
||||||
}
|
}
|
||||||
//line templates/readers.qtpl:64
|
//line templates/readers.qtpl:65
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
</main>
|
</main>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:66
|
//line templates/readers.qtpl:67
|
||||||
streamrelativeHyphae(qw422016, relatives)
|
streamrelativeHyphae(qw422016, relatives)
|
||||||
//line templates/readers.qtpl:66
|
//line templates/readers.qtpl:67
|
||||||
qw422016.N().S(`
|
qw422016.N().S(`
|
||||||
</div>
|
</div>
|
||||||
`)
|
`)
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
}
|
}
|
||||||
|
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
func WritePageHTML(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, relatives, prevHyphaName, nextHyphaName string, hasAmnt bool) {
|
func WritePageHTML(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, naviTitle, contents, relatives, prevHyphaName, nextHyphaName string, hasAmnt bool) {
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
qw422016 := qt422016.AcquireWriter(qq422016)
|
qw422016 := qt422016.AcquireWriter(qq422016)
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
StreamPageHTML(qw422016, rq, hyphaName, naviTitle, contents, relatives, prevHyphaName, nextHyphaName, hasAmnt)
|
StreamPageHTML(qw422016, rq, hyphaName, naviTitle, contents, relatives, prevHyphaName, nextHyphaName, hasAmnt)
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
qt422016.ReleaseWriter(qw422016)
|
qt422016.ReleaseWriter(qw422016)
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
}
|
}
|
||||||
|
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
func PageHTML(rq *http.Request, hyphaName, naviTitle, contents, relatives, prevHyphaName, nextHyphaName string, hasAmnt bool) string {
|
func PageHTML(rq *http.Request, hyphaName, naviTitle, contents, relatives, prevHyphaName, nextHyphaName string, hasAmnt bool) string {
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
qb422016 := qt422016.AcquireByteBuffer()
|
qb422016 := qt422016.AcquireByteBuffer()
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
WritePageHTML(qb422016, rq, hyphaName, naviTitle, contents, relatives, prevHyphaName, nextHyphaName, hasAmnt)
|
WritePageHTML(qb422016, rq, hyphaName, naviTitle, contents, relatives, prevHyphaName, nextHyphaName, hasAmnt)
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
qs422016 := string(qb422016.B)
|
qs422016 := string(qb422016.B)
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
qt422016.ReleaseByteBuffer(qb422016)
|
qt422016.ReleaseByteBuffer(qb422016)
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
return qs422016
|
return qs422016
|
||||||
//line templates/readers.qtpl:68
|
//line templates/readers.qtpl:69
|
||||||
}
|
}
|
||||||
|
198
tree/tree.go
198
tree/tree.go
@ -9,100 +9,122 @@ import (
|
|||||||
"github.com/bouncepaw/mycorrhiza/util"
|
"github.com/bouncepaw/mycorrhiza/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// If Name == "", the tree is empty.
|
type sibling struct {
|
||||||
type tree struct {
|
name string
|
||||||
name string
|
hasChildren bool
|
||||||
exists bool
|
}
|
||||||
prevSibling string
|
|
||||||
nextSibling string
|
func (s *sibling) checkThisChild(hyphaName string) {
|
||||||
siblings []string
|
if !s.hasChildren && path.Dir(hyphaName) == s.name {
|
||||||
descendants []*tree
|
s.hasChildren = true
|
||||||
root bool
|
}
|
||||||
hyphaIterator func(func(string))
|
}
|
||||||
|
|
||||||
|
func (s *sibling) asHTML() string {
|
||||||
|
class := "navitree__entry navitree__sibling"
|
||||||
|
if s.hasChildren {
|
||||||
|
class += " navitree__sibling_fertile navitree__entry_fertile"
|
||||||
|
} else {
|
||||||
|
class += " navitree__sibling_infertile navitree__entry_infertile"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(
|
||||||
|
`<li class="%s"><a class="navitree__link" href="/hypha/%s">%s</a></li>`,
|
||||||
|
class,
|
||||||
|
s.name,
|
||||||
|
util.BeautifulName(path.Base(s.name)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type mainFamilyMember struct {
|
||||||
|
name string
|
||||||
|
children []*mainFamilyMember
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mainFamilyMember) checkThisChild(hyphaName string) (adopted bool) {
|
||||||
|
if path.Dir(hyphaName) == m.name {
|
||||||
|
m.children = append(m.children, &mainFamilyMember{
|
||||||
|
name: hyphaName,
|
||||||
|
children: make([]*mainFamilyMember, 0),
|
||||||
|
})
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mainFamilyMember) asHTML() string {
|
||||||
|
if len(m.children) == 0 {
|
||||||
|
return fmt.Sprintf(`<li class="navitree__entry navitree__entry_infertile navitree__trunk navitree__trunk_infertile"><a class="navitree__link" href="/hypha/%s">%s</a></li>`, m.name, util.BeautifulName(path.Base(m.name)))
|
||||||
|
}
|
||||||
|
sort.Slice(m.children, func(i, j int) bool {
|
||||||
|
return m.children[i].name < m.children[j].name
|
||||||
|
})
|
||||||
|
html := fmt.Sprintf(`<li class="navitree__entry navitree__entry_fertile navitree__trunk navitree__trunk_fertile"><a class="navitree__link" href="/hypha/%s">%s</a><ul>`, m.name, util.BeautifulName(path.Base(m.name)))
|
||||||
|
for _, child := range m.children {
|
||||||
|
html += child.asHTML()
|
||||||
|
}
|
||||||
|
return html + `</li></ul></li>`
|
||||||
|
}
|
||||||
|
|
||||||
|
func mainFamilyFromPool(hyphaName string, subhyphaePool map[string]bool) *mainFamilyMember {
|
||||||
|
var (
|
||||||
|
nestLevel = strings.Count(hyphaName, "/")
|
||||||
|
adopted = make([]*mainFamilyMember, 0)
|
||||||
|
)
|
||||||
|
for subhyphaName, _ := range subhyphaePool {
|
||||||
|
subnestLevel := strings.Count(subhyphaName, "/")
|
||||||
|
if subnestLevel-1 == nestLevel && path.Dir(subhyphaName) == hyphaName {
|
||||||
|
delete(subhyphaePool, subhyphaName)
|
||||||
|
adopted = append(adopted, mainFamilyFromPool(subhyphaName, subhyphaePool))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &mainFamilyMember{name: hyphaName, children: adopted}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tree generates a tree for `hyphaName` as html and returns next and previous hyphae if any.
|
// Tree generates a tree for `hyphaName` as html and returns next and previous hyphae if any.
|
||||||
func Tree(hyphaName string, hyphaIterator func(func(string))) (html, prev, next string) {
|
func Tree(hyphaName string, hyphaIterator func(func(string))) (html, prev, next string) {
|
||||||
t := &tree{name: hyphaName, root: true, hyphaIterator: hyphaIterator}
|
var (
|
||||||
t.fill()
|
// One of the siblings is the hypha with name `hyphaName`
|
||||||
return t.asHtml(), util.BeautifulName(t.prevSibling), util.BeautifulName(t.nextSibling)
|
siblings = findSiblings(hyphaName, hyphaIterator)
|
||||||
}
|
subhyphaePool = make(map[string]bool)
|
||||||
|
I int
|
||||||
// subtree adds a descendant tree to `t` and returns that tree.
|
)
|
||||||
func (t *tree) fork(descendantName string) *tree {
|
hyphaIterator(func(otherHyphaName string) {
|
||||||
subt := &tree{
|
for _, s := range siblings {
|
||||||
name: descendantName,
|
s.checkThisChild(otherHyphaName)
|
||||||
root: false,
|
|
||||||
hyphaIterator: t.hyphaIterator,
|
|
||||||
}
|
|
||||||
t.descendants = append(t.descendants, subt)
|
|
||||||
return subt
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare current prev next hyphae and decide if any of them should be set to `name2`.
|
|
||||||
func (t *tree) prevNextDetermine(name2 string) {
|
|
||||||
if name2 < t.name && (name2 > t.prevSibling || t.prevSibling == "") {
|
|
||||||
t.prevSibling = name2
|
|
||||||
} else if name2 > t.name && (name2 < t.nextSibling || t.nextSibling == "") {
|
|
||||||
t.nextSibling = name2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compares names and does something with them, may generate a subtree.
|
|
||||||
func (t *tree) compareNamesAndAppend(name2 string) {
|
|
||||||
switch {
|
|
||||||
case t.name == name2:
|
|
||||||
t.exists = true
|
|
||||||
case t.root && path.Dir(t.name) == path.Dir(name2):
|
|
||||||
t.prevNextDetermine(name2)
|
|
||||||
t.siblings = append(t.siblings, name2)
|
|
||||||
case t.name == path.Dir(name2):
|
|
||||||
t.fork(name2).fill()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fills t.siblings and t.descendants, sorts them and does the same to the descendants.
|
|
||||||
func (t *tree) fill() {
|
|
||||||
t.hyphaIterator(func(hyphaName string) {
|
|
||||||
t.compareNamesAndAppend(hyphaName)
|
|
||||||
})
|
|
||||||
sort.Strings(t.siblings)
|
|
||||||
sort.Slice(t.descendants, func(i, j int) bool {
|
|
||||||
return t.descendants[i].name < t.descendants[j].name
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// asHtml returns HTML representation of a tree.
|
|
||||||
// It applies itself recursively on the tree's children.
|
|
||||||
func (t *tree) asHtml() (html string) {
|
|
||||||
if t.root {
|
|
||||||
html += navitreeEntry(t.name, "navitree__pagename")
|
|
||||||
} else {
|
|
||||||
html += navitreeEntry(t.name, "navitree__name")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, subtree := range t.descendants {
|
|
||||||
html += subtree.asHtml()
|
|
||||||
}
|
|
||||||
|
|
||||||
if t.root {
|
|
||||||
for _, siblingName := range t.siblings {
|
|
||||||
html += navitreeEntry(siblingName, "navitree__sibling")
|
|
||||||
}
|
}
|
||||||
|
if strings.HasPrefix(otherHyphaName, hyphaName+"/") {
|
||||||
|
subhyphaePool[otherHyphaName] = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
for i, s := range siblings {
|
||||||
|
if s.name == hyphaName {
|
||||||
|
I = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
html += s.asHTML()
|
||||||
}
|
}
|
||||||
|
html += mainFamilyFromPool(hyphaName, subhyphaePool).asHTML()
|
||||||
return `<ul class="navitree__node">` + html + `</ul>`
|
for _, s := range siblings[I+1:] {
|
||||||
|
html += s.asHTML()
|
||||||
|
}
|
||||||
|
if I != 0 {
|
||||||
|
prev = siblings[I-1].name
|
||||||
|
}
|
||||||
|
if I != len(siblings)-1 {
|
||||||
|
next = siblings[I+1].name
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(`<ul class="navitree">%s</ul>`, html), prev, next
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strip hypha name from all ancestor names, replace _ with spaces, title case
|
func findSiblings(hyphaName string, hyphaIterator func(func(string))) []*sibling {
|
||||||
func beautifulName(uglyName string) string {
|
siblings := []*sibling{&sibling{name: hyphaName, hasChildren: true}}
|
||||||
return strings.Title(strings.ReplaceAll(path.Base(uglyName), "_", " "))
|
hyphaIterator(func(otherHyphaName string) {
|
||||||
}
|
if path.Dir(hyphaName) == path.Dir(otherHyphaName) && hyphaName != otherHyphaName {
|
||||||
|
siblings = append(siblings, &sibling{name: otherHyphaName, hasChildren: false})
|
||||||
// navitreeEntry is a small utility function that makes generating html easier.
|
}
|
||||||
func navitreeEntry(name, class string) string {
|
})
|
||||||
return fmt.Sprintf(`<li class="navitree__entry %s">
|
sort.Slice(siblings, func(i, j int) bool {
|
||||||
<a class="navitree__link" href="/page/%s">%s</a>
|
return siblings[i].name < siblings[j].name
|
||||||
</li>
|
})
|
||||||
`, class, name, beautifulName(name))
|
return siblings
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user