MDL-68167 lib: Autocomplete selection to use listbox aria role
authorShamim Rezaie <shamim@moodle.com>
Mon, 27 Jul 2020 03:36:25 +0000 (13:36 +1000)
committerShamim Rezaie <shamim@moodle.com>
Fri, 30 Oct 2020 03:59:50 +0000 (14:59 +1100)
The aria-selected state cannot be used for the listitem role. The
autocomplete widget highly uses the aria-selected state internally.

12 files changed:
lib/amd/build/form-autocomplete.min.js
lib/amd/build/form-autocomplete.min.js.map
lib/amd/src/form-autocomplete.js
lib/behat/classes/partial_named_selector.php
lib/templates/form_autocomplete_selection.mustache
lib/templates/form_autocomplete_selection_items.mustache
mod/feedback/tests/behat/coursemapping.feature
theme/boost/scss/moodle/forms.scss
theme/boost/style/moodle.css
theme/classic/style/moodle.css
user/templates/local/participantsfilter/autocomplete_selection.mustache
user/templates/local/participantsfilter/autocomplete_selection_items.mustache

index f27fea3..2db663c 100644 (file)
Binary files a/lib/amd/build/form-autocomplete.min.js and b/lib/amd/build/form-autocomplete.min.js differ
index 7888e0d..bcee522 100644 (file)
Binary files a/lib/amd/build/form-autocomplete.min.js.map and b/lib/amd/build/form-autocomplete.min.js.map differ
index 71b7e95..bde69cd 100644 (file)
@@ -781,7 +781,7 @@ function($, log, str, templates, notification, LoadingIcon, Aria) {
         var suggestionsElement = $(document.getElementById(state.suggestionsId));
         // Remove any click handler first.
         suggestionsElement.parent().prop("onclick", null).off("click");
-        suggestionsElement.parent().on('click', '[role=option]', function(e) {
+        suggestionsElement.parent().on('click', `#${state.suggestionsId} [role=option]`, function(e) {
             var pendingPromise = addPendingJSPromise('form-autocomplete-parent');
             // Handle clicks on suggestions.
             var element = $(e.currentTarget).closest('[role=option]');
@@ -802,7 +802,7 @@ function($, log, str, templates, notification, LoadingIcon, Aria) {
         });
         var selectionElement = $(document.getElementById(state.selectionId));
         // Handle clicks on the selected items (will unselect an item).
-        selectionElement.on('click', '[role=listitem]', function(e) {
+        selectionElement.on('click', '[role=option]', function(e) {
             var pendingPromise = addPendingJSPromise('form-autocomplete-clicks');
 
             // Remove it from the selection.
index 1b2d43e..18c1526 100644 (file)
@@ -226,7 +226,7 @@ XPATH
     /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%)]
+.//div[contains(concat(' ', normalize-space(@class), ' '), concat(' ', 'form-autocomplete-selection', ' '))]/span[@role='option'][contains(normalize-space(.), %locator%)]
 XPATH
         , 'autocomplete_suggestions' => <<<XPATH
 .//ul[contains(concat(' ', normalize-space(@class), ' '), concat(' ', 'form-autocomplete-suggestions', ' '))]/li[@role='option'][contains(normalize-space(.), %locator%)]
index 932ad37..9c04e25 100644 (file)
         { "label": "Another item label with <strong>tags</strong>", "value": "4" }
     ], "noSelectionString": "No selection" }
 }}
-<div class="form-autocomplete-selection w-100 {{#multiple}}form-autocomplete-multiple{{/multiple}}" id="{{selectionId}}" role="list" aria-atomic="true" {{#multiple}}tabindex="0" aria-multiselectable="true"{{/multiple}}>
+<div{{!
+    }} class="form-autocomplete-selection w-100 {{#multiple}}form-autocomplete-multiple{{/multiple}}"{{!
+    }} id="{{selectionId}}"{{!
+    }} role="listbox"{{!
+    }} aria-atomic="true"{{!
+    }} {{#multiple}}tabindex="0" aria-multiselectable="true"{{/multiple}}>
 <span class="accesshide">{{#str}}selecteditems, form{{/str}}</span>
     {{> core/form_autocomplete_selection_items }}
 </div>
index 22ff5f2..bb9f16c 100644 (file)
@@ -38,7 +38,7 @@
     ], "noSelectionString": "No selection" }
 }}
 {{#items}}
-    <span role="listitem" data-value="{{value}}" aria-selected="true" class="badge badge-info mb-3 mr-1" style="font-size: 100%">
+    <span role="option" data-value="{{value}}" aria-selected="true" class="badge badge-info mb-3 mr-1" style="font-size: 100%">
         <span aria-hidden="true">× </span>{{{label}}}
     </span>
 {{/items}}
index a7ee83a..112ead2 100644 (file)
@@ -111,7 +111,7 @@ Feature: Mapping courses in a feedback
     And I follow "Course feedback"
 
     And I navigate to "Analysis" in current page administration
-    And I should see "All courses" in the "#feedback_course_filter [data-fieldtype=autocomplete] .form-autocomplete-selection [role=listitem]" "css_element"
+    And I should see "All courses" in the "#feedback_course_filter [data-fieldtype=autocomplete] .form-autocomplete-selection [role=option]" "css_element"
     And I show chart data for the "multichoicerated" feedback
     And I should see "1 (33.33 %)" in the "option a" "table_row"
     And I should see "1 (33.33 %)" in the "option b" "table_row"
@@ -123,7 +123,7 @@ Feature: Mapping courses in a feedback
     And I click on "Back" "link" in the "region-main" "region"
     And I set the field "Filter by course" to "Course 1"
     And I press "Filter"
-    And I should see "Course 1" in the "#feedback_course_filter [data-fieldtype=autocomplete] .form-autocomplete-selection [role=listitem]" "css_element"
+    And I should see "Course 1" in the "#feedback_course_filter [data-fieldtype=autocomplete] .form-autocomplete-selection [role=option]" "css_element"
     And I show chart data for the "multichoicerated" feedback
     And I should see "0" in the "option a" "table_row"
     And I should see "1 (50.00 %)" in the "option b" "table_row"
@@ -193,7 +193,7 @@ Feature: Mapping courses in a feedback
     And I am on site homepage
     And I follow "Course feedback"
     And I navigate to "Analysis" in current page administration
-    And I should see "All courses" in the "#feedback_course_filter [data-fieldtype=autocomplete] .form-autocomplete-selection [role=listitem]" "css_element"
+    And I should see "All courses" in the "#feedback_course_filter [data-fieldtype=autocomplete] .form-autocomplete-selection [role=option]" "css_element"
     And I show chart data for the "multichoicerated" feedback
     And I should see "0" in the "option a" "table_row"
     And I should see "1 (33.33 %)" in the "option b" "table_row"
index a8ef676..5e915f7 100644 (file)
@@ -276,7 +276,7 @@ fieldset.coursesearchbox label {
     min-height: 2 * $input-padding-y-sm + 2 * $font-size-base;
 }
 
-.form-autocomplete-selection [role=listitem] {
+.form-autocomplete-selection [role=option] {
     cursor: pointer;
     white-space: inherit;
     word-break: break-word;
index 861b225..2b6fb43 100644 (file)
@@ -16522,7 +16522,7 @@ fieldset.coursesearchbox label {
   margin: 0.25rem;
   min-height: 2.375rem; }
 
-.form-autocomplete-selection [role=listitem] {
+.form-autocomplete-selection [role=option] {
   cursor: pointer;
   white-space: inherit;
   word-break: break-word;
index e9ff491..b6ed702 100644 (file)
@@ -16748,7 +16748,7 @@ fieldset.coursesearchbox label {
   margin: 0.25rem;
   min-height: 2.375rem; }
 
-.form-autocomplete-selection [role=listitem] {
+.form-autocomplete-selection [role=option] {
   cursor: pointer;
   white-space: inherit;
   word-break: break-word;
index b5db9c8..3278577 100644 (file)
@@ -40,9 +40,9 @@
 <div{{!
     }} class="form-autocomplete-selection d-inline-block my-0{{#multiple}} form-autocomplete-multiple h5{{/multiple}}"{{!
     }} id="{{selectionId}}"{{!
-    }} role="list"{{!
+    }} role="listbox"{{!
     }} aria-atomic="true"{{!
-    }}{{#multiple}} tabindex="0" {{/multiple}}{{!
+    }}{{#multiple}} tabindex="0" aria-multiselectable="true"{{/multiple}}{{!
     }}>
 <span class="accesshide">{{#str}}selecteditems, form{{/str}}</span>
     {{> core/form_autocomplete_selection_items }}
index 71a36db..4faad8c 100644 (file)
@@ -41,7 +41,7 @@
     }
 }}
 {{#items}}
-    <span role="listitem" data-value="{{value}}" aria-selected="true"
+    <span role="option" data-value="{{value}}" aria-selected="true"
             class="badge badge-secondary clickable text-wrap text-break line-height-4 m-1">
         {{label}}<i class="icon fa fa-times pl-2 mr-0"></i>
     </span>