8000 Fixed #34917 -- Add an underline to the 'a' tags in the main content … · django/django@53f4bf9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 53f4bf9

Browse files
committed
Fixed #34917 -- Add an underline to the 'a' tags in the main content area of the admin.
1 parent ea1e370 commit 53f4bf9

30 files changed

+50
-33
lines changed

django/contrib/admin/static/admin/css/base.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@ a:focus {
118118
text-decoration: underline;
119119
}
120120

121+
a:not(
122+
[role="button"],
123+
#header a,
124+
#nav-sidebar a,
125+
#content-main.app-list a
126+
) {
127+
text-decoration: underline;
128+
}
129+
121130
a img {
122131
border: none;
123132
}

django/contrib/admin/static/admin/js/admin/DateTimeShortcuts.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
const now_link = document.createElement('a');
109109
now_link.href = "#";
110110
now_link.textContent = gettext('Now');
111+
now_link.role = 'button';
111112
now_link.addEventListener('click', function(e) {
112113
e.preventDefault();
113114
DateTimeShortcuts.handleClockQuicklink(num, -1);
@@ -163,7 +164,7 @@
163164
// where name is the name attribute of the <input>.
164165
const name = typeof DateTimeShortcuts.clockHours[inp.name] === 'undefined' ? 'default_' : inp.name;
165166
DateTimeShortcuts.clockHours[name].forEach(function(element) {
166-
const time_link = quickElement('a', quickElement('li', time_list), gettext(element[0]), 'href', '#');
167+
const time_link = quickElement('a', quickElement('li', time_list), gettext(element[0]), 'role', 'button', 'href', '#');
167168
time_link.addEventListener('click', function(e) {
168169
e.preventDefault();
169170
DateTimeShortcuts.handleClockQuicklink(num, element[1]);
@@ -172,7 +173,7 @@
172173

173174
const cancel_p = quickElement('p', clock_box);
174175
cancel_p.className = 'calendar-cancel';
175-
const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#');
176+
const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'role', 'button', 'href', '#');
176177
cancel_link.addEventListener('click', function(e) {
177178
e.preventDefault();
178179
DateTimeShortcuts.dismissClock(num);
@@ -235,6 +236,7 @@
235236
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
236237
const today_link = document.createElement('a');
237238
today_link.href = '#';
239+
today_link.role = 'button';
238240
today_link.appendChild(document.createTextNode(gettext('Today')));
239241
today_link.addEventListener('click', function(e) {
240242
e.preventDefault();
@@ -309,19 +311,19 @@
309311
// calendar shortcuts
310312
const shortcuts = quickElement('div', cal_box);
311313
shortcuts.className = 'calendar-shortcuts';
312-
let day_link = quickElement('a', shortcuts, gettext('Yesterday'), 'href', '#');
314+
let day_link = quickElement('a', shortcuts, gettext('Yesterday'), 'role', 'button', 'href', '#');
313315
day_link.addEventListener('click', function(e) {
314316
e.preventDefault();
315317
DateTimeShortcuts.handleCalendarQuickLink(num, -1);
316318
});
317319
shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0'));
318-
day_link = quickElement('a', shortcuts, gettext('Today'), 'href', '#');
320+
day_link = quickElement('a', shortcuts, gettext('Today'), 'role', 'button', 'href', '#');
319321
day_link.addEventListener('click', function(e) {
320322
e.preventDefault();
321323
DateTimeShortcuts.handleCalendarQuickLink(num, 0);
322324
});
323325
shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0'));
324-
day_link = quickElement('a', shortcuts, gettext('Tomorrow'), 'href', '#');
326+
day_link = quickElement('a', shortcuts, gettext('Tomorrow'), 'role', 'button', 'href', '#');
325327
day_link.addEventListener('click', function(e) {
326328
e.preventDefault();
327329
DateTimeShortcuts.handleCalendarQuickLink(num, +1);
@@ -330,7 +332,7 @@
330332
// cancel bar
331333
const cancel_p = quickElement('p', cal_box);
332334
cancel_p.className = 'calendar-cancel';
333-
const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#');
335+
const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'role', 'button', 'href', '#');
334336
cancel_link.addEventListener('click', function(e) {
335337
e.preventDefault();
336338
DateTimeShortcuts.dismissCalendar(num);

django/contrib/admin/static/admin/js/calendar.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ depends on core.js for utility functions like removeChildren or quickElement
160160
}
161161

162162
const cell = quickElement('td', tableRow, '', 'class', todayClass);
163-
const link = quickElement('a', cell, currentDay, 'href', '#');
163+
const link = quickElement('a', cell, currentDay, 'role', 'button', 'href', '#');
164164
link.addEventListener('click', calendarMonth(year, month));
165165
currentDay++;
166166
}

django/contrib/admin/templates/admin/change_form_object_tools.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{% block object-tools-items %}
33
<li>
44
{% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
5-
<a href="{% add_preserved_filters history_url %}" class="historylink">{% translate "History" %}</a>
5+
<a role="button" href="{% add_preserved_filters history_url %}" class="historylink">{% translate "History" %}</a>
66
</li>
77
{% if has_absolute_url %}<li><a href="{{ absolute_url }}" class="viewsitelink">{% translate "View on site" %}</a></li>{% endif %}
88
{% endblock %}

django/contrib/admin/templates/admin/change_list_object_tools.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{% if has_add_permission %}
55
<li>
66
{% url cl.opts|admin_urlname:'add' as add_url %}
7-
<a href="{% add_preserved_filters add_url is_popup to_field %}" class="addlink">
7+
<a role="button" href="{% add_preserved_filters add_url is_popup to_field %}" class="addlink">
88
{% blocktranslate with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktranslate %}
99
</a>
1010
</li>

django/contrib/admin/templates/admin/change_list_results.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<a href="{{ header.url_toggle }}" class="toggle {{ header.ascending|yesno:'ascending,descending' }}" title="{% translate "Toggle sorting" %}"></a>
1919
</div>
2020
{% endif %}
21-
<div class="text">{% if header.sortable %}<a href="{{ header.url_primary }}">{{ header.text|capfirst }}</a>{% else %}<span>{{ header.text|capfirst }}</span>{% endif %}</div>
21+
<div class="text">{% if header.sortable %}<a role="button"href="{{ header.url_primary }}">{{ header.text|capfirst }}</a>{% else %}<span>{{ header.text|capfirst }}</span>{% endif %}</div>
2222
<div class="clear"></div>
2323
</th>{% endfor %}
2424
</tr>

django/contrib/admin/templates/admin/delete_confirmation.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ <h2>{% translate "Objects" %}</h2>
4242
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1">{% endif %}
4343
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}">{% endif %}
4444
<input type="submit" value="{% translate 'Yes, I’m sure' %}">
45-
<a href="#" class="button cancel-link">{% translate "No, take me back" %}</a>
45+
<a role="button" href="#" class="button cancel-link">{% translate "No, take me back" %}</a>
4646
</div>
4747
</form>
4848
{% endblock %}

django/contrib/admin/templates/admin/delete_selected_confirmation.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ <h2>{% translate "Objects" %}</h2>
4040
<input type="hidden" name="action" value="delete_selected">
4141
<input type="hidden" name="post" value="yes">
4242
<input type="submit" value="{% translate 'Yes, I’m sure' %}">
43-
<a href="#" class="button cancel-link">{% translate "No, take me back" %}</a>
43+
<a role="button" href="#" class="button cancel-link">{% translate "No, take me back" %}</a>
4444
</div>
4545
</form>
4646
{% endif %}

django/contrib/admin/templates/admin/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
{% block nav-sidebar %}{% endblock %}
1313

1414
{% block content %}
15-
<div id="content-main">
15+
<div id="content-main" class="app-list">
1616
{% include "admin/app_list.html" with app_list=app_list show_changelinks=True %}
1717
</div>
1818
{% endblock %}

django/contrib/admin/templates/admin/object_history.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
{% elif i == action_list.number %}
4343
<span class="this-page">{{ i }}</span>
4444
{% else %}
45-
<a href="?{{ page_var }}={{ i }}" {% if i == action_list.paginator.num_pages %} class="end" {% endif %}>{{ i }}</a>
45+
<a role="button" href="?{{ page_var }}={{ i }}" {% if i == action_list.paginator.num_pages %} class="end" {% endif %}>{{ i }}</a>
4646
{% endif %}
4747
{% endfor %}
4848
{% endif %}

django/contrib/admin/templates/admin/submit_line.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
{% if show_save_and_continue %}<input type="submit" value="{% if can_change %}{% translate 'Save and continue editing' %}{% else %}{% translate 'Save and view' %}{% endif %}" name="_continue">{% endif %}
88
{% if show_close %}
99
{% url opts|admin_urlname:'changelist' as changelist_url %}
10-
<a href="{% add_preserved_filters changelist_url %}" class="closelink">{% translate 'Close' %}</a>
10+
<a role="button" href="{% add_preserved_filters changelist_url %}" class="closelink">{% translate 'Close' %}</a>
1111
{% endif %}
1212
{% if show_delete_link and original %}
1313
{% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url %}
14-
<a href="{% add_preserved_filters delete_url %}" class="deletelink">{% translate "Delete" %}</a>
14+
<a role="button" href="{% add_preserved_filters delete_url %}" class="deletelink">{% translate "Delete" %}</a>
1515
{% endif %}
1616
{% endblock %}
1717
</div>

django/contrib/admin/templatetags/admin_list.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def paginator_number(cl, i):
4545
return format_html('<span class="this-page">{}</span> ', i)
4646
else:
4747
return format_html(
48-
'<a href="{}"{}>{}</a> ',
48+
'<a role="button" href="{}"{}>{}</a> ',
4949
cl.get_query_string({PAGE_VAR: i}),
5050
mark_safe(' class="end"' if i == cl.paginator.num_pages else ""),
5151
i,

django/contrib/auth/templates/auth/widgets/read_only_password_hash.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
<strong>{{ entry.label }}</strong>{% if entry.value %}: <bdi>{{ entry.value }}</bdi>{% endif %}
55
{% endfor %}
66
</p>
7-
<p><a class="button" href="{{ password_url|default:"../password/" }}">{{ button_label }}</a></p>
7+
<p><a role="button" class="button" href="{{ password_url|default:"../password/" }}">{{ button_label }}</a></p>
88
</div>

docs/intro/_images/admin04t.png

34.6 KB
Loading

docs/intro/_images/admin05t.png

64.8 KB
Loading

docs/intro/_images/admin07.png

38 KB
Loading

docs/intro/_images/admin08t.png

35.7 KB
Loading

docs/intro/_images/admin10t.png

67.4 KB
Loading

docs/intro/_images/admin11t.png

25.5 KB
Loading

docs/intro/_images/admin12t.png

33.1 KB
Loading

docs/intro/_images/admin13t.png

53.4 KB
Loading

docs/intro/_images/admin14t.png

53.7 KB
Loading
Loading
Loading
50.1 KB
Loading
Loading

tests/admin_inlines/tests.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,12 +1454,13 @@ def test_submit_line_shows_only_close_button(self):
14541454
response = self.client.get(self.change_url)
14551455
self.assertContains(
14561456
response,
1457-
'<a href="/admin/admin_inlines/poll/" class="closelink">Close</a>',
1457+
'<a role="button" href="/admin/admin_inlines/poll/" class="closelink">'
1458+
"Close</a>",
14581459
html=True,
14591460
)
14601461
delete_link = (
1461-
'<a href="/admin/admin_inlines/poll/%s/delete/" class="deletelink">Delete'
1462-
"</a>"
1462+
'<a role="button" href="/admin/admin_inlines/poll/%s/delete/" '
1463+
'class="deletelink">Delete</a>'
14631464
)
14641465
self.assertNotContains(response, delete_link % self.poll.id, html=True)
14651466
self.assertNotContains(

tests/admin_views/tests.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2683,8 +2683,8 @@ def test_change_view(self):
26832683
self.assertContains(response, "<label>Extra form field:</label>")
26842684
self.assertContains(
26852685
response,
2686-
'<a href="/test_admin/admin/admin_views/article/" class="closelink">Close'
2687-
"</a>",
2686+
'<a role="button" href="/test_admin/admin/admin_views/article/" '
2687+
'class="closelink">Close</a>',
26882688
)
26892689
self.assertEqual(response.context["title"], "View article")
26902690
post = self.client.post(article_change_url, change_dict)
@@ -2835,8 +2835,8 @@ def test_change_view_without_object_change_permission(self):
28352835
self.assertContains(response, "<h1>View article</h1>")
28362836
self.assertContains(
28372837
response,
2838-
'<a href="/test_admin/admin9/admin_views/article/" class="closelink">Close'
2839-
"</a>",
2838+
'<a role="button" href="/test_admin/admin9/admin_views/article/" '
2839+
'class="closelink">Close</a>',
28402840
)
28412841

28422842
def test_change_view_save_as_new(self):
@@ -4059,7 +4059,8 @@ def test_change_view_history_link(self):
40594059
args=(quote(self.pk),),
40604060
)
40614061
self.assertContains(
4062-
response, '<a href="%s" class="historylink"' % escape(expected_link)
4062+
response,
4063+
'<a role="button" href="%s" class="historylink"' % escape(expected_link),
40634064
)
40644065

40654066
def test_redirect_on_add_view_continue_button(self):
@@ -8309,13 +8310,14 @@ def test_change_view(self):
83098310

83108311
# Check the history link.
83118312
history_link = re.search(
8312-
'<a href="(.*?)" class="historylink">History</a>', response.text
8313+
'<a role="button" href="(.*?)" class="historylink">History</a>',
8314+
response.text,
83138315
)
83148316
self.assertURLEqual(history_link[1], self.get_history_url())
83158317

83168318
# Check the delete link.
83178319
delete_link = re.search(
8318-
'<a href="(.*?)" class="deletelink">Delete</a>', response.text
8320+
'<a role="button" href="(.*?)" class="deletelink">Delete</a>', response.text
83198321
)
83208322
self.assertURLEqual(delete_link[1], self.get_delete_url())
83218323

@@ -8355,7 +8357,7 @@ def test_change_view_close_link(self):
83558357
self.client.force_login(viewuser)
83568358
response = self.client.get(self.get_change_url())
83578359
close_link = re.search(
8358-
'<a href="(.*?)" class="closelink">Close</a>', response.text
8360+
'<a role="button" href="(.*?)" class="closelink">Close</a>', response.text
83598361
)
83608362
close_link = close_link[1].replace("&amp;", "&")
83618363
self.assertURLEqual(close_link, self.get_changelist_url())

tests/auth_tests/test_forms.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,9 @@ def test_link_to_password_reset_in_user_change_form(self):
10891089
"Set password",
10901090
),
10911091
]
1092-
password_reset_link = r'<a class="button" href="([^"]*)">([^<]*)</a>'
1092+
password_reset_link = (
1093+
r'<a role="button" class="button" href="([^"]*)">([^<]*)</a>'
1094+
)
10931095
for username, expected_help_text, expected_button_label in cases:
10941096
with self.subTest(username=username):
10951097
user = User.objects.get(username=username)
@@ -1438,7 +1440,8 @@ def test_render(self):
14381440
" <strong>hash</strong>: "
14391441
" <bdi>WmCkn9**************************************</bdi>"
14401442
" </p>"
1441-
' <p><a class="button" href="../password/">Reset password</a></p>'
1443+
' <p><a role="button" class="button" href="../password/">'
1444+
"Reset password</a></p>"
14421445
"</div>",
14431446
)
14441447

tests/auth_tests/test_views.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,7 +1532,7 @@ def test_user_with_usable_password_change_password(self):
15321532
response = self.client.get(user_change_url)
15331533
# Test the link inside password field help_text.
15341534
rel_link = re.search(
1535-
r'<a class="button" href="([^"]*)">Reset password</a>',
1535+
r'<a role="button" class="button" href="([^"]*)">Reset password</a>',
15361536
response.text,
15371537
)[1]
15381538
self.assertEqual(urljoin(user_change_url, rel_link), password_change_url)
@@ -1628,7 +1628,7 @@ def test_user_with_unusable_password_change_password(self):
16281628
response = self.client.get(user_change_url)
16291629
# Test the link inside password field help_text.
16301630
rel_link = re.search(
1631-
r'<a class="button" href="([^"]*)">Set password</a>',
1631+
r'<a role="button" class="button" href="([^"]*)">Set password</a>',
16321632
response.text,
16331633
)[1]
16341634
self.assertEqual(urljoin(user_change_url, rel_link), password_change_url)

0 commit comments

Comments
 (0)
0