diff options
Diffstat (limited to 'src/main/kotlin/pl/treksoft/kvision')
8 files changed, 125 insertions, 11 deletions
diff --git a/src/main/kotlin/pl/treksoft/kvision/Main.kt b/src/main/kotlin/pl/treksoft/kvision/Main.kt index 385d23e8..e4816888 100644 --- a/src/main/kotlin/pl/treksoft/kvision/Main.kt +++ b/src/main/kotlin/pl/treksoft/kvision/Main.kt @@ -1,5 +1,6 @@ package pl.treksoft.kvision +import pl.treksoft.kvision.core.KVManager import kotlin.browser.document fun main(args: Array<String>) { @@ -10,6 +11,7 @@ fun main(args: Array<String>) { hot.dispose { data -> data.appState = application?.dispose() + KVManager.shutdown() application = null } @@ -19,6 +21,7 @@ fun main(args: Array<String>) { if (document.body != null) { application = start(state) } else { + KVManager.init() application = null document.addEventListener("DOMContentLoaded", { application = start(state) }) } diff --git a/src/main/kotlin/pl/treksoft/kvision/Showcase.kt b/src/main/kotlin/pl/treksoft/kvision/Showcase.kt index b2e6d764..6275fe88 100644 --- a/src/main/kotlin/pl/treksoft/kvision/Showcase.kt +++ b/src/main/kotlin/pl/treksoft/kvision/Showcase.kt @@ -3,7 +3,6 @@ package pl.treksoft.kvision import pl.treksoft.kvision.basic.Label import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.Img -import pl.treksoft.kvision.core.KVManager import pl.treksoft.kvision.core.Root import pl.treksoft.kvision.dropdown.DD.* import pl.treksoft.kvision.dropdown.DropDown @@ -32,11 +31,21 @@ class Showcase : ApplicationBase() { val dd = DropDown("Dropdown", listOf("abc" to "#!/x", "def" to "#!/y"), "flag") root.add(dd) + dd.setEventListener<Button> { + showBsDropdown = { e -> println("show" + (e.detail)?.text) } + shownBsDropdown = { e -> println("shown" + e.detail) } + hideBsDropdown = { e -> println("hide" + e.detail) } + hiddenBsDropdown = { e -> println("hidden" + e.detail) } + } val dd2 = DropDown("Dropdown2", listOf("abc" to "#!/abc", "def" to "#!/def", "xyz" to DISABLED.POS, "Header" to HEADER.POS, "Separtatorek" to SEPARATOR.POS ), "flag", dropup = true) root.add(dd2) + dd2.setEventListener<Button> { + hideBsDropdown = { e -> println("hide" + e.detail) } + hiddenBsDropdown = { e -> println("hidden" + e.detail) } + } val p = Tag(TAG.P, "To jest prawo", align = ALIGN.RIGHT) p.title = "Tytuł" @@ -65,6 +74,7 @@ class Showcase : ApplicationBase() { val button2 = Button("To jest przycisk", "flag", BUTTONSTYLE.DANGER) button2.setEventListener { click = { e -> + dd.hide() println("2" + e) button.setEventListener { click = null @@ -75,6 +85,7 @@ class Showcase : ApplicationBase() { val button3 = Button("To jest przycisk IMG", image = Img("kotlin.png")) button3.setEventListener { click = { e -> + dd.show() println("3" + e) button.setEventListener<Button> { click = { _ -> println(self.text) } @@ -90,6 +101,8 @@ class Showcase : ApplicationBase() { .on("/test", { -> println("test") }) .resolve() +// jQuery(document).off(".data-api") + // routing.on(RegExp("/abc/def/(.*)/(.*)/(.*)"), { x,y,z,u,v -> println(x) }) // router.on("/test", { -> println("test") }) @@ -113,7 +126,6 @@ class Showcase : ApplicationBase() { } override fun dispose(): Map<String, Any> { - KVManager.shutdown() return mapOf<String, Any>() } } diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Container.kt b/src/main/kotlin/pl/treksoft/kvision/core/Container.kt index e8d277dc..028c55ce 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Container.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Container.kt @@ -35,4 +35,5 @@ open class Container(classes: Set<String> = setOf()) : Widget(classes) { children.removeAt(index).clearParent() refresh() } + } diff --git a/src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt b/src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt index ab95a162..1d937511 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/KVManager.kt @@ -8,6 +8,7 @@ import com.github.snabbdom.datasetModule import com.github.snabbdom.eventListenersModule import com.github.snabbdom.propsModule import com.github.snabbdom.styleModule +import pl.treksoft.jquery.jQuery import pl.treksoft.kvision.require import pl.treksoft.kvision.routing.routing import kotlin.browser.document @@ -36,6 +37,10 @@ object KVManager { return sdVirtualize(html) } + fun init() { + jQuery(document).off(".data-api") + } + fun shutdown() { routing.destroy() } diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Root.kt b/src/main/kotlin/pl/treksoft/kvision/core/Root.kt index bea4db5e..c5f4a2d6 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Root.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Root.kt @@ -4,10 +4,10 @@ import com.github.snabbdom.VNode import pl.treksoft.kvision.snabbdom.StringBoolPair class Root(id: String, private val fluid: Boolean = false) : Container() { - private var vnode: VNode = render() + private var rootVnode: VNode = render() init { - vnode = KVManager.patch(id, this.render()) + rootVnode = KVManager.patch(id, this.render()) this.id = id } @@ -21,7 +21,7 @@ class Root(id: String, private val fluid: Boolean = false) : Container() { } override fun refresh() { - vnode = KVManager.patch(vnode, render()) + rootVnode = KVManager.patch(rootVnode, render()) } } diff --git a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt index a1405135..142c3069 100644 --- a/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt +++ b/src/main/kotlin/pl/treksoft/kvision/core/Widget.kt @@ -3,10 +3,14 @@ package pl.treksoft.kvision.core import com.github.snabbdom.VNode import com.github.snabbdom.VNodeData import com.github.snabbdom.h -import pl.treksoft.kvision.snabbdom.on +import org.w3c.dom.Node +import pl.treksoft.jquery.JQuery +import pl.treksoft.jquery.jQuery import pl.treksoft.kvision.snabbdom.SnOn import pl.treksoft.kvision.snabbdom.StringBoolPair import pl.treksoft.kvision.snabbdom.StringPair +import pl.treksoft.kvision.snabbdom.hooks +import pl.treksoft.kvision.snabbdom.on import pl.treksoft.kvision.snabbdom.snAttrs import pl.treksoft.kvision.snabbdom.snClasses import pl.treksoft.kvision.snabbdom.snOpt @@ -42,6 +46,8 @@ open class Widget(classes: Set<String> = setOf()) : KVObject { refresh() } + private var vnode: VNode? = null + internal open fun render(): VNode { return kvh("div") } @@ -60,6 +66,7 @@ open class Widget(classes: Set<String> = setOf()) : KVObject { style = snStyle(getSnStyle()) `class` = snClasses(getSnClass()) on = getSnOn() + hook = getSnHooks() } } @@ -86,10 +93,29 @@ open class Widget(classes: Set<String> = setOf()) : KVObject { return snattrs } - protected open fun getSnOn(): com.github.snabbdom.On { - val handlers = on(this) - listeners.forEach { on -> (handlers::apply)(on) } - return handlers + protected open fun getSnOn(): com.github.snabbdom.On? { + if (listeners.size > 0) { + val handlers = on(this) + listeners.forEach { l -> (handlers::apply)(l) } + return handlers + } else { + return null + } + } + + protected open fun getSnHooks(): com.github.snabbdom.Hooks? { + val hooks = hooks() + hooks.apply { + insert = { v -> + vnode = v + afterInsert(v) + } + postpatch = { ov, v -> + vnode = v + if (ov.elm !== v.elm) afterInsert(v) + } + } + return hooks } @Suppress("UNCHECKED_CAST") @@ -126,6 +152,18 @@ open class Widget(classes: Set<String> = setOf()) : KVObject { refresh() } + open fun getElement(): Node? { + return this.vnode?.elm + } + + open fun getElementJQuery(): JQuery? { + return getElement()?.let { jQuery(it) } + } + + open fun getElementJQueryD(): dynamic { + return getElement()?.let { jQuery(it).asDynamic() } + } + internal fun clearParent() { this.parent = null } @@ -133,4 +171,7 @@ open class Widget(classes: Set<String> = setOf()) : KVObject { protected open fun refresh() { this.parent?.refresh() } + + protected open fun afterInsert(node: VNode) { + } } diff --git a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt b/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt index 18946b27..d33b53d9 100644 --- a/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt +++ b/src/main/kotlin/pl/treksoft/kvision/dropdown/DropDown.kt @@ -1,5 +1,7 @@ package pl.treksoft.kvision.dropdown +import com.github.snabbdom.VNode +import org.w3c.dom.CustomEvent import pl.treksoft.kvision.core.Container import pl.treksoft.kvision.core.ResString import pl.treksoft.kvision.html.BUTTONSIZE @@ -11,6 +13,7 @@ import pl.treksoft.kvision.html.ListTag import pl.treksoft.kvision.html.TAG import pl.treksoft.kvision.html.Tag import pl.treksoft.kvision.snabbdom.StringPair +import pl.treksoft.kvision.snabbdom.obj enum class DD(val POS: String) { HEADER("DD#HEADER"), @@ -45,6 +48,12 @@ open class DropDown(text: String, elements: List<StringPair>, icon: String? = nu else -> Link(it.first, it.second) } } + button.setEventListener { + click = { + list.getElementJQueryD().dropdown("toggle") + } + } + list.addAll(children) this.add(button) this.add(list) @@ -54,6 +63,29 @@ open class DropDown(text: String, elements: List<StringPair>, icon: String? = nu companion object { var counter = 0 } + + override fun afterInsert(node: VNode) { + this.getElementJQuery()?.on("show.bs.dropdown", { e, _ -> + val event = CustomEvent("showBsDropdown", obj({ detail = button })) + this.getElement()?.dispatchEvent(event) as Any + }) + this.getElementJQuery()?.on("shown.bs.dropdown", { e, _ -> + val event = CustomEvent("shownBsDropdown", obj({ detail = button })) + this.getElement()?.dispatchEvent(event) as Any + }) + this.getElementJQuery()?.on("hide.bs.dropdown", { e, _ -> + val event = CustomEvent("hideBsDropdown", obj({ detail = button })) + this.getElement()?.dispatchEvent(event) as Any + }) + this.getElementJQuery()?.on("hidden.bs.dropdown", { e, _ -> + val event = CustomEvent("hiddenBsDropdown", obj({ detail = button })) + this.getElement()?.dispatchEvent(event) as Any + }) + } + + open fun toggle() { + list.getElementJQueryD().dropdown("toggle") + } } open class DropDownButton(id: String, text: String, icon: String? = null, style: BUTTONSTYLE = BUTTONSTYLE.DEFAULT, diff --git a/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt b/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt index 3bf68003..8a292910 100644 --- a/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt +++ b/src/main/kotlin/pl/treksoft/kvision/snabbdom/Types.kt @@ -2,11 +2,15 @@ package pl.treksoft.kvision.snabbdom import com.github.snabbdom.Attrs import com.github.snabbdom.Classes +import com.github.snabbdom.Hooks import com.github.snabbdom.On import com.github.snabbdom.Props import com.github.snabbdom.VNodeData import com.github.snabbdom.VNodeStyle +import org.w3c.dom.CustomEvent +import org.w3c.dom.CustomEventInit import pl.treksoft.kvision.core.Widget +import pl.treksoft.kvision.html.Button external class Object @@ -17,7 +21,18 @@ fun obj(init: dynamic.() -> Unit): dynamic { @Suppress("UnsafeCastFromDynamic") private fun vNodeData(): VNodeData = js("({})") -interface SnOn<T> : On { +class DropDownEvent(type: String, eventInitDict: CustomEventInit) : CustomEvent(type, eventInitDict) { + override val detail: Button? = null +} + +interface BtOn : On { + var showBsDropdown: ((DropDownEvent) -> kotlin.Unit)? + var shownBsDropdown: ((DropDownEvent) -> kotlin.Unit)? + var hideBsDropdown: ((DropDownEvent) -> kotlin.Unit)? + var hiddenBsDropdown: ((DropDownEvent) -> kotlin.Unit)? +} + +interface SnOn<T> : BtOn { var self: T } @@ -30,6 +45,11 @@ internal fun on(widget: Widget): SnOn<Widget> { return obj } +@Suppress("UnsafeCastFromDynamic") +internal fun hooks(): Hooks { + return js("({})") +} + typealias StringPair = Pair<String, String> typealias StringBoolPair = Pair<String, Boolean> |