mirror of
https://github.com/moodle/moodle.git
synced 2025-04-13 04:22:07 +02:00
Merge branch 'MDL-68353-master' of git://github.com/rezaies/moodle
This commit is contained in:
commit
96dc92f099
@ -49,15 +49,28 @@
|
||||
}}
|
||||
<div class="form-item row" id="{{id}}">
|
||||
<div class="form-label col-sm-3 text-sm-right">
|
||||
<label {{#labelfor}}for="{{labelfor}}"{{/labelfor}}>
|
||||
{{{title}}}
|
||||
{{#override}}
|
||||
<div class="alert alert-info">{{override}}</div>
|
||||
{{/override}}
|
||||
{{#warning}}
|
||||
<div class="alert alert-warning">{{warning}}</div>
|
||||
{{/warning}}
|
||||
</label>
|
||||
{{#customcontrol}}
|
||||
<p {{#labelfor}}id="{{labelfor}}_label"{{/labelfor}}>
|
||||
{{{title}}}
|
||||
{{#override}}
|
||||
<div class="alert alert-info">{{override}}</div>
|
||||
{{/override}}
|
||||
{{#warning}}
|
||||
<div class="alert alert-warning">{{warning}}</div>
|
||||
{{/warning}}
|
||||
</p>
|
||||
{{/customcontrol}}
|
||||
{{^customcontrol}}
|
||||
<label {{#labelfor}}for="{{labelfor}}"{{/labelfor}}>
|
||||
{{{title}}}
|
||||
{{#override}}
|
||||
<div class="alert alert-info">{{override}}</div>
|
||||
{{/override}}
|
||||
{{#warning}}
|
||||
<div class="alert alert-warning">{{warning}}</div>
|
||||
{{/warning}}
|
||||
</label>
|
||||
{{/customcontrol}}
|
||||
<span class="form-shortname d-block small text-muted">{{{name}}}</span>
|
||||
</div>
|
||||
<div class="form-setting col-sm-9">
|
||||
@ -72,3 +85,16 @@
|
||||
{{#dependenton}}<div class="form-dependenton mb-4 text-muted">{{{.}}}</div>{{/dependenton}}
|
||||
</div>
|
||||
</div>
|
||||
{{#customcontrol}}
|
||||
{{#js}}
|
||||
require(['jquery'], function($) {
|
||||
$('#{{id}}_label').css('cursor', 'default');
|
||||
$('#{{id}}_label').click(function() {
|
||||
$('#{{id}}')
|
||||
.find('button, a, input:not([type="hidden"]), select, textarea, [tabindex]')
|
||||
.filter(':not([disabled]):not([tabindex="0"]):not([tabindex="-1"])')
|
||||
.first().focus();
|
||||
});
|
||||
});
|
||||
{{/js}}
|
||||
{{/customcontrol}}
|
||||
|
@ -1686,6 +1686,8 @@ abstract class admin_setting {
|
||||
private $forceltr = null;
|
||||
/** @var array list of other settings that may cause this setting to be hidden */
|
||||
private $dependenton = [];
|
||||
/** @var bool Whether this setting uses a custom form control */
|
||||
protected $customcontrol = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -2081,6 +2083,16 @@ abstract class admin_setting {
|
||||
public function get_dependent_on() {
|
||||
return $this->dependenton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this setting uses a custom form control.
|
||||
* This function is especially useful to decide if we should render a label element for this setting or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_custom_form_control(): bool {
|
||||
return $this->customcontrol;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -8925,6 +8937,7 @@ function format_admin_setting($setting, $title='', $form='', $description='', $l
|
||||
$context->description = highlight($query, markdown_to_html($description));
|
||||
$context->element = $form;
|
||||
$context->forceltr = $setting->get_force_ltr();
|
||||
$context->customcontrol = $setting->has_custom_form_control();
|
||||
|
||||
return $OUTPUT->render_from_template('core_admin/setting', $context);
|
||||
}
|
||||
@ -10384,6 +10397,7 @@ class admin_setting_configstoredfile extends admin_setting {
|
||||
$this->filearea = $filearea;
|
||||
$this->itemid = $itemid;
|
||||
$this->options = (array)$options;
|
||||
$this->customcontrol = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,7 +221,9 @@ XPATH
|
||||
.//*[contains(., %locator%) and not(.//*[contains(., %locator%)])]
|
||||
XPATH
|
||||
, 'form_row' => <<<XPATH
|
||||
.//*[self::label or self::div[contains(concat(' ', @class, ' '), ' fstaticlabel ')]][contains(., %locator%)]/ancestor::*[contains(concat(' ', @class, ' '), ' fitem ')]
|
||||
.//*[contains(concat(' ', @class, ' '), ' col-form-label ')]
|
||||
[normalize-space(.)= %locator%]
|
||||
/ancestor::*[contains(concat(' ', @class, ' '), ' fitem ')]
|
||||
XPATH
|
||||
, 'autocomplete_selection' => <<<XPATH
|
||||
.//div[contains(concat(' ', normalize-space(@class), ' '), concat(' ', 'form-autocomplete-selection', ' '))]/span[@role='listitem'][contains(normalize-space(.), %locator%)]
|
||||
@ -253,7 +255,7 @@ XPATH
|
||||
,
|
||||
'filemanager' => <<<XPATH
|
||||
.//*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']
|
||||
/descendant::input[@id = //label[contains(normalize-space(string(.)), %locator%)]/@for]
|
||||
/descendant::input[@id = substring-before(//p[contains(normalize-space(string(.)), %locator%)]/@id, '_label')]
|
||||
XPATH
|
||||
,
|
||||
'passwordunmask' => <<<XPATH
|
||||
|
@ -74,7 +74,7 @@ trait core_behat_file_helper {
|
||||
$filepickerelement = behat_context_helper::escape($filepickerelement);
|
||||
$filepickercontainer = $this->find(
|
||||
'xpath',
|
||||
"//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" .
|
||||
"//input[./@id = substring-before(//p[normalize-space(.)=$filepickerelement]/@id, '_label')]" .
|
||||
"//ancestor::*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']",
|
||||
$exception
|
||||
);
|
||||
|
@ -251,7 +251,7 @@ class behat_form_field {
|
||||
// Defaults to label.
|
||||
if ($locatortype == 'label' || $locatortype == false) {
|
||||
|
||||
$labelnode = $this->session->getPage()->find('xpath', '//label[@for="' . $fieldid . '"]');
|
||||
$labelnode = $this->session->getPage()->find('xpath', "//label[@for='$fieldid']|//p[@id='{$fieldid}_label']");
|
||||
|
||||
// Exception only if $locatortype was specified.
|
||||
if (!$labelnode && $locatortype == 'label') {
|
||||
|
@ -68,7 +68,7 @@ class behat_form_filemanager extends behat_form_field {
|
||||
$fieldlabel = $this->get_field_locator();
|
||||
|
||||
// Get the name of the current directory elements.
|
||||
$xpath = "//label[contains(., '" . $fieldlabel . "')]" .
|
||||
$xpath = "//p[normalize-space(.)='$fieldlabel']" .
|
||||
"/ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' fitem ')]" .
|
||||
"/descendant::div[@data-fieldtype = 'filemanager']" .
|
||||
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-filename ')]";
|
||||
|
@ -13,7 +13,6 @@
|
||||
value="{{element.selectedvalue}}"
|
||||
{{/element.selectedvalue}}
|
||||
{{#element.checked}}checked{{/element.checked}}
|
||||
size="{{element.size}}"
|
||||
{{#error}}
|
||||
autofocus aria-describedby="{{element.iderror}}"
|
||||
{{/error}}
|
||||
|
@ -13,7 +13,6 @@
|
||||
value="1"
|
||||
{{/element.value}}
|
||||
{{#element.checked}}checked{{/element.checked}}
|
||||
size="{{element.size}}"
|
||||
{{#error}}
|
||||
autofocus aria-describedby="{{element.iderror}}"
|
||||
{{/error}}
|
||||
|
@ -1,5 +1,26 @@
|
||||
{{< core_form/element-template }}
|
||||
{{$label}}
|
||||
{{^element.hiddenlabel}}
|
||||
<p id="{{element.id}}_label" class="col-form-label d-inline" aria-hidden="true">
|
||||
{{{label}}}
|
||||
</p>
|
||||
{{/element.hiddenlabel}}
|
||||
{{/label}}
|
||||
{{$element}}
|
||||
{{{element.html}}}
|
||||
<fieldset class="w-100 m-0 p-0 border-0" id="{{element.id}}_fieldset">
|
||||
<legend class="sr-only">{{label}}</legend>
|
||||
{{{element.html}}}
|
||||
</fieldset>
|
||||
{{/element}}
|
||||
{{/ core_form/element-template }}
|
||||
{{#js}}
|
||||
(function() {
|
||||
var label = document.getElementById('{{element.id}}_label');
|
||||
if (label) {
|
||||
label.style.cursor = 'default';
|
||||
label.addEventListener('click', function() {
|
||||
document.querySelectorAll('#{{element.id}}_fieldset div.fp-toolbar a')[0].focus();
|
||||
});
|
||||
}
|
||||
})();
|
||||
{{/js}}
|
||||
|
@ -1,5 +1,26 @@
|
||||
{{< core_form/element-template }}
|
||||
{{$label}}
|
||||
{{^element.hiddenlabel}}
|
||||
<p id="{{element.id}}_label" class="col-form-label d-inline" aria-hidden="true">
|
||||
{{{label}}}
|
||||
</p>
|
||||
{{/element.hiddenlabel}}
|
||||
{{/label}}
|
||||
{{$element}}
|
||||
{{{element.html}}}
|
||||
<fieldset class="w-100 m-0 p-0 border-0" id="{{element.id}}_fieldset">
|
||||
<legend class="sr-only">{{label}}</legend>
|
||||
{{{element.html}}}
|
||||
</fieldset>
|
||||
{{/element}}
|
||||
{{/ core_form/element-template }}
|
||||
{{#js}}
|
||||
(function() {
|
||||
var label = document.getElementById('{{element.id}}_label');
|
||||
if (label) {
|
||||
label.style.cursor = 'default';
|
||||
label.addEventListener('click', function() {
|
||||
document.querySelectorAll('#{{element.id}}_fieldset .fp-btn-choose')[0].focus();
|
||||
});
|
||||
}
|
||||
})();
|
||||
{{/js}}
|
||||
|
@ -22,7 +22,10 @@
|
||||
require(['jquery'], function($) {
|
||||
$('#{{element.id}}_label').css('cursor', 'default');
|
||||
$('#{{element.id}}_label').click(function() {
|
||||
$('#{{element.id}}').find('button, a, input, select, textarea, [tabindex]:not([tabindex="-1"])').filter(':enabled').first().focus();
|
||||
$('#{{element.id}}')
|
||||
.find('button, a, input:not([type="hidden"]), select, textarea, [tabindex]')
|
||||
.filter(':not([disabled]):not([tabindex="0"]):not([tabindex="-1"])')
|
||||
.first().focus();
|
||||
});
|
||||
});
|
||||
{{/js}}
|
||||
|
@ -41,7 +41,7 @@
|
||||
name="{{element.name}}"
|
||||
id="{{element.id}}"
|
||||
value="{{element.value}}"
|
||||
size="{{element.size}}"
|
||||
{{#element.size}}size="{{element.size}}"{{/element.size}}
|
||||
{{#error}}
|
||||
autofocus aria-describedby="{{element.iderror}}"
|
||||
{{/error}} {{{element.attributes}}}>
|
||||
|
@ -41,7 +41,7 @@
|
||||
name="{{element.name}}"
|
||||
id="{{element.id}}"
|
||||
value="{{element.value}}"
|
||||
size="{{element.size}}"
|
||||
{{#element.size}}size="{{element.size}}"{{/element.size}}
|
||||
{{#error}}
|
||||
autofocus aria-describedby="{{element.iderror}}"
|
||||
{{/error}} {{{element.attributes}}}>
|
||||
|
@ -49,7 +49,7 @@
|
||||
{{#advanced}}<abbr class="initialism text-info" title="{{#str}}advanced{{/str}}">!</abbr>{{/advanced}}
|
||||
{{{helpbutton}}}
|
||||
</span>
|
||||
{{$ label }}
|
||||
{{# label}}{{$ label }}
|
||||
{{^element.staticlabel}}
|
||||
<label class="col-form-label d-inline {{#element.hiddenlabel}}sr-only{{/element.hiddenlabel}}" for="{{element.id}}">
|
||||
{{{label}}}
|
||||
@ -60,7 +60,7 @@
|
||||
{{{label}}}
|
||||
</span>
|
||||
{{/element.staticlabel}}
|
||||
{{/ label }}
|
||||
{{/ label }}{{/ label}}
|
||||
</div>
|
||||
<div class="col-md-9 form-inline felement" data-fieldtype="{{element.type}}">
|
||||
{{$ element }}
|
||||
|
@ -8,7 +8,7 @@
|
||||
readonly {{#element.hardfrozen}}disabled{{/element.hardfrozen}}
|
||||
{{/element.frozen}}
|
||||
value="{{element.value}}"
|
||||
size="{{element.size}}"
|
||||
{{#element.size}}size="{{element.size}}"{{/element.size}}
|
||||
{{#error}}
|
||||
autofocus aria-describedby="{{element.iderror}}"
|
||||
{{/error}}
|
||||
|
@ -8,7 +8,7 @@
|
||||
{{/element.frozen}}
|
||||
id="{{element.id}}"
|
||||
value="{{element.value}}"
|
||||
size="{{element.size}}"
|
||||
{{#element.size}}size="{{element.size}}"{{/element.size}}
|
||||
{{#error}}
|
||||
autofocus aria-describedby="{{element.iderror}}"
|
||||
{{/error}}
|
||||
|
@ -8,7 +8,7 @@
|
||||
name="{{element.name}}"
|
||||
id="{{element.id}}"
|
||||
value="{{element.value}}"
|
||||
size="{{element.size}}"
|
||||
{{#element.size}}size="{{element.size}}"{{/element.size}}
|
||||
{{#error}}
|
||||
autofocus aria-describedby="{{element.iderror}}"
|
||||
{{/error}}
|
||||
|
@ -62,13 +62,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="fp-original form-group row mx-0">
|
||||
<label class="form-control-label col-4 px-0">{{#str}}original, repository{{/str}}</label>
|
||||
<div class="form-control-label col-4 px-0">{{#str}}original, repository{{/str}}</div>
|
||||
<div class="col-8 form-inline">
|
||||
<span class="fp-originloading">{{#pix}}i/loading_small{{/pix}} {{#str}}loading, repository{{/str}}</span><span class="fp-value"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fp-reflist form-group row mx-0">
|
||||
<label class="form-control-label col-4 px-0">{{#str}}referenceslist, repository{{/str}}</label>
|
||||
<div class="form-control-label col-4 px-0">{{#str}}referenceslist, repository{{/str}}</div>
|
||||
<div class="col-8 form-inline">
|
||||
<p class="fp-refcount"></p>
|
||||
<span class="fp-reflistloading">{{#pix}}i/loading_small{{/pix}} {{#str}}loading, repository{{/str}}</span>
|
||||
|
@ -127,8 +127,10 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
var bb;
|
||||
|
||||
if (this.get('closeButton') !== false) {
|
||||
// The buttons constructor does not allow custom attributes
|
||||
this.get('buttons').header[0].setAttribute('title', this.get('closeButtonTitle'));
|
||||
var title = this.get('closeButtonTitle');
|
||||
// The buttons constructor does not allow custom attributes.
|
||||
this.get('buttons').header[0].setAttribute('title', title);
|
||||
this.get('buttons').header[0].setAttribute('aria-label', title);
|
||||
}
|
||||
|
||||
// Initialise the element cache.
|
||||
|
File diff suppressed because one or more lines are too long
@ -127,8 +127,10 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
var bb;
|
||||
|
||||
if (this.get('closeButton') !== false) {
|
||||
// The buttons constructor does not allow custom attributes
|
||||
this.get('buttons').header[0].setAttribute('title', this.get('closeButtonTitle'));
|
||||
var title = this.get('closeButtonTitle');
|
||||
// The buttons constructor does not allow custom attributes.
|
||||
this.get('buttons').header[0].setAttribute('title', title);
|
||||
this.get('buttons').header[0].setAttribute('aria-label', title);
|
||||
}
|
||||
|
||||
// Initialise the element cache.
|
||||
|
6
lib/yui/src/notification/js/dialogue.js
vendored
6
lib/yui/src/notification/js/dialogue.js
vendored
@ -97,8 +97,10 @@ Y.extend(DIALOGUE, Y.Panel, {
|
||||
var bb;
|
||||
|
||||
if (this.get('closeButton') !== false) {
|
||||
// The buttons constructor does not allow custom attributes
|
||||
this.get('buttons').header[0].setAttribute('title', this.get('closeButtonTitle'));
|
||||
var title = this.get('closeButtonTitle');
|
||||
// The buttons constructor does not allow custom attributes.
|
||||
this.get('buttons').header[0].setAttribute('title', title);
|
||||
this.get('buttons').header[0].setAttribute('aria-label', title);
|
||||
}
|
||||
|
||||
// Initialise the element cache.
|
||||
|
@ -39,20 +39,23 @@
|
||||
<h3 class="h6 font-weight-bold">{{#str}} privacy, message {{/str}}</h3>
|
||||
<p>{{#str}} privacy_desc, message {{/str}}</p>
|
||||
<div data-preference="blocknoncontacts" class="mb-3">
|
||||
{{#privacy}}
|
||||
<div class="custom-control custom-radio mb-2">
|
||||
<input
|
||||
type="radio"
|
||||
name="message_blocknoncontacts"
|
||||
class="custom-control-input"
|
||||
id="block-noncontacts-{{uniqid}}-{{value}}"
|
||||
value="{{value}}"
|
||||
>
|
||||
<label class="custom-control-label ml-2" for="block-noncontacts-{{uniqid}}-{{value}}">
|
||||
{{text}}
|
||||
</label>
|
||||
</div>
|
||||
{{/privacy}}
|
||||
<fieldset>
|
||||
<legend class="sr-only">{{#str}} contactableprivacy, message {{/str}}</legend>
|
||||
{{#privacy}}
|
||||
<div class="custom-control custom-radio mb-2">
|
||||
<input
|
||||
type="radio"
|
||||
name="message_blocknoncontacts"
|
||||
class="custom-control-input"
|
||||
id="block-noncontacts-{{uniqid}}-{{value}}"
|
||||
value="{{value}}"
|
||||
>
|
||||
<label class="custom-control-label ml-2" for="block-noncontacts-{{uniqid}}-{{value}}">
|
||||
{{text}}
|
||||
</label>
|
||||
</div>
|
||||
{{/privacy}}
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="hidden" data-region="notification-preference-container">
|
||||
|
@ -15,7 +15,7 @@
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template core_message/message_drawer
|
||||
@template core_message/message_index
|
||||
|
||||
This template will render the message drawer.
|
||||
|
||||
|
@ -19,7 +19,7 @@ Feature: A selected file can be cancelled
|
||||
| Name | Folder name |
|
||||
| Description | Folder description |
|
||||
And I upload "lib/tests/fixtures/upload_users.csv" file to "Files" filemanager
|
||||
And I click on "//label[contains(., 'Files')]/ancestor::div[contains(concat(' ', @class, ' '), ' fitem ')]//*[contains(@title, 'Add...')]" "xpath_element"
|
||||
And I click on "Add..." "button" in the "Files" "form_row"
|
||||
And I click on "Recent files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "//a[contains(concat(' ', normalize-space(@class), ' '), ' fp-file ')][normalize-space(.)='empty.txt']" "xpath_element"
|
||||
And I click on ".moodle-dialogue-focused .fp-select .fp-select-cancel" "css_element"
|
||||
|
@ -21,7 +21,7 @@ Feature: Select file feature
|
||||
And I click on "Save and display" "button"
|
||||
And I follow "Dashboard" in the user menu
|
||||
And I follow "Manage private files"
|
||||
And I click on "//label[contains(., 'Files')]/ancestor::div[contains(concat(' ', @class, ' '), ' fitem ')]//*[contains(@title, 'Add...')]" "xpath_element"
|
||||
And I click on "Add..." "button" in the "Files" "form_row"
|
||||
And I click on "Recent files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "Display folder with file icons" "link" in the ".file-picker" "css_element"
|
||||
And I click on "//a[contains(concat(' ', normalize-space(@class), ' '), ' fp-file ')][normalize-space(.)='empty.txt']" "xpath_element"
|
||||
@ -42,7 +42,7 @@ Feature: Select file feature
|
||||
And I click on "Save and display" "button"
|
||||
And I follow "Dashboard" in the user menu
|
||||
And I follow "Manage private files"
|
||||
And I click on "//label[contains(., 'Files')]/ancestor::div[contains(concat(' ', @class, ' '), ' fitem ')]//*[contains(@title, 'Add...')]" "xpath_element"
|
||||
And I click on "Add..." "button" in the "Files" "form_row"
|
||||
And I click on "Recent files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "Display folder with file details" "link" in the ".file-picker" "css_element"
|
||||
And I click on "//div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]/descendant::span[normalize-space(.)='empty.txt']/ancestor::a" "xpath_element"
|
||||
@ -63,7 +63,7 @@ Feature: Select file feature
|
||||
And I click on "Save and display" "button"
|
||||
And I follow "Dashboard" in the user menu
|
||||
And I follow "Manage private files"
|
||||
And I click on "//label[contains(., 'Files')]/ancestor::div[contains(concat(' ', @class, ' '), ' fitem ')]//*[contains(@title, 'Add...')]" "xpath_element"
|
||||
And I click on "Add..." "button" in the "Files" "form_row"
|
||||
And I click on "Recent files" "link" in the ".fp-repo-area" "css_element"
|
||||
And I click on "Display folder as file tree" "link" in the ".file-picker" "css_element"
|
||||
And I click on "//div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]/descendant::span[normalize-space(.)='empty.txt']/ancestor::a" "xpath_element"
|
||||
|
@ -209,10 +209,8 @@ class behat_repository_upload extends behat_base {
|
||||
$filepickerelement = behat_context_helper::escape($filepickerelement);
|
||||
$filepickercontainer = $this->find(
|
||||
'xpath',
|
||||
"//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" .
|
||||
"//ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' felement ')] |" .
|
||||
"//input[./@id = //label[normalize-space(.)=$filepickerelement]/@for]" .
|
||||
"//ancestor::div[contains(concat(' ', normalize-space(@class), ' '), ' form-setting ')]",
|
||||
"//input[./@id = substring-before(//p[normalize-space(.)=$filepickerelement]/@id, '_label')]" .
|
||||
"//ancestor::*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']",
|
||||
$exception
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user