mirror of
https://github.com/twbs/bootstrap.git
synced 2025-02-22 15:39:59 +00:00
bootstrap onto closure
This commit is contained in:
parent
aed1cd3121
commit
834220ea20
68
Gruntfile.js
68
Gruntfile.js
@ -108,33 +108,79 @@ module.exports = function (grunt) {
|
|||||||
},
|
},
|
||||||
bootstrap: {
|
bootstrap: {
|
||||||
src: [
|
src: [
|
||||||
'js/hover.js',
|
'js/util.js',
|
||||||
mq4HoverShim.featureDetector.umdGlobal,
|
|
||||||
'js/transition.js',
|
|
||||||
'js/alert.js',
|
'js/alert.js',
|
||||||
'js/button.js',
|
'js/button.js',
|
||||||
'js/carousel.js',
|
'js/carousel.js',
|
||||||
'js/collapse.js',
|
'js/collapse.js',
|
||||||
'js/dropdown.js',
|
'js/dropdown.js',
|
||||||
'js/modal.js',
|
'js/modal.js',
|
||||||
|
'js/scrollspy.js',
|
||||||
'js/tooltip.js',
|
'js/tooltip.js',
|
||||||
'js/popover.js',
|
'js/popover.js',
|
||||||
'js/scrollspy.js',
|
'js/tab.js'
|
||||||
'js/tab.js',
|
|
||||||
'js/affix.js'
|
|
||||||
],
|
],
|
||||||
dest: 'dist/js/<%= pkg.name %>.js'
|
dest: 'dist/js/<%= pkg.name %>.js'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
closureCompiler: {
|
||||||
|
|
||||||
|
options: {
|
||||||
|
compilerFile: require('superstartup-closure-compiler').getPath(),
|
||||||
|
checkModified: false,
|
||||||
|
|
||||||
|
compilerOpts: {
|
||||||
|
// jscomp_warning: 'reportUnknownTypes', someday - maybe we will get to 100% typed, this helps track those down
|
||||||
|
compilation_level: 'ADVANCED_OPTIMIZATIONS',
|
||||||
|
warning_level: 'verbose',
|
||||||
|
summary_detail_level: 3,
|
||||||
|
output_wrapper:
|
||||||
|
'"<%= banner %><%= jqueryCheck %><%= jqueryVersionCheck %>'
|
||||||
|
+ '(function($){%output%})(jQuery);"',
|
||||||
|
externs: 'js/externs/*.js'
|
||||||
|
},
|
||||||
|
|
||||||
|
execOpts: {
|
||||||
|
maxBuffer: 999999 * 1024
|
||||||
|
},
|
||||||
|
|
||||||
|
// [OPTIONAL] Java VM optimization options
|
||||||
|
// see https://code.google.com/p/closure-compiler/wiki/FAQ#What_are_the_recommended_Java_VM_command-line_options?
|
||||||
|
// Setting one of these to 'true' is strongly recommended,
|
||||||
|
// and can reduce compile times by 50-80% depending on compilation size
|
||||||
|
// and hardware.
|
||||||
|
// On server-class hardware, such as with Github's Travis hook,
|
||||||
|
// TieredCompilation should be used; on standard developer hardware,
|
||||||
|
// d32 may be better. Set as appropriate for your environment.
|
||||||
|
// Default for both is 'false'; do not set both to 'true'.
|
||||||
|
d32: false, // will use 'java -client -d32 -jar compiler.jar'
|
||||||
|
TieredCompilation: false // will use 'java -server -XX:+TieredCompilation -jar compiler.jar'
|
||||||
|
},
|
||||||
|
|
||||||
|
targetName: {
|
||||||
|
src: [
|
||||||
|
'js/util.js',
|
||||||
|
'js/alert.js',
|
||||||
|
'js/button.js',
|
||||||
|
'js/carousel.js',
|
||||||
|
'js/collapse.js',
|
||||||
|
'js/dropdown.js',
|
||||||
|
'js/modal.js',
|
||||||
|
'js/scrollspy.js',
|
||||||
|
'js/tooltip.js',
|
||||||
|
'js/popover.js',
|
||||||
|
'js/tab.js'
|
||||||
|
],
|
||||||
|
dest: 'dist/js/<%= pkg.name %>.min.js'
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
uglify: {
|
uglify: {
|
||||||
options: {
|
options: {
|
||||||
preserveComments: 'some'
|
preserveComments: 'some'
|
||||||
},
|
},
|
||||||
core: {
|
|
||||||
src: '<%= concat.bootstrap.dest %>',
|
|
||||||
dest: 'dist/js/<%= pkg.name %>.min.js'
|
|
||||||
},
|
|
||||||
docsJs: {
|
docsJs: {
|
||||||
src: configBridge.paths.docsJs,
|
src: configBridge.paths.docsJs,
|
||||||
dest: 'docs/assets/js/docs.min.js'
|
dest: 'docs/assets/js/docs.min.js'
|
||||||
@ -388,7 +434,7 @@ module.exports = function (grunt) {
|
|||||||
grunt.registerTask('test-js', ['jshint:core', 'jshint:test', 'jshint:grunt', 'jscs:core', 'jscs:test', 'jscs:grunt', 'qunit']);
|
grunt.registerTask('test-js', ['jshint:core', 'jshint:test', 'jshint:grunt', 'jscs:core', 'jscs:test', 'jscs:grunt', 'qunit']);
|
||||||
|
|
||||||
// JS distribution task.
|
// JS distribution task.
|
||||||
grunt.registerTask('dist-js', ['concat', 'uglify:core', 'commonjs']);
|
grunt.registerTask('dist-js', ['concat', 'closureCompiler', 'commonjs']);
|
||||||
|
|
||||||
grunt.registerTask('test-scss', ['scsslint:scss']);
|
grunt.registerTask('test-scss', ['scsslint:scss']);
|
||||||
|
|
||||||
|
6293
dist/js/bootstrap.js
vendored
6293
dist/js/bootstrap.js
vendored
File diff suppressed because it is too large
Load Diff
74
dist/js/bootstrap.min.js
vendored
74
dist/js/bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
BIN
dist/js/bootstrap.min.js.gz
vendored
Normal file
BIN
dist/js/bootstrap.min.js.gz
vendored
Normal file
Binary file not shown.
8
dist/js/npm.js
vendored
8
dist/js/npm.js
vendored
@ -1,13 +1,13 @@
|
|||||||
// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
|
// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
|
||||||
require('../../js/transition.js')
|
require('../../js/util.js')
|
||||||
|
require('../../node_modules/mq4-hover-shim/dist/browser/mq4-hover-shim.js')
|
||||||
require('../../js/alert.js')
|
require('../../js/alert.js')
|
||||||
require('../../js/button.js')
|
require('../../js/button.js')
|
||||||
require('../../js/carousel.js')
|
require('../../js/carousel.js')
|
||||||
require('../../js/collapse.js')
|
require('../../js/collapse.js')
|
||||||
require('../../js/dropdown.js')
|
require('../../js/dropdown.js')
|
||||||
require('../../js/modal.js')
|
require('../../js/modal.js')
|
||||||
|
require('../../js/scrollspy.js')
|
||||||
require('../../js/tooltip.js')
|
require('../../js/tooltip.js')
|
||||||
require('../../js/popover.js')
|
require('../../js/popover.js')
|
||||||
require('../../js/scrollspy.js')
|
require('../../js/tab.js')
|
||||||
require('../../js/tab.js')
|
|
||||||
require('../../js/affix.js')
|
|
288
js/alert.js
288
js/alert.js
@ -1,94 +1,260 @@
|
|||||||
/* ========================================================================
|
/** =======================================================================
|
||||||
* Bootstrap: alert.js v3.3.2
|
* Bootstrap: alert.js v4.0.0
|
||||||
* http://getbootstrap.com/javascript/#alerts
|
* http://getbootstrap.com/javascript/#alerts
|
||||||
* ========================================================================
|
* ========================================================================
|
||||||
* Copyright 2011-2015 Twitter, Inc.
|
* Copyright 2011-2015 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
* ======================================================================== */
|
* ========================================================================
|
||||||
|
* @fileoverview - Bootstrap's generic alert component. Add dismiss
|
||||||
|
* functionality to all alert messages with this plugin.
|
||||||
|
*
|
||||||
|
* Public Methods & Properties:
|
||||||
|
*
|
||||||
|
* + $.alert
|
||||||
|
* + $.alert.noConflict
|
||||||
|
* + $.alert.Constructor
|
||||||
|
* + $.alert.Constructor.VERSION
|
||||||
|
* + $.alert.Constructor.prototype.close
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
+function ($) {
|
/**
|
||||||
'use strict';
|
* Our Alert class.
|
||||||
|
* @param {Element=} opt_element
|
||||||
// ALERT CLASS DEFINITION
|
* @constructor
|
||||||
// ======================
|
*/
|
||||||
|
var Alert = function (opt_element) {
|
||||||
var dismiss = '[data-dismiss="alert"]'
|
if (opt_element) {
|
||||||
var Alert = function (el) {
|
$(opt_element).on('click', Alert._DISMISS_SELECTOR, Alert._handleDismiss(this))
|
||||||
$(el).on('click', dismiss, this.close)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Alert.VERSION = '3.3.2'
|
|
||||||
|
|
||||||
Alert.TRANSITION_DURATION = 150
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
Alert['VERSION'] = '4.0.0'
|
||||||
|
|
||||||
Alert.prototype.close = function (e) {
|
|
||||||
var $this = $(this)
|
|
||||||
var selector = $this.attr('data-target')
|
|
||||||
|
|
||||||
if (!selector) {
|
/**
|
||||||
selector = $this.attr('href')
|
* @const
|
||||||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert._NAME = 'alert'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert._DATA_KEY = 'bs.alert'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert._DISMISS_SELECTOR = '[data-dismiss="alert"]'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert._TRANSITION_DURATION = 150
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert._JQUERY_NO_CONFLICT = $.fn[Alert._NAME]
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert._Event = {
|
||||||
|
CLOSE : 'close.bs.alert',
|
||||||
|
CLOSED : 'closed.bs.alert'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert._ClassName = {
|
||||||
|
ALERT : 'alert',
|
||||||
|
FADE : 'fade',
|
||||||
|
IN : 'in'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the jQuery Interface for the alert component.
|
||||||
|
* @param {string=} opt_config
|
||||||
|
* @this {jQuery}
|
||||||
|
* @return {jQuery}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert._jQueryInterface = function (opt_config) {
|
||||||
|
return this.each(function () {
|
||||||
|
var $this = $(this)
|
||||||
|
var data = $this.data(Alert._DATA_KEY)
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
data = new Alert(this)
|
||||||
|
$this.data(Alert._DATA_KEY, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
var $parent = $(selector)
|
if (opt_config === 'close') {
|
||||||
|
data[opt_config](this)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (e) e.preventDefault()
|
|
||||||
|
|
||||||
if (!$parent.length) {
|
/**
|
||||||
$parent = $this.closest('.alert')
|
* Close the alert component
|
||||||
|
* @param {Alert} alertInstance
|
||||||
|
* @return {Function}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert._handleDismiss = function (alertInstance) {
|
||||||
|
return function (event) {
|
||||||
|
if (event) {
|
||||||
|
event.preventDefault()
|
||||||
}
|
}
|
||||||
|
|
||||||
$parent.trigger(e = $.Event('close.bs.alert'))
|
alertInstance['close'](this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (e.isDefaultPrevented()) return
|
|
||||||
|
|
||||||
$parent.removeClass('in')
|
/**
|
||||||
|
* Close the alert component
|
||||||
|
* @param {Element} element
|
||||||
|
*/
|
||||||
|
Alert.prototype['close'] = function (element) {
|
||||||
|
var rootElement = this._getRootElement(element)
|
||||||
|
var customEvent = this._triggerCloseEvent(rootElement)
|
||||||
|
|
||||||
function removeElement() {
|
if (customEvent.isDefaultPrevented()) return
|
||||||
// detach from parent, fire event then clean up data
|
|
||||||
$parent.detach().trigger('closed.bs.alert').remove()
|
|
||||||
}
|
|
||||||
|
|
||||||
$.support.transition && $parent.hasClass('fade') ?
|
this._removeElement(rootElement)
|
||||||
$parent
|
}
|
||||||
.one('bsTransitionEnd', removeElement)
|
|
||||||
.emulateTransitionEnd(Alert.TRANSITION_DURATION) :
|
|
||||||
removeElement()
|
/**
|
||||||
|
* Tries to get the alert's root element
|
||||||
|
* @return {Element}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert.prototype._getRootElement = function (element) {
|
||||||
|
var parent = false
|
||||||
|
var selector = Bootstrap.getSelectorFromElement(element)
|
||||||
|
|
||||||
|
if (selector) {
|
||||||
|
parent = $(selector)[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!parent) {
|
||||||
// ALERT PLUGIN DEFINITION
|
parent = $(element).closest('.' + Alert._ClassName.ALERT)[0]
|
||||||
// =======================
|
|
||||||
|
|
||||||
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
|
return parent
|
||||||
|
}
|
||||||
$.fn.alert = Plugin
|
|
||||||
$.fn.alert.Constructor = Alert
|
|
||||||
|
|
||||||
|
|
||||||
// ALERT NO CONFLICT
|
/**
|
||||||
// =================
|
* Trigger close event on element
|
||||||
|
* @return {$.Event}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert.prototype._triggerCloseEvent = function (element) {
|
||||||
|
var closeEvent = $.Event(Alert._Event.CLOSE)
|
||||||
|
$(element).trigger(closeEvent)
|
||||||
|
return closeEvent
|
||||||
|
}
|
||||||
|
|
||||||
$.fn.alert.noConflict = function () {
|
|
||||||
$.fn.alert = old
|
/**
|
||||||
return this
|
* Trigger closed event and remove element from dom
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert.prototype._removeElement = function (element) {
|
||||||
|
$(element).removeClass(Alert._ClassName.IN)
|
||||||
|
|
||||||
|
if (!Bootstrap.transition || !$(element).hasClass(Alert._ClassName.FADE)) {
|
||||||
|
this._destroyElement(element)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(element)
|
||||||
|
.one(Bootstrap.TRANSITION_END, this._destroyElement.bind(this, element))
|
||||||
|
.emulateTransitionEnd(Alert._TRANSITION_DURATION)
|
||||||
|
}
|
||||||
|
|
||||||
// ALERT DATA-API
|
|
||||||
// ==============
|
|
||||||
|
|
||||||
$(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
|
/**
|
||||||
|
* clean up any lingering jquery data and kill element
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Alert.prototype._destroyElement = function (element) {
|
||||||
|
$(element)
|
||||||
|
.detach()
|
||||||
|
.trigger(Alert._Event.CLOSED)
|
||||||
|
.remove()
|
||||||
|
}
|
||||||
|
|
||||||
}(jQuery);
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* jQuery Interface + noConflict implementaiton
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Alert._NAME] = Alert._jQueryInterface
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Alert._NAME]['Constructor'] = Alert
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Alert._NAME]['noConflict'] = function () {
|
||||||
|
$.fn[Alert._NAME] = Alert._JQUERY_NO_CONFLICT
|
||||||
|
return Alert._jQueryInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* Data Api implementation
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
$(document).on('click.bs.alert.data-api', Alert._DISMISS_SELECTOR, Alert._handleDismiss(new Alert))
|
||||||
|
265
js/button.js
265
js/button.js
@ -1,116 +1,207 @@
|
|||||||
/* ========================================================================
|
/** =======================================================================
|
||||||
* Bootstrap: button.js v3.3.2
|
* Bootstrap: button.js v4.0.0
|
||||||
* http://getbootstrap.com/javascript/#buttons
|
* http://getbootstrap.com/javascript/#buttons
|
||||||
* ========================================================================
|
* ========================================================================
|
||||||
* Copyright 2011-2015 Twitter, Inc.
|
* Copyright 2011-2015 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
* ======================================================================== */
|
* ========================================================================
|
||||||
|
* @fileoverview - Bootstrap's generic button component.
|
||||||
|
*
|
||||||
|
* Note (@fat): Deprecated "setState" – imo, better solutions for managing a
|
||||||
|
* buttons state should exist outside this plugin.
|
||||||
|
*
|
||||||
|
* Public Methods & Properties:
|
||||||
|
*
|
||||||
|
* + $.button
|
||||||
|
* + $.button.noConflict
|
||||||
|
* + $.button.Constructor
|
||||||
|
* + $.button.Constructor.VERSION
|
||||||
|
* + $.button.Constructor.prototype.toggle
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
+function ($) {
|
/**
|
||||||
'use strict';
|
* Our Button class.
|
||||||
|
* @param {Element!} element
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var Button = function (element) {
|
||||||
|
|
||||||
// BUTTON PUBLIC CLASS DEFINITION
|
/** @private {Element} */
|
||||||
// ==============================
|
this._element = element
|
||||||
|
|
||||||
var Button = function (element, options) {
|
}
|
||||||
this.$element = $(element)
|
|
||||||
this.options = $.extend({}, Button.DEFAULTS, options)
|
|
||||||
this.isLoading = false
|
|
||||||
}
|
|
||||||
|
|
||||||
Button.VERSION = '3.3.2'
|
|
||||||
|
|
||||||
Button.DEFAULTS = {
|
/**
|
||||||
loadingText: 'loading...'
|
* @const
|
||||||
}
|
* @type {string}
|
||||||
|
*/
|
||||||
|
Button['VERSION'] = '4.0.0'
|
||||||
|
|
||||||
Button.prototype.setState = function (state) {
|
|
||||||
var d = 'disabled'
|
|
||||||
var $el = this.$element
|
|
||||||
var val = $el.is('input') ? 'val' : 'html'
|
|
||||||
var data = $el.data()
|
|
||||||
|
|
||||||
state = state + 'Text'
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Button._NAME = 'button'
|
||||||
|
|
||||||
if (data.resetText == null) $el.data('resetText', $el[val]())
|
|
||||||
|
|
||||||
// push to event loop to allow forms to submit
|
/**
|
||||||
setTimeout($.proxy(function () {
|
* @const
|
||||||
$el[val](data[state] == null ? this.options[state] : data[state])
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Button._DATA_KEY = 'bs.button'
|
||||||
|
|
||||||
if (state == 'loadingText') {
|
|
||||||
this.isLoading = true
|
|
||||||
$el.addClass(d).attr(d, d)
|
|
||||||
} else if (this.isLoading) {
|
|
||||||
this.isLoading = false
|
|
||||||
$el.removeClass(d).removeAttr(d)
|
|
||||||
}
|
|
||||||
}, this), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
Button.prototype.toggle = function () {
|
/**
|
||||||
var changed = true
|
* @const
|
||||||
var $parent = this.$element.closest('[data-toggle="buttons"]')
|
* @type {Function}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Button._JQUERY_NO_CONFLICT = $.fn[Button._NAME]
|
||||||
|
|
||||||
if ($parent.length) {
|
|
||||||
var $input = this.$element.find('input')
|
/**
|
||||||
if ($input.prop('type') == 'radio') {
|
* @const
|
||||||
if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
|
* @enum {string}
|
||||||
else $parent.find('.active').removeClass('active')
|
* @private
|
||||||
}
|
*/
|
||||||
if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
|
Button._ClassName = {
|
||||||
} else {
|
ACTIVE : 'active',
|
||||||
this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
|
BUTTON : 'btn',
|
||||||
|
FOCUS : 'focus'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Button._Selector = {
|
||||||
|
DATA_TOGGLE_CARROT : '[data-toggle^="button"]',
|
||||||
|
DATA_TOGGLE : '[data-toggle="buttons"]',
|
||||||
|
INPUT : 'input',
|
||||||
|
ACTIVE : '.active',
|
||||||
|
BUTTON : '.btn'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the jQuery Interface for the Button component.
|
||||||
|
* @param {string=} opt_config
|
||||||
|
* @this {jQuery}
|
||||||
|
* @return {jQuery}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Button._jQueryInterface = function (opt_config) {
|
||||||
|
return this.each(function () {
|
||||||
|
var data = $(this).data(Button._DATA_KEY)
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
data = new Button(this)
|
||||||
|
$(this).data(Button._DATA_KEY, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) this.$element.toggleClass('active')
|
if (opt_config === 'toggle') {
|
||||||
|
data[opt_config]()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle's the button active state
|
||||||
|
*/
|
||||||
|
Button.prototype['toggle'] = function () {
|
||||||
|
var triggerChangeEvent = true
|
||||||
|
var rootElement = $(this._element).closest(Button._Selector.DATA_TOGGLE)[0]
|
||||||
|
|
||||||
|
if (rootElement) {
|
||||||
|
var input = $(this._element).find(Button._Selector.INPUT)[0]
|
||||||
|
if (input) {
|
||||||
|
if (input.type == 'radio') {
|
||||||
|
if (input.checked && $(this._element).hasClass(Button._ClassName.ACTIVE)) {
|
||||||
|
triggerChangeEvent = false
|
||||||
|
} else {
|
||||||
|
var activeElement = $(rootElement).find(Button._Selector.ACTIVE)[0]
|
||||||
|
if (activeElement) {
|
||||||
|
$(activeElement).removeClass(Button._ClassName.ACTIVE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (triggerChangeEvent) {
|
||||||
|
input.checked = !$(this._element).hasClass(Button._ClassName.ACTIVE)
|
||||||
|
$(this._element).trigger('change')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._element.setAttribute('aria-pressed', !$(this._element).hasClass(Button._ClassName.ACTIVE))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (triggerChangeEvent) {
|
||||||
// BUTTON PLUGIN DEFINITION
|
$(this._element).toggleClass(Button._ClassName.ACTIVE)
|
||||||
// ========================
|
|
||||||
|
|
||||||
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
|
/**
|
||||||
// ==================
|
* ------------------------------------------------------------------------
|
||||||
|
* jQuery Interface + noConflict implementaiton
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
$.fn.button.noConflict = function () {
|
/**
|
||||||
$.fn.button = old
|
* @const
|
||||||
return this
|
* @type {Function}
|
||||||
}
|
*/
|
||||||
|
$.fn[Button._NAME] = Button._jQueryInterface
|
||||||
|
|
||||||
|
|
||||||
// BUTTON DATA-API
|
/**
|
||||||
// ===============
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Button._NAME]['Constructor'] = Button
|
||||||
|
|
||||||
$(document)
|
|
||||||
.on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
|
|
||||||
var $btn = $(e.target)
|
|
||||||
if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
|
|
||||||
Plugin.call($btn, 'toggle')
|
|
||||||
e.preventDefault()
|
|
||||||
})
|
|
||||||
.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);
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Button._NAME]['noConflict'] = function () {
|
||||||
|
$.fn[Button._NAME] = Button._JQUERY_NO_CONFLICT
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* Data Api implementation
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
$(document)
|
||||||
|
.on('click.bs.button.data-api', Button._Selector.DATA_TOGGLE_CARROT, function (event) {
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
var button = event.target
|
||||||
|
|
||||||
|
if (!$(button).hasClass(Button._ClassName.BUTTON)) {
|
||||||
|
button = $(button).closest(Button._Selector.BUTTON)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button._jQueryInterface.call($(button), 'toggle')
|
||||||
|
})
|
||||||
|
.on('focus.bs.button.data-api blur.bs.button.data-api', Button._Selector.DATA_TOGGLE_CARROT, function (event) {
|
||||||
|
var button = $(event.target).closest(Button._Selector.BUTTON)[0]
|
||||||
|
$(button).toggleClass(Button._ClassName.FOCUS, /^focus(in)?$/.test(event.type))
|
||||||
|
})
|
||||||
|
725
js/carousel.js
725
js/carousel.js
@ -1,237 +1,576 @@
|
|||||||
/* ========================================================================
|
/** =======================================================================
|
||||||
* Bootstrap: carousel.js v3.3.2
|
* Bootstrap: carousel.js v4.0.0
|
||||||
* http://getbootstrap.com/javascript/#carousel
|
* http://getbootstrap.com/javascript/#carousel
|
||||||
* ========================================================================
|
* ========================================================================
|
||||||
* Copyright 2011-2015 Twitter, Inc.
|
* Copyright 2011-2015 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
* ======================================================================== */
|
* ========================================================================
|
||||||
|
* @fileoverview - Bootstrap's carousel. A slideshow component for cycling
|
||||||
|
* through elements, like a carousel. Nested carousels are not supported.
|
||||||
|
*
|
||||||
|
* Public Methods & Properties:
|
||||||
|
*
|
||||||
|
* + $.carousel
|
||||||
|
* + $.carousel.noConflict
|
||||||
|
* + $.carousel.Constructor
|
||||||
|
* + $.carousel.Constructor.VERSION
|
||||||
|
* + $.carousel.Constructor.Defaults
|
||||||
|
* + $.carousel.Constructor.Defaults.interval
|
||||||
|
* + $.carousel.Constructor.Defaults.pause
|
||||||
|
* + $.carousel.Constructor.Defaults.wrap
|
||||||
|
* + $.carousel.Constructor.Defaults.keyboard
|
||||||
|
* + $.carousel.Constructor.Defaults.slide
|
||||||
|
* + $.carousel.Constructor.prototype.next
|
||||||
|
* + $.carousel.Constructor.prototype.prev
|
||||||
|
* + $.carousel.Constructor.prototype.pause
|
||||||
|
* + $.carousel.Constructor.prototype.cycle
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
+function ($) {
|
/**
|
||||||
'use strict';
|
* Our carousel class.
|
||||||
|
* @param {Element!} element
|
||||||
|
* @param {Object=} opt_config
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var Carousel = function (element, opt_config) {
|
||||||
|
|
||||||
// CAROUSEL CLASS DEFINITION
|
/** @private {Element} */
|
||||||
// =========================
|
this._element = $(element)[0]
|
||||||
|
|
||||||
var Carousel = function (element, options) {
|
/** @private {Element} */
|
||||||
this.$element = $(element)
|
this._indicatorsElement = $(this._element).find(Carousel._Selector.INDICATORS)[0]
|
||||||
this.$indicators = this.$element.find('.carousel-indicators')
|
|
||||||
this.options = options
|
|
||||||
this.paused =
|
|
||||||
this.sliding =
|
|
||||||
this.interval =
|
|
||||||
this.$active =
|
|
||||||
this.$items = null
|
|
||||||
|
|
||||||
this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
|
/** @private {?Object} */
|
||||||
|
this._config = opt_config || null
|
||||||
|
|
||||||
this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
|
/** @private {boolean} */
|
||||||
.on('mouseenter.bs.carousel', $.proxy(this.pause, this))
|
this._isPaused = false
|
||||||
.on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
|
|
||||||
}
|
|
||||||
|
|
||||||
Carousel.VERSION = '3.3.2'
|
/** @private {boolean} */
|
||||||
|
this._isSliding = false
|
||||||
|
|
||||||
Carousel.TRANSITION_DURATION = 600
|
/** @private {?number} */
|
||||||
|
this._interval = null
|
||||||
|
|
||||||
Carousel.DEFAULTS = {
|
/** @private {?Element} */
|
||||||
interval: 5000,
|
this._activeElement = null
|
||||||
pause: 'hover',
|
|
||||||
wrap: true,
|
|
||||||
keyboard: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Carousel.prototype.keydown = function (e) {
|
/** @private {?Array} */
|
||||||
if (/input|textarea/i.test(e.target.tagName)) return
|
this._items = null
|
||||||
switch (e.which) {
|
|
||||||
case 37: this.prev(); break
|
this._addEventListeners()
|
||||||
case 39: this.next(); break
|
|
||||||
default: return
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
Carousel['VERSION'] = '4.0.0'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
Carousel['Defaults'] = {
|
||||||
|
'interval' : 5000,
|
||||||
|
'pause' : 'hover',
|
||||||
|
'wrap' : true,
|
||||||
|
'keyboard' : true,
|
||||||
|
'slide' : false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel._NAME = 'carousel'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel._DATA_KEY = 'bs.carousel'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel._TRANSITION_DURATION = 600
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel._Direction = {
|
||||||
|
NEXT : 'next',
|
||||||
|
PREVIOUS : 'prev'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel._Event = {
|
||||||
|
SLIDE : 'slide.bs.carousel',
|
||||||
|
SLID : 'slid.bs.carousel'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel._ClassName = {
|
||||||
|
CAROUSEL : 'carousel',
|
||||||
|
ACTIVE : 'active',
|
||||||
|
SLIDE : 'slide',
|
||||||
|
RIGHT : 'right',
|
||||||
|
LEFT : 'left',
|
||||||
|
ITEM : 'carousel-item'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel._Selector = {
|
||||||
|
ACTIVE : '.active',
|
||||||
|
ACTIVE_ITEM : '.active.carousel-item',
|
||||||
|
ITEM : '.carousel-item',
|
||||||
|
NEXT_PREV : '.next, .prev',
|
||||||
|
INDICATORS : '.carousel-indicators'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel._JQUERY_NO_CONFLICT = $.fn[Carousel._NAME]
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object=} opt_config
|
||||||
|
* @this {jQuery}
|
||||||
|
* @return {jQuery}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel._jQueryInterface = function (opt_config) {
|
||||||
|
return this.each(function () {
|
||||||
|
var data = $(this).data(Carousel._DATA_KEY)
|
||||||
|
var config = $.extend({}, Carousel['Defaults'], $(this).data(), typeof opt_config == 'object' && opt_config)
|
||||||
|
var action = typeof opt_config == 'string' ? opt_config : config.slide
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
data = new Carousel(this, config)
|
||||||
|
$(this).data(Carousel._DATA_KEY, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.preventDefault()
|
if (typeof opt_config == 'number') {
|
||||||
}
|
data.to(opt_config)
|
||||||
|
|
||||||
Carousel.prototype.cycle = function (e) {
|
} else if (action) {
|
||||||
e || (this.paused = false)
|
data[action]()
|
||||||
|
|
||||||
this.interval && clearInterval(this.interval)
|
} else if (config.interval) {
|
||||||
|
data['pause']()
|
||||||
this.options.interval
|
data['cycle']()
|
||||||
&& !this.paused
|
|
||||||
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
|
|
||||||
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
Carousel.prototype.getItemIndex = function (item) {
|
|
||||||
this.$items = item.parent().children('.carousel-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('.carousel-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
|
/**
|
||||||
|
* Click handler for data api
|
||||||
|
* @param {Event} event
|
||||||
|
* @this {Element}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel._dataApiClickHandler = function (event) {
|
||||||
|
var selector = Bootstrap.getSelectorFromElement(this)
|
||||||
|
|
||||||
|
if (!selector) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Carousel.prototype.next = function () {
|
var target = $(selector)[0]
|
||||||
if (this.sliding) return
|
|
||||||
return this.slide('next')
|
if (!target || !$(target).hasClass(Carousel._ClassName.CAROUSEL)) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Carousel.prototype.prev = function () {
|
var config = $.extend({}, $(target).data(), $(this).data())
|
||||||
if (this.sliding) return
|
|
||||||
return this.slide('prev')
|
var slideIndex = this.getAttribute('data-slide-to')
|
||||||
|
if (slideIndex) {
|
||||||
|
config.interval = false
|
||||||
}
|
}
|
||||||
|
|
||||||
Carousel.prototype.slide = function (type, next) {
|
Carousel._jQueryInterface.call($(target), config)
|
||||||
var $active = this.$element.find('.carousel-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)
|
if (slideIndex) {
|
||||||
|
$(target).data(Carousel._DATA_KEY).to(slideIndex)
|
||||||
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)
|
|
||||||
$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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
// CAROUSEL PLUGIN DEFINITION
|
|
||||||
// ==========================
|
|
||||||
|
|
||||||
function Plugin(option) {
|
/**
|
||||||
return this.each(function () {
|
* Advance the carousel to the next slide
|
||||||
var $this = $(this)
|
*/
|
||||||
var data = $this.data('bs.carousel')
|
Carousel.prototype['next'] = function () {
|
||||||
var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
if (!this._isSliding) {
|
||||||
var action = typeof option == 'string' ? option : options.slide
|
this._slide(Carousel._Direction.NEXT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
|
|
||||||
if (typeof option == 'number') data.to(option)
|
/**
|
||||||
else if (action) data[action]()
|
* Return the carousel to the previous slide
|
||||||
else if (options.interval) data.pause().cycle()
|
*/
|
||||||
})
|
Carousel.prototype['prev'] = function () {
|
||||||
|
if (!this._isSliding) {
|
||||||
|
this._slide(Carousel._Direction.PREVIOUS)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pause the carousel cycle
|
||||||
|
* @param {Event=} opt_event
|
||||||
|
*/
|
||||||
|
Carousel.prototype['pause'] = function (opt_event) {
|
||||||
|
if (!opt_event) {
|
||||||
|
this._isPaused = true
|
||||||
}
|
}
|
||||||
|
|
||||||
var old = $.fn.carousel
|
if ($(this._element).find(Carousel._Selector.NEXT_PREV)[0] && Bootstrap.transition) {
|
||||||
|
$(this._element).trigger(Bootstrap.transition.end)
|
||||||
$.fn.carousel = Plugin
|
this['cycle'](true)
|
||||||
$.fn.carousel.Constructor = Carousel
|
|
||||||
|
|
||||||
|
|
||||||
// CAROUSEL NO CONFLICT
|
|
||||||
// ====================
|
|
||||||
|
|
||||||
$.fn.carousel.noConflict = function () {
|
|
||||||
$.fn.carousel = old
|
|
||||||
return this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearInterval(this._interval)
|
||||||
|
this._interval = null
|
||||||
|
}
|
||||||
|
|
||||||
// CAROUSEL DATA-API
|
|
||||||
// =================
|
|
||||||
|
|
||||||
var clickHandler = function (e) {
|
/**
|
||||||
var href
|
* Cycle to the next carousel item
|
||||||
var $this = $(this)
|
* @param {Event|boolean=} opt_event
|
||||||
var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
|
*/
|
||||||
if (!$target.hasClass('carousel')) return
|
Carousel.prototype['cycle'] = function (opt_event) {
|
||||||
var options = $.extend({}, $target.data(), $this.data())
|
if (!opt_event) {
|
||||||
var slideIndex = $this.attr('data-slide-to')
|
this._isPaused = false
|
||||||
if (slideIndex) options.interval = false
|
|
||||||
|
|
||||||
Plugin.call($target, options)
|
|
||||||
|
|
||||||
if (slideIndex) {
|
|
||||||
$target.data('bs.carousel').to(slideIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
e.preventDefault()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document)
|
if (this._interval) {
|
||||||
.on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
|
clearInterval(this._interval)
|
||||||
.on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
|
this._interval = null
|
||||||
|
}
|
||||||
|
|
||||||
$(window).on('load', function () {
|
if (this._config['interval'] && !this._isPaused) {
|
||||||
$('[data-ride="carousel"]').each(function () {
|
this._interval = setInterval(this['next'].bind(this), this._config['interval'])
|
||||||
var $carousel = $(this)
|
}
|
||||||
Plugin.call($carousel, $carousel.data())
|
}
|
||||||
})
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Object}
|
||||||
|
*/
|
||||||
|
Carousel.prototype['getConfig'] = function () {
|
||||||
|
return this._config
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move active carousel item to specified index
|
||||||
|
* @param {number} index
|
||||||
|
*/
|
||||||
|
Carousel.prototype.to = function (index) {
|
||||||
|
this._activeElement = $(this._element).find(Carousel._Selector.ACTIVE_ITEM)[0]
|
||||||
|
|
||||||
|
var activeIndex = this._getItemIndex(this._activeElement)
|
||||||
|
|
||||||
|
if (index > (this._items.length - 1) || index < 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._isSliding) {
|
||||||
|
$(this._element).one(Carousel._Event.SLID, function () { this.to(index) }.bind(this))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeIndex == index) {
|
||||||
|
this['pause']()
|
||||||
|
this['cycle']()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var direction = index > activeIndex ?
|
||||||
|
Carousel._Direction.NEXT :
|
||||||
|
Carousel._Direction.PREVIOUS
|
||||||
|
|
||||||
|
this._slide(direction, this._items[index])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add event listeners to root element
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel.prototype._addEventListeners = function () {
|
||||||
|
if (this._config['keyboard']) {
|
||||||
|
$(this._element).on('keydown.bs.carousel', this._keydown.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._config['pause'] == 'hover' && !('ontouchstart' in document.documentElement)) {
|
||||||
|
$(this._element)
|
||||||
|
.on('mouseenter.bs.carousel', this['pause'].bind(this))
|
||||||
|
.on('mouseleave.bs.carousel', this['cycle'].bind(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keydown handler
|
||||||
|
* @param {Event} event
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel.prototype._keydown = function (event) {
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
if (/input|textarea/i.test(event.target.tagName)) return
|
||||||
|
|
||||||
|
switch (event.which) {
|
||||||
|
case 37: this['prev'](); break
|
||||||
|
case 39: this['next'](); break
|
||||||
|
default: return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get item index
|
||||||
|
* @param {Element} element
|
||||||
|
* @return {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel.prototype._getItemIndex = function (element) {
|
||||||
|
this._items = $.makeArray($(element).parent().find(Carousel._Selector.ITEM))
|
||||||
|
|
||||||
|
return this._items.indexOf(element)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get next displayed item based on direction
|
||||||
|
* @param {Carousel._Direction} direction
|
||||||
|
* @param {Element} activeElement
|
||||||
|
* @return {Element}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel.prototype._getItemByDirection = function (direction, activeElement) {
|
||||||
|
var activeIndex = this._getItemIndex(activeElement)
|
||||||
|
var isGoingToWrap = (direction === Carousel._Direction.PREVIOUS && activeIndex === 0) ||
|
||||||
|
(direction === Carousel._Direction.NEXT && activeIndex == (this._items.length - 1))
|
||||||
|
|
||||||
|
if (isGoingToWrap && !this._config['wrap']) {
|
||||||
|
return activeElement
|
||||||
|
}
|
||||||
|
|
||||||
|
var delta = direction == Carousel._Direction.PREVIOUS ? -1 : 1
|
||||||
|
var itemIndex = (activeIndex + delta) % this._items.length
|
||||||
|
|
||||||
|
return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger slide event on element
|
||||||
|
* @param {Element} relatedTarget
|
||||||
|
* @param {Carousel._ClassName} directionalClassname
|
||||||
|
* @return {$.Event}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel.prototype._triggerSlideEvent = function (relatedTarget, directionalClassname) {
|
||||||
|
var slideEvent = $.Event(Carousel._Event.SLIDE, {
|
||||||
|
relatedTarget: relatedTarget,
|
||||||
|
direction: directionalClassname
|
||||||
})
|
})
|
||||||
|
|
||||||
}(jQuery);
|
$(this._element).trigger(slideEvent)
|
||||||
|
|
||||||
|
return slideEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the active indicator if available
|
||||||
|
* @param {Element} element
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Carousel.prototype._setActiveIndicatorElement = function (element) {
|
||||||
|
if (this._indicatorsElement) {
|
||||||
|
$(this._indicatorsElement)
|
||||||
|
.find(Carousel._Selector.ACTIVE)
|
||||||
|
.removeClass(Carousel._ClassName.ACTIVE)
|
||||||
|
|
||||||
|
var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)]
|
||||||
|
if (nextIndicator) {
|
||||||
|
$(nextIndicator).addClass(Carousel._ClassName.ACTIVE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slide the carousel element in a direction
|
||||||
|
* @param {Carousel._Direction} direction
|
||||||
|
* @param {Element=} opt_nextElement
|
||||||
|
*/
|
||||||
|
Carousel.prototype._slide = function (direction, opt_nextElement) {
|
||||||
|
var activeElement = $(this._element).find(Carousel._Selector.ACTIVE_ITEM)[0]
|
||||||
|
var nextElement = opt_nextElement || activeElement && this._getItemByDirection(direction, activeElement)
|
||||||
|
|
||||||
|
var isCycling = !!this._interval
|
||||||
|
|
||||||
|
var directionalClassName = direction == Carousel._Direction.NEXT ?
|
||||||
|
Carousel._ClassName.LEFT :
|
||||||
|
Carousel._ClassName.RIGHT
|
||||||
|
|
||||||
|
if (nextElement && $(nextElement).hasClass(Carousel._ClassName.ACTIVE)) {
|
||||||
|
this._isSliding = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var slideEvent = this._triggerSlideEvent(nextElement, directionalClassName)
|
||||||
|
if (slideEvent.isDefaultPrevented()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!activeElement || !nextElement) {
|
||||||
|
// some weirdness is happening, so we bail (maybe throw exception here alerting user that they're dom is off
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this._isSliding = true
|
||||||
|
|
||||||
|
if (isCycling) {
|
||||||
|
this['pause']()
|
||||||
|
}
|
||||||
|
|
||||||
|
this._setActiveIndicatorElement(nextElement)
|
||||||
|
|
||||||
|
var slidEvent = $.Event(Carousel._Event.SLID, { relatedTarget: nextElement, direction: directionalClassName })
|
||||||
|
|
||||||
|
if (Bootstrap.transition && $(this._element).hasClass(Carousel._ClassName.SLIDE)) {
|
||||||
|
$(nextElement).addClass(direction)
|
||||||
|
|
||||||
|
Bootstrap.reflow(nextElement)
|
||||||
|
|
||||||
|
$(activeElement).addClass(directionalClassName)
|
||||||
|
$(nextElement).addClass(directionalClassName)
|
||||||
|
|
||||||
|
$(activeElement)
|
||||||
|
.one(Bootstrap.TRANSITION_END, function () {
|
||||||
|
$(nextElement)
|
||||||
|
.removeClass(directionalClassName)
|
||||||
|
.removeClass(direction)
|
||||||
|
|
||||||
|
$(nextElement).addClass(Carousel._ClassName.ACTIVE)
|
||||||
|
|
||||||
|
$(activeElement)
|
||||||
|
.removeClass(Carousel._ClassName.ACTIVE)
|
||||||
|
.removeClass(direction)
|
||||||
|
.removeClass(directionalClassName)
|
||||||
|
|
||||||
|
this._isSliding = false
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
$(this._element).trigger(slidEvent)
|
||||||
|
}.bind(this), 0)
|
||||||
|
}.bind(this))
|
||||||
|
.emulateTransitionEnd(Carousel._TRANSITION_DURATION)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$(activeElement).removeClass(Carousel._ClassName.ACTIVE)
|
||||||
|
$(nextElement).addClass(Carousel._ClassName.ACTIVE)
|
||||||
|
|
||||||
|
this._isSliding = false
|
||||||
|
$(this._element).trigger(slidEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCycling) {
|
||||||
|
this['cycle']()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* jQuery Interface + noConflict implementaiton
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Carousel._NAME] = Carousel._jQueryInterface
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Carousel._NAME]['Constructor'] = Carousel
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Carousel._NAME]['noConflict'] = function () {
|
||||||
|
$.fn[Carousel._NAME] = Carousel._JQUERY_NO_CONFLICT
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* Data Api implementation
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
$(document)
|
||||||
|
.on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', Carousel._dataApiClickHandler)
|
||||||
|
|
||||||
|
$(window).on('load', function () {
|
||||||
|
$('[data-ride="carousel"]').each(function () {
|
||||||
|
var $carousel = $(this)
|
||||||
|
Carousel._jQueryInterface.call($carousel, /** @type {Object} */ ($carousel.data()))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
612
js/collapse.js
612
js/collapse.js
@ -1,211 +1,455 @@
|
|||||||
/* ========================================================================
|
/** =======================================================================
|
||||||
* Bootstrap: collapse.js v3.3.2
|
* Bootstrap: collapse.js v4.0.0
|
||||||
* http://getbootstrap.com/javascript/#collapse
|
* http://getbootstrap.com/javascript/#collapse
|
||||||
* ========================================================================
|
* ========================================================================
|
||||||
* Copyright 2011-2015 Twitter, Inc.
|
* Copyright 2011-2015 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
* ======================================================================== */
|
* ========================================================================
|
||||||
|
* @fileoverview - Bootstrap's collapse plugin. Flexible support for
|
||||||
|
* collapsible components like accordions and navigation.
|
||||||
|
*
|
||||||
|
* Public Methods & Properties:
|
||||||
|
*
|
||||||
|
* + $.carousel
|
||||||
|
* + $.carousel.noConflict
|
||||||
|
* + $.carousel.Constructor
|
||||||
|
* + $.carousel.Constructor.VERSION
|
||||||
|
* + $.carousel.Constructor.Defaults
|
||||||
|
* + $.carousel.Constructor.Defaults.toggle
|
||||||
|
* + $.carousel.Constructor.Defaults.trigger
|
||||||
|
* + $.carousel.Constructor.Defaults.parent
|
||||||
|
* + $.carousel.Constructor.prototype.toggle
|
||||||
|
* + $.carousel.Constructor.prototype.show
|
||||||
|
* + $.carousel.Constructor.prototype.hide
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
+function ($) {
|
/**
|
||||||
'use strict';
|
* Our collapse class.
|
||||||
|
* @param {Element!} element
|
||||||
|
* @param {Object=} opt_config
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var Collapse = function (element, opt_config) {
|
||||||
|
|
||||||
// COLLAPSE PUBLIC CLASS DEFINITION
|
/** @private {Element} */
|
||||||
// ================================
|
this._element = element
|
||||||
|
|
||||||
var Collapse = function (element, options) {
|
/** @private {Object} */
|
||||||
this.$element = $(element)
|
this._config = $.extend({}, Collapse['Defaults'], opt_config)
|
||||||
this.options = $.extend({}, Collapse.DEFAULTS, options)
|
|
||||||
this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]')
|
|
||||||
this.transitioning = null
|
|
||||||
|
|
||||||
if (this.options.parent) {
|
/** @private {Element} */
|
||||||
this.$parent = this.getParent()
|
this._trigger = typeof this._config['trigger'] == 'string' ?
|
||||||
} else {
|
$(this._config['trigger'])[0] : this._config['trigger']
|
||||||
this.addAriaAndCollapsedClass(this.$element, this.$trigger)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.options.toggle) this.toggle()
|
/** @private {boolean} */
|
||||||
|
this._isTransitioning = false
|
||||||
|
|
||||||
|
/** @private {?Element} */
|
||||||
|
this._parent = this._config['parent'] ? this._getParent() : null
|
||||||
|
|
||||||
|
if (!this._config['parent']) {
|
||||||
|
this._addAriaAndCollapsedClass(this._element, this._trigger)
|
||||||
}
|
}
|
||||||
|
|
||||||
Collapse.VERSION = '3.3.2'
|
if (this._config['toggle']) {
|
||||||
|
this['toggle']()
|
||||||
Collapse.TRANSITION_DURATION = 350
|
|
||||||
|
|
||||||
Collapse.DEFAULTS = {
|
|
||||||
toggle: true,
|
|
||||||
trigger: '[data-toggle="collapse"]'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 $(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 $(target)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// COLLAPSE PLUGIN DEFINITION
|
/**
|
||||||
// ==========================
|
* @const
|
||||||
|
* @type {string}
|
||||||
function Plugin(option) {
|
*/
|
||||||
return this.each(function () {
|
Collapse['VERSION'] = '4.0.0'
|
||||||
var $this = $(this)
|
|
||||||
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) $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
|
/**
|
||||||
// ====================
|
* @const
|
||||||
|
* @type {Object}
|
||||||
$.fn.collapse.noConflict = function () {
|
*/
|
||||||
$.fn.collapse = old
|
Collapse['Defaults'] = {
|
||||||
return this
|
'toggle' : true,
|
||||||
}
|
'trigger' : '[data-toggle="collapse"]',
|
||||||
|
'parent' : null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// COLLAPSE DATA-API
|
/**
|
||||||
// =================
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse._NAME = 'collapse'
|
||||||
|
|
||||||
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse._DATA_KEY = 'bs.collapse'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse._TRANSITION_DURATION = 600
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse._JQUERY_NO_CONFLICT = $.fn[Collapse._NAME]
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse._Event = {
|
||||||
|
SHOW : 'show.bs.collapse',
|
||||||
|
SHOWN : 'shown.bs.collapse',
|
||||||
|
HIDE : 'hide.bs.collapse',
|
||||||
|
HIDDEN : 'hidden.bs.collapse'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse._ClassName = {
|
||||||
|
IN : 'in',
|
||||||
|
COLLAPSE : 'collapse',
|
||||||
|
COLLAPSING : 'collapsing',
|
||||||
|
COLLAPSED : 'collapsed'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse._Dimension = {
|
||||||
|
WIDTH : 'width',
|
||||||
|
HEIGHT : 'height'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse._Selector = {
|
||||||
|
ACTIVES : '.panel > .in, .panel > .collapsing'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the jQuery Interface for the alert component.
|
||||||
|
* @param {Object|string=} opt_config
|
||||||
|
* @this {jQuery}
|
||||||
|
* @return {jQuery}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse._jQueryInterface = function (opt_config) {
|
||||||
|
return this.each(function () {
|
||||||
var $this = $(this)
|
var $this = $(this)
|
||||||
|
var data = $this.data(Collapse._DATA_KEY)
|
||||||
|
var config = $.extend({}, Collapse['Defaults'], $this.data(), typeof opt_config == 'object' && opt_config)
|
||||||
|
|
||||||
if (!$this.attr('data-target')) e.preventDefault()
|
if (!data && config['toggle'] && opt_config == 'show') {
|
||||||
|
config['toggle'] = false
|
||||||
|
}
|
||||||
|
|
||||||
var $target = getTargetFromTrigger($this)
|
if (!data) {
|
||||||
var data = $target.data('bs.collapse')
|
data = new Collapse(this, config)
|
||||||
var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this })
|
$this.data(Collapse._DATA_KEY, data)
|
||||||
|
}
|
||||||
|
|
||||||
Plugin.call($target, option)
|
if (typeof opt_config == 'string') {
|
||||||
|
data[opt_config]()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}(jQuery);
|
|
||||||
|
/**
|
||||||
|
* Function for getting target element from element
|
||||||
|
* @return {Element}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse._getTargetFromElement = function (element) {
|
||||||
|
var selector = Bootstrap.getSelectorFromElement(element)
|
||||||
|
|
||||||
|
return selector ? $(selector)[0] : null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the collapse element based on the presence of the 'in' class
|
||||||
|
*/
|
||||||
|
Collapse.prototype['toggle'] = function () {
|
||||||
|
if ($(this._element).hasClass(Collapse._ClassName.IN)) {
|
||||||
|
this['hide']()
|
||||||
|
} else {
|
||||||
|
this['show']()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show's the collapsing element
|
||||||
|
*/
|
||||||
|
Collapse.prototype['show'] = function () {
|
||||||
|
if (this._isTransitioning || $(this._element).hasClass(Collapse._ClassName.IN)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var activesData, actives
|
||||||
|
|
||||||
|
if (this._parent) {
|
||||||
|
actives = $.makeArray($(Collapse._Selector.ACTIVES))
|
||||||
|
if (!actives.length) {
|
||||||
|
actives = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actives) {
|
||||||
|
activesData = $(actives).data(Collapse._DATA_KEY)
|
||||||
|
if (activesData && activesData._isTransitioning) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var startEvent = $.Event(Collapse._Event.SHOW)
|
||||||
|
$(this._element).trigger(startEvent)
|
||||||
|
if (startEvent.isDefaultPrevented()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actives) {
|
||||||
|
Collapse._jQueryInterface.call($(actives), 'hide')
|
||||||
|
if (!activesData) {
|
||||||
|
$(actives).data(Collapse._DATA_KEY, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var dimension = this._getDimension()
|
||||||
|
|
||||||
|
$(this._element)
|
||||||
|
.removeClass(Collapse._ClassName.COLLAPSE)
|
||||||
|
.addClass(Collapse._ClassName.COLLAPSING)
|
||||||
|
|
||||||
|
this._element.style[dimension] = 0
|
||||||
|
this._element.setAttribute('aria-expanded', true)
|
||||||
|
|
||||||
|
if (this._trigger) {
|
||||||
|
$(this._trigger).removeClass(Collapse._ClassName.COLLAPSED)
|
||||||
|
this._trigger.setAttribute('aria-expanded', true)
|
||||||
|
}
|
||||||
|
|
||||||
|
this['setTransitioning'](true)
|
||||||
|
|
||||||
|
var complete = function () {
|
||||||
|
$(this._element)
|
||||||
|
.removeClass(Collapse._ClassName.COLLAPSING)
|
||||||
|
.addClass(Collapse._ClassName.COLLAPSE)
|
||||||
|
.addClass(Collapse._ClassName.IN)
|
||||||
|
|
||||||
|
this._element.style[dimension] = ''
|
||||||
|
|
||||||
|
this['setTransitioning'](false)
|
||||||
|
|
||||||
|
$(this._element).trigger(Collapse._Event.SHOWN)
|
||||||
|
}.bind(this)
|
||||||
|
|
||||||
|
if (!Bootstrap.transition) {
|
||||||
|
complete()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var scrollSize = 'scroll' + (dimension[0].toUpperCase() + dimension.slice(1))
|
||||||
|
|
||||||
|
$(this._element)
|
||||||
|
.one(Bootstrap.TRANSITION_END, complete)
|
||||||
|
.emulateTransitionEnd(Collapse._TRANSITION_DURATION)
|
||||||
|
|
||||||
|
this._element.style[dimension] = this._element[scrollSize] + 'px'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides's the collapsing element
|
||||||
|
*/
|
||||||
|
Collapse.prototype['hide'] = function () {
|
||||||
|
if (this._isTransitioning || !$(this._element).hasClass(Collapse._ClassName.IN)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var startEvent = $.Event(Collapse._Event.HIDE)
|
||||||
|
$(this._element).trigger(startEvent)
|
||||||
|
if (startEvent.isDefaultPrevented()) return
|
||||||
|
|
||||||
|
var dimension = this._getDimension()
|
||||||
|
var offsetDimension = dimension === Collapse._Dimension.WIDTH ?
|
||||||
|
'offsetWidth' : 'offsetHeight'
|
||||||
|
|
||||||
|
this._element.style[dimension] = this._element[offsetDimension] + 'px'
|
||||||
|
|
||||||
|
Bootstrap.reflow(this._element)
|
||||||
|
|
||||||
|
$(this._element)
|
||||||
|
.addClass(Collapse._ClassName.COLLAPSING)
|
||||||
|
.removeClass(Collapse._ClassName.COLLAPSE)
|
||||||
|
.removeClass(Collapse._ClassName.IN)
|
||||||
|
|
||||||
|
this._element.setAttribute('aria-expanded', false)
|
||||||
|
|
||||||
|
if (this._trigger) {
|
||||||
|
$(this._trigger).addClass(Collapse._ClassName.COLLAPSED)
|
||||||
|
this._trigger.setAttribute('aria-expanded', false)
|
||||||
|
}
|
||||||
|
|
||||||
|
this['setTransitioning'](true)
|
||||||
|
|
||||||
|
var complete = function () {
|
||||||
|
this['setTransitioning'](false)
|
||||||
|
$(this._element)
|
||||||
|
.removeClass(Collapse._ClassName.COLLAPSING)
|
||||||
|
.addClass(Collapse._ClassName.COLLAPSE)
|
||||||
|
.trigger(Collapse._Event.HIDDEN)
|
||||||
|
|
||||||
|
}.bind(this)
|
||||||
|
|
||||||
|
this._element.style[dimension] = 0
|
||||||
|
|
||||||
|
if (!Bootstrap.transition) {
|
||||||
|
return complete()
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this._element)
|
||||||
|
.one(Bootstrap.TRANSITION_END, complete)
|
||||||
|
.emulateTransitionEnd(Collapse._TRANSITION_DURATION)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} isTransitioning
|
||||||
|
*/
|
||||||
|
Collapse.prototype['setTransitioning'] = function (isTransitioning) {
|
||||||
|
this._isTransitioning = isTransitioning
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the collapsing dimension
|
||||||
|
* @return {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse.prototype._getDimension = function () {
|
||||||
|
var hasWidth = $(this._element).hasClass(Collapse._Dimension.WIDTH)
|
||||||
|
return hasWidth ? Collapse._Dimension.WIDTH : Collapse._Dimension.HEIGHT
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the parent element
|
||||||
|
* @return {Element}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse.prototype._getParent = function () {
|
||||||
|
var selector = '[data-toggle="collapse"][data-parent="' + this._config['parent'] + '"]'
|
||||||
|
var parent = $(this._config['parent'])[0]
|
||||||
|
var elements = /** @type {Array.<Element>} */ ($.makeArray($(parent).find(selector)))
|
||||||
|
|
||||||
|
for (var i = 0; i < elements.length; i++) {
|
||||||
|
this._addAriaAndCollapsedClass(Collapse._getTargetFromElement(elements[i]), elements[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the parent element
|
||||||
|
* @param {Element} element
|
||||||
|
* @param {Element} trigger
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Collapse.prototype._addAriaAndCollapsedClass = function (element, trigger) {
|
||||||
|
if (element) {
|
||||||
|
var isOpen = $(element).hasClass(Collapse._ClassName.IN)
|
||||||
|
element.setAttribute('aria-expanded', isOpen)
|
||||||
|
|
||||||
|
if (trigger) {
|
||||||
|
trigger.setAttribute('aria-expanded', isOpen)
|
||||||
|
$(trigger).toggleClass(Collapse._ClassName.COLLAPSED, !isOpen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* jQuery Interface + noConflict implementaiton
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Collapse._NAME] = Collapse._jQueryInterface
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Collapse._NAME]['Constructor'] = Collapse
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Collapse._NAME]['noConflict'] = function () {
|
||||||
|
$.fn[Collapse._NAME] = Collapse._JQUERY_NO_CONFLICT
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* Data Api implementation
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (event) {
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
var target = Collapse._getTargetFromElement(this)
|
||||||
|
|
||||||
|
var data = $(target).data(Collapse._DATA_KEY)
|
||||||
|
var config = data ? 'toggle' : $.extend({}, $(this).data(), { trigger: this })
|
||||||
|
|
||||||
|
Collapse._jQueryInterface.call($(target), config)
|
||||||
|
})
|
||||||
|
403
js/dropdown.js
403
js/dropdown.js
@ -1,161 +1,322 @@
|
|||||||
/* ========================================================================
|
/** =======================================================================
|
||||||
* Bootstrap: dropdown.js v3.3.2
|
* Bootstrap: dropdown.js v4.0.0
|
||||||
* http://getbootstrap.com/javascript/#dropdowns
|
* http://getbootstrap.com/javascript/#dropdown
|
||||||
* ========================================================================
|
* ========================================================================
|
||||||
* Copyright 2011-2015 Twitter, Inc.
|
* Copyright 2011-2015 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
* ======================================================================== */
|
* ========================================================================
|
||||||
|
* @fileoverview - Add dropdown menus to nearly anything with this simple
|
||||||
|
* plugin, including the navbar, tabs, and pills.
|
||||||
|
*
|
||||||
|
* Public Methods & Properties:
|
||||||
|
*
|
||||||
|
* + $.dropdown
|
||||||
|
* + $.dropdown.noConflict
|
||||||
|
* + $.dropdown.Constructor
|
||||||
|
* + $.dropdown.Constructor.VERSION
|
||||||
|
* + $.dropdown.Constructor.prototype.toggle
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
+function ($) {
|
/**
|
||||||
'use strict';
|
* Our dropdown class.
|
||||||
|
* @param {Element!} element
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var Dropdown = function (element) {
|
||||||
|
$(element).on('click.bs.dropdown', this['toggle'])
|
||||||
|
}
|
||||||
|
|
||||||
// DROPDOWN CLASS DEFINITION
|
|
||||||
// =========================
|
|
||||||
|
|
||||||
var backdrop = '.dropdown-backdrop'
|
/**
|
||||||
var toggle = '[data-toggle="dropdown"]'
|
* @const
|
||||||
var Dropdown = function (element) {
|
* @type {string}
|
||||||
$(element).on('click.bs.dropdown', this.toggle)
|
*/
|
||||||
}
|
Dropdown['VERSION'] = '4.0.0'
|
||||||
|
|
||||||
Dropdown.VERSION = '3.3.2'
|
|
||||||
|
|
||||||
Dropdown.prototype.toggle = function (e) {
|
/**
|
||||||
var $this = $(this)
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Dropdown._NAME = 'dropdown'
|
||||||
|
|
||||||
if ($this.is('.disabled, :disabled')) return
|
|
||||||
|
|
||||||
var $parent = getParent($this)
|
/**
|
||||||
var isActive = $parent.hasClass('open')
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Dropdown._DATA_KEY = 'bs.dropdown'
|
||||||
|
|
||||||
clearMenus()
|
|
||||||
|
|
||||||
if (!isActive) {
|
/**
|
||||||
if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
|
* @const
|
||||||
// if mobile we use a backdrop because click events don't delegate
|
* @type {Function}
|
||||||
$('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
|
* @private
|
||||||
}
|
*/
|
||||||
|
Dropdown._JQUERY_NO_CONFLICT = $.fn[Dropdown._NAME]
|
||||||
|
|
||||||
var relatedTarget = { relatedTarget: this }
|
|
||||||
$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
|
|
||||||
|
|
||||||
if (e.isDefaultPrevented()) return
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Dropdown._Event = {
|
||||||
|
HIDE : 'hide.bs.dropdown',
|
||||||
|
HIDDEN : 'hidden.bs.dropdown',
|
||||||
|
SHOW : 'show.bs.dropdown',
|
||||||
|
SHOWN : 'shown.bs.dropdown'
|
||||||
|
}
|
||||||
|
|
||||||
$this
|
|
||||||
.trigger('focus')
|
|
||||||
.attr('aria-expanded', 'true')
|
|
||||||
|
|
||||||
$parent
|
/**
|
||||||
.toggleClass('open')
|
* @const
|
||||||
.trigger('shown.bs.dropdown', relatedTarget)
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Dropdown._ClassName = {
|
||||||
|
BACKDROP : 'dropdown-backdrop',
|
||||||
|
DISABLED : 'disabled',
|
||||||
|
OPEN : 'open'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Dropdown._Selector = {
|
||||||
|
BACKDROP : '.dropdown-backdrop',
|
||||||
|
DATA_TOGGLE : '[data-toggle="dropdown"]',
|
||||||
|
FORM_CHILD : '.dropdown form',
|
||||||
|
ROLE_MENU : '[role="menu"]',
|
||||||
|
ROLE_LISTBOX : '[role="listbox"]',
|
||||||
|
NAVBAR_NAV : '.navbar-nav',
|
||||||
|
VISIBLE_ITEMS : '[role="menu"] li:not(.divider) a, [role="listbox"] li:not(.divider) a'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the jQuery Interface for the alert component.
|
||||||
|
* @param {string=} opt_config
|
||||||
|
* @this {jQuery}
|
||||||
|
* @return {jQuery}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Dropdown._jQueryInterface = function (opt_config) {
|
||||||
|
return this.each(function () {
|
||||||
|
var data = $(this).data(Dropdown._DATA_KEY)
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
$(this).data(Dropdown._DATA_KEY, (data = new Dropdown(this)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof opt_config === 'string') {
|
||||||
|
data[opt_config].call(this)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Event=} opt_event
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Dropdown._clearMenus = function (opt_event) {
|
||||||
|
if (opt_event && opt_event.which == 3) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var backdrop = $(Dropdown._Selector.BACKDROP)[0]
|
||||||
|
if (backdrop) {
|
||||||
|
backdrop.parentNode.removeChild(backdrop)
|
||||||
|
}
|
||||||
|
|
||||||
|
var toggles = /** @type {Array.<Element>} */ ($.makeArray($(Dropdown._Selector.DATA_TOGGLE)))
|
||||||
|
|
||||||
|
for (var i = 0; i < toggles.length; i++) {
|
||||||
|
var parent = Dropdown._getParentFromElement(toggles[i])
|
||||||
|
var relatedTarget = { 'relatedTarget': toggles[i] }
|
||||||
|
|
||||||
|
if (!$(parent).hasClass(Dropdown._ClassName.OPEN)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var hideEvent = $.Event(Dropdown._Event.HIDE, relatedTarget)
|
||||||
|
$(parent).trigger(hideEvent)
|
||||||
|
if (hideEvent.isDefaultPrevented()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
toggles[i].setAttribute('aria-expanded', 'false')
|
||||||
|
|
||||||
|
$(parent)
|
||||||
|
.removeClass(Dropdown._ClassName.OPEN)
|
||||||
|
.trigger(Dropdown._Event.HIDDEN, relatedTarget)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Element} element
|
||||||
|
* @return {Element}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Dropdown._getParentFromElement = function (element) {
|
||||||
|
var selector = Bootstrap.getSelectorFromElement(element)
|
||||||
|
|
||||||
|
if (selector) {
|
||||||
|
var parent = $(selector)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
return /** @type {Element} */ (parent || element.parentNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Event} event
|
||||||
|
* @this {Element}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Dropdown._dataApiKeydownHandler = function (event) {
|
||||||
|
if (!/(38|40|27|32)/.test(event.which) || /input|textarea/i.test(event.target.tagName)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
event.preventDefault()
|
||||||
|
event.stopPropagation()
|
||||||
|
|
||||||
|
if (this.disabled || $(this).hasClass(Dropdown._ClassName.DISABLED)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var parent = Dropdown._getParentFromElement(this)
|
||||||
|
var isActive = $(parent).hasClass(Dropdown._ClassName.OPEN)
|
||||||
|
|
||||||
|
if ((!isActive && event.which != 27) || (isActive && event.which == 27)) {
|
||||||
|
if (event.which == 27) {
|
||||||
|
var toggle = $(parent).find(Dropdown._Selector.DATA_TOGGLE)[0]
|
||||||
|
$(toggle).trigger('focus')
|
||||||
|
}
|
||||||
|
$(this).trigger('click')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = $.makeArray($(Dropdown._Selector.VISIBLE_ITEMS))
|
||||||
|
|
||||||
|
items = items.filter(function (item) {
|
||||||
|
return item.offsetWidth || item.offsetHeight
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!items.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = items.indexOf(event.target)
|
||||||
|
|
||||||
|
if (event.which == 38 && index > 0) index-- // up
|
||||||
|
if (event.which == 40 && index < items.length - 1) index++ // down
|
||||||
|
if (!~index) index = 0
|
||||||
|
|
||||||
|
items[index].focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the dropdown
|
||||||
|
* @this {Element}
|
||||||
|
* @return {boolean|undefined}
|
||||||
|
*/
|
||||||
|
Dropdown.prototype['toggle'] = function () {
|
||||||
|
if (this.disabled || $(this).hasClass(Dropdown._ClassName.DISABLED)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var parent = Dropdown._getParentFromElement(this)
|
||||||
|
var isActive = $(parent).hasClass(Dropdown._ClassName.OPEN)
|
||||||
|
|
||||||
|
Dropdown._clearMenus()
|
||||||
|
|
||||||
|
if (isActive) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
Dropdown.prototype.keydown = function (e) {
|
if ('ontouchstart' in document.documentElement && !$(parent).closest(Dropdown._Selector.NAVBAR_NAV).length) {
|
||||||
if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
|
// if mobile we use a backdrop because click events don't delegate
|
||||||
|
var dropdown = document.createElement('div')
|
||||||
var $this = $(this)
|
dropdown.className = Dropdown._ClassName.BACKDROP
|
||||||
|
this.parentNode.insertBefore(this, dropdown)
|
||||||
e.preventDefault()
|
$(dropdown).on('click', Dropdown._clearMenus)
|
||||||
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(.divider):visible a'
|
|
||||||
var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + 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')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearMenus(e) {
|
var relatedTarget = { 'relatedTarget': this }
|
||||||
if (e && e.which === 3) return
|
var showEvent = $.Event(Dropdown._Event.SHOW, relatedTarget)
|
||||||
$(backdrop).remove()
|
|
||||||
$(toggle).each(function () {
|
|
||||||
var $this = $(this)
|
|
||||||
var $parent = getParent($this)
|
|
||||||
var relatedTarget = { relatedTarget: this }
|
|
||||||
|
|
||||||
if (!$parent.hasClass('open')) return
|
$(parent).trigger(showEvent)
|
||||||
|
|
||||||
$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
|
if (showEvent.isDefaultPrevented()) {
|
||||||
|
return
|
||||||
if (e.isDefaultPrevented()) return
|
|
||||||
|
|
||||||
$this.attr('aria-expanded', 'false')
|
|
||||||
$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getParent($this) {
|
this.focus()
|
||||||
var selector = $this.attr('data-target')
|
this.setAttribute('aria-expanded', 'true')
|
||||||
|
|
||||||
if (!selector) {
|
$(parent).toggleClass(Dropdown._ClassName.OPEN)
|
||||||
selector = $this.attr('href')
|
|
||||||
selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
|
||||||
}
|
|
||||||
|
|
||||||
var $parent = selector && $(selector)
|
$(parent).trigger(Dropdown._Event.SHOWN, relatedTarget)
|
||||||
|
|
||||||
return $parent && $parent.length ? $parent : $this.parent()
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// DROPDOWN PLUGIN DEFINITION
|
/**
|
||||||
// ==========================
|
* ------------------------------------------------------------------------
|
||||||
|
* jQuery Interface + noConflict implementaiton
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
function Plugin(option) {
|
/**
|
||||||
return this.each(function () {
|
* @const
|
||||||
var $this = $(this)
|
* @type {Function}
|
||||||
var data = $this.data('bs.dropdown')
|
*/
|
||||||
|
$.fn[Dropdown._NAME] = Dropdown._jQueryInterface
|
||||||
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
|
/**
|
||||||
// ====================
|
* @const
|
||||||
|
* @type {Function}
|
||||||
$.fn.dropdown.noConflict = function () {
|
*/
|
||||||
$.fn.dropdown = old
|
$.fn[Dropdown._NAME]['Constructor'] = Dropdown
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// APPLY TO STANDARD DROPDOWN ELEMENTS
|
/**
|
||||||
// ===================================
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Dropdown._NAME]['noConflict'] = function () {
|
||||||
|
$.fn[Dropdown._NAME] = Dropdown._JQUERY_NO_CONFLICT
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
$(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', '[role="menu"]', Dropdown.prototype.keydown)
|
|
||||||
.on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)
|
|
||||||
|
|
||||||
}(jQuery);
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* Data Api implementation
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
$(document)
|
||||||
|
.on('click.bs.dropdown.data-api', Dropdown._clearMenus)
|
||||||
|
.on('click.bs.dropdown.data-api', Dropdown._Selector.FORM_CHILD, function (e) { e.stopPropagation() })
|
||||||
|
.on('click.bs.dropdown.data-api', Dropdown._Selector.DATA_TOGGLE, Dropdown.prototype['toggle'])
|
||||||
|
.on('keydown.bs.dropdown.data-api', Dropdown._Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler)
|
||||||
|
.on('keydown.bs.dropdown.data-api', Dropdown._Selector.ROLE_MENU, Dropdown._dataApiKeydownHandler)
|
||||||
|
.on('keydown.bs.dropdown.data-api', Dropdown._Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler)
|
||||||
|
6
js/externs/bootstrap.js
vendored
Normal file
6
js/externs/bootstrap.js
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
jQuery.event.prototype.handleObj = function () {}
|
||||||
|
jQuery.event.prototype.handleObj.handler = function () {}
|
||||||
|
$.event.special = function () {}
|
||||||
|
$.event.trueHover = true
|
||||||
|
$.offset = {}
|
||||||
|
$.offset.setOffset = function (a,b,c) {}
|
2159
js/externs/jQuery.js
Normal file
2159
js/externs/jQuery.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,4 +0,0 @@
|
|||||||
$(document).on('mq4hsChange', function (e) {
|
|
||||||
'use strict';
|
|
||||||
$(document.documentElement).toggleClass('bs-true-hover', e.trueHover);
|
|
||||||
});
|
|
894
js/modal.js
894
js/modal.js
@ -1,324 +1,598 @@
|
|||||||
/* ========================================================================
|
/** =======================================================================
|
||||||
* Bootstrap: modal.js v3.3.2
|
* Bootstrap: modal.js v4.0.0
|
||||||
* http://getbootstrap.com/javascript/#modals
|
* http://getbootstrap.com/javascript/#modal
|
||||||
* ========================================================================
|
* ========================================================================
|
||||||
* Copyright 2011-2015 Twitter, Inc.
|
* Copyright 2011-2015 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
* ======================================================================== */
|
* ========================================================================
|
||||||
|
* @fileoverview - Bootstrap's modal plugin. Modals are streamlined, but
|
||||||
|
* flexible, dialog prompts with the minimum required functionality and
|
||||||
|
* smart defaults.
|
||||||
|
*
|
||||||
|
* Public Methods & Properties:
|
||||||
|
*
|
||||||
|
* + $.modal
|
||||||
|
* + $.modal.noConflict
|
||||||
|
* + $.modal.Constructor
|
||||||
|
* + $.modal.Constructor.VERSION
|
||||||
|
* + $.modal.Constructor.Defaults
|
||||||
|
* + $.modal.Constructor.Defaults.backdrop
|
||||||
|
* + $.modal.Constructor.Defaults.keyboard
|
||||||
|
* + $.modal.Constructor.Defaults.show
|
||||||
|
* + $.modal.Constructor.prototype.toggle
|
||||||
|
* + $.modal.Constructor.prototype.show
|
||||||
|
* + $.modal.Constructor.prototype.hide
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
+function ($) {
|
/**
|
||||||
'use strict';
|
* Our modal class.
|
||||||
|
* @param {Element} element
|
||||||
|
* @param {Object} config
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var Modal = function (element, config) {
|
||||||
|
|
||||||
// MODAL CLASS DEFINITION
|
/** @private {Object} */
|
||||||
// ======================
|
this._config = config
|
||||||
|
|
||||||
var Modal = function (element, options) {
|
/** @private {Element} */
|
||||||
this.options = options
|
this._element = element
|
||||||
this.$body = $(document.body)
|
|
||||||
this.$element = $(element)
|
|
||||||
this.$backdrop =
|
|
||||||
this.isShown = null
|
|
||||||
this.scrollbarWidth = 0
|
|
||||||
|
|
||||||
if (this.options.remote) {
|
/** @private {Element} */
|
||||||
this.$element
|
this._backdrop = null
|
||||||
.find('.modal-content')
|
|
||||||
.load(this.options.remote, $.proxy(function () {
|
/** @private {boolean} */
|
||||||
this.$element.trigger('loaded.bs.modal')
|
this._isShown = false
|
||||||
}, this))
|
|
||||||
|
/** @private {boolean} */
|
||||||
|
this._isBodyOverflowing = false
|
||||||
|
|
||||||
|
/** @private {number} */
|
||||||
|
this._scrollbarWidth = 0
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
Modal['VERSION'] = '4.0.0'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
Modal['Defaults'] = {
|
||||||
|
'backdrop' : true,
|
||||||
|
'keyboard' : true,
|
||||||
|
'show' : true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal._NAME = 'modal'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal._DATA_KEY = 'bs.modal'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal._TRANSITION_DURATION = 300
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal._BACKDROP_TRANSITION_DURATION = 150
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal._JQUERY_NO_CONFLICT = $.fn[Modal._NAME]
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal._Event = {
|
||||||
|
HIDE : 'hide.bs.modal',
|
||||||
|
HIDDEN : 'hidden.bs.modal',
|
||||||
|
SHOW : 'show.bs.modal',
|
||||||
|
SHOWN : 'shown.bs.modal'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal._ClassName = {
|
||||||
|
BACKDROP : 'modal-backdrop',
|
||||||
|
OPEN : 'modal-open',
|
||||||
|
FADE : 'fade',
|
||||||
|
IN : 'in'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal._Selector = {
|
||||||
|
DIALOG : '.modal-dialog',
|
||||||
|
DATA_TOGGLE : '[data-toggle="modal"]',
|
||||||
|
DATA_DISMISS : '[data-dismiss="modal"]',
|
||||||
|
SCROLLBAR_MEASURER : 'modal-scrollbar-measure'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the jQuery Interface for the alert component.
|
||||||
|
* @param {Object|string=} opt_config
|
||||||
|
* @param {Element=} opt_relatedTarget
|
||||||
|
* @this {jQuery}
|
||||||
|
* @return {jQuery}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal._jQueryInterface = function Plugin(opt_config, opt_relatedTarget) {
|
||||||
|
return this.each(function () {
|
||||||
|
var data = $(this).data(Modal._DATA_KEY)
|
||||||
|
var config = $.extend({}, Modal['Defaults'], $(this).data(), typeof opt_config == 'object' && opt_config)
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
data = new Modal(this, config)
|
||||||
|
$(this).data(Modal._DATA_KEY, data)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Modal.VERSION = '3.3.2'
|
if (typeof opt_config == 'string') {
|
||||||
|
data[opt_config](opt_relatedTarget)
|
||||||
|
|
||||||
Modal.TRANSITION_DURATION = 300
|
} else if (config['show']) {
|
||||||
Modal.BACKDROP_TRANSITION_DURATION = 150
|
data['show'](opt_relatedTarget)
|
||||||
|
|
||||||
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.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)
|
|
||||||
|
|
||||||
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.enforceFocus()
|
|
||||||
|
|
||||||
var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
|
|
||||||
|
|
||||||
transition ?
|
|
||||||
that.$element.find('.modal-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')
|
|
||||||
.attr('aria-hidden', true)
|
|
||||||
.off('click.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 (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 = $('<div class="modal-backdrop ' + animate + '" />')
|
|
||||||
.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))
|
|
||||||
|
|
||||||
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 () {
|
|
||||||
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 : '',
|
|
||||||
paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Modal.prototype.resetAdjustments = function () {
|
|
||||||
this.$element.css({
|
|
||||||
paddingLeft: '',
|
|
||||||
paddingRight: ''
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Modal.prototype.checkScrollbar = function () {
|
|
||||||
this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
Modal.prototype.resetScrollbar = function () {
|
|
||||||
this.$body.css('padding-right', '')
|
|
||||||
}
|
|
||||||
|
|
||||||
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 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);
|
|
||||||
|
/**
|
||||||
|
* @param {Element} relatedTarget
|
||||||
|
*/
|
||||||
|
Modal.prototype['toggle'] = function (relatedTarget) {
|
||||||
|
return this._isShown ? this['hide']() : this['show'](relatedTarget)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Element} relatedTarget
|
||||||
|
*/
|
||||||
|
Modal.prototype['show'] = function (relatedTarget) {
|
||||||
|
var showEvent = $.Event(Modal._Event.SHOW, { relatedTarget: relatedTarget })
|
||||||
|
|
||||||
|
$(this._element).trigger(showEvent)
|
||||||
|
|
||||||
|
if (this._isShown || showEvent.isDefaultPrevented()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this._isShown = true
|
||||||
|
|
||||||
|
this._checkScrollbar()
|
||||||
|
this._setScrollbar()
|
||||||
|
|
||||||
|
$(document.body).addClass(Modal._ClassName.OPEN)
|
||||||
|
|
||||||
|
this._escape()
|
||||||
|
this._resize()
|
||||||
|
|
||||||
|
$(this._element).on('click.dismiss.bs.modal', Modal._Selector.DATA_DISMISS, this['hide'].bind(this))
|
||||||
|
|
||||||
|
this._showBackdrop(this._showElement.bind(this, relatedTarget))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Event} event
|
||||||
|
*/
|
||||||
|
Modal.prototype['hide'] = function (event) {
|
||||||
|
if (event) {
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
var hideEvent = $.Event(Modal._Event.HIDE)
|
||||||
|
|
||||||
|
$(this._element).trigger(hideEvent)
|
||||||
|
|
||||||
|
if (!this._isShown || hideEvent.isDefaultPrevented()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this._isShown = false
|
||||||
|
|
||||||
|
this._escape()
|
||||||
|
this._resize()
|
||||||
|
|
||||||
|
$(document).off('focusin.bs.modal')
|
||||||
|
|
||||||
|
$(this._element).removeClass(Modal._ClassName.IN)
|
||||||
|
this._element.setAttribute('aria-hidden', true)
|
||||||
|
|
||||||
|
$(this._element).off('click.dismiss.bs.modal')
|
||||||
|
|
||||||
|
if (Bootstrap.transition && $(this._element).hasClass(Modal._ClassName.FADE)) {
|
||||||
|
$(this._element)
|
||||||
|
.one(Bootstrap.TRANSITION_END, this._hideModal.bind(this))
|
||||||
|
.emulateTransitionEnd(Modal._TRANSITION_DURATION)
|
||||||
|
} else {
|
||||||
|
this._hideModal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Element} relatedTarget
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._showElement = function (relatedTarget) {
|
||||||
|
var transition = Bootstrap.transition && $(this._element).hasClass(Modal._ClassName.FADE)
|
||||||
|
|
||||||
|
if (!this._element.parentNode || this._element.parentNode.nodeType != Node.ELEMENT_NODE) {
|
||||||
|
document.body.appendChild(this._element) // don't move modals dom position
|
||||||
|
}
|
||||||
|
|
||||||
|
this._element.style.display = 'block'
|
||||||
|
this._element.scrollTop = 0
|
||||||
|
|
||||||
|
if (this._config['backdrop']) {
|
||||||
|
this._adjustBackdrop()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transition) {
|
||||||
|
Bootstrap.reflow(this._element)
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this._element).addClass(Modal._ClassName.IN)
|
||||||
|
this._element.setAttribute('aria-hidden', false)
|
||||||
|
|
||||||
|
this._enforceFocus()
|
||||||
|
|
||||||
|
var shownEvent = $.Event(Modal._Event.SHOWN, { relatedTarget: relatedTarget })
|
||||||
|
|
||||||
|
var transitionComplete = function () {
|
||||||
|
this._element.focus()
|
||||||
|
$(this._element).trigger(shownEvent)
|
||||||
|
}.bind(this)
|
||||||
|
|
||||||
|
if (transition) {
|
||||||
|
var dialog = $(this._element).find(Modal._Selector.DIALOG)[0]
|
||||||
|
$(dialog)
|
||||||
|
.one(Bootstrap.TRANSITION_END, transitionComplete)
|
||||||
|
.emulateTransitionEnd(Modal._TRANSITION_DURATION)
|
||||||
|
} else {
|
||||||
|
transitionComplete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._enforceFocus = function () {
|
||||||
|
$(document)
|
||||||
|
.off('focusin.bs.modal') // guard against infinite focus loop
|
||||||
|
.on('focusin.bs.modal', function (e) {
|
||||||
|
if (this._element !== e.target && !$(this._element).has(e.target).length) {
|
||||||
|
this._element.focus()
|
||||||
|
}
|
||||||
|
}.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._escape = function () {
|
||||||
|
if (this._isShown && this._config['keyboard']) {
|
||||||
|
$(this._element).on('keydown.dismiss.bs.modal', function (event) {
|
||||||
|
if (event.which === 27) {
|
||||||
|
this['hide']()
|
||||||
|
}
|
||||||
|
}.bind(this))
|
||||||
|
|
||||||
|
} else if (!this._isShown) {
|
||||||
|
$(this._element).off('keydown.dismiss.bs.modal')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._resize = function () {
|
||||||
|
if (this._isShown) {
|
||||||
|
$(window).on('resize.bs.modal', this._handleUpdate.bind(this))
|
||||||
|
} else {
|
||||||
|
$(window).off('resize.bs.modal')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._hideModal = function () {
|
||||||
|
this._element.style.display = 'none'
|
||||||
|
this._showBackdrop(function () {
|
||||||
|
$(document.body).removeClass(Modal._ClassName.OPEN)
|
||||||
|
this._resetAdjustments()
|
||||||
|
this._resetScrollbar()
|
||||||
|
$(this._element).trigger(Modal._Event.HIDDEN)
|
||||||
|
}.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._removeBackdrop = function () {
|
||||||
|
if (this._backdrop) {
|
||||||
|
this._backdrop.parentNode.removeChild(this._backdrop)
|
||||||
|
this._backdrop = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Function} callback
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._showBackdrop = function (callback) {
|
||||||
|
var animate = $(this._element).hasClass(Modal._ClassName.FADE) ? Modal._ClassName.FADE : ''
|
||||||
|
|
||||||
|
if (this._isShown && this._config['backdrop']) {
|
||||||
|
var doAnimate = Bootstrap.transition && animate
|
||||||
|
|
||||||
|
this._backdrop = document.createElement('div')
|
||||||
|
this._backdrop.className = Modal._ClassName.BACKDROP
|
||||||
|
|
||||||
|
if (animate) {
|
||||||
|
$(this._backdrop).addClass(animate)
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this._element).prepend(this._backdrop)
|
||||||
|
|
||||||
|
$(this._backdrop).on('click.dismiss.bs.modal', function (event) {
|
||||||
|
if (event.target !== event.currentTarget) return
|
||||||
|
this._config['backdrop'] === 'static'
|
||||||
|
? this._element.focus()
|
||||||
|
: this['hide']()
|
||||||
|
}.bind(this))
|
||||||
|
|
||||||
|
if (doAnimate) {
|
||||||
|
Bootstrap.reflow(this._backdrop)
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this._backdrop).addClass(Modal._ClassName.IN)
|
||||||
|
|
||||||
|
if (!callback) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doAnimate) {
|
||||||
|
callback()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this._backdrop)
|
||||||
|
.one(Bootstrap.TRANSITION_END, callback)
|
||||||
|
.emulateTransitionEnd(Modal._BACKDROP_TRANSITION_DURATION)
|
||||||
|
|
||||||
|
} else if (!this._isShown && this._backdrop) {
|
||||||
|
$(this._backdrop).removeClass(Modal._ClassName.IN)
|
||||||
|
|
||||||
|
var callbackRemove = function () {
|
||||||
|
this._removeBackdrop()
|
||||||
|
if (callback) {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}.bind(this)
|
||||||
|
|
||||||
|
if (Bootstrap.transition && $(this._element).hasClass(Modal._ClassName.FADE)) {
|
||||||
|
$(this._backdrop)
|
||||||
|
.one(Bootstrap.TRANSITION_END, callbackRemove)
|
||||||
|
.emulateTransitionEnd(Modal._BACKDROP_TRANSITION_DURATION)
|
||||||
|
} else {
|
||||||
|
callbackRemove()
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (callback) {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* the following methods are used to handle overflowing modals
|
||||||
|
* todo (fat): these should probably be refactored into a
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._handleUpdate = function () {
|
||||||
|
if (this._config['backdrop']) this._adjustBackdrop()
|
||||||
|
this._adjustDialog()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._adjustBackdrop = function () {
|
||||||
|
this._backdrop.style.height = 0 // todo (fat): no clue why we do this
|
||||||
|
this._backdrop.style.height = this._element.scrollHeight + 'px'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._adjustDialog = function () {
|
||||||
|
var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight
|
||||||
|
|
||||||
|
if (!this._isBodyOverflowing && isModalOverflowing) {
|
||||||
|
this._element.style.paddingLeft = this._scrollbarWidth + 'px'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._isBodyOverflowing && !isModalOverflowing) {
|
||||||
|
this._element.style.paddingRight = this._scrollbarWidth + 'px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._resetAdjustments = function () {
|
||||||
|
this._element.style.paddingLeft = ''
|
||||||
|
this._element.style.paddingRight = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._checkScrollbar = function () {
|
||||||
|
this._isBodyOverflowing = document.body.scrollHeight > document.documentElement.clientHeight
|
||||||
|
this._scrollbarWidth = this._getScrollbarWidth()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._setScrollbar = function () {
|
||||||
|
var bodyPadding = parseInt(($(document.body).css('padding-right') || 0), 10)
|
||||||
|
|
||||||
|
if (this._isBodyOverflowing) {
|
||||||
|
document.body.style.paddingRight = bodyPadding + this._scrollbarWidth + 'px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._resetScrollbar = function () {
|
||||||
|
document.body.style.paddingRight = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Modal.prototype._getScrollbarWidth = function () { // thx walsh
|
||||||
|
var scrollDiv = document.createElement('div')
|
||||||
|
scrollDiv.className = Modal._Selector.SCROLLBAR_MEASURER
|
||||||
|
document.body.appendChild(scrollDiv)
|
||||||
|
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
|
||||||
|
document.body.removeChild(scrollDiv)
|
||||||
|
return scrollbarWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* jQuery Interface + noConflict implementaiton
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Modal._NAME] = Modal._jQueryInterface
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Modal._NAME]['Constructor'] = Modal
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Modal._NAME]['noConflict'] = function () {
|
||||||
|
$.fn[Modal._NAME] = Modal._JQUERY_NO_CONFLICT
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* Data Api implementation
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
$(document).on('click.bs.modal.data-api', Modal._Selector.DATA_TOGGLE, function (event) {
|
||||||
|
var selector = Bootstrap.getSelectorFromElement(this)
|
||||||
|
|
||||||
|
if (selector) {
|
||||||
|
var target = $(selector)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = $(target).data(Modal._DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data())
|
||||||
|
|
||||||
|
if (this.tagName == 'A') {
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
var $target = $(target).one(Modal._Event.SHOW, function (showEvent) {
|
||||||
|
if (showEvent.isDefaultPrevented()) {
|
||||||
|
return // only register focus restorer if modal will actually get shown
|
||||||
|
}
|
||||||
|
|
||||||
|
$target.one(Modal._Event.HIDDEN, function () {
|
||||||
|
if ($(this).is(':visible')) {
|
||||||
|
this.focus()
|
||||||
|
}
|
||||||
|
}.bind(this))
|
||||||
|
}.bind(this))
|
||||||
|
|
||||||
|
Modal._jQueryInterface.call($(target), config, this)
|
||||||
|
})
|
||||||
|
340
js/popover.js
340
js/popover.js
@ -1,113 +1,283 @@
|
|||||||
/* ========================================================================
|
/** =======================================================================
|
||||||
* Bootstrap: popover.js v3.3.2
|
* Bootstrap: popover.js v4.0.0
|
||||||
* http://getbootstrap.com/javascript/#popovers
|
* http://getbootstrap.com/javascript/#popovers
|
||||||
* ========================================================================
|
* ========================================================================
|
||||||
* Copyright 2011-2015 Twitter, Inc.
|
* Copyright 2011-2015 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
* ======================================================================== */
|
* ========================================================================
|
||||||
|
* @fileoverview - Bootstrap's popover plugin - extends tooltip.
|
||||||
|
*
|
||||||
|
* Public Methods & Properties:
|
||||||
|
*
|
||||||
|
* + $.popover
|
||||||
|
* + $.popover.noConflict
|
||||||
|
* + $.popover.Constructor
|
||||||
|
* + $.popover.Constructor.VERSION
|
||||||
|
* + $.popover.Constructor.Defaults
|
||||||
|
* + $.popover.Constructor.Defaults.container
|
||||||
|
* + $.popover.Constructor.Defaults.animation
|
||||||
|
* + $.popover.Constructor.Defaults.placement
|
||||||
|
* + $.popover.Constructor.Defaults.selector
|
||||||
|
* + $.popover.Constructor.Defaults.template
|
||||||
|
* + $.popover.Constructor.Defaults.trigger
|
||||||
|
* + $.popover.Constructor.Defaults.title
|
||||||
|
* + $.popover.Constructor.Defaults.content
|
||||||
|
* + $.popover.Constructor.Defaults.delay
|
||||||
|
* + $.popover.Constructor.Defaults.html
|
||||||
|
* + $.popover.Constructor.Defaults.viewport
|
||||||
|
* + $.popover.Constructor.Defaults.viewport.selector
|
||||||
|
* + $.popover.Constructor.Defaults.viewport.padding
|
||||||
|
* + $.popover.Constructor.prototype.enable
|
||||||
|
* + $.popover.Constructor.prototype.disable
|
||||||
|
* + $.popover.Constructor.prototype.destroy
|
||||||
|
* + $.popover.Constructor.prototype.toggleEnabled
|
||||||
|
* + $.popover.Constructor.prototype.toggle
|
||||||
|
* + $.popover.Constructor.prototype.show
|
||||||
|
* + $.popover.Constructor.prototype.hide
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
+function ($) {
|
'use strict';
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// POPOVER PUBLIC CLASS DEFINITION
|
|
||||||
// ===============================
|
|
||||||
|
|
||||||
var Popover = function (element, options) {
|
if (!Tooltip) throw new Error('Popover requires tooltip.js')
|
||||||
this.init('popover', element, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
|
|
||||||
|
|
||||||
Popover.VERSION = '3.3.2'
|
/**
|
||||||
|
* Our tooltip class.
|
||||||
|
* @param {Element!} element
|
||||||
|
* @param {Object=} opt_config
|
||||||
|
* @constructor
|
||||||
|
* @extends {Tooltip}
|
||||||
|
*/
|
||||||
|
var Popover = function (element, opt_config) {
|
||||||
|
Tooltip.apply(this, arguments)
|
||||||
|
}
|
||||||
|
Bootstrap.inherits(Popover, Tooltip)
|
||||||
|
|
||||||
Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
|
|
||||||
placement: 'right',
|
/**
|
||||||
trigger: 'click',
|
* @const
|
||||||
content: '',
|
* @type {string}
|
||||||
template: '<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
|
*/
|
||||||
|
Popover['VERSION'] = '4.0.0'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
Popover['Defaults'] = $.extend({}, $.fn['tooltip']['Constructor']['Defaults'], {
|
||||||
|
'placement': 'right',
|
||||||
|
'trigger': 'click',
|
||||||
|
'content': '',
|
||||||
|
'template': '<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Popover._NAME = 'popover'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Popover._DATA_KEY = 'bs.popover'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Popover._Event = {
|
||||||
|
HIDE : 'hide.bs.popover',
|
||||||
|
HIDDEN : 'hidden.bs.popover',
|
||||||
|
SHOW : 'show.bs.popover',
|
||||||
|
SHOWN : 'shown.bs.popover'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Popover._ClassName = {
|
||||||
|
FADE : 'fade',
|
||||||
|
IN : 'in'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Popover._Selector = {
|
||||||
|
TITLE : '.popover-title',
|
||||||
|
CONTENT : '.popover-content',
|
||||||
|
ARROW : '.popover-arrow'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Popover._JQUERY_NO_CONFLICT = $.fn[Popover._NAME]
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object|string=} opt_config
|
||||||
|
* @this {jQuery}
|
||||||
|
* @return {jQuery}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Popover._jQueryInterface = function (opt_config) {
|
||||||
|
return this.each(function () {
|
||||||
|
var data = $(this).data(Popover._DATA_KEY)
|
||||||
|
var config = typeof opt_config === 'object' ? opt_config : null
|
||||||
|
|
||||||
|
if (!data && opt_config === 'destroy') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
data = new Popover(this, config)
|
||||||
|
$(this).data(Popover._DATA_KEY, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof opt_config === 'string') {
|
||||||
|
data[opt_config]()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// NOTE: POPOVER EXTENDS tooltip.js
|
/**
|
||||||
// ================================
|
* @return {string}
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
Popover.prototype.getName = function () {
|
||||||
|
return Popover._NAME
|
||||||
|
}
|
||||||
|
|
||||||
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
|
|
||||||
|
|
||||||
Popover.prototype.constructor = Popover
|
/**
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
Popover.prototype.getDataKey = function () {
|
||||||
|
return Popover._DATA_KEY
|
||||||
|
}
|
||||||
|
|
||||||
Popover.prototype.getDefaults = function () {
|
|
||||||
return Popover.DEFAULTS
|
/**
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
Popover.prototype.getEventObject = function () {
|
||||||
|
return Popover._Event
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
Popover.prototype.getArrowElement = function () {
|
||||||
|
return (this.arrow = this.arrow || $(this.getTipElement()).find(Popover._Selector.ARROW)[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
Popover.prototype.setContent = function () {
|
||||||
|
var tip = this.getTipElement()
|
||||||
|
var title = this.getTitle()
|
||||||
|
var content = this._getContent()
|
||||||
|
var titleElement = $(tip).find(Popover._Selector.TITLE)[0]
|
||||||
|
|
||||||
|
if (titleElement) {
|
||||||
|
titleElement[this.config['html'] ? 'innerHTML' : 'innerText'] = title
|
||||||
}
|
}
|
||||||
|
|
||||||
Popover.prototype.setContent = function () {
|
// we use append for html objects to maintain js events
|
||||||
var $tip = this.tip()
|
$(tip).find(Popover._Selector.CONTENT).children().detach().end()[
|
||||||
var title = this.getTitle()
|
this.config['html'] ? (typeof content == 'string' ? 'html' : 'append') : 'text'
|
||||||
var content = this.getContent()
|
](content)
|
||||||
|
|
||||||
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
|
$(tip)
|
||||||
$tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
|
.removeClass(Popover._ClassName.FADE)
|
||||||
this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
|
.removeClass(Popover._ClassName.IN)
|
||||||
](content)
|
|
||||||
|
|
||||||
$tip.removeClass('fade popover-top popover-bottom popover-left popover-right in')
|
for (var direction in Tooltip.Direction) {
|
||||||
|
$(tip).removeClass(Popover._NAME + '-' + Tooltip.Direction[direction])
|
||||||
// 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('.popover-arrow'))
|
|
||||||
}
|
|
||||||
|
|
||||||
Popover.prototype.tip = function () {
|
|
||||||
if (!this.$tip) this.$tip = $(this.options.template)
|
|
||||||
return this.$tip
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// POPOVER PLUGIN DEFINITION
|
/**
|
||||||
// =========================
|
* @override
|
||||||
|
*/
|
||||||
function Plugin(option) {
|
Popover.prototype.isWithContent = function () {
|
||||||
return this.each(function () {
|
return this.getTitle() || this._getContent()
|
||||||
var $this = $(this)
|
}
|
||||||
var data = $this.data('bs.popover')
|
|
||||||
var options = typeof option == 'object' && option
|
|
||||||
|
|
||||||
if (!data && option == 'destroy') 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
|
/**
|
||||||
// ===================
|
* @override
|
||||||
|
*/
|
||||||
|
Popover.prototype.getTipElement = function () {
|
||||||
|
return (this.tip = this.tip || $(this.config['template'])[0])
|
||||||
|
}
|
||||||
|
|
||||||
$.fn.popover.noConflict = function () {
|
|
||||||
$.fn.popover = old
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
}(jQuery);
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Popover.prototype._getContent = function () {
|
||||||
|
return this.element.getAttribute('data-content')
|
||||||
|
|| (typeof this.config['content'] == 'function' ?
|
||||||
|
this.config['content'].call(this.element) :
|
||||||
|
this.config['content'])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* jQuery Interface + noConflict implementaiton
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Popover._NAME] = Popover._jQueryInterface
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Popover._NAME]['Constructor'] = Popover
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Popover._NAME]['noConflict'] = function () {
|
||||||
|
$.fn[Popover._NAME] = Popover._JQUERY_NO_CONFLICT
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
481
js/scrollspy.js
481
js/scrollspy.js
@ -1,175 +1,346 @@
|
|||||||
/* ========================================================================
|
/** =======================================================================
|
||||||
* Bootstrap: scrollspy.js v3.3.2
|
* Bootstrap: scrollspy.js v4.0.0
|
||||||
* http://getbootstrap.com/javascript/#scrollspy
|
* http://getbootstrap.com/javascript/#scrollspy
|
||||||
* ========================================================================
|
* ========================================================================
|
||||||
* Copyright 2011-2015 Twitter, Inc.
|
* Copyright 2011-2015 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
* ======================================================================== */
|
* ========================================================================
|
||||||
|
* @fileoverview - Bootstrap's scrollspy plugin.
|
||||||
|
*
|
||||||
|
* Public Methods & Properties:
|
||||||
|
*
|
||||||
|
* + $.scrollspy
|
||||||
|
* + $.scrollspy.noConflict
|
||||||
|
* + $.scrollspy.Constructor
|
||||||
|
* + $.scrollspy.Constructor.VERSION
|
||||||
|
* + $.scrollspy.Constructor.Defaults
|
||||||
|
* + $.scrollspy.Constructor.Defaults.offset
|
||||||
|
* + $.scrollspy.Constructor.prototype.refresh
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
+function ($) {
|
/**
|
||||||
'use strict';
|
* Our scrollspy class.
|
||||||
|
* @param {Element!} element
|
||||||
|
* @param {Object=} opt_config
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function ScrollSpy(element, opt_config) {
|
||||||
|
|
||||||
// SCROLLSPY CLASS DEFINITION
|
/** @private {Element|Window} */
|
||||||
// ==========================
|
this._scrollElement = element.tagName == 'BODY' ? window : element
|
||||||
|
|
||||||
function ScrollSpy(element, options) {
|
/** @private {Object} */
|
||||||
var process = $.proxy(this.process, this)
|
this._config = $.extend({}, ScrollSpy['Defaults'], opt_config)
|
||||||
|
|
||||||
this.$body = $('body')
|
/** @private {string} */
|
||||||
this.$scrollElement = $(element).is('body') ? $(window) : $(element)
|
this._selector = (this._config.target || '') + ' .nav li > a'
|
||||||
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', process)
|
/** @private {Array} */
|
||||||
this.refresh()
|
this._offsets = []
|
||||||
this.process()
|
|
||||||
}
|
|
||||||
|
|
||||||
ScrollSpy.VERSION = '3.3.2'
|
/** @private {Array} */
|
||||||
|
this._targets = []
|
||||||
|
|
||||||
ScrollSpy.DEFAULTS = {
|
/** @private {Element} */
|
||||||
offset: 10
|
this._activeTarget = null
|
||||||
}
|
|
||||||
|
|
||||||
ScrollSpy.prototype.getScrollHeight = function () {
|
/** @private {number} */
|
||||||
return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
|
this._scrollHeight = 0
|
||||||
}
|
|
||||||
|
|
||||||
ScrollSpy.prototype.refresh = function () {
|
$(this._scrollElement).on('scroll.bs.scrollspy', this._process.bind(this))
|
||||||
var offsetMethod = 'offset'
|
|
||||||
var offsetBase = 0
|
|
||||||
|
|
||||||
if (!$.isWindow(this.$scrollElement[0])) {
|
this['refresh']()
|
||||||
offsetMethod = 'position'
|
|
||||||
offsetBase = this.$scrollElement.scrollTop()
|
this._process()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ScrollSpy['VERSION'] = '4.0.0'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
ScrollSpy['Defaults'] = {
|
||||||
|
'offset': 10
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ScrollSpy._NAME = 'scrollspy'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ScrollSpy._DATA_KEY = 'bs.scrollspy'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ScrollSpy._JQUERY_NO_CONFLICT = $.fn[ScrollSpy._NAME]
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ScrollSpy._Event = {
|
||||||
|
ACTIVATE: 'activate.bs.scrollspy'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ScrollSpy._ClassName = {
|
||||||
|
DROPDOWN_MENU : 'dropdown-menu',
|
||||||
|
ACTIVE : 'active'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ScrollSpy._Selector = {
|
||||||
|
DATA_SPY : '[data-spy="scroll"]',
|
||||||
|
ACTIVE : '.active',
|
||||||
|
LI_DROPDOWN : 'li.dropdown',
|
||||||
|
LI : 'li'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object=} opt_config
|
||||||
|
* @this {jQuery}
|
||||||
|
* @return {jQuery}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ScrollSpy._jQueryInterface = function (opt_config) {
|
||||||
|
return this.each(function () {
|
||||||
|
var data = $(this).data(ScrollSpy._DATA_KEY)
|
||||||
|
var config = typeof opt_config === 'object' && opt_config || null
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
data = new ScrollSpy(this, config)
|
||||||
|
$(this).data(ScrollSpy._DATA_KEY, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.offsets = []
|
if (typeof opt_config === 'string') {
|
||||||
this.targets = []
|
data[opt_config]()
|
||||||
this.scrollHeight = this.getScrollHeight()
|
|
||||||
|
|
||||||
var self = this
|
|
||||||
|
|
||||||
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 () {
|
|
||||||
self.offsets.push(this[0])
|
|
||||||
self.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] || 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);
|
|
||||||
|
/**
|
||||||
|
* Refresh the scrollspy target cache
|
||||||
|
*/
|
||||||
|
ScrollSpy.prototype['refresh'] = function () {
|
||||||
|
var offsetMethod = 'offset'
|
||||||
|
var offsetBase = 0
|
||||||
|
|
||||||
|
if (this._scrollElement !== this._scrollElement.window) {
|
||||||
|
offsetMethod = 'position'
|
||||||
|
offsetBase = this._getScrollTop()
|
||||||
|
}
|
||||||
|
|
||||||
|
this._offsets = []
|
||||||
|
this._targets = []
|
||||||
|
|
||||||
|
this._scrollHeight = this._getScrollHeight()
|
||||||
|
|
||||||
|
var targets = /** @type {Array.<Element>} */ ($.makeArray($(this._selector)))
|
||||||
|
|
||||||
|
targets
|
||||||
|
.map(function (element, index) {
|
||||||
|
var target
|
||||||
|
var targetSelector = Bootstrap.getSelectorFromElement(element)
|
||||||
|
|
||||||
|
if (targetSelector) {
|
||||||
|
target = $(targetSelector)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target && (target.offsetWidth || target.offsetHeight)) {
|
||||||
|
// todo (fat): remove sketch reliance on jQuery position/offset
|
||||||
|
return [$(target)[offsetMethod]().top + offsetBase, targetSelector]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(function (item) { return item })
|
||||||
|
.sort(function (a, b) { return a[0] - b[0] })
|
||||||
|
.forEach(function (item, index) {
|
||||||
|
this._offsets.push(item[0])
|
||||||
|
this._targets.push(item[1])
|
||||||
|
}.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ScrollSpy.prototype._getScrollTop = function () {
|
||||||
|
return this._scrollElement === window ?
|
||||||
|
this._scrollElement.scrollY : this._scrollElement.scrollTop
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ScrollSpy.prototype._getScrollHeight = function () {
|
||||||
|
return this._scrollElement.scrollHeight
|
||||||
|
|| Math.max(document.body.scrollHeight, document.documentElement.scrollHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ScrollSpy.prototype._process = function () {
|
||||||
|
var scrollTop = this._getScrollTop() + this._config.offset
|
||||||
|
var scrollHeight = this._getScrollHeight()
|
||||||
|
var maxScroll = this._config.offset + scrollHeight - this._scrollElement.offsetHeight
|
||||||
|
|
||||||
|
if (this._scrollHeight != scrollHeight) {
|
||||||
|
this['refresh']()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scrollTop >= maxScroll) {
|
||||||
|
var target = this._targets[this._targets.length - 1]
|
||||||
|
|
||||||
|
if (this._activeTarget != target) {
|
||||||
|
this._activate(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._activeTarget && scrollTop < this._offsets[0]) {
|
||||||
|
this._activeTarget = null
|
||||||
|
this._clear()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = this._offsets.length; i--;) {
|
||||||
|
var isActiveTarget = this._activeTarget != this._targets[i]
|
||||||
|
&& scrollTop >= this._offsets[i]
|
||||||
|
&& (!this._offsets[i + 1] || scrollTop < this._offsets[i + 1])
|
||||||
|
|
||||||
|
if (isActiveTarget) {
|
||||||
|
this._activate(this._targets[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Element} target
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ScrollSpy.prototype._activate = function (target) {
|
||||||
|
this._activeTarget = target
|
||||||
|
|
||||||
|
this._clear()
|
||||||
|
|
||||||
|
var selector = this._selector
|
||||||
|
+ '[data-target="' + target + '"],'
|
||||||
|
+ this._selector + '[href="' + target + '"]'
|
||||||
|
|
||||||
|
// todo (fat): this seems horribly wrong… getting all raw li elements up the tree ,_,
|
||||||
|
var parentListItems = $(selector).parents(ScrollSpy._Selector.LI)
|
||||||
|
|
||||||
|
for (var i = parentListItems.length; i--;) {
|
||||||
|
$(parentListItems[i]).addClass(ScrollSpy._ClassName.ACTIVE)
|
||||||
|
|
||||||
|
var itemParent = parentListItems[i].parentNode
|
||||||
|
|
||||||
|
if (itemParent && $(itemParent).hasClass(ScrollSpy._ClassName.DROPDOWN_MENU)) {
|
||||||
|
var closestDropdown = $(itemParent).closest(ScrollSpy._Selector.LI_DROPDOWN)[0]
|
||||||
|
$(closestDropdown).addClass(ScrollSpy._ClassName.ACTIVE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this._scrollElement).trigger(ScrollSpy._Event.ACTIVATE, {
|
||||||
|
relatedTarget: target
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ScrollSpy.prototype._clear = function () {
|
||||||
|
var activeParents = $(this._selector).parentsUntil(this._config.target, ScrollSpy._Selector.ACTIVE)
|
||||||
|
|
||||||
|
for (var i = activeParents.length; i--;) {
|
||||||
|
$(activeParents[i]).removeClass(ScrollSpy._ClassName.ACTIVE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* jQuery Interface + noConflict implementaiton
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[ScrollSpy._NAME] = ScrollSpy._jQueryInterface
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[ScrollSpy._NAME]['Constructor'] = ScrollSpy
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[ScrollSpy._NAME]['noConflict'] = function () {
|
||||||
|
$.fn[ScrollSpy._NAME] = ScrollSpy._JQUERY_NO_CONFLICT
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* Data Api implementation
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
$(window).on('load.bs.scrollspy.data-api', function () {
|
||||||
|
var scrollSpys = /** @type {Array.<Element>} */ ($.makeArray($(ScrollSpy._Selector.DATA_SPY)))
|
||||||
|
|
||||||
|
for (var i = scrollSpys.length; i--;) {
|
||||||
|
var $spy = $(scrollSpys[i])
|
||||||
|
ScrollSpy._jQueryInterface.call($spy, /** @type {Object|null} */ ($spy.data()))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
405
js/tab.js
405
js/tab.js
@ -1,153 +1,324 @@
|
|||||||
/* ========================================================================
|
/** =======================================================================
|
||||||
* Bootstrap: tab.js v3.3.2
|
* Bootstrap: tab.js v4.0.0
|
||||||
* http://getbootstrap.com/javascript/#tabs
|
* http://getbootstrap.com/javascript/#tabs
|
||||||
* ========================================================================
|
* ========================================================================
|
||||||
* Copyright 2011-2015 Twitter, Inc.
|
* Copyright 2011-2015 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
* ======================================================================== */
|
* ========================================================================
|
||||||
|
* @fileoverview - Bootstrap's tab plugin. Tab O_O
|
||||||
|
*
|
||||||
|
* Public Methods & Properties:
|
||||||
|
*
|
||||||
|
* + $.tab
|
||||||
|
* + $.tab.noConflict
|
||||||
|
* + $.tab.Constructor
|
||||||
|
* + $.tab.Constructor.VERSION
|
||||||
|
* + $.tab.Constructor.prototype.show
|
||||||
|
*
|
||||||
|
* ========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
+function ($) {
|
'use strict';
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// TAB CLASS DEFINITION
|
/**
|
||||||
// ====================
|
* Our Tab class.
|
||||||
|
* @param {Element!} element
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
var Tab = function (element) {
|
||||||
|
|
||||||
var Tab = function (element) {
|
/** @type {Element} */
|
||||||
this.element = $(element)
|
this._element = element
|
||||||
}
|
|
||||||
|
|
||||||
Tab.VERSION = '3.3.2'
|
}
|
||||||
|
|
||||||
Tab.TRANSITION_DURATION = 150
|
|
||||||
|
|
||||||
Tab.prototype.show = function () {
|
/**
|
||||||
var $this = this.element
|
* @const
|
||||||
var $ul = $this.closest('ul:not(.dropdown-menu)')
|
* @type {string}
|
||||||
var selector = $this.data('target')
|
*/
|
||||||
|
Tab['VERSION'] = '4.0.0'
|
||||||
|
|
||||||
if (!selector) {
|
|
||||||
selector = $this.attr('href')
|
/**
|
||||||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Tab._NAME = 'tab'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Tab._DATA_KEY = 'bs.tab'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Tab._TRANSITION_DURATION = 150
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Tab._Event = {
|
||||||
|
HIDE : 'hide.bs.tab',
|
||||||
|
HIDDEN : 'hidden.bs.tab',
|
||||||
|
SHOW : 'show.bs.tab',
|
||||||
|
SHOWN : 'shown.bs.tab'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Tab._ClassName = {
|
||||||
|
DROPDOWN_MENU : 'dropdown-menu',
|
||||||
|
ACTIVE : 'active',
|
||||||
|
FADE : 'fade',
|
||||||
|
IN : 'in'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @enum {string}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Tab._Selector = {
|
||||||
|
A : 'a',
|
||||||
|
LI : 'li',
|
||||||
|
LI_DROPDOWN : 'li.dropdown',
|
||||||
|
UL : 'ul:not(.dropdown-menu)',
|
||||||
|
FADE_CHILD : ':scope > .fade',
|
||||||
|
ACTIVE : '.active',
|
||||||
|
ACTIVE_CHILD : ':scope > .active',
|
||||||
|
DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"]',
|
||||||
|
DROPDOWN_ACTIVE_CHILD : ':scope > .dropdown-menu > .active'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object|string=} opt_config
|
||||||
|
* @this {jQuery}
|
||||||
|
* @return {jQuery}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Tab._jQueryInterface = function (opt_config) {
|
||||||
|
return this.each(function () {
|
||||||
|
var $this = $(this)
|
||||||
|
var data = $this.data(Tab._DATA_KEY)
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
data = data = new Tab(this)
|
||||||
|
$this.data(Tab._DATA_KEY, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this.parent('li').hasClass('active')) return
|
if (typeof opt_config === 'string') {
|
||||||
|
data[opt_config]()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
* Show the tab
|
||||||
|
*/
|
||||||
if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
|
Tab.prototype['show'] = function () {
|
||||||
|
if ( this._element.parentNode
|
||||||
var $target = $(selector)
|
&& this._element.parentNode.nodeType == Node.ELEMENT_NODE
|
||||||
|
&& $(this._element).parent().hasClass(Tab._ClassName.ACTIVE)) {
|
||||||
this.activate($this.closest('li'), $ul)
|
return
|
||||||
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 ulElement = $(this._element).closest(Tab._Selector.UL)[0]
|
||||||
var $active = container.find('> .active')
|
var selector = Bootstrap.getSelectorFromElement(this._element)
|
||||||
var transition = callback
|
|
||||||
&& $.support.transition
|
|
||||||
&& (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
|
|
||||||
|
|
||||||
function next() {
|
if (ulElement) {
|
||||||
$active
|
var previous = /** @type {Array.<Element>} */ ($.makeArray($(ulElement).find(Tab._Selector.ACTIVE)))
|
||||||
.removeClass('active')
|
previous = previous[previous.length - 1]
|
||||||
.find('> .dropdown-menu > .active')
|
|
||||||
.removeClass('active')
|
|
||||||
.end()
|
|
||||||
.find('[data-toggle="tab"]')
|
|
||||||
.attr('aria-expanded', false)
|
|
||||||
|
|
||||||
element
|
if (previous) {
|
||||||
.addClass('active')
|
previous = $(previous).find('a')[0]
|
||||||
.find('[data-toggle="tab"]')
|
}
|
||||||
.attr('aria-expanded', true)
|
}
|
||||||
|
|
||||||
if (transition) {
|
var hideEvent = $.Event(Tab._Event.HIDE, {
|
||||||
element[0].offsetWidth // reflow for transition
|
relatedTarget: this._element
|
||||||
element.addClass('in')
|
})
|
||||||
} else {
|
|
||||||
element.removeClass('fade')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (element.parent('.dropdown-menu')) {
|
var showEvent = $.Event(Tab._Event.SHOW, {
|
||||||
element
|
relatedTarget: previous
|
||||||
.closest('li.dropdown')
|
})
|
||||||
.addClass('active')
|
|
||||||
.end()
|
|
||||||
.find('[data-toggle="tab"]')
|
|
||||||
.attr('aria-expanded', true)
|
|
||||||
}
|
|
||||||
|
|
||||||
callback && callback()
|
if (previous) {
|
||||||
|
$(previous).trigger(hideEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this._element).trigger(showEvent)
|
||||||
|
|
||||||
|
if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
|
||||||
|
|
||||||
|
if (selector) {
|
||||||
|
var target = $(selector)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
this._activate($(this._element).closest(Tab._Selector.LI)[0], ulElement)
|
||||||
|
|
||||||
|
var complete = function () {
|
||||||
|
var hiddenEvent = $.Event(Tab._Event.HIDDEN, {
|
||||||
|
relatedTarget: this._element
|
||||||
|
})
|
||||||
|
|
||||||
|
var shownEvent = $.Event(Tab._Event.SHOWN, {
|
||||||
|
relatedTarget: previous
|
||||||
|
})
|
||||||
|
|
||||||
|
$(previous).trigger(hiddenEvent)
|
||||||
|
$(this._element).trigger(shownEvent)
|
||||||
|
}.bind(this)
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
this._activate(target, /** @type {Element} */ (target.parentNode), complete)
|
||||||
|
} else {
|
||||||
|
complete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Element} element
|
||||||
|
* @param {Element} container
|
||||||
|
* @param {Function=} opt_callback
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Tab.prototype._activate = function (element, container, opt_callback) {
|
||||||
|
var active = $(container).find(Tab._Selector.ACTIVE_CHILD)[0]
|
||||||
|
var isTransitioning = opt_callback
|
||||||
|
&& Bootstrap.transition
|
||||||
|
&& ((active && $(active).hasClass(Tab._ClassName.FADE))
|
||||||
|
|| !!$(container).find(Tab._Selector.FADE_CHILD)[0])
|
||||||
|
|
||||||
|
var complete = this._transitionComplete.bind(this, element, active, isTransitioning, opt_callback)
|
||||||
|
|
||||||
|
if (active && isTransitioning) {
|
||||||
|
$(active)
|
||||||
|
.one(Bootstrap.TRANSITION_END, complete)
|
||||||
|
.emulateTransitionEnd(Tab._TRANSITION_DURATION)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
complete()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
$(active).removeClass(Tab._ClassName.IN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Element} element
|
||||||
|
* @param {Element} active
|
||||||
|
* @param {boolean} isTransitioning
|
||||||
|
* @param {Function=} opt_callback
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
Tab.prototype._transitionComplete = function (element, active, isTransitioning, opt_callback) {
|
||||||
|
if (active) {
|
||||||
|
$(active).removeClass(Tab._ClassName.ACTIVE)
|
||||||
|
|
||||||
|
var dropdownChild = $(active).find(Tab._Selector.DROPDOWN_ACTIVE_CHILD)[0]
|
||||||
|
if (dropdownChild) {
|
||||||
|
$(dropdownChild).removeClass(Tab._ClassName.ACTIVE)
|
||||||
}
|
}
|
||||||
|
|
||||||
$active.length && transition ?
|
var activeToggle = $(active).find(Tab._Selector.DATA_TOGGLE)[0]
|
||||||
$active
|
if (activeToggle) {
|
||||||
.one('bsTransitionEnd', next)
|
activeToggle.setAttribute('aria-expanded', false)
|
||||||
.emulateTransitionEnd(Tab.TRANSITION_DURATION) :
|
}
|
||||||
next()
|
|
||||||
|
|
||||||
$active.removeClass('in')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(element).addClass(Tab._ClassName.ACTIVE)
|
||||||
|
|
||||||
// TAB PLUGIN DEFINITION
|
var elementToggle = $(element).find(Tab._Selector.DATA_TOGGLE)[0]
|
||||||
// =====================
|
if (elementToggle) {
|
||||||
|
elementToggle.setAttribute('aria-expanded', true)
|
||||||
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
|
if (isTransitioning) {
|
||||||
|
Bootstrap.reflow(element)
|
||||||
$.fn.tab = Plugin
|
$(element).addClass(Tab._ClassName.IN)
|
||||||
$.fn.tab.Constructor = Tab
|
} else {
|
||||||
|
$(element).removeClass(Tab._ClassName.FADE)
|
||||||
|
|
||||||
// TAB NO CONFLICT
|
|
||||||
// ===============
|
|
||||||
|
|
||||||
$.fn.tab.noConflict = function () {
|
|
||||||
$.fn.tab = old
|
|
||||||
return this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (element.parentNode && $(element.parentNode).hasClass(Tab._ClassName.DROPDOWN_MENU)) {
|
||||||
|
var dropdownElement = $(element).closest(Tab._Selector.LI_DROPDOWN)[0]
|
||||||
|
if (dropdownElement) {
|
||||||
|
$(dropdownElement).addClass(Tab._ClassName.ACTIVE)
|
||||||
|
}
|
||||||
|
|
||||||
// TAB DATA-API
|
elementToggle = $(element).find(Tab._Selector.DATA_TOGGLE)[0]
|
||||||
// ============
|
if (elementToggle) {
|
||||||
|
elementToggle.setAttribute('aria-expanded', true)
|
||||||
var clickHandler = function (e) {
|
}
|
||||||
e.preventDefault()
|
|
||||||
Plugin.call($(this), 'show')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document)
|
if (opt_callback) {
|
||||||
.on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
|
opt_callback()
|
||||||
.on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}(jQuery);
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* jQuery Interface + noConflict implementaiton
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Tab._NAME] = Tab._jQueryInterface
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Tab._NAME]['Constructor'] = Tab
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
$.fn[Tab._NAME]['noConflict'] = function () {
|
||||||
|
$.fn[Tab._NAME] = Tab._JQUERY_NO_CONFLICT
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// TAB DATA-API
|
||||||
|
// ============
|
||||||
|
|
||||||
|
var clickHandler = function (e) {
|
||||||
|
e.preventDefault()
|
||||||
|
Tab._jQueryInterface.call($(this), 'show')
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document)
|
||||||
|
.on('click.bs.tab.data-api', Tab._Selector.DATA_TOGGLE, clickHandler)
|
||||||
|
83
js/tests/closure.html
Normal file
83
js/tests/closure.html
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Bootstrap Plugin Test Suite</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<!-- jQuery -->
|
||||||
|
<script src="vendor/jquery.min.js"></script>
|
||||||
|
|
||||||
|
<!-- QUnit -->
|
||||||
|
<link rel="stylesheet" href="vendor/qunit.css" media="screen">
|
||||||
|
<script src="vendor/qunit.js"></script>
|
||||||
|
<style>
|
||||||
|
#qunit-tests > li.pass {
|
||||||
|
display: none;/* Make it easier to see failing tests in Sauce screencasts */
|
||||||
|
}
|
||||||
|
|
||||||
|
#qunit-fixture {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
// See https://github.com/axemclion/grunt-saucelabs#test-result-details-with-qunit
|
||||||
|
var log = []
|
||||||
|
QUnit.done(function (testResults) {
|
||||||
|
var tests = []
|
||||||
|
for (var i = 0, len = log.length; i < len; i++) {
|
||||||
|
var details = log[i]
|
||||||
|
tests.push({
|
||||||
|
name: details.name,
|
||||||
|
result: details.result,
|
||||||
|
expected: details.expected,
|
||||||
|
actual: details.actual,
|
||||||
|
source: details.source
|
||||||
|
})
|
||||||
|
}
|
||||||
|
testResults.tests = tests
|
||||||
|
|
||||||
|
window.global_test_results = testResults
|
||||||
|
})
|
||||||
|
|
||||||
|
QUnit.testStart(function (testDetails) {
|
||||||
|
$(window).scrollTop(0)
|
||||||
|
QUnit.log = function (details) {
|
||||||
|
if (!details.result) {
|
||||||
|
details.name = testDetails.name
|
||||||
|
log.push(details)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
QUnit.testDone(function () {
|
||||||
|
$('#qunit-fixture').empty()
|
||||||
|
$('#modal-test, .modal-backdrop').remove()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Plugin sources -->
|
||||||
|
<script src="../../dist/js/bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Unit tests -->
|
||||||
|
<script src="unit/alert.js"></script>
|
||||||
|
<script src="unit/button.js"></script>
|
||||||
|
<script src="unit/carousel.js"></script>
|
||||||
|
<script src="unit/collapse.js"></script>
|
||||||
|
<script src="unit/dropdown.js"></script>
|
||||||
|
<script src="unit/modal.js"></script>
|
||||||
|
<script src="unit/scrollspy.js"></script>
|
||||||
|
<script src="unit/tab.js"></script>
|
||||||
|
<script src="unit/tooltip.js"></script>
|
||||||
|
<script src="unit/popover.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="qunit-container">
|
||||||
|
<div id="qunit"></div>
|
||||||
|
<div id="qunit-fixture"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -59,7 +59,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Plugin sources -->
|
<!-- Plugin sources -->
|
||||||
<script>$.support.transition = false</script>
|
<script src="../../js/util.js"></script>
|
||||||
<script src="../../js/alert.js"></script>
|
<script src="../../js/alert.js"></script>
|
||||||
<script src="../../js/button.js"></script>
|
<script src="../../js/button.js"></script>
|
||||||
<script src="../../js/carousel.js"></script>
|
<script src="../../js/carousel.js"></script>
|
||||||
@ -70,7 +70,6 @@
|
|||||||
<script src="../../js/tab.js"></script>
|
<script src="../../js/tab.js"></script>
|
||||||
<script src="../../js/tooltip.js"></script>
|
<script src="../../js/tooltip.js"></script>
|
||||||
<script src="../../js/popover.js"></script>
|
<script src="../../js/popover.js"></script>
|
||||||
<script src="../../js/affix.js"></script>
|
|
||||||
|
|
||||||
<!-- Unit tests -->
|
<!-- Unit tests -->
|
||||||
<script src="unit/alert.js"></script>
|
<script src="unit/alert.js"></script>
|
||||||
@ -83,7 +82,6 @@
|
|||||||
<script src="unit/tab.js"></script>
|
<script src="unit/tab.js"></script>
|
||||||
<script src="unit/tooltip.js"></script>
|
<script src="unit/tooltip.js"></script>
|
||||||
<script src="unit/popover.js"></script>
|
<script src="unit/popover.js"></script>
|
||||||
<script src="unit/affix.js"></script>
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -29,61 +29,6 @@ $(function () {
|
|||||||
strictEqual($button[0], $el[0], 'collection contains element')
|
strictEqual($button[0], $el[0], 'collection contains element')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should return set state to loading', function (assert) {
|
|
||||||
var $btn = $('<button class="btn" data-loading-text="fat">mdo</button>')
|
|
||||||
equal($btn.html(), 'mdo', 'btn text equals mdo')
|
|
||||||
$btn.bootstrapButton('loading')
|
|
||||||
var done = assert.async()
|
|
||||||
setTimeout(function () {
|
|
||||||
equal($btn.html(), 'fat', 'btn text equals fat')
|
|
||||||
ok($btn[0].hasAttribute('disabled'), 'btn is disabled')
|
|
||||||
ok($btn.hasClass('disabled'), 'btn has disabled class')
|
|
||||||
done()
|
|
||||||
}, 0)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('should return reset state', function (assert) {
|
|
||||||
var $btn = $('<button class="btn" data-loading-text="fat">mdo</button>')
|
|
||||||
equal($btn.html(), 'mdo', 'btn text equals mdo')
|
|
||||||
$btn.bootstrapButton('loading')
|
|
||||||
var doneOne = assert.async()
|
|
||||||
setTimeout(function () {
|
|
||||||
equal($btn.html(), 'fat', 'btn text equals fat')
|
|
||||||
ok($btn[0].hasAttribute('disabled'), 'btn is disabled')
|
|
||||||
ok($btn.hasClass('disabled'), 'btn has disabled class')
|
|
||||||
doneOne()
|
|
||||||
var doneTwo = assert.async()
|
|
||||||
$btn.bootstrapButton('reset')
|
|
||||||
setTimeout(function () {
|
|
||||||
equal($btn.html(), 'mdo', 'btn text equals mdo')
|
|
||||||
ok(!$btn[0].hasAttribute('disabled'), 'btn is not disabled')
|
|
||||||
ok(!$btn.hasClass('disabled'), 'btn does not have disabled class')
|
|
||||||
doneTwo()
|
|
||||||
}, 0)
|
|
||||||
}, 0)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('should work with an empty string as reset state', function (assert) {
|
|
||||||
var $btn = $('<button class="btn" data-loading-text="fat"/>')
|
|
||||||
equal($btn.html(), '', 'btn text equals ""')
|
|
||||||
$btn.bootstrapButton('loading')
|
|
||||||
var doneOne = assert.async()
|
|
||||||
setTimeout(function () {
|
|
||||||
equal($btn.html(), 'fat', 'btn text equals fat')
|
|
||||||
ok($btn[0].hasAttribute('disabled'), 'btn is disabled')
|
|
||||||
ok($btn.hasClass('disabled'), 'btn has disabled class')
|
|
||||||
doneOne()
|
|
||||||
var doneTwo = assert.async()
|
|
||||||
$btn.bootstrapButton('reset')
|
|
||||||
setTimeout(function () {
|
|
||||||
equal($btn.html(), '', 'btn text equals ""')
|
|
||||||
ok(!$btn[0].hasAttribute('disabled'), 'btn is not disabled')
|
|
||||||
ok(!$btn.hasClass('disabled'), 'btn does not have disabled class')
|
|
||||||
doneTwo()
|
|
||||||
}, 0)
|
|
||||||
}, 0)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('should toggle active', function () {
|
test('should toggle active', function () {
|
||||||
var $btn = $('<button class="btn" data-toggle="button">mdo</button>')
|
var $btn = $('<button class="btn" data-toggle="button">mdo</button>')
|
||||||
ok(!$btn.hasClass('active'), 'btn does not have active class')
|
ok(!$btn.hasClass('active'), 'btn does not have active class')
|
||||||
|
@ -322,30 +322,31 @@ $(function () {
|
|||||||
+ '<a class="left carousel-control" href="#myCarousel" data-slide="prev">‹</a>'
|
+ '<a class="left carousel-control" href="#myCarousel" data-slide="prev">‹</a>'
|
||||||
+ '<a class="right carousel-control" href="#myCarousel" data-slide="next">›</a>'
|
+ '<a class="right carousel-control" href="#myCarousel" data-slide="next">›</a>'
|
||||||
+ '</div>'
|
+ '</div>'
|
||||||
|
|
||||||
var $carousel = $(templateHTML)
|
var $carousel = $(templateHTML)
|
||||||
$carousel.attr('data-interval', 1814)
|
$carousel.attr('data-interval', 1814)
|
||||||
|
|
||||||
$carousel.appendTo('body')
|
$carousel.appendTo('body')
|
||||||
$('[data-slide]').first().click()
|
$('[data-slide]').first().click()
|
||||||
equal($carousel.data('bs.carousel').options.interval, 1814)
|
equal($carousel.data('bs.carousel').getConfig().interval, 1814)
|
||||||
$carousel.remove()
|
$carousel.remove()
|
||||||
|
|
||||||
$carousel.appendTo('body').attr('data-modal', 'foobar')
|
$carousel.appendTo('body').attr('data-modal', 'foobar')
|
||||||
$('[data-slide]').first().click()
|
$('[data-slide]').first().click()
|
||||||
equal($carousel.data('bs.carousel').options.interval, 1814, 'even if there is an data-modal attribute set')
|
equal($carousel.data('bs.carousel').getConfig().interval, 1814, 'even if there is an data-modal attribute set')
|
||||||
$carousel.remove()
|
$carousel.remove()
|
||||||
|
|
||||||
$carousel.appendTo('body')
|
$carousel.appendTo('body')
|
||||||
$('[data-slide]').first().click()
|
$('[data-slide]').first().click()
|
||||||
$carousel.attr('data-interval', 1860)
|
$carousel.attr('data-interval', 1860)
|
||||||
$('[data-slide]').first().click()
|
$('[data-slide]').first().click()
|
||||||
equal($carousel.data('bs.carousel').options.interval, 1814, 'attributes should be read only on initialization')
|
equal($carousel.data('bs.carousel').getConfig().interval, 1814, 'attributes should be read only on initialization')
|
||||||
$carousel.remove()
|
$carousel.remove()
|
||||||
|
|
||||||
$carousel.attr('data-interval', false)
|
$carousel.attr('data-interval', false)
|
||||||
$carousel.appendTo('body')
|
$carousel.appendTo('body')
|
||||||
$carousel.bootstrapCarousel(1)
|
$carousel.bootstrapCarousel(1)
|
||||||
strictEqual($carousel.data('bs.carousel').options.interval, false, 'data attribute has higher priority than default options')
|
strictEqual($carousel.data('bs.carousel').getConfig().interval, false, 'data attribute has higher priority than default options')
|
||||||
$carousel.remove()
|
$carousel.remove()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ $(function () {
|
|||||||
|
|
||||||
$body2
|
$body2
|
||||||
.toggleClass('in collapsing')
|
.toggleClass('in collapsing')
|
||||||
.data('bs.collapse').transitioning = 1
|
.data('bs.collapse').setTransitioning(true)
|
||||||
|
|
||||||
$target1.click()
|
$target1.click()
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ $(function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('should expose defaults var for settings', function () {
|
test('should expose defaults var for settings', function () {
|
||||||
ok($.fn.bootstrapModal.Constructor.DEFAULTS, 'default object exposed')
|
ok($.fn.bootstrapModal.Constructor.Defaults, 'default object exposed')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should insert into dom when show method is called', function (assert) {
|
test('should insert into dom when show method is called', function (assert) {
|
||||||
|
@ -30,7 +30,7 @@ $(function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('should expose default settings', function () {
|
test('should expose default settings', function () {
|
||||||
ok($.fn.bootstrapTooltip.Constructor.DEFAULTS, 'defaults is defined')
|
ok($.fn.bootstrapTooltip.Constructor.Defaults, 'defaults is defined')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should empty title attribute', function () {
|
test('should empty title attribute', function () {
|
||||||
@ -879,17 +879,17 @@ $(function () {
|
|||||||
.bootstrapTooltip({ delay: { show: 0, hide: 150 }})
|
.bootstrapTooltip({ delay: { show: 0, hide: 150 }})
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
ok($tooltip.data('bs.tooltip').$tip.is('.fade.in'), '1ms: tooltip faded in')
|
ok($('.tooltip').is('.fade.in'), '1ms: tooltip faded in')
|
||||||
|
|
||||||
$tooltip.trigger('mouseout')
|
$tooltip.trigger('mouseout')
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
ok($tooltip.data('bs.tooltip').$tip.is('.fade.in'), '100ms: tooltip still faded in')
|
ok($('.tooltip').is('.fade.in'), '100ms: tooltip still faded in')
|
||||||
}, 100)
|
}, 100)
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
ok(!$tooltip.data('bs.tooltip').$tip.is('.in'), '200ms: tooltip removed')
|
ok(!$('.tooltip').is('.in'), '200ms: tooltip removed')
|
||||||
done()
|
start()
|
||||||
}, 200)
|
}, 200)
|
||||||
|
|
||||||
}, 0)
|
}, 0)
|
||||||
@ -978,7 +978,7 @@ $(function () {
|
|||||||
|
|
||||||
test('should not reload the tooltip on subsequent mouseenter events', function () {
|
test('should not reload the tooltip on subsequent mouseenter events', function () {
|
||||||
var titleHtml = function () {
|
var titleHtml = function () {
|
||||||
var uid = $.fn.bootstrapTooltip.Constructor.prototype.getUID('tooltip')
|
var uid = 'fatTooltip'
|
||||||
return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
|
return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1004,7 +1004,7 @@ $(function () {
|
|||||||
|
|
||||||
test('should not reload the tooltip if the mouse leaves and re-enters before hiding', function () {
|
test('should not reload the tooltip if the mouse leaves and re-enters before hiding', function () {
|
||||||
var titleHtml = function () {
|
var titleHtml = function () {
|
||||||
var uid = $.fn.bootstrapTooltip.Constructor.prototype.getUID('tooltip')
|
var uid = 'fatTooltip'
|
||||||
return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
|
return '<p id="tt-content">' + uid + '</p><p>' + uid + '</p><p>' + uid + '</p>'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1029,10 +1029,12 @@ $(function () {
|
|||||||
$('#tt-outer').trigger('mouseleave')
|
$('#tt-outer').trigger('mouseleave')
|
||||||
equal(currentUid, $('#tt-content').text())
|
equal(currentUid, $('#tt-content').text())
|
||||||
|
|
||||||
ok(obj.hoverState == 'out', 'the tooltip hoverState should be set to "out"')
|
debugger
|
||||||
|
|
||||||
|
ok(obj.getHoverState() == 'out', 'the tooltip hoverState should be set to "out"')
|
||||||
|
|
||||||
$('#tt-content').trigger('mouseenter')
|
$('#tt-content').trigger('mouseenter')
|
||||||
ok(obj.hoverState == 'in', 'the tooltip hoverState should be set to "in"')
|
ok(obj.getHoverState() == 'in', 'the tooltip hoverState should be set to "in"')
|
||||||
|
|
||||||
equal(currentUid, $('#tt-content').text())
|
equal(currentUid, $('#tt-content').text())
|
||||||
})
|
})
|
||||||
@ -1051,7 +1053,7 @@ $(function () {
|
|||||||
$('<a href="#" title="tooltip title" style="position: absolute; bottom: 0; right: 0;">Foobar</a>')
|
$('<a href="#" title="tooltip title" style="position: absolute; bottom: 0; right: 0;">Foobar</a>')
|
||||||
.appendTo('body')
|
.appendTo('body')
|
||||||
.on('shown.bs.tooltip', function () {
|
.on('shown.bs.tooltip', function () {
|
||||||
var arrowStyles = $(this).data('bs.tooltip').$tip.find('.tooltip-arrow').attr('style')
|
var arrowStyles = $('.tooltip').find('.tooltip-arrow').attr('style')
|
||||||
ok(/left/i.test(arrowStyles) && !/top/i.test(arrowStyles), 'arrow positioned correctly')
|
ok(/left/i.test(arrowStyles) && !/top/i.test(arrowStyles), 'arrow positioned correctly')
|
||||||
$(this).bootstrapTooltip('hide')
|
$(this).bootstrapTooltip('hide')
|
||||||
})
|
})
|
||||||
|
@ -1,299 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<title>Affix</title>
|
|
||||||
<link rel="stylesheet" href="../../../dist/css/bootstrap.min.css">
|
|
||||||
|
|
||||||
<style>
|
|
||||||
/* Test Styles */
|
|
||||||
.affixed-element-top.affix {
|
|
||||||
top: 10px;
|
|
||||||
}
|
|
||||||
.affixed-element-top.affix-bottom {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
.affixed-element-bottom {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
.affixed-element-bottom.affix {
|
|
||||||
bottom: 10px;
|
|
||||||
}
|
|
||||||
.affixed-element-bottom.affix-bottom {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.grow-btn, .shrink-btn {
|
|
||||||
color: #FFF;
|
|
||||||
}
|
|
||||||
.grow-btn {
|
|
||||||
background-color: #2ECC40;
|
|
||||||
}
|
|
||||||
.grow-btn:hover {
|
|
||||||
background-color: #3D9970;
|
|
||||||
}
|
|
||||||
.shrink-btn {
|
|
||||||
background-color: #FF4136;
|
|
||||||
}
|
|
||||||
.shrink-btn:hover {
|
|
||||||
background-color: #85144B;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
|
|
||||||
<div class="page-header js-page-header">
|
|
||||||
<h1>Affix <small>Bootstrap Visual Test</small></h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-3">
|
|
||||||
<ul class="list-group affixed-element-top js-affixed-element-top">
|
|
||||||
<li class="list-group-item">Cras justo odio</li>
|
|
||||||
<li class="list-group-item">Dapibus ac facilisis in</li>
|
|
||||||
<li class="list-group-item">Morbi leo risus</li>
|
|
||||||
<li class="list-group-item">Porta ac consectetur ac</li>
|
|
||||||
<li class="list-group-item">Vestibulum at eros</li>
|
|
||||||
<li class="list-group-item">Cras justo odio</li>
|
|
||||||
<li class="list-group-item">Dapibus ac facilisis in</li>
|
|
||||||
<li class="list-group-item">Morbi leo risus</li>
|
|
||||||
<li class="list-group-item">Porta ac consectetur ac</li>
|
|
||||||
<li class="list-group-item">Vestibulum at eros</li>
|
|
||||||
<li class="list-group-item">Cras justo odio</li>
|
|
||||||
<li class="list-group-item">Dapibus ac facilisis in</li>
|
|
||||||
<li class="list-group-item">Morbi leo risus</li>
|
|
||||||
<li class="list-group-item">Porta ac consectetur ac</li>
|
|
||||||
<li class="list-group-item">Vestibulum at eros</li>
|
|
||||||
<li class="list-group-item">Porta ac consectetur ac</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6 js-content">
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-3">
|
|
||||||
<ul class="list-group affixed-element-bottom js-affixed-element-bottom">
|
|
||||||
<li class="list-group-item">Sit necessitatibus aspernatur.</li>
|
|
||||||
<li class="list-group-item">Adipisicing alias dolor!</li>
|
|
||||||
<li class="list-group-item">Ipsum molestiae impedit.</li>
|
|
||||||
<li class="list-group-item">Amet quis iste?</li>
|
|
||||||
<li class="list-group-item">Ipsum quaerat porro.</li>
|
|
||||||
<li class="list-group-item">Elit lorem libero.</li>
|
|
||||||
<li class="list-group-item">Ipsum dolore facilis.</li>
|
|
||||||
<li class="list-group-item">Elit ad atque.</li>
|
|
||||||
<li class="list-group-item">Dolor amet sequi!</li>
|
|
||||||
<li class="list-group-item">Consectetur voluptatum facilis!</li>
|
|
||||||
<li class="list-group-item">Sit neque eligendi?</li>
|
|
||||||
<li class="list-group-item">Amet fuga consectetur!</li>
|
|
||||||
<li class="list-group-item">Amet molestias repellat!</li>
|
|
||||||
<li class="list-group-item">Consectetur minima repellendus.</li>
|
|
||||||
<li class="list-group-item grow-btn js-grow-btn">Grow content</li>
|
|
||||||
<li class="list-group-item shrink-btn js-shrink-btn">Shrink content</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-12 js-footer">
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<p>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue. Maecenas sed diam eget risus varius blandit sit amet non magna.</p>
|
|
||||||
|
|
||||||
<p>Nullam id dolor id nibh ultricies vehicula ut id elit. Etiam porta sem malesuada magna mollis euismod. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Cras justo odio, dapibus ac facilisis in, egestas eget quam.</p>
|
|
||||||
|
|
||||||
<p>Sed posuere consectetur est at lobortis. Maecenas faucibus mollis interdum. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Nulla vitae elit libero, a pharetra augue. Nulla vitae elit libero, a pharetra augue.</p>
|
|
||||||
|
|
||||||
<p>Aenean lacinia bibendum nulla sed consectetur. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nulla vitae elit libero, a pharetra augue. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- JavaScript Includes -->
|
|
||||||
<script src="../vendor/jquery.min.js"></script>
|
|
||||||
<script src="../../transition.js"></script>
|
|
||||||
<script src="../../affix.js"></script>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- JavaScript Test -->
|
|
||||||
<script>
|
|
||||||
$(function () {
|
|
||||||
$('.js-affixed-element-top').affix({
|
|
||||||
offset: {
|
|
||||||
top: $('.js-page-header').outerHeight(true) - 10
|
|
||||||
, bottom: $('.js-footer').outerHeight(true) + 10
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// todo(fat): sux you have to do this.
|
|
||||||
.on('affix.bs.affix', function (e) {
|
|
||||||
$(e.target).width(e.target.offsetWidth)
|
|
||||||
})
|
|
||||||
|
|
||||||
$('.js-affixed-element-bottom').affix({
|
|
||||||
offset: {
|
|
||||||
bottom: $('.js-footer').outerHeight(true) + 10
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
$('.js-grow-btn').on('click', function() {
|
|
||||||
$('.js-content').append('<p>Ipsum corrupti ipsam est temporibus.</p>')
|
|
||||||
})
|
|
||||||
$('.js-shrink-btn').on('click', function() {
|
|
||||||
$('.js-content p').last().remove()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
<!-- JavaScript Includes -->
|
<!-- JavaScript Includes -->
|
||||||
<script src="../vendor/jquery.min.js"></script>
|
<script src="../vendor/jquery.min.js"></script>
|
||||||
<script src="../../transition.js"></script>
|
<script src="../../util.js"></script>
|
||||||
<script src="../../alert.js"></script>
|
<script src="../../alert.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -15,10 +15,6 @@
|
|||||||
<h1>Button <small>Bootstrap Visual Test</small></h1>
|
<h1>Button <small>Bootstrap Visual Test</small></h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="button" data-loading-text="Loading for 3 seconds..." class="btn btn-primary js-loading-button">
|
|
||||||
Loading state
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button type="button" class="btn btn-primary" data-toggle="button">Single toggle</button>
|
<button type="button" class="btn btn-primary" data-toggle="button">Single toggle</button>
|
||||||
|
|
||||||
<div class="btn-group" data-toggle="buttons">
|
<div class="btn-group" data-toggle="buttons">
|
||||||
@ -49,7 +45,7 @@
|
|||||||
|
|
||||||
<!-- JavaScript Includes -->
|
<!-- JavaScript Includes -->
|
||||||
<script src="../vendor/jquery.min.js"></script>
|
<script src="../vendor/jquery.min.js"></script>
|
||||||
<script src="../../transition.js"></script>
|
<script src="../../util.js"></script>
|
||||||
<script src="../../button.js"></script>
|
<script src="../../button.js"></script>
|
||||||
|
|
||||||
<!-- JavaScript Test -->
|
<!-- JavaScript Test -->
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
<!-- JavaScript Includes -->
|
<!-- JavaScript Includes -->
|
||||||
<script src="../vendor/jquery.min.js"></script>
|
<script src="../vendor/jquery.min.js"></script>
|
||||||
<script src="../../transition.js"></script>
|
<script src="../../util.js"></script>
|
||||||
<script src="../../carousel.js"></script>
|
<script src="../../carousel.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
<!-- JavaScript Includes -->
|
<!-- JavaScript Includes -->
|
||||||
<script src="../vendor/jquery.min.js"></script>
|
<script src="../vendor/jquery.min.js"></script>
|
||||||
<script src="../../transition.js"></script>
|
<script src="../../util.js"></script>
|
||||||
<script src="../../collapse.js"></script>
|
<script src="../../collapse.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
|
|
||||||
<!-- JavaScript Includes -->
|
<!-- JavaScript Includes -->
|
||||||
<script src="../vendor/jquery.min.js"></script>
|
<script src="../vendor/jquery.min.js"></script>
|
||||||
<script src="../../transition.js"></script>
|
<script src="../../util.js"></script>
|
||||||
<script src="../../dropdown.js"></script>
|
<script src="../../dropdown.js"></script>
|
||||||
<script src="../../collapse.js"></script>
|
<script src="../../collapse.js"></script>
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
<!-- JavaScript Includes -->
|
<!-- JavaScript Includes -->
|
||||||
<script src="../vendor/jquery.min.js"></script>
|
<script src="../vendor/jquery.min.js"></script>
|
||||||
<script src="../../transition.js"></script>
|
<script src="../../util.js"></script>
|
||||||
<script src="../../modal.js"></script>
|
<script src="../../modal.js"></script>
|
||||||
<script src="../../tooltip.js"></script>
|
<script src="../../tooltip.js"></script>
|
||||||
<script src="../../popover.js"></script>
|
<script src="../../popover.js"></script>
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
<!-- JavaScript Includes -->
|
<!-- JavaScript Includes -->
|
||||||
<script src="../vendor/jquery.min.js"></script>
|
<script src="../vendor/jquery.min.js"></script>
|
||||||
<script src="../../transition.js"></script>
|
<script src="../../util.js"></script>
|
||||||
<script src="../../tooltip.js"></script>
|
<script src="../../tooltip.js"></script>
|
||||||
<script src="../../popover.js"></script>
|
<script src="../../popover.js"></script>
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
|
|
||||||
<!-- JavaScript Includes -->
|
<!-- JavaScript Includes -->
|
||||||
<script src="../vendor/jquery.min.js"></script>
|
<script src="../vendor/jquery.min.js"></script>
|
||||||
<script src="../../transition.js"></script>
|
<script src="../../util.js"></script>
|
||||||
<script src="../../scrollspy.js"></script>
|
<script src="../../scrollspy.js"></script>
|
||||||
<script src="../../dropdown.js"></script>
|
<script src="../../dropdown.js"></script>
|
||||||
<script src="../../collapse.js"></script>
|
<script src="../../collapse.js"></script>
|
||||||
|
@ -157,7 +157,7 @@
|
|||||||
|
|
||||||
<!-- JavaScript Includes -->
|
<!-- JavaScript Includes -->
|
||||||
<script src="../vendor/jquery.min.js"></script>
|
<script src="../vendor/jquery.min.js"></script>
|
||||||
<script src="../../transition.js"></script>
|
<script src="../../util.js"></script>
|
||||||
<script src="../../tab.js"></script>
|
<script src="../../tab.js"></script>
|
||||||
<script src="../../dropdown.js"></script>
|
<script src="../../dropdown.js"></script>
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
<!-- JavaScript Includes -->
|
<!-- JavaScript Includes -->
|
||||||
<script src="../vendor/jquery.min.js"></script>
|
<script src="../vendor/jquery.min.js"></script>
|
||||||
<script src="../../transition.js"></script>
|
<script src="../../util.js"></script>
|
||||||
<script src="../../tooltip.js"></script>
|
<script src="../../tooltip.js"></script>
|
||||||
|
|
||||||
<!-- JavaScript Test -->
|
<!-- JavaScript Test -->
|
||||||
|
1154
js/tooltip.js
1154
js/tooltip.js
File diff suppressed because it is too large
Load Diff
165
js/util.js
Normal file
165
js/util.js
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/** =======================================================================
|
||||||
|
* Bootstrap: util.js v4.0.0
|
||||||
|
* http://getbootstrap.com/javascript/#alerts
|
||||||
|
* ========================================================================
|
||||||
|
* Copyright 2011-2015 Twitter, Inc.
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
|
* ========================================================================
|
||||||
|
* @fileoverview - Bootstrap's private util helper. Adds private util
|
||||||
|
* helpers for things like accesibility and transitions. These methods are
|
||||||
|
* shared across all bootstrap plugins.
|
||||||
|
* ========================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
var Bootstrap = {}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
Bootstrap.TRANSITION_END = 'bsTransitionEnd'
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
Bootstrap.TransitionEndEvent = {
|
||||||
|
'WebkitTransition' : 'webkitTransitionEnd',
|
||||||
|
'MozTransition' : 'transitionend',
|
||||||
|
'OTransition' : 'oTransitionEnd otransitionend',
|
||||||
|
'transition' : 'transitionend'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Function} childConstructor
|
||||||
|
* @param {Function} parentConstructor
|
||||||
|
*/
|
||||||
|
Bootstrap.inherits = function(childConstructor, parentConstructor) {
|
||||||
|
/** @constructor */
|
||||||
|
function tempConstructor() {}
|
||||||
|
tempConstructor.prototype = parentConstructor.prototype
|
||||||
|
childConstructor.prototype = new tempConstructor()
|
||||||
|
/** @override */
|
||||||
|
childConstructor.prototype.constructor = childConstructor
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Element} element
|
||||||
|
* @return {string|null}
|
||||||
|
*/
|
||||||
|
Bootstrap.getSelectorFromElement = function (element) {
|
||||||
|
var selector = element.getAttribute('data-target')
|
||||||
|
|
||||||
|
if (!selector) {
|
||||||
|
selector = element.getAttribute('href') || ''
|
||||||
|
selector = /^#[a-z]/i.test(selector) ? selector : null
|
||||||
|
}
|
||||||
|
|
||||||
|
return selector
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} prefix
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
Bootstrap.getUID = function (prefix) {
|
||||||
|
do prefix += ~~(Math.random() * 1000000)
|
||||||
|
while (document.getElementById(prefix))
|
||||||
|
return prefix
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Object}
|
||||||
|
*/
|
||||||
|
Bootstrap.getSpecialTransitionEndEvent = function () {
|
||||||
|
return {
|
||||||
|
bindType: Bootstrap.transition.end,
|
||||||
|
delegateType: Bootstrap.transition.end,
|
||||||
|
handle: /** @param {jQuery.Event} event */ (function (event) {
|
||||||
|
if ($(event.target).is(this)) {
|
||||||
|
return event.handleObj.handler.apply(this, arguments)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Element} element
|
||||||
|
*/
|
||||||
|
Bootstrap.reflow = function (element) {
|
||||||
|
new Function('bs',"return bs")(element.offsetHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Object|boolean}
|
||||||
|
*/
|
||||||
|
Bootstrap.transitionEndTest = function () {
|
||||||
|
if (window['QUnit']) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var el = document.createElement('bootstrap')
|
||||||
|
for (var name in Bootstrap.TransitionEndEvent) {
|
||||||
|
if (el.style[name] !== undefined) {
|
||||||
|
return { end: Bootstrap.TransitionEndEvent[name] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} duration
|
||||||
|
* @this {Element}
|
||||||
|
* @return {Object}
|
||||||
|
*/
|
||||||
|
Bootstrap.transitionEndEmulator = function (duration) {
|
||||||
|
var called = false
|
||||||
|
|
||||||
|
$(this).one(Bootstrap.TRANSITION_END, function () {
|
||||||
|
called = true
|
||||||
|
})
|
||||||
|
|
||||||
|
var callback = function () {
|
||||||
|
if (!called) {
|
||||||
|
$(this).trigger(Bootstrap.transition.end)
|
||||||
|
}
|
||||||
|
}.bind(this)
|
||||||
|
|
||||||
|
setTimeout(callback, duration)
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
* jQuery Interface
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
$.fn.emulateTransitionEnd = Bootstrap.transitionEndEmulator
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
Bootstrap.transition = Bootstrap.transitionEndTest()
|
||||||
|
|
||||||
|
if (!Bootstrap.transition) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$.event.special[Bootstrap.TRANSITION_END] = Bootstrap.getSpecialTransitionEndEvent()
|
||||||
|
})
|
@ -36,8 +36,9 @@
|
|||||||
"grunt": "~0.4.5",
|
"grunt": "~0.4.5",
|
||||||
"grunt-autoprefixer": "~2.2.0",
|
"grunt-autoprefixer": "~2.2.0",
|
||||||
"grunt-banner": "~0.3.1",
|
"grunt-banner": "~0.3.1",
|
||||||
|
"grunt-closure-tools": "^0.9.7",
|
||||||
"grunt-contrib-clean": "~0.6.0",
|
"grunt-contrib-clean": "~0.6.0",
|
||||||
"grunt-contrib-compress": "~0.13.0",
|
"grunt-contrib-compress": "^0.13.0",
|
||||||
"grunt-contrib-concat": "~0.5.0",
|
"grunt-contrib-concat": "~0.5.0",
|
||||||
"grunt-contrib-connect": "~0.9.0",
|
"grunt-contrib-connect": "~0.9.0",
|
||||||
"grunt-contrib-copy": "~0.7.0",
|
"grunt-contrib-copy": "~0.7.0",
|
||||||
@ -63,6 +64,8 @@
|
|||||||
"markdown-it": "^3.0.4",
|
"markdown-it": "^3.0.4",
|
||||||
"mq4-hover-shim": "^0.1.0",
|
"mq4-hover-shim": "^0.1.0",
|
||||||
"npm-shrinkwrap": "^200.0.0",
|
"npm-shrinkwrap": "^200.0.0",
|
||||||
|
"remarkable": "~1.6.0",
|
||||||
|
"superstartup-closure-compiler": "^0.1.6",
|
||||||
"time-grunt": "~1.0.0"
|
"time-grunt": "~1.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user