]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
add dropdown
authorfat <fat@folders.local>
Sun, 10 May 2015 20:47:11 +0000 (13:47 -0700)
committerfat <fat@folders.local>
Sun, 10 May 2015 20:47:11 +0000 (13:47 -0700)
Gruntfile.js
js/dist/dropdown.js [new file with mode: 0644]
js/dist/dropdown.js.map [new file with mode: 0644]
js/src/dropdown.js [new file with mode: 0644]
js/tests/index.html
js/tests/visual/dropdown.html

index ffc660958956431481bdac1ba04ca7d6723dbcda..5c29acf039fbc68cafc8103d4eb16ab58ca4cdb3 100644 (file)
@@ -63,11 +63,12 @@ module.exports = function (grunt) {
       },
       dist: {
         files: {
-          'js/dist/util.js': 'js/src/util.js',
-          'js/dist/alert.js': 'js/src/alert.js',
-          'js/dist/button.js': 'js/src/button.js',
-          'js/dist/carousel.js': 'js/src/carousel.js',
-          'js/dist/collapse.js': 'js/src/collapse.js',
+          'js/dist/util.js'     : 'js/src/util.js',
+          'js/dist/alert.js'    : 'js/src/alert.js',
+          'js/dist/button.js'   : 'js/src/button.js',
+          'js/dist/carousel.js' : 'js/src/carousel.js',
+          'js/dist/collapse.js' : 'js/src/collapse.js',
+          'js/dist/dropdown.js' : 'js/src/dropdown.js'
         }
       }
     },
diff --git a/js/dist/dropdown.js b/js/dist/dropdown.js
new file mode 100644 (file)
index 0000000..a22e3ce
--- /dev/null
@@ -0,0 +1,254 @@
+'use strict';
+
+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): dropdown.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Dropdown = (function ($) {
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  var NAME = 'dropdown';
+  var VERSION = '4.0.0';
+  var DATA_KEY = 'bs.dropdown';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+
+  var Event = {
+    HIDE: 'hide.bs.dropdown',
+    HIDDEN: 'hidden.bs.dropdown',
+    SHOW: 'show.bs.dropdown',
+    SHOWN: 'shown.bs.dropdown',
+    CLICK: 'click.bs.dropdown',
+    KEYDOWN: 'keydown.bs.dropdown.data-api',
+    CLICK_DATA: 'click.bs.dropdown.data-api'
+  };
+
+  var ClassName = {
+    BACKDROP: 'dropdown-backdrop',
+    DISABLED: 'disabled',
+    OPEN: 'open'
+  };
+
+  var Selector = {
+    BACKDROP: '.dropdown-backdrop',
+    DATA_TOGGLE: '[data-toggle="dropdown"]',
+    FORM_CHILD: '.dropdown form',
+    ROLE_MENU: '[role="menu"]',
+    ROLE_LISTBOX: '[role="listbox"]',
+    NAVBAR_NAV: '.navbar-nav',
+    VISIBLE_ITEMS: '[role="menu"] li:not(.disabled) a, ' + '[role="listbox"] li:not(.disabled) a'
+  };
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  var Dropdown = (function () {
+    function Dropdown(element) {
+      _classCallCheck(this, Dropdown);
+
+      $(element).on(Event.CLICK, this.toggle);
+    }
+
+    _createClass(Dropdown, [{
+      key: 'toggle',
+
+      // public
+
+      value: function toggle() {
+        if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+          return;
+        }
+
+        var parent = Dropdown._getParentFromElement(this);
+        var isActive = $(parent).hasClass(ClassName.OPEN);
+
+        Dropdown._clearMenus();
+
+        if (isActive) {
+          return false;
+        }
+
+        if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) {
+
+          // if mobile we use a backdrop because click events don't delegate
+          var dropdown = document.createElement('div');
+          dropdown.className = ClassName.BACKDROP;
+          $(dropdown).insertBefore(this);
+          $(dropdown).on('click', Dropdown._clearMenus);
+        }
+
+        var relatedTarget = { 'relatedTarget': this };
+        var showEvent = $.Event(Event.SHOW, relatedTarget);
+
+        $(parent).trigger(showEvent);
+
+        if (showEvent.isDefaultPrevented()) {
+          return;
+        }
+
+        this.focus();
+        this.setAttribute('aria-expanded', 'true');
+
+        $(parent).toggleClass(ClassName.OPEN);
+        $(parent).trigger(Event.SHOWN, relatedTarget);
+
+        return false;
+      }
+    }], [{
+      key: '_jQueryInterface',
+
+      // static
+
+      value: function _jQueryInterface(config) {
+        return this.each(function () {
+          var data = $(this).data(DATA_KEY);
+
+          if (!data) {
+            $(this).data(DATA_KEY, data = new Dropdown(this));
+          }
+
+          if (typeof config === 'string') {
+            data[config].call(this);
+          }
+        });
+      }
+    }, {
+      key: '_clearMenus',
+      value: function _clearMenus(event) {
+        if (event && event.which === 3) {
+          return;
+        }
+
+        var backdrop = $(Selector.BACKDROP)[0];
+        if (backdrop) {
+          backdrop.parentNode.removeChild(backdrop);
+        }
+
+        var toggles = $.makeArray($(Selector.DATA_TOGGLE));
+
+        for (var i = 0; i < toggles.length; i++) {
+          var _parent = Dropdown._getParentFromElement(toggles[i]);
+          var relatedTarget = { 'relatedTarget': toggles[i] };
+
+          if (!$(_parent).hasClass(ClassName.OPEN)) {
+            continue;
+          }
+
+          if (event && event.type === 'click' && /input|textarea/i.test(event.target.tagName) && $.contains(_parent, event.target)) {
+            continue;
+          }
+
+          var hideEvent = $.Event(Event.HIDE, relatedTarget);
+          $(_parent).trigger(hideEvent);
+          if (hideEvent.isDefaultPrevented()) {
+            continue;
+          }
+
+          toggles[i].setAttribute('aria-expanded', 'false');
+
+          $(_parent).removeClass(ClassName.OPEN).trigger(Event.HIDDEN, relatedTarget);
+        }
+      }
+    }, {
+      key: '_getParentFromElement',
+      value: function _getParentFromElement(element) {
+        var parent = undefined;
+        var selector = Util.getSelectorFromElement(element);
+
+        if (selector) {
+          parent = $(selector)[0];
+        }
+
+        return parent || element.parentNode;
+      }
+    }, {
+      key: '_dataApiKeydownHandler',
+      value: function _dataApiKeydownHandler(event) {
+        if (!/(38|40|27|32)/.test(event.which) || /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.OPEN);
+
+        if (!isActive && event.which !== 27 || isActive && event.which === 27) {
+
+          if (event.which === 27) {
+            var toggle = $(parent).find(Selector.DATA_TOGGLE)[0];
+            $(toggle).trigger('focus');
+          }
+
+          $(this).trigger('click');
+          return;
+        }
+
+        var items = $.makeArray($(Selector.VISIBLE_ITEMS));
+
+        items = items.filter(function (item) {
+          return item.offsetWidth || item.offsetHeight;
+        });
+
+        if (!items.length) {
+          return;
+        }
+
+        var index = items.indexOf(event.target);
+
+        if (event.which === 38 && index > 0) index--; // up
+        if (event.which === 40 && index < items.length - 1) index++; // down
+        if (! ~index) index = 0;
+
+        items[index].focus();
+      }
+    }]);
+
+    return Dropdown;
+  })();
+
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+  $(document).on(Event.KEYDOWN, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN, Selector.ROLE_MENU, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN, Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA, Dropdown._clearMenus).on(Event.CLICK_DATA, Selector.DATA_TOGGLE, Dropdown.prototype.toggle).on(Event.CLICK_DATA, 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);
+//# sourceMappingURL=dropdown.js.map
\ No newline at end of file
diff --git a/js/dist/dropdown.js.map b/js/dist/dropdown.js.map
new file mode 100644 (file)
index 0000000..16e6332
--- /dev/null
@@ -0,0 +1 @@
+{"version":3,"sources":["js/src/dropdown.js"],"names":[],"mappings":"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","file":"js/src/dropdown.js","sourcesContent":["import Util from './util'\n\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.0.0): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst Dropdown = (($) => {\n\n\n  /**\n   * ------------------------------------------------------------------------\n   * Constants\n   * ------------------------------------------------------------------------\n   */\n\n  const NAME                = 'dropdown'\n  const VERSION             = '4.0.0'\n  const DATA_KEY            = 'bs.dropdown'\n  const JQUERY_NO_CONFLICT  = $.fn[NAME]\n\n  const Event = {\n    HIDE       : 'hide.bs.dropdown',\n    HIDDEN     : 'hidden.bs.dropdown',\n    SHOW       : 'show.bs.dropdown',\n    SHOWN      : 'shown.bs.dropdown',\n    CLICK      : 'click.bs.dropdown',\n    KEYDOWN    : 'keydown.bs.dropdown.data-api',\n    CLICK_DATA : 'click.bs.dropdown.data-api'\n  }\n\n  const ClassName = {\n    BACKDROP : 'dropdown-backdrop',\n    DISABLED : 'disabled',\n    OPEN     : 'open'\n  }\n\n  const Selector = {\n    BACKDROP      : '.dropdown-backdrop',\n    DATA_TOGGLE   : '[data-toggle=\"dropdown\"]',\n    FORM_CHILD    : '.dropdown form',\n    ROLE_MENU     : '[role=\"menu\"]',\n    ROLE_LISTBOX  : '[role=\"listbox\"]',\n    NAVBAR_NAV    : '.navbar-nav',\n    VISIBLE_ITEMS : '[role=\"menu\"] li:not(.disabled) a, '\n                  + '[role=\"listbox\"] li:not(.disabled) a'\n  }\n\n\n  /**\n   * ------------------------------------------------------------------------\n   * Class Definition\n   * ------------------------------------------------------------------------\n   */\n\n  class Dropdown {\n\n    constructor(element) {\n      $(element).on(Event.CLICK, this.toggle)\n    }\n\n    // public\n\n    toggle() {\n      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {\n        return\n      }\n\n      let parent   = Dropdown._getParentFromElement(this)\n      let isActive = $(parent).hasClass(ClassName.OPEN)\n\n      Dropdown._clearMenus()\n\n      if (isActive) {\n        return false\n      }\n\n      if ('ontouchstart' in document.documentElement &&\n         (!$(parent).closest(Selector.NAVBAR_NAV).length)) {\n\n        // if mobile we use a backdrop because click events don't delegate\n        let dropdown       = document.createElement('div')\n        dropdown.className = ClassName.BACKDROP\n        $(dropdown).insertBefore(this)\n        $(dropdown).on('click', Dropdown._clearMenus)\n      }\n\n      let relatedTarget = { 'relatedTarget': this }\n      let showEvent     = $.Event(Event.SHOW, relatedTarget)\n\n      $(parent).trigger(showEvent)\n\n      if (showEvent.isDefaultPrevented()) {\n        return\n      }\n\n      this.focus()\n      this.setAttribute('aria-expanded', 'true')\n\n      $(parent).toggleClass(ClassName.OPEN)\n      $(parent).trigger(Event.SHOWN, relatedTarget)\n\n      return false\n    }\n\n\n    // static\n\n    static _jQueryInterface(config) {\n      return this.each(function () {\n        let data  = $(this).data(DATA_KEY)\n\n        if (!data) {\n          $(this).data(DATA_KEY, (data = new Dropdown(this)))\n        }\n\n        if (typeof config === 'string') {\n          data[config].call(this)\n        }\n      })\n    }\n\n    static _clearMenus(event) {\n      if (event && event.which === 3) {\n        return\n      }\n\n      let backdrop = $(Selector.BACKDROP)[0]\n      if (backdrop) {\n        backdrop.parentNode.removeChild(backdrop)\n      }\n\n      let toggles = $.makeArray($(Selector.DATA_TOGGLE))\n\n      for (let i = 0; i < toggles.length; i++) {\n        let parent        = Dropdown._getParentFromElement(toggles[i])\n        let relatedTarget = { 'relatedTarget': toggles[i] }\n\n        if (!$(parent).hasClass(ClassName.OPEN)) {\n          continue\n        }\n\n        if (event && event.type === 'click' &&\n           (/input|textarea/i.test(event.target.tagName)) &&\n           ($.contains(parent, event.target))) {\n          continue\n        }\n\n        let hideEvent = $.Event(Event.HIDE, relatedTarget)\n        $(parent).trigger(hideEvent)\n        if (hideEvent.isDefaultPrevented()) {\n          continue\n        }\n\n        toggles[i].setAttribute('aria-expanded', 'false')\n\n        $(parent)\n          .removeClass(ClassName.OPEN)\n          .trigger(Event.HIDDEN, relatedTarget)\n      }\n    }\n\n    static _getParentFromElement(element) {\n      let parent\n      let selector = Util.getSelectorFromElement(element)\n\n      if (selector) {\n        parent = $(selector)[0]\n      }\n\n      return parent || element.parentNode\n    }\n\n    static _dataApiKeydownHandler(event) {\n      if (!/(38|40|27|32)/.test(event.which) ||\n         /input|textarea/i.test(event.target.tagName)) {\n        return\n      }\n\n      event.preventDefault()\n      event.stopPropagation()\n\n      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {\n        return\n      }\n\n      let parent   = Dropdown._getParentFromElement(this)\n      let isActive = $(parent).hasClass(ClassName.OPEN)\n\n      if ((!isActive && event.which !== 27) ||\n           (isActive && event.which === 27)) {\n\n        if (event.which === 27) {\n          let toggle = $(parent).find(Selector.DATA_TOGGLE)[0]\n          $(toggle).trigger('focus')\n        }\n\n        $(this).trigger('click')\n        return\n      }\n\n      let items = $.makeArray($(Selector.VISIBLE_ITEMS))\n\n      items = items.filter((item) => {\n        return item.offsetWidth || item.offsetHeight\n      })\n\n      if (!items.length) {\n        return\n      }\n\n      let index = items.indexOf(event.target)\n\n      if (event.which === 38 && index > 0)                index--  // up\n      if (event.which === 40 && index < items.length - 1) index++  // down\n      if (!~index)                                        index = 0\n\n      items[index].focus()\n    }\n\n  }\n\n\n  /**\n   * ------------------------------------------------------------------------\n   * Data Api implementation\n   * ------------------------------------------------------------------------\n   */\n\n$(document)\n  .on(Event.KEYDOWN, Selector.DATA_TOGGLE,  Dropdown._dataApiKeydownHandler)\n  .on(Event.KEYDOWN, Selector.ROLE_MENU,    Dropdown._dataApiKeydownHandler)\n  .on(Event.KEYDOWN, Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler)\n  .on(Event.CLICK_DATA, Dropdown._clearMenus)\n  .on(Event.CLICK_DATA, Selector.DATA_TOGGLE, Dropdown.prototype.toggle)\n  .on(Event.CLICK_DATA, Selector.FORM_CHILD,  function (e) {\n     e.stopPropagation()\n   })\n\n\n  /**\n   * ------------------------------------------------------------------------\n   * jQuery\n   * ------------------------------------------------------------------------\n   */\n\n  $.fn[NAME]             = Dropdown._jQueryInterface\n  $.fn[NAME].Constructor = Dropdown\n  $.fn[NAME].noConflict  = function () {\n    $.fn[NAME] = JQUERY_NO_CONFLICT\n    return Dropdown._jQueryInterface\n  }\n\n  return Dropdown\n\n})(jQuery)\n\nexport default Dropdown\n"]}
\ No newline at end of file
diff --git a/js/src/dropdown.js b/js/src/dropdown.js
new file mode 100644 (file)
index 0000000..c5e29d8
--- /dev/null
@@ -0,0 +1,261 @@
+import Util from './util'
+
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0): dropdown.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+const Dropdown = (($) => {
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+  const NAME                = 'dropdown'
+  const VERSION             = '4.0.0'
+  const DATA_KEY            = 'bs.dropdown'
+  const JQUERY_NO_CONFLICT  = $.fn[NAME]
+
+  const Event = {
+    HIDE       : 'hide.bs.dropdown',
+    HIDDEN     : 'hidden.bs.dropdown',
+    SHOW       : 'show.bs.dropdown',
+    SHOWN      : 'shown.bs.dropdown',
+    CLICK      : 'click.bs.dropdown',
+    KEYDOWN    : 'keydown.bs.dropdown.data-api',
+    CLICK_DATA : 'click.bs.dropdown.data-api'
+  }
+
+  const ClassName = {
+    BACKDROP : 'dropdown-backdrop',
+    DISABLED : 'disabled',
+    OPEN     : 'open'
+  }
+
+  const Selector = {
+    BACKDROP      : '.dropdown-backdrop',
+    DATA_TOGGLE   : '[data-toggle="dropdown"]',
+    FORM_CHILD    : '.dropdown form',
+    ROLE_MENU     : '[role="menu"]',
+    ROLE_LISTBOX  : '[role="listbox"]',
+    NAVBAR_NAV    : '.navbar-nav',
+    VISIBLE_ITEMS : '[role="menu"] li:not(.disabled) a, '
+                  + '[role="listbox"] li:not(.disabled) a'
+  }
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Class Definition
+   * ------------------------------------------------------------------------
+   */
+
+  class Dropdown {
+
+    constructor(element) {
+      $(element).on(Event.CLICK, this.toggle)
+    }
+
+    // public
+
+    toggle() {
+      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+        return
+      }
+
+      let parent   = Dropdown._getParentFromElement(this)
+      let isActive = $(parent).hasClass(ClassName.OPEN)
+
+      Dropdown._clearMenus()
+
+      if (isActive) {
+        return false
+      }
+
+      if ('ontouchstart' in document.documentElement &&
+         (!$(parent).closest(Selector.NAVBAR_NAV).length)) {
+
+        // if mobile we use a backdrop because click events don't delegate
+        let dropdown       = document.createElement('div')
+        dropdown.className = ClassName.BACKDROP
+        $(dropdown).insertBefore(this)
+        $(dropdown).on('click', Dropdown._clearMenus)
+      }
+
+      let relatedTarget = { relatedTarget : this }
+      let showEvent     = $.Event(Event.SHOW, relatedTarget)
+
+      $(parent).trigger(showEvent)
+
+      if (showEvent.isDefaultPrevented()) {
+        return
+      }
+
+      this.focus()
+      this.setAttribute('aria-expanded', 'true')
+
+      $(parent).toggleClass(ClassName.OPEN)
+      $(parent).trigger(Event.SHOWN, relatedTarget)
+
+      return false
+    }
+
+
+    // static
+
+    static _jQueryInterface(config) {
+      return this.each(function () {
+        let data  = $(this).data(DATA_KEY)
+
+        if (!data) {
+          $(this).data(DATA_KEY, (data = new Dropdown(this)))
+        }
+
+        if (typeof config === 'string') {
+          data[config].call(this)
+        }
+      })
+    }
+
+    static _clearMenus(event) {
+      if (event && event.which === 3) {
+        return
+      }
+
+      let backdrop = $(Selector.BACKDROP)[0]
+      if (backdrop) {
+        backdrop.parentNode.removeChild(backdrop)
+      }
+
+      let toggles = $.makeArray($(Selector.DATA_TOGGLE))
+
+      for (let i = 0; i < toggles.length; i++) {
+        let parent        = Dropdown._getParentFromElement(toggles[i])
+        let relatedTarget = { relatedTarget : toggles[i] }
+
+        if (!$(parent).hasClass(ClassName.OPEN)) {
+          continue
+        }
+
+        if (event && event.type === 'click' &&
+           (/input|textarea/i.test(event.target.tagName)) &&
+           ($.contains(parent, event.target))) {
+          continue
+        }
+
+        let hideEvent = $.Event(Event.HIDE, relatedTarget)
+        $(parent).trigger(hideEvent)
+        if (hideEvent.isDefaultPrevented()) {
+          continue
+        }
+
+        toggles[i].setAttribute('aria-expanded', 'false')
+
+        $(parent)
+          .removeClass(ClassName.OPEN)
+          .trigger(Event.HIDDEN, relatedTarget)
+      }
+    }
+
+    static _getParentFromElement(element) {
+      let parent
+      let selector = Util.getSelectorFromElement(element)
+
+      if (selector) {
+        parent = $(selector)[0]
+      }
+
+      return parent || element.parentNode
+    }
+
+    static _dataApiKeydownHandler(event) {
+      if (!/(38|40|27|32)/.test(event.which) ||
+         /input|textarea/i.test(event.target.tagName)) {
+        return
+      }
+
+      event.preventDefault()
+      event.stopPropagation()
+
+      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+        return
+      }
+
+      let parent   = Dropdown._getParentFromElement(this)
+      let isActive = $(parent).hasClass(ClassName.OPEN)
+
+      if ((!isActive && event.which !== 27) ||
+           (isActive && event.which === 27)) {
+
+        if (event.which === 27) {
+          let toggle = $(parent).find(Selector.DATA_TOGGLE)[0]
+          $(toggle).trigger('focus')
+        }
+
+        $(this).trigger('click')
+        return
+      }
+
+      let items = $.makeArray($(Selector.VISIBLE_ITEMS))
+
+      items = items.filter((item) => {
+        return item.offsetWidth || item.offsetHeight
+      })
+
+      if (!items.length) {
+        return
+      }
+
+      let index = items.indexOf(event.target)
+
+      if (event.which === 38 && index > 0)                index--  // up
+      if (event.which === 40 && index < items.length - 1) index++  // down
+      if (!~index)                                        index = 0
+
+      items[index].focus()
+    }
+
+  }
+
+
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+  $(document)
+    .on(Event.KEYDOWN, Selector.DATA_TOGGLE,  Dropdown._dataApiKeydownHandler)
+    .on(Event.KEYDOWN, Selector.ROLE_MENU,    Dropdown._dataApiKeydownHandler)
+    .on(Event.KEYDOWN, Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler)
+    .on(Event.CLICK_DATA, Dropdown._clearMenus)
+    .on(Event.CLICK_DATA, Selector.DATA_TOGGLE, Dropdown.prototype.toggle)
+    .on(Event.CLICK_DATA, 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)
+
+export default Dropdown
index cc008152fbf95ce02ff6fa120421e1393712c62b..fa25ed883f83f41063994445b82044b6f9e1efa7 100644 (file)
     <script src="../../js/dist/button.js"></script>
     <script src="../../js/dist/carousel.js"></script>
     <script src="../../js/dist/collapse.js"></script>
+    <script src="../../js/dist/dropdown.js"></script>
 
     <!-- Old Plugin sources -->
-    <script src="../../js/dropdown.js"></script>
     <script src="../../js/modal.js"></script>
     <script src="../../js/scrollspy.js"></script>
     <script src="../../js/tab.js"></script>
index 02090b6cc9c58026a95254f7f41b05fdf184d42a..a51267de8444112bbadec2c3621391cb72e7afe4 100644 (file)
     <h1>Dropdown <small>Bootstrap Visual Test</small></h1>
   </div>
 
-  <nav id="navbar-example" class="navbar navbar-default navbar-static" role="navigation">
+  <nav id="navbar-example" class="navbar navbar-default navbar-static-top" role="navigation">
     <div class="container-fluid">
-      <div class="navbar-header">
-        <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".bs-example-js-navbar-collapse">
-          <span class="sr-only">Toggle navigation</span>
-          <span class="icon-bar"></span>
-          <span class="icon-bar"></span>
-          <span class="icon-bar"></span>
-        </button>
-        <a class="navbar-brand" href="#">Project Name</a>
-      </div>
-      <div class="collapse navbar-collapse bs-example-js-navbar-collapse">
-        <ul class="nav navbar-nav">
-          <li class="dropdown">
-            <a id="drop1" href="#" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
+      <button class="navbar-toggler hidden-sm-up" type="button" data-toggle="collapse" data-target="#exCollapsingNavbar2">
+        &#9776;
+      </button>
+      <div class="collapse navbar-toggleable-xs" id="exCollapsingNavbar2">
+        <ul class="nav navbar-nav pull-left">
+          <li class="dropdown nav-item">
+            <a id="drop1" href="#" role="button" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
             <ul class="dropdown-menu" role="menu" aria-labelledby="drop1">
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Action</a></li>
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Another action</a></li>
@@ -45,8 +39,8 @@
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Separated link</a></li>
             </ul>
           </li>
-          <li class="dropdown">
-            <a href="#" id="drop2" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown 2 <b class="caret"></b></a>
+          <li class="dropdown nav-item">
+            <a href="#" id="drop2" role="button" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown 2 <b class="caret"></b></a>
             <ul class="dropdown-menu" role="menu" aria-labelledby="drop2">
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Action</a></li>
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Another action</a></li>
@@ -56,9 +50,9 @@
             </ul>
           </li>
         </ul>
-        <ul class="nav navbar-nav navbar-right">
-          <li id="fat-menu" class="dropdown">
-            <a href="#" id="drop3" role="button" class="dropdown-toggle" data-toggle="dropdown">Dropdown 3 <b class="caret"></b></a>
+        <ul class="nav navbar-nav pull-right">
+          <li id="fat-menu" class="dropdown nav-item">
+            <a href="#" id="drop3" role="button" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown 3 <b class="caret"></b></a>
             <ul class="dropdown-menu" role="menu" aria-labelledby="drop3">
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Action</a></li>
               <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Another action</a></li>
@@ -73,9 +67,9 @@
   </nav>
 
   <ul class="nav nav-pills">
-    <li class="active"><a href="#">Regular link</a></li>
-    <li class="dropdown">
-      <a id="drop4" role="button" data-toggle="dropdown" href="#">Dropdown <b class="caret"></b></a>
+    <li class="active nav-item"><a href="#" class="nav-link">Regular link</a></li>
+    <li class="dropdown nav-item">
+      <a id="drop4" class="nav-link" role="button" data-toggle="dropdown" href="#">Dropdown <b class="caret"></b></a>
       <ul id="menu1" class="dropdown-menu" role="menu" aria-labelledby="drop4">
         <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Action</a></li>
         <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Another action</a></li>
@@ -84,8 +78,8 @@
         <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Separated link</a></li>
       </ul>
     </li>
-    <li class="dropdown">
-      <a id="drop5" role="button" data-toggle="dropdown" href="#">Dropdown 2 <b class="caret"></b></a>
+    <li class="dropdown nav-item">
+      <a id="drop5" class="nav-link" role="button" data-toggle="dropdown" href="#">Dropdown 2 <b class="caret"></b></a>
       <ul id="menu2" class="dropdown-menu" role="menu" aria-labelledby="drop5">
         <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Action</a></li>
         <li role="presentation"><a role="menuitem" tabindex="-1" href="https://twitter.com/fat">Another action</a></li>
 
 <!-- JavaScript Includes -->
 <script src="../vendor/jquery.min.js"></script>
-<script src="../../transition.js"></script>
-<script src="../../dropdown.js"></script>
-<script src="../../collapse.js"></script>
+<script src="../../dist/util.js"></script>
+<script src="../../dist/dropdown.js"></script>
+<script src="../../dist/collapse.js"></script>
 
 </body>
 </html>