WordPress.org

Make WordPress Core

Changeset 29898


Ignore:
Timestamp:
10/15/2014 06:04:15 AM (5 years ago)
Author:
azaozz
Message:

Admin menu:

  • Fix pinning after resizing the window.
  • Merge the two DOM ready callbacks in common.js
  • Fix the submenus position adjustment on focus.

See #29806

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/js/common.js

    r29835 r29898  
    174174    var checks, first, last, checked, sliced, mobileEvent, transitionTimeout, focusedRowActions,
    175175        lastClicked = false,
    176         menu = $('#adminmenu'),
    177176        pageInput = $('input.current-page'),
    178177        currentPage = pageInput.val(),
    179178        isIOS = /iPhone|iPad|iPod/.test( navigator.userAgent ),
    180         isAndroid = navigator.userAgent.indexOf( 'Android' ) !== -1;
     179        isAndroid = navigator.userAgent.indexOf( 'Android' ) !== -1,
     180        $document = $( document ),
     181        $window = $( window ),
     182        $body = $( document.body ),
     183        $adminMenuWrap = $( '#adminmenuwrap' ),
     184        $wpwrap = $( '#wpwrap' ),
     185        $adminmenu = $( '#adminmenu' ),
     186        $overlay = $( '#wp-responsive-overlay' ),
     187        $toolbar = $( '#wp-toolbar' ),
     188        $toolbarPopups = $toolbar.find( 'a[aria-haspopup="true"]' ),
     189        $sortables = $('.meta-box-sortables'),
     190        wpResponsiveActive = false,
     191        $adminbar = $( '#wpadminbar' ),
     192        lastScrollPosition = 0,
     193        pinnedMenuTop = false,
     194        pinnedMenuBottom = false,
     195        menuTop = 0,
     196        height = {
     197            window: $window.height(),
     198            adminbar: $adminbar.height(),
     199            menu: $adminMenuWrap.height()
     200        };
     201
    181202
    182203    // when the menu is folded, make the fly-out submenu header clickable
    183     menu.on('click.wp-submenu-head', '.wp-submenu-head', function(e){
     204    $adminmenu.on('click.wp-submenu-head', '.wp-submenu-head', function(e){
    184205        $(e.target).parent().siblings('a').get(0).click();
    185206    });
     
    225246    });
    226247
     248    function adjustSubmenu( $menuItem ) {
     249        var bottomOffset, pageHeight, adjustment, theFold, menutop, wintop, maxtop,
     250            $submenu = $menuItem.find( '.wp-submenu' );
     251
     252        menutop = $menuItem.offset().top;
     253        wintop = $window.scrollTop();
     254        maxtop = menutop - wintop - 30; // max = make the top of the sub almost touch admin bar
     255
     256        bottomOffset = menutop + $submenu.height() + 1; // Bottom offset of the menu
     257        pageHeight = $wpwrap.height(); // Height of the entire page
     258        adjustment = 60 + bottomOffset - pageHeight;
     259        theFold = $window.height() + wintop - 50; // The fold
     260
     261        if ( theFold < ( bottomOffset - adjustment ) ) {
     262            adjustment = bottomOffset - theFold;
     263        }
     264
     265        if ( adjustment > maxtop ) {
     266            adjustment = maxtop;
     267        }
     268
     269        if ( adjustment > 1 ) {
     270            $submenu.css( 'margin-top', '-' + adjustment + 'px' );
     271        } else {
     272            $submenu.css( 'margin-top', '' );
     273        }
     274    }
     275
    227276    if ( 'ontouchstart' in window || /IEMobile\/[1-9]/.test(navigator.userAgent) ) { // touch screen device
    228277        // iOS Safari works with touchstart, the rest work with click
     
    231280        // close any open submenus when touch/click is not on the menu
    232281        $(document.body).on( mobileEvent+'.wp-mobile-hover', function(e) {
    233             if ( menu.data('wp-responsive') ) {
     282            if ( $adminmenu.data('wp-responsive') ) {
    234283                return;
    235284            }
    236285
    237             if ( ! $(e.target).closest('#adminmenu').length ) {
    238                 menu.find('li.wp-has-submenu.opensub').removeClass('opensub');
    239             }
    240         });
    241 
    242         menu.find('a.wp-has-submenu').on( mobileEvent+'.wp-mobile-hover', function(e) {
    243             var b, h, o, f, menutop, wintop, maxtop,
    244                 el = $(this),
    245                 parent = el.parent(),
    246                 m = parent.find('.wp-submenu');
    247 
    248             if ( menu.data('wp-responsive') ) {
     286            if ( ! $( e.target ).closest( '#adminmenu' ).length ) {
     287                $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
     288            }
     289        });
     290
     291        $adminmenu.find( 'a.wp-has-submenu' ).on( mobileEvent + '.wp-mobile-hover', function( event ) {
     292            var $menuItem = $(this).parent();
     293
     294            if ( $adminmenu.data( 'wp-responsive' ) ) {
    249295                return;
    250296            }
     
    253299            //  - the submenu is not open
    254300            //  - the submenu is not shown inline or the menu is not folded
    255             if ( !parent.hasClass('opensub') && ( !parent.hasClass('wp-menu-open') || parent.width() < 40 ) ) {
    256                 e.preventDefault();
    257 
    258                 menutop = parent.offset().top;
    259                 wintop = $(window).scrollTop();
    260                 maxtop = menutop - wintop - 30; // max = make the top of the sub almost touch admin bar
    261 
    262                 b = menutop + m.height() + 1; // Bottom offset of the menu
    263                 h = $('#wpwrap').height(); // Height of the entire page
    264                 o = 60 + b - h;
    265                 f = $(window).height() + wintop - 50; // The fold
    266 
    267                 if ( f < (b - o) ) {
    268                     o = b - f;
    269                 }
    270 
    271                 if ( o > maxtop ) {
    272                     o = maxtop;
    273                 }
    274 
    275                 if ( o > 1 ) {
    276                     m.css('margin-top', '-'+o+'px');
    277                 } else {
    278                     m.css('margin-top', '');
    279                 }
    280 
    281                 menu.find('li.opensub').removeClass('opensub');
    282                 parent.addClass('opensub');
     301            if ( ! $menuItem.hasClass( 'opensub' ) && ( ! $menuItem.hasClass( 'wp-menu-open' ) || $menuItem.width() < 40 ) ) {
     302                event.preventDefault();
     303                adjustSubmenu( $menuItem );
     304                $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
     305                $menuItem.addClass('opensub');
    283306            }
    284307        });
     
    286309
    287310    if ( ! isIOS && ! isAndroid ) {
    288         menu.find('li.wp-has-submenu').hoverIntent({
     311        $adminmenu.find( 'li.wp-has-submenu' ).hoverIntent({
    289312            over: function() {
    290                 var b, h, o, f, m = $(this).find('.wp-submenu'), menutop, wintop, maxtop, top = parseInt( m.css('top'), 10 );
    291 
    292                 if ( isNaN(top) || top > -5 ) { // meaning the submenu is visible
     313                var $menuItem = $( this ),
     314                    $submenu = $menuItem.find( '.wp-submenu' ),
     315                    top = parseInt( $submenu.css( 'top' ), 10 );
     316
     317                if ( isNaN( top ) || top > -5 ) { // the submenu is visible
    293318                    return;
    294319                }
    295320
    296                 if ( menu.data('wp-responsive') ) {
     321                if ( $adminmenu.data( 'wp-responsive' ) ) {
    297322                    // The menu is in responsive mode, bail
    298323                    return;
    299324                }
    300325
    301                 menutop = $(this).offset().top;
    302                 wintop = $(window).scrollTop();
    303                 maxtop = menutop - wintop - 30; // max = make the top of the sub almost touch admin bar
    304 
    305                 b = menutop + m.height() + 1; // Bottom offset of the menu
    306                 h = $('#wpwrap').height(); // Height of the entire page
    307                 o = 60 + b - h;
    308                 f = $(window).height() + wintop - 15; // The fold
    309 
    310                 if ( f < (b - o) ) {
    311                     o = b - f;
    312                 }
    313 
    314                 if ( o > maxtop ) {
    315                     o = maxtop;
    316                 }
    317 
    318                 if ( o > 1 ) {
    319                     m.css('margin-top', '-'+o+'px');
    320                 } else {
    321                     m.css('margin-top', '');
    322                 }
    323 
    324                 menu.find('li.menu-top').removeClass('opensub');
    325                 $(this).addClass('opensub');
     326                adjustSubmenu( $menuItem );
     327                $adminmenu.find( 'li.opensub' ).removeClass( 'opensub' );
     328                $menuItem.addClass( 'opensub' );
    326329            },
    327330            out: function(){
    328                 if ( menu.data('wp-responsive') ) {
     331                if ( $adminmenu.data( 'wp-responsive' ) ) {
    329332                    // The menu is in responsive mode, bail
    330333                    return;
    331334                }
    332335
    333                 $(this).removeClass('opensub').find('.wp-submenu').css('margin-top', '');
     336                $( this ).removeClass( 'opensub' ).find( '.wp-submenu' ).css( 'margin-top', '' );
    334337            },
    335338            timeout: 200,
     
    338341        });
    339342
    340         menu.on('focus.adminmenu', '.wp-submenu a', function(e){
    341             if ( menu.data('wp-responsive') ) {
     343        $adminmenu.on( 'focus.adminmenu', '.wp-submenu a', function( event ) {
     344            if ( $adminmenu.data( 'wp-responsive' ) ) {
    342345                // The menu is in responsive mode, bail
    343346                return;
    344347            }
    345348
    346             $(e.target).closest('li.menu-top').addClass('opensub');
    347         }).on('blur.adminmenu', '.wp-submenu a', function(e){
    348             if ( menu.data('wp-responsive') ) {
    349                 // The menu is in responsive mode, bail
     349            $( event.target ).closest( 'li.menu-top' ).addClass( 'opensub' );
     350        }).on( 'blur.adminmenu', '.wp-submenu a', function( event ) {
     351            if ( $adminmenu.data( 'wp-responsive' ) ) {
    350352                return;
    351353            }
    352354
    353             $(e.target).closest('li.menu-top').removeClass('opensub');
     355            $( event.target ).closest( 'li.menu-top' ).removeClass( 'opensub' );
     356        }).find( 'li.wp-has-submenu' ).on( 'focusin.adminmenu', function() {
     357            adjustSubmenu( $( this ) );
    354358        });
    355359    }
     
    528532        input.on('change', toggleUploadButton);
    529533    })();
    530 });
    531 
    532 // Fire a custom jQuery event at the end of window resize
    533 ( function() {
    534     var timeout;
    535 
    536     function triggerEvent() {
    537         $(document).trigger( 'wp-window-resized' );
    538     }
    539 
    540     function fireOnce() {
    541         window.clearTimeout( timeout );
    542         timeout = window.setTimeout( triggerEvent, 200 );
    543     }
    544 
    545     $(window).on( 'resize.wp-fire-once', fireOnce );
    546 }());
    547 
    548 $(document).ready( function() {
    549     var $document = $( document ),
    550         $window = $( window ),
    551         $body = $( document.body ),
    552         $adminMenuWrap = $( '#adminmenuwrap' ),
    553         $wpwrap = $( '#wpwrap' ),
    554         $adminmenu = $( '#adminmenu' ),
    555         $overlay = $( '#wp-responsive-overlay' ),
    556         $toolbar = $( '#wp-toolbar' ),
    557         $toolbarPopups = $toolbar.find( 'a[aria-haspopup="true"]' ),
    558         $sortables = $('.meta-box-sortables'),
    559         wpResponsiveActive = false,
    560         $adminbar = $( '#wpadminbar' ),
    561         lastScrollPosition = 0,
    562         fixedMenuTop = false,
    563         fixedMenuBottom = false,
    564         menuTop = 0,
    565         height = {
    566             window: $window.height(),
    567             adminbar: $adminbar.height(),
    568             menu: $adminMenuWrap.height()
    569         };
    570534
    571535    function pinMenu() {
    572536        var windowPos = $window.scrollTop();
    573537
    574         if ( $adminmenu.data('wp-responsive') ) {
     538        if ( isIOS || $adminmenu.data('wp-responsive') ) {
    575539            return;
    576540        }
     
    579543            if ( windowPos > lastScrollPosition ) {
    580544                // Scrolling down
    581                 if ( fixedMenuTop ) {
     545                if ( pinnedMenuTop ) {
    582546                    // let it scroll
    583                     fixedMenuTop = false;
     547                    pinnedMenuTop = false;
    584548                    menuTop = $adminMenuWrap.offset().top - height.adminbar;
    585549
     
    589553                        bottom: ''
    590554                    });
    591                 } else if ( ! fixedMenuBottom && $adminMenuWrap.offset().top + height.menu < windowPos + height.window ) {
     555                } else if ( ! pinnedMenuBottom && $adminMenuWrap.offset().top + height.menu < windowPos + height.window ) {
    592556                    // pin the bottom
    593                     fixedMenuBottom = true;
     557                    pinnedMenuBottom = true;
    594558
    595559                    $adminMenuWrap.css({
     
    601565            } else if ( windowPos < lastScrollPosition ) {
    602566                // Scrolling up
    603                 if ( fixedMenuBottom ) {
     567                if ( pinnedMenuBottom ) {
    604568                    // let it scroll
    605                     fixedMenuBottom = false;
     569                    pinnedMenuBottom = false;
    606570                    menuTop = $adminMenuWrap.offset().top - height.adminbar;
    607571
     
    611575                        bottom: ''
    612576                    });
    613                 } else if ( ! fixedMenuTop && $adminMenuWrap.offset().top >= windowPos + height.adminbar ) {
     577                } else if ( ! pinnedMenuTop && $adminMenuWrap.offset().top >= windowPos + height.adminbar ) {
    614578                    // pin the top
    615                     fixedMenuTop = true;
     579                    pinnedMenuTop = true;
    616580
    617581                    $adminMenuWrap.css({
     
    621585                    });
    622586                }
     587            } else {
     588                // Resizing
     589                pinnedMenuTop = pinnedMenuBottom = false;
     590                menuTop = $adminMenuWrap.offset().top - height.adminbar;
     591
     592                $adminMenuWrap.css({
     593                    position: 'absolute',
     594                    top: menuTop,
     595                    bottom: ''
     596                });
    623597            }
    624598        }
    625599
    626600        lastScrollPosition = windowPos;
     601    }
     602
     603    function unpinMenu() {
     604        if ( isIOS ) {
     605            return;
     606        }
     607
     608        pinnedMenuTop = pinnedMenuBottom = false;
     609        $adminMenuWrap.css({
     610            position: '',
     611            top: '',
     612            bottom: ''
     613        });
    627614    }
    628615
     
    630617        if ( $adminmenu.data('wp-responsive') ) {
    631618            $body.removeClass( 'sticky-menu' );
    632             $adminMenuWrap.css({
    633                 position: '',
    634                 top: '',
    635                 bottom: ''
    636             });
     619            unpinMenu();
    637620        } else if ( height.menu + height.adminbar > height.window ) {
     621            pinMenu();
    638622            $body.removeClass( 'sticky-menu' );
    639             pinMenu();
    640623        } else {
    641624            $body.addClass( 'sticky-menu' );
     625            unpinMenu();
    642626        }
    643627    }
    644628
    645629    setPinMenu();
    646     $window.on( 'scroll.pin-menu', pinMenu );
     630
     631    if ( ! isIOS ) {
     632        $window.on( 'scroll.pin-menu', pinMenu );
     633    }
    647634
    648635    $document.on( 'wp-window-resized.pin-menu', function() {
     
    791778});
    792779
     780// Fire a custom jQuery event at the end of window resize
     781( function() {
     782    var timeout;
     783
     784    function triggerEvent() {
     785        $(document).trigger( 'wp-window-resized' );
     786    }
     787
     788    function fireOnce() {
     789        window.clearTimeout( timeout );
     790        timeout = window.setTimeout( triggerEvent, 200 );
     791    }
     792
     793    $(window).on( 'resize.wp-fire-once', fireOnce );
     794}());
     795
    793796// Make Windows 8 devices play along nicely.
    794797(function(){
Note: See TracChangeset for help on using the changeset viewer.