From 68faee1fab4375138e07ccc5e47aa48032d39f1a Mon Sep 17 00:00:00 2001 From: Taka Date: Sun, 11 Oct 2020 05:53:09 +0000 Subject: [PATCH] Changed how we handle the Escape key. --- vasl_templates/webapp/static/lfa.js | 1 + vasl_templates/webapp/static/main.js | 48 ++++++++++++++++++----- vasl_templates/webapp/static/roar.js | 7 +--- vasl_templates/webapp/static/scenarios.js | 23 ++--------- vasl_templates/webapp/static/utils.js | 25 ++---------- vasl_templates/webapp/static/vassal.js | 2 +- vasl_templates/webapp/static/vo.js | 6 +-- 7 files changed, 53 insertions(+), 59 deletions(-) diff --git a/vasl_templates/webapp/static/lfa.js b/vasl_templates/webapp/static/lfa.js index 783f3dc..7c0a21d 100644 --- a/vasl_templates/webapp/static/lfa.js +++ b/vasl_templates/webapp/static/lfa.js @@ -136,6 +136,7 @@ window.show_lfa_dialog = function( resp ) dialogClass: "lfa", modal: true, resizable: false, + // NOTE: We handle ESCAPE ourself, handle_escape() has an exception for this dialog. closeOnEscape: false, create: function() { // initialize the splitter diff --git a/vasl_templates/webapp/static/main.js b/vasl_templates/webapp/static/main.js index 93d111d..0761a22 100644 --- a/vasl_templates/webapp/static/main.js +++ b/vasl_templates/webapp/static/main.js @@ -76,15 +76,6 @@ $(document).ready( function () { pos.left+$(this).width(), pos.top+$(this).height()+2, "fade", 200 ) ; } ) ; - // nb: we dismiss the popmenu and any notifications on ESCAPE - $(document).keydown( function(evt) { - if ( evt.keyCode == 27 ) { - $menu.popmenu( "hide" ) ; - $(".growl-close").each( function() { - $(this).trigger( "click" ) ; - } ) ; - } - } ) ; // add handlers $("#load-scenario").change( on_load_scenario_file_selected ) ; $("#load-template-pack").change( on_template_pack_file_selected ) ; @@ -380,8 +371,12 @@ $(document).ready( function () { } ) ; } ) ; - // initialize hotkeys + // initialize keyboard handlers init_hotkeys() ; + $(document).on( "keydown", function( evt ) { + if ( evt.keyCode == $.ui.keyCode.ESCAPE ) + handle_escape( evt ) ; + } ) ; // check for a dirty scenario before leaving the page if ( ! getUrlParam( "disable_close_window_check" ) ) { @@ -880,6 +875,39 @@ function adjust_footer_vspacers() // -------------------------------------------------------------------- +function handle_escape( evt ) +{ + // NOTE: Handling Escape is messy, since we could have a modal dialog that opened another modal dialog + // that opened an image gallery, etc. We add a global keydown handler for Escape and try to figure out + // what we should do here. The only requirement is that dialogs set "closeOnEscape". + + // NOTE: We ignore ESCAPE if an image gallery is on-screen (we let it handle it). + if ( $( ".lg-outer" ).length > 0 ) + return ; + + // always close the menu and any notifications + $("#menu input").popmenu( "hide" ) ; + $(".growl-close").each( function() { + $(this).trigger( "click" ) ; + } ) ; + + // find the top-most dialog (if any) and close it + var $topmost = null ; + $( ".ui-dialog" ).each( function() { + if ( $(this).css( "display" ) != "block" ) + return ; + if ( $topmost === null || $(this).css("z-index") > $topmost.css("z-index") ) + $topmost = $(this) ; + } ) ; + if ( $topmost ) { + var $dlg = $topmost.children( ".ui-dialog-content" ) ; + if ( ["ask","lfa","vassal-shim-progress"].indexOf( $dlg.attr("id") ) === -1 ) + $topmost.children( ".ui-dialog-content" ).dialog( "close" ) ; + } +} + +// -------------------------------------------------------------------- + function show_help() { // check if we need to load the HELP tab diff --git a/vasl_templates/webapp/static/roar.js b/vasl_templates/webapp/static/roar.js index bab3b46..01237eb 100644 --- a/vasl_templates/webapp/static/roar.js +++ b/vasl_templates/webapp/static/roar.js @@ -52,13 +52,14 @@ window.selectRoarScenario = function( onSelected ) title: "Connect scenario to ROAR", dialogClass: "select-roar-scenario", modal: true, + closeOnEscape: false, // nb: handled in handle_escape() minWidth: 400, minHeight: 350, create: function() { // initialize the dialog init_dialog( $(this), "OK", false ) ; loadScenarios( $sel, scenarios ) ; - // handle ENTER, ESCAPE and double-click + // handle ENTER and double-click function autoSelectScenario( evt ) { if ( $sel.val() ) { $( ".ui-dialog.select-roar-scenario button.ok" ).click() ; @@ -68,10 +69,6 @@ window.selectRoarScenario = function( onSelected ) $(this).keydown( function( evt ) { if ( evt.keyCode == $.ui.keyCode.ENTER ) autoSelectScenario( evt ) ; - else if ( evt.keyCode == $.ui.keyCode.ESCAPE ) { - $(this).dialog( "close" ) ; - stopEvent( evt ) ; - } } ).dblclick( function( evt ) { autoSelectScenario( evt ) ; } ) ; diff --git a/vasl_templates/webapp/static/scenarios.js b/vasl_templates/webapp/static/scenarios.js index 9a97450..548e15e 100644 --- a/vasl_templates/webapp/static/scenarios.js +++ b/vasl_templates/webapp/static/scenarios.js @@ -35,7 +35,7 @@ window.searchForScenario = function() title: "Search for scenarios", dialogClass: "scenario-search", modal: true, - closeOnEscape: false, + closeOnEscape: false, // nb: handled in handle_escape() width: $(window).width() * 0.8, minWidth: 750, height: $(window).height() * 0.8, @@ -52,11 +52,6 @@ window.searchForScenario = function() open: function() { // initialize $dlg = $(this) ; - eventHandlers.addHandler( $(document), "keydown", function( evt ) { - // FUDGE! Escape doesn't always close the dialog, we handle it ourself :-/ - if ( evt.keyCode == $.ui.keyCode.ESCAPE ) - close_dialog_if_no_others( $dlg ) ; - } ) ; // reset everything $gSearchQueryInputBox.val( "" ) ; $gDialog.find( ".select2-results__option" ).remove() ; @@ -996,7 +991,7 @@ function onDownloads() { width: 450, minWidth: 300, height: 200, minHeight: 150, draggable: false, - closeOnEscape: false, + closeOnEscape: false, // nb: handled in handle_escape() open: function() { $dlg = $(this) ; $dlg.parent().draggable() ; @@ -1011,13 +1006,6 @@ function onDownloads() { $( ".ui-dialog.scenario-downloads" ).position( { my: "right bottom", at: "right top-2", of: $parentDlg.find( "button.downloads" ) } ) ; - // add a keyboard handler for ESCAPE - eventHandlers.addHandler( $(document), "keydown", function( evt ) { - if ( evt.keyCode == $.ui.keyCode.ESCAPE ) { - $dlg.dialog( "close" ) ; - stopEvent( evt ) ; - } - } ) ; }, close: function() { // clean up @@ -1214,7 +1202,7 @@ window.showScenarioInfo = function() $( "#scenario-info-dialog" ).dialog( { dialogClass: "scenario-info", modal: true, - closeOnEscape: false, + closeOnEscape: false, // nb: handled in handle_escape() width: $(window).width() * 0.8, minWidth: 500, height: $(window).height() * 0.8, @@ -1252,10 +1240,7 @@ window.showScenarioInfo = function() // update the layout onResize() ; eventHandlers.addHandler( $(document), "keydown", function( evt ) { - // FUDGE! Escape doesn't always close the dialog, we handle it ourself :-/ - if ( evt.keyCode == $.ui.keyCode.ESCAPE ) { - close_dialog_if_no_others( $dlg ) ; - } else if ( evt.keyCode == 16 ) { // nb: checking evt.shiftKey is unreliable + if ( evt.keyCode == 16 ) { // nb: checking evt.shiftKey is unreliable window.getSelection().empty() ; $draggable.draggable( "disable" ) ; } diff --git a/vasl_templates/webapp/static/utils.js b/vasl_templates/webapp/static/utils.js index 0d2052d..84f4a5f 100644 --- a/vasl_templates/webapp/static/utils.js +++ b/vasl_templates/webapp/static/utils.js @@ -238,25 +238,6 @@ function click_dialog_button( $dlg, btn_text ) $( $dlg2.find( ".ui-dialog-buttonpane button:contains('" + btn_text + "')" ) ).click() ; } -function close_dialog_if_no_others( $dlg ) -{ - // NOTE: Escape doesn't always close a dialog, so we do it ourself, but we have to handle the case - // where more than one dialog is on-screen, and only close if there isn't another dialog on top of us. - var nDialogs = 0 ; - $( ".ui-dialog" ).each( function() { - if ( $(this).css( "display" ) !== "none" ) - ++ nDialogs ; - } ) ; - if ( nDialogs >= 2 ) - return ; - // NOTE: We also want to stop Escape from closing a dialog if an image preview is being shown. - if ( $( ".lg-outer" ).length > 0 ) - return ; - - // close the dialog - $dlg.dialog( "close" ) ; -} - // -------------------------------------------------------------------- function ask( title, msg, args ) @@ -267,7 +248,7 @@ function ask( title, msg, args ) $dlg.dialog( { dialogClass: "ask", modal: true, - closeOnEscape:false, + closeOnEscape: false, // nb: handle_escape() has a special case for this dialog title: title, width: args.width || 400, minWidth: 250, @@ -276,8 +257,10 @@ function ask( title, msg, args ) init_dialog( $(this), "OK", false ) ; // we handle ESCAPE ourself, to make it the same as clicking Cancel, not just closing the dialog $(this).closest( ".ui-dialog" ).keydown( function( evt ) { - if ( evt.keyCode == $.ui.keyCode.ESCAPE ) + if ( evt.keyCode == $.ui.keyCode.ESCAPE ) { $(".ui-dialog.ask button:contains(Cancel)").click() ; + stopEvent( evt ) ; + } } ) ; }, open: function() { diff --git a/vasl_templates/webapp/static/vassal.js b/vasl_templates/webapp/static/vassal.js index c0f2d9f..b87e814 100644 --- a/vasl_templates/webapp/static/vassal.js +++ b/vasl_templates/webapp/static/vassal.js @@ -549,7 +549,7 @@ function _show_vassal_shim_progress_dlg( caption, width ) width: width || 300, height: 60, resizable: false, - closeOnEscape: false, + closeOnEscape: false, // nb: handle_escape() has a special case to ignore this dialog open: function() { $(this).find( ".message" ).text( caption ) ; }, diff --git a/vasl_templates/webapp/static/vo.js b/vasl_templates/webapp/static/vo.js index b8b053f..b8880f4 100644 --- a/vasl_templates/webapp/static/vo.js +++ b/vasl_templates/webapp/static/vo.js @@ -77,12 +77,13 @@ function add_vo( vo_type, player_no ) var $dlg = $("#select-vo").dialog( { title: "Add " + SORTABLE_DISPLAY_NAMES["ob_"+vo_type][0], dialogClass: "select-vo", + closeOnEscape: false, // nb: this is handled by handle_escape() modal: true, minWidth: 400, minHeight: 350, create: function() { init_dialog( $(this), "OK", false ) ; - // handle ENTER, ESCAPE and double-click + // handle ENTER and double-click function auto_select_vo( evt ) { if ( $( "#select-vo select" ).val() ) { $( ".ui-dialog.select-vo button:contains('OK')" ).click() ; @@ -92,8 +93,6 @@ function add_vo( vo_type, player_no ) $(this).keydown( function(evt) { if ( evt.keyCode == $.ui.keyCode.ENTER ) auto_select_vo( evt ) ; - else if ( evt.keyCode == $.ui.keyCode.ESCAPE ) - $(this).dialog( "close" ) ; } ).dblclick( function(evt) { auto_select_vo( evt ) ; } ) ; @@ -389,6 +388,7 @@ function on_select_vo_image( $btn, on_ok ) { // show the dialog var $dlg = $("#select-vo-image").dialog( { dialogClass: "select-vo-image", + closeOnEscape: false, // nb: this is handled by handle_escape() modal: true, position: { my: "left top", at: "left-50 bottom+5", of: $btn, "collision": "fit" }, width: 1, height: 1, // nb: to avoid flicker; we set the size when the images have finished loading