bootstrap_modal_rails 2.0.4 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
- Bootstrap Modal v2.0
2
- =============
1
+ # Bootstrap Modal v2.1
2
+ [![Gem Version](https://badge.fury.io/rb/bootstrap_modal_rails.png)](http://badge.fury.io/rb/bootstrap_modal_rails)
3
3
 
4
4
  See live demo [here](http://jschr.github.com/bootstrap-modal/).
5
5
 
@@ -27,7 +27,7 @@ Installation
27
27
 
28
28
  Add this line to your application's Gemfile:
29
29
 
30
- gem 'bootstrap_modal_rails', '~> 2.0.0'
30
+ gem 'bootstrap_modal_rails', '~> 2.1.0'
31
31
 
32
32
  And then execute:
33
33
 
@@ -1,3 +1,3 @@
1
1
  module BootstrapModalRails
2
- VERSION = "2.0.4"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -1,3 +1,2 @@
1
1
  //= require ./bootstrap-modalmanager.js
2
2
  //= require ./bootstrap-modal.js
3
- //= require ./dynamic-modal.js
@@ -1,5 +1,5 @@
1
1
  /* ===========================================================
2
- * bootstrap-modal.js v2.0
2
+ * bootstrap-modal.js v2.1
3
3
  * ===========================================================
4
4
  * Copyright 2012 Jordan Schroter
5
5
  *
@@ -19,337 +19,356 @@
19
19
 
20
20
  !function ($) {
21
21
 
22
- "use strict"; // jshint ;_;
23
-
24
- /* MODAL CLASS DEFINITION
25
- * ====================== */
22
+ "use strict"; // jshint ;_;
26
23
 
27
- var Modal = function (element, options) {
28
- this.init(element, options);
29
- }
24
+ /* MODAL CLASS DEFINITION
25
+ * ====================== */
30
26
 
31
- Modal.prototype = {
32
-
33
- constructor: Modal,
34
-
35
- init: function (element, options) {
36
- this.options = options;
37
-
38
- this.$element = $(element)
39
- .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this));
40
-
41
- this.options.remote && this.$element.find('.modal-body').load(this.options.remote);
42
-
43
- var manager = typeof this.options.manager === 'function' ?
44
- this.options.manager.call(this) : this.options.manager;
45
-
46
- manager = manager.appendModal ?
47
- manager : $(manager).modalmanager().data('modalmanager');
48
-
49
- manager.appendModal(this);
50
- },
51
-
52
- toggle: function () {
53
- return this[!this.isShown ? 'show' : 'hide']();
54
- },
55
-
56
- show: function () {
57
- var that = this,
58
- e = $.Event('show');
59
-
60
- if (this.isShown) return;
61
-
62
- this.$element.triggerHandler(e);
63
-
64
- if (e.isDefaultPrevented()) return;
65
-
66
- if (this.options.width){
67
- this.$element.css('width', this.options.width);
68
-
69
- var that = this;
70
- this.$element.css('margin-left', function () {
71
- if (/%/ig.test(that.options.width)){
72
- return -(parseInt(that.options.width) / 2) + '%';
73
- } else {
74
- return -($(this).width() / 2) + 'px';
75
- }
76
- });
77
- }
78
-
79
- var prop = this.options.height ? 'height' : 'max-height';
80
-
81
- var value = this.options.height || this.options.maxHeight;
82
-
83
- if (value){
84
- this.$element.find('.modal-body')
85
- .css('overflow', 'auto')
86
- .css(prop, value);
87
- }
88
-
89
- this.escape();
90
-
91
- this.tab();
92
-
93
- this.options.loading && this.loading();
94
- },
95
-
96
- hide: function (e) {
97
- e && e.preventDefault();
98
-
99
- e = $.Event('hide');
100
-
101
- this.$element.triggerHandler(e);
102
-
103
- if (!this.isShown || e.isDefaultPrevented()) return (this.isShown = false);
104
-
105
- this.isShown = false;
106
-
107
- this.escape();
108
-
109
- this.tab();
110
-
111
- this.isLoading && this.loading();
112
-
113
- $(document).off('focusin.modal');
114
-
115
- this.$element
116
- .removeClass('in')
117
- .removeClass('animated')
118
- .removeClass(this.options.attentionAnimation)
119
- .removeClass('modal-overflow')
120
- .attr('aria-hidden', true);
121
-
122
- $.support.transition && this.$element.hasClass('fade') ?
123
- this.hideWithTransition() :
124
- this.hideModal();
125
- },
126
-
127
- tab: function () {
128
- var that = this;
129
-
130
- if (this.isShown && this.options.consumeTab) {
131
- this.$element.on('keydown.tabindex.modal', '[data-tabindex]', function (e) {
132
- if (e.keyCode && e.keyCode == 9){
133
- var $next = $(this),
134
- $rollover = $(this);
135
-
136
- that.$element.find('[data-tabindex]:enabled:not([readonly])').each(function (e) {
137
- if (!e.shiftKey){
138
- $next = $next.data('tabindex') < $(this).data('tabindex') ?
139
- $next = $(this) :
140
- $rollover = $(this);
141
- } else {
142
- $next = $next.data('tabindex') > $(this).data('tabindex') ?
143
- $next = $(this) :
144
- $rollover = $(this);
145
- }
146
- });
147
-
148
- $next[0] !== $(this)[0] ?
149
- $next.focus() : $rollover.focus();
150
-
151
- e.preventDefault();
152
-
153
- }
154
- });
155
- } else if (!this.isShown) {
156
- this.$element.off('keydown.tabindex.modal');
157
- }
158
- },
159
-
160
- escape: function () {
161
- var that = this;
162
- if (this.isShown && this.options.keyboard) {
163
- if (!this.$element.attr('tabindex')) this.$element.attr('tabindex', -1);
164
-
165
- this.$element.on('keyup.dismiss.modal', function (e) {
166
- e.which == 27 && that.hide();
167
- });
168
- } else if (!this.isShown) {
169
- this.$element.off('keyup.dismiss.modal')
170
- }
171
- },
172
-
173
- hideWithTransition: function () {
174
- var that = this
175
- , timeout = setTimeout(function () {
176
- that.$element.off($.support.transition.end)
177
- that.hideModal()
178
- }, 500);
179
-
180
- this.$element.one($.support.transition.end, function () {
181
- clearTimeout(timeout)
182
- that.hideModal()
183
- });
184
- },
185
-
186
- hideModal: function () {
187
- this.$element
188
- .hide()
189
- .triggerHandler('hidden');
190
-
191
-
192
- var prop = this.options.height ? 'height' : 'max-height';
193
- var value = this.options.height || this.options.maxHeight;
194
-
195
- if (value){
196
- this.$element.find('.modal-body')
197
- .css('overflow', '')
198
- .css(prop, '');
199
- }
200
-
201
- },
202
-
203
- removeLoading: function () {
204
- this.$loading.remove();
205
- this.$loading = null;
206
- this.isLoading = false;
207
- },
208
-
209
- loading: function (callback) {
210
- callback = callback || function () {};
211
-
212
- var animate = this.$element.hasClass('fade') ? 'fade' : '';
213
-
214
- if (!this.isLoading) {
215
- var doAnimate = $.support.transition && animate;
216
-
217
- this.$loading = $('<div class="loading-mask ' + animate + '">')
218
- .append(this.options.spinner)
219
- .appendTo(this.$element);
220
-
221
- if (doAnimate) this.$loading[0].offsetWidth // force reflow
222
-
223
- this.$loading.addClass('in')
224
-
225
- this.isLoading = true;
226
-
227
- doAnimate ?
228
- this.$loading.one($.support.transition.end, callback) :
229
- callback();
230
-
231
- } else if (this.isLoading && this.$loading) {
232
- this.$loading.removeClass('in');
233
-
234
- var that = this;
235
- $.support.transition && this.$element.hasClass('fade')?
236
- this.$loading.one($.support.transition.end, function () { that.removeLoading() }) :
237
- that.removeLoading();
238
-
239
- } else if (callback) {
240
- callback(this.isLoading);
241
- }
242
- },
243
-
244
- focus: function () {
245
- var $focusElem = this.$element.find(this.options.focusOn);
246
-
247
- $focusElem = $focusElem.length ? $focusElem : this.$element;
248
-
249
- $focusElem.focus();
250
- },
251
-
252
- attention: function (){
253
- // NOTE: transitionEnd with keyframes causes odd behaviour
254
-
255
- if (this.options.attentionAnimation){
256
- this.$element
257
- .removeClass('animated')
258
- .removeClass(this.options.attentionAnimation);
259
-
260
- var that = this;
261
-
262
- setTimeout(function () {
263
- that.$element
264
- .addClass('animated')
265
- .addClass(that.options.attentionAnimation);
266
- }, 0);
267
- }
268
-
269
-
270
- this.focus();
271
- },
272
-
273
-
274
- destroy: function () {
275
- var e = $.Event('destroy');
276
- this.$element.triggerHandler(e);
277
- if (e.isDefaultPrevented()) return;
278
-
279
- this.teardown();
280
- },
281
-
282
- teardown: function () {
283
- if (!this.$parent.length){
284
- this.$element.remove();
285
- this.$element = null;
286
- return;
287
- }
288
-
289
- if (this.$parent !== this.$element.parent()){
290
- this.$element.appendTo(this.$parent);
291
- }
292
-
293
- this.$element.off('.modal');
294
- this.$element.removeData('modal');
295
- this.$element
296
- .removeClass('in')
297
- .attr('aria-hidden', true);
298
- }
299
- }
27
+ var Modal = function (element, options) {
28
+ this.init(element, options);
29
+ };
300
30
 
31
+ Modal.prototype = {
301
32
 
302
- /* MODAL PLUGIN DEFINITION
303
- * ======================= */
33
+ constructor: Modal,
304
34
 
305
- $.fn.modal = function (option) {
306
- return this.each(function () {
307
- var $this = $(this),
308
- data = $this.data('modal'),
309
- options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option);
35
+ init: function (element, options) {
36
+ this.options = options;
310
37
 
311
- if (!data) $this.data('modal', (data = new Modal(this, options)))
312
- if (typeof option == 'string') data[option]()
313
- else if (options.show) data.show()
314
- })
315
- }
38
+ this.$element = $(element)
39
+ .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this));
316
40
 
317
- $.fn.modal.defaults = {
318
- keyboard: true,
319
- backdrop: true,
320
- loading: false,
321
- show: true,
322
- width: null,
323
- height: null,
324
- maxHeight: null,
325
- modalOverflow: false,
326
- consumeTab: true,
327
- focusOn: null,
328
- attentionAnimation: 'shake',
329
- manager: 'body',
330
- spinner: '<div class="loading-spinner" style="width: 200px; margin-left: -100px;"><div class="progress progress-striped active"><div class="bar" style="width: 100%;"></div></div></div>'
331
- }
41
+ this.options.remote && this.$element.find('.modal-body').load(this.options.remote);
42
+
43
+ var manager = typeof this.options.manager === 'function' ?
44
+ this.options.manager.call(this) : this.options.manager;
45
+
46
+ manager = manager.appendModal ?
47
+ manager : $(manager).modalmanager().data('modalmanager');
48
+
49
+ manager.appendModal(this);
50
+ },
51
+
52
+ toggle: function () {
53
+ return this[!this.isShown ? 'show' : 'hide']();
54
+ },
55
+
56
+ show: function () {
57
+ var e = $.Event('show');
58
+
59
+ if (this.isShown) return;
60
+
61
+ this.$element.triggerHandler(e);
62
+
63
+ if (e.isDefaultPrevented()) return;
64
+
65
+ this.escape();
66
+
67
+ this.tab();
68
+
69
+ this.options.loading && this.loading();
70
+ },
332
71
 
333
- $.fn.modal.Constructor = Modal
72
+ hide: function (e) {
73
+ e && e.preventDefault();
334
74
 
75
+ e = $.Event('hide');
335
76
 
336
- /* MODAL DATA-API
337
- * ============== */
338
-
339
- $(function () {
340
- $(document).off('.modal').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
341
- var $this = $(this),
342
- href = $this.attr('href'),
343
- $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))), //strip for ie7
344
- option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data());
77
+ this.$element.triggerHandler(e);
78
+
79
+ if (!this.isShown || e.isDefaultPrevented()) return (this.isShown = false);
80
+
81
+ this.isShown = false;
82
+
83
+ this.escape();
84
+
85
+ this.tab();
86
+
87
+ this.isLoading && this.loading();
88
+
89
+ $(document).off('focusin.modal');
90
+
91
+ this.$element
92
+ .removeClass('in')
93
+ .removeClass('animated')
94
+ .removeClass(this.options.attentionAnimation)
95
+ .removeClass('modal-overflow')
96
+ .attr('aria-hidden', true);
97
+
98
+ $.support.transition && this.$element.hasClass('fade') ?
99
+ this.hideWithTransition() :
100
+ this.hideModal();
101
+ },
102
+
103
+ layout: function () {
104
+ var prop = this.options.height ? 'height' : 'max-height',
105
+ value = this.options.height || this.options.maxHeight;
106
+
107
+ if (this.options.width){
108
+ this.$element.css('width', this.options.width);
109
+
110
+ var that = this;
111
+ this.$element.css('margin-left', function () {
112
+ if (/%/ig.test(that.options.width)){
113
+ return -(parseInt(that.options.width) / 2) + '%';
114
+ } else {
115
+ return -($(this).width() / 2) + 'px';
116
+ }
117
+ });
118
+ } else {
119
+ this.$element.css('width', '');
120
+ this.$element.css('margin-left', '');
121
+ }
122
+
123
+ this.$element.find('.modal-body')
124
+ .css('overflow', '')
125
+ .css(prop, '');
126
+
127
+ var modalOverflow = $(window).height() - 10 < this.$element.height();
128
+
129
+ if (value){
130
+ this.$element.find('.modal-body')
131
+ .css('overflow', 'auto')
132
+ .css(prop, value);
133
+ }
134
+
135
+ if (modalOverflow || this.options.modalOverflow) {
136
+ this.$element
137
+ .css('margin-top', 0)
138
+ .addClass('modal-overflow');
139
+ } else {
140
+ this.$element
141
+ .css('margin-top', 0 - this.$element.height() / 2)
142
+ .removeClass('modal-overflow');
143
+ }
144
+ },
145
+
146
+ tab: function () {
147
+ var that = this;
148
+
149
+ if (this.isShown && this.options.consumeTab) {
150
+ this.$element.on('keydown.tabindex.modal', '[data-tabindex]', function (e) {
151
+ if (e.keyCode && e.keyCode == 9){
152
+ var $next = $(this),
153
+ $rollover = $(this);
154
+
155
+ that.$element.find('[data-tabindex]:enabled:not([readonly])').each(function (e) {
156
+ if (!e.shiftKey){
157
+ $next = $next.data('tabindex') < $(this).data('tabindex') ?
158
+ $next = $(this) :
159
+ $rollover = $(this);
160
+ } else {
161
+ $next = $next.data('tabindex') > $(this).data('tabindex') ?
162
+ $next = $(this) :
163
+ $rollover = $(this);
164
+ }
165
+ });
166
+
167
+ $next[0] !== $(this)[0] ?
168
+ $next.focus() : $rollover.focus();
345
169
 
346
170
  e.preventDefault();
347
- $target
348
- .modal(option)
349
- .one('hide', function () {
350
- $this.focus();
351
- })
171
+ }
172
+ });
173
+ } else if (!this.isShown) {
174
+ this.$element.off('keydown.tabindex.modal');
175
+ }
176
+ },
177
+
178
+ escape: function () {
179
+ var that = this;
180
+ if (this.isShown && this.options.keyboard) {
181
+ if (!this.$element.attr('tabindex')) this.$element.attr('tabindex', -1);
182
+
183
+ this.$element.on('keyup.dismiss.modal', function (e) {
184
+ e.which == 27 && that.hide();
352
185
  });
186
+ } else if (!this.isShown) {
187
+ this.$element.off('keyup.dismiss.modal')
188
+ }
189
+ },
190
+
191
+ hideWithTransition: function () {
192
+ var that = this
193
+ , timeout = setTimeout(function () {
194
+ that.$element.off($.support.transition.end);
195
+ that.hideModal();
196
+ }, 500);
197
+
198
+ this.$element.one($.support.transition.end, function () {
199
+ clearTimeout(timeout);
200
+ that.hideModal();
201
+ });
202
+ },
203
+
204
+ hideModal: function () {
205
+ this.$element
206
+ .hide()
207
+ .triggerHandler('hidden');
208
+
209
+ var prop = this.options.height ? 'height' : 'max-height';
210
+ var value = this.options.height || this.options.maxHeight;
211
+
212
+ if (value){
213
+ this.$element.find('.modal-body')
214
+ .css('overflow', '')
215
+ .css(prop, '');
216
+ }
217
+
218
+ },
219
+
220
+ removeLoading: function () {
221
+ this.$loading.remove();
222
+ this.$loading = null;
223
+ this.isLoading = false;
224
+ },
225
+
226
+ loading: function (callback) {
227
+ callback = callback || function () {};
228
+
229
+ var animate = this.$element.hasClass('fade') ? 'fade' : '';
230
+
231
+ if (!this.isLoading) {
232
+ var doAnimate = $.support.transition && animate;
233
+
234
+ this.$loading = $('<div class="loading-mask ' + animate + '">')
235
+ .append(this.options.spinner)
236
+ .appendTo(this.$element);
237
+
238
+ if (doAnimate) this.$loading[0].offsetWidth; // force reflow
239
+
240
+ this.$loading.addClass('in');
241
+
242
+ this.isLoading = true;
243
+
244
+ doAnimate ?
245
+ this.$loading.one($.support.transition.end, callback) :
246
+ callback();
247
+
248
+ } else if (this.isLoading && this.$loading) {
249
+ this.$loading.removeClass('in');
250
+
251
+ var that = this;
252
+ $.support.transition && this.$element.hasClass('fade')?
253
+ this.$loading.one($.support.transition.end, function () { that.removeLoading() }) :
254
+ that.removeLoading();
255
+
256
+ } else if (callback) {
257
+ callback(this.isLoading);
258
+ }
259
+ },
260
+
261
+ focus: function () {
262
+ var $focusElem = this.$element.find(this.options.focusOn);
263
+
264
+ $focusElem = $focusElem.length ? $focusElem : this.$element;
265
+
266
+ $focusElem.focus();
267
+ },
268
+
269
+ attention: function (){
270
+ // NOTE: transitionEnd with keyframes causes odd behaviour
271
+
272
+ if (this.options.attentionAnimation){
273
+ this.$element
274
+ .removeClass('animated')
275
+ .removeClass(this.options.attentionAnimation);
276
+
277
+ var that = this;
278
+
279
+ setTimeout(function () {
280
+ that.$element
281
+ .addClass('animated')
282
+ .addClass(that.options.attentionAnimation);
283
+ }, 0);
284
+ }
285
+
286
+
287
+ this.focus();
288
+ },
289
+
290
+
291
+ destroy: function () {
292
+ var e = $.Event('destroy');
293
+ this.$element.triggerHandler(e);
294
+ if (e.isDefaultPrevented()) return;
295
+
296
+ this.teardown();
297
+ },
298
+
299
+ teardown: function () {
300
+ if (!this.$parent.length){
301
+ this.$element.remove();
302
+ this.$element = null;
303
+ return;
304
+ }
305
+
306
+ if (this.$parent !== this.$element.parent()){
307
+ this.$element.appendTo(this.$parent);
308
+ }
309
+
310
+ this.$element.off('.modal');
311
+ this.$element.removeData('modal');
312
+ this.$element
313
+ .removeClass('in')
314
+ .attr('aria-hidden', true);
315
+ }
316
+ };
317
+
318
+
319
+ /* MODAL PLUGIN DEFINITION
320
+ * ======================= */
321
+
322
+ $.fn.modal = function (option, args) {
323
+ return this.each(function () {
324
+ var $this = $(this),
325
+ data = $this.data('modal'),
326
+ options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option);
327
+
328
+ if (!data) $this.data('modal', (data = new Modal(this, options)));
329
+ if (typeof option == 'string') data[option].apply(data, [].concat(args));
330
+ else if (options.show) data.show()
331
+ })
332
+ };
333
+
334
+ $.fn.modal.defaults = {
335
+ keyboard: true,
336
+ backdrop: true,
337
+ loading: false,
338
+ show: true,
339
+ width: null,
340
+ height: null,
341
+ maxHeight: null,
342
+ modalOverflow: false,
343
+ consumeTab: true,
344
+ focusOn: null,
345
+ replace: false,
346
+ resize: false,
347
+ attentionAnimation: 'shake',
348
+ manager: 'body',
349
+ spinner: '<div class="loading-spinner" style="width: 200px; margin-left: -100px;"><div class="progress progress-striped active"><div class="bar" style="width: 100%;"></div></div></div>'
350
+ };
351
+
352
+ $.fn.modal.Constructor = Modal;
353
+
354
+
355
+ /* MODAL DATA-API
356
+ * ============== */
357
+
358
+ $(function () {
359
+ $(document).off('.modal').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
360
+ var $this = $(this),
361
+ href = $this.attr('href'),
362
+ $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))), //strip for ie7
363
+ option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data());
364
+
365
+ e.preventDefault();
366
+ $target
367
+ .modal(option)
368
+ .one('hide', function () {
369
+ $this.focus();
370
+ })
353
371
  });
372
+ });
354
373
 
355
- }(window.jQuery);
374
+ }(window.jQuery);