search: add dedicated search page #386

This commit is contained in:
Sören Weber 2022-11-17 22:12:18 +01:00
parent 17d877a141
commit 8b8814d696
No known key found for this signature in database
GPG key ID: BEC6D55545451B6D
39 changed files with 448 additions and 38 deletions

View file

@ -22,3 +22,11 @@
mediaType = 'text/javascript'
permalinkable = false
noUgly = true
[outputFormats.SERCHPAGE]
name= "SEARCHPAGE"
baseName = "search"
isHTML = true
mediaType = 'text/html'
permalinkable = false
noUgly = true

View file

@ -44,7 +44,7 @@ disableHugoGeneratorInject = true
# for the search functionality
# add PRINT to home, section and page to activate the feature to print whole
# chapters
home = ["HTML", "RSS", "PRINT", "SEARCH"]
home = ["HTML", "RSS", "PRINT", "SEARCH", "SEARCHPAGE"]
section = ["HTML", "RSS", "PRINT"]
page = ["HTML", "RSS", "PRINT"]

View file

@ -128,7 +128,20 @@ If not already present, add the following lines in the same `config.toml` file.
home = ["HTML", "RSS", "SEARCH"]
```
This will generate a search index file at the root of your public folder ready to be consumed by the lunr.js javascript search engine.
This will generate a search index file at the root of your public folder ready to be consumed by the lunr.js javascript search engine. Note that the `SEARCH` outputformat was named `JSON` in previous releases but was implemented differently. Although `JSON` still works, it is now deprecated.
### Activate dedicated search page
You can add a dedicated search page for your page by adding the `SEARCHPAGE` outputformat to your home page by adding the following lines in your `config.toml` file.
```toml
[outputs]
home = ["HTML", "RSS", "SEARCH", "SEARCHPAGE"]
```
You can access this page by either clicking on the magnifier glass or by typing some search term and pressing `ENTER` inside of the menu's search box .
![Screenshot of the dedicated search page](search_page.png?&width=60pc)
## Activate print support

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View file

@ -14,6 +14,30 @@ This document shows you what's new in the latest release. For a detailed list of
---
## 5.6.0
- **New**: This release introduces an additional dedicated search page. On this page, displayed search results have more space making it easier scanning thru large number of results.
To activate this feature, you need to [configure it]({{% relref "basics/configuration#activate-dedicated-search-page" %}}) in your `config.toml` as a new outputformat `SEARCHPAGE` for the home page. If you don't configure it, no dedicated search page will be accessible and the theme works as before.
You can access the search page by either clicking on the magnifier glass or pressing enter inside of the search box.
- **New**: Keyboard handling for the TOC and search was improved.
Pressing `CTRL+ALT+t` now will not only toggle the TOC overlay but also places the focus to the first heading on opening. Subsequently this makes it possible to easily select headings by using the `TAB` key.
The search received its own brand new keyboard shortcut `CTRL+ALT+f`. This will focus the cursor inside of the the search box so you can immediately start your search by typing.
- **New**: You are now able to turn off the generation of generator meta tags in your HTML head to hide the used versions of Hugo and this theme.
To [configure this]({{% relref "basics/configuration#global-site-parameters" %}}) in your `config.toml` make sure to set Hugo's `disableHugoGeneratorInject=true` **and** also `[params] disableGeneratorVersion=true`, otherwise Hugo will generate a meta tag into your home page automagically.
- **New**: Creation of your project gets a little bit faster with this release.
This addresses increased build time with the 5.x releases. The theme now heavily caches partial results leading to improved performance. To further increase performance, unnecessary parts of the page are now skipped for creation of the print output (eg. menus, navigation bar, etc.).
---
## 5.5.0
- **Change**: The way images are processed has changed. Now images are lazy loaded by default which speeds up page load on slow networks and/or big pages and also the print preview.

View file

@ -7,6 +7,12 @@ other = "البحث"
[Search-placeholder]
other = "...البحث"
[No-results-found]
other = "لم يتم العثور على نتائج لـ \"{0}\""
[N-results-found]
other = "تم العثور على {1} نتيجة لـ \"{0}\""
[Clear-History]
other = "مسح السجل"

View file

@ -7,6 +7,12 @@ other = "Suchen"
[Search-placeholder]
other = "Suchen..."
[No-results-found]
other = "Keine Ergebnisse gefunden für \"{0}\""
[N-results-found]
other = "{1} Ergebnisse gefunden für \"{0}\""
[Clear-History]
other = "Verlauf löschen"

View file

@ -7,6 +7,12 @@ other = "Search"
[Search-placeholder]
other = "Search..."
[No-results-found]
other = "No results found for \"{0}\""
[N-results-found]
other = "{1} results found for \"{0}\""
[Clear-History]
other = "Clear History"

View file

@ -7,6 +7,12 @@ other = "Buscar"
[Search-placeholder]
other = "Buscar..."
[No-results-found]
other = "No se han encontrado resultados para \"{0}\""
[N-results-found]
other = "{1} resultados encontrados para \"{0}\""
[Clear-History]
other = "Borrar Historial"

View file

@ -7,6 +7,12 @@ other = "Etsi"
[Search-placeholder]
other = "Etsi..."
[No-results-found]
other = "Ei tuloksia haulle \"{0}\""
[N-results-found]
other = "{1} tulosta löytyi haulle \"{0}\""
[Clear-History]
other = "Tyhjennä historia"

View file

@ -7,6 +7,12 @@ other = "Rechercher"
[Search-placeholder]
other = "Rechercher..."
[No-results-found]
other = "Aucun résultat trouvé pour \"{0}\""
[N-results-found]
other = "{1} résultats trouvés pour \"{0}\""
[Clear-History]
other = "Supprimer l'historique"

View file

@ -7,6 +7,12 @@ other = "खोजे"
[Search-placeholder]
other = "खोजे..."
[No-results-found]
other = "\"{0}\" के लिए कोई परिणाम नहीं मिला"
[N-results-found]
other = "\"{0}\" के लिए {1} परिणाम मिले"
[Clear-History]
other = "इतिहास मिटाएँ"

View file

@ -7,6 +7,12 @@ other = "Telusuri"
[Search-placeholder]
other = "Telusuri..."
[No-results-found]
other = "Tidak ada hasil yang ditemukan untuk \"{0}\""
[N-results-found]
other = "Ditemukan {1} hasil untuk \"{0}\""
[Clear-History]
other = "Bersihkan Riwayat"

View file

@ -7,6 +7,12 @@ other = "Cerca"
[Search-placeholder]
other = "Cerca..."
[No-results-found]
other = "Nessun risultato trovato per \"{0}\""
[N-results-found]
other = "{1} risultati trovati per \"{0}\""
[Clear-History]
other = "Reimposta storico"

View file

@ -7,6 +7,12 @@ other = "検索"
[Search-placeholder]
other = "検索..."
[No-results-found]
other = "\"{0}\" の結果が見つかりません"
[N-results-found]
other = "\"{0}\" で {1} 件の結果が見つかりました"
[Clear-History]
other = "履歴削除"

View file

@ -7,6 +7,12 @@ other = "검색"
[Search-placeholder]
other = "검색어를 입력하세요"
[No-results-found]
other = "\"{0}\"에 대한 결과가 없습니다."
[N-results-found]
other = "\"{0}\"에 대해 {1}개의 결과가 검색되었습니다."
[Clear-History]
other = "방문 기록 삭제"

View file

@ -7,6 +7,12 @@ other = "Zoeken"
[Search-placeholder]
other = "Zoeken..."
[No-results-found]
other = "Geen resultaten gevonden voor \"{0}\""
[N-results-found]
other = "{1} resultaten gevonden voor \"{0}\""
[Clear-History]
other = "Wis geschiedenis"

View file

@ -7,6 +7,12 @@ other = "Searrrch"
[Search-placeholder]
other = "Searrrch..."
[No-results-found]
other = "No rrresults found fer \"{0}\""
[N-results-found]
other = "{1} rrresults found fer \"{0}\""
[Clear-History]
other = "Clear Historrry"

View file

@ -7,6 +7,12 @@ other = "Szukaj"
[Search-placeholder]
other = "Szukaj..."
[No-results-found]
other = "Nie znaleziono wyników dla \"{0}\""
[N-results-found]
other = "Znaleziono {1} wyników dla \"{0}\""
[Clear-History]
other = "Wyczyść historię"

View file

@ -7,6 +7,12 @@ other = "Procurar"
[Search-placeholder]
other = "Procurar..."
[No-results-found]
other = "Nenhum resultado encontrado para \"{0}\""
[N-results-found]
other = "{1} resultados encontrados para \"{0}\""
[Clear-History]
other = "Limpar Histórico"

View file

@ -7,6 +7,12 @@ other = "Поиск"
[Search-placeholder]
other = "Поиск..."
[No-results-found]
other = "Ничего не найдено для \"{0}\""
[N-results-found]
other = "{1} результатов найдено для \"{0}\""
[Clear-History]
other = "Очистить историю"

View file

@ -7,6 +7,12 @@ other = "Ara"
[Search-placeholder]
other = "Ara..."
[No-results-found]
other = "\"{0}\" için sonuç bulunamadı"
[N-results-found]
other = "\"{0}\" için {1} sonuç bulundu"
[Clear-History]
other = "Geçmişi Temizle"

View file

@ -7,6 +7,12 @@ other = "Tìm kiếm"
[Search-placeholder]
other = "Tìm kiếm..."
[No-results-found]
other = "Không tìm thấy kết quả nào cho \"{0}\""
[N-results-found]
other = "{1} kết quả được tìm thấy cho \"{0}\""
[Clear-History]
other = "Xóa lịch sử.."

View file

@ -7,6 +7,12 @@ other = "搜索"
[Search-placeholder]
other = "搜索..."
[No-results-found]
other = "找不到\"{0}\"的结果"
[N-results-found]
other = "为\"{0}\"找到 {1} 个结果"
[Clear-History]
other = "清理历史记录"

View file

@ -7,6 +7,12 @@ other = "搜尋"
[Search-placeholder]
other = "搜尋..."
[No-results-found]
other = "找不到\"{0}\"的結果"
[N-results-found]
other = "為\"{0}\"找到 {1} 個結果"
[Clear-History]
other = "清除歷史紀錄"

View file

@ -7,6 +7,12 @@ other = "搜索"
[Search-placeholder]
other = "搜索..."
[No-results-found]
other = "找不到\"{0}\"的结果"
[N-results-found]
other = "为\"{0}\"找到 {1} 个结果"
[Clear-History]
other = "清理历史记录"

View file

@ -0,0 +1,25 @@
{{- $title := T "Search" }}
<article class="default">
<h1 id="{{ $title | urlize }}">{{ $title }}</h1>
<form action="javascript:triggerSearch()">
<div class="searchform">
<label class="a11y-only" for="search-by">{{ T "Search" }}</label>
<input data-search-input id="search-by-detail" class="search-by" name="search-by" type="search" placeholder="{{ T "Search-placeholder" }}">
<span class="btn cstyle secondary">
<button type="submit" title="{{ T "Search" }}">
<i class="fas fa-search"></i> {{ T "Search" }}
</button>
</span>
</div>
</form>
<div class="searchhint">
</div>
<hr>
<div id="searchresults">
</div>
<footer class="footline">
{{- partial "content-footer.html" . }}
</footer>
</article>

View file

@ -1,5 +1,10 @@
<!DOCTYPE html>
{{- $outputFormat := partial "output-format.hugo" . }}
{{- $format := partial "get-format.hugo" . }}
{{- $outputFormat := partial "output-format.hugo" (dict "page" . "format" $format) }}
{{- $basename := "index" }}
{{- if eq $outputFormat "searchpage" }}
{{- $basename = path.BaseName $format.RelPermalink }}
{{- end }}
<html lang="{{ .Page.Language | default "en" }}" dir="{{ T "Reading-direction" | default "ltr" }}">
<head>
{{- partial "meta.html" . }}
@ -16,7 +21,9 @@
{{- else }}
{{- range .AlternativeOutputFormats }}
{{- if eq .Rel "canonical" }}
{{ (printf $link (partial "relLangPrettyUglyURL.hugo" (dict "to" . "abs" true)) .Rel .MediaType.Type ($title | htmlEscape)) | safeHTML }}
{{ (printf $link (partial "relLangPrettyUglyURL.hugo" (dict "to" . "abs" true "basename" $basename)) .Rel .MediaType.Type ($title | htmlEscape)) | safeHTML }}
{{- else if eq $outputFormat "searchpage" }}
{{- else if eq .Name "SEARCHPAGE" }}
{{- else if and (ne .Name "JSON") (ne .Name "SEARCH") }}
{{ (printf $link (partial "relLangPrettyUglyURL.hugo" (dict "to" .)) .Rel .MediaType.Type ($title | htmlEscape)) | safeHTML }}
{{- end }}
@ -24,7 +31,8 @@
{{- end }}
{{- if and (ne .Site.Params.disableSeoHiddenPages true) (ne .Site.Params.disableSearchHiddenPages true) }}
{{- range .AlternativeOutputFormats }}
{{- if eq .Name "JSON" }}
{{- if eq .Name "SEARCHPAGE" }}
{{- else if eq .Name "JSON" }}
{{ (printf $link (.Permalink | relURL) .Rel .MediaType.Type ($title | htmlEscape)) | safeHTML }}
{{- end }}
{{- end }}
@ -40,43 +48,46 @@
<div id="toc-overlay"></div>
<nav id="topbar" class="highlightable" dir="ltr">
<div>
{{- $File := .File }}
{{- $Site := .Site }}
{{- $showPrevNext := (and (not .Params.disableNextPrev) (not .Site.Params.disableNextPrev)) }}
{{- if $showPrevNext }}
{{- if and (or (eq $outputFormat "html") (eq $outputFormat "searchpage")) $showPrevNext }}
{{- $parent := .Parent }}
{{- $ispublished := true }}
{{- if $parent }}
{{- $ispublished = gt (int (len $parent.Permalink)) 0 }}
{{- end }}
<div class="navigation">
{{- if and $ispublished ($.Scratch.Get "relearnNextPage") }}
{{- if or (ne $outputFormat "html") (not (and $ispublished ($.Scratch.Get "relearnNextPage"))) }}
<span class="nav nav-next"><i class="fa fa-chevron-right fa-fw"></i></span>
{{- else }}
{{- with ($.Scratch.Get "relearnNextPage") }}
<a class="nav nav-next" href="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" .) }}" title="{{.Title}} (&#129106;)"><i class="fas fa-chevron-right fa-fw"></i></a>
{{- end }}
{{- else }}
<span class="nav nav-next"><i class="fa fa-chevron-right fa-fw"></i></span>
{{- end }}
</div>
<div class="navigation">
{{- if and $ispublished ($.Scratch.Get "relearnPrevPage") }}
{{- with ($.Scratch.Get "relearnPrevPage") }}
{{- if and (eq .RelPermalink .Site.Home.RelPermalink) (eq $outputFormat "html") }}
<span class="nav nav-prev"><i class="fa fa-chevron-left fa-fw"></i></span>
{{- else if or (ne $outputFormat "html") (eq .Page.Kind "taxonomy") (eq .Page.Kind "term") (not (and $ispublished ($.Scratch.Get "relearnPrevPage"))) }}
{{- with .Site.Home }}
<a class="nav nav-prev" href="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" .) }}" title="{{.Title}} (&#129104;)"><i class="fas fa-chevron-left fa-fw"></i></a>
{{- end }}
{{- else }}
<span class="nav nav-prev"><i class="fa fa-chevron-left fa-fw"></i></span>
{{- with ($.Scratch.Get "relearnPrevPage") }}
<a class="nav nav-prev" href="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" .) }}" title="{{.Title}} (&#129104;)"><i class="fas fa-chevron-left fa-fw"></i></a>
{{- end}}
{{- end}}
</div>
{{- end }}
{{- with .OutputFormats.Get "PRINT" }}
{{- with and (eq $outputFormat "html") (.OutputFormats.Get "PRINT") }}
<div id="top-print-link">
<a class="print-link" title='{{ T "Print-this-chapter" }} (CTRL+ALT+p)' href="{{ .RelPermalink }}">
<i class="fas fa-print fa-fw"></i>
</a>
</div>
{{- end -}}
{{- if .Site.Params.editURL }}
{{- $File := .File }}
{{- $Site := .Site }}
{{- if $File }}
{{- if and (eq $outputFormat "html") .Site.Params.editURL $File }}
{{- with $File.Path }}
<div id="top-github-link">
<a class="github-link" title='{{ T "Edit-this-page" }} (CTRL+ALT+w)' href="{{ $Site.Params.editURL }}{{ replace $File.Dir "\\" "/" }}{{ $File.LogicalName }}" target="blank">
@ -85,11 +96,10 @@
</div>
{{- end }}
{{- end }}
{{- end }}
{{- $defaultDisableToc := .Site.Params.disableToc | default false }}
{{- $currentDisableToc := .Params.disableToc | default $defaultDisableToc }}
{{- $hastoc := not (eq 0 (int (len (.TableOfContents | plainify)))) }}
{{- $toc := (and $hastoc (not $currentDisableToc)) }}
{{- $toc := and $hastoc (not $currentDisableToc) (eq $outputFormat "html") }}
<div id="breadcrumbs">
<span id="sidebar-toggle-span">
<a href="#" id="sidebar-toggle" title='{{ T "Navigation-toggle" }} (CTRL+ALT+n)'><i class="fas fa-bars fa-fw"></i></a>

View file

@ -1,5 +1,11 @@
{{- $showvisitedlinks := .Site.Params.showVisitedLinks }}
{{- $format := partial "get-format.hugo" . }}
{{- $outputFormat := partial "output-format.hugo" (dict "page" . "format" $format) }}
{{- $basename := "index" }}
{{- if ne $outputFormat "html" }}
{{- $basename = path.BaseName $format.RelPermalink }}
{{- end }}
<aside id="sidebar" class="default-animation{{ if $showvisitedlinks }} showVisitedLinks{{ end }}" dir="ltr">
{{- $currentNode := . }}
<div id="header-wrapper" class="default-animation">
@ -76,9 +82,9 @@
{{- range $siteLanguages }}
{{- if eq $translation.Lang .Lang }}
{{- if eq $pageLang .Lang }}
<option lang="{{ $translation.Lang }}" id="{{ $translation.Lang }}" value="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" $translation) }}" selected>{{ .LanguageName }}</option>
<option lang="{{ $translation.Lang }}" id="{{ $translation.Lang }}" value="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" $translation "basename" $basename) }}" selected>{{ .LanguageName }}</option>
{{- else }}
<option lang="{{ $translation.Lang }}" id="{{ $translation.Lang }}" value="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" $translation) }}">{{ .LanguageName }}</option>
<option lang="{{ $translation.Lang }}" id="{{ $translation.Lang }}" value="{{ partial "relLangPrettyUglyURL.hugo" (dict "to" $translation "basename" $basename) }}">{{ .LanguageName }}</option>
{{- end }}
{{- end }}
{{- end }}

View file

View file

@ -1,4 +1,11 @@
{{- $format := partial "get-format.hugo" . }}
{{- $page := . }}
{{- $format := "" }}
{{- if reflect.IsMap $page }}
{{- $format = $page.format }}
{{- $page = $page.page }}
{{- else }}
{{- $format = partial "get-format.hugo" $page }}
{{- end }}
{{- $ret := "default" }}
{{- if $format }}
{{ $ret = $format.Name | lower }}

View file

@ -1,10 +1,14 @@
{{- $to := .to }}
{{- $abs := .abs }}
{{- $basename := .basename }}
{{- $link := $to.RelPermalink }}
{{- if $abs }}
{{- $link = $to.Permalink }}
{{- end }}
{{- if not $basename }}
{{- $basename = "index" }}
{{- end }}
{{- if and (ne .Site.Params.disableExplicitIndexURLs true) (eq (substr $link -1) "/") }}
{{- $link = printf "%sindex.html" $link }}
{{- $link = printf "%s%s.html" $link $basename }}
{{- end }}
{{- $link }}

View file

@ -42,6 +42,8 @@
window.T_Copied_to_clipboard = '{{ T "Copied-to-clipboard" | safeJS }}';
window.T_Copy_link_to_clipboard = '{{ T "Copy-link-to-clipboard" | safeJS }}';
window.T_Link_copied_to_clipboard = '{{ T "Link-copied-to-clipboard" | safeJS }}';
window.T_No_results_found = '{{ T "No-results-found" | safeJS }}';
window.T_N_results_found = '{{ T "N-results-found" | safeJS }}';
{{ "// some further base stuff" | safeJS }}
var baseUriFull='{{ trim .Site.BaseURL "/" | safeJS }}/';
{{- $quotedthemevariants := slice }}

View file

@ -24,7 +24,7 @@
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #333;
color: #282828;
}
.autocomplete-suggestion b {
@ -33,12 +33,14 @@
}
.autocomplete-suggestion.selected {
background: #333;
background: #282828;
color: #fff;
}
.autocomplete-suggestion:hover {
background: #444;
.autocomplete-suggestion:hover,
.autocomplete-suggestion:hover > .context,
#searchresults .autocomplete-suggestion:hover > .context {
background: #383838;
color: #fff;
}

View file

@ -47,6 +47,9 @@
#body .tab-nav-button:first-child {
margin-left: 9px;
}
.searchform input {
margin-right: .5rem;
}
.autocomplete-suggestion > .context {
margin-left: 1em;
}
@ -62,7 +65,8 @@
a,
.anchor,
#toc-menu,
#body a.highlight:after {
#body a.highlight:after,
#searchresults .autocomplete-suggestion {
color: #486ac9; /* var(--MAIN-LINK-color) */
}
@ -283,7 +287,8 @@
background-color: #ffffff; /* var(--MAIN-BG-color) */
}
#body a[aria-disabled="true"] {
#body a[aria-disabled="true"],
#searchresults .autocomplete-suggestion > .context {
color: #101010; /* var(--MAIN-TEXT-color) - inherit is not processed correctly in Chrome */
}

View file

@ -1572,3 +1572,53 @@ input[type="search"]::-webkit-search-results-decoration { display: none; }
margin-left: 0;
margin-right: auto;
}
.searchform {
display: flex;
}
.searchform > :first-child {
color: rgba( 255, 255, 255, .8 );
}
.searchform input {
flex: 1 0 60%;
border-radius: 4px;
border: 2px solid rgba( 134, 134, 134, .125 );
background: rgba( 134, 134, 134, .125 );
display: block;
margin: 0;
margin-inline-end: .5rem;
}
.searchform input:-ms-input-placeholder,
.searchform input::placeholder {
color: rgba( 255, 255, 255, .4 );
}
.searchform .btn {
display: inline-flex;
}
.searchhint {
margin-top: 1rem;
height: 1.5rem;
}
#searchresults a.autocomplete-suggestion {
display: block;
font-size: 1.3rem;
font-weight: 500;
line-height: 1.5rem;
padding: 1rem;
}
#searchresults a.autocomplete-suggestion:after {
height: 0;
}
#searchresults .autocomplete-suggestion > .context {
font-size: 1rem;
font-weight: 300;
margin-top: .66rem;
}

View file

@ -110,7 +110,8 @@ body {
a,
.anchor,
#toc-menu,
#body a.highlight:after {
#body a.highlight:after,
#searchresults .autocomplete-suggestion {
color: var(--INTERNAL-MAIN-LINK-color);
}
@ -310,7 +311,8 @@ div.featherlight .featherlight-content{
background-color: var(--INTERNAL-MAIN-BG-color);
}
#body a[aria-disabled="true"] {
#body a[aria-disabled="true"],
#searchresults .autocomplete-suggestion > .context {
color: var(--INTERNAL-MAIN-TEXT-color);
}

View file

@ -1,3 +1,11 @@
window.relearn = window.relearn || {};
window.relearn.runInitialSearch = function(){
if( window.relearn.isSearchInit && window.relearn.isLunrInit ){
searchDetail();
}
}
var lunrIndex, pagesIndex;
function initLunrIndex( index ){
@ -25,7 +33,47 @@ function initLunrIndex( index ){
page.index = idx;
this.add(page);
}, this);
})
});
window.relearn.isLunrInit = true;
window.relearn.runInitialSearch();
}
function triggerSearch(){
searchDetail();
if( URL ){
// sorry IE11
var input = document.querySelector('#search-by-detail');
if( !input ){
return;
}
var value = input.value;
var url = new URL( window.location );
var oldValue = url.searchParams.get('search-by');
if( value != oldValue ){
url.searchParams.set('search-by', value);
window.history.pushState(url.toString(), '', url);
}
}
}
window.addEventListener('popstate', function ( event ) {
// restart search if browsed thru history
if (event.state && event.state.indexOf('search.html?search-by=') >= 0) {
window.location.reload();
}
});
var input = document.querySelector('#search-by-detail');
if( input ){
input.addEventListener( 'keydown', function(event) {
// if we are pressing ESC in the searchdetail our focus will
// be stolen by the other event handlers, so we have to refocus
// here after a short while
if (event.key == "Escape") {
setTimeout( function(){ input.focus(); }, 0 );
}
});
}
function initLunrJson() {
@ -86,10 +134,70 @@ function searchPatterns(word) {
];
}
function resolvePlaceholders( s, args ) {
var args = args || [];
// use replace to iterate over the string
// select the match and check if the related argument is present
// if yes, replace the match with the argument
return s.replace(/{([0-9]+)}/g, function (match, index) {
// check if the argument is present
return typeof args[index] == 'undefined' ? match : args[index];
});
};
function searchDetail() {
var input = document.querySelector('#search-by-detail');
if( !input ){
return;
}
var value = input.value;
var results = document.querySelector('#searchresults');
var hint = document.querySelector('.searchhint');
hint.innerText = '';
results.textContent = '';
var a = search( value );
if( a.length ){
hint.innerText = resolvePlaceholders( window.T_N_results_found, [ value, a.length ] );
a.forEach( function(item){
var page = pagesIndex[item.index];
var numContextWords = 10;
var contextPattern = '(?:\\S+ +){0,' + numContextWords + '}\\S*\\b(?:' +
item.matches.map( function(match){return match.replace(/\W/g, '\\$&')} ).join('|') +
')\\b\\S*(?: +\\S+){0,' + numContextWords + '}';
var context = page.content.match(new RegExp(contextPattern, 'i'));
var divcontext = document.createElement('div');
divcontext.className = 'context';
divcontext.innerText = (context || '');
var divsuggestion = document.createElement('a');
divsuggestion.className = 'autocomplete-suggestion';
divsuggestion.setAttribute('data-term', value);
divsuggestion.setAttribute('data-title', page.title);
divsuggestion.setAttribute('href', baseUri + page.uri);
divsuggestion.setAttribute('data-context', context);
divsuggestion.innerText = '» ' + page.title;
divsuggestion.appendChild(divcontext);
results.appendChild( divsuggestion );
});
window.relearn.markSearch();
}
else if( value.length ) {
hint.innerText = resolvePlaceholders( window.T_No_results_found, [ value ] );
}
input.focus();
setTimeout( adjustContentWidth, 0 );
}
// Let's get started
initLunrJson();
initLunrJs();
$(function() {
if( URL ){
// sorry IE11
var url = new URL( window.location );
window.history.replaceState(url.toString(), '', url);
}
var searchList = new autoComplete({
/* selector for the search box element */
selectorToInsert: '#header-wrapper',

View file

@ -1,3 +1,5 @@
window.relearn = window.relearn || {};
var theme = true;
var isIE = /*@cc_on!@*/false || !!document.documentMode;
if( isIE ){
@ -709,6 +711,10 @@ function scrollToFragment() {
}
function mark(){
// mark some additonal stuff as searchable
$('#topbar a:not(:has(img)):not(.btn)').addClass('highlight');
$('#body-inner a:not(:has(img)):not(.btn):not(a[rel="footnote"])').addClass('highlight');
var value = sessionStorage.getItem(baseUriFull+'search-value');
$(".highlightable").highlight(value, { element: 'mark' });
$("mark").parents(".expand").addClass("expand-marked");
@ -722,6 +728,7 @@ function mark(){
});
psm && psm.update();
}
window.relearn.markSearch = mark;
function unmark(){
sessionStorage.removeItem(baseUriFull+'search-value');
@ -747,24 +754,36 @@ function searchInputHandler(value) {
}
function initSearch() {
jQuery('[data-search-input]').on('keydown', function(event) {
// sync input/escape between searchbox and searchdetail
jQuery('input.search-by').on('keydown', function(event) {
if (event.key == "Escape") {
var input = jQuery(this);
input.blur();
searchInputHandler( '' );
jQuery('input.search-by').val('');
documentFocus();
}
});
jQuery('[data-search-input]').on('input', function() {
jQuery('input.search-by').on('input', function() {
var input = jQuery(this);
var value = input.val();
searchInputHandler( value );
jQuery('input.search-by').not(this).val($(this).val());
});
jQuery('[data-search-clear]').on('click', function() {
jQuery('[data-search-input]').val('').trigger('input');
unmark();
});
if( URLSearchParams ){
// sorry IE11
var urlParams = new URLSearchParams(window.location.search);
var value = urlParams.get('search-by');
if( value ){
sessionStorage.setItem(baseUriFull+'search-value', value);
}
}
mark();
// custom sizzle case insensitive "contains" pseudo selector
@ -789,9 +808,8 @@ function initSearch() {
}
}
// mark some additonal stuff as searchable
$('#topbar a:not(:has(img)):not(.btn)').addClass('highlight');
$('#body-inner a:not(:has(img)):not(.btn):not(a[rel="footnote"])').addClass('highlight');
window.relearn.isSearchInit = true;
window.relearn.runInitialSearch && window.relearn.runInitialSearch();
}
// debouncing function from John Hann