PageSourceSearch

https://zadna.org.za/media/system/js/messages.js?9a4811

js zadna.org.za collected 2026-09-24 18:32:37 UTC 10,432 bytes, 314 lines download raw bytes

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

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.