Bug 490879 - Pasting images into rich text editors creates temporary moz-screenshot.jpg; r+sr=roc
☠☠ backed out by 0cb354f894d1 ☠ ☠
authorEhsan Akhgari <ehsan.akhgari@gmail.com>
Sun, 03 May 2009 13:31:32 +0430
changeset 27953 12536e9936b2c43538eb5803937d5314ec3c4cf8
parent 27952 e902d43f10f26d623d6b46e6de320cd9d6860d1f
child 27954 96ce4672e2a97807417bc57e621c928a1873ab09
push id6801
push userehsan.akhgari@gmail.com
push dateSun, 03 May 2009 09:02:37 +0000
treeherdermozilla-central@12536e9936b2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs490879
milestone1.9.2a1pre
Bug 490879 - Pasting images into rich text editors creates temporary moz-screenshot.jpg; r+sr=roc
editor/libeditor/html/nsHTMLDataTransfer.cpp
editor/libeditor/html/tests/Makefile.in
editor/libeditor/html/tests/green.png
editor/libeditor/html/tests/test_bug490879.xul
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -126,16 +126,19 @@
 
 // Misc
 #include "TextEditorTest.h"
 #include "nsEditorUtils.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "nsIContentFilter.h"
 #include "nsEventDispatcher.h"
+#include "plbase64.h"
+#include "prmem.h"
+#include "nsStreamUtils.h"
 
 const PRUnichar nbsp = 160;
 
 static NS_DEFINE_CID(kCParserCID,     NS_PARSER_CID);
 
 // private clipboard data flavors for html copy/paste
 #define kHTMLContext   "text/_moz_htmlcontext"
 #define kHTMLInfo      "text/_moz_htmlinfo"
@@ -1411,70 +1414,35 @@ NS_IMETHODIMP nsHTMLEditor::InsertFromTr
     }
     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<nsIFile> fileToUse;
-      NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(fileToUse));
-
-      if (0 == nsCRT::strcmp(bestFlavor, kJPEGImageMime))
-        fileToUse->Append(NS_LITERAL_STRING("moz-screenshot.jpg"));
-      else if (0 == nsCRT::strcmp(bestFlavor, kPNGImageMime))
-        fileToUse->Append(NS_LITERAL_STRING("moz-screenshot.png"));
-      else if (0 == nsCRT::strcmp(bestFlavor, kGIFImageMime))
-        fileToUse->Append(NS_LITERAL_STRING("moz-screenshot.gif"));
-
-      nsCOMPtr<nsILocalFile> path = do_QueryInterface(fileToUse);
-      path->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600);
-
-      nsCOMPtr<nsIOutputStream> outputStream;
-      rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), fileToUse);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      PRUint32 length;
-      imageStream->Available(&length);
-
-      nsCOMPtr<nsIOutputStream> bufferedOutputStream;
-      rv = NS_NewBufferedOutputStream(getter_AddRefs(bufferedOutputStream), outputStream, length);
+      nsCString imageData;
+      rv = NS_ConsumeStream(imageStream, PR_UINT32_MAX, imageData);
       NS_ENSURE_SUCCESS(rv, rv);
 
-      PRUint32 numWritten;
-      rv = bufferedOutputStream->WriteFrom(imageStream, length, &numWritten);
-      NS_ENSURE_SUCCESS(rv, rv);
+      char * base64 = PL_Base64Encode(imageData.get(), imageData.Length(), nsnull);
+      NS_ENSURE_TRUE(base64, NS_ERROR_OUT_OF_MEMORY);
 
-      // force the stream close before we try to insert the image
-      // into the document.
-      rv = bufferedOutputStream->Close();
-      NS_ENSURE_SUCCESS(rv, rv);
-      
-      nsCOMPtr<nsIURI> uri;
-      rv = NS_NewFileURI(getter_AddRefs(uri), fileToUse);
-      NS_ENSURE_SUCCESS(rv, rv);
-      nsCOMPtr<nsIURL> fileURL(do_QueryInterface(uri));
-      if (fileURL)
-      {
-        nsCAutoString urltext;
-        rv = fileURL->GetSpec(urltext);
-        if (NS_SUCCEEDED(rv) && !urltext.IsEmpty())
-        {
-          stuffToPaste.AssignLiteral("<IMG src=\"");
-          AppendUTF8toUTF16(urltext, stuffToPaste);
-          stuffToPaste.AppendLiteral("\" alt=\"\" >");
-          nsAutoEditBatch beginBatching(this);
-          rv = InsertHTMLWithContext(stuffToPaste, EmptyString(), EmptyString(), 
-                                     NS_LITERAL_STRING(kFileMime),
-                                     aSourceDoc,
-                                     aDestinationNode, aDestOffset,
-                                     aDoDeleteSelection);
-        }
-      }
+      stuffToPaste.AssignLiteral("<IMG src=\"data:");
+      AppendUTF8toUTF16(bestFlavor, stuffToPaste);
+      stuffToPaste.AppendLiteral(";base64,");
+      AppendUTF8toUTF16(base64, stuffToPaste);
+      stuffToPaste.AppendLiteral("\" alt=\"\" >");
+      nsAutoEditBatch beginBatching(this);
+      rv = InsertHTMLWithContext(stuffToPaste, EmptyString(), EmptyString(), 
+                                 NS_LITERAL_STRING(kFileMime),
+                                 aSourceDoc,
+                                 aDestinationNode, aDestOffset,
+                                 aDoDeleteSelection);
+      PR_Free(base64);
     }
   }
       
   // Try to scroll the selection into view if the paste/drop succeeded
 
   // After ScrollSelectionIntoView(), the pending notifications might be
   // flushed and PresShell/PresContext/Frames may be dead. See bug 418470.
   if (NS_SUCCEEDED(rv))
--- a/editor/libeditor/html/tests/Makefile.in
+++ b/editor/libeditor/html/tests/Makefile.in
@@ -48,11 +48,19 @@ include $(topsrcdir)/config/rules.mk
 		test_bug366682.html \
 		test_bug432225.html \
 		test_bug455992.html \
 		test_bug456244.html \
 		test_bug478725.html \
 		test_bug480972.html \
 		$(NULL)
 
+_CHROME_TEST_FILES = \
+		test_bug490879.xul \
+		green.png \
+		$(NULL)
+
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
+libs:: $(_CHROME_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
+
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0aaec20932a3238bb9530e526049a56fbc363d20
GIT binary patch
literal 334
zc%17D@N?(olHy`uVBq!ia0vp^DIm<j1SJ1AFflVQFp7G*IEGZrd3!F9lR<&OW#jAk
uDD5BSava<n-oB}R%C1-^@My#lvf`V*yw?8Y-gN>PP7I!|elF{r5}E+-i)c;&
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/html/tests/test_bug490879.xul
@@ -0,0 +1,73 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin"
+                 type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=490879
+-->
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="Mozilla Bug 490879" onload="runTest();">
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"/>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=490879"
+     target="_blank">Mozilla Bug 490879</a>
+  <p/>
+  <iframe id="i1" width="200" height="100" src="about:blank" /><br />
+  <img id="i" src="green.png" />
+  <p/>
+  <pre id="test">
+  </pre>
+  </body>
+  <script class="testbody" type="application/javascript">
+  <![CDATA[
+
+function runTest() {
+  function verifyContent() {
+    const kExpectedImgSpec = "data:image/png;base64,";
+    var e = document.getElementById('i1');
+    var doc = e.contentDocument;
+    is(doc.getElementsByTagName("img")[0].src.substring(0, kExpectedImgSpec.length),
+       kExpectedImgSpec, "The pasted image is a base64-encoded data: URI");
+  }
+
+  function pasteInto() {
+    var e = document.getElementById('i1');
+    var doc = e.contentDocument;
+    doc.designMode = "on";
+    doc.defaultView.focus();
+    var selection = doc.defaultView.getSelection();
+    selection.removeAllRanges();
+    selection.selectAllChildren(doc.body);
+    selection.collapseToEnd();
+    doc.execCommand("paste", false, null);
+  }
+
+  function copyToClipBoard() {
+    var tmpNode = document.popupNode;
+    document.popupNode = document.getElementById("i");
+
+    const kCmd = "cmd_copyImageContents";
+    var controller = top.document.commandDispatcher
+                     .getControllerForCommand(kCmd);
+    ok((controller && controller.isCommandEnabled(kCmd)), "have copy command");
+    controller.doCommand(kCmd);
+
+    document.popupNode = tmpNode;
+  }
+
+  copyToClipBoard();
+  pasteInto();
+  verifyContent();
+
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+]]>
+</script>
+</window>