standard header in about page (#676)
[openemr.git] / public / assets / jquery-ui-1-12-1 / ui / widgets / dialog.js
blob27dccd2ad9362670ee7605cecd8137201ed8b4fb
1 /*!
2  * jQuery UI Dialog 1.12.1
3  * http://jqueryui.com
4  *
5  * Copyright jQuery Foundation and other contributors
6  * Released under the MIT license.
7  * http://jquery.org/license
8  */
10 //>>label: Dialog
11 //>>group: Widgets
12 //>>description: Displays customizable dialog windows.
13 //>>docs: http://api.jqueryui.com/dialog/
14 //>>demos: http://jqueryui.com/dialog/
15 //>>css.structure: ../../themes/base/core.css
16 //>>css.structure: ../../themes/base/dialog.css
17 //>>css.theme: ../../themes/base/theme.css
19 ( function( factory ) {
20         if ( typeof define === "function" && define.amd ) {
22                 // AMD. Register as an anonymous module.
23                 define( [
24                         "jquery",
25                         "./button",
26                         "./draggable",
27                         "./mouse",
28                         "./resizable",
29                         "../focusable",
30                         "../keycode",
31                         "../position",
32                         "../safe-active-element",
33                         "../safe-blur",
34                         "../tabbable",
35                         "../unique-id",
36                         "../version",
37                         "../widget"
38                 ], factory );
39         } else {
41                 // Browser globals
42                 factory( jQuery );
43         }
44 }( function( $ ) {
46 $.widget( "ui.dialog", {
47         version: "1.12.1",
48         options: {
49                 appendTo: "body",
50                 autoOpen: true,
51                 buttons: [],
52                 classes: {
53                         "ui-dialog": "ui-corner-all",
54                         "ui-dialog-titlebar": "ui-corner-all"
55                 },
56                 closeOnEscape: true,
57                 closeText: "Close",
58                 draggable: true,
59                 hide: null,
60                 height: "auto",
61                 maxHeight: null,
62                 maxWidth: null,
63                 minHeight: 150,
64                 minWidth: 150,
65                 modal: false,
66                 position: {
67                         my: "center",
68                         at: "center",
69                         of: window,
70                         collision: "fit",
72                         // Ensure the titlebar is always visible
73                         using: function( pos ) {
74                                 var topOffset = $( this ).css( pos ).offset().top;
75                                 if ( topOffset < 0 ) {
76                                         $( this ).css( "top", pos.top - topOffset );
77                                 }
78                         }
79                 },
80                 resizable: true,
81                 show: null,
82                 title: null,
83                 width: 300,
85                 // Callbacks
86                 beforeClose: null,
87                 close: null,
88                 drag: null,
89                 dragStart: null,
90                 dragStop: null,
91                 focus: null,
92                 open: null,
93                 resize: null,
94                 resizeStart: null,
95                 resizeStop: null
96         },
98         sizeRelatedOptions: {
99                 buttons: true,
100                 height: true,
101                 maxHeight: true,
102                 maxWidth: true,
103                 minHeight: true,
104                 minWidth: true,
105                 width: true
106         },
108         resizableRelatedOptions: {
109                 maxHeight: true,
110                 maxWidth: true,
111                 minHeight: true,
112                 minWidth: true
113         },
115         _create: function() {
116                 this.originalCss = {
117                         display: this.element[ 0 ].style.display,
118                         width: this.element[ 0 ].style.width,
119                         minHeight: this.element[ 0 ].style.minHeight,
120                         maxHeight: this.element[ 0 ].style.maxHeight,
121                         height: this.element[ 0 ].style.height
122                 };
123                 this.originalPosition = {
124                         parent: this.element.parent(),
125                         index: this.element.parent().children().index( this.element )
126                 };
127                 this.originalTitle = this.element.attr( "title" );
128                 if ( this.options.title == null && this.originalTitle != null ) {
129                         this.options.title = this.originalTitle;
130                 }
132                 // Dialogs can't be disabled
133                 if ( this.options.disabled ) {
134                         this.options.disabled = false;
135                 }
137                 this._createWrapper();
139                 this.element
140                         .show()
141                         .removeAttr( "title" )
142                         .appendTo( this.uiDialog );
144                 this._addClass( "ui-dialog-content", "ui-widget-content" );
146                 this._createTitlebar();
147                 this._createButtonPane();
149                 if ( this.options.draggable && $.fn.draggable ) {
150                         this._makeDraggable();
151                 }
152                 if ( this.options.resizable && $.fn.resizable ) {
153                         this._makeResizable();
154                 }
156                 this._isOpen = false;
158                 this._trackFocus();
159         },
161         _init: function() {
162                 if ( this.options.autoOpen ) {
163                         this.open();
164                 }
165         },
167         _appendTo: function() {
168                 var element = this.options.appendTo;
169                 if ( element && ( element.jquery || element.nodeType ) ) {
170                         return $( element );
171                 }
172                 return this.document.find( element || "body" ).eq( 0 );
173         },
175         _destroy: function() {
176                 var next,
177                         originalPosition = this.originalPosition;
179                 this._untrackInstance();
180                 this._destroyOverlay();
182                 this.element
183                         .removeUniqueId()
184                         .css( this.originalCss )
186                         // Without detaching first, the following becomes really slow
187                         .detach();
189                 this.uiDialog.remove();
191                 if ( this.originalTitle ) {
192                         this.element.attr( "title", this.originalTitle );
193                 }
195                 next = originalPosition.parent.children().eq( originalPosition.index );
197                 // Don't try to place the dialog next to itself (#8613)
198                 if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
199                         next.before( this.element );
200                 } else {
201                         originalPosition.parent.append( this.element );
202                 }
203         },
205         widget: function() {
206                 return this.uiDialog;
207         },
209         disable: $.noop,
210         enable: $.noop,
212         close: function( event ) {
213                 var that = this;
215                 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
216                         return;
217                 }
219                 this._isOpen = false;
220                 this._focusedElement = null;
221                 this._destroyOverlay();
222                 this._untrackInstance();
224                 if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
226                         // Hiding a focused element doesn't trigger blur in WebKit
227                         // so in case we have nothing to focus on, explicitly blur the active element
228                         // https://bugs.webkit.org/show_bug.cgi?id=47182
229                         $.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
230                 }
232                 this._hide( this.uiDialog, this.options.hide, function() {
233                         that._trigger( "close", event );
234                 } );
235         },
237         isOpen: function() {
238                 return this._isOpen;
239         },
241         moveToTop: function() {
242                 this._moveToTop();
243         },
245         _moveToTop: function( event, silent ) {
246                 var moved = false,
247                         zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
248                                 return +$( this ).css( "z-index" );
249                         } ).get(),
250                         zIndexMax = Math.max.apply( null, zIndices );
252                 if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
253                         this.uiDialog.css( "z-index", zIndexMax + 1 );
254                         moved = true;
255                 }
257                 if ( moved && !silent ) {
258                         this._trigger( "focus", event );
259                 }
260                 return moved;
261         },
263         open: function() {
264                 var that = this;
265                 if ( this._isOpen ) {
266                         if ( this._moveToTop() ) {
267                                 this._focusTabbable();
268                         }
269                         return;
270                 }
272                 this._isOpen = true;
273                 this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
275                 this._size();
276                 this._position();
277                 this._createOverlay();
278                 this._moveToTop( null, true );
280                 // Ensure the overlay is moved to the top with the dialog, but only when
281                 // opening. The overlay shouldn't move after the dialog is open so that
282                 // modeless dialogs opened after the modal dialog stack properly.
283                 if ( this.overlay ) {
284                         this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
285                 }
287                 this._show( this.uiDialog, this.options.show, function() {
288                         that._focusTabbable();
289                         that._trigger( "focus" );
290                 } );
292                 // Track the dialog immediately upon openening in case a focus event
293                 // somehow occurs outside of the dialog before an element inside the
294                 // dialog is focused (#10152)
295                 this._makeFocusTarget();
297                 this._trigger( "open" );
298         },
300         _focusTabbable: function() {
302                 // Set focus to the first match:
303                 // 1. An element that was focused previously
304                 // 2. First element inside the dialog matching [autofocus]
305                 // 3. Tabbable element inside the content element
306                 // 4. Tabbable element inside the buttonpane
307                 // 5. The close button
308                 // 6. The dialog itself
309                 var hasFocus = this._focusedElement;
310                 if ( !hasFocus ) {
311                         hasFocus = this.element.find( "[autofocus]" );
312                 }
313                 if ( !hasFocus.length ) {
314                         hasFocus = this.element.find( ":tabbable" );
315                 }
316                 if ( !hasFocus.length ) {
317                         hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
318                 }
319                 if ( !hasFocus.length ) {
320                         hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
321                 }
322                 if ( !hasFocus.length ) {
323                         hasFocus = this.uiDialog;
324                 }
325                 hasFocus.eq( 0 ).trigger( "focus" );
326         },
328         _keepFocus: function( event ) {
329                 function checkFocus() {
330                         var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
331                                 isActive = this.uiDialog[ 0 ] === activeElement ||
332                                         $.contains( this.uiDialog[ 0 ], activeElement );
333                         if ( !isActive ) {
334                                 this._focusTabbable();
335                         }
336                 }
337                 event.preventDefault();
338                 checkFocus.call( this );
340                 // support: IE
341                 // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
342                 // so we check again later
343                 this._delay( checkFocus );
344         },
346         _createWrapper: function() {
347                 this.uiDialog = $( "<div>" )
348                         .hide()
349                         .attr( {
351                                 // Setting tabIndex makes the div focusable
352                                 tabIndex: -1,
353                                 role: "dialog"
354                         } )
355                         .appendTo( this._appendTo() );
357                 this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
358                 this._on( this.uiDialog, {
359                         keydown: function( event ) {
360                                 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
361                                                 event.keyCode === $.ui.keyCode.ESCAPE ) {
362                                         event.preventDefault();
363                                         this.close( event );
364                                         return;
365                                 }
367                                 // Prevent tabbing out of dialogs
368                                 if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
369                                         return;
370                                 }
371                                 var tabbables = this.uiDialog.find( ":tabbable" ),
372                                         first = tabbables.filter( ":first" ),
373                                         last = tabbables.filter( ":last" );
375                                 if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
376                                                 !event.shiftKey ) {
377                                         this._delay( function() {
378                                                 first.trigger( "focus" );
379                                         } );
380                                         event.preventDefault();
381                                 } else if ( ( event.target === first[ 0 ] ||
382                                                 event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
383                                         this._delay( function() {
384                                                 last.trigger( "focus" );
385                                         } );
386                                         event.preventDefault();
387                                 }
388                         },
389                         mousedown: function( event ) {
390                                 if ( this._moveToTop( event ) ) {
391                                         this._focusTabbable();
392                                 }
393                         }
394                 } );
396                 // We assume that any existing aria-describedby attribute means
397                 // that the dialog content is marked up properly
398                 // otherwise we brute force the content as the description
399                 if ( !this.element.find( "[aria-describedby]" ).length ) {
400                         this.uiDialog.attr( {
401                                 "aria-describedby": this.element.uniqueId().attr( "id" )
402                         } );
403                 }
404         },
406         _createTitlebar: function() {
407                 var uiDialogTitle;
409                 this.uiDialogTitlebar = $( "<div>" );
410                 this._addClass( this.uiDialogTitlebar,
411                         "ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
412                 this._on( this.uiDialogTitlebar, {
413                         mousedown: function( event ) {
415                                 // Don't prevent click on close button (#8838)
416                                 // Focusing a dialog that is partially scrolled out of view
417                                 // causes the browser to scroll it into view, preventing the click event
418                                 if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
420                                         // Dialog isn't getting focus when dragging (#8063)
421                                         this.uiDialog.trigger( "focus" );
422                                 }
423                         }
424                 } );
426                 // Support: IE
427                 // Use type="button" to prevent enter keypresses in textboxes from closing the
428                 // dialog in IE (#9312)
429                 this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
430                         .button( {
431                                 label: $( "<a>" ).text( this.options.closeText ).html(),
432                                 icon: "ui-icon-closethick",
433                                 showLabel: false
434                         } )
435                         .appendTo( this.uiDialogTitlebar );
437                 this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
438                 this._on( this.uiDialogTitlebarClose, {
439                         click: function( event ) {
440                                 event.preventDefault();
441                                 this.close( event );
442                         }
443                 } );
445                 uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
446                 this._addClass( uiDialogTitle, "ui-dialog-title" );
447                 this._title( uiDialogTitle );
449                 this.uiDialogTitlebar.prependTo( this.uiDialog );
451                 this.uiDialog.attr( {
452                         "aria-labelledby": uiDialogTitle.attr( "id" )
453                 } );
454         },
456         _title: function( title ) {
457                 if ( this.options.title ) {
458                         title.text( this.options.title );
459                 } else {
460                         title.html( "&#160;" );
461                 }
462         },
464         _createButtonPane: function() {
465                 this.uiDialogButtonPane = $( "<div>" );
466                 this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
467                         "ui-widget-content ui-helper-clearfix" );
469                 this.uiButtonSet = $( "<div>" )
470                         .appendTo( this.uiDialogButtonPane );
471                 this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
473                 this._createButtons();
474         },
476         _createButtons: function() {
477                 var that = this,
478                         buttons = this.options.buttons;
480                 // If we already have a button pane, remove it
481                 this.uiDialogButtonPane.remove();
482                 this.uiButtonSet.empty();
484                 if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
485                         this._removeClass( this.uiDialog, "ui-dialog-buttons" );
486                         return;
487                 }
489                 $.each( buttons, function( name, props ) {
490                         var click, buttonOptions;
491                         props = $.isFunction( props ) ?
492                                 { click: props, text: name } :
493                                 props;
495                         // Default to a non-submitting button
496                         props = $.extend( { type: "button" }, props );
498                         // Change the context for the click callback to be the main element
499                         click = props.click;
500                         buttonOptions = {
501                                 icon: props.icon,
502                                 iconPosition: props.iconPosition,
503                                 showLabel: props.showLabel,
505                                 // Deprecated options
506                                 icons: props.icons,
507                                 text: props.text
508                         };
510                         delete props.click;
511                         delete props.icon;
512                         delete props.iconPosition;
513                         delete props.showLabel;
515                         // Deprecated options
516                         delete props.icons;
517                         if ( typeof props.text === "boolean" ) {
518                                 delete props.text;
519                         }
521                         $( "<button></button>", props )
522                                 .button( buttonOptions )
523                                 .appendTo( that.uiButtonSet )
524                                 .on( "click", function() {
525                                         click.apply( that.element[ 0 ], arguments );
526                                 } );
527                 } );
528                 this._addClass( this.uiDialog, "ui-dialog-buttons" );
529                 this.uiDialogButtonPane.appendTo( this.uiDialog );
530         },
532         _makeDraggable: function() {
533                 var that = this,
534                         options = this.options;
536                 function filteredUi( ui ) {
537                         return {
538                                 position: ui.position,
539                                 offset: ui.offset
540                         };
541                 }
543                 this.uiDialog.draggable( {
544                         cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
545                         handle: ".ui-dialog-titlebar",
546                         containment: "document",
547                         start: function( event, ui ) {
548                                 that._addClass( $( this ), "ui-dialog-dragging" );
549                                 that._blockFrames();
550                                 that._trigger( "dragStart", event, filteredUi( ui ) );
551                         },
552                         drag: function( event, ui ) {
553                                 that._trigger( "drag", event, filteredUi( ui ) );
554                         },
555                         stop: function( event, ui ) {
556                                 var left = ui.offset.left - that.document.scrollLeft(),
557                                         top = ui.offset.top - that.document.scrollTop();
559                                 options.position = {
560                                         my: "left top",
561                                         at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
562                                                 "top" + ( top >= 0 ? "+" : "" ) + top,
563                                         of: that.window
564                                 };
565                                 that._removeClass( $( this ), "ui-dialog-dragging" );
566                                 that._unblockFrames();
567                                 that._trigger( "dragStop", event, filteredUi( ui ) );
568                         }
569                 } );
570         },
572         _makeResizable: function() {
573                 var that = this,
574                         options = this.options,
575                         handles = options.resizable,
577                         // .ui-resizable has position: relative defined in the stylesheet
578                         // but dialogs have to use absolute or fixed positioning
579                         position = this.uiDialog.css( "position" ),
580                         resizeHandles = typeof handles === "string" ?
581                                 handles :
582                                 "n,e,s,w,se,sw,ne,nw";
584                 function filteredUi( ui ) {
585                         return {
586                                 originalPosition: ui.originalPosition,
587                                 originalSize: ui.originalSize,
588                                 position: ui.position,
589                                 size: ui.size
590                         };
591                 }
593                 this.uiDialog.resizable( {
594                         cancel: ".ui-dialog-content",
595                         containment: "document",
596                         alsoResize: this.element,
597                         maxWidth: options.maxWidth,
598                         maxHeight: options.maxHeight,
599                         minWidth: options.minWidth,
600                         minHeight: this._minHeight(),
601                         handles: resizeHandles,
602                         start: function( event, ui ) {
603                                 that._addClass( $( this ), "ui-dialog-resizing" );
604                                 that._blockFrames();
605                                 that._trigger( "resizeStart", event, filteredUi( ui ) );
606                         },
607                         resize: function( event, ui ) {
608                                 that._trigger( "resize", event, filteredUi( ui ) );
609                         },
610                         stop: function( event, ui ) {
611                                 var offset = that.uiDialog.offset(),
612                                         left = offset.left - that.document.scrollLeft(),
613                                         top = offset.top - that.document.scrollTop();
615                                 options.height = that.uiDialog.height();
616                                 options.width = that.uiDialog.width();
617                                 options.position = {
618                                         my: "left top",
619                                         at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
620                                                 "top" + ( top >= 0 ? "+" : "" ) + top,
621                                         of: that.window
622                                 };
623                                 that._removeClass( $( this ), "ui-dialog-resizing" );
624                                 that._unblockFrames();
625                                 that._trigger( "resizeStop", event, filteredUi( ui ) );
626                         }
627                 } )
628                         .css( "position", position );
629         },
631         _trackFocus: function() {
632                 this._on( this.widget(), {
633                         focusin: function( event ) {
634                                 this._makeFocusTarget();
635                                 this._focusedElement = $( event.target );
636                         }
637                 } );
638         },
640         _makeFocusTarget: function() {
641                 this._untrackInstance();
642                 this._trackingInstances().unshift( this );
643         },
645         _untrackInstance: function() {
646                 var instances = this._trackingInstances(),
647                         exists = $.inArray( this, instances );
648                 if ( exists !== -1 ) {
649                         instances.splice( exists, 1 );
650                 }
651         },
653         _trackingInstances: function() {
654                 var instances = this.document.data( "ui-dialog-instances" );
655                 if ( !instances ) {
656                         instances = [];
657                         this.document.data( "ui-dialog-instances", instances );
658                 }
659                 return instances;
660         },
662         _minHeight: function() {
663                 var options = this.options;
665                 return options.height === "auto" ?
666                         options.minHeight :
667                         Math.min( options.minHeight, options.height );
668         },
670         _position: function() {
672                 // Need to show the dialog to get the actual offset in the position plugin
673                 var isVisible = this.uiDialog.is( ":visible" );
674                 if ( !isVisible ) {
675                         this.uiDialog.show();
676                 }
677                 this.uiDialog.position( this.options.position );
678                 if ( !isVisible ) {
679                         this.uiDialog.hide();
680                 }
681         },
683         _setOptions: function( options ) {
684                 var that = this,
685                         resize = false,
686                         resizableOptions = {};
688                 $.each( options, function( key, value ) {
689                         that._setOption( key, value );
691                         if ( key in that.sizeRelatedOptions ) {
692                                 resize = true;
693                         }
694                         if ( key in that.resizableRelatedOptions ) {
695                                 resizableOptions[ key ] = value;
696                         }
697                 } );
699                 if ( resize ) {
700                         this._size();
701                         this._position();
702                 }
703                 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
704                         this.uiDialog.resizable( "option", resizableOptions );
705                 }
706         },
708         _setOption: function( key, value ) {
709                 var isDraggable, isResizable,
710                         uiDialog = this.uiDialog;
712                 if ( key === "disabled" ) {
713                         return;
714                 }
716                 this._super( key, value );
718                 if ( key === "appendTo" ) {
719                         this.uiDialog.appendTo( this._appendTo() );
720                 }
722                 if ( key === "buttons" ) {
723                         this._createButtons();
724                 }
726                 if ( key === "closeText" ) {
727                         this.uiDialogTitlebarClose.button( {
729                                 // Ensure that we always pass a string
730                                 label: $( "<a>" ).text( "" + this.options.closeText ).html()
731                         } );
732                 }
734                 if ( key === "draggable" ) {
735                         isDraggable = uiDialog.is( ":data(ui-draggable)" );
736                         if ( isDraggable && !value ) {
737                                 uiDialog.draggable( "destroy" );
738                         }
740                         if ( !isDraggable && value ) {
741                                 this._makeDraggable();
742                         }
743                 }
745                 if ( key === "position" ) {
746                         this._position();
747                 }
749                 if ( key === "resizable" ) {
751                         // currently resizable, becoming non-resizable
752                         isResizable = uiDialog.is( ":data(ui-resizable)" );
753                         if ( isResizable && !value ) {
754                                 uiDialog.resizable( "destroy" );
755                         }
757                         // Currently resizable, changing handles
758                         if ( isResizable && typeof value === "string" ) {
759                                 uiDialog.resizable( "option", "handles", value );
760                         }
762                         // Currently non-resizable, becoming resizable
763                         if ( !isResizable && value !== false ) {
764                                 this._makeResizable();
765                         }
766                 }
768                 if ( key === "title" ) {
769                         this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
770                 }
771         },
773         _size: function() {
775                 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
776                 // divs will both have width and height set, so we need to reset them
777                 var nonContentHeight, minContentHeight, maxContentHeight,
778                         options = this.options;
780                 // Reset content sizing
781                 this.element.show().css( {
782                         width: "auto",
783                         minHeight: 0,
784                         maxHeight: "none",
785                         height: 0
786                 } );
788                 if ( options.minWidth > options.width ) {
789                         options.width = options.minWidth;
790                 }
792                 // Reset wrapper sizing
793                 // determine the height of all the non-content elements
794                 nonContentHeight = this.uiDialog.css( {
795                         height: "auto",
796                         width: options.width
797                 } )
798                         .outerHeight();
799                 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
800                 maxContentHeight = typeof options.maxHeight === "number" ?
801                         Math.max( 0, options.maxHeight - nonContentHeight ) :
802                         "none";
804                 if ( options.height === "auto" ) {
805                         this.element.css( {
806                                 minHeight: minContentHeight,
807                                 maxHeight: maxContentHeight,
808                                 height: "auto"
809                         } );
810                 } else {
811                         this.element.height( Math.max( 0, options.height - nonContentHeight ) );
812                 }
814                 if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
815                         this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
816                 }
817         },
819         _blockFrames: function() {
820                 this.iframeBlocks = this.document.find( "iframe" ).map( function() {
821                         var iframe = $( this );
823                         return $( "<div>" )
824                                 .css( {
825                                         position: "absolute",
826                                         width: iframe.outerWidth(),
827                                         height: iframe.outerHeight()
828                                 } )
829                                 .appendTo( iframe.parent() )
830                                 .offset( iframe.offset() )[ 0 ];
831                 } );
832         },
834         _unblockFrames: function() {
835                 if ( this.iframeBlocks ) {
836                         this.iframeBlocks.remove();
837                         delete this.iframeBlocks;
838                 }
839         },
841         _allowInteraction: function( event ) {
842                 if ( $( event.target ).closest( ".ui-dialog" ).length ) {
843                         return true;
844                 }
846                 // TODO: Remove hack when datepicker implements
847                 // the .ui-front logic (#8989)
848                 return !!$( event.target ).closest( ".ui-datepicker" ).length;
849         },
851         _createOverlay: function() {
852                 if ( !this.options.modal ) {
853                         return;
854                 }
856                 // We use a delay in case the overlay is created from an
857                 // event that we're going to be cancelling (#2804)
858                 var isOpening = true;
859                 this._delay( function() {
860                         isOpening = false;
861                 } );
863                 if ( !this.document.data( "ui-dialog-overlays" ) ) {
865                         // Prevent use of anchors and inputs
866                         // Using _on() for an event handler shared across many instances is
867                         // safe because the dialogs stack and must be closed in reverse order
868                         this._on( this.document, {
869                                 focusin: function( event ) {
870                                         if ( isOpening ) {
871                                                 return;
872                                         }
874                                         if ( !this._allowInteraction( event ) ) {
875                                                 event.preventDefault();
876                                                 this._trackingInstances()[ 0 ]._focusTabbable();
877                                         }
878                                 }
879                         } );
880                 }
882                 this.overlay = $( "<div>" )
883                         .appendTo( this._appendTo() );
885                 this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
886                 this._on( this.overlay, {
887                         mousedown: "_keepFocus"
888                 } );
889                 this.document.data( "ui-dialog-overlays",
890                         ( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
891         },
893         _destroyOverlay: function() {
894                 if ( !this.options.modal ) {
895                         return;
896                 }
898                 if ( this.overlay ) {
899                         var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
901                         if ( !overlays ) {
902                                 this._off( this.document, "focusin" );
903                                 this.document.removeData( "ui-dialog-overlays" );
904                         } else {
905                                 this.document.data( "ui-dialog-overlays", overlays );
906                         }
908                         this.overlay.remove();
909                         this.overlay = null;
910                 }
911         }
912 } );
914 // DEPRECATED
915 // TODO: switch return back to widget declaration at top of file when this is removed
916 if ( $.uiBackCompat !== false ) {
918         // Backcompat for dialogClass option
919         $.widget( "ui.dialog", $.ui.dialog, {
920                 options: {
921                         dialogClass: ""
922                 },
923                 _createWrapper: function() {
924                         this._super();
925                         this.uiDialog.addClass( this.options.dialogClass );
926                 },
927                 _setOption: function( key, value ) {
928                         if ( key === "dialogClass" ) {
929                                 this.uiDialog
930                                         .removeClass( this.options.dialogClass )
931                                         .addClass( value );
932                         }
933                         this._superApply( arguments );
934                 }
935         } );
938 return $.ui.dialog;
940 } ) );