PageSourceSearch

https://cchs.org.uk/media/system/js/messages.js?7425e8d1cb9e4f061d5e30271d6d99b085344117

js cchs.org.uk collected 2026-10-05 07:06:14 UTC 10,540 bytes, 361 lines download raw bytes

1class AlertElement extends HTMLElement {
2  constructor() {
3    super(); // Bindings
4
5    this.close = this.close.bind(this);
6    this.destroyCloseButton = this.destroyCloseButton.bind(this);
7    this.createCloseButton = this.createCloseButton.bind(this);
8    this.onMutation = this.onMutation.bind(this);
9    this.observer = new MutationObserver(this.onMutation);
10    this.observer.observe(this, {
11      attributes: false,
12      childList: true,
13      subtree: true
14    }); // Handle the fade in animation
15
16    this.addEventListener('animationend', event => {
17      if (event.animationName === 'joomla-alert-fade-in' && event.target === this) {
18        this.dispatchEvent(new CustomEvent('joomla.alert.shown'));
19        this.style.removeProperty('animationName');
20      }
21    }); // Handle the fade out animation
22
23    this.addEventListener('animationend', event => {
24      if (event.animationName === 'joomla-alert-fade-out' && event.target === this) {
25        this.dispatchEvent(new CustomEvent('joomla.alert.closed'));
26        this.remove();
27      }
28    });
29  }
30  /* Attributes to monitor */
31
32
33  static get observedAttributes() {
34    return ['type', 'role', 'dismiss', 'auto-dismiss', 'close-text'];
35  }
36
37  get type() {
38    return this.getAttribute('type');
39  }
40
41  set type(value) {
42    this.setAttribute('type', value);
43  }
44
45  get role() {
46    return this.getAttribute('role');
47  }
48
49  set role(value) {
50    this.setAttribute('role', value);
51  }
52
53  get closeText() {
54    return this.getAttribute('close-text');
55  }
56
57  set closeText(value) {
58    this.setAttribute('close-text', value);
59  }
60
61  get dismiss() {
62    return this.getAttribute('dismiss');
63  }
64
65  set dismiss(value) {
66    this.setAttribute('dismiss', value);
67  }
68
69  get autodismiss() {
70    return this.getAttribute('auto-dismiss');
71  }
72
73  set autodismiss(value) {
74    this.setAttribute('auto-dismiss', value);
75  }
76  /* Lifecycle, element appended to the DOM */
77
78
79  connectedCallback() {
80    this.dispatchEvent(new CustomEvent('joomla.alert.show'));
81    this.style.animationName = 'joomla-alert-fade-in'; // Default to info
82
83    if (!this.type || !['info', 'warning', 'danger', 'success'].includes(this.type)) {
84      this.setAttribute('type', 'info');
85    } // Default to alert
86
87
88    if (!this.role || !['alert', 'alertdialog'].includes(this.role)) {
89      this.setAttribute('role', 'alert');
90    } // Hydrate the button
91
92
93    if (this.firstElementChild && this.firstElementChild.tagName === 'BUTTON') {
94      this.button = this.firstElementChild;
95
96      if (this.button.classList.contains('joomla-alert--close')) {
97        this.button.classList.add('joomla-alert--close');
98      }
99
100      if (this.button.innerHTML === '') {
101        this.button.innerHTML = '<span aria-hidden="true">&times;</span>';
102      }
103
104      if (!this.button.hasAttribute('aria-label')) {
105        this.button.setAttribute('aria-label', this.closeText);
106      }
107    } // Append button
108
109
110    if (this.hasAttribute('dismiss') && !this.button) {
111      this.createCloseButton();
112    }
113
114    if (this.hasAttribute('auto-dismiss')) {
115      this.autoDismiss();
116    }
117  }
118  /* Lifecycle, element removed from the DOM */
119
120
121  disconnectedCallback() {
122    if (this.button) {
123      this.button.removeEventListener('click', this.close);
124    }
125
126    this.observer.disconnect();
127  }
128  /* Respond to attribute changes */
129
130
131  attributeChangedCallback(attr, oldValue, newValue) {
132    switch (attr) {
133      case 'type':
134        if (!newValue || newValue && ['info', 'warning', 'danger', 'success'].indexOf(newValue) === -1) {
135          this.type = 'info';
136        }
137
138        break;
139
140      case 'role':
141        if (!newValue || newValue && ['alert', 'alertdialog'].indexOf(newValue) === -1) {
142          this.role = 'alert';
143        }
144
145        break;
146
147      case 'dismiss':
148        if ((!newValue || newValue === '') && (!oldValue || oldValue === '')) {
149          if (this.button && !this.hasAttribute('dismiss')) {
150            this.destroyCloseButton();
151          } else if (!this.button && this.hasAttribute('dismiss')) {
152            this.createCloseButton();
153          }
154        } else if (this.button && newValue === 'false') {
155          this.destroyCloseButton();
156        } else if (!this.button && newValue !== 'false') {
157          this.createCloseButton();
158        }
159
160        break;
161
162      case 'close-text':
163        if (!newValue || newValue !== oldValue) {
164          if (this.button) {
165            this.button.setAttribute('aria-label', newValue);
166          }
167        }
168
169        break;
170
171      case 'auto-dismiss':
172        this.autoDismiss();
173        break;
174    }
175  }
176  /* Observe added elements */
177
178
179  onMutation(mutationsList) {
180    // eslint-disable-next-line no-restricted-syntax
181    for (const mutation of mutationsList) {
182      if (mutation.type === 'childList') {
183        if (mutation.addedNodes.length) {
184          // Make sure that the button is always the first element
185          if (this.button && this.firstElementChild !== this.button) {
186            this.prepend(this.button);
187          }
188        }
189      }
190    }
191  }
192  /* Method to close the alert */
193
194
195  close() {
196    this.dispatchEvent(new CustomEvent('joomla.alert.close'));
197    this.style.animationName = 'joomla-alert-fade-out';
198  }
199  /* Method to create the close button */
200
201
202  createCloseButton() {
203    this.button = document.createElement('button');
204    this.button.setAttribute('type', 'button');
205    this.button.classList.add('joomla-alert--close');
206    this.button.innerHTML = '<span aria-hidden="true">&times;</span>';
207    this.button.setAttribute('aria-label', this.closeText);
208    this.insertAdjacentElement('afterbegin', this.button);
209    /* Add the required listener */
210
211    this.button.addEventListener('click', this.close);
212  }
213  /* Method to remove the close button */
214
215
216  destroyCloseButton() {
217    if (this.button) {
218      this.button.removeEventListener('click', this.close);
219      this.button.parentNode.removeChild(this.button);
220      this.button = null;
221    }
222  }
223  /* Method to auto-dismiss */
224
225
226  autoDismiss() {
227    const timer = parseInt(this.getAttribute('auto-dismiss'), 10);
228    setTimeout(this.close, timer >= 10 ? timer : 3000);
229  }
230
231}
232
233if (!customElements.get('joomla-alert')) {
234  customElements.define('joomla-alert', AlertElement);
235}
236
237/**
238 * @copyright  (C) 2020 Open Source Matters, Inc. <https://www.joomla.org>
239 * @license    GNU General Public License version 2 or later; see LICENSE.txt
240 */
241/**
242 * Returns the container of the Messages
243 *
244 * @param {string|HTMLElement}  container  The container
245 *
246 * @returns {HTMLElement}
247 */
248
249const getMessageContainer = container => {
250  let messageContainer;
251
252  if (container instanceof HTMLElement) {
253    return container;
254  }
255
256  if (typeof container === 'undefined' || container && container === '#system-message-container') {
257    messageContainer = document.getElementById('system-message-container');
258  } else {
259    messageContainer = document.querySelector(container);
260  }
261
262  return messageContainer;
263};
264/**
265 * Render messages send via JSON
266 * Used by some javascripts such as validate.js
267 *
268 * @param   {object}
268  messages JavaScript object containing the messages to render.
269 *          Example:
270 *          const messages = {
271 *              "message": ["This will be a green message", "So will this"],
272 *              "error": ["This will be a red message", "So will this"],
273 *              "info": ["This will be a blue message", "So will this"],
274 *              "notice": ["This will be same as info message", "So will this"],
275 *              "warning": ["This will be a orange message", "So will this"],
276 *              "my_custom_type": ["This will be same as info message", "So will this"]
277 *          };
278 * @param  {string} selector The selector of the container where the message will be rendered
279 * @param  {bool}   keepOld  If we shall discard old messages
280 * @param  {int}    timeout  The milliseconds before the message self destruct
281 * @return  void
282 */
283
284
285Joomla.renderMessages = (messages, selector, keepOld, timeout) => {
286  const messageContainer = getMessageContainer(selector);
287
288  if (typeof keepOld === 'undefined' || keepOld && keepOld === false) {
289    Joomla.removeMessages(messageContainer);
290  }
291
292  [].slice.call(Object.keys(messages)).forEach(type => {
293    let alertClass = type; // Array of messages of this type
294
295    const typeMessages = messages[type];
296    const messagesBox = document.createElement('joomla-alert');
297
298    if (['success', 'info', 'danger', 'warning'].indexOf(type) < 0) {
299      alertClass = type === 'notice' ? 'info' : type;
300      alertClass = type === 'message' ? 'success' : alertClass;
301      alertClass = type === 'error' ? 'danger' : alertClass;
302      alertClass = type === 'warning' ? 'warning' : alertClass;
303    }
304
305    messagesBox.setAttribute('type', alertClass);
306    messagesBox.setAttribute('close-text', Joomla.Text._('JCLOSE'));
307    messagesBox.setAttribute('dismiss', true);
308
309    if (timeout && parseInt(timeout, 10) > 0) {
310      messagesBox.setAttribute('auto-dismiss', timeout);
311    } // Title
312
313
314    const title = Joomla.Text._(type); // Skip titles with untranslated strings
315
316
317    if (typeof title !== 'undefined') {
318      const titleWrapper = document.createElement('div');
319      titleWrapper.className = 'alert-heading';
320      titleWrapper.innerHTML = Joomla.sanitizeHtml(`<span class="${type}"></span><span class="visually-hidden">${Joomla.Text._(type) ? Joomla.Text._(type) : type}</span>`);
321      messagesBox.appendChild(titleWrapper);
322    } // Add messages to the message box
323
324
325    const messageWrapper = document.createElement('div');
326    messageWrapper.className = 'alert-wrapper';
327    typeMessages.forEach(typeMessage => {
328      messageWrapper.innerHTML += Joomla.sanitizeHtml(`<div class="alert-message">${typeMessage}</div>`);
329    });
330    messagesBox.appendChild(messageWrapper);
331    messageContainer.appendChild(messagesBox);
332  });
333};
334/**
335 * Remove messages
336 *
337 * @param  {element} container The element of the container of the message
338 * to be removed
339 *
340 * @return  {void}
341 */
342
343
344Joomla.removeMessages = container => {
345  const messageContainer = getMessageContainer(container);
346  const alerts = [].slice.call(messageContainer.querySelectorAll('joomla-alert'));
347
348  if (alerts.length) {
349    alerts.forEach(alert => {
350      alert.close();
351    });
352  }
353};
354
355document.addEventListener('DOMContentLoaded', () => {
356  const messages = Joomla.getOptions('joomla.messages');
357
358  if (messages) {
359    Object.keys(messages).map(message => Joomla.renderMessages(messages[message], undefined, true, undefined));
360  }
361});

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.