Bug 1263104 - Ctrl+F in Storage Inspector should open search draft
authorLuke Chang <lchang@mozilla.com>
Wed, 29 Jun 2016 17:11:47 +0800
changeset 382699 8311a3dd0d97dd40982e54da4282c0924c17e606
parent 382391 b69a5bbb5e40bd426e35222baa600b481e50d265
child 524271 924b43550d403a90df6ec9a0b5c062a79eecd02f
push id21804
push userbmo:lchang@mozilla.com
push dateThu, 30 Jun 2016 07:25:27 +0000
bugs1263104
milestone50.0a1
Bug 1263104 - Ctrl+F in Storage Inspector should open search
devtools/client/locales/en-US/storage.properties
devtools/client/storage/test/browser.ini
devtools/client/storage/test/browser_storage_search_keyboard_trap.js
devtools/client/storage/test/head.js
devtools/client/storage/ui.js
--- 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);