[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-admin/js/ -> plugin-install.js (source)

   1  /**
   2   * @file Functionality for the plugin install screens.
   3   *
   4   * @output wp-admin/js/plugin-install.js
   5   */
   6  
   7  /* global tb_click, tb_remove, tb_position */
   8  
   9  /**
  10   * Initializes the plugin install screens.
  11   *
  12   * @param {JQueryStatic} $ The jQuery object.
  13   */
  14  jQuery( function( $ ) {
  15  
  16      var tbWindow,
  17          $iframeBody,
  18          $tabbables,
  19          $firstTabbable,
  20          $lastTabbable,
  21          $focusedBefore = $(),
  22          $uploadViewToggle = $( '.upload-view-toggle' ),
  23          $wrap = $ ( '.wrap' ),
  24          $body = $( document.body );
  25  
  26      window.tb_position = function() {
  27          var width = $( window ).width(),
  28              H = $( window ).height() - ( ( 792 < width ) ? 60 : 40 ),
  29              W = ( 792 < width ) ? 772 : width - 20;
  30  
  31          tbWindow = $( '#TB_window' );
  32  
  33          if ( tbWindow.length ) {
  34              tbWindow.width( W ).height( H );
  35              $( '#TB_iframeContent' ).width( W ).height( H );
  36              tbWindow.css({
  37                  'margin-left': '-' + parseInt( ( W / 2 ), 10 ) + 'px'
  38              });
  39              if ( typeof document.body.style.maxWidth !== 'undefined' ) {
  40                  tbWindow.css({
  41                      'top': '30px',
  42                      'margin-top': '0'
  43                  });
  44              }
  45          }
  46  
  47          return $( 'a.thickbox' ).each( function() {
  48              var href = $( this ).attr( 'href' );
  49              if ( ! href ) {
  50                  return;
  51              }
  52              href = href.replace( /&width=[0-9]+/g, '' );
  53              href = href.replace( /&height=[0-9]+/g, '' );
  54              $(this).attr( 'href', href + '&width=' + W + '&height=' + ( H ) );
  55          });
  56      };
  57  
  58      $( window ).on( 'resize', function() {
  59          tb_position();
  60      });
  61  
  62      /*
  63       * Custom events: when a Thickbox iframe has loaded and when the Thickbox
  64       * modal gets removed from the DOM.
  65       */
  66      $body
  67          .on( 'thickbox:iframe:loaded', tbWindow, function() {
  68              /*
  69               * Return if it's not the modal with the plugin details iframe. Other
  70               * thickbox instances might want to load an iframe with content from
  71               * an external domain. Avoid to access the iframe contents when we're
  72               * not sure the iframe loads from the same domain.
  73               */
  74              if ( ! tbWindow.hasClass( 'plugin-details-modal' ) ) {
  75                  return;
  76              }
  77  
  78              iframeLoaded();
  79          })
  80          .on( 'thickbox:removed', function() {
  81              // Set focus back to the element that opened the modal dialog.
  82              // Note: IE 8 would need this wrapped in a fake setTimeout `0`.
  83              $focusedBefore.trigger( 'focus' );
  84          });
  85  
  86      /**
  87       * Initializes the plugin details modal dialog after the iframe has fully loaded.
  88       */
  89  	function iframeLoaded() {
  90          var $iframe = tbWindow.find( '#TB_iframeContent' );
  91  
  92          // Get the iframe body.
  93          $iframeBody = $iframe.contents().find( 'body' );
  94  
  95          // Get the tabbable elements and handle the keydown event on first load.
  96          handleTabbables();
  97  
  98          // Set initial focus on the "Close" button.
  99          $firstTabbable.trigger( 'focus' );
 100  
 101          /*
 102           * When the "Install" button is disabled (e.g. the Plugin is already installed)
 103           * then we can't predict where the last focusable element is. We need to get
 104           * the tabbable elements and handle the keydown event again and again,
 105           * each time the active tab panel changes.
 106           */
 107          $( '#plugin-information-tabs a', $iframeBody ).on( 'click', function() {
 108              handleTabbables();
 109          });
 110  
 111          // Close the modal when pressing Escape.
 112          $iframeBody.on( 'keydown', function( event ) {
 113              if ( 27 !== event.which ) {
 114                  return;
 115              }
 116              tb_remove();
 117          });
 118      }
 119  
 120      /**
 121       * Gets the tabbable elements and detaches/attaches the keydown event.
 122       *
 123       * Called after the iframe has fully loaded so we have all the elements we need.
 124       * Called again each time a Tab gets clicked.
 125       * @todo Consider to implement a WordPress general utility for this and don't use jQuery UI.
 126       */
 127  	function handleTabbables() {
 128          var $firstAndLast;
 129          // Get all the tabbable elements.
 130          $tabbables = $( ':tabbable', $iframeBody );
 131          // Our first tabbable element is always the "Close" button.
 132          $firstTabbable = tbWindow.find( '#TB_closeWindowButton' );
 133          // Get the last tabbable element.
 134          $lastTabbable = $tabbables.last();
 135          // Make a jQuery collection.
 136          $firstAndLast = $firstTabbable.add( $lastTabbable );
 137          // Detach any previously attached keydown event.
 138          $firstAndLast.off( 'keydown.wp-plugin-details' );
 139          // Attach again the keydown event on the first and last focusable elements.
 140          $firstAndLast.on( 'keydown.wp-plugin-details', function( event ) {
 141              constrainTabbing( event );
 142          });
 143      }
 144  
 145      /**
 146       * Constrains tabbing within the plugin modal dialog.
 147       *
 148       * @param {JQuery.Event} event The keydown event.
 149       */
 150  	function constrainTabbing( event ) {
 151          if ( 9 !== event.which ) {
 152              return;
 153          }
 154  
 155          if ( $lastTabbable[0] === event.target && ! event.shiftKey ) {
 156              event.preventDefault();
 157              $firstTabbable.trigger( 'focus' );
 158          } else if ( $firstTabbable[0] === event.target && event.shiftKey ) {
 159              event.preventDefault();
 160              $lastTabbable.trigger( 'focus' );
 161          }
 162      }
 163  
 164      /**
 165       * Opens the Plugin details modal.
 166       *
 167       * The event is delegated to get also the links in the plugins search tab,
 168       * after the Ajax search rebuilds the HTML. It's delegated on the closest
 169       * ancestor and not on the body to avoid conflicts with other handlers, see
 170       * Trac ticket #43082.
 171       */
 172      $( '.wrap' ).on( 'click', '.thickbox.open-plugin-details-modal', function( e ) {
 173          // The `data-title` attribute is used only in the Plugin screens.
 174          var title = $( this ).data( 'title' ) ?
 175              wp.i18n.sprintf(
 176                  // translators: %s: Plugin name.
 177                  wp.i18n.__( 'Plugin: %s' ),
 178                  $( this ).data( 'title' )
 179              ) :
 180              wp.i18n.__( 'Plugin details' );
 181  
 182          e.preventDefault();
 183          e.stopPropagation();
 184  
 185          // Store the element that has focus before opening the modal dialog, i.e. the control which opens it.
 186          $focusedBefore = $( this );
 187  
 188          tb_click.call(this);
 189  
 190          // Set ARIA role, ARIA label, and add a CSS class.
 191          tbWindow
 192              .attr({
 193                  'role': 'dialog',
 194                  'aria-label': wp.i18n.__( 'Plugin details' )
 195              })
 196              .addClass( 'plugin-details-modal' );
 197  
 198          // Set title attribute on the iframe.
 199          tbWindow.find( '#TB_iframeContent' ).attr( 'title', title );
 200      });
 201  
 202      /* Plugin install related JS */
 203      $( '#plugin-information-tabs a' ).on( 'click', function( event ) {
 204          var tab = $( this ).attr( 'name' );
 205          event.preventDefault();
 206  
 207          // Flip the tab.
 208          $( '#plugin-information-tabs a.current' ).removeClass( 'current' );
 209          $( this ).addClass( 'current' );
 210  
 211          // Only show the fyi box in the description section, on smaller screen,
 212          // where it's otherwise always displayed at the top.
 213          if ( 'description' !== tab && $( window ).width() < 772 ) {
 214              $( '#plugin-information-content' ).find( '.fyi' ).hide();
 215          } else {
 216              $( '#plugin-information-content' ).find( '.fyi' ).show();
 217          }
 218  
 219          // Flip the content.
 220          $( '#section-holder div.section' ).hide(); // Hide 'em all.
 221          $( '#section-' + tab ).show();
 222      });
 223  
 224      /*
 225       * When a user presses the "Upload Plugin" button, show the upload form in place
 226       * rather than sending them to the devoted upload plugin page.
 227       * The `?tab=upload` page still exists for no-js support and for plugins that
 228       * might access it directly. When we're in this page, let the link behave
 229       * like a link. Otherwise we're in the normal plugin installer pages and the
 230       * link should behave like a toggle button.
 231       */
 232      if ( ! $wrap.hasClass( 'plugin-install-tab-upload' ) ) {
 233          $uploadViewToggle
 234              .attr({
 235                  role: 'button',
 236                  'aria-expanded': 'false'
 237              })
 238              .on( 'click', function( event ) {
 239                  event.preventDefault();
 240                  $body.toggleClass( 'show-upload-view' );
 241                  $uploadViewToggle.attr( 'aria-expanded', $body.hasClass( 'show-upload-view' ) );
 242              });
 243      }
 244  });


Generated : Thu Sep 10 08:20:30 2026 Cross-referenced by PHPXref