New parameters for nsIWebBrowserPersist saveURI & saveDocument. Caller may now specify target file as a uri or a file saveDocument has new flags for controlling encoding and line wrapping behaviour. b=110135 r=brade@netscape.com sr=rpotts@netscape.com

This commit is contained in:
locka%iol.ie 2002-01-14 12:41:27 +00:00
Родитель 59bfd3e7a3
Коммит a1ae2cd318
10 изменённых файлов: 566 добавлений и 246 удалений

Просмотреть файл

@ -660,7 +660,7 @@ LRESULT CMozillaBrowser::OnSaveAs(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL
nsCOMPtr<nsILocalFile> dataPath; nsCOMPtr<nsILocalFile> dataPath;
NS_NewLocalFile(szDataPath, TRUE, getter_AddRefs(dataPath)); NS_NewLocalFile(szDataPath, TRUE, getter_AddRefs(dataPath));
persist->SaveDocument(nsnull, file, dataPath); persist->SaveDocument(nsnull, file, dataPath, nsnull, 0, 0);
} }
return hr; return hr;

Просмотреть файл

@ -706,7 +706,7 @@ NS_METHOD CBrowserShell::SaveDocument(const FSSpec& outSpec)
nsCOMPtr<nsILocalFile> parentDirAsLocal(do_QueryInterface(parentDir, &rv)); nsCOMPtr<nsILocalFile> parentDirAsLocal(do_QueryInterface(parentDir, &rv));
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
rv = wbPersist->SaveDocument(domDoc, localFile, parentDirAsLocal); rv = wbPersist->SaveDocument(domDoc, localFile, parentDirAsLocal, nsnull, 0, 0);
return rv; return rv;
} }

Просмотреть файл

@ -871,8 +871,8 @@ NS_IMETHODIMP nsWebBrowser::SetProgressListener(nsIWebProgressListener * aProgre
return NS_OK; return NS_OK;
} }
/* void saveURI (in nsIURI aURI, in nsILocalFile aFile); */ /* void saveURI (in nsIURI aURI, in nsISupports aFile); */
NS_IMETHODIMP nsWebBrowser::SaveURI(nsIURI *aURI, nsIInputStream *aPostData, nsILocalFile *aFile) NS_IMETHODIMP nsWebBrowser::SaveURI(nsIURI *aURI, nsIInputStream *aPostData, nsISupports *aFile)
{ {
if (mPersist) if (mPersist)
{ {
@ -918,8 +918,10 @@ NS_IMETHODIMP nsWebBrowser::SaveURI(nsIURI *aURI, nsIInputStream *aPostData, nsI
return rv; return rv;
} }
/* void saveDocument (in nsIDOMDocument document, in nsILocalFile aFile, in nsILocalFile aDataPath); */ /* void saveDocument (in nsIDOMDocument document, in nsISupports aFile, in nsISupports aDataPath); */
NS_IMETHODIMP nsWebBrowser::SaveDocument(nsIDOMDocument *aDocument, nsILocalFile *aFile, nsILocalFile *aDataPath) NS_IMETHODIMP nsWebBrowser::SaveDocument(
nsIDOMDocument *aDocument, nsISupports *aFile, nsISupports *aDataPath,
const char *aOutputContentType, PRUint32 aEncodingFlags, PRUint32 aWrapColumn)
{ {
if (mPersist) if (mPersist)
{ {
@ -960,7 +962,7 @@ NS_IMETHODIMP nsWebBrowser::SaveDocument(nsIDOMDocument *aDocument, nsILocalFile
mPersist->SetProgressListener(this); mPersist->SetProgressListener(this);
mPersist->SetPersistFlags(mPersistFlags); mPersist->SetPersistFlags(mPersistFlags);
mPersist->GetCurrentState(&mPersistCurrentState); mPersist->GetCurrentState(&mPersistCurrentState);
rv = mPersist->SaveDocument(doc, aFile, aDataPath); rv = mPersist->SaveDocument(doc, aFile, aDataPath, aOutputContentType, aEncodingFlags, aWrapColumn);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
{ {
mPersist = nsnull; mPersist = nsnull;

Просмотреть файл

@ -404,7 +404,8 @@ function onLoad() {
if (!filesFolder.exists()) if (!filesFolder.exists())
filesFolder.create(lfIID.DIRECTORY_TYPE, 0755); filesFolder.create(lfIID.DIRECTORY_TYPE, 0755);
webBrowserPersist.saveDocument(persistArgs.source, targetFile, filesFolder);
webBrowserPersist.saveDocument(persistArgs.source, targetFile, filesFolder, null, 0, 0);
} }
} }

Просмотреть файл

@ -50,6 +50,8 @@ interface nsIWebBrowserPersist : nsISupports
const unsigned long PERSIST_FLAGS_IGNORE_IFRAMES = 8; const unsigned long PERSIST_FLAGS_IGNORE_IFRAMES = 8;
/** Do not run the incoming data through a content converter e.g. to decompress it */ /** Do not run the incoming data through a content converter e.g. to decompress it */
const unsigned long PERSIST_FLAGS_NO_CONVERSION = 16; const unsigned long PERSIST_FLAGS_NO_CONVERSION = 16;
/** Replace existing files on the disk (use with due diligence!) */
const unsigned long PERSIST_FLAGS_REPLACE_EXISTING_FILES = 32;
/** Flags governing how data is fetched from the network. */ /** Flags governing how data is fetched from the network. */
attribute unsigned long persistFlags; attribute unsigned long persistFlags;
@ -77,38 +79,102 @@ interface nsIWebBrowserPersist : nsISupports
readonly attribute unsigned long result; readonly attribute unsigned long result;
/** /**
* Callback listener for progress notifications. * Callback listener for progress notifications. The object
* may also implement nsIInterfaceRequestor and be prepared to
* return nsIAuthPrompt or other interfaces required to download
* data.
*/ */
attribute nsIWebProgressListener progressListener; attribute nsIWebProgressListener progressListener;
/** /**
* Save the specified URI to file. * Save the specified URI to file.
* *
* @param aURI URI to save to file or <CODE>nsnull</CODE> * @param aURI URI to save to file. Some implementations of this interface
* to use current URI if the implementation supports such * may also support <CODE>nsnull</CODE> to imply the currently
* a concept. * loaded URI.
* @param aPostData Data to pass with in an HTTP request or nsnull. * @param aPostData Data to pass with in an HTTP request or nsnull.
* @param aFile Target local file. * @param aFile Target local file.
* *
* @return NS_OK Operation has been started. * @return NS_OK Operation has been started.
* @return NS_ERROR_INVALID_ARG One or more arguments was invalid. * @return NS_ERROR_INVALID_ARG One or more arguments was invalid.
*/ */
void saveURI(in nsIURI aURI, in nsIInputStream aPostData, in nsILocalFile aFile); void saveURI(in nsIURI aURI, in nsIInputStream aPostData, in nsISupports aFile);
/** Output only the current selection as opposed to the whole document. */
const unsigned long ENCODE_FLAGS_SELECTION_ONLY = 1;
/**
* For plaintext output. Convert html to plaintext that looks like the html.
* Implies wrap (except inside &lt;pre&gt;), since html wraps.
* HTML output: always do prettyprinting, ignoring existing formatting.
*/
const unsigned long ENCODE_FLAGS_FORMATTED = 2;
/**
* Output without formatting or wrapping the content. This flag
* may be used to preserve the original formatting as much as possible.
*/
const unsigned long ENCODE_FLAGS_RAW = 4;
/** Output only the body section, no HTML tags. */
const unsigned long ENCODE_FLAGS_BODY_ONLY = 8;
/** Wrap even if when not doing formatted output (e.g. for text fields). */
const unsigned long ENCODE_FLAGS_PREFORMATTED = 16;
/** Wrap documents at the specified column. */
const unsigned long ENCODE_FLAGS_WRAP = 32;
/**
* For plaintext output. Output for format flowed (RFC 2646). This is used
* when converting to text for mail sending. This differs just slightly
* but in an important way from normal formatted, and that is that
* lines are space stuffed. This can't (correctly) be done later.
*/
const unsigned long ENCODE_FLAGS_FORMAT_FLOWED = 64;
/** Convert links to absolute links where possible. */
const unsigned long ENCODE_FLAGS_ABSOLUTE_LINKS = 128;
/** Encode entities, e.g. output &nbsp; instead of character code 0xa0. */
const unsigned long ENCODE_FLAGS_ENCODE_ENTITIES = 256;
/**
* Output with carriage return line breaks. May also be combined with
* ENCODE_FLAGS_LF_LINEBREAKS and if neither is specified, the platform
* default format is used.
*/
const unsigned long ENCODE_FLAGS_CR_LINEBREAKS = 512;
/**
* Output with linefeed line breaks. May also be combined with
* ENCODE_FLAGS_CR_LINEBREAKS and if neither is specified, the platform
* default format is used.
*/
const unsigned long ENCODE_FLAGS_LF_LINEBREAKS = 1024;
/** For plaintext output. Output the content of noscript elements. */
const unsigned long ENCODE_FLAGS_NOSCRIPT_CONTENT = 2048;
/** For plaintext output. Output the content of noframes elements. */
const unsigned long ENCODE_FLAGS_NOFRAMES_CONTENT = 4096;
/** /**
* Save the specified DOM document to file and optionally all linked files * Save the specified DOM document to file and optionally all linked files
* (e.g. images, CSS, JS & subframes). Do not call this method until the * (e.g. images, CSS, JS & subframes). Do not call this method until the
* document has finished loading! * document has finished loading!
* *
* @param aDocument Document to save to file. * @param aDocument Document to save to file. Some implementations of
* @param aFile Target local file. * this interface may also support <CODE>nsnull</CODE>
* @param aDataPath Path to folder (which must already exist) to save * to imply the currently loaded document.
* linked files to or nsnull. * @param aFileURI Target local file.
* @param aDataPathURI Path to directory where URIs linked to the document
* are saved or nsnull if no linked URIs should be saved.
* @param aOutputContentType The desired MIME type format to save the
* document and all subdocuments into or nsnull to use
* the default behaviour.
* @param aEncodingFlags Flags to pass to the encoder.
* @param aWrapColumn For text documents, indicates the desired width to
* wrap text at. Parameter is ignored if wrapping is not
* specified by the encoding flags.
*
* @see nsIDocumentEncoder
* *
* @return NS_OK Operation has been started. * @return NS_OK Operation has been started.
* @return NS_ERROR_INVALID_ARG One or more arguments was invalid. * @return NS_ERROR_INVALID_ARG One or more arguments was invalid.
*/ */
void saveDocument(in nsIDOMDocument aDocument, in nsILocalFile aFile, in nsILocalFile aDataPath); void saveDocument(in nsIDOMDocument aDocument,
in nsISupports aFile, in nsISupports aDataPath,
in string aOutputContentType, in unsigned long aEncodingFlags,
in unsigned long aWrapColumn);
/** /**
* Cancels the current operation. The caller is responsible for cleaning up * Cancels the current operation. The caller is responsible for cleaning up

Просмотреть файл

@ -65,8 +65,8 @@ struct DocData
{ {
nsCOMPtr<nsIURI> mBaseURI; nsCOMPtr<nsIURI> mBaseURI;
nsCOMPtr<nsIDOMDocument> mDocument; nsCOMPtr<nsIDOMDocument> mDocument;
nsCOMPtr<nsILocalFile> mFile; nsCOMPtr<nsIURI> mFile;
nsCOMPtr<nsILocalFile> mDataPath; nsCOMPtr<nsIURI> mDataPath;
PRBool mDataPathIsRelative; PRBool mDataPathIsRelative;
nsCString mRelativePathToData; nsCString mRelativePathToData;
}; };
@ -79,22 +79,22 @@ struct URIData
PRBool mIsSubFrame; PRBool mIsSubFrame;
nsString mFilename; nsString mFilename;
nsString mSubFrameExt; nsString mSubFrameExt;
nsCOMPtr<nsILocalFile> mDataPath; nsCOMPtr<nsIURI> mFile;
nsCOMPtr<nsIURI> mDataPath;
PRBool mDataPathIsRelative; PRBool mDataPathIsRelative;
nsCString mRelativePathToData; nsCString mRelativePathToData;
nsCOMPtr<nsILocalFile> mFile;
}; };
// Information about the output stream // Information about the output stream
struct OutputData struct OutputData
{ {
nsCOMPtr<nsILocalFile> mFile; nsCOMPtr<nsIURI> mFile;
PRBool mCalcFileExt; PRBool mCalcFileExt;
nsCOMPtr<nsIOutputStream> mStream; nsCOMPtr<nsIOutputStream> mStream;
PRInt32 mSelfProgress; PRInt32 mSelfProgress;
PRInt32 mSelfProgressMax; PRInt32 mSelfProgressMax;
OutputData(nsILocalFile *aFile, PRBool aCalcFileExt) : OutputData(nsIURI *aFile, PRBool aCalcFileExt) :
mFile(aFile), mFile(aFile),
mCalcFileExt(aCalcFileExt), mCalcFileExt(aCalcFileExt),
mSelfProgress(0), mSelfProgress(0),
@ -110,6 +110,14 @@ struct OutputData
} }
}; };
// Default flags for persistence
const PRUint32 kDefaultPersistFlags =
nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION;
// Default flags for encoding
const PRUint32 kDefaultEncodingFlags =
nsIDocumentEncoder::OutputRaw;
nsWebBrowserPersist::nsWebBrowserPersist() : nsWebBrowserPersist::nsWebBrowserPersist() :
mFileCounter(1), mFileCounter(1),
mFrameCounter(1), mFrameCounter(1),
@ -117,8 +125,11 @@ nsWebBrowserPersist::nsWebBrowserPersist() :
mCancel(PR_FALSE), mCancel(PR_FALSE),
mJustStartedLoading(PR_TRUE), mJustStartedLoading(PR_TRUE),
mCompleted(PR_FALSE), mCompleted(PR_FALSE),
mPersistFlags(PERSIST_FLAGS_NONE), mPersistFlags(kDefaultPersistFlags),
mPersistResult(NS_OK) mPersistResult(NS_OK),
mReplaceExisting(PR_TRUE),
mEncodingFlags(0),
mWrapColumn(72)
{ {
NS_INIT_REFCNT(); NS_INIT_REFCNT();
} }
@ -153,6 +164,21 @@ NS_INTERFACE_MAP_END
NS_IMETHODIMP nsWebBrowserPersist::GetInterface(const nsIID & aIID, void **aIFace) NS_IMETHODIMP nsWebBrowserPersist::GetInterface(const nsIID & aIID, void **aIFace)
{ {
NS_ENSURE_ARG_POINTER(aIFace); NS_ENSURE_ARG_POINTER(aIFace);
*aIFace = nsnull;
if (mProgressListener)
{
nsCOMPtr<nsIInterfaceRequestor> req = do_QueryInterface(mProgressListener);
if (req)
{
req->GetInterface(aIID, aIFace);
if (*aIFace)
{
return NS_OK;
}
}
}
return QueryInterface(aIID, aIFace); return QueryInterface(aIID, aIFace);
} }
@ -171,6 +197,7 @@ NS_IMETHODIMP nsWebBrowserPersist::GetPersistFlags(PRUint32 *aPersistFlags)
NS_IMETHODIMP nsWebBrowserPersist::SetPersistFlags(PRUint32 aPersistFlags) NS_IMETHODIMP nsWebBrowserPersist::SetPersistFlags(PRUint32 aPersistFlags)
{ {
mPersistFlags = aPersistFlags; mPersistFlags = aPersistFlags;
mReplaceExisting = (mPersistFlags & PERSIST_FLAGS_REPLACE_EXISTING_FILES) ? PR_TRUE : PR_FALSE;
return NS_OK; return NS_OK;
} }
@ -220,20 +247,79 @@ NS_IMETHODIMP nsWebBrowserPersist::SetProgressListener(
/* void saveURI (in nsIURI aURI, in string aFileName); */ /* void saveURI (in nsIURI aURI, in string aFileName); */
NS_IMETHODIMP nsWebBrowserPersist::SaveURI( NS_IMETHODIMP nsWebBrowserPersist::SaveURI(
nsIURI *aURI, nsIInputStream *aPostData, nsILocalFile *aFile) nsIURI *aURI, nsIInputStream *aPostData, nsISupports *aFile)
{ {
NS_ENSURE_TRUE(mFirstAndOnlyUse, NS_ERROR_FAILURE); NS_ENSURE_TRUE(mFirstAndOnlyUse, NS_ERROR_FAILURE);
mFirstAndOnlyUse = PR_FALSE; // Stop people from reusing this object! mFirstAndOnlyUse = PR_FALSE; // Stop people from reusing this object!
return SaveURIInternal(aURI, aPostData, aFile, PR_FALSE);
nsCOMPtr<nsIURI> fileAsURI;
nsresult rv;
rv = GetValidURIFromObject(aFile, getter_AddRefs(fileAsURI));
NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
return SaveURIInternal(aURI, aPostData, fileAsURI, PR_FALSE);
} }
/* void saveDocument (in nsIDOMDocument document); */
/* void saveDocument (in nsIDOMDocument aDocument, in nsIURI aFileURI,
in nsIURI aDataPathURI, in string aOutputContentType,
in unsigned long aEncodingFlags, in unsigned long aWrapColumn); */
NS_IMETHODIMP nsWebBrowserPersist::SaveDocument( NS_IMETHODIMP nsWebBrowserPersist::SaveDocument(
nsIDOMDocument *aDocument, nsILocalFile *aFile, nsILocalFile *aDataPath) nsIDOMDocument *aDocument, nsISupports *aFile, nsISupports *aDataPath,
const char *aOutputContentType, PRUint32 aEncodingFlags, PRUint32 aWrapColumn)
{ {
NS_ENSURE_TRUE(mFirstAndOnlyUse, NS_ERROR_FAILURE); NS_ENSURE_TRUE(mFirstAndOnlyUse, NS_ERROR_FAILURE);
mFirstAndOnlyUse = PR_FALSE; // Stop people from reusing this object! mFirstAndOnlyUse = PR_FALSE; // Stop people from reusing this object!
return SaveDocumentInternal(aDocument, aFile, aDataPath);
nsCOMPtr<nsIURI> fileAsURI;
nsCOMPtr<nsIURI> datapathAsURI;
nsresult rv;
rv = GetValidURIFromObject(aFile, getter_AddRefs(fileAsURI));
NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
if (aDataPath)
{
rv = GetValidURIFromObject(aDataPath, getter_AddRefs(datapathAsURI));
NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
}
mWrapColumn = aWrapColumn;
// Produce nsIDocumentEncoder encoding flags
mEncodingFlags = 0;
if (aEncodingFlags & ENCODE_FLAGS_SELECTION_ONLY)
mEncodingFlags |= nsIDocumentEncoder::OutputSelectionOnly;
if (aEncodingFlags & ENCODE_FLAGS_FORMATTED)
mEncodingFlags |= nsIDocumentEncoder::OutputFormatted;
if (aEncodingFlags & ENCODE_FLAGS_RAW)
mEncodingFlags |= nsIDocumentEncoder::OutputRaw;
if (aEncodingFlags & ENCODE_FLAGS_BODY_ONLY)
mEncodingFlags |= nsIDocumentEncoder::OutputBodyOnly;
if (aEncodingFlags & ENCODE_FLAGS_PREFORMATTED)
mEncodingFlags |= nsIDocumentEncoder::OutputPreformatted;
if (aEncodingFlags & ENCODE_FLAGS_WRAP)
mEncodingFlags |= nsIDocumentEncoder::OutputWrap;
if (aEncodingFlags & ENCODE_FLAGS_FORMAT_FLOWED)
mEncodingFlags |= nsIDocumentEncoder::OutputFormatFlowed;
if (aEncodingFlags & ENCODE_FLAGS_ABSOLUTE_LINKS)
mEncodingFlags |= nsIDocumentEncoder::OutputAbsoluteLinks;
if (aEncodingFlags & ENCODE_FLAGS_ENCODE_ENTITIES)
mEncodingFlags |= nsIDocumentEncoder::OutputEncodeEntities;
if (aEncodingFlags & ENCODE_FLAGS_CR_LINEBREAKS)
mEncodingFlags |= nsIDocumentEncoder::OutputCRLineBreak;
if (aEncodingFlags & ENCODE_FLAGS_LF_LINEBREAKS)
mEncodingFlags |= nsIDocumentEncoder::OutputLFLineBreak;
if (aEncodingFlags & ENCODE_FLAGS_NOSCRIPT_CONTENT)
mEncodingFlags |= nsIDocumentEncoder::OutputNoScriptContent;
if (aEncodingFlags & ENCODE_FLAGS_NOFRAMES_CONTENT)
mEncodingFlags |= nsIDocumentEncoder::OutputNoFramesContent;
if (aOutputContentType)
{
mContentType.AssignWithConversion(aOutputContentType);
}
return SaveDocumentInternal(aDocument, fileAsURI, datapathAsURI);
} }
/* void cancelSave(); */ /* void cancelSave(); */
@ -349,9 +435,11 @@ NS_IMETHODIMP nsWebBrowserPersist::OnDataAvailable(
// Make the output stream // Make the output stream
if (!data->mStream) if (!data->mStream)
{ {
rv = MakeOutputStream( if (data->mCalcFileExt)
data->mFile, data->mCalcFileExt, {
channel, getter_AddRefs(data->mStream)); CalculateAndAppendFileExt(data->mFile, channel);
}
rv = MakeOutputStream(data->mFile, channel, getter_AddRefs(data->mStream));
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
} }
@ -445,8 +533,92 @@ NS_IMETHODIMP nsWebBrowserPersist::OnStatus(
// nsWebBrowserPersist private methods // nsWebBrowserPersist private methods
//***************************************************************************** //*****************************************************************************
nsresult nsWebBrowserPersist::GetValidURIFromObject(nsISupports *aObject, nsIURI **aURI) const
{
NS_ENSURE_ARG_POINTER(aObject);
NS_ENSURE_ARG_POINTER(aURI);
nsCOMPtr<nsIFile> objAsFile = do_QueryInterface(aObject);
if (objAsFile)
{
return NS_NewFileURI(aURI, objAsFile);
}
nsCOMPtr<nsIURI> objAsURI = do_QueryInterface(aObject);
if (objAsURI)
{
PRBool isFile = PR_FALSE;
objAsURI->SchemeIs("file", &isFile);
NS_ENSURE_TRUE(isFile, NS_ERROR_FAILURE);
nsCOMPtr<nsIFileURL> objAsFileURL = do_QueryInterface(objAsURI);
if (objAsURI)
{
*aURI = objAsURI;
NS_ADDREF(*aURI);
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
nsresult nsWebBrowserPersist::GetLocalFileFromURI(nsIURI *aURI, nsILocalFile **aLocalFile) const
{
NS_ENSURE_ARG_POINTER(aURI);
NS_ENSURE_ARG_POINTER(aLocalFile);
*aLocalFile = nsnull;
nsresult rv = NS_OK;
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
if (NS_FAILED(rv) || !fileURL)
{
return NS_ERROR_MALFORMED_URI;
}
nsCOMPtr<nsIFile> file;
rv = fileURL->GetFile(getter_AddRefs(file));
if (NS_FAILED(rv) || !file)
{
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file, &rv);
if (NS_FAILED(rv) || !localFile)
{
return NS_ERROR_FAILURE;
}
*aLocalFile = localFile;
NS_ADDREF(*aLocalFile);
return NS_OK;
}
nsresult nsWebBrowserPersist::AppendPathToURI(nsIURI *aURI, const nsAString & aPath) const
{
NS_ENSURE_ARG_POINTER(aURI);
nsXPIDLCString oldPath;
nsresult rv = aURI->GetPath(getter_Copies(oldPath));
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
nsCAutoString newPath(oldPath);
// Append a forward slash if necessary
PRInt32 len = newPath.Length();
if (len > 0 && newPath.CharAt(len - 1) != '/')
{
newPath.Append('/');
}
// Store the path back on the URI
newPath.AppendWithConversion(aPath);
aURI->SetPath(newPath.get());
return NS_OK;
}
nsresult nsWebBrowserPersist::SaveURIInternal( nsresult nsWebBrowserPersist::SaveURIInternal(
nsIURI *aURI, nsIInputStream *aPostData, nsILocalFile *aFile, PRBool aCalcFileExt) nsIURI *aURI, nsIInputStream *aPostData, nsIURI *aFile, PRBool aCalcFileExt)
{ {
NS_ENSURE_ARG_POINTER(aURI); NS_ENSURE_ARG_POINTER(aURI);
NS_ENSURE_ARG_POINTER(aFile); NS_ENSURE_ARG_POINTER(aFile);
@ -522,13 +694,26 @@ nsresult nsWebBrowserPersist::SaveURIInternal(
return NS_OK; return NS_OK;
} }
nsresult nsWebBrowserPersist::SaveDocumentInternal( nsresult nsWebBrowserPersist::SaveDocumentInternal(
nsIDOMDocument *aDocument, nsILocalFile *aFile, nsILocalFile *aDataPath) nsIDOMDocument *aDocument, nsIURI *aFile, nsIURI *aDataPath)
{ {
NS_ENSURE_ARG_POINTER(aDocument); NS_ENSURE_ARG_POINTER(aDocument);
NS_ENSURE_ARG_POINTER(aFile); NS_ENSURE_ARG_POINTER(aFile);
nsresult rv; // See if we can get the local file representation of this URI
nsCOMPtr<nsILocalFile> localFile;
nsresult rv = GetLocalFileFromURI(aFile, getter_AddRefs(localFile));
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
// See if we can get the local file representation of this URI
nsCOMPtr<nsILocalFile> localDataPath;
if (aDataPath)
{
rv = GetLocalFileFromURI(aDataPath, getter_AddRefs(localDataPath));
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
}
nsCOMPtr<nsIDOMNode> docAsNode = do_QueryInterface(aDocument); nsCOMPtr<nsIDOMNode> docAsNode = do_QueryInterface(aDocument);
// Persist the main document // Persist the main document
@ -553,26 +738,26 @@ nsresult nsWebBrowserPersist::SaveDocumentInternal(
// 3. Store the document in a list and wait for URI persistence to finish // 3. Store the document in a list and wait for URI persistence to finish
// 4. After URI persistence completes save the list of documents, // 4. After URI persistence completes save the list of documents,
// fixing it up as it goes out to file. // fixing it up as it goes out to file.
aDataPath->Create(nsILocalFile::DIRECTORY_TYPE, 0664); if (localDataPath)
PRBool exists = PR_FALSE;
PRBool isDirectory = PR_FALSE;
aDataPath->Exists(&exists);
aDataPath->IsDirectory(&isDirectory);
if (!exists || !isDirectory)
{ {
EndDownload(NS_ERROR_FAILURE); localDataPath->Create(nsILocalFile::DIRECTORY_TYPE, 0664);
mCurrentBaseURI = oldBaseURI; PRBool exists = PR_FALSE;
return NS_ERROR_FAILURE; PRBool isDirectory = PR_FALSE;
localDataPath->Exists(&exists);
localDataPath->IsDirectory(&isDirectory);
if (!exists || !isDirectory)
{
EndDownload(NS_ERROR_FAILURE);
mCurrentBaseURI = oldBaseURI;
return NS_ERROR_FAILURE;
}
} }
// Test if the data path is relative to the base directory - // Test if the data path is relative to the base directory -
// the one that the document is saved into. // the one that the document is saved into.
nsCOMPtr<nsIFile> baseDir; nsCOMPtr<nsIURI> oldDataPath = mCurrentDataPath;
aFile->GetParent(getter_AddRefs(baseDir));
nsCOMPtr<nsILocalFile> oldDataPath = mCurrentDataPath;
PRBool oldDataPathIsRelative = mCurrentDataPathIsRelative; PRBool oldDataPathIsRelative = mCurrentDataPathIsRelative;
nsCString oldCurrentRelativePathToData = mCurrentRelativePathToData; nsCString oldCurrentRelativePathToData = mCurrentRelativePathToData;
@ -587,32 +772,38 @@ nsresult nsWebBrowserPersist::SaveDocumentInternal(
// Starting with the data dir work back through it's parents // Starting with the data dir work back through it's parents
// checking if one of them matches the base directory. // checking if one of them matches the base directory.
nsCAutoString relativePathToData; if (localDataPath && localFile)
nsCOMPtr<nsIFile> dataDirParent;
dataDirParent = aDataPath;
while (dataDirParent)
{ {
PRBool sameDir = PR_FALSE; nsCOMPtr<nsIFile> baseDir;
dataDirParent->Equals(baseDir, &sameDir); localFile->GetParent(getter_AddRefs(baseDir));
if (sameDir)
nsCAutoString relativePathToData;
nsCOMPtr<nsIFile> dataDirParent;
dataDirParent = localDataPath;
while (dataDirParent)
{ {
mCurrentRelativePathToData = relativePathToData; PRBool sameDir = PR_FALSE;
mCurrentDataPathIsRelative = PR_TRUE; dataDirParent->Equals(baseDir, &sameDir);
break; if (sameDir)
{
mCurrentRelativePathToData = relativePathToData;
mCurrentDataPathIsRelative = PR_TRUE;
break;
}
nsXPIDLCString dirName;
dataDirParent->GetLeafName(getter_Copies(dirName));
nsCAutoString newRelativePathToData;
newRelativePathToData = dirName.get();
newRelativePathToData.Append("/");
newRelativePathToData.Append(relativePathToData);
relativePathToData = newRelativePathToData;
nsCOMPtr<nsIFile> newDataDirParent;
rv = dataDirParent->GetParent(getter_AddRefs(newDataDirParent));
dataDirParent = newDataDirParent;
} }
nsXPIDLCString dirName;
dataDirParent->GetLeafName(getter_Copies(dirName));
nsCAutoString newRelativePathToData;
newRelativePathToData = dirName.get();
newRelativePathToData.Append("/");
newRelativePathToData.Append(relativePathToData);
relativePathToData = newRelativePathToData;
nsCOMPtr<nsIFile> newDataDirParent;
rv = dataDirParent->GetParent(getter_AddRefs(newDataDirParent));
dataDirParent = newDataDirParent;
} }
// Store the document in a list so when URI persistence is done and the // Store the document in a list so when URI persistence is done and the
@ -631,8 +822,18 @@ nsresult nsWebBrowserPersist::SaveDocumentInternal(
// Walk the DOM gathering a list of externally referenced URIs in the uri map // Walk the DOM gathering a list of externally referenced URIs in the uri map
nsDOMWalker walker; nsDOMWalker walker;
walker.WalkDOM(docAsNode, this); walker.WalkDOM(docAsNode, this);
// Persist each file in the uri map if (mURIMap.Count() > 0)
mURIMap.Enumerate(EnumPersistURIs, this); {
// Persist each file in the uri map. The document(s)
// will be saved after the last one of these is saved.
mURIMap.Enumerate(EnumPersistURIs, this);
}
else
{
// There are no URIs so just save the document(s)
SaveDocuments();
EndDownload(NS_OK);
}
mCurrentDataPath = oldDataPath; mCurrentDataPath = oldDataPath;
mCurrentDataPathIsRelative = oldDataPathIsRelative; mCurrentDataPathIsRelative = oldDataPathIsRelative;
@ -643,25 +844,29 @@ nsresult nsWebBrowserPersist::SaveDocumentInternal(
// Set the document base to ensure relative links still work // Set the document base to ensure relative links still work
SetDocumentBase(aDocument, mCurrentBaseURI); SetDocumentBase(aDocument, mCurrentBaseURI);
// create a uri for aFile
nsXPIDLCString urlString;
nsresult rv = NS_GetURLSpecFromFile(aFile, getter_Copies(urlString));
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), urlString);
if (NS_FAILED(rv)) return rv;
// Save the document // Save the document
nsCOMPtr<nsIDiskDocument> diskDoc = do_QueryInterface(docAsNode); nsCOMPtr<nsIDiskDocument> diskDoc = do_QueryInterface(docAsNode);
nsString contentType(NS_LITERAL_STRING("text/html")); // TODO
nsString charType; // Empty nsAutoString contentType;
if (mContentType.Length() > 0)
{
contentType = mContentType;
}
else
{
// TODO infer the other content type - from the DOM document maybe?
contentType = NS_LITERAL_STRING("text/html");
}
nsAutoString charType; // Empty
rv = diskDoc->SaveFile( rv = diskDoc->SaveFile(
uri, aFile,
PR_TRUE /* replace existing file */, mReplaceExisting,
PR_TRUE, /* save as a copy */ PR_TRUE, // save as a copy (i.e. don't change it's dirty status)
contentType.get(), contentType.get(),
charType.get(), charType.get(),
0, 72); mEncodingFlags,
mWrapColumn);
} }
mCurrentBaseURI = oldBaseURI; mCurrentBaseURI = oldBaseURI;
@ -686,8 +891,7 @@ nsresult nsWebBrowserPersist::SaveDocuments()
// Save the document, fixing it up with the new URIs as we do // Save the document, fixing it up with the new URIs as we do
nsCOMPtr<nsIDiskDocument> diskDoc = do_QueryInterface(docData->mDocument); nsCOMPtr<nsIDiskDocument> diskDoc = do_QueryInterface(docData->mDocument);
nsString contentType(NS_LITERAL_STRING("text/html")); // TODO nsAutoString charType; // Empty
nsString charType; // Empty
nsEncoderNodeFixup *nodeFixup; nsEncoderNodeFixup *nodeFixup;
nodeFixup = new nsEncoderNodeFixup; nodeFixup = new nsEncoderNodeFixup;
@ -698,16 +902,26 @@ nsresult nsWebBrowserPersist::SaveDocuments()
nsCOMPtr<nsIDocument> docAsDoc = do_QueryInterface(docData->mDocument); nsCOMPtr<nsIDocument> docAsDoc = do_QueryInterface(docData->mDocument);
nsAutoString contentType;
if (mContentType.Length() > 0)
{
contentType = mContentType;
}
else
{
// TODO infer the other content type - from the DOM document maybe?
contentType.AssignWithConversion("text/html");
}
// Save the document, fixing up the links as it goes out // Save the document, fixing up the links as it goes out
rv = SaveDocumentToFileWithFixup( rv = SaveDocumentWithFixup(
docAsDoc, docAsDoc,
nodeFixup, nodeFixup,
docData->mFile, docData->mFile,
PR_TRUE /* replace existing file */, mReplaceExisting,
PR_TRUE, /* save as a copy */
contentType, contentType,
charType, charType,
0); mEncodingFlags);
// Restore the document's BASE URL // Restore the document's BASE URL
SetDocumentBase(docData->mDocument, docData->mBaseURI); SetDocumentBase(docData->mDocument, docData->mBaseURI);
@ -738,85 +952,112 @@ void nsWebBrowserPersist::CleanUp()
nsresult nsresult
nsWebBrowserPersist::MakeOutputStream( nsWebBrowserPersist::CalculateAndAppendFileExt(nsIURI *aURI, nsIChannel *aChannel)
nsILocalFile *aFile, PRBool aCalcFileExt,
nsIChannel *aChannel, nsIOutputStream **aOutputStream)
{ {
NS_ENSURE_ARG_POINTER(aFile); nsresult rv;
if (!mMIMEService)
{
mMIMEService = do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
NS_ENSURE_TRUE(mMIMEService, NS_ERROR_FAILURE);
}
nsCOMPtr<nsILocalFile> localFile;
GetLocalFileFromURI(aURI, getter_AddRefs(localFile));
NS_ENSURE_TRUE(localFile, NS_ERROR_FAILURE);
nsXPIDLCString contentType;
// Get the content type from the channel
aChannel->GetContentType(getter_Copies(contentType));
// Get the content type from the MIME service
if (contentType.Length() == 0)
{
nsCOMPtr<nsIURI> uri;
aChannel->GetOriginalURI(getter_AddRefs(uri));
rv = mMIMEService->GetTypeFromURI(uri, getter_Copies(contentType));
}
// Append the extension onto the file
if (contentType.Length())
{
nsCOMPtr<nsIMIMEInfo> mimeInfo;
mMIMEService->GetFromMIMEType(
contentType.get(), getter_AddRefs(mimeInfo));
if (mimeInfo)
{
PRBool matchingExt = PR_FALSE;
nsXPIDLCString fileName;
localFile->GetLeafName(getter_Copies(fileName));
nsCString newFileName;
newFileName.Assign(fileName);
// Test if the current extension is current for the mime type
PRBool hasExtension = PR_FALSE;
PRInt32 ext = newFileName.RFind(".");
if (ext != -1)
{
mimeInfo->ExtensionExists(newFileName.get() + ext + 1, &hasExtension);
}
// Append the mime file extension
nsXPIDLCString fileExt;
if (!hasExtension &&
NS_SUCCEEDED(mimeInfo->FirstExtension(getter_Copies(fileExt))))
{
newFileName.Append(".");
newFileName.Append(fileExt.get());
localFile->SetLeafName(newFileName.get());
}
}
#ifdef XP_MAC
// Set appropriate Mac file type/creator for this mime type
nsCOMPtr<nsILocalFileMac> macFile(do_QueryInterface(aFile));
if (macFile)
{
macFile->SetFileTypeAndCreatorFromMIMEType(contentType.get());
}
#endif
}
// Resync the URI with the file after the extension has been appended
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aURI, &rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
fileURL->SetFile(localFile);
return NS_OK;
}
nsresult
nsWebBrowserPersist::MakeOutputStream(
nsIURI *aURI, nsIChannel *aChannel, nsIOutputStream **aOutputStream)
{
NS_ENSURE_ARG_POINTER(aURI);
NS_ENSURE_ARG_POINTER(aChannel); NS_ENSURE_ARG_POINTER(aChannel);
NS_ENSURE_ARG_POINTER(aOutputStream); NS_ENSURE_ARG_POINTER(aOutputStream);
nsCOMPtr<nsILocalFile> localFile;
GetLocalFileFromURI(aURI, getter_AddRefs(localFile));
NS_ENSURE_TRUE(localFile, NS_ERROR_FAILURE);
nsresult rv = MakeOutputStreamFromFile(localFile, aChannel, aOutputStream);
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
return NS_OK;
}
nsresult
nsWebBrowserPersist::MakeOutputStreamFromFile(
nsILocalFile *aFile, nsIChannel *aChannel, nsIOutputStream **aOutputStream)
{
nsresult rv = NS_OK; nsresult rv = NS_OK;
// Does the suggested file name need an extension?
if (aCalcFileExt)
{
if (!mMIMEService)
{
mMIMEService = do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
NS_ENSURE_TRUE(mMIMEService, NS_ERROR_FAILURE);
}
nsXPIDLCString contentType;
// Get the content type from the channel
aChannel->GetContentType(getter_Copies(contentType));
// Get the content type from the MIME service
if (contentType.Length() == 0)
{
nsCOMPtr<nsIURI> uri;
aChannel->GetOriginalURI(getter_AddRefs(uri));
rv = mMIMEService->GetTypeFromURI(uri, getter_Copies(contentType));
}
// Append the extension onto the file
if (contentType.Length())
{
nsCOMPtr<nsIMIMEInfo> mimeInfo;
mMIMEService->GetFromMIMEType(
contentType.get(), getter_AddRefs(mimeInfo));
if (mimeInfo)
{
PRBool matchingExt = PR_FALSE;
nsXPIDLCString fileName;
aFile->GetLeafName(getter_Copies(fileName));
nsCString newFileName;
newFileName.Assign(fileName);
// Test if the current extension is current for the mime type
PRBool hasExtension = PR_FALSE;
PRInt32 ext = newFileName.RFind(".");
if (ext != -1)
{
mimeInfo->ExtensionExists(newFileName.get() + ext + 1, &hasExtension);
}
// Append the mime file extension
nsXPIDLCString fileExt;
if (!hasExtension &&
NS_SUCCEEDED(mimeInfo->FirstExtension(getter_Copies(fileExt))))
{
newFileName.Append(".");
newFileName.Append(fileExt.get());
aFile->SetLeafName(newFileName.get());
}
}
#ifdef XP_MAC
// Set appropriate Mac file type/creator for this mime type
nsCOMPtr<nsILocalFileMac> macFile(do_QueryInterface(aFile));
if (macFile)
{
macFile->SetFileTypeAndCreatorFromMIMEType(contentType.get());
}
#endif
}
}
NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID); NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
nsCOMPtr<nsIFileTransportService> fts = nsCOMPtr<nsIFileTransportService> fts =
do_GetService(kFileTransportServiceCID, &rv); do_GetService(kFileTransportServiceCID, &rv);
@ -976,27 +1217,28 @@ nsWebBrowserPersist::EnumPersistURIs(nsHashKey *aKey, void *aData, void* closure
return PR_TRUE; return PR_TRUE;
} }
nsCString filename; filename.AssignWithConversion(data->mFilename);
nsWebBrowserPersist *pthis = (nsWebBrowserPersist *) closure; nsWebBrowserPersist *pthis = (nsWebBrowserPersist *) closure;
nsresult rv; nsresult rv;
// Save the data to a local file // Create a URI from the key
nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), ((nsCStringKey *) aKey)->GetString()); rv = NS_NewURI(getter_AddRefs(uri), ((nsCStringKey *) aKey)->GetString());
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
nsCOMPtr<nsIFile> fileAsFile; // Make a URI to save the data to
rv = data->mDataPath->Clone(getter_AddRefs(fileAsFile)); nsCOMPtr<nsIURI> fileAsURI;
rv = data->mDataPath->Clone(getter_AddRefs(fileAsURI));
NS_ENSURE_SUCCESS(rv, PR_FALSE); NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsCOMPtr<nsILocalFile> file = do_QueryInterface(fileAsFile); rv = pthis->AppendPathToURI(fileAsURI, data->mFilename);
file->AppendRelativePath(filename.get());
rv = pthis->SaveURIInternal(uri, nsnull, file, PR_TRUE);
NS_ENSURE_SUCCESS(rv, PR_FALSE); NS_ENSURE_SUCCESS(rv, PR_FALSE);
// Store the actual nsILocalFile object because once it's persisted this rv = pthis->SaveURIInternal(uri, nsnull, fileAsURI, PR_TRUE);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
// Store the actual object because once it's persisted this
// will be fixed up with the right file extension. // will be fixed up with the right file extension.
data->mFile = file;
data->mFile = fileAsURI;
data->mSaved = PR_TRUE; data->mSaved = PR_TRUE;
return PR_TRUE; return PR_TRUE;
@ -1271,20 +1513,23 @@ nsWebBrowserPersist::FixupNodeAttribute(nsIDOMNode *aNode,
if (mURIMap.Exists(&key)) if (mURIMap.Exists(&key))
{ {
URIData *data = (URIData *) mURIMap.Get(&key); URIData *data = (URIData *) mURIMap.Get(&key);
nsCOMPtr<nsILocalFile> file = data->mFile; nsCOMPtr<nsIURI> fileAsURI = data->mFile;
if (!file) if (!fileAsURI)
{ {
nsCOMPtr<nsIFile> fileAsFile; rv = data->mDataPath->Clone(getter_AddRefs(fileAsURI));
rv = data->mDataPath->Clone(getter_AddRefs(fileAsFile)); NS_ENSURE_SUCCESS(rv, PR_FALSE);
rv = AppendPathToURI(fileAsURI, data->mFilename);
NS_ENSURE_SUCCESS(rv, PR_FALSE); NS_ENSURE_SUCCESS(rv, PR_FALSE);
file = do_QueryInterface(fileAsFile);
file->AppendUnicode(data->mFilename.get());
} }
nsAutoString newValue; nsAutoString newValue;
if (data->mDataPathIsRelative)
// Use relative or absolute links
nsCOMPtr<nsILocalFile> localFile;
GetLocalFileFromURI(fileAsURI, getter_AddRefs(localFile));
if (data->mDataPathIsRelative && localFile)
{ {
nsXPIDLCString filename; nsXPIDLCString filename;
file->GetLeafName(getter_Copies(filename)); localFile->GetLeafName(getter_Copies(filename));
nsCAutoString rawPathURL; nsCAutoString rawPathURL;
rawPathURL.Assign(data->mRelativePathToData); rawPathURL.Assign(data->mRelativePathToData);
rawPathURL.Append(filename.get()); rawPathURL.Append(filename.get());
@ -1293,7 +1538,7 @@ nsWebBrowserPersist::FixupNodeAttribute(nsIDOMNode *aNode,
else else
{ {
nsXPIDLCString fileurl; nsXPIDLCString fileurl;
NS_GetURLSpecFromFile(file, getter_Copies(fileurl)); NS_GetURLSpecFromFile(localFile, getter_Copies(fileurl));
newValue.AssignWithConversion(fileurl); newValue.AssignWithConversion(fileurl);
} }
if (data->mIsSubFrame) if (data->mIsSubFrame)
@ -1359,68 +1604,68 @@ nsWebBrowserPersist::SaveSubframeContent(
nsIDOMDocument *aFrameContent, URIData *aData) nsIDOMDocument *aFrameContent, URIData *aData)
{ {
NS_ENSURE_ARG_POINTER(aData); NS_ENSURE_ARG_POINTER(aData);
nsresult rv; nsresult rv;
// Work out the path for the frame
nsString filenameWithExt = aData->mFilename; nsString filenameWithExt = aData->mFilename;
// Append an extension
filenameWithExt.Append(aData->mSubFrameExt); filenameWithExt.Append(aData->mSubFrameExt);
nsCOMPtr<nsIFile> frameFileAsFile;
rv = mCurrentDataPath->Clone(getter_AddRefs(frameFileAsFile));
NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsCOMPtr<nsILocalFile> frameFile = do_QueryInterface(frameFileAsFile);
frameFile->AppendUnicode(filenameWithExt.get());
// Work out the path for the frame data // Work out the path for the subframe
nsCOMPtr<nsIFile> frameDataPathAsFile; nsCOMPtr<nsIURI> frameURI;
rv = mCurrentDataPath->Clone(getter_AddRefs(frameDataPathAsFile)); rv = mCurrentDataPath->Clone(getter_AddRefs(frameURI));
NS_ENSURE_SUCCESS(rv, PR_FALSE);
rv = AppendPathToURI(frameURI, filenameWithExt);
NS_ENSURE_SUCCESS(rv, PR_FALSE); NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsCOMPtr<nsILocalFile> frameDatapath = do_QueryInterface(frameDataPathAsFile);
nsString frameDataPathName = aData->mFilename;
frameDataPathName.Append(NS_LITERAL_STRING("_data"));
frameDatapath->AppendUnicode(frameDataPathName.get());
SaveDocumentInternal(aFrameContent, frameFile, frameDatapath); // Work out the path for the subframe data
nsCOMPtr<nsIURI> frameDataURI;
rv = mCurrentDataPath->Clone(getter_AddRefs(frameDataURI));
NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsAutoString newFrameDataPath(aData->mFilename);
newFrameDataPath.Append(NS_LITERAL_STRING("_data"));
rv = AppendPathToURI(frameDataURI, newFrameDataPath);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
SaveDocumentInternal(aFrameContent, frameURI, frameDataURI);
return NS_OK; return NS_OK;
} }
nsresult nsresult
nsWebBrowserPersist::SaveDocumentToFileWithFixup( nsWebBrowserPersist::SaveDocumentWithFixup(
nsIDocument *aDocument, nsIDocumentEncoderNodeFixup *aNodeFixup, nsIDocument *aDocument, nsIDocumentEncoderNodeFixup *aNodeFixup,
nsIFile *aFile, PRBool aReplaceExisting, PRBool aSaveCopy, nsIURI *aFile, PRBool aReplaceExisting, const nsString &aFormatType,
const nsString &aFormatType, const nsString &aSaveCharset, const nsString &aSaveCharset, PRUint32 aFlags)
PRUint32 aFlags)
{ {
// NOTE: This function is essentially a copy of nsDocument::SaveFile // NOTE: This function is based off of nsDocument::SaveFile
// with a single line added to set the node fixup call back.
// This line is marked.
if (!aFile) NS_ENSURE_ARG_POINTER(aFile);
{
return NS_ERROR_NULL_POINTER;
}
nsresult rv = NS_OK; nsresult rv = NS_OK;
nsCOMPtr<nsIOutputStream> outputStream;
nsCOMPtr<nsILocalFile> localFile;
GetLocalFileFromURI(aFile, getter_AddRefs(localFile));
NS_ENSURE_TRUE(localFile, NS_ERROR_FAILURE);
// if we're not replacing an existing file but the file // if we're not replacing an existing file but the file
// exists, somethine is wrong // exists, something is wrong
PRBool fileExists; PRBool fileExists = PR_FALSE;
rv = aFile->Exists(&fileExists); rv = localFile->Exists(&fileExists);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
if (!aReplaceExisting && fileExists) if (!aReplaceExisting && fileExists)
return NS_ERROR_FAILURE; // where are the file I/O errors? return NS_ERROR_FAILURE; // where are the file I/O errors?
nsCOMPtr<nsIFileOutputStream> outputStream = nsCOMPtr<nsIFileOutputStream> fileOutputStream =
do_CreateInstance(NS_LOCALFILEOUTPUTSTREAM_CONTRACTID, &rv); do_CreateInstance(NS_LOCALFILEOUTPUTSTREAM_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
rv = outputStream->Init(aFile, -1, -1); rv = fileOutputStream->Init(localFile, -1, -1);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
outputStream = do_QueryInterface(fileOutputStream);
// Get a document encoder instance // Get a document encoder instance
nsCAutoString contractID(NS_DOC_ENCODER_CONTRACTID_BASE); nsCAutoString contractID(NS_DOC_ENCODER_CONTRACTID_BASE);
contractID.AppendWithConversion(aFormatType); contractID.AppendWithConversion(aFormatType);
@ -1435,9 +1680,8 @@ nsWebBrowserPersist::SaveDocumentToFileWithFixup(
return rv; return rv;
} }
// BEGIN --- Node fixup callback // Set the node fixup callback
encoder->SetNodeFixup(aNodeFixup); encoder->SetNodeFixup(aNodeFixup);
// END --- Node fixup callback
nsAutoString charsetStr(aSaveCharset); nsAutoString charsetStr(aSaveCharset);
if (charsetStr.Length() == 0) if (charsetStr.Length() == 0)

Просмотреть файл

@ -74,20 +74,25 @@ protected:
nsresult CloneNodeWithFixedUpURIAttributes( nsresult CloneNodeWithFixedUpURIAttributes(
nsIDOMNode *aNodeIn, nsIDOMNode **aNodeOut); nsIDOMNode *aNodeIn, nsIDOMNode **aNodeOut);
nsresult SaveURIInternal( nsresult SaveURIInternal(
nsIURI *aURI, nsIInputStream *aPostData, nsILocalFile *aFile, nsIURI *aURI, nsIInputStream *aPostData, nsIURI *aFile,
PRBool aCalcFileExt); PRBool aCalcFileExt);
nsresult SaveDocumentInternal(nsIDOMDocument *aDocument, nsresult SaveDocumentInternal(
nsILocalFile *aFile, nsILocalFile *aDataPath); nsIDOMDocument *aDocument, nsIURI *aFile, nsIURI *aDataPath);
nsresult SaveDocuments(); nsresult SaveDocuments();
// Private members // Private members
private: private:
void CleanUp(); void CleanUp();
nsresult GetValidURIFromObject(nsISupports *aObject, nsIURI **aURI) const;
nsresult GetLocalFileFromURI(nsIURI *aURI, nsILocalFile **aLocalFile) const;
nsresult AppendPathToURI(nsIURI *aURI, const nsAString & aPath) const;
nsresult MakeAndStoreLocalFilenameInURIMap( nsresult MakeAndStoreLocalFilenameInURIMap(
const char *aURI, PRBool aNeedsPersisting, URIData **aData); const char *aURI, PRBool aNeedsPersisting, URIData **aData);
nsresult MakeOutputStream( nsresult MakeOutputStream(
nsILocalFile *aFile, PRBool aCalcFileExt, nsIURI *aFile, nsIChannel *aChannel, nsIOutputStream **aOutputStream);
nsIChannel *aChannel, nsIOutputStream **aOutputStream); nsresult MakeOutputStreamFromFile(
nsILocalFile *aFile, nsIChannel *aChannel, nsIOutputStream **aOutputStream);
nsresult CalculateAndAppendFileExt(nsIURI *aURI, nsIChannel *aChannel);
nsresult MakeFilenameFromURI( nsresult MakeFilenameFromURI(
nsIURI *aURI, nsString &aFilename); nsIURI *aURI, nsString &aFilename);
nsresult StoreURIAttribute( nsresult StoreURIAttribute(
@ -97,11 +102,10 @@ private:
nsresult FixupNodeAttribute(nsIDOMNode *aNode, const char *aAttribute); nsresult FixupNodeAttribute(nsIDOMNode *aNode, const char *aAttribute);
nsresult FixupAnchor(nsIDOMNode *aNode); nsresult FixupAnchor(nsIDOMNode *aNode);
nsresult StoreAndFixupStyleSheet(nsIStyleSheet *aStyleSheet); nsresult StoreAndFixupStyleSheet(nsIStyleSheet *aStyleSheet);
nsresult SaveDocumentToFileWithFixup( nsresult SaveDocumentWithFixup(
nsIDocument *pDocument, nsIDocumentEncoderNodeFixup *pFixup, nsIDocument *pDocument, nsIDocumentEncoderNodeFixup *pFixup,
nsIFile *aFile, PRBool aReplaceExisting, PRBool aSaveCopy, nsIURI *aFile, PRBool aReplaceExisting, const nsString &aFormatType,
const nsString &aFormatType, const nsString &aSaveCharset, const nsString &aSaveCharset, PRUint32 aFlags);
PRUint32 aFlags);
nsresult SaveSubframeContent( nsresult SaveSubframeContent(
nsIDOMDocument *aFrameContent, URIData *aData); nsIDOMDocument *aFrameContent, URIData *aData);
nsresult SetDocumentBase(nsIDOMDocument *aDocument, nsIURI *aBaseURI); nsresult SetDocumentBase(nsIDOMDocument *aDocument, nsIURI *aBaseURI);
@ -126,7 +130,7 @@ private:
static PRBool PR_CALLBACK EnumFixRedirect( static PRBool PR_CALLBACK EnumFixRedirect(
nsHashKey *aKey, void *aData, void* closure); nsHashKey *aKey, void *aData, void* closure);
nsCOMPtr<nsILocalFile> mCurrentDataPath; nsCOMPtr<nsIURI> mCurrentDataPath;
PRBool mCurrentDataPathIsRelative; PRBool mCurrentDataPathIsRelative;
nsCString mCurrentRelativePathToData; nsCString mCurrentRelativePathToData;
nsCOMPtr<nsIURI> mCurrentBaseURI; nsCOMPtr<nsIURI> mCurrentBaseURI;
@ -147,7 +151,10 @@ private:
PRUint32 mPersistResult; PRUint32 mPersistResult;
PRInt32 mTotalCurrentProgress; PRInt32 mTotalCurrentProgress;
PRInt32 mTotalMaxProgress; PRInt32 mTotalMaxProgress;
PRBool mReplaceExisting;
PRInt16 mWrapColumn;
PRUint32 mEncodingFlags;
nsString mContentType;
}; };
// Helper class does node fixup during persistence // Helper class does node fixup during persistence

Просмотреть файл

@ -690,7 +690,7 @@ void CBrowserView::OnFileSaveAs()
// Save the file // Save the file
nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(mWebBrowser)); nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(mWebBrowser));
if(persist) if(persist)
{ {
nsCOMPtr<nsILocalFile> file; nsCOMPtr<nsILocalFile> file;
NS_NewLocalFile(T2A(pStrFullPath), TRUE, getter_AddRefs(file)); NS_NewLocalFile(T2A(pStrFullPath), TRUE, getter_AddRefs(file));
@ -702,11 +702,11 @@ void CBrowserView::OnFileSaveAs()
} }
if(bSaveAll) if(bSaveAll)
persist->SaveDocument(nsnull, file, dataPath); persist->SaveDocument(nsnull, file, dataPath, nsnull, 0, 0);
else else
persist->SaveURI(nsnull, nsnull, file); persist->SaveURI(nsnull, nsnull, file);
} }
} }
} }
void CBrowserView::OpenURL(const char* pUrl) void CBrowserView::OpenURL(const char* pUrl)
@ -841,9 +841,9 @@ void CBrowserView::OnSaveLinkAs()
{ {
nsCOMPtr<nsILocalFile> file; nsCOMPtr<nsILocalFile> file;
NS_NewLocalFile(strFullPath.GetBuffer(0), TRUE, getter_AddRefs(file)); NS_NewLocalFile(strFullPath.GetBuffer(0), TRUE, getter_AddRefs(file));
persist->SaveURI(linkURI, nsnull, file); persist->SaveURI(linkURI, nsnull, file);
} }
} }
} }
void CBrowserView::OnSaveImageAs() void CBrowserView::OnSaveImageAs()
@ -883,13 +883,13 @@ void CBrowserView::OnSaveImageAs()
CString strFullPath = cf.GetPathName(); CString strFullPath = cf.GetPathName();
nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(mWebBrowser)); nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(mWebBrowser));
if(persist) if(persist)
{ {
nsCOMPtr<nsILocalFile> file; nsCOMPtr<nsILocalFile> file;
NS_NewLocalFile(strFullPath.GetBuffer(0), TRUE, getter_AddRefs(file)); NS_NewLocalFile(strFullPath.GetBuffer(0), TRUE, getter_AddRefs(file));
persist->SaveURI(linkURI, nsnull, file); persist->SaveURI(linkURI, nsnull, file);
} }
} }
} }
void CBrowserView::OnShowFindDlg() void CBrowserView::OnShowFindDlg()

Просмотреть файл

@ -429,8 +429,8 @@ void SaveWebPage(nsIWebBrowser *aWebBrowser)
NS_NewLocalFile(pszDataPath, TRUE, getter_AddRefs(dataPath)); NS_NewLocalFile(pszDataPath, TRUE, getter_AddRefs(dataPath));
} }
persist->SaveDocument(nsnull, file, dataPath); persist->SaveDocument(nsnull, file, dataPath, nsnull, 0, 0);
} }
} }

Просмотреть файл

@ -400,7 +400,7 @@ function onLoad() {
filesFolder.leafName = filesFolderLeafName; filesFolder.leafName = filesFolderLeafName;
filesFolder.create(lfIID.DIRECTORY_TYPE, 0644); filesFolder.create(lfIID.DIRECTORY_TYPE, 0644);
webBrowserPersist.saveDocument(persistArgs.source, targetFile, filesFolder); webBrowserPersist.saveDocument(persistArgs.source, targetFile, filesFolder, null, 0, 0);
} }
} }