diff --git a/js/src/base-component.js b/js/src/base-component.js index 09de681beb..9201df3e39 100644 --- a/js/src/base-component.js +++ b/js/src/base-component.js @@ -30,7 +30,7 @@ class BaseComponent extends Config { } this._element = element - this._config = this._getConfig(config) + this.setConfig(this._getInitialConfig(config)) Data.set(this._element, this.constructor.DATA_KEY, this) } @@ -49,7 +49,7 @@ class BaseComponent extends Config { executeAfterTransition(callback, element, isAnimated) } - _getConfig(config) { + _getInitialConfig(config) { config = this._mergeConfigObj(config, this._element) config = this._configAfterMerge(config) this._typeCheckConfig(config) diff --git a/js/src/dropdown.js b/js/src/dropdown.js index 87dc496764..461e9b2e56 100644 --- a/js/src/dropdown.js +++ b/js/src/dropdown.js @@ -205,8 +205,8 @@ class Dropdown extends BaseComponent { EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget) } - _getConfig(config) { - config = super._getConfig(config) + _getInitialConfig(config) { + config = super._getInitialConfig(config) if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function' diff --git a/js/src/tooltip.js b/js/src/tooltip.js index a7368d085b..0356e4875a 100644 --- a/js/src/tooltip.js +++ b/js/src/tooltip.js @@ -562,7 +562,7 @@ class Tooltip extends BaseComponent { return Object.values(this._activeTrigger).includes(true) } - _getConfig(config) { + _getInitialConfig(config) { const dataAttributes = Manipulator.getDataAttributes(this._element) for (const dataAttribute of Object.keys(dataAttributes)) { diff --git a/js/src/util/backdrop.js b/js/src/util/backdrop.js index 31619de719..96e15641f8 100644 --- a/js/src/util/backdrop.js +++ b/js/src/util/backdrop.js @@ -41,7 +41,7 @@ const DefaultType = { class Backdrop extends Config { constructor(config) { super() - this._config = this._getConfig(config) + this.setConfig(this._getInitialConfig(config)) this._isAppended = false this._element = null } diff --git a/js/src/util/config.js b/js/src/util/config.js index 1878de3307..1e4c8a83db 100644 --- a/js/src/util/config.js +++ b/js/src/util/config.js @@ -13,6 +13,8 @@ import Manipulator from '../dom/manipulator' */ class Config { + _config = {} + // Getters static get Default() { return {} @@ -26,10 +28,17 @@ class Config { 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._configAfterMerge(config) - this._typeCheckConfig(config) return config } diff --git a/js/src/util/focustrap.js b/js/src/util/focustrap.js index 40509c1ba9..c1a6ec1242 100644 --- a/js/src/util/focustrap.js +++ b/js/src/util/focustrap.js @@ -40,7 +40,7 @@ const DefaultType = { class FocusTrap extends Config { constructor(config) { super() - this._config = this._getConfig(config) + this.setConfig(this._getInitialConfig(config)) this._isActive = false this._lastTabNavDirection = null } diff --git a/js/src/util/swipe.js b/js/src/util/swipe.js index 66baa3dade..3897ab90db 100644 --- a/js/src/util/swipe.js +++ b/js/src/util/swipe.js @@ -50,7 +50,7 @@ class Swipe extends Config { return } - this._config = this._getConfig(config) + this.setConfig(this._getInitialConfig(config)) this._deltaX = 0 this._supportPointerEvents = Boolean(window.PointerEvent) this._initEvents() diff --git a/js/src/util/template-factory.js b/js/src/util/template-factory.js index 39fa450c02..30ebb66716 100644 --- a/js/src/util/template-factory.js +++ b/js/src/util/template-factory.js @@ -48,7 +48,7 @@ const DefaultContentType = { class TemplateFactory extends Config { constructor(config) { super() - this._config = this._getConfig(config) + this.setConfig(this._getInitialConfig(config)) } // Getters diff --git a/js/tests/unit/util/config.spec.js b/js/tests/unit/util/config.spec.js index e1693c0c1f..8c82424c4f 100644 --- a/js/tests/unit/util/config.spec.js +++ b/js/tests/unit/util/config.spec.js @@ -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', () => { it('should parse element\'s data attributes and merge it with default config. Element\'s data attributes must excel Defaults', () => { fixtureEl.innerHTML = '
'