diff options
Diffstat (limited to 'plugins')
5 files changed, 120 insertions, 135 deletions
diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index 26560e4f..8ae4628f 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -6,10 +6,8 @@ import org.jetbrains.dokka.DokkaSourceSetID import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.DokkaBaseConfiguration import org.jetbrains.dokka.base.DokkaBaseConfiguration.Companion.defaultFooterMessage -import org.jetbrains.dokka.base.renderers.DefaultRenderer -import org.jetbrains.dokka.base.renderers.TabSortingStrategy +import org.jetbrains.dokka.base.renderers.* import org.jetbrains.dokka.base.renderers.html.command.consumers.ImmediateResolutionTagConsumer -import org.jetbrains.dokka.base.renderers.isImage import org.jetbrains.dokka.base.renderers.pageId import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint import org.jetbrains.dokka.base.resolvers.local.DokkaBaseLocationProvider @@ -23,6 +21,7 @@ import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.pages.HtmlContent import org.jetbrains.dokka.plugability.* import org.jetbrains.dokka.utilities.htmlEscape +import org.jetbrains.kotlin.utils.addIfNotNull import java.net.URI open class HtmlRenderer( @@ -169,13 +168,13 @@ open class HtmlRenderer( nodes: Map<DisplaySourceSet, Collection<ContentNode>>, pageContext: ContentPage, extra: PropertyContainer<ContentNode> = PropertyContainer.empty(), - styles: Set<Style> = emptySet() + styles: Set<Style> = emptySet(), + shouldHaveTabs: Boolean = true ) { val contents = contentsForSourceSetDependent(nodes, pageContext) - val shouldHaveTabs = contents.size != 1 - val styles = "platform-hinted ${styles.joinToString()}" + if (shouldHaveTabs) " with-platform-tabs" else "" - div(styles) { + val divStyles = "platform-hinted ${styles.joinToString()}" + if (shouldHaveTabs) " with-platform-tabs" else "" + div(divStyles) { attributes["data-platform-hinted"] = "data-platform-hinted" extra.extraHtmlAttributes().forEach { attributes[it.extraKey] = it.extraValue } if (shouldHaveTabs) { @@ -228,68 +227,63 @@ open class HtmlRenderer( } override fun FlowContent.buildDivergent(node: ContentDivergentGroup, pageContext: ContentPage) { - - val distinct = - node.groupDivergentInstances(pageContext, - beforeTransformer = { instance, _, sourceSet -> - createHTML(prettyPrint = false).prepareForTemplates().div { - instance.before?.let { before -> - buildContentNode(before, pageContext, sourceSet) - } - }.stripDiv() - }, - afterTransformer = { instance, _, sourceSet -> - createHTML(prettyPrint = false).prepareForTemplates().div { - instance.after?.let { after -> - buildContentNode(after, pageContext, sourceSet) - } - }.stripDiv() - }) - - distinct.forEach { distinctInstances -> - val groupedDivergent = distinctInstances.value.groupBy { it.second } - - consumer.onTagContentUnsafe { - +createHTML().prepareForTemplates().div("divergent-group") { - attributes["data-filterable-current"] = groupedDivergent.keys.joinToString(" ") { - it.sourceSetIDs.merged.toString() - } - attributes["data-filterable-set"] = groupedDivergent.keys.joinToString(" ") { - it.sourceSetIDs.merged.toString() - } - - val divergentForPlatformDependent = groupedDivergent.map { (sourceSet, elements) -> - sourceSet to elements.map { e -> e.first.divergent } - }.toMap() - - val content = contentsForSourceSetDependent(divergentForPlatformDependent, pageContext) - - consumer.onTagContentUnsafe { - +createHTML().prepareForTemplates().div("with-platform-tags") { - consumer.onTagContentUnsafe { +distinctInstances.key.first } - - consumer.onTagContentUnsafe { - +createHTML().prepareForTemplates().span("pull-right") { - if ((distinct.size > 1 && groupedDivergent.size == 1) || groupedDivergent.size == 1 || content.size == 1) { - if (node.sourceSets.size != 1) { - createPlatformTags(node, setOf(content.first().first)) - } - } + fun groupDivergentInstancesWithSourceSet( + instances: List<ContentDivergentInstance>, + sourceSet: DisplaySourceSet, + pageContext: ContentPage, + beforeTransformer: (ContentDivergentInstance, ContentPage, DisplaySourceSet) -> String, + afterTransformer: (ContentDivergentInstance, ContentPage, DisplaySourceSet) -> String + ): Map<SerializedBeforeAndAfter, List<ContentDivergentInstance>> = + instances.map { instance -> + instance to Pair( + beforeTransformer(instance, pageContext, sourceSet), + afterTransformer(instance, pageContext, sourceSet) + ) + }.groupBy( + Pair<ContentDivergentInstance, SerializedBeforeAndAfter>::second, + Pair<ContentDivergentInstance, SerializedBeforeAndAfter>::first + ) + + if (node.implicitlySourceSetHinted) { + val groupedInstancesBySourceSet = node.children.flatMap { instance -> + instance.sourceSets.map { sourceSet -> instance to sourceSet } + }.groupBy( + Pair<ContentDivergentInstance, DisplaySourceSet>::second, + Pair<ContentDivergentInstance, DisplaySourceSet>::first + ) + + val nodes = groupedInstancesBySourceSet.mapValues { + val distinct = + groupDivergentInstancesWithSourceSet(it.value, it.key, pageContext, + beforeTransformer = { instance, _, sourceSet -> + createHTML(prettyPrint = false).prepareForTemplates().div { + instance.before?.let { before -> + buildContentNode(before, pageContext, sourceSet) } - } - } - } - div { - if (node.implicitlySourceSetHinted) { - buildPlatformDependent(divergentForPlatformDependent, pageContext) - } else { - distinctInstances.value.forEach { - buildContentNode(it.first.divergent, pageContext, setOf(it.second)) - } - } - } - consumer.onTagContentUnsafe { +distinctInstances.key.second } + }.stripDiv() + }, + afterTransformer = { instance, _, sourceSet -> + createHTML(prettyPrint = false).prepareForTemplates().div { + instance.after?.let { after -> + buildContentNode(after, pageContext, sourceSet) + } + }.stripDiv() + }) + val contentOfSourceSet = mutableListOf<ContentNode>() + distinct.onEachIndexed{ i, (_, distinctInstances) -> + contentOfSourceSet.addIfNotNull(distinctInstances.firstOrNull()?.before) + contentOfSourceSet.addAll(distinctInstances.map { it.divergent }) + contentOfSourceSet.addIfNotNull( + distinctInstances.firstOrNull()?.after + ?: if (i != distinct.size - 1) ContentBreakLine(it.key) else null + ) } + contentOfSourceSet + } + buildPlatformDependent(nodes, pageContext) + } else { + node.children.forEach { + buildContentNode(it.divergent, pageContext, it.sourceSets) } } } @@ -416,9 +410,6 @@ open class HtmlRenderer( div { toRender.filter { it !is ContentLink && !it.hasStyle(ContentStyle.RowTitle) } .takeIf { it.isNotEmpty() }?.let { - if (ContentKind.shouldBePlatformTagged(contextNode.dci.kind) && contextNode.sourceSets.size == 1) - createPlatformTags(contextNode) - div("title") { it.forEach { it.build(this, pageContext, sourceSetRestriction) @@ -678,7 +669,7 @@ open class HtmlRenderer( - it is useless - it overflows with playground's run button */ - if(!code.style.contains(ContentStyle.RunnableSample)) copyButton() + if (!code.style.contains(ContentStyle.RunnableSample)) copyButton() } } @@ -758,13 +749,17 @@ open class HtmlRenderer( script { unsafe { +"""var pathToRoot = "###";""" } } } // This script doesn't need to be there but it is nice to have since app in dark mode doesn't 'blink' (class is added before it is rendered) - script { unsafe { +""" + script { + unsafe { + +""" const storage = localStorage.getItem("dokka-dark-mode") const savedDarkMode = storage ? JSON.parse(storage) : false if(savedDarkMode === true){ document.getElementsByTagName("html")[0].classList.add("theme-dark") } - """.trimIndent() } } + """.trimIndent() + } + } resources.forEach { when { it.substringBefore('?').substringAfterLast('.') == "css" -> @@ -840,7 +835,7 @@ open class HtmlRenderer( content() div(classes = "footer") { span("go-to-top-icon") { - a(href = "#content"){ + a(href = "#content") { id = "go-to-top-link" } } @@ -872,7 +867,12 @@ open class HtmlRenderer( templateCommand(PathToRootSubstitutionCommand(pattern = "###", default = pathToRoot)) { a { href = "###index.html" - templateCommand(ProjectNameSubstitutionCommand(pattern = "@@@", default = context.configuration.moduleName)) { + templateCommand( + ProjectNameSubstitutionCommand( + pattern = "@@@", + default = context.configuration.moduleName + ) + ) { span { text("@@@") } diff --git a/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt b/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt index 4592f6e6..6a504634 100644 --- a/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt +++ b/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt @@ -5,9 +5,8 @@ import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.pages.ContentDivergentGroup import org.junit.jupiter.api.Test import renderers.testPage -import utils.Div -import utils.Span import utils.match +import kotlin.test.assertEquals class DivergentTest : HtmlRenderingOnlyTestBase() { @@ -23,7 +22,7 @@ class DivergentTest : HtmlRenderingOnlyTestBase() { } } HtmlRenderer(context).render(page) - renderedContent.match(Div(Div(Div(Div("a"))))) + renderedContent.select("[data-togglable=DEFAULT/js]").single().match("a") } @Test @@ -38,7 +37,7 @@ class DivergentTest : HtmlRenderingOnlyTestBase() { } } HtmlRenderer(context).render(page) - renderedContent.match(Div(Div("a"))) + renderedContent.match("a") } @Test @@ -64,7 +63,10 @@ class DivergentTest : HtmlRenderingOnlyTestBase() { } HtmlRenderer(context).render(page) - renderedContent.match(Div(Div(Div(Div("a"), Div("b"), Div("c"))))) + val content = renderedContent + content.select("[data-togglable=DEFAULT/js]").single().match("a") + content.select("[data-togglable=DEFAULT/jvm]").single().match("b") + content.select("[data-togglable=DEFAULT/native]").single().match("c") } @Test @@ -90,7 +92,7 @@ class DivergentTest : HtmlRenderingOnlyTestBase() { } HtmlRenderer(context).render(page) - renderedContent.match(Div(Div((Div(Div("abc")))))) + renderedContent.select("[data-togglable=DEFAULT/js]").single().match("abc") } @Test @@ -126,7 +128,14 @@ class DivergentTest : HtmlRenderingOnlyTestBase() { } HtmlRenderer(context).render(page) - renderedContent.match(Div(Div(Div(Div("bd"), Div("c"), Div("ae"))))) + val content = renderedContent + val orderOfTabs = content.select(".platform-bookmarks-row").single().children().map { it.attr("data-toggle") } + + assertEquals(listOf("DEFAULT/js", "DEFAULT/jvm", "DEFAULT/native"), orderOfTabs) + + content.select("[data-togglable=DEFAULT/native]").single().match("ae") + content.select("[data-togglable=DEFAULT/js]").single().match("bd") + content.select("[data-togglable=DEFAULT/jvm]").single().match("c") } @Test @@ -174,12 +183,10 @@ class DivergentTest : HtmlRenderingOnlyTestBase() { } HtmlRenderer(context).render(page) - renderedContent.match( - Div(Div(Span(Div(Div("NATIVE")))), Div(Div(Div("a"))), "a+"), - Div(Div(Span(Div(Div("JS")))), Div(Div(Div("bd"))), "bd+"), - Div(Div(Span(Div(Div("JVM")))), Div(Div(Div("c")))), - Div(Div(Span(Div(Div("NATIVE")))), Div(Div(Div("e"))), "e+"), - ) + val content = renderedContent + content.select("[data-togglable=DEFAULT/native]").single().match("aa+ee+") + content.select("[data-togglable=DEFAULT/js]").single().match("bdbd+") + content.select("[data-togglable=DEFAULT/jvm]").single().match("c") } @Test @@ -206,15 +213,7 @@ class DivergentTest : HtmlRenderingOnlyTestBase() { } HtmlRenderer(context).render(page) - renderedContent.match( - Div( - Div( - "ab-", - Span() - ), - Div(Div(Div("ab"))) - ) - ) + renderedContent.select("[data-togglable=DEFAULT/native]").single().match("ab-ab") } @Test @@ -241,12 +240,7 @@ class DivergentTest : HtmlRenderingOnlyTestBase() { } HtmlRenderer(context).render(page) - renderedContent.match( - Div( - Div(Div(Div("ab"))), - "ab+" - ) - ) + renderedContent.select("[data-togglable=DEFAULT/native]").single().match("abab+") } @Test @@ -279,13 +273,7 @@ class DivergentTest : HtmlRenderingOnlyTestBase() { } HtmlRenderer(context).render(page) - renderedContent.match( - Div( - Div("ab-", Span()), - Div(Div(Div("ab"))), - "ab+" - ) - ) + renderedContent.select("[data-togglable=DEFAULT/native]").single().match("ab-abab+") } @Test @@ -318,9 +306,6 @@ class DivergentTest : HtmlRenderingOnlyTestBase() { } HtmlRenderer(context).render(page) - renderedContent.match( - Div(Div("a-", Span()), Div(Div(Div("a"))), "ab+"), - Div(Div("b-", Span()), Div(Div(Div(("b")))), "ab+") - ) + renderedContent.select("[data-togglable=DEFAULT/native]").single().match("a-aab+b-bab+") } } diff --git a/plugins/base/src/test/kotlin/signatures/AbstractRenderingTest.kt b/plugins/base/src/test/kotlin/signatures/AbstractRenderingTest.kt index 5ea5c02c..171e510c 100644 --- a/plugins/base/src/test/kotlin/signatures/AbstractRenderingTest.kt +++ b/plugins/base/src/test/kotlin/signatures/AbstractRenderingTest.kt @@ -46,6 +46,7 @@ abstract class AbstractRenderingTest : BaseAbstractTest() { .let { Jsoup.parse(it) }.select("#content").single() fun TestOutputWriterPlugin.renderedDivergentContent(path: String) = renderedContent(path).select("div.divergent-group") + fun TestOutputWriterPlugin.renderedSourceDepenentContent(path: String) = renderedContent(path).select("div.sourceset-depenent-content") val Element.brief: String get() = children().select("p").text() diff --git a/plugins/base/src/test/kotlin/signatures/DivergentSignatureTest.kt b/plugins/base/src/test/kotlin/signatures/DivergentSignatureTest.kt index 6471f555..f03103d8 100644 --- a/plugins/base/src/test/kotlin/signatures/DivergentSignatureTest.kt +++ b/plugins/base/src/test/kotlin/signatures/DivergentSignatureTest.kt @@ -1,13 +1,7 @@ package signatures -import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest -import org.jsoup.Jsoup -import org.jsoup.nodes.Element -import org.jsoup.select.Elements import org.junit.jupiter.api.Test -import java.nio.file.Paths import utils.TestOutputWriterPlugin -import kotlin.test.assertEquals class DivergentSignatureTest : AbstractRenderingTest() { @@ -21,10 +15,13 @@ class DivergentSignatureTest : AbstractRenderingTest() { pluginOverrides = listOf(writerPlugin) ) { renderingStage = { _, _ -> - val content = writerPlugin.renderedDivergentContent("example/example/-clock/get-time.html") + val content = writerPlugin.renderedSourceDepenentContent("example/example/-clock/get-time.html") - assert(content.count() == 1) - assert(content.select("[data-filterable-current=example/common example/js example/jvm]").single().brief == "") + assert(content.count() == 3) + val sourceSets = listOf("example/common", "example/js", "example/jvm") + sourceSets.forEach { + assert(content.select("[data-togglable=$it]").single().brief == "") + } } } } @@ -39,10 +36,12 @@ class DivergentSignatureTest : AbstractRenderingTest() { pluginOverrides = listOf(writerPlugin) ) { renderingStage = { _, _ -> - val content = writerPlugin.renderedDivergentContent("example/example/-clock/get-times-in-millis.html") - assert(content.count() == 2) - assert(content.select("[data-filterable-current=example/common example/jvm]").single().brief == "Time in minis") - assert(content.select("[data-filterable-current=example/js]").single().brief == "JS implementation of getTimeInMillis" ) + val content = writerPlugin.renderedSourceDepenentContent("example/example/-clock/get-times-in-millis.html") + + assert(content.count() == 3) + assert(content.select("[data-togglable=example/common]").single().brief == "Time in minis") + assert(content.select("[data-togglable=example/jvm]").single().brief == "Time in minis") + assert(content.select("[data-togglable=example/js]").single().brief == "JS implementation of getTimeInMillis" ) } } } @@ -57,11 +56,11 @@ class DivergentSignatureTest : AbstractRenderingTest() { pluginOverrides = listOf(writerPlugin) ) { renderingStage = { _, _ -> - val content = writerPlugin.renderedDivergentContent("example/example/-clock/get-year.html") + val content = writerPlugin.renderedSourceDepenentContent("example/example/-clock/get-year.html") assert(content.count() == 3) - assert(content.select("[data-filterable-current=example/jvm]").single().brief == "JVM custom kdoc") - assert(content.select("[data-filterable-current=example/js]").single().brief == "JS custom kdoc") - assert(content.select("[data-filterable-current=example/common]").single().brief == "") + assert(content.select("[data-togglable=example/jvm]").single().brief == "JVM custom kdoc") + assert(content.select("[data-togglable=example/js]").single().brief == "JS custom kdoc") + assert(content.select("[data-togglable=example/common]").single().brief == "") } } } diff --git a/plugins/base/src/test/kotlin/signatures/RawHtmlRenderingTest.kt b/plugins/base/src/test/kotlin/signatures/RawHtmlRenderingTest.kt index c741ac8b..4ac21c59 100644 --- a/plugins/base/src/test/kotlin/signatures/RawHtmlRenderingTest.kt +++ b/plugins/base/src/test/kotlin/signatures/RawHtmlRenderingTest.kt @@ -16,9 +16,9 @@ class RawHtmlRenderingTest: AbstractRenderingTest() { pluginOverrides = listOf(writerPlugin) ) { renderingStage = { _, _ -> - val content = writerPlugin.renderedDivergentContent("example/example/-html-test/test.html") + val content = writerPlugin.renderedSourceDepenentContent("example/example/-html-test/test.html") assert(content.count() == 1) - assertEquals(content.select("[data-filterable-current=example/jvm]").single().rawBrief,"This is an example <!-- not visible --> of html") + assertEquals(content.select("[data-togglable=example/jvm]").single().rawBrief,"This is an example <!-- not visible --> of html") val indexContent = writerPlugin.writer.contents.getValue("example/example/-html-test/index.html") .let { Jsoup.parse(it) } @@ -53,9 +53,9 @@ class RawHtmlRenderingTest: AbstractRenderingTest() { pluginOverrides = listOf(writerPlugin) ) { renderingStage = { _, _ -> - val content = writerPlugin.renderedDivergentContent("example/example/-html-test/test-p.html") + val content = writerPlugin.renderedSourceDepenentContent("example/example/-html-test/test-p.html") assert(content.count() == 1) - assertEquals(content.select("[data-filterable-current=example/jvm]").single().rawBrief, "This is an <b> documentation </b>") + assertEquals(content.select("[data-togglable=example/jvm]").single().rawBrief, "This is an <b> documentation </b>") val indexContent = writerPlugin.writer.contents.getValue("example/example/-html-test/index.html") .let { Jsoup.parse(it) } |