`);
+ }
+})();
diff --git a/src/Ramstack.HtmxToolkit/Assets/htmx-toolkit.js b/src/Ramstack.HtmxToolkit/Assets/htmx-toolkit.js
index f954ee8..2233f54 100644
--- a/src/Ramstack.HtmxToolkit/Assets/htmx-toolkit.js
+++ b/src/Ramstack.HtmxToolkit/Assets/htmx-toolkit.js
@@ -25,9 +25,9 @@ document._r_htmx ||= ((document, htmx) => {
});
document.addEventListener("_r_proxy", e => {
- for (let kvp of e.detail)
+ for (let kvp of e.detail.value) {
htmx.trigger(e.target, kvp.key, kvp.value);
+ }
});
-
return true;
})(document, htmx);
diff --git a/src/Ramstack.HtmxToolkit/Assets/htmx-toolkit.min.js b/src/Ramstack.HtmxToolkit/Assets/htmx-toolkit.min.js
index 8703d23..671f04a 100644
--- a/src/Ramstack.HtmxToolkit/Assets/htmx-toolkit.min.js
+++ b/src/Ramstack.HtmxToolkit/Assets/htmx-toolkit.min.js
@@ -1 +1 @@
-document._r_htmx||=((e,t)=>(e.addEventListener("htmx:afterOnLoad",e=>{if(e.detail.boosted){const r=(new DOMParser).parseFromString(e.detail.xhr.responseText,"text/html").querySelector("meta[name='htmx-config']");r&&(t.config.antiForgery=JSON.parse(r.content).antiForgery)}}),e.addEventListener("htmx:configRequest",e=>{if(!/^get$/i.test(e.detail.verb)){const{headerName:r,formFieldName:a,requestToken:n}=t.config.antiForgery??{};n&&!e.detail.parameters[a]&&(r?e.detail.headers[r]=n:e.detail.parameters[a]=n)}}),e.addEventListener("_r_proxy",e=>{for(let r of e.detail)t.trigger(e.target,r.key,r.value)}),!0))(document,htmx);
\ No newline at end of file
+document._r_htmx||=((e,t)=>(e.addEventListener("htmx:afterOnLoad",e=>{if(e.detail.boosted){const r=(new DOMParser).parseFromString(e.detail.xhr.responseText,"text/html").querySelector("meta[name='htmx-config']");r&&(t.config.antiForgery=JSON.parse(r.content).antiForgery)}}),e.addEventListener("htmx:configRequest",e=>{if(!/^get$/i.test(e.detail.verb)){const{headerName:r,formFieldName:a,requestToken:n}=t.config.antiForgery??{};n&&!e.detail.parameters[a]&&(r?e.detail.headers[r]=n:e.detail.parameters[a]=n)}}),e.addEventListener("_r_proxy",e=>{for(let r of e.detail.value)t.trigger(e.target,r.key,r.value)}),!0))(document,htmx);
\ No newline at end of file
diff --git a/src/Ramstack.HtmxToolkit/Ramstack.HtmxToolkit.csproj b/src/Ramstack.HtmxToolkit/Ramstack.HtmxToolkit.csproj
index f9b5bec..bfb969f 100644
--- a/src/Ramstack.HtmxToolkit/Ramstack.HtmxToolkit.csproj
+++ b/src/Ramstack.HtmxToolkit/Ramstack.HtmxToolkit.csproj
@@ -1,6 +1,6 @@
- net6.0;net8.0
+ net6.0Enables seamless integration of HTMX with ASP.NET Core (https://htmx.org).enableenable
diff --git a/src/Ramstack.HtmxToolkit/TagHelpers/HtmxConfigJsonSerializerContext.cs b/src/Ramstack.HtmxToolkit/TagHelpers/HtmxConfigJsonSerializerContext.cs
index b1d7520..d02b71a 100644
--- a/src/Ramstack.HtmxToolkit/TagHelpers/HtmxConfigJsonSerializerContext.cs
+++ b/src/Ramstack.HtmxToolkit/TagHelpers/HtmxConfigJsonSerializerContext.cs
@@ -1,4 +1,3 @@
-#if NET8_0_OR_GREATER
using System.Text.Json.Serialization;
namespace Ramstack.HtmxToolkit.TagHelpers;
@@ -8,8 +7,5 @@ namespace Ramstack.HtmxToolkit.TagHelpers;
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
GenerationMode = JsonSourceGenerationMode.Serialization)]
-[JsonSerializable(typeof(HtmxConfigTagHelper.HtmxConfiguration))]
-[JsonSerializable(typeof(HtmxConfigTagHelper.AntiForgeryTokenData?))]
-[JsonSerializable(typeof(IList))]
+[JsonSerializable(typeof(HtmxConfigTagHelper.HtmxConfigData))]
internal partial class HtmxConfigJsonSerializerContext : JsonSerializerContext;
-#endif
diff --git a/src/Ramstack.HtmxToolkit/TagHelpers/HtmxConfigTagHelper.cs b/src/Ramstack.HtmxToolkit/TagHelpers/HtmxConfigTagHelper.cs
index 5d56999..56bcfcf 100644
--- a/src/Ramstack.HtmxToolkit/TagHelpers/HtmxConfigTagHelper.cs
+++ b/src/Ramstack.HtmxToolkit/TagHelpers/HtmxConfigTagHelper.cs
@@ -1,4 +1,3 @@
-using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using Microsoft.AspNetCore.Antiforgery;
@@ -19,13 +18,7 @@ namespace Ramstack.HtmxToolkit.TagHelpers;
[HtmlTargetElement("htmx-config", TagStructure = TagStructure.NormalOrSelfClosing)]
public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
{
- private readonly IAntiforgery _antiforgery = antiforgery;
-
- ///
- /// The key used to pass items between
- /// and this tag helper via .
- ///
- internal const string ResponseHandlingEntriesKey = "Htmx_ResponseHandlingEntries";
+ private readonly HtmxConfigData _config = new();
///
/// Gets or sets a value indicating whether history is enabled.
@@ -35,14 +28,22 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
/// Supported in HTMX 1.x and 2.x. This is mainly useful for testing.
///
[HtmlAttributeName("history-enabled")]
- public bool? HistoryEnabled { get; set; }
+ public bool? HistoryEnabled
+ {
+ get => _config.HistoryEnabled;
+ set => _config.HistoryEnabled = value;
+ }
///
/// Gets or sets the size of the history cache. Defaults to 10.
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("history-cache-size")]
- public int? HistoryCacheSize { get; set; }
+ public int? HistoryCacheSize
+ {
+ get => _config.HistoryCacheSize;
+ set => _config.HistoryCacheSize = value;
+ }
///
/// Gets or sets a value indicating whether a full page refresh
@@ -51,7 +52,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("refresh-on-history-miss")]
- public bool? RefreshOnHistoryMiss { get; set; }
+ public bool? RefreshOnHistoryMiss
+ {
+ get => _config.RefreshOnHistoryMiss;
+ set => _config.RefreshOnHistoryMiss = value;
+ }
///
/// Gets or sets the default swap style.
@@ -59,21 +64,34 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("default-swap-style")]
- public HtmxSwap? DefaultSwapStyle { get; set; }
+ public HtmxSwap? DefaultSwapStyle
+ {
+ // NOTE: The getter exists primarily for debugging; performance is not a concern here.
+ get => EnumHelper.ParseHtmxSwap(_config.DefaultSwapStyle);
+ set => _config.DefaultSwapStyle = value.GetSwapValue();
+ }
///
/// Gets or sets the default swap delay. Defaults to 0.
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("default-swap-delay")]
- public int? DefaultSwapDelay { get; set; }
+ public int? DefaultSwapDelay
+ {
+ get => _config.DefaultSwapDelay;
+ set => _config.DefaultSwapDelay = value;
+ }
///
/// Gets or sets the default settle delay. Defaults to 20.
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("default-settle-delay")]
- public int? DefaultSettleDelay { get; set; }
+ public int? DefaultSettleDelay
+ {
+ get => _config.DefaultSettleDelay;
+ set => _config.DefaultSettleDelay = value;
+ }
///
/// Gets or sets a value indicating whether the indicator styles are loaded.
@@ -81,42 +99,66 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("include-indicator-styles")]
- public bool? IncludeIndicatorStyles { get; set; }
+ public bool? IncludeIndicatorStyles
+ {
+ get => _config.IncludeIndicatorStyles;
+ set => _config.IncludeIndicatorStyles = value;
+ }
///
/// Gets or sets the indicator class. Defaults to htmx-indicator.
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("indicator-class")]
- public string? IndicatorClass { get; set; }
+ public string? IndicatorClass
+ {
+ get => _config.IndicatorClass;
+ set => _config.IndicatorClass = value;
+ }
///
/// Gets or sets the request class. Defaults to htmx-request.
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("request-class")]
- public string? RequestClass { get; set; }
+ public string? RequestClass
+ {
+ get => _config.RequestClass;
+ set => _config.RequestClass = value;
+ }
///
/// Gets or sets the added class. Defaults to htmx-added.
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("added-class")]
- public string? AddedClass { get; set; }
+ public string? AddedClass
+ {
+ get => _config.AddedClass;
+ set => _config.AddedClass = value;
+ }
///
/// Gets or sets the swapping class. Defaults to htmx-swapping.
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("swapping-class")]
- public string? SwappingClass { get; set; }
+ public string? SwappingClass
+ {
+ get => _config.SwappingClass;
+ set => _config.SwappingClass = value;
+ }
///
/// Gets or sets the settling class. Defaults to htmx-settling.
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("settling-class")]
- public string? SettlingClass { get; set; }
+ public string? SettlingClass
+ {
+ get => _config.SettlingClass;
+ set => _config.SettlingClass = value;
+ }
///
/// Gets or sets a value indicating whether eval is allowed.
@@ -124,7 +166,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("allow-eval")]
- public bool? AllowEval { get; set; }
+ public bool? AllowEval
+ {
+ get => _config.AllowEval;
+ set => _config.AllowEval = value;
+ }
///
/// Gets or sets a value indicating whether script tags should be processed in new content.
@@ -132,7 +178,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("allow-script-tags")]
- public bool? AllowScriptTags { get; set; }
+ public bool? AllowScriptTags
+ {
+ get => _config.AllowScriptTags;
+ set => _config.AllowScriptTags = value;
+ }
///
/// Gets or sets a value meaning that no nonce will be added to inline scripts.
@@ -140,7 +190,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("inline-script-nonce")]
- public string? InlineScriptNonce { get; set; }
+ public string? InlineScriptNonce
+ {
+ get => _config.InlineScriptNonce;
+ set => _config.InlineScriptNonce = value;
+ }
///
/// Gets or sets a value meaning that no nonce will be added to inline styles.
@@ -148,7 +202,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported only in HTMX 2.x.
[HtmlAttributeName("inline-style-nonce")]
- public string? InlineStyleNonce { get; set; }
+ public string? InlineStyleNonce
+ {
+ get => _config.InlineStyleNonce;
+ set => _config.InlineStyleNonce = value;
+ }
///
/// Gets or sets the attributes to settle during the settling phase.
@@ -156,7 +214,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("attributes-to-settle")]
- public string[]? AttributesToSettle { get; set; }
+ public string[]? AttributesToSettle
+ {
+ get => _config.AttributesToSettle;
+ set => _config.AttributesToSettle = value;
+ }
///
/// Gets or sets a value indicating whether HTML template tags should be used for parsing content.
@@ -164,14 +226,22 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported only in HTMX 1.x. Removed in HTMX 2.x.
[HtmlAttributeName("use-template-fragments")]
- public bool? UseTemplateFragments { get; set; }
+ public bool? UseTemplateFragments
+ {
+ get => _config.UseTemplateFragments;
+ set => _config.UseTemplateFragments = value;
+ }
///
/// Gets or sets the WebSocket reconnect delay. Defaults to full-jitter.
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("ws-reconnect-delay")]
- public string? WsReconnectDelay { get; set; }
+ public string? WsReconnectDelay
+ {
+ get => _config.WsReconnectDelay;
+ set => _config.WsReconnectDelay = value;
+ }
///
/// Gets or sets the type of binary data
@@ -179,7 +249,12 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("ws-binary-type")]
- public HtmxBinaryType? WsBinaryType { get; set; }
+ public HtmxBinaryType? WsBinaryType
+ {
+ // NOTE: The getter exists primarily for debugging; performance is not a concern here.
+ get => Enum.TryParse(_config.WsBinaryType ?? "", true, out var v) ? v : null;
+ set => _config.WsBinaryType = value?.GetWsBinaryTypeValue();
+ }
///
/// Gets or sets the "disable" selector.
@@ -188,7 +263,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("disable-selector")]
- public string? DisableSelector { get; set; }
+ public string? DisableSelector
+ {
+ get => _config.DisableSelector;
+ set => _config.DisableSelector = value;
+ }
///
/// Gets or sets the value that allows cross-site Access-Control requests
@@ -197,7 +276,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("with-credentials")]
- public bool? WithCredentials { get; set; }
+ public bool? WithCredentials
+ {
+ get => _config.WithCredentials;
+ set => _config.WithCredentials = value;
+ }
///
/// Gets or sets a value indicating whether htmx attribute inheritance is disabled.
@@ -207,7 +290,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported only in HTMX 2.x.
[HtmlAttributeName("disable-inheritance")]
- public bool? DisableInheritance { get; set; }
+ public bool? DisableInheritance
+ {
+ get => _config.DisableInheritance;
+ set => _config.DisableInheritance = value;
+ }
///
/// Gets or sets the number of milliseconds a request can take before automatically being terminated.
@@ -215,7 +302,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("timeout")]
- public int? Timeout { get; set; }
+ public int? Timeout
+ {
+ get => _config.Timeout;
+ set => _config.Timeout = value;
+ }
///
/// Gets or sets a value indicating the behavior for a boosted link on page transitions.
@@ -224,7 +315,12 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("scroll-behavior")]
- public HtmxScrollBehavior? ScrollBehavior { get; set; }
+ public HtmxScrollBehavior? ScrollBehavior
+ {
+ // NOTE: The getter exists primarily for debugging; performance is not a concern here.
+ get => Enum.TryParse(_config.ScrollBehavior ?? "", true, out var v) ? v : null;
+ set => _config.ScrollBehavior = value?.GetScrollBehaviorValue();
+ }
///
/// Gets or sets a value indicating whether the focused element should be scrolled into view.
@@ -232,7 +328,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("default-focus-scroll")]
- public bool? DefaultFocusScroll { get; set; }
+ public bool? DefaultFocusScroll
+ {
+ get => _config.DefaultFocusScroll;
+ set => _config.DefaultFocusScroll = value;
+ }
///
/// Gets or sets a value indicating whether a cache‑busting parameter
@@ -245,7 +345,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
/// where the target element is appended to the GET request.
///
[HtmlAttributeName("get-cache-buster-param")]
- public bool? GetCacheBusterParam { get; set; }
+ public bool? GetCacheBusterParam
+ {
+ get => _config.GetCacheBusterParam;
+ set => _config.GetCacheBusterParam = value;
+ }
///
/// Gets or sets a value indicating whether the
@@ -255,7 +359,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("global-view-transitions")]
- public bool? GlobalViewTransitions { get; set; }
+ public bool? GlobalViewTransitions
+ {
+ get => _config.GlobalViewTransitions;
+ set => _config.GlobalViewTransitions = value;
+ }
///
/// Gets or sets a list of HTTP methods that use URL parameters.
@@ -269,7 +377,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
///
[HtmlAttributeName("methods-that-use-url-params")]
- public string[]? MethodsThatUseUrlParams { get; set; }
+ public string[]? MethodsThatUseUrlParams
+ {
+ get => _config.MethodsThatUseUrlParams;
+ set => _config.MethodsThatUseUrlParams = value;
+ }
///
/// Gets or sets a value indicating whether AJAX requests should be allowed only
@@ -278,7 +390,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("self-requests-only")]
- public bool? SelfRequestsOnly { get; set; }
+ public bool? SelfRequestsOnly
+ {
+ get => _config.SelfRequestsOnly;
+ set => _config.SelfRequestsOnly = value;
+ }
///
/// Gets or sets a value indicating whether htmx should not update the title of the document
@@ -286,7 +402,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("ignore-title")]
- public bool? IgnoreTitle { get; set; }
+ public bool? IgnoreTitle
+ {
+ get => _config.IgnoreTitle;
+ set => _config.IgnoreTitle = value;
+ }
///
/// Gets or sets a value indicating whether the target of a boosted element
@@ -296,7 +416,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("scroll-into-view-on-boost")]
- public bool? ScrollIntoViewOnBoost { get; set; }
+ public bool? ScrollIntoViewOnBoost
+ {
+ get => _config.ScrollIntoViewOnBoost;
+ set => _config.ScrollIntoViewOnBoost = value;
+ }
///
/// Gets or sets the cache to store evaluated trigger specifications into,
@@ -306,7 +430,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported in HTMX 1.x and 2.x.
[HtmlAttributeName("trigger-specs-cache")]
- public string? TriggerSpecsCache { get; set; }
+ public string? TriggerSpecsCache
+ {
+ get => _config.TriggerSpecsCache;
+ set => _config.TriggerSpecsCache = value;
+ }
///
/// Gets or sets the default response handling behavior for HTTP response status codes.
@@ -315,7 +443,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported only in HTMX 2.x.
[HtmlAttributeName("response-handling")]
- public IList? ResponseHandling { get; set; }
+ public IList? ResponseHandling
+ {
+ get => _config.ResponseHandling;
+ set => _config.ResponseHandling = value;
+ }
///
/// Gets or sets a value indicating whether to process OOB swaps
@@ -324,7 +456,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported only in HTMX 2.x.
[HtmlAttributeName("allow-nested-oob-swaps")]
- public bool? AllowNestedOobSwaps { get; set; }
+ public bool? AllowNestedOobSwaps
+ {
+ get => _config.AllowNestedOobSwaps;
+ set => _config.AllowNestedOobSwaps = value;
+ }
///
/// Gets or sets a value indicating whether to treat history cache miss
@@ -335,7 +471,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported only in HTMX 2.x.
[HtmlAttributeName("history-restore-as-hx-request")]
- public bool? HistoryRestoreAsHxRequest { get; set; }
+ public bool? HistoryRestoreAsHxRequest
+ {
+ get => _config.HistoryRestoreAsHxRequest;
+ set => _config.HistoryRestoreAsHxRequest = value;
+ }
///
/// Gets or sets a value indicating whether to report input validation errors
@@ -345,7 +485,11 @@ public sealed class HtmxConfigTagHelper(IAntiforgery antiforgery) : TagHelper
///
/// Supported only in HTMX 2.x.
[HtmlAttributeName("report-validity-of-forms")]
- public bool? ReportValidityOfForms { get; set; }
+ public bool? ReportValidityOfForms
+ {
+ get => _config.ReportValidityOfForms;
+ set => _config.ReportValidityOfForms = value;
+ }
///
/// Gets or sets a value indicating whether an antiforgery token should be included.
@@ -372,94 +516,66 @@ public override async Task ProcessAsync(TagHelperContext context, TagHelperOutpu
output.TagMode = TagMode.SelfClosing;
output.Attributes.SetAttribute("name", "htmx-config");
+ context.Items[typeof(HtmxConfigTagHelper)] = this;
await output.GetChildContentAsync();
- if (context.Items.TryGetValue(ResponseHandlingEntriesKey, out var value))
- if (value is List entries && entries.Count != 0)
- ResponseHandling = entries;
+ if (IncludeAntiForgeryToken)
+ _config.AntiForgery = antiforgery.GetAndStoreTokens(ViewContext.HttpContext);
- #if NET8_0_OR_GREATER
- var config = new HtmlString(
- JsonSerializer.Serialize(
- new HtmxConfiguration(this),
- HtmxConfigJsonSerializerContext.Default.HtmxConfiguration));
- #else
var config = new HtmlString(
JsonSerializer.Serialize(
- new HtmxConfiguration(this),
- JsonOptions.CamelCase));
- #endif
+ _config,
+ HtmxConfigJsonSerializerContext.Default.HtmxConfigData));
output.Attributes.SetAttribute(
new TagHelperAttribute("content", config, HtmlAttributeValueStyle.SingleQuotes));
}
- #region Inner type: HtmxConfiguration
-
- ///
- /// Represents a proxy structure for the class.
- ///
- [SuppressMessage("ReSharper", "UnusedMember.Local")]
- internal readonly struct HtmxConfiguration(HtmxConfigTagHelper helper)
- {
- public bool? HistoryEnabled => helper.HistoryEnabled;
- public int? HistoryCacheSize => helper.HistoryCacheSize;
- public bool? RefreshOnHistoryMiss => helper.RefreshOnHistoryMiss;
- public string? DefaultSwapStyle => helper.DefaultSwapStyle.GetSwapValue();
- public int? DefaultSwapDelay => helper.DefaultSwapDelay;
- public int? DefaultSettleDelay => helper.DefaultSettleDelay;
- public bool? IncludeIndicatorStyles => helper.IncludeIndicatorStyles;
- public string? IndicatorClass => helper.IndicatorClass;
- public string? RequestClass => helper.RequestClass;
- public string? AddedClass => helper.AddedClass;
- public string? SettlingClass => helper.SettlingClass;
- public string? SwappingClass => helper.SwappingClass;
- public bool? AllowEval => helper.AllowEval;
- public bool? AllowScriptTags => helper.AllowScriptTags;
- public string? InlineScriptNonce => helper.InlineScriptNonce;
- public string? InlineStyleNonce => helper.InlineStyleNonce;
- public string[]? AttributesToSettle => helper.AttributesToSettle;
- public bool? UseTemplateFragments => helper.UseTemplateFragments;
- public string? WsReconnectDelay => helper.WsReconnectDelay;
- public string? WsBinaryType => helper.WsBinaryType?.GetWsBinaryTypeValue();
- public string? DisableSelector => helper.DisableSelector;
- public bool? WithCredentials => helper.WithCredentials;
- public bool? DisableInheritance => helper.DisableInheritance;
- public int? Timeout => helper.Timeout;
- public string? ScrollBehavior => helper.ScrollBehavior?.GetScrollBehaviorValue();
- public bool? DefaultFocusScroll => helper.DefaultFocusScroll;
- public bool? GetCacheBusterParam => helper.GetCacheBusterParam;
- public bool? GlobalViewTransitions => helper.GlobalViewTransitions;
- public string[]? MethodsThatUseUrlParams => helper.MethodsThatUseUrlParams;
- public bool? SelfRequestsOnly => helper.SelfRequestsOnly;
- public bool? IgnoreTitle => helper.IgnoreTitle;
- public bool? ScrollIntoViewOnBoost => helper.ScrollIntoViewOnBoost;
- public string? TriggerSpecsCache => helper.TriggerSpecsCache;
- public IList? ResponseHandling => helper.ResponseHandling;
- public bool? AllowNestedOobSwaps => helper.AllowNestedOobSwaps;
- public bool? HistoryRestoreAsHxRequest => helper.HistoryRestoreAsHxRequest;
- public bool? ReportValidityOfForms => helper.ReportValidityOfForms;
- public AntiForgeryTokenData? AntiForgery => GetAntiForgeryToken(helper);
-
- private static AntiForgeryTokenData? GetAntiForgeryToken(HtmxConfigTagHelper h) =>
- h.IncludeAntiForgeryToken
- ? new AntiForgeryTokenData(h._antiforgery.GetAndStoreTokens(h.ViewContext.HttpContext))
- : null;
- }
-
- #endregion
-
- #region Inner type: AntiForgeryTokenData
+ #region Inner type: HtmxConfigData
///
- /// Represents a proxy structure for the class.
+ /// Represents the serializable configuration data for the class.
///
- [SuppressMessage("ReSharper", "UnusedMember.Local")]
- internal readonly struct AntiForgeryTokenData(AntiforgeryTokenSet antiforgery)
+ internal sealed class HtmxConfigData
{
- public string? HeaderName => antiforgery.HeaderName;
- public string FormFieldName => antiforgery.FormFieldName;
- public string? RequestToken => antiforgery.RequestToken;
+ public bool? HistoryEnabled { get; set; }
+ public int? HistoryCacheSize { get; set; }
+ public bool? RefreshOnHistoryMiss { get; set; }
+ public string? DefaultSwapStyle { get; set; }
+ public int? DefaultSwapDelay { get; set; }
+ public int? DefaultSettleDelay { get; set; }
+ public bool? IncludeIndicatorStyles { get; set; }
+ public string? IndicatorClass { get; set; }
+ public string? RequestClass { get; set; }
+ public string? AddedClass { get; set; }
+ public string? SwappingClass { get; set; }
+ public string? SettlingClass { get; set; }
+ public bool? AllowEval { get; set; }
+ public bool? AllowScriptTags { get; set; }
+ public string? InlineScriptNonce { get; set; }
+ public string? InlineStyleNonce { get; set; }
+ public string[]? AttributesToSettle { get; set; }
+ public bool? UseTemplateFragments { get; set; }
+ public string? WsReconnectDelay { get; set; }
+ public string? WsBinaryType { get; set; }
+ public string? DisableSelector { get; set; }
+ public bool? WithCredentials { get; set; }
+ public bool? DisableInheritance { get; set; }
+ public int? Timeout { get; set; }
+ public string? ScrollBehavior { get; set; }
+ public bool? DefaultFocusScroll { get; set; }
+ public bool? GetCacheBusterParam { get; set; }
+ public bool? GlobalViewTransitions { get; set; }
+ public string[]? MethodsThatUseUrlParams { get; set; }
+ public bool? SelfRequestsOnly { get; set; }
+ public bool? IgnoreTitle { get; set; }
+ public bool? ScrollIntoViewOnBoost { get; set; }
+ public string? TriggerSpecsCache { get; set; }
+ public IList? ResponseHandling { get; set; }
+ public bool? AllowNestedOobSwaps { get; set; }
+ public bool? HistoryRestoreAsHxRequest { get; set; }
+ public bool? ReportValidityOfForms { get; set; }
+ public AntiforgeryTokenSet? AntiForgery { get; set; }
}
#endregion
diff --git a/src/Ramstack.HtmxToolkit/TagHelpers/ResponseHandlingEntryTagHelper.cs b/src/Ramstack.HtmxToolkit/TagHelpers/ResponseHandlingEntryTagHelper.cs
index f767981..29faa3d 100644
--- a/src/Ramstack.HtmxToolkit/TagHelpers/ResponseHandlingEntryTagHelper.cs
+++ b/src/Ramstack.HtmxToolkit/TagHelpers/ResponseHandlingEntryTagHelper.cs
@@ -11,69 +11,88 @@ namespace Ramstack.HtmxToolkit.TagHelpers;
[HtmlTargetElement("response-handling", ParentTag = "htmx-config", TagStructure = TagStructure.WithoutEndTag)]
public sealed class ResponseHandlingEntryTagHelper : TagHelper
{
+ private readonly ResponseHandlingEntry _entry = new();
+
///
/// Gets or sets a regular expression that will be tested against response status codes.
///
[HtmlAttributeName("code")]
- public string? Code { get; set; }
+ public string? Code
+ {
+ get => _entry.Code;
+ set => _entry.Code = value;
+ }
///
/// Gets or sets a value indicating whether the response should be swapped into the DOM.
///
[HtmlAttributeName("swap")]
- public bool? Swap { get; set; }
+ public bool? Swap
+ {
+ get => _entry.Swap;
+ set => _entry.Swap = value;
+ }
///
/// Gets or sets a value indicating whether htmx should treat this response as an error.
///
[HtmlAttributeName("error")]
- public bool? Error { get; set; }
+ public bool? Error
+ {
+ get => _entry.Error;
+ set => _entry.Error = value;
+ }
///
/// Gets or sets a value indicating whether htmx should ignore title tags in the response.
///
[HtmlAttributeName("ignore-title")]
- public bool? IgnoreTitle { get; set; }
+ public bool? IgnoreTitle
+ {
+ get => _entry.IgnoreTitle;
+ set => _entry.IgnoreTitle = value;
+ }
///
/// Gets or sets a CSS selector to use to select content from the response.
///
[HtmlAttributeName("select")]
- public string? Select { get; set; }
+ public string? Select
+ {
+ get => _entry.Select;
+ set => _entry.Select = value;
+ }
///
/// Gets or sets a CSS selector specifying an alternative target for the response.
///
[HtmlAttributeName("target")]
- public string? Target { get; set; }
+ public string? Target
+ {
+ get => _entry.Target;
+ set => _entry.Target = value;
+ }
///
/// Gets or sets an alternative swap mechanism for the response.
///
[HtmlAttributeName("swap-override")]
- public string? SwapOverride { get; set; }
+ public string? SwapOverride
+ {
+ get => _entry.SwapOverride;
+ set => _entry.SwapOverride = value;
+ }
///
public override void Process(TagHelperContext context, TagHelperOutput output)
{
- if (!context.Items.TryGetValue(HtmxConfigTagHelper.ResponseHandlingEntriesKey, out var value))
- {
- value = new List();
- context.Items[HtmxConfigTagHelper.ResponseHandlingEntriesKey] = value;
- }
-
- if (value is List entries)
+ if (context.Items.TryGetValue(typeof(HtmxConfigTagHelper), out var value))
{
- entries.Add(new ResponseHandlingEntry
+ if (value is HtmxConfigTagHelper config)
{
- Code = Code,
- Swap = Swap,
- Error = Error,
- IgnoreTitle = IgnoreTitle,
- Select = Select,
- Target = Target,
- SwapOverride = SwapOverride
- });
+ config.ResponseHandling ??= new List();
+ config.ResponseHandling.Add(_entry);
+ }
}
output.SuppressOutput();