diff options
author | Paweł Marks <pmarks@virtuslab.com> | 2020-02-03 08:42:32 +0100 |
---|---|---|
committer | Paweł Marks <Kordyjan@users.noreply.github.com> | 2020-02-04 14:42:44 +0100 |
commit | 8a354b5d9156088b35031d861fd8a7ff31c55d9b (patch) | |
tree | d7ed029b4ec2fdb8e4a1ede36415a7ffed94b308 | |
parent | d68c95e31878acb01b93070ddd9014cd1ed70b26 (diff) | |
download | dokka-8a354b5d9156088b35031d861fd8a7ff31c55d9b.tar.gz dokka-8a354b5d9156088b35031d861fd8a7ff31c55d9b.tar.bz2 dokka-8a354b5d9156088b35031d861fd8a7ff31c55d9b.zip |
Implementation of transformable navigation
5 files changed, 107 insertions, 19 deletions
diff --git a/core/src/main/kotlin/plugability/DefaultExtensions.kt b/core/src/main/kotlin/plugability/DefaultExtensions.kt index 9f36b2a4..c62bdd41 100644 --- a/core/src/main/kotlin/plugability/DefaultExtensions.kt +++ b/core/src/main/kotlin/plugability/DefaultExtensions.kt @@ -12,7 +12,12 @@ import org.jetbrains.dokka.transformers.psi.DefaultPsiToDocumentationTranslator internal object DefaultExtensions { - private val renderer: LazyEvaluated<HtmlRenderer> = LazyEvaluated.fromRecipe { HtmlRenderer(it.single(CoreExtensions.outputWriter), it) } + private val renderer: LazyEvaluated<HtmlRenderer> = LazyEvaluated.fromRecipe { + HtmlRenderer( + it.single(CoreExtensions.outputWriter), + it + ) + } private val converter: LazyEvaluated<DocTagToContentConverter> = LazyEvaluated.fromRecipe { DocTagToContentConverter(it) } private val providerFactory: LazyEvaluated<DefaultLocationProviderFactory> = LazyEvaluated.fromRecipe { DefaultLocationProviderFactory(it) } diff --git a/core/src/main/kotlin/renderers/html/HtmlRenderer.kt b/core/src/main/kotlin/renderers/html/HtmlRenderer.kt index d0738289..d5dfb827 100644 --- a/core/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/core/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -2,11 +2,13 @@ package org.jetbrains.dokka.renderers.html import kotlinx.html.* import kotlinx.html.stream.createHTML +import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.Function import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.renderers.DefaultRenderer import org.jetbrains.dokka.renderers.OutputWriter +import org.jetbrains.dokka.transformers.pages.PageNodeTransformer import java.io.File open class HtmlRenderer( @@ -20,7 +22,7 @@ open class HtmlRenderer( RootCreator, SearchPageInstaller, ResourceInstaller, - NavigationInstaller, + NavigationPageInstaller, StyleAndScriptsAppender ) @@ -112,6 +114,13 @@ open class HtmlRenderer( text(to.name) } + fun FlowContent.buildLink( + to: DRI, + platforms: List<PlatformData>, + from: PageNode? = null, + block: FlowContent.() -> Unit + ) = buildLink(locationProvider.resolve(to, platforms, from), block) + override fun buildError(node: ContentNode) { context.logger.error("Unknown ContentNode type: $node") } @@ -166,6 +175,7 @@ open class HtmlRenderer( filter { it.substringBefore('?').substringAfterLast('.') == "js" } .forEach { script(type = ScriptType.textJavaScript, src = it) { async = true } } } + script { unsafe { +"""var pathToRoot = "${locationProvider.resolveRoot(page)}";""" } } } body { div { diff --git a/core/src/main/kotlin/renderers/html/NavigationPage.kt b/core/src/main/kotlin/renderers/html/NavigationPage.kt new file mode 100644 index 00000000..4a2fb40d --- /dev/null +++ b/core/src/main/kotlin/renderers/html/NavigationPage.kt @@ -0,0 +1,50 @@ +package org.jetbrains.dokka.renderers.html + +import kotlinx.html.* +import kotlinx.html.stream.createHTML +import org.jetbrains.dokka.links.DRI +import org.jetbrains.dokka.pages.PageNode +import org.jetbrains.dokka.pages.PlatformData +import org.jetbrains.dokka.pages.RendererSpecificPage +import org.jetbrains.dokka.pages.RenderingStrategy + +class NavigationPage(val root: NavigationNode) : RendererSpecificPage { + override val name = "navigation" + + override val children = emptyList<PageNode>() + + override fun modified(name: String, children: List<PageNode>) = this + + override val strategy = RenderingStrategy<HtmlRenderer> { + createHTML().visit(root, "nav-submenu", this) + } + + private fun <R> TagConsumer<R>.visit(node: NavigationNode, navId: String, renderer: HtmlRenderer): R = + with(renderer) { + div("sideMenuPart") { + id = navId + div("overview") { + buildLink(node.dri, node.platforms) { +node.name } + if (node.children.isNotEmpty()) { + span("navButton") { + onClick = """document.getElementById("$navId").classList.toggle("hidden");""" + span("navButtonContent") + } + } + } + node.children.withIndex().forEach { (n, p) -> visit(p, "$navId-$n", renderer) } + } + } +} + +class NavigationNode( + val name: String, + val dri: DRI, + val platforms: List<PlatformData>, + val children: List<NavigationNode> +) + +fun NavigationPage.transform(block: (NavigationNode) -> NavigationNode) = NavigationPage(root.transform(block)) + +fun NavigationNode.transform(block: (NavigationNode) -> NavigationNode) = + run(block).let { NavigationNode(it.name, it.dri, it.platforms, it.children.map(block)) } diff --git a/core/src/main/kotlin/renderers/html/htmlPreprocessors.kt b/core/src/main/kotlin/renderers/html/htmlPreprocessors.kt index 382cb204..22856368 100644 --- a/core/src/main/kotlin/renderers/html/htmlPreprocessors.kt +++ b/core/src/main/kotlin/renderers/html/htmlPreprocessors.kt @@ -4,10 +4,8 @@ import kotlinx.html.h1 import kotlinx.html.id import kotlinx.html.table import kotlinx.html.tbody -import org.jetbrains.dokka.pages.RendererSpecificResourcePage -import org.jetbrains.dokka.pages.RendererSpecificRootPage -import org.jetbrains.dokka.pages.RenderingStrategy -import org.jetbrains.dokka.pages.RootPageNode +import org.jetbrains.dokka.pages.* +import org.jetbrains.dokka.renderers.platforms import org.jetbrains.dokka.transformers.pages.PageNodeTransformer object RootCreator : PageNodeTransformer { @@ -19,22 +17,35 @@ object SearchPageInstaller : PageNodeTransformer { override fun invoke(input: RootPageNode) = input.modified(children = input.children + searchPage) private val searchPage = RendererSpecificResourcePage( - name = "Search", - children = emptyList(), - strategy = RenderingStrategy<HtmlRenderer> { - buildHtml(it, listOf("styles/style.css", "scripts/pages.js")) { - h1 { - id = "searchTitle" - text("Search results for ") - } - table { - tbody { - id = "searchTable" - } + name = "Search", + children = emptyList(), + strategy = RenderingStrategy<HtmlRenderer> { + buildHtml(it, listOf("styles/style.css", "scripts/pages.js")) { + h1 { + id = "searchTitle" + text("Search results for ") + } + table { + tbody { + id = "searchTable" } } - }) + } + }) +} + +object NavigationPageInstaller : PageNodeTransformer { + override fun invoke(input: RootPageNode) = input.modified( + children = input.children + NavigationPage( + input.children.filterIsInstance<ContentPage>().single().let(::visit) + ) + ) + private fun visit(page: ContentPage): NavigationNode = NavigationNode( + page.name, + page.dri, + page.platforms(), + page.children.filterIsInstance<ContentPage>().map { visit(it) }) } object ResourceInstaller : PageNodeTransformer { diff --git a/core/src/main/resources/dokka/scripts/navigationLoader.js b/core/src/main/resources/dokka/scripts/navigationLoader.js index e69de29b..d79203f2 100644 --- a/core/src/main/resources/dokka/scripts/navigationLoader.js +++ b/core/src/main/resources/dokka/scripts/navigationLoader.js @@ -0,0 +1,12 @@ +onload = () => { + fetch(pathToRoot + "navigation") + .then(response => response.text()) + .then(data => { + document.getElementById("sideMenu").innerHTML = data; + }).then(() => { + document.querySelectorAll(".overview > a").forEach(link => { + link.setAttribute("href", pathToRoot + link.getAttribute("href")) + console.log(link.attributes["href"]) + }) + }) +}
\ No newline at end of file |