Skip to content

Commit aa47989

Browse files
committed
Merge pull request twbs#16152 from jarthod/tooltip-placement-viewport-fix
Tooltip/popover: Fix auto placement to use viewport
2 parents cc8567d + 5921724 commit aa47989

File tree

2 files changed

+38
-18
lines changed

2 files changed

+38
-18
lines changed

js/tests/unit/tooltip.js

+33-12
Original file line numberDiff line numberDiff line change
@@ -376,23 +376,19 @@ $(function () {
376376
assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
377377
})
378378

379-
QUnit.test('should be placed dynamically with the dynamic placement option', function (assert) {
379+
QUnit.test('should be placed dynamically to viewport with the dynamic placement option', function (assert) {
380380
assert.expect(6)
381-
var $style = $('<style> a[rel="tooltip"] { display: inline-block; position: absolute; } </style>')
381+
var $style = $('<style> div[rel="tooltip"] { position: absolute; } #qunit-fixture { top: inherit; left: inherit } </style>').appendTo('head')
382382
var $container = $('<div/>')
383383
.css({
384-
position: 'absolute',
385-
overflow: 'hidden',
386-
width: 600,
387-
height: 400,
388-
top: 0,
389-
left: 0
384+
position: 'relative',
385+
height: '100%'
390386
})
391-
.appendTo(document.body)
387+
.appendTo('#qunit-fixture')
392388

393389
var $topTooltip = $('<div style="left: 0; top: 0;" rel="tooltip" title="Top tooltip">Top Dynamic Tooltip</div>')
394390
.appendTo($container)
395-
.bootstrapTooltip({ placement: 'auto' })
391+
.bootstrapTooltip({ placement: 'auto', viewport: '#qunit-fixture' })
396392

397393
$topTooltip.bootstrapTooltip('show')
398394
assert.ok($('.tooltip').is('.bottom'), 'top positioned tooltip is dynamically positioned to bottom')
@@ -402,7 +398,7 @@ $(function () {
402398

403399
var $rightTooltip = $('<div style="right: 0;" rel="tooltip" title="Right tooltip">Right Dynamic Tooltip</div>')
404400
.appendTo($container)
405-
.bootstrapTooltip({ placement: 'right auto' })
401+
.bootstrapTooltip({ placement: 'right auto', viewport: '#qunit-fixture' })
406402

407403
$rightTooltip.bootstrapTooltip('show')
408404
assert.ok($('.tooltip').is('.left'), 'right positioned tooltip is dynamically positioned left')
@@ -412,7 +408,7 @@ $(function () {
412408

413409
var $leftTooltip = $('<div style="left: 0;" rel="tooltip" title="Left tooltip">Left Dynamic Tooltip</div>')
414410
.appendTo($container)
415-
.bootstrapTooltip({ placement: 'auto left' })
411+
.bootstrapTooltip({ placement: 'auto left', viewport: '#qunit-fixture' })
416412

417413
$leftTooltip.bootstrapTooltip('show')
418414
assert.ok($('.tooltip').is('.right'), 'left positioned tooltip is dynamically positioned right')
@@ -450,6 +446,31 @@ $(function () {
450446
$styles.remove()
451447
})
452448

449+
QUnit.test('should position tip on top if viewport has enough space and is not parent', function (assert) {
450+
assert.expect(2)
451+
var styles = '<style>'
452+
+ '#section { height: 300px; border: 1px solid red; margin-top: 100px; }'
453+
+ 'div[rel="tooltip"] { width: 150px; border: 1px solid blue; }'
454+
+ '</style>'
455+
var $styles = $(styles).appendTo('head')
456+
457+
var $container = $('<div id="section"/>').appendTo('#qunit-fixture')
458+
var $target = $('<div rel="tooltip" title="tip"/>')
459+
.appendTo($container)
460+
.bootstrapTooltip({
461+
placement: 'auto top',
462+
viewport: '#qunit-fixture'
463+
})
464+
465+
$target.bootstrapTooltip('show')
466+
assert.ok($('.tooltip').is('.top'), 'top positioned tooltip is dynamically positioned to top')
467+
468+
$target.bootstrapTooltip('hide')
469+
assert.strictEqual($('.tooltip').length, 0, 'tooltip removed from dom')
470+
471+
$styles.remove()
472+
})
473+
453474
QUnit.test('should position tip on bottom if the tip\'s dimension exceeds the viewport area and placement is "auto top"', function (assert) {
454475
assert.expect(2)
455476
var styles = '<style>'

js/tooltip.js

+5-6
Original file line numberDiff line numberDiff line change
@@ -193,13 +193,12 @@
193193

194194
if (autoPlace) {
195195
var orgPlacement = placement
196-
var $container = this.options.container ? $(this.options.container) : this.$element.parent()
197-
var containerDim = this.getPosition($container)
196+
var viewportDim = this.getPosition(this.$viewport)
198197

199-
placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :
200-
placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :
201-
placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
202-
placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
198+
placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
199+
placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
200+
placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
201+
placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
203202
placement
204203

205204
$tip

0 commit comments

Comments
 (0)