1
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-08-19 11:51:23 +02:00

Merge branch 'v4-dev' into carousel

This commit is contained in:
Mark Otto
2016-12-04 21:05:19 -08:00
144 changed files with 2863 additions and 2399 deletions

2
js/dist/button.js vendored
View File

@@ -82,7 +82,7 @@ var Button = function ($) {
if (triggerChangeEvent) {
input.checked = !$(this._element).hasClass(ClassName.ACTIVE);
$(this._element).trigger('change');
$(input).trigger('change');
}
input.focus();

File diff suppressed because one or more lines are too long

19
js/dist/carousel.js vendored
View File

@@ -108,9 +108,10 @@ var Carousel = function ($) {
// public
Carousel.prototype.next = function next() {
if (!this._isSliding) {
this._slide(Direction.NEXT);
if (this._isSliding) {
throw new Error('Carousel is sliding');
}
this._slide(Direction.NEXT);
};
Carousel.prototype.nextWhenVisible = function nextWhenVisible() {
@@ -121,9 +122,10 @@ var Carousel = function ($) {
};
Carousel.prototype.prev = function prev() {
if (!this._isSliding) {
this._slide(Direction.PREVIOUS);
if (this._isSliding) {
throw new Error('Carousel is sliding');
}
this._slide(Direction.PREVIOUS);
};
Carousel.prototype.pause = function pause(event) {
@@ -225,11 +227,10 @@ var Carousel = function ($) {
};
Carousel.prototype._keydown = function _keydown(event) {
event.preventDefault();
if (/input|textarea/i.test(event.target.tagName)) {
return;
}
event.preventDefault();
switch (event.which) {
case ARROW_LEFT_KEYCODE:
@@ -336,11 +337,9 @@ var Carousel = function ($) {
$(nextElement).addClass(directionalClassName);
$(activeElement).one(Util.TRANSITION_END, function () {
$(nextElement).removeClass(directionalClassName).removeClass(direction);
$(nextElement).removeClass(directionalClassName + ' ' + direction).addClass(ClassName.ACTIVE);
$(nextElement).addClass(ClassName.ACTIVE);
$(activeElement).removeClass(ClassName.ACTIVE).removeClass(direction).removeClass(directionalClassName);
$(activeElement).removeClass(ClassName.ACTIVE + ' ' + direction + ' ' + directionalClassName);
_this3._isSliding = false;

File diff suppressed because one or more lines are too long

12
js/dist/collapse.js vendored
View File

@@ -103,7 +103,11 @@ var Collapse = function ($) {
Collapse.prototype.show = function show() {
var _this = this;
if (this._isTransitioning || $(this._element).hasClass(ClassName.ACTIVE)) {
if (this._isTransitioning) {
throw new Error('Collapse is transitioning');
}
if ($(this._element).hasClass(ClassName.ACTIVE)) {
return;
}
@@ -176,7 +180,11 @@ var Collapse = function ($) {
Collapse.prototype.hide = function hide() {
var _this2 = this;
if (this._isTransitioning || !$(this._element).hasClass(ClassName.ACTIVE)) {
if (this._isTransitioning) {
throw new Error('Collapse is transitioning');
}
if (!$(this._element).hasClass(ClassName.ACTIVE)) {
return;
}

File diff suppressed because one or more lines are too long

6
js/dist/dropdown.js vendored
View File

@@ -223,11 +223,7 @@ var Dropdown = function ($) {
return;
}
var items = $.makeArray($(Selector.VISIBLE_ITEMS));
items = items.filter(function (item) {
return item.offsetWidth || item.offsetHeight;
});
var items = $(parent).find(Selector.VISIBLE_ITEMS).get();
if (!items.length) {
return;

File diff suppressed because one or more lines are too long

32
js/dist/modal.js vendored
View File

@@ -89,6 +89,7 @@ var Modal = function ($) {
this._isShown = false;
this._isBodyOverflowing = false;
this._ignoreBackdropClick = false;
this._isTransitioning = false;
this._originalBodyPadding = 0;
this._scrollbarWidth = 0;
}
@@ -104,6 +105,13 @@ var Modal = function ($) {
Modal.prototype.show = function show(relatedTarget) {
var _this = this;
if (this._isTransitioning) {
throw new Error('Modal is transitioning');
}
if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
this._isTransitioning = true;
}
var showEvent = $.Event(Event.SHOW, {
relatedTarget: relatedTarget
});
@@ -148,8 +156,16 @@ var Modal = function ($) {
event.preventDefault();
}
var hideEvent = $.Event(Event.HIDE);
if (this._isTransitioning) {
throw new Error('Modal is transitioning');
}
var transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE);
if (transition) {
this._isTransitioning = true;
}
var hideEvent = $.Event(Event.HIDE);
$(this._element).trigger(hideEvent);
if (!this._isShown || hideEvent.isDefaultPrevented()) {
@@ -168,8 +184,7 @@ var Modal = function ($) {
$(this._element).off(Event.CLICK_DISMISS);
$(this._dialog).off(Event.MOUSEDOWN_DISMISS);
if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
if (transition) {
$(this._element).one(Util.TRANSITION_END, function (event) {
return _this2._hideModal(event);
}).emulateTransitionEnd(TRANSITION_DURATION);
@@ -181,10 +196,7 @@ var Modal = function ($) {
Modal.prototype.dispose = function dispose() {
$.removeData(this._element, DATA_KEY);
$(window).off(EVENT_KEY);
$(document).off(EVENT_KEY);
$(this._element).off(EVENT_KEY);
$(this._backdrop).off(EVENT_KEY);
$(window, document, this._element, this._backdrop).off(EVENT_KEY);
this._config = null;
this._element = null;
@@ -237,6 +249,7 @@ var Modal = function ($) {
if (_this3._config.focus) {
_this3._element.focus();
}
_this3._isTransitioning = false;
$(_this3._element).trigger(shownEvent);
};
@@ -288,7 +301,8 @@ var Modal = function ($) {
var _this7 = this;
this._element.style.display = 'none';
this._element.setAttribute('aria-hidden', true);
this._element.setAttribute('aria-hidden', 'true');
this._isTransitioning = false;
this._showBackdrop(function () {
$(document.body).removeClass(ClassName.OPEN);
_this7._resetAdjustments();
@@ -483,7 +497,7 @@ var Modal = function ($) {
var config = $(target).data(DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data());
if (this.tagName === 'A') {
if (this.tagName === 'A' || this.tagName === 'AREA') {
event.preventDefault();
}

File diff suppressed because one or more lines are too long

2
js/dist/popover.js vendored
View File

@@ -95,7 +95,7 @@ var Popover = function ($) {
this.setElementContent($tip.find(Selector.TITLE), this.getTitle());
this.setElementContent($tip.find(Selector.CONTENT), this._getContent());
$tip.removeClass(ClassName.FADE).removeClass(ClassName.ACTIVE);
$tip.removeClass(ClassName.FADE + ' ' + ClassName.ACTIVE);
this.cleanupTether();
};

File diff suppressed because one or more lines are too long

View File

@@ -204,7 +204,7 @@ var ScrollSpy = function ($) {
return;
}
if (this._activeTarget && scrollTop < this._offsets[0]) {
if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
this._activeTarget = null;
this._clear();
return;

File diff suppressed because one or more lines are too long

31
js/dist/tooltip.js vendored
View File

@@ -45,7 +45,8 @@ var Tooltip = function ($) {
selector: false,
placement: 'top',
offset: '0 0',
constraints: []
constraints: [],
container: false
};
var DefaultType = {
@@ -58,7 +59,8 @@ var Tooltip = function ($) {
selector: '(string|boolean)',
placement: '(string|function)',
offset: 'string',
constraints: 'array'
constraints: 'array',
container: '(string|element|boolean)'
};
var AttachmentMap = {
@@ -123,6 +125,7 @@ var Tooltip = function ($) {
this._timeout = 0;
this._hoverState = '';
this._activeTrigger = {};
this._isTransitioning = false;
this._tether = null;
// protected
@@ -185,6 +188,7 @@ var Tooltip = function ($) {
$.removeData(this.element, this.constructor.DATA_KEY);
$(this.element).off(this.constructor.EVENT_KEY);
$(this.element).closest('.modal').off('hide.bs.modal');
if (this.tip) {
$(this.tip).remove();
@@ -207,9 +211,12 @@ var Tooltip = function ($) {
if ($(this.element).css('display') === 'none') {
throw new Error('Please use show on visible elements');
}
var showEvent = $.Event(this.constructor.Event.SHOW);
var showEvent = $.Event(this.constructor.Event.SHOW);
if (this.isWithContent() && this._isEnabled) {
if (this._isTransitioning) {
throw new Error('Tooltip is transitioning');
}
$(this.element).trigger(showEvent);
var isInTheDom = $.contains(this.element.ownerDocument.documentElement, this.element);
@@ -234,7 +241,9 @@ var Tooltip = function ($) {
var attachment = this._getAttachment(placement);
$(tip).data(this.constructor.DATA_KEY, this).appendTo(document.body);
var container = this.config.container === false ? document.body : $(this.config.container);
$(tip).data(this.constructor.DATA_KEY, this).appendTo(container);
$(this.element).trigger(this.constructor.Event.INSERTED);
@@ -257,6 +266,7 @@ var Tooltip = function ($) {
var complete = function complete() {
var prevHoverState = _this._hoverState;
_this._hoverState = null;
_this._isTransitioning = false;
$(_this.element).trigger(_this.constructor.Event.SHOWN);
@@ -266,6 +276,7 @@ var Tooltip = function ($) {
};
if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
this._isTransitioning = true;
$(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(Tooltip._TRANSITION_DURATION);
return;
}
@@ -279,6 +290,9 @@ var Tooltip = function ($) {
var tip = this.getTipElement();
var hideEvent = $.Event(this.constructor.Event.HIDE);
if (this._isTransitioning) {
throw new Error('Tooltip is transitioning');
}
var complete = function complete() {
if (_this2._hoverState !== HoverState.ACTIVE && tip.parentNode) {
tip.parentNode.removeChild(tip);
@@ -286,6 +300,7 @@ var Tooltip = function ($) {
_this2.element.removeAttribute('aria-describedby');
$(_this2.element).trigger(_this2.constructor.Event.HIDDEN);
_this2._isTransitioning = false;
_this2.cleanupTether();
if (callback) {
@@ -302,7 +317,7 @@ var Tooltip = function ($) {
$(tip).removeClass(ClassName.ACTIVE);
if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
this._isTransitioning = true;
$(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
} else {
complete();
@@ -326,7 +341,7 @@ var Tooltip = function ($) {
this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle());
$tip.removeClass(ClassName.FADE).removeClass(ClassName.ACTIVE);
$tip.removeClass(ClassName.FADE + ' ' + ClassName.ACTIVE);
this.cleanupTether();
};
@@ -389,6 +404,10 @@ var Tooltip = function ($) {
return _this3._leave(event);
});
}
$(_this3.element).closest('.modal').on('hide.bs.modal', function () {
return _this3.hide();
});
});
if (this.config.selector) {

File diff suppressed because one or more lines are too long

View File

@@ -90,7 +90,7 @@ const Button = (($) => {
if (triggerChangeEvent) {
input.checked = !$(this._element).hasClass(ClassName.ACTIVE)
$(this._element).trigger('change')
$(input).trigger('change')
}
input.focus()

View File

@@ -120,9 +120,10 @@ const Carousel = (($) => {
// public
next() {
if (!this._isSliding) {
this._slide(Direction.NEXT)
if (this._isSliding) {
throw new Error('Carousel is sliding')
}
this._slide(Direction.NEXT)
}
nextWhenVisible() {
@@ -133,9 +134,10 @@ const Carousel = (($) => {
}
prev() {
if (!this._isSliding) {
this._slide(Direction.PREVIOUS)
if (this._isSliding) {
throw new Error('Carousel is sliding')
}
this._slide(Direction.PREVIOUS)
}
pause(event) {
@@ -236,11 +238,10 @@ const Carousel = (($) => {
}
_keydown(event) {
event.preventDefault()
if (/input|textarea/i.test(event.target.tagName)) {
return
}
event.preventDefault()
switch (event.which) {
case ARROW_LEFT_KEYCODE:
@@ -372,15 +373,10 @@ const Carousel = (($) => {
$(activeElement)
.one(Util.TRANSITION_END, () => {
$(nextElement)
.removeClass(directionalClassName)
.removeClass(orderClassName)
.removeClass(`${directionalClassName} ${orderClassName}`)
.addClass(ClassName.ACTIVE)
$(nextElement).addClass(ClassName.ACTIVE)
$(activeElement)
.removeClass(ClassName.ACTIVE)
.removeClass(orderClassName)
.removeClass(directionalClassName)
$(activeElement).removeClass(`${ClassName.ACTIVE} ${orderClassName} ${directionalClassName}`)
this._isSliding = false

View File

@@ -112,8 +112,11 @@ const Collapse = (($) => {
}
show() {
if (this._isTransitioning ||
$(this._element).hasClass(ClassName.ACTIVE)) {
if (this._isTransitioning) {
throw new Error('Collapse is transitioning')
}
if ($(this._element).hasClass(ClassName.ACTIVE)) {
return
}
@@ -193,8 +196,11 @@ const Collapse = (($) => {
}
hide() {
if (this._isTransitioning ||
!$(this._element).hasClass(ClassName.ACTIVE)) {
if (this._isTransitioning) {
throw new Error('Collapse is transitioning')
}
if (!$(this._element).hasClass(ClassName.ACTIVE)) {
return
}

View File

@@ -239,11 +239,7 @@ const Dropdown = (($) => {
return
}
let items = $.makeArray($(Selector.VISIBLE_ITEMS))
items = items.filter((item) => {
return item.offsetWidth || item.offsetHeight
})
const items = $(parent).find(Selector.VISIBLE_ITEMS).get()
if (!items.length) {
return

View File

@@ -87,6 +87,7 @@ const Modal = (($) => {
this._isShown = false
this._isBodyOverflowing = false
this._ignoreBackdropClick = false
this._isTransitioning = false
this._originalBodyPadding = 0
this._scrollbarWidth = 0
}
@@ -110,6 +111,14 @@ const Modal = (($) => {
}
show(relatedTarget) {
if (this._isTransitioning) {
throw new Error('Modal is transitioning')
}
if (Util.supportsTransitionEnd() &&
$(this._element).hasClass(ClassName.FADE)) {
this._isTransitioning = true
}
const showEvent = $.Event(Event.SHOW, {
relatedTarget
})
@@ -152,8 +161,17 @@ const Modal = (($) => {
event.preventDefault()
}
const hideEvent = $.Event(Event.HIDE)
if (this._isTransitioning) {
throw new Error('Modal is transitioning')
}
const transition = Util.supportsTransitionEnd() &&
$(this._element).hasClass(ClassName.FADE)
if (transition) {
this._isTransitioning = true
}
const hideEvent = $.Event(Event.HIDE)
$(this._element).trigger(hideEvent)
if (!this._isShown || hideEvent.isDefaultPrevented()) {
@@ -172,9 +190,7 @@ const Modal = (($) => {
$(this._element).off(Event.CLICK_DISMISS)
$(this._dialog).off(Event.MOUSEDOWN_DISMISS)
if (Util.supportsTransitionEnd() &&
$(this._element).hasClass(ClassName.FADE)) {
if (transition) {
$(this._element)
.one(Util.TRANSITION_END, (event) => this._hideModal(event))
.emulateTransitionEnd(TRANSITION_DURATION)
@@ -186,10 +202,7 @@ const Modal = (($) => {
dispose() {
$.removeData(this._element, DATA_KEY)
$(window).off(EVENT_KEY)
$(document).off(EVENT_KEY)
$(this._element).off(EVENT_KEY)
$(this._backdrop).off(EVENT_KEY)
$(window, document, this._element, this._backdrop).off(EVENT_KEY)
this._config = null
this._element = null
@@ -243,6 +256,7 @@ const Modal = (($) => {
if (this._config.focus) {
this._element.focus()
}
this._isTransitioning = false
$(this._element).trigger(shownEvent)
}
@@ -290,7 +304,8 @@ const Modal = (($) => {
_hideModal() {
this._element.style.display = 'none'
this._element.setAttribute('aria-hidden', true)
this._element.setAttribute('aria-hidden', 'true')
this._isTransitioning = false
this._showBackdrop(() => {
$(document.body).removeClass(ClassName.OPEN)
this._resetAdjustments()
@@ -489,7 +504,7 @@ const Modal = (($) => {
const config = $(target).data(DATA_KEY) ?
'toggle' : $.extend({}, $(target).data(), $(this).data())
if (this.tagName === 'A') {
if (this.tagName === 'A' || this.tagName === 'AREA') {
event.preventDefault()
}

View File

@@ -117,9 +117,7 @@ const Popover = (($) => {
this.setElementContent($tip.find(Selector.TITLE), this.getTitle())
this.setElementContent($tip.find(Selector.CONTENT), this._getContent())
$tip
.removeClass(ClassName.FADE)
.removeClass(ClassName.ACTIVE)
$tip.removeClass(`${ClassName.FADE} ${ClassName.ACTIVE}`)
this.cleanupTether()
}

View File

@@ -221,7 +221,7 @@ const ScrollSpy = (($) => {
return
}
if (this._activeTarget && scrollTop < this._offsets[0]) {
if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
this._activeTarget = null
this._clear()
return

View File

@@ -46,7 +46,8 @@ const Tooltip = (($) => {
selector : false,
placement : 'top',
offset : '0 0',
constraints : []
constraints : [],
container : false
}
const DefaultType = {
@@ -59,7 +60,8 @@ const Tooltip = (($) => {
selector : '(string|boolean)',
placement : '(string|function)',
offset : 'string',
constraints : 'array'
constraints : 'array',
container : '(string|element|boolean)'
}
const AttachmentMap = {
@@ -121,11 +123,12 @@ const Tooltip = (($) => {
constructor(element, config) {
// private
this._isEnabled = true
this._timeout = 0
this._hoverState = ''
this._activeTrigger = {}
this._tether = null
this._isEnabled = true
this._timeout = 0
this._hoverState = ''
this._activeTrigger = {}
this._isTransitioning = false
this._tether = null
// protected
this.element = element
@@ -222,6 +225,7 @@ const Tooltip = (($) => {
$.removeData(this.element, this.constructor.DATA_KEY)
$(this.element).off(this.constructor.EVENT_KEY)
$(this.element).closest('.modal').off('hide.bs.modal')
if (this.tip) {
$(this.tip).remove()
@@ -242,9 +246,12 @@ const Tooltip = (($) => {
if ($(this.element).css('display') === 'none') {
throw new Error('Please use show on visible elements')
}
const showEvent = $.Event(this.constructor.Event.SHOW)
const showEvent = $.Event(this.constructor.Event.SHOW)
if (this.isWithContent() && this._isEnabled) {
if (this._isTransitioning) {
throw new Error('Tooltip is transitioning')
}
$(this.element).trigger(showEvent)
const isInTheDom = $.contains(
@@ -274,9 +281,11 @@ const Tooltip = (($) => {
const attachment = this._getAttachment(placement)
const container = this.config.container === false ? document.body : $(this.config.container)
$(tip)
.data(this.constructor.DATA_KEY, this)
.appendTo(document.body)
.appendTo(container)
$(this.element).trigger(this.constructor.Event.INSERTED)
@@ -298,7 +307,8 @@ const Tooltip = (($) => {
const complete = () => {
const prevHoverState = this._hoverState
this._hoverState = null
this._hoverState = null
this._isTransitioning = false
$(this.element).trigger(this.constructor.Event.SHOWN)
@@ -308,6 +318,7 @@ const Tooltip = (($) => {
}
if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
this._isTransitioning = true
$(this.tip)
.one(Util.TRANSITION_END, complete)
.emulateTransitionEnd(Tooltip._TRANSITION_DURATION)
@@ -321,6 +332,9 @@ const Tooltip = (($) => {
hide(callback) {
const tip = this.getTipElement()
const hideEvent = $.Event(this.constructor.Event.HIDE)
if (this._isTransitioning) {
throw new Error('Tooltip is transitioning')
}
const complete = () => {
if (this._hoverState !== HoverState.ACTIVE && tip.parentNode) {
tip.parentNode.removeChild(tip)
@@ -328,6 +342,7 @@ const Tooltip = (($) => {
this.element.removeAttribute('aria-describedby')
$(this.element).trigger(this.constructor.Event.HIDDEN)
this._isTransitioning = false
this.cleanupTether()
if (callback) {
@@ -345,7 +360,7 @@ const Tooltip = (($) => {
if (Util.supportsTransitionEnd() &&
$(this.tip).hasClass(ClassName.FADE)) {
this._isTransitioning = true
$(tip)
.one(Util.TRANSITION_END, complete)
.emulateTransitionEnd(TRANSITION_DURATION)
@@ -373,9 +388,7 @@ const Tooltip = (($) => {
this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle())
$tip
.removeClass(ClassName.FADE)
.removeClass(ClassName.ACTIVE)
$tip.removeClass(`${ClassName.FADE} ${ClassName.ACTIVE}`)
this.cleanupTether()
}
@@ -452,6 +465,11 @@ const Tooltip = (($) => {
(event) => this._leave(event)
)
}
$(this.element).closest('.modal').on(
'hide.bs.modal',
() => this.hide()
)
})
if (this.config.selector) {

View File

@@ -72,6 +72,26 @@ $(function () {
assert.strictEqual($btn.attr('aria-pressed'), 'true', 'btn aria-pressed state is true')
})
QUnit.test('should trigger input change event when toggled button has input field', function (assert) {
assert.expect(1)
var done = assert.async()
var groupHTML = '<div class="btn-group" data-toggle="buttons">'
+ '<label class="btn btn-primary">'
+ '<input type="radio" id="radio" autocomplete="off">Radio'
+ '</label>'
+ '</div>'
var $group = $(groupHTML).appendTo('#qunit-fixture')
$group.find('input').on('change', function (e) {
e.preventDefault()
assert.ok(true, 'change event fired')
done()
})
$group.find('label').trigger('click')
})
QUnit.test('should check for closest matching toggle', function (assert) {
assert.expect(12)
var groupHTML = '<div class="btn-group" data-toggle="buttons">'

View File

@@ -759,4 +759,36 @@ $(function () {
.bootstrapCarousel('prev')
assert.strictEqual($carousel.find('.carousel-item.active').attr('id'), 'one', 'carousel did not wrap around and stayed on 1st slide')
})
QUnit.test('should not prevent keydown for inputs and textareas', function (assert) {
assert.expect(2)
var templateHTML = '<div id="myCarousel" class="carousel" data-interval="false">'
+ '<div class="carousel-inner">'
+ '<div id="first" class="carousel-item">'
+ '<input type="text" id="inputText" />'
+ '</div>'
+ '<div id="second" class="carousel-item active">'
+ '<textarea id="txtArea"></textarea>'
+ '</div>'
+ '</div>'
+ '</div>'
var $template = $(templateHTML)
var done = assert.async()
$template.appendTo('#qunit-fixture')
var $inputText = $template.find('#inputText')
var $textArea = $template.find('#txtArea')
$template.bootstrapCarousel()
var eventKeyDown = $.Event('keydown', { which: 65 }) // 65 for "a"
$inputText.on('keydown', function (event) {
assert.strictEqual(event.isDefaultPrevented(), false)
})
$inputText.trigger(eventKeyDown)
$textArea.on('keydown', function (event) {
assert.strictEqual(event.isDefaultPrevented(), false)
done()
})
$textArea.trigger(eventKeyDown)
})
})

View File

@@ -174,6 +174,19 @@ $(function () {
.bootstrapModal('show')
})
QUnit.test('should not close modal when clicking outside of modal-content if data-backdrop="true"', function (assert) {
assert.expect(1)
var done = assert.async()
$('<div id="modal-test" data-backdrop="false"><div class="contents"/></div>')
.on('shown.bs.modal', function () {
$('#modal-test').trigger('click')
assert.ok($('#modal-test').is(':visible'), 'modal not hidden')
done()
})
.bootstrapModal('show')
})
QUnit.test('should close modal when escape key is pressed via keydown', function (assert) {
assert.expect(3)
var done = assert.async()
@@ -441,4 +454,26 @@ $(function () {
})
.bootstrapModal('show')
})
QUnit.test('should not follow link in area tag', function (assert) {
assert.expect(2)
var done = assert.async()
$('<map><area id="test" shape="default" data-toggle="modal" data-target="#modal-test" href="demo.html"/></map>')
.appendTo('#qunit-fixture')
$('<div id="modal-test"><div class="contents"><div id="close" data-dismiss="modal"/></div></div>')
.appendTo('#qunit-fixture')
$('#test')
.on('click.bs.modal.data-api', function (event) {
assert.notOk(event.isDefaultPrevented(), 'navigating to href will happen')
setTimeout(function () {
assert.ok(event.isDefaultPrevented(), 'model shown instead of navigating to href')
done()
}, 1)
})
.trigger('click')
})
})

View File

@@ -287,6 +287,50 @@ $(function () {
.scrollTop(201)
})
QUnit.test('should NOT clear selection if above the first section and first section is at the top', function (assert) {
assert.expect(4)
var done = assert.async()
var sectionHTML = '<div id="header" style="height: 500px;"></div>'
+ '<nav id="navigation" class="navbar">'
+ '<ul class="nav navbar-nav">'
+ '<li><a id="one-link" class="nav-link active" href="#one">One</a></li>'
+ '<li><a id="two-link" class="nav-link" href="#two">Two</a></li>'
+ '<li><a id="three-link" class="nav-link" href="#three">Three</a></li>'
+ '</ul>'
+ '</nav>'
$(sectionHTML).appendTo('#qunit-fixture')
var negativeHeight = -10
var startOfSectionTwo = 101
var scrollspyHTML = '<div id="content" style="height: 200px; overflow-y: auto;">'
+ '<div id="one" style="height: 100px;"/>'
+ '<div id="two" style="height: 100px;"/>'
+ '<div id="three" style="height: 100px;"/>'
+ '<div id="spacer" style="height: 100px;"/>'
+ '</div>'
var $scrollspy = $(scrollspyHTML).appendTo('#qunit-fixture')
$scrollspy
.bootstrapScrollspy({
target: '#navigation',
offset: $scrollspy.position().top
})
.one('scroll', function () {
assert.strictEqual($('.active').length, 1, '"active" class on only one element present')
assert.strictEqual($('.active').is('#two-link'), true, '"active" class on second section')
$scrollspy
.one('scroll', function () {
assert.strictEqual($('.active').length, 1, '"active" class on only one element present')
assert.strictEqual($('.active').is('#one-link'), true, '"active" class on first section')
done()
})
.scrollTop(negativeHeight)
})
.scrollTop(startOfSectionTwo)
})
QUnit.test('should correctly select navigation element on backward scrolling when each target section height is 100%', function (assert) {
assert.expect(5)
var navbarHtml =

View File

@@ -46,11 +46,31 @@
<script src="../../dist/carousel.js"></script>
<script>
$(function() {
// Should throw an error because carousel is in transition
function testCarouselTransitionError() {
var err = false
var $carousel = $('#carousel-example-generic')
$carousel.on('slid.bs.carousel', function () {
$carousel.off('slid.bs.carousel')
if (!err) {
alert('No error thrown for : testCarouselTransitionError')
}
})
try {
$carousel.carousel('next').carousel('prev')
}
catch (e) {
err = true
console.error(e.message)
}
}
$(function () {
// Test to show that the carousel doesn't slide when the current tab isn't visible
$('#carousel-example-generic').on('slid.bs.carousel', function(event) {
$('#carousel-example-generic').on('slid.bs.carousel', function (event) {
console.log('slid at ', event.timeStamp)
})
testCarouselTransitionError()
})
</script>
</body>

View File

@@ -61,5 +61,30 @@
<script src="../vendor/jquery.min.js"></script>
<script src="../../dist/util.js"></script>
<script src="../../dist/collapse.js"></script>
<script>
// JavaScript Test
$(function () {
testCollapseTransitionError()
});
// Should throw an error because carousel is in transition
function testCollapseTransitionError() {
var err = false
$('#collapseOne').on('hidden.bs.collapse', function (e) {
$(this).off('hidden.bs.collapse')
if (!err) {
alert('No error thrown for : testCollapseTransitionError')
}
})
try {
$('#collapseOne').collapse('hide').collapse('show')
}
catch (e) {
err = true
console.error(e.message)
}
}
</script>
</body>
</html>

View File

@@ -188,6 +188,26 @@
}
}
// Should throw an error because modal is in transition
function testModalTransitionError() {
var err = false
// Close #myModal
$('#myModal').on('shown.bs.modal', function () {
$('#myModal').modal('hide').off('shown.bs.modal')
if (!err) {
alert('No error thrown for : testModalTransitionError')
}
})
try {
$('#myModal').modal('show').modal('hide')
}
catch (e) {
err = true
console.error(e.message)
}
}
$(function () {
$('[data-toggle="popover"]').popover()
$('[data-toggle="tooltip"]').tooltip()
@@ -200,6 +220,7 @@
$('#firefoxModal').on('focus', reportFirefoxTestResult.bind(false))
$('#ff-bug-input').on('focus', reportFirefoxTestResult.bind(true))
})
testModalTransitionError()
})
</script>
</body>

View File

@@ -42,7 +42,26 @@
<script>
$(function () {
$('[data-toggle="tooltip"]').tooltip()
testTooltipTransitionError()
})
// Should throw an error because tooltip is in transition
function testTooltipTransitionError() {
var err = false
$('#btnOne').on('shown.bs.tooltip', function () {
$('#btnOne').tooltip('hide').off('shown.bs.tooltip')
if (!err) {
alert('No error thrown for : testTooltipTransitionError')
}
})
try {
$('#btnOne').tooltip('show').tooltip('hide')
}
catch (e) {
err = true
console.error(e.message)
}
}
</script>
</body>
</html>