From 0074ad2d90cd724e73b8a14f7394c9b9f7109849 Mon Sep 17 00:00:00 2001 From: Helen Hou-Sandi Date: Wed, 13 Nov 2013 04:29:27 +0000 Subject: [PATCH] Merge the sticky menu component from MP6. The admin menu is now fixed if the viewport is large enough. props tollmanz, tillkruess, dd32. see #25858. git-svn-id: https://develop.svn.wordpress.org/trunk@26125 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/css/wp-admin.css | 13 ++++++ src/wp-admin/js/common.js | 85 ++++++++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/src/wp-admin/css/wp-admin.css b/src/wp-admin/css/wp-admin.css index c197873653..165e782b01 100644 --- a/src/wp-admin/css/wp-admin.css +++ b/src/wp-admin/css/wp-admin.css @@ -1919,6 +1919,19 @@ div.wp-menu-image:before { height: 34px; } +/* Sticky admin menu */ + +.sticky-menu #wpwrap { + z-index: 1; /* prevent flyouts from going behind content in Webkit */ +} + +.sticky-menu #adminmenuwrap { + position: fixed; + top: 32px; + left: 0; + z-index: 2; /* needs to be above .sticky-menu #wpwrap */ +} + /* A new arrow */ .wp-menu-arrow { diff --git a/src/wp-admin/js/common.js b/src/wp-admin/js/common.js index fd1c8ddcdf..dc6093eb95 100644 --- a/src/wp-admin/js/common.js +++ b/src/wp-admin/js/common.js @@ -1,5 +1,5 @@ /* global setUserSetting, ajaxurl, commonL10n, alert, confirm, toggleWithKeyboard, pagenow */ -var showNotice, adminMenu, columns, validateForm, screenMeta; +var showNotice, adminMenu, columns, validateForm, screenMeta, stickyMenu; (function($){ // Removed in 3.3. // (perhaps) needed for back-compat @@ -447,6 +447,89 @@ $(document).ready( function() { })(); }); +stickyMenu = { + active: false, + + init: function () { + this.$window = $( window ); + this.$body = $( document.body ); + this.$adminMenuWrap = $( '#adminmenuwrap' ); + this.$collapseMenu = $( '#collapse-menu' ); + this.bodyMinWidth = parseInt( this.$body.css( 'min-width' ), 10 ); + this.enable(); + }, + + enable: function () { + if ( ! this.active ) { + this.$window.on( 'resize.stickyMenu scroll.stickyMenu', this.debounce( + $.proxy( this.update, this ), 200 + ) ); + this.$collapseMenu.on( 'click.stickyMenu', $.proxy( this.update, this ) ); + this.update(); + this.active = true; + } + }, + + disable: function () { + if ( this.active ) { + this.$window.off( 'resize.stickyMenu scroll.stickyMenu' ); + this.$collapseMenu.off( 'click.stickyMenu' ); + this.$body.removeClass( 'sticky-menu' ); + this.active = false; + } + }, + + update: function () { + // Make the admin menu sticky if both of the following: + // 1. The viewport is taller than the admin menu + // 2. The viewport is wider than the min-width of the + if ( this.$window.height() > this.$adminMenuWrap.height() + 32 && this.$window.width() > this.bodyMinWidth) { + if ( ! this.$body.hasClass( 'sticky-menu' ) ) { + this.$body.addClass( 'sticky-menu' ); + } + } else { + if ( this.$body.hasClass( 'sticky-menu' ) ) { + this.$body.removeClass( 'sticky-menu' ); + } + } + }, + + // Borrowed from Underscore.js + debounce: function( func, wait, immediate ) { + var timeout, args, context, timestamp, result; + return function() { + var later, callNow; + context = this; + args = arguments; + timestamp = new Date().getTime(); + later = function() { + var last = new Date().getTime() - timestamp; + if ( last < wait ) { + timeout = setTimeout( later, wait - last ); + } else { + timeout = null; + if ( ! immediate ) { + result = func.apply( context, args ); + context = args = null; + } + } + }; + callNow = immediate && !timeout; + if ( ! timeout ) { + timeout = setTimeout( later, wait ); + } + if ( callNow ) { + result = func.apply( context, args ); + context = args = null; + } + + return result; + }; + } +}; + +stickyMenu.init(); + // internal use $(document).bind( 'wp_CloseOnEscape', function( e, data ) { if ( typeof(data.cb) != 'function' )