[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/jquery/ui/ -> dialog.js (source)

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


Generated : Wed Jul 22 08:20:19 2026 Cross-referenced by PHPXref