wp/wp-includes/js/admin-bar.js
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
       
     1 /**
       
     2  * @output wp-includes/js/admin-bar.js
       
     3  */
       
     4 
     1 /* jshint loopfunc: true */
     5 /* jshint loopfunc: true */
     2 // use jQuery and hoverIntent if loaded
     6 // use jQuery and hoverIntent if loaded
     3 if ( typeof(jQuery) != 'undefined' ) {
     7 if ( typeof(jQuery) != 'undefined' ) {
     4 	if ( typeof(jQuery.fn.hoverIntent) == 'undefined' ) {
     8 	if ( typeof(jQuery.fn.hoverIntent) == 'undefined' ) {
     5 		/* jshint ignore:start */
     9 		/* jshint ignore:start */
     8 		/* jshint ignore:end */
    12 		/* jshint ignore:end */
     9 	}
    13 	}
    10 	jQuery(document).ready(function($){
    14 	jQuery(document).ready(function($){
    11 		var adminbar = $('#wpadminbar'), refresh, touchOpen, touchClose, disableHoverIntent = false;
    15 		var adminbar = $('#wpadminbar'), refresh, touchOpen, touchClose, disableHoverIntent = false;
    12 
    16 
    13 		refresh = function(i, el){ // force the browser to refresh the tabbing index
    17 		/**
       
    18 		 * Forces the browser to refresh the tabbing index.
       
    19 		 *
       
    20 		 * @since 3.3.0
       
    21 		 *
       
    22 		 * @param {number}      i  The index of the HTML element to remove the tab index
       
    23 		 *                         from. This parameter is necessary because we use this
       
    24 		 *                         function in .each calls.
       
    25 		 * @param {HTMLElement} el The HTML element to remove the tab index from.
       
    26 		 *
       
    27 		 * @return {void}
       
    28 		 */
       
    29 		refresh = function(i, el){
    14 			var node = $(el), tab = node.attr('tabindex');
    30 			var node = $(el), tab = node.attr('tabindex');
    15 			if ( tab )
    31 			if ( tab )
    16 				node.attr('tabindex', '0').attr('tabindex', tab);
    32 				node.attr('tabindex', '0').attr('tabindex', tab);
    17 		};
    33 		};
    18 
    34 
       
    35 		/**
       
    36 		 * Adds or removes the hover class on touch.
       
    37 		 *
       
    38 		 * @since 3.5.0
       
    39 		 *
       
    40 		 * @param {boolean} unbind If true removes the wp-mobile-hover class.
       
    41 		 *
       
    42 		 * @return {void}
       
    43 		 */
    19 		touchOpen = function(unbind) {
    44 		touchOpen = function(unbind) {
    20 			adminbar.find('li.menupop').on('click.wp-mobile-hover', function(e) {
    45 			adminbar.find('li.menupop').on('click.wp-mobile-hover', function(e) {
    21 				var el = $(this);
    46 				var el = $(this);
    22 
    47 
    23 				if ( el.parent().is('#wp-admin-bar-root-default') && !el.hasClass('hover') ) {
    48 				if ( el.parent().is('#wp-admin-bar-root-default') && !el.hasClass('hover') ) {
    41 					disableHoverIntent = false;
    66 					disableHoverIntent = false;
    42 				}
    67 				}
    43 			});
    68 			});
    44 		};
    69 		};
    45 
    70 
       
    71 		/**
       
    72 		 * Removes the hover class if clicked or touched outside the admin bar.
       
    73 		 *
       
    74 		 * @since 3.5.0
       
    75 		 *
       
    76 		 * @return {void}
       
    77 		 */
    46 		touchClose = function() {
    78 		touchClose = function() {
    47 			var mobileEvent = /Mobile\/.+Safari/.test(navigator.userAgent) ? 'touchstart' : 'click';
    79 			var mobileEvent = /Mobile\/.+Safari/.test(navigator.userAgent) ? 'touchstart' : 'click';
    48 			// close any open drop-downs when the click/touch is not on the toolbar
    80 			// close any open drop-downs when the click/touch is not on the toolbar
    49 			$(document.body).on( mobileEvent+'.wp-mobile-hover', function(e) {
    81 			$(document.body).on( mobileEvent+'.wp-mobile-hover', function(e) {
    50 				if ( !$(e.target).closest('#wpadminbar').length )
    82 				if ( !$(e.target).closest('#wpadminbar').length )
    52 			});
    84 			});
    53 		};
    85 		};
    54 
    86 
    55 		adminbar.removeClass('nojq').removeClass('nojs');
    87 		adminbar.removeClass('nojq').removeClass('nojs');
    56 
    88 
       
    89 		// If clicked on the adminbar add the hoverclass, if clicked outside it remove
       
    90 		// it.
    57 		if ( 'ontouchstart' in window ) {
    91 		if ( 'ontouchstart' in window ) {
    58 			adminbar.on('touchstart', function(){
    92 			adminbar.on('touchstart', function(){
    59 				touchOpen(true);
    93 				touchOpen(true);
    60 				disableHoverIntent = true;
    94 				disableHoverIntent = true;
    61 			});
    95 			});
    63 		} else if ( /IEMobile\/[1-9]/.test(navigator.userAgent) ) {
    97 		} else if ( /IEMobile\/[1-9]/.test(navigator.userAgent) ) {
    64 			touchOpen();
    98 			touchOpen();
    65 			touchClose();
    99 			touchClose();
    66 		}
   100 		}
    67 
   101 
       
   102 		// Adds or removes the hover class based on the hover intent.
    68 		adminbar.find('li.menupop').hoverIntent({
   103 		adminbar.find('li.menupop').hoverIntent({
    69 			over: function() {
   104 			over: function() {
    70 				if ( disableHoverIntent )
   105 				if ( disableHoverIntent )
    71 					return;
   106 					return;
    72 
   107 
    81 			timeout: 180,
   116 			timeout: 180,
    82 			sensitivity: 7,
   117 			sensitivity: 7,
    83 			interval: 100
   118 			interval: 100
    84 		});
   119 		});
    85 
   120 
       
   121 		// Prevents the toolbar from covering up content when a hash is present in the
       
   122 		// URL.
    86 		if ( window.location.hash )
   123 		if ( window.location.hash )
    87 			window.scrollBy( 0, -32 );
   124 			window.scrollBy( 0, -32 );
    88 
   125 
       
   126 		/**
       
   127 		 * Handles the selected state of the Shortlink link.
       
   128 		 *
       
   129 		 * When the input is visible the link should be selected, when the input is
       
   130 		 * unfocused the link should be unselected.
       
   131 		 *
       
   132 		 * @param {Object} e The click event.
       
   133 		 *
       
   134 		 * @return {void}
       
   135 		 **/
    89 		$('#wp-admin-bar-get-shortlink').click(function(e){
   136 		$('#wp-admin-bar-get-shortlink').click(function(e){
    90 			e.preventDefault();
   137 			e.preventDefault();
    91 			$(this).addClass('selected').children('.shortlink-input').blur(function(){
   138 			$(this).addClass('selected').children('.shortlink-input').blur(function(){
    92 				$(this).parents('#wp-admin-bar-get-shortlink').removeClass('selected');
   139 				$(this).parents('#wp-admin-bar-get-shortlink').removeClass('selected');
    93 			}).focus().select();
   140 			}).focus().select();
    94 		});
   141 		});
    95 
   142 
       
   143 		/**
       
   144 		 * Removes the hoverclass if the enter key is pressed.
       
   145 		 *
       
   146 		 * Makes sure the tab index is refreshed by refreshing each ab-item
       
   147 		 * and its children.
       
   148 		 *
       
   149 		 * @param {Object} e The keydown event.
       
   150 		 *
       
   151 		 * @return {void}
       
   152 		 */
    96 		$('#wpadminbar li.menupop > .ab-item').bind('keydown.adminbar', function(e){
   153 		$('#wpadminbar li.menupop > .ab-item').bind('keydown.adminbar', function(e){
       
   154 			// Key code 13 is the enter key.
    97 			if ( e.which != 13 )
   155 			if ( e.which != 13 )
    98 				return;
   156 				return;
    99 
   157 
   100 			var target = $(e.target),
   158 			var target = $(e.target),
   101 				wrap = target.closest('.ab-sub-wrapper'),
   159 				wrap = target.closest('.ab-sub-wrapper'),
   114 			}
   172 			}
   115 
   173 
   116 			target.siblings('.ab-sub-wrapper').find('.ab-item').each(refresh);
   174 			target.siblings('.ab-sub-wrapper').find('.ab-item').each(refresh);
   117 		}).each(refresh);
   175 		}).each(refresh);
   118 
   176 
       
   177 		/**
       
   178 		 * Removes the hover class when the escape key is pressed.
       
   179 		 *
       
   180 		 * Makes sure the tab index is refreshed by refreshing each ab-item
       
   181 		 * and its children.
       
   182 		 *
       
   183 		 * @param {Object} e The keydown event.
       
   184 		 *
       
   185 		 * @return {void}
       
   186 		 */
   119 		$('#wpadminbar .ab-item').bind('keydown.adminbar', function(e){
   187 		$('#wpadminbar .ab-item').bind('keydown.adminbar', function(e){
       
   188 			// Key code 27 is the escape key.
   120 			if ( e.which != 27 )
   189 			if ( e.which != 27 )
   121 				return;
   190 				return;
   122 
   191 
   123 			var target = $(e.target);
   192 			var target = $(e.target);
   124 
   193 
   127 
   196 
   128 			target.closest('.hover').removeClass('hover').children('.ab-item').focus();
   197 			target.closest('.hover').removeClass('hover').children('.ab-item').focus();
   129 			target.siblings('.ab-sub-wrapper').find('.ab-item').each(refresh);
   198 			target.siblings('.ab-sub-wrapper').find('.ab-item').each(refresh);
   130 		});
   199 		});
   131 
   200 
       
   201 		/**
       
   202 		 * Scrolls to top of page by clicking the adminbar.
       
   203 		 *
       
   204 		 * @param {Object} e The click event.
       
   205 		 *
       
   206 		 * @return {void}
       
   207 		 */
   132 		adminbar.click( function(e) {
   208 		adminbar.click( function(e) {
   133 			if ( e.target.id != 'wpadminbar' && e.target.id != 'wp-admin-bar-top-secondary' ) {
   209 			if ( e.target.id != 'wpadminbar' && e.target.id != 'wp-admin-bar-top-secondary' ) {
   134 				return;
   210 				return;
   135 			}
   211 			}
   136 
   212 
   137 			adminbar.find( 'li.menupop.hover' ).removeClass( 'hover' );
   213 			adminbar.find( 'li.menupop.hover' ).removeClass( 'hover' );
   138 			$( 'html, body' ).animate( { scrollTop: 0 }, 'fast' );
   214 			$( 'html, body' ).animate( { scrollTop: 0 }, 'fast' );
   139 			e.preventDefault();
   215 			e.preventDefault();
   140 		});
   216 		});
   141 
   217 
   142 		// fix focus bug in WebKit
   218 		/**
       
   219 		 * Sets the focus on an element with a href attribute.
       
   220 		 *
       
   221 		 * The timeout is used to fix a focus bug in WebKit.
       
   222 		 *
       
   223 		 * @param {Object} e The keydown event.
       
   224 		 *
       
   225 		 * @return {void}
       
   226 		 */
   143 		$('.screen-reader-shortcut').keydown( function(e) {
   227 		$('.screen-reader-shortcut').keydown( function(e) {
   144 			var id, ua;
   228 			var id, ua;
   145 
   229 
   146 			if ( 13 != e.which )
   230 			if ( 13 != e.which )
   147 				return;
   231 				return;
   156 				}, 100);
   240 				}, 100);
   157 			}
   241 			}
   158 		});
   242 		});
   159 
   243 
   160 		$( '#adminbar-search' ).on({
   244 		$( '#adminbar-search' ).on({
       
   245 			/**
       
   246 			 * Adds the adminbar-focused class on focus.
       
   247 			 *
       
   248 			 * @return {void}
       
   249 			 */
   161 			focus: function() {
   250 			focus: function() {
   162 				$( '#adminbarsearch' ).addClass( 'adminbar-focused' );
   251 				$( '#adminbarsearch' ).addClass( 'adminbar-focused' );
       
   252 			/**
       
   253 			 * Removes the adminbar-focused class on blur.
       
   254 			 *
       
   255 			 * @return {void}
       
   256 			 */
   163 			}, blur: function() {
   257 			}, blur: function() {
   164 				$( '#adminbarsearch' ).removeClass( 'adminbar-focused' );
   258 				$( '#adminbarsearch' ).removeClass( 'adminbar-focused' );
   165 			}
   259 			}
   166 		} );
   260 		} );
   167 
   261 
   168 		// Empty sessionStorage on logging out
       
   169 		if ( 'sessionStorage' in window ) {
   262 		if ( 'sessionStorage' in window ) {
       
   263 			/**
       
   264 			 * Empties sessionStorage on logging out.
       
   265 			 *
       
   266 			 * @return {void}
       
   267 			 */
   170 			$('#wp-admin-bar-logout a').click( function() {
   268 			$('#wp-admin-bar-logout a').click( function() {
   171 				try {
   269 				try {
   172 					for ( var key in sessionStorage ) {
   270 					for ( var key in sessionStorage ) {
   173 						if ( key.indexOf('wp-autosave-') != -1 )
   271 						if ( key.indexOf('wp-autosave-') != -1 )
   174 							sessionStorage.removeItem(key);
   272 							sessionStorage.removeItem(key);
   182 
   280 
   183 			document.body.className += ' no-font-face';
   281 			document.body.className += ' no-font-face';
   184 		}
   282 		}
   185 	});
   283 	});
   186 } else {
   284 } else {
       
   285 	/**
       
   286 	 * Wrapper function for the adminbar that's used if jQuery isn't available.
       
   287 	 *
       
   288 	 * @param {Object} d The document object.
       
   289 	 * @param {Object} w The window object.
       
   290 	 *
       
   291 	 * @return {void}
       
   292 	 */
   187 	(function(d, w) {
   293 	(function(d, w) {
       
   294 		/**
       
   295 		 * Adds an event listener to an object.
       
   296 		 *
       
   297 		 * @since 3.1.0
       
   298 		 *
       
   299 		 * @param {Object}   obj  The object to add the event listener to.
       
   300 		 * @param {string}   type The type of event.
       
   301 		 * @param {function} fn   The function to bind to the event listener.
       
   302 		 *
       
   303 		 * @return {void}
       
   304 		 */
   188 		var addEvent = function( obj, type, fn ) {
   305 		var addEvent = function( obj, type, fn ) {
   189 			if ( obj.addEventListener )
   306 			if ( obj && typeof obj.addEventListener === 'function' ) {
   190 				obj.addEventListener(type, fn, false);
   307 				obj.addEventListener( type, fn, false );
   191 			else if ( obj.attachEvent )
   308 			} else if ( obj && typeof obj.attachEvent === 'function' ) {
   192 				obj.attachEvent('on' + type, function() { return fn.call(obj, window.event);});
   309 				obj.attachEvent( 'on' + type, function() {
       
   310 					return fn.call( obj, window.event );
       
   311 				} );
       
   312 			}
   193 		},
   313 		},
   194 
   314 
   195 		aB, hc = new RegExp('\\bhover\\b', 'g'), q = [],
   315 		aB, hc = new RegExp('\\bhover\\b', 'g'), q = [],
   196 		rselected = new RegExp('\\bselected\\b', 'g'),
   316 		rselected = new RegExp('\\bselected\\b', 'g'),
   197 
   317 
   198 		/**
   318 		/**
   199 		 * Get the timeout ID of the given element
   319 		 * Gets the timeout ID of the given element.
       
   320 		 *
       
   321 		 * @since 3.1.0
       
   322 		 *
       
   323 		 * @param {HTMLElement} el The HTML element.
       
   324 		 *
       
   325 		 * @return {number|boolean} The ID value of the timer that is set or false.
   200 		 */
   326 		 */
   201 		getTOID = function(el) {
   327 		getTOID = function(el) {
   202 			var i = q.length;
   328 			var i = q.length;
   203 			while ( i-- ) {
   329 			while ( i-- ) {
   204 				if ( q[i] && el == q[i][1] )
   330 				if ( q[i] && el == q[i][1] )
   205 					return q[i][0];
   331 					return q[i][0];
   206 			}
   332 			}
   207 			return false;
   333 			return false;
   208 		},
   334 		},
   209 
   335 
       
   336 		/**
       
   337 		 * Adds the hoverclass to menu items.
       
   338 		 *
       
   339 		 * @since 3.1.0
       
   340 		 *
       
   341 		 * @param {HTMLElement} t The HTML element.
       
   342 		 *
       
   343 		 * @return {void}
       
   344 		 */
   210 		addHoverClass = function(t) {
   345 		addHoverClass = function(t) {
   211 			var i, id, inA, hovering, ul, li,
   346 			var i, id, inA, hovering, ul, li,
   212 				ancestors = [],
   347 				ancestors = [],
   213 				ancestorLength = 0;
   348 				ancestorLength = 0;
   214 
   349 
       
   350 			// aB is adminbar. d is document.
   215 			while ( t && t != aB && t != d ) {
   351 			while ( t && t != aB && t != d ) {
   216 				if ( 'LI' == t.nodeName.toUpperCase() ) {
   352 				if ( 'LI' == t.nodeName.toUpperCase() ) {
   217 					ancestors[ ancestors.length ] = t;
   353 					ancestors[ ancestors.length ] = t;
   218 					id = getTOID(t);
   354 					id = getTOID(t);
   219 					if ( id )
   355 					if ( id )
   222 					hovering = t;
   358 					hovering = t;
   223 				}
   359 				}
   224 				t = t.parentNode;
   360 				t = t.parentNode;
   225 			}
   361 			}
   226 
   362 
   227 			// Remove any selected classes.
   363 			// Removes any selected classes.
   228 			if ( hovering && hovering.parentNode ) {
   364 			if ( hovering && hovering.parentNode ) {
   229 				ul = hovering.parentNode;
   365 				ul = hovering.parentNode;
   230 				if ( ul && 'UL' == ul.nodeName.toUpperCase() ) {
   366 				if ( ul && 'UL' == ul.nodeName.toUpperCase() ) {
   231 					i = ul.childNodes.length;
   367 					i = ul.childNodes.length;
   232 					while ( i-- ) {
   368 					while ( i-- ) {
   235 							li.className = li.className ? li.className.replace( rselected, '' ) : '';
   371 							li.className = li.className ? li.className.replace( rselected, '' ) : '';
   236 					}
   372 					}
   237 				}
   373 				}
   238 			}
   374 			}
   239 
   375 
   240 			/* remove the hover class for any objects not in the immediate element's ancestry */
   376 			// Removes the hover class for any objects not in the immediate element's ancestry.
   241 			i = q.length;
   377 			i = q.length;
   242 			while ( i-- ) {
   378 			while ( i-- ) {
   243 				inA = false;
   379 				inA = false;
   244 				ancestorLength = ancestors.length;
   380 				ancestorLength = ancestors.length;
   245 				while( ancestorLength-- ) {
   381 				while( ancestorLength-- ) {
   250 				if ( ! inA )
   386 				if ( ! inA )
   251 					q[i][1].className = q[i][1].className ? q[i][1].className.replace(hc, '') : '';
   387 					q[i][1].className = q[i][1].className ? q[i][1].className.replace(hc, '') : '';
   252 			}
   388 			}
   253 		},
   389 		},
   254 
   390 
       
   391 		/**
       
   392 		 * Removes the hoverclass from menu items.
       
   393 		 *
       
   394 		 * @since 3.1.0
       
   395 		 *
       
   396 		 * @param {HTMLElement} t The HTML element.
       
   397 		 *
       
   398 		 * @return {void}
       
   399 		 */
   255 		removeHoverClass = function(t) {
   400 		removeHoverClass = function(t) {
   256 			while ( t && t != aB && t != d ) {
   401 			while ( t && t != aB && t != d ) {
   257 				if ( 'LI' == t.nodeName.toUpperCase() ) {
   402 				if ( 'LI' == t.nodeName.toUpperCase() ) {
   258 					(function(t) {
   403 					(function(t) {
   259 						var to = setTimeout(function() {
   404 						var to = setTimeout(function() {
   264 				}
   409 				}
   265 				t = t.parentNode;
   410 				t = t.parentNode;
   266 			}
   411 			}
   267 		},
   412 		},
   268 
   413 
       
   414 		/**
       
   415 		 * Handles the click on the Shortlink link in the adminbar.
       
   416 		 *
       
   417 		 * @since 3.1.0
       
   418 		 *
       
   419 		 * @param {Object} e The click event.
       
   420 		 *
       
   421 		 * @return {boolean} Returns false to prevent default click behavior.
       
   422 		 */
   269 		clickShortlink = function(e) {
   423 		clickShortlink = function(e) {
   270 			var i, l, node,
   424 			var i, l, node,
   271 				t = e.target || e.srcElement;
   425 				t = e.target || e.srcElement;
   272 
   426 
   273 			// Make t the shortlink menu item, or return.
   427 			// Make t the shortlink menu item, or return.
   302 				}
   456 				}
   303 			}
   457 			}
   304 			return false;
   458 			return false;
   305 		},
   459 		},
   306 
   460 
       
   461 		/**
       
   462 		 * Scrolls to the top of the page.
       
   463 		 *
       
   464 		 * @since 3.4.0
       
   465 		 *
       
   466 		 * @param {HTMLElement} t The HTML element.
       
   467 		 *
       
   468 		 * @return {void}
       
   469 		 */
   307 		scrollToTop = function(t) {
   470 		scrollToTop = function(t) {
   308 			var distance, speed, step, steps, timer, speed_step;
   471 			var distance, speed, step, steps, timer, speed_step;
   309 
   472 
   310 			// Ensure that the #wpadminbar was the target of the click.
   473 			// Ensure that the #wpadminbar was the target of the click.
   311 			if ( t.id != 'wpadminbar' && t.id != 'wp-admin-bar-top-secondary' )
   474 			if ( t.id != 'wpadminbar' && t.id != 'wp-admin-bar-top-secondary' )