From 2f7ee2b82cda39f6bd94c5200b83563418b68dd7 Mon Sep 17 00:00:00 2001 From: Marcin Aman Date: Thu, 17 Dec 2020 10:17:45 +0100 Subject: Navigate to root after logo click, add data to searchbars on multimodule (#1631) --- plugins/all-modules-page/build.gradle.kts | 1 + .../src/main/kotlin/AllModulesPagePlugin.kt | 12 ++++ .../JsonElementBasedTemplateProcessingStrategy.kt | 74 ++++++++++++++++++++++ .../navigationPaneSearch/navigationPaneSearch.tsx | 5 +- .../frontend/src/main/components/search/search.tsx | 37 +++++++---- .../src/main/components/utils/requests.tsx | 7 ++ .../src/main/kotlin/renderers/html/HtmlRenderer.kt | 43 ++++++++++--- .../main/kotlin/renderers/html/NavigationPage.kt | 19 ++++-- .../renderers/html/SearchbarDataInstaller.kt | 19 ++++-- .../kotlin/renderers/html/htmlPreprocessors.kt | 22 +++++-- .../base/src/main/kotlin/templating/AddToSearch.kt | 5 ++ .../main/kotlin/templating/jsonMapperForPlugins.kt | 1 - .../base/src/main/resources/dokka/styles/style.css | 1 + 13 files changed, 200 insertions(+), 46 deletions(-) create mode 100644 plugins/all-modules-page/src/main/kotlin/templates/JsonElementBasedTemplateProcessingStrategy.kt create mode 100644 plugins/base/frontend/src/main/components/utils/requests.tsx create mode 100644 plugins/base/src/main/kotlin/templating/AddToSearch.kt diff --git a/plugins/all-modules-page/build.gradle.kts b/plugins/all-modules-page/build.gradle.kts index a0c5a5ed..ecf8a384 100644 --- a/plugins/all-modules-page/build.gradle.kts +++ b/plugins/all-modules-page/build.gradle.kts @@ -11,4 +11,5 @@ dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version") implementation("org.jsoup:jsoup:1.12.1") + implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.11.1") } \ No newline at end of file diff --git a/plugins/all-modules-page/src/main/kotlin/AllModulesPagePlugin.kt b/plugins/all-modules-page/src/main/kotlin/AllModulesPagePlugin.kt index 95a94cf4..c99293ef 100644 --- a/plugins/all-modules-page/src/main/kotlin/AllModulesPagePlugin.kt +++ b/plugins/all-modules-page/src/main/kotlin/AllModulesPagePlugin.kt @@ -54,6 +54,18 @@ class AllModulesPagePlugin : DokkaPlugin() { templateProcessingStrategy providing ::FallbackTemplateProcessingStrategy } + val navigationSearchTemplateStrategy by extending { + templateProcessingStrategy providing ::NavigationSearchTemplateStrategy order { + before(fallbackProcessingStrategy) + } + } + + val pagesSearchTemplateStrategy by extending { + templateProcessingStrategy providing ::PagesSearchTemplateStrategy order { + before(fallbackProcessingStrategy) + } + } + val pathToRootSubstitutor by extending { substitutor providing ::PathToRootSubstitutor } diff --git a/plugins/all-modules-page/src/main/kotlin/templates/JsonElementBasedTemplateProcessingStrategy.kt b/plugins/all-modules-page/src/main/kotlin/templates/JsonElementBasedTemplateProcessingStrategy.kt new file mode 100644 index 00000000..c6c67752 --- /dev/null +++ b/plugins/all-modules-page/src/main/kotlin/templates/JsonElementBasedTemplateProcessingStrategy.kt @@ -0,0 +1,74 @@ +package org.jetbrains.dokka.allModulesPage.templates + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import java.io.File +import java.nio.file.Files +import com.fasterxml.jackson.module.kotlin.treeToValue +import org.jetbrains.dokka.base.renderers.html.SearchRecord +import org.jetbrains.dokka.base.templating.* +import org.jetbrains.dokka.plugability.DokkaContext +import java.util.concurrent.ConcurrentHashMap + +abstract class BaseJsonNavigationTemplateProcessingStrategy(val context: DokkaContext) : TemplateProcessingStrategy { + abstract val navigationFileNameWithoutExtension: String + abstract val path: String + + private val fragments = ConcurrentHashMap>() + + open fun canProcess(file: File): Boolean = + file.extension == "json" && file.nameWithoutExtension == navigationFileNameWithoutExtension + + override suspend fun process(input: File, output: File): Boolean = coroutineScope { + val canProcess = canProcess(input) + if (canProcess) { + launch { + withContext(Dispatchers.IO) { + runCatching { parseJson(input.readText()) }.getOrNull() + }?.let { command -> + fragments[command.moduleName] = command.elements + } ?: fallbackToCopy(input, output) + } + } + canProcess + } + + override suspend fun finish(output: File) { + if (fragments.isNotEmpty()) { + val content = toJsonString(fragments.entries.flatMap { (moduleName, navigation) -> + navigation.map { it.withResolvedLocation(moduleName) } + }) + withContext(Dispatchers.IO) { + output.resolve("$path/$navigationFileNameWithoutExtension.json").writeText(content) + + fragments.keys.forEach { + output.resolve(it).resolve("$path/$navigationFileNameWithoutExtension.json").writeText(content) + } + } + } + } + + private suspend fun fallbackToCopy(input: File, output: File) { + context.logger.warn("Falling back to just copying file for ${input.name} even thought it should process it") + withContext(Dispatchers.IO) { input.copyTo(output) } + } + + private fun SearchRecord.withResolvedLocation(moduleName: String): SearchRecord = + copy(location = "$moduleName/$location") + +} + +class NavigationSearchTemplateStrategy(val dokkaContext: DokkaContext) : + BaseJsonNavigationTemplateProcessingStrategy(dokkaContext) { + override val navigationFileNameWithoutExtension: String = "navigation-pane" + override val path: String = "scripts" +} + +class PagesSearchTemplateStrategy(val dokkaContext: DokkaContext) : + BaseJsonNavigationTemplateProcessingStrategy(dokkaContext) { + override val navigationFileNameWithoutExtension: String = "pages" + override val path: String = "scripts" +} \ No newline at end of file diff --git a/plugins/base/frontend/src/main/components/navigationPaneSearch/navigationPaneSearch.tsx b/plugins/base/frontend/src/main/components/navigationPaneSearch/navigationPaneSearch.tsx index b11b36f6..152e7719 100644 --- a/plugins/base/frontend/src/main/components/navigationPaneSearch/navigationPaneSearch.tsx +++ b/plugins/base/frontend/src/main/components/navigationPaneSearch/navigationPaneSearch.tsx @@ -4,6 +4,7 @@ import { DokkaFuzzyFilterComponent } from '../search/dokkaFuzzyFilter'; import { IWindow, Option } from '../search/types'; import './navigationPaneSearch.scss'; import ClearIcon from 'react-svg-loader!./clear.svg'; +import { relativizeUrlForRequest } from '../utils/requests'; export const NavigationPaneSearch = () => { const [navigationList, setNavigationList] = useState([]); @@ -31,9 +32,7 @@ export const NavigationPaneSearch = () => { } useEffect(() => { - const pathToRoot = (window as IWindow).pathToRoot - const url = pathToRoot.endsWith('/') ? `${pathToRoot}scripts/navigation-pane.json` : `${pathToRoot}/scripts/navigation-pane.json` - fetch(url) + fetch(relativizeUrlForRequest('scripts/navigation-pane.json')) .then(response => response.json()) .then((result) => { setNavigationList(result.map((record: Option, idx: number) => { diff --git a/plugins/base/frontend/src/main/components/search/search.tsx b/plugins/base/frontend/src/main/components/search/search.tsx index 3616a396..f0527cc0 100644 --- a/plugins/base/frontend/src/main/components/search/search.tsx +++ b/plugins/base/frontend/src/main/components/search/search.tsx @@ -1,10 +1,11 @@ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { Select, List } from '@jetbrains/ring-ui'; import '@jetbrains/ring-ui/components/input-size/input-size.scss'; import './search.scss'; import { IWindow, Option, Props } from "./types"; import { DokkaSearchAnchor } from "./dokkaSearchAnchor"; import { DokkaFuzzyFilterComponent } from "./dokkaFuzzyFilter"; +import { relativizeUrlForRequest } from '../utils/requests'; const WithFuzzySearchFilterComponent: React.FC = ({ data }: Props) => { const [selected, onSelected] = useState