aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorMarcin Aman <maman@virtuslab.com>2020-05-31 21:02:46 +0200
committerPaweł Marks <Kordyjan@users.noreply.github.com>2020-06-09 17:18:17 +0200
commit77c8777b7f66bddd374d68decd507547d356d602 (patch)
treef941a53d1591c56edd454ef40068e831a4ed9d48 /plugins
parent902b670bc764a6db4f49f96d08f2115dd08bdf9b (diff)
downloaddokka-77c8777b7f66bddd374d68decd507547d356d602.tar.gz
dokka-77c8777b7f66bddd374d68decd507547d356d602.tar.bz2
dokka-77c8777b7f66bddd374d68decd507547d356d602.zip
Improve CSS, pages navigation tree and create anchors on page
Diffstat (limited to 'plugins')
-rw-r--r--plugins/base/frontend/src/main/components/app/index.scss8
-rw-r--r--plugins/base/frontend/src/main/components/app/index.tsx45
-rw-r--r--plugins/base/frontend/src/main/components/search/search.scss14
-rw-r--r--plugins/base/frontend/src/main/components/search/search.tsx16
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt258
-rw-r--r--plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt20
-rw-r--r--plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt2
-rw-r--r--plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt67
-rw-r--r--plugins/base/src/main/kotlin/translators/documentables/PageContentBuilder.kt14
-rw-r--r--plugins/base/src/main/resources/dokka/scripts/clipboard.js52
-rw-r--r--plugins/base/src/main/resources/dokka/scripts/navigationLoader.js11
-rw-r--r--plugins/base/src/main/resources/dokka/styles/style.css330
-rw-r--r--plugins/base/src/test/kotlin/content/params/ContentForParamsTest.kt146
-rw-r--r--plugins/base/src/test/kotlin/content/seealso/ContentForSeeAlsoTest.kt170
-rw-r--r--plugins/base/src/test/kotlin/enums/EnumsTest.kt8
-rw-r--r--plugins/base/src/test/kotlin/linkableContent/LinkableContentTest.kt4
-rw-r--r--plugins/base/src/test/kotlin/markdown/LinkTest.kt13
-rw-r--r--plugins/base/src/test/kotlin/renderers/RenderingOnlyTestBase.kt1
-rw-r--r--plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt26
19 files changed, 831 insertions, 374 deletions
diff --git a/plugins/base/frontend/src/main/components/app/index.scss b/plugins/base/frontend/src/main/components/app/index.scss
index c267bc6e..da5042b1 100644
--- a/plugins/base/frontend/src/main/components/app/index.scss
+++ b/plugins/base/frontend/src/main/components/app/index.scss
@@ -17,5 +17,11 @@ html,
}
.search-content {
- padding: 24px 41px;
+ padding-top: 24px;
+ margin: 0 41px;
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 8;
+ background-color: #f4f4f4
}
diff --git a/plugins/base/frontend/src/main/components/app/index.tsx b/plugins/base/frontend/src/main/components/app/index.tsx
index 1a51e699..4081dec4 100644
--- a/plugins/base/frontend/src/main/components/app/index.tsx
+++ b/plugins/base/frontend/src/main/components/app/index.tsx
@@ -1,49 +1,10 @@
-import React, {useEffect, useRef, useState} from 'react';
+import React from 'react';
import {WithFuzzySearchFilter} from '../search/search';
import './index.scss';
-function useComponentVisible(initialIsVisible: boolean) {
- const [isComponentVisible, setIsComponentVisible] = useState(initialIsVisible);
- const ref = useRef(null);
-
- const handleHideDropdown = (event: KeyboardEvent) => {
- if (event.key === "Escape") {
- setIsComponentVisible(false);
- }
- };
-
- const handleClickOutside = (event : MouseEvent)=> {
- // @ts-ignore
- if (ref.current && !ref.current.contains(event.target)) {
- setIsComponentVisible(false);
- }
- };
-
- useEffect(() => {
- document.addEventListener("keydown", handleHideDropdown, false);
- document.addEventListener("click", handleClickOutside, false);
- return () => {
- document.removeEventListener("keydown", handleHideDropdown, false);
- document.removeEventListener("click", handleClickOutside, false);
- };
- });
-
- return { ref, isComponentVisible, setIsComponentVisible };
-}
-
const App: React.FC = () => {
- const {
- ref,
- isComponentVisible,
- setIsComponentVisible
- } = useComponentVisible(false);
-
- return <div ref={ref} className="search-content">
- {isComponentVisible && (<WithFuzzySearchFilter/>)}
- {!isComponentVisible && (
- <span onClick={() => setIsComponentVisible(true)}>
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M19.64 18.36l-6.24-6.24a7.52 7.52 0 1 0-1.28 1.28l6.24 6.24zM7.5 13.4a5.9 5.9 0 1 1 5.9-5.9 5.91 5.91 0 0 1-5.9 5.9z"/></svg>
- </span>)}
+ return <div className="search-content">
+ <WithFuzzySearchFilter/>
</div>
}
diff --git a/plugins/base/frontend/src/main/components/search/search.scss b/plugins/base/frontend/src/main/components/search/search.scss
new file mode 100644
index 00000000..a891283e
--- /dev/null
+++ b/plugins/base/frontend/src/main/components/search/search.scss
@@ -0,0 +1,14 @@
+.search {
+ button {
+ border: none;
+ fill: #637282;
+
+ &:focus {
+ outline: none;
+ }
+ }
+}
+
+.popup-wrapper {
+ min-width: calc(100% - 360px) !important;
+} \ No newline at end of file
diff --git a/plugins/base/frontend/src/main/components/search/search.tsx b/plugins/base/frontend/src/main/components/search/search.tsx
index f0df0c98..b0fdd96a 100644
--- a/plugins/base/frontend/src/main/components/search/search.tsx
+++ b/plugins/base/frontend/src/main/components/search/search.tsx
@@ -1,7 +1,8 @@
import React, {useCallback, useState} from 'react';
import {Select} from '@jetbrains/ring-ui';
import '@jetbrains/ring-ui/components/input-size/input-size.scss';
-import {IWindow, Option, Props, State} from "./types";
+import './search.scss';
+import {IWindow, Option, Props} from "./types";
const WithFuzzySearchFilterComponent: React.FC<Props> = ({data}: Props) => {
const [selected, onSelected] = useState<Option>(data[0]);
@@ -12,6 +13,7 @@ const WithFuzzySearchFilterComponent: React.FC<Props> = ({data}: Props) => {
},
[data]
);
+
return (
<div className="search-container">
<div className="search">
@@ -19,10 +21,22 @@ const WithFuzzySearchFilterComponent: React.FC<Props> = ({data}: Props) => {
selectedLabel="Search"
label="Please type page name"
filter={{fuzzy: true}}
+ type={Select.Type.CUSTOM}
clear
selected={selected}
data={data}
+ popupClassName={"popup-wrapper"}
onSelect={onChangeSelected}
+ customAnchor={({wrapperProps, buttonProps, popup}) => (
+ <span {...wrapperProps}>
+ <button type="button" {...buttonProps}>
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+ <path d="M19.64 18.36l-6.24-6.24a7.52 7.52 0 1 0-1.28 1.28l6.24 6.24zM7.5 13.4a5.9 5.9 0 1 1 5.9-5.9 5.91 5.91 0 0 1-5.9 5.9z"/>
+ </svg>
+ </button>
+ {popup}
+ </span>
+ )}
/>
</div>
</div>
diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
index 7ebcf00e..67fa2d91 100644
--- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt
@@ -22,7 +22,7 @@ open class HtmlRenderer(
private val sourceSetDependencyMap = with(context.sourceSetCache) {
allSourceSets.map { sourceSet ->
- sourceSet to allSourceSets.filter { sourceSet.dependentSourceSets.contains(it.sourceSetName ) }
+ sourceSet to allSourceSets.filter { sourceSet.dependentSourceSets.contains(it.sourceSetName) }
}.toMap()
}
@@ -38,22 +38,24 @@ open class HtmlRenderer(
val additionalClasses = node.style.joinToString(" ") { it.toString().toLowerCase() }
return when {
node.hasStyle(ContentStyle.TabbedContent) -> div(additionalClasses) {
- val secondLevel = node.children.filterIsInstance<ContentComposite>().flatMap { it.children }.filterIsInstance<ContentHeader>().flatMap { it.children }.filterIsInstance<ContentText>()
- val firstLevel = node.children.filterIsInstance<ContentHeader>().flatMap { it.children }.filterIsInstance<ContentText>()
+ val secondLevel = node.children.filterIsInstance<ContentComposite>().flatMap { it.children }
+ .filterIsInstance<ContentHeader>().flatMap { it.children }.filterIsInstance<ContentText>()
+ val firstLevel = node.children.filterIsInstance<ContentHeader>().flatMap { it.children }
+ .filterIsInstance<ContentText>()
val renderable = firstLevel.union(secondLevel)
- div(classes = "tabs-section"){
+ div(classes = "tabs-section") {
attributes["tabs-section"] = "tabs-section"
renderable.forEachIndexed { index, node ->
- button(classes = "section-tab"){
- if(index == 0 ) attributes["data-active"] = ""
+ button(classes = "section-tab") {
+ if (index == 0) attributes["data-active"] = ""
attributes["data-togglable"] = node.text
text(node.text)
}
}
}
- div(classes = "tabs-section-body"){
+ div(classes = "tabs-section-body") {
childrenCallback()
}
}
@@ -61,7 +63,10 @@ open class HtmlRenderer(
node.extra.extraHtmlAttributes().forEach { attributes[it.extraKey] = it.extraValue }
childrenCallback()
}
- node.dci.kind == ContentKind.Symbol -> div("symbol $additionalClasses") { childrenCallback() }
+ node.dci.kind in setOf(ContentKind.Symbol, ContentKind.Sample) -> div("symbol $additionalClasses") {
+ childrenCallback()
+ if (node.hasStyle(TextStyle.Monospace)) copyButton()
+ }
node.dci.kind == ContentKind.BriefComment -> div("brief $additionalClasses") { childrenCallback() }
node.dci.kind == ContentKind.Cover -> div("cover $additionalClasses") {
filterButtons(node)
@@ -80,7 +85,7 @@ open class HtmlRenderer(
button(classes = "platform-tag platform-selector") {
attributes["data-active"] = ""
attributes["data-filter"] = it.sourceSetName
- when(it.platform.key){
+ when (it.platform.key) {
"common" -> classes = classes + "common-like"
"native" -> classes = classes + "native-like"
"jvm" -> classes = classes + "jvm-like"
@@ -92,40 +97,57 @@ open class HtmlRenderer(
}
}
+ private fun FlowContent.copyButton() = span(classes = "top-right-position") {
+ span("copy-icon") {
+ unsafe {
+ raw(
+ """<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M5 4H15V16H5V4ZM17 7H19V18V20H17H8V18H17V7Z" fill="black"/>
+ </svg>""".trimIndent()
+ )
+ }
+ }
+ copiedPopup("Content copied to clipboard", "popup-to-left")
+ }
+
+ private fun FlowContent.copiedPopup(notificationContent: String, additionalClasses: String = "") =
+ div("copy-popup-wrapper $additionalClasses") {
+ unsafe {
+ raw(
+ """
+ <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M18 9C18 14 14 18 9 18C4 18 0 14 0 9C0 4 4 0 9 0C14 0 18 4 18 9ZM14.2 6.2L12.8 4.8L7.5 10.1L5.3 7.8L3.8 9.2L7.5 13L14.2 6.2Z" fill="#4DBB5F"/>
+ </svg>
+ """.trimIndent()
+ )
+ }
+ span {
+ text(notificationContent)
+ }
+ }
+
override fun FlowContent.buildPlatformDependent(content: PlatformHintedContent, pageContext: ContentPage) =
- buildPlatformDependent(content.sourceSets.map { it to setOf(content.inner) }.toMap(), pageContext, content.extra)
+ buildPlatformDependent(
+ content.sourceSets.map { it to setOf(content.inner) }.toMap(),
+ pageContext,
+ content.extra,
+ content.style
+ )
private fun FlowContent.buildPlatformDependent(
nodes: Map<SourceSetData, Collection<ContentNode>>,
pageContext: ContentPage,
- extra: PropertyContainer<ContentNode> = PropertyContainer.empty()
+ extra: PropertyContainer<ContentNode> = PropertyContainer.empty(),
+ styles: Set<Style> = emptySet()
) {
- var mergedToOneSourceSet : SourceSetData? = null
- div("platform-hinted") {
+ val contents = contentsForSourceSetDependent(nodes, pageContext)
+ val shouldHaveTabs = contents.size != 1
+
+ val styles = "platform-hinted ${styles.joinToString()}" + if (shouldHaveTabs) " with-platform-tabs" else ""
+ div(styles) {
attributes["data-platform-hinted"] = "data-platform-hinted"
extra.extraHtmlAttributes().forEach { attributes[it.extraKey] = it.extraValue }
- val additionalClasses = if(nodes.toList().size == 1) "single-content" else ""
- var counter = 0
- val contents = nodes.toList().map { (sourceSet, elements) ->
- sourceSet to createHTML(prettyPrint = false).div {
- elements.forEach {
- buildContentNode(it, pageContext, setOf(sourceSet))
- }
- }.stripDiv()
- }.groupBy(Pair<SourceSetData, String>::second, Pair<SourceSetData, String>::first).entries.flatMap { (html, sourceSets) ->
- sourceSets.filterNot {
- sourceSetDependencyMap[it].orEmpty().any { dependency -> sourceSets.contains(dependency) }
- }.map {
- it to createHTML(prettyPrint = false).div(classes = "content $additionalClasses") {
- if (counter++ == 0) attributes["data-active"] = ""
- attributes["data-togglable"] = it.sourceSetName
- unsafe {
- +html
- }
- }
- }
- }
- if (contents.size != 1) {
+ if (shouldHaveTabs) {
div("platform-bookmarks-row") {
attributes["data-toggle-list"] = "data-toggle-list"
contents.forEachIndexed { index, pair ->
@@ -134,27 +156,53 @@ open class HtmlRenderer(
attributes["data-filterable-set"] = pair.first.sourceSetName
if (index == 0) attributes["data-active"] = ""
attributes["data-toggle"] = pair.first.sourceSetName
- when(
+ when (
pair.first.platform.key
- ){
- "common" -> classes = classes + "common-like"
- "native" -> classes = classes + "native-like"
- "jvm" -> classes = classes + "jvm-like"
- "js" -> classes = classes + "js-like"
+ ) {
+ "common" -> classes = classes + "common-like"
+ "native" -> classes = classes + "native-like"
+ "jvm" -> classes = classes + "jvm-like"
+ "js" -> classes = classes + "js-like"
}
attributes["data-toggle"] = pair.first.sourceSetName
text(pair.first.sourceSetName)
}
}
}
- } else if (nodes.size > 1) {
- mergedToOneSourceSet = contents.first().first
}
contents.forEach {
consumer.onTagContentUnsafe { +it.second }
}
}
- mergedToOneSourceSet?.let { createPlatformTagBubbles(listOf(it)) }
+ }
+
+ private fun contentsForSourceSetDependent(
+ nodes: Map<SourceSetData, Collection<ContentNode>>,
+ pageContext: ContentPage,
+ ): List<Pair<SourceSetData, String>> {
+ var counter = 0
+ return nodes.toList().map { (sourceSet, elements) ->
+ sourceSet to createHTML(prettyPrint = false).div {
+ elements.forEach {
+ buildContentNode(it, pageContext, setOf(sourceSet))
+ }
+ }.stripDiv()
+ }.groupBy(
+ Pair<SourceSetData, String>::second,
+ Pair<SourceSetData, String>::first
+ ).entries.flatMap { (html, sourceSets) ->
+ sourceSets.filterNot {
+ sourceSetDependencyMap[it].orEmpty().any { dependency -> sourceSets.contains(dependency) }
+ }.map {
+ it to createHTML(prettyPrint = false).div(classes = "content sourceset-depenent-content") {
+ if (counter++ == 0) attributes["data-active"] = ""
+ attributes["data-togglable"] = it.sourceSetName
+ unsafe {
+ +html
+ }
+ }
+ }
+ }
}
override fun FlowContent.buildDivergent(node: ContentDivergentGroup, pageContext: ContentPage) {
@@ -183,26 +231,38 @@ open class HtmlRenderer(
val groupedDivergent = it.value.groupBy { it.second }
consumer.onTagContentUnsafe {
- +createHTML().div("divergent-group"){
+ +createHTML().div("divergent-group") {
attributes["data-filterable-current"] = groupedDivergent.keys.joinToString(" ") {
it.sourceSetName
}
attributes["data-filterable-set"] = groupedDivergent.keys.joinToString(" ") {
it.sourceSetName
}
- consumer.onTagContentUnsafe { +it.key.first }
- div("main-subrow") {
- if (node.implicitlySourceSetHinted) {
- buildPlatformDependent(
- groupedDivergent.map { (sourceSet, elements) ->
- sourceSet to elements.map { e -> e.first.divergent }
- }.toMap(),
- pageContext
- )
- if (distinct.size > 1 && groupedDivergent.size == 1) {
- createPlatformTags(node, groupedDivergent.keys)
+ val divergentForPlatformDependent = groupedDivergent.map { (sourceSet, elements) ->
+ sourceSet to elements.map { e -> e.first.divergent }
+ }.toMap()
+
+ val content = contentsForSourceSetDependent(divergentForPlatformDependent, pageContext)
+
+ consumer.onTagContentUnsafe {
+ +createHTML().div("brief-with-platform-tags") {
+ consumer.onTagContentUnsafe { +it.key.first }
+
+ consumer.onTagContentUnsafe {
+ +createHTML().span("pull-right") {
+ if ((distinct.size > 1 && groupedDivergent.size == 1) || groupedDivergent.size == 1 || content.size == 1) {
+ if (node.sourceSets.size != 1) {
+ createPlatformTags(node, setOf(content.first().first))
+ }
+ }
+ }
}
+ }
+ }
+ div("main-subrow") {
+ if (node.implicitlySourceSetHinted) {
+ buildPlatformDependent(divergentForPlatformDependent, pageContext)
} else {
it.value.forEach {
buildContentNode(it.first.divergent, pageContext, setOf(it.second))
@@ -272,7 +332,8 @@ open class HtmlRenderer(
.filter { sourceSetRestriction == null || it.sourceSets.any { s -> s in sourceSetRestriction } }
.takeIf { it.isNotEmpty() }
?.let {
- withAnchor(node.dci.dri.first().toString()) {
+ val anchorName = node.dci.dri.first().toString()
+ withAnchor(anchorName) {
div(classes = "table-row") {
if (!style.contains(MultimoduleTable)) {
attributes["data-filterable-current"] = node.sourceSets.joinToString(" ") {
@@ -286,7 +347,10 @@ open class HtmlRenderer(
div("main-subrow " + node.style.joinToString(" ")) {
it.filter { sourceSetRestriction == null || it.sourceSets.any { s -> s in sourceSetRestriction } }
.forEach {
- it.build(this, pageContext, sourceSetRestriction)
+ span {
+ it.build(this, pageContext, sourceSetRestriction)
+ buildAnchor(anchorName)
+ }
if (ContentKind.shouldBePlatformTagged(node.dci.kind) && (node.sourceSets.size == 1))
createPlatformTags(node)
}
@@ -317,7 +381,7 @@ open class HtmlRenderer(
div("platform-tags") {
sourceSets.forEach {
div("platform-tag") {
- when(it.platform.key){
+ when (it.platform.key) {
"common" -> classes = classes + "common-like"
"native" -> classes = classes + "native-like"
"jvm" -> classes = classes + "jvm-like"
@@ -331,7 +395,7 @@ open class HtmlRenderer(
private fun FlowContent.createPlatformTags(node: ContentNode, sourceSetRestriction: Set<SourceSetData>? = null) {
node.takeIf { sourceSetRestriction == null || it.sourceSets.any { s -> s in sourceSetRestriction } }?.let {
- createPlatformTagBubbles( node.sourceSets.filter {
+ createPlatformTagBubbles(node.sourceSets.filter {
sourceSetRestriction == null || it in sourceSetRestriction
})
}
@@ -342,7 +406,7 @@ open class HtmlRenderer(
pageContext: ContentPage,
sourceSetRestriction: Set<SourceSetData>?
) {
- when(node.dci.kind){
+ when (node.dci.kind) {
ContentKind.Comment -> buildDefaultTable(node, pageContext, sourceSetRestriction)
else -> div(classes = "table") {
node.extra.extraHtmlAttributes().forEach { attributes[it.extraKey] = it.extraValue }
@@ -388,13 +452,14 @@ open class HtmlRenderer(
override fun FlowContent.buildHeader(level: Int, node: ContentHeader, content: FlowContent.() -> Unit) {
val anchor = node.extra[SimpleAttr.SimpleAttrKey("anchor")]?.extraValue
+ val classes = node.style.joinToString { it.toString() }.toLowerCase()
when (level) {
- 1 -> h1() { withAnchor(anchor, content) }
- 2 -> h2() { withAnchor(anchor, content) }
- 3 -> h3() { withAnchor(anchor, content) }
- 4 -> h4() { withAnchor(anchor, content) }
- 5 -> h5() { withAnchor(anchor, content) }
- else -> h6() { withAnchor(anchor, content) }
+ 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) }
}
}
@@ -420,6 +485,23 @@ open class HtmlRenderer(
text(to.name)
}
+ private fun FlowContent.buildAnchor(pointingTo: String) {
+ span(classes = "anchor-wrapper") {
+ span(classes = "anchor-icon") {
+ attributes["pointing-to"] = pointingTo
+ unsafe {
+ raw("""
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M21.2496 5.3C20.3496 4.5 19.2496 4 18.0496 4C16.8496 4 15.6496 4.5 14.8496 5.3L10.3496 9.8L11.7496 11.2L16.2496 6.7C17.2496 5.7 18.8496 5.7 19.8496 6.7C20.8496 7.7 20.8496 9.3 19.8496 10.3L15.3496 14.8L16.7496 16.2L21.2496 11.7C22.1496 10.8 22.5496 9.7 22.5496 8.5C22.5496 7.3 22.1496 6.2 21.2496 5.3Z"/>
+ <path d="M8.35 16.7998C7.35 17.7998 5.75 17.7998 4.75 16.7998C3.75 15.7998 3.75 14.1998 4.75 13.1998L9.25 8.6998L7.85 7.2998L3.35 11.7998C1.55 13.5998 1.55 16.3998 3.35 18.1998C4.25 19.0998 5.35 19.4998 6.55 19.4998C7.75 19.4998 8.85 19.0998 9.75 18.1998L14.25 13.6998L12.85 12.2998L8.35 16.7998Z"/>
+ </svg>
+ """.trimIndent())
+ }
+ }
+ copiedPopup("Link copied to clipboard")
+ }
+ }
+
fun FlowContent.buildLink(
to: DRI,
platforms: List<SourceSetData>,
@@ -497,7 +579,7 @@ open class HtmlRenderer(
}
}
- private fun resolveLink(link: String, page: PageNode) : String = if (URI(link).isAbsolute) link else page.root(link)
+ private fun resolveLink(link: String, page: PageNode): String = if (URI(link).isAbsolute) link else page.root(link)
open fun buildHtml(page: PageNode, resources: List<String>, content: FlowContent.() -> Unit) =
createHTML().html {
@@ -506,9 +588,13 @@ open class HtmlRenderer(
title(page.name)
with(resources) {
filter { it.substringBefore('?').substringAfterLast('.') == "css" }
- .forEach { link(rel = LinkRel.stylesheet, href = resolveLink(it,page)) }
+ .forEach { link(rel = LinkRel.stylesheet, href = resolveLink(it, page)) }
filter { it.substringBefore('?').substringAfterLast('.') == "js" }
- .forEach { script(type = ScriptType.textJavaScript, src = resolveLink(it,page)) { async = true } }
+ .forEach {
+ script(type = ScriptType.textJavaScript, src = resolveLink(it, page)) {
+ async = true
+ }
+ }
}
script { unsafe { +"""var pathToRoot = "${locationProvider.resolveRoot(page)}";""" } }
}
@@ -532,6 +618,38 @@ open class HtmlRenderer(
script(type = ScriptType.textJavaScript, src = page.root("scripts/pages.js")) {}
script(type = ScriptType.textJavaScript, src = page.root("scripts/main.js")) {}
content()
+ div(classes = "footer") {
+ span("go-to-top-icon") {
+ a(href = "#container") {
+ unsafe {
+ raw(
+ """
+ <svg width="12" height="10" viewBox="0 0 12 10" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M11.3337 9.66683H0.666992L6.00033 3.66683L11.3337 9.66683Z" fill="black"/>
+ <path d="M0.666992 0.333496H11.3337V1.66683H0.666992V0.333496Z" fill="black"/>
+ </svg>
+ """.trimIndent()
+ )
+ }
+ }
+ }
+ span { text("© 2020 Copyright") }
+ span { text("Privacy Policy") }
+ span("pull-right") {
+ span { text("Sponsored and developed by Dokka") }
+ span(classes = "padded-icon") {
+ unsafe {
+ raw(
+ """
+ <svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8 0H2.3949L4.84076 2.44586L0 7.28662L0.713376 8L5.55414 3.15924L8 5.6051V0Z" fill="black"/>
+ </svg>
+ """.trimIndent()
+ )
+ }
+ }
+ }
+ }
}
}
}
diff --git a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
index 45ef1457..f10c85d5 100644
--- a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
+++ b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt
@@ -5,6 +5,8 @@ import kotlinx.html.id
import kotlinx.html.table
import kotlinx.html.tbody
import org.jetbrains.dokka.base.renderers.platforms
+import org.jetbrains.dokka.model.DEnum
+import org.jetbrains.dokka.model.DEnumEntry
import org.jetbrains.dokka.pages.*
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.transformers.pages.PageTransformer
@@ -44,12 +46,19 @@ object NavigationPageInstaller : PageTransformer {
page.name,
page.dri.first(),
page.platforms(),
- if (page !is ClasslikePageNode)
- page.children.filterIsInstance<ContentPage>()
- .map { visit(it) }
- else
- emptyList()
+ page.navigableChildren()
)
+
+ private fun ContentPage.navigableChildren(): List<NavigationNode> {
+ if(this !is ClasslikePageNode){
+ return children.filterIsInstance<ContentPage>()
+ .map { visit(it) }
+ } else if(documentable is DEnum) {
+ return children.filter { it is ContentPage && it.documentable is DEnumEntry }.map { visit(it as ContentPage) }
+ }
+
+ return emptyList()
+ }
}
object ResourceInstaller : PageTransformer {
@@ -68,6 +77,7 @@ object StyleAndScriptsAppender : PageTransformer {
"scripts/navigationLoader.js",
"scripts/platformContentHandler.js",
"scripts/sourceset_dependencies.js",
+ "scripts/clipboard.js",
"styles/jetbrains-mono.css"
)
)
diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
index 4868d91e..5514f9e5 100644
--- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
+++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt
@@ -253,7 +253,7 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog
}
private fun funType(dri: DRI, sourceSets: Set<SourceSetData>, type: TypeConstructor) =
- contentBuilder.contentFor(dri, sourceSets, ContentKind.Symbol, setOf(TextStyle.Monospace)) {
+ contentBuilder.contentFor(dri, sourceSets) {
if (type.extension) {
signatureForProjection(type.projections.first())
text(".")
diff --git a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt
index 1954cec9..bdc6d680 100644
--- a/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt
+++ b/plugins/base/src/main/kotlin/translators/documentables/DefaultPageCreator.kt
@@ -66,9 +66,11 @@ open class DefaultPageCreator(
protected open fun contentForModule(m: DModule) = contentBuilder.contentFor(m) {
group(kind = ContentKind.Cover) {
- header(1, m.name)
- sourceSetDependentHint(m.dri, m.sourceSets.toSet(), kind = ContentKind.SourceSetDependantHint){
- +contentForDescription(m)
+ cover(m.name)
+ if(contentForDescription(m).isNotEmpty()){
+ sourceSetDependentHint(m.dri, m.sourceSets.toSet(), kind = ContentKind.SourceSetDependantHint, styles = setOf(TextStyle.UnderCoverText)){
+ +contentForDescription(m)
+ }
}
}
+contentForComments(m)
@@ -81,9 +