From 85a9d81638d240f3fa9ed01cb139ef33243b379b Mon Sep 17 00:00:00 2001 From: sanjeevi01 Date: Fri, 5 Jul 2019 15:30:52 +0530 Subject: Initial commit --- bootstrap/fonts/js/.jscsrc | 42 + bootstrap/fonts/js/.jshintrc | 15 + bootstrap/fonts/js/affix.js | 164 ++ bootstrap/fonts/js/alert.js | 95 ++ bootstrap/fonts/js/button.js | 125 ++ bootstrap/fonts/js/carousel.js | 246 +++ bootstrap/fonts/js/collapse.js | 212 +++ bootstrap/fonts/js/dropdown.js | 165 ++ bootstrap/fonts/js/modal.js | 358 ++++ bootstrap/fonts/js/popover.js | 123 ++ bootstrap/fonts/js/scrollspy.js | 172 ++ bootstrap/fonts/js/tab.js | 155 ++ bootstrap/fonts/js/tests/README.md | 61 + bootstrap/fonts/js/tests/index.html | 168 ++ bootstrap/fonts/js/tests/unit/.jshintrc | 6 + bootstrap/fonts/js/tests/unit/affix.js | 123 ++ bootstrap/fonts/js/tests/unit/alert.js | 83 + bootstrap/fonts/js/tests/unit/button.js | 168 ++ bootstrap/fonts/js/tests/unit/carousel.js | 718 ++++++++ bootstrap/fonts/js/tests/unit/collapse.js | 447 +++++ bootstrap/fonts/js/tests/unit/dropdown.js | 454 ++++++ bootstrap/fonts/js/tests/unit/modal.js | 466 ++++++ bootstrap/fonts/js/tests/unit/popover.js | 338 ++++ bootstrap/fonts/js/tests/unit/scrollspy.js | 278 ++++ bootstrap/fonts/js/tests/unit/tab.js | 216 +++ bootstrap/fonts/js/tests/unit/tooltip.js | 1709 ++++++++++++++++++++ bootstrap/fonts/js/tests/vendor/jquery.min.js | 5 + .../js/tests/visual/affix-with-sticky-footer.html | 317 ++++ bootstrap/fonts/js/tests/visual/affix.html | 316 ++++ bootstrap/fonts/js/tests/visual/alert.html | 48 + bootstrap/fonts/js/tests/visual/button.html | 79 + bootstrap/fonts/js/tests/visual/carousel.html | 58 + bootstrap/fonts/js/tests/visual/collapse.html | 84 + bootstrap/fonts/js/tests/visual/dropdown.html | 108 ++ bootstrap/fonts/js/tests/visual/modal.html | 208 +++ bootstrap/fonts/js/tests/visual/popover.html | 54 + bootstrap/fonts/js/tests/visual/scrollspy.html | 108 ++ bootstrap/fonts/js/tests/visual/tab.html | 172 ++ bootstrap/fonts/js/tests/visual/tooltip.html | 52 + bootstrap/fonts/js/tooltip.js | 677 ++++++++ bootstrap/fonts/js/transition.js | 59 + 41 files changed, 9452 insertions(+) create mode 100755 bootstrap/fonts/js/.jscsrc create mode 100755 bootstrap/fonts/js/.jshintrc create mode 100755 bootstrap/fonts/js/affix.js create mode 100755 bootstrap/fonts/js/alert.js create mode 100755 bootstrap/fonts/js/button.js create mode 100755 bootstrap/fonts/js/carousel.js create mode 100755 bootstrap/fonts/js/collapse.js create mode 100755 bootstrap/fonts/js/dropdown.js create mode 100755 bootstrap/fonts/js/modal.js create mode 100755 bootstrap/fonts/js/popover.js create mode 100755 bootstrap/fonts/js/scrollspy.js create mode 100755 bootstrap/fonts/js/tab.js create mode 100755 bootstrap/fonts/js/tests/README.md create mode 100755 bootstrap/fonts/js/tests/index.html create mode 100755 bootstrap/fonts/js/tests/unit/.jshintrc create mode 100755 bootstrap/fonts/js/tests/unit/affix.js create mode 100755 bootstrap/fonts/js/tests/unit/alert.js create mode 100755 bootstrap/fonts/js/tests/unit/button.js create mode 100755 bootstrap/fonts/js/tests/unit/carousel.js create mode 100755 bootstrap/fonts/js/tests/unit/collapse.js create mode 100755 bootstrap/fonts/js/tests/unit/dropdown.js create mode 100755 bootstrap/fonts/js/tests/unit/modal.js create mode 100755 bootstrap/fonts/js/tests/unit/popover.js create mode 100755 bootstrap/fonts/js/tests/unit/scrollspy.js create mode 100755 bootstrap/fonts/js/tests/unit/tab.js create mode 100755 bootstrap/fonts/js/tests/unit/tooltip.js create mode 100755 bootstrap/fonts/js/tests/vendor/jquery.min.js create mode 100755 bootstrap/fonts/js/tests/visual/affix-with-sticky-footer.html create mode 100755 bootstrap/fonts/js/tests/visual/affix.html create mode 100755 bootstrap/fonts/js/tests/visual/alert.html create mode 100755 bootstrap/fonts/js/tests/visual/button.html create mode 100755 bootstrap/fonts/js/tests/visual/carousel.html create mode 100755 bootstrap/fonts/js/tests/visual/collapse.html create mode 100755 bootstrap/fonts/js/tests/visual/dropdown.html create mode 100755 bootstrap/fonts/js/tests/visual/modal.html create mode 100755 bootstrap/fonts/js/tests/visual/popover.html create mode 100755 bootstrap/fonts/js/tests/visual/scrollspy.html create mode 100755 bootstrap/fonts/js/tests/visual/tab.html create mode 100755 bootstrap/fonts/js/tests/visual/tooltip.html create mode 100755 bootstrap/fonts/js/tooltip.js create mode 100755 bootstrap/fonts/js/transition.js (limited to 'bootstrap/fonts/js') diff --git a/bootstrap/fonts/js/.jscsrc b/bootstrap/fonts/js/.jscsrc new file mode 100755 index 0000000..9544d2d --- /dev/null +++ b/bootstrap/fonts/js/.jscsrc @@ -0,0 +1,42 @@ +{ + "disallowEmptyBlocks": true, + "disallowKeywords": ["with"], + "disallowMixedSpacesAndTabs": true, + "disallowMultipleLineStrings": true, + "disallowMultipleVarDecl": true, + "disallowQuotedKeysInObjects": "allButReserved", + "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], + "disallowSpaceBeforeBinaryOperators": [","], + "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], + "disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true }, + "disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true }, + "disallowSpacesInsideArrayBrackets": true, + "disallowSpacesInsideParentheses": true, + "disallowTrailingComma": true, + "disallowTrailingWhitespace": true, + "requireCamelCaseOrUpperCaseIdentifiers": true, + "requireCapitalizedConstructors": true, + "requireCommaBeforeLineBreak": true, + "requireDollarBeforejQueryAssignment": true, + "requireDotNotation": true, + "requireLineFeedAtFileEnd": true, + "requirePaddingNewLinesAfterUseStrict": true, + "requirePaddingNewLinesBeforeExport": true, + "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="], + "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"], + "requireSpaceAfterLineComment": true, + "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!==", ">", "<", ">=", "<="], + "requireSpaceBetweenArguments": true, + "requireSpacesInAnonymousFunctionExpression": { "beforeOpeningCurlyBrace": true, "beforeOpeningRoundBrace": true }, + "requireSpacesInConditionalExpression": true, + "requireSpacesInForStatement": true, + "requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true }, + "requireSpacesInFunctionExpression": { "beforeOpeningCurlyBrace": true }, + "requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true }, + "requireSpacesInsideObjectBrackets": "allButNested", + "validateAlignedFunctionParameters": true, + "validateIndentation": 2, + "validateLineBreaks": "LF", + "validateNewlineAfterArrayElements": true, + "validateQuoteMarks": "'" +} diff --git a/bootstrap/fonts/js/.jshintrc b/bootstrap/fonts/js/.jshintrc new file mode 100755 index 0000000..a59e1d0 --- /dev/null +++ b/bootstrap/fonts/js/.jshintrc @@ -0,0 +1,15 @@ +{ + "asi" : true, + "browser" : true, + "eqeqeq" : false, + "eqnull" : true, + "es3" : true, + "expr" : true, + "jquery" : true, + "latedef" : true, + "laxbreak" : true, + "nonbsp" : true, + "strict" : true, + "undef" : true, + "unused" : true +} diff --git a/bootstrap/fonts/js/affix.js b/bootstrap/fonts/js/affix.js new file mode 100755 index 0000000..ad62904 --- /dev/null +++ b/bootstrap/fonts/js/affix.js @@ -0,0 +1,164 @@ +/* ======================================================================== + * Bootstrap: affix.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#affix + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // AFFIX CLASS DEFINITION + // ====================== + + var Affix = function (element, options) { + this.options = $.extend({}, Affix.DEFAULTS, options) + + 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 = null + this.unpin = null + this.pinnedOffset = null + + this.checkPosition() + } + + Affix.VERSION = '3.4.1' + + Affix.RESET = 'affix affix-top affix-bottom' + + Affix.DEFAULTS = { + offset: 0, + target: window + } + + Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + var targetHeight = this.$target.height() + + if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false + + if (this.affixed == 'bottom') { + if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' + return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' + } + + var initializing = this.affixed == null + var colliderTop = initializing ? scrollTop : position.top + var colliderHeight = initializing ? targetHeight : height + + if (offsetTop != null && scrollTop <= offsetTop) return 'top' + if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' + + return false + } + + Affix.prototype.getPinnedOffset = function () { + if (this.pinnedOffset) return this.pinnedOffset + this.$element.removeClass(Affix.RESET).addClass('affix') + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + return (this.pinnedOffset = position.top - scrollTop) + } + + Affix.prototype.checkPositionWithEventLoop = function () { + setTimeout($.proxy(this.checkPosition, this), 1) + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var height = this.$element.height() + var offset = this.options.offset + var offsetTop = offset.top + var offsetBottom = offset.bottom + 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) + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) + + var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) + + if (this.affixed != affix) { + if (this.unpin != null) this.$element.css('top', '') + + var affixType = 'affix' + (affix ? '-' + affix : '') + var e = $.Event(affixType + '.bs.affix') + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null + + this.$element + .removeClass(Affix.RESET) + .addClass(affixType) + .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') + } + + if (affix == 'bottom') { + this.$element.offset({ + top: scrollHeight - height - offsetBottom + }) + } + } + + + // AFFIX PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.affix') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.affix + + $.fn.affix = Plugin + $.fn.affix.Constructor = Affix + + + // AFFIX NO CONFLICT + // ================= + + $.fn.affix.noConflict = function () { + $.fn.affix = old + return this + } + + + // AFFIX DATA-API + // ============== + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + var data = $spy.data() + + data.offset = data.offset || {} + + if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom + if (data.offsetTop != null) data.offset.top = data.offsetTop + + Plugin.call($spy, data) + }) + }) + +}(jQuery); diff --git a/bootstrap/fonts/js/alert.js b/bootstrap/fonts/js/alert.js new file mode 100755 index 0000000..7f9606b --- /dev/null +++ b/bootstrap/fonts/js/alert.js @@ -0,0 +1,95 @@ +/* ======================================================================== + * Bootstrap: alert.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#alerts + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // ALERT CLASS DEFINITION + // ====================== + + var dismiss = '[data-dismiss="alert"]' + var Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.VERSION = '3.4.1' + + Alert.TRANSITION_DURATION = 150 + + Alert.prototype.close = function (e) { + var $this = $(this) + var selector = $this.attr('data-target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + selector = selector === '#' ? [] : selector + var $parent = $(document).find(selector) + + if (e) e.preventDefault() + + if (!$parent.length) { + $parent = $this.closest('.alert') + } + + $parent.trigger(e = $.Event('close.bs.alert')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + // detach from parent, fire event then clean up data + $parent.detach().trigger('closed.bs.alert').remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent + .one('bsTransitionEnd', removeElement) + .emulateTransitionEnd(Alert.TRANSITION_DURATION) : + removeElement() + } + + + // ALERT PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.alert') + + if (!data) $this.data('bs.alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.alert + + $.fn.alert = Plugin + $.fn.alert.Constructor = Alert + + + // ALERT NO CONFLICT + // ================= + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + // ALERT DATA-API + // ============== + + $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) + +}(jQuery); diff --git a/bootstrap/fonts/js/button.js b/bootstrap/fonts/js/button.js new file mode 100755 index 0000000..ff4af20 --- /dev/null +++ b/bootstrap/fonts/js/button.js @@ -0,0 +1,125 @@ +/* ======================================================================== + * Bootstrap: button.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#buttons + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // BUTTON PUBLIC CLASS DEFINITION + // ============================== + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Button.DEFAULTS, options) + this.isLoading = false + } + + Button.VERSION = '3.4.1' + + Button.DEFAULTS = { + loadingText: 'loading...' + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + var $el = this.$element + var val = $el.is('input') ? 'val' : 'html' + var data = $el.data() + + state += 'Text' + + if (data.resetText == null) $el.data('resetText', $el[val]()) + + // push to event loop to allow forms to submit + setTimeout($.proxy(function () { + $el[val](data[state] == null ? this.options[state] : data[state]) + + if (state == 'loadingText') { + this.isLoading = true + $el.addClass(d).attr(d, d).prop(d, true) + } else if (this.isLoading) { + this.isLoading = false + $el.removeClass(d).removeAttr(d).prop(d, false) + } + }, this), 0) + } + + Button.prototype.toggle = function () { + var changed = true + var $parent = this.$element.closest('[data-toggle="buttons"]') + + if ($parent.length) { + var $input = this.$element.find('input') + if ($input.prop('type') == 'radio') { + 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') + } + $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') + } + } + + + // BUTTON PLUGIN DEFINITION + // ======================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.button') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.button', (data = new Button(this, options))) + + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + var old = $.fn.button + + $.fn.button = Plugin + $.fn.button.Constructor = Button + + + // BUTTON NO CONFLICT + // ================== + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + // BUTTON DATA-API + // =============== + + $(document) + .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { + var $btn = $(e.target).closest('.btn') + Plugin.call($btn, 'toggle') + 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)) + }) + +}(jQuery); diff --git a/bootstrap/fonts/js/carousel.js b/bootstrap/fonts/js/carousel.js new file mode 100755 index 0000000..a5fcac3 --- /dev/null +++ b/bootstrap/fonts/js/carousel.js @@ -0,0 +1,246 @@ +/* ======================================================================== + * Bootstrap: carousel.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#carousel + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CAROUSEL CLASS DEFINITION + // ========================= + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + 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)) + + this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element + .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) + .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) + } + + Carousel.VERSION = '3.4.1' + + Carousel.TRANSITION_DURATION = 600 + + Carousel.DEFAULTS = { + interval: 5000, + pause: 'hover', + wrap: true, + keyboard: true + } + + Carousel.prototype.keydown = function (e) { + if (/input|textarea/i.test(e.target.tagName)) return + switch (e.which) { + case 37: this.prev(); break + case 39: this.next(); break + default: return + } + + e.preventDefault() + } + + Carousel.prototype.cycle = function (e) { + e || (this.paused = false) + + this.interval && clearInterval(this.interval) + + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + + return this + } + + Carousel.prototype.getItemIndex = function (item) { + this.$items = item.parent().children('.item') + return this.$items.index(item || this.$active) + } + + Carousel.prototype.getItemForDirection = function (direction, active) { + var activeIndex = this.getItemIndex(active) + var willWrap = (direction == 'prev' && activeIndex === 0) + || (direction == 'next' && activeIndex == (this.$items.length - 1)) + if (willWrap && !this.options.wrap) return active + var delta = direction == 'prev' ? -1 : 1 + var itemIndex = (activeIndex + delta) % this.$items.length + return this.$items.eq(itemIndex) + } + + Carousel.prototype.to = function (pos) { + var that = this + var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" + if (activeIndex == pos) return this.pause().cycle() + + return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) + } + + Carousel.prototype.pause = function (e) { + e || (this.paused = true) + + if (this.$element.find('.next, .prev').length && $.support.transition) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + + this.interval = clearInterval(this.interval) + + return this + } + + Carousel.prototype.next = function () { + if (this.sliding) return + return this.slide('next') + } + + Carousel.prototype.prev = function () { + if (this.sliding) return + return this.slide('prev') + } + + Carousel.prototype.slide = function (type, next) { + var $active = this.$element.find('.item.active') + var $next = next || this.getItemForDirection(type, $active) + var isCycling = this.interval + var direction = type == 'next' ? 'left' : 'right' + var that = this + + if ($next.hasClass('active')) return (this.sliding = false) + + var relatedTarget = $next[0] + var slideEvent = $.Event('slide.bs.carousel', { + relatedTarget: relatedTarget, + direction: direction + }) + this.$element.trigger(slideEvent) + if (slideEvent.isDefaultPrevented()) return + + this.sliding = true + + isCycling && this.pause() + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) + $nextIndicator && $nextIndicator.addClass('active') + } + + var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" + if ($.support.transition && this.$element.hasClass('slide')) { + $next.addClass(type) + if (typeof $next === 'object' && $next.length) { + $next[0].offsetWidth // force reflow + } + $active.addClass(direction) + $next.addClass(direction) + $active + .one('bsTransitionEnd', function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { + that.$element.trigger(slidEvent) + }, 0) + }) + .emulateTransitionEnd(Carousel.TRANSITION_DURATION) + } else { + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger(slidEvent) + } + + isCycling && this.cycle() + + return this + } + + + // CAROUSEL PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.carousel') + var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) + var action = typeof option == 'string' ? option : options.slide + + if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + var old = $.fn.carousel + + $.fn.carousel = Plugin + $.fn.carousel.Constructor = Carousel + + + // CAROUSEL NO CONFLICT + // ==================== + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + + // CAROUSEL DATA-API + // ================= + + var clickHandler = function (e) { + var $this = $(this) + 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 + + Plugin.call($target, options) + + if (slideIndex) { + $target.data('bs.carousel').to(slideIndex) + } + + e.preventDefault() + } + + $(document) + .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) + .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) + + $(window).on('load', function () { + $('[data-ride="carousel"]').each(function () { + var $carousel = $(this) + Plugin.call($carousel, $carousel.data()) + }) + }) + +}(jQuery); diff --git a/bootstrap/fonts/js/collapse.js b/bootstrap/fonts/js/collapse.js new file mode 100755 index 0000000..2cd5997 --- /dev/null +++ b/bootstrap/fonts/js/collapse.js @@ -0,0 +1,212 @@ +/* ======================================================================== + * Bootstrap: collapse.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#collapse + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + +/* jshint latedef: false */ + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + + '[data-toggle="collapse"][data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.4.1' + + Collapse.TRANSITION_DURATION = 350 + + Collapse.DEFAULTS = { + toggle: true + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var activesData + var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') + + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return + } + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) + + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) + + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(document).find(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(document).find(target) + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + 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]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $this.data() + + Plugin.call($target, option) + }) + +}(jQuery); diff --git a/bootstrap/fonts/js/dropdown.js b/bootstrap/fonts/js/dropdown.js new file mode 100755 index 0000000..4ded850 --- /dev/null +++ b/bootstrap/fonts/js/dropdown.js @@ -0,0 +1,165 @@ +/* ======================================================================== + * Bootstrap: dropdown.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#dropdowns + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // DROPDOWN CLASS DEFINITION + // ========================= + + var backdrop = '.dropdown-backdrop' + var toggle = '[data-toggle="dropdown"]' + var Dropdown = function (element) { + $(element).on('click.bs.dropdown', this.toggle) + } + + 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) + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { + // if mobile we use a backdrop because click events don't delegate + $(document.createElement('div')) + .addClass('dropdown-backdrop') + .insertAfter($(this)) + .on('click', clearMenus) + } + + var relatedTarget = { relatedTarget: this } + $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) + + if (e.isDefaultPrevented()) return + + $this + .trigger('focus') + .attr('aria-expanded', 'true') + + $parent + .toggleClass('open') + .trigger($.Event('shown.bs.dropdown', relatedTarget)) + } + + return false + } + + Dropdown.prototype.keydown = function (e) { + if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return + + var $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + var $parent = getParent($this) + var isActive = $parent.hasClass('open') + + 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(.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 + + $items.eq(index).trigger('focus') + } + + + // DROPDOWN PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.dropdown') + + if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + var old = $.fn.dropdown + + $.fn.dropdown = Plugin + $.fn.dropdown.Constructor = Dropdown + + + // DROPDOWN NO CONFLICT + // ==================== + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + // APPLY TO STANDARD DROPDOWN ELEMENTS + // =================================== + + $(document) + .on('click.bs.dropdown.data-api', clearMenus) + .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', '.dropdown-menu', Dropdown.prototype.keydown) + +}(jQuery); diff --git a/bootstrap/fonts/js/modal.js b/bootstrap/fonts/js/modal.js new file mode 100755 index 0000000..b9eca49 --- /dev/null +++ b/bootstrap/fonts/js/modal.js @@ -0,0 +1,358 @@ +/* ======================================================================== + * Bootstrap: modal.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#modals + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + 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 + .find('.modal-content') + .load(this.options.remote, $.proxy(function () { + this.$element.trigger('loaded.bs.modal') + }, this)) + } + } + + Modal.VERSION = '3.4.1' + + Modal.TRANSITION_DURATION = 300 + Modal.BACKDROP_TRANSITION_DURATION = 150 + + Modal.DEFAULTS = { + backdrop: true, + keyboard: true, + show: true + } + + Modal.prototype.toggle = function (_relatedTarget) { + return this.isShown ? this.hide() : this.show(_relatedTarget) + } + + Modal.prototype.show = function (_relatedTarget) { + var that = this + var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.checkScrollbar() + this.setScrollbar() + this.$body.addClass('modal-open') + + this.escape() + this.resize() + + 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') + + if (!that.$element.parent().length) { + that.$element.appendTo(that.$body) // don't move modals dom position + } + + that.$element + .show() + .scrollTop(0) + + that.adjustDialog() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element.addClass('in') + + that.enforceFocus() + + var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) + + transition ? + that.$dialog // wait for modal to slide in + .one('bsTransitionEnd', function () { + that.$element.trigger('focus').trigger(e) + }) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + that.$element.trigger('focus').trigger(e) + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + this.resize() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .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 + .one('bsTransitionEnd', $.proxy(this.hideModal, this)) + .emulateTransitionEnd(Modal.TRANSITION_DURATION) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (document !== e.target && + this.$element[0] !== e.target && + !this.$element.has(e.target).length) { + this.$element.trigger('focus') + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keydown.dismiss.bs.modal') + } + } + + Modal.prototype.resize = function () { + if (this.isShown) { + $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) + } else { + $(window).off('resize.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.$body.removeClass('modal-open') + that.resetAdjustments() + that.resetScrollbar() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + 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 + + this.$backdrop.addClass('in') + + if (!callback) return + + doAnimate ? + this.$backdrop + .one('bsTransitionEnd', callback) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callback() + + } else if (!this.isShown && this.$backdrop) { + this.$backdrop.removeClass('in') + + var callbackRemove = function () { + that.removeBackdrop() + callback && callback() + } + $.support.transition && this.$element.hasClass('fade') ? + this.$backdrop + .one('bsTransitionEnd', callbackRemove) + .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : + callbackRemove() + + } else if (callback) { + callback() + } + } + + // these following methods are used to handle overflowing modals + + Modal.prototype.handleUpdate = function () { + this.adjustDialog() + } + + Modal.prototype.adjustDialog = function () { + var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight + + this.$element.css({ + paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', + paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' + }) + } + + Modal.prototype.resetAdjustments = function () { + this.$element.css({ + paddingLeft: '', + paddingRight: '' + }) + } + + Modal.prototype.checkScrollbar = function () { + 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) + 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.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 + var scrollDiv = document.createElement('div') + scrollDiv.className = 'modal-scrollbar-measure' + this.$body.append(scrollDiv) + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth + this.$body[0].removeChild(scrollDiv) + return scrollbarWidth + } + + + // MODAL PLUGIN DEFINITION + // ======================= + + function Plugin(option, _relatedTarget) { + return this.each(function () { + 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))) + if (typeof option == 'string') data[option](_relatedTarget) + else if (options.show) data.show(_relatedTarget) + }) + } + + var old = $.fn.modal + + $.fn.modal = Plugin + $.fn.modal.Constructor = Modal + + + // MODAL NO CONFLICT + // ================= + + $.fn.modal.noConflict = function () { + $.fn.modal = old + return this + } + + + // MODAL DATA-API + // ============== + + $(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 $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() + + $target.one('show.bs.modal', function (showEvent) { + if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown + $target.one('hidden.bs.modal', function () { + $this.is(':visible') && $this.trigger('focus') + }) + }) + Plugin.call($target, option, this) + }) + +}(jQuery); diff --git a/bootstrap/fonts/js/popover.js b/bootstrap/fonts/js/popover.js new file mode 100755 index 0000000..66a301c --- /dev/null +++ b/bootstrap/fonts/js/popover.js @@ -0,0 +1,123 @@ +/* ======================================================================== + * Bootstrap: popover.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#popovers + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // POPOVER PUBLIC CLASS DEFINITION + // =============================== + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') + + Popover.VERSION = '3.4.1' + + Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { + placement: 'right', + trigger: 'click', + content: '', + template: '' + }) + + + // NOTE: POPOVER EXTENDS tooltip.js + // ================================ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) + + Popover.prototype.constructor = Popover + + Popover.prototype.getDefaults = function () { + return Popover.DEFAULTS + } + + Popover.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + var content = this.getContent() + + 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') + + // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do + // this manually by checking the contents. + if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() + } + + Popover.prototype.hasContent = function () { + return this.getTitle() || this.getContent() + } + + Popover.prototype.getContent = function () { + var $e = this.$element + var o = this.options + + return $e.attr('data-content') + || (typeof o.content == 'function' ? + o.content.call($e[0]) : + o.content) + } + + Popover.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.arrow')) + } + + + // POPOVER PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.popover') + var options = typeof option == 'object' && option + + if (!data && /destroy|hide/.test(option)) return + if (!data) $this.data('bs.popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.popover + + $.fn.popover = Plugin + $.fn.popover.Constructor = Popover + + + // POPOVER NO CONFLICT + // =================== + + $.fn.popover.noConflict = function () { + $.fn.popover = old + return this + } + +}(jQuery); diff --git a/bootstrap/fonts/js/scrollspy.js b/bootstrap/fonts/js/scrollspy.js new file mode 100755 index 0000000..a629ac6 --- /dev/null +++ b/bootstrap/fonts/js/scrollspy.js @@ -0,0 +1,172 @@ +/* ======================================================================== + * Bootstrap: scrollspy.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#scrollspy + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // SCROLLSPY CLASS DEFINITION + // ========================== + + function ScrollSpy(element, options) { + 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 = [] + this.targets = [] + this.activeTarget = null + this.scrollHeight = 0 + + this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) + this.refresh() + this.process() + } + + ScrollSpy.VERSION = '3.4.1' + + ScrollSpy.DEFAULTS = { + offset: 10 + } + + ScrollSpy.prototype.getScrollHeight = function () { + return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) + } + + ScrollSpy.prototype.refresh = function () { + 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.$body + .find(this.selector) + .map(function () { + var $el = $(this) + var href = $el.data('target') || $el.attr('href') + var $href = /^#./.test(href) && $(href) + + return ($href + && $href.length + && $href.is(':visible') + && [[$href[offsetMethod]().top + offsetBase, href]]) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + that.offsets.push(this[0]) + that.targets.push(this[1]) + }) + } + + ScrollSpy.prototype.process = function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + var scrollHeight = this.getScrollHeight() + var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() + var offsets = this.offsets + var targets = this.targets + var activeTarget = this.activeTarget + var i + + if (this.scrollHeight != scrollHeight) { + this.refresh() + } + + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) + } + + if (activeTarget && scrollTop < offsets[0]) { + this.activeTarget = null + return this.clear() + } + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) + && this.activate(targets[i]) + } + } + + ScrollSpy.prototype.activate = function (target) { + this.activeTarget = target + + this.clear() + + var selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' + + var active = $(selector) + .parents('li') + .addClass('active') + + if (active.parent('.dropdown-menu').length) { + active = active + .closest('li.dropdown') + .addClass('active') + } + + active.trigger('activate.bs.scrollspy') + } + + ScrollSpy.prototype.clear = function () { + $(this.selector) + .parentsUntil(this.options.target, '.active') + .removeClass('active') + } + + + // SCROLLSPY PLUGIN DEFINITION + // =========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.scrollspy') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.scrollspy + + $.fn.scrollspy = Plugin + $.fn.scrollspy.Constructor = ScrollSpy + + + // SCROLLSPY NO CONFLICT + // ===================== + + $.fn.scrollspy.noConflict = function () { + $.fn.scrollspy = old + return this + } + + + // SCROLLSPY DATA-API + // ================== + + $(window).on('load.bs.scrollspy.data-api', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + Plugin.call($spy, $spy.data()) + }) + }) + +}(jQuery); diff --git a/bootstrap/fonts/js/tab.js b/bootstrap/fonts/js/tab.js new file mode 100755 index 0000000..74495df --- /dev/null +++ b/bootstrap/fonts/js/tab.js @@ -0,0 +1,155 @@ +/* ======================================================================== + * Bootstrap: tab.js v3.4.1 + * https://getbootstrap.com/docs/3.4/javascript/#tabs + * ======================================================================== + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TAB CLASS DEFINITION + // ==================== + + var Tab = function (element) { + // jscs:disable requireDollarBeforejQueryAssignment + this.element = $(element) + // jscs:enable requireDollarBeforejQueryAssignment + } + + Tab.VERSION = '3.4.1' + + Tab.TRANSITION_DURATION = 150 + + Tab.prototype.show = function () { + var $this = this.element + var $ul = $this.closest('ul:not(.dropdown-menu)') + var selector = $this.data('target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + if ($this.parent('li').hasClass('active')) return + + var $previous = $ul.find('.active:last a') + var hideEvent = $.Event('hide.bs.tab', { + relatedTarget: $this[0] + }) + var showEvent = $.Event('show.bs.tab', { + relatedTarget: $previous[0] + }) + + $previous.trigger(hideEvent) + $this.trigger(showEvent) + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + + var $target = $(document).find(selector) + + this.activate($this.closest('li'), $ul) + this.activate($target, $target.parent(), function () { + $previous.trigger({ + type: 'hidden.bs.tab', + relatedTarget: $this[0] + }) + $this.trigger({ + type: 'shown.bs.tab', + relatedTarget: $previous[0] + }) + }) + } + + Tab.prototype.activate = function (element, container, callback) { + var $active = container.find('> .active') + var transition = callback + && $.support.transition + && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', false) + + element + .addClass('active') + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if (element.parent('.dropdown-menu').length) { + element + .closest('li.dropdown') + .addClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + } + + callback && callback() + } + + $active.length && transition ? + $active + .one('bsTransitionEnd', next) + .emulateTransitionEnd(Tab.TRANSITION_DURATION) : + next() + + $active.removeClass('in') + } + + + // TAB PLUGIN DEFINITION + // ===================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tab') + + if (!data) $this.data('bs.tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tab + + $.fn.tab = Plugin + $.fn.tab.Constructor = Tab + + + // TAB NO CONFLICT + // =============== + + $.fn.tab.noConflict = function () { + $.fn.tab = old + return this + } + + + // TAB DATA-API + // ============ + + var clickHandler = function (e) { + e.preventDefault() + Plugin.call($(this), 'show') + } + + $(document) + .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) + .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) + +}(jQuery); diff --git a/bootstrap/fonts/js/tests/README.md b/bootstrap/fonts/js/tests/README.md new file mode 100755 index 0000000..9e3d7cc --- /dev/null +++ b/bootstrap/fonts/js/tests/README.md @@ -0,0 +1,61 @@ +## How does Bootstrap's test suite work? + +Bootstrap uses [QUnit](https://api.qunitjs.com/), a powerful, easy-to-use JavaScript unit test framework. Each plugin has a file dedicated to its tests in `unit/.js`. + +* `unit/` contains the unit test files for each Bootstrap plugin. +* `vendor/` contains jQuery. +* `visual/` contains "visual" tests which are run interactively in real browsers and require manual verification by humans. + +To run our unit tests on a real web browser [Karma](https://karma-runner.github.io/2.0/index.html), run `grunt test-js` or you can +open `index.html`. + + +## How do I add a new unit test? + +1. Locate and open the file dedicated to the plugin which you need to add tests to (`unit/.js`). +2. Review the [QUnit API Documentation](https://api.qunitjs.com/) and use the existing tests as references for how to structure your new tests. +3. Write the necessary unit test(s) for the new or revised functionality. +4. Run `grunt test-js` to see the results of your newly-added test(s). + +**Note:** Your new unit tests should fail before your changes are applied to the plugin, and should pass after your changes are applied to the plugin. + + +## What should a unit test look like? + +* Each test should have a unique name clearly stating what unit is being tested. +* Each test should test only one unit per test, although one test can include several assertions. Create multiple tests for multiple units of functionality. +* Each test should begin with [`assert.expect`](https://api.qunitjs.com/expect/) to ensure that the expected assertions are run. +* Each test should follow the project's [JavaScript Code Guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md#js) + +### Example tests + +```javascript +// Synchronous test +QUnit.test('should describe the unit being tested', function (assert) { + assert.expect(1) + var templateHTML = '
' + + '×' + + '

Template necessary for the test.

' + + '
' + var $alert = $(templateHTML).appendTo('#qunit-fixture').bootstrapAlert() + + $alert.find('.close').click() + + // Make assertion + assert.strictEqual($alert.hasClass('in'), false, 'remove .in class on .close click') +}) + +// Asynchronous test +QUnit.test('should describe the unit being tested', function (assert) { + assert.expect(1) + var done = assert.async() + + $('
') + .appendTo('#qunit-fixture') + .on('shown.bs.tooltip', function () { + assert.ok(true, '"shown" event was fired after calling "show"') + done() + }) + .bootstrapTooltip('show') +}) +``` diff --git a/bootstrap/fonts/js/tests/index.html b/bootstrap/fonts/js/tests/index.html new file mode 100755 index 0000000..bb86baa --- /dev/null +++ b/bootstrap/fonts/js/tests/index.html @@ -0,0 +1,168 @@ + + + + + Bootstrap Plugin Test Suite + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + diff --git a/bootstrap/fonts/js/tests/unit/.jshintrc b/bootstrap/fonts/js/tests/unit/.jshintrc new file mode 100755 index 0000000..22e8785 --- /dev/null +++ b/bootstrap/fonts/js/tests/unit/.jshintrc @@ -0,0 +1,6 @@ +{ + "extends" : "../../.jshintrc", + "devel" : true, + "es3" : false, + "qunit" : true +} diff --git a/bootstrap/fonts/js/tests/unit/affix.js b/bootstrap/fonts/js/tests/unit/affix.js new file mode 100755 index 0000000..98dfb52 --- /dev/null +++ b/bootstrap/fonts/js/tests/unit/affix.js @@ -0,0 +1,123 @@ +$(function () { + 'use strict'; + + QUnit.module('affix plugin') + + QUnit.test('should be defined on jquery object', function (assert) { + assert.expect(1) + assert.ok($(document.body).affix, 'affix method is defined') + }) + + QUnit.module('affix', { + beforeEach: function () { + // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode + $.fn.bootstrapAffix = $.fn.affix.noConflict() + }, + afterEach: function () { + $.fn.affix = $.fn.bootstrapAffix + delete $.fn.bootstrapAffix + } + }) + + QUnit.test('should provide no conflict', function (assert) { + assert.expect(1) + assert.strictEqual($.fn.affix, undefined, 'affix was set back to undefined (org value)') + }) + + QUnit.test('should return jquery collection containing the element', function (assert) { + assert.expect(2) + var $el = $('
').appendTo('#qunit-fixture') + var $affix = $el.bootstrapAffix() + assert.ok($affix instanceof $, 'returns jquery collection') + assert.strictEqual($affix[0], $el[0], 'collection contains element') + }) + + QUnit.test('should exit early if element is not visible', function (assert) { + assert.expect(1) + var $affix = $('
') + .appendTo('#qunit-fixture') + .bootstrapAffix() + + $affix.data('bs.affix').checkPosition() + assert.ok(!$affix.hasClass('affix'), 'affix class was not added') + }) + + QUnit.test('should trigger affixed event after affix', function (assert) { + // Disable for iOS because of: https://bugs.webkit.org/show_bug.cgi?id=172854 + if (window.navigator.userAgent.match(/iPhone/i)) { + assert.expect(0) + return + } + + assert.expect(2) + var done = assert.async() + + var templateHTML = '
' + + '
    ' + + '
  • Please affix
  • ' + + '
  • And unaffix
  • ' + + '
' + + '
' + + '
' + $(templateHTML).appendTo(document.body) + + $('#affixTarget').bootstrapAffix({ + offset: $('#affixTarget ul').position() + }) + + $('#affixTarget') + .on('affix.bs.affix', function () { + assert.ok(true, 'affix event fired') + }).on('affixed.bs.affix', function () { + assert.ok(true, 'affixed event fired') + $('#affixTarget, #affixAfter').remove() + done() + }) + + setTimeout(function () { + window.scrollTo(0, document.body.scrollHeight - 5) + + // for testing in a browser + setTimeout(function () { + window.scroll(0, 0) + }, 150) + }, 0) + }) + + QUnit.test('should affix-top when scrolling up to offset when parent has padding', function (assert) { + // Disable for iOS because of: https://bugs.webkit.org/show_bug.cgi?id=172854 + if (window.navigator.userAgent.match(/iPhone/i)) { + assert.expect(0) + return + } + + assert.expect(1) + var done = assert.async() + + var templateHTML = '
' + + '
' + + '

Testing affix-top class is added

' + + '
' + + '
' + + '
' + $(templateHTML).appendTo(document.body) + + $('#affixTopTarget') + .bootstrapAffix({ + offset: { top: 120, bottom: 0 } + }) + .on('affixed-top.bs.affix', function () { + assert.ok($('#affixTopTarget').hasClass('affix-top'), 'affix-top class applied') + $('#padding-offset').remove() + done() + }) + + setTimeout(function () { + window.scrollTo(0, document.body.scrollHeight - 5) + + setTimeout(function () { + window.scroll(0, 119) + }, 250) + }, 0) + }) +}) diff --git a/bootstrap/fonts/js/tests/unit/alert.js b/bootstrap/fonts/js/tests/unit/alert.js new file mode 100755 index 0000000..ef9bdf2 --- /dev/null +++ b/bootstrap/fonts/js/tests/unit/alert.js @@ -0,0 +1,83 @@ +$(function () { + 'use strict'; + + QUnit.module('alert plugin') + + QUnit.test('should be defined on jquery object', function (assert) { + assert.expect(1) + assert.ok($(document.body).alert, 'alert method is defined') + }) + + QUnit.module('alert', { + beforeEach: function () { + // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode + $.fn.bootstrapAlert = $.fn.alert.noConflict() + }, + afterEach: function () { + $.fn.alert = $.fn.bootstrapAlert + delete $.fn.bootstrapAlert + } + }) + + QUnit.test('should provide no conflict', function (assert) { + assert.expect(1) + assert.strictEqual($.fn.alert, undefined, 'alert was set back to undefined (org value)') + }) + + QUnit.test('should return jquery collection containing the element', function (assert) { + assert.expect(2) + var $el = $('
') + var $alert = $el.bootstrapAlert() + assert.ok($alert instanceof $, 'returns jquery collection') + assert.strictEqual($alert[0], $el[0], 'collection contains element') + }) + + QUnit.test('should fade element out on clicking .close', function (assert) { + assert.expect(1) + var alertHTML = '
' + + '×' + + '

Holy guacamole! Best check yo self, you\'re not looking too good.

' + + '
' + var $alert = $(alertHTML).bootstrapAlert() + + $alert.find('.close').trigger('click') + + assert.strictEqual($alert.hasClass('in'), false, 'remove .in class on .close click') + }) + + QUnit.test('should remove element when clicking .close', function (assert) { + assert.expect(2) + var done = assert.async() + + var alertHTML = '
' + + '×' + + '

Holy guacamole! Best check yo self, you\'re not looking too good.

' + + '
' + var $alert = $(alertHTML).appendTo('#qunit-fixture').bootstrapAlert() + + assert.notEqual($('#qunit-fixture').find('.alert').length, 0, 'element added to dom') + + $alert.on('closed.bs.alert', function () { + assert.strictEqual($('#qunit-fixture').find('.alert').length, 0, 'element removed from dom') + done() + }) + + $alert.find('.close').trigger('click') + }) + + QUnit.test('should not fire closed when close is prevented', function (assert) { + assert.expect(1) + var done = assert.async() + $('
') + .on('close.bs.alert', function (e) { + e.preventDefault() + assert.ok(true, 'close event fired') + done() + }) + .on('closed.bs.alert', function () { + assert.ok(false, 'closed event fired') + }) + .bootstrapAlert('close') + }) + +}) diff --git a/bootstrap/fonts/js/tests/unit/button.js b/bootstrap/fonts/js/tests/unit/button.js new file mode 100755 index 0000000..691796c --- /dev/null +++ b/bootstrap/fonts/js/tests/unit/button.js @@ -0,0 +1,168 @@ +$(function () { + 'use strict'; + + QUnit.module('button plugin') + + QUnit.test('should be defined on jquery object', function (assert) { + assert.expect(1) + assert.ok($(document.body).button, 'button method is defined') + }) + + QUnit.module('button', { + beforeEach: function () { + // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode + $.fn.bootstrapButton = $.fn.button.noConflict() + }, + afterEach: function () { + $.fn.button = $.fn.bootstrapButton + delete $.fn.bootstrapButton + } + }) + + QUnit.test('should provide no conflict', function (assert) { + assert.expect(1) + assert.strictEqual($.fn.button, undefined, 'button was set back to undefined (org value)') + }) + + QUnit.test('should return jquery collection containing the element', function (assert) { + assert.expect(2) + var $el = $('
') + var $button = $el.bootstrapButton() + assert.ok($button instanceof $, 'returns jquery collection') + assert.strictEqual($button[0], $el[0], 'collection contains element') + }) + + QUnit.test('should return set state to loading', function (assert) { + assert.expect(4) + var $btn = $('') + assert.strictEqual($btn.html(), 'mdo', 'btn text equals mdo') + $btn.bootstrapButton('loading') + var done = assert.async() + setTimeout(function () { + assert.strictEqual($btn.html(), 'fat', 'btn text equals fat') + assert.ok($btn[0].hasAttribute('disabled'), 'btn is disabled') + assert.ok($btn.hasClass('disabled'), 'btn has disabled class') + done() + }, 0) + }) + + QUnit.test('should return reset state', function (assert) { + assert.expect(7) + var $btn = $('') + assert.strictEqual($btn.html(), 'mdo', 'btn text equals mdo') + $btn.bootstrapButton('loading') + var doneOne = assert.async() + setTimeout(function () { + assert.strictEqual($btn.html(), 'fat', 'btn text equals fat') + assert.ok($btn[0].hasAttribute('disabled'), 'btn is disabled') + assert.ok($btn.hasClass('disabled'), 'btn has disabled class') + doneOne() + var doneTwo = assert.async() + $btn.bootstrapButton('reset') + setTimeout(function () { + assert.strictEqual($btn.html(), 'mdo', 'btn text equals mdo') + assert.ok(!$btn[0].hasAttribute('disabled'), 'btn is not disabled') + assert.ok(!$btn.hasClass('disabled'), 'btn does not have disabled class') + doneTwo() + }, 0) + }, 0) + }) + + QUnit.test('should work with an empty string as reset state', function (assert) { + assert.expect(7) + var $btn = $('') + assert.ok(!$btn.hasClass('active'), 'btn does not have active class') + $btn.bootstrapButton('toggle') + assert.ok($btn.hasClass('active'), 'btn has class active') + }) + + QUnit.test('should toggle active when btn children are clicked', function (assert) { + assert.expect(2) + var $btn = $('') + var $inner = $('') + $btn + .append($inner) + .appendTo('#qunit-fixture') + assert.ok(!$btn.hasClass('active'), 'btn does not have active class') + $inner.trigger('click') + assert.ok($btn.hasClass('active'), 'btn has class active') + }) + + QUnit.test('should toggle aria-pressed', function (assert) { + assert.expect(2) + var $btn = $('') + assert.strictEqual($btn.attr('aria-pressed'), 'false', 'btn aria-pressed state is false') + $btn.bootstrapButton('toggle') + assert.strictEqual($btn.attr('aria-pressed'), 'true', 'btn aria-pressed state is true') + }) + + QUnit.test('should toggle aria-pressed when btn children are clicked', function (assert) { + assert.expect(2) + var $btn = $('') + var $inner = $('') + $btn + .append($inner) + .appendTo('#qunit-fixture') + assert.strictEqual($btn.attr('aria-pressed'), 'false', 'btn aria-pressed state is false') + $inner.trigger('click') + assert.strictEqual($btn.attr('aria-pressed'), 'true', 'btn aria-pressed state is true') + }) + + QUnit.test('should check for closest matching toggle', function (assert) { + assert.expect(12) + var groupHTML = '
' + + '' + + '' + + '' + + '
' + var $group = $(groupHTML).appendTo('#qunit-fixture') + + var $btn1 = $group.children().eq(0) + var $btn2 = $group.children().eq(1) + + assert.ok($btn1.hasClass('active'), 'btn1 has active class') + assert.ok($btn1.find('input').prop('checked'), 'btn1 is checked') + assert.ok(!$btn2.hasClass('active'), 'btn2 does not have active class') + assert.ok(!$btn2.find('input').prop('checked'), 'btn2 is not checked') + $btn2.find('input').trigger('click') + assert.ok(!$btn1.hasClass('active'), 'btn1 does not have active class') + assert.ok(!$btn1.find('input').prop('checked'), 'btn1 is not checked') + assert.ok($btn2.hasClass('active'), 'btn2 has active class') + assert.ok($btn2.find('input').prop('checked'), 'btn2 is checked') + + $btn2.find('input').trigger('click') // clicking an already checked radio should not un-check it + assert.ok(!$btn1.hasClass('active'), 'btn1 does not have active class') + assert.ok(!$btn1.find('input').prop('checked'), 'btn1 is not checked') + assert.ok($btn2.hasClass('active'), 'btn2 has active class') + assert.ok($btn2.find('input').prop('checked'), 'btn2 is checked') + }) + +}) diff --git a/bootstrap/fonts/js/tests/unit/carousel.js b/bootstrap/fonts/js/tests/unit/carousel.js new file mode 100755 index 0000000..39d2505 --- /dev/null +++ b/bootstrap/fonts/js/tests/unit/carousel.js @@ -0,0 +1,718 @@ +$(function () { + 'use strict'; + + QUnit.module('carousel plugin') + + QUnit.test('should be defined on jQuery object', function (assert) { + assert.expect(1) + assert.ok($(document.body).carousel, 'carousel method is defined') + }) + + QUnit.module('carousel', { + beforeEach: function () { + // Run all tests in noConflict mode -- it's the only way to ensure that the plugin works in noConflict mode + $.fn.bootstrapCarousel = $.fn.carousel.noConflict() + }, + afterEach: function () { + $.fn.carousel = $.fn.bootstrapCarousel + delete $.fn.bootstrapCarousel + } + }) + + QUnit.test('should provide no conflict', function (assert) { + assert.expect(1) + assert.strictEqual($.fn.carousel, undefined, 'carousel was set back to undefined (orig value)') + }) + + QUnit.test('should return jquery collection containing the element', function (assert) { + assert.expect(2) + var $el = $('
') + var $carousel = $el.bootstrapCarousel() + assert.ok($carousel instanceof $, 'returns jquery collection') + assert.strictEqual($carousel[0], $el[0], 'collection contains element') + }) + + QUnit.test('should not fire slid when slide is prevented', function (assert) { + assert.expect(1) + var done = assert.async() + $('