From 12256cfa4e8f495d62549d860a5ad9a5e03d6122 Mon Sep 17 00:00:00 2001 From: vmishenev Date: Thu, 17 Feb 2022 00:28:58 +0300 Subject: [PATCH 1/4] Keep template commands in html comments --- plugins/base/api/base.api | 4 ++ .../kotlin/renderers/html/HtmlRenderer.kt | 22 ++++--- .../src/main/kotlin/renderers/html/Tags.kt | 11 ++++ .../kotlin/resourceLinks/ResourceLinksTest.kt | 7 ++- plugins/templating/api/templating.api | 24 +++++-- .../main/kotlin/templates/CommandHandler.kt | 7 +++ .../DirectiveBasedTemplateProcessing.kt | 49 +++++++++++++++ .../templates/SubstitutionCommandHandler.kt | 29 +++++---- .../kotlin/templates/TemplateProcessor.kt | 4 +- .../SubstitutionCommandResolutionTest.kt | 62 ++++++++++++++++--- 10 files changed, 177 insertions(+), 42 deletions(-) diff --git a/plugins/base/api/base.api b/plugins/base/api/base.api index b17b405294..8ee15183f7 100644 --- a/plugins/base/api/base.api +++ b/plugins/base/api/base.api @@ -512,6 +512,8 @@ public final class org/jetbrains/dokka/base/renderers/html/StylesInstaller : org } public final class org/jetbrains/dokka/base/renderers/html/TagsKt { + public static final field TEMPLATE_COMMAND_BEGIN_BORDER Ljava/lang/String; + public static final field TEMPLATE_COMMAND_END_BORDER Ljava/lang/String; public static final fun buildAsInnerHtml (Lkotlin/jvm/functions/Function1;)Ljava/lang/String; public static final fun strike (Lkotlinx/html/FlowOrPhrasingContent;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V public static synthetic fun strike$default (Lkotlinx/html/FlowOrPhrasingContent;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V @@ -519,6 +521,8 @@ public final class org/jetbrains/dokka/base/renderers/html/TagsKt { public static final fun templateCommand (Lkotlinx/html/TagConsumer;Lorg/jetbrains/dokka/base/templating/Command;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static synthetic fun templateCommand$default (Lkotlinx/html/FlowOrMetaDataContent;Lorg/jetbrains/dokka/base/templating/Command;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V public static synthetic fun templateCommand$default (Lkotlinx/html/TagConsumer;Lorg/jetbrains/dokka/base/templating/Command;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ljava/lang/Object; + public static final fun templateCommandAsHtmlComment (Lkotlinx/html/FlowOrMetaDataContent;Lorg/jetbrains/dokka/base/templating/Command;Lkotlin/jvm/functions/Function1;)V + public static synthetic fun templateCommandAsHtmlComment$default (Lkotlinx/html/FlowOrMetaDataContent;Lorg/jetbrains/dokka/base/templating/Command;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V public static final fun templateCommandFor (Lorg/jetbrains/dokka/base/templating/Command;Lkotlinx/html/TagConsumer;)Lorg/jetbrains/dokka/base/renderers/html/TemplateCommand; public static final fun wbr (Lkotlinx/html/FlowOrPhrasingContent;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V public static synthetic fun wbr$default (Lkotlinx/html/FlowOrPhrasingContent;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index 4dd020ce13..0ba085cd1f 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -23,6 +23,8 @@ import org.jetbrains.dokka.utilities.htmlEscape import org.jetbrains.kotlin.utils.addIfNotNull import java.net.URI +internal const val TEMPLATE_REPLACEMENT: String = "###" + open class HtmlRenderer( context: DokkaContext ) : DefaultRenderer(context) { @@ -779,11 +781,11 @@ open class HtmlRenderer( head { meta(name = "viewport", content = "width=device-width, initial-scale=1", charset = "UTF-8") title(page.name) - templateCommand(PathToRootSubstitutionCommand("###", default = pathToRoot)) { - link(href = "###images/logo-icon.svg", rel = "icon", type = "image/svg") + templateCommandAsHtmlComment(PathToRootSubstitutionCommand(TEMPLATE_REPLACEMENT, default = pathToRoot)) { + link(href = "${TEMPLATE_REPLACEMENT}images/logo-icon.svg", rel = "icon", type = "image/svg") } - templateCommand(PathToRootSubstitutionCommand("###", default = pathToRoot)) { - script { unsafe { +"""var pathToRoot = "###";""" } } + templateCommandAsHtmlComment(PathToRootSubstitutionCommand(TEMPLATE_REPLACEMENT, default = pathToRoot)) { + script { unsafe { +"""var pathToRoot = "$TEMPLATE_REPLACEMENT";""" } } } // 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 { @@ -804,10 +806,10 @@ open class HtmlRenderer( rel = LinkRel.stylesheet, href = it ) - else templateCommand(PathToRootSubstitutionCommand("###", default = pathToRoot)) { + else templateCommandAsHtmlComment(PathToRootSubstitutionCommand(TEMPLATE_REPLACEMENT, default = pathToRoot)) { link( rel = LinkRel.stylesheet, - href = "###$it" + href = TEMPLATE_REPLACEMENT + it ) } it.substringBefore('?').substringAfterLast('.') == "js" -> @@ -816,10 +818,10 @@ open class HtmlRenderer( src = it ) { async = true - } else templateCommand(PathToRootSubstitutionCommand("###", default = pathToRoot)) { + } else templateCommandAsHtmlComment(PathToRootSubstitutionCommand(TEMPLATE_REPLACEMENT, default = pathToRoot)) { script( type = ScriptType.textJavaScript, - src = "###$it" + src = TEMPLATE_REPLACEMENT + it ) { if (it == "scripts/main.js") defer = true @@ -828,8 +830,8 @@ open class HtmlRenderer( } } it.isImage() -> if (it.isAbsolute) link(href = it) - else templateCommand(PathToRootSubstitutionCommand("###", default = pathToRoot)) { - link(href = "###$it") + else templateCommandAsHtmlComment(PathToRootSubstitutionCommand(TEMPLATE_REPLACEMENT, default = pathToRoot)) { + link(href = TEMPLATE_REPLACEMENT + it) } else -> unsafe { +it } } diff --git a/plugins/base/src/main/kotlin/renderers/html/Tags.kt b/plugins/base/src/main/kotlin/renderers/html/Tags.kt index a23c7bf16e..ec4603ac5f 100644 --- a/plugins/base/src/main/kotlin/renderers/html/Tags.kt +++ b/plugins/base/src/main/kotlin/renderers/html/Tags.kt @@ -26,6 +26,17 @@ inline fun FlowOrPhrasingContent.strike(classes : String? = null, crossinline bl open class STRIKE(initialAttributes: Map, override val consumer: TagConsumer<*>) : HTMLTag("strike", consumer, initialAttributes, null, false, false), HtmlBlockInlineTag +const val TEMPLATE_COMMAND_BEGIN_BORDER = "[+]cmd:" +const val TEMPLATE_COMMAND_END_BORDER = "[-]cmd" + +fun FlowOrMetaDataContent.templateCommandAsHtmlComment(data: Command, block: FlowOrMetaDataContent.() -> Unit = {}): Unit = + (consumer as? ImmediateResolutionTagConsumer)?.processCommand(data, block) + ?: let{ + comment( "$TEMPLATE_COMMAND_BEGIN_BORDER${toJsonString(data)}") + block() + comment(TEMPLATE_COMMAND_END_BORDER) + } + fun FlowOrMetaDataContent.templateCommand(data: Command, block: TemplateBlock = {}): Unit = (consumer as? ImmediateResolutionTagConsumer)?.processCommand(data, block) ?: TemplateCommand(attributesMapOf("data", toJsonString(data)), consumer).visit(block) diff --git a/plugins/base/src/test/kotlin/resourceLinks/ResourceLinksTest.kt b/plugins/base/src/test/kotlin/resourceLinks/ResourceLinksTest.kt index 9b010b56b7..fb9ec10eac 100644 --- a/plugins/base/src/test/kotlin/resourceLinks/ResourceLinksTest.kt +++ b/plugins/base/src/test/kotlin/resourceLinks/ResourceLinksTest.kt @@ -4,10 +4,11 @@ import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.PluginConfigurationImpl import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.DokkaBaseConfiguration +import org.jetbrains.dokka.base.renderers.html.TEMPLATE_REPLACEMENT import org.jetbrains.dokka.base.templating.toJsonString +import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest import org.jetbrains.dokka.pages.RootPageNode import org.jetbrains.dokka.plugability.DokkaPlugin -import org.jetbrains.dokka.base.testApi.testRunner.BaseAbstractTest import org.jetbrains.dokka.transformers.pages.PageTransformer import org.jsoup.Jsoup import org.junit.jupiter.api.Test @@ -125,11 +126,11 @@ class ResourceLinksTest : BaseAbstractTest() { if (isMultiModule) { Jsoup .parse(writerPlugin.writer.contents["example.html"]) - .body() + .head() .select("link, script") .let { listOf("styles/customStyle.css").forEach { r -> - assert(it.`is`("[href=###$r]")) + assert(it.`is`("[href=$TEMPLATE_REPLACEMENT$r]")) } } } else { diff --git a/plugins/templating/api/templating.api b/plugins/templating/api/templating.api index a0fb512288..6ad3983123 100644 --- a/plugins/templating/api/templating.api +++ b/plugins/templating/api/templating.api @@ -40,6 +40,16 @@ public final class org/jetbrains/dokka/templates/CommandHandler$DefaultImpls { public static fun finish (Lorg/jetbrains/dokka/templates/CommandHandler;Ljava/io/File;)V } +public abstract interface class org/jetbrains/dokka/templates/CommentCommandHandler { + public abstract fun canHandle (Lorg/jetbrains/dokka/base/templating/Command;)Z + public abstract fun finish (Ljava/io/File;)V + public abstract fun handleCommand (Ljava/util/List;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V +} + +public final class org/jetbrains/dokka/templates/CommentCommandHandler$DefaultImpls { + public static fun finish (Lorg/jetbrains/dokka/templates/CommentCommandHandler;Ljava/io/File;)V +} + public final class org/jetbrains/dokka/templates/DefaultMultiModuleTemplateProcessor : org/jetbrains/dokka/templates/MultiModuleTemplateProcessor { public fun (Lorg/jetbrains/dokka/plugability/DokkaContext;)V public final fun getContext ()Lorg/jetbrains/dokka/plugability/DokkaContext; @@ -54,6 +64,7 @@ public final class org/jetbrains/dokka/templates/DefaultSubmoduleTemplateProcess public final class org/jetbrains/dokka/templates/DirectiveBasedHtmlTemplateProcessingStrategy : org/jetbrains/dokka/templates/TemplateProcessingStrategy { public fun (Lorg/jetbrains/dokka/plugability/DokkaContext;)V public fun finish (Ljava/io/File;)V + public final fun handleCommand (Ljava/util/List;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public final fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public fun process (Ljava/io/File;Ljava/io/File;Lorg/jetbrains/dokka/DokkaConfiguration$DokkaModuleDescription;)Z } @@ -77,10 +88,11 @@ public abstract interface class org/jetbrains/dokka/templates/SubmoduleTemplateP public abstract fun process (Ljava/util/List;)Lorg/jetbrains/dokka/templates/TemplatingResult; } -public final class org/jetbrains/dokka/templates/SubstitutionCommandHandler : org/jetbrains/dokka/templates/CommandHandler { +public final class org/jetbrains/dokka/templates/SubstitutionCommandHandler : org/jetbrains/dokka/templates/CommandHandler, org/jetbrains/dokka/templates/CommentCommandHandler { public fun (Lorg/jetbrains/dokka/plugability/DokkaContext;)V public fun canHandle (Lorg/jetbrains/dokka/base/templating/Command;)Z public fun finish (Ljava/io/File;)V + public fun handleCommand (Ljava/util/List;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V } @@ -101,17 +113,17 @@ public abstract interface class org/jetbrains/dokka/templates/TemplateProcessor } public final class org/jetbrains/dokka/templates/TemplatingContext { - public fun (Ljava/io/File;Ljava/io/File;Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;)V + public fun (Ljava/io/File;Ljava/io/File;Ljava/util/List;Lorg/jetbrains/dokka/base/templating/Command;)V public final fun component1 ()Ljava/io/File; public final fun component2 ()Ljava/io/File; - public final fun component3 ()Lorg/jsoup/nodes/Element; + public final fun component3 ()Ljava/util/List; public final fun component4 ()Lorg/jetbrains/dokka/base/templating/Command; - public final fun copy (Ljava/io/File;Ljava/io/File;Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;)Lorg/jetbrains/dokka/templates/TemplatingContext; - public static synthetic fun copy$default (Lorg/jetbrains/dokka/templates/TemplatingContext;Ljava/io/File;Ljava/io/File;Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;ILjava/lang/Object;)Lorg/jetbrains/dokka/templates/TemplatingContext; + public final fun copy (Ljava/io/File;Ljava/io/File;Ljava/util/List;Lorg/jetbrains/dokka/base/templating/Command;)Lorg/jetbrains/dokka/templates/TemplatingContext; + public static synthetic fun copy$default (Lorg/jetbrains/dokka/templates/TemplatingContext;Ljava/io/File;Ljava/io/File;Ljava/util/List;Lorg/jetbrains/dokka/base/templating/Command;ILjava/lang/Object;)Lorg/jetbrains/dokka/templates/TemplatingContext; public fun equals (Ljava/lang/Object;)Z public final fun getCommand ()Lorg/jetbrains/dokka/base/templating/Command; - public final fun getElement ()Lorg/jsoup/nodes/Element; public final fun getInput ()Ljava/io/File; + public final fun getNodes ()Ljava/util/List; public final fun getOutput ()Ljava/io/File; public fun hashCode ()I public fun toString ()Ljava/lang/String; diff --git a/plugins/templating/src/main/kotlin/templates/CommandHandler.kt b/plugins/templating/src/main/kotlin/templates/CommandHandler.kt index d72092a19c..30277648b5 100644 --- a/plugins/templating/src/main/kotlin/templates/CommandHandler.kt +++ b/plugins/templating/src/main/kotlin/templates/CommandHandler.kt @@ -2,10 +2,17 @@ package org.jetbrains.dokka.templates import org.jetbrains.dokka.base.templating.Command import org.jsoup.nodes.Element +import org.jsoup.nodes.Node import java.io.File interface CommandHandler { fun handleCommand(element: Element, command: Command, input: File, output: File) fun canHandle(command: Command): Boolean fun finish(output: File) {} +} + +interface CommentCommandHandler { + fun handleCommand(nodes: List, command: Command, input: File, output: File) + fun canHandle(command: Command): Boolean + fun finish(output: File) {} } \ No newline at end of file diff --git a/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt b/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt index 2b4951a171..e242cd53e1 100644 --- a/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt +++ b/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt @@ -1,13 +1,18 @@ package org.jetbrains.dokka.templates import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.base.renderers.html.TEMPLATE_COMMAND_BEGIN_BORDER +import org.jetbrains.dokka.base.renderers.html.TEMPLATE_COMMAND_END_BORDER import org.jetbrains.dokka.base.templating.Command import org.jetbrains.dokka.base.templating.parseJson import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.plugin import org.jetbrains.dokka.plugability.query import org.jsoup.Jsoup +import org.jsoup.nodes.Comment import org.jsoup.nodes.Element +import org.jsoup.nodes.Node +import org.jsoup.nodes.TextNode import java.io.File import java.nio.file.Files @@ -20,9 +25,17 @@ class DirectiveBasedHtmlTemplateProcessingStrategy(private val context: DokkaCon if (input.isFile && input.extension == "html") { val document = Jsoup.parse(input, "UTF-8") document.outputSettings().indentAmount(0).prettyPrint(false) + document.select("dokka-template-command").forEach { handleCommand(it, parseJson(it.attr("data")), input, output) } + extractCommandsFromComments(document) { nodes, command -> + val nodesTrimed = + nodes.dropWhile { (it is TextNode && it.isBlank).also { res -> if (res) it.remove() } } + .dropLastWhile { (it is TextNode && it.isBlank).also { res -> if (res) it.remove() } } + handleCommand(nodesTrimed, command, input, output) + } + Files.write(output.toPath(), listOf(document.outerHtml())) true } else false @@ -33,7 +46,43 @@ class DirectiveBasedHtmlTemplateProcessingStrategy(private val context: DokkaCon context.logger.warn("Unknown templating command $command") else handlers.forEach { it.handleCommand(element, command, input, output) } + } + + fun handleCommand(nodes: List, command: Command, input: File, output: File) { + val handlers = directiveBasedCommandHandlers.filterIsInstance().filter { it.canHandle(command) } + if (handlers.isEmpty()) + context.logger.warn("Unknown templating command $command") + else + handlers.forEach { it.handleCommand(nodes, command, input, output) } + } + private fun extractCommandsFromComments(node: Node, startFrom: Int = 0, handler: (List, Command) -> Unit) { + val nodes: MutableList = mutableListOf() + var lastStartBorder: Comment? = null + var firstStartBorder: Comment? = null + for (ind in startFrom until node.childNodeSize()) { + when (val currentChild = node.childNode(ind)) { + is Comment -> if (currentChild.data?.startsWith(TEMPLATE_COMMAND_BEGIN_BORDER) == true) { + lastStartBorder = currentChild + firstStartBorder = firstStartBorder ?: currentChild + nodes.clear() + } else if (lastStartBorder != null && currentChild.data?.startsWith(TEMPLATE_COMMAND_END_BORDER) == true) { + lastStartBorder.remove() + val cmd: Command? = + lastStartBorder.data?.removePrefix(TEMPLATE_COMMAND_BEGIN_BORDER)?.let { parseJson(it) } + cmd?.let { handler(nodes, it) } + currentChild.remove() + extractCommandsFromComments(node, firstStartBorder?.siblingIndex() ?: 0, handler) + return + } else { + lastStartBorder?.let { nodes.add(currentChild) } + } + else -> { + extractCommandsFromComments(currentChild, handler = handler) + lastStartBorder?.let { nodes.add(currentChild) } + } + } + } } override fun finish(output: File) { diff --git a/plugins/templating/src/main/kotlin/templates/SubstitutionCommandHandler.kt b/plugins/templating/src/main/kotlin/templates/SubstitutionCommandHandler.kt index c7b151378e..faceef4f51 100644 --- a/plugins/templating/src/main/kotlin/templates/SubstitutionCommandHandler.kt +++ b/plugins/templating/src/main/kotlin/templates/SubstitutionCommandHandler.kt @@ -11,30 +11,37 @@ import org.jsoup.nodes.Node import org.jsoup.nodes.TextNode import java.io.File -class SubstitutionCommandHandler(context: DokkaContext) : CommandHandler { +class SubstitutionCommandHandler(context: DokkaContext) : CommandHandler, CommentCommandHandler { override fun handleCommand(element: Element, command: Command, input: File, output: File) { command as SubstitutionCommand - substitute(element, TemplatingContext(input, output, element, command)) + val childrenCopy = element.children().toList() + substitute(childrenCopy, TemplatingContext(input, output, childrenCopy, command)) + + val position = element.elementSiblingIndex() + val parent = element.parent() + element.remove() + + parent?.insertChildren(position, childrenCopy) + } + + override fun handleCommand(nodes: List, command: Command, input: File, output: File) { + command as SubstitutionCommand + substitute(nodes, TemplatingContext(input, output, nodes, command)) } override fun canHandle(command: Command): Boolean = command is SubstitutionCommand + override fun finish(output: File) { } + private val substitutors = context.plugin().query { substitutor } private fun findSubstitution(commandContext: TemplatingContext, match: MatchResult): String = substitutors.asSequence().mapNotNull { it.trySubstitute(commandContext, match) }.firstOrNull() ?: match.value - private fun substitute(element: Element, commandContext: TemplatingContext) { + private fun substitute(elements: List, commandContext: TemplatingContext) { val regex = commandContext.command.pattern.toRegex() - element.children().forEach { it.traverseToSubstitute(regex, commandContext) } - - val childrenCopy = element.children().toList() - val position = element.elementSiblingIndex() - val parent = element.parent() - element.remove() - - parent.insertChildren(position, childrenCopy) + elements.forEach { it.traverseToSubstitute(regex, commandContext) } } private fun Node.traverseToSubstitute(regex: Regex, commandContext: TemplatingContext) { diff --git a/plugins/templating/src/main/kotlin/templates/TemplateProcessor.kt b/plugins/templating/src/main/kotlin/templates/TemplateProcessor.kt index 5f36530bbf..9ea9139955 100644 --- a/plugins/templating/src/main/kotlin/templates/TemplateProcessor.kt +++ b/plugins/templating/src/main/kotlin/templates/TemplateProcessor.kt @@ -12,7 +12,7 @@ import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.plugability.plugin import org.jetbrains.dokka.plugability.query import org.jetbrains.dokka.plugability.querySingle -import org.jsoup.nodes.Element +import org.jsoup.nodes.Node import java.io.File interface TemplateProcessor @@ -88,7 +88,7 @@ class DefaultMultiModuleTemplateProcessor( data class TemplatingContext( val input: File, val output: File, - val element: Element, + val nodes: List, val command: T, ) diff --git a/plugins/templating/src/test/kotlin/templates/SubstitutionCommandResolutionTest.kt b/plugins/templating/src/test/kotlin/templates/SubstitutionCommandResolutionTest.kt index ce2a8afdc7..44acf34061 100644 --- a/plugins/templating/src/test/kotlin/templates/SubstitutionCommandResolutionTest.kt +++ b/plugins/templating/src/test/kotlin/templates/SubstitutionCommandResolutionTest.kt @@ -3,13 +3,15 @@ package org.jetbrains.dokka.templates import kotlinx.html.a import kotlinx.html.div import kotlinx.html.id +import kotlinx.html.span import kotlinx.html.stream.createHTML import org.jetbrains.dokka.DokkaModuleDescriptionImpl import org.jetbrains.dokka.base.renderers.html.templateCommand +import org.jetbrains.dokka.base.renderers.html.templateCommandAsHtmlComment import org.jetbrains.dokka.base.templating.PathToRootSubstitutionCommand import org.junit.Rule -import org.junit.rules.TemporaryFolder import org.junit.jupiter.api.Test +import org.junit.rules.TemporaryFolder import utils.assertHtmlEqualsIgnoringWhitespace import java.io.File @@ -36,7 +38,56 @@ class SubstitutionCommandResolutionTest : TemplatingAbstractTest() { id = "logo" } } + checkSubstitutedResult(template, expected) + } + + @Test + fun `should handle PathToRootCommand as HTML comment`() { + val template = createHTML().span { + templateCommandAsHtmlComment(PathToRootSubstitutionCommand(pattern = "###", default = "default")) { + this@span.a { + href = "###index.html" + div { + id = "logo" + } + } + templateCommandAsHtmlComment(PathToRootSubstitutionCommand(pattern = "####", default = "default")) { + this@span.a { + href = "####index.html" + div { + id = "logo" + } + } + } + } + } + + val expected = createHTML().span { + a { + href = "../index.html" + div { + id = "logo" + } + } + a { + href = "../index.html" + div { + id = "logo" + } + } + } + checkSubstitutedResult(template, expected) + } + + private fun createDirectoriesAndWriteContent(content: String): File { + folder.create() + val module1 = folder.newFolder("module1") + val module1Content = module1.resolve("index.html") + module1Content.writeText(content) + return module1Content + } + private fun checkSubstitutedResult(template: String, expected:String) { val testedFile = createDirectoriesAndWriteContent(template) val configuration = dokkaConfiguration { @@ -57,13 +108,4 @@ class SubstitutionCommandResolutionTest : TemplatingAbstractTest() { } } } - - private fun createDirectoriesAndWriteContent(content: String): File { - folder.create() - val module1 = folder.newFolder("module1") - val module1Content = module1.resolve("index.html") - module1Content.writeText(content) - return module1Content - } - } From dc93c71bb156807923b1fc5b2a5ce62cd390ff47 Mon Sep 17 00:00:00 2001 From: vmishenev Date: Fri, 18 Feb 2022 19:29:48 +0300 Subject: [PATCH 2/4] Refactor --- .../all-modules-page/api/all-modules-page.api | 1 + plugins/base/api/base.api | 1 + .../src/main/kotlin/renderers/html/Tags.kt | 5 +- .../consumers/ReplaceVersionsConsumer.kt | 2 +- plugins/templating/api/templating.api | 24 ++++----- .../main/kotlin/templates/CommandHandler.kt | 10 ++-- .../DirectiveBasedTemplateProcessing.kt | 49 ++++++++++--------- .../templates/SubstitutionCommandHandler.kt | 6 +-- .../kotlin/templates/TemplateProcessor.kt | 2 +- plugins/versioning/api/versioning.api | 1 + 10 files changed, 50 insertions(+), 51 deletions(-) diff --git a/plugins/all-modules-page/api/all-modules-page.api b/plugins/all-modules-page/api/all-modules-page.api index 9d8bca9b48..d9724a9a2d 100644 --- a/plugins/all-modules-page/api/all-modules-page.api +++ b/plugins/all-modules-page/api/all-modules-page.api @@ -83,5 +83,6 @@ public final class org/jetbrains/dokka/allModulesPage/ResolveLinkCommandHandler public fun canHandle (Lorg/jetbrains/dokka/base/templating/Command;)Z public fun finish (Ljava/io/File;)V public fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V + public fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V } diff --git a/plugins/base/api/base.api b/plugins/base/api/base.api index 8ee15183f7..6906627c5e 100644 --- a/plugins/base/api/base.api +++ b/plugins/base/api/base.api @@ -514,6 +514,7 @@ public final class org/jetbrains/dokka/base/renderers/html/StylesInstaller : org public final class org/jetbrains/dokka/base/renderers/html/TagsKt { public static final field TEMPLATE_COMMAND_BEGIN_BORDER Ljava/lang/String; public static final field TEMPLATE_COMMAND_END_BORDER Ljava/lang/String; + public static final field TEMPLATE_COMMAND_SEPARATOR Ljava/lang/String; public static final fun buildAsInnerHtml (Lkotlin/jvm/functions/Function1;)Ljava/lang/String; public static final fun strike (Lkotlinx/html/FlowOrPhrasingContent;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V public static synthetic fun strike$default (Lkotlinx/html/FlowOrPhrasingContent;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V diff --git a/plugins/base/src/main/kotlin/renderers/html/Tags.kt b/plugins/base/src/main/kotlin/renderers/html/Tags.kt index ec4603ac5f..94a53c27fb 100644 --- a/plugins/base/src/main/kotlin/renderers/html/Tags.kt +++ b/plugins/base/src/main/kotlin/renderers/html/Tags.kt @@ -26,13 +26,14 @@ inline fun FlowOrPhrasingContent.strike(classes : String? = null, crossinline bl open class STRIKE(initialAttributes: Map, override val consumer: TagConsumer<*>) : HTMLTag("strike", consumer, initialAttributes, null, false, false), HtmlBlockInlineTag -const val TEMPLATE_COMMAND_BEGIN_BORDER = "[+]cmd:" +const val TEMPLATE_COMMAND_SEPARATOR = ":" +const val TEMPLATE_COMMAND_BEGIN_BORDER = "[+]cmd" const val TEMPLATE_COMMAND_END_BORDER = "[-]cmd" fun FlowOrMetaDataContent.templateCommandAsHtmlComment(data: Command, block: FlowOrMetaDataContent.() -> Unit = {}): Unit = (consumer as? ImmediateResolutionTagConsumer)?.processCommand(data, block) ?: let{ - comment( "$TEMPLATE_COMMAND_BEGIN_BORDER${toJsonString(data)}") + comment( "$TEMPLATE_COMMAND_BEGIN_BORDER$TEMPLATE_COMMAND_SEPARATOR${toJsonString(data)}") block() comment(TEMPLATE_COMMAND_END_BORDER) } diff --git a/plugins/base/src/main/kotlin/renderers/html/command/consumers/ReplaceVersionsConsumer.kt b/plugins/base/src/main/kotlin/renderers/html/command/consumers/ReplaceVersionsConsumer.kt index ea8cde0f4c..bbc33164a7 100644 --- a/plugins/base/src/main/kotlin/renderers/html/command/consumers/ReplaceVersionsConsumer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/command/consumers/ReplaceVersionsConsumer.kt @@ -19,7 +19,7 @@ class ReplaceVersionsConsumer(private val context: DokkaContext) : ImmediateHtml } override fun processCommandAndFinalize(command: Command, block: TemplateBlock, tagConsumer: ImmediateResolutionTagConsumer): R { - PathToRootConsumer.processCommand(command, block, tagConsumer) + processCommand(command, block, tagConsumer) return tagConsumer.finalize() } } \ No newline at end of file diff --git a/plugins/templating/api/templating.api b/plugins/templating/api/templating.api index 6ad3983123..17c9751553 100644 --- a/plugins/templating/api/templating.api +++ b/plugins/templating/api/templating.api @@ -28,26 +28,19 @@ public final class org/jetbrains/dokka/templates/AddToNavigationCommandHandler : public fun finish (Ljava/io/File;)V public final fun getContext ()Lorg/jetbrains/dokka/plugability/DokkaContext; public fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V + public fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V } public abstract interface class org/jetbrains/dokka/templates/CommandHandler { public abstract fun canHandle (Lorg/jetbrains/dokka/base/templating/Command;)Z public abstract fun finish (Ljava/io/File;)V public abstract fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V + public abstract fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V } public final class org/jetbrains/dokka/templates/CommandHandler$DefaultImpls { public static fun finish (Lorg/jetbrains/dokka/templates/CommandHandler;Ljava/io/File;)V -} - -public abstract interface class org/jetbrains/dokka/templates/CommentCommandHandler { - public abstract fun canHandle (Lorg/jetbrains/dokka/base/templating/Command;)Z - public abstract fun finish (Ljava/io/File;)V - public abstract fun handleCommand (Ljava/util/List;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V -} - -public final class org/jetbrains/dokka/templates/CommentCommandHandler$DefaultImpls { - public static fun finish (Lorg/jetbrains/dokka/templates/CommentCommandHandler;Ljava/io/File;)V + public static fun handleCommandAsComment (Lorg/jetbrains/dokka/templates/CommandHandler;Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V } public final class org/jetbrains/dokka/templates/DefaultMultiModuleTemplateProcessor : org/jetbrains/dokka/templates/MultiModuleTemplateProcessor { @@ -64,8 +57,8 @@ public final class org/jetbrains/dokka/templates/DefaultSubmoduleTemplateProcess public final class org/jetbrains/dokka/templates/DirectiveBasedHtmlTemplateProcessingStrategy : org/jetbrains/dokka/templates/TemplateProcessingStrategy { public fun (Lorg/jetbrains/dokka/plugability/DokkaContext;)V public fun finish (Ljava/io/File;)V - public final fun handleCommand (Ljava/util/List;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V - public final fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V + public final fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V + public final fun handleCommandAsTag (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public fun process (Ljava/io/File;Ljava/io/File;Lorg/jetbrains/dokka/DokkaConfiguration$DokkaModuleDescription;)Z } @@ -88,12 +81,12 @@ public abstract interface class org/jetbrains/dokka/templates/SubmoduleTemplateP public abstract fun process (Ljava/util/List;)Lorg/jetbrains/dokka/templates/TemplatingResult; } -public final class org/jetbrains/dokka/templates/SubstitutionCommandHandler : org/jetbrains/dokka/templates/CommandHandler, org/jetbrains/dokka/templates/CommentCommandHandler { +public final class org/jetbrains/dokka/templates/SubstitutionCommandHandler : org/jetbrains/dokka/templates/CommandHandler { public fun (Lorg/jetbrains/dokka/plugability/DokkaContext;)V public fun canHandle (Lorg/jetbrains/dokka/base/templating/Command;)Z public fun finish (Ljava/io/File;)V - public fun handleCommand (Ljava/util/List;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V + public fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V } public abstract interface class org/jetbrains/dokka/templates/Substitutor { @@ -121,9 +114,9 @@ public final class org/jetbrains/dokka/templates/TemplatingContext { public final fun copy (Ljava/io/File;Ljava/io/File;Ljava/util/List;Lorg/jetbrains/dokka/base/templating/Command;)Lorg/jetbrains/dokka/templates/TemplatingContext; public static synthetic fun copy$default (Lorg/jetbrains/dokka/templates/TemplatingContext;Ljava/io/File;Ljava/io/File;Ljava/util/List;Lorg/jetbrains/dokka/base/templating/Command;ILjava/lang/Object;)Lorg/jetbrains/dokka/templates/TemplatingContext; public fun equals (Ljava/lang/Object;)Z + public final fun getBody ()Ljava/util/List; public final fun getCommand ()Lorg/jetbrains/dokka/base/templating/Command; public final fun getInput ()Ljava/io/File; - public final fun getNodes ()Ljava/util/List; public final fun getOutput ()Ljava/io/File; public fun hashCode ()I public fun toString ()Ljava/lang/String; @@ -174,6 +167,7 @@ public final class templates/ReplaceVersionCommandHandler : org/jetbrains/dokka/ public fun canHandle (Lorg/jetbrains/dokka/base/templating/Command;)Z public fun finish (Ljava/io/File;)V public fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V + public fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V } public final class templates/SourcesetDependencyProcessingStrategy : org/jetbrains/dokka/templates/TemplateProcessingStrategy { diff --git a/plugins/templating/src/main/kotlin/templates/CommandHandler.kt b/plugins/templating/src/main/kotlin/templates/CommandHandler.kt index 30277648b5..772754564c 100644 --- a/plugins/templating/src/main/kotlin/templates/CommandHandler.kt +++ b/plugins/templating/src/main/kotlin/templates/CommandHandler.kt @@ -5,14 +5,10 @@ import org.jsoup.nodes.Element import org.jsoup.nodes.Node import java.io.File -interface CommandHandler { - fun handleCommand(element: Element, command: Command, input: File, output: File) - fun canHandle(command: Command): Boolean - fun finish(output: File) {} -} -interface CommentCommandHandler { - fun handleCommand(nodes: List, command: Command, input: File, output: File) +interface CommandHandler { + fun handleCommand(element: Element, command: Command, input: File, output: File) + fun handleCommandAsComment(command: Command, body: List, input: File, output: File) { } fun canHandle(command: Command): Boolean fun finish(output: File) {} } \ No newline at end of file diff --git a/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt b/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt index e242cd53e1..d5579f8a16 100644 --- a/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt +++ b/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt @@ -3,6 +3,7 @@ package org.jetbrains.dokka.templates import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.base.renderers.html.TEMPLATE_COMMAND_BEGIN_BORDER import org.jetbrains.dokka.base.renderers.html.TEMPLATE_COMMAND_END_BORDER +import org.jetbrains.dokka.base.renderers.html.TEMPLATE_COMMAND_SEPARATOR import org.jetbrains.dokka.base.templating.Command import org.jetbrains.dokka.base.templating.parseJson import org.jetbrains.dokka.plugability.DokkaContext @@ -27,41 +28,45 @@ class DirectiveBasedHtmlTemplateProcessingStrategy(private val context: DokkaCon document.outputSettings().indentAmount(0).prettyPrint(false) document.select("dokka-template-command").forEach { - handleCommand(it, parseJson(it.attr("data")), input, output) + handleCommandAsTag(it, parseJson(it.attr("data")), input, output) } - extractCommandsFromComments(document) { nodes, command -> - val nodesTrimed = - nodes.dropWhile { (it is TextNode && it.isBlank).also { res -> if (res) it.remove() } } - .dropLastWhile { (it is TextNode && it.isBlank).also { res -> if (res) it.remove() } } - handleCommand(nodesTrimed, command, input, output) + extractCommandsFromComments(document) { command, body -> + val bodyTrimed = + body.dropWhile { node -> (node is TextNode && node.isBlank).also { if (it) node.remove() } } + .dropLastWhile { node -> (node is TextNode && node.isBlank).also { if (it) node.remove() } } + handleCommandAsComment(command, bodyTrimed, input, output) } Files.write(output.toPath(), listOf(document.outerHtml())) true } else false - fun handleCommand(element: Element, command: Command, input: File, output: File) { - val handlers = directiveBasedCommandHandlers.filter { it.canHandle(command) } - if (handlers.isEmpty()) - context.logger.warn("Unknown templating command $command") - else - handlers.forEach { it.handleCommand(element, command, input, output) } + fun handleCommandAsTag(element: Element, command: Command, input: File, output: File) { + traverseHandlers(command) { handleCommand(element, command, input, output) } } - fun handleCommand(nodes: List, command: Command, input: File, output: File) { - val handlers = directiveBasedCommandHandlers.filterIsInstance().filter { it.canHandle(command) } + fun handleCommandAsComment(command: Command, body: List, input: File, output: File) { + traverseHandlers(command) { handleCommandAsComment(command, body, input, output) } + } + + private fun traverseHandlers(command: Command, action: CommandHandler.() -> Unit) { + val handlers = directiveBasedCommandHandlers.filter { it.canHandle(command) } if (handlers.isEmpty()) context.logger.warn("Unknown templating command $command") else - handlers.forEach { it.handleCommand(nodes, command, input, output) } + handlers.forEach(action) } - private fun extractCommandsFromComments(node: Node, startFrom: Int = 0, handler: (List, Command) -> Unit) { + private fun extractCommandsFromComments( + node: Node, + startFrom: Int = 0, + handler: (command: Command, body: List) -> Unit + ) { val nodes: MutableList = mutableListOf() var lastStartBorder: Comment? = null var firstStartBorder: Comment? = null - for (ind in startFrom until node.childNodeSize()) { - when (val currentChild = node.childNode(ind)) { + for (index in startFrom until node.childNodeSize()) { + when (val currentChild = node.childNode(index)) { is Comment -> if (currentChild.data?.startsWith(TEMPLATE_COMMAND_BEGIN_BORDER) == true) { lastStartBorder = currentChild firstStartBorder = firstStartBorder ?: currentChild @@ -69,17 +74,17 @@ class DirectiveBasedHtmlTemplateProcessingStrategy(private val context: DokkaCon } else if (lastStartBorder != null && currentChild.data?.startsWith(TEMPLATE_COMMAND_END_BORDER) == true) { lastStartBorder.remove() val cmd: Command? = - lastStartBorder.data?.removePrefix(TEMPLATE_COMMAND_BEGIN_BORDER)?.let { parseJson(it) } - cmd?.let { handler(nodes, it) } + lastStartBorder.data?.removePrefix("$TEMPLATE_COMMAND_BEGIN_BORDER$TEMPLATE_COMMAND_SEPARATOR")?.let { parseJson(it) } + cmd?.let { handler(it, nodes) } currentChild.remove() extractCommandsFromComments(node, firstStartBorder?.siblingIndex() ?: 0, handler) return } else { - lastStartBorder?.let { nodes.add(currentChild) } + if (lastStartBorder != null) nodes.add(currentChild) } else -> { extractCommandsFromComments(currentChild, handler = handler) - lastStartBorder?.let { nodes.add(currentChild) } + if (lastStartBorder != null) nodes.add(currentChild) } } } diff --git a/plugins/templating/src/main/kotlin/templates/SubstitutionCommandHandler.kt b/plugins/templating/src/main/kotlin/templates/SubstitutionCommandHandler.kt index faceef4f51..58cd76948f 100644 --- a/plugins/templating/src/main/kotlin/templates/SubstitutionCommandHandler.kt +++ b/plugins/templating/src/main/kotlin/templates/SubstitutionCommandHandler.kt @@ -11,7 +11,7 @@ import org.jsoup.nodes.Node import org.jsoup.nodes.TextNode import java.io.File -class SubstitutionCommandHandler(context: DokkaContext) : CommandHandler, CommentCommandHandler { +class SubstitutionCommandHandler(context: DokkaContext) : CommandHandler { override fun handleCommand(element: Element, command: Command, input: File, output: File) { command as SubstitutionCommand @@ -25,9 +25,9 @@ class SubstitutionCommandHandler(context: DokkaContext) : CommandHandler, Commen parent?.insertChildren(position, childrenCopy) } - override fun handleCommand(nodes: List, command: Command, input: File, output: File) { + override fun handleCommandAsComment(command: Command, body: List, input: File, output: File) { command as SubstitutionCommand - substitute(nodes, TemplatingContext(input, output, nodes, command)) + substitute(body, TemplatingContext(input, output, body, command)) } override fun canHandle(command: Command): Boolean = command is SubstitutionCommand diff --git a/plugins/templating/src/main/kotlin/templates/TemplateProcessor.kt b/plugins/templating/src/main/kotlin/templates/TemplateProcessor.kt index 9ea9139955..01c1006722 100644 --- a/plugins/templating/src/main/kotlin/templates/TemplateProcessor.kt +++ b/plugins/templating/src/main/kotlin/templates/TemplateProcessor.kt @@ -88,7 +88,7 @@ class DefaultMultiModuleTemplateProcessor( data class TemplatingContext( val input: File, val output: File, - val nodes: List, + val body: List, val command: T, ) diff --git a/plugins/versioning/api/versioning.api b/plugins/versioning/api/versioning.api index 15ebe7bea7..f62670582b 100644 --- a/plugins/versioning/api/versioning.api +++ b/plugins/versioning/api/versioning.api @@ -59,6 +59,7 @@ public final class org/jetbrains/dokka/versioning/ReplaceVersionCommandHandler : public fun finish (Ljava/io/File;)V public final fun getVersionsNavigationCreator ()Lorg/jetbrains/dokka/versioning/VersionsNavigationCreator; public fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V + public fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V } public final class org/jetbrains/dokka/versioning/SemVerVersionOrdering : org/jetbrains/dokka/versioning/VersionsOrdering { From 8c7a477403a39a1f8c65115187fffb16d3f77540 Mon Sep 17 00:00:00 2001 From: vmishenev Date: Mon, 21 Feb 2022 17:20:12 +0300 Subject: [PATCH 3/4] Rename `handleCommand`to `handleCommandAsTag` --- plugins/all-modules-page/api/all-modules-page.api | 1 + .../src/main/kotlin/ResolveLinkCommandHandler.kt | 10 +++++----- plugins/templating/api/templating.api | 5 +++++ .../kotlin/templates/AddToNavigationCommandHandler.kt | 4 ++-- .../src/main/kotlin/templates/CommandHandler.kt | 5 ++++- .../templates/DirectiveBasedTemplateProcessing.kt | 2 +- .../kotlin/templates/ReplaceVersionCommandHandler.kt | 8 ++++---- .../kotlin/templates/SubstitutionCommandHandler.kt | 10 +++++----- .../src/main/kotlin/templates/TemplatingPlugin.kt | 1 + plugins/versioning/api/versioning.api | 1 + .../main/kotlin/versioning/ReplaceVersionsCommand.kt | 2 +- 11 files changed, 30 insertions(+), 19 deletions(-) diff --git a/plugins/all-modules-page/api/all-modules-page.api b/plugins/all-modules-page/api/all-modules-page.api index d9724a9a2d..0763d75a04 100644 --- a/plugins/all-modules-page/api/all-modules-page.api +++ b/plugins/all-modules-page/api/all-modules-page.api @@ -84,5 +84,6 @@ public final class org/jetbrains/dokka/allModulesPage/ResolveLinkCommandHandler public fun finish (Ljava/io/File;)V public fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V + public fun handleCommandAsTag (Lorg/jetbrains/dokka/base/templating/Command;Lorg/jsoup/nodes/Element;Ljava/io/File;Ljava/io/File;)V } diff --git a/plugins/all-modules-page/src/main/kotlin/ResolveLinkCommandHandler.kt b/plugins/all-modules-page/src/main/kotlin/ResolveLinkCommandHandler.kt index e881a5abec..7976ba5a0c 100644 --- a/plugins/all-modules-page/src/main/kotlin/ResolveLinkCommandHandler.kt +++ b/plugins/all-modules-page/src/main/kotlin/ResolveLinkCommandHandler.kt @@ -16,29 +16,29 @@ class ResolveLinkCommandHandler(context: DokkaContext) : CommandHandler { private val externalModuleLinkResolver = context.plugin().querySingle { externalModuleLinkResolver } - override fun handleCommand(element: Element, command: Command, input: File, output: File) { + override fun handleCommandAsTag(command: Command, body: Element, input: File, output: File) { command as ResolveLinkCommand val link = externalModuleLinkResolver.resolve(command.dri, output) if (link == null) { - val children = element.childNodes().toList() + val children = body.childNodes().toList() val attributes = Attributes().apply { put("data-unresolved-link", command.dri.toString()) } val el = Element(Tag.valueOf("span"), "", attributes).apply { children.forEach { ch -> appendChild(ch) } } - element.replaceWith(el) + body.replaceWith(el) return } val attributes = Attributes().apply { put("href", link) } - val children = element.childNodes().toList() + val children = body.childNodes().toList() val el = Element(Tag.valueOf("a"), "", attributes).apply { children.forEach { ch -> appendChild(ch) } } - element.replaceWith(el) + body.replaceWith(el) } override fun canHandle(command: Command): Boolean = command is ResolveLinkCommand diff --git a/plugins/templating/api/templating.api b/plugins/templating/api/templating.api index 17c9751553..37255cd75e 100644 --- a/plugins/templating/api/templating.api +++ b/plugins/templating/api/templating.api @@ -29,6 +29,7 @@ public final class org/jetbrains/dokka/templates/AddToNavigationCommandHandler : public final fun getContext ()Lorg/jetbrains/dokka/plugability/DokkaContext; public fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V + public fun handleCommandAsTag (Lorg/jetbrains/dokka/base/templating/Command;Lorg/jsoup/nodes/Element;Ljava/io/File;Ljava/io/File;)V } public abstract interface class org/jetbrains/dokka/templates/CommandHandler { @@ -36,10 +37,12 @@ public abstract interface class org/jetbrains/dokka/templates/CommandHandler { public abstract fun finish (Ljava/io/File;)V public abstract fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public abstract fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V + public abstract fun handleCommandAsTag (Lorg/jetbrains/dokka/base/templating/Command;Lorg/jsoup/nodes/Element;Ljava/io/File;Ljava/io/File;)V } public final class org/jetbrains/dokka/templates/CommandHandler$DefaultImpls { public static fun finish (Lorg/jetbrains/dokka/templates/CommandHandler;Ljava/io/File;)V + public static fun handleCommand (Lorg/jetbrains/dokka/templates/CommandHandler;Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public static fun handleCommandAsComment (Lorg/jetbrains/dokka/templates/CommandHandler;Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V } @@ -87,6 +90,7 @@ public final class org/jetbrains/dokka/templates/SubstitutionCommandHandler : or public fun finish (Ljava/io/File;)V public fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V + public fun handleCommandAsTag (Lorg/jetbrains/dokka/base/templating/Command;Lorg/jsoup/nodes/Element;Ljava/io/File;Ljava/io/File;)V } public abstract interface class org/jetbrains/dokka/templates/Substitutor { @@ -168,6 +172,7 @@ public final class templates/ReplaceVersionCommandHandler : org/jetbrains/dokka/ public fun finish (Ljava/io/File;)V public fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V + public fun handleCommandAsTag (Lorg/jetbrains/dokka/base/templating/Command;Lorg/jsoup/nodes/Element;Ljava/io/File;Ljava/io/File;)V } public final class templates/SourcesetDependencyProcessingStrategy : org/jetbrains/dokka/templates/TemplateProcessingStrategy { diff --git a/plugins/templating/src/main/kotlin/templates/AddToNavigationCommandHandler.kt b/plugins/templating/src/main/kotlin/templates/AddToNavigationCommandHandler.kt index 3e7e1290c3..9531c27968 100644 --- a/plugins/templating/src/main/kotlin/templates/AddToNavigationCommandHandler.kt +++ b/plugins/templating/src/main/kotlin/templates/AddToNavigationCommandHandler.kt @@ -13,12 +13,12 @@ import java.util.concurrent.ConcurrentHashMap class AddToNavigationCommandHandler(val context: DokkaContext) : CommandHandler { private val navigationFragments = ConcurrentHashMap() - override fun handleCommand(element: Element, command: Command, input: File, output: File) { + override fun handleCommandAsTag(command: Command, body: Element, input: File, output: File) { command as AddToNavigationCommand context.configuration.modules.find { it.name == command.moduleName } ?.relativePathToOutputDirectory ?.relativeToOrSelf(context.configuration.outputDir) - ?.let { key -> navigationFragments[key.toString()] = element } + ?.let { key -> navigationFragments[key.toString()] = body } } override fun canHandle(command: Command) = command is AddToNavigationCommand diff --git a/plugins/templating/src/main/kotlin/templates/CommandHandler.kt b/plugins/templating/src/main/kotlin/templates/CommandHandler.kt index 772754564c..e0a69cb8ab 100644 --- a/plugins/templating/src/main/kotlin/templates/CommandHandler.kt +++ b/plugins/templating/src/main/kotlin/templates/CommandHandler.kt @@ -7,7 +7,10 @@ import java.io.File interface CommandHandler { - fun handleCommand(element: Element, command: Command, input: File, output: File) + @Deprecated("This was renamed to handleCommandAsTag", ReplaceWith("handleCommandAsTag(command, element, input, output)")) + fun handleCommand(element: Element, command: Command, input: File, output: File) = + handleCommandAsTag(command, element, input, output) + fun handleCommandAsTag(command: Command, body: Element, input: File, output: File) fun handleCommandAsComment(command: Command, body: List, input: File, output: File) { } fun canHandle(command: Command): Boolean fun finish(output: File) {} diff --git a/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt b/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt index d5579f8a16..7ef4cb10eb 100644 --- a/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt +++ b/plugins/templating/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt @@ -42,7 +42,7 @@ class DirectiveBasedHtmlTemplateProcessingStrategy(private val context: DokkaCon } else false fun handleCommandAsTag(element: Element, command: Command, input: File, output: File) { - traverseHandlers(command) { handleCommand(element, command, input, output) } + traverseHandlers(command) { handleCommandAsTag(command, element, input, output) } } fun handleCommandAsComment(command: Command, body: List, input: File, output: File) { diff --git a/plugins/templating/src/main/kotlin/templates/ReplaceVersionCommandHandler.kt b/plugins/templating/src/main/kotlin/templates/ReplaceVersionCommandHandler.kt index 8035fc83be..0257084926 100644 --- a/plugins/templating/src/main/kotlin/templates/ReplaceVersionCommandHandler.kt +++ b/plugins/templating/src/main/kotlin/templates/ReplaceVersionCommandHandler.kt @@ -12,10 +12,10 @@ class ReplaceVersionCommandHandler(private val context: DokkaContext) : CommandH override fun canHandle(command: Command): Boolean = command is ReplaceVersionsCommand - override fun handleCommand(element: Element, command: Command, input: File, output: File) { - val position = element.elementSiblingIndex() - val parent = element.parent() - element.remove() + override fun handleCommandAsTag(command: Command, body: Element, input: File, output: File) { + val position = body.elementSiblingIndex() + val parent = body.parent() + body.remove() context.configuration.moduleVersion?.takeIf { it.isNotEmpty() } ?.let { parent.insertChildren(position, TextNode(it)) } } diff --git a/plugins/templating/src/main/kotlin/templates/SubstitutionCommandHandler.kt b/plugins/templating/src/main/kotlin/templates/SubstitutionCommandHandler.kt index 58cd76948f..178f52dcd2 100644 --- a/plugins/templating/src/main/kotlin/templates/SubstitutionCommandHandler.kt +++ b/plugins/templating/src/main/kotlin/templates/SubstitutionCommandHandler.kt @@ -13,14 +13,14 @@ import java.io.File class SubstitutionCommandHandler(context: DokkaContext) : CommandHandler { - override fun handleCommand(element: Element, command: Command, input: File, output: File) { + override fun handleCommandAsTag(command: Command, body: Element, input: File, output: File) { command as SubstitutionCommand - val childrenCopy = element.children().toList() + val childrenCopy = body.children().toList() substitute(childrenCopy, TemplatingContext(input, output, childrenCopy, command)) - val position = element.elementSiblingIndex() - val parent = element.parent() - element.remove() + val position = body.elementSiblingIndex() + val parent = body.parent() + body.remove() parent?.insertChildren(position, childrenCopy) } diff --git a/plugins/templating/src/main/kotlin/templates/TemplatingPlugin.kt b/plugins/templating/src/main/kotlin/templates/TemplatingPlugin.kt index 7001b1ba59..aea019708b 100644 --- a/plugins/templating/src/main/kotlin/templates/TemplatingPlugin.kt +++ b/plugins/templating/src/main/kotlin/templates/TemplatingPlugin.kt @@ -7,6 +7,7 @@ import templates.ProjectNameSubstitutor import templates.ReplaceVersionCommandHandler import templates.SourcesetDependencyProcessingStrategy +@Suppress("unused") class TemplatingPlugin : DokkaPlugin() { val submoduleTemplateProcessor by extensionPoint() diff --git a/plugins/versioning/api/versioning.api b/plugins/versioning/api/versioning.api index f62670582b..b163fd4abe 100644 --- a/plugins/versioning/api/versioning.api +++ b/plugins/versioning/api/versioning.api @@ -60,6 +60,7 @@ public final class org/jetbrains/dokka/versioning/ReplaceVersionCommandHandler : public final fun getVersionsNavigationCreator ()Lorg/jetbrains/dokka/versioning/VersionsNavigationCreator; public fun handleCommand (Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public fun handleCommandAsComment (Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V + public fun handleCommandAsTag (Lorg/jetbrains/dokka/base/templating/Command;Lorg/jsoup/nodes/Element;Ljava/io/File;Ljava/io/File;)V } public final class org/jetbrains/dokka/versioning/SemVerVersionOrdering : org/jetbrains/dokka/versioning/VersionsOrdering { diff --git a/plugins/versioning/src/main/kotlin/versioning/ReplaceVersionsCommand.kt b/plugins/versioning/src/main/kotlin/versioning/ReplaceVersionsCommand.kt index 728eac09d4..ad1edd2b95 100644 --- a/plugins/versioning/src/main/kotlin/versioning/ReplaceVersionsCommand.kt +++ b/plugins/versioning/src/main/kotlin/versioning/ReplaceVersionsCommand.kt @@ -18,7 +18,7 @@ class ReplaceVersionCommandHandler(context: DokkaContext) : CommandHandler { override fun canHandle(command: Command): Boolean = command is ReplaceVersionsCommand - override fun handleCommand(element: Element, command: Command, input: File, output: File) { + override fun handleCommandAsTag(command: Command, element: Element, input: File, output: File) { element.empty() element.append(versionsNavigationCreator(output)) } From f77ec86c336c3a466e9c2ef889d8e64998edac33 Mon Sep 17 00:00:00 2001 From: vmishenev Date: Tue, 22 Feb 2022 00:23:55 +0300 Subject: [PATCH 4/4] Call deprecated `handleCommand` from `handleCommandAsTag` --- plugins/templating/api/templating.api | 1 + .../src/main/kotlin/templates/CommandHandler.kt | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/templating/api/templating.api b/plugins/templating/api/templating.api index 37255cd75e..aedd8ef39b 100644 --- a/plugins/templating/api/templating.api +++ b/plugins/templating/api/templating.api @@ -44,6 +44,7 @@ public final class org/jetbrains/dokka/templates/CommandHandler$DefaultImpls { public static fun finish (Lorg/jetbrains/dokka/templates/CommandHandler;Ljava/io/File;)V public static fun handleCommand (Lorg/jetbrains/dokka/templates/CommandHandler;Lorg/jsoup/nodes/Element;Lorg/jetbrains/dokka/base/templating/Command;Ljava/io/File;Ljava/io/File;)V public static fun handleCommandAsComment (Lorg/jetbrains/dokka/templates/CommandHandler;Lorg/jetbrains/dokka/base/templating/Command;Ljava/util/List;Ljava/io/File;Ljava/io/File;)V + public static fun handleCommandAsTag (Lorg/jetbrains/dokka/templates/CommandHandler;Lorg/jetbrains/dokka/base/templating/Command;Lorg/jsoup/nodes/Element;Ljava/io/File;Ljava/io/File;)V } public final class org/jetbrains/dokka/templates/DefaultMultiModuleTemplateProcessor : org/jetbrains/dokka/templates/MultiModuleTemplateProcessor { diff --git a/plugins/templating/src/main/kotlin/templates/CommandHandler.kt b/plugins/templating/src/main/kotlin/templates/CommandHandler.kt index e0a69cb8ab..1956310b8b 100644 --- a/plugins/templating/src/main/kotlin/templates/CommandHandler.kt +++ b/plugins/templating/src/main/kotlin/templates/CommandHandler.kt @@ -8,9 +8,11 @@ import java.io.File interface CommandHandler { @Deprecated("This was renamed to handleCommandAsTag", ReplaceWith("handleCommandAsTag(command, element, input, output)")) - fun handleCommand(element: Element, command: Command, input: File, output: File) = - handleCommandAsTag(command, element, input, output) - fun handleCommandAsTag(command: Command, body: Element, input: File, output: File) + fun handleCommand(element: Element, command: Command, input: File, output: File) { } + + @Suppress("DEPRECATION") + fun handleCommandAsTag(command: Command, body: Element, input: File, output: File) = + handleCommand(body, command, input, output) fun handleCommandAsComment(command: Command, body: List, input: File, output: File) { } fun canHandle(command: Command): Boolean fun finish(output: File) {}