Skip to content

Commit e949505

Browse files
Adrien Siamicvrebert
authored andcommitted
Allow viewport option to be a function
Closes twbs#16151 by merging a rebased version of it that adds docs and 1 more assertion.
1 parent 48232aa commit e949505

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed

docs/_includes/js/popovers.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,11 @@ <h3 id="popovers-options">Options</h3>
233233
</tr>
234234
<tr>
235235
<td>viewport</td>
236-
<td>string | object</td>
236+
<td>string | object | function</td>
237237
<td>{ selector: 'body', padding: 0 }</td>
238238
<td>
239239
<p>Keeps the popover within the bounds of this element. Example: <code>viewport: '#viewport'</code> or <code>{ "selector": "#viewport", "padding": 0 }</code></p>
240+
<p>If a function is given, it is called with the triggering element DOM node as its only argument. The <code>this</code> context is set to the popover instance.</p>
240241
</td>
241242
</tr>
242243
</tbody>

docs/_includes/js/tooltips.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,11 @@ <h3 id="tooltips-options">Options</h3>
199199
</tr>
200200
<tr>
201201
<td>viewport</td>
202-
<td>string | object</td>
202+
<td>string | object | function</td>
203203
<td>{ selector: 'body', padding: 0 }</td>
204204
<td>
205205
<p>Keeps the tooltip within the bounds of this element. Example: <code>viewport: '#viewport'</code> or <code>{ "selector": "#viewport", "padding": 0 }</code></p>
206+
<p>If a function is given, it is called with the triggering element DOM node as its only argument. The <code>this</code> context is set to the tooltip instance.</p>
206207
</td>
207208
</tr>
208209
</tbody>

js/tests/unit/tooltip.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,37 @@ $(function () {
733733
$styles.remove()
734734
})
735735

736+
QUnit.test('should get viewport element from function', function (assert) {
737+
assert.expect(3)
738+
var styles = '<style>'
739+
+ '.tooltip, .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
740+
+ '.container-viewport { position: absolute; top: 50px; left: 60px; width: 300px; height: 300px; }'
741+
+ 'a[rel="tooltip"] { position: fixed; }'
742+
+ '</style>'
743+
var $styles = $(styles).appendTo('head')
744+
745+
var $container = $('<div class="container-viewport"/>').appendTo(document.body)
746+
var $target = $('<a href="#" rel="tooltip" title="tip" style="top: 50px; left: 350px;"/>').appendTo($container)
747+
$target
748+
.bootstrapTooltip({
749+
placement: 'bottom',
750+
viewport: function ($element) {
751+
assert.strictEqual($element[0], $target[0], 'viewport function was passed target as argument')
752+
return ($element.closest('.container-viewport'))
753+
}
754+
})
755+
756+
$target.bootstrapTooltip('show')
757+
var $tooltip = $container.find('.tooltip')
758+
assert.strictEqual(Math.round($tooltip.offset().left), Math.round(60 + $container.width() - $tooltip[0].offsetWidth))
759+
760+
$target.bootstrapTooltip('hide')
761+
assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
762+
763+
$container.remove()
764+
$styles.remove()
765+
})
766+
736767
QUnit.test('should not error when trying to show an auto-placed tooltip that has been removed from the dom', function (assert) {
737768
assert.expect(1)
738769
var passed = true

js/tooltip.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
this.type = type
5151
this.$element = $(element)
5252
this.options = this.getOptions(options)
53-
this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
53+
this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
5454

5555
if (this.$element[0] instanceof document.constructor && !this.options.selector) {
5656
throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')

0 commit comments

Comments
 (0)