Bug 885294 - Immediate script selection from debugger search box is really janky and loses selection if you don't find anything, r=past
authorVictor Porof <vporof@mozilla.com>
Wed, 08 Jan 2014 10:48:32 +0200
changeset 162545 7f48035ecdb486544b4ba672429725a67ee5e1e6
parent 162494 96e869c388d70ba356c21706f2ceb6be8f7bfff7
child 162546 b524fc6b21b9da837c0ee6f0c91ae3f0b86e37bb
push id25959
push userryanvm@gmail.com
push dateWed, 08 Jan 2014 20:28:56 +0000
treeherdermozilla-central@9ca0f64ee634 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspast
bugs885294
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 885294 - Immediate script selection from debugger search box is really janky and loses selection if you don't find anything, r=past
browser/devtools/debugger/debugger-toolbar.js
browser/devtools/debugger/debugger-view.js
browser/devtools/debugger/test/browser.ini
browser/devtools/debugger/test/browser_dbg_search-popup-jank.js
browser/devtools/debugger/test/head.js
--- a/browser/devtools/debugger/debugger-toolbar.js
+++ b/browser/devtools/debugger/debugger-toolbar.js
@@ -863,17 +863,16 @@ FilterView.prototype = {
    * @param string aToken
    *        The source token to find.
    */
   _performTokenSearch: function(aToken) {
     // Make sure we're actually searching for a valid token.
     if (!aToken) {
       return;
     }
-
     DebuggerView.editor.find(aToken);
   },
 
   /**
    * The click listener for the search container.
    */
   _onClick: function() {
     // If there's some text in the searchbox, displaying a panel would
@@ -995,16 +994,19 @@ FilterView.prototype = {
     // a new function search immediately, or clear it.
     if (isFunctionSearch) {
       let targetView = DebuggerView.FilteredFunctions;
       if (!isReturnKey) {
         targetView[actionToPerform]();
       } else if (targetView.hidden) {
         targetView.scheduleSearch(args[0], 0);
       } else {
+        if (!targetView.selectedItem) {
+          targetView.selectedIndex = 0;
+        }
         this.clearSearch();
       }
       return;
     }
 
     // Perform a new variable search immediately.
     if (isVariableSearch) {
       let targetView = DebuggerView.Variables;
@@ -1018,16 +1020,19 @@ FilterView.prototype = {
     // a new file search immediately, or clear it.
     if (isFileOnlySearch) {
       let targetView = DebuggerView.FilteredSources;
       if (!isReturnKey) {
         targetView[actionToPerform]();
       } else if (targetView.hidden) {
         targetView.scheduleSearch(args[0], 0);
       } else {
+        if (!targetView.selectedItem) {
+          targetView.selectedIndex = 0;
+        }
         this.clearSearch();
       }
       return;
     }
 
     // Jump to the next/previous instance of the currently searched token.
     if (isTokenSearch) {
       let methods = { selectNext: "findNext", selectPrev: "findPrev" };
@@ -1253,18 +1258,21 @@ FilteredSourcesView.prototype = Heritage
       this.push([itemView], {
         index: -1, /* specifies on which position should the item be appended */
         attachment: {
           url: item.value
         }
       });
     }
 
-    // Select the first entry in this container.
-    this.selectedIndex = 0;
+    // There's at least one item displayed in this container. Don't select it
+    // automatically if not forced (by tests) or in tandem with an operator.
+    if (this._autoSelectFirstItem || DebuggerView.Filtering.searchOperator) {
+      this.selectedIndex = 0;
+    }
     this.hidden = false;
 
     // Signal that file search matches were found and displayed.
     window.emit(EVENTS.FILE_SEARCH_MATCH_FOUND);
   },
 
   /**
    * The click listener for this container.
@@ -1454,18 +1462,21 @@ FilteredFunctionsView.prototype = Herita
 
       // Append a function item to this container for each match.
       this.push([itemView], {
         index: -1, /* specifies on which position should the item be appended */
         attachment: item
       });
     }
 
-    // Select the first entry in this container.
-    this.selectedIndex = 0;
+    // There's at least one item displayed in this container. Don't select it
+    // automatically if not forced (by tests).
+    if (this._autoSelectFirstItem) {
+      this.selectedIndex = 0;
+    }
     this.hidden = false;
 
     // Signal that function search matches were found and displayed.
     window.emit(EVENTS.FUNCTION_SEARCH_MATCH_FOUND);
   },
 
   /**
    * The click listener for this container.
--- a/browser/devtools/debugger/debugger-view.js
+++ b/browser/devtools/debugger/debugger-view.js
@@ -685,16 +685,18 @@ ResultsPanelContainer.prototype = Herita
         this._panel.className = "results-panel";
         this._panel.setAttribute("level", "top");
         this._panel.setAttribute("noautofocus", "true");
         this._panel.setAttribute("consumeoutsideclicks", "false");
         document.documentElement.appendChild(this._panel);
       }
       if (!this.widget) {
         this.widget = new SimpleListWidget(this._panel);
+        this.autoFocusOnFirstItem = false;
+        this.autoFocusOnSelection = false;
         this.maintainSelectionVisible = false;
       }
     }
     // Cleanup the anchor and remove the previously created panel.
     else {
       this._panel.remove();
       this._panel = null;
       this.widget = null;
--- a/browser/devtools/debugger/test/browser.ini
+++ b/browser/devtools/debugger/test/browser.ini
@@ -170,16 +170,17 @@ support-files =
 [browser_dbg_search-basic-03.js]
 [browser_dbg_search-basic-04.js]
 [browser_dbg_search-global-01.js]
 [browser_dbg_search-global-02.js]
 [browser_dbg_search-global-03.js]
 [browser_dbg_search-global-04.js]
 [browser_dbg_search-global-05.js]
 [browser_dbg_search-global-06.js]
+[browser_dbg_search-popup-jank.js]
 [browser_dbg_search-sources-01.js]
 [browser_dbg_search-sources-02.js]
 [browser_dbg_search-sources-03.js]
 [browser_dbg_search-symbols.js]
 [browser_dbg_searchbox-help-popup-01.js]
 [browser_dbg_searchbox-help-popup-02.js]
 [browser_dbg_searchbox-parse.js]
 [browser_dbg_source-maps-01.js]
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_search-popup-jank.js
@@ -0,0 +1,118 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Tests that sources aren't selected by default when finding a match.
+ */
+
+const TAB_URL = EXAMPLE_URL + "doc_editor-mode.html";
+
+let gTab, gDebuggee, gPanel, gDebugger;
+let gSearchBox;
+
+function test() {
+  initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
+    gTab = aTab;
+    gDebuggee = aDebuggee;
+    gPanel = aPanel;
+    gDebugger = gPanel.panelWin;
+    gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
+
+    gDebugger.DebuggerView.FilteredSources._autoSelectFirstItem = false;
+    gDebugger.DebuggerView.FilteredFunctions._autoSelectFirstItem = false;
+
+    waitForSourceShown(gPanel, "-01.js")
+      .then(superGenericFileSearch)
+      .then(() => ensureSourceIs(aPanel, "-01.js"))
+      .then(() => ensureCaretAt(aPanel, 1))
+
+      .then(superAccurateFileSearch)
+      .then(() => ensureSourceIs(aPanel, "-01.js"))
+      .then(() => ensureCaretAt(aPanel, 1))
+      .then(() => pressKeyToHide("RETURN"))
+      .then(() => ensureSourceIs(aPanel, "code_test-editor-mode", true))
+      .then(() => ensureCaretAt(aPanel, 1))
+
+      .then(superGenericFileSearch)
+      .then(() => ensureSourceIs(aPanel, "code_test-editor-mode"))
+      .then(() => ensureCaretAt(aPanel, 1))
+      .then(() => pressKey("UP"))
+      .then(() => ensureSourceIs(aPanel, "doc_editor-mode", true))
+      .then(() => ensureCaretAt(aPanel, 1))
+      .then(() => pressKeyToHide("RETURN"))
+      .then(() => ensureSourceIs(aPanel, "doc_editor-mode"))
+      .then(() => ensureCaretAt(aPanel, 1))
+
+      .then(superAccurateFileSearch)
+      .then(() => ensureSourceIs(aPanel, "doc_editor-mode"))
+      .then(() => ensureCaretAt(aPanel, 1))
+      .then(() => typeText(gSearchBox, ":"))
+      .then(() => ensureSourceIs(aPanel, "code_test-editor-mode", true))
+      .then(() => ensureCaretAt(aPanel, 1))
+      .then(() => typeText(gSearchBox, "5"))
+      .then(() => ensureSourceIs(aPanel, "code_test-editor-mode"))
+      .then(() => ensureCaretAt(aPanel, 5))
+      .then(() => pressKey("DOWN"))
+      .then(() => ensureSourceIs(aPanel, "code_test-editor-mode"))
+      .then(() => ensureCaretAt(aPanel, 6))
+
+      .then(superGenericFunctionSearch)
+      .then(() => ensureSourceIs(aPanel, "code_test-editor-mode"))
+      .then(() => ensureCaretAt(aPanel, 6))
+      .then(() => pressKey("RETURN"))
+      .then(() => ensureSourceIs(aPanel, "code_test-editor-mode"))
+      .then(() => ensureCaretAt(aPanel, 4, 10))
+
+      .then(() => closeDebuggerAndFinish(gPanel))
+      .then(null, aError => {
+        ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
+      });
+  });
+}
+
+function waitForMatchFoundAndResultsShown(aName) {
+  return promise.all([
+    once(gDebugger, "popupshown"),
+    waitForDebuggerEvents(gPanel, gDebugger.EVENTS[aName])
+  ]);
+}
+
+function waitForResultsHidden() {
+  return once(gDebugger, "popuphidden");
+}
+
+function superGenericFunctionSearch() {
+  let finished = waitForMatchFoundAndResultsShown("FUNCTION_SEARCH_MATCH_FOUND");
+  setText(gSearchBox, "@");
+  return finished;
+}
+
+function superGenericFileSearch() {
+  let finished = waitForMatchFoundAndResultsShown("FILE_SEARCH_MATCH_FOUND");
+  setText(gSearchBox, ".");
+  return finished;
+}
+
+function superAccurateFileSearch() {
+  let finished = waitForMatchFoundAndResultsShown("FILE_SEARCH_MATCH_FOUND");
+  setText(gSearchBox, "editor");
+  return finished;
+}
+
+function pressKey(aKey) {
+  EventUtils.sendKey(aKey, gDebugger);
+}
+
+function pressKeyToHide(aKey) {
+  let finished = waitForResultsHidden();
+  EventUtils.sendKey(aKey, gDebugger);
+  return finished;
+}
+
+registerCleanupFunction(function() {
+  gTab = null;
+  gDebuggee = null;
+  gPanel = null;
+  gDebugger = null;
+  gSearchBox = null;
+});
--- a/browser/devtools/debugger/test/head.js
+++ b/browser/devtools/debugger/test/head.js
@@ -501,19 +501,21 @@ function initChromeDebugger(aOnClose) {
     deferred.resolve(aProcess);
   });
 
   return deferred.promise;
 }
 
 function prepareDebugger(aDebugger) {
   if ("target" in aDebugger) {
-    let variables = aDebugger.panelWin.DebuggerView.Variables;
-    variables.lazyEmpty = false;
-    variables.lazySearch = false;
+    let view = aDebugger.panelWin.DebuggerView;
+    view.Variables.lazyEmpty = false;
+    view.Variables.lazySearch = false;
+    view.FilteredSources._autoSelectFirstItem = true;
+    view.FilteredFunctions._autoSelectFirstItem = true;
   } else {
     // Nothing to do here yet.
   }
 }
 
 function teardown(aPanel, aFlags = {}) {
   info("Destroying the specified debugger.");