Backed out changeset 2a040986845d (bug 1071562) for bustage.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 10 Apr 2015 13:14:33 -0400
changeset 270064 40bc31482401bccc71ccaffd3d5a2e1b362d97d0
parent 270063 2a040986845da97f1eaf87c33136d9168817606a
child 270065 1064927c1469400ee0adc983056e8cfd314f15b6
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)
bugs1071562
milestone40.0a1
backs out2a040986845da97f1eaf87c33136d9168817606a
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
Backed out changeset 2a040986845d (bug 1071562) for bustage. CLOSED TREE
browser/base/content/test/general/browser.ini
browser/base/content/test/general/browser_clipboard.js
dom/base/moz.build
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/DOMTypes.ipdlh
dom/ipc/PContent.ipdl
widget/nsClipboardProxy.cpp
widget/nsDragServiceProxy.cpp
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -290,17 +290,16 @@ skip-if = buildapp == "mulet" || e10s # 
 [browser_bug970746.js]
 skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
 [browser_bug1015721.js]
 skip-if = os == 'win' || e10s # Bug 1056146 - zoom tests use FullZoomHelper and break in e10s
 [browser_bug1064280_changeUrlInPinnedTab.js]
 [browser_bug1070778.js]
 [browser_canonizeURL.js]
 skip-if = e10s # Bug 1094510 - test hits the network in e10s mode only
-[browser_clipboard.js]
 [browser_contentAreaClick.js]
 skip-if = e10s
 [browser_contextSearchTabPosition.js]
 skip-if = os == "mac" || e10s # bug 967013; e10s: bug 1094761 - test hits the network in e10s, causing next test to crash
 [browser_ctrlTab.js]
 [browser_datareporting_notification.js]
 skip-if = !datareporting
 [browser_devedition.js]
deleted file mode 100644
--- a/browser/base/content/test/general/browser_clipboard.js
+++ /dev/null
@@ -1,123 +0,0 @@
-// This test is used to check copy and paste in editable areas to ensure that non-text
-// types (html and images) are copied to and pasted from the clipboard properly.
-
-let testPage = "<div id='main' contenteditable='true'>Test <b>Bold</b> After Text</div>";
-
-add_task(function*() {
-  let tab = gBrowser.addTab();
-  let browser = gBrowser.getBrowserForTab(tab);
-
-  gBrowser.selectedTab = tab;
-
-  yield promiseTabLoadEvent(tab, "data:text/html," + escape(testPage));
-  yield SimpleTest.promiseFocus(browser.contentWindowAsCPOW);
-
-  let results = yield ContentTask.spawn(browser, {}, function* () {
-    var doc = content.document;
-    var main = doc.getElementById("main");
-    main.focus();
-
-    const utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
-                         .getInterface(Components.interfaces.nsIDOMWindowUtils);
-
-    const modifier = (content.navigator.platform.indexOf("Mac") >= 0) ?
-                     Components.interfaces.nsIDOMWindowUtils.MODIFIER_META :
-                     Components.interfaces.nsIDOMWindowUtils.MODIFIER_CONTROL;
-
-    function sendKey(key)
-    {
-     if (utils.sendKeyEvent("keydown", key, 0, modifier)) {
-       utils.sendKeyEvent("keypress", key, key.charCodeAt(0), modifier);
-     }
-     utils.sendKeyEvent("keyup", key, 0, modifier);
-    }
-
-    let results = [];
-    function is(l, r, v) {
-      results.push(((l === r) ? "PASSED" : "FAILED") + " got: " + l + " expected: " + r + " - " + v);
-    }
-
-    // Select an area of the text.
-    let selection = doc.getSelection();
-    selection.modify("move", "left", "line");
-    selection.modify("move", "right", "character");
-    selection.modify("move", "right", "character");
-    selection.modify("move", "right", "character");
-    selection.modify("extend", "right", "word");
-    selection.modify("extend", "right", "word");
-
-    yield new content.Promise((resolve, reject) => {
-      addEventListener("copy", function copyEvent(event) {
-        removeEventListener("copy", copyEvent, true);
-        // The data is empty as the selection is copied during the event default phase.
-        is(event.clipboardData.mozItemCount, 0, "Zero items on clipboard");
-        resolve();
-      }, true)
-
-      sendKey("c");
-    });
-
-    selection.modify("move", "right", "line");
-
-    yield new content.Promise((resolve, reject) => {
-      addEventListener("paste", function copyEvent(event) {
-        removeEventListener("paste", copyEvent, true);
-        let clipboardData = event.clipboardData; 
-        is(clipboardData.mozItemCount, 1, "One item on clipboard");
-        is(clipboardData.types.length, 2, "Two types on clipboard");
-        is(clipboardData.types[0], "text/html", "text/html on clipboard");
-        is(clipboardData.types[1], "text/plain", "text/plain on clipboard");
-        is(clipboardData.getData("text/html"), "t <b>Bold</b>", "text/html value");
-        is(clipboardData.getData("text/plain"), "t Bold", "text/plain value");
-        resolve();
-      }, true)
-      sendKey("v");
-    });
-
-    is(main.innerHTML, "Test <b>Bold</b> After Textt <b>Bold</b>", "Copy and paste html");
-
-    selection.modify("extend", "left", "word");
-    selection.modify("extend", "left", "word");
-    selection.modify("extend", "left", "character");
-
-    yield new content.Promise((resolve, reject) => {
-      addEventListener("cut", function copyEvent(event) {
-        removeEventListener("cut", copyEvent, true);
-        event.clipboardData.setData("text/plain", "Some text");
-        event.clipboardData.setData("text/html", "<i>Italic</i> ");
-        selection.deleteFromDocument();
-        event.preventDefault();
-        resolve();
-      }, true)
-      sendKey("x");
-    });
-
-    selection.modify("move", "left", "line");
-
-    yield new content.Promise((resolve, reject) => {
-      addEventListener("paste", function copyEvent(event) {
-        removeEventListener("paste", copyEvent, true);
-        let clipboardData = event.clipboardData; 
-        is(clipboardData.mozItemCount, 1, "One item on clipboard 2");
-        is(clipboardData.types.length, 2, "Two types on clipboard 2");
-        is(clipboardData.types[0], "text/html", "text/html on clipboard 2");
-        is(clipboardData.types[1], "text/plain", "text/plain on clipboard 2");
-        is(clipboardData.getData("text/html"), "<i>Italic</i> ", "text/html value 2");
-        is(clipboardData.getData("text/plain"), "Some text", "text/plain value 2");
-        resolve();
-      }, true)
-      sendKey("v");
-    });
-
-    is(main.innerHTML, "<i>Italic</i> Test <b>Bold</b> After<b></b>", "Copy and paste html 2");
-    return results;
-  });
-
-  is(results.length, 15, "Correct number of results");
-  for (var t = 0; t < results.length; t++) {
-    ok(results[t].startsWith("PASSED"), results[t]);
-  }
-
-  gBrowser.removeCurrentTab();
-});
-
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -410,17 +410,16 @@ LOCAL_INCLUDES += [
     '/dom/ipc',
     '/dom/storage',
     '/dom/svg',
     '/dom/workers',
     '/dom/xbl',
     '/dom/xml',
     '/dom/xslt/xpath',
     '/dom/xul',
-    '/gfx/2d',
     '/image/src',
     '/js/xpconnect/src',
     '/js/xpconnect/wrappers',
     '/layout/base',
     '/layout/generic',
     '/layout/style',
     '/layout/svg',
     '/layout/xul',
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -166,17 +166,16 @@
 #include "nsParserCIID.h"
 #include "nsParserConstants.h"
 #include "nsPIDOMWindow.h"
 #include "nsPresContext.h"
 #include "nsPrintfCString.h"
 #include "nsReferencedElement.h"
 #include "nsSandboxFlags.h"
 #include "nsScriptSecurityManager.h"
-#include "nsStreamUtils.h"
 #include "nsSVGFeatures.h"
 #include "nsTextEditorState.h"
 #include "nsTextFragment.h"
 #include "nsTextNode.h"
 #include "nsThreadUtils.h"
 #include "nsUnicharUtilCIID.h"
 #include "nsUnicodeProperties.h"
 #include "nsViewManager.h"
@@ -7210,173 +7209,92 @@ nsContentUtils::CallOnAllRemoteChildren(
 
 void
 nsContentUtils::TransferablesToIPCTransferables(nsISupportsArray* aTransferables,
                                                 nsTArray<IPCDataTransfer>& aIPC,
                                                 mozilla::dom::nsIContentChild* aChild,
                                                 mozilla::dom::nsIContentParent* aParent)
 {
   aIPC.Clear();
+  MOZ_ASSERT((aChild && !aParent) || (!aChild && aParent));
   if (aTransferables) {
     uint32_t transferableCount = 0;
     aTransferables->Count(&transferableCount);
     for (uint32_t i = 0; i < transferableCount; ++i) {
       IPCDataTransfer* dt = aIPC.AppendElement();
       nsCOMPtr<nsISupports> genericItem;
       aTransferables->GetElementAt(i, getter_AddRefs(genericItem));
-      nsCOMPtr<nsITransferable> transferable(do_QueryInterface(genericItem));
-      TransferableToIPCTransferable(transferable, dt, aChild, aParent);
-    }
-  }
-}
-
-void
-nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
-                                              IPCDataTransfer* aIPCDataTransfer,
-                                              mozilla::dom::nsIContentChild* aChild,
-                                              mozilla::dom::nsIContentParent* aParent)
-{
-  MOZ_ASSERT((aChild && !aParent) || (!aChild && aParent));
-
-  if (aTransferable) {
-    nsCOMPtr<nsISupportsArray> flavorList;
-    aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
-    if (flavorList) {
-      uint32_t flavorCount = 0;
-      flavorList->Count(&flavorCount);
-      for (uint32_t j = 0; j < flavorCount; ++j) {
-        nsCOMPtr<nsISupportsCString> flavor = do_QueryElementAt(flavorList, j);
-        if (!flavor) {
-          continue;
-        }
-
-        nsAutoCString flavorStr;
-        flavor->GetData(flavorStr);
-        if (!flavorStr.Length()) {
-          continue;
-        }
-
-        nsCOMPtr<nsISupports> data;
-        uint32_t dataLen = 0;
-        aTransferable->GetTransferData(flavorStr.get(), getter_AddRefs(data), &dataLen);
-
-        nsCOMPtr<nsISupportsString> text = do_QueryInterface(data);
-        nsCOMPtr<nsISupportsCString> ctext = do_QueryInterface(data);
-        if (text) {
-          nsAutoString dataAsString;
-          text->GetData(dataAsString);
-          IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
-          item->flavor() = nsCString(flavorStr);
-          item->data() = nsString(dataAsString);
-        } else if (ctext) {
-          nsAutoCString dataAsString;
-          ctext->GetData(dataAsString);
-          IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
-          item->flavor() = nsCString(flavorStr);
-          item->data() = nsCString(dataAsString);
-        } else {
-          nsCOMPtr<nsISupportsInterfacePointer> sip =
-            do_QueryInterface(data);
-          if (sip) {
-            sip->GetData(getter_AddRefs(data));
-          }
-
-          // Images to be pasted on the clipboard are nsIInputStreams
-          nsCOMPtr<nsIInputStream> stream(do_QueryInterface(data));
-          if (stream) {
-            IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
-            item->flavor() = nsCString(flavorStr);
-
-            nsCString imageData;
-            NS_ConsumeStream(stream, UINT32_MAX, imageData);
-            item->data() = imageData;
-            continue;
-          }
-
-          // Images to be placed on the clipboard are imgIContainers.
-          nsCOMPtr<imgIContainer> image(do_QueryInterface(data));
-          if (image) {
-            RefPtr<mozilla::gfx::SourceSurface> surface =
-              image->GetFrame(imgIContainer::FRAME_CURRENT,
-                              imgIContainer::FLAG_SYNC_DECODE);
-
-            mozilla::RefPtr<mozilla::gfx::DataSourceSurface> dataSurface =
-              surface->GetDataSurface();
-            size_t length;
-            int32_t stride;
-            const uint8_t* data = nsContentUtils::GetSurfaceData(dataSurface, &length, &stride);
-            nsDependentCSubstring imageData(reinterpret_cast<const char*>(data), length);
-
-            IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
-            item->flavor() = nsCString(flavorStr);
-            item->data() = nsCString(imageData);
-
-            IPCDataTransferImage& imageDetails = item->imageDetails();
-            mozilla::gfx::IntSize size = dataSurface->GetSize();
-            imageDetails.width() = size.width;
-            imageDetails.height() = size.height;
-            imageDetails.stride() = stride;
-            imageDetails.format() = static_cast<uint8_t>(dataSurface->GetFormat());
-
-            dataSurface->Unmap();
-            continue;
-          }
-
-          // Otherwise, handle this as a file.
-          nsCOMPtr<FileImpl> fileImpl;
-          nsCOMPtr<nsIFile> file = do_QueryInterface(data);
-          if (file) {
-            fileImpl = new FileImplFile(file, false);
-            ErrorResult rv;
-            fileImpl->GetSize(rv);
-            fileImpl->GetLastModified(rv);
-          } else {
-            fileImpl = do_QueryInterface(data);
-          }
-          if (fileImpl) {
-            IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
-            item->flavor() = nsCString(flavorStr);
-            if (aChild) {
-              item->data() =
-                mozilla::dom::BlobChild::GetOrCreate(aChild,
-                  static_cast<FileImpl*>(fileImpl.get()));
-            } else if (aParent) {
-              item->data() =
-                mozilla::dom::BlobParent::GetOrCreate(aParent,
-                  static_cast<FileImpl*>(fileImpl.get()));
+      nsCOMPtr<nsITransferable> item(do_QueryInterface(genericItem));
+      if (item) {
+        nsCOMPtr<nsISupportsArray> flavorList;
+        item->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
+        if (flavorList) {
+          uint32_t flavorCount = 0;
+          flavorList->Count(&flavorCount);
+          for (uint32_t j = 0; j < flavorCount; ++j) {
+            nsCOMPtr<nsISupportsCString> flavor = do_QueryElementAt(flavorList, j);
+            if (!flavor) {
+              continue;
+            }
+
+            nsAutoCString flavorStr;
+            flavor->GetData(flavorStr);
+            if (!flavorStr.Length()) {
+              continue;
             }
-          } else {
-            // This is a hack to support kFilePromiseMime.
-            // On Windows there just needs to be an entry for it, 
-            // and for OSX we need to create
-            // nsContentAreaDragDropDataProvider as nsIFlavorDataProvider.
-            if (flavorStr.EqualsLiteral(kFilePromiseMime)) {
-              IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
+
+            nsCOMPtr<nsISupports> data;
+            uint32_t dataLen = 0;
+            item->GetTransferData(flavorStr.get(), getter_AddRefs(data), &dataLen);
+
+            nsCOMPtr<nsISupportsString> text = do_QueryInterface(data);
+            if (text) {
+              nsAutoString dataAsString;
+              text->GetData(dataAsString);
+              IPCDataTransferItem* item = dt->items().AppendElement();
               item->flavor() = nsCString(flavorStr);
-              item->data() = NS_ConvertUTF8toUTF16(flavorStr);
+              item->data() = nsString(dataAsString);
+            } else {
+              nsCOMPtr<nsISupportsInterfacePointer> sip =
+                do_QueryInterface(data);
+              if (sip) {
+                sip->GetData(getter_AddRefs(data));
+              }
+              nsCOMPtr<FileImpl> fileImpl;
+              nsCOMPtr<nsIFile> file = do_QueryInterface(data);
+              if (file) {
+                fileImpl = new FileImplFile(file, false);
+                ErrorResult rv;
+                fileImpl->GetSize(rv);
+                fileImpl->GetLastModified(rv);
+              } else {
+                fileImpl = do_QueryInterface(data);
+              }
+              if (fileImpl) {
+                IPCDataTransferItem* item = dt->items().AppendElement();
+                item->flavor() = nsCString(flavorStr);
+                if (aChild) {
+                  item->data() =
+                    mozilla::dom::BlobChild::GetOrCreate(aChild,
+                      static_cast<FileImpl*>(fileImpl.get()));
+                } else if (aParent) {
+                  item->data() =
+                    mozilla::dom::BlobParent::GetOrCreate(aParent,
+                      static_cast<FileImpl*>(fileImpl.get()));
+                }
+              } else {
+                // This is a hack to support kFilePromiseMime.
+                // On Windows there just needs to be an entry for it, 
+                // and for OSX we need to create
+                // nsContentAreaDragDropDataProvider as nsIFlavorDataProvider.
+                if (flavorStr.EqualsLiteral(kFilePromiseMime)) {
+                  IPCDataTransferItem* item = dt->items().AppendElement();
+                  item->flavor() = nsCString(flavorStr);
+                  item->data() = NS_ConvertUTF8toUTF16(flavorStr);
+                }
+              }
             }
           }
         }
       }
     }
   }
 }
-
-const uint8_t*
-nsContentUtils::GetSurfaceData(mozilla::gfx::DataSourceSurface* aSurface,
-                               size_t* aLength, int32_t* aStride)
-{
-  mozilla::gfx::DataSourceSurface::MappedSurface map;
-  aSurface->Map(mozilla::gfx::DataSourceSurface::MapType::READ, &map);
-  mozilla::gfx::IntSize size = aSurface->GetSize();
-  mozilla::CheckedInt32 requiredBytes =
-    mozilla::CheckedInt32(map.mStride) * mozilla::CheckedInt32(size.height);
-  size_t bufLen = requiredBytes.isValid() ? requiredBytes.value() : 0;
-  mozilla::gfx::SurfaceFormat format = aSurface->GetFormat();
-
-  // Surface data handling is totally nuts. This is the magic one needs to
-  // know to access the data.
-  bufLen = bufLen - map.mStride + (size.width * BytesPerPixel(format));
-
-  *aLength = bufLen;
-  *aStride = map.mStride;
-  return map.mData;
-}
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -98,17 +98,16 @@ class nsPIDOMWindow;
 class nsPresContext;
 class nsScriptObjectTracer;
 class nsStringBuffer;
 class nsStringHashKey;
 class nsTextFragment;
 class nsViewportInfo;
 class nsWrapperCache;
 class nsAttrValue;
-class nsITransferable;
 
 struct JSPropertyDescriptor;
 struct JSRuntime;
 struct nsIntMargin;
 
 template<class E> class nsCOMArray;
 template<class K, class V> class nsDataHashtable;
 template<class K, class V> class nsRefPtrHashtable;
@@ -125,20 +124,16 @@ class EventTarget;
 class IPCDataTransfer;
 class NodeInfo;
 class nsIContentChild;
 class nsIContentParent;
 class Selection;
 class TabParent;
 } // namespace dom
 
-namespace gfx {
-class DataSourceSurface;
-} // namespace gfx
-
 namespace layers {
 class LayerManager;
 } // namespace layers
 
 } // namespace mozilla
 
 class nsIBidiKeyboard;
 
@@ -2295,31 +2290,16 @@ public:
   static void CallOnAllRemoteChildren(nsIDOMWindow* aWindow,
                                       CallOnRemoteChildFunction aCallback,
                                       void* aArg);
 
   static void TransferablesToIPCTransferables(nsISupportsArray* aTransferables,
                                               nsTArray<mozilla::dom::IPCDataTransfer>& aIPC,
                                               mozilla::dom::nsIContentChild* aChild,
                                               mozilla::dom::nsIContentParent* aParent);
-
-  static void TransferableToIPCTransferable(nsITransferable* aTransferable,
-                                            mozilla::dom::IPCDataTransfer* aIPCDataTransfer,
-                                            mozilla::dom::nsIContentChild* aChild,
-                                            mozilla::dom::nsIContentParent* aParent);
-
-  /*
-   * Get the pixel data from the given source surface and return it as a buffer.
-   * The length and stride will be assigned from the surface. This method will map
-   * the surface; the caller should call Unmap on the surface when finished with
-   * the data.
-   */
-  static const uint8_t* GetSurfaceData(mozilla::gfx::DataSourceSurface* aSurface,
-                                       size_t* aLength, int32_t* aStride);
-
 private:
   static bool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
                                 nsIPrincipal* aPrincipal);
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -123,31 +123,28 @@
 #include "nsISpellChecker.h"
 #include "nsIStyleSheet.h"
 #include "nsISupportsPrimitives.h"
 #include "nsISystemMessagesInternal.h"
 #include "nsITimer.h"
 #include "nsIURIFixup.h"
 #include "nsIWindowWatcher.h"
 #include "nsIXULRuntime.h"
-#include "gfxDrawable.h"
-#include "ImageOps.h"
 #include "nsMemoryInfoDumper.h"
 #include "nsMemoryReporterManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStyleSheetService.h"
 #include "nsThreadUtils.h"
 #include "nsThreadManager.h"
 #include "nsToolkitCompsCID.h"
 #include "nsWidgetsCID.h"
 #include "PreallocatedProcessManager.h"
 #include "ProcessPriorityManager.h"
 #include "SandboxHal.h"
 #include "ScreenManagerParent.h"
-#include "SourceSurfaceRawData.h"
 #include "StructuredCloneUtils.h"
 #include "TabParent.h"
 #include "URIUtils.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsIDocShell.h"
 #include "mozilla/net/NeckoMessageUtils.h"
 #include "gfxPrefs.h"
 #include "prio.h"
@@ -215,16 +212,17 @@ using namespace mozilla::system;
 #endif
 
 #ifdef MOZ_ENABLE_PROFILER_SPS
 #include "nsIProfiler.h"
 #include "nsIProfileSaveEvent.h"
 #endif
 
 static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
+static const char* sClipboardTextFlavors[] = { kUnicodeMime };
 
 using base::ChildPrivileges;
 using base::KillProcess;
 
 #ifdef MOZ_CRASHREPORTER
 using namespace CrashReporter;
 #endif
 using namespace mozilla::dom::bluetooth;
@@ -2520,137 +2518,98 @@ ContentParent::RecvReadPermissions(Infal
     // Ask for future changes
     mSendPermissionUpdates = true;
 #endif
 
     return true;
 }
 
 bool
-ContentParent::RecvSetClipboard(const IPCDataTransfer& aDataTransfer,
-                                const bool& aIsPrivateData,
-                                const int32_t& aWhichClipboard)
+ContentParent::RecvSetClipboardText(const nsString& text,
+                                       const bool& isPrivateData,
+                                       const int32_t& whichClipboard)
+{
+    nsresult rv;
+    nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
+    NS_ENSURE_SUCCESS(rv, true);
+
+    nsCOMPtr<nsISupportsString> dataWrapper =
+        do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
+    NS_ENSURE_SUCCESS(rv, true);
+
+    rv = dataWrapper->SetData(text);
+    NS_ENSURE_SUCCESS(rv, true);
+
+    nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
+    NS_ENSURE_SUCCESS(rv, true);
+    trans->Init(nullptr);
+
+    // If our data flavor has already been added, this will fail. But we don't care
+    trans->AddDataFlavor(kUnicodeMime);
+    trans->SetIsPrivateData(isPrivateData);
+
+    nsCOMPtr<nsISupports> nsisupportsDataWrapper =
+        do_QueryInterface(dataWrapper);
+
+    rv = trans->SetTransferData(kUnicodeMime, nsisupportsDataWrapper,
+                                text.Length() * sizeof(char16_t));
+    NS_ENSURE_SUCCESS(rv, true);
+
+    clipboard->SetData(trans, nullptr, whichClipboard);
+    return true;
+}
+
+bool
+ContentParent::RecvGetClipboardText(const int32_t& whichClipboard, nsString* text)
 {
     nsresult rv;
     nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
     NS_ENSURE_SUCCESS(rv, true);
 
     nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
     NS_ENSURE_SUCCESS(rv, true);
     trans->Init(nullptr);
-
-    const nsTArray<IPCDataTransferItem>& items = aDataTransfer.items();
-    for (uint32_t j = 0; j < items.Length(); ++j) {
-      const IPCDataTransferItem& item = items[j];
-
-      trans->AddDataFlavor(item.flavor().get());
-
-      if (item.data().type() == IPCDataTransferData::TnsString) {
-        nsCOMPtr<nsISupportsString> dataWrapper =
-          do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
-        NS_ENSURE_SUCCESS(rv, true);
-
-        nsString text = item.data().get_nsString();
-        rv = dataWrapper->SetData(text);
-        NS_ENSURE_SUCCESS(rv, true);
-
-        rv = trans->SetTransferData(item.flavor().get(), dataWrapper,
-                                    text.Length() * sizeof(char16_t));
-
-        NS_ENSURE_SUCCESS(rv, true);
-      } else if (item.data().type() == IPCDataTransferData::TnsCString) {
-        const IPCDataTransferImage& imageDetails = item.imageDetails();
-        const gfxIntSize size(imageDetails.width(), imageDetails.height());
-        if (!size.width || !size.height) {
-          return true;
-        }
-
-        nsCString text = item.data().get_nsCString();
-        mozilla::RefPtr<gfx::DataSourceSurface> image =
-          new mozilla::gfx::SourceSurfaceRawData();
-        mozilla::gfx::SourceSurfaceRawData* raw =
-          static_cast<mozilla::gfx::SourceSurfaceRawData*>(image.get());
-        raw->InitWrappingData(
-          reinterpret_cast<uint8_t*>(const_cast<nsCString&>(text).BeginWriting()),
-          size, imageDetails.stride(),
-          static_cast<mozilla::gfx::SurfaceFormat>(imageDetails.format()), false);
-        raw->GuaranteePersistance();
-
-        nsRefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(image, size);
-        nsCOMPtr<imgIContainer> imageContainer(image::ImageOps::CreateFromDrawable(drawable)); 
-
-        nsCOMPtr<nsISupportsInterfacePointer>
-          imgPtr(do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv));
-
-        rv = imgPtr->SetData(imageContainer);
-        NS_ENSURE_SUCCESS(rv, true);
-
-        trans->SetTransferData(item.flavor().get(), imgPtr, sizeof(nsISupports*));
-      }
-    }
-
-    trans->SetIsPrivateData(aIsPrivateData);
-
-    clipboard->SetData(trans, nullptr, aWhichClipboard);
+    trans->AddDataFlavor(kUnicodeMime);
+
+    clipboard->GetData(trans, whichClipboard);
+    nsCOMPtr<nsISupports> tmp;
+    uint32_t len;
+    rv = trans->GetTransferData(kUnicodeMime, getter_AddRefs(tmp), &len);
+    if (NS_FAILED(rv))
+        return true;
+
+    nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(tmp);
+    // No support for non-text data
+    if (!supportsString)
+        return true;
+    supportsString->GetData(*text);
     return true;
 }
 
 bool
-ContentParent::RecvGetClipboard(nsTArray<nsCString>&& aTypes,
-                                const int32_t& aWhichClipboard,
-                                IPCDataTransfer* aDataTransfer)
+ContentParent::RecvEmptyClipboard(const int32_t& whichClipboard)
 {
     nsresult rv;
     nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
     NS_ENSURE_SUCCESS(rv, true);
 
-    nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
-    NS_ENSURE_SUCCESS(rv, true);
-    trans->Init(nullptr);
-
-    for (uint32_t t = 0; t < aTypes.Length(); t++) {
-      trans->AddDataFlavor(aTypes[t].get());
-    }
-
-    clipboard->GetData(trans, aWhichClipboard);
-    nsContentUtils::TransferableToIPCTransferable(trans, aDataTransfer,
-                                                  nullptr, this);
-    return true;
-}
-
-bool
-ContentParent::RecvEmptyClipboard(const int32_t& aWhichClipboard)
-{
-    nsresult rv;
-    nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
-    NS_ENSURE_SUCCESS(rv, true);
-
-    clipboard->EmptyClipboard(aWhichClipboard);
+    clipboard->EmptyClipboard(whichClipboard);
 
     return true;
 }
 
 bool
-ContentParent::RecvClipboardHasType(nsTArray<nsCString>&& aTypes,
-                                    const int32_t& aWhichClipboard,
-                                    bool* aHasType)
+ContentParent::RecvClipboardHasText(const int32_t& whichClipboard, bool* hasText)
 {
     nsresult rv;
     nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
     NS_ENSURE_SUCCESS(rv, true);
 
-    const char** typesChrs = new const char *[aTypes.Length()];
-    for (uint32_t t = 0; t < aTypes.Length(); t++) {
-      typesChrs[t] = aTypes[t].get();
-    }
-
-    clipboard->HasDataMatchingFlavors(typesChrs, aTypes.Length(),
-                                      aWhichClipboard, aHasType);
-
-    delete [] typesChrs;
+    clipboard->HasDataMatchingFlavors(sClipboardTextFlavors, 1,
+                                      whichClipboard, hasText);
     return true;
 }
 
 bool
 ContentParent::RecvGetSystemColors(const uint32_t& colorsCount, InfallibleTArray<uint32_t>* colors)
 {
 #ifdef MOZ_WIDGET_ANDROID
     NS_ASSERTION(AndroidBridge::Bridge() != nullptr, "AndroidBridge is not available");
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -646,26 +646,22 @@ private:
     virtual bool DeallocPSpeechSynthesisParent(PSpeechSynthesisParent* aActor) override;
     virtual bool RecvPSpeechSynthesisConstructor(PSpeechSynthesisParent* aActor) override;
 
     virtual bool RecvReadPrefsArray(InfallibleTArray<PrefSetting>* aPrefs) override;
     virtual bool RecvReadFontList(InfallibleTArray<FontListEntry>* retValue) override;
 
     virtual bool RecvReadPermissions(InfallibleTArray<IPC::Permission>* aPermissions) override;
 
-    virtual bool RecvSetClipboard(const IPCDataTransfer& aDataTransfer,
-                                  const bool& aIsPrivateData,
-                                  const int32_t& aWhichClipboard) override;
-    virtual bool RecvGetClipboard(nsTArray<nsCString>&& aTypes,
-                                  const int32_t& aWhichClipboard,
-                                  IPCDataTransfer* aDataTransfer) override;
-    virtual bool RecvEmptyClipboard(const int32_t& aWhichClipboard) override;
-    virtual bool RecvClipboardHasType(nsTArray<nsCString>&& aTypes,
-                                      const int32_t& aWhichClipboard,
-                                      bool* aHasType) override;
+    virtual bool RecvSetClipboardText(const nsString& text,
+                                      const bool& isPrivateData,
+                                      const int32_t& whichClipboard) override;
+    virtual bool RecvGetClipboardText(const int32_t& whichClipboard, nsString* text) override;
+    virtual bool RecvEmptyClipboard(const int32_t& whichClipboard) override;
+    virtual bool RecvClipboardHasText(const int32_t& whichClipboard, bool* hasText) override;
 
     virtual bool RecvGetSystemColors(const uint32_t& colorsCount,
                                      InfallibleTArray<uint32_t>* colors) override;
     virtual bool RecvGetIconForExtension(const nsCString& aFileExt,
                                          const uint32_t& aIconSize,
                                          InfallibleTArray<uint8_t>* bits) override;
     virtual bool RecvGetShowPasswordSetting(bool* showPassword) override;
 
--- a/dom/ipc/DOMTypes.ipdlh
+++ b/dom/ipc/DOMTypes.ipdlh
@@ -132,34 +132,23 @@ struct ParentBlobConstructorParams
 union BlobConstructorParams
 {
   ChildBlobConstructorParams;
   ParentBlobConstructorParams;
 };
 
 union IPCDataTransferData
 {
-  nsString;  // text
-  nsCString; // images
-  PBlob;     // files
-};
-
-struct IPCDataTransferImage
-{
-  uint32_t width;
-  uint32_t height;
-  uint32_t stride;
-  uint8_t format;
+  nsString;
+  PBlob;
 };
 
 struct IPCDataTransferItem
 {
   nsCString flavor;
-  // The image details are only used when transferring images.
-  IPCDataTransferImage imageDetails;
   IPCDataTransferData data;
 };
 
 struct IPCDataTransfer
 {
   IPCDataTransferItem[] items;
 };
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -762,32 +762,22 @@ parent:
     ConsoleMessage(nsString message);
     ScriptError(nsString message, nsString sourceName, nsString sourceLine,
                 uint32_t lineNumber, uint32_t colNumber, uint32_t flags,
                 nsCString category);
 
     // nsIPermissionManager messages
     sync ReadPermissions() returns (Permission[] permissions);
 
-    // Places the items within dataTransfer on the clipboard.
-    SetClipboard(IPCDataTransfer aDataTransfer,
-                 bool aIsPrivateData,
-                 int32_t aWhichClipboard);
-
-    // Given a list of supported types, returns the clipboard data for the
-    // first type that matches.
-    sync GetClipboard(nsCString[] aTypes, int32_t aWhichClipboard)
-        returns (IPCDataTransfer dataTransfer);
-
-    // Clears the clipboard.
-    EmptyClipboard(int32_t aWhichClipboard);
-
-    // Returns true if data of one of the specified types is on the clipboard.
-    sync ClipboardHasType(nsCString[] aTypes, int32_t aWhichClipboard)
-        returns (bool hasType);
+    SetClipboardText(nsString text, bool isPrivateData, int32_t whichClipboard);
+    sync GetClipboardText(int32_t whichClipboard)
+        returns (nsString text);
+    EmptyClipboard(int32_t whichClipboard);
+    sync ClipboardHasText(int32_t whichClipboard)
+        returns (bool hasText);
 
     sync GetSystemColors(uint32_t colorsCount)
         returns (uint32_t[] colors);
 
     sync GetIconForExtension(nsCString aFileExt, uint32_t aIconSize)
         returns (uint8_t[] bits);
 
     sync GetShowPasswordSetting()
--- a/widget/nsClipboardProxy.cpp
+++ b/widget/nsClipboardProxy.cpp
@@ -3,140 +3,90 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/ContentChild.h"
 #include "nsClipboardProxy.h"
 #include "nsISupportsPrimitives.h"
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsXULAppAPI.h"
-#include "nsContentUtils.h"
-#include "nsStringStream.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_ISUPPORTS(nsClipboardProxy, nsIClipboard, nsIClipboardProxy)
 
 nsClipboardProxy::nsClipboardProxy()
   : mClipboardCaps(false, false)
 {
 }
 
 NS_IMETHODIMP
 nsClipboardProxy::SetData(nsITransferable *aTransferable,
                           nsIClipboardOwner *anOwner, int32_t aWhichClipboard)
 {
-  ContentChild* child = ContentChild::GetSingleton();
-
-  IPCDataTransfer ipcDataTransfer;
-  nsContentUtils::TransferableToIPCTransferable(aTransferable, &ipcDataTransfer,
-                                                child, nullptr);
+  nsCOMPtr<nsISupports> tmp;
+  uint32_t len;
+  nsresult rv  = aTransferable->GetTransferData(kUnicodeMime, getter_AddRefs(tmp),
+                                                &len);
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(tmp);
+  // No support for non-text data
+  NS_ENSURE_TRUE(supportsString, NS_ERROR_NOT_IMPLEMENTED);
+  nsAutoString buffer;
+  supportsString->GetData(buffer);
 
   bool isPrivateData = false;
   aTransferable->GetIsPrivateData(&isPrivateData);
-  child->SendSetClipboard(ipcDataTransfer, isPrivateData, aWhichClipboard);
+  ContentChild::GetSingleton()->SendSetClipboardText(buffer, isPrivateData,
+                                                     aWhichClipboard);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClipboardProxy::GetData(nsITransferable *aTransferable, int32_t aWhichClipboard)
 {
-   nsTArray<nsCString> types;
-  
-  nsCOMPtr<nsISupportsArray> flavorList;
-  aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
-  if (flavorList) {
-    uint32_t flavorCount = 0;
-    flavorList->Count(&flavorCount);
-    for (uint32_t j = 0; j < flavorCount; ++j) {
-      nsCOMPtr<nsISupportsCString> flavor = do_QueryElementAt(flavorList, j);
-      if (flavor) {
-        nsAutoCString flavorStr;
-        flavor->GetData(flavorStr);
-        if (flavorStr.Length()) {
-          types.AppendElement(flavorStr);
-        }
-      }
-    }
-  }
+  nsAutoString buffer;
+  ContentChild::GetSingleton()->SendGetClipboardText(aWhichClipboard, &buffer);
 
   nsresult rv;
-  IPCDataTransfer dataTransfer;
-  ContentChild::GetSingleton()->SendGetClipboard(types, aWhichClipboard, &dataTransfer);
-
-  auto& items = dataTransfer.items();
-  for (uint32_t j = 0; j < items.Length(); ++j) {
-    const IPCDataTransferItem& item = items[j];
+  nsCOMPtr<nsISupportsString> dataWrapper =
+    do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-    if (item.data().type() == IPCDataTransferData::TnsString) {
-      nsCOMPtr<nsISupportsString> dataWrapper =
-        do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      nsString data = item.data().get_nsString();
-      rv = dataWrapper->SetData(data);
-      NS_ENSURE_SUCCESS(rv, rv);
+  rv = dataWrapper->SetData(buffer);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-      rv = aTransferable->SetTransferData(item.flavor().get(), dataWrapper,
-                                          data.Length() * sizeof(char16_t));
-      NS_ENSURE_SUCCESS(rv, rv);
-    } else if (item.data().type() == IPCDataTransferData::TnsCString) {
-      // If this is an image, convert it into an nsIInputStream.
-      nsCString flavor = item.flavor();
-      if (flavor.EqualsLiteral(kJPEGImageMime) ||
-          flavor.EqualsLiteral(kJPGImageMime) ||
-          flavor.EqualsLiteral(kPNGImageMime) ||
-          flavor.EqualsLiteral(kGIFImageMime)) {
-        nsCOMPtr<nsIInputStream> stream;
-        NS_NewCStringInputStream(getter_AddRefs(stream), item.data().get_nsCString());
+  // If our data flavor has already been added, this will fail. But we don't care
+  aTransferable->AddDataFlavor(kUnicodeMime);
 
-        rv = aTransferable->SetTransferData(flavor.get(), stream, sizeof(nsISupports*));
-        NS_ENSURE_SUCCESS(rv, rv);
-      } else if (flavor.EqualsLiteral(kNativeHTMLMime)) {
-        nsCOMPtr<nsISupportsCString> dataWrapper =
-          do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        nsCString data = item.data().get_nsCString();
-        rv = dataWrapper->SetData(data);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        rv = aTransferable->SetTransferData(item.flavor().get(), dataWrapper,
-                                            data.Length());
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-    }
-  }
+  nsCOMPtr<nsISupports> nsisupportsDataWrapper =
+    do_QueryInterface(dataWrapper);
+  rv = aTransferable->SetTransferData(kUnicodeMime, nsisupportsDataWrapper,
+                                      buffer.Length() * sizeof(char16_t));
+  NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClipboardProxy::EmptyClipboard(int32_t aWhichClipboard)
 {
   ContentChild::GetSingleton()->SendEmptyClipboard(aWhichClipboard);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClipboardProxy::HasDataMatchingFlavors(const char **aFlavorList,
-                                         uint32_t aLength, int32_t aWhichClipboard,
-                                         bool *aHasType)
+                                    uint32_t aLength, int32_t aWhichClipboard,
+                                    bool *aHasText)
 {
-  *aHasType = false;
-
-  nsTArray<nsCString> types;
-  for (uint32_t j = 0; j < aLength; ++j) {
-    types.AppendElement(nsDependentCString(aFlavorList[j]));
-  }
-
-  ContentChild::GetSingleton()->SendClipboardHasType(types, aWhichClipboard, aHasType);
-
+  *aHasText = false;
+  ContentChild::GetSingleton()->SendClipboardHasText(aWhichClipboard, aHasText);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsClipboardProxy::SupportsSelectionClipboard(bool *aIsSupported)
 {
   *aIsSupported = mClipboardCaps.supportsSelectionClipboard();
   return NS_OK;
--- a/widget/nsDragServiceProxy.cpp
+++ b/widget/nsDragServiceProxy.cpp
@@ -52,27 +52,31 @@ nsDragServiceProxy::InvokeDragSession(ns
     nsPresContext* pc;
     mozilla::RefPtr<mozilla::gfx::SourceSurface> surface;
     DrawDrag(mSourceNode, aRegion, mScreenX, mScreenY,
              &dragRect, &surface, &pc);
 
     if (surface) {
       mozilla::RefPtr<mozilla::gfx::DataSourceSurface> dataSurface =
         surface->GetDataSurface();
-
-      size_t length;
-      int32_t stride;
-      const uint8_t* data = nsContentUtils::GetSurfaceData(dataSurface, &length, &stride);
-      nsDependentCString dragImage(reinterpret_cast<const char*>(data), length);
-
+      mozilla::gfx::DataSourceSurface::MappedSurface map;
+      dataSurface->Map(mozilla::gfx::DataSourceSurface::MapType::READ, &map);
       mozilla::gfx::IntSize size = dataSurface->GetSize();
+      mozilla::CheckedInt32 requiredBytes =
+        mozilla::CheckedInt32(map.mStride) * mozilla::CheckedInt32(size.height);
+      size_t bufLen = requiredBytes.isValid() ? requiredBytes.value() : 0;
+      mozilla::gfx::SurfaceFormat format = dataSurface->GetFormat();
+      // Surface data handling is totally nuts. This is the magic one needs to
+      // know to access the data.
+      bufLen = bufLen - map.mStride + (size.width * BytesPerPixel(format));
+      nsDependentCString dragImage(reinterpret_cast<char*>(map.mData), bufLen);
       mozilla::unused <<
         child->SendInvokeDragSession(dataTransfers, aActionType, dragImage,
-                                     size.width, size.height, stride,
-                                     static_cast<uint8_t>(dataSurface->GetFormat()),
+                                     size.width, size.height, map.mStride,
+                                     static_cast<uint8_t>(format),
                                      dragRect.x, dragRect.y);
       dataSurface->Unmap();
       StartDragSession();
       return NS_OK;
     }
   }
 
   mozilla::unused << child->SendInvokeDragSession(dataTransfers, aActionType,