diff options
Diffstat (limited to 'docs/dist/js/bootstrap.js')
| -rw-r--r-- | docs/dist/js/bootstrap.js | 810 |
1 files changed, 520 insertions, 290 deletions
diff --git a/docs/dist/js/bootstrap.js b/docs/dist/js/bootstrap.js index b9e5f56f9..f05008306 100644 --- a/docs/dist/js/bootstrap.js +++ b/docs/dist/js/bootstrap.js @@ -1,6 +1,6 @@ /*! - * Bootstrap v4.0.0-alpha.5 (https://getbootstrap.com) - * Copyright 2011-2016 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Bootstrap v4.0.0-alpha.6 (https://getbootstrap.com) + * Copyright 2011-2017 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ @@ -8,16 +8,14 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.') } -+function ($) { +(function ($) { var version = $.fn.jquery.split(' ')[0].split('.') if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] >= 4)) { throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0') } -}(jQuery); - - -+function () { +})(jQuery); +(function () { 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; }; }(); @@ -30,7 +28,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons /** * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-alpha.5): util.js + * Bootstrap (v4.0.0-alpha.6): util.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ @@ -141,13 +139,16 @@ var Util = function ($) { }, getSelectorFromElement: function getSelectorFromElement(element) { var selector = element.getAttribute('data-target'); - - if (!selector) { + if (!selector || selector === '#') { selector = element.getAttribute('href') || ''; - selector = /^#[a-z]/i.test(selector) ? selector : null; } - return selector; + try { + var $selector = $(selector); + return $selector.length > 0 ? selector : null; + } catch (error) { + return null; + } }, reflow: function reflow(element) { return element.offsetHeight; @@ -180,7 +181,7 @@ var Util = function ($) { /** * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-alpha.5): alert.js + * Bootstrap (v4.0.0-alpha.6): alert.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ @@ -194,7 +195,7 @@ var Alert = function ($) { */ var NAME = 'alert'; - var VERSION = '4.0.0-alpha.5'; + var VERSION = '4.0.0-alpha.6'; var DATA_KEY = 'bs.alert'; var EVENT_KEY = '.' + DATA_KEY; var DATA_API_KEY = '.data-api'; @@ -359,7 +360,7 @@ var Alert = function ($) { /** * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-alpha.5): button.js + * Bootstrap (v4.0.0-alpha.6): button.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ @@ -373,7 +374,7 @@ var Button = function ($) { */ var NAME = 'button'; - var VERSION = '4.0.0-alpha.5'; + var VERSION = '4.0.0-alpha.6'; var DATA_KEY = 'bs.button'; var EVENT_KEY = '.' + DATA_KEY; var DATA_API_KEY = '.data-api'; @@ -417,6 +418,7 @@ var Button = function ($) { Button.prototype.toggle = function toggle() { var triggerChangeEvent = true; + var addAriaPressed = true; var rootElement = $(this._element).closest(Selector.DATA_TOGGLE)[0]; if (rootElement) { @@ -436,13 +438,19 @@ var Button = function ($) { } if (triggerChangeEvent) { + if (input.hasAttribute('disabled') || rootElement.hasAttribute('disabled') || input.classList.contains('disabled') || rootElement.classList.contains('disabled')) { + return; + } input.checked = !$(this._element).hasClass(ClassName.ACTIVE); $(input).trigger('change'); } input.focus(); + addAriaPressed = false; } - } else { + } + + if (addAriaPressed) { this._element.setAttribute('aria-pressed', !$(this._element).hasClass(ClassName.ACTIVE)); } @@ -522,7 +530,7 @@ var Button = function ($) { /** * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-alpha.5): carousel.js + * Bootstrap (v4.0.0-alpha.6): carousel.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ @@ -536,7 +544,7 @@ var Carousel = function ($) { */ var NAME = 'carousel'; - var VERSION = '4.0.0-alpha.5'; + var VERSION = '4.0.0-alpha.6'; var DATA_KEY = 'bs.carousel'; var EVENT_KEY = '.' + DATA_KEY; var DATA_API_KEY = '.data-api'; @@ -544,6 +552,7 @@ var Carousel = function ($) { var TRANSITION_DURATION = 600; var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key + var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch var Default = { interval: 5000, @@ -574,6 +583,7 @@ var Carousel = function ($) { KEYDOWN: 'keydown' + EVENT_KEY, MOUSEENTER: 'mouseenter' + EVENT_KEY, MOUSELEAVE: 'mouseleave' + EVENT_KEY, + TOUCHEND: 'touchend' + EVENT_KEY, LOAD_DATA_API: 'load' + EVENT_KEY + DATA_API_KEY, CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY }; @@ -616,6 +626,8 @@ var Carousel = function ($) { this._isPaused = false; this._isSliding = false; + this.touchTimeout = null; + this._config = this._getConfig(config); this._element = $(element)[0]; this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0]; @@ -628,10 +640,9 @@ var Carousel = function ($) { // public Carousel.prototype.next = function next() { - if (this._isSliding) { - throw new Error('Carousel is sliding'); + if (!this._isSliding) { + this._slide(Direction.NEXT); } - this._slide(Direction.NEXT); }; Carousel.prototype.nextWhenVisible = function nextWhenVisible() { @@ -642,10 +653,9 @@ var Carousel = function ($) { }; Carousel.prototype.prev = function prev() { - if (this._isSliding) { - throw new Error('Carousel is sliding'); + if (!this._isSliding) { + this._slide(Direction.PREV); } - this._slide(Direction.PREVIOUS); }; Carousel.prototype.pause = function pause(event) { @@ -701,7 +711,7 @@ var Carousel = function ($) { return; } - var direction = index > activeIndex ? Direction.NEXT : Direction.PREVIOUS; + var direction = index > activeIndex ? Direction.NEXT : Direction.PREV; this._slide(direction, this._items[index]); }; @@ -737,12 +747,30 @@ var Carousel = function ($) { }); } - if (this._config.pause === 'hover' && !('ontouchstart' in document.documentElement)) { + if (this._config.pause === 'hover') { $(this._element).on(Event.MOUSEENTER, function (event) { return _this4.pause(event); }).on(Event.MOUSELEAVE, function (event) { return _this4.cycle(event); }); + if ('ontouchstart' in document.documentElement) { + // if it's a touch-enabled device, mouseenter/leave are fired as + // part of the mouse compatibility events on first tap - the carousel + // would stop cycling until user tapped out of it; + // here, we listen for touchend, explicitly pause the carousel + // (as if it's the second time we tap on it, mouseenter compat event + // is NOT fired) and after a timeout (to allow for mouse compatibility + // events to fire) we explicitly restart cycling + $(this._element).on(Event.TOUCHEND, function () { + _this4.pause(); + if (_this4.touchTimeout) { + clearTimeout(_this4.touchTimeout); + } + _this4.touchTimeout = setTimeout(function (event) { + return _this4.cycle(event); + }, TOUCHEVENT_COMPAT_WAIT + _this4._config.interval); + }); + } } }; @@ -772,7 +800,7 @@ var Carousel = function ($) { Carousel.prototype._getItemByDirection = function _getItemByDirection(direction, activeElement) { var isNextDirection = direction === Direction.NEXT; - var isPrevDirection = direction === Direction.PREVIOUS; + var isPrevDirection = direction === Direction.PREV; var activeIndex = this._getItemIndex(activeElement); var lastItemIndex = this._items.length - 1; var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex; @@ -781,16 +809,20 @@ var Carousel = function ($) { return activeElement; } - var delta = direction === Direction.PREVIOUS ? -1 : 1; + var delta = direction === Direction.PREV ? -1 : 1; var itemIndex = (activeIndex + delta) % this._items.length; return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex]; }; Carousel.prototype._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) { + var targetIndex = this._getItemIndex(relatedTarget); + var fromIndex = this._getItemIndex($(this._element).find(Selector.ACTIVE_ITEM)[0]); var slideEvent = $.Event(Event.SLIDE, { relatedTarget: relatedTarget, - direction: eventDirectionName + direction: eventDirectionName, + from: fromIndex, + to: targetIndex }); $(this._element).trigger(slideEvent); @@ -814,8 +846,9 @@ var Carousel = function ($) { var _this5 = this; var activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]; + var activeElementIndex = this._getItemIndex(activeElement); var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement); - + var nextElementIndex = this._getItemIndex(nextElement); var isCycling = Boolean(this._interval); var directionalClassName = void 0; @@ -857,7 +890,9 @@ var Carousel = function ($) { var slidEvent = $.Event(Event.SLID, { relatedTarget: nextElement, - direction: eventDirectionName + direction: eventDirectionName, + from: activeElementIndex, + to: nextElementIndex }); if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.SLIDE)) { @@ -1002,7 +1037,7 @@ var Carousel = function ($) { /** * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-alpha.5): collapse.js + * Bootstrap (v4.0.0-alpha.6): collapse.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ @@ -1016,7 +1051,7 @@ var Collapse = function ($) { */ var NAME = 'collapse'; - var VERSION = '4.0.0-alpha.5'; + var VERSION = '4.0.0-alpha.6'; var DATA_KEY = 'bs.collapse'; var EVENT_KEY = '.' + DATA_KEY; var DATA_API_KEY = '.data-api'; @@ -1054,7 +1089,7 @@ var Collapse = function ($) { }; var Selector = { - ACTIVES: '.card > .show, .card > .collapsing', + ACTIVES: '.show, .collapsing', DATA_TOGGLE: '[data-toggle="collapse"]' }; @@ -1099,11 +1134,7 @@ var Collapse = function ($) { Collapse.prototype.show = function show() { var _this6 = this; - if (this._isTransitioning) { - throw new Error('Collapse is transitioning'); - } - - if ($(this._element).hasClass(ClassName.SHOW)) { + if (this._isTransitioning || $(this._element).hasClass(ClassName.SHOW)) { return; } @@ -1111,7 +1142,7 @@ var Collapse = function ($) { var activesData = void 0; if (this._parent) { - actives = $.makeArray($(this._parent).find(Selector.ACTIVES)); + actives = $.makeArray($(this._parent).children().children(Selector.ACTIVES)); if (!actives.length) { actives = null; } @@ -1142,7 +1173,6 @@ var Collapse = function ($) { $(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING); this._element.style[dimension] = 0; - this._element.setAttribute('aria-expanded', true); if (this._triggerArray.length) { $(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true); @@ -1176,11 +1206,7 @@ var Collapse = function ($) { Collapse.prototype.hide = function hide() { var _this7 = this; - if (this._isTransitioning) { - throw new Error('Collapse is transitioning'); - } - - if (!$(this._element).hasClass(ClassName.SHOW)) { + if (this._isTransitioning || !$(this._element).hasClass(ClassName.SHOW)) { return; } @@ -1191,16 +1217,13 @@ var Collapse = function ($) { } var dimension = this._getDimension(); - var offsetDimension = dimension === Dimension.WIDTH ? 'offsetWidth' : 'offsetHeight'; - this._element.style[dimension] = this._element[offsetDimension] + 'px'; + this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + 'px'; Util.reflow(this._element); $(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW); - this._element.setAttribute('aria-expanded', false); - if (this._triggerArray.length) { $(this._triggerArray).addClass(ClassName.COLLAPSED).attr('aria-expanded', false); } @@ -1266,7 +1289,6 @@ var Collapse = function ($) { Collapse.prototype._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) { if (element) { var isOpen = $(element).hasClass(ClassName.SHOW); - element.setAttribute('aria-expanded', isOpen); if (triggerArray.length) { $(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen); @@ -1327,7 +1349,9 @@ var Collapse = function ($) { */ $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { - event.preventDefault(); + if (!/input|textarea/i.test(event.target.tagName)) { + event.preventDefault(); + } var target = Collapse._getTargetFromElement(this); var data = $(target).data(DATA_KEY); @@ -1352,9 +1376,11 @@ var Collapse = function ($) { return Collapse; }(jQuery); +/* global Popper */ + /** * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-alpha.5): dropdown.js + * Bootstrap (v4.0.0-alpha.6): dropdown.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ @@ -1362,21 +1388,32 @@ var Collapse = function ($) { 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.5'; + 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, @@ -1385,23 +1422,38 @@ var Dropdown = function ($) { 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 + KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + DATA_API_KEY, + KEYUP_DATA_API: 'keyup' + EVENT_KEY + DATA_API_KEY }; var ClassName = { - BACKDROP: 'dropdown-backdrop', DISABLED: 'disabled', SHOW: 'show' }; var Selector = { - BACKDROP: '.dropdown-backdrop', DATA_TOGGLE: '[data-toggle="dropdown"]', FORM_CHILD: '.dropdown form', - ROLE_MENU: '[role="menu"]', - ROLE_LISTBOX: '[role="listbox"]', + MENU: '.dropdown-menu', NAVBAR_NAV: '.navbar-nav', - VISIBLE_ITEMS: '[role="menu"] li:not(.disabled) a, ' + '[role="listbox"] li:not(.disabled) a' + VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled)' + }; + + var AttachmentMap = { + TOP: 'top-start', + BOTTOM: 'bottom-start' + }; + + var Default = { + placement: AttachmentMap.BOTTOM, + offset: 0, + flip: true + }; + + var DefaultType = { + placement: 'string', + offset: '(number|string)', + flip: 'boolean' }; /** @@ -1411,10 +1463,13 @@ var Dropdown = function ($) { */ var Dropdown = function () { - function Dropdown(element) { + function Dropdown(element, config) { _classCallCheck(this, Dropdown); this._element = element; + this._popper = null; + this._config = this._getConfig(config); + this._menu = this._getMenuElement(); this._addEventListeners(); } @@ -1424,58 +1479,107 @@ var Dropdown = function ($) { // public Dropdown.prototype.toggle = function toggle() { - if (this.disabled || $(this).hasClass(ClassName.DISABLED)) { - return false; + if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) { + return; } - var parent = Dropdown._getParentFromElement(this); - var isActive = $(parent).hasClass(ClassName.SHOW); + var parent = Dropdown._getParentFromElement(this._element); + var isActive = $(this._menu).hasClass(ClassName.SHOW); 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); + return; } var relatedTarget = { - relatedTarget: this + relatedTarget: this._element }; var showEvent = $.Event(Event.SHOW, relatedTarget); $(parent).trigger(showEvent); if (showEvent.isDefaultPrevented()) { - return false; + return; } - this.focus(); - this.setAttribute('aria-expanded', true); + // Handle dropup + var dropdownPlacement = $(this._element).parent().hasClass('dropup') ? AttachmentMap.TOP : this._config.placement; + this._popper = new Popper(this._element, this._menu, { + placement: dropdownPlacement, + modifiers: { + offset: { + offset: this._config.offset + }, + flip: { + enabled: this._config.flip + } + } + }); + + // 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); + } - $(parent).toggleClass(ClassName.SHOW); - $(parent).trigger($.Event(Event.SHOWN, relatedTarget)); + this._element.focus(); + this._element.setAttribute('aria-expanded', true); - return false; + $(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() { + if (this._popper !== null) { + this._popper.scheduleUpdate(); + } }; // private Dropdown.prototype._addEventListeners = function _addEventListeners() { - $(this._element).on(Event.CLICK, this.toggle); + var _this9 = this; + + $(this._element).on(Event.CLICK, function (event) { + event.preventDefault(); + event.stopPropagation(); + _this9.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; }; // static @@ -1483,9 +1587,10 @@ var Dropdown = function ($) { 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); + data = new Dropdown(this, _config); $(this).data(DATA_KEY, data); } @@ -1493,34 +1598,34 @@ var Dropdown = function ($) { if (data[config] === undefined) { throw new Error('No method named "' + config + '"'); } - data[config].call(this); + data[config](); } }); }; Dropdown._clearMenus = function _clearMenus(event) { - if (event && event.which === RIGHT_MOUSE_BUTTON_WHICH) { + if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) { 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 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) && $.contains(parent, event.target)) { + if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) { continue; } @@ -1530,8 +1635,15 @@ var Dropdown = function ($) { 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)); } }; @@ -1548,7 +1660,7 @@ var Dropdown = function ($) { }; Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) { - if (!/(38|40|27|32)/.test(event.which) || /input|textarea/i.test(event.target.tagName)) { + if (!REGEXP_KEYDOWN.test(event.which) || /button/i.test(event.target.tagName) && event.which === SPACE_KEYCODE || /input|textarea/i.test(event.target.tagName)) { return; } @@ -1562,7 +1674,7 @@ var Dropdown = function ($) { var parent = Dropdown._getParentFromElement(this); var isActive = $(parent).hasClass(ClassName.SHOW); - if (!isActive && event.which !== ESCAPE_KEYCODE || isActive && event.which === ESCAPE_KEYCODE) { + 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]; @@ -1603,6 +1715,16 @@ var Dropdown = function ($) { get: function get() { return VERSION; } + }, { + key: 'Default', + get: function get() { + return Default; + } + }, { + key: 'DefaultType', + get: function get() { + return DefaultType; + } }]); return Dropdown; @@ -1614,7 +1736,11 @@ var Dropdown = function ($) { * ------------------------------------------------------------------------ */ - $(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.ROLE_MENU, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, Dropdown.prototype.toggle).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) { + $(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(); }); @@ -1636,7 +1762,7 @@ var Dropdown = function ($) { /** * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-alpha.5): modal.js + * Bootstrap (v4.0.0-alpha.6): modal.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ @@ -1650,7 +1776,7 @@ var Modal = function ($) { */ var NAME = 'modal'; - var VERSION = '4.0.0-alpha.5'; + var VERSION = '4.0.0-alpha.6'; var DATA_KEY = 'bs.modal'; var EVENT_KEY = '.' + DATA_KEY; var DATA_API_KEY = '.data-api'; @@ -1699,7 +1825,8 @@ var Modal = function ($) { DIALOG: '.modal-dialog', DATA_TOGGLE: '[data-toggle="modal"]', DATA_DISMISS: '[data-dismiss="modal"]', - FIXED_CONTENT: '.navbar-fixed-top, .navbar-fixed-bottom, .is-fixed' + FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top', + NAVBAR_TOGGLER: '.navbar-toggler' }; /** @@ -1719,7 +1846,6 @@ var Modal = function ($) { this._isShown = false; this._isBodyOverflowing = false; this._ignoreBackdropClick = false; - this._isTransitioning = false; this._originalBodyPadding = 0; this._scrollbarWidth = 0; } @@ -1733,15 +1859,16 @@ var Modal = function ($) { }; Modal.prototype.show = function show(relatedTarget) { - var _this9 = this; + var _this10 = this; if (this._isTransitioning) { - throw new Error('Modal is transitioning'); + return; } if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) { this._isTransitioning = true; } + var showEvent = $.Event(Event.SHOW, { relatedTarget: relatedTarget }); @@ -1763,39 +1890,41 @@ var Modal = function ($) { this._setResizeEvent(); $(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, function (event) { - return _this9.hide(event); + return _this10.hide(event); }); $(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () { - $(_this9._element).one(Event.MOUSEUP_DISMISS, function (event) { - if ($(event.target).is(_this9._element)) { - _this9._ignoreBackdropClick = true; + $(_this10._element).one(Event.MOUSEUP_DISMISS, function (event) { + if ($(event.target).is(_this10._element)) { + _this10._ignoreBackdropClick = true; } }); }); this._showBackdrop(function () { - return _this9._showElement(relatedTarget); + return _this10._showElement(relatedTarget); }); }; Modal.prototype.hide = function hide(event) { - var _this10 = this; + var _this11 = this; if (event) { event.preventDefault(); } - if (this._isTransitioning) { - throw new Error('Modal is transitioning'); + if (this._isTransitioning || !this._isShown) { + return; } var transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE); + if (transition) { this._isTransitioning = true; } var hideEvent = $.Event(Event.HIDE); + $(this._element).trigger(hideEvent); if (!this._isShown || hideEvent.isDefaultPrevented()) { @@ -1815,8 +1944,9 @@ var Modal = function ($) { $(this._dialog).off(Event.MOUSEDOWN_DISMISS); if (transition) { + $(this._element).one(Util.TRANSITION_END, function (event) { - return _this10._hideModal(event); + return _this11._hideModal(event); }).emulateTransitionEnd(TRANSITION_DURATION); } else { this._hideModal(); @@ -1835,10 +1965,13 @@ var Modal = function ($) { this._isShown = null; this._isBodyOverflowing = null; this._ignoreBackdropClick = null; - this._originalBodyPadding = null; this._scrollbarWidth = null; }; + Modal.prototype.handleUpdate = function handleUpdate() { + this._adjustDialog(); + }; + // private Modal.prototype._getConfig = function _getConfig(config) { @@ -1848,7 +1981,7 @@ var Modal = function ($) { }; Modal.prototype._showElement = function _showElement(relatedTarget) { - var _this11 = this; + var _this12 = this; var transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE); @@ -1876,11 +2009,11 @@ var Modal = function ($) { }); var transitionComplete = function transitionComplete() { - if (_this11._config.focus) { - _this11._element.focus(); + if (_this12._config.focus) { + _this12._element.focus(); } - _this11._isTransitioning = false; - $(_this11._element).trigger(shownEvent); + _this12._isTransitioning = false; + $(_this12._element).trigger(shownEvent); }; if (transition) { @@ -1891,23 +2024,24 @@ var Modal = function ($) { }; Modal.prototype._enforceFocus = function _enforceFocus() { - var _this12 = this; + var _this13 = this; $(document).off(Event.FOCUSIN) // guard against infinite focus loop .on(Event.FOCUSIN, function (event) { - if (document !== event.target && _this12._element !== event.target && !$(_this12._element).has(event.target).length) { - _this12._element.focus(); + if (document !== event.target && _this13._element !== event.target && !$(_this13._element).has(event.target).length) { + _this13._element.focus(); } }); }; Modal.prototype._setEscapeEvent = function _setEscapeEvent() { - var _this13 = this; + var _this14 = this; if (this._isShown && this._config.keyboard) { $(this._element).on(Event.KEYDOWN_DISMISS, function (event) { if (event.which === ESCAPE_KEYCODE) { - _this13.hide(); + event.preventDefault(); + _this14.hide(); } }); } else if (!this._isShown) { @@ -1916,11 +2050,11 @@ var Modal = function ($) { }; Modal.prototype._setResizeEvent = function _setResizeEvent() { - var _this14 = this; + var _this15 = this; if (this._isShown) { $(window).on(Event.RESIZE, function (event) { - return _this14._handleUpdate(event); + return _this15.handleUpdate(event); }); } else { $(window).off(Event.RESIZE); @@ -1928,16 +2062,16 @@ var Modal = function ($) { }; Modal.prototype._hideModal = function _hideModal() { - var _this15 = this; + var _this16 = this; this._element.style.display = 'none'; - this._element.setAttribute('aria-hidden', 'true'); + this._element.setAttribute('aria-hidden', true); this._isTransitioning = false; this._showBackdrop(function () { $(document.body).removeClass(ClassName.OPEN); - _this15._resetAdjustments(); - _this15._resetScrollbar(); - $(_this15._element).trigger(Event.HIDDEN); + _this16._resetAdjustments(); + _this16._resetScrollbar(); + $(_this16._element).trigger(Event.HIDDEN); }); }; @@ -1949,7 +2083,7 @@ var Modal = function ($) { }; Modal.prototype._showBackdrop = function _showBackdrop(callback) { - var _this16 = this; + var _this17 = this; var animate = $(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : ''; @@ -1966,17 +2100,17 @@ var Modal = function ($) { $(this._backdrop).appendTo(document.body); $(this._element).on(Event.CLICK_DISMISS, function (event) { - if (_this16._ignoreBackdropClick) { - _this16._ignoreBackdropClick = false; + if (_this17._ignoreBackdropClick) { + _this17._ignoreBackdropClick = false; return; } if (event.target !== event.currentTarget) { return; } - if (_this16._config.backdrop === 'static') { - _this16._element.focus(); + if (_this17._config.backdrop === 'static') { + _this17._element.focus(); } else { - _this16.hide(); + _this17.hide(); } }); @@ -2000,7 +2134,7 @@ var Modal = function ($) { $(this._backdrop).removeClass(ClassName.SHOW); var callbackRemove = function callbackRemove() { - _this16._removeBackdrop(); + _this17._removeBackdrop(); if (callback) { callback(); } @@ -2021,10 +2155,6 @@ var Modal = function ($) { // todo (fat): these should probably be refactored out of modal.js // ---------------------------------------------------------------------- - Modal.prototype._handleUpdate = function _handleUpdate() { - this._adjustDialog(); - }; - Modal.prototype._adjustDialog = function _adjustDialog() { var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; @@ -2048,17 +2178,55 @@ var Modal = function ($) { }; Modal.prototype._setScrollbar = function _setScrollbar() { - var bodyPadding = parseInt($(Selector.FIXED_CONTENT).css('padding-right') || 0, 10); - - this._originalBodyPadding = document.body.style.paddingRight || ''; + var _this18 = this; if (this._isBodyOverflowing) { - document.body.style.paddingRight = bodyPadding + this._scrollbarWidth + 'px'; + // Note: DOMNode.style.paddingRight returns the actual value or '' if not set + // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set + + // Adjust fixed content padding + $(Selector.FIXED_CONTENT).each(function (index, element) { + var actualPadding = $(element)[0].style.paddingRight; + var calculatedPadding = $(element).css('padding-right'); + $(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this18._scrollbarWidth + 'px'); + }); + + // Adjust navbar-toggler margin + $(Selector.NAVBAR_TOGGLER).each(function (index, element) { + var actualMargin = $(element)[0].style.marginRight; + var calculatedMargin = $(element).css('margin-right'); + $(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) + _this18._scrollbarWidth + 'px'); + }); + + // Adjust body padding + var actualPadding = document.body.style.paddingRight; + var calculatedPadding = $('body').css('padding-right'); + $('body').data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + 'px'); } }; Modal.prototype._resetScrollbar = function _resetScrollbar() { - document.body.style.paddingRight = this._originalBodyPadding; + // Restore fixed content padding + $(Selector.FIXED_CONTENT).each(function (index, element) { + var padding = $(element).data('padding-right'); + if (typeof padding !== 'undefined') { + $(element).css('padding-right', padding).removeData('padding-right'); + } + }); + + // Restore navbar-toggler margin + $(Selector.NAVBAR_TOGGLER).each(function (index, element) { + var margin = $(element).data('margin-right'); + if (typeof margin !== 'undefined') { + $(element).css('margin-right', margin).removeData('margin-right'); + } + }); + + // Restore body padding + var padding = $('body').data('padding-right'); + if (typeof padding !== 'undefined') { + $('body').css('padding-right', padding).removeData('padding-right'); + } }; Modal.prototype._getScrollbarWidth = function _getScrollbarWidth() { @@ -2066,7 +2234,7 @@ var Modal = function ($) { var scrollDiv = document.createElement('div'); scrollDiv.className = ClassName.SCROLLBAR_MEASURER; document.body.appendChild(scrollDiv); - var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth; + var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth; document.body.removeChild(scrollDiv); return scrollbarWidth; }; @@ -2116,7 +2284,7 @@ var Modal = function ($) { */ $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { - var _this17 = this; + var _this19 = this; var target = void 0; var selector = Util.getSelectorFromElement(this); @@ -2138,8 +2306,8 @@ var Modal = function ($) { } $target.one(Event.HIDDEN, function () { - if ($(_this17).is(':visible')) { - _this17.focus(); + if ($(_this19).is(':visible')) { + _this19.focus(); } }); }); @@ -2165,7 +2333,7 @@ var Modal = function ($) { /** * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-alpha.5): scrollspy.js + * Bootstrap (v4.0.0-alpha.6): scrollspy.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ @@ -2179,7 +2347,7 @@ var ScrollSpy = function ($) { */ var NAME = 'scrollspy'; - var VERSION = '4.0.0-alpha.5'; + var VERSION = '4.0.0-alpha.6'; var DATA_KEY = 'bs.scrollspy'; var EVENT_KEY = '.' + DATA_KEY; var DATA_API_KEY = '.data-api'; @@ -2206,18 +2374,15 @@ var ScrollSpy = function ($) { var ClassName = { DROPDOWN_ITEM: 'dropdown-item', DROPDOWN_MENU: 'dropdown-menu', - NAV_LINK: 'nav-link', - NAV: 'nav', ACTIVE: 'active' }; var Selector = { DATA_SPY: '[data-spy="scroll"]', ACTIVE: '.active', - LIST_ITEM: '.list-item', - LI: 'li', - LI_DROPDOWN: 'li.dropdown', + NAV_LIST_GROUP: '.nav, .list-group', NAV_LINKS: '.nav-link', + LIST_ITEMS: '.list-group-item', DROPDOWN: '.dropdown', DROPDOWN_ITEMS: '.dropdown-item', DROPDOWN_TOGGLE: '.dropdown-toggle' @@ -2236,21 +2401,21 @@ var ScrollSpy = function ($) { var ScrollSpy = function () { function ScrollSpy(element, config) { - var _this18 = this; + var _this20 = this; _classCallCheck(this, ScrollSpy); this._element = element; this._scrollElement = element.tagName === 'BODY' ? window : element; this._config = this._getConfig(config); - this._selector = this._config.target + ' ' + Selector.NAV_LINKS + ',' + (this._config.target + ' ' + Selector.DROPDOWN_ITEMS); + this._selector = this._config.target + ' ' + Selector.NAV_LINKS + ',' + (this._config.target + ' ' + Selector.LIST_ITEMS + ',') + (this._config.target + ' ' + Selector.DROPDOWN_ITEMS); this._offsets = []; this._targets = []; this._activeTarget = null; this._scrollHeight = 0; $(this._scrollElement).on(Event.SCROLL, function (event) { - return _this18._process(event); + return _this20._process(event); }); this.refresh(); @@ -2262,7 +2427,7 @@ var ScrollSpy = function ($) { // public ScrollSpy.prototype.refresh = function refresh() { - var _this19 = this; + var _this21 = this; var autoMethod = this._scrollElement !== this._scrollElement.window ? OffsetMethod.POSITION : OffsetMethod.OFFSET; @@ -2285,9 +2450,12 @@ var ScrollSpy = function ($) { target = $(targetSelector)[0]; } - if (target && (target.offsetWidth || target.offsetHeight)) { - // todo (fat): remove sketch reliance on jQuery position/offset - return [$(target)[offsetMethod]().top + offsetBase, targetSelector]; + if (target) { + var targetBCR = target.getBoundingClientRect(); + if (targetBCR.width || targetBCR.height) { + // todo (fat): remove sketch reliance on jQuery position/offset + return [$(target)[offsetMethod]().top + offsetBase, targetSelector]; + } } return null; }).filter(function (item) { @@ -2295,8 +2463,8 @@ var ScrollSpy = function ($) { }).sort(function (a, b) { return a[0] - b[0]; }).forEach(function (item) { - _this19._offsets.push(item[0]); - _this19._targets.push(item[1]); + _this21._offsets.push(item[0]); + _this21._targets.push(item[1]); }); }; @@ -2334,7 +2502,7 @@ var ScrollSpy = function ($) { }; ScrollSpy.prototype._getScrollTop = function _getScrollTop() { - return this._scrollElement === window ? this._scrollElement.scrollY : this._scrollElement.scrollTop; + return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop; }; ScrollSpy.prototype._getScrollHeight = function _getScrollHeight() { @@ -2342,7 +2510,7 @@ var ScrollSpy = function ($) { }; ScrollSpy.prototype._getOffsetHeight = function _getOffsetHeight() { - return this._scrollElement === window ? window.innerHeight : this._scrollElement.offsetHeight; + return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height; }; ScrollSpy.prototype._process = function _process() { @@ -2394,9 +2562,11 @@ var ScrollSpy = function ($) { $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE); $link.addClass(ClassName.ACTIVE); } else { - // todo (fat) this is kinda sus... - // recursively add actives to tested nav-links - $link.parents(Selector.LI).find('> ' + Selector.NAV_LINKS).addClass(ClassName.ACTIVE); + // Set triggered link as active + $link.addClass(ClassName.ACTIVE); + // Set triggered links parents as active + // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor + $link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_LINKS + ', ' + Selector.LIST_ITEMS).addClass(ClassName.ACTIVE); } $(this._scrollElement).trigger(Event.ACTIVATE, { @@ -2477,7 +2647,7 @@ var ScrollSpy = function ($) { /** * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-alpha.5): tab.js + * Bootstrap (v4.0.0-alpha.6): tab.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ @@ -2491,7 +2661,7 @@ var Tab = function ($) { */ var NAME = 'tab'; - var VERSION = '4.0.0-alpha.5'; + var VERSION = '4.0.0-alpha.6'; var DATA_KEY = 'bs.tab'; var EVENT_KEY = '.' + DATA_KEY; var DATA_API_KEY = '.data-api'; @@ -2515,14 +2685,10 @@ var Tab = function ($) { }; var Selector = { - A: 'a', - LI: 'li', DROPDOWN: '.dropdown', - LIST: 'ul:not(.dropdown-menu), ol:not(.dropdown-menu)', - FADE_CHILD: '> .nav-item .fade, > .fade', + NAV_LIST_GROUP: '.nav, .list-group', ACTIVE: '.active', - ACTIVE_CHILD: '> .nav-item > .active, > .active', - DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"]', + DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]', DROPDOWN_TOGGLE: '.dropdown-toggle', DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active' }; @@ -2545,7 +2711,7 @@ var Tab = function ($) { // public Tab.prototype.show = function show() { - var _this20 = this; + var _this22 = this; if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $(this._element).hasClass(ClassName.ACTIVE) || $(this._element).hasClass(ClassName.DISABLED)) { return; @@ -2553,7 +2719,7 @@ var Tab = function ($) { var target = void 0; var previous = void 0; - var listElement = $(this._element).closest(Selector.LIST)[0]; + var listElement = $(this._element).closest(Selector.NAV_LIST_GROUP)[0]; var selector = Util.getSelectorFromElement(this._element); if (listElement) { @@ -2587,7 +2753,7 @@ var Tab = function ($) { var complete = function complete() { var hiddenEvent = $.Event(Event.HIDDEN, { - relatedTarget: _this20._element + relatedTarget: _this22._element }); var shownEvent = $.Event(Event.SHOWN, { @@ -2595,7 +2761,7 @@ var Tab = function ($) { }); $(previous).trigger(hiddenEvent); - $(_this20._element).trigger(shownEvent); + $(_this22._element).trigger(shownEvent); }; if (target) { @@ -2606,20 +2772,20 @@ var Tab = function ($) { }; Tab.prototype.dispose = function dispose() { - $.removeClass(this._element, DATA_KEY); + $.removeData(this._element, DATA_KEY); this._element = null; }; // private Tab.prototype._activate = function _activate(element, container, callback) { - var _this21 = this; + var _this23 = this; - var active = $(container).find(Selector.ACTIVE_CHILD)[0]; - var isTransitioning = callback && Util.supportsTransitionEnd() && (active && $(active).hasClass(ClassName.FADE) || Boolean($(container).find(Selector.FADE_CHILD)[0])); + var active = $(container).find(Selector.ACTIVE)[0]; + var isTransitioning = callback && Util.supportsTransitionEnd() && active && $(active).hasClass(ClassName.FADE); var complete = function complete() { - return _this21._transitionComplete(element, active, isTransitioning, callback); + return _this23._transitionComplete(element, active, isTransitioning, callback); }; if (active && isTransitioning) { @@ -2729,11 +2895,11 @@ var Tab = function ($) { return Tab; }(jQuery); -/* global Tether */ +/* global Popper */ /** * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-alpha.5): tooltip.js + * Bootstrap (v4.0.0-alpha.6): tooltip.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ @@ -2741,11 +2907,11 @@ var Tab = function ($) { var Tooltip = function ($) { /** - * Check for Tether dependency - * Tether - http://tether.io/ + * Check for Popper dependency + * Popper - https://popper.js.org */ - if (typeof Tether === 'undefined') { - throw new Error('Bootstrap tooltips require Tether (http://tether.io/)'); + if (typeof Popper === 'undefined') { + throw new Error('Bootstrap tooltips require Popper.js (https://popper.js.org)'); } /** @@ -2755,26 +2921,13 @@ var Tooltip = function ($) { */ var NAME = 'tooltip'; - var VERSION = '4.0.0-alpha.5'; + var VERSION = '4.0.0-alpha.6'; var DATA_KEY = 'bs.tooltip'; var EVENT_KEY = '.' + DATA_KEY; var JQUERY_NO_CONFLICT = $.fn[NAME]; var TRANSITION_DURATION = 150; - var CLASS_PREFIX = 'bs-tether'; - - var Default = { - animation: true, - template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-inner"></div></div>', - trigger: 'hover focus', - title: '', - delay: 0, - html: false, - selector: false, - placement: 'top', - offset: '0 0', - constraints: [], - container: false - }; + var CLASS_PREFIX = 'bs-tooltip'; + var BSCLS_PREFIX_REGEX = new RegExp('(^|\\s)' + CLASS_PREFIX + '\\S+', 'g'); var DefaultType = { animation: 'boolean', @@ -2785,16 +2938,30 @@ var Tooltip = function ($) { html: 'boolean', selector: '(string|boolean)', placement: '(string|function)', - offset: 'string', - constraints: 'array', - container: '(string|element|boolean)' + offset: '(number|string)', + container: '(string|element|boolean)', + fallbackPlacement: '(string|array)' }; var AttachmentMap = { - TOP: 'bottom center', - RIGHT: 'middle left', - BOTTOM: 'top center', - LEFT: 'middle right' + TOP: 'top', + RIGHT: 'right', + BOTTOM: 'bottom', + LEFT: 'left' + }; + + var Default = { + animation: true, + template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + selector: false, + placement: 'top', + offset: 0, + container: false, + fallbackPlacement: 'flip' }; var HoverState = { @@ -2825,11 +2992,6 @@ var Tooltip = function ($) { TOOLTIP_INNER: '.tooltip-inner' }; - var TetherClass = { - element: false, - enabled: false - }; - var Trigger = { HOVER: 'hover', FOCUS: 'focus', @@ -2852,8 +3014,7 @@ var Tooltip = function ($) { this._timeout = 0; this._hoverState = ''; this._activeTrigger = {}; - this._isTransitioning = false; - this._tether = null; + this._popper = null; // protected this.element = element; @@ -2910,8 +3071,6 @@ var Tooltip = function ($) { Tooltip.prototype.dispose = function dispose() { clearTimeout(this._timeout); - this.cleanupTether(); - $.removeData(this.element, this.constructor.DATA_KEY); $(this.element).off(this.constructor.EVENT_KEY); @@ -2925,7 +3084,10 @@ var Tooltip = function ($) { this._timeout = null; this._hoverState = null; this._activeTrigger = null; - this._tether = null; + if (this._popper !== null) { + this._popper.destroy(); + } + this._popper = null; this.element = null; this.config = null; @@ -2933,7 +3095,7 @@ var Tooltip = function ($) { }; Tooltip.prototype.show = function show() { - var _this22 = this; + var _this24 = this; if ($(this.element).css('display') === 'none') { throw new Error('Please use show on visible elements'); @@ -2941,9 +3103,6 @@ var Tooltip = function ($) { var showEvent = $.Event(this.constructor.Event.SHOW); if (this.isWithContent() && this._isEnabled) { - if (this._isTransitioning) { - throw new Error('Tooltip is transitioning'); - } $(this.element).trigger(showEvent); var isInTheDom = $.contains(this.element.ownerDocument.documentElement, this.element); @@ -2967,68 +3126,86 @@ var Tooltip = function ($) { var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; var attachment = this._getAttachment(placement); + this.addAttachmentClass(attachment); var container = this.config.container === false ? document.body : $(this.config.container); - $(tip).data(this.constructor.DATA_KEY, this).appendTo(container); + $(tip).data(this.constructor.DATA_KEY, this); + + if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) { + $(tip).appendTo(container); + } $(this.element).trigger(this.constructor.Event.INSERTED); - this._tether = new Tether({ - attachment: attachment, - element: tip, - target: this.element, - classes: TetherClass, - classPrefix: CLASS_PREFIX, - offset: this.config.offset, - constraints: this.config.constraints, - addTargetClasses: false + this._popper = new Popper(this.element, tip, { + placement: attachment, + modifiers: { + offset: { + offset: this.config.offset + }, + flip: { + behavior: this.config.fallbackPlacement + } + }, + onCreate: function onCreate(data) { + if (data.originalPlacement !== data.placement) { + _this24._handlePopperPlacementChange(data); + } + }, + onUpdate: function onUpdate(data) { + _this24._handlePopperPlacementChange(data); + } }); - Util.reflow(tip); - this._tether.position(); - $(tip).addClass(ClassName.SHOW); + // 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) { + $('body').children().on('mouseover', null, $.noop); + } + var complete = function complete() { - var prevHoverState = _this22._hoverState; - _this22._hoverState = null; - _this22._isTransitioning = false; + if (_this24.config.animation) { + _this24._fixTransition(); + } + var prevHoverState = _this24._hoverState; + _this24._hoverState = null; - $(_this22.element).trigger(_this22.constructor.Event.SHOWN); + $(_this24.element).trigger(_this24.constructor.Event.SHOWN); if (prevHoverState === HoverState.OUT) { - _this22._leave(null, _this22); + _this24._leave(null, _this24); } }; if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) { - this._isTransitioning = true; $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(Tooltip._TRANSITION_DURATION); - return; + } else { + complete(); } - - complete(); } }; Tooltip.prototype.hide = function hide(callback) { - var _this23 = this; + var _this25 = this; var tip = this.getTipElement(); var hideEvent = $.Event(this.constructor.Event.HIDE); - if (this._isTransitioning) { - throw new Error('Tooltip is transitioning'); - } var complete = function complete() { - if (_this23._hoverState !== HoverState.SHOW && tip.parentNode) { + if (_this25._hoverState !== HoverState.SHOW && tip.parentNode) { tip.parentNode.removeChild(tip); } - _this23.element.removeAttribute('aria-describedby'); - $(_this23.element).trigger(_this23.constructor.Event.HIDDEN); - _this23._isTransitioning = false; - _this23.cleanupTether(); + _this25._cleanTipClass(); + _this25.element.removeAttribute('aria-describedby'); + $(_this25.element).trigger(_this25.constructor.Event.HIDDEN); + if (_this25._popper !== null) { + _this25._popper.destroy(); + } if (callback) { callback(); @@ -3043,12 +3220,18 @@ var Tooltip = function ($) { $(tip).removeClass(ClassName.SHOW); + // 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); + } + this._activeTrigger[Trigger.CLICK] = false; this._activeTrigger[Trigger.FOCUS] = false; this._activeTrigger[Trigger.HOVER] = false; if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) { - this._isTransitioning = true; + $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION); } else { complete(); @@ -3057,24 +3240,30 @@ var Tooltip = function ($) { this._hoverState = ''; }; + Tooltip.prototype.update = function update() { + if (this._popper !== null) { + this._popper.scheduleUpdate(); + } + }; + // protected Tooltip.prototype.isWithContent = function isWithContent() { return Boolean(this.getTitle()); }; + Tooltip.prototype.addAttachmentClass = function addAttachmentClass(attachment) { + $(this.getTipElement()).addClass(CLASS_PREFIX + '-' + attachment); + }; + Tooltip.prototype.getTipElement = function getTipElement() { return this.tip = this.tip || $(this.config.template)[0]; }; Tooltip.prototype.setContent = function setContent() { var $tip = $(this.getTipElement()); - this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle()); - $tip.removeClass(ClassName.FADE + ' ' + ClassName.SHOW); - - this.cleanupTether(); }; Tooltip.prototype.setElementContent = function setElementContent($element, content) { @@ -3103,12 +3292,6 @@ var Tooltip = function ($) { return title; }; - Tooltip.prototype.cleanupTether = function cleanupTether() { - if (this._tether) { - this._tether.destroy(); - } - }; - // private Tooltip.prototype._getAttachment = function _getAttachment(placement) { @@ -3116,28 +3299,28 @@ var Tooltip = function ($) { }; Tooltip.prototype._setListeners = function _setListeners() { - var _this24 = this; + var _this26 = this; var triggers = this.config.trigger.split(' '); triggers.forEach(function (trigger) { if (trigger === 'click') { - $(_this24.element).on(_this24.constructor.Event.CLICK, _this24.config.selector, function (event) { - return _this24.toggle(event); + $(_this26.element).on(_this26.constructor.Event.CLICK, _this26.config.selector, function (event) { + return _this26.toggle(event); }); } else if (trigger !== Trigger.MANUAL) { - var eventIn = trigger === Trigger.HOVER ? _this24.constructor.Event.MOUSEENTER : _this24.constructor.Event.FOCUSIN; - var eventOut = trigger === Trigger.HOVER ? _this24.constructor.Event.MOUSELEAVE : _this24.constructor.Event.FOCUSOUT; + var eventIn = trigger === Trigger.HOVER ? _this26.constructor.Event.MOUSEENTER : _this26.constructor.Event.FOCUSIN; + var eventOut = trigger === Trigger.HOVER ? _this26.constructor.Event.MOUSELEAVE : _this26.constructor.Event.FOCUSOUT; - $(_this24.element).on(eventIn, _this24.config.selector, function (event) { - return _this24._enter(event); - }).on(eventOut, _this24.config.selector, function (event) { - return _this24._leave(event); + $(_this26.element).on(eventIn, _this26.config.selector, function (event) { + return _this26._enter(event); + }).on(eventOut, _this26.config.selector, function (event) { + return _this26._leave(event); }); } - $(_this24.element).closest('.modal').on('hide.bs.modal', function () { - return _this24.hide(); + $(_this26.element).closest('.modal').on('hide.bs.modal', function () { + return _this26.hide(); }); }); @@ -3248,6 +3431,14 @@ var Tooltip = function ($) { }; } + if (config.title && typeof config.title === 'number') { + config.title = config.title.toString(); + } + + if (config.content && typeof config.content === 'number') { + config.content = config.content.toString(); + } + Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); return config; @@ -3267,6 +3458,32 @@ var Tooltip = function ($) { return config; }; + Tooltip.prototype._cleanTipClass = function _cleanTipClass() { + var $tip = $(this.getTipElement()); + var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); + if (tabClass !== null && tabClass.length > 0) { + $tip.removeClass(tabClass.join('')); + } + }; + + Tooltip.prototype._handlePopperPlacementChange = function _handlePopperPlacementChange(data) { + this._cleanTipClass(); + this.addAttachmentClass(this._getAttachment(data.placement)); + }; + + Tooltip.prototype._fixTransition = function _fixTransition() { + var tip = this.getTipElement(); + var initConfigAnimation = this.config.animation; + if (tip.getAttribute('x-placement') !== null) { + return; + } + $(tip).removeClass(ClassName.FADE); + this.config.animation = false; + this.hide(); + this.show(); + this.config.animation = initConfigAnimation; + }; + // static Tooltip._jQueryInterface = function _jQueryInterface(config) { @@ -3350,7 +3567,7 @@ var Tooltip = function ($) { /** * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0-alpha.5): popover.js + * Bootstrap (v4.0.0-alpha.6): popover.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ @@ -3364,16 +3581,18 @@ var Popover = function ($) { */ var NAME = 'popover'; - var VERSION = '4.0.0-alpha.5'; + var VERSION = '4.0.0-alpha.6'; var DATA_KEY = 'bs.popover'; var EVENT_KEY = '.' + DATA_KEY; var JQUERY_NO_CONFLICT = $.fn[NAME]; + var CLASS_PREFIX = 'bs-popover'; + var BSCLS_PREFIX_REGEX = new RegExp('(^|\\s)' + CLASS_PREFIX + '\\S+', 'g'); var Default = $.extend({}, Tooltip.Default, { placement: 'right', trigger: 'click', content: '', - template: '<div class="popover" role="tooltip">' + '<h3 class="popover-title"></h3>' + '<div class="popover-content"></div></div>' + template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-title"></h3>' + '<div class="popover-content"></div></div>' }); var DefaultType = $.extend({}, Tooltip.DefaultType, { @@ -3424,6 +3643,10 @@ var Popover = function ($) { return this.getTitle() || this._getContent(); }; + Popover.prototype.addAttachmentClass = function addAttachmentClass(attachment) { + $(this.getTipElement()).addClass(CLASS_PREFIX + '-' + attachment); + }; + Popover.prototype.getTipElement = function getTipElement() { return this.tip = this.tip || $(this.config.template)[0]; }; @@ -3436,8 +3659,6 @@ var Popover = function ($) { this.setElementContent($tip.find(Selector.CONTENT), this._getContent()); $tip.removeClass(ClassName.FADE + ' ' + ClassName.SHOW); - - this.cleanupTether(); }; // private @@ -3446,6 +3667,14 @@ var Popover = function ($) { return this.element.getAttribute('data-content') || (typeof this.config.content === 'function' ? this.config.content.call(this.element) : this.config.content); }; + Popover.prototype._cleanTipClass = function _cleanTipClass() { + var $tip = $(this.getTipElement()); + var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); + if (tabClass !== null && tabClass.length > 0) { + $tip.removeClass(tabClass.join('')); + } + }; + // static Popover._jQueryInterface = function _jQueryInterface(config) { @@ -3531,4 +3760,5 @@ var Popover = function ($) { return Popover; }(jQuery); -}(); + +})()
\ No newline at end of file |
