PageSourceSearch

https://www.marilynholsing.com/bootstrap/js/bootstrap-modal.js

js marilynholsing.com collected 2026-10-05 02:07:54 UTC 9,659 bytes, 378 lines download raw bytes

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);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.