diff options
| author | fat <[email protected]> | 2015-05-10 19:45:38 -0700 |
|---|---|---|
| committer | fat <[email protected]> | 2015-05-10 19:45:38 -0700 |
| commit | ca9c850ebbfc880dc5021b451ffc9fa12184ff87 (patch) | |
| tree | 8db34e73d402c3f71fd2e8c853b7fddf6cee33d6 /js/src | |
| parent | bbb97a8660639002e70b1786e595ef9171bfecc6 (diff) | |
| download | bootstrap-ca9c850ebbfc880dc5021b451ffc9fa12184ff87.tar.xz bootstrap-ca9c850ebbfc880dc5021b451ffc9fa12184ff87.zip | |
add getters for Version and Default where applicable
add modal my gawd
Diffstat (limited to 'js/src')
| -rw-r--r-- | js/src/alert.js | 7 | ||||
| -rw-r--r-- | js/src/button.js | 8 | ||||
| -rw-r--r-- | js/src/carousel.js | 15 | ||||
| -rw-r--r-- | js/src/collapse.js | 18 | ||||
| -rw-r--r-- | js/src/dropdown.js | 8 | ||||
| -rw-r--r-- | js/src/modal.js | 492 |
6 files changed, 541 insertions, 7 deletions
diff --git a/js/src/alert.js b/js/src/alert.js index a712154ab..57a59746a 100644 --- a/js/src/alert.js +++ b/js/src/alert.js @@ -53,6 +53,13 @@ const Alert = (($) => { } + // getters + + static get VERSION() { + return VERSION + } + + // public close(element) { diff --git a/js/src/button.js b/js/src/button.js index 0f1dab2af..7520de2f6 100644 --- a/js/src/button.js +++ b/js/src/button.js @@ -52,6 +52,14 @@ const Button = (($) => { this._element = element } + + // getters + + static get VERSION() { + return VERSION + } + + // public toggle() { diff --git a/js/src/carousel.js b/js/src/carousel.js index 08476d666..bce51d7fd 100644 --- a/js/src/carousel.js +++ b/js/src/carousel.js @@ -23,7 +23,7 @@ const Carousel = (($) => { const JQUERY_NO_CONFLICT = $.fn[NAME] const TRANSITION_DURATION = 600 - const Defaults = { + const Default = { interval : 5000, keyboard : true, slide : false, @@ -72,7 +72,6 @@ const Carousel = (($) => { class Carousel { constructor(element, config) { - this._items = null this._interval = null this._activeElement = null @@ -85,7 +84,17 @@ const Carousel = (($) => { this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0] this._addEventListeners() + } + + + // getters + + static get VERSION() { + return VERSION + } + static get Default() { + return Default } @@ -331,7 +340,7 @@ const Carousel = (($) => { static _jQueryInterface(config) { return this.each(function () { let data = $(this).data(DATA_KEY) - let _config = $.extend({}, Defaults, $(this).data()) + let _config = $.extend({}, Default, $(this).data()) if (typeof config === 'object') { $.extend(_config, config) diff --git a/js/src/collapse.js b/js/src/collapse.js index 00ae29097..ac506b86b 100644 --- a/js/src/collapse.js +++ b/js/src/collapse.js @@ -23,7 +23,7 @@ const Collapse = (($) => { const JQUERY_NO_CONFLICT = $.fn[NAME] const TRANSITION_DURATION = 600 - const Defaults = { + const Default = { toggle : true, parent : null } @@ -63,10 +63,9 @@ const Collapse = (($) => { class Collapse { constructor(element, config) { - this._isTransitioning = false this._element = element - this._config = $.extend({}, Defaults, config) + this._config = $.extend({}, Default, config) this._triggerArray = $.makeArray($( `[data-toggle="collapse"][href="#${element.id}"],` + `[data-toggle="collapse"][data-target="#${element.id}"]` @@ -81,9 +80,20 @@ const Collapse = (($) => { if (this._config.toggle) { this.toggle() } + } + + + // getters + static get VERSION() { + return VERSION } + static get Default() { + return Default + } + + // public toggle() { @@ -284,7 +294,7 @@ const Collapse = (($) => { let data = $this.data(DATA_KEY) let _config = $.extend( {}, - Defaults, + Default, $this.data(), typeof config === 'object' && config ) diff --git a/js/src/dropdown.js b/js/src/dropdown.js index c5e29d8f1..3135ca73a 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -62,6 +62,14 @@ const Dropdown = (($) => { $(element).on(Event.CLICK, this.toggle) } + + // getters + + static get VERSION() { + return VERSION + } + + // public toggle() { diff --git a/js/src/modal.js b/js/src/modal.js new file mode 100644 index 000000000..b2e8fd77f --- /dev/null +++ b/js/src/modal.js @@ -0,0 +1,492 @@ +import Util from './util' + + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0): modal.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const Modal = (($) => { + + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + const NAME = 'modal' + const VERSION = '4.0.0' + const DATA_KEY = 'bs.modal' + const JQUERY_NO_CONFLICT = $.fn[NAME] + const TRANSITION_DURATION = 300 + const BACKDROP_TRANSITION_DURATION = 150 + + const Default = { + backdrop : true, + keyboard : true, + show : true + } + + const Event = { + HIDE : 'hide.bs.modal', + HIDDEN : 'hidden.bs.modal', + SHOW : 'show.bs.modal', + SHOWN : 'shown.bs.modal', + DISMISS : 'click.dismiss.bs.modal', + KEYDOWN : 'keydown.dismiss.bs.modal', + FOCUSIN : 'focusin.bs.modal', + RESIZE : 'resize.bs.modal', + CLICK : 'click.bs.modal.data-api', + MOUSEDOWN : 'mousedown.dismiss.bs.modal', + MOUSEUP : 'mouseup.dismiss.bs.modal' + } + + const ClassName = { + BACKDROP : 'modal-backdrop', + OPEN : 'modal-open', + FADE : 'fade', + IN : 'in' + } + + const Selector = { + DIALOG : '.modal-dialog', + DATA_TOGGLE : '[data-toggle="modal"]', + DATA_DISMISS : '[data-dismiss="modal"]', + SCROLLBAR_MEASURER : 'modal-scrollbar-measure' + } + + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + class Modal { + + constructor(element, config) { + this._config = config + this._element = element + this._dialog = $(element).find(Selector.DIALOG)[0] + this._backdrop = null + this._isShown = false + this._isBodyOverflowing = false + this._ignoreBackdropClick = false + this._originalBodyPadding = 0 + this._scrollbarWidth = 0 + } + + + // getters + + static get VERSION() { + return VERSION + } + + static get Default() { + return Default + } + + + // public + + toggle(relatedTarget) { + return this._isShown ? this.hide() : this.show(relatedTarget) + } + + show(relatedTarget) { + let showEvent = $.Event(Event.SHOW, { + relatedTarget: relatedTarget + }) + + $(this._element).trigger(showEvent) + + if (this._isShown || showEvent.isDefaultPrevented()) { + return + } + + this._isShown = true + + this._checkScrollbar() + this._setScrollbar() + + $(document.body).addClass(ClassName.OPEN) + + this._setEscapeEvent() + this._setResizeEvent() + + $(this._element).on( + Event.DISMISS, + Selector.DATA_DISMISS, + this.hide.bind(this) + ) + + $(this._dialog).on(Event.MOUSEDOWN, () => { + $(this._element).one(Event.MOUSEUP, (event) => { + if ($(event.target).is(this._element)) { + that._ignoreBackdropClick = true + } + }) + }) + + this._showBackdrop( + this._showElement.bind(this, relatedTarget) + ) + } + + hide(event) { + if (event) { + event.preventDefault() + } + + let hideEvent = $.Event(Event.HIDE) + + $(this._element).trigger(hideEvent) + + if (!this._isShown || hideEvent.isDefaultPrevented()) { + return + } + + this._isShown = false + + this._setEscapeEvent() + this._setResizeEvent() + + $(document).off(Event.FOCUSIN) + + $(this._element).removeClass(ClassName.IN) + + $(this._element).off(Event.DISMISS) + $(this._dialog).off(Event.MOUSEDOWN) + + if (Util.supportsTransitionEnd() && + ($(this._element).hasClass(ClassName.FADE))) { + + $(this._element) + .one(Util.TRANSITION_END, this._hideModal.bind(this)) + .emulateTransitionEnd(TRANSITION_DURATION) + } else { + this._hideModal() + } + } + + + // private + + _showElement(relatedTarget) { + let transition = Util.supportsTransitionEnd() && + $(this._element).hasClass(ClassName.FADE) + + if (!this._element.parentNode || + (this._element.parentNode.nodeType !== Node.ELEMENT_NODE)) { + // don't move modals dom position + document.body.appendChild(this._element) + } + + this._element.style.display = 'block' + this._element.scrollTop = 0 + + if (transition) { + Util.reflow(this._element) + } + + $(this._element).addClass(ClassName.IN) + + this._enforceFocus() + + let shownEvent = $.Event(Event.SHOWN, { + relatedTarget: relatedTarget + }) + + let transitionComplete = () => { + this._element.focus() + $(this._element).trigger(shownEvent) + } + + if (transition) { + $(this._dialog) + .one(Util.TRANSITION_END, transitionComplete) + .emulateTransitionEnd(TRANSITION_DURATION) + } else { + transitionComplete() + } + } + + _enforceFocus() { + $(document) + .off(Event.FOCUSIN) // guard against infinite focus loop + .on(Event.FOCUSIN, (event) => { + if (this._element !== event.target && + (!$(this._element).has(event.target).length)) { + this._element.focus() + } + }) + } + + _setEscapeEvent() { + if (this._isShown && this._config.keyboard) { + $(this._element).on(Event.KEYDOWN, (event) => { + if (event.which === 27) { + this.hide() + } + }) + + } else if (!this._isShown) { + $(this._element).off(Event.KEYDOWN) + } + } + + _setResizeEvent() { + if (this._isShown) { + $(window).on(Event.RESIZE, this._handleUpdate.bind(this)) + } else { + $(window).off(Event.RESIZE) + } + } + + _hideModal() { + this._element.style.display = 'none' + this._showBackdrop(() => { + $(document.body).removeClass(ClassName.OPEN) + this._resetAdjustments() + this._resetScrollbar() + $(this._element).trigger(Event.HIDDEN) + }) + } + + _removeBackdrop() { + if (this._backdrop) { + $(this._backdrop).remove() + this._backdrop = null + } + } + + _showBackdrop(callback) { + let animate = $(this._element).hasClass(ClassName.FADE) ? + ClassName.FADE : '' + + if (this._isShown && this._config.backdrop) { + let doAnimate = Util.supportsTransitionEnd() && animate + + this._backdrop = document.createElement('div') + this._backdrop.className = ClassName.BACKDROP + + if (animate) { + $(this._backdrop).addClass(animate) + } + + $(this._backdrop).appendTo(this.$body) + + $(this._element).on(Event.DISMISS, (event) => { + if (this._ignoreBackdropClick) { + this._ignoreBackdropClick = false + return + } + if (event.target !== event.currentTarget) { + return + } + if (this._config.backdrop === 'static') { + this._element.focus() + } else { + this.hide() + } + }) + + if (doAnimate) { + Util.reflow(this._backdrop) + } + + $(this._backdrop).addClass(ClassName.IN) + + if (!callback) { + return + } + + if (!doAnimate) { + callback() + return + } + + $(this._backdrop) + .one(Util.TRANSITION_END, callback) + .emulateTransitionEnd(BACKDROP_TRANSITION_DURATION) + + } else if (!this._isShown && this._backdrop) { + $(this._backdrop).removeClass(ClassName.IN) + + let callbackRemove = () => { + this._removeBackdrop() + if (callback) { + callback() + } + } + + if (Util.supportsTransitionEnd() && + ($(this._element).hasClass(ClassName.FADE))) { + $(this._backdrop) + .one(Util.TRANSITION_END, callbackRemove) + .emulateTransitionEnd(BACKDROP_TRANSITION_DURATION) + } else { + callbackRemove() + } + + } else if (callback) { + callback() + } + } + + + // ---------------------------------------------------------------------- + // the following methods are used to handle overflowing modals + // todo (fat): these should probably be refactored out of modal.js + // ---------------------------------------------------------------------- + + _handleUpdate() { + this._adjustDialog() + } + + _adjustDialog() { + let isModalOverflowing = + this._element.scrollHeight > document.documentElement.clientHeight + + if (!this._isBodyOverflowing && isModalOverflowing) { + this._element.style.paddingLeft = this._scrollbarWidth + 'px' + } + + if (this._isBodyOverflowing && !isModalOverflowing) { + this._element.style.paddingRight = this._scrollbarWidth + 'px' + } + } + + _resetAdjustments() { + this._element.style.paddingLeft = '' + this._element.style.paddingRight = '' + } + + _checkScrollbar() { + let fullWindowWidth = window.innerWidth + if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 + let documentElementRect = document.documentElement.getBoundingClientRect() + fullWindowWidth = + documentElementRect.right - Math.abs(documentElementRect.left) + } + this._isBodyOverflowing = document.body.clientWidth < fullWindowWidth + this._scrollbarWidth = this._getScrollbarWidth() + } + + _setScrollbar() { + let bodyPadding = parseInt( + $(document.body).css('padding-right') || 0, + 10 + ) + + this._originalBodyPadding = document.body.style.paddingRight || '' + + if (this._isBodyOverflowing) { + document.body.style.paddingRight = + bodyPadding + this._scrollbarWidth + 'px' + } + } + + _resetScrollbar() { + document.body.style.paddingRight = this._originalBodyPadding + } + + _getScrollbarWidth() { // thx d.walsh + let scrollDiv = document.createElement('div') + scrollDiv.className = Selector.SCROLLBAR_MEASURER + document.body.appendChild(scrollDiv) + let scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + document.body.removeChild(scrollDiv) + return scrollbarWidth + } + + + // static + + static _jQueryInterface(config, relatedTarget) { + return this.each(function () { + let data = $(this).data(DATA_KEY) + let _config = $.extend( + {}, + Modal.Default, + $(this).data(), + typeof config === 'object' && config + ) + + if (!data) { + data = new Modal(this, _config) + $(this).data(DATA_KEY, data) + } + + if (typeof config === 'string') { + data[config](relatedTarget) + + } else if (_config.show) { + data.show(relatedTarget) + } + }) + } + + } + + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + $(document).on(Event.CLICK, Selector.DATA_TOGGLE, function (event) { + let target + let selector = Util.getSelectorFromElement(this) + + if (selector) { + target = $(selector)[0] + } + + let config = $(target).data(DATA_KEY) ? + 'toggle' : $.extend({}, $(target).data(), $(this).data()) + + if (this.tagName === 'A') { + event.preventDefault() + } + + let $target = $(target).one(Event.SHOW, (showEvent) => { + if (showEvent.isDefaultPrevented()) { + // only register focus restorer if modal will actually get shown + return + } + + $target.one(Event.HIDDEN, () => { + if ($(this).is(':visible')) { + this.focus() + } + }) + }) + + Modal._jQueryInterface.call($(target), config, this) + }) + + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Modal._jQueryInterface + $.fn[NAME].Constructor = Modal + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Modal._jQueryInterface + } + + return Modal + +})(jQuery) + +export default Modal |
