aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/core/Style.kt14
-rw-r--r--src/main/kotlin/pl/treksoft/kvision/panel/Root.kt39
-rw-r--r--src/test/kotlin/test/pl/treksoft/kvision/core/StyleSpec.kt13
3 files changed, 35 insertions, 31 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Style.kt b/src/main/kotlin/pl/treksoft/kvision/core/Style.kt
index c2858fa0..62154f77 100644
--- a/src/main/kotlin/pl/treksoft/kvision/core/Style.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/core/Style.kt
@@ -40,7 +40,7 @@ import pl.treksoft.kvision.panel.Root
open class Style(className: String? = null, parentStyle: Style? = null, init: (Style.() -> Unit)? = null) :
StyledComponent() {
- override var parent: Container? = null
+ override var parent: Container? = Root.getFirstRoot()
private val newClassName: String = if (parentStyle == null) {
className ?: "kv_styleclass_${counter++}"
@@ -54,15 +54,7 @@ open class Style(className: String? = null, parentStyle: Style? = null, init: (S
var className: String by refreshOnUpdate(newClassName)
init {
- val root = Root.getLastRoot()
- @Suppress("LeakingThis")
- parent = root
- if (root != null) {
- @Suppress("LeakingThis")
- root.addStyle(this)
- } else {
- println("At least one Root object is required to create a style object!")
- }
+ styles.add(this)
@Suppress("LeakingThis")
init?.invoke(this)
}
@@ -141,10 +133,12 @@ open class Style(className: String? = null, parentStyle: Style? = null, init: (S
}
override fun dispose() {
+ styles.remove(this)
}
companion object {
internal var counter = 0
+ internal var styles = mutableListOf<Style>()
/**
* DSL builder extension function.
diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt
index 1a90f7fc..16d3a0f8 100644
--- a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt
@@ -46,17 +46,21 @@ import pl.treksoft.kvision.utils.snOpt
*/
@Suppress("TooManyFunctions")
class Root(id: String, private val fixed: Boolean = false, init: (Root.() -> Unit)? = null) : SimplePanel() {
- private val styles: MutableList<Style> = mutableListOf()
private val modals: MutableList<Modal> = mutableListOf()
private val contextMenus: MutableList<ContextMenu> = mutableListOf()
private var rootVnode: VNode = renderVNode()
internal var renderDisabled = false
+ private val isFirstRoot = roots.isEmpty()
+
init {
rootVnode = KVManager.patch(id, this.renderVNode())
this.id = id
roots.add(this)
+ if (isFirstRoot) {
+ Style.styles.forEach { it.parent = this }
+ }
@Suppress("LeakingThis")
init?.invoke(this)
}
@@ -71,12 +75,6 @@ class Root(id: String, private val fixed: Boolean = false, init: (Root.() -> Uni
}
}
- internal fun addStyle(style: Style) {
- styles.add(style)
- style.parent = this
- refresh()
- }
-
internal fun addModal(modal: Modal) {
modals.add(modal)
modal.parent = this
@@ -96,10 +94,14 @@ class Root(id: String, private val fixed: Boolean = false, init: (Root.() -> Uni
}
private fun stylesVNodes(): Array<VNode> {
- val visibleStyles = styles.filter { it.visible }
- return if (visibleStyles.isNotEmpty()) {
- val stylesDesc = visibleStyles.joinToString("\n") { it.generateStyle() }
- arrayOf(h("style", arrayOf(stylesDesc)))
+ return if (isFirstRoot) {
+ val visibleStyles = Style.styles.filter { it.visible }
+ if (visibleStyles.isNotEmpty()) {
+ val stylesDesc = visibleStyles.joinToString("\n") { it.generateStyle() }
+ arrayOf(h("style", arrayOf(stylesDesc)))
+ } else {
+ arrayOf()
+ }
} else {
arrayOf()
}
@@ -135,18 +137,25 @@ class Root(id: String, private val fixed: Boolean = false, init: (Root.() -> Uni
}
override fun dispose() {
- styles.forEach { it.dispose() }
- modals.forEach { it.dispose() }
- contextMenus.forEach { it.dispose() }
super.dispose()
roots.remove(this)
+ if (isFirstRoot) {
+ Style.styles.clear()
+ }
}
companion object {
internal val roots: MutableList<Root> = mutableListOf()
+ internal fun getFirstRoot(): Root? {
+ return if (roots.isNotEmpty())
+ roots[0]
+ else
+ null
+ }
+
internal fun getLastRoot(): Root? {
- return if (roots.size > 0)
+ return if (roots.isNotEmpty())
roots[roots.size - 1]
else
null
diff --git a/src/test/kotlin/test/pl/treksoft/kvision/core/StyleSpec.kt b/src/test/kotlin/test/pl/treksoft/kvision/core/StyleSpec.kt
index 00eb027f..bfcf5208 100644
--- a/src/test/kotlin/test/pl/treksoft/kvision/core/StyleSpec.kt
+++ b/src/test/kotlin/test/pl/treksoft/kvision/core/StyleSpec.kt
@@ -24,6 +24,7 @@ package test.pl.treksoft.kvision.core
import pl.treksoft.kvision.core.Col
import pl.treksoft.kvision.core.Color
import pl.treksoft.kvision.core.Overflow
+import pl.treksoft.kvision.core.Style
import pl.treksoft.kvision.core.Style.Companion.style
import pl.treksoft.kvision.core.Widget.Companion.widget
import pl.treksoft.kvision.panel.Root
@@ -37,7 +38,7 @@ class StyleSpec : DomSpec {
@Test
fun render() {
run {
- val root = Root("test", true) {
+ Root("test", true) {
widget {
style {
margin = 2.px
@@ -46,20 +47,20 @@ class StyleSpec : DomSpec {
}
}
}
- root.reRender()
val element = document.getElementById("test")
assertEqualsHtml(
"<style>.kv_styleclass_0 {\noverflow: scroll;\nmargin: 2px;\ncolor: silver;\n}</style><div class=\"kv_styleclass_0\"></div>",
element?.innerHTML,
"Should render correct style element"
)
+ Style.styles.clear()
}
}
@Test
fun renderCustomClass() {
run {
- val root = Root("test", true) {
+ Root("test", true) {
widget {
style("customclass") {
margin = 2.px
@@ -68,20 +69,20 @@ class StyleSpec : DomSpec {
}
}
}
- root.reRender()
val element = document.getElementById("test")
assertEqualsHtml(
"<style>.customclass {\noverflow: scroll;\nmargin: 2px;\ncolor: silver;\n}</style><div class=\"customclass\"></div>",
element?.innerHTML,
"Should render correct style element with custom class name"
)
+ Style.styles.clear()
}
}
@Test
fun renderSubclass() {
run {
- val root = Root("test", true) {
+ Root("test", true) {
widget {
style("customclass") {
margin = 2.px
@@ -93,7 +94,6 @@ class StyleSpec : DomSpec {
}
}
}
- root.reRender()
val element = document.getElementById("test")
assertEqualsHtml(
"<style>.customclass {\noverflow: scroll;\nmargin: 2px;\ncolor: silver;\n}\n" +
@@ -104,6 +104,7 @@ class StyleSpec : DomSpec {
element?.innerHTML,
"Should render correct child style class name"
)
+ Style.styles.clear()
}
}
} \ No newline at end of file