summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Vobornik <pvoborni@redhat.com>2014-01-14 17:29:47 +0100
committerPetr Viktorin <pviktori@redhat.com>2014-03-05 09:59:13 +0100
commit9b540ef21864f8da822bd92d58385339147e773d (patch)
tree6d493f296300d668e65a8928a094eaa2da75f459
parentb50cdd55af8af7fdf30a822dce03af68969ddfe6 (diff)
downloadfreeipa-9b540ef21864f8da822bd92d58385339147e773d.tar.gz
freeipa-9b540ef21864f8da822bd92d58385339147e773d.tar.xz
freeipa-9b540ef21864f8da822bd92d58385339147e773d.zip
webui: Don't act on keyboard events which originated in different dialog
Fixes issue when: 1. 2 dialogs are opened 2. top dialog's close button is focused 3. user presses enter to execute 'close' action 4. dialog is immediately closed (enter key is still pressed) 5. second dialog automatically receives focus (it's top dialog now) 6. user releases the key 7. second dialog reacts to keyup event - which is by default confirmation mixin's confirm event 8. UNDESIRED behavior occurs Now confirmation mixin remembers which keys were pressed and released and reacts only to those which originated there. https://fedorahosted.org/freeipa/ticket/4098 Reviewed-By: Adam Misnyovszki <amisnyov@redhat.com>
-rw-r--r--install/ui/src/freeipa/dialog.js35
1 files changed, 33 insertions, 2 deletions
diff --git a/install/ui/src/freeipa/dialog.js b/install/ui/src/freeipa/dialog.js
index 0a8497b1c..f169b18f2 100644
--- a/install/ui/src/freeipa/dialog.js
+++ b/install/ui/src/freeipa/dialog.js
@@ -1246,7 +1246,16 @@ IPA.confirm_mixin = function() {
},
/**
+ * Map of keys which are down
+ * @property {Object}
+ */
+ keysdown: {},
+
+ /**
* Test if event is confirmation event
+ *
+ * Clears event's keyCode in `keysdown` map
+ *
* @param {Event} event
* @return {boolean}
*/
@@ -1254,9 +1263,11 @@ IPA.confirm_mixin = function() {
var ir = this.ignore_enter_rules,
t = event.target,
-
+ key = event.keyCode,
ignore = ir.src_elements.indexOf(t.tagName.toLowerCase()) > -1 ||
- ir.src_types.indexOf(t.type) > -1;
+ ir.src_types.indexOf(t.type) > -1 ||
+ !this.keysdown[key];
+ delete this.keysdown[key];
return ignore;
},
@@ -1267,8 +1278,10 @@ IPA.confirm_mixin = function() {
register_listeners: function() {
var self = this;
this._on_key_up_listener = function(e) { self.on_key_up(e); };
+ this._on_key_down_listener = function(e) { self._on_key_down(e); };
var dialog_container = this.dom_node;
dialog_container.bind('keyup', this._on_key_up_listener);
+ dialog_container.bind('keydown', this._on_key_down_listener);
},
/**
@@ -1277,6 +1290,7 @@ IPA.confirm_mixin = function() {
remove_listeners: function() {
var dialog_container = this.dom_node;
dialog_container.unbind('keyup', this._on_key_up_listener);
+ dialog_container.unbind('keydown', this._on_key_down_listener);
},
/**
@@ -1295,6 +1309,23 @@ IPA.confirm_mixin = function() {
event.preventDefault();
this.on_cancel();
}
+ delete this.keysdown[event.keyCode];
+ },
+
+ /**
+ * Internal listener for saving which keys were pressed to
+ * prevent reaction to event which originated in completely different
+ * control.
+ *
+ * Example: first dialog is closed by keydown event, second is
+ * therefore focused and consumes keyup event which can lead to undesired
+ * behavior.
+ *
+ * @private
+ * @param {Event} event
+ */
+ _on_key_down: function(event) {
+ this.keysdown[event.keyCode] = true;
}
},