From edb221a20ceabebd427e27d0432e94a227717217 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Fri, 22 Nov 2013 11:58:53 -0800 Subject: Add tooltip `viewport` option, respect bounds of the viewport --- js/tooltip.js | 81 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 28 deletions(-) (limited to 'js/tooltip.js') diff --git a/js/tooltip.js b/js/tooltip.js index a976bbf1e..2bc718d63 100644 --- a/js/tooltip.js +++ b/js/tooltip.js @@ -34,7 +34,9 @@ title: '', delay: 0, html: false, - container: false + container: false, + viewport: 'body', + viewportPadding: 0 } Tooltip.prototype.init = function (type, element, options) { @@ -42,6 +44,7 @@ this.type = type this.$element = $(element) this.options = this.getOptions(options) + this.$viewport = $(this.options.viewport) var triggers = this.options.trigger.split(' ') @@ -157,18 +160,14 @@ var actualHeight = $tip[0].offsetHeight if (autoPlace) { + var orgPlacement = placement var $parent = this.$element.parent() + var parentDim = this.getElementDimensions($parent) - 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 = 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' : placement $tip @@ -228,29 +227,22 @@ var actualHeight = $tip[0].offsetHeight if (placement == 'top' && actualHeight != height) { - replace = true offset.top = offset.top + height - actualHeight } - if (/bottom|top/.test(placement)) { - var delta = 0 - - if (offset.left < 0) { - delta = offset.left * -2 - offset.left = 0 + var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) - $tip.offset(offset) - - actualWidth = $tip[0].offsetWidth - actualHeight = $tip[0].offsetHeight - } + if (delta.left) + offset.left = offset.left + delta.left + else + offset.top = offset.top + delta.top - this.replaceArrow(delta - width + actualWidth, actualWidth, 'left') - } else { - this.replaceArrow(actualHeight - height, actualHeight, 'top') - } + var arrowDelta = delta.left * 2 - (delta.left ? width + actualWidth : height + actualHeight) + var arrowPosition = delta.left ? 'left' : 'top' + var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight' - if (replace) $tip.offset(offset) + $tip.offset(offset) + this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition) } Tooltip.prototype.replaceArrow = function (delta, dimension, position) { @@ -316,6 +308,39 @@ 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 () { -- cgit v1.2.3 From 6af0013ac52c391dd7623f9cbbb25cd7d3c43d35 Mon Sep 17 00:00:00 2001 From: Chris Rebert Date: Thu, 16 Jan 2014 20:31:19 -0800 Subject: Revert "Add tooltip `viewport` option, respect bounds of the viewport" This reverts commit edb221a20ceabebd427e27d0432e94a227717217. Reverting due to broken JS unit tests. Conflicts: docs/javascript.html --- js/tooltip.js | 81 +++++++++++++++++++++-------------------------------------- 1 file changed, 28 insertions(+), 53 deletions(-) (limited to 'js/tooltip.js') diff --git a/js/tooltip.js b/js/tooltip.js index 2bc718d63..a976bbf1e 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 () { -- cgit v1.2.3 From 1409cde7e800ca83fd761f87e5ad8f0d259e38d1 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Thu, 30 Jan 2014 08:30:37 -0800 Subject: Bump versions, run grunt --- js/tooltip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/tooltip.js') diff --git a/js/tooltip.js b/js/tooltip.js index a976bbf1e..6cf2b0f8e 100644 --- a/js/tooltip.js +++ b/js/tooltip.js @@ -1,5 +1,5 @@ /* ======================================================================== - * Bootstrap: tooltip.js v3.0.3 + * Bootstrap: tooltip.js v3.1.0 * http://getbootstrap.com/javascript/#tooltip * Inspired by the original jQuery.tipsy by Jason Frame * ======================================================================== -- cgit v1.2.3