PageSourceSearch

https://www.ntccthailand.org/sites/default/files/js/optimized/js_e…b1p6aIl_3M1jyWpZA3GAaEMv0agFV0g.js?v=10.5.4

js ntccthailand.org collected 2026-09-25 00:07:45 UTC 4,564 bytes, 120 lines download raw bytes

1/* Source and licensing information for the line(s) below can be found at https://www.ntccthailand.org/core/misc/announce.js. */
2/**
3 * @file
4 * Adds an HTML element and method to trigger audio UAs to read system messages.
5 *
6 * Use {@link Drupal.announce} to indicate to screen reader users that an
7 * element on the page has changed state. For instance, if clicking a link
8 * loads 10 more items into a list, one might announce the change like this.
9 *
10 * @example
11 * $('#search-list')
12 *   .on('itemInsert', function (event, data) {
13 *     // Insert the new items.
14 *     $(data.container.el).append(data.items.el);
15 *     // Announce the change to the page contents.
16 *     Drupal.announce(Drupal.t('@count items added to @container',
17 *       {'@count': data.items.length, '@container': data.container.title}
18 *     ));
19 *   });
20 */
21
22(function (Drupal, debounce) {
23  let liveElement;
24  const announcements = [];
25
26  /**
27   * Builds a div element with the aria-live attribute and add it to the DOM.
28   *
29   * @type {Drupal~behavior}
30   *
31   * @prop {Drupal~behaviorAttach} attach
32   *   Attaches the behavior for drupalAnnounce.
33   */
34  Drupal.behaviors.drupalAnnounce = {
35    attach(context) {
36      // Create only one aria-live element.
37      if (!liveElement) {
38        liveElement = document.createElement('div');
39        liveElement.id = 'drupal-live-announce';
40        liveElement.className = 'visually-hidden';
41        liveElement.setAttribute('aria-live', 'polite');
42        liveElement.setAttribute('aria-busy', 'false');
43        document.body.appendChild(liveElement);
44      }
45    },
46  };
47
48  /**
49   * Concatenates announcements to a single string; appends to the live region.
50   */
51  function announce() {
52    const text = [];
53    let priority = 'polite';
54    let announcement;
55
56    // Create an array of announcement strings to be joined and appended to the
57    // aria live region.
58    const il = announcements.length;
59    for (let i = 0; i < il; i++) {
60      announcement = announcements.pop();
61      text.unshift(announcement.text);
62      // If any of the announcements has a priority of assertive then the group
63      // of joined announcements will have this priority.
64      if (announcement.priority === 'assertive') {
65        priority = 'assertive';
66      }
67    }
68
69    if (text.length) {
70      // Clear the liveElement so that repeated strings will be read.
71      liveElement.innerHTML = '';
72      // Set the busy state to true until the node changes are complete.
73      liveElement.setAttribute('aria-busy', 'true');
74      // Set the priority to assertive, or default to polite.
75      liveElement.setAttribute('aria-live', priority);
76      // Print the text to the live region. Text should be run through
77      // Drupal.t() before being passed to Drupal.announce().
78      liveElement.innerHTML = text.join('\n');
79      // The live text area is updated. Allow the AT to announce the text.
80      liveElement.setAttribute('aria-busy', 'false');
81    }
82  }
83
84  /**
85   * Triggers audio UAs to read the supplied text.
86   *
87   * The aria-live region will only read the text that currently populates its
88   * text node. Replacing text quickly in rapid calls to announce results in
89   * only the text from the most recent call to {@link Drupal.announce} being
90   * read. By wrapping the call to announce in a debounce function, we allow for
91   * time for multiple calls to {@link Drupal.announce} to queue up their
92   * messages. These messages are then joined and append to the aria-live region
93   * as one text node.
94   *
95   * @param {string} text
96   *   A string to be read by the UA.
97   * @param {string} [priority='polite']
98   *   A string to indicate the priority of the message. Can be either
99   *   'polite' or 'assertive'.
100   *
101   * @return {function}
102   *   The return of the call to debounce.
103   *
104   * @see https://www.w3.org/WAI/PF/aria-practices/#liveprops
105   */
106  Drupal.announce = function (text, priority) {
107    // Save the text and priority into a closure variable. Multiple simultaneous
108    // announcements will be concatenated and read in sequence.
109    announcements.push({
110      text,
111      priority,
112    });
113    // Immediately invoke the function that debounce returns. 200 ms is right at
114    // the cusp where humans notice a pause, so we will wait
115    // at most this much time before the set of queued announcements is read.
116    return debounce(announce, 200)();
117  };
118})(Drupal, Drupal.debounce);
119
120/* Source and licensing information for the above line(s) can be found at https://www.ntccthailand.org/core/misc/announce.js. */

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.