all repos — searchix @ 6b98722a6098b85d3f913a95e3bf7b0cee29eb7b

Search engine for NixOS, nix-darwin, home-manager and NUR users

fix: Combined pagination fix, construct page titles correctly, history set incorrectly in certain cases

Kaya
commit

6b98722a6098b85d3f913a95e3bf7b0cee29eb7b

parent

342121cc03e7ecb8ce68fd445dbf4a60fddf7a52

M frontend/static/search.jsfrontend/static/search.js
@@ -6,7 +6,7 @@ const results = document.getElementById("results");
let pagination = document.getElementById("pagination"); let facets = document.querySelector(".facets"); let titleParts = document.title.split(/ [\p{Dash}] /u); -let siteTitle = titleParts.slice(titleParts.length > 1 ? 1 : 0).join(" ‐ "); +let siteTitle = titleParts.at(-1); const resultsRange = new Range(); resultsRange.setStart(results, 0);
@@ -22,11 +22,19 @@ const pageHistory = {
state: null, init() { - const url = new URL(location); - this.state = history.state || { - url: url.toString(), - title: document.title, - input: url.searchParams.get("query"), + this.state = history.state?.searchState || history.state || this.snapshot(); + if (history.state == null) { + this.replace(location.href); + } + }, + + snapshot(url = location.href, title = document.title) { + const stateURL = new URL(url, location.href); + + return { + url: stateURL.toString(), + title, + input: stateURL.searchParams.get("query"), results: resultsRange.cloneContents().innerHTML || null, }; },
@@ -111,16 +119,27 @@ *
* @param {string|null} title * @param {boolean} updateState */ +function setDocumentTitle(title) { + if (!title) { + document.title = siteTitle; + } else if (title.endsWith(siteTitle)) { + document.title = title; + } else { + document.title = `${title} ${siteTitle}`; + } +} + function updateTitle(title, updateState) { if (title) { title = title.replaceAll("‐", "\u2010"); - document.title = title + " " + siteTitle; if (updateState) { pageHistory.state.title = title; } } else { - document.title = pageHistory.state.title; + title = pageHistory.state.title; } + + setDocumentTitle(title); } /**
@@ -297,7 +316,15 @@
// If the dialog was open via js or via ssr const closeLink = dialog.querySelector("a.button"); if (closeLink) { - pageHistory.state.url = closeLink.href; + pageHistory.state = pageHistory.snapshot( + closeLink.href, + dialog.dataset.searchTitle || pageHistory.state.title, + ); + history.replaceState( + { detail: true, searchState: pageHistory.state }, + null, + location.href, + ); } dialog.showModal();
@@ -314,13 +341,13 @@ detailUrl.searchParams.delete("query");
getDetail(detailUrl); } else if (ev.state != null) { pageHistory.restore(ev.state); - document.title = pageHistory.state.title || siteTitle; + setDocumentTitle(pageHistory.state.title); if (pageHistory.state.results !== null) { queryInput.value = pageHistory.state.input; renderResults(pageHistory.state.results); } } else { - document.title = siteTitle; + setDocumentTitle(""); resultsRange.deleteContents(); search.reset(); }
M internal/components/data.gointernal/components/data.go
@@ -27,6 +27,7 @@ Assets *frontend.AssetCollection
SearchNav SearchNav DetailContent g.Node SearchURL string + SearchTitle string } type ResultData struct {
M internal/components/search.gointernal/components/search.go
@@ -114,6 +114,7 @@ ),
Dialog( ID("dialog"), g.If(tdata.DetailContent != nil, g.Attr("open")), + g.If(tdata.SearchTitle != "", g.Attr("data-search-title", tdata.SearchTitle)), g.If(tdata.DetailContent != nil, A(Class("button"), Href(tdata.SearchURL), AutoFocus(), g.Text("Close")), Button(AutoFocus(), g.Text("Close")),
M internal/server/global.gointernal/server/global.go
@@ -6,6 +6,7 @@ "encoding/xml"
"fmt" "math" "net/http" + "net/url" "strconv" "alin.ovh/x/log"
@@ -56,6 +57,17 @@
return h } +func searchURL(source config.Source) *url.URL { + if source.Importer == config.All { + return &url.URL{Path: "/"} + } + + searchURL := *source.LocalURL() + searchURL.Path += "search" + + return &searchURL +} + func (g *GlobalHandler) ExecuteSearch( source config.Source, r *http.Request,
@@ -124,8 +136,7 @@ if source.Importer != config.All {
searchDesc += " in " + source.Name } - searchURL := *source.LocalURL() - searchURL.Path += "search" + searchURL := searchURL(source) searchQuery := r.URL.Query() searchQuery.Del("scoped") searchURL.RawQuery = searchQuery.Encode()
@@ -140,7 +151,7 @@ Query: qs,
Title: g.getTitle(source, qs), Description: searchDesc, BaseURL: g.cfg.Web.BaseURL, - SearchNav: components.NewSearchNav(searchURL).WithPagination(page), + SearchNav: components.NewSearchNav(*searchURL).WithPagination(page), }, Query: qs, FacetQueries: facets,
M internal/server/source.gointernal/server/source.go
@@ -100,10 +100,12 @@ w.Header().Add("Title", h.getTitle(doc))
baseErr = components.Detail(doc).Render(w) } else if searchResult, _, searchErr := h.global.ExecuteSearch(h.searchSource(r), r); searchErr == nil && searchResult != nil { + searchTitle := searchResult.Title searchResult.Title = h.getTitle(doc) searchResult.Description = components.MetaDescription(doc) searchResult.DetailContent = components.Detail(doc) searchResult.SearchURL = h.closeURL(r) + searchResult.SearchTitle = searchTitle baseErr = components.ResultsPage(*searchResult).Render(w) } else { tdata := components.TemplateData{