mirror of
https://github.com/vinta/awesome-python.git
synced 2026-05-09 22:53:49 +08:00
feat(website): switch index filter URLs from querystring to path
Tag clicks on / pushState a category/group/subcategory path; on static pages they fully navigate. Search and sort stay in querystring. Built-in source tag has no data-url and stays as an in-page filter. The isIndexDocument flag is captured at load time so toggling on the index keeps working after pushState changes location.pathname. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+52
-10
@@ -167,19 +167,39 @@ function applyFilters() {
|
|||||||
updateURL();
|
updateURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateURL() {
|
const filterUrlsScript = document.getElementById("filter-urls");
|
||||||
|
const filterToUrl = filterUrlsScript
|
||||||
|
? JSON.parse(filterUrlsScript.textContent)
|
||||||
|
: {};
|
||||||
|
const urlToFilter = {};
|
||||||
|
Object.keys(filterToUrl).forEach(function (k) {
|
||||||
|
urlToFilter[filterToUrl[k]] = k;
|
||||||
|
});
|
||||||
|
|
||||||
|
const isIndexDocument =
|
||||||
|
location.pathname === "/" || location.pathname === "/index.html";
|
||||||
|
|
||||||
|
function isIndexPage() {
|
||||||
|
return isIndexDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildQueryString() {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
const query = searchInput ? searchInput.value.trim() : "";
|
const query = searchInput ? searchInput.value.trim() : "";
|
||||||
if (query) params.set("q", query);
|
if (query) params.set("q", query);
|
||||||
if (activeFilter) {
|
|
||||||
params.set("filter", activeFilter);
|
|
||||||
}
|
|
||||||
if (activeSort.col !== "stars" || activeSort.order !== "desc") {
|
if (activeSort.col !== "stars" || activeSort.order !== "desc") {
|
||||||
params.set("sort", activeSort.col);
|
params.set("sort", activeSort.col);
|
||||||
params.set("order", activeSort.order);
|
params.set("order", activeSort.order);
|
||||||
}
|
}
|
||||||
const qs = params.toString();
|
const qs = params.toString();
|
||||||
history.replaceState(null, "", qs ? "?" + qs : location.pathname);
|
return qs ? "?" + qs : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateURL() {
|
||||||
|
if (!isIndexPage()) return;
|
||||||
|
const path =
|
||||||
|
activeFilter && filterToUrl[activeFilter] ? filterToUrl[activeFilter] : "/";
|
||||||
|
history.replaceState(null, "", path + buildQueryString());
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSortValue(row, col) {
|
function getSortValue(row, col) {
|
||||||
@@ -288,8 +308,21 @@ tags.forEach(function (tag) {
|
|||||||
tag.addEventListener("click", function (e) {
|
tag.addEventListener("click", function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const value = tag.dataset.value;
|
const value = tag.dataset.value;
|
||||||
activeFilter = activeFilter === value ? null : value;
|
const url = tag.dataset.url;
|
||||||
applyFilters();
|
if (isIndexPage()) {
|
||||||
|
activeFilter = activeFilter === value ? null : value;
|
||||||
|
if (activeFilter && url) {
|
||||||
|
history.pushState(null, "", url + buildQueryString());
|
||||||
|
} else {
|
||||||
|
history.pushState(null, "", "/" + buildQueryString());
|
||||||
|
}
|
||||||
|
applyFilters();
|
||||||
|
} else if (url) {
|
||||||
|
window.location.href = url;
|
||||||
|
} else {
|
||||||
|
activeFilter = activeFilter === value ? null : value;
|
||||||
|
applyFilters();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -396,19 +429,28 @@ if (backToTop) {
|
|||||||
(function () {
|
(function () {
|
||||||
const params = new URLSearchParams(location.search);
|
const params = new URLSearchParams(location.search);
|
||||||
const q = params.get("q");
|
const q = params.get("q");
|
||||||
const filter = params.get("filter");
|
|
||||||
const sort = params.get("sort");
|
const sort = params.get("sort");
|
||||||
const order = params.get("order");
|
const order = params.get("order");
|
||||||
if (q && searchInput) searchInput.value = q;
|
if (q && searchInput) searchInput.value = q;
|
||||||
if (filter) activeFilter = filter;
|
|
||||||
if (
|
if (
|
||||||
(sort === "name" || sort === "stars" || sort === "commit-time") &&
|
(sort === "name" || sort === "stars" || sort === "commit-time") &&
|
||||||
(order === "desc" || order === "asc")
|
(order === "desc" || order === "asc")
|
||||||
) {
|
) {
|
||||||
activeSort = { col: sort, order: order };
|
activeSort = { col: sort, order: order };
|
||||||
}
|
}
|
||||||
if (q || filter || sort) {
|
if (isIndexPage()) {
|
||||||
|
const matched = urlToFilter[location.pathname];
|
||||||
|
if (matched) activeFilter = matched;
|
||||||
|
}
|
||||||
|
if (q || activeFilter || sort) {
|
||||||
sortRows();
|
sortRows();
|
||||||
}
|
}
|
||||||
updateSortIndicators();
|
updateSortIndicators();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
window.addEventListener("popstate", function () {
|
||||||
|
if (!isIndexPage()) return;
|
||||||
|
const matched = urlToFilter[location.pathname];
|
||||||
|
activeFilter = matched || null;
|
||||||
|
applyFilters();
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user