@@ -693,10 +693,11 @@ function setupMobileSidebarKeyboardHandlers() {
693
693
}
694
694
695
695
/**
696
- * When the page loads or the window resizes check code blocks and Jupyter
697
- * notebook outputs, and if they have scrollable overflow, set tabIndex = 0.
696
+ * When the page loads, or the window resizes, or descendant nodes are added or
697
+ * removed from the main element, check all code blocks and Jupyter notebook
698
+ * outputs, and for each one that has scrollable overflow, set tabIndex = 0.
698
699
*/
699
- function setupLiteralBlockTabStops ( ) {
700
+ function addTabStopsToScrollableElements ( ) {
700
701
const updateTabStops = ( ) => {
701
702
document
702
703
. querySelectorAll (
@@ -712,7 +713,25 @@ function setupLiteralBlockTabStops() {
712
713
: - 1 ;
713
714
} ) ;
714
715
} ;
715
- window . addEventListener ( "resize" , debounce ( updateTabStops , 300 ) ) ;
716
+ const debouncedUpdateTabStops = debounce ( updateTabStops , 300 ) ;
717
+
718
+ // On window resize
719
+ window . addEventListener ( "resize" , debouncedUpdateTabStops ) ;
720
+
721
+ // The following MutationObserver is for ipywidgets, which take some time to
722
+ // finish loading and rendering on the page (so even after the "load" event is
723
+ // fired, they still have not finished rendering). Would be nice to replace
724
+ // the MutationObserver if there is a way to hook into the ipywidgets code to
725
+ // know when it is done.
726
+ const mainObserver = new MutationObserver ( debouncedUpdateTabStops ) ;
727
+
728
+ // On descendant nodes added/removed from main element
729
+ mainObserver . observe ( document . getElementById ( "main-content" ) , {
730
+ subtree : true ,
731
+ childList : true ,
732
+ } ) ;
733
+
734
+ // On page load
716
735
updateTabStops ( ) ;
717
736
}
718
737
function debounce ( callback , wait ) {
@@ -736,4 +755,7 @@ documentReady(setupSearchButtons);
736
755
documentReady ( initRTDObserver ) ;
737
756
documentReady ( setupMobileSidebarKeyboardHandlers ) ;
738
757
documentReady ( fixMoreLinksInMobileSidebar ) ;
739
- documentReady ( setupLiteralBlockTabStops ) ;
758
+
759
+ // Use load event because determining whether an element has scrollable content
760
+ // depends on stylesheets (which come after DOMContentLoaded)
761
+ window . addEventListener ( "load" , addTabStopsToScrollableElements ) ;
0 commit comments