All files / js/lib perfundo.js

69.23% Statements 45/65
36.59% Branches 15/41
63.64% Functions 7/11
75.44% Lines 43/57
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105  16x 16x       16x 8x     12x 12x 12x 12x 12x   12x   12x                               12x 12x           12x 12x             12x     2x 1x 1x       2x 1x       2x 2x 2x 2x 1x   1x 1x 1x     1x       2x 2x 2x 2x 1x   1x 1x 1x     1x       2x 3x   3x 3x              
export default function Perfundo(dependencies, target, userOptions = {}) {
  const { configure, context, defaultOptions, swipe } = dependencies;
  const elements = typeof target === `string`
    ? context.querySelectorAll(target)
    : target;
 
  if (elements.length > 1) {
    return [].slice.call(elements).map(element => new Perfundo(dependencies, element, userOptions));
  }
 
  this.context = context;
  this.element = elements[0] || elements;
  this.options = configure(this.element, userOptions, defaultOptions);
  this.hasPrev = this.element.querySelector(`.${this.options.classNames.prev}`) !== null;
  this.hasNext = this.element.querySelector(`.${this.options.classNames.next}`) !== null;
 
  this.element.setAttribute(this.options.rootAttribute, true);
 
  Iif (this.options.disableHistory) {
    this.element.addEventListener(`click`, (e) => {
      e.preventDefault();
 
      const close = e.target.classList.contains(this.options.classNames.close)
        || e.target.classList.contains(this.options.classNames.overlay);
      const open = e.target.classList.contains(this.options.classNames.link)
        || e.target.parentElement.classList.contains(this.options.classNames.link);
 
      if (close) this.close();
      else if (open) this.open();
      else if (e.target.classList.contains(this.options.classNames.prev)) this.prev();
      else if (e.target.classList.contains(this.options.classNames.next)) this.next();
    });
  }
 
  Eif (this.options.keyboard) {
    this.element.addEventListener(`keyup`, (e) => {
      if (this.hasPrev && e.keyCode === 37) this.prev();
      else if (this.hasNext && e.keyCode === 39) this.next();
    });
  }
 
  Eif (this.options.swipe) {
    swipe(this.element, {
      wipeLeft: () => this.next(),
      wipeRight: () => this.prev(),
      preventDefaultEvents: this.options.disableHistory,
    });
  }
 
  return this;
}
 
Perfundo.prototype.open = function open() {
  this.element.querySelector(`.${this.options.classNames.link}`).focus();
  this.element.querySelector(`.${this.options.classNames.overlay}`)
    .classList.add(this.options.classNames.active);
};
 
Perfundo.prototype.close = function close() {
  this.element.querySelector(`.${this.options.classNames.overlay}`)
    .classList.remove(this.options.classNames.active);
};
 
Perfundo.prototype.prev = function prev() {
  try {
    const prevLink = this.element.querySelector(`.${this.options.classNames.prev}`);
    const prevItem = this.context.querySelector(`${prevLink.getAttribute(`href`)}`);
    const prevRoot = this.getRootElement(prevItem);
 
    Eif (prevRoot) {
      this.close();
      prevRoot.querySelector(`.${this.options.classNames.link}`).click();
    }
  } catch (e) {
    throw new Error(`Previous item not found.`);
  }
};
 
Perfundo.prototype.next = function next() {
  try {
    const nextLink = this.element.querySelector(`.${this.options.classNames.next}`);
    const nextItem = this.context.querySelector(`${nextLink.getAttribute(`href`)}`);
    const nextRoot = this.getRootElement(nextItem);
 
    Eif (nextRoot) {
      this.close();
      nextRoot.querySelector(`.${this.options.classNames.link}`).click();
    }
  } catch (e) {
    throw new Error(`Next item not found.`);
  }
};
 
Perfundo.prototype.getRootElement = function getRootElement(element) {
  let parent = element.parentElement;
 
  while (parent && parent !== this.context) {
    Eif (parent.hasAttribute(this.options.rootAttribute)) return parent;
 
    parent = parent.parentElement;
  }
 
  return null;
};