From 25d826bb75a78eb674a63aed19f55e92d7ff8bca Mon Sep 17 00:00:00 2001 From: Filip Zybała Date: Tue, 12 May 2020 14:58:05 +0200 Subject: Migrated resources to base-plugin --- .../main/resources/dokka/styles/jetbrains-mono.css | 13 + .../base/src/main/resources/dokka/styles/style.css | 735 +++++++++++++++++++++ 2 files changed, 748 insertions(+) create mode 100644 plugins/base/src/main/resources/dokka/styles/jetbrains-mono.css create mode 100644 plugins/base/src/main/resources/dokka/styles/style.css (limited to 'plugins/base/src/main/resources/dokka/styles') diff --git a/plugins/base/src/main/resources/dokka/styles/jetbrains-mono.css b/plugins/base/src/main/resources/dokka/styles/jetbrains-mono.css new file mode 100644 index 00000000..2af32a92 --- /dev/null +++ b/plugins/base/src/main/resources/dokka/styles/jetbrains-mono.css @@ -0,0 +1,13 @@ +@font-face{ + font-family: 'JetBrains Mono'; + src: url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/web/woff2/JetBrainsMono-Regular.woff2') format('woff2'); + font-weight: normal; + font-style: normal; +} + +@font-face{ + font-family: 'JetBrains Mono'; + src: url('https://raw.githubusercontent.com/JetBrains/JetBrainsMono/master/web/woff2/JetBrainsMono-Bold.woff2') format('woff2'); + font-weight: bold; + font-style: normal; +} \ No newline at end of file diff --git a/plugins/base/src/main/resources/dokka/styles/style.css b/plugins/base/src/main/resources/dokka/styles/style.css new file mode 100644 index 00000000..6ba41db4 --- /dev/null +++ b/plugins/base/src/main/resources/dokka/styles/style.css @@ -0,0 +1,735 @@ +@import url(https://fonts.googleapis.com/css?family=Open+Sans:300i,400,700); +@import url('https://rsms.me/inter/inter.css'); +@import url('jetbrains-mono.css'); + +:root { + --breadcrumb-font-color: #A6AFBA; + --hover-link-color: #5B5DEF +} + +#content { + padding: 0 41px; +} + +.breadcrumbs { + padding: 24px 0; + color: var(--breadcrumb-font-color); +} + +.breadcrumbs a { + color: var(--breadcrumb-font-color) +} + +.breadcrumbs a:hover { + color: var(--hover-link-color) +} + +.tabs-section-body > *:not([data-active]){ + display: none; +} + +.tabs-section > .section-tab:first-child { + margin-left: 0; +} + +.section-tab { + border: 0; + cursor: pointer; + background-color: transparent; + border-bottom: 1px solid #DADFE6; + padding: 11px 3px; + font-size: 14px; + color: #637282; + outline:none; + margin: 0 8px; +} + +.section-tab:hover { + color: #282E34; + border-bottom: 2px solid var(--hover-link-color); +} + +.section-tab[data-active=''] { + color: #282E34; + border-bottom: 2px solid var(--hover-link-color); +} + +.tabs-section-body { + padding: 24px 0 +} + +.cover > .platform-hinted { + padding: 24px 0 +} + +.tabbedcontent { + padding: 24px 0; +} + +.cover .platform-hinted .single-content > .symbol { + background-color: white; +} + +.divergent-group { + background-color: white; + padding: 12px 8px; + margin-bottom: 2px; +} + +.divergent-group .table-row { + background-color: #F4F4F4; +} + +#container { + display: flex; + flex-direction: row; + min-height: 100%; +} + +#main { + width: 100%; + padding-left: 12px; +} + +#leftColumn { + width: 280px; + min-height: 100%; + border-right: 1px solid #DADFE6; + flex: 0 0 auto; +} + +@media screen and (max-width: 600px) { + #container { + flex-direction: column; + } + + #leftColumn { + border-right: none; + } +} + +#sideMenu { + height: 100%; + padding-top: 16px; + position: relative; + overflow: auto; +} + +#sideMenu img { + margin: 1em 0.25em; +} + +#sideMenu hr { + background: #DADFE6; +} + +#searchBar { + float: right; +} + +#logo { + background-size: 125px 26px; + border-bottom: 1px solid #DADFE6; + background-repeat: no-repeat; + background-image: url(../images/docs_logo.svg); + background-origin: content-box; + padding-left: 24px; + padding-top: 24px; + height: 48px; +} + +.monospace, +.code { + font-family: monospace; +} + +.overview > .navButton { + width: 100%; + height: 100%; + align-items: center; + display: flex; + justify-content: flex-end; + padding-right: 24px; +} + +.strikethrough { + text-decoration: line-through; +} + +.symbol:empty { + padding: 0; +} + +.symbol { + background-color: #F4F4F4; + align-items: center; + display: flex; + padding: 8px 16px; + box-sizing: border-box; + font-weight: bold; + white-space: pre; + flex-wrap: wrap; +} + +#nav-submenu > .sideMenuPart { + padding-left: 0; /* packages are same level as modules */ +} + +.sideMenuPart > .overview { + height: 40px; + width: 100%; + display: flex; + align-items: center; + position: relative; + user-select: none; /* there's a weird bug with text selection */ +} + +.sideMenuPart a { + display: flex; + align-items: center; + flex: 1; + height: 100%; + color: #637282; +} + +.sideMenuPart > .overview:before { + box-sizing: border-box; + content: ''; + top: 0; + width: 200%; + right: 0; + bottom: 0; + position: absolute; + z-index: -1; +} + +.overview:hover:before { + background-color: #DADFE5; +} + +#nav-submenu { + padding-left: 24px; +} + +.sideMenuPart { + padding-left: 12px; + box-sizing: border-box; +} + +.sideMenuPart .hidden > .overview .navButtonContent::before { + transform: rotate(0deg); +} + +.sideMenuPart > .overview .navButtonContent::before { + content: url("../images/arrow_down.svg"); + height: 100%; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + transform: rotate(180deg); +} + +.sideMenuPart.hidden > .navButton .navButtonContent::after { + content: '\02192'; +} + +.sideMenuPart.hidden > .sideMenuPart { + height: 0; + visibility: hidden; +} + +.filtered > a, .filtered > .navButton { + display: none; +} + +body, table { + font-family: 'Inter', "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + background: #F4F4F4; + font-style: normal; + font-weight: normal; + font-size: 14px; + line-height: 24px; + margin: 0; + max-width: 1440px; +} + +table { + width: 100%; + border-collapse: collapse; + background-color: #ffffff; + padding: 5px; +} + +tbody > tr { + border-bottom: 2px solid #F4F4F4; + min-height: 56px; +} + +td:first-child { + width: 20vw; +} + +.keyword { + color: black; + font-family: JetBrains Mono, Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; + font-size: 12px; +} + +.symbol { + font-family: JetBrains Mono, Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; + font-size: 12px; + min-height: 43px; +} + +.symbol > a { + color: var(--hover-link-color); + text-decoration: underline; +} + +.identifier { + color: darkblue; + font-size: 12px; + font-family: JetBrains Mono, Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; +} + +.brief { + white-space: pre-wrap; + overflow: hidden; + padding-top: 8px; +} + +h1, h2, h3, h4, h5, h6 { + color: #222; +} + +p, ul, ol, table, pre, dl { + margin: 0 0 20px; +} + +h1, h2, h3 { + line-height: 1.1; +} + +h1 { + font-size: 60px; + line-height: 64px; + letter-spacing: -1.5px; +} + +h2 { + color: #393939; +} + +h3, h4, h5, h6 { + color: #494949; +} + +a { + color: #258aaf; + font-weight: 400; + text-decoration: none; +} + +a:hover { + color: #282E34; + text-decoration: none; +} + +a small { + font-size: 11px; + color: #555; + margin-top: -0.6em; + display: block; +} + +.wrapper { + width: 860px; + margin: 0 auto; +} + +blockquote { + border-left: 1px solid #e5e5e5; + margin: 0; + padding: 0 0 0 20px; + font-style: italic; +} + +code, pre { + font-family: Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; + color: #333; + font-size: 12px; +} + +pre { + display: block; + /* + padding:8px 8px; + background: #f8f8f8; + border-radius:5px; + border:1px solid #e5e5e5; + */ + overflow-x: auto; +} + +th, td { + text-align: left; + vertical-align: top; + padding: 5px 10px; +} + +dt { + color: #444; + font-weight: 700; +} + +th { + color: #444; +} + +img { + max-width: 100%; +} + +header { + width: 270px; + float: left; + position: fixed; +} + +header ul { + list-style: none; + height: 40px; + + padding: 0; + + background: #eee; + background: -moz-linear-gradient(top, #f8f8f8 0%, #dddddd 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f8f8f8), color-stop(100%, #dddddd)); + background: -webkit-linear-gradient(top, #f8f8f8 0%, #dddddd 100%); + background: -o-linear-gradient(top, #f8f8f8 0%, #dddddd 100%); + background: -ms-linear-gradient(top, #f8f8f8 0%, #dddddd 100%); + background: linear-gradient(top, #f8f8f8 0%, #dddddd 100%); + + border-radius: 5px; + border: 1px solid #d2d2d2; + box-shadow: inset #fff 0 1px 0, inset rgba(0, 0, 0, 0.03) 0 -1px 0; + width: 270px; +} + +header li { + width: 89px; + float: left; + border-right: 1px solid #d2d2d2; + height: 40px; +} + +header ul a { + line-height: 1; + font-size: 11px; + color: #999; + display: block; + text-align: center; + padding-top: 6px; + height: 40px; +} + +strong { + color: #222; + font-weight: 700; +} + +header ul li + li { + width: 88px; + border-left: 1px solid #fff; +} + +header ul li + li + li { + border-right: none; + width: 89px; +} + +header ul a strong { + font-size: 14px; + display: block; + color: #222; +} + +section { + width: 500px; + float: right; + padding-bottom: 50px; +} + +small { + font-size: 11px; +} + +hr { + border: 0; + background: #e5e5e5; + height: 1px; + margin: 0 0 20px; +} + +footer { + width: 270px; + float: left; + position: fixed; + bottom: 50px; +} + +.platform-tag { + display: flex; + flex-direction: row; + padding: 4px 8px; + height: 16px; + border-radius: 100px; + + font-family: Inter, Arial, sans-serif; + font-size: 12px; + font-weight: 400; + font-style: normal; + font-stretch: normal; + line-height: normal; + letter-spacing: normal; + text-align: center; + + color: #fff + +} + +.platform-tags { + flex: 0 0 auto; + display: flex; +} + +.platform-tags > .platform-tag { + align-self: center; +} + +.platform-tag.jvm-like { + background-color: #4DBB5F; + color: white; +} + +.platform-tag.js-like { + background-color: #FED236; + color: white; +} + +.platform-tag.native-like { + background-color: #CD74F6; + color: white; +} + +.platform-tag.common-like { + background-color: #A6AFBA; + color: white; +} + +td.content { + padding-left: 24px; + padding-top: 16px; + display: flex; + flex-direction: column; +} + +.main-subrow { + display: flex; + flex-direction: row; + padding: 0; + justify-content: space-between; +} + +.main-subrow > a { + text-decoration: none; + font-style: normal; + font-weight: 600; + font-size: 14px; + color: #282E34; +} + +.main-subrow > a:hover { + color: var(--hover-link-color); +} + +.platform-hinted { + flex: auto; + display: block; + margin-bottom: 5px; +} + +.platform-hinted > .platform-bookmarks-row > .platform-bookmark { + min-width: 64px; + height: 36px; + border: 2px solid white; + background: white; + outline: none; + flex: none; + order: 5; + align-self: flex-start; + margin: 0; +} + +.platform-hinted > .platform-bookmarks-row > .platform-bookmark.jvm-like:hover { + border-top: 2px solid rgba(77, 187, 95, 0.3); +} + +.platform-hinted > .platform-bookmarks-row > .platform-bookmark.js-like:hover { + border-top: 2px solid rgba(254, 175, 54, 0.3); +} + +.platform-hinted > .platform-bookmarks-row > .platform-bookmark.native-like:hover { + border-top: 2px solid rgba(105, 118, 249, 0.3); +} + +.platform-hinted > .platform-bookmarks-row > .platform-bookmark.common-like:hover { + border-top: 2px solid rgba(161, 170, 180, 0.3); +} + +.platform-hinted > .platform-bookmarks-row > .platform-bookmark.jvm-like[data-active=''] { + border: 2px solid #F4F4F4; + border-top: 2px solid #4DBB5F; + + background: #F4F4F4; +} + +.platform-hinted > .platform-bookmarks-row > .platform-bookmark.js-like[data-active=''] { + border: 2px solid #F4F4F4; + border-top: 2px solid #FED236; + + background: #F4F4F4; +} + +.platform-hinted > .platform-bookmarks-row > .platform-bookmark.native-like[data-active=''] { + border: 2px solid #F4F4F4; + border-top: 2px solid #CD74F6; + + background: #F4F4F4; +} + +.platform-hinted > .platform-bookmarks-row > .platform-bookmark.common-like[data-active=''] { + border: 2px solid #F4F4F4; + border-top: 2px solid #A6AFBA; + + background: #F4F4F4; +} + +.platform-hinted > .content:not([data-active]) { + display: none +} + +.sideMenuPart[data-active] > .overview { + background: rgba(91, 93, 239, 0.15); + border-left: 4px solid var(--hover-link-color); +} + +.table { + display: flex; + flex-direction: column; +} + +.table-row { + display: flex; + flex-direction: column; + background: white; + margin-bottom: 2px; + padding: 16px 24px 16px 24px; +} + +.platform-dependent-row { + display: grid; + padding-top: 8px; +} + +.title-row { + display: grid; + grid-template-columns: auto auto 7em; + width: 100%; +} + +.keyValue { + display: grid; +} + +@media print, screen and (min-width: 960px) { + .keyValue { + grid-template-columns: 20% auto; + } + + .title-row { + grid-template-columns: 20% auto 7em; + } +} + +@media print, screen and (max-width: 960px) { + + div.wrapper { + width: auto; + margin: 0; + } + + header, section, footer { + float: none; + position: static; + width: auto; + } + + header { + padding-right: 320px; + } + + section { + border: 1px solid #e5e5e5; + border-width: 1px 0; + padding: 20px 0; + margin: 0 0 20px; + } + + header a small { + display: inline; + } + + header ul { + position: absolute; + right: 50px; + top: 52px; + } +} + +@media print, screen and (max-width: 720px) { + body { + word-wrap: break-word; + } + + header { + padding: 0; + } + + header ul, header p.view { + position: static; + } + + pre, code { + word-wrap: normal; + } +} + +@media print, screen and (max-width: 480px) { + body { + padding-right: 15px; + } + + header ul { + display: none; + } +} + +@media print { + body { + padding: 0.4in; + font-size: 12pt; + color: #444; + } +} -- cgit From dd5d4ba7d80b0880489cf74bb11549ff836fc41f Mon Sep 17 00:00:00 2001 From: Filip Zybała Date: Wed, 27 May 2020 13:03:32 +0200 Subject: Fixed table rendering for markdown. --- .../src/main/kotlin/renderers/html/HtmlRenderer.kt | 43 ++++++++++++++++++++-- .../base/src/main/resources/dokka/styles/style.css | 6 +-- 2 files changed, 42 insertions(+), 7 deletions(-) (limited to 'plugins/base/src/main/resources/dokka/styles') diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index 792eb1dc..52f7024a 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -302,10 +302,45 @@ open class HtmlRenderer( pageContext: ContentPage, sourceSetRestriction: Set? ) { - div(classes = "table") { - node.extra.extraHtmlAttributes().forEach { attributes[it.extraKey] = it.extraValue } - node.children.forEach { - buildRow(it, pageContext, sourceSetRestriction) + when(node.dci.kind){ + ContentKind.Comment -> buildDefaultTable(node, pageContext, sourceSetRestriction) + else -> div(classes = "table") { + node.extra.extraHtmlAttributes().forEach { attributes[it.extraKey] = it.extraValue } + node.children.forEach { + buildRow(it, pageContext, sourceSetRestriction) + } + } + } + + } + + fun FlowContent.buildDefaultTable( + node: ContentTable, + pageContext: ContentPage, + sourceSetRestriction: Set? + ) { + table { + thead { + node.header.forEach { + tr { + it.children.forEach { + th { + it.build(this@table, pageContext, sourceSetRestriction) + } + } + } + } + } + tbody { + node.children.forEach { + tr { + it.children.forEach { + td { + it.build(this, pageContext, sourceSetRestriction) + } + } + } + } } } } diff --git a/plugins/base/src/main/resources/dokka/styles/style.css b/plugins/base/src/main/resources/dokka/styles/style.css index 6ba41db4..671dfe8a 100644 --- a/plugins/base/src/main/resources/dokka/styles/style.css +++ b/plugins/base/src/main/resources/dokka/styles/style.css @@ -326,14 +326,14 @@ h3, h4, h5, h6 { } a { - color: #258aaf; + color: #5B5DEF; font-weight: 400; text-decoration: none; } a:hover { - color: #282E34; - text-decoration: none; + color: #5B5DEF; + text-decoration: underline; } a small { -- cgit From 0f1c461d20336444bc667713954ea2879cc0a396 Mon Sep 17 00:00:00 2001 From: Filip Zybała Date: Thu, 21 May 2020 09:51:54 +0200 Subject: Added filtering to HTML pages --- plugins/base/src/main/kotlin/DokkaBase.kt | 6 ++ .../src/main/kotlin/renderers/html/HtmlRenderer.kt | 39 ++++++++- .../kotlin/renderers/html/htmlPreprocessors.kt | 26 ++++++ .../dokka/scripts/platformContentHandler.js | 95 +++++++++++++++++++++- .../base/src/main/resources/dokka/styles/style.css | 33 +++++++- 5 files changed, 195 insertions(+), 4 deletions(-) (limited to 'plugins/base/src/main/resources/dokka/styles') diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt index a6052a9e..382b8f86 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -174,4 +174,10 @@ class DokkaBase : DokkaPlugin() { ) } order { after(rootCreator) } } + + val sourcesetDependencyAppender by extending { + htmlPreprocessors providing ::SourcesetDependencyAppender order { after(rootCreator)} + } + + } \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index 52f7024a..b089c71a 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -63,13 +63,35 @@ open class HtmlRenderer( } node.dci.kind == ContentKind.Symbol -> div("symbol $additionalClasses") { childrenCallback() } node.dci.kind == ContentKind.BriefComment -> div("brief $additionalClasses") { childrenCallback() } - node.dci.kind == ContentKind.Cover -> div("cover $additionalClasses") { childrenCallback() } + node.dci.kind == ContentKind.Cover -> div("cover $additionalClasses") { + filterButtons(node) + childrenCallback() + } node.hasStyle(TextStyle.Paragraph) -> p(additionalClasses) { childrenCallback() } node.hasStyle(TextStyle.Block) -> div(additionalClasses) { childrenCallback() } else -> childrenCallback() } } + private fun FlowContent.filterButtons(group: ContentGroup) { + div(classes = "filter-section") { + id = "filter-section" + group.sourceSets.forEach { + button(classes = "platform-tag platform-selector") { + attributes["data-active"] = "" + attributes["data-filter"] = it.sourceSetName + when(it.platform.key){ + "common" -> classes = classes + "common-like" + "native" -> classes = classes + "native-like" + "jvm" -> classes = classes + "jvm-like" + "js" -> classes = classes + "js-like" + } + text(it.sourceSetName) + } + } + } + } + override fun FlowContent.buildPlatformDependent(content: PlatformHintedContent, pageContext: ContentPage) = buildPlatformDependent(content.sourceSets.map { it to setOf(content.inner) }.toMap(), pageContext, content.extra) @@ -108,6 +130,8 @@ open class HtmlRenderer( attributes["data-toggle-list"] = "data-toggle-list" contents.forEachIndexed { index, pair -> button(classes = "platform-bookmark") { + attributes["data-filterable-current"] = pair.first.sourceSetName + attributes["data-filterable-set"] = pair.first.sourceSetName if (index == 0) attributes["data-active"] = "" attributes["data-toggle"] = pair.first.sourceSetName when( @@ -160,8 +184,15 @@ open class HtmlRenderer( consumer.onTagContentUnsafe { +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) -> @@ -242,6 +273,12 @@ open class HtmlRenderer( ?.let { withAnchor(node.dci.dri.first().toString()) { div(classes = "table-row") { + attributes["data-filterable-current"] = node.sourceSets.joinToString(" ") { + it.sourceSetName + } + attributes["data-filterable-set"] = node.sourceSets.joinToString(" ") { + it.sourceSetName + } it.filterIsInstance().takeIf { it.isNotEmpty() }?.let { div("main-subrow " + node.style.joinToString(" ")) { it.filter { sourceSetRestriction == null || it.sourceSets.any { s -> s in sourceSetRestriction } } diff --git a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt index 710407c5..45ef1457 100644 --- a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt +++ b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt @@ -6,6 +6,7 @@ import kotlinx.html.table import kotlinx.html.tbody import org.jetbrains.dokka.base.renderers.platforms import org.jetbrains.dokka.pages.* +import org.jetbrains.dokka.plugability.DokkaContext import org.jetbrains.dokka.transformers.pages.PageTransformer @@ -66,8 +67,33 @@ object StyleAndScriptsAppender : PageTransformer { "styles/style.css", "scripts/navigationLoader.js", "scripts/platformContentHandler.js", + "scripts/sourceset_dependencies.js", "styles/jetbrains-mono.css" ) ) } +} + +class SourcesetDependencyAppender(val context: DokkaContext) : PageTransformer{ + override fun invoke(input: RootPageNode): RootPageNode { + val dependenciesMap = context.configuration.passesConfigurations.map { + it.sourceSetName to it.dependentSourceSets + }.toMap() + fun createDependenciesJson() : String = "sourceset_dependencies = '{${ + dependenciesMap.entries.joinToString(", ") { + "\"${it.key}\": [${it.value.joinToString(","){ + "\"$it\"" + }}]" + } + }}'" + val deps = RendererSpecificResourcePage( + name = "scripts/sourceset_dependencies.js", + children = emptyList(), + strategy = RenderingStrategy.Write(createDependenciesJson()) + ) + + return input.modified( + children = input.children + deps + ) + } } \ No newline at end of file diff --git a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js b/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js index 72c8daae..cd993587 100644 --- a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js +++ b/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js @@ -1,13 +1,71 @@ +filteringContext = { + dependencies: {}, + restrictedDependencies: [], + activeFilters: [] +} window.addEventListener('load', () => { + initializeFiltering() document.querySelectorAll("div[data-platform-hinted]") .forEach(elem => elem.addEventListener('click', (event) => togglePlatformDependent(event,elem))) document.querySelectorAll("div[tabs-section]") - .forEach(elem => elem.addEventListener('click', (event) => toggleSections(event))) + .forEach(elem => elem.addEventListener('click', (event) => toggleSections(event))) + document.getElementById('filter-section').addEventListener('click', (event) => filterButtonHandler(event)) document.querySelector(".tabs-section-body") .querySelector("div[data-togglable]") .setAttribute("data-active", "") }) +function filterButtonHandler(event) { + if(event.target.tagName == "BUTTON" && event.target.hasAttribute("data-filter")) { + let sourceset = event.target.getAttribute("data-filter") + if(filteringContext.activeFilters.indexOf(sourceset) != -1) { + filterSourceset(sourceset) + } else { + unfilterSourceset(sourceset) + } + } + refreshFilterButtons(); + refreshPlatformTabs() +} + +function initializeFiltering() { + filteringContext.dependencies = JSON.parse(sourceset_dependencies) + document.querySelectorAll("#filter-section > button") + .forEach(p => filteringContext.restrictedDependencies.push(p.getAttribute("data-filter"))) + Object.keys(filteringContext.dependencies).forEach(p => { + filteringContext.dependencies[p] = filteringContext.dependencies[p] + .filter(q => -1 !== filteringContext.restrictedDependencies.indexOf(q)) + }) + filteringContext.activeFilters = filteringContext.restrictedDependencies +} + +function refreshFilterButtons() { + document.querySelectorAll("#filter-section > button") + .forEach(f => { + if(filteringContext.activeFilters.indexOf(f.getAttribute("data-filter")) != -1){ + f.setAttribute("data-active","") + } else { + f.removeAttribute("data-active") + } + }) +} + +function filterSourceset(sourceset) { + filteringContext.activeFilters = filteringContext.activeFilters.filter(p => p != sourceset) + refreshFiltering() +} + +function unfilterSourceset(sourceset) { + if(filteringContext.activeFilters.length == 0) { + filteringContext.activeFilters = filteringContext.dependencies[sourceset].concat([sourceset]) + refreshFiltering() + } else { + filteringContext.activeFilters.push(sourceset) + refreshFiltering() + } +} + + function toggleSections(evt){ if(!evt.target.getAttribute("data-togglable")) return @@ -50,3 +108,38 @@ function togglePlatformDependent(e, container) { } } } + +function refreshFiltering() { + let sourcesetList = filteringContext.activeFilters + document.querySelectorAll("[data-filterable-set]") + .forEach( + elem => { + let platformList = elem.getAttribute("data-filterable-set").split(' ').filter(v => -1 !== sourcesetList.indexOf(v)) + elem.setAttribute("data-filterable-current", platformList.join(' ')) + } + ) +} + +function refreshPlatformTabs() { + document.querySelectorAll(".platform-hinted > .platform-bookmarks-row").forEach( + p => { + let active = false; + let firstAvailable = null + p.childNodes.forEach( + element => { + if(element.getAttribute("data-filterable-current") != ''){ + if( firstAvailable == null) { + firstAvailable = element + } + if(element.hasAttribute("data-active")) { + active = true; + } + } + } + ) + if( active == false && firstAvailable !== null ) { + firstAvailable.click() + } + } + ) +} diff --git a/plugins/base/src/main/resources/dokka/styles/style.css b/plugins/base/src/main/resources/dokka/styles/style.css index 671dfe8a..d9927046 100644 --- a/plugins/base/src/main/resources/dokka/styles/style.css +++ b/plugins/base/src/main/resources/dokka/styles/style.css @@ -62,6 +62,11 @@ padding: 24px 0 } +.cover { + display: flex; + flex-direction: column; +} + .tabbedcontent { padding: 24px 0; } @@ -483,9 +488,11 @@ footer { display: flex; flex-direction: row; padding: 4px 8px; - height: 16px; + height: 24px; border-radius: 100px; - + box-sizing: border-box; + border: 1px solid transparent; + margin: 2px; font-family: Inter, Arial, sans-serif; font-size: 12px; font-weight: 400; @@ -494,6 +501,7 @@ footer { line-height: normal; letter-spacing: normal; text-align: center; + outline: none; color: #fff @@ -528,6 +536,27 @@ footer { color: white; } +.filter-section { + display: flex; + display: flex; + flex-direction: row; + align-self: flex-end; + min-height: 30px; +} + +.platform-selector:hover { + border: 1px solid #A6AFBA !important; +} + +[data-filterable-current=''] { + display: none !important; +} +.platform-selector:not([data-active]) { + border: 1px solid #DADFE6; + background-color: white; + color: #637282; +} + td.content { padding-left: 24px; padding-top: 16px; -- cgit From f0742fb7f8a937ef7c2e5a92d6f4a0fd079baa62 Mon Sep 17 00:00:00 2001 From: Marcin Aman Date: Mon, 25 May 2020 14:40:59 +0200 Subject: Enum constructor values --- core/src/main/kotlin/model/aditionalExtras.kt | 11 ++ .../kotlin/signatures/KotlinSignatureProvider.kt | 14 +- .../DefaultDescriptorToDocumentableTranslator.kt | 26 +++- .../base/src/main/resources/dokka/styles/style.css | 1 - plugins/base/src/test/kotlin/enums/EnumsTest.kt | 146 ++++++++++++++++++++- plugins/base/src/test/kotlin/utils/contentUtils.kt | 2 +- 6 files changed, 189 insertions(+), 11 deletions(-) (limited to 'plugins/base/src/main/resources/dokka/styles') diff --git a/core/src/main/kotlin/model/aditionalExtras.kt b/core/src/main/kotlin/model/aditionalExtras.kt index f71852c4..055fc5a6 100644 --- a/core/src/main/kotlin/model/aditionalExtras.kt +++ b/core/src/main/kotlin/model/aditionalExtras.kt @@ -59,4 +59,15 @@ data class ActualTypealias(val underlyingType: SourceSetDependent) : Extr } override val key: ExtraProperty.Key = ActualTypealias +} + +data class ConstructorValues(val values: List) : ExtraProperty{ + companion object : ExtraProperty.Key { + override fun mergeStrategyFor(left: ConstructorValues, right: ConstructorValues) = + MergeStrategy.Fail{ + throw IllegalArgumentException("Merging constructor parameters not applicable") + } + } + + override val key: ExtraProperty.Key = ConstructorValues } \ No newline at end of file diff --git a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt index 33c82458..367a7a95 100644 --- a/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt +++ b/plugins/base/src/main/kotlin/signatures/KotlinSignatureProvider.kt @@ -33,8 +33,16 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog } private fun signature(e: DEnumEntry) = - contentBuilder.contentFor(e, ContentKind.Symbol, setOf(TextStyle.Monospace)) { - link(e.name, e.dri) + contentBuilder.contentFor(e, ContentKind.Symbol, setOf(TextStyle.Monospace), sourceSets = e.sourceSets.toSet()) { + group(styles = setOf(TextStyle.Block)){ + annotationsBlock(e) + link(e.name, e.dri, styles = emptySet()) + e.extra[ConstructorValues]?.let { + list(it.values, prefix = "(", suffix = ")"){ + text(it) + } + } + } } private fun actualTypealiasedSignature(dri: DRI, name: String, aliasedTypes: SourceSetDependent) = @@ -87,7 +95,7 @@ class KotlinSignatureProvider(ctcc: CommentsToContentConverter, logger: DokkaLog +buildSignature(it) } } - if (c is DClass) { + if (c is WithConstructors) { val pConstructor = c.constructors.singleOrNull { it.extra[PrimaryConstructorExtra] != null } if (pConstructor?.annotations()?.isNotEmpty() == true) { text(nbsp.toString()) diff --git a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt index 60182ba9..a56eb454 100644 --- a/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt +++ b/plugins/base/src/main/kotlin/translators/descriptors/DefaultDescriptorToDocumentableTranslator.kt @@ -24,8 +24,9 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies import org.jetbrains.kotlin.idea.kdoc.findKDoc import org.jetbrains.kotlin.load.kotlin.toSourceElement -import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentsInParentheses import org.jetbrains.kotlin.resolve.calls.components.isVararg import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.AnnotationValue as ConstantsAnnotationValue @@ -41,9 +42,12 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.source.KotlinSourceElement +import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.types.DynamicType import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeProjection +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.safeAs import java.nio.file.Paths import kotlin.IllegalArgumentException @@ -212,7 +216,11 @@ private class DokkaDescriptorVisitor( properties = scope.properties(driWithPlatform), sourceSets = listOf(sourceSet), expectPresentInSet = sourceSet.takeIf { isExpect }, - extra = PropertyContainer.withAll(descriptor.additionalExtras(), descriptor.getAnnotations()) + extra = PropertyContainer.withAll( + descriptor.additionalExtras(), + descriptor.getAnnotations(), + ConstructorValues(descriptor.getAppliedConstructorParameters()) + ) ) } @@ -499,7 +507,6 @@ private class DokkaDescriptorVisitor( getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS, packageLevel) .filter { it is ClassDescriptor && it.kind != ClassKind.ENUM_ENTRY } .map { visitClassDescriptor(it as ClassDescriptor, parent) } - .mapNotNull { it as? DClasslike } private fun MemberScope.packages(parent: DRIWithPlatformInfo): List = getContributedDescriptors(DescriptorKindFilter.PACKAGES) { true } @@ -681,6 +688,19 @@ private class DokkaDescriptorVisitor( private fun ValueParameterDescriptor.getDefaultValue(): String? = (source as? KotlinSourceElement)?.psi?.children?.find { it is KtExpression }?.text + private fun ClassDescriptor.getAppliedConstructorParameters() = + (source as PsiSourceElement).psi?.children?.flatMap { + it.safeAs()?.initializersAsText().orEmpty() + }.orEmpty() + + private fun KtInitializerList.initializersAsText() = + initializers.firstIsInstanceOrNull() + ?.getValueArgumentsInParentheses() + ?.flatMap { it.childrenAsText() } + .orEmpty() + + private fun ValueArgument.childrenAsText() = this.safeAs()?.children?.map {it.text }.orEmpty() + private data class ClassInfo(val supertypes: List, val docs: SourceSetDependent) private fun Visibility.toDokkaVisibility(): org.jetbrains.dokka.model.Visibility = when (this) { diff --git a/plugins/base/src/main/resources/dokka/styles/style.css b/plugins/base/src/main/resources/dokka/styles/style.css index d9927046..d573b76c 100644 --- a/plugins/base/src/main/resources/dokka/styles/style.css +++ b/plugins/base/src/main/resources/dokka/styles/style.css @@ -172,7 +172,6 @@ padding: 8px 16px; box-sizing: border-box; font-weight: bold; - white-space: pre; flex-wrap: wrap; } diff --git a/plugins/base/src/test/kotlin/enums/EnumsTest.kt b/plugins/base/src/test/kotlin/enums/EnumsTest.kt index 5f8bf8c8..6c44dc35 100644 --- a/plugins/base/src/test/kotlin/enums/EnumsTest.kt +++ b/plugins/base/src/test/kotlin/enums/EnumsTest.kt @@ -1,11 +1,16 @@ package enums +import matchers.content.assertNode +import matchers.content.group +import matchers.content.header +import matchers.content.link +import org.jetbrains.dokka.model.ConstructorValues import org.jetbrains.dokka.model.DEnum -import org.jetbrains.dokka.pages.ClasslikePageNode -import org.jetbrains.dokka.pages.ModulePageNode -import org.junit.jupiter.api.Test +import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.testApi.testRunner.AbstractCoreTest import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Test +import utils.unwrapAnnotation class EnumsTest : AbstractCoreTest() { @@ -85,7 +90,142 @@ class EnumsTest : AbstractCoreTest() { } } + @Test + fun enumWithConstructor() { + val configuration = dokkaConfiguration { + passes { + pass { + sourceRoots = listOf("src/") + } + } + } + + testInline( + """ + |/src/main/kotlin/basic/Test.kt + |package enums + | + | + |enum class Test(name: String, index: Int, excluded: Boolean) { + | E1("e1", 1, true), + | E2("e2", 2, false); + |} + """.trimMargin(), + configuration + ) { + documentablesTransformationStage = { m -> + m.packages.let { p -> + p.first().classlikes.let { c -> + val enum = c.first() as DEnum + val (first, second) = enum.entries + + assertEquals(1, first.extra.allOfType().size) + assertEquals(1, second.extra.allOfType().size) + assertEquals(listOf("\"e1\"", "1", "true"), first.extra.allOfType().first().values) + assertEquals(listOf("\"e2\"", "2", "false"), second.extra.allOfType().first().values) + } + } + } + pagesGenerationStage = { module -> + val entryPage = module.dfs { it.name == "E1" } as ClasslikePageNode + val signaturePart = (entryPage.content.dfs { + it is ContentGroup && it.dci.toString() == "[enums/Test.E1///PointingToDeclaration/][Symbol]" + } as ContentGroup).children.first() as ContentGroup + assertEquals("(\"e1\", 1, true)", signaturePart.constructorSignature()) + } + } + } + + @Test + fun enumWithMethods() { + val configuration = dokkaConfiguration { + passes { + pass { + sourceRoots = listOf("src/") + } + } + } + + testInline( + """ + |/src/main/kotlin/basic/Test.kt + |package enums + | + | + |interface Sample { + | fun toBeImplemented(): String + |} + | + |enum class Test: Sample { + | E1 { + | override fun toBeImplemented(): String = "e1" + | } + |} + """.trimMargin(), + configuration + ) { + documentablesTransformationStage = { m -> + m.packages.let { p -> + p.first().classlikes.let { c -> + val enum = c.first { it is DEnum } as DEnum + val first = enum.entries.first() + + assertEquals(1, first.extra.allOfType().size) + assertEquals(emptyList(), first.extra.allOfType().first().values) + assertNotNull(first.functions.find { it.name == "toBeImplemented" }) + } + } + } + } + } + + @Test + fun enumWithAnnotationsOnEntries(){ + val configuration = dokkaConfiguration { + passes { + pass { + sourceRoots = listOf("src/") + } + } + } + + testInline( + """ + |/src/main/kotlin/basic/Test.kt + |package enums + | + |enum class Test { + | @SinceKotlin("1.3") + | E1 + |} + """.trimMargin(), + configuration + ) { + pagesTransformationStage = { m -> + val entryNode = m.children.first { it.name == "enums" }.children.first { it.name == "Test" }.children.first() as ClasslikePageNode + val signature = (entryNode.content as ContentGroup).dfs { it is ContentGroup && it.dci.toString() == "[enums/Test.E1///PointingToDeclaration/][Cover]" } as ContentGroup + + signature.assertNode { + header(1) { +"E1" } + group { + mapOf("SinceKotlin" to setOf("version")).entries.forEach { + group { + group { + unwrapAnnotation(it) + } + link { +"E1" } + } + } + } + } + } + } + } + fun ModulePageNode.getClasslikeToMemberMap() = this.parentMap.filterValues { it is ClasslikePageNode }.entries.groupBy({ it.value }) { it.key } + + private fun ContentGroup.constructorSignature(): String = + children.drop(1).joinToString(separator = "") { (it as ContentText).text } } \ No newline at end of file diff --git a/plugins/base/src/test/kotlin/utils/contentUtils.kt b/plugins/base/src/test/kotlin/utils/contentUtils.kt index 4aba3e9d..7e1b8bf4 100644 --- a/plugins/base/src/test/kotlin/utils/contentUtils.kt +++ b/plugins/base/src/test/kotlin/utils/contentUtils.kt @@ -184,7 +184,7 @@ fun ContentMatcherBuilder<*>.unnamedTag(tag: String, content: ContentMatcherBuil group { content() } } -private fun ContentMatcherBuilder<*>.unwrapAnnotation(elem: Map.Entry>) { +fun ContentMatcherBuilder<*>.unwrapAnnotation(elem: Map.Entry>) { +"@" link { +elem.key } +"(" -- cgit From 77c8777b7f66bddd374d68decd507547d356d602 Mon Sep 17 00:00:00 2001 From: Marcin Aman Date: Sun, 31 May 2020 21:02:46 +0200 Subject: Improve CSS, pages navigation tree and create anchors on page --- core/src/main/kotlin/pages/ContentNodes.kt | 14 +- core/src/main/kotlin/pages/PageNodes.kt | 1 - .../frontend/src/main/components/app/index.scss | 8 +- .../frontend/src/main/components/app/index.tsx | 45 +-- .../src/main/components/search/search.scss | 14 + .../frontend/src/main/components/search/search.tsx | 16 +- .../src/main/kotlin/renderers/html/HtmlRenderer.kt | 258 +++++++++++----- .../kotlin/renderers/html/htmlPreprocessors.kt | 20 +- .../kotlin/signatures/KotlinSignatureProvider.kt | 2 +- .../documentables/DefaultPageCreator.kt | 67 ++--- .../documentables/PageContentBuilder.kt | 14 +- .../src/main/resources/dokka/scripts/clipboard.js | 52 ++++ .../resources/dokka/scripts/navigationLoader.js | 11 + .../base/src/main/resources/dokka/styles/style.css | 330 ++++++++++++++++++--- .../kotlin/content/params/ContentForParamsTest.kt | 146 ++++----- .../content/seealso/ContentForSeeAlsoTest.kt | 170 +++++------ plugins/base/src/test/kotlin/enums/EnumsTest.kt | 8 + .../kotlin/linkableContent/LinkableContentTest.kt | 4 +- plugins/base/src/test/kotlin/markdown/LinkTest.kt | 13 +- .../test/kotlin/renderers/RenderingOnlyTestBase.kt | 1 + .../test/kotlin/renderers/html/DivergentTest.kt | 26 +- 21 files changed, 842 insertions(+), 378 deletions(-) create mode 100644 plugins/base/frontend/src/main/components/search/search.scss create mode 100644 plugins/base/src/main/resources/dokka/scripts/clipboard.js (limited to 'plugins/base/src/main/resources/dokka/styles') diff --git a/core/src/main/kotlin/pages/ContentNodes.kt b/core/src/main/kotlin/pages/ContentNodes.kt index 95b7b371..d6105bec 100644 --- a/core/src/main/kotlin/pages/ContentNodes.kt +++ b/core/src/main/kotlin/pages/ContentNodes.kt @@ -13,6 +13,8 @@ interface ContentNode : WithExtraProperties { val dci: DCI val sourceSets: Set val style: Set