]>
Commit | Line | Data |
---|---|---|
0731742a XL |
1 | // From rust: |
2 | /* global ALIASES, currentCrate, rootPath */ | |
3 | ||
4 | // Local js definitions: | |
5 | /* global addClass, getCurrentValue, hasClass */ | |
60c5eb7d | 6 | /* global onEach, removeClass, updateLocalStorage */ |
1a4d82fc | 7 | |
a1dfa0c6 XL |
8 | if (!String.prototype.startsWith) { |
9 | String.prototype.startsWith = function(searchString, position) { | |
10 | position = position || 0; | |
11 | return this.indexOf(searchString, position) === position; | |
12 | }; | |
13 | } | |
14 | if (!String.prototype.endsWith) { | |
15 | String.prototype.endsWith = function(suffix, length) { | |
16 | var l = length || this.length; | |
17 | return this.indexOf(suffix, l - suffix.length) !== -1; | |
18 | }; | |
19 | } | |
20 | ||
0731742a XL |
21 | if (!DOMTokenList.prototype.add) { |
22 | DOMTokenList.prototype.add = function(className) { | |
23 | if (className && !hasClass(this, className)) { | |
24 | if (this.className && this.className.length > 0) { | |
25 | this.className += " " + className; | |
26 | } else { | |
27 | this.className = className; | |
28 | } | |
29 | } | |
30 | }; | |
31 | } | |
32 | ||
33 | if (!DOMTokenList.prototype.remove) { | |
34 | DOMTokenList.prototype.remove = function(className) { | |
35 | if (className && this.className) { | |
36 | this.className = (" " + this.className + " ").replace(" " + className + " ", " ") | |
37 | .trim(); | |
38 | } | |
39 | }; | |
40 | } | |
41 | ||
e1599b0c XL |
42 | function getSearchInput() { |
43 | return document.getElementsByClassName("search-input")[0]; | |
44 | } | |
45 | ||
46 | function getSearchElement() { | |
47 | return document.getElementById("search"); | |
48 | } | |
49 | ||
1a4d82fc JJ |
50 | (function() { |
51 | "use strict"; | |
1a4d82fc | 52 | |
c34b1796 AL |
53 | // This mapping table should match the discriminants of |
54 | // `rustdoc::html::item_type::ItemType` type in Rust. | |
55 | var itemTypes = ["mod", | |
56 | "externcrate", | |
57 | "import", | |
58 | "struct", | |
59 | "enum", | |
60 | "fn", | |
61 | "type", | |
62 | "static", | |
63 | "trait", | |
64 | "impl", | |
65 | "tymethod", | |
66 | "method", | |
67 | "structfield", | |
68 | "variant", | |
69 | "macro", | |
70 | "primitive", | |
71 | "associatedtype", | |
d9579d0f | 72 | "constant", |
9e0c209e | 73 | "associatedconstant", |
abe05a73 | 74 | "union", |
94b46f34 | 75 | "foreigntype", |
0bf4aa26 XL |
76 | "keyword", |
77 | "existential", | |
78 | "attr", | |
9fa01778 XL |
79 | "derive", |
80 | "traitalias"]; | |
abe05a73 | 81 | |
e74abb32 | 82 | var disableShortcuts = getCurrentValue("rustdoc-disable-shortcuts") === "true"; |
e1599b0c | 83 | var search_input = getSearchInput(); |
83c7162d | 84 | |
abe05a73 XL |
85 | // On the search screen, so you remain on the last tab you opened. |
86 | // | |
ff7c6d11 XL |
87 | // 0 for "In Names" |
88 | // 1 for "In Parameters" | |
89 | // 2 for "In Return Types" | |
abe05a73 | 90 | var currentTab = 0; |
c34b1796 | 91 | |
b7449926 XL |
92 | var titleBeforeSearch = document.title; |
93 | ||
83c7162d | 94 | function getPageId() { |
0731742a | 95 | var id = document.location.href.split("#")[1]; |
83c7162d | 96 | if (id) { |
0731742a | 97 | return id.split("?")[0].split("&")[0]; |
83c7162d XL |
98 | } |
99 | return null; | |
100 | } | |
101 | ||
ff7c6d11 XL |
102 | function showSidebar() { |
103 | var elems = document.getElementsByClassName("sidebar-elems")[0]; | |
104 | if (elems) { | |
105 | addClass(elems, "show-it"); | |
106 | } | |
0731742a | 107 | var sidebar = document.getElementsByClassName("sidebar")[0]; |
ff7c6d11 | 108 | if (sidebar) { |
0731742a | 109 | addClass(sidebar, "mobile"); |
ff7c6d11 XL |
110 | var filler = document.getElementById("sidebar-filler"); |
111 | if (!filler) { | |
112 | var div = document.createElement("div"); | |
113 | div.id = "sidebar-filler"; | |
114 | sidebar.appendChild(div); | |
115 | } | |
116 | } | |
e1599b0c XL |
117 | var themePickers = document.getElementsByClassName("theme-picker"); |
118 | if (themePickers && themePickers.length > 0) { | |
119 | themePickers[0].style.display = "none"; | |
2c00a5a8 | 120 | } |
ff7c6d11 XL |
121 | } |
122 | ||
123 | function hideSidebar() { | |
124 | var elems = document.getElementsByClassName("sidebar-elems")[0]; | |
125 | if (elems) { | |
126 | removeClass(elems, "show-it"); | |
127 | } | |
0731742a XL |
128 | var sidebar = document.getElementsByClassName("sidebar")[0]; |
129 | removeClass(sidebar, "mobile"); | |
ff7c6d11 XL |
130 | var filler = document.getElementById("sidebar-filler"); |
131 | if (filler) { | |
132 | filler.remove(); | |
133 | } | |
0731742a | 134 | document.getElementsByTagName("body")[0].style.marginTop = ""; |
e1599b0c XL |
135 | var themePickers = document.getElementsByClassName("theme-picker"); |
136 | if (themePickers && themePickers.length > 0) { | |
137 | themePickers[0].style.display = null; | |
2c00a5a8 | 138 | } |
ff7c6d11 XL |
139 | } |
140 | ||
62682a34 SL |
141 | // used for special search precedence |
142 | var TY_PRIMITIVE = itemTypes.indexOf("primitive"); | |
94b46f34 | 143 | var TY_KEYWORD = itemTypes.indexOf("keyword"); |
62682a34 | 144 | |
1a4d82fc JJ |
145 | function getQueryStringParams() { |
146 | var params = {}; | |
147 | window.location.search.substring(1).split("&"). | |
148 | map(function(s) { | |
149 | var pair = s.split("="); | |
150 | params[decodeURIComponent(pair[0])] = | |
ff7c6d11 | 151 | typeof pair[1] === "undefined" ? null : decodeURIComponent(pair[1]); |
1a4d82fc JJ |
152 | }); |
153 | return params; | |
154 | } | |
155 | ||
156 | function browserSupportsHistoryApi() { | |
9fa01778 | 157 | return window.history && typeof window.history.pushState === "function"; |
1a4d82fc JJ |
158 | } |
159 | ||
60c5eb7d XL |
160 | function isHidden(elem) { |
161 | return elem.offsetHeight === 0; | |
162 | } | |
163 | ||
0731742a | 164 | var main = document.getElementById("main"); |
60c5eb7d | 165 | var savedHash = ""; |
0731742a | 166 | |
60c5eb7d | 167 | function handleHashes(ev) { |
e1599b0c | 168 | var search = getSearchElement(); |
60c5eb7d XL |
169 | if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) { |
170 | // This block occurs when clicking on an element in the navbar while | |
171 | // in a search. | |
172 | addClass(search, "hidden"); | |
173 | removeClass(main, "hidden"); | |
174 | var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1); | |
175 | if (browserSupportsHistoryApi()) { | |
176 | history.replaceState(hash, "", "?search=#" + hash); | |
dc9dc135 | 177 | } |
60c5eb7d XL |
178 | var elem = document.getElementById(hash); |
179 | if (elem) { | |
180 | elem.scrollIntoView(); | |
dc9dc135 | 181 | } |
60c5eb7d XL |
182 | } |
183 | // This part is used in case an element is not visible. | |
184 | if (savedHash !== window.location.hash) { | |
185 | savedHash = window.location.hash; | |
186 | if (savedHash.length === 0) { | |
1a4d82fc JJ |
187 | return; |
188 | } | |
60c5eb7d XL |
189 | var elem = document.getElementById(savedHash.slice(1)); // we remove the '#' |
190 | if (!elem || !isHidden(elem)) { | |
191 | return; | |
abe05a73 | 192 | } |
60c5eb7d XL |
193 | var parent = elem.parentNode; |
194 | if (parent && hasClass(parent, "impl-items")) { | |
195 | // In case this is a trait implementation item, we first need to toggle | |
196 | // the "Show hidden undocumented items". | |
197 | onEachLazy(parent.getElementsByClassName("collapsed"), function(e) { | |
198 | if (e.parentNode === parent) { | |
199 | // Only click on the toggle we're looking for. | |
200 | e.click(); | |
201 | return true; | |
202 | } | |
7cac9316 | 203 | }); |
60c5eb7d XL |
204 | if (isHidden(elem)) { |
205 | // The whole parent is collapsed. We need to click on its toggle as well! | |
206 | if (hasClass(parent.lastElementChild, "collapse-toggle")) { | |
207 | parent.lastElementChild.click(); | |
208 | } | |
dc9dc135 | 209 | } |
1a4d82fc | 210 | } |
60c5eb7d XL |
211 | } |
212 | } | |
213 | ||
214 | function highlightSourceLines(match, ev) { | |
215 | if (typeof match === "undefined") { | |
216 | // If we're in mobile mode, we should hide the sidebar in any case. | |
217 | hideSidebar(); | |
218 | match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/); | |
219 | } | |
220 | if (!match) { | |
221 | return; | |
222 | } | |
223 | var from = parseInt(match[1], 10); | |
224 | var to = from; | |
225 | if (typeof match[2] !== "undefined") { | |
226 | to = parseInt(match[2], 10); | |
227 | } | |
228 | if (to < from) { | |
229 | var tmp = to; | |
230 | to = from; | |
231 | from = tmp; | |
232 | } | |
233 | var elem = document.getElementById(from); | |
234 | if (!elem) { | |
235 | return; | |
236 | } | |
237 | if (!ev) { | |
238 | var x = document.getElementById(from); | |
239 | if (x) { | |
240 | x.scrollIntoView(); | |
abe05a73 | 241 | } |
60c5eb7d XL |
242 | } |
243 | onEachLazy(document.getElementsByClassName("line-numbers"), function(e) { | |
244 | onEachLazy(e.getElementsByTagName("span"), function(i_e) { | |
245 | removeClass(i_e, "line-highlighted"); | |
246 | }); | |
247 | }); | |
248 | for (var i = from; i <= to; ++i) { | |
249 | elem = document.getElementById(i); | |
250 | if (!elem) { | |
251 | break; | |
abe05a73 | 252 | } |
60c5eb7d XL |
253 | addClass(elem, "line-highlighted"); |
254 | } | |
255 | } | |
256 | ||
257 | function onHashChange(ev) { | |
258 | // If we're in mobile mode, we should hide the sidebar in any case. | |
259 | hideSidebar(); | |
260 | var match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/); | |
261 | if (match) { | |
262 | return highlightSourceLines(match, ev); | |
1a4d82fc | 263 | } |
60c5eb7d | 264 | handleHashes(ev); |
1a4d82fc | 265 | } |
b7449926 XL |
266 | |
267 | function expandSection(id) { | |
268 | var elem = document.getElementById(id); | |
269 | if (elem && isHidden(elem)) { | |
0731742a XL |
270 | var h3 = elem.parentNode.previousElementSibling; |
271 | if (h3 && h3.tagName !== "H3") { | |
272 | h3 = h3.previousElementSibling; // skip div.docblock | |
b7449926 XL |
273 | } |
274 | ||
275 | if (h3) { | |
276 | var collapses = h3.getElementsByClassName("collapse-toggle"); | |
277 | if (collapses.length > 0) { | |
278 | // The element is not visible, we need to make it appear! | |
279 | collapseDocs(collapses[0], "show"); | |
280 | } | |
281 | } | |
282 | } | |
283 | } | |
284 | ||
c1a9b12d SL |
285 | // Gets the human-readable string for the virtual-key code of the |
286 | // given KeyboardEvent, ev. | |
287 | // | |
288 | // This function is meant as a polyfill for KeyboardEvent#key, | |
289 | // since it is not supported in Trident. We also test for | |
290 | // KeyboardEvent#keyCode because the handleShortcut handler is | |
291 | // also registered for the keydown event, because Blink doesn't fire | |
292 | // keypress on hitting the Escape key. | |
293 | // | |
294 | // So I guess you could say things are getting pretty interoperable. | |
295 | function getVirtualKey(ev) { | |
0731742a | 296 | if ("key" in ev && typeof ev.key != "undefined") { |
c1a9b12d | 297 | return ev.key; |
0731742a | 298 | } |
c1a9b12d SL |
299 | |
300 | var c = ev.charCode || ev.keyCode; | |
0731742a | 301 | if (c == 27) { |
c1a9b12d | 302 | return "Escape"; |
0731742a | 303 | } |
c1a9b12d SL |
304 | return String.fromCharCode(c); |
305 | } | |
306 | ||
e1599b0c XL |
307 | function getHelpElement() { |
308 | return document.getElementById("help"); | |
309 | } | |
310 | ||
9fa01778 | 311 | function displayHelp(display, ev, help) { |
e1599b0c | 312 | var help = help ? help : getHelpElement(); |
abe05a73 XL |
313 | if (display === true) { |
314 | if (hasClass(help, "hidden")) { | |
315 | ev.preventDefault(); | |
316 | removeClass(help, "hidden"); | |
317 | addClass(document.body, "blur"); | |
318 | } | |
0731742a | 319 | } else if (hasClass(help, "hidden") === false) { |
abe05a73 XL |
320 | ev.preventDefault(); |
321 | addClass(help, "hidden"); | |
322 | removeClass(document.body, "blur"); | |
323 | } | |
324 | } | |
325 | ||
e1599b0c XL |
326 | function handleEscape(ev) { |
327 | var help = getHelpElement(); | |
328 | var search = getSearchElement(); | |
0531ce1d | 329 | hideModal(); |
0731742a | 330 | if (hasClass(help, "hidden") === false) { |
9fa01778 | 331 | displayHelp(false, ev, help); |
0731742a | 332 | } else if (hasClass(search, "hidden") === false) { |
0531ce1d XL |
333 | ev.preventDefault(); |
334 | addClass(search, "hidden"); | |
0731742a | 335 | removeClass(main, "hidden"); |
b7449926 | 336 | document.title = titleBeforeSearch; |
0531ce1d XL |
337 | } |
338 | defocusSearchBar(); | |
339 | } | |
1a4d82fc | 340 | |
0531ce1d | 341 | function handleShortcut(ev) { |
92a42be0 | 342 | // Don't interfere with browser shortcuts |
e74abb32 | 343 | if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts === true) { |
92a42be0 | 344 | return; |
0531ce1d | 345 | } |
92a42be0 | 346 | |
0531ce1d XL |
347 | if (document.activeElement.tagName === "INPUT") { |
348 | switch (getVirtualKey(ev)) { | |
349 | case "Escape": | |
e1599b0c | 350 | handleEscape(ev); |
0531ce1d | 351 | break; |
9346a6ac | 352 | } |
0531ce1d XL |
353 | } else { |
354 | switch (getVirtualKey(ev)) { | |
355 | case "Escape": | |
e1599b0c | 356 | handleEscape(ev); |
0531ce1d | 357 | break; |
c1a9b12d | 358 | |
0531ce1d XL |
359 | case "s": |
360 | case "S": | |
e1599b0c | 361 | displayHelp(false, ev); |
0531ce1d XL |
362 | hideModal(); |
363 | ev.preventDefault(); | |
364 | focusSearchBar(); | |
365 | break; | |
c1a9b12d | 366 | |
0531ce1d XL |
367 | case "+": |
368 | case "-": | |
369 | ev.preventDefault(); | |
370 | toggleAllDocs(); | |
371 | break; | |
a7813a04 | 372 | |
0531ce1d XL |
373 | case "?": |
374 | if (ev.shiftKey) { | |
375 | hideModal(); | |
e1599b0c | 376 | displayHelp(true, ev); |
0531ce1d XL |
377 | } |
378 | break; | |
1a4d82fc | 379 | } |
1a4d82fc | 380 | } |
c1a9b12d SL |
381 | } |
382 | ||
b7449926 XL |
383 | function findParentElement(elem, tagName) { |
384 | do { | |
385 | if (elem && elem.tagName === tagName) { | |
386 | return elem; | |
387 | } | |
0731742a XL |
388 | elem = elem.parentNode; |
389 | } while (elem); | |
b7449926 XL |
390 | return null; |
391 | } | |
392 | ||
7cac9316 XL |
393 | document.onkeypress = handleShortcut; |
394 | document.onkeydown = handleShortcut; | |
7cac9316 | 395 | |
60c5eb7d XL |
396 | var handleSourceHighlight = (function() { |
397 | var prev_line_id = 0; | |
398 | ||
399 | var set_fragment = function(name) { | |
400 | var x = window.scrollX, | |
401 | y = window.scrollY; | |
402 | if (browserSupportsHistoryApi()) { | |
403 | history.replaceState(null, null, "#" + name); | |
404 | highlightSourceLines(); | |
405 | } else { | |
406 | location.replace("#" + name); | |
407 | } | |
408 | // Prevent jumps when selecting one or many lines | |
409 | window.scrollTo(x, y); | |
410 | }; | |
7cac9316 | 411 | |
60c5eb7d XL |
412 | return function(ev) { |
413 | var cur_line_id = parseInt(ev.target.id, 10); | |
414 | ev.preventDefault(); | |
7cac9316 | 415 | |
60c5eb7d XL |
416 | if (ev.shiftKey && prev_line_id) { |
417 | // Swap selection if needed | |
418 | if (prev_line_id > cur_line_id) { | |
419 | var tmp = prev_line_id; | |
420 | prev_line_id = cur_line_id; | |
421 | cur_line_id = tmp; | |
7cac9316 | 422 | } |
1a4d82fc | 423 | |
60c5eb7d | 424 | set_fragment(prev_line_id + "-" + cur_line_id); |
7cac9316 | 425 | } else { |
60c5eb7d | 426 | prev_line_id = cur_line_id; |
1a4d82fc | 427 | |
60c5eb7d | 428 | set_fragment(cur_line_id); |
1a4d82fc | 429 | } |
60c5eb7d XL |
430 | } |
431 | })(); | |
432 | ||
433 | document.onclick = function(ev) { | |
434 | if (hasClass(ev.target, "collapse-toggle")) { | |
435 | collapseDocs(ev.target, "toggle"); | |
436 | } else if (hasClass(ev.target.parentNode, "collapse-toggle")) { | |
437 | collapseDocs(ev.target.parentNode, "toggle"); | |
438 | } else if (ev.target.tagName === "SPAN" && hasClass(ev.target.parentNode, "line-numbers")) { | |
439 | handleSourceHighlight(ev); | |
e74abb32 XL |
440 | } else if (hasClass(getHelpElement(), "hidden") === false) { |
441 | var help = getHelpElement(); | |
442 | var is_inside_help_popup = ev.target !== help && help.contains(ev.target); | |
443 | if (is_inside_help_popup === false) { | |
444 | addClass(help, "hidden"); | |
445 | removeClass(document.body, "blur"); | |
446 | } | |
b7449926 XL |
447 | } else { |
448 | // Making a collapsed element visible on onhashchange seems | |
449 | // too late | |
0731742a | 450 | var a = findParentElement(ev.target, "A"); |
b7449926 | 451 | if (a && a.hash) { |
0731742a | 452 | expandSection(a.hash.replace(/^#/, "")); |
b7449926 | 453 | } |
1a4d82fc | 454 | } |
7cac9316 | 455 | }; |
1a4d82fc | 456 | |
0731742a | 457 | var x = document.getElementsByClassName("version-selector"); |
7cac9316 XL |
458 | if (x.length > 0) { |
459 | x[0].onchange = function() { | |
460 | var i, match, | |
461 | url = document.location.href, | |
0731742a | 462 | stripped = "", |
7cac9316 | 463 | len = rootPath.match(/\.\.\//g).length + 1; |
1a4d82fc | 464 | |
7cac9316 XL |
465 | for (i = 0; i < len; ++i) { |
466 | match = url.match(/\/[^\/]*$/); | |
467 | if (i < len - 1) { | |
468 | stripped = match[0] + stripped; | |
469 | } | |
470 | url = url.substring(0, url.length - match[0].length); | |
471 | } | |
472 | ||
0731742a | 473 | url += "/" + document.getElementsByClassName("version-selector")[0].value + stripped; |
7cac9316 XL |
474 | |
475 | document.location.href = url; | |
476 | }; | |
477 | } | |
c1a9b12d | 478 | |
1a4d82fc JJ |
479 | /** |
480 | * A function to compute the Levenshtein distance between two strings | |
481 | * Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported | |
482 | * Full License can be found at http://creativecommons.org/licenses/by-sa/3.0/legalcode | |
483 | * This code is an unmodified version of the code written by Marco de Wit | |
484 | * and was found at http://stackoverflow.com/a/18514751/745719 | |
485 | */ | |
2c00a5a8 XL |
486 | var levenshtein_row2 = []; |
487 | function levenshtein(s1, s2) { | |
488 | if (s1 === s2) { | |
489 | return 0; | |
490 | } | |
491 | var s1_len = s1.length, s2_len = s2.length; | |
492 | if (s1_len && s2_len) { | |
493 | var i1 = 0, i2 = 0, a, b, c, c2, row = levenshtein_row2; | |
494 | while (i1 < s1_len) { | |
495 | row[i1] = ++i1; | |
62682a34 | 496 | } |
2c00a5a8 XL |
497 | while (i2 < s2_len) { |
498 | c2 = s2.charCodeAt(i2); | |
499 | a = i2; | |
500 | ++i2; | |
501 | b = i2; | |
502 | for (i1 = 0; i1 < s1_len; ++i1) { | |
503 | c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0); | |
504 | a = row[i1]; | |
505 | b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c); | |
506 | row[i1] = b; | |
1a4d82fc JJ |
507 | } |
508 | } | |
2c00a5a8 XL |
509 | return b; |
510 | } | |
511 | return s1_len + s2_len; | |
512 | } | |
1a4d82fc JJ |
513 | |
514 | function initSearch(rawSearchIndex) { | |
515 | var currentResults, index, searchIndex; | |
516 | var MAX_LEV_DISTANCE = 3; | |
abe05a73 | 517 | var MAX_RESULTS = 200; |
8faf50e0 XL |
518 | var GENERICS_DATA = 1; |
519 | var NAME = 0; | |
520 | var INPUTS_DATA = 0; | |
521 | var OUTPUT_DATA = 1; | |
1a4d82fc JJ |
522 | var params = getQueryStringParams(); |
523 | ||
524 | // Populate search bar with query string search term when provided, | |
525 | // but only if the input bar is empty. This avoid the obnoxious issue | |
526 | // where you start trying to do a search, and the index loads, and | |
527 | // suddenly your search is gone! | |
83c7162d | 528 | if (search_input.value === "") { |
0731742a | 529 | search_input.value = params.search || ""; |
1a4d82fc JJ |
530 | } |
531 | ||
532 | /** | |
533 | * Executes the query and builds an index of results | |
0731742a XL |
534 | * @param {[Object]} query [The user query] |
535 | * @param {[type]} searchWords [The list of search words to query | |
536 | * against] | |
537 | * @param {[type]} filterCrates [Crate to search in if defined] | |
538 | * @return {[type]} [A search index of results] | |
1a4d82fc | 539 | */ |
0731742a | 540 | function execQuery(query, searchWords, filterCrates) { |
2c00a5a8 | 541 | function itemTypeFromName(typename) { |
0731742a XL |
542 | var length = itemTypes.length; |
543 | for (var i = 0; i < length; ++i) { | |
2c00a5a8 XL |
544 | if (itemTypes[i] === typename) { |
545 | return i; | |
546 | } | |
547 | } | |
548 | return -1; | |
549 | } | |
550 | ||
1a4d82fc JJ |
551 | var valLower = query.query.toLowerCase(), |
552 | val = valLower, | |
553 | typeFilter = itemTypeFromName(query.type), | |
abe05a73 | 554 | results = {}, results_in_args = {}, results_returned = {}, |
1a4d82fc JJ |
555 | split = valLower.split("::"); |
556 | ||
0731742a XL |
557 | var length = split.length; |
558 | for (var z = 0; z < length; ++z) { | |
abe05a73 XL |
559 | if (split[z] === "") { |
560 | split.splice(z, 1); | |
561 | z -= 1; | |
562 | } | |
563 | } | |
564 | ||
565 | function transformResults(results, isType) { | |
566 | var out = []; | |
0731742a XL |
567 | var length = results.length; |
568 | for (var i = 0; i < length; ++i) { | |
abe05a73 XL |
569 | if (results[i].id > -1) { |
570 | var obj = searchIndex[results[i].id]; | |
571 | obj.lev = results[i].lev; | |
572 | if (isType !== true || obj.type) { | |
94b46f34 XL |
573 | var res = buildHrefAndPath(obj); |
574 | obj.displayPath = pathSplitter(res[0]); | |
575 | obj.fullPath = obj.displayPath + obj.name; | |
576 | // To be sure than it some items aren't considered as duplicate. | |
0731742a | 577 | obj.fullPath += "|" + obj.ty; |
94b46f34 | 578 | obj.href = res[1]; |
abe05a73 | 579 | out.push(obj); |
94b46f34 XL |
580 | if (out.length >= MAX_RESULTS) { |
581 | break; | |
582 | } | |
abe05a73 XL |
583 | } |
584 | } | |
abe05a73 XL |
585 | } |
586 | return out; | |
587 | } | |
588 | ||
589 | function sortResults(results, isType) { | |
590 | var ar = []; | |
591 | for (var entry in results) { | |
592 | if (results.hasOwnProperty(entry)) { | |
593 | ar.push(results[entry]); | |
594 | } | |
595 | } | |
596 | results = ar; | |
0731742a | 597 | var i; |
abe05a73 | 598 | var nresults = results.length; |
0731742a | 599 | for (i = 0; i < nresults; ++i) { |
abe05a73 XL |
600 | results[i].word = searchWords[results[i].id]; |
601 | results[i].item = searchIndex[results[i].id] || {}; | |
602 | } | |
603 | // if there are no results then return to default and fail | |
604 | if (results.length === 0) { | |
605 | return []; | |
606 | } | |
607 | ||
608 | results.sort(function(aaa, bbb) { | |
609 | var a, b; | |
610 | ||
e1599b0c XL |
611 | // sort by exact match with regard to the last word (mismatch goes later) |
612 | a = (aaa.word !== val); | |
613 | b = (bbb.word !== val); | |
614 | if (a !== b) { return a - b; } | |
615 | ||
abe05a73 XL |
616 | // Sort by non levenshtein results and then levenshtein results by the distance |
617 | // (less changes required to match means higher rankings) | |
618 | a = (aaa.lev); | |
619 | b = (bbb.lev); | |
620 | if (a !== b) { return a - b; } | |
621 | ||
622 | // sort by crate (non-current crate goes later) | |
623 | a = (aaa.item.crate !== window.currentCrate); | |
624 | b = (bbb.item.crate !== window.currentCrate); | |
625 | if (a !== b) { return a - b; } | |
626 | ||
abe05a73 XL |
627 | // sort by item name length (longer goes later) |
628 | a = aaa.word.length; | |
629 | b = bbb.word.length; | |
630 | if (a !== b) { return a - b; } | |
631 | ||
632 | // sort by item name (lexicographically larger goes later) | |
633 | a = aaa.word; | |
634 | b = bbb.word; | |
635 | if (a !== b) { return (a > b ? +1 : -1); } | |
636 | ||
637 | // sort by index of keyword in item name (no literal occurrence goes later) | |
638 | a = (aaa.index < 0); | |
639 | b = (bbb.index < 0); | |
640 | if (a !== b) { return a - b; } | |
641 | // (later literal occurrence, if any, goes later) | |
642 | a = aaa.index; | |
643 | b = bbb.index; | |
644 | if (a !== b) { return a - b; } | |
645 | ||
94b46f34 XL |
646 | // special precedence for primitive and keyword pages |
647 | if ((aaa.item.ty === TY_PRIMITIVE && bbb.item.ty !== TY_KEYWORD) || | |
648 | (aaa.item.ty === TY_KEYWORD && bbb.item.ty !== TY_PRIMITIVE)) { | |
abe05a73 XL |
649 | return -1; |
650 | } | |
94b46f34 XL |
651 | if ((bbb.item.ty === TY_PRIMITIVE && aaa.item.ty !== TY_PRIMITIVE) || |
652 | (bbb.item.ty === TY_KEYWORD && aaa.item.ty !== TY_KEYWORD)) { | |
abe05a73 XL |
653 | return 1; |
654 | } | |
655 | ||
656 | // sort by description (no description goes later) | |
0731742a XL |
657 | a = (aaa.item.desc === ""); |
658 | b = (bbb.item.desc === ""); | |
abe05a73 XL |
659 | if (a !== b) { return a - b; } |
660 | ||
661 | // sort by type (later occurrence in `itemTypes` goes later) | |
662 | a = aaa.item.ty; | |
663 | b = bbb.item.ty; | |
664 | if (a !== b) { return a - b; } | |
665 | ||
666 | // sort by path (lexicographically larger goes later) | |
667 | a = aaa.item.path; | |
668 | b = bbb.item.path; | |
669 | if (a !== b) { return (a > b ? +1 : -1); } | |
670 | ||
671 | // que sera, sera | |
672 | return 0; | |
673 | }); | |
674 | ||
0731742a XL |
675 | var length = results.length; |
676 | for (i = 0; i < length; ++i) { | |
abe05a73 XL |
677 | var result = results[i]; |
678 | ||
679 | // this validation does not make sense when searching by types | |
680 | if (result.dontValidate) { | |
681 | continue; | |
682 | } | |
683 | var name = result.item.name.toLowerCase(), | |
684 | path = result.item.path.toLowerCase(), | |
685 | parent = result.item.parent; | |
686 | ||
687 | if (isType !== true && | |
688 | validateResult(name, path, split, parent) === false) | |
689 | { | |
690 | result.id = -1; | |
691 | } | |
692 | } | |
693 | return transformResults(results); | |
694 | } | |
695 | ||
696 | function extractGenerics(val) { | |
697 | val = val.toLowerCase(); | |
0731742a XL |
698 | if (val.indexOf("<") !== -1) { |
699 | var values = val.substring(val.indexOf("<") + 1, val.lastIndexOf(">")); | |
abe05a73 | 700 | return { |
0731742a | 701 | name: val.substring(0, val.indexOf("<")), |
abe05a73 XL |
702 | generics: values.split(/\s*,\s*/), |
703 | }; | |
704 | } | |
705 | return { | |
706 | name: val, | |
707 | generics: [], | |
708 | }; | |
709 | } | |
710 | ||
711 | function checkGenerics(obj, val) { | |
712 | // The names match, but we need to be sure that all generics kinda | |
713 | // match as well. | |
714 | var lev_distance = MAX_LEV_DISTANCE + 1; | |
715 | if (val.generics.length > 0) { | |
8faf50e0 XL |
716 | if (obj.length > GENERICS_DATA && |
717 | obj[GENERICS_DATA].length >= val.generics.length) { | |
718 | var elems = obj[GENERICS_DATA].slice(0); | |
abe05a73 XL |
719 | var total = 0; |
720 | var done = 0; | |
721 | // We need to find the type that matches the most to remove it in order | |
722 | // to move forward. | |
0731742a XL |
723 | var vlength = val.generics.length; |
724 | for (var y = 0; y < vlength; ++y) { | |
abe05a73 | 725 | var lev = { pos: -1, lev: MAX_LEV_DISTANCE + 1}; |
0731742a XL |
726 | var elength = elems.length; |
727 | for (var x = 0; x < elength; ++x) { | |
abe05a73 XL |
728 | var tmp_lev = levenshtein(elems[x], val.generics[y]); |
729 | if (tmp_lev < lev.lev) { | |
730 | lev.lev = tmp_lev; | |
731 | lev.pos = x; | |
732 | } | |
733 | } | |
734 | if (lev.pos !== -1) { | |
735 | elems.splice(lev.pos, 1); | |
736 | lev_distance = Math.min(lev.lev, lev_distance); | |
737 | total += lev.lev; | |
738 | done += 1; | |
739 | } else { | |
740 | return MAX_LEV_DISTANCE + 1; | |
741 | } | |
742 | } | |
9fa01778 | 743 | return Math.ceil(total / done); |
abe05a73 XL |
744 | } |
745 | } | |
746 | return MAX_LEV_DISTANCE + 1; | |
747 | } | |
748 | ||
749 | // Check for type name and type generics (if any). | |
750 | function checkType(obj, val, literalSearch) { | |
751 | var lev_distance = MAX_LEV_DISTANCE + 1; | |
0731742a | 752 | var x; |
8faf50e0 | 753 | if (obj[NAME] === val.name) { |
abe05a73 | 754 | if (literalSearch === true) { |
2c00a5a8 | 755 | if (val.generics && val.generics.length !== 0) { |
8faf50e0 XL |
756 | if (obj.length > GENERICS_DATA && |
757 | obj[GENERICS_DATA].length >= val.generics.length) { | |
758 | var elems = obj[GENERICS_DATA].slice(0); | |
abe05a73 | 759 | var allFound = true; |
abe05a73 XL |
760 | |
761 | for (var y = 0; allFound === true && y < val.generics.length; ++y) { | |
762 | allFound = false; | |
763 | for (x = 0; allFound === false && x < elems.length; ++x) { | |
764 | allFound = elems[x] === val.generics[y]; | |
765 | } | |
766 | if (allFound === true) { | |
767 | elems.splice(x - 1, 1); | |
768 | } | |
769 | } | |
770 | if (allFound === true) { | |
771 | return true; | |
772 | } | |
773 | } else { | |
774 | return false; | |
775 | } | |
776 | } | |
777 | return true; | |
778 | } | |
779 | // If the type has generics but don't match, then it won't return at this point. | |
780 | // Otherwise, `checkGenerics` will return 0 and it'll return. | |
8faf50e0 | 781 | if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length !== 0) { |
abe05a73 XL |
782 | var tmp_lev = checkGenerics(obj, val); |
783 | if (tmp_lev <= MAX_LEV_DISTANCE) { | |
784 | return tmp_lev; | |
785 | } | |
786 | } else { | |
787 | return 0; | |
788 | } | |
789 | } | |
790 | // Names didn't match so let's check if one of the generic types could. | |
791 | if (literalSearch === true) { | |
8faf50e0 | 792 | if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) { |
0731742a XL |
793 | var length = obj[GENERICS_DATA].length; |
794 | for (x = 0; x < length; ++x) { | |
8faf50e0 | 795 | if (obj[GENERICS_DATA][x] === val.name) { |
abe05a73 XL |
796 | return true; |
797 | } | |
798 | } | |
799 | } | |
800 | return false; | |
801 | } | |
0731742a | 802 | lev_distance = Math.min(levenshtein(obj[NAME], val.name), lev_distance); |
abe05a73 | 803 | if (lev_distance <= MAX_LEV_DISTANCE) { |
532ac7d7 XL |
804 | // The generics didn't match but the name kinda did so we give it |
805 | // a levenshtein distance value that isn't *this* good so it goes | |
806 | // into the search results but not too high. | |
807 | lev_distance = Math.ceil((checkGenerics(obj, val) + lev_distance) / 2); | |
8faf50e0 | 808 | } else if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) { |
abe05a73 | 809 | // We can check if the type we're looking for is inside the generics! |
0731742a XL |
810 | var olength = obj[GENERICS_DATA].length; |
811 | for (x = 0; x < olength; ++x) { | |
8faf50e0 | 812 | lev_distance = Math.min(levenshtein(obj[GENERICS_DATA][x], val.name), |
abe05a73 XL |
813 | lev_distance); |
814 | } | |
815 | } | |
816 | // Now whatever happens, the returned distance is "less good" so we should mark it | |
817 | // as such, and so we add 1 to the distance to make it "less good". | |
818 | return lev_distance + 1; | |
819 | } | |
820 | ||
821 | function findArg(obj, val, literalSearch) { | |
822 | var lev_distance = MAX_LEV_DISTANCE + 1; | |
823 | ||
8faf50e0 XL |
824 | if (obj && obj.type && obj.type[INPUTS_DATA] && |
825 | obj.type[INPUTS_DATA].length > 0) { | |
0731742a XL |
826 | var length = obj.type[INPUTS_DATA].length; |
827 | for (var i = 0; i < length; i++) { | |
8faf50e0 | 828 | var tmp = checkType(obj.type[INPUTS_DATA][i], val, literalSearch); |
abe05a73 XL |
829 | if (literalSearch === true && tmp === true) { |
830 | return true; | |
831 | } | |
832 | lev_distance = Math.min(tmp, lev_distance); | |
833 | if (lev_distance === 0) { | |
834 | return 0; | |
835 | } | |
836 | } | |
837 | } | |
838 | return literalSearch === true ? false : lev_distance; | |
839 | } | |
840 | ||
841 | function checkReturned(obj, val, literalSearch) { | |
842 | var lev_distance = MAX_LEV_DISTANCE + 1; | |
843 | ||
8faf50e0 | 844 | if (obj && obj.type && obj.type.length > OUTPUT_DATA) { |
532ac7d7 XL |
845 | var ret = obj.type[OUTPUT_DATA]; |
846 | if (!obj.type[OUTPUT_DATA].length) { | |
847 | ret = [ret]; | |
abe05a73 | 848 | } |
532ac7d7 XL |
849 | for (var x = 0; x < ret.length; ++x) { |
850 | var r = ret[x]; | |
851 | if (typeof r === "string") { | |
852 | r = [r]; | |
853 | } | |
854 | var tmp = checkType(r, val, literalSearch); | |
855 | if (literalSearch === true) { | |
856 | if (tmp === true) { | |
857 | return true; | |
858 | } | |
859 | continue; | |
860 | } | |
861 | lev_distance = Math.min(tmp, lev_distance); | |
862 | if (lev_distance === 0) { | |
863 | return 0; | |
864 | } | |
abe05a73 XL |
865 | } |
866 | } | |
867 | return literalSearch === true ? false : lev_distance; | |
868 | } | |
869 | ||
b7449926 XL |
870 | function checkPath(contains, lastElem, ty) { |
871 | if (contains.length === 0) { | |
ff7c6d11 XL |
872 | return 0; |
873 | } | |
abe05a73 XL |
874 | var ret_lev = MAX_LEV_DISTANCE + 1; |
875 | var path = ty.path.split("::"); | |
876 | ||
877 | if (ty.parent && ty.parent.name) { | |
878 | path.push(ty.parent.name.toLowerCase()); | |
879 | } | |
880 | ||
0731742a XL |
881 | var length = path.length; |
882 | var clength = contains.length; | |
883 | if (clength > length) { | |
abe05a73 XL |
884 | return MAX_LEV_DISTANCE + 1; |
885 | } | |
0731742a XL |
886 | for (var i = 0; i < length; ++i) { |
887 | if (i + clength > length) { | |
abe05a73 XL |
888 | break; |
889 | } | |
890 | var lev_total = 0; | |
891 | var aborted = false; | |
0731742a | 892 | for (var x = 0; x < clength; ++x) { |
b7449926 | 893 | var lev = levenshtein(path[i + x], contains[x]); |
abe05a73 XL |
894 | if (lev > MAX_LEV_DISTANCE) { |
895 | aborted = true; | |
896 | break; | |
897 | } | |
898 | lev_total += lev; | |
899 | } | |
900 | if (aborted === false) { | |
0731742a | 901 | ret_lev = Math.min(ret_lev, Math.round(lev_total / clength)); |
abe05a73 | 902 | } |
1a4d82fc | 903 | } |
abe05a73 | 904 | return ret_lev; |
1a4d82fc JJ |
905 | } |
906 | ||
e9174d1e SL |
907 | function typePassesFilter(filter, type) { |
908 | // No filter | |
909 | if (filter < 0) return true; | |
910 | ||
911 | // Exact match | |
912 | if (filter === type) return true; | |
913 | ||
914 | // Match related items | |
915 | var name = itemTypes[type]; | |
916 | switch (itemTypes[filter]) { | |
917 | case "constant": | |
918 | return (name == "associatedconstant"); | |
919 | case "fn": | |
920 | return (name == "method" || name == "tymethod"); | |
921 | case "type": | |
94b46f34 | 922 | return (name == "primitive" || name == "keyword"); |
e9174d1e SL |
923 | } |
924 | ||
925 | // No match | |
926 | return false; | |
927 | } | |
928 | ||
abe05a73 XL |
929 | function generateId(ty) { |
930 | if (ty.parent && ty.parent.name) { | |
931 | return itemTypes[ty.ty] + ty.path + ty.parent.name + ty.name; | |
932 | } | |
933 | return itemTypes[ty.ty] + ty.path + ty.name; | |
934 | } | |
935 | ||
1a4d82fc JJ |
936 | // quoted values mean literal search |
937 | var nSearchWords = searchWords.length; | |
0731742a XL |
938 | var i; |
939 | var ty; | |
940 | var fullId; | |
941 | var returned; | |
942 | var in_args; | |
1a4d82fc JJ |
943 | if ((val.charAt(0) === "\"" || val.charAt(0) === "'") && |
944 | val.charAt(val.length - 1) === val.charAt(0)) | |
945 | { | |
abe05a73 | 946 | val = extractGenerics(val.substr(1, val.length - 2)); |
0731742a XL |
947 | for (i = 0; i < nSearchWords; ++i) { |
948 | if (filterCrates !== undefined && searchIndex[i].crate !== filterCrates) { | |
949 | continue; | |
950 | } | |
951 | in_args = findArg(searchIndex[i], val, true); | |
952 | returned = checkReturned(searchIndex[i], val, true); | |
953 | ty = searchIndex[i]; | |
954 | fullId = generateId(ty); | |
abe05a73 XL |
955 | |
956 | if (searchWords[i] === val.name) { | |
1a4d82fc | 957 | // filter type: ... queries |
abe05a73 XL |
958 | if (typePassesFilter(typeFilter, searchIndex[i].ty) && |
959 | results[fullId] === undefined) | |
960 | { | |
961 | results[fullId] = {id: i, index: -1}; | |
962 | } | |
963 | } else if ((in_args === true || returned === true) && | |
964 | typePassesFilter(typeFilter, searchIndex[i].ty)) { | |
965 | if (in_args === true || returned === true) { | |
966 | if (in_args === true) { | |
967 | results_in_args[fullId] = { | |
968 | id: i, | |
969 | index: -1, | |
970 | dontValidate: true, | |
971 | }; | |
972 | } | |
973 | if (returned === true) { | |
974 | results_returned[fullId] = { | |
975 | id: i, | |
976 | index: -1, | |
977 | dontValidate: true, | |
978 | }; | |
979 | } | |
980 | } else { | |
981 | results[fullId] = { | |
982 | id: i, | |
983 | index: -1, | |
984 | dontValidate: true, | |
985 | }; | |
1a4d82fc | 986 | } |
1a4d82fc JJ |
987 | } |
988 | } | |
abe05a73 XL |
989 | query.inputs = [val]; |
990 | query.output = val; | |
991 | query.search = val; | |
c34b1796 AL |
992 | // searching by type |
993 | } else if (val.search("->") > -1) { | |
83c7162d | 994 | var trimmer = function(s) { return s.trim(); }; |
c34b1796 AL |
995 | var parts = val.split("->").map(trimmer); |
996 | var input = parts[0]; | |
997 | // sort inputs so that order does not matter | |
abe05a73 | 998 | var inputs = input.split(",").map(trimmer).sort(); |
0731742a | 999 | for (i = 0; i < inputs.length; ++i) { |
abe05a73 XL |
1000 | inputs[i] = extractGenerics(inputs[i]); |
1001 | } | |
1002 | var output = extractGenerics(parts[1]); | |
c34b1796 | 1003 | |
0731742a XL |
1004 | for (i = 0; i < nSearchWords; ++i) { |
1005 | if (filterCrates !== undefined && searchIndex[i].crate !== filterCrates) { | |
1006 | continue; | |
1007 | } | |
c34b1796 | 1008 | var type = searchIndex[i].type; |
0731742a | 1009 | ty = searchIndex[i]; |
c34b1796 AL |
1010 | if (!type) { |
1011 | continue; | |
1012 | } | |
0731742a | 1013 | fullId = generateId(ty); |
c34b1796 AL |
1014 | |
1015 | // allow searching for void (no output) functions as well | |
8faf50e0 | 1016 | var typeOutput = type.length > OUTPUT_DATA ? type[OUTPUT_DATA].name : ""; |
0731742a | 1017 | returned = checkReturned(ty, output, true); |
abe05a73 | 1018 | if (output.name === "*" || returned === true) { |
0731742a | 1019 | in_args = false; |
48663c56 | 1020 | var is_module = false; |
abe05a73 XL |
1021 | |
1022 | if (input === "*") { | |
48663c56 | 1023 | is_module = true; |
abe05a73 XL |
1024 | } else { |
1025 | var allFound = true; | |
1026 | for (var it = 0; allFound === true && it < inputs.length; it++) { | |
1027 | allFound = checkType(type, inputs[it], true); | |
1a4d82fc | 1028 | } |
abe05a73 | 1029 | in_args = allFound; |
1a4d82fc | 1030 | } |
abe05a73 XL |
1031 | if (in_args === true) { |
1032 | results_in_args[fullId] = { | |
1033 | id: i, | |
1034 | index: -1, | |
1035 | dontValidate: true, | |
1036 | }; | |
1037 | } | |
1038 | if (returned === true) { | |
1039 | results_returned[fullId] = { | |
1040 | id: i, | |
1041 | index: -1, | |
1042 | dontValidate: true, | |
1043 | }; | |
1044 | } | |
48663c56 | 1045 | if (is_module === true) { |
abe05a73 XL |
1046 | results[fullId] = { |
1047 | id: i, | |
1048 | index: -1, | |
1049 | dontValidate: true, | |
1050 | }; | |
1a4d82fc JJ |
1051 | } |
1052 | } | |
1053 | } | |
abe05a73 XL |
1054 | query.inputs = inputs.map(function(input) { |
1055 | return input.name; | |
1056 | }); | |
1057 | query.output = output.name; | |
1058 | } else { | |
1059 | query.inputs = [val]; | |
1060 | query.output = val; | |
1061 | query.search = val; | |
1062 | // gather matching search results up to a certain maximum | |
1063 | val = val.replace(/\_/g, ""); | |
1a4d82fc | 1064 | |
abe05a73 | 1065 | var valGenerics = extractGenerics(val); |
1a4d82fc | 1066 | |
abe05a73 XL |
1067 | var paths = valLower.split("::"); |
1068 | var j; | |
1069 | for (j = 0; j < paths.length; ++j) { | |
1070 | if (paths[j] === "") { | |
1071 | paths.splice(j, 1); | |
1072 | j -= 1; | |
1073 | } | |
b039eaaf | 1074 | } |
abe05a73 | 1075 | val = paths[paths.length - 1]; |
b7449926 | 1076 | var contains = paths.slice(0, paths.length > 1 ? paths.length - 1 : 1); |
1a4d82fc | 1077 | |
60c5eb7d XL |
1078 | var lev; |
1079 | var lev_distance; | |
abe05a73 | 1080 | for (j = 0; j < nSearchWords; ++j) { |
0731742a XL |
1081 | ty = searchIndex[j]; |
1082 | if (!ty || (filterCrates !== undefined && ty.crate !== filterCrates)) { | |
abe05a73 XL |
1083 | continue; |
1084 | } | |
1085 | var lev_add = 0; | |
1086 | if (paths.length > 1) { | |
0731742a | 1087 | lev = checkPath(contains, paths[paths.length - 1], ty); |
abe05a73 XL |
1088 | if (lev > MAX_LEV_DISTANCE) { |
1089 | continue; | |
1090 | } else if (lev > 0) { | |
e1599b0c | 1091 | lev_add = lev / 10; |
abe05a73 XL |
1092 | } |
1093 | } | |
1a4d82fc | 1094 | |
0731742a XL |
1095 | returned = MAX_LEV_DISTANCE + 1; |
1096 | in_args = MAX_LEV_DISTANCE + 1; | |
abe05a73 XL |
1097 | var index = -1; |
1098 | // we want lev results to go lower than others | |
0731742a XL |
1099 | lev = MAX_LEV_DISTANCE + 1; |
1100 | fullId = generateId(ty); | |
abe05a73 XL |
1101 | |
1102 | if (searchWords[j].indexOf(split[i]) > -1 || | |
1103 | searchWords[j].indexOf(val) > -1 || | |
1104 | searchWords[j].replace(/_/g, "").indexOf(val) > -1) | |
1105 | { | |
1106 | // filter type: ... queries | |
1107 | if (typePassesFilter(typeFilter, ty.ty) && results[fullId] === undefined) { | |
1108 | index = searchWords[j].replace(/_/g, "").indexOf(val); | |
1109 | } | |
1110 | } | |
1111 | if ((lev = levenshtein(searchWords[j], val)) <= MAX_LEV_DISTANCE) { | |
1112 | if (typePassesFilter(typeFilter, ty.ty) === false) { | |
1113 | lev = MAX_LEV_DISTANCE + 1; | |
1114 | } else { | |
1115 | lev += 1; | |
1116 | } | |
1117 | } | |
1118 | if ((in_args = findArg(ty, valGenerics)) <= MAX_LEV_DISTANCE) { | |
1119 | if (typePassesFilter(typeFilter, ty.ty) === false) { | |
1120 | in_args = MAX_LEV_DISTANCE + 1; | |
1121 | } | |
1122 | } | |
1123 | if ((returned = checkReturned(ty, valGenerics)) <= MAX_LEV_DISTANCE) { | |
1124 | if (typePassesFilter(typeFilter, ty.ty) === false) { | |
1125 | returned = MAX_LEV_DISTANCE + 1; | |
1126 | } | |
1127 | } | |
1a4d82fc | 1128 | |
abe05a73 | 1129 | lev += lev_add; |
b7449926 | 1130 | if (lev > 0 && val.length > 3 && searchWords[j].indexOf(val) > -1) { |
ff7c6d11 XL |
1131 | if (val.length < 6) { |
1132 | lev -= 1; | |
1133 | } else { | |
1134 | lev = 0; | |
1135 | } | |
1136 | } | |
abe05a73 XL |
1137 | if (in_args <= MAX_LEV_DISTANCE) { |
1138 | if (results_in_args[fullId] === undefined) { | |
1139 | results_in_args[fullId] = { | |
1140 | id: j, | |
1141 | index: index, | |
1142 | lev: in_args, | |
1143 | }; | |
1144 | } | |
1145 | results_in_args[fullId].lev = | |
1146 | Math.min(results_in_args[fullId].lev, in_args); | |
1147 | } | |
1148 | if (returned <= MAX_LEV_DISTANCE) { | |
1149 | if (results_returned[fullId] === undefined) { | |
1150 | results_returned[fullId] = { | |
1151 | id: j, | |
1152 | index: index, | |
1153 | lev: returned, | |
1154 | }; | |
1155 | } | |
1156 | results_returned[fullId].lev = | |
1157 | Math.min(results_returned[fullId].lev, returned); | |
1158 | } | |
1159 | if (index !== -1 || lev <= MAX_LEV_DISTANCE) { | |
94b46f34 | 1160 | if (index !== -1 && paths.length < 2) { |
abe05a73 XL |
1161 | lev = 0; |
1162 | } | |
1163 | if (results[fullId] === undefined) { | |
1164 | results[fullId] = { | |
1165 | id: j, | |
1166 | index: index, | |
1167 | lev: lev, | |
1168 | }; | |
1169 | } | |
1170 | results[fullId].lev = Math.min(results[fullId].lev, lev); | |
1171 | } | |
1a4d82fc JJ |
1172 | } |
1173 | } | |
c34b1796 | 1174 | |
83c7162d | 1175 | var ret = { |
0731742a XL |
1176 | "in_args": sortResults(results_in_args, true), |
1177 | "returned": sortResults(results_returned, true), | |
1178 | "others": sortResults(results), | |
abe05a73 | 1179 | }; |
83c7162d XL |
1180 | if (ALIASES && ALIASES[window.currentCrate] && |
1181 | ALIASES[window.currentCrate][query.raw]) { | |
1182 | var aliases = ALIASES[window.currentCrate][query.raw]; | |
0731742a | 1183 | for (i = 0; i < aliases.length; ++i) { |
94b46f34 XL |
1184 | aliases[i].is_alias = true; |
1185 | aliases[i].alias = query.raw; | |
1186 | aliases[i].path = aliases[i].p; | |
1187 | var res = buildHrefAndPath(aliases[i]); | |
1188 | aliases[i].displayPath = pathSplitter(res[0]); | |
1189 | aliases[i].fullPath = aliases[i].displayPath + aliases[i].name; | |
1190 | aliases[i].href = res[1]; | |
0731742a XL |
1191 | ret.others.unshift(aliases[i]); |
1192 | if (ret.others.length > MAX_RESULTS) { | |
1193 | ret.others.pop(); | |
83c7162d XL |
1194 | } |
1195 | } | |
1196 | } | |
1197 | return ret; | |
1a4d82fc JJ |
1198 | } |
1199 | ||
1200 | /** | |
1201 | * Validate performs the following boolean logic. For example: | |
1202 | * "File::open" will give IF A PARENT EXISTS => ("file" && "open") | |
1203 | * exists in (name || path || parent) OR => ("file" && "open") exists in | |
1204 | * (name || path ) | |
1205 | * | |
1206 | * This could be written functionally, but I wanted to minimise | |
1207 | * functions on stack. | |
1208 | * | |
1209 | * @param {[string]} name [The name of the result] | |
1210 | * @param {[string]} path [The path of the result] | |
1211 | * @param {[string]} keys [The keys to be used (["file", "open"])] | |
1212 | * @param {[object]} parent [The parent of the result] | |
1213 | * @return {[boolean]} [Whether the result is valid or not] | |
1214 | */ | |
1215 | function validateResult(name, path, keys, parent) { | |
62682a34 | 1216 | for (var i = 0; i < keys.length; ++i) { |
1a4d82fc JJ |
1217 | // each check is for validation so we negate the conditions and invalidate |
1218 | if (!( | |
1219 | // check for an exact name match | |
abe05a73 | 1220 | name.indexOf(keys[i]) > -1 || |
1a4d82fc | 1221 | // then an exact path match |
abe05a73 | 1222 | path.indexOf(keys[i]) > -1 || |
1a4d82fc | 1223 | // next if there is a parent, check for exact parent match |
60c5eb7d | 1224 | (parent !== undefined && parent.name !== undefined && |
1a4d82fc JJ |
1225 | parent.name.toLowerCase().indexOf(keys[i]) > -1) || |
1226 | // lastly check to see if the name was a levenshtein match | |
abe05a73 | 1227 | levenshtein(name, keys[i]) <= MAX_LEV_DISTANCE)) { |
1a4d82fc JJ |
1228 | return false; |
1229 | } | |
1230 | } | |
1231 | return true; | |
1232 | } | |
1233 | ||
2c00a5a8 XL |
1234 | function getQuery(raw) { |
1235 | var matches, type, query; | |
1a4d82fc JJ |
1236 | query = raw; |
1237 | ||
e9174d1e | 1238 | matches = query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i); |
1a4d82fc | 1239 | if (matches) { |
0731742a | 1240 | type = matches[1].replace(/^const$/, "constant"); |
1a4d82fc JJ |
1241 | query = query.substring(matches[0].length); |
1242 | } | |
1243 | ||
1244 | return { | |
1245 | raw: raw, | |
1246 | query: query, | |
1247 | type: type, | |
62682a34 | 1248 | id: query + type |
1a4d82fc JJ |
1249 | }; |
1250 | } | |
1251 | ||
1252 | function initSearchNav() { | |
7cac9316 | 1253 | var hoverTimeout; |
1a4d82fc | 1254 | |
7cac9316 XL |
1255 | var click_func = function(e) { |
1256 | var el = e.target; | |
1257 | // to retrieve the real "owner" of the event. | |
0731742a | 1258 | while (el.tagName !== "TR") { |
7cac9316 XL |
1259 | el = el.parentNode; |
1260 | } | |
0731742a | 1261 | var dst = e.target.getElementsByTagName("a"); |
7cac9316 XL |
1262 | if (dst.length < 1) { |
1263 | return; | |
1264 | } | |
1265 | dst = dst[0]; | |
62682a34 | 1266 | if (window.location.pathname === dst.pathname) { |
e74abb32 | 1267 | addClass(getSearchElement(), "hidden"); |
0731742a | 1268 | removeClass(main, "hidden"); |
1a4d82fc JJ |
1269 | document.location.href = dst.href; |
1270 | } | |
7cac9316 XL |
1271 | }; |
1272 | var mouseover_func = function(e) { | |
1273 | var el = e.target; | |
1274 | // to retrieve the real "owner" of the event. | |
0731742a | 1275 | while (el.tagName !== "TR") { |
7cac9316 XL |
1276 | el = el.parentNode; |
1277 | } | |
1a4d82fc JJ |
1278 | clearTimeout(hoverTimeout); |
1279 | hoverTimeout = setTimeout(function() { | |
0731742a XL |
1280 | onEachLazy(document.getElementsByClassName("search-results"), function(e) { |
1281 | onEachLazy(e.getElementsByClassName("result"), function(i_e) { | |
1282 | removeClass(i_e, "highlighted"); | |
7cac9316 XL |
1283 | }); |
1284 | }); | |
0731742a | 1285 | addClass(el, "highlighted"); |
1a4d82fc | 1286 | }, 20); |
7cac9316 | 1287 | }; |
0731742a XL |
1288 | onEachLazy(document.getElementsByClassName("search-results"), function(e) { |
1289 | onEachLazy(e.getElementsByClassName("result"), function(i_e) { | |
7cac9316 XL |
1290 | i_e.onclick = click_func; |
1291 | i_e.onmouseover = mouseover_func; | |
1292 | }); | |
1a4d82fc JJ |
1293 | }); |
1294 | ||
7cac9316 | 1295 | search_input.onkeydown = function(e) { |
abe05a73 XL |
1296 | // "actives" references the currently highlighted item in each search tab. |
1297 | // Each array in "actives" represents a tab. | |
1298 | var actives = [[], [], []]; | |
1299 | // "current" is used to know which tab we're looking into. | |
1300 | var current = 0; | |
9fa01778 | 1301 | onEachLazy(document.getElementById("results").childNodes, function(e) { |
0731742a | 1302 | onEachLazy(e.getElementsByClassName("highlighted"), function(e) { |
abe05a73 | 1303 | actives[current].push(e); |
7cac9316 | 1304 | }); |
abe05a73 | 1305 | current += 1; |
7cac9316 | 1306 | }); |
1a4d82fc JJ |
1307 | |
1308 | if (e.which === 38) { // up | |
abe05a73 XL |
1309 | if (!actives[currentTab].length || |
1310 | !actives[currentTab][0].previousElementSibling) { | |
1a4d82fc JJ |
1311 | return; |
1312 | } | |
1313 | ||
0731742a XL |
1314 | addClass(actives[currentTab][0].previousElementSibling, "highlighted"); |
1315 | removeClass(actives[currentTab][0], "highlighted"); | |
1a4d82fc | 1316 | } else if (e.which === 40) { // down |
abe05a73 | 1317 | if (!actives[currentTab].length) { |
9fa01778 | 1318 | var results = document.getElementById("results").childNodes; |
7cac9316 | 1319 | if (results.length > 0) { |
0731742a | 1320 | var res = results[currentTab].getElementsByClassName("result"); |
7cac9316 | 1321 | if (res.length > 0) { |
0731742a | 1322 | addClass(res[0], "highlighted"); |
7cac9316 XL |
1323 | } |
1324 | } | |
abe05a73 | 1325 | } else if (actives[currentTab][0].nextElementSibling) { |
0731742a XL |
1326 | addClass(actives[currentTab][0].nextElementSibling, "highlighted"); |
1327 | removeClass(actives[currentTab][0], "highlighted"); | |
1a4d82fc JJ |
1328 | } |
1329 | } else if (e.which === 13) { // return | |
abe05a73 XL |
1330 | if (actives[currentTab].length) { |
1331 | document.location.href = | |
0731742a | 1332 | actives[currentTab][0].getElementsByTagName("a")[0].href; |
abe05a73 XL |
1333 | } |
1334 | } else if (e.which === 9) { // tab | |
1335 | if (e.shiftKey) { | |
1336 | printTab(currentTab > 0 ? currentTab - 1 : 2); | |
1337 | } else { | |
1338 | printTab(currentTab > 1 ? 0 : currentTab + 1); | |
1a4d82fc | 1339 | } |
abe05a73 XL |
1340 | e.preventDefault(); |
1341 | } else if (e.which === 16) { // shift | |
1342 | // Does nothing, it's just to avoid losing "focus" on the highlighted element. | |
2c00a5a8 | 1343 | } else if (e.which === 27) { // escape |
e1599b0c | 1344 | handleEscape(e); |
abe05a73 | 1345 | } else if (actives[currentTab].length > 0) { |
0731742a | 1346 | removeClass(actives[currentTab][0], "highlighted"); |
1a4d82fc | 1347 | } |
7cac9316 | 1348 | }; |
1a4d82fc JJ |
1349 | } |
1350 | ||
83c7162d XL |
1351 | function buildHrefAndPath(item) { |
1352 | var displayPath; | |
1353 | var href; | |
1354 | var type = itemTypes[item.ty]; | |
1355 | var name = item.name; | |
1356 | ||
0731742a XL |
1357 | if (type === "mod") { |
1358 | displayPath = item.path + "::"; | |
1359 | href = rootPath + item.path.replace(/::/g, "/") + "/" + | |
1360 | name + "/index.html"; | |
94b46f34 | 1361 | } else if (type === "primitive" || type === "keyword") { |
83c7162d | 1362 | displayPath = ""; |
0731742a XL |
1363 | href = rootPath + item.path.replace(/::/g, "/") + |
1364 | "/" + type + "." + name + ".html"; | |
83c7162d XL |
1365 | } else if (type === "externcrate") { |
1366 | displayPath = ""; | |
0731742a | 1367 | href = rootPath + name + "/index.html"; |
83c7162d XL |
1368 | } else if (item.parent !== undefined) { |
1369 | var myparent = item.parent; | |
0731742a | 1370 | var anchor = "#" + type + "." + name; |
83c7162d XL |
1371 | var parentType = itemTypes[myparent.ty]; |
1372 | if (parentType === "primitive") { | |
0731742a | 1373 | displayPath = myparent.name + "::"; |
83c7162d | 1374 | } else { |
0731742a | 1375 | displayPath = item.path + "::" + myparent.name + "::"; |
83c7162d | 1376 | } |
0731742a XL |
1377 | href = rootPath + item.path.replace(/::/g, "/") + |
1378 | "/" + parentType + | |
1379 | "." + myparent.name + | |
1380 | ".html" + anchor; | |
83c7162d | 1381 | } else { |
0731742a XL |
1382 | displayPath = item.path + "::"; |
1383 | href = rootPath + item.path.replace(/::/g, "/") + | |
1384 | "/" + type + "." + name + ".html"; | |
83c7162d XL |
1385 | } |
1386 | return [displayPath, href]; | |
1387 | } | |
1388 | ||
94b46f34 | 1389 | function escape(content) { |
0731742a | 1390 | var h1 = document.createElement("h1"); |
94b46f34 XL |
1391 | h1.textContent = content; |
1392 | return h1.innerHTML; | |
1393 | } | |
1394 | ||
1395 | function pathSplitter(path) { | |
0731742a | 1396 | var tmp = "<span>" + path.replace(/::/g, "::</span><span>"); |
94b46f34 XL |
1397 | if (tmp.endsWith("<span>")) { |
1398 | return tmp.slice(0, tmp.length - 6); | |
1399 | } | |
1400 | return tmp; | |
1401 | } | |
1402 | ||
abe05a73 | 1403 | function addTab(array, query, display) { |
0731742a | 1404 | var extraStyle = ""; |
abe05a73 | 1405 | if (display === false) { |
0731742a | 1406 | extraStyle = " style=\"display: none;\""; |
abe05a73 | 1407 | } |
1a4d82fc | 1408 | |
0731742a | 1409 | var output = ""; |
94b46f34 XL |
1410 | var duplicates = {}; |
1411 | var length = 0; | |
abe05a73 | 1412 | if (array.length > 0) { |
0731742a | 1413 | output = "<table class=\"search-results\"" + extraStyle + ">"; |
1a4d82fc | 1414 | |
abe05a73 | 1415 | array.forEach(function(item) { |
94b46f34 | 1416 | var name, type; |
1a4d82fc | 1417 | |
1a4d82fc JJ |
1418 | name = item.name; |
1419 | type = itemTypes[item.ty]; | |
1420 | ||
94b46f34 XL |
1421 | if (item.is_alias !== true) { |
1422 | if (duplicates[item.fullPath]) { | |
1423 | return; | |
1424 | } | |
1425 | duplicates[item.fullPath] = true; | |
1426 | } | |
1427 | length += 1; | |
1a4d82fc | 1428 | |
0731742a XL |
1429 | output += "<tr class=\"" + type + " result\"><td>" + |
1430 | "<a href=\"" + item.href + "\">" + | |
94b46f34 | 1431 | (item.is_alias === true ? |
0731742a XL |
1432 | ("<span class=\"alias\"><b>" + item.alias + " </b></span><span " + |
1433 | "class=\"grey\"><i> - see </i></span>") : "") + | |
1434 | item.displayPath + "<span class=\"" + type + "\">" + | |
1435 | name + "</span></a></td><td>" + | |
1436 | "<a href=\"" + item.href + "\">" + | |
1437 | "<span class=\"desc\">" + escape(item.desc) + | |
1438 | " </span></a></td></tr>"; | |
1a4d82fc | 1439 | }); |
0731742a | 1440 | output += "</table>"; |
1a4d82fc | 1441 | } else { |
0731742a XL |
1442 | output = "<div class=\"search-failed\"" + extraStyle + ">No results :(<br/>" + |
1443 | "Try on <a href=\"https://duckduckgo.com/?q=" + | |
1444 | encodeURIComponent("rust " + query.query) + | |
1445 | "\">DuckDuckGo</a>?<br/><br/>" + | |
1446 | "Or try looking in one of these:<ul><li>The <a " + | |
1447 | "href=\"https://doc.rust-lang.org/reference/index.html\">Rust Reference</a> " + | |
1448 | " for technical details about the language.</li><li><a " + | |
1449 | "href=\"https://doc.rust-lang.org/rust-by-example/index.html\">Rust By " + | |
1450 | "Example</a> for expository code examples.</a></li><li>The <a " + | |
1451 | "href=\"https://doc.rust-lang.org/book/index.html\">Rust Book</a> for " + | |
1452 | "introductions to language features and the language itself.</li><li><a " + | |
1453 | "href=\"https://docs.rs\">Docs.rs</a> for documentation of crates released on" + | |
1454 | " <a href=\"https://crates.io/\">crates.io</a>.</li></ul></div>"; | |
1a4d82fc | 1455 | } |
94b46f34 | 1456 | return [output, length]; |
abe05a73 XL |
1457 | } |
1458 | ||
1459 | function makeTabHeader(tabNb, text, nbElems) { | |
1460 | if (currentTab === tabNb) { | |
0731742a XL |
1461 | return "<div class=\"selected\">" + text + |
1462 | " <div class=\"count\">(" + nbElems + ")</div></div>"; | |
abe05a73 | 1463 | } |
0731742a | 1464 | return "<div>" + text + " <div class=\"count\">(" + nbElems + ")</div></div>"; |
abe05a73 XL |
1465 | } |
1466 | ||
1467 | function showResults(results) { | |
0731742a XL |
1468 | if (results.others.length === 1 && |
1469 | getCurrentValue("rustdoc-go-to-only-result") === "true") { | |
1470 | var elem = document.createElement("a"); | |
1471 | elem.href = results.others[0].href; | |
1472 | elem.style.display = "none"; | |
83c7162d XL |
1473 | // For firefox, we need the element to be in the DOM so it can be clicked. |
1474 | document.body.appendChild(elem); | |
1475 | elem.click(); | |
1476 | } | |
94b46f34 | 1477 | var query = getQuery(search_input.value); |
abe05a73 XL |
1478 | |
1479 | currentResults = query.id; | |
94b46f34 | 1480 | |
0731742a XL |
1481 | var ret_others = addTab(results.others, query); |
1482 | var ret_in_args = addTab(results.in_args, query, false); | |
1483 | var ret_returned = addTab(results.returned, query, false); | |
94b46f34 | 1484 | |
0731742a XL |
1485 | var output = "<h1>Results for " + escape(query.query) + |
1486 | (query.type ? " (type: " + escape(query.type) + ")" : "") + "</h1>" + | |
1487 | "<div id=\"titles\">" + | |
94b46f34 XL |
1488 | makeTabHeader(0, "In Names", ret_others[1]) + |
1489 | makeTabHeader(1, "In Parameters", ret_in_args[1]) + | |
1490 | makeTabHeader(2, "In Return Types", ret_returned[1]) + | |
0731742a XL |
1491 | "</div><div id=\"results\">" + |
1492 | ret_others[0] + ret_in_args[0] + ret_returned[0] + "</div>"; | |
1a4d82fc | 1493 | |
0731742a | 1494 | addClass(main, "hidden"); |
e1599b0c | 1495 | var search = getSearchElement(); |
0731742a | 1496 | removeClass(search, "hidden"); |
7cac9316 | 1497 | search.innerHTML = output; |
0731742a | 1498 | var tds = search.getElementsByTagName("td"); |
7cac9316 XL |
1499 | var td_width = 0; |
1500 | if (tds.length > 0) { | |
1501 | td_width = tds[0].offsetWidth; | |
1502 | } | |
1503 | var width = search.offsetWidth - 40 - td_width; | |
0731742a XL |
1504 | onEachLazy(search.getElementsByClassName("desc"), function(e) { |
1505 | e.style.width = width + "px"; | |
7cac9316 | 1506 | }); |
1a4d82fc | 1507 | initSearchNav(); |
0731742a | 1508 | var elems = document.getElementById("titles").childNodes; |
abe05a73 XL |
1509 | elems[0].onclick = function() { printTab(0); }; |
1510 | elems[1].onclick = function() { printTab(1); }; | |
1511 | elems[2].onclick = function() { printTab(2); }; | |
1512 | printTab(currentTab); | |
1a4d82fc JJ |
1513 | } |
1514 | ||
0731742a XL |
1515 | function execSearch(query, searchWords, filterCrates) { |
1516 | function getSmallest(arrays, positions, notDuplicates) { | |
1517 | var start = null; | |
83c7162d | 1518 | |
0731742a XL |
1519 | for (var it = 0; it < positions.length; ++it) { |
1520 | if (arrays[it].length > positions[it] && | |
1521 | (start === null || start > arrays[it][positions[it]].lev) && | |
1522 | !notDuplicates[arrays[it][positions[it]].fullPath]) { | |
1523 | start = arrays[it][positions[it]].lev; | |
83c7162d | 1524 | } |
83c7162d | 1525 | } |
0731742a XL |
1526 | return start; |
1527 | } | |
83c7162d | 1528 | |
0731742a XL |
1529 | function mergeArrays(arrays) { |
1530 | var ret = []; | |
1531 | var positions = []; | |
1532 | var notDuplicates = {}; | |
83c7162d | 1533 | |
0731742a XL |
1534 | for (var x = 0; x < arrays.length; ++x) { |
1535 | positions.push(0); | |
1536 | } | |
1537 | while (ret.length < MAX_RESULTS) { | |
1538 | var smallest = getSmallest(arrays, positions, notDuplicates); | |
94b46f34 | 1539 | |
0731742a XL |
1540 | if (smallest === null) { |
1541 | break; | |
1542 | } | |
1543 | for (x = 0; x < arrays.length && ret.length < MAX_RESULTS; ++x) { | |
1544 | if (arrays[x].length > positions[x] && | |
1545 | arrays[x][positions[x]].lev === smallest && | |
1546 | !notDuplicates[arrays[x][positions[x]].fullPath]) { | |
1547 | ret.push(arrays[x][positions[x]]); | |
1548 | notDuplicates[arrays[x][positions[x]].fullPath] = true; | |
1549 | positions[x] += 1; | |
83c7162d XL |
1550 | } |
1551 | } | |
83c7162d | 1552 | } |
0731742a XL |
1553 | return ret; |
1554 | } | |
1555 | ||
1556 | var queries = query.raw.split(","); | |
1557 | var results = { | |
1558 | "in_args": [], | |
1559 | "returned": [], | |
1560 | "others": [], | |
1561 | }; | |
1562 | ||
1563 | for (var i = 0; i < queries.length; ++i) { | |
1564 | query = queries[i].trim(); | |
1565 | if (query.length !== 0) { | |
1566 | var tmp = execQuery(getQuery(query), searchWords, filterCrates); | |
83c7162d | 1567 | |
0731742a XL |
1568 | results.in_args.push(tmp.in_args); |
1569 | results.returned.push(tmp.returned); | |
1570 | results.others.push(tmp.others); | |
1571 | } | |
1572 | } | |
1573 | if (queries.length > 1) { | |
83c7162d | 1574 | return { |
0731742a XL |
1575 | "in_args": mergeArrays(results.in_args), |
1576 | "returned": mergeArrays(results.returned), | |
1577 | "others": mergeArrays(results.others), | |
83c7162d XL |
1578 | }; |
1579 | } else { | |
1580 | return { | |
0731742a XL |
1581 | "in_args": results.in_args[0], |
1582 | "returned": results.returned[0], | |
1583 | "others": results.others[0], | |
83c7162d XL |
1584 | }; |
1585 | } | |
1586 | } | |
1587 | ||
0731742a XL |
1588 | function getFilterCrates() { |
1589 | var elem = document.getElementById("crate-search"); | |
1590 | ||
1591 | if (elem && elem.value !== "All crates" && rawSearchIndex.hasOwnProperty(elem.value)) { | |
1592 | return elem.value; | |
1593 | } | |
1594 | return undefined; | |
1595 | } | |
1596 | ||
1597 | function search(e, forced) { | |
1a4d82fc | 1598 | var params = getQueryStringParams(); |
83c7162d | 1599 | var query = getQuery(search_input.value.trim()); |
1a4d82fc | 1600 | |
1a4d82fc JJ |
1601 | if (e) { |
1602 | e.preventDefault(); | |
1603 | } | |
1604 | ||
0731742a XL |
1605 | if (query.query.length === 0) { |
1606 | return; | |
1607 | } | |
1608 | if (forced !== true && query.id === currentResults) { | |
83c7162d XL |
1609 | if (query.query.length > 0) { |
1610 | putBackSearch(search_input); | |
1611 | } | |
1a4d82fc JJ |
1612 | return; |
1613 | } | |
1614 | ||
62682a34 | 1615 | // Update document title to maintain a meaningful browser history |
7cac9316 | 1616 | document.title = "Results for " + query.query + " - Rust"; |
62682a34 | 1617 | |
1a4d82fc JJ |
1618 | // Because searching is incremental by character, only the most |
1619 | // recent search query is added to the browser history. | |
1620 | if (browserSupportsHistoryApi()) { | |
1621 | if (!history.state && !params.search) { | |
7cac9316 | 1622 | history.pushState(query, "", "?search=" + encodeURIComponent(query.raw)); |
1a4d82fc | 1623 | } else { |
7cac9316 | 1624 | history.replaceState(query, "", "?search=" + encodeURIComponent(query.raw)); |
1a4d82fc JJ |
1625 | } |
1626 | } | |
1627 | ||
0731742a | 1628 | var filterCrates = getFilterCrates(); |
60c5eb7d | 1629 | showResults(execSearch(query, index, filterCrates)); |
1a4d82fc JJ |
1630 | } |
1631 | ||
1a4d82fc JJ |
1632 | function buildIndex(rawSearchIndex) { |
1633 | searchIndex = []; | |
1634 | var searchWords = []; | |
0731742a XL |
1635 | var i; |
1636 | ||
1a4d82fc | 1637 | for (var crate in rawSearchIndex) { |
62682a34 | 1638 | if (!rawSearchIndex.hasOwnProperty(crate)) { continue; } |
1a4d82fc | 1639 | |
7453a54e SL |
1640 | searchWords.push(crate); |
1641 | searchIndex.push({ | |
1642 | crate: crate, | |
1643 | ty: 1, // == ExternCrate | |
1644 | name: crate, | |
1645 | path: "", | |
1646 | desc: rawSearchIndex[crate].doc, | |
1647 | type: null, | |
1648 | }); | |
1649 | ||
1a4d82fc JJ |
1650 | // an array of [(Number) item type, |
1651 | // (String) name, | |
1652 | // (String) full path or empty string for previous path, | |
1653 | // (String) description, | |
c34b1796 AL |
1654 | // (Number | null) the parent path index to `paths`] |
1655 | // (Object | null) the type of the function (if any) | |
9fa01778 | 1656 | var items = rawSearchIndex[crate].i; |
1a4d82fc JJ |
1657 | // an array of [(Number) item type, |
1658 | // (String) name] | |
9fa01778 | 1659 | var paths = rawSearchIndex[crate].p; |
1a4d82fc JJ |
1660 | |
1661 | // convert `paths` into an object form | |
1662 | var len = paths.length; | |
0731742a | 1663 | for (i = 0; i < len; ++i) { |
1a4d82fc JJ |
1664 | paths[i] = {ty: paths[i][0], name: paths[i][1]}; |
1665 | } | |
1666 | ||
1667 | // convert `items` into an object form, and construct word indices. | |
1668 | // | |
1669 | // before any analysis is performed lets gather the search terms to | |
1670 | // search against apart from the rest of the data. This is a quick | |
1671 | // operation that is cached for the life of the page state so that | |
1672 | // all other search operations have access to this cached data for | |
1673 | // faster analysis operations | |
0731742a | 1674 | len = items.length; |
1a4d82fc | 1675 | var lastPath = ""; |
0731742a | 1676 | for (i = 0; i < len; ++i) { |
1a4d82fc JJ |
1677 | var rawRow = items[i]; |
1678 | var row = {crate: crate, ty: rawRow[0], name: rawRow[1], | |
1679 | path: rawRow[2] || lastPath, desc: rawRow[3], | |
c34b1796 | 1680 | parent: paths[rawRow[4]], type: rawRow[5]}; |
1a4d82fc JJ |
1681 | searchIndex.push(row); |
1682 | if (typeof row.name === "string") { | |
1683 | var word = row.name.toLowerCase(); | |
1684 | searchWords.push(word); | |
1685 | } else { | |
1686 | searchWords.push(""); | |
1687 | } | |
1688 | lastPath = row.path; | |
1689 | } | |
1690 | } | |
1691 | return searchWords; | |
1692 | } | |
1693 | ||
1694 | function startSearch() { | |
b039eaaf | 1695 | var searchTimeout; |
7cac9316 | 1696 | var callback = function() { |
b039eaaf | 1697 | clearTimeout(searchTimeout); |
7cac9316 | 1698 | if (search_input.value.length === 0) { |
54a0048b | 1699 | if (browserSupportsHistoryApi()) { |
9fa01778 | 1700 | history.replaceState("", window.currentCrate + " - Rust", "?search="); |
54a0048b | 1701 | } |
0731742a XL |
1702 | if (hasClass(main, "content")) { |
1703 | removeClass(main, "hidden"); | |
7cac9316 | 1704 | } |
e1599b0c | 1705 | var search_c = getSearchElement(); |
0731742a XL |
1706 | if (hasClass(search_c, "content")) { |
1707 | addClass(search_c, "hidden"); | |
7cac9316 | 1708 | } |
b039eaaf SL |
1709 | } else { |
1710 | searchTimeout = setTimeout(search, 500); | |
1711 | } | |
7cac9316 | 1712 | }; |
7cac9316 XL |
1713 | search_input.onkeyup = callback; |
1714 | search_input.oninput = callback; | |
abe05a73 | 1715 | document.getElementsByClassName("search-form")[0].onsubmit = function(e) { |
b039eaaf SL |
1716 | e.preventDefault(); |
1717 | clearTimeout(searchTimeout); | |
1718 | search(); | |
7cac9316 XL |
1719 | }; |
1720 | search_input.onchange = function(e) { | |
b039eaaf SL |
1721 | // Do NOT e.preventDefault() here. It will prevent pasting. |
1722 | clearTimeout(searchTimeout); | |
1723 | // zero-timeout necessary here because at the time of event handler execution the | |
1724 | // pasted content is not in the input field yet. Shouldn’t make any difference for | |
1725 | // change, though. | |
1726 | setTimeout(search, 0); | |
7cac9316 XL |
1727 | }; |
1728 | search_input.onpaste = search_input.onchange; | |
1a4d82fc | 1729 | |
e1599b0c | 1730 | var selectCrate = document.getElementById("crate-search"); |
0731742a XL |
1731 | if (selectCrate) { |
1732 | selectCrate.onchange = function() { | |
e1599b0c | 1733 | updateLocalStorage("rustdoc-saved-filter-crate", selectCrate.value); |
0731742a XL |
1734 | search(undefined, true); |
1735 | }; | |
1736 | } | |
1737 | ||
1a4d82fc JJ |
1738 | // Push and pop states are used to add search results to the browser |
1739 | // history. | |
1740 | if (browserSupportsHistoryApi()) { | |
c1a9b12d | 1741 | // Store the previous <title> so we can revert back to it later. |
7cac9316 | 1742 | var previousTitle = document.title; |
c1a9b12d | 1743 | |
7cac9316 | 1744 | window.onpopstate = function(e) { |
1a4d82fc JJ |
1745 | var params = getQueryStringParams(); |
1746 | // When browsing back from search results the main page | |
1747 | // visibility must be reset. | |
1748 | if (!params.search) { | |
0731742a XL |
1749 | if (hasClass(main, "content")) { |
1750 | removeClass(main, "hidden"); | |
7cac9316 | 1751 | } |
e1599b0c | 1752 | var search_c = getSearchElement(); |
0731742a XL |
1753 | if (hasClass(search_c, "content")) { |
1754 | addClass(search_c, "hidden"); | |
7cac9316 | 1755 | } |
1a4d82fc | 1756 | } |
c1a9b12d SL |
1757 | // Revert to the previous title manually since the History |
1758 | // API ignores the title parameter. | |
7cac9316 | 1759 | document.title = previousTitle; |
1a4d82fc JJ |
1760 | // When browsing forward to search results the previous |
1761 | // search will be repeated, so the currentResults are | |
1762 | // cleared to ensure the search is successful. | |
1763 | currentResults = null; | |
1764 | // Synchronize search bar with query string state and | |
1765 | // perform the search. This will empty the bar if there's | |
1766 | // nothing there, which lets you really go back to a | |
1767 | // previous state with nothing in the bar. | |
7cac9316 | 1768 | if (params.search) { |
83c7162d | 1769 | search_input.value = params.search; |
7cac9316 | 1770 | } else { |
0731742a | 1771 | search_input.value = ""; |
7cac9316 | 1772 | } |
0731742a | 1773 | // Some browsers fire "onpopstate" for every page load |
1a4d82fc JJ |
1774 | // (Chrome), while others fire the event only when actually |
1775 | // popping a state (Firefox), which is why search() is | |
1776 | // called both here and at the end of the startSearch() | |
1777 | // function. | |
1778 | search(); | |
7cac9316 | 1779 | }; |
1a4d82fc JJ |
1780 | } |
1781 | search(); | |
1782 | } | |
1783 | ||
1784 | index = buildIndex(rawSearchIndex); | |
1785 | startSearch(); | |
1786 | ||
1787 | // Draw a convenient sidebar of known crates if we have a listing | |
0731742a XL |
1788 | if (rootPath === "../" || rootPath === "./") { |
1789 | var sidebar = document.getElementsByClassName("sidebar-elems")[0]; | |
0531ce1d | 1790 | if (sidebar) { |
0731742a XL |
1791 | var div = document.createElement("div"); |
1792 | div.className = "block crate"; | |
1793 | div.innerHTML = "<h3>Crates</h3>"; | |
1794 | var ul = document.createElement("ul"); | |
0531ce1d XL |
1795 | div.appendChild(ul); |
1796 | ||
1797 | var crates = []; | |
1798 | for (var crate in rawSearchIndex) { | |
1799 | if (!rawSearchIndex.hasOwnProperty(crate)) { | |
1800 | continue; | |
1801 | } | |
1802 | crates.push(crate); | |
abe05a73 | 1803 | } |
0531ce1d XL |
1804 | crates.sort(); |
1805 | for (var i = 0; i < crates.length; ++i) { | |
0731742a | 1806 | var klass = "crate"; |
83c7162d | 1807 | if (rootPath !== "./" && crates[i] === window.currentCrate) { |
0731742a | 1808 | klass += " current"; |
0531ce1d | 1809 | } |
0731742a XL |
1810 | var link = document.createElement("a"); |
1811 | link.href = rootPath + crates[i] + "/index.html"; | |
0531ce1d XL |
1812 | link.title = rawSearchIndex[crates[i]].doc; |
1813 | link.className = klass; | |
1814 | link.textContent = crates[i]; | |
1815 | ||
0731742a | 1816 | var li = document.createElement("li"); |
0531ce1d XL |
1817 | li.appendChild(link); |
1818 | ul.appendChild(li); | |
1a4d82fc | 1819 | } |
0531ce1d | 1820 | sidebar.appendChild(div); |
1a4d82fc | 1821 | } |
1a4d82fc JJ |
1822 | } |
1823 | } | |
1824 | ||
1825 | window.initSearch = initSearch; | |
1826 | ||
c34b1796 AL |
1827 | // delayed sidebar rendering. |
1828 | function initSidebarItems(items) { | |
0731742a | 1829 | var sidebar = document.getElementsByClassName("sidebar-elems")[0]; |
c34b1796 AL |
1830 | var current = window.sidebarCurrent; |
1831 | ||
1832 | function block(shortty, longty) { | |
1833 | var filtered = items[shortty]; | |
0731742a XL |
1834 | if (!filtered) { |
1835 | return; | |
1836 | } | |
c34b1796 | 1837 | |
0731742a XL |
1838 | var div = document.createElement("div"); |
1839 | div.className = "block " + shortty; | |
1840 | var h3 = document.createElement("h3"); | |
7cac9316 XL |
1841 | h3.textContent = longty; |
1842 | div.appendChild(h3); | |
0731742a | 1843 | var ul = document.createElement("ul"); |
c34b1796 | 1844 | |
0731742a XL |
1845 | var length = filtered.length; |
1846 | for (var i = 0; i < length; ++i) { | |
c34b1796 AL |
1847 | var item = filtered[i]; |
1848 | var name = item[0]; | |
1849 | var desc = item[1]; // can be null | |
1850 | ||
1851 | var klass = shortty; | |
62682a34 | 1852 | if (name === current.name && shortty === current.ty) { |
0731742a | 1853 | klass += " current"; |
c34b1796 AL |
1854 | } |
1855 | var path; | |
0731742a XL |
1856 | if (shortty === "mod") { |
1857 | path = name + "/index.html"; | |
c34b1796 | 1858 | } else { |
0731742a | 1859 | path = shortty + "." + name + ".html"; |
c34b1796 | 1860 | } |
0731742a | 1861 | var link = document.createElement("a"); |
7cac9316 XL |
1862 | link.href = current.relpath + path; |
1863 | link.title = desc; | |
1864 | link.className = klass; | |
1865 | link.textContent = name; | |
0731742a | 1866 | var li = document.createElement("li"); |
7cac9316 XL |
1867 | li.appendChild(link); |
1868 | ul.appendChild(li); | |
c34b1796 | 1869 | } |
7cac9316 | 1870 | div.appendChild(ul); |
2c00a5a8 XL |
1871 | if (sidebar) { |
1872 | sidebar.appendChild(div); | |
1873 | } | |
c34b1796 AL |
1874 | } |
1875 | ||
3157f602 | 1876 | block("primitive", "Primitive Types"); |
c34b1796 | 1877 | block("mod", "Modules"); |
3157f602 | 1878 | block("macro", "Macros"); |
c34b1796 AL |
1879 | block("struct", "Structs"); |
1880 | block("enum", "Enums"); | |
3b2f2976 | 1881 | block("union", "Unions"); |
3157f602 XL |
1882 | block("constant", "Constants"); |
1883 | block("static", "Statics"); | |
c34b1796 AL |
1884 | block("trait", "Traits"); |
1885 | block("fn", "Functions"); | |
3157f602 | 1886 | block("type", "Type Definitions"); |
abe05a73 | 1887 | block("foreigntype", "Foreign Types"); |
94b46f34 | 1888 | block("keyword", "Keywords"); |
9fa01778 | 1889 | block("traitalias", "Trait Aliases"); |
c34b1796 AL |
1890 | } |
1891 | ||
1892 | window.initSidebarItems = initSidebarItems; | |
1893 | ||
1a4d82fc | 1894 | window.register_implementors = function(imp) { |
0731742a XL |
1895 | var implementors = document.getElementById("implementors-list"); |
1896 | var synthetic_implementors = document.getElementById("synthetic-implementors-list"); | |
0531ce1d | 1897 | |
1a4d82fc | 1898 | var libs = Object.getOwnPropertyNames(imp); |
0731742a XL |
1899 | var llength = libs.length; |
1900 | for (var i = 0; i < llength; ++i) { | |
62682a34 | 1901 | if (libs[i] === currentCrate) { continue; } |
1a4d82fc | 1902 | var structs = imp[libs[i]]; |
0531ce1d | 1903 | |
0731742a | 1904 | var slength = structs.length; |
0531ce1d | 1905 | struct_loop: |
0731742a | 1906 | for (var j = 0; j < slength; ++j) { |
0531ce1d XL |
1907 | var struct = structs[j]; |
1908 | ||
1909 | var list = struct.synthetic ? synthetic_implementors : implementors; | |
1910 | ||
1911 | if (struct.synthetic) { | |
0731742a XL |
1912 | var stlength = struct.types.length; |
1913 | for (var k = 0; k < stlength; k++) { | |
0531ce1d XL |
1914 | if (window.inlined_types.has(struct.types[k])) { |
1915 | continue struct_loop; | |
1916 | } | |
1917 | window.inlined_types.add(struct.types[k]); | |
1918 | } | |
1919 | } | |
1920 | ||
0731742a | 1921 | var code = document.createElement("code"); |
0531ce1d | 1922 | code.innerHTML = struct.text; |
7cac9316 | 1923 | |
0731742a XL |
1924 | var x = code.getElementsByTagName("a"); |
1925 | var xlength = x.length; | |
1926 | for (var it = 0; it < xlength; it++) { | |
1927 | var href = x[it].getAttribute("href"); | |
1928 | if (href && href.indexOf("http") !== 0) { | |
1929 | x[it].setAttribute("href", rootPath + href); | |
1a4d82fc | 1930 | } |
7cac9316 | 1931 | } |
0731742a | 1932 | var display = document.createElement("h3"); |
b7449926 | 1933 | addClass(display, "impl"); |
0731742a XL |
1934 | display.innerHTML = "<span class=\"in-band\"><table class=\"table-display\">" + |
1935 | "<tbody><tr><td><code>" + code.outerHTML + "</code></td><td></td></tr>" + | |
1936 | "</tbody></table></span>"; | |
b7449926 | 1937 | list.appendChild(display); |
1a4d82fc JJ |
1938 | } |
1939 | } | |
1940 | }; | |
1941 | if (window.pending_implementors) { | |
1942 | window.register_implementors(window.pending_implementors); | |
1943 | } | |
1944 | ||
d9579d0f AL |
1945 | function labelForToggleButton(sectionIsCollapsed) { |
1946 | if (sectionIsCollapsed) { | |
1947 | // button will expand the section | |
1948 | return "+"; | |
d9579d0f | 1949 | } |
62682a34 SL |
1950 | // button will collapse the section |
1951 | // note that this text is also set in the HTML template in render.rs | |
0731742a | 1952 | return "\u2212"; // "\u2212" is "−" minus sign |
d9579d0f | 1953 | } |
1a4d82fc | 1954 | |
7cac9316 XL |
1955 | function onEveryMatchingChild(elem, className, func) { |
1956 | if (elem && className && func) { | |
0731742a XL |
1957 | var length = elem.childNodes.length; |
1958 | var nodes = elem.childNodes; | |
1959 | for (var i = 0; i < length; ++i) { | |
1960 | if (hasClass(nodes[i], className)) { | |
1961 | func(nodes[i]); | |
7cac9316 | 1962 | } else { |
0731742a | 1963 | onEveryMatchingChild(nodes[i], className, func); |
7cac9316 XL |
1964 | } |
1965 | } | |
1966 | } | |
1967 | } | |
1968 | ||
94b46f34 | 1969 | function toggleAllDocs(pageId, fromAutoCollapse) { |
0731742a XL |
1970 | var innerToggle = document.getElementById("toggle-all-docs"); |
1971 | if (!innerToggle) { | |
83c7162d XL |
1972 | return; |
1973 | } | |
0731742a | 1974 | if (hasClass(innerToggle, "will-expand")) { |
0531ce1d | 1975 | updateLocalStorage("rustdoc-collapse", "false"); |
0731742a XL |
1976 | removeClass(innerToggle, "will-expand"); |
1977 | onEveryMatchingChild(innerToggle, "inner", function(e) { | |
7cac9316 XL |
1978 | e.innerHTML = labelForToggleButton(false); |
1979 | }); | |
0731742a | 1980 | innerToggle.title = "collapse all docs"; |
94b46f34 | 1981 | if (fromAutoCollapse !== true) { |
0731742a | 1982 | onEachLazy(document.getElementsByClassName("collapse-toggle"), function(e) { |
94b46f34 XL |
1983 | collapseDocs(e, "show"); |
1984 | }); | |
1985 | } | |
d9579d0f | 1986 | } else { |
0531ce1d | 1987 | updateLocalStorage("rustdoc-collapse", "true"); |
0731742a XL |
1988 | addClass(innerToggle, "will-expand"); |
1989 | onEveryMatchingChild(innerToggle, "inner", function(e) { | |
9fa01778 XL |
1990 | var parent = e.parentNode; |
1991 | var superParent = null; | |
1992 | ||
1993 | if (parent) { | |
1994 | superParent = parent.parentNode; | |
1995 | } | |
1996 | if (!parent || !superParent || superParent.id !== "main" || | |
1997 | hasClass(parent, "impl") === false) { | |
1998 | e.innerHTML = labelForToggleButton(true); | |
1999 | } | |
7cac9316 | 2000 | }); |
0731742a | 2001 | innerToggle.title = "expand all docs"; |
94b46f34 | 2002 | if (fromAutoCollapse !== true) { |
0731742a | 2003 | onEachLazy(document.getElementsByClassName("collapse-toggle"), function(e) { |
9fa01778 XL |
2004 | var parent = e.parentNode; |
2005 | var superParent = null; | |
2006 | ||
2007 | if (parent) { | |
2008 | superParent = parent.parentNode; | |
2009 | } | |
2010 | if (!parent || !superParent || superParent.id !== "main" || | |
2011 | hasClass(parent, "impl") === false) { | |
2012 | collapseDocs(e, "hide", pageId); | |
2013 | } | |
94b46f34 XL |
2014 | }); |
2015 | } | |
d9579d0f | 2016 | } |
a7813a04 XL |
2017 | } |
2018 | ||
83c7162d | 2019 | function collapseDocs(toggle, mode, pageId) { |
7cac9316 XL |
2020 | if (!toggle || !toggle.parentNode) { |
2021 | return; | |
d9579d0f | 2022 | } |
0531ce1d XL |
2023 | |
2024 | function adjustToggle(arg) { | |
2025 | return function(e) { | |
0731742a | 2026 | if (hasClass(e, "toggle-label")) { |
0531ce1d | 2027 | if (arg) { |
0731742a | 2028 | e.style.display = "inline-block"; |
0531ce1d | 2029 | } else { |
0731742a | 2030 | e.style.display = "none"; |
7cac9316 | 2031 | } |
0531ce1d | 2032 | } |
0731742a | 2033 | if (hasClass(e, "inner")) { |
0531ce1d XL |
2034 | e.innerHTML = labelForToggleButton(arg); |
2035 | } | |
2036 | }; | |
0731742a XL |
2037 | } |
2038 | ||
9fa01778 | 2039 | function implHider(addOrRemove, fullHide) { |
0731742a | 2040 | return function(n) { |
9fa01778 | 2041 | var is_method = hasClass(n, "method") || fullHide; |
0731742a XL |
2042 | if (is_method || hasClass(n, "type")) { |
2043 | if (is_method === true) { | |
2044 | if (addOrRemove) { | |
2045 | addClass(n, "hidden-by-impl-hider"); | |
2046 | } else { | |
2047 | removeClass(n, "hidden-by-impl-hider"); | |
2048 | } | |
2049 | } | |
2050 | var ns = n.nextElementSibling; | |
2051 | while (true) { | |
2052 | if (ns && ( | |
2053 | hasClass(ns, "docblock") || | |
2054 | hasClass(ns, "stability"))) { | |
2055 | if (addOrRemove) { | |
2056 | addClass(ns, "hidden-by-impl-hider"); | |
2057 | } else { | |
2058 | removeClass(ns, "hidden-by-impl-hider"); | |
2059 | } | |
2060 | ns = ns.nextElementSibling; | |
2061 | continue; | |
2062 | } | |
2063 | break; | |
2064 | } | |
2065 | } | |
2066 | }; | |
2067 | } | |
0531ce1d | 2068 | |
0731742a XL |
2069 | var relatedDoc; |
2070 | var action = mode; | |
2071 | if (hasClass(toggle.parentNode, "impl") === false) { | |
2072 | relatedDoc = toggle.parentNode.nextElementSibling; | |
0531ce1d XL |
2073 | if (hasClass(relatedDoc, "stability")) { |
2074 | relatedDoc = relatedDoc.nextElementSibling; | |
2075 | } | |
a1dfa0c6 | 2076 | if (hasClass(relatedDoc, "docblock") || hasClass(relatedDoc, "sub-variant")) { |
0731742a | 2077 | if (mode === "toggle") { |
0531ce1d XL |
2078 | if (hasClass(relatedDoc, "hidden-by-usual-hider")) { |
2079 | action = "show"; | |
2080 | } else { | |
2081 | action = "hide"; | |
7cac9316 | 2082 | } |
0531ce1d XL |
2083 | } |
2084 | if (action === "hide") { | |
2085 | addClass(relatedDoc, "hidden-by-usual-hider"); | |
0731742a XL |
2086 | onEachLazy(toggle.childNodes, adjustToggle(true)); |
2087 | addClass(toggle.parentNode, "collapsed"); | |
0531ce1d XL |
2088 | } else if (action === "show") { |
2089 | removeClass(relatedDoc, "hidden-by-usual-hider"); | |
0731742a XL |
2090 | removeClass(toggle.parentNode, "collapsed"); |
2091 | onEachLazy(toggle.childNodes, adjustToggle(false)); | |
0531ce1d XL |
2092 | } |
2093 | } | |
2094 | } else { | |
9fa01778 | 2095 | // we are collapsing the impl block(s). |
0531ce1d | 2096 | |
83c7162d | 2097 | var parentElem = toggle.parentNode; |
0731742a | 2098 | relatedDoc = parentElem; |
0531ce1d XL |
2099 | var docblock = relatedDoc.nextElementSibling; |
2100 | ||
0731742a | 2101 | while (hasClass(relatedDoc, "impl-items") === false) { |
0531ce1d XL |
2102 | relatedDoc = relatedDoc.nextElementSibling; |
2103 | } | |
2104 | ||
0731742a XL |
2105 | if ((!relatedDoc && hasClass(docblock, "docblock") === false) || |
2106 | (pageId && document.getElementById(pageId))) { | |
0531ce1d XL |
2107 | return; |
2108 | } | |
2109 | ||
9fa01778 | 2110 | // Hide all functions, but not associated types/consts. |
0531ce1d | 2111 | |
0731742a | 2112 | if (mode === "toggle") { |
0531ce1d | 2113 | if (hasClass(relatedDoc, "fns-now-collapsed") || |
0731742a | 2114 | hasClass(docblock, "hidden-by-impl-hider")) { |
0531ce1d XL |
2115 | action = "show"; |
2116 | } else { | |
2117 | action = "hide"; | |
2118 | } | |
2119 | } | |
2120 | ||
9fa01778 | 2121 | var dontApplyBlockRule = toggle.parentNode.parentNode.id !== "main"; |
0531ce1d XL |
2122 | if (action === "show") { |
2123 | removeClass(relatedDoc, "fns-now-collapsed"); | |
2124 | removeClass(docblock, "hidden-by-usual-hider"); | |
9fa01778 XL |
2125 | onEachLazy(toggle.childNodes, adjustToggle(false, dontApplyBlockRule)); |
2126 | onEachLazy(relatedDoc.childNodes, implHider(false, dontApplyBlockRule)); | |
0531ce1d XL |
2127 | } else if (action === "hide") { |
2128 | addClass(relatedDoc, "fns-now-collapsed"); | |
2129 | addClass(docblock, "hidden-by-usual-hider"); | |
9fa01778 XL |
2130 | onEachLazy(toggle.childNodes, adjustToggle(true, dontApplyBlockRule)); |
2131 | onEachLazy(relatedDoc.childNodes, implHider(true, dontApplyBlockRule)); | |
0731742a XL |
2132 | } |
2133 | } | |
2134 | } | |
2135 | ||
2136 | function collapser(e, collapse) { | |
2137 | // inherent impl ids are like "impl" or impl-<number>'. | |
2138 | // they will never be hidden by default. | |
2139 | var n = e.parentElement; | |
2140 | if (n.id.match(/^impl(?:-\d+)?$/) === null) { | |
2141 | // Automatically minimize all non-inherent impls | |
2142 | if (collapse || hasClass(n, "impl")) { | |
2143 | collapseDocs(e, "hide", pageId); | |
0531ce1d XL |
2144 | } |
2145 | } | |
2146 | } | |
2147 | ||
94b46f34 XL |
2148 | function autoCollapse(pageId, collapse) { |
2149 | if (collapse) { | |
2150 | toggleAllDocs(pageId, true); | |
60c5eb7d | 2151 | } else if (getCurrentValue("rustdoc-auto-hide-trait-implementations") !== "false") { |
0731742a | 2152 | var impl_list = document.getElementById("implementations-list"); |
0bf4aa26 XL |
2153 | |
2154 | if (impl_list !== null) { | |
0731742a XL |
2155 | onEachLazy(impl_list.getElementsByClassName("collapse-toggle"), function(e) { |
2156 | collapser(e, collapse); | |
b7449926 XL |
2157 | }); |
2158 | } | |
532ac7d7 XL |
2159 | |
2160 | var blanket_list = document.getElementById("blanket-implementations-list"); | |
2161 | ||
2162 | if (blanket_list !== null) { | |
2163 | onEachLazy(blanket_list.getElementsByClassName("collapse-toggle"), function(e) { | |
2164 | collapser(e, collapse); | |
2165 | }); | |
2166 | } | |
8faf50e0 | 2167 | } |
476ff2be SL |
2168 | } |
2169 | ||
0731742a XL |
2170 | var toggles = document.getElementById("toggle-all-docs"); |
2171 | if (toggles) { | |
2172 | toggles.onclick = toggleAllDocs; | |
7cac9316 | 2173 | } |
476ff2be | 2174 | |
7cac9316 XL |
2175 | function insertAfter(newNode, referenceNode) { |
2176 | referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); | |
2177 | } | |
1a4d82fc | 2178 | |
0731742a XL |
2179 | function createSimpleToggle(sectionIsCollapsed) { |
2180 | var toggle = document.createElement("a"); | |
2181 | toggle.href = "javascript:void(0)"; | |
2182 | toggle.className = "collapse-toggle"; | |
2183 | toggle.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(sectionIsCollapsed) + | |
2184 | "</span>]"; | |
2185 | return toggle; | |
0531ce1d XL |
2186 | } |
2187 | ||
0731742a | 2188 | var toggle = createSimpleToggle(false); |
60c5eb7d | 2189 | var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true"; |
532ac7d7 | 2190 | var pageId = getPageId(); |
1a4d82fc | 2191 | |
7cac9316 XL |
2192 | var func = function(e) { |
2193 | var next = e.nextElementSibling; | |
0731742a XL |
2194 | if (!next) { |
2195 | return; | |
2196 | } | |
532ac7d7 XL |
2197 | if (hasClass(next, "docblock") === true || |
2198 | (hasClass(next, "stability") === true && | |
2199 | hasClass(next.nextElementSibling, "docblock") === true)) { | |
2200 | var newToggle = toggle.cloneNode(true); | |
2201 | insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]); | |
2202 | if (hideMethodDocs === true && hasClass(e, "method") === true) { | |
2203 | collapseDocs(newToggle, "hide", pageId); | |
2204 | } | |
0731742a XL |
2205 | } |
2206 | }; | |
2207 | ||
2208 | var funcImpl = function(e) { | |
2209 | var next = e.nextElementSibling; | |
2210 | if (next && hasClass(next, "docblock")) { | |
0531ce1d XL |
2211 | next = next.nextElementSibling; |
2212 | } | |
7cac9316 XL |
2213 | if (!next) { |
2214 | return; | |
2215 | } | |
0731742a | 2216 | if (next.getElementsByClassName("method").length > 0 && hasClass(e, "impl")) { |
7cac9316 XL |
2217 | insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]); |
2218 | } | |
94b46f34 | 2219 | }; |
0731742a XL |
2220 | |
2221 | onEachLazy(document.getElementsByClassName("method"), func); | |
2222 | onEachLazy(document.getElementsByClassName("associatedconstant"), func); | |
2223 | onEachLazy(document.getElementsByClassName("impl"), funcImpl); | |
2224 | var impl_call = function() {}; | |
532ac7d7 | 2225 | if (hideMethodDocs === true) { |
0731742a XL |
2226 | impl_call = function(e, newToggle, pageId) { |
2227 | if (e.id.match(/^impl(?:-\d+)?$/) === null) { | |
2228 | // Automatically minimize all non-inherent impls | |
532ac7d7 | 2229 | if (hasClass(e, "impl") === true) { |
0731742a XL |
2230 | collapseDocs(newToggle, "hide", pageId); |
2231 | } | |
2232 | } | |
2233 | }; | |
2234 | } | |
0731742a XL |
2235 | var newToggle = document.createElement("a"); |
2236 | newToggle.href = "javascript:void(0)"; | |
2237 | newToggle.className = "collapse-toggle hidden-default collapsed"; | |
2238 | newToggle.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) + | |
2239 | "</span>] Show hidden undocumented items"; | |
2240 | function toggleClicked() { | |
2241 | if (hasClass(this, "collapsed")) { | |
2242 | removeClass(this, "collapsed"); | |
2243 | onEachLazy(this.parentNode.getElementsByClassName("hidden"), function(x) { | |
2244 | if (hasClass(x, "content") === false) { | |
2245 | removeClass(x, "hidden"); | |
2246 | addClass(x, "x"); | |
2247 | } | |
2248 | }, true); | |
2249 | this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(false) + | |
2250 | "</span>] Hide undocumented items"; | |
2251 | } else { | |
2252 | addClass(this, "collapsed"); | |
2253 | onEachLazy(this.parentNode.getElementsByClassName("x"), function(x) { | |
2254 | if (hasClass(x, "content") === false) { | |
2255 | addClass(x, "hidden"); | |
2256 | removeClass(x, "x"); | |
2257 | } | |
2258 | }, true); | |
2259 | this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) + | |
2260 | "</span>] Show hidden undocumented items"; | |
2261 | } | |
2262 | } | |
2263 | onEachLazy(document.getElementsByClassName("impl-items"), function(e) { | |
2264 | onEachLazy(e.getElementsByClassName("associatedconstant"), func); | |
2265 | var hiddenElems = e.getElementsByClassName("hidden"); | |
a1dfa0c6 XL |
2266 | var needToggle = false; |
2267 | ||
0731742a XL |
2268 | var hlength = hiddenElems.length; |
2269 | for (var i = 0; i < hlength; ++i) { | |
a1dfa0c6 XL |
2270 | if (hasClass(hiddenElems[i], "content") === false && |
2271 | hasClass(hiddenElems[i], "docblock") === false) { | |
2272 | needToggle = true; | |
2273 | break; | |
2274 | } | |
2275 | } | |
2276 | if (needToggle === true) { | |
0731742a XL |
2277 | var inner_toggle = newToggle.cloneNode(true); |
2278 | inner_toggle.onclick = toggleClicked; | |
2279 | e.insertBefore(inner_toggle, e.firstChild); | |
532ac7d7 | 2280 | impl_call(e.previousSibling, inner_toggle, pageId); |
a1dfa0c6 XL |
2281 | } |
2282 | }); | |
1a4d82fc | 2283 | |
b7449926 | 2284 | function createToggle(otherMessage, fontSize, extraClass, show) { |
0731742a XL |
2285 | var span = document.createElement("span"); |
2286 | span.className = "toggle-label"; | |
b7449926 | 2287 | if (show) { |
0731742a | 2288 | span.style.display = "none"; |
b7449926 | 2289 | } |
0531ce1d | 2290 | if (!otherMessage) { |
0731742a | 2291 | span.innerHTML = " Expand description"; |
0531ce1d XL |
2292 | } else { |
2293 | span.innerHTML = otherMessage; | |
8faf50e0 XL |
2294 | } |
2295 | ||
2296 | if (fontSize) { | |
2297 | span.style.fontSize = fontSize; | |
0531ce1d | 2298 | } |
476ff2be | 2299 | |
041b39d2 XL |
2300 | var mainToggle = toggle.cloneNode(true); |
2301 | mainToggle.appendChild(span); | |
1a4d82fc | 2302 | |
0731742a XL |
2303 | var wrapper = document.createElement("div"); |
2304 | wrapper.className = "toggle-wrapper"; | |
b7449926 | 2305 | if (!show) { |
0731742a XL |
2306 | addClass(wrapper, "collapsed"); |
2307 | var inner = mainToggle.getElementsByClassName("inner"); | |
b7449926 | 2308 | if (inner && inner.length > 0) { |
0731742a | 2309 | inner[0].innerHTML = "+"; |
b7449926 XL |
2310 | } |
2311 | } | |
94b46f34 | 2312 | if (extraClass) { |
b7449926 | 2313 | addClass(wrapper, extraClass); |
94b46f34 | 2314 | } |
041b39d2 XL |
2315 | wrapper.appendChild(mainToggle); |
2316 | return wrapper; | |
2317 | } | |
1a4d82fc | 2318 | |
60c5eb7d XL |
2319 | var currentType = document.getElementsByClassName("type-decl")[0]; |
2320 | var className = null; | |
2321 | if (currentType) { | |
2322 | currentType = currentType.getElementsByClassName("rust")[0]; | |
2323 | if (currentType) { | |
2324 | currentType.classList.forEach(function(item) { | |
2325 | if (item !== "main") { | |
2326 | className = item; | |
2327 | return true; | |
2328 | } | |
2329 | }); | |
2330 | } | |
2331 | } | |
2332 | var showItemDeclarations = getCurrentValue("rustdoc-auto-hide-" + className); | |
2333 | if (showItemDeclarations === null) { | |
2334 | if (className === "enum" || className === "macro") { | |
2335 | showItemDeclarations = "false"; | |
2336 | } else if (className === "struct" || className === "union" || className === "trait") { | |
2337 | showItemDeclarations = "true"; | |
2338 | } else { | |
2339 | // In case we found an unknown type, we just use the "parent" value. | |
2340 | showItemDeclarations = getCurrentValue("rustdoc-auto-hide-declarations"); | |
2341 | } | |
2342 | } | |
2343 | showItemDeclarations = showItemDeclarations === "false"; | |
a1dfa0c6 | 2344 | function buildToggleWrapper(e) { |
0731742a | 2345 | if (hasClass(e, "autohide")) { |
7cac9316 | 2346 | var wrap = e.previousElementSibling; |
0731742a XL |
2347 | if (wrap && hasClass(wrap, "toggle-wrapper")) { |
2348 | var inner_toggle = wrap.childNodes[0]; | |
2349 | var extra = e.childNodes[0].tagName === "H3"; | |
a1dfa0c6 | 2350 | |
0731742a XL |
2351 | e.style.display = "none"; |
2352 | addClass(wrap, "collapsed"); | |
2353 | onEachLazy(inner_toggle.getElementsByClassName("inner"), function(e) { | |
7cac9316 XL |
2354 | e.innerHTML = labelForToggleButton(true); |
2355 | }); | |
0731742a XL |
2356 | onEachLazy(inner_toggle.getElementsByClassName("toggle-label"), function(e) { |
2357 | e.style.display = "inline-block"; | |
83c7162d XL |
2358 | if (extra === true) { |
2359 | i_e.innerHTML = " Show " + e.childNodes[0].innerHTML; | |
2360 | } | |
7cac9316 | 2361 | }); |
1a4d82fc | 2362 | } |
7cac9316 | 2363 | } |
83c7162d | 2364 | if (e.parentNode.id === "main") { |
0731742a | 2365 | var otherMessage = ""; |
8faf50e0 | 2366 | var fontSize; |
94b46f34 | 2367 | var extraClass; |
8faf50e0 | 2368 | |
83c7162d | 2369 | if (hasClass(e, "type-decl")) { |
8faf50e0 | 2370 | fontSize = "20px"; |
0731742a | 2371 | otherMessage = " Show declaration"; |
a1dfa0c6 | 2372 | if (showItemDeclarations === false) { |
0731742a | 2373 | extraClass = "collapsed"; |
b7449926 | 2374 | } |
a1dfa0c6 | 2375 | } else if (hasClass(e, "sub-variant")) { |
0731742a | 2376 | otherMessage = " Show fields"; |
8faf50e0 | 2377 | } else if (hasClass(e, "non-exhaustive")) { |
0731742a | 2378 | otherMessage = " This "; |
8faf50e0 | 2379 | if (hasClass(e, "non-exhaustive-struct")) { |
0731742a | 2380 | otherMessage += "struct"; |
8faf50e0 | 2381 | } else if (hasClass(e, "non-exhaustive-enum")) { |
0731742a | 2382 | otherMessage += "enum"; |
532ac7d7 XL |
2383 | } else if (hasClass(e, "non-exhaustive-variant")) { |
2384 | otherMessage += "enum variant"; | |
8faf50e0 | 2385 | } else if (hasClass(e, "non-exhaustive-type")) { |
0731742a | 2386 | otherMessage += "type"; |
8faf50e0 | 2387 | } |
0731742a | 2388 | otherMessage += " is marked as non-exhaustive"; |
94b46f34 XL |
2389 | } else if (hasClass(e.childNodes[0], "impl-items")) { |
2390 | extraClass = "marg-left"; | |
83c7162d | 2391 | } |
8faf50e0 | 2392 | |
a1dfa0c6 XL |
2393 | e.parentNode.insertBefore( |
2394 | createToggle(otherMessage, | |
2395 | fontSize, | |
2396 | extraClass, | |
2397 | hasClass(e, "type-decl") === false || showItemDeclarations === true), | |
2398 | e); | |
2399 | if (hasClass(e, "type-decl") === true && showItemDeclarations === true) { | |
83c7162d XL |
2400 | collapseDocs(e.previousSibling.childNodes[0], "toggle"); |
2401 | } | |
532ac7d7 XL |
2402 | if (hasClass(e, "non-exhaustive") === true) { |
2403 | collapseDocs(e.previousSibling.childNodes[0], "toggle"); | |
2404 | } | |
83c7162d | 2405 | } |
a1dfa0c6 XL |
2406 | } |
2407 | ||
0731742a XL |
2408 | onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper); |
2409 | onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper); | |
7cac9316 | 2410 | |
0731742a XL |
2411 | function createToggleWrapper(tog) { |
2412 | var span = document.createElement("span"); | |
2413 | span.className = "toggle-label"; | |
2414 | span.style.display = "none"; | |
2415 | span.innerHTML = " Expand attributes"; | |
2416 | tog.appendChild(span); | |
2417 | ||
2418 | var wrapper = document.createElement("div"); | |
2419 | wrapper.className = "toggle-wrapper toggle-attributes"; | |
2420 | wrapper.appendChild(tog); | |
2421 | return wrapper; | |
2422 | } | |
2423 | ||
a1dfa0c6 XL |
2424 | // To avoid checking on "rustdoc-item-attributes" value on every loop... |
2425 | var itemAttributesFunc = function() {}; | |
60c5eb7d | 2426 | if (getCurrentValue("rustdoc-auto-hide-attributes") !== "false") { |
a1dfa0c6 XL |
2427 | itemAttributesFunc = function(x) { |
2428 | collapseDocs(x.previousSibling.childNodes[0], "toggle"); | |
2429 | }; | |
2430 | } | |
0731742a XL |
2431 | var attributesToggle = createToggleWrapper(createSimpleToggle(false)); |
2432 | onEachLazy(main.getElementsByClassName("attributes"), function(i_e) { | |
48663c56 XL |
2433 | var attr_tog = attributesToggle.cloneNode(true); |
2434 | if (hasClass(i_e, "top-attr") === true) { | |
2435 | addClass(attr_tog, "top-attr"); | |
2436 | } | |
2437 | i_e.parentNode.insertBefore(attr_tog, i_e); | |
a1dfa0c6 | 2438 | itemAttributesFunc(i_e); |
7cac9316 | 2439 | }); |
ea8adc8c | 2440 | |
a1dfa0c6 XL |
2441 | // To avoid checking on "rustdoc-line-numbers" value on every loop... |
2442 | var lineNumbersFunc = function() {}; | |
2443 | if (getCurrentValue("rustdoc-line-numbers") === "true") { | |
2444 | lineNumbersFunc = function(x) { | |
0731742a | 2445 | var count = x.textContent.split("\n").length; |
a1dfa0c6 XL |
2446 | var elems = []; |
2447 | for (var i = 0; i < count; ++i) { | |
2448 | elems.push(i + 1); | |
2449 | } | |
0731742a XL |
2450 | var node = document.createElement("pre"); |
2451 | addClass(node, "line-number"); | |
2452 | node.innerHTML = elems.join("\n"); | |
a1dfa0c6 XL |
2453 | x.parentNode.insertBefore(node, x); |
2454 | }; | |
2455 | } | |
0731742a XL |
2456 | onEachLazy(document.getElementsByClassName("rust-example-rendered"), function(e) { |
2457 | if (hasClass(e, "compile_fail")) { | |
ea8adc8c | 2458 | e.addEventListener("mouseover", function(event) { |
0731742a | 2459 | this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00"; |
ea8adc8c XL |
2460 | }); |
2461 | e.addEventListener("mouseout", function(event) { | |
0731742a | 2462 | this.parentElement.previousElementSibling.childNodes[0].style.color = ""; |
ea8adc8c | 2463 | }); |
0731742a | 2464 | } else if (hasClass(e, "ignore")) { |
ea8adc8c | 2465 | e.addEventListener("mouseover", function(event) { |
0731742a | 2466 | this.parentElement.previousElementSibling.childNodes[0].style.color = "#ff9200"; |
ea8adc8c XL |
2467 | }); |
2468 | e.addEventListener("mouseout", function(event) { | |
0731742a | 2469 | this.parentElement.previousElementSibling.childNodes[0].style.color = ""; |
ea8adc8c XL |
2470 | }); |
2471 | } | |
a1dfa0c6 | 2472 | lineNumbersFunc(e); |
ea8adc8c | 2473 | }); |
abe05a73 | 2474 | |
ff7c6d11 | 2475 | function showModal(content) { |
0731742a | 2476 | var modal = document.createElement("div"); |
ff7c6d11 | 2477 | modal.id = "important"; |
0731742a XL |
2478 | addClass(modal, "modal"); |
2479 | modal.innerHTML = "<div class=\"modal-content\"><div class=\"close\" id=\"modal-close\">✕" + | |
2480 | "</div><div class=\"whiter\"></div><span class=\"docblock\">" + content + | |
2481 | "</span></div>"; | |
2482 | document.getElementsByTagName("body")[0].appendChild(modal); | |
2483 | document.getElementById("modal-close").onclick = hideModal; | |
ff7c6d11 XL |
2484 | modal.onclick = hideModal; |
2485 | } | |
2486 | ||
2487 | function hideModal() { | |
2488 | var modal = document.getElementById("important"); | |
2489 | if (modal) { | |
2490 | modal.parentNode.removeChild(modal); | |
2491 | } | |
2492 | } | |
2493 | ||
0731742a | 2494 | onEachLazy(document.getElementsByClassName("important-traits"), function(e) { |
ff7c6d11 XL |
2495 | e.onclick = function() { |
2496 | showModal(e.lastElementChild.innerHTML); | |
2497 | }; | |
2498 | }); | |
2499 | ||
532ac7d7 XL |
2500 | // In the search display, allows to switch between tabs. |
2501 | function printTab(nb) { | |
2502 | if (nb === 0 || nb === 1 || nb === 2) { | |
2503 | currentTab = nb; | |
2504 | } | |
2505 | var nb_copy = nb; | |
2506 | onEachLazy(document.getElementById("titles").childNodes, function(elem) { | |
2507 | if (nb_copy === 0) { | |
2508 | addClass(elem, "selected"); | |
2509 | } else { | |
2510 | removeClass(elem, "selected"); | |
2511 | } | |
2512 | nb_copy -= 1; | |
2513 | }); | |
2514 | onEachLazy(document.getElementById("results").childNodes, function(elem) { | |
2515 | if (nb === 0) { | |
2516 | elem.style.display = ""; | |
2517 | } else { | |
2518 | elem.style.display = "none"; | |
2519 | } | |
2520 | nb -= 1; | |
2521 | }); | |
2522 | } | |
2523 | ||
83c7162d XL |
2524 | function putBackSearch(search_input) { |
2525 | if (search_input.value !== "") { | |
0731742a | 2526 | addClass(main, "hidden"); |
e74abb32 | 2527 | removeClass(getSearchElement(), "hidden"); |
83c7162d XL |
2528 | if (browserSupportsHistoryApi()) { |
2529 | history.replaceState(search_input.value, | |
2530 | "", | |
2531 | "?search=" + encodeURIComponent(search_input.value)); | |
2532 | } | |
2533 | } | |
2534 | } | |
abe05a73 XL |
2535 | |
2536 | if (search_input) { | |
2537 | search_input.onfocus = function() { | |
83c7162d | 2538 | putBackSearch(this); |
abe05a73 XL |
2539 | }; |
2540 | } | |
ff7c6d11 XL |
2541 | |
2542 | var params = getQueryStringParams(); | |
2543 | if (params && params.search) { | |
0731742a | 2544 | addClass(main, "hidden"); |
e1599b0c | 2545 | var search = getSearchElement(); |
ff7c6d11 | 2546 | removeClass(search, "hidden"); |
0731742a | 2547 | search.innerHTML = "<h3 style=\"text-align: center;\">Loading search results...</h3>"; |
ff7c6d11 XL |
2548 | } |
2549 | ||
2550 | var sidebar_menu = document.getElementsByClassName("sidebar-menu")[0]; | |
2551 | if (sidebar_menu) { | |
2552 | sidebar_menu.onclick = function() { | |
0731742a | 2553 | var sidebar = document.getElementsByClassName("sidebar")[0]; |
ff7c6d11 XL |
2554 | if (hasClass(sidebar, "mobile") === true) { |
2555 | hideSidebar(); | |
2556 | } else { | |
2557 | showSidebar(); | |
2558 | } | |
2559 | }; | |
2560 | } | |
2561 | ||
2562 | window.onresize = function() { | |
2563 | hideSidebar(); | |
2564 | }; | |
0531ce1d | 2565 | |
94b46f34 | 2566 | autoCollapse(getPageId(), getCurrentValue("rustdoc-collapse") === "true"); |
b7449926 XL |
2567 | |
2568 | if (window.location.hash && window.location.hash.length > 0) { | |
0731742a | 2569 | expandSection(window.location.hash.replace(/^#/, "")); |
b7449926 | 2570 | } |
0731742a XL |
2571 | |
2572 | if (main) { | |
2573 | onEachLazy(main.getElementsByClassName("loading-content"), function(e) { | |
2574 | e.remove(); | |
2575 | }); | |
2576 | onEachLazy(main.childNodes, function(e) { | |
2577 | // Unhide the actual content once loading is complete. Headers get | |
2578 | // flex treatment for their horizontal layout, divs get block treatment | |
2579 | // for vertical layout (column-oriented flex layout for divs caused | |
2580 | // errors in mobile browsers). | |
2581 | if (e.tagName === "H2" || e.tagName === "H3") { | |
9fa01778 | 2582 | var nextTagName = e.nextElementSibling.tagName; |
0731742a XL |
2583 | if (nextTagName == "H2" || nextTagName == "H3") { |
2584 | e.nextElementSibling.style.display = "flex"; | |
2585 | } else { | |
2586 | e.nextElementSibling.style.display = "block"; | |
2587 | } | |
2588 | } | |
2589 | }); | |
2590 | } | |
2591 | ||
2592 | function addSearchOptions(crates) { | |
e1599b0c | 2593 | var elem = document.getElementById("crate-search"); |
0731742a XL |
2594 | |
2595 | if (!elem) { | |
2596 | return; | |
2597 | } | |
2598 | var crates_text = []; | |
2599 | if (Object.keys(crates).length > 1) { | |
2600 | for (var crate in crates) { | |
2601 | if (crates.hasOwnProperty(crate)) { | |
2602 | crates_text.push(crate); | |
2603 | } | |
2604 | } | |
2605 | } | |
2606 | crates_text.sort(function(a, b) { | |
2607 | var lower_a = a.toLowerCase(); | |
2608 | var lower_b = b.toLowerCase(); | |
2609 | ||
2610 | if (lower_a < lower_b) { | |
2611 | return -1; | |
2612 | } else if (lower_a > lower_b) { | |
2613 | return 1; | |
2614 | } | |
2615 | return 0; | |
2616 | }); | |
60c5eb7d | 2617 | var savedCrate = getCurrentValue("rustdoc-saved-filter-crate"); |
0731742a XL |
2618 | for (var i = 0; i < crates_text.length; ++i) { |
2619 | var option = document.createElement("option"); | |
2620 | option.value = crates_text[i]; | |
2621 | option.innerText = crates_text[i]; | |
2622 | elem.appendChild(option); | |
60c5eb7d XL |
2623 | // Set the crate filter from saved storage, if the current page has the saved crate |
2624 | // filter. | |
2625 | // | |
2626 | // If not, ignore the crate filter -- we want to support filtering for crates on sites | |
2627 | // like doc.rust-lang.org where the crates may differ from page to page while on the | |
2628 | // same domain. | |
2629 | if (crates_text[i] === savedCrate) { | |
2630 | elem.value = savedCrate; | |
2631 | } | |
0731742a | 2632 | } |
60c5eb7d XL |
2633 | |
2634 | if (search_input) { | |
2635 | search_input.removeAttribute('disabled'); | |
2636 | }; | |
0731742a XL |
2637 | } |
2638 | ||
2639 | window.addSearchOptions = addSearchOptions; | |
e74abb32 XL |
2640 | |
2641 | function buildHelperPopup() { | |
2642 | var popup = document.createElement("aside"); | |
2643 | addClass(popup, "hidden"); | |
2644 | popup.id = "help"; | |
2645 | ||
2646 | var container = document.createElement("div"); | |
2647 | var shortcuts = [ | |
2648 | ["?", "Show this help dialog"], | |
2649 | ["S", "Focus the search field"], | |
2650 | ["↑", "Move up in search results"], | |
2651 | ["↓", "Move down in search results"], | |
2652 | ["↹", "Switch tab"], | |
2653 | ["⏎", "Go to active search result"], | |
2654 | ["+", "Expand all sections"], | |
2655 | ["-", "Collapse all sections"], | |
2656 | ].map(x => "<dt><kbd>" + x[0] + "</kbd></dt><dd>" + x[1] + "</dd>").join(""); | |
2657 | var div_shortcuts = document.createElement("div"); | |
2658 | addClass(div_shortcuts, "shortcuts"); | |
2659 | div_shortcuts.innerHTML = "<h2>Keyboard Shortcuts</h2><dl>" + shortcuts + "</dl></div>"; | |
2660 | ||
2661 | var infos = [ | |
2662 | "Prefix searches with a type followed by a colon (e.g., <code>fn:</code>) to \ | |
2663 | restrict the search to a given type.", | |
2664 | "Accepted types are: <code>fn</code>, <code>mod</code>, <code>struct</code>, \ | |
2665 | <code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, \ | |
2666 | and <code>const</code>.", | |
2667 | "Search functions by type signature (e.g., <code>vec -> usize</code> or \ | |
2668 | <code>* -> vec</code>)", | |
2669 | "Search multiple things at once by splitting your query with comma (e.g., \ | |
2670 | <code>str,u8</code> or <code>String,struct:Vec,test</code>)", | |
2671 | "You can look for items with an exact name by putting double quotes around \ | |
2672 | your request: <code>\"string\"</code>", | |
2673 | "Look for items inside another one by searching for a path: <code>vec::Vec</code>", | |
2674 | ].map(x => "<p>" + x + "</p>").join(""); | |
2675 | var div_infos = document.createElement("div"); | |
2676 | addClass(div_infos, "infos"); | |
2677 | div_infos.innerHTML = "<h2>Search Tricks</h2>" + infos; | |
2678 | ||
2679 | container.appendChild(div_shortcuts); | |
2680 | container.appendChild(div_infos); | |
2681 | ||
2682 | popup.appendChild(container); | |
2683 | insertAfter(popup, getSearchElement()); | |
2684 | } | |
2685 | ||
60c5eb7d XL |
2686 | onHashChange(null); |
2687 | window.onhashchange = onHashChange; | |
2688 | ||
e74abb32 | 2689 | buildHelperPopup(); |
1a4d82fc | 2690 | }()); |
c1a9b12d SL |
2691 | |
2692 | // Sets the focus on the search bar at the top of the page | |
2693 | function focusSearchBar() { | |
e1599b0c | 2694 | getSearchInput().focus(); |
c1a9b12d | 2695 | } |
2c00a5a8 XL |
2696 | |
2697 | // Removes the focus from the search bar | |
2698 | function defocusSearchBar() { | |
e1599b0c | 2699 | getSearchInput().blur(); |
2c00a5a8 | 2700 | } |