rails_admin 0.6.5 → 0.6.6

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 (133) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-affix.js +99 -74
  3. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-alert.js +48 -55
  4. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-button.js +70 -65
  5. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-carousel.js +163 -147
  6. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-collapse.js +117 -114
  7. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-dropdown.js +89 -107
  8. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-modal.js +208 -175
  9. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-popover.js +77 -78
  10. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-scrollspy.js +137 -129
  11. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-tab.js +85 -101
  12. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-tooltip.js +364 -268
  13. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-transition.js +51 -52
  14. data/app/assets/javascripts/rails_admin/bootstrap/bootstrap-typeahead.js +1782 -335
  15. data/app/assets/javascripts/rails_admin/ra.filter-box.js +1 -1
  16. data/app/assets/javascripts/rails_admin/ra.filtering-multiselect.js +3 -3
  17. data/app/assets/javascripts/rails_admin/ra.filtering-select.js +1 -1
  18. data/app/assets/javascripts/rails_admin/ra.remote-form.js +6 -2
  19. data/app/assets/stylesheets/rails_admin/base/theming.scss +34 -14
  20. data/app/assets/stylesheets/rails_admin/bootstrap/_alerts.scss +47 -58
  21. data/app/assets/stylesheets/rails_admin/bootstrap/_badges.scss +57 -0
  22. data/app/assets/stylesheets/rails_admin/bootstrap/_breadcrumbs.scss +12 -10
  23. data/app/assets/stylesheets/rails_admin/bootstrap/_button-groups.scss +163 -152
  24. data/app/assets/stylesheets/rails_admin/bootstrap/_buttons.scss +98 -169
  25. data/app/assets/stylesheets/rails_admin/bootstrap/_carousel.scss +151 -66
  26. data/app/assets/stylesheets/rails_admin/bootstrap/_close.scss +11 -8
  27. data/app/assets/stylesheets/rails_admin/bootstrap/_code.scss +36 -29
  28. data/app/assets/stylesheets/rails_admin/bootstrap/_component-animations.scss +16 -3
  29. data/app/assets/stylesheets/rails_admin/bootstrap/_dropdowns.scss +115 -148
  30. data/app/assets/stylesheets/rails_admin/bootstrap/_forms.scss +396 -547
  31. data/app/assets/stylesheets/rails_admin/bootstrap/_glyphicons.scss +237 -0
  32. data/app/assets/stylesheets/rails_admin/bootstrap/_grid.scss +74 -11
  33. data/app/assets/stylesheets/rails_admin/bootstrap/_input-groups.scss +166 -0
  34. data/app/assets/stylesheets/rails_admin/bootstrap/_jumbotron.scss +48 -0
  35. data/app/assets/stylesheets/rails_admin/bootstrap/_labels.scss +66 -0
  36. data/app/assets/stylesheets/rails_admin/bootstrap/_list-group.scss +131 -0
  37. data/app/assets/stylesheets/rails_admin/bootstrap/_media.scss +8 -7
  38. data/app/assets/stylesheets/rails_admin/bootstrap/_mixins.scss +36 -693
  39. data/app/assets/stylesheets/rails_admin/bootstrap/_modals.scss +108 -53
  40. data/app/assets/stylesheets/rails_admin/bootstrap/_navbar.scss +545 -383
  41. data/app/assets/stylesheets/rails_admin/bootstrap/_navs.scss +191 -358
  42. data/app/assets/stylesheets/rails_admin/bootstrap/_normalize.scss +425 -0
  43. data/app/assets/stylesheets/rails_admin/bootstrap/_pager.scss +45 -33
  44. data/app/assets/stylesheets/rails_admin/bootstrap/_pagination.scss +70 -105
  45. data/app/assets/stylesheets/rails_admin/bootstrap/_panels.scss +243 -0
  46. data/app/assets/stylesheets/rails_admin/bootstrap/_popovers.scss +61 -61
  47. data/app/assets/stylesheets/rails_admin/bootstrap/_print.scss +101 -0
  48. data/app/assets/stylesheets/rails_admin/bootstrap/_progress-bars.scss +56 -73
  49. data/app/assets/stylesheets/rails_admin/bootstrap/_responsive-embed.scss +34 -0
  50. data/app/assets/stylesheets/rails_admin/bootstrap/_responsive-utilities.scss +150 -50
  51. data/app/assets/stylesheets/rails_admin/bootstrap/_scaffolding.scss +120 -23
  52. data/app/assets/stylesheets/rails_admin/bootstrap/_tables.scss +168 -170
  53. data/app/assets/stylesheets/rails_admin/bootstrap/_theme.scss +258 -0
  54. data/app/assets/stylesheets/rails_admin/bootstrap/_thumbnails.scss +27 -42
  55. data/app/assets/stylesheets/rails_admin/bootstrap/_tooltip.scss +49 -24
  56. data/app/assets/stylesheets/rails_admin/bootstrap/_type.scss +200 -143
  57. data/app/assets/stylesheets/rails_admin/bootstrap/_utilities.scss +33 -21
  58. data/app/assets/stylesheets/rails_admin/bootstrap/_variables.scss +764 -215
  59. data/app/assets/stylesheets/rails_admin/bootstrap/_wells.scss +7 -7
  60. data/app/assets/stylesheets/rails_admin/bootstrap/bootstrap.scss +47 -60
  61. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_alerts.scss +14 -0
  62. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_background-variant.scss +11 -0
  63. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_border-radius.scss +18 -0
  64. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_buttons.scss +50 -0
  65. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_center-block.scss +7 -0
  66. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_clearfix.scss +22 -0
  67. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_forms.scss +84 -0
  68. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_gradients.scss +58 -0
  69. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_grid-framework.scss +81 -0
  70. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_grid.scss +122 -0
  71. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_hide-text.scss +21 -0
  72. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_image.scss +34 -0
  73. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_labels.scss +12 -0
  74. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_list-group.scss +31 -0
  75. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_nav-divider.scss +10 -0
  76. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_nav-vertical-align.scss +9 -0
  77. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_opacity.scss +8 -0
  78. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_pagination.scss +23 -0
  79. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_panels.scss +24 -0
  80. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_progress-bar.scss +10 -0
  81. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_reset-filter.scss +8 -0
  82. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_resize.scss +6 -0
  83. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_responsive-visibility.scss +21 -0
  84. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_size.scss +10 -0
  85. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_tab-focus.scss +9 -0
  86. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_table-row.scss +28 -0
  87. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_text-emphasis.scss +11 -0
  88. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_text-overflow.scss +8 -0
  89. data/app/assets/stylesheets/rails_admin/bootstrap/mixins/_vendor-prefixes.scss +219 -0
  90. data/app/assets/stylesheets/rails_admin/ra.calendar-additions.scss +17 -0
  91. data/app/assets/stylesheets/rails_admin/rails_admin.scss.erb +9 -5
  92. data/app/helpers/rails_admin/application_helper.rb +20 -19
  93. data/app/helpers/rails_admin/form_builder.rb +14 -11
  94. data/app/views/kaminari/twitter-bootstrap/_paginator.html.haml +8 -9
  95. data/app/views/layouts/rails_admin/_navigation.html.haml +5 -5
  96. data/app/views/layouts/rails_admin/_secondary_navigation.html.haml +1 -1
  97. data/app/views/layouts/rails_admin/application.html.haml +9 -8
  98. data/app/views/layouts/rails_admin/pjax.html.haml +4 -3
  99. data/app/views/rails_admin/main/_form_datetime.html.haml +2 -1
  100. data/app/views/rails_admin/main/_form_field.html.haml +1 -1
  101. data/app/views/rails_admin/main/_form_text.html.haml +1 -1
  102. data/app/views/rails_admin/main/_submit_buttons.html.haml +1 -0
  103. data/app/views/rails_admin/main/dashboard.html.haml +1 -1
  104. data/app/views/rails_admin/main/export.html.haml +19 -16
  105. data/app/views/rails_admin/main/index.html.haml +11 -7
  106. data/app/views/rails_admin/main/show.html.haml +1 -1
  107. data/lib/rails_admin/adapters/active_record.rb +2 -2
  108. data/lib/rails_admin/adapters/mongoid/property.rb +1 -1
  109. data/lib/rails_admin/config/actions/bulk_delete.rb +0 -1
  110. data/lib/rails_admin/config/actions/edit.rb +0 -2
  111. data/lib/rails_admin/config/actions/export.rb +0 -2
  112. data/lib/rails_admin/config/actions/index.rb +0 -3
  113. data/lib/rails_admin/config/actions/new.rb +0 -2
  114. data/lib/rails_admin/config/configurable.rb +1 -1
  115. data/lib/rails_admin/config/fields/base.rb +9 -0
  116. data/lib/rails_admin/config/fields/factories/enum.rb +2 -3
  117. data/lib/rails_admin/config/fields/types/polymorphic_association.rb +4 -0
  118. data/lib/rails_admin/config/model.rb +2 -1
  119. data/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb +2 -2
  120. data/lib/rails_admin/support/csv_converter.rb +22 -42
  121. data/lib/rails_admin/version.rb +1 -1
  122. metadata +59 -18
  123. data/app/assets/stylesheets/rails_admin/bootstrap/_accordion.scss +0 -34
  124. data/app/assets/stylesheets/rails_admin/bootstrap/_hero-unit.scss +0 -25
  125. data/app/assets/stylesheets/rails_admin/bootstrap/_labels-badges.scss +0 -83
  126. data/app/assets/stylesheets/rails_admin/bootstrap/_layouts.scss +0 -16
  127. data/app/assets/stylesheets/rails_admin/bootstrap/_reset.scss +0 -216
  128. data/app/assets/stylesheets/rails_admin/bootstrap/_responsive-1200px-min.scss +0 -28
  129. data/app/assets/stylesheets/rails_admin/bootstrap/_responsive-767px-max.scss +0 -193
  130. data/app/assets/stylesheets/rails_admin/bootstrap/_responsive-768px-979px.scss +0 -19
  131. data/app/assets/stylesheets/rails_admin/bootstrap/_responsive-navbar.scss +0 -189
  132. data/app/assets/stylesheets/rails_admin/bootstrap/_sprites.scss +0 -197
  133. data/app/assets/stylesheets/rails_admin/bootstrap/responsive.scss +0 -48
@@ -1,131 +1,115 @@
1
- /* ========================================================
2
- * bootstrap-tab.js v2.3.2
3
- * http://getbootstrap.com/2.3.2/javascript.html#tabs
4
- * ========================================================
5
- * Copyright 2012 Twitter, Inc.
6
- *
7
- * Licensed under the Apache License, Version 2.0 (the "License");
8
- * you may not use this file except in compliance with the License.
9
- * You may obtain a copy of the License at
10
- *
11
- * http://www.apache.org/licenses/LICENSE-2.0
12
- *
13
- * Unless required by applicable law or agreed to in writing, software
14
- * distributed under the License is distributed on an "AS IS" BASIS,
15
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- * See the License for the specific language governing permissions and
17
- * limitations under the License.
18
- * ======================================================== */
19
-
20
-
21
- !function ($) {
22
-
23
- "use strict"; // jshint ;_;
24
-
25
-
26
- /* TAB CLASS DEFINITION
27
- * ==================== */
1
+ /* ========================================================================
2
+ * Bootstrap: tab.js v3.2.0
3
+ * http://getbootstrap.com/javascript/#tabs
4
+ * ========================================================================
5
+ * Copyright 2011-2014 Twitter, Inc.
6
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7
+ * ======================================================================== */
8
+
9
+
10
+ +function ($) {
11
+ 'use strict';
12
+
13
+ // TAB CLASS DEFINITION
14
+ // ====================
28
15
 
29
16
  var Tab = function (element) {
30
17
  this.element = $(element)
31
18
  }
32
19
 
33
- Tab.prototype = {
34
-
35
- constructor: Tab
20
+ Tab.VERSION = '3.2.0'
36
21
 
37
- , show: function () {
38
- var $this = this.element
39
- , $ul = $this.closest('ul:not(.dropdown-menu)')
40
- , selector = $this.attr('data-target')
41
- , previous
42
- , $target
43
- , e
22
+ Tab.prototype.show = function () {
23
+ var $this = this.element
24
+ var $ul = $this.closest('ul:not(.dropdown-menu)')
25
+ var selector = $this.data('target')
44
26
 
45
- if (!selector) {
46
- selector = $this.attr('href')
47
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
48
- }
49
-
50
- if ( $this.parent('li').hasClass('active') ) return
27
+ if (!selector) {
28
+ selector = $this.attr('href')
29
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
30
+ }
51
31
 
52
- previous = $ul.find('.active:last a')[0]
32
+ if ($this.parent('li').hasClass('active')) return
53
33
 
54
- e = $.Event('show', {
55
- relatedTarget: previous
56
- })
34
+ var previous = $ul.find('.active:last a')[0]
35
+ var e = $.Event('show.bs.tab', {
36
+ relatedTarget: previous
37
+ })
57
38
 
58
- $this.trigger(e)
39
+ $this.trigger(e)
59
40
 
60
- if (e.isDefaultPrevented()) return
41
+ if (e.isDefaultPrevented()) return
61
42
 
62
- $target = $(selector)
43
+ var $target = $(selector)
63
44
 
64
- this.activate($this.parent('li'), $ul)
65
- this.activate($target, $target.parent(), function () {
66
- $this.trigger({
67
- type: 'shown'
68
- , relatedTarget: previous
69
- })
45
+ this.activate($this.closest('li'), $ul)
46
+ this.activate($target, $target.parent(), function () {
47
+ $this.trigger({
48
+ type: 'shown.bs.tab',
49
+ relatedTarget: previous
70
50
  })
71
- }
72
-
73
- , activate: function ( element, container, callback) {
74
- var $active = container.find('> .active')
75
- , transition = callback
76
- && $.support.transition
77
- && $active.hasClass('fade')
78
-
79
- function next() {
80
- $active
81
- .removeClass('active')
82
- .find('> .dropdown-menu > .active')
83
- .removeClass('active')
84
-
85
- element.addClass('active')
86
-
87
- if (transition) {
88
- element[0].offsetWidth // reflow for transition
89
- element.addClass('in')
90
- } else {
91
- element.removeClass('fade')
92
- }
93
-
94
- if ( element.parent('.dropdown-menu') ) {
95
- element.closest('li.dropdown').addClass('active')
96
- }
51
+ })
52
+ }
97
53
 
98
- callback && callback()
54
+ Tab.prototype.activate = function (element, container, callback) {
55
+ var $active = container.find('> .active')
56
+ var transition = callback
57
+ && $.support.transition
58
+ && $active.hasClass('fade')
59
+
60
+ function next() {
61
+ $active
62
+ .removeClass('active')
63
+ .find('> .dropdown-menu > .active')
64
+ .removeClass('active')
65
+
66
+ element.addClass('active')
67
+
68
+ if (transition) {
69
+ element[0].offsetWidth // reflow for transition
70
+ element.addClass('in')
71
+ } else {
72
+ element.removeClass('fade')
99
73
  }
100
74
 
101
- transition ?
102
- $active.one($.support.transition.end, next) :
103
- next()
75
+ if (element.parent('.dropdown-menu')) {
76
+ element.closest('li.dropdown').addClass('active')
77
+ }
104
78
 
105
- $active.removeClass('in')
79
+ callback && callback()
106
80
  }
107
- }
108
81
 
82
+ transition ?
83
+ $active
84
+ .one('bsTransitionEnd', next)
85
+ .emulateTransitionEnd(150) :
86
+ next()
109
87
 
110
- /* TAB PLUGIN DEFINITION
111
- * ===================== */
88
+ $active.removeClass('in')
89
+ }
112
90
 
113
- var old = $.fn.tab
114
91
 
115
- $.fn.tab = function ( option ) {
92
+ // TAB PLUGIN DEFINITION
93
+ // =====================
94
+
95
+ function Plugin(option) {
116
96
  return this.each(function () {
117
97
  var $this = $(this)
118
- , data = $this.data('tab')
119
- if (!data) $this.data('tab', (data = new Tab(this)))
98
+ var data = $this.data('bs.tab')
99
+
100
+ if (!data) $this.data('bs.tab', (data = new Tab(this)))
120
101
  if (typeof option == 'string') data[option]()
121
102
  })
122
103
  }
123
104
 
105
+ var old = $.fn.tab
106
+
107
+ $.fn.tab = Plugin
124
108
  $.fn.tab.Constructor = Tab
125
109
 
126
110
 
127
- /* TAB NO CONFLICT
128
- * =============== */
111
+ // TAB NO CONFLICT
112
+ // ===============
129
113
 
130
114
  $.fn.tab.noConflict = function () {
131
115
  $.fn.tab = old
@@ -133,12 +117,12 @@
133
117
  }
134
118
 
135
119
 
136
- /* TAB DATA-API
137
- * ============ */
120
+ // TAB DATA-API
121
+ // ============
138
122
 
139
- $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
123
+ $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
140
124
  e.preventDefault()
141
- $(this).tab('show')
125
+ Plugin.call($(this), 'show')
142
126
  })
143
127
 
144
- }(window.jQuery);
128
+ }(jQuery);
@@ -1,361 +1,457 @@
1
- /* ===========================================================
2
- * bootstrap-tooltip.js v2.3.2
3
- * http://getbootstrap.com/2.3.2/javascript.html#tooltips
1
+ /* ========================================================================
2
+ * Bootstrap: tooltip.js v3.2.0
3
+ * http://getbootstrap.com/javascript/#tooltip
4
4
  * Inspired by the original jQuery.tipsy by Jason Frame
5
- * ===========================================================
6
- * Copyright 2012 Twitter, Inc.
7
- *
8
- * Licensed under the Apache License, Version 2.0 (the "License");
9
- * you may not use this file except in compliance with the License.
10
- * You may obtain a copy of the License at
11
- *
12
- * http://www.apache.org/licenses/LICENSE-2.0
13
- *
14
- * Unless required by applicable law or agreed to in writing, software
15
- * distributed under the License is distributed on an "AS IS" BASIS,
16
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
- * See the License for the specific language governing permissions and
18
- * limitations under the License.
19
- * ========================================================== */
5
+ * ========================================================================
6
+ * Copyright 2011-2014 Twitter, Inc.
7
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
8
+ * ======================================================================== */
20
9
 
21
10
 
22
- !function ($) {
11
+ +function ($) {
12
+ 'use strict';
23
13
 
24
- "use strict"; // jshint ;_;
25
-
26
-
27
- /* TOOLTIP PUBLIC CLASS DEFINITION
28
- * =============================== */
14
+ // TOOLTIP PUBLIC CLASS DEFINITION
15
+ // ===============================
29
16
 
30
17
  var Tooltip = function (element, options) {
18
+ this.type =
19
+ this.options =
20
+ this.enabled =
21
+ this.timeout =
22
+ this.hoverState =
23
+ this.$element = null
24
+
31
25
  this.init('tooltip', element, options)
32
26
  }
33
27
 
34
- Tooltip.prototype = {
35
-
36
- constructor: Tooltip
37
-
38
- , init: function (type, element, options) {
39
- var eventIn
40
- , eventOut
41
- , triggers
42
- , trigger
43
- , i
44
-
45
- this.type = type
46
- this.$element = $(element)
47
- this.options = this.getOptions(options)
48
- this.enabled = true
49
-
50
- triggers = this.options.trigger.split(' ')
51
-
52
- for (i = triggers.length; i--;) {
53
- trigger = triggers[i]
54
- if (trigger == 'click') {
55
- this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
56
- } else if (trigger != 'manual') {
57
- eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
58
- eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
59
- this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
60
- this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
61
- }
62
- }
63
-
64
- this.options.selector ?
65
- (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
66
- this.fixTitle()
28
+ Tooltip.VERSION = '3.2.0'
29
+
30
+ Tooltip.DEFAULTS = {
31
+ animation: true,
32
+ placement: 'top',
33
+ selector: false,
34
+ template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
35
+ trigger: 'hover focus',
36
+ title: '',
37
+ delay: 0,
38
+ html: false,
39
+ container: false,
40
+ viewport: {
41
+ selector: 'body',
42
+ padding: 0
67
43
  }
44
+ }
45
+
46
+ Tooltip.prototype.init = function (type, element, options) {
47
+ this.enabled = true
48
+ this.type = type
49
+ this.$element = $(element)
50
+ this.options = this.getOptions(options)
51
+ this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
68
52
 
69
- , getOptions: function (options) {
70
- options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)
53
+ var triggers = this.options.trigger.split(' ')
71
54
 
72
- if (options.delay && typeof options.delay == 'number') {
73
- options.delay = {
74
- show: options.delay
75
- , hide: options.delay
76
- }
55
+ for (var i = triggers.length; i--;) {
56
+ var trigger = triggers[i]
57
+
58
+ if (trigger == 'click') {
59
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
60
+ } else if (trigger != 'manual') {
61
+ var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
62
+ var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
63
+
64
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
65
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
77
66
  }
67
+ }
68
+
69
+ this.options.selector ?
70
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
71
+ this.fixTitle()
72
+ }
73
+
74
+ Tooltip.prototype.getDefaults = function () {
75
+ return Tooltip.DEFAULTS
76
+ }
78
77
 
79
- return options
78
+ Tooltip.prototype.getOptions = function (options) {
79
+ options = $.extend({}, this.getDefaults(), this.$element.data(), options)
80
+
81
+ if (options.delay && typeof options.delay == 'number') {
82
+ options.delay = {
83
+ show: options.delay,
84
+ hide: options.delay
85
+ }
80
86
  }
81
87
 
82
- , enter: function (e) {
83
- var defaults = $.fn[this.type].defaults
84
- , options = {}
85
- , self
88
+ return options
89
+ }
86
90
 
87
- this._options && $.each(this._options, function (key, value) {
88
- if (defaults[key] != value) options[key] = value
89
- }, this)
91
+ Tooltip.prototype.getDelegateOptions = function () {
92
+ var options = {}
93
+ var defaults = this.getDefaults()
90
94
 
91
- self = $(e.currentTarget)[this.type](options).data(this.type)
95
+ this._options && $.each(this._options, function (key, value) {
96
+ if (defaults[key] != value) options[key] = value
97
+ })
92
98
 
93
- if (!self.options.delay || !self.options.delay.show) return self.show()
99
+ return options
100
+ }
101
+
102
+ Tooltip.prototype.enter = function (obj) {
103
+ var self = obj instanceof this.constructor ?
104
+ obj : $(obj.currentTarget).data('bs.' + this.type)
94
105
 
95
- clearTimeout(this.timeout)
96
- self.hoverState = 'in'
97
- this.timeout = setTimeout(function() {
98
- if (self.hoverState == 'in') self.show()
99
- }, self.options.delay.show)
106
+ if (!self) {
107
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
108
+ $(obj.currentTarget).data('bs.' + this.type, self)
100
109
  }
101
110
 
102
- , leave: function (e) {
103
- var self = $(e.currentTarget)[this.type](this._options).data(this.type)
111
+ clearTimeout(self.timeout)
104
112
 
105
- if (this.timeout) clearTimeout(this.timeout)
106
- if (!self.options.delay || !self.options.delay.hide) return self.hide()
113
+ self.hoverState = 'in'
107
114
 
108
- self.hoverState = 'out'
109
- this.timeout = setTimeout(function() {
110
- if (self.hoverState == 'out') self.hide()
111
- }, self.options.delay.hide)
112
- }
115
+ if (!self.options.delay || !self.options.delay.show) return self.show()
113
116
 
114
- , show: function () {
115
- var $tip
116
- , pos
117
- , actualWidth
118
- , actualHeight
119
- , placement
120
- , tp
121
- , e = $.Event('show')
122
-
123
- if (this.hasContent() && this.enabled) {
124
- this.$element.trigger(e)
125
- if (e.isDefaultPrevented()) return
126
- $tip = this.tip()
127
- this.setContent()
128
-
129
- if (this.options.animation) {
130
- $tip.addClass('fade')
131
- }
132
-
133
- placement = typeof this.options.placement == 'function' ?
134
- this.options.placement.call(this, $tip[0], this.$element[0]) :
135
- this.options.placement
117
+ self.timeout = setTimeout(function () {
118
+ if (self.hoverState == 'in') self.show()
119
+ }, self.options.delay.show)
120
+ }
136
121
 
137
- $tip
138
- .detach()
139
- .css({ top: 0, left: 0, display: 'block' })
140
-
141
- this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
142
-
143
- pos = this.getPosition()
144
-
145
- actualWidth = $tip[0].offsetWidth
146
- actualHeight = $tip[0].offsetHeight
147
-
148
- switch (placement) {
149
- case 'bottom':
150
- tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
151
- break
152
- case 'top':
153
- tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
154
- break
155
- case 'left':
156
- tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
157
- break
158
- case 'right':
159
- tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
160
- break
161
- }
162
-
163
- this.applyPlacement(tp, placement)
164
- this.$element.trigger('shown')
165
- }
122
+ Tooltip.prototype.leave = function (obj) {
123
+ var self = obj instanceof this.constructor ?
124
+ obj : $(obj.currentTarget).data('bs.' + this.type)
125
+
126
+ if (!self) {
127
+ self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
128
+ $(obj.currentTarget).data('bs.' + this.type, self)
166
129
  }
167
130
 
168
- , applyPlacement: function(offset, placement){
131
+ clearTimeout(self.timeout)
132
+
133
+ self.hoverState = 'out'
134
+
135
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
136
+
137
+ self.timeout = setTimeout(function () {
138
+ if (self.hoverState == 'out') self.hide()
139
+ }, self.options.delay.hide)
140
+ }
141
+
142
+ Tooltip.prototype.show = function () {
143
+ var e = $.Event('show.bs.' + this.type)
144
+
145
+ if (this.hasContent() && this.enabled) {
146
+ this.$element.trigger(e)
147
+
148
+ var inDom = $.contains(document.documentElement, this.$element[0])
149
+ if (e.isDefaultPrevented() || !inDom) return
150
+ var that = this
151
+
169
152
  var $tip = this.tip()
170
- , width = $tip[0].offsetWidth
171
- , height = $tip[0].offsetHeight
172
- , actualWidth
173
- , actualHeight
174
- , delta
175
- , replace
153
+
154
+ var tipId = this.getUID(this.type)
155
+
156
+ this.setContent()
157
+ $tip.attr('id', tipId)
158
+ this.$element.attr('aria-describedby', tipId)
159
+
160
+ if (this.options.animation) $tip.addClass('fade')
161
+
162
+ var placement = typeof this.options.placement == 'function' ?
163
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
164
+ this.options.placement
165
+
166
+ var autoToken = /\s?auto?\s?/i
167
+ var autoPlace = autoToken.test(placement)
168
+ if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
176
169
 
177
170
  $tip
178
- .offset(offset)
171
+ .detach()
172
+ .css({ top: 0, left: 0, display: 'block' })
179
173
  .addClass(placement)
180
- .addClass('in')
174
+ .data('bs.' + this.type, this)
175
+
176
+ this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
181
177
 
182
- actualWidth = $tip[0].offsetWidth
183
- actualHeight = $tip[0].offsetHeight
178
+ var pos = this.getPosition()
179
+ var actualWidth = $tip[0].offsetWidth
180
+ var actualHeight = $tip[0].offsetHeight
184
181
 
185
- if (placement == 'top' && actualHeight != height) {
186
- offset.top = offset.top + height - actualHeight
187
- replace = true
182
+ if (autoPlace) {
183
+ var orgPlacement = placement
184
+ var $parent = this.$element.parent()
185
+ var parentDim = this.getPosition($parent)
186
+
187
+ placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' :
188
+ placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' :
189
+ placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' :
190
+ placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' :
191
+ placement
192
+
193
+ $tip
194
+ .removeClass(orgPlacement)
195
+ .addClass(placement)
188
196
  }
189
197
 
190
- if (placement == 'bottom' || placement == 'top') {
191
- delta = 0
198
+ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
192
199
 
193
- if (offset.left < 0){
194
- delta = offset.left * -2
195
- offset.left = 0
196
- $tip.offset(offset)
197
- actualWidth = $tip[0].offsetWidth
198
- actualHeight = $tip[0].offsetHeight
199
- }
200
+ this.applyPlacement(calculatedOffset, placement)
200
201
 
201
- this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
202
- } else {
203
- this.replaceArrow(actualHeight - height, actualHeight, 'top')
202
+ var complete = function () {
203
+ that.$element.trigger('shown.bs.' + that.type)
204
+ that.hoverState = null
204
205
  }
205
206
 
206
- if (replace) $tip.offset(offset)
207
+ $.support.transition && this.$tip.hasClass('fade') ?
208
+ $tip
209
+ .one('bsTransitionEnd', complete)
210
+ .emulateTransitionEnd(150) :
211
+ complete()
207
212
  }
213
+ }
208
214
 
209
- , replaceArrow: function(delta, dimension, position){
210
- this
211
- .arrow()
212
- .css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
213
- }
215
+ Tooltip.prototype.applyPlacement = function (offset, placement) {
216
+ var $tip = this.tip()
217
+ var width = $tip[0].offsetWidth
218
+ var height = $tip[0].offsetHeight
219
+
220
+ // manually read margins because getBoundingClientRect includes difference
221
+ var marginTop = parseInt($tip.css('margin-top'), 10)
222
+ var marginLeft = parseInt($tip.css('margin-left'), 10)
223
+
224
+ // we must check for NaN for ie 8/9
225
+ if (isNaN(marginTop)) marginTop = 0
226
+ if (isNaN(marginLeft)) marginLeft = 0
227
+
228
+ offset.top = offset.top + marginTop
229
+ offset.left = offset.left + marginLeft
230
+
231
+ // $.fn.offset doesn't round pixel values
232
+ // so we use setOffset directly with our own function B-0
233
+ $.offset.setOffset($tip[0], $.extend({
234
+ using: function (props) {
235
+ $tip.css({
236
+ top: Math.round(props.top),
237
+ left: Math.round(props.left)
238
+ })
239
+ }
240
+ }, offset), 0)
214
241
 
215
- , setContent: function () {
216
- var $tip = this.tip()
217
- , title = this.getTitle()
242
+ $tip.addClass('in')
218
243
 
219
- $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
220
- $tip.removeClass('fade in top bottom left right')
244
+ // check to see if placing tip in new offset caused the tip to resize itself
245
+ var actualWidth = $tip[0].offsetWidth
246
+ var actualHeight = $tip[0].offsetHeight
247
+
248
+ if (placement == 'top' && actualHeight != height) {
249
+ offset.top = offset.top + height - actualHeight
221
250
  }
222
251
 
223
- , hide: function () {
224
- var that = this
225
- , $tip = this.tip()
226
- , e = $.Event('hide')
252
+ var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
227
253
 
228
- this.$element.trigger(e)
229
- if (e.isDefaultPrevented()) return
254
+ if (delta.left) offset.left += delta.left
255
+ else offset.top += delta.top
230
256
 
231
- $tip.removeClass('in')
257
+ var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
258
+ var arrowPosition = delta.left ? 'left' : 'top'
259
+ var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
232
260
 
233
- function removeWithAnimation() {
234
- var timeout = setTimeout(function () {
235
- $tip.off($.support.transition.end).detach()
236
- }, 500)
261
+ $tip.offset(offset)
262
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
263
+ }
237
264
 
238
- $tip.one($.support.transition.end, function () {
239
- clearTimeout(timeout)
240
- $tip.detach()
241
- })
242
- }
265
+ Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
266
+ this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
267
+ }
243
268
 
244
- $.support.transition && this.$tip.hasClass('fade') ?
245
- removeWithAnimation() :
246
- $tip.detach()
269
+ Tooltip.prototype.setContent = function () {
270
+ var $tip = this.tip()
271
+ var title = this.getTitle()
247
272
 
248
- this.$element.trigger('hidden')
273
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
274
+ $tip.removeClass('fade in top bottom left right')
275
+ }
249
276
 
250
- return this
251
- }
277
+ Tooltip.prototype.hide = function () {
278
+ var that = this
279
+ var $tip = this.tip()
280
+ var e = $.Event('hide.bs.' + this.type)
252
281
 
253
- , fixTitle: function () {
254
- var $e = this.$element
255
- if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
256
- $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
257
- }
258
- }
282
+ this.$element.removeAttr('aria-describedby')
259
283
 
260
- , hasContent: function () {
261
- return this.getTitle()
284
+ function complete() {
285
+ if (that.hoverState != 'in') $tip.detach()
286
+ that.$element.trigger('hidden.bs.' + that.type)
262
287
  }
263
288
 
264
- , getPosition: function () {
265
- var el = this.$element[0]
266
- return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
267
- width: el.offsetWidth
268
- , height: el.offsetHeight
269
- }, this.$element.offset())
270
- }
289
+ this.$element.trigger(e)
271
290
 
272
- , getTitle: function () {
273
- var title
274
- , $e = this.$element
275
- , o = this.options
291
+ if (e.isDefaultPrevented()) return
276
292
 
277
- title = $e.attr('data-original-title')
278
- || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
293
+ $tip.removeClass('in')
279
294
 
280
- return title
281
- }
295
+ $.support.transition && this.$tip.hasClass('fade') ?
296
+ $tip
297
+ .one('bsTransitionEnd', complete)
298
+ .emulateTransitionEnd(150) :
299
+ complete()
282
300
 
283
- , tip: function () {
284
- return this.$tip = this.$tip || $(this.options.template)
285
- }
301
+ this.hoverState = null
286
302
 
287
- , arrow: function(){
288
- return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
303
+ return this
304
+ }
305
+
306
+ Tooltip.prototype.fixTitle = function () {
307
+ var $e = this.$element
308
+ if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
309
+ $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
289
310
  }
311
+ }
312
+
313
+ Tooltip.prototype.hasContent = function () {
314
+ return this.getTitle()
315
+ }
316
+
317
+ Tooltip.prototype.getPosition = function ($element) {
318
+ $element = $element || this.$element
319
+ var el = $element[0]
320
+ var isBody = el.tagName == 'BODY'
321
+ return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
322
+ scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
323
+ width: isBody ? $(window).width() : $element.outerWidth(),
324
+ height: isBody ? $(window).height() : $element.outerHeight()
325
+ }, isBody ? { top: 0, left: 0 } : $element.offset())
326
+ }
290
327
 
291
- , validate: function () {
292
- if (!this.$element[0].parentNode) {
293
- this.hide()
294
- this.$element = null
295
- this.options = null
328
+ Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
329
+ return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
330
+ placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
331
+ placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
332
+ /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
333
+
334
+ }
335
+
336
+ Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
337
+ var delta = { top: 0, left: 0 }
338
+ if (!this.$viewport) return delta
339
+
340
+ var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
341
+ var viewportDimensions = this.getPosition(this.$viewport)
342
+
343
+ if (/right|left/.test(placement)) {
344
+ var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
345
+ var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
346
+ if (topEdgeOffset < viewportDimensions.top) { // top overflow
347
+ delta.top = viewportDimensions.top - topEdgeOffset
348
+ } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
349
+ delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
350
+ }
351
+ } else {
352
+ var leftEdgeOffset = pos.left - viewportPadding
353
+ var rightEdgeOffset = pos.left + viewportPadding + actualWidth
354
+ if (leftEdgeOffset < viewportDimensions.left) { // left overflow
355
+ delta.left = viewportDimensions.left - leftEdgeOffset
356
+ } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
357
+ delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
296
358
  }
297
359
  }
298
360
 
299
- , enable: function () {
300
- this.enabled = true
301
- }
361
+ return delta
362
+ }
302
363
 
303
- , disable: function () {
304
- this.enabled = false
305
- }
364
+ Tooltip.prototype.getTitle = function () {
365
+ var title
366
+ var $e = this.$element
367
+ var o = this.options
306
368
 
307
- , toggleEnabled: function () {
308
- this.enabled = !this.enabled
309
- }
369
+ title = $e.attr('data-original-title')
370
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
371
+
372
+ return title
373
+ }
374
+
375
+ Tooltip.prototype.getUID = function (prefix) {
376
+ do prefix += ~~(Math.random() * 1000000)
377
+ while (document.getElementById(prefix))
378
+ return prefix
379
+ }
380
+
381
+ Tooltip.prototype.tip = function () {
382
+ return (this.$tip = this.$tip || $(this.options.template))
383
+ }
310
384
 
311
- , toggle: function (e) {
312
- var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this
313
- self.tip().hasClass('in') ? self.hide() : self.show()
385
+ Tooltip.prototype.arrow = function () {
386
+ return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
387
+ }
388
+
389
+ Tooltip.prototype.validate = function () {
390
+ if (!this.$element[0].parentNode) {
391
+ this.hide()
392
+ this.$element = null
393
+ this.options = null
314
394
  }
395
+ }
315
396
 
316
- , destroy: function () {
317
- this.hide().$element.off('.' + this.type).removeData(this.type)
397
+ Tooltip.prototype.enable = function () {
398
+ this.enabled = true
399
+ }
400
+
401
+ Tooltip.prototype.disable = function () {
402
+ this.enabled = false
403
+ }
404
+
405
+ Tooltip.prototype.toggleEnabled = function () {
406
+ this.enabled = !this.enabled
407
+ }
408
+
409
+ Tooltip.prototype.toggle = function (e) {
410
+ var self = this
411
+ if (e) {
412
+ self = $(e.currentTarget).data('bs.' + this.type)
413
+ if (!self) {
414
+ self = new this.constructor(e.currentTarget, this.getDelegateOptions())
415
+ $(e.currentTarget).data('bs.' + this.type, self)
416
+ }
318
417
  }
319
418
 
419
+ self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
320
420
  }
321
421
 
422
+ Tooltip.prototype.destroy = function () {
423
+ clearTimeout(this.timeout)
424
+ this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
425
+ }
322
426
 
323
- /* TOOLTIP PLUGIN DEFINITION
324
- * ========================= */
325
427
 
326
- var old = $.fn.tooltip
428
+ // TOOLTIP PLUGIN DEFINITION
429
+ // =========================
327
430
 
328
- $.fn.tooltip = function ( option ) {
431
+ function Plugin(option) {
329
432
  return this.each(function () {
330
- var $this = $(this)
331
- , data = $this.data('tooltip')
332
- , options = typeof option == 'object' && option
333
- if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
433
+ var $this = $(this)
434
+ var data = $this.data('bs.tooltip')
435
+ var options = typeof option == 'object' && option
436
+
437
+ if (!data && option == 'destroy') return
438
+ if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
334
439
  if (typeof option == 'string') data[option]()
335
440
  })
336
441
  }
337
442
 
338
- $.fn.tooltip.Constructor = Tooltip
443
+ var old = $.fn.tooltip
339
444
 
340
- $.fn.tooltip.defaults = {
341
- animation: true
342
- , placement: 'top'
343
- , selector: false
344
- , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
345
- , trigger: 'hover focus'
346
- , title: ''
347
- , delay: 0
348
- , html: false
349
- , container: false
350
- }
445
+ $.fn.tooltip = Plugin
446
+ $.fn.tooltip.Constructor = Tooltip
351
447
 
352
448
 
353
- /* TOOLTIP NO CONFLICT
354
- * =================== */
449
+ // TOOLTIP NO CONFLICT
450
+ // ===================
355
451
 
356
452
  $.fn.tooltip.noConflict = function () {
357
453
  $.fn.tooltip = old
358
454
  return this
359
455
  }
360
456
 
361
- }(window.jQuery);
457
+ }(jQuery);