@@ -919,9 +919,9 @@ function web_editor(config) {
919919 }
920920
921921 // Trap focus in modal and pass focus to first actionable element
922- function focusModal ( ) {
922+ function focusModal ( modalId ) {
923923 document . querySelector ( 'body > :not(.vex)' ) . setAttribute ( 'aria-hidden' , true ) ;
924- var dialog = document . querySelector ( '.modal-div' ) ;
924+ var dialog = document . querySelector ( modalId ) ;
925925 var focusableEls = dialog . querySelectorAll ( 'a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])' ) ;
926926 $ ( focusableEls ) . each ( function ( ) {
927927 $ ( this ) . attr ( 'tabindex' , '0' ) ;
@@ -930,10 +930,15 @@ function web_editor(config) {
930930 dialog . onkeydown = function ( event ) {
931931 if ( event . which == 9 ) {
932932 // if tab key is pressed
933- var focusedEl = document . activeElement ;
934933 var numberOfFocusableEls = focusableEls . length ;
935- var focusedElIndex = Array . prototype . indexOf . call ( focusableEls , focusedEl ) ;
934+ if ( ! numberOfFocusableEls ) {
935+ dialog . focus ( ) ;
936+ event . preventDefault ( ) ;
937+ return ;
938+ }
936939
940+ var focusedEl = document . activeElement ;
941+ var focusedElIndex = Array . prototype . indexOf . call ( focusableEls , focusedEl ) ;
937942 if ( event . which == 16 ) {
938943 // if focused on first item and user shift-tabs back, go to the last focusable item
939944 if ( focusedElIndex == 0 ) {
@@ -987,7 +992,7 @@ function web_editor(config) {
987992 vex . open ( {
988993 content : Mustache . render ( template , loadStrings ) ,
989994 afterOpen : function ( vexContent ) {
990- focusModal ( ) ;
995+ focusModal ( "#files-modal" ) ;
991996 $ ( "#show-files" ) . attr ( "title" , loadStrings [ "show-files" ] + " (" + micropythonFs . ls ( ) . length + ")" ) ;
992997 document . getElementById ( "show-files" ) . innerHTML = loadStrings [ "show-files" ] + " (" + micropythonFs . ls ( ) . length + ") <i class='fa fa-caret-down'>" ;
993998 $ ( '#save-hex' ) . click ( function ( ) {
@@ -1173,7 +1178,7 @@ function web_editor(config) {
11731178 vex . open ( {
11741179 content : Mustache . render ( template , context ) ,
11751180 afterOpen : function ( vexContent ) {
1176- focusModal ( ) ;
1181+ focusModal ( "#snippet-modal" ) ;
11771182 $ ( vexContent ) . find ( '.snippet-selection' ) . click ( function ( e ) {
11781183 var snippet_name = $ ( this ) . find ( '.snippet-name' ) . text ( ) ;
11791184 EDITOR . triggerSnippet ( snippet_name ) ;
@@ -1236,15 +1241,16 @@ function web_editor(config) {
12361241 loadPy ( file . name , e . target . result ) ;
12371242 } ;
12381243 reader . readAsText ( file ) ;
1244+ $ ( '#editor' ) . focus ( ) ;
12391245 } else if ( ext == 'hex' ) {
12401246 reader . onload = function ( e ) {
12411247 loadHex ( file . name , e . target . result ) ;
12421248 } ;
12431249 reader . readAsText ( file ) ;
1244- } else {
1250+ $ ( '#editor' ) . focus ( ) ;
1251+ } else {
12451252 invalidFileWarning ( ext ) ;
12461253 }
1247- $ ( '#editor' ) . focus ( ) ;
12481254 }
12491255
12501256 function showDisconnectError ( event ) {
@@ -1329,7 +1335,7 @@ function web_editor(config) {
13291335 $ ( "#flashing-info" ) . addClass ( 'hidden' ) ;
13301336
13311337 // Log error to console for feedback
1332- console . log ( "An error occured whilst attempting to use WebUSB." ) ;
1338+ console . log ( "An error occurred whilst attempting to use WebUSB." ) ;
13331339 console . log ( "Details of the error can be found below, and may be useful when trying to replicate and debug the error." ) ;
13341340 console . log ( err ) ;
13351341 console . trace ( ) ;
@@ -1347,7 +1353,7 @@ function web_editor(config) {
13471353
13481354 // Disconnect from the microbit
13491355 doDisconnect ( ) ;
1350-
1356+
13511357 var errorType ;
13521358 var errorTitle ;
13531359 var errorDescription ;
@@ -1450,6 +1456,15 @@ function web_editor(config) {
14501456 // Attach download handler
14511457 $ ( "#flashing-overlay-download" ) . click ( doDownload ) ;
14521458
1459+ // Make the modal accessible now that all the content is present
1460+ focusModal ( "#flashing-overlay" ) ;
1461+ // If escape key is pressed close modal
1462+ $ ( '#flashing-overlay' ) . keydown ( function ( e ) {
1463+ if ( e . which == 27 ) {
1464+ flashErrorClose ( ) ;
1465+ }
1466+ } ) ;
1467+
14531468 // Send event
14541469 var errorMessage = ( err . message ? ( err . message . replace ( / \W + / g, '-' ) . replace ( / \W $ / , '' ) . toLowerCase ( ) ) : "" ) ;
14551470 // Append error message, replace all special chars with '-', if last char is '-' remove it
@@ -1614,11 +1629,9 @@ function web_editor(config) {
16141629 document . dispatchEvent ( new CustomEvent ( 'webusb' , { detail : details } ) ) ;
16151630
16161631 console . log ( "Flash complete" ) ;
1617-
1632+
16181633 // Close overview
1619- setTimeout ( function ( ) {
1620- $ ( "#flashing-overlay-container" ) . hide ( ) ;
1621- } , 500 ) ;
1634+ setTimeout ( flashErrorClose , 500 ) ;
16221635 } )
16231636 . catch ( webusbErrorHandler )
16241637 . finally ( function ( ) {
@@ -1720,16 +1733,32 @@ function web_editor(config) {
17201733 $ ( "#modal-msg-title" ) . text ( title ) ;
17211734 $ ( "#modal-msg-content" ) . html ( content ) ;
17221735 var modalLinks = [ ] ;
1736+ var addCloseClickListener = false ;
17231737 if ( links ) {
17241738 Object . keys ( links ) . forEach ( function ( key ) {
17251739 if ( links [ key ] === "close" ) {
1726- modalLinks . push ( '<a href="#" onclick = "$(\'' + overlayContainer + '\').hide()">Close</a>' ) ;
1740+ modalLinks . push ( '<a href="#" id="modal-msg-close-link">' + key + '</a>' ) ;
1741+ addCloseClickListener = true ;
17271742 } else {
17281743 modalLinks . push ( '<a href="' + links [ key ] + '" target="_blank">' + key + '</a>' ) ;
17291744 }
17301745 } ) ;
17311746 }
17321747 $ ( "#modal-msg-links" ) . html ( ( modalLinks ) . join ( ' | ' ) ) ;
1748+ focusModal ( "#modal-msg-overlay" ) ;
1749+ var modalMsgClose = function ( ) {
1750+ $ ( overlayContainer ) . hide ( )
1751+ $ ( overlayContainer ) . off ( "keydown" ) ;
1752+ } ;
1753+ $ ( "#modal-msg-close-cross" ) . click ( modalMsgClose ) ;
1754+ if ( addCloseClickListener ) {
1755+ $ ( "#modal-msg-close-link" ) . click ( modalMsgClose ) ;
1756+ }
1757+ $ ( overlayContainer ) . keydown ( function ( e ) {
1758+ if ( e . which == 27 ) {
1759+ modalMsgClose ( ) ;
1760+ }
1761+ } ) ;
17331762 }
17341763
17351764 function formatMenuContainer ( parentButtonId , containerId ) {
@@ -1941,4 +1970,5 @@ function web_editor(config) {
19411970function flashErrorClose ( ) {
19421971 $ ( '#flashing-overlay-error' ) . html ( "" ) ;
19431972 $ ( '#flashing-overlay-container' ) . hide ( ) ;
1973+ $ ( '#flashing-overlay' ) . off ( "keydown" ) ;
19441974}
0 commit comments