[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

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

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


Generated: Thu Nov 21 01:00:03 2024 Cross-referenced by PHPXref 0.7.1