diff --git a/mozilla/content/base/public/nsIDocumentEncoder.h b/mozilla/content/base/public/nsIDocumentEncoder.h index c07563086b2..ba2666a2df4 100644 --- a/mozilla/content/base/public/nsIDocumentEncoder.h +++ b/mozilla/content/base/public/nsIDocumentEncoder.h @@ -65,11 +65,13 @@ public: * have access to the symbols, not just the constants. */ enum { - // Output only the selection. + // Output only the selection (as opposed to the whole document). OutputSelectionOnly = 1, - // Convert html to plaintext that looks like the html. + // Plaintext output: Convert html to plaintext that looks like the html. // Implies wrap (except inside
), since html wraps.
+    // HTML output: always do prettyprinting, ignoring existing formatting.
+    // (Probably not well tested for HTML output.)
     OutputFormatted     = 2,
 
     // Don't output the html doctype and gecko output system comment headers
diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp
index 2c7bc8e5129..7776f38376d 100644
--- a/mozilla/content/base/src/nsDocument.cpp
+++ b/mozilla/content/base/src/nsDocument.cpp
@@ -56,11 +56,12 @@
 #include "nsICSSStyleSheet.h"
 
 #include "nsITextContent.h"
-#include "nsXIFConverter.h"
+#include "nsIDocumentEncoder.h"
+//#include "nsXIFConverter.h"
 #include "nsIHTMLContentSink.h"
-#include "nsHTMLContentSinkStream.h"
-#include "nsHTMLToTXTSinkStream.h"
-#include "nsXIFDTD.h"
+//#include "nsHTMLContentSinkStream.h"
+//#include "nsHTMLToTXTSinkStream.h"
+//#include "nsXIFDTD.h"
 #include "nsIParser.h"
 #include "nsParserCIID.h"
 #include "nsFileSpec.h"
@@ -3070,9 +3071,13 @@ nsDocument::CreateXIF(nsString & aBuffer, nsIDOMSelection* aSelection)
 static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID);
 static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID);
 
-
+#if 0
 nsresult
-nsDocument::OutputDocumentAs(nsIOutputStream* aStream, nsIDOMSelection* selection, EOutputFormat aOutputFormat, const nsString& aCharset)
+nsDocument::OutputDocumentAs(nsIOutputStream* aStream,
+                             nsIDOMSelection* selection,
+                             EOutputFormat aOutputFormat,
+                             const nsString& aCharset,
+                             PRUint32 aFlags)
 {
   nsresult  rv = NS_OK;
   
@@ -3126,19 +3131,7 @@ nsDocument::OutputDocumentAs(nsIOutputStream* aStream, nsIDOMSelection* selectio
   }
   return rv;
 }
-
-nsresult
-nsDocument::OutputDocumentAsHTML(nsIOutputStream* aStream, nsIDOMSelection* selection, const nsString& aCharset)
-{
- return OutputDocumentAs(aStream, selection, eOutputHTML, aCharset);
-}
-
-nsresult
-nsDocument::OutputDocumentAsText(nsIOutputStream* aStream, nsIDOMSelection* selection, const nsString& aCharset)
-{
- return OutputDocumentAs(aStream, selection, eOutputText, aCharset);
-}
-
+#endif
 
 NS_IMETHODIMP
 nsDocument::InitDiskDocument(nsFileSpec* aFileSpec)
@@ -3159,13 +3152,13 @@ nsDocument::InitDiskDocument(nsFileSpec* aFileSpec)
 
 
 NS_IMETHODIMP
-nsDocument::SaveFile(     nsFileSpec*     aFileSpec,
-                          PRBool          aReplaceExisting,
-                          PRBool          aSaveCopy,
-                          ESaveFileType   aSaveFileType,
-                          const nsString& aSaveCharset)
+nsDocument::SaveFile(nsFileSpec*     aFileSpec,
+                     PRBool          aReplaceExisting,
+                     PRBool          aSaveCopy,
+                     const nsString& aFormatType,
+                     const nsString& aSaveCharset,
+                     PRUint32        aFlags)
 {
-
   if (!aFileSpec)
     return NS_ERROR_NULL_POINTER;
     
@@ -3180,16 +3173,41 @@ nsDocument::SaveFile(     nsFileSpec*     aFileSpec,
   // if the stream didn't open, something went wrong
   if (!stream.is_open())
     return NS_BASE_STREAM_CLOSED;
-  
-  // convert to our internal enum. Shame we have to do this.
-  EOutputFormat  outputFormat = eOutputHTML;
-  switch (aSaveFileType)
+
+  // Get a document encoder instance:
+  nsCOMPtr encoder;
+  char* progid = (char *)nsAllocator::Alloc(strlen(NS_DOC_ENCODER_PROGID_BASE)
+                                            + aFormatType.Length() + 1);
+  if (! progid)
+    return NS_ERROR_OUT_OF_MEMORY;
+  strcpy(progid, NS_DOC_ENCODER_PROGID_BASE);
+  char* type = aFormatType.ToNewCString();
+  strcat(progid, type);
+  nsCRT::free(type);
+  rv = nsComponentManager::CreateInstance(progid,
+                                          nsnull,
+                                          NS_GET_IID(nsIDocumentEncoder),
+                                          getter_AddRefs(encoder));
+  nsCRT::free(progid);
+  if (NS_FAILED(rv))
+    return rv;
+
+  rv = encoder->Init(this, aFormatType, aFlags);
+  if (NS_FAILED(rv))
+    return rv;
+
+  nsAutoString charsetStr = aSaveCharset;
+  if (charsetStr.Length() == 0)
   {
-    case eSaveFileText:    outputFormat = eOutputText;  break;
-    case eSaveFileHTML:    outputFormat = eOutputHTML;  break;
+	  rv = GetDocumentCharacterSet(charsetStr);
+	  if(NS_FAILED(rv)) {
+	     charsetStr.AssignWithConversion("ISO-8859-1"); 
+	  }
   }
-  
-  rv = OutputDocumentAs(stream.GetIStream(), nsnull, outputFormat, aSaveCharset);
+  encoder->SetCharset(aSaveCharset);
+
+  rv = encoder->EncodeToStream(stream.GetIStream());
+
   if (NS_SUCCEEDED(rv))
   {
     // if everything went OK and we're not just saving off a copy,
diff --git a/mozilla/content/base/src/nsDocument.h b/mozilla/content/base/src/nsDocument.h
index 2d8343a8434..1af7f524dd6 100644
--- a/mozilla/content/base/src/nsDocument.h
+++ b/mozilla/content/base/src/nsDocument.h
@@ -366,11 +366,12 @@ public:
 
   // nsIDiskDocument inteface
   NS_IMETHOD  InitDiskDocument(nsFileSpec *aFileSpec);
-  NS_IMETHOD  SaveFile(     nsFileSpec*     aFileSpec,
-                            PRBool          aReplaceExisting,
-                            PRBool          aSaveCopy,
-                            ESaveFileType   aSaveFileType,
-                            const nsString& aSaveCharset);
+  NS_IMETHOD  SaveFile(nsFileSpec*     aFileSpec,
+                       PRBool          aReplaceExisting,
+                       PRBool          aSaveCopy,
+                       const nsString& aSaveFileType,
+                       const nsString& aSaveCharset,
+                       PRUint32        aFlags);
 
   NS_IMETHOD  GetFileSpec(nsFileSpec& aFileSpec);
   NS_IMETHOD  GetModCount(PRInt32 *outModCount);
@@ -411,36 +412,12 @@ public:
   virtual PRBool    Convert(JSContext *aContext, JSObject *aObj, jsval aID);
   virtual void      Finalize(JSContext *aContext, JSObject *aObj);
 
-  /**
-    * Methods to output the document contents as Text or HTML, outputting into
-    * the given output stream. If charset is not an empty string, the contents
-    * will be converted into the given charset.
-    *
-    * If the selection is passed in is not null, only the selected content
-    * will be output. Note that the selection is stored on a per-presentation
-    * shell basis, not per document, hence it is a parameter here.
-    * These should be exposed in an interface, but aren't yet.
-    */
-
-  virtual nsresult  OutputDocumentAsText(nsIOutputStream* aStream, nsIDOMSelection* selection, const nsString& aCharset);
-  virtual nsresult  OutputDocumentAsHTML(nsIOutputStream* aStream, nsIDOMSelection* selection, const nsString& aCharset);
-
 protected:
   nsIContent* FindContent(const nsIContent* aStartNode,
                           const nsIContent* aTest1, 
                           const nsIContent* aTest2) const;
   virtual nsresult Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup);
 
-	// this enum is temporary; there should be no knowledge of HTML in
-	// nsDocument. That will be fixed when content sink stream factories
-	// are available.
-  enum EOutputFormat {
-    eOutputText,
-    eOutputHTML
-  };
-
-	virtual nsresult  OutputDocumentAs(nsIOutputStream* aStream, nsIDOMSelection* selection, EOutputFormat aOutputFormat, const nsString& aCharset);
-
   nsresult GetPixelDimensions(nsIPresShell* aShell,
                               PRInt32* aWidth,
                               PRInt32* aHeight);
diff --git a/mozilla/content/base/src/nsSelection.cpp b/mozilla/content/base/src/nsSelection.cpp
index 83be3aa908e..7a249086634 100644
--- a/mozilla/content/base/src/nsSelection.cpp
+++ b/mozilla/content/base/src/nsSelection.cpp
@@ -1388,6 +1388,19 @@ nsSelection::MoveCaret(PRUint32 aKeycode, PRBool aContinue, nsSelectionAmount aA
     {
       if (NS_SUCCEEDED(result = frame->PeekOffset(context, &pos)) && pos.mResultContent)
       {
+  /* Some parts of pos which might come in handy:
+   *  @param mDirection enum defined in this file to be eForward or eBackward
+   *  @param mStartOffset start offset to start the peek. 0 == beginning -1 = end
+   *  @param mResultContent content that actually is the next/previous
+   *  @param mResultOffset offset for result content
+   *  @param mEatingWS boolean to tell us the state of our search for Next/Prev
+   *  @param mPreferLeft true = prev line end, false = next line begin
+   */
+        if (pos.mAmount == eWord)
+        {
+          // Word selection: layout treats punctuation as part of
+          // the word; we may not want to do that.
+        }
         mHint = (HINT)pos.mPreferLeft;
         result = TakeFocus(pos.mResultContent, pos.mContentOffset, pos.mContentOffset, aContinue, PR_FALSE);
       }
diff --git a/mozilla/editor/base/nsEditor.cpp b/mozilla/editor/base/nsEditor.cpp
index 9b21eda1600..5bb01ccab6c 100644
--- a/mozilla/editor/base/nsEditor.cpp
+++ b/mozilla/editor/base/nsEditor.cpp
@@ -71,6 +71,7 @@
 
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
+#include "nsIDocumentEncoder.h"
 #include "nsLayoutCID.h"
 
 // transactions the editor knows how to build
@@ -107,6 +108,7 @@
 static NS_DEFINE_CID(kCRangeCID,            NS_RANGE_CID);
 static NS_DEFINE_CID(kCContentIteratorCID,  NS_CONTENTITERATOR_CID);
 static NS_DEFINE_CID(kCDOMRangeCID,         NS_RANGE_CID);
+static NS_DEFINE_CID(kPrefServiceCID,       NS_PREF_CID);
 
 // transaction manager
 static NS_DEFINE_CID(kCTransactionManagerCID, NS_TRANSACTIONMANAGER_CID);
@@ -1434,41 +1436,52 @@ nsEditor::SetDocumentCharacterSet(const PRUnichar* characterSet)
   if (NS_SUCCEEDED(rv))
   {
     presShell->GetDocument(getter_AddRefs(doc));
-    if (doc ) {
-    return doc->SetDocumentCharacterSet(character_set);
-  }
+    if (doc) {
+      return doc->SetDocumentCharacterSet(character_set);
+    }
   }
 
   return rv;
 }
 
 NS_IMETHODIMP 
-nsEditor::SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting, PRBool aSaveCopy, nsIDiskDocument::ESaveFileType aSaveFileType)
+nsEditor::SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting,
+                   PRBool aSaveCopy, const nsString& aFormat)
 {
   if (!aFileSpec)
     return NS_ERROR_NULL_POINTER;
   
   ForceCompositionEnd();
-  
 
   // get the document
   nsCOMPtr doc;
-  nsresult res = GetDocument(getter_AddRefs(doc));
-  if (NS_FAILED(res)) return res;
+  nsresult rv = GetDocument(getter_AddRefs(doc));
+  if (NS_FAILED(rv)) return rv;
   if (!doc) return NS_ERROR_NULL_POINTER;
   
   nsCOMPtr diskDoc = do_QueryInterface(doc);
   if (!diskDoc)
     return NS_ERROR_NO_INTERFACE;
 
+  // Should we prettyprint?
+  PRUint32 flags = 0;
+  NS_WITH_SERVICE(nsIPref, prefService, kPrefServiceCID, &rv);
+  if (NS_SUCCEEDED(rv) && prefService)
+  {
+    PRBool prettyprint = PR_FALSE;;
+    rv = prefService->GetBoolPref("editor.prettyprint", &prettyprint);
+    if (NS_SUCCEEDED(rv) && prettyprint)
+      flags |= nsIDocumentEncoder::OutputFormatted;
+  }
+
   nsAutoString useDocCharset;
 
-  res = diskDoc->SaveFile(aFileSpec, aReplaceExisting, aSaveCopy, 
-                          aSaveFileType, useDocCharset);
-  if (NS_SUCCEEDED(res))
+  rv = diskDoc->SaveFile(aFileSpec, aReplaceExisting, aSaveCopy, 
+                          aFormat, useDocCharset, flags);
+  if (NS_SUCCEEDED(rv))
     DoAfterDocumentSave();
 
-  return res;
+  return rv;
 }
 
 NS_IMETHODIMP 
diff --git a/mozilla/editor/base/nsEditor.h b/mozilla/editor/base/nsEditor.h
index d272a5252ad..1039a5bdf42 100644
--- a/mozilla/editor/base/nsEditor.h
+++ b/mozilla/editor/base/nsEditor.h
@@ -216,7 +216,7 @@ public:
   NS_IMETHOD GetDocumentModified(PRBool *outDocModified);
   NS_IMETHOD GetDocumentCharacterSet(PRUnichar** characterSet);
   NS_IMETHOD SetDocumentCharacterSet(const PRUnichar* characterSet);
-  NS_IMETHOD SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting, PRBool aSaveCopy, nsIDiskDocument::ESaveFileType aSaveFileType);
+  NS_IMETHOD SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting, PRBool aSaveCopy, const nsString& aFormat);
 
   // these are pure virtual in this base class
   NS_IMETHOD Cut() = 0;
diff --git a/mozilla/editor/base/nsEditorEventListeners.cpp b/mozilla/editor/base/nsEditorEventListeners.cpp
index da1cf8d4bbc..10b753cb68e 100644
--- a/mozilla/editor/base/nsEditorEventListeners.cpp
+++ b/mozilla/editor/base/nsEditorEventListeners.cpp
@@ -496,7 +496,7 @@ nsTextEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
     NS_WITH_SERVICE(nsIPref, prefService, kPrefServiceCID, &rv);
     if (NS_SUCCEEDED(rv) && prefService)
     {
-      PRInt32 doMiddleMousePaste = PR_FALSE;;
+      PRBool doMiddleMousePaste = PR_FALSE;;
       rv = prefService->GetBoolPref("middlemouse.paste", &doMiddleMousePaste);
       if (NS_SUCCEEDED(rv) && doMiddleMousePaste)
       {
diff --git a/mozilla/editor/base/nsEditorShell.cpp b/mozilla/editor/base/nsEditorShell.cpp
index 8b8982868ba..29fac1b1695 100644
--- a/mozilla/editor/base/nsEditorShell.cpp
+++ b/mozilla/editor/base/nsEditorShell.cpp
@@ -1510,7 +1510,9 @@ nsEditorShell::SaveDocument(PRBool saveAs, PRBool saveCopy, PRBool *_retval)
         // TODO: Get the file type (from the extension?) the user set for the file
         // How do we do this in an XP way??? 
         // For now, just save as HTML type
-        res = editor->SaveFile(&docFileSpec, replacing, saveCopy, nsIDiskDocument::eSaveFileHTML);
+        nsString format;
+        format.AssignWithConversion("text/html");
+        res = editor->SaveFile(&docFileSpec, replacing, saveCopy, format);
         if (NS_FAILED(res))
         {
           nsAutoString saveDocStr, failedStr;
diff --git a/mozilla/editor/base/nsHTMLEditor.cpp b/mozilla/editor/base/nsHTMLEditor.cpp
index d73df29f238..5015b1e03db 100644
--- a/mozilla/editor/base/nsHTMLEditor.cpp
+++ b/mozilla/editor/base/nsHTMLEditor.cpp
@@ -4811,10 +4811,7 @@ NS_IMETHODIMP nsHTMLEditor::OutputToString(nsString& aOutputString,
 
     nsCRT::free(progid);
     if (NS_FAILED(rv))
-    {
-      printf("Couldn't get progid %s\n", progid);
       return rv;
-    }
 
     nsCOMPtr domdoc;
     rv = GetDocument(getter_AddRefs(domdoc));
diff --git a/mozilla/editor/composer/src/nsEditorShell.cpp b/mozilla/editor/composer/src/nsEditorShell.cpp
index 8b8982868ba..29fac1b1695 100644
--- a/mozilla/editor/composer/src/nsEditorShell.cpp
+++ b/mozilla/editor/composer/src/nsEditorShell.cpp
@@ -1510,7 +1510,9 @@ nsEditorShell::SaveDocument(PRBool saveAs, PRBool saveCopy, PRBool *_retval)
         // TODO: Get the file type (from the extension?) the user set for the file
         // How do we do this in an XP way??? 
         // For now, just save as HTML type
-        res = editor->SaveFile(&docFileSpec, replacing, saveCopy, nsIDiskDocument::eSaveFileHTML);
+        nsString format;
+        format.AssignWithConversion("text/html");
+        res = editor->SaveFile(&docFileSpec, replacing, saveCopy, format);
         if (NS_FAILED(res))
         {
           nsAutoString saveDocStr, failedStr;
diff --git a/mozilla/editor/libeditor/base/nsEditor.cpp b/mozilla/editor/libeditor/base/nsEditor.cpp
index 9b21eda1600..5bb01ccab6c 100644
--- a/mozilla/editor/libeditor/base/nsEditor.cpp
+++ b/mozilla/editor/libeditor/base/nsEditor.cpp
@@ -71,6 +71,7 @@
 
 #include "nsIContent.h"
 #include "nsIContentIterator.h"
+#include "nsIDocumentEncoder.h"
 #include "nsLayoutCID.h"
 
 // transactions the editor knows how to build
@@ -107,6 +108,7 @@
 static NS_DEFINE_CID(kCRangeCID,            NS_RANGE_CID);
 static NS_DEFINE_CID(kCContentIteratorCID,  NS_CONTENTITERATOR_CID);
 static NS_DEFINE_CID(kCDOMRangeCID,         NS_RANGE_CID);
+static NS_DEFINE_CID(kPrefServiceCID,       NS_PREF_CID);
 
 // transaction manager
 static NS_DEFINE_CID(kCTransactionManagerCID, NS_TRANSACTIONMANAGER_CID);
@@ -1434,41 +1436,52 @@ nsEditor::SetDocumentCharacterSet(const PRUnichar* characterSet)
   if (NS_SUCCEEDED(rv))
   {
     presShell->GetDocument(getter_AddRefs(doc));
-    if (doc ) {
-    return doc->SetDocumentCharacterSet(character_set);
-  }
+    if (doc) {
+      return doc->SetDocumentCharacterSet(character_set);
+    }
   }
 
   return rv;
 }
 
 NS_IMETHODIMP 
-nsEditor::SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting, PRBool aSaveCopy, nsIDiskDocument::ESaveFileType aSaveFileType)
+nsEditor::SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting,
+                   PRBool aSaveCopy, const nsString& aFormat)
 {
   if (!aFileSpec)
     return NS_ERROR_NULL_POINTER;
   
   ForceCompositionEnd();
-  
 
   // get the document
   nsCOMPtr doc;
-  nsresult res = GetDocument(getter_AddRefs(doc));
-  if (NS_FAILED(res)) return res;
+  nsresult rv = GetDocument(getter_AddRefs(doc));
+  if (NS_FAILED(rv)) return rv;
   if (!doc) return NS_ERROR_NULL_POINTER;
   
   nsCOMPtr diskDoc = do_QueryInterface(doc);
   if (!diskDoc)
     return NS_ERROR_NO_INTERFACE;
 
+  // Should we prettyprint?
+  PRUint32 flags = 0;
+  NS_WITH_SERVICE(nsIPref, prefService, kPrefServiceCID, &rv);
+  if (NS_SUCCEEDED(rv) && prefService)
+  {
+    PRBool prettyprint = PR_FALSE;;
+    rv = prefService->GetBoolPref("editor.prettyprint", &prettyprint);
+    if (NS_SUCCEEDED(rv) && prettyprint)
+      flags |= nsIDocumentEncoder::OutputFormatted;
+  }
+
   nsAutoString useDocCharset;
 
-  res = diskDoc->SaveFile(aFileSpec, aReplaceExisting, aSaveCopy, 
-                          aSaveFileType, useDocCharset);
-  if (NS_SUCCEEDED(res))
+  rv = diskDoc->SaveFile(aFileSpec, aReplaceExisting, aSaveCopy, 
+                          aFormat, useDocCharset, flags);
+  if (NS_SUCCEEDED(rv))
     DoAfterDocumentSave();
 
-  return res;
+  return rv;
 }
 
 NS_IMETHODIMP 
diff --git a/mozilla/editor/libeditor/base/nsEditor.h b/mozilla/editor/libeditor/base/nsEditor.h
index d272a5252ad..1039a5bdf42 100644
--- a/mozilla/editor/libeditor/base/nsEditor.h
+++ b/mozilla/editor/libeditor/base/nsEditor.h
@@ -216,7 +216,7 @@ public:
   NS_IMETHOD GetDocumentModified(PRBool *outDocModified);
   NS_IMETHOD GetDocumentCharacterSet(PRUnichar** characterSet);
   NS_IMETHOD SetDocumentCharacterSet(const PRUnichar* characterSet);
-  NS_IMETHOD SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting, PRBool aSaveCopy, nsIDiskDocument::ESaveFileType aSaveFileType);
+  NS_IMETHOD SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting, PRBool aSaveCopy, const nsString& aFormat);
 
   // these are pure virtual in this base class
   NS_IMETHOD Cut() = 0;
diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp
index d73df29f238..5015b1e03db 100644
--- a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp
@@ -4811,10 +4811,7 @@ NS_IMETHODIMP nsHTMLEditor::OutputToString(nsString& aOutputString,
 
     nsCRT::free(progid);
     if (NS_FAILED(rv))
-    {
-      printf("Couldn't get progid %s\n", progid);
       return rv;
-    }
 
     nsCOMPtr domdoc;
     rv = GetDocument(getter_AddRefs(domdoc));
diff --git a/mozilla/editor/libeditor/text/nsEditorEventListeners.cpp b/mozilla/editor/libeditor/text/nsEditorEventListeners.cpp
index da1cf8d4bbc..10b753cb68e 100644
--- a/mozilla/editor/libeditor/text/nsEditorEventListeners.cpp
+++ b/mozilla/editor/libeditor/text/nsEditorEventListeners.cpp
@@ -496,7 +496,7 @@ nsTextEditorMouseListener::MouseDown(nsIDOMEvent* aMouseEvent)
     NS_WITH_SERVICE(nsIPref, prefService, kPrefServiceCID, &rv);
     if (NS_SUCCEEDED(rv) && prefService)
     {
-      PRInt32 doMiddleMousePaste = PR_FALSE;;
+      PRBool doMiddleMousePaste = PR_FALSE;;
       rv = prefService->GetBoolPref("middlemouse.paste", &doMiddleMousePaste);
       if (NS_SUCCEEDED(rv) && doMiddleMousePaste)
       {
diff --git a/mozilla/editor/public/nsIEditor.h b/mozilla/editor/public/nsIEditor.h
index 2bb79827724..5561f635cba 100644
--- a/mozilla/editor/public/nsIEditor.h
+++ b/mozilla/editor/public/nsIEditor.h
@@ -143,8 +143,10 @@ public:
    *          without changing the disk file associated with the doc.
    *          This would correspond to a 'Save Copy As' menu command
    *          (currently not in our UI)
+   *  @param aFormat
+   *          Mime type to save (text/plain or text/html)
    */
-  NS_IMETHOD SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting, PRBool aSaveCopy, nsIDiskDocument::ESaveFileType aSaveFileType)=0;
+  NS_IMETHOD SaveFile(nsFileSpec *aFileSpec, PRBool aReplaceExisting, PRBool aSaveCopy, const nsString& aFormat)=0;
 
   /* ------------ Transaction methods -------------- */
 
diff --git a/mozilla/layout/base/public/nsIDiskDocument.h b/mozilla/layout/base/public/nsIDiskDocument.h
index 99ff1c2f567..cd386e6a9e8 100644
--- a/mozilla/layout/base/public/nsIDiskDocument.h
+++ b/mozilla/layout/base/public/nsIDiskDocument.h
@@ -52,7 +52,6 @@ public:
 
   static const nsIID& GetIID() { static nsIID iid = NS_IDISKDOCUMENT_IID; return iid; }
 
-	typedef enum {eSaveFileText = 0, eSaveFileHTML = 1 } ESaveFileType;
 	//typedef enum {eFileDiskFile = 0, eFileRemote = 1 } ESaveFileLocation;
 
   /** Initialize the document output. This may be called on document
@@ -74,15 +73,17 @@ public:
     *    												If false and aFileSpec exists, SaveFile returns an error.
     * @param inSaveCopy					True to save a copy of the file, without changing the file
     *														referenced internally.
-    * @param inSaveFileType			File type to save (text or HTML)
+    * @param inSaveFileType			Mime type to save (text/plain or text/html)
     * @param inSaveCharset			Charset to save the document in. If this is an empty
     *    												string, or "UCS2", then the doc will be saved as Unicode.
+    * @param inSaveFlags        Flags (see nsIDocumentEncoder).  If unsure, use 0.
     */
   NS_IMETHOD SaveFile(			nsFileSpec*			inFileSpec,
   													PRBool 					inReplaceExisting,
   													PRBool					inSaveCopy,
-  													ESaveFileType 	inSaveFileType,
-  													const nsString&	inSaveCharset)=0;
+  													const nsString&	inSaveFileType,
+  													const nsString&	inSaveCharset,
+                            PRUint32        inSaveFlags)=0;
   
   /** Return a file spec for the file. If the file has not been saved yet,
     * and thus has no fileSpec, this will return NS_ERROR_NOT_INITIALIZED.
diff --git a/mozilla/layout/base/public/nsIDocumentEncoder.h b/mozilla/layout/base/public/nsIDocumentEncoder.h
index c07563086b2..ba2666a2df4 100644
--- a/mozilla/layout/base/public/nsIDocumentEncoder.h
+++ b/mozilla/layout/base/public/nsIDocumentEncoder.h
@@ -65,11 +65,13 @@ public:
    * have access to the symbols, not just the constants.
    */
   enum {
-    // Output only the selection.
+    // Output only the selection (as opposed to the whole document).
     OutputSelectionOnly = 1,
 
-    // Convert html to plaintext that looks like the html.
+    // Plaintext output: Convert html to plaintext that looks like the html.
     // Implies wrap (except inside 
), since html wraps.
+    // HTML output: always do prettyprinting, ignoring existing formatting.
+    // (Probably not well tested for HTML output.)
     OutputFormatted     = 2,
 
     // Don't output the html doctype and gecko output system comment headers
diff --git a/mozilla/layout/base/src/nsDocument.cpp b/mozilla/layout/base/src/nsDocument.cpp
index 2c7bc8e5129..7776f38376d 100644
--- a/mozilla/layout/base/src/nsDocument.cpp
+++ b/mozilla/layout/base/src/nsDocument.cpp
@@ -56,11 +56,12 @@
 #include "nsICSSStyleSheet.h"
 
 #include "nsITextContent.h"
-#include "nsXIFConverter.h"
+#include "nsIDocumentEncoder.h"
+//#include "nsXIFConverter.h"
 #include "nsIHTMLContentSink.h"
-#include "nsHTMLContentSinkStream.h"
-#include "nsHTMLToTXTSinkStream.h"
-#include "nsXIFDTD.h"
+//#include "nsHTMLContentSinkStream.h"
+//#include "nsHTMLToTXTSinkStream.h"
+//#include "nsXIFDTD.h"
 #include "nsIParser.h"
 #include "nsParserCIID.h"
 #include "nsFileSpec.h"
@@ -3070,9 +3071,13 @@ nsDocument::CreateXIF(nsString & aBuffer, nsIDOMSelection* aSelection)
 static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID);
 static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID);
 
-
+#if 0
 nsresult
-nsDocument::OutputDocumentAs(nsIOutputStream* aStream, nsIDOMSelection* selection, EOutputFormat aOutputFormat, const nsString& aCharset)
+nsDocument::OutputDocumentAs(nsIOutputStream* aStream,
+                             nsIDOMSelection* selection,
+                             EOutputFormat aOutputFormat,
+                             const nsString& aCharset,
+                             PRUint32 aFlags)
 {
   nsresult  rv = NS_OK;
   
@@ -3126,19 +3131,7 @@ nsDocument::OutputDocumentAs(nsIOutputStream* aStream, nsIDOMSelection* selectio
   }
   return rv;
 }
-
-nsresult
-nsDocument::OutputDocumentAsHTML(nsIOutputStream* aStream, nsIDOMSelection* selection, const nsString& aCharset)
-{
- return OutputDocumentAs(aStream, selection, eOutputHTML, aCharset);
-}
-
-nsresult
-nsDocument::OutputDocumentAsText(nsIOutputStream* aStream, nsIDOMSelection* selection, const nsString& aCharset)
-{
- return OutputDocumentAs(aStream, selection, eOutputText, aCharset);
-}
-
+#endif
 
 NS_IMETHODIMP
 nsDocument::InitDiskDocument(nsFileSpec* aFileSpec)
@@ -3159,13 +3152,13 @@ nsDocument::InitDiskDocument(nsFileSpec* aFileSpec)
 
 
 NS_IMETHODIMP
-nsDocument::SaveFile(     nsFileSpec*     aFileSpec,
-                          PRBool          aReplaceExisting,
-                          PRBool          aSaveCopy,
-                          ESaveFileType   aSaveFileType,
-                          const nsString& aSaveCharset)
+nsDocument::SaveFile(nsFileSpec*     aFileSpec,
+                     PRBool          aReplaceExisting,
+                     PRBool          aSaveCopy,
+                     const nsString& aFormatType,
+                     const nsString& aSaveCharset,
+                     PRUint32        aFlags)
 {
-
   if (!aFileSpec)
     return NS_ERROR_NULL_POINTER;
     
@@ -3180,16 +3173,41 @@ nsDocument::SaveFile(     nsFileSpec*     aFileSpec,
   // if the stream didn't open, something went wrong
   if (!stream.is_open())
     return NS_BASE_STREAM_CLOSED;
-  
-  // convert to our internal enum. Shame we have to do this.
-  EOutputFormat  outputFormat = eOutputHTML;
-  switch (aSaveFileType)
+
+  // Get a document encoder instance:
+  nsCOMPtr encoder;
+  char* progid = (char *)nsAllocator::Alloc(strlen(NS_DOC_ENCODER_PROGID_BASE)
+                                            + aFormatType.Length() + 1);
+  if (! progid)
+    return NS_ERROR_OUT_OF_MEMORY;
+  strcpy(progid, NS_DOC_ENCODER_PROGID_BASE);
+  char* type = aFormatType.ToNewCString();
+  strcat(progid, type);
+  nsCRT::free(type);
+  rv = nsComponentManager::CreateInstance(progid,
+                                          nsnull,
+                                          NS_GET_IID(nsIDocumentEncoder),
+                                          getter_AddRefs(encoder));
+  nsCRT::free(progid);
+  if (NS_FAILED(rv))
+    return rv;
+
+  rv = encoder->Init(this, aFormatType, aFlags);
+  if (NS_FAILED(rv))
+    return rv;
+
+  nsAutoString charsetStr = aSaveCharset;
+  if (charsetStr.Length() == 0)
   {
-    case eSaveFileText:    outputFormat = eOutputText;  break;
-    case eSaveFileHTML:    outputFormat = eOutputHTML;  break;
+	  rv = GetDocumentCharacterSet(charsetStr);
+	  if(NS_FAILED(rv)) {
+	     charsetStr.AssignWithConversion("ISO-8859-1"); 
+	  }
   }
-  
-  rv = OutputDocumentAs(stream.GetIStream(), nsnull, outputFormat, aSaveCharset);
+  encoder->SetCharset(aSaveCharset);
+
+  rv = encoder->EncodeToStream(stream.GetIStream());
+
   if (NS_SUCCEEDED(rv))
   {
     // if everything went OK and we're not just saving off a copy,
diff --git a/mozilla/layout/base/src/nsDocument.h b/mozilla/layout/base/src/nsDocument.h
index 2d8343a8434..1af7f524dd6 100644
--- a/mozilla/layout/base/src/nsDocument.h
+++ b/mozilla/layout/base/src/nsDocument.h
@@ -366,11 +366,12 @@ public:
 
   // nsIDiskDocument inteface
   NS_IMETHOD  InitDiskDocument(nsFileSpec *aFileSpec);
-  NS_IMETHOD  SaveFile(     nsFileSpec*     aFileSpec,
-                            PRBool          aReplaceExisting,
-                            PRBool          aSaveCopy,
-                            ESaveFileType   aSaveFileType,
-                            const nsString& aSaveCharset);
+  NS_IMETHOD  SaveFile(nsFileSpec*     aFileSpec,
+                       PRBool          aReplaceExisting,
+                       PRBool          aSaveCopy,
+                       const nsString& aSaveFileType,
+                       const nsString& aSaveCharset,
+                       PRUint32        aFlags);
 
   NS_IMETHOD  GetFileSpec(nsFileSpec& aFileSpec);
   NS_IMETHOD  GetModCount(PRInt32 *outModCount);
@@ -411,36 +412,12 @@ public:
   virtual PRBool    Convert(JSContext *aContext, JSObject *aObj, jsval aID);
   virtual void      Finalize(JSContext *aContext, JSObject *aObj);
 
-  /**
-    * Methods to output the document contents as Text or HTML, outputting into
-    * the given output stream. If charset is not an empty string, the contents
-    * will be converted into the given charset.
-    *
-    * If the selection is passed in is not null, only the selected content
-    * will be output. Note that the selection is stored on a per-presentation
-    * shell basis, not per document, hence it is a parameter here.
-    * These should be exposed in an interface, but aren't yet.
-    */
-
-  virtual nsresult  OutputDocumentAsText(nsIOutputStream* aStream, nsIDOMSelection* selection, const nsString& aCharset);
-  virtual nsresult  OutputDocumentAsHTML(nsIOutputStream* aStream, nsIDOMSelection* selection, const nsString& aCharset);
-
 protected:
   nsIContent* FindContent(const nsIContent* aStartNode,
                           const nsIContent* aTest1, 
                           const nsIContent* aTest2) const;
   virtual nsresult Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup);
 
-	// this enum is temporary; there should be no knowledge of HTML in
-	// nsDocument. That will be fixed when content sink stream factories
-	// are available.
-  enum EOutputFormat {
-    eOutputText,
-    eOutputHTML
-  };
-
-	virtual nsresult  OutputDocumentAs(nsIOutputStream* aStream, nsIDOMSelection* selection, EOutputFormat aOutputFormat, const nsString& aCharset);
-
   nsresult GetPixelDimensions(nsIPresShell* aShell,
                               PRInt32* aWidth,
                               PRInt32* aHeight);
diff --git a/mozilla/layout/base/src/nsSelection.cpp b/mozilla/layout/base/src/nsSelection.cpp
index 83be3aa908e..7a249086634 100644
--- a/mozilla/layout/base/src/nsSelection.cpp
+++ b/mozilla/layout/base/src/nsSelection.cpp
@@ -1388,6 +1388,19 @@ nsSelection::MoveCaret(PRUint32 aKeycode, PRBool aContinue, nsSelectionAmount aA
     {
       if (NS_SUCCEEDED(result = frame->PeekOffset(context, &pos)) && pos.mResultContent)
       {
+  /* Some parts of pos which might come in handy:
+   *  @param mDirection enum defined in this file to be eForward or eBackward
+   *  @param mStartOffset start offset to start the peek. 0 == beginning -1 = end
+   *  @param mResultContent content that actually is the next/previous
+   *  @param mResultOffset offset for result content
+   *  @param mEatingWS boolean to tell us the state of our search for Next/Prev
+   *  @param mPreferLeft true = prev line end, false = next line begin
+   */
+        if (pos.mAmount == eWord)
+        {
+          // Word selection: layout treats punctuation as part of
+          // the word; we may not want to do that.
+        }
         mHint = (HINT)pos.mPreferLeft;
         result = TakeFocus(pos.mResultContent, pos.mContentOffset, pos.mContentOffset, aContinue, PR_FALSE);
       }
diff --git a/mozilla/layout/base/src/nsXIFConverter.cpp b/mozilla/layout/base/src/nsXIFConverter.cpp
index bd21d301233..df7c49d9476 100644
--- a/mozilla/layout/base/src/nsXIFConverter.cpp
+++ b/mozilla/layout/base/src/nsXIFConverter.cpp
@@ -31,6 +31,8 @@ nsXIFConverter::nsXIFConverter(nsString& aBuffer)
 {
   MOZ_COUNT_CTOR(nsXIFConverter);
 
+  mInScript = PR_FALSE;
+
   char* prolog = "\n";
   char* doctype = "\n";
 
@@ -245,6 +247,10 @@ void nsXIFConverter::AddEndTag(nsIAtom* aTag, PRBool aDoIndent, PRBool aDoReturn
 
 PRBool  nsXIFConverter::IsMarkupEntity(const PRUnichar aChar)
 {
+  // If we're in a script, pass entities straight through without conversion:
+  if (mInScript)
+    return PR_FALSE;
+
   PRBool result = PR_FALSE;
   switch (aChar)
   {
@@ -386,6 +392,10 @@ void nsXIFConverter::BeginContainer(const nsString& aTag)
   BeginStartTag(container);
     AddAttribute(mIsa,aTag);
   FinishStartTag(container,PR_FALSE,PR_FALSE);
+
+  // Remember if we're inside a script tag:
+  if (aTag.EqualsWithConversion("script") || aTag.EqualsWithConversion("style"))
+    mInScript = PR_TRUE;
 }
 
 void nsXIFConverter::EndContainer(const nsString& aTag)
@@ -395,6 +405,10 @@ void nsXIFConverter::EndContainer(const nsString& aTag)
   AddEndTag(container,PR_TRUE,PR_FALSE);
   AddComment(aTag);
   mBuffer.Append(mLF);
+
+  // Remember if we're exiting a script tag:
+  if (aTag.EqualsWithConversion("script") || aTag.EqualsWithConversion("style"))
+    mInScript = PR_FALSE;
 }
 
 
diff --git a/mozilla/layout/base/src/nsXIFConverter.h b/mozilla/layout/base/src/nsXIFConverter.h
index 07df55657ae..c1e68cb5834 100644
--- a/mozilla/layout/base/src/nsXIFConverter.h
+++ b/mozilla/layout/base/src/nsXIFConverter.h
@@ -47,6 +47,10 @@ private:
   nsString mSelector;
   nsString mRule;
   nsString mSheet;
+
+  // We need to remember when we're inside a script,
+  // and not encode entities in that case:
+  PRBool mInScript;
    
   nsString mNULL;
   nsString mSpacing;
diff --git a/mozilla/layout/generic/nsSelection.cpp b/mozilla/layout/generic/nsSelection.cpp
index 83be3aa908e..7a249086634 100644
--- a/mozilla/layout/generic/nsSelection.cpp
+++ b/mozilla/layout/generic/nsSelection.cpp
@@ -1388,6 +1388,19 @@ nsSelection::MoveCaret(PRUint32 aKeycode, PRBool aContinue, nsSelectionAmount aA
     {
       if (NS_SUCCEEDED(result = frame->PeekOffset(context, &pos)) && pos.mResultContent)
       {
+  /* Some parts of pos which might come in handy:
+   *  @param mDirection enum defined in this file to be eForward or eBackward
+   *  @param mStartOffset start offset to start the peek. 0 == beginning -1 = end
+   *  @param mResultContent content that actually is the next/previous
+   *  @param mResultOffset offset for result content
+   *  @param mEatingWS boolean to tell us the state of our search for Next/Prev
+   *  @param mPreferLeft true = prev line end, false = next line begin
+   */
+        if (pos.mAmount == eWord)
+        {
+          // Word selection: layout treats punctuation as part of
+          // the word; we may not want to do that.
+        }
         mHint = (HINT)pos.mPreferLeft;
         result = TakeFocus(pos.mResultContent, pos.mContentOffset, pos.mContentOffset, aContinue, PR_FALSE);
       }