mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2024-11-25 18:20:20 -06:00
Support tab navigation in dialogs. Fixes #2898
This commit is contained in:
parent
3be22383b8
commit
aa1849c13a
@ -10,36 +10,51 @@ desired.˝
|
|||||||
|
|
||||||
When using main browser window, the following keyboard shortcuts are available:
|
When using main browser window, the following keyboard shortcuts are available:
|
||||||
|
|
||||||
+---------------------------+--------------------------------------------------------+
|
+----------------------------+-------------------------------------------------------+
|
||||||
| Shortcut for all platform | Function |
|
| Shortcut for all platforms | Function |
|
||||||
+===========================+========================================================+
|
+============================+=======================================================+
|
||||||
| Alt+Shift+F | Open the File menu |
|
| Alt+Shift+F | Open the File menu |
|
||||||
+---------------------------+--------------------------------------------------------+
|
+----------------------------+-------------------------------------------------------+
|
||||||
| Alt+Shift+O | Open the Object menu |
|
| Alt+Shift+O | Open the Object menu |
|
||||||
+---------------------------+--------------------------------------------------------+
|
+----------------------------+-------------------------------------------------------+
|
||||||
| Alt+Shift+L | Open the Tools menu |
|
| Alt+Shift+L | Open the Tools menu |
|
||||||
+---------------------------+--------------------------------------------------------+
|
+----------------------------+-------------------------------------------------------+
|
||||||
| Alt+Shift+H | Open the Help menu |
|
| Alt+Shift+H | Open the Help menu |
|
||||||
+---------------------------+--------------------------------------------------------+
|
+----------------------------+-------------------------------------------------------+
|
||||||
| Alt+Shift+B | Focus the browser tree |
|
| Alt+Shift+B | Focus the browser tree |
|
||||||
+---------------------------+--------------------------------------------------------+
|
+----------------------------+-------------------------------------------------------+
|
||||||
| Alt+Shift+[ | Move tabbed panel backward/forward |
|
| Alt+Shift+[ | Move tabbed panel backward |
|
||||||
| Alt+Shift+] | |
|
+----------------------------+-------------------------------------------------------+
|
||||||
+---------------------------+--------------------------------------------------------+
|
| Alt+Shift+] | Move tabbed panel forward |
|
||||||
| Alt+Shift+Q | Open the Query Tool in the current database |
|
+----------------------------+-------------------------------------------------------+
|
||||||
+---------------------------+--------------------------------------------------------+
|
| Alt+Shift+Q | Open the Query Tool in the current database |
|
||||||
| Alt+Shift+V | View Data in the selected table/view |
|
+----------------------------+-------------------------------------------------------+
|
||||||
+---------------------------+--------------------------------------------------------+
|
| Alt+Shift+V | View Data in the selected table/view |
|
||||||
| Alt+Shift+C | Open the context menu |
|
+----------------------------+-------------------------------------------------------+
|
||||||
+---------------------------+--------------------------------------------------------+
|
| Alt+Shift+C | Open the context menu |
|
||||||
| Alt+Shift+N | Create an object |
|
+----------------------------+-------------------------------------------------------+
|
||||||
+---------------------------+--------------------------------------------------------+
|
| Alt+Shift+N | Create an object |
|
||||||
| Alt+Shift+E | Edit object properties |
|
+----------------------------+-------------------------------------------------------+
|
||||||
+---------------------------+--------------------------------------------------------+
|
| Alt+Shift+E | Edit object properties |
|
||||||
| Alt+Shift+D | Delete the object |
|
+----------------------------+-------------------------------------------------------+
|
||||||
+---------------------------+--------------------------------------------------------+
|
| Alt+Shift+D | Delete the object |
|
||||||
| Alt+Shift+G | Direct debugging |
|
+----------------------------+-------------------------------------------------------+
|
||||||
+---------------------------+--------------------------------------------------------+
|
| Alt+Shift+G | Direct debugging |
|
||||||
|
+----------------------------+-------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
**Dialog tab shortcuts**
|
||||||
|
|
||||||
|
Use the shortcuts below to navigate the tabsets on dialogs:
|
||||||
|
|
||||||
|
+----------------------------+-------------------------------------------------------+
|
||||||
|
| Shortcut for all platforms | Function |
|
||||||
|
+============================+=======================================================+
|
||||||
|
| Control+Shift+[ | Dialog tab backward |
|
||||||
|
+----------------------------+-------------------------------------------------------+
|
||||||
|
| Control+Shift+] | Dialog tab forward |
|
||||||
|
+----------------------------+-------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
**SQL Editors**
|
**SQL Editors**
|
||||||
|
|
||||||
|
@ -433,6 +433,36 @@ class BrowserModule(PgAdminModule):
|
|||||||
fields=fields
|
fields=fields
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'dialog_tab_forward',
|
||||||
|
gettext('Dialog tab forward'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': False,
|
||||||
|
'shift': True,
|
||||||
|
'control': True,
|
||||||
|
'key': {'key_code': 93, 'char': ']'}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=fields
|
||||||
|
)
|
||||||
|
|
||||||
|
self.preference.register(
|
||||||
|
'keyboard_shortcuts',
|
||||||
|
'dialog_tab_backward',
|
||||||
|
gettext('Dialog tab backward'),
|
||||||
|
'keyboardshortcut',
|
||||||
|
{
|
||||||
|
'alt': False,
|
||||||
|
'shift': True,
|
||||||
|
'control': True,
|
||||||
|
'key': {'key_code': 91, 'char': '['}
|
||||||
|
},
|
||||||
|
category_label=gettext('Keyboard shortcuts'),
|
||||||
|
fields=fields
|
||||||
|
)
|
||||||
|
|
||||||
def get_exposed_url_endpoints(self):
|
def get_exposed_url_endpoints(self):
|
||||||
"""
|
"""
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
/* eslint-disable */
|
define(['underscore', 'underscore.string', 'sources/pgadmin', 'jquery', 'mousetrap',
|
||||||
define(
|
'sources/utils', 'sources/dialog_tab_navigator'],
|
||||||
['underscore', 'underscore.string', 'sources/pgadmin', 'jquery', 'mousetrap'],
|
function(_, S, pgAdmin, $, Mousetrap, commonUtils, dialogTabNavigator) {
|
||||||
function(_, S, pgAdmin, $, Mousetrap) {
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var pgBrowser = pgAdmin.Browser = pgAdmin.Browser || {};
|
var pgBrowser = pgAdmin.Browser = pgAdmin.Browser || {};
|
||||||
@ -12,27 +11,26 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
init: function() {
|
init: function() {
|
||||||
Mousetrap.reset();
|
Mousetrap.reset();
|
||||||
if (pgBrowser.preferences_cache.length > 0) {
|
if (pgBrowser.preferences_cache.length > 0) {
|
||||||
var getShortcut = this.parseShortcutValue;
|
|
||||||
this.keyboardShortcut = {
|
this.keyboardShortcut = {
|
||||||
'file_shortcut': getShortcut(pgBrowser.get_preference('browser', 'main_menu_file').value),
|
'file_shortcut': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'main_menu_file').value),
|
||||||
'object_shortcut': getShortcut(pgBrowser.get_preference('browser', 'main_menu_object').value),
|
'object_shortcut': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'main_menu_object').value),
|
||||||
'tools_shortcut': getShortcut(pgBrowser.get_preference('browser', 'main_menu_tools').value),
|
'tools_shortcut': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'main_menu_tools').value),
|
||||||
'help_shortcut': getShortcut(pgBrowser.get_preference('browser', 'main_menu_help').value),
|
'help_shortcut': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'main_menu_help').value),
|
||||||
'left_tree_shortcut': getShortcut(pgBrowser.get_preference('browser', 'browser_tree').value),
|
'left_tree_shortcut': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'browser_tree').value),
|
||||||
'tabbed_panel_backward': getShortcut(pgBrowser.get_preference('browser', 'tabbed_panel_backward').value),
|
'tabbed_panel_backward': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'tabbed_panel_backward').value),
|
||||||
'tabbed_panel_forward': getShortcut(pgBrowser.get_preference('browser', 'tabbed_panel_forward').value),
|
'tabbed_panel_forward': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'tabbed_panel_forward').value),
|
||||||
'sub_menu_query_tool': getShortcut(pgBrowser.get_preference('browser', 'sub_menu_query_tool').value),
|
'sub_menu_query_tool': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_query_tool').value),
|
||||||
'sub_menu_view_data': getShortcut(pgBrowser.get_preference('browser', 'sub_menu_view_data').value),
|
'sub_menu_view_data': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_view_data').value),
|
||||||
'sub_menu_properties': getShortcut(pgBrowser.get_preference('browser', 'sub_menu_properties').value),
|
'sub_menu_properties': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_properties').value),
|
||||||
'sub_menu_create': getShortcut(pgBrowser.get_preference('browser', 'sub_menu_create').value),
|
'sub_menu_create': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_create').value),
|
||||||
'sub_menu_delete': getShortcut(pgBrowser.get_preference('browser', 'sub_menu_delete').value),
|
'sub_menu_delete': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_delete').value),
|
||||||
'context_menu': getShortcut(pgBrowser.get_preference('browser', 'context_menu').value),
|
'context_menu': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'context_menu').value),
|
||||||
'direct_debugging': getShortcut(pgBrowser.get_preference('browser', 'direct_debugging').value)
|
'direct_debugging': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'direct_debugging').value),
|
||||||
};
|
};
|
||||||
this.shortcutMethods = {
|
this.shortcutMethods = {
|
||||||
'bindMainMenu': {'shortcuts': [this.keyboardShortcut.file_shortcut,
|
'bindMainMenu': {'shortcuts': [this.keyboardShortcut.file_shortcut,
|
||||||
this.keyboardShortcut.object_shortcut, this.keyboardShortcut.tools_shortcut,
|
this.keyboardShortcut.object_shortcut, this.keyboardShortcut.tools_shortcut,
|
||||||
this.keyboardShortcut.help_shortcut]}, // Main menu
|
this.keyboardShortcut.help_shortcut]}, // Main menu
|
||||||
'bindRightPanel': {'shortcuts': [this.keyboardShortcut.tabbed_panel_backward, this.keyboardShortcut.tabbed_panel_forward]}, // Main window panels
|
'bindRightPanel': {'shortcuts': [this.keyboardShortcut.tabbed_panel_backward, this.keyboardShortcut.tabbed_panel_forward]}, // Main window panels
|
||||||
'bindMainMenuLeft': {'shortcuts': 'left', 'bindElem': '.pg-navbar'}, // Main menu
|
'bindMainMenuLeft': {'shortcuts': 'left', 'bindElem': '.pg-navbar'}, // Main menu
|
||||||
'bindMainMenuRight': {'shortcuts': 'right', 'bindElem': '.pg-navbar'}, // Main menu
|
'bindMainMenuRight': {'shortcuts': 'right', 'bindElem': '.pg-navbar'}, // Main menu
|
||||||
@ -44,9 +42,9 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
'bindSubMenuCreate': {'shortcuts': this.keyboardShortcut.sub_menu_create}, // Sub menu - Create Object,
|
'bindSubMenuCreate': {'shortcuts': this.keyboardShortcut.sub_menu_create}, // Sub menu - Create Object,
|
||||||
'bindSubMenuDelete': {'shortcuts': this.keyboardShortcut.sub_menu_delete}, // Sub menu - Delete object,
|
'bindSubMenuDelete': {'shortcuts': this.keyboardShortcut.sub_menu_delete}, // Sub menu - Delete object,
|
||||||
'bindContextMenu': {'shortcuts': this.keyboardShortcut.context_menu}, // Sub menu - Open context menu,
|
'bindContextMenu': {'shortcuts': this.keyboardShortcut.context_menu}, // Sub menu - Open context menu,
|
||||||
'bindDirectDebugging': {'shortcuts': this.keyboardShortcut.direct_debugging} // Sub menu - Direct Debugging
|
'bindDirectDebugging': {'shortcuts': this.keyboardShortcut.direct_debugging}, // Sub menu - Direct Debugging
|
||||||
};
|
};
|
||||||
this.bindShortcuts();
|
this.bindShortcuts();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bindShortcuts: function() {
|
bindShortcuts: function() {
|
||||||
@ -71,6 +69,20 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
attachShortcut: function(shortcut, callback, bindElem) {
|
attachShortcut: function(shortcut, callback, bindElem) {
|
||||||
this._bindWithMousetrap(shortcut, callback, bindElem);
|
this._bindWithMousetrap(shortcut, callback, bindElem);
|
||||||
},
|
},
|
||||||
|
attachDialogTabNavigatorShortcut: function(dialogTabNavigator, shortcuts) {
|
||||||
|
var callback = dialogTabNavigator.on_keyboard_event,
|
||||||
|
domElem = dialogTabNavigator.dialog.el;
|
||||||
|
|
||||||
|
if (domElem) {
|
||||||
|
Mousetrap(domElem).bind(shortcuts, function() {
|
||||||
|
callback.apply(dialogTabNavigator, arguments);
|
||||||
|
}.bind(domElem));
|
||||||
|
} else {
|
||||||
|
Mousetrap.bind(shortcuts, function() {
|
||||||
|
callback.apply(dialogTabNavigator, arguments);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
detachShortcut: function(shortcut, bindElem) {
|
detachShortcut: function(shortcut, bindElem) {
|
||||||
if (bindElem) Mousetrap(bindElem).unbind(shortcut);
|
if (bindElem) Mousetrap(bindElem).unbind(shortcut);
|
||||||
else Mousetrap.unbind(shortcut);
|
else Mousetrap.unbind(shortcut);
|
||||||
@ -211,18 +223,18 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
},
|
},
|
||||||
bindContextMenu: function(e) {
|
bindContextMenu: function(e) {
|
||||||
var tree = this.getTreeDetails(),
|
var tree = this.getTreeDetails(),
|
||||||
e = window.event,
|
left = $(e.srcElement).find('.aciTreeEntry').position().left + 70,
|
||||||
left = $(e.srcElement).find('.aciTreeEntry').position().left + 70,
|
top = $(e.srcElement).find('.aciTreeEntry').position().top + 70;
|
||||||
top = $(e.srcElement).find('.aciTreeEntry').position().top + 70;
|
e = window.event;
|
||||||
|
|
||||||
tree.t.blur(tree.i);
|
tree.t.blur(tree.i);
|
||||||
$('#tree').blur();
|
$('#tree').blur();
|
||||||
// Call context menu and set position
|
// Call context menu and set position
|
||||||
var ctx = tree.i.children().contextMenu({x: left, y:top});
|
tree.i.children().contextMenu({x: left, y:top});
|
||||||
},
|
},
|
||||||
bindDirectDebugging: function(e) {
|
bindDirectDebugging: function() {
|
||||||
var tree = this.getTreeDetails(),
|
var tree = this.getTreeDetails(),
|
||||||
type = tree.t.itemData(tree.i)._type;
|
type = tree.t.itemData(tree.i)._type;
|
||||||
|
|
||||||
if (!tree.d || (type != 'function' && type != 'procedure'))
|
if (!tree.d || (type != 'function' && type != 'procedure'))
|
||||||
return;
|
return;
|
||||||
@ -232,26 +244,23 @@ function(_, S, pgAdmin, $, Mousetrap) {
|
|||||||
pgAdmin.Tools.Debugger.get_function_information(pgAdmin.Browser.Nodes[type]);
|
pgAdmin.Tools.Debugger.get_function_information(pgAdmin.Browser.Nodes[type]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
parseShortcutValue: function(obj) {
|
|
||||||
var shortcut = "";
|
|
||||||
if (obj.alt) { shortcut += 'alt+'; }
|
|
||||||
if (obj.shift) { shortcut += 'shift+'; }
|
|
||||||
if (obj.control) { shortcut += 'ctrl+'; }
|
|
||||||
shortcut += String.fromCharCode(obj.key.key_code).toLowerCase();
|
|
||||||
return shortcut;
|
|
||||||
},
|
|
||||||
getTreeDetails: function() {
|
getTreeDetails: function() {
|
||||||
var t = pgAdmin.Browser.tree,
|
var t = pgAdmin.Browser.tree,
|
||||||
i = t.selected().length > 0 ? t.selected() : t.first(),
|
i = t.selected().length > 0 ? t.selected() : t.first(),
|
||||||
d = i && i.length == 1 ? t.itemData(i) : undefined;
|
d = i && i.length == 1 ? t.itemData(i) : undefined;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
t: t,
|
t: t,
|
||||||
i: i,
|
i: i,
|
||||||
d: d
|
d: d,
|
||||||
}
|
};
|
||||||
}
|
},
|
||||||
|
getDialogTabNavigator: function(dialog) {
|
||||||
|
var backward_shortcut = pgBrowser.get_preference('browser', 'dialog_tab_backward').value,
|
||||||
|
forward_shortcut = pgBrowser.get_preference('browser', 'dialog_tab_forward').value;
|
||||||
|
|
||||||
|
return new dialogTabNavigator.dialogTabNavigator(dialog, backward_shortcut, forward_shortcut);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return pgAdmin.keyboardNavigation;
|
return pgAdmin.keyboardNavigation;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
define('pgadmin.browser.node', [
|
define('pgadmin.browser.node', [
|
||||||
'sources/gettext', 'jquery', 'underscore', 'underscore.string', 'sources/pgadmin',
|
'sources/gettext', 'jquery', 'underscore', 'underscore.string', 'sources/pgadmin',
|
||||||
'pgadmin.browser.menu', 'backbone', 'pgadmin.alertifyjs', 'pgadmin.browser.datamodel',
|
'pgadmin.browser.menu', 'backbone', 'pgadmin.alertifyjs', 'pgadmin.browser.datamodel',
|
||||||
'backform', 'sources/browser/generate_url', 'pgadmin.browser.utils', 'pgadmin.backform',
|
'backform', 'sources/browser/generate_url', 'sources/utils', 'pgadmin.browser.utils',
|
||||||
], function(gettext, $, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform, generateUrl) {
|
'pgadmin.backform',
|
||||||
|
], function(gettext, $, _, S, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform, generateUrl, commonUtils) {
|
||||||
|
|
||||||
var wcDocker = window.wcDocker,
|
var wcDocker = window.wcDocker,
|
||||||
keyCode = {
|
keyCode = {
|
||||||
@ -365,9 +366,8 @@ define('pgadmin.browser.node', [
|
|||||||
}
|
}
|
||||||
|
|
||||||
var setFocusOnEl = function() {
|
var setFocusOnEl = function() {
|
||||||
setTimeout(function() {
|
var container = $(el).find('.tab-content:first > .tab-pane.active:first');
|
||||||
$(el).find('.tab-pane.active:first').find('input:first').focus();
|
commonUtils.findAndSetFocus(container);
|
||||||
}, 500);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!newModel.isNew()) {
|
if (!newModel.isNew()) {
|
||||||
@ -394,6 +394,8 @@ define('pgadmin.browser.node', [
|
|||||||
view.render();
|
view.render();
|
||||||
setFocusOnEl();
|
setFocusOnEl();
|
||||||
newModel.startNewSession();
|
newModel.startNewSession();
|
||||||
|
// var dialogTabNavigator = pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||||
|
pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||||
},
|
},
|
||||||
error: function(xhr, error, message) {
|
error: function(xhr, error, message) {
|
||||||
var _label = that && item ?
|
var _label = that && item ?
|
||||||
@ -430,8 +432,11 @@ define('pgadmin.browser.node', [
|
|||||||
view.render();
|
view.render();
|
||||||
setFocusOnEl();
|
setFocusOnEl();
|
||||||
newModel.startNewSession();
|
newModel.startNewSession();
|
||||||
|
// var dialogTabNavigator = pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||||
|
pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
define([
|
define([
|
||||||
'underscore', 'jquery', 'backbone', 'sources/pgadmin', 'pgadmin.browser',
|
'underscore', 'jquery', 'backbone', 'sources/pgadmin', 'pgadmin.browser',
|
||||||
'sources/gettext',
|
'sources/gettext', 'sources/utils',
|
||||||
], function(_, $, Backbone, pgAdmin, pgBrowser, gettext) {
|
], function(_, $, Backbone, pgAdmin, pgBrowser, gettext, commonUtils) {
|
||||||
|
|
||||||
var wcDocker = window.wcDocker;
|
var wcDocker = window.wcDocker;
|
||||||
|
|
||||||
@ -157,7 +157,8 @@ define([
|
|||||||
this.currPage = this.collection.at(this.options.curr_page).toJSON();
|
this.currPage = this.collection.at(this.options.curr_page).toJSON();
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
var data = this.currPage;
|
var self = this,
|
||||||
|
data = this.currPage;
|
||||||
|
|
||||||
/* Check Status of the buttons */
|
/* Check Status of the buttons */
|
||||||
this.options.disable_next = (this.options.disable_next ? true : this.evalASFunc(this.currPage.disable_next));
|
this.options.disable_next = (this.options.disable_next ? true : this.evalASFunc(this.currPage.disable_next));
|
||||||
@ -179,6 +180,11 @@ define([
|
|||||||
/* OnLoad Callback */
|
/* OnLoad Callback */
|
||||||
this.onLoad();
|
this.onLoad();
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
var container = $(self.el);
|
||||||
|
commonUtils.findAndSetFocus(container);
|
||||||
|
}, 100);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
nextPage: function() {
|
nextPage: function() {
|
||||||
|
@ -500,12 +500,12 @@ define([
|
|||||||
template: {
|
template: {
|
||||||
'header': _.template([
|
'header': _.template([
|
||||||
'<li role="presentation" <%=disabled ? "disabled" : ""%>>',
|
'<li role="presentation" <%=disabled ? "disabled" : ""%>>',
|
||||||
' <a data-toggle="tab" data-tab-index="<%=tabIndex%>" href="#<%=cId%>"',
|
' <a data-toggle="tab" tabindex="-1" data-tab-index="<%=tabIndex%>" href="#<%=cId%>"',
|
||||||
' id="<%=hId%>" aria-controls="<%=cId%>">',
|
' id="<%=hId%>" aria-controls="<%=cId%>">',
|
||||||
'<%=label%></a></li>',
|
'<%=label%></a></li>',
|
||||||
].join(' ')),
|
].join(' ')),
|
||||||
'panel': _.template(
|
'panel': _.template(
|
||||||
'<div role="tabpanel" class="tab-pane <%=label%> pg-el-sm-12 pg-el-md-12 pg-el-lg-12 pg-el-xs-12 fade" id="<%=cId%>" aria-labelledby="<%=hId%>"></div>'
|
'<div role="tabpanel" tabindex="-1" class="tab-pane <%=label%> pg-el-sm-12 pg-el-md-12 pg-el-lg-12 pg-el-xs-12 fade" id="<%=cId%>" aria-labelledby="<%=hId%>"></div>'
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
|
143
web/pgadmin/static/js/dialog_tab_navigator.js
Normal file
143
web/pgadmin/static/js/dialog_tab_navigator.js
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
import $ from 'jquery';
|
||||||
|
import Mousetrap from 'mousetrap';
|
||||||
|
import { findAndSetFocus } from './utils';
|
||||||
|
import { parseShortcutValue } from './utils';
|
||||||
|
|
||||||
|
class dialogTabNavigator {
|
||||||
|
constructor(dialog, backwardShortcut, forwardShortcut) {
|
||||||
|
|
||||||
|
this.dialog = dialog;
|
||||||
|
|
||||||
|
this.tabSwitching = false;
|
||||||
|
|
||||||
|
this.tabs = this.dialog.$el.find('.nav-tabs');
|
||||||
|
|
||||||
|
if (this.tabs.length > 0 ) {
|
||||||
|
this.tabs = this.tabs[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dialogTabBackward = parseShortcutValue(backwardShortcut);
|
||||||
|
this.dialogTabForward = parseShortcutValue(forwardShortcut);
|
||||||
|
|
||||||
|
Mousetrap(this.dialog.el).bind(this.dialogTabBackward, this.onKeyboardEvent.bind(this));
|
||||||
|
Mousetrap(this.dialog.el).bind(this.dialogTabForward, this.onKeyboardEvent.bind(this));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyboardEvent(event, shortcut) {
|
||||||
|
var currentTabPane = this.dialog.$el
|
||||||
|
.find('.tab-content:first > .tab-pane.active:first'),
|
||||||
|
childTabData = this.isActivePaneHasChildTabs(currentTabPane);
|
||||||
|
|
||||||
|
if (this.tabSwitching) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tabSwitching = true;
|
||||||
|
|
||||||
|
if(childTabData) {
|
||||||
|
var res = this.navigate(shortcut, childTabData.childTab,
|
||||||
|
childTabData.childTabPane);
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
this.navigate(shortcut, this.tabs, currentTabPane);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.navigate(shortcut, this.tabs, currentTabPane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isActivePaneHasChildTabs(currentTabPane) {
|
||||||
|
var childTab = currentTabPane.find('.nav-tabs:first'),
|
||||||
|
childTabPane;
|
||||||
|
|
||||||
|
if (childTab.length > 0) {
|
||||||
|
childTabPane = currentTabPane
|
||||||
|
.find('.tab-content:first > .tab-pane.active:first');
|
||||||
|
|
||||||
|
return {
|
||||||
|
'childTab': childTab,
|
||||||
|
'childTabPane': childTabPane,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigate(shortcut, tabs, tab_pane) {
|
||||||
|
if(shortcut == this.dialogTabBackward) {
|
||||||
|
return this.navigateBackward(tabs, tab_pane);
|
||||||
|
}else if (shortcut == this.dialogTabForward) {
|
||||||
|
return this.navigateForward(tabs, tab_pane);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigateBackward(tabs, tab_pane) {
|
||||||
|
var self = this,
|
||||||
|
nextTabPane,
|
||||||
|
innerTabContainer,
|
||||||
|
prevtab = $(tabs).find('li.active').prev('li');
|
||||||
|
|
||||||
|
if (prevtab.length > 0) {
|
||||||
|
prevtab.find('a').tab('show');
|
||||||
|
|
||||||
|
nextTabPane = tab_pane.prev();
|
||||||
|
innerTabContainer = nextTabPane
|
||||||
|
.find('.tab-content:first > .tab-pane.active:first');
|
||||||
|
|
||||||
|
if (innerTabContainer.length > 0) {
|
||||||
|
findAndSetFocus(innerTabContainer);
|
||||||
|
} else {
|
||||||
|
findAndSetFocus(nextTabPane);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
self.tabSwitching = false;
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tabSwitching = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigateForward(tabs, tab_pane) {
|
||||||
|
var self = this,
|
||||||
|
nextTabPane,
|
||||||
|
innerTabContainer,
|
||||||
|
nexttab = $(tabs).find('li.active').next('li');
|
||||||
|
|
||||||
|
if(nexttab.length > 0) {
|
||||||
|
nexttab.find('a').tab('show');
|
||||||
|
|
||||||
|
nextTabPane = tab_pane.next();
|
||||||
|
innerTabContainer = nextTabPane
|
||||||
|
.find('.tab-content:first > .tab-pane.active:first');
|
||||||
|
|
||||||
|
if (innerTabContainer.length > 0) {
|
||||||
|
findAndSetFocus(innerTabContainer);
|
||||||
|
} else {
|
||||||
|
findAndSetFocus(nextTabPane);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
self.tabSwitching = false;
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
this.tabSwitching = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
detach() {
|
||||||
|
Mousetrap(this.dialog.el).unbind(this.dialogTabBackward);
|
||||||
|
Mousetrap(this.dialog.el).unbind(this.dialogTabForward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
dialogTabNavigator: dialogTabNavigator,
|
||||||
|
};
|
38
web/pgadmin/static/js/utils.js
Normal file
38
web/pgadmin/static/js/utils.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
export function parseShortcutValue(obj) {
|
||||||
|
var shortcut = '';
|
||||||
|
if (obj.alt) { shortcut += 'alt+'; }
|
||||||
|
if (obj.shift) { shortcut += 'shift+'; }
|
||||||
|
if (obj.control) { shortcut += 'ctrl+'; }
|
||||||
|
shortcut += String.fromCharCode(obj.key.key_code).toLowerCase();
|
||||||
|
return shortcut;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function findAndSetFocus(container) {
|
||||||
|
if (container.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTimeout(function() {
|
||||||
|
var first_el = container
|
||||||
|
.find('button.fa-plus:first');
|
||||||
|
|
||||||
|
if (first_el.length == 0) {
|
||||||
|
first_el = container
|
||||||
|
.find('.pgadmin-controls:first>input:enabled,.CodeMirror-scroll');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(first_el.length > 0) {
|
||||||
|
first_el[0].focus();
|
||||||
|
} else {
|
||||||
|
container[0].focus();
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
}
|
@ -2,9 +2,10 @@
|
|||||||
define([
|
define([
|
||||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||||
'underscore.string', 'pgadmin.alertifyjs', 'backbone', 'pgadmin.backgrid',
|
'underscore.string', 'pgadmin.alertifyjs', 'backbone', 'pgadmin.backgrid',
|
||||||
'pgadmin.backform', 'pgadmin.browser',
|
'pgadmin.backform', 'pgadmin.browser', 'sources/utils',
|
||||||
], function(
|
], function(
|
||||||
gettext, url_for, $, _, S, alertify, Backbone, Backgrid, Backform, pgBrowser
|
gettext, url_for, $, _, S, alertify, Backbone, Backgrid, Backform, pgBrowser,
|
||||||
|
commonUtils
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// if module is already initialized, refer to that.
|
// if module is already initialized, refer to that.
|
||||||
@ -696,6 +697,9 @@ define([
|
|||||||
|
|
||||||
this.elements.content.appendChild($container.get(0));
|
this.elements.content.appendChild($container.get(0));
|
||||||
|
|
||||||
|
var container = view.$el.find('.tab-content:first > .tab-pane.active:first');
|
||||||
|
commonUtils.findAndSetFocus(container);
|
||||||
|
|
||||||
// Listen to model & if filename is provided then enable Backup button
|
// Listen to model & if filename is provided then enable Backup button
|
||||||
this.view.model.on('change', function() {
|
this.view.model.on('change', function() {
|
||||||
if (!_.isUndefined(this.get('file')) && this.get('file') !== '') {
|
if (!_.isUndefined(this.get('file')) && this.get('file') !== '') {
|
||||||
@ -940,6 +944,13 @@ define([
|
|||||||
|
|
||||||
this.elements.content.appendChild($container.get(0));
|
this.elements.content.appendChild($container.get(0));
|
||||||
|
|
||||||
|
if(view) {
|
||||||
|
view.$el.attr('tabindex', -1);
|
||||||
|
// var dialogTabNavigator = pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||||
|
pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||||
|
var container = view.$el.find('.tab-content:first > .tab-pane.active:first');
|
||||||
|
commonUtils.findAndSetFocus(container);
|
||||||
|
}
|
||||||
// Listen to model & if filename is provided then enable Backup button
|
// Listen to model & if filename is provided then enable Backup button
|
||||||
this.view.model.on('change', function() {
|
this.view.model.on('change', function() {
|
||||||
if (!_.isUndefined(this.get('file')) && this.get('file') !== '') {
|
if (!_.isUndefined(this.get('file')) && this.get('file') !== '') {
|
||||||
|
@ -89,8 +89,10 @@ define([
|
|||||||
cell: Backgrid.Extension.SelectRowCell.extend({
|
cell: Backgrid.Extension.SelectRowCell.extend({
|
||||||
render: function() {
|
render: function() {
|
||||||
|
|
||||||
// Use the Backform Control's render function
|
// Do not use parent's render function. It set's tabindex to -1 on
|
||||||
Backgrid.Extension.SelectRowCell.prototype.render.apply(this, arguments);
|
// checkboxes.
|
||||||
|
this.$el.empty().append('<input type="checkbox" />');
|
||||||
|
this.delegateEvents();
|
||||||
|
|
||||||
var col = this.column.get('name');
|
var col = this.column.get('name');
|
||||||
if (this.model && this.model.has(col)) {
|
if (this.model && this.model.has(col)) {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
define([
|
define([
|
||||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'underscore.string', 'pgadmin.alertifyjs',
|
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'underscore.string', 'pgadmin.alertifyjs',
|
||||||
'sources/pgadmin', 'pgadmin.browser', 'backbone', 'backgrid', 'backform',
|
'sources/pgadmin', 'pgadmin.browser', 'backbone', 'backgrid', 'backform',
|
||||||
'pgadmin.backform', 'pgadmin.backgrid', 'pgadmin.browser.node.ui',
|
'sources/utils', 'pgadmin.backform', 'pgadmin.backgrid', 'pgadmin.browser.node.ui',
|
||||||
], function(
|
], function(
|
||||||
gettext, url_for, $, _, S, Alertify, pgAdmin, pgBrowser, Backbone, Backgrid, Backform
|
gettext, url_for, $, _, S, Alertify, pgAdmin, pgBrowser, Backbone, Backgrid,
|
||||||
|
Backform, commonUtils
|
||||||
) {
|
) {
|
||||||
|
|
||||||
pgAdmin = pgAdmin || window.pgAdmin || {};
|
pgAdmin = pgAdmin || window.pgAdmin || {};
|
||||||
@ -652,6 +653,12 @@ define([
|
|||||||
// Give the dialog initial height & width
|
// Give the dialog initial height & width
|
||||||
this.elements.dialog.style.minHeight = '80%';
|
this.elements.dialog.style.minHeight = '80%';
|
||||||
this.elements.dialog.style.minWidth = '70%';
|
this.elements.dialog.style.minWidth = '70%';
|
||||||
|
|
||||||
|
view.$el.attr('tabindex', -1);
|
||||||
|
// var dialogTabNavigator = pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||||
|
pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||||
|
var container = view.$el.find('.tab-content:first > .tab-pane.active:first');
|
||||||
|
commonUtils.findAndSetFocus(container);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
define([
|
define([
|
||||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||||
'underscore.string', 'pgadmin.alertifyjs', 'sources/pgadmin', 'pgadmin.browser', 'backbone',
|
'underscore.string', 'pgadmin.alertifyjs', 'sources/pgadmin', 'pgadmin.browser', 'backbone',
|
||||||
'backgrid', 'backform',
|
'backgrid', 'backform', 'sources/utils',
|
||||||
'pgadmin.backform', 'pgadmin.backgrid',
|
'pgadmin.backform', 'pgadmin.backgrid',
|
||||||
'pgadmin.browser.node.ui',
|
'pgadmin.browser.node.ui',
|
||||||
], function(
|
], function(
|
||||||
gettext, url_for, $, _, S, Alertify, pgAdmin, pgBrowser, Backbone, Backgrid,
|
gettext, url_for, $, _, S, Alertify, pgAdmin, pgBrowser, Backbone, Backgrid,
|
||||||
Backform
|
Backform, commonUtils
|
||||||
) {
|
) {
|
||||||
|
|
||||||
pgAdmin = pgAdmin || window.pgAdmin || {};
|
pgAdmin = pgAdmin || window.pgAdmin || {};
|
||||||
@ -468,6 +468,10 @@ define([
|
|||||||
$(reindex_btn).addClass('active');
|
$(reindex_btn).addClass('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
view.$el.attr('tabindex', -1);
|
||||||
|
var container = view.$el.find('.tab-content:first > .tab-pane.active:first');
|
||||||
|
commonUtils.findAndSetFocus(container);
|
||||||
|
|
||||||
this.elements.content.appendChild($container.get(0));
|
this.elements.content.appendChild($container.get(0));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
define('tools.restore', [
|
define('tools.restore', [
|
||||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
|
'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'backbone',
|
||||||
'underscore.string', 'pgadmin.alertifyjs', 'pgadmin.browser',
|
'underscore.string', 'pgadmin.alertifyjs', 'pgadmin.browser',
|
||||||
'pgadmin.backgrid', 'pgadmin.backform',
|
'pgadmin.backgrid', 'pgadmin.backform', 'sources/utils',
|
||||||
], function(
|
], function(
|
||||||
gettext, url_for, $, _, Backbone, S, alertify, pgBrowser, Backgrid, Backform
|
gettext, url_for, $, _, Backbone, S, alertify, pgBrowser, Backgrid, Backform,
|
||||||
|
commonUtils
|
||||||
) {
|
) {
|
||||||
|
|
||||||
// if module is already initialized, refer to that.
|
// if module is already initialized, refer to that.
|
||||||
@ -572,6 +573,12 @@ define('tools.restore', [
|
|||||||
|
|
||||||
this.elements.content.appendChild($container.get(0));
|
this.elements.content.appendChild($container.get(0));
|
||||||
|
|
||||||
|
view.$el.attr('tabindex', -1);
|
||||||
|
// var dialogTabNavigator = pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||||
|
pgBrowser.keyboardNavigation.getDialogTabNavigator(view);
|
||||||
|
var container = view.$el.find('.tab-content:first > .tab-pane.active:first');
|
||||||
|
commonUtils.findAndSetFocus(container);
|
||||||
|
|
||||||
// Listen to model & if filename is provided then enable Backup button
|
// Listen to model & if filename is provided then enable Backup button
|
||||||
this.view.model.on('change', function() {
|
this.view.model.on('change', function() {
|
||||||
if (!_.isUndefined(this.get('file')) && this.get('file') !== '') {
|
if (!_.isUndefined(this.get('file')) && this.get('file') !== '') {
|
||||||
|
115
web/regression/javascript/dialog_tab_navigator_spec.js
Normal file
115
web/regression/javascript/dialog_tab_navigator_spec.js
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 - 2018, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
import dialogTabNavigator from 'sources/dialog_tab_navigator';
|
||||||
|
import $ from 'jquery';
|
||||||
|
import 'bootstrap';
|
||||||
|
|
||||||
|
describe('dialogTabNavigator', function () {
|
||||||
|
let dialog, tabNavigator, backward_shortcut, forward_shortcut;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
let dialogHtml =$('<div tabindex="1" class="backform-tab" role="tabpanel">'+
|
||||||
|
' <ul class="nav nav-tabs" role="tablist">'+
|
||||||
|
' <li role="presentation" class="active">'+
|
||||||
|
' <a data-toggle="tab" tabindex="-1" data-tab-index="1" href="#1" aria-controls="1"> General</a>'+
|
||||||
|
' </li>'+
|
||||||
|
' <li role="presentation">'+
|
||||||
|
' <a data-toggle="tab" tabindex="-1" data-tab-index="5" href="#2" aria-controls="2"> Default Privileges</a>'+
|
||||||
|
' </li>'+
|
||||||
|
' <li role="presentation">'+
|
||||||
|
' <a data-toggle="tab" tabindex="-1" data-tab-index="6" href="#3" aria-controls="3"> SQL</a>'+
|
||||||
|
' </li>'+
|
||||||
|
' </ul>'+
|
||||||
|
' <ul class="tab-content">'+
|
||||||
|
' <div role="tabpanel" tabindex="-1" class="tab-pane fade collapse in active" id="1">'+
|
||||||
|
' </div>'+
|
||||||
|
' <div role="tabpanel" tabindex="-1" class="tab-pane fade collapse" id="2">'+
|
||||||
|
' <div class="inline-tab-panel" role="tabpanel">'+
|
||||||
|
' <ul class="nav nav-tabs" role="tablist">'+
|
||||||
|
' <li role="presentation" class="active">'+
|
||||||
|
' <a data-toggle="tab" tabindex="-1" data-tab-index="601" href="#11" aria-controls="11"> Tables</a>'+
|
||||||
|
' </li>'+
|
||||||
|
' <li role="presentation">'+
|
||||||
|
' <a data-toggle="tab" tabindex="-1" data-tab-index="602" href="#22" aria-controls="22"> Sequences</a>'+
|
||||||
|
' </li>'+
|
||||||
|
' </ul>'+
|
||||||
|
' <ul class="tab-content">'+
|
||||||
|
' <div role="tabpanel" tabindex="-1" class="tab-pane fade collapse in active" id="11" >'+
|
||||||
|
' </div>'+
|
||||||
|
' <div role="tabpanel" tabindex="-1" class="tab-pane fade collapse" id="22">'+
|
||||||
|
' </div>'+
|
||||||
|
' </ul>'+
|
||||||
|
' </div>'+
|
||||||
|
' </div>'+
|
||||||
|
' <div role="tabpanel" tabindex="-1" class="tab-pane fade collapse" id="3">'+
|
||||||
|
' </div>'+
|
||||||
|
' </ul>'+
|
||||||
|
'</div>');
|
||||||
|
|
||||||
|
dialog = {};
|
||||||
|
|
||||||
|
dialog.el = dialogHtml[0];
|
||||||
|
dialog.$el = dialogHtml;
|
||||||
|
|
||||||
|
backward_shortcut = {
|
||||||
|
'alt': false,
|
||||||
|
'shift': true,
|
||||||
|
'control': true,
|
||||||
|
'key': {'key_code': 91, 'char': '['}
|
||||||
|
};
|
||||||
|
|
||||||
|
forward_shortcut = {
|
||||||
|
'alt': false,
|
||||||
|
'shift': true,
|
||||||
|
'control': true,
|
||||||
|
'key': {'key_code': 93, 'char': ']'}
|
||||||
|
};
|
||||||
|
|
||||||
|
tabNavigator = new dialogTabNavigator.dialogTabNavigator(
|
||||||
|
dialog, backward_shortcut, forward_shortcut);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('navigate', function () {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(tabNavigator, 'navigateBackward').and.callThrough();
|
||||||
|
|
||||||
|
spyOn(tabNavigator, 'navigateForward').and.callThrough();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('navigate backward', function () {
|
||||||
|
tabNavigator.onKeyboardEvent({}, 'shift+ctrl+[');
|
||||||
|
|
||||||
|
expect(tabNavigator.navigateBackward).toHaveBeenCalled();
|
||||||
|
|
||||||
|
expect(tabNavigator.navigateForward).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('navigate forward', function () {
|
||||||
|
tabNavigator.onKeyboardEvent({}, 'shift+ctrl+]');
|
||||||
|
|
||||||
|
expect(tabNavigator.navigateForward).toHaveBeenCalled();
|
||||||
|
|
||||||
|
expect(tabNavigator.navigateBackward).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not navigate', function () {
|
||||||
|
tabNavigator.onKeyboardEvent({}, 'shift+ctrl+a');
|
||||||
|
|
||||||
|
expect(tabNavigator.navigateForward).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
expect(tabNavigator.navigateBackward).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
@ -126,6 +126,7 @@ var webpackShimConfig = {
|
|||||||
'pgadmin': path.join(__dirname, './pgadmin/static/js/pgadmin'),
|
'pgadmin': path.join(__dirname, './pgadmin/static/js/pgadmin'),
|
||||||
'translations': path.join(__dirname, './pgadmin/tools/templates/js/translations'),
|
'translations': path.join(__dirname, './pgadmin/tools/templates/js/translations'),
|
||||||
'sources/gettext': path.join(__dirname, './pgadmin/static/js/gettext'),
|
'sources/gettext': path.join(__dirname, './pgadmin/static/js/gettext'),
|
||||||
|
'sources/utils': path.join(__dirname, './pgadmin/static/js/utils'),
|
||||||
'babel-polyfill': path.join(__dirname, './node_modules/babel-polyfill/dist/polyfill'),
|
'babel-polyfill': path.join(__dirname, './node_modules/babel-polyfill/dist/polyfill'),
|
||||||
|
|
||||||
// Vendor JS
|
// Vendor JS
|
||||||
|
Loading…
Reference in New Issue
Block a user