From f7cf98ea86fd35f13163394a5d7da276239c36bd Mon Sep 17 00:00:00 2001 From: Jun Pataleta Date: Thu, 29 Jan 2026 22:40:51 +0800 Subject: [PATCH] MDL-85902 course: Better labeling of activity navigation components * The arrow icons produced by the `$OUTPUT->larrow()` and `$OUTPUT->rarrow()` functions are announced by screen readers, and they do not make sense when heard by screen reader users. To fix this, we need to override the accessible names of the previous and next activity links using the `aria-label` attribute and specify whether the activity links point to the previous or next activities. * The label for the jump menu "Jump to" is not informative enough to convey the element's purpose. Let's improve it's accessible label to "Jump to activity". --- course/classes/output/activity_navigation.php | 8 +- .../tests/behat/activity_navigation.feature | 16 +-- course/templates/activity_navigation.mustache | 2 +- .../tests/behat/activity_navigation.feature | 104 +++++++++--------- ...ivity_navigation_with_restrictions.feature | 8 +- lang/en/course.php | 3 + 6 files changed, 73 insertions(+), 68 deletions(-) diff --git a/course/classes/output/activity_navigation.php b/course/classes/output/activity_navigation.php index 7412eaebbfa..8d0a78026d6 100644 --- a/course/classes/output/activity_navigation.php +++ b/course/classes/output/activity_navigation.php @@ -74,6 +74,7 @@ class activity_navigation implements renderable, templatable { $attributes = [ 'class' => 'btn btn-link', 'id' => 'prev-activity-link', + 'aria-label' => get_string('activitynavigation:preva', 'course', $linkname), ]; $this->prevlink = new \action_link($linkurl, $OUTPUT->larrow() . ' ' . $linkname, null, $attributes); } @@ -89,15 +90,16 @@ class activity_navigation implements renderable, templatable { $attributes = [ 'class' => 'btn btn-link', 'id' => 'next-activity-link', + 'aria-label' => get_string('activitynavigation:nexta', 'course', $linkname), ]; $this->nextlink = new \action_link($linkurl, $linkname . ' ' . $OUTPUT->rarrow(), null, $attributes); } // Render the activity list dropdown menu if available. if (!empty($activitylist)) { - $select = new url_select($activitylist, '', array('' => get_string('jumpto'))); - $select->set_label(get_string('jumpto'), array('class' => 'sr-only')); - $select->attributes = array('id' => 'jump-to-activity'); + $select = new url_select($activitylist, '', ['' => get_string('activitynavigation:jumptoactivity', 'course')]); + $select->set_label(get_string('activitynavigation:jumptoactivity', 'course'), ['class' => 'sr-only']); + $select->attributes = ['id' => 'jump-to-activity']; $this->activitylist = $select; } } diff --git a/course/format/singleactivity/tests/behat/activity_navigation.feature b/course/format/singleactivity/tests/behat/activity_navigation.feature index 0fae0c0ada0..e8941dc67f4 100644 --- a/course/format/singleactivity/tests/behat/activity_navigation.feature +++ b/course/format/singleactivity/tests/behat/activity_navigation.feature @@ -39,23 +39,23 @@ Feature: Activity navigation in a single activity course Scenario: Jump to a hidden activity as a teacher Given I log in as "teacher1" When I am on "Course 1" course homepage - Then "Jump to..." "field" should exist + Then "Jump to activity" "field" should exist # The current activity (Forum 1) will not be listed. - And the "Jump to..." select box should not contain "Forum 1" + And the "Jump to activity" select box should not contain "Forum 1" # Check drop down menu contents. - And the "Jump to..." select box should contain "Assignment 1 (hidden)" - And the "Jump to..." select box should contain "Lesson 1 (hidden)" + And the "Jump to activity" select box should contain "Assignment 1 (hidden)" + And the "Jump to activity" select box should contain "Lesson 1 (hidden)" # Jump to a hidden activity somewhere in the middle. - When I select "Assignment 1 (hidden)" from the "Jump to..." singleselect + When I select "Assignment 1 (hidden)" from the "Jump to activity" singleselect Then I should see "Assignment 1" And I should see "Forum 1" in the "#prev-activity-link" "css_element" And I should see "Lesson 1 (hidden)" in the "#next-activity-link" "css_element" # Jump to the first activity. - And I select "Forum 1" from the "Jump to..." singleselect + And I select "Forum 1" from the "Jump to activity" singleselect And I should see "Assignment 1 (hidden)" in the "#next-activity-link" "css_element" But "#prev-activity-link" "css_element" should not exist # Jump to the last activity. - And I select "Lesson 1 (hidden)" from the "Jump to..." singleselect + And I select "Lesson 1 (hidden)" from the "Jump to activity" singleselect And I should see "Assignment 1 (hidden)" in the "#prev-activity-link" "css_element" But "#next-activity-link" "css_element" should not exist @@ -65,7 +65,7 @@ Feature: Activity navigation in a single activity course # The first activity won't have the previous activity link. Then "#prev-activity-link" "css_element" should not exist And "#next-activity-link" "css_element" should not exist - And "Jump to..." "field" should not exist + And "Jump to activity" "field" should not exist Scenario: The activity navigation asks for login to guest user Given I log in as "guest" diff --git a/course/templates/activity_navigation.mustache b/course/templates/activity_navigation.mustache index e3e540babf6..d7f661d80ae 100644 --- a/course/templates/activity_navigation.mustache +++ b/course/templates/activity_navigation.mustache @@ -56,7 +56,7 @@ "id": "url_select_test", "action": "#", "options": [ - {"name": "Jump to...", "value": "#0"}, + {"name": "Jump to activity", "value": "#0"}, {"name": "Activity A", "value": "#1"}, {"name": "Activity B", "value": "#2"}, {"name": "Activity C", "value": "#3"} diff --git a/course/tests/behat/activity_navigation.feature b/course/tests/behat/activity_navigation.feature index ee8919ac662..47a84037b5c 100644 --- a/course/tests/behat/activity_navigation.feature +++ b/course/tests/behat/activity_navigation.feature @@ -191,49 +191,49 @@ Feature: Activity navigation Given I log in as "teacher1" When I am on "Course 1" course homepage And I follow "Assignment 1" - Then "Jump to..." "field" should exist + Then "Jump to activity" "field" should exist # The current activity will not be listed. - And the "Jump to..." select box should not contain "Assignment 1" + And the "Jump to activity" select box should not contain "Assignment 1" # Stealth activities will not be listed. - And the "Jump to..." select box should not contain "Forum 1" + And the "Jump to activity" select box should not contain "Forum 1" # Resources without view URL (e.g. labels) will not be listed. - And the "Jump to..." select box should not contain "Label 1" + And the "Jump to activity" select box should not contain "Label 1" # Check drop down menu contents. - And the "Jump to..." select box should contain "Book 1" - And the "Jump to..." select box should contain "Chat 1" - And the "Jump to..." select box should contain "Choice 1" - And the "Jump to..." select box should contain "Database 1" - And the "Jump to..." select box should contain "Feedback 1" - And the "Jump to..." select box should contain "Folder 1" - And the "Jump to..." select box should contain "Imscp 1" - And the "Jump to..." select box should contain "Lesson 1" - And the "Jump to..." select box should contain "Lti 1" - And the "Jump to..." select box should contain "Page 1" - And the "Jump to..." select box should contain "Quiz 1" - And the "Jump to..." select box should contain "Url 1" - And the "Jump to..." select box should contain "Wiki 1" - And the "Jump to..." select box should contain "Workshop 1" + And the "Jump to activity" select box should contain "Book 1" + And the "Jump to activity" select box should contain "Chat 1" + And the "Jump to activity" select box should contain "Choice 1" + And the "Jump to activity" select box should contain "Database 1" + And the "Jump to activity" select box should contain "Feedback 1" + And the "Jump to activity" select box should contain "Folder 1" + And the "Jump to activity" select box should contain "Imscp 1" + And the "Jump to activity" select box should contain "Lesson 1" + And the "Jump to activity" select box should contain "Lti 1" + And the "Jump to activity" select box should contain "Page 1" + And the "Jump to activity" select box should contain "Quiz 1" + And the "Jump to activity" select box should contain "Url 1" + And the "Jump to activity" select box should contain "Wiki 1" + And the "Jump to activity" select box should contain "Workshop 1" # Hidden activities will be rendered with a '(hidden)' text. - And the "Jump to..." select box should contain "Glossary 1 (hidden)" + And the "Jump to activity" select box should contain "Glossary 1 (hidden)" # Activities in hidden sections will be rendered with a '(hidden)' text. - And the "Jump to..." select box should contain "Resource 1 (hidden)" - And the "Jump to..." select box should contain "Scorm 1 (hidden)" - And the "Jump to..." select box should contain "Survey 1 (hidden)" + And the "Jump to activity" select box should contain "Resource 1 (hidden)" + And the "Jump to activity" select box should contain "Scorm 1 (hidden)" + And the "Jump to activity" select box should contain "Survey 1 (hidden)" # Jump to an activity somewhere in the middle. - When I select "Page 1" from the "Jump to..." singleselect + When I select "Page 1" from the "Jump to activity" singleselect Then I should see "Page 1" And I should see "Lti 1" in the "#prev-activity-link" "css_element" And I should see "Quiz 1" in the "#next-activity-link" "css_element" # Jump to the first activity. - And I select "Assignment 1" from the "Jump to..." singleselect + And I select "Assignment 1" from the "Jump to activity" singleselect And I should see "Book 1" in the "#next-activity-link" "css_element" But "#prev-activity-link" "css_element" should not exist # Jump to the last activity. - And I select "Workshop 1" from the "Jump to..." singleselect + And I select "Workshop 1" from the "Jump to activity" singleselect And I should see "Wiki 1" in the "#prev-activity-link" "css_element" But "#next-activity-link" "css_element" should not exist # Jump to a hidden activity. - And I select "Glossary 1" from the "Jump to..." singleselect + And I select "Glossary 1" from the "Jump to activity" singleselect And I should see "Folder 1" in the "#prev-activity-link" "css_element" And I should see "Imscp 1" in the "#next-activity-link" "css_element" @@ -241,45 +241,45 @@ Feature: Activity navigation Given I log in as "student1" And I am on "Course 1" course homepage And I follow "Assignment 1" - And "Jump to..." "field" should exist + And "Jump to activity" "field" should exist # The current activity will not be listed. - And the "Jump to..." select box should not contain "Assignment 1" + And the "Jump to activity" select box should not contain "Assignment 1" # Stealth activities will not be listed for students. - And the "Jump to..." select box should not contain "Forum 1" + And the "Jump to activity" select box should not contain "Forum 1" # Resources without view URL (e.g. labels) will not be listed. - And the "Jump to..." select box should not contain "Label 1" + And the "Jump to activity" select box should not contain "Label 1" # Hidden activities will not be listed for students. - And the "Jump to..." select box should not contain "Glossary 1" + And the "Jump to activity" select box should not contain "Glossary 1" # Activities in hidden sections will not be listed for students. - And the "Jump to..." select box should not contain "Resource 1" - And the "Jump to..." select box should not contain "Scorm 1" - And the "Jump to..." select box should not contain "Survey 1" + And the "Jump to activity" select box should not contain "Resource 1" + And the "Jump to activity" select box should not contain "Scorm 1" + And the "Jump to activity" select box should not contain "Survey 1" # Only activities visible to students will be listed. - And the "Jump to..." select box should contain "Book 1" - And the "Jump to..." select box should contain "Chat 1" - And the "Jump to..." select box should contain "Choice 1" - And the "Jump to..." select box should contain "Database 1" - And the "Jump to..." select box should contain "Feedback 1" - And the "Jump to..." select box should contain "Folder 1" - And the "Jump to..." select box should contain "Imscp 1" - And the "Jump to..." select box should contain "Lesson 1" - And the "Jump to..." select box should contain "Lti 1" - And the "Jump to..." select box should contain "Page 1" - And the "Jump to..." select box should contain "Quiz 1" - And the "Jump to..." select box should contain "Url 1" - And the "Jump to..." select box should contain "Wiki 1" - And the "Jump to..." select box should contain "Workshop 1" + And the "Jump to activity" select box should contain "Book 1" + And the "Jump to activity" select box should contain "Chat 1" + And the "Jump to activity" select box should contain "Choice 1" + And the "Jump to activity" select box should contain "Database 1" + And the "Jump to activity" select box should contain "Feedback 1" + And the "Jump to activity" select box should contain "Folder 1" + And the "Jump to activity" select box should contain "Imscp 1" + And the "Jump to activity" select box should contain "Lesson 1" + And the "Jump to activity" select box should contain "Lti 1" + And the "Jump to activity" select box should contain "Page 1" + And the "Jump to activity" select box should contain "Quiz 1" + And the "Jump to activity" select box should contain "Url 1" + And the "Jump to activity" select box should contain "Wiki 1" + And the "Jump to activity" select box should contain "Workshop 1" # Jump to an activity somewhere in the middle. - When I select "Page 1" from the "Jump to..." singleselect + When I select "Page 1" from the "Jump to activity" singleselect Then I should see "Page 1" And I should see "Lti 1" in the "#prev-activity-link" "css_element" And I should see "Quiz 1" in the "#next-activity-link" "css_element" # Jump to the first activity. - And I select "Assignment 1" from the "Jump to..." singleselect + And I select "Assignment 1" from the "Jump to activity" singleselect And I should see "Book 1" in the "#next-activity-link" "css_element" But "#prev-activity-link" "css_element" should not exist # Jump to the last activity. - And I select "Workshop 1" from the "Jump to..." singleselect + And I select "Workshop 1" from the "Jump to activity" singleselect And I should see "Wiki 1" in the "#prev-activity-link" "css_element" But "#next-activity-link" "css_element" should not exist @@ -289,4 +289,4 @@ Feature: Activity navigation And I follow "Assignment 1" Then "#prev-activity-link" "css_element" should not exist And "#next-activity-link" "css_element" should not exist - And "Jump to..." "field" should not exist + And "Jump to activity" "field" should not exist diff --git a/course/tests/behat/activity_navigation_with_restrictions.feature b/course/tests/behat/activity_navigation_with_restrictions.feature index 05f0c90fab6..695292ecff5 100644 --- a/course/tests/behat/activity_navigation_with_restrictions.feature +++ b/course/tests/behat/activity_navigation_with_restrictions.feature @@ -48,13 +48,13 @@ Feature: Activity navigation involving activities with access restrictions Given I am on the "Page 1" "page activity" page logged in as student1 Then I should see "Page 2" in the "#next-activity-link" "css_element" # Activity that has access restriction should not show up in the dropdown. - And the "Jump to..." select box should not contain "Page 3" - And I select "Page 4" from the "Jump to..." singleselect + And the "Jump to activity" select box should not contain "Page 3" + And I select "Page 4" from the "Jump to activity" singleselect # Page 2 should be shown in the previous link since Page 3 is not yet available. And I should see "Page 2" in the "#prev-activity-link" "css_element" - And the "Jump to..." select box should not contain "Page 3" + And the "Jump to activity" select box should not contain "Page 3" # Navigate to Page 2. And I click on "Page 2" "link" in the "page-content" "region" # Since Page 2 has now been viewed and deemed completed, Page 3 can now be accessed. And I should see "Page 3" in the "#next-activity-link" "css_element" - And the "Jump to..." select box should contain "Page 3" + And the "Jump to activity" select box should contain "Page 3" diff --git a/lang/en/course.php b/lang/en/course.php index f86e6bf3905..da6ec16457a 100644 --- a/lang/en/course.php +++ b/lang/en/course.php @@ -41,6 +41,9 @@ $string['activitydate:closes'] = 'Closes:'; $string['activitydate:opened'] = 'Opened:'; $string['activitydate:opens'] = 'Opens:'; $string['activitynavigation'] = 'Activity navigation'; +$string['activitynavigation:jumptoactivity'] = 'Jump to activity'; +$string['activitynavigation:nexta'] = 'Next activity: {$a}'; +$string['activitynavigation:preva'] = 'Previous activity: {$a}'; $string['aria:coursecategory'] = 'Course category'; $string['aria:courseshortname'] = 'Course short name'; $string['aria:coursename'] = 'Course name';