flashgrid 1.0.20 → 1.0.21

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/flashgrid/version.rb +1 -1
  3. data/vendor/assets/javascripts/affix.js +2 -4
  4. data/vendor/assets/javascripts/collapse.js +6 -4
  5. data/vendor/assets/javascripts/dropdown.js +7 -7
  6. data/vendor/assets/javascripts/map.js +39 -25
  7. data/vendor/assets/javascripts/modal.js +35 -12
  8. data/vendor/assets/javascripts/popover.js +1 -1
  9. data/vendor/assets/javascripts/tooltip.js +64 -40
  10. data/vendor/assets/javascripts/transition.js +4 -4
  11. data/vendor/assets/stylesheets/ad.css.scss +1 -1
  12. data/vendor/assets/stylesheets/affix.css.scss +5 -1
  13. data/vendor/assets/stylesheets/alert.css.scss +5 -5
  14. data/vendor/assets/stylesheets/breadcrumb.css.scss +1 -1
  15. data/vendor/assets/stylesheets/button.css.scss +58 -11
  16. data/vendor/assets/stylesheets/code.css.scss +3 -3
  17. data/vendor/assets/stylesheets/datepicker.css.scss +5 -5
  18. data/vendor/assets/stylesheets/dropdown.css.scss +2 -2
  19. data/vendor/assets/stylesheets/form.css.scss +6 -6
  20. data/vendor/assets/stylesheets/header.css.scss +2 -2
  21. data/vendor/assets/stylesheets/image.css.scss +1 -1
  22. data/vendor/assets/stylesheets/label_and_badge.css.scss +4 -4
  23. data/vendor/assets/stylesheets/map.css.scss +1 -1
  24. data/vendor/assets/stylesheets/modal.css.scss +3 -3
  25. data/vendor/assets/stylesheets/pagination.css.scss +3 -3
  26. data/vendor/assets/stylesheets/panel.css.scss +3 -3
  27. data/vendor/assets/stylesheets/placeholder.css.scss +1 -1
  28. data/vendor/assets/stylesheets/popover.css.scss +5 -4
  29. data/vendor/assets/stylesheets/progress.css.scss +2 -2
  30. data/vendor/assets/stylesheets/tab.css.scss +12 -12
  31. data/vendor/assets/stylesheets/table.css.scss +5 -5
  32. data/vendor/assets/stylesheets/tooltip.css.scss +2 -1
  33. data/vendor/assets/stylesheets/trunk.css.scss +4 -4
  34. data/vendor/assets/stylesheets/typography.css.scss +5 -1
  35. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4c5229a1d4681449ec4279cac70494ea0987a6ed
4
- data.tar.gz: cd532627376844d552b5c5f7a5ca2acf53862311
3
+ metadata.gz: f35ac3b3d7318eff440da460a22eab9dc32d8131
4
+ data.tar.gz: bc61675d2d8ad19cc7ed9f61dae83deda1150d65
5
5
  SHA512:
6
- metadata.gz: b4aebc737602e5f1725be99084eca7bebfefa3992a96b86dcbb3b5968cfeaa17c773520020a978fae3c4d9a5157d8f6aac274577f6105f0b3277e4a5c7d85840
7
- data.tar.gz: 9f0c40cc45465df33db91a895796400a1c5a7705c7e436776ccc766273f629f3a4a148b9b91d0254e90d6539fd38e9cc56f5bec101c75b53fb11435d1405303c
6
+ metadata.gz: fbb208ad687ef4ddcf1f69a680e8a2e422c166bdae76d27436b4556ffc298d19da37c88d2e73be14dd91c3e966fca88482da33c46208843dcc9b7b9bc7b7de6b
7
+ data.tar.gz: 156afa8de6a7fd6e3e41e6cfbfed537b2c3f568014e7aa865577c1f7a666d2dd8d394eae6ad037e77c0e43e377114470f38bc104fbf13223e5249276b4c30dd5
@@ -1,3 +1,3 @@
1
1
  module Flashgrid
2
- VERSION = "1.0.20"
2
+ VERSION = "1.0.21"
3
3
  end
@@ -46,8 +46,6 @@
46
46
  var offsetTop = offset.top
47
47
  var offsetBottom = offset.bottom
48
48
 
49
- if (this.affixed == 'top') position.top += scrollTop
50
-
51
49
  if (typeof offset != 'object') offsetBottom = offsetTop = offset
52
50
  if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
53
51
  if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
@@ -57,7 +55,7 @@
57
55
  offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
58
56
 
59
57
  if (this.affixed === affix) return
60
- if (this.unpin) this.$element.css('top', '')
58
+ if (this.unpin != null) this.$element.css('top', '')
61
59
 
62
60
  var affixType = 'affix' + (affix ? '-' + affix : '')
63
61
  var e = $.Event(affixType + '.bs.affix')
@@ -75,7 +73,7 @@
75
73
  .trigger($.Event(affixType.replace('affix', 'affixed')))
76
74
 
77
75
  if (affix == 'bottom') {
78
- this.$element.offset({ top: scrollHeight - offsetBottom - this.$element.height() })
76
+ this.$element.offset({ top: position.top })
79
77
  }
80
78
  }
81
79
 
@@ -47,7 +47,8 @@
47
47
 
48
48
  this.transitioning = 1
49
49
 
50
- var complete = function () {
50
+ var complete = function (e) {
51
+ if (e && e.target != this.$element[0]) return
51
52
  this.$element
52
53
  .removeClass('collapsing')
53
54
  .addClass('collapse in')
@@ -86,7 +87,8 @@
86
87
 
87
88
  this.transitioning = 1
88
89
 
89
- var complete = function () {
90
+ var complete = function (e) {
91
+ if (e && e.target != this.$element[0]) return
90
92
  this.transitioning = 0
91
93
  this.$element
92
94
  .trigger('hidden.bs.collapse')
@@ -139,7 +141,7 @@
139
141
  // COLLAPSE DATA-API
140
142
  // =================
141
143
 
142
- $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
144
+ $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
143
145
  var $this = $(this), href
144
146
  var target = $this.attr('data-target')
145
147
  || e.preventDefault()
@@ -151,7 +153,7 @@
151
153
  var $parent = parent && $(parent)
152
154
 
153
155
  if (!data || !data.transitioning) {
154
- if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed')
156
+ if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
155
157
  $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
156
158
  }
157
159
 
@@ -5,7 +5,7 @@
5
5
  // =========================
6
6
 
7
7
  var backdrop = '.dropdown-backdrop'
8
- var toggle = '[data-toggle=dropdown]'
8
+ var toggle = '[data-toggle="dropdown"]'
9
9
  var Dropdown = function (element) {
10
10
  $(element).on('click.bs.dropdown', this.toggle)
11
11
  }
@@ -35,7 +35,7 @@
35
35
  .toggleClass('open')
36
36
  .trigger('shown.bs.dropdown', relatedTarget)
37
37
 
38
- $this.focus()
38
+ $this.trigger('focus')
39
39
  }
40
40
 
41
41
  return false
@@ -55,12 +55,12 @@
55
55
  var isActive = $parent.hasClass('open')
56
56
 
57
57
  if (!isActive || (isActive && e.keyCode == 27)) {
58
- if (e.which == 27) $parent.find(toggle).focus()
59
- return $this.click()
58
+ if (e.which == 27) $parent.find(toggle).trigger('focus')
59
+ return $this.trigger('click')
60
60
  }
61
61
 
62
62
  var desc = ' li:not(.divider):visible a'
63
- var $items = $parent.find('[role=menu]' + desc + ', [role=listbox]' + desc)
63
+ var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
64
64
 
65
65
  if (!$items.length) return
66
66
 
@@ -70,7 +70,7 @@
70
70
  if (e.keyCode == 40 && index < $items.length - 1) index++ // down
71
71
  if (!~index) index = 0
72
72
 
73
- $items.eq(index).focus()
73
+ $items.eq(index).trigger('focus')
74
74
  }
75
75
 
76
76
  function clearMenus(e) {
@@ -133,6 +133,6 @@
133
133
  .on('click.bs.dropdown.data-api', clearMenus)
134
134
  .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
135
135
  .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
136
- .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu], [role=listbox]', Dropdown.prototype.keydown)
136
+ .on('keydown.bs.dropdown.data-api', toggle + ', [role="menu"], [role="listbox"]', Dropdown.prototype.keydown)
137
137
 
138
138
  }(jQuery);
@@ -259,7 +259,7 @@ var GMaps = (function(global) {
259
259
  context_menu_element.innerHTML = html;
260
260
 
261
261
  var context_menu_items = context_menu_element.getElementsByTagName('a'),
262
- context_menu_items_count = context_menu_items.length
262
+ context_menu_items_count = context_menu_items.length,
263
263
  i;
264
264
 
265
265
  for (i = 0; i < context_menu_items_count; i++) {
@@ -472,9 +472,12 @@ GMaps.prototype.createControl = function(options) {
472
472
  var control = document.createElement('div');
473
473
 
474
474
  control.style.cursor = 'pointer';
475
- control.style.fontFamily = 'Arial, sans-serif';
476
- control.style.fontSize = '13px';
477
- control.style.boxShadow = 'rgba(0, 0, 0, 0.398438) 0px 2px 4px';
475
+
476
+ if (options.disableDefaultStyles !== true) {
477
+ control.style.fontFamily = 'Roboto, Arial, sans-serif';
478
+ control.style.fontSize = '11px';
479
+ control.style.boxShadow = 'rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px';
480
+ }
478
481
 
479
482
  for (var option in options.style) {
480
483
  control.style[option] = options.style[option];
@@ -530,15 +533,15 @@ GMaps.prototype.createMarker = function(options) {
530
533
  base_options = {
531
534
  position: new google.maps.LatLng(options.lat, options.lng),
532
535
  map: null
533
- };
536
+ },
537
+ marker_options = extend_object(base_options, options);
534
538
 
535
- delete options.lat;
536
- delete options.lng;
537
- delete options.fences;
538
- delete options.outside;
539
+ delete marker_options.lat;
540
+ delete marker_options.lng;
541
+ delete marker_options.fences;
542
+ delete marker_options.outside;
539
543
 
540
- var marker_options = extend_object(base_options, options),
541
- marker = new google.maps.Marker(marker_options);
544
+ var marker = new google.maps.Marker(marker_options);
542
545
 
543
546
  marker.fences = fences;
544
547
 
@@ -660,7 +663,7 @@ GMaps.prototype.addMarkers = function(array) {
660
663
 
661
664
  GMaps.prototype.hideInfoWindows = function() {
662
665
  for (var i = 0, marker; marker = this.markers[i]; i++){
663
- if (marker.infoWindow){
666
+ if (marker.infoWindow) {
664
667
  marker.infoWindow.close();
665
668
  }
666
669
  }
@@ -685,24 +688,31 @@ GMaps.prototype.removeMarker = function(marker) {
685
688
  return marker;
686
689
  };
687
690
 
688
- GMaps.prototype.removeMarkers = function(collection) {
689
- var collection = (collection || this.markers);
691
+ GMaps.prototype.removeMarkers = function (collection) {
692
+ var new_markers = [];
690
693
 
691
- for (var i = 0;i < this.markers.length; i++) {
692
- if(this.markers[i] === collection[i]) {
694
+ if (typeof collection == 'undefined') {
695
+ for (var i = 0; i < this.markers.length; i++) {
693
696
  this.markers[i].setMap(null);
694
697
  }
695
- }
696
698
 
697
- var new_markers = [];
699
+ this.markers = new_markers;
700
+ }
701
+ else {
702
+ for (var i = 0; i < collection.length; i++) {
703
+ if (this.markers.indexOf(collection[i]) > -1) {
704
+ this.markers[i].setMap(null);
705
+ }
706
+ }
698
707
 
699
- for (var i = 0;i < this.markers.length; i++) {
700
- if(this.markers[i].getMap() != null) {
701
- new_markers.push(this.markers[i]);
708
+ for (var i = 0; i < this.markers.length; i++) {
709
+ if (this.markers[i].getMap() != null) {
710
+ new_markers.push(this.markers[i]);
711
+ }
702
712
  }
703
- }
704
713
 
705
- this.markers = new_markers;
714
+ this.markers = new_markers;
715
+ }
706
716
  };
707
717
 
708
718
  GMaps.prototype.drawOverlay = function(options) {
@@ -1129,8 +1139,8 @@ GMaps.prototype.addLayer = function(layerName, options) {
1129
1139
  case 'places':
1130
1140
  this.singleLayers.places = layer = new google.maps.places.PlacesService(this.map);
1131
1141
 
1132
- //search and nearbySearch callback, Both are the same
1133
- if (options.search || options.nearbySearch) {
1142
+ //search, nearbySearch, radarSearch callback, Both are the same
1143
+ if (options.search || options.nearbySearch || options.radarSearch) {
1134
1144
  var placeSearchRequest = {
1135
1145
  bounds : options.bounds || null,
1136
1146
  keyword : options.keyword || null,
@@ -1141,6 +1151,10 @@ GMaps.prototype.addLayer = function(layerName, options) {
1141
1151
  types : options.types || null
1142
1152
  };
1143
1153
 
1154
+ if (options.radarSearch) {
1155
+ layer.radarSearch(placeSearchRequest, options.radarSearch);
1156
+ }
1157
+
1144
1158
  if (options.search) {
1145
1159
  layer.search(placeSearchRequest, options.search);
1146
1160
  }
@@ -6,13 +6,14 @@
6
6
 
7
7
  var Modal = function (element, options) {
8
8
  this.options = options
9
+ this.$body = $(document.body)
9
10
  this.$element = $(element)
10
11
  this.$backdrop =
11
12
  this.isShown = null
12
13
 
13
14
  if (this.options.remote) {
14
15
  this.$element
15
- .find('.modal')
16
+ .find('.modal-content')
16
17
  .load(this.options.remote, $.proxy(function () {
17
18
  this.$element.trigger('loaded.bs.modal')
18
19
  }, this))
@@ -26,7 +27,7 @@
26
27
  }
27
28
 
28
29
  Modal.prototype.toggle = function (_relatedTarget) {
29
- return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)
30
+ return this.isShown ? this.hide() : this.show(_relatedTarget)
30
31
  }
31
32
 
32
33
  Modal.prototype.show = function (_relatedTarget) {
@@ -39,6 +40,9 @@
39
40
 
40
41
  this.isShown = true
41
42
 
43
+ this.$body.addClass('modal-open')
44
+
45
+ this.setScrollbar()
42
46
  this.escape()
43
47
 
44
48
  this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
@@ -47,7 +51,7 @@
47
51
  var transition = $.support.transition && that.$element.hasClass('fade')
48
52
 
49
53
  if (!that.$element.parent().length) {
50
- that.$element.appendTo(document.body) // don't move modals dom position
54
+ that.$element.appendTo(that.$body) // don't move modals dom position
51
55
  }
52
56
 
53
57
  that.$element
@@ -69,10 +73,10 @@
69
73
  transition ?
70
74
  that.$element.find('.modal-dialog') // wait for modal to slide in
71
75
  .one($.support.transition.end, function () {
72
- that.$element.focus().trigger(e)
76
+ that.$element.trigger('focus').trigger(e)
73
77
  })
74
78
  .emulateTransitionEnd(300) :
75
- that.$element.focus().trigger(e)
79
+ that.$element.trigger('focus').trigger(e)
76
80
  })
77
81
  }
78
82
 
@@ -87,6 +91,9 @@
87
91
 
88
92
  this.isShown = false
89
93
 
94
+ this.$body.removeClass('modal-open')
95
+
96
+ this.resetScrollbar()
90
97
  this.escape()
91
98
 
92
99
  $(document).off('focusin.bs.modal')
@@ -108,7 +115,7 @@
108
115
  .off('focusin.bs.modal') // guard against infinite focus loop
109
116
  .on('focusin.bs.modal', $.proxy(function (e) {
110
117
  if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
111
- this.$element.focus()
118
+ this.$element.trigger('focus')
112
119
  }
113
120
  }, this))
114
121
  }
@@ -144,7 +151,7 @@
144
151
  var doAnimate = $.support.transition && animate
145
152
 
146
153
  this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
147
- .appendTo(document.body)
154
+ .appendTo(this.$body)
148
155
 
149
156
  this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
150
157
  if (e.target !== e.currentTarget) return
@@ -179,6 +186,26 @@
179
186
  }
180
187
  }
181
188
 
189
+ Modal.prototype.setScrollbar = function () {
190
+ if (document.body.clientHeight <= window.innerHeight) return
191
+ var scrollbarWidth = this.measureScrollbar()
192
+ var bodyPad = parseInt(this.$body.css('padding-right') || 0)
193
+ if (scrollbarWidth) this.$body.css('padding-right', bodyPad + scrollbarWidth)
194
+ }
195
+
196
+ Modal.prototype.resetScrollbar = function () {
197
+ this.$body.css('padding-right', '')
198
+ }
199
+
200
+ Modal.prototype.measureScrollbar = function () { // thx walsh
201
+ var scrollDiv = document.createElement('div')
202
+ scrollDiv.className = 'modal-scrollbar-measure'
203
+ this.$body.append(scrollDiv)
204
+ var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
205
+ this.$body[0].removeChild(scrollDiv)
206
+ return scrollbarWidth
207
+ }
208
+
182
209
 
183
210
  // MODAL PLUGIN DEFINITION
184
211
  // =======================
@@ -223,12 +250,8 @@
223
250
  $target
224
251
  .modal(option, this)
225
252
  .one('hide', function () {
226
- $this.is(':visible') && $this.focus()
253
+ $this.is(':visible') && $this.trigger('focus')
227
254
  })
228
255
  })
229
256
 
230
- $(document)
231
- .on('show.bs.modal', '.modal', function () { $(document.body).addClass('in') })
232
- .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('in') })
233
-
234
257
  }(jQuery);
@@ -35,7 +35,7 @@
35
35
  var content = this.getContent()
36
36
 
37
37
  $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
38
- $tip.find('.popover-content')[ // we use append for html objects to maintain js events
38
+ $tip.find('.popover-content').empty()[ // we use append for html objects to maintain js events
39
39
  this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
40
40
  ](content)
41
41
 
@@ -19,19 +19,24 @@
19
19
  animation: true,
20
20
  placement: 'top',
21
21
  selector: false,
22
- template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
22
+ template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
23
23
  trigger: 'hover focus',
24
24
  title: '',
25
25
  delay: 0,
26
26
  html: false,
27
- container: false
27
+ container: false,
28
+ viewport: {
29
+ selector: 'body',
30
+ padding: 0
31
+ }
28
32
  }
29
33
 
30
34
  Tooltip.prototype.init = function (type, element, options) {
31
- this.enabled = true
32
- this.type = type
33
- this.$element = $(element)
34
- this.options = this.getOptions(options)
35
+ this.enabled = true
36
+ this.type = type
37
+ this.$element = $(element)
38
+ this.options = this.getOptions(options)
39
+ this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
35
40
 
36
41
  var triggers = this.options.trigger.split(' ')
37
42
 
@@ -147,18 +152,14 @@
147
152
  var actualHeight = $tip[0].offsetHeight
148
153
 
149
154
  if (autoPlace) {
150
- var $parent = this.$element.parent()
151
-
152
155
  var orgPlacement = placement
153
- var docScroll = document.documentElement.scrollTop || document.body.scrollTop
154
- var parentWidth = this.options.container == 'body' ? window.innerWidth : $parent.outerWidth()
155
- var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()
156
- var parentLeft = this.options.container == 'body' ? 0 : $parent.offset().left
157
-
158
- placement = placement == 'bottom' && pos.top + pos.height + actualHeight - docScroll > parentHeight ? 'top' :
159
- placement == 'top' && pos.top - docScroll - actualHeight < 0 ? 'bottom' :
160
- placement == 'right' && pos.right + actualWidth > parentWidth ? 'left' :
161
- placement == 'left' && pos.left - actualWidth < parentLeft ? 'right' :
156
+ var $parent = this.$element.parent()
157
+ var parentDim = this.getPosition($parent)
158
+
159
+ placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' :
160
+ placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' :
161
+ placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' :
162
+ placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' :
162
163
  placement
163
164
 
164
165
  $tip
@@ -218,29 +219,20 @@
218
219
  var actualHeight = $tip[0].offsetHeight
219
220
 
220
221
  if (placement == 'top' && actualHeight != height) {
221
- replace = true
222
222
  offset.top = offset.top + height - actualHeight
223
223
  }
224
224
 
225
- if (/bottom|top/.test(placement)) {
226
- var delta = 0
225
+ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
227
226
 
228
- if (offset.left < 0) {
229
- delta = offset.left * -2
230
- offset.left = 0
227
+ if (delta.left) offset.left += delta.left
228
+ else offset.top += delta.top
231
229
 
232
- $tip.offset(offset)
233
-
234
- actualWidth = $tip[0].offsetWidth
235
- actualHeight = $tip[0].offsetHeight
236
- }
230
+ var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
231
+ var arrowPosition = delta.left ? 'left' : 'top'
232
+ var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
237
233
 
238
- this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
239
- } else {
240
- this.replaceArrow(actualHeight - height, actualHeight, 'top')
241
- }
242
-
243
- if (replace) $tip.offset(offset)
234
+ $tip.offset(offset)
235
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
244
236
  }
245
237
 
246
238
  Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
@@ -293,12 +285,15 @@
293
285
  return this.getTitle()
294
286
  }
295
287
 
296
- Tooltip.prototype.getPosition = function () {
297
- var el = this.$element[0]
298
- return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
299
- width: el.offsetWidth,
300
- height: el.offsetHeight
301
- }, this.$element.offset())
288
+ Tooltip.prototype.getPosition = function ($element) {
289
+ $element = $element || this.$element
290
+ var el = $element[0]
291
+ var isBody = el.tagName == 'BODY'
292
+ return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
293
+ scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
294
+ width: isBody ? $(window).width() : $element.outerWidth(),
295
+ height: isBody ? $(window).height() : $element.outerHeight()
296
+ }, isBody ? {top: 0, left: 0} : $element.offset())
302
297
  }
303
298
 
304
299
  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
@@ -306,6 +301,35 @@
306
301
  placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
307
302
  placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
308
303
  /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
304
+
305
+ }
306
+
307
+ Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
308
+ var delta = { top: 0, left: 0 }
309
+ if (!this.$viewport) return delta
310
+
311
+ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
312
+ var viewportDimensions = this.getPosition(this.$viewport)
313
+
314
+ if (/right|left/.test(placement)) {
315
+ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
316
+ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
317
+ if (topEdgeOffset < viewportDimensions.top) { // top overflow
318
+ delta.top = viewportDimensions.top - topEdgeOffset
319
+ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
320
+ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
321
+ }
322
+ } else {
323
+ var leftEdgeOffset = pos.left - viewportPadding
324
+ var rightEdgeOffset = pos.left + viewportPadding + actualWidth
325
+ if (leftEdgeOffset < viewportDimensions.left) { // left overflow
326
+ delta.left = viewportDimensions.left - leftEdgeOffset
327
+ } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
328
+ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
329
+ }
330
+ }
331
+
332
+ return delta
309
333
  }
310
334
 
311
335
  Tooltip.prototype.getTitle = function () {