diff options
author | Marcin Aman <maman@virtuslab.com> | 2020-08-13 16:23:26 +0200 |
---|---|---|
committer | Kamil Doległo <9080183+kamildoleglo@users.noreply.github.com> | 2020-10-08 19:05:41 +0200 |
commit | aae7623bb459d2bcd1e1b492aadf5c3858a3e657 (patch) | |
tree | f404b8bb3caed3e394f7b54d7296836851cfb2ab /plugins/base/src/main/kotlin | |
parent | be3fea152ae5dcec5ba9a29d86a69010d6b2e428 (diff) | |
download | dokka-aae7623bb459d2bcd1e1b492aadf5c3858a3e657.tar.gz dokka-aae7623bb459d2bcd1e1b492aadf5c3858a3e657.tar.bz2 dokka-aae7623bb459d2bcd1e1b492aadf5c3858a3e657.zip |
Anchors hint
Diffstat (limited to 'plugins/base/src/main/kotlin')
5 files changed, 100 insertions, 76 deletions
diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index abb4e85b..ef5d78b6 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -9,6 +9,8 @@ import org.jetbrains.dokka.DokkaSourceSetID import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.renderers.DefaultRenderer import org.jetbrains.dokka.base.renderers.TabSortingStrategy +import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint +import org.jetbrains.dokka.base.transformers.pages.sourcelinks.hasTabbedContent import org.jetbrains.dokka.base.renderers.isImage import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.DisplaySourceSet @@ -103,6 +105,7 @@ open class HtmlRenderer( } node.hasStyle(TextStyle.Paragraph) -> p(additionalClasses) { childrenCallback() } node.hasStyle(TextStyle.Block) -> div(additionalClasses) { childrenCallback() } + node.isAnchorable -> buildAnchor(node.anchor, node.anchorLabel!!) { childrenCallback() } else -> childrenCallback() } } @@ -376,14 +379,12 @@ open class HtmlRenderer( sourceSetRestriction: Set<DisplaySourceSet>?, style: Set<Style> ) { - val anchorName = contextNode.dci.dri.first().anchor - withAnchor(anchorName) { - div(classes = "table-row") { - div("main-subrow " + contextNode.style.joinToString(separator = " ")) { - buildRowHeaderLink(toRender, pageContext, sourceSetRestriction, anchorName, "w-100") - div { - buildRowBriefSectionForDocs(toRender, pageContext, sourceSetRestriction) - } + anchorFromNode(contextNode) + div(classes = "table-row") { + div("main-subrow " + contextNode.style.joinToString(separator = " ")) { + buildRowHeaderLink(toRender, pageContext, sourceSetRestriction, contextNode.anchor, "w-100") + div { + buildRowBriefSectionForDocs(toRender, pageContext, sourceSetRestriction) } } } @@ -396,22 +397,20 @@ open class HtmlRenderer( sourceSetRestriction: Set<DisplaySourceSet>?, style: Set<Style> ) { - val anchorName = contextNode.dci.dri.first().anchor - withAnchor(anchorName) { - div(classes = "table-row") { - addSourceSetFilteringAttributes(contextNode) - div { - div("main-subrow " + contextNode.style.joinToString(separator = " ")) { - buildRowHeaderLink(toRender, pageContext, sourceSetRestriction, anchorName) - div("pull-right") { - if (ContentKind.shouldBePlatformTagged(contextNode.dci.kind)) { - createPlatformTags(contextNode, cssClasses = "no-gutters") - } + anchorFromNode(contextNode) + div(classes = "table-row") { + addSourceSetFilteringAttributes(contextNode) + div { + div("main-subrow " + contextNode.style.joinToString(separator = " ")) { + buildRowHeaderLink(toRender, pageContext, sourceSetRestriction, contextNode.anchor) + div("pull-right") { + if (ContentKind.shouldBePlatformTagged(contextNode.dci.kind)) { + createPlatformTags(contextNode, cssClasses = "no-gutters") } } - div { - buildRowBriefSectionForDocs(toRender, pageContext, sourceSetRestriction) - } + } + div { + buildRowBriefSectionForDocs(toRender, pageContext, sourceSetRestriction) } } } @@ -424,21 +423,20 @@ open class HtmlRenderer( sourceSetRestriction: Set<DisplaySourceSet>?, style: Set<Style> ) { - val anchorName = contextNode.dci.dri.first().anchor - withAnchor(anchorName) { - div(classes = "table-row") { - addSourceSetFilteringAttributes(contextNode) - div("main-subrow keyValue " + contextNode.style.joinToString(separator = " ")) { - buildRowHeaderLink(toRender, pageContext, sourceSetRestriction, anchorName) - 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) + anchorFromNode(contextNode) + div(classes = "table-row") { + addSourceSetFilteringAttributes(contextNode) + div("main-subrow keyValue " + contextNode.style.joinToString(separator = " ")) { + buildRowHeaderLink(toRender, pageContext, sourceSetRestriction, contextNode.anchor) + 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) - } + div("title") { + it.forEach { + it.build(this, pageContext, sourceSetRestriction) } } } @@ -451,7 +449,7 @@ open class HtmlRenderer( toRender: List<ContentNode>, pageContext: ContentPage, sourceSetRestriction: Set<DisplaySourceSet>?, - anchorName: String, + anchorDestination: String, classes: String = "" ) { toRender.filter { it is ContentLink || it.hasStyle(ContentStyle.RowTitle) }.takeIf { it.isNotEmpty() }?.let { @@ -460,7 +458,7 @@ open class HtmlRenderer( .forEach { span("inline-flex") { it.build(this, pageContext, sourceSetRestriction) - if(it is ContentLink) buildAnchor(anchorName) + if(it is ContentLink) buildAnchorCopyButton(anchorDestination) } } } @@ -572,25 +570,32 @@ open class HtmlRenderer( override fun FlowContent.buildHeader(level: Int, node: ContentHeader, content: FlowContent.() -> Unit) { - val anchor = node.extra[SimpleAttr.SimpleAttrKey("anchor")]?.extraValue?.urlEncoded() val classes = node.style.joinToString { it.toString() }.toLowerCase() when (level) { - 1 -> h1(classes = classes) { withAnchor(anchor, content) } - 2 -> h2(classes = classes) { withAnchor(anchor, content) } - 3 -> h3(classes = classes) { withAnchor(anchor, content) } - 4 -> h4(classes = classes) { withAnchor(anchor, content) } - 5 -> h5(classes = classes) { withAnchor(anchor, content) } - else -> h6(classes = classes) { withAnchor(anchor, content) } + 1 -> h1(classes = classes, content) + 2 -> h2(classes = classes, content) + 3 -> h3(classes = classes, content) + 4 -> h4(classes = classes, content) + 5 -> h5(classes = classes, content) + else -> h6(classes = classes, content) } } - private fun FlowContent.withAnchor(anchorName: String?, content: FlowContent.() -> Unit) { + private fun FlowContent.buildAnchor(anchor: String, anchorLabel: String, content: FlowContent.() -> Unit) { a { - anchorName?.let { attributes["data-name"] = it } + attributes["data-name"] = anchor + attributes["anchor-label"] = anchorLabel } content() } + private fun FlowContent.buildAnchor(anchor: String, anchorLabel: String) = + buildAnchor(anchor, anchorLabel) {} + + private fun FlowContent.anchorFromNode(node: ContentNode) { + node.anchorLabel?.let { label -> buildAnchor(node.anchor, label) } + } + override fun FlowContent.buildNavigation(page: PageNode) = div(classes = "breadcrumbs") { @@ -618,7 +623,7 @@ open class HtmlRenderer( text(to.name) } - fun FlowContent.buildAnchor(pointingTo: String) { + fun FlowContent.buildAnchorCopyButton(pointingTo: String) { span(classes = "anchor-wrapper") { span(classes = "anchor-icon") { attributes["pointing-to"] = pointingTo @@ -835,5 +840,11 @@ private val PageNode.isNavigable: Boolean fun PropertyContainer<ContentNode>.extraHtmlAttributes() = allOfType<SimpleAttr>() -private val DRI.anchor: String - get() = toString().urlEncoded() +val ContentNode.isAnchorable: Boolean + get() = anchorLabel != null + +val ContentNode.anchorLabel: String? + get() = extra[SymbolAnchorHint.SymbolAnchorHintKey]?.anchorName + +val ContentNode.anchor: String + get() = dci.dri.first().toString().urlEncoded() diff --git a/plugins/base/src/main/kotlin/resolvers/anchors/AnchorsHint.kt b/plugins/base/src/main/kotlin/resolvers/anchors/AnchorsHint.kt index 1b741484..0b68db10 100644 --- a/plugins/base/src/main/kotlin/resolvers/anchors/AnchorsHint.kt +++ b/plugins/base/src/main/kotlin/resolvers/anchors/AnchorsHint.kt @@ -1,9 +1,13 @@ package org.jetbrains.dokka.base.resolvers.anchors +import org.jetbrains.dokka.model.Documentable import org.jetbrains.dokka.model.properties.ExtraProperty import org.jetbrains.dokka.pages.ContentNode -// TODO IMPORTANT: https://github.com/Kotlin/dokka/issues/1054 -object SymbolAnchorHint: ExtraProperty<ContentNode>, ExtraProperty.Key<ContentNode, SymbolAnchorHint> { - override val key = this +data class SymbolAnchorHint(val anchorName: String): ExtraProperty<ContentNode> { + object SymbolAnchorHintKey : ExtraProperty.Key<ContentNode, SymbolAnchorHint> + override val key: ExtraProperty.Key<ContentNode, SymbolAnchorHint> = SymbolAnchorHintKey + companion object: ExtraProperty.Key<ContentNode, SymbolAnchorHint> { + fun from(d: Documentable): SymbolAnchorHint? = d.name?.let { SymbolAnchorHint(it) } + } }
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt index 76bf0067..8e1e99f2 100644 --- a/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt +++ b/plugins/base/src/main/kotlin/transformers/pages/sourcelinks/SourceLinksTransformer.kt @@ -8,6 +8,7 @@ import org.jetbrains.dokka.model.DocumentableSource import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.analysis.DescriptorDocumentableSource import org.jetbrains.dokka.analysis.PsiDocumentableSource +import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint import org.jetbrains.dokka.model.WithSources import org.jetbrains.dokka.model.toDisplaySourceSets import org.jetbrains.dokka.pages.* @@ -63,7 +64,7 @@ class SourceLinksTransformer(val context: DokkaContext, val builder: PageContent +ContentTable( emptyList(), sources.map { - buildGroup(node.dri, setOf(it.first), kind = ContentKind.Source) { + buildGroup(node.dri, setOf(it.first), kind = ContentKind.Source, extra = mainExtra + SymbolAnchorHint(it.second)) { link("(source)", it.second) } }, diff --git a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt index f5fbb51e..caeb6bcb 100644 --- a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt +++ b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt @@ -18,6 +18,7 @@ import kotlin.reflect.full.isSubclassOf import org.jetbrains.dokka.DokkaConfiguration.DokkaSourceSet import org.jetbrains.dokka.base.resolvers.anchors.SymbolAnchorHint import org.jetbrains.dokka.base.transformers.documentables.ClashingDriIdentifier +import org.jetbrains.dokka.model.properties.plus private typealias GroupedTags = Map<KClass<out TagWrapper>, List<Pair<DokkaSourceSet?, TagWrapper>>> @@ -108,7 +109,7 @@ open class DefaultPageCreator( } +contentForComments(m) - block("Packages", 2, ContentKind.Packages, m.packages, m.sourceSets.toSet()) { + block("Packages", 2, ContentKind.Packages, m.packages, m.sourceSets.toSet(), needsAnchors = true) { val documentations = it.sourceSets.map { platform -> it.descriptions[platform]?.also { it.root } } @@ -168,7 +169,7 @@ open class DefaultPageCreator( extra = mainExtra + SimpleAttr.header("Properties") ) { link(it.name, it.dri, kind = ContentKind.Main) - sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependentHint) { + sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependentHint, extra = PropertyContainer.empty()) { +buildSignature(it) contentForBrief(it) } @@ -183,11 +184,10 @@ open class DefaultPageCreator( }), map.entries.flatMap { entry -> entry.value.map { Pair(entry.key, it) } } .groupBy({ it.second }, { it.first }).map { (classlike, platforms) -> - buildGroup(setOf(dri), platforms.toSet(), ContentKind.Inheritors) { - link( - classlike.classNames?.substringBeforeLast(".") ?: classlike.toString() - .also { logger.warn("No class name found for DRI $classlike") }, classlike - ) + val label = classlike.classNames?.substringBeforeLast(".") ?: classlike.toString() + .also { logger.warn("No class name found for DRI $classlike") } + buildGroup(setOf(dri), platforms.toSet(), ContentKind.Inheritors, extra = mainExtra + SymbolAnchorHint(label)) { + link(label, classlike) } }, DCI(setOf(dri), ContentKind.Inheritors), @@ -240,6 +240,7 @@ open class DefaultPageCreator( ContentKind.Constructors, c.constructors.filter { it.extra[PrimaryConstructorExtra] == null || it.documentation.isNotEmpty() }, c.sourceSets, + needsAnchors = true, extra = PropertyContainer.empty<ContentNode>() + SimpleAttr.header("Constructors") ) { link(it.name, it.dri, kind = ContentKind.Main) @@ -247,7 +248,8 @@ open class DefaultPageCreator( it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependentHint, - styles = emptySet() + styles = emptySet(), + extra = PropertyContainer.empty<ContentNode>() ) { +buildSignature(it) contentForBrief(it) @@ -262,11 +264,12 @@ open class DefaultPageCreator( c.entries, c.sourceSets.toSet(), needsSorting = false, + needsAnchors = true, extra = mainExtra + SimpleAttr.header("Entries"), styles = emptySet() ) { link(it.name, it.dri) - sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependentHint) { + sourceSetDependentHint(it.dri, it.sourceSets.toSet(), kind = ContentKind.SourceSetDependentHint, extra = PropertyContainer.empty<ContentNode>()) { +buildSignature(it) contentForBrief(it) } @@ -406,7 +409,7 @@ open class DefaultPageCreator( buildGroup( sourceSets = setOf(platform), kind = ContentKind.Comment, - styles = mainStyles + ContentStyle.RowTitle + styles = mainStyles + ContentStyle.RowTitle, ) { if (it.address != null) link( it.name, @@ -526,16 +529,18 @@ open class DefaultPageCreator( dri = elements.map { it.dri }.toSet(), sourceSets = elements.flatMap { it.sourceSets }.toSet(), kind = kind, - styles = emptySet() - ) { - link(elementName.orEmpty(), elements.first().dri, kind = kind) - divergentGroup( - ContentDivergentGroup.GroupID(name), - elements.map { it.dri }.toSet(), - kind = kind + styles = emptySet(), + extra = elementName?.let { name -> extra + SymbolAnchorHint(name) } ?: extra + ) { + link(elementName.orEmpty(), elements.first().dri, kind = kind) + divergentGroup( + ContentDivergentGroup.GroupID(name), + elements.map { it.dri }.toSet(), + kind = kind, + extra = extra ) { elements.map { - instance(setOf(it.dri), it.sourceSets.toSet(), extra = PropertyContainer.withAll(SymbolAnchorHint)) { + instance(setOf(it.dri), it.sourceSets.toSet(), extra = PropertyContainer.withAll(SymbolAnchorHint(it.name ?: ""))) { divergent { group { +buildSignature(it) diff --git a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt index 4bebd9f1..2fc0c7b2 100644 --- a/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt +++ b/plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt @@ -13,6 +13,7 @@ import org.jetbrains.dokka.model.properties.PropertyContainer import org.jetbrains.dokka.model.toDisplaySourceSets import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.utilities.DokkaLogger +import org.jetbrains.dokka.model.properties.plus @DslMarker annotation class ContentBuilderMarker @@ -114,7 +115,7 @@ open class PageContentBuilder( sourceSets, kind, styles, - extra + SimpleAttr("anchor", text.replace("\\s".toRegex(), "").toLowerCase()) + extra + SymbolAnchorHint(text.replace("\\s".toRegex(), "").toLowerCase()) ) { text(text, kind = kind) block() @@ -184,7 +185,7 @@ open class PageContentBuilder( else it } .map { - val newExtra = if (needsAnchors) extra + SymbolAnchorHint else extra + val newExtra = if (needsAnchors) extra + SymbolAnchorHint.from(it) else extra buildGroup(setOf(it.dri), it.sourceSets.toSet(), kind, styles, newExtra) { operation(it) } @@ -236,7 +237,8 @@ open class PageContentBuilder( listOf(createText(text, kind, sourceSets, styles, extra)), address, DCI(mainDRI, kind), - sourceSets.toDisplaySourceSets() + sourceSets.toDisplaySourceSets(), + extra = extra ) fun link( @@ -269,7 +271,8 @@ open class PageContentBuilder( contentFor(mainDRI, sourceSets, kind, styles, extra, block).children, address, DCI(mainDRI, kind), - sourceSets.toDisplaySourceSets() + sourceSets.toDisplaySourceSets(), + extra = extra ) } |