Commit 6b2b0ed3 authored by fat's avatar fat

al tests passing, dist rebuilt, w/typechecker

parent eaab1def
...@@ -50,6 +50,15 @@ var Util = (function ($) { ...@@ -50,6 +50,15 @@ var Util = (function ($) {
transition: 'transitionend' transition: 'transitionend'
}; };
// shoutout AngusCroll (https://goo.gl/pxwQGp)
function toType(obj) {
return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
}
function isElement(obj) {
return (obj[0] || obj).nodeType;
}
function getSpecialTransitionEndEvent() { function getSpecialTransitionEndEvent() {
return { return {
bindType: transition.end, bindType: transition.end,
...@@ -142,6 +151,21 @@ var Util = (function ($) { ...@@ -142,6 +151,21 @@ var Util = (function ($) {
supportsTransitionEnd: function supportsTransitionEnd() { supportsTransitionEnd: function supportsTransitionEnd() {
return !!transition; return !!transition;
},
typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
for (var property in configTypes) {
var expectedTypes = configTypes[property];
var value = config[property];
var valueType = undefined;
if (value && isElement(value)) valueType = 'element';else valueType = toType(value);
if (!new RegExp(expectedTypes).test(valueType)) {
throw new Error('' + componentName.toUpperCase() + ': ' + ('Option "' + property + '" provided type "' + valueType + '" ') + ('but expected type "' + expectedTypes + '".'));
}
}
} }
}; };
...@@ -536,6 +560,14 @@ var Carousel = (function ($) { ...@@ -536,6 +560,14 @@ var Carousel = (function ($) {
wrap: true wrap: true
}; };
var DefaultType = {
interval: '(number|boolean)',
keyboard: 'boolean',
slide: '(boolean|string)',
pause: '(string|boolean)',
wrap: 'boolean'
};
var Direction = { var Direction = {
NEXT: 'next', NEXT: 'next',
PREVIOUS: 'prev' PREVIOUS: 'prev'
...@@ -587,7 +619,7 @@ var Carousel = (function ($) { ...@@ -587,7 +619,7 @@ var Carousel = (function ($) {
this._isPaused = false; this._isPaused = false;
this._isSliding = false; this._isSliding = false;
this._config = config; this._config = this._getConfig(config);
this._element = $(element)[0]; this._element = $(element)[0];
this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0]; this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0];
...@@ -688,10 +720,17 @@ var Carousel = (function ($) { ...@@ -688,10 +720,17 @@ var Carousel = (function ($) {
this._indicatorsElement = null; this._indicatorsElement = null;
} }
}, { }, {
key: '_addEventListeners', key: '_getConfig',
// private // private
value: function _getConfig(config) {
config = $.extend({}, Default, config);
Util.typeCheckConfig(NAME, config, DefaultType);
return config;
}
}, {
key: '_addEventListeners',
value: function _addEventListeners() { value: function _addEventListeners() {
if (this._config.keyboard) { if (this._config.keyboard) {
$(this._element).on(Event.KEYDOWN, $.proxy(this._keydown, this)); $(this._element).on(Event.KEYDOWN, $.proxy(this._keydown, this));
...@@ -975,7 +1014,12 @@ var Collapse = (function ($) { ...@@ -975,7 +1014,12 @@ var Collapse = (function ($) {
var Default = { var Default = {
toggle: true, toggle: true,
parent: null parent: ''
};
var DefaultType = {
toggle: 'boolean',
parent: 'string'
}; };
var Event = { var Event = {
...@@ -1015,7 +1059,7 @@ var Collapse = (function ($) { ...@@ -1015,7 +1059,7 @@ var Collapse = (function ($) {
this._isTransitioning = false; this._isTransitioning = false;
this._element = element; this._element = element;
this._config = $.extend({}, Default, config); this._config = this._getConfig(config);
this._triggerArray = $.makeArray($('[data-toggle="collapse"][href="#' + element.id + '"],' + ('[data-toggle="collapse"][data-target="#' + element.id + '"]'))); this._triggerArray = $.makeArray($('[data-toggle="collapse"][href="#' + element.id + '"],' + ('[data-toggle="collapse"][data-target="#' + element.id + '"]')));
this._parent = this._config.parent ? this._getParent() : null; this._parent = this._config.parent ? this._getParent() : null;
...@@ -1176,10 +1220,18 @@ var Collapse = (function ($) { ...@@ -1176,10 +1220,18 @@ var Collapse = (function ($) {
this._isTransitioning = null; this._isTransitioning = null;
} }
}, { }, {
key: '_getDimension', key: '_getConfig',
// private // private
value: function _getConfig(config) {
config = $.extend({}, Default, config);
config.toggle = !!config.toggle; // coerce string values
Util.typeCheckConfig(NAME, config, DefaultType);
return config;
}
}, {
key: '_getDimension',
value: function _getDimension() { value: function _getDimension() {
var hasWidth = $(this._element).hasClass(Dimension.WIDTH); var hasWidth = $(this._element).hasClass(Dimension.WIDTH);
return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT; return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;
...@@ -1594,9 +1646,17 @@ var Modal = (function ($) { ...@@ -1594,9 +1646,17 @@ var Modal = (function ($) {
var Default = { var Default = {
backdrop: true, backdrop: true,
keyboard: true, keyboard: true,
focus: true,
show: true show: true
}; };
var DefaultType = {
backdrop: '(boolean|string)',
keyboard: 'boolean',
focus: 'boolean',
show: 'boolean'
};
var Event = { var Event = {
HIDE: 'hide' + EVENT_KEY, HIDE: 'hide' + EVENT_KEY,
HIDDEN: 'hidden' + EVENT_KEY, HIDDEN: 'hidden' + EVENT_KEY,
...@@ -1635,7 +1695,7 @@ var Modal = (function ($) { ...@@ -1635,7 +1695,7 @@ var Modal = (function ($) {
function Modal(element, config) { function Modal(element, config) {
_classCallCheck(this, Modal); _classCallCheck(this, Modal);
this._config = config; this._config = this._getConfig(config);
this._element = element; this._element = element;
this._dialog = $(element).find(Selector.DIALOG)[0]; this._dialog = $(element).find(Selector.DIALOG)[0];
this._backdrop = null; this._backdrop = null;
...@@ -1746,10 +1806,17 @@ var Modal = (function ($) { ...@@ -1746,10 +1806,17 @@ var Modal = (function ($) {
this._scrollbarWidth = null; this._scrollbarWidth = null;
} }
}, { }, {
key: '_showElement', key: '_getConfig',
// private // private
value: function _getConfig(config) {
config = $.extend({}, Default, config);
Util.typeCheckConfig(NAME, config, DefaultType);
return config;
}
}, {
key: '_showElement',
value: function _showElement(relatedTarget) { value: function _showElement(relatedTarget) {
var _this8 = this; var _this8 = this;
...@@ -1769,14 +1836,14 @@ var Modal = (function ($) { ...@@ -1769,14 +1836,14 @@ var Modal = (function ($) {
$(this._element).addClass(ClassName.IN); $(this._element).addClass(ClassName.IN);
this._enforceFocus(); if (this._config.focus) this._enforceFocus();
var shownEvent = $.Event(Event.SHOWN, { var shownEvent = $.Event(Event.SHOWN, {
relatedTarget: relatedTarget relatedTarget: relatedTarget
}); });
var transitionComplete = function transitionComplete() { var transitionComplete = function transitionComplete() {
_this8._element.focus(); if (_this8._config.focus) _this8._element.focus();
$(_this8._element).trigger(shownEvent); $(_this8._element).trigger(shownEvent);
}; };
...@@ -2098,7 +2165,15 @@ var ScrollSpy = (function ($) { ...@@ -2098,7 +2165,15 @@ var ScrollSpy = (function ($) {
var JQUERY_NO_CONFLICT = $.fn[NAME]; var JQUERY_NO_CONFLICT = $.fn[NAME];
var Default = { var Default = {
offset: 10 offset: 10,
method: 'auto',
target: ''
};
var DefaultType = {
offset: 'number',
method: 'string',
target: '(string|element)'
}; };
var Event = { var Event = {
...@@ -2115,8 +2190,14 @@ var ScrollSpy = (function ($) { ...@@ -2115,8 +2190,14 @@ var ScrollSpy = (function ($) {
var Selector = { var Selector = {
DATA_SPY: '[data-spy="scroll"]', DATA_SPY: '[data-spy="scroll"]',
ACTIVE: '.active', ACTIVE: '.active',
LI: 'li',
LI_DROPDOWN: 'li.dropdown', LI_DROPDOWN: 'li.dropdown',
LI: 'li' NAV_ANCHORS: '.nav li > a'
};
var OffsetMethod = {
OFFSET: 'offset',
POSITION: 'position'
}; };
/** /**
...@@ -2131,8 +2212,8 @@ var ScrollSpy = (function ($) { ...@@ -2131,8 +2212,8 @@ var ScrollSpy = (function ($) {
this._element = element; this._element = element;
this._scrollElement = element.tagName === 'BODY' ? window : element; this._scrollElement = element.tagName === 'BODY' ? window : element;
this._config = $.extend({}, Default, config); this._config = this._getConfig(config);
this._selector = '' + (this._config.target || '') + ' .nav li > a'; this._selector = '' + this._config.target + ' ' + Selector.NAV_ANCHORS;
this._offsets = []; this._offsets = [];
this._targets = []; this._targets = [];
this._activeTarget = null; this._activeTarget = null;
...@@ -2152,13 +2233,11 @@ var ScrollSpy = (function ($) { ...@@ -2152,13 +2233,11 @@ var ScrollSpy = (function ($) {
value: function refresh() { value: function refresh() {
var _this14 = this; var _this14 = this;
var offsetMethod = 'offset'; var autoMethod = this._scrollElement !== this._scrollElement.window ? OffsetMethod.POSITION : OffsetMethod.OFFSET;
var offsetBase = 0;
if (this._scrollElement !== this._scrollElement.window) { var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
offsetMethod = 'position';
offsetBase = this._getScrollTop(); var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0;
}
this._offsets = []; this._offsets = [];
this._targets = []; this._targets = [];
...@@ -2204,10 +2283,28 @@ var ScrollSpy = (function ($) { ...@@ -2204,10 +2283,28 @@ var ScrollSpy = (function ($) {
this._scrollHeight = null; this._scrollHeight = null;
} }
}, { }, {
key: '_getScrollTop', key: '_getConfig',
// private // private
value: function _getConfig(config) {
config = $.extend({}, Default, config);
if (typeof config.target !== 'string') {
var id = $(config.target).attr('id');
if (!id) {
id = Util.getUID(NAME);
$(config.target).attr('id', id);
}
config.target = '#' + id;
}
Util.typeCheckConfig(NAME, config, DefaultType);
return config;
}
}, {
key: '_getScrollTop',
value: function _getScrollTop() { value: function _getScrollTop() {
return this._scrollElement === window ? this._scrollElement.scrollY : this._scrollElement.scrollTop; return this._scrollElement === window ? this._scrollElement.scrollY : this._scrollElement.scrollTop;
} }
...@@ -2569,11 +2666,6 @@ var Tab = (function ($) { ...@@ -2569,11 +2666,6 @@ var Tab = (function ($) {
get: function () { get: function () {
return VERSION; return VERSION;
} }
}, {
key: 'Default',
get: function () {
return Default;
}
}, { }, {
key: '_jQueryInterface', key: '_jQueryInterface',
...@@ -2659,7 +2751,20 @@ var Tooltip = (function ($) { ...@@ -2659,7 +2751,20 @@ var Tooltip = (function ($) {
selector: false, selector: false,
placement: 'top', placement: 'top',
offset: '0 0', offset: '0 0',
constraints: null constraints: []
};
var DefaultType = {
animation: 'boolean',
template: 'string',
title: '(string|function)',
trigger: 'string',
delay: '(number|object)',
html: 'boolean',
selector: '(string|boolean)',
placement: '(string|function)',
offset: 'string',
constraints: 'array'
}; };
var AttachmentMap = { var AttachmentMap = {
...@@ -3098,6 +3203,8 @@ var Tooltip = (function ($) { ...@@ -3098,6 +3203,8 @@ var Tooltip = (function ($) {
}; };
} }
Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
return config; return config;
} }
}, { }, {
...@@ -3149,6 +3256,11 @@ var Tooltip = (function ($) { ...@@ -3149,6 +3256,11 @@ var Tooltip = (function ($) {
get: function () { get: function () {
return EVENT_KEY; return EVENT_KEY;
} }
}, {
key: 'DefaultType',
get: function () {
return DefaultType;
}
}, { }, {
key: '_jQueryInterface', key: '_jQueryInterface',
...@@ -3222,6 +3334,10 @@ var Popover = (function ($) { ...@@ -3222,6 +3334,10 @@ var Popover = (function ($) {
template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-title"></h3>' + '<div class="popover-content"></div></div>' template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-title"></h3>' + '<div class="popover-content"></div></div>'
}); });
var DefaultType = $.extend({}, Tooltip.DefaultType, {
content: '(string|function)'
});
var ClassName = { var ClassName = {
FADE: 'fade', FADE: 'fade',
IN: 'in' IN: 'in'
...@@ -3336,6 +3452,11 @@ var Popover = (function ($) { ...@@ -3336,6 +3452,11 @@ var Popover = (function ($) {
get: function () { get: function () {
return EVENT_KEY; return EVENT_KEY;
} }
}, {
key: 'DefaultType',
get: function () {
return DefaultType;
}
}, { }, {
key: '_jQueryInterface', key: '_jQueryInterface',
......
This diff is collapsed.
...@@ -52,6 +52,14 @@ ...@@ -52,6 +52,14 @@
wrap: true wrap: true
}; };
var DefaultType = {
interval: '(number|boolean)',
keyboard: 'boolean',
slide: '(boolean|string)',
pause: '(string|boolean)',
wrap: 'boolean'
};
var Direction = { var Direction = {
NEXT: 'next', NEXT: 'next',
PREVIOUS: 'prev' PREVIOUS: 'prev'
...@@ -103,7 +111,7 @@ ...@@ -103,7 +111,7 @@
this._isPaused = false; this._isPaused = false;
this._isSliding = false; this._isSliding = false;
this._config = config; this._config = this._getConfig(config);
this._element = $(element)[0]; this._element = $(element)[0];
this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0]; this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0];
...@@ -204,10 +212,17 @@ ...@@ -204,10 +212,17 @@
this._indicatorsElement = null; this._indicatorsElement = null;
} }
}, { }, {
key: '_addEventListeners', key: '_getConfig',
// private // private
value: function _getConfig(config) {
config = $.extend({}, Default, config);
_Util.typeCheckConfig(NAME, config, DefaultType);
return config;
}
}, {
key: '_addEventListeners',
value: function _addEventListeners() { value: function _addEventListeners() {
if (this._config.keyboard) { if (this._config.keyboard) {
$(this._element).on(Event.KEYDOWN, $.proxy(this._keydown, this)); $(this._element).on(Event.KEYDOWN, $.proxy(this._keydown, this));
......
...@@ -46,7 +46,12 @@ ...@@ -46,7 +46,12 @@
var Default = { var Default = {
toggle: true, toggle: true,
parent: null parent: ''
};
var DefaultType = {
toggle: 'boolean',
parent: 'string'
}; };
var Event = { var Event = {
...@@ -86,7 +91,7 @@ ...@@ -86,7 +91,7 @@
this._isTransitioning = false; this._isTransitioning = false;
this._element = element; this._element = element;
this._config = $.extend({}, Default, config); this._config = this._getConfig(config);
this._triggerArray = $.makeArray($('[data-toggle="collapse"][href="#' + element.id + '"],' + ('[data-toggle="collapse"][data-target="#' + element.id + '"]'))); this._triggerArray = $.makeArray($('[data-toggle="collapse"][href="#' + element.id + '"],' + ('[data-toggle="collapse"][data-target="#' + element.id + '"]')));
this._parent = this._config.parent ? this._getParent() : null; this._parent = this._config.parent ? this._getParent() : null;
...@@ -247,10 +252,18 @@ ...@@ -247,10 +252,18 @@
this._isTransitioning = null; this._isTransitioning = null;
} }
}, { }, {
key: '_getDimension', key: '_getConfig',
// private // private
value: function _getConfig(config) {
config = $.extend({}, Default, config);
config.toggle = !!config.toggle; // coerce string values
_Util.typeCheckConfig(NAME, config, DefaultType);
return config;
}
}, {
key: '_getDimension',
value: function _getDimension() { value: function _getDimension() {
var hasWidth = $(this._element).hasClass(Dimension.WIDTH); var hasWidth = $(this._element).hasClass(Dimension.WIDTH);
return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT; return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;
......
...@@ -48,9 +48,17 @@ ...@@ -48,9 +48,17 @@
var Default = { var Default = {
backdrop: true, backdrop: true,
keyboard: true, keyboard: true,
focus: true,
show: true show: true
}; };
var DefaultType = {
backdrop: '(boolean|string)',
keyboard: 'boolean',
focus: 'boolean',
show: 'boolean'
};
var Event = { var Event = {
HIDE: 'hide' + EVENT_KEY, HIDE: 'hide' + EVENT_KEY,
HIDDEN: 'hidden' + EVENT_KEY, HIDDEN: 'hidden' + EVENT_KEY,
...@@ -89,7 +97,7 @@ ...@@ -89,7 +97,7 @@
function Modal(element, config) { function Modal(element, config) {
_classCallCheck(this, Modal); _classCallCheck(this, Modal);
this._config = config; this._config = this._getConfig(config);
this._element = element; this._element = element;
this._dialog = $(element).find(Selector.DIALOG)[0]; this._dialog = $(element).find(Selector.DIALOG)[0];
this._backdrop = null; this._backdrop = null;
...@@ -200,10 +208,17 @@ ...@@ -200,10 +208,17 @@
this._scrollbarWidth = null; this._scrollbarWidth = null;
} }
}, { }, {
key: '_showElement', key: '_getConfig',
// private // private
value: function _getConfig(config) {
config = $.extend({}, Default, config);
_Util.typeCheckConfig(NAME, config, DefaultType);
return config;
}
}, {
key: '_showElement',
value: function _showElement(relatedTarget) { value: function _showElement(relatedTarget) {
var _this2 = this; var _this2 = this;
...@@ -223,14 +238,14 @@ ...@@ -223,14 +238,14 @@
$(this._element).addClass(ClassName.IN); $(this._element).addClass(ClassName.IN);
this._enforceFocus(); if (this._config.focus) this._enforceFocus();
var shownEvent = $.Event(Event.SHOWN, { var shownEvent = $.Event(Event.SHOWN, {
relatedTarget: relatedTarget relatedTarget: relatedTarget
}); });
var transitionComplete = function transitionComplete() { var transitionComplete = function transitionComplete() {
_this2._element.focus(); if (_this2._config.focus) _this2._element.focus();
$(_this2._element).trigger(shownEvent); $(_this2._element).trigger(shownEvent);
}; };
......
...@@ -51,6 +51,10 @@ ...@@ -51,6 +51,10 @@
template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-title"></h3>' + '<div class="popover-content"></div></div>' template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-title"></h3>' + '<div class="popover-content"></div></div>'
}); });
var DefaultType = $.extend({}, _Tooltip2.DefaultType, {
content: '(string|function)'
});
var ClassName = { var ClassName = {
FADE: 'fade', FADE: 'fade',
IN: 'in' IN: 'in'
...@@ -165,6 +169,11 @@ ...@@ -165,6 +169,11 @@
get: function () { get: function () {
return EVENT_KEY; return EVENT_KEY;
} }
}, {
key: 'DefaultType',
get: function () {
return DefaultType;
}
}, { }, {
key: '_jQueryInterface', key: '_jQueryInterface',
......
...@@ -44,7 +44,15 @@ ...@@ -44,7 +44,15 @@
var JQUERY_NO_CONFLICT = $.fn[NAME]; var JQUERY_NO_CONFLICT = $.fn[NAME];
var Default = { var Default = {
offset: 10 offset: 10,
method: 'auto',
target: ''
};
var DefaultType = {
offset: 'number',
method: 'string',
target: '(string|element)'
}; };
var Event = { var Event = {
...@@ -61,8 +69,14 @@ ...@@ -61,8 +69,14 @@
var Selector = { var Selector = {
DATA_SPY: '[data-spy="scroll"]', DATA_SPY: '[data-spy="scroll"]',
ACTIVE: '.active', ACTIVE: '.active',
LI: 'li',
LI_DROPDOWN: 'li.dropdown', LI_DROPDOWN: 'li.dropdown',
LI: 'li' NAV_ANCHORS: '.nav li > a'
};
var OffsetMethod = {
OFFSET: 'offset',
POSITION: 'position'
}; };
/** /**
...@@ -77,8 +91,8 @@ ...@@ -77,8 +91,8 @@
this._element = element; this._element = element;
this._scrollElement = element.tagName === 'BODY' ? window : element; this._scrollElement = element.tagName === 'BODY' ? window : element;
this._config = $.extend({}, Default, config); this._config = this._getConfig(config);
this._selector = '' + (this._config.target || '') + ' .nav li > a'; this._selector = '' + this._config.target + ' ' + Selector.NAV_ANCHORS;
this._offsets = []; this._offsets = [];
this._targets = []; this._targets = [];
this._activeTarget = null; this._activeTarget = null;
...@@ -98,13 +112,11 @@ ...@@ -98,13 +112,11 @@
value: function refresh() { value: function refresh() {
var _this = this; var _this = this;
var offsetMethod = 'offset'; var autoMethod = this._scrollElement !== this._scrollElement.window ? OffsetMethod.POSITION : OffsetMethod.OFFSET;
var offsetBase = 0;
if (this._scrollElement !== this._scrollElement.window) { var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
offsetMethod = 'position';
offsetBase = this._getScrollTop(); var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0;
}
this._offsets = []; this._offsets = [];
this._targets = []; this._targets = [];
...@@ -150,10 +162,28 @@ ...@@ -150,10 +162,28 @@
this._scrollHeight = null; this._scrollHeight = null;
} }
}, { }, {
key: '_getScrollTop', key: '_getConfig',
// private // private
value: function _getConfig(config) {
config = $.extend({}, Default, config);
if (typeof config.target !== 'string') {
var id = $(config.target).attr('id');
if (!id) {
id = _Util.getUID(NAME);
$(config.target).attr('id', id);
}
config.target = '#' + id;
}
_Util.typeCheckConfig(NAME, config, DefaultType);
return config;
}
}, {
key: '_getScrollTop',
value: function _getScrollTop() { value: function _getScrollTop() {
return this._scrollElement === window ? this._scrollElement.scrollY : this._scrollElement.scrollTop; return this._scrollElement === window ? this._scrollElement.scrollY : this._scrollElement.scrollTop;
} }
......
...@@ -236,11 +236,6 @@ ...@@ -236,11 +236,6 @@
get: function () { get: function () {
return VERSION; return VERSION;
} }
}, {
key: 'Default',
get: function () {
return Default;
}
}, { }, {
key: '_jQueryInterface', key: '_jQueryInterface',
......
...@@ -54,7 +54,20 @@ ...@@ -54,7 +54,20 @@
selector: false, selector: false,
placement: 'top', placement: 'top',
offset: '0 0', offset: '0 0',
constraints: null constraints: []
};
var DefaultType = {
animation: 'boolean',
template: 'string',
title: '(string|function)',
trigger: 'string',
delay: '(number|object)',
html: 'boolean',
selector: '(string|boolean)',
placement: '(string|function)',
offset: 'string',
constraints: 'array'
}; };
var AttachmentMap = { var AttachmentMap = {
...@@ -493,6 +506,8 @@ ...@@ -493,6 +506,8 @@
}; };
} }
_Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
return config; return config;
} }
}, { }, {
...@@ -544,6 +559,11 @@ ...@@ -544,6 +559,11 @@
get: function () { get: function () {
return EVENT_KEY; return EVENT_KEY;
} }
}, {
key: 'DefaultType',
get: function () {
return DefaultType;
}
}, { }, {
key: '_jQueryInterface', key: '_jQueryInterface',
......
...@@ -37,6 +37,15 @@ ...@@ -37,6 +37,15 @@
transition: 'transitionend' transition: 'transitionend'
}; };
// shoutout AngusCroll (https://goo.gl/pxwQGp)
function toType(obj) {
return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
}
function isElement(obj) {
return (obj[0] || obj).nodeType;
}
function getSpecialTransitionEndEvent() { function getSpecialTransitionEndEvent() {
return { return {
bindType: transition.end, bindType: transition.end,
...@@ -129,6 +138,21 @@ ...@@ -129,6 +138,21 @@
supportsTransitionEnd: function supportsTransitionEnd() { supportsTransitionEnd: function supportsTransitionEnd() {
return !!transition; return !!transition;
},
typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
for (var property in configTypes) {
var expectedTypes = configTypes[property];
var value = config[property];
var valueType = undefined;
if (value && isElement(value)) valueType = 'element';else valueType = toType(value);
if (!new RegExp(expectedTypes).test(valueType)) {
throw new Error('' + componentName.toUpperCase() + ': ' + ('Option "' + property + '" provided type "' + valueType + '" ') + ('but expected type "' + expectedTypes + '".'));
}
}
} }
}; };
......
...@@ -39,7 +39,7 @@ var Carousel = (function ($) { ...@@ -39,7 +39,7 @@ var Carousel = (function ($) {
interval: '(number|boolean)', interval: '(number|boolean)',
keyboard: 'boolean', keyboard: 'boolean',
slide: '(boolean|string)', slide: '(boolean|string)',
pause: 'string', pause: '(string|boolean)',
wrap: 'boolean' wrap: 'boolean'
}; };
......
This diff was suppressed by a .gitattributes entry.
...@@ -29,12 +29,12 @@ var Collapse = (function ($) { ...@@ -29,12 +29,12 @@ var Collapse = (function ($) {
var Default = { var Default = {
toggle: true, toggle: true,
parent: null parent: ''
}; };
var DefaultType = { var DefaultType = {
toggle: 'boolean', toggle: 'boolean',
parent: '(string|null)' parent: 'string'
}; };
var Event = { var Event = {
...@@ -241,7 +241,7 @@ var Collapse = (function ($) { ...@@ -241,7 +241,7 @@ var Collapse = (function ($) {
value: function _getConfig(config) { value: function _getConfig(config) {
config = $.extend({}, Default, config); config = $.extend({}, Default, config);
config.toggle = !!config.toggle; config.toggle = !!config.toggle; // coerce string values
Util.typeCheckConfig(NAME, config, DefaultType); Util.typeCheckConfig(NAME, config, DefaultType);
return config; return config;
} }
......
This diff was suppressed by a .gitattributes entry.
...@@ -27,12 +27,12 @@ const Collapse = (($) => { ...@@ -27,12 +27,12 @@ const Collapse = (($) => {
const Default = { const Default = {
toggle : true, toggle : true,
parent : null parent : ''
} }
const DefaultType = { const DefaultType = {
toggle : 'boolean', toggle : 'boolean',
parent : '(string|null)' parent : 'string'
} }
const Event = { const Event = {
......
...@@ -33,6 +33,8 @@ $(function () { ...@@ -33,6 +33,8 @@ $(function () {
}) })
QUnit.test('should type check config options', function (assert) { QUnit.test('should type check config options', function (assert) {
assert.expect(2)
var message var message
var expectedMessage = 'CAROUSEL: Option "interval" provided type "string" but expected type "(number|boolean)".' var expectedMessage = 'CAROUSEL: Option "interval" provided type "string" but expected type "(number|boolean)".'
var config = { var config = {
...@@ -48,7 +50,7 @@ $(function () { ...@@ -48,7 +50,7 @@ $(function () {
assert.ok(message === expectedMessage, 'correct error message') assert.ok(message === expectedMessage, 'correct error message')
config = { config = {
keyboard: $('div') keyboard: document.createElement('div')
} }
expectedMessage = 'CAROUSEL: Option "keyboard" provided type "element" but expected type "boolean".' expectedMessage = 'CAROUSEL: Option "keyboard" provided type "element" but expected type "boolean".'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment