about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-05-26 22:11:26 +0200
committerGitHub <noreply@github.com>2020-05-26 22:11:26 +0200
commit0747f586ebada402e2b2d5cb14ab40d5f33518a6 (patch)
tree4c2b0c0f890987e5cd4d7567a4ac7ffc95bc2d50
parent6e6bd630e67e79d553e52eaca191555991eedd8f (diff)
parent398511a1352ab5b6d5fd8f2c9e80b357f6b84441 (diff)
downloadrust-0747f586ebada402e2b2d5cb14ab40d5f33518a6.tar.gz
rust-0747f586ebada402e2b2d5cb14ab40d5f33518a6.zip
Rollup merge of #72294 - GuillaumeGomez:js-cleanup, r=kinnison
JS cleanup

The goal here is just to improve the source code a bit. I recommend to review one commit at a time, otherwise it might not make much sense. :)

The biggest commit is the second one: to prevent to have "global" variables declared in `main.js` (and thus prevent name conflict or overwriting), I moved such code into anonymous functions.

r? @kinnison

cc @rust-lang/rustdoc
-rw-r--r--src/librustdoc/html/static/main.js588
-rw-r--r--src/librustdoc/html/static/settings.js3
-rw-r--r--src/librustdoc/html/static/source-script.js2
-rw-r--r--src/librustdoc/html/static/storage.js9
-rw-r--r--src/tools/rustdoc-js/tester.js2
5 files changed, 305 insertions, 299 deletions
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 9869c50fbb0..22c9426db20 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -3,7 +3,7 @@
 
 // Local js definitions:
 /* global addClass, getCurrentValue, hasClass */
-/* global onEach, removeClass, updateLocalStorage */
+/* global onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */
 
 if (!String.prototype.startsWith) {
     String.prototype.startsWith = function(searchString, position) {
@@ -47,6 +47,16 @@ function getSearchElement() {
     return document.getElementById("search");
 }
 
+// Sets the focus on the search bar at the top of the page
+function focusSearchBar() {
+    getSearchInput().focus();
+}
+
+// Removes the focus from the search bar
+function defocusSearchBar() {
+    getSearchInput().blur();
+}
+
 (function() {
     "use strict";
 
@@ -181,6 +191,7 @@ function getSearchElement() {
     var savedHash = "";
 
     function handleHashes(ev) {
+        var elem;
         var search = getSearchElement();
         if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) {
             // This block occurs when clicking on an element in the navbar while
@@ -190,7 +201,7 @@ function getSearchElement() {
             if (browserSupportsHistoryApi()) {
                 history.replaceState(hash, "", "?search=#" + hash);
             }
-            var elem = document.getElementById(hash);
+            elem = document.getElementById(hash);
             if (elem) {
                 elem.scrollIntoView();
             }
@@ -201,7 +212,7 @@ function getSearchElement() {
             if (savedHash.length === 0) {
                 return;
             }
-            var elem = document.getElementById(savedHash.slice(1)); // we remove the '#'
+            elem = document.getElementById(savedHash.slice(1)); // we remove the '#'
             if (!elem || !isHidden(elem)) {
                 return;
             }
@@ -324,7 +335,7 @@ function getSearchElement() {
     }
 
     function displayHelp(display, ev, help) {
-        var help = help ? help : getHelpElement();
+        help = help ? help : getHelpElement();
         if (display === true) {
             if (hasClass(help, "hidden")) {
                 ev.preventDefault();
@@ -438,8 +449,8 @@ function getSearchElement() {
 
                 set_fragment(cur_line_id);
             }
-        }
-    })();
+        };
+    }());
 
     document.addEventListener("click", function(ev) {
         if (hasClass(ev.target, "collapse-toggle")) {
@@ -465,27 +476,30 @@ function getSearchElement() {
         }
     });
 
-    var x = document.getElementsByClassName("version-selector");
-    if (x.length > 0) {
-        x[0].onchange = function() {
-            var i, match,
-                url = document.location.href,
-                stripped = "",
-                len = rootPath.match(/\.\.\//g).length + 1;
+    (function() {
+        var x = document.getElementsByClassName("version-selector");
+        if (x.length > 0) {
+            x[0].onchange = function() {
+                var i, match,
+                    url = document.location.href,
+                    stripped = "",
+                    len = rootPath.match(/\.\.\//g).length + 1;
 
-            for (i = 0; i < len; ++i) {
-                match = url.match(/\/[^\/]*$/);
-                if (i < len - 1) {
-                    stripped = match[0] + stripped;
+                for (i = 0; i < len; ++i) {
+                    match = url.match(/\/[^\/]*$/);
+                    if (i < len - 1) {
+                        stripped = match[0] + stripped;
+                    }
+                    url = url.substring(0, url.length - match[0].length);
                 }
-                url = url.substring(0, url.length - match[0].length);
-            }
 
-            url += "/" + document.getElementsByClassName("version-selector")[0].value + stripped;
+                var selectedVersion = document.getElementsByClassName("version-selector")[0].value;
+                url += "/" + selectedVersion + stripped;
 
-            document.location.href = url;
-        };
-    }
+                document.location.href = url;
+            };
+        }
+    }());
 
     /**
      * A function to compute the Levenshtein distance between two strings
@@ -522,7 +536,7 @@ function getSearchElement() {
         return s1_len + s2_len;
     }
 
-    function initSearch(rawSearchIndex) {
+    window.initSearch = function(rawSearchIndex) {
         var MAX_LEV_DISTANCE = 3;
         var MAX_RESULTS = 200;
         var GENERICS_DATA = 1;
@@ -602,7 +616,7 @@ function getSearchElement() {
             function sortResults(results, isType) {
                 var ar = [];
                 for (var entry in results) {
-                    if (results.hasOwnProperty(entry)) {
+                    if (hasOwnProperty(results, entry)) {
                         ar.push(results[entry]);
                     }
                 }
@@ -1100,8 +1114,6 @@ function getSearchElement() {
                     }
                     fullId = generateId(ty);
 
-                    // allow searching for void (no output) functions as well
-                    var typeOutput = type.length > OUTPUT_DATA ? type[OUTPUT_DATA].name : "";
                     returned = checkReturned(ty, output, true, NO_TYPE_FILTER);
                     if (output.name === "*" || returned === true) {
                         in_args = false;
@@ -1164,7 +1176,6 @@ function getSearchElement() {
                 var contains = paths.slice(0, paths.length > 1 ? paths.length - 1 : 1);
 
                 var lev;
-                var lev_distance;
                 for (j = 0; j < nSearchWords; ++j) {
                     ty = searchIndex[j];
                     if (!ty || (filterCrates !== undefined && ty.crate !== filterCrates)) {
@@ -1661,7 +1672,7 @@ function getSearchElement() {
         function getFilterCrates() {
             var elem = document.getElementById("crate-search");
 
-            if (elem && elem.value !== "All crates" && rawSearchIndex.hasOwnProperty(elem.value)) {
+            if (elem && elem.value !== "All crates" && hasOwnProperty(rawSearchIndex, elem.value)) {
                 return elem.value;
             }
             return undefined;
@@ -1709,7 +1720,7 @@ function getSearchElement() {
             var currentIndex = 0;
 
             for (var crate in rawSearchIndex) {
-                if (!rawSearchIndex.hasOwnProperty(crate)) { continue; }
+                if (!hasOwnProperty(rawSearchIndex, crate)) { continue; }
 
                 var crateSize = 0;
 
@@ -1893,7 +1904,7 @@ function getSearchElement() {
 
                 var crates = [];
                 for (var crate in rawSearchIndex) {
-                    if (!rawSearchIndex.hasOwnProperty(crate)) {
+                    if (!hasOwnProperty(rawSearchIndex, crate)) {
                         continue;
                     }
                     crates.push(crate);
@@ -1917,12 +1928,11 @@ function getSearchElement() {
                 sidebar.appendChild(div);
             }
         }
-    }
+    };
 
-    window.initSearch = initSearch;
 
     // delayed sidebar rendering.
-    function initSidebarItems(items) {
+    window.initSidebarItems = function(items) {
         var sidebar = document.getElementsByClassName("sidebar-elems")[0];
         var current = window.sidebarCurrent;
 
@@ -1984,9 +1994,7 @@ function getSearchElement() {
         block("foreigntype", "Foreign Types");
         block("keyword", "Keywords");
         block("traitalias", "Trait Aliases");
-    }
-
-    window.initSidebarItems = initSidebarItems;
+    };
 
     window.register_implementors = function(imp) {
         var implementors = document.getElementById("implementors-list");
@@ -2163,19 +2171,13 @@ function getSearchElement() {
                         }
                     }
                     var ns = n.nextElementSibling;
-                    while (true) {
-                        if (ns && (
-                                hasClass(ns, "docblock") ||
-                                hasClass(ns, "stability"))) {
-                            if (addOrRemove) {
-                                addClass(ns, "hidden-by-impl-hider");
-                            } else {
-                                removeClass(ns, "hidden-by-impl-hider");
-                            }
-                            ns = ns.nextElementSibling;
-                            continue;
+                    while (ns && (hasClass(ns, "docblock") || hasClass(ns, "stability"))) {
+                        if (addOrRemove) {
+                            addClass(ns, "hidden-by-impl-hider");
+                        } else {
+                            removeClass(ns, "hidden-by-impl-hider");
                         }
-                        break;
+                        ns = ns.nextElementSibling;
                     }
                 }
             };
@@ -2248,7 +2250,7 @@ function getSearchElement() {
         }
     }
 
-    function collapser(e, collapse) {
+    function collapser(pageId, e, collapse) {
         // inherent impl ids are like "impl" or impl-<number>'.
         // they will never be hidden by default.
         var n = e.parentElement;
@@ -2268,7 +2270,7 @@ function getSearchElement() {
 
             if (impl_list !== null) {
                 onEachLazy(impl_list.getElementsByClassName("collapse-toggle"), function(e) {
-                    collapser(e, collapse);
+                    collapser(pageId, e, collapse);
                 });
             }
 
@@ -2276,7 +2278,7 @@ function getSearchElement() {
 
             if (blanket_list !== null) {
                 onEachLazy(blanket_list.getElementsByClassName("collapse-toggle"), function(e) {
-                    collapser(e, collapse);
+                    collapser(pageId, e, collapse);
                 });
             }
         }
@@ -2300,103 +2302,7 @@ function getSearchElement() {
         return toggle;
     }
 
-    var toggle = createSimpleToggle(false);
-    var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true";
-    var pageId = getPageId();
-
-    var func = function(e) {
-        var next = e.nextElementSibling;
-        if (!next) {
-            return;
-        }
-        if (hasClass(next, "docblock") === true ||
-            (hasClass(next, "stability") === true &&
-             hasClass(next.nextElementSibling, "docblock") === true)) {
-            var newToggle = toggle.cloneNode(true);
-            insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
-            if (hideMethodDocs === true && hasClass(e, "method") === true) {
-                collapseDocs(newToggle, "hide", pageId);
-            }
-        }
-    };
-
-    var funcImpl = function(e) {
-        var next = e.nextElementSibling;
-        if (next && hasClass(next, "docblock")) {
-            next = next.nextElementSibling;
-        }
-        if (!next) {
-            return;
-        }
-        if (next.getElementsByClassName("method").length > 0 && hasClass(e, "impl")) {
-            insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
-        }
-    };
-
-    onEachLazy(document.getElementsByClassName("method"), func);
-    onEachLazy(document.getElementsByClassName("associatedconstant"), func);
-    onEachLazy(document.getElementsByClassName("impl"), funcImpl);
-    var impl_call = function() {};
-    if (hideMethodDocs === true) {
-        impl_call = function(e, newToggle, pageId) {
-            if (e.id.match(/^impl(?:-\d+)?$/) === null) {
-                // Automatically minimize all non-inherent impls
-                if (hasClass(e, "impl") === true) {
-                    collapseDocs(newToggle, "hide", pageId);
-                }
-            }
-        };
-    }
-    var newToggle = document.createElement("a");
-    newToggle.href = "javascript:void(0)";
-    newToggle.className = "collapse-toggle hidden-default collapsed";
-    newToggle.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) +
-                          "</span>] Show hidden undocumented items";
-    function toggleClicked() {
-        if (hasClass(this, "collapsed")) {
-            removeClass(this, "collapsed");
-            onEachLazy(this.parentNode.getElementsByClassName("hidden"), function(x) {
-                if (hasClass(x, "content") === false) {
-                    removeClass(x, "hidden");
-                    addClass(x, "x");
-                }
-            }, true);
-            this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(false) +
-                             "</span>] Hide undocumented items";
-        } else {
-            addClass(this, "collapsed");
-            onEachLazy(this.parentNode.getElementsByClassName("x"), function(x) {
-                if (hasClass(x, "content") === false) {
-                    addClass(x, "hidden");
-                    removeClass(x, "x");
-                }
-            }, true);
-            this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) +
-                             "</span>] Show hidden undocumented items";
-        }
-    }
-    onEachLazy(document.getElementsByClassName("impl-items"), function(e) {
-        onEachLazy(e.getElementsByClassName("associatedconstant"), func);
-        var hiddenElems = e.getElementsByClassName("hidden");
-        var needToggle = false;
-
-        var hlength = hiddenElems.length;
-        for (var i = 0; i < hlength; ++i) {
-            if (hasClass(hiddenElems[i], "content") === false &&
-                hasClass(hiddenElems[i], "docblock") === false) {
-                needToggle = true;
-                break;
-            }
-        }
-        if (needToggle === true) {
-            var inner_toggle = newToggle.cloneNode(true);
-            inner_toggle.onclick = toggleClicked;
-            e.insertBefore(inner_toggle, e.firstChild);
-            impl_call(e.previousSibling, inner_toggle, pageId);
-        }
-    });
-
-    function createToggle(otherMessage, fontSize, extraClass, show) {
+    function createToggle(toggle, otherMessage, fontSize, extraClass, show) {
         var span = document.createElement("span");
         span.className = "toggle-label";
         if (show) {
@@ -2431,97 +2337,197 @@ function getSearchElement() {
         return wrapper;
     }
 
-    var currentType = document.getElementsByClassName("type-decl")[0];
-    var className = null;
-    if (currentType) {
-        currentType = currentType.getElementsByClassName("rust")[0];
-        if (currentType) {
-            currentType.classList.forEach(function(item) {
-                if (item !== "main") {
-                    className = item;
-                    return true;
+    (function() {
+        var toggle = createSimpleToggle(false);
+        var hideMethodDocs = getCurrentValue("rustdoc-auto-hide-method-docs") === "true";
+        var pageId = getPageId();
+
+        var func = function(e) {
+            var next = e.nextElementSibling;
+            if (!next) {
+                return;
+            }
+            if (hasClass(next, "docblock") === true ||
+                (hasClass(next, "stability") === true &&
+                 hasClass(next.nextElementSibling, "docblock") === true)) {
+                var newToggle = toggle.cloneNode(true);
+                insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]);
+                if (hideMethodDocs === true && hasClass(e, "method") === true) {
+                    collapseDocs(newToggle, "hide", pageId);
                 }
-            });
+            }
+        };
+
+        var funcImpl = function(e) {
+            var next = e.nextElementSibling;
+            if (next && hasClass(next, "docblock")) {
+                next = next.nextElementSibling;
+            }
+            if (!next) {
+                return;
+            }
+            if (next.getElementsByClassName("method").length > 0 && hasClass(e, "impl")) {
+                insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
+            }
+        };
+
+        onEachLazy(document.getElementsByClassName("method"), func);
+        onEachLazy(document.getElementsByClassName("associatedconstant"), func);
+        onEachLazy(document.getElementsByClassName("impl"), funcImpl);
+        var impl_call = function() {};
+        if (hideMethodDocs === true) {
+            impl_call = function(e, newToggle) {
+                if (e.id.match(/^impl(?:-\d+)?$/) === null) {
+                    // Automatically minimize all non-inherent impls
+                    if (hasClass(e, "impl") === true) {
+                        collapseDocs(newToggle, "hide", pageId);
+                    }
+                }
+            };
         }
-    }
-    var showItemDeclarations = getCurrentValue("rustdoc-auto-hide-" + className);
-    if (showItemDeclarations === null) {
-        if (className === "enum" || className === "macro") {
-            showItemDeclarations = "false";
-        } else if (className === "struct" || className === "union" || className === "trait") {
-            showItemDeclarations = "true";
-        } else {
-            // In case we found an unknown type, we just use the "parent" value.
-            showItemDeclarations = getCurrentValue("rustdoc-auto-hide-declarations");
+        var newToggle = document.createElement("a");
+        newToggle.href = "javascript:void(0)";
+        newToggle.className = "collapse-toggle hidden-default collapsed";
+        newToggle.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) +
+                              "</span>] Show hidden undocumented items";
+        function toggleClicked() {
+            if (hasClass(this, "collapsed")) {
+                removeClass(this, "collapsed");
+                onEachLazy(this.parentNode.getElementsByClassName("hidden"), function(x) {
+                    if (hasClass(x, "content") === false) {
+                        removeClass(x, "hidden");
+                        addClass(x, "x");
+                    }
+                }, true);
+                this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(false) +
+                                 "</span>] Hide undocumented items";
+            } else {
+                addClass(this, "collapsed");
+                onEachLazy(this.parentNode.getElementsByClassName("x"), function(x) {
+                    if (hasClass(x, "content") === false) {
+                        addClass(x, "hidden");
+                        removeClass(x, "x");
+                    }
+                }, true);
+                this.innerHTML = "[<span class=\"inner\">" + labelForToggleButton(true) +
+                                 "</span>] Show hidden undocumented items";
+            }
         }
-    }
-    showItemDeclarations = showItemDeclarations === "false";
-    function buildToggleWrapper(e) {
-        if (hasClass(e, "autohide")) {
-            var wrap = e.previousElementSibling;
-            if (wrap && hasClass(wrap, "toggle-wrapper")) {
-                var inner_toggle = wrap.childNodes[0];
-                var extra = e.childNodes[0].tagName === "H3";
-
-                e.style.display = "none";
-                addClass(wrap, "collapsed");
-                onEachLazy(inner_toggle.getElementsByClassName("inner"), function(e) {
-                    e.innerHTML = labelForToggleButton(true);
-                });
-                onEachLazy(inner_toggle.getElementsByClassName("toggle-label"), function(e) {
-                    e.style.display = "inline-block";
-                    if (extra === true) {
-                        i_e.innerHTML = " Show " + e.childNodes[0].innerHTML;
+        onEachLazy(document.getElementsByClassName("impl-items"), function(e) {
+            onEachLazy(e.getElementsByClassName("associatedconstant"), func);
+            var hiddenElems = e.getElementsByClassName("hidden");
+            var needToggle = false;
+
+            var hlength = hiddenElems.length;
+            for (var i = 0; i < hlength; ++i) {
+                if (hasClass(hiddenElems[i], "content") === false &&
+                    hasClass(hiddenElems[i], "docblock") === false) {
+                    needToggle = true;
+                    break;
+                }
+            }
+            if (needToggle === true) {
+                var inner_toggle = newToggle.cloneNode(true);
+                inner_toggle.onclick = toggleClicked;
+                e.insertBefore(inner_toggle, e.firstChild);
+                impl_call(e.previousSibling, inner_toggle);
+            }
+        });
+
+        var currentType = document.getElementsByClassName("type-decl")[0];
+        var className = null;
+        if (currentType) {
+            currentType = currentType.getElementsByClassName("rust")[0];
+            if (currentType) {
+                currentType.classList.forEach(function(item) {
+                    if (item !== "main") {
+                        className = item;
+                        return true;
                     }
                 });
             }
         }
-        if (e.parentNode.id === "main") {
-            var otherMessage = "";
-            var fontSize;
-            var extraClass;
-
-            if (hasClass(e, "type-decl")) {
-                fontSize = "20px";
-                otherMessage = "&nbsp;Show&nbsp;declaration";
-                if (showItemDeclarations === false) {
-                    extraClass = "collapsed";
-                }
-            } else if (hasClass(e, "sub-variant")) {
-                otherMessage = "&nbsp;Show&nbsp;fields";
-            } else if (hasClass(e, "non-exhaustive")) {
-                otherMessage = "&nbsp;This&nbsp;";
-                if (hasClass(e, "non-exhaustive-struct")) {
-                    otherMessage += "struct";
-                } else if (hasClass(e, "non-exhaustive-enum")) {
-                    otherMessage += "enum";
-                } else if (hasClass(e, "non-exhaustive-variant")) {
-                    otherMessage += "enum variant";
-                } else if (hasClass(e, "non-exhaustive-type")) {
-                    otherMessage += "type";
-                }
-                otherMessage += "&nbsp;is&nbsp;marked&nbsp;as&nbsp;non-exhaustive";
-            } else if (hasClass(e.childNodes[0], "impl-items")) {
-                extraClass = "marg-left";
-            }
-
-            e.parentNode.insertBefore(
-                createToggle(otherMessage,
-                             fontSize,
-                             extraClass,
-                             hasClass(e, "type-decl") === false || showItemDeclarations === true),
-                e);
-            if (hasClass(e, "type-decl") === true && showItemDeclarations === true) {
-                collapseDocs(e.previousSibling.childNodes[0], "toggle");
-            }
-            if (hasClass(e, "non-exhaustive") === true) {
-                collapseDocs(e.previousSibling.childNodes[0], "toggle");
+        var showItemDeclarations = getCurrentValue("rustdoc-auto-hide-" + className);
+        if (showItemDeclarations === null) {
+            if (className === "enum" || className === "macro") {
+                showItemDeclarations = "false";
+            } else if (className === "struct" || className === "union" || className === "trait") {
+                showItemDeclarations = "true";
+            } else {
+                // In case we found an unknown type, we just use the "parent" value.
+                showItemDeclarations = getCurrentValue("rustdoc-auto-hide-declarations");
+            }
+        }
+        showItemDeclarations = showItemDeclarations === "false";
+        function buildToggleWrapper(e) {
+            if (hasClass(e, "autohide")) {
+                var wrap = e.previousElementSibling;
+                if (wrap && hasClass(wrap, "toggle-wrapper")) {
+                    var inner_toggle = wrap.childNodes[0];
+                    var extra = e.childNodes[0].tagName === "H3";
+
+                    e.style.display = "none";
+                    addClass(wrap, "collapsed");
+                    onEachLazy(inner_toggle.getElementsByClassName("inner"), function(e) {
+                        e.innerHTML = labelForToggleButton(true);
+                    });
+                    onEachLazy(inner_toggle.getElementsByClassName("toggle-label"), function(e) {
+                        e.style.display = "inline-block";
+                        if (extra === true) {
+                            e.innerHTML = " Show " + e.childNodes[0].innerHTML;
+                        }
+                    });
+                }
+            }
+            if (e.parentNode.id === "main") {
+                var otherMessage = "";
+                var fontSize;
+                var extraClass;
+
+                if (hasClass(e, "type-decl")) {
+                    fontSize = "20px";
+                    otherMessage = "&nbsp;Show&nbsp;declaration";
+                    if (showItemDeclarations === false) {
+                        extraClass = "collapsed";
+                    }
+                } else if (hasClass(e, "sub-variant")) {
+                    otherMessage = "&nbsp;Show&nbsp;fields";
+                } else if (hasClass(e, "non-exhaustive")) {
+                    otherMessage = "&nbsp;This&nbsp;";
+                    if (hasClass(e, "non-exhaustive-struct")) {
+                        otherMessage += "struct";
+                    } else if (hasClass(e, "non-exhaustive-enum")) {
+                        otherMessage += "enum";
+                    } else if (hasClass(e, "non-exhaustive-variant")) {
+                        otherMessage += "enum variant";
+                    } else if (hasClass(e, "non-exhaustive-type")) {
+                        otherMessage += "type";
+                    }
+                    otherMessage += "&nbsp;is&nbsp;marked&nbsp;as&nbsp;non-exhaustive";
+                } else if (hasClass(e.childNodes[0], "impl-items")) {
+                    extraClass = "marg-left";
+                }
+
+                e.parentNode.insertBefore(
+                    createToggle(
+                        toggle,
+                        otherMessage,
+                        fontSize,
+                        extraClass,
+                        hasClass(e, "type-decl") === false || showItemDeclarations === true),
+                    e);
+                if (hasClass(e, "type-decl") === true && showItemDeclarations === true) {
+                    collapseDocs(e.previousSibling.childNodes[0], "toggle");
+                }
+                if (hasClass(e, "non-exhaustive") === true) {
+                    collapseDocs(e.previousSibling.childNodes[0], "toggle");
+                }
             }
         }
-    }
 
-    onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper);
-    onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper);
+        onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper);
+        onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper);
+    }());
 
     function createToggleWrapper(tog) {
         var span = document.createElement("span");
@@ -2536,56 +2542,60 @@ function getSearchElement() {
         return wrapper;
     }
 
-    // To avoid checking on "rustdoc-item-attributes" value on every loop...
-    var itemAttributesFunc = function() {};
-    if (getCurrentValue("rustdoc-auto-hide-attributes") !== "false") {
-        itemAttributesFunc = function(x) {
-            collapseDocs(x.previousSibling.childNodes[0], "toggle");
-        };
-    }
-    var attributesToggle = createToggleWrapper(createSimpleToggle(false));
-    onEachLazy(main.getElementsByClassName("attributes"), function(i_e) {
-        var attr_tog = attributesToggle.cloneNode(true);
-        if (hasClass(i_e, "top-attr") === true) {
-            addClass(attr_tog, "top-attr");
-        }
-        i_e.parentNode.insertBefore(attr_tog, i_e);
-        itemAttributesFunc(i_e);
-    });
-
-    // To avoid checking on "rustdoc-line-numbers" value on every loop...
-    var lineNumbersFunc = function() {};
-    if (getCurrentValue("rustdoc-line-numbers") === "true") {
-        lineNumbersFunc = function(x) {
-            var count = x.textContent.split("\n").length;
-            var elems = [];
-            for (var i = 0; i < count; ++i) {
-                elems.push(i + 1);
-            }
-            var node = document.createElement("pre");
-            addClass(node, "line-number");
-            node.innerHTML = elems.join("\n");
-            x.parentNode.insertBefore(node, x);
-        };
-    }
-    onEachLazy(document.getElementsByClassName("rust-example-rendered"), function(e) {
-        if (hasClass(e, "compile_fail")) {
-            e.addEventListener("mouseover", function(event) {
-                this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00";
-            });
-            e.addEventListener("mouseout", function(event) {
-                this.parentElement.previousElementSibling.childNodes[0].style.color = "";
-            });
-        } else if (hasClass(e, "ignore")) {
-            e.addEventListener("mouseover", function(event) {
-                this.parentElement.previousElementSibling.childNodes[0].style.color = "#ff9200";
-            });
-            e.addEventListener("mouseout", function(event) {
-                this.parentElement.previousElementSibling.childNodes[0].style.color = "";
-            });
+    (function() {
+        // To avoid checking on "rustdoc-item-attributes" value on every loop...
+        var itemAttributesFunc = function() {};
+        if (getCurrentValue("rustdoc-auto-hide-attributes") !== "false") {
+            itemAttributesFunc = function(x) {
+                collapseDocs(x.previousSibling.childNodes[0], "toggle");
+            };
         }
-        lineNumbersFunc(e);
-    });
+        var attributesToggle = createToggleWrapper(createSimpleToggle(false));
+        onEachLazy(main.getElementsByClassName("attributes"), function(i_e) {
+            var attr_tog = attributesToggle.cloneNode(true);
+            if (hasClass(i_e, "top-attr") === true) {
+                addClass(attr_tog, "top-attr");
+            }
+            i_e.parentNode.insertBefore(attr_tog, i_e);
+            itemAttributesFunc(i_e);
+        });
+    }());
+
+    (function() {
+        // To avoid checking on "rustdoc-line-numbers" value on every loop...
+        var lineNumbersFunc = function() {};
+        if (getCurrentValue("rustdoc-line-numbers") === "true") {
+            lineNumbersFunc = function(x) {
+                var count = x.textContent.split("\n").length;
+                var elems = [];
+                for (var i = 0; i < count; ++i) {
+                    elems.push(i + 1);
+                }
+                var node = document.createElement("pre");
+                addClass(node, "line-number");
+                node.innerHTML = elems.join("\n");
+                x.parentNode.insertBefore(node, x);
+            };
+        }
+        onEachLazy(document.getElementsByClassName("rust-example-rendered"), function(e) {
+            if (hasClass(e, "compile_fail")) {
+                e.addEventListener("mouseover", function() {
+                    this.parentElement.previousElementSibling.childNodes[0].style.color = "#f00";
+                });
+                e.addEventListener("mouseout", function() {
+                    this.parentElement.previousElementSibling.childNodes[0].style.color = "";
+                });
+            } else if (hasClass(e, "ignore")) {
+                e.addEventListener("mouseover", function() {
+                    this.parentElement.previousElementSibling.childNodes[0].style.color = "#ff9200";
+                });
+                e.addEventListener("mouseout", function() {
+                    this.parentElement.previousElementSibling.childNodes[0].style.color = "";
+                });
+            }
+            lineNumbersFunc(e);
+        });
+    }());
 
     // In the search display, allows to switch between tabs.
     function printTab(nb) {
@@ -2678,7 +2688,7 @@ function getSearchElement() {
         });
     }
 
-    function addSearchOptions(crates) {
+    window.addSearchOptions = function(crates) {
         var elem = document.getElementById("crate-search");
 
         if (!elem) {
@@ -2687,7 +2697,7 @@ function getSearchElement() {
         var crates_text = [];
         if (Object.keys(crates).length > 1) {
             for (var crate in crates) {
-                if (crates.hasOwnProperty(crate)) {
+                if (hasOwnProperty(crates, crate)) {
                     crates_text.push(crate);
                 }
             }
@@ -2722,10 +2732,8 @@ function getSearchElement() {
 
         if (search_input) {
             search_input.removeAttribute('disabled');
-        };
-    }
-
-    window.addSearchOptions = addSearchOptions;
+        }
+    };
 
     function buildHelperPopup() {
         var popup = document.createElement("aside");
@@ -2778,16 +2786,6 @@ function getSearchElement() {
     buildHelperPopup();
 }());
 
-// Sets the focus on the search bar at the top of the page
-function focusSearchBar() {
-    getSearchInput().focus();
-}
-
-// Removes the focus from the search bar
-function defocusSearchBar() {
-    getSearchInput().blur();
-}
-
 // This is required in firefox. Explanations: when going back in the history, firefox doesn't re-run
 // the JS, therefore preventing rustdoc from setting a few things required to be able to reload the
 // previous search results (if you navigated to a search result with the keyboard, pressed enter on
diff --git a/src/librustdoc/html/static/settings.js b/src/librustdoc/html/static/settings.js
index c21db7371f3..427a74c0c87 100644
--- a/src/librustdoc/html/static/settings.js
+++ b/src/librustdoc/html/static/settings.js
@@ -1,3 +1,6 @@
+// Local js definitions:
+/* global getCurrentValue, updateLocalStorage */
+
 (function () {
     function changeSetting(settingName, isEnabled) {
         updateLocalStorage('rustdoc-' + settingName, isEnabled);
diff --git a/src/librustdoc/html/static/source-script.js b/src/librustdoc/html/static/source-script.js
index 567022b4139..cfbfe6675f5 100644
--- a/src/librustdoc/html/static/source-script.js
+++ b/src/librustdoc/html/static/source-script.js
@@ -1,5 +1,5 @@
 // From rust:
-/* global sourcesIndex */
+/* global search, sourcesIndex */
 
 // Local js definitions:
 /* global addClass, getCurrentValue, hasClass, removeClass, updateLocalStorage */
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index d142d99ac70..0a2fae274fa 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -27,14 +27,15 @@ function removeClass(elem, className) {
 function onEach(arr, func, reversed) {
     if (arr && arr.length > 0 && func) {
         var length = arr.length;
+        var i;
         if (reversed !== true) {
-            for (var i = 0; i < length; ++i) {
+            for (i = 0; i < length; ++i) {
                 if (func(arr[i]) === true) {
                     return true;
                 }
             }
         } else {
-            for (var i = length - 1; i >= 0; --i) {
+            for (i = length - 1; i >= 0; --i) {
                 if (func(arr[i]) === true) {
                     return true;
                 }
@@ -51,6 +52,10 @@ function onEachLazy(lazyArray, func, reversed) {
         reversed);
 }
 
+function hasOwnProperty(obj, property) {
+    return Object.prototype.hasOwnProperty.call(obj, property);
+}
+
 function usableLocalStorage() {
     // Check if the browser supports localStorage at all:
     if (typeof Storage === "undefined") {
diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js
index 1fa46ce99f5..163571bc5b9 100644
--- a/src/tools/rustdoc-js/tester.js
+++ b/src/tools/rustdoc-js/tester.js
@@ -241,7 +241,7 @@ function loadMainJsAndIndex(mainJs, searchIndex, storageJs, crate) {
     ALIASES = {};
     finalJS += 'window = { "currentCrate": "' + crate + '" };\n';
     finalJS += 'var rootPath = "../";\n';
-    finalJS += loadThings(["onEach"], 'function', extractFunction, storageJs);
+    finalJS += loadThings(["hasOwnProperty", "onEach"], 'function', extractFunction, storageJs);
     finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs);
     finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs);
     finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs);