Implement nsIDiskDocument interface for editable documents.

git-svn-id: svn://10.0.0.236/trunk@30664 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
sfraser%netscape.com 1999-05-07 04:59:23 +00:00
parent f6c7ec8177
commit eea6214816
4 changed files with 496 additions and 10 deletions

View File

@ -55,7 +55,14 @@
#include "nsITextContent.h"
#include "nsXIFConverter.h"
#include "nsIHTMLContentSink.h"
#include "nsHTMLContentSinkStream.h"
#include "nsHTMLToTXTSinkStream.h"
#include "nsXIFDTD.h"
#include "nsIParser.h"
#include "nsParserCIID.h"
#include "nsFileSpec.h"
#include "nsFileStream.h"
#include "nsIDOMText.h"
#include "nsIDOMComment.h"
@ -631,7 +638,8 @@ nsDocument::nsDocument()
mEpilog = nsnull;
mChildNodes = nsnull;
mWordBreaker = nsnull;
mModCount = 0;
mFileSpec = nsnull;
Init();/* XXX */
}
@ -709,6 +717,15 @@ nsDocument::~nsDocument()
}
NS_IF_RELEASE(mLineBreaker);
NS_IF_RELEASE(mWordBreaker);
#ifdef DEBUG
if (mModCount > 0)
{
NS_WARNING("Disposing an unsaved modified document");
}
#endif
delete mFileSpec;
}
nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr)
@ -770,6 +787,12 @@ nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(nsIDiskDocument::GetIID())) {
nsIDiskDocument* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(kISupportsIID)) {
nsIDocument* tmp = this;
@ -2634,9 +2657,6 @@ void nsDocument::CreateXIF(nsString & aBuffer, nsIDOMSelection* aSelection)
converter.AddEndTag("section_head");
converter.AddStartTag("section_body");
nsIDOMElement* root = nsnull;
if (NS_OK == GetDocumentElement(&root))
{
@ -2651,6 +2671,184 @@ void nsDocument::CreateXIF(nsString & aBuffer, nsIDOMSelection* aSelection)
}
static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID);
static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID);
nsresult
nsDocument::OutputDocumentAs(nsIOutputStream* aStream, nsIDOMSelection* selection, EOutputFormat aOutputFormat, const nsString& aCharset)
{
nsresult rv = NS_OK;
nsAutoString charsetStr = aCharset;
if (charsetStr.Length() == 0)
{
rv = GetDocumentCharacterSet(charsetStr);
if(NS_FAILED(rv)) {
charsetStr = "ISO-8859-1";
}
}
nsCOMPtr<nsIParser> parser;
rv = nsComponentManager::CreateInstance(kCParserCID,
nsnull,
kCParserIID,
getter_AddRefs(parser));
if (NS_SUCCEEDED(rv))
{
nsString buffer;
CreateXIF(buffer, selection); // if selection is null, ignores the selection
nsCOMPtr<nsIHTMLContentSink> sink;
switch (aOutputFormat)
{
case eOutputText:
rv = NS_New_HTMLToTXT_SinkStream(getter_AddRefs(sink), aStream, &charsetStr);
break;
case eOutputHTML:
rv = NS_New_HTML_ContentSinkStream(getter_AddRefs(sink), aStream, &charsetStr);
break;
default:
rv = NS_ERROR_INVALID_ARG;
}
if (NS_SUCCEEDED(rv) && sink)
{
parser->SetContentSink(sink);
parser->SetDocumentCharset(charsetStr, kCharsetFromPreviousLoading);
nsCOMPtr<nsIDTD> dtd;
rv = NS_NewXIFDTD(getter_AddRefs(dtd));
if (NS_SUCCEEDED(rv) && dtd)
{
parser->RegisterDTD(dtd);
parser->Parse(buffer, 0, "text/xif", PR_FALSE, PR_TRUE);
}
}
}
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);
}
NS_IMETHODIMP
nsDocument::InitDiskDocument(nsFileSpec* aFileSpec)
{
mFileSpec = nsnull;
if (aFileSpec)
{
mFileSpec = new nsFileSpec(*aFileSpec);
if (!mFileSpec)
return NS_ERROR_OUT_OF_MEMORY;
}
mModCount = 0;
return NS_OK;
}
NS_IMETHODIMP
nsDocument::SaveFile( nsFileSpec* aFileSpec,
PRBool aReplaceExisting,
PRBool aSaveCopy,
ESaveFileType aSaveFileType,
const nsString& aSaveCharset)
{
if (!aFileSpec)
return NS_ERROR_NULL_POINTER;
nsresult rv = NS_OK;
// if we're not replacing an existing file but the file
// exists, somethine is wrong
if (!aReplaceExisting && aFileSpec->Exists())
return NS_ERROR_FAILURE; // where are the file I/O errors?
nsOutputFileStream stream(*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)
{
case eSaveFileText: outputFormat = eOutputText; break;
case eSaveFileHTML: outputFormat = eOutputHTML; break;
}
rv = OutputDocumentAs(stream.GetIStream(), nsnull, outputFormat, aSaveCharset);
if (NS_SUCCEEDED(rv))
{
// if everything went OK and we're not just saving off a copy,
// store the new fileSpec in the doc
if (!aSaveCopy)
{
delete mFileSpec;
mFileSpec = new nsFileSpec(*aFileSpec);
if (!mFileSpec)
return NS_ERROR_OUT_OF_MEMORY;
// and mark the document as clean
ResetModCount();
}
}
return rv;
}
NS_IMETHODIMP
nsDocument::GetFileSpec(nsFileSpec& aFileSpec)
{
if (mFileSpec)
{
aFileSpec = *mFileSpec;
return NS_OK;
}
return NS_ERROR_NOT_INITIALIZED;
}
NS_IMETHODIMP
nsDocument::GetModCount(PRInt32 *outModCount)
{
if (!outModCount)
return NS_ERROR_NULL_POINTER;
*outModCount = mModCount;
return NS_OK;
}
NS_IMETHODIMP
nsDocument::ResetModCount()
{
mModCount = 0;
return NS_OK;
}
NS_IMETHODIMP
nsDocument::IncrementModCount()
{
mModCount++;
return NS_OK;
}
nsIContent* nsDocument::FindContent(const nsIContent* aStartNode,
const nsIContent* aTest1,

View File

@ -22,6 +22,7 @@
#include "nsVoidArray.h"
#include "nsIDOMDocument.h"
#include "nsIDOMNSDocument.h"
#include "nsIDiskDocument.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptContextOwner.h"
#include "nsIDOMEventCapturer.h"
@ -34,6 +35,7 @@
class nsIEventListenerManager;
class nsDOMStyleSheetCollection;
class nsIDOMSelection;
class nsIOutputStream;
class nsDocument;
class nsPostData : public nsIPostData {
@ -99,6 +101,7 @@ protected:
class nsDocument : public nsIDocument,
public nsIDOMDocument,
public nsIDOMNSDocument,
public nsIDiskDocument,
public nsIScriptObjectOwner,
public nsIDOMEventCapturer,
public nsIJSScriptObject
@ -351,6 +354,19 @@ public:
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager **aInstancePtrResult);
// nsIDiskDocument inteface
NS_IMETHOD InitDiskDocument(nsFileSpec *aFileSpec);
NS_IMETHOD SaveFile( nsFileSpec* aFileSpec,
PRBool aReplaceExisting,
PRBool aSaveCopy,
ESaveFileType aSaveFileType,
const nsString& aSaveCharset);
NS_IMETHOD GetFileSpec(nsFileSpec& aFileSpec);
NS_IMETHOD GetModCount(PRInt32 *outModCount);
NS_IMETHOD ResetModCount();
NS_IMETHOD IncrementModCount();
// nsIDOMEventTarget interface
NS_IMETHOD AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
@ -383,12 +399,36 @@ public:
virtual PRBool Convert(JSContext *aContext, jsval aID);
virtual void Finalize(JSContext *aContext);
/**
* 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(nsIURL* aURL);
// 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);
protected:
virtual void InternalAddStyleSheet(nsIStyleSheet* aSheet); // subclass hook for sheet ordering
@ -421,6 +461,11 @@ protected:
nsVoidArray *mEpilog;
nsDocumentChildNodes* mChildNodes;
nsIWordBreaker* mWordBreaker;
// disk file members
nsFileSpec* mFileSpec;
PRInt32 mModCount;
};
#endif /* nsDocument_h___ */

View File

@ -55,7 +55,14 @@
#include "nsITextContent.h"
#include "nsXIFConverter.h"
#include "nsIHTMLContentSink.h"
#include "nsHTMLContentSinkStream.h"
#include "nsHTMLToTXTSinkStream.h"
#include "nsXIFDTD.h"
#include "nsIParser.h"
#include "nsParserCIID.h"
#include "nsFileSpec.h"
#include "nsFileStream.h"
#include "nsIDOMText.h"
#include "nsIDOMComment.h"
@ -631,7 +638,8 @@ nsDocument::nsDocument()
mEpilog = nsnull;
mChildNodes = nsnull;
mWordBreaker = nsnull;
mModCount = 0;
mFileSpec = nsnull;
Init();/* XXX */
}
@ -709,6 +717,15 @@ nsDocument::~nsDocument()
}
NS_IF_RELEASE(mLineBreaker);
NS_IF_RELEASE(mWordBreaker);
#ifdef DEBUG
if (mModCount > 0)
{
NS_WARNING("Disposing an unsaved modified document");
}
#endif
delete mFileSpec;
}
nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr)
@ -770,6 +787,12 @@ nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(nsIDiskDocument::GetIID())) {
nsIDiskDocument* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(kISupportsIID)) {
nsIDocument* tmp = this;
@ -2634,9 +2657,6 @@ void nsDocument::CreateXIF(nsString & aBuffer, nsIDOMSelection* aSelection)
converter.AddEndTag("section_head");
converter.AddStartTag("section_body");
nsIDOMElement* root = nsnull;
if (NS_OK == GetDocumentElement(&root))
{
@ -2651,6 +2671,184 @@ void nsDocument::CreateXIF(nsString & aBuffer, nsIDOMSelection* aSelection)
}
static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID);
static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID);
nsresult
nsDocument::OutputDocumentAs(nsIOutputStream* aStream, nsIDOMSelection* selection, EOutputFormat aOutputFormat, const nsString& aCharset)
{
nsresult rv = NS_OK;
nsAutoString charsetStr = aCharset;
if (charsetStr.Length() == 0)
{
rv = GetDocumentCharacterSet(charsetStr);
if(NS_FAILED(rv)) {
charsetStr = "ISO-8859-1";
}
}
nsCOMPtr<nsIParser> parser;
rv = nsComponentManager::CreateInstance(kCParserCID,
nsnull,
kCParserIID,
getter_AddRefs(parser));
if (NS_SUCCEEDED(rv))
{
nsString buffer;
CreateXIF(buffer, selection); // if selection is null, ignores the selection
nsCOMPtr<nsIHTMLContentSink> sink;
switch (aOutputFormat)
{
case eOutputText:
rv = NS_New_HTMLToTXT_SinkStream(getter_AddRefs(sink), aStream, &charsetStr);
break;
case eOutputHTML:
rv = NS_New_HTML_ContentSinkStream(getter_AddRefs(sink), aStream, &charsetStr);
break;
default:
rv = NS_ERROR_INVALID_ARG;
}
if (NS_SUCCEEDED(rv) && sink)
{
parser->SetContentSink(sink);
parser->SetDocumentCharset(charsetStr, kCharsetFromPreviousLoading);
nsCOMPtr<nsIDTD> dtd;
rv = NS_NewXIFDTD(getter_AddRefs(dtd));
if (NS_SUCCEEDED(rv) && dtd)
{
parser->RegisterDTD(dtd);
parser->Parse(buffer, 0, "text/xif", PR_FALSE, PR_TRUE);
}
}
}
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);
}
NS_IMETHODIMP
nsDocument::InitDiskDocument(nsFileSpec* aFileSpec)
{
mFileSpec = nsnull;
if (aFileSpec)
{
mFileSpec = new nsFileSpec(*aFileSpec);
if (!mFileSpec)
return NS_ERROR_OUT_OF_MEMORY;
}
mModCount = 0;
return NS_OK;
}
NS_IMETHODIMP
nsDocument::SaveFile( nsFileSpec* aFileSpec,
PRBool aReplaceExisting,
PRBool aSaveCopy,
ESaveFileType aSaveFileType,
const nsString& aSaveCharset)
{
if (!aFileSpec)
return NS_ERROR_NULL_POINTER;
nsresult rv = NS_OK;
// if we're not replacing an existing file but the file
// exists, somethine is wrong
if (!aReplaceExisting && aFileSpec->Exists())
return NS_ERROR_FAILURE; // where are the file I/O errors?
nsOutputFileStream stream(*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)
{
case eSaveFileText: outputFormat = eOutputText; break;
case eSaveFileHTML: outputFormat = eOutputHTML; break;
}
rv = OutputDocumentAs(stream.GetIStream(), nsnull, outputFormat, aSaveCharset);
if (NS_SUCCEEDED(rv))
{
// if everything went OK and we're not just saving off a copy,
// store the new fileSpec in the doc
if (!aSaveCopy)
{
delete mFileSpec;
mFileSpec = new nsFileSpec(*aFileSpec);
if (!mFileSpec)
return NS_ERROR_OUT_OF_MEMORY;
// and mark the document as clean
ResetModCount();
}
}
return rv;
}
NS_IMETHODIMP
nsDocument::GetFileSpec(nsFileSpec& aFileSpec)
{
if (mFileSpec)
{
aFileSpec = *mFileSpec;
return NS_OK;
}
return NS_ERROR_NOT_INITIALIZED;
}
NS_IMETHODIMP
nsDocument::GetModCount(PRInt32 *outModCount)
{
if (!outModCount)
return NS_ERROR_NULL_POINTER;
*outModCount = mModCount;
return NS_OK;
}
NS_IMETHODIMP
nsDocument::ResetModCount()
{
mModCount = 0;
return NS_OK;
}
NS_IMETHODIMP
nsDocument::IncrementModCount()
{
mModCount++;
return NS_OK;
}
nsIContent* nsDocument::FindContent(const nsIContent* aStartNode,
const nsIContent* aTest1,

View File

@ -22,6 +22,7 @@
#include "nsVoidArray.h"
#include "nsIDOMDocument.h"
#include "nsIDOMNSDocument.h"
#include "nsIDiskDocument.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptContextOwner.h"
#include "nsIDOMEventCapturer.h"
@ -34,6 +35,7 @@
class nsIEventListenerManager;
class nsDOMStyleSheetCollection;
class nsIDOMSelection;
class nsIOutputStream;
class nsDocument;
class nsPostData : public nsIPostData {
@ -99,6 +101,7 @@ protected:
class nsDocument : public nsIDocument,
public nsIDOMDocument,
public nsIDOMNSDocument,
public nsIDiskDocument,
public nsIScriptObjectOwner,
public nsIDOMEventCapturer,
public nsIJSScriptObject
@ -351,6 +354,19 @@ public:
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager **aInstancePtrResult);
// nsIDiskDocument inteface
NS_IMETHOD InitDiskDocument(nsFileSpec *aFileSpec);
NS_IMETHOD SaveFile( nsFileSpec* aFileSpec,
PRBool aReplaceExisting,
PRBool aSaveCopy,
ESaveFileType aSaveFileType,
const nsString& aSaveCharset);
NS_IMETHOD GetFileSpec(nsFileSpec& aFileSpec);
NS_IMETHOD GetModCount(PRInt32 *outModCount);
NS_IMETHOD ResetModCount();
NS_IMETHOD IncrementModCount();
// nsIDOMEventTarget interface
NS_IMETHOD AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
@ -383,12 +399,36 @@ public:
virtual PRBool Convert(JSContext *aContext, jsval aID);
virtual void Finalize(JSContext *aContext);
/**
* 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(nsIURL* aURL);
// 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);
protected:
virtual void InternalAddStyleSheet(nsIStyleSheet* aSheet); // subclass hook for sheet ordering
@ -421,6 +461,11 @@ protected:
nsVoidArray *mEpilog;
nsDocumentChildNodes* mChildNodes;
nsIWordBreaker* mWordBreaker;
// disk file members
nsFileSpec* mFileSpec;
PRInt32 mModCount;
};
#endif /* nsDocument_h___ */