mirror of
https://github.com/twbs/bootstrap.git
synced 2025-08-16 10:34:07 +02:00
Manipulator: Add JSON parse support (#35077)
Support parsing JSON from each component's main element using the `data-bs-config` attribute. The `bs-config` attribute will be reserved and omitted during `getDataAttributes` parsing. With this commit, every component, will create its config object, using: * defaults * data-bs-config * the rest of data attributes * configuration object given during instance initialization Co-authored-by: XhmikosR <xhmikosr@gmail.com> Co-authored-by: Mark Otto <markd.otto@gmail.com> Co-authored-by: Mark Otto <markdotto@gmail.com>
This commit is contained in:
@@ -70,6 +70,17 @@ describe('Manipulator', () => {
|
||||
target: '#element'
|
||||
})
|
||||
})
|
||||
|
||||
it('should omit `bs-config` data attribute', () => {
|
||||
fixtureEl.innerHTML = '<div data-bs-toggle="tabs" data-bs-target="#element" data-bs-config=\'{"testBool":false}\'></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
expect(Manipulator.getDataAttributes(div)).toEqual({
|
||||
toggle: 'tabs',
|
||||
target: '#element'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('getDataAttribute', () => {
|
||||
@@ -104,5 +115,21 @@ describe('Manipulator', () => {
|
||||
div.setAttribute('data-bs-test', '1')
|
||||
expect(Manipulator.getDataAttribute(div, 'test')).toEqual(1)
|
||||
})
|
||||
|
||||
it('should normalize json data', () => {
|
||||
fixtureEl.innerHTML = '<div data-bs-test=\'{"delay":{"show":100,"hide":10}}\'></div>'
|
||||
|
||||
const div = fixtureEl.querySelector('div')
|
||||
|
||||
expect(Manipulator.getDataAttribute(div, 'test')).toEqual({ delay: { show: 100, hide: 10 } })
|
||||
|
||||
const objectData = { 'Super Hero': ['Iron Man', 'Super Man'], testNum: 90, url: 'http://localhost:8080/test?foo=bar' }
|
||||
const dataStr = JSON.stringify(objectData)
|
||||
div.setAttribute('data-bs-test', encodeURIComponent(dataStr))
|
||||
expect(Manipulator.getDataAttribute(div, 'test')).toEqual(objectData)
|
||||
|
||||
div.setAttribute('data-bs-test', dataStr)
|
||||
expect(Manipulator.getDataAttribute(div, 'test')).toEqual(objectData)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@@ -730,15 +730,12 @@ describe('Tooltip', () => {
|
||||
|
||||
it('should not hide tooltip if leave event occurs and enter event occurs within the hide delay', () => {
|
||||
return new Promise(resolve => {
|
||||
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip">'
|
||||
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip" data-bs-delay=\'{"show":0,"hide":150}\'>'
|
||||
|
||||
const tooltipEl = fixtureEl.querySelector('a')
|
||||
const tooltip = new Tooltip(tooltipEl, {
|
||||
delay: {
|
||||
show: 0,
|
||||
hide: 150
|
||||
}
|
||||
})
|
||||
const tooltip = new Tooltip(tooltipEl)
|
||||
|
||||
expect(tooltip._config.delay).toEqual({ show: 0, hide: 150 })
|
||||
|
||||
setTimeout(() => {
|
||||
expect(tooltip._getTipElement()).toHaveClass('show')
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import Config from '../../../src/util/config'
|
||||
import { clearFixture, getFixture } from '../../helpers/fixture'
|
||||
|
||||
class DummyConfigClass extends Config {
|
||||
static get NAME() {
|
||||
@@ -7,7 +8,17 @@ class DummyConfigClass extends Config {
|
||||
}
|
||||
|
||||
describe('Config', () => {
|
||||
let fixtureEl
|
||||
const name = 'dummy'
|
||||
|
||||
beforeAll(() => {
|
||||
fixtureEl = getFixture()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
clearFixture()
|
||||
})
|
||||
|
||||
describe('NAME', () => {
|
||||
it('should return plugin NAME', () => {
|
||||
expect(DummyConfigClass.NAME).toEqual(name)
|
||||
@@ -26,6 +37,83 @@ describe('Config', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('mergeConfigObj', () => {
|
||||
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>'
|
||||
|
||||
spyOnProperty(DummyConfigClass, 'Default', 'get').and.returnValue({
|
||||
testBool: true,
|
||||
testString: 'foo',
|
||||
testString1: 'foo',
|
||||
testInt: 7
|
||||
})
|
||||
const instance = new DummyConfigClass()
|
||||
const configResult = instance._mergeConfigObj({}, fixtureEl.querySelector('#test'))
|
||||
|
||||
expect(configResult.testBool).toEqual(false)
|
||||
expect(configResult.testString).toEqual('foo')
|
||||
expect(configResult.testString1).toEqual('bar')
|
||||
expect(configResult.testInt).toEqual(8)
|
||||
})
|
||||
|
||||
it('should parse element\'s data attributes and merge it with default config, plug these given during method call. The programmatically given should excel all', () => {
|
||||
fixtureEl.innerHTML = '<div id="test" data-bs-test-bool="false" data-bs-test-int="8" data-bs-test-string-1="bar"></div>'
|
||||
|
||||
spyOnProperty(DummyConfigClass, 'Default', 'get').and.returnValue({
|
||||
testBool: true,
|
||||
testString: 'foo',
|
||||
testString1: 'foo',
|
||||
testInt: 7
|
||||
})
|
||||
const instance = new DummyConfigClass()
|
||||
const configResult = instance._mergeConfigObj({
|
||||
testString1: 'test',
|
||||
testInt: 3
|
||||
}, fixtureEl.querySelector('#test'))
|
||||
|
||||
expect(configResult.testBool).toEqual(false)
|
||||
expect(configResult.testString).toEqual('foo')
|
||||
expect(configResult.testString1).toEqual('test')
|
||||
expect(configResult.testInt).toEqual(3)
|
||||
})
|
||||
|
||||
it('should parse element\'s data attribute `config` and any rest attributes. The programmatically given should excel all. Data attribute `config` should excel only Defaults', () => {
|
||||
fixtureEl.innerHTML = '<div id="test" data-bs-config=\'{"testBool":false,"testInt":50,"testInt2":100}\' data-bs-test-int="8" data-bs-test-string-1="bar"></div>'
|
||||
|
||||
spyOnProperty(DummyConfigClass, 'Default', 'get').and.returnValue({
|
||||
testBool: true,
|
||||
testString: 'foo',
|
||||
testString1: 'foo',
|
||||
testInt: 7,
|
||||
testInt2: 600
|
||||
})
|
||||
const instance = new DummyConfigClass()
|
||||
const configResult = instance._mergeConfigObj({
|
||||
testString1: 'test'
|
||||
}, fixtureEl.querySelector('#test'))
|
||||
|
||||
expect(configResult.testBool).toEqual(false)
|
||||
expect(configResult.testString).toEqual('foo')
|
||||
expect(configResult.testString1).toEqual('test')
|
||||
expect(configResult.testInt).toEqual(8)
|
||||
expect(configResult.testInt2).toEqual(100)
|
||||
})
|
||||
|
||||
it('should omit element\'s data attribute `config` if is not an object', () => {
|
||||
fixtureEl.innerHTML = '<div id="test" data-bs-config="foo" data-bs-test-int="8"></div>'
|
||||
|
||||
spyOnProperty(DummyConfigClass, 'Default', 'get').and.returnValue({
|
||||
testInt: 7,
|
||||
testInt2: 79
|
||||
})
|
||||
const instance = new DummyConfigClass()
|
||||
const configResult = instance._mergeConfigObj({}, fixtureEl.querySelector('#test'))
|
||||
|
||||
expect(configResult.testInt).toEqual(8)
|
||||
expect(configResult.testInt2).toEqual(79)
|
||||
})
|
||||
})
|
||||
|
||||
describe('typeCheckConfig', () => {
|
||||
it('should check type of the config object', () => {
|
||||
spyOnProperty(DummyConfigClass, 'DefaultType', 'get').and.returnValue({
|
||||
|
Reference in New Issue
Block a user