Bug 1005870 - Adding a copy() command to the console;r=robcee
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Wed, 04 Feb 2015 18:53:40 -0800
changeset 227572 a18bcb21d735f295b2079d8d6fe9086892459f75
parent 227571 f24e06712083923d06ef01746219a2b90b2a3fc9
child 227573 e31a48f67a62d7e7f4a387108be705b1a575338d
push id28234
push usercbook@mozilla.com
push dateThu, 05 Feb 2015 13:37:15 +0000
treeherdermozilla-central@759ee85bf3f0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrobcee
bugs1005870
milestone38.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 1005870 - Adding a copy() command to the console;r=robcee
browser/devtools/webconsole/test/browser.ini
browser/devtools/webconsole/test/browser_console_copy_command.js
browser/devtools/webconsole/webconsole.js
toolkit/devtools/webconsole/utils.js
--- a/browser/devtools/webconsole/test/browser.ini
+++ b/browser/devtools/webconsole/test/browser.ini
@@ -139,16 +139,17 @@ skip-if = e10s # Bug 1042253 - webconsol
 skip-if = e10s # Bug 1042253 - webconsole e10s tests (intermittent Linux debug)
 [browser_cached_messages.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 1042253 - webconsole e10s tests (expectUncaughtException)
 [browser_console.js]
 [browser_console_addonsdk_loader_exception.js]
 [browser_console_clear_on_reload.js]
 [browser_console_click_focus.js]
 [browser_console_consolejsm_output.js]
+[browser_console_copy_command.js]
 [browser_console_dead_objects.js]
 skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
 [browser_console_copy_entire_message_context_menu.js]
 [browser_console_error_source_click.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 1042253 - webconsole e10s tests
 [browser_console_filters.js]
 [browser_console_iframe_messages.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 1042253 - webconsole e10s tests
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/browser_console_copy_command.js
@@ -0,0 +1,70 @@
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Tests that the `copy` console helper works as intended.
+
+let gWebConsole, gJSTerm;
+
+let TEXT =  "Lorem ipsum dolor sit amet, consectetur adipisicing " +
+    "elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
+    "aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
+    "laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
+    "dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
+    "fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
+    "proident, sunt in culpa qui officia deserunt mollit anim id est laborum." +
+    new Date();
+
+let ID = "select-me";
+
+add_task(function* init() {
+  yield loadTab("data:text/html;charset=utf-8," +
+                "<body>" +
+                "  <div>" +
+                "    <h1>Testing copy command</h1>" +
+                "    <p>This is some example text</p>" +
+                "    <p id='select-me'>"+TEXT+"</p>" +
+                "  </div>" +
+                "  <div><p></p></div>" +
+                "</body>");
+
+  gWebConsole = yield openConsole();
+  gJSTerm = gWebConsole.jsterm;
+});
+
+add_task(function* test_copy() {
+  let RANDOM = Math.random();
+  let string = "Text: " + RANDOM;
+  let obj = {a: 1, b: "foo", c: RANDOM};
+
+  let samples = [[RANDOM, RANDOM],
+                 [JSON.stringify(string), string],
+                 [obj.toSource(),  JSON.stringify(obj, null, "  ")],
+                 ["$('#" + ID + "')", content.document.getElementById(ID).outerHTML]
+                ];
+  for (let [source, reference] of samples) {
+    let deferredResult = promise.defer();
+
+    SimpleTest.waitForClipboard(
+      "" + reference,
+      () => {
+        let command = "copy(" + source + ")";
+        info("Attempting to copy: " + source);
+        info("Executing command: " + command);
+        gJSTerm.execute(command, msg => {
+          is(msg, undefined, "Command success: " + command);
+        });
+      },
+      deferredResult.resolve,
+      deferredResult.reject);
+
+    yield deferredResult.promise;
+  }
+});
+
+add_task(function* cleanup() {
+  gWebConsole = gJSTerm = null;
+  gBrowser.removeTab(gBrowser.selectedTab);
+  finishTest();
+});
--- a/browser/devtools/webconsole/webconsole.js
+++ b/browser/devtools/webconsole/webconsole.js
@@ -3277,16 +3277,19 @@ JSTerm.prototype = {
           }
           catch (ex) {
             errorMessage = helperResult.message;
           }
           break;
         case "help":
           this.hud.owner.openLink(HELP_URL);
           break;
+        case "copyValueToClipboard":
+          clipboardHelper.copyString(helperResult.value);
+          break;
       }
     }
 
     // Hide undefined results coming from JSTerm helper functions.
     if (!errorMessage && result && typeof result == "object" &&
         result.type == "undefined" &&
         helperResult && !helperHasRawOutput) {
       aCallback && aCallback();
--- a/toolkit/devtools/webconsole/utils.js
+++ b/toolkit/devtools/webconsole/utils.js
@@ -1747,16 +1747,43 @@ function JSTermHelpers(aOwner)
       return Symbol.prototype.toString.call(aValue);
     }
     // Waiving Xrays here allows us to see a closer representation of the
     // underlying object. This may execute arbitrary content code, but that
     // code will run with content privileges, and the result will be rendered
     // inert by coercing it to a String.
     return String(Cu.waiveXrays(aValue));
   };
+
+  /**
+   * Copy the String representation of a value to the clipboard.
+   *
+   * @param any aValue
+   *        A value you want to copy as a string.
+   * @return void
+   */
+  aOwner.sandbox.copy = function JSTH_copy(aValue)
+  {
+    let payload;
+    try {
+      if (aValue instanceof Ci.nsIDOMElement) {
+        payload = aValue.outerHTML;
+      } else if (typeof aValue == "string") {
+        payload = aValue;
+      } else {
+        payload = JSON.stringify(aValue, null, "  ");
+      }
+    } catch (ex) {
+      payload = "/* " + ex  + " */";
+    }
+    aOwner.helperResult = {
+      type: "copyValueToClipboard",
+      value: payload,
+    };
+  };
 }
 exports.JSTermHelpers = JSTermHelpers;
 
 
 /**
  * A ReflowObserver that listens for reflow events from the page.
  * Implements nsIReflowObserver.
  *