diff --git a/django/contrib/admin/static/admin/js/nav_sidebar.js b/django/contrib/admin/static/admin/js/nav_sidebar.js index 86cb1cf837..261a9d4992 100644 --- a/django/contrib/admin/static/admin/js/nav_sidebar.js +++ b/django/contrib/admin/static/admin/js/nav_sidebar.js @@ -13,6 +13,12 @@ navLink.tabIndex = 0; } } + function disableNavFilterTabbing() { + document.getElementById('nav-filter').tabIndex = -1; + } + function enableNavFilterTabbing() { + document.getElementById('nav-filter').tabIndex = 0; + } const main = document.getElementById('main'); let navSidebarIsOpen = localStorage.getItem('django.admin.navSidebarIsOpen'); @@ -21,6 +27,7 @@ } if (navSidebarIsOpen === 'false') { disableNavLinkTabbing(); + disableNavFilterTabbing(); } main.classList.toggle('shifted', navSidebarIsOpen === 'true'); @@ -28,9 +35,11 @@ if (navSidebarIsOpen === 'true') { navSidebarIsOpen = 'false'; disableNavLinkTabbing(); + disableNavFilterTabbing(); } else { navSidebarIsOpen = 'true'; enableNavLinkTabbing(); + enableNavFilterTabbing(); } localStorage.setItem('django.admin.navSidebarIsOpen', navSidebarIsOpen); main.classList.toggle('shifted'); diff --git a/docs/releases/4.0.5.txt b/docs/releases/4.0.5.txt index b626f9ef36..15461a3f54 100644 --- a/docs/releases/4.0.5.txt +++ b/docs/releases/4.0.5.txt @@ -14,3 +14,6 @@ Bugfixes * Fixed a bug in Django 4.0 that caused a crash of ``QuerySet.filter()`` on ``IsNull()`` expressions (:ticket:`33705`). + +* Fixed a bug in Django 4.0 where a hidden quick filter toolbar in the admin's + navigation sidebar was focusable (:ticket:`33725`). diff --git a/docs/spelling_wordlist b/docs/spelling_wordlist index 29bc732dfe..fb3686f43c 100644 --- a/docs/spelling_wordlist +++ b/docs/spelling_wordlist @@ -170,6 +170,7 @@ filesystem filesystems flatpage flatpages +focusable fooapp formatter formatters diff --git a/tests/admin_views/test_nav_sidebar.py b/tests/admin_views/test_nav_sidebar.py index a58193c550..994fdc4799 100644 --- a/tests/admin_views/test_nav_sidebar.py +++ b/tests/admin_views/test_nav_sidebar.py @@ -148,10 +148,14 @@ class SeleniumTests(AdminSeleniumTestCase): self.assertEqual(toggle_button.get_attribute("aria-label"), "Toggle navigation") for link in self.selenium.find_elements(By.CSS_SELECTOR, "#nav-sidebar a"): self.assertEqual(link.get_attribute("tabIndex"), "0") + filter_input = self.selenium.find_element_by_css_selector("#nav-filter") + self.assertEqual(filter_input.get_attribute("tabIndex"), "0") toggle_button.click() # Hidden sidebar is not reachable via keyboard navigation. for link in self.selenium.find_elements(By.CSS_SELECTOR, "#nav-sidebar a"): self.assertEqual(link.get_attribute("tabIndex"), "-1") + filter_input = self.selenium.find_element_by_css_selector("#nav-filter") + self.assertEqual(filter_input.get_attribute("tabIndex"), "-1") main_element = self.selenium.find_element(By.CSS_SELECTOR, "#main") self.assertNotIn("shifted", main_element.get_attribute("class").split()) @@ -188,9 +192,13 @@ class SeleniumTests(AdminSeleniumTestCase): # Hidden sidebar is not reachable via keyboard navigation. for link in self.selenium.find_elements(By.CSS_SELECTOR, "#nav-sidebar a"): self.assertEqual(link.get_attribute("tabIndex"), "-1") + filter_input = self.selenium.find_element_by_css_selector("#nav-filter") + self.assertEqual(filter_input.get_attribute("tabIndex"), "-1") toggle_button.click() for link in self.selenium.find_elements(By.CSS_SELECTOR, "#nav-sidebar a"): self.assertEqual(link.get_attribute("tabIndex"), "0") + filter_input = self.selenium.find_element_by_css_selector("#nav-filter") + self.assertEqual(filter_input.get_attribute("tabIndex"), "0") self.assertEqual( self.selenium.execute_script( "return localStorage.getItem('django.admin.navSidebarIsOpen')"