@@ -515,17 +515,39 @@ aria-label="Show hidden lines"></button>';
515515} ) ( ) ;
516516
517517( function sidebar ( ) {
518- const body = document . querySelector ( 'body' ) ;
519518 const sidebar = document . getElementById ( 'sidebar' ) ;
520519 const sidebarLinks = document . querySelectorAll ( '#sidebar a' ) ;
521520 const sidebarToggleButton = document . getElementById ( 'sidebar-toggle' ) ;
522- const sidebarToggleAnchor = document . getElementById ( 'sidebar-toggle-anchor' ) ;
523521 const sidebarResizeHandle = document . getElementById ( 'sidebar-resize-handle' ) ;
522+ const sidebarCheckbox = document . getElementById ( 'sidebar-toggle-anchor' ) ;
524523 let firstContact = null ;
525524
525+
526+ /* Because we cannot change the `display` using only CSS after/before the transition, we
527+ need JS to do it. We change the display to prevent the browsers search to find text inside
528+ the collapsed sidebar. */
529+ if ( ! document . documentElement . classList . contains ( 'sidebar-visible' ) ) {
530+ sidebar . style . display = 'none' ;
531+ }
532+ sidebar . addEventListener ( 'transitionend' , ( ) => {
533+ /* We only change the display to "none" if we're collapsing the sidebar. */
534+ if ( ! sidebarCheckbox . checked ) {
535+ sidebar . style . display = 'none' ;
536+ }
537+ } ) ;
538+ sidebarToggleButton . addEventListener ( 'click' , ( ) => {
539+ /* To allow the sidebar expansion animation, we first need to put back the display. */
540+ if ( ! sidebarCheckbox . checked ) {
541+ sidebar . style . display = '' ;
542+ // Workaround for Safari skipping the animation when changing
543+ // `display` and a transform in the same event loop. This forces a
544+ // reflow after updating the display.
545+ sidebar . offsetHeight ;
546+ }
547+ } ) ;
548+
526549 function showSidebar ( ) {
527- body . classList . remove ( 'sidebar-hidden' ) ;
528- body . classList . add ( 'sidebar-visible' ) ;
550+ document . documentElement . classList . add ( 'sidebar-visible' ) ;
529551 Array . from ( sidebarLinks ) . forEach ( function ( link ) {
530552 link . setAttribute ( 'tabIndex' , 0 ) ;
531553 } ) ;
@@ -539,8 +561,7 @@ aria-label="Show hidden lines"></button>';
539561 }
540562
541563 function hideSidebar ( ) {
542- body . classList . remove ( 'sidebar-visible' ) ;
543- body . classList . add ( 'sidebar-hidden' ) ;
564+ document . documentElement . classList . remove ( 'sidebar-visible' ) ;
544565 Array . from ( sidebarLinks ) . forEach ( function ( link ) {
545566 link . setAttribute ( 'tabIndex' , - 1 ) ;
546567 } ) ;
@@ -554,8 +575,8 @@ aria-label="Show hidden lines"></button>';
554575 }
555576
556577 // Toggle sidebar
557- sidebarToggleAnchor . addEventListener ( 'change' , function sidebarToggle ( ) {
558- if ( sidebarToggleAnchor . checked ) {
578+ sidebarCheckbox . addEventListener ( 'change' , function sidebarToggle ( ) {
579+ if ( sidebarCheckbox . checked ) {
559580 const current_width = parseInt (
560581 document . documentElement . style . getPropertyValue ( '--sidebar-target-width' ) , 10 ) ;
561582 if ( current_width < 150 ) {
@@ -572,14 +593,14 @@ aria-label="Show hidden lines"></button>';
572593 function initResize ( ) {
573594 window . addEventListener ( 'mousemove' , resize , false ) ;
574595 window . addEventListener ( 'mouseup' , stopResize , false ) ;
575- body . classList . add ( 'sidebar-resizing' ) ;
596+ document . documentElement . classList . add ( 'sidebar-resizing' ) ;
576597 }
577598 function resize ( e ) {
578599 let pos = e . clientX - sidebar . offsetLeft ;
579600 if ( pos < 20 ) {
580601 hideSidebar ( ) ;
581602 } else {
582- if ( body . classList . contains ( 'sidebar-hidden ' ) ) {
603+ if ( ! document . documentElement . classList . contains ( 'sidebar-visible ' ) ) {
583604 showSidebar ( ) ;
584605 }
585606 pos = Math . min ( pos , window . innerWidth - 100 ) ;
@@ -588,7 +609,7 @@ aria-label="Show hidden lines"></button>';
588609 }
589610 //on mouseup remove windows functions mousemove & mouseup
590611 function stopResize ( ) {
591- body . classList . remove ( 'sidebar-resizing' ) ;
612+ document . documentElement . classList . remove ( 'sidebar-resizing' ) ;
592613 window . removeEventListener ( 'mousemove' , resize , false ) ;
593614 window . removeEventListener ( 'mouseup' , stopResize , false ) ;
594615 }
@@ -623,7 +644,7 @@ aria-label="Show hidden lines"></button>';
623644
624645( function chapterNavigation ( ) {
625646 document . addEventListener ( 'keydown' , function ( e ) {
626- if ( e . altKey || e . ctrlKey || e . metaKey || e . shiftKey ) {
647+ if ( e . altKey || e . ctrlKey || e . metaKey ) {
627648 return ;
628649 }
629650 if ( window . search && window . search . hasFocus ( ) ) {
@@ -643,6 +664,55 @@ aria-label="Show hidden lines"></button>';
643664 window . location . href = previousButton . href ;
644665 }
645666 }
667+ function showHelp ( ) {
668+ const container = document . getElementById ( 'mdbook-help-container' ) ;
669+ const overlay = document . getElementById ( 'mdbook-help-popup' ) ;
670+ container . style . display = 'flex' ;
671+
672+ // Clicking outside the popup will dismiss it.
673+ const mouseHandler = event => {
674+ if ( overlay . contains ( event . target ) ) {
675+ return ;
676+ }
677+ if ( event . button !== 0 ) {
678+ return ;
679+ }
680+ event . preventDefault ( ) ;
681+ event . stopPropagation ( ) ;
682+ document . removeEventListener ( 'mousedown' , mouseHandler ) ;
683+ hideHelp ( ) ;
684+ } ;
685+
686+ // Pressing esc will dismiss the popup.
687+ const escapeKeyHandler = event => {
688+ if ( event . key === 'Escape' ) {
689+ event . preventDefault ( ) ;
690+ event . stopPropagation ( ) ;
691+ document . removeEventListener ( 'keydown' , escapeKeyHandler , true ) ;
692+ hideHelp ( ) ;
693+ }
694+ } ;
695+ document . addEventListener ( 'keydown' , escapeKeyHandler , true ) ;
696+ document . getElementById ( 'mdbook-help-container' )
697+ . addEventListener ( 'mousedown' , mouseHandler ) ;
698+ }
699+ function hideHelp ( ) {
700+ document . getElementById ( 'mdbook-help-container' ) . style . display = 'none' ;
701+ }
702+
703+ // Usually needs the Shift key to be pressed
704+ switch ( e . key ) {
705+ case '?' :
706+ e . preventDefault ( ) ;
707+ showHelp ( ) ;
708+ break ;
709+ }
710+
711+ // Rest of the keys are only active when the Shift key is not pressed
712+ if ( e . shiftKey ) {
713+ return ;
714+ }
715+
646716 switch ( e . key ) {
647717 case 'ArrowRight' :
648718 e . preventDefault ( ) ;
@@ -716,7 +786,7 @@ aria-label="Show hidden lines"></button>';
716786 let scrollTop = document . scrollingElement . scrollTop ;
717787 let prevScrollTop = scrollTop ;
718788 const minMenuY = - menu . clientHeight - 50 ;
719- // When the script loads, the page can be at any scroll (e.g. if you reforesh it).
789+ // When the script loads, the page can be at any scroll (e.g. if you refresh it).
720790 menu . style . top = scrollTop + 'px' ;
721791 // Same as parseInt(menu.style.top.slice(0, -2), but faster
722792 let topCache = menu . style . top . slice ( 0 , - 2 ) ;
0 commit comments