integration/lib/jquery-ui/ui/jquery.ui.dialog.js
changeset 11 e5feaa369ccc
parent 10 34df8e58b6fc
parent 9 e3d551eda5a6
child 12 0a242859c85b
equal deleted inserted replaced
10:34df8e58b6fc 11:e5feaa369ccc
     1 /*!
       
     2  * jQuery UI Dialog 1.10.3
       
     3  * http://jqueryui.com
       
     4  *
       
     5  * Copyright 2013 jQuery Foundation and other contributors
       
     6  * Released under the MIT license.
       
     7  * http://jquery.org/license
       
     8  *
       
     9  * http://api.jqueryui.com/dialog/
       
    10  *
       
    11  * Depends:
       
    12  *	jquery.ui.core.js
       
    13  *	jquery.ui.widget.js
       
    14  *  jquery.ui.button.js
       
    15  *	jquery.ui.draggable.js
       
    16  *	jquery.ui.mouse.js
       
    17  *	jquery.ui.position.js
       
    18  *	jquery.ui.resizable.js
       
    19  */
       
    20 (function( $, undefined ) {
       
    21 
       
    22 var sizeRelatedOptions = {
       
    23 		buttons: true,
       
    24 		height: true,
       
    25 		maxHeight: true,
       
    26 		maxWidth: true,
       
    27 		minHeight: true,
       
    28 		minWidth: true,
       
    29 		width: true
       
    30 	},
       
    31 	resizableRelatedOptions = {
       
    32 		maxHeight: true,
       
    33 		maxWidth: true,
       
    34 		minHeight: true,
       
    35 		minWidth: true
       
    36 	};
       
    37 
       
    38 $.widget( "ui.dialog", {
       
    39 	version: "1.10.3",
       
    40 	options: {
       
    41 		appendTo: "body",
       
    42 		autoOpen: true,
       
    43 		buttons: [],
       
    44 		closeOnEscape: true,
       
    45 		closeText: "close",
       
    46 		dialogClass: "",
       
    47 		draggable: true,
       
    48 		hide: null,
       
    49 		height: "auto",
       
    50 		maxHeight: null,
       
    51 		maxWidth: null,
       
    52 		minHeight: 150,
       
    53 		minWidth: 150,
       
    54 		modal: false,
       
    55 		position: {
       
    56 			my: "center",
       
    57 			at: "center",
       
    58 			of: window,
       
    59 			collision: "fit",
       
    60 			// Ensure the titlebar is always visible
       
    61 			using: function( pos ) {
       
    62 				var topOffset = $( this ).css( pos ).offset().top;
       
    63 				if ( topOffset < 0 ) {
       
    64 					$( this ).css( "top", pos.top - topOffset );
       
    65 				}
       
    66 			}
       
    67 		},
       
    68 		resizable: true,
       
    69 		show: null,
       
    70 		title: null,
       
    71 		width: 300,
       
    72 
       
    73 		// callbacks
       
    74 		beforeClose: null,
       
    75 		close: null,
       
    76 		drag: null,
       
    77 		dragStart: null,
       
    78 		dragStop: null,
       
    79 		focus: null,
       
    80 		open: null,
       
    81 		resize: null,
       
    82 		resizeStart: null,
       
    83 		resizeStop: null
       
    84 	},
       
    85 
       
    86 	_create: function() {
       
    87 		this.originalCss = {
       
    88 			display: this.element[0].style.display,
       
    89 			width: this.element[0].style.width,
       
    90 			minHeight: this.element[0].style.minHeight,
       
    91 			maxHeight: this.element[0].style.maxHeight,
       
    92 			height: this.element[0].style.height
       
    93 		};
       
    94 		this.originalPosition = {
       
    95 			parent: this.element.parent(),
       
    96 			index: this.element.parent().children().index( this.element )
       
    97 		};
       
    98 		this.originalTitle = this.element.attr("title");
       
    99 		this.options.title = this.options.title || this.originalTitle;
       
   100 
       
   101 		this._createWrapper();
       
   102 
       
   103 		this.element
       
   104 			.show()
       
   105 			.removeAttr("title")
       
   106 			.addClass("ui-dialog-content ui-widget-content")
       
   107 			.appendTo( this.uiDialog );
       
   108 
       
   109 		this._createTitlebar();
       
   110 		this._createButtonPane();
       
   111 
       
   112 		if ( this.options.draggable && $.fn.draggable ) {
       
   113 			this._makeDraggable();
       
   114 		}
       
   115 		if ( this.options.resizable && $.fn.resizable ) {
       
   116 			this._makeResizable();
       
   117 		}
       
   118 
       
   119 		this._isOpen = false;
       
   120 	},
       
   121 
       
   122 	_init: function() {
       
   123 		if ( this.options.autoOpen ) {
       
   124 			this.open();
       
   125 		}
       
   126 	},
       
   127 
       
   128 	_appendTo: function() {
       
   129 		var element = this.options.appendTo;
       
   130 		if ( element && (element.jquery || element.nodeType) ) {
       
   131 			return $( element );
       
   132 		}
       
   133 		return this.document.find( element || "body" ).eq( 0 );
       
   134 	},
       
   135 
       
   136 	_destroy: function() {
       
   137 		var next,
       
   138 			originalPosition = this.originalPosition;
       
   139 
       
   140 		this._destroyOverlay();
       
   141 
       
   142 		this.element
       
   143 			.removeUniqueId()
       
   144 			.removeClass("ui-dialog-content ui-widget-content")
       
   145 			.css( this.originalCss )
       
   146 			// Without detaching first, the following becomes really slow
       
   147 			.detach();
       
   148 
       
   149 		this.uiDialog.stop( true, true ).remove();
       
   150 
       
   151 		if ( this.originalTitle ) {
       
   152 			this.element.attr( "title", this.originalTitle );
       
   153 		}
       
   154 
       
   155 		next = originalPosition.parent.children().eq( originalPosition.index );
       
   156 		// Don't try to place the dialog next to itself (#8613)
       
   157 		if ( next.length && next[0] !== this.element[0] ) {
       
   158 			next.before( this.element );
       
   159 		} else {
       
   160 			originalPosition.parent.append( this.element );
       
   161 		}
       
   162 	},
       
   163 
       
   164 	widget: function() {
       
   165 		return this.uiDialog;
       
   166 	},
       
   167 
       
   168 	disable: $.noop,
       
   169 	enable: $.noop,
       
   170 
       
   171 	close: function( event ) {
       
   172 		var that = this;
       
   173 
       
   174 		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
       
   175 			return;
       
   176 		}
       
   177 
       
   178 		this._isOpen = false;
       
   179 		this._destroyOverlay();
       
   180 
       
   181 		if ( !this.opener.filter(":focusable").focus().length ) {
       
   182 			// Hiding a focused element doesn't trigger blur in WebKit
       
   183 			// so in case we have nothing to focus on, explicitly blur the active element
       
   184 			// https://bugs.webkit.org/show_bug.cgi?id=47182
       
   185 			$( this.document[0].activeElement ).blur();
       
   186 		}
       
   187 
       
   188 		this._hide( this.uiDialog, this.options.hide, function() {
       
   189 			that._trigger( "close", event );
       
   190 		});
       
   191 	},
       
   192 
       
   193 	isOpen: function() {
       
   194 		return this._isOpen;
       
   195 	},
       
   196 
       
   197 	moveToTop: function() {
       
   198 		this._moveToTop();
       
   199 	},
       
   200 
       
   201 	_moveToTop: function( event, silent ) {
       
   202 		var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
       
   203 		if ( moved && !silent ) {
       
   204 			this._trigger( "focus", event );
       
   205 		}
       
   206 		return moved;
       
   207 	},
       
   208 
       
   209 	open: function() {
       
   210 		var that = this;
       
   211 		if ( this._isOpen ) {
       
   212 			if ( this._moveToTop() ) {
       
   213 				this._focusTabbable();
       
   214 			}
       
   215 			return;
       
   216 		}
       
   217 
       
   218 		this._isOpen = true;
       
   219 		this.opener = $( this.document[0].activeElement );
       
   220 
       
   221 		this._size();
       
   222 		this._position();
       
   223 		this._createOverlay();
       
   224 		this._moveToTop( null, true );
       
   225 		this._show( this.uiDialog, this.options.show, function() {
       
   226 			that._focusTabbable();
       
   227 			that._trigger("focus");
       
   228 		});
       
   229 
       
   230 		this._trigger("open");
       
   231 	},
       
   232 
       
   233 	_focusTabbable: function() {
       
   234 		// Set focus to the first match:
       
   235 		// 1. First element inside the dialog matching [autofocus]
       
   236 		// 2. Tabbable element inside the content element
       
   237 		// 3. Tabbable element inside the buttonpane
       
   238 		// 4. The close button
       
   239 		// 5. The dialog itself
       
   240 		var hasFocus = this.element.find("[autofocus]");
       
   241 		if ( !hasFocus.length ) {
       
   242 			hasFocus = this.element.find(":tabbable");
       
   243 		}
       
   244 		if ( !hasFocus.length ) {
       
   245 			hasFocus = this.uiDialogButtonPane.find(":tabbable");
       
   246 		}
       
   247 		if ( !hasFocus.length ) {
       
   248 			hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
       
   249 		}
       
   250 		if ( !hasFocus.length ) {
       
   251 			hasFocus = this.uiDialog;
       
   252 		}
       
   253 		hasFocus.eq( 0 ).focus();
       
   254 	},
       
   255 
       
   256 	_keepFocus: function( event ) {
       
   257 		function checkFocus() {
       
   258 			var activeElement = this.document[0].activeElement,
       
   259 				isActive = this.uiDialog[0] === activeElement ||
       
   260 					$.contains( this.uiDialog[0], activeElement );
       
   261 			if ( !isActive ) {
       
   262 				this._focusTabbable();
       
   263 			}
       
   264 		}
       
   265 		event.preventDefault();
       
   266 		checkFocus.call( this );
       
   267 		// support: IE
       
   268 		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
       
   269 		// so we check again later
       
   270 		this._delay( checkFocus );
       
   271 	},
       
   272 
       
   273 	_createWrapper: function() {
       
   274 		this.uiDialog = $("<div>")
       
   275 			.addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
       
   276 				this.options.dialogClass )
       
   277 			.hide()
       
   278 			.attr({
       
   279 				// Setting tabIndex makes the div focusable
       
   280 				tabIndex: -1,
       
   281 				role: "dialog"
       
   282 			})
       
   283 			.appendTo( this._appendTo() );
       
   284 
       
   285 		this._on( this.uiDialog, {
       
   286 			keydown: function( event ) {
       
   287 				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
       
   288 						event.keyCode === $.ui.keyCode.ESCAPE ) {
       
   289 					event.preventDefault();
       
   290 					this.close( event );
       
   291 					return;
       
   292 				}
       
   293 
       
   294 				// prevent tabbing out of dialogs
       
   295 				if ( event.keyCode !== $.ui.keyCode.TAB ) {
       
   296 					return;
       
   297 				}
       
   298 				var tabbables = this.uiDialog.find(":tabbable"),
       
   299 					first = tabbables.filter(":first"),
       
   300 					last  = tabbables.filter(":last");
       
   301 
       
   302 				if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
       
   303 					first.focus( 1 );
       
   304 					event.preventDefault();
       
   305 				} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
       
   306 					last.focus( 1 );
       
   307 					event.preventDefault();
       
   308 				}
       
   309 			},
       
   310 			mousedown: function( event ) {
       
   311 				if ( this._moveToTop( event ) ) {
       
   312 					this._focusTabbable();
       
   313 				}
       
   314 			}
       
   315 		});
       
   316 
       
   317 		// We assume that any existing aria-describedby attribute means
       
   318 		// that the dialog content is marked up properly
       
   319 		// otherwise we brute force the content as the description
       
   320 		if ( !this.element.find("[aria-describedby]").length ) {
       
   321 			this.uiDialog.attr({
       
   322 				"aria-describedby": this.element.uniqueId().attr("id")
       
   323 			});
       
   324 		}
       
   325 	},
       
   326 
       
   327 	_createTitlebar: function() {
       
   328 		var uiDialogTitle;
       
   329 
       
   330 		this.uiDialogTitlebar = $("<div>")
       
   331 			.addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
       
   332 			.prependTo( this.uiDialog );
       
   333 		this._on( this.uiDialogTitlebar, {
       
   334 			mousedown: function( event ) {
       
   335 				// Don't prevent click on close button (#8838)
       
   336 				// Focusing a dialog that is partially scrolled out of view
       
   337 				// causes the browser to scroll it into view, preventing the click event
       
   338 				if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) {
       
   339 					// Dialog isn't getting focus when dragging (#8063)
       
   340 					this.uiDialog.focus();
       
   341 				}
       
   342 			}
       
   343 		});
       
   344 
       
   345 		this.uiDialogTitlebarClose = $("<button></button>")
       
   346 			.button({
       
   347 				label: this.options.closeText,
       
   348 				icons: {
       
   349 					primary: "ui-icon-closethick"
       
   350 				},
       
   351 				text: false
       
   352 			})
       
   353 			.addClass("ui-dialog-titlebar-close")
       
   354 			.appendTo( this.uiDialogTitlebar );
       
   355 		this._on( this.uiDialogTitlebarClose, {
       
   356 			click: function( event ) {
       
   357 				event.preventDefault();
       
   358 				this.close( event );
       
   359 			}
       
   360 		});
       
   361 
       
   362 		uiDialogTitle = $("<span>")
       
   363 			.uniqueId()
       
   364 			.addClass("ui-dialog-title")
       
   365 			.prependTo( this.uiDialogTitlebar );
       
   366 		this._title( uiDialogTitle );
       
   367 
       
   368 		this.uiDialog.attr({
       
   369 			"aria-labelledby": uiDialogTitle.attr("id")
       
   370 		});
       
   371 	},
       
   372 
       
   373 	_title: function( title ) {
       
   374 		if ( !this.options.title ) {
       
   375 			title.html("&#160;");
       
   376 		}
       
   377 		title.text( this.options.title );
       
   378 	},
       
   379 
       
   380 	_createButtonPane: function() {
       
   381 		this.uiDialogButtonPane = $("<div>")
       
   382 			.addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
       
   383 
       
   384 		this.uiButtonSet = $("<div>")
       
   385 			.addClass("ui-dialog-buttonset")
       
   386 			.appendTo( this.uiDialogButtonPane );
       
   387 
       
   388 		this._createButtons();
       
   389 	},
       
   390 
       
   391 	_createButtons: function() {
       
   392 		var that = this,
       
   393 			buttons = this.options.buttons;
       
   394 
       
   395 		// if we already have a button pane, remove it
       
   396 		this.uiDialogButtonPane.remove();
       
   397 		this.uiButtonSet.empty();
       
   398 
       
   399 		if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
       
   400 			this.uiDialog.removeClass("ui-dialog-buttons");
       
   401 			return;
       
   402 		}
       
   403 
       
   404 		$.each( buttons, function( name, props ) {
       
   405 			var click, buttonOptions;
       
   406 			props = $.isFunction( props ) ?
       
   407 				{ click: props, text: name } :
       
   408 				props;
       
   409 			// Default to a non-submitting button
       
   410 			props = $.extend( { type: "button" }, props );
       
   411 			// Change the context for the click callback to be the main element
       
   412 			click = props.click;
       
   413 			props.click = function() {
       
   414 				click.apply( that.element[0], arguments );
       
   415 			};
       
   416 			buttonOptions = {
       
   417 				icons: props.icons,
       
   418 				text: props.showText
       
   419 			};
       
   420 			delete props.icons;
       
   421 			delete props.showText;
       
   422 			$( "<button></button>", props )
       
   423 				.button( buttonOptions )
       
   424 				.appendTo( that.uiButtonSet );
       
   425 		});
       
   426 		this.uiDialog.addClass("ui-dialog-buttons");
       
   427 		this.uiDialogButtonPane.appendTo( this.uiDialog );
       
   428 	},
       
   429 
       
   430 	_makeDraggable: function() {
       
   431 		var that = this,
       
   432 			options = this.options;
       
   433 
       
   434 		function filteredUi( ui ) {
       
   435 			return {
       
   436 				position: ui.position,
       
   437 				offset: ui.offset
       
   438 			};
       
   439 		}
       
   440 
       
   441 		this.uiDialog.draggable({
       
   442 			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
       
   443 			handle: ".ui-dialog-titlebar",
       
   444 			containment: "document",
       
   445 			start: function( event, ui ) {
       
   446 				$( this ).addClass("ui-dialog-dragging");
       
   447 				that._blockFrames();
       
   448 				that._trigger( "dragStart", event, filteredUi( ui ) );
       
   449 			},
       
   450 			drag: function( event, ui ) {
       
   451 				that._trigger( "drag", event, filteredUi( ui ) );
       
   452 			},
       
   453 			stop: function( event, ui ) {
       
   454 				options.position = [
       
   455 					ui.position.left - that.document.scrollLeft(),
       
   456 					ui.position.top - that.document.scrollTop()
       
   457 				];
       
   458 				$( this ).removeClass("ui-dialog-dragging");
       
   459 				that._unblockFrames();
       
   460 				that._trigger( "dragStop", event, filteredUi( ui ) );
       
   461 			}
       
   462 		});
       
   463 	},
       
   464 
       
   465 	_makeResizable: function() {
       
   466 		var that = this,
       
   467 			options = this.options,
       
   468 			handles = options.resizable,
       
   469 			// .ui-resizable has position: relative defined in the stylesheet
       
   470 			// but dialogs have to use absolute or fixed positioning
       
   471 			position = this.uiDialog.css("position"),
       
   472 			resizeHandles = typeof handles === "string" ?
       
   473 				handles	:
       
   474 				"n,e,s,w,se,sw,ne,nw";
       
   475 
       
   476 		function filteredUi( ui ) {
       
   477 			return {
       
   478 				originalPosition: ui.originalPosition,
       
   479 				originalSize: ui.originalSize,
       
   480 				position: ui.position,
       
   481 				size: ui.size
       
   482 			};
       
   483 		}
       
   484 
       
   485 		this.uiDialog.resizable({
       
   486 			cancel: ".ui-dialog-content",
       
   487 			containment: "document",
       
   488 			alsoResize: this.element,
       
   489 			maxWidth: options.maxWidth,
       
   490 			maxHeight: options.maxHeight,
       
   491 			minWidth: options.minWidth,
       
   492 			minHeight: this._minHeight(),
       
   493 			handles: resizeHandles,
       
   494 			start: function( event, ui ) {
       
   495 				$( this ).addClass("ui-dialog-resizing");
       
   496 				that._blockFrames();
       
   497 				that._trigger( "resizeStart", event, filteredUi( ui ) );
       
   498 			},
       
   499 			resize: function( event, ui ) {
       
   500 				that._trigger( "resize", event, filteredUi( ui ) );
       
   501 			},
       
   502 			stop: function( event, ui ) {
       
   503 				options.height = $( this ).height();
       
   504 				options.width = $( this ).width();
       
   505 				$( this ).removeClass("ui-dialog-resizing");
       
   506 				that._unblockFrames();
       
   507 				that._trigger( "resizeStop", event, filteredUi( ui ) );
       
   508 			}
       
   509 		})
       
   510 		.css( "position", position );
       
   511 	},
       
   512 
       
   513 	_minHeight: function() {
       
   514 		var options = this.options;
       
   515 
       
   516 		return options.height === "auto" ?
       
   517 			options.minHeight :
       
   518 			Math.min( options.minHeight, options.height );
       
   519 	},
       
   520 
       
   521 	_position: function() {
       
   522 		// Need to show the dialog to get the actual offset in the position plugin
       
   523 		var isVisible = this.uiDialog.is(":visible");
       
   524 		if ( !isVisible ) {
       
   525 			this.uiDialog.show();
       
   526 		}
       
   527 		this.uiDialog.position( this.options.position );
       
   528 		if ( !isVisible ) {
       
   529 			this.uiDialog.hide();
       
   530 		}
       
   531 	},
       
   532 
       
   533 	_setOptions: function( options ) {
       
   534 		var that = this,
       
   535 			resize = false,
       
   536 			resizableOptions = {};
       
   537 
       
   538 		$.each( options, function( key, value ) {
       
   539 			that._setOption( key, value );
       
   540 
       
   541 			if ( key in sizeRelatedOptions ) {
       
   542 				resize = true;
       
   543 			}
       
   544 			if ( key in resizableRelatedOptions ) {
       
   545 				resizableOptions[ key ] = value;
       
   546 			}
       
   547 		});
       
   548 
       
   549 		if ( resize ) {
       
   550 			this._size();
       
   551 			this._position();
       
   552 		}
       
   553 		if ( this.uiDialog.is(":data(ui-resizable)") ) {
       
   554 			this.uiDialog.resizable( "option", resizableOptions );
       
   555 		}
       
   556 	},
       
   557 
       
   558 	_setOption: function( key, value ) {
       
   559 		/*jshint maxcomplexity:15*/
       
   560 		var isDraggable, isResizable,
       
   561 			uiDialog = this.uiDialog;
       
   562 
       
   563 		if ( key === "dialogClass" ) {
       
   564 			uiDialog
       
   565 				.removeClass( this.options.dialogClass )
       
   566 				.addClass( value );
       
   567 		}
       
   568 
       
   569 		if ( key === "disabled" ) {
       
   570 			return;
       
   571 		}
       
   572 
       
   573 		this._super( key, value );
       
   574 
       
   575 		if ( key === "appendTo" ) {
       
   576 			this.uiDialog.appendTo( this._appendTo() );
       
   577 		}
       
   578 
       
   579 		if ( key === "buttons" ) {
       
   580 			this._createButtons();
       
   581 		}
       
   582 
       
   583 		if ( key === "closeText" ) {
       
   584 			this.uiDialogTitlebarClose.button({
       
   585 				// Ensure that we always pass a string
       
   586 				label: "" + value
       
   587 			});
       
   588 		}
       
   589 
       
   590 		if ( key === "draggable" ) {
       
   591 			isDraggable = uiDialog.is(":data(ui-draggable)");
       
   592 			if ( isDraggable && !value ) {
       
   593 				uiDialog.draggable("destroy");
       
   594 			}
       
   595 
       
   596 			if ( !isDraggable && value ) {
       
   597 				this._makeDraggable();
       
   598 			}
       
   599 		}
       
   600 
       
   601 		if ( key === "position" ) {
       
   602 			this._position();
       
   603 		}
       
   604 
       
   605 		if ( key === "resizable" ) {
       
   606 			// currently resizable, becoming non-resizable
       
   607 			isResizable = uiDialog.is(":data(ui-resizable)");
       
   608 			if ( isResizable && !value ) {
       
   609 				uiDialog.resizable("destroy");
       
   610 			}
       
   611 
       
   612 			// currently resizable, changing handles
       
   613 			if ( isResizable && typeof value === "string" ) {
       
   614 				uiDialog.resizable( "option", "handles", value );
       
   615 			}
       
   616 
       
   617 			// currently non-resizable, becoming resizable
       
   618 			if ( !isResizable && value !== false ) {
       
   619 				this._makeResizable();
       
   620 			}
       
   621 		}
       
   622 
       
   623 		if ( key === "title" ) {
       
   624 			this._title( this.uiDialogTitlebar.find(".ui-dialog-title") );
       
   625 		}
       
   626 	},
       
   627 
       
   628 	_size: function() {
       
   629 		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
       
   630 		// divs will both have width and height set, so we need to reset them
       
   631 		var nonContentHeight, minContentHeight, maxContentHeight,
       
   632 			options = this.options;
       
   633 
       
   634 		// Reset content sizing
       
   635 		this.element.show().css({
       
   636 			width: "auto",
       
   637 			minHeight: 0,
       
   638 			maxHeight: "none",
       
   639 			height: 0
       
   640 		});
       
   641 
       
   642 		if ( options.minWidth > options.width ) {
       
   643 			options.width = options.minWidth;
       
   644 		}
       
   645 
       
   646 		// reset wrapper sizing
       
   647 		// determine the height of all the non-content elements
       
   648 		nonContentHeight = this.uiDialog.css({
       
   649 				height: "auto",
       
   650 				width: options.width
       
   651 			})
       
   652 			.outerHeight();
       
   653 		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
       
   654 		maxContentHeight = typeof options.maxHeight === "number" ?
       
   655 			Math.max( 0, options.maxHeight - nonContentHeight ) :
       
   656 			"none";
       
   657 
       
   658 		if ( options.height === "auto" ) {
       
   659 			this.element.css({
       
   660 				minHeight: minContentHeight,
       
   661 				maxHeight: maxContentHeight,
       
   662 				height: "auto"
       
   663 			});
       
   664 		} else {
       
   665 			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
       
   666 		}
       
   667 
       
   668 		if (this.uiDialog.is(":data(ui-resizable)") ) {
       
   669 			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
       
   670 		}
       
   671 	},
       
   672 
       
   673 	_blockFrames: function() {
       
   674 		this.iframeBlocks = this.document.find( "iframe" ).map(function() {
       
   675 			var iframe = $( this );
       
   676 
       
   677 			return $( "<div>" )
       
   678 				.css({
       
   679 					position: "absolute",
       
   680 					width: iframe.outerWidth(),
       
   681 					height: iframe.outerHeight()
       
   682 				})
       
   683 				.appendTo( iframe.parent() )
       
   684 				.offset( iframe.offset() )[0];
       
   685 		});
       
   686 	},
       
   687 
       
   688 	_unblockFrames: function() {
       
   689 		if ( this.iframeBlocks ) {
       
   690 			this.iframeBlocks.remove();
       
   691 			delete this.iframeBlocks;
       
   692 		}
       
   693 	},
       
   694 
       
   695 	_allowInteraction: function( event ) {
       
   696 		if ( $( event.target ).closest(".ui-dialog").length ) {
       
   697 			return true;
       
   698 		}
       
   699 
       
   700 		// TODO: Remove hack when datepicker implements
       
   701 		// the .ui-front logic (#8989)
       
   702 		return !!$( event.target ).closest(".ui-datepicker").length;
       
   703 	},
       
   704 
       
   705 	_createOverlay: function() {
       
   706 		if ( !this.options.modal ) {
       
   707 			return;
       
   708 		}
       
   709 
       
   710 		var that = this,
       
   711 			widgetFullName = this.widgetFullName;
       
   712 		if ( !$.ui.dialog.overlayInstances ) {
       
   713 			// Prevent use of anchors and inputs.
       
   714 			// We use a delay in case the overlay is created from an
       
   715 			// event that we're going to be cancelling. (#2804)
       
   716 			this._delay(function() {
       
   717 				// Handle .dialog().dialog("close") (#4065)
       
   718 				if ( $.ui.dialog.overlayInstances ) {
       
   719 					this.document.bind( "focusin.dialog", function( event ) {
       
   720 						if ( !that._allowInteraction( event ) ) {
       
   721 							event.preventDefault();
       
   722 							$(".ui-dialog:visible:last .ui-dialog-content")
       
   723 								.data( widgetFullName )._focusTabbable();
       
   724 						}
       
   725 					});
       
   726 				}
       
   727 			});
       
   728 		}
       
   729 
       
   730 		this.overlay = $("<div>")
       
   731 			.addClass("ui-widget-overlay ui-front")
       
   732 			.appendTo( this._appendTo() );
       
   733 		this._on( this.overlay, {
       
   734 			mousedown: "_keepFocus"
       
   735 		});
       
   736 		$.ui.dialog.overlayInstances++;
       
   737 	},
       
   738 
       
   739 	_destroyOverlay: function() {
       
   740 		if ( !this.options.modal ) {
       
   741 			return;
       
   742 		}
       
   743 
       
   744 		if ( this.overlay ) {
       
   745 			$.ui.dialog.overlayInstances--;
       
   746 
       
   747 			if ( !$.ui.dialog.overlayInstances ) {
       
   748 				this.document.unbind( "focusin.dialog" );
       
   749 			}
       
   750 			this.overlay.remove();
       
   751 			this.overlay = null;
       
   752 		}
       
   753 	}
       
   754 });
       
   755 
       
   756 $.ui.dialog.overlayInstances = 0;
       
   757 
       
   758 // DEPRECATED
       
   759 if ( $.uiBackCompat !== false ) {
       
   760 	// position option with array notation
       
   761 	// just override with old implementation
       
   762 	$.widget( "ui.dialog", $.ui.dialog, {
       
   763 		_position: function() {
       
   764 			var position = this.options.position,
       
   765 				myAt = [],
       
   766 				offset = [ 0, 0 ],
       
   767 				isVisible;
       
   768 
       
   769 			if ( position ) {
       
   770 				if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
       
   771 					myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
       
   772 					if ( myAt.length === 1 ) {
       
   773 						myAt[1] = myAt[0];
       
   774 					}
       
   775 
       
   776 					$.each( [ "left", "top" ], function( i, offsetPosition ) {
       
   777 						if ( +myAt[ i ] === myAt[ i ] ) {
       
   778 							offset[ i ] = myAt[ i ];
       
   779 							myAt[ i ] = offsetPosition;
       
   780 						}
       
   781 					});
       
   782 
       
   783 					position = {
       
   784 						my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
       
   785 							myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
       
   786 						at: myAt.join(" ")
       
   787 					};
       
   788 				}
       
   789 
       
   790 				position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
       
   791 			} else {
       
   792 				position = $.ui.dialog.prototype.options.position;
       
   793 			}
       
   794 
       
   795 			// need to show the dialog to get the actual offset in the position plugin
       
   796 			isVisible = this.uiDialog.is(":visible");
       
   797 			if ( !isVisible ) {
       
   798 				this.uiDialog.show();
       
   799 			}
       
   800 			this.uiDialog.position( position );
       
   801 			if ( !isVisible ) {
       
   802 				this.uiDialog.hide();
       
   803 			}
       
   804 		}
       
   805 	});
       
   806 }
       
   807 
       
   808 }( jQuery ) );