diff --git a/docs/articles/configuration-v4.md b/docs/articles/configuration-v4.md index 5c2202e..26a8150 100644 --- a/docs/articles/configuration-v4.md +++ b/docs/articles/configuration-v4.md @@ -13,7 +13,7 @@ builder.Services.AddHtmxToolkit(options => { config.History = HtmxHistoryMode.Enabled; config.DefaultTimeout = 10_000; - config.Mode = HtmxFetchMode.SameOrigin; + config.Mode = HtmxRequestMode.SameOrigin; config.Transitions = true; config.NoSwap = ["204", "304", "4xx", "5xx"]; }); @@ -49,6 +49,7 @@ no `HX-*` headers or `hx-headers` values, and no antiforgery token sent in a hea and `[HtmxRequest]` does not match. A cross-origin response is opaque, so HTMX cannot read its headers and swaps an empty body into the target. +The mode applies to all requests: HTMX ignores a `mode` set on an element with `hx-config`. Changing this setting does not configure CORS on the ASP.NET Core server. ## History behavior diff --git a/src/Ramstack.HtmxToolkit/Configuration/HtmxFetchMode.cs b/src/Ramstack.HtmxToolkit/Configuration/HtmxRequestMode.cs similarity index 85% rename from src/Ramstack.HtmxToolkit/Configuration/HtmxFetchMode.cs rename to src/Ramstack.HtmxToolkit/Configuration/HtmxRequestMode.cs index 013c7bc..36f22ca 100644 --- a/src/Ramstack.HtmxToolkit/Configuration/HtmxFetchMode.cs +++ b/src/Ramstack.HtmxToolkit/Configuration/HtmxRequestMode.cs @@ -4,14 +4,17 @@ namespace Ramstack.HtmxToolkit.Configuration; /// Specifies the request mode used by HTMX. /// /// -/// In HTMX 4.x, this is passed as the mode option of the Fetch API. +/// +/// In HTMX 4.x, this is passed as the mode option of the Fetch API. The mode applies to all requests: +/// HTMX ignores a mode set on an element, so it is configured only with . +/// /// /// HTMX 1.9.x and 2.x use XMLHttpRequest instead of fetch. /// Use or /// to restrict requests to the current origin. /// /// -public enum HtmxFetchMode +public enum HtmxRequestMode { /// /// Allows requests only to the current origin. diff --git a/src/Ramstack.HtmxToolkit/Configuration/HtmxV4Config.cs b/src/Ramstack.HtmxToolkit/Configuration/HtmxV4Config.cs index 1889704..9ff162d 100644 --- a/src/Ramstack.HtmxToolkit/Configuration/HtmxV4Config.cs +++ b/src/Ramstack.HtmxToolkit/Configuration/HtmxV4Config.cs @@ -166,10 +166,10 @@ public int? DefaultTimeout /// /// Gets or sets the request mode passed to the Fetch API. - /// The HTMX default is . + /// The HTMX default is . /// - [JsonConverter(typeof(HtmxFetchModeJsonConverter))] - public HtmxFetchMode? Mode + [JsonConverter(typeof(HtmxRequestModeJsonConverter))] + public HtmxRequestMode? Mode { get; set => SetField(ref field, value); diff --git a/src/Ramstack.HtmxToolkit/Internal/EnumHelper.cs b/src/Ramstack.HtmxToolkit/Internal/EnumHelper.cs index 9179602..300c91d 100644 --- a/src/Ramstack.HtmxToolkit/Internal/EnumHelper.cs +++ b/src/Ramstack.HtmxToolkit/Internal/EnumHelper.cs @@ -136,43 +136,43 @@ or HtmxHttpVerb.Trace } /// - /// Converts a value + /// Converts a value /// to the corresponding Fetch API request mode string. /// - /// The value. + /// The value. /// /// same-origin, cors, or no-cors. /// - public static string GetFetchModeValue(this HtmxFetchMode value) + public static string GetRequestModeValue(this HtmxRequestMode value) { Debug.Assert(value - is HtmxFetchMode.SameOrigin - or HtmxFetchMode.Cors - or HtmxFetchMode.NoCors); + is HtmxRequestMode.SameOrigin + or HtmxRequestMode.Cors + or HtmxRequestMode.NoCors); return value switch { - HtmxFetchMode.SameOrigin => "same-origin", - HtmxFetchMode.Cors => "cors", + HtmxRequestMode.SameOrigin => "same-origin", + HtmxRequestMode.Cors => "cors", _ => "no-cors" }; } /// - /// Parses a string into a value. + /// Parses a string into a value. /// /// The string to parse. /// - /// The parsed value if successful; + /// The parsed value if successful; /// otherwise, . /// - public static HtmxFetchMode? ParseHtmxFetchMode(string? expression) + public static HtmxRequestMode? ParseHtmxRequestMode(string? expression) { return expression switch { - "same-origin" => HtmxFetchMode.SameOrigin, - "cors" => HtmxFetchMode.Cors, - "no-cors" => HtmxFetchMode.NoCors, + "same-origin" => HtmxRequestMode.SameOrigin, + "cors" => HtmxRequestMode.Cors, + "no-cors" => HtmxRequestMode.NoCors, _ => null }; } diff --git a/src/Ramstack.HtmxToolkit/Serialization/HtmxFetchModeJsonConverter.cs b/src/Ramstack.HtmxToolkit/Serialization/HtmxRequestModeJsonConverter.cs similarity index 55% rename from src/Ramstack.HtmxToolkit/Serialization/HtmxFetchModeJsonConverter.cs rename to src/Ramstack.HtmxToolkit/Serialization/HtmxRequestModeJsonConverter.cs index 73542f2..2ba879e 100644 --- a/src/Ramstack.HtmxToolkit/Serialization/HtmxFetchModeJsonConverter.cs +++ b/src/Ramstack.HtmxToolkit/Serialization/HtmxRequestModeJsonConverter.cs @@ -7,19 +7,19 @@ namespace Ramstack.HtmxToolkit.Serialization; /// -/// Represents a for nullable values. +/// Represents a for nullable values. /// -internal sealed class HtmxFetchModeJsonConverter : JsonConverter +internal sealed class HtmxRequestModeJsonConverter : JsonConverter { /// - public override HtmxFetchMode? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => + public override HtmxRequestMode? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotSupportedException(); /// - public override void Write(Utf8JsonWriter writer, HtmxFetchMode? value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, HtmxRequestMode? value, JsonSerializerOptions options) { // NOTE: value is never null here: null-valued properties are omitted // by JsonIgnoreCondition.WhenWritingNull before this converter is invoked. - writer.WriteStringValue(value.GetValueOrDefault().GetFetchModeValue()); + writer.WriteStringValue(value.GetValueOrDefault().GetRequestModeValue()); } } diff --git a/tests/Ramstack.HtmxToolkit.Tests/Internal/EnumHelperTests.cs b/tests/Ramstack.HtmxToolkit.Tests/Internal/EnumHelperTests.cs index e764bcb..5a8398a 100644 --- a/tests/Ramstack.HtmxToolkit.Tests/Internal/EnumHelperTests.cs +++ b/tests/Ramstack.HtmxToolkit.Tests/Internal/EnumHelperTests.cs @@ -101,9 +101,9 @@ public void GetWsBinaryTypeValue_ReturnsExpectedString(HtmxBinaryType value, str public void GetScrollBehaviorValue_ReturnsExpectedString(HtmxScrollBehavior value, string expected) => Assert.That(value.GetScrollBehaviorValue(), Is.EqualTo(expected)); - [TestCase(HtmxFetchMode.SameOrigin, "same-origin")] - [TestCase(HtmxFetchMode.Cors, "cors")] - [TestCase(HtmxFetchMode.NoCors, "no-cors")] - public void GetFetchModeValue_ReturnsExpectedString(HtmxFetchMode value, string expected) => - Assert.That(value.GetFetchModeValue(), Is.EqualTo(expected)); + [TestCase(HtmxRequestMode.SameOrigin, "same-origin")] + [TestCase(HtmxRequestMode.Cors, "cors")] + [TestCase(HtmxRequestMode.NoCors, "no-cors")] + public void GetRequestModeValue_ReturnsExpectedString(HtmxRequestMode value, string expected) => + Assert.That(value.GetRequestModeValue(), Is.EqualTo(expected)); } diff --git a/tests/Ramstack.HtmxToolkit.Tests/TagHelpers/HtmxConfigTagHelperTests.cs b/tests/Ramstack.HtmxToolkit.Tests/TagHelpers/HtmxConfigTagHelperTests.cs index 69cf25d..75ac172 100644 --- a/tests/Ramstack.HtmxToolkit.Tests/TagHelpers/HtmxConfigTagHelperTests.cs +++ b/tests/Ramstack.HtmxToolkit.Tests/TagHelpers/HtmxConfigTagHelperTests.cs @@ -334,7 +334,7 @@ public async Task ProcessAsync_SerializesOnlyHtmx4Options() htmx.Extensions = "sse, ws"; htmx.ImplicitInheritance = false; htmx.DefaultTimeout = 5000; - htmx.Mode = HtmxFetchMode.NoCors; + htmx.Mode = HtmxRequestMode.NoCors; htmx.DefaultFocusScroll = true; htmx.Transitions = true; htmx.MorphIgnore = ["data-htmx-powered"];