about summary refs log tree commit diff
path: root/src/tools/clippy/util/gh-pages/script.js
diff options
context:
space:
mode:
authorPhilipp Krones <hello@philkrones.com>2023-07-02 14:35:19 +0200
committerPhilipp Krones <hello@philkrones.com>2023-07-02 14:59:02 +0200
commitbeb0e731de1c13ee0ee341965718b6350a48b34d (patch)
tree55b99c273013575811111601fc4ff948e4d27157 /src/tools/clippy/util/gh-pages/script.js
parent72b21014344fe5a595270c951d5a15887f9c7992 (diff)
parent37f4c1725d3fd7e9c3ffd8783246bc5589debc53 (diff)
downloadrust-beb0e731de1c13ee0ee341965718b6350a48b34d.tar.gz
rust-beb0e731de1c13ee0ee341965718b6350a48b34d.zip
Merge commit '37f4c1725d3fd7e9c3ffd8783246bc5589debc53' into clippyup
Diffstat (limited to 'src/tools/clippy/util/gh-pages/script.js')
-rw-r--r--src/tools/clippy/util/gh-pages/script.js204
1 files changed, 177 insertions, 27 deletions
diff --git a/src/tools/clippy/util/gh-pages/script.js b/src/tools/clippy/util/gh-pages/script.js
index 1c16ecd6b0b..f59245e556c 100644
--- a/src/tools/clippy/util/gh-pages/script.js
+++ b/src/tools/clippy/util/gh-pages/script.js
@@ -24,9 +24,9 @@
         target.scrollIntoView();
     }
 
-    function scrollToLintByURL($scope) {
-        var removeListener = $scope.$on('ngRepeatFinished', function(ngRepeatFinishedEvent) {
-            scrollToLint(window.location.hash.slice(1));
+    function scrollToLintByURL($scope, $location) {
+        var removeListener = $scope.$on('ngRepeatFinished', function (ngRepeatFinishedEvent) {
+            scrollToLint($location.path().substring(1));
             removeListener();
         });
     }
@@ -106,10 +106,10 @@
                 }
             };
         })
-        .controller("lintList", function ($scope, $http, $timeout) {
+        .controller("lintList", function ($scope, $http, $location, $timeout) {
             // Level filter
             var LEVEL_FILTERS_DEFAULT = {allow: true, warn: true, deny: true, none: true};
-            $scope.levels = LEVEL_FILTERS_DEFAULT;
+            $scope.levels = { ...LEVEL_FILTERS_DEFAULT };
             $scope.byLevels = function (lint) {
                 return $scope.levels[lint.level];
             };
@@ -146,6 +146,165 @@
                 "=": {enabled: false, minorVersion: null },
             };
 
+            // Map the versionFilters to the query parameters in a way that is easier to work with in a URL
+            const versionFilterKeyMap = {
+                "≥": "gte",
+                "≤": "lte",
+                "=": "eq"
+            };
+            const reverseVersionFilterKeyMap = Object.fromEntries(
+                Object.entries(versionFilterKeyMap).map(([key, value]) => [value, key])
+            );
+
+            // loadFromURLParameters retrieves filter settings from the URL parameters and assigns them
+            // to corresponding $scope variables.
+            function loadFromURLParameters() {
+                // Extract parameters from URL
+                const urlParameters = $location.search();
+
+                // Define a helper function that assigns URL parameters to a provided scope variable
+                const handleParameter = (parameter, scopeVariable, defaultValues) => {
+                    if (urlParameters[parameter]) {
+                        const items = urlParameters[parameter].split(',');
+                        for (const key in scopeVariable) {
+                            if (scopeVariable.hasOwnProperty(key)) {
+                                scopeVariable[key] = items.includes(key);
+                            }
+                        }
+                    } else if (defaultValues) {
+                        for (const key in defaultValues) {
+                            if (scopeVariable.hasOwnProperty(key)) {
+                                scopeVariable[key] = defaultValues[key];
+                            }
+                        }
+                    }
+                };
+
+                handleParameter('levels', $scope.levels, LEVEL_FILTERS_DEFAULT);
+                handleParameter('groups', $scope.groups, GROUPS_FILTER_DEFAULT);
+
+                // Handle 'versions' parameter separately because it needs additional processing
+                if (urlParameters.versions) {
+                    const versionFilters = urlParameters.versions.split(',');
+                    for (const versionFilter of versionFilters) {
+                        const [key, minorVersion] = versionFilter.split(':');
+                        const parsedMinorVersion = parseInt(minorVersion);
+
+                        // Map the key from the URL parameter to its original form
+                        const originalKey = reverseVersionFilterKeyMap[key];
+
+                        if (originalKey in $scope.versionFilters && !isNaN(parsedMinorVersion)) {
+                            $scope.versionFilters[originalKey].enabled = true;
+                            $scope.versionFilters[originalKey].minorVersion = parsedMinorVersion;
+                        }
+                    }
+                }
+
+                // Load the search parameter from the URL path
+                const searchParameter = $location.path().substring(1); // Remove the leading slash
+                if (searchParameter) {
+                    $scope.search = searchParameter;
+                    $scope.open[searchParameter] = true;
+                    scrollToLintByURL($scope, $location);
+                }
+            }
+
+            // updateURLParameter updates the URL parameter with the given key to the given value
+            function updateURLParameter(filterObj, urlKey, defaultValue = {}, processFilter = filter => filter) {
+                const parameter = Object.keys(filterObj)
+                    .filter(filter => filterObj[filter])
+                    .sort()
+                    .map(processFilter)
+                    .filter(Boolean) // Filters out any falsy values, including null
+                    .join(',');
+
+                const defaultParameter = Object.keys(defaultValue)
+                    .filter(filter => defaultValue[filter])
+                    .sort()
+                    .map(processFilter)
+                    .filter(Boolean) // Filters out any falsy values, including null
+                    .join(',');
+
+                // if we ended up back at the defaults, just remove it from the URL
+                if (parameter === defaultParameter) {
+                    $location.search(urlKey, null);
+                } else {
+                    $location.search(urlKey, parameter || null);
+                }
+            }
+
+            // updateVersionURLParameter updates the version URL parameter with the given version filters
+            function updateVersionURLParameter(versionFilters) {
+                updateURLParameter(
+                    versionFilters,
+                    'versions', {},
+                    versionFilter => versionFilters[versionFilter].enabled && versionFilters[versionFilter].minorVersion != null
+                        ? `${versionFilterKeyMap[versionFilter]}:${versionFilters[versionFilter].minorVersion}`
+                        : null
+                );
+            }
+
+            // updateAllURLParameters updates all the URL parameters with the current filter settings
+            function updateAllURLParameters() {
+                updateURLParameter($scope.levels, 'levels', LEVEL_FILTERS_DEFAULT);
+                updateURLParameter($scope.groups, 'groups', GROUPS_FILTER_DEFAULT);
+                updateVersionURLParameter($scope.versionFilters);
+            }
+
+            // Add $watches to automatically update URL parameters when the data changes
+            $scope.$watch('levels', function (newVal, oldVal) {
+                if (newVal !== oldVal) {
+                    updateURLParameter(newVal, 'levels', LEVEL_FILTERS_DEFAULT);
+                }
+            }, true);
+
+            $scope.$watch('groups', function (newVal, oldVal) {
+                if (newVal !== oldVal) {
+                    updateURLParameter(newVal, 'groups', GROUPS_FILTER_DEFAULT);
+                }
+            }, true);
+
+            $scope.$watch('versionFilters', function (newVal, oldVal) {
+                if (newVal !== oldVal) {
+                    updateVersionURLParameter(newVal);
+                }
+            }, true);
+
+            // Watch for changes in the URL path and update the search and lint display
+            $scope.$watch(function () { return $location.path(); }, function (newPath) {
+                const searchParameter = newPath.substring(1);
+                if ($scope.search !== searchParameter) {
+                    $scope.search = searchParameter;
+                    $scope.open[searchParameter] = true;
+                    scrollToLintByURL($scope, $location);
+                }
+            });
+
+            let debounceTimeout;
+            $scope.$watch('search', function (newVal, oldVal) {
+                if (newVal !== oldVal) {
+                    if (debounceTimeout) {
+                        $timeout.cancel(debounceTimeout);
+                    }
+
+                    debounceTimeout = $timeout(function () {
+                        $location.path(newVal);
+                    }, 1000);
+                }
+            });
+
+            $scope.$watch(function () { return $location.search(); }, function (newParameters) {
+                loadFromURLParameters();
+            }, true);
+
+            $scope.updatePath = function () {
+                if (debounceTimeout) {
+                    $timeout.cancel(debounceTimeout);
+                }
+
+                $location.path($scope.search);
+            }
+
             $scope.selectTheme = function (theme) {
                 setTheme(theme, true);
             }
@@ -169,10 +328,9 @@
             };
 
             $scope.resetGroupsToDefault = function () {
-                const groups = $scope.groups;
-                for (const [key, value] of Object.entries(GROUPS_FILTER_DEFAULT)) {
-                    groups[key] = value;
-                }
+                $scope.groups = {
+                    ...GROUPS_FILTER_DEFAULT
+                };
             };
 
             $scope.selectedValuesCount = function (obj) {
@@ -272,6 +430,12 @@
                 return true;
             }
 
+            // Show details for one lint
+            $scope.openLint = function (lint) {
+                $scope.open[lint.id] = true;
+                $location.path(lint.id);
+            };
+
             $scope.copyToClipboard = function (lint) {
                 const clipboard = document.getElementById("clipboard-" + lint.id);
                 if (clipboard) {
@@ -296,14 +460,12 @@
             // Get data
             $scope.open = {};
             $scope.loading = true;
+
             // This will be used to jump into the source code of the version that this documentation is for.
             $scope.docVersion = window.location.pathname.split('/')[2] || "master";
 
-            if (window.location.hash.length > 1) {
-                $scope.search = window.location.hash.slice(1);
-                $scope.open[window.location.hash.slice(1)] = true;
-                scrollToLintByURL($scope);
-            }
+            // Set up the filters from the URL parameters before we start loading the data
+            loadFromURLParameters();
 
             $http.get('./lints.json')
                 .success(function (data) {
@@ -315,7 +477,7 @@
                         selectGroup($scope, selectedGroup.toLowerCase());
                     }
 
-                    scrollToLintByURL($scope);
+                    scrollToLintByURL($scope, $location);
 
                     setTimeout(function () {
                         var el = document.getElementById('filter-input');
@@ -326,18 +488,6 @@
                     $scope.error = data;
                     $scope.loading = false;
                 });
-
-            window.addEventListener('hashchange', function () {
-                // trigger re-render
-                $timeout(function () {
-                    $scope.levels = LEVEL_FILTERS_DEFAULT;
-                    $scope.search = window.location.hash.slice(1);
-                    $scope.open[window.location.hash.slice(1)] = true;
-
-                    scrollToLintByURL($scope);
-                });
-                return true;
-            }, false);
         });
 })();