Fully remove search

This commit is contained in:
david-swift 2025-02-27 17:03:23 +01:00
parent e511f83749
commit 5c26b8a4a2
9 changed files with 3 additions and 502 deletions

View File

@ -171,7 +171,6 @@
}
a,
#search button,
#language-switcher summary,
#theme-switcher summary,
#theme-switcher button,
@ -264,15 +263,6 @@
}
}
#search .icon {
-webkit-mask-image: var(--icon-search);
mask-image: var(--icon-search);
:root[dir*="rtl"] & {
transform: scaleX(-1);
}
}
#feed .icon {
-webkit-mask-image: var(--icon-feed);
mask-image: var(--icon-feed);
@ -336,108 +326,4 @@
}
}
}
#search-container {
transform: scale(0.5) translateY(-2.75rem);
opacity: 0;
transition: var(--transition);
padding: 0 0.5rem 0;
height: 0;
pointer-events: none;
&.active {
transform: none;
opacity: 1;
padding: 0 0.5rem 0.5rem;
height: 2.75rem;
pointer-events: all;
}
}
#search-bar {
box-shadow: var(--edge-highlight);
border: none;
border-radius: 999px;
background: var(--fg-muted-1);
padding: 0 0.75rem;
width: 100%;
height: 2.25rem;
color: inherit;
font-size: var(--font-size-medium);
&::placeholder {
opacity: 1;
color: var(--fg-muted-4);
}
}
#search-results-container {
-webkit-backdrop-filter: var(--blur);
display: flex;
position: absolute;
backdrop-filter: var(--blur);
inset-block-start: calc(100% + 0.5rem);
inset-inline-start: 0;
box-shadow: var(--edge-highlight), var(--shadow-glass);
border-radius: calc(var(--rounded-corner) + 0.5rem);
background-color: var(--glass-bg);
width: 100%;
max-height: 50vh;
}
#search-results {
--mask: linear-gradient(to bottom,
transparent,
black 1rem,
black calc(100% - 1rem),
transparent);
-webkit-mask-image: var(--mask);
display: none;
flex: 1;
flex-direction: column;
gap: 0.5rem;
mask-image: var(--mask);
padding: 0.5rem;
overflow: auto;
.item {
display: inline-flex;
flex-direction: column;
box-shadow: var(--edge-highlight);
border-radius: var(--rounded-corner);
background-color: var(--fg-muted-1);
padding: 0.5rem;
a {
width: fit-content;
&::after {
content: "";
:root[dir*="rtl"] & {
content: "";
}
}
}
span {
color: var(--fg-muted-5);
&:first-of-type,
&.more-matches {
margin-block-start: 0.5rem;
border-block-start: max(1px, 0.0625rem) solid var(--fg-muted-2);
padding-block-start: 0.25rem;
}
&.more-matches {
font-size: var(--font-size-small);
}
strong {
color: var(--fg-color);
}
}
}
}
}

View File

@ -154,16 +154,6 @@
margin: 0;
}
//
// 1. Correct the odd appearance in Chrome, Edge, and Safari.
// 2. Correct the outline style in Safari.
//
:where(input[type="search" i]) {
-webkit-appearance: textfield; // 1
outline-offset: -2px; // 2
}
//
// Correct the cursor style of increment and decrement buttons in Safari.
//
@ -182,14 +172,6 @@
color: inherit;
}
//
// Remove the inner padding in Chrome, Edge, and Safari on macOS.
//
::-webkit-search-decoration {
-webkit-appearance: none;
}
//
// 1. Correct the inability to style upload buttons in iOS and Safari.
// 2. Change font properties to `inherit` in Safari.

View File

@ -189,7 +189,6 @@
--icon-poop: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8.963 1.514A4 4 0 0 1 5 5H4c-1.108 0-2 .892-2 2s.892 2 2 2H3c-1.662 0-3 1.338-3 3s1.338 3 3 3h10c1.662 0 3-1.338 3-3s-1.338-3-3-3h-1c1.108 0 2-.892 2-2s-.892-2-2-2h-1a4 4 0 0 0-2.037-3.486'/%3E%3C/svg%3E");
--icon-previous: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='m9.293 13.707-5-5a1 1 0 0 1 0-1.414l5-5a1 1 0 1 1 1.414 1.414L6.414 8l4.293 4.293a1 1 0 1 1-1.414 1.414m0 0'/%3E%3C/svg%3E");
--icon-right: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='m5.707 1.293 6 6a1 1 0 0 1 0 1.414l-6 6a1 1 0 1 1-1.414-1.414L9.586 8 4.293 2.707a1 1 0 1 1 1.414-1.414m0 0'/%3E%3C/svg%3E");
--icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M6.57.063c-3.578 0-6.5 2.921-6.5 6.5 0 3.578 2.922 6.5 6.5 6.5a6.46 6.46 0 0 0 3.83-1.256l2.975 2.974c.957.938 2.363-.5 1.406-1.437l-2.96-2.961a6.46 6.46 0 0 0 1.25-3.82c0-3.579-2.923-6.5-6.5-6.5m0 2c2.5 0 4.5 2.003 4.5 4.5 0 2.5-2 4.5-4.5 4.5-2.496 0-4.5-2-4.5-4.5 0-2.497 2.004-4.5 4.5-4.5'/%3E%3C/svg%3E");
--icon-share: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8 1a1 1 0 0 0-.5.135 1 1 0 0 0-.207.158l-3 3a1 1 0 0 0 0 1.414 1 1 0 0 0 1.414 0L7 4.414V10a1 1 0 0 0 1 1 1 1 0 0 0 1-1V4.414l1.293 1.293a1 1 0 0 0 1.414 0 1 1 0 0 0 0-1.414L8.738 1.326 8.7 1.287a1 1 0 0 0-.195-.15l-.008-.004a1 1 0 0 0-.236-.098h-.004A1 1 0 0 0 8 1M4 7c-1.645 0-3 1.355-3 3v2c0 1.645 1.355 3 3 3h8c1.645 0 3-1.355 3-3v-2c0-1.645-1.355-3-3-3a1 1 0 0 0 0 2c.564 0 1 .436 1 1v2c0 .564-.436 1-1 1H4c-.564 0-1-.436-1-1v-2c0-.564.436-1 1-1a1 1 0 0 0 0-2'/%3E%3C/svg%3E");
--icon-star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M8 0a1 1 0 0 0-.95.684l-1.448 4.34-4.59-.016C.032 5.004-.371 6.266.43 6.828l3.625 2.555-1.5 4.285c-.317.902.687 1.691 1.492 1.172l4.004-2.594 3.894 2.586c.801.531 1.817-.258 1.5-1.16l-1.504-4.29 3.645-2.577c.789-.563.394-1.809-.574-1.813l-4.66-.015L8.949.69A1 1 0 0 0 8 0m0 0'/%3E%3C/svg%3E");
--icon-theme-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M.918 8.004a7.072 7.072 0 0 0 14.102.793 1.01 1.01 0 0 0-.457-.957 1 1 0 0 0-1.063-.004 3.9 3.9 0 0 1-2.031.578 3.89 3.89 0 0 1-3.883-3.883c0-.715.203-1.422.578-2.031a1 1 0 0 0-.004-1.062c-.207-.32-.578-.5-.957-.458A7.07 7.07 0 0 0 .918 8.004M5.586 4.53a5.877 5.877 0 0 0 8.965 5.004l-1.52-.96a5.09 5.09 0 0 1-5.035 4.507 5.09 5.09 0 0 1-5.078-5.078 5.09 5.09 0 0 1 4.508-5.035l-.961-1.52a5.9 5.9 0 0 0-.88 3.082m0 0'/%3E%3C/svg%3E");

View File

@ -10,8 +10,7 @@
border-radius: 0;
}
nav,
#search-container {
nav {
margin: 0 auto;
width: min(var(--container-width), 90%);
}
@ -19,7 +18,6 @@
nav ul li {
a,
summary,
&#search button,
&#language-switcher details summary,
&#theme-switcher details summary {
border-radius: var(--rounded-corner);
@ -33,10 +31,4 @@
.divider {
display: none;
}
#search-container {
#search-bar {
border-radius: var(--rounded-corner);
}
}
}

View File

@ -29,7 +29,6 @@
e: !!(vars.event || goatcounter.event),
s: [window.screen.width, window.screen.height, (window.devicePixelRatio || 1)],
b: is_bot(),
q: location.search,
}
var rcb, pcb, tcb // Save callbacks to apply later.
@ -99,7 +98,7 @@
if (a.hostname.replace(/^www\./, '') === location.hostname.replace(/^www\./, ''))
loc = a
}
return (loc.pathname + loc.search) || '/'
return (loc.pathname) || '/'
}
// Run function after DOM is loaded.
@ -167,14 +166,6 @@
}
}
// Get a query parameter.
window.goatcounter.get_query = function(name) {
var s = location.search.substr(1).split('&')
for (var i = 0; i < s.length; i++)
if (s[i].toLowerCase().indexOf(name.toLowerCase() + '=') === 0)
return s[i].substr(name.length + 1)
}
// Track click events.
window.goatcounter.bind_events = function() {
if (!document.querySelectorAll) // Just in case someone uses an ancient browser.

File diff suppressed because one or more lines are too long

View File

@ -1,209 +0,0 @@
// Based on https://github.com/getzola/zola/blob/1ac1231de1e342bbaf4d7a51a8a9a40ea152e246/docs/static/search.js
function debounce(func, wait) {
var timeout;
return function () {
var context = this;
var args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function () {
timeout = null;
func.apply(context, args);
}, wait);
};
}
// Taken from mdbook
// The strategy is as follows:
// First, assign a value to each word in the document:
// Words that correspond to search terms (stemmer aware): 40
// Normal words: 2
// First word in a sentence: 8
// Then use a sliding window with a constant number of words and count the
// sum of the values of the words within the window. Then use the window that got the
// maximum sum. If there are multiple maximas, then get the last one.
// Enclose the terms in <b>.
function makeTeaser(body, terms) {
var TERM_WEIGHT = 40;
var NORMAL_WORD_WEIGHT = 2;
var FIRST_WORD_WEIGHT = 8;
var TEASER_MAX_WORDS = 30;
var stemmedTerms = terms.map(function (w) {
return elasticlunr.stemmer(w.toLowerCase());
});
var termFound = false;
var index = 0;
var weighted = []; // contains elements of ["word", weight, index_in_document]
// split in sentences, then words
var sentences = body.toLowerCase().split(". ");
for (var i in sentences) {
var words = sentences[i].split(" ");
var value = FIRST_WORD_WEIGHT;
for (var j in words) {
var word = words[j];
if (word.length > 0) {
for (var k in stemmedTerms) {
if (elasticlunr.stemmer(word).startsWith(stemmedTerms[k])) {
value = TERM_WEIGHT;
termFound = true;
}
}
weighted.push([word, value, index]);
value = NORMAL_WORD_WEIGHT;
}
index += word.length;
index += 1; // ' ' or '.' if last word in sentence
}
index += 1; // because we split at a two-char boundary '. '
}
if (weighted.length === 0) {
return body;
}
var windowWeights = [];
var windowSize = Math.min(weighted.length, TEASER_MAX_WORDS);
// We add a window with all the weights first
var curSum = 0;
for (var i = 0; i < windowSize; i++) {
curSum += weighted[i][1];
}
windowWeights.push(curSum);
for (var i = 0; i < weighted.length - windowSize; i++) {
curSum -= weighted[i][1];
curSum += weighted[i + windowSize][1];
windowWeights.push(curSum);
}
// If we didn't find the term, just pick the first window
var maxSumIndex = 0;
if (termFound) {
var maxFound = 0;
// backwards
for (var i = windowWeights.length - 1; i >= 0; i--) {
if (windowWeights[i] > maxFound) {
maxFound = windowWeights[i];
maxSumIndex = i;
}
}
}
var teaser = [];
var startIndex = weighted[maxSumIndex][2];
for (var i = maxSumIndex; i < maxSumIndex + windowSize; i++) {
var word = weighted[i];
if (startIndex < word[2]) {
// missing text from index to start of `word`
teaser.push(body.substring(startIndex, word[2]));
startIndex = word[2];
}
// add <strong> around search terms
if (word[1] === TERM_WEIGHT) {
teaser.push("<strong>");
}
startIndex = word[2] + word[0].length;
teaser.push(body.substring(word[2], startIndex));
if (word[1] === TERM_WEIGHT) {
teaser.push("</strong>");
}
}
teaser.push("…");
return teaser.join("");
}
function formatSearchResultItem(item, terms) {
return '<div class="item">'
+ `<a href="${item.ref}">${item.doc.title}</a>`
+ `<span>${makeTeaser(item.doc.body, terms)}</span>`
+ '</div>';
}
function initSearch() {
var searchBar = document.getElementById("search-bar");
var searchContainer = document.getElementById("search-container");
var searchResults = document.getElementById("search-results");
var MAX_ITEMS = 10;
var options = {
bool: "AND",
fields: {
title: { boost: 2 },
body: { boost: 1 },
}
};
var currentTerm = "";
var index;
var initIndex = async function () {
if (index === undefined) {
let searchIndex = document.getElementById("search-index").textContent;
index = fetch(searchIndex)
.then(
async function (response) {
return await elasticlunr.Index.load(await response.json());
}
);
}
let res = await index;
return res;
}
searchBar.addEventListener("keyup", debounce(async function () {
var term = searchBar.value.trim();
if (term === currentTerm) {
return;
}
searchResults.style.display = term === "" ? "none" : "flex";
searchResults.innerHTML = "";
currentTerm = term;
if (term === "") {
return;
}
var results = (await initIndex()).search(term, options);
if (results.length === 0) {
searchResults.style.display = "none";
return;
}
for (var i = 0; i < Math.min(results.length, MAX_ITEMS); i++) {
searchResults.innerHTML += formatSearchResultItem(results[i], term.split(" "));
}
}, 150));
document.addEventListener("keydown", function (event) {
if (event.key === "/") {
event.preventDefault();
toggleSearch();
}
});
document.getElementById("search-toggle").addEventListener("click", toggleSearch);
}
function toggleSearch() {
var searchContainer = document.getElementById("search-container");
var searchBar = document.getElementById("search-bar");
searchContainer.classList.toggle("active");
searchBar.toggleAttribute("disabled");
searchBar.focus();
}
if (document.readyState === "complete" ||
(document.readyState !== "loading" && !document.documentElement.doScroll)
) {
initSearch();
} else {
document.addEventListener("DOMContentLoaded", initSearch);
}

View File

@ -1,127 +0,0 @@
// Based on https://codeberg.org/daudix/duckquill/issues/101#issuecomment-2377169
let searchSetup = false;
let fuse;
async function initIndex() {
if (searchSetup) return;
const url = document.getElementById("search-index").textContent;
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const options = {
includeScore: false,
includeMatches: true,
ignoreLocation: true,
threshold: 0.15,
keys: [
{ name: "title", weight: 3 },
{ name: "description", weight: 2 },
{ name: "body", weight: 1 }
]
};
fuse = new Fuse(await response.json(), options);
searchSetup = true;
console.log("Search index initialized successfully");
}
function toggleSearch() {
initIndex();
const searchBar = document.getElementById("search-bar");
const searchContainer = document.getElementById("search-container");
const searchResults = document.getElementById("search-results");
searchContainer.classList.toggle("active");
searchBar.toggleAttribute("disabled");
searchBar.focus();
}
function debounce(actual_fn, wait) {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
actual_fn(...args);
}, wait);
};
};
function initSearch() {
const searchBar = document.getElementById("search-bar");
const searchResults = document.getElementById("search-results");
const searchContainer = document.getElementById("search-container");
const MAX_ITEMS = 10;
const MAX_RESULTS = 4;
let currentTerm = "";
searchBar.addEventListener("keyup", (e) => {
const searchVal = searchBar.value.trim();
const results = fuse.search(searchVal, { limit: MAX_ITEMS });
let html = "";
for (const result of results) {
html += makeTeaser(result, searchVal);
}
searchResults.innerHTML = html;
if (html) {
searchResults.style.display = "flex";
} else {
searchResults.style.display = "none";
}
});
function makeTeaser(result, searchVal) {
const TEASER_SIZE = 20;
let output = `<div class="search-result item"><a class="result-title" href=${result.item.url}>${result.item.title}</a>`;
for (const match of result.matches) {
if (match.key === "title") continue;
const indices = match.indices.sort((a, b) => Math.abs(a[1] - a[0] - searchVal.length) - Math.abs(b[1] - b[0] - searchVal.length)).slice(0, MAX_RESULTS);
const value = match.value;
for (const ind of indices) {
const start = Math.max(0, ind[0] - TEASER_SIZE);
const end = Math.min(value.length - 1, ind[1] + TEASER_SIZE);
output += "<span>"
+ value.substring(start, ind[0])
+ `<strong>${value.substring(ind[0], ind[1] + 1)}</strong>`
+ value.substring(ind[1] + 1, end)
+ "</span>";
}
if (match.indices.length > 4) {
const moreMatchesText = document.getElementById("more-matches-text").textContent;
output += `<span class="more-matches">${moreMatchesText}</span>`.replace("$MATCHES", `+${match.indices.length - MAX_RESULTS}`);
}
}
return output + "</div>";
}
/*window.addEventListener("click", function (event) {
if (searchSetup && searchBar.getAttribute("disabled") === null && !searchContainer.contains(event.target)) {
toggleSearch();
}
}, { passive: true });*/
document.addEventListener("keydown", function(event) {
if (event.key === "/") {
event.preventDefault();
toggleSearch();
}
});
document.getElementById("search-toggle").addEventListener("click", toggleSearch);
}
if (document.readyState === "complete" ||
(document.readyState !== "loading" && !document.documentElement.doScroll))
initSearch();
else
document.addEventListener("DOMContentLoaded", initSearch);

View File

@ -12,11 +12,7 @@ Parameters:
The macro supports special pluralization rules for:
- Arabic (`ar`): Has unique forms for zero, one, two, few, and many.
- Slavic languages: Pluralization depends on the last digit of the number, with exceptions for numbers ending in 11-14.
NOTE: If the logic for pluralization is modified, it needs to be replicated on the JavaScript search.
Files: static/js/searchElasticlunr.js and its minified version at static/js/searchElasticlunr.min.js
Function name: getPluralizationKey -#}
- Slavic languages: Pluralization depends on the last digit of the number, with exceptions for numbers ending in 11-14.#}
{% macro translate(key, number=-1, language_strings="", default="", replace=true) %}
{%- set slavic_plural_languages = ["uk", "be", "bs", "hr", "ru", "sr"] -%}