mirror of
https://github.com/moodle/moodle.git
synced 2025-04-22 17:02:03 +02:00
MDL-68612 user: Participants filter row accessibility improvements
More clearly defining each filter row and its ability to remove filter selections for screen readers.
This commit is contained in:
parent
03cb6064ea
commit
3d60881d5d
@ -29,7 +29,9 @@ $string['adverbfor_or'] = 'or';
|
||||
$string['applyfilters'] = 'Apply filters';
|
||||
$string['clearfilterrow'] = 'Remove filter row';
|
||||
$string['clearfilters'] = 'Clear filters';
|
||||
$string['clearfilterselection'] = 'Remove "{$a}" from filter';
|
||||
$string['countparticipantsfound'] = '{$a} participants found';
|
||||
$string['filterrowlegend'] = 'Filter {$a}';
|
||||
$string['filtersetmatchdescription'] = 'How multiple filters should be combined';
|
||||
$string['match'] = 'Match';
|
||||
$string['matchofthefollowing'] = 'of the following:';
|
||||
|
@ -1,2 +1,2 @@
|
||||
define ("core_user/local/participantsfilter/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;var b=function(a){return"[data-filterregion=\"".concat(a,"\"]")},c=function(a){return"[data-filteraction=\"".concat(a,"\"]")},d=function(a){return"[data-filterfield=\"".concat(a,"\"]")},e={filter:{region:b("filter"),actions:{remove:c("remove")},fields:{join:d("join"),type:d("type")},regions:{values:b("value")},byName:function byName(a){return"".concat(b("filter"),"[data-filter-type=\"").concat(a,"\"]")}},filterset:{region:b("actions"),actions:{addRow:c("add"),applyFilters:c("apply"),resetFilters:c("reset")},regions:{filtermatch:b("filtermatch"),filterlist:b("filters"),datasource:b("filtertypedata")},fields:{join:"".concat(b("filtermatch")," ").concat(d("join"))}},data:{fields:{byName:function byName(a){return"[data-field-name=\"".concat(a,"\"]")},all:"".concat(b("filtertypedata")," [data-field-name]")},typeList:b("filtertypelist")}};a.default=e;return a.default});
|
||||
define ("core_user/local/participantsfilter/selectors",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;var b=function(a){return"[data-filterregion=\"".concat(a,"\"]")},c=function(a){return"[data-filteraction=\"".concat(a,"\"]")},d=function(a){return"[data-filterfield=\"".concat(a,"\"]")},e={filter:{region:b("filter"),actions:{remove:c("remove")},fields:{join:d("join"),type:d("type")},regions:{values:b("value")},byName:function byName(a){return"".concat(b("filter"),"[data-filter-type=\"").concat(a,"\"]")}},filterset:{region:b("actions"),actions:{addRow:c("add"),applyFilters:c("apply"),resetFilters:c("reset")},regions:{filtermatch:b("filtermatch"),filterlist:b("filters"),datasource:b("filtertypedata")},fields:{join:"".concat(b("filtermatch")," ").concat(d("join"))}},data:{fields:{byName:function byName(a){return"[data-field-name=\"".concat(a,"\"]")},all:"".concat(b("filtertypedata")," [data-field-name]")},typeList:b("filtertypelist"),typeListSelect:"select".concat(b("filtertypelist"))}};a.default=e;return a.default});
|
||||
//# sourceMappingURL=selectors.min.js.map
|
||||
|
@ -1 +1 @@
|
||||
{"version":3,"sources":["../../../src/local/participantsfilter/selectors.js"],"names":["getFilterRegion","region","getFilterAction","action","getFilterField","field","filter","actions","remove","fields","join","type","regions","values","byName","name","filterset","addRow","applyFilters","resetFilters","filtermatch","filterlist","datasource","data","all","typeList"],"mappings":"iKAwBMA,CAAAA,CAAe,CAAG,SAAAC,CAAM,uCAA2BA,CAA3B,Q,CACxBC,CAAe,CAAG,SAAAC,CAAM,uCAA2BA,CAA3B,Q,CACxBC,CAAc,CAAG,SAAAC,CAAK,sCAA0BA,CAA1B,Q,GAEb,CACXC,MAAM,CAAE,CACJL,MAAM,CAAED,CAAe,CAAC,QAAD,CADnB,CAEJO,OAAO,CAAE,CACLC,MAAM,CAAEN,CAAe,CAAC,QAAD,CADlB,CAFL,CAKJO,MAAM,CAAE,CACJC,IAAI,CAAEN,CAAc,CAAC,MAAD,CADhB,CAEJO,IAAI,CAAEP,CAAc,CAAC,MAAD,CAFhB,CALJ,CASJQ,OAAO,CAAE,CACLC,MAAM,CAAEb,CAAe,CAAC,OAAD,CADlB,CATL,CAYJc,MAAM,CAAE,gBAAAC,CAAI,kBAAOf,CAAe,CAAC,QAAD,CAAtB,gCAAsDe,CAAtD,QAZR,CADG,CAeXC,SAAS,CAAE,CACPf,MAAM,CAAED,CAAe,CAAC,SAAD,CADhB,CAEPO,OAAO,CAAE,CACLU,MAAM,CAAEf,CAAe,CAAC,KAAD,CADlB,CAELgB,YAAY,CAAEhB,CAAe,CAAC,OAAD,CAFxB,CAGLiB,YAAY,CAAEjB,CAAe,CAAC,OAAD,CAHxB,CAFF,CAOPU,OAAO,CAAE,CACLQ,WAAW,CAAEpB,CAAe,CAAC,aAAD,CADvB,CAELqB,UAAU,CAAErB,CAAe,CAAC,SAAD,CAFtB,CAGLsB,UAAU,CAAEtB,CAAe,CAAC,gBAAD,CAHtB,CAPF,CAYPS,MAAM,CAAE,CACJC,IAAI,WAAKV,CAAe,CAAC,aAAD,CAApB,aAAuCI,CAAc,CAAC,MAAD,CAArD,CADA,CAZD,CAfA,CA+BXmB,IAAI,CAAE,CACFd,MAAM,CAAE,CACJK,MAAM,CAAE,gBAAAC,CAAI,qCAAyBA,CAAzB,QADR,CAEJS,GAAG,WAAKxB,CAAe,CAAC,gBAAD,CAApB,sBAFC,CADN,CAKFyB,QAAQ,CAAEzB,CAAe,CAAC,gBAAD,CALvB,CA/BK,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Module containing the selectors for user filters.\n *\n * @module core_user/local/user_filter/selectors\n * @package core_user\n * @copyright 2020 Michael Hawkins <michaelh@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nconst getFilterRegion = region => `[data-filterregion=\"${region}\"]`;\nconst getFilterAction = action => `[data-filteraction=\"${action}\"]`;\nconst getFilterField = field => `[data-filterfield=\"${field}\"]`;\n\nexport default {\n filter: {\n region: getFilterRegion('filter'),\n actions: {\n remove: getFilterAction('remove'),\n },\n fields: {\n join: getFilterField('join'),\n type: getFilterField('type'),\n },\n regions: {\n values: getFilterRegion('value'),\n },\n byName: name => `${getFilterRegion('filter')}[data-filter-type=\"${name}\"]`,\n },\n filterset: {\n region: getFilterRegion('actions'),\n actions: {\n addRow: getFilterAction('add'),\n applyFilters: getFilterAction('apply'),\n resetFilters: getFilterAction('reset'),\n },\n regions: {\n filtermatch: getFilterRegion('filtermatch'),\n filterlist: getFilterRegion('filters'),\n datasource: getFilterRegion('filtertypedata'),\n },\n fields: {\n join: `${getFilterRegion('filtermatch')} ${getFilterField('join')}`,\n },\n },\n data: {\n fields: {\n byName: name => `[data-field-name=\"${name}\"]`,\n all: `${getFilterRegion('filtertypedata')} [data-field-name]`,\n },\n typeList: getFilterRegion('filtertypelist'),\n },\n};\n"],"file":"selectors.min.js"}
|
||||
{"version":3,"sources":["../../../src/local/participantsfilter/selectors.js"],"names":["getFilterRegion","region","getFilterAction","action","getFilterField","field","filter","actions","remove","fields","join","type","regions","values","byName","name","filterset","addRow","applyFilters","resetFilters","filtermatch","filterlist","datasource","data","all","typeList","typeListSelect"],"mappings":"iKAwBMA,CAAAA,CAAe,CAAG,SAAAC,CAAM,uCAA2BA,CAA3B,Q,CACxBC,CAAe,CAAG,SAAAC,CAAM,uCAA2BA,CAA3B,Q,CACxBC,CAAc,CAAG,SAAAC,CAAK,sCAA0BA,CAA1B,Q,GAEb,CACXC,MAAM,CAAE,CACJL,MAAM,CAAED,CAAe,CAAC,QAAD,CADnB,CAEJO,OAAO,CAAE,CACLC,MAAM,CAAEN,CAAe,CAAC,QAAD,CADlB,CAFL,CAKJO,MAAM,CAAE,CACJC,IAAI,CAAEN,CAAc,CAAC,MAAD,CADhB,CAEJO,IAAI,CAAEP,CAAc,CAAC,MAAD,CAFhB,CALJ,CASJQ,OAAO,CAAE,CACLC,MAAM,CAAEb,CAAe,CAAC,OAAD,CADlB,CATL,CAYJc,MAAM,CAAE,gBAAAC,CAAI,kBAAOf,CAAe,CAAC,QAAD,CAAtB,gCAAsDe,CAAtD,QAZR,CADG,CAeXC,SAAS,CAAE,CACPf,MAAM,CAAED,CAAe,CAAC,SAAD,CADhB,CAEPO,OAAO,CAAE,CACLU,MAAM,CAAEf,CAAe,CAAC,KAAD,CADlB,CAELgB,YAAY,CAAEhB,CAAe,CAAC,OAAD,CAFxB,CAGLiB,YAAY,CAAEjB,CAAe,CAAC,OAAD,CAHxB,CAFF,CAOPU,OAAO,CAAE,CACLQ,WAAW,CAAEpB,CAAe,CAAC,aAAD,CADvB,CAELqB,UAAU,CAAErB,CAAe,CAAC,SAAD,CAFtB,CAGLsB,UAAU,CAAEtB,CAAe,CAAC,gBAAD,CAHtB,CAPF,CAYPS,MAAM,CAAE,CACJC,IAAI,WAAKV,CAAe,CAAC,aAAD,CAApB,aAAuCI,CAAc,CAAC,MAAD,CAArD,CADA,CAZD,CAfA,CA+BXmB,IAAI,CAAE,CACFd,MAAM,CAAE,CACJK,MAAM,CAAE,gBAAAC,CAAI,qCAAyBA,CAAzB,QADR,CAEJS,GAAG,WAAKxB,CAAe,CAAC,gBAAD,CAApB,sBAFC,CADN,CAKFyB,QAAQ,CAAEzB,CAAe,CAAC,gBAAD,CALvB,CAMF0B,cAAc,iBAAW1B,CAAe,CAAC,gBAAD,CAA1B,CANZ,CA/BK,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Module containing the selectors for user filters.\n *\n * @module core_user/local/user_filter/selectors\n * @package core_user\n * @copyright 2020 Michael Hawkins <michaelh@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nconst getFilterRegion = region => `[data-filterregion=\"${region}\"]`;\nconst getFilterAction = action => `[data-filteraction=\"${action}\"]`;\nconst getFilterField = field => `[data-filterfield=\"${field}\"]`;\n\nexport default {\n filter: {\n region: getFilterRegion('filter'),\n actions: {\n remove: getFilterAction('remove'),\n },\n fields: {\n join: getFilterField('join'),\n type: getFilterField('type'),\n },\n regions: {\n values: getFilterRegion('value'),\n },\n byName: name => `${getFilterRegion('filter')}[data-filter-type=\"${name}\"]`,\n },\n filterset: {\n region: getFilterRegion('actions'),\n actions: {\n addRow: getFilterAction('add'),\n applyFilters: getFilterAction('apply'),\n resetFilters: getFilterAction('reset'),\n },\n regions: {\n filtermatch: getFilterRegion('filtermatch'),\n filterlist: getFilterRegion('filters'),\n datasource: getFilterRegion('filtertypedata'),\n },\n fields: {\n join: `${getFilterRegion('filtermatch')} ${getFilterField('join')}`,\n },\n },\n data: {\n fields: {\n byName: name => `[data-field-name=\"${name}\"]`,\n all: `${getFilterRegion('filtertypedata')} [data-field-name]`,\n },\n typeList: getFilterRegion('filtertypelist'),\n typeListSelect: `select${getFilterRegion('filtertypelist')}`,\n },\n};\n"],"file":"selectors.min.js"}
|
2
user/amd/build/participantsfilter.min.js
vendored
2
user/amd/build/participantsfilter.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -63,5 +63,6 @@ export default {
|
||||
all: `${getFilterRegion('filtertypedata')} [data-field-name]`,
|
||||
},
|
||||
typeList: getFilterRegion('filtertypelist'),
|
||||
typeListSelect: `select${getFilterRegion('filtertypelist')}`,
|
||||
},
|
||||
};
|
||||
|
@ -25,6 +25,7 @@
|
||||
import CourseFilter from './local/participantsfilter/filtertypes/courseid';
|
||||
import * as DynamicTable from 'core_table/dynamic';
|
||||
import GenericFilter from './local/participantsfilter/filter';
|
||||
import {get_strings as getStrings} from 'core/str';
|
||||
import Notification from 'core/notification';
|
||||
import Selectors from './local/participantsfilter/selectors';
|
||||
import Templates from 'core/templates';
|
||||
@ -56,7 +57,8 @@ export const init = participantsRegionId => {
|
||||
* @return {Promise}
|
||||
*/
|
||||
const addFilterRow = () => {
|
||||
return Templates.renderForPromise('core_user/local/participantsfilter/filterrow', {})
|
||||
const rownum = 1 + getFilterRegion().querySelectorAll(Selectors.filter.region).length;
|
||||
return Templates.renderForPromise('core_user/local/participantsfilter/filterrow', {"rownumber": rownum})
|
||||
.then(({html, js}) => {
|
||||
const newContentNodes = Templates.appendNodeContents(getFilterRegion(), html, js);
|
||||
|
||||
@ -157,7 +159,7 @@ export const init = participantsRegionId => {
|
||||
*
|
||||
* @param {HTMLElement} filterRow
|
||||
*/
|
||||
const removeFilterRow = filterRow => {
|
||||
const removeFilterRow = async filterRow => {
|
||||
// Remove the filter object.
|
||||
removeFilterObject(filterRow.dataset.filterType);
|
||||
|
||||
@ -169,19 +171,28 @@ export const init = participantsRegionId => {
|
||||
|
||||
// Update the list of available filter types.
|
||||
updateFiltersOptions();
|
||||
|
||||
// Update filter fieldset legends.
|
||||
const filterLegends = await getAvailableFilterLegends();
|
||||
|
||||
getFilterRegion().querySelectorAll(Selectors.filter.region).forEach((filterRow, index) => {
|
||||
filterRow.querySelector('legend').innerText = filterLegends[index];
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace the specified filter row with a new one.
|
||||
*
|
||||
* @param {HTMLElement} filterRow
|
||||
* @param {Number} rowNum The number used to label the filter fieldset legend (eg Row 1). Defaults to 1 (the first filter).
|
||||
* @return {Promise}
|
||||
*/
|
||||
const replaceFilterRow = filterRow => {
|
||||
const replaceFilterRow = (filterRow, rowNum = 1) => {
|
||||
// Remove the filter object.
|
||||
removeFilterObject(filterRow.dataset.filterType);
|
||||
|
||||
return Templates.renderForPromise('core_user/local/participantsfilter/filterrow', {})
|
||||
return Templates.renderForPromise('core_user/local/participantsfilter/filterrow', {"rownumber": rowNum})
|
||||
.then(({html, js}) => {
|
||||
const newContentNodes = Templates.replaceNode(filterRow, html, js);
|
||||
|
||||
@ -302,6 +313,33 @@ export const init = participantsRegionId => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch the strings used to populate the fieldset legends for the maximum number of filters possible.
|
||||
*
|
||||
* @return {array}
|
||||
*/
|
||||
const getAvailableFilterLegends = async() => {
|
||||
const maxFilters = document.querySelector(Selectors.data.typeListSelect).length - 1;
|
||||
let requests = [];
|
||||
|
||||
[...Array(maxFilters)].forEach((_, rowIndex) => {
|
||||
requests.push({
|
||||
"key": "filterrowlegend",
|
||||
"component": "core_user",
|
||||
// Add 1 since rows begin at 1 (index begins at zero).
|
||||
"param": rowIndex + 1
|
||||
});
|
||||
});
|
||||
|
||||
const legendStrings = await getStrings(requests)
|
||||
.then(fetchedStrings => {
|
||||
return fetchedStrings;
|
||||
})
|
||||
.catch(Notification.exception);
|
||||
|
||||
return legendStrings;
|
||||
};
|
||||
|
||||
// Add listeners for the main actions.
|
||||
filterSet.querySelector(Selectors.filterset.region).addEventListener('click', e => {
|
||||
if (e.target.closest(Selectors.filterset.actions.addRow)) {
|
||||
|
@ -350,6 +350,7 @@ class participants_filter implements renderable, templatable {
|
||||
'tableregionid' => $this->tableregionid,
|
||||
'courseid' => $this->context->instanceid,
|
||||
'filtertypes' => $this->get_filtertypes(),
|
||||
'rownumber' => 1,
|
||||
];
|
||||
|
||||
return $data;
|
||||
|
@ -43,7 +43,10 @@
|
||||
{{#items}}
|
||||
<span role="listitem" data-value="{{value}}" aria-selected="true"
|
||||
class="badge badge-secondary clickable text-wrap text-break line-height-4 mr-2 my-1">
|
||||
{{label}}<i class="icon fa fa-times pl-2 mr-0"></i>
|
||||
{{label}}
|
||||
<button class="btn btn-link text-reset p-0" aria-label='{{#str}}clearfilterselection, core_user, {{label}}{{/str}}'>
|
||||
<i class="icon fa fa-times pl-2 mr-0"></i>
|
||||
</button>
|
||||
</span>
|
||||
{{/items}}
|
||||
{{^items}}
|
||||
|
@ -29,37 +29,41 @@
|
||||
"name": "status",
|
||||
"title": "Status"
|
||||
}
|
||||
]
|
||||
],
|
||||
"rownumber": 1
|
||||
}
|
||||
}}
|
||||
<div data-filterregion="filter">
|
||||
<div class="border-radius my-2 p-2 bg-white border d-flex flex-column flex-md-row align-items-md-start">
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center">
|
||||
<label for="core_user-local-participantsfilter-filterrow-jointype-{{uniqid}}" class="mr-md-2 mb-md-0">{{#str}}match, core_user{{/str}}</label>
|
||||
<select class="custom-select mb-1 mb-md-0 mr-md-2" data-filterfield="join" id="core_user-local-participantsfilter-filterrow-jointype-{{uniqid}}">
|
||||
<option value="0">{{#str}}none{{/str}}</option>
|
||||
<option selected=selected value="1">{{#str}}any{{/str}}</option>
|
||||
<option value="2">{{#str}}all{{/str}}</option>
|
||||
<fieldset>
|
||||
<legend class="sr-only">{{#str}}filterrowlegend, core_user, {{rownumber}}{{/str}}</legend>
|
||||
<div class="border-radius my-2 p-2 bg-white border d-flex flex-column flex-md-row align-items-md-start">
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center">
|
||||
<label for="core_user-local-participantsfilter-filterrow-jointype-{{uniqid}}" class="mr-md-2 mb-md-0">{{#str}}match, core_user{{/str}}</label>
|
||||
<select class="custom-select mb-1 mb-md-0 mr-md-2" data-filterfield="join" id="core_user-local-participantsfilter-filterrow-jointype-{{uniqid}}">
|
||||
<option value="0">{{#str}}none{{/str}}</option>
|
||||
<option selected=selected value="1">{{#str}}any{{/str}}</option>
|
||||
<option value="2">{{#str}}all{{/str}}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label class="sr-only pt-2" for="core_user-local-participantsfilter-filterrow-filtertype-{{uniqid}}">filtertype</label>
|
||||
<select class="custom-select mb-1 mb-md-0 mr-md-2" data-filterfield="type" id="core_user-local-participantsfilter-filterrow-filtertype-{{uniqid}}">
|
||||
<option value="">{{#str}}selectfiltertype, core_user{{/str}}</option>
|
||||
{{#filtertypes}}
|
||||
<option value="{{name}}">{{title}}</option>
|
||||
{{/filtertypes}}
|
||||
</select>
|
||||
|
||||
<div data-filterregion="value" class="d-md-flex flex-column align-items-start flex-lg-row"></div>
|
||||
|
||||
<button data-filteraction="remove" class="ml-auto icon-no-margin icon-size-4 btn text-reset" aria-label="{{#str}}clearfilterrow, core_user{{/str}}">
|
||||
<i class="icon fa fa-times-circle"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<label class="sr-only pt-2" for="core_user-local-participantsfilter-filterrow-filtertype-{{uniqid}}">filtertype</label>
|
||||
<select class="custom-select mb-1 mb-md-0 mr-md-2" data-filterfield="type" id="core_user-local-participantsfilter-filterrow-filtertype-{{uniqid}}">
|
||||
<option value="">{{#str}}selectfiltertype, core_user{{/str}}</option>
|
||||
{{#filtertypes}}
|
||||
<option value="{{name}}">{{title}}</option>
|
||||
{{/filtertypes}}
|
||||
</select>
|
||||
|
||||
<div data-filterregion="value" class="d-md-flex flex-column align-items-start flex-lg-row"></div>
|
||||
|
||||
<button data-filteraction="remove" class="ml-auto icon-no-margin icon-size-4 btn text-reset" aria-label="{{#str}}clearfilterrow, core_user{{/str}}">
|
||||
<i class="icon fa fa-times-circle"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div data-filterregion="joinadverb" class="pl-1 text-uppercase font-weight-bold">
|
||||
<div data-filterverbfor="0">{{#str}}adverbfor_andnot, core_user{{/str}}</div>
|
||||
<div data-filterverbfor="1">{{#str}}adverbfor_or, core_user{{/str}}</div>
|
||||
<div data-filterverbfor="2">{{#str}}adverbfor_and, core_user{{/str}}</div>
|
||||
</div>
|
||||
<div data-filterregion="joinadverb" class="pl-1 text-uppercase font-weight-bold">
|
||||
<div data-filterverbfor="0">{{#str}}adverbfor_andnot, core_user{{/str}}</div>
|
||||
<div data-filterverbfor="1">{{#str}}adverbfor_or, core_user{{/str}}</div>
|
||||
<div data-filterverbfor="2">{{#str}}adverbfor_and, core_user{{/str}}</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user