mirror of
https://github.com/snachodog/just-the-docs.git
synced 2025-04-08 04:51:23 -06:00
Search for sections (configurable via search.heading_level)
Added more search configurations Display "no results found"
This commit is contained in:
parent
38689d07b1
commit
7f5b1f14f1
@ -26,6 +26,11 @@ exclude: ["node_modules/", "*.gemspec", "*.gem", "Gemfile", "Gemfile.lock", "pac
|
||||
|
||||
# Enable or disable the site search
|
||||
search_enabled: true
|
||||
search:
|
||||
heading_level: 2
|
||||
preview_words_before: 5
|
||||
preview_words_after: 10
|
||||
rel_url: false
|
||||
|
||||
# Set the search token separator for hyphenated-word search:
|
||||
search_tokenizer_separator: /[\s/]+/
|
||||
|
@ -24,6 +24,10 @@ layout: table_wrappers
|
||||
<title>Expand</title>
|
||||
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/><path d="M0 0h24v24H0z" fill="none"/>
|
||||
</symbol>
|
||||
<symbol id="svg-doc" viewBox="0 0 24 24">
|
||||
<title>Document</title>
|
||||
<path fill="none" d="M0 0h24v24H0V0z"/><path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zM6 20V4h7v5h5v11H6z"/>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
<div class="side-bar">
|
||||
|
@ -131,29 +131,50 @@
|
||||
&.active {
|
||||
background-color: $feedback-color;
|
||||
}
|
||||
|
||||
@include mq(md) {
|
||||
padding-right: $sp-4;
|
||||
padding-left: $sp-4;
|
||||
}
|
||||
}
|
||||
|
||||
.search-result-title {
|
||||
display: block;
|
||||
padding-top: $sp-2;
|
||||
padding-right: $sp-4;
|
||||
padding-bottom: $sp-2;
|
||||
|
||||
@include mq(sm) {
|
||||
display: inline-block;
|
||||
width: 40%;
|
||||
padding-right: $sp-2;
|
||||
word-wrap: break-word;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
.search-result-doc {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&.search-result-doc-parent {
|
||||
opacity: 0.5;
|
||||
@include fs-3;
|
||||
|
||||
@include mq(md) {
|
||||
@include fs-2;
|
||||
}
|
||||
}
|
||||
|
||||
.search-result-icon {
|
||||
width: $sp-4;
|
||||
height: $sp-4;
|
||||
margin-right: $sp-2;
|
||||
fill: $link-color;
|
||||
}
|
||||
}
|
||||
|
||||
.search-result-section {
|
||||
margin-left: #{$sp-4 + $sp-2};
|
||||
}
|
||||
|
||||
.search-result-rel-url {
|
||||
display: block;
|
||||
margin-left: #{$sp-4 + $sp-2};
|
||||
overflow: hidden;
|
||||
color: $search-result-preview-color;
|
||||
text-overflow: ellipsis;
|
||||
@ -166,6 +187,7 @@
|
||||
padding-top: $sp-2;
|
||||
padding-bottom: $sp-2;
|
||||
padding-left: $sp-4;
|
||||
margin-left: $sp-2;
|
||||
color: $search-result-preview-color;
|
||||
border-left: $border;
|
||||
border-left-color: $border-color;
|
||||
@ -174,13 +196,22 @@
|
||||
@include mq(sm) {
|
||||
display: inline-block;
|
||||
width: 60%;
|
||||
padding-left: $sp-2;
|
||||
margin-left: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
.search-result-highlight {
|
||||
font-weight: bold;
|
||||
color: $link-color;
|
||||
}
|
||||
|
||||
.search-no-result {
|
||||
padding-top: $sp-2;
|
||||
padding-right: $sp-3;
|
||||
padding-bottom: $sp-2;
|
||||
padding-left: $sp-3;
|
||||
@include fs-3;
|
||||
}
|
||||
|
||||
.search-button {
|
||||
@ -205,7 +236,7 @@
|
||||
z-index: 1;
|
||||
width: 0;
|
||||
height: 0;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
opacity: 0;
|
||||
transition: opacity ease $transition-duration, width 0s $transition-duration, height 0s $transition-duration;
|
||||
}
|
||||
|
@ -81,7 +81,9 @@ function initSearch() {
|
||||
this.ref('id');
|
||||
this.field('title', { boost: 200 });
|
||||
this.field('content', { boost: 2 });
|
||||
this.field('url');
|
||||
{% if site.search.rel_url != false -%}
|
||||
this.field('relUrl');
|
||||
{%- endif %}
|
||||
this.metadataWhitelist = ['position']
|
||||
|
||||
for (var i in docs) {
|
||||
@ -89,7 +91,9 @@ function initSearch() {
|
||||
id: i,
|
||||
title: docs[i].title,
|
||||
content: docs[i].content,
|
||||
url: docs[i].url
|
||||
{% if site.search.rel_url != false -%}
|
||||
relUrl: docs[i].relUrl
|
||||
{%- endif %}
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -112,20 +116,29 @@ function initSearch() {
|
||||
var searchInput = document.getElementById('search-input');
|
||||
var searchResults = document.getElementById('search-results');
|
||||
var mainHeader = document.getElementById('main-header');
|
||||
var currentInput;
|
||||
|
||||
function clearResults() {
|
||||
searchResults.innerHTML = '';
|
||||
hideResults();
|
||||
function showSearch() {
|
||||
document.documentElement.classList.add('search-active');
|
||||
}
|
||||
|
||||
function hideResults() {
|
||||
function hideSearch() {
|
||||
document.documentElement.classList.remove('search-active');
|
||||
}
|
||||
|
||||
function update() {
|
||||
clearResults();
|
||||
|
||||
var input = searchInput.value;
|
||||
if (input === '') {
|
||||
hideSearch();
|
||||
} else {
|
||||
showSearch();
|
||||
window.scroll(0, window.scrollY + mainHeader.getBoundingClientRect().top);
|
||||
}
|
||||
if (input === currentInput) {
|
||||
return;
|
||||
}
|
||||
currentInput = input;
|
||||
searchResults.innerHTML = '';
|
||||
if (input === '') {
|
||||
return;
|
||||
}
|
||||
@ -140,10 +153,13 @@ function initSearch() {
|
||||
});
|
||||
});
|
||||
|
||||
if (results.length > 0) {
|
||||
window.scroll(0, window.scrollY + mainHeader.getBoundingClientRect().top);
|
||||
document.documentElement.classList.add('search-active');
|
||||
if (results.length == 0) {
|
||||
var noResultsDiv = document.createElement('div');
|
||||
noResultsDiv.classList.add('search-no-result');
|
||||
noResultsDiv.innerText = 'No results found';
|
||||
searchResults.appendChild(noResultsDiv);
|
||||
|
||||
} else {
|
||||
var resultsList = document.createElement('ul');
|
||||
resultsList.classList.add('search-results-list');
|
||||
searchResults.appendChild(resultsList);
|
||||
@ -163,13 +179,26 @@ function initSearch() {
|
||||
|
||||
var resultTitle = document.createElement('div');
|
||||
resultTitle.classList.add('search-result-title');
|
||||
resultTitle.innerText = doc.title;
|
||||
resultLink.appendChild(resultTitle);
|
||||
|
||||
var resultRelUrl = document.createElement('span');
|
||||
resultRelUrl.classList.add('search-result-rel-url');
|
||||
resultRelUrl.innerText = doc.relUrl;
|
||||
resultTitle.appendChild(resultRelUrl);
|
||||
var resultDoc = document.createElement('div');
|
||||
resultDoc.classList.add('search-result-doc');
|
||||
resultDoc.innerHTML = '<svg viewBox="0 0 24 24" class="search-result-icon"><use xlink:href="#svg-doc"></use></svg>';
|
||||
resultTitle.appendChild(resultDoc);
|
||||
|
||||
var resultDocSpan = document.createElement('span');
|
||||
resultDocSpan.innerText = doc.doc;
|
||||
resultDoc.appendChild(resultDocSpan);
|
||||
var resultDocOrSection = resultDocSpan;
|
||||
|
||||
if (doc.doc != doc.title) {
|
||||
resultDoc.classList.add('search-result-doc-parent');
|
||||
var resultSection = document.createElement('div');
|
||||
resultSection.classList.add('search-result-section');
|
||||
resultSection.innerText = doc.title;
|
||||
resultTitle.appendChild(resultSection);
|
||||
resultDocOrSection = resultSection;
|
||||
}
|
||||
|
||||
var metadata = result.matchData.metadata;
|
||||
var contentFound = false;
|
||||
@ -178,9 +207,9 @@ function initSearch() {
|
||||
var position = metadata[j].title.position[0];
|
||||
var start = position[0];
|
||||
var end = position[0] + position[1];
|
||||
resultTitle.innerHTML = doc.title.substring(0, start) + '<span class="search-result-highlight">' + doc.title.substring(start, end) + '</span>' + doc.title.substring(end, doc.title.length)+'<span class="search-result-rel-url">'+doc.relUrl+'</span>';
|
||||
|
||||
} else if (metadata[j].content && !contentFound) {
|
||||
resultDocOrSection.innerHTML = doc.title.substring(0, start) + '<span class="search-result-highlight">' + doc.title.substring(start, end) + '</span>' + doc.title.substring(end, doc.title.length);
|
||||
}
|
||||
if (metadata[j].content && !contentFound) {
|
||||
contentFound = true;
|
||||
|
||||
var position = metadata[j].content.position[0];
|
||||
@ -190,10 +219,10 @@ function initSearch() {
|
||||
var previewEnd = end;
|
||||
var ellipsesBefore = true;
|
||||
var ellipsesAfter = true;
|
||||
for (var k = 0; k < 3; k++) {
|
||||
for (var k = 0; k < {{ site.search.preview_words_before | default: 5 }}; k++) {
|
||||
var nextSpace = doc.content.lastIndexOf(' ', previewStart - 2);
|
||||
var nextDot = doc.content.lastIndexOf('.', previewStart - 2);
|
||||
if ((nextDot > 0) && (nextDot > nextSpace)) {
|
||||
var nextDot = doc.content.lastIndexOf('. ', previewStart - 2);
|
||||
if ((nextDot >= 0) && (nextDot > nextSpace)) {
|
||||
previewStart = nextDot + 1;
|
||||
ellipsesBefore = false;
|
||||
break;
|
||||
@ -205,10 +234,10 @@ function initSearch() {
|
||||
}
|
||||
previewStart = nextSpace + 1;
|
||||
}
|
||||
for (var k = 0; k < 10; k++) {
|
||||
for (var k = 0; k < {{ site.search.preview_words_after | default: 10 }}; k++) {
|
||||
var nextSpace = doc.content.indexOf(' ', previewEnd + 1);
|
||||
var nextDot = doc.content.indexOf('.', previewEnd + 1);
|
||||
if ((nextDot > 0) && (nextDot < nextSpace)) {
|
||||
var nextDot = doc.content.indexOf('. ', previewEnd + 1);
|
||||
if ((nextDot >= 0) && (nextDot < nextSpace)) {
|
||||
previewEnd = nextDot;
|
||||
ellipsesAfter = false;
|
||||
break;
|
||||
@ -236,6 +265,13 @@ function initSearch() {
|
||||
resultLink.appendChild(resultPreview);
|
||||
}
|
||||
}
|
||||
|
||||
{% if site.search.rel_url != false -%}
|
||||
var resultRelUrl = document.createElement('span');
|
||||
resultRelUrl.classList.add('search-result-rel-url');
|
||||
resultRelUrl.innerText = doc.relUrl;
|
||||
resultTitle.appendChild(resultRelUrl);
|
||||
{%- endif %}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -247,9 +283,8 @@ function initSearch() {
|
||||
jtd.addEvent(searchInput, 'keyup', function(e){
|
||||
switch (e.keyCode) {
|
||||
case 27: // When esc key is pressed, hide the results and clear the field
|
||||
clearResults();
|
||||
searchInput.value = '';
|
||||
return;
|
||||
break;
|
||||
case 38: // arrow up
|
||||
case 40: // arrow down
|
||||
case 13: // enter
|
||||
@ -305,7 +340,7 @@ function initSearch() {
|
||||
|
||||
jtd.addEvent(document, 'click', function(e){
|
||||
if (e.target != searchInput) {
|
||||
hideResults();
|
||||
hideSearch();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -2,12 +2,57 @@
|
||||
permalink: /assets/js/search-data.json
|
||||
---
|
||||
{
|
||||
{% assign comma = false %}
|
||||
{% for page in site.html_pages %}{% if page.search_exclude != true %}{% if comma == true%},{% endif %}"{{ forloop.index0 }}": {
|
||||
{%- assign i = 0 -%}
|
||||
{% for page in site.html_pages %}
|
||||
{%- if page.title and page.search_exclude != true -%}
|
||||
{%- assign page_content = page.content -%}
|
||||
{%- assign heading_level = site.search.heading_level | default: 1 -%}
|
||||
{%- for j in (2..heading_level) -%}
|
||||
{%- assign tag = '<h' | append: j -%}
|
||||
{%- assign closing_tag = '</h' | append: j -%}
|
||||
{%- assign page_content = page_content | replace: tag, '<h1' | replace: closing_tag, '</h1' -%}
|
||||
{%- endfor -%}
|
||||
{%- assign parts = page_content | split: '<h1' -%}
|
||||
{%- assign title_found = false -%}
|
||||
{% for part in parts offset: 1 %}
|
||||
{%- assign titleAndContent = part | split: '</h1>' -%}
|
||||
{%- assign title = titleAndContent[0] | replace_first: '>', '<h1>' | split: '<h1>' -%}
|
||||
{%- assign title = title[1] | strip_html -%}
|
||||
{%- assign content = titleAndContent[1] -%}
|
||||
{%- assign url = page.url -%}
|
||||
{%- if title == page.title and parts[0] == '' -%}
|
||||
{%- assign title_found = true -%}
|
||||
{%- else -%}
|
||||
{%- assign id = titleAndContent[0] -%}
|
||||
{%- assign id = id | split: 'id="' -%}
|
||||
{%- if id.size == 2 -%}
|
||||
{%- assign id = id[1] -%}
|
||||
{%- assign id = id | split: '"' -%}
|
||||
{%- assign id = id[0] -%}
|
||||
{%- capture url -%}{{ url | append: '#' | append: id }}{%- endcapture -%}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- unless i == 0 -%},{%- endunless -%}
|
||||
"{{ i }}": {
|
||||
"doc": "{{ page.title | escape_once }}",
|
||||
"title": "{{ title | escape_once }}",
|
||||
"content": "{{ content | replace: '</h', ' . </h' | replace: '<hr', ' . <hr' | replace: '</p', ' . </p' | replace: '<ul', ' . <ul' | replace: '</ul', ' . </ul' | replace: '<ol', ' . <ol' | replace: '</ol', ' . </ol' | replace: '</tr', ' . </tr' | replace: '<li', ' | <li' | replace: '</li', ' | </li' | replace: '</td', ' | </td' | replace: '<td', ' | <td' | replace: '</th', ' | </th' | replace: '<th', ' | <th' | strip_html | escape_once | remove: 'Table of contents' | replace: '\', '\' | replace: ' . . . ', ' . ' | replace: ' . . ', ' . ' | normalize_whitespace | replace: '| |', '|' }}",
|
||||
"url": "{{ url | absolute_url }}",
|
||||
"relUrl": "{{ url }}"
|
||||
}
|
||||
{%- assign i = i | plus: 1 -%}
|
||||
{%- endfor -%}
|
||||
{%- unless title_found -%}
|
||||
{%- unless i == 0 -%},{%- endunless -%}
|
||||
"{{ i }}": {
|
||||
"doc": "{{ page.title | escape_once }}",
|
||||
"title": "{{ page.title | escape_once }}",
|
||||
"content": "{{ page.content | replace: '</h', ' . </h' | replace: '<hr', ' . <hr' | replace: '</p', ' . </p' | replace: '</ul', ' . </ul' | replace: '</tr', ' . </tr' | replace: '</li', ' | </li' | replace: '</td', ' | </td' | strip_html | escape_once | remove: 'Table of contents' | replace: '\', ' ' | replace: ' . . . ', ' . ' | replace: ' . . ', ' . ' | normalize_whitespace }}",
|
||||
"content": "{{ parts[0] | replace: '</h', ' . </h' | replace: '<hr', ' . <hr' | replace: '</p', ' . </p' | replace: '<ul', ' . <ul' | replace: '</ul', ' . </ul' | replace: '<ol', ' . <ol' | replace: '</ol', ' . </ol' | replace: '</tr', ' . </tr' | replace: '<li', ' | <li' | replace: '</li', ' | </li' | replace: '</td', ' | </td' | replace: '<td', ' | <td' | replace: '</th', ' | </th' | replace: '<th', ' | <th' | strip_html | escape_once | remove: 'Table of contents' | replace: '\', '\' | replace: ' . . . ', ' . ' | replace: ' . . ', ' . ' | normalize_whitespace | replace: '| |', '|' }}",
|
||||
"url": "{{ page.url | absolute_url }}",
|
||||
"relUrl": "{{ page.url }}"
|
||||
}{% assign comma = true %}
|
||||
{% endif %}{% endfor %}
|
||||
}
|
||||
{%- assign i = i | plus: 1 -%}
|
||||
{%- endunless -%}
|
||||
{%- endif -%}
|
||||
{% endfor %}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user