tooltipster-rails 4.1.2 → 4.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,