diff --git a/docs/javascript.html b/docs/javascript.html index 9f8f8675c7d7466be764d94a92a05e1e01673530..2d8c0e7c6145a124b5f52810103d21a688cdab84 100644 --- a/docs/javascript.html +++ b/docs/javascript.html @@ -1015,22 +1015,6 @@ $('#example').tooltip(options) <p>Appends the tooltip to a specific element. Example: <code>container: 'body'</code></p> </td> </tr> - <tr> - <td>viewport</td> - <td>string</td> - <td>'body'</td> - <td> - <p>Keeps the tooltip within the bounds of this element. Example: <code>viewport: '#viewport'</code></p> - </td> - </tr> - <tr> - <td>viewportPadding</td> - <td>number</td> - <td>0</td> - <td> - <p>Pixel distance to keep the tooltip from the edges of the viewport element. Example: <code>viewportPadding: 10</code></p> - </td> - </tr> </tbody> </table> </div><!-- /.table-responsive --> diff --git a/examples/tooltips/viewport.html b/examples/tooltips/viewport.html deleted file mode 100644 index 6805056f2e0b3ef6865b720954e246b637ed49a5..0000000000000000000000000000000000000000 --- a/examples/tooltips/viewport.html +++ /dev/null @@ -1,71 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <meta charset="utf-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <meta name="description" content=""> - <meta name="author" content=""> - <link rel="shortcut icon" href="../../docs-assets/ico/favicon.png"> - - <title>Tooltip Viewport Example for Bootstrap</title> - - <!-- Bootstrap core CSS --> - <link href="../../dist/css/bootstrap.css" rel="stylesheet"> - - <!-- Just for debugging purposes. Don't actually copy this line! --> - <!--[if lt IE 9]><script src="../../docs-assets/js/ie8-responsive-file-warning.js"></script><![endif]--> - - <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> - <!--[if lt IE 9]> - <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> - <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> - <![endif]--> - - <style> - .tooltip { - min-width: 250px; - max-width: 500px; - } - .tooltip .tooltip-inner { - min-height: 200px; - min-width: 250px; - max-width: 500px; - } - - .placeholder { - height: 900px; - } - </style> - </head> - - <body> - - <button class="btn pull-right tooltip-bottom", title="This should be shifted to the left">Shift Left</button> - <button class="btn tooltip-bottom", title="This should be shifted to the right">Shift Right</button> - <button class="btn tooltip-right", title="This should be shifted down">Shift Down</button> - - <div class="placeholder">There is a button down there ↓</div> - - <button class="btn tooltip-right", title="This should be shifted up">Shift Up</button> - - <!-- Bootstrap core JavaScript - ================================================== --> - <!-- Placed at the end of the document so the pages load faster --> - <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script> - <script src="../../js/tooltip.js"></script> - - <script> - $(function(){ - $('.tooltip-right').tooltip({ - placement: 'right', - viewportPadding: 2 - }); - $('.tooltip-bottom').tooltip({ - placement: 'bottom', - viewportPadding: 2 - }); - }); - </script> - </body> -</html> diff --git a/js/tests/unit/tooltip.js b/js/tests/unit/tooltip.js index 9fab6c61f5abf75954f955c29fa02d668506b7f7..b9b003dd1d1055152cb7534ca1b3b33e1fdfc3c1 100644 --- a/js/tests/unit/tooltip.js +++ b/js/tests/unit/tooltip.js @@ -338,10 +338,10 @@ $(function () { }) test('should add position class before positioning so that position-specific styles are taken into account', function () { - $('head').append('<style id="test"> .tooltip.right { white-space: nowrap; } .tooltip.right .tooltip-inner { max-width: none; } </style>') + $('head').append('<style> .tooltip.right { white-space: nowrap; } .tooltip.right .tooltip-inner { max-width: none; } </style>') var container = $('<div />').appendTo('body'), - target = $('<a href="#" rel="tooltip" title="very very very very very very very very long tooltip in one line" style="position: fixed; top: 10px; left: 0px;"></a>') + target = $('<a href="#" rel="tooltip" title="very very very very very very very very long tooltip in one line"></a>') .appendTo(container) .tooltip({placement: 'right'}) .tooltip('show'), @@ -353,67 +353,6 @@ $(function () { var topDiff = top - top2 ok(topDiff <= 1 && topDiff >= -1) target.tooltip('hide') - $('head #test').remove() - }) - - test('should adjust the tip\'s top when up against the top of the viewport', function () { - $('head').append('<style id="test"> .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>') - - var container = $('<div />').appendTo('body'), - target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 0px; left: 0px;"></a>') - .appendTo(container) - .tooltip({placement: 'right', viewportPadding: 12}) - .tooltip('show'), - tooltip = container.find('.tooltip') - - ok( Math.round(tooltip.offset().top) === 12 ) - target.tooltip('hide') - $('head #test').remove() - }) - - test('should adjust the tip\'s top when up against the bottom of the viewport', function () { - $('head').append('<style id="test"> .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>') - - var container = $('<div />').appendTo('body'), - target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; bottom: 0px; left: 0px;"></a>') - .appendTo(container) - .tooltip({placement: 'right', viewportPadding: 12}) - .tooltip('show'), - tooltip = container.find('.tooltip') - - ok( Math.round(tooltip.offset().top) === Math.round($(window).height() - 12 - tooltip[0].offsetHeight) ) - target.tooltip('hide') - $('head #test').remove() - }) - - test('should adjust the tip\'s left when up against the left of the viewport', function () { - $('head').append('<style id="test"> .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>') - - var container = $('<div />').appendTo('body'), - target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 0px; left: 0px;"></a>') - .appendTo(container) - .tooltip({placement: 'bottom', viewportPadding: 12}) - .tooltip('show'), - tooltip = container.find('.tooltip') - - ok( Math.round(tooltip.offset().left) === 12 ) - target.tooltip('hide') - $('head #test').remove() - }) - - test('should adjust the tip\'s left when up against the right of the viewport', function () { - $('head').append('<style id="test"> .tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; } </style>') - - var container = $('<div />').appendTo('body'), - target = $('<a href="#" rel="tooltip" title="tip" style="position: fixed; top: 0px; right: 0px;"></a>') - .appendTo(container) - .tooltip({placement: 'bottom', viewportPadding: 12}) - .tooltip('show'), - tooltip = container.find('.tooltip') - - ok( Math.round(tooltip.offset().left) === Math.round($(window).width() - 12 - tooltip[0].offsetWidth) ) - target.tooltip('hide') - $('head #test').remove() }) test('tooltip title test #1', function () { diff --git a/js/tooltip.js b/js/tooltip.js index 2bc718d633001b19d63cd19f890215effbf2d4da..a976bbf1e6c0c2edadfcd74340bf4d10f505b256 100644 --- a/js/tooltip.js +++ b/js/tooltip.js @@ -34,9 +34,7 @@ title: '', delay: 0, html: false, - container: false, - viewport: 'body', - viewportPadding: 0 + container: false } Tooltip.prototype.init = function (type, element, options) { @@ -44,7 +42,6 @@ this.type = type this.$element = $(element) this.options = this.getOptions(options) - this.$viewport = $(this.options.viewport) var triggers = this.options.trigger.split(' ') @@ -160,14 +157,18 @@ var actualHeight = $tip[0].offsetHeight if (autoPlace) { - var orgPlacement = placement var $parent = this.$element.parent() - var parentDim = this.getElementDimensions($parent) - placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' : - placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' : - placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' : - placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' : + var orgPlacement = placement + var docScroll = document.documentElement.scrollTop || document.body.scrollTop + var parentWidth = this.options.container == 'body' ? window.innerWidth : $parent.outerWidth() + var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight() + var parentLeft = this.options.container == 'body' ? 0 : $parent.offset().left + + placement = placement == 'bottom' && pos.top + pos.height + actualHeight - docScroll > parentHeight ? 'top' : + placement == 'top' && pos.top - docScroll - actualHeight < 0 ? 'bottom' : + placement == 'right' && pos.right + actualWidth > parentWidth ? 'left' : + placement == 'left' && pos.left - actualWidth < parentLeft ? 'right' : placement $tip @@ -227,22 +228,29 @@ var actualHeight = $tip[0].offsetHeight if (placement == 'top' && actualHeight != height) { + replace = true offset.top = offset.top + height - actualHeight } - var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) + if (/bottom|top/.test(placement)) { + var delta = 0 + + if (offset.left < 0) { + delta = offset.left * -2 + offset.left = 0 - if (delta.left) - offset.left = offset.left + delta.left - else - offset.top = offset.top + delta.top + $tip.offset(offset) + + actualWidth = $tip[0].offsetWidth + actualHeight = $tip[0].offsetHeight + } - var arrowDelta = delta.left * 2 - (delta.left ? width + actualWidth : height + actualHeight) - var arrowPosition = delta.left ? 'left' : 'top' - var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' + this.replaceArrow(delta - width + actualWidth, actualWidth, 'left') + } else { + this.replaceArrow(actualHeight - height, actualHeight, 'top') + } - $tip.offset(offset) - this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) + if (replace) $tip.offset(offset) } Tooltip.prototype.replaceArrow = function (delta, dimension, position) { @@ -308,39 +316,6 @@ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } - - } - - Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { - var delta = {} - var viewportPadding = this.options.viewportPadding - var viewportDimensions = this.getElementDimensions(this.$viewport) - - if (/right|left/.test(placement)) { - if (pos.top + actualHeight - viewportDimensions.scroll + viewportPadding > viewportDimensions.height) { // bottom overflow - delta.top = viewportDimensions.height + viewportDimensions.scroll - actualHeight - viewportPadding - pos.top - } else if (pos.top - viewportDimensions.scroll - viewportPadding < 0) { // top overflow - delta.top = viewportDimensions.scroll + viewportPadding - pos.top - } - } else { - if (pos.left + actualWidth + viewportPadding > viewportDimensions.width) { // right overflow - delta.left = viewportDimensions.width - actualWidth - viewportPadding - pos.left - } else if (pos.left - viewportPadding < viewportDimensions.left) { // left overflow - delta.left = viewportDimensions.left + viewportPadding - pos.left - } - } - - return delta - } - - Tooltip.prototype.getElementDimensions = function ($element) { - var isBody = $element[0].tagName == 'BODY' - return { - scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(), - width: isBody ? window.innerWidth : $element.outerWidth(), - height: isBody ? window.innerHeight : $element.outerHeight(), - left: isBody ? 0 : $element.offset().left - } } Tooltip.prototype.getTitle = function () {