]> git.lizzy.rs Git - rust.git/blobdiff - src/librustdoc/html/static/main.js
auto merge of #14874 : pcwalton/rust/enum-to-float-casts-part-deux, r=alexcrichton
[rust.git] / src / librustdoc / html / static / main.js
index ffdf67e56cf7fd67a84db1442c922ed5f745355a..697199e9abf5a34fca3ca8bcb964cb526c31b4f6 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 /*jslint browser: true, es5: true */
-/*globals $: true, rootPath: true, allPaths: true */
+/*globals $: true, rootPath: true */
 
 (function() {
     "use strict";
         function execQuery(query, max, searchWords) {
             var valLower = query.query.toLowerCase(),
                 val = valLower,
-                typeFilter = query.type,
+                typeFilter = itemTypeFromName(query.type),
                 results = [],
-                aa = 0,
-                bb = 0,
                 split = valLower.split("::");
 
             //remove empty keywords
             }
 
             // quoted values mean literal search
-            bb = searchWords.length;
+            var nSearchWords = searchWords.length;
             if ((val.charAt(0) === "\"" || val.charAt(0) === "'") &&
                 val.charAt(val.length - 1) === val.charAt(0))
             {
                 val = val.substr(1, val.length - 2);
-                for (aa = 0; aa < bb; aa += 1) {
-                    if (searchWords[aa] === val) {
+                for (var i = 0; i < nSearchWords; i += 1) {
+                    if (searchWords[i] === val) {
                         // filter type: ... queries
-                        if (!typeFilter || typeFilter === searchIndex[aa].ty) {
-                            results.push([aa, -1]);
+                        if (typeFilter < 0 || typeFilter === searchIndex[i].ty) {
+                            results.push({id: i, index: -1});
                         }
                     }
                     if (results.length === max) {
                 // gather matching search results up to a certain maximum
                 val = val.replace(/\_/g, "");
                 for (var i = 0; i < split.length; i++) {
-                    for (aa = 0; aa < bb; aa += 1) {
-                        if (searchWords[aa].indexOf(split[i]) > -1 ||
-                            searchWords[aa].indexOf(val) > -1 ||
-                            searchWords[aa].replace(/_/g, "").indexOf(val) > -1)
+                    for (var j = 0; j < nSearchWords; j += 1) {
+                        if (searchWords[j].indexOf(split[i]) > -1 ||
+                            searchWords[j].indexOf(val) > -1 ||
+                            searchWords[j].replace(/_/g, "").indexOf(val) > -1)
                         {
                             // filter type: ... queries
-                            if (!typeFilter || typeFilter === searchIndex[aa].ty) {
-                                results.push([aa, searchWords[aa].replace(/_/g, "").indexOf(val)]);
+                            if (typeFilter < 0 || typeFilter === searchIndex[j].ty) {
+                                results.push({id: j, index: searchWords[j].replace(/_/g, "").indexOf(val)});
                             }
                         }
                         if (results.length === max) {
                 }
             }
 
-            bb = results.length;
-            for (aa = 0; aa < bb; aa += 1) {
-                results[aa].push(searchIndex[results[aa][0]].ty);
-                results[aa].push(searchIndex[results[aa][0]].path);
-                results[aa].push(searchIndex[results[aa][0]].name);
-                results[aa].push(searchIndex[results[aa][0]].parent);
-                results[aa].push(searchIndex[results[aa][0]].crate);
+            var nresults = results.length;
+            for (var i = 0; i < nresults; i += 1) {
+                results[i].word = searchWords[results[i].id];
+                results[i].item = searchIndex[results[i].id] || {};
             }
             // if there are no results then return to default and fail
             if (results.length === 0) {
                 return [];
             }
 
-            // sort by exact match
-            results.sort(function search_complete_sort0(aaa, bbb) {
-                if (searchWords[aaa[0]] === valLower &&
-                    searchWords[bbb[0]] !== valLower) {
-                    return 1;
-                }
-            });
-            // first sorting attempt
-            // sort by item name length
-            results.sort(function search_complete_sort1(aaa, bbb) {
-                if (searchWords[aaa[0]].length > searchWords[bbb[0]].length) {
-                    return 1;
-                }
-            });
-            // second sorting attempt
-            // sort by item name
-            results.sort(function search_complete_sort1(aaa, bbb) {
-                if (searchWords[aaa[0]].length === searchWords[bbb[0]].length &&
-                    searchWords[aaa[0]] > searchWords[bbb[0]]) {
-                    return 1;
-                }
+            results.sort(function(aaa, bbb) {
+                var a, b;
+
+                // sort by crate (non-current crate goes later)
+                a = (aaa.item.crate !== window.currentCrate);
+                b = (bbb.item.crate !== window.currentCrate);
+                if (a !== b) return a - b;
+
+                // sort by exact match (mismatch goes later)
+                a = (aaa.word !== valLower);
+                b = (bbb.word !== valLower);
+                if (a !== b) return a - b;
+
+                // sort by item name length (longer goes later)
+                a = aaa.word.length;
+                b = bbb.word.length;
+                if (a !== b) return a - b;
+
+                // sort by item name (lexicographically larger goes later)
+                a = aaa.word;
+                b = bbb.word;
+                if (a !== b) return (a > b ? +1 : -1);
+
+                // sort by index of keyword in item name (no literal occurrence goes later)
+                a = (aaa.index < 0);
+                b = (bbb.index < 0);
+                if (a !== b) return a - b;
+                // (later literal occurrence, if any, goes later)
+                a = aaa.index;
+                b = bbb.index;
+                if (a !== b) return a - b;
+
+                // sort by description (no description goes later)
+                a = (aaa.item.desc === '');
+                b = (bbb.item.desc === '');
+                if (a !== b) return a - b;
+
+                // sort by type (later occurrence in `itemTypes` goes later)
+                a = aaa.item.ty;
+                b = bbb.item.ty;
+                if (a !== b) return a - b;
+
+                // sort by path (lexicographically larger goes later)
+                a = aaa.item.path;
+                b = bbb.item.path;
+                if (a !== b) return (a > b ? +1 : -1);
+
+                // que sera, sera
+                return 0;
             });
-            // third sorting attempt
-            // sort by index of keyword in item name
-            if (results[0][1] !== -1) {
-                results.sort(function search_complete_sort1(aaa, bbb) {
-                    if (aaa[1] > bbb[1] && bbb[1] === 0) {
-                        return 1;
-                    }
-                });
-            }
-            // fourth sorting attempt
-            // sort by type
-            results.sort(function search_complete_sort3(aaa, bbb) {
-                if (searchWords[aaa[0]] === searchWords[bbb[0]] &&
-                    aaa[2] > bbb[2]) {
-                    return 1;
-                }
-            });
-            // fifth sorting attempt
-            // sort by path
-            results.sort(function search_complete_sort4(aaa, bbb) {
-                if (searchWords[aaa[0]] === searchWords[bbb[0]] &&
-                    aaa[2] === bbb[2] && aaa[3] > bbb[3]) {
-                    return 1;
-                }
-            });
-            // sixth sorting attempt
+
             // remove duplicates, according to the data provided
-            for (aa = results.length - 1; aa > 0; aa -= 1) {
-                if (searchWords[results[aa][0]] === searchWords[results[aa - 1][0]] &&
-                    results[aa][2] === results[aa - 1][2] &&
-                    results[aa][3] === results[aa - 1][3])
+            for (var i = results.length - 1; i > 0; i -= 1) {
+                if (results[i].word === results[i - 1].word &&
+                    results[i].item.ty === results[i - 1].item.ty &&
+                    results[i].item.path === results[i - 1].item.path)
                 {
-                    results[aa][0] = -1;
+                    results[i].id = -1;
                 }
             }
             for (var i = 0; i < results.length; i++) {
                 var result = results[i],
-                    name = result[4].toLowerCase(),
-                    path = result[3].toLowerCase(),
-                    parent = allPaths[result[6]][result[5]];
+                    name = result.item.name.toLowerCase(),
+                    path = result.item.path.toLowerCase(),
+                    parent = result.item.parent;
 
                 var valid = validateResult(name, path, split, parent);
                 if (!valid) {
-                    result[0] = -1;
+                    result.id = -1;
                 }
             }
             return results;
             });
         }
 
+        function escape(content) {
+            return $('<h1/>').text(content).html();
+        }
+
         function showResults(results) {
             var output, shown, query = getQuery();
 
             currentResults = query.id;
-            output = '<h1>Results for ' + query.query +
-                    (query.type ? ' (type: ' + query.type + ')' : '') + '</h1>';
+            output = '<h1>Results for ' + escape(query.query) +
+                (query.type ? ' (type: ' + escape(query.type) + ')' : '') + '</h1>';
             output += '<table class="search-results">';
 
             if (results.length > 0) {
 
                     shown.push(item);
                     name = item.name;
-                    type = item.ty;
+                    type = itemTypes[item.ty];
 
                     output += '<tr class="' + type + ' result"><td>';
 
                             '/index.html" class="' + type +
                             '">' + name + '</a>';
                     } else if (item.parent !== undefined) {
-                        var myparent = allPaths[item.crate][item.parent];
+                        var myparent = item.parent;
                         var anchor = '#' + type + '.' + name;
                         output += item.path + '::' + myparent.name +
                             '::<a href="' + rootPath +
                             item.path.replace(/::/g, '/') +
-                            '/' + myparent.type +
+                            '/' + itemTypes[myparent.ty] +
                             '.' + myparent.name +
                             '.html' + anchor +
                             '" class="' + type +
             resultIndex = execQuery(query, 20000, index);
             len = resultIndex.length;
             for (i = 0; i < len; i += 1) {
-                if (resultIndex[i][0] > -1) {
-                    obj = searchIndex[resultIndex[i][0]];
+                if (resultIndex[i].id > -1) {
+                    obj = searchIndex[resultIndex[i].id];
                     filterdata.push([obj.name, obj.ty, obj.path, obj.desc]);
                     results.push(obj);
                 }
             showResults(results);
         }
 
+        // This mapping table should match the discriminants of
+        // `rustdoc::html::item_type::ItemType` type in Rust.
+        var itemTypes = ["mod",
+                         "struct",
+                         "type",
+                         "fn",
+                         "type",
+                         "static",
+                         "trait",
+                         "impl",
+                         "viewitem",
+                         "tymethod",
+                         "method",
+                         "structfield",
+                         "variant",
+                         "ffi",
+                         "ffs",
+                         "macro",
+                         "primitive"];
+
+        function itemTypeFromName(typename) {
+            for (var i = 0; i < itemTypes.length; ++i) {
+                if (itemTypes[i] === typename) return i;
+            }
+            return -1;
+        }
+
         function buildIndex(rawSearchIndex) {
             searchIndex = [];
             var searchWords = [];
             for (var crate in rawSearchIndex) {
                 if (!rawSearchIndex.hasOwnProperty(crate)) { continue }
-                var len = rawSearchIndex[crate].length;
-                var i = 0;
 
+                // an array of [(Number) item type,
+                //              (String) name,
+                //              (String) full path or empty string for previous path,
+                //              (String) description,
+                //              (optional Number) the parent path index to `paths`]
+                var items = rawSearchIndex[crate].items;
+                // an array of [(Number) item type,
+                //              (String) name]
+                var paths = rawSearchIndex[crate].paths;
+
+                // convert `paths` into an object form
+                var len = paths.length;
+                for (var i = 0; i < len; ++i) {
+                    paths[i] = {ty: paths[i][0], name: paths[i][1]};
+                }
+
+                // convert `items` into an object form, and construct word indices.
+                //
                 // before any analysis is performed lets gather the search terms to
                 // search against apart from the rest of the data.  This is a quick
                 // operation that is cached for the life of the page state so that
                 // all other search operations have access to this cached data for
                 // faster analysis operations
-                for (i = 0; i < len; i += 1) {
-                    rawSearchIndex[crate][i].crate = crate;
-                    searchIndex.push(rawSearchIndex[crate][i]);
-                    if (typeof rawSearchIndex[crate][i].name === "string") {
-                        var word = rawSearchIndex[crate][i].name.toLowerCase();
+                var len = items.length;
+                var lastPath = "";
+                for (var i = 0; i < len; i += 1) {
+                    var rawRow = items[i];
+                    var row = {crate: crate, ty: rawRow[0], name: rawRow[1],
+                               path: rawRow[2] || lastPath, desc: rawRow[3],
+                               parent: paths[rawRow[4]]};
+                    searchIndex.push(row);
+                    if (typeof row.name === "string") {
+                        var word = row.name.toLowerCase();
                         searchWords.push(word);
                     } else {
                         searchWords.push("");
                     }
+                    lastPath = row.path;
                 }
             }
             return searchWords;
                     // cleared to ensure the search is successful.
                     currentResults = null;
                     // Synchronize search bar with query string state and
-                    // perform the search, but don't empty the bar if there's
-                    // nothing there.
-                    if (params.search !== undefined) {
-                        $('.search-input').val(params.search);
-                    }
+                    // perform the search. This will empty the bar if there's
+                    // nothing there, which lets you really go back to a
+                    // previous state with nothing in the bar.
+                    $('.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
 
         // Draw a convenient sidebar of known crates if we have a listing
         if (rootPath == '../') {
-            console.log('here');
             var sidebar = $('.sidebar');
             var div = $('<div>').attr('class', 'block crate');
             div.append($('<h2>').text('Crates'));
                 }
                 div.append($('<a>', {'href': '../' + crates[i] + '/index.html',
                                     'class': klass}).text(crates[i]));
-                div.append($('<br>'));
             }
             sidebar.append(div);
         }
     }
 
     window.initSearch = initSearch;
-}());
 
+    window.register_implementors = function(imp) {
+        var list = $('#implementors-list');
+        var libs = Object.getOwnPropertyNames(imp);
+        for (var i = 0; i < libs.length; i++) {
+            if (libs[i] == currentCrate) continue;
+            var structs = imp[libs[i]];
+            for (var j = 0; j < structs.length; j++) {
+                var code = $('<code>').append(structs[j]);
+                $.each(code.find('a'), function(idx, a) {
+                    var href = $(a).attr('href');
+                    if (!href.startsWith('http')) {
+                        $(a).attr('href', rootPath + $(a).attr('href'));
+                    }
+                });
+                var li = $('<li>').append(code);
+                list.append(li);
+            }
+        }
+    };
+    if (window.pending_implementors) {
+        window.register_implementors(window.pending_implementors);
+    }
+
+    // See documentation in html/render.rs for what this is doing.
+    var query = getQueryStringParams();
+    if (query['gotosrc']) {
+        window.location = $('#src-' + query['gotosrc']).attr('href');
+    }
+}());