bootstrap_modal_rails 2.0.4 → 2.1.0

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.
@@ -1,5 +1,5 @@
1
- /* ===========================================================
2
- * bootstrap-modalmanager.js v2.0
1
+ /* ===========================================================
2
+ * bootstrap-modalmanager.js v2.1
3
3
  * ===========================================================
4
4
  * Copyright 2012 Jordan Schroter.
5
5
  *
@@ -18,353 +18,389 @@
18
18
 
19
19
  !function ($) {
20
20
 
21
- "use strict"; // jshint ;_;
21
+ "use strict"; // jshint ;_;
22
22
 
23
- /* MODAL MANAGER CLASS DEFINITION
24
- * ====================== */
23
+ /* MODAL MANAGER CLASS DEFINITION
24
+ * ====================== */
25
25
 
26
- var ModalManager = function (element, options) {
27
- this.init(element, options);
28
- }
26
+ var ModalManager = function (element, options) {
27
+ this.init(element, options);
28
+ };
29
29
 
30
- ModalManager.prototype = {
30
+ ModalManager.prototype = {
31
31
 
32
- constructor: ModalManager,
32
+ constructor: ModalManager,
33
33
 
34
- init: function (element, options) {
35
- this.$element = $(element);
36
- this.options = $.extend({}, $.fn.modalmanager.defaults, this.$element.data(), typeof options == 'object' && options);
37
- this.stack = [];
38
- this.backdropCount = 0;
39
- },
34
+ init: function (element, options) {
35
+ this.$element = $(element);
36
+ this.options = $.extend({}, $.fn.modalmanager.defaults, this.$element.data(), typeof options == 'object' && options);
37
+ this.stack = [];
38
+ this.backdropCount = 0;
40
39
 
41
- createModal: function (element, options) {
42
- $(element).modal($.extend({ manager: this }, options));
43
- },
40
+ if (this.options.resize) {
41
+ var resizeTimeout,
42
+ that = this;
44
43
 
45
- appendModal: function (modal) {
46
- this.stack.push(modal);
44
+ $(window).on('resize.modal', function(){
45
+ resizeTimeout && clearTimeout(resizeTimeout);
46
+ resizeTimeout = setTimeout(function(){
47
+ for (var i = 0; i < that.stack.length; i++){
48
+ that.stack[i].isShown && that.stack[i].layout();
49
+ }
50
+ }, 10);
51
+ });
52
+ }
53
+ },
47
54
 
48
- var that = this;
55
+ createModal: function (element, options) {
56
+ $(element).modal($.extend({ manager: this }, options));
57
+ },
49
58
 
50
- modal.$element.on('show.modalmanager', targetIsSelf(function (e) {
51
- modal.isShown = true;
59
+ appendModal: function (modal) {
60
+ this.stack.push(modal);
52
61
 
53
- var transition = $.support.transition && modal.$element.hasClass('fade');
54
-
55
- that.$element
56
- .toggleClass('modal-open', that.hasOpenModal())
57
- .toggleClass('page-overflow', $(window).height() < that.$element.height());
58
-
59
- modal.$parent = modal.$element.parent();
60
-
61
- modal.$container = that.createContainer(modal);
62
+ var that = this;
62
63
 
63
- modal.$element.appendTo(modal.$container);
64
+ modal.$element.on('show.modalmanager', targetIsSelf(function (e) {
64
65
 
65
- var modalOverflow = $(window).height() < modal.$element.height() || modal.options.modalOverflow;
66
-
67
- that.backdrop(modal, function () {
66
+ var showModal = function(){
67
+ modal.isShown = true;
68
68
 
69
- modal.$element.show();
69
+ var transition = $.support.transition && modal.$element.hasClass('fade');
70
70
 
71
- if (transition) {
72
- modal.$element[0].style.display = 'run-in';
73
- modal.$element[0].offsetWidth;
74
- modal.$element.one($.support.transition.end, function () { modal.$element[0].style.display = 'block' });
75
- }
71
+ that.$element
72
+ .toggleClass('modal-open', that.hasOpenModal())
73
+ .toggleClass('page-overflow', $(window).height() < that.$element.height());
76
74
 
77
- modal.$element
78
- .toggleClass('modal-overflow', modalOverflow)
79
- .css('margin-top', modalOverflow ? 0 : 0 - modal.$element.height()/2)
80
- .addClass('in')
81
- .attr('aria-hidden', false);
82
-
83
- var complete = function () {
84
- that.setFocus();
85
- modal.$element.triggerHandler('shown');
86
- }
75
+ modal.$parent = modal.$element.parent();
87
76
 
88
- transition ?
89
- modal.$element.one($.support.transition.end, complete) :
90
- complete();
91
- });
92
- }));
77
+ modal.$container = that.createContainer(modal);
93
78
 
94
- modal.$element.on('hidden.modalmanager', targetIsSelf(function (e) {
79
+ modal.$element.appendTo(modal.$container);
95
80
 
96
- that.backdrop(modal);
81
+ that.backdrop(modal, function () {
97
82
 
98
- if (modal.$backdrop){
99
- $.support.transition && modal.$element.hasClass('fade')?
100
- modal.$backdrop.one($.support.transition.end, function () { that.destroyModal(modal) }) :
101
- that.destroyModal(modal);
102
- } else {
103
- that.destroyModal(modal);
104
- }
83
+ modal.$element.show();
105
84
 
106
- }));
85
+ modal.layout();
107
86
 
108
- modal.$element.on('destroy.modalmanager', targetIsSelf(function (e) {
109
- that.removeModal(modal);
110
- }));
111
- },
87
+ modal.$element
88
+ .addClass('in')
89
+ .attr('aria-hidden', false);
112
90
 
113
- destroyModal: function (modal) {
91
+ var complete = function () {
92
+ that.setFocus();
93
+ modal.$element.triggerHandler('shown');
94
+ };
114
95
 
115
- modal.destroy();
96
+ transition ?
97
+ modal.$element.one($.support.transition.end, complete) :
98
+ complete();
99
+ });
100
+ };
116
101
 
117
- var hasOpenModal = this.hasOpenModal();
102
+ modal.options.replace ?
103
+ that.replace(showModal) :
104
+ showModal();
105
+ }));
118
106
 
119
- this.$element.toggleClass('modal-open', hasOpenModal);
120
-
121
- if (!hasOpenModal){
122
- this.$element.removeClass('page-overflow');
123
- }
107
+ modal.$element.on('hidden.modalmanager', targetIsSelf(function (e) {
124
108
 
125
- this.removeContainer(modal);
109
+ that.backdrop(modal);
126
110
 
127
- this.setFocus();
128
- },
111
+ if (modal.$backdrop){
112
+ $.support.transition && modal.$element.hasClass('fade') ?
113
+ modal.$backdrop.one($.support.transition.end, function () { that.destroyModal(modal) }) :
114
+ that.destroyModal(modal);
115
+ } else {
116
+ that.destroyModal(modal);
117
+ }
129
118
 
130
- hasOpenModal: function () {
131
- for (var i = 0; i < this.stack.length; i++){
132
- if (this.stack[i].isShown) return true;
133
- }
119
+ }));
134
120
 
135
- return false;
136
- },
121
+ modal.$element.on('destroy.modalmanager', targetIsSelf(function (e) {
122
+ that.removeModal(modal);
123
+ }));
137
124
 
138
- setFocus: function () {
139
- var topModal;
125
+ },
140
126
 
141
- for (var i = 0; i < this.stack.length; i++){
142
- if (this.stack[i].isShown) topModal = this.stack[i];
143
- }
127
+ destroyModal: function (modal) {
144
128
 
145
- if (!topModal) return;
129
+ modal.destroy();
146
130
 
147
- topModal.focus();
131
+ var hasOpenModal = this.hasOpenModal();
148
132
 
149
- },
133
+ this.$element.toggleClass('modal-open', hasOpenModal);
150
134
 
151
- removeModal: function (modal) {
152
- modal.$element.off('.modalmanager');
153
- if (modal.$backdrop) this.removeBackdrop.call(modal);
154
- this.stack.splice(this.getIndexOfModal(modal), 1);
155
- },
135
+ if (!hasOpenModal){
136
+ this.$element.removeClass('page-overflow');
137
+ }
156
138
 
157
- getModalAt: function (index) {
158
- return this.stack[index];
159
- },
139
+ this.removeContainer(modal);
160
140
 
161
- getIndexOfModal: function (modal) {
162
- for (var i = 0; i < this.stack.length; i++){
163
- if (modal === this.stack[i]) return i;
164
- }
165
- },
166
-
167
- removeBackdrop: function (modal) {
168
- modal.$backdrop.remove();
169
- modal.$backdrop = null;
170
- },
171
-
172
- createBackdrop: function (animate) {
173
- var $backdrop;
174
-
175
- if (!this.isLoading) {
176
- $backdrop = $('<div class="modal-backdrop ' + animate + '" />')
177
- .appendTo(this.$element);
178
-
179
- } else {
180
- $backdrop = this.$loading;
181
- $backdrop.off('.modalmanager');
182
- this.$spinner.remove();
183
- this.isLoading = false;
184
- this.$loading = this.$spinner = null;
185
- }
141
+ this.setFocus();
142
+ },
186
143
 
187
- return $backdrop
188
- },
189
-
190
- removeContainer: function (modal) {
191
- modal.$container.remove();
192
- modal.$container = null;
193
- },
194
-
195
- createContainer: function (modal) {
196
- var $container;
197
-
198
- $container = $('<div class="modal-scrollable">')
199
- .css('z-index', getzIndex( 'modal',
200
- modal ? this.getIndexOfModal(modal) : this.stack.length ))
201
- .appendTo(this.$element);
202
-
203
- if (modal && modal.options.backdrop != 'static') {
204
- $container.on('click.modal', targetIsSelf(function (e) {
205
- modal.hide();
206
- }));
207
- } else if (modal) {
208
- $container.on('click.modal', targetIsSelf(function (e) {
209
- modal.attention();
210
- }));
211
- }
144
+ hasOpenModal: function () {
145
+ for (var i = 0; i < this.stack.length; i++){
146
+ if (this.stack[i].isShown) return true;
147
+ }
212
148
 
213
- return $container;
149
+ return false;
150
+ },
214
151
 
215
- },
152
+ setFocus: function () {
153
+ var topModal;
216
154
 
217
- backdrop: function (modal, callback) {
218
- var animate = modal.$element.hasClass('fade') ? 'fade' : '',
219
- showBackdrop = modal.options.backdrop &&
220
- this.backdropCount < this.options.backdropLimit;
155
+ for (var i = 0; i < this.stack.length; i++){
156
+ if (this.stack[i].isShown) topModal = this.stack[i];
157
+ }
221
158
 
222
- if (modal.isShown && showBackdrop) {
223
- var doAnimate = $.support.transition && animate && !this.isLoading;
159
+ if (!topModal) return;
224
160
 
161
+ topModal.focus();
225
162
 
226
- modal.$backdrop = this.createBackdrop(animate);
163
+ },
227
164
 
228
- modal.$backdrop.css('z-index', getzIndex( 'backdrop', this.getIndexOfModal(modal) ))
165
+ removeModal: function (modal) {
166
+ modal.$element.off('.modalmanager');
167
+ if (modal.$backdrop) this.removeBackdrop.call(modal);
168
+ this.stack.splice(this.getIndexOfModal(modal), 1);
169
+ },
229
170
 
230
- if (doAnimate) modal.$backdrop[0].offsetWidth // force reflow
171
+ getModalAt: function (index) {
172
+ return this.stack[index];
173
+ },
231
174
 
232
- modal.$backdrop.addClass('in')
175
+ getIndexOfModal: function (modal) {
176
+ for (var i = 0; i < this.stack.length; i++){
177
+ if (modal === this.stack[i]) return i;
178
+ }
179
+ },
233
180
 
234
- this.backdropCount += 1;
181
+ replace: function (callback) {
182
+ var topModal;
235
183
 
236
- doAnimate ?
237
- modal.$backdrop.one($.support.transition.end, callback) :
238
- callback();
184
+ for (var i = 0; i < this.stack.length; i++){
185
+ if (this.stack[i].isShown) topModal = this.stack[i];
186
+ }
239
187
 
240
- } else if (!modal.isShown && modal.$backdrop) {
241
- modal.$backdrop.removeClass('in');
188
+ if (topModal) {
189
+ this.$backdropHandle = topModal.$backdrop;
190
+ topModal.$backdrop = null;
242
191
 
243
- this.backdropCount -= 1;
192
+ callback && topModal.$element.one('hidden',
193
+ targetIsSelf( $.proxy(callback, this) ));
244
194
 
245
- var that = this;
195
+ topModal.hide();
196
+ } else if (callback) {
197
+ callback();
198
+ }
199
+ },
246
200
 
247
- $.support.transition && modal.$element.hasClass('fade')?
248
- modal.$backdrop.one($.support.transition.end, function () { that.removeBackdrop(modal) }) :
249
- that.removeBackdrop(modal);
201
+ removeBackdrop: function (modal) {
202
+ modal.$backdrop.remove();
203
+ modal.$backdrop = null;
204
+ },
250
205
 
251
- } else if (callback) {
252
- callback();
253
- }
254
- },
206
+ createBackdrop: function (animate) {
207
+ var $backdrop;
255
208
 
256
- removeLoading: function () {
257
- this.$loading && this.$loading.remove();
258
- this.$loading = null;
259
- this.isLoading = false;
260
- },
209
+ if (!this.$backdropHandle) {
210
+ $backdrop = $('<div class="modal-backdrop ' + animate + '" />')
211
+ .appendTo(this.$element);
212
+ } else {
213
+ $backdrop = this.$backdropHandle;
214
+ $backdrop.off('.modalmanager');
215
+ this.$backdropHandle = null;
216
+ this.isLoading && this.removeSpinner();
217
+ }
261
218
 
262
- loading: function (callback) {
263
- callback = callback || function () { };
264
-
265
- this.$element
266
- .toggleClass('modal-open', !this.isLoading || this.hasOpenModal())
267
- .toggleClass('page-overflow', $(window).height() < this.$element.height());
268
-
269
- if (!this.isLoading) {
219
+ return $backdrop
220
+ },
270
221
 
271
- this.$loading = this.createBackdrop('fade');
222
+ removeContainer: function (modal) {
223
+ modal.$container.remove();
224
+ modal.$container = null;
225
+ },
272
226
 
273
- this.$loading[0].offsetWidth // force reflow
227
+ createContainer: function (modal) {
228
+ var $container;
274
229
 
275
- this.$loading
276
- .css('z-index', getzIndex('backdrop', this.stack.length))
277
- .addClass('in');
230
+ $container = $('<div class="modal-scrollable">')
231
+ .css('z-index', getzIndex( 'modal',
232
+ modal ? this.getIndexOfModal(modal) : this.stack.length ))
233
+ .appendTo(this.$element);
278
234
 
279
- var $spinner = $(this.options.spinner)
280
- .css('z-index', getzIndex('modal', this.stack.length))
281
- .appendTo(this.$element)
282
- .addClass('in');
235
+ if (modal && modal.options.backdrop != 'static') {
236
+ $container.on('click.modal', targetIsSelf(function (e) {
237
+ modal.hide();
238
+ }));
239
+ } else if (modal) {
240
+ $container.on('click.modal', targetIsSelf(function (e) {
241
+ modal.attention();
242
+ }));
243
+ }
283
244
 
284
- this.$spinner = $(this.createContainer())
285
- .append($spinner)
286
- .on('click.modalmanager', $.proxy(this.loading, this));
245
+ return $container;
287
246
 
288
- this.isLoading = true;
247
+ },
289
248
 
290
- $.support.transition ?
291
- this.$loading.one($.support.transition.end, callback) :
292
- callback();
249
+ backdrop: function (modal, callback) {
250
+ var animate = modal.$element.hasClass('fade') ? 'fade' : '',
251
+ showBackdrop = modal.options.backdrop &&
252
+ this.backdropCount < this.options.backdropLimit;
293
253
 
294
- } else if (this.isLoading && this.$loading) {
295
- this.$loading.removeClass('in');
254
+ if (modal.isShown && showBackdrop) {
255
+ var doAnimate = $.support.transition && animate && !this.$backdropHandle;
296
256
 
297
- if (this.$spinner) this.$spinner.remove();
257
+ modal.$backdrop = this.createBackdrop(animate);
298
258
 
299
- var that = this;
300
- $.support.transition ?
301
- this.$loading.one($.support.transition.end, function () { that.removeLoading() }) :
302
- that.removeLoading();
259
+ modal.$backdrop.css('z-index', getzIndex( 'backdrop', this.getIndexOfModal(modal) ));
303
260
 
304
- } else if (callback) {
305
- callback(this.isLoading);
306
- }
307
- }
308
- }
261
+ if (doAnimate) modal.$backdrop[0].offsetWidth; // force reflow
309
262
 
310
- /* PRIVATE METHODS
311
- * ======================= */
263
+ modal.$backdrop.addClass('in');
312
264
 
313
- // computes and caches the zindexes
314
- var getzIndex = (function () {
315
- var zIndexFactor,
316
- baseIndex = {};
265
+ this.backdropCount += 1;
317
266
 
318
- return function (type, pos) {
267
+ doAnimate ?
268
+ modal.$backdrop.one($.support.transition.end, callback) :
269
+ callback();
319
270
 
320
- if (typeof zIndexFactor === 'undefined'){
321
- var $baseModal = $('<div class="modal hide" />').appendTo('body'),
322
- $baseBackdrop = $('<div class="modal-backdrop hide" />').appendTo('body');
271
+ } else if (!modal.isShown && modal.$backdrop) {
272
+ modal.$backdrop.removeClass('in');
323
273
 
324
- baseIndex['modal'] = +$baseModal.css('z-index'),
325
- baseIndex['backdrop'] = +$baseBackdrop.css('z-index'),
326
- zIndexFactor = baseIndex['modal'] - baseIndex['backdrop'];
327
-
328
- $baseModal.remove();
329
- $baseBackdrop.remove();
330
- $baseBackdrop = $baseModal = null;
331
- }
274
+ this.backdropCount -= 1;
332
275
 
333
- return baseIndex[type] + (zIndexFactor * pos);
276
+ var that = this;
334
277
 
335
- }
336
- }())
337
-
338
- // make sure the event target is the modal itself in order to prevent
339
- // other components such as tabsfrom triggering the modal manager.
340
- // if Boostsrap namespaced events, this would not be needed.
341
- function targetIsSelf(callback){
342
- return function (e) {
343
- if (this === e.target){
344
- return callback.apply(this, arguments);
345
- }
346
- }
347
- }
278
+ $.support.transition && modal.$element.hasClass('fade')?
279
+ modal.$backdrop.one($.support.transition.end, function () { that.removeBackdrop(modal) }) :
280
+ that.removeBackdrop(modal);
281
+
282
+ } else if (callback) {
283
+ callback();
284
+ }
285
+ },
286
+
287
+ removeSpinner: function(){
288
+ this.$spinner && this.$spinner.remove();
289
+ this.$spinner = null;
290
+ this.isLoading = false;
291
+ },
292
+
293
+ removeLoading: function () {
294
+ this.$backdropHandle && this.$backdropHandle.remove();
295
+ this.$backdropHandle = null;
296
+ this.removeSpinner();
297
+ },
298
+
299
+ loading: function (callback) {
300
+ callback = callback || function () { };
348
301
 
302
+ this.$element
303
+ .toggleClass('modal-open', !this.isLoading || this.hasOpenModal())
304
+ .toggleClass('page-overflow', $(window).height() < this.$element.height());
349
305
 
350
- /* MODAL MANAGER PLUGIN DEFINITION
351
- * ======================= */
306
+ if (!this.isLoading) {
352
307
 
353
- $.fn.modalmanager = function (option) {
354
- return this.each(function () {
355
- var $this = $(this),
356
- data = $this.data('modalmanager');
308
+ this.$backdropHandle = this.createBackdrop('fade');
357
309
 
358
- if (!data) $this.data('modalmanager', (data = new ModalManager(this, option)))
359
- if (typeof option === 'string') data[option]()
360
- })
310
+ this.$backdropHandle[0].offsetWidth; // force reflow
311
+
312
+ this.$backdropHandle
313
+ .css('z-index', getzIndex('backdrop', this.stack.length))
314
+ .addClass('in');
315
+
316
+ var $spinner = $(this.options.spinner)
317
+ .css('z-index', getzIndex('modal', this.stack.length))
318
+ .appendTo(this.$element)
319
+ .addClass('in');
320
+
321
+ this.$spinner = $(this.createContainer())
322
+ .append($spinner)
323
+ .on('click.modalmanager', $.proxy(this.loading, this));
324
+
325
+ this.isLoading = true;
326
+
327
+ $.support.transition ?
328
+ this.$backdropHandle.one($.support.transition.end, callback) :
329
+ callback();
330
+
331
+ } else if (this.isLoading && this.$backdropHandle) {
332
+ this.$backdropHandle.removeClass('in');
333
+
334
+ var that = this;
335
+ $.support.transition ?
336
+ this.$backdropHandle.one($.support.transition.end, function () { that.removeLoading() }) :
337
+ that.removeLoading();
338
+
339
+ } else if (callback) {
340
+ callback(this.isLoading);
341
+ }
361
342
  }
343
+ };
344
+
345
+ /* PRIVATE METHODS
346
+ * ======================= */
347
+
348
+ // computes and caches the zindexes
349
+ var getzIndex = (function () {
350
+ var zIndexFactor,
351
+ baseIndex = {};
352
+
353
+ return function (type, pos) {
362
354
 
363
- $.fn.modalmanager.defaults = {
364
- backdropLimit: 999,
365
- spinner: '<div class="loading-spinner fade" style="width: 200px; margin-left: -100px;"><div class="progress progress-striped active"><div class="bar" style="width: 100%;"></div></div></div>'
355
+ if (typeof zIndexFactor === 'undefined'){
356
+ var $baseModal = $('<div class="modal hide" />').appendTo('body'),
357
+ $baseBackdrop = $('<div class="modal-backdrop hide" />').appendTo('body');
358
+
359
+ baseIndex['modal'] = +$baseModal.css('z-index');
360
+ baseIndex['backdrop'] = +$baseBackdrop.css('z-index');
361
+ zIndexFactor = baseIndex['modal'] - baseIndex['backdrop'];
362
+
363
+ $baseModal.remove();
364
+ $baseBackdrop.remove();
365
+ $baseBackdrop = $baseModal = null;
366
+ }
367
+
368
+ return baseIndex[type] + (zIndexFactor * pos);
369
+
370
+ }
371
+ }());
372
+
373
+ // make sure the event target is the modal itself in order to prevent
374
+ // other components such as tabsfrom triggering the modal manager.
375
+ // if Boostsrap namespaced events, this would not be needed.
376
+ function targetIsSelf(callback){
377
+ return function (e) {
378
+ if (this === e.target){
379
+ return callback.apply(this, arguments);
380
+ }
366
381
  }
382
+ }
383
+
384
+
385
+ /* MODAL MANAGER PLUGIN DEFINITION
386
+ * ======================= */
387
+
388
+ $.fn.modalmanager = function (option, args) {
389
+ return this.each(function () {
390
+ var $this = $(this),
391
+ data = $this.data('modalmanager');
392
+
393
+ if (!data) $this.data('modalmanager', (data = new ModalManager(this, option)))
394
+ if (typeof option === 'string') data[option].apply(data, [].concat(args))
395
+ })
396
+ };
397
+
398
+ $.fn.modalmanager.defaults = {
399
+ backdropLimit: 999,
400
+ resize: true,
401
+ spinner: '<div class="loading-spinner fade" style="width: 200px; margin-left: -100px;"><div class="progress progress-striped active"><div class="bar" style="width: 100%;"></div></div></div>'
402
+ };
367
403
 
368
- $.fn.modalmanager.Constructor = ModalManager
404
+ $.fn.modalmanager.Constructor = ModalManager
369
405
 
370
- }(jQuery);
406
+ }(jQuery);