Bug 609632 - Insert image files dropped onto editable areas as data: URI images; r=roc a=blocking-beta8+
authorEhsan Akhgari <ehsan@mozilla.com>
Sat, 06 Nov 2010 18:49:26 -0400
changeset 57548 f576b6e16d462b1872dadb3322d0b8560a3e7353
parent 57547 0f66d961d5329c1e092c28ad2fd2c0ba147021cc
child 57549 68df5bb6da6c009aa0d656cbecbdff7ce7879d8c
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersroc, blocking-beta8
bugs609632
milestone2.0b8pre
Bug 609632 - Insert image files dropped onto editable areas as data: URI images; r=roc a=blocking-beta8+
editor/libeditor/html/nsHTMLDataTransfer.cpp
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -1116,16 +1116,17 @@ NS_IMETHODIMP nsHTMLEditor::PrepareHTMLT
     // This should only happen in html editors, not plaintext
     if (!IsPlaintextEditor())
     {
       if (!aHavePrivFlavor) 
       {
         (*aTransferable)->AddDataFlavor(kNativeHTMLMime);
       }
       (*aTransferable)->AddDataFlavor(kHTMLMime);
+      (*aTransferable)->AddDataFlavor(kFileMime);
 
       nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
       PRInt32 clipboardPasteOrder = 1; // order of image-encoding preference
 
       if (prefs)
       {
         prefs->GetIntPref("clipboard.paste_image_type", &clipboardPasteOrder);
         switch (clipboardPasteOrder)
@@ -1315,16 +1316,38 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromTr
 
       nsIPrincipal* srcPrincipal = srcdoc->NodePrincipal();
       nsIPrincipal* destPrincipal = destdoc->NodePrincipal();
       NS_ASSERTION(srcPrincipal && destPrincipal, "How come we don't have a principal?");
       rv = srcPrincipal->Subsumes(destPrincipal, &isSafe);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
+    // Check to see if we can insert an image file
+    PRBool insertAsImage = PR_FALSE;
+    nsCOMPtr<nsIURI> fileURI;
+    if (0 == nsCRT::strcmp(bestFlavor, kFileMime))
+    {
+      nsCOMPtr<nsIFile> fileObj(do_QueryInterface(genericDataObj));
+      if (fileObj && len > 0)
+      {
+        nsCOMPtr<nsIMIMEService> mime = do_GetService("@mozilla.org/mime;1");
+        NS_ENSURE_TRUE(mime, NS_ERROR_FAILURE);
+        nsAutoCString contentType;
+        rv = mime->GetTypeFromFile(fileObj, contentType);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        // Accept any image type fed to us
+        if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("image/"))) {
+          insertAsImage = PR_TRUE;
+          bestFlavor = contentType;
+        }
+      }
+    }
+
     if (0 == nsCRT::strcmp(bestFlavor, kNativeHTMLMime))
     {
       // note cf_html uses utf8, hence use length = len, not len/2 as in flavors below
       nsCOMPtr<nsISupportsCString> textDataObj(do_QueryInterface(genericDataObj));
       if (textDataObj && len > 0)
       {
         nsCAutoString cfhtml;
         textDataObj->GetData(cfhtml);
@@ -1376,23 +1399,33 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromTr
         // need to provide a hook from this point
         rv = InsertTextAt(stuffToPaste, aDestinationNode, aDestOffset, aDoDeleteSelection);
       }
     }
     else if (0 == nsCRT::strcmp(bestFlavor, kJPEGImageMime) ||
              0 == nsCRT::strcmp(bestFlavor, kPNGImageMime) ||
              0 == nsCRT::strcmp(bestFlavor, kGIFImageMime))
     {
-      nsCOMPtr<nsIInputStream> imageStream(do_QueryInterface(genericDataObj));
-      NS_ENSURE_TRUE(imageStream, NS_ERROR_FAILURE);
+      nsCOMPtr<nsIInputStream> imageStream;
+      if (insertAsImage) {
+        NS_ASSERTION(fileURI, "The file URI should be retrieved earlier");
+        rv = NS_OpenURI(getter_AddRefs(imageStream), fileURI);
+        NS_ENSURE_SUCCESS(rv, rv);
+      } else {
+        imageStream = do_QueryInterface(genericDataObj);
+        NS_ENSURE_TRUE(imageStream, NS_ERROR_FAILURE);
+      }
 
       nsCString imageData;
       rv = NS_ConsumeStream(imageStream, PR_UINT32_MAX, imageData);
       NS_ENSURE_SUCCESS(rv, rv);
 
+      rv = imageStream->Close();
+      NS_ENSURE_SUCCESS(rv, rv);
+
       char * base64 = PL_Base64Encode(imageData.get(), imageData.Length(), nsnull);
       NS_ENSURE_TRUE(base64, NS_ERROR_OUT_OF_MEMORY);
 
       stuffToPaste.AssignLiteral("<IMG src=\"data:");
       AppendUTF8toUTF16(bestFlavor, stuffToPaste);
       stuffToPaste.AppendLiteral(";base64,");
       AppendUTF8toUTF16(base64, stuffToPaste);
       stuffToPaste.AppendLiteral("\" alt=\"\" >");