Skip to content

Commit 3744e1a

Browse files
committed
Inject our search for mkdocs projects
1 parent 422f919 commit 3744e1a

File tree

2 files changed

+143
-11
lines changed

2 files changed

+143
-11
lines changed

readthedocs/core/static-src/core/js/doc-embed/search.js

Lines changed: 142 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Sphinx search overrides
2+
* Sphinx and Mkdocs search overrides
33
*/
44

55
var rtddata = require('./rtd-data');
@@ -40,7 +40,7 @@ function append_html_to_contents(contents, template, data) {
4040
* Sphinx indexer. This will fall back to the standard indexer on an API
4141
* failure,
4242
*/
43-
function attach_elastic_search_query(data) {
43+
function attach_elastic_search_query_sphinx(data) {
4444
var project = data.project;
4545
var version = data.version;
4646
var language = data.language || 'en';
@@ -272,13 +272,9 @@ function attach_elastic_search_query(data) {
272272
};
273273

274274
if (typeof Search !== 'undefined' && project && version) {
275-
276-
// Do not replace the built-in search if RTD's docsearch is disabled
277-
if (!data.features || !data.features.docsearch_disabled) {
278-
var query_fallback = Search.query;
279-
Search.query_fallback = query_fallback;
280-
Search.query = query_override;
281-
}
275+
var query_fallback = Search.query;
276+
Search.query_fallback = query_fallback;
277+
Search.query = query_override;
282278
}
283279
$(document).ready(function () {
284280
if (typeof Search !== 'undefined') {
@@ -288,9 +284,145 @@ function attach_elastic_search_query(data) {
288284
}
289285

290286

287+
function attach_elastic_search_query_mkdocs(data) {
288+
var project = data.project;
289+
var version = data.version;
290+
var language = data.language || 'en';
291+
292+
var fallbackSearch = function () {
293+
if (typeof window.doSearchFallback !== 'undefined') {
294+
window.doSearchFallback();
295+
} else {
296+
console.log('Unable to fallback to original MkDocs search.');
297+
}
298+
};
299+
300+
var doSearch = function () {
301+
var query = document.getElementById('mkdocs-search-query').value;
302+
303+
var search_def = $.Deferred();
304+
305+
var search_url = document.createElement('a');
306+
search_url.href = data.proxied_api_host + '/api/v2/docsearch/';
307+
search_url.search = '?q=' + encodeURIComponent(query) + '&project=' + project +
308+
'&version=' + version + '&language=' + language;
309+
310+
search_def
311+
.then(function (data) {
312+
var hit_list = data.results || [];
313+
314+
if (hit_list.length) {
315+
var searchResults = $('#mkdocs-search-results');
316+
searchResults.empty();
317+
318+
for (var i = 0; i < hit_list.length; i += 1) {
319+
var doc = hit_list[i];
320+
var inner_hits = doc.inner_hits || [];
321+
322+
var result = $('<article>');
323+
result.append(
324+
$('<h3>').append($('<a>', {'href': doc.link, 'text': doc.title}))
325+
);
326+
327+
if (doc.project !== project) {
328+
var text = '(from project ' + doc.project + ')';
329+
result.append($('<span>', {'text': text}));
330+
}
331+
332+
for (var j = 0; j < inner_hits.length; j += 1) {
333+
var section = inner_hits[j];
334+
335+
if (section.type === 'sections') {
336+
var section_link = doc.link + '#' + section._source.id;
337+
var section_title = section._source.title;
338+
var section_content = section._source.content.substr(0, MAX_SUBSTRING_LIMIT) + " ...";
339+
340+
result.append(
341+
$('<h4>').append($('<a>', {'href': section_link, 'text': section_title}))
342+
);
343+
result.append(
344+
$('<p>', {'text': section_content})
345+
);
346+
searchResults.append(result);
347+
}
348+
}
349+
}
350+
} else {
351+
console.log('Read the Docs search returned 0 result. Falling back to MkDocs search.');
352+
fallbackSearch();
353+
}
354+
})
355+
.fail(function (error) {
356+
console.log('Read the Docs search failed. Falling back to MkDocs search.');
357+
fallbackSearch();
358+
});
359+
360+
$.ajax({
361+
url: search_url.href,
362+
crossDomain: true,
363+
xhrFields: {
364+
withCredentials: true,
365+
},
366+
complete: function (resp, status_code) {
367+
if (
368+
status_code !== 'success' ||
369+
typeof (resp.responseJSON) === 'undefined' ||
370+
resp.responseJSON.count === 0
371+
) {
372+
return search_def.reject();
373+
}
374+
return search_def.resolve(resp.responseJSON);
375+
}
376+
})
377+
.fail(function (resp, status_code, error) {
378+
return search_def.reject();
379+
});
380+
};
381+
382+
var initSearch = function () {
383+
var search_input = document.getElementById('mkdocs-search-query');
384+
if (search_input) {
385+
search_input.addEventListener('keyup', doSearch);
386+
}
387+
388+
var term = window.getSearchTermFromLocation();
389+
if (term) {
390+
search_input.value = term;
391+
doSearch();
392+
}
393+
};
394+
395+
$(document).ready(function () {
396+
// We can't override the search completely,
397+
// because we can't delete the original event listener,
398+
// and MkDocs includes its search functions after ours.
399+
// If MkDocs is loaded before, this will trigger a double search
400+
// (but ours will have precendece).
401+
402+
// Note: this function is only available on Mkdocs >=1.x
403+
window.doSearchFallback = window.doSearch;
404+
405+
window.doSearch = doSearch;
406+
window.initSearch = initSearch;
407+
initSearch();
408+
});
409+
}
410+
411+
412+
291413
function init() {
292414
var data = rtddata.get();
293-
attach_elastic_search_query(data);
415+
// Do not replace the built-in search if RTD's docsearch is disabled
416+
if (!data.features || !data.features.docsearch_disabled) {
417+
if (data.is_sphinx_builder()) {
418+
attach_elastic_search_query_sphinx(data);
419+
} else {
420+
// MkDocs projects should have this flag explicitly for now.
421+
if (data.features && !data.features.docsearch_disabled) {
422+
attach_elastic_search_query_mkdocs(data);
423+
}
424+
}
425+
}
294426
}
295427

296428
module.exports = {

readthedocs/projects/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1672,7 +1672,7 @@ def add_features(sender, **kwargs):
16721672
ENABLE_MKDOCS_SERVER_SIDE_SEARCH,
16731673
_('Enable server side search for MkDocs projects'),
16741674
),
1675-
),
1675+
)
16761676

16771677
projects = models.ManyToManyField(
16781678
Project,

0 commit comments

Comments
 (0)