bootstrap-sass 3.3.0.1 → 3.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.travis.yml +8 -14
  4. data/CHANGELOG.md +64 -0
  5. data/CONTRIBUTING.md +8 -1
  6. data/Gemfile +1 -4
  7. data/LICENSE +2 -1
  8. data/README.md +135 -114
  9. data/Rakefile +58 -12
  10. data/assets/fonts/bootstrap/glyphicons-halflings-regular.eot +0 -0
  11. data/assets/fonts/bootstrap/glyphicons-halflings-regular.svg +273 -214
  12. data/assets/fonts/bootstrap/glyphicons-halflings-regular.ttf +0 -0
  13. data/assets/fonts/bootstrap/glyphicons-halflings-regular.woff +0 -0
  14. data/assets/fonts/bootstrap/glyphicons-halflings-regular.woff2 +0 -0
  15. data/assets/javascripts/bootstrap/affix.js +11 -9
  16. data/assets/javascripts/bootstrap/alert.js +6 -5
  17. data/assets/javascripts/bootstrap/button.js +25 -16
  18. data/assets/javascripts/bootstrap/carousel.js +25 -18
  19. data/assets/javascripts/bootstrap/collapse.js +13 -12
  20. data/assets/javascripts/bootstrap/dropdown.js +51 -47
  21. data/assets/javascripts/bootstrap/modal.js +112 -35
  22. data/assets/javascripts/bootstrap/popover.js +31 -27
  23. data/assets/javascripts/bootstrap/scrollspy.js +19 -22
  24. data/assets/javascripts/bootstrap/tab.js +14 -12
  25. data/assets/javascripts/bootstrap/tooltip.js +255 -56
  26. data/assets/javascripts/bootstrap/transition.js +5 -5
  27. data/assets/javascripts/bootstrap-sprockets.js +2 -2
  28. data/assets/javascripts/bootstrap.js +1282 -962
  29. data/assets/javascripts/bootstrap.min.js +6 -0
  30. data/assets/stylesheets/_bootstrap-compass.scss +2 -0
  31. data/assets/stylesheets/_bootstrap-mincer.scss +4 -2
  32. data/assets/stylesheets/_bootstrap-sprockets.scss +2 -0
  33. data/assets/stylesheets/_bootstrap.scss +6 -0
  34. data/assets/stylesheets/bootstrap/_alerts.scss +8 -3
  35. data/assets/stylesheets/bootstrap/_badges.scss +16 -5
  36. data/assets/stylesheets/bootstrap/_breadcrumbs.scss +3 -1
  37. data/assets/stylesheets/bootstrap/_button-groups.scss +11 -14
  38. data/assets/stylesheets/bootstrap/_buttons.scss +18 -10
  39. data/assets/stylesheets/bootstrap/_carousel.scss +40 -36
  40. data/assets/stylesheets/bootstrap/_close.scss +2 -0
  41. data/assets/stylesheets/bootstrap/_code.scss +3 -3
  42. data/assets/stylesheets/bootstrap/_component-animations.scss +2 -2
  43. data/assets/stylesheets/bootstrap/_dropdowns.scss +24 -24
  44. data/assets/stylesheets/bootstrap/_forms.scss +149 -103
  45. data/assets/stylesheets/bootstrap/_glyphicons.scss +85 -12
  46. data/assets/stylesheets/bootstrap/_grid.scss +10 -0
  47. data/assets/stylesheets/bootstrap/_input-groups.scss +10 -5
  48. data/assets/stylesheets/bootstrap/_jumbotron.scss +11 -5
  49. data/assets/stylesheets/bootstrap/_labels.scss +1 -1
  50. data/assets/stylesheets/bootstrap/_list-group.scss +30 -34
  51. data/assets/stylesheets/bootstrap/_media.scss +19 -0
  52. data/assets/stylesheets/bootstrap/_mixins.scss +1 -0
  53. data/assets/stylesheets/bootstrap/_modals.scss +9 -8
  54. data/assets/stylesheets/bootstrap/_navbar.scss +77 -82
  55. data/assets/stylesheets/bootstrap/_navs.scss +4 -6
  56. data/assets/stylesheets/bootstrap/_normalize.scss +13 -13
  57. data/assets/stylesheets/bootstrap/_pager.scss +2 -2
  58. data/assets/stylesheets/bootstrap/_pagination.scss +15 -17
  59. data/assets/stylesheets/bootstrap/_panels.scss +16 -6
  60. data/assets/stylesheets/bootstrap/_popovers.scss +50 -58
  61. data/assets/stylesheets/bootstrap/_print.scss +90 -98
  62. data/assets/stylesheets/bootstrap/_progress-bars.scss +3 -3
  63. data/assets/stylesheets/bootstrap/_responsive-embed.scss +10 -10
  64. data/assets/stylesheets/bootstrap/_responsive-utilities.scss +11 -6
  65. data/assets/stylesheets/bootstrap/_scaffolding.scss +18 -7
  66. data/assets/stylesheets/bootstrap/_tables.scss +24 -24
  67. data/assets/stylesheets/bootstrap/_theme.scss +57 -22
  68. data/assets/stylesheets/bootstrap/_thumbnails.scss +1 -1
  69. data/assets/stylesheets/bootstrap/_tooltip.scss +49 -32
  70. data/assets/stylesheets/bootstrap/_type.scss +12 -12
  71. data/assets/stylesheets/bootstrap/_utilities.scss +0 -1
  72. data/assets/stylesheets/bootstrap/_variables.scss +27 -17
  73. data/assets/stylesheets/bootstrap/_wells.scss +2 -2
  74. data/assets/stylesheets/bootstrap/mixins/_alerts.scss +2 -1
  75. data/assets/stylesheets/bootstrap/mixins/_background-variant.scss +2 -1
  76. data/assets/stylesheets/bootstrap/mixins/_border-radius.scss +4 -4
  77. data/assets/stylesheets/bootstrap/mixins/_buttons.scss +20 -11
  78. data/assets/stylesheets/bootstrap/mixins/_center-block.scss +1 -1
  79. data/assets/stylesheets/bootstrap/mixins/_clearfix.scss +1 -1
  80. data/assets/stylesheets/bootstrap/mixins/_forms.scss +4 -4
  81. data/assets/stylesheets/bootstrap/mixins/_gradients.scss +6 -8
  82. data/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +2 -2
  83. data/assets/stylesheets/bootstrap/mixins/_grid.scss +8 -8
  84. data/assets/stylesheets/bootstrap/mixins/_hide-text.scss +3 -3
  85. data/assets/stylesheets/bootstrap/mixins/_image.scss +5 -10
  86. data/assets/stylesheets/bootstrap/mixins/_list-group.scss +3 -2
  87. data/assets/stylesheets/bootstrap/mixins/_opacity.scss +2 -3
  88. data/assets/stylesheets/bootstrap/mixins/_pagination.scss +2 -1
  89. data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +18 -0
  90. data/assets/stylesheets/bootstrap/mixins/_resize.scss +1 -1
  91. data/assets/stylesheets/bootstrap/mixins/_responsive-visibility.scss +1 -5
  92. data/assets/stylesheets/bootstrap/mixins/_tab-focus.scss +3 -3
  93. data/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +2 -1
  94. data/assets/stylesheets/bootstrap/mixins/_vendor-prefixes.scss +4 -4
  95. data/bootstrap-sass.gemspec +10 -9
  96. data/bower.json +6 -20
  97. data/composer.json +2 -2
  98. data/eyeglass-exports.js +7 -0
  99. data/lib/bootstrap-sass/engine.rb +6 -1
  100. data/lib/bootstrap-sass/version.rb +2 -2
  101. data/lib/bootstrap-sass.rb +32 -13
  102. data/package-lock.json +1611 -0
  103. data/package.json +21 -7
  104. data/sache.json +1 -1
  105. data/tasks/bower.rake +2 -5
  106. data/tasks/converter/fonts_conversion.rb +1 -1
  107. data/tasks/converter/js_conversion.rb +7 -5
  108. data/tasks/converter/less_conversion.rb +48 -37
  109. data/tasks/converter/network.rb +12 -7
  110. data/tasks/converter.rb +1 -1
  111. data/templates/project/_bootstrap-variables.sass +27 -18
  112. data/templates/project/styles.sass +3 -0
  113. data/test/compilation_test.rb +24 -12
  114. data/test/dummy_rails/app/assets/stylesheets/{application.css.sass → application.sass} +0 -0
  115. data/test/dummy_rails/app/views/pages/root.html.slim +43 -0
  116. data/test/dummy_rails/config/application.rb +2 -1
  117. data/test/dummy_rails/config/boot.rb +1 -1
  118. data/test/dummy_rails/config/environments/development.rb +0 -3
  119. data/test/dummy_rails/config/environments/production.rb +7 -1
  120. data/test/dummy_rails/config/environments/test.rb +9 -1
  121. data/test/dummy_sass_only/Gemfile +1 -1
  122. data/test/dummy_sass_only/compile.rb +14 -7
  123. data/test/dummy_sass_only/import_all.scss +2 -0
  124. data/test/gemfiles/default.gemfile +3 -0
  125. data/test/node_mincer_test.rb +2 -3
  126. data/test/node_sass_compile_test.sh +4 -3
  127. data/test/sass_test.rb +10 -7
  128. data/test/sprockets_rails_test.rb +12 -8
  129. data/test/support/dummy_rails_integration.rb +1 -1
  130. data/test/support/reporting.rb +10 -0
  131. data/test/test_helper.rb +3 -2
  132. metadata +56 -46
  133. data/test/compass_test.rb +0 -9
  134. data/test/dummy_rails/log/development.log +0 -0
  135. data/test/dummy_sass_only/import_all.sass +0 -2
  136. data/test/gemfiles/sass_3_2.gemfile +0 -6
  137. data/test/gemfiles/sass_3_3.gemfile +0 -6
  138. data/test/gemfiles/sass_3_4.gemfile +0 -7
  139. data/test/gemfiles/sass_head.gemfile +0 -6
@@ -1,31 +1,162 @@
1
1
  /* ========================================================================
2
- * Bootstrap: tooltip.js v3.3.0
3
- * http://getbootstrap.com/javascript/#tooltip
2
+ * Bootstrap: tooltip.js v3.4.1
3
+ * https://getbootstrap.com/docs/3.4/javascript/#tooltip
4
4
  * Inspired by the original jQuery.tipsy by Jason Frame
5
5
  * ========================================================================
6
- * Copyright 2011-2014 Twitter, Inc.
6
+ * Copyright 2011-2019 Twitter, Inc.
7
7
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
8
8
  * ======================================================================== */
9
9
 
10
-
11
10
  +function ($) {
12
11
  'use strict';
13
12
 
13
+ var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']
14
+
15
+ var uriAttrs = [
16
+ 'background',
17
+ 'cite',
18
+ 'href',
19
+ 'itemtype',
20
+ 'longdesc',
21
+ 'poster',
22
+ 'src',
23
+ 'xlink:href'
24
+ ]
25
+
26
+ var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i
27
+
28
+ var DefaultWhitelist = {
29
+ // Global attributes allowed on any supplied element below.
30
+ '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
31
+ a: ['target', 'href', 'title', 'rel'],
32
+ area: [],
33
+ b: [],
34
+ br: [],
35
+ col: [],
36
+ code: [],
37
+ div: [],
38
+ em: [],
39
+ hr: [],
40
+ h1: [],
41
+ h2: [],
42
+ h3: [],
43
+ h4: [],
44
+ h5: [],
45
+ h6: [],
46
+ i: [],
47
+ img: ['src', 'alt', 'title', 'width', 'height'],
48
+ li: [],
49
+ ol: [],
50
+ p: [],
51
+ pre: [],
52
+ s: [],
53
+ small: [],
54
+ span: [],
55
+ sub: [],
56
+ sup: [],
57
+ strong: [],
58
+ u: [],
59
+ ul: []
60
+ }
61
+
62
+ /**
63
+ * A pattern that recognizes a commonly useful subset of URLs that are safe.
64
+ *
65
+ * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
66
+ */
67
+ var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi
68
+
69
+ /**
70
+ * A pattern that matches safe data URLs. Only matches image, video and audio types.
71
+ *
72
+ * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
73
+ */
74
+ var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i
75
+
76
+ function allowedAttribute(attr, allowedAttributeList) {
77
+ var attrName = attr.nodeName.toLowerCase()
78
+
79
+ if ($.inArray(attrName, allowedAttributeList) !== -1) {
80
+ if ($.inArray(attrName, uriAttrs) !== -1) {
81
+ return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN))
82
+ }
83
+
84
+ return true
85
+ }
86
+
87
+ var regExp = $(allowedAttributeList).filter(function (index, value) {
88
+ return value instanceof RegExp
89
+ })
90
+
91
+ // Check if a regular expression validates the attribute.
92
+ for (var i = 0, l = regExp.length; i < l; i++) {
93
+ if (attrName.match(regExp[i])) {
94
+ return true
95
+ }
96
+ }
97
+
98
+ return false
99
+ }
100
+
101
+ function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
102
+ if (unsafeHtml.length === 0) {
103
+ return unsafeHtml
104
+ }
105
+
106
+ if (sanitizeFn && typeof sanitizeFn === 'function') {
107
+ return sanitizeFn(unsafeHtml)
108
+ }
109
+
110
+ // IE 8 and below don't support createHTMLDocument
111
+ if (!document.implementation || !document.implementation.createHTMLDocument) {
112
+ return unsafeHtml
113
+ }
114
+
115
+ var createdDocument = document.implementation.createHTMLDocument('sanitization')
116
+ createdDocument.body.innerHTML = unsafeHtml
117
+
118
+ var whitelistKeys = $.map(whiteList, function (el, i) { return i })
119
+ var elements = $(createdDocument.body).find('*')
120
+
121
+ for (var i = 0, len = elements.length; i < len; i++) {
122
+ var el = elements[i]
123
+ var elName = el.nodeName.toLowerCase()
124
+
125
+ if ($.inArray(elName, whitelistKeys) === -1) {
126
+ el.parentNode.removeChild(el)
127
+
128
+ continue
129
+ }
130
+
131
+ var attributeList = $.map(el.attributes, function (el) { return el })
132
+ var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])
133
+
134
+ for (var j = 0, len2 = attributeList.length; j < len2; j++) {
135
+ if (!allowedAttribute(attributeList[j], whitelistedAttributes)) {
136
+ el.removeAttribute(attributeList[j].nodeName)
137
+ }
138
+ }
139
+ }
140
+
141
+ return createdDocument.body.innerHTML
142
+ }
143
+
14
144
  // TOOLTIP PUBLIC CLASS DEFINITION
15
145
  // ===============================
16
146
 
17
147
  var Tooltip = function (element, options) {
18
- this.type =
19
- this.options =
20
- this.enabled =
21
- this.timeout =
22
- this.hoverState =
148
+ this.type = null
149
+ this.options = null
150
+ this.enabled = null
151
+ this.timeout = null
152
+ this.hoverState = null
23
153
  this.$element = null
154
+ this.inState = null
24
155
 
25
156
  this.init('tooltip', element, options)
26
157
  }
27
158
 
28
- Tooltip.VERSION = '3.3.0'
159
+ Tooltip.VERSION = '3.4.1'
29
160
 
30
161
  Tooltip.TRANSITION_DURATION = 150
31
162
 
@@ -42,7 +173,10 @@
42
173
  viewport: {
43
174
  selector: 'body',
44
175
  padding: 0
45
- }
176
+ },
177
+ sanitize : true,
178
+ sanitizeFn : null,
179
+ whiteList : DefaultWhitelist
46
180
  }
47
181
 
48
182
  Tooltip.prototype.init = function (type, element, options) {
@@ -50,7 +184,12 @@
50
184
  this.type = type
51
185
  this.$element = $(element)
52
186
  this.options = this.getOptions(options)
53
- this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
187
+ this.$viewport = this.options.viewport && $(document).find($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
188
+ this.inState = { click: false, hover: false, focus: false }
189
+
190
+ if (this.$element[0] instanceof document.constructor && !this.options.selector) {
191
+ throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
192
+ }
54
193
 
55
194
  var triggers = this.options.trigger.split(' ')
56
195
 
@@ -78,7 +217,15 @@
78
217
  }
79
218
 
80
219
  Tooltip.prototype.getOptions = function (options) {
81
- options = $.extend({}, this.getDefaults(), this.$element.data(), options)
220
+ var dataAttributes = this.$element.data()
221
+
222
+ for (var dataAttr in dataAttributes) {
223
+ if (dataAttributes.hasOwnProperty(dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) {
224
+ delete dataAttributes[dataAttr]
225
+ }
226
+ }
227
+
228
+ options = $.extend({}, this.getDefaults(), dataAttributes, options)
82
229
 
83
230
  if (options.delay && typeof options.delay == 'number') {
84
231
  options.delay = {
@@ -87,6 +234,10 @@
87
234
  }
88
235
  }
89
236
 
237
+ if (options.sanitize) {
238
+ options.template = sanitizeHtml(options.template, options.whiteList, options.sanitizeFn)
239
+ }
240
+
90
241
  return options
91
242
  }
92
243
 
@@ -105,16 +256,20 @@
105
256
  var self = obj instanceof this.constructor ?
106
257
  obj : $(obj.currentTarget).data('bs.' + this.type)
107
258
 
108
- if (self && self.$tip && self.$tip.is(':visible')) {
109
- self.hoverState = 'in'
110
- return
111
- }
112
-
113
259
  if (!self) {
114
260
  self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
115
261
  $(obj.currentTarget).data('bs.' + this.type, self)
116
262
  }
117
263
 
264
+ if (obj instanceof $.Event) {
265
+ self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
266
+ }
267
+
268
+ if (self.tip().hasClass('in') || self.hoverState == 'in') {
269
+ self.hoverState = 'in'
270
+ return
271
+ }
272
+
118
273
  clearTimeout(self.timeout)
119
274
 
120
275
  self.hoverState = 'in'
@@ -126,6 +281,14 @@
126
281
  }, self.options.delay.show)
127
282
  }
128
283
 
284
+ Tooltip.prototype.isInStateTrue = function () {
285
+ for (var key in this.inState) {
286
+ if (this.inState[key]) return true
287
+ }
288
+
289
+ return false
290
+ }
291
+
129
292
  Tooltip.prototype.leave = function (obj) {
130
293
  var self = obj instanceof this.constructor ?
131
294
  obj : $(obj.currentTarget).data('bs.' + this.type)
@@ -135,6 +298,12 @@
135
298
  $(obj.currentTarget).data('bs.' + this.type, self)
136
299
  }
137
300
 
301
+ if (obj instanceof $.Event) {
302
+ self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
303
+ }
304
+
305
+ if (self.isInStateTrue()) return
306
+
138
307
  clearTimeout(self.timeout)
139
308
 
140
309
  self.hoverState = 'out'
@@ -180,7 +349,8 @@
180
349
  .addClass(placement)
181
350
  .data('bs.' + this.type, this)
182
351
 
183
- this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
352
+ this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element)
353
+ this.$element.trigger('inserted.bs.' + this.type)
184
354
 
185
355
  var pos = this.getPosition()
186
356
  var actualWidth = $tip[0].offsetWidth
@@ -188,13 +358,12 @@
188
358
 
189
359
  if (autoPlace) {
190
360
  var orgPlacement = placement
191
- var $container = this.options.container ? $(this.options.container) : this.$element.parent()
192
- var containerDim = this.getPosition($container)
361
+ var viewportDim = this.getPosition(this.$viewport)
193
362
 
194
- placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :
195
- placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :
196
- placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
197
- placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
363
+ placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' :
364
+ placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' :
365
+ placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' :
366
+ placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' :
198
367
  placement
199
368
 
200
369
  $tip
@@ -235,8 +404,8 @@
235
404
  if (isNaN(marginTop)) marginTop = 0
236
405
  if (isNaN(marginLeft)) marginLeft = 0
237
406
 
238
- offset.top = offset.top + marginTop
239
- offset.left = offset.left + marginLeft
407
+ offset.top += marginTop
408
+ offset.left += marginLeft
240
409
 
241
410
  // $.fn.offset doesn't round pixel values
242
411
  // so we use setOffset directly with our own function B-0
@@ -272,30 +441,41 @@
272
441
  this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
273
442
  }
274
443
 
275
- Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) {
444
+ Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
276
445
  this.arrow()
277
- .css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
278
- .css(isHorizontal ? 'top' : 'left', '')
446
+ .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
447
+ .css(isVertical ? 'top' : 'left', '')
279
448
  }
280
449
 
281
450
  Tooltip.prototype.setContent = function () {
282
451
  var $tip = this.tip()
283
452
  var title = this.getTitle()
284
453
 
285
- $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
454
+ if (this.options.html) {
455
+ if (this.options.sanitize) {
456
+ title = sanitizeHtml(title, this.options.whiteList, this.options.sanitizeFn)
457
+ }
458
+
459
+ $tip.find('.tooltip-inner').html(title)
460
+ } else {
461
+ $tip.find('.tooltip-inner').text(title)
462
+ }
463
+
286
464
  $tip.removeClass('fade in top bottom left right')
287
465
  }
288
466
 
289
467
  Tooltip.prototype.hide = function (callback) {
290
468
  var that = this
291
- var $tip = this.tip()
469
+ var $tip = $(this.$tip)
292
470
  var e = $.Event('hide.bs.' + this.type)
293
471
 
294
472
  function complete() {
295
473
  if (that.hoverState != 'in') $tip.detach()
296
- that.$element
297
- .removeAttr('aria-describedby')
298
- .trigger('hidden.bs.' + that.type)
474
+ if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
475
+ that.$element
476
+ .removeAttr('aria-describedby')
477
+ .trigger('hidden.bs.' + that.type)
478
+ }
299
479
  callback && callback()
300
480
  }
301
481
 
@@ -305,7 +485,7 @@
305
485
 
306
486
  $tip.removeClass('in')
307
487
 
308
- $.support.transition && this.$tip.hasClass('fade') ?
488
+ $.support.transition && $tip.hasClass('fade') ?
309
489
  $tip
310
490
  .one('bsTransitionEnd', complete)
311
491
  .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
@@ -318,7 +498,7 @@
318
498
 
319
499
  Tooltip.prototype.fixTitle = function () {
320
500
  var $e = this.$element
321
- if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
501
+ if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
322
502
  $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
323
503
  }
324
504
  }
@@ -338,7 +518,10 @@
338
518
  // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
339
519
  elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
340
520
  }
341
- var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
521
+ var isSvg = window.SVGElement && el instanceof window.SVGElement
522
+ // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
523
+ // See https://github.com/twbs/bootstrap/issues/20280
524
+ var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
342
525
  var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
343
526
  var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
344
527
 
@@ -346,10 +529,10 @@
346
529
  }
347
530
 
348
531
  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
349
- return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
350
- placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
532
+ return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
533
+ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
351
534
  placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
352
- /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
535
+ /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
353
536
 
354
537
  }
355
538
 
@@ -373,7 +556,7 @@
373
556
  var rightEdgeOffset = pos.left + viewportPadding + actualWidth
374
557
  if (leftEdgeOffset < viewportDimensions.left) { // left overflow
375
558
  delta.left = viewportDimensions.left - leftEdgeOffset
376
- } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
559
+ } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
377
560
  delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
378
561
  }
379
562
  }
@@ -399,7 +582,13 @@
399
582
  }
400
583
 
401
584
  Tooltip.prototype.tip = function () {
402
- return (this.$tip = this.$tip || $(this.options.template))
585
+ if (!this.$tip) {
586
+ this.$tip = $(this.options.template)
587
+ if (this.$tip.length != 1) {
588
+ throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
589
+ }
590
+ }
591
+ return this.$tip
403
592
  }
404
593
 
405
594
  Tooltip.prototype.arrow = function () {
@@ -428,7 +617,13 @@
428
617
  }
429
618
  }
430
619
 
431
- self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
620
+ if (e) {
621
+ self.inState.click = !self.inState.click
622
+ if (self.isInStateTrue()) self.enter(self)
623
+ else self.leave(self)
624
+ } else {
625
+ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
626
+ }
432
627
  }
433
628
 
434
629
  Tooltip.prototype.destroy = function () {
@@ -436,27 +631,31 @@
436
631
  clearTimeout(this.timeout)
437
632
  this.hide(function () {
438
633
  that.$element.off('.' + that.type).removeData('bs.' + that.type)
634
+ if (that.$tip) {
635
+ that.$tip.detach()
636
+ }
637
+ that.$tip = null
638
+ that.$arrow = null
639
+ that.$viewport = null
640
+ that.$element = null
439
641
  })
440
642
  }
441
643
 
644
+ Tooltip.prototype.sanitizeHtml = function (unsafeHtml) {
645
+ return sanitizeHtml(unsafeHtml, this.options.whiteList, this.options.sanitizeFn)
646
+ }
442
647
 
443
648
  // TOOLTIP PLUGIN DEFINITION
444
649
  // =========================
445
650
 
446
651
  function Plugin(option) {
447
652
  return this.each(function () {
448
- var $this = $(this)
449
- var data = $this.data('bs.tooltip')
450
- var options = typeof option == 'object' && option
451
- var selector = options && options.selector
452
-
453
- if (!data && option == 'destroy') return
454
- if (selector) {
455
- if (!data) $this.data('bs.tooltip', (data = {}))
456
- if (!data[selector]) data[selector] = new Tooltip(this, options)
457
- } else {
458
- if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
459
- }
653
+ var $this = $(this)
654
+ var data = $this.data('bs.tooltip')
655
+ var options = typeof option == 'object' && option
656
+
657
+ if (!data && /destroy|hide/.test(option)) return
658
+ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
460
659
  if (typeof option == 'string') data[option]()
461
660
  })
462
661
  }
@@ -1,8 +1,8 @@
1
1
  /* ========================================================================
2
- * Bootstrap: transition.js v3.3.0
3
- * http://getbootstrap.com/javascript/#transitions
2
+ * Bootstrap: transition.js v3.4.1
3
+ * https://getbootstrap.com/docs/3.4/javascript/#transitions
4
4
  * ========================================================================
5
- * Copyright 2011-2014 Twitter, Inc.
5
+ * Copyright 2011-2019 Twitter, Inc.
6
6
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7
7
  * ======================================================================== */
8
8
 
@@ -10,7 +10,7 @@
10
10
  +function ($) {
11
11
  'use strict';
12
12
 
13
- // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
13
+ // CSS TRANSITION SUPPORT (Shoutout: https://modernizr.com/)
14
14
  // ============================================================
15
15
 
16
16
  function transitionEnd() {
@@ -32,7 +32,7 @@
32
32
  return false // explicit for ie8 ( ._.)
33
33
  }
34
34
 
35
- // http://blog.alexmaccaw.com/css-transitions
35
+ // https://blog.alexmaccaw.com/css-transitions
36
36
  $.fn.emulateTransitionEnd = function (duration) {
37
37
  var called = false
38
38
  var $el = this
@@ -4,9 +4,9 @@
4
4
  //= require ./bootstrap/carousel
5
5
  //= require ./bootstrap/collapse
6
6
  //= require ./bootstrap/dropdown
7
+ //= require ./bootstrap/modal
8
+ //= require ./bootstrap/scrollspy
7
9
  //= require ./bootstrap/tab
8
10
  //= require ./bootstrap/transition
9
- //= require ./bootstrap/scrollspy
10
- //= require ./bootstrap/modal
11
11
  //= require ./bootstrap/tooltip
12
12
  //= require ./bootstrap/popover