From e87cef2dd69d4e8067b376a0419080971c06f9da Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Wed, 29 Mar 2017 14:52:32 -0500 Subject: [PATCH] wip --- .../kotlin/com/github/sanity/kweb/Kweb.kt | 2 +- .../kweb/browserConnection/OutboundChannel.kt | 26 +++++++++---- .../kweb/dev/hotswap/KwebHotswapPlugin.kt | 1 - .../github/sanity/kweb/dom/element/Element.kt | 7 +++- .../kweb/dom/element/creation/tags/other.kt | 6 +++ .../plugins/foundation/FoundationPlugin.kt | 5 ++- .../plugins/foundation/navigation/menu.kt | 39 ++++++++++++------- 7 files changed, 60 insertions(+), 26 deletions(-) diff --git a/src/main/kotlin/com/github/sanity/kweb/Kweb.kt b/src/main/kotlin/com/github/sanity/kweb/Kweb.kt index 94b9980f48..09439b1687 100644 --- a/src/main/kotlin/com/github/sanity/kweb/Kweb.kt +++ b/src/main/kotlin/com/github/sanity/kweb/Kweb.kt @@ -248,7 +248,7 @@ class Kweb(val port: Int, } private data class WSClientData(val id: String, @Volatile var outboundChannel: OutboundChannel, val handlers: MutableMap Unit> = HashMap(), val debugTokens: MutableMap = HashMap()) { - fun send(message: S2CWebsocketMessage) = async(CommonPool){ + fun send(message: S2CWebsocketMessage) { outboundChannel.send(gson.toJson(message)) } } diff --git a/src/main/kotlin/com/github/sanity/kweb/browserConnection/OutboundChannel.kt b/src/main/kotlin/com/github/sanity/kweb/browserConnection/OutboundChannel.kt index 09b440cf06..34fc1d6819 100644 --- a/src/main/kotlin/com/github/sanity/kweb/browserConnection/OutboundChannel.kt +++ b/src/main/kotlin/com/github/sanity/kweb/browserConnection/OutboundChannel.kt @@ -1,15 +1,18 @@ package com.github.sanity.kweb.browserConnection +import kotlinx.coroutines.experimental.runBlocking import org.jetbrains.ktor.websocket.Frame import org.jetbrains.ktor.websocket.WebSocket import java.util.concurrent.ConcurrentLinkedQueue sealed class OutboundChannel { - abstract suspend fun send(message: String) + abstract fun send(message: String) class WSChannel(private val channel: WebSocket) : OutboundChannel() { - override suspend fun send(message: String) { - channel.send(Frame.Text(message)) + override fun send(message: String) { + runBlocking { + channel.send(Frame.Text(message)) + } } } @@ -17,14 +20,21 @@ sealed class OutboundChannel { class TemporarilyStoringChannel() : OutboundChannel() { private @Volatile var queue: ConcurrentLinkedQueue? = ConcurrentLinkedQueue() - override suspend fun send(message: String) { - (queue ?: throw RuntimeException("Can't write to queue after it has been read")).add(message) + override fun send(message: String) { + queue.let { + it?.add(message) ?: throw RuntimeException("Can't write to queue after it has been read") + } } fun read(): List { - val r = (queue ?: throw RuntimeException("Queue can only be read once")).toList() - queue = null - return r + queue.let { + if (it == null) throw RuntimeException("Queue can only be read once") + else { + val r = it.toList() + queue = null + return r + } + } } fun queueSize() = queue?.size diff --git a/src/main/kotlin/com/github/sanity/kweb/dev/hotswap/KwebHotswapPlugin.kt b/src/main/kotlin/com/github/sanity/kweb/dev/hotswap/KwebHotswapPlugin.kt index 595b7685c4..43b74899dd 100644 --- a/src/main/kotlin/com/github/sanity/kweb/dev/hotswap/KwebHotswapPlugin.kt +++ b/src/main/kotlin/com/github/sanity/kweb/dev/hotswap/KwebHotswapPlugin.kt @@ -22,7 +22,6 @@ class KwebHotswapPlugin { @OnClassLoadEvent(classNameRegexp = ".*", events = arrayOf(LoadEvent.REDEFINE)) @JvmStatic fun onAnyReload() { - println("Reload detected") logger.debug { "Hotswap load event detected, calling listeners" } listeners.forEach { it.invoke() } } diff --git a/src/main/kotlin/com/github/sanity/kweb/dom/element/Element.kt b/src/main/kotlin/com/github/sanity/kweb/dom/element/Element.kt index 628c7b694c..b1c17b7d9d 100644 --- a/src/main/kotlin/com/github/sanity/kweb/dom/element/Element.kt +++ b/src/main/kotlin/com/github/sanity/kweb/dom/element/Element.kt @@ -58,6 +58,7 @@ open class Element (open val webBrowser: WebBrowser, open var jsExpression: Stri * * @receiver This will be the parent element of any elements created with the returned * [ElementCreator] + * @Param position What position among the parent's children should the new element have? * * @sample new_sample_1 */ @@ -66,10 +67,12 @@ fun T.new(position : Int? = null) = ElementCreator(this, position) /** * A convenience wrapper around [new] which allows a nested DSL-style syntax * +* @Param position What position among the parent's children should the new element have? + * * @sample new_sample_2 */ -fun T.new(receiver: ElementCreator.() -> Unit) : T { - receiver(new()) +fun T.new(position : Int? = null, receiver: ElementCreator.() -> Unit) : T { + receiver(new(position)) return this } diff --git a/src/main/kotlin/com/github/sanity/kweb/dom/element/creation/tags/other.kt b/src/main/kotlin/com/github/sanity/kweb/dom/element/creation/tags/other.kt index 64e758b055..f41d8dbd5a 100644 --- a/src/main/kotlin/com/github/sanity/kweb/dom/element/creation/tags/other.kt +++ b/src/main/kotlin/com/github/sanity/kweb/dom/element/creation/tags/other.kt @@ -47,3 +47,9 @@ fun ElementCreator.h1(attributes: Map = attr) = H1Element( open class PElement(parent: Element) : Element(parent) fun ElementCreator.p(attributes: Map = attr) = PElement(element("p", attributes)) + +open class NavElement(parent: Element) : Element(parent) +fun ElementCreator.nav(attributes: Map = attr) = NavElement(element("nav", attributes)) + +open class SectionElement(parent: Element) : Element(parent) +fun ElementCreator.section(attributes: Map = attr) = SectionElement(element("section", attributes)) \ No newline at end of file diff --git a/src/main/kotlin/com/github/sanity/kweb/plugins/foundation/FoundationPlugin.kt b/src/main/kotlin/com/github/sanity/kweb/plugins/foundation/FoundationPlugin.kt index f53813d1aa..113d49b8c6 100644 --- a/src/main/kotlin/com/github/sanity/kweb/plugins/foundation/FoundationPlugin.kt +++ b/src/main/kotlin/com/github/sanity/kweb/plugins/foundation/FoundationPlugin.kt @@ -3,6 +3,7 @@ package com.github.sanity.kweb.plugins.foundation import com.github.sanity.kweb.dom.element.Element import com.github.sanity.kweb.dom.element.creation.ElementCreator import com.github.sanity.kweb.plugins.KWebPlugin +import com.github.sanity.kweb.plugins.jqueryCore.jqueryCore /** * Created by ian on 3/24/17. @@ -10,11 +11,13 @@ import com.github.sanity.kweb.plugins.KWebPlugin val foundation = FoundationPlugin() -class FoundationPlugin : KWebPlugin() { +class FoundationPlugin : KWebPlugin(dependsOn = setOf(jqueryCore)) { override fun decorate(startHead: StringBuilder, endHead: StringBuilder) { endHead.appendln("""""") endHead.appendln("""""") } + + override fun executeAfterPageCreation() = "$(document).foundation();" } val ElementCreator.foundation : ElementCreator> get() { diff --git a/src/main/kotlin/com/github/sanity/kweb/plugins/foundation/navigation/menu.kt b/src/main/kotlin/com/github/sanity/kweb/plugins/foundation/navigation/menu.kt index ba42c8ac51..eb11f3d474 100644 --- a/src/main/kotlin/com/github/sanity/kweb/plugins/foundation/navigation/menu.kt +++ b/src/main/kotlin/com/github/sanity/kweb/plugins/foundation/navigation/menu.kt @@ -16,28 +16,41 @@ import com.github.sanity.kweb.plugins.foundation.foundation * Created by ian on 3/28/17. */ -open class FoundationTopBarElement(parent: DivElement) : FoundationElement(parent) -fun ElementCreator>.topBar(attributes: Map = attr) = FoundationTopBarElement(div(attributes.classes("top-bar"))) +open class FoundationTopBarElement(parent: NavElement) : NavElement(parent) +fun ElementCreator>.topBar(attributes: Map = attr) + = FoundationTopBarElement(nav(attributes + .classes("top-bar") + .set("data-topbar", true) + .set("role", "navigation"))) -open class FoundationTopBarLeftElement(parent: DivElement) : FoundationElement(parent) -fun ElementCreator>.topBarLeft(attributes: Map = attr) = FoundationTopBarLeftElement(div(attributes.classes("top-bar-left"))) +open class FoundationTitleAreaElement(parent: ULElement) : ULElement(parent) +fun ElementCreator.titleArea(attributes: Map = attr) = FoundationTitleAreaElement(ul(attributes.classes("title-area"))) + +open class FoundationNameElement(parent: LIElement) : LIElement(parent) +fun ElementCreator.name(attributes: Map = attr) = FoundationNameElement(this.li(attributes.classes("name"))) + +open class FoundationTopBarSectionElement(parent: Element) : Element(parent) +fun ElementCreator.topBarSection(attributes: Map = attr) + = FoundationTopBarSectionElement(section(attributes.classes("top-bar-section"))) + +open class FoundationLeftElement(parent: Element) : Element(parent) +fun ElementCreator.left(attributes: Map = attr) + = FoundationRightElement(ul(attributes.classes("left"))) + +open class FoundationRightElement(parent: Element) : Element(parent) +fun ElementCreator.right(attributes: Map = attr) + = FoundationRightElement(ul(attributes.classes("right"))) -open class FoundationMenuElement(parent: ULElement) : ULElement(parent) -fun ElementCreator>.menu(dropdown : Boolean? = null, attributes: Map = attr) - = FoundationMenuElement(ul(attributes.classes("menu").classes("dropdown", onlyIf = dropdown ?: false).set("data-drop-down", dropdown))) fun main(args: Array) { foundation_menu_sample() } private fun foundation_menu_sample() { - Kweb(port = 1234, plugins = listOf(foundation)) { + Kweb(port = 1234, plugins = listOf(foundation), refreshPageOnHotswap = true) { doc.body.new { - foundation.menu().new { - li().new().a(href = "#").text("Item 1") - li().new().a(href = "#").text("Item 2") - li().new().a(href = "#").text("Item 3") - li().new().a(href = "#").text("Item 4") + foundation.topBar().new { + titleArea().new().name().new().a(href="#").text("My Site") } } }