Skip to content

Commit 076f450

Browse files
committed
Account for anchors when appending version hash
1 parent cf4cd4e commit 076f450

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

src/Elastic.Documentation.Site/Htmx.cs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,70 @@
44

55
using System.Reflection;
66
using System.Text;
7+
using System.Text.Encodings.Web;
78
using Elastic.Documentation.Extensions;
89

910
namespace Elastic.Documentation.Site;
1011

12+
public static class UrlHelper
13+
{
14+
private static readonly KeyValuePair<string, string?>[] VersionParameters = [new("v", Htmx.VersionHash)];
15+
16+
public static string AddVersionParameters(string uri) => AddQueryString(uri, VersionParameters);
17+
18+
/// <summary>
19+
/// Append the given query keys and values to the URI.
20+
/// </summary>
21+
/// <param name="uri">The base URI.</param>
22+
/// <param name="queryString">A collection of name value query pairs to append.</param>
23+
/// <returns>The combined result.</returns>
24+
/// <exception cref="ArgumentNullException"><paramref name="uri"/> is <c>null</c>.</exception>
25+
/// <exception cref="ArgumentNullException"><paramref name="queryString"/> is <c>null</c>.</exception>
26+
public static string AddQueryString(
27+
string uri,
28+
IEnumerable<KeyValuePair<string, string?>> queryString)
29+
{
30+
ArgumentNullException.ThrowIfNull(uri);
31+
ArgumentNullException.ThrowIfNull(queryString);
32+
33+
var anchorIndex = uri.IndexOf('#');
34+
var uriToBeAppended = uri.AsSpan();
35+
var anchorText = ReadOnlySpan<char>.Empty;
36+
// If there is an anchor, then the query string must be inserted before its first occurrence.
37+
if (anchorIndex != -1)
38+
{
39+
anchorText = uriToBeAppended.Slice(anchorIndex);
40+
uriToBeAppended = uriToBeAppended.Slice(0, anchorIndex);
41+
}
42+
43+
var queryIndex = uriToBeAppended.IndexOf('?');
44+
var hasQuery = queryIndex != -1;
45+
46+
var sb = new StringBuilder();
47+
_ = sb.Append(uriToBeAppended);
48+
foreach (var parameter in queryString)
49+
{
50+
if (parameter.Value == null)
51+
continue;
52+
53+
_ = sb.Append(hasQuery ? '&' : '?')
54+
.Append(UrlEncoder.Default.Encode(parameter.Key))
55+
.Append('=')
56+
.Append(UrlEncoder.Default.Encode(parameter.Value));
57+
hasQuery = true;
58+
}
59+
60+
_ = sb.Append(anchorText);
61+
return sb.ToString();
62+
}
63+
}
64+
1165
public static class Htmx
1266
{
1367
private static readonly string Version =
1468
Assembly.GetExecutingAssembly().GetCustomAttributes<AssemblyInformationalVersionAttribute>()
1569
.FirstOrDefault()?.InformationalVersion ?? "0.0.0";
70+
1671
public static readonly string VersionHash = ShortId.Create(Version);
1772

1873
public static string GetHxSelectOob(bool hasSameTopLevelGroup) => hasSameTopLevelGroup ? "#content-container,#toc-nav" : "#main-container";
@@ -31,7 +86,8 @@ public static string GetHxAttributes(
3186
string? hxIndicator = HxIndicator
3287
)
3388
{
34-
var hxGetUrl = targetUrl.Contains('?') ? $"{targetUrl}&v={VersionHash}" : $"{targetUrl}?v={VersionHash}";
89+
var hxGetUrl = UrlHelper.AddVersionParameters(targetUrl);
90+
3591
var attributes = new StringBuilder();
3692
_ = attributes.Append($" hx-get={hxGetUrl}");
3793
_ = attributes.Append($" hx-select-oob={hxSwapOob ?? GetHxSelectOob(hasSameTopLevelGroup)}");

src/Elastic.Markdown/Myst/Renderers/HtmxLinkInlineRenderer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ protected override void Write(HtmlRenderer renderer, LinkInline link)
3030
var url = link.GetDynamicUrl?.Invoke() ?? link.Url;
3131
var hxGetUrl = url;
3232
if (hxGetUrl is not null)
33-
hxGetUrl = hxGetUrl.Contains('?') ? $"{hxGetUrl}&v={Htmx.VersionHash}" : $"{hxGetUrl}?v={Htmx.VersionHash}";
33+
hxGetUrl = UrlHelper.AddVersionParameters(hxGetUrl);
3434

3535
var isCrossLink = (link.GetData("isCrossLink") as bool?) == true;
3636
var isHttpLink = url?.StartsWith("http") ?? false;

0 commit comments

Comments
 (0)