Source: popin.es6.js

/**
* Popin class.
* @class Popin
*/
class Popin {
  /**
  * Represents an Popin instance.
  * @constructs Popin
  * @param {Object} options - Options to configure the plugin
  * @param {string} options.input - Selector of the input to bind
  * @param {Array} [options.data] - Data to use
  */
  constructor( params ) {
    var defaultParams = {
      overlay : true
    }
    if(params) {
      for (var key in params) {
        if (defaultParams.hasOwnProperty(key)) {
          defaultOptions[key] = params[key];
        }
      }
    }
    this.popins  = document.querySelectorAll(defaultParams && defaultParams.popin ? defaultParams.popin : '.js-popin');
    this.isDevice = 'ontouchstart' in document.documentElement;
    this.instanciedPopins = [];
    this.instanciedPopinsOptions = [];
    this.openedPopins = [];

    /** create overlay when params.overlay is true */
    if(defaultParams.overlay){
      var overlay = document.createElement('div');
      overlay.id = 'popin-overlay';
      overlay.className = 'popin-overlay';

      document.body.appendChild(overlay);
      this.overlay = document.getElementById('popin-overlay');
      this.overlay.addEventListener('click', (e) => {
        var popinOptions = this.instanciedPopinsOptions[this.openedPopins[this.openedPopins.length-1]];
        this.close(popinOptions);
      }, false);
    }
  }

  /** init generic popins ans specifique if selector is past in arg */
  init(options) {
    var defaultOptions = {
      overlayVisible : true,
      closeButton : true
    }
    if(options) {
      for (var key in options) {
        if (options.hasOwnProperty(key)) {
          defaultOptions[key] = options[key];
        }
      }
    }
    var _this  = this;
    if(defaultOptions.className) {
      this[defaultOptions.className]  = document.querySelectorAll('.'+defaultOptions.className);
    }


    [].forEach.call((this[defaultOptions.className]) ? this[defaultOptions.className] : this.popins, (popin, i) => {
      var elements = {
        overlayVisible : defaultOptions.overlayVisible,
        closeButton : defaultOptions.closeButton,
        buttonSticky : defaultOptions.buttonSticky,
        popinId : (defaultOptions.content) ? 'popin-'+this.instanciedPopins.length : popin.getAttribute('data-target'),
        beforeOpen : defaultOptions.beforeOpen,
        afterOpen : defaultOptions.afterOpen,
        beforeClose : defaultOptions.beforeClose,
        afterClose : defaultOptions.afterClose,
        disableAfterClose : defaultOptions.disableAfterClose,
        link : popin
      };

      /** if content is past in params add content to body */
      if(defaultOptions.content){
          var div = document.createElement('div');
          div.id = 'popin-'+this.instanciedPopins.length;
          div.className = "popin";
          div.innerHTML = defaultOptions.content
          document.body.appendChild(div);
      }

      popin.setAttribute('data-popin-id',this.instanciedPopins.length);
      popin.setAttribute('data-className',defaultOptions.className ? defaultOptions.className :'js-popin' );
      this.instanciedPopins.push(elements.popinId);
      this.instanciedPopinsOptions.push(elements);

      popin.addEventListener('click',event => {
        event.preventDefault();
        event.stopPropagation();
        var el  = event.target;
        this.open(event,el ,this.instanciedPopinsOptions[ el.getAttribute('data-popin-id')]);
      } ,false);

    });


  }


  click(){

  }

  /** METHODE */
  open(e, currentPopin, options) {
    //if the popin is disable break;
    if(currentPopin.getAttribute('data-disable')) {
      return false;
    }
    //if there is a opened popin close it temporary
    if(this.openedPopins.length > 0){
      document.getElementById(this.instanciedPopins[this.openedPopins.length-1]).classList.add('popin--closeJs');
    }
    //execute callback before openning popin
    if(options.beforeOpen && typeof options.beforeOpen == "function") {
      options.beforeOpen();
    }

    //popin Div
    var popinDiv = document.getElementById(options.popinId);

    //show overlay when options.overlay true => default : true
    if(options.overlayVisible && this.openedPopins.length == 0){
      this.overlay.classList.add('popin-overlay--visible');
    }

    //add popin to table memory of opened popin
    this.openedPopins.push(currentPopin.getAttribute('data-popin-id'));

    //show the popin
    var windowHeight = document.documentElement.clientHeight,
        popinHeight = popinDiv.clientHeight,
        popinOffset = this.getOffset(currentPopin),
        popinTop = (options.buttonSticky) ? popinOffset.top + 'px' : document.body.scrollTop + 20 + 'px';

    if(options.buttonSticky || popinHeight > windowHeight) {
      //Popin is bigenouth screen height
      popinDiv.style.top = popinTop;
      popinDiv.classList.add('popin--openJs');
    } else {
      //popin fit in screen
      popinDiv.classList.add('popin--open');
    }

    //bind closing event
    if(options.closeButton){
      var closeBtn = popinDiv.querySelectorAll('.js-popin-linkClose');
      [].forEach.call(closeBtn, (button, i) => {
        button.addEventListener('click', (event) => {
          event.preventDefault();
          event.stopPropagation();
          //open the popin
          this.close(options);
        });
      });
    }

    //execute callback after openning popin
    if(options.afterOpen && typeof options.afterOpen == "function") {
      options.afterOpen();
    }
  }

  getOffset(el) {
    var rect = el.getBoundingClientRect();

    return {
      top: rect.top + document.body.scrollTop,
          left: rect.left + document.body.scrollLeft
    };

  }

  close(options) {
    if(!options) {
      var options = {}
    }
    //execute callback before closing popin
    if(options.beforeClose && typeof options.beforeClose == "function") {
      options.beforeClose();
    }

    //close the current popin
    var currentPopin = this.openedPopins[this.openedPopins.length-1];
    var popinDiv = document.getElementById(this.instanciedPopins[currentPopin]);
    popinDiv.classList.remove('popin--open','popin--openJs');
    popinDiv.style.top = '';

    this.openedPopins.splice(this.openedPopins.length-1,1);


    //open last opened popin
    if(this.openedPopins.length > 0){
      document.getElementById(this.instanciedPopins[this.openedPopins.length-1]).classList.remove('popin--closeJs');
    }

    //hide overlay
    if(this.openedPopins.length == 0) {
      this.overlay.classList.remove('popin-overlay--visible');
    }

    //execute callback after closing popin
    if(options.afterClose && typeof options.afterClose == "function") {
      options.afterClose();
    }

    //disable the popin
    this.disable(currentPopin);
  }

  disable(currentPopin) {
    var popinOptions = this.instanciedPopinsOptions[currentPopin];
    var link = document.querySelector('[data-popin-id="'+currentPopin+'"]');
    if(popinOptions.disableAfterClose){
      link.setAttribute('data-disable', true)
    }
  }
};


export default Popin;