11define ( 'navbar' ,
2- [ 'capabilities' , 'categories' , 'jquery' , 'log' , 'navigation' , 'nunjucks' ,
3- 'settings' , 'underscore' , 'user' , 'z' ] ,
4- function ( capabilities , cats , $ , log , navigation , nunjucks , settings , _ ,
5- user , z ) {
2+ [ 'categories' , 'jquery' , 'log' , 'navigation' , 'nunjucks' , 'settings' ,
3+ 'underscore' , 'urls' , 'user' , 'z' ] ,
4+ function ( cats , $ , log , navigation , nunjucks , settings , _ , urls , user , z ) {
65 'use strict' ;
76 var logger = log ( 'navbar' ) ;
87
8+ var DESKTOP_WIDTH = 710 ;
9+ var NAV_MKT_BASE_OFFSET = - 65 ;
10+ var NAV_SETTINGS_BASE_OFFSET = 0 ;
911 var NAV_LINK_VISIBLE_WIDTH = 50 ;
1012
1113 function initNavbarButtons ( ) {
1214 // Navbar settings + Marketplace buttons.
13- var $navContainer = $ ( '.navbar-container' ) ;
1415 var $mktNav = $ ( '.nav-mkt' ) ;
1516 var $settingsNav = $ ( '.nav-settings' ) ;
1617 var $mktNavGroup = $mktNav . add ( '.act-tray-mobile' ) ;
@@ -19,15 +20,14 @@ define('navbar',
1920 function toggleNavbar ( $on , $off ) {
2021 $on . addClass ( 'active' ) ;
2122 $off . removeClass ( 'active' ) ;
22- $navContainer [ 0 ] . scrollLeft = 0 ;
2323 }
2424
2525 function fitNavbarOnSwitch ( $navbar , $item ) {
2626 // Switching between navbars makes it difficult to do initial
2727 // line-fitting since the navbar is in a transitioning state. So
2828 // we do a timeout. But for navbars that have already been fitted,
2929 // don't do a timeout delay.
30- var waitForTransition = 200 ;
30+ var waitForTransition = 500 ;
3131 if ( $navbar . data ( 'fitted' ) ) {
3232 waitForTransition = 0 ;
3333 }
@@ -41,6 +41,7 @@ define('navbar',
4141 z . body . on ( 'click' , '.act-tray-mobile' , function ( e ) {
4242 // Activate Settings page navbar.
4343 e . preventDefault ( ) ;
44+ $mktNav . css ( 'right' , '' ) ; // Reset the offset for transition effect.
4445 toggleNavbar ( $settingsNavGroup , $mktNavGroup ) ;
4546
4647 var $firstLink = $settingsNavGroup . find ( '[data-tab]:first-child a' ) ;
@@ -52,6 +53,7 @@ define('navbar',
5253 . on ( 'click' , '.mkt-tray' , function ( e ) {
5354 // Activate Marketplace pages navbar.
5455 e . preventDefault ( ) ;
56+ $ ( '.nav-settings' ) . css ( 'right' , '' ) ; // Reset the offset for transition effect.
5557 toggleNavbar ( $mktNavGroup , $settingsNavGroup ) ;
5658
5759 var $firstLink = $mktNavGroup . find ( '[data-tab]:first-child a' ) ;
@@ -63,23 +65,77 @@ define('navbar',
6365 . on ( 'click' , '.site a' , function ( ) {
6466 // Activate Marketplace pages navbar.
6567 toggleNavbar ( $mktNavGroup , $settingsNavGroup ) ;
66- } )
67- . on ( 'click' , '.tab-link' , function ( e ) {
68- if ( capabilities . widescreen ( ) ) {
69- return ;
70- }
71-
72- // Jump to the beginning when user clicks on the first link.
73- if ( $ ( this ) . closest ( '.tab-item' ) . is ( ':first-child' ) ) {
74- $navContainer [ 0 ] . scrollLeft = 0 ;
75- } else {
76- $navContainer [ 0 ] . scrollLeft = this . getBoundingClientRect ( ) . left ;
77- }
78- this . blur ( ) ;
7968 } ) ;
8069 }
8170 z . body . one ( 'loaded' , initNavbarButtons ) ;
8271
72+ z . body . on ( 'click' , '.navbar li > a' , function ( ) {
73+ var $this = $ ( this ) ;
74+ if ( $this . hasClass ( 'desktop-cat-link' ) ) {
75+ // Don't allow click of category tab on desktop.
76+ return ;
77+ }
78+
79+ calcNavbarOffset ( $this . closest ( 'li' ) ) ;
80+ } ) ;
81+
82+ function calcNavbarOffset ( $item ) {
83+ // Calculate appropriate offsets for the navbar so that it slides well
84+ // for any language. Good luck understanding what's going on.
85+ var $navbar = $item . closest ( '.navbar' ) ;
86+ if ( ! $navbar . length ) {
87+ return ;
88+ }
89+
90+ var currentNavbarOffset = $navbar . offset ( ) . left * - 1 ;
91+ var padding = 10 ;
92+ var right = currentNavbarOffset ;
93+ var rightEdgeOffset = $item . offset ( ) . left + $item . width ( ) ;
94+
95+ var baseOffset = NAV_MKT_BASE_OFFSET ;
96+ var windowWidth = z . win . width ( ) ;
97+ if ( $navbar . hasClass ( 'nav-settings' ) ) {
98+ baseOffset = NAV_SETTINGS_BASE_OFFSET ;
99+ windowWidth -= $ ( '.mkt-tray' ) . width ( ) ;
100+ }
101+
102+ if ( rightEdgeOffset > windowWidth ) {
103+ // Sliding forwards.
104+ // If the link is overflowing off the right edge of the page,
105+ // slide the navbar enough so the link is fully visible.
106+ right = ( currentNavbarOffset +
107+ ( rightEdgeOffset - windowWidth ) + padding ) ;
108+
109+ // If there is another link after the current link, move the navbar
110+ // some more such that the next link is clickable (50px target).
111+ if ( $item . next ( ) . length ) {
112+ right += NAV_LINK_VISIBLE_WIDTH ;
113+ }
114+ } else if ( currentNavbarOffset !== NAV_MKT_BASE_OFFSET ) {
115+ // Sliding backwards.
116+ // If the next link to the one clicked is in full view, slide it
117+ // so it becomes visible by only 50px and thus clickable.
118+ var $next = $item . next ( ) ;
119+ if ( $next . length ) {
120+ var nextLeftEdgeOffset = $next . offset ( ) . left ;
121+ var nextRightEdgeOffset = nextLeftEdgeOffset + $next . width ( ) ;
122+ if ( nextRightEdgeOffset < windowWidth ) {
123+ right = ( currentNavbarOffset -
124+ ( windowWidth + NAV_LINK_VISIBLE_WIDTH - nextRightEdgeOffset ) +
125+ padding ) ;
126+ }
127+ }
128+ }
129+
130+ if ( right < baseOffset ) {
131+ // Don't scroll past the base starting point.
132+ right = baseOffset ;
133+ }
134+
135+ $item . closest ( '.navbar' ) . css ( 'right' , right + 'px' ) ;
136+ return right ;
137+ }
138+
83139 function linefitNavbarMobile ( $navbar ) {
84140 // Linefits the navbar on mobile such that the nav element flowing
85141 // off the screen is clickable by 50px.
@@ -127,17 +183,20 @@ define('navbar',
127183 }
128184
129185 function fitNavbarMobile ( $item ) {
130- // Does line-fitting for the navbar.
186+ // Does both line-fitting and offset calculations for the navbar.
187+ // Note that line-fitting must be done first since the offset affects
188+ // its calculations.
131189 linefitNavbarMobile ( $item . closest ( '.navbar' ) ) ;
190+ calcNavbarOffset ( $item ) ;
132191 }
133192
134193 function fitNavbarDesktop ( ) {
135194 // Shrinks the font-size and padding of the nav elements until it
136195 // all fits within the window.
137- if ( ! capabilities . widescreen ( ) ) {
196+ var windowWidth = z . win . width ( ) ;
197+ if ( windowWidth < DESKTOP_WIDTH ) {
138198 return ;
139199 }
140- var windowWidth = z . win . width ( ) ;
141200 var $navbar = $ ( '.nav-mkt' ) ;
142201 var $navbarItems = $navbar . find ( 'li' ) ;
143202 var navbarWidth = $navbar . width ( ) ;
0 commit comments