Bug 1385791 - Fix message filtering; r=? draft
authorJan Odvarko <odvarko@gmail.com>
Thu, 10 Aug 2017 13:04:42 +0200
changeset 644047 d38539fed8f7a1caeec2390aa17c42bd0248b705
parent 641444 bb8de16ce00cb57b587a14c210ecc7505f366328
child 725474 998b313b61f6e8cadf4e039468aa5c60310b924c
push id73291
push userjodvarko@mozilla.com
push dateThu, 10 Aug 2017 11:05:15 +0000
bugs1385791
milestone57.0a1
Bug 1385791 - Fix message filtering; r=? MozReview-Commit-ID: J6lIfuh8tJZ
devtools/client/themes/common.css
devtools/client/webconsole/new-console-output/components/message-container.js
devtools/client/webconsole/new-console-output/constants.js
devtools/client/webconsole/new-console-output/new-console-output-wrapper.js
devtools/client/webconsole/new-console-output/reducers/messages.js
devtools/client/webconsole/package.json
--- a/devtools/client/themes/common.css
+++ b/devtools/client/themes/common.css
@@ -334,17 +334,18 @@ checkbox:-moz-focusring {
 .devtools-button:not(:empty):not(.checked):not(:disabled):hover:active,
 .devtools-toolbarbutton:not(:-moz-any([checked=true],[disabled]))[label]:hover:active {
   background-color: var(--theme-selection-background-semitransparent);
 }
 
 .devtools-toolbarbutton:not([disabled])[label][checked=true],
 .devtools-toolbarbutton:not([disabled])[label][open],
 .devtools-button:not(:empty).checked,
-.theme-firebug .devtools-toolbarbutton:-moz-any([checked],[open]),
+.theme-firebug .devtools-toolbarbutton[checked],
+.theme-firebug .devtools-toolbarbutton[open],
 .theme-firebug .devtools-button.checked:empty {
   background: var(--toolbarbutton-checked-background);
   border-color: var(--toolbarbutton-checked-border-color);
   color: var(--toolbarbutton-checked-color);
 }
 
 /* Icons */
 :root {
--- a/devtools/client/webconsole/new-console-output/components/message-container.js
+++ b/devtools/client/webconsole/new-console-output/components/message-container.js
@@ -74,16 +74,20 @@ const MessageContainer = createClass({
     const message = this.props.getMessage();
 
     let MessageComponent = getMessageComponent(message);
     return MessageComponent(Object.assign({message}, this.props));
   }
 });
 
 function getMessageComponent(message) {
+  if (!message) {
+    return componentMap.get("DefaultRenderer");
+  }
+
   switch (message.source) {
     case MESSAGE_SOURCE.CONSOLE_API:
       return componentMap.get("ConsoleApiCall");
     case MESSAGE_SOURCE.NETWORK:
       return componentMap.get("NetworkEventMessage");
     case MESSAGE_SOURCE.CSS:
     case MESSAGE_SOURCE.JAVASCRIPT:
       switch (message.type) {
--- a/devtools/client/webconsole/new-console-output/constants.js
+++ b/devtools/client/webconsole/new-console-output/constants.js
@@ -60,16 +60,17 @@ const chromeRDPEnums = {
     DIR: "dir",
     TABLE: "table",
     TRACE: "trace",
     CLEAR: "clear",
     START_GROUP: "startGroup",
     START_GROUP_COLLAPSED: "startGroupCollapsed",
     END_GROUP: "endGroup",
     ASSERT: "assert",
+    DEBUG: "debug",
     PROFILE: "profile",
     PROFILE_END: "profileEnd",
     // Undocumented in Chrome RDP, but is used for evaluation results.
     RESULT: "result",
     // Undocumented in Chrome RDP, but is used for input.
     COMMAND: "command",
     // Undocumented in Chrome RDP, but is used for messages that should not
     // output anything (e.g. `console.time()` calls).
--- a/devtools/client/webconsole/new-console-output/new-console-output-wrapper.js
+++ b/devtools/client/webconsole/new-console-output/new-console-output-wrapper.js
@@ -42,22 +42,23 @@ NewConsoleOutputWrapper.prototype = {
     // Focus the input line whenever the output area is clicked.
     this.parentNode.addEventListener("click", (event) => {
       // Do not focus on middle/right-click or 2+ clicks.
       if (event.detail !== 1 || event.button !== 0) {
         return;
       }
 
       // Do not focus if a link was clicked
-      if (event.originalTarget.closest("a")) {
+      let target = event.originalTarget || event.target;
+      if (target.closest("a")) {
         return;
       }
 
       // Do not focus if something other than the output region was clicked
-      if (!event.originalTarget.closest(".webconsole-output")) {
+      if (!target.closest(".webconsole-output")) {
         return;
       }
 
       // Do not focus if something is selected
       let selection = this.document.defaultView.getSelection();
       if (selection && !selection.isCollapsed) {
         return;
       }
--- a/devtools/client/webconsole/new-console-output/reducers/messages.js
+++ b/devtools/client/webconsole/new-console-output/reducers/messages.js
@@ -426,32 +426,63 @@ function getAllActorsInMessage(message, 
 /**
  * Returns total count of top level messages (those which are not
  * within a group).
  */
 function getToplevelMessageCount(record) {
   return record.messagesById.count(message => !message.groupId);
 }
 
+/**
+ * Returns true if given message should be visible, false otherwise.
+ */
 function shouldMessageBeVisible(message, messagesState, filtersState, checkGroup = true) {
-  return (
-    (
-      checkGroup === false
-      || isInOpenedGroup(message, messagesState.groupsById, messagesState.messagesUiById)
-    )
-    && (
-      isUnfilterable(message)
-      || (
-        matchLevelFilters(message, filtersState)
-        && matchCssFilters(message, filtersState)
-        && matchNetworkFilters(message, filtersState)
-        && matchSearchFilters(message, filtersState)
-      )
-    )
-  );
+  // Do not display the message if it's in closed group.
+  if (checkGroup && !isInOpenedGroup(message, messagesState.groupsById,
+      messagesState.messagesUiById)) {
+    return false;
+  }
+
+  // Some messages can't be filtered out (e.g. groups).
+  // So, always return true for those.
+  if (isUnfilterable(message)) {
+    return true;
+  }
+
+  // Return true if the message belongs to enabled level
+  // (e.g. 'log', 'warn', etc.)
+  if (matchLevelFilters(message, filtersState)) {
+    return true;
+  }
+
+  // Return true if the message type is 'debug'
+  // and Debug filter is enabled.
+  if (matchDebugFilters(message, filtersState)) {
+    return true;
+  }
+
+  // Return true if the message source is 'css'
+  // and CSS filter is enabled.
+  if (matchCssFilters(message, filtersState)) {
+    return true;
+  }
+
+  // Return true if the message is network event
+  // and Network and/or XHR filter is enabled.
+  if (matchNetworkFilters(message, filtersState)) {
+    return true;
+  }
+
+  // Return true if the user is filtering using a free text
+  // and the message contains it.
+  if (matchSearchFilters(message, filtersState)) {
+    return true;
+  }
+
+  return false;
 }
 
 function isUnfilterable(message) {
   return [
     MESSAGE_TYPE.COMMAND,
     MESSAGE_TYPE.RESULT,
     MESSAGE_TYPE.START_GROUP,
     MESSAGE_TYPE.START_GROUP_COLLAPSED,
@@ -475,35 +506,46 @@ function isGroupClosed(groupId, messages
 }
 
 function matchLevelFilters(message, filters) {
   return filters.get(message.level) === true;
 }
 
 function matchNetworkFilters(message, filters) {
   return (
-    message.source !== MESSAGE_SOURCE.NETWORK
-    || (filters.get("net") === true && message.isXHR === false)
-    || (filters.get("netxhr") === true && message.isXHR === true)
+    message.source === MESSAGE_SOURCE.NETWORK &&
+    (filters.get("net") === true && message.isXHR === false) ||
+    (filters.get("netxhr") === true && message.isXHR === true)
+  );
+}
+
+function matchDebugFilters(message, filters) {
+  return (
+    message.source === MESSAGE_SOURCE.CONSOLE_API &&
+    message.type == MESSAGE_TYPE.DEBUG &&
+    filters.get("debug") === true
   );
 }
 
 function matchCssFilters(message, filters) {
   return (
-    message.source != MESSAGE_SOURCE.CSS
-    || filters.get("css") === true
+    message.source === MESSAGE_SOURCE.CSS &&
+    filters.get("css") === true
   );
 }
 
 function matchSearchFilters(message, filters) {
   let text = (filters.text || "").trim();
+  if (!text) {
+    return false;
+  }
+
   return (
-    text === ""
     // Look for a match in parameters.
-    || isTextInParameters(text, message.parameters)
+    isTextInParameters(text, message.parameters)
     // Look for a match in location.
     || isTextInFrame(text, message.frame)
     // Look for a match in net events.
     || isTextInNetEvent(text, message.request)
     // Look for a match in stack-trace.
     || isTextInStackTrace(text, message.stacktrace)
     // Look for a match in messageText.
     || isTextInMessageText(text, message.messageText)
--- a/devtools/client/webconsole/package.json
+++ b/devtools/client/webconsole/package.json
@@ -2,17 +2,17 @@
   "name": "webconsole",
   "version": "0.0.1",
   "engines": {
     "node": ">=6.9.0"
   },
   "scripts": {
     "start": "cross-env NODE_ENV=production node bin/dev-server",
     "dev": "node bin/dev-server",
-    "test": "cross-env NODE_ENV=test NODE_PATH=../../../ mocha new-console-output/test/**/*.test.js --compilers js:babel-register -r jsdom-global/register -r ./new-console-output/test/require-helper.js"
+    "test": "cross-env NODE_ENV=test NODE_PATH=../../../ mocha new-console-output/test/**/filters.test.js --compilers js:babel-register -r jsdom-global/register -r ./new-console-output/test/require-helper.js"
   },
   "dependencies": {
     "amd-loader": "0.0.5",
     "babel-preset-es2015": "^6.6.0",
     "babel-register": "^6.24.0",
     "cross-env": "^3.1.3",
     "devtools-config": "0.0.12",
     "devtools-launchpad": "0.0.67",