Skip to content

Commit

Permalink
Merge pull request #14607 from dotty-staging/scaladoc/rhs-table-of-co…
Browse files Browse the repository at this point in the history
…ntent

Add table of content to static sites
  • Loading branch information
pikinier20 authored Mar 17, 2022
2 parents 21a5401 + cd39061 commit 1a5b165
Show file tree
Hide file tree
Showing 21 changed files with 314 additions and 60 deletions.
4 changes: 0 additions & 4 deletions docs/_layouts/doc-page.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,5 @@ <h1>{{ page.title }}</h1>
{% endif %}
</header>
{{ content }}
<div class="content-contributors hidden">
<h5>Contributors to this page:</h5>
<div id="documentation-contributors" class="contributors-container"></div>
</div>
</main>

10 changes: 8 additions & 2 deletions docs/_layouts/static-site-main.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,20 @@
{{ content }}
<nav class="arrows-wrapper" aria-label="Page navigation">
{% if page.previous %}
<a rel="prev" href="{{ page.previous }}" class="arrows previous" aria-keyshortcuts="Left">
<a rel="prev" href="{{ page.previous.url }}" class="arrows previous" aria-keyshortcuts="Left">
<span>{{ page.previous.title }}</span>
<i class="fa fa-angle-left"></i>
</a>
{% endif %}
{% if page.next %}
<a rel="next" href="{{ page.next }}" class="arrows next" aria-keyshortcuts="Right">
<a rel="next" href="{{ page.next.url }}" class="arrows next" aria-keyshortcuts="Right">
<span>{{ page.next.title }}</span>
<i class="fa fa-angle-right"></i>
</a>
{% endif %}
</nav>
<div class="content-contributors hidden">
<span><b>Contributors to this page</b></span>
<div id="documentation-contributors" class="contributors-container"></div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,20 @@
{{ content }}
<nav class="arrows-wrapper" aria-label="Page navigation">
{% if page.previous %}
<a rel="prev" href="{{ page.previous }}" class="arrows previous" aria-keyshortcuts="Left">
<a rel="prev" href="{{ page.previous.url }}" class="arrows previous" aria-keyshortcuts="Left">
<span>{{ page.previous.title }}</span>
<i class="fa fa-angle-left"></i>
</a>
{% endif %}
{% if page.next %}
<a rel="next" href="{{ page.next }}" class="arrows next" aria-keyshortcuts="Right">
<a rel="next" href="{{ page.next.url }}" class="arrows next" aria-keyshortcuts="Right">
<span>{{ page.next.title }}</span>
<i class="fa fa-angle-right"></i>
</a>
{% endif %}
</nav>
<div class="content-contributors hidden">
<span><b>Contributors to this page</b></span>
<div id="documentation-contributors" class="contributors-container"></div>
</div>
</div>
3 changes: 3 additions & 0 deletions scaladoc-testcases/docs/_docs/docs/f5.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<h1>Header 1</h1>
<h2>Header 2</h2>
<h3>Header 3</h3>
10 changes: 8 additions & 2 deletions scaladoc-testcases/docs/_layouts/static-site-main.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@
{{ content }}
<nav class="arrows-wrapper" aria-label="Page navigation">
{% if page.previous %}
<a rel="prev" href="{{ page.previous }}" class="arrows previous" aria-keyshortcuts="Left">
<a rel="prev" href="{{ page.previous.url }}" class="arrows previous" aria-keyshortcuts="Left">
<span>{{ page.previous.title }}</span>
<i class="fa fa-angle-left"></i>
</a>
{% endif %}
{% if page.next %}
<a rel="next" href="{{ page.next }}" class="arrows next" aria-keyshortcuts="Right">
<a rel="next" href="{{ page.next.url }}" class="arrows next" aria-keyshortcuts="Right">
<span>{{ page.next.title }}</span>
<i class="fa fa-angle-right"></i>
</a>
{% endif %}
</nav>
<div class="content-contributors hidden">
<span><b>Contributors to this page</b></span>
<div id="documentation-contributors" class="contributors-container"></div>
</div>
</div>
1 change: 1 addition & 0 deletions scaladoc-testcases/docs/sidebar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ subsection:
- page: docs/f2.md
- page: docs/f3.md
- page: docs/f4.md
- page: docs/f5.html
16 changes: 16 additions & 0 deletions scaladoc/resources/dotty_res/scripts/ux.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ window.addEventListener("DOMContentLoaded", () => {
$(this).parent().toggleClass("expanded")
});

const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
const id = entry.target.getAttribute('id');
if (entry.intersectionRatio > 0) {
document.querySelector(`#toc li a[href="#${id}"]`).parentElement.classList.add('active');
} else {
document.querySelector(`#toc li a[href="#${id}"]`).parentElement.classList.remove('active');
}
});
});


document.querySelectorAll('#content section[id]').forEach((section) => {
observer.observe(section);
});

document.querySelectorAll("#sideMenu2 a").forEach(elem => elem.addEventListener('click', e => e.stopPropagation()))

$('.names .tab').on('click', function() {
Expand Down
88 changes: 72 additions & 16 deletions scaladoc/resources/dotty_res/styles/scalastyle.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

/* Layout Settings (changes on small screens) */
--side-width: 300px;
--toc-width: 300px;
--content-padding: 24px 42px;
--footer-height: 42px;
}
Expand Down Expand Up @@ -43,6 +44,7 @@ body, button, input {
#main-content {
min-height: calc(100vh - var(--footer-height) - 24px);
margin-left: var(--side-width);
margin-right: var(--toc-width);
padding: var(--content-padding);
padding-bottom: calc(24px + var(--footer-height));

Expand Down Expand Up @@ -905,6 +907,46 @@ footer .socials {
height: 8px;
}

#toc {
position: fixed;
right: 0px;
top: 0px;
width: var(--toc-width);
height: 100%;

padding-top: 15vh;
padding-right: 10px;

display: flex;
flex-direction: column;
}

#toc .toc-title {
font-weight: bold;
padding-left: 16px;
}

#toc ul {
list-style-type: none;
padding-left: 16px;
}

#toc a {
display: block;
padding-top: 0.5em;
padding-bottom: 0.5em;
color: var(--leftbar-fg);
transition-duration: 0.2s;
}

#toc li:hover > a {
color: var(--link-hover-fg);
}

#toc li.active > a {
color: var(--link-hover-fg);
}

/* Signature coloring */

:root {
Expand Down Expand Up @@ -941,6 +983,12 @@ footer .socials {
}
}
/* Landscape phones, portait tablets */
@media(max-width: 1200px) {
:root {
--toc-width: 0px;
}
}

@media(max-width: 768px) {
:root {
--content-padding: 12px 12px;
Expand Down Expand Up @@ -1070,43 +1118,51 @@ footer .socials {

/* Nav Icons */

.arrows-wrapper {
display: flex;
justify-content: space-between;
padding-top: 16px;
padding-bottom: 16px;
}

.arrows {
font-size: 3em;
color: var(--link-fg);
font-size: 1em;
text-align: center;

position: fixed;
top: 0;
bottom: 0;
margin: 0;
max-width: 150px;
min-width: 90px;

display: flex;
justify-content: center;
flex-direction: column;
align-items: center;

transition: color 0.5s, background-color 0.5s;
}

.arrows span {
max-width: 10vw;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}

.arrows i {
margin: 8px;
}

.arrows.previous, .arrows.next {
color: var(--grey400);
}

.arrows:hover {
text-decoration: none;
color: var(--grey300);
background-color: var(--grey900);
color: var(--link-hover-fg);
transition: background-color 0.15s, color 0.15s;
}

.previous {
left: var(--side-width);
float: left;
flex-direction: row-reverse;
}

.next {
right: 0;
float: right;
flex-direction: row;
}

@media screen and (max-width: 1000px) {
Expand Down
16 changes: 16 additions & 0 deletions scaladoc/src/dotty/tools/scaladoc/api.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dotty.tools.scaladoc

import dotty.tools.scaladoc.tasty.comments.Comment
import util.HTML.AppliedTag

enum Visibility(val name: String):
case Unrestricted extends Visibility("")
Expand Down Expand Up @@ -258,3 +259,18 @@ case class SnippetCompilerData(
imports: List[String],
position: SnippetCompilerData.Position
)

case class PageContent(content: AppliedTag, toc: Seq[TocEntry])

case class TocEntry(level: Int, content: String, anchor: String)

object TocEntry:
val tagLevels: Map[String, Int] = Map(
("h1" -> 1),
("h2" -> 2),
("h3" -> 3),
("h4" -> 4),
("h5" -> 5),
("h6" -> 6)
)
def apply(tag: String, content: String, anchor: String): TocEntry = TocEntry(tagLevels(tag), content, anchor)
30 changes: 26 additions & 4 deletions scaladoc/src/dotty/tools/scaladoc/renderers/HtmlRenderer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do
html(
mkHead(page),
body(
if !page.hasFrame then renderContent(page)
if !page.hasFrame then renderContent(page).content
else mkFrame(page.link, parents, renderContent(page))
)
)
Expand Down Expand Up @@ -148,7 +148,23 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do
)
}

private def mkFrame(link: Link, parents: Vector[Link], content: => AppliedTag): AppliedTag =
private def renderTableOfContents(toc: Seq[TocEntry]): Option[AppliedTag] =
def renderTocRec(level: Int, rest: Seq[TocEntry]): Seq[AppliedTag] =
rest match {
case Nil => Nil
case head :: tail if head.level == level =>
val (nested, rest) = tail.span(_.level > level)
val nestedList = if nested.nonEmpty then Seq(ul(renderTocRec(level + 1, nested))) else Nil
li(a(href := head.anchor)(head.content), nestedList) +: renderTocRec(level, rest)
case rest @ (head :: tail) if head.level > level =>
val (prefix, suffix) = rest.span(_.level > level)
li(ul(renderTocRec(level + 1, prefix))) +: renderTocRec(level, suffix)
}

renderTocRec(1, toc).headOption.map(toc => nav(cls := "toc-nav")(ul(cls := "toc-list")(toc)))


private def mkFrame(link: Link, parents: Vector[Link], content: => PageContent): AppliedTag =
val projectLogo =
args.projectLogo.map { path =>
val fileName = Paths.get(path).getFileName()
Expand Down Expand Up @@ -202,7 +218,7 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do
div(id := "scaladoc-searchBar"),
main(id := "main-content")(
parentsHtml,
div(id := "content")(content),
div(id := "content")(content.content),
),
footer(
div(id := "generated-by")(
Expand Down Expand Up @@ -239,5 +255,11 @@ class HtmlRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx: Do
)
)
)
)
),
renderTableOfContents(content.toc).fold(Nil) { toc =>
div(id := "toc")(
span(cls := "toc-title")("In this article"),
toc
)
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class MarkdownRenderer(rootPackage: Member, members: Map[DRI, Member])(using ctx
super.render()

override def pageContent(page: Page, parents: Vector[Link]): AppliedTag =
renderContent(page)
renderContent(page).content

private def renderResources(): Seq[String] =
allResources(Nil).flatMap(renderResource)
18 changes: 10 additions & 8 deletions scaladoc/src/dotty/tools/scaladoc/renderers/MemberRenderer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ class MemberRenderer(signatureRenderer: SignatureRenderer)(using DocContext) ext
div(cls := "filterLowerContainer")()
)

def fullMember(m: Member): AppliedTag =
def fullMember(m: Member): PageContent =
val intro = m.kind match
case Kind.RootPackage =>Seq(h1(summon[DocContext].args.name))
case _ =>
Expand All @@ -401,11 +401,13 @@ class MemberRenderer(signatureRenderer: SignatureRenderer)(using DocContext) ext
memberSignature(m)
)
)

div(
intro,
memberInfo(m, withBrief = false),
classLikeParts(m),
buildDocumentableFilter, // TODO Need to make it work in JS :(
buildMembers(m)
PageContent(
div(
intro,
memberInfo(m, withBrief = false),
classLikeParts(m),
buildDocumentableFilter, // TODO Need to make it work in JS :(
buildMembers(m)
),
Seq.empty // For now, we don't support table of contents in members
)
Loading

0 comments on commit 1a5b165

Please sign in to comment.