Skip to content

Commit

Permalink
fixup! KTOR-7584 HTMX extension for Ktor
Browse files Browse the repository at this point in the history
  • Loading branch information
bjhham committed Feb 10, 2025
1 parent d0ba173 commit ffafe9c
Show file tree
Hide file tree
Showing 20 changed files with 387 additions and 190 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,49 +21,20 @@ public final class io/ktor/server/htmx/HXRequestHeaders {
public final synthetic fun unbox-impl ()Lio/ktor/http/Headers;
}

public final class io/ktor/server/htmx/HXResponseHeaders : io/ktor/server/htmx/StringMap {
public final class io/ktor/server/htmx/HXResponseHeaders : io/ktor/util/collections/StringMap {
public fun <init> (Lio/ktor/server/response/ResponseHeaders;)V
public fun get (Ljava/lang/String;)Ljava/lang/String;
public final fun getLocation ()Ljava/lang/String;
public final fun getPushUrl ()Ljava/lang/String;
public final fun getRedirect ()Ljava/lang/String;
public final fun getRefresh ()Ljava/lang/String;
public final fun getRefresh ()Ljava/lang/Boolean;
public final fun getReplaceUrl ()Ljava/lang/String;
public fun remove (Ljava/lang/String;)Ljava/lang/String;
public fun set (Ljava/lang/String;Ljava/lang/String;)V
public final fun setLocation (Ljava/lang/String;)V
public final fun setPushUrl (Ljava/lang/String;)V
public final fun setRedirect (Ljava/lang/String;)V
public final fun setRefresh (Ljava/lang/String;)V
}

public final class io/ktor/server/htmx/HXRoute : io/ktor/server/routing/Route {
public static final synthetic fun box-impl (Lio/ktor/server/routing/Route;)Lio/ktor/server/htmx/HXRoute;
public static fun constructor-impl (Lio/ktor/server/routing/Route;)Lio/ktor/server/routing/Route;
public fun createChild (Lio/ktor/server/routing/RouteSelector;)Lio/ktor/server/routing/Route;
public static fun createChild-impl (Lio/ktor/server/routing/Route;Lio/ktor/server/routing/RouteSelector;)Lio/ktor/server/routing/Route;
public fun equals (Ljava/lang/Object;)Z
public static fun equals-impl (Lio/ktor/server/routing/Route;Ljava/lang/Object;)Z
public static final fun equals-impl0 (Lio/ktor/server/routing/Route;Lio/ktor/server/routing/Route;)Z
public fun getAttributes ()Lio/ktor/util/Attributes;
public static fun getAttributes-impl (Lio/ktor/server/routing/Route;)Lio/ktor/util/Attributes;
public fun getEnvironment ()Lio/ktor/server/application/ApplicationEnvironment;
public static fun getEnvironment-impl (Lio/ktor/server/routing/Route;)Lio/ktor/server/application/ApplicationEnvironment;
public fun getParent ()Lio/ktor/server/routing/Route;
public static fun getParent-impl (Lio/ktor/server/routing/Route;)Lio/ktor/server/routing/Route;
public fun handle (Lkotlin/jvm/functions/Function2;)V
public static fun handle-impl (Lio/ktor/server/routing/Route;Lkotlin/jvm/functions/Function2;)V
public fun hashCode ()I
public static fun hashCode-impl (Lio/ktor/server/routing/Route;)I
public fun install (Lio/ktor/server/application/Plugin;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public static fun install-impl (Lio/ktor/server/routing/Route;Lio/ktor/server/application/Plugin;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public fun plugin (Lio/ktor/server/application/Plugin;)Ljava/lang/Object;
public static fun plugin-impl (Lio/ktor/server/routing/Route;Lio/ktor/server/application/Plugin;)Ljava/lang/Object;
public static final fun target-impl (Lio/ktor/server/routing/Route;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lio/ktor/server/routing/Route;
public fun toString ()Ljava/lang/String;
public static fun toString-impl (Lio/ktor/server/routing/Route;)Ljava/lang/String;
public static final fun trigger-impl (Lio/ktor/server/routing/Route;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lio/ktor/server/routing/Route;
public final synthetic fun unbox-impl ()Lio/ktor/server/routing/Route;
public final fun setRefresh (Ljava/lang/Boolean;)V
}

public final class io/ktor/server/htmx/HxAttributes : io/ktor/server/htmx/StringMapDelegate {
Expand Down Expand Up @@ -123,6 +94,34 @@ public final class io/ktor/server/htmx/HxHeadersKt {
public static final fun isHtmx (Lio/ktor/server/routing/RoutingRequest;)Z
}

public final class io/ktor/server/htmx/HxRoute : io/ktor/server/routing/Route {
public static final synthetic fun box-impl (Lio/ktor/server/routing/Route;)Lio/ktor/server/htmx/HxRoute;
public fun createChild (Lio/ktor/server/routing/RouteSelector;)Lio/ktor/server/routing/Route;
public static fun createChild-impl (Lio/ktor/server/routing/Route;Lio/ktor/server/routing/RouteSelector;)Lio/ktor/server/routing/Route;
public fun equals (Ljava/lang/Object;)Z
public static fun equals-impl (Lio/ktor/server/routing/Route;Ljava/lang/Object;)Z
public static final fun equals-impl0 (Lio/ktor/server/routing/Route;Lio/ktor/server/routing/Route;)Z
public fun getAttributes ()Lio/ktor/util/Attributes;
public static fun getAttributes-impl (Lio/ktor/server/routing/Route;)Lio/ktor/util/Attributes;
public fun getEnvironment ()Lio/ktor/server/application/ApplicationEnvironment;
public static fun getEnvironment-impl (Lio/ktor/server/routing/Route;)Lio/ktor/server/application/ApplicationEnvironment;
public fun getParent ()Lio/ktor/server/routing/Route;
public static fun getParent-impl (Lio/ktor/server/routing/Route;)Lio/ktor/server/routing/Route;
public fun handle (Lkotlin/jvm/functions/Function2;)V
public static fun handle-impl (Lio/ktor/server/routing/Route;Lkotlin/jvm/functions/Function2;)V
public fun hashCode ()I
public static fun hashCode-impl (Lio/ktor/server/routing/Route;)I
public fun install (Lio/ktor/server/application/Plugin;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public static fun install-impl (Lio/ktor/server/routing/Route;Lio/ktor/server/application/Plugin;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public fun plugin (Lio/ktor/server/application/Plugin;)Ljava/lang/Object;
public static fun plugin-impl (Lio/ktor/server/routing/Route;Lio/ktor/server/application/Plugin;)Ljava/lang/Object;
public static final fun target-impl (Lio/ktor/server/routing/Route;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lio/ktor/server/routing/Route;
public fun toString ()Ljava/lang/String;
public static fun toString-impl (Lio/ktor/server/routing/Route;)Ljava/lang/String;
public static final fun trigger-impl (Lio/ktor/server/routing/Route;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lio/ktor/server/routing/Route;
public final synthetic fun unbox-impl ()Lio/ktor/server/routing/Route;
}

public final class io/ktor/server/htmx/HxRoutingKt {
public static final fun getHx (Lio/ktor/server/routing/Route;)Lio/ktor/server/routing/Route;
public static final fun hx (Lio/ktor/server/routing/Route;Lkotlin/jvm/functions/Function1;)Lio/ktor/server/routing/Route;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ kotlin.sourceSets {
dependencies {
api(project(":ktor-shared:ktor-htmx"))
api(project(":ktor-server:ktor-server-plugins:ktor-server-html-builder"))
implementation(project(":ktor-utils"))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import io.ktor.htmx.*
import io.ktor.http.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.util.collections.*
import io.ktor.utils.io.InternalAPI
import kotlin.jvm.JvmInline

@ExperimentalHtmxApi
Expand All @@ -25,7 +27,7 @@ public value class HXRequestHeaders(private val headers: Headers) {
public val isHistoryRestore: Boolean get() = headers[HxRequestHeaders.HistoryRestoreRequest]?.toBoolean() == true

/** The current URL of the browser */
public val currentUrl: Url? get() = headers[HxRequestHeaders.CurrentURL]?.let { Url(it) }
public val currentUrl: Url? get() = headers[HxRequestHeaders.CurrentUrl]?.let { Url(it) }

/** The user response to an hx-prompt */
public val prompt: String? get() = headers[HxRequestHeaders.Prompt]
Expand All @@ -41,12 +43,13 @@ public value class HXRequestHeaders(private val headers: Headers) {
}

@ExperimentalHtmxApi
@OptIn(InternalAPI::class)
public class HXResponseHeaders(private val headers: ResponseHeaders) : StringMap {

public var location: String? by HxResponseHeaders.Location
public var pushUrl: String? by HxResponseHeaders.PushUrl
public var redirect: String? by HxResponseHeaders.Redirect
public var refresh: String? by HxResponseHeaders.Refresh // TODO boolean
public var refresh: Boolean? by HxResponseHeaders.Refresh.asBoolean()
public val replaceUrl: String? by HxResponseHeaders.ReplaceUrl

override fun set(key: String, value: String): Unit =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ import io.ktor.server.routing.*
import io.ktor.utils.io.*
import kotlin.jvm.JvmInline

/**
* Property for scoping routes to HTMX (e.g., `hx.get { ... }`
*/
@ExperimentalHtmxApi
public val Route.hx: HXRoute get() = HXRoute(this)
public val Route.hx: HxRoute get() = HxRoute.wrap(this)

/**
* Scope child routes to apply when `HX-Request` header is supplied.
*/
@ExperimentalHtmxApi
public fun Route.hx(configuration: HXRoute.() -> Unit): Route = with(HXRoute(this)) {
public fun Route.hx(configuration: HxRoute.() -> Unit): Route = with(HxRoute.wrap(this)) {
header(HxRequestHeaders.Request, "true") {
configuration()
}
Expand All @@ -28,7 +31,11 @@ public fun Route.hx(configuration: HXRoute.() -> Unit): Route = with(HXRoute(thi
@ExperimentalHtmxApi
@KtorDsl
@JvmInline
public value class HXRoute(private val route: Route) : Route by route {
public value class HxRoute internal constructor(private val route: Route) : Route by route {
internal companion object {
internal fun wrap(route: Route) =
HxRoute(route.createChild(HttpHeaderRouteSelector(HxRequestHeaders.Request, "true")))
}

/**
* Sub-routes only apply to a specific HX-Target header.
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.htmx.*
import io.ktor.server.html.*
import io.ktor.server.response.respondText
import io.ktor.server.routing.*
import io.ktor.server.testing.*
import kotlinx.html.body
Expand All @@ -30,7 +31,7 @@ class HtmxTest {
attributes.hx {
get = "/?page=1"
target = "#replaceMe"
swap = HxSwap.outerHTML
swap = HxSwap.outerHtml
trigger = "click[console.log('Hello!')||true]"
}
}
Expand Down Expand Up @@ -69,8 +70,11 @@ class HtmxTest {
}
}
route("htmx") {
get {
call.respondText { "Not HTMX" }
}
hx.get {
respondWith("No target")
respondWith("No target or trigger")
}
hx {
target("#test") {
Expand All @@ -87,7 +91,11 @@ class HtmxTest {
}
}
assertEquals(
responseTemplate("No target"),
"Not HTMX",
client.get("htmx").bodyAsText().trim()
)
assertEquals(
responseTemplate("No target or trigger"),
client.get("htmx") {
headers[HxRequestHeaders.Request] = "true"
}.bodyAsText().trim()
Expand Down
15 changes: 9 additions & 6 deletions ktor-shared/ktor-htmx/api/ktor-htmx.api
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
public abstract interface annotation class io/ktor/htmx/ExperimentalHtmxApi : java/lang/annotation/Annotation {
}

public final class io/ktor/htmx/HxAttributeKeys {
public static final field Boost Ljava/lang/String;
public static final field Confirm Ljava/lang/String;
Expand Down Expand Up @@ -69,17 +72,17 @@ public final class io/ktor/htmx/HxEvents {
public static final field HistoryRestore Ljava/lang/String;
public static final field INSTANCE Lio/ktor/htmx/HxEvents;
public static final field Load Ljava/lang/String;
public static final field NoSSESourceError Ljava/lang/String;
public static final field NoSseSourceError Ljava/lang/String;
public static final field OnLoadError Ljava/lang/String;
public static final field OobAfterSwap Ljava/lang/String;
public static final field OobBeforeSwap Ljava/lang/String;
public static final field OobErrorNoTarget Ljava/lang/String;
public static final field Prompt Ljava/lang/String;
public static final field PushedIntoHistory Ljava/lang/String;
public static final field ResponseError Ljava/lang/String;
public static final field SSEError Ljava/lang/String;
public static final field SSEOpen Ljava/lang/String;
public static final field SendError Ljava/lang/String;
public static final field SseError Ljava/lang/String;
public static final field SseOpen Ljava/lang/String;
public static final field SwapError Ljava/lang/String;
public static final field TargetError Ljava/lang/String;
public static final field Timeout Ljava/lang/String;
Expand All @@ -94,7 +97,7 @@ public final class io/ktor/htmx/HxEvents {

public final class io/ktor/htmx/HxRequestHeaders {
public static final field Boosted Ljava/lang/String;
public static final field CurrentURL Ljava/lang/String;
public static final field CurrentUrl Ljava/lang/String;
public static final field HistoryRestoreRequest Ljava/lang/String;
public static final field INSTANCE Lio/ktor/htmx/HxRequestHeaders;
public static final field Prompt Ljava/lang/String;
Expand Down Expand Up @@ -126,9 +129,9 @@ public final class io/ktor/htmx/HxSwap {
public static final field beforeBegin Ljava/lang/String;
public static final field beforeEnd Ljava/lang/String;
public static final field delete Ljava/lang/String;
public static final field innerHTML Ljava/lang/String;
public static final field innerHtml Ljava/lang/String;
public static final field none Ljava/lang/String;
public static final field outerHTML Ljava/lang/String;
public static final field outerHtml Ljava/lang/String;
public static final field textContent Ljava/lang/String;
}

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/*
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
* Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

package io.ktor.server.htmx
package io.ktor.htmx

@MustBeDocumented @Retention @RequiresOptIn
public annotation class ExperimentalHtmxApi
Loading

0 comments on commit ffafe9c

Please sign in to comment.