Skip to content

Commit 2f1fbbe

Browse files
committed
fix: this reference for JavaScript functions
1 parent d0a9142 commit 2f1fbbe

File tree

8 files changed

+101
-12
lines changed

8 files changed

+101
-12
lines changed

js/src/dropdown.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ class Dropdown extends BaseComponent {
323323

324324
return {
325325
...defaultBsPopperConfig,
326-
...execute(this._config.popperConfig, [defaultBsPopperConfig])
326+
...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig])
327327
}
328328
}
329329

js/src/tooltip.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ class Tooltip extends BaseComponent {
395395
}
396396

397397
_resolvePossibleFunction(arg) {
398-
return execute(arg, [this._element])
398+
return execute(arg, [this._element, this._element])
399399
}
400400

401401
_getPopperConfig(attachment) {
@@ -441,7 +441,7 @@ class Tooltip extends BaseComponent {
441441

442442
return {
443443
...defaultBsPopperConfig,
444-
...execute(this._config.popperConfig, [defaultBsPopperConfig])
444+
...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig])
445445
}
446446
}
447447

js/src/util/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ const defineJQueryPlugin = plugin => {
226226
}
227227

228228
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
229-
return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue
229+
return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue
230230
}
231231

232232
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {

js/src/util/template-factory.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ class TemplateFactory extends Config {
146146
}
147147

148148
_resolvePossibleFunction(arg) {
149-
return execute(arg, [this])
149+
return execute(arg, [undefined, this])
150150
}
151151

152152
_putElementInTemplate(element, templateElement) {

js/tests/unit/dropdown.spec.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,10 @@ describe('Dropdown', () => {
172172

173173
const popperConfig = dropdown._getPopperConfig()
174174

175-
expect(getPopperConfig).toHaveBeenCalled()
175+
// Ensure that the function was called with the default config.
176+
expect(getPopperConfig).toHaveBeenCalledWith(jasmine.objectContaining({
177+
placement: jasmine.any(String)
178+
}))
176179
expect(popperConfig.placement).toEqual('left')
177180
})
178181
})

js/tests/unit/popover.spec.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,60 @@ describe('Popover', () => {
9595
})
9696
})
9797

98+
it('should call content and title functions with trigger element', () => {
99+
return new Promise(resolve => {
100+
fixtureEl.innerHTML = '<a href="#" data-foo="bar">BS twitter</a>'
101+
102+
const popoverEl = fixtureEl.querySelector('a')
103+
const popover = new Popover(popoverEl, {
104+
title(el) {
105+
return el.dataset.foo
106+
},
107+
content(el) {
108+
return el.dataset.foo
109+
}
110+
})
111+
112+
popoverEl.addEventListener('shown.bs.popover', () => {
113+
const popoverDisplayed = document.querySelector('.popover')
114+
115+
expect(popoverDisplayed).not.toBeNull()
116+
expect(popoverDisplayed.querySelector('.popover-header').textContent).toEqual('bar')
117+
expect(popoverDisplayed.querySelector('.popover-body').textContent).toEqual('bar')
118+
resolve()
119+
})
120+
121+
popover.show()
122+
})
123+
})
124+
125+
it('should call content and title functions with correct this value', () => {
126+
return new Promise(resolve => {
127+
fixtureEl.innerHTML = '<a href="#" data-foo="bar">BS twitter</a>'
128+
129+
const popoverEl = fixtureEl.querySelector('a')
130+
const popover = new Popover(popoverEl, {
131+
title() {
132+
return this.dataset.foo
133+
},
134+
content() {
135+
return this.dataset.foo
136+
}
137+
})
138+
139+
popoverEl.addEventListener('shown.bs.popover', () => {
140+
const popoverDisplayed = document.querySelector('.popover')
141+
142+
expect(popoverDisplayed).not.toBeNull()
143+
expect(popoverDisplayed.querySelector('.popover-header').textContent).toEqual('bar')
144+
expect(popoverDisplayed.querySelector('.popover-body').textContent).toEqual('bar')
145+
resolve()
146+
})
147+
148+
popover.show()
149+
})
150+
})
151+
98152
it('should show a popover with just content without having header', () => {
99153
return new Promise(resolve => {
100154
fixtureEl.innerHTML = '<a href="#">Nice link</a>'

js/tests/unit/tooltip.spec.js

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,10 @@ describe('Tooltip', () => {
177177

178178
const popperConfig = tooltip._getPopperConfig('top')
179179

180-
expect(getPopperConfig).toHaveBeenCalled()
180+
// Ensure that the function was called with the default config.
181+
expect(getPopperConfig).toHaveBeenCalledWith(jasmine.objectContaining({
182+
placement: jasmine.any(String)
183+
}))
181184
expect(popperConfig.placement).toEqual('left')
182185
})
183186

@@ -919,10 +922,12 @@ describe('Tooltip', () => {
919922

920923
it('should show a tooltip with custom class provided as a function in config', () => {
921924
return new Promise(resolve => {
922-
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip"></a>'
925+
fixtureEl.innerHTML = '<a href="#" rel="tooltip" title="Another tooltip" data-class-a="custom-class-a" data-class-b="custom-class-b"></a>'
923926

924-
const spy = jasmine.createSpy('customClass').and.returnValue('custom-class')
925927
const tooltipEl = fixtureEl.querySelector('a')
928+
const spy = jasmine.createSpy('customClass').and.callFake(function (el) {
929+
return `${el.dataset.classA} ${this.dataset.classB}`
930+
})
926931
const tooltip = new Tooltip(tooltipEl, {
927932
customClass: spy
928933
})
@@ -931,7 +936,8 @@ describe('Tooltip', () => {
931936
const tip = document.querySelector('.tooltip')
932937
expect(tip).not.toBeNull()
933938
expect(spy).toHaveBeenCalled()
934-
expect(tip).toHaveClass('custom-class')
939+
expect(tip).toHaveClass('custom-class-a')
940+
expect(tip).toHaveClass('custom-class-b')
935941
resolve()
936942
})
937943

@@ -1339,6 +1345,32 @@ describe('Tooltip', () => {
13391345
})
13401346
})
13411347

1348+
it('should call title function with trigger element', () => {
1349+
fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-foo="bar"></a>'
1350+
1351+
const tooltipEl = fixtureEl.querySelector('a')
1352+
const tooltip = new Tooltip(tooltipEl, {
1353+
title(el) {
1354+
return el.dataset.foo
1355+
}
1356+
})
1357+
1358+
expect(tooltip._getTitle()).toEqual('bar')
1359+
})
1360+
1361+
it('should call title function with correct this value', () => {
1362+
fixtureEl.innerHTML = '<a href="#" rel="tooltip" data-foo="bar"></a>'
1363+
1364+
const tooltipEl = fixtureEl.querySelector('a')
1365+
const tooltip = new Tooltip(tooltipEl, {
1366+
title() {
1367+
return this.dataset.foo
1368+
}
1369+
})
1370+
1371+
expect(tooltip._getTitle()).toEqual('bar')
1372+
})
1373+
13421374
describe('getInstance', () => {
13431375
it('should return tooltip instance', () => {
13441376
fixtureEl.innerHTML = '<div></div>'

js/tests/unit/util/index.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,10 +521,10 @@ describe('Util', () => {
521521

522522
it('should execute if arg is function & return the result', () => {
523523
const functionFoo = (num1, num2 = 10) => num1 + num2
524-
const resultFoo = Util.execute(functionFoo, [4, 5])
524+
const resultFoo = Util.execute(functionFoo, [undefined, 4, 5])
525525
expect(resultFoo).toBe(9)
526526

527-
const resultFoo1 = Util.execute(functionFoo, [4])
527+
const resultFoo1 = Util.execute(functionFoo, [undefined, 4])
528528
expect(resultFoo1).toBe(14)
529529

530530
const functionBar = () => 'foo'

0 commit comments

Comments
 (0)