tooltipster-rails 4.1.2 → 4.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a033eec222966a3faf3e1530a21b8b840032c6c5
4
- data.tar.gz: 11c528d683537ffdf45434f61276081efbc5891e
3
+ metadata.gz: 7480e6c2f7f7d4d0d96bb416df7b336aeb4d556d
4
+ data.tar.gz: 97206e57068758ccd7ba243d81001f1430ee1e34
5
5
  SHA512:
6
- metadata.gz: 264c9532d65762c0e2dfba3f097216e36ac12edf89184d592346758c26f5a44ddb140e68e2b0f8bfe0b98443e73871dc8eac140e6c649822832c3f4d590e4c2a
7
- data.tar.gz: 6c9da822d85cdf4a4a38e712b8e1e39a6bb9f2ecbe0fbe7a785aa047c1d8af17d6deb03485b60fcadfbccc4b1093de9cdbb65235045e18a6bfb6203e9b840341
6
+ metadata.gz: c2689e12598e1b6f0fb4807cadce32eee27a944ccf1fd304050dc653eb9b1459f8855167ee122e5f7061f777d4616e1a958eb8985e936572816ce30c1bf4672a
7
+ data.tar.gz: aa160e32325ea116a688ed8e17e80b01e9a3df0490628bbb541e8936e048be16f180ad4e4a1e83514e8ad3ac9f8b34256dea7b63a5ee77d2c709734cfac8b966
data/README.md CHANGED
@@ -23,8 +23,8 @@ In your application.js, require one of the following JavaScript files:
23
23
  ```
24
24
  //= require tooltipster.bundle
25
25
  //= require tooltipster.bundle.min
26
- //= require tooltipster.core
27
- //= require tooltipster.core.min
26
+ //= require tooltipster.main
27
+ //= require tooltipster.main.min
28
28
  ```
29
29
 
30
30
  In your application.css, include one of the following CSS files:
@@ -32,8 +32,8 @@ In your application.css, include one of the following CSS files:
32
32
  ```
33
33
  *= require tooltipster.bundle
34
34
  *= require tooltipster.bundle.min
35
- *= require tooltipster.core
36
- *= require tooltipster.core.min
35
+ *= require tooltipster.main
36
+ *= require tooltipster.main.min
37
37
  ```
38
38
 
39
39
  If you want to use one of the included themes, include that in your application.css as well. Here's an example:
@@ -1,5 +1,5 @@
1
1
  module Tooltipster
2
2
  module Rails
3
- VERSION = "4.1.2"
3
+ VERSION = "4.2.3"
4
4
  end
5
5
  end
@@ -39,9 +39,9 @@ var defaults = {
39
39
  IEmin: 6,
40
40
  interactive: false,
41
41
  multiple: false,
42
- // must be 'body' for now, or an element positioned at (0, 0)
42
+ // will default to document.body, or must be an element positioned at (0, 0)
43
43
  // in the document, typically like the very top views of an app.
44
- parent: 'body',
44
+ parent: null,
45
45
  plugins: ['sideTip'],
46
46
  repositionOnScroll: false,
47
47
  restoration: 'none',
@@ -89,7 +89,7 @@ var defaults = {
89
89
  hasTransitions: transitionSupport(),
90
90
  IE: false,
91
91
  // don't set manually, it will be updated by a build task after the manifest
92
- semVer: '4.1.2',
92
+ semVer: '4.2.3',
93
93
  window: win
94
94
  },
95
95
  core = function() {
@@ -432,9 +432,8 @@ $.Tooltipster = function(element, options) {
432
432
  this.__Content;
433
433
  // for the size tracker
434
434
  this.__contentBcr;
435
- // to disable the tooltip once the destruction has begun
435
+ // to disable the tooltip after destruction
436
436
  this.__destroyed = false;
437
- this.__destroying = false;
438
437
  // we can't emit directly on the instance because if a method with the same
439
438
  // name as the event exists, it will be called by jQuery. Se we use a plain
440
439
  // object as emitter. This emitter is for internal use by plugins,
@@ -568,7 +567,7 @@ $.Tooltipster.prototype = {
568
567
 
569
568
  // to detect swiping
570
569
  if (env.hasTouchCapability) {
571
- $('body').on('touchmove.'+ self.__namespace +'-triggerOpen', function(event) {
570
+ $(env.window.document.body).on('touchmove.'+ self.__namespace +'-triggerOpen', function(event) {
572
571
  self._touchRecordEvent(event);
573
572
  });
574
573
  }
@@ -875,8 +874,8 @@ $.Tooltipster.prototype = {
875
874
  geo.origin.windowOffset.right = geo.origin.windowOffset.left + geo.origin.size.width;
876
875
  geo.origin.windowOffset.bottom = geo.origin.windowOffset.top + geo.origin.size.height;
877
876
 
878
- geo.origin.offset.left = geo.origin.windowOffset.left + env.window.scrollX;
879
- geo.origin.offset.top = geo.origin.windowOffset.top + env.window.scrollY;
877
+ geo.origin.offset.left = geo.origin.windowOffset.left + geo.window.scroll.left;
878
+ geo.origin.offset.top = geo.origin.windowOffset.top + geo.window.scroll.top;
880
879
  geo.origin.offset.bottom = geo.origin.offset.top + geo.origin.size.height;
881
880
  geo.origin.offset.right = geo.origin.offset.left + geo.origin.size.width;
882
881
 
@@ -963,7 +962,10 @@ $.Tooltipster.prototype = {
963
962
  }
964
963
 
965
964
  // determine the future parent
966
- if (typeof this.__options.parent == 'string') {
965
+ if (this.__options.parent === null) {
966
+ this.__options.parent = $(env.window.document.body);
967
+ }
968
+ else if (typeof this.__options.parent == 'string') {
967
969
  this.__options.parent = $(this.__options.parent);
968
970
  }
969
971
 
@@ -1025,7 +1027,10 @@ $.Tooltipster.prototype = {
1025
1027
 
1026
1028
  // auto-destruct if the origin is gone
1027
1029
  if (!bodyContains(self._$origin)) {
1028
- self.destroy();
1030
+
1031
+ self.close(function(){
1032
+ self.destroy();
1033
+ });
1029
1034
  }
1030
1035
  }, 20000);
1031
1036
  }
@@ -1194,106 +1199,111 @@ $.Tooltipster.prototype = {
1194
1199
  }
1195
1200
  else {
1196
1201
 
1197
- // if the scroll happened on the window
1198
- if (event.target === env.window.document) {
1202
+ // if the origin or tooltip have been removed: do nothing, the tracker will
1203
+ // take care of it later
1204
+ if (bodyContains(self._$origin) && bodyContains(self._$tooltip)) {
1199
1205
 
1200
- // if the origin has a fixed lineage, window scroll will have no
1201
- // effect on its position nor on the position of the tooltip
1202
- if (!self.__Geometry.origin.fixedLineage) {
1206
+ // if the scroll happened on the window
1207
+ if (event.target === env.window.document) {
1203
1208
 
1204
- // we don't need to do anything unless repositionOnScroll is true
1205
- // because the tooltip will already have moved with the window
1206
- // (and of course with the origin)
1207
- if (self.__options.repositionOnScroll) {
1208
- self.reposition(event);
1209
+ // if the origin has a fixed lineage, window scroll will have no
1210
+ // effect on its position nor on the position of the tooltip
1211
+ if (!self.__Geometry.origin.fixedLineage) {
1212
+
1213
+ // we don't need to do anything unless repositionOnScroll is true
1214
+ // because the tooltip will already have moved with the window
1215
+ // (and of course with the origin)
1216
+ if (self.__options.repositionOnScroll) {
1217
+ self.reposition(event);
1218
+ }
1209
1219
  }
1210
1220
  }
1211
- }
1212
- // if the scroll happened on another parent of the tooltip, it means
1213
- // that it's in a scrollable area and now needs to have its position
1214
- // adjusted or recomputed, depending ont the repositionOnScroll
1215
- // option. Also, if the origin is partly hidden due to a parent that
1216
- // hides its overflow, we'll just hide (not close) the tooltip.
1217
- else {
1218
-
1219
- var g = self.__geometry(),
1220
- overflows = false;
1221
-
1222
- // a fixed position origin is not affected by the overflow hiding
1223
- // of a parent
1224
- if (self._$origin.css('position') != 'fixed') {
1221
+ // if the scroll happened on another parent of the tooltip, it means
1222
+ // that it's in a scrollable area and now needs to have its position
1223
+ // adjusted or recomputed, depending ont the repositionOnScroll
1224
+ // option. Also, if the origin is partly hidden due to a parent that
1225
+ // hides its overflow, we'll just hide (not close) the tooltip.
1226
+ else {
1225
1227
 
1226
- self.__$originParents.each(function(i, el) {
1227
-
1228
- var $el = $(el),
1229
- overflowX = $el.css('overflow-x'),
1230
- overflowY = $el.css('overflow-y');
1228
+ var g = self.__geometry(),
1229
+ overflows = false;
1230
+
1231
+ // a fixed position origin is not affected by the overflow hiding
1232
+ // of a parent
1233
+ if (self._$origin.css('position') != 'fixed') {
1231
1234
 
1232
- if (overflowX != 'visible' || overflowY != 'visible') {
1235
+ self.__$originParents.each(function(i, el) {
1233
1236
 
1234
- var bcr = el.getBoundingClientRect();
1237
+ var $el = $(el),
1238
+ overflowX = $el.css('overflow-x'),
1239
+ overflowY = $el.css('overflow-y');
1235
1240
 
1236
- if (overflowX != 'visible') {
1241
+ if (overflowX != 'visible' || overflowY != 'visible') {
1242
+
1243
+ var bcr = el.getBoundingClientRect();
1237
1244
 
1238
- if ( g.origin.windowOffset.left < bcr.left
1239
- || g.origin.windowOffset.right > bcr.right
1240
- ) {
1241
- overflows = true;
1242
- return false;
1245
+ if (overflowX != 'visible') {
1246
+
1247
+ if ( g.origin.windowOffset.left < bcr.left
1248
+ || g.origin.windowOffset.right > bcr.right
1249
+ ) {
1250
+ overflows = true;
1251
+ return false;
1252
+ }
1243
1253
  }
1244
- }
1245
-
1246
- if (overflowY != 'visible') {
1247
1254
 
1248
- if ( g.origin.windowOffset.top < bcr.top
1249
- || g.origin.windowOffset.bottom > bcr.bottom
1250
- ) {
1251
- overflows = true;
1252
- return false;
1255
+ if (overflowY != 'visible') {
1256
+
1257
+ if ( g.origin.windowOffset.top < bcr.top
1258
+ || g.origin.windowOffset.bottom > bcr.bottom
1259
+ ) {
1260
+ overflows = true;
1261
+ return false;
1262
+ }
1253
1263
  }
1254
1264
  }
1255
- }
1256
-
1257
- // no need to go further if fixed, for the same reason as above
1258
- if ($el.css('position') == 'fixed') {
1259
- return false;
1260
- }
1261
- });
1262
- }
1263
-
1264
- if (overflows) {
1265
- self._$tooltip.css('visibility', 'hidden');
1266
- }
1267
- else {
1268
- self._$tooltip.css('visibility', 'visible');
1265
+
1266
+ // no need to go further if fixed, for the same reason as above
1267
+ if ($el.css('position') == 'fixed') {
1268
+ return false;
1269
+ }
1270
+ });
1271
+ }
1269
1272
 
1270
- // reposition
1271
- if (self.__options.repositionOnScroll) {
1272
- self.reposition(event);
1273
+ if (overflows) {
1274
+ self._$tooltip.css('visibility', 'hidden');
1273
1275
  }
1274
- // or just adjust offset
1275
1276
  else {
1277
+ self._$tooltip.css('visibility', 'visible');
1276
1278
 
1277
- // we have to use offset and not windowOffset because this way,
1278
- // only the scroll distance of the scrollable areas are taken into
1279
- // account (the scrolltop value of the main window must be
1280
- // ignored since the tooltip already moves with it)
1281
- var offsetLeft = g.origin.offset.left - self.__Geometry.origin.offset.left,
1282
- offsetTop = g.origin.offset.top - self.__Geometry.origin.offset.top;
1283
-
1284
- // add the offset to the position initially computed by the display plugin
1285
- self._$tooltip.css({
1286
- left: self.__lastPosition.coord.left + offsetLeft,
1287
- top: self.__lastPosition.coord.top + offsetTop
1288
- });
1279
+ // reposition
1280
+ if (self.__options.repositionOnScroll) {
1281
+ self.reposition(event);
1282
+ }
1283
+ // or just adjust offset
1284
+ else {
1285
+
1286
+ // we have to use offset and not windowOffset because this way,
1287
+ // only the scroll distance of the scrollable areas are taken into
1288
+ // account (the scrolltop value of the main window must be
1289
+ // ignored since the tooltip already moves with it)
1290
+ var offsetLeft = g.origin.offset.left - self.__Geometry.origin.offset.left,
1291
+ offsetTop = g.origin.offset.top - self.__Geometry.origin.offset.top;
1292
+
1293
+ // add the offset to the position initially computed by the display plugin
1294
+ self._$tooltip.css({
1295
+ left: self.__lastPosition.coord.left + offsetLeft,
1296
+ top: self.__lastPosition.coord.top + offsetTop
1297
+ });
1298
+ }
1289
1299
  }
1290
1300
  }
1301
+
1302
+ self._trigger({
1303
+ type: 'scroll',
1304
+ event: event
1305
+ });
1291
1306
  }
1292
-
1293
- self._trigger({
1294
- type: 'scroll',
1295
- event: event
1296
- });
1297
1307
  }
1298
1308
 
1299
1309
  return self;
@@ -1428,10 +1438,11 @@ $.Tooltipster.prototype = {
1428
1438
  *
1429
1439
  * @param event
1430
1440
  * @param callback
1441
+ * @param force Set to true to override a potential refusal of the user's function
1431
1442
  * @returns {self}
1432
1443
  * @protected
1433
1444
  */
1434
- _close: function(event, callback) {
1445
+ _close: function(event, callback, force) {
1435
1446
 
1436
1447
  var self = this,
1437
1448
  ok = true;
@@ -1444,8 +1455,8 @@ $.Tooltipster.prototype = {
1444
1455
  }
1445
1456
  });
1446
1457
 
1447
- // a destroying tooltip may not refuse to close
1448
- if (ok || self.__destroying) {
1458
+ // a destroying tooltip (force == true) may not refuse to close
1459
+ if (ok || force) {
1449
1460
 
1450
1461
  // save the method custom callback and cancel any open method custom callbacks
1451
1462
  if (callback) self.__callbacks.close.push(callback);
@@ -1536,7 +1547,7 @@ $.Tooltipster.prototype = {
1536
1547
  // clear the array to prevent memory leaks
1537
1548
  self.__$originParents = null;
1538
1549
 
1539
- $('body').off('.'+ self.__namespace +'-triggerClose');
1550
+ $(env.window.document.body).off('.'+ self.__namespace +'-triggerClose');
1540
1551
 
1541
1552
  self._$origin.off('.'+ self.__namespace +'-triggerClose');
1542
1553
 
@@ -1555,7 +1566,8 @@ $.Tooltipster.prototype = {
1555
1566
  // call our constructor custom callback function
1556
1567
  if (self.__options.functionAfter) {
1557
1568
  self.__options.functionAfter.call(self, self, {
1558
- event: event
1569
+ event: event,
1570
+ origin: self._$origin[0]
1559
1571
  });
1560
1572
  }
1561
1573
 
@@ -1639,10 +1651,10 @@ $.Tooltipster.prototype = {
1639
1651
  },
1640
1652
 
1641
1653
  /**
1642
- * Opens the tooltip right away
1654
+ * Opens the tooltip right away.
1643
1655
  *
1644
1656
  * @param event
1645
- * @param callback
1657
+ * @param callback Will be called when the opening animation is over
1646
1658
  * @returns {self}
1647
1659
  * @protected
1648
1660
  */
@@ -1834,7 +1846,17 @@ $.Tooltipster.prototype = {
1834
1846
  $(env.window)
1835
1847
  // reposition on resize
1836
1848
  .on('resize.'+ self.__namespace +'-triggerClose', function(e) {
1837
- self.reposition(e);
1849
+
1850
+ var $ae = $(document.activeElement);
1851
+
1852
+ // reposition only if the resize event was not triggered upon the opening
1853
+ // of a virtual keyboard due to an input field being focused within the tooltip
1854
+ // (otherwise the repositioning would lose the focus)
1855
+ if ( (!$ae.is('input') && !$ae.is('textarea'))
1856
+ || !$.contains(self._$tooltip[0], $ae[0])
1857
+ ) {
1858
+ self.reposition(e);
1859
+ }
1838
1860
  })
1839
1861
  // same as below for parents
1840
1862
  .on('scroll.'+ self.__namespace +'-triggerClose', function(e) {
@@ -1969,7 +1991,9 @@ $.Tooltipster.prototype = {
1969
1991
 
1970
1992
  if (self.__state != 'closed') {
1971
1993
 
1972
- var eventNames = '';
1994
+ var eventNames = '',
1995
+ $body = $(env.window.document.body);
1996
+
1973
1997
  if (self.__options.triggerClose.click) {
1974
1998
  eventNames += 'click.'+ self.__namespace +'-triggerClose ';
1975
1999
  }
@@ -1977,7 +2001,7 @@ $.Tooltipster.prototype = {
1977
2001
  eventNames += 'touchend.'+ self.__namespace +'-triggerClose';
1978
2002
  }
1979
2003
 
1980
- $('body').on(eventNames, function(event) {
2004
+ $body.on(eventNames, function(event) {
1981
2005
 
1982
2006
  if (self._touchIsMeaningfulEvent(event)) {
1983
2007
 
@@ -1992,7 +2016,7 @@ $.Tooltipster.prototype = {
1992
2016
  // needed to detect and ignore swiping
1993
2017
  if (self.__options.triggerClose.tap && env.hasTouchCapability) {
1994
2018
 
1995
- $('body').on('touchstart.'+ self.__namespace +'-triggerClose', function(event) {
2019
+ $body.on('touchstart.'+ self.__namespace +'-triggerClose', function(event) {
1996
2020
  self._touchRecordEvent(event);
1997
2021
  });
1998
2022
  }
@@ -2474,94 +2498,94 @@ $.Tooltipster.prototype = {
2474
2498
 
2475
2499
  if (!self.__destroyed) {
2476
2500
 
2477
- if (!self.__destroying) {
2501
+ if(self.__state != 'closed'){
2478
2502
 
2479
- self.__destroying = true;
2503
+ // no closing delay
2504
+ self.option('animationDuration', 0)
2505
+ // force closing
2506
+ ._close(null, null, true);
2507
+ }
2508
+
2509
+ // send event
2510
+ self._trigger('destroy');
2511
+
2512
+ self.__destroyed = true;
2513
+
2514
+ self._$origin
2515
+ .removeData(self.__namespace)
2516
+ // remove the open trigger listeners
2517
+ .off('.'+ self.__namespace +'-triggerOpen');
2518
+
2519
+ // remove the touch listener
2520
+ $(env.window.document.body).off('.' + self.__namespace +'-triggerOpen');
2521
+
2522
+ var ns = self._$origin.data('tooltipster-ns');
2523
+
2524
+ // if the origin has been removed from DOM, its data may
2525
+ // well have been destroyed in the process and there would
2526
+ // be nothing to clean up or restore
2527
+ if (ns) {
2480
2528
 
2481
- self._close(null, function() {
2529
+ // if there are no more tooltips on this element
2530
+ if (ns.length === 1) {
2482
2531
 
2483
- self._trigger('destroy');
2484
-
2485
- self.__destroying = false;
2486
- self.__destroyed = true;
2487
-
2488
- self._$origin
2489
- .removeData(self.__namespace)
2490
- // remove the open trigger listeners
2491
- .off('.'+ self.__namespace +'-triggerOpen');
2492
-
2493
- // remove the touch listener
2494
- $('body').off('.' + self.__namespace +'-triggerOpen');
2495
-
2496
- var ns = self._$origin.data('tooltipster-ns');
2497
-
2498
- // if the origin has been removed from DOM, its data may
2499
- // well have been destroyed in the process and there would
2500
- // be nothing to clean up or restore
2501
- if (ns) {
2532
+ // optional restoration of a title attribute
2533
+ var title = null;
2534
+ if (self.__options.restoration == 'previous') {
2535
+ title = self._$origin.data('tooltipster-initialTitle');
2536
+ }
2537
+ else if (self.__options.restoration == 'current') {
2502
2538
 
2503
- // if there are no more tooltips on this element
2504
- if (ns.length === 1) {
2505
-
2506
- // optional restoration of a title attribute
2507
- var title = null;
2508
- if (self.__options.restoration == 'previous') {
2509
- title = self._$origin.data('tooltipster-initialTitle');
2510
- }
2511
- else if (self.__options.restoration == 'current') {
2512
-
2513
- // old school technique to stringify when outerHTML is not supported
2514
- title = (typeof self.__Content == 'string') ?
2515
- self.__Content :
2516
- $('<div></div>').append(self.__Content).html();
2517
- }
2518
-
2519
- if (title) {
2520
- self._$origin.attr('title', title);
2521
- }
2522
-
2523
- // final cleaning
2524
-
2525
- self._$origin.removeClass('tooltipstered');
2526
-
2527
- self._$origin
2528
- .removeData('tooltipster-ns')
2529
- .removeData('tooltipster-initialTitle');
2530
- }
2531
- else {
2532
- // remove the instance namespace from the list of namespaces of
2533
- // tooltips present on the element
2534
- ns = $.grep(ns, function(el, i) {
2535
- return el !== self.__namespace;
2536
- });
2537
- self._$origin.data('tooltipster-ns', ns);
2538
- }
2539
+ // old school technique to stringify when outerHTML is not supported
2540
+ title = (typeof self.__Content == 'string') ?
2541
+ self.__Content :
2542
+ $('<div></div>').append(self.__Content).html();
2539
2543
  }
2540
2544
 
2541
- // last event
2542
- self._trigger('destroyed');
2545
+ if (title) {
2546
+ self._$origin.attr('title', title);
2547
+ }
2543
2548
 
2544
- // unbind private and public event listeners
2545
- self._off();
2546
- self.off();
2549
+ // final cleaning
2547
2550
 
2548
- // remove external references, just in case
2549
- self.__Content = null;
2550
- self.__$emitterPrivate = null;
2551
- self.__$emitterPublic = null;
2552
- self.__options.parent = null;
2553
- self._$origin = null;
2554
- self._$tooltip = null;
2551
+ self._$origin.removeClass('tooltipstered');
2555
2552
 
2556
- // make sure the object is no longer referenced in there to prevent
2557
- // memory leaks
2558
- $.tooltipster.__instancesLatestArr = $.grep($.tooltipster.__instancesLatestArr, function(el, i) {
2559
- return self !== el;
2553
+ self._$origin
2554
+ .removeData('tooltipster-ns')
2555
+ .removeData('tooltipster-initialTitle');
2556
+ }
2557
+ else {
2558
+ // remove the instance namespace from the list of namespaces of
2559
+ // tooltips present on the element
2560
+ ns = $.grep(ns, function(el, i) {
2561
+ return el !== self.__namespace;
2560
2562
  });
2561
-
2562
- clearInterval(self.__garbageCollector);
2563
- });
2563
+ self._$origin.data('tooltipster-ns', ns);
2564
+ }
2564
2565
  }
2566
+
2567
+ // last event
2568
+ self._trigger('destroyed');
2569
+
2570
+ // unbind private and public event listeners
2571
+ self._off();
2572
+ self.off();
2573
+
2574
+ // remove external references, just in case
2575
+ self.__Content = null;
2576
+ self.__$emitterPrivate = null;
2577
+ self.__$emitterPublic = null;
2578
+ self.__options.parent = null;
2579
+ self._$origin = null;
2580
+ self._$tooltip = null;
2581
+
2582
+ // make sure the object is no longer referenced in there to prevent
2583
+ // memory leaks
2584
+ $.tooltipster.__instancesLatestArr = $.grep($.tooltipster.__instancesLatestArr, function(el, i) {
2585
+ return self !== el;
2586
+ });
2587
+
2588
+ clearInterval(self.__garbageCollector);
2565
2589
  }
2566
2590
  else {
2567
2591
  self.__destroyError();
@@ -2713,7 +2737,7 @@ $.Tooltipster.prototype = {
2713
2737
  */
2714
2738
  open: function(callback) {
2715
2739
 
2716
- if (!this.__destroyed && !this.__destroying) {
2740
+ if (!this.__destroyed) {
2717
2741
  this._open(null, callback);
2718
2742
  }
2719
2743
  else {
@@ -2786,27 +2810,31 @@ $.Tooltipster.prototype = {
2786
2810
 
2787
2811
  if (!self.__destroyed) {
2788
2812
 
2789
- // if the tooltip has not been removed from DOM manually (or if it
2790
- // has been detached on purpose)
2791
- if (bodyContains(self._$tooltip) || tooltipIsDetached) {
2792
-
2793
- if (!tooltipIsDetached) {
2794
- // detach in case the tooltip overflows the window and adds
2795
- // scrollbars to it, so __geometry can be accurate
2796
- self._$tooltip.detach();
2797
- }
2813
+ // if the tooltip is still open and the origin is still in the DOM
2814
+ if (self.__state != 'closed' && bodyContains(self._$origin)) {
2798
2815
 
2799
- // refresh the geometry object before passing it as a helper
2800
- self.__Geometry = self.__geometry();
2801
-
2802
- // let a plugin fo the rest
2803
- self._trigger({
2804
- type: 'reposition',
2805
- event: event,
2806
- helper: {
2807
- geo: self.__Geometry
2816
+ // if the tooltip has not been removed from DOM manually (or if it
2817
+ // has been detached on purpose)
2818
+ if (tooltipIsDetached || bodyContains(self._$tooltip)) {
2819
+
2820
+ if (!tooltipIsDetached) {
2821
+ // detach in case the tooltip overflows the window and adds
2822
+ // scrollbars to it, so __geometry can be accurate
2823
+ self._$tooltip.detach();
2808
2824
  }
2809
- });
2825
+
2826
+ // refresh the geometry object before passing it as a helper
2827
+ self.__Geometry = self.__geometry();
2828
+
2829
+ // let a plugin fo the rest
2830
+ self._trigger({
2831
+ type: 'reposition',
2832
+ event: event,
2833
+ helper: {
2834
+ geo: self.__Geometry
2835
+ }
2836
+ });
2837
+ }
2810
2838
  }
2811
2839
  }
2812
2840
  else {
@@ -2837,7 +2865,6 @@ $.Tooltipster.prototype = {
2837
2865
 
2838
2866
  return {
2839
2867
  destroyed: this.__destroyed,
2840
- destroying: this.__destroying,
2841
2868
  enabled: this.__enabled,
2842
2869
  open: this.__state !== 'closed',
2843
2870
  state: this.__state
@@ -3072,7 +3099,7 @@ Ruler.prototype = {
3072
3099
 
3073
3100
  this.$container = $('<div class="tooltipster-ruler"></div>')
3074
3101
  .append(this.__$tooltip)
3075
- .appendTo('body');
3102
+ .appendTo(env.window.document.body);
3076
3103
  },
3077
3104
 
3078
3105
  /**
@@ -3190,9 +3217,10 @@ Ruler.prototype = {
3190
3217
  // bcr.width/height are not defined in IE8- but in this
3191
3218
  // case, bcr.right/bottom will have the same value
3192
3219
  // except in iOS 8+ where tooltipBcr.bottom/right are wrong
3193
- // after scrolling for reasons yet to be determined
3194
- height: tooltipBcr.height || tooltipBcr.bottom,
3195
- width: tooltipBcr.width || tooltipBcr.right
3220
+ // after scrolling for reasons yet to be determined.
3221
+ // tooltipBcr.top/left might not be 0, see issue #514
3222
+ height: tooltipBcr.height || (tooltipBcr.bottom - tooltipBcr.top),
3223
+ width: tooltipBcr.width || (tooltipBcr.right - tooltipBcr.left)
3196
3224
  }};
3197
3225
 
3198
3226
  if (this.constraints) {
@@ -3229,8 +3257,13 @@ Ruler.prototype = {
3229
3257
  result.fits = fits.height && fits.width;
3230
3258
  }
3231
3259
 
3232
- // old versions of IE get the width wrong for some reason
3233
- if (env.IE && env.IE <= 11) {
3260
+ // old versions of IE get the width wrong for some reason and it causes
3261
+ // the text to be broken to a new line, so we round it up. If the width
3262
+ // is the width of the screen though, we can assume it is accurate.
3263
+ if ( env.IE
3264
+ && env.IE <= 11
3265
+ && result.size.width !== env.window.document.documentElement.clientWidth
3266
+ ) {
3234
3267
  result.size.width = Math.ceil(result.size.width) + 1;
3235
3268
  }
3236
3269
 
@@ -3294,7 +3327,7 @@ function transitionSupport() {
3294
3327
 
3295
3328
  // we'll return jQuery for plugins not to have to declare it as a dependency,
3296
3329
  // but it's done by a build task since it should be included only once at the
3297
- // end when we concatenate the core file with a plugin
3330
+ // end when we concatenate the main file with a plugin
3298
3331
  // sideTip is Tooltipster's default plugin.
3299
3332
  // This file will be UMDified by a build task.
3300
3333
 
@@ -3566,7 +3599,13 @@ $.tooltipster._plugin({
3566
3599
  var $clone = self.__instance._$tooltip.clone(),
3567
3600
  // start position tests session
3568
3601
  ruler = $.tooltipster._getRuler($clone),
3569
- satisfied = false;
3602
+ satisfied = false,
3603
+ animation = self.__instance.option('animation');
3604
+
3605
+ // an animation class could contain properties that distort the size
3606
+ if (animation) {
3607
+ $clone.removeClass('tooltipster-'+ animation);
3608
+ }
3570
3609
 
3571
3610
  // start evaluating scenarios
3572
3611
  $.each(['window', 'document'], function(i, container) {
@@ -4009,7 +4048,6 @@ $.tooltipster._plugin({
4009
4048
 
4010
4049
  if (self.__options.functionPosition) {
4011
4050
 
4012
-
4013
4051
  var result = self.__options.functionPosition.call(self, self.__instance, helper, finalResultClone);
4014
4052
 
4015
4053
  if (result) finalResult = result;
@@ -4019,7 +4057,6 @@ $.tooltipster._plugin({
4019
4057
  // use for it during the position event, now it's over)
4020
4058
  ruler.destroy();
4021
4059
 
4022
-
4023
4060
  // compute the position of the target relatively to the tooltip root
4024
4061
  // element so we can place the arrow and make the needed adjustments
4025
4062
  var arrowCoord,