diff --git a/core/core.libraries.yml b/core/core.libraries.yml index ce12db5..4e4ef2a 100644 --- a/core/core.libraries.yml +++ b/core/core.libraries.yml @@ -225,6 +225,15 @@ drupal.machine-name: - core/drupalSettings - core/drupal.form +drupal.message: + version: VERSION + js: + misc/message.js: {} + dependencies: + - core/jquery + - core/drupal + - core/drupal.debounce + drupal.progress: version: VERSION js: diff --git a/core/misc/announce.js b/core/misc/announce.js index acf850a..4d29df5 100644 --- a/core/misc/announce.js +++ b/core/misc/announce.js @@ -34,7 +34,7 @@ * Attaches the behavior for drupalAnnouce. */ Drupal.behaviors.drupalAnnounce = { - attach: function (context) { + attach: function () { // Create only one aria-live element. if (!liveElement) { liveElement = document.createElement('div'); @@ -50,21 +50,23 @@ /** * Concatenates announcements to a single string; appends to the live region. */ - function announce() { + function processAnnounce() { var text = []; var priority = 'polite'; var announcement; - // Create an array of announcement strings to be joined and appended to the - // aria live region. - var il = announcements.length; - for (var i = 0; i < il; i++) { - announcement = announcements.pop(); - text.unshift(announcement.text); - // If any of the announcements has a priority of assertive then the group - // of joined announcements will have this priority. - if (announcement.priority === 'assertive') { - priority = 'assertive'; + if (announcements.length) { + // Create an array of announcement strings to be joined and appended to + // the aria live region. + var il = announcements.length; + for (var i = 0; i < il; i++) { + announcement = announcements.pop(); + text.unshift(announcement.text); + // If any of the announcements has a priority of assertive then the + // group of joined announcements will have this priority. + if (announcement.priority === 'assertive') { + priority = 'assertive'; + } } } @@ -81,8 +83,13 @@ // The live text area is updated. Allow the AT to announce the text. liveElement.setAttribute('aria-busy', 'false'); } + } + // 200 ms is right at the cusp where humans notice a pause, so we will wait + // at most this much time before the set of queued announcements is read. + var debouncedProcessAnnounce = debounce(processAnnounce, 200); + /** * Triggers audio UAs to read the supplied text. * @@ -94,9 +101,9 @@ * messages. These messages are then joined and append to the aria-live region * as one text node. * - * @param {string} text + * @param {String} text * A string to be read by the UA. - * @param {string} [priority='polite'] + * @param {String} priority * A string to indicate the priority of the message. Can be either * 'polite' or 'assertive'. * @@ -106,15 +113,14 @@ * @see http://www.w3.org/WAI/PF/aria-practices/#liveprops */ Drupal.announce = function (text, priority) { - // Save the text and priority into a closure variable. Multiple simultaneous - // announcements will be concatenated and read in sequence. - announcements.push({ - text: text, - priority: priority - }); - // Immediately invoke the function that debounce returns. 200 ms is right at - // the cusp where humans notice a pause, so we will wait - // at most this much time before the set of queued announcements is read. - return (debounce(announce, 200)()); + if (typeof text === 'string') { + // Save the text and priority into a closure variable. Multiple + // simultaneous announcements will be concatenated and read in sequence. + announcements.push({ + text: text, + priority: priority + }); + debouncedProcessAnnounce(announcements); + } }; }(Drupal, Drupal.debounce)); diff --git a/core/modules/system/templates/status-messages.html.twig b/core/modules/system/templates/status-messages.html.twig index 73bd9b7..243df6e 100644 --- a/core/modules/system/templates/status-messages.html.twig +++ b/core/modules/system/templates/status-messages.html.twig @@ -23,25 +23,26 @@ * @ingroup themeable */ #} -{% for type, messages in message_list %} -
- {% if type == 'error' %} -
- {% endif %} - {% if status_headings[type] %} -

{{ status_headings[type] }}

- {% endif %} - {% if messages|length > 1 %} - - {% else %} - {{ messages|first }} - {% endif %} - {% if type == 'error' %} -
- {% endif %} -
-{% endfor %} +
+ {% for type, messages in message_list %} +
+ {% if type == 'error' %} +
+ {% endif %} + {% if status_headings[type] %} +

{{ status_headings[type] }}

+ {% endif %} + {% if messages|length > 1 %} +
    + {% for message in messages %} +
  • {{ message }}
  • + {% endfor %} +
+ {% else %} + {{ messages|first }} + {% endif %} +
+ {% endfor %} +
+
\ No newline at end of file diff --git a/core/themes/classy/templates/misc/status-messages.html.twig b/core/themes/classy/templates/misc/status-messages.html.twig index bc8fd10..c635a58 100644 --- a/core/themes/classy/templates/misc/status-messages.html.twig +++ b/core/themes/classy/templates/misc/status-messages.html.twig @@ -21,7 +21,7 @@ * - class: HTML classes. */ #} -{{ attach_library('classy/messages') }} +
{% block messages %} {% for type, messages in message_list %} {% @@ -54,3 +54,4 @@ {% set attributes = attributes.removeClass(classes) %} {% endfor %} {% endblock messages %} +
\ No newline at end of file