diff --git a/src/Common/Common.fs b/src/Common/Common.fs index a0946c8..5a45cd7 100644 --- a/src/Common/Common.fs +++ b/src/Common/Common.fs @@ -3,7 +3,7 @@ module Giraffe.Htmx.Common /// The version of htmx embedded in the package -let HtmxVersion = "4.0.0-beta5" +let HtmxVersion = "4.0.0" /// URLs for the included htmx library static web assets module StaticAssetUrl = diff --git a/src/Directory.Build.props b/src/Directory.Build.props index c761399..a93b0a7 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,16 +3,10 @@ net8.0;net9.0;net10.0 4.0.0 - beta5 true - Update htmx 4 to beta5 -- [Common] Update provided htmx/htmax 4 to 4.0.0-beta5 -- [Common] Add StaticAssetUrl module with static asset paths for htmx and htmax -- [Server] Unobsolete HX-Prompt header, note that it requires hx-prompt extension -- [View Engine] Unobsolete hx-prompt attribute, note that it requires hx-prompt extension -- [View Engine] Updated CDN script tags to pull htmx / htmax 4.0.0-beta5 + htmx 4.0.0 Initial Release -See package and prior alpha release READMEs; v2 to v4 is not an update-and-forget-it release +See package and prior alpha/beta release READMEs; v2 to v4 is not an update-and-forget-it release. If you encounter build errors after installing this, install v4.0.0-beta5 instead; obsolete elements will generate a warning with suggestions of what to use instead. danieljsummers Bit Badger Solutions diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 1f8d6c3..8d028b7 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -3,11 +3,11 @@ true - - + + - - + + \ No newline at end of file diff --git a/src/Htmx/Htmx.fs b/src/Htmx/Htmx.fs index 1433c84..ea00e2c 100644 --- a/src/Htmx/Htmx.fs +++ b/src/Htmx/Htmx.fs @@ -91,16 +91,6 @@ type IHeaderDictionary with Some (parts[0], if parts[1] <> "" then Some parts[1] else None) | None -> None - /// The id attribute of the triggered element if it exists - [] - member this.HxTrigger - with get () = hdr this "HX-Trigger" - - /// The name attribute of the triggered element if it exists - [] - member this.HxTriggerName - with get () = hdr this "HX-Trigger-Name" - /// Extensions for the request object type HttpRequest with @@ -209,38 +199,6 @@ module Handlers = let withHxTriggerMany evts : HttpHandler = toJson evts |> setHttpHeader "HX-Trigger" - /// Allows you to trigger a single client side event after changes have settled - /// The call to the event that should be triggered - /// An HTTP handler with the HX-Trigger-After-Settle header set - /// Documentation - [] - let withHxTriggerAfterSettle (evt: string) : HttpHandler = - setHttpHeader "HX-Trigger" evt - - /// Allows you to trigger multiple client side events after changes have settled - /// The calls to events that should be triggered - /// An HTTP handler with the HX-Trigger-After-Settle header set for all given events - /// Documentation - [] - let withHxTriggerManyAfterSettle evts : HttpHandler = - toJson evts |> setHttpHeader "HX-Trigger" - - /// Allows you to trigger a single client side event after DOM swapping occurs - /// The call to the event that should be triggered - /// An HTTP handler with the HX-Trigger-After-Swap header set - /// Documentation - [] - let withHxTriggerAfterSwap (evt: string) : HttpHandler = - setHttpHeader "HX-Trigger" evt - - /// Allows you to trigger multiple client side events after DOM swapping occurs - /// The calls to events that should be triggered - /// An HTTP handler with the HX-Trigger-After-Swap header set for all given events - /// Documentation - [] - let withHxTriggerManyAfterSwap evts : HttpHandler = - toJson evts |> setHttpHeader "HX-Trigger" - /// Load the package-provided version of the htmx script [] diff --git a/src/Tests/Common.fs b/src/Tests/Common.fs index 0942e42..80f4b6a 100644 --- a/src/Tests/Common.fs +++ b/src/Tests/Common.fs @@ -6,7 +6,7 @@ open Giraffe.Htmx /// Test to ensure the version was updated let version = test "HtmxVersion is correct" { - Expect.equal HtmxVersion "4.0.0-beta5" "htmx version incorrect" + Expect.equal HtmxVersion "4.0.0" "htmx version incorrect" } let staticAssetUrl = diff --git a/src/Tests/Htmx.fs b/src/Tests/Htmx.fs index 4c29c5c..1b0bd31 100644 --- a/src/Tests/Htmx.fs +++ b/src/Tests/Htmx.fs @@ -441,76 +441,5 @@ let script = } ] -#nowarn 44 // Obsolete items still have tests -let dictExtensionsObs = - testList "IHeaderDictionaryExtensions (Obsolete)" [ - testList "HxTrigger" [ - test "succeeds when the header is not present" { - let ctx = Substitute.For() - ctx.Request.Headers.ReturnsForAnyArgs (HeaderDictionary ()) |> ignore - Expect.isNone ctx.Request.Headers.HxTrigger "There should not have been a header returned" - } - test "succeeds when the header is present" { - let ctx = Substitute.For() - let dic = HeaderDictionary() - dic.Add("HX-Trigger", "#trig") - ctx.Request.Headers.ReturnsForAnyArgs dic |> ignore - Expect.isSome ctx.Request.Headers.HxTrigger "There should be a header present" - Expect.equal ctx.Request.Headers.HxTrigger.Value "#trig" "The header value was incorrect" - } - ] - testList "HxTriggerName" [ - test "succeeds when the header is not present" { - let ctx = Substitute.For() - ctx.Request.Headers.ReturnsForAnyArgs(HeaderDictionary()) |> ignore - Expect.isNone ctx.Request.Headers.HxTriggerName "There should not have been a header returned" - } - test "HxTriggerName succeeds when the header is present" { - let ctx = Substitute.For() - let dic = HeaderDictionary() - dic.Add("HX-Trigger-Name", "click") - ctx.Request.Headers.ReturnsForAnyArgs dic |> ignore - Expect.isSome ctx.Request.Headers.HxTriggerName "There should be a header present" - Expect.equal ctx.Request.Headers.HxTriggerName.Value "click" "The header value was incorrect" - } - ] - ] - -let handlerObs = - testList "Handler Tests (Obsolete)" [ - testTask "withHxTriggerAfterSettle succeeds" { - let ctx = Substitute.For() - let dic = HeaderDictionary() - ctx.Response.Headers.ReturnsForAnyArgs dic |> ignore - let! _ = withHxTriggerAfterSettle "byTheWay" next ctx - Expect.isTrue (dic.ContainsKey "HX-Trigger") "The HX-Trigger header should be present" - Expect.equal dic["HX-Trigger"].[0] "byTheWay" "The HX-Trigger value was incorrect" - } - testTask "withHxTriggerManyAfterSettle succeeds" { - let ctx = Substitute.For() - let dic = HeaderDictionary() - ctx.Response.Headers.ReturnsForAnyArgs dic |> ignore - let! _ = withHxTriggerManyAfterSettle [ "oof", "ouch"; "hmm", "uh" ] next ctx - Expect.isTrue (dic.ContainsKey "HX-Trigger") "The HX-Trigger header should be present" - Expect.equal dic["HX-Trigger"].[0] """{ "oof": "ouch", "hmm": "uh" }""" "The HX-Trigger value was incorrect" - } - testTask "withHxTriggerAfterSwap succeeds" { - let ctx = Substitute.For() - let dic = HeaderDictionary() - ctx.Response.Headers.ReturnsForAnyArgs dic |> ignore - let! _ = withHxTriggerAfterSwap "justASec" next ctx - Expect.isTrue (dic.ContainsKey "HX-Trigger") "The HX-Trigger header should be present" - Expect.equal dic["HX-Trigger"].[0] "justASec" "The HX-Trigger value was incorrect" - } - testTask "withHxTriggerManyAfterSwap succeeds" { - let ctx = Substitute.For() - let dic = HeaderDictionary() - ctx.Response.Headers.ReturnsForAnyArgs dic |> ignore - let! _ = withHxTriggerManyAfterSwap [ "this", "1"; "that", "2" ] next ctx - Expect.isTrue (dic.ContainsKey "HX-Trigger") "The HX-Trigger header should be present" - Expect.equal dic["HX-Trigger"].[0] """{ "this": "1", "that": "2" }""" "The HX-Trigger value was incorrect" - } - ] - /// All tests for this module -let allTests = testList "Htmx" [ dictExtensions; reqExtensions; handlers; script; dictExtensionsObs; handlerObs ] +let allTests = testList "Htmx" [ dictExtensions; reqExtensions; handlers; script ] diff --git a/src/Tests/ViewEngine.fs b/src/Tests/ViewEngine.fs index af633a9..9f7adac 100644 --- a/src/Tests/ViewEngine.fs +++ b/src/Tests/ViewEngine.fs @@ -863,474 +863,6 @@ let renderFragment = ] ] -#nowarn 44 // Obsolete events still have tests - -let hxEventObs = - testList "HxEvent (Obsolete)" [ - testList "AfterOnLoad" [ - test "ToString succeeds" { - Expect.equal (string AfterOnLoad) "afterOnLoad" "AfterOnLoad event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (AfterOnLoad.ToHxOnString()) "after:init" "AfterOnLoad hx-on event name not correct" - } - ] - testList "AfterProcessNode" [ - test "ToString succeeds" { - Expect.equal (string AfterProcessNode) "afterProcessNode" "AfterProcessNode event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (AfterProcessNode.ToHxOnString()) "after:process" "AfterProcessNode hx-on event name not correct" - } - ] - testList "AfterSseMessage" [ - test "ToString succeeds" { - Expect.equal (string AfterSseMessage) "afterSseMessage" "AfterSseMessage event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (AfterSseMessage.ToHxOnString()) "after:sse:message" "AfterSseMessage hx-on event name not correct" - } - ] - testList "AfterSseStream" [ - test "ToString succeeds" { - Expect.equal (string AfterSseStream) "afterSseStream" "AfterSseStream event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (AfterSseStream.ToHxOnString()) "after:sse:stream" "AfterSseStream hx-on event name not correct" - } - ] - testList "BeforeCleanupElement" [ - test "ToString succeeds" { - Expect.equal - (string BeforeCleanupElement) "beforeCleanupElement" "BeforeCleanupElement event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (BeforeCleanupElement.ToHxOnString()) - "before:cleanup" - "BeforeCleanupElement hx-on event name not correct" - } - ] - testList "BeforeHistorySave" [ - test "ToString succeeds" { - Expect.equal (string BeforeHistorySave) "beforeHistorySave" "BeforeHistorySave event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (BeforeHistorySave.ToHxOnString()) - "before:history:update" - "BeforeHistorySave hx-on event name not correct" - } - ] - testList "BeforeOnLoad" [ - test "ToString succeeds" { - Expect.equal (string BeforeOnLoad) "beforeOnLoad" "BeforeOnLoad event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (BeforeOnLoad.ToHxOnString()) "before:init" "BeforeOnLoad hx-on event name not correct" - } - ] - testList "BeforeProcessNode" [ - test "ToString succeeds" { - Expect.equal (string BeforeProcessNode) "beforeProcessNode" "BeforeProcessNode event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (BeforeProcessNode.ToHxOnString()) "before:process" "BeforeProcessNode hx-on event name not correct" - } - ] - testList "BeforeSend" [ - test "ToString succeeds" { - Expect.equal (string BeforeSend) "beforeSend" "BeforeSend event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (BeforeSend.ToHxOnString()) "before:request" "BeforeSend hx-on event name not correct" - } - ] - testList "BeforeSseMessage" [ - test "ToString succeeds" { - Expect.equal (string BeforeSseMessage) "beforeSseMessage" "BeforeSseMessage event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (BeforeSseMessage.ToHxOnString()) - "before:sse:message" - "BeforeSseMessage hx-on event name not correct" - } - ] - testList "BeforeSseReconnect" [ - test "ToString succeeds" { - Expect.equal - (string BeforeSseReconnect) "beforeSseReconnect" "BeforeSseReconnect event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (BeforeSseReconnect.ToHxOnString()) - "before:sse:reconnect" - "BeforeSseReconnect hx-on event name not correct" - } - ] - testList "BeforeSseStream" [ - test "ToString succeeds" { - Expect.equal (string BeforeSseStream) "beforeSseStream" "BeforeSseStream event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (BeforeSseStream.ToHxOnString()) "before:sse:stream" "BeforeSseStream hx-on event name not correct" - } - ] - testList "HistoryCacheError" [ - test "ToString succeeds" { - Expect.equal (string HistoryCacheError) "historyCacheError" "HistoryCacheError event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (HistoryCacheError.ToHxOnString()) - "history-cache-error" - "HistoryCacheError hx-on event name not correct" - } - ] - testList "HistoryCacheMiss" [ - test "ToString succeeds" { - Expect.equal (string HistoryCacheMiss) "historyCacheMiss" "HistoryCacheMiss event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (HistoryCacheMiss.ToHxOnString()) - "before:history:restore" - "HistoryCacheMiss hx-on event name not correct" - } - ] - testList "HistoryCacheMissError" [ - test "ToString succeeds" { - Expect.equal - (string HistoryCacheMissError) - "historyCacheMissError" - "HistoryCacheMissError event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (HistoryCacheMissError.ToHxOnString()) - "history-cache-miss-error" - "HistoryCacheMissError hx-on event name not correct" - } - ] - testList "HistoryCacheMissLoad" [ - test "ToString succeeds" { - Expect.equal - (string HistoryCacheMissLoad) "historyCacheMissLoad" "HistoryCacheMissLoad event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (HistoryCacheMissLoad.ToHxOnString()) - "before:history:restore" - "HistoryCacheMissLoad hx-on event name not correct" - } - ] - testList "HistoryRestore" [ - test "ToString succeeds" { - Expect.equal (string HistoryRestore) "historyRestore" "HistoryRestore event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (HistoryRestore.ToHxOnString()) - "before:history:restore" - "HistoryRestore hx-on event name not correct" - } - ] - testList "Load" [ - test "ToString succeeds" { - Expect.equal (string Load) "load" "Load event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (Load.ToHxOnString()) "after:init" "Load hx-on event name not correct" - } - ] - testList "NoSseSourceError" [ - test "ToString succeeds" { - Expect.equal (string NoSseSourceError) "noSSESourceError" "NoSseSourceError event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (NoSseSourceError.ToHxOnString()) "error" "NoSseSourceError hx-on event name not correct" - } - ] - testList "OnLoadError" [ - test "ToString succeeds" { - Expect.equal (string OnLoadError) "onLoadError" "OnLoadError event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (OnLoadError.ToHxOnString()) "error" "OnLoadError hx-on event name not correct" - } - ] - testList "OobAfterSwap" [ - test "ToString succeeds" { - Expect.equal (string OobAfterSwap) "oobAfterSwap" "OobAfterSwap event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (OobAfterSwap.ToHxOnString()) "after:swap" "OobAfterSwap hx-on event name not correct" - } - ] - testList "OobBeforeSwap" [ - test "ToString succeeds" { - Expect.equal (string OobBeforeSwap) "oobBeforeSwap" "OobBeforeSwap event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (OobBeforeSwap.ToHxOnString()) "before:swap" "OobBeforeSwap hx-on event name not correct" - } - ] - testList "OobErrorNoTarget" [ - test "ToString succeeds" { - Expect.equal (string OobErrorNoTarget) "oobErrorNoTarget" "OobErrorNoTarget event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (OobErrorNoTarget.ToHxOnString()) "error" "OobErrorNoTarget hx-on event name not correct" - } - ] - testList "Prompt" [ - test "ToString succeeds" { - Expect.equal (string Prompt) "prompt" "Prompt event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (Prompt.ToHxOnString()) "prompt" "Prompt hx-on event name not correct" - } - ] - testList "PushedIntoHistory" [ - test "ToString succeeds" { - Expect.equal (string PushedIntoHistory) "pushedIntoHistory" "PushedIntoHistory event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (PushedIntoHistory.ToHxOnString()) - "after:push:into:history" - "PushedIntoHistory hx-on event name not correct" - } - ] - testList "SendError" [ - test "ToString succeeds" { - Expect.equal (string SendError) "sendError" "SendError event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (SendError.ToHxOnString()) "error" "SendError hx-on event name not correct" - } - ] - testList "SseError" [ - test "ToString succeeds" { - Expect.equal (string SseError) "sseError" "SseError event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (SseError.ToHxOnString()) "sse:error" "SseError hx-on event name not correct" - } - ] - testList "SseOpen" [ - test "ToString succeeds" { - Expect.equal (string SseOpen) "sseOpen" "SseOpen event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (SseOpen.ToHxOnString()) "after:sse:connection" "SseOpen hx-on event name not correct" - } - ] - testList "SwapError" [ - test "ToString succeeds" { - Expect.equal (string SwapError) "swapError" "SwapError event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (SwapError.ToHxOnString()) "error" "SwapError hx-on event name not correct" - } - ] - testList "TargetError" [ - test "ToString succeeds" { - Expect.equal (string TargetError) "targetError" "TargetError event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (TargetError.ToHxOnString()) "error" "TargetError hx-on event name not correct" - } - ] - testList "Timeout" [ - test "ToString succeeds" { - Expect.equal (string Timeout) "timeout" "Timeout event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (Timeout.ToHxOnString()) "error" "Timeout hx-on event name not correct" - } - ] - testList "ValidationValidate" [ - test "ToString succeeds" { - Expect.equal - (string ValidationValidate) "validation:validate" "ValidationValidate event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (ValidationValidate.ToHxOnString()) - "validation:validate" - "ValidationValidate hx-on event name not correct" - } - ] - testList "ValidationFailed" [ - test "ToString succeeds" { - Expect.equal (string ValidationFailed) "validation:failed" "ValidationFailed event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (ValidationFailed.ToHxOnString()) - "validation:failed" - "ValidationFailed hx-on event name not correct" - } - ] - testList "ValidationHalted" [ - test "ToString succeeds" { - Expect.equal (string ValidationHalted) "validation:halted" "ValidationHalted event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal - (ValidationHalted.ToHxOnString()) - "validation:halted" - "ValidationHalted hx-on event name not correct" - } - ] - testList "XhrAbort" [ - test "ToString succeeds" { - Expect.equal (string XhrAbort) "xhr:abort" "XhrAbort event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (XhrAbort.ToHxOnString()) "error" "XhrAbort hx-on event name not correct" - } - ] - testList "XhrLoadEnd" [ - test "ToString succeeds" { - Expect.equal (string XhrLoadEnd) "xhr:loadend" "XhrLoadEnd event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (XhrLoadEnd.ToHxOnString()) "finally:request" "XhrLoadEnd hx-on event name not correct" - } - ] - testList "XhrLoadStart" [ - test "ToString succeeds" { - Expect.equal (string XhrLoadStart) "xhr:loadstart" "XhrLoadStart event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (XhrLoadStart.ToHxOnString()) "xhr:loadstart" "XhrLoadStart hx-on event name not correct" - } - ] - testList "XhrProgress" [ - test "ToString succeeds" { - Expect.equal (string XhrProgress) "xhr:progress" "XhrProgress event name not correct" - } - test "ToHxOnString succeeds" { - Expect.equal (XhrProgress.ToHxOnString()) "xhr:progress" "XhrProgress hx-on event name not correct" - } - ] - ] - -/// Tests for the HxParams module -let hxParamsObs = - testList "HxParams" [ - test "All is correct" { - Expect.equal HxParams.All "*" "All is not correct" - } - test "None is correct" { - Expect.equal HxParams.None "none" "None is not correct" - } - testList "With" [ - test "succeeds with empty list" { - Expect.equal (HxParams.With []) "" "With with empty list should have been blank" - } - test "succeeds with one list item" { - Expect.equal (HxParams.With [ "boo" ]) "boo" "With single item incorrect" - } - test "succeeds with multiple list items" { - Expect.equal (HxParams.With [ "foo"; "bar"; "baz" ]) "foo,bar,baz" "With multiple items incorrect" - } - ] - testList "Except" [ - test "succeeds with empty list" { - Expect.equal (HxParams.Except []) "not " "Except with empty list incorrect" - } - test "succeeds with one list item" { - Expect.equal (HxParams.Except [ "that" ]) "not that" "Except single item incorrect" - } - test "succeeds with multiple list items" { - Expect.equal (HxParams.Except [ "blue"; "green" ]) "not blue,green" "Except multiple items incorrect" - } - ] - ] - -/// Tests for the HxConfig module -let hxRequestObs = - testList "HxRequest (Obsolete)" [ - testList "Configure" [ - test "succeeds with an empty list" { - Expect.equal (HxRequest.Configure []) "{ }" "Configure with empty list incorrect" - } - test "succeeds with a non-empty list" { - Expect.equal - (HxRequest.Configure [ "\"a\": \"b\""; "\"c\": \"d\"" ]) """{ "a": "b", "c": "d" }""" - "Configure with a non-empty list incorrect" - } - test "succeeds with all known params configured" { - Expect.equal - (HxRequest.Configure - [ HxRequest.Timeout 1000; HxRequest.Credentials false; HxRequest.NoHeaders true ]) - """{ "timeout": 1000, "credentials": false, "noHeaders": true }""" - "Configure with all known params incorrect" - } - ] - test "Timeout succeeds" { - Expect.equal (HxRequest.Timeout 50) "\"timeout\": 50" "Timeout value incorrect" - } - testList "Credentials" [ - test "succeeds when set to true" { - Expect.equal (HxRequest.Credentials true) "\"credentials\": true" "Credentials value incorrect" - } - test "succeeds when set to false" { - Expect.equal (HxRequest.Credentials false) "\"credentials\": false" "Credentials value incorrect" - } - ] - testList "NoHeaders" [ - test "succeeds when set to true" { - Expect.equal (HxRequest.NoHeaders true) "\"noHeaders\": true" "NoHeaders value incorrect" - } - test "succeeds when set to false" { - Expect.equal (HxRequest.NoHeaders false) "\"noHeaders\": false" "NoHeaders value incorrect" - } - ] - ] - -let attributesObs = - testList "Attributes (Obsolete)" [ - test "_hxDisabledElt succeeds" { - button [ _hxDisabledElt "this" ] [] |> shouldRender """""" - } - test "_hxDisinherit succeeds" { - strong [ _hxDisinherit "*" ] [] |> shouldRender """""" - } - test "_hxExt succeeds" { - section [ _hxExt "extendme" ] [] |> shouldRender """
""" - } - test "_hxHistory succeeds" { - span [ _hxHistory false ] [] |> shouldRender """""" - } - test "_hxHistoryElt succeeds" { - table [ _hxHistoryElt ] [] |> shouldRender """
""" - } - test "_hxParams succeeds" { - br [ _hxParams "[p1,p2]" ] |> shouldRender """
""" - } - test "_hxRequest succeeds" { - u [ _hxRequest "noHeaders" ] [] |> shouldRender """""" - } - test "_sseConnect succeeds" { - div [ _sseConnect "/gps/sse" ] [] |> shouldRender """
""" - } - test "_sseSwap succeeds" { - ul [ _sseSwap "sseMessageName" ] [] |> shouldRender """
    """ - } - ] - -let obsolete = testList "Obsolete" [ hxEventObs; hxParamsObs; hxRequestObs; attributesObs ] - /// All tests in this module let allTests = testList "ViewEngine.Htmx" [ @@ -1345,5 +877,4 @@ let allTests = hxTags script renderFragment - obsolete ] diff --git a/src/ViewEngine.Htmx/Htmx.fs b/src/ViewEngine.Htmx/Htmx.fs index ccbba1d..c1e80cd 100644 --- a/src/ViewEngine.Htmx/Htmx.fs +++ b/src/ViewEngine.Htmx/Htmx.fs @@ -50,7 +50,6 @@ module HxEncoding = let MultipartForm = "multipart/form-data" -#nowarn 44 // Obsolete elements still have entries in the conversion map; will be removed for v4 final /// The events recognized by htmx /// Documentation [] @@ -68,15 +67,9 @@ type HxEvent = /// Triggered after a request has initialized | AfterInit - /// Triggered after an AJAX request has completed processing a successful response - | [] AfterOnLoad - /// Triggered after htmx has initialized a DOM node or subtree | AfterProcess - /// Triggered after htmx has initialized a node - | [] AfterProcessNode - /// Triggered after new content is saved to the history cache | AfterPushIntoHistory @@ -89,12 +82,6 @@ type HxEvent = /// Triggered after the DOM has settled | AfterSettle - /// Triggered after a Server Sent Events (SSE) message is read - | [] AfterSseMessage - - /// Triggered after a Server Sent Events (SSE) stream is closed - | [] AfterSseStream - /// Triggered after new content has been swapped in | AfterSwap @@ -104,27 +91,15 @@ type HxEvent = /// Triggered before htmx disables an element or removes it from the DOM | BeforeCleanup - /// Triggered before htmx disables an element or removes it from the DOM - | [] BeforeCleanupElement - - /// Triggered before content is saved to the history cache - | [] BeforeHistorySave - /// Triggered before content is saved to the history cache | BeforeHistoryUpdate /// Triggered before htmx initializes a node | BeforeInit - /// Triggered before any response processing occurs - | [] BeforeOnLoad - /// Triggered before htmx begins processing a DOM node or subtree | BeforeProcess - /// Triggered before htmx initializes a node - | [] BeforeProcessNode - /// Triggered before an HTTP request is made | BeforeRequest @@ -134,18 +109,6 @@ type HxEvent = /// Triggered before a history restore request is made | BeforeRestoreHistory - /// Triggered just before an ajax request is sent - | [] BeforeSend - - /// Triggered before a Server Sent Events (SSE) message is read - | [] BeforeSseMessage - - /// Triggered before a Server Sent Events (SSE) connection is reconnected - | [] BeforeSseReconnect - - /// Triggered before a Server Sent Events (SSE) stream is opened - | [] BeforeSseStream - /// Triggered before a swap is done, allows you to configure the swap | BeforeSwap @@ -166,153 +129,35 @@ type HxEvent = /// Triggered after an HTTP request is made, whether it was successful or not | FinallyRequest - /// Triggered on an error during cache writing - | [] HistoryCacheError - - /// Triggered on a cache miss in the history subsystem - | [] HistoryCacheMiss - - /// Triggered on a unsuccessful remote retrieval - | [] HistoryCacheMissError - - /// Triggered on a successful remote retrieval - | [] HistoryCacheMissLoad - - /// Triggered when htmx handles a history restoration action - | [] HistoryRestore - - /// Triggered when new content is added to the DOM - | [] Load - - /// - /// Triggered when an element refers to a SSE event in its trigger, but no parent SSE source has been defined - /// - | [] NoSseSourceError - - /// Triggered when an exception occurs during the onLoad handling in htmx - | [] OnLoadError - - /// Triggered after an out of band element as been swapped in - | [] OobAfterSwap - - /// Triggered before an out of band element swap is done, allows you to configure the swap - | [] OobBeforeSwap - - /// Triggered when an out of band element does not have a matching ID in the current DOM - | [] OobErrorNoTarget - - /// Triggered after a prompt is shown - | [] Prompt - - /// Triggered after an url is pushed into history - | [] PushedIntoHistory - /// Triggered when an HTTP response error (non-200 or 300 response code) occurs | ResponseError - /// Triggered when a network error prevents an HTTP request from happening - | [] SendError - - /// Triggered when an error occurs with a SSE source - | [] SseError - - /// Triggered when an SSE source is opened - | [] SseOpen - - /// Triggered when an error occurs during the swap phase - | [] SwapError - - /// Triggered when an invalid target is specified - | [] TargetError - - /// Triggered when a request timeout occurs - | [] Timeout - - /// Triggered before an element is validated - | [] ValidationValidate - - /// Triggered when an element fails validation - | [] ValidationFailed - - /// Triggered when a request is halted due to validation errors - | [] ValidationHalted - - /// Triggered when an ajax request aborts - | [] XhrAbort - - /// Triggered when an ajax request ends - | [] XhrLoadEnd - - /// Triggered when an ajax request starts - | [] XhrLoadStart - - /// Triggered periodically during an ajax request that supports progress events - | [] XhrProgress - /// The htmx event name (fst) and kebab-case name (snd, for use with hx-on) static member private Values = Map [ Abort, ("abort", "abort") AfterCleanup, ("afterCleanup", "after:cleanup") AfterHistoryUpdate, ("afterHistoryUpdate", "after:history:update") AfterInit, ("afterInit", "after:init") - AfterOnLoad, ("afterOnLoad", "after:init") - AfterProcessNode, ("afterProcessNode", "after:process") AfterPushIntoHistory, ("afterPushIntoHistory", "after:push:into:history") AfterReplaceIntoHistory, ("afterReplaceIntoHistory", "after:replace:into:history") AfterRequest, ("afterRequest", "after:request") AfterSettle, ("afterSettle", "after:settle") - AfterSseMessage, ("afterSseMessage", "after:sse:message") - AfterSseStream, ("afterSseStream", "after:sse:stream") AfterSwap, ("afterSwap", "after:swap") AfterViewTransition, ("afterViewTransition", "after:viewTransition") BeforeCleanup, ("beforeCleanup", "before:cleanup") - BeforeCleanupElement, ("beforeCleanupElement", "before:cleanup") - BeforeHistorySave, ("beforeHistorySave", "before:history:update") BeforeHistoryUpdate, ("beforeHistoryUpdate", "before:history:update") BeforeInit, ("beforeInit", "before:init") - BeforeOnLoad, ("beforeOnLoad", "before:init") BeforeProcess, ("beforeProcess", "before:process") - BeforeProcessNode, ("beforeProcessNode", "before:process") BeforeRequest, ("beforeRequest", "before:request") BeforeResponse, ("beforeResponse", "before:response") BeforeRestoreHistory, ("beforeRestoreHistory", "before:restore:history") - BeforeSend, ("beforeSend", "before:request") - BeforeSseMessage, ("beforeSseMessage", "before:sse:message") - BeforeSseReconnect, ("beforeSseReconnect", "before:sse:reconnect") - BeforeSseStream, ("beforeSseStream", "before:sse:stream") BeforeSwap, ("beforeSwap", "before:swap") BeforeViewTransition, ("beforeTransition", "before:viewTransition") ConfigRequest, ("configRequest", "config:request") Confirm, ("confirm", "confirm") Error, ("error", "error") FinallyRequest, ("finallyRequest", "finally:request") - HistoryCacheError, ("historyCacheError", "history-cache-error") - HistoryCacheMiss, ("historyCacheMiss", "before:history:restore") - HistoryCacheMissError, ("historyCacheMissError", "history-cache-miss-error") - HistoryCacheMissLoad, ("historyCacheMissLoad", "before:history:restore") - HistoryRestore, ("historyRestore", "before:history:restore") - Load, ("load", "after:init") - NoSseSourceError, ("noSSESourceError", "error") - OnLoadError, ("onLoadError", "error") - OobAfterSwap, ("oobAfterSwap", "after:swap") - OobBeforeSwap, ("oobBeforeSwap", "before:swap") - OobErrorNoTarget, ("oobErrorNoTarget", "error") - Prompt, ("prompt", "prompt") - PushedIntoHistory, ("pushedIntoHistory", "after:push:into:history") ResponseError, ("responseError", "response:error") - SendError, ("sendError", "error") - SseError, ("sseError", "sse:error") - SseOpen, ("sseOpen", "after:sse:connection") - SwapError, ("swapError", "error") - TargetError, ("targetError", "error") - Timeout, ("timeout", "error") - ValidationValidate, ("validation:validate", "validation:validate") - ValidationFailed, ("validation:failed", "validation:failed") - ValidationHalted, ("validation:halted", "validation:halted") - XhrAbort, ("xhr:abort", "error") - XhrLoadEnd, ("xhr:loadend", "finally:request") - XhrLoadStart, ("xhr:loadstart", "xhr:loadstart") - XhrProgress, ("xhr:progress", "xhr:progress") ] /// The htmx event name @@ -320,7 +165,6 @@ type HxEvent = /// The hx-on variant of the htmx event name member this.ToHxOnString() = snd HxEvent.Values[this] -#warn 44 // restore obsolete warning /// Helper to create the hx-headers attribute @@ -331,70 +175,6 @@ module HxHeaders = let From = Giraffe.Htmx.Common.toJson -/// Values / helpers for the hx-params attribute -/// Documentation -[] -[] -module HxParams = - - /// Include all parameters - [] - let All = "*" - - /// Include no parameters - [] - let None = "none" - - /// Include the specified parameters - /// One or more fields to include in the request - /// The list of fields for the hx-params attribute value - let With fields = - match fields with [] -> "" | _ -> fields |> List.reduce (fun acc it -> $"{acc},{it}") - - /// Exclude the specified parameters - /// One or more fields to exclude from the request - /// The list of fields for the hx-params attribute value prefixed with "not" - let Except fields = - With fields |> sprintf "not %s" - - -/// Helpers to define hx-request attribute values -/// Documentation -[] -[] -module HxRequest = - - open Giraffe.Htmx.Common - - /// Configure the request with various options - /// The options to configure - /// A string with the configured options - let Configure (opts: string list) = - opts - |> String.concat ", " - |> sprintf "{ %s }" - - /// Set a timeout (in milliseconds) - /// The milliseconds for the request timeout - /// A string with the configured request timeout - let Timeout (ms: int) = - $"\"timeout\": {ms}" - - /// Include or exclude credentials from the request - /// true if credentials should be sent, false if not - /// A string with the configured credential options - let Credentials send = - (toLowerBool >> sprintf "\"credentials\": %s") send - - /// Exclude or include headers from the request - /// - /// true if no headers should be sent; false if headers should be sent - /// - /// A string with the configured header options - let NoHeaders exclude = - (toLowerBool >> sprintf "\"noHeaders\": %s") exclude - - /// Helpers for the hx-sync attribute /// Documentation [] @@ -663,22 +443,6 @@ module HtmxAttrs = let _hxDisable elt = attr "hx-disable" elt - /// Specifies elements that should be disabled when an htmx request is in flight - /// The element to disable when an htmx request is in flight - /// A configured hx-disabled-elt attribute - /// Documentation - [] - let _hxDisabledElt elt = - attr "hx-disabled-elt" elt - - /// Disinherit all ("*") or specific htmx attributes - /// The htmx attributes to disinherit (should start with "hx-") - /// A configured hx-disinherit attribute - /// Documentation - [] - let _hxDisinherit hxAttrs = - attr "hx-disinherit" hxAttrs - /// Changes the request encoding type /// The encoding type (use HxEncoding constants) /// A configured hx-encoding attribute @@ -687,14 +451,6 @@ module HtmxAttrs = let _hxEncoding enc = attr "hx-encoding" enc - /// Extensions to use for this element - /// A list of extensions to apply to this element - /// A configured hx-ext attribute - /// Documentation - [] - let _hxExt exts = - attr "hx-ext" exts - /// Issues a GET to the specified URL /// The URL to which the GET request should be sent /// A configured hx-get attribute @@ -709,22 +465,6 @@ module HtmxAttrs = let _hxHeaders hdrs = attr "hx-headers" hdrs - /// - /// Set to "false" to prevent pages with sensitive information from being stored in the history cache - /// - /// Whether the page should be stored in the history cache - /// A configured hx-history attribute - /// Documentation - [] - let _hxHistory shouldStore = - attr "hx-history" (toLowerBool shouldStore) - - /// The element to snapshot and restore during history navigation - /// Documentation - [] - let _hxHistoryElt = - flag "hx-history-elt" - /// Disables htmx processing for the given node and any children nodes /// Documentation let _hxIgnore = @@ -773,15 +513,6 @@ module HtmxAttrs = let _hxOnHxEvent (hxEvent: HxEvent) handler = _hxOnEvent $"htmx:{hxEvent.ToHxOnString()}" handler - /// Filters the parameters that will be submitted with a request - /// The fields to include (use HxParams to generate this value) - /// A configured hx-params attribute - /// - /// Documentation - [] - let _hxParams toInclude = - attr "hx-params" toInclude - /// Issues a PATCH to the specified URL /// The URL to which the request should be directed /// A configured hx-patch attribute @@ -847,15 +578,6 @@ module HtmxAttrs = let _hxReplaceUrl spec = attr "hx-replace-url" spec - /// Configures various aspects of the request - /// The configuration spec (use HxRequest.Configure to create value) - /// A configured hx-request attribute - /// - /// Documentation - [] - let _hxRequest spec = - attr "hx-request" spec - /// Selects a subset of the server response to process /// A CSS selector for the content to be selected /// A configured hx-select attribute @@ -966,20 +688,6 @@ module HtmxAttrs = let _hxVals values = attr "hx-vals" values - /// The URL of the SSE server - /// The URL from which events will be received - /// A configured sse-connect attribute - /// Extension Docs - let [] _sseConnect url = - attr "sse-connect" url - - /// The name(s) of the message(s) to swap into the DOM - /// The message names (comma-delimited) to swap (use "message" for unnamed events) - /// A configured sse-swap attribute - /// Extension Docs - let [] _sseSwap messages = - attr "sse-swap" messages - /// Modifiers for htmx attributes [] @@ -1013,8 +721,6 @@ module HxTags = /// Script tags to pull htmx into a web page module Script = - open System - /// Script tag to load the package-provided version of htmx let local = script [ _src StaticAssetUrl.htmx ] [] @@ -1052,14 +758,6 @@ module Script = _integrity "sha384-kjhVuvnX3/TsR1qH4JaIcHR6muh/WLMU5CTQRacCQZERzQlP4/r9p/TK7ucFwqvV" _crossorigin "anonymous" ] [] - /// Script tag to load the minified version from jsdelivr.net - [] - let minified = cdnMinified - - /// Script tag to load the unminified version from jsdelivr.net - [] - let unminified = cdnUnminified - /// Functions to extract and render an HTML fragment from a document []