From f9398d1ae7da496d3a290d7b225225d70a4bb174 Mon Sep 17 00:00:00 2001
From: Robert Jaros <rjaros@finn.pl>
Date: Mon, 3 Jun 2019 18:31:49 +0200
Subject: Refactor support for additional attributes from Tag up to the Widget
 class.

---
 .../kotlin/pl/treksoft/kvision/core/Component.kt   | 20 ++++++
 src/main/kotlin/pl/treksoft/kvision/core/Style.kt  | 78 +---------------------
 .../pl/treksoft/kvision/core/StyledComponent.kt    |  2 +-
 src/main/kotlin/pl/treksoft/kvision/core/Widget.kt | 22 +++++-
 src/main/kotlin/pl/treksoft/kvision/html/Tag.kt    | 43 +-----------
 .../kotlin/pl/treksoft/kvision/panel/FlexPanel.kt  |  6 +-
 src/main/kotlin/pl/treksoft/kvision/panel/Root.kt  |  6 +-
 7 files changed, 50 insertions(+), 127 deletions(-)

(limited to 'src/main/kotlin')

diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Component.kt b/src/main/kotlin/pl/treksoft/kvision/core/Component.kt
index 411eae8d..fe5569d4 100644
--- a/src/main/kotlin/pl/treksoft/kvision/core/Component.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/core/Component.kt
@@ -96,6 +96,26 @@ interface Component {
      */
     fun removeSurroundingCssClass(css: Style): Component
 
+    /**
+     * Returns the value of an additional attribute.
+     * @param name the name of the attribute
+     * @return the value of the attribute
+     */
+    fun getAttribute(name: String): String?
+
+    /**
+     * Sets the value of additional attribute.
+     * @param name the name of the attribute
+     * @param value the value of the attribute
+     */
+    fun setAttribute(name: String, value: String): Component
+
+    /**
+     * Removes the value of additional attribute.
+     * @param name the name of the attribute
+     */
+    fun removeAttribute(name: String): Component
+
     /**
      * @suppress
      * Internal function
diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Style.kt b/src/main/kotlin/pl/treksoft/kvision/core/Style.kt
index 282d2e7e..ff91c429 100644
--- a/src/main/kotlin/pl/treksoft/kvision/core/Style.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/core/Style.kt
@@ -21,11 +21,6 @@
  */
 package pl.treksoft.kvision.core
 
-import com.github.snabbdom.VNode
-import com.github.snabbdom.h
-import org.w3c.dom.Node
-import pl.treksoft.jquery.JQuery
-import pl.treksoft.kvision.panel.Root
 import kotlin.reflect.KProperty
 
 /**
@@ -41,8 +36,6 @@ open class Style(className: String? = null, parentStyle: Style? = null, init: (S
     StyledComponent() {
     private val propertyValues: MutableMap<String, Any?> = mutableMapOf()
 
-    override var parent: Container? = Root.getFirstRoot()
-
     private val newClassName: String = if (parentStyle == null) {
         className ?: "kv_styleclass_${counter++}"
     } else {
@@ -55,86 +48,19 @@ open class Style(className: String? = null, parentStyle: Style? = null, init: (S
     var className: String by refreshOnUpdate(newClassName)
 
     init {
+        @Suppress("LeakingThis")
         styles.add(this)
         @Suppress("LeakingThis")
         init?.invoke(this)
     }
 
-    override var visible: Boolean = true
-        set(value) {
-            val oldField = field
-            field = value
-            if (oldField != field) refresh()
-        }
-
-    override fun addCssClass(css: String): Component {
-        return this
-    }
-
-    override fun removeCssClass(css: String): Component {
-        return this
-    }
-
-    override fun addSurroundingCssClass(css: String): Component {
-        return this
-    }
-
-    override fun removeSurroundingCssClass(css: String): Component {
-        return this
-    }
-
-    override fun addCssClass(css: Style): Component {
-        return this
-    }
-
-    override fun removeCssClass(css: Style): Component {
-        return this
-    }
-
-    override fun addSurroundingCssClass(css: Style): Component {
-        return this
-    }
-
-    override fun removeSurroundingCssClass(css: Style): Component {
-        return this
-    }
-
-    override fun renderVNode(): VNode {
-        return h("style", arrayOf(generateStyle()))
-    }
-
     internal fun generateStyle(): String {
-        val styles = getSnStyle()
+        val styles = getSnStyleInternal()
         return ".$className {\n" + styles.joinToString("\n") {
             "${it.first}: ${it.second};"
         } + "\n}"
     }
 
-    override fun getElement(): Node? {
-        return null
-    }
-
-    override fun getElementJQuery(): JQuery? {
-        return null
-    }
-
-    override fun getElementJQueryD(): dynamic {
-        return null
-    }
-
-    override fun clearParent(): Component {
-        this.parent = null
-        return this
-    }
-
-    override fun getRoot(): Root? {
-        return this.parent?.getRoot()
-    }
-
-    override fun dispose() {
-        styles.remove(this)
-    }
-
     protected fun <T> refreshOnUpdate(refreshFunction: ((T) -> Unit) = { this.refresh() }) =
         RefreshDelegateProvider<T>(null, refreshFunction)
 
diff --git a/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt b/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt
index aa3f26bb..d9fa63fc 100644
--- a/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/core/StyledComponent.kt
@@ -29,7 +29,7 @@ import kotlin.reflect.KProperty
  * Base class for components supporting CSS styling.
  */
 @Suppress("LargeClass")
-abstract class StyledComponent : Component {
+abstract class StyledComponent {
     private val propertyValues: MutableMap<String, Any?> = mutableMapOf()
 
     /**
diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt
index 3388a011..fbcd89da 100644
--- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt
@@ -53,11 +53,12 @@ import kotlin.reflect.KProperty
  * @param classes Set of CSS class names
  */
 @Suppress("TooManyFunctions", "LargeClass")
-open class Widget(classes: Set<String> = setOf()) : StyledComponent() {
+open class Widget(classes: Set<String> = setOf()) : StyledComponent(), Component {
     private val propertyValues: MutableMap<String, Any?> = mutableMapOf()
 
     internal val classes = classes.toMutableSet()
     internal val surroundingClasses: MutableSet<String> = mutableSetOf()
+    internal val attributes: MutableMap<String, String> = mutableMapOf()
     internal val internalListeners = mutableListOf<SnOn<Widget>.() -> Unit>()
     internal val listeners = mutableListOf<SnOn<Widget>.() -> Unit>()
 
@@ -243,6 +244,9 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent() {
         if (draggable == true) {
             snattrs.add("draggable" to "true")
         }
+        if (attributes.isNotEmpty()) {
+            snattrs += attributes.toList()
+        }
         return snattrs
     }
 
@@ -565,6 +569,22 @@ open class Widget(classes: Set<String> = setOf()) : StyledComponent() {
         return removeSurroundingCssClass(css.className)
     }
 
+    override fun getAttribute(name: String): String? {
+        return this.attributes[name]
+    }
+
+    override fun setAttribute(name: String, value: String): Widget {
+        this.attributes[name] = value
+        refresh()
+        return this
+    }
+
+    override fun removeAttribute(name: String): Widget {
+        this.attributes.remove(name)
+        refresh()
+        return this
+    }
+
     override fun getElement(): Node? {
         return this.vnode?.elm
     }
diff --git a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt
index d9d839ba..81d6848b 100644
--- a/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/html/Tag.kt
@@ -25,8 +25,6 @@ import com.github.snabbdom.VNode
 import pl.treksoft.kvision.KVManager
 import pl.treksoft.kvision.core.Container
 import pl.treksoft.kvision.core.StringBoolPair
-import pl.treksoft.kvision.core.StringPair
-import pl.treksoft.kvision.core.Widget
 import pl.treksoft.kvision.i18n.I18n
 import pl.treksoft.kvision.panel.SimplePanel
 
@@ -115,8 +113,6 @@ open class Tag(
     init: (Tag.() -> Unit)? = null
 ) : SimplePanel(classes), Template {
 
-    protected val attributes = attributes.toMutableMap()
-
     /**
      * Tag type.
      */
@@ -148,6 +144,7 @@ open class Tag(
     override var templates: Map<String, (Any?) -> String> by refreshOnUpdate(mapOf())
 
     init {
+        this.attributes += attributes
         @Suppress("LeakingThis")
         init?.invoke(this)
     }
@@ -181,14 +178,6 @@ open class Tag(
         return cl
     }
 
-    override fun getSnAttrs(): List<StringPair> {
-        return if (attributes.isEmpty()) {
-            super.getSnAttrs()
-        } else {
-            attributes.toList() + super.getSnAttrs()
-        }
-    }
-
     operator fun String.unaryPlus() {
         if (content == null)
             content = this
@@ -196,36 +185,6 @@ open class Tag(
             content += translate(this)
     }
 
-    /**
-     * Returns the value of an additional attribute.
-     * @param name the name of the attribute
-     * @return the value of the attribute
-     */
-    fun getAttribute(name: String): String? {
-        return this.attributes[name]
-    }
-
-    /**
-     * Sets the value of additional attribute.
-     * @param name the name of the attribute
-     * @param value the value of the attribute
-     */
-    fun setAttribute(name: String, value: String): Widget {
-        this.attributes[name] = value
-        refresh()
-        return this
-    }
-
-    /**
-     * Removes the value of additional attribute.
-     * @param name the name of the attribute
-     */
-    fun removeAttribute(name: String): Widget {
-        this.attributes.remove(name)
-        refresh()
-        return this
-    }
-
     companion object {
         /**
          * DSL builder extension function.
diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt b/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt
index 310d4d49..010f7cba 100644
--- a/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/panel/FlexPanel.kt
@@ -24,7 +24,7 @@ package pl.treksoft.kvision.panel
 import pl.treksoft.kvision.core.Component
 import pl.treksoft.kvision.core.Container
 import pl.treksoft.kvision.core.StringPair
-import pl.treksoft.kvision.core.StyledComponent
+import pl.treksoft.kvision.core.Widget
 import pl.treksoft.kvision.core.WidgetWrapper
 import pl.treksoft.kvision.utils.px
 
@@ -152,10 +152,10 @@ open class FlexPanel(
     }
 
     private fun refreshSpacing() {
-        getChildren().filterIsInstance<StyledComponent>().map { applySpacing(it) }
+        getChildren().filterIsInstance<Widget>().map { applySpacing(it) }
     }
 
-    private fun applySpacing(wrapper: StyledComponent): StyledComponent {
+    private fun applySpacing(wrapper: Widget): Widget {
         wrapper.marginTop = null
         wrapper.marginRight = null
         wrapper.marginBottom = null
diff --git a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt
index dd3d39b6..2d9dcc46 100644
--- a/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt
+++ b/src/main/kotlin/pl/treksoft/kvision/panel/Root.kt
@@ -71,7 +71,6 @@ class Root(
         }
         roots.add(this)
         if (isFirstRoot) {
-            Style.styles.forEach { it.parent = this }
             Modal.modals.forEach { it.parent = this }
         }
         @Suppress("LeakingThis")
@@ -102,9 +101,8 @@ class Root(
 
     private fun stylesVNodes(): Array<VNode> {
         return if (isFirstRoot) {
-            val visibleStyles = Style.styles.filter { it.visible }
-            if (visibleStyles.isNotEmpty()) {
-                val stylesDesc = visibleStyles.joinToString("\n") { it.generateStyle() }
+            if (Style.styles.isNotEmpty()) {
+                val stylesDesc = Style.styles.joinToString("\n") { it.generateStyle() }
                 arrayOf(h("style", arrayOf(stylesDesc)))
             } else {
                 arrayOf()
-- 
cgit