1
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-10-01 15:56:45 +02:00

add simple type checker implementation

This commit is contained in:
fat
2015-05-13 14:46:50 -07:00
parent c2ced2292a
commit eaab1def7a
25 changed files with 258 additions and 28 deletions

View File

@@ -33,6 +33,14 @@ const Carousel = (($) => {
wrap : true
}
const DefaultType = {
interval : '(number|boolean)',
keyboard : 'boolean',
slide : '(boolean|string)',
pause : '(string|boolean)',
wrap : 'boolean'
}
const Direction = {
NEXT : 'next',
PREVIOUS : 'prev'
@@ -84,7 +92,7 @@ const Carousel = (($) => {
this._isPaused = false
this._isSliding = false
this._config = config
this._config = this._getConfig(config)
this._element = $(element)[0]
this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0]
@@ -193,6 +201,12 @@ const Carousel = (($) => {
// private
_getConfig(config) {
config = $.extend({}, Default, config)
Util.typeCheckConfig(NAME, config, DefaultType)
return config
}
_addEventListeners() {
if (this._config.keyboard) {
$(this._element)

View File

@@ -30,6 +30,11 @@ const Collapse = (($) => {
parent : null
}
const DefaultType = {
toggle : 'boolean',
parent : '(string|null)'
}
const Event = {
SHOW : `show${EVENT_KEY}`,
SHOWN : `shown${EVENT_KEY}`,
@@ -67,7 +72,7 @@ const Collapse = (($) => {
constructor(element, config) {
this._isTransitioning = false
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}"]`
@@ -259,6 +264,13 @@ const Collapse = (($) => {
// private
_getConfig(config) {
config = $.extend({}, Default, config)
config.toggle = !!config.toggle // coerce string values
Util.typeCheckConfig(NAME, config, DefaultType)
return config
}
_getDimension() {
let hasWidth = $(this._element).hasClass(Dimension.WIDTH)
return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT

View File

@@ -33,6 +33,13 @@ const Modal = (($) => {
show : true
}
const DefaultType = {
backdrop : '(boolean|string)',
keyboard : 'boolean',
focus : 'boolean',
show : 'boolean'
}
const Event = {
HIDE   : `hide${EVENT_KEY}`,
HIDDEN   : `hidden${EVENT_KEY}`,
@@ -71,7 +78,7 @@ const Modal = (($) => {
class Modal {
constructor(element, config) {
this._config = config
this._config = this._getConfig(config)
this._element = element
this._dialog = $(element).find(Selector.DIALOG)[0]
this._backdrop = null
@@ -198,6 +205,12 @@ const Modal = (($) => {
// private
_getConfig(config) {
config = $.extend({}, Default, config)
Util.typeCheckConfig(NAME, config, DefaultType)
return config
}
_showElement(relatedTarget) {
let transition = Util.supportsTransitionEnd() &&
$(this._element).hasClass(ClassName.FADE)

View File

@@ -33,6 +33,10 @@ const Popover = (($) => {
+ '<div class="popover-content"></div></div>'
})
const DefaultType = $.extend({}, Tooltip.DefaultType, {
content : '(string|function)'
})
const ClassName = {
FADE : 'fade',
IN : 'in'
@@ -93,6 +97,10 @@ const Popover = (($) => {
return EVENT_KEY
}
static get DefaultType() {
return DefaultType
}
// overrides

View File

@@ -30,6 +30,12 @@ const ScrollSpy = (($) => {
target : ''
}
const DefaultType = {
offset : 'number',
method : 'string',
target : '(string|element)'
}
const Event = {
ACTIVATE : `activate${EVENT_KEY}`,
SCROLL : `scroll${EVENT_KEY}`,
@@ -164,6 +170,8 @@ const ScrollSpy = (($) => {
config.target = `#${id}`
}
Util.typeCheckConfig(NAME, config, DefaultType)
return config
}

View File

@@ -72,10 +72,6 @@ const Tab = (($) => {
return VERSION
}
static get Default() {
return Default
}
// public

View File

@@ -37,7 +37,20 @@ const Tooltip = (($) => {
selector : false,
placement : 'top',
offset : '0 0',
constraints : null
constraints : []
}
const 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'
}
const AttachmentMap = {
@@ -141,6 +154,10 @@ const Tooltip = (($) => {
return EVENT_KEY
}
static get DefaultType() {
return DefaultType
}
// public
@@ -544,6 +561,12 @@ const Tooltip = (($) => {
}
}
Util.typeCheckConfig(
NAME,
config,
this.constructor.DefaultType
)
return config
}

View File

@@ -23,6 +23,15 @@ const Util = (($) => {
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() {
return {
bindType: transition.end,
@@ -115,6 +124,25 @@ const Util = (($) => {
supportsTransitionEnd() {
return !!transition
},
typeCheckConfig(componentName, config, configTypes) {
for (let property in configTypes) {
let expectedTypes = configTypes[property]
let value = config[property]
let valueType
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}".`)
}
}
}
}