"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _utils = require("./utils");
var _imageLayout = _interopRequireDefault(require("./imageLayout"));
const TIMEOUT = 250;
const imageEffectMap = {
  parallax: 'ImageParallax',
  fixed: 'ImageReveal'
};
function wowImageFactory(services, environmentConsts, contextWindow) {
  return class WowImage extends contextWindow.HTMLElement {
    constructor() {
      // eslint-disable-line no-useless-constructor
      super();
      (0, _defineProperty2.default)(this, "childListObserver", void 0);
      (0, _defineProperty2.default)(this, "timeoutId", void 0);
      this.childListObserver = null;
      this.timeoutId = null;
    }
    attributeChangedCallback(_, oldValue) {
      if (oldValue) {
        this.reLayout();
      }
    }
    connectedCallback() {
      if (environmentConsts.disableImagesLazyLoading) {
        this.reLayout();
      } else {
        this.observeIntersect();
      }
    }
    disconnectedCallback() {
      this.unobserveResize();
      this.unobserveIntersect();
      this.unobserveChildren();
    }
    static get observedAttributes() {
      return ['data-image-info'];
    }
    reLayout() {
      const domNodes = {};
      const measures = {};
      const imageId = this.getAttribute('id');
      const imageInfo = JSON.parse(this.dataset.imageInfo || '');
      const isResponsive = this.dataset.isResponsive === 'true';
      const {
        bgEffectName
      } = this.dataset;
      const {
        scrollEffect
      } = imageInfo.imageData;
      const {
        sourceSets
      } = imageInfo;
      const bgEffect = bgEffectName || scrollEffect && imageEffectMap[scrollEffect];
      if (sourceSets && sourceSets.length) {
        sourceSets.forEach(sourceSet => {
          if (sourceSet.scrollEffect) {
            sourceSet.scrollEffect = imageEffectMap[sourceSet.scrollEffect];
          }
        });
      }
      domNodes[imageId] = this;
      if (imageInfo.containerId) {
        domNodes[imageInfo.containerId] = contextWindow.document.getElementById(`${imageInfo.containerId}`);
      }
      const containerElm = imageInfo.containerId ? domNodes[imageInfo.containerId] : undefined;
      domNodes.image = this.querySelector('img');
      domNodes.picture = this.querySelector('picture');
      if (!domNodes.image) {
        // missing children, can't layout, wait for children to be created first
        const target = this;
        this.observeChildren(target);
        return;
      }

      // clean up
      this.unobserveChildren();

      // from now on just observe changes to children of top level
      this.observeChildren(this);
      services.mutationService.measure(() => {
        _imageLayout.default.measure(imageId, measures, domNodes, {
          containerElm,
          bgEffect,
          sourceSets
        }, services);
      });
      const patchImage = (shouldLoadImage, loadImageImmediately) => {
        services.mutationService.mutate(() => {
          _imageLayout.default.patch(imageId, measures, domNodes, imageInfo, services, environmentConsts, shouldLoadImage, isResponsive, bgEffect, loadImageImmediately);
        });
      };
      const imageElement = domNodes.image;
      const ssrSrcNeedProcessing = this.dataset.hasSsrSrc && !imageElement.dataset.ssrSrcDone;
      // if image has no src or current src if from ssr render stage  -
      // load the image immediately, otherwise - debounce the reload
      const loadImageImmediately = !(0, _utils.getImageSrc)(imageElement) || ssrSrcNeedProcessing;
      if (loadImageImmediately) {
        patchImage(true, true);
      } else {
        this.debounceImageLoad(patchImage);
      }
    }

    /**
     * Debounce consecutive image loads
     *
     * @param {function} patchImage closure for patching the image
     */
    debounceImageLoad(patchImage) {
      clearTimeout(this.timeoutId);
      this.timeoutId = contextWindow.setTimeout(() => {
        patchImage(true);
      }, TIMEOUT);
      patchImage(false);
    }
    observeResize() {
      var _services$resizeServi;
      (_services$resizeServi = services.resizeService) == null || _services$resizeServi.observe(this);
    }
    unobserveResize() {
      var _services$resizeServi2;
      (_services$resizeServi2 = services.resizeService) == null || _services$resizeServi2.unobserve(this);
    }
    observeIntersect() {
      var _services$intersectio;
      (_services$intersectio = services.intersectionService) == null || _services$intersectio.observe(this);
    }
    unobserveIntersect() {
      var _services$intersectio2;
      (_services$intersectio2 = services.intersectionService) == null || _services$intersectio2.unobserve(this);
    }

    /**
     * Observe DOM mutations to wait for addition of missing children
     *
     * @param {HTMLElement} parent
     */
    observeChildren(parent) {
      if (!this.childListObserver) {
        this.childListObserver = new contextWindow.MutationObserver(() => {
          this.reLayout();
        });
      }
      this.childListObserver.observe(parent, {
        childList: true
      });
    }

    /**
     * Remove DOM MutationObserver if one was created
     */
    unobserveChildren() {
      if (this.childListObserver) {
        this.childListObserver.disconnect();
        this.childListObserver = null;
      }
    }
  };
}
var _default = exports.default = wowImageFactory;
//# sourceMappingURL=WowImage.js.map