MDL-81608 quiz: Adjust size and spacing for the quiz edit page buttons
* In order to meet WCAG 2.2 criterion for minimum target size and make it easier for users who have mobility limitations to use the quiz editing page, we need to use the Bootstrap icon button styles and increase the size and the spacing for the following buttons: * Add/remove page break button * Lock/unlock question dependency button * This commit also makes the icons within the buttons as decorative and moves the accessible name to the button elements themselves via the aria-label attribute. * Adjust Behat tests for checking the dependency buttons. * Add accessibility Behat coverage for the quiz edit page.
This commit is contained in:
@@ -1001,9 +1001,21 @@ class edit_renderer extends \plugin_renderer_base {
|
||||
if (!$structure->can_be_edited()) {
|
||||
$disabled = 'disabled';
|
||||
}
|
||||
return html_writer::span($this->action_link($url, $image, null, ['title' => $title,
|
||||
'class' => 'page_split_join cm-edit-action', 'disabled' => $disabled, 'data-action' => $action]),
|
||||
'page_split_join_wrapper');
|
||||
return html_writer::span(
|
||||
$this->action_link(
|
||||
$url,
|
||||
$image,
|
||||
null,
|
||||
[
|
||||
'title' => $title,
|
||||
'aria-label' => $title,
|
||||
'class' => 'page_split_join cm-edit-action btn btn-sm icon-no-margin',
|
||||
'disabled' => $disabled,
|
||||
'data-action' => $action,
|
||||
]
|
||||
),
|
||||
'page_split_join_wrapper'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1021,13 +1033,11 @@ class edit_renderer extends \plugin_renderer_base {
|
||||
];
|
||||
if ($structure->is_question_dependent_on_previous_slot($slot)) {
|
||||
$title = get_string('questiondependencyremove', 'quiz', $a);
|
||||
$image = $this->pix_icon('t/locked', get_string('questiondependsonprevious', 'quiz'),
|
||||
'moodle', ['title' => '']);
|
||||
$image = $this->pix_icon('t/locked', '');
|
||||
$action = 'removedependency';
|
||||
} else {
|
||||
$title = get_string('questiondependencyadd', 'quiz', $a);
|
||||
$image = $this->pix_icon('t/unlocked', get_string('questiondependencyfree', 'quiz'),
|
||||
'moodle', ['title' => '']);
|
||||
$image = $this->pix_icon('t/unlocked', '');
|
||||
$action = 'adddependency';
|
||||
}
|
||||
|
||||
@@ -1040,9 +1050,22 @@ class edit_renderer extends \plugin_renderer_base {
|
||||
if (!$structure->can_question_depend_on_previous_slot($slot)) {
|
||||
$extraclass = ' question_dependency_cannot_depend';
|
||||
}
|
||||
return html_writer::span($this->action_link('#', $image, null, ['title' => $title,
|
||||
'class' => 'cm-edit-action', 'disabled' => $disabled, 'data-action' => $action]),
|
||||
'question_dependency_wrapper' . $extraclass);
|
||||
return html_writer::span(
|
||||
$this->action_link(
|
||||
'#',
|
||||
$image,
|
||||
null,
|
||||
[
|
||||
'title' => $title,
|
||||
'aria-label' => $title,
|
||||
'class' => 'cm-edit-action btn btn-link btn-sm icon-no-margin',
|
||||
'disabled' => $disabled,
|
||||
'data-action' => $action,
|
||||
'role' => 'button',
|
||||
]
|
||||
),
|
||||
'question_dependency_wrapper' . $extraclass
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -615,7 +615,7 @@ table.quizreviewsummary td.cell {
|
||||
|
||||
#page-mod-quiz-edit ul.section {
|
||||
margin: 0;
|
||||
padding: 0 20px;
|
||||
padding: 0 38px;
|
||||
}
|
||||
|
||||
#page-mod-quiz-edit ul.slots {
|
||||
@@ -688,8 +688,11 @@ table.quizreviewsummary td.cell {
|
||||
|
||||
#page-mod-quiz-edit ul.slots li.section li.activity .page_split_join_wrapper {
|
||||
position: absolute;
|
||||
left: -20px;
|
||||
bottom: -11px;
|
||||
left: -38px;
|
||||
bottom: -18px;
|
||||
.icon {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
#page-mod-quiz-edit ul.slots li.section li.activity .instancemaxmark.decimalplaces_0 {
|
||||
@@ -742,8 +745,8 @@ table.quizreviewsummary td.cell {
|
||||
|
||||
#page-mod-quiz-edit ul.slots li.section li.activity .question_dependency_wrapper {
|
||||
position: absolute;
|
||||
top: -1em;
|
||||
right: -20px;
|
||||
top: -1.25em;
|
||||
right: -38px;
|
||||
}
|
||||
|
||||
#page-mod-quiz-edit ul.slots li.section li.activity .question_dependency_wrapper.question_dependency_cannot_depend {
|
||||
|
||||
@@ -51,7 +51,7 @@ Feature: Edit quizzes where some questions require the previous one to have been
|
||||
| TF1 | 1 | 0 |
|
||||
| TF2 | 1 | 1 |
|
||||
And I am on the "Quiz 1" "mod_quiz > Edit" page
|
||||
Then "This question cannot be attempted until the previous question has been completed." "link" should be visible
|
||||
Then "Question 2 cannot be attempted until the previous question 1 has been completed" "button" should be visible
|
||||
|
||||
@javascript
|
||||
Scenario: A question can depend on a random question
|
||||
@@ -66,9 +66,9 @@ Feature: Edit quizzes where some questions require the previous one to have been
|
||||
| Random (Test questions) | 1 | 0 | Test questions |
|
||||
| TF1 | 1 | 1 | |
|
||||
And I am on the "Quiz 1" "mod_quiz > Edit" page
|
||||
Then "This question cannot be attempted until the previous question has been completed." "link" should be visible
|
||||
Then "Question 2 cannot be attempted until the previous question 1 has been completed" "button" should be visible
|
||||
|
||||
@javascript
|
||||
@javascript @accessibility
|
||||
Scenario: The second question can be set to depend on the first
|
||||
Given the following "activities" exist:
|
||||
| activity | name | intro | course | idnumber | preferredbehaviour |
|
||||
@@ -84,9 +84,10 @@ Feature: Edit quizzes where some questions require the previous one to have been
|
||||
| TF2 | 1 | 0 |
|
||||
| TF3 | 1 | 0 |
|
||||
And I am on the "Quiz 1" "mod_quiz > Edit" page
|
||||
When I follow "No restriction on when question 2 can be attempted • Click to change"
|
||||
Then "Question 2 cannot be attempted until the previous question 1 has been completed • Click to change" "link" should be visible
|
||||
And "No restriction on when question 3 can be attempted • Click to change" "link" should be visible
|
||||
When I click on "No restriction on when question 2 can be attempted • Click to change" "button"
|
||||
Then "Question 2 cannot be attempted until the previous question 1 has been completed • Click to change" "button" should be visible
|
||||
And "No restriction on when question 3 can be attempted • Click to change" "button" should be visible
|
||||
And the "region-main" "region" should meet accessibility standards with "best-practice" extra tests
|
||||
|
||||
@javascript
|
||||
Scenario: A question that did depend on the previous can be un-linked
|
||||
@@ -104,9 +105,9 @@ Feature: Edit quizzes where some questions require the previous one to have been
|
||||
| TF2 | 1 | 1 |
|
||||
| TF3 | 1 | 1 |
|
||||
And I am on the "Quiz 1" "mod_quiz > Edit" page
|
||||
When I follow "Question 3 cannot be attempted until the previous question 2 has been completed • Click to change"
|
||||
Then "Question 2 cannot be attempted until the previous question 1 has been completed • Click to change" "link" should be visible
|
||||
And "No restriction on when question 3 can be attempted • Click to change" "link" should be visible
|
||||
When I click on "Question 3 cannot be attempted until the previous question 2 has been completed • Click to change" "button"
|
||||
Then "Question 2 cannot be attempted until the previous question 1 has been completed • Click to change" "button" should be visible
|
||||
And "No restriction on when question 3 can be attempted • Click to change" "button" should be visible
|
||||
|
||||
@javascript
|
||||
Scenario: Question dependency cannot apply to deferred feedback quizzes so UI is hidden
|
||||
@@ -230,6 +231,6 @@ Feature: Edit quizzes where some questions require the previous one to have been
|
||||
| TF3 | 1 | 1 |
|
||||
And I am on the "Quiz 1" "mod_quiz > Edit" page
|
||||
When I move "TF1" to "After Question 3" in the quiz by clicking the move icon
|
||||
Then "Question 2 cannot be attempted until the previous question 1 has been completed • Click to change" "link" should be visible
|
||||
And "No restriction on when question 3 can be attempted • Click to change" "link" should be visible
|
||||
Then "Question 2 cannot be attempted until the previous question 1 has been completed • Click to change" "button" should be visible
|
||||
And "No restriction on when question 3 can be attempted • Click to change" "button" should be visible
|
||||
And "be attempted" "link" in the "TF2" "list_item" should not be visible
|
||||
|
||||
+2
-2
@@ -384,8 +384,8 @@ Y.extend(DRAGRESOURCE, M.core.dragdrop, {
|
||||
// Replace move icons
|
||||
var move = resourcesnode.one('a.' + CSS.EDITINGMOVE);
|
||||
if (move) {
|
||||
var resourcedraghandle = this.get_drag_handle(M.util.get_string('move', 'moodle'),
|
||||
CSS.EDITINGMOVE, CSS.ICONCLASS, true);
|
||||
var dragHandleClass = 'btn px-1 icon-no-margin ' + CSS.EDITINGMOVE;
|
||||
var resourcedraghandle = this.get_drag_handle(M.util.get_string('move', 'moodle'), dragHandleClass, CSS.ICONCLASS);
|
||||
move.replace(resourcedraghandle);
|
||||
}
|
||||
}, this);
|
||||
|
||||
+2
-2
File diff suppressed because one or more lines are too long
+2
-2
@@ -378,8 +378,8 @@ Y.extend(DRAGRESOURCE, M.core.dragdrop, {
|
||||
// Replace move icons
|
||||
var move = resourcesnode.one('a.' + CSS.EDITINGMOVE);
|
||||
if (move) {
|
||||
var resourcedraghandle = this.get_drag_handle(M.util.get_string('move', 'moodle'),
|
||||
CSS.EDITINGMOVE, CSS.ICONCLASS, true);
|
||||
var dragHandleClass = 'btn px-1 icon-no-margin ' + CSS.EDITINGMOVE;
|
||||
var resourcedraghandle = this.get_drag_handle(M.util.get_string('move', 'moodle'), dragHandleClass, CSS.ICONCLASS);
|
||||
move.replace(resourcedraghandle);
|
||||
}
|
||||
}, this);
|
||||
|
||||
+13
-14
@@ -345,11 +345,10 @@ Y.Moodle.mod_quiz.util.slot = {
|
||||
|
||||
// Update the link and image titles
|
||||
pagebreaklink.set('title', M.util.get_string(action, 'quiz'));
|
||||
pagebreaklink.set('aria-label', M.util.get_string(action, 'quiz'));
|
||||
pagebreaklink.setData('action', action);
|
||||
// Update the image title.
|
||||
var icon = pagebreaklink.one(this.SELECTORS.ICON);
|
||||
icon.set('title', M.util.get_string(action, 'quiz'));
|
||||
icon.set('alt', M.util.get_string(action, 'quiz'));
|
||||
|
||||
// Update the image src.
|
||||
icon.set('src', M.util.image_url(iconname));
|
||||
@@ -417,27 +416,27 @@ Y.Moodle.mod_quiz.util.slot = {
|
||||
requiresprevious = link.getData('action') === 'removedependency';
|
||||
}
|
||||
|
||||
var iconname = '';
|
||||
if (requiresprevious) {
|
||||
link.set('title', M.util.get_string('questiondependencyremove', 'quiz', a));
|
||||
link.set('aria-label', M.util.get_string('questiondependencyremove', 'quiz', a));
|
||||
link.setData('action', 'removedependency');
|
||||
window.require(['core/templates'], function(Templates) {
|
||||
Templates.renderPix('t/locked', 'core', M.util.get_string('questiondependsonprevious', 'quiz')).then(
|
||||
function(html) {
|
||||
icon.replace(html);
|
||||
}
|
||||
);
|
||||
});
|
||||
iconname = 't/locked';
|
||||
} else {
|
||||
link.set('title', M.util.get_string('questiondependencyadd', 'quiz', a));
|
||||
link.set('aria-label', M.util.get_string('questiondependencyadd', 'quiz', a));
|
||||
link.setData('action', 'adddependency');
|
||||
window.require(['core/templates'], function(Templates) {
|
||||
Templates.renderPix('t/unlocked', 'core', M.util.get_string('questiondependencyfree', 'quiz')).then(
|
||||
iconname = 't/unlocked';
|
||||
}
|
||||
window.require(['core/templates', 'core/notification'], function(Templates, Notification) {
|
||||
Templates.renderPix(iconname, 'core', '')
|
||||
.then(
|
||||
function(html) {
|
||||
icon.replace(html);
|
||||
return;
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
).catch(Notification.exception);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+13
-14
@@ -345,11 +345,10 @@ Y.Moodle.mod_quiz.util.slot = {
|
||||
|
||||
// Update the link and image titles
|
||||
pagebreaklink.set('title', M.util.get_string(action, 'quiz'));
|
||||
pagebreaklink.set('aria-label', M.util.get_string(action, 'quiz'));
|
||||
pagebreaklink.setData('action', action);
|
||||
// Update the image title.
|
||||
var icon = pagebreaklink.one(this.SELECTORS.ICON);
|
||||
icon.set('title', M.util.get_string(action, 'quiz'));
|
||||
icon.set('alt', M.util.get_string(action, 'quiz'));
|
||||
|
||||
// Update the image src.
|
||||
icon.set('src', M.util.image_url(iconname));
|
||||
@@ -417,27 +416,27 @@ Y.Moodle.mod_quiz.util.slot = {
|
||||
requiresprevious = link.getData('action') === 'removedependency';
|
||||
}
|
||||
|
||||
var iconname = '';
|
||||
if (requiresprevious) {
|
||||
link.set('title', M.util.get_string('questiondependencyremove', 'quiz', a));
|
||||
link.set('aria-label', M.util.get_string('questiondependencyremove', 'quiz', a));
|
||||
link.setData('action', 'removedependency');
|
||||
window.require(['core/templates'], function(Templates) {
|
||||
Templates.renderPix('t/locked', 'core', M.util.get_string('questiondependsonprevious', 'quiz')).then(
|
||||
function(html) {
|
||||
icon.replace(html);
|
||||
}
|
||||
);
|
||||
});
|
||||
iconname = 't/locked';
|
||||
} else {
|
||||
link.set('title', M.util.get_string('questiondependencyadd', 'quiz', a));
|
||||
link.set('aria-label', M.util.get_string('questiondependencyadd', 'quiz', a));
|
||||
link.setData('action', 'adddependency');
|
||||
window.require(['core/templates'], function(Templates) {
|
||||
Templates.renderPix('t/unlocked', 'core', M.util.get_string('questiondependencyfree', 'quiz')).then(
|
||||
iconname = 't/unlocked';
|
||||
}
|
||||
window.require(['core/templates', 'core/notification'], function(Templates, Notification) {
|
||||
Templates.renderPix(iconname, 'core', '')
|
||||
.then(
|
||||
function(html) {
|
||||
icon.replace(html);
|
||||
return;
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
).catch(Notification.exception);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -83,8 +83,8 @@ Y.extend(DRAGRESOURCE, M.core.dragdrop, {
|
||||
// Replace move icons
|
||||
var move = resourcesnode.one('a.' + CSS.EDITINGMOVE);
|
||||
if (move) {
|
||||
var resourcedraghandle = this.get_drag_handle(M.util.get_string('move', 'moodle'),
|
||||
CSS.EDITINGMOVE, CSS.ICONCLASS, true);
|
||||
var dragHandleClass = 'btn px-1 icon-no-margin ' + CSS.EDITINGMOVE;
|
||||
var resourcedraghandle = this.get_drag_handle(M.util.get_string('move', 'moodle'), dragHandleClass, CSS.ICONCLASS);
|
||||
move.replace(resourcedraghandle);
|
||||
}
|
||||
}, this);
|
||||
|
||||
+13
-14
@@ -343,11 +343,10 @@ Y.Moodle.mod_quiz.util.slot = {
|
||||
|
||||
// Update the link and image titles
|
||||
pagebreaklink.set('title', M.util.get_string(action, 'quiz'));
|
||||
pagebreaklink.set('aria-label', M.util.get_string(action, 'quiz'));
|
||||
pagebreaklink.setData('action', action);
|
||||
// Update the image title.
|
||||
var icon = pagebreaklink.one(this.SELECTORS.ICON);
|
||||
icon.set('title', M.util.get_string(action, 'quiz'));
|
||||
icon.set('alt', M.util.get_string(action, 'quiz'));
|
||||
|
||||
// Update the image src.
|
||||
icon.set('src', M.util.image_url(iconname));
|
||||
@@ -415,26 +414,26 @@ Y.Moodle.mod_quiz.util.slot = {
|
||||
requiresprevious = link.getData('action') === 'removedependency';
|
||||
}
|
||||
|
||||
var iconname = '';
|
||||
if (requiresprevious) {
|
||||
link.set('title', M.util.get_string('questiondependencyremove', 'quiz', a));
|
||||
link.set('aria-label', M.util.get_string('questiondependencyremove', 'quiz', a));
|
||||
link.setData('action', 'removedependency');
|
||||
window.require(['core/templates'], function(Templates) {
|
||||
Templates.renderPix('t/locked', 'core', M.util.get_string('questiondependsonprevious', 'quiz')).then(
|
||||
function(html) {
|
||||
icon.replace(html);
|
||||
}
|
||||
);
|
||||
});
|
||||
iconname = 't/locked';
|
||||
} else {
|
||||
link.set('title', M.util.get_string('questiondependencyadd', 'quiz', a));
|
||||
link.set('aria-label', M.util.get_string('questiondependencyadd', 'quiz', a));
|
||||
link.setData('action', 'adddependency');
|
||||
window.require(['core/templates'], function(Templates) {
|
||||
Templates.renderPix('t/unlocked', 'core', M.util.get_string('questiondependencyfree', 'quiz')).then(
|
||||
iconname = 't/unlocked';
|
||||
}
|
||||
window.require(['core/templates', 'core/notification'], function(Templates, Notification) {
|
||||
Templates.renderPix(iconname, 'core', '')
|
||||
.then(
|
||||
function(html) {
|
||||
icon.replace(html);
|
||||
return;
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
).catch(Notification.exception);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user