mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-02 15:15:23 +00:00
1211 lines
35 KiB
C++
1211 lines
35 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is the Mozilla browser.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications, Inc. Portions created by Netscape are
|
|
* Copyright (C) 1999, Mozilla. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Adam Lock <adamlock@netscape.com>
|
|
*/
|
|
|
|
#include "nspr.h"
|
|
|
|
#define NO_XPCOM_FILE_STREAMS
|
|
#include "nsIFileStream.h" // Old XPCOM file streams
|
|
#undef NO_XPCOM_FILE_STREAMS
|
|
|
|
#include "nsIFileStreams.h" // New Necko file streams
|
|
|
|
#include "nsNetUtil.h"
|
|
#include "nsIFileTransportService.h"
|
|
#include "nsIHttpChannel.h"
|
|
#include "nsEscape.h"
|
|
|
|
#include "nsCExternalHandlerService.h"
|
|
|
|
#include "nsIURL.h"
|
|
#include "nsIDocument.h"
|
|
#include "nsIDOMDocument.h"
|
|
#include "nsIDOMNode.h"
|
|
#include "nsIDOMNamedNodeMap.h"
|
|
#include "nsIDOMNodeList.h"
|
|
#include "nsIDiskDocument.h"
|
|
|
|
#include "nsIDOMHTMLBodyElement.h"
|
|
#include "nsIDOMHTMLAnchorElement.h"
|
|
#include "nsIDOMHTMLAreaElement.h"
|
|
#include "nsIDOMHTMLImageElement.h"
|
|
#include "nsIDOMHTMLScriptElement.h"
|
|
#include "nsIDOMHTMLLinkElement.h"
|
|
#include "nsIDOMHTMLBaseElement.h"
|
|
#include "nsIDOMHTMLFrameElement.h"
|
|
#include "nsIDOMHTMLIFrameElement.h"
|
|
#include "nsIDOMHTMLInputElement.h"
|
|
#include "nsIDOMHTMLDocument.h"
|
|
|
|
#include "nsWebBrowserPersist.h"
|
|
|
|
struct URIData
|
|
{
|
|
PRBool mNeedsPersisting;
|
|
nsString mFilename;
|
|
};
|
|
|
|
nsWebBrowserPersist::nsWebBrowserPersist() :
|
|
mFileCounter(1),
|
|
mFrameCounter(1),
|
|
mTaskCounter(0),
|
|
mDataPathIsRelative(PR_FALSE),
|
|
mFirstAndOnlyUse(PR_TRUE)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
}
|
|
|
|
nsWebBrowserPersist::~nsWebBrowserPersist()
|
|
{
|
|
CleanUp();
|
|
}
|
|
|
|
void nsWebBrowserPersist::CleanUp()
|
|
{
|
|
if (mOutputStream)
|
|
{
|
|
mOutputStream->Close();
|
|
mOutputStream = nsnull;
|
|
}
|
|
mOutputTransport = nsnull;
|
|
}
|
|
|
|
NS_IMPL_ADDREF(nsWebBrowserPersist)
|
|
NS_IMPL_RELEASE(nsWebBrowserPersist)
|
|
|
|
NS_INTERFACE_MAP_BEGIN(nsWebBrowserPersist)
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserPersist)
|
|
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPersist)
|
|
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPersistProgress)
|
|
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
|
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
//*****************************************************************************
|
|
// nsWebBrowserPersist::nsIWebBrowserPersist
|
|
//*****************************************************************************
|
|
|
|
/* attribute nsIWebBrowserPersistProgress progressListener; */
|
|
NS_IMETHODIMP nsWebBrowserPersist::GetProgressListener(nsIWebBrowserPersistProgress * *aProgressListener)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aProgressListener);
|
|
*aProgressListener = mProgressListener;
|
|
NS_IF_ADDREF(*aProgressListener);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsWebBrowserPersist::SetProgressListener(nsIWebBrowserPersistProgress * aProgressListener)
|
|
{
|
|
mProgressListener = aProgressListener;
|
|
return NS_OK;
|
|
}
|
|
|
|
/* void saveURI (in nsIURI aURI, in string aFileName); */
|
|
NS_IMETHODIMP nsWebBrowserPersist::SaveURI(nsIURI *aURI, nsIInputStream *aPostData, const char *aFileName)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aURI);
|
|
NS_ENSURE_ARG_POINTER(aFileName);
|
|
NS_ENSURE_TRUE(mFirstAndOnlyUse, NS_ERROR_FAILURE);
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
mURI = aURI;
|
|
mFirstAndOnlyUse = PR_FALSE; // Stop people from reusing this object!
|
|
|
|
OnBeginDownload();
|
|
|
|
// Open a channel to the URI
|
|
nsCOMPtr<nsIChannel> inputChannel;
|
|
rv = NS_OpenURI(getter_AddRefs(inputChannel), aURI, nsnull);
|
|
|
|
if (NS_FAILED(rv) || inputChannel == nsnull)
|
|
{
|
|
OnEndDownload();
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// Post data
|
|
if (aPostData)
|
|
{
|
|
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(inputChannel));
|
|
if (httpChannel)
|
|
{
|
|
nsCOMPtr<nsIRandomAccessStore> stream(do_QueryInterface(aPostData));
|
|
if (stream)
|
|
{
|
|
// Rewind the postdata stream
|
|
stream->Seek(PR_SEEK_SET, 0);
|
|
// Attach the postdata to the http channel
|
|
httpChannel->SetUploadStream(aPostData);
|
|
}
|
|
}
|
|
}
|
|
|
|
NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
|
|
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
|
|
|
|
if (NS_FAILED(rv))
|
|
{
|
|
OnEndDownload();
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// Create a local file object
|
|
nsCOMPtr<nsILocalFile> file;
|
|
rv = NS_NewLocalFile(aFileName, PR_FALSE, getter_AddRefs(file));
|
|
if (NS_FAILED(rv))
|
|
{
|
|
OnEndDownload();
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// Open a channel on the local file
|
|
nsCOMPtr<nsITransport> outputChannel;
|
|
rv = fts->CreateTransport(file, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
|
|
0664, getter_AddRefs(outputChannel));
|
|
if (NS_FAILED(rv))
|
|
{
|
|
OnEndDownload();
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
mOutputTransport = outputChannel;
|
|
|
|
// Read from the input channel
|
|
rv = inputChannel->AsyncOpen(this, nsnull);
|
|
if (NS_FAILED(rv))
|
|
{
|
|
OnEndDownload();
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
/* void saveCurrentURI (in string aFileName); */
|
|
NS_IMETHODIMP nsWebBrowserPersist::SaveCurrentURI(const char *aFileName)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
|
|
/* void saveDocument (in nsIDOMDocument document); */
|
|
NS_IMETHODIMP nsWebBrowserPersist::SaveDocument(nsIDOMDocument *aDocument, const char *aFileName, const char *aDataPath)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aDocument);
|
|
NS_ENSURE_ARG_POINTER(aFileName);
|
|
NS_ENSURE_TRUE(mFirstAndOnlyUse, NS_ERROR_FAILURE);
|
|
|
|
mFirstAndOnlyUse = PR_FALSE; // Stop people from reusing this object!
|
|
|
|
OnBeginDownload();
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsIDOMNode> docAsNode = do_QueryInterface(aDocument);
|
|
|
|
// Persist the main document
|
|
nsCOMPtr<nsIDocument> doc(do_QueryInterface(aDocument));
|
|
mURI = do_QueryInterface(doc->GetDocumentURL());
|
|
|
|
// Store the base URI
|
|
doc->GetBaseURL(*getter_AddRefs(mBaseURI));
|
|
|
|
nsCOMPtr<nsILocalFile> fileSpec(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
|
|
if (NS_FAILED(rv))
|
|
{
|
|
OnEndDownload();
|
|
return rv;
|
|
}
|
|
|
|
rv = fileSpec->InitWithPath(aFileName);
|
|
if (NS_FAILED(rv))
|
|
{
|
|
OnEndDownload();
|
|
return rv;
|
|
}
|
|
|
|
// Does the caller want to fixup the referenced URIs and save those too?
|
|
if (aDataPath)
|
|
{
|
|
// Sanity check & create the specified data path
|
|
nsCOMPtr<nsILocalFile> dataPath;
|
|
rv = NS_NewLocalFile(aDataPath, PR_FALSE, getter_AddRefs(dataPath));
|
|
if (NS_FAILED(rv))
|
|
{
|
|
OnEndDownload();
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
dataPath->Create(nsILocalFile::DIRECTORY_TYPE, 0664);
|
|
PRBool exists = PR_FALSE;
|
|
PRBool isDirectory = PR_FALSE;
|
|
dataPath->Exists(&exists);
|
|
dataPath->IsDirectory(&isDirectory);
|
|
if (!exists || !isDirectory)
|
|
{
|
|
OnEndDownload();
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// Test if the data path is relative to the base directory -
|
|
// the one that the document is saved into.
|
|
|
|
mDataPathIsRelative = PR_FALSE;
|
|
nsCOMPtr<nsIFile> baseDir;
|
|
fileSpec->GetParent(getter_AddRefs(baseDir));
|
|
|
|
// Starting with the data dir work back through it's parents
|
|
// checking if one of them is the base directory.
|
|
|
|
nsCAutoString relativePathURL;
|
|
|
|
nsCOMPtr<nsIFile> dataDirParent;
|
|
dataDirParent = dataPath;
|
|
while (dataDirParent)
|
|
{
|
|
PRBool sameDir = PR_FALSE;
|
|
dataDirParent->Equals(baseDir, &sameDir);
|
|
if (sameDir)
|
|
{
|
|
mRelativeDataPathURL = relativePathURL;
|
|
mDataPathIsRelative = PR_TRUE;
|
|
break;
|
|
}
|
|
|
|
nsXPIDLCString dirName;
|
|
dataDirParent->GetLeafName(getter_Copies(dirName));
|
|
|
|
nsCAutoString newRelativePathURL;
|
|
newRelativePathURL = dirName.get();
|
|
newRelativePathURL.Append("/");
|
|
newRelativePathURL.Append(relativePathURL);
|
|
relativePathURL = newRelativePathURL;
|
|
|
|
nsCOMPtr<nsIFile> newDataDirParent;
|
|
rv = dataDirParent->GetParent(getter_AddRefs(newDataDirParent));
|
|
dataDirParent = newDataDirParent;
|
|
}
|
|
|
|
// Try and get the MIME lookup service
|
|
if (!mMIMEService)
|
|
{
|
|
mMIMEService = do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
|
|
}
|
|
|
|
// Walk the DOM gathering a list of externally referenced URIs in the uri map
|
|
mDataPath = aDataPath;
|
|
nsDOMWalker walker;
|
|
walker.WalkDOM(docAsNode, this);
|
|
// Persist each file in the uri map
|
|
mURIMap.Enumerate(PersistURIs, this);
|
|
|
|
// Save the document, fixing it up with the new URIs as we do
|
|
nsCOMPtr<nsIDiskDocument> diskDoc = do_QueryInterface(docAsNode);
|
|
nsString contentType; contentType.AssignWithConversion("text/html"); // TODO
|
|
nsString charType; // Empty
|
|
|
|
nsEncoderNodeFixup *nodeFixup;
|
|
nodeFixup = new nsEncoderNodeFixup;
|
|
nodeFixup->mWebBrowserPersist = this;
|
|
|
|
// Remove document base so relative links work on the persisted version
|
|
SetDocumentBase(aDocument, nsnull);
|
|
|
|
// Save the document, fixing up the links as it goes out
|
|
rv = SaveDocumentToFileWithFixup(
|
|
doc,
|
|
nodeFixup,
|
|
fileSpec,
|
|
PR_TRUE /* replace existing file */,
|
|
PR_TRUE, /* save as a copy */
|
|
contentType,
|
|
charType,
|
|
0);
|
|
|
|
// Restore the document's BASE URL
|
|
SetDocumentBase(aDocument, mBaseURI);
|
|
|
|
mURIMap.Enumerate(CleanupURIMap, this);
|
|
mURIMap.Reset();
|
|
}
|
|
else
|
|
{
|
|
// Set the document base to ensure relative links still work
|
|
SetDocumentBase(aDocument, mBaseURI);
|
|
|
|
// Save the document
|
|
nsCOMPtr<nsIDiskDocument> diskDoc = do_QueryInterface(docAsNode);
|
|
nsString contentType; contentType.AssignWithConversion("text/html"); // TODO
|
|
nsString charType; // Empty
|
|
|
|
rv = diskDoc->SaveFile(
|
|
fileSpec,
|
|
PR_TRUE /* replace existing file */,
|
|
PR_TRUE, /* save as a copy */
|
|
contentType.GetUnicode(),
|
|
charType.GetUnicode(),
|
|
0, 72);
|
|
}
|
|
|
|
OnEndDownload();
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
// nsWebBrowserPersist::nsIWebBrowserPersistProgress
|
|
//*****************************************************************************
|
|
|
|
|
|
/* void OnProgress (in unsigned long aStatus, in string aURI, out boolean aAbort); */
|
|
NS_IMETHODIMP nsWebBrowserPersist::OnProgress(PRUint32 aStatus, nsIURI *aURI, PRBool *aAbort)
|
|
{
|
|
if (mProgressListener)
|
|
{
|
|
if (aStatus & PROGRESS_STARTED)
|
|
{
|
|
// Listener only needs to know if this is the first thing to start
|
|
if (mTaskCounter == 0)
|
|
{
|
|
mProgressListener->OnProgress(PROGRESS_STARTED, nsnull, aAbort);
|
|
}
|
|
mTaskCounter++;
|
|
}
|
|
else if (aStatus & PROGRESS_FINISHED)
|
|
{
|
|
mTaskCounter--;
|
|
// Listener only needs to know if this is the last thing to finish
|
|
if (mTaskCounter == 0)
|
|
{
|
|
mProgressListener->OnProgress(PROGRESS_FINISHED, nsnull, aAbort);
|
|
mProgressListener = nsnull;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Other notifications
|
|
mProgressListener->OnProgress(aStatus, aURI, aAbort);
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
// nsWebBrowserPersist::nsIRequestObserver
|
|
//*****************************************************************************
|
|
|
|
|
|
NS_IMETHODIMP nsWebBrowserPersist::OnStartRequest(nsIRequest* request, nsISupports *ctxt)
|
|
{
|
|
nsresult rv = mOutputTransport->OpenOutputStream(0, -1, 0, getter_AddRefs(mOutputStream));
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP nsWebBrowserPersist::OnStopRequest(nsIRequest* request, nsISupports *ctxt, nsresult status)
|
|
{
|
|
OnEndDownload();
|
|
CleanUp();
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
// nsWebBrowserPersist::nsIStreamListener
|
|
//*****************************************************************************
|
|
|
|
|
|
NS_IMETHODIMP nsWebBrowserPersist::OnDataAvailable(nsIRequest* request, nsISupports *aContext, nsIInputStream *aIStream, PRUint32 aOffset, PRUint32 aLength)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
unsigned long bytesRemaining = aLength;
|
|
PRBool cancel = PR_FALSE;
|
|
|
|
while (bytesRemaining)
|
|
{
|
|
char buffer[8192];
|
|
unsigned int bytesRead;
|
|
|
|
rv = aIStream->Read(buffer, PR_MIN(sizeof(buffer), bytesRemaining), &bytesRead);
|
|
if (NS_SUCCEEDED(rv))
|
|
{
|
|
unsigned int bytesWritten;
|
|
rv = mOutputStream->Write(buffer, bytesRead, &bytesWritten);
|
|
if (NS_SUCCEEDED(rv) && bytesWritten == bytesRead)
|
|
{
|
|
bytesRemaining -= bytesWritten;
|
|
}
|
|
else
|
|
{
|
|
// Disaster - can't write out the bytes - disk full / permission?
|
|
cancel = PR_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Disaster - can't read the bytes - broken link / file error?
|
|
cancel = PR_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Cancel reading?
|
|
if (cancel)
|
|
{
|
|
if (request)
|
|
{
|
|
request->Cancel(NS_BINDING_ABORTED);
|
|
}
|
|
CleanUp();
|
|
OnEndDownload();
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
//*****************************************************************************
|
|
// nsWebBrowserPersist private methods
|
|
//*****************************************************************************
|
|
|
|
|
|
void
|
|
nsWebBrowserPersist::OnBeginDownload()
|
|
{
|
|
PRBool abortOperation = PR_FALSE;
|
|
OnProgress(PROGRESS_STARTED, nsnull, &abortOperation);
|
|
OnProgress(PROGRESS_START_URI, mURI, &abortOperation);
|
|
}
|
|
|
|
|
|
void
|
|
nsWebBrowserPersist::OnEndDownload()
|
|
{
|
|
PRBool abortOperation = PR_FALSE;
|
|
OnProgress(PROGRESS_END_URI, mURI, &abortOperation);
|
|
OnProgress(PROGRESS_FINISHED, nsnull, &abortOperation);
|
|
Release();
|
|
}
|
|
|
|
|
|
PRBool PR_CALLBACK
|
|
nsWebBrowserPersist::PersistURIs(nsHashKey *aKey, void *aData, void* closure)
|
|
{
|
|
URIData *data = (URIData *) aData;
|
|
if (!data->mNeedsPersisting)
|
|
{
|
|
return PR_TRUE;
|
|
}
|
|
|
|
nsCString filename; filename.AssignWithConversion(data->mFilename);
|
|
nsWebBrowserPersist *pthis = (nsWebBrowserPersist *) closure;
|
|
nsresult rv;
|
|
|
|
// Save the data to a local file
|
|
nsCOMPtr<nsIURI> uri;
|
|
rv = NS_NewURI(getter_AddRefs(uri), ((nsCStringKey *) aKey)->GetString(), pthis->mBaseURI);
|
|
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
|
|
|
nsCOMPtr<nsILocalFile> file;
|
|
nsXPIDLCString filePath;
|
|
rv = NS_NewLocalFile(pthis->mDataPath, PR_FALSE, getter_AddRefs(file));
|
|
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
|
|
|
file->AppendRelativePath(filename);
|
|
file->GetPath(getter_Copies(filePath));
|
|
|
|
// Create a persistence object to save the URI to
|
|
nsWebBrowserPersist *persist = new nsWebBrowserPersist();
|
|
if (persist == nsnull)
|
|
{
|
|
return PR_FALSE;
|
|
}
|
|
persist->AddRef();
|
|
persist->SetProgressListener(NS_STATIC_CAST(nsIWebBrowserPersistProgress *, pthis));
|
|
rv = persist->SaveURI(uri, nsnull, filePath);
|
|
|
|
return PR_TRUE;
|
|
}
|
|
|
|
|
|
PRBool PR_CALLBACK
|
|
nsWebBrowserPersist::CleanupURIMap(nsHashKey *aKey, void *aData, void* closure)
|
|
{
|
|
URIData *data = (URIData *) aData;
|
|
if (data)
|
|
{
|
|
delete data; // Delete data associated with key
|
|
}
|
|
return PR_TRUE;
|
|
}
|
|
|
|
|
|
nsresult
|
|
nsWebBrowserPersist::OnWalkDOMNode(nsIDOMNode *aNode, PRBool *aAbort)
|
|
{
|
|
// Test the node to see if it's an image, frame, iframe, css, js
|
|
nsCOMPtr<nsIDOMHTMLImageElement> nodeAsImage = do_QueryInterface(aNode);
|
|
if (nodeAsImage)
|
|
{
|
|
StoreURIAttribute(aNode, "src");
|
|
StoreURIAttribute(aNode, "lowsrc");
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLBodyElement> nodeAsBody = do_QueryInterface(aNode);
|
|
if (nodeAsBody)
|
|
{
|
|
StoreURIAttribute(aNode, "background");
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLScriptElement> nodeAsScript = do_QueryInterface(aNode);
|
|
if (nodeAsScript)
|
|
{
|
|
StoreURIAttribute(aNode, "src");
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLLinkElement> nodeAsLink = do_QueryInterface(aNode);
|
|
if (nodeAsLink)
|
|
{
|
|
StoreURIAttribute(aNode, "href");
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLFrameElement> nodeAsFrame = do_QueryInterface(aNode);
|
|
if (nodeAsFrame)
|
|
{
|
|
nsString filename;
|
|
StoreURIAttribute(aNode, "src", PR_FALSE, &filename);
|
|
// Save the frame content
|
|
nsCOMPtr<nsIDOMDocument> content;
|
|
nodeAsFrame->GetContentDocument(getter_AddRefs(content));
|
|
if (content)
|
|
{
|
|
SaveSubframeContent(content, filename);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLIFrameElement> nodeAsIFrame = do_QueryInterface(aNode);
|
|
if (nodeAsIFrame)
|
|
{
|
|
nsString filename;
|
|
StoreURIAttribute(aNode, "src", PR_FALSE, &filename);
|
|
// Save the frame content
|
|
nsCOMPtr<nsIDOMDocument> content;
|
|
nodeAsIFrame->GetContentDocument(getter_AddRefs(content));
|
|
if (content)
|
|
{
|
|
SaveSubframeContent(content, filename);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLInputElement> nodeAsInput = do_QueryInterface(aNode);
|
|
if (nodeAsInput)
|
|
{
|
|
StoreURIAttribute(aNode, "src");
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
nsresult
|
|
nsWebBrowserPersist::CloneNodeWithFixedUpURIAttributes(nsIDOMNode *aNodeIn, nsIDOMNode **aNodeOut)
|
|
{
|
|
*aNodeOut = nsnull;
|
|
|
|
// Fix up href and file links in the elements
|
|
|
|
nsCOMPtr<nsIDOMHTMLAnchorElement> nodeAsAnchor = do_QueryInterface(aNodeIn);
|
|
if (nodeAsAnchor)
|
|
{
|
|
aNodeIn->CloneNode(PR_FALSE, aNodeOut);
|
|
FixupAnchor(*aNodeOut);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLAreaElement> nodeAsArea = do_QueryInterface(aNodeIn);
|
|
if (nodeAsArea)
|
|
{
|
|
aNodeIn->CloneNode(PR_FALSE, aNodeOut);
|
|
FixupAnchor(*aNodeOut);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLBodyElement> nodeAsBody = do_QueryInterface(aNodeIn);
|
|
if (nodeAsBody)
|
|
{
|
|
aNodeIn->CloneNode(PR_FALSE, aNodeOut);
|
|
FixupNodeAttribute(*aNodeOut, "background");
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLImageElement> nodeAsImage = do_QueryInterface(aNodeIn);
|
|
if (nodeAsImage)
|
|
{
|
|
aNodeIn->CloneNode(PR_FALSE, aNodeOut);
|
|
FixupAnchor(*aNodeOut);
|
|
FixupNodeAttribute(*aNodeOut, "src");
|
|
FixupNodeAttribute(*aNodeOut, "lowsrc");
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLScriptElement> nodeAsScript = do_QueryInterface(aNodeIn);
|
|
if (nodeAsScript)
|
|
{
|
|
aNodeIn->CloneNode(PR_FALSE, aNodeOut);
|
|
FixupNodeAttribute(*aNodeOut, "src");
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLLinkElement> nodeAsLink = do_QueryInterface(aNodeIn);
|
|
if (nodeAsLink)
|
|
{
|
|
aNodeIn->CloneNode(PR_FALSE, aNodeOut);
|
|
FixupNodeAttribute(*aNodeOut, "href");
|
|
// TODO if "type" attribute == "text/css"
|
|
// fixup stylesheet
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLFrameElement> nodeAsFrame = do_QueryInterface(aNodeIn);
|
|
if (nodeAsFrame)
|
|
{
|
|
aNodeIn->CloneNode(PR_FALSE, aNodeOut);
|
|
FixupNodeAttribute(*aNodeOut, "src");
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLIFrameElement> nodeAsIFrame = do_QueryInterface(aNodeIn);
|
|
if (nodeAsIFrame)
|
|
{
|
|
aNodeIn->CloneNode(PR_FALSE, aNodeOut);
|
|
FixupNodeAttribute(*aNodeOut, "src");
|
|
return NS_OK;
|
|
}
|
|
|
|
nsCOMPtr<nsIDOMHTMLInputElement> nodeAsInput = do_QueryInterface(aNodeIn);
|
|
if (nodeAsInput)
|
|
{
|
|
aNodeIn->CloneNode(PR_FALSE, aNodeOut);
|
|
FixupNodeAttribute(*aNodeOut, "src");
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsWebBrowserPersist::StoreURIAttribute(nsIDOMNode *aNode, char *aAttribute, PRBool aNeedsPersisting, nsString *aFilename)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aNode);
|
|
NS_ENSURE_ARG_POINTER(aAttribute);
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
// Find the named URI attribute on the (element) node and store
|
|
// a reference to the URI that maps onto a local file name
|
|
|
|
nsCOMPtr<nsIDOMNamedNodeMap> attrMap;
|
|
nsCOMPtr<nsIDOMNode> attrNode;
|
|
rv = aNode->GetAttributes(getter_AddRefs(attrMap));
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
|
|
|
|
nsString attribute; attribute.AssignWithConversion(aAttribute);
|
|
rv = attrMap->GetNamedItem(attribute, getter_AddRefs(attrNode));
|
|
if (attrNode)
|
|
{
|
|
nsString oldValue;
|
|
attrNode->GetNodeValue(oldValue);
|
|
nsCString oldCValue; oldCValue.AssignWithConversion(oldValue);
|
|
nsString filename;
|
|
MakeAndStoreLocalFilenameInURIMap(oldCValue, filename, aNeedsPersisting);
|
|
if (aFilename)
|
|
{
|
|
*aFilename = filename;
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsWebBrowserPersist::FixupNodeAttribute(nsIDOMNode *aNode, char *aAttribute)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aNode);
|
|
NS_ENSURE_ARG_POINTER(aAttribute);
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
// Find the named URI attribute on the (element) node and change it to reference
|
|
// a local file.
|
|
|
|
nsCOMPtr<nsIDOMNamedNodeMap> attrMap;
|
|
nsCOMPtr<nsIDOMNode> attrNode;
|
|
rv = aNode->GetAttributes(getter_AddRefs(attrMap));
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
|
|
|
|
nsString attribute; attribute.AssignWithConversion(aAttribute);
|
|
rv = attrMap->GetNamedItem(attribute, getter_AddRefs(attrNode));
|
|
if (attrNode)
|
|
{
|
|
nsString oldValue;
|
|
attrNode->GetNodeValue(oldValue);
|
|
nsCString oldCValue; oldCValue.AssignWithConversion(oldValue);
|
|
|
|
// Search for the URI in the map and replace it with the local file
|
|
nsCStringKey key(oldCValue);
|
|
if (mURIMap.Exists(&key))
|
|
{
|
|
nsString filename = ((URIData *) mURIMap.Get(&key))->mFilename;
|
|
nsAutoString newValue;
|
|
|
|
if (mDataPathIsRelative)
|
|
{
|
|
nsCAutoString rawPathURL;
|
|
rawPathURL.Assign(mRelativeDataPathURL);
|
|
rawPathURL.AppendWithConversion(filename);
|
|
newValue.AssignWithConversion(nsEscape(rawPathURL, url_Path));
|
|
}
|
|
else
|
|
{
|
|
nsCOMPtr<nsILocalFile> file;
|
|
NS_NewLocalFile(mDataPath, PR_FALSE, getter_AddRefs(file));
|
|
file->AppendUnicode(filename.get());
|
|
|
|
nsXPIDLCString fileurl;
|
|
file->GetURL(getter_Copies(fileurl));
|
|
newValue.AssignWithConversion(fileurl);
|
|
}
|
|
|
|
attrNode->SetNodeValue(newValue);
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsWebBrowserPersist::FixupAnchor(nsIDOMNode *aNode)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aNode);
|
|
|
|
nsCOMPtr<nsIDOMNamedNodeMap> attrMap;
|
|
nsCOMPtr<nsIDOMNode> attrNode;
|
|
nsresult rv = aNode->GetAttributes(getter_AddRefs(attrMap));
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
|
|
|
|
// Make all anchor links absolute so they point off onto the Internet
|
|
nsString attribute; attribute.AssignWithConversion("href");
|
|
rv = attrMap->GetNamedItem(attribute, getter_AddRefs(attrNode));
|
|
if (attrNode)
|
|
{
|
|
nsString oldValue;
|
|
attrNode->GetNodeValue(oldValue);
|
|
nsCString oldCValue; oldCValue.AssignWithConversion(oldValue);
|
|
|
|
// Skip self-referencing bookmarks
|
|
if (oldCValue.Length() > 0 && oldCValue.CharAt(0) == '#')
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
// Make a new URI to replace the current one
|
|
nsCOMPtr<nsIURI> newURI;
|
|
rv = NS_NewURI(getter_AddRefs(newURI), oldCValue.get(), mBaseURI);
|
|
if (NS_SUCCEEDED(rv))
|
|
{
|
|
nsXPIDLCString uriSpec;
|
|
newURI->GetSpec(getter_Copies(uriSpec));
|
|
nsAutoString newValue; newValue.AssignWithConversion(uriSpec);
|
|
attrNode->SetNodeValue(newValue);
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsWebBrowserPersist::StoreAndFixupStyleSheet(nsIStyleSheet *aStyleSheet)
|
|
{
|
|
// TODO go through the style sheet fixing up all links
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsWebBrowserPersist::SaveSubframeContent(nsIDOMDocument *aFrameContent, const nsString &aFilename)
|
|
{
|
|
nsresult rv;
|
|
|
|
// Work out the path for the frame
|
|
nsCOMPtr<nsILocalFile> frameFile;
|
|
rv = NS_NewLocalFile(mDataPath, PR_FALSE, getter_AddRefs(frameFile));
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
|
|
frameFile->AppendUnicode(aFilename.get());
|
|
|
|
// Work out the path for the frame data
|
|
nsCOMPtr<nsILocalFile> frameDatapath;
|
|
rv = NS_NewLocalFile(mDataPath, PR_FALSE, getter_AddRefs(frameDatapath));
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
|
|
nsString dataname;
|
|
char * tmp = PR_smprintf("subframe_%d", mFrameCounter++);
|
|
if (tmp == nsnull)
|
|
{
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
dataname.AssignWithConversion(tmp);
|
|
PR_smprintf_free(tmp);
|
|
frameDatapath->AppendUnicode(dataname.get());
|
|
|
|
// Create a new persistence object to persist the frame
|
|
nsWebBrowserPersist *framePersist = new nsWebBrowserPersist;
|
|
if (framePersist)
|
|
{
|
|
nsXPIDLCString filename;
|
|
frameFile->GetTarget(getter_Copies(filename));
|
|
nsXPIDLCString datapath;
|
|
frameDatapath->GetTarget(getter_Copies(datapath));
|
|
|
|
framePersist->AddRef();
|
|
framePersist->SetProgressListener(NS_STATIC_CAST(nsIWebBrowserPersistProgress *, this));
|
|
framePersist->SaveDocument(aFrameContent, filename.get(), datapath.get());
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
nsresult
|
|
nsWebBrowserPersist::SaveDocumentToFileWithFixup(
|
|
nsIDocument *aDocument,
|
|
nsIDocumentEncoderNodeFixup *aNodeFixup,
|
|
nsIFile* aFileSpec,
|
|
PRBool aReplaceExisting,
|
|
PRBool aSaveCopy,
|
|
const nsString& aFormatType,
|
|
const nsString& aSaveCharset,
|
|
PRUint32 aFlags)
|
|
{
|
|
// NOTE: This function is essentially a copy of nsDocument::SaveFile
|
|
// with a single line added to set the node fixup call back.
|
|
// This line is marked.
|
|
|
|
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
|
|
PRBool fileExists;
|
|
rv = aFileSpec->Exists(&fileExists);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (!aReplaceExisting && fileExists)
|
|
return NS_ERROR_FAILURE; // where are the file I/O errors?
|
|
|
|
nsCOMPtr<nsIFileOutputStream> outputStream = do_CreateInstance(NS_LOCALFILEOUTPUTSTREAM_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
rv = outputStream->Init(aFileSpec, -1, -1);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
// Get a document encoder instance
|
|
nsCAutoString contractID(NS_DOC_ENCODER_CONTRACTID_BASE);
|
|
contractID.AppendWithConversion(aFormatType);
|
|
|
|
nsCOMPtr<nsIDocumentEncoder> encoder = do_CreateInstance(contractID, &rv);
|
|
if (NS_FAILED(rv))
|
|
return rv;
|
|
|
|
rv = encoder->Init(aDocument, aFormatType, aFlags);
|
|
if (NS_FAILED(rv))
|
|
{
|
|
return rv;
|
|
}
|
|
|
|
// BEGIN --- Node fixup callback
|
|
encoder->SetNodeFixup(aNodeFixup);
|
|
// END --- Node fixup callback
|
|
|
|
nsAutoString charsetStr(aSaveCharset);
|
|
if (charsetStr.Length() == 0)
|
|
{
|
|
rv = aDocument->GetDocumentCharacterSet(charsetStr);
|
|
if(NS_FAILED(rv))
|
|
{
|
|
charsetStr.AssignWithConversion("ISO-8859-1");
|
|
}
|
|
}
|
|
encoder->SetCharset(charsetStr);
|
|
|
|
rv = encoder->EncodeToStream(outputStream);
|
|
|
|
return rv;
|
|
}
|
|
|
|
|
|
nsresult
|
|
nsWebBrowserPersist::MakeAndStoreLocalFilenameInURIMap(const char *aURI, nsString &aFilename, PRBool aNeedsPersisting)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aURI);
|
|
|
|
// Create a sensibly named filename for the URI and store in the URI map
|
|
|
|
nsCStringKey key(aURI);
|
|
nsString filename;
|
|
if (mURIMap.Exists(&key))
|
|
{
|
|
filename = ((URIData *) mURIMap.Get(&key))->mFilename;
|
|
}
|
|
else
|
|
{
|
|
nsresult rv;
|
|
|
|
// Open a channel to the URI
|
|
nsCOMPtr<nsIURI> uri;
|
|
rv = NS_NewURI(getter_AddRefs(uri), aURI, mBaseURI);
|
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
|
|
|
|
|
|
nsCOMPtr<nsIChannel> inputChannel;
|
|
rv = NS_OpenURI(getter_AddRefs(inputChannel), uri, nsnull);
|
|
if (NS_FAILED(rv) || inputChannel == nsnull)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// Create a unique file name for the uri
|
|
MakeFilenameFromURI(uri, inputChannel, filename);
|
|
|
|
if (!mMIMEService)
|
|
{
|
|
mMIMEService = do_GetService(NS_MIMESERVICE_CONTRACTID);
|
|
if (!mMIMEService)
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// Strap on the file extension using the mime lookup service
|
|
|
|
nsXPIDLCString contentType;
|
|
rv = mMIMEService->GetTypeFromURI(uri, getter_Copies(contentType));
|
|
if (NS_FAILED(rv))
|
|
return rv;
|
|
|
|
nsCOMPtr<nsIMIMEInfo> mimeInfo;
|
|
mMIMEService->GetFromMIMEType(contentType, getter_AddRefs(mimeInfo));
|
|
if (mimeInfo)
|
|
{
|
|
// Append the mime file extension
|
|
nsXPIDLCString fileExtension;
|
|
if (NS_SUCCEEDED(mimeInfo->FirstExtension(getter_Copies(fileExtension))))
|
|
{
|
|
nsString newExt;
|
|
newExt.AssignWithConversion(".");
|
|
newExt.AppendWithConversion(fileExtension);
|
|
// TODO no need to append if an extension for the mime type is already there
|
|
filename.Append(newExt);
|
|
}
|
|
}
|
|
|
|
// Store the file name
|
|
URIData *data = new URIData;
|
|
if (!data)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
data->mNeedsPersisting = aNeedsPersisting;
|
|
data->mFilename = filename;
|
|
mURIMap.Put(&key, data);
|
|
}
|
|
|
|
aFilename = filename;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsWebBrowserPersist::MakeFilenameFromURI(nsIURI *aURI, nsIChannel *aChannel, nsString &aFilename)
|
|
{
|
|
// Try to get filename from the URI.
|
|
aFilename.Truncate(0);
|
|
|
|
// TODO we can get a suggested file name from the http channel and
|
|
// failing that from the uri with code like below, but how can we be
|
|
// sure it will be a legal file name for the platform?
|
|
// We would have to ensure it only contained legal characters, was
|
|
// a legal length and was unique.
|
|
|
|
// nsCOMPtr<nsIURL> url(do_QueryInterface(aURI));
|
|
// if (url)
|
|
// {
|
|
// char *nameFromURL = nsnull;
|
|
// url->GetFileBaseName(&nameFromURL);
|
|
// if (nameFromURL)
|
|
// {
|
|
// // Unescape the file name (GetFileName escapes it).
|
|
// aFilename.AssignWithConversion(nsUnescape(nameFromURL));
|
|
// nsCRT::free(nameFromURL);
|
|
// }
|
|
// }
|
|
|
|
//
|
|
if (aFilename.Length() == 0)
|
|
{
|
|
// file_X is a dumb name but it's better than nothing
|
|
char * tmp = PR_smprintf("file_%d", mFileCounter++);
|
|
if (tmp == nsnull)
|
|
{
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
aFilename.AssignWithConversion(tmp);
|
|
PR_smprintf_free(tmp);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsWebBrowserPersist::SetDocumentBase(nsIDOMDocument *aDocument, nsIURI *aBaseURI)
|
|
{
|
|
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(aDocument);
|
|
if (!htmlDoc)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// Find the head element
|
|
nsCOMPtr<nsIDOMElement> headElement;
|
|
nsCOMPtr<nsIDOMNodeList> headList;
|
|
aDocument->GetElementsByTagName(NS_ConvertASCIItoUCS2("head"), getter_AddRefs(headList));
|
|
if (headList)
|
|
{
|
|
nsCOMPtr<nsIDOMNode> headNode;
|
|
headList->Item(0, getter_AddRefs(headNode));
|
|
headElement = do_QueryInterface(headNode);
|
|
}
|
|
if (!headElement)
|
|
{
|
|
// Create head and insert as first element
|
|
nsCOMPtr<nsIDOMNode> firstChildNode;
|
|
nsCOMPtr<nsIDOMNode> newNode;
|
|
aDocument->CreateElement(NS_ConvertASCIItoUCS2("head"), getter_AddRefs(headElement));
|
|
aDocument->GetFirstChild(getter_AddRefs(firstChildNode));
|
|
aDocument->InsertBefore(headElement, firstChildNode, getter_AddRefs(newNode));
|
|
}
|
|
if (!headElement)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// Find or create the BASE element
|
|
nsCOMPtr<nsIDOMElement> baseElement;
|
|
nsCOMPtr<nsIDOMNodeList> baseList;
|
|
headElement->GetElementsByTagName(NS_ConvertASCIItoUCS2("base"), getter_AddRefs(baseList));
|
|
if (baseList)
|
|
{
|
|
nsCOMPtr<nsIDOMNode> baseNode;
|
|
baseList->Item(0, getter_AddRefs(baseNode));
|
|
baseElement = do_QueryInterface(baseNode);
|
|
}
|
|
|
|
// Add or remove the BASE element
|
|
if (aBaseURI)
|
|
{
|
|
if (!baseElement)
|
|
{
|
|
nsCOMPtr<nsIDOMNode> newNode;
|
|
aDocument->CreateElement(NS_ConvertASCIItoUCS2("base"), getter_AddRefs(baseElement));
|
|
headElement->AppendChild(baseElement, getter_AddRefs(newNode));
|
|
}
|
|
if (!baseElement)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
nsXPIDLCString uriSpec;
|
|
aBaseURI->GetSpec(getter_Copies(uriSpec));
|
|
nsString href; href.AssignWithConversion(uriSpec);
|
|
baseElement->SetAttribute(NS_ConvertASCIItoUCS2("href"), href);
|
|
}
|
|
else
|
|
{
|
|
if (baseElement)
|
|
{
|
|
nsCOMPtr<nsIDOMNode> node;
|
|
headElement->RemoveChild(baseElement, getter_AddRefs(node));
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
nsEncoderNodeFixup::nsEncoderNodeFixup() : mWebBrowserPersist(nsnull)
|
|
{
|
|
NS_INIT_REFCNT();
|
|
}
|
|
|
|
|
|
nsEncoderNodeFixup::~nsEncoderNodeFixup()
|
|
{
|
|
}
|
|
|
|
|
|
NS_IMPL_ADDREF(nsEncoderNodeFixup)
|
|
NS_IMPL_RELEASE(nsEncoderNodeFixup)
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN(nsEncoderNodeFixup)
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocumentEncoderNodeFixup)
|
|
NS_INTERFACE_MAP_ENTRY(nsIDocumentEncoderNodeFixup)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
|
|
NS_IMETHODIMP nsEncoderNodeFixup::FixupNode(nsIDOMNode *aNode, nsIDOMNode **aOutNode)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aNode);
|
|
NS_ENSURE_ARG_POINTER(aOutNode);
|
|
NS_ENSURE_TRUE(mWebBrowserPersist, NS_ERROR_FAILURE);
|
|
|
|
*aOutNode = nsnull;
|
|
|
|
// Test whether we need to fixup the node
|
|
PRUint16 type = 0;
|
|
aNode->GetNodeType(&type);
|
|
if (type == nsIDOMNode::ELEMENT_NODE)
|
|
{
|
|
mWebBrowserPersist->CloneNodeWithFixedUpURIAttributes(aNode, aOutNode);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|