text: import Debouncer from 'src/helper/debouncer.helper';
  import Feature from 'src/helper/feature.helper';
  
  /**
   * Viewport Detection
   */
  const RESIZE_DEBOUNCE_TIME = 200;
  
  export default class ViewportDetection {
  
      /**
       * Constructor
       */
      constructor() {
          this.previousViewport = null;
          this.currentViewport = ViewportDetection.getCurrentViewport();
          this._registerEvents();
      }
  
      /**
       * Register events
       * @private
       */
      _registerEvents() {
          // add listener on DOMContentLoaded to initially register viewport events
          window.addEventListener('DOMContentLoaded', this._onDOMContentLoaded.bind(this));
  
          // add listener to the window resize events
          window.addEventListener(
              'resize',
              Debouncer.debounce(this._onResize.bind(this), RESIZE_DEBOUNCE_TIME),
              {
                  capture: true,
                  passive: true,
              }
          );
      }
  
      /**
       * Dispatch the custom viewport events immediately after DOM content
       * has been loaded to allow the execution of other JS code via listening the events
       * @private
       */
      _onDOMContentLoaded() {
          this._dispatchEvents();
      }
  
      /**
       * Dispatch the custom viewport event after window resizing
       * to allow the execution of other JS code via listening the events
       * @private
       */
      _onResize() {
          if (this._viewportHasChanged(ViewportDetection.getCurrentViewport())) {
              this._dispatchEvents();
  
              // dispatch event that a viewport change has taken place
              this._dispatchViewportEvent('Viewport/hasChanged');
          }
      }
  
      /**
       * Dispatch custom events for every single viewport
       * @private
       */
      _dispatchEvents() {
          // dispatch specific events for each single viewport
          if (ViewportDetection.isXS()) {
              this._dispatchViewportEvent('Viewport/isXS');
          } else if (ViewportDetection.isSM()) {
              this._dispatchViewportEvent('Viewport/isSM');
          } else if (ViewportDetection.isMD()) {
              this._dispatchViewportEvent('Viewport/isMD');
          } else if (ViewportDetection.isLG()) {
              this._dispatchViewportEvent('Viewport/isLG');
          } else if (ViewportDetection.isXL()) {
              this._dispatchViewportEvent('Viewport/isXL');
  
          /** @deprecated tag:v6.5.0 - Bootstrap v5 adds xxl breakpoint */
          } else if (ViewportDetection.isXXL() && Feature.isActive('V6_5_0_0')) {
              this._dispatchViewportEvent('Viewport/isXXL');
          }
      }
  
      /**
       * Determine whether the viewport has changed
       * @param newViewport
       * @returns {boolean}
       * @private
       */
      _viewportHasChanged(newViewport) {
          // determine whether the viewport has changed
          const hasChanged = newViewport !== this.currentViewport;
  
          if (hasChanged) {
              this.previousViewport = this.currentViewport;
              this.currentViewport = newViewport;
          }
  
          return hasChanged;
      }
  
      /**
       * Dispatch event with additional data
       * including the previous viewport
       * @param {string} eventName
       * @private
       */
      _dispatchViewportEvent(eventName) {
          document.$emitter.publish(eventName, {
              previousViewport: this.previousViewport,
          });
      }
  
      /**
       * Determine whether the current viewport is XS
       * @returns {boolean}
       */
      static isXS() {
          return (ViewportDetection.getCurrentViewport() === 'XS');
      }
  
      /**
       * Determine whether the current viewport is SM
       * @returns {boolean}
       */
      static isSM() {
          return (ViewportDetection.getCurrentViewport() === 'SM');
      }
  
      /**
       * Determine whether the current viewport is MD
       * @returns {boolean}
       */
      static isMD() {
          return (ViewportDetection.getCurrentViewport() === 'MD');
      }
  
      /**
       * Determine whether the current viewport is LG
       * @returns {boolean}
       */
      static isLG() {
          return (ViewportDetection.getCurrentViewport() === 'LG');
      }
  
      /**
       * Determine whether the current viewport is XL
       * @returns {boolean}
       */
      static isXL() {
          return (ViewportDetection.getCurrentViewport() === 'XL');
      }
  
      /**
       * Determine whether the current viewport is XXL
       * @internal tag:v6.5.0 - Bootstrap v5 adds xxl breakpoint
       * @returns {boolean}
       */
      static isXXL() {
          return (ViewportDetection.getCurrentViewport() === 'XXL');
      }
  
      /**
       * Determine the current viewport value set in the HTML::before element,
       * remove all quotes and convert it to uppercase
       * @returns {string}
       */
      static getCurrentViewport() {
          const viewport = window.getComputedStyle(document.documentElement, ':before').content;
          return viewport.replace(/['"]+/g, '').toUpperCase();
      }
  }
  