Bug 1200551 - Handle multiple %c formatters without a string between them by using only the last one for styling;r=baku,r=past
authorBrian Grinstead <bgrinstead@mozilla.com>
Fri, 11 Sep 2015 07:44:06 -0700
changeset 294735 ea0f3fa6453fc3c1555fd1b6dd8427834ca279f6
parent 294734 a5940e145cf88632a410b3a44a15158dc2dd31d9
child 294736 c1a90db05a54452f615de6a62d5a61337e86d545
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, past
bugs1200551
milestone43.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 1200551 - Handle multiple %c formatters without a string between them by using only the last one for styling;r=baku,r=past
dom/base/Console.cpp
toolkit/devtools/webconsole/test/chrome.ini
toolkit/devtools/webconsole/test/test_console_styling.html
--- a/dom/base/Console.cpp
+++ b/dom/base/Console.cpp
@@ -1502,16 +1502,22 @@ Console::ProcessArguments(JSContext* aCx
           return false;
         }
 
         break;
       }
 
       case 'c':
       {
+        // If there isn't any output but there's already a style, then
+        // discard the previous style and use the next one instead.
+        if (output.IsEmpty() && !aStyles.IsEmpty()) {
+          aStyles.TruncateLength(aStyles.Length() - 1);
+        }
+
         if (!FlushOutput(aCx, aSequence, output)) {
           return false;
         }
 
         if (index < aData.Length()) {
           JS::Rooted<JS::Value> v(aCx, aData[index++]);
           JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, v));
           if (!jsString) {
--- a/toolkit/devtools/webconsole/test/chrome.ini
+++ b/toolkit/devtools/webconsole/test/chrome.ini
@@ -10,16 +10,17 @@ support-files =
 
 [test_basics.html]
 [test_bug819670_getter_throws.html]
 [test_cached_messages.html]
 [test_commands_other.html]
 [test_commands_registration.html]
 [test_consoleapi.html]
 [test_consoleapi_innerID.html]
+[test_console_styling.html]
 [test_file_uri.html]
 [test_reflow.html]
 [test_jsterm.html]
 [test_jsterm_cd_iframe.html]
 [test_jsterm_last_result.html]
 [test_jsterm_queryselector.html]
 [test_network_get.html]
 [test_network_longstring.html]
new file mode 100644
--- /dev/null
+++ b/toolkit/devtools/webconsole/test/test_console_styling.html
@@ -0,0 +1,126 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+  <meta charset="utf8">
+  <title>Test for console.log styling with %c</title>
+  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript;version=1.8" src="common.js"></script>
+  <!-- Any copyright is dedicated to the Public Domain.
+     - http://creativecommons.org/publicdomain/zero/1.0/ -->
+</head>
+<body>
+<p>Test for console.log styling with %c</p>
+
+<script class="testbody" type="text/javascript;version=1.8">
+SimpleTest.waitForExplicitFinish();
+
+let expectedConsoleCalls = [];
+
+function doConsoleCalls(aState)
+{
+  top.console.log("%cOne formatter with no styles");
+  top.console.log("%cOne formatter", "color: red");
+  top.console.log("%cTwo formatters%cEach with an arg",
+    "color: red", "background: red");
+  top.console.log("%c%cTwo formatters next to each other",
+    "color: red", "background: red");
+  top.console.log("%c%c%cThree formatters next to each other",
+    "color: red", "background: red", "font-size: 150%");
+  top.console.log("%c%cTwo formatters%cWith a third separated",
+    "color: red", "background: red", "font-size: 150%");
+  top.console.log("%cOne formatter", "color: red",
+                  "Second arg with no styles");
+  top.console.log("%cOne formatter", "color: red",
+                  "%cSecond formatter is ignored", "background: blue")
+
+  expectedConsoleCalls = [
+    {
+      level: "log",
+      styles: /^$/,
+      arguments: ["%cOne formatter with no styles"],
+    },
+    {
+      level: "log",
+      styles: /^color: red$/,
+      arguments: ["One formatter"],
+    },
+    {
+      level: "log",
+      styles: /^color: red,background: red$/,
+      arguments: ["Two formatters", "Each with an arg"],
+    },
+    {
+      level: "log",
+      styles: /^background: red$/,
+      arguments: ["Two formatters next to each other"],
+    },
+    {
+      level: "log",
+      styles: /^font-size: 150%$/,
+      arguments: ["Three formatters next to each other"],
+    },
+    {
+      level: "log",
+      styles: /^background: red,font-size: 150%$/,
+      arguments: ["Two formatters", "With a third separated"],
+    },
+    {
+      level: "log",
+      styles: /^color: red$/,
+      arguments: ["One formatter", "Second arg with no styles"],
+    },
+    {
+      level: "log",
+      styles: /^color: red$/,
+      arguments: ["One formatter",
+                  "%cSecond formatter is ignored",
+                  "background: blue"],
+    },
+  ];
+}
+
+function startTest()
+{
+  removeEventListener("load", startTest);
+
+  attachConsole(["ConsoleAPI"], onAttach, true);
+}
+
+function onAttach(aState, aResponse)
+{
+  onConsoleAPICall = onConsoleAPICall.bind(null, aState);
+  aState.dbgClient.addListener("consoleAPICall", onConsoleAPICall);
+  doConsoleCalls(aState.actor);
+}
+
+let consoleCalls = [];
+
+function onConsoleAPICall(aState, aType, aPacket)
+{
+  info("received message level: " + aPacket.message.level);
+  is(aPacket.from, aState.actor, "console API call actor");
+
+  consoleCalls.push(aPacket.message);
+  if (consoleCalls.length != expectedConsoleCalls.length) {
+    return;
+  }
+
+  aState.dbgClient.removeListener("consoleAPICall", onConsoleAPICall);
+
+  expectedConsoleCalls.forEach(function(aMessage, aIndex) {
+    info("checking received console call #" + aIndex);
+    checkConsoleAPICall(consoleCalls[aIndex], expectedConsoleCalls[aIndex]);
+  });
+
+
+  consoleCalls = [];
+
+  closeDebugger(aState, function() {
+    SimpleTest.finish();
+  });
+}
+
+addEventListener("load", startTest);
+</script>
+</body>
+</html>