mirror of
https://github.com/snachodog/just-the-docs.git
synced 2025-04-18 17:12:23 -06:00
Improved search responsiveness for many results
This commit is contained in:
parent
0421ab7f82
commit
16628f2b8e
@ -118,6 +118,7 @@ function searchLoaded(index, docs) {
|
|||||||
var searchResults = document.getElementById('search-results');
|
var searchResults = document.getElementById('search-results');
|
||||||
var mainHeader = document.getElementById('main-header');
|
var mainHeader = document.getElementById('main-header');
|
||||||
var currentInput;
|
var currentInput;
|
||||||
|
var currentSearchIndex = 0;
|
||||||
|
|
||||||
function showSearch() {
|
function showSearch() {
|
||||||
document.documentElement.classList.add('search-active');
|
document.documentElement.classList.add('search-active');
|
||||||
@ -128,6 +129,8 @@ function searchLoaded(index, docs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
|
currentSearchIndex++;
|
||||||
|
|
||||||
var input = searchInput.value;
|
var input = searchInput.value;
|
||||||
if (input === '') {
|
if (input === '') {
|
||||||
hideSearch();
|
hideSearch();
|
||||||
@ -180,161 +183,177 @@ function searchLoaded(index, docs) {
|
|||||||
resultsList.classList.add('search-results-list');
|
resultsList.classList.add('search-results-list');
|
||||||
searchResults.appendChild(resultsList);
|
searchResults.appendChild(resultsList);
|
||||||
|
|
||||||
for (var i in results) {
|
addResults(resultsList, results, 0, 10, 100, currentSearchIndex);
|
||||||
var result = results[i];
|
}
|
||||||
var doc = docs[result.ref];
|
|
||||||
|
|
||||||
var resultsListItem = document.createElement('li');
|
function addResults(resultsList, results, start, batchSize, batchMillis, searchIndex) {
|
||||||
resultsListItem.classList.add('search-results-list-item');
|
if (searchIndex != currentSearchIndex) {
|
||||||
resultsList.appendChild(resultsListItem);
|
return;
|
||||||
|
|
||||||
var resultLink = document.createElement('a');
|
|
||||||
resultLink.classList.add('search-result');
|
|
||||||
resultLink.setAttribute('href', doc.url);
|
|
||||||
resultsListItem.appendChild(resultLink);
|
|
||||||
|
|
||||||
var resultTitle = document.createElement('div');
|
|
||||||
resultTitle.classList.add('search-result-title');
|
|
||||||
resultLink.appendChild(resultTitle);
|
|
||||||
|
|
||||||
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 resultDocTitle = document.createElement('div');
|
|
||||||
resultDocTitle.classList.add('search-result-doc-title');
|
|
||||||
resultDocTitle.innerHTML = doc.doc;
|
|
||||||
resultDoc.appendChild(resultDocTitle);
|
|
||||||
var resultDocOrSection = resultDocTitle;
|
|
||||||
|
|
||||||
if (doc.doc != doc.title) {
|
|
||||||
resultDoc.classList.add('search-result-doc-parent');
|
|
||||||
var resultSection = document.createElement('div');
|
|
||||||
resultSection.classList.add('search-result-section');
|
|
||||||
resultSection.innerHTML = doc.title;
|
|
||||||
resultTitle.appendChild(resultSection);
|
|
||||||
resultDocOrSection = resultSection;
|
|
||||||
}
|
|
||||||
|
|
||||||
var metadata = result.matchData.metadata;
|
|
||||||
var titlePositions = [];
|
|
||||||
var contentPositions = [];
|
|
||||||
for (var j in metadata) {
|
|
||||||
var meta = metadata[j];
|
|
||||||
if (meta.title) {
|
|
||||||
var positions = meta.title.position;
|
|
||||||
for (var k in positions) {
|
|
||||||
titlePositions.push(positions[k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (meta.content) {
|
|
||||||
var positions = meta.content.position;
|
|
||||||
for (var k in positions) {
|
|
||||||
var position = positions[k];
|
|
||||||
var previewStart = position[0];
|
|
||||||
var previewEnd = position[0] + position[1];
|
|
||||||
var ellipsesBefore = true;
|
|
||||||
var ellipsesAfter = true;
|
|
||||||
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)) {
|
|
||||||
previewStart = nextDot + 1;
|
|
||||||
ellipsesBefore = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (nextSpace < 0) {
|
|
||||||
previewStart = 0;
|
|
||||||
ellipsesBefore = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
previewStart = nextSpace + 1;
|
|
||||||
}
|
|
||||||
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)) {
|
|
||||||
previewEnd = nextDot;
|
|
||||||
ellipsesAfter = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (nextSpace < 0) {
|
|
||||||
previewEnd = doc.content.length;
|
|
||||||
ellipsesAfter = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
previewEnd = nextSpace;
|
|
||||||
}
|
|
||||||
contentPositions.push({
|
|
||||||
highlight: position,
|
|
||||||
previewStart: previewStart, previewEnd: previewEnd,
|
|
||||||
ellipsesBefore: ellipsesBefore, ellipsesAfter: ellipsesAfter
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (titlePositions.length > 0) {
|
|
||||||
titlePositions.sort(function(p1, p2){ return p1[0] - p2[0] });
|
|
||||||
resultDocOrSection.innerHTML = '';
|
|
||||||
addHighlightedText(resultDocOrSection, doc.title, 0, doc.title.length, titlePositions);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contentPositions.length > 0) {
|
|
||||||
contentPositions.sort(function(p1, p2){ return p1.highlight[0] - p2.highlight[0] });
|
|
||||||
var contentPosition = contentPositions[0];
|
|
||||||
var previewPosition = {
|
|
||||||
highlight: [contentPosition.highlight],
|
|
||||||
previewStart: contentPosition.previewStart, previewEnd: contentPosition.previewEnd,
|
|
||||||
ellipsesBefore: contentPosition.ellipsesBefore, ellipsesAfter: contentPosition.ellipsesAfter
|
|
||||||
};
|
|
||||||
var previewPositions = [previewPosition];
|
|
||||||
for (var j = 1; j < contentPositions.length; j++) {
|
|
||||||
contentPosition = contentPositions[j];
|
|
||||||
if (previewPosition.previewEnd < contentPosition.previewStart) {
|
|
||||||
previewPosition = {
|
|
||||||
highlight: [contentPosition.highlight],
|
|
||||||
previewStart: contentPosition.previewStart, previewEnd: contentPosition.previewEnd,
|
|
||||||
ellipsesBefore: contentPosition.ellipsesBefore, ellipsesAfter: contentPosition.ellipsesAfter
|
|
||||||
}
|
|
||||||
previewPositions.push(previewPosition);
|
|
||||||
} else {
|
|
||||||
previewPosition.highlight.push(contentPosition.highlight);
|
|
||||||
previewPosition.previewEnd = contentPosition.previewEnd;
|
|
||||||
previewPosition.ellipsesAfter = contentPosition.ellipsesAfter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var resultPreviews = document.createElement('div');
|
|
||||||
resultPreviews.classList.add('search-result-previews');
|
|
||||||
resultLink.appendChild(resultPreviews);
|
|
||||||
|
|
||||||
var content = doc.content;
|
|
||||||
for (var j = 0; j < Math.min(previewPositions.length, {{ site.search.previews | default: 3 }}); j++) {
|
|
||||||
var position = previewPositions[j];
|
|
||||||
|
|
||||||
var resultPreview = document.createElement('div');
|
|
||||||
resultPreview.classList.add('search-result-preview');
|
|
||||||
resultPreviews.appendChild(resultPreview);
|
|
||||||
|
|
||||||
if (position.ellipsesBefore) {
|
|
||||||
resultPreview.appendChild(document.createTextNode('... '));
|
|
||||||
}
|
|
||||||
addHighlightedText(resultPreview, content, position.previewStart, position.previewEnd, position.highlight);
|
|
||||||
if (position.ellipsesAfter) {
|
|
||||||
resultPreview.appendChild(document.createTextNode(' ...'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{%- 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 %}
|
|
||||||
}
|
}
|
||||||
|
for (var i = start; i < (start + batchSize); i++) {
|
||||||
|
if (i == results.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addResult(resultsList, results[i]);
|
||||||
|
}
|
||||||
|
setTimeout(function() {
|
||||||
|
addResults(resultsList, results, start + batchSize, batchSize, batchMillis, searchIndex);
|
||||||
|
}, batchMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addResult(resultsList, result) {
|
||||||
|
var doc = docs[result.ref];
|
||||||
|
|
||||||
|
var resultsListItem = document.createElement('li');
|
||||||
|
resultsListItem.classList.add('search-results-list-item');
|
||||||
|
resultsList.appendChild(resultsListItem);
|
||||||
|
|
||||||
|
var resultLink = document.createElement('a');
|
||||||
|
resultLink.classList.add('search-result');
|
||||||
|
resultLink.setAttribute('href', doc.url);
|
||||||
|
resultsListItem.appendChild(resultLink);
|
||||||
|
|
||||||
|
var resultTitle = document.createElement('div');
|
||||||
|
resultTitle.classList.add('search-result-title');
|
||||||
|
resultLink.appendChild(resultTitle);
|
||||||
|
|
||||||
|
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 resultDocTitle = document.createElement('div');
|
||||||
|
resultDocTitle.classList.add('search-result-doc-title');
|
||||||
|
resultDocTitle.innerHTML = doc.doc;
|
||||||
|
resultDoc.appendChild(resultDocTitle);
|
||||||
|
var resultDocOrSection = resultDocTitle;
|
||||||
|
|
||||||
|
if (doc.doc != doc.title) {
|
||||||
|
resultDoc.classList.add('search-result-doc-parent');
|
||||||
|
var resultSection = document.createElement('div');
|
||||||
|
resultSection.classList.add('search-result-section');
|
||||||
|
resultSection.innerHTML = doc.title;
|
||||||
|
resultTitle.appendChild(resultSection);
|
||||||
|
resultDocOrSection = resultSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
var metadata = result.matchData.metadata;
|
||||||
|
var titlePositions = [];
|
||||||
|
var contentPositions = [];
|
||||||
|
for (var j in metadata) {
|
||||||
|
var meta = metadata[j];
|
||||||
|
if (meta.title) {
|
||||||
|
var positions = meta.title.position;
|
||||||
|
for (var k in positions) {
|
||||||
|
titlePositions.push(positions[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (meta.content) {
|
||||||
|
var positions = meta.content.position;
|
||||||
|
for (var k in positions) {
|
||||||
|
var position = positions[k];
|
||||||
|
var previewStart = position[0];
|
||||||
|
var previewEnd = position[0] + position[1];
|
||||||
|
var ellipsesBefore = true;
|
||||||
|
var ellipsesAfter = true;
|
||||||
|
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)) {
|
||||||
|
previewStart = nextDot + 1;
|
||||||
|
ellipsesBefore = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nextSpace < 0) {
|
||||||
|
previewStart = 0;
|
||||||
|
ellipsesBefore = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
previewStart = nextSpace + 1;
|
||||||
|
}
|
||||||
|
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)) {
|
||||||
|
previewEnd = nextDot;
|
||||||
|
ellipsesAfter = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nextSpace < 0) {
|
||||||
|
previewEnd = doc.content.length;
|
||||||
|
ellipsesAfter = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
previewEnd = nextSpace;
|
||||||
|
}
|
||||||
|
contentPositions.push({
|
||||||
|
highlight: position,
|
||||||
|
previewStart: previewStart, previewEnd: previewEnd,
|
||||||
|
ellipsesBefore: ellipsesBefore, ellipsesAfter: ellipsesAfter
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (titlePositions.length > 0) {
|
||||||
|
titlePositions.sort(function(p1, p2){ return p1[0] - p2[0] });
|
||||||
|
resultDocOrSection.innerHTML = '';
|
||||||
|
addHighlightedText(resultDocOrSection, doc.title, 0, doc.title.length, titlePositions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contentPositions.length > 0) {
|
||||||
|
contentPositions.sort(function(p1, p2){ return p1.highlight[0] - p2.highlight[0] });
|
||||||
|
var contentPosition = contentPositions[0];
|
||||||
|
var previewPosition = {
|
||||||
|
highlight: [contentPosition.highlight],
|
||||||
|
previewStart: contentPosition.previewStart, previewEnd: contentPosition.previewEnd,
|
||||||
|
ellipsesBefore: contentPosition.ellipsesBefore, ellipsesAfter: contentPosition.ellipsesAfter
|
||||||
|
};
|
||||||
|
var previewPositions = [previewPosition];
|
||||||
|
for (var j = 1; j < contentPositions.length; j++) {
|
||||||
|
contentPosition = contentPositions[j];
|
||||||
|
if (previewPosition.previewEnd < contentPosition.previewStart) {
|
||||||
|
previewPosition = {
|
||||||
|
highlight: [contentPosition.highlight],
|
||||||
|
previewStart: contentPosition.previewStart, previewEnd: contentPosition.previewEnd,
|
||||||
|
ellipsesBefore: contentPosition.ellipsesBefore, ellipsesAfter: contentPosition.ellipsesAfter
|
||||||
|
}
|
||||||
|
previewPositions.push(previewPosition);
|
||||||
|
} else {
|
||||||
|
previewPosition.highlight.push(contentPosition.highlight);
|
||||||
|
previewPosition.previewEnd = contentPosition.previewEnd;
|
||||||
|
previewPosition.ellipsesAfter = contentPosition.ellipsesAfter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var resultPreviews = document.createElement('div');
|
||||||
|
resultPreviews.classList.add('search-result-previews');
|
||||||
|
resultLink.appendChild(resultPreviews);
|
||||||
|
|
||||||
|
var content = doc.content;
|
||||||
|
for (var j = 0; j < Math.min(previewPositions.length, {{ site.search.previews | default: 3 }}); j++) {
|
||||||
|
var position = previewPositions[j];
|
||||||
|
|
||||||
|
var resultPreview = document.createElement('div');
|
||||||
|
resultPreview.classList.add('search-result-preview');
|
||||||
|
resultPreviews.appendChild(resultPreview);
|
||||||
|
|
||||||
|
if (position.ellipsesBefore) {
|
||||||
|
resultPreview.appendChild(document.createTextNode('... '));
|
||||||
|
}
|
||||||
|
addHighlightedText(resultPreview, content, position.previewStart, position.previewEnd, position.highlight);
|
||||||
|
if (position.ellipsesAfter) {
|
||||||
|
resultPreview.appendChild(document.createTextNode(' ...'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{%- 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 %}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addHighlightedText(parent, text, start, end, positions) {
|
function addHighlightedText(parent, text, start, end, positions) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user