@@ -876,7 +876,7 @@ function web_editor(config) {
876
876
$ ( '.fs-file-list table tbody' ) . append (
877
877
'<tr><td>' + name + '</td>' +
878
878
'<td>' + ( micropythonFs . size ( filename ) / 1024 ) . toFixed ( 2 ) + ' Kb</td>' +
879
- '<td><button id="' + pseudoUniqueId + '_remove" class="action save-button remove ' + disabled + '" title=' + loadStrings [ "remove-but" ] + '><i class="fa fa-trash"></i></button>' +
879
+ '<td><button id="' + pseudoUniqueId + '_remove" class="action save-button remove ' + disabled + '" title=' + loadStrings [ "remove-but" ] + ' ' + disabled + '><i class="fa fa-trash"></i></button>' +
880
880
'<button id="' + pseudoUniqueId + '_save" class="action save-button save" title=' + loadStrings [ "save-but" ] + '><i class="fa fa-download"></i></button></td></tr>'
881
881
) ;
882
882
$ ( '#' + pseudoUniqueId + '_save' ) . click ( function ( e ) {
@@ -918,6 +918,39 @@ function web_editor(config) {
918
918
return fullHex ;
919
919
}
920
920
921
+ // Trap focus in modal and pass focus to first actionable element
922
+ function focusModal ( ) {
923
+ document . querySelector ( 'body > :not(.vex)' ) . setAttribute ( 'aria-hidden' , true ) ;
924
+ var dialog = document . querySelector ( '.modal-div' ) ;
925
+ 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])' ) ;
926
+ $ ( focusableEls ) . each ( function ( ) {
927
+ $ ( this ) . attr ( 'tabindex' , '0' ) ;
928
+ } ) ;
929
+ dialog . focus ( ) ;
930
+ dialog . onkeydown = function ( event ) {
931
+ if ( event . which == 9 ) {
932
+ // if tab key is pressed
933
+ var focusedEl = document . activeElement ;
934
+ var numberOfFocusableEls = focusableEls . length ;
935
+ var focusedElIndex = Array . prototype . indexOf . call ( focusableEls , focusedEl ) ;
936
+
937
+ if ( event . which == 16 ) {
938
+ // if focused on first item and user shift-tabs back, go to the last focusable item
939
+ if ( focusedElIndex == 0 ) {
940
+ focusableEls . item ( numberOfFocusableEls - 1 ) . focus ( ) ;
941
+ event . preventDefault ( ) ;
942
+ }
943
+ } else {
944
+ // if focused on the last item and user tabs forward, go to the first focusable item
945
+ if ( focusedElIndex == numberOfFocusableEls - 1 ) {
946
+ focusableEls [ 0 ] . focus ( ) ;
947
+ event . preventDefault ( ) ;
948
+ }
949
+ }
950
+ }
951
+ } ;
952
+ }
953
+
921
954
// This function describes what to do when the download button is clicked.
922
955
function doDownload ( ) {
923
956
try {
@@ -945,7 +978,6 @@ function web_editor(config) {
945
978
modalMsg ( config [ 'translate' ] [ 'load' ] [ 'invalid-file-title' ] , config [ 'translate' ] [ 'load' ] [ 'extension-warning' ] , "" ) ;
946
979
}
947
980
}
948
-
949
981
// Describes what to do when the save/load button is clicked.
950
982
function doFiles ( ) {
951
983
var template = $ ( '#files-template' ) . html ( ) ;
@@ -955,6 +987,7 @@ function web_editor(config) {
955
987
vex . open ( {
956
988
content : Mustache . render ( template , loadStrings ) ,
957
989
afterOpen : function ( vexContent ) {
990
+ focusModal ( ) ;
958
991
$ ( "#show-files" ) . attr ( "title" , loadStrings [ "show-files" ] + " (" + micropythonFs . ls ( ) . length + ")" ) ;
959
992
document . getElementById ( "show-files" ) . innerHTML = loadStrings [ "show-files" ] + " (" + micropythonFs . ls ( ) . length + ") <i class='fa fa-caret-down'>" ;
960
993
$ ( '#save-hex' ) . click ( function ( ) {
@@ -968,12 +1001,14 @@ function web_editor(config) {
968
1001
}
969
1002
downloadFileFromFilesystem ( 'main.py' ) ;
970
1003
} ) ;
971
- $ ( "#files-expand-help " ) . click ( function ( ) {
1004
+ $ ( "#expandHelpPara " ) . click ( function ( ) {
972
1005
if ( $ ( "#fileHelpPara" ) . css ( "display" ) == "none" ) {
973
1006
$ ( "#fileHelpPara" ) . show ( ) ;
1007
+ $ ( "#expandHelpPara" ) . attr ( "aria-expanded" , "true" ) ;
974
1008
$ ( "#addFile" ) . css ( "margin-bottom" , "10px" ) ;
975
1009
} else {
976
1010
$ ( "#fileHelpPara" ) . hide ( ) ;
1011
+ $ ( "#expandHelpPara" ) . attr ( "aria-expanded" , "false" ) ;
977
1012
$ ( "#addFile" ) . css ( "margin-bottom" , "22px" ) ;
978
1013
}
979
1014
} ) ;
@@ -982,11 +1017,13 @@ function web_editor(config) {
982
1017
if ( content . style . maxHeight ) {
983
1018
content . style . maxHeight = null ;
984
1019
$ ( "#hide-files" ) . attr ( "id" , "show-files" ) ;
1020
+ $ ( "#show-files" ) . attr ( "aria-expanded" , "false" ) ;
985
1021
$ ( "#show-files" ) . attr ( "title" , loadStrings [ "show-files" ] + " (" + micropythonFs . ls ( ) . length + ")" ) ;
986
1022
document . getElementById ( "show-files" ) . innerHTML = loadStrings [ "show-files" ] + " (" + micropythonFs . ls ( ) . length + ") <i class='fa fa-caret-down'>" ;
987
1023
} else {
988
1024
content . style . maxHeight = content . scrollHeight + "px" ;
989
1025
$ ( "#show-files" ) . attr ( "id" , "hide-files" ) ;
1026
+ $ ( "#hide-files" ) . attr ( "aria-expanded" , "true" ) ;
990
1027
$ ( "#hide-files" ) . attr ( "title" , loadStrings [ "hide-files" ] ) ;
991
1028
document . getElementById ( "hide-files" ) . innerHTML = loadStrings [ "hide-files" ] + " <i class='fa fa-caret-up'>" ;
992
1029
}
@@ -1136,6 +1173,7 @@ function web_editor(config) {
1136
1173
vex . open ( {
1137
1174
content : Mustache . render ( template , context ) ,
1138
1175
afterOpen : function ( vexContent ) {
1176
+ focusModal ( ) ;
1139
1177
$ ( vexContent ) . find ( '.snippet-selection' ) . click ( function ( e ) {
1140
1178
var snippet_name = $ ( this ) . find ( '.snippet-name' ) . text ( ) ;
1141
1179
EDITOR . triggerSnippet ( snippet_name ) ;
@@ -1680,7 +1718,7 @@ function web_editor(config) {
1680
1718
var overlayContainer = "#modal-msg-overlay-container" ;
1681
1719
$ ( overlayContainer ) . css ( "display" , "block" ) ;
1682
1720
$ ( "#modal-msg-title" ) . text ( title ) ;
1683
- $ ( "#modal-msg-content" ) . html ( content ) ;
1721
+ $ ( "#modal-msg-content" ) . html ( content ) ;
1684
1722
var modalLinks = [ ] ;
1685
1723
if ( links ) {
1686
1724
Object . keys ( links ) . forEach ( function ( key ) {
0 commit comments