From 6af0013ac52c391dd7623f9cbbb25cd7d3c43d35 Mon Sep 17 00:00:00 2001
From: Chris Rebert <code@rebertia.com>
Date: Thu, 16 Jan 2014 20:31:19 -0800
Subject: [PATCH] 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
---
 docs/javascript.html            | 16 -------
 examples/tooltips/viewport.html | 71 -----------------------------
 js/tests/unit/tooltip.js        | 65 +-------------------------
 js/tooltip.js                   | 81 ++++++++++++---------------------
 4 files changed, 30 insertions(+), 203 deletions(-)
 delete mode 100644 examples/tooltips/viewport.html

diff --git a/docs/javascript.html b/docs/javascript.html
index 9f8f8675c7..2d8c0e7c61 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 6805056f2e..0000000000
--- 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 9fab6c61f5..b9b003dd1d 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 2bc718d633..a976bbf1e6 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 () {
-- 
GitLab