<template>
  <div class="qf-dialog">
    <transition name="dialog-fade">
      <div>
        <component :is="currentView" @hide="hide" @show="show" ref="content"></component>
      </div>
    </transition>
  </div>
</template>

<script>
import PopupManager from '../util/PopupManager';
import KeydownMgr from '../util/KeydownMgr';

export default {

  data() {
    return {
      currentView: null,
      model: true,
      target: document.body,
      dialogId: 0,
      modalClass: null,
      modalFade: true,
      closeOnClickModal: false,
      escClose: true
    };
  },
  beforeMount() {
    this.dialogId = 'dialogId-' + PopupManager.nextId();
    this.modelIndex = PopupManager.nextZIndex();
    this.dialogIndex = PopupManager.nextZIndex();
    PopupManager.register(this.dialogId, this);
  },

  created() {
    KeydownMgr.bind(this, this.onKeydown);
  },
  destroyed() {
    if (this.activeElement) {
      this.activeElement.focus();
      this.activeElement = null;
    }
  },

  methods: {
    getTarget() {
      if (!this.target) {
        return document.body;
      }
      return this.target;
    },

    getDom(dom) {
      if (dom.nodeType === 3) {
        dom = dom.nextElementSibling || dom.nextSibling;
        this.getDom(dom);
      }
      return dom;
    },

    show() {
      if (this.model) {
        PopupManager.openModal(this.dialogId, this.modelIndex, this.getTarget(), this.modalClass, this.modalFade);
      }
      const dom = this.getDom(this.$el);
      dom.style.zIndex = this.dialogIndex;

      // document.activeElement.blur() // 失去焦点
      this.activeElement = document.activeElement;
      this.activeElement.blur();
      this.getTarget().appendChild(this.$el);
    },

    canShow() {
      if (this.$refs.content && this.$refs.content.canShow) {
        return this.$refs.content.canShow();
      } else {
        return true;
      }
    },

    hide() {
      this.$emit('hide');
      this.$destroy(true);
    },

    getAllFocusable() {
      let pattern = [
        'button:not([disabled]):not([style*="display: none"])',
        '[href]',
        'input:not([disabled]):not([readonly]):not([style*="display: none"])',
        'select:not([disabled]):not([style*="display: none"])',
        'textarea:not([disabled]):not([style*="display: none"])',
        '[tabindex]:not([tabindex="-1"]):not([style*="display: none"])'
      ];
      return Array.apply(null, this.$el.querySelectorAll(pattern.join(',')));
    },

    onKeydown(event) {
      if (this.escClose && event.keyCode === 27) {
        this.hide();
      } else if (event.keyCode === 9) {
        let components = this.getAllFocusable();
        if (components.length > 0 && components.indexOf(event.target) === components.length - 1) {
          components[0].focus();
          event.stopPropagation();
          event.preventDefault();
          event.returnValue = false;
          event.cancelBubble = true;
        }
      }
    }
  },

  beforeDestroy() {
    PopupManager.deregister(this.dialogId);
    PopupManager.closeModal(this.dialogId);
    if (this.$el.parentElement) {
      this.getTarget().removeChild(this.$el);
    }
    KeydownMgr.unbind(this, this.onKeydown);
  }
};
</script>
