<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[46872] trunk: Fix the admin toolbar js when jQuery is not present and replace the jQuery based hoverIntent.js with a native implementation.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/46872">46872</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/46872","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>azaozz</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2019-12-10 01:01:35 +0000 (Tue, 10 Dec 2019)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Fix the admin toolbar js when jQuery is not present and replace the jQuery based hoverIntent.js with a native implementation. Introduces the "hoverintent" (no dependencies) package.

Props dinhtungdu, audrasjb, azaozz.
Fixes <a href="https://core.trac.wordpress.org/ticket/47069">#47069</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkGruntfilejs">trunk/Gruntfile.js</a></li>
<li><a href="#trunkpackagelockjson">trunk/package-lock.json</a></li>
<li><a href="#trunkpackagejson">trunk/package.json</a></li>
<li><a href="#trunksrcjs_enqueueslibadminbarjs">trunk/src/js/_enqueues/lib/admin-bar.js</a></li>
<li><a href="#trunksrcwpincludesscriptloaderphp">trunk/src/wp-includes/script-loader.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkGruntfilejs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/Gruntfile.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/Gruntfile.js        2019-12-09 22:28:59 UTC (rev 46871)
+++ trunk/Gruntfile.js  2019-12-10 01:01:35 UTC (rev 46872)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -162,6 +162,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                [ WORKING_DIR + 'wp-includes/js/backbone.js' ]: [ './node_modules/backbone/backbone.js' ],
</span><span class="cx" style="display: block; padding: 0 10px">                                                [ WORKING_DIR + 'wp-includes/js/clipboard.js' ]: [ './node_modules/clipboard/dist/clipboard.js' ],
</span><span class="cx" style="display: block; padding: 0 10px">                                                [ WORKING_DIR + 'wp-includes/js/hoverIntent.js' ]: [ './node_modules/jquery-hoverintent/jquery.hoverIntent.js' ],
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                                               // Renamed to avoid conflict with jQuery hoverIntent.min.js (after minifying)
+                                               [ WORKING_DIR + 'wp-includes/js/hoverintent-js.min.js' ]: [ './node_modules/hoverintent/dist/hoverintent.min.js' ],
</ins><span class="cx" style="display: block; padding: 0 10px">                                                 [ WORKING_DIR + 'wp-includes/js/imagesloaded.min.js' ]: [ './node_modules/imagesloaded/imagesloaded.pkgd.min.js' ],
</span><span class="cx" style="display: block; padding: 0 10px">                                                [ WORKING_DIR + 'wp-includes/js/jquery/jquery-migrate.js' ]: [ './node_modules/jquery-migrate/dist/jquery-migrate.js' ],
</span><span class="cx" style="display: block; padding: 0 10px">                                                [ WORKING_DIR + 'wp-includes/js/jquery/jquery-migrate.min.js' ]: [ './node_modules/jquery-migrate/dist/jquery-migrate.min.js' ],
</span></span></pre></div>
<a id="trunkpackagelockjson"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/package-lock.json</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/package-lock.json   2019-12-09 22:28:59 UTC (rev 46871)
+++ trunk/package-lock.json     2019-12-10 01:01:35 UTC (rev 46872)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -13217,6 +13217,11 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                "jquery": ">=1.7"
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px">                },
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                "hoverintent": {
+                       "version": "2.2.1",
+                       "resolved": "https://registry.npmjs.org/hoverintent/-/hoverintent-2.2.1.tgz",
+                       "integrity": "sha512-VyU54L1xW5rSqpsv/LJ6ecymGXsXXeGs9iVEKot4kKBCq5UodSAuy3DqX686LZxEpaMEfeCHPu4LndsMX5Q9eQ=="
+               },
</ins><span class="cx" style="display: block; padding: 0 10px">                 "jquery-hoverintent": {
</span><span class="cx" style="display: block; padding: 0 10px">                        "version": "1.8.3",
</span><span class="cx" style="display: block; padding: 0 10px">                        "resolved": "https://registry.npmjs.org/jquery-hoverintent/-/jquery-hoverintent-1.8.3.tgz",
</span></span></pre></div>
<a id="trunkpackagejson"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/package.json</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/package.json        2019-12-09 22:28:59 UTC (rev 46871)
+++ trunk/package.json  2019-12-10 01:01:35 UTC (rev 46872)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -120,8 +120,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                "imagesloaded": "3.2.0",
</span><span class="cx" style="display: block; padding: 0 10px">                "jquery-color": "https://github.com/jquery/jquery-color/archive/2.1.2.tar.gz",
</span><span class="cx" style="display: block; padding: 0 10px">                "jquery-form": "4.2.1",
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                "jquery-ui": "https://github.com/jquery/jquery-ui/archive/1.11.4.tar.gz",
</ins><span class="cx" style="display: block; padding: 0 10px">                 "jquery-hoverintent": "1.8.3",
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                "jquery-ui": "https://github.com/jquery/jquery-ui/archive/1.11.4.tar.gz",
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         "hoverintent": "2.2.1",
</ins><span class="cx" style="display: block; padding: 0 10px">                 "lodash": "4.17.15",
</span><span class="cx" style="display: block; padding: 0 10px">                "masonry-layout": "3.3.2",
</span><span class="cx" style="display: block; padding: 0 10px">                "moment": "2.22.2",
</span></span></pre></div>
<a id="trunksrcjs_enqueueslibadminbarjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/js/_enqueues/lib/admin-bar.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/js/_enqueues/lib/admin-bar.js   2019-12-09 22:28:59 UTC (rev 46871)
+++ trunk/src/js/_enqueues/lib/admin-bar.js     2019-12-10 01:01:35 UTC (rev 46872)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,550 +1,405 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * @output wp-includes/js/admin-bar.js
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/**
+ * Admin bar with Vanilla JS, no external dependencies.
+ *
+ * @param {Object} document  The document object.
+ * @param {Object} window    The window object.
+ * @param {Object} navigator The navigator object.
+ *
+ * @return {void}
+ */
+( function( document, window, navigator ) {
+       document.addEventListener( 'DOMContentLoaded', function() {
+               var adminBar = document.getElementById( 'wpadminbar' ),
+                       topMenuItems = adminBar.querySelectorAll( 'li.menupop' ),
+                       allMenuItems = adminBar.querySelectorAll( '.ab-item' ),
+                       adminBarLogout = document.getElementById( 'wp-admin-bar-logout' ),
+                       adminBarSearchForm = document.getElementById( 'adminbarsearch' ),
+                       shortlink = document.getElementById( 'wp-admin-bar-get-shortlink' ),
+                       skipLink = adminBar.querySelector( '.screen-reader-shortcut' ),
+                       mobileEvent = /Mobile\/.+Safari/.test( navigator.userAgent ) ? 'touchstart' : 'click',
+                       adminBarSearchInput,
+                       i;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/* jshint loopfunc: true */
-// use jQuery and hoverIntent if loaded
-if ( typeof(jQuery) != 'undefined' ) {
-       if ( typeof(jQuery.fn.hoverIntent) == 'undefined' ) {
-               /* jshint ignore:start */
-               // hoverIntent v1.8.1 - Copy of wp-includes/js/hoverIntent.min.js
-               !function(a){a.fn.hoverIntent=function(b,c,d){var e={interval:100,sensitivity:6,timeout:0};e="object"==typeof b?a.extend(e,b):a.isFunction(c)?a.extend(e,{over:b,out:c,selector:d}):a.extend(e,{over:b,out:b,selector:c});var f,g,h,i,j=function(a){f=a.pageX,g=a.pageY},k=function(b,c){return c.hoverIntent_t=clearTimeout(c.hoverIntent_t),Math.sqrt((h-f)*(h-f)+(i-g)*(i-g))<e.sensitivity?(a(c).off("mousemove.hoverIntent",j),c.hoverIntent_s=!0,e.over.apply(c,[b])):(h=f,i=g,c.hoverIntent_t=setTimeout(function(){k(b,c)},e.interval),void 0)},l=function(a,b){return b.hoverIntent_t=clearTimeout(b.hoverIntent_t),b.hoverIntent_s=!1,e.out.apply(b,[a])},m=function(b){var c=a.extend({},b),d=this;d.hoverIntent_t&&(d.hoverIntent_t=clearTimeout(d.hoverIntent_t)),"mouseenter"===b.type?(h=c.pageX,i=c.pageY,a(d).on("mousemove.hoverIntent",j),d.hoverIntent_s||(d.hoverIntent_t=setTimeout(function(){k(c,d)},e.interval))):(a(d).off("mousemove.hoverIntent
 ",j),d.hoverIntent_s&&(d.hoverIntent_t=setTimeout(function(){l(c,d)},e.timeout)))};return this.on({"mouseenter.hoverIntent":m,"mouseleave.hoverIntent":m},e.selector)}}(jQuery);
-               /* jshint ignore:end */
-       }
-       jQuery(document).ready(function($){
-               var adminbar = $('#wpadminbar'), refresh, touchOpen, touchClose, disableHoverIntent = false;
-
</del><span class="cx" style="display: block; padding: 0 10px">                 /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                 * Forces the browser to refresh the tabbing index.
-                *
-                * @since 3.3.0
-                *
-                * @param {number}      i  The index of the HTML element to remove the tab index
-                *                         from. This parameter is necessary because we use this
-                *                         function in .each calls.
-                * @param {HTMLElement} el The HTML element to remove the tab index from.
-                *
-                * @return {void}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+          * Remove nojs class after the DOM is loaded.
</ins><span class="cx" style="display: block; padding: 0 10px">                  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                refresh = function(i, el){
-                       var node = $(el), tab = node.attr('tabindex');
-                       if ( tab )
-                               node.attr('tabindex', '0').attr('tabindex', tab);
-               };
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         adminBar.classList.remove( 'nojs' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                /**
-                * Adds or removes the hover class on touch.
-                *
-                * @since 3.5.0
-                *
-                * @param {boolean} unbind If true removes the wp-mobile-hover class.
-                *
-                * @return {void}
-                */
-               touchOpen = function(unbind) {
-                       adminbar.find('li.menupop').on('click.wp-mobile-hover', function(e) {
-                               var el = $(this);
-
-                               if ( el.parent().is('#wp-admin-bar-root-default') && !el.hasClass('hover') ) {
-                                       e.preventDefault();
-                                       adminbar.find('li.menupop.hover').removeClass('hover');
-                                       el.addClass('hover');
-                               } else if ( !el.hasClass('hover') ) {
-                                       e.stopPropagation();
-                                       e.preventDefault();
-                                       el.addClass('hover');
-                               } else if ( ! $( e.target ).closest( 'div' ).hasClass( 'ab-sub-wrapper' ) ) {
-                                       // We're dealing with an already-touch-opened menu genericon (we know el.hasClass('hover')),
-                                       // so close it on a second tap and prevent propag and defaults. See #29906
-                                       e.stopPropagation();
-                                       e.preventDefault();
-                                       el.removeClass('hover');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( 'ontouchstart' in window ) {
+                       /**
+                        * Remove hover class when the user touches outside the menu items.
+                        */
+                       document.body.addEventListener( mobileEvent, function( e ) {
+                               if ( ! getClosest( e.target, 'li.menupop' ) ) {
+                                       removeAllHoverClass( topMenuItems );
</ins><span class="cx" style="display: block; padding: 0 10px">                                 }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        } );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                if ( unbind ) {
-                                       $('li.menupop').off('click.wp-mobile-hover');
-                                       disableHoverIntent = false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 /**
+                        * Add listener for menu items to toggle hover class by touches.
+                        * Remove the callback later for better performance.
+                        */
+                       adminBar.addEventListener( 'touchstart', function bindMobileEvents() {
+                               for ( var i = 0; i < topMenuItems.length; i++ ) {
+                                       topMenuItems[i].addEventListener( 'click', mobileHover.bind( null, topMenuItems ) );
</ins><span class="cx" style="display: block; padding: 0 10px">                                 }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        });
-               };
</del><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                adminBar.removeEventListener( 'touchstart', bindMobileEvents );
+                       } );
+               }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                 * Removes the hover class if clicked or touched outside the admin bar.
-                *
-                * @since 3.5.0
-                *
-                * @return {void}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+          * Scroll page to top when clicking on the admin bar.
</ins><span class="cx" style="display: block; padding: 0 10px">                  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                touchClose = function() {
-                       var mobileEvent = /Mobile\/.+Safari/.test(navigator.userAgent) ? 'touchstart' : 'click';
-                       // close any open drop-downs when the click/touch is not on the toolbar
-                       $(document.body).on( mobileEvent+'.wp-mobile-hover', function(e) {
-                               if ( !$(e.target).closest('#wpadminbar').length )
-                                       adminbar.find('li.menupop.hover').removeClass('hover');
-                       });
-               };
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         adminBar.addEventListener( 'click', scrollToTop );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                adminbar.removeClass('nojq').removeClass('nojs');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         for ( i = 0; i < topMenuItems.length; i++ ) {
+                       /**
+                        * Adds or removes the hover class based on the hover intent.
+                        */
+                       hoverintent(
+                               topMenuItems[i],
+                               addHoverClass.bind( null, topMenuItems[i] ),
+                               removeHoverClass.bind( null, topMenuItems[i] )
+                       ).options( {
+                               timeout: 180,
+                       } );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // If clicked on the adminbar add the hoverclass, if clicked outside it remove
-               // it.
-               if ( 'ontouchstart' in window ) {
-                       adminbar.on('touchstart', function(){
-                               touchOpen(true);
-                               disableHoverIntent = true;
-                       });
-                       touchClose();
-               } else if ( /IEMobile\/[1-9]/.test(navigator.userAgent) ) {
-                       touchOpen();
-                       touchClose();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 /**
+                        * Toggle hover class if the enter key is pressed.
+                        */
+                       topMenuItems[i].addEventListener( 'keydown', toggleHoverIfEnter );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // Adds or removes the hover class based on the hover intent.
-               adminbar.find('li.menupop').hoverIntent({
-                       over: function() {
-                               if ( disableHoverIntent )
-                                       return;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         /**
+                * Remove hover class if the escape key is pressed.
+                */
+               for ( i = 0; i < allMenuItems.length; i++ ) {
+                       allMenuItems[i].addEventListener( 'keydown', removeHoverIfEscape );
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $(this).addClass('hover');
-                       },
-                       out: function() {
-                               if ( disableHoverIntent )
-                                       return;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( adminBarSearchForm ) {
+                       adminBarSearchInput = document.getElementById( 'adminbar-search' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $(this).removeClass('hover');
-                       },
-                       timeout: 180,
-                       sensitivity: 7,
-                       interval: 100
-               });
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 /**
+                        * Adds the adminbar-focused class on focus.
+                        */
+                       adminBarSearchInput.addEventListener( 'focus', function() {
+                               adminBarSearchForm.classList.add( 'adminbar-focused' );
+                       } );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // Prevents the toolbar from covering up content when a hash is present in the
-               // URL.
-               if ( window.location.hash )
-                       window.scrollBy( 0, -32 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 /**
+                        * Removes the adminbar-focused class on blur.
+                        */
+                       adminBarSearchInput.addEventListener( 'blur', function() {
+                               adminBarSearchForm.classList.remove( 'adminbar-focused' );
+                       } );
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                 * Handles the selected state of the Shortlink link.
-                *
-                * When the input is visible the link should be selected, when the input is
-                * unfocused the link should be unselected.
-                *
-                * @param {Object} e The click event.
-                *
-                * @return {void}
-                **/
-               $('#wp-admin-bar-get-shortlink').click(function(e){
-                       e.preventDefault();
-                       $(this).addClass('selected').children('.shortlink-input').blur(function(){
-                               $(this).parents('#wp-admin-bar-get-shortlink').removeClass('selected');
-                       }).focus().select();
-               });
-
-               /**
-                * Removes the hoverclass if the enter key is pressed.
-                *
-                * Makes sure the tab index is refreshed by refreshing each ab-item
-                * and its children.
-                *
-                * @param {Object} e The keydown event.
-                *
-                * @return {void}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+          * Focus the target of skip link after pressing Enter.
</ins><span class="cx" style="display: block; padding: 0 10px">                  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $('#wpadminbar li.menupop > .ab-item').bind('keydown.adminbar', function(e){
-                       // Key code 13 is the enter key.
-                       if ( e.which != 13 )
-                               return;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         skipLink.addEventListener( 'keydown', focusTargetAfterEnter );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        var target = $(e.target),
-                               wrap = target.closest('.ab-sub-wrapper'),
-                               parentHasHover = target.parent().hasClass('hover');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( shortlink ) {
+                       shortlink.addEventListener( 'click', clickShortlink );
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        e.stopPropagation();
-                       e.preventDefault();
-
-                       if ( !wrap.length )
-                               wrap = $('#wpadminbar .quicklinks');
-
-                       wrap.find('.menupop').removeClass('hover');
-
-                       if ( ! parentHasHover ) {
-                               target.parent().toggleClass('hover');
-                       }
-
-                       target.siblings('.ab-sub-wrapper').find('.ab-item').each(refresh);
-               }).each(refresh);
-
</del><span class="cx" style="display: block; padding: 0 10px">                 /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                 * Removes the hover class when the escape key is pressed.
-                *
-                * Makes sure the tab index is refreshed by refreshing each ab-item
-                * and its children.
-                *
-                * @param {Object} e The keydown event.
-                *
-                * @return {void}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+          * Prevents the toolbar from covering up content when a hash is present
+                * in the URL.
</ins><span class="cx" style="display: block; padding: 0 10px">                  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $('#wpadminbar .ab-item').bind('keydown.adminbar', function(e){
-                       // Key code 27 is the escape key.
-                       if ( e.which != 27 )
-                               return;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( window.location.hash ) {
+                       window.scrollBy( 0, -32 );
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        var target = $(e.target);
-
-                       e.stopPropagation();
-                       e.preventDefault();
-
-                       target.closest('.hover').removeClass('hover').children('.ab-item').focus();
-                       target.siblings('.ab-sub-wrapper').find('.ab-item').each(refresh);
-               });
-
</del><span class="cx" style="display: block; padding: 0 10px">                 /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                 * Scrolls to top of page by clicking the adminbar.
-                *
-                * @param {Object} e The click event.
-                *
-                * @return {void}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+          * Add no-font-face class to body if needed.
</ins><span class="cx" style="display: block; padding: 0 10px">                  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                adminbar.click( function(e) {
-                       if ( e.target.id != 'wpadminbar' && e.target.id != 'wp-admin-bar-top-secondary' ) {
-                               return;
-                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( navigator.userAgent && document.body.className.indexOf( 'no-font-face' ) === -1 &&
+                       /Android (1.0|1.1|1.5|1.6|2.0|2.1)|Nokia|Opera Mini|w(eb)?OSBrowser|webOS|UCWEB|Windows Phone OS 7|XBLWP7|ZuneWP7|MSIE 7/.test( navigator.userAgent ) ) {
+                       document.body.className += ' no-font-face';
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        adminbar.find( 'li.menupop.hover' ).removeClass( 'hover' );
-                       $( 'html, body' ).animate( { scrollTop: 0 }, 'fast' );
-                       e.preventDefault();
-               });
-
</del><span class="cx" style="display: block; padding: 0 10px">                 /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                 * Sets the focus on an element with a href attribute.
-                *
-                * The timeout is used to fix a focus bug in WebKit.
-                *
-                * @param {Object} e The keydown event.
-                *
-                * @return {void}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+          * Clear sessionStorage on logging out.
</ins><span class="cx" style="display: block; padding: 0 10px">                  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $('.screen-reader-shortcut').keydown( function(e) {
-                       var id, ua;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         adminBarLogout.addEventListener( 'click', emptySessionStorage );
+       } );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( 13 != e.which )
-                               return;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Remove hover class for top level menu item when escape is pressed.
+        *
+        * @since 5.3.0
+        *
+        * @param {Event} e The keydown event.
+        */
+       function removeHoverIfEscape( e ) {
+               var wrapper;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        id = $( this ).attr( 'href' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( e.which != 27 ) {
+                       return;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        ua = navigator.userAgent.toLowerCase();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         wrapper = getClosest( e.target, '.menupop' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( ua.indexOf('applewebkit') != -1 && id && id.charAt(0) == '#' ) {
-                               setTimeout(function () {
-                                       $(id).focus();
-                               }, 100);
-                       }
-               });
-
-               $( '#adminbar-search' ).on({
-                       /**
-                        * Adds the adminbar-focused class on focus.
-                        *
-                        * @return {void}
-                        */
-                       focus: function() {
-                               $( '#adminbarsearch' ).addClass( 'adminbar-focused' );
-                       /**
-                        * Removes the adminbar-focused class on blur.
-                        *
-                        * @return {void}
-                        */
-                       }, blur: function() {
-                               $( '#adminbarsearch' ).removeClass( 'adminbar-focused' );
-                       }
-               } );
-
-               if ( 'sessionStorage' in window ) {
-                       /**
-                        * Empties sessionStorage on logging out.
-                        *
-                        * @return {void}
-                        */
-                       $('#wp-admin-bar-logout a').click( function() {
-                               try {
-                                       for ( var key in sessionStorage ) {
-                                               if ( key.indexOf('wp-autosave-') != -1 )
-                                                       sessionStorage.removeItem(key);
-                                       }
-                               } catch(e) {}
-                       });
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( ! wrapper ) {
+                       return;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( navigator.userAgent && document.body.className.indexOf( 'no-font-face' ) === -1 &&
-                       /Android (1.0|1.1|1.5|1.6|2.0|2.1)|Nokia|Opera Mini|w(eb)?OSBrowser|webOS|UCWEB|Windows Phone OS 7|XBLWP7|ZuneWP7|MSIE 7/.test( navigator.userAgent ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         wrapper.querySelector( '.menupop > .ab-item' ).focus();
+               removeHoverClass( wrapper );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        document.body.className += ' no-font-face';
-               }
-       });
-} else {
</del><span class="cx" style="display: block; padding: 0 10px">         /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Wrapper function for the adminbar that's used if jQuery isn't available.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Toggle hover class for top level menu item when enter is pressed.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @param {Object} d The document object.
-        * @param {Object} w The window object.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @since 5.3.0
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @return {void}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @param {Event} e The keydown event.
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        (function(d, w) {
-               /**
-                * Adds an event listener to an object.
-                *
-                * @since 3.1.0
-                *
-                * @param {Object}   obj  The object to add the event listener to.
-                * @param {string}   type The type of event.
-                * @param {function} fn   The function to bind to the event listener.
-                *
-                * @return {void}
-                */
-               var addEvent = function( obj, type, fn ) {
-                       if ( obj && typeof obj.addEventListener === 'function' ) {
-                               obj.addEventListener( type, fn, false );
-                       } else if ( obj && typeof obj.attachEvent === 'function' ) {
-                               obj.attachEvent( 'on' + type, function() {
-                                       return fn.call( obj, window.event );
-                               } );
-                       }
-               },
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ function toggleHoverIfEnter( e ) {
+               var wrapper;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                aB, hc = new RegExp('\\bhover\\b', 'g'), q = [],
-               rselected = new RegExp('\\bselected\\b', 'g'),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( e.which != 13 ) {
+                       return;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                /**
-                * Gets the timeout ID of the given element.
-                *
-                * @since 3.1.0
-                *
-                * @param {HTMLElement} el The HTML element.
-                *
-                * @return {number|boolean} The ID value of the timer that is set or false.
-                */
-               getTOID = function(el) {
-                       var i = q.length;
-                       while ( i-- ) {
-                               if ( q[i] && el == q[i][1] )
-                                       return q[i][0];
-                       }
-                       return false;
-               },
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( !! getClosest( e.target, '.ab-sub-wrapper' ) ) {
+                       return;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                /**
-                * Adds the hoverclass to menu items.
-                *
-                * @since 3.1.0
-                *
-                * @param {HTMLElement} t The HTML element.
-                *
-                * @return {void}
-                */
-               addHoverClass = function(t) {
-                       var i, id, inA, hovering, ul, li,
-                               ancestors = [],
-                               ancestorLength = 0;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         wrapper = getClosest( e.target, '.menupop' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        // aB is adminbar. d is document.
-                       while ( t && t != aB && t != d ) {
-                               if ( 'LI' == t.nodeName.toUpperCase() ) {
-                                       ancestors[ ancestors.length ] = t;
-                                       id = getTOID(t);
-                                       if ( id )
-                                               clearTimeout( id );
-                                       t.className = t.className ? ( t.className.replace(hc, '') + ' hover' ) : 'hover';
-                                       hovering = t;
-                               }
-                               t = t.parentNode;
-                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( ! wrapper ) {
+                       return;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        // Removes any selected classes.
-                       if ( hovering && hovering.parentNode ) {
-                               ul = hovering.parentNode;
-                               if ( ul && 'UL' == ul.nodeName.toUpperCase() ) {
-                                       i = ul.childNodes.length;
-                                       while ( i-- ) {
-                                               li = ul.childNodes[i];
-                                               if ( li != hovering )
-                                                       li.className = li.className ? li.className.replace( rselected, '' ) : '';
-                                       }
-                               }
-                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         e.preventDefault();
+               if ( hasHoverClass( wrapper ) ) {
+                       removeHoverClass( wrapper );
+               } else {
+                       addHoverClass( wrapper );
+               }
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        // Removes the hover class for any objects not in the immediate element's ancestry.
-                       i = q.length;
-                       while ( i-- ) {
-                               inA = false;
-                               ancestorLength = ancestors.length;
-                               while( ancestorLength-- ) {
-                                       if ( ancestors[ ancestorLength ] == q[i][1] )
-                                               inA = true;
-                               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Focus the target of skip link after pressing Enter.
+        *
+        * @since 5.3.0
+        *
+        * @param {Event} e The keydown event.
+        */
+       function focusTargetAfterEnter( e ) {
+               var id, userAgent;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                if ( ! inA )
-                                       q[i][1].className = q[i][1].className ? q[i][1].className.replace(hc, '') : '';
-                       }
-               },
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( 13 !==     e.which ) {
+                       return;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                /**
-                * Removes the hoverclass from menu items.
-                *
-                * @since 3.1.0
-                *
-                * @param {HTMLElement} t The HTML element.
-                *
-                * @return {void}
-                */
-               removeHoverClass = function(t) {
-                       while ( t && t != aB && t != d ) {
-                               if ( 'LI' == t.nodeName.toUpperCase() ) {
-                                       (function(t) {
-                                               var to = setTimeout(function() {
-                                                       t.className = t.className ? t.className.replace(hc, '') : '';
-                                               }, 500);
-                                               q[q.length] = [to, t];
-                                       })(t);
-                               }
-                               t = t.parentNode;
-                       }
-               },
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         id = e.target.getAttribute( 'href' );
+               userAgent = navigator.userAgent.toLowerCase();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                /**
-                * Handles the click on the Shortlink link in the adminbar.
-                *
-                * @since 3.1.0
-                *
-                * @param {Object} e The click event.
-                *
-                * @return {boolean} Returns false to prevent default click behavior.
-                */
-               clickShortlink = function(e) {
-                       var i, l, node,
-                               t = e.target || e.srcElement;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( userAgent.indexOf( 'applewebkit' ) != -1 && id && id.charAt( 0 ) == '#' ) {
+                       setTimeout( function() {
+                               var target = document.getElementById( id.replace( '#', '' ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        // Make t the shortlink menu item, or return.
-                       while ( true ) {
-                               // Check if we've gone past the shortlink node,
-                               // or if the user is clicking on the input.
-                               if ( ! t || t == d || t == aB )
-                                       return;
-                               // Check if we've found the shortlink node.
-                               if ( t.id && t.id == 'wp-admin-bar-get-shortlink' )
-                                       break;
-                               t = t.parentNode;
-                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         target.setAttribute( 'tabIndex', '0' );
+                               target.focus();
+                       }, 100 );
+               }
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        // IE doesn't support preventDefault, and does support returnValue
-                       if ( e.preventDefault )
-                               e.preventDefault();
-                       e.returnValue = false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Toogle hover class for mobile devices.
+        *
+        * @since 5.3.0
+        *
+        * @param {NodeList} topMenuItems All menu items.
+        * @param {Event} e The click event.
+        */
+       function mobileHover( topMenuItems, e ) {
+               var wrapper;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( -1 == t.className.indexOf('selected') )
-                               t.className += ' selected';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( !! getClosest( e.target, '.ab-sub-wrapper' ) ) {
+                       return;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        for ( i = 0, l = t.childNodes.length; i < l; i++ ) {
-                               node = t.childNodes[i];
-                               if ( node.className && -1 != node.className.indexOf('shortlink-input') ) {
-                                       node.focus();
-                                       node.select();
-                                       node.onblur = function() {
-                                               t.className = t.className ? t.className.replace( rselected, '' ) : '';
-                                       };
-                                       break;
-                               }
-                       }
-                       return false;
-               },
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         e.preventDefault();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                /**
-                * Scrolls to the top of the page.
-                *
-                * @since 3.4.0
-                *
-                * @param {HTMLElement} t The HTML element.
-                *
-                * @return {void}
-                */
-               scrollToTop = function(t) {
-                       var distance, speed, step, steps, timer, speed_step;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         wrapper = getClosest( e.target, '.menupop' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        // Ensure that the #wpadminbar was the target of the click.
-                       if ( t.id != 'wpadminbar' && t.id != 'wp-admin-bar-top-secondary' )
-                               return;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( ! wrapper ) {
+                       return;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        distance    = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( hasHoverClass( wrapper ) ) {
+                       removeHoverClass( wrapper );
+               } else {
+                       removeAllHoverClass( topMenuItems );
+                       addHoverClass( wrapper );
+               }
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( distance < 1 )
-                               return;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Handles the click on the Shortlink link in the adminbar.
+        *
+        * @since 3.1.0
+        * @since 5.3.0 Use querySelector to clean up the function.
+        *
+        * @param {Event} e The click event.
+        *
+        * @return {boolean} Returns false to prevent default click behavior.
+        */
+       function clickShortlink( e ) {
+               var wrapper = e.target.parentNode,
+                       input = wrapper.querySelector( '.shortlink-input' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        speed_step = distance > 800 ? 130 : 100;
-                       speed     = Math.min( 12, Math.round( distance / speed_step ) );
-                       step      = distance > 800 ? Math.round( distance / 30  ) : Math.round( distance / 20  );
-                       steps     = [];
-                       timer     = 0;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // IE doesn't support preventDefault, and does support returnValue
+               if ( e.preventDefault ) {
+                       e.preventDefault();
+               }
+               e.returnValue = false;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        // Animate scrolling to the top of the page by generating steps to
-                       // the top of the page and shifting to each step at a set interval.
-                       while ( distance ) {
-                               distance -= step;
-                               if ( distance < 0 )
-                                       distance = 0;
-                               steps.push( distance );
-
-                               setTimeout( function() {
-                                       window.scrollTo( 0, steps.shift() );
-                               }, timer * speed );
-
-                               timer++;
-                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         wrapper.classList.add( 'selected' );
+               input.focus();
+               input.select();
+               input.onblur = function() {
+                       wrapper.classList.remove( 'selected' );
</ins><span class="cx" style="display: block; padding: 0 10px">                 };
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                addEvent(w, 'load', function() {
-                       aB = d.getElementById('wpadminbar');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         return false;
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( d.body && aB ) {
-                               d.body.appendChild( aB );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Clear sessionStorage on logging out.
+        *
+        * @since 5.3.0
+        */
+       function emptySessionStorage() {
+               if ( 'sessionStorage' in window ) {
+                       try {
+                               for ( var key in sessionStorage ) {
+                                       if ( key.indexOf( 'wp-autosave-' ) != -1 ) {
+                                               sessionStorage.removeItem( key );
+                                       }
+                               }
+                       } catch ( e ) {}
+               }
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                if ( aB.className )
-                                       aB.className = aB.className.replace(/nojs/, '');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Check if menu item has hover class.
+        *
+        * @since 5.3.0
+        *
+        * @param {HTMLElement} item Menu item Element.
+        */
+       function hasHoverClass( item ) {
+               return item.classList.contains( 'hover' );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                addEvent(aB, 'mouseover', function(e) {
-                                       addHoverClass( e.target || e.srcElement );
-                               });
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Add hover class for menu item.
+        *
+        * @since 5.3.0
+        *
+        * @param {HTMLElement} item Menu item Element.
+        */
+       function addHoverClass( item ) {
+               item.classList.add( 'hover' );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                addEvent(aB, 'mouseout', function(e) {
-                                       removeHoverClass( e.target || e.srcElement );
-                               });
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Remove hover class for menu item.
+        *
+        * @since 5.3.0
+        *
+        * @param {HTMLElement} item Menu item Element.
+        */
+       function removeHoverClass( item ) {
+               item.classList.remove( 'hover' );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                addEvent(aB, 'click', clickShortlink );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Remove hover class for all menu items.
+        *
+        * @since 5.3.0
+        *
+        * @param {NodeList} topMenuItems All menu items.
+        */
+       function removeAllHoverClass( topMenuItems ) {
+               for ( var i = 0; i < topMenuItems.length; i++ ) {
+                       if ( hasHoverClass( topMenuItems[i] ) ) {
+                               removeHoverClass( topMenuItems[i] );
+                       }
+               }
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                addEvent(aB, 'click', function(e) {
-                                       scrollToTop( e.target || e.srcElement );
-                               });
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Scrolls to the top of the page.
+        *
+        * @since 3.4.0
+        *
+        * @param {Event} e The Click event.
+        *
+        * @return {void}
+        */
+       function scrollToTop( event ) {
+               // Only scroll when clicking on the wpadminbar, not on menus or submenus.
+               if (
+                       event.target &&
+                       event.target.id &&
+                       event.target.id != 'wpadminbar' &&
+                       event.target.id != 'wp-admin-bar-top-secondary'
+               ) {
+                       return;
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                addEvent( document.getElementById('wp-admin-bar-logout'), 'click', function() {
-                                       if ( 'sessionStorage' in window ) {
-                                               try {
-                                                       for ( var key in sessionStorage ) {
-                                                               if ( key.indexOf('wp-autosave-') != -1 )
-                                                                       sessionStorage.removeItem(key);
-                                                       }
-                                               } catch(e) {}
-                                       }
-                               });
-                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         try {
+                       window.scrollTo( {
+                               top: -32,
+                               left: 0,
+                               behavior: 'smooth'
+                       } );
+               } catch ( er ) {
+                       window.scrollTo( 0, -32 );
+               }
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( w.location.hash )
-                               w.scrollBy(0,-32);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Get closest Element.
+        *
+        * @since 5.3.0
+        *
+        * @param {HTMLElement} el Element to get parent.
+        * @param {string} selector CSS selector to match.
+        */
+       function getClosest( el, selector ) {
+               if ( ! Element.prototype.matches ) {
+                       Element.prototype.matches =
+                               Element.prototype.matchesSelector ||
+                               Element.prototype.mozMatchesSelector ||
+                               Element.prototype.msMatchesSelector ||
+                               Element.prototype.oMatchesSelector ||
+                               Element.prototype.webkitMatchesSelector ||
+                               function( s ) {
+                                       var matches = ( this.document || this.ownerDocument ).querySelectorAll( s ),
+                                               i = matches.length;
+                                       while ( --i >= 0 && matches.item( i ) !== this ) { }
+                                       return i > -1;
+                               };
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( navigator.userAgent && document.body.className.indexOf( 'no-font-face' ) === -1 &&
-                               /Android (1.0|1.1|1.5|1.6|2.0|2.1)|Nokia|Opera Mini|w(eb)?OSBrowser|webOS|UCWEB|Windows Phone OS 7|XBLWP7|ZuneWP7|MSIE 7/.test( navigator.userAgent ) ) {
-
-                               document.body.className += ' no-font-face';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Get the closest matching elent
+               for ( ; el && el !== document; el = el.parentNode ) {
+                       if ( el.matches( selector ) ) {
+                               return el;
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                });
-       })(document, window);
-
-}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         }
+               return null;
+       }
+} )( document, window, navigator );
</ins></span></pre></div>
<a id="trunksrcwpincludesscriptloaderphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/script-loader.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/script-loader.php   2019-12-09 22:28:59 UTC (rev 46871)
+++ trunk/src/wp-includes/script-loader.php     2019-12-10 01:01:35 UTC (rev 46872)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1490,7 +1490,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $scripts->add( 'user-suggest', "/wp-admin/js/user-suggest$suffix.js", array( 'jquery-ui-autocomplete' ), false, 1 );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $scripts->add( 'admin-bar', "/wp-includes/js/admin-bar$suffix.js", array(), false, 1 );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $scripts->add( 'admin-bar', "/wp-includes/js/admin-bar$suffix.js", array( 'hoverintent-js' ), false, 1 );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $scripts->add( 'wplink', "/wp-includes/js/wplink$suffix.js", array( 'jquery', 'wp-a11y' ), false, 1 );
</span><span class="cx" style="display: block; padding: 0 10px">        did_action( 'init' ) && $scripts->localize(
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1515,6 +1515,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $scripts->add( 'hoverIntent', "/wp-includes/js/hoverIntent$suffix.js", array( 'jquery' ), '1.8.1', 1 );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        // JS-only version of hoverintent (no dependencies).
+       $scripts->add( 'hoverintent-js', "/wp-includes/js/hoverintent-js.min.js", array(), '2.2.1', 1 );
+
</ins><span class="cx" style="display: block; padding: 0 10px">         $scripts->add( 'customize-base', "/wp-includes/js/customize-base$suffix.js", array( 'jquery', 'json2', 'underscore' ), false, 1 );
</span><span class="cx" style="display: block; padding: 0 10px">        $scripts->add( 'customize-loader', "/wp-includes/js/customize-loader$suffix.js", array( 'customize-base' ), false, 1 );
</span><span class="cx" style="display: block; padding: 0 10px">        $scripts->add( 'customize-preview', "/wp-includes/js/customize-preview$suffix.js", array( 'wp-a11y', 'customize-base' ), false, 1 );
</span></span></pre>
</div>
</div>

</body>
</html>