Bug 1263104 - Ctrl+F in Storage Inspector should open search
--- a/devtools/client/locales/en-US/storage.properties
+++ b/devtools/client/locales/en-US/storage.properties
@@ -32,16 +32,20 @@ storage.menuLabel=Storage Inspector
storage.panelLabel=Storage Panel
# LOCALIZATION NOTE (storage.tooltip3):
# This string is displayed in the tooltip of the tab when the storage editor is
# displayed inside the developer tools window.
# A keyboard shortcut for Storage Inspector will be shown inside the brackets.
storage.tooltip3=Storage Inspector (Cookies, Local Storage, …) (%S)
+# LOCALIZATION NOTE (storage.filter.key):
+# Key shortcut used to focus the filter box on top of the data view
+storage.filter.key=CmdOrCtrl+F
+
# LOCALIZATION NOTE (tree.emptyText):
# This string is displayed when the Storage Tree is empty. This can happen when
# there are no websites on the current page (about:blank)
tree.emptyText=No hosts on the page
# LOCALIZATION NOTE (table.emptyText):
# This string is displayed when there are no rows in the Storage Table for the
# selected host.
--- a/devtools/client/storage/test/browser.ini
+++ b/devtools/client/storage/test/browser.ini
@@ -30,12 +30,13 @@ support-files =
[browser_storage_delete_tree.js]
[browser_storage_dynamic_updates.js]
[browser_storage_empty_objectstores.js]
[browser_storage_indexeddb_delete.js]
[browser_storage_indexeddb_delete_blocked.js]
[browser_storage_localstorage_edit.js]
[browser_storage_overflow.js]
[browser_storage_search.js]
+[browser_storage_search_keyboard_trap.js]
[browser_storage_sessionstorage_edit.js]
[browser_storage_sidebar.js]
[browser_storage_sidebar_update.js]
[browser_storage_values.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/storage/test/browser_storage_search_keyboard_trap.js
@@ -0,0 +1,15 @@
+// Test ability to focus search field by using keyboard
+"use strict";
+
+add_task(function* () {
+ yield openTabAndSetupStorage(MAIN_DOMAIN + "storage-search.html");
+
+ gUI.tree.expandAll();
+ yield selectTreeItem(["localStorage", "http://test1.example.org"]);
+
+ yield focusSearchBoxUsingShortcut(gPanelWindow);
+ ok(containsFocus(gPanelWindow.document, gUI.searchBox),
+ "Focus is in a searchbox");
+
+ yield finishTests();
+});
--- a/devtools/client/storage/test/head.js
+++ b/devtools/client/storage/test/head.js
@@ -783,8 +783,42 @@ function* checkState(state) {
is(items.size, names.length,
`There is correct number of rows in ${storeName}`);
for (let name of names) {
ok(items.has(name),
`There is item with name '${name}' in ${storeName}`);
}
}
}
+
+/**
+ * Checks if document's active element is within the given element.
+ * @param {HTMLDocument} doc document with active element in question
+ * @param {DOMNode} container element tested on focus containment
+ * @return {Boolean}
+ */
+function containsFocus(doc, container) {
+ let elm = doc.activeElement;
+ while (elm) {
+ if (elm === container) {
+ return true;
+ }
+ elm = elm.parentNode;
+ }
+ return false;
+}
+
+var focusSearchBoxUsingShortcut = Task.async(function* (panelWin, callback) {
+ info("Focusing search box");
+ let searchBox = panelWin.document.getElementById("storage-searchbox");
+ let focused = once(searchBox, "focus");
+
+ panelWin.focus();
+ let strings = Services.strings.createBundle(
+ "chrome://devtools/locale/storage.properties");
+ synthesizeKeyShortcut(strings.GetStringFromName("storage.filter.key"));
+
+ yield focused;
+
+ if (callback) {
+ callback();
+ }
+});
--- a/devtools/client/storage/ui.js
+++ b/devtools/client/storage/ui.js
@@ -3,16 +3,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {Task} = require("devtools/shared/task");
const EventEmitter = require("devtools/shared/event-emitter");
const {LocalizationHelper} = require("devtools/client/shared/l10n");
+const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
loader.lazyRequireGetter(this, "TreeWidget",
"devtools/client/shared/widgets/TreeWidget", true);
loader.lazyRequireGetter(this, "TableWidget",
"devtools/client/shared/widgets/TableWidget", true);
loader.lazyRequireGetter(this, "ViewHelpers",
"devtools/client/shared/widgets/view-helpers");
loader.lazyImporter(this, "VariablesView",
@@ -106,16 +107,25 @@ function StorageUI(front, target, panelW
this.sidebar.setAttribute("width", "300");
this.view = new VariablesView(this.sidebar.firstChild,
GENERIC_VARIABLES_VIEW_SETTINGS);
this.searchBox = this._panelDoc.getElementById("storage-searchbox");
this.filterItems = this.filterItems.bind(this);
this.searchBox.addEventListener("command", this.filterItems);
+ let shortcuts = new KeyShortcuts({
+ window: this._panelDoc.defaultView,
+ });
+ let key = L10N.getStr("storage.filter.key");
+ shortcuts.on(key, (name, event) => {
+ event.preventDefault();
+ this.searchBox.focus();
+ });
+
this.front.listStores().then(storageTypes => {
this.populateStorageTree(storageTypes);
}).then(null, console.error);
this.onUpdate = this.onUpdate.bind(this);
this.front.on("stores-update", this.onUpdate);
this.onCleared = this.onCleared.bind(this);
this.front.on("stores-cleared", this.onCleared);