Bug 1169096 - Fix remote filtering on nested attributes. r=past, a=ritu
authorAlexandre Poirot <poirot.alex@gmail.com>
Tue, 21 Jul 2015 13:24:25 -0700
changeset 281768 b015222e675e086b90ad1ba44b05bda300ed1c48
parent 281767 39c6017f9e675c3e5be3624b4d54dbb5f19e783c
child 281769 08f7921cb81038ae9cd591de21de2aa3616aeb58
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspast, ritu
bugs1169096
milestone41.0a2
Bug 1169096 - Fix remote filtering on nested attributes. r=past, a=ritu
browser/devtools/debugger/test/browser_dbg_variables-view-02.js
browser/devtools/debugger/test/browser_dbg_variables-view-filter-01.js
browser/devtools/debugger/test/browser_dbg_variables-view-filter-02.js
browser/devtools/shared/widgets/VariablesView.jsm
browser/devtools/shared/widgets/VariablesViewController.jsm
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-02.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-02.js
@@ -1,13 +1,13 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
- * Tests that creating, collpasing and expanding variables in the
+ * Tests that creating, collapsing and expanding variables in the
  * variables view works as expected.
  */
 
 const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
 
 function test() {
   initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
     let variables = aPanel.panelWin.DebuggerView.Variables;
@@ -17,17 +17,17 @@ function test() {
 
     info("Scope id: " + testScope.id);
     info("Scope name: " + testScope.name);
     info("Variable id: " + testVar.id);
     info("Variable name: " + testVar.name);
 
     ok(testScope,
       "Should have created a scope.");
-    is(duplVar, null,
+    is(duplVar, testVar,
       "Shouldn't be able to duplicate variables in the same scope.");
 
     ok(testVar,
       "Should have created a variable.");
     ok(testVar.id.includes("something"),
       "The newly created variable should have the default id set.");
     is(testVar.name, "something",
       "The newly created variable should have the desired name set.");
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-filter-01.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-filter-01.js
@@ -91,18 +91,19 @@ function testVariablesAndPropertiesFilte
       "constructor", "The first inner property displayed should be 'constructor'");
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched]) > .title > .name")[1].getAttribute("value"),
       "__proto__", "The second inner property displayed should be '__proto__'");
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched]) > .title > .name")[2].getAttribute("value"),
       "constructor", "The third inner property displayed should be 'constructor'");
   }
 
   function firstFilter() {
+    let expanded = once(gVariables, "fetched");
     typeText(gSearchBox, "constructor");
-    testFiltered();
+    return expanded.then(testFiltered);
   }
 
   function secondFilter() {
     localScope.collapse();
     withScope.collapse();
     functionScope.collapse();
     globalScope.collapse();
     protoVar.collapse();
@@ -123,23 +124,23 @@ function testVariablesAndPropertiesFilte
       "The protoVar should not be expanded.");
     is(constrVar.expanded, false,
       "The constrVar should not be expanded.");
     is(proto2Var.expanded, false,
       "The proto2Var should not be expanded.");
     is(constr2Var.expanded, false,
       "The constr2Var should not be expanded.");
 
+    let expanded = once(gVariables, "fetched");
     clearText(gSearchBox);
     typeText(gSearchBox, "constructor");
-    testFiltered();
+    expanded.then(testFiltered);
   }
 
-  firstFilter();
-  secondFilter();
+  firstFilter().then(secondFilter);
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
--- a/browser/devtools/debugger/test/browser_dbg_variables-view-filter-02.js
+++ b/browser/devtools/debugger/test/browser_dbg_variables-view-filter-02.js
@@ -98,18 +98,19 @@ function testVariablesAndPropertiesFilte
 
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched]) > .title > .name")[3].getAttribute("value"),
       "name", "The fourth inner property displayed should be 'name'");
     is(localScope.target.querySelectorAll(".variables-view-property:not([unmatched]) > .title > .value")[3].getAttribute("value"),
       "\"Function\"", "The fourth inner property displayed should be '\"Function\"'");
   }
 
   function firstFilter() {
+    let expanded = once(gVariables, "fetched");
     typeText(gSearchBox, "\"Function\"");
-    testFiltered();
+    return expanded.then(testFiltered);
   }
 
   function secondFilter() {
     localScope.collapse();
     withScope.collapse();
     functionScope.collapse();
     globalScope.collapse();
     protoVar.collapse();
@@ -131,22 +132,22 @@ function testVariablesAndPropertiesFilte
     is(constrVar.expanded, false,
       "The constrVar should not be expanded.");
     is(proto2Var.expanded, false,
       "The proto2Var should not be expanded.");
     is(constr2Var.expanded, false,
       "The constr2Var should not be expanded.");
 
     backspaceText(gSearchBox, 10);
+    let expanded = once(gVariables, "fetched");
     typeText(gSearchBox, "\"Function\"");
-    testFiltered();
+    expanded.then(testFiltered);
   }
 
-  firstFilter();
-  secondFilter();
+  firstFilter().then(secondFilter);
 }
 
 function prepareVariablesAndProperties() {
   let deferred = promise.defer();
 
   let localScope = gVariables.getScopeAtIndex(0);
   let withScope = gVariables.getScopeAtIndex(1);
   let functionScope = gVariables.getScopeAtIndex(2);
--- a/browser/devtools/shared/widgets/VariablesView.jsm
+++ b/browser/devtools/shared/widgets/VariablesView.jsm
@@ -545,21 +545,32 @@ VariablesView.prototype = {
    * while the available variables and properties inside those scopes are
    * just unhidden.
    *
    * @param string aToken
    *        The variable or property to search for.
    */
   _doSearch: function(aToken) {
     if (this.controller.supportsSearch()) {
-      this.empty();
-      let scope = this.addScope(aToken);
-      scope.expanded = true; // Expand the scope by default.
-      scope.locked = true; // Prevent collapsing the scope.
+      // Retrieve the main Scope in which we add attributes
+      let scope = this._store[0]._store.get("");
+      if (!aToken) {
+        // Prune the view from old previous content
+        // so that we delete the intermediate search results
+        // we created in previous searches
+        for (let property of scope._store.values()) {
+          property.remove();
+        }
+      }
+      // Retrieve new attributes eventually hidden in splits
       this.controller.performSearch(scope, aToken);
+      // Filter already displayed attributes
+      if (aToken) {
+        scope._performSearch(aToken.toLowerCase());
+      }
       return;
     }
     for (let scope of this._store) {
       switch (aToken) {
         case "":
         case null:
         case undefined:
           scope.expand();
@@ -1283,17 +1294,17 @@ Scope.prototype = {
    * @param boolean aRelaxed [optional]
    *        Pass true if name duplicates should be allowed.
    *        You probably shouldn't do it. Use this with caution.
    * @return Variable
    *         The newly created Variable instance, null if it already exists.
    */
   addItem: function(aName = "", aDescriptor = {}, aRelaxed = false) {
     if (this._store.has(aName) && !aRelaxed) {
-      return null;
+      return this._store.get(aName);
     }
 
     let child = this._createChild(aName, aDescriptor);
     this._store.set(aName, child);
     this._variablesView._itemsByElement.set(child._target, child);
     this._variablesView._currHierarchy.set(child.absoluteName, child);
     child.header = !!aName;
 
--- a/browser/devtools/shared/widgets/VariablesViewController.jsm
+++ b/browser/devtools/shared/widgets/VariablesViewController.jsm
@@ -632,17 +632,20 @@ VariablesViewController.prototype = {
    * Try to use the actor to perform an attribute search.
    *
    * @param Scope aScope
    *        The Scope instance to populate with properties
    * @param string aToken
    *        The query string
    */
   performSearch: function(aScope, aToken) {
-    this._populateFromObjectWithIterator(aScope, this.objectActor, aToken);
+    this._populateFromObjectWithIterator(aScope, this.objectActor, aToken)
+        .then(() => {
+          this.view.emit("fetched", "search", aScope);
+        });
   },
 
   /**
    * Release an actor from the controller.
    *
    * @param object aActor
    *        The actor to release.
    */