if ( windowPos > lastScrollPosition ) {
// When a down scroll has been detected.
// If it was pinned to the top, unpin and calculate relative scroll.
// Calculate new offset position.
menuTop = $adminMenuWrap.offset().top - height.adminbar - ( windowPos - lastScrollPosition );
if ( menuTop + height.menu + height.adminbar < windowPos + height.window ) {
menuTop = windowPos + height.window - height.menu - height.adminbar;
} else if ( ! pinnedMenuBottom && $adminMenuWrap.offset().top + height.menu < windowPos + height.window ) {
} else if ( windowPos < lastScrollPosition ) {
// When a scroll up is detected.
// If it was pinned to the bottom, unpin and calculate relative scroll.
if ( pinnedMenuBottom ) {
pinnedMenuBottom = false;
// Calculate new offset position.
menuTop = $adminMenuWrap.offset().top - height.adminbar + ( lastScrollPosition - windowPos );
if ( menuTop + height.menu > windowPos + height.window ) {
} else if ( ! pinnedMenuTop && $adminMenuWrap.offset().top >= windowPos + height.adminbar ) {
// Window is being resized.
pinnedMenuTop = pinnedMenuBottom = false;
// Calculate the new offset.
menuTop = windowPos + height.window - height.menu - height.adminbar - 1;
lastScrollPosition = windowPos;
* Determines the height of certain elements.
function resetHeights() {
window: $window.height(),
wpwrap: $wpwrap.height(),
adminbar: $adminbar.height(),
menu: $adminMenuWrap.height()
if ( isIOS || ! menuIsPinned ) {
pinnedMenuTop = pinnedMenuBottom = menuIsPinned = false;
* Pins and unpins the menu when applicable.
if ( $adminmenu.data('wp-responsive') ) {
$body.removeClass( 'sticky-menu' );
} else if ( height.menu + height.adminbar > height.window ) {
$body.removeClass( 'sticky-menu' );
$body.addClass( 'sticky-menu' );
$window.on( 'scroll.pin-menu', pinMenu );
$document.on( 'tinymce-editor-init.pin-menu', function( event, editor ) {
editor.on( 'wp-autoresize', resetHeights );
* Changes the sortables and responsiveness of metaboxes.
* Initializes the wpResponsive object.
this.maybeDisableSortables = this.maybeDisableSortables.bind( this );
// Modify functionality based on custom activate/deactivate event.
$document.on( 'wp-responsive-activate.wp-responsive', function() {
}).on( 'wp-responsive-deactivate.wp-responsive', function() {
$( '#wp-admin-bar-menu-toggle a' ).attr( 'aria-expanded', 'false' );
// Toggle sidebar when toggle is clicked.
$( '#wp-admin-bar-menu-toggle' ).on( 'click.wp-responsive', function( event ) {
// Close any open toolbar submenus.
$adminbar.find( '.hover' ).removeClass( 'hover' );
$wpwrap.toggleClass( 'wp-responsive-open' );
if ( $wpwrap.hasClass( 'wp-responsive-open' ) ) {
$(this).find('a').attr( 'aria-expanded', 'true' );
$( '#adminmenu a:first' ).trigger( 'focus' );
$(this).find('a').attr( 'aria-expanded', 'false' );
$adminmenu.on( 'click.wp-responsive', 'li.wp-has-submenu > a', function( event ) {
if ( ! $adminmenu.data('wp-responsive') ) {
$( this ).parent( 'li' ).toggleClass( 'selected' );
$document.on( 'wp-window-resized.wp-responsive', $.proxy( this.trigger, this ) );
// This needs to run later as UI Sortable may be initialized later on $(document).ready().
$window.on( 'load.wp-responsive', this.maybeDisableSortables );
$document.on( 'postbox-toggled', this.maybeDisableSortables );
// When the screen columns are changed, potentially disable sortables.
$( '#screen-options-wrap input' ).on( 'click', this.maybeDisableSortables );
* Disable sortables if there is only one metabox, or the screen is in one column mode. Otherwise, enable sortables.
maybeDisableSortables: function() {
var width = navigator.userAgent.indexOf('AppleWebKit/') > -1 ? $window.width() : window.innerWidth;
( 1 >= $sortables.find( '.ui-sortable-handle:visible' ).length && jQuery( '.columns-prefs-1 input' ).prop( 'checked' ) )
* Changes properties of body and admin menu.
* Pins and unpins the menu and adds the auto-fold class to the body.
* Makes the admin menu responsive and disables the metabox sortables.
if ( ! $body.hasClass( 'auto-fold' ) ) {
$body.addClass( 'auto-fold' );
$adminmenu.data( 'wp-responsive', 1 );
* Changes properties of admin menu and enables metabox sortables.
* Pin and unpin the menu.
* Removes the responsiveness of the admin menu and enables the metabox sortables.
$adminmenu.removeData('wp-responsive');
this.maybeDisableSortables();
* Sets the responsiveness and enables the overlay based on the viewport width.
var viewportWidth = getViewportWidth();
// Exclude IE < 9, it doesn't support @media CSS rules.
if ( viewportWidth <= 782 ) {
if ( ! wpResponsiveActive ) {
$document.trigger( 'wp-responsive-activate' );
wpResponsiveActive = true;
if ( wpResponsiveActive ) {
$document.trigger( 'wp-responsive-deactivate' );
wpResponsiveActive = false;
if ( viewportWidth <= 480 ) {
this.maybeDisableSortables();
* Inserts a responsive overlay and toggles the window.
enableOverlay: function() {
if ( $overlay.length === 0 ) {
$overlay = $( '<div id="wp-responsive-overlay"></div>' )
.insertAfter( '#wpcontent' )
.on( 'click.wp-responsive', function() {
$toolbar.find( '.menupop.hover' ).removeClass( 'hover' );
$toolbarPopups.on( 'click.wp-responsive', function() {
* Disables the responsive overlay and removes the overlay.
disableOverlay: function() {
$toolbarPopups.off( 'click.wp-responsive' );
disableSortables: function() {
if ( $sortables.length ) {
$sortables.sortable( 'disable' );
$sortables.find( '.ui-sortable-handle' ).addClass( 'is-non-sortable' );
enableSortables: function() {
if ( $sortables.length ) {
$sortables.sortable( 'enable' );
$sortables.find( '.ui-sortable-handle' ).removeClass( 'is-non-sortable' );
* Add an ARIA role `button` to elements that behave like UI controls when JavaScript is on.
function aria_button_if_js() {
$( '.aria-button-if-js' ).attr( 'role', 'button' );
$( document ).ajaxComplete( function() {
* Get the viewport width.
* @return {number|boolean} The current viewport width or false if the
* browser doesn't support innerWidth (IE < 9).
function getViewportWidth() {
var viewportWidth = false;
if ( window.innerWidth ) {
// On phones, window.innerWidth is affected by zooming.
viewportWidth = Math.max( window.innerWidth, document.documentElement.clientWidth );
* Sets the admin menu collapsed/expanded state.
* Sets the global variable `menuState` and triggers a custom event passing
* the current menu state.
function setMenuState() {
var viewportWidth = getViewportWidth() || 961;
if ( viewportWidth <= 782 ) {
menuState = 'responsive';
} else if ( $body.hasClass( 'folded' ) || ( $body.hasClass( 'auto-fold' ) && viewportWidth <= 960 && viewportWidth > 782 ) ) {
$document.trigger( 'wp-menu-state-set', { state: menuState } );
// Set the menu state when the window gets resized.
$document.on( 'wp-window-resized.set-menu-state', setMenuState );
* Sets ARIA attributes on the collapse/expand menu button.
* When the admin menu is open or folded, updates the `aria-expanded` and
* `aria-label` attributes of the button to give feedback to assistive
* technologies. In the responsive view, the button is always hidden.
$document.on( 'wp-menu-state-set wp-collapse-menu', function( event, eventData ) {
var $collapseButton = $( '#collapse-button' ),
ariaExpanded, ariaLabelText;
if ( 'folded' === eventData.state ) {
ariaLabelText = __( 'Expand Main menu' );
ariaLabelText = __( 'Collapse Main menu' );
'aria-expanded': ariaExpanded,
'aria-label': ariaLabelText
window.wpResponsive.init();
currentMenuItemHasPopup();
makeNoticesDismissible();
$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 );
// Set initial focus on a specific element.
$( '.wp-initial-focus' ).trigger( 'focus' );
// Toggle update details on update-core.php.
$body.on( 'click', '.js-update-details-toggle', function() {
var $updateNotice = $( this ).closest( '.js-update-details' ),
$progressDiv = $( '#' + $updateNotice.data( 'update-details' ) );
* When clicking on "Show details" move the progress div below the update
* notice. Make sure it gets moved just the first time.
if ( ! $progressDiv.hasClass( 'update-details-moved' ) ) {
$progressDiv.insertAfter( $updateNotice ).addClass( 'update-details-moved' );
// Toggle the progress div visibility.
// Toggle the Show Details button expanded state.
$( this ).attr( 'aria-expanded', $progressDiv.is( ':visible' ) );