diff options
author | Michael Kuhn <[email protected]> | 2019-04-07 12:21:52 +0200 |
---|---|---|
committer | Michael Kuhn <[email protected]> | 2019-04-13 22:34:57 +0200 |
commit | 4a2a90c980bb7436150ed82556fdb6f4db3ff138 (patch) | |
tree | f30bf3f5c20c58ccb0cddc5c2815ec4befd22c44 | |
parent | 7e55340295d7c3f7d1fded0c8d07700b908b57f2 (diff) |
Fix focus issues with hotkeys
Since making use of keypress in addition to keydown, hotkeys did not
work in certain scenarios, including clicking on the feed tree expanders
or empty spaces of the toolbar.
This issue is caused by dijit.Tree and dijit.Toolbar implementing the
_KeyNavMixin, which explicitly stops propagation of keypress events.
This change contains two main fixes plus a smaller hotfix:
1. It overrides _onContainerKeydown and _onContainerKeypress for
fox.FeedTree (which inherits from dijit.Tree).
2. It adds fox.Toolbar, which overrides _onContainerKeydown,
_onContainerKeypress and focus. This fixes hotkeys being swallowed
and the first focusable child receiving focus when clicking on an
empty space of the toolbar.
3. It adds the same handling of keydown and keypress to the prefs hotkey
handler as is done in the main hotkey handler.
-rwxr-xr-x | classes/pref/feeds.php | 6 | ||||
-rwxr-xr-x | classes/pref/filters.php | 10 | ||||
-rw-r--r-- | classes/pref/labels.php | 2 | ||||
-rw-r--r-- | classes/pref/prefs.php | 2 | ||||
-rw-r--r-- | classes/pref/users.php | 2 | ||||
-rw-r--r-- | index.php | 2 | ||||
-rwxr-xr-x | js/FeedTree.js | 5 | ||||
-rwxr-xr-x | js/Toolbar.js | 14 | ||||
-rwxr-xr-x | js/prefs.js | 7 | ||||
-rw-r--r-- | js/tt-rss.js | 5 |
10 files changed, 39 insertions, 16 deletions
diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index b90fd5848..bb854553d 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -1208,7 +1208,7 @@ class Pref_Feeds extends Handler_Protected { print '<div dojoType="dijit.layout.BorderContainer" gutters="false">'; - print "<div region='top' dojoType=\"dijit.Toolbar\">"; #toolbar + print "<div region='top' dojoType=\"fox.Toolbar\">"; #toolbar print "<div style='float : right; padding-right : 4px;'> <input dojoType=\"dijit.form.TextBox\" id=\"feed_search\" size=\"20\" type=\"search\" @@ -1449,7 +1449,7 @@ class Pref_Feeds extends Handler_Protected { ORDER BY last_article"); $sth->execute([$_SESSION['uid']]); - print "<div dojoType='dijit.Toolbar'>"; + print "<div dojoType='fox.Toolbar'>"; print "<div dojoType='dijit.form.DropDownButton'>". "<span>" . __('Select')."</span>"; print "<div dojoType='dijit.Menu' style='display: none'>"; @@ -1506,7 +1506,7 @@ class Pref_Feeds extends Handler_Protected { FROM ttrss_feeds WHERE last_error != '' AND owner_uid = ?"); $sth->execute([$_SESSION['uid']]); - print "<div dojoType=\"dijit.Toolbar\">"; + print "<div dojoType=\"fox.Toolbar\">"; print "<div dojoType=\"dijit.form.DropDownButton\">". "<span>" . __('Select')."</span>"; print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">"; diff --git a/classes/pref/filters.php b/classes/pref/filters.php index 37a7236ee..9663bfdd0 100755 --- a/classes/pref/filters.php +++ b/classes/pref/filters.php @@ -354,7 +354,7 @@ class Pref_Filters extends Handler_Protected { print "<header class='horizontal'>".__("Match")."</header>"; print "<section>"; - print "<div dojoType=\"dijit.Toolbar\">"; + print "<div dojoType=\"fox.Toolbar\">"; print "<div dojoType=\"dijit.form.DropDownButton\">". "<span>" . __('Select')."</span>"; @@ -414,7 +414,7 @@ class Pref_Filters extends Handler_Protected { print "<section>"; - print "<div dojoType=\"dijit.Toolbar\">"; + print "<div dojoType=\"fox.Toolbar\">"; print "<div dojoType=\"dijit.form.DropDownButton\">". "<span>" . __('Select')."</span>"; @@ -757,7 +757,7 @@ class Pref_Filters extends Handler_Protected { print "<div dojoType='dijit.layout.BorderContainer' gutters='false'>"; print "<div style='padding : 0px' dojoType='dijit.layout.ContentPane' region='top'>"; - print "<div dojoType='dijit.Toolbar'>"; + print "<div dojoType='fox.Toolbar'>"; if (array_key_exists("search", $_REQUEST)) { $_SESSION["prefs_filter_search"] = $filter_search; @@ -856,7 +856,7 @@ class Pref_Filters extends Handler_Protected { print "<header class='horizontal'>".__("Match")."</header >"; print "<section>"; - print "<div dojoType='dijit.Toolbar'>"; + print "<div dojoType='fox.Toolbar'>"; print "<div dojoType='dijit.form.DropDownButton'>". "<span>" . __('Select')."</span>"; @@ -885,7 +885,7 @@ class Pref_Filters extends Handler_Protected { print "<section>"; - print "<div dojoType='dijit.Toolbar'>"; + print "<div dojoType='fox.Toolbar'>"; print "<div dojoType='dijit.form.DropDownButton'>". "<span>" . __('Select')."</span>"; diff --git a/classes/pref/labels.php b/classes/pref/labels.php index 5dadddab4..90cb32214 100644 --- a/classes/pref/labels.php +++ b/classes/pref/labels.php @@ -251,7 +251,7 @@ class Pref_Labels extends Handler_Protected { print "<div dojoType='dijit.layout.BorderContainer' gutters='false'>"; print "<div style='padding : 0px' dojoType='dijit.layout.ContentPane' region='top'>"; - print "<div dojoType='dijit.Toolbar'>"; + print "<div dojoType='fox.Toolbar'>"; print "<div dojoType='dijit.form.DropDownButton'>". "<span>" . __('Select')."</span>"; diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php index d75b47f87..fbc7f000a 100644 --- a/classes/pref/prefs.php +++ b/classes/pref/prefs.php @@ -1021,7 +1021,7 @@ class Pref_Prefs extends Handler_Protected { } function editPrefProfiles() { - print "<div dojoType='dijit.Toolbar'>"; + print "<div dojoType='fox.Toolbar'>"; print "<div dojoType='dijit.form.DropDownButton'>". "<span>" . __('Select')."</span>"; diff --git a/classes/pref/users.php b/classes/pref/users.php index 7b75bb872..12be1207f 100644 --- a/classes/pref/users.php +++ b/classes/pref/users.php @@ -313,7 +313,7 @@ class Pref_Users extends Handler_Protected { print "<div dojoType='dijit.layout.BorderContainer' gutters='false'>"; print "<div style='padding : 0px' dojoType='dijit.layout.ContentPane' region='top'>"; - print "<div dojoType='dijit.Toolbar'>"; + print "<div dojoType='fox.Toolbar'>"; $user_search = trim(clean($_REQUEST["search"])); @@ -145,7 +145,7 @@ <div dojoType="dijit.layout.BorderContainer" region="center" id="content-wrap"> <div id="toolbar-frame" dojoType="dijit.layout.ContentPane" region="top"> - <div id="toolbar" dojoType="dijit.Toolbar"> + <div id="toolbar" dojoType="fox.Toolbar"> <i class="material-icons net-alert" style="display : none" title="<?php echo __("Communication problem with server.") ?>">error_outline</i> diff --git a/js/FeedTree.js b/js/FeedTree.js index 976848d28..99685a781 100755 --- a/js/FeedTree.js +++ b/js/FeedTree.js @@ -2,7 +2,10 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"], function (declare, domConstruct) { return declare("fox.FeedTree", dijit.Tree, { - _onKeyPress: function(/* Event */ e) { + _onContainerKeydown: function(/* Event */ e) { + return; // Stop dijit.Tree from interpreting keystrokes + }, + _onContainerKeypress: function(/* Event */ e) { return; // Stop dijit.Tree from interpreting keystrokes }, _createTreeNode: function(args) { diff --git a/js/Toolbar.js b/js/Toolbar.js new file mode 100755 index 000000000..6d2c20058 --- /dev/null +++ b/js/Toolbar.js @@ -0,0 +1,14 @@ +/* global dijit */ +define(["dojo/_base/declare", "dijit/Toolbar"], function (declare) { + return declare("fox.Toolbar", dijit.Toolbar, { + _onContainerKeydown: function(/* Event */ e) { + return; // Stop dijit.Toolbar from interpreting keystrokes + }, + _onContainerKeypress: function(/* Event */ e) { + return; // Stop dijit.Toolbar from interpreting keystrokes + }, + focus: function() { + return; // Stop dijit.Toolbar from focusing the first child on click + }, + }); +}); diff --git a/js/prefs.js b/js/prefs.js index ae6286330..69b7899ec 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -53,7 +53,8 @@ require(["dojo/_base/kernel", "fox/PrefFilterStore", "fox/PrefFeedTree", "fox/PrefFilterTree", - "fox/PrefLabelTree"], function (dojo, declare, ready, parser, AppBase) { + "fox/PrefLabelTree", + "fox/Toolbar"], function (dojo, declare, ready, parser, AppBase) { ready(function () { try { @@ -118,6 +119,10 @@ require(["dojo/_base/kernel", hotkeyHandler: function (event) { if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA") return; + // Arrow buttons and escape are not reported via keypress, handle them via keydown. + // escape = 27, left = 37, up = 38, right = 39, down = 40 + if (event.type == "keydown" && event.which != 27 && (event.which < 37 || event.which > 40)) return; + const action_name = App.keyeventToAction(event); if (action_name) { diff --git a/js/tt-rss.js b/js/tt-rss.js index eaedecd22..5db742f07 100644 --- a/js/tt-rss.js +++ b/js/tt-rss.js @@ -54,7 +54,8 @@ require(["dojo/_base/kernel", "fox/Headlines", "fox/Article", "fox/FeedStoreModel", - "fox/FeedTree"], function (dojo, declare, ready, parser, AppBase) { + "fox/FeedTree", + "fox/Toolbar"], function (dojo, declare, ready, parser, AppBase) { ready(function () { try { @@ -203,7 +204,7 @@ require(["dojo/_base/kernel", isCombinedMode: function() { return App.getInitParam("combined_display_mode"); }, - hotkeyHandler(event) { + hotkeyHandler: function(event) { if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA") return; // Arrow buttons and escape are not reported via keypress, handle them via keydown. |