11/* global addClass, getNakedUrl, getSettingValue, hasOwnPropertyRustdoc, initSearch, onEach */
2- /* global onEachLazy, removeClass, searchState, updateLocalStorage */
2+ /* global onEachLazy, removeClass, searchState, hasClass */
33
44( function ( ) {
55// This mapping table should match the discriminants of
@@ -133,6 +133,39 @@ window.initSearch = function(rawSearchIndex) {
133133 searchState . input . value = params . search || "" ;
134134 }
135135
136+ /**
137+ * Build an URL with search parameters.
138+ *
139+ * @param {string } search - The current search being performed.
140+ * @param {string|null } filterCrates - The current filtering crate (if any).
141+ * @return {string }
142+ */
143+ function buildUrl ( search , filterCrates ) {
144+ var extra = "?search=" + encodeURIComponent ( search ) ;
145+
146+ if ( filterCrates !== null ) {
147+ extra += "&filter-crate=" + encodeURIComponent ( filterCrates ) ;
148+ }
149+ return getNakedUrl ( ) + extra + window . location . hash ;
150+ }
151+
152+ /**
153+ * Return the filtering crate or `null` if there is none.
154+ *
155+ * @return {string|null }
156+ */
157+ function getFilterCrates ( ) {
158+ var elem = document . getElementById ( "crate-search" ) ;
159+
160+ if ( elem &&
161+ elem . value !== "All crates" &&
162+ hasOwnPropertyRustdoc ( rawSearchIndex , elem . value ) )
163+ {
164+ return elem . value ;
165+ }
166+ return null ;
167+ }
168+
136169 /**
137170 * Executes the query and returns a list of results for each results tab.
138171 * @param {Object } query - The user query
@@ -595,7 +628,7 @@ window.initSearch = function(rawSearchIndex) {
595628 // aliases to be before the others in the displayed results.
596629 var aliases = [ ] ;
597630 var crateAliases = [ ] ;
598- if ( filterCrates !== undefined ) {
631+ if ( filterCrates !== null ) {
599632 if ( ALIASES [ filterCrates ] && ALIASES [ filterCrates ] [ query . search ] ) {
600633 var query_aliases = ALIASES [ filterCrates ] [ query . search ] ;
601634 var len = query_aliases . length ;
@@ -694,7 +727,7 @@ window.initSearch = function(rawSearchIndex) {
694727 {
695728 val = extractGenerics ( val . substr ( 1 , val . length - 2 ) ) ;
696729 for ( i = 0 ; i < nSearchWords ; ++ i ) {
697- if ( filterCrates !== undefined && searchIndex [ i ] . crate !== filterCrates ) {
730+ if ( filterCrates !== null && searchIndex [ i ] . crate !== filterCrates ) {
698731 continue ;
699732 }
700733 in_args = findArg ( searchIndex [ i ] , val , true , typeFilter ) ;
@@ -725,7 +758,7 @@ window.initSearch = function(rawSearchIndex) {
725758 var output = extractGenerics ( parts [ 1 ] ) ;
726759
727760 for ( i = 0 ; i < nSearchWords ; ++ i ) {
728- if ( filterCrates !== undefined && searchIndex [ i ] . crate !== filterCrates ) {
761+ if ( filterCrates !== null && searchIndex [ i ] . crate !== filterCrates ) {
729762 continue ;
730763 }
731764 var type = searchIndex [ i ] . type ;
@@ -781,7 +814,7 @@ window.initSearch = function(rawSearchIndex) {
781814 var lev , j ;
782815 for ( j = 0 ; j < nSearchWords ; ++ j ) {
783816 ty = searchIndex [ j ] ;
784- if ( ! ty || ( filterCrates !== undefined && ty . crate !== filterCrates ) ) {
817+ if ( ! ty || ( filterCrates !== null && ty . crate !== filterCrates ) ) {
785818 continue ;
786819 }
787820 var lev_add = 0 ;
@@ -1279,17 +1312,6 @@ window.initSearch = function(rawSearchIndex) {
12791312 } ;
12801313 }
12811314
1282- function getFilterCrates ( ) {
1283- var elem = document . getElementById ( "crate-search" ) ;
1284-
1285- if ( elem && elem . value !== "All crates" &&
1286- hasOwnPropertyRustdoc ( rawSearchIndex , elem . value ) )
1287- {
1288- return elem . value ;
1289- }
1290- return undefined ;
1291- }
1292-
12931315 /**
12941316 * Perform a search based on the current state of the search input element
12951317 * and display the results.
@@ -1309,27 +1331,34 @@ window.initSearch = function(rawSearchIndex) {
13091331 }
13101332 if ( ! forced && query . id === currentResults ) {
13111333 if ( query . query . length > 0 ) {
1312- searchState . putBackSearch ( searchState . input ) ;
1334+ putBackSearch ( ) ;
13131335 }
13141336 return ;
13151337 }
13161338
1339+ var filterCrates = getFilterCrates ( ) ;
1340+
1341+ // In case we have no information about the saved crate and there is a URL query parameter,
1342+ // we override it with the URL query parameter.
1343+ if ( filterCrates === null && params [ "filter-crate" ] !== undefined ) {
1344+ filterCrates = params [ "filter-crate" ] ;
1345+ }
1346+
13171347 // Update document title to maintain a meaningful browser history
13181348 searchState . title = "Results for " + query . query + " - Rust" ;
13191349
13201350 // Because searching is incremental by character, only the most
13211351 // recent search query is added to the browser history.
13221352 if ( searchState . browserSupportsHistoryApi ( ) ) {
1323- var newURL = getNakedUrl ( ) + "?search=" + encodeURIComponent ( query . raw ) +
1324- window . location . hash ;
1353+ var newURL = buildUrl ( query . raw , filterCrates ) ;
1354+
13251355 if ( ! history . state && ! params . search ) {
1326- history . pushState ( query , "" , newURL ) ;
1356+ history . pushState ( null , "" , newURL ) ;
13271357 } else {
1328- history . replaceState ( query , "" , newURL ) ;
1358+ history . replaceState ( null , "" , newURL ) ;
13291359 }
13301360 }
13311361
1332- var filterCrates = getFilterCrates ( ) ;
13331362 showResults ( execSearch ( query , searchWords , filterCrates ) ,
13341363 params [ "go_to_first" ] , filterCrates ) ;
13351364 }
@@ -1495,12 +1524,28 @@ window.initSearch = function(rawSearchIndex) {
14951524 search ( ) ;
14961525 }
14971526
1527+ function putBackSearch ( ) {
1528+ var search_input = searchState . input ;
1529+ if ( ! searchState . input ) {
1530+ return ;
1531+ }
1532+ var search = searchState . outputElement ( ) ;
1533+ if ( search_input . value !== "" && hasClass ( search , "hidden" ) ) {
1534+ searchState . showResults ( search ) ;
1535+ if ( searchState . browserSupportsHistoryApi ( ) ) {
1536+ history . replaceState ( null , "" ,
1537+ buildUrl ( search_input . value , getFilterCrates ( ) ) ) ;
1538+ }
1539+ document . title = searchState . title ;
1540+ }
1541+ }
1542+
14981543 function registerSearchEvents ( ) {
14991544 var searchAfter500ms = function ( ) {
15001545 searchState . clearInputTimeout ( ) ;
15011546 if ( searchState . input . value . length === 0 ) {
15021547 if ( searchState . browserSupportsHistoryApi ( ) ) {
1503- history . replaceState ( "" , window . currentCrate + " - Rust" ,
1548+ history . replaceState ( null , window . currentCrate + " - Rust" ,
15041549 getNakedUrl ( ) + window . location . hash ) ;
15051550 }
15061551 searchState . hideResults ( ) ;
@@ -1567,6 +1612,14 @@ window.initSearch = function(rawSearchIndex) {
15671612 }
15681613 } ) ;
15691614
1615+ searchState . input . addEventListener ( "focus" , function ( ) {
1616+ putBackSearch ( ) ;
1617+ } ) ;
1618+
1619+ searchState . input . addEventListener ( "blur" , function ( ) {
1620+ searchState . input . placeholder = searchState . input . origPlaceholder ;
1621+ } ) ;
1622+
15701623 // Push and pop states are used to add search results to the browser
15711624 // history.
15721625 if ( searchState . browserSupportsHistoryApi ( ) ) {
@@ -1619,7 +1672,16 @@ window.initSearch = function(rawSearchIndex) {
16191672 }
16201673
16211674 function updateCrate ( ev ) {
1622- updateLocalStorage ( "saved-filter-crate" , ev . target . value ) ;
1675+ if ( ev . target . value === "All crates" ) {
1676+ // If we don't remove it from the URL, it'll be picked up again by the search.
1677+ var params = searchState . getQueryStringParams ( ) ;
1678+ var query = searchState . input . value . trim ( ) ;
1679+ if ( ! history . state && ! params . search ) {
1680+ history . pushState ( null , "" , buildUrl ( query , null ) ) ;
1681+ } else {
1682+ history . replaceState ( null , "" , buildUrl ( query , null ) ) ;
1683+ }
1684+ }
16231685 // In case you "cut" the entry from the search input, then change the crate filter
16241686 // before paste back the previous search, you get the old search results without
16251687 // the filter. To prevent this, we need to remove the previous results.
@@ -1629,10 +1691,15 @@ window.initSearch = function(rawSearchIndex) {
16291691
16301692 searchWords = buildIndex ( rawSearchIndex ) ;
16311693 registerSearchEvents ( ) ;
1632- // If there's a search term in the URL, execute the search now.
1633- if ( searchState . getQueryStringParams ( ) . search ) {
1634- search ( ) ;
1694+
1695+ function runSearchIfNeeded ( ) {
1696+ // If there's a search term in the URL, execute the search now.
1697+ if ( searchState . getQueryStringParams ( ) . search ) {
1698+ search ( ) ;
1699+ }
16351700 }
1701+
1702+ runSearchIfNeeded ( ) ;
16361703} ;
16371704
16381705if ( window . searchIndex !== undefined ) {
0 commit comments