[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/media/system/js/ -> messages.js (source)

   1  class 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  
 233  if (!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  
 249  const 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}  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  
 285  Joomla.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  
 344  Joomla.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  
 355  document.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  });


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer