[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

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       * @returns {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       * @returns {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       * @returns {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       * @returns {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       * @returns {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       * @returns {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   * @returns {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   * @returns {void}
 180   */
 181  window.showNotice = {
 182  
 183      /**
 184       * Shows a delete confirmation pop-up message.
 185       *
 186       * @since 2.7.0
 187       *
 188       * @returns {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   * @returns {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       * @returns {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       * @returns {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       * @returns {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           * @returns {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       * @returns {void}
 301       */
 302      close: function( panel, button ) {
 303          /**
 304           * Hides the screen meta options panel.
 305           *
 306           * @since 3.2.0
 307           *
 308           * @returns {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   * @returns {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       * @returns {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       * @returns {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       * @returns {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       * @returns {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           * @returns {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           * @returns {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              // Show the sub instead of following the link if:
 643              //    - the submenu is not open
 644              //    - the submenu is not shown inline or the menu is not folded
 645              if ( ! $menuItem.hasClass( 'opensub' ) && ( ! $menuItem.hasClass( 'wp-menu-open' ) || $menuItem.width() < 40 ) ) {
 646                  event.preventDefault();
 647                  adjustSubmenu( $menuItem );
 648                  $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
 649                  $menuItem.addClass('opensub');
 650              }
 651          });
 652      }
 653  
 654      if ( ! isIOS && ! isAndroid ) {
 655          $adminmenu.find( 'li.wp-has-submenu' ).hoverIntent({
 656  
 657              /**
 658               * Opens the submenu when hovered over the menu item for desktops.
 659               *
 660               * @returns {void}
 661               */
 662              over: function() {
 663                  var $menuItem = $( this ),
 664                      $submenu = $menuItem.find( '.wp-submenu' ),
 665                      top = parseInt( $submenu.css( 'top' ), 10 );
 666  
 667                  if ( isNaN( top ) || top > -5 ) { // the submenu is visible
 668                      return;
 669                  }
 670  
 671                  if ( $adminmenu.data( 'wp-responsive' ) ) {
 672                      // The menu is in responsive mode, bail
 673                      return;
 674                  }
 675  
 676                  adjustSubmenu( $menuItem );
 677                  $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
 678                  $menuItem.addClass( 'opensub' );
 679              },
 680  
 681              /**
 682               * Closes the submenu when no longer hovering the menu item.
 683               *
 684               * @returns {void}
 685               */
 686              out: function(){
 687                  if ( $adminmenu.data( 'wp-responsive' ) ) {
 688                      // The menu is in responsive mode, bail
 689                      return;
 690                  }
 691  
 692                  $( this ).removeClass( 'opensub' ).find( '.wp-submenu' ).css( 'margin-top', '' );
 693              },
 694              timeout: 200,
 695              sensitivity: 7,
 696              interval: 90
 697          });
 698  
 699          /**
 700           * Opens the submenu on when focused on the menu item.
 701           *
 702           * @param {Event} event The event object.
 703           *
 704           * @returns {void}
 705           */
 706          $adminmenu.on( 'focus.adminmenu', '.wp-submenu a', function( event ) {
 707              if ( $adminmenu.data( 'wp-responsive' ) ) {
 708                  // The menu is in responsive mode, bail
 709                  return;
 710              }
 711  
 712              $( event.target ).closest( 'li.menu-top' ).addClass( 'opensub' );
 713  
 714              /**
 715               * Closes the submenu on blur from the menu item.
 716               *
 717               * @param {Event} event The event object.
 718               *
 719               * @returns {void}
 720               */
 721          }).on( 'blur.adminmenu', '.wp-submenu a', function( event ) {
 722              if ( $adminmenu.data( 'wp-responsive' ) ) {
 723                  return;
 724              }
 725  
 726              $( event.target ).closest( 'li.menu-top' ).removeClass( 'opensub' );
 727  
 728              /**
 729               * Adjusts the size for the submenu.
 730               *
 731               * @returns {void}
 732               */
 733          }).find( 'li.wp-has-submenu.wp-not-current-submenu' ).on( 'focusin.adminmenu', function() {
 734              adjustSubmenu( $( this ) );
 735          });
 736      }
 737  
 738      /*
 739       * The `.below-h2` class is here just for backward compatibility with plugins
 740       * that are (incorrectly) using it. Do not use. Use `.inline` instead. See #34570.
 741       * If '.wp-header-end' is found, append the notices after it otherwise
 742       * after the first h1 or h2 heading found within the main content.
 743       */
 744      if ( ! $headerEnd.length ) {
 745          $headerEnd = $( '.wrap h1, .wrap h2' ).first();
 746      }
 747      $( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd );
 748  
 749      /**
 750       * Makes notices dismissible.
 751       *
 752       * @since 4.4.0
 753       *
 754       * @returns {void}
 755       */
 756  	function makeNoticesDismissible() {
 757          $( '.notice.is-dismissible' ).each( function() {
 758              var $el = $( this ),
 759                  $button = $( '<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>' ),
 760                  btnText = commonL10n.dismiss || '';
 761  
 762              // Ensure plain text
 763              $button.find( '.screen-reader-text' ).text( btnText );
 764              $button.on( 'click.wp-dismiss-notice', function( event ) {
 765                  event.preventDefault();
 766                  $el.fadeTo( 100, 0, function() {
 767                      $el.slideUp( 100, function() {
 768                          $el.remove();
 769                      });
 770                  });
 771              });
 772  
 773              $el.append( $button );
 774          });
 775      }
 776  
 777      $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 );
 778  
 779      // Init screen meta
 780      screenMeta.init();
 781  
 782      /**
 783       * Checks a checkbox.
 784       *
 785       * This event needs to be delegated. Ticket #37973.
 786       *
 787       * @returns {boolean} Returns whether a checkbox is checked or not.
 788       */
 789      $body.on( 'click', 'tbody > tr > .check-column :checkbox', function( event ) {
 790          // Shift click to select a range of checkboxes.
 791          if ( 'undefined' == event.shiftKey ) { return true; }
 792          if ( event.shiftKey ) {
 793              if ( !lastClicked ) { return true; }
 794              checks = $( lastClicked ).closest( 'form' ).find( ':checkbox' ).filter( ':visible:enabled' );
 795              first = checks.index( lastClicked );
 796              last = checks.index( this );
 797              checked = $(this).prop('checked');
 798              if ( 0 < first && 0 < last && first != last ) {
 799                  sliced = ( last > first ) ? checks.slice( first, last ) : checks.slice( last, first );
 800                  sliced.prop( 'checked', function() {
 801                      if ( $(this).closest('tr').is(':visible') )
 802                          return checked;
 803  
 804                      return false;
 805                  });
 806              }
 807          }
 808          lastClicked = this;
 809  
 810          // Toggle the "Select all" checkboxes depending if the other ones are all checked or not.
 811          var unchecked = $(this).closest('tbody').find(':checkbox').filter(':visible:enabled').not(':checked');
 812  
 813          /**
 814           * Determines if all checkboxes are checked.
 815           *
 816           * @returns {boolean} Returns true if there are no unchecked checkboxes.
 817           */
 818          $(this).closest('table').children('thead, tfoot').find(':checkbox').prop('checked', function() {
 819              return ( 0 === unchecked.length );
 820          });
 821  
 822          return true;
 823      });
 824  
 825      /**
 826       * Controls all the toggles on bulk toggle change.
 827       *
 828       * When the bulk checkbox is changed, all the checkboxes in the tables are changed accordingly.
 829       * When the shift-button is pressed while changing the bulk checkbox the checkboxes in the table are inverted.
 830       *
 831       * This event needs to be delegated. Ticket #37973.
 832       *
 833       * @param {Event} event The event object.
 834       *
 835       * @returns {boolean}
 836       */
 837      $body.on( 'click.wp-toggle-checkboxes', 'thead .check-column :checkbox, tfoot .check-column :checkbox', function( event ) {
 838          var $this = $(this),
 839              $table = $this.closest( 'table' ),
 840              controlChecked = $this.prop('checked'),
 841              toggle = event.shiftKey || $this.data('wp-toggle');
 842  
 843          $table.children( 'tbody' ).filter(':visible')
 844              .children().children('.check-column').find(':checkbox')
 845              /**
 846               * Updates the checked state on the checkbox in the table.
 847               *
 848               * @returns {boolean} True checks the checkbox, False unchecks the checkbox.
 849               */
 850              .prop('checked', function() {
 851                  if ( $(this).is(':hidden,:disabled') ) {
 852                      return false;
 853                  }
 854  
 855                  if ( toggle ) {
 856                      return ! $(this).prop( 'checked' );
 857                  } else if ( controlChecked ) {
 858                      return true;
 859                  }
 860  
 861                  return false;
 862              });
 863  
 864          $table.children('thead,  tfoot').filter(':visible')
 865              .children().children('.check-column').find(':checkbox')
 866  
 867              /**
 868               * Syncs the bulk checkboxes on the top and bottom of the table.
 869               *
 870               * @returns {boolean} True checks the checkbox, False unchecks the checkbox.
 871               */
 872              .prop('checked', function() {
 873                  if ( toggle ) {
 874                      return false;
 875                  } else if ( controlChecked ) {
 876                      return true;
 877                  }
 878  
 879                  return false;
 880              });
 881      });
 882  
 883      /**
 884       * Shows row actions on focus of its parent container element or any other elements contained within.
 885       *
 886       * @returns {void}
 887       */
 888      $( '#wpbody-content' ).on({
 889          focusin: function() {
 890              clearTimeout( transitionTimeout );
 891              focusedRowActions = $( this ).find( '.row-actions' );
 892              // transitionTimeout is necessary for Firefox, but Chrome won't remove the CSS class without a little help.
 893              $( '.row-actions' ).not( this ).removeClass( 'visible' );
 894              focusedRowActions.addClass( 'visible' );
 895          },
 896          focusout: function() {
 897              // Tabbing between post title and .row-actions links needs a brief pause, otherwise
 898              // the .row-actions div gets hidden in transit in some browsers (ahem, Firefox).
 899              transitionTimeout = setTimeout( function() {
 900                  focusedRowActions.removeClass( 'visible' );
 901              }, 30 );
 902          }
 903      }, '.has-row-actions' );
 904  
 905      // Toggle list table rows on small screens
 906      $( 'tbody' ).on( 'click', '.toggle-row', function() {
 907          $( this ).closest( 'tr' ).toggleClass( 'is-expanded' );
 908      });
 909  
 910      $('#default-password-nag-no').click( function() {
 911          setUserSetting('default_password_nag', 'hide');
 912          $('div.default-password-nag').hide();
 913          return false;
 914      });
 915  
 916      /**
 917       * Handles tab keypresses in theme and plugin editor textareas.
 918       *
 919       * @param {Event} e The event object.
 920       *
 921       * @returns {void}
 922       */
 923      $('#newcontent').bind('keydown.wpevent_InsertTab', function(e) {
 924          var el = e.target, selStart, selEnd, val, scroll, sel;
 925  
 926          // After pressing escape key (keyCode: 27), the tab key should tab out of the textarea.
 927          if ( e.keyCode == 27 ) {
 928              // when pressing Escape: Opera 12 and 27 blur form fields, IE 8 clears them
 929              e.preventDefault();
 930              $(el).data('tab-out', true);
 931              return;
 932          }
 933  
 934          // Only listen for plain tab key (keyCode: 9) without any modifiers.
 935          if ( e.keyCode != 9 || e.ctrlKey || e.altKey || e.shiftKey )
 936              return;
 937  
 938          // After tabbing out, reset it so next time the tab key can be used again.
 939          if ( $(el).data('tab-out') ) {
 940              $(el).data('tab-out', false);
 941              return;
 942          }
 943  
 944          selStart = el.selectionStart;
 945          selEnd = el.selectionEnd;
 946          val = el.value;
 947  
 948          // If any text is selected, replace the selection with a tab character.
 949          if ( document.selection ) {
 950              el.focus();
 951              sel = document.selection.createRange();
 952              sel.text = '\t';
 953          } else if ( selStart >= 0 ) {
 954              scroll = this.scrollTop;
 955              el.value = val.substring(0, selStart).concat('\t', val.substring(selEnd) );
 956              el.selectionStart = el.selectionEnd = selStart + 1;
 957              this.scrollTop = scroll;
 958          }
 959  
 960          // Cancel the regular tab functionality, to prevent losing focus of the textarea.
 961          if ( e.stopPropagation )
 962              e.stopPropagation();
 963          if ( e.preventDefault )
 964              e.preventDefault();
 965      });
 966  
 967      // Reset page number variable for new filters/searches but not for bulk actions. See #17685.
 968      if ( pageInput.length ) {
 969  
 970          /**
 971           * Handles pagination variable when filtering the list table.
 972           *
 973           * Set the pagination argument to the first page when the post-filter form is submitted.
 974           * This happens when pressing the 'filter' button on the list table page.
 975           *
 976           * The pagination argument should not be touched when the bulk action dropdowns are set to do anything.
 977           *
 978           * The form closest to the pageInput is the post-filter form.
 979           *
 980           * @returns {void}
 981           */
 982          pageInput.closest('form').submit( function() {
 983              /*
 984               * action = bulk action dropdown at the top of the table
 985               * action2 = bulk action dropdow at the bottom of the table
 986               */
 987              if ( $('select[name="action"]').val() == -1 && $('select[name="action2"]').val() == -1 && pageInput.val() == currentPage )
 988                  pageInput.val('1');
 989          });
 990      }
 991  
 992      /**
 993       * Resets the bulk actions when the search button is clicked.
 994       *
 995       * @returns {void}
 996       */
 997      $('.search-box input[type="search"], .search-box input[type="submit"]').mousedown(function () {
 998          $('select[name^="action"]').val('-1');
 999      });
1000  
1001      /**
1002       * Scrolls into view when focus.scroll-into-view is triggered.
1003       *
1004       * @param {Event} e The event object.
1005       *
1006       * @returns {void}
1007        */
1008      $('#contextual-help-link, #show-settings-link').on( 'focus.scroll-into-view', function(e){
1009          if ( e.target.scrollIntoView )
1010              e.target.scrollIntoView(false);
1011      });
1012  
1013      /**
1014       * Disables the submit upload buttons when no data is entered.
1015       *
1016       * @returns {void}
1017       */
1018      (function(){
1019          var button, input, form = $('form.wp-upload-form');
1020  
1021          // Exit when no upload form is found.
1022          if ( ! form.length )
1023              return;
1024  
1025          button = form.find('input[type="submit"]');
1026          input = form.find('input[type="file"]');
1027  
1028          /**
1029           * Determines if any data is entered in any file upload input.
1030           *
1031           * @since 3.5.0
1032           *
1033           * @returns {void}
1034           */
1035  		function toggleUploadButton() {
1036              // When no inputs have a value, disable the upload buttons.
1037              button.prop('disabled', '' === input.map( function() {
1038                  return $(this).val();
1039              }).get().join(''));
1040          }
1041  
1042          // Update the status initially.
1043          toggleUploadButton();
1044          // Update the status when any file input changes.
1045          input.on('change', toggleUploadButton);
1046      })();
1047  
1048      /**
1049       * Pins the menu while distraction-free writing is enabled.
1050       *
1051       * @param {Event} event Event data.
1052       *
1053       * @since 4.1.0
1054       *
1055       * @returns {void}
1056       */
1057  	function pinMenu( event ) {
1058          var windowPos = $window.scrollTop(),
1059              resizing = ! event || event.type !== 'scroll';
1060  
1061          if ( isIOS || isIE8 || $adminmenu.data( 'wp-responsive' ) ) {
1062              return;
1063          }
1064  
1065          /*
1066           * When the menu is higher than the window and smaller than the entire page.
1067           * It should be adjusted to be able to see the entire menu.
1068           *
1069           * Otherwise it can be accessed normally.
1070           */
1071          if ( height.menu + height.adminbar < height.window ||
1072              height.menu + height.adminbar + 20 > height.wpwrap ) {
1073              unpinMenu();
1074              return;
1075          }
1076  
1077          menuIsPinned = true;
1078  
1079          // If the menu is higher than the window, compensate on scroll.
1080          if ( height.menu + height.adminbar > height.window ) {
1081              // Check for overscrolling, this happens when swiping up at the top of the document in modern browsers.
1082              if ( windowPos < 0 ) {
1083                  // Stick the menu to the top.
1084                  if ( ! pinnedMenuTop ) {
1085                      pinnedMenuTop = true;
1086                      pinnedMenuBottom = false;
1087  
1088                      $adminMenuWrap.css({
1089                          position: 'fixed',
1090                          top: '',
1091                          bottom: ''
1092                      });
1093                  }
1094  
1095                  return;
1096              } else if ( windowPos + height.window > $document.height() - 1 ) {
1097                  // When overscrolling at the bottom, stick the menu to the bottom.
1098                  if ( ! pinnedMenuBottom ) {
1099                      pinnedMenuBottom = true;
1100                      pinnedMenuTop = false;
1101  
1102                      $adminMenuWrap.css({
1103                          position: 'fixed',
1104                          top: '',
1105                          bottom: 0
1106                      });
1107                  }
1108  
1109                  return;
1110              }
1111  
1112              if ( windowPos > lastScrollPosition ) {
1113                  // When a down scroll has been detected.
1114  
1115                  // If it was pinned to the top, unpin and calculate relative scroll.
1116                  if ( pinnedMenuTop ) {
1117                      pinnedMenuTop = false;
1118                      // Calculate new offset position.
1119                      menuTop = $adminMenuWrap.offset().top - height.adminbar - ( windowPos - lastScrollPosition );
1120  
1121                      if ( menuTop + height.menu + height.adminbar < windowPos + height.window ) {
1122                          menuTop = windowPos + height.window - height.menu - height.adminbar;
1123                      }
1124  
1125                      $adminMenuWrap.css({
1126                          position: 'absolute',
1127                          top: menuTop,
1128                          bottom: ''
1129                      });
1130                  } else if ( ! pinnedMenuBottom && $adminMenuWrap.offset().top + height.menu < windowPos + height.window ) {
1131                      // Pin it to the bottom.
1132                      pinnedMenuBottom = true;
1133  
1134                      $adminMenuWrap.css({
1135                          position: 'fixed',
1136                          top: '',
1137                          bottom: 0
1138                      });
1139                  }
1140              } else if ( windowPos < lastScrollPosition ) {
1141                  // When a scroll up is detected.
1142  
1143                  // If it was pinned to the bottom, unpin and calculate relative scroll.
1144                  if ( pinnedMenuBottom ) {
1145                      pinnedMenuBottom = false;
1146  
1147                      // Calculate new offset position.
1148                      menuTop = $adminMenuWrap.offset().top - height.adminbar + ( lastScrollPosition - windowPos );
1149  
1150                      if ( menuTop + height.menu > windowPos + height.window ) {
1151                          menuTop = windowPos;
1152                      }
1153  
1154                      $adminMenuWrap.css({
1155                          position: 'absolute',
1156                          top: menuTop,
1157                          bottom: ''
1158                      });
1159                  } else if ( ! pinnedMenuTop && $adminMenuWrap.offset().top >= windowPos + height.adminbar ) {
1160  
1161                      // Pin it to the top.
1162                      pinnedMenuTop = true;
1163  
1164                      $adminMenuWrap.css({
1165                          position: 'fixed',
1166                          top: '',
1167                          bottom: ''
1168                      });
1169                  }
1170              } else if ( resizing ) {
1171                  // Window is being resized.
1172  
1173                  pinnedMenuTop = pinnedMenuBottom = false;
1174  
1175                  // Calculate the new offset.
1176                  menuTop = windowPos + height.window - height.menu - height.adminbar - 1;
1177  
1178                  if ( menuTop > 0 ) {
1179                      $adminMenuWrap.css({
1180                          position: 'absolute',
1181                          top: menuTop,
1182                          bottom: ''
1183                      });
1184                  } else {
1185                      unpinMenu();
1186                  }
1187              }
1188          }
1189  
1190          lastScrollPosition = windowPos;
1191      }
1192  
1193      /**
1194       * Determines the height of certain elements.
1195       *
1196       * @since 4.1.0
1197       *
1198       * @returns {void}
1199       */
1200  	function resetHeights() {
1201          height = {
1202              window: $window.height(),
1203              wpwrap: $wpwrap.height(),
1204              adminbar: $adminbar.height(),
1205              menu: $adminMenuWrap.height()
1206          };
1207      }
1208  
1209      /**
1210       * Unpins the menu.
1211       *
1212       * @since 4.1.0
1213       *
1214       * @returns {void}
1215       */
1216  	function unpinMenu() {
1217          if ( isIOS || ! menuIsPinned ) {
1218              return;
1219          }
1220  
1221          pinnedMenuTop = pinnedMenuBottom = menuIsPinned = false;
1222          $adminMenuWrap.css({
1223              position: '',
1224              top: '',
1225              bottom: ''
1226          });
1227      }
1228  
1229      /**
1230       * Pins and unpins the menu when applicable.
1231       *
1232       * @since 4.1.0
1233       *
1234       * @returns {void}
1235       */
1236  	function setPinMenu() {
1237          resetHeights();
1238  
1239          if ( $adminmenu.data('wp-responsive') ) {
1240              $body.removeClass( 'sticky-menu' );
1241              unpinMenu();
1242          } else if ( height.menu + height.adminbar > height.window ) {
1243              pinMenu();
1244              $body.removeClass( 'sticky-menu' );
1245          } else {
1246              $body.addClass( 'sticky-menu' );
1247              unpinMenu();
1248          }
1249      }
1250  
1251      if ( ! isIOS ) {
1252          $window.on( 'scroll.pin-menu', pinMenu );
1253          $document.on( 'tinymce-editor-init.pin-menu', function( event, editor ) {
1254              editor.on( 'wp-autoresize', resetHeights );
1255          });
1256      }
1257  
1258      /**
1259       * Changes the sortables and responsiveness of metaboxes.
1260       *
1261       * @since 3.8.0
1262       *
1263       *@returns {void}
1264       */
1265      window.wpResponsive = {
1266  
1267          /**
1268           * Initializes the wpResponsive object.
1269           *
1270           * @since 3.8.0
1271           *
1272           * @returns {void}
1273           */
1274          init: function() {
1275              var self = this;
1276  
1277              this.maybeDisableSortables = this.maybeDisableSortables.bind( this );
1278  
1279              // Modify functionality based on custom activate/deactivate event
1280              $document.on( 'wp-responsive-activate.wp-responsive', function() {
1281                  self.activate();
1282              }).on( 'wp-responsive-deactivate.wp-responsive', function() {
1283                  self.deactivate();
1284              });
1285  
1286              $( '#wp-admin-bar-menu-toggle a' ).attr( 'aria-expanded', 'false' );
1287  
1288              // Toggle sidebar when toggle is clicked.
1289              $( '#wp-admin-bar-menu-toggle' ).on( 'click.wp-responsive', function( event ) {
1290                  event.preventDefault();
1291  
1292                  // close any open toolbar submenus.
1293                  $adminbar.find( '.hover' ).removeClass( 'hover' );
1294  
1295                  $wpwrap.toggleClass( 'wp-responsive-open' );
1296                  if ( $wpwrap.hasClass( 'wp-responsive-open' ) ) {
1297                      $(this).find('a').attr( 'aria-expanded', 'true' );
1298                      $( '#adminmenu a:first' ).focus();
1299                  } else {
1300                      $(this).find('a').attr( 'aria-expanded', 'false' );
1301                  }
1302              } );
1303  
1304              // Add menu events.
1305              $adminmenu.on( 'click.wp-responsive', 'li.wp-has-submenu > a', function( event ) {
1306                  if ( ! $adminmenu.data('wp-responsive') ) {
1307                      return;
1308                  }
1309  
1310                  $( this ).parent( 'li' ).toggleClass( 'selected' );
1311                  event.preventDefault();
1312              });
1313  
1314              self.trigger();
1315              $document.on( 'wp-window-resized.wp-responsive', $.proxy( this.trigger, this ) );
1316  
1317              // This needs to run later as UI Sortable may be initialized later on $(document).ready().
1318              $window.on( 'load.wp-responsive', this.maybeDisableSortables );
1319              $document.on( 'postbox-toggled', this.maybeDisableSortables );
1320  
1321              // When the screen columns are changed, potentially disable sortables.
1322              $( '#screen-options-wrap input' ).on( 'click', this.maybeDisableSortables );
1323          },
1324  
1325          /**
1326           * Disable sortables if there is only one metabox, or the screen is in one column mode. Otherwise, enable sortables.
1327           *
1328           * @since 5.3.0
1329           *
1330           * @returns {void}
1331           */
1332          maybeDisableSortables: function() {
1333              var width = navigator.userAgent.indexOf('AppleWebKit/') > -1 ? $window.width() : window.innerWidth;
1334  
1335              if (
1336                  ( width <= 782 ) ||
1337                  ( 1 >= $sortables.find( '.ui-sortable-handle:visible' ).length && jQuery( '.columns-prefs-1 input' ).prop( 'checked' ) )
1338              ) {
1339                  this.disableSortables();
1340              } else {
1341                  this.enableSortables();
1342              }
1343          },
1344  
1345          /**
1346           * Changes properties of body and admin menu.
1347           *
1348           * Pins and unpins the menu and adds the auto-fold class to the body.
1349           * Makes the admin menu responsive and disables the metabox sortables.
1350           *
1351           * @since 3.8.0
1352           *
1353           * @returns {void}
1354           */
1355          activate: function() {
1356              setPinMenu();
1357  
1358              if ( ! $body.hasClass( 'auto-fold' ) ) {
1359                  $body.addClass( 'auto-fold' );
1360              }
1361  
1362              $adminmenu.data( 'wp-responsive', 1 );
1363              this.disableSortables();
1364          },
1365  
1366          /**
1367           * Changes properties of admin menu and enables metabox sortables.
1368           *
1369           * Pin and unpin the menu.
1370           * Removes the responsiveness of the admin menu and enables the metabox sortables.
1371           *
1372           * @since 3.8.0
1373           *
1374           * @returns {void}
1375           */
1376          deactivate: function() {
1377              setPinMenu();
1378              $adminmenu.removeData('wp-responsive');
1379  
1380              this.maybeDisableSortables();
1381          },
1382  
1383          /**
1384           * Sets the responsiveness and enables the overlay based on the viewport width.
1385           *
1386           * @since 3.8.0
1387           *
1388           * @returns {void}
1389           */
1390          trigger: function() {
1391              var viewportWidth = getViewportWidth();
1392  
1393              // Exclude IE < 9, it doesn't support @media CSS rules.
1394              if ( ! viewportWidth ) {
1395                  return;
1396              }
1397  
1398              if ( viewportWidth <= 782 ) {
1399                  if ( ! wpResponsiveActive ) {
1400                      $document.trigger( 'wp-responsive-activate' );
1401                      wpResponsiveActive = true;
1402                  }
1403              } else {
1404                  if ( wpResponsiveActive ) {
1405                      $document.trigger( 'wp-responsive-deactivate' );
1406                      wpResponsiveActive = false;
1407                  }
1408              }
1409  
1410              if ( viewportWidth <= 480 ) {
1411                  this.enableOverlay();
1412              } else {
1413                  this.disableOverlay();
1414              }
1415  
1416              this.maybeDisableSortables();
1417          },
1418  
1419          /**
1420           * Inserts a responsive overlay and toggles the window.
1421           *
1422           * @since 3.8.0
1423           *
1424           * @returns {void}
1425           */
1426          enableOverlay: function() {
1427              if ( $overlay.length === 0 ) {
1428                  $overlay = $( '<div id="wp-responsive-overlay"></div>' )
1429                      .insertAfter( '#wpcontent' )
1430                      .hide()
1431                      .on( 'click.wp-responsive', function() {
1432                          $toolbar.find( '.menupop.hover' ).removeClass( 'hover' );
1433                          $( this ).hide();
1434                      });
1435              }
1436  
1437              $toolbarPopups.on( 'click.wp-responsive', function() {
1438                  $overlay.show();
1439              });
1440          },
1441  
1442          /**
1443           * Disables the responsive overlay and removes the overlay.
1444           *
1445           * @since 3.8.0
1446           *
1447           * @returns {void}
1448           */
1449          disableOverlay: function() {
1450              $toolbarPopups.off( 'click.wp-responsive' );
1451              $overlay.hide();
1452          },
1453  
1454          /**
1455           * Disables sortables.
1456           *
1457           * @since 3.8.0
1458           *
1459           * @returns {void}
1460           */
1461          disableSortables: function() {
1462              if ( $sortables.length ) {
1463                  try {
1464                      $sortables.sortable( 'disable' );
1465                      $sortables.find( '.ui-sortable-handle' ).addClass( 'is-non-sortable' );
1466                  } catch ( e ) {}
1467              }
1468          },
1469  
1470          /**
1471           * Enables sortables.
1472           *
1473           * @since 3.8.0
1474           *
1475           * @returns {void}
1476           */
1477          enableSortables: function() {
1478              if ( $sortables.length ) {
1479                  try {
1480                      $sortables.sortable( 'enable' );
1481                      $sortables.find( '.ui-sortable-handle' ).removeClass( 'is-non-sortable' );
1482                  } catch ( e ) {}
1483              }
1484          }
1485      };
1486  
1487      /**
1488       * Add an ARIA role `button` to elements that behave like UI controls when JavaScript is on.
1489       *
1490       * @since 4.5.0
1491       *
1492       * @returns {void}
1493       */
1494  	function aria_button_if_js() {
1495          $( '.aria-button-if-js' ).attr( 'role', 'button' );
1496      }
1497  
1498      $( document ).ajaxComplete( function() {
1499          aria_button_if_js();
1500      });
1501  
1502      /**
1503       * Get the viewport width.
1504       *
1505       * @since 4.7.0
1506       *
1507       * @returns {number|boolean} The current viewport width or false if the
1508       *                           browser doesn't support innerWidth (IE < 9).
1509       */
1510  	function getViewportWidth() {
1511          var viewportWidth = false;
1512  
1513          if ( window.innerWidth ) {
1514              // On phones, window.innerWidth is affected by zooming.
1515              viewportWidth = Math.max( window.innerWidth, document.documentElement.clientWidth );
1516          }
1517  
1518          return viewportWidth;
1519      }
1520  
1521      /**
1522       * Sets the admin menu collapsed/expanded state.
1523       *
1524       * Sets the global variable `menuState` and triggers a custom event passing
1525       * the current menu state.
1526       *
1527       * @since 4.7.0
1528       *
1529       * @returns {void}
1530       */
1531  	function setMenuState() {
1532          var viewportWidth = getViewportWidth() || 961;
1533  
1534          if ( viewportWidth <= 782  ) {
1535              menuState = 'responsive';
1536          } else if ( $body.hasClass( 'folded' ) || ( $body.hasClass( 'auto-fold' ) && viewportWidth <= 960 && viewportWidth > 782 ) ) {
1537              menuState = 'folded';
1538          } else {
1539              menuState = 'open';
1540          }
1541  
1542          $document.trigger( 'wp-menu-state-set', { state: menuState } );
1543      }
1544  
1545      // Set the menu state when the window gets resized.
1546      $document.on( 'wp-window-resized.set-menu-state', setMenuState );
1547  
1548      /**
1549       * Sets ARIA attributes on the collapse/expand menu button.
1550       *
1551       * When the admin menu is open or folded, updates the `aria-expanded` and
1552       * `aria-label` attributes of the button to give feedback to assistive
1553       * technologies. In the responsive view, the button is always hidden.
1554       *
1555       * @since 4.7.0
1556       *
1557       * @returns {void}
1558       */
1559      $document.on( 'wp-menu-state-set wp-collapse-menu', function( event, eventData ) {
1560          var $collapseButton = $( '#collapse-button' ),
1561              ariaExpanded = 'true',
1562              ariaLabelText = commonL10n.collapseMenu;
1563  
1564          if ( 'folded' === eventData.state ) {
1565              ariaExpanded = 'false';
1566              ariaLabelText = commonL10n.expandMenu;
1567          }
1568  
1569          $collapseButton.attr({
1570              'aria-expanded': ariaExpanded,
1571              'aria-label': ariaLabelText
1572          });
1573      });
1574  
1575      window.wpResponsive.init();
1576      setPinMenu();
1577      setMenuState();
1578      currentMenuItemHasPopup();
1579      makeNoticesDismissible();
1580      aria_button_if_js();
1581  
1582      $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 );
1583  
1584      // Set initial focus on a specific element.
1585      $( '.wp-initial-focus' ).focus();
1586  
1587      // Toggle update details on update-core.php.
1588      $body.on( 'click', '.js-update-details-toggle', function() {
1589          var $updateNotice = $( this ).closest( '.js-update-details' ),
1590              $progressDiv = $( '#' + $updateNotice.data( 'update-details' ) );
1591  
1592          /*
1593           * When clicking on "Show details" move the progress div below the update
1594           * notice. Make sure it gets moved just the first time.
1595           */
1596          if ( ! $progressDiv.hasClass( 'update-details-moved' ) ) {
1597              $progressDiv.insertAfter( $updateNotice ).addClass( 'update-details-moved' );
1598          }
1599  
1600          // Toggle the progress div visibility.
1601          $progressDiv.toggle();
1602          // Toggle the Show Details button expanded state.
1603          $( this ).attr( 'aria-expanded', $progressDiv.is( ':visible' ) );
1604      });
1605  });
1606  
1607  // Fire a custom jQuery event at the end of window resize.
1608  ( function() {
1609      var timeout;
1610  
1611      /**
1612       * Triggers the WP window-resize event.
1613       *
1614       * @since 3.8.0
1615       *
1616       * @returns {void}
1617       */
1618  	function triggerEvent() {
1619          $document.trigger( 'wp-window-resized' );
1620      }
1621  
1622      /**
1623       * Fires the trigger event again after 200 ms.
1624       *
1625       * @since 3.8.0
1626       *
1627       * @returns {void}
1628       */
1629  	function fireOnce() {
1630          window.clearTimeout( timeout );
1631          timeout = window.setTimeout( triggerEvent, 200 );
1632      }
1633  
1634      $window.on( 'resize.wp-fire-once', fireOnce );
1635  }());
1636  
1637  // Make Windows 8 devices play along nicely.
1638  (function(){
1639      if ( '-ms-user-select' in document.documentElement.style && navigator.userAgent.match(/IEMobile\/10\.0/) ) {
1640          var msViewportStyle = document.createElement( 'style' );
1641          msViewportStyle.appendChild(
1642              document.createTextNode( '@-ms-viewport{width:auto!important}' )
1643          );
1644          document.getElementsByTagName( 'head' )[0].appendChild( msViewportStyle );
1645      }
1646  })();
1647  
1648  }( jQuery, window ));


Generated: Sat Nov 23 20:47:33 2019 Cross-referenced by PHPXref 0.7