Fix button focus issues

This change introduces derived classes for ComboButton, DropDownButton
and Select that make sure that buttons do not remain focused after their
menus are closed. This allows using hotkeys after closing them.
This commit is contained in:
Michael Kuhn 2019-04-13 22:36:15 +02:00
parent 4a2a90c980
commit e38fcd6dea
13 changed files with 82 additions and 44 deletions

View File

@ -516,7 +516,7 @@ class Article extends Handler_Protected {
$rv .= "<br clear='both'/>";
}
$rv .= "<div class=\"attachments\" dojoType=\"dijit.form.DropDownButton\">".
$rv .= "<div class=\"attachments\" dojoType=\"fox.form.DropDownButton\">".
"<span>" . __('Attachments')."</span>";
$rv .= "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";

View File

@ -54,7 +54,7 @@ class Feeds extends Handler_Protected {
$reply .= "<span class=\"right\">";
$reply .= "<span id='selected_prompt'></span>";
$reply .= "&nbsp;";
$reply .= "<select dojoType=\"dijit.form.Select\"
$reply .= "<select dojoType=\"fox.form.Select\"
onchange=\"Headlines.onActionChanged(this)\">";
$reply .= "<option value=\"0\" disabled='1'>".__('Select...')."</option>";
@ -659,7 +659,7 @@ class Feeds extends Handler_Protected {
if (get_pref('ENABLE_FEED_CATS')) {
print "<label class='inline'>" . __('Place in category:') . "</label> ";
print_feed_cat_select("cat", false, 'dojoType="dijit.form.Select"');
print_feed_cat_select("cat", false, 'dojoType="fox.form.Select"');
}
print "</fieldset>";
@ -671,7 +671,7 @@ class Feeds extends Handler_Protected {
<section>
<fieldset>
<select id="feedDlg_feedContainerSelect"
dojoType="dijit.form.Select" size="3">
dojoType="fox.form.Select" size="3">
<script type="dojo/method" event="onChange" args="value">
dijit.byId("feedDlg_feedUrl").attr("value", value);
</script>
@ -734,7 +734,7 @@ class Feeds extends Handler_Protected {
print "<fieldset>";
print "<label class='inline'>" . __("Language:") . "</label>";
print_select("search_language", get_pref('DEFAULT_SEARCH_LANGUAGE'), Pref_Feeds::get_ts_languages(),
"dojoType='dijit.form.Select' title=\"".__('Used for word stemming')."\"");
"dojoType='fox.form.Select' title=\"".__('Used for word stemming')."\"");
print "</fieldset>";
}

View File

@ -571,7 +571,7 @@ class Pref_Feeds extends Handler_Protected {
print "<label>" . __('Place in category:') . "</label> ";
print_feed_cat_select("cat_id", $cat_id,
'dojoType="dijit.form.Select"');
'dojoType="fox.form.Select"');
print "</fieldset>";
}
@ -602,7 +602,7 @@ class Pref_Feeds extends Handler_Protected {
print "<label>" . __('Language:') . "</label> ";
print_select("feed_language", $feed_language, $this::get_ts_languages(),
'dojoType="dijit.form.Select"');
'dojoType="fox.form.Select"');
print "</fieldset>";
}
@ -621,7 +621,7 @@ class Pref_Feeds extends Handler_Protected {
print "<label>".__("Interval:")."</label> ";
print_select_hash("update_interval", $update_interval, $update_intervals,
'dojoType="dijit.form.Select"');
'dojoType="fox.form.Select"');
print "</fieldset>";
@ -634,7 +634,7 @@ class Pref_Feeds extends Handler_Protected {
print "<label>" . __('Article purging:') . "</label> ";
print_select_hash("purge_interval", $purge_interval, $purge_intervals,
'dojoType="dijit.form.Select" ' .
'dojoType="fox.form.Select" ' .
((FORCE_ARTICLE_PURGE == 0) ? "" : 'disabled="1"'));
print "</fieldset>";
@ -826,7 +826,7 @@ class Pref_Feeds extends Handler_Protected {
print "<label>" . __('Place in category:') . "</label> ";
print_feed_cat_select("cat_id", false,
'disabled="1" dojoType="dijit.form.Select"');
'disabled="1" dojoType="fox.form.Select"');
$this->batch_edit_cbox("cat_id");
@ -840,7 +840,7 @@ class Pref_Feeds extends Handler_Protected {
print "<label>" . __('Language:') . "</label> ";
print_select("feed_language", "", $this::get_ts_languages(),
'disabled="1" dojoType="dijit.form.Select"');
'disabled="1" dojoType="fox.form.Select"');
$this->batch_edit_cbox("feed_language");
@ -859,7 +859,7 @@ class Pref_Feeds extends Handler_Protected {
print "<label>".__("Interval:")."</label> ";
print_select_hash("update_interval", "", $update_intervals,
'disabled="1" dojoType="dijit.form.Select"');
'disabled="1" dojoType="fox.form.Select"');
$this->batch_edit_cbox("update_interval");
@ -874,7 +874,7 @@ class Pref_Feeds extends Handler_Protected {
print "<label>" . __('Article purging:') . "</label> ";
print_select_hash("purge_interval", "", $purge_intervals,
'disabled="1" dojoType="dijit.form.Select"');
'disabled="1" dojoType="fox.form.Select"');
$this->batch_edit_cbox("purge_interval");
@ -1217,7 +1217,7 @@ class Pref_Feeds extends Handler_Protected {
__('Search')."</button>
</div>";
print "<div dojoType=\"dijit.form.DropDownButton\">".
print "<div dojoType=\"fox.form.DropDownButton\">".
"<span>" . __('Select')."</span>";
print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
print "<div onclick=\"dijit.byId('feedTree').model.setAllChecked(true)\"
@ -1226,7 +1226,7 @@ class Pref_Feeds extends Handler_Protected {
dojoType=\"dijit.MenuItem\">".__('None')."</div>";
print "</div></div>";
print "<div dojoType=\"dijit.form.DropDownButton\">".
print "<div dojoType=\"fox.form.DropDownButton\">".
"<span>" . __('Feeds')."</span>";
print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
print "<div onclick=\"CommonDialogs.quickAddFeed()\"
@ -1242,7 +1242,7 @@ class Pref_Feeds extends Handler_Protected {
print "</div></div>";
if (get_pref('ENABLE_FEED_CATS')) {
print "<div dojoType=\"dijit.form.DropDownButton\">".
print "<div dojoType=\"fox.form.DropDownButton\">".
"<span>" . __('Categories')."</span>";
print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
print "<div onclick=\"dijit.byId('feedTree').createCategory()\"
@ -1450,7 +1450,7 @@ class Pref_Feeds extends Handler_Protected {
$sth->execute([$_SESSION['uid']]);
print "<div dojoType='fox.Toolbar'>";
print "<div dojoType='dijit.form.DropDownButton'>".
print "<div dojoType='fox.form.DropDownButton'>".
"<span>" . __('Select')."</span>";
print "<div dojoType='dijit.Menu' style='display: none'>";
print "<div onclick=\"Tables.select('inactive-feeds-list', true)\"
@ -1507,7 +1507,7 @@ class Pref_Feeds extends Handler_Protected {
$sth->execute([$_SESSION['uid']]);
print "<div dojoType=\"fox.Toolbar\">";
print "<div dojoType=\"dijit.form.DropDownButton\">".
print "<div dojoType=\"fox.form.DropDownButton\">".
"<span>" . __('Select')."</span>";
print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
print "<div onclick=\"Tables.select('error-feeds-list', true)\"
@ -1662,7 +1662,7 @@ class Pref_Feeds extends Handler_Protected {
if (get_pref('ENABLE_FEED_CATS')) {
print "<fieldset>";
print "<label>" . __('Place in category:') . "</label> ";
print_feed_cat_select("cat", false, 'dojoType="dijit.form.Select"');
print_feed_cat_select("cat", false, 'dojoType="fox.form.Select"');
print "</fieldset>";
}

View File

@ -356,7 +356,7 @@ class Pref_Filters extends Handler_Protected {
print "<div dojoType=\"fox.Toolbar\">";
print "<div dojoType=\"dijit.form.DropDownButton\">".
print "<div dojoType=\"fox.form.DropDownButton\">".
"<span>" . __('Select')."</span>";
print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
print "<div onclick=\"dijit.byId('filterEditDlg').selectRules(true)\"
@ -416,7 +416,7 @@ class Pref_Filters extends Handler_Protected {
print "<div dojoType=\"fox.Toolbar\">";
print "<div dojoType=\"dijit.form.DropDownButton\">".
print "<div dojoType=\"fox.form.DropDownButton\">".
"<span>" . __('Select')."</span>";
print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
print "<div onclick=\"dijit.byId('filterEditDlg').selectActions(true)\"
@ -772,7 +772,7 @@ class Pref_Filters extends Handler_Protected {
__('Search')."</button>
</div>";
print "<div dojoType=\"dijit.form.DropDownButton\">".
print "<div dojoType=\"fox.form.DropDownButton\">".
"<span>" . __('Select')."</span>";
print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
print "<div onclick=\"dijit.byId('filterTree').model.setAllChecked(true)\"
@ -858,7 +858,7 @@ class Pref_Filters extends Handler_Protected {
print "<div dojoType='fox.Toolbar'>";
print "<div dojoType='dijit.form.DropDownButton'>".
print "<div dojoType='fox.form.DropDownButton'>".
"<span>" . __('Select')."</span>";
print "<div dojoType='dijit.Menu' style='display: none'>";
print "<div onclick=\"dijit.byId('filterEditDlg').selectRules(true)\"
@ -887,7 +887,7 @@ class Pref_Filters extends Handler_Protected {
print "<div dojoType='fox.Toolbar'>";
print "<div dojoType='dijit.form.DropDownButton'>".
print "<div dojoType='fox.form.DropDownButton'>".
"<span>" . __('Select')."</span>";
print "<div dojoType='dijit.Menu' style='display: none'>";
print "<div onclick=\"dijit.byId('filterEditDlg').selectActions(true)\"
@ -993,7 +993,7 @@ class Pref_Filters extends Handler_Protected {
print "<fieldset>";
print "<label style='display : inline'>". __("on field") . "</label> ";
print_select_hash("filter_type", $filter_type, $filter_types,
'dojoType="dijit.form.Select"');
'dojoType="fox.form.Select"');
print "<label style='padding-left : 10px; display : inline'>" . __("in") . "</label> ";
print "</fieldset>";
@ -1042,7 +1042,7 @@ class Pref_Filters extends Handler_Protected {
print "<section>";
print "<select name='action_id' dojoType='dijit.form.Select'
print "<select name='action_id' dojoType='fox.form.Select'
onchange='Filters.filterDlgCheckAction(this)'>";
$res = $this->pdo->query("SELECT id,description FROM ttrss_filter_actions
@ -1073,7 +1073,7 @@ class Pref_Filters extends Handler_Protected {
print_label_select("action_param_label", $action_param,
"id='filterDlg_actionParamLabel' style=\"$label_param_hidden\"
dojoType='dijit.form.Select'");
dojoType='fox.form.Select'");
$filter_actions = PluginHost::getInstance()->get_filter_actions();
$filter_action_hash = array();
@ -1096,7 +1096,7 @@ class Pref_Filters extends Handler_Protected {
}
print_select_hash("filterDlg_actionParamPlugin", $action_param, $filter_action_hash,
"style=\"$plugin_param_hidden\" dojoType='dijit.form.Select' $filter_plugin_disabled",
"style=\"$plugin_param_hidden\" dojoType='fox.form.Select' $filter_plugin_disabled",
"action_param_plugin");
print "</span>";

View File

@ -253,7 +253,7 @@ class Pref_Labels extends Handler_Protected {
print "<div style='padding : 0px' dojoType='dijit.layout.ContentPane' region='top'>";
print "<div dojoType='fox.Toolbar'>";
print "<div dojoType='dijit.form.DropDownButton'>".
print "<div dojoType='fox.form.DropDownButton'>".
"<span>" . __('Select')."</span>";
print "<div dojoType=\"dijit.Menu\" style=\"display: none;\">";
print "<div onclick=\"dijit.byId('labelTree').model.setAllChecked(true)\"

View File

@ -579,7 +579,7 @@ class Pref_Prefs extends Handler_Protected {
if ($pref_name == "USER_LANGUAGE") {
print_select_hash($pref_name, $value, get_translations(),
"style='width : 220px; margin : 0px' dojoType='dijit.form.Select'");
"style='width : 220px; margin : 0px' dojoType='fox.form.Select'");
} else if ($pref_name == "USER_TIMEZONE") {
@ -595,7 +595,7 @@ class Pref_Prefs extends Handler_Protected {
if (!theme_exists($value)) $value = "default.php";
print "<select name='$pref_name' id='$pref_name' dojoType='dijit.form.Select'>";
print "<select name='$pref_name' id='$pref_name' dojoType='fox.form.Select'>";
$issel = $value == "default.php" ? "selected='selected'" : "";
print "<option $issel value='default.php'>".__("default")."</option>";
@ -618,11 +618,11 @@ class Pref_Prefs extends Handler_Protected {
global $update_intervals_nodefault;
print_select_hash($pref_name, $value, $update_intervals_nodefault,
'dojoType="dijit.form.Select"');
'dojoType="fox.form.Select"');
} else if ($pref_name == "DEFAULT_SEARCH_LANGUAGE") {
print_select($pref_name, $value, Pref_Feeds::get_ts_languages(),
'dojoType="dijit.form.Select"');
'dojoType="fox.form.Select"');
} else if ($type_name == "bool") {
@ -715,7 +715,7 @@ class Pref_Prefs extends Handler_Protected {
print_hidden("op", "pref-prefs");
print_hidden("method", "saveconfig");
print "<div dojoType=\"dijit.form.ComboButton\" type=\"submit\" class=\"alt-primary\">
print "<div dojoType=\"fox.form.ComboButton\" type=\"submit\" class=\"alt-primary\">
<span>".__('Save configuration')."</span>
<div dojoType=\"dijit.DropDownMenu\">
<div dojoType=\"dijit.MenuItem\"
@ -1023,7 +1023,7 @@ class Pref_Prefs extends Handler_Protected {
function editPrefProfiles() {
print "<div dojoType='fox.Toolbar'>";
print "<div dojoType='dijit.form.DropDownButton'>".
print "<div dojoType='fox.form.DropDownButton'>".
"<span>" . __('Select')."</span>";
print "<div dojoType='dijit.Menu' style='display: none'>";
print "<div onclick=\"Tables.select('pref-profiles-list', true)\"

View File

@ -69,10 +69,10 @@ class Pref_Users extends Handler_Protected {
if (!$sel_disabled) {
print_select_hash("access_level", $access_level, $access_level_names,
"dojoType=\"dijit.form.Select\" $sel_disabled");
"dojoType=\"fox.form.Select\" $sel_disabled");
} else {
print_select_hash("", $access_level, $access_level_names,
"dojoType=\"dijit.form.Select\" $sel_disabled");
"dojoType=\"fox.form.Select\" $sel_disabled");
print_hidden("access_level", "$access_level");
}
@ -336,7 +336,7 @@ class Pref_Users extends Handler_Protected {
$sort = "login";
}
print "<div dojoType='dijit.form.DropDownButton'>".
print "<div dojoType='fox.form.DropDownButton'>".
"<span>" . __('Select')."</span>";
print "<div dojoType='dijit.Menu' style='display: none'>";
print "<div onclick=\"Tables.select('prefUserList', true)\"

View File

@ -170,7 +170,7 @@
<select name="view_mode" title="<?php echo __('Show articles') ?>"
onchange="App.onViewModeChanged()"
dojoType="dijit.form.Select">
dojoType="fox.form.Select">
<option selected="selected" value="adaptive"><?php echo __('Adaptive') ?></option>
<option value="all_articles"><?php echo __('All Articles') ?></option>
<option value="marked"><?php echo __('Starred') ?></option>
@ -182,7 +182,7 @@
<select title="<?php echo __('Sort articles') ?>"
onchange="App.onViewModeChanged()"
dojoType="dijit.form.Select" name="order_by">
dojoType="fox.form.Select" name="order_by">
<option selected="selected" value="default"><?php echo __('Default') ?></option>
<option value="feed_dates"><?php echo __('Newest first') ?></option>
@ -190,7 +190,7 @@
<option value="title"><?php echo __('Title') ?></option>
</select>
<div dojoType="dijit.form.ComboButton" onclick="Feeds.catchupCurrent()">
<div dojoType="fox.form.ComboButton" onclick="Feeds.catchupCurrent()">
<span><?php echo __('Mark as read') ?></span>
<div dojoType="dijit.DropDownMenu">
<div dojoType="dijit.MenuItem" onclick="Feeds.catchupCurrent('1day')">
@ -215,7 +215,7 @@
}
?>
<div dojoType="dijit.form.DropDownButton" class="action-button" title="<?php echo __('Actions...') ?>">
<div dojoType="fox.form.DropDownButton" class="action-button" title="<?php echo __('Actions...') ?>">
<span><i class="material-icons">menu</i></span>
<div dojoType="dijit.Menu" style="display: none">
<div dojoType="dijit.MenuItem" onclick="App.onActionSelected('qmcPrefs')"><?php echo __('Preferences...') ?></div>

12
js/form/ComboButton.js Executable file
View File

@ -0,0 +1,12 @@
/* global dijit */
define(["dojo/_base/declare", "dijit/form/ComboButton"], function (declare) {
return declare("fox.form.ComboButton", dijit.form.ComboButton, {
startup: function() {
this.inherited(arguments);
this.dropDown.autoFocus = true; // Allow dropdown menu to be focused on click
},
focus: function() {
return; // Stop dijit.form.ComboButton from keeping focus after closing the menu
},
});
});

12
js/form/DropDownButton.js Executable file
View File

@ -0,0 +1,12 @@
/* global dijit */
define(["dojo/_base/declare", "dijit/form/DropDownButton"], function (declare) {
return declare("fox.form.DropDownButton", dijit.form.DropDownButton, {
startup: function() {
this.inherited(arguments);
this.dropDown.autoFocus = true; // Allow dropdown menu to be focused on click
},
focus: function() {
return; // Stop dijit.form.DropDownButton from keeping focus after closing the menu
},
});
});

8
js/form/Select.js Executable file
View File

@ -0,0 +1,8 @@
/* global dijit */
define(["dojo/_base/declare", "dijit/form/Select"], function (declare) {
return declare("fox.form.Select", dijit.form.Select, {
focus: function() {
return; // Stop dijit.form.Select from keeping focus after closing the menu
},
});
});

View File

@ -54,7 +54,10 @@ require(["dojo/_base/kernel",
"fox/PrefFeedTree",
"fox/PrefFilterTree",
"fox/PrefLabelTree",
"fox/Toolbar"], function (dojo, declare, ready, parser, AppBase) {
"fox/Toolbar",
"fox/form/Select",
"fox/form/ComboButton",
"fox/form/DropDownButton"], function (dojo, declare, ready, parser, AppBase) {
ready(function () {
try {

View File

@ -55,7 +55,10 @@ require(["dojo/_base/kernel",
"fox/Article",
"fox/FeedStoreModel",
"fox/FeedTree",
"fox/Toolbar"], function (dojo, declare, ready, parser, AppBase) {
"fox/Toolbar",
"fox/form/Select",
"fox/form/ComboButton",
"fox/form/DropDownButton"], function (dojo, declare, ready, parser, AppBase) {
ready(function () {
try {