Bug 1290230 - move clipboard helper to new devtools platform module; r?gregtatum draft
authorTom Tromey <tom@tromey.com>
Fri, 12 Aug 2016 12:52:40 -0600
changeset 403334 f31f6f649c8170d80b7f6b738ce64c0956fc7716
parent 403333 8dfc2fdb7ae3990b73f8207aaf62de68a4f47bf5
child 528874 2797f1467c9a51693f91c74c7b855787e88d1915
push id26878
push userbmo:ttromey@mozilla.com
push dateFri, 19 Aug 2016 14:05:10 +0000
reviewersgregtatum
bugs1290230
milestone51.0a1
Bug 1290230 - move clipboard helper to new devtools platform module; r?gregtatum MozReview-Commit-ID: 53tOehW9kxo
devtools/client/inspector/computed/computed.js
devtools/client/inspector/inspector-panel.js
devtools/client/inspector/markup/markup.js
devtools/client/inspector/rules/rules.js
devtools/client/inspector/shared/style-inspector-menu.js
devtools/shared/platform/chrome/clipboard.js
devtools/shared/platform/chrome/moz.build
devtools/shared/platform/content/clipboard.js
devtools/shared/platform/content/moz.build
devtools/shared/platform/content/test/mochitest.ini
devtools/shared/platform/content/test/test_clipboard.html
--- a/devtools/client/inspector/computed/computed.js
+++ b/devtools/client/inspector/computed/computed.js
@@ -3,20 +3,16 @@
 /* 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/. */
 
 /* globals StopIteration */
 
 "use strict";
 
-/* eslint-disable mozilla/reject-some-requires */
-const {Cc, Ci} = require("chrome");
-/* eslint-enable mozilla/reject-some-requires */
-
 const ToolDefinitions = require("devtools/client/definitions").Tools;
 const CssLogic = require("devtools/shared/inspector/css-logic");
 const {ELEMENT_STYLE} = require("devtools/shared/specs/styles");
 const promise = require("promise");
 const defer = require("devtools/shared/defer");
 const Services = require("Services");
 const {OutputParser} = require("devtools/client/shared/output-parser");
 const {PrefObserver, PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
@@ -26,30 +22,26 @@ const {gDevTools} = require("devtools/cl
 const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
 /* eslint-enable mozilla/reject-some-requires */
 const {getCssProperties} = require("devtools/shared/fronts/css-properties");
 
 const overlays = require("devtools/client/inspector/shared/style-inspector-overlays");
 const StyleInspectorMenu = require("devtools/client/inspector/shared/style-inspector-menu");
 const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
 const {LayoutView} = require("devtools/client/inspector/layout/layout");
+const clipboardHelper = require("devtools/shared/platform/clipboard");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
                                   "resource://gre/modules/PluralForm.jsm");
 
 XPCOMUtils.defineLazyGetter(CssComputedView, "_strings", function () {
   return Services.strings.createBundle(
     "chrome://devtools-shared/locale/styleinspector.properties");
 });
 
-XPCOMUtils.defineLazyGetter(this, "clipboardHelper", function () {
-  return Cc["@mozilla.org/widget/clipboardhelper;1"]
-         .getService(Ci.nsIClipboardHelper);
-});
-
 const FILTER_CHANGED_TIMEOUT = 150;
 const HTML_NS = "http://www.w3.org/1999/xhtml";
 
 /**
  * Helper for long-running processes that should yield occasionally to
  * the mainloop.
  *
  * @param {Window} win
--- a/devtools/client/inspector/inspector-panel.js
+++ b/devtools/client/inspector/inspector-panel.js
@@ -1,25 +1,20 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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/. */
 
 "use strict";
 
-/* eslint-disable mozilla/reject-some-requires */
-const {Cc, Ci} = require("chrome");
-/* eslint-enable mozilla/reject-some-requires */
-
 var Services = require("Services");
 var promise = require("promise");
 var defer = require("devtools/shared/defer");
 var EventEmitter = require("devtools/shared/event-emitter");
-var clipboard = require("sdk/clipboard");
 const {executeSoon} = require("devtools/shared/DevToolsUtils");
 var {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
 var {Task} = require("devtools/shared/task");
 const {initCssProperties} = require("devtools/shared/fronts/css-properties");
 const nodeConstants = require("devtools/shared/dom-node-constants");
 const Telemetry = require("devtools/client/shared/telemetry");
 
 const Menu = require("devtools/client/framework/menu");
@@ -29,26 +24,24 @@ const {CommandUtils} = require("devtools
 const {ComputedViewTool} = require("devtools/client/inspector/computed/computed");
 const {FontInspector} = require("devtools/client/inspector/fonts/fonts");
 const {HTMLBreadcrumbs} = require("devtools/client/inspector/breadcrumbs");
 const {InspectorSearch} = require("devtools/client/inspector/inspector-search");
 const {MarkupView} = require("devtools/client/inspector/markup/markup");
 const {RuleViewTool} = require("devtools/client/inspector/rules/rules");
 const {ToolSidebar} = require("devtools/client/inspector/toolsidebar");
 const {ViewHelpers} = require("devtools/client/shared/widgets/view-helpers");
+const clipboardHelper = require("devtools/shared/platform/clipboard");
 
 loader.lazyGetter(this, "strings", () => {
   return Services.strings.createBundle("chrome://devtools/locale/inspector.properties");
 });
 loader.lazyGetter(this, "toolboxStrings", () => {
   return Services.strings.createBundle("chrome://devtools/locale/toolbox.properties");
 });
-loader.lazyGetter(this, "clipboardHelper", () => {
-  return Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
-});
 
 /**
  * Represents an open instance of the Inspector for a tab.
  * The inspector controls the breadcrumbs, the markup view, and the sidebar
  * (computed view, rule view, font view and layout view).
  *
  * Events:
  * - ready
@@ -823,20 +816,20 @@ InspectorPanel.prototype = {
     return this._panelDestroyer;
   },
 
   /**
    * Returns the clipboard content if it is appropriate for pasting
    * into the current node's outer HTML, otherwise returns null.
    */
   _getClipboardContentForPaste: function () {
-    let flavors = clipboard.currentFlavors;
+    let flavors = clipboardHelper.getCurrentFlavors();
     if (flavors.indexOf("text") != -1 ||
         (flavors.indexOf("html") != -1 && flavors.indexOf("image") == -1)) {
-      let content = clipboard.get();
+      let content = clipboardHelper.getData();
       if (content && content.trim().length > 0) {
         return content;
       }
     }
     return null;
   },
 
   _onContextMenu: function (e) {
--- a/devtools/client/inspector/markup/markup.js
+++ b/devtools/client/inspector/markup/markup.js
@@ -2,20 +2,16 @@
 /* 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/. */
 /* globals template */
 
 "use strict";
 
-/* eslint-disable mozilla/reject-some-requires */
-const {Cc, Ci} = require("chrome");
-/* eslint-enable mozilla/reject-some-requires */
-
 // Page size for pageup/pagedown
 const PAGE_SIZE = 10;
 const DEFAULT_MAX_CHILDREN = 100;
 const COLLAPSE_DATA_URL_REGEX = /^data.+base64/;
 const COLLAPSE_DATA_URL_LENGTH = 60;
 const NEW_SELECTION_HIGHLIGHTER_TIMER = 1000;
 const DRAG_DROP_AUTOSCROLL_EDGE_MAX_DISTANCE = 50;
 const DRAG_DROP_AUTOSCROLL_EDGE_RATIO = 0.1;
@@ -58,16 +54,17 @@ const nodeConstants = require("devtools/
 const nodeFilterConstants = require("devtools/shared/dom-node-filter-constants");
 /* eslint-disable mozilla/reject-some-requires */
 const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
 /* eslint-enable mozilla/reject-some-requires */
 const {getCssProperties} = require("devtools/shared/fronts/css-properties");
 const {KeyCodes} = require("devtools/client/shared/keycodes");
 
 const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup");
+const clipboardHelper = require("devtools/shared/platform/clipboard");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
   "resource://gre/modules/PluralForm.jsm");
 
 /**
  * Vocabulary for the purposes of this file:
  *
  * MarkupContainer - the structure that holds an editor and its
@@ -3618,14 +3615,9 @@ function getAutocompleteMaxWidth(element
   let containerRect = container.getBoundingClientRect();
   return containerRect.right - elementRect.left - 2;
 }
 
 loader.lazyGetter(MarkupView.prototype, "strings", () => Services.strings.createBundle(
   "chrome://devtools/locale/inspector.properties"
 ));
 
-XPCOMUtils.defineLazyGetter(this, "clipboardHelper", function () {
-  return Cc["@mozilla.org/widget/clipboardhelper;1"]
-    .getService(Ci.nsIClipboardHelper);
-});
-
 exports.MarkupView = MarkupView;
--- a/devtools/client/inspector/rules/rules.js
+++ b/devtools/client/inspector/rules/rules.js
@@ -2,19 +2,16 @@
 /* vim: set 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/. */
 /* globals gDevTools */
 
 "use strict";
 
-/* eslint-disable mozilla/reject-some-requires */
-const {Cc, Ci} = require("chrome");
-/* eslint-enable mozilla/reject-some-requires */
 const promise = require("promise");
 const defer = require("devtools/shared/defer");
 const Services = require("Services");
 /* eslint-disable mozilla/reject-some-requires */
 const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
 /* eslint-enable mozilla/reject-some-requires */
 const {Task} = require("devtools/shared/task");
 const {Tools} = require("devtools/client/definitions");
@@ -28,21 +25,17 @@ const {RuleEditor} = require("devtools/c
 const {createChild, promiseWarn, throttle} = require("devtools/client/inspector/shared/utils");
 const {gDevTools} = require("devtools/client/framework/devtools");
 const {getCssProperties} = require("devtools/shared/fronts/css-properties");
 
 const overlays = require("devtools/client/inspector/shared/style-inspector-overlays");
 const EventEmitter = require("devtools/shared/event-emitter");
 const StyleInspectorMenu = require("devtools/client/inspector/shared/style-inspector-menu");
 const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts");
-
-XPCOMUtils.defineLazyGetter(this, "clipboardHelper", function () {
-  return Cc["@mozilla.org/widget/clipboardhelper;1"]
-    .getService(Ci.nsIClipboardHelper);
-});
+const clipboardHelper = require("devtools/shared/platform/clipboard");
 
 XPCOMUtils.defineLazyGetter(this, "_strings", function () {
   return Services.strings.createBundle(
     "chrome://devtools-shared/locale/styleinspector.properties");
 });
 
 const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup");
 
--- a/devtools/client/inspector/shared/style-inspector-menu.js
+++ b/devtools/client/inspector/shared/style-inspector-menu.js
@@ -10,18 +10,17 @@
 const {PREF_ORIG_SOURCES} = require("devtools/client/styleeditor/utils");
 const Services = require("Services");
 const {Task} = require("devtools/shared/task");
 
 const Menu = require("devtools/client/framework/menu");
 const MenuItem = require("devtools/client/framework/menu-item");
 
 const overlays = require("devtools/client/inspector/shared/style-inspector-overlays");
-loader.lazyServiceGetter(this, "clipboardHelper",
-  "@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
+const clipboardHelper = require("devtools/shared/platform/clipboard");
 loader.lazyGetter(this, "_strings", () => {
   return Services.strings
   .createBundle("chrome://devtools-shared/locale/styleinspector.properties");
 });
 
 const PREF_ENABLE_MDN_DOCS_TOOLTIP =
   "devtools.inspector.mdnDocsTooltip.enabled";
 
new file mode 100644
--- /dev/null
+++ b/devtools/shared/platform/chrome/clipboard.js
@@ -0,0 +1,28 @@
+/* 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/. */
+
+// Helpers for clipboard handling.
+
+"use strict";
+
+const {Cc, Ci} = require("chrome");
+const clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"]
+      .getService(Ci.nsIClipboardHelper);
+var clipboard = require("sdk/clipboard");
+
+function copyString(string) {
+  clipboardHelper.copyString(string);
+}
+
+function getCurrentFlavors() {
+  return clipboard.currentFlavors;
+}
+
+function getData() {
+  return clipboard.get();
+}
+
+exports.copyString = copyString;
+exports.getCurrentFlavors = getCurrentFlavors;
+exports.getData = getData;
--- a/devtools/shared/platform/chrome/moz.build
+++ b/devtools/shared/platform/chrome/moz.build
@@ -1,9 +1,10 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 DevToolsModules(
+    'clipboard.js',
     'stack.js',
 )
new file mode 100644
--- /dev/null
+++ b/devtools/shared/platform/content/clipboard.js
@@ -0,0 +1,34 @@
+/* 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/. */
+
+// Helpers for clipboard handling.
+
+/* globals document */
+
+"use strict";
+
+function copyString(string) {
+  let doCopy = function (e) {
+    e.clipboardData.setData("text/plain", string);
+    e.preventDefault();
+  };
+
+  document.addEventListener("copy", doCopy);
+  document.execCommand("copy", false, null);
+  document.removeEventListener("copy", doCopy);
+}
+
+function getCurrentFlavors() {
+  // See bug 1295692.
+  return [];
+}
+
+function getData() {
+  // See bug 1295692.
+  return null;
+}
+
+exports.copyString = copyString;
+exports.getCurrentFlavors = getCurrentFlavors;
+exports.getData = getData;
--- a/devtools/shared/platform/content/moz.build
+++ b/devtools/shared/platform/content/moz.build
@@ -1,11 +1,16 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 DevToolsModules(
+    'clipboard.js',
     'stack.js',
 )
 
 XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell.ini']
+
+MOCHITEST_MANIFESTS += [
+    'test/mochitest.ini',
+]
new file mode 100644
--- /dev/null
+++ b/devtools/shared/platform/content/test/mochitest.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+support-files =
+
+[test_clipboard.html]
new file mode 100644
--- /dev/null
+++ b/devtools/shared/platform/content/test/test_clipboard.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1290230
+-->
+<head>
+  <title>Test for Bug 1290230 - clipboard helpers</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css">
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+
+<script type="application/javascript;version=1.8">
+"use strict";
+var exports = {}
+</script>
+
+  <script type="application/javascript;version=1.8"
+	  src="resource://devtools/shared/platform/content/clipboard.js"></script>
+
+</head>
+<body onload="do_tests()">
+<script type="application/javascript;version=1.8">
+"use strict";
+
+const RESULT = "lark bunting";
+
+function doCopy(e) {
+  console.log(e.isTrusted);
+  copyString(RESULT);
+}
+
+function do_tests() {
+  let elt = document.querySelector("#key");
+  elt.addEventListener("keydown", doCopy);
+
+  // Set the clipboard to something other than what we expect.
+  SpecialPowers.clipboardCopyString("snowy owl");
+
+  elt.focus();
+  synthesizeKey("x", {});
+
+  is(SpecialPowers.getClipboardData("text/unicode"), RESULT, "clipboard copying worked");
+
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+<div id="key" tabindex="-1">Type Here</div>
+</body>