Skip to content
This repository has been archived by the owner on Aug 10, 2024. It is now read-only.

Commit

Permalink
bump to 0.2.0 for new routing/state code, still requires experimentat…
Browse files Browse the repository at this point in the history
…ion, fine tuning, and documentation
  • Loading branch information
sanity committed Apr 16, 2017
1 parent 8bfec6a commit f288c0d
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 13 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ plugins {
}

group 'io.kweb'
version '0.1.4'
version '0.2.0'

apply plugin: 'java'
apply plugin: 'kotlin'
Expand Down
59 changes: 49 additions & 10 deletions src/main/kotlin/io/kweb/routing/routing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,58 @@ package io.kweb.routing

import io.kweb.WebBrowser
import io.kweb.state.Observable
import io.mola.galimatias.URL
import java.net.URLDecoder


/**
* @sample route_sample
*
* Created by @@jmdesprez, some modifications by @sanity
*/

// TODO: Handle window.onpopstate so that handle
// TODO: Encode and decode should occur automatically using some kind of object serialization, also need to figure out
// TODO: humanization of titles
fun <T : Any> WebBrowser.router(fromPath : (String) -> T, toPath : (T) -> String, humanize : (T) -> String = {it.toString()}) : Observable<T> {
val decoded = fromPath(this.httpRequestInfo.requestedUrl.path())
val observable = Observable(decoded)
observable.addListener({ _, new ->
doc.body.execute("""window.history.pushState({}, "${humanize(new)}", "${toPath(new)}");""")
})
return observable
// TODO: Handle window.onpopstate so that back buttons will work in a sensible way

fun main(args: Array<String>) {
val url = URL.parse("http://a.b.c/hello?dog=cat&mouse=pig")
println(url)
}

val urlPathTranslator = UrlPathTranslator()

fun WebBrowser.pushState(path: String) {
execute("""history.pushState({}, "$path", "$path");""")
}

inline fun <reified T : Any> WebBrowser.route(receiver: (RequestURL<T>).() -> Unit) {
val requestUrl = with(httpRequestInfo.requestedUrl) {
this.query()
RequestURL<T>(scheme = Scheme.valueOf(scheme()), host = host().toHumanString(), port = port(), path = Observable(urlPathTranslator.parse(path())), query = Observable(query()), rawUrl = this)
}
requestUrl.path.addListener { _, new ->
pushState(urlPathTranslator.toPath(new) + requestUrl.query.value)
}
requestUrl.query.addListener { _, new ->
pushState(urlPathTranslator.toPath(requestUrl.path.value) + new)
}
receiver(requestUrl)
}

data class RequestURL<T : Any>(val scheme: Scheme, val host: String, val port: Int = 80, val path: Observable<T>, val query: Observable<String>, val rawUrl: URL) {
private fun queryToQueryMap(query: String): Map<String, String> {
val pairs = query.split("&".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()
val queryMap = HashMap<String, String>()
for (pair in pairs) {
val idx = pair.indexOf("=")
queryMap.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"))
}
return queryMap
}
}

enum class Scheme {
http, https
}

fun route_sample() {
}
17 changes: 15 additions & 2 deletions src/main/kotlin/io/kweb/state/state.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,21 @@ class Observable<T : Any?>(@Volatile private var state : T) {
val value get() = state

@Synchronized fun changeTo(newVal : T) {
listeners.values.forEach {it(state, newVal)}
state = newVal
if (newVal != state) {
listeners.values.forEach { it(state, newVal) }
state = newVal
}
}

fun <O> view(mapper : (T) -> O, unmapper : (T, O) -> T) : Observable<O> {
val oobs = Observable(mapper(value))
addListener { old, new ->
oobs.changeTo(mapper(new))
}
oobs.addListener({old, new ->
changeTo(unmapper(value, new))
})
return oobs
}
}

Expand Down

0 comments on commit f288c0d

Please sign in to comment.