diff --git a/src/Ramstack.HtmxToolkit/HtmxFieldValues.cs b/src/Ramstack.HtmxToolkit/HtmxFieldValues.cs index 85b87b5..7374749 100644 --- a/src/Ramstack.HtmxToolkit/HtmxFieldValues.cs +++ b/src/Ramstack.HtmxToolkit/HtmxFieldValues.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Text.Json.Serialization; @@ -82,6 +83,7 @@ public HtmxFieldValues(string[]? values) => /// /// An containing the specified values. /// + [SuppressMessage("ReSharper", "UseCollectionExpression")] public static HtmxFieldValues Create(ReadOnlySpan values) { return values.Length switch @@ -100,6 +102,7 @@ public static HtmxFieldValues Create(ReadOnlySpan values) /// /// An containing . /// + [SuppressMessage("ReSharper", "UseCollectionExpression")] public static implicit operator HtmxFieldValues(string? value) => new(value); @@ -110,6 +113,7 @@ public static implicit operator HtmxFieldValues(string? value) => /// /// An containing . /// + [SuppressMessage("ReSharper", "UseCollectionExpression")] public static implicit operator HtmxFieldValues(string[]? values) => new(values); diff --git a/src/Ramstack.HtmxToolkit/wwwroot/htmx-toolkit.js b/src/Ramstack.HtmxToolkit/wwwroot/htmx-toolkit.js index cf5eb38..46e7858 100644 --- a/src/Ramstack.HtmxToolkit/wwwroot/htmx-toolkit.js +++ b/src/Ramstack.HtmxToolkit/wwwroot/htmx-toolkit.js @@ -159,15 +159,15 @@ document._r_htmx ||= ((document, htmx) => { // HTMX reads hx-request from the element and its ancestors; the nearest value wins. // Values computed with "js:" cannot be read without evaluating them, so they are skipped. - const no_headers = elt => { + const has_no_headers = elt => { let result = false; api.getClosestMatch(elt, e => { let value = api.getAttributeValue(e, "hx-request")?.trim(); if (value && !/^(js|javascript):/.test(value)) { try { - let { noHeaders } = JSON.parse(value[0] === "{" ? value : `{${value}}`); - if (noHeaders != null) { - result = !!noHeaders; + let no_headers = JSON.parse(value[0] === "{" ? value : `{${value}}`).noHeaders; + if (no_headers != null) { + result = !!no_headers; return true; } } @@ -189,7 +189,7 @@ document._r_htmx ||= ((document, htmx) => { let elt = e.target; let { xhr, target, select, requestConfig } = e.detail; - if (requestConfig.headers["HX-Request-Type"] == null && !no_headers(elt)) { + if (requestConfig.headers["HX-Request-Type"] == null && !has_no_headers(elt)) { select ||= api.getClosestAttributeValue(elt, "hx-select"); let request_type = target === document.body || select && select !== "unset" ? "full" : "partial"; xhr.setRequestHeader("HX-Request-Type", request_type); diff --git a/src/Ramstack.HtmxToolkit/wwwroot/htmx-toolkit.min.js b/src/Ramstack.HtmxToolkit/wwwroot/htmx-toolkit.min.js index 46d3d55..74a8ae0 100644 --- a/src/Ramstack.HtmxToolkit/wwwroot/htmx-toolkit.min.js +++ b/src/Ramstack.HtmxToolkit/wwwroot/htmx-toolkit.min.js @@ -1 +1 @@ -document._r_htmx||=((e,t)=>{const r=e=>console.warn(`ramstack.htmxtoolkit: ${e}`),n=parseInt(t.version);let a;const o=e=>{let t=new DocumentFragment;for(;e.firstChild;)t.append(e.firstChild);return t};t.defineExtension&&t.defineExtension("ramstack-swap",{init(e){a=e},isInlineSwap:e=>"outerMorph"===e||"outerSync"===e,handleSwap(e,t,n){if("textContent"===e)return t.textContent=n.textContent,[t];let a="innerMorph"===e?"innerHTML":"outerMorph"===e?"outerHTML":null;if(a){let i=globalThis.Idiomorph;if(i?.morph)return i.morph(t,n.children,{morphStyle:a});r(`Idiomorph is unavailable; falling back from ${e} to ${a}`);let l=[...n.childNodes],s=o(n);return"innerHTML"===a?t.replaceChildren(s):t.replaceWith(s),l}if("outerSync"===e){r("outerSync requires HTMX 4.x; falling back to attribute sync and innerHTML");let e=n.firstElementChild;if(e){for(let r of[...t.attributes])e.hasAttribute(r.name)||t.removeAttribute(r.name);for(let r of e.attributes)t.setAttribute(r.name,r.value);return t.replaceChildren(o(e)),[t]}}}});const i=(t,r)=>{e.addEventListener(t,r)},l=e=>{let t=e.querySelector("meta[name='htmx-config']")?.dataset||{};return{headerName:t.antiforgeryHeaderName,formFieldName:t.antiforgeryFormFieldName,requestToken:t.antiforgeryRequestToken}};let s=l(e);const u=(t,r,n,a)=>{if(!/^get$/i.test(t)&&(t=>{try{return new URL(t,e.baseURI).origin===location.origin}catch{return!1}})(r)){const{headerName:e,formFieldName:t,requestToken:r}=s;r&&(a.has?.(t)||a[t]||(e?n[e]=r:a.set?a.set(t,r):a[t]=r))}},d=e=>{let t=(new DOMParser).parseFromString(e||"","text/html"),r=l(t);r.requestToken&&(s=r)};return i("htmx:afterOnLoad",e=>{let t=e.detail;t.boosted&&d(t.xhr.responseText)}),i("htmx:after:request",e=>{let t=e.detail.ctx;t.boosted&&d(t.text)}),i("htmx:configRequest",e=>{let t=e.detail;u(t.verb,t.path,t.headers,t.parameters)}),i("htmx:config:request",e=>{let t=e.detail.ctx.request;u(t.method,t.action,t.headers,t.body)}),i("htmx:beforeRequest",t=>{if(4>n){let r=t.target,{xhr:n,target:o,select:i,requestConfig:l}=t.detail;null!=l.headers["HX-Request-Type"]||(e=>{let t=!1;return a.getClosestMatch(e,e=>{let r=a.getAttributeValue(e,"hx-request")?.trim();if(r&&!/^(js|javascript):/.test(r))try{let{noHeaders:e}=JSON.parse("{"===r[0]?r:`{${r}}`);if(null!=e)return t=!!e,!0}catch{}}),t})(r)||(i||=a.getClosestAttributeValue(r,"hx-select"),n.setRequestHeader("HX-Request-Type",o===e.body||i&&"unset"!==i?"full":"partial"))}}),i("rs:event",e=>{let r=e.target;for(let{key:a,value:o}of e.detail.value||e.detail){let e=r;4>n?"[object Object]"===Object.prototype.toString.call(o)?2===n&&void 0!==o.target&&(r=e=o.target):o={value:o}:(o?.target&&(e=t.find(o.target)),"object"!=typeof o&&(o={value:o})),t.trigger(e,a,o)}}),!0})(document,htmx); \ No newline at end of file +document._r_htmx||=((e,t)=>{const r=e=>console.warn(`ramstack.htmxtoolkit: ${e}`),n=parseInt(t.version);let a;const o=e=>{let t=new DocumentFragment;for(;e.firstChild;)t.append(e.firstChild);return t};t.defineExtension&&t.defineExtension("ramstack-swap",{init(e){a=e},isInlineSwap:e=>"outerMorph"===e||"outerSync"===e,handleSwap(e,t,n){if("textContent"===e)return t.textContent=n.textContent,[t];let a="innerMorph"===e?"innerHTML":"outerMorph"===e?"outerHTML":null;if(a){let i=globalThis.Idiomorph;if(i?.morph)return i.morph(t,n.children,{morphStyle:a});r(`Idiomorph is unavailable; falling back from ${e} to ${a}`);let l=[...n.childNodes],s=o(n);return"innerHTML"===a?t.replaceChildren(s):t.replaceWith(s),l}if("outerSync"===e){r("outerSync requires HTMX 4.x; falling back to attribute sync and innerHTML");let e=n.firstElementChild;if(e){for(let r of[...t.attributes])e.hasAttribute(r.name)||t.removeAttribute(r.name);for(let r of e.attributes)t.setAttribute(r.name,r.value);return t.replaceChildren(o(e)),[t]}}}});const i=(t,r)=>{e.addEventListener(t,r)},l=e=>{let t=e.querySelector("meta[name='htmx-config']")?.dataset||{};return{headerName:t.antiforgeryHeaderName,formFieldName:t.antiforgeryFormFieldName,requestToken:t.antiforgeryRequestToken}};let s=l(e);const u=(t,r,n,a)=>{if(!/^get$/i.test(t)&&(t=>{try{return new URL(t,e.baseURI).origin===location.origin}catch{return!1}})(r)){const{headerName:e,formFieldName:t,requestToken:r}=s;r&&(a.has?.(t)||a[t]||(e?n[e]=r:a.set?a.set(t,r):a[t]=r))}},d=e=>{let t=(new DOMParser).parseFromString(e||"","text/html"),r=l(t);r.requestToken&&(s=r)};return i("htmx:afterOnLoad",e=>{let t=e.detail;t.boosted&&d(t.xhr.responseText)}),i("htmx:after:request",e=>{let t=e.detail.ctx;t.boosted&&d(t.text)}),i("htmx:configRequest",e=>{let t=e.detail;u(t.verb,t.path,t.headers,t.parameters)}),i("htmx:config:request",e=>{let t=e.detail.ctx.request;u(t.method,t.action,t.headers,t.body)}),i("htmx:beforeRequest",t=>{if(4>n){let r=t.target,{xhr:n,target:o,select:i,requestConfig:l}=t.detail;null!=l.headers["HX-Request-Type"]||(e=>{let t=!1;return a.getClosestMatch(e,e=>{let r=a.getAttributeValue(e,"hx-request")?.trim();if(r&&!/^(js|javascript):/.test(r))try{let e=JSON.parse("{"===r[0]?r:`{${r}}`).noHeaders;if(null!=e)return t=!!e,!0}catch{}}),t})(r)||(i||=a.getClosestAttributeValue(r,"hx-select"),n.setRequestHeader("HX-Request-Type",o===e.body||i&&"unset"!==i?"full":"partial"))}}),i("rs:event",e=>{let r=e.target;for(let{key:a,value:o}of e.detail.value||e.detail){let e=r;4>n?"[object Object]"===Object.prototype.toString.call(o)?2===n&&void 0!==o.target&&(r=e=o.target):o={value:o}:(o?.target&&(e=t.find(o.target)),"object"!=typeof o&&(o={value:o})),t.trigger(e,a,o)}}),!0})(document,htmx); \ No newline at end of file