@@ -1082,14 +1082,19 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1082
1082
title : '' ,
1083
1083
delay : 0 ,
1084
1084
html : false ,
1085
- container : false
1085
+ container : false ,
1086
+ viewport : {
1087
+ selector : 'body' ,
1088
+ padding : 0
1089
+ }
1086
1090
}
1087
1091
1088
1092
Tooltip . prototype . init = function ( type , element , options ) {
1089
- this . enabled = true
1090
- this . type = type
1091
- this . $element = $ ( element )
1092
- this . options = this . getOptions ( options )
1093
+ this . enabled = true
1094
+ this . type = type
1095
+ this . $element = $ ( element )
1096
+ this . options = this . getOptions ( options )
1097
+ this . $viewport = this . options . viewport && $ ( this . options . viewport . selector || this . options . viewport )
1093
1098
1094
1099
var triggers = this . options . trigger . split ( ' ' )
1095
1100
@@ -1205,18 +1210,14 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1205
1210
var actualHeight = $tip [ 0 ] . offsetHeight
1206
1211
1207
1212
if ( autoPlace ) {
1208
- var $parent = this . $element . parent ( )
1209
-
1210
1213
var orgPlacement = placement
1211
- var docScroll = document . documentElement . scrollTop
1212
- var parentWidth = this . options . container == 'body' ? window . innerWidth : $parent . outerWidth ( )
1213
- var parentHeight = this . options . container == 'body' ? window . innerHeight : $parent . outerHeight ( )
1214
- var parentLeft = this . options . container == 'body' ? 0 : $parent . offset ( ) . left
1215
-
1216
- placement = placement == 'bottom' && pos . top + pos . height + actualHeight - docScroll > parentHeight ? 'top' :
1217
- placement == 'top' && pos . top - docScroll - actualHeight < 0 ? 'bottom' :
1218
- placement == 'right' && pos . right + actualWidth > parentWidth ? 'left' :
1219
- placement == 'left' && pos . left - actualWidth < parentLeft ? 'right' :
1214
+ var $parent = this . $element . parent ( )
1215
+ var parentDim = this . getPosition ( $parent )
1216
+
1217
+ placement = placement == 'bottom' && pos . top + pos . height + actualHeight - parentDim . scroll > parentDim . height ? 'top' :
1218
+ placement == 'top' && pos . top - parentDim . scroll - actualHeight < 0 ? 'bottom' :
1219
+ placement == 'right' && pos . right + actualWidth > parentDim . width ? 'left' :
1220
+ placement == 'left' && pos . left - actualWidth < parentDim . left ? 'right' :
1220
1221
placement
1221
1222
1222
1223
$tip
@@ -1276,29 +1277,20 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1276
1277
var actualHeight = $tip [ 0 ] . offsetHeight
1277
1278
1278
1279
if ( placement == 'top' && actualHeight != height ) {
1279
- replace = true
1280
1280
offset . top = offset . top + height - actualHeight
1281
1281
}
1282
1282
1283
- if ( / b o t t o m | t o p / . test ( placement ) ) {
1284
- var delta = 0
1285
-
1286
- if ( offset . left < 0 ) {
1287
- delta = offset . left * - 2
1288
- offset . left = 0
1283
+ var delta = this . getViewportAdjustedDelta ( placement , offset , actualWidth , actualHeight )
1289
1284
1290
- $tip . offset ( offset )
1285
+ if ( delta . left ) offset . left += delta . left
1286
+ else offset . top += delta . top
1291
1287
1292
- actualWidth = $tip [ 0 ] . offsetWidth
1293
- actualHeight = $tip [ 0 ] . offsetHeight
1294
- }
1288
+ var arrowDelta = delta . left ? delta . left * 2 - width + actualWidth : delta . top * 2 - height + actualHeight
1289
+ var arrowPosition = delta . left ? 'left' : 'top'
1290
+ var arrowOffsetPosition = delta . left ? 'offsetWidth' : 'offsetHeight'
1295
1291
1296
- this . replaceArrow ( delta - width + actualWidth , actualWidth , 'left' )
1297
- } else {
1298
- this . replaceArrow ( actualHeight - height , actualHeight , 'top' )
1299
- }
1300
-
1301
- if ( replace ) $tip . offset ( offset )
1292
+ $tip . offset ( offset )
1293
+ this . replaceArrow ( arrowDelta , $tip [ 0 ] [ arrowOffsetPosition ] , arrowPosition )
1302
1294
}
1303
1295
1304
1296
Tooltip . prototype . replaceArrow = function ( delta , dimension , position ) {
@@ -1351,19 +1343,51 @@ if (typeof jQuery === 'undefined') { throw new Error('Bootstrap\'s JavaScript re
1351
1343
return this . getTitle ( )
1352
1344
}
1353
1345
1354
- Tooltip . prototype . getPosition = function ( ) {
1355
- var el = this . $element [ 0 ]
1356
- return $ . extend ( { } , ( typeof el . getBoundingClientRect == 'function' ) ? el . getBoundingClientRect ( ) : {
1357
- width : el . offsetWidth ,
1358
- height : el . offsetHeight
1359
- } , this . $element . offset ( ) )
1346
+ Tooltip . prototype . getPosition = function ( $element ) {
1347
+ $element = $element || this . $element
1348
+ var el = $element [ 0 ]
1349
+ var isBody = el . tagName == 'BODY'
1350
+ return $ . extend ( { } , ( typeof el . getBoundingClientRect == 'function' ) ? el . getBoundingClientRect ( ) : null , {
1351
+ scroll : isBody ? document . documentElement . scrollTop || document . body . scrollTop : $element . scrollTop ( ) ,
1352
+ width : isBody ? $ ( window ) . width ( ) : $element . outerWidth ( ) ,
1353
+ height : isBody ? $ ( window ) . height ( ) : $element . outerHeight ( )
1354
+ } , isBody ? { top : 0 , left : 0 } : $element . offset ( ) )
1360
1355
}
1361
1356
1362
1357
Tooltip . prototype . getCalculatedOffset = function ( placement , pos , actualWidth , actualHeight ) {
1363
1358
return placement == 'bottom' ? { top : pos . top + pos . height , left : pos . left + pos . width / 2 - actualWidth / 2 } :
1364
1359
placement == 'top' ? { top : pos . top - actualHeight , left : pos . left + pos . width / 2 - actualWidth / 2 } :
1365
1360
placement == 'left' ? { top : pos . top + pos . height / 2 - actualHeight / 2 , left : pos . left - actualWidth } :
1366
1361
/* placement == 'right' */ { top : pos . top + pos . height / 2 - actualHeight / 2 , left : pos . left + pos . width }
1362
+
1363
+ }
1364
+
1365
+ Tooltip . prototype . getViewportAdjustedDelta = function ( placement , pos , actualWidth , actualHeight ) {
1366
+ var delta = { top : 0 , left : 0 }
1367
+ if ( ! this . $viewport ) return delta
1368
+
1369
+ var viewportPadding = this . options . viewport && this . options . viewport . padding || 0
1370
+ var viewportDimensions = this . getPosition ( this . $viewport )
1371
+
1372
+ if ( / r i g h t | l e f t / . test ( placement ) ) {
1373
+ var topEdgeOffset = pos . top - viewportPadding - viewportDimensions . scroll
1374
+ var bottomEdgeOffset = pos . top + viewportPadding - viewportDimensions . scroll + actualHeight
1375
+ if ( topEdgeOffset < viewportDimensions . top ) { // top overflow
1376
+ delta . top = viewportDimensions . top - topEdgeOffset
1377
+ } else if ( bottomEdgeOffset > viewportDimensions . top + viewportDimensions . height ) { // bottom overflow
1378
+ delta . top = viewportDimensions . top + viewportDimensions . height - bottomEdgeOffset
1379
+ }
1380
+ } else {
1381
+ var leftEdgeOffset = pos . left - viewportPadding
1382
+ var rightEdgeOffset = pos . left + viewportPadding + actualWidth
1383
+ if ( leftEdgeOffset < viewportDimensions . left ) { // left overflow
1384
+ delta . left = viewportDimensions . left - leftEdgeOffset
1385
+ } else if ( rightEdgeOffset > viewportDimensions . width ) { // right overflow
1386
+ delta . left = viewportDimensions . left + viewportDimensions . width - rightEdgeOffset
1387
+ }
1388
+ }
1389
+
1390
+ return delta
1367
1391
}
1368
1392
1369
1393
Tooltip . prototype . getTitle = function ( ) {
0 commit comments