Subversion Repositories Integrator Subversion

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 espaco 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);