2014-01-10 04:59:53 +00:00
|
|
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
2013-09-19 05:18:38 +00:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
|
|
/*jslint browser: true, es5: true */
|
2014-03-16 08:08:56 +00:00
|
|
|
/*globals $: true, rootPath: true, allPaths: true */
|
2013-09-19 05:18:38 +00:00
|
|
|
|
2014-01-10 04:59:53 +00:00
|
|
|
(function() {
|
2013-09-19 05:18:38 +00:00
|
|
|
"use strict";
|
|
|
|
var resizeTimeout, interval;
|
|
|
|
|
|
|
|
$('.js-only').removeClass('js-only');
|
|
|
|
|
2014-01-23 01:44:27 +00:00
|
|
|
function getQueryStringParams() {
|
|
|
|
var params = {};
|
|
|
|
window.location.search.substring(1).split("&").
|
|
|
|
map(function(s) {
|
|
|
|
var pair = s.split("=");
|
|
|
|
params[decodeURIComponent(pair[0])] =
|
2014-03-16 08:08:56 +00:00
|
|
|
typeof pair[1] === "undefined" ?
|
|
|
|
null : decodeURIComponent(pair[1]);
|
2014-01-23 01:44:27 +00:00
|
|
|
});
|
|
|
|
return params;
|
|
|
|
}
|
|
|
|
|
|
|
|
function browserSupportsHistoryApi() {
|
|
|
|
return window.history && typeof window.history.pushState === "function";
|
|
|
|
}
|
|
|
|
|
2013-09-19 05:18:38 +00:00
|
|
|
function resizeShortBlocks() {
|
|
|
|
if (resizeTimeout) {
|
|
|
|
clearTimeout(resizeTimeout);
|
|
|
|
}
|
2014-01-10 04:59:53 +00:00
|
|
|
resizeTimeout = setTimeout(function() {
|
2013-09-19 05:18:38 +00:00
|
|
|
var contentWidth = $('.content').width();
|
2014-01-10 04:59:53 +00:00
|
|
|
$('.docblock.short').width(function() {
|
2013-09-19 05:18:38 +00:00
|
|
|
return contentWidth - 40 - $(this).prev().width();
|
|
|
|
}).addClass('nowrap');
|
|
|
|
}, 150);
|
|
|
|
}
|
|
|
|
resizeShortBlocks();
|
|
|
|
$(window).on('resize', resizeShortBlocks);
|
|
|
|
|
2013-10-02 17:32:13 +00:00
|
|
|
function highlightSourceLines() {
|
|
|
|
var i, from, to, match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
|
|
|
|
if (match) {
|
|
|
|
from = parseInt(match[1], 10);
|
|
|
|
to = Math.min(50000, parseInt(match[2] || match[1], 10));
|
|
|
|
from = Math.min(from, to);
|
|
|
|
if ($('#' + from).length === 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$('#' + from)[0].scrollIntoView();
|
|
|
|
$('.line-numbers span').removeClass('line-highlighted');
|
|
|
|
for (i = from; i <= to; i += 1) {
|
|
|
|
$('#' + i).addClass('line-highlighted');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
highlightSourceLines();
|
|
|
|
$(window).on('hashchange', highlightSourceLines);
|
|
|
|
|
2014-01-10 04:59:53 +00:00
|
|
|
$(document).on('keyup', function(e) {
|
2013-09-19 05:18:38 +00:00
|
|
|
if (document.activeElement.tagName === 'INPUT') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e.keyCode === 188 && $('#help').hasClass('hidden')) { // question mark
|
|
|
|
e.preventDefault();
|
|
|
|
$('#help').removeClass('hidden');
|
2013-09-27 18:06:07 +00:00
|
|
|
} else if (e.keyCode === 27) { // esc
|
|
|
|
if (!$('#help').hasClass('hidden')) {
|
|
|
|
e.preventDefault();
|
|
|
|
$('#help').addClass('hidden');
|
|
|
|
} else if (!$('#search').hasClass('hidden')) {
|
|
|
|
e.preventDefault();
|
|
|
|
$('#search').addClass('hidden');
|
|
|
|
$('#main').removeClass('hidden');
|
|
|
|
}
|
2013-09-19 05:18:38 +00:00
|
|
|
} else if (e.keyCode === 83) { // S
|
|
|
|
e.preventDefault();
|
|
|
|
$('.search-input').focus();
|
|
|
|
}
|
2014-01-10 04:59:53 +00:00
|
|
|
}).on('click', function(e) {
|
2013-09-19 05:18:38 +00:00
|
|
|
if (!$(e.target).closest('#help').length) {
|
|
|
|
$('#help').addClass('hidden');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2014-01-10 04:59:53 +00:00
|
|
|
$('.version-selector').on('change', function() {
|
2013-09-19 05:18:38 +00:00
|
|
|
var i, match,
|
|
|
|
url = document.location.href,
|
|
|
|
stripped = '',
|
|
|
|
len = rootPath.match(/\.\.\//g).length + 1;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i += 1) {
|
|
|
|
match = url.match(/\/[^\/]*$/);
|
|
|
|
if (i < len - 1) {
|
|
|
|
stripped = match[0] + stripped;
|
|
|
|
}
|
|
|
|
url = url.substring(0, url.length - match[0].length);
|
|
|
|
}
|
|
|
|
|
|
|
|
url += '/' + $('.version-selector').val() + stripped;
|
|
|
|
|
|
|
|
document.location.href = url;
|
|
|
|
});
|
|
|
|
|
2014-03-16 08:08:56 +00:00
|
|
|
function initSearch(rawSearchIndex) {
|
|
|
|
var currentResults, index, searchIndex;
|
|
|
|
var params = getQueryStringParams();
|
2013-09-19 05:18:38 +00:00
|
|
|
|
2014-02-21 07:15:08 +00:00
|
|
|
// Populate search bar with query string search term when provided,
|
|
|
|
// but only if the input bar is empty. This avoid the obnoxious issue
|
|
|
|
// where you start trying to do a search, and the index loads, and
|
|
|
|
// suddenly your search is gone!
|
|
|
|
if ($(".search-input")[0].value === "") {
|
|
|
|
$(".search-input")[0].value = params.search || '';
|
|
|
|
}
|
2013-09-19 05:18:38 +00:00
|
|
|
|
2014-01-10 04:59:53 +00:00
|
|
|
/**
|
|
|
|
* Executes the query and builds an index of results
|
|
|
|
* @param {[Object]} query [The user query]
|
|
|
|
* @param {[type]} max [The maximum results returned]
|
2014-03-16 08:08:56 +00:00
|
|
|
* @param {[type]} searchWords [The list of search words to query
|
|
|
|
* against]
|
2014-01-10 04:59:53 +00:00
|
|
|
* @return {[type]} [A search index of results]
|
|
|
|
*/
|
2013-09-19 05:18:38 +00:00
|
|
|
function execQuery(query, max, searchWords) {
|
|
|
|
var valLower = query.query.toLowerCase(),
|
|
|
|
val = valLower,
|
|
|
|
typeFilter = query.type,
|
|
|
|
results = [],
|
|
|
|
aa = 0,
|
2014-01-10 04:59:53 +00:00
|
|
|
bb = 0,
|
|
|
|
split = valLower.split("::");
|
|
|
|
|
|
|
|
//remove empty keywords
|
|
|
|
for (var j = 0; j < split.length; j++) {
|
|
|
|
split[j].toLowerCase();
|
|
|
|
if (split[j] === "") {
|
|
|
|
split.splice(j, 1);
|
|
|
|
}
|
|
|
|
}
|
2013-09-19 05:18:38 +00:00
|
|
|
|
|
|
|
// quoted values mean literal search
|
|
|
|
bb = searchWords.length;
|
2014-03-16 08:08:56 +00:00
|
|
|
if ((val.charAt(0) === "\"" || val.charAt(0) === "'") &&
|
|
|
|
val.charAt(val.length - 1) === val.charAt(0))
|
|
|
|
{
|
2013-09-19 05:18:38 +00:00
|
|
|
val = val.substr(1, val.length - 2);
|
|
|
|
for (aa = 0; aa < bb; aa += 1) {
|
|
|
|
if (searchWords[aa] === val) {
|
|
|
|
// filter type: ... queries
|
|
|
|
if (!typeFilter || typeFilter === searchIndex[aa].ty) {
|
|
|
|
results.push([aa, -1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (results.length === max) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// gather matching search results up to a certain maximum
|
|
|
|
val = val.replace(/\_/g, "");
|
2014-01-10 04:59:53 +00:00
|
|
|
for (var i = 0; i < split.length; i++) {
|
|
|
|
for (aa = 0; aa < bb; aa += 1) {
|
2014-03-16 08:08:56 +00:00
|
|
|
if (searchWords[aa].indexOf(split[i]) > -1 ||
|
|
|
|
searchWords[aa].indexOf(val) > -1 ||
|
|
|
|
searchWords[aa].replace(/_/g, "").indexOf(val) > -1)
|
|
|
|
{
|
2014-01-10 04:59:53 +00:00
|
|
|
// filter type: ... queries
|
|
|
|
if (!typeFilter || typeFilter === searchIndex[aa].ty) {
|
|
|
|
results.push([aa, searchWords[aa].replace(/_/g, "").indexOf(val)]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (results.length === max) {
|
|
|
|
break;
|
2013-09-19 05:18:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-01-10 04:59:53 +00:00
|
|
|
|
2013-09-19 05:18:38 +00:00
|
|
|
bb = results.length;
|
|
|
|
for (aa = 0; aa < bb; aa += 1) {
|
|
|
|
results[aa].push(searchIndex[results[aa][0]].ty);
|
|
|
|
results[aa].push(searchIndex[results[aa][0]].path);
|
2014-01-10 04:59:53 +00:00
|
|
|
results[aa].push(searchIndex[results[aa][0]].name);
|
|
|
|
results[aa].push(searchIndex[results[aa][0]].parent);
|
2014-03-16 08:08:56 +00:00
|
|
|
results[aa].push(searchIndex[results[aa][0]].crate);
|
2013-09-19 05:18:38 +00:00
|
|
|
}
|
|
|
|
// if there are no results then return to default and fail
|
|
|
|
if (results.length === 0) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
// sort by exact match
|
|
|
|
results.sort(function search_complete_sort0(aaa, bbb) {
|
2014-03-16 08:08:56 +00:00
|
|
|
if (searchWords[aaa[0]] === valLower &&
|
|
|
|
searchWords[bbb[0]] !== valLower) {
|
2013-09-19 05:18:38 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// first sorting attempt
|
|
|
|
// sort by item name length
|
|
|
|
results.sort(function search_complete_sort1(aaa, bbb) {
|
|
|
|
if (searchWords[aaa[0]].length > searchWords[bbb[0]].length) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// second sorting attempt
|
|
|
|
// sort by item name
|
|
|
|
results.sort(function search_complete_sort1(aaa, bbb) {
|
2014-03-16 08:08:56 +00:00
|
|
|
if (searchWords[aaa[0]].length === searchWords[bbb[0]].length &&
|
|
|
|
searchWords[aaa[0]] > searchWords[bbb[0]]) {
|
2013-09-19 05:18:38 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// third sorting attempt
|
|
|
|
// sort by index of keyword in item name
|
|
|
|
if (results[0][1] !== -1) {
|
|
|
|
results.sort(function search_complete_sort1(aaa, bbb) {
|
|
|
|
if (aaa[1] > bbb[1] && bbb[1] === 0) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
// fourth sorting attempt
|
|
|
|
// sort by type
|
|
|
|
results.sort(function search_complete_sort3(aaa, bbb) {
|
2014-03-16 08:08:56 +00:00
|
|
|
if (searchWords[aaa[0]] === searchWords[bbb[0]] &&
|
|
|
|
aaa[2] > bbb[2]) {
|
2013-09-19 05:18:38 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// fifth sorting attempt
|
|
|
|
// sort by path
|
|
|
|
results.sort(function search_complete_sort4(aaa, bbb) {
|
2014-03-16 08:08:56 +00:00
|
|
|
if (searchWords[aaa[0]] === searchWords[bbb[0]] &&
|
|
|
|
aaa[2] === bbb[2] && aaa[3] > bbb[3]) {
|
2013-09-19 05:18:38 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// sixth sorting attempt
|
|
|
|
// remove duplicates, according to the data provided
|
|
|
|
for (aa = results.length - 1; aa > 0; aa -= 1) {
|
2014-03-16 08:08:56 +00:00
|
|
|
if (searchWords[results[aa][0]] === searchWords[results[aa - 1][0]] &&
|
|
|
|
results[aa][2] === results[aa - 1][2] &&
|
|
|
|
results[aa][3] === results[aa - 1][3])
|
|
|
|
{
|
2013-09-19 05:18:38 +00:00
|
|
|
results[aa][0] = -1;
|
|
|
|
}
|
|
|
|
}
|
2014-01-10 04:59:53 +00:00
|
|
|
for (var i = 0; i < results.length; i++) {
|
|
|
|
var result = results[i],
|
|
|
|
name = result[4].toLowerCase(),
|
|
|
|
path = result[3].toLowerCase(),
|
2014-03-16 08:08:56 +00:00
|
|
|
parent = allPaths[result[6]][result[5]];
|
2014-01-10 04:59:53 +00:00
|
|
|
|
|
|
|
var valid = validateResult(name, path, split, parent);
|
|
|
|
if (!valid) {
|
|
|
|
result[0] = -1;
|
|
|
|
}
|
|
|
|
}
|
2013-09-19 05:18:38 +00:00
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
2014-01-10 04:59:53 +00:00
|
|
|
/**
|
2014-03-16 08:08:56 +00:00
|
|
|
* Validate performs the following boolean logic. For example:
|
|
|
|
* "File::open" will give IF A PARENT EXISTS => ("file" && "open")
|
|
|
|
* exists in (name || path || parent) OR => ("file" && "open") exists in
|
|
|
|
* (name || path )
|
|
|
|
*
|
|
|
|
* This could be written functionally, but I wanted to minimise
|
|
|
|
* functions on stack.
|
2014-01-10 04:59:53 +00:00
|
|
|
*
|
|
|
|
* @param {[string]} name [The name of the result]
|
|
|
|
* @param {[string]} path [The path of the result]
|
|
|
|
* @param {[string]} keys [The keys to be used (["file", "open"])]
|
|
|
|
* @param {[object]} parent [The parent of the result]
|
|
|
|
* @return {[boolean]} [Whether the result is valid or not]
|
|
|
|
*/
|
|
|
|
function validateResult(name, path, keys, parent) {
|
|
|
|
//initially valid
|
|
|
|
var validate = true;
|
|
|
|
//if there is a parent, then validate against parent
|
|
|
|
if (parent !== undefined) {
|
|
|
|
for (var i = 0; i < keys.length; i++) {
|
2014-03-16 08:08:56 +00:00
|
|
|
// if previous keys are valid and current key is in the
|
|
|
|
// path, name or parent
|
|
|
|
if ((validate) &&
|
|
|
|
(name.toLowerCase().indexOf(keys[i]) > -1 ||
|
|
|
|
path.toLowerCase().indexOf(keys[i]) > -1 ||
|
|
|
|
parent.name.toLowerCase().indexOf(keys[i]) > -1))
|
|
|
|
{
|
2014-01-10 04:59:53 +00:00
|
|
|
validate = true;
|
|
|
|
} else {
|
|
|
|
validate = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (var i = 0; i < keys.length; i++) {
|
2014-03-16 08:08:56 +00:00
|
|
|
// if previous keys are valid and current key is in the
|
|
|
|
// path, name
|
|
|
|
if ((validate) &&
|
|
|
|
(name.toLowerCase().indexOf(keys[i]) > -1 ||
|
|
|
|
path.toLowerCase().indexOf(keys[i]) > -1))
|
|
|
|
{
|
2014-01-10 04:59:53 +00:00
|
|
|
validate = true;
|
|
|
|
} else {
|
|
|
|
validate = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return validate;
|
|
|
|
}
|
|
|
|
|
2013-09-19 05:18:38 +00:00
|
|
|
function getQuery() {
|
|
|
|
var matches, type, query = $('.search-input').val();
|
|
|
|
|
|
|
|
matches = query.match(/^(fn|mod|str(uct)?|enum|trait|t(ype)?d(ef)?)\s*:\s*/i);
|
|
|
|
if (matches) {
|
2014-03-16 08:08:56 +00:00
|
|
|
type = matches[1].replace(/^td$/, 'typedef')
|
|
|
|
.replace(/^str$/, 'struct')
|
|
|
|
.replace(/^tdef$/, 'typedef')
|
|
|
|
.replace(/^typed$/, 'typedef');
|
2013-09-19 05:18:38 +00:00
|
|
|
query = query.substring(matches[0].length);
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
query: query,
|
|
|
|
type: type,
|
|
|
|
id: query + type,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function initSearchNav() {
|
|
|
|
var hoverTimeout, $results = $('.search-results .result');
|
|
|
|
|
2014-01-10 04:59:53 +00:00
|
|
|
$results.on('click', function() {
|
2013-09-27 18:06:07 +00:00
|
|
|
var dst = $(this).find('a')[0];
|
|
|
|
if (window.location.pathname == dst.pathname) {
|
|
|
|
$('#search').addClass('hidden');
|
|
|
|
$('#main').removeClass('hidden');
|
|
|
|
}
|
|
|
|
document.location.href = dst.href;
|
2014-01-10 04:59:53 +00:00
|
|
|
}).on('mouseover', function() {
|
2013-09-19 05:18:38 +00:00
|
|
|
var $el = $(this);
|
|
|
|
clearTimeout(hoverTimeout);
|
2014-01-10 04:59:53 +00:00
|
|
|
hoverTimeout = setTimeout(function() {
|
2013-09-19 05:18:38 +00:00
|
|
|
$results.removeClass('highlighted');
|
|
|
|
$el.addClass('highlighted');
|
|
|
|
}, 20);
|
|
|
|
});
|
|
|
|
|
2013-09-30 22:35:29 +00:00
|
|
|
$(document).off('keypress.searchnav');
|
2014-01-10 04:59:53 +00:00
|
|
|
$(document).on('keypress.searchnav', function(e) {
|
2013-09-19 05:18:38 +00:00
|
|
|
var $active = $results.filter('.highlighted');
|
|
|
|
|
|
|
|
if (e.keyCode === 38) { // up
|
|
|
|
e.preventDefault();
|
|
|
|
if (!$active.length || !$active.prev()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$active.prev().addClass('highlighted');
|
|
|
|
$active.removeClass('highlighted');
|
|
|
|
} else if (e.keyCode === 40) { // down
|
|
|
|
e.preventDefault();
|
|
|
|
if (!$active.length) {
|
|
|
|
$results.first().addClass('highlighted');
|
|
|
|
} else if ($active.next().length) {
|
|
|
|
$active.next().addClass('highlighted');
|
|
|
|
$active.removeClass('highlighted');
|
|
|
|
}
|
|
|
|
} else if (e.keyCode === 13) { // return
|
|
|
|
e.preventDefault();
|
|
|
|
if ($active.length) {
|
|
|
|
document.location.href = $active.find('a').prop('href');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function showResults(results) {
|
|
|
|
var output, shown, query = getQuery();
|
|
|
|
|
|
|
|
currentResults = query.id;
|
2014-03-16 08:08:56 +00:00
|
|
|
output = '<h1>Results for ' + query.query +
|
|
|
|
(query.type ? ' (type: ' + query.type + ')' : '') + '</h1>';
|
2013-09-19 05:18:38 +00:00
|
|
|
output += '<table class="search-results">';
|
|
|
|
|
|
|
|
if (results.length > 0) {
|
|
|
|
shown = [];
|
|
|
|
|
2014-01-10 04:59:53 +00:00
|
|
|
results.forEach(function(item) {
|
2013-09-19 05:18:38 +00:00
|
|
|
var name, type;
|
|
|
|
|
|
|
|
if (shown.indexOf(item) !== -1) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
shown.push(item);
|
|
|
|
name = item.name;
|
|
|
|
type = item.ty;
|
|
|
|
|
|
|
|
output += '<tr class="' + type + ' result"><td>';
|
|
|
|
|
|
|
|
if (type === 'mod') {
|
2013-09-27 17:40:41 +00:00
|
|
|
output += item.path +
|
|
|
|
'::<a href="' + rootPath +
|
2014-01-10 04:59:53 +00:00
|
|
|
item.path.replace(/::/g, '/') + '/' +
|
|
|
|
name + '/index.html" class="' +
|
|
|
|
type + '">' + name + '</a>';
|
2013-09-19 05:18:38 +00:00
|
|
|
} else if (type === 'static' || type === 'reexport') {
|
2013-09-27 17:40:41 +00:00
|
|
|
output += item.path +
|
|
|
|
'::<a href="' + rootPath +
|
2014-01-10 04:59:53 +00:00
|
|
|
item.path.replace(/::/g, '/') +
|
|
|
|
'/index.html" class="' + type +
|
|
|
|
'">' + name + '</a>';
|
2013-09-19 05:18:38 +00:00
|
|
|
} else if (item.parent !== undefined) {
|
2014-03-16 08:08:56 +00:00
|
|
|
var myparent = allPaths[item.crate][item.parent];
|
2013-09-27 17:40:41 +00:00
|
|
|
var anchor = '#' + type + '.' + name;
|
|
|
|
output += item.path + '::' + myparent.name +
|
|
|
|
'::<a href="' + rootPath +
|
2014-01-10 04:59:53 +00:00
|
|
|
item.path.replace(/::/g, '/') +
|
|
|
|
'/' + myparent.type +
|
|
|
|
'.' + myparent.name +
|
|
|
|
'.html' + anchor +
|
|
|
|
'" class="' + type +
|
|
|
|
'">' + name + '</a>';
|
2013-09-19 05:18:38 +00:00
|
|
|
} else {
|
2013-09-27 17:40:41 +00:00
|
|
|
output += item.path +
|
|
|
|
'::<a href="' + rootPath +
|
2014-01-10 04:59:53 +00:00
|
|
|
item.path.replace(/::/g, '/') +
|
|
|
|
'/' + type +
|
|
|
|
'.' + name +
|
|
|
|
'.html" class="' + type +
|
|
|
|
'">' + name + '</a>';
|
2013-09-19 05:18:38 +00:00
|
|
|
}
|
|
|
|
|
2013-09-27 17:40:41 +00:00
|
|
|
output += '</td><td><span class="desc">' + item.desc +
|
2014-01-10 04:59:53 +00:00
|
|
|
'</span></td></tr>';
|
2013-09-19 05:18:38 +00:00
|
|
|
});
|
|
|
|
} else {
|
2013-09-27 17:40:41 +00:00
|
|
|
output += 'No results :( <a href="https://duckduckgo.com/?q=' +
|
2014-01-10 04:59:53 +00:00
|
|
|
encodeURIComponent('rust ' + query.query) +
|
|
|
|
'">Try on DuckDuckGo?</a>';
|
2013-09-19 05:18:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
output += "</p>";
|
2013-09-27 18:06:07 +00:00
|
|
|
$('#main.content').addClass('hidden');
|
|
|
|
$('#search.content').removeClass('hidden').html(output);
|
2013-09-30 22:35:29 +00:00
|
|
|
$('#search .desc').width($('#search').width() - 40 -
|
2014-01-10 04:59:53 +00:00
|
|
|
$('#search td:first-child').first().width());
|
2013-09-19 05:18:38 +00:00
|
|
|
initSearchNav();
|
|
|
|
}
|
|
|
|
|
|
|
|
function search(e) {
|
2014-01-10 04:59:53 +00:00
|
|
|
var query,
|
|
|
|
filterdata = [],
|
|
|
|
obj, i, len,
|
2013-09-19 05:18:38 +00:00
|
|
|
results = [],
|
|
|
|
maxResults = 200,
|
|
|
|
resultIndex;
|
2014-01-23 01:44:27 +00:00
|
|
|
var params = getQueryStringParams();
|
2013-09-19 05:18:38 +00:00
|
|
|
|
|
|
|
query = getQuery();
|
|
|
|
if (e) {
|
|
|
|
e.preventDefault();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!query.query || query.id === currentResults) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-16 08:08:56 +00:00
|
|
|
// Because searching is incremental by character, only the most
|
|
|
|
// recent search query is added to the browser history.
|
2014-01-23 01:44:27 +00:00
|
|
|
if (browserSupportsHistoryApi()) {
|
|
|
|
if (!history.state && !params.search) {
|
2014-03-16 08:08:56 +00:00
|
|
|
history.pushState(query, "", "?search=" +
|
|
|
|
encodeURIComponent(query.query));
|
2014-01-23 01:44:27 +00:00
|
|
|
} else {
|
2014-03-16 08:08:56 +00:00
|
|
|
history.replaceState(query, "", "?search=" +
|
|
|
|
encodeURIComponent(query.query));
|
2014-01-23 01:44:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-19 05:18:38 +00:00
|
|
|
resultIndex = execQuery(query, 20000, index);
|
|
|
|
len = resultIndex.length;
|
|
|
|
for (i = 0; i < len; i += 1) {
|
|
|
|
if (resultIndex[i][0] > -1) {
|
|
|
|
obj = searchIndex[resultIndex[i][0]];
|
|
|
|
filterdata.push([obj.name, obj.ty, obj.path, obj.desc]);
|
|
|
|
results.push(obj);
|
|
|
|
}
|
|
|
|
if (results.length >= maxResults) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
showResults(results);
|
|
|
|
}
|
|
|
|
|
2014-03-16 08:08:56 +00:00
|
|
|
function buildIndex(rawSearchIndex) {
|
|
|
|
searchIndex = [];
|
|
|
|
var searchWords = [];
|
|
|
|
for (var crate in rawSearchIndex) {
|
|
|
|
if (!rawSearchIndex.hasOwnProperty(crate)) { continue }
|
|
|
|
var len = rawSearchIndex[crate].length;
|
|
|
|
var i = 0;
|
|
|
|
|
|
|
|
// before any analysis is performed lets gather the search terms to
|
|
|
|
// search against apart from the rest of the data. This is a quick
|
|
|
|
// operation that is cached for the life of the page state so that
|
|
|
|
// all other search operations have access to this cached data for
|
|
|
|
// faster analysis operations
|
|
|
|
for (i = 0; i < len; i += 1) {
|
|
|
|
rawSearchIndex[crate][i].crate = crate;
|
|
|
|
searchIndex.push(rawSearchIndex[crate][i]);
|
|
|
|
if (typeof rawSearchIndex[crate][i].name === "string") {
|
|
|
|
var word = rawSearchIndex[crate][i].name.toLowerCase();
|
|
|
|
searchWords.push(word);
|
|
|
|
} else {
|
|
|
|
searchWords.push("");
|
|
|
|
}
|
2013-09-19 05:18:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return searchWords;
|
|
|
|
}
|
|
|
|
|
|
|
|
function startSearch() {
|
|
|
|
var keyUpTimeout;
|
|
|
|
$('.do-search').on('click', search);
|
2014-01-10 04:59:53 +00:00
|
|
|
$('.search-input').on('keyup', function() {
|
2013-09-19 05:18:38 +00:00
|
|
|
clearTimeout(keyUpTimeout);
|
|
|
|
keyUpTimeout = setTimeout(search, 100);
|
|
|
|
});
|
2014-03-16 08:08:56 +00:00
|
|
|
|
|
|
|
// Push and pop states are used to add search results to the browser
|
|
|
|
// history.
|
2014-01-23 01:44:27 +00:00
|
|
|
if (browserSupportsHistoryApi()) {
|
|
|
|
$(window).on('popstate', function(e) {
|
|
|
|
var params = getQueryStringParams();
|
2014-03-16 08:08:56 +00:00
|
|
|
// When browsing back from search results the main page
|
|
|
|
// visibility must be reset.
|
2014-01-23 01:44:27 +00:00
|
|
|
if (!params.search) {
|
|
|
|
$('#main.content').removeClass('hidden');
|
|
|
|
$('#search.content').addClass('hidden');
|
|
|
|
}
|
2014-03-16 08:08:56 +00:00
|
|
|
// When browsing forward to search results the previous
|
|
|
|
// search will be repeated, so the currentResults are
|
|
|
|
// cleared to ensure the search is successful.
|
2014-01-23 01:44:27 +00:00
|
|
|
currentResults = null;
|
2014-02-21 07:15:08 +00:00
|
|
|
// Synchronize search bar with query string state and
|
|
|
|
// perform the search, but don't empty the bar if there's
|
|
|
|
// nothing there.
|
2014-02-23 01:08:17 +00:00
|
|
|
if (params.search !== undefined) {
|
2014-02-21 07:15:08 +00:00
|
|
|
$('.search-input').val(params.search);
|
|
|
|
}
|
2014-03-16 08:08:56 +00:00
|
|
|
// Some browsers fire 'onpopstate' for every page load
|
|
|
|
// (Chrome), while others fire the event only when actually
|
|
|
|
// popping a state (Firefox), which is why search() is
|
|
|
|
// called both here and at the end of the startSearch()
|
|
|
|
// function.
|
2014-01-23 01:44:27 +00:00
|
|
|
search();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
search();
|
2013-09-19 05:18:38 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 08:08:56 +00:00
|
|
|
index = buildIndex(rawSearchIndex);
|
2013-09-19 05:18:38 +00:00
|
|
|
startSearch();
|
|
|
|
|
2014-03-16 08:08:56 +00:00
|
|
|
// Draw a convenient sidebar of known crates if we have a listing
|
|
|
|
if (rootPath == '../') {
|
|
|
|
console.log('here');
|
|
|
|
var sidebar = $('.sidebar');
|
|
|
|
var div = $('<div>').attr('class', 'block crate');
|
|
|
|
div.append($('<h2>').text('Crates'));
|
|
|
|
|
|
|
|
var crates = [];
|
|
|
|
for (var crate in rawSearchIndex) {
|
|
|
|
if (!rawSearchIndex.hasOwnProperty(crate)) { continue }
|
|
|
|
crates.push(crate);
|
|
|
|
}
|
|
|
|
crates.sort();
|
|
|
|
for (var i = 0; i < crates.length; i++) {
|
|
|
|
var klass = 'crate';
|
|
|
|
if (crates[i] == window.currentCrate) {
|
|
|
|
klass += ' current';
|
|
|
|
}
|
|
|
|
div.append($('<a>', {'href': '../' + crates[i] + '/index.html',
|
|
|
|
'class': klass}).text(crates[i]));
|
|
|
|
div.append($('<br>'));
|
|
|
|
}
|
|
|
|
sidebar.append(div);
|
|
|
|
}
|
|
|
|
}
|
2014-03-04 19:24:20 +00:00
|
|
|
|
2014-03-16 08:08:56 +00:00
|
|
|
window.initSearch = initSearch;
|
2014-01-15 01:09:50 +00:00
|
|
|
}());
|
2014-03-16 08:08:56 +00:00
|
|
|
|