You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
6.2 KiB
213 lines
6.2 KiB
require([ |
|
'gitbook', |
|
'jquery' |
|
], function(gitbook, $) { |
|
var MAX_RESULTS = 15; |
|
var MAX_DESCRIPTION_SIZE = 500; |
|
|
|
var usePushState = (typeof history.pushState !== 'undefined'); |
|
|
|
// DOM Elements |
|
var $body = $('body'); |
|
var $bookSearchResults; |
|
var $searchInput; |
|
var $searchList; |
|
var $searchTitle; |
|
var $searchResultsCount; |
|
var $searchQuery; |
|
|
|
// Throttle search |
|
function throttle(fn, wait) { |
|
var timeout; |
|
|
|
return function() { |
|
var ctx = this, args = arguments; |
|
if (!timeout) { |
|
timeout = setTimeout(function() { |
|
timeout = null; |
|
fn.apply(ctx, args); |
|
}, wait); |
|
} |
|
}; |
|
} |
|
|
|
function displayResults(res) { |
|
$bookSearchResults.addClass('open'); |
|
|
|
var noResults = res.count == 0; |
|
$bookSearchResults.toggleClass('no-results', noResults); |
|
|
|
// Clear old results |
|
$searchList.empty(); |
|
|
|
// Display title for research |
|
$searchResultsCount.text(res.count); |
|
$searchQuery.text(res.query); |
|
|
|
// Create an <li> element for each result |
|
res.results.forEach(function(res) { |
|
var $li = $('<li>', { |
|
'class': 'search-results-item' |
|
}); |
|
|
|
var $title = $('<h3>'); |
|
|
|
var $link = $('<a>', { |
|
'href': gitbook.state.basePath + '/' + res.url, |
|
'text': res.title |
|
}); |
|
|
|
var content = res.body.trim(); |
|
if (content.length > MAX_DESCRIPTION_SIZE) { |
|
content = content.slice(0, MAX_DESCRIPTION_SIZE).trim()+'...'; |
|
} |
|
var $content = $('<p>').html(content); |
|
|
|
$link.appendTo($title); |
|
$title.appendTo($li); |
|
$content.appendTo($li); |
|
$li.appendTo($searchList); |
|
}); |
|
} |
|
|
|
function launchSearch(q) { |
|
// Add class for loading |
|
$body.addClass('with-search'); |
|
$body.addClass('search-loading'); |
|
|
|
// Launch search query |
|
throttle(gitbook.search.query(q, 0, MAX_RESULTS) |
|
.then(function(results) { |
|
displayResults(results); |
|
}) |
|
.always(function() { |
|
$body.removeClass('search-loading'); |
|
}), 1000); |
|
} |
|
|
|
function closeSearch() { |
|
$body.removeClass('with-search'); |
|
$bookSearchResults.removeClass('open'); |
|
} |
|
|
|
function launchSearchFromQueryString() { |
|
var q = getParameterByName('q'); |
|
if (q && q.length > 0) { |
|
// Update search input |
|
$searchInput.val(q); |
|
|
|
// Launch search |
|
launchSearch(q); |
|
} |
|
} |
|
|
|
function bindSearch() { |
|
// Bind DOM |
|
$searchInput = $('#book-search-input input'); |
|
$bookSearchResults = $('#book-search-results'); |
|
$searchList = $bookSearchResults.find('.search-results-list'); |
|
$searchTitle = $bookSearchResults.find('.search-results-title'); |
|
$searchResultsCount = $searchTitle.find('.search-results-count'); |
|
$searchQuery = $searchTitle.find('.search-query'); |
|
|
|
// Launch query based on input content |
|
function handleUpdate() { |
|
var q = $searchInput.val(); |
|
|
|
if (q.length == 0) { |
|
closeSearch(); |
|
} |
|
else { |
|
launchSearch(q); |
|
} |
|
} |
|
|
|
// Detect true content change in search input |
|
// Workaround for IE < 9 |
|
var propertyChangeUnbound = false; |
|
$searchInput.on('propertychange', function(e) { |
|
if (e.originalEvent.propertyName == 'value') { |
|
handleUpdate(); |
|
} |
|
}); |
|
|
|
// HTML5 (IE9 & others) |
|
$searchInput.on('input', function(e) { |
|
// Unbind propertychange event for IE9+ |
|
if (!propertyChangeUnbound) { |
|
$(this).unbind('propertychange'); |
|
propertyChangeUnbound = true; |
|
} |
|
|
|
handleUpdate(); |
|
}); |
|
|
|
// Push to history on blur |
|
$searchInput.on('blur', function(e) { |
|
// Update history state |
|
if (usePushState) { |
|
var uri = updateQueryString('q', $(this).val()); |
|
history.pushState({ path: uri }, null, uri); |
|
} |
|
}); |
|
} |
|
|
|
gitbook.events.on('page.change', function() { |
|
bindSearch(); |
|
closeSearch(); |
|
|
|
// Launch search based on query parameter |
|
if (gitbook.search.isInitialized()) { |
|
launchSearchFromQueryString(); |
|
} |
|
}); |
|
|
|
gitbook.events.on('search.ready', function() { |
|
bindSearch(); |
|
|
|
// Launch search from query param at start |
|
launchSearchFromQueryString(); |
|
}); |
|
|
|
function getParameterByName(name) { |
|
var url = window.location.href; |
|
name = name.replace(/[\[\]]/g, '\\$&'); |
|
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)', 'i'), |
|
results = regex.exec(url); |
|
if (!results) return null; |
|
if (!results[2]) return ''; |
|
return decodeURIComponent(results[2].replace(/\+/g, ' ')); |
|
} |
|
|
|
function updateQueryString(key, value) { |
|
value = encodeURIComponent(value); |
|
|
|
var url = window.location.href; |
|
var re = new RegExp('([?&])' + key + '=.*?(&|#|$)(.*)', 'gi'), |
|
hash; |
|
|
|
if (re.test(url)) { |
|
if (typeof value !== 'undefined' && value !== null) |
|
return url.replace(re, '$1' + key + '=' + value + '$2$3'); |
|
else { |
|
hash = url.split('#'); |
|
url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, ''); |
|
if (typeof hash[1] !== 'undefined' && hash[1] !== null) |
|
url += '#' + hash[1]; |
|
return url; |
|
} |
|
} |
|
else { |
|
if (typeof value !== 'undefined' && value !== null) { |
|
var separator = url.indexOf('?') !== -1 ? '&' : '?'; |
|
hash = url.split('#'); |
|
url = hash[0] + separator + key + '=' + value; |
|
if (typeof hash[1] !== 'undefined' && hash[1] !== null) |
|
url += '#' + hash[1]; |
|
return url; |
|
} |
|
else |
|
return url; |
|
} |
|
} |
|
});
|
|
|