mirror of
https://github.com/twbs/bootstrap.git
synced 2025-08-24 14:13:06 +02:00
Merge branch 'twbs/v4-dev' into dropdown-keyboard
This commit is contained in:
@@ -3,7 +3,7 @@ import Util from './util'
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.0.0-alpha.2): dropdown.js
|
||||
* Bootstrap (v4.0.0-alpha.5): dropdown.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -17,12 +17,16 @@ const Dropdown = (($) => {
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const NAME = 'dropdown'
|
||||
const VERSION = '4.0.0-alpha.2'
|
||||
const DATA_KEY = 'bs.dropdown'
|
||||
const EVENT_KEY = `.${DATA_KEY}`
|
||||
const DATA_API_KEY = '.data-api'
|
||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
||||
const NAME = 'dropdown'
|
||||
const VERSION = '4.0.0-alpha.5'
|
||||
const DATA_KEY = 'bs.dropdown'
|
||||
const EVENT_KEY = `.${DATA_KEY}`
|
||||
const DATA_API_KEY = '.data-api'
|
||||
const JQUERY_NO_CONFLICT = $.fn[NAME]
|
||||
const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
|
||||
const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key
|
||||
const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key
|
||||
const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)
|
||||
|
||||
const Event = {
|
||||
HIDE : `hide${EVENT_KEY}`,
|
||||
@@ -37,7 +41,7 @@ const Dropdown = (($) => {
|
||||
const ClassName = {
|
||||
BACKDROP : 'dropdown-backdrop',
|
||||
DISABLED : 'disabled',
|
||||
OPEN : 'open'
|
||||
SHOW : 'show'
|
||||
}
|
||||
|
||||
const Selector = {
|
||||
@@ -79,8 +83,8 @@ const Dropdown = (($) => {
|
||||
return false
|
||||
}
|
||||
|
||||
let parent = Dropdown._getParentFromElement(this)
|
||||
let isActive = $(parent).hasClass(ClassName.OPEN)
|
||||
const parent = Dropdown._getParentFromElement(this)
|
||||
const isActive = $(parent).hasClass(ClassName.SHOW)
|
||||
|
||||
Dropdown._clearMenus()
|
||||
|
||||
@@ -89,17 +93,19 @@ const Dropdown = (($) => {
|
||||
}
|
||||
|
||||
if ('ontouchstart' in document.documentElement &&
|
||||
(!$(parent).closest(Selector.NAVBAR_NAV).length)) {
|
||||
!$(parent).closest(Selector.NAVBAR_NAV).length) {
|
||||
|
||||
// if mobile we use a backdrop because click events don't delegate
|
||||
let dropdown = document.createElement('div')
|
||||
const 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)
|
||||
const relatedTarget = {
|
||||
relatedTarget : this
|
||||
}
|
||||
const showEvent = $.Event(Event.SHOW, relatedTarget)
|
||||
|
||||
$(parent).trigger(showEvent)
|
||||
|
||||
@@ -108,9 +114,9 @@ const Dropdown = (($) => {
|
||||
}
|
||||
|
||||
this.focus()
|
||||
this.setAttribute('aria-expanded', 'true')
|
||||
this.setAttribute('aria-expanded', true)
|
||||
|
||||
$(parent).toggleClass(ClassName.OPEN)
|
||||
$(parent).toggleClass(ClassName.SHOW)
|
||||
$(parent).trigger($.Event(Event.SHOWN, relatedTarget))
|
||||
|
||||
return false
|
||||
@@ -134,10 +140,11 @@ const Dropdown = (($) => {
|
||||
|
||||
static _jQueryInterface(config) {
|
||||
return this.each(function () {
|
||||
let data = $(this).data(DATA_KEY)
|
||||
let data = $(this).data(DATA_KEY)
|
||||
|
||||
if (!data) {
|
||||
$(this).data(DATA_KEY, (data = new Dropdown(this)))
|
||||
data = new Dropdown(this)
|
||||
$(this).data(DATA_KEY, data)
|
||||
}
|
||||
|
||||
if (typeof config === 'string') {
|
||||
@@ -150,32 +157,34 @@ const Dropdown = (($) => {
|
||||
}
|
||||
|
||||
static _clearMenus(event) {
|
||||
if (event && event.which === 3) {
|
||||
if (event && event.which === RIGHT_MOUSE_BUTTON_WHICH) {
|
||||
return
|
||||
}
|
||||
|
||||
let backdrop = $(Selector.BACKDROP)[0]
|
||||
const backdrop = $(Selector.BACKDROP)[0]
|
||||
if (backdrop) {
|
||||
backdrop.parentNode.removeChild(backdrop)
|
||||
}
|
||||
|
||||
let toggles = $.makeArray($(Selector.DATA_TOGGLE))
|
||||
const toggles = $.makeArray($(Selector.DATA_TOGGLE))
|
||||
|
||||
for (let i = 0; i < toggles.length; i++) {
|
||||
let parent = Dropdown._getParentFromElement(toggles[i])
|
||||
let relatedTarget = { relatedTarget : toggles[i] }
|
||||
const parent = Dropdown._getParentFromElement(toggles[i])
|
||||
const relatedTarget = {
|
||||
relatedTarget : toggles[i]
|
||||
}
|
||||
|
||||
if (!$(parent).hasClass(ClassName.OPEN)) {
|
||||
if (!$(parent).hasClass(ClassName.SHOW)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (event && event.type === 'click' &&
|
||||
(/input|textarea/i.test(event.target.tagName)) &&
|
||||
($.contains(parent, event.target))) {
|
||||
/input|textarea/i.test(event.target.tagName) &&
|
||||
$.contains(parent, event.target)) {
|
||||
continue
|
||||
}
|
||||
|
||||
let hideEvent = $.Event(Event.HIDE, relatedTarget)
|
||||
const hideEvent = $.Event(Event.HIDE, relatedTarget)
|
||||
$(parent).trigger(hideEvent)
|
||||
if (hideEvent.isDefaultPrevented()) {
|
||||
continue
|
||||
@@ -184,14 +193,14 @@ const Dropdown = (($) => {
|
||||
toggles[i].setAttribute('aria-expanded', 'false')
|
||||
|
||||
$(parent)
|
||||
.removeClass(ClassName.OPEN)
|
||||
.removeClass(ClassName.SHOW)
|
||||
.trigger($.Event(Event.HIDDEN, relatedTarget))
|
||||
}
|
||||
}
|
||||
|
||||
static _getParentFromElement(element) {
|
||||
let parent
|
||||
let selector = Util.getSelectorFromElement(element)
|
||||
const selector = Util.getSelectorFromElement(element)
|
||||
|
||||
if (selector) {
|
||||
parent = $(selector)[0]
|
||||
@@ -213,14 +222,14 @@ const Dropdown = (($) => {
|
||||
return
|
||||
}
|
||||
|
||||
let parent = Dropdown._getParentFromElement(this)
|
||||
let isActive = $(parent).hasClass(ClassName.OPEN)
|
||||
const parent = Dropdown._getParentFromElement(this)
|
||||
const isActive = $(parent).hasClass(ClassName.SHOW)
|
||||
|
||||
if ((!isActive && event.which !== 27) ||
|
||||
(isActive && event.which === 27)) {
|
||||
if (!isActive && event.which !== ESCAPE_KEYCODE ||
|
||||
isActive && event.which === ESCAPE_KEYCODE) {
|
||||
|
||||
if (event.which === 27) {
|
||||
let toggle = $(parent).find(Selector.DATA_TOGGLE)[0]
|
||||
if (event.which === ESCAPE_KEYCODE) {
|
||||
const toggle = $(parent).find(Selector.DATA_TOGGLE)[0]
|
||||
$(toggle).trigger('focus')
|
||||
}
|
||||
|
||||
@@ -228,11 +237,7 @@ const Dropdown = (($) => {
|
||||
return
|
||||
}
|
||||
|
||||
let items = $.makeArray($(Selector.VISIBLE_ITEMS))
|
||||
|
||||
items = items.filter((item) => {
|
||||
return item.offsetWidth || item.offsetHeight
|
||||
})
|
||||
const items = $(parent).find(Selector.VISIBLE_ITEMS).get()
|
||||
|
||||
if (!items.length) {
|
||||
return
|
||||
@@ -240,11 +245,11 @@ const Dropdown = (($) => {
|
||||
|
||||
let index = items.indexOf(event.target)
|
||||
|
||||
if (event.which === 38 && index > 0) { // up
|
||||
if (event.which === ARROW_UP_KEYCODE && index > 0) { // up
|
||||
index--
|
||||
}
|
||||
|
||||
if (event.which === 40 && index < items.length - 1) { // down
|
||||
if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { // down
|
||||
index++
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user