about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-01-24 08:46:33 -0800
committerbors <bors@rust-lang.org>2014-01-24 08:46:33 -0800
commit8c805fa70bdbcbce07862d59eaf6524e4306bf46 (patch)
tree55cd2f32a7e24e24fc089d74110cf9269ccbfbae
parent1ea0947c5d1d113f58beafd98a6bb966e07b6f60 (diff)
parentb869f36e787530989172db7a9ec233785f93dca3 (diff)
downloadrust-8c805fa70bdbcbce07862d59eaf6524e4306bf46.tar.gz
rust-8c805fa70bdbcbce07862d59eaf6524e4306bf46.zip
auto merge of #11760 : dmac/rust/addressable-search, r=alexcrichton
This change adds two improvements to docs searching functionality.

First, search results will immediately be displayed when a ?search=searchterm
query string parameter is provided to any docs url.

Second, search results are now inserted into the browser history, allowing for
easier navigation between search results and docs pages.
-rw-r--r--src/librustdoc/html/static/main.js53
1 files changed, 50 insertions, 3 deletions
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index b2500a1bc68..6dbf56681bd 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -17,6 +17,21 @@
 
     $('.js-only').removeClass('js-only');
 
+    function getQueryStringParams() {
+        var params = {};
+        window.location.search.substring(1).split("&").
+            map(function(s) {
+                var pair = s.split("=");
+                params[decodeURIComponent(pair[0])] =
+                    typeof pair[1] === "undefined" ? null : decodeURIComponent(pair[1]);
+            });
+        return params;
+    }
+
+    function browserSupportsHistoryApi() {
+        return window.history && typeof window.history.pushState === "function";
+    }
+
     function resizeShortBlocks() {
         if (resizeTimeout) {
             clearTimeout(resizeTimeout);
@@ -97,10 +112,10 @@
     });
 
     function initSearch(searchIndex) {
-        var currentResults, index;
+        var currentResults, index, params = getQueryStringParams();
 
-        // clear cached values from the search bar
-        $(".search-input")[0].value = '';
+        // Populate search bar with query string search term when provided.
+        $(".search-input")[0].value = params.search || '';
 
         /**
          * Executes the query and builds an index of results
@@ -418,6 +433,7 @@
                 results = [],
                 maxResults = 200,
                 resultIndex;
+            var params = getQueryStringParams();
 
             query = getQuery();
             if (e) {
@@ -428,6 +444,16 @@
                 return;
             }
 
+            // Because searching is incremental by character, only the most recent search query
+            // is added to the browser history.
+            if (browserSupportsHistoryApi()) {
+                if (!history.state && !params.search) {
+                    history.pushState(query, "", "?search=" + encodeURIComponent(query.query));
+                } else {
+                    history.replaceState(query, "", "?search=" + encodeURIComponent(query.query));
+                }
+            }
+
             resultIndex = execQuery(query, 20000, index);
             len = resultIndex.length;
             for (i = 0; i < len; i += 1) {
@@ -536,6 +562,27 @@
                 clearTimeout(keyUpTimeout);
                 keyUpTimeout = setTimeout(search, 100);
             });
+            // Push and pop states are used to add search results to the browser history.
+            if (browserSupportsHistoryApi()) {
+                $(window).on('popstate', function(e) {
+                    var params = getQueryStringParams();
+                    // When browsing back from search results the main page visibility must be reset.
+                    if (!params.search) {
+                        $('#main.content').removeClass('hidden');
+                        $('#search.content').addClass('hidden');
+                    }
+                    // When browsing forward to search results the previous search will be repeated,
+                    // so the currentResults are cleared to ensure the search is successful.
+                    currentResults = null;
+                    // Synchronize search bar with query string state and perform the search.
+                    $('.search-input').val(params.search);
+                    // Some browsers fire 'onpopstate' for every page load (Chrome), while others fire the
+                    // event only when actually popping a state (Firefox), which is why search() is called
+                    // both here and at the end of the startSearch() function.
+                    search();
+                });
+            }
+            search();
         }
 
         index = buildIndex(searchIndex);