Merge branch 'MDL-76597-401-2' of https://github.com/junpataleta/moodle into MOODLE_401_STABLE

This commit is contained in:
Jake Dallimore 2023-01-11 10:12:08 +08:00
commit 5123d2bf53
9 changed files with 116 additions and 24 deletions

View File

@ -367,7 +367,7 @@ class edit_renderer extends \plugin_renderer_base {
if ($structure->get_section_count() == 1) {
$class .= ' only-one-section';
}
return html_writer::start_tag('ul', array('class' => $class));
return html_writer::start_tag('ul', array('class' => $class, 'role' => 'presentation'));
}
/**
@ -394,24 +394,32 @@ class edit_renderer extends \plugin_renderer_base {
$sectionstyle = ' only-has-one-slot';
}
if ($section->heading) {
$sectionheadingtext = format_string($section->heading);
$sectionheading = html_writer::span($sectionheadingtext, 'instancesection');
} else {
// Use a sr-only default section heading, so we don't end up with an empty section heading.
$sectionheadingtext = get_string('sectionnoname', 'quiz');
$sectionheading = html_writer::span($sectionheadingtext, 'instancesection sr-only');
}
$output .= html_writer::start_tag('li', array('id' => 'section-'.$section->id,
'class' => 'section main clearfix'.$sectionstyle, 'role' => 'region',
'aria-label' => $section->heading));
'class' => 'section main clearfix'.$sectionstyle, 'role' => 'presentation',
'data-sectionname' => $sectionheadingtext));
$output .= html_writer::start_div('content');
$output .= html_writer::start_div('section-heading');
$headingtext = $this->heading(html_writer::span(
html_writer::span($section->heading, 'instancesection'), 'sectioninstance'), 3);
$headingtext = $this->heading(html_writer::span($sectionheading, 'sectioninstance'), 3);
if (!$structure->can_be_edited()) {
$editsectionheadingicon = '';
} else {
$editsectionheadingicon = html_writer::link(new \moodle_url('#'),
$this->pix_icon('t/editstring', get_string('sectionheadingedit', 'quiz', $section->heading),
$this->pix_icon('t/editstring', get_string('sectionheadingedit', 'quiz', $sectionheadingtext),
'moodle', array('class' => 'editicon visibleifjs')),
array('class' => 'editing_section', 'data-action' => 'edit_section_title'));
array('class' => 'editing_section', 'data-action' => 'edit_section_title', 'role' => 'button'));
}
$output .= html_writer::div($headingtext . $editsectionheadingicon, 'instancesectioncontainer');
@ -482,7 +490,7 @@ class edit_renderer extends \plugin_renderer_base {
* @return string HTML to output.
*/
public function section_remove_icon($section) {
$title = get_string('sectionheadingremove', 'quiz', $section->heading);
$title = get_string('sectionheadingremove', 'quiz', format_string($section->heading));
$url = new \moodle_url('/mod/quiz/edit.php',
array('sesskey' => sesskey(), 'removesection' => '1', 'sectionid' => $section->id));
$image = $this->pix_icon('t/delete', $title);
@ -776,12 +784,15 @@ class edit_renderer extends \plugin_renderer_base {
* @return string HTML to output.
*/
public function get_checkbox_render(structure $structure, int $slot) : string {
$questionslot = $structure->get_displayed_number_for_slot($slot);
$checkbox = new \core\output\checkbox_toggleall($this->togglegroup, false,
[
'id' => 'selectquestion-' . $structure->get_displayed_number_for_slot($slot),
'id' => 'selectquestion-' . $questionslot,
'name' => 'selectquestion[]',
'value' => $structure->get_displayed_number_for_slot($slot),
'value' => $questionslot,
'classes' => 'select-multiple-checkbox',
'label' => get_string('selectquestionslot', 'quiz', $questionslot),
'labelclasses' => 'sr-only',
]);
return $this->render($checkbox);
@ -1232,6 +1243,7 @@ class edit_renderer extends \plugin_renderer_base {
'numquestionsx',
'sectionheadingedit',
'sectionheadingremove',
'sectionnoname',
'removepagebreak',
'questiondependencyadd',
'questiondependencyfree',

View File

@ -930,6 +930,7 @@ $string['selectedattempts'] = 'Selected attempts...';
$string['selectmultipleitems'] = 'Select multiple items';
$string['selectmultipletoolbar'] = 'Select multiple toolbar';
$string['selectnone'] = 'Deselect all';
$string['selectquestionslot'] = 'Select question {$a}';
$string['selectquestiontype'] = '-- Select question type --';
$string['serveradded'] = 'Server added';
$string['serveridentifier'] = 'Identifier';

View File

@ -609,7 +609,7 @@ table.quizreviewsummary td.cell {
#page-mod-quiz-edit .section-heading .instancesectioncontainer h3 {
display: inline;
color: #999;
color: #555;
}
#page-mod-quiz-edit .section-heading .editing_section,

View File

@ -36,7 +36,7 @@
</div>
<span class="actions">
{{#versionselection}}
<label for="version-{{slotid}}"> </label>
<label for="version-{{slotid}}" class="sr-only">{{#str}}question_version, question{{/str}}</label>
<select id="version-{{slotid}}" name="version" class="form-control mr-2 h-auto version-selection"
data-action="mod_quiz-select_slot" data-slot-id="{{slotid}}">
{{#versionoption}}

View File

@ -676,6 +676,10 @@ class behat_mod_quiz extends behat_question_base {
* @param string $sectionheading the new heading to set.
*/
public function i_set_the_section_heading_for($sectionname, $sectionheading) {
// Empty section headings will have a default names of "Untitled heading".
if (empty($sectionname)) {
$sectionname = get_string('sectionnoname', 'quiz');
}
$this->execute('behat_general::click_link', $this->escape("Edit heading '{$sectionname}'"));
$this->execute('behat_general::assert_page_contains_text', $this->escape(get_string('edittitleinstructions')));

View File

@ -929,7 +929,7 @@ Y.extend(SECTIONTOOLBOX, TOOLBOX, {
// Create the confirmation dialogue.
var confirm = new M.core.confirm({
question: M.util.get_string('confirmremovesectionheading', 'quiz', activity.get('aria-label')),
question: M.util.get_string('confirmremovesectionheading', 'quiz', activity.getData('sectionname')),
modal: true
});
@ -1027,7 +1027,18 @@ Y.extend(SECTIONTOOLBOX, TOOLBOX, {
var spinner = M.util.add_spinner(Y, activity.one(SELECTOR.INSTANCESECTIONAREA));
this.edit_section_title_clear(activity);
if (newtext !== null && newtext !== oldtext) {
activity.one(SELECTOR.INSTANCESECTION).setContent(newtext);
var instancesection = activity.one(SELECTOR.INSTANCESECTION);
var instancesectiontext = newtext;
if (newtext.trim() === '') {
// Add a sr-only default section heading text to make sure we don't end up with an empty section heading.
instancesectiontext = M.util.get_string('sectionnoname', 'quiz');
instancesection.addClass('sr-only');
} else {
// Show the section heading when a non-empty value is set.
instancesection.removeClass('sr-only');
}
instancesection.setContent(instancesectiontext);
var data = {
'class': 'section',
'field': 'updatesectiontitle',
@ -1036,7 +1047,21 @@ Y.extend(SECTIONTOOLBOX, TOOLBOX, {
};
this.send_request(data, spinner, function(response) {
if (response) {
activity.one(SELECTOR.INSTANCESECTION).setContent(response.instancesection);
// Set the content of the section heading if for some reason the response is different from the new text.
// e.g. filters were applied, the update failed, etc.
if (newtext !== response.instancesection) {
if (response.instancesection.trim() === '') {
// Add a sr-only default section heading text.
instancesectiontext = M.util.get_string('sectionnoname', 'quiz');
instancesection.addClass('sr-only');
} else {
instancesectiontext = response.instancesection;
// Show the section heading when a non-empty value is set.
instancesection.removeClass('sr-only');
}
instancesection.setContent(instancesectiontext);
}
activity.one(SELECTOR.EDITSECTIONICON).set('title',
M.util.get_string('sectionheadingedit', 'quiz', response.instancesection));
activity.one(SELECTOR.EDITSECTIONICON).set('alt',

File diff suppressed because one or more lines are too long

View File

@ -929,7 +929,7 @@ Y.extend(SECTIONTOOLBOX, TOOLBOX, {
// Create the confirmation dialogue.
var confirm = new M.core.confirm({
question: M.util.get_string('confirmremovesectionheading', 'quiz', activity.get('aria-label')),
question: M.util.get_string('confirmremovesectionheading', 'quiz', activity.getData('sectionname')),
modal: true
});
@ -1027,7 +1027,18 @@ Y.extend(SECTIONTOOLBOX, TOOLBOX, {
var spinner = M.util.add_spinner(Y, activity.one(SELECTOR.INSTANCESECTIONAREA));
this.edit_section_title_clear(activity);
if (newtext !== null && newtext !== oldtext) {
activity.one(SELECTOR.INSTANCESECTION).setContent(newtext);
var instancesection = activity.one(SELECTOR.INSTANCESECTION);
var instancesectiontext = newtext;
if (newtext.trim() === '') {
// Add a sr-only default section heading text to make sure we don't end up with an empty section heading.
instancesectiontext = M.util.get_string('sectionnoname', 'quiz');
instancesection.addClass('sr-only');
} else {
// Show the section heading when a non-empty value is set.
instancesection.removeClass('sr-only');
}
instancesection.setContent(instancesectiontext);
var data = {
'class': 'section',
'field': 'updatesectiontitle',
@ -1036,7 +1047,21 @@ Y.extend(SECTIONTOOLBOX, TOOLBOX, {
};
this.send_request(data, spinner, function(response) {
if (response) {
activity.one(SELECTOR.INSTANCESECTION).setContent(response.instancesection);
// Set the content of the section heading if for some reason the response is different from the new text.
// e.g. filters were applied, the update failed, etc.
if (newtext !== response.instancesection) {
if (response.instancesection.trim() === '') {
// Add a sr-only default section heading text.
instancesectiontext = M.util.get_string('sectionnoname', 'quiz');
instancesection.addClass('sr-only');
} else {
instancesectiontext = response.instancesection;
// Show the section heading when a non-empty value is set.
instancesection.removeClass('sr-only');
}
instancesection.setContent(instancesectiontext);
}
activity.one(SELECTOR.EDITSECTIONICON).set('title',
M.util.get_string('sectionheadingedit', 'quiz', response.instancesection));
activity.one(SELECTOR.EDITSECTIONICON).set('alt',

View File

@ -113,7 +113,7 @@ Y.extend(SECTIONTOOLBOX, TOOLBOX, {
// Create the confirmation dialogue.
var confirm = new M.core.confirm({
question: M.util.get_string('confirmremovesectionheading', 'quiz', activity.get('aria-label')),
question: M.util.get_string('confirmremovesectionheading', 'quiz', activity.getData('sectionname')),
modal: true
});
@ -211,7 +211,18 @@ Y.extend(SECTIONTOOLBOX, TOOLBOX, {
var spinner = M.util.add_spinner(Y, activity.one(SELECTOR.INSTANCESECTIONAREA));
this.edit_section_title_clear(activity);
if (newtext !== null && newtext !== oldtext) {
activity.one(SELECTOR.INSTANCESECTION).setContent(newtext);
var instancesection = activity.one(SELECTOR.INSTANCESECTION);
var instancesectiontext = newtext;
if (newtext.trim() === '') {
// Add a sr-only default section heading text to make sure we don't end up with an empty section heading.
instancesectiontext = M.util.get_string('sectionnoname', 'quiz');
instancesection.addClass('sr-only');
} else {
// Show the section heading when a non-empty value is set.
instancesection.removeClass('sr-only');
}
instancesection.setContent(instancesectiontext);
var data = {
'class': 'section',
'field': 'updatesectiontitle',
@ -220,7 +231,21 @@ Y.extend(SECTIONTOOLBOX, TOOLBOX, {
};
this.send_request(data, spinner, function(response) {
if (response) {
activity.one(SELECTOR.INSTANCESECTION).setContent(response.instancesection);
// Set the content of the section heading if for some reason the response is different from the new text.
// e.g. filters were applied, the update failed, etc.
if (newtext !== response.instancesection) {
if (response.instancesection.trim() === '') {
// Add a sr-only default section heading text.
instancesectiontext = M.util.get_string('sectionnoname', 'quiz');
instancesection.addClass('sr-only');
} else {
instancesectiontext = response.instancesection;
// Show the section heading when a non-empty value is set.
instancesection.removeClass('sr-only');
}
instancesection.setContent(instancesectiontext);
}
activity.one(SELECTOR.EDITSECTIONICON).set('title',
M.util.get_string('sectionheadingedit', 'quiz', response.instancesection));
activity.one(SELECTOR.EDITSECTIONICON).set('alt',