Bug 292607 Dragging preformatted text collapses whitespace r+sr=bz a=pavlov
authorneil@parkwaycc.co.uk
Fri, 28 Sep 2007 03:28:28 -0700
changeset 6391 787afe8d47ea996bb080f6066b24ddeb9dfb4193
parent 6390 e5182a66c316a85350072b6746695239cdf29e53
child 6392 6b821bbc782cf3be8f8dd78c8a3cbb58aef894e6
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspavlov
bugs292607
milestone1.9a9pre
Bug 292607 Dragging preformatted text collapses whitespace r+sr=bz a=pavlov
content/base/src/nsContentAreaDragDrop.cpp
--- a/content/base/src/nsContentAreaDragDrop.cpp
+++ b/content/base/src/nsContentAreaDragDrop.cpp
@@ -93,16 +93,19 @@
 #include "nsEscape.h"
 #include "nsContentUtils.h"
 #include "nsIMIMEService.h"
 #include "imgIRequest.h"
 #include "nsContentCID.h"
 #include "nsISelectionController.h"
 #include "nsFrameSelection.h"
 #include "nsIDOMEventTarget.h"
+#include "nsWidgetsCID.h"
+
+static NS_DEFINE_CID(kHTMLConverterCID,        NS_HTMLFORMATCONVERTER_CID);
 
 // private clipboard data flavors for html copy, used by editor when pasting
 #define kHTMLContext   "text/_moz_htmlcontext"
 #define kHTMLInfo      "text/_moz_htmlinfo"
 
 
 NS_IMPL_ADDREF(nsContentAreaDragDrop)
 NS_IMPL_RELEASE(nsContentAreaDragDrop)
@@ -132,21 +135,18 @@ private:
   static already_AddRefed<nsIDOMNode> FindParentLinkNode(nsIDOMNode* inNode);
   static void GetAnchorURL(nsIDOMNode* inNode, nsAString& outURL);
   static void GetNodeString(nsIDOMNode* inNode, nsAString & outNodeString);
   static void CreateLinkText(const nsAString& inURL, const nsAString & inText,
                               nsAString& outLinkText);
   static void GetSelectedLink(nsISelection* inSelection,
                               nsIDOMNode **outLinkNode);
 
-  enum serializationMode {serializeAsText, serializeAsHTML};
   // if inNode is null, use the selection from the window
-  static nsresult SerializeNodeOrSelection(serializationMode inMode,
-                                           PRUint32 inFlags,
-                                           nsIDOMWindow* inWindow,
+  static nsresult SerializeNodeOrSelection(nsIDOMWindow* inWindow,
                                            nsIDOMNode* inNode,
                                            nsAString& outResultString,
                                            nsAString& outHTMLContext,
                                            nsAString& outHTMLInfo);
 
   PRBool mInstanceAlreadyUsed;
 
   nsCOMPtr<nsIDOMEvent> mMouseEvent;
@@ -1333,26 +1333,34 @@ nsTransferableFactory::Produce(PRBool* a
   }
 
   if (nodeToSerialize || useSelectedText) {
     // if we have selected text, use it in preference to the node
     if (useSelectedText) {
       nodeToSerialize = nsnull;
     }
 
-    SerializeNodeOrSelection(serializeAsHTML,
-                             nsIDocumentEncoder::OutputAbsoluteLinks |
-                             nsIDocumentEncoder::OutputEncodeW3CEntities,
-                             window, nodeToSerialize,
+    SerializeNodeOrSelection(window, nodeToSerialize,
                              mHtmlString, mContextString, mInfoString);
 
-    nsAutoString dummy1, dummy2;
-    SerializeNodeOrSelection(serializeAsText, 0,
-                             window, nodeToSerialize,
-                             mTitleString, dummy1, dummy2);
+    nsCOMPtr<nsIFormatConverter> htmlConverter =
+      do_CreateInstance(kHTMLConverterCID);
+    NS_ENSURE_TRUE(htmlConverter, NS_ERROR_FAILURE);
+
+    nsCOMPtr<nsISupportsString> html =
+      do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
+    NS_ENSURE_TRUE(html, NS_ERROR_FAILURE);
+    html->SetData(mHtmlString);
+
+    nsCOMPtr<nsISupportsString> text;
+    PRUint32 textLen;
+    htmlConverter->Convert(kHTMLMime, html, mHtmlString.Length() * 2,
+                           kUnicodeMime, getter_AddRefs(text), &textLen);
+    NS_ENSURE_TRUE(text, NS_ERROR_FAILURE);
+    text->GetData(mTitleString);
 
 #ifdef CHANGE_SELECTION_ON_DRAG
     // We used to change the selection to wrap the dragged node (mainly
     // to work around now-fixed issues with dragging unselected elements).
     // There is no reason to do this any more.
     NormalizeSelection(selectionNormalizeNode, selection);
 #endif
   }
@@ -1683,70 +1691,52 @@ void nsTransferableFactory::GetSelectedL
     }
   }
 
   return;
 }
 
 // static
 nsresult
-nsTransferableFactory::SerializeNodeOrSelection(serializationMode inMode,
-                                                PRUint32 inFlags,
-                                                nsIDOMWindow* inWindow,
+nsTransferableFactory::SerializeNodeOrSelection(nsIDOMWindow* inWindow,
                                                 nsIDOMNode* inNode,
                                                 nsAString& outResultString,
                                                 nsAString& outContext,
                                                 nsAString& outInfo)
 {
   NS_ENSURE_ARG_POINTER(inWindow);
 
   nsresult rv;
-  nsCOMPtr<nsIDocumentEncoder> encoder;
-  static const char *textplain = "text/plain";
-
-  if (inMode == serializeAsText) {
-    nsCAutoString formatType(NS_DOC_ENCODER_CONTRACTID_BASE);
-    formatType.Append(textplain);
-    encoder = do_CreateInstance(formatType.get(), &rv);
-  } else {
-    encoder = do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID, &rv);
-  }
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIDocumentEncoder> encoder =
+    do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID);
+  NS_ENSURE_TRUE(encoder, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDOMDocument> domDoc;
   inWindow->GetDocument(getter_AddRefs(domDoc));
   NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
 
+  PRUint32 flags = nsIDocumentEncoder::OutputAbsoluteLinks |
+                   nsIDocumentEncoder::OutputEncodeW3CEntities;
   nsCOMPtr<nsIDOMRange> range;
   nsCOMPtr<nsISelection> selection;
   if (inNode) {
     // make a range around this node
     rv = NS_NewRange(getter_AddRefs(range));
     NS_ENSURE_SUCCESS(rv, rv);
     rv = range->SelectNode(inNode);
     NS_ENSURE_SUCCESS(rv, rv);
   } else {
     inWindow->GetSelection(getter_AddRefs(selection));
-    inFlags |= nsIDocumentEncoder::OutputSelectionOnly;
+    flags |= nsIDocumentEncoder::OutputSelectionOnly;
   }
 
-  if (inMode == serializeAsText) {
-    rv = encoder->Init(domDoc, NS_ConvertASCIItoUTF16(textplain), inFlags);
-  } else {
-    rv = encoder->Init(domDoc, NS_LITERAL_STRING(kHTMLMime), inFlags);
-  }
+  rv = encoder->Init(domDoc, NS_LITERAL_STRING(kHTMLMime), flags);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (range) {
     encoder->SetRange(range);
   } else if (selection) {
     encoder->SetSelection(selection);
   }
 
-  if (inMode == serializeAsText) {
-    outContext.Truncate();
-    outInfo.Truncate();
-    return encoder->EncodeToString(outResultString);
-  }
-
   return encoder->EncodeToStringWithContext(outContext, outInfo,
                                             outResultString);
 }