Skip to content

Commit 61ca968

Browse files
committed
Update all other dropdowns to be tab-able
1 parent d0d5299 commit 61ca968

File tree

7 files changed

+189
-168
lines changed

7 files changed

+189
-168
lines changed

warehouse/static/js/warehouse/index.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,16 +147,16 @@ docReady(() => {
147147
}
148148
});
149149

150-
// Bind click handlers to dropdowns for keyboard users
151-
docReady(() => {
152-
let dropdownTriggers = document.querySelectorAll(".dropdown__trigger");
153-
for (let trigger of dropdownTriggers) {
154-
let button = trigger.querySelector("button");
155-
let content = trigger.querySelector(".dropdown__content");
156-
157-
// If the user has clicked the button (either with a mouse or by pressing
150+
var bindDropdowns = function () {
151+
// Bind click handlers to dropdowns for keyboard users
152+
let dropdowns = document.querySelectorAll(".dropdown");
153+
for (let dropdown of dropdowns) {
154+
let trigger = dropdown.querySelector(".dropdown__trigger");
155+
let content = dropdown.querySelector(".dropdown__content");
156+
157+
// If the user has clicked the trigger (either with a mouse or by pressing
158158
// space/enter on the keyboard) show the content
159-
button.addEventListener("click", function () {
159+
trigger.addEventListener("click", function () {
160160
// Toggle the visibility of the content
161161
if (content.classList.contains("display-block")) {
162162
content.classList.remove("display-block");
@@ -165,14 +165,21 @@ docReady(() => {
165165
}
166166
});
167167

168-
// If the user has moused onto the button and has happened to click it,
168+
// If the user has moused onto the trigger and has happened to click it,
169169
// remove the `display-block` class so that it doesn't stay visable when
170170
// they mouse out
171-
button.addEventListener("mouseout", function() {
171+
trigger.addEventListener("mouseout", function() {
172172
content.classList.remove("display-block");
173173
});
174174
}
175-
});
175+
};
176+
177+
// Bind the dropdowns when the page is ready
178+
docReady(bindDropdowns);
179+
180+
// Bind again when client-side includes have been loaded (for the logged-in
181+
// user dropdown)
182+
document.addEventListener("CSILoaded", bindDropdowns);
176183

177184
const application = Application.start();
178185
const context = require.context("./controllers", true, /\.js$/);

warehouse/static/js/warehouse/utils/html-include.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,15 @@ export default () => {
4040
promises.push(p);
4141
});
4242

43-
// Once all of our HTML includes have fired, then we'll go ahead and record
44-
// the fact that our HTML includes have happened. This allows us to
45-
// introspect the state of our includes inside of our Selenium tests.
46-
Promise.all(promises).then(() => { window._WarehouseHTMLIncluded = true; });
43+
Promise.all(promises).then(() => {
44+
45+
// Once all of our HTML includes have fired, then we'll go ahead and record
46+
// the fact that our HTML includes have happened. This allows us to
47+
// introspect the state of our includes inside of our Selenium tests.
48+
window._WarehouseHTMLIncluded = true;
49+
50+
// Dispatch an event to any listeners that our CSI includes have loaded
51+
var event = new Event("CSILoaded");
52+
document.dispatchEvent(event);
53+
});
4754
};

warehouse/static/sass/blocks/_dropdown.scss

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
list-style-type: none;
4141
}
4242

43+
&:hover .dropdown__content {
44+
display: block;
45+
}
46+
4347
&__trigger {
4448
cursor: pointer;
4549
}
@@ -61,10 +65,6 @@
6165
display: none;
6266
}
6367

64-
&__trigger:hover .dropdown__content {
65-
display: block;
66-
}
67-
6868
&__link,
6969
button.dropdown__link {
7070
display: block;
@@ -78,7 +78,8 @@
7878
text-align: left;
7979
position: relative;
8080

81-
&:hover {
81+
&:hover,
82+
&:focus {
8283
background-color: $base-grey;
8384
color: $text-color;
8485
text-decoration: none;

warehouse/templates/includes/current-user-indicator.html

Lines changed: 66 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -15,64 +15,72 @@
1515
{% if request.user %}
1616
<div id="user-indicator" class="horizontal-menu horizontal-menu--light horizontal-menu--tall">
1717
<nav aria-label="Main navigation" class="dropdown dropdown--on-menu dropdown--with-icons">
18-
<ul>
19-
<li class="dropdown__trigger">
20-
<a href="#" class="horizontal-menu__link" aria-haspopup="true" aria-expanded="false">
21-
<span class="hide-on-mobile">Welcome back, </span>{{ request.user.username }}
22-
<span class="dropdown__trigger-caret">
23-
<i class="fa fa-caret-down" aria-hidden="true"></i>
24-
<span class="sr-only">view submenu</span>
25-
</span>
26-
</a>
27-
<ul class="dropdown__content">
28-
{% if request.has_permission("admin") %}
29-
<li>
30-
<a href="{{ request.route_path('admin.dashboard') }}" class="dropdown__link">
31-
<i class="fa fa-wrench" aria-hidden="true"></i>
32-
Admin
33-
</a>
34-
</li>
35-
{% endif %}
36-
<li>
37-
<a href="{{ request.route_path('manage.projects') }}" class="dropdown__link">
38-
<i class="fa fa-cube" aria-hidden="true"></i>
39-
Your Projects
40-
</a>
41-
</li>
42-
<li>
43-
<a href="{{ request.route_path('manage.account') }}" class="dropdown__link">
44-
<i class="fa fa-cog" aria-hidden="true"></i>
45-
Account Settings
46-
</a>
47-
</li>
48-
<li>
49-
<a href="{{ request.route_path('accounts.profile', username=request.user.username) }}" class="dropdown__link">
50-
<i class="fa fa-user-circle" aria-hidden="true"></i>
51-
Public Profile
52-
</a>
53-
</li>
54-
<li>
55-
<a href="{{ request.route_path('help') }}" class="dropdown__link">
56-
<i class="fa fa-question-circle" aria-hidden="true"></i>
57-
Get Help
58-
</a>
59-
</li>
60-
<li>
61-
<a href="https://donate.pypi.org" class="dropdown__link">
62-
<i class="fa fa-heart" aria-hidden="true"></i>
63-
Donate
64-
</a>
65-
</li>
66-
<li>
67-
<form method="POST" action="{{ request.route_path('accounts.logout') }}">
68-
<input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}">
69-
<button type="submit" value="log out" class="dropdown__link">
70-
<i class="fa fa-sign-out" aria-hidden="true"></i>
71-
Log Out
72-
</button>
73-
</form>
74-
</li>
75-
</ul>
18+
<button class="horizontal-menu__link dropdown__trigger" aria-haspopup="true" aria-expanded="false">
19+
<span class="hide-on-mobile">Welcome back, </span>{{ request.user.username }}
20+
<span class="dropdown__trigger-caret">
21+
<i class="fa fa-caret-down" aria-hidden="true"></i>
22+
<span class="sr-only">view submenu</span>
23+
</span>
24+
</button>
25+
<ul class="dropdown__content">
26+
{% if request.has_permission("admin") %}
27+
<li>
28+
<button class="dropdown__link">
29+
<a href="{{ request.route_path('admin.dashboard') }}" tabindex="-1">
30+
<i class="fa fa-wrench" aria-hidden="true"></i>
31+
Admin
32+
</a>
33+
</button>
34+
</li>
35+
{% endif %}
36+
<li>
37+
<button class="dropdown__link">
38+
<a href="{{ request.route_path('manage.projects') }}" tabindex="-1">
39+
<i class="fa fa-cube" aria-hidden="true"></i>
40+
Your Projects
41+
</a>
42+
</button>
43+
</li>
44+
<li>
45+
<button class="dropdown__link">
46+
<a href="{{ request.route_path('manage.account') }}" tabindex="-1">
47+
<i class="fa fa-cog" aria-hidden="true"></i>
48+
Account Settings
49+
</a>
50+
</button>
51+
</li>
52+
<li>
53+
<button class="dropdown__link">
54+
<a href="{{ request.route_path('accounts.profile', username=request.user.username) }}" tabindex="-1">
55+
<i class="fa fa-user-circle" aria-hidden="true"></i>
56+
Public Profile
57+
</a>
58+
</button>
59+
</li>
60+
<li>
61+
<button class="dropdown__link">
62+
<a href="{{ request.route_path('help') }}" tabindex="-1">
63+
<i class="fa fa-question-circle" aria-hidden="true"></i>
64+
Get Help
65+
</a>
66+
</button>
67+
</li>
68+
<li>
69+
<button class="dropdown__link">
70+
<a href="https://donate.pypi.org" tabindex="-1">
71+
<i class="fa fa-heart" aria-hidden="true"></i>
72+
Donate
73+
</a>
74+
</button>
75+
</li>
76+
<li>
77+
<form method="POST" action="{{ request.route_path('accounts.logout') }}">
78+
<input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}">
79+
<button type="submit" value="log out" class="dropdown__link">
80+
<i class="fa fa-sign-out" aria-hidden="true"></i>
81+
Log Out
82+
</button>
83+
</form>
7684
</li>
7785
</ul>
7886
</nav>

warehouse/templates/manage/account.html

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -67,53 +67,49 @@
6767
<td class="table__action">
6868
{% if not email.verified or user.emails|length > 1 and not email.primary%}
6969
<nav class="dropdown dropdown--with-icons dropdown--wide">
70-
<ul>
71-
<li class="dropdown__trigger">
72-
<button class="button button--primary" aria-haspopup="true" aria-expanded="false">
73-
Options
74-
<span class="dropdown__trigger-caret">
75-
<i class="fa fa-caret-down" aria-hidden="true"></i>
76-
<span class="sr-only">view submenu</span>
77-
</span>
78-
</button>
79-
<ul class="dropdown__content">
80-
<li>
81-
{% if not email.verified %}
82-
<form method="POST">
83-
<input hidden name="reverify_email_id" value="{{ email.id }}">
84-
<input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}">
85-
<button class="dropdown__link" type="submit" title="Resend verification email">
86-
<i class="fa fa-envelope" aria-hidden="true"></i>
87-
Resend Verification Email
88-
</button>
89-
</form>
90-
{% endif %}
91-
</li>
92-
<li>
93-
{% if not email.primary and email.verified %}
94-
<form method="POST">
95-
<input hidden name="primary_email_id" value="{{ email.id }}">
96-
<input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}">
97-
<button class="dropdown__link" type="submit" title="Set this email address as primary">
98-
<i class="fa fa-cog" aria-hidden="true"></i>
99-
Set as Primary
100-
</button>
101-
</form>
102-
{% endif %}
103-
</li>
104-
<li>
105-
{% if user.emails|length > 1 and not email.primary %}
106-
<form method="POST">
107-
<input hidden name="delete_email_id" value="{{ email.id }}">
108-
<input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}">
109-
<button class="dropdown__link" type="submit" title="Remove this email address">
110-
<i class="fa fa-trash" aria-hidden="true"></i>
111-
Remove Email
112-
</button>
113-
</form>
114-
{% endif %}
115-
</li>
116-
</ul>
70+
<button class="button button--primary dropdown__trigger" aria-haspopup="true" aria-expanded="false">
71+
Options
72+
<span class="dropdown__trigger-caret">
73+
<i class="fa fa-caret-down" aria-hidden="true"></i>
74+
<span class="sr-only">view submenu</span>
75+
</span>
76+
</button>
77+
<ul class="dropdown__content">
78+
<li>
79+
{% if not email.verified %}
80+
<form method="POST">
81+
<input hidden name="reverify_email_id" value="{{ email.id }}">
82+
<input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}">
83+
<button class="dropdown__link" type="submit" title="Resend verification email">
84+
<i class="fa fa-envelope" aria-hidden="true"></i>
85+
Resend Verification Email
86+
</button>
87+
</form>
88+
{% endif %}
89+
</li>
90+
<li>
91+
{% if not email.primary and email.verified %}
92+
<form method="POST">
93+
<input hidden name="primary_email_id" value="{{ email.id }}">
94+
<input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}">
95+
<button class="dropdown__link" type="submit" title="Set this email address as primary">
96+
<i class="fa fa-cog" aria-hidden="true"></i>
97+
Set as Primary
98+
</button>
99+
</form>
100+
{% endif %}
101+
</li>
102+
<li>
103+
{% if user.emails|length > 1 and not email.primary %}
104+
<form method="POST">
105+
<input hidden name="delete_email_id" value="{{ email.id }}">
106+
<input name="csrf_token" type="hidden" value="{{ request.session.get_csrf_token() }}">
107+
<button class="dropdown__link" type="submit" title="Remove this email address">
108+
<i class="fa fa-trash" aria-hidden="true"></i>
109+
Remove Email
110+
</button>
111+
</form>
112+
{% endif %}
117113
</li>
118114
</ul>
119115
</nav>

0 commit comments

Comments
 (0)