package org.jetbrains.dokka.base.renderers.html
import org.jetbrains.dokka.Platform
import org.jetbrains.dokka.model.DisplaySourceSet
import org.jetbrains.dokka.model.dfs
import org.jetbrains.dokka.pages.*
import java.util.concurrent.ConcurrentHashMap
class SearchbarDataInstaller {
private val pageList = ConcurrentHashMap>()
private fun String.escaped(): String = this.replace("'", "\\'")
fun generatePagesList(): String =
pageList.entries
.filter { it.key.isNotEmpty() }
.sortedWith(compareBy({ it.key }, { it.value.first }, { it.value.second }))
.groupBy { it.key.substringAfterLast(".") }
.entries
.flatMapIndexed { topLevelIndex, entry ->
entry.value.mapIndexed { index, subentry ->
"{\'name\': \'${subentry.value.first.escaped()}\', \'description\':\'${subentry.key.escaped()}\', \'location\':\'${subentry.value.second.escaped()}\', 'searchKey':'${entry.key.escaped()}'}"
}
}
.joinToString(prefix = "[", separator = ",\n", postfix = "]")
private fun getSymbolSignature(page: ContentPage) = page.content.dfs { it.dci.kind == ContentKind.Symbol }
private fun flattenToText(node: ContentNode): String {
fun getContentTextNodes(node: ContentNode, sourceSetRestriction: DisplaySourceSet): List =
when (node) {
is ContentText -> listOf(node)
is ContentComposite -> node.children
.filter { sourceSetRestriction in it.sourceSets }
.flatMap { getContentTextNodes(it, sourceSetRestriction) }
.takeIf { node.dci.kind != ContentKind.Annotations }
.orEmpty()
else -> emptyList()
}
val sourceSetRestriction =
node.sourceSets.find { it.platform == Platform.common } ?: node.sourceSets.first()
return getContentTextNodes(node, sourceSetRestriction).joinToString("") { it.text }
}
fun processPage(page: ContentPage, link: String) {
val signature = getSymbolSignature(page)
val textNodes = signature?.let { flattenToText(it) }
val documentable = page.documentable
if (documentable != null) {
listOf(
documentable.dri.packageName,
documentable.dri.classNames,
documentable.dri.callable?.name
).filter { !it.isNullOrEmpty() }
.takeIf { it.isNotEmpty() }
?.joinToString(".")
?.let { id -> pageList.put(id, Pair(textNodes ?: page.name, link)) }
}
}
}