0
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-02-26 23:54:23 +01:00

feat(config.js): provide a setConfig method for all js components

This commit is contained in:
GeoSot 2022-05-11 12:36:05 +03:00
parent d388bd6e1b
commit 04ab8ba426
9 changed files with 63 additions and 11 deletions

View File

@ -30,7 +30,7 @@ class BaseComponent extends Config {
} }
this._element = element this._element = element
this._config = this._getConfig(config) this.setConfig(this._getInitialConfig(config))
Data.set(this._element, this.constructor.DATA_KEY, this) Data.set(this._element, this.constructor.DATA_KEY, this)
} }
@ -49,7 +49,7 @@ class BaseComponent extends Config {
executeAfterTransition(callback, element, isAnimated) executeAfterTransition(callback, element, isAnimated)
} }
_getConfig(config) { _getInitialConfig(config) {
config = this._mergeConfigObj(config, this._element) config = this._mergeConfigObj(config, this._element)
config = this._configAfterMerge(config) config = this._configAfterMerge(config)
this._typeCheckConfig(config) this._typeCheckConfig(config)

View File

@ -205,8 +205,8 @@ class Dropdown extends BaseComponent {
EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget) EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget)
} }
_getConfig(config) { _getInitialConfig(config) {
config = super._getConfig(config) config = super._getInitialConfig(config)
if (typeof config.reference === 'object' && !isElement(config.reference) && if (typeof config.reference === 'object' && !isElement(config.reference) &&
typeof config.reference.getBoundingClientRect !== 'function' typeof config.reference.getBoundingClientRect !== 'function'

View File

@ -562,7 +562,7 @@ class Tooltip extends BaseComponent {
return Object.values(this._activeTrigger).includes(true) return Object.values(this._activeTrigger).includes(true)
} }
_getConfig(config) { _getInitialConfig(config) {
const dataAttributes = Manipulator.getDataAttributes(this._element) const dataAttributes = Manipulator.getDataAttributes(this._element)
for (const dataAttribute of Object.keys(dataAttributes)) { for (const dataAttribute of Object.keys(dataAttributes)) {

View File

@ -41,7 +41,7 @@ const DefaultType = {
class Backdrop extends Config { class Backdrop extends Config {
constructor(config) { constructor(config) {
super() super()
this._config = this._getConfig(config) this.setConfig(this._getInitialConfig(config))
this._isAppended = false this._isAppended = false
this._element = null this._element = null
} }

View File

@ -13,6 +13,8 @@ import Manipulator from '../dom/manipulator'
*/ */
class Config { class Config {
_config = {}
// Getters // Getters
static get Default() { static get Default() {
return {} return {}
@ -26,10 +28,17 @@ class Config {
throw new Error('You have to implement the static method "NAME", for each component!') throw new Error('You have to implement the static method "NAME", for each component!')
} }
_getConfig(config) { setConfig(config) {
this._typeCheckConfig(config)
this._config = {
...this._config,
...(typeof config === 'object' ? config : {})
}
}
_getInitialConfig(config) {
config = this._mergeConfigObj(config) config = this._mergeConfigObj(config)
config = this._configAfterMerge(config) config = this._configAfterMerge(config)
this._typeCheckConfig(config)
return config return config
} }

View File

@ -40,7 +40,7 @@ const DefaultType = {
class FocusTrap extends Config { class FocusTrap extends Config {
constructor(config) { constructor(config) {
super() super()
this._config = this._getConfig(config) this.setConfig(this._getInitialConfig(config))
this._isActive = false this._isActive = false
this._lastTabNavDirection = null this._lastTabNavDirection = null
} }

View File

@ -50,7 +50,7 @@ class Swipe extends Config {
return return
} }
this._config = this._getConfig(config) this.setConfig(this._getInitialConfig(config))
this._deltaX = 0 this._deltaX = 0
this._supportPointerEvents = Boolean(window.PointerEvent) this._supportPointerEvents = Boolean(window.PointerEvent)
this._initEvents() this._initEvents()

View File

@ -48,7 +48,7 @@ const DefaultContentType = {
class TemplateFactory extends Config { class TemplateFactory extends Config {
constructor(config) { constructor(config) {
super() super()
this._config = this._getConfig(config) this.setConfig(this._getInitialConfig(config))
} }
// Getters // Getters

View File

@ -37,6 +37,49 @@ describe('Config', () => {
}) })
}) })
describe('setConfig', () => {
it('should merge config object', () => {
const instance = new DummyConfigClass()
spyOnProperty(DummyConfigClass, 'DefaultType', 'get').and.returnValue({
testBool: 'boolean',
testString: 'string'
})
instance.setConfig({
testBool: true,
testString: 'foo'
})
expect(instance._config.testBool).toBeTrue()
expect(instance._config.testString).toEqual('foo')
instance.setConfig({
testBool: false,
testString: 'bar'
})
expect(instance._config.testBool).toBeFalse()
expect(instance._config.testString).toEqual('bar')
})
it('should check values before merging them', () => {
const instance = new DummyConfigClass()
spyOnProperty(DummyConfigClass, 'DefaultType', 'get').and.returnValue({
testBool: 'boolean',
testString: 'string'
})
expect(() => {
instance.setConfig({
testBool: 'foo',
testString: true
})
}).toThrowError(TypeError)
})
})
describe('mergeConfigObj', () => { describe('mergeConfigObj', () => {
it('should parse element\'s data attributes and merge it with default config. Element\'s data attributes must excel Defaults', () => { it('should parse element\'s data attributes and merge it with default config. Element\'s data attributes must excel Defaults', () => {
fixtureEl.innerHTML = '<div id="test" data-bs-test-bool="false" data-bs-test-int="8" data-bs-test-string1="bar"></div>' fixtureEl.innerHTML = '<div id="test" data-bs-test-bool="false" data-bs-test-int="8" data-bs-test-string1="bar"></div>'