diff options
6 files changed, 48 insertions, 52 deletions
diff --git a/plugins/base/frontend/src/main/components/search/dokkaFuzzyFilter.tsx b/plugins/base/frontend/src/main/components/search/dokkaFuzzyFilter.tsx index 6d40336f..98fb1455 100644 --- a/plugins/base/frontend/src/main/components/search/dokkaFuzzyFilter.tsx +++ b/plugins/base/frontend/src/main/components/search/dokkaFuzzyFilter.tsx @@ -1,5 +1,5 @@ import {Select} from "@jetbrains/ring-ui"; -import {Option, OptionWithHighlightComponent, OptionWithSearchResult, SearchRank} from "./types"; +import {Option, OptionWithHighlightComponent, OptionWithSearchResult} from "./types"; import fuzzyHighlight from '@jetbrains/ring-ui/components/global/fuzzy-highlight.js' import React from "react"; import {SearchResultRow, signatureFromSearchResult} from "./searchResultRow"; @@ -8,7 +8,7 @@ import _ from "lodash"; const orderRecords = (records: OptionWithSearchResult[], searchPhrase: string): OptionWithSearchResult[] => { return records.sort((a: OptionWithSearchResult, b: OptionWithSearchResult) => { //Prefer higher rank - const byRank = b.rank - a.rank + const byRank = a.rank - b.rank if(byRank !== 0){ return byRank } @@ -70,23 +70,29 @@ export class DokkaFuzzyFilterComponent extends Select { } } - getListItems(rawFilterString: string, _: Option[]) { + getListItems(rawFilterString: string, e: Option[]) { const filterPhrase = (rawFilterString ? rawFilterString : '').trim() const matchedRecords = this.props.data .map((record: Option) => { - const bySearchKey = fuzzyHighlight(filterPhrase, record.searchKey, false) - if(bySearchKey.matched){ + const searched = record.searchKeys.map((value, index) => { return { - ...bySearchKey, + ...fuzzyHighlight(filterPhrase, value, false), ...record, - rank: SearchRank.SearchKeyMatch + rank: index } + }).filter((e) => e.matched) + + const first = _.head(searched) + + if(first){ + return first } + return { - ...fuzzyHighlight(filterPhrase, record.name, false), + matched: false, ...record, - rank: SearchRank.NameMatch } + }) .filter((record: OptionWithSearchResult) => record.matched && (hasAnyMatchedPhraseLongerThan(record, 3) || filterPhrase.length < 3)) diff --git a/plugins/base/frontend/src/main/components/search/search.tsx b/plugins/base/frontend/src/main/components/search/search.tsx index ba7f6093..3616a396 100644 --- a/plugins/base/frontend/src/main/components/search/search.tsx +++ b/plugins/base/frontend/src/main/components/search/search.tsx @@ -47,7 +47,7 @@ export const WithFuzzySearchFilter = () => { if (pages) { data = pages.map((page, i) => ({ ...page, - label: page.searchKey, + label: page.name, key: i + 1, type: page.kind, rgItemType: List.ListProps.Type.CUSTOM diff --git a/plugins/base/frontend/src/main/components/search/searchResultRow.tsx b/plugins/base/frontend/src/main/components/search/searchResultRow.tsx index 5910eec4..b9dbf482 100644 --- a/plugins/base/frontend/src/main/components/search/searchResultRow.tsx +++ b/plugins/base/frontend/src/main/components/search/searchResultRow.tsx @@ -1,5 +1,5 @@ import React from "react"; -import {OptionWithSearchResult, SearchProps, SearchRank} from "./types"; +import {OptionWithSearchResult, SearchProps} from "./types"; import _ from "lodash"; type HighlighterProps = { @@ -11,10 +11,7 @@ const Highlighter: React.FC<HighlighterProps> = ({label}: HighlighterProps) => { } export const signatureFromSearchResult = (searchResult: OptionWithSearchResult): string => { - if(searchResult.rank == SearchRank.SearchKeyMatch){ - return searchResult.name.replace(searchResult.searchKey, searchResult.highlight) - } - return searchResult.highlight + return searchResult.name.replace(searchResult.searchKeys[searchResult.rank], searchResult.highlight) } export const SearchResultRow: React.FC<SearchProps> = ({searchResult}: SearchProps) => { diff --git a/plugins/base/frontend/src/main/components/search/types.ts b/plugins/base/frontend/src/main/components/search/types.ts index 11e2edf8..84e55399 100644 --- a/plugins/base/frontend/src/main/components/search/types.ts +++ b/plugins/base/frontend/src/main/components/search/types.ts @@ -4,7 +4,7 @@ export type Page = { name: string; kind: string; location: string; - searchKey: string; + searchKeys: string[]; description: string; } @@ -24,14 +24,10 @@ export type Props = { data: Option[] }; -export enum SearchRank { - SearchKeyMatch = 1, - NameMatch = 0 -} export type OptionWithSearchResult = Option & { matched: boolean, highlight: string, - rank: SearchRank + rank: number } export type OptionWithHighlightComponent = Option & { diff --git a/plugins/base/src/main/kotlin/renderers/html/SearchbarDataInstaller.kt b/plugins/base/src/main/kotlin/renderers/html/SearchbarDataInstaller.kt index f953821f..3c562315 100644 --- a/plugins/base/src/main/kotlin/renderers/html/SearchbarDataInstaller.kt +++ b/plugins/base/src/main/kotlin/renderers/html/SearchbarDataInstaller.kt @@ -1,28 +1,43 @@ package org.jetbrains.dokka.base.renderers.html +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper 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<String, Pair<String, String>>() +data class SearchRecord(val name: String, val description: String? = null, val location: String, val searchKeys: List<String> = listOf(name)) { + companion object { } +} + +open class SearchbarDataInstaller { + private val mapper = jacksonObjectMapper() - private fun String.escaped(): String = this.replace("'", "\\'") + private val pageList = ConcurrentHashMap<String, Pair<String, String>>() - fun generatePagesList(): String = - pageList.entries + open fun generatePagesList(): String { + val pages = 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()}'}" + .flatMap { entry -> + entry.value.map { subentry -> + val name = subentry.value.first + createSearchRecord( + name = name, + description = subentry.key, + location = subentry.value.second, + searchKeys = listOf(entry.key, name) + ) } } - .joinToString(prefix = "[", separator = ",\n", postfix = "]") + return mapper.writeValueAsString(pages) + } + + open fun createSearchRecord(name: String, description: String?, location: String, searchKeys: List<String>): SearchRecord = + SearchRecord(name, description, location, searchKeys) private fun getSymbolSignature(page: ContentPage) = page.content.dfs { it.dci.kind == ContentKind.Symbol } @@ -44,7 +59,7 @@ class SearchbarDataInstaller { return getContentTextNodes(node, sourceSetRestriction).joinToString("") { it.text } } - fun processPage(page: ContentPage, link: String) { + open fun processPage(page: ContentPage, link: String) { val signature = getSymbolSignature(page) val textNodes = signature?.let { flattenToText(it) } val documentable = page.documentable diff --git a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt index b34d3d6e..fdb5be3c 100644 --- a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt +++ b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt @@ -1,17 +1,9 @@ package org.jetbrains.dokka.base.renderers.html -import com.fasterxml.jackson.databind.annotation.JsonSerialize -import com.fasterxml.jackson.databind.ser.std.ToStringSerializer import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import kotlinx.html.h1 -import kotlinx.html.id -import kotlinx.html.table -import kotlinx.html.tbody -import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.DokkaBaseConfiguration import org.jetbrains.dokka.base.renderers.sourceSets -import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.DEnum import org.jetbrains.dokka.model.DEnumEntry import org.jetbrains.dokka.model.DFunction @@ -24,18 +16,8 @@ import org.jetbrains.dokka.transformers.pages.PageTransformer object NavigationPageInstaller : PageTransformer { private val mapper = jacksonObjectMapper() - private data class NavigationNodeView( - val name: String, - val label: String = name, - val searchKey: String = name, - @get:JsonSerialize(using = ToStringSerializer::class) val dri: DRI, - val location: String - ) { - companion object { - fun from(node: NavigationNode, location: String): NavigationNodeView = - NavigationNodeView(name = node.name, dri = node.dri, location = location) - } - } + fun SearchRecord.Companion.from(node: NavigationNode, location: String): SearchRecord = + SearchRecord(name = node.name, location = location) override fun invoke(input: RootPageNode): RootPageNode { val nodes = input.children.filterIsInstance<ContentPage>().single() @@ -46,7 +28,7 @@ object NavigationPageInstaller : PageTransformer { children = emptyList(), strategy = RenderingStrategy.LocationResolvableWrite { resolver -> mapper.writeValueAsString( - nodes.withDescendants().map { NavigationNodeView.from(it, resolver(it.dri, it.sourceSets)) }) + nodes.withDescendants().map { SearchRecord.from(it, resolver(it.dri, it.sourceSets)) }) }) return input.modified( |