PageSourceSearch

https://www.starwoodhotels.com/core/misc/message.js?v=10.6.15

js starwoodhotels.com collected 2026-09-24 08:30:08 UTC 8,446 bytes, 268 lines download raw bytes

1/**
2 * @file
3 * Message API.
4 */
5((Drupal) => {
6  /**
7   * @typedef {class} Drupal.Message~messageDefinition
8   */
9
10  /**
11   * Constructs a new instance of the Drupal.Message class.
12   *
13   * This provides a uniform interface for adding and removing messages to a
14   * specific location on the page.
15   *
16   * @param {HTMLElement} messageWrapper
17   *   The zone where to add messages. If no element is provided an attempt is
18   *   made to determine a default location.
19   *
20   * @return {Drupal.Message~messageDefinition}
21   *   Class to add and remove messages.
22   */
23  Drupal.Message = class {
24    constructor(messageWrapper = null) {
25      if (!messageWrapper) {
26        this.messageWrapper = Drupal.Message.defaultWrapper();
27      } else {
28        this.messageWrapper = messageWrapper;
29      }
30    }
31
32    /**
33     * Attempt to determine the default location for
34     * inserting JavaScript messages or create one if needed.
35     *
36     * @return {HTMLElement}
37     *   The default destination for JavaScript messages.
38     */
39    static defaultWrapper() {
40      // Search for the element with '[data-drupal-messages]' selector.
41      // If not found then only try to search for fallback element.
42      let wrapper =
43        document.querySelector('[data-drupal-messages]') ||
44        document.querySelector('[data-drupal-messages-fallback]');
45      if (!wrapper) {
46        // If no status messages element is found, a fallback element is created to prevent
47        // execution-breaking JS errors when attempting to report a problem.
48        // This scenario can occur on any page that does not include a status_messages
49        // render element.
50        wrapper = document.createElement('div');
51        document.body.appendChild(wrapper);
52      }
53
54      if (wrapper.hasAttribute('data-drupal-messages-fallback')) {
55        // Remove the fallback attribute if it exists.
56        wrapper.removeAttribute('data-drupal-messages-fallback');
57        wrapper.classList.remove('hidden');
58      }
59      wrapper.setAttribute('data-drupal-messages', '');
60
61      return wrapper.innerHTML === ''
62        ? Drupal.Message.messageInternalWrapper(wrapper)
63        : wrapper.firstElementChild;
64    }
65
66    /**
67     * Provide an object containing the available message types.
68     *
69     * @return {Object}
70     *   An object containing message type strings.
71     */
72    static getMessageTypeLabels() {
73      return {
74        status: Drupal.t('Status message'),
75        error: Drupal.t('Error message'),
76        warning: Drupal.t('Warning message'),
77      };
78    }
79
80    /**
81     * Sequentially adds a message to the message area.
82     *
83     * @name Drupal.Message~messageDefinition.add
84     *
85     * @param {string} message
86     *   The message to display
87     * @param {object} [options]
88     *   The context of the message.
89     * @param {string} [options.id]
90     *   The message ID, it can be a simple value: `'file_validation_error'`
91     *   or several values separated by a space: `'my_module form_validation'`
92     *   which can be used as an explicit selector for a message.
93     * @param {string} [options.type=status]
94     *   Message type, can be either 'status', 'error' or 'warning'.
95     * @param {string} [options.announce]
96     *   Screen-reader version of the message if necessary. To prevent a message
97     *   being sent to Drupal.announce() this should be an empty string.
98     * @param {string} [options.priority]
99     *   Priority of the message for Drupal.announce().
100     *
101     * @return {string}
102     *   ID of message.
103     */
104    add(message, options = {}) {
105      if (!options.hasOwnProperty('type')) {
106        options.type = 'status';
107      }
108
109      if (typeof message !== 'string') {
110        throw new Error('Message must be a string.');
111      }
112
113      // Send message to screen reader.
114      Drupal.Message.announce(message, options);
115      /**
116       * Use the provided index for the message or generate a pseudo-random key
117       * to allow message deletion.
118       */
119      options.id = options.id
120        ? String(options.id)
121        : `${options.type}-${Math.random().toFixed(15).replace('0.', '')}`;
122
123      // Throw an error if an unexpected message type is used.
124      if (!Drupal.Message.getMessageTypeLabels().hasOwnProperty(options.type)) {
125        const { type } = options;
126        throw new Error(
127          `The message type, ${type}, is not present in Drupal.Message.getMessageTypeLabels().`,
128        );
129      }
130
131      this.messageWrapper.appendChild(
132        Drupal.theme('message', { text: message }, options),
133      );
134
135      return options.id;
136    }
137
138    /**
139     * Select a message based on id.
140     *
141     * @name Drupal.Message~messageDefinition.select
142     *
143     * @param {string} id
144     *   The message id to delete from the area.
145     *
146     * @return {Element}
147     *   Element found.
148     */
149    select(id) {
150      return this.messageWrapper.querySelector(
151        `[data-drupal-message-id^="${id}"]`,
152      );
153    }
154
155    /**
156     * Removes a message element from the message area.
157     *
158     * @name Drupal.Message~messageDefinition.remove
159     *
160     * @param {string} id
161     *   The unique identifier of the message to remove, as returned by
162     *   {@link Drupal.Message~messageDefinition.add}.
163     *
164     * @return {Element}
165     *   Returns the removed message element.
166     */
167    remove(id) {
168      return this.messageWrapper.removeChild(this.select(id));
169    }
170
171    /**
172     * Removes all messages from the message area.
173     *
174     * @name Drupal.Message~messageDefinition.clear
175     */
176    clear() {
177      Array.prototype.forEach.call(
178        this.messageWrapper.querySelectorAll('[data-drupal-message-id]'),
179        (message) => {
180          this.messageWrapper.removeChild(message);
181        },
182      );
183    }
184
185    /**
186     * Helper to call Drupal.announce() with the right parameters.
187     *
188     * @param {string} message
189     *   Displayed message.
190     * @param {object} options
191     *   Additional data.
192     * @param {string} [options.announce]
193     *   Screen-reader version of the message if necessary. To prevent a message
194     *   being sent to Drupal.announce() this should be `''`.
195     * @param {string} [options.priority]
196     *   Priority of the message for Drupal.announce().
197     * @param {string} [options.type]
198     *   Message type, can be either 'status', 'error' or 'warning'.
199     */
200    static announce(message, options) {
201      if (
202        !options.priority &&
203        (options.type === 'warning' || options.type === 'error')
204      ) {
205        options.priority = 'assertive';
206      }
207      /**
208       * If screen reader message is not disabled announce screen reader
209       * specific text or fallback to the displayed message.
210       */
211      if (options.announce !== '') {
212        Drupal.announce(options.announce || message, options.priority);
213      }
214    }
215
216    /**
217     * Function for creating the internal message wrapper element.
218     *
219     * @param {HTMLElement} messageWrapper
220     *   The message wrapper.
221     *
222     * @return {HTMLElement}
223     *   The internal wrapper DOM element.
224     */
225    static messageInternalWrapper(messageWrapper) {
226      const innerWrapper = document.createElement('div');
227      innerWrapper.setAttribute('class', 'messages__wrapper');
228      messageWrapper.insertAdjacentElement('afterbegin', innerWrapper);
229      return innerWrapper;
230    }
231  };
232
233  /**
234   * Theme function for a message.
235   *
236   * @param {object} message
237   *   The message object.
238   * @param {string} message.text
239   *   The message text.
240   * @param {object} options
241   *   The message context.
242   * @param {string} options.type
243   *   The message type.
244   * @param {string} options.id
245   *   ID of the message, for reference.
246   *
247   * @return {HTMLElement}
248   *   A DOM Node.
249   */
250  Drupal.theme.message = ({ text }, { type, id }) => {
251    const messagesTypes = Drupal.Message.getMessageTypeLabels();
252    const messageWrapper = document.createElement('div');
253
254    messageWrapper.setAttribute('class', `messages messages--${type}`);
255    messageWrapper.setAttribute(
256      'role',
257      type === 'error' || type === 'warning' ? 'alert' : 'status',
258    );
259    messageWrapper.setAttribute('data-drupal-message-id', id);
260    messageWrapper.setAttribute('data-drupal-message-type', type);
261
262    messageWrapper.setAttribute('aria-label', messagesTypes[type]);
263
264    messageWrapper.innerHTML = `${text}`;
265
266    return messageWrapper;
267  };
268})(Drupal);

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.