[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-admin/js/ -> common.js (source)

   1  /**
   2   * @output wp-admin/js/common.js
   3   */
   4  
   5  /* global setUserSetting, ajaxurl, commonL10n, alert, confirm, pagenow */
   6  /* global columns, screenMeta */
   7  
   8  /**
   9   *  Adds common WordPress functionality to the window.
  10   *
  11   *  @param {jQuery} $        jQuery object.
  12   *  @param {Object} window   The window object.
  13   *  @param {mixed} undefined Unused.
  14   */
  15  ( function( $, window, undefined ) {
  16      var $document = $( document ),
  17          $window = $( window ),
  18          $body = $( document.body );
  19  
  20  /**
  21   * Removed in 3.3.0, needed for back-compatibility.
  22   *
  23   * @since 2.7.0
  24   * @deprecated 3.3.0
  25   */
  26  window.adminMenu = {
  27      init : function() {},
  28      fold : function() {},
  29      restoreMenuState : function() {},
  30      toggle : function() {},
  31      favorites : function() {}
  32  };
  33  
  34  // Show/hide/save table columns.
  35  window.columns = {
  36  
  37      /**
  38       * Initializes the column toggles in the screen options.
  39       *
  40       * Binds an onClick event to the checkboxes to show or hide the table columns
  41       * based on their toggled state. And persists the toggled state.
  42       *
  43       * @since 2.7.0
  44       *
  45       * @return {void}
  46       */
  47      init : function() {
  48          var that = this;
  49          $('.hide-column-tog', '#adv-settings').click( function() {
  50              var $t = $(this), column = $t.val();
  51              if ( $t.prop('checked') )
  52                  that.checked(column);
  53              else
  54                  that.unchecked(column);
  55  
  56              columns.saveManageColumnsState();
  57          });
  58      },
  59  
  60      /**
  61       * Saves the toggled state for the columns.
  62       *
  63       * Saves whether the columns should be shown or hidden on a page.
  64       *
  65       * @since 3.0.0
  66       *
  67       * @return {void}
  68       */
  69      saveManageColumnsState : function() {
  70          var hidden = this.hidden();
  71          $.post(ajaxurl, {
  72              action: 'hidden-columns',
  73              hidden: hidden,
  74              screenoptionnonce: $('#screenoptionnonce').val(),
  75              page: pagenow
  76          });
  77      },
  78  
  79      /**
  80       * Makes a column visible and adjusts the column span for the table.
  81       *
  82       * @since 3.0.0
  83       * @param {string} column The column name.
  84       *
  85       * @return {void}
  86       */
  87      checked : function(column) {
  88          $('.column-' + column).removeClass( 'hidden' );
  89          this.colSpanChange(+1);
  90      },
  91  
  92      /**
  93       * Hides a column and adjusts the column span for the table.
  94       *
  95       * @since 3.0.0
  96       * @param {string} column The column name.
  97       *
  98       * @return {void}
  99       */
 100      unchecked : function(column) {
 101          $('.column-' + column).addClass( 'hidden' );
 102          this.colSpanChange(-1);
 103      },
 104  
 105      /**
 106       * Gets all hidden columns.
 107       *
 108       * @since 3.0.0
 109       *
 110       * @return {string} The hidden column names separated by a comma.
 111       */
 112      hidden : function() {
 113          return $( '.manage-column[id]' ).filter( '.hidden' ).map(function() {
 114              return this.id;
 115          }).get().join( ',' );
 116      },
 117  
 118      /**
 119       * Gets the checked column toggles from the screen options.
 120       *
 121       * @since 3.0.0
 122       *
 123       * @return {string} String containing the checked column names.
 124       */
 125      useCheckboxesForHidden : function() {
 126          this.hidden = function(){
 127              return $('.hide-column-tog').not(':checked').map(function() {
 128                  var id = this.id;
 129                  return id.substring( id, id.length - 5 );
 130              }).get().join(',');
 131          };
 132      },
 133  
 134      /**
 135       * Adjusts the column span for the table.
 136       *
 137       * @since 3.1.0
 138       *
 139       * @param {int} diff The modifier for the column span.
 140       */
 141      colSpanChange : function(diff) {
 142          var $t = $('table').find('.colspanchange'), n;
 143          if ( !$t.length )
 144              return;
 145          n = parseInt( $t.attr('colspan'), 10 ) + diff;
 146          $t.attr('colspan', n.toString());
 147      }
 148  };
 149  
 150  $document.ready(function(){columns.init();});
 151  
 152  /**
 153   * Validates that the required form fields are not empty.
 154   *
 155   * @since 2.9.0
 156   *
 157   * @param {jQuery} form The form to validate.
 158   *
 159   * @return {boolean} Returns true if all required fields are not an empty string.
 160   */
 161  window.validateForm = function( form ) {
 162      return !$( form )
 163          .find( '.form-required' )
 164          .filter( function() { return $( ':input:visible', this ).val() === ''; } )
 165          .addClass( 'form-invalid' )
 166          .find( ':input:visible' )
 167          .change( function() { $( this ).closest( '.form-invalid' ).removeClass( 'form-invalid' ); } )
 168          .length;
 169  };
 170  
 171  // Stub for doing better warnings.
 172  /**
 173   * Shows message pop-up notice or confirmation message.
 174   *
 175   * @since 2.7.0
 176   *
 177   * @type {{warn: showNotice.warn, note: showNotice.note}}
 178   *
 179   * @return {void}
 180   */
 181  window.showNotice = {
 182  
 183      /**
 184       * Shows a delete confirmation pop-up message.
 185       *
 186       * @since 2.7.0
 187       *
 188       * @return {boolean} Returns true if the message is confirmed.
 189       */
 190      warn : function() {
 191          var msg = commonL10n.warnDelete || '';
 192          if ( confirm(msg) ) {
 193              return true;
 194          }
 195  
 196          return false;
 197      },
 198  
 199      /**
 200       * Shows an alert message.
 201       *
 202       * @since 2.7.0
 203       *
 204       * @param text The text to display in the message.
 205       */
 206      note : function(text) {
 207          alert(text);
 208      }
 209  };
 210  
 211  /**
 212   * Represents the functions for the meta screen options panel.
 213   *
 214   * @since 3.2.0
 215   *
 216   * @type {{element: null, toggles: null, page: null, init: screenMeta.init,
 217   *         toggleEvent: screenMeta.toggleEvent, open: screenMeta.open,
 218   *         close: screenMeta.close}}
 219   *
 220   * @return {void}
 221   */
 222  window.screenMeta = {
 223      element: null, // #screen-meta
 224      toggles: null, // .screen-meta-toggle
 225      page:    null, // #wpcontent
 226  
 227      /**
 228       * Initializes the screen meta options panel.
 229       *
 230       * @since 3.2.0
 231       *
 232       * @return {void}
 233       */
 234      init: function() {
 235          this.element = $('#screen-meta');
 236          this.toggles = $( '#screen-meta-links' ).find( '.show-settings' );
 237          this.page    = $('#wpcontent');
 238  
 239          this.toggles.click( this.toggleEvent );
 240      },
 241  
 242      /**
 243       * Toggles the screen meta options panel.
 244       *
 245       * @since 3.2.0
 246       *
 247       * @return {void}
 248       */
 249      toggleEvent: function() {
 250          var panel = $( '#' + $( this ).attr( 'aria-controls' ) );
 251  
 252          if ( !panel.length )
 253              return;
 254  
 255          if ( panel.is(':visible') )
 256              screenMeta.close( panel, $(this) );
 257          else
 258              screenMeta.open( panel, $(this) );
 259      },
 260  
 261      /**
 262       * Opens the screen meta options panel.
 263       *
 264       * @since 3.2.0
 265       *
 266       * @param {jQuery} panel  The screen meta options panel div.
 267       * @param {jQuery} button The toggle button.
 268       *
 269       * @return {void}
 270       */
 271      open: function( panel, button ) {
 272  
 273          $( '#screen-meta-links' ).find( '.screen-meta-toggle' ).not( button.parent() ).css( 'visibility', 'hidden' );
 274  
 275          panel.parent().show();
 276  
 277          /**
 278           * Sets the focus to the meta options panel and adds the necessary CSS classes.
 279           *
 280           * @since 3.2.0
 281           *
 282           * @return {void}
 283           */
 284          panel.slideDown( 'fast', function() {
 285              panel.focus();
 286              button.addClass( 'screen-meta-active' ).attr( 'aria-expanded', true );
 287          });
 288  
 289          $document.trigger( 'screen:options:open' );
 290      },
 291  
 292      /**
 293       * Closes the screen meta options panel.
 294       *
 295       * @since 3.2.0
 296       *
 297       * @param {jQuery} panel  The screen meta options panel div.
 298       * @param {jQuery} button The toggle button.
 299       *
 300       * @return {void}
 301       */
 302      close: function( panel, button ) {
 303          /**
 304           * Hides the screen meta options panel.
 305           *
 306           * @since 3.2.0
 307           *
 308           * @return {void}
 309           */
 310          panel.slideUp( 'fast', function() {
 311              button.removeClass( 'screen-meta-active' ).attr( 'aria-expanded', false );
 312              $('.screen-meta-toggle').css('visibility', '');
 313              panel.parent().hide();
 314          });
 315  
 316          $document.trigger( 'screen:options:close' );
 317      }
 318  };
 319  
 320  /**
 321   * Initializes the help tabs in the help panel.
 322   *
 323   * @param {Event} e The event object.
 324   *
 325   * @return {void}
 326   */
 327  $('.contextual-help-tabs').delegate('a', 'click', function(e) {
 328      var link = $(this),
 329          panel;
 330  
 331      e.preventDefault();
 332  
 333      // Don't do anything if the click is for the tab already showing.
 334      if ( link.is('.active a') )
 335          return false;
 336  
 337      // Links.
 338      $('.contextual-help-tabs .active').removeClass('active');
 339      link.parent('li').addClass('active');
 340  
 341      panel = $( link.attr('href') );
 342  
 343      // Panels.
 344      $('.help-tab-content').not( panel ).removeClass('active').hide();
 345      panel.addClass('active').show();
 346  });
 347  
 348  /**
 349   * Update custom permalink structure via buttons.
 350   */
 351  var permalinkStructureFocused = false,
 352      $permalinkStructure       = $( '#permalink_structure' ),
 353      $permalinkStructureInputs = $( '.permalink-structure input:radio' ),
 354      $permalinkCustomSelection = $( '#custom_selection' ),
 355      $availableStructureTags   = $( '.form-table.permalink-structure .available-structure-tags button' );
 356  
 357  // Change permalink structure input when selecting one of the common structures.
 358  $permalinkStructureInputs.on( 'change', function() {
 359      if ( 'custom' === this.value ) {
 360          return;
 361      }
 362  
 363      $permalinkStructure.val( this.value );
 364  
 365      // Update button states after selection.
 366      $availableStructureTags.each( function() {
 367          changeStructureTagButtonState( $( this ) );
 368      } );
 369  } );
 370  
 371  $permalinkStructure.on( 'click input', function() {
 372      $permalinkCustomSelection.prop( 'checked', true );
 373  } );
 374  
 375  // Check if the permalink structure input field has had focus at least once.
 376  $permalinkStructure.on( 'focus', function( event ) {
 377      permalinkStructureFocused = true;
 378      $( this ).off( event );
 379  } );
 380  
 381  /**
 382   * Enables or disables a structure tag button depending on its usage.
 383   *
 384   * If the structure is already used in the custom permalink structure,
 385   * it will be disabled.
 386   *
 387   * @param {object} button Button jQuery object.
 388   */
 389  function changeStructureTagButtonState( button ) {
 390      if ( -1 !== $permalinkStructure.val().indexOf( button.text().trim() ) ) {
 391          button.attr( 'data-label', button.attr( 'aria-label' ) );
 392          button.attr( 'aria-label', button.attr( 'data-used' ) );
 393          button.attr( 'aria-pressed', true );
 394          button.addClass( 'active' );
 395      } else if ( button.attr( 'data-label' ) ) {
 396          button.attr( 'aria-label', button.attr( 'data-label' ) );
 397          button.attr( 'aria-pressed', false );
 398          button.removeClass( 'active' );
 399      }
 400  }
 401  
 402  // Check initial button state.
 403  $availableStructureTags.each( function() {
 404      changeStructureTagButtonState( $( this ) );
 405  } );
 406  
 407  // Observe permalink structure field and disable buttons of tags that are already present.
 408  $permalinkStructure.on( 'change', function() {
 409      $availableStructureTags.each( function() {
 410          changeStructureTagButtonState( $( this ) );
 411      } );
 412  } );
 413  
 414  $availableStructureTags.on( 'click', function() {
 415      var permalinkStructureValue = $permalinkStructure.val(),
 416          selectionStart          = $permalinkStructure[ 0 ].selectionStart,
 417          selectionEnd            = $permalinkStructure[ 0 ].selectionEnd,
 418          textToAppend            = $( this ).text().trim(),
 419          textToAnnounce          = $( this ).attr( 'data-added' ),
 420          newSelectionStart;
 421  
 422      // Remove structure tag if already part of the structure.
 423      if ( -1 !== permalinkStructureValue.indexOf( textToAppend ) ) {
 424          permalinkStructureValue = permalinkStructureValue.replace( textToAppend + '/', '' );
 425  
 426          $permalinkStructure.val( '/' === permalinkStructureValue ? '' : permalinkStructureValue );
 427  
 428          // Announce change to screen readers.
 429          $( '#custom_selection_updated' ).text( textToAnnounce );
 430  
 431          // Disable button.
 432          changeStructureTagButtonState( $( this ) );
 433  
 434          return;
 435      }
 436  
 437      // Input field never had focus, move selection to end of input.
 438      if ( ! permalinkStructureFocused && 0 === selectionStart && 0 === selectionEnd ) {
 439          selectionStart = selectionEnd = permalinkStructureValue.length;
 440      }
 441  
 442      $permalinkCustomSelection.prop( 'checked', true );
 443  
 444      // Prepend and append slashes if necessary.
 445      if ( '/' !== permalinkStructureValue.substr( 0, selectionStart ).substr( -1 ) ) {
 446          textToAppend = '/' + textToAppend;
 447      }
 448  
 449      if ( '/' !== permalinkStructureValue.substr( selectionEnd, 1 ) ) {
 450          textToAppend = textToAppend + '/';
 451      }
 452  
 453      // Insert structure tag at the specified position.
 454      $permalinkStructure.val( permalinkStructureValue.substr( 0, selectionStart ) + textToAppend + permalinkStructureValue.substr( selectionEnd ) );
 455  
 456      // Announce change to screen readers.
 457      $( '#custom_selection_updated' ).text( textToAnnounce );
 458  
 459      // Disable button.
 460      changeStructureTagButtonState( $( this ) );
 461  
 462      // If input had focus give it back with cursor right after appended text.
 463      if ( permalinkStructureFocused && $permalinkStructure[0].setSelectionRange ) {
 464          newSelectionStart = ( permalinkStructureValue.substr( 0, selectionStart ) + textToAppend ).length;
 465          $permalinkStructure[0].setSelectionRange( newSelectionStart, newSelectionStart );
 466          $permalinkStructure.focus();
 467      }
 468  } );
 469  
 470  $document.ready( function() {
 471      var checks, first, last, checked, sliced, mobileEvent, transitionTimeout, focusedRowActions,
 472          lastClicked = false,
 473          pageInput = $('input.current-page'),
 474          currentPage = pageInput.val(),
 475          isIOS = /iPhone|iPad|iPod/.test( navigator.userAgent ),
 476          isAndroid = navigator.userAgent.indexOf( 'Android' ) !== -1,
 477          isIE8 = $( document.documentElement ).hasClass( 'ie8' ),
 478          $adminMenuWrap = $( '#adminmenuwrap' ),
 479          $wpwrap = $( '#wpwrap' ),
 480          $adminmenu = $( '#adminmenu' ),
 481          $overlay = $( '#wp-responsive-overlay' ),
 482          $toolbar = $( '#wp-toolbar' ),
 483          $toolbarPopups = $toolbar.find( 'a[aria-haspopup="true"]' ),
 484          $sortables = $('.meta-box-sortables'),
 485          wpResponsiveActive = false,
 486          $adminbar = $( '#wpadminbar' ),
 487          lastScrollPosition = 0,
 488          pinnedMenuTop = false,
 489          pinnedMenuBottom = false,
 490          menuTop = 0,
 491          menuState,
 492          menuIsPinned = false,
 493          height = {
 494              window: $window.height(),
 495              wpwrap: $wpwrap.height(),
 496              adminbar: $adminbar.height(),
 497              menu: $adminMenuWrap.height()
 498          },
 499          $headerEnd = $( '.wp-header-end' );
 500  
 501      /**
 502       * Makes the fly-out submenu header clickable, when the menu is folded.
 503       *
 504       * @param {Event} e The event object.
 505       *
 506       * @return {void}
 507       */
 508      $adminmenu.on('click.wp-submenu-head', '.wp-submenu-head', function(e){
 509          $(e.target).parent().siblings('a').get(0).click();
 510      });
 511  
 512      /**
 513       * Collapses the admin menu.
 514       *
 515       * @return {void}
 516       */
 517      $( '#collapse-button' ).on( 'click.collapse-menu', function() {
 518          var viewportWidth = getViewportWidth() || 961;
 519  
 520          // Reset any compensation for submenus near the bottom of the screen.
 521          $('#adminmenu div.wp-submenu').css('margin-top', '');
 522  
 523          if ( viewportWidth < 960 ) {
 524              if ( $body.hasClass('auto-fold') ) {
 525                  $body.removeClass('auto-fold').removeClass('folded');
 526                  setUserSetting('unfold', 1);
 527                  setUserSetting('mfold', 'o');
 528                  menuState = 'open';
 529              } else {
 530                  $body.addClass('auto-fold');
 531                  setUserSetting('unfold', 0);
 532                  menuState = 'folded';
 533              }
 534          } else {
 535              if ( $body.hasClass('folded') ) {
 536                  $body.removeClass('folded');
 537                  setUserSetting('mfold', 'o');
 538                  menuState = 'open';
 539              } else {
 540                  $body.addClass('folded');
 541                  setUserSetting('mfold', 'f');
 542                  menuState = 'folded';
 543              }
 544          }
 545  
 546          $document.trigger( 'wp-collapse-menu', { state: menuState } );
 547      });
 548  
 549      /**
 550       * Handles the `aria-haspopup` attribute on the current menu item when it has a submenu.
 551       *
 552       * @since 4.4.0
 553       *
 554       * @return {void}
 555       */
 556  	function currentMenuItemHasPopup() {
 557          var $current = $( 'a.wp-has-current-submenu' );
 558  
 559          if ( 'folded' === menuState ) {
 560              // When folded or auto-folded and not responsive view, the current menu item does have a fly-out sub-menu.
 561              $current.attr( 'aria-haspopup', 'true' );
 562          } else {
 563              // When expanded or in responsive view, reset aria-haspopup.
 564              $current.attr( 'aria-haspopup', 'false' );
 565          }
 566      }
 567  
 568      $document.on( 'wp-menu-state-set wp-collapse-menu wp-responsive-activate wp-responsive-deactivate', currentMenuItemHasPopup );
 569  
 570      /**
 571       * Ensures an admin submenu is within the visual viewport.
 572       *
 573       * @since 4.1.0
 574       *
 575       * @param {jQuery} $menuItem The parent menu item containing the submenu.
 576       *
 577       * @return {void}
 578       */
 579  	function adjustSubmenu( $menuItem ) {
 580          var bottomOffset, pageHeight, adjustment, theFold, menutop, wintop, maxtop,
 581              $submenu = $menuItem.find( '.wp-submenu' );
 582  
 583          menutop = $menuItem.offset().top;
 584          wintop = $window.scrollTop();
 585          maxtop = menutop - wintop - 30; // max = make the top of the sub almost touch admin bar.
 586  
 587          bottomOffset = menutop + $submenu.height() + 1; // Bottom offset of the menu.
 588          pageHeight = $wpwrap.height();                  // Height of the entire page.
 589          adjustment = 60 + bottomOffset - pageHeight;
 590          theFold = $window.height() + wintop - 50;       // The fold.
 591  
 592          if ( theFold < ( bottomOffset - adjustment ) ) {
 593              adjustment = bottomOffset - theFold;
 594          }
 595  
 596          if ( adjustment > maxtop ) {
 597              adjustment = maxtop;
 598          }
 599  
 600          if ( adjustment > 1 ) {
 601              $submenu.css( 'margin-top', '-' + adjustment + 'px' );
 602          } else {
 603              $submenu.css( 'margin-top', '' );
 604          }
 605      }
 606  
 607      if ( 'ontouchstart' in window || /IEMobile\/[1-9]/.test(navigator.userAgent) ) { // Touch screen device.
 608          // iOS Safari works with touchstart, the rest work with click.
 609          mobileEvent = isIOS ? 'touchstart' : 'click';
 610  
 611          /**
 612           * Closes any open submenus when touch/click is not on the menu.
 613           *
 614           * @param {Event} e The event object.
 615           *
 616           * @return {void}
 617           */
 618          $body.on( mobileEvent+'.wp-mobile-hover', function(e) {
 619              if ( $adminmenu.data('wp-responsive') ) {
 620                  return;
 621              }
 622  
 623              if ( ! $( e.target ).closest( '#adminmenu' ).length ) {
 624                  $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
 625              }
 626          });
 627  
 628          /**
 629           * Handles the opening or closing the submenu based on the mobile click|touch event.
 630           *
 631           * @param {Event} event The event object.
 632           *
 633           * @return {void}
 634           */
 635          $adminmenu.find( 'a.wp-has-submenu' ).on( mobileEvent + '.wp-mobile-hover', function( event ) {
 636              var $menuItem = $(this).parent();
 637  
 638              if ( $adminmenu.data( 'wp-responsive' ) ) {
 639                  return;
 640              }
 641  
 642              /*
 643               * Show the sub instead of following the link if:
 644               *     - the submenu is not open.
 645               *     - the submenu is not shown inline or the menu is not folded.
 646               */
 647              if ( ! $menuItem.hasClass( 'opensub' ) && ( ! $menuItem.hasClass( 'wp-menu-open' ) || $menuItem.width() < 40 ) ) {
 648                  event.preventDefault();
 649                  adjustSubmenu( $menuItem );
 650                  $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
 651                  $menuItem.addClass('opensub');
 652              }
 653          });
 654      }
 655  
 656      if ( ! isIOS && ! isAndroid ) {
 657          $adminmenu.find( 'li.wp-has-submenu' ).hoverIntent({
 658  
 659              /**
 660               * Opens the submenu when hovered over the menu item for desktops.
 661               *
 662               * @return {void}
 663               */
 664              over: function() {
 665                  var $menuItem = $( this ),
 666                      $submenu = $menuItem.find( '.wp-submenu' ),
 667                      top = parseInt( $submenu.css( 'top' ), 10 );
 668  
 669                  if ( isNaN( top ) || top > -5 ) { // The submenu is visible.
 670                      return;
 671                  }
 672  
 673                  if ( $adminmenu.data( 'wp-responsive' ) ) {
 674                      // The menu is in responsive mode, bail.
 675                      return;
 676                  }
 677  
 678                  adjustSubmenu( $menuItem );
 679                  $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
 680                  $menuItem.addClass( 'opensub' );
 681              },
 682  
 683              /**
 684               * Closes the submenu when no longer hovering the menu item.
 685               *
 686               * @return {void}
 687               */
 688              out: function(){
 689                  if ( $adminmenu.data( 'wp-responsive' ) ) {
 690                      // The menu is in responsive mode, bail.
 691                      return;
 692                  }
 693  
 694                  $( this ).removeClass( 'opensub' ).find( '.wp-submenu' ).css( 'margin-top', '' );
 695              },
 696              timeout: 200,
 697              sensitivity: 7,
 698              interval: 90
 699          });
 700  
 701          /**
 702           * Opens the submenu on when focused on the menu item.
 703           *
 704           * @param {Event} event The event object.
 705           *
 706           * @return {void}
 707           */
 708          $adminmenu.on( 'focus.adminmenu', '.wp-submenu a', function( event ) {
 709              if ( $adminmenu.data( 'wp-responsive' ) ) {
 710                  // The menu is in responsive mode, bail.
 711                  return;
 712              }
 713  
 714              $( event.target ).closest( 'li.menu-top' ).addClass( 'opensub' );
 715  
 716              /**
 717               * Closes the submenu on blur from the menu item.
 718               *
 719               * @param {Event} event The event object.
 720               *
 721               * @return {void}
 722               */
 723          }).on( 'blur.adminmenu', '.wp-submenu a', function( event ) {
 724              if ( $adminmenu.data( 'wp-responsive' ) ) {
 725                  return;
 726              }
 727  
 728              $( event.target ).closest( 'li.menu-top' ).removeClass( 'opensub' );
 729  
 730              /**
 731               * Adjusts the size for the submenu.
 732               *
 733               * @return {void}
 734               */
 735          }).find( 'li.wp-has-submenu.wp-not-current-submenu' ).on( 'focusin.adminmenu', function() {
 736              adjustSubmenu( $( this ) );
 737          });
 738      }
 739  
 740      /*
 741       * The `.below-h2` class is here just for backward compatibility with plugins
 742       * that are (incorrectly) using it. Do not use. Use `.inline` instead. See #34570.
 743       * If '.wp-header-end' is found, append the notices after it otherwise
 744       * after the first h1 or h2 heading found within the main content.
 745       */
 746      if ( ! $headerEnd.length ) {
 747          $headerEnd = $( '.wrap h1, .wrap h2' ).first();
 748      }
 749      $( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd );
 750  
 751      /**
 752       * Makes notices dismissible.
 753       *
 754       * @since 4.4.0
 755       *
 756       * @return {void}
 757       */
 758  	function makeNoticesDismissible() {
 759          $( '.notice.is-dismissible' ).each( function() {
 760              var $el = $( this ),
 761                  $button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' ),
 762                  btnText = commonL10n.dismiss || '';
 763  
 764              // Ensure plain text.
 765              $button.find( '.screen-reader-text' ).text( btnText );
 766              $button.on( 'click.wp-dismiss-notice', function( event ) {
 767                  event.preventDefault();
 768                  $el.fadeTo( 100, 0, function() {
 769                      $el.slideUp( 100, function() {
 770                          $el.remove();
 771                      });
 772                  });
 773              });
 774  
 775              $el.append( $button );
 776          });
 777      }
 778  
 779      $document.on( 'wp-updates-notice-added wp-plugin-install-error wp-plugin-update-error wp-plugin-delete-error wp-theme-install-error wp-theme-delete-error', makeNoticesDismissible );
 780  
 781      // Init screen meta.
 782      screenMeta.init();
 783  
 784      /**
 785       * Checks a checkbox.
 786       *
 787       * This event needs to be delegated. Ticket #37973.
 788       *
 789       * @return {boolean} Returns whether a checkbox is checked or not.
 790       */
 791      $body.on( 'click', 'tbody > tr > .check-column :checkbox', function( event ) {
 792          // Shift click to select a range of checkboxes.
 793          if ( 'undefined' == event.shiftKey ) { return true; }
 794          if ( event.shiftKey ) {
 795              if ( !lastClicked ) { return true; }
 796              checks = $( lastClicked ).closest( 'form' ).find( ':checkbox' ).filter( ':visible:enabled' );
 797              first = checks.index( lastClicked );
 798              last = checks.index( this );
 799              checked = $(this).prop('checked');
 800              if ( 0 < first && 0 < last && first != last ) {
 801                  sliced = ( last > first ) ? checks.slice( first, last ) : checks.slice( last, first );
 802                  sliced.prop( 'checked', function() {
 803                      if ( $(this).closest('tr').is(':visible') )
 804                          return checked;
 805  
 806                      return false;
 807                  });
 808              }
 809          }
 810          lastClicked = this;
 811  
 812          // Toggle the "Select all" checkboxes depending if the other ones are all checked or not.
 813          var unchecked = $(this).closest('tbody').find(':checkbox').filter(':visible:enabled').not(':checked');
 814  
 815          /**
 816           * Determines if all checkboxes are checked.
 817           *
 818           * @return {boolean} Returns true if there are no unchecked checkboxes.
 819           */
 820          $(this).closest('table').children('thead, tfoot').find(':checkbox').prop('checked', function() {
 821              return ( 0 === unchecked.length );
 822          });
 823  
 824          return true;
 825      });
 826  
 827      /**
 828       * Controls all the toggles on bulk toggle change.
 829       *
 830       * When the bulk checkbox is changed, all the checkboxes in the tables are changed accordingly.
 831       * When the shift-button is pressed while changing the bulk checkbox the checkboxes in the table are inverted.
 832       *
 833       * This event needs to be delegated. Ticket #37973.
 834       *
 835       * @param {Event} event The event object.
 836       *
 837       * @return {boolean}
 838       */
 839      $body.on( 'click.wp-toggle-checkboxes', 'thead .check-column :checkbox, tfoot .check-column :checkbox', function( event ) {
 840          var $this = $(this),
 841              $table = $this.closest( 'table' ),
 842              controlChecked = $this.prop('checked'),
 843              toggle = event.shiftKey || $this.data('wp-toggle');
 844  
 845          $table.children( 'tbody' ).filter(':visible')
 846              .children().children('.check-column').find(':checkbox')
 847              /**
 848               * Updates the checked state on the checkbox in the table.
 849               *
 850               * @return {boolean} True checks the checkbox, False unchecks the checkbox.
 851               */
 852              .prop('checked', function() {
 853                  if ( $(this).is(':hidden,:disabled') ) {
 854                      return false;
 855                  }
 856  
 857                  if ( toggle ) {
 858                      return ! $(this).prop( 'checked' );
 859                  } else if ( controlChecked ) {
 860                      return true;
 861                  }
 862  
 863                  return false;
 864              });
 865  
 866          $table.children('thead,  tfoot').filter(':visible')
 867              .children().children('.check-column').find(':checkbox')
 868  
 869              /**
 870               * Syncs the bulk checkboxes on the top and bottom of the table.
 871               *
 872               * @return {boolean} True checks the checkbox, False unchecks the checkbox.
 873               */
 874              .prop('checked', function() {
 875                  if ( toggle ) {
 876                      return false;
 877                  } else if ( controlChecked ) {
 878                      return true;
 879                  }
 880  
 881                  return false;
 882              });
 883      });
 884  
 885      /**
 886       * Shows row actions on focus of its parent container element or any other elements contained within.
 887       *
 888       * @return {void}
 889       */
 890      $( '#wpbody-content' ).on({
 891          focusin: function() {
 892              clearTimeout( transitionTimeout );
 893              focusedRowActions = $( this ).find( '.row-actions' );
 894              // transitionTimeout is necessary for Firefox, but Chrome won't remove the CSS class without a little help.
 895              $( '.row-actions' ).not( this ).removeClass( 'visible' );
 896              focusedRowActions.addClass( 'visible' );
 897          },
 898          focusout: function() {
 899              // Tabbing between post title and .row-actions links needs a brief pause, otherwise
 900              // the .row-actions div gets hidden in transit in some browsers (ahem, Firefox).
 901              transitionTimeout = setTimeout( function() {
 902                  focusedRowActions.removeClass( 'visible' );
 903              }, 30 );
 904          }
 905      }, '.has-row-actions' );
 906  
 907      // Toggle list table rows on small screens.
 908      $( 'tbody' ).on( 'click', '.toggle-row', function() {
 909          $( this ).closest( 'tr' ).toggleClass( 'is-expanded' );
 910      });
 911  
 912      $('#default-password-nag-no').click( function() {
 913          setUserSetting('default_password_nag', 'hide');
 914          $('div.default-password-nag').hide();
 915          return false;
 916      });
 917  
 918      /**
 919       * Handles tab keypresses in theme and plugin editor textareas.
 920       *
 921       * @param {Event} e The event object.
 922       *
 923       * @return {void}
 924       */
 925      $('#newcontent').bind('keydown.wpevent_InsertTab', function(e) {
 926          var el = e.target, selStart, selEnd, val, scroll, sel;
 927  
 928          // After pressing escape key (keyCode: 27), the tab key should tab out of the textarea.
 929          if ( e.keyCode == 27 ) {
 930              // When pressing Escape: Opera 12 and 27 blur form fields, IE 8 clears them.
 931              e.preventDefault();
 932              $(el).data('tab-out', true);
 933              return;
 934          }
 935  
 936          // Only listen for plain tab key (keyCode: 9) without any modifiers.
 937          if ( e.keyCode != 9 || e.ctrlKey || e.altKey || e.shiftKey )
 938              return;
 939  
 940          // After tabbing out, reset it so next time the tab key can be used again.
 941          if ( $(el).data('tab-out') ) {
 942              $(el).data('tab-out', false);
 943              return;
 944          }
 945  
 946          selStart = el.selectionStart;
 947          selEnd = el.selectionEnd;
 948          val = el.value;
 949  
 950          // If any text is selected, replace the selection with a tab character.
 951          if ( document.selection ) {
 952              el.focus();
 953              sel = document.selection.createRange();
 954              sel.text = '\t';
 955          } else if ( selStart >= 0 ) {
 956              scroll = this.scrollTop;
 957              el.value = val.substring(0, selStart).concat('\t', val.substring(selEnd) );
 958              el.selectionStart = el.selectionEnd = selStart + 1;
 959              this.scrollTop = scroll;
 960          }
 961  
 962          // Cancel the regular tab functionality, to prevent losing focus of the textarea.
 963          if ( e.stopPropagation )
 964              e.stopPropagation();
 965          if ( e.preventDefault )
 966              e.preventDefault();
 967      });
 968  
 969      // Reset page number variable for new filters/searches but not for bulk actions. See #17685.
 970      if ( pageInput.length ) {
 971  
 972          /**
 973           * Handles pagination variable when filtering the list table.
 974           *
 975           * Set the pagination argument to the first page when the post-filter form is submitted.
 976           * This happens when pressing the 'filter' button on the list table page.
 977           *
 978           * The pagination argument should not be touched when the bulk action dropdowns are set to do anything.
 979           *
 980           * The form closest to the pageInput is the post-filter form.
 981           *
 982           * @return {void}
 983           */
 984          pageInput.closest('form').submit( function() {
 985              /*
 986               * action = bulk action dropdown at the top of the table
 987               * action2 = bulk action dropdow at the bottom of the table
 988               */
 989              if ( $('select[name="action"]').val() == -1 && $('select[name="action2"]').val() == -1 && pageInput.val() == currentPage )
 990                  pageInput.val('1');
 991          });
 992      }
 993  
 994      /**
 995       * Resets the bulk actions when the search button is clicked.
 996       *
 997       * @return {void}
 998       */
 999      $('.search-box input[type="search"], .search-box input[type="submit"]').mousedown(function () {
1000          $('select[name^="action"]').val('-1');
1001      });
1002  
1003      /**
1004       * Scrolls into view when focus.scroll-into-view is triggered.
1005       *
1006       * @param {Event} e The event object.
1007       *
1008       * @return {void}
1009        */
1010      $('#contextual-help-link, #show-settings-link').on( 'focus.scroll-into-view', function(e){
1011          if ( e.target.scrollIntoView )
1012              e.target.scrollIntoView(false);
1013      });
1014  
1015      /**
1016       * Disables the submit upload buttons when no data is entered.
1017       *
1018       * @return {void}
1019       */
1020      (function(){
1021          var button, input, form = $('form.wp-upload-form');
1022  
1023          // Exit when no upload form is found.
1024          if ( ! form.length )
1025              return;
1026  
1027          button = form.find('input[type="submit"]');
1028          input = form.find('input[type="file"]');
1029  
1030          /**
1031           * Determines if any data is entered in any file upload input.
1032           *
1033           * @since 3.5.0
1034           *
1035           * @return {void}
1036           */
1037  		function toggleUploadButton() {
1038              // When no inputs have a value, disable the upload buttons.
1039              button.prop('disabled', '' === input.map( function() {
1040                  return $(this).val();
1041              }).get().join(''));
1042          }
1043  
1044          // Update the status initially.
1045          toggleUploadButton();
1046          // Update the status when any file input changes.
1047          input.on('change', toggleUploadButton);
1048      })();
1049  
1050      /**
1051       * Pins the menu while distraction-free writing is enabled.
1052       *
1053       * @param {Event} event Event data.
1054       *
1055       * @since 4.1.0
1056       *
1057       * @return {void}
1058       */
1059  	function pinMenu( event ) {
1060          var windowPos = $window.scrollTop(),
1061              resizing = ! event || event.type !== 'scroll';
1062  
1063          if ( isIOS || isIE8 || $adminmenu.data( 'wp-responsive' ) ) {
1064              return;
1065          }
1066  
1067          /*
1068           * When the menu is higher than the window and smaller than the entire page.
1069           * It should be adjusted to be able to see the entire menu.
1070           *
1071           * Otherwise it can be accessed normally.
1072           */
1073          if ( height.menu + height.adminbar < height.window ||
1074              height.menu + height.adminbar + 20 > height.wpwrap ) {
1075              unpinMenu();
1076              return;
1077          }
1078  
1079          menuIsPinned = true;
1080  
1081          // If the menu is higher than the window, compensate on scroll.
1082          if ( height.menu + height.adminbar > height.window ) {
1083              // Check for overscrolling, this happens when swiping up at the top of the document in modern browsers.
1084              if ( windowPos < 0 ) {
1085                  // Stick the menu to the top.
1086                  if ( ! pinnedMenuTop ) {
1087                      pinnedMenuTop = true;
1088                      pinnedMenuBottom = false;
1089  
1090                      $adminMenuWrap.css({
1091                          position: 'fixed',
1092                          top: '',
1093                          bottom: ''
1094                      });
1095                  }
1096  
1097                  return;
1098              } else if ( windowPos + height.window > $document.height() - 1 ) {
1099                  // When overscrolling at the bottom, stick the menu to the bottom.
1100                  if ( ! pinnedMenuBottom ) {
1101                      pinnedMenuBottom = true;
1102                      pinnedMenuTop = false;
1103  
1104                      $adminMenuWrap.css({
1105                          position: 'fixed',
1106                          top: '',
1107                          bottom: 0
1108                      });
1109                  }
1110  
1111                  return;
1112              }
1113  
1114              if ( windowPos > lastScrollPosition ) {
1115                  // When a down scroll has been detected.
1116  
1117                  // If it was pinned to the top, unpin and calculate relative scroll.
1118                  if ( pinnedMenuTop ) {
1119                      pinnedMenuTop = false;
1120                      // Calculate new offset position.
1121                      menuTop = $adminMenuWrap.offset().top - height.adminbar - ( windowPos - lastScrollPosition );
1122  
1123                      if ( menuTop + height.menu + height.adminbar < windowPos + height.window ) {
1124                          menuTop = windowPos + height.window - height.menu - height.adminbar;
1125                      }
1126  
1127                      $adminMenuWrap.css({
1128                          position: 'absolute',
1129                          top: menuTop,
1130                          bottom: ''
1131                      });
1132                  } else if ( ! pinnedMenuBottom && $adminMenuWrap.offset().top + height.menu < windowPos + height.window ) {
1133                      // Pin it to the bottom.
1134                      pinnedMenuBottom = true;
1135  
1136                      $adminMenuWrap.css({
1137                          position: 'fixed',
1138                          top: '',
1139                          bottom: 0
1140                      });
1141                  }
1142              } else if ( windowPos < lastScrollPosition ) {
1143                  // When a scroll up is detected.
1144  
1145                  // If it was pinned to the bottom, unpin and calculate relative scroll.
1146                  if ( pinnedMenuBottom ) {
1147                      pinnedMenuBottom = false;
1148  
1149                      // Calculate new offset position.
1150                      menuTop = $adminMenuWrap.offset().top - height.adminbar + ( lastScrollPosition - windowPos );
1151  
1152                      if ( menuTop + height.menu > windowPos + height.window ) {
1153                          menuTop = windowPos;
1154                      }
1155  
1156                      $adminMenuWrap.css({
1157                          position: 'absolute',
1158                          top: menuTop,
1159                          bottom: ''
1160                      });
1161                  } else if ( ! pinnedMenuTop && $adminMenuWrap.offset().top >= windowPos + height.adminbar ) {
1162  
1163                      // Pin it to the top.
1164                      pinnedMenuTop = true;
1165  
1166                      $adminMenuWrap.css({
1167                          position: 'fixed',
1168                          top: '',
1169                          bottom: ''
1170                      });
1171                  }
1172              } else if ( resizing ) {
1173                  // Window is being resized.
1174  
1175                  pinnedMenuTop = pinnedMenuBottom = false;
1176  
1177                  // Calculate the new offset.
1178                  menuTop = windowPos + height.window - height.menu - height.adminbar - 1;
1179  
1180                  if ( menuTop > 0 ) {
1181                      $adminMenuWrap.css({
1182                          position: 'absolute',
1183                          top: menuTop,
1184                          bottom: ''
1185                      });
1186                  } else {
1187                      unpinMenu();
1188                  }
1189              }
1190          }
1191  
1192          lastScrollPosition = windowPos;
1193      }
1194  
1195      /**
1196       * Determines the height of certain elements.
1197       *
1198       * @since 4.1.0
1199       *
1200       * @return {void}
1201       */
1202  	function resetHeights() {
1203          height = {
1204              window: $window.height(),
1205              wpwrap: $wpwrap.height(),
1206              adminbar: $adminbar.height(),
1207              menu: $adminMenuWrap.height()
1208          };
1209      }
1210  
1211      /**
1212       * Unpins the menu.
1213       *
1214       * @since 4.1.0
1215       *
1216       * @return {void}
1217       */
1218  	function unpinMenu() {
1219          if ( isIOS || ! menuIsPinned ) {
1220              return;
1221          }
1222  
1223          pinnedMenuTop = pinnedMenuBottom = menuIsPinned = false;
1224          $adminMenuWrap.css({
1225              position: '',
1226              top: '',
1227              bottom: ''
1228          });
1229      }
1230  
1231      /**
1232       * Pins and unpins the menu when applicable.
1233       *
1234       * @since 4.1.0
1235       *
1236       * @return {void}
1237       */
1238  	function setPinMenu() {
1239          resetHeights();
1240  
1241          if ( $adminmenu.data('wp-responsive') ) {
1242              $body.removeClass( 'sticky-menu' );
1243              unpinMenu();
1244          } else if ( height.menu + height.adminbar > height.window ) {
1245              pinMenu();
1246              $body.removeClass( 'sticky-menu' );
1247          } else {
1248              $body.addClass( 'sticky-menu' );
1249              unpinMenu();
1250          }
1251      }
1252  
1253      if ( ! isIOS ) {
1254          $window.on( 'scroll.pin-menu', pinMenu );
1255          $document.on( 'tinymce-editor-init.pin-menu', function( event, editor ) {
1256              editor.on( 'wp-autoresize', resetHeights );
1257          });
1258      }
1259  
1260      /**
1261       * Changes the sortables and responsiveness of metaboxes.
1262       *
1263       * @since 3.8.0
1264       *
1265       * @return {void}
1266       */
1267      window.wpResponsive = {
1268  
1269          /**
1270           * Initializes the wpResponsive object.
1271           *
1272           * @since 3.8.0
1273           *
1274           * @return {void}
1275           */
1276          init: function() {
1277              var self = this;
1278  
1279              this.maybeDisableSortables = this.maybeDisableSortables.bind( this );
1280  
1281              // Modify functionality based on custom activate/deactivate event.
1282              $document.on( 'wp-responsive-activate.wp-responsive', function() {
1283                  self.activate();
1284              }).on( 'wp-responsive-deactivate.wp-responsive', function() {
1285                  self.deactivate();
1286              });
1287  
1288              $( '#wp-admin-bar-menu-toggle a' ).attr( 'aria-expanded', 'false' );
1289  
1290              // Toggle sidebar when toggle is clicked.
1291              $( '#wp-admin-bar-menu-toggle' ).on( 'click.wp-responsive', function( event ) {
1292                  event.preventDefault();
1293  
1294                  // Close any open toolbar submenus.
1295                  $adminbar.find( '.hover' ).removeClass( 'hover' );
1296  
1297                  $wpwrap.toggleClass( 'wp-responsive-open' );
1298                  if ( $wpwrap.hasClass( 'wp-responsive-open' ) ) {
1299                      $(this).find('a').attr( 'aria-expanded', 'true' );
1300                      $( '#adminmenu a:first' ).focus();
1301                  } else {
1302                      $(this).find('a').attr( 'aria-expanded', 'false' );
1303                  }
1304              } );
1305  
1306              // Add menu events.
1307              $adminmenu.on( 'click.wp-responsive', 'li.wp-has-submenu > a', function( event ) {
1308                  if ( ! $adminmenu.data('wp-responsive') ) {
1309                      return;
1310                  }
1311  
1312                  $( this ).parent( 'li' ).toggleClass( 'selected' );
1313                  event.preventDefault();
1314              });
1315  
1316              self.trigger();
1317              $document.on( 'wp-window-resized.wp-responsive', $.proxy( this.trigger, this ) );
1318  
1319              // This needs to run later as UI Sortable may be initialized later on $(document).ready().
1320              $window.on( 'load.wp-responsive', this.maybeDisableSortables );
1321              $document.on( 'postbox-toggled', this.maybeDisableSortables );
1322  
1323              // When the screen columns are changed, potentially disable sortables.
1324              $( '#screen-options-wrap input' ).on( 'click', this.maybeDisableSortables );
1325          },
1326  
1327          /**
1328           * Disable sortables if there is only one metabox, or the screen is in one column mode. Otherwise, enable sortables.
1329           *
1330           * @since 5.3.0
1331           *
1332           * @return {void}
1333           */
1334          maybeDisableSortables: function() {
1335              var width = navigator.userAgent.indexOf('AppleWebKit/') > -1 ? $window.width() : window.innerWidth;
1336  
1337              if (
1338                  ( width <= 782 ) ||
1339                  ( 1 >= $sortables.find( '.ui-sortable-handle:visible' ).length && jQuery( '.columns-prefs-1 input' ).prop( 'checked' ) )
1340              ) {
1341                  this.disableSortables();
1342              } else {
1343                  this.enableSortables();
1344              }
1345          },
1346  
1347          /**
1348           * Changes properties of body and admin menu.
1349           *
1350           * Pins and unpins the menu and adds the auto-fold class to the body.
1351           * Makes the admin menu responsive and disables the metabox sortables.
1352           *
1353           * @since 3.8.0
1354           *
1355           * @return {void}
1356           */
1357          activate: function() {
1358              setPinMenu();
1359  
1360              if ( ! $body.hasClass( 'auto-fold' ) ) {
1361                  $body.addClass( 'auto-fold' );
1362              }
1363  
1364              $adminmenu.data( 'wp-responsive', 1 );
1365              this.disableSortables();
1366          },
1367  
1368          /**
1369           * Changes properties of admin menu and enables metabox sortables.
1370           *
1371           * Pin and unpin the menu.
1372           * Removes the responsiveness of the admin menu and enables the metabox sortables.
1373           *
1374           * @since 3.8.0
1375           *
1376           * @return {void}
1377           */
1378          deactivate: function() {
1379              setPinMenu();
1380              $adminmenu.removeData('wp-responsive');
1381  
1382              this.maybeDisableSortables();
1383          },
1384  
1385          /**
1386           * Sets the responsiveness and enables the overlay based on the viewport width.
1387           *
1388           * @since 3.8.0
1389           *
1390           * @return {void}
1391           */
1392          trigger: function() {
1393              var viewportWidth = getViewportWidth();
1394  
1395              // Exclude IE < 9, it doesn't support @media CSS rules.
1396              if ( ! viewportWidth ) {
1397                  return;
1398              }
1399  
1400              if ( viewportWidth <= 782 ) {
1401                  if ( ! wpResponsiveActive ) {
1402                      $document.trigger( 'wp-responsive-activate' );
1403                      wpResponsiveActive = true;
1404                  }
1405              } else {
1406                  if ( wpResponsiveActive ) {
1407                      $document.trigger( 'wp-responsive-deactivate' );
1408                      wpResponsiveActive = false;
1409                  }
1410              }
1411  
1412              if ( viewportWidth <= 480 ) {
1413                  this.enableOverlay();
1414              } else {
1415                  this.disableOverlay();
1416              }
1417  
1418              this.maybeDisableSortables();
1419          },
1420  
1421          /**
1422           * Inserts a responsive overlay and toggles the window.
1423           *
1424           * @since 3.8.0
1425           *
1426           * @return {void}
1427           */
1428          enableOverlay: function() {
1429              if ( $overlay.length === 0 ) {
1430                  $overlay = $( '<div id="wp-responsive-overlay"></div>' )
1431                      .insertAfter( '#wpcontent' )
1432                      .hide()
1433                      .on( 'click.wp-responsive', function() {
1434                          $toolbar.find( '.menupop.hover' ).removeClass( 'hover' );
1435                          $( this ).hide();
1436                      });
1437              }
1438  
1439              $toolbarPopups.on( 'click.wp-responsive', function() {
1440                  $overlay.show();
1441              });
1442          },
1443  
1444          /**
1445           * Disables the responsive overlay and removes the overlay.
1446           *
1447           * @since 3.8.0
1448           *
1449           * @return {void}
1450           */
1451          disableOverlay: function() {
1452              $toolbarPopups.off( 'click.wp-responsive' );
1453              $overlay.hide();
1454          },
1455  
1456          /**
1457           * Disables sortables.
1458           *
1459           * @since 3.8.0
1460           *
1461           * @return {void}
1462           */
1463          disableSortables: function() {
1464              if ( $sortables.length ) {
1465                  try {
1466                      $sortables.sortable( 'disable' );
1467                      $sortables.find( '.ui-sortable-handle' ).addClass( 'is-non-sortable' );
1468                  } catch ( e ) {}
1469              }
1470          },
1471  
1472          /**
1473           * Enables sortables.
1474           *
1475           * @since 3.8.0
1476           *
1477           * @return {void}
1478           */
1479          enableSortables: function() {
1480              if ( $sortables.length ) {
1481                  try {
1482                      $sortables.sortable( 'enable' );
1483                      $sortables.find( '.ui-sortable-handle' ).removeClass( 'is-non-sortable' );
1484                  } catch ( e ) {}
1485              }
1486          }
1487      };
1488  
1489      /**
1490       * Add an ARIA role `button` to elements that behave like UI controls when JavaScript is on.
1491       *
1492       * @since 4.5.0
1493       *
1494       * @return {void}
1495       */
1496  	function aria_button_if_js() {
1497          $( '.aria-button-if-js' ).attr( 'role', 'button' );
1498      }
1499  
1500      $( document ).ajaxComplete( function() {
1501          aria_button_if_js();
1502      });
1503  
1504      /**
1505       * Get the viewport width.
1506       *
1507       * @since 4.7.0
1508       *
1509       * @return {number|boolean} The current viewport width or false if the
1510       *                          browser doesn't support innerWidth (IE < 9).
1511       */
1512  	function getViewportWidth() {
1513          var viewportWidth = false;
1514  
1515          if ( window.innerWidth ) {
1516              // On phones, window.innerWidth is affected by zooming.
1517              viewportWidth = Math.max( window.innerWidth, document.documentElement.clientWidth );
1518          }
1519  
1520          return viewportWidth;
1521      }
1522  
1523      /**
1524       * Sets the admin menu collapsed/expanded state.
1525       *
1526       * Sets the global variable `menuState` and triggers a custom event passing
1527       * the current menu state.
1528       *
1529       * @since 4.7.0
1530       *
1531       * @return {void}
1532       */
1533  	function setMenuState() {
1534          var viewportWidth = getViewportWidth() || 961;
1535  
1536          if ( viewportWidth <= 782  ) {
1537              menuState = 'responsive';
1538          } else if ( $body.hasClass( 'folded' ) || ( $body.hasClass( 'auto-fold' ) && viewportWidth <= 960 && viewportWidth > 782 ) ) {
1539              menuState = 'folded';
1540          } else {
1541              menuState = 'open';
1542          }
1543  
1544          $document.trigger( 'wp-menu-state-set', { state: menuState } );
1545      }
1546  
1547      // Set the menu state when the window gets resized.
1548      $document.on( 'wp-window-resized.set-menu-state', setMenuState );
1549  
1550      /**
1551       * Sets ARIA attributes on the collapse/expand menu button.
1552       *
1553       * When the admin menu is open or folded, updates the `aria-expanded` and
1554       * `aria-label` attributes of the button to give feedback to assistive
1555       * technologies. In the responsive view, the button is always hidden.
1556       *
1557       * @since 4.7.0
1558       *
1559       * @return {void}
1560       */
1561      $document.on( 'wp-menu-state-set wp-collapse-menu', function( event, eventData ) {
1562          var $collapseButton = $( '#collapse-button' ),
1563              ariaExpanded = 'true',
1564              ariaLabelText = commonL10n.collapseMenu;
1565  
1566          if ( 'folded' === eventData.state ) {
1567              ariaExpanded = 'false';
1568              ariaLabelText = commonL10n.expandMenu;
1569          }
1570  
1571          $collapseButton.attr({
1572              'aria-expanded': ariaExpanded,
1573              'aria-label': ariaLabelText
1574          });
1575      });
1576  
1577      window.wpResponsive.init();
1578      setPinMenu();
1579      setMenuState();
1580      currentMenuItemHasPopup();
1581      makeNoticesDismissible();
1582      aria_button_if_js();
1583  
1584      $document.on( 'wp-pin-menu wp-window-resized.pin-menu postboxes-columnchange.pin-menu postbox-toggled.pin-menu wp-collapse-menu.pin-menu wp-scroll-start.pin-menu', setPinMenu );
1585  
1586      // Set initial focus on a specific element.
1587      $( '.wp-initial-focus' ).focus();
1588  
1589      // Toggle update details on update-core.php.
1590      $body.on( 'click', '.js-update-details-toggle', function() {
1591          var $updateNotice = $( this ).closest( '.js-update-details' ),
1592              $progressDiv = $( '#' + $updateNotice.data( 'update-details' ) );
1593  
1594          /*
1595           * When clicking on "Show details" move the progress div below the update
1596           * notice. Make sure it gets moved just the first time.
1597           */
1598          if ( ! $progressDiv.hasClass( 'update-details-moved' ) ) {
1599              $progressDiv.insertAfter( $updateNotice ).addClass( 'update-details-moved' );
1600          }
1601  
1602          // Toggle the progress div visibility.
1603          $progressDiv.toggle();
1604          // Toggle the Show Details button expanded state.
1605          $( this ).attr( 'aria-expanded', $progressDiv.is( ':visible' ) );
1606      });
1607  });
1608  
1609  // Fire a custom jQuery event at the end of window resize.
1610  ( function() {
1611      var timeout;
1612  
1613      /**
1614       * Triggers the WP window-resize event.
1615       *
1616       * @since 3.8.0
1617       *
1618       * @return {void}
1619       */
1620  	function triggerEvent() {
1621          $document.trigger( 'wp-window-resized' );
1622      }
1623  
1624      /**
1625       * Fires the trigger event again after 200 ms.
1626       *
1627       * @since 3.8.0
1628       *
1629       * @return {void}
1630       */
1631  	function fireOnce() {
1632          window.clearTimeout( timeout );
1633          timeout = window.setTimeout( triggerEvent, 200 );
1634      }
1635  
1636      $window.on( 'resize.wp-fire-once', fireOnce );
1637  }());
1638  
1639  // Make Windows 8 devices play along nicely.
1640  (function(){
1641      if ( '-ms-user-select' in document.documentElement.style && navigator.userAgent.match(/IEMobile\/10\.0/) ) {
1642          var msViewportStyle = document.createElement( 'style' );
1643          msViewportStyle.appendChild(
1644              document.createTextNode( '@-ms-viewport{width:auto!important}' )
1645          );
1646          document.getElementsByTagName( 'head' )[0].appendChild( msViewportStyle );
1647      }
1648  })();
1649  
1650  }( jQuery, window ));


Generated: Sun Apr 5 01:00:03 2020 Cross-referenced by PHPXref 0.7.1