/*! bxs-vue-ui v3.3.0 */
'use strict';

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

var entryVirtual = require('./entry-virtual.js');
var normalizeComponent = require('./normalize-component.js');
require('./es.number.constructor.js');
var filter = require('./filter.js');
var _extends = require('./extends.js');
var some = require('./some.js');
var Vue = _interopDefault(require('vue'));
var safeAreaPatch = require('../safe-area-patch/index.js');

var context = {
  zIndex: 700,
  stack: [],

  get top() {
    return this.stack[this.stack.length - 1];
  }

};

//
//
//
//
//
//
//
//
//
//
//
//
//
var script = {
  name: 'overlay',
  props: {
    visible: Boolean,
    zIndex: {
      type: Number,
      default: 700
    }
  },
  computed: {
    style: function style() {
      return {
        zIndex: this.zIndex
      };
    }
  }
};

/* script */
var __vue_script__ = script;
/* template */

var __vue_render__ = function __vue_render__() {
  var _vm = this;

  var _h = _vm.$createElement;

  var _c = _vm._self._c || _h;

  return _c('transition', {
    attrs: {
      "enter-active-class": "bx-animate-fade-in",
      "leave-active-class": "bx-animate-fade-out"
    }
  }, [_c('div', {
    directives: [{
      name: "show",
      rawName: "v-show",
      value: _vm.visible,
      expression: "visible"
    }],
    staticClass: "bx-overlay",
    style: _vm.style,
    on: {
      "click": function click($event) {
        _vm.$emit('click', $event);
      }
    }
  })]);
};

var __vue_staticRenderFns__ = [];
/* style */

var __vue_inject_styles__ = undefined;
/* scoped */

var __vue_scope_id__ = undefined;
/* module identifier */

var __vue_module_identifier__ = undefined;
/* functional template */

var __vue_is_functional_template__ = false;
/* style inject */

/* style inject SSR */

var Overlay = normalizeComponent.__vue_normalize__({
  render: __vue_render__,
  staticRenderFns: __vue_staticRenderFns__
}, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, undefined, undefined);

// `Object.defineProperty` method
// https://tc39.github.io/ecma262/#sec-object.defineproperty
entryVirtual.$({ target: 'Object', stat: true, forced: !entryVirtual.DESCRIPTORS, sham: !entryVirtual.DESCRIPTORS }, {
  defineProperty: entryVirtual.objectDefinePropertyModile.f
});

var defineProperty_1 = entryVirtual.createCommonjsModule(function (module) {
var Object = entryVirtual.path.Object;

var defineProperty = module.exports = function defineProperty(it, key, desc) {
  return Object.defineProperty(it, key, desc);
};

if (Object.defineProperty.sham) defineProperty.sham = true;
});

var defineProperty = defineProperty_1;

var defineProperty$1 = defineProperty;

var passiveSupported = false;

try {
  var options = defineProperty$1({}, 'passive', {
    get: function get() {
      passiveSupported = true;
      return passiveSupported;
    }
  });

  window.addEventListener('test', null, options);
} catch (err) {
  passiveSupported = false;
} // 添加事件


function addEvent(target, event, handler, passive) {
  if (passive === void 0) {
    passive = false;
  }

  target.addEventListener(event, handler, passiveSupported ? {
    capture: false,
    passive: passive
  } : false);
} // 移除事件

function removeEvent(target, event, handler) {
  target.removeEventListener(event, handler);
}

var manager = {
  open: function open(vm, config) {
    var _context;

    if (!some._someInstanceProperty(_context = context.stack).call(_context, function (item) {
      return item.vm === vm;
    })) {
      var el = vm.$el;
      var target = el && el.parentNode ? el.parentNode : document.body;
      context.stack.push({
        vm: vm,
        config: config,
        target: target
      });
      this.update();
    }
  },
  close: function close(vm) {
    var stack = context.stack;

    if (stack.length) {
      if (context.top.vm === vm) {
        stack.pop();
        context.zIndex -= 2;
        this.update();
      } else {
        context.stack = filter._filterInstanceProperty(stack).call(stack, function (item) {
          return item.vm !== vm;
        });
      }
    }
  },
  update: function update() {
    var overlay = context.overlay;

    if (!overlay) {
      overlay = new (Vue.extend(Overlay))({
        el: document.createElement('div')
      });
      overlay.$on('click', this.onClick);
      addEvent(overlay.$el, 'touchmove', this.onTouchMove);
      addEvent(overlay.$el, 'webkitAnimationEnd', this.onAnimationEnd);
      addEvent(overlay.$el, 'animationend', this.onAnimationEnd);
      context.overlay = overlay;
    }

    if (overlay.$el.parentNode) {
      overlay.visible = false;
    }

    if (context.top) {
      var _context$top = context.top,
          config = _context$top.config,
          target = _context$top.target;
      target.appendChild(overlay.$el);

      _extends._extends(overlay, config, {
        visible: true
      });
    }
  },
  onClick: function onClick() {
    if (context.top) {
      var vm = context.top.vm;

      if (vm.closeOnClickOverlay) {
        vm.$emit('input', false);
        vm.$emit('overlayClose');
      }
    }
  },
  onTouchMove: function onTouchMove(e) {
    e.preventDefault();
    e.stopPropagation();
  },
  onAnimationEnd: function onAnimationEnd() {
    if (context.top) {
      var vm = context.top.vm;
      context.activeVm = vm;
      vm.openAfter();
    } else if (context.activeVm) {
      context.activeVm.closeAfter();
      context.activeVm = null;
    }
  }
};

var MODAL_OPEN_CLASS = 'bx-overlay-open';
var Popup = {
  props: {
    // 和emit('input')配合
    value: Boolean,
    // 遮罩背景是否显示
    overlay: {
      type: Boolean,
      default: true
    },
    // 点击遮罩是否关闭
    closeOnClickOverlay: {
      type: Boolean,
      default: true
    },
    // 禁止document滚动
    lockScroll: {
      type: Boolean,
      default: false
    },
    // 防止滚动穿透，页面会有轻微闪动
    preventScrollThrough: {
      type: Boolean,
      default: false
    },
    // 是否兼容iphoneX，解决在app内不满一屏情况下的bug，废弃，改为补丁的方式
    supportIphoneX: {
      type: Boolean,
      default: false
    }
  },
  data: function data() {
    return {
      // 记住打开overlay时 body 的位置
      scrollTop: 0,
      // Vue挂载的节点
      appNode: null
    };
  },
  watch: {
    value: {
      immediate: true,
      handler: function handler(val) {
        this[val ? 'open' : 'close']();
      }
    },
    overlay: function overlay() {
      this.renderOverlay();
    }
  },
  beforeDestroy: function beforeDestroy() {
    this.close();
  },
  deactivated: function deactivated() {
    this.close();
  },
  methods: {
    open: function open() {
      if (this.opened) {
        return false;
      }

      this.openBefore();
      this.renderOverlay();
      this.opened = true;
      return this.opened;
    },
    openBefore: function openBefore() {
      // 禁止滚动，在弹出层无需滚动时使用
      if (this.lockScroll) {
        addEvent(document, 'touchmove', this.onTouchMove);
      }
    },
    openAfter: function openAfter() {
      // 防止滚动穿透
      if (this.preventScrollThrough) {
        this.scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;

        if (!this.appNode) {
          this.appNode = this.findRootElement(this.$el);
        }

        this.appNode.classList.add(MODAL_OPEN_CLASS);
        this.appNode.style.top = -1 * this.scrollTop + "px"; // 增加了「MODAL_OPEN_CLASS」导致Body高度变化，因此需要更新安全区域补丁

        safeAreaPatch.default.update();
      }
    },
    close: function close() {
      if (!this.opened) {
        return false;
      }

      this.closeBefore();
      manager.close(this);
      this.opened = false;
      return this.opened;
    },
    closeBefore: function closeBefore() {
      if (this.lockScroll) {
        removeEvent(document, 'touchmove', this.onTouchMove);
      }

      if (this.preventScrollThrough && this.appNode) {
        this.appNode.classList.remove(MODAL_OPEN_CLASS);
        this.appNode.style.top = '0';
        window.scrollTo(0, this.scrollTop);
      }
    },
    // 透明遮罩动画结束后，调用
    closeAfter: function closeAfter() {
      if (this.preventScrollThrough) {
        // 移除了「MODAL_OPEN_CLASS」导致Body高度变化，因此需要更新安全区域补丁
        safeAreaPatch.default.update();
      }
    },
    renderOverlay: function renderOverlay() {
      var _this = this;

      if (this.overlay) {
        context.zIndex += 1;
        manager.open(this, {
          zIndex: context.zIndex
        });
      } else {
        manager.close(this);
      }

      this.$nextTick(function () {
        context.zIndex += 1;
        _this.$el.style.zIndex = context.zIndex;
      });
    },
    onTouchMove: function onTouchMove(e) {
      e.preventDefault();
      e.stopPropagation();
    },
    // 查找Vue挂载的节点
    findRootElement: function findRootElement($el) {
      var $rootNode = $el;

      while ($rootNode.parentNode && $rootNode.parentNode.tagName !== 'BODY') {
        $rootNode = $rootNode.parentNode;
      }

      if ($rootNode.parentNode && $el === $rootNode) {
        $rootNode = $rootNode.parentNode;
      }

      return $rootNode;
    }
  }
};

exports.Popup = Popup;
