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 --- .../dokka/scripts/platformContentHandler.js | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js (limited to 'plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js') diff --git a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js b/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js new file mode 100644 index 00000000..72c8daae --- /dev/null +++ b/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js @@ -0,0 +1,52 @@ +window.addEventListener('load', () => { + 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))) + document.querySelector(".tabs-section-body") + .querySelector("div[data-togglable]") + .setAttribute("data-active", "") +}) + +function toggleSections(evt){ + if(!evt.target.getAttribute("data-togglable")) return + + const activateTabs = (containerClass) => { + for(const element of document.getElementsByClassName(containerClass)){ + for(const child of element.children){ + if(child.getAttribute("data-togglable") === evt.target.getAttribute("data-togglable")){ + child.setAttribute("data-active", "") + } else { + child.removeAttribute("data-active") + } + } + } + } + + activateTabs("tabs-section") + activateTabs("tabs-section-body") +} + +function togglePlatformDependent(e, container) { + let target = e.target + if (target.tagName != 'BUTTON') return; + let index = target.getAttribute('data-toggle') + + for(let child of container.children){ + if(child.hasAttribute('data-toggle-list')){ + for(let bm of child.children){ + if(bm == target){ + bm.setAttribute('data-active',"") + } else if(bm != target) { + bm.removeAttribute('data-active') + } + } + } + else if(child.getAttribute('data-togglable') == index) { + child.setAttribute('data-active',"") + } + else { + child.removeAttribute('data-active') + } + } +} -- 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/scripts/platformContentHandler.js') 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 6a907269a96130e798815ba1723a2789fc158f3d Mon Sep 17 00:00:00 2001 From: Marcin Aman Date: Wed, 27 May 2020 13:00:08 +0200 Subject: Initially show only the default chosen tab body --- .../resources/dokka/scripts/platformContentHandler.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js') diff --git a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js b/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js index cd993587..335bb230 100644 --- a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js +++ b/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js @@ -10,10 +10,23 @@ window.addEventListener('load', () => { document.querySelectorAll("div[tabs-section]") .forEach(elem => elem.addEventListener('click', (event) => toggleSections(event))) document.getElementById('filter-section').addEventListener('click', (event) => filterButtonHandler(event)) + initTabs() +}) + +function initTabs(){ + document.querySelectorAll("div[tabs-section]") + .forEach(element => { + showCorrespondingTabBody(element) + element.addEventListener('click', (event) => toggleSections(event)) + }) +} + +function showCorrespondingTabBody(element){ + const key = element.querySelector("button[data-active]").getAttribute("data-togglable") document.querySelector(".tabs-section-body") - .querySelector("div[data-togglable]") + .querySelector("div[data-togglable='" + key + "']") .setAttribute("data-active", "") -}) +} function filterButtonHandler(event) { if(event.target.tagName == "BUTTON" && event.target.hasAttribute("data-filter")) { -- cgit From cb705ba0f457b6e0eb02337d9444d6f0ad1e67a3 Mon Sep 17 00:00:00 2001 From: Filip Zybała Date: Wed, 3 Jun 2020 10:19:59 +0200 Subject: Added persistence in window scope for filtering and tabs state. --- .../dokka/scripts/platformContentHandler.js | 72 +++++++++++++++++----- 1 file changed, 56 insertions(+), 16 deletions(-) (limited to 'plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js') diff --git a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js b/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js index 335bb230..3ff74ad5 100644 --- a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js +++ b/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js @@ -4,12 +4,12 @@ filteringContext = { 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))) document.getElementById('filter-section').addEventListener('click', (event) => filterButtonHandler(event)) + initializeFiltering() initTabs() }) @@ -19,6 +19,14 @@ function initTabs(){ showCorrespondingTabBody(element) element.addEventListener('click', (event) => toggleSections(event)) }) + let cached = localStorage.getItem("active-tab") + if (cached) { + let parsed = JSON.parse(cached) + let tab = document.querySelector('div[tabs-section] > button[data-togglable="' + parsed + '"]') + if(tab) { + tab.click() + } + } } function showCorrespondingTabBody(element){ @@ -37,8 +45,6 @@ function filterButtonHandler(event) { unfilterSourceset(sourceset) } } - refreshFilterButtons(); - refreshPlatformTabs() } function initializeFiltering() { @@ -49,38 +55,58 @@ function initializeFiltering() { 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") - } - }) + let cached = window.localStorage.getItem('inactive-filters') + if (cached) { + let parsed = JSON.parse(cached) + filteringContext.activeFilters = filteringContext.restrictedDependencies + .filter(q => parsed.indexOf(q) == -1 ) + } else { + filteringContext.activeFilters = filteringContext.restrictedDependencies + } + refreshFiltering() } function filterSourceset(sourceset) { filteringContext.activeFilters = filteringContext.activeFilters.filter(p => p != sourceset) refreshFiltering() + addSourcesetFilterToCache(sourceset) } function unfilterSourceset(sourceset) { if(filteringContext.activeFilters.length == 0) { filteringContext.activeFilters = filteringContext.dependencies[sourceset].concat([sourceset]) refreshFiltering() + filteringContext.dependencies[sourceset].concat([sourceset]).forEach(p => removeSourcesetFilterFromCache(p)) } else { filteringContext.activeFilters.push(sourceset) refreshFiltering() + removeSourcesetFilterFromCache(sourceset) + } + +} + +function addSourcesetFilterToCache(sourceset) { + let cached = localStorage.getItem('inactive-filters') + if (cached) { + let parsed = JSON.parse(cached) + localStorage.setItem('inactive-filters', JSON.stringify(parsed.concat([sourceset]))) + } else { + localStorage.setItem('inactive-filters', JSON.stringify([sourceset])) + } +} + +function removeSourcesetFilterFromCache(sourceset) { + let cached = localStorage.getItem('inactive-filters') + if (cached) { + let parsed = JSON.parse(cached) + localStorage.setItem('inactive-filters', JSON.stringify(parsed.filter(p => p != sourceset))) } } function toggleSections(evt){ if(!evt.target.getAttribute("data-togglable")) return + localStorage.setItem('active-tab', JSON.stringify(evt.target.getAttribute("data-togglable"))) const activateTabs = (containerClass) => { for(const element of document.getElementsByClassName(containerClass)){ @@ -131,6 +157,8 @@ function refreshFiltering() { elem.setAttribute("data-filterable-current", platformList.join(' ')) } ) + refreshFilterButtons() + refreshPlatformTabs() } function refreshPlatformTabs() { @@ -150,9 +178,21 @@ function refreshPlatformTabs() { } } ) - if( active == false && firstAvailable !== null ) { + if( active == false && firstAvailable) { firstAvailable.click() } } ) } + +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") + } + }) +} + -- cgit From 902b670bc764a6db4f49f96d08f2115dd08bdf9b Mon Sep 17 00:00:00 2001 From: Filip Zybała Date: Thu, 4 Jun 2020 09:05:38 +0200 Subject: Changed anchors handling to work properly with tabs --- .../src/main/kotlin/renderers/html/HtmlRenderer.kt | 2 +- .../dokka/scripts/platformContentHandler.js | 43 +++++++++++++++++----- 2 files changed, 35 insertions(+), 10 deletions(-) (limited to 'plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js') diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index 76a52a83..7ebcf00e 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -400,7 +400,7 @@ open class HtmlRenderer( private fun FlowContent.withAnchor(anchorName: String?, content: FlowContent.() -> Unit) { a { - anchorName?.let { attributes["name"] = it } + anchorName?.let { attributes["data-name"] = it } } content() } diff --git a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js b/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js index 3ff74ad5..e295d90b 100644 --- a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js +++ b/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js @@ -7,24 +7,47 @@ window.addEventListener('load', () => { 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) => toggleSectionsEventHandler(event))) document.getElementById('filter-section').addEventListener('click', (event) => filterButtonHandler(event)) initializeFiltering() initTabs() + handleAnchor() }) +function handleAnchor() { + let searchForTab = function(element) { + if(element && element.hasAttribute) { + if(element.hasAttribute("data-togglable")) return element; + else return searchForTab(element.parentNode) + } else return null + } + let anchor = window.location.hash + if (anchor != "") { + anchor = anchor.substring(1) + let element = document.querySelector('a[data-name="' + anchor+'"]') + if (element) { + let tab = searchForTab(element) + if (tab) { + let found = document.querySelector('.tabs-section > .section-tab[data-togglable="' + tab.getAttribute("data-togglable") + '"]') + toggleSections(tab) + element.scrollIntoView({behavior: "smooth"}) + } + } + } +} + function initTabs(){ document.querySelectorAll("div[tabs-section]") .forEach(element => { showCorrespondingTabBody(element) - element.addEventListener('click', (event) => toggleSections(event)) + element.addEventListener('click', (event) => toggleSectionsEventHandler(event)) }) let cached = localStorage.getItem("active-tab") if (cached) { let parsed = JSON.parse(cached) let tab = document.querySelector('div[tabs-section] > button[data-togglable="' + parsed + '"]') if(tab) { - tab.click() + toggleSections(tab) } } } @@ -103,15 +126,12 @@ function removeSourcesetFilterFromCache(sourceset) { } } - -function toggleSections(evt){ - if(!evt.target.getAttribute("data-togglable")) return - localStorage.setItem('active-tab', JSON.stringify(evt.target.getAttribute("data-togglable"))) - +function toggleSections(target) { + localStorage.setItem('active-tab', JSON.stringify(target.getAttribute("data-togglable"))) const activateTabs = (containerClass) => { for(const element of document.getElementsByClassName(containerClass)){ for(const child of element.children){ - if(child.getAttribute("data-togglable") === evt.target.getAttribute("data-togglable")){ + if(child.getAttribute("data-togglable") === target.getAttribute("data-togglable")){ child.setAttribute("data-active", "") } else { child.removeAttribute("data-active") @@ -124,6 +144,11 @@ function toggleSections(evt){ activateTabs("tabs-section-body") } +function toggleSectionsEventHandler(evt){ + if(!evt.target.getAttribute("data-togglable")) return + toggleSections(evt.target) +} + function togglePlatformDependent(e, container) { let target = e.target if (target.tagName != 'BUTTON') return; -- cgit From b8c11e696e91807ef615a0f76b5bc0199415e544 Mon Sep 17 00:00:00 2001 From: Andrzej Ratajczak Date: Mon, 13 Jul 2020 13:47:19 +0200 Subject: Single platform bubbles fix --- .../src/main/kotlin/renderers/html/HtmlRenderer.kt | 54 ++++++++++++---------- .../dokka/scripts/platformContentHandler.js | 7 ++- .../test/kotlin/renderers/html/DivergentTest.kt | 22 --------- .../renderers/html/HtmlRenderingOnlyTestBase.kt | 28 ++++++++++- 4 files changed, 62 insertions(+), 49 deletions(-) (limited to 'plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js') diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index dc211502..f1ff9673 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -28,6 +28,10 @@ open class HtmlRenderer( sourceSet to context.configuration.sourceSets.filter { sourceSet.dependentSourceSets.contains(it.sourceSetID) } }.toMap() + private val isMultiplatform by lazy { + sourceSetDependencyMap.size > 1 + } + private val pageList = mutableMapOf>() override val preprocessors = context.plugin().query { htmlPreprocessors } @@ -99,19 +103,21 @@ open class HtmlRenderer( } 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.sourceSetID.toString() - when (it.analysisPlatform.key) { - "common" -> classes = classes + "common-like" - "native" -> classes = classes + "native-like" - "jvm" -> classes = classes + "jvm-like" - "js" -> classes = classes + "js-like" + if (isMultiplatform) { + div(classes = "filter-section") { + id = "filter-section" + group.sourceSets.forEach { + button(classes = "platform-tag platform-selector") { + attributes["data-active"] = "" + attributes["data-filter"] = it.sourceSetID.toString() + when (it.analysisPlatform.key) { + "common" -> classes = classes + "common-like" + "native" -> classes = classes + "native-like" + "jvm" -> classes = classes + "jvm-like" + "js" -> classes = classes + "js-like" + } + text(it.displayName) } - text(it.displayName) } } } @@ -182,9 +188,7 @@ open class HtmlRenderer( attributes["data-filterable-set"] = pair.first.sourceSetID.toString() if (index == 0) attributes["data-active"] = "" attributes["data-toggle"] = pair.first.sourceSetID.toString() - when ( - pair.first.analysisPlatform.key - ) { + when (pair.first.analysisPlatform.key) { "common" -> classes = classes + "common-like" "native" -> classes = classes + "native-like" "jvm" -> classes = classes + "jvm-like" @@ -400,16 +404,18 @@ open class HtmlRenderer( } private fun FlowContent.createPlatformTagBubbles(sourceSets: List) { - div("platform-tags") { - sourceSets.forEach { - div("platform-tag") { - when (it.analysisPlatform.key) { - "common" -> classes = classes + "common-like" - "native" -> classes = classes + "native-like" - "jvm" -> classes = classes + "jvm-like" - "js" -> classes = classes + "js-like" + if (isMultiplatform) { + div("platform-tags") { + sourceSets.forEach { + div("platform-tag") { + when (it.analysisPlatform.key) { + "common" -> classes = classes + "common-like" + "native" -> classes = classes + "native-like" + "jvm" -> classes = classes + "jvm-like" + "js" -> classes = classes + "js-like" + } + text(it.displayName) } - text(it.displayName) } } } diff --git a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js b/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js index e295d90b..6f10b08a 100644 --- a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js +++ b/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js @@ -8,8 +8,11 @@ window.addEventListener('load', () => { .forEach(elem => elem.addEventListener('click', (event) => togglePlatformDependent(event,elem))) document.querySelectorAll("div[tabs-section]") .forEach(elem => elem.addEventListener('click', (event) => toggleSectionsEventHandler(event))) - document.getElementById('filter-section').addEventListener('click', (event) => filterButtonHandler(event)) - initializeFiltering() + const filterSection = document.getElementById('filter-section') + if (filterSection) { + filterSection.addEventListener('click', (event) => filterButtonHandler(event)) + initializeFiltering() + } initTabs() handleAnchor() }) diff --git a/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt b/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt index 54d55721..734bea1d 100644 --- a/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt +++ b/plugins/base/src/test/kotlin/renderers/html/DivergentTest.kt @@ -12,28 +12,6 @@ import utils.Span import utils.match class DivergentTest : HtmlRenderingOnlyTestBase() { - private val js = defaultSourceSet.copy( - "root", - "JS", - defaultSourceSet.sourceSetID.copy(sourceSetName = "js"), - analysisPlatform = Platform.js, - sourceRoots = listOf(SourceRootImpl("pl1")) - ) - private val jvm = defaultSourceSet.copy( - "root", - "JVM", - defaultSourceSet.sourceSetID.copy(sourceSetName = "jvm"), - - analysisPlatform = Platform.jvm, - sourceRoots = listOf(SourceRootImpl("pl1")) - ) - private val native = defaultSourceSet.copy( - "root", - "NATIVE", - defaultSourceSet.sourceSetID.copy(sourceSetName = "native"), - analysisPlatform = Platform.native, - sourceRoots = listOf(SourceRootImpl("pl1")) - ) @Test fun simpleWrappingCase() { diff --git a/plugins/base/src/test/kotlin/renderers/html/HtmlRenderingOnlyTestBase.kt b/plugins/base/src/test/kotlin/renderers/html/HtmlRenderingOnlyTestBase.kt index d533988d..b6765fda 100644 --- a/plugins/base/src/test/kotlin/renderers/html/HtmlRenderingOnlyTestBase.kt +++ b/plugins/base/src/test/kotlin/renderers/html/HtmlRenderingOnlyTestBase.kt @@ -1,6 +1,8 @@ package renderers.html import org.jetbrains.dokka.DokkaConfigurationImpl +import org.jetbrains.dokka.Platform +import org.jetbrains.dokka.SourceRootImpl import org.jetbrains.dokka.base.DokkaBase import org.jetbrains.dokka.base.renderers.DefaultTabSortingStrategy import org.jetbrains.dokka.base.renderers.RootCreator @@ -14,9 +16,33 @@ import org.jsoup.nodes.Node import org.jsoup.nodes.TextNode import renderers.RenderingOnlyTestBase import utils.TestOutputWriter +import renderers.defaultSourceSet abstract class HtmlRenderingOnlyTestBase : RenderingOnlyTestBase() { + protected val js = defaultSourceSet.copy( + "root", + "JS", + defaultSourceSet.sourceSetID.copy(sourceSetName = "js"), + analysisPlatform = Platform.js, + sourceRoots = listOf(SourceRootImpl("pl1")) + ) + protected val jvm = defaultSourceSet.copy( + "root", + "JVM", + defaultSourceSet.sourceSetID.copy(sourceSetName = "jvm"), + + analysisPlatform = Platform.jvm, + sourceRoots = listOf(SourceRootImpl("pl1")) + ) + protected val native = defaultSourceSet.copy( + "root", + "NATIVE", + defaultSourceSet.sourceSetID.copy(sourceSetName = "native"), + analysisPlatform = Platform.native, + sourceRoots = listOf(SourceRootImpl("pl1")) + ) + val files = TestOutputWriter() override val context = MockContext( DokkaBase().outputWriter to { _ -> files }, @@ -26,7 +52,7 @@ abstract class HtmlRenderingOnlyTestBase : RenderingOnlyTestBase() { DokkaBase().externalLocationProviderFactory to { ::DokkaExternalLocationProviderFactory }, DokkaBase().tabSortingStrategy to { DefaultTabSortingStrategy() }, testConfiguration = DokkaConfigurationImpl( - "", null, false, emptyList(), emptyList(), emptyMap(), emptyList(), false + "", null, false, listOf(js, jvm, native), emptyList(), emptyMap(), emptyList(), false ) ) -- cgit