diff --git a/src/pretix/static/bootstrap/js/bootstrap.js b/src/pretix/static/bootstrap/js/bootstrap.js index 4139b6fc3..170bd608f 100644 --- a/src/pretix/static/bootstrap/js/bootstrap.js +++ b/src/pretix/static/bootstrap/js/bootstrap.js @@ -1,7 +1,7 @@ /*! - * Bootstrap v3.3.2 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * Bootstrap v3.4.1 (https://getbootstrap.com/) + * Copyright 2011-2019 Twitter, Inc. + * Licensed under the MIT license */ if (typeof jQuery === 'undefined') { @@ -11,16 +11,16 @@ if (typeof jQuery === 'undefined') { +function ($) { 'use strict'; var version = $.fn.jquery.split(' ')[0].split('.') - if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) { - throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) { + throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4') } }(jQuery); /* ======================================================================== - * Bootstrap: transition.js v3.3.2 - * http://getbootstrap.com/javascript/#transitions + * Bootstrap: transition.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#transitions * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. + * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ @@ -28,7 +28,7 @@ if (typeof jQuery === 'undefined') { +function ($) { 'use strict'; - // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // CSS TRANSITION SUPPORT (Shoutout: https://modernizr.com/) // ============================================================ function transitionEnd() { @@ -50,7 +50,7 @@ if (typeof jQuery === 'undefined') { return false // explicit for ie8 ( ._.) } - // http://blog.alexmaccaw.com/css-transitions + // https://blog.alexmaccaw.com/css-transitions $.fn.emulateTransitionEnd = function (duration) { var called = false var $el = this @@ -77,10 +77,10 @@ if (typeof jQuery === 'undefined') { }(jQuery); /* ======================================================================== - * Bootstrap: alert.js v3.3.2 - * http://getbootstrap.com/javascript/#alerts + * Bootstrap: alert.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#alerts * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. + * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ @@ -96,7 +96,7 @@ if (typeof jQuery === 'undefined') { $(el).on('click', dismiss, this.close) } - Alert.VERSION = '3.3.2' + Alert.VERSION = '3.4.1' Alert.TRANSITION_DURATION = 150 @@ -109,7 +109,8 @@ if (typeof jQuery === 'undefined') { selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } - var $parent = $(selector) + selector = selector === '#' ? [] : selector + var $parent = $(document).find(selector) if (e) e.preventDefault() @@ -172,10 +173,10 @@ if (typeof jQuery === 'undefined') { }(jQuery); /* ======================================================================== - * Bootstrap: button.js v3.3.2 - * http://getbootstrap.com/javascript/#buttons + * Bootstrap: button.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#buttons * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. + * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ @@ -192,7 +193,7 @@ if (typeof jQuery === 'undefined') { this.isLoading = false } - Button.VERSION = '3.3.2' + Button.VERSION = '3.4.1' Button.DEFAULTS = { loadingText: 'loading...' @@ -204,7 +205,7 @@ if (typeof jQuery === 'undefined') { var val = $el.is('input') ? 'val' : 'html' var data = $el.data() - state = state + 'Text' + state += 'Text' if (data.resetText == null) $el.data('resetText', $el[val]()) @@ -214,10 +215,10 @@ if (typeof jQuery === 'undefined') { if (state == 'loadingText') { this.isLoading = true - $el.addClass(d).attr(d, d) + $el.addClass(d).attr(d, d).prop(d, true) } else if (this.isLoading) { this.isLoading = false - $el.removeClass(d).removeAttr(d) + $el.removeClass(d).removeAttr(d).prop(d, false) } }, this), 0) } @@ -229,15 +230,19 @@ if (typeof jQuery === 'undefined') { if ($parent.length) { var $input = this.$element.find('input') if ($input.prop('type') == 'radio') { - if ($input.prop('checked') && this.$element.hasClass('active')) changed = false - else $parent.find('.active').removeClass('active') + if ($input.prop('checked')) changed = false + $parent.find('.active').removeClass('active') + this.$element.addClass('active') + } else if ($input.prop('type') == 'checkbox') { + if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false + this.$element.toggleClass('active') } - if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') + $input.prop('checked', this.$element.hasClass('active')) + if (changed) $input.trigger('change') } else { this.$element.attr('aria-pressed', !this.$element.hasClass('active')) + this.$element.toggleClass('active') } - - if (changed) this.$element.toggleClass('active') } @@ -277,10 +282,15 @@ if (typeof jQuery === 'undefined') { $(document) .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { - var $btn = $(e.target) - if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + var $btn = $(e.target).closest('.btn') Plugin.call($btn, 'toggle') - e.preventDefault() + if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) { + // Prevent double click on radios, and the double selections (so cancellation) on checkboxes + e.preventDefault() + // The target component still receive the focus + if ($btn.is('input,button')) $btn.trigger('focus') + else $btn.find('input:visible,button:visible').first().trigger('focus') + } }) .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) @@ -289,10 +299,10 @@ if (typeof jQuery === 'undefined') { }(jQuery); /* ======================================================================== - * Bootstrap: carousel.js v3.3.2 - * http://getbootstrap.com/javascript/#carousel + * Bootstrap: carousel.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#carousel * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. + * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ @@ -307,10 +317,10 @@ if (typeof jQuery === 'undefined') { this.$element = $(element) this.$indicators = this.$element.find('.carousel-indicators') this.options = options - this.paused = - this.sliding = - this.interval = - this.$active = + this.paused = null + this.sliding = null + this.interval = null + this.$active = null this.$items = null this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) @@ -320,7 +330,7 @@ if (typeof jQuery === 'undefined') { .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) } - Carousel.VERSION = '3.3.2' + Carousel.VERSION = '3.4.1' Carousel.TRANSITION_DURATION = 600 @@ -434,7 +444,9 @@ if (typeof jQuery === 'undefined') { var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" if ($.support.transition && this.$element.hasClass('slide')) { $next.addClass(type) - $next[0].offsetWidth // force reflow + if (typeof $next === 'object' && $next.length) { + $next[0].offsetWidth // force reflow + } $active.addClass(direction) $next.addClass(direction) $active @@ -496,10 +508,17 @@ if (typeof jQuery === 'undefined') { // ================= var clickHandler = function (e) { - var href var $this = $(this) - var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + var href = $this.attr('href') + if (href) { + href = href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + } + + var target = $this.attr('data-target') || href + var $target = $(document).find(target) + if (!$target.hasClass('carousel')) return + var options = $.extend({}, $target.data(), $this.data()) var slideIndex = $this.attr('data-slide-to') if (slideIndex) options.interval = false @@ -527,13 +546,14 @@ if (typeof jQuery === 'undefined') { }(jQuery); /* ======================================================================== - * Bootstrap: collapse.js v3.3.2 - * http://getbootstrap.com/javascript/#collapse + * Bootstrap: collapse.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#collapse * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. + * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +/* jshint latedef: false */ +function ($) { 'use strict'; @@ -544,7 +564,8 @@ if (typeof jQuery === 'undefined') { var Collapse = function (element, options) { this.$element = $(element) this.options = $.extend({}, Collapse.DEFAULTS, options) - this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]') + this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + + '[data-toggle="collapse"][data-target="#' + element.id + '"]') this.transitioning = null if (this.options.parent) { @@ -556,13 +577,12 @@ if (typeof jQuery === 'undefined') { if (this.options.toggle) this.toggle() } - Collapse.VERSION = '3.3.2' + Collapse.VERSION = '3.4.1' Collapse.TRANSITION_DURATION = 350 Collapse.DEFAULTS = { - toggle: true, - trigger: '[data-toggle="collapse"]' + toggle: true } Collapse.prototype.dimension = function () { @@ -664,7 +684,7 @@ if (typeof jQuery === 'undefined') { } Collapse.prototype.getParent = function () { - return $(this.options.parent) + return $(document).find(this.options.parent) .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') .each($.proxy(function (i, element) { var $element = $(element) @@ -687,7 +707,7 @@ if (typeof jQuery === 'undefined') { var target = $trigger.attr('data-target') || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 - return $(target) + return $(document).find(target) } @@ -700,7 +720,7 @@ if (typeof jQuery === 'undefined') { var data = $this.data('bs.collapse') var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) - if (!data && options.toggle && option == 'show') options.toggle = false + if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) if (typeof option == 'string') data[option]() }) @@ -731,7 +751,7 @@ if (typeof jQuery === 'undefined') { var $target = getTargetFromTrigger($this) var data = $target.data('bs.collapse') - var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this }) + var option = data ? 'toggle' : $this.data() Plugin.call($target, option) }) @@ -739,10 +759,10 @@ if (typeof jQuery === 'undefined') { }(jQuery); /* ======================================================================== - * Bootstrap: dropdown.js v3.3.2 - * http://getbootstrap.com/javascript/#dropdowns + * Bootstrap: dropdown.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#dropdowns * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. + * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ @@ -759,7 +779,41 @@ if (typeof jQuery === 'undefined') { $(element).on('click.bs.dropdown', this.toggle) } - Dropdown.VERSION = '3.3.2' + Dropdown.VERSION = '3.4.1' + + function getParent($this) { + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + var $parent = selector !== '#' ? $(document).find(selector) : null + + return $parent && $parent.length ? $parent : $this.parent() + } + + function clearMenus(e) { + if (e && e.which === 3) return + $(backdrop).remove() + $(toggle).each(function () { + var $this = $(this) + var $parent = getParent($this) + var relatedTarget = { relatedTarget: this } + + if (!$parent.hasClass('open')) return + + if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return + + $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this.attr('aria-expanded', 'false') + $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) + }) + } Dropdown.prototype.toggle = function (e) { var $this = $(this) @@ -774,7 +828,10 @@ if (typeof jQuery === 'undefined') { if (!isActive) { if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { // if mobile we use a backdrop because click events don't delegate - $('
').insertAfter($(this)).on('click', clearMenus) + $(document.createElement('div')) + .addClass('dropdown-backdrop') + .insertAfter($(this)) + .on('click', clearMenus) } var relatedTarget = { relatedTarget: this } @@ -788,7 +845,7 @@ if (typeof jQuery === 'undefined') { $parent .toggleClass('open') - .trigger('shown.bs.dropdown', relatedTarget) + .trigger($.Event('shown.bs.dropdown', relatedTarget)) } return false @@ -807,57 +864,25 @@ if (typeof jQuery === 'undefined') { var $parent = getParent($this) var isActive = $parent.hasClass('open') - if ((!isActive && e.which != 27) || (isActive && e.which == 27)) { + if (!isActive && e.which != 27 || isActive && e.which == 27) { if (e.which == 27) $parent.find(toggle).trigger('focus') return $this.trigger('click') } - var desc = ' li:not(.divider):visible a' - var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc) + var desc = ' li:not(.disabled):visible a' + var $items = $parent.find('.dropdown-menu' + desc) if (!$items.length) return var index = $items.index(e.target) - if (e.which == 38 && index > 0) index-- // up - if (e.which == 40 && index < $items.length - 1) index++ // down - if (!~index) index = 0 + if (e.which == 38 && index > 0) index-- // up + if (e.which == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 $items.eq(index).trigger('focus') } - function clearMenus(e) { - if (e && e.which === 3) return - $(backdrop).remove() - $(toggle).each(function () { - var $this = $(this) - var $parent = getParent($this) - var relatedTarget = { relatedTarget: this } - - if (!$parent.hasClass('open')) return - - $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) - - if (e.isDefaultPrevented()) return - - $this.attr('aria-expanded', 'false') - $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget) - }) - } - - function getParent($this) { - var selector = $this.attr('data-target') - - if (!selector) { - selector = $this.attr('href') - selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 - } - - var $parent = selector && $(selector) - - return $parent && $parent.length ? $parent : $this.parent() - } - // DROPDOWN PLUGIN DEFINITION // ========================== @@ -895,16 +920,15 @@ if (typeof jQuery === 'undefined') { .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) - .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown) - .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown) + .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) }(jQuery); /* ======================================================================== - * Bootstrap: modal.js v3.3.2 - * http://getbootstrap.com/javascript/#modals + * Bootstrap: modal.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#modals * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. + * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ @@ -916,12 +940,16 @@ if (typeof jQuery === 'undefined') { // ====================== var Modal = function (element, options) { - this.options = options - this.$body = $(document.body) - this.$element = $(element) - this.$backdrop = - this.isShown = null + this.options = options + this.$body = $(document.body) + this.$element = $(element) + this.$dialog = this.$element.find('.modal-dialog') + this.$backdrop = null + this.isShown = null + this.originalBodyPad = null this.scrollbarWidth = 0 + this.ignoreBackdropClick = false + this.fixedContent = '.navbar-fixed-top, .navbar-fixed-bottom' if (this.options.remote) { this.$element @@ -932,7 +960,7 @@ if (typeof jQuery === 'undefined') { } } - Modal.VERSION = '3.3.2' + Modal.VERSION = '3.4.1' Modal.TRANSITION_DURATION = 300 Modal.BACKDROP_TRANSITION_DURATION = 150 @@ -949,7 +977,7 @@ if (typeof jQuery === 'undefined') { Modal.prototype.show = function (_relatedTarget) { var that = this - var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) this.$element.trigger(e) @@ -966,6 +994,12 @@ if (typeof jQuery === 'undefined') { this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) + this.$dialog.on('mousedown.dismiss.bs.modal', function () { + that.$element.one('mouseup.dismiss.bs.modal', function (e) { + if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true + }) + }) + this.backdrop(function () { var transition = $.support.transition && that.$element.hasClass('fade') @@ -977,23 +1011,20 @@ if (typeof jQuery === 'undefined') { .show() .scrollTop(0) - if (that.options.backdrop) that.adjustBackdrop() that.adjustDialog() if (transition) { that.$element[0].offsetWidth // force reflow } - that.$element - .addClass('in') - .attr('aria-hidden', false) + that.$element.addClass('in') that.enforceFocus() var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) transition ? - that.$element.find('.modal-dialog') // wait for modal to slide in + that.$dialog // wait for modal to slide in .one('bsTransitionEnd', function () { that.$element.trigger('focus').trigger(e) }) @@ -1020,8 +1051,10 @@ if (typeof jQuery === 'undefined') { this.$element .removeClass('in') - .attr('aria-hidden', true) .off('click.dismiss.bs.modal') + .off('mouseup.dismiss.bs.modal') + + this.$dialog.off('mousedown.dismiss.bs.modal') $.support.transition && this.$element.hasClass('fade') ? this.$element @@ -1034,7 +1067,9 @@ if (typeof jQuery === 'undefined') { $(document) .off('focusin.bs.modal') // guard against infinite focus loop .on('focusin.bs.modal', $.proxy(function (e) { - if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { + if (document !== e.target && + this.$element[0] !== e.target && + !this.$element.has(e.target).length) { this.$element.trigger('focus') } }, this)) @@ -1081,14 +1116,20 @@ if (typeof jQuery === 'undefined') { if (this.isShown && this.options.backdrop) { var doAnimate = $.support.transition && animate - this.$backdrop = $('') - .prependTo(this.$element) - .on('click.dismiss.bs.modal', $.proxy(function (e) { - if (e.target !== e.currentTarget) return - this.options.backdrop == 'static' - ? this.$element[0].focus.call(this.$element[0]) - : this.hide.call(this) - }, this)) + this.$backdrop = $(document.createElement('div')) + .addClass('modal-backdrop ' + animate) + .appendTo(this.$body) + + this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { + if (this.ignoreBackdropClick) { + this.ignoreBackdropClick = false + return + } + if (e.target !== e.currentTarget) return + this.options.backdrop == 'static' + ? this.$element[0].focus() + : this.hide() + }, this)) if (doAnimate) this.$backdrop[0].offsetWidth // force reflow @@ -1123,21 +1164,14 @@ if (typeof jQuery === 'undefined') { // these following methods are used to handle overflowing modals Modal.prototype.handleUpdate = function () { - if (this.options.backdrop) this.adjustBackdrop() this.adjustDialog() } - Modal.prototype.adjustBackdrop = function () { - this.$backdrop - .css('height', 0) - .css('height', this.$element[0].scrollHeight) - } - Modal.prototype.adjustDialog = function () { var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight this.$element.css({ - paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' }) } @@ -1150,17 +1184,38 @@ if (typeof jQuery === 'undefined') { } Modal.prototype.checkScrollbar = function () { - this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight + var fullWindowWidth = window.innerWidth + if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 + var documentElementRect = document.documentElement.getBoundingClientRect() + fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) + } + this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth this.scrollbarWidth = this.measureScrollbar() } Modal.prototype.setScrollbar = function () { var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) - if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) + this.originalBodyPad = document.body.style.paddingRight || '' + var scrollbarWidth = this.scrollbarWidth + if (this.bodyIsOverflowing) { + this.$body.css('padding-right', bodyPad + scrollbarWidth) + $(this.fixedContent).each(function (index, element) { + var actualPadding = element.style.paddingRight + var calculatedPadding = $(element).css('padding-right') + $(element) + .data('padding-right', actualPadding) + .css('padding-right', parseFloat(calculatedPadding) + scrollbarWidth + 'px') + }) + } } Modal.prototype.resetScrollbar = function () { - this.$body.css('padding-right', '') + this.$body.css('padding-right', this.originalBodyPad) + $(this.fixedContent).each(function (index, element) { + var padding = $(element).data('padding-right') + $(element).removeData('padding-right') + element.style.paddingRight = padding ? padding : '' + }) } Modal.prototype.measureScrollbar = function () { // thx walsh @@ -1178,8 +1233,8 @@ if (typeof jQuery === 'undefined') { function Plugin(option, _relatedTarget) { return this.each(function () { - var $this = $(this) - var data = $this.data('bs.modal') + var $this = $(this) + var data = $this.data('bs.modal') var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) if (!data) $this.data('bs.modal', (data = new Modal(this, options))) @@ -1190,7 +1245,7 @@ if (typeof jQuery === 'undefined') { var old = $.fn.modal - $.fn.modal = Plugin + $.fn.modal = Plugin $.fn.modal.Constructor = Modal @@ -1207,10 +1262,13 @@ if (typeof jQuery === 'undefined') { // ============== $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { - var $this = $(this) - var href = $this.attr('href') - var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 - var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) + var $this = $(this) + var href = $this.attr('href') + var target = $this.attr('data-target') || + (href && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 + + var $target = $(document).find(target) + var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) if ($this.is('a')) e.preventDefault() @@ -1226,33 +1284,164 @@ if (typeof jQuery === 'undefined') { }(jQuery); /* ======================================================================== - * Bootstrap: tooltip.js v3.3.2 - * http://getbootstrap.com/javascript/#tooltip + * Bootstrap: tooltip.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#tooltip * Inspired by the original jQuery.tipsy by Jason Frame * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. + * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ - +function ($) { 'use strict'; + var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'] + + var uriAttrs = [ + 'background', + 'cite', + 'href', + 'itemtype', + 'longdesc', + 'poster', + 'src', + 'xlink:href' + ] + + var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i + + var DefaultWhitelist = { + // Global attributes allowed on any supplied element below. + '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], + a: ['target', 'href', 'title', 'rel'], + area: [], + b: [], + br: [], + col: [], + code: [], + div: [], + em: [], + hr: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + i: [], + img: ['src', 'alt', 'title', 'width', 'height'], + li: [], + ol: [], + p: [], + pre: [], + s: [], + small: [], + span: [], + sub: [], + sup: [], + strong: [], + u: [], + ul: [] + } + + /** + * A pattern that recognizes a commonly useful subset of URLs that are safe. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi + + /** + * A pattern that matches safe data URLs. Only matches image, video and audio types. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i + + function allowedAttribute(attr, allowedAttributeList) { + var attrName = attr.nodeName.toLowerCase() + + if ($.inArray(attrName, allowedAttributeList) !== -1) { + if ($.inArray(attrName, uriAttrs) !== -1) { + return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)) + } + + return true + } + + var regExp = $(allowedAttributeList).filter(function (index, value) { + return value instanceof RegExp + }) + + // Check if a regular expression validates the attribute. + for (var i = 0, l = regExp.length; i < l; i++) { + if (attrName.match(regExp[i])) { + return true + } + } + + return false + } + + function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) { + if (unsafeHtml.length === 0) { + return unsafeHtml + } + + if (sanitizeFn && typeof sanitizeFn === 'function') { + return sanitizeFn(unsafeHtml) + } + + // IE 8 and below don't support createHTMLDocument + if (!document.implementation || !document.implementation.createHTMLDocument) { + return unsafeHtml + } + + var createdDocument = document.implementation.createHTMLDocument('sanitization') + createdDocument.body.innerHTML = unsafeHtml + + var whitelistKeys = $.map(whiteList, function (el, i) { return i }) + var elements = $(createdDocument.body).find('*') + + for (var i = 0, len = elements.length; i < len; i++) { + var el = elements[i] + var elName = el.nodeName.toLowerCase() + + if ($.inArray(elName, whitelistKeys) === -1) { + el.parentNode.removeChild(el) + + continue + } + + var attributeList = $.map(el.attributes, function (el) { return el }) + var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []) + + for (var j = 0, len2 = attributeList.length; j < len2; j++) { + if (!allowedAttribute(attributeList[j], whitelistedAttributes)) { + el.removeAttribute(attributeList[j].nodeName) + } + } + } + + return createdDocument.body.innerHTML + } + // TOOLTIP PUBLIC CLASS DEFINITION // =============================== var Tooltip = function (element, options) { - this.type = - this.options = - this.enabled = - this.timeout = - this.hoverState = + this.type = null + this.options = null + this.enabled = null + this.timeout = null + this.hoverState = null this.$element = null + this.inState = null this.init('tooltip', element, options) } - Tooltip.VERSION = '3.3.2' + Tooltip.VERSION = '3.4.1' Tooltip.TRANSITION_DURATION = 150 @@ -1269,7 +1458,10 @@ if (typeof jQuery === 'undefined') { viewport: { selector: 'body', padding: 0 - } + }, + sanitize : true, + sanitizeFn : null, + whiteList : DefaultWhitelist } Tooltip.prototype.init = function (type, element, options) { @@ -1277,7 +1469,12 @@ if (typeof jQuery === 'undefined') { this.type = type this.$element = $(element) this.options = this.getOptions(options) - this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) + this.$viewport = this.options.viewport && $(document).find($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) + this.inState = { click: false, hover: false, focus: false } + + if (this.$element[0] instanceof document.constructor && !this.options.selector) { + throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') + } var triggers = this.options.trigger.split(' ') @@ -1305,7 +1502,15 @@ if (typeof jQuery === 'undefined') { } Tooltip.prototype.getOptions = function (options) { - options = $.extend({}, this.getDefaults(), this.$element.data(), options) + var dataAttributes = this.$element.data() + + for (var dataAttr in dataAttributes) { + if (dataAttributes.hasOwnProperty(dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) { + delete dataAttributes[dataAttr] + } + } + + options = $.extend({}, this.getDefaults(), dataAttributes, options) if (options.delay && typeof options.delay == 'number') { options.delay = { @@ -1314,6 +1519,10 @@ if (typeof jQuery === 'undefined') { } } + if (options.sanitize) { + options.template = sanitizeHtml(options.template, options.whiteList, options.sanitizeFn) + } + return options } @@ -1332,16 +1541,20 @@ if (typeof jQuery === 'undefined') { var self = obj instanceof this.constructor ? obj : $(obj.currentTarget).data('bs.' + this.type) - if (self && self.$tip && self.$tip.is(':visible')) { - self.hoverState = 'in' - return - } - if (!self) { self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) $(obj.currentTarget).data('bs.' + this.type, self) } + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true + } + + if (self.tip().hasClass('in') || self.hoverState == 'in') { + self.hoverState = 'in' + return + } + clearTimeout(self.timeout) self.hoverState = 'in' @@ -1353,6 +1566,14 @@ if (typeof jQuery === 'undefined') { }, self.options.delay.show) } + Tooltip.prototype.isInStateTrue = function () { + for (var key in this.inState) { + if (this.inState[key]) return true + } + + return false + } + Tooltip.prototype.leave = function (obj) { var self = obj instanceof this.constructor ? obj : $(obj.currentTarget).data('bs.' + this.type) @@ -1362,6 +1583,12 @@ if (typeof jQuery === 'undefined') { $(obj.currentTarget).data('bs.' + this.type, self) } + if (obj instanceof $.Event) { + self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false + } + + if (self.isInStateTrue()) return + clearTimeout(self.timeout) self.hoverState = 'out' @@ -1407,7 +1634,8 @@ if (typeof jQuery === 'undefined') { .addClass(placement) .data('bs.' + this.type, this) - this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) + this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element) + this.$element.trigger('inserted.bs.' + this.type) var pos = this.getPosition() var actualWidth = $tip[0].offsetWidth @@ -1415,13 +1643,12 @@ if (typeof jQuery === 'undefined') { if (autoPlace) { var orgPlacement = placement - var $container = this.options.container ? $(this.options.container) : this.$element.parent() - var containerDim = this.getPosition($container) + var viewportDim = this.getPosition(this.$viewport) - placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' : - placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' : - placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' : - placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' : + placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : + placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : + placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : + placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : placement $tip @@ -1462,8 +1689,8 @@ if (typeof jQuery === 'undefined') { if (isNaN(marginTop)) marginTop = 0 if (isNaN(marginLeft)) marginLeft = 0 - offset.top = offset.top + marginTop - offset.left = offset.left + marginLeft + offset.top += marginTop + offset.left += marginLeft // $.fn.offset doesn't round pixel values // so we use setOffset directly with our own function B-0 @@ -1499,30 +1726,41 @@ if (typeof jQuery === 'undefined') { this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) } - Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) { + Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { this.arrow() - .css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') - .css(isHorizontal ? 'top' : 'left', '') + .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') + .css(isVertical ? 'top' : 'left', '') } Tooltip.prototype.setContent = function () { var $tip = this.tip() var title = this.getTitle() - $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) + if (this.options.html) { + if (this.options.sanitize) { + title = sanitizeHtml(title, this.options.whiteList, this.options.sanitizeFn) + } + + $tip.find('.tooltip-inner').html(title) + } else { + $tip.find('.tooltip-inner').text(title) + } + $tip.removeClass('fade in top bottom left right') } Tooltip.prototype.hide = function (callback) { var that = this - var $tip = this.tip() + var $tip = $(this.$tip) var e = $.Event('hide.bs.' + this.type) function complete() { if (that.hoverState != 'in') $tip.detach() - that.$element - .removeAttr('aria-describedby') - .trigger('hidden.bs.' + that.type) + if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary. + that.$element + .removeAttr('aria-describedby') + .trigger('hidden.bs.' + that.type) + } callback && callback() } @@ -1532,7 +1770,7 @@ if (typeof jQuery === 'undefined') { $tip.removeClass('in') - $.support.transition && this.$tip.hasClass('fade') ? + $.support.transition && $tip.hasClass('fade') ? $tip .one('bsTransitionEnd', complete) .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : @@ -1545,7 +1783,7 @@ if (typeof jQuery === 'undefined') { Tooltip.prototype.fixTitle = function () { var $e = this.$element - if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') { + if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') } } @@ -1565,7 +1803,10 @@ if (typeof jQuery === 'undefined') { // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) } - var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() + var isSvg = window.SVGElement && el instanceof window.SVGElement + // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. + // See https://github.com/twbs/bootstrap/issues/20280 + var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null @@ -1600,7 +1841,7 @@ if (typeof jQuery === 'undefined') { var rightEdgeOffset = pos.left + viewportPadding + actualWidth if (leftEdgeOffset < viewportDimensions.left) { // left overflow delta.left = viewportDimensions.left - leftEdgeOffset - } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow + } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset } } @@ -1626,7 +1867,13 @@ if (typeof jQuery === 'undefined') { } Tooltip.prototype.tip = function () { - return (this.$tip = this.$tip || $(this.options.template)) + if (!this.$tip) { + this.$tip = $(this.options.template) + if (this.$tip.length != 1) { + throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') + } + } + return this.$tip } Tooltip.prototype.arrow = function () { @@ -1655,7 +1902,13 @@ if (typeof jQuery === 'undefined') { } } - self.tip().hasClass('in') ? self.leave(self) : self.enter(self) + if (e) { + self.inState.click = !self.inState.click + if (self.isInStateTrue()) self.enter(self) + else self.leave(self) + } else { + self.tip().hasClass('in') ? self.leave(self) : self.enter(self) + } } Tooltip.prototype.destroy = function () { @@ -1663,9 +1916,19 @@ if (typeof jQuery === 'undefined') { clearTimeout(this.timeout) this.hide(function () { that.$element.off('.' + that.type).removeData('bs.' + that.type) + if (that.$tip) { + that.$tip.detach() + } + that.$tip = null + that.$arrow = null + that.$viewport = null + that.$element = null }) } + Tooltip.prototype.sanitizeHtml = function (unsafeHtml) { + return sanitizeHtml(unsafeHtml, this.options.whiteList, this.options.sanitizeFn) + } // TOOLTIP PLUGIN DEFINITION // ========================= @@ -1676,7 +1939,7 @@ if (typeof jQuery === 'undefined') { var data = $this.data('bs.tooltip') var options = typeof option == 'object' && option - if (!data && option == 'destroy') return + if (!data && /destroy|hide/.test(option)) return if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) if (typeof option == 'string') data[option]() }) @@ -1699,10 +1962,10 @@ if (typeof jQuery === 'undefined') { }(jQuery); /* ======================================================================== - * Bootstrap: popover.js v3.3.2 - * http://getbootstrap.com/javascript/#popovers + * Bootstrap: popover.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#popovers * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. + * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ @@ -1719,7 +1982,7 @@ if (typeof jQuery === 'undefined') { if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') - Popover.VERSION = '3.3.2' + Popover.VERSION = '3.4.1' Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { placement: 'right', @@ -1745,10 +2008,25 @@ if (typeof jQuery === 'undefined') { var title = this.getTitle() var content = this.getContent() - $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) - $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events - this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' - ](content) + if (this.options.html) { + var typeContent = typeof content + + if (this.options.sanitize) { + title = this.sanitizeHtml(title) + + if (typeContent === 'string') { + content = this.sanitizeHtml(content) + } + } + + $tip.find('.popover-title').html(title) + $tip.find('.popover-content').children().detach().end()[ + typeContent === 'string' ? 'html' : 'append' + ](content) + } else { + $tip.find('.popover-title').text(title) + $tip.find('.popover-content').children().detach().end().text(content) + } $tip.removeClass('fade top bottom left right in') @@ -1767,19 +2045,14 @@ if (typeof jQuery === 'undefined') { return $e.attr('data-content') || (typeof o.content == 'function' ? - o.content.call($e[0]) : - o.content) + o.content.call($e[0]) : + o.content) } Popover.prototype.arrow = function () { return (this.$arrow = this.$arrow || this.tip().find('.arrow')) } - Popover.prototype.tip = function () { - if (!this.$tip) this.$tip = $(this.options.template) - return this.$tip - } - // POPOVER PLUGIN DEFINITION // ========================= @@ -1790,7 +2063,7 @@ if (typeof jQuery === 'undefined') { var data = $this.data('bs.popover') var options = typeof option == 'object' && option - if (!data && option == 'destroy') return + if (!data && /destroy|hide/.test(option)) return if (!data) $this.data('bs.popover', (data = new Popover(this, options))) if (typeof option == 'string') data[option]() }) @@ -1813,10 +2086,10 @@ if (typeof jQuery === 'undefined') { }(jQuery); /* ======================================================================== - * Bootstrap: scrollspy.js v3.3.2 - * http://getbootstrap.com/javascript/#scrollspy + * Bootstrap: scrollspy.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#scrollspy * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. + * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ @@ -1828,10 +2101,8 @@ if (typeof jQuery === 'undefined') { // ========================== function ScrollSpy(element, options) { - var process = $.proxy(this.process, this) - - this.$body = $('body') - this.$scrollElement = $(element).is('body') ? $(window) : $(element) + this.$body = $(document.body) + this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) this.options = $.extend({}, ScrollSpy.DEFAULTS, options) this.selector = (this.options.target || '') + ' .nav li > a' this.offsets = [] @@ -1839,12 +2110,12 @@ if (typeof jQuery === 'undefined') { this.activeTarget = null this.scrollHeight = 0 - this.$scrollElement.on('scroll.bs.scrollspy', process) + this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) this.refresh() this.process() } - ScrollSpy.VERSION = '3.3.2' + ScrollSpy.VERSION = '3.4.1' ScrollSpy.DEFAULTS = { offset: 10 @@ -1855,20 +2126,19 @@ if (typeof jQuery === 'undefined') { } ScrollSpy.prototype.refresh = function () { - var offsetMethod = 'offset' - var offsetBase = 0 + var that = this + var offsetMethod = 'offset' + var offsetBase = 0 + + this.offsets = [] + this.targets = [] + this.scrollHeight = this.getScrollHeight() if (!$.isWindow(this.$scrollElement[0])) { offsetMethod = 'position' offsetBase = this.$scrollElement.scrollTop() } - this.offsets = [] - this.targets = [] - this.scrollHeight = this.getScrollHeight() - - var self = this - this.$body .find(this.selector) .map(function () { @@ -1883,8 +2153,8 @@ if (typeof jQuery === 'undefined') { }) .sort(function (a, b) { return a[0] - b[0] }) .each(function () { - self.offsets.push(this[0]) - self.targets.push(this[1]) + that.offsets.push(this[0]) + that.targets.push(this[1]) }) } @@ -1913,7 +2183,7 @@ if (typeof jQuery === 'undefined') { for (i = offsets.length; i--;) { activeTarget != targets[i] && scrollTop >= offsets[i] - && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) + && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) && this.activate(targets[i]) } } @@ -1924,8 +2194,8 @@ if (typeof jQuery === 'undefined') { this.clear() var selector = this.selector + - '[data-target="' + target + '"],' + - this.selector + '[href="' + target + '"]' + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' var active = $(selector) .parents('li') @@ -1989,10 +2259,10 @@ if (typeof jQuery === 'undefined') { }(jQuery); /* ======================================================================== - * Bootstrap: tab.js v3.3.2 - * http://getbootstrap.com/javascript/#tabs + * Bootstrap: tab.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#tabs * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. + * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ @@ -2004,10 +2274,12 @@ if (typeof jQuery === 'undefined') { // ==================== var Tab = function (element) { + // jscs:disable requireDollarBeforejQueryAssignment this.element = $(element) + // jscs:enable requireDollarBeforejQueryAssignment } - Tab.VERSION = '3.3.2' + Tab.VERSION = '3.4.1' Tab.TRANSITION_DURATION = 150 @@ -2036,7 +2308,7 @@ if (typeof jQuery === 'undefined') { if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return - var $target = $(selector) + var $target = $(document).find(selector) this.activate($this.closest('li'), $ul) this.activate($target, $target.parent(), function () { @@ -2055,21 +2327,21 @@ if (typeof jQuery === 'undefined') { var $active = container.find('> .active') var transition = callback && $.support.transition - && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length) + && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) function next() { $active .removeClass('active') .find('> .dropdown-menu > .active') - .removeClass('active') + .removeClass('active') .end() .find('[data-toggle="tab"]') - .attr('aria-expanded', false) + .attr('aria-expanded', false) element .addClass('active') .find('[data-toggle="tab"]') - .attr('aria-expanded', true) + .attr('aria-expanded', true) if (transition) { element[0].offsetWidth // reflow for transition @@ -2078,13 +2350,13 @@ if (typeof jQuery === 'undefined') { element.removeClass('fade') } - if (element.parent('.dropdown-menu')) { + if (element.parent('.dropdown-menu').length) { element .closest('li.dropdown') - .addClass('active') + .addClass('active') .end() .find('[data-toggle="tab"]') - .attr('aria-expanded', true) + .attr('aria-expanded', true) } callback && callback() @@ -2143,10 +2415,10 @@ if (typeof jQuery === 'undefined') { }(jQuery); /* ======================================================================== - * Bootstrap: affix.js v3.3.2 - * http://getbootstrap.com/javascript/#affix + * Bootstrap: affix.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#affix * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. + * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ @@ -2160,19 +2432,21 @@ if (typeof jQuery === 'undefined') { var Affix = function (element, options) { this.options = $.extend({}, Affix.DEFAULTS, options) - this.$target = $(this.options.target) + var target = this.options.target === Affix.DEFAULTS.target ? $(this.options.target) : $(document).find(this.options.target) + + this.$target = target .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) this.$element = $(element) - this.affixed = - this.unpin = + this.affixed = null + this.unpin = null this.pinnedOffset = null this.checkPosition() } - Affix.VERSION = '3.3.2' + Affix.VERSION = '3.4.1' Affix.RESET = 'affix affix-top affix-bottom' @@ -2222,7 +2496,7 @@ if (typeof jQuery === 'undefined') { var offset = this.options.offset var offsetTop = offset.top var offsetBottom = offset.bottom - var scrollHeight = $('body').height() + var scrollHeight = Math.max($(document).height(), $(document.body).height()) if (typeof offset != 'object') offsetBottom = offsetTop = offset if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) diff --git a/src/pretix/static/bootstrap/js/bootstrap.min.js b/src/pretix/static/bootstrap/js/bootstrap.min.js index c6d36920b..eb0a8b410 100644 --- a/src/pretix/static/bootstrap/js/bootstrap.min.js +++ b/src/pretix/static/bootstrap/js/bootstrap.min.js @@ -1,7 +1,6 @@ /*! - * Bootstrap v3.3.2 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * Bootstrap v3.4.1 (https://getbootstrap.com/) + * Copyright 2011-2019 Twitter, Inc. + * Licensed under the MIT license */ -if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.2",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.2",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.2",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a(this.options.trigger).filter('[href="#'+b.id+'"], [data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.2",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":a.extend({},e.data(),{trigger:this});c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.2",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.divider):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j