Subversion Repositories eFlore/Applications.cel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2328 jpm 1
/* ===========================================================
2
 * bootstrap-modal.js v2.2.5
3
 * ===========================================================
4
 * Copyright 2012 Jordan Schroter
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 * ========================================================== */
18
 
19
 
20
!function ($) {
21
 
22
	"use strict"; // jshint ;_;
23
 
24
	/* MODAL CLASS DEFINITION
25
	* ====================== */
26
 
27
	var Modal = function (element, options) {
28
		this.init(element, options);
29
	};
30
 
31
	Modal.prototype = {
32
 
33
		constructor: Modal,
34
 
35
		init: function (element, options) {
36
			var that = this;
37
 
38
			this.options = options;
39
 
40
			this.$element = $(element)
41
				.delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this));
42
 
43
			this.options.remote && this.$element.find('.modal-body').load(this.options.remote, function () {
44
				var e = $.Event('loaded');
45
				that.$element.trigger(e);
46
			});
47
 
48
			var manager = typeof this.options.manager === 'function' ?
49
				this.options.manager.call(this) : this.options.manager;
50
 
51
			manager = manager.appendModal ?
52
				manager : $(manager).modalmanager().data('modalmanager');
53
 
54
			manager.appendModal(this);
55
		},
56
 
57
		toggle: function () {
58
			return this[!this.isShown ? 'show' : 'hide']();
59
		},
60
 
61
		show: function () {
62
			var e = $.Event('show');
63
 
64
			if (this.isShown) return;
65
 
66
			this.$element.trigger(e);
67
 
68
			if (e.isDefaultPrevented()) return;
69
 
70
			this.escape();
71
 
72
			this.tab();
73
 
74
			this.options.loading && this.loading();
75
		},
76
 
77
		hide: function (e) {
78
			e && e.preventDefault();
79
 
80
			e = $.Event('hide');
81
 
82
			this.$element.trigger(e);
83
 
84
			if (!this.isShown || e.isDefaultPrevented()) return;
85
 
86
			this.isShown = false;
87
 
88
			this.escape();
89
 
90
			this.tab();
91
 
92
			this.isLoading && this.loading();
93
 
94
			$(document).off('focusin.modal');
95
 
96
			this.$element
97
				.removeClass('in')
98
				.removeClass('animated')
99
				.removeClass(this.options.attentionAnimation)
100
				.removeClass('modal-overflow')
101
				.attr('aria-hidden', true);
102
 
103
			$.support.transition && this.$element.hasClass('fade') ?
104
				this.hideWithTransition() :
105
				this.hideModal();
106
		},
107
 
108
		layout: function () {
109
			var prop = this.options.height ? 'height' : 'max-height',
110
				value = this.options.height || this.options.maxHeight;
111
 
112
			if (this.options.width){
113
				this.$element.css('width', this.options.width);
114
 
115
				var that = this;
116
				this.$element.css('margin-left', function () {
117
					if (/%/ig.test(that.options.width)){
118
						return -(parseInt(that.options.width) / 2) + '%';
119
					} else {
120
						return -($(this).width() / 2) + 'px';
121
					}
122
				});
123
			} else {
124
				this.$element.css('width', '');
125
				this.$element.css('margin-left', '');
126
			}
127
 
128
			this.$element.find('.modal-body')
129
				.css('overflow', '')
130
				.css(prop, '');
131
 
132
			if (value){
133
				this.$element.find('.modal-body')
134
					.css('overflow', 'auto')
135
					.css(prop, value);
136
			}
137
 
138
			var modalOverflow = $(window).height() - 10 < this.$element.height();
139
 
140
			if (modalOverflow || this.options.modalOverflow) {
141
				this.$element
142
					.css('margin-top', 0)
143
					.addClass('modal-overflow');
144
			} else {
145
				this.$element
146
					.css('margin-top', 0 - this.$element.height() / 2)
147
					.removeClass('modal-overflow');
148
			}
149
		},
150
 
151
		tab: function () {
152
			var that = this;
153
 
154
			if (this.isShown && this.options.consumeTab) {
155
				this.$element.on('keydown.tabindex.modal', '[data-tabindex]', function (e) {
156
			    	if (e.keyCode && e.keyCode == 9){
157
						var elements = [],
158
							tabindex = Number($(this).data('tabindex'));
159
 
160
						that.$element.find('[data-tabindex]:enabled:visible:not([readonly])').each(function (ev) {
161
							elements.push(Number($(this).data('tabindex')));
162
						});
163
						elements.sort(function(a,b){return a-b});
164
 
165
						var arrayPos = $.inArray(tabindex, elements);
166
						if (!e.shiftKey){
167
						 		arrayPos < elements.length-1 ?
168
									that.$element.find('[data-tabindex='+elements[arrayPos+1]+']').focus() :
169
									that.$element.find('[data-tabindex='+elements[0]+']').focus();
170
							} else {
171
								arrayPos == 0 ?
172
									that.$element.find('[data-tabindex='+elements[elements.length-1]+']').focus() :
173
									that.$element.find('[data-tabindex='+elements[arrayPos-1]+']').focus();
174
							}
175
 
176
						e.preventDefault();
177
					}
178
				});
179
			} else if (!this.isShown) {
180
				this.$element.off('keydown.tabindex.modal');
181
			}
182
		},
183
 
184
		escape: function () {
185
			var that = this;
186
			if (this.isShown && this.options.keyboard) {
187
				if (!this.$element.attr('tabindex')) this.$element.attr('tabindex', -1);
188
 
189
				this.$element.on('keyup.dismiss.modal', function (e) {
190
					e.which == 27 && that.hide();
191
				});
192
			} else if (!this.isShown) {
193
				this.$element.off('keyup.dismiss.modal')
194
			}
195
		},
196
 
197
		hideWithTransition: function () {
198
			var that = this
199
				, timeout = setTimeout(function () {
200
					that.$element.off($.support.transition.end);
201
					that.hideModal();
202
				}, 500);
203
 
204
			this.$element.one($.support.transition.end, function () {
205
				clearTimeout(timeout);
206
				that.hideModal();
207
			});
208
		},
209
 
210
		hideModal: function () {
211
			var prop = this.options.height ? 'height' : 'max-height';
212
			var value = this.options.height || this.options.maxHeight;
213
 
214
			if (value){
215
				this.$element.find('.modal-body')
216
					.css('overflow', '')
217
					.css(prop, '');
218
			}
219
 
220
			this.$element
221
				.hide()
222
				.trigger('hidden');
223
		},
224
 
225
		removeLoading: function () {
226
			this.$loading.remove();
227
			this.$loading = null;
228
			this.isLoading = false;
229
		},
230
 
231
		loading: function (callback) {
232
			callback = callback || function () {};
233
 
234
			var animate = this.$element.hasClass('fade') ? 'fade' : '';
235
 
236
			if (!this.isLoading) {
237
				var doAnimate = $.support.transition && animate;
238
 
239
				this.$loading = $('<div class="loading-mask ' + animate + '">')
240
					.append(this.options.spinner)
241
					.appendTo(this.$element);
242
 
243
				if (doAnimate) this.$loading[0].offsetWidth; // force reflow
244
 
245
				this.$loading.addClass('in');
246
 
247
				this.isLoading = true;
248
 
249
				doAnimate ?
250
					this.$loading.one($.support.transition.end, callback) :
251
					callback();
252
 
253
			} else if (this.isLoading && this.$loading) {
254
				this.$loading.removeClass('in');
255
 
256
				var that = this;
257
				$.support.transition && this.$element.hasClass('fade')?
258
					this.$loading.one($.support.transition.end, function () { that.removeLoading() }) :
259
					that.removeLoading();
260
 
261
			} else if (callback) {
262
				callback(this.isLoading);
263
			}
264
		},
265
 
266
		focus: function () {
267
			var $focusElem = this.$element.find(this.options.focusOn);
268
 
269
			$focusElem = $focusElem.length ? $focusElem : this.$element;
270
 
271
			$focusElem.focus();
272
		},
273
 
274
		attention: function (){
275
			// NOTE: transitionEnd with keyframes causes odd behaviour
276
 
277
			if (this.options.attentionAnimation){
278
				this.$element
279
					.removeClass('animated')
280
					.removeClass(this.options.attentionAnimation);
281
 
282
				var that = this;
283
 
284
				setTimeout(function () {
285
					that.$element
286
						.addClass('animated')
287
						.addClass(that.options.attentionAnimation);
288
				}, 0);
289
			}
290
 
291
 
292
			this.focus();
293
		},
294
 
295
 
296
		destroy: function () {
297
			var e = $.Event('destroy');
298
 
299
			this.$element.trigger(e);
300
 
301
			if (e.isDefaultPrevented()) return;
302
 
303
			this.$element
304
				.off('.modal')
305
				.removeData('modal')
306
				.removeClass('in')
307
				.attr('aria-hidden', true);
308
 
309
			if (this.$parent !== this.$element.parent()) {
310
				this.$element.appendTo(this.$parent);
311
			} else if (!this.$parent.length) {
312
				// modal is not part of the DOM so remove it.
313
				this.$element.remove();
314
				this.$element = null;
315
			}
316
 
317
			this.$element.trigger('destroyed');
318
		}
319
	};
320
 
321
 
322
	/* MODAL PLUGIN DEFINITION
323
	* ======================= */
324
 
325
	$.fn.modal = function (option, args) {
326
		return this.each(function () {
327
			var $this = $(this),
328
				data = $this.data('modal'),
329
				options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option);
330
 
331
			if (!data) $this.data('modal', (data = new Modal(this, options)));
332
			if (typeof option == 'string') data[option].apply(data, [].concat(args));
333
			else if (options.show) data.show()
334
		})
335
	};
336
 
337
	$.fn.modal.defaults = {
338
		keyboard: true,
339
		backdrop: true,
340
		loading: false,
341
		show: true,
342
		width: null,
343
		height: null,
344
		maxHeight: null,
345
		modalOverflow: false,
346
		consumeTab: true,
347
		focusOn: null,
348
		replace: false,
349
		resize: false,
350
		attentionAnimation: 'shake',
351
		manager: 'body',
352
		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>',
353
		backdropTemplate: '<div class="modal-backdrop" />'
354
	};
355
 
356
	$.fn.modal.Constructor = Modal;
357
 
358
 
359
	/* MODAL DATA-API
360
	* ============== */
361
 
362
	$(function () {
363
		$(document).off('click.modal').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
364
			var $this = $(this),
365
				href = $this.attr('href'),
366
				$target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))), //strip for ie7
367
				option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data());
368
 
369
			e.preventDefault();
370
			$target
371
				.modal(option)
372
				.one('hide', function () {
373
					$this.focus();
374
				})
375
		});
376
	});
377
 
378
}(window.jQuery);