Skip to content

Commit 9a45c9d

Browse files
author
b1nd
committed
Completed patch searching for rust docs
Made temporary changes to include multiple keywords in rustdoc search Implemented search based on multiple keywords Added some commenting and house cleaning Added path searching to rustdoc
1 parent ff3d5d4 commit 9a45c9d

File tree

1 file changed

+125
-49
lines changed

1 file changed

+125
-49
lines changed

src/librustdoc/html/static/main.js

+125-49
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -11,7 +11,7 @@
1111
/*jslint browser: true, es5: true */
1212
/*globals $: true, searchIndex: true, rootPath: true, allPaths: true */
1313

14-
(function () {
14+
(function() {
1515
"use strict";
1616
var resizeTimeout, interval;
1717

@@ -21,9 +21,9 @@
2121
if (resizeTimeout) {
2222
clearTimeout(resizeTimeout);
2323
}
24-
resizeTimeout = setTimeout(function () {
24+
resizeTimeout = setTimeout(function() {
2525
var contentWidth = $('.content').width();
26-
$('.docblock.short').width(function () {
26+
$('.docblock.short').width(function() {
2727
return contentWidth - 40 - $(this).prev().width();
2828
}).addClass('nowrap');
2929
}, 150);
@@ -50,7 +50,7 @@
5050
highlightSourceLines();
5151
$(window).on('hashchange', highlightSourceLines);
5252

53-
$(document).on('keyup', function (e) {
53+
$(document).on('keyup', function(e) {
5454
if (document.activeElement.tagName === 'INPUT') {
5555
return;
5656
}
@@ -71,13 +71,13 @@
7171
e.preventDefault();
7272
$('.search-input').focus();
7373
}
74-
}).on('click', function (e) {
74+
}).on('click', function(e) {
7575
if (!$(e.target).closest('#help').length) {
7676
$('#help').addClass('hidden');
7777
}
7878
});
7979

80-
$('.version-selector').on('change', function () {
80+
$('.version-selector').on('change', function() {
8181
var i, match,
8282
url = document.location.href,
8383
stripped = '',
@@ -102,13 +102,29 @@
102102
// clear cached values from the search bar
103103
$(".search-input")[0].value = '';
104104

105+
/**
106+
* Executes the query and builds an index of results
107+
* @param {[Object]} query [The user query]
108+
* @param {[type]} max [The maximum results returned]
109+
* @param {[type]} searchWords [The list of search words to query against]
110+
* @return {[type]} [A search index of results]
111+
*/
105112
function execQuery(query, max, searchWords) {
106113
var valLower = query.query.toLowerCase(),
107114
val = valLower,
108115
typeFilter = query.type,
109116
results = [],
110117
aa = 0,
111-
bb = 0;
118+
bb = 0,
119+
split = valLower.split("::");
120+
121+
//remove empty keywords
122+
for (var j = 0; j < split.length; j++) {
123+
split[j].toLowerCase();
124+
if (split[j] === "") {
125+
split.splice(j, 1);
126+
}
127+
}
112128

113129
// quoted values mean literal search
114130
bb = searchWords.length;
@@ -128,31 +144,41 @@
128144
} else {
129145
// gather matching search results up to a certain maximum
130146
val = val.replace(/\_/g, "");
131-
for (aa = 0; aa < bb; aa += 1) {
132-
if (searchWords[aa].indexOf(val) > -1 || searchWords[aa].replace(/_/g, "").indexOf(val) > -1) {
133-
// filter type: ... queries
134-
if (!typeFilter || typeFilter === searchIndex[aa].ty) {
135-
results.push([aa, searchWords[aa].replace(/_/g, "").indexOf(val)]);
147+
for (var i = 0; i < split.length; i++) {
148+
for (aa = 0; aa < bb; aa += 1) {
149+
if (searchWords[aa].indexOf(split[i]) > -1 || searchWords[aa].indexOf(val) > -1 || searchWords[aa].replace(/_/g, "").indexOf(val) > -1) {
150+
// filter type: ... queries
151+
if (!typeFilter || typeFilter === searchIndex[aa].ty) {
152+
results.push([aa, searchWords[aa].replace(/_/g, "").indexOf(val)]);
153+
}
154+
}
155+
if (results.length === max) {
156+
break;
136157
}
137-
}
138-
if (results.length === max) {
139-
break;
140158
}
141159
}
142160
}
161+
143162
bb = results.length;
144163
for (aa = 0; aa < bb; aa += 1) {
145164
results[aa].push(searchIndex[results[aa][0]].ty);
146-
}
147-
for (aa = 0; aa < bb; aa += 1) {
148165
results[aa].push(searchIndex[results[aa][0]].path);
166+
results[aa].push(searchIndex[results[aa][0]].name);
167+
results[aa].push(searchIndex[results[aa][0]].parent);
149168
}
150-
151169
// if there are no results then return to default and fail
152170
if (results.length === 0) {
153171
return [];
154172
}
155173

174+
results.forEach(function(item) {
175+
for (var i = 0; i < split.length; i++) {
176+
if (item[3].indexOf(split[i]) === -1) {
177+
item = null;
178+
break;
179+
}
180+
}
181+
});
156182
// sort by exact match
157183
results.sort(function search_complete_sort0(aaa, bbb) {
158184
if (searchWords[aaa[0]] === valLower && searchWords[bbb[0]] !== valLower) {
@@ -203,10 +229,58 @@
203229
results[aa][0] = -1;
204230
}
205231
}
206-
232+
for (var i = 0; i < results.length; i++) {
233+
var result = results[i],
234+
name = result[4].toLowerCase(),
235+
path = result[3].toLowerCase(),
236+
parent = allPaths[result[5]];
237+
238+
var valid = validateResult(name, path, split, parent);
239+
if (!valid) {
240+
result[0] = -1;
241+
}
242+
}
207243
return results;
208244
}
209245

246+
/**
247+
* Validate performs the following boolean logic. For example: "File::open" will give
248+
* IF A PARENT EXISTS => ("file" && "open") exists in (name || path || parent)
249+
* OR => ("file" && "open") exists in (name || path )
250+
*
251+
* This could be written functionally, but I wanted to minimise functions on stack.
252+
* @param {[string]} name [The name of the result]
253+
* @param {[string]} path [The path of the result]
254+
* @param {[string]} keys [The keys to be used (["file", "open"])]
255+
* @param {[object]} parent [The parent of the result]
256+
* @return {[boolean]} [Whether the result is valid or not]
257+
*/
258+
function validateResult(name, path, keys, parent) {
259+
//initially valid
260+
var validate = true;
261+
//if there is a parent, then validate against parent
262+
if (parent !== undefined) {
263+
for (var i = 0; i < keys.length; i++) {
264+
// if previous keys are valid and current key is in the path, name or parent
265+
if ((validate) && (name.toLowerCase().indexOf(keys[i]) > -1 || path.toLowerCase().indexOf(keys[i]) > -1 || parent.name.toLowerCase().indexOf(keys[i]) > -1)) {
266+
validate = true;
267+
} else {
268+
validate = false;
269+
}
270+
}
271+
} else {
272+
for (var i = 0; i < keys.length; i++) {
273+
// if previous keys are valid and current key is in the path, name
274+
if ((validate) && (name.toLowerCase().indexOf(keys[i]) > -1 || path.toLowerCase().indexOf(keys[i]) > -1)) {
275+
validate = true;
276+
} else {
277+
validate = false;
278+
}
279+
}
280+
}
281+
return validate;
282+
}
283+
210284
function getQuery() {
211285
var matches, type, query = $('.search-input').val();
212286

@@ -226,25 +300,25 @@
226300
function initSearchNav() {
227301
var hoverTimeout, $results = $('.search-results .result');
228302

229-
$results.on('click', function () {
303+
$results.on('click', function() {
230304
var dst = $(this).find('a')[0];
231305
console.log(window.location.pathname, dst.pathname);
232306
if (window.location.pathname == dst.pathname) {
233307
$('#search').addClass('hidden');
234308
$('#main').removeClass('hidden');
235309
}
236310
document.location.href = dst.href;
237-
}).on('mouseover', function () {
311+
}).on('mouseover', function() {
238312
var $el = $(this);
239313
clearTimeout(hoverTimeout);
240-
hoverTimeout = setTimeout(function () {
314+
hoverTimeout = setTimeout(function() {
241315
$results.removeClass('highlighted');
242316
$el.addClass('highlighted');
243317
}, 20);
244318
});
245319

246320
$(document).off('keypress.searchnav');
247-
$(document).on('keypress.searchnav', function (e) {
321+
$(document).on('keypress.searchnav', function(e) {
248322
var $active = $results.filter('.highlighted');
249323

250324
if (e.keyCode === 38) { // up
@@ -282,7 +356,7 @@
282356
if (results.length > 0) {
283357
shown = [];
284358

285-
results.forEach(function (item) {
359+
results.forEach(function(item) {
286360
var name, type;
287361

288362
if (shown.indexOf(item) !== -1) {
@@ -298,55 +372,57 @@
298372
if (type === 'mod') {
299373
output += item.path +
300374
'::<a href="' + rootPath +
301-
item.path.replace(/::/g, '/') + '/' +
302-
name + '/index.html" class="' +
303-
type + '">' + name + '</a>';
375+
item.path.replace(/::/g, '/') + '/' +
376+
name + '/index.html" class="' +
377+
type + '">' + name + '</a>';
304378
} else if (type === 'static' || type === 'reexport') {
305379
output += item.path +
306380
'::<a href="' + rootPath +
307-
item.path.replace(/::/g, '/') +
308-
'/index.html" class="' + type +
309-
'">' + name + '</a>';
381+
item.path.replace(/::/g, '/') +
382+
'/index.html" class="' + type +
383+
'">' + name + '</a>';
310384
} else if (item.parent !== undefined) {
311385
var myparent = allPaths[item.parent];
312386
var anchor = '#' + type + '.' + name;
313387
output += item.path + '::' + myparent.name +
314388
'::<a href="' + rootPath +
315-
item.path.replace(/::/g, '/') +
316-
'/' + myparent.type +
317-
'.' + myparent.name +
318-
'.html' + anchor +
319-
'" class="' + type +
320-
'">' + name + '</a>';
389+
item.path.replace(/::/g, '/') +
390+
'/' + myparent.type +
391+
'.' + myparent.name +
392+
'.html' + anchor +
393+
'" class="' + type +
394+
'">' + name + '</a>';
321395
} else {
322396
output += item.path +
323397
'::<a href="' + rootPath +
324-
item.path.replace(/::/g, '/') +
325-
'/' + type +
326-
'.' + name +
327-
'.html" class="' + type +
328-
'">' + name + '</a>';
398+
item.path.replace(/::/g, '/') +
399+
'/' + type +
400+
'.' + name +
401+
'.html" class="' + type +
402+
'">' + name + '</a>';
329403
}
330404

331405
output += '</td><td><span class="desc">' + item.desc +
332-
'</span></td></tr>';
406+
'</span></td></tr>';
333407
});
334408
} else {
335409
output += 'No results :( <a href="https://duckduckgo.com/?q=' +
336-
encodeURIComponent('rust ' + query.query) +
337-
'">Try on DuckDuckGo?</a>';
410+
encodeURIComponent('rust ' + query.query) +
411+
'">Try on DuckDuckGo?</a>';
338412
}
339413

340414
output += "</p>";
341415
$('#main.content').addClass('hidden');
342416
$('#search.content').removeClass('hidden').html(output);
343417
$('#search .desc').width($('#search').width() - 40 -
344-
$('#search td:first-child').first().width());
418+
$('#search td:first-child').first().width());
345419
initSearchNav();
346420
}
347421

348422
function search(e) {
349-
var query, filterdata = [], obj, i, len,
423+
var query,
424+
filterdata = [],
425+
obj, i, len,
350426
results = [],
351427
maxResults = 200,
352428
resultIndex;
@@ -464,7 +540,7 @@
464540
function startSearch() {
465541
var keyUpTimeout;
466542
$('.do-search').on('click', search);
467-
$('.search-input').on('keyup', function () {
543+
$('.search-input').on('keyup', function() {
468544
clearTimeout(keyUpTimeout);
469545
keyUpTimeout = setTimeout(search, 100);
470546
});
@@ -475,4 +551,4 @@
475551
}
476552

477553
initSearch(searchIndex);
478-
}());
554+
}());

0 commit comments

Comments
 (0)