Bug 879293 - Allow alt+click to select only one category of messages in the console; r=msucan
authorGabriel Luong <gabriel.luong@gmail.com>
Tue, 12 Nov 2013 14:20:14 +0200
changeset 154648 44acc55647b6e1d969f2891d5eaa48bd02cc0650
parent 154509 3338311ca993b3db159130ee6594521870978b18
child 154649 419d3348fab4bc0271db57d717264f46ce333e0b
push id25652
push userkwierso@gmail.com
push dateWed, 13 Nov 2013 02:43:23 +0000
treeherdermozilla-central@7b014f0f3b03 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmsucan
bugs879293
milestone28.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 879293 - Allow alt+click to select only one category of messages in the console; r=msucan
browser/devtools/webconsole/test/browser_webconsole_bug_601667_filter_buttons.js
browser/devtools/webconsole/webconsole.js
browser/devtools/webconsole/webconsole.xul
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_601667_filter_buttons.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_601667_filter_buttons.js
@@ -17,16 +17,23 @@ function testFilterButtons(aHud) {
   hud = aHud;
   hudId = hud.hudId;
   hudBox = hud.ui.rootElement;
 
   testMenuFilterButton("net");
   testMenuFilterButton("css");
   testMenuFilterButton("js");
   testMenuFilterButton("logging");
+  testMenuFilterButton("security");
+
+  testIsolateFilterButton("net");
+  testIsolateFilterButton("css");
+  testIsolateFilterButton("js");
+  testIsolateFilterButton("logging");
+  testIsolateFilterButton("security");
 
   finishTest();
 }
 
 function testMenuFilterButton(aCategory) {
   let selector = ".webconsole-filter-button[category=\"" + aCategory + "\"]";
   let button = hudBox.querySelector(selector);
   ok(button, "we have the \"" + aCategory + "\" button");
@@ -67,25 +74,17 @@ function testMenuFilterButton(aCategory)
   ok(!isChecked(firstMenuItem), "the first menu item for category " +
      aCategory + " is no longer checked after clicking it");
   ok(!hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
      "turned off after clicking the appropriate menu item");
   ok(isChecked(button), "the button for category " + aCategory + " is still " +
      "checked after turning off its first menu item");
 
   // Turn all the filters off by clicking the main part of the button.
-  let anonymousNodes = hud.ui.document.getAnonymousNodes(button);
-  let subbutton;
-  for (let i = 0; i < anonymousNodes.length; i++) {
-    let node = anonymousNodes[i];
-    if (node.classList.contains("toolbarbutton-menubutton-button")) {
-      subbutton = node;
-      break;
-    }
-  }
+  let subbutton = getMainButton(button);
   ok(subbutton, "we have the subbutton for category " + aCategory);
 
   clickButton(subbutton);
   ok(!isChecked(button), "the button for category " + aCategory + " is " +
      "no longer checked after clicking its main part");
 
   menuItem = firstMenuItem;
   while (menuItem) {
@@ -124,20 +123,91 @@ function testMenuFilterButton(aCategory)
 
   ok(!isChecked(button), "the button for category " + aCategory + " is " +
      "unchecked after unchecking all its filters");
 
   // Turn all the filters on again by clicking the button.
   clickButton(subbutton);
 }
 
+function testIsolateFilterButton(aCategory) {
+  let selector = ".webconsole-filter-button[category=\"" + aCategory + "\"]";
+  let targetButton = hudBox.querySelector(selector);
+  ok(targetButton, "we have the \"" + aCategory + "\" button");
+
+  // Get the main part of the filter button.
+  let subbutton = getMainButton(targetButton);
+  ok(subbutton, "we have the subbutton for category " + aCategory);
+
+  // Turn on all the filters by alt clicking the main part of the button.
+  altClickButton(subbutton);
+  ok(isChecked(targetButton), "the button for category " + aCategory +
+     " is checked after isolating for filter");
+
+  // Check if all the filters for the target button are on.
+  let menuItems = targetButton.querySelectorAll("menuitem");
+  Array.forEach(menuItems, (item) => {
+    let prefKey = item.getAttribute("prefKey");
+    ok(isChecked(item), "menu item " + prefKey + " for category " +
+      aCategory + " is checked after isolating for " + aCategory);
+    ok(hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
+      "turned on after isolating for " + aCategory);
+  });
+
+  // Ensure all other filter buttons are toggled off and their
+  // associated filters are turned off
+  let buttons = hudBox.querySelectorAll(".webconsole-filter-button[category]");
+  Array.forEach(buttons, (filterButton) => {
+    if (filterButton !== targetButton) {
+      let category = filterButton.getAttribute("category");
+      ok(!isChecked(filterButton), "the button for category " +
+        category + " is unchecked after isolating for " + aCategory);
+
+      menuItems = filterButton.querySelectorAll("menuitem");
+      Array.forEach(menuItems, (item) => {
+        let prefKey = item.getAttribute("prefKey");
+        ok(!isChecked(item), "menu item " + prefKey + " for category " +
+          aCategory + " is unchecked after isolating for " + aCategory);
+        ok(!hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
+          "turned off after isolating for " + aCategory);
+      });
+
+      // Turn all the filters on again by clicking the button.
+      let mainButton = getMainButton(filterButton);
+      clickButton(mainButton);
+    }
+  });
+}
+
+/**
+ * Return the main part of the target filter button.
+ */
+function getMainButton(aTargetButton) {
+  let anonymousNodes = hud.ui.document.getAnonymousNodes(aTargetButton);
+  let subbutton;
+
+  for (let i = 0; i < anonymousNodes.length; i++) {
+    let node = anonymousNodes[i];
+    if (node.classList.contains("toolbarbutton-menubutton-button")) {
+      subbutton = node;
+      break;
+    }
+  }
+
+  return subbutton;
+}
+
 function clickButton(aNode) {
   EventUtils.sendMouseEvent({ type: "click" }, aNode);
 }
 
+function altClickButton(aNode) {
+  EventUtils.sendMouseEvent({ type: "click", altKey: true }, aNode);
+}
+
 function chooseMenuItem(aNode) {
   let event = document.createEvent("XULCommandEvent");
   event.initCommandEvent("command", true, true, window, 0, false, false, false,
                          false, null);
   aNode.dispatchEvent(event);
 }
 
 function isChecked(aNode) {
--- a/browser/devtools/webconsole/webconsole.js
+++ b/browser/devtools/webconsole/webconsole.js
@@ -796,28 +796,36 @@ WebConsoleFrame.prototype = {
         if (!classes.contains("toolbarbutton-menubutton-button") &&
             originalTarget.getAttribute("type") === "menu-button") {
           // This is a filter button with a drop-down. The user clicked the
           // drop-down, so do nothing. (The menu will automatically appear
           // without our intervention.)
           break;
         }
 
+        // Toggle on the targeted filter button, and if the user alt clicked,
+        // toggle off all other filter buttons and their associated filters.
         let state = target.getAttribute("checked") !== "true";
+        if (aEvent.getModifierState("Alt")) {
+          let buttons = this.document
+                        .querySelectorAll(".webconsole-filter-button");
+          Array.forEach(buttons, (button) => {
+            if (button !== target) {
+              button.setAttribute("checked", false);
+              this._setMenuState(button, false);
+            }
+          });
+          state = true;
+        }
         target.setAttribute("checked", state);
 
         // This is a filter button with a drop-down, and the user clicked the
         // main part of the button. Go through all the severities and toggle
         // their associated filters.
-        let menuItems = target.querySelectorAll("menuitem");
-        for (let i = 0; i < menuItems.length; i++) {
-          menuItems[i].setAttribute("checked", state);
-          let prefKey = menuItems[i].getAttribute("prefKey");
-          this.setFilterState(prefKey, state);
-        }
+        this._setMenuState(target, state);
         break;
       }
 
       case "menuitem": {
         let state = target.getAttribute("checked") !== "true";
         target.setAttribute("checked", state);
 
         let prefKey = target.getAttribute("prefKey");
@@ -847,16 +855,35 @@ WebConsoleFrame.prototype = {
         let toolbarButton = menuPopup.parentNode;
         toolbarButton.setAttribute("checked", someChecked);
         break;
       }
     }
   },
 
   /**
+   * Set the menu attributes for a specific toggle button.
+   *
+   * @private
+   * @param XULElement aTarget
+   *        Button with drop down items to be toggled.
+   * @param boolean aState
+   *        True if the menu item is being toggled on, and false otherwise.
+   */
+  _setMenuState: function WCF__setMenuState(aTarget, aState)
+  {
+    let menuItems = aTarget.querySelectorAll("menuitem");
+    Array.forEach(menuItems, (item) => {
+      item.setAttribute("checked", aState);
+      let prefKey = item.getAttribute("prefKey");
+      this.setFilterState(prefKey, aState);
+    });
+  },
+
+  /**
    * Set the filter state for a specific toggle button.
    *
    * @param string aToggleType
    * @param boolean aState
    * @returns void
    */
   setFilterState: function WCF_setFilterState(aToggleType, aState)
   {
--- a/browser/devtools/webconsole/webconsole.xul
+++ b/browser/devtools/webconsole/webconsole.xul
@@ -43,18 +43,18 @@ function goUpdateConsoleCommands() {
              oncommand="goDoCommand('consoleCmd_clearOutput');"/>
     <command id="cmd_find" oncommand="goDoCommand('cmd_find');"/>
     <command id="cmd_fullZoomEnlarge" oncommand="goDoCommand('cmd_fontSizeEnlarge');" disabled="true"/>
     <command id="cmd_fullZoomReduce" oncommand="goDoCommand('cmd_fontSizeReduce');" disabled="true"/>
     <command id="cmd_fullZoomReset" oncommand="goDoCommand('cmd_fontSizeReset');" disabled="true"/>
     <command id="cmd_close" oncommand="goDoCommand('cmd_close');" disabled="true"/>
   </commandset>
   <keyset id="consoleKeys">
-    <key id="key_fullZoomReduce"  key="&fullZoomReduceCmd.commandkey;" command="cmd_fullZoomReduce"  modifiers="accel"/>
-    <key key="&fullZoomReduceCmd.commandkey2;"  command="cmd_fullZoomReduce" modifiers="accel"/>
+    <key id="key_fullZoomReduce" key="&fullZoomReduceCmd.commandkey;" command="cmd_fullZoomReduce" modifiers="accel"/>
+    <key key="&fullZoomReduceCmd.commandkey2;" command="cmd_fullZoomReduce" modifiers="accel"/>
     <key id="key_fullZoomEnlarge" key="&fullZoomEnlargeCmd.commandkey;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
     <key key="&fullZoomEnlargeCmd.commandkey2;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
     <key key="&fullZoomEnlargeCmd.commandkey3;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
     <key id="key_fullZoomReset" key="&fullZoomResetCmd.commandkey;" command="cmd_fullZoomReset" modifiers="accel"/>
     <key key="&fullZoomResetCmd.commandkey2;" command="cmd_fullZoomReset" modifiers="accel"/>
     <key key="&findCmd.key;" command="cmd_find" modifiers="accel"/>
     <key key="&closeCmd.key;" command="cmd_close" modifiers="accel"/>
     <key key="&clearOutputCtrl.key;" command="consoleCmd_clearOutput" modifiers="control"/>