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


Generated : Thu Nov 21 08:20:01 2024 Cross-referenced by PHPXref