mirror of https://github.com/twbs/bootstrap.git
				
				
				
			
		
			
				
	
	
		
			432 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			432 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
 | 
						|
 | 
						|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
 | 
						|
 | 
						|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 | 
						|
 | 
						|
/**
 | 
						|
 * --------------------------------------------------------------------------
 | 
						|
 * Bootstrap (v4.0.0-alpha.6): dropdown.js
 | 
						|
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 | 
						|
 * --------------------------------------------------------------------------
 | 
						|
 */
 | 
						|
 | 
						|
var Dropdown = function ($) {
 | 
						|
 | 
						|
  /**
 | 
						|
   * Check for Popper dependency
 | 
						|
   * Popper - https://popper.js.org
 | 
						|
   */
 | 
						|
  if (typeof Popper === 'undefined') {
 | 
						|
    throw new Error('Bootstrap dropdown require Popper.js (https://popper.js.org)');
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * ------------------------------------------------------------------------
 | 
						|
   * Constants
 | 
						|
   * ------------------------------------------------------------------------
 | 
						|
   */
 | 
						|
 | 
						|
  var NAME = 'dropdown';
 | 
						|
  var VERSION = '4.0.0-alpha.6';
 | 
						|
  var DATA_KEY = 'bs.dropdown';
 | 
						|
  var EVENT_KEY = '.' + DATA_KEY;
 | 
						|
  var DATA_API_KEY = '.data-api';
 | 
						|
  var JQUERY_NO_CONFLICT = $.fn[NAME];
 | 
						|
  var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
 | 
						|
  var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
 | 
						|
  var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
 | 
						|
  var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
 | 
						|
  var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
 | 
						|
  var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)
 | 
						|
  var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + '|' + ARROW_DOWN_KEYCODE + '|' + ESCAPE_KEYCODE);
 | 
						|
 | 
						|
  var Event = {
 | 
						|
    HIDE: 'hide' + EVENT_KEY,
 | 
						|
    HIDDEN: 'hidden' + EVENT_KEY,
 | 
						|
    SHOW: 'show' + EVENT_KEY,
 | 
						|
    SHOWN: 'shown' + EVENT_KEY,
 | 
						|
    CLICK: 'click' + EVENT_KEY,
 | 
						|
    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY,
 | 
						|
    KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + DATA_API_KEY,
 | 
						|
    KEYUP_DATA_API: 'keyup' + EVENT_KEY + DATA_API_KEY
 | 
						|
  };
 | 
						|
 | 
						|
  var ClassName = {
 | 
						|
    DISABLED: 'disabled',
 | 
						|
    SHOW: 'show',
 | 
						|
    DROPUP: 'dropup',
 | 
						|
    MENURIGHT: 'dropdown-menu-right',
 | 
						|
    MENULEFT: 'dropdown-menu-left'
 | 
						|
  };
 | 
						|
 | 
						|
  var Selector = {
 | 
						|
    DATA_TOGGLE: '[data-toggle="dropdown"]',
 | 
						|
    FORM_CHILD: '.dropdown form',
 | 
						|
    MENU: '.dropdown-menu',
 | 
						|
    NAVBAR_NAV: '.navbar-nav',
 | 
						|
    VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled)'
 | 
						|
  };
 | 
						|
 | 
						|
  var AttachmentMap = {
 | 
						|
    TOP: 'top-start',
 | 
						|
    TOPEND: 'top-end',
 | 
						|
    BOTTOM: 'bottom-start',
 | 
						|
    BOTTOMEND: 'bottom-end'
 | 
						|
  };
 | 
						|
 | 
						|
  var Default = {
 | 
						|
    placement: AttachmentMap.BOTTOM,
 | 
						|
    offset: 0,
 | 
						|
    flip: true
 | 
						|
  };
 | 
						|
 | 
						|
  var DefaultType = {
 | 
						|
    placement: 'string',
 | 
						|
    offset: '(number|string)',
 | 
						|
    flip: 'boolean'
 | 
						|
  };
 | 
						|
 | 
						|
  /**
 | 
						|
   * ------------------------------------------------------------------------
 | 
						|
   * Class Definition
 | 
						|
   * ------------------------------------------------------------------------
 | 
						|
   */
 | 
						|
 | 
						|
  var Dropdown = function () {
 | 
						|
    function Dropdown(element, config) {
 | 
						|
      _classCallCheck(this, Dropdown);
 | 
						|
 | 
						|
      this._element = element;
 | 
						|
      this._popper = null;
 | 
						|
      this._config = this._getConfig(config);
 | 
						|
      this._menu = this._getMenuElement();
 | 
						|
      this._inNavbar = this._detectNavbar();
 | 
						|
 | 
						|
      this._addEventListeners();
 | 
						|
    }
 | 
						|
 | 
						|
    // getters
 | 
						|
 | 
						|
    // public
 | 
						|
 | 
						|
    Dropdown.prototype.toggle = function toggle() {
 | 
						|
      if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      var parent = Dropdown._getParentFromElement(this._element);
 | 
						|
      var isActive = $(this._menu).hasClass(ClassName.SHOW);
 | 
						|
 | 
						|
      Dropdown._clearMenus();
 | 
						|
 | 
						|
      if (isActive) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      var relatedTarget = {
 | 
						|
        relatedTarget: this._element
 | 
						|
      };
 | 
						|
      var showEvent = $.Event(Event.SHOW, relatedTarget);
 | 
						|
 | 
						|
      $(parent).trigger(showEvent);
 | 
						|
 | 
						|
      if (showEvent.isDefaultPrevented()) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      var element = this._element;
 | 
						|
      // for dropup with alignment we use the parent as popper container
 | 
						|
      if ($(parent).hasClass(ClassName.DROPUP)) {
 | 
						|
        if ($(this._menu).hasClass(ClassName.MENULEFT) || $(this._menu).hasClass(ClassName.MENURIGHT)) {
 | 
						|
          element = parent;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      this._popper = new Popper(element, this._menu, this._getPopperConfig());
 | 
						|
 | 
						|
      // if this is a touch-enabled device we add extra
 | 
						|
      // empty mouseover listeners to the body's immediate children;
 | 
						|
      // only needed because of broken event delegation on iOS
 | 
						|
      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
 | 
						|
      if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) {
 | 
						|
        $('body').children().on('mouseover', null, $.noop);
 | 
						|
      }
 | 
						|
 | 
						|
      this._element.focus();
 | 
						|
      this._element.setAttribute('aria-expanded', true);
 | 
						|
 | 
						|
      $(this._menu).toggleClass(ClassName.SHOW);
 | 
						|
      $(parent).toggleClass(ClassName.SHOW).trigger($.Event(Event.SHOWN, relatedTarget));
 | 
						|
    };
 | 
						|
 | 
						|
    Dropdown.prototype.dispose = function dispose() {
 | 
						|
      $.removeData(this._element, DATA_KEY);
 | 
						|
      $(this._element).off(EVENT_KEY);
 | 
						|
      this._element = null;
 | 
						|
      this._menu = null;
 | 
						|
      if (this._popper !== null) {
 | 
						|
        this._popper.destroy();
 | 
						|
      }
 | 
						|
      this._popper = null;
 | 
						|
    };
 | 
						|
 | 
						|
    Dropdown.prototype.update = function update() {
 | 
						|
      this._inNavbar = this._detectNavbar();
 | 
						|
      if (this._popper !== null) {
 | 
						|
        this._popper.scheduleUpdate();
 | 
						|
      }
 | 
						|
    };
 | 
						|
 | 
						|
    // private
 | 
						|
 | 
						|
    Dropdown.prototype._addEventListeners = function _addEventListeners() {
 | 
						|
      var _this = this;
 | 
						|
 | 
						|
      $(this._element).on(Event.CLICK, function (event) {
 | 
						|
        event.preventDefault();
 | 
						|
        event.stopPropagation();
 | 
						|
        _this.toggle();
 | 
						|
      });
 | 
						|
    };
 | 
						|
 | 
						|
    Dropdown.prototype._getConfig = function _getConfig(config) {
 | 
						|
      var elementData = $(this._element).data();
 | 
						|
      if (elementData.placement !== undefined) {
 | 
						|
        elementData.placement = AttachmentMap[elementData.placement.toUpperCase()];
 | 
						|
      }
 | 
						|
 | 
						|
      config = $.extend({}, this.constructor.Default, $(this._element).data(), config);
 | 
						|
 | 
						|
      Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
 | 
						|
 | 
						|
      return config;
 | 
						|
    };
 | 
						|
 | 
						|
    Dropdown.prototype._getMenuElement = function _getMenuElement() {
 | 
						|
      if (!this._menu) {
 | 
						|
        var parent = Dropdown._getParentFromElement(this._element);
 | 
						|
        this._menu = $(parent).find(Selector.MENU)[0];
 | 
						|
      }
 | 
						|
      return this._menu;
 | 
						|
    };
 | 
						|
 | 
						|
    Dropdown.prototype._getPlacement = function _getPlacement() {
 | 
						|
      var $parentDropdown = $(this._element).parent();
 | 
						|
      var placement = this._config.placement;
 | 
						|
 | 
						|
      // Handle dropup
 | 
						|
      if ($parentDropdown.hasClass(ClassName.DROPUP) || this._config.placement === AttachmentMap.TOP) {
 | 
						|
        placement = AttachmentMap.TOP;
 | 
						|
        if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
 | 
						|
          placement = AttachmentMap.TOPEND;
 | 
						|
        }
 | 
						|
      } else if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
 | 
						|
        placement = AttachmentMap.BOTTOMEND;
 | 
						|
      }
 | 
						|
      return placement;
 | 
						|
    };
 | 
						|
 | 
						|
    Dropdown.prototype._detectNavbar = function _detectNavbar() {
 | 
						|
      return $(this._element).closest('.navbar').length > 0;
 | 
						|
    };
 | 
						|
 | 
						|
    Dropdown.prototype._getPopperConfig = function _getPopperConfig() {
 | 
						|
      var popperConfig = {
 | 
						|
        placement: this._getPlacement(),
 | 
						|
        modifiers: {
 | 
						|
          offset: {
 | 
						|
            offset: this._config.offset
 | 
						|
          },
 | 
						|
          flip: {
 | 
						|
            enabled: this._config.flip
 | 
						|
          }
 | 
						|
        }
 | 
						|
      };
 | 
						|
 | 
						|
      // Disable Popper.js for Dropdown in Navbar
 | 
						|
      if (this._inNavbar) {
 | 
						|
        popperConfig.modifiers.applyStyle = {
 | 
						|
          enabled: !this._inNavbar
 | 
						|
        };
 | 
						|
      }
 | 
						|
      return popperConfig;
 | 
						|
    };
 | 
						|
 | 
						|
    // static
 | 
						|
 | 
						|
    Dropdown._jQueryInterface = function _jQueryInterface(config) {
 | 
						|
      return this.each(function () {
 | 
						|
        var data = $(this).data(DATA_KEY);
 | 
						|
        var _config = (typeof config === 'undefined' ? 'undefined' : _typeof(config)) === 'object' ? config : null;
 | 
						|
 | 
						|
        if (!data) {
 | 
						|
          data = new Dropdown(this, _config);
 | 
						|
          $(this).data(DATA_KEY, data);
 | 
						|
        }
 | 
						|
 | 
						|
        if (typeof config === 'string') {
 | 
						|
          if (data[config] === undefined) {
 | 
						|
            throw new Error('No method named "' + config + '"');
 | 
						|
          }
 | 
						|
          data[config]();
 | 
						|
        }
 | 
						|
      });
 | 
						|
    };
 | 
						|
 | 
						|
    Dropdown._clearMenus = function _clearMenus(event) {
 | 
						|
      if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      var toggles = $.makeArray($(Selector.DATA_TOGGLE));
 | 
						|
      for (var i = 0; i < toggles.length; i++) {
 | 
						|
        var parent = Dropdown._getParentFromElement(toggles[i]);
 | 
						|
        var context = $(toggles[i]).data(DATA_KEY);
 | 
						|
        var relatedTarget = {
 | 
						|
          relatedTarget: toggles[i]
 | 
						|
        };
 | 
						|
 | 
						|
        if (!context) {
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
 | 
						|
        var dropdownMenu = context._menu;
 | 
						|
        if (!$(parent).hasClass(ClassName.SHOW)) {
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
 | 
						|
        if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) {
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
 | 
						|
        var hideEvent = $.Event(Event.HIDE, relatedTarget);
 | 
						|
        $(parent).trigger(hideEvent);
 | 
						|
        if (hideEvent.isDefaultPrevented()) {
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
 | 
						|
        // if this is a touch-enabled device we remove the extra
 | 
						|
        // empty mouseover listeners we added for iOS support
 | 
						|
        if ('ontouchstart' in document.documentElement) {
 | 
						|
          $('body').children().off('mouseover', null, $.noop);
 | 
						|
        }
 | 
						|
 | 
						|
        toggles[i].setAttribute('aria-expanded', 'false');
 | 
						|
 | 
						|
        $(dropdownMenu).removeClass(ClassName.SHOW);
 | 
						|
        $(parent).removeClass(ClassName.SHOW).trigger($.Event(Event.HIDDEN, relatedTarget));
 | 
						|
      }
 | 
						|
    };
 | 
						|
 | 
						|
    Dropdown._getParentFromElement = function _getParentFromElement(element) {
 | 
						|
      var parent = void 0;
 | 
						|
      var selector = Util.getSelectorFromElement(element);
 | 
						|
 | 
						|
      if (selector) {
 | 
						|
        parent = $(selector)[0];
 | 
						|
      }
 | 
						|
 | 
						|
      return parent || element.parentNode;
 | 
						|
    };
 | 
						|
 | 
						|
    Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
 | 
						|
      if (!REGEXP_KEYDOWN.test(event.which) || /button/i.test(event.target.tagName) && event.which === SPACE_KEYCODE || /input|textarea/i.test(event.target.tagName)) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      event.preventDefault();
 | 
						|
      event.stopPropagation();
 | 
						|
 | 
						|
      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      var parent = Dropdown._getParentFromElement(this);
 | 
						|
      var isActive = $(parent).hasClass(ClassName.SHOW);
 | 
						|
 | 
						|
      if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {
 | 
						|
 | 
						|
        if (event.which === ESCAPE_KEYCODE) {
 | 
						|
          var toggle = $(parent).find(Selector.DATA_TOGGLE)[0];
 | 
						|
          $(toggle).trigger('focus');
 | 
						|
        }
 | 
						|
 | 
						|
        $(this).trigger('click');
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      var items = $(parent).find(Selector.VISIBLE_ITEMS).get();
 | 
						|
 | 
						|
      if (!items.length) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      var index = items.indexOf(event.target);
 | 
						|
 | 
						|
      if (event.which === ARROW_UP_KEYCODE && index > 0) {
 | 
						|
        // up
 | 
						|
        index--;
 | 
						|
      }
 | 
						|
 | 
						|
      if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
 | 
						|
        // down
 | 
						|
        index++;
 | 
						|
      }
 | 
						|
 | 
						|
      if (index < 0) {
 | 
						|
        index = 0;
 | 
						|
      }
 | 
						|
 | 
						|
      items[index].focus();
 | 
						|
    };
 | 
						|
 | 
						|
    _createClass(Dropdown, null, [{
 | 
						|
      key: 'VERSION',
 | 
						|
      get: function get() {
 | 
						|
        return VERSION;
 | 
						|
      }
 | 
						|
    }, {
 | 
						|
      key: 'Default',
 | 
						|
      get: function get() {
 | 
						|
        return Default;
 | 
						|
      }
 | 
						|
    }, {
 | 
						|
      key: 'DefaultType',
 | 
						|
      get: function get() {
 | 
						|
        return DefaultType;
 | 
						|
      }
 | 
						|
    }]);
 | 
						|
 | 
						|
    return Dropdown;
 | 
						|
  }();
 | 
						|
 | 
						|
  /**
 | 
						|
   * ------------------------------------------------------------------------
 | 
						|
   * Data Api implementation
 | 
						|
   * ------------------------------------------------------------------------
 | 
						|
   */
 | 
						|
 | 
						|
  $(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + ' ' + Event.KEYUP_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
 | 
						|
    event.preventDefault();
 | 
						|
    event.stopPropagation();
 | 
						|
    Dropdown._jQueryInterface.call($(this), 'toggle');
 | 
						|
  }).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) {
 | 
						|
    e.stopPropagation();
 | 
						|
  });
 | 
						|
 | 
						|
  /**
 | 
						|
   * ------------------------------------------------------------------------
 | 
						|
   * jQuery
 | 
						|
   * ------------------------------------------------------------------------
 | 
						|
   */
 | 
						|
 | 
						|
  $.fn[NAME] = Dropdown._jQueryInterface;
 | 
						|
  $.fn[NAME].Constructor = Dropdown;
 | 
						|
  $.fn[NAME].noConflict = function () {
 | 
						|
    $.fn[NAME] = JQUERY_NO_CONFLICT;
 | 
						|
    return Dropdown._jQueryInterface;
 | 
						|
  };
 | 
						|
 | 
						|
  return Dropdown;
 | 
						|
}(jQuery); /* global Popper */
 | 
						|
//# sourceMappingURL=dropdown.js.map
 |