diff --git a/mozilla/editor/base/nsEditRules.h b/mozilla/editor/base/nsEditRules.h index eb97e6c6b18..e8818ad8cfa 100644 --- a/mozilla/editor/base/nsEditRules.h +++ b/mozilla/editor/base/nsEditRules.h @@ -48,7 +48,7 @@ public: NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult)=0; NS_IMETHOD GetFlags(PRUint32 *aFlags)=0; NS_IMETHOD SetFlags(PRUint32 aFlags)=0; - + NS_IMETHOD DocumentIsEmpty(PRBool *aDocumentIsEmpty)=0; }; #endif //nsEditRules_h__ diff --git a/mozilla/editor/base/nsEditor.h b/mozilla/editor/base/nsEditor.h index 0db1f18d774..9a66efcf106 100644 --- a/mozilla/editor/base/nsEditor.h +++ b/mozilla/editor/base/nsEditor.h @@ -121,6 +121,9 @@ public: NS_IMETHOD BeginTransaction(); NS_IMETHOD EndTransaction(); + // pure virtual, because the definition of 'empty' depends on the doc type + NS_IMETHOD GetDocumentIsEmpty(PRBool *aDocumentIsEmpty)=0; + // file handling NS_IMETHOD GetDocumentModified(PRBool *outDocModified); NS_IMETHOD GetDocumentCharacterSet(PRUnichar** characterSet); diff --git a/mozilla/editor/base/nsEditorShell.cpp b/mozilla/editor/base/nsEditorShell.cpp index 870ecc796f4..da7e6c61ff1 100644 --- a/mozilla/editor/base/nsEditorShell.cpp +++ b/mozilla/editor/base/nsEditorShell.cpp @@ -2019,15 +2019,9 @@ nsEditorShell::GetEditorDocument(nsIDOMDocument** aEditorDocument) NS_IMETHODIMP nsEditorShell::GetEditorSelection(nsIDOMSelection** aEditorSelection) { - - if (mEditor) - { - nsCOMPtr editor = do_QueryInterface(mEditor); - if (editor) - { + nsCOMPtr editor = do_QueryInterface(mEditor); + if (editor) return editor->GetSelection(aEditorSelection); - } - } return NS_NOINTERFACE; } @@ -2043,6 +2037,27 @@ nsEditorShell::GetDocumentModified(PRBool *aDocumentModified) } +NS_IMETHODIMP +nsEditorShell::GetDocumentIsEmpty(PRBool *aDocumentIsEmpty) +{ + nsCOMPtr editor = do_QueryInterface(mEditor); + if (editor) + return editor->GetDocumentIsEmpty(aDocumentIsEmpty); + + return NS_NOINTERFACE; +} + +NS_IMETHODIMP +nsEditorShell::GetDocumentLength(PRInt32 *aDocumentLength) +{ + nsCOMPtr editor = do_QueryInterface(mEditor); + if (editor) + return editor->GetDocumentLength(aDocumentLength); + + return NS_NOINTERFACE; +} + + NS_IMETHODIMP nsEditorShell::InsertList(const PRUnichar *listType) { diff --git a/mozilla/editor/base/nsHTMLEditor.cpp b/mozilla/editor/base/nsHTMLEditor.cpp index 18bf69e0632..a3d17891d51 100644 --- a/mozilla/editor/base/nsHTMLEditor.cpp +++ b/mozilla/editor/base/nsHTMLEditor.cpp @@ -2334,6 +2334,18 @@ NS_IMETHODIMP nsHTMLEditor::ScrollIntoView(PRBool aScrollToBegin) */ +NS_IMETHODIMP +nsHTMLEditor::GetDocumentIsEmpty(PRBool *aDocumentIsEmpty) +{ + if (!aDocumentIsEmpty) + return NS_ERROR_NULL_POINTER; + + if (!mRules) + return NS_ERROR_NOT_INITIALIZED; + + return mRules->DocumentIsEmpty(aDocumentIsEmpty); +} + NS_IMETHODIMP nsHTMLEditor::GetDocumentLength(PRInt32 *aCount) @@ -2343,6 +2355,16 @@ nsHTMLEditor::GetDocumentLength(PRInt32 *aCount) // initialize out params *aCount = 0; + // special-case for empty document, to account for the bogus text node + PRBool docEmpty; + result = GetDocumentIsEmpty(&docEmpty); + if (NS_FAILED(result)) return result; + if (docEmpty) + { + *aCount = 0; + return NS_OK; + } + nsCOMPtr sel; result = GetSelection(getter_AddRefs(sel)); if (NS_FAILED(result)) return result; @@ -3017,6 +3039,24 @@ NS_IMETHODIMP nsHTMLEditor::OutputToString(nsString& aOutputString, // } // else // { // default processing + + + nsresult rv = NS_OK; + + // special-case for empty document when requesting plain text, + // to account for the bogus text node + if (aFormatType == "text/plain") + { + PRBool docEmpty; + rv = GetDocumentIsEmpty(&docEmpty); + if (NS_FAILED(rv)) return rv; + + if (docEmpty) { + aOutputString = ""; + return NS_OK; + } + } + nsCOMPtr encoder; char* progid = (char *)nsAllocator::Alloc(strlen(NS_DOC_ENCODER_PROGID_BASE) + aFormatType.Length() + 1); if (! progid) @@ -3025,7 +3065,7 @@ NS_IMETHODIMP nsHTMLEditor::OutputToString(nsString& aOutputString, char* type = aFormatType.ToNewCString(); strcat(progid, type); nsCRT::free(type); - nsresult rv = nsComponentManager::CreateInstance(progid, + rv = nsComponentManager::CreateInstance(progid, nsnull, nsIDocumentEncoder::GetIID(), getter_AddRefs(encoder)); @@ -3084,7 +3124,21 @@ NS_IMETHODIMP nsHTMLEditor::OutputToStream(nsIOutputStream* aOutputStream, const nsString* aCharset, PRUint32 aFlags) { + nsresult rv; + + // special-case for empty document when requesting plain text, + // to account for the bogus text node + if (aFormatType == "text/plain") + { + PRBool docEmpty; + rv = GetDocumentIsEmpty(&docEmpty); + if (NS_FAILED(rv)) return rv; + + if (docEmpty) + return NS_OK; // output nothing + } + nsCOMPtr encoder; char* progid = (char *)nsAllocator::Alloc(strlen(NS_DOC_ENCODER_PROGID_BASE) + aFormatType.Length() + 1); if (! progid) diff --git a/mozilla/editor/base/nsHTMLEditor.h b/mozilla/editor/base/nsHTMLEditor.h index 70a037019ed..adc834c548e 100644 --- a/mozilla/editor/base/nsHTMLEditor.h +++ b/mozilla/editor/base/nsHTMLEditor.h @@ -60,6 +60,7 @@ public: /* ------------ nsIHTMLEditor methods -------------- */ + NS_IMETHOD GetDocumentIsEmpty(PRBool *aDocumentIsEmpty); NS_IMETHOD GetDocumentLength(PRInt32 *aCount); NS_IMETHOD SetMaxTextLength(PRInt32 aMaxTextLength); NS_IMETHOD GetMaxTextLength(PRInt32& aMaxTextLength); diff --git a/mozilla/editor/base/nsTextEditRules.cpp b/mozilla/editor/base/nsTextEditRules.cpp index f9ce3193f59..cc6d9a29998 100644 --- a/mozilla/editor/base/nsTextEditRules.cpp +++ b/mozilla/editor/base/nsTextEditRules.cpp @@ -194,7 +194,17 @@ nsTextEditRules::DidDoAction(nsIDOMSelection *aSelection, } return NS_ERROR_FAILURE; } + + +NS_IMETHODIMP +nsTextEditRules::DocumentIsEmpty(PRBool *aDocumentIsEmpty) +{ + if (!aDocumentIsEmpty) + return NS_ERROR_NULL_POINTER; + *aDocumentIsEmpty = (mBogusNode.get() != nsnull); + return NS_OK; +} /******************************************************** * Protected methods diff --git a/mozilla/editor/base/nsTextEditRules.h b/mozilla/editor/base/nsTextEditRules.h index fec23ca66e6..7b6663a26a4 100644 --- a/mozilla/editor/base/nsTextEditRules.h +++ b/mozilla/editor/base/nsTextEditRules.h @@ -54,6 +54,7 @@ public: NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult); NS_IMETHOD GetFlags(PRUint32 *aFlags); NS_IMETHOD SetFlags(PRUint32 aFlags); + NS_IMETHOD DocumentIsEmpty(PRBool *aDocumentIsEmpty); // nsTextEditRules action id's enum diff --git a/mozilla/editor/composer/src/nsEditorShell.cpp b/mozilla/editor/composer/src/nsEditorShell.cpp index 870ecc796f4..da7e6c61ff1 100644 --- a/mozilla/editor/composer/src/nsEditorShell.cpp +++ b/mozilla/editor/composer/src/nsEditorShell.cpp @@ -2019,15 +2019,9 @@ nsEditorShell::GetEditorDocument(nsIDOMDocument** aEditorDocument) NS_IMETHODIMP nsEditorShell::GetEditorSelection(nsIDOMSelection** aEditorSelection) { - - if (mEditor) - { - nsCOMPtr editor = do_QueryInterface(mEditor); - if (editor) - { + nsCOMPtr editor = do_QueryInterface(mEditor); + if (editor) return editor->GetSelection(aEditorSelection); - } - } return NS_NOINTERFACE; } @@ -2043,6 +2037,27 @@ nsEditorShell::GetDocumentModified(PRBool *aDocumentModified) } +NS_IMETHODIMP +nsEditorShell::GetDocumentIsEmpty(PRBool *aDocumentIsEmpty) +{ + nsCOMPtr editor = do_QueryInterface(mEditor); + if (editor) + return editor->GetDocumentIsEmpty(aDocumentIsEmpty); + + return NS_NOINTERFACE; +} + +NS_IMETHODIMP +nsEditorShell::GetDocumentLength(PRInt32 *aDocumentLength) +{ + nsCOMPtr editor = do_QueryInterface(mEditor); + if (editor) + return editor->GetDocumentLength(aDocumentLength); + + return NS_NOINTERFACE; +} + + NS_IMETHODIMP nsEditorShell::InsertList(const PRUnichar *listType) { diff --git a/mozilla/editor/idl/nsIEditorShell.idl b/mozilla/editor/idl/nsIEditorShell.idl index 0970b03fd5a..2b19366fc7c 100644 --- a/mozilla/editor/idl/nsIEditorShell.idl +++ b/mozilla/editor/idl/nsIEditorShell.idl @@ -47,9 +47,11 @@ interface nsIEditorShell : nsISupports }; %} readonly attribute boolean documentModified; + readonly attribute boolean documentIsEmpty; + readonly attribute long documentLength; - attribute wstring paragraphFormat; - attribute long wrapColumn; + attribute wstring paragraphFormat; + attribute long wrapColumn; /* Setup */ void SetEditorType(in wstring editorType); diff --git a/mozilla/editor/libeditor/base/nsEditRules.h b/mozilla/editor/libeditor/base/nsEditRules.h index eb97e6c6b18..e8818ad8cfa 100644 --- a/mozilla/editor/libeditor/base/nsEditRules.h +++ b/mozilla/editor/libeditor/base/nsEditRules.h @@ -48,7 +48,7 @@ public: NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult)=0; NS_IMETHOD GetFlags(PRUint32 *aFlags)=0; NS_IMETHOD SetFlags(PRUint32 aFlags)=0; - + NS_IMETHOD DocumentIsEmpty(PRBool *aDocumentIsEmpty)=0; }; #endif //nsEditRules_h__ diff --git a/mozilla/editor/libeditor/base/nsEditor.h b/mozilla/editor/libeditor/base/nsEditor.h index 0db1f18d774..9a66efcf106 100644 --- a/mozilla/editor/libeditor/base/nsEditor.h +++ b/mozilla/editor/libeditor/base/nsEditor.h @@ -121,6 +121,9 @@ public: NS_IMETHOD BeginTransaction(); NS_IMETHOD EndTransaction(); + // pure virtual, because the definition of 'empty' depends on the doc type + NS_IMETHOD GetDocumentIsEmpty(PRBool *aDocumentIsEmpty)=0; + // file handling NS_IMETHOD GetDocumentModified(PRBool *outDocModified); NS_IMETHOD GetDocumentCharacterSet(PRUnichar** characterSet); diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp index 18bf69e0632..a3d17891d51 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.cpp @@ -2334,6 +2334,18 @@ NS_IMETHODIMP nsHTMLEditor::ScrollIntoView(PRBool aScrollToBegin) */ +NS_IMETHODIMP +nsHTMLEditor::GetDocumentIsEmpty(PRBool *aDocumentIsEmpty) +{ + if (!aDocumentIsEmpty) + return NS_ERROR_NULL_POINTER; + + if (!mRules) + return NS_ERROR_NOT_INITIALIZED; + + return mRules->DocumentIsEmpty(aDocumentIsEmpty); +} + NS_IMETHODIMP nsHTMLEditor::GetDocumentLength(PRInt32 *aCount) @@ -2343,6 +2355,16 @@ nsHTMLEditor::GetDocumentLength(PRInt32 *aCount) // initialize out params *aCount = 0; + // special-case for empty document, to account for the bogus text node + PRBool docEmpty; + result = GetDocumentIsEmpty(&docEmpty); + if (NS_FAILED(result)) return result; + if (docEmpty) + { + *aCount = 0; + return NS_OK; + } + nsCOMPtr sel; result = GetSelection(getter_AddRefs(sel)); if (NS_FAILED(result)) return result; @@ -3017,6 +3039,24 @@ NS_IMETHODIMP nsHTMLEditor::OutputToString(nsString& aOutputString, // } // else // { // default processing + + + nsresult rv = NS_OK; + + // special-case for empty document when requesting plain text, + // to account for the bogus text node + if (aFormatType == "text/plain") + { + PRBool docEmpty; + rv = GetDocumentIsEmpty(&docEmpty); + if (NS_FAILED(rv)) return rv; + + if (docEmpty) { + aOutputString = ""; + return NS_OK; + } + } + nsCOMPtr encoder; char* progid = (char *)nsAllocator::Alloc(strlen(NS_DOC_ENCODER_PROGID_BASE) + aFormatType.Length() + 1); if (! progid) @@ -3025,7 +3065,7 @@ NS_IMETHODIMP nsHTMLEditor::OutputToString(nsString& aOutputString, char* type = aFormatType.ToNewCString(); strcat(progid, type); nsCRT::free(type); - nsresult rv = nsComponentManager::CreateInstance(progid, + rv = nsComponentManager::CreateInstance(progid, nsnull, nsIDocumentEncoder::GetIID(), getter_AddRefs(encoder)); @@ -3084,7 +3124,21 @@ NS_IMETHODIMP nsHTMLEditor::OutputToStream(nsIOutputStream* aOutputStream, const nsString* aCharset, PRUint32 aFlags) { + nsresult rv; + + // special-case for empty document when requesting plain text, + // to account for the bogus text node + if (aFormatType == "text/plain") + { + PRBool docEmpty; + rv = GetDocumentIsEmpty(&docEmpty); + if (NS_FAILED(rv)) return rv; + + if (docEmpty) + return NS_OK; // output nothing + } + nsCOMPtr encoder; char* progid = (char *)nsAllocator::Alloc(strlen(NS_DOC_ENCODER_PROGID_BASE) + aFormatType.Length() + 1); if (! progid) diff --git a/mozilla/editor/libeditor/html/nsHTMLEditor.h b/mozilla/editor/libeditor/html/nsHTMLEditor.h index 70a037019ed..adc834c548e 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditor.h +++ b/mozilla/editor/libeditor/html/nsHTMLEditor.h @@ -60,6 +60,7 @@ public: /* ------------ nsIHTMLEditor methods -------------- */ + NS_IMETHOD GetDocumentIsEmpty(PRBool *aDocumentIsEmpty); NS_IMETHOD GetDocumentLength(PRInt32 *aCount); NS_IMETHOD SetMaxTextLength(PRInt32 aMaxTextLength); NS_IMETHOD GetMaxTextLength(PRInt32& aMaxTextLength); diff --git a/mozilla/editor/libeditor/text/nsTextEditRules.cpp b/mozilla/editor/libeditor/text/nsTextEditRules.cpp index f9ce3193f59..cc6d9a29998 100644 --- a/mozilla/editor/libeditor/text/nsTextEditRules.cpp +++ b/mozilla/editor/libeditor/text/nsTextEditRules.cpp @@ -194,7 +194,17 @@ nsTextEditRules::DidDoAction(nsIDOMSelection *aSelection, } return NS_ERROR_FAILURE; } + + +NS_IMETHODIMP +nsTextEditRules::DocumentIsEmpty(PRBool *aDocumentIsEmpty) +{ + if (!aDocumentIsEmpty) + return NS_ERROR_NULL_POINTER; + *aDocumentIsEmpty = (mBogusNode.get() != nsnull); + return NS_OK; +} /******************************************************** * Protected methods diff --git a/mozilla/editor/libeditor/text/nsTextEditRules.h b/mozilla/editor/libeditor/text/nsTextEditRules.h index fec23ca66e6..7b6663a26a4 100644 --- a/mozilla/editor/libeditor/text/nsTextEditRules.h +++ b/mozilla/editor/libeditor/text/nsTextEditRules.h @@ -54,6 +54,7 @@ public: NS_IMETHOD DidDoAction(nsIDOMSelection *aSelection, nsRulesInfo *aInfo, nsresult aResult); NS_IMETHOD GetFlags(PRUint32 *aFlags); NS_IMETHOD SetFlags(PRUint32 aFlags); + NS_IMETHOD DocumentIsEmpty(PRBool *aDocumentIsEmpty); // nsTextEditRules action id's enum diff --git a/mozilla/editor/public/nsIEditor.h b/mozilla/editor/public/nsIEditor.h index 4ba0a8eefe3..9ee836678cf 100644 --- a/mozilla/editor/public/nsIEditor.h +++ b/mozilla/editor/public/nsIEditor.h @@ -109,6 +109,10 @@ public: /* ------------ Document info and file methods -------------- */ + + /** Returns true if the document has no *meaningful* content */ + NS_IMETHOD GetDocumentIsEmpty(PRBool *aDocumentIsEmpty)=0; + /** Returns true if the document is modifed and needs saving */ NS_IMETHOD GetDocumentModified(PRBool *outDocModified)=0;