Bug 922212 - Add console.dirxml. r=bgrins, r=mrbkap
authorFlorent Fayolle <fayolle-florent@orange.fr>
Wed, 29 Apr 2015 11:34:00 -0400
changeset 273581 7ea0e4207486fdc78f0b40fb4345aad81bd78d70
parent 273580 486e691d3e68a1e50f6b380efeaa103d47ec021d
child 273582 b4ad268f693877c4dc4d59f0b7ac4eff6ceaa079
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins, mrbkap
bugs922212
milestone40.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 922212 - Add console.dirxml. r=bgrins, r=mrbkap
browser/devtools/webconsole/console-output.js
browser/devtools/webconsole/test/browser.ini
browser/devtools/webconsole/test/browser_webconsole_bug_659907_console_dir.js
browser/devtools/webconsole/test/browser_webconsole_bug_922212_console_dirxml.js
browser/devtools/webconsole/test/head.js
browser/devtools/webconsole/test/test-console-extras.html
browser/devtools/webconsole/webconsole.js
dom/base/Console.cpp
dom/base/Console.h
dom/webidl/Console.webidl
--- a/browser/devtools/webconsole/console-output.js
+++ b/browser/devtools/webconsole/console-output.js
@@ -88,16 +88,17 @@ const CONSOLE_API_LEVELS_TO_SEVERITIES =
   assert: "error",
   warn: "warning",
   info: "info",
   log: "log",
   trace: "log",
   table: "log",
   debug: "log",
   dir: "log",
+  dirxml: "log",
   group: "log",
   groupCollapsed: "log",
   groupEnd: "log",
   time: "log",
   timeEnd: "log",
   count: "log"
 };
 
@@ -2977,17 +2978,18 @@ Widgets.ObjectRenderers.add({
         break;
       default:
         throw new Error("Unsupported nodeType: " + preview.nodeType);
     }
   },
 
   _renderDocumentNode: function()
   {
-    let fn = Widgets.ObjectRenderers.byKind.ObjectWithURL.prototype._renderElement;
+    let fn =
+      Widgets.ObjectRenderers.byKind.ObjectWithURL.prototype._renderElement;
     this.element = fn.call(this, this.objectActor,
                            this.objectActor.preview.location);
     this.element.classList.add("documentNode");
   },
 
   _renderAttributeNode: function(nodeName, nodeValue, addLink)
   {
     let value = VariablesView.getString(nodeValue, { noStringQuotes: true });
--- a/browser/devtools/webconsole/test/browser.ini
+++ b/browser/devtools/webconsole/test/browser.ini
@@ -379,8 +379,9 @@ skip-if = e10s # Bug 1042253 - webconsol
 [browser_webconsole_start_netmon_first.js]
 [browser_webconsole_console_trace_duplicates.js]
 [browser_webconsole_cd_iframe.js]
 [browser_webconsole_autocomplete_crossdomain_iframe.js]
 [browser_webconsole_console_custom_styles.js]
 [browser_webconsole_console_api_stackframe.js]
 [browser_webconsole_column_numbers.js]
 [browser_console_open_or_focus.js]
+[browser_webconsole_bug_922212_console_dirxml.js]
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_659907_console_dir.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_659907_console_dir.js
@@ -4,17 +4,17 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // Tests that console.dir works as intended.
 
 "use strict";
 
 const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 659907: " +
-  "Expand console object with a dir method"
+  "Expand console object with a dir method";
 
 let test = asyncTest(function*() {
   yield loadTab(TEST_URI);
   let hud = yield openConsole();
   hud.jsterm.clearOutput();
 
   hud.jsterm.execute("console.dir(document)");
 
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_922212_console_dirxml.js
@@ -0,0 +1,49 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+// Tests that console.dirxml works as intended.
+
+"use strict";
+
+const TEST_URI = `data:text/html;charset=utf-8,Web Console test for bug 922212:
+  Add console.dirxml`;
+
+let test = asyncTest(function*() {
+  yield loadTab(TEST_URI);
+  let hud = yield openConsole();
+  hud.jsterm.clearOutput();
+
+  // Should work like console.log(window)
+  hud.jsterm.execute("console.dirxml(window)");
+
+  let [result] = yield waitForMessages({
+    webconsole: hud,
+    messages: [{
+      name: "console.dirxml(window) output:",
+      text: /Window \u2192/,
+      category: CATEGORY_WEBDEV,
+      severity: SEVERITY_LOG,
+    }],
+  });
+
+  hud.jsterm.clearOutput();
+
+  hud.jsterm.execute("console.dirxml(document.body)");
+
+  // Should work like console.log(document.body);
+  [result] = yield waitForMessages({
+    webconsole: hud,
+    messages: [{
+      name: "console.dirxml(document.body) output:",
+      text: "<body>",
+      category: CATEGORY_WEBDEV,
+      severity: SEVERITY_LOG,
+    }],
+  });
+  let msg = [...result.matched][0];
+  yield checkLinkToInspector(true, msg);
+});
+
--- a/browser/devtools/webconsole/test/head.js
+++ b/browser/devtools/webconsole/test/head.js
@@ -1469,17 +1469,18 @@ function checkOutputForInputs(hud, input
         text: entry.output,
         category: CATEGORY_WEBDEV,
         severity: SEVERITY_LOG,
       }],
     });
 
     if (typeof entry.inspectorIcon == "boolean") {
       let msg = [...result.matched][0];
-      yield checkLinkToInspector(entry, msg);
+      info("Checking Inspector Link: " + entry.input);
+      yield checkLinkToInspector(entry.inspectorIcon, msg);
     }
   }
 
   function checkPrintOutput(entry)
   {
     info("Printing: " + entry.input);
     hud.jsterm.clearOutput();
     hud.jsterm.execute("print(" + entry.input + ")");
@@ -1511,17 +1512,18 @@ function checkOutputForInputs(hud, input
       }],
     });
 
     let msg = [...result.matched][0];
     if (!entry.noClick) {
       yield checkObjectClick(entry, msg);
     }
     if (typeof entry.inspectorIcon == "boolean") {
-      yield checkLinkToInspector(entry, msg);
+      info("Checking Inspector Link: " + entry.input);
+      yield checkLinkToInspector(entry.inspectorIcon, msg);
     }
   }
 
   function* checkObjectClick(entry, msg)
   {
     info("Clicking: " + entry.input);
     let body = msg.querySelector(".message-body a") ||
                msg.querySelector(".message-body");
@@ -1551,40 +1553,16 @@ function checkOutputForInputs(hud, input
     } else {
       container.removeEventListener("TabOpen", entry._onTabOpen, true);
       entry._onTabOpen = null;
     }
 
     yield promise.resolve(null);
   }
 
-  function checkLinkToInspector(entry, msg)
-  {
-    info("Checking Inspector Link: " + entry.input);
-    let elementNodeWidget = [...msg._messageObject.widgets][0];
-    if (!elementNodeWidget) {
-      ok(!entry.inspectorIcon, "The message has no ElementNode widget");
-      return;
-    }
-
-    return elementNodeWidget.linkToInspector().then(() => {
-      // linkToInspector resolved, check for the .open-inspector element
-      if (entry.inspectorIcon) {
-        ok(msg.querySelectorAll(".open-inspector").length,
-          "The ElementNode widget is linked to the inspector");
-      } else {
-        ok(!msg.querySelectorAll(".open-inspector").length,
-          "The ElementNode widget isn't linked to the inspector");
-      }
-    }, () => {
-      // linkToInspector promise rejected, node not linked to inspector
-      ok(!entry.inspectorIcon, "The ElementNode widget isn't linked to the inspector");
-    });
-  }
-
   function onVariablesViewOpen(entry, {resolve, reject}, event, view, options)
   {
     info("Variables view opened: " + entry.input);
     let label = entry.variablesViewLabel || entry.output;
     if (typeof label == "string" && options.label != label) {
       return;
     }
     if (label instanceof RegExp && !label.test(options.label)) {
@@ -1641,16 +1619,46 @@ function once(target, eventName, useCapt
       }, useCapture);
       break;
     }
   }
 
   return deferred.promise;
 }
 
+/**
+ * Checks a link to the inspector
+ *
+ * @param {boolean} hasLinkToInspector Set to true if the message should
+ *  link to the inspector panel.
+ * @param {element} msg The message to test.
+ */
+function checkLinkToInspector(hasLinkToInspector, msg)
+{
+  let elementNodeWidget = [...msg._messageObject.widgets][0];
+  if (!elementNodeWidget) {
+    ok(!hasLinkToInspector, "The message has no ElementNode widget");
+    return;
+  }
+
+  return elementNodeWidget.linkToInspector().then(() => {
+    // linkToInspector resolved, check for the .open-inspector element
+    if (hasLinkToInspector) {
+      ok(msg.querySelectorAll(".open-inspector").length,
+        "The ElementNode widget is linked to the inspector");
+    } else {
+      ok(!msg.querySelectorAll(".open-inspector").length,
+        "The ElementNode widget isn't linked to the inspector");
+    }
+  }, () => {
+    // linkToInspector promise rejected, node not linked to inspector
+    ok(!hasLinkToInspector, "The ElementNode widget isn't linked to the inspector");
+  });
+}
+
 function getSourceActor(aSources, aURL) {
   let item = aSources.getItemForAttachment(a => a.source.url === aURL);
   return item && item.value;
 }
 
 /**
  * Verify that clicking on a link from a popup notification message tries to
  * open the expected URL.
--- a/browser/devtools/webconsole/test/test-console-extras.html
+++ b/browser/devtools/webconsole/test/test-console-extras.html
@@ -1,17 +1,17 @@
 <!DOCTYPE HTML>
 <html dir="ltr" xml:lang="en-US" lang="en-US"><head>
     <meta charset="utf-8">
     <title>Console extended API test</title>
     <script type="text/javascript">
       function test() {
         console.log("start");
         console.clear()
-        console.dirxml()
+        console.timeStamp()
         console.log("end");
       }
     </script>
   </head>
   <body>
     <h1 id="header">Heads Up Display Demo</h1>
     <button onclick="test();">Test Extended API</button>
     <div id="myDiv"></div>
--- a/browser/devtools/webconsole/webconsole.js
+++ b/browser/devtools/webconsole/webconsole.js
@@ -125,16 +125,17 @@ const LEVELS = {
   assert: SEVERITY_ERROR,
   warn: SEVERITY_WARNING,
   info: SEVERITY_INFO,
   log: SEVERITY_LOG,
   trace: SEVERITY_LOG,
   table: SEVERITY_LOG,
   debug: SEVERITY_LOG,
   dir: SEVERITY_LOG,
+  dirxml: SEVERITY_LOG,
   group: SEVERITY_LOG,
   groupCollapsed: SEVERITY_LOG,
   groupEnd: SEVERITY_LOG,
   time: SEVERITY_LOG,
   timeEnd: SEVERITY_LOG,
   count: SEVERITY_LOG
 };
 
@@ -1280,17 +1281,21 @@ WebConsoleFrame.prototype = {
         body = { arguments: args };
         let clipboardArray = [];
         args.forEach((aValue) => {
           clipboardArray.push(VariablesView.getString(aValue));
         });
         clipboardText = clipboardArray.join(" ");
         break;
       }
-
+      case "dirxml": {
+        // We just alias console.dirxml() with console.log().
+        aMessage.level = "log";
+        return WCF_logConsoleAPIMessage.call(this, aMessage);
+      }
       case "group":
       case "groupCollapsed":
         clipboardText = body = aMessage.groupName;
         this.groupDepth++;
         break;
 
       case "groupEnd":
         if (this.groupDepth > 0) {
--- a/dom/base/Console.cpp
+++ b/dom/base/Console.cpp
@@ -809,16 +809,17 @@ void
 Console::Trace(JSContext* aCx)
 {
   const Sequence<JS::Value> data;
   Method(aCx, MethodTrace, NS_LITERAL_STRING("trace"), data);
 }
 
 // Displays an interactive listing of all the properties of an object.
 METHOD(Dir, "dir");
+METHOD(Dirxml, "dirxml");
 
 METHOD(Group, "group")
 METHOD(GroupCollapsed, "groupCollapsed")
 METHOD(GroupEnd, "groupEnd")
 
 void
 Console::Time(JSContext* aCx, const JS::Handle<JS::Value> aTime)
 {
--- a/dom/base/Console.h
+++ b/dom/base/Console.h
@@ -70,16 +70,19 @@ public:
 
   void
   Trace(JSContext* aCx);
 
   void
   Dir(JSContext* aCx, const Sequence<JS::Value>& aData);
 
   void
+  Dirxml(JSContext* aCx, const Sequence<JS::Value>& aData);
+
+  void
   Group(JSContext* aCx, const Sequence<JS::Value>& aData);
 
   void
   GroupCollapsed(JSContext* aCx, const Sequence<JS::Value>& aData);
 
   void
   GroupEnd(JSContext* aCx, const Sequence<JS::Value>& aData);
 
@@ -111,16 +114,17 @@ private:
     MethodInfo,
     MethodWarn,
     MethodError,
     MethodException,
     MethodDebug,
     MethodTable,
     MethodTrace,
     MethodDir,
+    MethodDirxml,
     MethodGroup,
     MethodGroupCollapsed,
     MethodGroupEnd,
     MethodTime,
     MethodTimeEnd,
     MethodAssert,
     MethodCount
   };
--- a/dom/webidl/Console.webidl
+++ b/dom/webidl/Console.webidl
@@ -11,34 +11,33 @@ interface Console {
   void info(any... data);
   void warn(any... data);
   void error(any... data);
   void _exception(any... data);
   void debug(any... data);
   void table(any... data);
   void trace();
   void dir(any... data);
+  void dirxml(any... data);
   void group(any... data);
   void groupCollapsed(any... data);
   void groupEnd(any... data);
   void time(optional any time);
   void timeEnd(optional any time);
 
   void profile(any... data);
   void profileEnd(any... data);
 
   void assert(boolean condition, any... data);
   void count(any... data);
 
   // No-op methods for compatibility with other browsers.
   [BinaryName="noopMethod"]
   void clear();
   [BinaryName="noopMethod"]
-  void dirxml();
-  [BinaryName="noopMethod"]
   void markTimeline();
   [BinaryName="noopMethod"]
   void timeline();
   [BinaryName="noopMethod"]
   void timelineEnd();
   [BinaryName="noopMethod"]
   void timeStamp();
 };