PageSourceSearch

https://unitedhouse.net/javascript/jquery.simplemodal-1.4.3.js

js unitedhouse.net collected 2026-10-02 23:42:02 UTC 22,658 bytes, 710 lines download raw bytes

1/*
2 * SimpleModal 1.4.3 - jQuery Plugin
3 * http://simplemodal.com/
4 * Copyright (c) 2012 Eric Martin
5 * Licensed under MIT and GPL
6 * Date: Sat, Sep 8 2012 07:52:31 -0700
7 */
8
9/**
10 * SimpleModal is a lightweight jQuery plugin that provides a simple
11 * interface to create a modal dialog.
12 *
13 * The goal of SimpleModal is to provide developers with a cross-browser
14 * overlay and container that will be populated with data provided to
15 * SimpleModal.
16 *
17 * There are two ways to call SimpleModal:
18 * 1) As a chained function on a jQuery object, like $('#myDiv').modal();.
19 * This call would place the DOM object, #myDiv, inside a modal dialog.
20 * Chaining requires a jQuery object. An optional options object can be
21 * passed as a parameter.
22 *
23 * @example $('<div>my data</div>').modal({options});
24 * @example $('#myDiv').modal({options});
25 * @example jQueryObject.modal({options});
26 *
27 * 2) As a stand-alone function, like $.modal(data). The data parameter
28 * is required and an optional options object can be passed as a second
29 * parameter. This method provides more flexibility in the types of data
30 * that are allowed. The data could be a DOM object, a jQuery object, HTML
31 * or a string.
32 *
33 * @example $.modal('<div>my data</div>', {options});
34 * @example $.modal('my data', {options});
35 * @example $.modal($('#myDiv'), {options});
36 * @example $.modal(jQueryObject, {options});
37 * @example $.modal(document.getElementById('myDiv'), {options});
38 *
39 * A SimpleModal call can contain multiple elements, but only one modal
40 * dialog can be created at a time. Which means that all of the matched
41 * elements will be displayed within the modal container.
42 *
43 * SimpleModal internally sets the CSS needed to display the modal dialog
44 * properly in all browsers, yet provides the developer with the flexibility
45 * to easily control the look and feel. The styling for SimpleModal can be
46 * done through external stylesheets, or through SimpleModal, using the
47 * overlayCss, containerCss, and dataCss options.
48 *
49 * SimpleModal has been tested in the following browsers:
50 * - IE 6+
51 * - Firefox 2+
52 * - Opera 9+
53 * - Safari 3+
54 * - Chrome 1+
55 *
56 * @name SimpleModal
57 * @type jQuery
58 * @requires jQuery v1.3
59 * @cat Plugins/Windows and Overlays
60 * @author Eric Martin (http://ericmmartin.com)
61 * @version 1.4.3
62 */
63
64;(function (factory) {
65	if (typeof define === 'function' && define.amd) {
66		// AMD. Register as an anonymous module.
67		define(['jquery'], factory);
68	} else {
69		// Browser globals
70		factory(jQuery);
71	}
72}
73(function ($) {
74	var d = [],
75		doc = $(document),
76		ie6 = $.browser.msie && parseInt($.browser.version) === 6 && typeof window['XMLHttpRequest'] !== 'object',
77		ie7 = $.browser.msie && parseInt($.browser.version) === 7,
78		ieQuirks = null,
79		wndw = $(window),
80		w = [];
81
82	/*
83	 * Create and display a modal dialog.
84	 *
85	 * @param {string, object} data A string, jQuery object or DOM object
86	 * @param {object} [options] An optional object containing options overrides
87	 */
88	$.modal = function (data, options) {
89		return $.modal.impl.init(data, options);
90	};
91
92	/*
93	 * Close the modal dialog.
94	 */
95	$.modal.close = function () {
96		$.modal.impl.close();
97	};
98
99	/*
100	 * Set focus on first or last visible input in the modal dialog. To focus on the last
101	 * element, call $.modal.focus('last'). If no input elements are found, focus is placed
102	 * on the data wrapper element.
103	 */
104	$.modal.focus = function (pos) {
105		$.modal.impl.focus(pos);
106	};
107
108	/*
109	 * Determine and set the dimensions of the modal dialog container.
110	 * setPosition() is called if the autoPosition option is true.
111	 */
112	$.modal.setContainerDimensions = function () {
113		$.modal.impl.setContainerDimensions();
114	};
115
116	/*
117	 * Re-position the modal dialog.
118	 */
119	$.modal.setPosition = function () {
120		$.modal.impl.setPosition();
121	};
122
123	/*
124	 * Update the modal dialog. If new dimensions are passed, they will be used to determine
125	 * the dimensions of the container.
126	 *
127	 * setContainerDimensions() is called, which in turn calls setPosition(), if enabled.
128	 * Lastly, focus() is called is the focus option is true.
129	 */
130	$.modal.update = function (height, width) {
131		$.modal.impl.update(height, width);
132	};
133
134	/*
135	 * Chained function to create a modal dialog.
136	 *
137	 * @param {object}
137 [options] An optional object containing options overrides
138	 */
139	$.fn.modal = function (options) {
140		return $.modal.impl.init(this, options);
141	};
142
143	/*
144	 * SimpleModal default options
145	 *
146	 * appendTo:		(String:'body') The jQuery selector to append the elements to. For .NET, use 'form'.
147	 * focus:			(Boolean:true) Focus in the first visible, enabled element?
148	 * opacity:			(Number:50) The opacity value for the overlay div, from 0 - 100
149	 * overlayId:		(String:'simplemodal-overlay') The DOM element id for the overlay div
150	 * overlayCss:		(Object:{}) The CSS styling for the overlay div
151	 * containerId:		(String:'simplemodal-container') The DOM element id for the container div
152	 * containerCss:	(Object:{}) The CSS styling for the container div
153	 * dataId:			(String:'simplemodal-data') The DOM element id for the data div
154	 * dataCss:			(Object:{}) The CSS styling for the data div
155	 * minHeight:		(Number:null) The minimum height for the container
156	 * minWidth:		(Number:null) The minimum width for the container
157	 * maxHeight:		(Number:null) The maximum height for the container. If not specified, the window height is used.
158	 * maxWidth:		(Number:null) The maximum width for the container. If not specified, the window width is used.
159	 * autoResize:		(Boolean:false) Automatically resize the container if it exceeds the browser window dimensions?
160	 * autoPosition:	(Boolean:true) Automatically position the container upon creation and on window resize?
161	 * zIndex:			(Number: 1000) Starting z-index value
162	 * close:			(Boolean:true) If true, closeHTML, escClose and overClose will be used if set.
163	 							If false, none of them will be used.
164	 * closeHTML:		(String:'<a class="modalCloseImg" title="Close"></a>') The HTML for the default close link.
165								SimpleModal will automatically add the closeClass to this element.
166	 * closeClass:		(String:'simplemodal-close') The CSS class used to bind to the close event
167	 * escClose:		(Boolean:true) Allow Esc keypress to close the dialog?
168	 * overlayClose:	(Boolean:false) Allow click on overlay to close the dialog?
169	 * fixed:			(Boolean:true) If true, the container will use a fixed position. If false, it will use a
170								absolute position (the dialog will scroll with the page)
171	 * position:		(Array:null) Position of container [top, left]. Can be number of pixels or percentage
172	 * persist:			(Boolean:false) Persist the data across modal calls? Only used for existing
173								DOM elements. If true, the data will be maintained across modal calls, if false,
174								the data will be reverted to its original state.
175	 * modal:			(Boolean:true) User will be unable to interact with the page below the modal or tab away from the dialog.
176								If false, the overlay, iframe, and certain events will be disabled allowing the user to interact
177								with the page below the dialog.
178	 * onOpen:			(Function:null) The callback function used in place of SimpleModal's open
179	 * onShow:			(Function:null) The callback function used after the modal dialog has opened
180	 * onClose:			(Function:null) The callback function used in place of SimpleModal's close
181	 */
182	$.modal.defaults = {
183		appendTo: 'body',
184		focus: true,
185		opacity: 50,
186		overlayId: 'simplemodal-overlay',
187		overlayCss: {},
188		containerId: 'simplemodal-container',
189		containerCss: {},
190		dataId: 'simplemodal-data',
191		dataCss: {},
192		minHeight: null,
193		minWidth: null,
194		maxHeight: null,
195		maxWidth: null,
196		autoResize: false,
197		autoPosition: true,
198		zIndex: 1000,
199		close: true,
200		closeHTML: '<a class="modalCloseImg" title="Close"></a>',
201		closeClass: 'simplemodal-close',
202		escClose: true,
203		overlayClose: false,
204		fixed: true,
205		position: null,
206		persist: false,
207		modal: true,
208		onOpen: null,
209		onShow: null,
210		onClose: null
211	};
212
213	/*
214	 * Main modal object
215	 * o = options
216	 */
217	$.modal.impl = {
218		/*
219		 * Contains the modal dialog elements and is the object passed
220		 * back to the callback (onOpen, onShow, onClose) functions
221		 */
222		d: {},
223		/*
224		 * Initialize the modal dialog
225		 */
226		init: function (data, options) {
227			var s = this;
228
229			// don't allow multiple calls
230			if (s.d.data) {
231				return false;
232			}
233
234			// $.support.boxModel is undefined if checked earlier
235			ieQuirks = $.browser.msie && !$.support.boxModel;
236
237			// merge defaults and user options
238			s.o = $.extend({}, $.modal.defaults, options);
239
240			// keep track of z-index
241			s.zIndex = s.o.zIndex;
242
243			// set the onClose callback flag
244			s.occb = false;
245
246			// determine how to handle the data based on its type
247			if (typeof data === 'object') {
248				// convert DOM object to a jQuery object
249				data = data instanceof $ ? data : $(data);
250				s.d.placeholder = false;
251
252				// if the object came from the DOM, keep track of its parent
253				if (data.parent().parent().size() > 0) {
254					data.before($('<span></span>')
255						.attr('id', 'simplemodal-placeholder')
256						.css({display: 'none'}));
257
258					s.d.placeholder = true;
259					s.display = data.css('display');
260
261					// persist changes? if not, make a clone of the element
262					if (!s.o.persist) {
263						s.d.orig = data.clone(true);
264					}
265				}
266			}
267			else if (typeof data === 'string' || typeof data === 'number') {
268				// just insert the data as innerHTML
269				data = $('<div></div>').html(data);
270			}
271			else {
272				// unsupported data type!
273				alert('SimpleModal Error: Unsupported data type: ' + typeof data);
274				return s;
275			}
276
277			// create the modal overlay, container and, if necessary, iframe
278			s.create(data);
279			data = null;
280
281			// display the modal dialog
282			s.open();
283
284			// useful for adding events/manipulating data in the modal dialog
285			if ($.isFunction(s.o.onShow)) {
286				s.o.onShow.apply(s, [s.d]);
287			}
288
289			// don't break the chain =)
290			return s;
291		},
292		/*
293		 * Create and add the modal overlay and container to the page
294		 */
295		create: function (data) {
296			var s = this;
297
298			// get the window properties
299			s.getDimensions();
300
301			// add an iframe to prevent select options from bleeding through
302			if (s.o.modal && ie6) {
303				s.d.iframe = $('<iframe src="javascript:false;"></iframe>')
304					.css($.extend(s.o.iframeCss, {
305						display: 'none',
306						opacity: 0,
307						position: 'fixed',
308						height: w[0],
309						width: w[1],
310						zIndex: s.o.zIndex,
311						top: 0,
312						left: 0
313					}))
314					.appendTo(s.o.appendTo);
315			}
316
317			// create the overlay
318			s.d.overlay = $('<div></div>')
319				.attr('id', s.o.overlayId)
320				.addClass('simplemodal-overlay')
321				.css($.extend(s.o.overlayCss, {
322					display: 'none',
323					opacity: s.o.opacity / 100,
324					height: s.o.modal ? d[0] : 0,
325					width: s.o.modal ? d[1] : 0,
326					position: 'fixed',
327					left: 0,
328					top: 0,
329					zIndex: s.o.zIndex + 1
330				}))
331				.appendTo(s.o.appendTo);
332
333			// create the container
334			s.d.container = $('<div></div>')
335				.attr('id', s.o.containerId)
336				.addClass('simplemodal-container')
337				.css($.extend(
338					{position: s.o.fixed ? 'fixed' : 'absolute'},
339					s.o.containerCss,
340					{display: 'none', zIndex: s.o.zIndex + 2}
341				))
342				.append(s.o.close && s.o.closeHTML
343					? $(s.o.closeHTML).addClass(s.o.closeClass)
344					: '')
345				.appendTo(s.o.appendTo);
346
347			s.d.wrap = $('<div></div>')
348				.attr('tabIndex', -1)
349				.addClass('simplemodal-wrap')
350				.css({height: '100%', outline: 0, width: '100%'})
351				.appendTo(s.d.container);
352
353			// add styling and attributes to the data
354			// append to body to get correct dimensions, then move to wrap
355			s.d.data = data
356				.attr('id', data.attr('id') || s.o.dataId)
357				.addClass('simplemodal-data')
358				.css($.extend(s.o.dataCss, {
359						display: 'none'
360				}))
361				.appendTo('body');
362			data = null;
363
364			s.setContainerDimensions();
365			s.d.data.appendTo(s.d.wrap);
366
367			// fix issues with IE
368			if (ie6 || ieQuirks) {
369				s.fixIE();
370			}
371		},
372		/*
373		 * Bind events
374		 */
375		bindEvents: function () {
376			var s = this;
377
378			// bind the close event to any element with the closeClass class
379			$('.' + s.o.closeClass).bind('click.simplemodal', function (e) {
380				e.preventDefault();
381				s.close();
382			});
383
384			// bind the overlay click to the close function, if enabled
385			if (s.o.modal && s.o.close && s.o.overlayClose) {
386				s.d.overlay.bind('click.simplemodal', function (e) {
387					e.preventDefault();
388					s.close();
389				});
390			}
391
392			// bind keydown events
393			doc.bind('keydown.simplemodal', function (e) {
394				if (s.o.modal && e.keyCode === 9) { // TAB
395					s.watchTab(e);
396				}
397				else if ((s.o.close && s.o.escClose) && e.keyCode === 27) { // ESC
398					e.preventDefault();
399					s.close();
400				}
401			});
402
403			// update window size
404			wndw.bind('resize.simplemodal orientationchange.simplemodal', function () {
405				// redetermine the window width/height
406				s.getDimensions();
407
408				// reposition the dialog
409				s.o.autoResize ? s.setContainerDimensions() : s.o.autoPosition && s.setPosition();
410
411				if (ie6 || ieQuirks) {
412					s.fixIE();
413				}
414				else if (s.o.modal) {
415					// update the iframe & overlay
416					s.d.iframe && s.d.iframe.css({height: w[0], width: w[1]});
417					s.d.overlay.css({height: d[0], width: d[1]});
418				}
419			});
420		},
421		/*
422		 * Unbind events
423		 */
424		unbindEvents: function () {
425			$('.' + this.o.closeClass).unbind('click.simplemodal');
426			doc.unbind('keydown.simplemodal');
427			wndw.unbind('.simplemodal');
428			this.d.overlay.unbind('click.simplemodal');
429		},
430		/*
431		 * Fix issues in IE6 and IE7 in quirks mode
432		 */
433		fixIE: function () {
434			var s = this, p = s.o.position;
435
436			// simulate fixed position - adapted from BlockUI
437			$.each([s.d.iframe || null, !s.o.modal ? null : s.d.overlay, s.d.container.css('position') === 'fixed' ? s.d.container : null], function (i, el) {
438				if (el) {
439					var bch = 'document.body.clientHeight', bcw = 'document.body.clientWidth',
440						bsh = 'document.body.scrollHeight', bsl = 'document.body.scrollLeft',
441						bst = 'document.body.scrollTop', bsw = 'document.body.scrollWidth',
442						ch = 'document.documentElement.clientHeight', cw = 'document.documentElement.clientWidth',
443						sl = 'document.documentElement.scrollLeft', st = 'document.documentElement.scrollTop',
444						s = el[0].style;
445
446					s.position = 'absolute';
447					if (i < 2) {
448						s.removeExpression('height');
449						s.removeExpression('width');
450						s.setExpression('height','' + bsh + ' > ' + bch + ' ? ' + bsh + ' : ' + bch + ' + "px"');
451						s.setExpression('width','' + bsw + ' > ' + bcw + ' ? ' + bsw + ' : ' + bcw + ' + "px"');
452					}
453					else {
454						var te, le;
455						if (p && p.constructor === Array) {
456							var top = p[0]
457								? typeof p[0] === 'number' ? p[0].toString() : p[0].replace(/px/, '')
458								: el.css('top').replace(/px/, '');
459							te = top.indexOf('%') === -1
460								? top + ' + (t = ' + st + ' ? ' + st + ' : ' + bst + ') + "px"'
461								: parseInt(top.replace(/%/, '')) + ' * ((' + ch + ' || ' + bch + ') / 100) + (t = ' + st + ' ? ' + st + ' : ' + bst + ') + "px"';
462
463							if (p[1]) {
464								var left = typeof p[1] === 'number' ? p[1].toString() : p[1].replace(/px/, '');
465								le = left.indexOf('%') === -1
466									? left + ' + (t = ' + sl + ' ? ' + sl + ' : ' + bsl + ') + "px"'
467									: parseInt(left.replace(/%/, '')) + ' * ((' + cw + ' || ' + bcw + ') / 100) + (t = ' + sl + ' ? ' + sl + ' : ' + bsl + ') + "px"';
468							}
469						}
470						else {
471							te = '(' + ch + ' || ' + bch + ') / 2 - (this.offsetHeight / 2) + (t = ' + st + ' ? ' + st + ' : ' + bst + ') + "px"';
472							le = '(' + cw + ' || ' + bcw + ') / 2 - (this.offsetWidth / 2) + (t = ' + sl + ' ? ' + sl + ' : ' + bsl + ') + "px"';
473						}
474						s.removeExpression('top');
475						s.removeExpression('left');
476						s.setExpression('top', te);
477						s.setExpression('left', le);
478					}
479				}
480			});
481		},
482		/*
483		 * Place focus on the first or last visible input
484		 */
485		focus: function (pos) {
486			var s = this, p = pos && $.inArray(pos, ['first', 'last']) !== -1 ? pos : 'first';
487
488			// focus on dialog or the first visible/enabled input element
489			var input = $(':input:enabled:visible:' + p, s.d.wrap);
490			setTimeout(function () {
491				input.length > 0 ? input.focus() : s.d.wrap.focus();
492			}, 10);
493		},
494		getDimensions: function () {
495			// fix a jQuery bug with determining the window height - use innerHeight if available
496			var s = this,
497				h = typeof window.innerHeight === 'undefined' ? wndw.height() : window.innerHeight;
498
499			d = [doc.height(), doc.width()];
500			w = [h, wndw.width()];
501		},
502		getVal: function (v, d) {
503			return v ? (typeof v === 'number' ? v
504					: v === 'auto' ? 0
505					: v.indexOf('%') > 0 ? ((parseInt(v.replace(/%/, '')) / 100) * (d === 'h' ? w[0] : w[1]))
506					: parseInt(v.replace(/px/, '')))
507				: null;
508		},
509		/*
510		 * Update the container. Set new dimensions, if provided.
511		 * Focus, if enabled. Re-bind events.
512		 */
513		update: function (height, width) {
514			var s = this;
515
516			// prevent update if dialog does not exist
517			if (!s.d.data) {
518				return false;
519			}
520
521			// reset orig values
522			s.d.origHeight = s.getVal(height, 'h');
523			s.d.origWidth = s.getVal(width, 'w');
524
525			// hide data to prevent screen flicker
526			s.d.data.hide();
527			height && s.d.container.css('height', height);
528			width && s.d.container.css('width', width);
529			s.setContainerDimensions();
530			s.d.data.show();
531			s.o.focus && s.focus();
532
533			// rebind events
534			s.unbindEvents();
535			s.bindEvents();
536		},
537		setContainerDimensions: function () {
538			var s = this,
539				badIE = ie6 || ie7;
540
541			// get the dimensions for the container and data
542			var ch = s.d.origHeight ? s.d.origHeight : $.browser.opera ? s.d.container.height() : s.getVal(badIE ? s.d.container[0].currentStyle['height'] : s.d.container.css('height'), 'h'),
543				cw = s.d.origWidth ? s.d.origWidth : $.browser.opera ? s.d.container.width() : s.getVal(badIE ? s.d.container[0].currentStyle['width'] : s.d.container.css('width'), 'w'),
544				dh = s.d.data.outerHeight(true), dw = s.d.data.outerWidth(true);
545
546			s.d.origHeight = s.d.origHeight || ch;
547			s.d.origWidth = s.d.origWidth || cw;
548
549			// mxoh = max option height, mxow = max option width
550			var mxoh = s.o.maxHeight ? s.getVal(s.o.maxHeight, 'h') : null,
551				mxow = s.o.maxWidth ? s.getVal(s.o.maxWidth, 'w') : null,
552				mh = mxoh && mxoh < w[0] ? mxoh : w[0],
553				mw = mxow && mxow < w[1] ? mxow : w[1];
554
555			// moh = min option height
556			var moh = s.o.minHeight ? s.getVal(s.o.minHeight, 'h') : 'auto';
557			if (!ch) {
558				if (!dh) {ch = moh;}
559				else {
560					if (dh > mh) {ch = mh;}
561					else if (s.o.minHeight && moh !== 'auto' && dh < moh) {ch = moh;}
562					else {ch = dh;}
563				}
564			}
565			else {
566				ch = s.o.autoResize && ch > mh ? mh : ch < moh ? moh : ch;
567			}
568
569			// mow = min option width
570			var mow = s.o.minWidth ? s.getVal(s.o.minWidth, 'w') : 'auto';
571			if (!cw) {
572				if (!dw) {cw = mow;}
573				else {
574					if (dw > mw) {cw = mw;}
575					else if (s.o.minWidth && mow !== 'auto' && dw < mow) {cw = mow;}
576					else {cw = dw;}
577				}
578			}
579			else {
580				cw = s.o.autoResize && cw > mw ? mw : cw < mow ? mow : cw;
581			}
582
583			s.d.container.css({height: ch, width: cw});
584			s.d.wrap.css({overflow: (dh > ch || dw > cw) ? 'auto' : 'visible'});
585			s.o.autoPosition && s.setPosition();
586		},
587		setPosition: function () {
588			var s = this, top, left,
589				hc = (w[0]/2) - (s.d.container.outerHeight(true)/2),
590				vc = (w[1]/2) - (s.d.container.outerWidth(true)/2),
591				st = s.d.container.css('position') !== 'fixed' ? wndw.scrollTop() : 0;
592
593			if (s.o.position && Object.prototype.toString.call(s.o.position) === '[object Array]') {
594				top = st + (s.o.position[0] || hc);
595				left = s.o.position[1] || vc;
596			} else {
597				top = st + hc;
598				left = vc;
599			}
600			s.d.container.css({left: left, top: top});
601		},
602		watchTab: function (e) {
603			var s = this;
604
605			if ($(e.target).parents('.simplemodal-container').length > 0) {
606				// save the list of inputs
607				s.inputs = $(':input:enabled:visible:first, :input:enabled:visible:last', s.d.data[0]);
608
609				// if it's the first or last tabbable element, refocus
610				if ((!e.shiftKey && e.target === s.inputs[s.inputs.length -1]) ||
611						(e.shiftKey && e.target === s.inputs[0]) ||
612						s.inputs.length === 0) {
613					e.preventDefault();
614					var pos = e.shiftKey ? 'last' : 'first';
615					s.focus(pos);
616				}
617			}
618			else {
619				// might be necessary when custom onShow callback is used
620				e.preventDefault();
621				s.focus();
622			}
623		},
624		/*
625		 * Open the modal dialog elements
626		 * - Note: If you use the onOpen callback, you must "show" the
627		 *         overlay and container elements manually
628		 *         (the iframe will be handled by SimpleModal)
629		 */
630		open: function () {
631			var s = this;
632			// display the iframe
633			s.d.iframe && s.d.iframe.show();
634
635			if ($.isFunction(s.o.onOpen)) {
636				// execute the onOpen callback
637				s.o.onOpen.apply(s, [s.d]);
638			}
639			else {
640				// display the remaining elements
641				s.d.overlay.show();
642				s.d.container.show();
643				s.d.data.show();
644			}
645
646			s.o.focus && s.focus();
647
648			// bind default events
649			s.bindEvents();
650		},
651		/*
652		 * Close the modal dialog
653		 * - Note: If you use an onClose callback, you must remove the
654		 *         overlay, container and iframe elements manually
655		 *
656		 * @param {boolean} external Indicates whether the call to this
657		 *     function was internal or external. If it was external, the
658		 *     onClose callback will be ignored
659		 */
660		close: function () {
661			var s = this;
662
663			// prevent close when dialog does not exist
664			if (!s.d.data) {
665				return false;
666			}
667
668			// remove the default events
669			s.unbindEvents();
670
671			if ($.isFunction(s.o.onClose) && !s.occb) {
672				// set the onClose callback flag
673				s.occb = true;
674
675				// execute the onClose callback
676				s.o.onClose.apply(s, [s.d]);
677			}
678			else {
679				// if the data came from the DOM, put it back
680				if (s.d.placeholder) {
681					var ph = $('#simplemodal-placeholder');
682					// save changes to the data?
683					if (s.o.persist) {
684						// insert the (possibly) modified data back into the DOM
685						ph.replaceWith(s.d.data.removeClass('simplemodal-data').css('display', s.display));
686					}
687					else {
688						// remove the current and insert the original,
689						// unmodified data back into the DOM
690						s.d.data.hide().remove();
691						ph.replaceWith(s.d.orig);
692					}
693				}
694				else {
695					// otherwise, remove it
696					s.d.data.hide().remove();
697				}
698
699				// remove the remaining elements
700				s.d.container.hide().remove();
701				s.d.overlay.hide();
702				s.d.iframe && s.d.iframe.hide().remove();
703				s.d.overlay.remove();
704
705				// reset the dialog object
706				s.d = {};
707			}
708		}
709	};
710}));

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.